Path: blob/main/contrib/llvm-project/llvm/lib/Target/Sparc/LeonPasses.cpp
35294 views
//===------ LeonPasses.cpp - Define passes specific to LEON ---------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8//9//===----------------------------------------------------------------------===//1011#include "LeonPasses.h"12#include "SparcSubtarget.h"13#include "llvm/CodeGen/MachineBasicBlock.h"14#include "llvm/CodeGen/MachineFunction.h"15#include "llvm/CodeGen/MachineInstr.h"16#include "llvm/CodeGen/MachineInstrBuilder.h"17#include "llvm/Support/raw_ostream.h"1819using namespace llvm;2021LEONMachineFunctionPass::LEONMachineFunctionPass(char &ID)22: MachineFunctionPass(ID) {}2324//*****************************************************************************25//**** InsertNOPLoad pass26//*****************************************************************************27// This pass fixes the incorrectly working Load instructions that exists for28// some earlier versions of the LEON processor line. NOP instructions must29// be inserted after the load instruction to ensure that the Load instruction30// behaves as expected for these processors.31//32// This pass inserts a NOP after any LD or LDF instruction.33//34char InsertNOPLoad::ID = 0;3536InsertNOPLoad::InsertNOPLoad() : LEONMachineFunctionPass(ID) {}3738bool InsertNOPLoad::runOnMachineFunction(MachineFunction &MF) {39Subtarget = &MF.getSubtarget<SparcSubtarget>();40if (!Subtarget->insertNOPLoad())41return false;4243const TargetInstrInfo &TII = *Subtarget->getInstrInfo();44DebugLoc DL = DebugLoc();4546bool Modified = false;47for (MachineBasicBlock &MBB : MF) {48for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {49MachineInstr &MI = *MBBI;50unsigned Opcode = MI.getOpcode();51if (Opcode >= SP::LDDArr && Opcode <= SP::LDrr) {52MachineBasicBlock::iterator NMBBI = std::next(MBBI);53BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));54Modified = true;55}56}57}5859return Modified;60}61626364//*****************************************************************************65//**** DetectRoundChange pass66//*****************************************************************************67// To prevent any explicit change of the default rounding mode, this pass68// detects any call of the fesetround function.69// A warning is generated to ensure the user knows this has happened.70//71// Detects an erratum in UT699 LEON 3 processor7273char DetectRoundChange::ID = 0;7475DetectRoundChange::DetectRoundChange() : LEONMachineFunctionPass(ID) {}7677bool DetectRoundChange::runOnMachineFunction(MachineFunction &MF) {78Subtarget = &MF.getSubtarget<SparcSubtarget>();79if (!Subtarget->detectRoundChange())80return false;8182bool Modified = false;83for (MachineBasicBlock &MBB : MF) {84for (MachineInstr &MI : MBB) {85unsigned Opcode = MI.getOpcode();86if (Opcode == SP::CALL && MI.getNumOperands() > 0) {87MachineOperand &MO = MI.getOperand(0);8889if (MO.isGlobal()) {90StringRef FuncName = MO.getGlobal()->getName();91if (FuncName.compare_insensitive("fesetround") == 0) {92errs() << "Error: You are using the detectroundchange "93"option to detect rounding changes that will "94"cause LEON errata. The only way to fix this "95"is to remove the call to fesetround from "96"the source code.\n";97}98}99}100}101}102103return Modified;104}105106//*****************************************************************************107//**** FixAllFDIVSQRT pass108//*****************************************************************************109// This pass fixes the incorrectly working FDIVx and FSQRTx instructions that110// exist for some earlier versions of the LEON processor line. Five NOP111// instructions need to be inserted after these instructions to ensure the112// correct result is placed in the destination registers before they are used.113//114// This pass implements two fixes:115// 1) fixing the FSQRTS and FSQRTD instructions.116// 2) fixing the FDIVS and FDIVD instructions.117//118// FSQRTS and FDIVS are converted to FDIVD and FSQRTD respectively earlier in119// the pipeline when this option is enabled, so this pass needs only to deal120// with the changes that still need implementing for the "double" versions121// of these instructions.122//123char FixAllFDIVSQRT::ID = 0;124125FixAllFDIVSQRT::FixAllFDIVSQRT() : LEONMachineFunctionPass(ID) {}126127bool FixAllFDIVSQRT::runOnMachineFunction(MachineFunction &MF) {128Subtarget = &MF.getSubtarget<SparcSubtarget>();129if (!Subtarget->fixAllFDIVSQRT())130return false;131132const TargetInstrInfo &TII = *Subtarget->getInstrInfo();133DebugLoc DL = DebugLoc();134135bool Modified = false;136for (MachineBasicBlock &MBB : MF) {137for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {138MachineInstr &MI = *MBBI;139unsigned Opcode = MI.getOpcode();140141// Note: FDIVS and FSQRTS cannot be generated when this erratum fix is142// switched on so we don't need to check for them here. They will143// already have been converted to FSQRTD or FDIVD earlier in the144// pipeline.145if (Opcode == SP::FSQRTD || Opcode == SP::FDIVD) {146for (int InsertedCount = 0; InsertedCount < 5; InsertedCount++)147BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));148149MachineBasicBlock::iterator NMBBI = std::next(MBBI);150for (int InsertedCount = 0; InsertedCount < 28; InsertedCount++)151BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));152153Modified = true;154}155}156}157158return Modified;159}160161162