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