Path: blob/main/contrib/llvm-project/llvm/lib/Target/M68k/M68kMCInstLower.cpp
35294 views
//===-- M68kMCInstLower.cpp - M68k MachineInstr to MCInst -------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// This file contains code to lower M68k MachineInstrs to their10/// corresponding MCInst records.11///12//===----------------------------------------------------------------------===//1314#include "M68kMCInstLower.h"1516#include "M68kAsmPrinter.h"17#include "M68kInstrInfo.h"1819#include "MCTargetDesc/M68kBaseInfo.h"2021#include "llvm/CodeGen/MachineFunction.h"22#include "llvm/CodeGen/MachineInstr.h"23#include "llvm/CodeGen/MachineOperand.h"24#include "llvm/IR/Mangler.h"25#include "llvm/MC/MCContext.h"26#include "llvm/MC/MCExpr.h"27#include "llvm/MC/MCInst.h"2829using namespace llvm;3031#define DEBUG_TYPE "m68k-mc-inst-lower"3233M68kMCInstLower::M68kMCInstLower(MachineFunction &MF, M68kAsmPrinter &AP)34: Ctx(MF.getContext()), MF(MF), TM(MF.getTarget()), MAI(*TM.getMCAsmInfo()),35AsmPrinter(AP) {}3637MCSymbol *38M68kMCInstLower::GetSymbolFromOperand(const MachineOperand &MO) const {39assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) &&40"Isn't a symbol reference");4142const auto &TT = TM.getTargetTriple();43if (MO.isGlobal() && TT.isOSBinFormatELF())44return AsmPrinter.getSymbolPreferLocal(*MO.getGlobal());4546const DataLayout &DL = MF.getDataLayout();4748MCSymbol *Sym = nullptr;49SmallString<128> Name;50StringRef Suffix;5152if (!Suffix.empty())53Name += DL.getPrivateGlobalPrefix();5455if (MO.isGlobal()) {56const GlobalValue *GV = MO.getGlobal();57AsmPrinter.getNameWithPrefix(Name, GV);58} else if (MO.isSymbol()) {59Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL);60} else if (MO.isMBB()) {61assert(Suffix.empty());62Sym = MO.getMBB()->getSymbol();63}6465Name += Suffix;66if (!Sym)67Sym = Ctx.getOrCreateSymbol(Name);6869return Sym;70}7172MCOperand M68kMCInstLower::LowerSymbolOperand(const MachineOperand &MO,73MCSymbol *Sym) const {74// FIXME We would like an efficient form for this, so we don't have to do a75// lot of extra uniquing. This fixme is originally from X8676const MCExpr *Expr = nullptr;77MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;7879switch (MO.getTargetFlags()) {80default:81llvm_unreachable("Unknown target flag on GV operand");82case M68kII::MO_NO_FLAG:83case M68kII::MO_ABSOLUTE_ADDRESS:84case M68kII::MO_PC_RELATIVE_ADDRESS:85break;86case M68kII::MO_GOTPCREL:87RefKind = MCSymbolRefExpr::VK_GOTPCREL;88break;89case M68kII::MO_GOT:90RefKind = MCSymbolRefExpr::VK_GOT;91break;92case M68kII::MO_GOTOFF:93RefKind = MCSymbolRefExpr::VK_GOTOFF;94break;95case M68kII::MO_PLT:96RefKind = MCSymbolRefExpr::VK_PLT;97break;98case M68kII::MO_TLSGD:99RefKind = MCSymbolRefExpr::VK_TLSGD;100break;101case M68kII::MO_TLSLD:102RefKind = MCSymbolRefExpr::VK_TLSLD;103break;104case M68kII::MO_TLSLDM:105RefKind = MCSymbolRefExpr::VK_TLSLDM;106break;107case M68kII::MO_TLSIE:108RefKind = MCSymbolRefExpr::VK_GOTTPOFF;109break;110case M68kII::MO_TLSLE:111RefKind = MCSymbolRefExpr::VK_TPOFF;112break;113}114115if (!Expr) {116Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);117}118119if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) {120Expr = MCBinaryExpr::createAdd(121Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);122}123124return MCOperand::createExpr(Expr);125}126127std::optional<MCOperand>128M68kMCInstLower::LowerOperand(const MachineInstr *MI,129const MachineOperand &MO) const {130switch (MO.getType()) {131default:132llvm_unreachable("unknown operand type");133case MachineOperand::MO_Register:134// Ignore all implicit register operands.135if (MO.isImplicit())136return std::nullopt;137return MCOperand::createReg(MO.getReg());138case MachineOperand::MO_Immediate:139return MCOperand::createImm(MO.getImm());140case MachineOperand::MO_MachineBasicBlock:141case MachineOperand::MO_GlobalAddress:142case MachineOperand::MO_ExternalSymbol:143return LowerSymbolOperand(MO, GetSymbolFromOperand(MO));144case MachineOperand::MO_MCSymbol:145return LowerSymbolOperand(MO, MO.getMCSymbol());146case MachineOperand::MO_JumpTableIndex:147return LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));148case MachineOperand::MO_ConstantPoolIndex:149return LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));150case MachineOperand::MO_BlockAddress:151return LowerSymbolOperand(152MO, AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));153case MachineOperand::MO_RegisterMask:154// Ignore call clobbers.155return std::nullopt;156}157}158159void M68kMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {160unsigned Opcode = MI->getOpcode();161OutMI.setOpcode(Opcode);162163for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {164const MachineOperand &MO = MI->getOperand(i);165std::optional<MCOperand> MCOp = LowerOperand(MI, MO);166167if (MCOp.has_value() && MCOp.value().isValid())168OutMI.addOperand(MCOp.value());169}170171// TAILJMPj, TAILJMPq - Lower to the correct jump instructions.172if (Opcode == M68k::TAILJMPj || Opcode == M68k::TAILJMPq) {173assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands");174switch (Opcode) {175case M68k::TAILJMPj:176Opcode = M68k::JMP32j;177break;178case M68k::TAILJMPq:179Opcode = M68k::BRA8;180break;181}182OutMI.setOpcode(Opcode);183}184}185186187