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