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