forked from OSchip/llvm-project
[ARM] Tighten restrictions on use of SP in v8.1-M CSEL.
In the `CSEL Rd,Rm,Rn` instruction family (also including CSINC, CSINV and CSNEG), the architecture lists it as CONSTRAINED UNPREDICTABLE (i.e. SoftFail) to use SP in the Rd or Rm slot, but outright illegal to use it in the Rn slot, not least because some encodings of that form are used by MVE instructions such as UQRSHLL. MC was treating all three slots the same, as SoftFail. So the only reason UQRSHLL was disassembled correctly at all was because the MVE decode table is separate from the Thumb2 one and takes priority; if you turned off MVE, then encodings such as `[0x5f,0xea,0x0d,0x83]` would disassemble as spurious CSELs. Fixed by inventing another version of the `GPRwithZR` register class, which disallows SP completely instead of just SoftFailing it. Reviewers: DavidSpickett, ostannard Subscribers: javed.absar, kristof.beyls, hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63862 llvm-svn: 364531
This commit is contained in:
parent
c5cff5d3d1
commit
02449f9c3c
llvm
lib/Target/ARM
test/MC/Disassembler/ARM
|
@ -5223,7 +5223,7 @@ def t2LoopEnd :
|
||||||
} // end isNotDuplicable
|
} // end isNotDuplicable
|
||||||
|
|
||||||
class CS<string iname, bits<4> opcode, list<dag> pattern=[]>
|
class CS<string iname, bits<4> opcode, list<dag> 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> {
|
AddrModeNone, NoItinerary, iname, "$Rd, $Rn, $Rm, $fcond", "", pattern> {
|
||||||
bits<4> Rd;
|
bits<4> Rd;
|
||||||
bits<4> Rm;
|
bits<4> Rm;
|
||||||
|
@ -5255,11 +5255,11 @@ let Predicates = [HasV8_1MMainline] in {
|
||||||
(t2CSINC rGPR:$Rd, ZR, ZR, pred_noal_inv:$fcond)>;
|
(t2CSINC rGPR:$Rd, ZR, ZR, pred_noal_inv:$fcond)>;
|
||||||
|
|
||||||
def : InstAlias<"cinc\t$Rd, $Rn, $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",
|
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",
|
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)>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -261,13 +261,19 @@ def GPRwithAPSRnosp : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 1
|
||||||
let isAllocatable = 0;
|
let isAllocatable = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
def GPRwithZR : RegisterClass<"ARM", [i32], 32, (add (sequence "R%u", 0, 12),
|
def GPRwithZR : RegisterClass<"ARM", [i32], 32, (add (sub GPR, PC), ZR)> {
|
||||||
LR, ZR)> {
|
|
||||||
|
|
||||||
let AltOrders = [(add LR, GPRwithZR), (trunc GPRwithZR, 8)];
|
let AltOrders = [(add LR, GPRwithZR), (trunc GPRwithZR, 8)];
|
||||||
let AltOrderSelect = [{
|
let AltOrderSelect = [{
|
||||||
return 1 + MF.getSubtarget<ARMSubtarget>().isThumb1Only();
|
return 1 + MF.getSubtarget<ARMSubtarget>().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<ARMSubtarget>().isThumb1Only();
|
||||||
|
}];
|
||||||
let DiagnosticString = "operand must be a register in range [r0, r12] or r14 or zr";
|
let DiagnosticString = "operand must be a register in range [r0, r12] or r14 or zr";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,8 @@ static DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst &Inst,
|
||||||
static DecodeStatus DecodeGPRwithZRRegisterClass(MCInst &Inst,
|
static DecodeStatus DecodeGPRwithZRRegisterClass(MCInst &Inst,
|
||||||
unsigned RegNo, uint64_t Address,
|
unsigned RegNo, uint64_t Address,
|
||||||
const void *Decoder);
|
const void *Decoder);
|
||||||
|
static DecodeStatus DecodeGPRwithZRnospRegisterClass(
|
||||||
|
MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder);
|
||||||
static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
|
static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
|
||||||
uint64_t Address, const void *Decoder);
|
uint64_t Address, const void *Decoder);
|
||||||
static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
|
static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
|
||||||
|
@ -1184,12 +1186,22 @@ DecodeGPRwithZRRegisterClass(MCInst &Inst, unsigned RegNo,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RegNo == 13)
|
if (RegNo == 13)
|
||||||
S = MCDisassembler::SoftFail;
|
Check(S, MCDisassembler::SoftFail);
|
||||||
|
|
||||||
Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
|
Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
|
||||||
return S;
|
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,
|
static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
|
||||||
uint64_t Address, const void *Decoder) {
|
uint64_t Address, const void *Decoder) {
|
||||||
if (RegNo > 7)
|
if (RegNo > 7)
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
[0x5f 0xea 0x2d 0x83]
|
[0x5f 0xea 0x2d 0x83]
|
||||||
# CHECK: sqrshrl lr, r3, r8 @ encoding: [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]
|
[0x5e 0xea 0x7f 0x4f]
|
||||||
# CHECK: sqshl lr, #17 @ encoding: [0x5e,0xea,0x7f,0x4f]
|
# CHECK: sqshl lr, #17 @ encoding: [0x5e,0xea,0x7f,0x4f]
|
||||||
|
|
|
@ -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
|
# RUN: FileCheck --check-prefix=ERROR < %t %s
|
||||||
|
|
||||||
[0x52 0xea 0x22 0x9e]
|
[0x52 0xea 0x22 0x9e]
|
||||||
|
@ -37,6 +37,20 @@
|
||||||
[0x50,0xea,0x01,0x80]
|
[0x50,0xea,0x01,0x80]
|
||||||
# CHECK: csel r0, r0, r1, eq @ encoding: [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]
|
[0x5d 0xea 0x22 0x9e]
|
||||||
# ERROR: [[@LINE-1]]:2: warning: potentially undefined instruction encoding
|
# ERROR: [[@LINE-1]]:2: warning: potentially undefined instruction encoding
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue