[llvm-commits] CVS: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp SparcV8RegisterInfo.td

Chris Lattner lattner at cs.uiuc.edu
Mon Dec 19 23:56:42 PST 2005



Changes in directory llvm/lib/Target/SparcV8:

SparcV8RegisterInfo.cpp updated: 1.30 -> 1.31
SparcV8RegisterInfo.td updated: 1.26 -> 1.27
---
Log message:

Reserve G1 for frame offset stuff and use it to handle large stack frames.
For example, instead of emitting this:

test:
        save -40112, %o6, %o6   ;; imm too large
        add %i6, -40016, %o0    ;; imm too large
        call caller
        nop
        restore %g0, %g0, %g0
        retl
        nop

emit this:

test:
        sethi 4194264, %g1
        or %g1, 848, %g1
        save %o6, %g1, %o6
        sethi 4194264, %g1
        add %g1, %i6, %g1
        add %i1, 944, %o0
        call caller
        nop
        restore %g0, %g0, %g0
        retl
        nop

which doesn't cause the assembler to barf.



---
Diffs of the changes:  (+42 -9)

 SparcV8RegisterInfo.cpp |   44 +++++++++++++++++++++++++++++++++++++-------
 SparcV8RegisterInfo.td  |    7 +++++--
 2 files changed, 42 insertions(+), 9 deletions(-)


Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp
diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.30 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.31
--- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp:1.30	Sun Dec 18 20:51:12 2005
+++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.cpp	Tue Dec 20 01:56:31 2005
@@ -96,15 +96,30 @@
 
   int FrameIndex = MI.getOperand(i).getFrameIndex();
 
-  // Replace frame index with a frame pointer reference
-  MI.SetMachineOperandReg (i, V8::I6);
-
   // Addressable stack objects are accessed using neg. offsets from %fp
   MachineFunction &MF = *MI.getParent()->getParent();
   int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
                MI.getOperand(i+1).getImmedValue();
-  // note: Offset < 0
-  MI.SetMachineOperandConst (i+1, MachineOperand::MO_SignExtendedImmed, Offset);
+
+  // Replace frame index with a frame pointer reference.
+  if (Offset >= -4096 && Offset <= 4095) {
+    // If the offset is small enough to fit in the immediate field, directly
+    // encode it.
+    MI.SetMachineOperandReg(i, V8::I6);
+    MI.SetMachineOperandConst(i+1, MachineOperand::MO_SignExtendedImmed,Offset);
+  } else {
+    // Otherwise, emit a G1 = SETHI %hi(offset).  FIXME: it would be better to 
+    // scavenge a register here instead of reserving G1 all of the time.
+    unsigned OffHi = (unsigned)Offset >> 10U;
+    BuildMI(*MI.getParent(), II, V8::SETHIi, 1, V8::G1).addImm(OffHi);
+    // Emit G1 = G1 + I6
+    BuildMI(*MI.getParent(), II, V8::ADDrr, 2, 
+            V8::G1).addReg(V8::G1).addReg(V8::I6);
+    // Insert: G1+%lo(offset) into the user.
+    MI.SetMachineOperandReg(i, V8::I1);
+    MI.SetMachineOperandConst(i+1, MachineOperand::MO_SignExtendedImmed,
+                              Offset & ((1 << 10)-1));
+  }
 }
 
 void SparcV8RegisterInfo::
@@ -128,8 +143,23 @@
   // Round up to next doubleword boundary -- a double-word boundary
   // is required by the ABI.
   NumBytes = (NumBytes + 7) & ~7;
-  BuildMI(MBB, MBB.begin(), V8::SAVEri, 2,
-          V8::O6).addImm(-NumBytes).addReg(V8::O6);
+  NumBytes = -NumBytes;
+  
+  if (NumBytes >= -4096) {
+    BuildMI(MBB, MBB.begin(), V8::SAVEri, 2,
+            V8::O6).addImm(NumBytes).addReg(V8::O6);
+  } else {
+    MachineBasicBlock::iterator InsertPt = MBB.begin();
+    // Emit this the hard way.  This clobbers G1 which we always know is 
+    // available here.
+    unsigned OffHi = (unsigned)NumBytes >> 10U;
+    BuildMI(MBB, InsertPt, V8::SETHIi, 1, V8::G1).addImm(OffHi);
+    // Emit G1 = G1 + I6
+    BuildMI(MBB, InsertPt, V8::ORri, 2, V8::G1)
+      .addReg(V8::G1).addImm(NumBytes & ((1 << 10)-1));
+    BuildMI(MBB, InsertPt, V8::SAVErr, 2,
+            V8::O6).addReg(V8::O6).addReg(V8::G1);
+  }
 }
 
 void SparcV8RegisterInfo::emitEpilogue(MachineFunction &MF,


Index: llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td
diff -u llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td:1.26 llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td:1.27
--- llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td:1.26	Sun Dec 18 18:06:52 2005
+++ llvm/lib/Target/SparcV8/SparcV8RegisterInfo.td	Tue Dec 20 01:56:31 2005
@@ -84,8 +84,10 @@
 //
 def IntRegs : RegisterClass<"V8", [i32], 32, [L0, L1, L2, L3, L4, L5, L6, L7,
                                      I0, I1, I2, I3, I4, I5,
-                                     G1,
                                      O0, O1, O2, O3, O4, O5, O7,
+
+   // FIXME: G1 reserved for now for large imm generation by frame code.
+                                     G1,
                                      // Non-allocatable regs:
                                      G2, G3, G4, // FIXME: OK for use only in
                                                  // applications, not libraries.
@@ -102,7 +104,8 @@
     IntRegsClass::iterator
     IntRegsClass::allocation_order_end(MachineFunction &MF) const {
       // FIXME: These special regs should be taken out of the regclass!
-      return end()-10;  // Don't allocate special registers
+      return end()-10  // Don't allocate special registers
+         -1;  // FIXME: G1 reserved for large imm generation by frame code.
     }
   }];
 }






More information about the llvm-commits mailing list