xref: /freebsd/contrib/llvm-project/llvm/lib/Target/LoongArch/LoongArchMCInstLower.cpp (revision 753f127f3ace09432b2baeffd71a308760641a62)
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"
1681ad6265SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
1781ad6265SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
1881ad6265SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
1981ad6265SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
2081ad6265SDimitry Andric #include "llvm/MC/MCContext.h"
2181ad6265SDimitry Andric #include "llvm/Support/raw_ostream.h"
2281ad6265SDimitry Andric 
2381ad6265SDimitry Andric using namespace llvm;
2481ad6265SDimitry Andric 
25*753f127fSDimitry Andric static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym,
26*753f127fSDimitry Andric                                     const AsmPrinter &AP) {
27*753f127fSDimitry Andric   MCContext &Ctx = AP.OutContext;
28*753f127fSDimitry Andric 
29*753f127fSDimitry Andric   // TODO: Processing target flags.
30*753f127fSDimitry Andric 
31*753f127fSDimitry Andric   const MCExpr *ME =
32*753f127fSDimitry Andric       MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx);
33*753f127fSDimitry Andric 
34*753f127fSDimitry Andric   if (!MO.isJTI() && !MO.isMBB() && MO.getOffset())
35*753f127fSDimitry Andric     ME = MCBinaryExpr::createAdd(
36*753f127fSDimitry Andric         ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
37*753f127fSDimitry Andric 
38*753f127fSDimitry Andric   return MCOperand::createExpr(ME);
39*753f127fSDimitry Andric }
40*753f127fSDimitry Andric 
4181ad6265SDimitry Andric bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO,
4281ad6265SDimitry Andric                                                    MCOperand &MCOp,
4381ad6265SDimitry Andric                                                    const AsmPrinter &AP) {
4481ad6265SDimitry Andric   switch (MO.getType()) {
4581ad6265SDimitry Andric   default:
4681ad6265SDimitry Andric     report_fatal_error(
4781ad6265SDimitry Andric         "lowerLoongArchMachineOperandToMCOperand: unknown operand type");
4881ad6265SDimitry Andric   case MachineOperand::MO_Register:
4981ad6265SDimitry Andric     // Ignore all implicit register operands.
5081ad6265SDimitry Andric     if (MO.isImplicit())
5181ad6265SDimitry Andric       return false;
5281ad6265SDimitry Andric     MCOp = MCOperand::createReg(MO.getReg());
5381ad6265SDimitry Andric     break;
5481ad6265SDimitry Andric   case MachineOperand::MO_RegisterMask:
5581ad6265SDimitry Andric     // Regmasks are like implicit defs.
5681ad6265SDimitry Andric     return false;
5781ad6265SDimitry Andric   case MachineOperand::MO_Immediate:
5881ad6265SDimitry Andric     MCOp = MCOperand::createImm(MO.getImm());
5981ad6265SDimitry Andric     break;
6081ad6265SDimitry Andric   case MachineOperand::MO_ConstantPoolIndex:
61*753f127fSDimitry Andric     MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP);
62*753f127fSDimitry Andric     break;
63*753f127fSDimitry Andric   case MachineOperand::MO_GlobalAddress:
64*753f127fSDimitry Andric     MCOp = lowerSymbolOperand(MO, AP.getSymbolPreferLocal(*MO.getGlobal()), AP);
65*753f127fSDimitry Andric     break;
66*753f127fSDimitry Andric   case MachineOperand::MO_MachineBasicBlock:
67*753f127fSDimitry Andric     MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), AP);
68*753f127fSDimitry Andric     break;
69*753f127fSDimitry Andric   case MachineOperand::MO_ExternalSymbol:
70*753f127fSDimitry Andric     MCOp = lowerSymbolOperand(
71*753f127fSDimitry Andric         MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP);
72*753f127fSDimitry Andric     break;
73*753f127fSDimitry Andric   // TODO: lower special operands
74*753f127fSDimitry Andric   case MachineOperand::MO_BlockAddress:
7581ad6265SDimitry Andric   case MachineOperand::MO_JumpTableIndex:
7681ad6265SDimitry Andric     break;
7781ad6265SDimitry Andric   }
7881ad6265SDimitry Andric   return true;
7981ad6265SDimitry Andric }
8081ad6265SDimitry Andric 
8181ad6265SDimitry Andric bool llvm::lowerLoongArchMachineInstrToMCInst(const MachineInstr *MI,
8281ad6265SDimitry Andric                                               MCInst &OutMI, AsmPrinter &AP) {
8381ad6265SDimitry Andric   OutMI.setOpcode(MI->getOpcode());
8481ad6265SDimitry Andric 
8581ad6265SDimitry Andric   for (const MachineOperand &MO : MI->operands()) {
8681ad6265SDimitry Andric     MCOperand MCOp;
8781ad6265SDimitry Andric     if (lowerLoongArchMachineOperandToMCOperand(MO, MCOp, AP))
8881ad6265SDimitry Andric       OutMI.addOperand(MCOp);
8981ad6265SDimitry Andric   }
9081ad6265SDimitry Andric   return false;
9181ad6265SDimitry Andric }
92