1 //===-- RISCVMCInstLower.cpp - Convert RISCV MachineInstr to an MCInst ------=//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains code to lower RISCV MachineInstrs to their corresponding
12 //===----------------------------------------------------------------------===//
15 #include "MCTargetDesc/RISCVMCExpr.h"
16 #include "llvm/CodeGen/AsmPrinter.h"
17 #include "llvm/CodeGen/MachineBasicBlock.h"
18 #include "llvm/CodeGen/MachineInstr.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/MC/MCContext.h"
21 #include "llvm/MC/MCExpr.h"
22 #include "llvm/MC/MCInst.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
28 static MCOperand
lowerSymbolOperand(const MachineOperand
&MO
, MCSymbol
*Sym
,
29 const AsmPrinter
&AP
) {
30 MCContext
&Ctx
= AP
.OutContext
;
31 RISCVMCExpr::VariantKind Kind
;
33 switch (MO
.getTargetFlags()) {
35 llvm_unreachable("Unknown target flag on GV operand");
36 case RISCVII::MO_None
:
37 Kind
= RISCVMCExpr::VK_RISCV_None
;
39 case RISCVII::MO_CALL
:
40 Kind
= RISCVMCExpr::VK_RISCV_CALL
;
43 Kind
= RISCVMCExpr::VK_RISCV_CALL_PLT
;
46 Kind
= RISCVMCExpr::VK_RISCV_LO
;
49 Kind
= RISCVMCExpr::VK_RISCV_HI
;
51 case RISCVII::MO_PCREL_LO
:
52 Kind
= RISCVMCExpr::VK_RISCV_PCREL_LO
;
54 case RISCVII::MO_PCREL_HI
:
55 Kind
= RISCVMCExpr::VK_RISCV_PCREL_HI
;
57 case RISCVII::MO_GOT_HI
:
58 Kind
= RISCVMCExpr::VK_RISCV_GOT_HI
;
60 case RISCVII::MO_TPREL_LO
:
61 Kind
= RISCVMCExpr::VK_RISCV_TPREL_LO
;
63 case RISCVII::MO_TPREL_HI
:
64 Kind
= RISCVMCExpr::VK_RISCV_TPREL_HI
;
66 case RISCVII::MO_TPREL_ADD
:
67 Kind
= RISCVMCExpr::VK_RISCV_TPREL_ADD
;
69 case RISCVII::MO_TLS_GOT_HI
:
70 Kind
= RISCVMCExpr::VK_RISCV_TLS_GOT_HI
;
72 case RISCVII::MO_TLS_GD_HI
:
73 Kind
= RISCVMCExpr::VK_RISCV_TLS_GD_HI
;
78 MCSymbolRefExpr::create(Sym
, MCSymbolRefExpr::VK_None
, Ctx
);
80 if (!MO
.isJTI() && !MO
.isMBB() && MO
.getOffset())
81 ME
= MCBinaryExpr::createAdd(
82 ME
, MCConstantExpr::create(MO
.getOffset(), Ctx
), Ctx
);
84 if (Kind
!= RISCVMCExpr::VK_RISCV_None
)
85 ME
= RISCVMCExpr::create(ME
, Kind
, Ctx
);
86 return MCOperand::createExpr(ME
);
89 bool llvm::LowerRISCVMachineOperandToMCOperand(const MachineOperand
&MO
,
91 const AsmPrinter
&AP
) {
92 switch (MO
.getType()) {
94 report_fatal_error("LowerRISCVMachineInstrToMCInst: unknown operand type");
95 case MachineOperand::MO_Register
:
96 // Ignore all implicit register operands.
99 MCOp
= MCOperand::createReg(MO
.getReg());
101 case MachineOperand::MO_RegisterMask
:
102 // Regmasks are like implicit defs.
104 case MachineOperand::MO_Immediate
:
105 MCOp
= MCOperand::createImm(MO
.getImm());
107 case MachineOperand::MO_MachineBasicBlock
:
108 MCOp
= lowerSymbolOperand(MO
, MO
.getMBB()->getSymbol(), AP
);
110 case MachineOperand::MO_GlobalAddress
:
111 MCOp
= lowerSymbolOperand(MO
, AP
.getSymbol(MO
.getGlobal()), AP
);
113 case MachineOperand::MO_BlockAddress
:
114 MCOp
= lowerSymbolOperand(
115 MO
, AP
.GetBlockAddressSymbol(MO
.getBlockAddress()), AP
);
117 case MachineOperand::MO_ExternalSymbol
:
118 MCOp
= lowerSymbolOperand(
119 MO
, AP
.GetExternalSymbolSymbol(MO
.getSymbolName()), AP
);
121 case MachineOperand::MO_ConstantPoolIndex
:
122 MCOp
= lowerSymbolOperand(MO
, AP
.GetCPISymbol(MO
.getIndex()), AP
);
128 void llvm::LowerRISCVMachineInstrToMCInst(const MachineInstr
*MI
, MCInst
&OutMI
,
129 const AsmPrinter
&AP
) {
130 OutMI
.setOpcode(MI
->getOpcode());
132 for (const MachineOperand
&MO
: MI
->operands()) {
134 if (LowerRISCVMachineOperandToMCOperand(MO
, MCOp
, AP
))
135 OutMI
.addOperand(MCOp
);