1 //===-- CSKYMCInstLower.cpp - Convert CSKY 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 CSKY MachineInstrs to their corresponding
10 // MCInst records.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "CSKYMCInstLower.h"
15 #include "MCTargetDesc/CSKYBaseInfo.h"
16 #include "MCTargetDesc/CSKYMCExpr.h"
17 #include "llvm/CodeGen/AsmPrinter.h"
18 #include "llvm/MC/MCExpr.h"
19
20 #define DEBUG_TYPE "csky-mcinst-lower"
21
22 using namespace llvm;
23
CSKYMCInstLower(MCContext & Ctx,AsmPrinter & Printer)24 CSKYMCInstLower::CSKYMCInstLower(MCContext &Ctx, AsmPrinter &Printer)
25 : Ctx(Ctx), Printer(Printer) {}
26
Lower(const MachineInstr * MI,MCInst & OutMI) const27 void CSKYMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
28 OutMI.setOpcode(MI->getOpcode());
29
30 for (const MachineOperand &MO : MI->operands()) {
31 MCOperand MCOp;
32 if (lowerOperand(MO, MCOp))
33 OutMI.addOperand(MCOp);
34 }
35 }
36
lowerSymbolOperand(const MachineOperand & MO,MCSymbol * Sym) const37 MCOperand CSKYMCInstLower::lowerSymbolOperand(const MachineOperand &MO,
38 MCSymbol *Sym) const {
39 CSKYMCExpr::VariantKind Kind;
40 MCContext &Ctx = Printer.OutContext;
41
42 switch (MO.getTargetFlags()) {
43 default:
44 llvm_unreachable("Unknown target flag.");
45 case CSKYII::MO_None:
46 Kind = CSKYMCExpr::VK_CSKY_None;
47 break;
48 case CSKYII::MO_GOT32:
49 Kind = CSKYMCExpr::VK_CSKY_GOT;
50 break;
51 case CSKYII::MO_GOTOFF:
52 Kind = CSKYMCExpr::VK_CSKY_GOTOFF;
53 break;
54 case CSKYII::MO_ADDR32:
55 Kind = CSKYMCExpr::VK_CSKY_ADDR;
56 break;
57 case CSKYII::MO_PLT32:
58 Kind = CSKYMCExpr::VK_CSKY_PLT;
59 break;
60 case CSKYII::MO_ADDR_HI16:
61 Kind = CSKYMCExpr::VK_CSKY_ADDR_HI16;
62 break;
63 case CSKYII::MO_ADDR_LO16:
64 Kind = CSKYMCExpr::VK_CSKY_ADDR_LO16;
65 break;
66 }
67 const MCExpr *ME =
68 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
69
70 if (Kind != CSKYMCExpr::VK_CSKY_None)
71 ME = CSKYMCExpr::create(ME, Kind, Ctx);
72
73 return MCOperand::createExpr(ME);
74 }
75
lowerOperand(const MachineOperand & MO,MCOperand & MCOp) const76 bool CSKYMCInstLower::lowerOperand(const MachineOperand &MO,
77 MCOperand &MCOp) const {
78 switch (MO.getType()) {
79 default:
80 llvm_unreachable("unknown operand type");
81 case MachineOperand::MO_RegisterMask:
82 break;
83 case MachineOperand::MO_Immediate:
84 MCOp = MCOperand::createImm(MO.getImm());
85 break;
86 case MachineOperand::MO_Register:
87 if (MO.isImplicit())
88 return false;
89 MCOp = MCOperand::createReg(MO.getReg());
90 break;
91 case MachineOperand::MO_MachineBasicBlock:
92 MCOp = MCOperand::createExpr(
93 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
94 break;
95 case MachineOperand::MO_GlobalAddress:
96 MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal()));
97 break;
98 case MachineOperand::MO_BlockAddress:
99 MCOp = lowerSymbolOperand(
100 MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
101 break;
102 case MachineOperand::MO_ExternalSymbol:
103 MCOp = lowerSymbolOperand(
104 MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName()));
105 break;
106 case MachineOperand::MO_ConstantPoolIndex:
107 MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()));
108 break;
109 case MachineOperand::MO_JumpTableIndex:
110 MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()));
111 break;
112 case MachineOperand::MO_MCSymbol:
113 MCOp = lowerSymbolOperand(MO, MO.getMCSymbol());
114 break;
115 }
116 return true;
117 }
118