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