From 5edb03ee57f5289aa768fabb441c2ab5e33d2328 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Thu, 21 Oct 2010 22:03:21 +0000 Subject: [PATCH] ARM Binary encoding information for BFC/BFI instructions. llvm-svn: 117072 --- llvm/lib/Target/ARM/ARMCodeEmitter.cpp | 2 ++ llvm/lib/Target/ARM/ARMInstrInfo.td | 25 ++++++++++++++++++------ llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp | 14 +++++++++++++ llvm/test/MC/ARM/simple-encoding.ll | 7 +++++++ 4 files changed, 42 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp b/llvm/lib/Target/ARM/ARMCodeEmitter.cpp index 0220e7ddacb2..2b1239d921bd 100644 --- a/llvm/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/llvm/lib/Target/ARM/ARMCodeEmitter.cpp @@ -172,6 +172,8 @@ namespace { const { return 0; } unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op) const { return 0; } + unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI, + unsigned Op) const { return 0; } /// getMovi32Value - Return binary encoding of operand for movw/movt. If the /// machine operand requires relocation, record the relocation and return diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index df698f9e21f6..7d6942250dca 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -232,6 +232,7 @@ def bf_inv_mask_imm : Operand, PatLeaf<(imm), [{ return ARM::isBitFieldInvertedMask(N->getZExtValue()); }] > { + string EncoderMethod = "getBitfieldInvertedMaskOpValue"; let PrintMethod = "printBitfieldInvMaskImmOperand"; } @@ -2174,24 +2175,36 @@ defm BIC : AsI1_bin_irs<0b1110, "bic", IIC_iBITi, IIC_iBITr, IIC_iBITsr, BinOpFrag<(and node:$LHS, (not node:$RHS))>>; -def BFC : I<(outs GPR:$dst), (ins GPR:$src, bf_inv_mask_imm:$imm), +def BFC : I<(outs GPR:$Rd), (ins GPR:$src, bf_inv_mask_imm:$imm), AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, - "bfc", "\t$dst, $imm", "$src = $dst", - [(set GPR:$dst, (and GPR:$src, bf_inv_mask_imm:$imm))]>, + "bfc", "\t$Rd, $imm", "$src = $Rd", + [(set GPR:$Rd, (and GPR:$src, bf_inv_mask_imm:$imm))]>, Requires<[IsARM, HasV6T2]> { + bits<4> Rd; + bits<10> imm; let Inst{27-21} = 0b0111110; let Inst{6-0} = 0b0011111; + let Inst{15-12} = Rd; + let Inst{11-7} = imm{4-0}; // lsb + let Inst{20-16} = imm{9-5}; // width } // A8.6.18 BFI - Bitfield insert (Encoding A1) -def BFI : I<(outs GPR:$dst), (ins GPR:$src, GPR:$val, bf_inv_mask_imm:$imm), +def BFI : I<(outs GPR:$Rd), (ins GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm), AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi, - "bfi", "\t$dst, $val, $imm", "$src = $dst", - [(set GPR:$dst, (ARMbfi GPR:$src, GPR:$val, + "bfi", "\t$Rd, $Rn, $imm", "$src = $Rd", + [(set GPR:$Rd, (ARMbfi GPR:$src, GPR:$Rn, bf_inv_mask_imm:$imm))]>, Requires<[IsARM, HasV6T2]> { + bits<4> Rd; + bits<4> Rn; + bits<10> imm; let Inst{27-21} = 0b0111110; let Inst{6-4} = 0b001; // Rn: Inst{3-0} != 15 + let Inst{15-12} = Rd; + let Inst{11-7} = imm{4-0}; // lsb + let Inst{20-16} = imm{9-5}; // width + let Inst{3-0} = Rn; } def MVNr : AsI1<0b1111, (outs GPR:$dst), (ins GPR:$src), DPFrm, IIC_iMVNr, diff --git a/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp b/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp index ea7789c073c2..f0680e82508d 100644 --- a/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/llvm/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -88,6 +88,8 @@ public: return MI.getOperand(Op).getImm() - 1; } + unsigned getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op) const; + unsigned getNumFixupKinds() const { assert(0 && "ARMMCCodeEmitter::getNumFixupKinds() not yet implemented."); return 0; @@ -238,6 +240,18 @@ unsigned ARMMCCodeEmitter::getSORegOpValue(const MCInst &MI, return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7; } +unsigned ARMMCCodeEmitter::getBitfieldInvertedMaskOpValue(const MCInst &MI, + unsigned Op) const { + // 10 bits. lower 5 bits are are the lsb of the mask, high five bits are the + // msb of the mask. + const MCOperand &MO = MI.getOperand(Op); + uint32_t v = ~MO.getImm(); + uint32_t lsb = CountTrailingZeros_32(v); + uint32_t msb = (32 - CountLeadingZeros_32 (v)) - 1; + assert (v != 0 && lsb < 32 && msb < 32 && "Illegal bitfield mask!"); + return lsb | (msb << 5); +} + void ARMMCCodeEmitter:: EncodeInstruction(const MCInst &MI, raw_ostream &OS, SmallVectorImpl &Fixups) const { diff --git a/llvm/test/MC/ARM/simple-encoding.ll b/llvm/test/MC/ARM/simple-encoding.ll index 650990bfc497..e4ac2f58915e 100644 --- a/llvm/test/MC/ARM/simple-encoding.ll +++ b/llvm/test/MC/ARM/simple-encoding.ll @@ -114,4 +114,11 @@ entry: ret i32 %mul } +define i32 @f12(i32 %a) { +; CHECK: f12: +; CHECK: bfc r0, #4, #20 @ encoding: [0x1f,0x02,0xd7,0xe7] + %tmp = and i32 %a, 4278190095 + ret i32 %tmp +} + declare void @llvm.trap() nounwind