diff options
author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-01-18 20:45:56 +0000 |
---|---|---|
committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2011-01-18 20:45:56 +0000 |
commit | a461d4222877f43588da38c466145f38dd74e229 (patch) | |
tree | 4b76c21206e79f775997c85bc06796738c0d972d /lib/Target/ARM | |
parent | ff12a8bd999569ce76b3a9f5e167f6e89280e9d9 (diff) | |
download | external_llvm-a461d4222877f43588da38c466145f38dd74e229.zip external_llvm-a461d4222877f43588da38c466145f38dd74e229.tar.gz external_llvm-a461d4222877f43588da38c466145f38dd74e229.tar.bz2 |
Add support for parsing and encoding ARM's official syntax for the BFI instruction
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123770 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM')
-rw-r--r-- | lib/Target/ARM/ARMCodeEmitter.cpp | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 31 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrThumb2.td | 45 | ||||
-rw-r--r-- | lib/Target/ARM/ARMMCCodeEmitter.cpp | 14 |
4 files changed, 79 insertions, 13 deletions
diff --git a/lib/Target/ARM/ARMCodeEmitter.cpp b/lib/Target/ARM/ARMCodeEmitter.cpp index 895ad73..fc12ddc 100644 --- a/lib/Target/ARM/ARMCodeEmitter.cpp +++ b/lib/Target/ARM/ARMCodeEmitter.cpp @@ -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) diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 9909dd0..15949c0 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -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 { diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index fe143af..1bd8530 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -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", diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index 3aa40db..a309122 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -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, @@ -1067,6 +1070,17 @@ getBitfieldInvertedMaskOpValue(const MCInst &MI, unsigned Op, } 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 { // VLDM/VSTM: |