From f482d3d3387549bc319d2ef67bd98e261c9dac42 Mon Sep 17 00:00:00 2001 From: Venkatraman Govindaraju Date: Sun, 6 Oct 2013 07:06:44 +0000 Subject: [Sparc] Do not emit nop after fcmp* instruction with V9. llvm-svn: 192056 --- llvm/lib/Target/Sparc/DelaySlotFiller.cpp | 17 +++++++++++++++-- llvm/lib/Target/Sparc/SparcInstrInfo.td | 12 +++++++----- 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'llvm/lib/Target/Sparc') diff --git a/llvm/lib/Target/Sparc/DelaySlotFiller.cpp b/llvm/lib/Target/Sparc/DelaySlotFiller.cpp index b101751e707..4ae6407b1f4 100644 --- a/llvm/lib/Target/Sparc/DelaySlotFiller.cpp +++ b/llvm/lib/Target/Sparc/DelaySlotFiller.cpp @@ -14,6 +14,7 @@ #define DEBUG_TYPE "delay-slot-filler" #include "Sparc.h" +#include "SparcSubtarget.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -39,10 +40,13 @@ namespace { /// layout, etc. /// TargetMachine &TM; + const SparcSubtarget *Subtarget; static char ID; Filler(TargetMachine &tm) - : MachineFunctionPass(ID), TM(tm) { } + : MachineFunctionPass(ID), TM(tm), + Subtarget(&TM.getSubtarget()) { + } virtual const char *getPassName() const { return "SPARC Delay Slot Filler"; @@ -102,6 +106,8 @@ FunctionPass *llvm::createSparcDelaySlotFillerPass(TargetMachine &tm) { bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { bool Changed = false; + const TargetInstrInfo *TII = TM.getInstrInfo(); + for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) { MachineBasicBlock::iterator MI = I; ++I; @@ -114,6 +120,14 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { continue; } + if (!Subtarget->isV9() && + (MI->getOpcode() == SP::FCMPS || MI->getOpcode() == SP::FCMPD + || MI->getOpcode() == SP::FCMPQ)) { + BuildMI(MBB, I, MI->getDebugLoc(), TII->get(SP::NOP)); + Changed = true; + continue; + } + // If MI has no delay slot, skip. if (!MI->hasDelaySlot()) continue; @@ -126,7 +140,6 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { ++FilledSlots; Changed = true; - const TargetInstrInfo *TII = TM.getInstrInfo(); if (D == MBB.end()) BuildMI(MBB, I, MI->getDebugLoc(), TII->get(SP::NOP)); else diff --git a/llvm/lib/Target/Sparc/SparcInstrInfo.td b/llvm/lib/Target/Sparc/SparcInstrInfo.td index 470de70b457..e6a9cf53d18 100644 --- a/llvm/lib/Target/Sparc/SparcInstrInfo.td +++ b/llvm/lib/Target/Sparc/SparcInstrInfo.td @@ -807,20 +807,22 @@ def FDIVQ : F3_3<2, 0b110100, 0b001001111, // Floating-point Compare Instructions, p. 148 // Note: the 2nd template arg is different for these guys. // Note 2: the result of a FCMP is not available until the 2nd cycle -// after the instr is retired, but there is no interlock. This behavior -// is modelled with a forced noop after the instruction. +// after the instr is retired, but there is no interlock in Sparc V8. +// This behavior is modeled with a forced noop after the instruction in +// DelaySlotFiller. + let Defs = [FCC] in { def FCMPS : F3_3c<2, 0b110101, 0b001010001, (outs), (ins FPRegs:$src1, FPRegs:$src2), - "fcmps $src1, $src2\n\tnop", + "fcmps $src1, $src2", [(SPcmpfcc f32:$src1, f32:$src2)]>; def FCMPD : F3_3c<2, 0b110101, 0b001010010, (outs), (ins DFPRegs:$src1, DFPRegs:$src2), - "fcmpd $src1, $src2\n\tnop", + "fcmpd $src1, $src2", [(SPcmpfcc f64:$src1, f64:$src2)]>; def FCMPQ : F3_3c<2, 0b110101, 0b001010011, (outs), (ins QFPRegs:$src1, QFPRegs:$src2), - "fcmpq $src1, $src2\n\tnop", + "fcmpq $src1, $src2", [(SPcmpfcc f128:$src1, f128:$src2)]>, Requires<[HasHardQuad]>; } -- cgit v1.2.3