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