xref: /freebsd/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYMCInstLower.cpp (revision 1342eb5a832fa10e689a29faab3acb6054e4778c)
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 
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   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 
75 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