Add support for parsing and encoding ARM's official syntax for the BFI instruction

llvm-svn: 123770
This commit is contained in:
Bruno Cardoso Lopes 2011-01-18 20:45:56 +00:00
parent 6de3a4f76f
commit 94247155c4
8 changed files with 91 additions and 13 deletions

View File

@ -225,6 +225,8 @@ namespace {
const { return 0; }
unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI,
unsigned Op) const { return 0; }
unsigned getMsbOpValue(const MachineInstr &MI,
unsigned Op) const { return 0; }
uint32_t getLdStmModeOpValue(const MachineInstr &MI, unsigned OpIdx)
const {return 0; }
uint32_t getLdStSORegOpValue(const MachineInstr &MI, unsigned OpIdx)

View File

@ -443,6 +443,18 @@ def bf_inv_mask_imm : Operand<i32>,
let PrintMethod = "printBitfieldInvMaskImmOperand";
}
/// lsb_pos_imm - position of the lsb bit, used by BFI4p and t2BFI4p
def lsb_pos_imm : Operand<i32>, PatLeaf<(imm), [{
return isInt<5>(N->getSExtValue());
}]>;
/// width_imm - number of bits to be copied, used by BFI4p and t2BFI4p
def width_imm : Operand<i32>, PatLeaf<(imm), [{
return N->getSExtValue() > 0 && N->getSExtValue() <= 32;
}] > {
let EncoderMethod = "getMsbOpValue";
}
// Define ARM specific addressing modes.
@ -2463,6 +2475,25 @@ def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm),
let Inst{3-0} = Rn;
}
// GNU as only supports this form of bfi (w/ 4 arguments)
let isAsmParserOnly = 1 in
def BFI4p : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn,
lsb_pos_imm:$lsb, width_imm:$width),
AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
"bfi", "\t$Rd, $Rn, $lsb, $width", "$src = $Rd",
[]>, Requires<[IsARM, HasV6T2]> {
bits<4> Rd;
bits<4> Rn;
bits<5> lsb;
bits<5> width;
let Inst{27-21} = 0b0111110;
let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15
let Inst{15-12} = Rd;
let Inst{11-7} = lsb;
let Inst{20-16} = width; // Custom encoder => lsb+width-1
let Inst{3-0} = Rn;
}
def MVNr : AsI1<0b1111, (outs GPR:$Rd), (ins GPR:$Rm), DPFrm, IIC_iMVNr,
"mvn", "\t$Rd, $Rm",
[(set GPR:$Rd, (not GPR:$Rm))]>, UnaryDP {

View File

@ -2152,8 +2152,8 @@ def t2UBFX: T2TwoRegBitFI<
}
// A8.6.18 BFI - Bitfield insert (Encoding T1)
let Constraints = "$src = $Rd" in
def t2BFI : T2TwoRegBitFI<(outs rGPR:$Rd),
let Constraints = "$src = $Rd" in {
def t2BFI : T2TwoRegBitFI<(outs rGPR:$Rd),
(ins rGPR:$src, rGPR:$Rn, bf_inv_mask_imm:$imm),
IIC_iBITi, "bfi", "\t$Rd, $Rn, $imm",
[(set rGPR:$Rd, (ARMbfi rGPR:$src, rGPR:$Rn,
@ -2166,6 +2166,25 @@ def t2BFI : T2TwoRegBitFI<(outs rGPR:$Rd),
bits<10> imm;
let msb{4-0} = imm{9-5};
let lsb{4-0} = imm{4-0};
}
// GNU as only supports this form of bfi (w/ 4 arguments)
let isAsmParserOnly = 1 in
def t2BFI4p : T2TwoRegBitFI<(outs rGPR:$Rd),
(ins rGPR:$src, rGPR:$Rn, lsb_pos_imm:$lsbit,
width_imm:$width),
IIC_iBITi, "bfi", "\t$Rd, $Rn, $lsbit, $width",
[]> {
let Inst{31-27} = 0b11110;
let Inst{25} = 1;
let Inst{24-20} = 0b10110;
let Inst{15} = 0;
bits<5> lsbit;
bits<5> width;
let msb{4-0} = width; // Custom encoder => lsb+width-1
let lsb{4-0} = lsbit;
}
}
defm t2ORN : T2I_bin_irs<0b0011, "orn",

View File

@ -262,6 +262,9 @@ public:
unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getMsbOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getRegisterListOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const;
unsigned getAddrMode6AddressOpValue(const MCInst &MI, unsigned Op,
@ -1066,6 +1069,17 @@ getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op,
return lsb | (msb << 5);
}
unsigned ARMMCCodeEmitter::
getMsbOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const {
// MSB - 5 bits.
uint32_t lsb = MI.getOperand(Op-1).getImm();
uint32_t width = MI.getOperand(Op).getImm();
uint32_t msb = lsb+width-1;
assert (width != 0 && msb < 32 && "Illegal bit width!");
return msb;
}
unsigned ARMMCCodeEmitter::
getRegisterListOpValue(const MCInst &MI, unsigned Op,
SmallVectorImpl<MCFixup> &Fixups) const {

View File

@ -124,3 +124,6 @@
@ may depend on flags.
@ CHECK-FIXME:: mlas r1, r2, r3, r4 @ encoding: [0x92,0x43,0x31,0xe0]
@ mlas r1,r2,r3,r4
@ CHECK: bfi r0, r0, #5, #7 @ encoding: [0x90,0x02,0xcb,0xe7]
bfi r0, r0, #5, #7

View File

@ -162,3 +162,6 @@
ldrsb.w r0, [r0]
@ CHECK: ldrsh.w r0, [r0] @ encoding: [0x00,0x00,0xb0,0xf9]
ldrsh.w r0, [r0]
@ CHECK: bfi r0, r0, #5, #7 @ encoding: [0x60,0xf3,0x4b,0x10]
bfi r0, r0, #5, #7

View File

@ -1560,6 +1560,10 @@ ARMDEBackend::populateInstruction(const CodeGenInstruction &CGI,
// which is a better design and less fragile than the name matchings.
if (Bits.allInComplete()) return false;
// Ignore "asm parser only" instructions.
if (Def.getValueAsBit("isAsmParserOnly"))
return false;
if (TN == TARGET_ARM) {
// FIXME: what about Int_MemBarrierV6 and Int_SyncBarrierV6?
if ((Name != "Int_MemBarrierV7" && Name != "Int_SyncBarrierV7") &&

View File

@ -566,6 +566,8 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
IMM("i32imm");
IMM("i32imm_hilo16");
IMM("bf_inv_mask_imm");
IMM("lsb_pos_imm");
IMM("width_imm");
IMM("jtblock_operand");
IMM("nohash_imm");
IMM("p_imm");