diff --git a/compiler/GHC/CmmToAsm/PPC/CodeGen.hs b/compiler/GHC/CmmToAsm/PPC/CodeGen.hs index 7105c2c73364ec06e21f21cc4f3b2498e0ccb127..fbca416f20a9a2f1ff668a5692af3f1036ace368 100644 --- a/compiler/GHC/CmmToAsm/PPC/CodeGen.hs +++ b/compiler/GHC/CmmToAsm/PPC/CodeGen.hs @@ -398,7 +398,7 @@ iselExpr64 expr platform <- getPlatform pprPanic "iselExpr64(powerpc)" (pdoc platform expr) - +data MinOrMax = Min | Max getRegister :: CmmExpr -> NatM Register getRegister e = do config <- getConfig @@ -589,8 +589,9 @@ getRegister' _ _ (CmmMachOp mop [x, y]) -- dyadic PrimOps MO_F_Sub w -> triv_float w FSUB MO_F_Mul w -> triv_float w FMUL MO_F_Quot w -> triv_float w FDIV - MO_F_Min w -> triv_float w FMIN - MO_F_Max w -> triv_float w FMAX + + MO_F_Min w -> minmax_float Min w x y + MO_F_Max w -> minmax_float Max w x y -- optimize addition with 32-bit immediate -- (needed for PIC) @@ -696,6 +697,31 @@ getRegister' _ _ (CmmMachOp mop [x, y]) -- dyadic PrimOps code <- remainderCode rep sgn tmp x y return (Any fmt code) + minmax_float :: MinOrMax -> Width -> CmmExpr -> CmmExpr -> NatM Register + minmax_float m w x y = + do + (src1, src1Code) <- getSomeReg x + (src2, src2Code) <- getSomeReg y + l1 <- getBlockIdNat + l2 <- getBlockIdNat + end <- getBlockIdNat + let cond = case m of + Min -> LTT + Max -> GTT + let code dst = src1Code `appOL` src2Code `appOL` + toOL [ FCMP src1 src2 + , BCC cond l1 Nothing + , BCC ALWAYS l2 Nothing + , NEWBLOCK l2 + , MR dst src2 + , BCC ALWAYS end Nothing + , NEWBLOCK l1 + , MR dst src1 + , BCC ALWAYS end Nothing + , NEWBLOCK end + ] + return (Any (floatFormat w) code) + getRegister' _ _ (CmmMachOp mop [x, y, z]) -- ternary PrimOps = case mop of diff --git a/compiler/GHC/CmmToAsm/PPC/Instr.hs b/compiler/GHC/CmmToAsm/PPC/Instr.hs index 2948d787916851ecf4bfb94c064c5603d7d8119f..a93c77f87cf082d90ccf83e408df7cc2650d87b4 100644 --- a/compiler/GHC/CmmToAsm/PPC/Instr.hs +++ b/compiler/GHC/CmmToAsm/PPC/Instr.hs @@ -277,8 +277,6 @@ data Instr | FDIV Format Reg Reg Reg | FABS Reg Reg -- abs is the same for single and double | FNEG Reg Reg -- negate is the same for single and double prec. - | FMIN Format Reg Reg Reg - | FMAX Format Reg Reg Reg -- | Fused multiply-add instructions. -- diff --git a/compiler/GHC/CmmToAsm/PPC/Ppr.hs b/compiler/GHC/CmmToAsm/PPC/Ppr.hs index 44f7dc95effc3e1a4ebbd4de827a4f11c6bfa197..b5c829164cf6c8e8dded858ba47ca780cce01778 100644 --- a/compiler/GHC/CmmToAsm/PPC/Ppr.hs +++ b/compiler/GHC/CmmToAsm/PPC/Ppr.hs @@ -941,12 +941,6 @@ pprInstr platform instr = case instr of FNEG reg1 reg2 -> pprUnary (text "fneg") reg1 reg2 - FMIN fmt reg1 reg2 reg3 - -> pprBinaryF (text "fmin") fmt reg1 reg2 reg3 - - FMAX fmt reg1 reg2 reg3 - -> pprBinaryF (text "fmax") fmt reg1 reg2 reg3 - FMADD signs fmt dst ra rc rb -> pprTernaryF (pprFMASign signs) fmt dst ra rc rb