mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Add support for parsing and encoding ARM's official syntax for the BFI instruction
llvm-svn: 123770
This commit is contained in:
parent
6de3a4f76f
commit
94247155c4
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -2152,20 +2152,39 @@ def t2UBFX: T2TwoRegBitFI<
|
||||
}
|
||||
|
||||
// A8.6.18 BFI - Bitfield insert (Encoding T1)
|
||||
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,
|
||||
bf_inv_mask_imm:$imm))]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25} = 1;
|
||||
let Inst{24-20} = 0b10110;
|
||||
let Inst{15} = 0;
|
||||
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,
|
||||
bf_inv_mask_imm:$imm))]> {
|
||||
let Inst{31-27} = 0b11110;
|
||||
let Inst{25} = 1;
|
||||
let Inst{24-20} = 0b10110;
|
||||
let Inst{15} = 0;
|
||||
|
||||
bits<10> imm;
|
||||
let msb{4-0} = imm{9-5};
|
||||
let lsb{4-0} = imm{4-0};
|
||||
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",
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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") &&
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user