[llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9CodeEmitter.h SparcV9CodeEmitter.cpp

Misha Brukman brukman at cs.uiuc.edu
Thu Jul 3 13:37:01 PDT 2003


Changes in directory llvm/lib/Target/Sparc:

SparcV9CodeEmitter.h updated: 1.7 -> 1.8
SparcV9CodeEmitter.cpp updated: 1.17 -> 1.18

---
Log message:

Apparently, the "regType" and "regClass" used in the Sparc backend are not both
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.


---
Diffs of the changes:

Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.h
diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.7 llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.8
--- llvm/lib/Target/Sparc/SparcV9CodeEmitter.h:1.7	Thu Jun  5 15:52:06 2003
+++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.h	Thu Jul  3 13:36:47 2003
@@ -43,13 +43,15 @@
 
 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);
 
 };
 


Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp
diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.17 llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.18
--- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.17	Fri Jun  6 04:53:28 2003
+++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp	Thu Jul  3 13:36:47 2003
@@ -334,9 +334,9 @@
       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 @@
 }
 
 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 @@
       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 @@
     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 @@
     
     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 @@
   }
 }
 
+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 @@
   } 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 @@
   {
     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 @@
     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; }





More information about the llvm-commits mailing list