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
30using namespace llvm;
31
32MCSymbol *
33LanaiMCInstLower::GetGlobalAddressSymbol(const MachineOperand &MO) const {
34 return Printer.getSymbol(GV: MO.getGlobal());
35}
36
37MCSymbol *
38LanaiMCInstLower::GetBlockAddressSymbol(const MachineOperand &MO) const {
39 return Printer.GetBlockAddressSymbol(BA: MO.getBlockAddress());
40}
41
42MCSymbol *
43LanaiMCInstLower::GetExternalSymbolSymbol(const MachineOperand &MO) const {
44 return Printer.GetExternalSymbolSymbol(Sym: MO.getSymbolName());
45}
46
47MCSymbol *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: Name.str());
54}
55
56MCSymbol *
57LanaiMCInstLower::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: Name.str());
64}
65
66MCOperand 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(Symbol: Sym, Kind: MCSymbolRefExpr::VK_None, Ctx);
86 if (!MO.isJTI() && MO.getOffset())
87 Expr = MCBinaryExpr::createAdd(
88 LHS: Expr, RHS: MCConstantExpr::create(Value: MO.getOffset(), Ctx), Ctx);
89 Expr = LanaiMCExpr::create(Kind, Expr, Ctx);
90 return MCOperand::createExpr(Val: Expr);
91}
92
93void 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(Reg: MO.getReg());
104 break;
105 case MachineOperand::MO_Immediate:
106 MCOp = MCOperand::createImm(Val: MO.getImm());
107 break;
108 case MachineOperand::MO_MachineBasicBlock:
109 MCOp = MCOperand::createExpr(
110 Val: MCSymbolRefExpr::create(Symbol: MO.getMBB()->getSymbol(), Ctx));
111 break;
112 case MachineOperand::MO_RegisterMask:
113 continue;
114 case MachineOperand::MO_GlobalAddress:
115 MCOp = LowerSymbolOperand(MO, Sym: GetGlobalAddressSymbol(MO));
116 break;
117 case MachineOperand::MO_BlockAddress:
118 MCOp = LowerSymbolOperand(MO, Sym: GetBlockAddressSymbol(MO));
119 break;
120 case MachineOperand::MO_ExternalSymbol:
121 MCOp = LowerSymbolOperand(MO, Sym: GetExternalSymbolSymbol(MO));
122 break;
123 case MachineOperand::MO_JumpTableIndex:
124 MCOp = LowerSymbolOperand(MO, Sym: GetJumpTableSymbol(MO));
125 break;
126 case MachineOperand::MO_ConstantPoolIndex:
127 MCOp = LowerSymbolOperand(MO, Sym: GetConstantPoolIndexSymbol(MO));
128 break;
129 default:
130 MI->print(OS&: errs());
131 llvm_unreachable("unknown operand type");
132 }
133
134 OutMI.addOperand(Op: MCOp);
135 }
136}
137