From 29c47f24687689192837b711045ad1dd9828bc7b Mon Sep 17 00:00:00 2001 From: simonmar Date: Mon, 11 Apr 2005 08:53:39 +0000 Subject: [PATCH] [project @ 2005-04-11 08:53:39 by simonmar] A couple of optimisations to float code --- ghc/compiler/nativeGen/MachCodeGen.hs | 56 +++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/ghc/compiler/nativeGen/MachCodeGen.hs b/ghc/compiler/nativeGen/MachCodeGen.hs index 077eeed..d911c24 100644 --- a/ghc/compiler/nativeGen/MachCodeGen.hs +++ b/ghc/compiler/nativeGen/MachCodeGen.hs @@ -1997,6 +1997,12 @@ getAmode other getNonClobberedOperand :: CmmExpr -> NatM (Operand, InstrBlock) getNonClobberedOperand (CmmLit lit) + | isSuitableFloatingPointLit lit = do + lbl <- getNewLabelNat + let code = unitOL (LDATA ReadOnlyData [CmmDataLabel lbl, + CmmStaticLit lit]) + return (OpAddr (ripRel (ImmCLbl lbl)), code) +getNonClobberedOperand (CmmLit lit) | not (is64BitLit lit) && not (isFloatingRep (cmmLitRep lit)) = return (OpImm (litToImm lit), nilOL) getNonClobberedOperand (CmmLoad mem pk) @@ -2025,22 +2031,35 @@ regClobbered _ = False -- computation of an arbitrary expression. getOperand :: CmmExpr -> NatM (Operand, InstrBlock) getOperand (CmmLit lit) - | not (is64BitLit lit) && not (isFloatingRep (cmmLitRep lit)) = + | isSuitableFloatingPointLit lit = do + lbl <- getNewLabelNat + let code = unitOL (LDATA ReadOnlyData [CmmDataLabel lbl, + CmmStaticLit lit]) + return (OpAddr (ripRel (ImmCLbl lbl)), code) +getOperand (CmmLit lit) + | not (is64BitLit lit) && not (isFloatingRep (cmmLitRep lit)) = do return (OpImm (litToImm lit), nilOL) getOperand (CmmLoad mem pk) | IF_ARCH_i386(not (isFloatingRep pk) && pk /= I64, True) = do Amode src mem_code <- getAmode mem return (OpAddr src, mem_code) getOperand e = do - (reg, code) <- getNonClobberedReg e + (reg, code) <- getSomeReg e return (OpReg reg, code) isOperand :: CmmExpr -> Bool isOperand (CmmLoad _ _) = True -isOperand (CmmLit lit) = not (is64BitLit lit) && - not (isFloatingRep (cmmLitRep lit)) +isOperand (CmmLit lit) = not (is64BitLit lit) + || isSuitableFloatingPointLit lit isOperand _ = False +-- if we want a floating-point literal as an operand, we can +-- use it directly from memory. However, if the literal is +-- zero, we're better off generating it into a register using +-- xor. +isSuitableFloatingPointLit (CmmFloat f _) = f /= 0.0 +isSuitableFloatingPointLit _ = False + getRegOrMem :: CmmExpr -> NatM (Operand, InstrBlock) getRegOrMem (CmmLoad mem pk) | IF_ARCH_i386(not (isFloatingRep pk) && pk /= I64, True) = do @@ -4277,7 +4296,10 @@ trivialCode rep instr (Just revinstr) (CmmLit lit_a) b -- in return (Any rep code) -trivialCode rep instr maybe_revinstr a b = do +trivialCode rep instr maybe_revinstr a b = genTrivialCode rep instr a b + +-- This is re-used for floating pt instructions too. +genTrivialCode rep instr a b = do (b_op, b_code) <- getNonClobberedOperand b a_code <- getAnyReg a tmp <- getNewRegNat rep @@ -4289,7 +4311,7 @@ trivialCode rep instr maybe_revinstr a b = do -- as the destination reg. In this case, we have to save b in a -- new temporary across the computation of a. code dst - | dst `clashesWith` b_op = + | dst `regClashesWithOp` b_op = b_code `appOL` unitOL (MOV rep b_op (OpReg tmp)) `appOL` a_code dst `snocOL` @@ -4300,10 +4322,10 @@ trivialCode rep instr maybe_revinstr a b = do instr b_op (OpReg dst) -- in return (Any rep code) - where - reg `clashesWith` OpReg reg2 = reg == reg2 - reg `clashesWith` OpAddr amode = any (==reg) (addrModeRegs amode) - reg `clashesWith` _ = False + +reg `regClashesWithOp` OpReg reg2 = reg == reg2 +reg `regClashesWithOp` OpAddr amode = any (==reg) (addrModeRegs amode) +reg `regClashesWithOp` _ = False ----------- @@ -4335,19 +4357,7 @@ trivialFCode pk instr x y = do #if x86_64_TARGET_ARCH --- We use the 2-operand SSE2 floating pt instructions. ToDo: improve on --- this by using some of the special cases in trivialCode above. -trivialFCode pk instr x y = do - (y_reg, y_code) <- getNonClobberedReg y -- these work for float regs too - x_code <- getAnyReg x - let - code dst = - y_code `appOL` - x_code dst `snocOL` - instr pk (IF_ARCH_x86_64(OpReg,) y_reg) - (IF_ARCH_x86_64(OpReg,) dst) - -- in - return (Any pk code) +trivialFCode pk instr x y = genTrivialCode pk (instr pk) x y #endif -- 1.7.10.4