1 //===-- Emitter.cpp - Write machine code to executable memory -------------===//
3 // This file defines a MachineCodeEmitter object that is used by Jello to write
4 // machine code to memory and remember where relocatable values lie.
6 //===----------------------------------------------------------------------===//
9 #include "llvm/CodeGen/MachineCodeEmitter.h"
10 #include "llvm/CodeGen/MachineFunction.h"
11 #include "llvm/CodeGen/MachineConstantPool.h"
12 #include "llvm/Target/TargetData.h"
13 #include "llvm/Function.h"
14 #include "Support/Statistic.h"
17 Statistic<> NumBytes("jello", "Number of bytes of machine code compiled");
19 class Emitter : public MachineCodeEmitter {
22 unsigned char *CurBlock, *CurByte;
24 // When outputting a function stub in the context of some other function, we
25 // save CurBlock and CurByte here.
26 unsigned char *SavedCurBlock, *SavedCurByte;
28 std::vector<std::pair<BasicBlock*, unsigned *> > BBRefs;
29 std::map<BasicBlock*, unsigned> BBLocations;
30 std::vector<void*> ConstantPoolAddresses;
32 Emitter(VM &vm) : TheVM(vm) {}
34 virtual void startFunction(MachineFunction &F);
35 virtual void finishFunction(MachineFunction &F);
36 virtual void emitConstantPool(MachineConstantPool *MCP);
37 virtual void startBasicBlock(MachineBasicBlock &BB);
38 virtual void startFunctionStub(const Function &F, unsigned StubSize);
39 virtual void* finishFunctionStub(const Function &F);
40 virtual void emitByte(unsigned char B);
41 virtual void emitPCRelativeDisp(Value *V);
42 virtual void emitGlobalAddress(GlobalValue *V, bool isPCRelative);
43 virtual void emitGlobalAddress(const std::string &Name, bool isPCRelative);
44 virtual void emitFunctionConstantValueAddress(unsigned ConstantNum,
47 void emitAddress(void *Addr, bool isPCRelative);
51 MachineCodeEmitter *VM::createX86Emitter(VM &V) {
52 return new Emitter(V);
56 #define _POSIX_MAPPED_FILES
60 // FIXME: This should be rewritten to support a real memory manager for
61 // executable memory pages!
62 static void *getMemory(unsigned NumPages) {
63 return mmap(0, 4096*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
64 MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
68 void Emitter::startFunction(MachineFunction &F) {
69 CurBlock = (unsigned char *)getMemory(8);
70 CurByte = CurBlock; // Start writing at the beginning of the fn.
71 TheVM.addGlobalMapping(F.getFunction(), CurBlock);
74 void Emitter::finishFunction(MachineFunction &F) {
75 ConstantPoolAddresses.clear();
76 for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
77 unsigned Location = BBLocations[BBRefs[i].first];
78 unsigned *Ref = BBRefs[i].second;
79 *Ref = Location-(unsigned)(intptr_t)Ref-4;
84 NumBytes += CurByte-CurBlock;
86 DEBUG(std::cerr << "Finished CodeGen of [0x" << std::hex
87 << (unsigned)(intptr_t)CurBlock
88 << std::dec << "] Function: " << F.getFunction()->getName()
89 << ": " << CurByte-CurBlock << " bytes of text\n");
92 void Emitter::emitConstantPool(MachineConstantPool *MCP) {
93 const std::vector<Constant*> &Constants = MCP->getConstants();
94 for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
95 // For now we just allocate some memory on the heap, this can be
96 // dramatically improved.
97 const Type *Ty = ((Value*)Constants[i])->getType();
98 void *Addr = malloc(TheVM.getTargetData().getTypeSize(Ty));
99 TheVM.InitializeMemory(Constants[i], Addr);
100 ConstantPoolAddresses.push_back(Addr);
105 void Emitter::startBasicBlock(MachineBasicBlock &BB) {
106 BBLocations[BB.getBasicBlock()] = (unsigned)(intptr_t)CurByte;
110 void Emitter::startFunctionStub(const Function &F, unsigned StubSize) {
111 SavedCurBlock = CurBlock; SavedCurByte = CurByte;
112 // FIXME: this is a huge waste of memory.
113 CurBlock = (unsigned char *)getMemory((StubSize+4095)/4096);
114 CurByte = CurBlock; // Start writing at the beginning of the fn.
117 void *Emitter::finishFunctionStub(const Function &F) {
118 NumBytes += CurByte-CurBlock;
119 DEBUG(std::cerr << "Finished CodeGen of [0x" << std::hex
120 << (unsigned)(intptr_t)CurBlock
121 << std::dec << "] Function stub for: " << F.getName()
122 << ": " << CurByte-CurBlock << " bytes of text\n");
123 std::swap(CurBlock, SavedCurBlock);
124 CurByte = SavedCurByte;
125 return SavedCurBlock;
128 void Emitter::emitByte(unsigned char B) {
129 *CurByte++ = B; // Write the byte to memory
133 // emitPCRelativeDisp - For functions, just output a displacement that will
134 // cause a reference to the zero page, which will cause a seg-fault, causing
135 // things to get resolved on demand. Keep track of these markers.
137 // For basic block references, keep track of where the references are so they
138 // may be patched up when the basic block is defined.
140 void Emitter::emitPCRelativeDisp(Value *V) {
141 BasicBlock *BB = cast<BasicBlock>(V); // Keep track of reference...
142 BBRefs.push_back(std::make_pair(BB, (unsigned*)CurByte));
146 // emitAddress - Emit an address in either direct or PCRelative form...
148 void Emitter::emitAddress(void *Addr, bool isPCRelative) {
150 *(intptr_t*)CurByte = (intptr_t)Addr - (intptr_t)CurByte-4;
152 *(void**)CurByte = Addr;
157 void Emitter::emitGlobalAddress(GlobalValue *V, bool isPCRelative) {
158 if (isPCRelative) { // must be a call, this is a major hack!
159 // Try looking up the function to see if it is already compiled!
160 if (void *Addr = TheVM.getPointerToGlobalIfAvailable(V)) {
161 emitAddress(Addr, isPCRelative);
162 } else { // Function has not yet been code generated!
163 TheVM.addFunctionRef(CurByte, cast<Function>(V));
165 // Delayed resolution...
166 emitAddress((void*)VM::CompilationCallback, isPCRelative);
169 emitAddress(TheVM.getPointerToGlobal(V), isPCRelative);
173 void Emitter::emitGlobalAddress(const std::string &Name, bool isPCRelative) {
174 emitAddress(TheVM.getPointerToNamedFunction(Name), isPCRelative);
177 void Emitter::emitFunctionConstantValueAddress(unsigned ConstantNum,
179 assert(ConstantNum < ConstantPoolAddresses.size() &&
180 "Invalid ConstantPoolIndex!");
181 *(void**)CurByte = (char*)ConstantPoolAddresses[ConstantNum]+Offset;