blob: 6ad6940c6b51b23e395bd465100b2923bc4fd9f7 [file] [log] [blame]
Chris Dewhurst4f7cac32016-05-23 10:56:36 +00001//===------ LeonPasses.cpp - Define passes specific to LEON ---------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Dewhurst4f7cac32016-05-23 10:56:36 +00006//
7//===----------------------------------------------------------------------===//
8//
9//
10//===----------------------------------------------------------------------===//
11
12#include "LeonPasses.h"
Simon Pilgrimdfc33302020-09-07 17:09:42 +010013#include "SparcSubtarget.h"
14#include "llvm/CodeGen/MachineBasicBlock.h"
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000015#include "llvm/CodeGen/MachineFunction.h"
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000016#include "llvm/CodeGen/MachineInstr.h"
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000017#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000018#include "llvm/Support/raw_ostream.h"
Simon Pilgrimdfc33302020-09-07 17:09:42 +010019
Benjamin Kramer797fb962016-05-27 10:06:27 +000020using namespace llvm;
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000021
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000022LEONMachineFunctionPass::LEONMachineFunctionPass(char &ID)
23 : MachineFunctionPass(ID) {}
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000024
25//*****************************************************************************
26//**** InsertNOPLoad pass
27//*****************************************************************************
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000028// This pass fixes the incorrectly working Load instructions that exists for
29// some earlier versions of the LEON processor line. NOP instructions must
30// be inserted after the load instruction to ensure that the Load instruction
31// behaves as expected for these processors.
32//
33// This pass inserts a NOP after any LD or LDF instruction.
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000034//
35char InsertNOPLoad::ID = 0;
36
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +000037InsertNOPLoad::InsertNOPLoad() : LEONMachineFunctionPass(ID) {}
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000038
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000039bool InsertNOPLoad::runOnMachineFunction(MachineFunction &MF) {
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000040 Subtarget = &MF.getSubtarget<SparcSubtarget>();
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000041 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000042 DebugLoc DL = DebugLoc();
43
44 bool Modified = false;
45 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
46 MachineBasicBlock &MBB = *MFI;
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000047 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000048 MachineInstr &MI = *MBBI;
49 unsigned Opcode = MI.getOpcode();
Chris Dewhurst2bad85c2016-06-27 14:19:19 +000050 if (Opcode >= SP::LDDArr && Opcode <= SP::LDrr) {
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000051 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
52 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
53 Modified = true;
Chris Dewhurst4f7cac32016-05-23 10:56:36 +000054 }
55 }
56 }
57
58 return Modified;
59}
Chris Dewhurst0c1e0022016-06-19 11:03:28 +000060
Chris Dewhurst0c1e0022016-06-19 11:03:28 +000061
Chris Dewhurst2c3cdd62016-10-19 14:01:06 +000062
63//*****************************************************************************
64//**** DetectRoundChange pass
65//*****************************************************************************
66// To prevent any explicit change of the default rounding mode, this pass
67// detects any call of the fesetround function.
68// A warning is generated to ensure the user knows this has happened.
69//
70// Detects an erratum in UT699 LEON 3 processor
71
72char DetectRoundChange::ID = 0;
73
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +000074DetectRoundChange::DetectRoundChange() : LEONMachineFunctionPass(ID) {}
Chris Dewhurst2c3cdd62016-10-19 14:01:06 +000075
76bool DetectRoundChange::runOnMachineFunction(MachineFunction &MF) {
77 Subtarget = &MF.getSubtarget<SparcSubtarget>();
78
79 bool Modified = false;
80 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
81 MachineBasicBlock &MBB = *MFI;
82 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
83 MachineInstr &MI = *MBBI;
84 unsigned Opcode = MI.getOpcode();
85 if (Opcode == SP::CALL && MI.getNumOperands() > 0) {
86 MachineOperand &MO = MI.getOperand(0);
87
88 if (MO.isGlobal()) {
89 StringRef FuncName = MO.getGlobal()->getName();
90 if (FuncName.compare_lower("fesetround") == 0) {
91 errs() << "Error: You are using the detectroundchange "
92 "option to detect rounding changes that will "
93 "cause LEON errata. The only way to fix this "
94 "is to remove the call to fesetround from "
95 "the source code.\n";
96 }
97 }
98 }
99 }
100 }
101
102 return Modified;
103}
104
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000105//*****************************************************************************
106//**** FixAllFDIVSQRT pass
107//*****************************************************************************
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000108// This pass fixes the incorrectly working FDIVx and FSQRTx instructions that
109// exist for some earlier versions of the LEON processor line. Five NOP
110// instructions need to be inserted after these instructions to ensure the
111// correct result is placed in the destination registers before they are used.
112//
113// This pass implements two fixes:
114// 1) fixing the FSQRTS and FSQRTD instructions.
115// 2) fixing the FDIVS and FDIVD instructions.
116//
117// FSQRTS and FDIVS are converted to FDIVD and FSQRTD respectively earlier in
118// the pipeline when this option is enabled, so this pass needs only to deal
119// with the changes that still need implementing for the "double" versions
120// of these instructions.
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000121//
122char FixAllFDIVSQRT::ID = 0;
123
Francis Visoiu Mistrih8b617642017-05-18 17:21:13 +0000124FixAllFDIVSQRT::FixAllFDIVSQRT() : LEONMachineFunctionPass(ID) {}
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000125
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000126bool FixAllFDIVSQRT::runOnMachineFunction(MachineFunction &MF) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000127 Subtarget = &MF.getSubtarget<SparcSubtarget>();
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000128 const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000129 DebugLoc DL = DebugLoc();
130
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000131 bool Modified = false;
132 for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
133 MachineBasicBlock &MBB = *MFI;
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000134 for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000135 MachineInstr &MI = *MBBI;
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000136 unsigned Opcode = MI.getOpcode();
137
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000138 // Note: FDIVS and FSQRTS cannot be generated when this erratum fix is
139 // switched on so we don't need to check for them here. They will
140 // already have been converted to FSQRTD or FDIVD earlier in the
141 // pipeline.
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000142 if (Opcode == SP::FSQRTD || Opcode == SP::FDIVD) {
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000143 for (int InsertedCount = 0; InsertedCount < 5; InsertedCount++)
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000144 BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
145
146 MachineBasicBlock::iterator NMBBI = std::next(MBBI);
Chris Dewhurst2bad85c2016-06-27 14:19:19 +0000147 for (int InsertedCount = 0; InsertedCount < 28; InsertedCount++)
Chris Dewhurst0c1e0022016-06-19 11:03:28 +0000148 BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
149
150 Modified = true;
151 }
152 }
153 }
154
155 return Modified;
156}