diff --git a/lib/Target/SparcV8/FPMover.cpp b/lib/Target/SparcV8/FPMover.cpp index feeadc52a79..af11eb8f7f7 100644 --- a/lib/Target/SparcV8/FPMover.cpp +++ b/lib/Target/SparcV8/FPMover.cpp @@ -84,27 +84,39 @@ bool FPMover::runOnMachineBasicBlock(MachineBasicBlock &MBB) { bool Changed = false; for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ) { MachineInstr *MI = I++; - if (MI->getOpcode() == V8::FpMOVD) { + if (MI->getOpcode() == V8::FpMOVD || MI->getOpcode() == V8::FpABSD || + MI->getOpcode() == V8::FpNEGD) { + Changed = true; unsigned DestDReg = MI->getOperand(0).getReg(); unsigned SrcDReg = MI->getOperand(1).getReg(); - if (DestDReg != SrcDReg || MI->getOpcode() != V8::FpMOVD) { - unsigned EvenSrcReg = 0, OddSrcReg = 0, EvenDestReg = 0, OddDestReg = 0; - getDoubleRegPair(DestDReg, EvenDestReg, OddDestReg); - getDoubleRegPair(SrcDReg, EvenSrcReg, OddSrcReg); + if (DestDReg == SrcDReg && MI->getOpcode() == V8::FpMOVD) { + MBB.erase(MI); // Eliminate the noop copy. + ++NoopFpDs; + continue; + } + + unsigned EvenSrcReg = 0, OddSrcReg = 0, EvenDestReg = 0, OddDestReg = 0; + getDoubleRegPair(DestDReg, EvenDestReg, OddDestReg); + getDoubleRegPair(SrcDReg, EvenSrcReg, OddSrcReg); - I->setOpcode(V8::FMOVS); - I->SetMachineOperandReg(0, EvenDestReg); - I->SetMachineOperandReg(1, EvenSrcReg); - DEBUG(std::cerr << "FPMover: the modified instr is: " << *I); - // Insert copy for the other half of the double: + if (MI->getOpcode() == V8::FpMOVD) + MI->setOpcode(V8::FMOVS); + else if (MI->getOpcode() == V8::FpNEGD) + MI->setOpcode(V8::FNEGS); + else if (MI->getOpcode() == V8::FpABSD) + MI->setOpcode(V8::FABSS); + else + assert(0 && "Unknown opcode!"); + + MI->SetMachineOperandReg(0, EvenDestReg); + MI->SetMachineOperandReg(1, EvenSrcReg); + DEBUG(std::cerr << "FPMover: the modified instr is: " << *MI); + // Insert copy for the other half of the double. + if (DestDReg != SrcDReg) { MI = BuildMI(MBB, I, V8::FMOVS, 1, OddDestReg).addReg(OddSrcReg); DEBUG(std::cerr << "FPMover: the inserted instr is: " << *MI); - ++NumFpDs; - } else { - MBB.erase(MI); - ++NoopFpDs; } - Changed = true; + ++NumFpDs; } } return Changed; diff --git a/lib/Target/SparcV8/SparcV8InstrInfo.td b/lib/Target/SparcV8/SparcV8InstrInfo.td index 3c9b8d43358..e6506ca6aa7 100644 --- a/lib/Target/SparcV8/SparcV8InstrInfo.td +++ b/lib/Target/SparcV8/SparcV8InstrInfo.td @@ -118,8 +118,17 @@ def IMPLICIT_DEF_FP : Pseudo<(ops FPRegs:$dst), "!IMPLICIT_DEF $dst", [(set FPRegs:$dst, (undef))]>; def IMPLICIT_DEF_DFP : Pseudo<(ops DFPRegs:$dst), "!IMPLICIT_DEF $dst", [(set DFPRegs:$dst, (undef))]>; + +// FpMOVD/FpNEGD/FpABSD - These are lowered to single-precision ops by the +// fpmover pass. def FpMOVD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src), - "!FpMOVD", []>; // pseudo 64-bit double move + "!FpMOVD $src, $dst", []>; // pseudo 64-bit double move +def FpNEGD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src), + "!FpNEGD $src, $dst", + [(set DFPRegs:$dst, (fneg DFPRegs:$src))]>; +def FpABSD : Pseudo<(ops DFPRegs:$dst, DFPRegs:$src), + "!FpABSD $src, $dst", + [(set DFPRegs:$dst, (fabs DFPRegs:$src))]>; // SELECT_CC_* - Used to implement the SELECT_CC DAG operation. Expanded by the // scheduler into a branch sequence. This has to handle all permutations of @@ -624,7 +633,6 @@ def FABSS : F3_3<2, 0b110100, 0b000001001, (ops FPRegs:$dst, FPRegs:$src), "fabss $src, $dst", [(set FPRegs:$dst, (fabs FPRegs:$src))]>; -// FIXME: ADD FNEGD/FABSD pseudo instructions. // Floating-point Square Root Instructions, p.145