[llvm-commits] [llvm] r59102 - in /llvm/trunk/lib/Target/ARM: ARMCodeEmitter.cpp ARMInstrVFP.td ARMRegisterInfo.cpp ARMRegisterInfo.h

Evan Cheng evan.cheng at apple.com
Tue Nov 11 18:19:38 PST 2008


Author: evancheng
Date: Tue Nov 11 20:19:38 2008
New Revision: 59102

URL: http://llvm.org/viewvc/llvm-project?rev=59102&view=rev
Log:
Fix encoding of single-precision VFP registers.

Modified:
    llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
    llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
    llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp
    llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h

Modified: llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp?rev=59102&r1=59101&r2=59102&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMCodeEmitter.cpp Tue Nov 11 20:19:38 2008
@@ -1053,9 +1053,16 @@
          (Binary & ARMII::M_BitShift) == 0 && "VFP encoding bug!");
 
   // Encode Dd / Sd.
-  unsigned RegD = getMachineOpValue(MI, OpIdx++);
-  Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
-  Binary |= (RegD & 0x10) << ARMII::D_BitShift;
+  unsigned RegD = MI.getOperand(OpIdx++).getReg();
+  bool isSPVFP = false;
+  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegD               << ARMII::RegRdShift;
+  else {
+    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
+    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
+  }
+    
 
   // If this is a two-address operand, skip it, e.g. FMACD.
   if (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1)
@@ -1063,15 +1070,27 @@
 
   // Encode Dn / Sn.
   if ((TID.TSFlags & ARMII::FormMask) == ARMII::VFPBinaryFrm) {
-    unsigned RegN = getMachineOpValue(MI, OpIdx++);
-    Binary |= (RegN & 0x0f) << ARMII::RegRnShift;
-    Binary |= (RegN & 0x10) << ARMII::N_BitShift;
+    unsigned RegN = MI.getOperand(OpIdx++).getReg();
+    isSPVFP = false;
+    RegN = ARMRegisterInfo::getRegisterNumbering(RegN, isSPVFP);
+    if (!isSPVFP)
+      Binary |=   RegN               << ARMII::RegRnShift;
+    else {
+      Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift;
+      Binary |=  (RegN & 0x01)       << ARMII::N_BitShift;
+    }
   }
 
   // Encode Dm / Sm.
-  unsigned RegM = getMachineOpValue(MI, OpIdx++);
-  Binary |= (RegM & 0x0f);
-  Binary |= (RegM & 0x10) << ARMII::M_BitShift;
+  unsigned RegM = MI.getOperand(OpIdx++).getReg();
+  isSPVFP = false;
+  RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegM;
+  else {
+    Binary |= ((RegM & 0x1E) >> 1);
+    Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
+  }
   
   emitWordLE(Binary);
 }
@@ -1087,41 +1106,65 @@
 
   // FMDRR encodes registers in reverse order.
   unsigned Form = TID.TSFlags & ARMII::FormMask;
-  unsigned OpIdx = (Form == ARMII::VFPConv2Frm) ? 2 : 0;
+  unsigned OpIdx = (Form == ARMII::VFPConv2Frm)
+    ? MI.findFirstPredOperandIdx()-1 : 0;
 
   // Encode Dd / Sd.
-  unsigned RegD = getMachineOpValue(MI, OpIdx);
-  Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
-  Binary |= (RegD & 0x10) << ARMII::D_BitShift;
+  unsigned RegD = MI.getOperand(OpIdx).getReg();
+  bool isSPVFP = false;
+  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegD               << ARMII::RegRdShift;
+  else {
+    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
+    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
+  }
   if (Form == ARMII::VFPConv2Frm)
     --OpIdx;
   else
     ++OpIdx;
 
+  if (Form == ARMII::VFPConv3Frm) {
+    unsigned RegM = MI.getOperand(OpIdx).getReg();
+    isSPVFP = false;
+    RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
+    if (!isSPVFP)
+      Binary |=   RegM;
+    else {
+      Binary |= ((RegM & 0x1E) >> 1);
+      Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
+    }
+
+    emitWordLE(Binary);
+    return;
+  }
+
   // Encode Dn / Sn.
-  if (Form == ARMII::VFPConv1Frm || Form == ARMII::VFPConv2Frm) {
-    unsigned RegN = getMachineOpValue(MI, OpIdx);
-    Binary |= (RegN & 0x0f) << ARMII::RegRnShift;
-    Binary |= (RegN & 0x10) << ARMII::N_BitShift;
-    if (Form == ARMII::VFPConv2Frm)
-      --OpIdx;
-    else
-      ++OpIdx;
-
-    // FMRS / FMSR do not have Rm.
-    if (TID.getNumOperands() > OpIdx && MI.getOperand(OpIdx).isReg()) {
-      unsigned RegM = getMachineOpValue(MI, OpIdx);
-      Binary |= (RegM & 0x0f);
-      Binary |= (RegM & 0x10) << ARMII::M_BitShift;
-    } else if (Form == ARMII::VFPConv2Frm) {
-      // FMDRR encodes definition register in Dm field.
-      Binary |= getMachineOpValue(MI, 0);
+  unsigned RegN = MI.getOperand(OpIdx).getReg();
+  isSPVFP = false;
+  RegN = ARMRegisterInfo::getRegisterNumbering(RegN, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegN               << ARMII::RegRnShift;
+  else {
+    Binary |= ((RegN & 0x1E) >> 1) << ARMII::RegRnShift;
+    Binary |=  (RegN & 0x01)       << ARMII::N_BitShift;
+  }
+  if (Form == ARMII::VFPConv2Frm)
+    --OpIdx;
+  else
+    ++OpIdx;
+
+  // FMRS / FMSR do not have Rm.
+  if (TID.getNumOperands() > OpIdx && MI.getOperand(OpIdx).isReg()) {
+    unsigned RegM = MI.getOperand(OpIdx).getReg();
+    isSPVFP = false;
+    RegM = ARMRegisterInfo::getRegisterNumbering(RegM, isSPVFP);
+    if (!isSPVFP)
+      Binary |=   RegM;
+    else {
+      Binary |= ((RegM & 0x1E) >> 1);
+      Binary |=  (RegM & 0x01)       << ARMII::M_BitShift;
     }
-  } else {
-    assert(Form == ARMII::VFPConv3Frm && "Unsupported format!");
-    unsigned RegM = getMachineOpValue(MI, OpIdx);
-    Binary |= (RegM & 0x0f);
-    Binary |= (RegM & 0x10) << ARMII::M_BitShift;
   }
 
   emitWordLE(Binary);
@@ -1137,9 +1180,15 @@
   unsigned OpIdx = 0;
 
   // Encode Dd / Sd.
-  unsigned RegD = getMachineOpValue(MI, OpIdx++);
-  Binary |= (RegD & 0x0f) << ARMII::RegRdShift;
-  Binary |= (RegD & 0x10) << ARMII::D_BitShift;
+  unsigned RegD = MI.getOperand(OpIdx++).getReg();
+  bool isSPVFP = false;
+  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegD               << ARMII::RegRdShift;
+  else {
+    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
+    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
+  }
 
   // Encode address base.
   const MachineOperand &Base = MI.getOperand(OpIdx++);
@@ -1184,8 +1233,15 @@
     Binary |= 0x1 << ARMII::W_BitShift;
 
   // First register is encoded in Dd.
-  unsigned FirstReg = MI.getOperand(4).getReg();
-  Binary |= ARMRegisterInfo::getRegisterNumbering(FirstReg)<< ARMII::RegRdShift;
+  unsigned RegD = MI.getOperand(4).getReg();
+  bool isSPVFP = false;
+  RegD = ARMRegisterInfo::getRegisterNumbering(RegD, isSPVFP);
+  if (!isSPVFP)
+    Binary |=   RegD               << ARMII::RegRdShift;
+  else {
+    Binary |= ((RegD & 0x1E) >> 1) << ARMII::RegRdShift;
+    Binary |=  (RegD & 0x01)       << ARMII::D_BitShift;
+  }
 
   // Number of registers are encoded in offset field.
   unsigned NumRegs = 1;

Modified: llvm/trunk/lib/Target/ARM/ARMInstrVFP.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrVFP.td?rev=59102&r1=59101&r2=59102&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrVFP.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrVFP.td Tue Nov 11 20:19:38 2008
@@ -223,7 +223,7 @@
                  "fmrs", " $dst, $src",
                  [(set GPR:$dst, (bitconvert SPR:$src))]>;
 
-def FMSR   : AVConv1I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src),
+def FMSR   : AVConv2I<0b11100000, 0b1010, (outs SPR:$dst), (ins GPR:$src),
                  "fmsr", " $dst, $src",
                  [(set SPR:$dst, (bitconvert GPR:$src))]>;
 

Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp?rev=59102&r1=59101&r2=59102&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.cpp Tue Nov 11 20:19:38 2008
@@ -81,6 +81,80 @@
   }
 }
 
+unsigned ARMRegisterInfo::getRegisterNumbering(unsigned RegEnum,
+                                               bool &isSPVFP) {
+  isSPVFP = false;
+
+  using namespace ARM;
+  switch (RegEnum) {
+  default:
+    assert(0 && "Unknown ARM register!");
+    abort();
+  case R0:  case D0:  return 0;
+  case R1:  case D1:  return 1;
+  case R2:  case D2:  return 2;
+  case R3:  case D3:  return 3;
+  case R4:  case D4:  return 4;
+  case R5:  case D5:  return 5;
+  case R6:  case D6:  return 6;
+  case R7:  case D7:  return 7;
+  case R8:  case D8:  return 8;
+  case R9:  case D9:  return 9;
+  case R10: case D10: return 10;
+  case R11: case D11: return 11;
+  case R12: case D12: return 12;
+  case SP:  case D13: return 13;
+  case LR:  case D14: return 14;
+  case PC:  case D15: return 15;
+
+  case S0: case S1: case S2: case S3:
+  case S4: case S5: case S6: case S7: 
+  case S8: case S9: case S10: case S11: 
+  case S12: case S13: case S14: case S15: 
+  case S16: case S17: case S18: case S19: 
+  case S20: case S21: case S22: case S23: 
+  case S24: case S25: case S26: case S27: 
+  case S28: case S29: case S30: case S31:  {
+    isSPVFP = true;
+    switch (RegEnum) {
+    default: return 0; // Avoid compile time warning.
+    case S0: return 0;
+    case S1: return 1;
+    case S2: return 2;
+    case S3: return 3;
+    case S4: return 4;
+    case S5: return 5;
+    case S6: return 6;
+    case S7: return 7;
+    case S8: return 8;
+    case S9: return 9;
+    case S10: return 10;
+    case S11: return 11;
+    case S12: return 12;
+    case S13: return 13;
+    case S14: return 14;
+    case S15: return 15;
+    case S16: return 16;
+    case S17: return 17;
+    case S18: return 18;
+    case S19: return 19;
+    case S20: return 20;
+    case S21: return 21;
+    case S22: return 22;
+    case S23: return 23;
+    case S24: return 24;
+    case S25: return 25;
+    case S26: return 26;
+    case S27: return 27;
+    case S28: return 28;
+    case S29: return 29;
+    case S30: return 30;
+    case S31: return 31;
+    }
+  }
+  }
+}
+
 ARMRegisterInfo::ARMRegisterInfo(const TargetInstrInfo &tii,
                                  const ARMSubtarget &sti)
   : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),

Modified: llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h?rev=59102&r1=59101&r2=59102&view=diff

==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMRegisterInfo.h Tue Nov 11 20:19:38 2008
@@ -44,6 +44,10 @@
   /// ARM::LR, return the number that it corresponds to (e.g. 14).
   static unsigned getRegisterNumbering(unsigned RegEnum);
 
+  /// Same as previous getRegisterNumbering except it returns true in isSPVFP
+  /// if the register is a single precision VFP register.
+  static unsigned getRegisterNumbering(unsigned RegEnum, bool &isSPVFP);
+
   /// Code Generation virtual methods...
   const unsigned *getCalleeSavedRegs(const MachineFunction *MF = 0) const;
 





More information about the llvm-commits mailing list