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; 981db9f3b2SDimitry Andric case LoongArchII::MO_CALL36: 991db9f3b2SDimitry Andric Kind = LoongArchMCExpr::VK_LoongArch_CALL36; 1001db9f3b2SDimitry Andric break; 101*0fca6ea1SDimitry Andric case LoongArchII::MO_DESC_PC_HI: 102*0fca6ea1SDimitry Andric Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_PC_HI20; 103*0fca6ea1SDimitry Andric break; 104*0fca6ea1SDimitry Andric case LoongArchII::MO_DESC_PC_LO: 105*0fca6ea1SDimitry Andric Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_PC_LO12; 106*0fca6ea1SDimitry Andric break; 107*0fca6ea1SDimitry Andric case LoongArchII::MO_DESC64_PC_LO: 108*0fca6ea1SDimitry Andric Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC64_PC_LO20; 109*0fca6ea1SDimitry Andric break; 110*0fca6ea1SDimitry Andric case LoongArchII::MO_DESC64_PC_HI: 111*0fca6ea1SDimitry Andric Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC64_PC_HI12; 112*0fca6ea1SDimitry Andric break; 113*0fca6ea1SDimitry Andric case LoongArchII::MO_DESC_LD: 114*0fca6ea1SDimitry Andric Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_LD; 115*0fca6ea1SDimitry Andric break; 116*0fca6ea1SDimitry Andric case LoongArchII::MO_DESC_CALL: 117*0fca6ea1SDimitry Andric Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_CALL; 118*0fca6ea1SDimitry Andric break; 119bdd1243dSDimitry Andric // TODO: Handle more target-flags. 120bdd1243dSDimitry Andric } 121753f127fSDimitry Andric 122753f127fSDimitry Andric const MCExpr *ME = 123753f127fSDimitry Andric MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); 124753f127fSDimitry Andric 125753f127fSDimitry Andric if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) 126753f127fSDimitry Andric ME = MCBinaryExpr::createAdd( 127753f127fSDimitry Andric ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); 128753f127fSDimitry Andric 129bdd1243dSDimitry Andric if (Kind != LoongArchMCExpr::VK_LoongArch_None) 130bdd1243dSDimitry Andric ME = LoongArchMCExpr::create(ME, Kind, Ctx); 131753f127fSDimitry Andric return MCOperand::createExpr(ME); 132753f127fSDimitry Andric } 133753f127fSDimitry Andric 13481ad6265SDimitry Andric bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO, 13581ad6265SDimitry Andric MCOperand &MCOp, 13681ad6265SDimitry Andric const AsmPrinter &AP) { 13781ad6265SDimitry Andric switch (MO.getType()) { 13881ad6265SDimitry Andric default: 13981ad6265SDimitry Andric report_fatal_error( 14081ad6265SDimitry Andric "lowerLoongArchMachineOperandToMCOperand: unknown operand type"); 14181ad6265SDimitry Andric case MachineOperand::MO_Register: 14281ad6265SDimitry Andric // Ignore all implicit register operands. 14381ad6265SDimitry Andric if (MO.isImplicit()) 14481ad6265SDimitry Andric return false; 14581ad6265SDimitry Andric MCOp = MCOperand::createReg(MO.getReg()); 14681ad6265SDimitry Andric break; 14781ad6265SDimitry Andric case MachineOperand::MO_RegisterMask: 14881ad6265SDimitry Andric // Regmasks are like implicit defs. 14981ad6265SDimitry Andric return false; 15081ad6265SDimitry Andric case MachineOperand::MO_Immediate: 15181ad6265SDimitry Andric MCOp = MCOperand::createImm(MO.getImm()); 15281ad6265SDimitry Andric break; 15381ad6265SDimitry Andric case MachineOperand::MO_ConstantPoolIndex: 154753f127fSDimitry Andric MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP); 155753f127fSDimitry Andric break; 156753f127fSDimitry Andric case MachineOperand::MO_GlobalAddress: 157753f127fSDimitry Andric MCOp = lowerSymbolOperand(MO, AP.getSymbolPreferLocal(*MO.getGlobal()), AP); 158753f127fSDimitry Andric break; 159753f127fSDimitry Andric case MachineOperand::MO_MachineBasicBlock: 160753f127fSDimitry Andric MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), AP); 161753f127fSDimitry Andric break; 162753f127fSDimitry Andric case MachineOperand::MO_ExternalSymbol: 163753f127fSDimitry Andric MCOp = lowerSymbolOperand( 164753f127fSDimitry Andric MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP); 165753f127fSDimitry Andric break; 166753f127fSDimitry Andric case MachineOperand::MO_BlockAddress: 167bdd1243dSDimitry Andric MCOp = lowerSymbolOperand( 168bdd1243dSDimitry Andric MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP); 169bdd1243dSDimitry Andric break; 17081ad6265SDimitry Andric case MachineOperand::MO_JumpTableIndex: 171bdd1243dSDimitry Andric MCOp = lowerSymbolOperand(MO, AP.GetJTISymbol(MO.getIndex()), AP); 17281ad6265SDimitry Andric break; 17381ad6265SDimitry Andric } 17481ad6265SDimitry Andric return true; 17581ad6265SDimitry Andric } 17681ad6265SDimitry Andric 17781ad6265SDimitry Andric bool llvm::lowerLoongArchMachineInstrToMCInst(const MachineInstr *MI, 17881ad6265SDimitry Andric MCInst &OutMI, AsmPrinter &AP) { 17981ad6265SDimitry Andric OutMI.setOpcode(MI->getOpcode()); 18081ad6265SDimitry Andric 18181ad6265SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 18281ad6265SDimitry Andric MCOperand MCOp; 18381ad6265SDimitry Andric if (lowerLoongArchMachineOperandToMCOperand(MO, MCOp, AP)) 18481ad6265SDimitry Andric OutMI.addOperand(MCOp); 18581ad6265SDimitry Andric } 18681ad6265SDimitry Andric return false; 18781ad6265SDimitry Andric } 188