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 *
GetGlobalAddressSymbol(const MachineOperand & MO) const33 LanaiMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
34 return Printer.getSymbol(MO.getGlobal());
35 }
36
37 MCSymbol *
GetBlockAddressSymbol(const MachineOperand & MO) const38 LanaiMCInstLower::GetBlockAddressSymbol(const MachineOperand &MO) const {
39 return Printer.GetBlockAddressSymbol(MO.getBlockAddress());
40 }
41
42 MCSymbol *
GetExternalSymbolSymbol(const MachineOperand & MO) const43 LanaiMCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const {
44 return Printer.GetExternalSymbolSymbol(MO.getSymbolName());
45 }
46
GetJumpTableSymbol(const MachineOperand & MO) const47 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 *
GetConstantPoolIndexSymbol(const MachineOperand & MO) const57 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
LowerSymbolOperand(const MachineOperand & MO,MCSymbol * Sym) const66 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
Lower(const MachineInstr * MI,MCInst & OutMI) const93 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