[llvm-commits] CVS: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp
Misha Brukman
brukman at cs.uiuc.edu
Wed Aug 6 17:20:01 PDT 2003
Changes in directory llvm/lib/Target/Sparc:
SparcV9CodeEmitter.cpp updated: 1.25 -> 1.26
---
Log message:
Use the registers g1 and g5 as temporaries for making far jumps and far calls,
because saving i1 and i2 to their ``designated'' stack slots corrupts unknown
memory in other functions, standard libraries, and worse.
In addition, this has the benefit of improving JIT performance because we
eliminate writing out 4 instructions in CompilationCallback() and 2 loads and 2
stores.
---
Diffs of the changes:
Index: llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp
diff -u llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.25 llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.26
--- llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp:1.25 Wed Aug 6 11:20:22 2003
+++ llvm/lib/Target/Sparc/SparcV9CodeEmitter.cpp Wed Aug 6 17:19:18 2003
@@ -128,37 +128,29 @@
static const unsigned i1 = SparcIntRegClass::i1, i2 = SparcIntRegClass::i2,
i7 = SparcIntRegClass::i7,
- o6 = SparcIntRegClass::o6, g0 = SparcIntRegClass::g0;
+ o6 = SparcIntRegClass::o6, g0 = SparcIntRegClass::g0,
+ g1 = SparcIntRegClass::g1, g5 = SparcIntRegClass::g5;
MachineInstr* BinaryCode[] = {
//
- // Save %i1, %i2 to the stack so we can form a 64-bit constant in %i2
+ // Get address to branch into %g1, using %g5 as a temporary
//
- // stx %i1, [%sp + 2119] ;; save %i1 to the stack, used as temp
- BuildMI(V9::STXi, 3).addReg(i1).addReg(o6).addSImm(2119),
- // stx %i2, [%sp + 2127] ;; save %i2 to the stack
- BuildMI(V9::STXi, 3).addReg(i2).addReg(o6).addSImm(2127),
- //
- // Get address to branch into %i2, using %i1 as a temporary
- //
- // sethi %uhi(Target), %i1 ;; get upper 22 bits of Target into %i1
- BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(i1),
- // or %i1, %ulo(Target), %i1 ;; get 10 lower bits of upper word into %1
- BuildMI(V9::ORi, 3).addReg(i1).addSImm((Target >> 32) & 0x03ff).addReg(i1),
- // sllx %i1, 32, %i1 ;; shift those 10 bits to the upper word
- BuildMI(V9::SLLXi6, 3).addReg(i1).addSImm(32).addReg(i1),
- // sethi %hi(Target), %i2 ;; extract bits 10-31 into the dest reg
- BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(i2),
- // or %i1, %i2, %i2 ;; get upper word (in %i1) into %i2
- BuildMI(V9::ORr, 3).addReg(i1).addReg(i2).addReg(i2),
- // or %i2, %lo(Target), %i2 ;; get lowest 10 bits of Target into %i2
- BuildMI(V9::ORi, 3).addReg(i2).addSImm(Target & 0x03ff).addReg(i2),
- // ldx [%sp + 2119], %i1 ;; restore %i1 -> 2119 = BIAS(2047) + 72
- BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2119).addReg(i1),
- // jmpl %i2, %g0, %g0 ;; indirect branch on %i2
- BuildMI(V9::JMPLRETr, 3).addReg(i2).addReg(g0).addReg(g0),
- // ldx [%sp + 2127], %i2 ;; restore %i2 -> 2127 = BIAS(2047) + 80
- BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2127).addReg(i2)
+ // sethi %uhi(Target), %g5 ;; get upper 22 bits of Target into %g5
+ BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(g5),
+ // or %g5, %ulo(Target), %g5 ;; get 10 lower bits of upper word into %g5
+ BuildMI(V9::ORi, 3).addReg(g5).addSImm((Target >> 32) & 0x03ff).addReg(g5),
+ // sllx %g5, 32, %g5 ;; shift those 10 bits to the upper word
+ BuildMI(V9::SLLXi6, 3).addReg(g5).addSImm(32).addReg(g5),
+ // sethi %hi(Target), %g1 ;; extract bits 10-31 into the dest reg
+ BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(g1),
+ // or %g5, %g1, %g1 ;; get upper word (in %i1) into %g1
+ BuildMI(V9::ORr, 3).addReg(g5).addReg(g1).addReg(g1),
+ // or %g1, %lo(Target), %g1 ;; get lowest 10 bits of Target into %g1
+ BuildMI(V9::ORi, 3).addReg(g1).addSImm(Target & 0x03ff).addReg(g1),
+ // jmpl %g1, %g0, %g0 ;; indirect branch on %g1
+ BuildMI(V9::JMPLRETr, 3).addReg(g1).addReg(g0).addReg(g0),
+ // nop ;; delay slot
+ BuildMI(V9::NOP, 0)
};
for (unsigned i=0, e=sizeof(BinaryCode)/sizeof(BinaryCode[0]); i!=e; ++i) {
@@ -188,9 +180,9 @@
static const unsigned o6 = SparcIntRegClass::o6;
// Subtract enough to overwrite up to the 'save' instruction
- // This depends on whether we made a short call (1 instruction) to the
- // farCall (10 instructions)
- uint64_t Offset = (LazyCallFlavor[CameFrom] == ShortCall) ? 4 : 40;
+ // This depends on whether we made a short call (1 instruction) or the
+ // farCall (long form: 10 instructions, short form: 7 instructions)
+ uint64_t Offset = (LazyCallFlavor[CameFrom] == ShortCall) ? 4 : 28;
uint64_t CodeBegin = CameFrom - Offset;
// Make sure that what we're about to overwrite is indeed "save"
@@ -257,12 +249,12 @@
int64_t Addr = (int64_t)addFunctionReference(CurrPC, F);
int64_t CallTarget = (Addr-CurrPC) >> 2;
//if (CallTarget >= (1 << 29) || CallTarget <= -(1 << 29)) {
- // Since this is a far call, the actual address of the call is shifted
- // by the number of instructions it takes to calculate the exact address
+ // Since this is a far call, the actual address of the call is shifted
+ // by the number of instructions it takes to calculate the exact address
deleteFunctionReference(CurrPC);
SparcV9.emitFarCall(Addr, F);
#if 0
- } else {
+ else {
// call CallTarget ;; invoke the callback
MachineInstr *Call = BuildMI(V9::CALL, 1).addSImm(CallTarget);
SparcV9.emitWord(SparcV9.getBinaryCodeForInstr(*Call));
@@ -368,43 +360,35 @@
// being accounted for, and the behavior will be incorrect!!
inline void SparcV9CodeEmitter::emitFarCall(uint64_t Target, Function *F) {
static const unsigned i1 = SparcIntRegClass::i1, i2 = SparcIntRegClass::i2,
- i7 = SparcIntRegClass::i7, o6 = SparcIntRegClass::o6,
- o7 = SparcIntRegClass::o7, g0 = SparcIntRegClass::g0;
+ i7 = SparcIntRegClass::i7, o6 = SparcIntRegClass::o6,
+ o7 = SparcIntRegClass::o7, g0 = SparcIntRegClass::g0,
+ g1 = SparcIntRegClass::g1, g5 = SparcIntRegClass::g5;
MachineInstr* BinaryCode[] = {
- //
- // Save %i1, %i2 to the stack so we can form a 64-bit constant in %i2
- //
- // stx %i1, [%sp + 2119] ;; save %i1 to the stack, used as temp
- BuildMI(V9::STXi, 3).addReg(i1).addReg(o6).addSImm(2119),
- // stx %i2, [%sp + 2127] ;; save %i2 to the stack
- BuildMI(V9::STXi, 3).addReg(i2).addReg(o6).addSImm(2127),
//
- // Get address to branch into %i2, using %i1 as a temporary
+ // Get address to branch into %g1, using %g5 as a temporary
//
- // sethi %uhi(Target), %i1 ;; get upper 22 bits of Target into %i1
- BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(i1),
- // or %i1, %ulo(Target), %i1 ;; get 10 lower bits of upper word into %1
- BuildMI(V9::ORi, 3).addReg(i1).addSImm((Target >> 32) & 0x03ff).addReg(i1),
- // sllx %i1, 32, %i1 ;; shift those 10 bits to the upper word
- BuildMI(V9::SLLXi6, 3).addReg(i1).addSImm(32).addReg(i1),
- // sethi %hi(Target), %i2 ;; extract bits 10-31 into the dest reg
- BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(i2),
- // or %i1, %i2, %i2 ;; get upper word (in %i1) into %i2
- BuildMI(V9::ORr, 3).addReg(i1).addReg(i2).addReg(i2),
- // or %i2, %lo(Target), %i2 ;; get lowest 10 bits of Target into %i2
- BuildMI(V9::ORi, 3).addReg(i2).addSImm(Target & 0x03ff).addReg(i2),
- // ldx [%sp + 2119], %i1 ;; restore %i1 -> 2119 = BIAS(2047) + 72
- BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2119).addReg(i1),
- // jmpl %i2, %g0, %o7 ;; indirect call on %i2
- BuildMI(V9::JMPLRETr, 3).addReg(i2).addReg(g0).addReg(o7),
- // ldx [%sp + 2127], %i2 ;; restore %i2 -> 2127 = BIAS(2047) + 80
- BuildMI(V9::LDXi, 3).addReg(o6).addSImm(2127).addReg(i2)
+ // sethi %uhi(Target), %g5 ;; get upper 22 bits of Target into %g5
+ BuildMI(V9::SETHI, 2).addSImm(Target >> 42).addReg(g5),
+ // or %g5, %ulo(Target), %g5 ;; get 10 lower bits of upper word into %1
+ BuildMI(V9::ORi, 3).addReg(g5).addSImm((Target >> 32) & 0x03ff).addReg(g5),
+ // sllx %g5, 32, %g5 ;; shift those 10 bits to the upper word
+ BuildMI(V9::SLLXi6, 3).addReg(g5).addSImm(32).addReg(g5),
+ // sethi %hi(Target), %g1 ;; extract bits 10-31 into the dest reg
+ BuildMI(V9::SETHI, 2).addSImm((Target >> 10) & 0x03fffff).addReg(g1),
+ // or %g5, %g1, %g1 ;; get upper word (in %g5) into %g1
+ BuildMI(V9::ORr, 3).addReg(g5).addReg(g1).addReg(g1),
+ // or %g1, %lo(Target), %g1 ;; get lowest 10 bits of Target into %g1
+ BuildMI(V9::ORi, 3).addReg(g1).addSImm(Target & 0x03ff).addReg(g1),
+ // jmpl %g1, %g0, %o7 ;; indirect call on %g1
+ BuildMI(V9::JMPLRETr, 3).addReg(g1).addReg(g0).addReg(o7),
+ // nop ;; delay slot
+ BuildMI(V9::NOP, 0)
};
for (unsigned i=0, e=sizeof(BinaryCode)/sizeof(BinaryCode[0]); i!=e; ++i) {
// This is where we save the return address in the LazyResolverMap!!
- if (i == 9 && F != 0) { // Do this right before the JMPL
+ if (i == 6 && F != 0) { // Do this right before the JMPL
uint64_t CurrPC = MCE.getCurrentPCValue();
TheJITResolver->addFunctionReference(CurrPC, F);
// Remember that this is a far call, to subtract appropriate offset later
@@ -474,14 +458,14 @@
}
}
}
- DEBUG(std::cerr << "Global addr: " << rv << "\n");
+ DEBUG(std::cerr << "Global addr: 0x" << std::hex << rv << "\n");
}
// The real target of the call is Addr = PC + (rv * 4)
// So undo that: give the instruction (Addr - PC) / 4
if (MI.getOpcode() == V9::CALL) {
int64_t CurrPC = MCE.getCurrentPCValue();
DEBUG(std::cerr << "rv addr: 0x" << std::hex << rv << "\n"
- << "curr PC: 0x" << CurrPC << "\n");
+ << "curr PC: 0x" << std::hex << CurrPC << "\n");
int64_t CallInstTarget = (rv - CurrPC) >> 2;
if (CallInstTarget >= (1<<29) || CallInstTarget <= -(1<<29)) {
DEBUG(std::cerr << "Making far call!\n");
More information about the llvm-commits
mailing list