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 30 using namespace llvm; 31 32 MCSymbol * 33 LanaiMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const { 34 return Printer.getSymbol(MO.getGlobal()); 35 } 36 37 MCSymbol * 38 LanaiMCInstLower::GetBlockAddressSymbol(const MachineOperand &MO) const { 39 return Printer.GetBlockAddressSymbol(MO.getBlockAddress()); 40 } 41 42 MCSymbol * 43 LanaiMCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const { 44 return Printer.GetExternalSymbolSymbol(MO.getSymbolName()); 45 } 46 47 MCSymbol *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 56 MCSymbol * 57 LanaiMCInstLower::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 66 MCOperand 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 93 void 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