xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
181ad6265SDimitry Andric //=- LoongArchMCInstLower.cpp - Convert LoongArch MachineInstr to an MCInst -=//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric //
981ad6265SDimitry Andric // This file contains code to lower LoongArch MachineInstrs to their
1081ad6265SDimitry Andric // corresponding MCInst records.
1181ad6265SDimitry Andric //
1281ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1381ad6265SDimitry Andric 
1481ad6265SDimitry Andric #include "LoongArch.h"
1581ad6265SDimitry Andric #include "LoongArchSubtarget.h"
16bdd1243dSDimitry Andric #include "MCTargetDesc/LoongArchBaseInfo.h"
17bdd1243dSDimitry Andric #include "MCTargetDesc/LoongArchMCExpr.h"
1881ad6265SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
1981ad6265SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
2081ad6265SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
2181ad6265SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
2281ad6265SDimitry Andric #include "llvm/MC/MCContext.h"
2381ad6265SDimitry Andric #include "llvm/Support/raw_ostream.h"
2481ad6265SDimitry Andric 
2581ad6265SDimitry Andric using namespace llvm;
2681ad6265SDimitry Andric 
27753f127fSDimitry Andric static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
28753f127fSDimitry Andric                                     const AsmPrinter &AP) {
29753f127fSDimitry Andric   MCContext &Ctx = AP.OutContext;
30bdd1243dSDimitry Andric   LoongArchMCExpr::VariantKind Kind;
31753f127fSDimitry Andric 
32bdd1243dSDimitry Andric   switch (MO.getTargetFlags()) {
33bdd1243dSDimitry Andric   default:
34bdd1243dSDimitry Andric     llvm_unreachable("Unknown target flag on GV operand");
35bdd1243dSDimitry Andric   case LoongArchII::MO_None:
36bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_None;
37bdd1243dSDimitry Andric     break;
38bdd1243dSDimitry Andric   case LoongArchII::MO_CALL:
39bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_CALL;
40bdd1243dSDimitry Andric     break;
41bdd1243dSDimitry Andric   case LoongArchII::MO_CALL_PLT:
42bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_CALL_PLT;
43bdd1243dSDimitry Andric     break;
44bdd1243dSDimitry Andric   case LoongArchII::MO_PCREL_HI:
45bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_PCALA_HI20;
46bdd1243dSDimitry Andric     break;
47bdd1243dSDimitry Andric   case LoongArchII::MO_PCREL_LO:
48bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_PCALA_LO12;
49bdd1243dSDimitry Andric     break;
5006c3fb27SDimitry Andric   case LoongArchII::MO_PCREL64_LO:
5106c3fb27SDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_PCALA64_LO20;
5206c3fb27SDimitry Andric     break;
5306c3fb27SDimitry Andric   case LoongArchII::MO_PCREL64_HI:
5406c3fb27SDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_PCALA64_HI12;
5506c3fb27SDimitry Andric     break;
56bdd1243dSDimitry Andric   case LoongArchII::MO_GOT_PC_HI:
57bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_GOT_PC_HI20;
58bdd1243dSDimitry Andric     break;
59bdd1243dSDimitry Andric   case LoongArchII::MO_GOT_PC_LO:
60bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12;
61bdd1243dSDimitry Andric     break;
6206c3fb27SDimitry Andric   case LoongArchII::MO_GOT_PC64_LO:
6306c3fb27SDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_GOT64_PC_LO20;
6406c3fb27SDimitry Andric     break;
6506c3fb27SDimitry Andric   case LoongArchII::MO_GOT_PC64_HI:
6606c3fb27SDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_GOT64_PC_HI12;
6706c3fb27SDimitry Andric     break;
68bdd1243dSDimitry Andric   case LoongArchII::MO_LE_HI:
69bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE_HI20;
70bdd1243dSDimitry Andric     break;
71bdd1243dSDimitry Andric   case LoongArchII::MO_LE_LO:
72bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12;
73bdd1243dSDimitry Andric     break;
7406c3fb27SDimitry Andric   case LoongArchII::MO_LE64_LO:
7506c3fb27SDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE64_LO20;
7606c3fb27SDimitry Andric     break;
7706c3fb27SDimitry Andric   case LoongArchII::MO_LE64_HI:
7806c3fb27SDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE64_HI12;
7906c3fb27SDimitry Andric     break;
80bdd1243dSDimitry Andric   case LoongArchII::MO_IE_PC_HI:
81bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_HI20;
82bdd1243dSDimitry Andric     break;
83bdd1243dSDimitry Andric   case LoongArchII::MO_IE_PC_LO:
84bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_LO12;
85bdd1243dSDimitry Andric     break;
8606c3fb27SDimitry Andric   case LoongArchII::MO_IE_PC64_LO:
8706c3fb27SDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_LO20;
8806c3fb27SDimitry Andric     break;
8906c3fb27SDimitry Andric   case LoongArchII::MO_IE_PC64_HI:
9006c3fb27SDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_HI12;
9106c3fb27SDimitry Andric     break;
92bdd1243dSDimitry Andric   case LoongArchII::MO_LD_PC_HI:
93bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_TLS_LD_PC_HI20;
94bdd1243dSDimitry Andric     break;
95bdd1243dSDimitry Andric   case LoongArchII::MO_GD_PC_HI:
96bdd1243dSDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_TLS_GD_PC_HI20;
97bdd1243dSDimitry Andric     break;
98*1db9f3b2SDimitry Andric   case LoongArchII::MO_CALL36:
99*1db9f3b2SDimitry Andric     Kind = LoongArchMCExpr::VK_LoongArch_CALL36;
100*1db9f3b2SDimitry Andric     break;
101bdd1243dSDimitry Andric     // TODO: Handle more target-flags.
102bdd1243dSDimitry Andric   }
103753f127fSDimitry Andric 
104753f127fSDimitry Andric   const MCExpr *ME =
105753f127fSDimitry Andric       MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
106753f127fSDimitry Andric 
107753f127fSDimitry Andric   if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
108753f127fSDimitry Andric     ME = MCBinaryExpr::createAdd(
109753f127fSDimitry Andric         ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
110753f127fSDimitry Andric 
111bdd1243dSDimitry Andric   if (Kind != LoongArchMCExpr::VK_LoongArch_None)
112bdd1243dSDimitry Andric     ME = LoongArchMCExpr::create(ME, Kind, Ctx);
113753f127fSDimitry Andric   return MCOperand::createExpr(ME);
114753f127fSDimitry Andric }
115753f127fSDimitry Andric 
11681ad6265SDimitry Andric bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
11781ad6265SDimitry Andric                                                    MCOperand &MCOp,
11881ad6265SDimitry Andric                                                    const AsmPrinter &AP) {
11981ad6265SDimitry Andric   switch (MO.getType()) {
12081ad6265SDimitry Andric   default:
12181ad6265SDimitry Andric     report_fatal_error(
12281ad6265SDimitry Andric         "lowerLoongArchMachineOperandToMCOperand: unknown operand type");
12381ad6265SDimitry Andric   case MachineOperand::MO_Register:
12481ad6265SDimitry Andric     // Ignore all implicit register operands.
12581ad6265SDimitry Andric     if (MO.isImplicit())
12681ad6265SDimitry Andric       return false;
12781ad6265SDimitry Andric     MCOp = MCOperand::createReg(MO.getReg());
12881ad6265SDimitry Andric     break;
12981ad6265SDimitry Andric   case MachineOperand::MO_RegisterMask:
13081ad6265SDimitry Andric     // Regmasks are like implicit defs.
13181ad6265SDimitry Andric     return false;
13281ad6265SDimitry Andric   case MachineOperand::MO_Immediate:
13381ad6265SDimitry Andric     MCOp = MCOperand::createImm(MO.getImm());
13481ad6265SDimitry Andric     break;
13581ad6265SDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
136753f127fSDimitry Andric     MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP);
137753f127fSDimitry Andric     break;
138753f127fSDimitry Andric   case MachineOperand::MO_GlobalAddress:
139753f127fSDimitry Andric     MCOp = lowerSymbolOperand(MO, AP.getSymbolPreferLocal(*MO.getGlobal()), AP);
140753f127fSDimitry Andric     break;
141753f127fSDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
142753f127fSDimitry Andric     MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), AP);
143753f127fSDimitry Andric     break;
144753f127fSDimitry Andric   case MachineOperand::MO_ExternalSymbol:
145753f127fSDimitry Andric     MCOp = lowerSymbolOperand(
146753f127fSDimitry Andric         MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP);
147753f127fSDimitry Andric     break;
148753f127fSDimitry Andric   case MachineOperand::MO_BlockAddress:
149bdd1243dSDimitry Andric     MCOp = lowerSymbolOperand(
150bdd1243dSDimitry Andric         MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP);
151bdd1243dSDimitry Andric     break;
15281ad6265SDimitry Andric   case MachineOperand::MO_JumpTableIndex:
153bdd1243dSDimitry Andric     MCOp = lowerSymbolOperand(MO, AP.GetJTISymbol(MO.getIndex()), AP);
15481ad6265SDimitry Andric     break;
15581ad6265SDimitry Andric   }
15681ad6265SDimitry Andric   return true;
15781ad6265SDimitry Andric }
15881ad6265SDimitry Andric 
15981ad6265SDimitry Andric bool llvm::lowerLoongArchMachineInstrToMCInst(const MachineInstr *MI,
16081ad6265SDimitry Andric                                               MCInst &OutMI, AsmPrinter &AP) {
16181ad6265SDimitry Andric   OutMI.setOpcode(MI->getOpcode());
16281ad6265SDimitry Andric 
16381ad6265SDimitry Andric   for (const MachineOperand &MO : MI->operands()) {
16481ad6265SDimitry Andric     MCOperand MCOp;
16581ad6265SDimitry Andric     if (lowerLoongArchMachineOperandToMCOperand(MO, MCOp, AP))
16681ad6265SDimitry Andric       OutMI.addOperand(MCOp);
16781ad6265SDimitry Andric   }
16881ad6265SDimitry Andric   return false;
16981ad6265SDimitry Andric }
170