131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- ARMJITInfo.h - ARM implementation of the JIT interface  -*- C++ -*-===//
2148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng//
3148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng//                     The LLVM Compiler Infrastructure
4148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng//
54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source
64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details.
7148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng//
8148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng//===----------------------------------------------------------------------===//
9148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng//
10148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng// This file contains the declaration of the ARMJITInfo class.
11148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng//
12148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng//===----------------------------------------------------------------------===//
13148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng
14148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng#ifndef ARMJITINFO_H
15148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng#define ARMJITINFO_H
16148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng
17f1bbb9577a42cf7dc3079412f1dd7683e3a03665Evan Cheng#include "ARMMachineFunctionInfo.h"
18a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "llvm/ADT/DenseMap.h"
19a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "llvm/ADT/SmallVector.h"
2025e04788bfddc54dde7bed65302146b46089a166Evan Cheng#include "llvm/CodeGen/MachineConstantPool.h"
214df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng#include "llvm/CodeGen/MachineFunction.h"
224df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h"
23f1bbb9577a42cf7dc3079412f1dd7683e3a03665Evan Cheng#include "llvm/Target/TargetJITInfo.h"
24148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng
25148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Chengnamespace llvm {
26148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng  class ARMTargetMachine;
27148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng
28148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng  class ARMJITInfo : public TargetJITInfo {
290f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng    // ConstPoolId2AddrMap - A map from constant pool ids to the corresponding
300f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng    // CONSTPOOL_ENTRY addresses.
314df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    SmallVector<intptr_t, 16> ConstPoolId2AddrMap;
324df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng
334df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    // JumpTableId2AddrMap - A map from inline jumptable ids to the
344df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    // corresponding inline jump table bases.
354df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    SmallVector<intptr_t, 16> JumpTableId2AddrMap;
360f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng
3725e04788bfddc54dde7bed65302146b46089a166Evan Cheng    // PCLabelMap - A map from PC labels to addresses.
3825e04788bfddc54dde7bed65302146b46089a166Evan Cheng    DenseMap<unsigned, intptr_t> PCLabelMap;
3925e04788bfddc54dde7bed65302146b46089a166Evan Cheng
40588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    // Sym2IndirectSymMap - A map from symbol (GlobalValue and ExternalSymbol)
41588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    // addresses to their indirect symbol addresses.
42588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    DenseMap<void*, intptr_t> Sym2IndirectSymMap;
43588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng
443cc8223a3c062daee763d6db272415a76de38a78Evan Cheng    // IsPIC - True if the relocation model is PIC. This is used to determine
453cc8223a3c062daee763d6db272415a76de38a78Evan Cheng    // how to codegen function stubs.
463cc8223a3c062daee763d6db272415a76de38a78Evan Cheng    bool IsPIC;
473cc8223a3c062daee763d6db272415a76de38a78Evan Cheng
48148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng  public:
493cc8223a3c062daee763d6db272415a76de38a78Evan Cheng    explicit ARMJITInfo() : IsPIC(false) { useGOT = false; }
50148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng
51148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    /// replaceMachineCodeForFunction - Make it so that calling the function
52148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    /// whose machine code is at OLD turns into a call to NEW, perhaps by
53148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    /// overwriting OLD with a branch to NEW.  This is used for self-modifying
54148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    /// code.
55148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    ///
56148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    virtual void replaceMachineCodeForFunction(void *Old, void *New);
57148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng
58a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    /// emitGlobalValueIndirectSym - Use the specified JITCodeEmitter object
599ed2f80910160bbf8051d91cd74c82d4619885b4Evan Cheng    /// to emit an indirect symbol which contains the address of the specified
609ed2f80910160bbf8051d91cd74c82d4619885b4Evan Cheng    /// ptr.
619ed2f80910160bbf8051d91cd74c82d4619885b4Evan Cheng    virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr,
62a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes                                            JITCodeEmitter &JCE);
63e96a490d7a0e224961d37f60f85e8556a64ed2b1Evan Cheng
64108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    // getStubLayout - Returns the size and alignment of the largest call stub
65108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    // on ARM.
66108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin    virtual StubLayout getStubLayout();
67108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin
68a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a
69148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    /// small native function that simply calls the function at the specified
70148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    /// address.
7151cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray    virtual void *emitFunctionStub(const Function* F, void *Fn,
72a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes                                   JITCodeEmitter &JCE);
73148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng
74148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    /// getLazyResolverFunction - Expose the lazy resolver to the JIT.
75148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
76148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng
77148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    /// relocate - Before the JIT can run a block of code that has been emitted,
78148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    /// it must rewrite the code to contain the actual addresses of any
79148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    /// referenced global symbols.
80148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng    virtual void relocate(void *Function, MachineRelocation *MR,
81148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng                          unsigned NumRelocs, unsigned char* GOTBase);
8225e04788bfddc54dde7bed65302146b46089a166Evan Cheng
83bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach    /// hasCustomConstantPool - Allows a target to specify that constant
84bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach    /// pool address resolution is handled by the target.
85bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach    virtual bool hasCustomConstantPool() const { return true; }
86bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach
874df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// hasCustomJumpTables - Allows a target to specify that jumptables
884df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// are emitted by the target.
894df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    virtual bool hasCustomJumpTables() const { return true; }
904df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng
91b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng    /// allocateSeparateGVMemory - If true, globals should be placed in
92b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng    /// separately allocated heap memory rather than in the same
93a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes    /// code memory allocated by JITCodeEmitter.
94b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng    virtual bool allocateSeparateGVMemory() const {
95b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng#ifdef __APPLE__
96b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng      return true;
97b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng#else
98b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng      return false;
99b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng#endif
100b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng    }
101b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng
1023cc8223a3c062daee763d6db272415a76de38a78Evan Cheng    /// Initialize - Initialize internal stage for the function being JITted.
1033cc8223a3c062daee763d6db272415a76de38a78Evan Cheng    /// Resize constant pool ids to CONSTPOOL_ENTRY addresses map; resize
1043cc8223a3c062daee763d6db272415a76de38a78Evan Cheng    /// jump table ids to jump table bases map; remember if codegen relocation
1053cc8223a3c062daee763d6db272415a76de38a78Evan Cheng    /// model is PIC.
1063cc8223a3c062daee763d6db272415a76de38a78Evan Cheng    void Initialize(const MachineFunction &MF, bool isPIC) {
107f1bbb9577a42cf7dc3079412f1dd7683e3a03665Evan Cheng      const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
1085de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng      ConstPoolId2AddrMap.resize(AFI->getNumPICLabels());
109f1bbb9577a42cf7dc3079412f1dd7683e3a03665Evan Cheng      JumpTableId2AddrMap.resize(AFI->getNumJumpTables());
1103cc8223a3c062daee763d6db272415a76de38a78Evan Cheng      IsPIC = isPIC;
111938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng    }
112938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng
1130f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng    /// getConstantPoolEntryAddr - The ARM target puts all constant
1144df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// pool entries into constant islands. This returns the address of the
1154df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// constant pool entry of the specified index.
116938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng    intptr_t getConstantPoolEntryAddr(unsigned CPI) const {
117938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng      assert(CPI < ConstPoolId2AddrMap.size());
118938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng      return ConstPoolId2AddrMap[CPI];
1190f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng    }
120bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach
1214df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// addConstantPoolEntryAddr - Map a Constant Pool Index to the address
122bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach    /// where its associated value is stored. When relocations are processed,
123bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach    /// this value will be used to resolve references to the constant.
124938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng    void addConstantPoolEntryAddr(unsigned CPI, intptr_t Addr) {
125938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng      assert(CPI < ConstPoolId2AddrMap.size());
126938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng      ConstPoolId2AddrMap[CPI] = Addr;
1270f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng    }
12825e04788bfddc54dde7bed65302146b46089a166Evan Cheng
1294df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// getJumpTableBaseAddr - The ARM target inline all jump tables within
1304df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// text section of the function. This returns the address of the base of
1314df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// the jump table of the specified index.
1324df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    intptr_t getJumpTableBaseAddr(unsigned JTI) const {
1334df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng      assert(JTI < JumpTableId2AddrMap.size());
1344df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng      return JumpTableId2AddrMap[JTI];
1354df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    }
1364df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng
1374df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// addJumpTableBaseAddr - Map a jump table index to the address where
1384df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// the corresponding inline jump table is emitted. When relocations are
1394df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// processed, this value will be used to resolve references to the
1404df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// jump table.
1414df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    void addJumpTableBaseAddr(unsigned JTI, intptr_t Addr) {
1424df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng      assert(JTI < JumpTableId2AddrMap.size());
1434df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng      JumpTableId2AddrMap[JTI] = Addr;
1444df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    }
1454df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng
14618f30e6f5e80787808fe1455742452a5210afe07Jim Grosbach    /// getPCLabelAddr - Retrieve the address of the PC label of the
14718f30e6f5e80787808fe1455742452a5210afe07Jim Grosbach    /// specified id.
14825e04788bfddc54dde7bed65302146b46089a166Evan Cheng    intptr_t getPCLabelAddr(unsigned Id) const {
14925e04788bfddc54dde7bed65302146b46089a166Evan Cheng      DenseMap<unsigned, intptr_t>::const_iterator I = PCLabelMap.find(Id);
15025e04788bfddc54dde7bed65302146b46089a166Evan Cheng      assert(I != PCLabelMap.end());
15125e04788bfddc54dde7bed65302146b46089a166Evan Cheng      return I->second;
15225e04788bfddc54dde7bed65302146b46089a166Evan Cheng    }
15325e04788bfddc54dde7bed65302146b46089a166Evan Cheng
15425e04788bfddc54dde7bed65302146b46089a166Evan Cheng    /// addPCLabelAddr - Remember the address of the specified PC label.
15525e04788bfddc54dde7bed65302146b46089a166Evan Cheng    void addPCLabelAddr(unsigned Id, intptr_t Addr) {
15625e04788bfddc54dde7bed65302146b46089a166Evan Cheng      PCLabelMap.insert(std::make_pair(Id, Addr));
15725e04788bfddc54dde7bed65302146b46089a166Evan Cheng    }
15825e04788bfddc54dde7bed65302146b46089a166Evan Cheng
159588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    /// getIndirectSymAddr - Retrieve the address of the indirect symbol of the
160588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    /// specified symbol located at address. Returns 0 if the indirect symbol
161588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    /// has not been emitted.
162588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    intptr_t getIndirectSymAddr(void *Addr) const {
163588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng      DenseMap<void*,intptr_t>::const_iterator I= Sym2IndirectSymMap.find(Addr);
164588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng      if (I != Sym2IndirectSymMap.end())
165588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng        return I->second;
166588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng      return 0;
167588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    }
168588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng
169588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    /// addIndirectSymAddr - Add a mapping from address of an emitted symbol to
170588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    /// its indirect symbol address.
171588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    void addIndirectSymAddr(void *SymAddr, intptr_t IndSymAddr) {
172588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng      Sym2IndirectSymMap.insert(std::make_pair(SymAddr, IndSymAddr));
173588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng    }
174588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng
17525e04788bfddc54dde7bed65302146b46089a166Evan Cheng  private:
1764df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    /// resolveRelocDestAddr - Resolve the resulting address of the relocation
17725e04788bfddc54dde7bed65302146b46089a166Evan Cheng    /// if it's not already solved. Constantpool entries must be resolved by
17825e04788bfddc54dde7bed65302146b46089a166Evan Cheng    /// ARM target.
1794df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng    intptr_t resolveRelocDestAddr(MachineRelocation *MR) const;
180148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng  };
181148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng}
182148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng
183148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng#endif
184