1 //===-- RISCVExpandPseudoInsts.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. This pass should be run after register allocation but before 11 // the post-regalloc scheduling pass. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "RISCV.h" 16 #include "RISCVInstrInfo.h" 17 #include "RISCVTargetMachine.h" 18 19 #include "llvm/CodeGen/LivePhysRegs.h" 20 #include "llvm/CodeGen/MachineFunctionPass.h" 21 #include "llvm/CodeGen/MachineInstrBuilder.h" 22 #include "llvm/MC/MCContext.h" 23 24 using namespace llvm; 25 26 #define RISCV_EXPAND_PSEUDO_NAME "RISC-V pseudo instruction expansion pass" 27 #define RISCV_PRERA_EXPAND_PSEUDO_NAME "RISC-V Pre-RA pseudo instruction expansion pass" 28 29 namespace { 30 31 class RISCVExpandPseudo : public MachineFunctionPass { 32 public: 33 const RISCVSubtarget *STI; 34 const RISCVInstrInfo *TII; 35 static char ID; 36 37 RISCVExpandPseudo() : MachineFunctionPass(ID) {} 38 39 bool runOnMachineFunction(MachineFunction &MF) override; 40 41 StringRef getPassName() const override { return RISCV_EXPAND_PSEUDO_NAME; } 42 43 private: 44 bool expandMBB(MachineBasicBlock &MBB); 45 bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 46 MachineBasicBlock::iterator &NextMBBI); 47 bool expandCCOp(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 48 MachineBasicBlock::iterator &NextMBBI); 49 bool expandVSetVL(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); 50 bool expandVMSET_VMCLR(MachineBasicBlock &MBB, 51 MachineBasicBlock::iterator MBBI, unsigned Opcode); 52 bool expandRV32ZdinxStore(MachineBasicBlock &MBB, 53 MachineBasicBlock::iterator MBBI); 54 bool expandRV32ZdinxLoad(MachineBasicBlock &MBB, 55 MachineBasicBlock::iterator MBBI); 56 #ifndef NDEBUG 57 unsigned getInstSizeInBytes(const MachineFunction &MF) const { 58 unsigned Size = 0; 59 for (auto &MBB : MF) 60 for (auto &MI : MBB) 61 Size += TII->getInstSizeInBytes(MI); 62 return Size; 63 } 64 #endif 65 }; 66 67 char RISCVExpandPseudo::ID = 0; 68 69 bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 70 STI = &MF.getSubtarget<RISCVSubtarget>(); 71 TII = STI->getInstrInfo(); 72 73 #ifndef NDEBUG 74 const unsigned OldSize = getInstSizeInBytes(MF); 75 #endif 76 77 bool Modified = false; 78 for (auto &MBB : MF) 79 Modified |= expandMBB(MBB); 80 81 #ifndef NDEBUG 82 const unsigned NewSize = getInstSizeInBytes(MF); 83 assert(OldSize >= NewSize); 84 #endif 85 return Modified; 86 } 87 88 bool RISCVExpandPseudo::expandMBB(MachineBasicBlock &MBB) { 89 bool Modified = false; 90 91 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 92 while (MBBI != E) { 93 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 94 Modified |= expandMI(MBB, MBBI, NMBBI); 95 MBBI = NMBBI; 96 } 97 98 return Modified; 99 } 100 101 bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB, 102 MachineBasicBlock::iterator MBBI, 103 MachineBasicBlock::iterator &NextMBBI) { 104 // RISCVInstrInfo::getInstSizeInBytes expects that the total size of the 105 // expanded instructions for each pseudo is correct in the Size field of the 106 // tablegen definition for the pseudo. 107 switch (MBBI->getOpcode()) { 108 case RISCV::PseudoRV32ZdinxSD: 109 return expandRV32ZdinxStore(MBB, MBBI); 110 case RISCV::PseudoRV32ZdinxLD: 111 return expandRV32ZdinxLoad(MBB, MBBI); 112 case RISCV::PseudoCCMOVGPRNoX0: 113 case RISCV::PseudoCCMOVGPR: 114 case RISCV::PseudoCCADD: 115 case RISCV::PseudoCCSUB: 116 case RISCV::PseudoCCAND: 117 case RISCV::PseudoCCOR: 118 case RISCV::PseudoCCXOR: 119 case RISCV::PseudoCCADDW: 120 case RISCV::PseudoCCSUBW: 121 case RISCV::PseudoCCSLL: 122 case RISCV::PseudoCCSRL: 123 case RISCV::PseudoCCSRA: 124 case RISCV::PseudoCCADDI: 125 case RISCV::PseudoCCSLLI: 126 case RISCV::PseudoCCSRLI: 127 case RISCV::PseudoCCSRAI: 128 case RISCV::PseudoCCANDI: 129 case RISCV::PseudoCCORI: 130 case RISCV::PseudoCCXORI: 131 case RISCV::PseudoCCSLLW: 132 case RISCV::PseudoCCSRLW: 133 case RISCV::PseudoCCSRAW: 134 case RISCV::PseudoCCADDIW: 135 case RISCV::PseudoCCSLLIW: 136 case RISCV::PseudoCCSRLIW: 137 case RISCV::PseudoCCSRAIW: 138 case RISCV::PseudoCCANDN: 139 case RISCV::PseudoCCORN: 140 case RISCV::PseudoCCXNOR: 141 return expandCCOp(MBB, MBBI, NextMBBI); 142 case RISCV::PseudoVSETVLI: 143 case RISCV::PseudoVSETVLIX0: 144 case RISCV::PseudoVSETIVLI: 145 return expandVSetVL(MBB, MBBI); 146 case RISCV::PseudoVMCLR_M_B1: 147 case RISCV::PseudoVMCLR_M_B2: 148 case RISCV::PseudoVMCLR_M_B4: 149 case RISCV::PseudoVMCLR_M_B8: 150 case RISCV::PseudoVMCLR_M_B16: 151 case RISCV::PseudoVMCLR_M_B32: 152 case RISCV::PseudoVMCLR_M_B64: 153 // vmclr.m vd => vmxor.mm vd, vd, vd 154 return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXOR_MM); 155 case RISCV::PseudoVMSET_M_B1: 156 case RISCV::PseudoVMSET_M_B2: 157 case RISCV::PseudoVMSET_M_B4: 158 case RISCV::PseudoVMSET_M_B8: 159 case RISCV::PseudoVMSET_M_B16: 160 case RISCV::PseudoVMSET_M_B32: 161 case RISCV::PseudoVMSET_M_B64: 162 // vmset.m vd => vmxnor.mm vd, vd, vd 163 return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXNOR_MM); 164 } 165 166 return false; 167 } 168 169 bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB, 170 MachineBasicBlock::iterator MBBI, 171 MachineBasicBlock::iterator &NextMBBI) { 172 173 MachineFunction *MF = MBB.getParent(); 174 MachineInstr &MI = *MBBI; 175 DebugLoc DL = MI.getDebugLoc(); 176 177 MachineBasicBlock *TrueBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); 178 MachineBasicBlock *MergeBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock()); 179 180 MF->insert(++MBB.getIterator(), TrueBB); 181 MF->insert(++TrueBB->getIterator(), MergeBB); 182 183 // We want to copy the "true" value when the condition is true which means 184 // we need to invert the branch condition to jump over TrueBB when the 185 // condition is false. 186 auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm()); 187 CC = RISCVCC::getOppositeBranchCondition(CC); 188 189 // Insert branch instruction. 190 BuildMI(MBB, MBBI, DL, TII->getBrCond(CC)) 191 .addReg(MI.getOperand(1).getReg()) 192 .addReg(MI.getOperand(2).getReg()) 193 .addMBB(MergeBB); 194 195 Register DestReg = MI.getOperand(0).getReg(); 196 assert(MI.getOperand(4).getReg() == DestReg); 197 198 if (MI.getOpcode() == RISCV::PseudoCCMOVGPR || 199 MI.getOpcode() == RISCV::PseudoCCMOVGPRNoX0) { 200 // Add MV. 201 BuildMI(TrueBB, DL, TII->get(RISCV::ADDI), DestReg) 202 .add(MI.getOperand(5)) 203 .addImm(0); 204 } else { 205 unsigned NewOpc; 206 switch (MI.getOpcode()) { 207 default: 208 llvm_unreachable("Unexpected opcode!"); 209 case RISCV::PseudoCCADD: NewOpc = RISCV::ADD; break; 210 case RISCV::PseudoCCSUB: NewOpc = RISCV::SUB; break; 211 case RISCV::PseudoCCSLL: NewOpc = RISCV::SLL; break; 212 case RISCV::PseudoCCSRL: NewOpc = RISCV::SRL; break; 213 case RISCV::PseudoCCSRA: NewOpc = RISCV::SRA; break; 214 case RISCV::PseudoCCAND: NewOpc = RISCV::AND; break; 215 case RISCV::PseudoCCOR: NewOpc = RISCV::OR; break; 216 case RISCV::PseudoCCXOR: NewOpc = RISCV::XOR; break; 217 case RISCV::PseudoCCADDI: NewOpc = RISCV::ADDI; break; 218 case RISCV::PseudoCCSLLI: NewOpc = RISCV::SLLI; break; 219 case RISCV::PseudoCCSRLI: NewOpc = RISCV::SRLI; break; 220 case RISCV::PseudoCCSRAI: NewOpc = RISCV::SRAI; break; 221 case RISCV::PseudoCCANDI: NewOpc = RISCV::ANDI; break; 222 case RISCV::PseudoCCORI: NewOpc = RISCV::ORI; break; 223 case RISCV::PseudoCCXORI: NewOpc = RISCV::XORI; break; 224 case RISCV::PseudoCCADDW: NewOpc = RISCV::ADDW; break; 225 case RISCV::PseudoCCSUBW: NewOpc = RISCV::SUBW; break; 226 case RISCV::PseudoCCSLLW: NewOpc = RISCV::SLLW; break; 227 case RISCV::PseudoCCSRLW: NewOpc = RISCV::SRLW; break; 228 case RISCV::PseudoCCSRAW: NewOpc = RISCV::SRAW; break; 229 case RISCV::PseudoCCADDIW: NewOpc = RISCV::ADDIW; break; 230 case RISCV::PseudoCCSLLIW: NewOpc = RISCV::SLLIW; break; 231 case RISCV::PseudoCCSRLIW: NewOpc = RISCV::SRLIW; break; 232 case RISCV::PseudoCCSRAIW: NewOpc = RISCV::SRAIW; break; 233 case RISCV::PseudoCCANDN: NewOpc = RISCV::ANDN; break; 234 case RISCV::PseudoCCORN: NewOpc = RISCV::ORN; break; 235 case RISCV::PseudoCCXNOR: NewOpc = RISCV::XNOR; break; 236 } 237 BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg) 238 .add(MI.getOperand(5)) 239 .add(MI.getOperand(6)); 240 } 241 242 TrueBB->addSuccessor(MergeBB); 243 244 MergeBB->splice(MergeBB->end(), &MBB, MI, MBB.end()); 245 MergeBB->transferSuccessors(&MBB); 246 247 MBB.addSuccessor(TrueBB); 248 MBB.addSuccessor(MergeBB); 249 250 NextMBBI = MBB.end(); 251 MI.eraseFromParent(); 252 253 // Make sure live-ins are correctly attached to this new basic block. 254 LivePhysRegs LiveRegs; 255 computeAndAddLiveIns(LiveRegs, *TrueBB); 256 computeAndAddLiveIns(LiveRegs, *MergeBB); 257 258 return true; 259 } 260 261 bool RISCVExpandPseudo::expandVSetVL(MachineBasicBlock &MBB, 262 MachineBasicBlock::iterator MBBI) { 263 assert(MBBI->getNumExplicitOperands() == 3 && MBBI->getNumOperands() >= 5 && 264 "Unexpected instruction format"); 265 266 DebugLoc DL = MBBI->getDebugLoc(); 267 268 assert((MBBI->getOpcode() == RISCV::PseudoVSETVLI || 269 MBBI->getOpcode() == RISCV::PseudoVSETVLIX0 || 270 MBBI->getOpcode() == RISCV::PseudoVSETIVLI) && 271 "Unexpected pseudo instruction"); 272 unsigned Opcode; 273 if (MBBI->getOpcode() == RISCV::PseudoVSETIVLI) 274 Opcode = RISCV::VSETIVLI; 275 else 276 Opcode = RISCV::VSETVLI; 277 const MCInstrDesc &Desc = TII->get(Opcode); 278 assert(Desc.getNumOperands() == 3 && "Unexpected instruction format"); 279 280 Register DstReg = MBBI->getOperand(0).getReg(); 281 bool DstIsDead = MBBI->getOperand(0).isDead(); 282 BuildMI(MBB, MBBI, DL, Desc) 283 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) 284 .add(MBBI->getOperand(1)) // VL 285 .add(MBBI->getOperand(2)); // VType 286 287 MBBI->eraseFromParent(); // The pseudo instruction is gone now. 288 return true; 289 } 290 291 bool RISCVExpandPseudo::expandVMSET_VMCLR(MachineBasicBlock &MBB, 292 MachineBasicBlock::iterator MBBI, 293 unsigned Opcode) { 294 DebugLoc DL = MBBI->getDebugLoc(); 295 Register DstReg = MBBI->getOperand(0).getReg(); 296 const MCInstrDesc &Desc = TII->get(Opcode); 297 BuildMI(MBB, MBBI, DL, Desc, DstReg) 298 .addReg(DstReg, RegState::Undef) 299 .addReg(DstReg, RegState::Undef); 300 MBBI->eraseFromParent(); // The pseudo instruction is gone now. 301 return true; 302 } 303 304 // This function expands the PseudoRV32ZdinxSD for storing a double-precision 305 // floating-point value into memory by generating an equivalent instruction 306 // sequence for RV32. 307 bool RISCVExpandPseudo::expandRV32ZdinxStore(MachineBasicBlock &MBB, 308 MachineBasicBlock::iterator MBBI) { 309 DebugLoc DL = MBBI->getDebugLoc(); 310 const TargetRegisterInfo *TRI = STI->getRegisterInfo(); 311 Register Lo = 312 TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_gpr_even); 313 Register Hi = 314 TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_gpr_odd); 315 316 assert(MBBI->hasOneMemOperand() && "Expected mem operand"); 317 MachineMemOperand *OldMMO = MBBI->memoperands().front(); 318 MachineFunction *MF = MBB.getParent(); 319 MachineMemOperand *MMOLo = MF->getMachineMemOperand(OldMMO, 0, 4); 320 MachineMemOperand *MMOHi = MF->getMachineMemOperand(OldMMO, 4, 4); 321 322 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW)) 323 .addReg(Lo, getKillRegState(MBBI->getOperand(0).isKill())) 324 .addReg(MBBI->getOperand(1).getReg()) 325 .add(MBBI->getOperand(2)) 326 .setMemRefs(MMOLo); 327 328 if (MBBI->getOperand(2).isGlobal() || MBBI->getOperand(2).isCPI()) { 329 // FIXME: Zdinx RV32 can not work on unaligned scalar memory. 330 assert(!STI->enableUnalignedScalarMem()); 331 332 assert(MBBI->getOperand(2).getOffset() % 8 == 0); 333 MBBI->getOperand(2).setOffset(MBBI->getOperand(2).getOffset() + 4); 334 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW)) 335 .addReg(Hi, getKillRegState(MBBI->getOperand(0).isKill())) 336 .add(MBBI->getOperand(1)) 337 .add(MBBI->getOperand(2)) 338 .setMemRefs(MMOHi); 339 } else { 340 assert(isInt<12>(MBBI->getOperand(2).getImm() + 4)); 341 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW)) 342 .addReg(Hi, getKillRegState(MBBI->getOperand(0).isKill())) 343 .add(MBBI->getOperand(1)) 344 .addImm(MBBI->getOperand(2).getImm() + 4) 345 .setMemRefs(MMOHi); 346 } 347 MBBI->eraseFromParent(); 348 return true; 349 } 350 351 // This function expands PseudoRV32ZdinxLoad for loading a double-precision 352 // floating-point value from memory into an equivalent instruction sequence for 353 // RV32. 354 bool RISCVExpandPseudo::expandRV32ZdinxLoad(MachineBasicBlock &MBB, 355 MachineBasicBlock::iterator MBBI) { 356 DebugLoc DL = MBBI->getDebugLoc(); 357 const TargetRegisterInfo *TRI = STI->getRegisterInfo(); 358 Register Lo = 359 TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_gpr_even); 360 Register Hi = 361 TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_gpr_odd); 362 363 assert(MBBI->hasOneMemOperand() && "Expected mem operand"); 364 MachineMemOperand *OldMMO = MBBI->memoperands().front(); 365 MachineFunction *MF = MBB.getParent(); 366 MachineMemOperand *MMOLo = MF->getMachineMemOperand(OldMMO, 0, 4); 367 MachineMemOperand *MMOHi = MF->getMachineMemOperand(OldMMO, 4, 4); 368 369 // If the register of operand 1 is equal to the Lo register, then swap the 370 // order of loading the Lo and Hi statements. 371 bool IsOp1EqualToLo = Lo == MBBI->getOperand(1).getReg(); 372 // Order: Lo, Hi 373 if (!IsOp1EqualToLo) { 374 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Lo) 375 .addReg(MBBI->getOperand(1).getReg()) 376 .add(MBBI->getOperand(2)) 377 .setMemRefs(MMOLo); 378 } 379 380 if (MBBI->getOperand(2).isGlobal() || MBBI->getOperand(2).isCPI()) { 381 auto Offset = MBBI->getOperand(2).getOffset(); 382 assert(MBBI->getOperand(2).getOffset() % 8 == 0); 383 MBBI->getOperand(2).setOffset(Offset + 4); 384 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Hi) 385 .addReg(MBBI->getOperand(1).getReg()) 386 .add(MBBI->getOperand(2)) 387 .setMemRefs(MMOHi); 388 MBBI->getOperand(2).setOffset(Offset); 389 } else { 390 assert(isInt<12>(MBBI->getOperand(2).getImm() + 4)); 391 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Hi) 392 .addReg(MBBI->getOperand(1).getReg()) 393 .addImm(MBBI->getOperand(2).getImm() + 4) 394 .setMemRefs(MMOHi); 395 } 396 397 // Order: Hi, Lo 398 if (IsOp1EqualToLo) { 399 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Lo) 400 .addReg(MBBI->getOperand(1).getReg()) 401 .add(MBBI->getOperand(2)) 402 .setMemRefs(MMOLo); 403 } 404 405 MBBI->eraseFromParent(); 406 return true; 407 } 408 409 class RISCVPreRAExpandPseudo : public MachineFunctionPass { 410 public: 411 const RISCVSubtarget *STI; 412 const RISCVInstrInfo *TII; 413 static char ID; 414 415 RISCVPreRAExpandPseudo() : MachineFunctionPass(ID) {} 416 417 bool runOnMachineFunction(MachineFunction &MF) override; 418 419 void getAnalysisUsage(AnalysisUsage &AU) const override { 420 AU.setPreservesCFG(); 421 MachineFunctionPass::getAnalysisUsage(AU); 422 } 423 StringRef getPassName() const override { 424 return RISCV_PRERA_EXPAND_PSEUDO_NAME; 425 } 426 427 private: 428 bool expandMBB(MachineBasicBlock &MBB); 429 bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 430 MachineBasicBlock::iterator &NextMBBI); 431 bool expandAuipcInstPair(MachineBasicBlock &MBB, 432 MachineBasicBlock::iterator MBBI, 433 MachineBasicBlock::iterator &NextMBBI, 434 unsigned FlagsHi, unsigned SecondOpcode); 435 bool expandLoadLocalAddress(MachineBasicBlock &MBB, 436 MachineBasicBlock::iterator MBBI, 437 MachineBasicBlock::iterator &NextMBBI); 438 bool expandLoadGlobalAddress(MachineBasicBlock &MBB, 439 MachineBasicBlock::iterator MBBI, 440 MachineBasicBlock::iterator &NextMBBI); 441 bool expandLoadTLSIEAddress(MachineBasicBlock &MBB, 442 MachineBasicBlock::iterator MBBI, 443 MachineBasicBlock::iterator &NextMBBI); 444 bool expandLoadTLSGDAddress(MachineBasicBlock &MBB, 445 MachineBasicBlock::iterator MBBI, 446 MachineBasicBlock::iterator &NextMBBI); 447 bool expandLoadTLSDescAddress(MachineBasicBlock &MBB, 448 MachineBasicBlock::iterator MBBI, 449 MachineBasicBlock::iterator &NextMBBI); 450 451 #ifndef NDEBUG 452 unsigned getInstSizeInBytes(const MachineFunction &MF) const { 453 unsigned Size = 0; 454 for (auto &MBB : MF) 455 for (auto &MI : MBB) 456 Size += TII->getInstSizeInBytes(MI); 457 return Size; 458 } 459 #endif 460 }; 461 462 char RISCVPreRAExpandPseudo::ID = 0; 463 464 bool RISCVPreRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 465 STI = &MF.getSubtarget<RISCVSubtarget>(); 466 TII = STI->getInstrInfo(); 467 468 #ifndef NDEBUG 469 const unsigned OldSize = getInstSizeInBytes(MF); 470 #endif 471 472 bool Modified = false; 473 for (auto &MBB : MF) 474 Modified |= expandMBB(MBB); 475 476 #ifndef NDEBUG 477 const unsigned NewSize = getInstSizeInBytes(MF); 478 assert(OldSize >= NewSize); 479 #endif 480 return Modified; 481 } 482 483 bool RISCVPreRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) { 484 bool Modified = false; 485 486 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 487 while (MBBI != E) { 488 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 489 Modified |= expandMI(MBB, MBBI, NMBBI); 490 MBBI = NMBBI; 491 } 492 493 return Modified; 494 } 495 496 bool RISCVPreRAExpandPseudo::expandMI(MachineBasicBlock &MBB, 497 MachineBasicBlock::iterator MBBI, 498 MachineBasicBlock::iterator &NextMBBI) { 499 500 switch (MBBI->getOpcode()) { 501 case RISCV::PseudoLLA: 502 return expandLoadLocalAddress(MBB, MBBI, NextMBBI); 503 case RISCV::PseudoLGA: 504 return expandLoadGlobalAddress(MBB, MBBI, NextMBBI); 505 case RISCV::PseudoLA_TLS_IE: 506 return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI); 507 case RISCV::PseudoLA_TLS_GD: 508 return expandLoadTLSGDAddress(MBB, MBBI, NextMBBI); 509 case RISCV::PseudoLA_TLSDESC: 510 return expandLoadTLSDescAddress(MBB, MBBI, NextMBBI); 511 } 512 return false; 513 } 514 515 bool RISCVPreRAExpandPseudo::expandAuipcInstPair( 516 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 517 MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi, 518 unsigned SecondOpcode) { 519 MachineFunction *MF = MBB.getParent(); 520 MachineInstr &MI = *MBBI; 521 DebugLoc DL = MI.getDebugLoc(); 522 523 Register DestReg = MI.getOperand(0).getReg(); 524 Register ScratchReg = 525 MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); 526 527 MachineOperand &Symbol = MI.getOperand(1); 528 Symbol.setTargetFlags(FlagsHi); 529 MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("pcrel_hi"); 530 531 MachineInstr *MIAUIPC = 532 BuildMI(MBB, MBBI, DL, TII->get(RISCV::AUIPC), ScratchReg).add(Symbol); 533 MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol); 534 535 MachineInstr *SecondMI = 536 BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg) 537 .addReg(ScratchReg) 538 .addSym(AUIPCSymbol, RISCVII::MO_PCREL_LO); 539 540 if (MI.hasOneMemOperand()) 541 SecondMI->addMemOperand(*MF, *MI.memoperands_begin()); 542 543 MI.eraseFromParent(); 544 return true; 545 } 546 547 bool RISCVPreRAExpandPseudo::expandLoadLocalAddress( 548 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 549 MachineBasicBlock::iterator &NextMBBI) { 550 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI, 551 RISCV::ADDI); 552 } 553 554 bool RISCVPreRAExpandPseudo::expandLoadGlobalAddress( 555 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 556 MachineBasicBlock::iterator &NextMBBI) { 557 unsigned SecondOpcode = STI->is64Bit() ? RISCV::LD : RISCV::LW; 558 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_GOT_HI, 559 SecondOpcode); 560 } 561 562 bool RISCVPreRAExpandPseudo::expandLoadTLSIEAddress( 563 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 564 MachineBasicBlock::iterator &NextMBBI) { 565 unsigned SecondOpcode = STI->is64Bit() ? RISCV::LD : RISCV::LW; 566 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GOT_HI, 567 SecondOpcode); 568 } 569 570 bool RISCVPreRAExpandPseudo::expandLoadTLSGDAddress( 571 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 572 MachineBasicBlock::iterator &NextMBBI) { 573 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GD_HI, 574 RISCV::ADDI); 575 } 576 577 bool RISCVPreRAExpandPseudo::expandLoadTLSDescAddress( 578 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 579 MachineBasicBlock::iterator &NextMBBI) { 580 MachineFunction *MF = MBB.getParent(); 581 MachineInstr &MI = *MBBI; 582 DebugLoc DL = MI.getDebugLoc(); 583 584 const auto &STI = MF->getSubtarget<RISCVSubtarget>(); 585 unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW; 586 587 Register FinalReg = MI.getOperand(0).getReg(); 588 Register DestReg = 589 MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); 590 Register ScratchReg = 591 MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); 592 593 MachineOperand &Symbol = MI.getOperand(1); 594 Symbol.setTargetFlags(RISCVII::MO_TLSDESC_HI); 595 MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("tlsdesc_hi"); 596 597 MachineInstr *MIAUIPC = 598 BuildMI(MBB, MBBI, DL, TII->get(RISCV::AUIPC), ScratchReg).add(Symbol); 599 MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol); 600 601 BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg) 602 .addReg(ScratchReg) 603 .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_LOAD_LO); 604 605 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), RISCV::X10) 606 .addReg(ScratchReg) 607 .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_ADD_LO); 608 609 BuildMI(MBB, MBBI, DL, TII->get(RISCV::PseudoTLSDESCCall), RISCV::X5) 610 .addReg(DestReg) 611 .addImm(0) 612 .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_CALL); 613 614 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADD), FinalReg) 615 .addReg(RISCV::X10) 616 .addReg(RISCV::X4); 617 618 MI.eraseFromParent(); 619 return true; 620 } 621 622 } // end of anonymous namespace 623 624 INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo", 625 RISCV_EXPAND_PSEUDO_NAME, false, false) 626 627 INITIALIZE_PASS(RISCVPreRAExpandPseudo, "riscv-prera-expand-pseudo", 628 RISCV_PRERA_EXPAND_PSEUDO_NAME, false, false) 629 630 namespace llvm { 631 632 FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); } 633 FunctionPass *createRISCVPreRAExpandPseudoPass() { return new RISCVPreRAExpandPseudo(); } 634 635 } // end of namespace llvm 636