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