Fix the failures in the PPC JIT by marking relocation entries for
[oota-llvm.git] / include / llvm / CodeGen / MachineRelocation.h
1 //===-- llvm/CodeGen/MachineRelocation.h - Target Relocation ----*- C++ -*-===//
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 // This file defines the MachineRelocation class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CODEGEN_MACHINERELOCATION_H
15 #define LLVM_CODEGEN_MACHINERELOCATION_H
16
17 #include "llvm/Support/DataTypes.h"
18 #include <cassert>
19
20 namespace llvm {
21 class GlobalValue;
22 class MachineBasicBlock;
23
24 /// MachineRelocation - This represents a target-specific relocation value,
25 /// produced by the code emitter.  This relocation is resolved after the has
26 /// been emitted, either to an object file or to memory, when the target of the
27 /// relocation can be resolved.
28 ///
29 /// A relocation is made up of the following logical portions:
30 ///   1. An offset in the machine code buffer, the location to modify.
31 ///   2. A target specific relocation type (a number from 0 to 63).
32 ///   3. A symbol being referenced, either as a GlobalValue* or as a string.
33 ///   4. An optional constant value to be added to the reference.
34 ///   5. A bit, CanRewrite, which indicates to the JIT that a function stub is
35 ///      not needed for the relocation.
36 ///   6. An index into the GOT, if the target uses a GOT
37 ///
38 class MachineRelocation {
39   enum AddressType {
40     isResult,         // Relocation has be transformed into its result pointer.
41     isGV,             // The Target.GV field is valid.
42     isGVLazyPtr,      // Relocation of a lazily resolved GV address.
43     isBB,             // Relocation of BB address.
44     isExtSym,         // The Target.ExtSym field is valid.
45     isConstPool,      // Relocation of constant pool address.
46     isJumpTable,      // Relocation of jump table address.
47     isGOTIndex        // The Target.GOTIndex field is valid.
48   };
49   
50   /// Offset - This is the offset from the start of the code buffer of the
51   /// relocation to perform.
52   intptr_t Offset;
53   
54   /// ConstantVal - A field that may be used by the target relocation type.
55   intptr_t ConstantVal;
56
57   union {
58     void *Result;           // If this has been resolved to a resolved pointer
59     GlobalValue *GV;        // If this is a pointer to a GV or a GV lazy ptr
60     MachineBasicBlock *MBB; // If this is a pointer to a LLVM BB
61     const char *ExtSym;     // If this is a pointer to a named symbol
62     unsigned Index;         // Constant pool / jump table index
63     unsigned GOTIndex;      // Index in the GOT of this symbol/global
64   } Target;
65
66   unsigned TargetReloType : 6; // The target relocation ID.
67   AddressType AddrType    : 4; // The field of Target to use.
68   bool NeedStub           : 1; // True if this relocation requires a stub.
69   bool GOTRelative        : 1; // Should this relocation be relative to the GOT?
70
71 public:
72  // Relocation types used in a generic implementation.  Currently, relocation
73  // entries for all things use the generic VANILLA type until they are refined
74  // into target relocation types.
75   enum RelocationType {
76     VANILLA
77   };
78   
79   /// MachineRelocation::getGV - Return a relocation entry for a GlobalValue.
80   ///
81   static MachineRelocation getGV(intptr_t offset, unsigned RelocationType, 
82                                  GlobalValue *GV, intptr_t cst = 0,
83                                  bool NeedStub = 0,
84                                  bool GOTrelative = 0) {
85     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
86     MachineRelocation Result;
87     Result.Offset = offset;
88     Result.ConstantVal = cst;
89     Result.TargetReloType = RelocationType;
90     Result.AddrType = isGV;
91     Result.NeedStub = NeedStub;
92     Result.GOTRelative = GOTrelative;
93     Result.Target.GV = GV;
94     return Result;
95   }
96
97   /// MachineRelocation::getGVLazyPtr - Return a relocation entry for a
98   /// lazily resolved GlobalValue address.
99   static MachineRelocation getGVLazyPtr(intptr_t offset,
100                                  unsigned RelocationType, 
101                                  GlobalValue *GV, intptr_t cst = 0,
102                                  bool NeedStub = 0,
103                                  bool GOTrelative = 0) {
104     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
105     MachineRelocation Result;
106     Result.Offset = offset;
107     Result.ConstantVal = cst;
108     Result.TargetReloType = RelocationType;
109     Result.AddrType = isGVLazyPtr;
110     Result.NeedStub = NeedStub;
111     Result.GOTRelative = GOTrelative;
112     Result.Target.GV = GV;
113     return Result;
114   }
115
116   /// MachineRelocation::getBB - Return a relocation entry for a BB.
117   ///
118   static MachineRelocation getBB(intptr_t offset,unsigned RelocationType,
119                                  MachineBasicBlock *MBB, intptr_t cst = 0) {
120     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
121     MachineRelocation Result;
122     Result.Offset = offset;
123     Result.ConstantVal = cst;
124     Result.TargetReloType = RelocationType;
125     Result.AddrType = isBB;
126     Result.NeedStub = false;
127     Result.GOTRelative = false;
128     Result.Target.MBB = MBB;
129     return Result;
130   }
131
132   /// MachineRelocation::getExtSym - Return a relocation entry for an external
133   /// symbol, like "free".
134   ///
135   static MachineRelocation getExtSym(intptr_t offset, unsigned RelocationType, 
136                                      const char *ES, intptr_t cst = 0,
137                                      bool GOTrelative = 0) {
138     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
139     MachineRelocation Result;
140     Result.Offset = offset;
141     Result.ConstantVal = cst;
142     Result.TargetReloType = RelocationType;
143     Result.AddrType = isExtSym;
144     Result.NeedStub = true;
145     Result.GOTRelative = GOTrelative;
146     Result.Target.ExtSym = ES;
147     return Result;
148   }
149
150   /// MachineRelocation::getConstPool - Return a relocation entry for a constant
151   /// pool entry.
152   ///
153   static MachineRelocation getConstPool(intptr_t offset,unsigned RelocationType,
154                                         unsigned CPI, intptr_t cst = 0) {
155     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
156     MachineRelocation Result;
157     Result.Offset = offset;
158     Result.ConstantVal = cst;
159     Result.TargetReloType = RelocationType;
160     Result.AddrType = isConstPool;
161     Result.NeedStub = false;
162     Result.GOTRelative = false;
163     Result.Target.Index = CPI;
164     return Result;
165   }
166
167   /// MachineRelocation::getJumpTable - Return a relocation entry for a jump
168   /// table entry.
169   ///
170   static MachineRelocation getJumpTable(intptr_t offset,unsigned RelocationType,
171                                         unsigned JTI, intptr_t cst = 0) {
172     assert((RelocationType & ~63) == 0 && "Relocation type too large!");
173     MachineRelocation Result;
174     Result.Offset = offset;
175     Result.ConstantVal = cst;
176     Result.TargetReloType = RelocationType;
177     Result.AddrType = isJumpTable;
178     Result.NeedStub = false;
179     Result.GOTRelative = false;
180     Result.Target.Index = JTI;
181     return Result;
182   }
183
184   /// getMachineCodeOffset - Return the offset into the code buffer that the
185   /// relocation should be performed.
186   intptr_t getMachineCodeOffset() const {
187     return Offset;
188   }
189
190   /// getRelocationType - Return the target-specific relocation ID for this
191   /// relocation.
192   unsigned getRelocationType() const {
193     return TargetReloType;
194   }
195
196   /// getConstantVal - Get the constant value associated with this relocation.
197   /// This is often an offset from the symbol.
198   ///
199   intptr_t getConstantVal() const {
200     return ConstantVal;
201   }
202
203   /// setConstantVal - Set the constant value associated with this relocation.
204   /// This is often an offset from the symbol.
205   ///
206   void setConstantVal(intptr_t val) {
207     ConstantVal = val;
208   }
209
210   /// isGlobalValue - Return true if this relocation is a GlobalValue, as
211   /// opposed to a constant string.
212   bool isGlobalValue() const {
213     return AddrType == isGV;
214   }
215
216   /// isGlobalValueVLazyPtr - Return true if this relocation is the address
217   /// of a lazily resolved GlobalValue.
218   bool isGlobalValueLazyPtr() const {
219     return AddrType == isGVLazyPtr;
220   }
221
222   /// isBasicBlock - Return true if this relocation is a basic block reference.
223   ///
224   bool isBasicBlock() const {
225     return AddrType == isBB;
226   }
227
228   /// isString - Return true if this is a constant string.
229   ///
230   bool isString() const {
231     return AddrType == isExtSym;
232   }
233
234   /// isConstantPoolIndex - Return true if this is a constant pool reference.
235   ///
236   bool isConstantPoolIndex() const {
237     return AddrType == isConstPool;
238   }
239
240   /// isJumpTableIndex - Return true if this is a jump table reference.
241   ///
242   bool isJumpTableIndex() const {
243     return AddrType == isJumpTable;
244   }
245
246   /// isGOTRelative - Return true the target wants the index into the GOT of
247   /// the symbol rather than the address of the symbol.
248   bool isGOTRelative() const {
249     return GOTRelative;
250   }
251
252   /// doesntNeedStub - This function returns true if the JIT for this target
253   /// target is capable of directly handling the relocated GlobalValue reference
254   /// without using either a stub function or issuing an extra load to get the
255   /// GV address.
256   bool doesntNeedStub() const {
257     return !NeedStub;
258   }
259
260   /// getGlobalValue - If this is a global value reference, return the
261   /// referenced global.
262   GlobalValue *getGlobalValue() const {
263     assert((isGlobalValue() || isGlobalValueLazyPtr()) &&
264            "This is not a global value reference!");
265     return Target.GV;
266   }
267
268   MachineBasicBlock *getBasicBlock() const {
269     assert(isBasicBlock() && "This is not a basic block reference!");
270     return Target.MBB;
271   }
272
273   /// getString - If this is a string value, return the string reference.
274   ///
275   const char *getString() const {
276     assert(isString() && "This is not a string reference!");
277     return Target.ExtSym;
278   }
279
280   /// getConstantPoolIndex - If this is a const pool reference, return
281   /// the index into the constant pool.
282   unsigned getConstantPoolIndex() const {
283     assert(isConstantPoolIndex() && "This is not a constant pool reference!");
284     return Target.Index;
285   }
286
287   /// getJumpTableIndex - If this is a jump table reference, return
288   /// the index into the jump table.
289   unsigned getJumpTableIndex() const {
290     assert(isJumpTableIndex() && "This is not a jump table reference!");
291     return Target.Index;
292   }
293
294   /// getResultPointer - Once this has been resolved to point to an actual
295   /// address, this returns the pointer.
296   void *getResultPointer() const {
297     assert(AddrType == isResult && "Result pointer isn't set yet!");
298     return Target.Result;
299   }
300
301   /// setResultPointer - Set the result to the specified pointer value.
302   ///
303   void setResultPointer(void *Ptr) {
304     Target.Result = Ptr;
305     AddrType = isResult;
306   }
307
308   /// setGOTIndex - Set the GOT index to a specific value.
309   void setGOTIndex(unsigned idx) {
310     AddrType = isGOTIndex;
311     Target.GOTIndex = idx;
312   }
313
314   /// getGOTIndex - Once this has been resolved to an entry in the GOT,
315   /// this returns that index.  The index is from the lowest address entry
316   /// in the GOT.
317   unsigned getGOTIndex() const {
318     assert(AddrType == isGOTIndex);
319     return Target.GOTIndex;
320   }
321 };
322 }
323
324 #endif