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