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

Misha Brukman brukman at cs.uiuc.edu
Thu Aug 28 23:24:00 PDT 2003


Changes in directory llvm/lib/Target/Sparc:

SparcV9CodeEmitter.cpp updated: 1.30 -> 1.31

---
Log message:

* Use alloca() to force GCC not to eliminate frame pointer
* Break apart saving and restoring registers into separate functions
* Instead of saving single and double FP registers, just save the double
  registers -- aliasing helps preserve the single FP registers as well.
* Request just as much memory for a stub as we actually use


---
Diffs of the changes:

Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp
diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.30 llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.31
--- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.30	Fri Aug 15 13:03:06 2003
+++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp	Thu Aug 28 23:22:54 2003
@@ -19,6 +19,7 @@
 #include "Support/hash_set"
 #include "SparcInternals.h"
 #include "SparcV9CodeEmitter.h"
+#include "Config/alloca.h"
 
 bool UltraSparc::addPassesToEmitMachineCode(FunctionPassManager &PM,
                                             MachineCodeEmitter &MCE) {
@@ -75,8 +76,9 @@
 
   private:
     uint64_t emitStubForFunction(Function *F);
-    static void SaveRestoreRegisters();
-    static uint64_t CompilationCallback();
+    static void SaveRegisters(uint64_t DoubleFP[]);
+    static void RestoreRegisters(uint64_t DoubleFP[]);
+    static void CompilationCallback();
     uint64_t resolveFunctionReference(uint64_t RetAddr);
 
   };
@@ -92,7 +94,7 @@
 ///
 uint64_t JITResolver::addFunctionReference(uint64_t Address, Function *F) {
   LazyCodeGenMap[Address] = F;
-  return (intptr_t)&JITResolver::SaveRestoreRegisters;
+  return (intptr_t)&JITResolver::CompilationCallback;
 }
 
 /// deleteFunctionReference - If we are emitting a far call, we already added a
@@ -162,61 +164,37 @@
   return Addr;
 }
 
-void JITResolver::SaveRestoreRegisters() {
-  uint32_t SingleFP[32];
-  uint64_t DoubleFP[16];
-  // FIXME: uint128_t QuadFloatRegs[..];
-  uint64_t CCR, FSR, FPRS, g1, g5;
-
+void JITResolver::SaveRegisters(uint64_t DoubleFP[]) {
 #if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
-  __asm__ __volatile__ (// Save g1 and g5
-                        "stx %%g1, %0;\n\t" "stx %%g5, %1;\n\t"
-                        : "=m"(g1), "=m"(g5));
 
+#if 0
   __asm__ __volatile__ (// Save condition-code registers
                         "stx %%fsr, %0;\n\t" 
                         "rd %%fprs, %1;\n\t" 
                         "rd %%ccr,  %2;\n\t"
                         : "=m"(FSR), "=r"(FPRS), "=r"(CCR));
+#endif
 
   // GCC says: `asm' only allows up to thirty parameters!
-  __asm__ __volatile__ (// Save Single FP registers, part 1
-                        "st  %%f0,  %0;\n\t"  "st  %%f1,  %1;\n\t"
-                        "st  %%f2,  %2;\n\t"  "st  %%f3,  %3;\n\t"
-                        "st  %%f4,  %4;\n\t"  "st  %%f5,  %5;\n\t"
-                        "st  %%f6,  %6;\n\t"  "st  %%f7,  %7;\n\t"
-                        "st  %%f8,  %8;\n\t"  "st  %%f9,  %9;\n\t"
-                        "st  %%f10, %10;\n\t" "st  %%f11, %11;\n\t"
-                        "st  %%f12, %12;\n\t" "st  %%f13, %13;\n\t"
-                        "st  %%f14, %14;\n\t" "st  %%f15, %15;\n\t"
-                        : "=m"(SingleFP[ 0]), "=m"(SingleFP[ 1]),
-                          "=m"(SingleFP[ 2]), "=m"(SingleFP[ 3]),
-                          "=m"(SingleFP[ 4]), "=m"(SingleFP[ 5]),
-                          "=m"(SingleFP[ 6]), "=m"(SingleFP[ 7]),
-                          "=m"(SingleFP[ 8]), "=m"(SingleFP[ 9]),
-                          "=m"(SingleFP[10]), "=m"(SingleFP[11]),
-                          "=m"(SingleFP[12]), "=m"(SingleFP[13]),
-                          "=m"(SingleFP[14]), "=m"(SingleFP[15]));
+  __asm__ __volatile__ (// Save Single/Double FP registers, part 1
+                        "std  %%f0,  %0;\n\t"  "std  %%f2,  %1;\n\t"
+                        "std  %%f4,  %2;\n\t"  "std  %%f6,  %3;\n\t"
+                        "std  %%f8,  %4;\n\t"  "std  %%f10, %5;\n\t"
+                        "std  %%f12, %6;\n\t"  "std  %%f14, %7;\n\t"
+                        "std  %%f16, %8;\n\t"  "std  %%f18, %9;\n\t"
+                        "std  %%f20, %10;\n\t" "std  %%f22, %11;\n\t"
+                        "std  %%f24, %12;\n\t" "std  %%f26, %13;\n\t"
+                        "std  %%f28, %14;\n\t" "std  %%f30, %15;\n\t"
+                        : "=m"(DoubleFP[ 0]), "=m"(DoubleFP[ 1]),
+                          "=m"(DoubleFP[ 2]), "=m"(DoubleFP[ 3]),
+                          "=m"(DoubleFP[ 4]), "=m"(DoubleFP[ 5]),
+                          "=m"(DoubleFP[ 6]), "=m"(DoubleFP[ 7]),
+                          "=m"(DoubleFP[ 8]), "=m"(DoubleFP[ 9]),
+                          "=m"(DoubleFP[10]), "=m"(DoubleFP[11]),
+                          "=m"(DoubleFP[12]), "=m"(DoubleFP[13]),
+                          "=m"(DoubleFP[14]), "=m"(DoubleFP[15]));
                         
-  __asm__ __volatile__ (// Save Single FP registers, part 2
-                        "st  %%f16, %0;\n\t"  "st  %%f17, %1;\n\t"
-                        "st  %%f18, %2;\n\t"  "st  %%f19, %3;\n\t"
-                        "st  %%f20, %4;\n\t"  "st  %%f21, %5;\n\t"
-                        "st  %%f22, %6;\n\t"  "st  %%f23, %7;\n\t"
-                        "st  %%f24, %8;\n\t"  "st  %%f25, %9;\n\t"
-                        "st  %%f26, %10;\n\t" "st  %%f27, %11;\n\t"
-                        "st  %%f28, %12;\n\t" "st  %%f29, %13;\n\t"
-                        "st  %%f30, %14;\n\t" "st  %%f31, %15;\n\t"
-                        : "=m"(SingleFP[16]), "=m"(SingleFP[17]),
-                          "=m"(SingleFP[18]), "=m"(SingleFP[19]),
-                          "=m"(SingleFP[20]), "=m"(SingleFP[21]),
-                          "=m"(SingleFP[22]), "=m"(SingleFP[23]),
-                          "=m"(SingleFP[24]), "=m"(SingleFP[25]),
-                          "=m"(SingleFP[26]), "=m"(SingleFP[27]),
-                          "=m"(SingleFP[28]), "=m"(SingleFP[29]),
-                          "=m"(SingleFP[30]), "=m"(SingleFP[31]));
-
-  __asm__ __volatile__ (// Save Double FP registers
+  __asm__ __volatile__ (// Save Double FP registers, part 2
                         "std %%f32, %0;\n\t"  "std %%f34, %1;\n\t"
                         "std %%f36, %2;\n\t"  "std %%f38, %3;\n\t"
                         "std %%f40, %4;\n\t"  "std %%f42, %5;\n\t"
@@ -225,71 +203,49 @@
                         "std %%f52, %10;\n\t" "std %%f54, %11;\n\t"
                         "std %%f56, %12;\n\t" "std %%f58, %13;\n\t"
                         "std %%f60, %14;\n\t" "std %%f62, %15;\n\t"
-                        : "=m"(DoubleFP[32/2-16]), "=m"(DoubleFP[34/2-16]),
-                          "=m"(DoubleFP[36/2-16]), "=m"(DoubleFP[38/2-16]),
-                          "=m"(DoubleFP[40/2-16]), "=m"(DoubleFP[42/2-16]),
-                          "=m"(DoubleFP[44/2-16]), "=m"(DoubleFP[46/2-16]),
-                          "=m"(DoubleFP[48/2-16]), "=m"(DoubleFP[50/2-16]),
-                          "=m"(DoubleFP[52/2-16]), "=m"(DoubleFP[54/2-16]),
-                          "=m"(DoubleFP[56/2-16]), "=m"(DoubleFP[58/2-16]),
-                          "=m"(DoubleFP[60/2-16]), "=m"(DoubleFP[62/2-16]));
+                        : "=m"(DoubleFP[16]), "=m"(DoubleFP[17]),
+                          "=m"(DoubleFP[18]), "=m"(DoubleFP[19]),
+                          "=m"(DoubleFP[20]), "=m"(DoubleFP[21]),
+                          "=m"(DoubleFP[22]), "=m"(DoubleFP[23]),
+                          "=m"(DoubleFP[24]), "=m"(DoubleFP[25]),
+                          "=m"(DoubleFP[26]), "=m"(DoubleFP[27]),
+                          "=m"(DoubleFP[28]), "=m"(DoubleFP[29]),
+                          "=m"(DoubleFP[30]), "=m"(DoubleFP[31]));
 #endif
+}
 
-  // Resolve the function call
-  register uint64_t restoreAddr = CompilationCallback();
 
+void JITResolver::RestoreRegisters(uint64_t DoubleFP[]) {
 #if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
-  // Set the return address to re-execute the `restore' instruction
-  __asm__ __volatile__ ("or %%o0, %%g0, %%i7;\n\t"
-
-                        // Restore g1 and g5
-                        "ldx %0, %%g1;\n\t" "ldx %1, %%g5;\n\t"
-                        :: "m"(g1), "m"(g5));
 
+#if 0
   __asm__ __volatile__ (// Restore condition-code registers
                         "ldx %0,    %%fsr;\n\t" 
                         "wr  %1, 0, %%fprs;\n\t"
                         "wr  %2, 0, %%ccr;\n\t" 
                         :: "m"(FSR), "r"(FPRS), "r"(CCR));
+#endif
 
   // GCC says: `asm' only allows up to thirty parameters!
-  __asm__ __volatile__ (// Restore Single FP registers, part 1
-                        "ld  %0, %%f0;\n\t"   "ld  %1, %%f1;\n\t" 
-                        "ld  %2, %%f2;\n\t"   "ld  %3, %%f3;\n\t" 
-                        "ld  %4, %%f4;\n\t"   "ld  %5, %%f5;\n\t" 
-                        "ld  %6, %%f6;\n\t"   "ld  %7, %%f7;\n\t" 
-                        "ld  %8, %%f8;\n\t"   "ld  %9, %%f9;\n\t" 
-                        "ld  %10, %%f10;\n\t" "ld  %11, %%f11;\n\t"
-                        "ld  %12, %%f12;\n\t" "ld  %13, %%f13;\n\t"
-                        "ld  %14, %%f14;\n\t" "ld  %15, %%f15;\n\t"
-                        :: "m"(SingleFP[0]), "m"(SingleFP[1]),
-                           "m"(SingleFP[2]), "m"(SingleFP[3]),
-                           "m"(SingleFP[4]), "m"(SingleFP[5]),
-                           "m"(SingleFP[6]), "m"(SingleFP[7]),
-                           "m"(SingleFP[8]), "m"(SingleFP[9]),
-                           "m"(SingleFP[10]), "m"(SingleFP[11]),
-                           "m"(SingleFP[12]), "m"(SingleFP[13]),
-                           "m"(SingleFP[14]), "m"(SingleFP[15]));
-
-  __asm__ __volatile__ (// Restore Single FP registers, part 2
-                        "ld  %0, %%f16;\n\t"  "ld  %1, %%f17;\n\t"
-                        "ld  %2, %%f18;\n\t"  "ld  %3, %%f19;\n\t"
-                        "ld  %4, %%f20;\n\t"  "ld  %5, %%f21;\n\t"
-                        "ld  %6, %%f22;\n\t"  "ld  %7, %%f23;\n\t"
-                        "ld  %8, %%f24;\n\t"  "ld  %9, %%f25;\n\t"
-                        "ld  %10, %%f26;\n\t" "ld  %11, %%f27;\n\t"
-                        "ld  %12, %%f28;\n\t" "ld  %13, %%f29;\n\t"
-                        "ld  %14, %%f30;\n\t" "ld  %15, %%f31;\n\t"
-                        :: "m"(SingleFP[16]), "m"(SingleFP[17]),
-                           "m"(SingleFP[18]), "m"(SingleFP[19]),
-                           "m"(SingleFP[20]), "m"(SingleFP[21]),
-                           "m"(SingleFP[22]), "m"(SingleFP[23]),
-                           "m"(SingleFP[24]), "m"(SingleFP[25]),
-                           "m"(SingleFP[26]), "m"(SingleFP[27]),
-                           "m"(SingleFP[28]), "m"(SingleFP[29]),
-                           "m"(SingleFP[30]), "m"(SingleFP[31]));
+  __asm__ __volatile__ (// Restore Single/Double FP registers, part 1
+                        "ldd %0,  %%f0;\n\t"   "ldd %1, %%f2;\n\t" 
+                        "ldd %2,  %%f4;\n\t"   "ldd %3, %%f6;\n\t" 
+                        "ldd %4,  %%f8;\n\t"   "ldd %5, %%f10;\n\t" 
+                        "ldd %6,  %%f12;\n\t"  "ldd %7, %%f14;\n\t" 
+                        "ldd %8,  %%f16;\n\t"  "ldd %9, %%f18;\n\t" 
+                        "ldd %10, %%f20;\n\t" "ldd %11, %%f22;\n\t"
+                        "ldd %12, %%f24;\n\t" "ldd %13, %%f26;\n\t"
+                        "ldd %14, %%f28;\n\t" "ldd %15, %%f30;\n\t"
+                        :: "m"(DoubleFP[0]), "m"(DoubleFP[1]),
+                           "m"(DoubleFP[2]), "m"(DoubleFP[3]),
+                           "m"(DoubleFP[4]), "m"(DoubleFP[5]),
+                           "m"(DoubleFP[6]), "m"(DoubleFP[7]),
+                           "m"(DoubleFP[8]), "m"(DoubleFP[9]),
+                           "m"(DoubleFP[10]), "m"(DoubleFP[11]),
+                           "m"(DoubleFP[12]), "m"(DoubleFP[13]),
+                           "m"(DoubleFP[14]), "m"(DoubleFP[15]));
 
-  __asm__ __volatile__ (// Restore Double FP registers
+  __asm__ __volatile__ (// Restore Double FP registers, part 2
                         "ldd %0, %%f32;\n\t"  "ldd %1, %%f34;\n\t"
                         "ldd %2, %%f36;\n\t"  "ldd %3, %%f38;\n\t"
                         "ldd %4, %%f40;\n\t"  "ldd %5, %%f42;\n\t"
@@ -298,19 +254,25 @@
                         "ldd %10, %%f52;\n\t" "ldd %11, %%f54;\n\t"
                         "ldd %12, %%f56;\n\t" "ldd %13, %%f58;\n\t"
                         "ldd %14, %%f60;\n\t" "ldd %15, %%f62;\n\t"
-                        :: "m"(DoubleFP[32/2-16]), "m"(DoubleFP[34/2-16]),
-                           "m"(DoubleFP[36/2-16]), "m"(DoubleFP[38/2-16]),
-                           "m"(DoubleFP[40/2-16]), "m"(DoubleFP[42/2-16]),
-                           "m"(DoubleFP[44/2-16]), "m"(DoubleFP[46/2-16]),
-                           "m"(DoubleFP[48/2-16]), "m"(DoubleFP[50/2-16]),
-                           "m"(DoubleFP[52/2-16]), "m"(DoubleFP[54/2-16]),
-                           "m"(DoubleFP[56/2-16]), "m"(DoubleFP[58/2-16]),
-                           "m"(DoubleFP[60/2-16]), "m"(DoubleFP[62/2-16]));
+                        :: "m"(DoubleFP[16]), "m"(DoubleFP[17]),
+                           "m"(DoubleFP[18]), "m"(DoubleFP[19]),
+                           "m"(DoubleFP[20]), "m"(DoubleFP[21]),
+                           "m"(DoubleFP[22]), "m"(DoubleFP[23]),
+                           "m"(DoubleFP[24]), "m"(DoubleFP[25]),
+                           "m"(DoubleFP[26]), "m"(DoubleFP[27]),
+                           "m"(DoubleFP[28]), "m"(DoubleFP[29]),
+                           "m"(DoubleFP[30]), "m"(DoubleFP[31]));
 #endif
 }
 
-uint64_t JITResolver::CompilationCallback() {
-  uint64_t CameFrom = (uint64_t)(intptr_t)__builtin_return_address(1);
+void JITResolver::CompilationCallback() {
+  // Local space to save double registers
+  uint64_t DoubleFP[32];
+  //uint64_t CCR, FSR, FPRS;
+
+  SaveRegisters(DoubleFP);
+
+  uint64_t CameFrom = (uint64_t)(intptr_t)__builtin_return_address(0);
   int64_t Target = (int64_t)TheJITResolver->resolveFunctionReference(CameFrom);
   DEBUG(std::cerr << "In callback! Addr=0x" << std::hex << CameFrom << "\n");
   register int64_t returnAddr = 0;
@@ -331,13 +293,23 @@
   // farCall (7 instructions)
   uint64_t Offset = (LazyCallFlavor[CameFrom] == ShortCall) ? 4 : 28;
   uint64_t CodeBegin = CameFrom - Offset;
+
+  // FIXME FIXME FIXME FIXME: __builtin_frame_address doesn't work if frame
+  // pointer elimination has been performed.  Having a variable sized alloca
+  // disables frame pointer elimination currently, even if it's dead.  This is a
+  // gross hack.
+  alloca(42+Offset);
+  // FIXME FIXME FIXME FIXME
   
   // Make sure that what we're about to overwrite is indeed "save"
   MachineInstr *SV = BuildMI(V9::SAVEi, 3).addReg(o6).addSImm(-192).addReg(o6);
   unsigned SaveInst = TheJITResolver->getBinaryCodeForInstr(*SV);
   delete SV;
   unsigned CodeInMem = *(unsigned*)(intptr_t)CodeBegin;
-  assert(CodeInMem == SaveInst && "About to overwrite smthg not a save instr!");
+  if (CodeInMem != SaveInst) {
+    std::cerr << "About to overwrite smthg not a save instr!";
+    abort();
+  }
   DEBUG(std::cerr << "Emitting a far jump to 0x" << std::hex << Target << "\n");
   TheJITResolver->insertFarJumpAtAddr(Target, CodeBegin);
 
@@ -357,13 +329,17 @@
   delete MI;
 #endif
 
+  RestoreRegisters(DoubleFP);
+
   // Change the return address to reexecute the restore, then the jump However,
   // we can't just modify %i7 here, because we return to the function that will
   // restore the floating-point registers for us. Thus, we just return the value
   // we want it to be, and the parent will take care of setting %i7 correctly.
   DEBUG(std::cerr << "Callback returning the addr of restore inst: "
                   << std::hex << (CameFrom-Offset-12) << "\n");
-  return CameFrom - Offset - 12; // 8 because of call+delay, 4 more to restore
+#if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
+  __asm__ __volatile__ ("sub %%i7, %0, %%i7" : : "r" (Offset+12));
+#endif
 }
 
 /// emitStubForFunction - This method is used by the JIT when it needs to emit
@@ -373,8 +349,7 @@
 /// directly.
 ///
 uint64_t JITResolver::emitStubForFunction(Function *F) {
-  // FIXME: 40 is not enough... but should be
-  MCE.startFunctionStub(*F, 64);
+  MCE.startFunctionStub(*F, 44);
 
   DEBUG(std::cerr << "Emitting stub at addr: 0x" 
                   << std::hex << MCE.getCurrentPCValue() << "\n");





More information about the llvm-commits mailing list