187 lines · cpp
1//===-- M68kMCInstLower.cpp - M68k MachineInstr to MCInst -------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file contains code to lower M68k MachineInstrs to their11/// corresponding MCInst records.12///13//===----------------------------------------------------------------------===//14 15#include "M68kMCInstLower.h"16 17#include "M68kAsmPrinter.h"18#include "M68kInstrInfo.h"19 20#include "MCTargetDesc/M68kBaseInfo.h"21#include "MCTargetDesc/M68kMCAsmInfo.h"22 23#include "llvm/CodeGen/MachineFunction.h"24#include "llvm/CodeGen/MachineInstr.h"25#include "llvm/CodeGen/MachineOperand.h"26#include "llvm/IR/Mangler.h"27#include "llvm/MC/MCContext.h"28#include "llvm/MC/MCExpr.h"29#include "llvm/MC/MCInst.h"30 31using namespace llvm;32 33#define DEBUG_TYPE "m68k-mc-inst-lower"34 35M68kMCInstLower::M68kMCInstLower(MachineFunction &MF, M68kAsmPrinter &AP)36 : Ctx(AP.OutContext), MF(MF), TM(MF.getTarget()), MAI(*TM.getMCAsmInfo()),37 AsmPrinter(AP) {}38 39MCSymbol *40M68kMCInstLower::GetSymbolFromOperand(const MachineOperand &MO) const {41 assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) &&42 "Isn't a symbol reference");43 44 const auto &TT = TM.getTargetTriple();45 if (MO.isGlobal() && TT.isOSBinFormatELF())46 return AsmPrinter.getSymbolPreferLocal(*MO.getGlobal());47 48 const DataLayout &DL = MF.getDataLayout();49 50 MCSymbol *Sym = nullptr;51 SmallString<128> Name;52 StringRef Suffix;53 54 if (!Suffix.empty())55 Name += DL.getPrivateGlobalPrefix();56 57 if (MO.isGlobal()) {58 const GlobalValue *GV = MO.getGlobal();59 AsmPrinter.getNameWithPrefix(Name, GV);60 } else if (MO.isSymbol()) {61 Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL);62 } else if (MO.isMBB()) {63 assert(Suffix.empty());64 Sym = MO.getMBB()->getSymbol();65 }66 67 Name += Suffix;68 if (!Sym)69 Sym = Ctx.getOrCreateSymbol(Name);70 71 return Sym;72}73 74MCOperand M68kMCInstLower::LowerSymbolOperand(const MachineOperand &MO,75 MCSymbol *Sym) const {76 // FIXME We would like an efficient form for this, so we don't have to do a77 // lot of extra uniquing. This fixme is originally from X8678 const MCExpr *Expr = nullptr;79 M68k::Specifier RefKind = M68k::S_None;80 81 switch (MO.getTargetFlags()) {82 default:83 llvm_unreachable("Unknown target flag on GV operand");84 case M68kII::MO_NO_FLAG:85 case M68kII::MO_ABSOLUTE_ADDRESS:86 case M68kII::MO_PC_RELATIVE_ADDRESS:87 break;88 case M68kII::MO_GOTPCREL:89 RefKind = M68k::S_GOTPCREL;90 break;91 case M68kII::MO_GOT:92 RefKind = M68k::S_GOT;93 break;94 case M68kII::MO_GOTOFF:95 RefKind = M68k::S_GOTOFF;96 break;97 case M68kII::MO_PLT:98 RefKind = M68k::S_PLT;99 break;100 case M68kII::MO_TLSGD:101 RefKind = M68k::S_TLSGD;102 break;103 case M68kII::MO_TLSLD:104 RefKind = M68k::S_TLSLD;105 break;106 case M68kII::MO_TLSLDM:107 RefKind = M68k::S_TLSLDM;108 break;109 case M68kII::MO_TLSIE:110 RefKind = M68k::S_GOTTPOFF;111 break;112 case M68kII::MO_TLSLE:113 RefKind = M68k::S_TPOFF;114 break;115 }116 117 if (!Expr) {118 Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);119 }120 121 if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) {122 Expr = MCBinaryExpr::createAdd(123 Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);124 }125 126 return MCOperand::createExpr(Expr);127}128 129std::optional<MCOperand>130M68kMCInstLower::LowerOperand(const MachineInstr *MI,131 const MachineOperand &MO) const {132 switch (MO.getType()) {133 default:134 llvm_unreachable("unknown operand type");135 case MachineOperand::MO_Register:136 // Ignore all implicit register operands.137 if (MO.isImplicit())138 return std::nullopt;139 return MCOperand::createReg(MO.getReg());140 case MachineOperand::MO_Immediate:141 return MCOperand::createImm(MO.getImm());142 case MachineOperand::MO_MachineBasicBlock:143 case MachineOperand::MO_GlobalAddress:144 case MachineOperand::MO_ExternalSymbol:145 return LowerSymbolOperand(MO, GetSymbolFromOperand(MO));146 case MachineOperand::MO_MCSymbol:147 return LowerSymbolOperand(MO, MO.getMCSymbol());148 case MachineOperand::MO_JumpTableIndex:149 return LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));150 case MachineOperand::MO_ConstantPoolIndex:151 return LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));152 case MachineOperand::MO_BlockAddress:153 return LowerSymbolOperand(154 MO, AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));155 case MachineOperand::MO_RegisterMask:156 // Ignore call clobbers.157 return std::nullopt;158 }159}160 161void M68kMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {162 unsigned Opcode = MI->getOpcode();163 OutMI.setOpcode(Opcode);164 165 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {166 const MachineOperand &MO = MI->getOperand(i);167 std::optional<MCOperand> MCOp = LowerOperand(MI, MO);168 169 if (MCOp.has_value() && MCOp.value().isValid())170 OutMI.addOperand(MCOp.value());171 }172 173 // TAILJMPj, TAILJMPq - Lower to the correct jump instructions.174 if (Opcode == M68k::TAILJMPj || Opcode == M68k::TAILJMPq) {175 assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands");176 switch (Opcode) {177 case M68k::TAILJMPj:178 Opcode = M68k::JMP32j;179 break;180 case M68k::TAILJMPq:181 Opcode = M68k::BRA8;182 break;183 }184 OutMI.setOpcode(Opcode);185 }186}187