[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