[cfe-commits] r104816 - /cfe/trunk/lib/CodeGen/TargetInfo.cpp

John McCall rjmccall at apple.com
Wed May 26 23:19:26 PDT 2010


Author: rjmccall
Date: Thu May 27 01:19:26 2010
New Revision: 104816

URL: http://llvm.org/viewvc/llvm-project?rev=104816&view=rev
Log:
Implement __builtin_init_dwarf_reg_size_table and __builtin_dwarf_sp_column
for 32-bit MIPS processors.  Hat-tip to rdivacky for providing gcc dumps
on this.


Modified:
    cfe/trunk/lib/CodeGen/TargetInfo.cpp

Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=104816&r1=104815&r2=104816&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Thu May 27 01:19:26 2010
@@ -23,6 +23,18 @@
 using namespace clang;
 using namespace CodeGen;
 
+static void AssignToArrayRange(CodeGen::CGBuilderTy &Builder,
+                               llvm::Value *Array,
+                               llvm::Value *Value,
+                               unsigned FirstIndex,
+                               unsigned LastIndex) {
+  // Alternatively, we could emit this as a loop in the source.
+  for (unsigned I = FirstIndex; I <= LastIndex; ++I) {
+    llvm::Value *Cell = Builder.CreateConstInBoundsGEP1_32(Array, I);
+    Builder.CreateStore(Value, Cell);
+  }
+}
+
 ABIInfo::~ABIInfo() {}
 
 void ABIArgInfo::dump() const {
@@ -621,20 +633,14 @@
   // 0-7 are the eight integer registers;  the order is different
   //   on Darwin (for EH), but the range is the same.
   // 8 is %eip.
-  for (unsigned I = 0, E = 9; I != E; ++I) {
-    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
-    Builder.CreateStore(Four8, Slot);
-  }
+  AssignToArrayRange(Builder, Address, Four8, 0, 8);
 
   if (CGF.CGM.isTargetDarwin()) {
     // 12-16 are st(0..4).  Not sure why we stop at 4.
     // These have size 16, which is sizeof(long double) on
     // platforms with 8-byte alignment for that type.
     llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
-    for (unsigned I = 12, E = 17; I != E; ++I) {
-      llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
-      Builder.CreateStore(Sixteen8, Slot);
-    }
+    AssignToArrayRange(Builder, Address, Sixteen8, 12, 16);
       
   } else {
     // 9 is %eflags, which doesn't get a size on Darwin for some
@@ -645,11 +651,8 @@
     // These have size 12, which is sizeof(long double) on
     // platforms with 4-byte alignment for that type.
     llvm::Value *Twelve8 = llvm::ConstantInt::get(i8, 12);
-    for (unsigned I = 11, E = 17; I != E; ++I) {
-      llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
-      Builder.CreateStore(Twelve8, Slot);
-    }
-  }      
+    AssignToArrayRange(Builder, Address, Twelve8, 11, 16);
+  }
 
   return false;
 }
@@ -758,12 +761,9 @@
     const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
     llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);
       
-    // 0-16 are the 16 integer registers.
-    // 17 is %rip.
-    for (unsigned I = 0, E = 17; I != E; ++I) {
-      llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
-      Builder.CreateStore(Eight8, Slot);
-    }
+    // 0-15 are the 16 integer registers.
+    // 16 is %rip.
+    AssignToArrayRange(Builder, Address, Eight8, 0, 16);
 
     return false;
   }
@@ -1691,16 +1691,10 @@
   llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16);
 
   // 0-31: r0-31, the 4-byte general-purpose registers
-  for (unsigned I = 0, E = 32; I != E; ++I) {
-    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
-    Builder.CreateStore(Four8, Slot);
-  }
+  AssignToArrayRange(Builder, Address, Four8, 0, 31);
 
   // 32-63: fp0-31, the 8-byte floating-point registers
-  for (unsigned I = 32, E = 64; I != E; ++I) {
-    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
-    Builder.CreateStore(Eight8, Slot);
-  }
+  AssignToArrayRange(Builder, Address, Eight8, 32, 63);
 
   // 64-76 are various 4-byte special-purpose registers:
   // 64: mq
@@ -1709,26 +1703,17 @@
   // 67: ap
   // 68-75 cr0-7
   // 76: xer
-  for (unsigned I = 64, E = 77; I != E; ++I) {
-    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
-    Builder.CreateStore(Four8, Slot);
-  }
+  AssignToArrayRange(Builder, Address, Four8, 64, 76);
 
   // 77-108: v0-31, the 16-byte vector registers
-  for (unsigned I = 77, E = 109; I != E; ++I) {
-    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
-    Builder.CreateStore(Sixteen8, Slot);
-  }
+  AssignToArrayRange(Builder, Address, Sixteen8, 77, 108);
 
   // 109: vrsave
   // 110: vscr
   // 111: spe_acc
   // 112: spefscr
   // 113: sfp
-  for (unsigned I = 109, E = 114; I != E; ++I) {
-    llvm::Value *Slot = Builder.CreateConstInBoundsGEP1_32(Address, I);
-    Builder.CreateStore(Four8, Slot);
-  }
+  AssignToArrayRange(Builder, Address, Four8, 109, 113);
 
   return false;  
 }
@@ -2153,6 +2138,56 @@
   }
 }
 
+// MIPS ABI Implementation.  This works for both little-endian and
+// big-endian variants.
+namespace {
+class MIPSTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  MIPSTargetCodeGenInfo(): TargetCodeGenInfo(new DefaultABIInfo()) {}
+
+  int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {
+    return 29;
+  }
+
+  bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                               llvm::Value *Address) const;  
+};
+}
+
+bool
+MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
+                                               llvm::Value *Address) const {
+  // This information comes from gcc's implementation, which seems to
+  // as canonical as it gets.
+
+  CodeGen::CGBuilderTy &Builder = CGF.Builder;
+  llvm::LLVMContext &Context = CGF.getLLVMContext();
+
+  // Everything on MIPS is 4 bytes.  Double-precision FP registers
+  // are aliased to pairs of single-precision FP registers.
+  const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);
+  llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);
+
+  // 0-31 are the general purpose registers, $0 - $31.
+  // 32-63 are the floating-point registers, $f0 - $f31.
+  // 64 and 65 are the multiply/divide registers, $hi and $lo.
+  // 66 is the (notional, I think) register for signal-handler return.
+  AssignToArrayRange(Builder, Address, Four8, 0, 65);
+
+  // 67-74 are the floating-point status registers, $fcc0 - $fcc7.
+  // They are one bit wide and ignored here.
+
+  // 80-111 are the coprocessor 0 registers, $c0r0 - $c0r31.
+  // (coprocessor 1 is the FP unit)
+  // 112-143 are the coprocessor 2 registers, $c2r0 - $c2r31.
+  // 144-175 are the coprocessor 3 registers, $c3r0 - $c3r31.
+  // 176-181 are the DSP accumulator registers.
+  AssignToArrayRange(Builder, Address, Four8, 80, 181);
+
+  return false;
+}
+
+
 const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() const {
   if (TheTargetCodeGenInfo)
     return *TheTargetCodeGenInfo;
@@ -2165,6 +2200,10 @@
   default:
     return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo);
 
+  case llvm::Triple::mips:
+  case llvm::Triple::mipsel:
+    return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo());
+
   case llvm::Triple::arm:
   case llvm::Triple::thumb:
     // FIXME: We want to know the float calling convention as well.





More information about the cfe-commits mailing list