[llvm-commits] CVS: llvm/lib/Reoptimizer/BinInterface/emit.cpp
Anand Shukla
ashukla at cs.uiuc.edu
Sat May 31 17:08:12 PDT 2003
Changes in directory llvm/lib/Reoptimizer/BinInterface:
emit.cpp updated: 1.3 -> 1.4
---
Log message:
First version of working bininterface API/implementation
---
Diffs of the changes:
Index: llvm/lib/Reoptimizer/BinInterface/emit.cpp
diff -u llvm/lib/Reoptimizer/BinInterface/emit.cpp:1.3 llvm/lib/Reoptimizer/BinInterface/emit.cpp:1.4
--- llvm/lib/Reoptimizer/BinInterface/emit.cpp:1.3 Thu Apr 10 18:12:35 2003
+++ llvm/lib/Reoptimizer/BinInterface/emit.cpp Sat May 31 17:07:45 2003
@@ -1,31 +1,22 @@
-//*****************************************************************************
-// SPARC Binary Manipulation Interface
+//===--------llvm/Reoptimizer/BinInterface/emit.cpp---------------*- C++ -*--=//
//
// Code Emitter
-//
-// Interface Definition
-//
-//
-// 2002 Cameron Buschardt
-//*****************************************************************************
+//===----------------------------------------------------------------------===//
+#include "llvm/Reoptimizer/BinInterface/analyze.h" // SPARC analysis library
+#include "llvm/Reoptimizer/BinInterface/sparcbin.h" // Prototype for this class
+#include "llvm/Reoptimizer/BinInterface/sparcpriv.h"// Private definitions
+#include "llvm/Reoptimizer/BinInterface/sparcdis.h" // sparc disassembler
+#include "llvm/Reoptimizer/BinInterface/bitmath.h" // binary math routines
+#include "llvm/Reoptimizer/BinInterface/sparc9.h" // SPARC9 opcode definitions
+#include "llvm/Reoptimizer/BinInterface/regmask.h" // Register mask allocator
#include <stdio.h>
#include <stdlib.h>
-#include "salloc.h" // Stack allocator class
-#include "fvector.h" // fast vector (sits on stack allocator)
-#include "analyze.h" // SPARC analysis library
-#include "sparcbin.h" // Prototype for this class
-#include "sparcpriv.h" // Private definitions
-#include "regmask.h" // Register mask allocator
-
-#include "llvm/Reoptimizer/BinInterface/sparcdis.h" // prototype for sparc disassembler
-#include "llvm/Reoptimizer/BinInterface/bitmath.h" // header of optimized binary math routines
-#include "llvm/Reoptimizer/BinInterface/sparc9.h" // SPARC 9 opcode definitions
+#include <vector>
+#include <assert.h>
-#include <vector> // Use STL pair class
using std::pair;
-
-#include <assert.h>
+using std::vector;
//*****************************************************************************
// prepare_exit(regalloc & regalloc,
@@ -39,62 +30,93 @@
//*****************************************************************************
void BinInterface::prepare_exit(const regalloc & regalloc,
- fvector<shufflepair> * mod,
- unsigned * & out)
-{
- // what register is the value for each mod pair in
- fvector<unsigned> orig_reg(alloca);
-
- // what 'mod' pair is in a given register
- fvector<unsigned> regs(alloca);
-
- int spillidx=0; // index into regalloc.memspills
- // (memspills is a set of Stack
- // locations that are safe to use)
-
- orig_reg.sizehint((*mod).size());
- regs.resize(32);
-
- for (int k = 0; k<32;k++)
- regs[k] = 0;
-
- // lookup the registers each gen-site is in
- for (int k = 0; k<(*mod).size();k++)
- {
- int vr = regalloc.ssa_to_vreg[(*mod)[k].gen];
- int mr = regalloc.vregs[vr].mreg;
- orig_reg.push_back(regalloc.vregs[vr].mreg);
-
- if (VREG_ISREG(mr)) // in a machine register?
- regs[mr] = k;
- }
-
- // load each one-by-one spilling registers as needed
- for (int k=0; k<(*mod).size(); k++)
- {
- int dreg = (*mod)[k].reg;
- int sreg = orig_reg[k];
-
- if (sreg==dreg)
- continue;
-
- // is that register free? if not spill it
- if (regs[dreg])
- {
- // spill whats in DREG to an unused register or memory location?
- unsigned spillm = regalloc.memspills[spillidx++];
- *out++=MK_STX_STACK(dreg, VREG_GETMEM(spillm));
- }
-
- // do move
- if (VREG_ISMEM(sreg))
- *out++=MK_LDX_STACK(dreg, VREG_GETMEM(sreg));
+ vector<shufflepair> * mod,
+ unsigned * & out){
+
+ // what register is the value for each mod pair in
+ vector<unsigned> orig_reg;//(alloca);
+
+ // what 'mod' pair is in a given register
+ vector<unsigned> regs;//(alloca);
+
+ int spillidx=0; // index into regalloc.memspills
+ // (memspills is a set of Stack
+ // locations that are safe to use)
+
+ //orig_reg.sizehint((*mod).size());
+ regs.resize(32);
+
+ for (int k = 0; k<32;k++)
+ regs[k] = 0;
+
+ // lookup the registers each gen-site is in
+ for (unsigned int k = 0; k<(*mod).size();k++){
+ int vr = regalloc.ssa_to_vreg[(*mod)[k].gen];
+ int mr = regalloc.vregs[vr].mreg;
+ orig_reg.push_back(regalloc.vregs[vr].mreg);
+
+ if (VREG_ISREG(mr)) // in a machine register?
+ regs[mr] = k;
+ }
+
+ // load each one-by-one spilling registers as needed
+ for (unsigned int k=0; k<(*mod).size(); k++){
+ int dreg = (*mod)[k].reg;
+ int sreg = orig_reg[k];
+
+ if (sreg==dreg)
+ continue;
+
+ // is that register free? if not spill it
+ if (regs[dreg]>k){ //if future reg is going to use a value
+ // spill whats in DREG to an unused register or memory location?
+ unsigned spillm = regalloc.memspills[spillidx++];
+ assert(spillm >= 32);
+ orig_reg[regs[dreg]] = spillm;
+
+ int save_area = 2047+176+VREG_GETMEM(spillm);
+
+ //MARK
+ //if(save_area%16)//if its not divisible by 16
+ //save_area+=8;
+
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ MK_STX_STACK(dreg, save_area));
+ out++;
+ }
+ else
+ *out++=MK_STX_STACK(dreg, save_area);
+ }
+
+ // do move
+ if (VREG_ISMEM(sreg)){
+
+ int save_area = 2047+176+VREG_GETMEM(sreg);
+
+ //MARK
+ //if(save_area%16)//if its not divisible by 16
+ //save_area+=8;
+
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ MK_LDX_STACK(dreg, save_area));
+ out++;
+ }
else
- {
- regs[sreg] = 0;
- *out++=MK_MOV_R_R(dreg, sreg);
+ *out++=MK_LDX_STACK(dreg, save_area);
+ }
+ else{
+ regs[sreg] = 0;
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ MK_MOV_R_R(dreg, sreg));
+ out++;
}
- }
+ else
+ *out++=MK_MOV_R_R(dreg, sreg);
+ }
+ }
}
@@ -121,34 +143,56 @@
// This is used during liveout transitions.
//
//*****************************************************************************
-int BinInterface::spill_load(int vreg, regmask32 & rmask,
- const int memspills[32],int & freereg,
- int spilled[32], int & spilled_cnt,
- unsigned * & out)
-{
- assert(VREG_ISMEM(vreg)); // doesn't make sense if it is ALREADY a register
-
- int r = 0;
- // can we used the set-aside register?
- if (freereg)
- {
- r = freereg;
- freereg = 0;
- }
- else
- { // no? grab one from spill_candidates
- r=rmask.allocreg();
- assert(r);
-
- // spill the value in that register out to memory
- spilled[spilled_cnt] = r;
- *out++=MK_STX_STACK(r, VREG_GETMEM(memspills[spilled_cnt]));
- spilled_cnt++;
- }
- // now load the value from memory
- *out++=MK_LDX_STACK(r, VREG_GETMEM(vreg));
-
- return r;
+int BinInterface::spill_load(int vreg, regmask32 & rmask,
+ const int memspills[32],int & freereg,
+ int spilled[32], int & spilled_cnt,
+ unsigned * & out){
+ assert(VREG_ISMEM(vreg)); // doesn't make sense if it is ALREADY a register
+
+ int r = 0;
+ // can we used the set-aside register?
+ if (freereg){
+ r = freereg;
+ freereg = 0;
+ }
+ else{ // no? grab one from spill_candidates
+ r=rmask.allocreg();
+ assert(r);
+
+ // spill the value in that register out to memory
+ spilled[spilled_cnt] = r;
+ int save_area = 2047+176+VREG_GETMEM(memspills[spilled_cnt]);
+
+ //MARK
+ //if(save_area%16)//if its not divisible by 16
+ //save_area+=8;
+
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ MK_STX_STACK(r, save_area));
+ out++;
+ }
+ else
+ *out++=MK_STX_STACK(r, save_area);
+ spilled_cnt++;
+ }
+
+ // now load the value from memory
+ int save_area = 2047+176+VREG_GETMEM(vreg);
+
+ //MARK
+ //if(save_area%16)//if its not divisible by 16
+ //save_area+=8;
+
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ MK_LDX_STACK(r, save_area));
+ out++;
+ }
+ else
+ *out++=MK_LDX_STACK(r, save_area);
+
+ return r;
}
@@ -160,237 +204,339 @@
//
//*****************************************************************************
-unsigned BinInterface::emit_gen(unsigned char * cde, const regalloc & regs)
-{
- int s;
- unsigned * out = (unsigned *) cde;
-
- // pairs of instruction addrs +destination section #'s
- // (used for branch resolution)
- fvector<pair<unsigned *, unsigned> > fwdbranch(alloca);
-
- // address of section when emitted
- fvector<unsigned *> secaddr(alloca);
-
- // mask to be used for spill candidates
- regmask32 rmask;
-
- secaddr.inc(sections.size());
-
- // load stack size from allocator
- unsigned stack_size = regs.stack_size;
-
- // calculate the set of registers we must save and alloc stack
- // and allocate space for them in the prolog (and save)
- unsigned save_regs = regs.touched_regs & ~ regs.liveout_regs;
- unsigned save_area = stack_size;
- stack_size += countbits_dense(save_regs)*8;
- *out++=MK_ADD_R_I(R_SP, R_SP, -stack_size);
-
- for (unsigned m=save_regs, l = 0, a=save_area; l<32;l++, m>>=1)
- if (m & 1)
- {
- *out++=MK_STX_STACK(l, a);
- a+=8;
- }
-
- // Iterate across instructions
- for (s=0;s<sections.size();s++)
- {
- secaddr[s] = out; // mark down section start address for patching
- // jump instructions
- for (int i = begin(s); i!=end(s); i=next(i))
- {
- // Find what registers this instruction depends on.
- int rs1 = 0; // this register will contain the rs1 value
- int rs2 = 0; // this register will contain the rs2 value
- int r_rd = 0; // this register will contain the rd value
-
- instruction * instr = itable[i];
- unsigned flags = instr->flags;
-
- if (flags & (IF_REGSHUFFLE | IF_NODELIVEIN))
- {
- if (flags & IF_REGSHUFFLE)
- {
- prepare_exit(regs, instr->regshuffle.shuffles,out);
-
- }
- else // nodelivein
- {
- int id = regs.ssa_to_vreg[i];
- int dreg = regs.vregs[id].mreg;
- int sreg = instr->livein.reg;
-
- if (dreg!=sreg)
- {
- if (VREG_ISREG(dreg))
- *out++=MK_MOV_R_R(dreg, sreg);
- else
- *out++=MK_STX_STACK(sreg, VREG_GETMEM(dreg));
- }
- }
- continue;
- }
-
- // make sure this is ACTUALLY an instruction and not a phi node
- if (! (flags & (IF_ALUOP | IF_BR)))
- continue;
-
- // Find out what registers the instruction is already using
- // (since the values were assigned to registers by defaults
- rmask.set(R_ALLOCREGS);
-
- if (flags & IF_R_RS1)
- {
- rs1 = regs.vregs[regs.ssa_to_vreg[instr->alu.genrs1]].mreg;
-
- if (VREG_ISREG(rs1))
- rmask.grabreg(rs1);
- }
- if (flags & IF_R_RS2)
- {
- rs2 = regs.vregs[regs.ssa_to_vreg[instr->alu.genrs2]].mreg;
-
- if (VREG_ISREG(rs2))
- rmask.grabreg(rs2);
- }
- if (flags & IF_R_RD)
- {
- r_rd = regs.vregs[regs.ssa_to_vreg[instr->alu.genrd]].mreg;
-
- if (VREG_ISREG(r_rd))
- rmask.grabreg(r_rd);
- }
-
- // the free spill register - this gets zerod when used
- int freereg = regs.spillreg;
-
- // array containing the registers that were spilled
- // NOTE: spilled[k] ALWAYS spills to memspills[k]
- int spilled[3];
- int spilled_cnt = 0; // how many registers are in spilled
-
- unsigned ins = instr->instr;
-
- // load parameters of instruction and spill as needed
- if (flags & IF_R_RS1)
- {
- if (VREG_ISMEM(rs1))
- rs1 = spill_load(rs1, rmask, regs.memspills,
- freereg, spilled, spilled_cnt, out);
-
- ins = RM_FLD(INSTR_RS1, ins) | MK_FLD(INSTR_RS1, rs1);
- }
-
- if (flags & IF_R_RS2)
- {
- if (VREG_ISMEM(rs2))
- rs2 = spill_load(rs2, rmask, regs.memspills,
- freereg, spilled, spilled_cnt, out);
-
- ins = RM_FLD(INSTR_RS2, ins) | MK_FLD(INSTR_RS2, rs2);
- }
-
- if (flags & IF_R_RD)
- {
- if (VREG_ISMEM(r_rd))
- r_rd = spill_load(r_rd, rmask, regs.memspills,
- freereg, spilled, spilled_cnt, out);
-
- ins = RM_FLD(INSTR_RD, ins) | MK_FLD(INSTR_RD, r_rd);
- }
- //
- // Branch instructions must have their target fixed up
- // (note that the next instruction emitted is guaranteed
- // to be the actual instruction and not a spill fixup)
- if (flags & IF_BR)
- {
- if (flags & IF_BRINTERNAL)
- {
- // we need to fix up destination.
- // forward branches we store a backtable FIXME
- if (instr->ibranch.dest <= s)
- {
- unsigned rel = secaddr[instr->ibranch.dest] - out;
- instr->instr = sparc_setbrdest(instr->instr,rel);
- }
- else
- fwdbranch.push_back(
- pair<unsigned *, unsigned>(out, instr->ibranch.dest));
- }
- else
- {
- // do absolute jump
- unsigned rel = instr->ebranch.dest - out;
- instr->instr = sparc_setbrdest(instr->instr,rel);
- }
- }
-
- if (flags & IF_W_RD)
- {
- int id = regs.ssa_to_vreg[i];
-
- // We need to generate and store a result. We should check to see
- // if any registers are currently 'free'. If not we must spill one.
-
- int dreg = regs.vregs[id].mreg;
-
- if (VREG_ISREG(dreg))
- {
- ins = RM_FLD(INSTR_RD, ins) | MK_FLD(INSTR_RD, dreg);
- *out++=ins;
- }
- else
- {
- // always use the spillreg since it contains
- // a value that was loaded from memory that is
- // a SECOND copy.
- ins = RM_FLD(INSTR_RD, ins) | MK_FLD(INSTR_RD, regs.spillreg);
- *out++=ins;
- *out++=MK_STX_STACK(regs.spillreg, VREG_GETMEM(dreg));
- }
- }
- else
- *out++=(ins); // no dreg? just emit it
-
- // now unspill everything
- for (int z=0;z<spilled_cnt;z++)
- {
- // load (reg) spilled[z] with (mem) memspills[z]
- *out++=MK_LDX_STACK(spilled[z], VREG_GETMEM(regs.memspills[z]));
- }
- }
-
- //
- // End of section handler
- //
- if (s > SECTION_TRACE) // epilog sections
- {
- // free space at top of prolog
- // restore registers
- for (unsigned m=save_regs, l = 0, a=save_area; l<32;l++, m>>=1)
- if (m & 1)
- {
- *out++=MK_LDX_STACK(l, a);
- a+=8;
- }
- // free stack space
- *out++=MK_ADD_R_I(R_SP, R_SP, stack_size);
- }
- }
-
- //
- // Handle forward branches.
- //
- for(int t = 0; t<fwdbranch.size(); t++)
- {
- pair<unsigned *, unsigned> & i = fwdbranch[t];
+unsigned BinInterface::emit_gen(unsigned char * cde, const regalloc & regs){
+ unsigned int s;
+ unsigned * out = (unsigned *) cde;
+
+ // pairs of instruction addrs +destination section #'s
+ // (used for branch resolution)
+ vector<pair<unsigned *, unsigned> > fwdbranch;
+
+ // address of section when emitted
+ vector<unsigned *> secaddr;
+
+ // mask to be used for spill candidates
+ regmask32 rmask;
+
+ secaddr.resize(sections.size());
+
+ // load stack size from reg allocator
+ unsigned stack_size = regs.stack_size;
+
+ //MARK
+ //if(stack_size%16) //make it align to 16 byte boundary
+ //stack_size += 8;
+
+ // calculate the set of registers we must save and alloc stack
+ // and allocate space for them in the prolog (and save)
+ // Do not touch reg 0
+ unsigned save_regs = regs.touched_regs & ~ regs.liveout_regs & ~1;
+
+ unsigned save_area = stack_size;
+
+ //add to the stack size, the regs being saved in prolog
+ stack_size += countbits_dense(save_regs)*8;
+
+ if(stack_size%16) //make it align to 16 byte boundary
+ stack_size += 8;
+
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ MK_ADD_R_I(R_SP, R_SP, -stack_size));
+ out++;
+ }
+ else
+ *out++=MK_ADD_R_I(R_SP, R_SP, -stack_size);
+
+ save_area += 2047+176; //take care of BIAS
+
+ for(unsigned m=save_regs, l = 0, a=save_area; l<32;l++, m>>=1){
+ if(m & 1){
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,MK_STX_STACK(l, a));
+ out++;
+ }
+ else
+ *out++=MK_STX_STACK(l, a);
+ a+=8;
+ }
+ }
+
+ // Iterate across instructions
+ for(s=0;s<sections.size();s++){
+ secaddr[s] = out; // mark down section start address for patching
+ // jump instructions
+ for(unsigned int i = begin(s); i!=end(s); i=next(i)){
+ // Find what registers this instruction depends on.
+ int rs1 = 0; // this register will contain the rs1 value
+ int rs2 = 0; // this register will contain the rs2 value
+ int r_rd = 0; // this register will contain the rd value
+
+ instruction *instr = itable[i];
+ unsigned flags = instr->flags;
+
+ if(instr->isFloatingPoint){
+ unsigned ins = instr->instr;
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,ins);
+ out++;
+ }
+ else
+ *out++=ins;
+
+ continue;
+ }
+
+ if (flags & (IF_REGSHUFFLE | IF_NODELIVEIN)){
+ if (flags & IF_REGSHUFFLE){
+ prepare_exit(regs, instr->regshuffle.shuffles,out);
+ }
+ else{ // nodelivein
+ int id = regs.ssa_to_vreg[i];
+ int dreg = regs.vregs[id].mreg;
+ int sreg = instr->livein.reg;
+
+ if (dreg!=sreg){
+ if (VREG_ISREG(dreg)){
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ MK_MOV_R_R(dreg, sreg) );
+ out++;
+ }
+ else
+ *out++=MK_MOV_R_R(dreg, sreg);
+ }
+ else{
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ MK_STX_STACK(sreg,
+ 2047+176+VREG_GETMEM(dreg)));
+ out++;
+ }
+ else
+ *out++=MK_STX_STACK(sreg, 2047+176+VREG_GETMEM(dreg));
+ }
+ }
+ }
+ continue;
+ }
+
+ // make sure this is ACTUALLY an instruction and not a phi node
+ if (! (flags & (IF_ALUOP | IF_BR)))
+ continue;
+
+ // Find out what registers the instruction is already using
+ // (since the values were assigned to registers by defaults
+ rmask.set(R_ALLOCREGS);
+
+ if (flags & IF_R_RS1){
+ if(!(flags & IF_BR))
+ rs1 = regs.vregs[regs.ssa_to_vreg[instr->alu.genrs1]].mreg;
+ else{
+ if(flags & IF_BRINTERNAL)
+ rs1 = regs.vregs[regs.ssa_to_vreg[instr->ibranch.genrs1]].mreg;
+ else
+ rs1 = regs.vregs[regs.ssa_to_vreg[instr->ebranch.genrs1]].mreg;
+ }
+
+ if (VREG_ISREG(rs1))
+ rmask.grabreg(rs1);
+ }
+ if (flags & IF_R_RS2){
+ rs2 = regs.vregs[regs.ssa_to_vreg[instr->alu.genrs2]].mreg;
+
+ if (VREG_ISREG(rs2))
+ rmask.grabreg(rs2);
+ }
+ if (flags & IF_R_RD){
+ r_rd = regs.vregs[regs.ssa_to_vreg[instr->alu.genrd]].mreg;
+
+ if (VREG_ISREG(r_rd))
+ rmask.grabreg(r_rd);
+ }
+
+ // the free spill register - this gets zerod when used
+ int freereg = regs.spillreg;
+
+ // array containing the registers that were spilled
+ // NOTE: spilled[k] ALWAYS spills to memspills[k]
+ int spilled[3];
+ int spilled_cnt = 0; // how many registers are in spilled
+
+ unsigned ins = instr->instr;
+
+ // load parameters of instruction and spill as needed
+ if (flags & IF_R_RS1){
+ if (VREG_ISMEM(rs1))
+ rs1 = spill_load(rs1, rmask, regs.memspills,
+ freereg, spilled, spilled_cnt, out);
+
+ ins = RM_FLD(INSTR_RS1, ins) | MK_FLD(INSTR_RS1, rs1);
+ }
+
+ if (flags & IF_R_RS2){
+ if (VREG_ISMEM(rs2))
+ rs2 = spill_load(rs2, rmask, regs.memspills,
+ freereg, spilled, spilled_cnt, out);
+
+ ins = RM_FLD(INSTR_RS2, ins) | MK_FLD(INSTR_RS2, rs2);
+ }
+
+ if (flags & IF_R_RD){
+ if (VREG_ISMEM(r_rd))
+ r_rd = spill_load(r_rd, rmask, regs.memspills,
+ freereg, spilled, spilled_cnt, out);
+
+ ins = RM_FLD(INSTR_RD, ins) | MK_FLD(INSTR_RD, r_rd);
+ }
+
+ // Branch instructions must have their target fixed up
+ // (note that the next instruction emitted is guaranteed
+ // to be the actual instruction and not a spill fixup)
+ if (flags & IF_BR){
+ if (flags & IF_BRINTERNAL){
+ // we need to fix up destination.
+ // forward branches we store a backtable FIXME
+ if (instr->ibranch.dest <= s){
+ unsigned rel = secaddr[instr->ibranch.dest] - out;
+ instr->instr = sparc_setbrdest(instr->instr,rel);
+ ins = instr->instr;
+ }
+ else
+ fwdbranch.push_back(pair<unsigned *, unsigned>
+ (out, instr->ibranch.dest));
+ }
+ else{
+ // do absolute jump
+ unsigned rel = instr->ebranch.dest - out;
+ instr->instr = sparc_setbrdest(instr->instr,rel);
+ ins = instr->instr;
+ }
+ }
+
+ if ((flags & IF_W_RD) || ((flags & IF_RS1_RS2_DEFINED) &&
+ !(flags & IF_BR))){
+ int id = regs.ssa_to_vreg[i];
+
+ // We need to generate and store a result. We should check to see
+ // if any registers are currently 'free'. If not we must spill one.
+
+ int dreg = regs.vregs[id].mreg;
+
+ if (VREG_ISREG(dreg)){
+ ins = RM_FLD(INSTR_RD, ins) | MK_FLD(INSTR_RD, dreg);
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,ins);
+ out++;
+ }
+ else
+ *out++=ins;
+ }
+ else{
+ // always use the spillreg since it contains
+ // a value that was loaded from memory that is
+ // a SECOND copy.
+ ins = RM_FLD(INSTR_RD, ins) | MK_FLD(INSTR_RD, regs.spillreg);
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out, ins);
+ out++;
+ }
+ else
+ *out++=ins;
+
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ MK_STX_STACK(regs.spillreg,
+ 2047+176+VREG_GETMEM(dreg)));
+ out++;
+ }
+ else
+ *out++=MK_STX_STACK(regs.spillreg, 2047+176+VREG_GETMEM(dreg));
+ }
+ }
+ else{
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out, ins);
+ out++;
+ }
+ else
+ *out++=(ins); // no dreg? just emit it
+ }
+
+ // now unspill everything
+ for (int z=0;z<spilled_cnt;z++){
+ // load (reg) spilled[z] with (mem) memspills[z]
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ MK_LDX_STACK(spilled[z],
+ 2047+176+VREG_GETMEM(regs.memspills[z]
+ )));
+ out++;
+ }
+ else
+ *out++=MK_LDX_STACK(spilled[z],
+ 2047+176+VREG_GETMEM(regs.memspills[z]));
+ }
+ } //End of instruction iterator through a section
+
+
- unsigned rel = secaddr[i.second] - out;
+ if (s > SECTION_TRACE){ // epilog sections
+ // free space at top of prolog
+ // restore registers
+ for (unsigned m=save_regs, l = 0, a=save_area; l<32;l++, m>>=1){
+ if (m & 1){
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,MK_LDX_STACK(l, a) );
+ out++;
+ }
+ else
+ *out++=MK_LDX_STACK(l, a);
+
+ a+=8;
+ }
+ }
+
+ // free stack space
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ MK_ADD_R_I(R_SP, R_SP, stack_size));
+ out++;
+ }
+ else
+ *out++=MK_ADD_R_I(R_SP, R_SP, stack_size);
+ }
+
+ //insert branch, if it has one
+ if(epToRetAddr[s]){
+ unsigned rel = epToRetAddr[s] - out;
+ if(vm){
+ vm->writeInstToVM((uint64_t)(intptr_t)out,
+ sparc_setbrdest(MK_INSTR_BRANCH_NO_RS1(COND_BA),rel));
+ out++;
+ vm->writeInstToVM((uint64_t)(intptr_t)out, NOP);
+ out++;
+ }
+ else{
+ *out++ = sparc_setbrdest(MK_INSTR_BRANCH_NO_RS1(COND_BA),rel);
+ *out++ = NOP;
+ }
+ }
+ }
+
+ //
+ // Handle forward branches.
+ //
+ for(unsigned int t = 0; t<fwdbranch.size(); t++){
+ pair<unsigned *, unsigned> & i = fwdbranch[t];
+ unsigned rel = secaddr[i.second] - i.first;
+ if(vm)
+ vm->writeInstToVM((uint64_t)(intptr_t)i.first,
+ sparc_setbrdest(*i.first,rel));
+ else
*i.first = sparc_setbrdest(*i.first,rel);
- }
-
- return out- ((unsigned *)cde);
+ }
+
+ return out-((unsigned *)cde);
}
More information about the llvm-commits
mailing list