ARM mode encoding information for UBFX and SBFX instructions.
authorJim Grosbach <grosbach@apple.com>
Fri, 15 Oct 2010 17:15:16 +0000 (17:15 +0000)
committerJim Grosbach <grosbach@apple.com>
Fri, 15 Oct 2010 17:15:16 +0000 (17:15 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116588 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMCodeEmitter.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMMCCodeEmitter.cpp
test/MC/ARM/simple-encoding.ll
utils/TableGen/EDEmitter.cpp

index b5f534f36a8f8d5dc2c6c6a6e65a25c0edfa670c..910e438f0f50ee7e482167ead34d85849ce75a53 100644 (file)
@@ -172,6 +172,8 @@ namespace {
       const { return 0; }
     unsigned getRotImmOpValue(const MachineInstr &MI, unsigned Op)
       const { return 0; }
+    unsigned getImmMinusOneOpValue(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
index 6e168d5b7aaf6edc7d9d0c635380270c24c61561..832b1363fba149b9ba7dca644d4714363db65a02 100644 (file)
@@ -367,6 +367,13 @@ def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
   return (int32_t)N->getZExtValue() < 32;
 }]>;
 
+/// imm0_31_m1 - Matches and prints like imm0_31, but encodes as 'value - 1'.
+def imm0_31_m1 : Operand<i32>, PatLeaf<(imm), [{
+  return (int32_t)N->getZExtValue() < 32;
+}]> {
+  string EncoderMethod = "getImmMinusOneOpValue";
+}
+
 // Define ARM specific addressing modes.
 
 // addrmode2base := reg +/- imm12
@@ -1761,22 +1768,38 @@ defm UXTAH : AI_exta_rrot<0b01101111, "uxtah",
 defm UXTAB16 : AI_exta_rrot_np<0b01101100, "uxtab16">;
 
 
-def SBFX  : I<(outs GPR:$dst),
-              (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
+def SBFX  : I<(outs GPR:$Rd),
+              (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
                AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
-               "sbfx", "\t$dst, $src, $lsb, $width", "", []>,
+               "sbfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
                Requires<[IsARM, HasV6T2]> {
+  bits<4> Rd;
+  bits<4> Rn;
+  bits<5> lsb;
+  bits<5> width;
   let Inst{27-21} = 0b0111101;
   let Inst{6-4}   = 0b101;
+  let Inst{20-16} = width;
+  let Inst{15-12} = Rd;
+  let Inst{11-7}  = lsb;
+  let Inst{3-0}   = Rn;
 }
 
-def UBFX  : I<(outs GPR:$dst),
-              (ins GPR:$src, imm0_31:$lsb, imm0_31:$width),
+def UBFX  : I<(outs GPR:$Rd),
+              (ins GPR:$Rn, imm0_31:$lsb, imm0_31_m1:$width),
                AddrMode1, Size4Bytes, IndexModeNone, DPFrm, IIC_iUNAsi,
-               "ubfx", "\t$dst, $src, $lsb, $width", "", []>,
+               "ubfx", "\t$Rd, $Rn, $lsb, $width", "", []>,
                Requires<[IsARM, HasV6T2]> {
+  bits<4> Rd;
+  bits<4> Rn;
+  bits<5> lsb;
+  bits<5> width;
   let Inst{27-21} = 0b0111111;
   let Inst{6-4}   = 0b101;
+  let Inst{20-16} = width;
+  let Inst{15-12} = Rd;
+  let Inst{11-7}  = lsb;
+  let Inst{3-0}   = Rn;
 }
 
 //===----------------------------------------------------------------------===//
index cafd3f235c3ebfe354fe93bdfac45a80f4c0b922..6132d6df7f31cd05f4c99edad65db1c9a3522e4a 100644 (file)
@@ -84,6 +84,10 @@ public:
     }
   }
 
+  unsigned getImmMinusOneOpValue(const MCInst &MI, unsigned Op) const {
+    return MI.getOperand(Op).getImm() - 1;
+  }
+
   unsigned getNumFixupKinds() const {
     assert(0 && "ARMMCCodeEmitter::getNumFixupKinds() not yet implemented.");
     return 0;
index 3d6358188cc414aafdce273fcfec2d127f2c5db6..650990bfc497c9ddee11919bc2f32f60d5b816f5 100644 (file)
@@ -99,4 +99,19 @@ entry:
   ret i64 %shr
 }
 
+define i32 @f11([1 x i32] %A.coerce0, [1 x i32] %B.coerce0) nounwind readnone ssp {
+entry:
+; CHECK: f11
+; CHECK: ubfx  r1, r1, #8, #5         @ encoding: [0x51,0x14,0xe4,0xe7]
+; CHECK: sbfx  r0, r0, #13, #7        @ encoding: [0xd0,0x06,0xa6,0xe7]
+  %tmp11 = extractvalue [1 x i32] %A.coerce0, 0
+  %tmp4 = extractvalue [1 x i32] %B.coerce0, 0
+  %0 = shl i32 %tmp11, 12
+  %bf.val.sext = ashr i32 %0, 25
+  %1 = lshr i32 %tmp4, 8
+  %bf.clear2 = and i32 %1, 31
+  %mul = mul nsw i32 %bf.val.sext, %bf.clear2
+  ret i32 %mul
+}
+
 declare void @llvm.trap() nounwind
index 8435bb4144db8baaddadb8c66defc53e70b943af..678ec6a8c6f37d1512313ff468baf7606cda8b5c 100644 (file)
@@ -575,6 +575,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
   IMM("msr_mask");
   IMM("neg_zero");
   IMM("imm0_31");
+  IMM("imm0_31_m1");
   IMM("nModImm");
   IMM("imm0_4095");
   IMM("jt2block_operand");