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