From 3432d1d1d5684098cdfd6e16f0ab6f209d0973b4 Mon Sep 17 00:00:00 2001 From: Misha Brukman Date: Tue, 27 May 2003 22:43:19 +0000 Subject: [PATCH] Added a debugging code emitter that prints code to a file, debug to std::cerr, and passes the real code to a memory-outputting code emitter. This may be removed at a later point in development. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@6379 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineCodeEmitter.cpp | 121 +++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/lib/CodeGen/MachineCodeEmitter.cpp b/lib/CodeGen/MachineCodeEmitter.cpp index d91efe2cc1b..ae4d7cecec6 100644 --- a/lib/CodeGen/MachineCodeEmitter.cpp +++ b/lib/CodeGen/MachineCodeEmitter.cpp @@ -8,6 +8,7 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/Function.h" #include +#include namespace { struct DebugMachineCodeEmitter : public MachineCodeEmitter { @@ -59,3 +60,123 @@ namespace { MachineCodeEmitter *MachineCodeEmitter::createDebugMachineCodeEmitter() { return new DebugMachineCodeEmitter(); } + +namespace { + class FilePrinterMachineCodeEmitter : public MachineCodeEmitter { + std::ofstream f, actual; + std::ostream &o; + MachineCodeEmitter *MCE; + unsigned counter; + bool mustClose; + unsigned values[4]; + + public: + FilePrinterMachineCodeEmitter() : + f("lli.out"), o(f), counter(0), mustClose(true) + { + if (! f.good()) { + std::cerr << "Cannot open 'lli.out' for writing\n"; + abort(); + } + openActual(); + } + + FilePrinterMachineCodeEmitter(MachineCodeEmitter &M, std::ostream &os) : + o(os), MCE(&M), counter(0) + { + FilePrinterMachineCodeEmitter(); + mustClose = false; + openActual(); + } + + ~FilePrinterMachineCodeEmitter() { + o << "\n"; + actual.close(); + if (mustClose) f.close(); + } + + void openActual() { + actual.open("lli.actual.obj"); + if (! actual.good()) { + std::cerr << "Cannot open 'lli.actual.obj' for writing\n"; + abort(); + } + } + + void startFunction(MachineFunction &F) { + // resolve any outstanding calls + if (MCE) MCE->startFunction(F); + } + void finishFunction(MachineFunction &F) { + if (MCE) MCE->finishFunction(F); + } + + void startBasicBlock(MachineBasicBlock &BB) { + // if any instructions were waiting for the address of this block, + // let them fix their addresses now + if (MCE) MCE->startBasicBlock(BB); + } + + void startFunctionStub(const Function &F, unsigned StubSize) { + // + if (MCE) MCE->startFunctionStub(F, StubSize); + } + + void *finishFunctionStub(const Function &F) { + if (MCE) return MCE->finishFunctionStub(F); + else return 0; + } + + void emitByte(unsigned char B) { + if (MCE) MCE->emitByte(B); + + values[counter] = (unsigned int) B; + if (++counter % 4 == 0 && counter != 0) { + o << std::hex; + for (unsigned i=0; i<4; ++i) { + if (values[i] < 16) o << "0"; + o << values[i] << " "; + actual << values[i]; + } + actual.flush(); + + o << std::dec << "\t"; + for (unsigned i=0; i<4; ++i) { + for (int j=7; j>=0; --j) { + o << ((values[i] >> j) & 1); + } + o << " "; + } + + o << "\n"; + + unsigned instr = 0; + for (unsigned i=0; i<4; ++i) + instr |= values[i] << (i*8); + + o << "--- * --- * --- * --- * ---\n"; + counter %= 4; + } + } + void emitPCRelativeDisp(Value *V) { + // put block in mapping BB -> { instr, address }. when BB is beginning to + // output, find instr, set disp, overwrite instr at addr using the + // unsigned value gotten from emitter + } + + void emitGlobalAddress(GlobalValue *V, bool isPCRelative) { + if (MCE) MCE->emitGlobalAddress(V, isPCRelative); + } + void emitGlobalAddress(const std::string &Name, bool isPCRelative) { + if (MCE) MCE->emitGlobalAddress(Name, isPCRelative); + } + + void emitFunctionConstantValueAddress(unsigned ConstantNum, int Offset) { + if (MCE) MCE->emitFunctionConstantValueAddress(ConstantNum, Offset); + } + }; +} + +MachineCodeEmitter *MachineCodeEmitter::createFilePrinterMachineCodeEmitter(MachineCodeEmitter &MCE) { + return new FilePrinterMachineCodeEmitter(MCE, std::cerr); +}