[llvm-commits] CVS: llvm/lib/Reoptimizer/BinInterface/sparcbin.cpp

Anand Shukla ashukla at cs.uiuc.edu
Sat May 31 17:09:12 PDT 2003


Changes in directory llvm/lib/Reoptimizer/BinInterface:

sparcbin.cpp updated: 1.4 -> 1.5

---
Log message:

First version of working bininterface API/implementation

---
Diffs of the changes:

Index: llvm/lib/Reoptimizer/BinInterface/sparcbin.cpp
diff -u llvm/lib/Reoptimizer/BinInterface/sparcbin.cpp:1.4 llvm/lib/Reoptimizer/BinInterface/sparcbin.cpp:1.5
--- llvm/lib/Reoptimizer/BinInterface/sparcbin.cpp:1.4	Thu Apr 10 18:12:35 2003
+++ llvm/lib/Reoptimizer/BinInterface/sparcbin.cpp	Sat May 31 17:08:08 2003
@@ -1,40 +1,27 @@
-//*****************************************************************************
-//                      SPARC Binary Interface
-//
-//  Main C++ Driver file
+//===--------llvm/Reoptimizer/BinInterface/sparcbin.cpp-----------*- C++ -*--=//
 //
-//  Current flaws:
-//    * Makes no attempts to handle the difficulties of call instructions
-//      need to add 'affinity' for register allocator to handle efficient
-//      selection of Ixx registers.
-//    * Needs to save parameter registers
-//
-//  Goals
-//    * Performance       - Efficient use of memory and allocation code
-//    * Minimal Algorithms- 100% linear time, and make as many assumptions
-//                          based on our definition of trace as possible
+//  BinInterface: implementation for runtime manipulation of binary code
 //
-// 2002 Cameron Buschardt
-//*****************************************************************************
-
+//  Notes:
+//  move_instr into epilog ONLY after reduce()
+//  Remove instruction from anywhere before reduce()
+//
+//===----------------------------------------------------------------------===//
+
+#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"  // SPARC 9 opcode definitions
 #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 "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>           // Bring in STL pair class
-using std::pair;
-
+#include <vector>
 #include <assert.h>
 #include <new>
 
+using std::pair;
+using std::vector;
 
 //*****************************************************************************
 // liveout(unsigned instr)
@@ -45,9 +32,8 @@
 //  register by end of epilog!
 //
 //*****************************************************************************
-void BinInterface::liveout(unsigned instr)
-{
-   itable[instr]->flags |= IF_LIVEOUT;
+void BinInterface::liveout(unsigned instr){
+  itable[instr]->flags |= IF_LIVEOUT;
 }
 
 
@@ -60,20 +46,18 @@
 //
 //*****************************************************************************
 
-unsigned BinInterface::emit(unsigned char * out)
-{
-   // 
-   // This structure receives the register allocation
-   // and spill register information to be passed
-   // on to the emitter.
-   //
-   regalloc regs(alloca);
-
-   // Fill structure
-   select(regs);                 
-
-   // Compile code
-   return emit_gen(out, regs);         
+unsigned BinInterface::emit(unsigned char * out){ 
+  // This structure receives the register allocation
+  // and spill register information to be passed
+  // on to the emitter.
+  //
+  regalloc regs;
+  
+  // Fill structure
+  select(regs);                 
+  
+  // Compile code
+  return emit_gen(out, regs);         
 }
 
 //*****************************************************************************
@@ -84,9 +68,8 @@
 //
 //*****************************************************************************
 
-unsigned   BinInterface::predict()
-{
-   return (4 * itable.size() + 32*4) * sizeof(unsigned);
+unsigned   BinInterface::predict(){
+  return (4 * itable.size() + 32*4) * sizeof(unsigned);
 }
 
 
@@ -97,21 +80,14 @@
 //
 //*****************************************************************************
 
-instruction *   BinInterface::allocphi()
-{
-   instruction * phi = (instruction *)alloca->alloc(sizeof(instruction));
-
-   phi->flags = IF_PHI;
-   phi->next = phi->prev = phi->self  = itable.size();
-   itable.push_back(phi);
-
-   // allocate memory for fvector AND call constructor
-   phi->phi.params =  
-    (fvector<unsigned> *) alloca->alloc(sizeof(fvector<unsigned>));
-    
-   new ((void *)phi->phi.params) fvector<unsigned>(alloca);
-
-   return phi;
+instruction *   BinInterface::allocphi(){
+  instruction * phi = new instruction();
+  phi->flags = IF_PHI;
+  phi->next = phi->prev = phi->self  = itable.size();
+  itable.push_back(phi);
+  
+  phi->phi.params = new vector<unsigned>();
+  return phi;
 }
 
 //*****************************************************************************
@@ -129,80 +105,93 @@
 //
 //*****************************************************************************
 
-void BinInterface::process_branch(
-            const insertion & i, unsigned ** brdest, int scns)
-{
-   unsigned cid = i.idstart;
-   unsigned *ibegin = i.begin;
-   unsigned *iend   = i.end;
-   unsigned tail    = sections[i.section];
-
-
-   while(ibegin!=iend)
-   {
-      // Analyze the instruction
-      unsigned flags = sparc_analyze(*ibegin);
-
-      instruction * instr;
-
+void BinInterface::process_branch(const insertion & i, 
+				  unsigned ** brdest, int scns){
+  unsigned cid = i.idstart;
+  unsigned *ibegin = i.begin;
+  unsigned *iend   = i.end;
+  unsigned tail    = itable[sections[i.section]]->prev;
+  
+  while(ibegin!=iend){
+    // Analyze the instruction
+    unsigned int flags;
+    unsigned int orig_instr;
+    
+    instruction * instr = new instruction();
+    
+    if(vm)
+      orig_instr = vm->readInstrFrmVm((uint64_t)(intptr_t)ibegin, tr);
+    else
+      orig_instr = *ibegin;
+    
+    if(isFloatingPoint(orig_instr)){
+      instr->isFloatingPoint = true;
+    }
+    else{
+      instr->isFloatingPoint = false;
+      flags = sparc_analyze(orig_instr);
       // Branch?
-      if (flags & IF_BR)
-      {
-         int fwd = sparc_getbrdest(*ibegin);    // Relative adress
-         unsigned * dest = ibegin + fwd;        // eval
-
-         // allocate the SSA node
-         instr          = (instruction *)alloca->alloc(sizeof(instruction));
-
-         instr->flags   = flags;
-         
-         // scan for branch destination
-         for (int l = 0; l<scns; l++)
-         {
-            if (dest == brdest[l])
-            {
-               // found? this must be an internal
-               // branch!
-               instr->ibranch.dest = l;
-               instr->flags |= IF_BRINTERNAL;
-               goto ibfound;
-            }
-         }
-         // must have been external (eg out of trace)
-         instr->ebranch.dest = dest;
-
-ibfound:    // internal branch found
-         ;
-
+      if (flags & IF_BR){
+	int fwd;
+	if(vm)
+	  fwd = sparc_getbrdest(vm->readInstrFrmVm((uint64_t)(intptr_t)ibegin,
+						   tr));
+	else
+	  fwd = sparc_getbrdest(*ibegin);    // Relative adress
+	
+	unsigned * dest = ibegin + fwd;        // eval
+	instr->flags   = flags;
+	
+	// scan for branch destination
+	for (int l = 0; l<scns; l++){
+	  if (dest == brdest[l]){
+	    // found? this must be an internal
+	    // branch!
+	    instr->ibranch.dest = l;
+	    instr->flags |= IF_BRINTERNAL;
+	    goto ibfound;
+	  }
+	}
+	// must have been external (eg out of trace)
+	instr->ebranch.dest = dest;
+	
+      ibfound:    // internal branch found
+	;
+	
       }
-      else
-      {
-         // create a generic ALU instruction since it wasn't
-         // a branch
-         instr          = (instruction *)alloca->alloc(sizeof(instruction));
-         instr->flags   = flags | IF_ALUOP;
-
-         // zero out SSA parameters
-         instr->alu.genccf = instr->alu.genrs1 = instr->alu.genrs2 = 0; 
+      else{
+	// create a generic ALU instruction since it wasn't
+	// a branch
+	instr->flags   = flags | IF_ALUOP;
+	
+	// zero out SSA parameters
+	instr->alu.genccf = instr->alu.genrs1 = instr->alu.genrs2 = 0; 
       }
-
-      // Store instruction data and store instruction ID # in
-      // the node
+    }
+    // Store instruction data and store instruction ID # in
+    // the node
+    if(vm)
+      instr->instr = vm->readInstrFrmVm((uint64_t)(intptr_t)ibegin, tr);
+    else
       instr->instr = *ibegin;
-      instr->self  = cid;
-
-      // Add the instruction to the ID table
-      itable[cid]  = instr;
-
-      // Add instruction into linked list for given section
-      insert_instr(tail, instr);
-      tail = cid;
-
-      cid++;
-      ibegin++;
-
-   }
-
+    instr->self  = cid;
+    
+    // Add the instruction to the ID table
+    itable[cid]  = instr;
+    
+    // Add instruction into linked list for given section
+    insert_instr(tail, instr);
+    tail = cid;
+    
+    printf("cid :%u\t", cid);
+    if(instr->isFloatingPoint)
+      printf("FP\n");
+    else
+      sparc_print(instr->instr);printf("\n");
+    
+    cid++;
+    ibegin++;
+  }
 }
 
 //*****************************************************************************
@@ -214,32 +203,34 @@
 //
 //*****************************************************************************
 
-void BinInterface::complete()
-{
-   int p;
-   assert(sections.size() <= MAX_SECTIONS);
-   
-   // Compute  branch destination table by section
-   unsigned * brdest[MAX_SECTIONS];
-
-   // We nullify the structure before the scan
-   // step since not EVERY section has an instruction
-   // in it.
-   for (p = 0; p<sections.size(); p++)
-      brdest[p] = NULL;
-
-   // Look for the first insertion for each section
-   // and mark down address
-   for (p = 0; p<queue.size(); p++)
-      if (!brdest[queue[p].section])
-         brdest[queue[p].section] = queue[p].begin;
-
-   // Complete delayed insertion per section
-   for (p = 0; p<queue.size(); p++)
-      process_branch(queue[p], brdest,sections.size());
-
-   // Throw away queue
-   queue.clear();
+void BinInterface::complete(){
+  unsigned int p;
+  assert(sections.size() <= MAX_SECTIONS);
+  
+  // Compute  branch destination table by section
+  unsigned * brdest[MAX_SECTIONS];
+  
+  // We nullify the structure before the scan
+  // step since not EVERY section has an instruction
+  // in it.
+  for (p = 0; p<sections.size(); p++)
+    brdest[p] = NULL;
+  
+  // Look for the first insertion for each section
+  // and mark down address
+  for (p = 0; p<queue.size(); p++)
+    if (!brdest[queue[p].section])
+      brdest[queue[p].section] = queue[p].begin;
+  
+  // Complete delayed insertion per section
+  for (p = 0; p<queue.size(); p++)
+    process_branch(queue[p], brdest,sections.size());
+  
+  // Throw away queue
+  queue.clear();
+  
+  //clear epilog to abs addr map
+  epToRetAddr.clear();
 }
 
 //*****************************************************************************
@@ -252,63 +243,56 @@
 //
 //*****************************************************************************
 
-void BinInterface::print(unsigned section)
-{
-   unsigned u = begin(section);
-
-   while (u!=end(section))
-   {
-      instruction * instr = itable[u];
-
-      if (instr->flags & IF_NODELIVEIN)
-      {
-         printf("l%04d:  livein[r%d]\n", instr->self,instr->livein.reg);
-      }
-      else if (instr->flags & IF_REGSHUFFLE)
-      {
-         for (int k = 0; k<instr->regshuffle.shuffles->size(); k++)
-            printf("r%02d:    liveout[l%04d]\n", 
-                (*instr->regshuffle.shuffles)[k].reg, 
-                (*instr->regshuffle.shuffles)[k].gen);
-      }
-      else if (instr->flags & IF_PHI)
-      {
-         printf("l%04d:  phi[", instr->self);
-         for (int i=0;i<(*instr->phi.params).size();++i)
-            printf("%d ", (*instr->phi.params)[i]);
-         printf("]\n");
-      }
-      else if (instr->flags & IF_BR)
-      {
-         printf("l%04d:  ", instr->self);
-         if (instr->flags & IF_BRINTERNAL)
-            printf("{dest:s%02d} ", instr->ibranch.dest);
-         else
-            printf("{dest:0x%08X} ", instr->ebranch.dest);
-
-         sparc_print_pseudo(instr->instr, 
-                            instr->alu.genrs1, 
-                            instr->alu.genrs2, 
-                            -1, 
-                            instr->alu.genccf);
-         printf("\n");
-
-      }
+void BinInterface::print(unsigned section){
+  unsigned u = begin(section);
+  
+  while (u!=end(section)){
+    instruction * instr = itable[u];
+    
+    if(instr->isFloatingPoint){
+      printf("FP\n");
+    }
+    else if (instr->flags & IF_NODELIVEIN){
+      printf("l%04d:  livein[r%d]\n", instr->self,instr->livein.reg);
+    }
+    else if (instr->flags & IF_REGSHUFFLE){
+      for (unsigned int k = 0; k<instr->regshuffle.shuffles->size(); k++)
+	printf("r%02d:    liveout[l%04d]\n", 
+	       (*instr->regshuffle.shuffles)[k].reg, 
+	       (*instr->regshuffle.shuffles)[k].gen);
+    }
+    else if (instr->flags & IF_PHI){
+      printf("l%04d:  phi[", instr->self);
+      for (unsigned int i=0;i<(*instr->phi.params).size();++i)
+	printf("%d ", (*instr->phi.params)[i]);
+      printf("]\n");
+    }
+    else if (instr->flags & IF_BR){
+      printf("l%04d:  ", instr->self);
+      if (instr->flags & IF_BRINTERNAL)
+	printf("{dest:s%02d} ", instr->ibranch.dest);
       else
-      {
-         printf("l%04d:  ", instr->self);
-         
-         sparc_print_pseudo(instr->instr, 
-                            instr->alu.genrs1, 
-                            instr->alu.genrs2, 
-                            -1, 
-                            instr->alu.genccf);
-         printf("\n");
-      }
-
-
-      u = instr->next;
-   }
+	printf("{dest:0x%08X} ", (unsigned int)instr->ebranch.dest);
+      
+      sparc_print_pseudo(instr->instr, 
+			 instr->alu.genrs1, 
+			 instr->alu.genrs2, 
+			 -1, 
+			 instr->alu.genccf);
+      printf("\n");
+    }
+    else{
+      printf("l%04d:  ", instr->self);
+      
+      sparc_print_pseudo(instr->instr, 
+			 instr->alu.genrs1, 
+			 instr->alu.genrs2, 
+			 -1, 
+			 instr->alu.genccf);
+      printf("\n");
+    }
+    u = instr->next;
+  }
 }
 
 //*****************************************************************************
@@ -318,15 +302,11 @@
 //
 //*****************************************************************************
 
-void BinInterface::print()
-{
-   alloca->print();
-
-   for (int p = 0; p< sections.size(); p++)
-   {
-      printf("Section %d\n",p);
-      print(p);
-   }
+void BinInterface::print(){
+  for (unsigned int p = 0; p< sections.size(); p++){
+    printf("Section %d\n",p);
+    print(p);
+  }
 }
 
 
@@ -338,11 +318,10 @@
 //*****************************************************************************
 
 
-unsigned     BinInterface::newepilog()
-{
-   unsigned v = sections.size();
-   push_section();
-   return v;
+unsigned BinInterface::newepilog(){
+  unsigned v = sections.size();
+  push_section();
+  return v;
 }
 
 
@@ -354,16 +333,75 @@
 //
 //*****************************************************************************
 
-void   BinInterface::insert_instr(unsigned instr_id, instruction * instr)
-{
-   unsigned a = instr_id;
-   unsigned c = itable[a]->next;
-
-   itable[a]->next = instr->self;
-   instr->prev     = a;
-
-   instr->next     = c;
-   itable[c]->prev = instr->self;
+void BinInterface::insert_instr(unsigned instr_id, instruction * instr){
+  unsigned a = instr_id;
+  unsigned c = itable[a]->next;
+  
+  itable[a]->next = instr->self;
+  instr->prev     = a;
+  
+  instr->next     = c;
+  itable[c]->prev = instr->self;
+}
+
+//remove an instruction cid
+void BinInterface::remove(unsigned cid){
+  instruction *instr = itable[cid];
+
+  //must not be only instr in section
+  assert(instr->next != instr->self && "Can not remove this instruction");
+  assert(instr->prev != instr->self && "Can't remmove this!\n");
+  
+  //detach it
+  itable[instr->prev]->next = instr->next;
+  itable[instr->next]->prev = instr->prev;
+
+  //delete the instruction
+  delete instr;
+  itable[cid] = NULL;
+}
+
+//Move an instruction to after another instr
+void BinInterface::move_instr(unsigned instr_id, unsigned after_this){
+  instruction *instr = itable[instr_id];
+  //make sure it is not the ONLY instruction
+  assert(instr->next != instr->self && "Can not move this instruction");
+  assert(instr->prev != instr->self && "Can't move this!\n");
+  
+  //detach this one
+  itable[instr->prev]->next = instr->next;
+  itable[instr->next]->prev = instr->prev;
+  
+  instruction *after = itable[after_this];
+  instr->next = after->next;
+  instr->prev = after_this;
+  itable[after->next]->prev = instr_id;
+  after->next = instr_id;
+}
+
+//Move an instruction before another instr
+void BinInterface::move_instr_before(unsigned instr_id, unsigned before_this){
+  instruction *instr = itable[instr_id];
+  //make sure it is not the ONLY instruction
+  assert(instr->next != instr->self && "Can not move this instruction");
+  assert(instr->prev != instr->self && "Can't move this!\n");
+  
+  //detach this one
+  itable[instr->prev]->next = instr->next;
+  itable[instr->next]->prev = instr->prev;
+  
+  instruction *before = itable[before_this];
+  instr->next = before_this;
+  instr->prev = before->prev;
+  itable[before->prev]->next = instr_id;
+  before->prev = instr_id;
+}
+
+
+//Move an instruction to end the end of a section
+void BinInterface::moveToEnd(unsigned instr_id, unsigned section){
+  unsigned after_this = itable[end(section)]->prev;
+  move_instr(instr_id, after_this);
 }
 
 //*****************************************************************************
@@ -372,37 +410,45 @@
 //     Adds a new section. Initialized empty.
 //
 //*****************************************************************************
-void   BinInterface::push_section()
-{
-   // create header node
-   instruction * instr = (instruction *)alloca->alloc(sizeof(instruction));
-   instr->next  = itable.size();
-   instr->prev  = itable.size();
-   instr->flags = 0;
-   instr->self  = itable.size();
-   sections.push_back(itable.size());
-   itable.push_back(instr);
+void BinInterface::push_section(){
+  // create header node
+  instruction * instr = new instruction();
+  instr->next  = itable.size();
+  instr->prev  = itable.size();
+  instr->flags = 0;
+  instr->self  = itable.size();
+  sections.push_back(itable.size());
+  itable.push_back(instr);
 }
 
-
 //*****************************************************************************
 // BinInterface(unsigned heapsize)
+// This constructor is used if code is to be read from, and is output into
+// a buffer in the data region  
 //
-//  Heapsize must be sufficiently large or memory allocations will fail!
-//  
+//*****************************************************************************
+
+BinInterface::BinInterface(unsigned heapsize){
+  // create prolog and trace link nodes
+  push_section();
+  push_section();
+}
+
+//*****************************************************************************
+// BinInterface(unsigned heapsize)
+// This constructor must be used if BinInterface
+// must read and write into code region of executing program
 //
 //*****************************************************************************
 
-BinInterface::BinInterface(unsigned heapsize)
-{
-   alloca = new StackAllocator(heapsize);
-   itable.setallocator(alloca);
-   sections.setallocator(alloca);
-   queue.setallocator(alloca);
-   livein.setallocator(alloca);
-   // create prolog and trace link nodes
-   push_section();
-   push_section();
+BinInterface::BinInterface(unsigned heapsize, VirtualMem *vmem, 
+			   TraceCache *trc){
+  // create prolog and trace link nodes
+  push_section();
+  push_section();
+  
+  vm = vmem;
+  tr = trc;
 }
 
 //*****************************************************************************
@@ -413,18 +459,22 @@
 //
 //*****************************************************************************
 
-unsigned   BinInterface::allocnodelivein(int s, int reg)
-{
-   int idx = itable.size();
-   instruction * instr = (instruction *)alloca->alloc(sizeof(instruction));
-   instr->flags = IF_NODELIVEIN;
-   instr->livein.reg = reg;
-   instr->self = idx;
-   itable.push_back(instr);
-   livein.push_back(idx);
-   insert_instr(sections[s], instr);
-   return idx;
-
+unsigned BinInterface::allocnodelivein(unsigned int s, unsigned int reg){
+  //check if livein doesn't already exist for this reg
+  for(vector<unsigned int>::iterator VI = livein.begin(), VE = livein.end();
+      VI != VE; ++VI)
+    if(itable[*VI]->livein.reg == reg)
+      return *VI;
+  
+  int idx = itable.size();
+  instruction * instr = new instruction();
+  instr->flags = IF_NODELIVEIN;
+  instr->livein.reg = reg;
+  instr->self = idx;
+  itable.push_back(instr);
+  livein.push_back(idx);
+  insert_instr(sections[s], instr);
+  return idx;
 }
 
 //*****************************************************************************
@@ -437,17 +487,17 @@
 //
 //*****************************************************************************
 
-unsigned   BinInterface::allocnodeshuffles(int s, fvector<shufflepair> * shuffles)
-{
-   int idx = itable.size();
-   instruction * instr = (instruction *)alloca->alloc(sizeof(instruction));
-   instr->flags = IF_REGSHUFFLE;
-   instr->regshuffle.shuffles = shuffles;
-
-   instr->self = idx;
-   itable.push_back(instr);
-   insert_instr(end(s), instr);
-   return idx;
+unsigned BinInterface::allocnodeshuffles(int s, 
+                                           vector<shufflepair> * shuffles){
+  int idx = itable.size();
+  instruction * instr = new instruction();
+  instr->flags = IF_REGSHUFFLE;
+  instr->regshuffle.shuffles = shuffles;
+  
+  instr->self = idx;
+  itable.push_back(instr);
+  insert_instr(end(s), instr);
+  return idx;
 }
 
 //*****************************************************************************
@@ -460,23 +510,24 @@
 //
 //*****************************************************************************
 
-unsigned   BinInterface::insert(unsigned section, 
-                                unsigned *ibegin, unsigned * iend) 
-{
-   // you're not allowed to have machine instructions
-   // INITIALLY in the epilogs
-   assert(section==SECTION_TRACE || section==SECTION_PROLOG);
-   
-   insertion i;
-   i.begin   = ibegin;
-   i.end     = iend;
-   i.section = section;
-   i.idstart = itable.size();
-
-   itable.inc(iend - ibegin);
-   queue.push_back(i);
-
-   return i.idstart;
+unsigned BinInterface::insert(unsigned section, 
+			      unsigned *ibegin, unsigned * iend){
+  // you're not allowed to have machine instructions
+  // INITIALLY in the epilogs
+  assert(section==SECTION_TRACE || section==SECTION_PROLOG);
+  int sz = itable.size();
+  
+  insertion i;
+  i.begin   = ibegin;
+  i.end     = iend;
+  i.section = section;
+  
+  i.idstart = sz;
+  
+  itable.resize(sz+iend-ibegin);
+  queue.push_back(i);
+  
+  return i.idstart;
 }
 
 //*****************************************************************************
@@ -487,16 +538,15 @@
 //
 //*****************************************************************************
 
-void   BinInterface::clear()
-{
-   itable.clear();
-   sections.clear();
-   queue.clear();
-   livein.clear();
-   alloca->clear();
-   // create prolog and trace link nodes
-   push_section();
-   push_section();
+void BinInterface::clear(){
+  itable.clear();
+  sections.clear();
+  queue.clear();
+  livein.clear();
+
+  // create prolog and trace link nodes
+  push_section();
+  push_section();
 }
 
 //*****************************************************************************
@@ -509,6 +559,231 @@
 
 BinInterface::~BinInterface()
 {
-   delete alloca;
+  //TODO
 }
 
+// Move instruction id to just after after_this 
+void BinInterface::move(unsigned id, unsigned after_this){
+  instruction *instr = itable[id];
+  insert_instr(after_this, instr);
+}
+
+//Creating a new alu instruction
+//This must be "moved" or "inserted" after being created
+//OP Must have the following flags set:
+//INSTR_OP: OP2 or OP3
+//INSTR_OP3 or INSTR_OP2: corresponding OPCODE
+//INSTR_I = 0 (no immediate)
+//Do not set rs1 or rs2, or the correspoding flags
+
+//We don't have to read RD_W because it'll get set automatically
+//in select().
+unsigned BinInterface::newalu(unsigned op, unsigned rs1, unsigned rs2){
+  instruction *instr = new instruction();
+  //do not set the flags IF_R_RSx, and instead assign SSA values to 
+  //rs1 and rs2 right here
+  instr->flags = (IF_ALUOP | IF_RS1_RS2_DEFINED | IF_R_RS1 | IF_R_RS2);
+  instr->alu.genrs1 = rs1;
+  instr-> alu.genrs2 = rs2;
+  
+  instr->instr = op;
+  unsigned cid = itable.size();
+  instr->self = cid;
+  itable.push_back(instr);
+  
+  return cid;
+}
+
+//Create a NOP
+unsigned BinInterface::newnop(){
+  instruction *instr = new instruction();
+  instr->flags = (IF_ALUOP);
+  
+  instr->instr = NOP;
+  unsigned cid = itable.size();
+  instr->self = cid;
+  itable.push_back(instr);
+  
+  return cid;
+}
+
+// New relative branch, destination is a section ID (returns
+// branch instruction ID)
+//rs1 is SSAid of register value on which branch condition is determined
+unsigned BinInterface::newbranch(unsigned op, unsigned rs1, unsigned dest){
+  instruction *instr = new instruction();
+    
+  instr->flags = (IF_BR | IF_RCC | IF_RS1 | IF_BRINTERNAL | IF_R_RS1 | 
+		  IF_RS1_RS2_DEFINED);
+  instr->ibranch.genrs1 = rs1;
+  instr->ibranch.dest = dest;
+  
+  instr->instr = op;
+  unsigned cid = itable.size();
+  instr->self = cid;
+  itable.push_back(instr);
+  
+  return cid;
+}
+
+// New relative branch, destination is a section ID (returns
+// branch instruction ID)
+// NO rs1
+unsigned BinInterface::newbranch(unsigned op, unsigned dest){
+  instruction *instr = new instruction();
+  
+  instr->flags = (IF_BR | IF_RCC | IF_BRINTERNAL);
+  instr->ibranch.dest = dest;
+  
+  instr->instr = op;
+  unsigned cid = itable.size();
+  instr->self = cid;
+  itable.push_back(instr);
+  
+  return cid;
+}
+
+// New relative branch, destination is a absolute address (returns
+// branch instruction ID)
+// rs1 is SSAid of register value on which branch condition is determined
+unsigned BinInterface::newabsbranch(unsigned op, unsigned rs1, unsigned *dest){
+  instruction *instr = new instruction();
+  
+  instr->flags = (IF_BR | IF_RCC | IF_RS1 | IF_R_RS1 | IF_RS1_RS2_DEFINED);
+  instr->ebranch.genrs1 = rs1;
+  instr->ebranch.dest = dest;
+  
+  instr->instr = op;
+  unsigned cid = itable.size();
+  instr->self = cid;
+  itable.push_back(instr);
+  
+  return cid;
+}
+
+// New relative branch, destination is a section ID (returns
+// branch instruction ID)
+// NO rs1
+unsigned BinInterface::newabsbranch(unsigned op, unsigned *dest){
+  instruction *instr = new instruction();
+  
+  instr->flags = (IF_BR | IF_RCC);
+  instr->ebranch.dest = dest;
+  
+  instr->instr = op;
+  unsigned cid = itable.size();
+  instr->self = cid;
+  itable.push_back(instr);
+  
+  return cid;
+}
+
+
+
+//set the branch as internal
+//dest is the desctination section
+void BinInterface::setBranchAsInternal(unsigned cid, unsigned dest){
+  instruction *instr = itable[cid];
+  assert(instr->flags & IF_BR && "Not a branch\n");
+  instr->flags |= IF_BRINTERNAL;
+  instr->ibranch.dest = dest;
+}
+
+
+//reverse the branch condition
+void BinInterface::reverseBranch(unsigned cid){
+  instruction *instr = itable[cid];
+  assert(instr->flags & IF_BR && "Not a branch\n");
+  instr->instr = getInvertedBranch(instr->instr);
+}
+
+//change the branch destination
+//should be called ONLY AFTER complete()
+void BinInterface::setBranchDest(unsigned cid, unsigned int *dest){
+  instruction *instr = itable[cid];
+  assert(instr->flags & IF_BR && "Not a branch\n");
+  assert(!(instr->flags & IF_BRINTERNAL) && "Is internal branch");
+  instr->ebranch.dest = dest;
+}
+
+//assign return addr to epilog
+void BinInterface::assignRetAdress(unsigned int sec, unsigned int *addr){
+  assert(sec > 1 && "Not a trace section or a prolog");
+  epToRetAddr[sec] = addr;
+}
+
+//pin down a ssaid
+//pinning down ensures that the oiginal register allocation
+//for a given instruction is preserved: the instruction
+//pinned down writes into the same register it originally wrote into
+//however, the incoming registers might still be changed 
+void BinInterface::pinDown(unsigned int pin){
+  if(itable[pin]->flags & IF_W_RD)
+    pinned.push_back(pin);
+}
+
+void BinInterface::setLiveOutReg(unsigned char rs){
+  liveOutRegs.push_back(rs);
+}
+
+bool BinInterface::hasrs1(unsigned int cid){
+  instruction *inst = itable[cid];
+  assert(inst && "No instruction");
+  
+  unsigned flags = inst->flags;
+  if(flags & IF_R_RS1)
+    return true;
+
+  return false;
+}
+
+bool BinInterface::hasrs2(unsigned int cid){
+  instruction *inst = itable[cid];
+  assert(inst && "No instruction");
+  
+  unsigned flags = inst->flags;
+  if(flags & IF_R_RS2)
+    return true;
+
+  return false;
+}
+
+unsigned int BinInterface::getrs1(unsigned int cid){
+  instruction *inst = itable[cid];
+  assert(inst && "No instruction");
+  
+  unsigned flags = inst->flags;
+  assert(flags & IF_R_RS1 && "No rs1");
+  
+  return inst->alu.genrs1;
+}
+
+unsigned int BinInterface::getrs2(unsigned int cid){
+  instruction *inst = itable[cid];
+  assert(inst && "No instruction");
+  
+  unsigned flags = inst->flags;
+  assert(flags & IF_R_RS2 && "No rs1");
+  
+  return inst->alu.genrs2;
+}
+
+void BinInterface::setrs1(unsigned int cid, unsigned int to){
+  instruction *inst = itable[cid];
+  assert(inst && "No instruction");
+  
+  unsigned flags = inst->flags;
+  assert(flags & IF_R_RS1 && "No rs1");
+  
+  inst->alu.genrs1 = to;
+}
+
+void BinInterface::setrs2(unsigned int cid, unsigned int to){
+  instruction *inst = itable[cid];
+  assert(inst && "No instruction");
+  
+  unsigned flags = inst->flags;
+  assert(flags & IF_R_RS2 && "No rs1");
+  
+  inst->alu.genrs2 = to;
+}





More information about the llvm-commits mailing list