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 "MCTargetDesc/LoongArchBaseInfo.h" 17 #include "MCTargetDesc/LoongArchMCExpr.h" 18 #include "llvm/CodeGen/AsmPrinter.h" 19 #include "llvm/CodeGen/MachineBasicBlock.h" 20 #include "llvm/CodeGen/MachineInstr.h" 21 #include "llvm/MC/MCAsmInfo.h" 22 #include "llvm/MC/MCContext.h" 23 #include "llvm/Support/raw_ostream.h" 24 25 using namespace llvm; 26 27 static MCOperand lowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym, 28 const AsmPrinter &AP) { 29 MCContext &Ctx = AP.OutContext; 30 LoongArchMCExpr::VariantKind Kind; 31 32 switch (MO.getTargetFlags()) { 33 default: 34 llvm_unreachable("Unknown target flag on GV operand"); 35 case LoongArchII::MO_None: 36 Kind = LoongArchMCExpr::VK_LoongArch_None; 37 break; 38 case LoongArchII::MO_CALL: 39 Kind = LoongArchMCExpr::VK_LoongArch_CALL; 40 break; 41 case LoongArchII::MO_CALL_PLT: 42 Kind = LoongArchMCExpr::VK_LoongArch_CALL_PLT; 43 break; 44 case LoongArchII::MO_PCREL_HI: 45 Kind = LoongArchMCExpr::VK_LoongArch_PCALA_HI20; 46 break; 47 case LoongArchII::MO_PCREL_LO: 48 Kind = LoongArchMCExpr::VK_LoongArch_PCALA_LO12; 49 break; 50 case LoongArchII::MO_PCREL64_LO: 51 Kind = LoongArchMCExpr::VK_LoongArch_PCALA64_LO20; 52 break; 53 case LoongArchII::MO_PCREL64_HI: 54 Kind = LoongArchMCExpr::VK_LoongArch_PCALA64_HI12; 55 break; 56 case LoongArchII::MO_GOT_PC_HI: 57 Kind = LoongArchMCExpr::VK_LoongArch_GOT_PC_HI20; 58 break; 59 case LoongArchII::MO_GOT_PC_LO: 60 Kind = LoongArchMCExpr::VK_LoongArch_GOT_PC_LO12; 61 break; 62 case LoongArchII::MO_GOT_PC64_LO: 63 Kind = LoongArchMCExpr::VK_LoongArch_GOT64_PC_LO20; 64 break; 65 case LoongArchII::MO_GOT_PC64_HI: 66 Kind = LoongArchMCExpr::VK_LoongArch_GOT64_PC_HI12; 67 break; 68 case LoongArchII::MO_LE_HI: 69 Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE_HI20; 70 break; 71 case LoongArchII::MO_LE_LO: 72 Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE_LO12; 73 break; 74 case LoongArchII::MO_LE64_LO: 75 Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE64_LO20; 76 break; 77 case LoongArchII::MO_LE64_HI: 78 Kind = LoongArchMCExpr::VK_LoongArch_TLS_LE64_HI12; 79 break; 80 case LoongArchII::MO_IE_PC_HI: 81 Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_HI20; 82 break; 83 case LoongArchII::MO_IE_PC_LO: 84 Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE_PC_LO12; 85 break; 86 case LoongArchII::MO_IE_PC64_LO: 87 Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_LO20; 88 break; 89 case LoongArchII::MO_IE_PC64_HI: 90 Kind = LoongArchMCExpr::VK_LoongArch_TLS_IE64_PC_HI12; 91 break; 92 case LoongArchII::MO_LD_PC_HI: 93 Kind = LoongArchMCExpr::VK_LoongArch_TLS_LD_PC_HI20; 94 break; 95 case LoongArchII::MO_GD_PC_HI: 96 Kind = LoongArchMCExpr::VK_LoongArch_TLS_GD_PC_HI20; 97 break; 98 case LoongArchII::MO_CALL36: 99 Kind = LoongArchMCExpr::VK_LoongArch_CALL36; 100 break; 101 case LoongArchII::MO_DESC_PC_HI: 102 Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_PC_HI20; 103 break; 104 case LoongArchII::MO_DESC_PC_LO: 105 Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_PC_LO12; 106 break; 107 case LoongArchII::MO_DESC64_PC_LO: 108 Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC64_PC_LO20; 109 break; 110 case LoongArchII::MO_DESC64_PC_HI: 111 Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC64_PC_HI12; 112 break; 113 case LoongArchII::MO_DESC_LD: 114 Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_LD; 115 break; 116 case LoongArchII::MO_DESC_CALL: 117 Kind = LoongArchMCExpr::VK_LoongArch_TLS_DESC_CALL; 118 break; 119 // TODO: Handle more target-flags. 120 } 121 122 const MCExpr *ME = 123 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, Ctx); 124 125 if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) 126 ME = MCBinaryExpr::createAdd( 127 ME, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx); 128 129 if (Kind != LoongArchMCExpr::VK_LoongArch_None) 130 ME = LoongArchMCExpr::create(ME, Kind, Ctx); 131 return MCOperand::createExpr(ME); 132 } 133 134 bool llvm::lowerLoongArchMachineOperandToMCOperand(const MachineOperand &MO, 135 MCOperand &MCOp, 136 const AsmPrinter &AP) { 137 switch (MO.getType()) { 138 default: 139 report_fatal_error( 140 "lowerLoongArchMachineOperandToMCOperand: unknown operand type"); 141 case MachineOperand::MO_Register: 142 // Ignore all implicit register operands. 143 if (MO.isImplicit()) 144 return false; 145 MCOp = MCOperand::createReg(MO.getReg()); 146 break; 147 case MachineOperand::MO_RegisterMask: 148 // Regmasks are like implicit defs. 149 return false; 150 case MachineOperand::MO_Immediate: 151 MCOp = MCOperand::createImm(MO.getImm()); 152 break; 153 case MachineOperand::MO_ConstantPoolIndex: 154 MCOp = lowerSymbolOperand(MO, AP.GetCPISymbol(MO.getIndex()), AP); 155 break; 156 case MachineOperand::MO_GlobalAddress: 157 MCOp = lowerSymbolOperand(MO, AP.getSymbolPreferLocal(*MO.getGlobal()), AP); 158 break; 159 case MachineOperand::MO_MachineBasicBlock: 160 MCOp = lowerSymbolOperand(MO, MO.getMBB()->getSymbol(), AP); 161 break; 162 case MachineOperand::MO_ExternalSymbol: 163 MCOp = lowerSymbolOperand( 164 MO, AP.GetExternalSymbolSymbol(MO.getSymbolName()), AP); 165 break; 166 case MachineOperand::MO_BlockAddress: 167 MCOp = lowerSymbolOperand( 168 MO, AP.GetBlockAddressSymbol(MO.getBlockAddress()), AP); 169 break; 170 case MachineOperand::MO_JumpTableIndex: 171 MCOp = lowerSymbolOperand(MO, AP.GetJTISymbol(MO.getIndex()), AP); 172 break; 173 } 174 return true; 175 } 176 177 bool llvm::lowerLoongArchMachineInstrToMCInst(const MachineInstr *MI, 178 MCInst &OutMI, AsmPrinter &AP) { 179 OutMI.setOpcode(MI->getOpcode()); 180 181 for (const MachineOperand &MO : MI->operands()) { 182 MCOperand MCOp; 183 if (lowerLoongArchMachineOperandToMCOperand(MO, MCOp, AP)) 184 OutMI.addOperand(MCOp); 185 } 186 return false; 187 } 188