//===-- MipsMCExpr.cpp - Mips specific MC expression classes --------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "MipsMCExpr.h"
#include "llvm/BinaryFormat/ELF.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdint>

using namespace llvm;

#define DEBUG_TYPE "mipsmcexpr"

const MipsMCExpr *MipsMCExpr::create(MipsMCExpr::MipsExprKind Kind,
                                     const MCExpr *Expr, MCContext &Ctx) {
  return new (Ctx) MipsMCExpr(Kind, Expr);
}

const MipsMCExpr *MipsMCExpr::createGpOff(MipsMCExpr::MipsExprKind Kind,
                                          const MCExpr *Expr, MCContext &Ctx) {
  return create(Kind, create(MEK_NEG, create(MEK_GPREL, Expr, Ctx), Ctx), Ctx);
}

void MipsMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const {
  int64_t AbsVal;

  switch (Kind) {
  case MEK_None:
  case MEK_Special:
    llvm_unreachable("MEK_None and MEK_Special are invalid");
    break;
  case MEK_DTPREL:
    // MEK_DTPREL is used for marking TLS DIEExpr only
    // and contains a regular sub-expression.
    getSubExpr()->print(OS, MAI, true);
    return;
  case MEK_CALL_HI16:
    OS << "%call_hi";
    break;
  case MEK_CALL_LO16:
    OS << "%call_lo";
    break;
  case MEK_DTPREL_HI:
    OS << "%dtprel_hi";
    break;
  case MEK_DTPREL_LO:
    OS << "%dtprel_lo";
    break;
  case MEK_GOT:
    OS << "%got";
    break;
  case MEK_GOTTPREL:
    OS << "%gottprel";
    break;
  case MEK_GOT_CALL:
    OS << "%call16";
    break;
  case MEK_GOT_DISP:
    OS << "%got_disp";
    break;
  case MEK_GOT_HI16:
    OS << "%got_hi";
    break;
  case MEK_GOT_LO16:
    OS << "%got_lo";
    break;
  case MEK_GOT_PAGE:
    OS << "%got_page";
    break;
  case MEK_GOT_OFST:
    OS << "%got_ofst";
    break;
  case MEK_GPREL:
    OS << "%gp_rel";
    break;
  case MEK_HI:
    OS << "%hi";
    break;
  case MEK_HIGHER:
    OS << "%higher";
    break;
  case MEK_HIGHEST:
    OS << "%highest";
    break;
  case MEK_LO:
    OS << "%lo";
    break;
  case MEK_NEG:
    OS << "%neg";
    break;
  case MEK_PCREL_HI16:
    OS << "%pcrel_hi";
    break;
  case MEK_PCREL_LO16:
    OS << "%pcrel_lo";
    break;
  case MEK_TLSGD:
    OS << "%tlsgd";
    break;
  case MEK_TLSLDM:
    OS << "%tlsldm";
    break;
  case MEK_TPREL_HI:
    OS << "%tprel_hi";
    break;
  case MEK_TPREL_LO:
    OS << "%tprel_lo";
    break;
  }

  OS << '(';
  if (Expr->evaluateAsAbsolute(AbsVal))
    OS << AbsVal;
  else
    Expr->print(OS, MAI, true);
  OS << ')';
}

bool
MipsMCExpr::evaluateAsRelocatableImpl(MCValue &Res,
                                      const MCAsmLayout *Layout,
                                      const MCFixup *Fixup) const {
  // Look for the %hi(%neg(%gp_rel(X))) and %lo(%neg(%gp_rel(X))) special cases.
  if (isGpOff()) {
    const MCExpr *SubExpr =
        cast<MipsMCExpr>(cast<MipsMCExpr>(getSubExpr())->getSubExpr())
            ->getSubExpr();
    if (!SubExpr->evaluateAsRelocatable(Res, Layout, Fixup))
      return false;

    Res = MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(),
                       MEK_Special);
    return true;
  }

  if (!getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup))
    return false;

  if (Res.getRefKind() != MCSymbolRefExpr::VK_None)
    return false;

  // evaluateAsAbsolute() and evaluateAsValue() require that we evaluate the
  // %hi/%lo/etc. here. Fixup is a null pointer when either of these is the
  // caller.
  if (Res.isAbsolute() && Fixup == nullptr) {
    int64_t AbsVal = Res.getConstant();
    switch (Kind) {
    case MEK_None:
    case MEK_Special:
      llvm_unreachable("MEK_None and MEK_Special are invalid");
    case MEK_DTPREL:
      // MEK_DTPREL is used for marking TLS DIEExpr only
      // and contains a regular sub-expression.
      return getSubExpr()->evaluateAsRelocatable(Res, Layout, Fixup);
    case MEK_DTPREL_HI:
    case MEK_DTPREL_LO:
    case MEK_GOT:
    case MEK_GOTTPREL:
    case MEK_GOT_CALL:
    case MEK_GOT_DISP:
    case MEK_GOT_HI16:
    case MEK_GOT_LO16:
    case MEK_GOT_OFST:
    case MEK_GOT_PAGE:
    case MEK_GPREL:
    case MEK_PCREL_HI16:
    case MEK_PCREL_LO16:
    case MEK_TLSGD:
    case MEK_TLSLDM:
    case MEK_TPREL_HI:
    case MEK_TPREL_LO:
      return false;
    case MEK_LO:
    case MEK_CALL_LO16:
      AbsVal = SignExtend64<16>(AbsVal);
      break;
    case MEK_CALL_HI16:
    case MEK_HI:
      AbsVal = SignExtend64<16>((AbsVal + 0x8000) >> 16);
      break;
    case MEK_HIGHER:
      AbsVal = SignExtend64<16>((AbsVal + 0x80008000LL) >> 32);
      break;
    case MEK_HIGHEST:
      AbsVal = SignExtend64<16>((AbsVal + 0x800080008000LL) >> 48);
      break;
    case MEK_NEG:
      AbsVal = -AbsVal;
      break;
    }
    Res = MCValue::get(AbsVal);
    return true;
  }

  // We want to defer it for relocatable expressions since the constant is
  // applied to the whole symbol value.
  //
  // The value of getKind() that is given to MCValue is only intended to aid
  // debugging when inspecting MCValue objects. It shouldn't be relied upon
  // for decision making.
  Res =
      MCValue::get(Res.getSymA(), Res.getSymB(), Res.getConstant(), getKind());

  return true;
}

void MipsMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
  Streamer.visitUsedExpr(*getSubExpr());
}

static void fixELFSymbolsInTLSFixupsImpl(const MCExpr *Expr, MCAssembler &Asm) {
  switch (Expr->getKind()) {
  case MCExpr::Target:
    fixELFSymbolsInTLSFixupsImpl(cast<MipsMCExpr>(Expr)->getSubExpr(), Asm);
    break;
  case MCExpr::Constant:
    break;
  case MCExpr::Binary: {
    const MCBinaryExpr *BE = cast<MCBinaryExpr>(Expr);
    fixELFSymbolsInTLSFixupsImpl(BE->getLHS(), Asm);
    fixELFSymbolsInTLSFixupsImpl(BE->getRHS(), Asm);
    break;
  }
  case MCExpr::SymbolRef: {
    // We're known to be under a TLS fixup, so any symbol should be
    // modified. There should be only one.
    const MCSymbolRefExpr &SymRef = *cast<MCSymbolRefExpr>(Expr);
    cast<MCSymbolELF>(SymRef.getSymbol()).setType(ELF::STT_TLS);
    break;
  }
  case MCExpr::Unary:
    fixELFSymbolsInTLSFixupsImpl(cast<MCUnaryExpr>(Expr)->getSubExpr(), Asm);
    break;
  }
}

void MipsMCExpr::fixELFSymbolsInTLSFixups(MCAssembler &Asm) const {
  switch (getKind()) {
  case MEK_None:
  case MEK_Special:
    llvm_unreachable("MEK_None and MEK_Special are invalid");
    break;
  case MEK_CALL_HI16:
  case MEK_CALL_LO16:
  case MEK_GOT:
  case MEK_GOT_CALL:
  case MEK_GOT_DISP:
  case MEK_GOT_HI16:
  case MEK_GOT_LO16:
  case MEK_GOT_OFST:
  case MEK_GOT_PAGE:
  case MEK_GPREL:
  case MEK_HI:
  case MEK_HIGHER:
  case MEK_HIGHEST:
  case MEK_LO:
  case MEK_NEG:
  case MEK_PCREL_HI16:
  case MEK_PCREL_LO16:
    // If we do have nested target-specific expressions, they will be in
    // a consecutive chain.
    if (const MipsMCExpr *E = dyn_cast<const MipsMCExpr>(getSubExpr()))
      E->fixELFSymbolsInTLSFixups(Asm);
    break;
  case MEK_DTPREL:
  case MEK_DTPREL_HI:
  case MEK_DTPREL_LO:
  case MEK_TLSLDM:
  case MEK_TLSGD:
  case MEK_GOTTPREL:
  case MEK_TPREL_HI:
  case MEK_TPREL_LO:
    fixELFSymbolsInTLSFixupsImpl(getSubExpr(), Asm);
    break;
  }
}

bool MipsMCExpr::isGpOff(MipsExprKind &Kind) const {
  if (getKind() == MEK_HI || getKind() == MEK_LO) {
    if (const MipsMCExpr *S1 = dyn_cast<const MipsMCExpr>(getSubExpr())) {
      if (const MipsMCExpr *S2 = dyn_cast<const MipsMCExpr>(S1->getSubExpr())) {
        if (S1->getKind() == MEK_NEG && S2->getKind() == MEK_GPREL) {
          Kind = getKind();
          return true;
        }
      }
    }
  }
  return false;
}
