Apparently, the "regType" and "regClass" used in the Sparc backend are not both
authorMisha Brukman <brukman+llvm@gmail.com>
Thu, 3 Jul 2003 18:36:47 +0000 (18:36 +0000)
committerMisha Brukman <brukman+llvm@gmail.com>
Thu, 3 Jul 2003 18:36:47 +0000 (18:36 +0000)
correct: empirically, "regType" is wrong for a number of registers. Thus, one
can only rely on the "regClass" to figure out what kind of register one is
dealing with.

This change switches to using only "regClass" and adds a few extra DEBUG() print
statements and a few clean-ups in comments and code, mostly minor.

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

lib/Target/SparcV9/SparcV9CodeEmitter.cpp
lib/Target/SparcV9/SparcV9CodeEmitter.h

index 619a014b4168f47eff98eca35b71b8ad2dea1bfb..91a8adea1258e54f4accbf73a7abc4639758bc93 100644 (file)
@@ -334,9 +334,9 @@ bool SparcV9CodeEmitter::isFPInstr(MachineInstr &MI) {
       unsigned fakeReg = MO.getReg(), realReg, regClass, regType;
       regType = TM.getRegInfo().getRegType(fakeReg);
       // At least map fakeReg into its class
-      fakeReg = TM.getRegInfo().getClassRegNum(fakeReg, regClass);
-      if (regClass == UltraSparcRegInfo::FPSingleRegType ||
-          regClass == UltraSparcRegInfo::FPDoubleRegType)
+      // fakeReg = TM.getRegInfo().getClassRegNum(fakeReg, regClass);
+      if (regType == UltraSparcRegInfo::FPSingleRegType ||
+          regType == UltraSparcRegInfo::FPDoubleRegType)
         return true;
     }
   }
@@ -344,9 +344,9 @@ bool SparcV9CodeEmitter::isFPInstr(MachineInstr &MI) {
 }
 
 unsigned 
-SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
-                                  MachineInstr &MI) {
-  switch (regClass) {
+SparcV9CodeEmitter::getRealRegNumByType(unsigned fakeReg, unsigned regType,
+                                        MachineInstr &MI) {
+  switch (regType) {
   case UltraSparcRegInfo::IntRegType: {
     // Sparc manual, p31
     static const unsigned IntRegMap[] = {
@@ -354,11 +354,9 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
       8, 9, 10, 11, 12, 13, 15,
       // "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
       16, 17, 18, 19, 20, 21, 22, 23,
-      // "i0", "i1", "i2", "i3", "i4", "i5",  
-      24, 25, 26, 27, 28, 29,
-      // "i6", "i7",
-      30, 31,
-      // "g0", "g1", "g2", "g3", "g4", "g5",  "g6", "g7", 
+      // "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
+      24, 25, 26, 27, 28, 29, 30, 31,
+      // "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", 
       0, 1, 2, 3, 4, 5, 6, 7,
       // "o6"
       14
@@ -368,15 +366,17 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
     break;
   }
   case UltraSparcRegInfo::FPSingleRegType: {
+    DEBUG(std::cerr << "FP single reg: " << fakeReg << "\n");
     return fakeReg;
   }
   case UltraSparcRegInfo::FPDoubleRegType: {
+    DEBUG(std::cerr << "FP double reg: " << fakeReg << "\n");
     return fakeReg;
   }
   case UltraSparcRegInfo::FloatCCRegType: {
     /* These are laid out %fcc0 - %fcc3 => 0 - 3, so are correct */
+    DEBUG(std::cerr << "FP CC reg: " << fakeReg << "\n");
     return fakeReg;
-
   }
   case UltraSparcRegInfo::IntCCRegType: {
     static const unsigned FPInstrIntCCReg[]  = { 6 /* xcc */, 4  /* icc */ };
@@ -384,11 +384,13 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
     
     if (isFPInstr(MI)) {
       assert(fakeReg < sizeof(FPInstrIntCCReg)/sizeof(FPInstrIntCCReg[0])
-             && "Int CC register out of bounds for FPInstr IntCCReg map");      
+             && "FP CC register out of bounds for FPInstr IntCCReg map");      
+      DEBUG(std::cerr << "FP instr, IntCC reg: " << FPInstrIntCCReg[fakeReg] << "\n");
       return FPInstrIntCCReg[fakeReg];
     } else {
       assert(fakeReg < sizeof(IntInstrIntCCReg)/sizeof(IntInstrIntCCReg[0])
              && "Int CC register out of bounds for IntInstr IntCCReg map");
+      DEBUG(std::cerr << "FP instr, IntCC reg: " << IntInstrIntCCReg[fakeReg] << "\n");
       return IntInstrIntCCReg[fakeReg];
     }
   }
@@ -398,6 +400,60 @@ SparcV9CodeEmitter::getRealRegNum(unsigned fakeReg, unsigned regClass,
   }
 }
 
+unsigned 
+SparcV9CodeEmitter::getRealRegNumByClass(unsigned fakeReg, unsigned regClass,
+                                         MachineInstr &MI) {
+  switch (regClass) {
+  case UltraSparcRegInfo::IntRegClassID: {
+    // Sparc manual, p31
+    static const unsigned IntRegMap[] = {
+      // "o0", "o1", "o2", "o3", "o4", "o5",       "o7",
+      8, 9, 10, 11, 12, 13, 15,
+      // "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
+      16, 17, 18, 19, 20, 21, 22, 23,
+      // "i0", "i1", "i2", "i3", "i4", "i5", "i6", "i7",
+      24, 25, 26, 27, 28, 29, 30, 31,
+      // "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", 
+      0, 1, 2, 3, 4, 5, 6, 7,
+      // "o6"
+      14
+    }; 
+    return IntRegMap[fakeReg];
+    break;
+  }
+  case UltraSparcRegInfo::FloatRegClassID: {
+    DEBUG(std::cerr << "FP reg: " << fakeReg << "\n");
+    return fakeReg;
+  }
+  case UltraSparcRegInfo::IntCCRegClassID: {
+    static const unsigned FPInstrIntCCReg[]  = { 6 /* xcc */, 4  /* icc */ };
+    static const unsigned IntInstrIntCCReg[] = { 2 /* xcc */, 0  /* icc */ };
+    
+    if (isFPInstr(MI)) {
+      assert(fakeReg < sizeof(FPInstrIntCCReg)/sizeof(FPInstrIntCCReg[0])
+             && "FP CC register out of bounds for FPInstr IntCCReg map");      
+      DEBUG(std::cerr << "FP instr, IntCC reg: " << FPInstrIntCCReg[fakeReg] << "\n");
+      return FPInstrIntCCReg[fakeReg];
+    } else {
+      assert(fakeReg < sizeof(IntInstrIntCCReg)/sizeof(IntInstrIntCCReg[0])
+             && "Int CC register out of bounds for IntInstr IntCCReg map");
+      DEBUG(std::cerr << "FP instr, IntCC reg: " << IntInstrIntCCReg[fakeReg] << "\n");
+      return IntInstrIntCCReg[fakeReg];
+    }
+  }
+  case UltraSparcRegInfo::FloatCCRegClassID: {
+    /* These are laid out %fcc0 - %fcc3 => 0 - 3, so are correct */
+    DEBUG(std::cerr << "FP CC reg: " << fakeReg << "\n");
+    return fakeReg;
+  }
+  default:
+    assert(0 && "Invalid unified register number in getRegType");
+    return fakeReg;
+  }
+}
+
+
 int64_t SparcV9CodeEmitter::getMachineOpValue(MachineInstr &MI,
                                               MachineOperand &MO) {
   int64_t rv = 0; // Return value; defaults to 0 for unhandled cases
@@ -477,19 +533,22 @@ int64_t SparcV9CodeEmitter::getMachineOpValue(MachineInstr &MI,
   } else if (MO.isPhysicalRegister() ||
              MO.getType() == MachineOperand::MO_CCRegister)
   {
-    // This is necessary because the Sparc doesn't actually lay out registers
-    // in the real fashion -- it skips those that it chooses not to allocate,
-    // i.e. those that are the SP, etc.
-    unsigned fakeReg = MO.getReg(), realReg, regClass, regType;
-    regType = TM.getRegInfo().getRegType(fakeReg);
+    // This is necessary because the Sparc backend doesn't actually lay out
+    // registers in the real fashion -- it skips those that it chooses not to
+    // allocate, i.e. those that are the FP, SP, etc.
+    unsigned fakeReg = MO.getAllocatedRegNum(), regClass, regType;
+    unsigned realRegByClass; //realRegByType, 
+    const TargetRegInfo &RI = TM.getRegInfo();
+    DEBUG(std::cerr << std::dec << "LLC: " << fakeReg << " => "
+                    << RI.getUnifiedRegName(fakeReg) << "\n");
+    regType = RI.getRegType(fakeReg);
     // At least map fakeReg into its class
-    fakeReg = TM.getRegInfo().getClassRegNum(fakeReg, regClass);
-    // Find the real register number for use in an instruction
-    /////realReg = getRealRegNum(fakeReg, regClass, MI);
-    realReg = getRealRegNum(fakeReg, regType, MI);
-    DEBUG(std::cerr << MO << ": Reg[" << std::dec << fakeReg << "] = "
-                    << realReg << "\n");
-    rv = realReg;
+    fakeReg = RI.getClassRegNum(fakeReg, regClass);
+    //realRegByType = getRealRegNumByType(fakeReg, regType, MI);
+    realRegByClass = getRealRegNumByClass(fakeReg, regClass, MI);
+    DEBUG(std::cerr << MO << ": Reg[" << std::dec << fakeReg << "] = by class: "
+                    << realRegByClass << "\n");
+    rv = realRegByClass;
   } else if (MO.isImmediate()) {
     rv = MO.getImmedValue();
     DEBUG(std::cerr << "immed: " << rv << "\n");
@@ -561,8 +620,7 @@ bool SparcV9CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
   {
     Constant *C = (Constant*)*I;
     unsigned idx = MCP.getConstantPoolIndex(C);
-    DEBUG(std::cerr << "Mapping constant 0x" << (intptr_t)C << " to " 
-                    << idx << "\n");
+    DEBUG(std::cerr << "Constant[" << idx << "] = 0x" << (intptr_t)C << "\n");
     ConstantMap[C] = idx;
   }  
   MCE.emitConstantPool(&MCP);
@@ -571,31 +629,24 @@ bool SparcV9CodeEmitter::runOnMachineFunction(MachineFunction &MF) {
     emitBasicBlock(*I);
   MCE.finishFunction(MF);
 
-  DEBUG(std::cerr << "Finishing function " << MF.getFunction()->getName() 
-                  << "\n");
+  DEBUG(std::cerr << "Finishing fn " << MF.getFunction()->getName() << "\n");
   ConstantMap.clear();
-  for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
-    long Location = BBLocations[BBRefs[i].first];
-    unsigned *Ref = BBRefs[i].second.first;
-    MachineInstr *MI = BBRefs[i].second.second;
-    DEBUG(std::cerr << "Fixup @" << std::hex << Ref << " to " << Location
-                    << " in instr: " << std::dec << *MI << "\n");
-  }
 
   // Resolve branches to BasicBlocks for the entire function
   for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
     long Location = BBLocations[BBRefs[i].first];
     unsigned *Ref = BBRefs[i].second.first;
     MachineInstr *MI = BBRefs[i].second.second;
-    DEBUG(std::cerr << "attempting to resolve BB: " << i << "\n");
+    DEBUG(std::cerr << "Fixup @ " << std::hex << Ref << " to 0x" << Location
+                    << " in instr: " << std::dec << *MI);
     for (unsigned ii = 0, ee = MI->getNumOperands(); ii != ee; ++ii) {
       MachineOperand &op = MI->getOperand(ii);
       if (op.isPCRelativeDisp()) {
         // the instruction's branch target is made such that it branches to
-        // PC + (br target * 4), so undo that arithmetic here:
+        // PC + (branchTarget * 4), so undo that arithmetic here:
         // Location is the target of the branch
         // Ref is the location of the instruction, and hence the PC
-        unsigned branchTarget = (Location - (long)Ref) >> 2;
+        int64_t branchTarget = (Location - (long)Ref) >> 2;
         // Save the flags.
         bool loBits32=false, hiBits32=false, loBits64=false, hiBits64=false;   
         if (op.opLoBits32()) { loBits32=true; }
index d9a03e5b2314f6d62965c68cddcf54918095c162..7f11a7b439e44fe9efc776c16c20e446cffd1c1f 100644 (file)
@@ -43,13 +43,15 @@ public:
 
 private:    
   int64_t getMachineOpValue(MachineInstr &MI, MachineOperand &MO);
-  unsigned getValueBit(int64_t Val, unsigned bit);
+  inline unsigned getValueBit(int64_t Val, unsigned bit);
   void emitBasicBlock(MachineBasicBlock &MBB);
   void* getGlobalAddress(GlobalValue *V, MachineInstr &MI,
                          bool isPCRelative);
   bool isFPInstr(MachineInstr &MI);
-  unsigned getRealRegNum(unsigned fakeReg, unsigned regClass,
-                         MachineInstr &MI);
+  unsigned getRealRegNumByType(unsigned fakeReg, unsigned regType,
+                               MachineInstr &MI);
+  unsigned getRealRegNumByClass(unsigned fakeReg, unsigned regClass,
+                                MachineInstr &MI);
 
 };