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 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW)) 316 .addReg(Lo, getKillRegState(MBBI->getOperand(0).isKill())) 317 .addReg(MBBI->getOperand(1).getReg()) 318 .add(MBBI->getOperand(2)); 319 if (MBBI->getOperand(2).isGlobal() || MBBI->getOperand(2).isCPI()) { 320 // FIXME: Zdinx RV32 can not work on unaligned scalar memory. 321 assert(!STI->hasFastUnalignedAccess() && 322 !STI->enableUnalignedScalarMem()); 323 324 assert(MBBI->getOperand(2).getOffset() % 8 == 0); 325 MBBI->getOperand(2).setOffset(MBBI->getOperand(2).getOffset() + 4); 326 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW)) 327 .addReg(Hi, getKillRegState(MBBI->getOperand(0).isKill())) 328 .add(MBBI->getOperand(1)) 329 .add(MBBI->getOperand(2)); 330 } else { 331 assert(isInt<12>(MBBI->getOperand(2).getImm() + 4)); 332 BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW)) 333 .addReg(Hi, getKillRegState(MBBI->getOperand(0).isKill())) 334 .add(MBBI->getOperand(1)) 335 .addImm(MBBI->getOperand(2).getImm() + 4); 336 } 337 MBBI->eraseFromParent(); 338 return true; 339 } 340 341 // This function expands PseudoRV32ZdinxLoad for loading a double-precision 342 // floating-point value from memory into an equivalent instruction sequence for 343 // RV32. 344 bool RISCVExpandPseudo::expandRV32ZdinxLoad(MachineBasicBlock &MBB, 345 MachineBasicBlock::iterator MBBI) { 346 DebugLoc DL = MBBI->getDebugLoc(); 347 const TargetRegisterInfo *TRI = STI->getRegisterInfo(); 348 Register Lo = 349 TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_gpr_even); 350 Register Hi = 351 TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_gpr_odd); 352 353 // If the register of operand 1 is equal to the Lo register, then swap the 354 // order of loading the Lo and Hi statements. 355 bool IsOp1EqualToLo = Lo == MBBI->getOperand(1).getReg(); 356 // Order: Lo, Hi 357 if (!IsOp1EqualToLo) { 358 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Lo) 359 .addReg(MBBI->getOperand(1).getReg()) 360 .add(MBBI->getOperand(2)); 361 } 362 363 if (MBBI->getOperand(2).isGlobal() || MBBI->getOperand(2).isCPI()) { 364 auto Offset = MBBI->getOperand(2).getOffset(); 365 assert(MBBI->getOperand(2).getOffset() % 8 == 0); 366 MBBI->getOperand(2).setOffset(Offset + 4); 367 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Hi) 368 .addReg(MBBI->getOperand(1).getReg()) 369 .add(MBBI->getOperand(2)); 370 MBBI->getOperand(2).setOffset(Offset); 371 } else { 372 assert(isInt<12>(MBBI->getOperand(2).getImm() + 4)); 373 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Hi) 374 .addReg(MBBI->getOperand(1).getReg()) 375 .addImm(MBBI->getOperand(2).getImm() + 4); 376 } 377 378 // Order: Hi, Lo 379 if (IsOp1EqualToLo) { 380 BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Lo) 381 .addReg(MBBI->getOperand(1).getReg()) 382 .add(MBBI->getOperand(2)); 383 } 384 385 MBBI->eraseFromParent(); 386 return true; 387 } 388 389 class RISCVPreRAExpandPseudo : public MachineFunctionPass { 390 public: 391 const RISCVSubtarget *STI; 392 const RISCVInstrInfo *TII; 393 static char ID; 394 395 RISCVPreRAExpandPseudo() : MachineFunctionPass(ID) {} 396 397 bool runOnMachineFunction(MachineFunction &MF) override; 398 399 void getAnalysisUsage(AnalysisUsage &AU) const override { 400 AU.setPreservesCFG(); 401 MachineFunctionPass::getAnalysisUsage(AU); 402 } 403 StringRef getPassName() const override { 404 return RISCV_PRERA_EXPAND_PSEUDO_NAME; 405 } 406 407 private: 408 bool expandMBB(MachineBasicBlock &MBB); 409 bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 410 MachineBasicBlock::iterator &NextMBBI); 411 bool expandAuipcInstPair(MachineBasicBlock &MBB, 412 MachineBasicBlock::iterator MBBI, 413 MachineBasicBlock::iterator &NextMBBI, 414 unsigned FlagsHi, unsigned SecondOpcode); 415 bool expandLoadLocalAddress(MachineBasicBlock &MBB, 416 MachineBasicBlock::iterator MBBI, 417 MachineBasicBlock::iterator &NextMBBI); 418 bool expandLoadGlobalAddress(MachineBasicBlock &MBB, 419 MachineBasicBlock::iterator MBBI, 420 MachineBasicBlock::iterator &NextMBBI); 421 bool expandLoadTLSIEAddress(MachineBasicBlock &MBB, 422 MachineBasicBlock::iterator MBBI, 423 MachineBasicBlock::iterator &NextMBBI); 424 bool expandLoadTLSGDAddress(MachineBasicBlock &MBB, 425 MachineBasicBlock::iterator MBBI, 426 MachineBasicBlock::iterator &NextMBBI); 427 bool expandLoadTLSDescAddress(MachineBasicBlock &MBB, 428 MachineBasicBlock::iterator MBBI, 429 MachineBasicBlock::iterator &NextMBBI); 430 431 #ifndef NDEBUG 432 unsigned getInstSizeInBytes(const MachineFunction &MF) const { 433 unsigned Size = 0; 434 for (auto &MBB : MF) 435 for (auto &MI : MBB) 436 Size += TII->getInstSizeInBytes(MI); 437 return Size; 438 } 439 #endif 440 }; 441 442 char RISCVPreRAExpandPseudo::ID = 0; 443 444 bool RISCVPreRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 445 STI = &MF.getSubtarget<RISCVSubtarget>(); 446 TII = STI->getInstrInfo(); 447 448 #ifndef NDEBUG 449 const unsigned OldSize = getInstSizeInBytes(MF); 450 #endif 451 452 bool Modified = false; 453 for (auto &MBB : MF) 454 Modified |= expandMBB(MBB); 455 456 #ifndef NDEBUG 457 const unsigned NewSize = getInstSizeInBytes(MF); 458 assert(OldSize >= NewSize); 459 #endif 460 return Modified; 461 } 462 463 bool RISCVPreRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) { 464 bool Modified = false; 465 466 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 467 while (MBBI != E) { 468 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 469 Modified |= expandMI(MBB, MBBI, NMBBI); 470 MBBI = NMBBI; 471 } 472 473 return Modified; 474 } 475 476 bool RISCVPreRAExpandPseudo::expandMI(MachineBasicBlock &MBB, 477 MachineBasicBlock::iterator MBBI, 478 MachineBasicBlock::iterator &NextMBBI) { 479 480 switch (MBBI->getOpcode()) { 481 case RISCV::PseudoLLA: 482 return expandLoadLocalAddress(MBB, MBBI, NextMBBI); 483 case RISCV::PseudoLGA: 484 return expandLoadGlobalAddress(MBB, MBBI, NextMBBI); 485 case RISCV::PseudoLA_TLS_IE: 486 return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI); 487 case RISCV::PseudoLA_TLS_GD: 488 return expandLoadTLSGDAddress(MBB, MBBI, NextMBBI); 489 case RISCV::PseudoLA_TLSDESC: 490 return expandLoadTLSDescAddress(MBB, MBBI, NextMBBI); 491 } 492 return false; 493 } 494 495 bool RISCVPreRAExpandPseudo::expandAuipcInstPair( 496 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 497 MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi, 498 unsigned SecondOpcode) { 499 MachineFunction *MF = MBB.getParent(); 500 MachineInstr &MI = *MBBI; 501 DebugLoc DL = MI.getDebugLoc(); 502 503 Register DestReg = MI.getOperand(0).getReg(); 504 Register ScratchReg = 505 MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); 506 507 MachineOperand &Symbol = MI.getOperand(1); 508 Symbol.setTargetFlags(FlagsHi); 509 MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("pcrel_hi"); 510 511 MachineInstr *MIAUIPC = 512 BuildMI(MBB, MBBI, DL, TII->get(RISCV::AUIPC), ScratchReg).add(Symbol); 513 MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol); 514 515 MachineInstr *SecondMI = 516 BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg) 517 .addReg(ScratchReg) 518 .addSym(AUIPCSymbol, RISCVII::MO_PCREL_LO); 519 520 if (MI.hasOneMemOperand()) 521 SecondMI->addMemOperand(*MF, *MI.memoperands_begin()); 522 523 MI.eraseFromParent(); 524 return true; 525 } 526 527 bool RISCVPreRAExpandPseudo::expandLoadLocalAddress( 528 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 529 MachineBasicBlock::iterator &NextMBBI) { 530 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI, 531 RISCV::ADDI); 532 } 533 534 bool RISCVPreRAExpandPseudo::expandLoadGlobalAddress( 535 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 536 MachineBasicBlock::iterator &NextMBBI) { 537 unsigned SecondOpcode = STI->is64Bit() ? RISCV::LD : RISCV::LW; 538 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_GOT_HI, 539 SecondOpcode); 540 } 541 542 bool RISCVPreRAExpandPseudo::expandLoadTLSIEAddress( 543 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 544 MachineBasicBlock::iterator &NextMBBI) { 545 unsigned SecondOpcode = STI->is64Bit() ? RISCV::LD : RISCV::LW; 546 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GOT_HI, 547 SecondOpcode); 548 } 549 550 bool RISCVPreRAExpandPseudo::expandLoadTLSGDAddress( 551 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 552 MachineBasicBlock::iterator &NextMBBI) { 553 return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GD_HI, 554 RISCV::ADDI); 555 } 556 557 bool RISCVPreRAExpandPseudo::expandLoadTLSDescAddress( 558 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, 559 MachineBasicBlock::iterator &NextMBBI) { 560 MachineFunction *MF = MBB.getParent(); 561 MachineInstr &MI = *MBBI; 562 DebugLoc DL = MI.getDebugLoc(); 563 564 const auto &STI = MF->getSubtarget<RISCVSubtarget>(); 565 unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW; 566 567 Register FinalReg = MI.getOperand(0).getReg(); 568 Register DestReg = 569 MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); 570 Register ScratchReg = 571 MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass); 572 573 MachineOperand &Symbol = MI.getOperand(1); 574 Symbol.setTargetFlags(RISCVII::MO_TLSDESC_HI); 575 MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("tlsdesc_hi"); 576 577 MachineInstr *MIAUIPC = 578 BuildMI(MBB, MBBI, DL, TII->get(RISCV::AUIPC), ScratchReg).add(Symbol); 579 MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol); 580 581 BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg) 582 .addReg(ScratchReg) 583 .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_LOAD_LO); 584 585 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), RISCV::X10) 586 .addReg(ScratchReg) 587 .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_ADD_LO); 588 589 BuildMI(MBB, MBBI, DL, TII->get(RISCV::PseudoTLSDESCCall), RISCV::X5) 590 .addReg(DestReg) 591 .addImm(0) 592 .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_CALL); 593 594 BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADD), FinalReg) 595 .addReg(RISCV::X10) 596 .addReg(RISCV::X4); 597 598 MI.eraseFromParent(); 599 return true; 600 } 601 602 } // end of anonymous namespace 603 604 INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo", 605 RISCV_EXPAND_PSEUDO_NAME, false, false) 606 607 INITIALIZE_PASS(RISCVPreRAExpandPseudo, "riscv-prera-expand-pseudo", 608 RISCV_PRERA_EXPAND_PSEUDO_NAME, false, false) 609 610 namespace llvm { 611 612 FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); } 613 FunctionPass *createRISCVPreRAExpandPseudoPass() { return new RISCVPreRAExpandPseudo(); } 614 615 } // end of namespace llvm 616