PPC NCG: Lower MO_*_Fabs as PowerPC fabs instruction
authorPeter Trommler <ptrommler@acm.org>
Mon, 1 May 2017 15:17:25 +0000 (11:17 -0400)
committerBen Gamari <ben@smart-cactus.org>
Mon, 1 May 2017 15:17:40 +0000 (11:17 -0400)
In Phab:D3265 we introduced MO_F32_Fabs and MO_F64_Fabs.
This patch improves code generation by generating PowerPC fabs
instructions.

Test Plan: run numeric/should_run/numrun015 or validate

Reviewers: austin, bgamari, hvr, simonmar, erikd

Reviewed By: erikd

Subscribers: rwbarton, thomie

Differential Revision: https://phabricator.haskell.org/D3512

compiler/codeGen/StgCmmPrim.hs
compiler/nativeGen/PPC/CodeGen.hs
compiler/nativeGen/PPC/Instr.hs
compiler/nativeGen/PPC/Ppr.hs

index 235109f..e0a68f6 100644 (file)
@@ -852,10 +852,12 @@ callishPrimOpSupported dflags op
                                || ppc)
                          || llvm      -> Left (MO_U_Mul2     (wordWidth dflags))
                      | otherwise      -> Right genericWordMul2Op
-      FloatFabsOp    | (ncg && x86ish)
+      FloatFabsOp    | (ncg && x86ish
+                               || ppc)
                          || llvm      -> Left MO_F32_Fabs
                      | otherwise      -> Right $ genericFabsOp W32
-      DoubleFabsOp   | (ncg && x86ish)
+      DoubleFabsOp   | (ncg && x86ish
+                               || ppc)
                          || llvm      -> Left MO_F64_Fabs
                      | otherwise      -> Right $ genericFabsOp W64
 
index 1467267..a1a205b 100644 (file)
@@ -1233,6 +1233,8 @@ genCCall target dest_regs argsAndHints
                                                    dest_regs argsAndHints
         PrimTarget (MO_SubIntC width) -> addSubCOp SUBFO platform width
                                                    dest_regs argsAndHints
+        PrimTarget MO_F64_Fabs -> fabs platform dest_regs argsAndHints
+        PrimTarget MO_F32_Fabs -> fabs platform dest_regs argsAndHints
         _ -> genCCall' dflags (platformToGCP platform)
                        target dest_regs argsAndHints
         where divOp1 platform signed width [res_q, res_r] [arg_x, arg_y]
@@ -1444,6 +1446,12 @@ genCCall target dest_regs argsAndHints
                                          ]
               addSubCOp _ _ _ _ _
                 = panic "genCall: Wrong number of arguments/results for addC"
+              fabs platform [res] [arg]
+                = do let res_r = getRegisterReg platform (CmmLocal res)
+                     (arg_reg, arg_code) <- getSomeReg arg
+                     return $ arg_code `snocOL` FABS res_r arg_reg
+              fabs _ _ _
+                = panic "genCall: Wrong number of arguments/results for fabs"
 
 -- TODO: replace 'Int' by an enum such as 'PPC_64ABI'
 data GenCCallPlatform = GCPLinux | GCPDarwin | GCPLinux64ELF !Int | GCPAIX
index e395b38..b8b5043 100644 (file)
@@ -254,6 +254,7 @@ data Instr
     | FSUB    Format Reg Reg Reg
     | FMUL    Format Reg Reg Reg
     | 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.
 
     | FCMP    Reg Reg
@@ -342,6 +343,7 @@ ppc_regUsageOfInstr platform instr
     FSUB    _ r1 r2 r3      -> usage ([r2,r3], [r1])
     FMUL    _ r1 r2 r3      -> usage ([r2,r3], [r1])
     FDIV    _ r1 r2 r3      -> usage ([r2,r3], [r1])
+    FABS    r1 r2           -> usage ([r2], [r1])
     FNEG    r1 r2           -> usage ([r2], [r1])
     FCMP    r1 r2           -> usage ([r1,r2], [])
     FCTIWZ  r1 r2           -> usage ([r2], [r1])
@@ -436,6 +438,7 @@ ppc_patchRegsOfInstr instr env
     FSUB    fmt r1 r2 r3    -> FSUB fmt (env r1) (env r2) (env r3)
     FMUL    fmt r1 r2 r3    -> FMUL fmt (env r1) (env r2) (env r3)
     FDIV    fmt r1 r2 r3    -> FDIV fmt (env r1) (env r2) (env r3)
+    FABS    r1 r2           -> FABS (env r1) (env r2)
     FNEG    r1 r2           -> FNEG (env r1) (env r2)
     FCMP    r1 r2           -> FCMP (env r1) (env r2)
     FCTIWZ  r1 r2           -> FCTIWZ (env r1) (env r2)
index 025dfaf..7f30c5b 100644 (file)
@@ -870,6 +870,7 @@ pprInstr (FADD fmt reg1 reg2 reg3) = pprBinaryF (sLit "fadd") fmt reg1 reg2 reg3
 pprInstr (FSUB fmt reg1 reg2 reg3) = pprBinaryF (sLit "fsub") fmt reg1 reg2 reg3
 pprInstr (FMUL fmt reg1 reg2 reg3) = pprBinaryF (sLit "fmul") fmt reg1 reg2 reg3
 pprInstr (FDIV fmt reg1 reg2 reg3) = pprBinaryF (sLit "fdiv") fmt reg1 reg2 reg3
+pprInstr (FABS reg1 reg2) = pprUnary (sLit "fabs") reg1 reg2
 pprInstr (FNEG reg1 reg2) = pprUnary (sLit "fneg") reg1 reg2
 
 pprInstr (FCMP reg1 reg2) = hcat [