1 //=- LoongArchMCInstLower.cpp - Convert LoongArch 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 LoongArch MachineInstrs to their
10 // corresponding MCInst records.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "LoongArch.h"
15 #include "LoongArchSubtarget.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/Support/raw_ostream.h"
22
23 using namespace llvm;
24
lowerSymbolOperand(const MachineOperand & MO,MCSymbol * Sym,const AsmPrinter & AP)25 static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
26 const AsmPrinter &AP) {
27 MCContext &Ctx = AP.OutContext;
28
29 // TODO: Processing target flags.
30
31 const MCExpr *ME =
32 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
33
34 if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
35 ME = MCBinaryExpr::createAdd(
36 ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
37
38 return MCOperand::createExpr(ME);
39 }
40
lowerLoongArchMachineOperandToMCOperand(const MachineOperand & MO,MCOperand & MCOp,const AsmPrinter & AP)41 bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
42 MCOperand &MCOp,
43 const AsmPrinter &AP) {
44 switch (MO.getType()) {
45 default:
46 report_fatal_error(
47 "lowerLoongArchMachineOperandToMCOperand: unknown operand type");
48 case MachineOperand::MO_Register:
49 // Ignore all implicit register operands.
50 if (MO.isImplicit())
51 return false;
52 MCOp = MCOperand::createReg(MO.getReg());
53 break;
54 case MachineOperand::MO_RegisterMask:
55 // Regmasks are like implicit defs.
56 return false;
57 case MachineOperand::MO_Immediate:
58 MCOp = MCOperand::createImm(MO.getImm());
59 break;
60 case MachineOperand::MO_ConstantPoolIndex:
61 MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP);
62 break;
63 case MachineOperand::MO_GlobalAddress:
64 MCOp = lowerSymbolOperand(MO, AP.getSymbolPreferLocal(*MO.getGlobal()), AP);
65 break;
66 case MachineOperand::MO_MachineBasicBlock:
67 MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), AP);
68 break;
69 case MachineOperand::MO_ExternalSymbol:
70 MCOp = lowerSymbolOperand(
71 MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP);
72 break;
73 // TODO: lower special operands
74 case MachineOperand::MO_BlockAddress:
75 case MachineOperand::MO_JumpTableIndex:
76 break;
77 }
78 return true;
79 }
80
lowerLoongArchMachineInstrToMCInst(const MachineInstr * MI,MCInst & OutMI,AsmPrinter & AP)81 bool llvm::lowerLoongArchMachineInstrToMCInst(const MachineInstr *MI,
82 MCInst &OutMI, AsmPrinter &AP) {
83 OutMI.setOpcode(MI->getOpcode());
84
85 for (const MachineOperand &MO : MI->operands()) {
86 MCOperand MCOp;
87 if (lowerLoongArchMachineOperandToMCOperand(MO, MCOp, AP))
88 OutMI.addOperand(MCOp);
89 }
90 return false;
91 }
92