1//=-- LanaiMCInstLower.cpp - Convert Lanai MachineInstr to an MCInst --------=// 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-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file contains code to lower Lanai MachineInstrs to their corresponding 10// MCInst records. 11// 12//===----------------------------------------------------------------------===// 13 14#include "LanaiMCInstLower.h" 15 16#include "MCTargetDesc/LanaiBaseInfo.h" 17#include "MCTargetDesc/LanaiMCExpr.h" 18#include "llvm/ADT/SmallString.h" 19#include "llvm/CodeGen/AsmPrinter.h" 20#include "llvm/CodeGen/MachineBasicBlock.h" 21#include "llvm/CodeGen/MachineInstr.h" 22#include "llvm/IR/Constants.h" 23#include "llvm/MC/MCAsmInfo.h" 24#include "llvm/MC/MCContext.h" 25#include "llvm/MC/MCExpr.h" 26#include "llvm/MC/MCInst.h" 27#include "llvm/Support/ErrorHandling.h" 28#include "llvm/Support/raw_ostream.h" 29 30using namespace llvm; 31 32MCSymbol * 33LanaiMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const { 34 return Printer.getSymbol(MO.getGlobal()); 35} 36 37MCSymbol * 38LanaiMCInstLower::GetBlockAddressSymbol(const MachineOperand &MO) const { 39 return Printer.GetBlockAddressSymbol(MO.getBlockAddress()); 40} 41 42MCSymbol * 43LanaiMCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const { 44 return Printer.GetExternalSymbolSymbol(MO.getSymbolName()); 45} 46 47MCSymbol *LanaiMCInstLower::GetJumpTableSymbol(const MachineOperand &MO) const { 48 SmallString<256> Name; 49 raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "JTI" 50 << Printer.getFunctionNumber() << '_' 51 << MO.getIndex(); 52 // Create a symbol for the name. 53 return Ctx.getOrCreateSymbol(Name.str()); 54} 55 56MCSymbol * 57LanaiMCInstLower::GetConstantPoolIndexSymbol(const MachineOperand &MO) const { 58 SmallString<256> Name; 59 raw_svector_ostream(Name) << Printer.MAI->getPrivateGlobalPrefix() << "CPI" 60 << Printer.getFunctionNumber() << '_' 61 << MO.getIndex(); 62 // Create a symbol for the name. 63 return Ctx.getOrCreateSymbol(Name.str()); 64} 65 66MCOperand LanaiMCInstLower::LowerSymbolOperand(const MachineOperand &MO, 67 MCSymbol *Sym) const { 68 LanaiMCExpr::VariantKind Kind; 69 70 switch (MO.getTargetFlags()) { 71 case LanaiII::MO_NO_FLAG: 72 Kind = LanaiMCExpr::VK_Lanai_None; 73 break; 74 case LanaiII::MO_ABS_HI: 75 Kind = LanaiMCExpr::VK_Lanai_ABS_HI; 76 break; 77 case LanaiII::MO_ABS_LO: 78 Kind = LanaiMCExpr::VK_Lanai_ABS_LO; 79 break; 80 default: 81 llvm_unreachable("Unknown target flag on GV operand"); 82 } 83 84 const MCExpr *Expr = 85 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); 86 if (!MO.isJTI() && MO.getOffset()) 87 Expr = MCBinaryExpr::createAdd( 88 Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); 89 Expr = LanaiMCExpr::create(Kind, Expr, Ctx); 90 return MCOperand::createExpr(Expr); 91} 92 93void LanaiMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const { 94 OutMI.setOpcode(MI->getOpcode()); 95 96 for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) { 97 const MachineOperand &MO = MI->getOperand(I); 98 99 MCOperand MCOp; 100 switch (MO.getType()) { 101 case MachineOperand::MO_Register: 102 // Ignore all implicit register operands. 103 if (MO.isImplicit()) 104 continue; 105 MCOp = MCOperand::createReg(MO.getReg()); 106 break; 107 case MachineOperand::MO_Immediate: 108 MCOp = MCOperand::createImm(MO.getImm()); 109 break; 110 case MachineOperand::MO_MachineBasicBlock: 111 MCOp = MCOperand::createExpr( 112 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); 113 break; 114 case MachineOperand::MO_RegisterMask: 115 continue; 116 case MachineOperand::MO_GlobalAddress: 117 MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); 118 break; 119 case MachineOperand::MO_BlockAddress: 120 MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO)); 121 break; 122 case MachineOperand::MO_ExternalSymbol: 123 MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); 124 break; 125 case MachineOperand::MO_JumpTableIndex: 126 MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO)); 127 break; 128 case MachineOperand::MO_ConstantPoolIndex: 129 MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO)); 130 break; 131 default: 132 MI->print(errs()); 133 llvm_unreachable("unknown operand type"); 134 } 135 136 OutMI.addOperand(MCOp); 137 } 138} 139