1//===-- ARMJITInfo.h - ARM implementation of the JIT interface  -*- 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 contains the declaration of the ARMJITInfo class.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef ARMJITINFO_H
15#define ARMJITINFO_H
16
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/CodeGen/MachineConstantPool.h"
20#include "llvm/CodeGen/MachineFunction.h"
21#include "llvm/CodeGen/MachineJumpTableInfo.h"
22#include "llvm/Target/TargetJITInfo.h"
23
24namespace llvm {
25  class ARMTargetMachine;
26
27  class ARMJITInfo : public TargetJITInfo {
28    // ConstPoolId2AddrMap - A map from constant pool ids to the corresponding
29    // CONSTPOOL_ENTRY addresses.
30    SmallVector<intptr_t, 16> ConstPoolId2AddrMap;
31
32    // JumpTableId2AddrMap - A map from inline jumptable ids to the
33    // corresponding inline jump table bases.
34    SmallVector<intptr_t, 16> JumpTableId2AddrMap;
35
36    // PCLabelMap - A map from PC labels to addresses.
37    DenseMap<unsigned, intptr_t> PCLabelMap;
38
39    // Sym2IndirectSymMap - A map from symbol (GlobalValue and ExternalSymbol)
40    // addresses to their indirect symbol addresses.
41    DenseMap<void*, intptr_t> Sym2IndirectSymMap;
42
43    // IsPIC - True if the relocation model is PIC. This is used to determine
44    // how to codegen function stubs.
45    bool IsPIC;
46
47  public:
48    explicit ARMJITInfo() : IsPIC(false) { useGOT = false; }
49
50    /// replaceMachineCodeForFunction - Make it so that calling the function
51    /// whose machine code is at OLD turns into a call to NEW, perhaps by
52    /// overwriting OLD with a branch to NEW.  This is used for self-modifying
53    /// code.
54    ///
55    void replaceMachineCodeForFunction(void *Old, void *New) override;
56
57    /// emitGlobalValueIndirectSym - Use the specified JITCodeEmitter object
58    /// to emit an indirect symbol which contains the address of the specified
59    /// ptr.
60    void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
61                                    JITCodeEmitter &JCE) override;
62
63    // getStubLayout - Returns the size and alignment of the largest call stub
64    // on ARM.
65    StubLayout getStubLayout() override;
66
67    /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
68    /// small native function that simply calls the function at the specified
69    /// address.
70    void *emitFunctionStub(const Function* F, void *Fn,
71                           JITCodeEmitter &JCE) override;
72
73    /// getLazyResolverFunction - Expose the lazy resolver to the JIT.
74    LazyResolverFn getLazyResolverFunction(JITCompilerFn) override;
75
76    /// relocate - Before the JIT can run a block of code that has been emitted,
77    /// it must rewrite the code to contain the actual addresses of any
78    /// referenced global symbols.
79    void relocate(void *Function, MachineRelocation *MR,
80                  unsigned NumRelocs, unsigned char* GOTBase) override;
81
82    /// hasCustomConstantPool - Allows a target to specify that constant
83    /// pool address resolution is handled by the target.
84    bool hasCustomConstantPool() const override { return true; }
85
86    /// hasCustomJumpTables - Allows a target to specify that jumptables
87    /// are emitted by the target.
88    bool hasCustomJumpTables() const override { return true; }
89
90    /// allocateSeparateGVMemory - If true, globals should be placed in
91    /// separately allocated heap memory rather than in the same
92    /// code memory allocated by JITCodeEmitter.
93    bool allocateSeparateGVMemory() const override {
94#ifdef __APPLE__
95      return true;
96#else
97      return false;
98#endif
99    }
100
101    /// Initialize - Initialize internal stage for the function being JITted.
102    /// Resize constant pool ids to CONSTPOOL_ENTRY addresses map; resize
103    /// jump table ids to jump table bases map; remember if codegen relocation
104    /// model is PIC.
105    void Initialize(const MachineFunction &MF, bool isPIC);
106
107    /// getConstantPoolEntryAddr - The ARM target puts all constant
108    /// pool entries into constant islands. This returns the address of the
109    /// constant pool entry of the specified index.
110    intptr_t getConstantPoolEntryAddr(unsigned CPI) const {
111      assert(CPI < ConstPoolId2AddrMap.size());
112      return ConstPoolId2AddrMap[CPI];
113    }
114
115    /// addConstantPoolEntryAddr - Map a Constant Pool Index to the address
116    /// where its associated value is stored. When relocations are processed,
117    /// this value will be used to resolve references to the constant.
118    void addConstantPoolEntryAddr(unsigned CPI, intptr_t Addr) {
119      assert(CPI < ConstPoolId2AddrMap.size());
120      ConstPoolId2AddrMap[CPI] = Addr;
121    }
122
123    /// getJumpTableBaseAddr - The ARM target inline all jump tables within
124    /// text section of the function. This returns the address of the base of
125    /// the jump table of the specified index.
126    intptr_t getJumpTableBaseAddr(unsigned JTI) const {
127      assert(JTI < JumpTableId2AddrMap.size());
128      return JumpTableId2AddrMap[JTI];
129    }
130
131    /// addJumpTableBaseAddr - Map a jump table index to the address where
132    /// the corresponding inline jump table is emitted. When relocations are
133    /// processed, this value will be used to resolve references to the
134    /// jump table.
135    void addJumpTableBaseAddr(unsigned JTI, intptr_t Addr) {
136      assert(JTI < JumpTableId2AddrMap.size());
137      JumpTableId2AddrMap[JTI] = Addr;
138    }
139
140    /// getPCLabelAddr - Retrieve the address of the PC label of the
141    /// specified id.
142    intptr_t getPCLabelAddr(unsigned Id) const {
143      DenseMap<unsigned, intptr_t>::const_iterator I = PCLabelMap.find(Id);
144      assert(I != PCLabelMap.end());
145      return I->second;
146    }
147
148    /// addPCLabelAddr - Remember the address of the specified PC label.
149    void addPCLabelAddr(unsigned Id, intptr_t Addr) {
150      PCLabelMap.insert(std::make_pair(Id, Addr));
151    }
152
153    /// getIndirectSymAddr - Retrieve the address of the indirect symbol of the
154    /// specified symbol located at address. Returns 0 if the indirect symbol
155    /// has not been emitted.
156    intptr_t getIndirectSymAddr(void *Addr) const {
157      DenseMap<void*,intptr_t>::const_iterator I= Sym2IndirectSymMap.find(Addr);
158      if (I != Sym2IndirectSymMap.end())
159        return I->second;
160      return 0;
161    }
162
163    /// addIndirectSymAddr - Add a mapping from address of an emitted symbol to
164    /// its indirect symbol address.
165    void addIndirectSymAddr(void *SymAddr, intptr_t IndSymAddr) {
166      Sym2IndirectSymMap.insert(std::make_pair(SymAddr, IndSymAddr));
167    }
168
169  private:
170    /// resolveRelocDestAddr - Resolve the resulting address of the relocation
171    /// if it's not already solved. Constantpool entries must be resolved by
172    /// ARM target.
173    intptr_t resolveRelocDestAddr(MachineRelocation *MR) const;
174  };
175}
176
177#endif
178