Index: llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td +++ llvm/trunk/lib/Target/ARM/ARMInstrThumb2.td @@ -5223,7 +5223,7 @@ } // end isNotDuplicable class CS opcode, list pattern=[]> - : V8_1MI<(outs rGPR:$Rd), (ins GPRwithZR:$Rn, GPRwithZR:$Rm, pred_noal:$fcond), + : V8_1MI<(outs rGPR:$Rd), (ins GPRwithZR:$Rn, GPRwithZRnosp:$Rm, pred_noal:$fcond), AddrModeNone, NoItinerary, iname, "$Rd, $Rn, $Rm, $fcond", "", pattern> { bits<4> Rd; bits<4> Rm; @@ -5255,11 +5255,11 @@ (t2CSINC rGPR:$Rd, ZR, ZR, pred_noal_inv:$fcond)>; def : InstAlias<"cinc\t$Rd, $Rn, $fcond", - (t2CSINC rGPR:$Rd, GPRwithZR:$Rn, GPRwithZR:$Rn, pred_noal_inv:$fcond)>; + (t2CSINC rGPR:$Rd, GPRwithZRnosp:$Rn, GPRwithZRnosp:$Rn, pred_noal_inv:$fcond)>; def : InstAlias<"cinv\t$Rd, $Rn, $fcond", - (t2CSINV rGPR:$Rd, GPRwithZR:$Rn, GPRwithZR:$Rn, pred_noal_inv:$fcond)>; + (t2CSINV rGPR:$Rd, GPRwithZRnosp:$Rn, GPRwithZRnosp:$Rn, pred_noal_inv:$fcond)>; def : InstAlias<"cneg\t$Rd, $Rn, $fcond", - (t2CSNEG rGPR:$Rd, GPRwithZR:$Rn, GPRwithZR:$Rn, pred_noal_inv:$fcond)>; + (t2CSNEG rGPR:$Rd, GPRwithZRnosp:$Rn, GPRwithZRnosp:$Rn, pred_noal_inv:$fcond)>; } Index: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td =================================================================== --- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td +++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.td @@ -261,13 +261,19 @@ let isAllocatable = 0; } -def GPRwithZR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12), - LR, ZR)> { - +def GPRwithZR : RegisterClass<"ARM", [i32], 32, (add (sub GPR, PC), ZR)> { let AltOrders = [(add LR, GPRwithZR), (trunc GPRwithZR, 8)]; let AltOrderSelect = [{ return 1 + MF.getSubtarget().isThumb1Only(); }]; + let DiagnosticString = "operand must be a register in range [r0, r14] or zr"; +} + +def GPRwithZRnosp : RegisterClass<"ARM", [i32], 32, (sub GPRwithZR, SP)> { + let AltOrders = [(add LR, GPRwithZRnosp), (trunc GPRwithZRnosp, 8)]; + let AltOrderSelect = [{ + return 1 + MF.getSubtarget().isThumb1Only(); + }]; let DiagnosticString = "operand must be a register in range [r0, r12] or r14 or zr"; } Index: llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp =================================================================== --- llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ llvm/trunk/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -194,6 +194,8 @@ static DecodeStatus DecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPRwithZRnospRegisterClass( + MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, @@ -1184,12 +1186,22 @@ } if (RegNo == 13) - S = MCDisassembler::SoftFail; + Check(S, MCDisassembler::SoftFail); Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder)); return S; } +static DecodeStatus +DecodeGPRwithZRnospRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + if (RegNo == 13) + return MCDisassembler::Fail; + Check(S, DecodeGPRwithZRRegisterClass(Inst, RegNo, Address, Decoder)); + return S; +} + static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { if (RegNo > 7) Index: llvm/trunk/test/MC/Disassembler/ARM/mve-scalar-shift.txt =================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/mve-scalar-shift.txt +++ llvm/trunk/test/MC/Disassembler/ARM/mve-scalar-shift.txt @@ -28,7 +28,7 @@ [0x5f 0xea 0x2d 0x83] # CHECK: sqrshrl lr, r3, r8 @ encoding: [0x5f,0xea,0x2d,0x83] -# CHECK-NOMVE: [[@LINE-2]]:2: warning: potentially undefined instruction encoding +# CHECK-NOMVE: [[@LINE-2]]:2: warning: invalid instruction encoding [0x5e 0xea 0x7f 0x4f] # CHECK: sqshl lr, #17 @ encoding: [0x5e,0xea,0x7f,0x4f] Index: llvm/trunk/test/MC/Disassembler/ARM/thumbv8.1m.s =================================================================== --- llvm/trunk/test/MC/Disassembler/ARM/thumbv8.1m.s +++ llvm/trunk/test/MC/Disassembler/ARM/thumbv8.1m.s @@ -1,4 +1,4 @@ -# RUN: llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -show-encoding %s 2> %t | FileCheck %s +# RUN: not llvm-mc -disassemble -triple=thumbv8.1m.main-none-eabi -show-encoding %s 2> %t | FileCheck %s # RUN: FileCheck --check-prefix=ERROR < %t %s [0x52 0xea 0x22 0x9e] @@ -37,6 +37,20 @@ [0x50,0xea,0x01,0x80] # CHECK: csel r0, r0, r1, eq @ encoding: [0x50,0xea,0x01,0x80] +[0x51,0xea,0x02,0x8d] +# CHECK: csel sp, r1, r2, eq @ encoding: [0x51,0xea,0x02,0x8d] +# ERROR: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x5d,0xea,0x02,0x80] +# CHECK: csel r0, sp, r2, eq @ encoding: [0x5d,0xea,0x02,0x80] +# ERROR: [[@LINE-2]]:2: warning: potentially undefined instruction encoding + +[0x51,0xea,0x0d,0x80] +# ERROR: [[@LINE-1]]:2: warning: invalid instruction encoding + +[0x5f,0xea,0x0d,0x83] +# ERROR: [[@LINE-1]]:2: warning: invalid instruction encoding + [0x5d 0xea 0x22 0x9e] # ERROR: [[@LINE-1]]:2: warning: potentially undefined instruction encoding