[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