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/CSKYMCAsmInfo.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 CSKY::Specifier Spec;
40 MCContext &Ctx = Printer.OutContext;
41
42 switch (MO.getTargetFlags()) {
43 default:
44 llvm_unreachable("Unknown target flag.");
45 case CSKYII::MO_None:
46 Spec = CSKY::S_None;
47 break;
48 case CSKYII::MO_GOT32:
49 Spec = CSKY::S_GOT;
50 break;
51 case CSKYII::MO_GOTOFF:
52 Spec = CSKY::S_GOTOFF;
53 break;
54 case CSKYII::MO_ADDR32:
55 Spec = CSKY::S_ADDR;
56 break;
57 case CSKYII::MO_PLT32:
58 Spec = CSKY::S_PLT;
59 break;
60 case CSKYII::MO_ADDR_HI16:
61 Spec = CSKY::S_ADDR_HI16;
62 break;
63 case CSKYII::MO_ADDR_LO16:
64 Spec = CSKY::S_ADDR_LO16;
65 break;
66 }
67 const MCExpr *ME = MCSymbolRefExpr::create(Sym, Ctx);
68
69 if (Spec != CSKY::S_None)
70 ME = MCSpecifierExpr::create(ME, Spec, Ctx);
71
72 return MCOperand::createExpr(ME);
73 }
74
lowerOperand(const MachineOperand & MO,MCOperand & MCOp) const75 bool CSKYMCInstLower::lowerOperand(const MachineOperand &MO,
76 MCOperand &MCOp) const {
77 switch (MO.getType()) {
78 default:
79 llvm_unreachable("unknown operand type");
80 case MachineOperand::MO_RegisterMask:
81 break;
82 case MachineOperand::MO_Immediate:
83 MCOp = MCOperand::createImm(MO.getImm());
84 break;
85 case MachineOperand::MO_Register:
86 if (MO.isImplicit())
87 return false;
88 MCOp = MCOperand::createReg(MO.getReg());
89 break;
90 case MachineOperand::MO_MachineBasicBlock:
91 MCOp = MCOperand::createExpr(
92 MCSymbolRefExpr::create(MO.getMBB()->getSymbol(), Ctx));
93 break;
94 case MachineOperand::MO_GlobalAddress:
95 MCOp = lowerSymbolOperand(MO, Printer.getSymbol(MO.getGlobal()));
96 break;
97 case MachineOperand::MO_BlockAddress:
98 MCOp = lowerSymbolOperand(
99 MO, Printer.GetBlockAddressSymbol(MO.getBlockAddress()));
100 break;
101 case MachineOperand::MO_ExternalSymbol:
102 MCOp = lowerSymbolOperand(
103 MO, Printer.GetExternalSymbolSymbol(MO.getSymbolName()));
104 break;
105 case MachineOperand::MO_ConstantPoolIndex:
106 MCOp = lowerSymbolOperand(MO, Printer.GetCPISymbol(MO.getIndex()));
107 break;
108 case MachineOperand::MO_JumpTableIndex:
109 MCOp = lowerSymbolOperand(MO, Printer.GetJTISymbol(MO.getIndex()));
110 break;
111 case MachineOperand::MO_MCSymbol:
112 MCOp = lowerSymbolOperand(MO, MO.getMCSymbol());
113 break;
114 }
115 return true;
116 }
117