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 (const MachineOperand &MO : MI->operands()) { 97 MCOperand MCOp; 98 switch (MO.getType()) { 99 case MachineOperand::MO_Register: 100 // Ignore all implicit register operands. 101 if (MO.isImplicit()) 102 continue; 103 MCOp = MCOperand::createReg(MO.getReg()); 104 break; 105 case MachineOperand::MO_Immediate: 106 MCOp = MCOperand::createImm(MO.getImm()); 107 break; 108 case MachineOperand::MO_MachineBasicBlock: 109 MCOp = MCOperand::createExpr( 110 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx)); 111 break; 112 case MachineOperand::MO_RegisterMask: 113 continue; 114 case MachineOperand::MO_GlobalAddress: 115 MCOp = LowerSymbolOperand(MO, GetGlobalAddressSymbol(MO)); 116 break; 117 case MachineOperand::MO_BlockAddress: 118 MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO)); 119 break; 120 case MachineOperand::MO_ExternalSymbol: 121 MCOp = LowerSymbolOperand(MO, GetExternalSymbolSymbol(MO)); 122 break; 123 case MachineOperand::MO_JumpTableIndex: 124 MCOp = LowerSymbolOperand(MO, GetJumpTableSymbol(MO)); 125 break; 126 case MachineOperand::MO_ConstantPoolIndex: 127 MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO)); 128 break; 129 default: 130 MI->print(errs()); 131 llvm_unreachable("unknown operand type"); 132 } 133 134 OutMI.addOperand(MCOp); 135 } 136 } 137