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 
24 CSKYMCInstLower::CSKYMCInstLower(MCContext &Ctx, AsmPrinter &Printer)
25     : Ctx(Ctx), Printer(Printer) {}
26 
27 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 
37 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 
76 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