mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-24 19:44:49 +00:00
ARM parsing and encoding of SBFX and UBFX.
Encode the width operand as it encodes in the instruction, which simplifies the disassembler and the encoder, by using the imm1_32 operand def. Add a diagnostic for the context-sensitive constraint that the width must be in the range [1,32-lsb]. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136264 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c94eefb258
commit
fb8989e640
@ -215,8 +215,6 @@ namespace {
|
||||
const { return 0; }
|
||||
unsigned getT2SORegOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op)
|
||||
const { return 0; }
|
||||
unsigned getAddrMode6AddressOpValue(const MachineInstr &MI, unsigned Op)
|
||||
|
@ -2024,7 +2024,8 @@ SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N,
|
||||
Srl_imm)) {
|
||||
assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!");
|
||||
|
||||
unsigned Width = CountTrailingOnes_32(And_imm);
|
||||
// Note: The width operand is encoded as width-1.
|
||||
unsigned Width = CountTrailingOnes_32(And_imm) - 1;
|
||||
unsigned LSB = Srl_imm;
|
||||
SDValue Reg0 = CurDAG->getRegister(0, MVT::i32);
|
||||
SDValue Ops[] = { N->getOperand(0).getOperand(0),
|
||||
@ -2044,7 +2045,8 @@ SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N,
|
||||
unsigned Srl_imm = 0;
|
||||
if (isInt32Immediate(N->getOperand(1), Srl_imm)) {
|
||||
assert(Srl_imm > 0 && Srl_imm < 32 && "bad amount in shift node!");
|
||||
unsigned Width = 32 - Srl_imm;
|
||||
// Note: The width operand is encoded as width-1.
|
||||
unsigned Width = 32 - Srl_imm - 1;
|
||||
int LSB = Srl_imm - Shl_imm;
|
||||
if (LSB < 0)
|
||||
return NULL;
|
||||
|
@ -513,14 +513,6 @@ def imm0_31 : Operand<i32>, ImmLeaf<i32, [{
|
||||
let ParserMatchClass = Imm0_31AsmOperand;
|
||||
}
|
||||
|
||||
/// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
|
||||
def imm0_31_m1 : Operand<i32>, ImmLeaf<i32, [{
|
||||
return Imm >= 0 && Imm < 32;
|
||||
}]> {
|
||||
let EncoderMethod = "getImmMinusOneOpValue";
|
||||
let DecoderMethod = "DecodeImmMinusOneOperand";
|
||||
}
|
||||
|
||||
// imm0_65535_expr - For movt/movw - 16-bit immediate that can also reference
|
||||
// a relocatable expression.
|
||||
//
|
||||
@ -2423,7 +2415,7 @@ def UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
|
||||
|
||||
|
||||
def SBFX : I<(outs GPR:$Rd),
|
||||
(ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
|
||||
(ins GPR:$Rn, imm0_31:$lsb, imm1_32:$width),
|
||||
AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
|
||||
"sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
|
||||
Requires<[IsARM, HasV6T2]> {
|
||||
@ -2440,7 +2432,7 @@ def SBFX : I<(outs GPR:$Rd),
|
||||
}
|
||||
|
||||
def UBFX : I<(outs GPR:$Rd),
|
||||
(ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
|
||||
(ins GPR:$Rn, imm0_31:$lsb, imm1_32:$width),
|
||||
AddrMode1, 4, IndexModeNone, DPFrm, IIC_iUNAsi,
|
||||
"ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
|
||||
Requires<[IsARM, HasV6T2]> {
|
||||
|
@ -2024,7 +2024,7 @@ def t2BFC : T2BitFI<(outs rGPR:$Rd), (ins rGPR:$src, bf_inv_mask_imm:$imm),
|
||||
}
|
||||
|
||||
def t2SBFX: T2TwoRegBitFI<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm1_32:$msb),
|
||||
IIC_iUNAsi, "sbfx", "\t$Rd, $Rn, $lsb, $msb", []> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25} = 1;
|
||||
@ -2033,7 +2033,7 @@ def t2SBFX: T2TwoRegBitFI<
|
||||
}
|
||||
|
||||
def t2UBFX: T2TwoRegBitFI<
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm0_31_m1:$msb),
|
||||
(outs rGPR:$Rd), (ins rGPR:$Rn, imm0_31:$lsb, imm1_32:$msb),
|
||||
IIC_iUNAsi, "ubfx", "\t$Rd, $Rn, $lsb, $msb", []> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25} = 1;
|
||||
|
@ -2605,6 +2605,15 @@ validateInstruction(MCInst &Inst,
|
||||
"source operands must be sequential");
|
||||
return false;
|
||||
}
|
||||
case ARM::SBFX:
|
||||
case ARM::UBFX: {
|
||||
// width must be in range [1, 32-lsb]
|
||||
unsigned lsb = Inst.getOperand(2).getImm();
|
||||
unsigned widthm1 = Inst.getOperand(3).getImm();
|
||||
if (widthm1 >= 32 - lsb)
|
||||
return Error(Operands[5]->getStartLoc(),
|
||||
"bitfield width must be in range [1,32-lsb]");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -1026,7 +1026,7 @@ static bool DisassembleDPFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
|
||||
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
|
||||
decodeRm(insn))));
|
||||
MI.addOperand(MCOperand::CreateImm(slice(insn, 11, 7)));
|
||||
MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 16) + 1));
|
||||
MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 16)));
|
||||
OpIdx += 3;
|
||||
return true;
|
||||
}
|
||||
|
@ -1698,7 +1698,7 @@ static bool DisassembleThumb2DPBinImm(MCInst &MI, unsigned Opcode,
|
||||
assert((Opcode == ARM::t2SBFX || Opcode == ARM::t2UBFX)
|
||||
&& "Unexpected opcode");
|
||||
MI.addOperand(MCOperand::CreateImm(getLsb(insn)));
|
||||
MI.addOperand(MCOperand::CreateImm(getWidthMinus1(insn) + 1));
|
||||
MI.addOperand(MCOperand::CreateImm(getWidthMinus1(insn)));
|
||||
|
||||
++OpIdx;
|
||||
}
|
||||
|
@ -259,11 +259,6 @@ public:
|
||||
unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const;
|
||||
|
||||
unsigned getImmMinusOneOpValue(const MCInst &MI, unsigned Op,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
return MI.getOperand(Op).getImm() - 1;
|
||||
}
|
||||
|
||||
unsigned getNEONVcvtImm32OpValue(const MCInst &MI, unsigned Op,
|
||||
SmallVectorImpl<MCFixup> &Fixups) const {
|
||||
return 64 - MI.getOperand(Op).getImm();
|
||||
|
@ -1308,6 +1308,16 @@ _func:
|
||||
@ CHECK: sbc r6, r6, r7, ror r9 @ encoding: [0x77,0x69,0xc6,0xe0]
|
||||
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ SBFX
|
||||
@------------------------------------------------------------------------------
|
||||
sbfx r4, r5, #16, #1
|
||||
sbfxgt r4, r5, #16, #16
|
||||
|
||||
@ CHECK: sbfx r4, r5, #16, #1 @ encoding: [0x55,0x48,0xa0,0xe7]
|
||||
@ CHECK: sbfxgt r4, r5, #16, #16 @ encoding: [0x55,0x48,0xaf,0xc7]
|
||||
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ SEL
|
||||
@------------------------------------------------------------------------------
|
||||
@ -2001,3 +2011,11 @@ _func:
|
||||
@ CHECK: uasxeq r9, r12, r0 @ encoding: [0x30,0x9f,0x5c,0x06]
|
||||
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
@ UBFX
|
||||
@------------------------------------------------------------------------------
|
||||
ubfx r4, r5, #16, #1
|
||||
ubfxgt r4, r5, #16, #16
|
||||
|
||||
@ CHECK: ubfx r4, r5, #16, #1 @ encoding: [0x55,0x48,0xe0,0xe7]
|
||||
@ CHECK: ubfxgt r4, r5, #16, #16 @ encoding: [0x55,0x48,0xef,0xc7]
|
||||
|
@ -272,3 +272,14 @@
|
||||
@ CHECK-ERRORS: error: rotate operator 'ror' expected
|
||||
@ CHECK-ERRORS: sxtb16ge r2, r3, lsr #24
|
||||
@ CHECK-ERRORS: ^
|
||||
|
||||
@ Out of range width for SBFX/UBFX
|
||||
sbfx r4, r5, #31, #2
|
||||
ubfxgt r4, r5, #16, #17
|
||||
|
||||
@ CHECK-ERRORS: error: bitfield width must be in range [1,32-lsb]
|
||||
@ CHECK-ERRORS: sbfx r4, r5, #31, #2
|
||||
@ CHECK-ERRORS: ^
|
||||
@ CHECK-ERRORS: error: bitfield width must be in range [1,32-lsb]
|
||||
@ CHECK-ERRORS: ubfxgt r4, r5, #16, #17
|
||||
@ CHECK-ERRORS: ^
|
||||
|
Loading…
x
Reference in New Issue
Block a user