02b02de9ec36c2ade1888988b7c6fd0f856d3497
[oota-llvm.git] / lib / CodeGen / MachOCodeEmitter.cpp
1 //===-- MachOEmitter.cpp - Target-independent Mach-O Emitter code --------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "MachOCodeEmitter.h"
11 #include "llvm/Constants.h"
12 #include "llvm/DerivedTypes.h"
13 #include "llvm/Function.h"
14 #include "llvm/CodeGen/MachineConstantPool.h"
15 #include "llvm/CodeGen/MachineJumpTableInfo.h"
16 #include "llvm/Target/TargetAsmInfo.h"
17 #include "llvm/Support/Mangler.h"
18 #include "llvm/Support/OutputBuffer.h"
19
20 //===----------------------------------------------------------------------===//
21 //                       MachOCodeEmitter Implementation
22 //===----------------------------------------------------------------------===//
23
24 namespace llvm {
25     
26 /// startFunction - This callback is invoked when a new machine function is
27 /// about to be emitted.
28
29 void MachOCodeEmitter::startFunction(MachineFunction &MF) {
30   const TargetData *TD = TM.getTargetData();
31   const Function *F = MF.getFunction();
32
33   // Align the output buffer to the appropriate alignment, power of 2.
34   unsigned FnAlign = F->getAlignment();
35   unsigned TDAlign = TD->getPrefTypeAlignment(F->getType());
36   unsigned Align = Log2_32(std::max(FnAlign, TDAlign));
37   assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
38
39   // Get the Mach-O Section that this function belongs in.
40   MachOSection *MOS = MOW.getTextSection();
41   
42   // FIXME: better memory management
43   MOS->SectionData.reserve(4096);
44   BufferBegin = &MOS->SectionData[0];
45   BufferEnd = BufferBegin + MOS->SectionData.capacity();
46
47   // Upgrade the section alignment if required.
48   if (MOS->align < Align) MOS->align = Align;
49
50   // Round the size up to the correct alignment for starting the new function.
51   if ((MOS->size & ((1 << Align) - 1)) != 0) {
52     MOS->size += (1 << Align);
53     MOS->size &= ~((1 << Align) - 1);
54   }
55
56   // FIXME: Using MOS->size directly here instead of calculating it from the
57   // output buffer size (impossible because the code emitter deals only in raw
58   // bytes) forces us to manually synchronize size and write padding zero bytes
59   // to the output buffer for all non-text sections.  For text sections, we do
60   // not synchonize the output buffer, and we just blow up if anyone tries to
61   // write non-code to it.  An assert should probably be added to
62   // AddSymbolToSection to prevent calling it on the text section.
63   CurBufferPtr = BufferBegin + MOS->size;
64 }
65
66 /// finishFunction - This callback is invoked after the function is completely
67 /// finished.
68
69 bool MachOCodeEmitter::finishFunction(MachineFunction &MF) {
70     
71   // Get the Mach-O Section that this function belongs in.
72   MachOSection *MOS = MOW.getTextSection();
73
74   // Get a symbol for the function to add to the symbol table
75   // FIXME: it seems like we should call something like AddSymbolToSection
76   // in startFunction rather than changing the section size and symbol n_value
77   // here.
78   const GlobalValue *FuncV = MF.getFunction();
79   MachOSym FnSym(FuncV, MOW.Mang->getValueName(FuncV), MOS->Index, TAI);
80   FnSym.n_value = MOS->size;
81   MOS->size = CurBufferPtr - BufferBegin;
82   
83   // Emit constant pool to appropriate section(s)
84   emitConstantPool(MF.getConstantPool());
85
86   // Emit jump tables to appropriate section
87   emitJumpTables(MF.getJumpTableInfo());
88   
89   // If we have emitted any relocations to function-specific objects such as 
90   // basic blocks, constant pools entries, or jump tables, record their
91   // addresses now so that we can rewrite them with the correct addresses
92   // later.
93   for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
94     MachineRelocation &MR = Relocations[i];
95     intptr_t Addr;
96
97     if (MR.isBasicBlock()) {
98       Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
99       MR.setConstantVal(MOS->Index);
100       MR.setResultPointer((void*)Addr);
101     } else if (MR.isJumpTableIndex()) {
102       Addr = getJumpTableEntryAddress(MR.getJumpTableIndex());
103       MR.setConstantVal(MOW.getJumpTableSection()->Index);
104       MR.setResultPointer((void*)Addr);
105     } else if (MR.isConstantPoolIndex()) {
106       Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex());
107       MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]);
108       MR.setResultPointer((void*)Addr);
109     } else if (MR.isGlobalValue()) {
110       // FIXME: This should be a set or something that uniques
111       MOW.PendingGlobals.push_back(MR.getGlobalValue());
112     } else {
113       assert(0 && "Unhandled relocation type");
114     }
115     MOS->Relocations.push_back(MR);
116   }
117   Relocations.clear();
118   
119   // Finally, add it to the symtab.
120   MOW.SymbolTable.push_back(FnSym);
121
122   // Clear per-function data structures.
123   CPLocations.clear();
124   CPSections.clear();
125   JTLocations.clear();
126   MBBLocations.clear();
127
128   return false;
129 }
130
131 /// emitConstantPool - For each constant pool entry, figure out which section
132 /// the constant should live in, allocate space for it, and emit it to the 
133 /// Section data buffer.
134 void MachOCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
135   const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
136   if (CP.empty()) return;
137
138   // FIXME: handle PIC codegen
139   assert(TM.getRelocationModel() != Reloc::PIC_ &&
140          "PIC codegen not yet handled for mach-o jump tables!");
141
142   // Although there is no strict necessity that I am aware of, we will do what
143   // gcc for OS X does and put each constant pool entry in a section of constant
144   // objects of a certain size.  That means that float constants go in the
145   // literal4 section, and double objects go in literal8, etc.
146   //
147   // FIXME: revisit this decision if we ever do the "stick everything into one
148   // "giant object for PIC" optimization.
149   for (unsigned i = 0, e = CP.size(); i != e; ++i) {
150     const Type *Ty = CP[i].getType();
151     unsigned Size = TM.getTargetData()->getTypeAllocSize(Ty);
152
153     MachOSection *Sec = MOW.getConstSection(CP[i].Val.ConstVal);
154     OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
155
156     CPLocations.push_back(Sec->SectionData.size());
157     CPSections.push_back(Sec->Index);
158     
159     // FIXME: remove when we have unified size + output buffer
160     Sec->size += Size;
161
162     // Allocate space in the section for the global.
163     // FIXME: need alignment?
164     // FIXME: share between here and AddSymbolToSection?
165     for (unsigned j = 0; j < Size; ++j)
166       SecDataOut.outbyte(0);
167
168     MOW.InitMem(CP[i].Val.ConstVal, &Sec->SectionData[0], CPLocations[i],
169                 TM.getTargetData(), Sec->Relocations);
170   }
171 }
172
173 /// emitJumpTables - Emit all the jump tables for a given jump table info
174 /// record to the appropriate section.
175
176 void MachOCodeEmitter::emitJumpTables(MachineJumpTableInfo *MJTI) {
177   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
178   if (JT.empty()) return;
179
180   // FIXME: handle PIC codegen
181   assert(TM.getRelocationModel() != Reloc::PIC_ &&
182          "PIC codegen not yet handled for mach-o jump tables!");
183
184   MachOSection *Sec = MOW.getJumpTableSection();
185   unsigned TextSecIndex = MOW.getTextSection()->Index;
186   OutputBuffer SecDataOut(Sec->SectionData, is64Bit, isLittleEndian);
187
188   for (unsigned i = 0, e = JT.size(); i != e; ++i) {
189     // For each jump table, record its offset from the start of the section,
190     // reserve space for the relocations to the MBBs, and add the relocations.
191     const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
192     JTLocations.push_back(Sec->SectionData.size());
193     for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
194       MachineRelocation MR(MOW.GetJTRelocation(Sec->SectionData.size(),
195                                                MBBs[mi]));
196       MR.setResultPointer((void *)JTLocations[i]);
197       MR.setConstantVal(TextSecIndex);
198       Sec->Relocations.push_back(MR);
199       SecDataOut.outaddr(0);
200     }
201   }
202   // FIXME: remove when we have unified size + output buffer
203   Sec->size = Sec->SectionData.size();
204 }
205
206 } // end namespace llvm
207