1 //===-- LoongArchExpandPseudoInsts.cpp - Expand pseudo instructions -------===// 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 a pass that expands pseudo instructions into target 10 // instructions. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "LoongArch.h" 15 #include "LoongArchInstrInfo.h" 16 #include "LoongArchTargetMachine.h" 17 #include "MCTargetDesc/LoongArchBaseInfo.h" 18 #include "MCTargetDesc/LoongArchMCTargetDesc.h" 19 #include "llvm/CodeGen/LivePhysRegs.h" 20 #include "llvm/CodeGen/MachineFunctionPass.h" 21 #include "llvm/CodeGen/MachineInstrBuilder.h" 22 #include "llvm/CodeGen/MachineOperand.h" 23 #include "llvm/CodeGen/Register.h" 24 #include "llvm/MC/MCContext.h" 25 #include "llvm/Support/CodeGen.h" 26 #include "llvm/Support/ErrorHandling.h" 27 28 using namespace llvm; 29 30 #define LOONGARCH_PRERA_EXPAND_PSEUDO_NAME \ 31 "LoongArch Pre-RA pseudo instruction expansion pass" 32 33 namespace { 34 35 class LoongArchPreRAExpandPseudo : public MachineFunctionPass { 36 public: 37 const LoongArchInstrInfo *TII; 38 static char ID; 39 40 LoongArchPreRAExpandPseudo() : MachineFunctionPass(ID) { 41 initializeLoongArchPreRAExpandPseudoPass(*PassRegistry::getPassRegistry()); 42 } 43 44 bool runOnMachineFunction(MachineFunction &MF) override; 45 46 void getAnalysisUsage(AnalysisUsage &AU) const override { 47 AU.setPreservesCFG(); 48 MachineFunctionPass::getAnalysisUsage(AU); 49 } 50 StringRef getPassName() const override { 51 return LOONGARCH_PRERA_EXPAND_PSEUDO_NAME; 52 } 53 54 private: 55 bool expandMBB(MachineBasicBlock &MBB); 56 bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 57 MachineBasicBlock::iterator &NextMBBI); 58 bool expandPcalau12iInstPair(MachineBasicBlock &MBB, 59 MachineBasicBlock::iterator MBBI, 60 MachineBasicBlock::iterator &NextMBBI, 61 unsigned FlagsHi, unsigned SecondOpcode, 62 unsigned FlagsLo); 63 bool expandLargeAddressLoad(MachineBasicBlock &MBB, 64 MachineBasicBlock::iterator MBBI, 65 MachineBasicBlock::iterator &NextMBBI, 66 unsigned LastOpcode, unsigned IdentifyingMO); 67 bool expandLargeAddressLoad(MachineBasicBlock &MBB, 68 MachineBasicBlock::iterator MBBI, 69 MachineBasicBlock::iterator &NextMBBI, 70 unsigned LastOpcode, unsigned IdentifyingMO, 71 const MachineOperand &Symbol, Register DestReg, 72 bool EraseFromParent); 73 bool expandLoadAddressPcrel(MachineBasicBlock &MBB, 74 MachineBasicBlock::iterator MBBI, 75 MachineBasicBlock::iterator &NextMBBI, 76 bool Large = false); 77 bool expandLoadAddressGot(MachineBasicBlock &MBB, 78 MachineBasicBlock::iterator MBBI, 79 MachineBasicBlock::iterator &NextMBBI, 80 bool Large = false); 81 bool expandLoadAddressTLSLE(MachineBasicBlock &MBB, 82 MachineBasicBlock::iterator MBBI, 83 MachineBasicBlock::iterator &NextMBBI); 84 bool expandLoadAddressTLSIE(MachineBasicBlock &MBB, 85 MachineBasicBlock::iterator MBBI, 86 MachineBasicBlock::iterator &NextMBBI, 87 bool Large = false); 88 bool expandLoadAddressTLSLD(MachineBasicBlock &MBB, 89 MachineBasicBlock::iterator MBBI, 90 MachineBasicBlock::iterator &NextMBBI, 91 bool Large = false); 92 bool expandLoadAddressTLSGD(MachineBasicBlock &MBB, 93 MachineBasicBlock::iterator MBBI, 94 MachineBasicBlock::iterator &NextMBBI, 95 bool Large = false); 96 bool expandFunctionCALL(MachineBasicBlock &MBB, 97 MachineBasicBlock::iterator MBBI, 98 MachineBasicBlock::iterator &NextMBBI, 99 bool IsTailCall); 100 }; 101 102 char LoongArchPreRAExpandPseudo::ID = 0; 103 104 bool LoongArchPreRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 105 TII = 106 static_cast<const LoongArchInstrInfo *>(MF.getSubtarget().getInstrInfo()); 107 bool Modified = false; 108 for (auto &MBB : MF) 109 Modified |= expandMBB(MBB); 110 return Modified; 111 } 112 113 bool LoongArchPreRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) { 114 bool Modified = false; 115 116 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 117 while (MBBI != E) { 118 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 119 Modified |= expandMI(MBB, MBBI, NMBBI); 120 MBBI = NMBBI; 121 } 122 123 return Modified; 124 } 125 126 bool LoongArchPreRAExpandPseudo::expandMI( 127 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 128 MachineBasicBlock::iterator &NextMBBI) { 129 switch (MBBI->getOpcode()) { 130 case LoongArch::PseudoLA_PCREL: 131 return expandLoadAddressPcrel(MBB, MBBI, NextMBBI); 132 case LoongArch::PseudoLA_PCREL_LARGE: 133 return expandLoadAddressPcrel(MBB, MBBI, NextMBBI, /*Large=*/true); 134 case LoongArch::PseudoLA_GOT: 135 return expandLoadAddressGot(MBB, MBBI, NextMBBI); 136 case LoongArch::PseudoLA_GOT_LARGE: 137 return expandLoadAddressGot(MBB, MBBI, NextMBBI, /*Large=*/true); 138 case LoongArch::PseudoLA_TLS_LE: 139 return expandLoadAddressTLSLE(MBB, MBBI, NextMBBI); 140 case LoongArch::PseudoLA_TLS_IE: 141 return expandLoadAddressTLSIE(MBB, MBBI, NextMBBI); 142 case LoongArch::PseudoLA_TLS_IE_LARGE: 143 return expandLoadAddressTLSIE(MBB, MBBI, NextMBBI, /*Large=*/true); 144 case LoongArch::PseudoLA_TLS_LD: 145 return expandLoadAddressTLSLD(MBB, MBBI, NextMBBI); 146 case LoongArch::PseudoLA_TLS_LD_LARGE: 147 return expandLoadAddressTLSLD(MBB, MBBI, NextMBBI, /*Large=*/true); 148 case LoongArch::PseudoLA_TLS_GD: 149 return expandLoadAddressTLSGD(MBB, MBBI, NextMBBI); 150 case LoongArch::PseudoLA_TLS_GD_LARGE: 151 return expandLoadAddressTLSGD(MBB, MBBI, NextMBBI, /*Large=*/true); 152 case LoongArch::PseudoCALL: 153 return expandFunctionCALL(MBB, MBBI, NextMBBI, /*IsTailCall=*/false); 154 case LoongArch::PseudoTAIL: 155 return expandFunctionCALL(MBB, MBBI, NextMBBI, /*IsTailCall=*/true); 156 } 157 return false; 158 } 159 160 bool LoongArchPreRAExpandPseudo::expandPcalau12iInstPair( 161 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 162 MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi, 163 unsigned SecondOpcode, unsigned FlagsLo) { 164 MachineFunction *MF = MBB.getParent(); 165 MachineInstr &MI = *MBBI; 166 DebugLoc DL = MI.getDebugLoc(); 167 168 Register DestReg = MI.getOperand(0).getReg(); 169 Register ScratchReg = 170 MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass); 171 MachineOperand &Symbol = MI.getOperand(1); 172 173 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), ScratchReg) 174 .addDisp(Symbol, 0, FlagsHi); 175 176 MachineInstr *SecondMI = 177 BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg) 178 .addReg(ScratchReg) 179 .addDisp(Symbol, 0, FlagsLo); 180 181 if (MI.hasOneMemOperand()) 182 SecondMI->addMemOperand(*MF, *MI.memoperands_begin()); 183 184 MI.eraseFromParent(); 185 return true; 186 } 187 188 bool LoongArchPreRAExpandPseudo::expandLargeAddressLoad( 189 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 190 MachineBasicBlock::iterator &NextMBBI, unsigned LastOpcode, 191 unsigned IdentifyingMO) { 192 MachineInstr &MI = *MBBI; 193 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LastOpcode, IdentifyingMO, 194 MI.getOperand(2), MI.getOperand(0).getReg(), 195 true); 196 } 197 198 bool LoongArchPreRAExpandPseudo::expandLargeAddressLoad( 199 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 200 MachineBasicBlock::iterator &NextMBBI, unsigned LastOpcode, 201 unsigned IdentifyingMO, const MachineOperand &Symbol, Register DestReg, 202 bool EraseFromParent) { 203 // Code Sequence: 204 // 205 // Part1: pcalau12i $scratch, %MO1(sym) 206 // Part0: addi.d $dest, $zero, %MO0(sym) 207 // Part2: lu32i.d $dest, %MO2(sym) 208 // Part3: lu52i.d $dest, $dest, %MO3(sym) 209 // Fin: LastOpcode $dest, $dest, $scratch 210 211 unsigned MO0, MO1, MO2, MO3; 212 switch (IdentifyingMO) { 213 default: 214 llvm_unreachable("unsupported identifying MO"); 215 case LoongArchII::MO_PCREL_LO: 216 MO0 = IdentifyingMO; 217 MO1 = LoongArchII::MO_PCREL_HI; 218 MO2 = LoongArchII::MO_PCREL64_LO; 219 MO3 = LoongArchII::MO_PCREL64_HI; 220 break; 221 case LoongArchII::MO_GOT_PC_HI: 222 case LoongArchII::MO_LD_PC_HI: 223 case LoongArchII::MO_GD_PC_HI: 224 // These cases relocate just like the GOT case, except for Part1. 225 MO0 = LoongArchII::MO_GOT_PC_LO; 226 MO1 = IdentifyingMO; 227 MO2 = LoongArchII::MO_GOT_PC64_LO; 228 MO3 = LoongArchII::MO_GOT_PC64_HI; 229 break; 230 case LoongArchII::MO_IE_PC_LO: 231 MO0 = IdentifyingMO; 232 MO1 = LoongArchII::MO_IE_PC_HI; 233 MO2 = LoongArchII::MO_IE_PC64_LO; 234 MO3 = LoongArchII::MO_IE_PC64_HI; 235 break; 236 } 237 238 MachineFunction *MF = MBB.getParent(); 239 MachineInstr &MI = *MBBI; 240 DebugLoc DL = MI.getDebugLoc(); 241 242 assert(MF->getSubtarget<LoongArchSubtarget>().is64Bit() && 243 "Large code model requires LA64"); 244 245 Register TmpPart1 = 246 MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass); 247 Register TmpPart0 = 248 DestReg.isVirtual() 249 ? MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass) 250 : DestReg; 251 Register TmpParts02 = 252 DestReg.isVirtual() 253 ? MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass) 254 : DestReg; 255 Register TmpParts023 = 256 DestReg.isVirtual() 257 ? MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass) 258 : DestReg; 259 260 auto Part1 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), TmpPart1); 261 auto Part0 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::ADDI_D), TmpPart0) 262 .addReg(LoongArch::R0); 263 auto Part2 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU32I_D), TmpParts02) 264 // "rj" is needed due to InstrInfo pattern requirement. 265 .addReg(TmpPart0, RegState::Kill); 266 auto Part3 = BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU52I_D), TmpParts023) 267 .addReg(TmpParts02, RegState::Kill); 268 BuildMI(MBB, MBBI, DL, TII->get(LastOpcode), DestReg) 269 .addReg(TmpParts023) 270 .addReg(TmpPart1, RegState::Kill); 271 272 if (Symbol.getType() == MachineOperand::MO_ExternalSymbol) { 273 const char *SymName = Symbol.getSymbolName(); 274 Part0.addExternalSymbol(SymName, MO0); 275 Part1.addExternalSymbol(SymName, MO1); 276 Part2.addExternalSymbol(SymName, MO2); 277 Part3.addExternalSymbol(SymName, MO3); 278 } else { 279 Part0.addDisp(Symbol, 0, MO0); 280 Part1.addDisp(Symbol, 0, MO1); 281 Part2.addDisp(Symbol, 0, MO2); 282 Part3.addDisp(Symbol, 0, MO3); 283 } 284 285 if (EraseFromParent) 286 MI.eraseFromParent(); 287 288 return true; 289 } 290 291 bool LoongArchPreRAExpandPseudo::expandLoadAddressPcrel( 292 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 293 MachineBasicBlock::iterator &NextMBBI, bool Large) { 294 if (Large) 295 // Emit the 5-insn large address load sequence with the `%pc` family of 296 // relocs. 297 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::ADD_D, 298 LoongArchII::MO_PCREL_LO); 299 300 // Code Sequence: 301 // pcalau12i $rd, %pc_hi20(sym) 302 // addi.w/d $rd, $rd, %pc_lo12(sym) 303 MachineFunction *MF = MBB.getParent(); 304 const auto &STI = MF->getSubtarget<LoongArchSubtarget>(); 305 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; 306 return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_PCREL_HI, 307 SecondOpcode, LoongArchII::MO_PCREL_LO); 308 } 309 310 bool LoongArchPreRAExpandPseudo::expandLoadAddressGot( 311 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 312 MachineBasicBlock::iterator &NextMBBI, bool Large) { 313 if (Large) 314 // Emit the 5-insn large address load sequence with the `%got_pc` family 315 // of relocs, loading the result from GOT with `ldx.d` in the end. 316 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::LDX_D, 317 LoongArchII::MO_GOT_PC_HI); 318 319 // Code Sequence: 320 // pcalau12i $rd, %got_pc_hi20(sym) 321 // ld.w/d $rd, $rd, %got_pc_lo12(sym) 322 MachineFunction *MF = MBB.getParent(); 323 const auto &STI = MF->getSubtarget<LoongArchSubtarget>(); 324 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W; 325 return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_GOT_PC_HI, 326 SecondOpcode, LoongArchII::MO_GOT_PC_LO); 327 } 328 329 bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLE( 330 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 331 MachineBasicBlock::iterator &NextMBBI) { 332 // Code Sequence: 333 // lu12i.w $rd, %le_hi20(sym) 334 // ori $rd, $rd, %le_lo12(sym) 335 // 336 // And additionally if generating code using the large code model: 337 // 338 // lu32i.d $rd, %le64_lo20(sym) 339 // lu52i.d $rd, $rd, %le64_hi12(sym) 340 MachineFunction *MF = MBB.getParent(); 341 MachineInstr &MI = *MBBI; 342 DebugLoc DL = MI.getDebugLoc(); 343 344 bool Large = MF->getTarget().getCodeModel() == CodeModel::Large; 345 Register DestReg = MI.getOperand(0).getReg(); 346 Register Parts01 = 347 Large ? MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass) 348 : DestReg; 349 Register Part1 = 350 MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass); 351 MachineOperand &Symbol = MI.getOperand(1); 352 353 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU12I_W), Part1) 354 .addDisp(Symbol, 0, LoongArchII::MO_LE_HI); 355 356 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::ORI), Parts01) 357 .addReg(Part1, RegState::Kill) 358 .addDisp(Symbol, 0, LoongArchII::MO_LE_LO); 359 360 if (Large) { 361 Register Parts012 = 362 MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass); 363 364 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU32I_D), Parts012) 365 // "rj" is needed due to InstrInfo pattern requirement. 366 .addReg(Parts01, RegState::Kill) 367 .addDisp(Symbol, 0, LoongArchII::MO_LE64_LO); 368 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::LU52I_D), DestReg) 369 .addReg(Parts012, RegState::Kill) 370 .addDisp(Symbol, 0, LoongArchII::MO_LE64_HI); 371 } 372 373 MI.eraseFromParent(); 374 return true; 375 } 376 377 bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSIE( 378 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 379 MachineBasicBlock::iterator &NextMBBI, bool Large) { 380 if (Large) 381 // Emit the 5-insn large address load sequence with the `%ie_pc` family 382 // of relocs, loading the result with `ldx.d` in the end. 383 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::LDX_D, 384 LoongArchII::MO_IE_PC_LO); 385 386 // Code Sequence: 387 // pcalau12i $rd, %ie_pc_hi20(sym) 388 // ld.w/d $rd, $rd, %ie_pc_lo12(sym) 389 MachineFunction *MF = MBB.getParent(); 390 const auto &STI = MF->getSubtarget<LoongArchSubtarget>(); 391 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::LD_D : LoongArch::LD_W; 392 return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_IE_PC_HI, 393 SecondOpcode, LoongArchII::MO_IE_PC_LO); 394 } 395 396 bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSLD( 397 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 398 MachineBasicBlock::iterator &NextMBBI, bool Large) { 399 if (Large) 400 // Emit the 5-insn large address load sequence with the `%got_pc` family 401 // of relocs, with the `pcalau12i` insn relocated with `%ld_pc_hi20`. 402 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::ADD_D, 403 LoongArchII::MO_LD_PC_HI); 404 405 // Code Sequence: 406 // pcalau12i $rd, %ld_pc_hi20(sym) 407 // addi.w/d $rd, $rd, %got_pc_lo12(sym) 408 MachineFunction *MF = MBB.getParent(); 409 const auto &STI = MF->getSubtarget<LoongArchSubtarget>(); 410 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; 411 return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_LD_PC_HI, 412 SecondOpcode, LoongArchII::MO_GOT_PC_LO); 413 } 414 415 bool LoongArchPreRAExpandPseudo::expandLoadAddressTLSGD( 416 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 417 MachineBasicBlock::iterator &NextMBBI, bool Large) { 418 if (Large) 419 // Emit the 5-insn large address load sequence with the `%got_pc` family 420 // of relocs, with the `pcalau12i` insn relocated with `%gd_pc_hi20`. 421 return expandLargeAddressLoad(MBB, MBBI, NextMBBI, LoongArch::ADD_D, 422 LoongArchII::MO_GD_PC_HI); 423 424 // Code Sequence: 425 // pcalau12i $rd, %gd_pc_hi20(sym) 426 // addi.w/d $rd, $rd, %got_pc_lo12(sym) 427 MachineFunction *MF = MBB.getParent(); 428 const auto &STI = MF->getSubtarget<LoongArchSubtarget>(); 429 unsigned SecondOpcode = STI.is64Bit() ? LoongArch::ADDI_D : LoongArch::ADDI_W; 430 return expandPcalau12iInstPair(MBB, MBBI, NextMBBI, LoongArchII::MO_GD_PC_HI, 431 SecondOpcode, LoongArchII::MO_GOT_PC_LO); 432 } 433 434 bool LoongArchPreRAExpandPseudo::expandFunctionCALL( 435 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 436 MachineBasicBlock::iterator &NextMBBI, bool IsTailCall) { 437 MachineFunction *MF = MBB.getParent(); 438 MachineInstr &MI = *MBBI; 439 DebugLoc DL = MI.getDebugLoc(); 440 const MachineOperand &Func = MI.getOperand(0); 441 MachineInstrBuilder CALL; 442 unsigned Opcode; 443 444 switch (MF->getTarget().getCodeModel()) { 445 default: 446 report_fatal_error("Unsupported code model"); 447 break; 448 case CodeModel::Small: { 449 // CALL: 450 // bl func 451 // TAIL: 452 // b func 453 Opcode = IsTailCall ? LoongArch::PseudoB_TAIL : LoongArch::BL; 454 CALL = BuildMI(MBB, MBBI, DL, TII->get(Opcode)).add(Func); 455 break; 456 } 457 case CodeModel::Medium: { 458 // CALL: 459 // pcalau12i $ra, %pc_hi20(func) 460 // jirl $ra, $ra, %pc_lo12(func) 461 // TAIL: 462 // pcalau12i $scratch, %pc_hi20(func) 463 // jirl $r0, $scratch, %pc_lo12(func) 464 Opcode = 465 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL; 466 Register ScratchReg = 467 IsTailCall 468 ? MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass) 469 : LoongArch::R1; 470 MachineInstrBuilder MIB = 471 BuildMI(MBB, MBBI, DL, TII->get(LoongArch::PCALAU12I), ScratchReg); 472 CALL = BuildMI(MBB, MBBI, DL, TII->get(Opcode)).addReg(ScratchReg); 473 if (Func.isSymbol()) { 474 const char *FnName = Func.getSymbolName(); 475 MIB.addExternalSymbol(FnName, LoongArchII::MO_PCREL_HI); 476 CALL.addExternalSymbol(FnName, LoongArchII::MO_PCREL_LO); 477 break; 478 } 479 assert(Func.isGlobal() && "Expected a GlobalValue at this time"); 480 const GlobalValue *GV = Func.getGlobal(); 481 MIB.addGlobalAddress(GV, 0, LoongArchII::MO_PCREL_HI); 482 CALL.addGlobalAddress(GV, 0, LoongArchII::MO_PCREL_LO); 483 break; 484 } 485 case CodeModel::Large: { 486 // Emit the 5-insn large address load sequence, either directly or 487 // indirectly in case of going through the GOT, then JIRL_TAIL or 488 // JIRL_CALL to $addr. 489 Opcode = 490 IsTailCall ? LoongArch::PseudoJIRL_TAIL : LoongArch::PseudoJIRL_CALL; 491 Register AddrReg = 492 IsTailCall 493 ? MF->getRegInfo().createVirtualRegister(&LoongArch::GPRRegClass) 494 : LoongArch::R1; 495 496 bool UseGOT = Func.isGlobal() && !Func.getGlobal()->isDSOLocal(); 497 unsigned MO = UseGOT ? LoongArchII::MO_GOT_PC_HI : LoongArchII::MO_PCREL_LO; 498 unsigned LAOpcode = UseGOT ? LoongArch::LDX_D : LoongArch::ADD_D; 499 expandLargeAddressLoad(MBB, MBBI, NextMBBI, LAOpcode, MO, Func, AddrReg, 500 false); 501 CALL = BuildMI(MBB, MBBI, DL, TII->get(Opcode)).addReg(AddrReg).addImm(0); 502 break; 503 } 504 } 505 506 // Transfer implicit operands. 507 CALL.copyImplicitOps(MI); 508 509 // Transfer MI flags. 510 CALL.setMIFlags(MI.getFlags()); 511 512 MI.eraseFromParent(); 513 return true; 514 } 515 516 } // end namespace 517 518 INITIALIZE_PASS(LoongArchPreRAExpandPseudo, "loongarch-prera-expand-pseudo", 519 LOONGARCH_PRERA_EXPAND_PSEUDO_NAME, false, false) 520 521 namespace llvm { 522 523 FunctionPass *createLoongArchPreRAExpandPseudoPass() { 524 return new LoongArchPreRAExpandPseudo(); 525 } 526 527 } // end namespace llvm 528