MC machine encoding for simple aritmetic instructions that use a shifted
authorJim Grosbach <grosbach@apple.com>
Mon, 11 Oct 2010 23:16:21 +0000 (23:16 +0000)
committerJim Grosbach <grosbach@apple.com>
Mon, 11 Oct 2010 23:16:21 +0000 (23:16 +0000)
register operand.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116259 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMAddressingModes.h
lib/Target/ARM/ARMBaseInstrInfo.h
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMMCCodeEmitter.cpp
test/MC/ARM/simple-encoding.ll

index db481005b3a4c65483ad0cf0493bfcc9bd43f314..7f68c8109431decada2fa6ea23e5d1902d42375d 100644 (file)
@@ -50,6 +50,16 @@ namespace ARM_AM {
     }
   }
 
+  static inline unsigned getShiftOpcEncoding(ShiftOpc Op) {
+    switch (Op) {
+    default: assert(0 && "Unknown shift opc!");
+    case ARM_AM::asr: return 2;
+    case ARM_AM::lsl: return 0;
+    case ARM_AM::lsr: return 1;
+    case ARM_AM::ror: return 3;
+    }
+  }
+
   static inline ShiftOpc getShiftOpcForNode(SDValue N) {
     switch (N.getOpcode()) {
     default:          return ARM_AM::no_shift;
index 1c6aef1bd66b246cc052aaabd6988f0bf959636c..cbfd7529b13afdf6002213c3245c7b2a7fae2593 100644 (file)
@@ -160,6 +160,11 @@ namespace ARMII {
     //===------------------------------------------------------------------===//
     // Field shifts - such shifts are used to set field while generating
     // machine instructions.
+    //
+    // FIXME: This list will need adjusting/fixing as the MC code emitter
+    // takes shape and the ARMCodeEmitter.cpp bits go away.
+    ShiftTypeShift = 4,
+
     M_BitShift     = 5,
     ShiftImmShift  = 5,
     ShiftShift     = 7,
index 2fda464d64687b9e330dce936f23fed60ae18a73..2ed2bfac1036af29f3d6262dba8625bdd6b2919b 100644 (file)
@@ -494,7 +494,13 @@ multiclass AsI1_bin_irs<bits<4> opcod, string opc,
   def rs : AsI1<opcod, (outs GPR:$dst), (ins GPR:$a, so_reg:$b), DPSoRegFrm,
                iis, opc, "\t$dst, $a, $b",
                [(set GPR:$dst, (opnode GPR:$a, so_reg:$b))]> {
+    bits<4> Rd;
+    bits<4> Rn;
+    bits<4> Rm;
     let Inst{25} = 0;
+    let Inst{3-0} = Rm;
+    let Inst{15-12} = Rd;
+    let Inst{19-16} = Rn;
   }
 }
 
index fce1f3914def7b7d187ef2f8df6c0e5b12aac148..ad87b386d3d1a4b453cde41c26f9a22e901251f7 100644 (file)
@@ -13,6 +13,7 @@
 
 #define DEBUG_TYPE "arm-emitter"
 #include "ARM.h"
+#include "ARMAddressingModes.h"
 #include "ARMInstrInfo.h"
 #include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCExpr.h"
@@ -139,8 +140,27 @@ EncodeInstruction(const MCInst &MI, raw_ostream &OS,
     return;
 
   ++MCNumEmitted;  // Keep track of the # of mi's emitted
+  // FIXME: TableGen doesn't deal well with operands that expand to multiple
+  // machine instruction operands, so for now we'll fix those up here.
   switch (Opcode) {
-  //FIXME: Any non-pseudos that need special handling, if there are any...
+  case ARM::ADDrs:
+  case ARM::ANDrs:
+  case ARM::BICrs:
+  case ARM::EORrs:
+  case ARM::ORRrs:
+  case ARM::SUBrs: {
+    // The so_reg operand needs the shift ammount encoded.
+    unsigned Value = getBinaryCodeForInstr(MI);
+    unsigned ShVal = MI.getOperand(4).getImm();
+    unsigned ShType = ARM_AM::getShiftOpcEncoding(ARM_AM::getSORegShOp(ShVal));
+    unsigned ShAmt = ARM_AM::getSORegOffset(ShVal);
+
+    Value |= ShType << ARMII::ShiftTypeShift;
+    Value |= ShAmt << ARMII::ShiftShift;
+
+    EmitConstant(Value, 4, CurByte, OS);
+    break;
+  }
   default: {
     unsigned Value = getBinaryCodeForInstr(MI);
     EmitConstant(Value, 4, CurByte, OS);
index 2da4e74c89a7d632f47bfb834e203c68af2275bd..4c23c7e7f2694267d80823538f8d3ccaddbf1ab9 100644 (file)
@@ -8,8 +8,8 @@
 define i32 @foo(i32 %a, i32 %b) nounwind ssp {
 entry:
 ; CHECK: foo
-; CHECK: 0xf0,0x00,0xf0,0x07
-; CHECK: 0x1e,0xff,0x2f,0xe1
+; CHECK: trap                         @ encoding: [0xf0,0x00,0xf0,0x07]
+; CHECK: bx lr                        @ encoding: [0x1e,0xff,0x2f,0xe1]
 
   tail call void @llvm.trap()
   ret i32 undef
@@ -18,9 +18,21 @@ entry:
 define i32 @f2(i32 %a, i32 %b) nounwind readnone ssp {
 entry:
 ; CHECK: f2
-; CHECK: 0x00,0x00,0x81,0xe0
-; CHECK: 0x1e,0xff,0x2f,0xe1
+; CHECK: add  r0, r1, r0              @ encoding: [0x00,0x00,0x81,0xe0]
+; CHECK: bx lr                        @ encoding: [0x1e,0xff,0x2f,0xe1]
   %add = add nsw i32 %b, %a
   ret i32 %add
 }
+
+
+define i32 @f3(i32 %a, i32 %b) nounwind readnone ssp {
+entry:
+; CHECK: f3
+; CHECK: add  r0, r0, r1, lsl #3      @ encoding: [0x81,0x01,0x80,0xe0]
+; CHECK: bx lr                        @ encoding: [0x1e,0xff,0x2f,0xe1]
+  %mul = shl i32 %b, 3
+  %add = add nsw i32 %mul, %a
+  ret i32 %add
+}
+
 declare void @llvm.trap() nounwind