Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -1580,7 +1580,8 @@ (Value >= 0x010000 && Value <= 0xff0000) || (Value >= 0x01000000 && Value <= 0xff000000) || (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) || - (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff); + (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff) || + (Value == 0xffffffff); } bool isNEONi32vmovNeg() const { if (!isImm()) return false; @@ -2284,8 +2285,34 @@ Value = (Value >> 8) | ((Value & 0xff) ? 0xc00 : 0x200); else if (Value > 0xffff && Value <= 0xffffff) Value = (Value >> 16) | ((Value & 0xff) ? 0xd00 : 0x400); - else if (Value > 0xffffff) + else if (Value > 0xffffff && Value != 0xffffffff) Value = (Value >> 24) | 0x600; + else if (Value == 0xffffffff) { + // FIXME: This is compatability workaround for GNU assembler: + // gcc sometimes emits "vmov.i32 dN, 0xffffffff" instructions, + // even they are illegal gcc-as eats them and replaces + // with "vmov.i8 dN, 0xff". + switch (Inst.getOpcode()) { + case ARM::VMOVv2i32: + Inst.setOpcode(ARM::VMOVv8i8); + Value = 0xeff; + break; + case ARM::VMOVv4i32: + Inst.setOpcode(ARM::VMOVv16i8); + Value = 0xeff; + break; + case ARM::VMVNv4i32: + Inst.setOpcode(ARM::VMOVv2i32); + Value = 0; + break; + case ARM::VMVNv2i32: + Inst.setOpcode(ARM::VMOVv2i32); + Value = 0; + break; + default: + llvm_unreachable("Unexpected instruction opcode."); + } + } Inst.addOperand(MCOperand::CreateImm(Value)); } Index: test/MC/ARM/vmov-i32-allones.s =================================================================== --- /dev/null +++ test/MC/ARM/vmov-i32-allones.s @@ -0,0 +1,12 @@ +@ PR18921, "vmov" part. +@ RUN: llvm-mc -triple=armv7-linux-gnueabi -show-encoding < %s | FileCheck %s +.text + +@ CHECK: vmov.i8 d2, #0xff @ encoding: [0x1f,0x2e,0x87,0xf3] +@ CHECK: vmov.i8 q2, #0xff @ encoding: [0x5f,0x4e,0x87,0xf3] +@ CHECK: vmov.i32 d2, #0x0 @ encoding: [0x10,0x20,0x80,0xf2] +@ CHECK: vmov.i32 q2, #0x0 @ encoding: [0x10,0x40,0x80,0xf2] + vmov.i32 d2, #0xffffffff + vmov.i32 q2, #0xffffffff + vmvn.i32 d2, #0xffffffff + vmvn.i32 q2, #0xffffffff