//===-- llvm/CodeGen/MachineRelocation.h - Target Relocation ----*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MachineRelocation class.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CODEGEN_MACHINERELOCATION_H
#define LLVM_CODEGEN_MACHINERELOCATION_H

#include "llvm/Support/DataTypes.h"
#include <cassert>

namespace llvm {
class GlobalValue;
class MachineBasicBlock;

/// MachineRelocation - This represents a target-specific relocation value,
/// produced by the code emitter.  This relocation is resolved after the has
/// been emitted, either to an object file or to memory, when the target of the
/// relocation can be resolved.
///
/// A relocation is made up of the following logical portions:
///   1. An offset in the machine code buffer, the location to modify.
///   2. A target specific relocation type (a number from 0 to 63).
///   3. A symbol being referenced, either as a GlobalValue* or as a string.
///   4. An optional constant value to be added to the reference.
///   5. A bit, CanRewrite, which indicates to the JIT that a function stub is
///      not needed for the relocation.
///   6. An index into the GOT, if the target uses a GOT
///
class MachineRelocation {
  enum AddressType {
    isResult,         // Relocation has be transformed into its result pointer.
    isGV,             // The Target.GV field is valid.
    isIndirectSym,    // Relocation of an indirect symbol.
    isBB,             // Relocation of BB address.
    isExtSym,         // The Target.ExtSym field is valid.
    isConstPool,      // Relocation of constant pool address.
    isJumpTable,      // Relocation of jump table address.
    isGOTIndex        // The Target.GOTIndex field is valid.
  };
  
  /// Offset - This is the offset from the start of the code buffer of the
  /// relocation to perform.
  uintptr_t Offset;
  
  /// ConstantVal - A field that may be used by the target relocation type.
  intptr_t ConstantVal;

  union {
    void *Result;           // If this has been resolved to a resolved pointer
    GlobalValue *GV;        // If this is a pointer to a GV or an indirect ref.
    MachineBasicBlock *MBB; // If this is a pointer to a LLVM BB
    const char *ExtSym;     // If this is a pointer to a named symbol
    unsigned Index;         // Constant pool / jump table index
    unsigned GOTIndex;      // Index in the GOT of this symbol/global
  } Target;

  unsigned TargetReloType : 6; // The target relocation ID
  AddressType AddrType    : 4; // The field of Target to use
  bool NeedStub           : 1; // True if this relocation requires a stub
  bool GOTRelative        : 1; // Should this relocation be relative to the GOT?
  bool TargetResolve      : 1; // True if target should resolve the address

public:
 // Relocation types used in a generic implementation.  Currently, relocation
 // entries for all things use the generic VANILLA type until they are refined
 // into target relocation types.
  enum RelocationType {
    VANILLA
  };
  
  /// MachineRelocation::getGV - Return a relocation entry for a GlobalValue.
  ///
  static MachineRelocation getGV(uintptr_t offset, unsigned RelocationType, 
                                 GlobalValue *GV, intptr_t cst = 0,
                                 bool NeedStub = 0,
                                 bool GOTrelative = 0) {
    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
    MachineRelocation Result;
    Result.Offset = offset;
    Result.ConstantVal = cst;
    Result.TargetReloType = RelocationType;
    Result.AddrType = isGV;
    Result.NeedStub = NeedStub;
    Result.GOTRelative = GOTrelative;
    Result.TargetResolve = false;
    Result.Target.GV = GV;
    return Result;
  }

  /// MachineRelocation::getIndirectSymbol - Return a relocation entry for an
  /// indirect symbol.
  static MachineRelocation getIndirectSymbol(uintptr_t offset,
                                             unsigned RelocationType, 
                                             GlobalValue *GV, intptr_t cst = 0,
                                             bool NeedStub = 0,
                                             bool GOTrelative = 0) {
    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
    MachineRelocation Result;
    Result.Offset = offset;
    Result.ConstantVal = cst;
    Result.TargetReloType = RelocationType;
    Result.AddrType = isIndirectSym;
    Result.NeedStub = NeedStub;
    Result.GOTRelative = GOTrelative;
    Result.TargetResolve = false;
    Result.Target.GV = GV;
    return Result;
  }

  /// MachineRelocation::getBB - Return a relocation entry for a BB.
  ///
  static MachineRelocation getBB(uintptr_t offset,unsigned RelocationType,
                                 MachineBasicBlock *MBB, intptr_t cst = 0) {
    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
    MachineRelocation Result;
    Result.Offset = offset;
    Result.ConstantVal = cst;
    Result.TargetReloType = RelocationType;
    Result.AddrType = isBB;
    Result.NeedStub = false;
    Result.GOTRelative = false;
    Result.TargetResolve = false;
    Result.Target.MBB = MBB;
    return Result;
  }

  /// MachineRelocation::getExtSym - Return a relocation entry for an external
  /// symbol, like "free".
  ///
  static MachineRelocation getExtSym(uintptr_t offset, unsigned RelocationType, 
                                     const char *ES, intptr_t cst = 0,
                                     bool GOTrelative = 0) {
    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
    MachineRelocation Result;
    Result.Offset = offset;
    Result.ConstantVal = cst;
    Result.TargetReloType = RelocationType;
    Result.AddrType = isExtSym;
    Result.NeedStub = true;
    Result.GOTRelative = GOTrelative;
    Result.TargetResolve = false;
    Result.Target.ExtSym = ES;
    return Result;
  }

  /// MachineRelocation::getConstPool - Return a relocation entry for a constant
  /// pool entry.
  ///
  static MachineRelocation getConstPool(uintptr_t offset,unsigned RelocationType,
                                        unsigned CPI, intptr_t cst = 0,
                                        bool letTargetResolve = false) {
    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
    MachineRelocation Result;
    Result.Offset = offset;
    Result.ConstantVal = cst;
    Result.TargetReloType = RelocationType;
    Result.AddrType = isConstPool;
    Result.NeedStub = false;
    Result.GOTRelative = false;
    Result.TargetResolve = letTargetResolve;
    Result.Target.Index = CPI;
    return Result;
  }

  /// MachineRelocation::getJumpTable - Return a relocation entry for a jump
  /// table entry.
  ///
  static MachineRelocation getJumpTable(uintptr_t offset,unsigned RelocationType,
                                        unsigned JTI, intptr_t cst = 0,
                                        bool letTargetResolve = false) {
    assert((RelocationType & ~63) == 0 && "Relocation type too large!");
    MachineRelocation Result;
    Result.Offset = offset;
    Result.ConstantVal = cst;
    Result.TargetReloType = RelocationType;
    Result.AddrType = isJumpTable;
    Result.NeedStub = false;
    Result.GOTRelative = false;
    Result.TargetResolve = letTargetResolve;
    Result.Target.Index = JTI;
    return Result;
  }

  /// getMachineCodeOffset - Return the offset into the code buffer that the
  /// relocation should be performed.
  intptr_t getMachineCodeOffset() const {
    return Offset;
  }

  /// getRelocationType - Return the target-specific relocation ID for this
  /// relocation.
  unsigned getRelocationType() const {
    return TargetReloType;
  }

  /// getConstantVal - Get the constant value associated with this relocation.
  /// This is often an offset from the symbol.
  ///
  intptr_t getConstantVal() const {
    return ConstantVal;
  }

  /// setConstantVal - Set the constant value associated with this relocation.
  /// This is often an offset from the symbol.
  ///
  void setConstantVal(intptr_t val) {
    ConstantVal = val;
  }

  /// isGlobalValue - Return true if this relocation is a GlobalValue, as
  /// opposed to a constant string.
  bool isGlobalValue() const {
    return AddrType == isGV;
  }

  /// isIndirectSymbol - Return true if this relocation is the address an
  /// indirect symbol
  bool isIndirectSymbol() const {
    return AddrType == isIndirectSym;
  }

  /// isBasicBlock - Return true if this relocation is a basic block reference.
  ///
  bool isBasicBlock() const {
    return AddrType == isBB;
  }

  /// isExternalSymbol - Return true if this is a constant string.
  ///
  bool isExternalSymbol() const {
    return AddrType == isExtSym;
  }

  /// isConstantPoolIndex - Return true if this is a constant pool reference.
  ///
  bool isConstantPoolIndex() const {
    return AddrType == isConstPool;
  }

  /// isJumpTableIndex - Return true if this is a jump table reference.
  ///
  bool isJumpTableIndex() const {
    return AddrType == isJumpTable;
  }

  /// isGOTRelative - Return true the target wants the index into the GOT of
  /// the symbol rather than the address of the symbol.
  bool isGOTRelative() const {
    return GOTRelative;
  }

  /// doesntNeedStub - This function returns true if the JIT for this target
  /// target is capable of directly handling the relocated GlobalValue reference
  /// without using either a stub function or issuing an extra load to get the
  /// GV address.
  bool doesntNeedStub() const {
    return !NeedStub;
  }

  /// letTargetResolve - Return true if the target JITInfo is usually
  /// responsible for resolving the address of this relocation.
  bool letTargetResolve() const {
    return TargetResolve;
  }

  /// getGlobalValue - If this is a global value reference, return the
  /// referenced global.
  GlobalValue *getGlobalValue() const {
    assert((isGlobalValue() || isIndirectSymbol()) &&
           "This is not a global value reference!");
    return Target.GV;
  }

  MachineBasicBlock *getBasicBlock() const {
    assert(isBasicBlock() && "This is not a basic block reference!");
    return Target.MBB;
  }

  /// getString - If this is a string value, return the string reference.
  ///
  const char *getExternalSymbol() const {
    assert(isExternalSymbol() && "This is not an external symbol reference!");
    return Target.ExtSym;
  }

  /// getConstantPoolIndex - If this is a const pool reference, return
  /// the index into the constant pool.
  unsigned getConstantPoolIndex() const {
    assert(isConstantPoolIndex() && "This is not a constant pool reference!");
    return Target.Index;
  }

  /// getJumpTableIndex - If this is a jump table reference, return
  /// the index into the jump table.
  unsigned getJumpTableIndex() const {
    assert(isJumpTableIndex() && "This is not a jump table reference!");
    return Target.Index;
  }

  /// getResultPointer - Once this has been resolved to point to an actual
  /// address, this returns the pointer.
  void *getResultPointer() const {
    assert(AddrType == isResult && "Result pointer isn't set yet!");
    return Target.Result;
  }

  /// setResultPointer - Set the result to the specified pointer value.
  ///
  void setResultPointer(void *Ptr) {
    Target.Result = Ptr;
    AddrType = isResult;
  }

  /// setGOTIndex - Set the GOT index to a specific value.
  void setGOTIndex(unsigned idx) {
    AddrType = isGOTIndex;
    Target.GOTIndex = idx;
  }

  /// getGOTIndex - Once this has been resolved to an entry in the GOT,
  /// this returns that index.  The index is from the lowest address entry
  /// in the GOT.
  unsigned getGOTIndex() const {
    assert(AddrType == isGOTIndex);
    return Target.GOTIndex;
  }
};
}

#endif
