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