Add encoder method for ARM load/store shifted register offset operands.
authorJim Grosbach <grosbach@apple.com>
Tue, 9 Nov 2010 17:20:53 +0000 (17:20 +0000)
committerJim Grosbach <grosbach@apple.com>
Tue, 9 Nov 2010 17:20:53 +0000 (17:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118513 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMCodeEmitter.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMMCCodeEmitter.cpp

index 15b3aab5b3acb4c206d400f28589ef6e904e2e9d..7f073d7c0a1e16075918a82f7a9e65147552a56c 100644 (file)
@@ -177,6 +177,8 @@ namespace {
       const { return 0; }
     unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI,
                                             unsigned Op) const { return 0; }
+    uint32_t getLdStSORegOpValue(const MachineInstr &MI, unsigned OpIdx)
+      const { return 0; }
 
     unsigned getAddrModeImm12OpValue(const MachineInstr &MI, unsigned Op)
       const {
index 7c7257900fd916e1c43419ede17229219225e484..69f8a6459ef7223281a046fa3a6a00cff6d51f4a 100644 (file)
@@ -415,8 +415,8 @@ def addrmode_imm12 : Operand<i32>,
 //
 def ldst_so_reg : Operand<i32>,
                   ComplexPattern<i32, 3, "SelectLdStSOReg", []> {
+  string EncoderMethod = "getLdStSORegOpValue";
   // FIXME: Simplify the printer
-  // FIXME: Add EncoderMethod for this addressing mode
   let PrintMethod = "printAddrMode2Operand";
   let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
 }
index 94fe8fc0e0e8cdc10009ddc776be1afe222e1721..7b0bf12bffcd06baf55f49249ce871a844a15822 100644 (file)
@@ -77,6 +77,11 @@ public:
   uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
                                    SmallVectorImpl<MCFixup> &Fixups) const;
 
+  /// getLdStSORegOpValue - Return encoding info for 'reg +/- reg shop imm'
+  /// operand as needed by load/store instructions.
+  uint32_t getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
+                               SmallVectorImpl<MCFixup> &Fixups) const;
+
   /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm8' operand.
   uint32_t getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,
                                SmallVectorImpl<MCFixup> &Fixups) const;
@@ -254,6 +259,46 @@ getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx,
   return Binary;
 }
 
+uint32_t ARMMCCodeEmitter::
+getLdStSORegOpValue(const MCInst &MI, unsigned OpIdx,
+                    SmallVectorImpl<MCFixup> &Fixups) const {
+  const MCOperand &MO = MI.getOperand(OpIdx);
+  const MCOperand &MO1 = MI.getOperand(OpIdx+1);
+  const MCOperand &MO2 = MI.getOperand(OpIdx+2);
+  unsigned Rn = getARMRegisterNumbering(MO.getReg());
+  unsigned Rm = getARMRegisterNumbering(MO1.getReg());
+  ARM_AM::ShiftOpc ShOp = ARM_AM::getAM2ShiftOpc(MO2.getImm());
+  unsigned ShImm = ARM_AM::getAM2Offset(MO2.getImm());
+  bool isAdd = ARM_AM::getAM2Op(MO2.getImm()) == ARM_AM::add;
+  unsigned SBits;
+  // LSL - 00
+  // LSR - 01
+  // ASR - 10
+  // ROR - 11
+  switch (ShOp) {
+  default: llvm_unreachable("Unknown shift opc!");
+  case ARM_AM::lsl: SBits = 0x0; break;
+  case ARM_AM::lsr: SBits = 0x1; break;
+  case ARM_AM::asr: SBits = 0x2; break;
+  case ARM_AM::ror: SBits = 0x3; break;
+  }
+
+  // {16-13} = Rn
+  // {12}    = isAdd
+  // {11-0}  = shifter
+  //  {3-0}  = Rm
+  //  {4}    = 0
+  //  {6-5}  = type
+  //  {11-7} = imm
+  int64_t Binary = Rm;
+  Binary |= Rn << 13;
+  Binary |= SBits << 5;
+  Binary |= ShImm << 7;
+  if (isAdd)
+    Binary |= 1 << 12;
+  return Binary;
+}
+
 /// getAddrMode5OpValue - Return encoding info for 'reg +/- imm12' operand.
 uint32_t ARMMCCodeEmitter::
 getAddrMode5OpValue(const MCInst &MI, unsigned OpIdx,