aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM
diff options
context:
space:
mode:
authorBruno Cardoso Lopes <bruno.cardoso@gmail.com>2011-01-18 20:45:56 +0000
committerBruno Cardoso Lopes <bruno.cardoso@gmail.com>2011-01-18 20:45:56 +0000
commita461d4222877f43588da38c466145f38dd74e229 (patch)
tree4b76c21206e79f775997c85bc06796738c0d972d /lib/Target/ARM
parentff12a8bd999569ce76b3a9f5e167f6e89280e9d9 (diff)
downloadexternal_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.cpp2
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td31
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td45
-rw-r--r--lib/Target/ARM/ARMMCCodeEmitter.cpp14
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: