167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//===-- CodeEmitter.h - CodeEmitter Class -----------------------*- C++ -*-===//
267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//
367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//                     The LLVM Compiler Infrastructure
467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//
567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao// This file is distributed under the University of Illinois Open Source
667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao// License. See external/llvm/LICENSE.TXT for details.
767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//
867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//===----------------------------------------------------------------------===//
967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//
1067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//  This file defines the CodeEmitter class.
1167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//
1267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao//===----------------------------------------------------------------------===//
1367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
1467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#ifndef BCC_CODEEMITTER_H
1567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#define BCC_CODEEMITTER_H
1667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
1767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <bcc/bcc.h>
18bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines#include <bcc/bcc_assert.h>
1967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <bcc/bcc_cache.h>
208d3b5e184b776dbf0b4af8a1c95f027d8653ca66Logan Chien#include "ExecutionEngine/bcc_internal.h"
2167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
2267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "Config.h"
2367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
2467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/ADT/DenseMap.h"
2567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/ADT/SmallVector.h"
2667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/ADT/StringRef.h"
27bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines#include "llvm/CodeGen/MachineConstantPool.h"
2867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/CodeGen/MachineRelocation.h"
2967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/CodeGen/JITCodeEmitter.h"
3067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include "llvm/Support/ValueHandle.h"
3167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
3267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <map>
3367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <vector>
3467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <set>
3567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
3667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#include <stdint.h>
3767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
3867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liaonamespace llvm {
3967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class Constant;
4067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class GenericValue;
4167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class GlobalVariable;
4267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class GlobalValue;
4367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class Function;
4467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class MachineBasicBlock;
4567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class MachineFunction;
4667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class MachineJumpTableInfo;
4767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class MachineModuleInfo;
4867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class MCSymbol;
4967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class Target;
5067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class TargetData;
5167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class TargetJITInfo;
5267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class TargetMachine;
5367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class Type;
5467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao}
5567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
5667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liaonamespace bcc {
5767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class CodeMemoryManager;
5867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class ScriptCompiled;
5967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
6067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  class CodeEmitter : public llvm::JITCodeEmitter {
6167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  private:
6267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    typedef llvm::DenseMap<const llvm::GlobalValue *, void *>
6367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      GlobalAddressMapTy;
6467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
6567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    typedef llvm::DenseMap<const llvm::Function *, void*>
6667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      FunctionToLazyStubMapTy;
6767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
6867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    typedef std::map<llvm::AssertingVH<llvm::GlobalValue>, void *>
6967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      GlobalToIndirectSymMapTy;
7067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
7167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  public:
7267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    typedef GlobalAddressMapTy::const_iterator global_addresses_const_iterator;
7367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
7467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
7567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  private:
7667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    ScriptCompiled *mpResult;
7767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
7867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    CodeMemoryManager *mpMemMgr;
7967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
80cfd23fde40cf0cb600dd8a09563ff8fe3e5f9c0aShih-wei Liao    llvm::TargetMachine *mpTargetMachine;
81cfd23fde40cf0cb600dd8a09563ff8fe3e5f9c0aShih-wei Liao
8267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // The JITInfo for the target we are compiling to
8367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    const llvm::Target *mpTarget;
8467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
8567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    llvm::TargetJITInfo *mpTJI;
8667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
8767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    const llvm::TargetData *mpTD;
8867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
8967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
9067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    FuncInfo *mpCurEmitFunction;
9167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
9267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    GlobalAddressMapTy mGlobalAddressMap;
9367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
9467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // This vector is a mapping from MBB ID's to their address. It is filled in
9567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // by the StartMachineBasicBlock callback and queried by the
9667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // getMachineBasicBlockAddress callback.
9767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    std::vector<uintptr_t> mMBBLocations;
9867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
9967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // The constant pool for the current function.
10067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    llvm::MachineConstantPool *mpConstantPool;
10167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
10267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // A pointer to the first entry in the constant pool.
10367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *mpConstantPoolBase;
10467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
10567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Addresses of individual constant pool entries.
10667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    llvm::SmallVector<uintptr_t, 8> mConstPoolAddresses;
10767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
10867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // The jump tables for the current function.
10967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    llvm::MachineJumpTableInfo *mpJumpTable;
11067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
11167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // A pointer to the first entry in the jump table.
11267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *mpJumpTableBase;
11367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
11467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // When outputting a function stub in the context of some other function, we
11567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // save BufferBegin/BufferEnd/CurBufferPtr here.
11667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    uint8_t *mpSavedBufferBegin, *mpSavedBufferEnd, *mpSavedCurBufferPtr;
11767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
11867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // These are the relocations that the function needs, as emitted.
11967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    std::vector<llvm::MachineRelocation> mRelocations;
12067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
12167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#if 0
12267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    std::vector<oBCCRelocEntry> mCachingRelocations;
12367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#endif
12467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
12567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // This vector is a mapping from Label ID's to their address.
12667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    llvm::DenseMap<llvm::MCSymbol*, uintptr_t> mLabelLocations;
12767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
12867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Machine module info for exception informations
12967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    llvm::MachineModuleInfo *mpMMI;
13067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
13167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
13267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    FunctionToLazyStubMapTy mFunctionToLazyStubMap;
13367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
13467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    std::set<const llvm::Function*> PendingFunctions;
13567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
13667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
13767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
13867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    std::map<void*, void*> ExternalFnToStubMap;
13967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
14067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  public:
14167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Resolver to undefined symbol in CodeEmitter
14267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    BCCSymbolLookupFn mpSymbolLookupFn;
14367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *mpSymbolLookupContext;
14467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
14567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Will take the ownership of @MemMgr
14667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    explicit CodeEmitter(ScriptCompiled *result, CodeMemoryManager *pMemMgr);
14767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
14867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual ~CodeEmitter();
14967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
15067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    global_addresses_const_iterator global_address_begin() const {
15167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      return mGlobalAddressMap.begin();
15267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
15367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
15467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    global_addresses_const_iterator global_address_end() const {
15567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      return mGlobalAddressMap.end();
15667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
15767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
15867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#if 0
15967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    std::vector<oBCCRelocEntry> const &getCachingRelocations() const {
16067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      return mCachingRelocations;
16167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
16267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#endif
16367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
16467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
16567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      mpSymbolLookupFn = pFn;
16667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      mpSymbolLookupContext = pContext;
16767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
16867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
16967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void setTargetMachine(llvm::TargetMachine &TM);
17067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
17167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // This callback is invoked when the specified function is about to be code
17267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // generated.  This initializes the BufferBegin/End/Ptr fields.
17367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual void startFunction(llvm::MachineFunction &F);
17467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
17567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // This callback is invoked when the specified function has finished code
17667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // generation. If a buffer overflow has occurred, this method returns true
17767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // (the callee is required to try again).
17867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual bool finishFunction(llvm::MachineFunction &F);
17967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
18067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Allocates and fills storage for an indirect GlobalValue, and returns the
18167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // address.
18267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual void *allocIndirectGV(const llvm::GlobalValue *GV,
18367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao                                  const uint8_t *Buffer, size_t Size,
18467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao                                  unsigned Alignment);
18567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
18667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Emits a label
18767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual void emitLabel(llvm::MCSymbol *Label) {
18867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      mLabelLocations[Label] = getCurrentPCValue();
18967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
19067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
19167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Allocate memory for a global. Unlike allocateSpace, this method does not
19267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // allocate memory in the current output buffer, because a global may live
19367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // longer than the current function.
19467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment);
19567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
19667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // This should be called by the target when a new basic block is about to be
19767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // emitted. This way the MCE knows where the start of the block is, and can
19867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // implement getMachineBasicBlockAddress.
19967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual void StartMachineBasicBlock(llvm::MachineBasicBlock *MBB);
20067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
20167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Whenever a relocatable address is needed, it should be noted with this
20267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // interface.
20367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual void addRelocation(const llvm::MachineRelocation &MR) {
20467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      mRelocations.push_back(MR);
20567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
20667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
20767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Return the address of the @Index entry in the constant pool that was
20867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // last emitted with the emitConstantPool method.
20967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
210bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines      bccAssert(Index < mpConstantPool->getConstants().size() &&
211bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines                "Invalid constant pool index!");
21267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      return mConstPoolAddresses[Index];
21367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
21467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
21567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Return the address of the jump table with index @Index in the function
21667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // that last called initJumpTableInfo.
21767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const;
21867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
21967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Return the address of the specified MachineBasicBlock, only usable after
22067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // the label for the MBB has been emitted.
22167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual uintptr_t getMachineBasicBlockAddress(
22267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao                                        llvm::MachineBasicBlock *MBB) const;
22367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
22467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Return the address of the specified LabelID, only usable after the
22567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // LabelID has been emitted.
22667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual uintptr_t getLabelAddress(llvm::MCSymbol *Label) const {
227bbcef8ad069ee33c3bfc52dcd1bd6e1a7633e1f9Stephen Hines      bccAssert(mLabelLocations.count(Label) && "Label not emitted!");
22867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      return mLabelLocations.find(Label)->second;
22967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
23067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
23167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Specifies the MachineModuleInfo object. This is used for exception
23267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // handling purposes.
23367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    virtual void setModuleInfo(llvm::MachineModuleInfo *Info) {
23467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      mpMMI = Info;
23567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
23667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
23767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void releaseUnnecessary();
23867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
23967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void reset();
24067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
24167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  private:
24267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void startGVStub(const llvm::GlobalValue *GV, unsigned StubSize,
24367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao                     unsigned Alignment);
24467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
24567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void startGVStub(void *Buffer, unsigned StubSize);
24667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
24767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void finishGVStub();
24867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
24967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Replace an existing mapping for GV with a new address. This updates both
25067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // maps as required. If Addr is null, the entry for the global is removed
25167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // from the mappings.
25267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr);
25367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
25467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Tell the execution engine that the specified global is at the specified
25567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // location. This is used internally as functions are JIT'd and as global
25667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // variables are laid out in memory.
25767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void AddGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
25867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao       void *&CurVal = mGlobalAddressMap[GV];
25967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao       assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
26067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao       CurVal = Addr;
26167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
26267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
26367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // This returns the address of the specified global value if it is has
26467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // already been codegen'd, otherwise it returns null.
26567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *GetPointerToGlobalIfAvailable(const llvm::GlobalValue *GV) {
26667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
26767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      return ((I != mGlobalAddressMap.end()) ? I->second : NULL);
26867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
26967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
27067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    unsigned int GetConstantPoolSizeInBytes(llvm::MachineConstantPool *MCP);
27167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
27267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // This function converts a Constant* into a GenericValue. The interesting
27367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // part is if C is a ConstantExpr.
27467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void GetConstantValue(const llvm::Constant *C, llvm::GenericValue &Result);
27567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
27667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Stores the data in @Val of type @Ty at address @Addr.
27767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void StoreValueToMemory(const llvm::GenericValue &Val, void *Addr,
278d3fe15c7b86a438020553c7a7ef7ec102c63d712Logan Chien                            llvm::Type *Ty);
27967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
28067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Recursive function to apply a @Constant value into the specified memory
28167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // location @Addr.
28267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void InitializeConstantToMemory(const llvm::Constant *C, void *Addr);
28367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
28467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void emitConstantPool(llvm::MachineConstantPool *MCP);
28567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
28667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI);
28767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
28867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI);
28967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
29067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *GetPointerToGlobal(llvm::GlobalValue *V,
29167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao                             void *Reference,
29267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao                             bool MayNeedFarStub);
29367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
29467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // If the specified function has been code-gen'd, return a pointer to the
29567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // function. If not, compile it, or use a stub to implement lazy compilation
29667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // if available.
29767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *GetPointerToFunctionOrStub(llvm::Function *F);
29867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
29967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *GetLazyFunctionStubIfAvailable(llvm::Function *F) {
30067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao      return mFunctionToLazyStubMap.lookup(F);
30167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    }
30267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
30367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *GetLazyFunctionStub(llvm::Function *F);
30467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
30567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void updateFunctionStub(const llvm::Function *F);
30667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
30767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *GetPointerToFunction(const llvm::Function *F, bool AbortOnFailure);
30867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
30967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *GetPointerToNamedSymbol(const std::string &Name,
31067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao                                  bool AbortOnFailure);
31167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
31267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Return the address of the specified global variable, possibly emitting it
31367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // to memory if needed. This is used by the Emitter.
314d3fe15c7b86a438020553c7a7ef7ec102c63d712Logan Chien    void *GetOrEmitGlobalVariable(llvm::GlobalVariable *GV);
31567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
31667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // This method abstracts memory allocation of global variable so that the
31767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // JIT can allocate thread local variables depending on the target.
318d3fe15c7b86a438020553c7a7ef7ec102c63d712Logan Chien    void *GetMemoryForGV(llvm::GlobalVariable *GV);
31967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
320d3fe15c7b86a438020553c7a7ef7ec102c63d712Logan Chien    void EmitGlobalVariable(llvm::GlobalVariable *GV);
32167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
32267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference);
32367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
32467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // This is the equivalent of FunctionToLazyStubMap for external functions.
32567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    //
32667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // TODO(llvm.org): Of course, external functions don't need a lazy stub.
32767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    //                 It's actually here to make it more likely that far calls
32867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    //                 succeed, but no single stub can guarantee that. I'll
32967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    //                 remove this in a subsequent checkin when I actually fix
33067d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    //                 far calls.
33167d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
33267d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    // Return a stub for the function at the specified address.
33367d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao    void *GetExternalFunctionStub(void *FnAddr);
33467d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
33567d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao  };
33667d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
33767d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao} // namespace bcc
33867d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao
33967d8f37778f6730cef365a0d469113bc929c0a66Shih-wei Liao#endif // BCC_CODEEMITTER_H
340