1 //===------ LeonPasses.cpp - Define passes specific to LEON ---------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "LeonPasses.h" 14 #include "llvm/CodeGen/ISDOpcodes.h" 15 #include "llvm/CodeGen/MachineFunction.h" 16 #include "llvm/CodeGen/MachineInstr.h" 17 #include "llvm/CodeGen/MachineInstrBuilder.h" 18 #include "llvm/CodeGen/MachineRegisterInfo.h" 19 #include "llvm/IR/LLVMContext.h" 20 #include "llvm/Support/raw_ostream.h" 21 using namespace llvm; 22 23 LEONMachineFunctionPass::LEONMachineFunctionPass(TargetMachine &tm, char &ID) 24 : MachineFunctionPass(ID) {} 25 26 LEONMachineFunctionPass::LEONMachineFunctionPass(char &ID) 27 : MachineFunctionPass(ID) {} 28 29 int LEONMachineFunctionPass::GetRegIndexForOperand(MachineInstr &MI, 30 int OperandIndex) { 31 if (MI.getNumOperands() > 0) { 32 if (OperandIndex == LAST_OPERAND) { 33 OperandIndex = MI.getNumOperands() - 1; 34 } 35 36 if (MI.getNumOperands() > (unsigned)OperandIndex && 37 MI.getOperand(OperandIndex).isReg()) { 38 return (int)MI.getOperand(OperandIndex).getReg(); 39 } 40 } 41 42 static int NotFoundIndex = -10; 43 // Return a different number each time to avoid any comparisons between the 44 // values returned. 45 NotFoundIndex -= 10; 46 return NotFoundIndex; 47 } 48 49 // finds a new free FP register 50 // checks also the AllocatedRegisters vector 51 int LEONMachineFunctionPass::getUnusedFPRegister(MachineRegisterInfo &MRI) { 52 for (int RegisterIndex = SP::F0; RegisterIndex <= SP::F31; ++RegisterIndex) { 53 if (!MRI.isPhysRegUsed(RegisterIndex) && 54 !is_contained(UsedRegisters, RegisterIndex)) { 55 return RegisterIndex; 56 } 57 } 58 59 return -1; 60 } 61 62 //***************************************************************************** 63 //**** InsertNOPLoad pass 64 //***************************************************************************** 65 // This pass fixes the incorrectly working Load instructions that exists for 66 // some earlier versions of the LEON processor line. NOP instructions must 67 // be inserted after the load instruction to ensure that the Load instruction 68 // behaves as expected for these processors. 69 // 70 // This pass inserts a NOP after any LD or LDF instruction. 71 // 72 char InsertNOPLoad::ID = 0; 73 74 InsertNOPLoad::InsertNOPLoad(TargetMachine &tm) 75 : LEONMachineFunctionPass(tm, ID) {} 76 77 bool InsertNOPLoad::runOnMachineFunction(MachineFunction &MF) { 78 Subtarget = &MF.getSubtarget<SparcSubtarget>(); 79 const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); 80 DebugLoc DL = DebugLoc(); 81 82 bool Modified = false; 83 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { 84 MachineBasicBlock &MBB = *MFI; 85 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { 86 MachineInstr &MI = *MBBI; 87 unsigned Opcode = MI.getOpcode(); 88 if (Opcode >= SP::LDDArr && Opcode <= SP::LDrr) { 89 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 90 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); 91 Modified = true; 92 } else if (MI.isInlineAsm()) { 93 // Look for an inline ld or ldf instruction. 94 StringRef AsmString = 95 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); 96 if (AsmString.startswith_lower("ld")) { 97 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 98 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); 99 Modified = true; 100 } 101 } 102 } 103 } 104 105 return Modified; 106 } 107 108 //***************************************************************************** 109 //**** FixFSMULD pass 110 //***************************************************************************** 111 // This pass fixes the incorrectly working FSMULD instruction that exists for 112 // some earlier versions of the LEON processor line. 113 // 114 // The pass should convert the FSMULD operands to double precision in scratch 115 // registers, then calculate the result with the FMULD instruction. Therefore, 116 // the pass should replace operations of the form: 117 // fsmuld %f20,%f21,%f8 118 // with the sequence: 119 // fstod %f20,%f0 120 // fstod %f21,%f2 121 // fmuld %f0,%f2,%f8 122 // 123 char FixFSMULD::ID = 0; 124 125 FixFSMULD::FixFSMULD(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {} 126 127 bool FixFSMULD::runOnMachineFunction(MachineFunction &MF) { 128 Subtarget = &MF.getSubtarget<SparcSubtarget>(); 129 const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); 130 DebugLoc DL = DebugLoc(); 131 132 bool Modified = false; 133 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { 134 MachineBasicBlock &MBB = *MFI; 135 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { 136 137 MachineInstr &MI = *MBBI; 138 unsigned Opcode = MI.getOpcode(); 139 140 const int UNASSIGNED_INDEX = -1; 141 int Reg1Index = UNASSIGNED_INDEX; 142 int Reg2Index = UNASSIGNED_INDEX; 143 int Reg3Index = UNASSIGNED_INDEX; 144 145 if (Opcode == SP::FSMULD && MI.getNumOperands() == 3) { 146 // take the registers from fsmuld %f20,%f21,%f8 147 Reg1Index = MI.getOperand(0).getReg(); 148 Reg2Index = MI.getOperand(1).getReg(); 149 Reg3Index = MI.getOperand(2).getReg(); 150 } else if (MI.isInlineAsm()) { 151 StringRef AsmString = 152 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); 153 if (AsmString.startswith_lower("fsmuld")) { 154 // this is an inline FSMULD instruction 155 156 unsigned StartOp = InlineAsm::MIOp_FirstOperand; 157 158 // extracts the registers from the inline assembly instruction 159 for (unsigned i = StartOp, e = MI.getNumOperands(); i != e; ++i) { 160 const MachineOperand &MO = MI.getOperand(i); 161 if (MO.isReg()) { 162 if (Reg1Index == UNASSIGNED_INDEX) 163 Reg1Index = MO.getReg(); 164 else if (Reg2Index == UNASSIGNED_INDEX) 165 Reg2Index = MO.getReg(); 166 else if (Reg3Index == UNASSIGNED_INDEX) 167 Reg3Index = MO.getReg(); 168 } 169 if (Reg3Index != UNASSIGNED_INDEX) 170 break; 171 } 172 } 173 } 174 175 if (Reg1Index != UNASSIGNED_INDEX && Reg2Index != UNASSIGNED_INDEX && 176 Reg3Index != UNASSIGNED_INDEX) { 177 clearUsedRegisterList(); 178 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 179 // Whatever Reg3Index is hasn't been used yet, so we need to reserve it. 180 markRegisterUsed(Reg3Index); 181 const int ScratchReg1Index = getUnusedFPRegister(MF.getRegInfo()); 182 markRegisterUsed(ScratchReg1Index); 183 const int ScratchReg2Index = getUnusedFPRegister(MF.getRegInfo()); 184 markRegisterUsed(ScratchReg2Index); 185 186 if (ScratchReg1Index == UNASSIGNED_INDEX || 187 ScratchReg2Index == UNASSIGNED_INDEX) { 188 errs() << "Cannot allocate free scratch registers for the FixFSMULD " 189 "pass." 190 << "\n"; 191 } else { 192 // create fstod %f20,%f0 193 BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD)) 194 .addReg(ScratchReg1Index) 195 .addReg(Reg1Index); 196 197 // create fstod %f21,%f2 198 BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD)) 199 .addReg(ScratchReg2Index) 200 .addReg(Reg2Index); 201 202 // create fmuld %f0,%f2,%f8 203 BuildMI(MBB, MBBI, DL, TII.get(SP::FMULD)) 204 .addReg(Reg3Index) 205 .addReg(ScratchReg1Index) 206 .addReg(ScratchReg2Index); 207 208 MI.eraseFromParent(); 209 MBBI = NMBBI; 210 211 Modified = true; 212 } 213 } 214 } 215 } 216 217 return Modified; 218 } 219 220 //***************************************************************************** 221 //**** ReplaceFMULS pass 222 //***************************************************************************** 223 // This pass fixes the incorrectly working FMULS instruction that exists for 224 // some earlier versions of the LEON processor line. 225 // 226 // This pass converts the FMULS operands to double precision in scratch 227 // registers, then calculates the result with the FMULD instruction. 228 // The pass should replace operations of the form: 229 // fmuls %f20,%f21,%f8 230 // with the sequence: 231 // fstod %f20,%f0 232 // fstod %f21,%f2 233 // fmuld %f0,%f2,%f8 234 // 235 char ReplaceFMULS::ID = 0; 236 237 ReplaceFMULS::ReplaceFMULS(TargetMachine &tm) 238 : LEONMachineFunctionPass(tm, ID) {} 239 240 bool ReplaceFMULS::runOnMachineFunction(MachineFunction &MF) { 241 Subtarget = &MF.getSubtarget<SparcSubtarget>(); 242 const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); 243 DebugLoc DL = DebugLoc(); 244 245 bool Modified = false; 246 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { 247 MachineBasicBlock &MBB = *MFI; 248 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { 249 MachineInstr &MI = *MBBI; 250 unsigned Opcode = MI.getOpcode(); 251 252 const int UNASSIGNED_INDEX = -1; 253 int Reg1Index = UNASSIGNED_INDEX; 254 int Reg2Index = UNASSIGNED_INDEX; 255 int Reg3Index = UNASSIGNED_INDEX; 256 257 if (Opcode == SP::FMULS && MI.getNumOperands() == 3) { 258 // take the registers from fmuls %f20,%f21,%f8 259 Reg1Index = MI.getOperand(0).getReg(); 260 Reg2Index = MI.getOperand(1).getReg(); 261 Reg3Index = MI.getOperand(2).getReg(); 262 } else if (MI.isInlineAsm()) { 263 StringRef AsmString = 264 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); 265 if (AsmString.startswith_lower("fmuls")) { 266 // this is an inline FMULS instruction 267 unsigned StartOp = InlineAsm::MIOp_FirstOperand; 268 269 // extracts the registers from the inline assembly instruction 270 for (unsigned i = StartOp, e = MI.getNumOperands(); i != e; ++i) { 271 const MachineOperand &MO = MI.getOperand(i); 272 if (MO.isReg()) { 273 if (Reg1Index == UNASSIGNED_INDEX) 274 Reg1Index = MO.getReg(); 275 else if (Reg2Index == UNASSIGNED_INDEX) 276 Reg2Index = MO.getReg(); 277 else if (Reg3Index == UNASSIGNED_INDEX) 278 Reg3Index = MO.getReg(); 279 } 280 if (Reg3Index != UNASSIGNED_INDEX) 281 break; 282 } 283 } 284 } 285 286 if (Reg1Index != UNASSIGNED_INDEX && Reg2Index != UNASSIGNED_INDEX && 287 Reg3Index != UNASSIGNED_INDEX) { 288 clearUsedRegisterList(); 289 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 290 // Whatever Reg3Index is hasn't been used yet, so we need to reserve it. 291 markRegisterUsed(Reg3Index); 292 const int ScratchReg1Index = getUnusedFPRegister(MF.getRegInfo()); 293 markRegisterUsed(ScratchReg1Index); 294 const int ScratchReg2Index = getUnusedFPRegister(MF.getRegInfo()); 295 markRegisterUsed(ScratchReg2Index); 296 297 if (ScratchReg1Index == UNASSIGNED_INDEX || 298 ScratchReg2Index == UNASSIGNED_INDEX) { 299 errs() << "Cannot allocate free scratch registers for the " 300 "ReplaceFMULS pass." 301 << "\n"; 302 } else { 303 // create fstod %f20,%f0 304 BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD)) 305 .addReg(ScratchReg1Index) 306 .addReg(Reg1Index); 307 308 // create fstod %f21,%f2 309 BuildMI(MBB, MBBI, DL, TII.get(SP::FSTOD)) 310 .addReg(ScratchReg2Index) 311 .addReg(Reg2Index); 312 313 // create fmuld %f0,%f2,%f8 314 BuildMI(MBB, MBBI, DL, TII.get(SP::FMULD)) 315 .addReg(Reg3Index) 316 .addReg(ScratchReg1Index) 317 .addReg(ScratchReg2Index); 318 319 MI.eraseFromParent(); 320 MBBI = NMBBI; 321 322 Modified = true; 323 } 324 } 325 } 326 } 327 328 return Modified; 329 } 330 331 //***************************************************************************** 332 //**** FixAllFDIVSQRT pass 333 //***************************************************************************** 334 // This pass fixes the incorrectly working FDIVx and FSQRTx instructions that 335 // exist for some earlier versions of the LEON processor line. Five NOP 336 // instructions need to be inserted after these instructions to ensure the 337 // correct result is placed in the destination registers before they are used. 338 // 339 // This pass implements two fixes: 340 // 1) fixing the FSQRTS and FSQRTD instructions. 341 // 2) fixing the FDIVS and FDIVD instructions. 342 // 343 // FSQRTS and FDIVS are converted to FDIVD and FSQRTD respectively earlier in 344 // the pipeline when this option is enabled, so this pass needs only to deal 345 // with the changes that still need implementing for the "double" versions 346 // of these instructions. 347 // 348 char FixAllFDIVSQRT::ID = 0; 349 350 FixAllFDIVSQRT::FixAllFDIVSQRT(TargetMachine &tm) 351 : LEONMachineFunctionPass(tm, ID) {} 352 353 bool FixAllFDIVSQRT::runOnMachineFunction(MachineFunction &MF) { 354 Subtarget = &MF.getSubtarget<SparcSubtarget>(); 355 const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); 356 DebugLoc DL = DebugLoc(); 357 358 bool Modified = false; 359 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { 360 MachineBasicBlock &MBB = *MFI; 361 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { 362 MachineInstr &MI = *MBBI; 363 unsigned Opcode = MI.getOpcode(); 364 365 if (MI.isInlineAsm()) { 366 StringRef AsmString = 367 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); 368 if (AsmString.startswith_lower("fsqrtd")) { 369 // this is an inline fsqrts instruction 370 Opcode = SP::FSQRTD; 371 } else if (AsmString.startswith_lower("fdivd")) { 372 // this is an inline fsqrts instruction 373 Opcode = SP::FDIVD; 374 } 375 } 376 377 // Note: FDIVS and FSQRTS cannot be generated when this erratum fix is 378 // switched on so we don't need to check for them here. They will 379 // already have been converted to FSQRTD or FDIVD earlier in the 380 // pipeline. 381 if (Opcode == SP::FSQRTD || Opcode == SP::FDIVD) { 382 // Insert 5 NOPs before FSQRTD,FDIVD. 383 for (int InsertedCount = 0; InsertedCount < 5; InsertedCount++) 384 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 385 386 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 387 // ... and inserting 28 NOPs after FSQRTD,FDIVD. 388 for (int InsertedCount = 0; InsertedCount < 28; InsertedCount++) 389 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); 390 391 Modified = true; 392 } 393 } 394 } 395 396 return Modified; 397 } 398 399 //***************************************************************************** 400 //**** ReplaceSDIV pass 401 //***************************************************************************** 402 // This pass fixes the incorrectly working SDIV instruction that 403 // exist for some earlier versions of the LEON processor line. The instruction 404 // is replaced with an SDIVcc instruction instead, which is working. 405 // 406 char ReplaceSDIV::ID = 0; 407 408 ReplaceSDIV::ReplaceSDIV() : LEONMachineFunctionPass(ID) {} 409 410 ReplaceSDIV::ReplaceSDIV(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {} 411 412 bool ReplaceSDIV::runOnMachineFunction(MachineFunction &MF) { 413 Subtarget = &MF.getSubtarget<SparcSubtarget>(); 414 const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); 415 416 bool Modified = false; 417 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { 418 MachineBasicBlock &MBB = *MFI; 419 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { 420 MachineInstr &MI = *MBBI; 421 unsigned Opcode = MI.getOpcode(); 422 if (Opcode == SP::SDIVrr) { 423 MI.setDesc(TII.get(SP::SDIVCCrr)); 424 Modified = true; 425 } else if (Opcode == SP::SDIVri) { 426 MI.setDesc(TII.get(SP::SDIVCCri)); 427 Modified = true; 428 } 429 } 430 } 431 432 return Modified; 433 } 434 435 static RegisterPass<ReplaceSDIV> X("replace-sdiv", "Replase SDIV Pass", false, 436 false); 437 438 //***************************************************************************** 439 //**** FixCALL pass 440 //***************************************************************************** 441 // This pass restricts the size of the immediate operand of the CALL 442 // instruction, which can cause problems on some earlier versions of the LEON 443 // processor, which can interpret some of the call address bits incorrectly. 444 // 445 char FixCALL::ID = 0; 446 447 FixCALL::FixCALL(TargetMachine &tm) : LEONMachineFunctionPass(tm, ID) {} 448 449 bool FixCALL::runOnMachineFunction(MachineFunction &MF) { 450 bool Modified = false; 451 452 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { 453 MachineBasicBlock &MBB = *MFI; 454 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { 455 MachineInstr &MI = *MBBI; 456 MI.print(errs()); 457 errs() << "\n"; 458 459 unsigned Opcode = MI.getOpcode(); 460 if (Opcode == SP::CALL || Opcode == SP::CALLrr) { 461 unsigned NumOperands = MI.getNumOperands(); 462 for (unsigned OperandIndex = 0; OperandIndex < NumOperands; 463 OperandIndex++) { 464 MachineOperand &MO = MI.getOperand(OperandIndex); 465 if (MO.isImm()) { 466 int64_t Value = MO.getImm(); 467 MO.setImm(Value & 0x000fffffL); 468 Modified = true; 469 break; 470 } 471 } 472 } else if (MI.isInlineAsm()) // inline assembly immediate call 473 { 474 StringRef AsmString = 475 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); 476 if (AsmString.startswith_lower("call")) { 477 // this is an inline call instruction 478 unsigned StartOp = InlineAsm::MIOp_FirstOperand; 479 480 // extracts the registers from the inline assembly instruction 481 for (unsigned i = StartOp, e = MI.getNumOperands(); i != e; ++i) { 482 MachineOperand &MO = MI.getOperand(i); 483 if (MO.isImm()) { 484 int64_t Value = MO.getImm(); 485 MO.setImm(Value & 0x000fffffL); 486 Modified = true; 487 } 488 } 489 } 490 } 491 } 492 } 493 494 return Modified; 495 } 496 497 //***************************************************************************** 498 //**** IgnoreZeroFlag pass 499 //***************************************************************************** 500 // This erratum fix fixes the overflow behavior of SDIVCC and UDIVCC 501 // instructions that exists on some earlier LEON processors. Where these 502 // instructions are detected, they are replaced by a sequence that will 503 // explicitly write the overflow bit flag if this is required. 504 // 505 char IgnoreZeroFlag::ID = 0; 506 507 IgnoreZeroFlag::IgnoreZeroFlag(TargetMachine &tm) 508 : LEONMachineFunctionPass(tm, ID) {} 509 510 bool IgnoreZeroFlag::runOnMachineFunction(MachineFunction &MF) { 511 Subtarget = &MF.getSubtarget<SparcSubtarget>(); 512 const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); 513 DebugLoc DL = DebugLoc(); 514 515 bool Modified = false; 516 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { 517 MachineBasicBlock &MBB = *MFI; 518 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { 519 MachineInstr &MI = *MBBI; 520 unsigned Opcode = MI.getOpcode(); 521 if (Opcode == SP::SDIVCCrr || Opcode == SP::SDIVCCri || 522 Opcode == SP::UDIVCCrr || Opcode == SP::UDIVCCri) { 523 524 // split the current machine basic block - just after the sdivcc/udivcc 525 // instruction 526 // create a label that help us skip the zero flag update (of PSR - 527 // Processor Status Register) 528 // if conditions are not met 529 const BasicBlock *LLVM_BB = MBB.getBasicBlock(); 530 MachineFunction::iterator It = 531 std::next(MachineFunction::iterator(MBB)); 532 533 MachineBasicBlock *dneBB = MF.CreateMachineBasicBlock(LLVM_BB); 534 MF.insert(It, dneBB); 535 536 // Transfer the remainder of MBB and its successor edges to dneBB. 537 dneBB->splice(dneBB->begin(), &MBB, 538 std::next(MachineBasicBlock::iterator(MI)), MBB.end()); 539 dneBB->transferSuccessorsAndUpdatePHIs(&MBB); 540 541 MBB.addSuccessor(dneBB); 542 543 MachineBasicBlock::iterator NextMBBI = std::next(MBBI); 544 545 // bvc - branch if overflow flag not set 546 BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND)) 547 .addMBB(dneBB) 548 .addImm(SPCC::ICC_VS); 549 550 // bnz - branch if not zero 551 BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND)) 552 .addMBB(dneBB) 553 .addImm(SPCC::ICC_NE); 554 555 // use the WRPSR (Write Processor State Register) instruction to set the 556 // zeo flag to 1 557 // create wr %g0, 1, %psr 558 BuildMI(MBB, NextMBBI, DL, TII.get(SP::WRPSRri)) 559 .addReg(SP::G0) 560 .addImm(1); 561 562 BuildMI(MBB, NextMBBI, DL, TII.get(SP::NOP)); 563 564 Modified = true; 565 } else if (MI.isInlineAsm()) { 566 StringRef AsmString = 567 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); 568 if (AsmString.startswith_lower("sdivcc") || 569 AsmString.startswith_lower("udivcc")) { 570 // this is an inline SDIVCC or UDIVCC instruction 571 572 // split the current machine basic block - just after the 573 // sdivcc/udivcc instruction 574 // create a label that help us skip the zero flag update (of PSR - 575 // Processor Status Register) 576 // if conditions are not met 577 const BasicBlock *LLVM_BB = MBB.getBasicBlock(); 578 MachineFunction::iterator It = 579 std::next(MachineFunction::iterator(MBB)); 580 581 MachineBasicBlock *dneBB = MF.CreateMachineBasicBlock(LLVM_BB); 582 MF.insert(It, dneBB); 583 584 // Transfer the remainder of MBB and its successor edges to dneBB. 585 dneBB->splice(dneBB->begin(), &MBB, 586 std::next(MachineBasicBlock::iterator(MI)), MBB.end()); 587 dneBB->transferSuccessorsAndUpdatePHIs(&MBB); 588 589 MBB.addSuccessor(dneBB); 590 591 MachineBasicBlock::iterator NextMBBI = std::next(MBBI); 592 593 // bvc - branch if overflow flag not set 594 BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND)) 595 .addMBB(dneBB) 596 .addImm(SPCC::ICC_VS); 597 598 // bnz - branch if not zero 599 BuildMI(MBB, NextMBBI, DL, TII.get(SP::BCOND)) 600 .addMBB(dneBB) 601 .addImm(SPCC::ICC_NE); 602 603 // use the WRPSR (Write Processor State Register) instruction to set 604 // the zeo flag to 1 605 // create wr %g0, 1, %psr 606 BuildMI(MBB, NextMBBI, DL, TII.get(SP::WRPSRri)) 607 .addReg(SP::G0) 608 .addImm(1); 609 610 BuildMI(MBB, NextMBBI, DL, TII.get(SP::NOP)); 611 612 Modified = true; 613 } 614 } 615 } 616 } 617 618 return Modified; 619 } 620 621 //***************************************************************************** 622 //**** InsertNOPDoublePrecision pass 623 //***************************************************************************** 624 // This erratum fix for some earlier LEON processors fixes a problem where a 625 // double precision load will not yield the correct result if used in FMUL, 626 // FDIV, FADD, FSUB or FSQRT instructions later. If this sequence is detected, 627 // inserting a NOP between the two instructions will fix the erratum. 628 // 1.scans the code after register allocation; 629 // 2.checks for the problem conditions as described in the AT697E erratum 630 // “Odd-Numbered FPU Register Dependency not Properly Checked in some 631 // Double-Precision FPU Operations”; 632 // 3.inserts NOPs if the problem exists. 633 // 634 char InsertNOPDoublePrecision::ID = 0; 635 636 InsertNOPDoublePrecision::InsertNOPDoublePrecision(TargetMachine &tm) 637 : LEONMachineFunctionPass(tm, ID) {} 638 639 bool InsertNOPDoublePrecision::runOnMachineFunction(MachineFunction &MF) { 640 Subtarget = &MF.getSubtarget<SparcSubtarget>(); 641 const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); 642 DebugLoc DL = DebugLoc(); 643 644 bool Modified = false; 645 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { 646 MachineBasicBlock &MBB = *MFI; 647 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { 648 MachineInstr &MI = *MBBI; 649 unsigned Opcode = MI.getOpcode(); 650 if (Opcode == SP::LDDFri || Opcode == SP::LDDFrr) { 651 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 652 MachineInstr &NMI = *NMBBI; 653 654 unsigned NextOpcode = NMI.getOpcode(); 655 // NMI.print(errs()); 656 if (NextOpcode == SP::FADDD || NextOpcode == SP::FSUBD || 657 NextOpcode == SP::FMULD || NextOpcode == SP::FDIVD) { 658 int RegAIndex = GetRegIndexForOperand(MI, 0); 659 int RegBIndex = GetRegIndexForOperand(NMI, 0); 660 int RegCIndex = 661 GetRegIndexForOperand(NMI, 2); // Second source operand is index 2 662 int RegDIndex = 663 GetRegIndexForOperand(NMI, 1); // Destination operand is index 1 664 665 if ((RegAIndex == RegBIndex + 1 && RegBIndex == RegDIndex) || 666 (RegAIndex == RegCIndex + 1 && RegCIndex == RegDIndex) || 667 (RegAIndex == RegBIndex + 1 && RegCIndex == RegDIndex) || 668 (RegAIndex == RegCIndex + 1 && RegBIndex == RegDIndex)) { 669 // Insert NOP between the two instructions. 670 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); 671 Modified = true; 672 } 673 674 // Check the errata patterns that only happen for FADDD and FMULD 675 if (Modified == false && 676 (NextOpcode == SP::FADDD || NextOpcode == SP::FMULD)) { 677 RegAIndex = GetRegIndexForOperand(MI, 1); 678 if (RegAIndex == RegBIndex + 1 && RegBIndex == RegCIndex && 679 RegBIndex == RegDIndex) { 680 // Insert NOP between the two instructions. 681 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); 682 Modified = true; 683 } 684 } 685 } else if (NextOpcode == SP::FSQRTD) { 686 int RegAIndex = GetRegIndexForOperand(MI, 1); 687 int RegBIndex = GetRegIndexForOperand(NMI, 0); 688 int RegCIndex = GetRegIndexForOperand(NMI, 1); 689 690 if (RegAIndex == RegBIndex + 1 && RegBIndex == RegCIndex) { 691 // Insert NOP between the two instructions. 692 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP)); 693 Modified = true; 694 } 695 } 696 } 697 } 698 } 699 700 return Modified; 701 } 702 703 //***************************************************************************** 704 //**** PreventRoundChange pass 705 //***************************************************************************** 706 // To prevent any explicit change of the default rounding mode, this pass 707 // detects any call of the fesetround function and removes this call from the 708 // list of generated operations. 709 // 710 char PreventRoundChange::ID = 0; 711 712 PreventRoundChange::PreventRoundChange(TargetMachine &tm) 713 : LEONMachineFunctionPass(tm, ID) {} 714 715 bool PreventRoundChange::runOnMachineFunction(MachineFunction &MF) { 716 Subtarget = &MF.getSubtarget<SparcSubtarget>(); 717 718 bool Modified = false; 719 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { 720 MachineBasicBlock &MBB = *MFI; 721 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { 722 MachineInstr &MI = *MBBI; 723 unsigned Opcode = MI.getOpcode(); 724 if (Opcode == SP::CALL && MI.getNumOperands() > 0) { 725 MachineOperand &MO = MI.getOperand(0); 726 727 if (MO.isGlobal()) { 728 StringRef FuncName = MO.getGlobal()->getName(); 729 if (FuncName.compare_lower("fesetround") == 0) { 730 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 731 MI.eraseFromParent(); 732 MBBI = NMBBI; 733 Modified = true; 734 } 735 } 736 } 737 } 738 } 739 740 return Modified; 741 } 742 //***************************************************************************** 743 //**** FlushCacheLineSWAP pass 744 //***************************************************************************** 745 // This pass inserts FLUSHW just before any SWAP atomic instruction. 746 // 747 char FlushCacheLineSWAP::ID = 0; 748 749 FlushCacheLineSWAP::FlushCacheLineSWAP(TargetMachine &tm) 750 : LEONMachineFunctionPass(tm, ID) {} 751 752 bool FlushCacheLineSWAP::runOnMachineFunction(MachineFunction &MF) { 753 Subtarget = &MF.getSubtarget<SparcSubtarget>(); 754 const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); 755 DebugLoc DL = DebugLoc(); 756 757 bool Modified = false; 758 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { 759 MachineBasicBlock &MBB = *MFI; 760 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { 761 MachineInstr &MI = *MBBI; 762 unsigned Opcode = MI.getOpcode(); 763 if (Opcode == SP::SWAPrr || Opcode == SP::SWAPri || 764 Opcode == SP::LDSTUBrr || Opcode == SP::LDSTUBri) { 765 // insert flush and 5 NOPs before the swap/ldstub instruction 766 BuildMI(MBB, MBBI, DL, TII.get(SP::FLUSH)); 767 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 768 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 769 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 770 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 771 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 772 773 Modified = true; 774 } else if (MI.isInlineAsm()) { 775 StringRef AsmString = 776 MI.getOperand(InlineAsm::MIOp_AsmString).getSymbolName(); 777 if (AsmString.startswith_lower("swap") || 778 AsmString.startswith_lower("ldstub")) { 779 // this is an inline swap or ldstub instruction 780 781 // insert flush and 5 NOPs before the swap/ldstub instruction 782 BuildMI(MBB, MBBI, DL, TII.get(SP::FLUSH)); 783 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 784 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 785 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 786 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 787 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 788 789 Modified = true; 790 } 791 } 792 } 793 } 794 795 return Modified; 796 } 797 798 //***************************************************************************** 799 //**** InsertNOPsLoadStore pass 800 //***************************************************************************** 801 // This pass shall insert NOPs between floating point loads and stores when the 802 // following circumstances are present [5]: 803 // Pattern 1: 804 // 1. single-precision load or single-precision FPOP to register %fX, where X is 805 // the same register as the store being checked; 806 // 2. single-precision load or single-precision FPOP to register %fY , where Y 807 // is the opposite register in the same double-precision pair; 808 // 3. 0-3 instructions of any kind, except stores from %fX or %fY or operations 809 // with %fX as destination; 810 // 4. the store (from register %fX) being considered. 811 // Pattern 2: 812 // 1. double-precision FPOP; 813 // 2. any number of operations on any kind, except no double-precision FPOP and 814 // at most one (less than two) single-precision or single-to-double FPOPs; 815 // 3. the store (from register %fX) being considered. 816 // 817 char InsertNOPsLoadStore::ID = 0; 818 819 InsertNOPsLoadStore::InsertNOPsLoadStore(TargetMachine &tm) 820 : LEONMachineFunctionPass(tm, ID) {} 821 822 bool InsertNOPsLoadStore::runOnMachineFunction(MachineFunction &MF) { 823 Subtarget = &MF.getSubtarget<SparcSubtarget>(); 824 const TargetInstrInfo &TII = *Subtarget->getInstrInfo(); 825 DebugLoc DL = DebugLoc(); 826 827 MachineInstr *Pattern1FirstInstruction = NULL; 828 MachineInstr *Pattern2FirstInstruction = NULL; 829 unsigned int StoreInstructionsToCheck = 0; 830 int FxRegIndex, FyRegIndex; 831 832 bool Modified = false; 833 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) { 834 MachineBasicBlock &MBB = *MFI; 835 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) { 836 MachineInstr &MI = *MBBI; 837 838 if (StoreInstructionsToCheck > 0) { 839 if (((MI.getOpcode() == SP::STFrr || MI.getOpcode() == SP::STFri) && 840 (GetRegIndexForOperand(MI, LAST_OPERAND) == FxRegIndex || 841 GetRegIndexForOperand(MI, LAST_OPERAND) == FyRegIndex)) || 842 GetRegIndexForOperand(MI, 0) == FxRegIndex) { 843 // Insert four NOPs 844 for (unsigned InsertedCount = 0; InsertedCount < 4; InsertedCount++) { 845 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 846 } 847 Modified = true; 848 } 849 StoreInstructionsToCheck--; 850 } 851 852 switch (MI.getOpcode()) { 853 // Watch for Pattern 1 FPop instructions 854 case SP::LDrr: 855 case SP::LDri: 856 case SP::LDFrr: 857 case SP::LDFri: 858 case SP::FADDS: 859 case SP::FSUBS: 860 case SP::FMULS: 861 case SP::FDIVS: 862 case SP::FSQRTS: 863 case SP::FCMPS: 864 case SP::FMOVS: 865 case SP::FNEGS: 866 case SP::FABSS: 867 case SP::FITOS: 868 case SP::FSTOI: 869 case SP::FITOD: 870 case SP::FDTOI: 871 case SP::FDTOS: 872 if (Pattern1FirstInstruction != NULL) { 873 FxRegIndex = GetRegIndexForOperand(*Pattern1FirstInstruction, 0); 874 FyRegIndex = GetRegIndexForOperand(MI, 0); 875 876 // Check to see if these registers are part of the same double 877 // precision 878 // register pair. 879 int DoublePrecRegIndexForX = (FxRegIndex - SP::F0) / 2; 880 int DoublePrecRegIndexForY = (FyRegIndex - SP::F0) / 2; 881 882 if (DoublePrecRegIndexForX == DoublePrecRegIndexForY) 883 StoreInstructionsToCheck = 4; 884 } 885 886 Pattern1FirstInstruction = &MI; 887 break; 888 // End of Pattern 1 889 890 // Search for Pattern 2 891 case SP::FADDD: 892 case SP::FSUBD: 893 case SP::FMULD: 894 case SP::FDIVD: 895 case SP::FSQRTD: 896 case SP::FCMPD: 897 Pattern2FirstInstruction = &MI; 898 Pattern1FirstInstruction = NULL; 899 break; 900 901 case SP::STFrr: 902 case SP::STFri: 903 case SP::STDFrr: 904 case SP::STDFri: 905 if (Pattern2FirstInstruction != NULL) { 906 if (GetRegIndexForOperand(MI, LAST_OPERAND) == 907 GetRegIndexForOperand(*Pattern2FirstInstruction, 0)) { 908 // Insert four NOPs 909 for (unsigned InsertedCount = 0; InsertedCount < 4; 910 InsertedCount++) { 911 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP)); 912 } 913 914 Pattern2FirstInstruction = NULL; 915 } 916 } 917 Pattern1FirstInstruction = NULL; 918 break; 919 // End of Pattern 2 920 921 default: 922 // Ensure we don't count debug-only values while we're testing for the 923 // patterns. 924 if (!MI.isDebugValue()) 925 Pattern1FirstInstruction = NULL; 926 break; 927 } 928 } 929 } 930 931 return Modified; 932 } 933