From 4bb4a1cfa8b88fefae3405d101dc6ff0f7adbae3 Mon Sep 17 00:00:00 2001 From: David Terei Date: Mon, 21 Jun 2010 12:36:06 +0000 Subject: [PATCH] Fix negate op not working for -0 in llvm backend --- compiler/llvmGen/Llvm/Types.hs | 22 +++++++--------------- compiler/llvmGen/LlvmCodeGen/CodeGen.hs | 5 +++-- compiler/llvmGen/LlvmCodeGen/Data.hs | 2 +- 3 files changed, 11 insertions(+), 18 deletions(-) diff --git a/compiler/llvmGen/Llvm/Types.hs b/compiler/llvmGen/Llvm/Types.hs index 9275c07..a0b0032 100644 --- a/compiler/llvmGen/Llvm/Types.hs +++ b/compiler/llvmGen/Llvm/Types.hs @@ -95,7 +95,7 @@ data LlvmLit -- | Refers to an integer constant (i64 42). = LMIntLit Integer LlvmType -- | Floating point literal - | LMFloatLit Rational LlvmType + | LMFloatLit Double LlvmType deriving (Eq) instance Show LlvmLit where @@ -191,12 +191,8 @@ getPlainName (LMLitVar x ) = getLit x -- | Print a literal value. No type. getLit :: LlvmLit -> String -getLit (LMIntLit i _) = show ((fromInteger i)::Int) --- In Llvm float literals can be printed in a big-endian hexadecimal format, --- regardless of underlying architecture. -getLit (LMFloatLit r LMFloat) = fToStr $ fromRational r -getLit (LMFloatLit r LMDouble) = dToStr $ fromRational r -getLit l = error $ "getLit: Usupported LlvmLit type! " ++ show (getLitType l) +getLit (LMIntLit i _) = show ((fromInteger i)::Int) +getLit (LMFloatLit r _) = dToStr r -- | Return the 'LlvmType' of the 'LlvmVar' getVarType :: LlvmVar -> LlvmType @@ -695,11 +691,9 @@ instance Show LlvmCastOp where -- * Floating point conversion -- --- | Convert a Haskell Float to an LLVM hex encoded floating point form -fToStr :: Float -> String -fToStr f = dToStr $ realToFrac f - --- | Convert a Haskell Double to an LLVM hex encoded floating point form +-- | Convert a Haskell Double to an LLVM hex encoded floating point form. In +-- Llvm float literals can be printed in a big-endian hexadecimal format, +-- regardless of underlying architecture. dToStr :: Double -> String dToStr d = let bs = doubleToBytes d @@ -712,9 +706,7 @@ dToStr d str = map toUpper $ concat . fixEndian . (map hex) $ bs in "0x" ++ str --- | Reverse or leave byte data alone to fix endianness on this --- target. LLVM generally wants things in Big-Endian form --- regardless of target architecture. +-- | Reverse or leave byte data alone to fix endianness on this target. fixEndian :: [a] -> [a] #ifdef WORDS_BIGENDIAN fixEndian = id diff --git a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs index 075a731..f5c71ab 100644 --- a/compiler/llvmGen/LlvmCodeGen/CodeGen.hs +++ b/compiler/llvmGen/LlvmCodeGen/CodeGen.hs @@ -558,7 +558,7 @@ genMachOp env _ op [x] = case op of in negate (widthToLlvmInt w) all0 LM_MO_Sub MO_F_Neg w -> - let all0 = LMLitVar $ LMFloatLit 0 (widthToLlvmFloat w) + let all0 = LMLitVar $ LMFloatLit (-0) (widthToLlvmFloat w) in negate (widthToLlvmFloat w) all0 LM_MO_Sub MO_SF_Conv _ w -> fiConv (widthToLlvmFloat w) LM_Sitofp @@ -807,7 +807,8 @@ genLit env (CmmInt i w) = return (env, mkIntLit i (LMInt $ widthInBits w), nilOL, []) genLit env (CmmFloat r w) - = return (env, LMLitVar $ LMFloatLit r (widthToLlvmFloat w), nilOL, []) + = return (env, LMLitVar $ LMFloatLit (fromRational r) (widthToLlvmFloat w), + nilOL, []) genLit env cmm@(CmmLabel l) = let label = strCLabel_llvm l diff --git a/compiler/llvmGen/LlvmCodeGen/Data.hs b/compiler/llvmGen/LlvmCodeGen/Data.hs index 69cd0e7..e3d2adc 100644 --- a/compiler/llvmGen/LlvmCodeGen/Data.hs +++ b/compiler/llvmGen/LlvmCodeGen/Data.hs @@ -168,7 +168,7 @@ genStaticLit (CmmInt i w) = Right $ LMStaticLit (LMIntLit i (LMInt $ widthInBits w)) genStaticLit (CmmFloat r w) - = Right $ LMStaticLit (LMFloatLit r (widthToLlvmFloat w)) + = Right $ LMStaticLit (LMFloatLit (fromRational r) (widthToLlvmFloat w)) -- Leave unresolved, will fix later genStaticLit c@(CmmLabel _ ) = Left $ c -- 1.7.10.4