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:
Jim Grosbach 2011-07-27 21:09:25 +00:00
parent c94eefb258
commit fb8989e640
10 changed files with 48 additions and 23 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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]> {

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();

View File

@ -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]

View File

@ -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: ^