[llvm-commits] [llvm] r116377 - in /llvm/trunk/lib/Target/ARM: ARMCodeEmitter.cpp ARMInstrInfo.td ARMMCCodeEmitter.cpp

Jim Grosbach grosbach at apple.com
Tue Oct 12 16:53:58 PDT 2010


Author: grosbach
Date: Tue Oct 12 18:53:58 2010
New Revision: 116377

URL: http://llvm.org/viewvc/llvm-project?rev=116377&view=rev
Log:
Add the rest of the ARM so_reg encoding options (register shifted register)
and move to a custom operand encoder. Remove the last of the special handling
stuff from ARMMCCodeEmitter::EncodeInstruction.

Modified:
    llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
    llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=116377&r1=116376&r2=116377&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue Oct 12 18:53:58 2010
@@ -168,6 +168,8 @@
       const { return 0; }
     unsigned getSOImmOpValue(const MachineInstr &MI, unsigned Op)
       const { return 0; }
+    unsigned getSORegOpValue(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

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=116377&r1=116376&r2=116377&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Tue Oct 12 18:53:58 2010
@@ -313,6 +313,7 @@
 def so_reg : Operand<i32>,    // reg reg imm
              ComplexPattern<i32, 3, "SelectShifterOperandReg",
                             [shl,srl,sra,rotr]> {
+  string EncoderMethod = "getSORegOpValue";
   let PrintMethod = "printSORegOperand";
   let MIOperandInfo = (ops GPR, GPR, i32imm);
 }
@@ -498,14 +499,14 @@
     let Inst{15-12} = Rd;
     let Inst{19-16} = Rn;
   }
-  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))]> {
+  def rs : AsI1<opcod, (outs GPR:$Rd), (ins GPR:$Rn, so_reg:$shift), DPSoRegFrm,
+               iis, opc, "\t$Rd, $Rn, $shift",
+               [(set GPR:$Rd, (opnode GPR:$Rn, so_reg:$shift))]> {
     bits<4> Rd;
     bits<4> Rn;
-    bits<4> Rm;
+    bits<12> shift;
     let Inst{25} = 0;
-    let Inst{3-0} = Rm;
+    let Inst{11-0} = shift;
     let Inst{15-12} = Rd;
     let Inst{19-16} = Rn;
   }

Modified: llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp?rev=116377&r1=116376&r2=116377&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMMCCodeEmitter.cpp Tue Oct 12 18:53:58 2010
@@ -55,6 +55,7 @@
     // '1' respectively.
     return MI.getOperand(Op).getReg() == ARM::CPSR;
   }
+
   /// getSOImmOpValue - Return an encoded 12-bit shifted-immediate value.
   unsigned getSOImmOpValue(const MCInst &MI, unsigned Op) const {
     unsigned SoImm = MI.getOperand(Op).getImm();
@@ -70,6 +71,9 @@
     return Binary;
   }
 
+  /// getSORegOpValue - Return an encoded so_reg shifted register value.
+  unsigned getSORegOpValue(const MCInst &MI, unsigned Op) const;
+
   unsigned getNumFixupKinds() const {
     assert(0 && "ARMMCCodeEmitter::getNumFixupKinds() not yet implemented.");
     return 0;
@@ -137,6 +141,76 @@
   return 0;
 }
 
+
+unsigned ARMMCCodeEmitter::getSORegOpValue(const MCInst &MI,
+                                           unsigned OpIdx) const {
+  // Sub-operands are [reg, reg, imm]. The first register is Rm, the reg
+  // to be shifted. The second is either Rs, the amount to shift by, or
+  // reg0 in which case the imm contains the amount to shift by.
+  // {3-0} = Rm.
+  // {4} = 1 if reg shift, 0 if imm shift
+  // {6-5} = type
+  //    If reg shift:
+  //      {7} = 0
+  //      {11-8} = Rs
+  //    else (imm shift)
+  //      {11-7} = imm
+
+  const MCOperand &MO  = MI.getOperand(OpIdx);
+  const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
+  const MCOperand &MO2 = MI.getOperand(OpIdx + 2);
+  ARM_AM::ShiftOpc SOpc = ARM_AM::getSORegShOp(MO2.getImm());
+
+  // Encode Rm.
+  unsigned Binary = getARMRegisterNumbering(MO.getReg());
+
+  // Encode the shift opcode.
+  unsigned SBits = 0;
+  unsigned Rs = MO1.getReg();
+  if (Rs) {
+    // Set shift operand (bit[7:4]).
+    // LSL - 0001
+    // LSR - 0011
+    // ASR - 0101
+    // ROR - 0111
+    // RRX - 0110 and bit[11:8] clear.
+    switch (SOpc) {
+    default: llvm_unreachable("Unknown shift opc!");
+    case ARM_AM::lsl: SBits = 0x1; break;
+    case ARM_AM::lsr: SBits = 0x3; break;
+    case ARM_AM::asr: SBits = 0x5; break;
+    case ARM_AM::ror: SBits = 0x7; break;
+    case ARM_AM::rrx: SBits = 0x6; break;
+    }
+  } else {
+    // Set shift operand (bit[6:4]).
+    // LSL - 000
+    // LSR - 010
+    // ASR - 100
+    // ROR - 110
+    switch (SOpc) {
+    default: llvm_unreachable("Unknown shift opc!");
+    case ARM_AM::lsl: SBits = 0x0; break;
+    case ARM_AM::lsr: SBits = 0x2; break;
+    case ARM_AM::asr: SBits = 0x4; break;
+    case ARM_AM::ror: SBits = 0x6; break;
+    }
+  }
+  Binary |= SBits << 4;
+  if (SOpc == ARM_AM::rrx)
+    return Binary;
+
+  // Encode the shift operation Rs or shift_imm (except rrx).
+  if (Rs) {
+    // Encode Rs bit[11:8].
+    assert(ARM_AM::getSORegOffset(MO2.getImm()) == 0);
+    return Binary | (getARMRegisterNumbering(Rs) << ARMII::RegRsShift);
+  }
+
+  // Encode shift_imm bit[11:7].
+  return Binary | ARM_AM::getSORegOffset(MO2.getImm()) << 7;
+}
+
 void ARMMCCodeEmitter::
 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
                   SmallVectorImpl<MCFixup> &Fixups) const {
@@ -151,27 +225,9 @@
     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.
-  // Similarly, operands that are encoded as other than their literal
-  // values in the MI.
   unsigned Value = getBinaryCodeForInstr(MI);
   switch (Opcode) {
   default: break;
-  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 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;
-    break;
-  }
   }
   EmitConstant(Value, 4, CurByte, OS);
 }





More information about the llvm-commits mailing list