//===-- llvm/MC/MCFixup.h - Instruction Relocation and Patching -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_MC_MCFIXUP_H
#define LLVM_MC_MCFIXUP_H

#include "llvm/MC/MCExpr.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/SMLoc.h"
#include <cassert>

namespace llvm {
class MCExpr;

/// Extensible enumeration to represent the type of a fixup.
enum MCFixupKind {
  FK_NONE = 0,   ///< A no-op fixup.
  FK_Data_1,     ///< A one-byte fixup.
  FK_Data_2,     ///< A two-byte fixup.
  FK_Data_4,     ///< A four-byte fixup.
  FK_Data_8,     ///< A eight-byte fixup.
  FK_PCRel_1,    ///< A one-byte pc relative fixup.
  FK_PCRel_2,    ///< A two-byte pc relative fixup.
  FK_PCRel_4,    ///< A four-byte pc relative fixup.
  FK_PCRel_8,    ///< A eight-byte pc relative fixup.
  FK_GPRel_1,    ///< A one-byte gp relative fixup.
  FK_GPRel_2,    ///< A two-byte gp relative fixup.
  FK_GPRel_4,    ///< A four-byte gp relative fixup.
  FK_GPRel_8,    ///< A eight-byte gp relative fixup.
  FK_DTPRel_4,   ///< A four-byte dtp relative fixup.
  FK_DTPRel_8,   ///< A eight-byte dtp relative fixup.
  FK_TPRel_4,    ///< A four-byte tp relative fixup.
  FK_TPRel_8,    ///< A eight-byte tp relative fixup.
  FK_SecRel_1,   ///< A one-byte section relative fixup.
  FK_SecRel_2,   ///< A two-byte section relative fixup.
  FK_SecRel_4,   ///< A four-byte section relative fixup.
  FK_SecRel_8,   ///< A eight-byte section relative fixup.
  FK_Data_Add_1, ///< A one-byte add fixup.
  FK_Data_Add_2, ///< A two-byte add fixup.
  FK_Data_Add_4, ///< A four-byte add fixup.
  FK_Data_Add_8, ///< A eight-byte add fixup.
  FK_Data_Sub_1, ///< A one-byte sub fixup.
  FK_Data_Sub_2, ///< A two-byte sub fixup.
  FK_Data_Sub_4, ///< A four-byte sub fixup.
  FK_Data_Sub_8, ///< A eight-byte sub fixup.

  FirstTargetFixupKind = 128,

  // Limit range of target fixups, in case we want to pack more efficiently
  // later.
  MaxTargetFixupKind = (1 << 8)
};

/// Encode information on a single operation to perform on a byte
/// sequence (e.g., an encoded instruction) which requires assemble- or run-
/// time patching.
///
/// Fixups are used any time the target instruction encoder needs to represent
/// some value in an instruction which is not yet concrete. The encoder will
/// encode the instruction assuming the value is 0, and emit a fixup which
/// communicates to the assembler backend how it should rewrite the encoded
/// value.
///
/// During the process of relaxation, the assembler will apply fixups as
/// symbolic values become concrete. When relaxation is complete, any remaining
/// fixups become relocations in the object file (or errors, if the fixup cannot
/// be encoded on the target).
class MCFixup {
  /// The value to put into the fixup location. The exact interpretation of the
  /// expression is target dependent, usually it will be one of the operands to
  /// an instruction or an assembler directive.
  const MCExpr *Value;

  /// The byte index of start of the relocation inside the MCFragment.
  uint32_t Offset;

  /// The target dependent kind of fixup item this is. The kind is used to
  /// determine how the operand value should be encoded into the instruction.
  unsigned Kind;

  /// The source location which gave rise to the fixup, if any.
  SMLoc Loc;
public:
  static MCFixup create(uint32_t Offset, const MCExpr *Value,
                        MCFixupKind Kind, SMLoc Loc = SMLoc()) {
    assert(unsigned(Kind) < MaxTargetFixupKind && "Kind out of range!");
    MCFixup FI;
    FI.Value = Value;
    FI.Offset = Offset;
    FI.Kind = unsigned(Kind);
    FI.Loc = Loc;
    return FI;
  }

  /// Return a fixup corresponding to the add half of a add/sub fixup pair for
  /// the given Fixup.
  static MCFixup createAddFor(const MCFixup &Fixup) {
    MCFixup FI;
    FI.Value = Fixup.getValue();
    FI.Offset = Fixup.getOffset();
    FI.Kind = (unsigned)getAddKindForKind(Fixup.getKind());
    FI.Loc = Fixup.getLoc();
    return FI;
  }

  /// Return a fixup corresponding to the sub half of a add/sub fixup pair for
  /// the given Fixup.
  static MCFixup createSubFor(const MCFixup &Fixup) {
    MCFixup FI;
    FI.Value = Fixup.getValue();
    FI.Offset = Fixup.getOffset();
    FI.Kind = (unsigned)getSubKindForKind(Fixup.getKind());
    FI.Loc = Fixup.getLoc();
    return FI;
  }

  MCFixupKind getKind() const { return MCFixupKind(Kind); }

  uint32_t getOffset() const { return Offset; }
  void setOffset(uint32_t Value) { Offset = Value; }

  const MCExpr *getValue() const { return Value; }

  /// Return the generic fixup kind for a value with the given size. It
  /// is an error to pass an unsupported size.
  static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) {
    switch (Size) {
    default: llvm_unreachable("Invalid generic fixup size!");
    case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1;
    case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2;
    case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4;
    case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8;
    }
  }

  /// Return the generic fixup kind for an addition with a given size. It
  /// is an error to pass an unsupported size.
  static MCFixupKind getAddKindForKind(unsigned Kind) {
    switch (Kind) {
    default: llvm_unreachable("Unknown type to convert!");
    case FK_Data_1: return FK_Data_Add_1;
    case FK_Data_2: return FK_Data_Add_2;
    case FK_Data_4: return FK_Data_Add_4;
    case FK_Data_8: return FK_Data_Add_8;
    }
  }

  /// Return the generic fixup kind for an subtraction with a given size. It
  /// is an error to pass an unsupported size.
  static MCFixupKind getSubKindForKind(unsigned Kind) {
    switch (Kind) {
    default: llvm_unreachable("Unknown type to convert!");
    case FK_Data_1: return FK_Data_Sub_1;
    case FK_Data_2: return FK_Data_Sub_2;
    case FK_Data_4: return FK_Data_Sub_4;
    case FK_Data_8: return FK_Data_Sub_8;
    }
  }

  SMLoc getLoc() const { return Loc; }
};

} // End llvm namespace

#endif
