[llvm-commits] CVS: llvm/lib/Reoptimizer/Inst/InstManip.cpp InstManip.h Phase2.cpp
Joel Stanley
jstanley at cs.uiuc.edu
Tue Apr 8 23:31:00 PDT 2003
Changes in directory llvm/lib/Reoptimizer/Inst:
InstManip.cpp added (r1.1)
InstManip.h added (r1.1)
Phase2.cpp updated: 1.3 -> 1.4
---
Log message:
Factored out InstManip code into separate files.
---
Diffs of the changes:
Index: llvm/lib/Reoptimizer/Inst/Phase2.cpp
diff -u llvm/lib/Reoptimizer/Inst/Phase2.cpp:1.3 llvm/lib/Reoptimizer/Inst/Phase2.cpp:1.4
--- llvm/lib/Reoptimizer/Inst/Phase2.cpp:1.3 Tue Apr 8 22:37:42 2003
+++ llvm/lib/Reoptimizer/Inst/Phase2.cpp Tue Apr 8 23:32:03 2003
@@ -33,63 +33,17 @@
#include <iomanip>
#include <vector>
-#include "ElfReader.h"
#include "llvm/Reoptimizer/TraceCache.h"
#include "llvm/Reoptimizer/VirtualMem.h"
-#include "llvm/Reoptimizer/InstrUtils.h"
-#include "../BinInterface/sparcdis.h" // TODO: Move to proper include directory
-#include "../BinInterface/sparc9.h" // TODO: Move to proper include directory
-#include "../BinInterface/bitmath.h" // TODO: Move to proper include directory
#include "../TraceCache/MemoryManager.h" // TODO: Move to proper include directory
+#include "ElfReader.h"
+#include "InstManip.h"
+
using std::vector;
using std::cerr;
using std::endl;
-typedef std::pair<uint64_t, uint64_t> AddressRange;
-
-// InstManip is a wrapper class around any BinInterface macros/mechanisms, as well as the
-// TraceCache "instruction utilities, all which are SparcV9-specific; this class exists
-// both for conceptual clarity and to facilitate hiding the Sparc-specificity from the
-// Phase2 actions (and thus making it easier to use the phase2 transformations on other
-// platforms in the future; we should be able to change which instruction manipulator
-// object is instantiated, after making the appropriate superclass, etc).
-
-class InstManip
-{
- public:
- void printRange(unsigned* start, unsigned* end);
- inline void printRange(AddressRange& range);
- inline void printRange(uint64_t start, uint64_t end);
-
- inline void printInst(unsigned inst);
- inline void printInst(unsigned* instAddr);
-
- uint64_t skipFunctionHdr(uint64_t addr, VirtualMem* vm);
-
- void generateLoad64(uint64_t value, vector<unsigned>& snippet);
-
- unsigned getBranchAlways(uint64_t dest, uint64_t pc, bool annulHigh = true);
- inline unsigned getCall(uint64_t dest, uint64_t pc);
-
- unsigned getNOP() const { return 0x01000000; }
- unsigned getGenLoad64Size() const { return 6; }
-
- private:
- ////////////////
- // Instruction constants and field-extraction "macros", etc.
-
- // Branch-always (annul bit high) instruction base (i.e. address not filled in yet)
- static const int wtf = 19;
-
- static const unsigned BRANCH_ALWAYS_BASE = 0x30480000;
-
- unsigned low10(unsigned value) { return value & 0x000003ff; }
- unsigned high22(unsigned value) { return value >> 10; }
- unsigned highWord(uint64_t value) { return (unsigned) (value >> 32); }
- unsigned lowWord(uint64_t value) { return (unsigned) value; }
-};
-
// Phase2 is the class that is responsible for effecting the core of the phase 2
// transformation; the global function phase2() is simply an C-linkage interface.
@@ -97,7 +51,7 @@
{
public:
void transform();
- void transformFunction(AddressRange& range);
+ void transformFunction(std::pair<uint64_t, uint64_t>& range);
private:
inline unsigned getSlotSize() const;
@@ -122,12 +76,12 @@
ElfReader elfReader(execName);
std::string funcName;
- AddressRange range;
+ std::pair<uint64_t, uint64_t> range;
while(elfReader.GetNextFunction(funcName, range)) {
if(funcName == "l16_fibs") {
//cerr << "Printing information about function " << funcName << endl;
- //m_instManip.printRange(range);
+ m_instManip.printRange(range.first, range.second);
cerr << "Transforming function " << funcName << "..." << endl;
transformFunction(range);
@@ -144,7 +98,7 @@
fflush(stdout);
}
-void Phase2::transformFunction(AddressRange& range)
+void Phase2::transformFunction(std::pair<uint64_t, uint64_t>& range)
{
////////////////
// 1. Replace the first instruction in F with a branch to a new slot (annulling bit
@@ -169,7 +123,7 @@
uint64_t slotBase = mm->getMemory(getSlotSize());
unsigned origInstr = vm->readInstrFrmVm(repInstAddr);
- if(isBranchInstr(origInstr))
+ if(m_instManip.isBranch(origInstr))
assert(0 && "Unhandled case: branch instruction first in function body");
// Replace the instruction at repInstAddr with a branch to the start of the slot
@@ -212,91 +166,3 @@
return m_instManip.getGenLoad64Size() + 5;
}
-
-//////////////// InstManip implementation ////////////////
-
-void InstManip::printRange(unsigned* start, unsigned* end)
-{
- // Dumps contents (and corresponding disassembly) of memory range given by range
- // to stdout. TODO: Parameterize by an ostream instance; cannot do this yet
- // because BinInterface is hard-coded to use printf and must be changed.
-
- std::cout << "Sparc dissassembly of range ["
- << start << ", " << end << "]:" << endl;
-
- for(; start <= end; ++start) {
- std::cout << start << " | "
- << std::hex << std::setw(8) << std::setfill('0')
- << *start << " | ";
- sparc_print(*start);
- std::cout << endl;
- }
-}
-
-void InstManip::printRange(AddressRange& range)
-{
- printRange((unsigned*) range.first, (unsigned*) range.second);
-}
-
-void InstManip::printRange(uint64_t start, uint64_t end)
-{
- printRange((unsigned*) start, (unsigned*) end);
-}
-
-void InstManip::printInst(unsigned inst)
-{
- sparc_print(inst);
- fflush(stdout);
-}
-
-void InstManip::printInst(unsigned* instAddr)
-{
- sparc_print(*instAddr);
- fflush(stdout);
-}
-
-uint64_t InstManip::skipFunctionHdr(uint64_t addr, VirtualMem* vm)
-{
- // For SparcV9, what we're calling the "function header" is the save instruction (if
- // present) that occurs as the first instruction of the function.
-
- unsigned inst = vm->readInstrFrmVm(addr);
- return RD_FLD(inst, INSTR_OP3) == OP3_SAVE ? addr + 4 : addr;
-}
-
-void InstManip::generateLoad64(uint64_t value, vector<unsigned>& snippet)
-{
- // Using %o0 and %o1, load the 64-bit value 'value' into %o0. The sequence of
- // instructions to do this is placed in the provided instruction vector 'snippet'.
-
- unsigned initSize = snippet.size();
- snippet.push_back(0x11000000 | high22(highWord(value))); // sethi (upper 22b of upper wrd), %o0
- snippet.push_back(0x90122000 | low10(highWord(value))); // or %o0, (lower 10b of upper wrd), %o0
- snippet.push_back(0x912a3020); // sllx %o0, 32, %o0
- snippet.push_back(0x13000000 | high22(lowWord(value))); // sethi (upper 22b of lwr wrd), %o1
- snippet.push_back(0x90120009); // or %o0, %o1, %o0
- snippet.push_back(0x90022000 | low10(lowWord(value))); // add %o0, (lwr 10b of lwr wrd), %o0
-
- assert(snippet.size() - initSize == getGenLoad64Size() &&
- "Unexpected number of instructions in code sequence for 64-bit value -> %o0");
-}
-
-unsigned InstManip::getBranchAlways(uint64_t dest, uint64_t pc, bool annul)
-{
- // dest is the destination address, pc is the value of the program counter when the
- // branch instruction is executed (i.e., the address of the branch instruction). NB:
- // Only handles branch-always-annul-high at the moment
-
- assert(annul && "Unhandled case: annul bit low");
- return getUndepJumpInstr(BRANCH_ALWAYS_BASE, dest, pc);
-}
-
-unsigned InstManip::getCall(uint64_t dest, uint64_t pc)
-{
- // dest is the destination address to call, pc is the value of the program counter
- // when the call instruction is executed (i.e., the address of the branch
- // instruction).
-
- return getCallInstr(dest, pc);
-}
-
More information about the llvm-commits
mailing list