//===- HexagonMCInstLower.cpp - Convert Hexagon MachineInstr to an MCInst -===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains code to lower Hexagon MachineInstrs to their corresponding
// MCInst records.
//
//===----------------------------------------------------------------------===//

#include "Hexagon.h"
#include "HexagonAsmPrinter.h"
#include "HexagonMachineFunctionInfo.h"
#include "MCTargetDesc/HexagonMCInstrInfo.h"

#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Mangler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"

using namespace llvm;

namespace llvm {
  void HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,
                        MCInst &MCB, HexagonAsmPrinter &AP);
}

static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
                              HexagonAsmPrinter &Printer, bool MustExtend) {
  MCContext &MC = Printer.OutContext;
  const MCExpr *ME;

  // Populate the relocation type based on Hexagon target flags
  // set on an operand
  MCSymbolRefExpr::VariantKind RelocationType;
  switch (MO.getTargetFlags()) {
  default:
    RelocationType = MCSymbolRefExpr::VK_None;
    break;
  case HexagonII::MO_PCREL:
    RelocationType = MCSymbolRefExpr::VK_Hexagon_PCREL;
    break;
  case HexagonII::MO_GOT:
    RelocationType = MCSymbolRefExpr::VK_GOT;
    break;
  case HexagonII::MO_LO16:
    RelocationType = MCSymbolRefExpr::VK_Hexagon_LO16;
    break;
  case HexagonII::MO_HI16:
    RelocationType = MCSymbolRefExpr::VK_Hexagon_HI16;
    break;
  case HexagonII::MO_GPREL:
    RelocationType = MCSymbolRefExpr::VK_Hexagon_GPREL;
    break;
  case HexagonII::MO_GDGOT:
    RelocationType = MCSymbolRefExpr::VK_Hexagon_GD_GOT;
    break;
  case HexagonII::MO_GDPLT:
    RelocationType = MCSymbolRefExpr::VK_Hexagon_GD_PLT;
    break;
  case HexagonII::MO_IE:
    RelocationType = MCSymbolRefExpr::VK_Hexagon_IE;
    break;
  case HexagonII::MO_IEGOT:
    RelocationType = MCSymbolRefExpr::VK_Hexagon_IE_GOT;
    break;
  case HexagonII::MO_TPREL:
    RelocationType = MCSymbolRefExpr::VK_TPREL;
    break;
  }

  ME = MCSymbolRefExpr::create(Symbol, RelocationType, MC);

  if (!MO.isJTI() && MO.getOffset())
    ME = MCBinaryExpr::createAdd(ME, MCConstantExpr::create(MO.getOffset(), MC),
                                 MC);

  ME = HexagonMCExpr::create(ME, MC);
  HexagonMCInstrInfo::setMustExtend(*ME, MustExtend);
  return MCOperand::createExpr(ME);
}

// Create an MCInst from a MachineInstr
void llvm::HexagonLowerToMC(const MCInstrInfo &MCII, const MachineInstr *MI,
                            MCInst &MCB, HexagonAsmPrinter &AP) {
  if (MI->getOpcode() == Hexagon::ENDLOOP0) {
    HexagonMCInstrInfo::setInnerLoop(MCB);
    return;
  }
  if (MI->getOpcode() == Hexagon::ENDLOOP1) {
    HexagonMCInstrInfo::setOuterLoop(MCB);
    return;
  }
  MCInst *MCI = new (AP.OutContext) MCInst;
  MCI->setOpcode(MI->getOpcode());
  assert(MCI->getOpcode() == static_cast<unsigned>(MI->getOpcode()) &&
         "MCI opcode should have been set on construction");

  for (unsigned i = 0, e = MI->getNumOperands(); i < e; i++) {
    const MachineOperand &MO = MI->getOperand(i);
    MCOperand MCO;
    bool MustExtend = MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended;

    switch (MO.getType()) {
    default:
      MI->print(errs());
      llvm_unreachable("unknown operand type");
    case MachineOperand::MO_RegisterMask:
      continue;
    case MachineOperand::MO_Register:
      // Ignore all implicit register operands.
      if (MO.isImplicit())
        continue;
      MCO = MCOperand::createReg(MO.getReg());
      break;
    case MachineOperand::MO_FPImmediate: {
      APFloat Val = MO.getFPImm()->getValueAPF();
      // FP immediates are used only when setting GPRs, so they may be dealt
      // with like regular immediates from this point on.
      auto Expr = HexagonMCExpr::create(
          MCConstantExpr::create(*Val.bitcastToAPInt().getRawData(),
                                 AP.OutContext),
          AP.OutContext);
      HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
      MCO = MCOperand::createExpr(Expr);
      break;
    }
    case MachineOperand::MO_Immediate: {
      auto Expr = HexagonMCExpr::create(
          MCConstantExpr::create(MO.getImm(), AP.OutContext), AP.OutContext);
      HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
      MCO = MCOperand::createExpr(Expr);
      break;
    }
    case MachineOperand::MO_MachineBasicBlock: {
      MCExpr const *Expr = MCSymbolRefExpr::create(MO.getMBB()->getSymbol(),
                                                   AP.OutContext);
      Expr = HexagonMCExpr::create(Expr, AP.OutContext);
      HexagonMCInstrInfo::setMustExtend(*Expr, MustExtend);
      MCO = MCOperand::createExpr(Expr);
      break;
    }
    case MachineOperand::MO_GlobalAddress:
      MCO = GetSymbolRef(MO, AP.getSymbol(MO.getGlobal()), AP, MustExtend);
      break;
    case MachineOperand::MO_ExternalSymbol:
      MCO = GetSymbolRef(MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()),
                         AP, MustExtend);
      break;
    case MachineOperand::MO_JumpTableIndex:
      MCO = GetSymbolRef(MO, AP.GetJTISymbol(MO.getIndex()), AP, MustExtend);
      break;
    case MachineOperand::MO_ConstantPoolIndex:
      MCO = GetSymbolRef(MO, AP.GetCPISymbol(MO.getIndex()), AP, MustExtend);
      break;
    case MachineOperand::MO_BlockAddress:
      MCO = GetSymbolRef(MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP,
                         MustExtend);
      break;
    }

    MCI->addOperand(MCO);
  }
  AP.HexagonProcessInstruction(*MCI, *MI);
  HexagonMCInstrInfo::extendIfNeeded(AP.OutContext, MCII, MCB, *MCI);
  MCB.addOperand(MCOperand::createInst(MCI));
}
