diff options
author | Peter Trommler <ptrommler@acm.org> | 2021-03-20 23:28:52 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-03-23 08:09:40 -0400 |
commit | 26ba86f73c9125c03968aec88be919bdd6a2152b (patch) | |
tree | 7d82fd5f1261007d896a6a8432d5f376dc6ac0d6 /compiler/GHC/CmmToAsm | |
parent | 26dd1f887319c7b62bcfbd85a3727f94088a6852 (diff) | |
download | haskell-26ba86f73c9125c03968aec88be919bdd6a2152b.tar.gz |
PPC NCG: Fix int to float conversion
In commit 540fa6b2 integer to float conversions were changed to round to
the nearest even. Implement a special case for 64 bit integer to single
precision floating point numbers.
Fixes #19563.
Diffstat (limited to 'compiler/GHC/CmmToAsm')
-rw-r--r-- | compiler/GHC/CmmToAsm/PPC/CodeGen.hs | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/compiler/GHC/CmmToAsm/PPC/CodeGen.hs b/compiler/GHC/CmmToAsm/PPC/CodeGen.hs index 1111917de8..0a78722c85 100644 --- a/compiler/GHC/CmmToAsm/PPC/CodeGen.hs +++ b/compiler/GHC/CmmToAsm/PPC/CodeGen.hs @@ -2381,6 +2381,10 @@ coerceInt2FP' ArchPPC fromRep toRep x = do coerceInt2FP' (ArchPPC_64 _) fromRep toRep x = do (src, code) <- getSomeReg x platform <- getPlatform + upper <- getNewRegNat II64 + lower <- getNewRegNat II64 + l1 <- getBlockIdNat + l2 <- getBlockIdNat let code' dst = code `appOL` maybe_exts `appOL` toOL [ ST II64 src (spRel platform 3), @@ -2388,12 +2392,28 @@ coerceInt2FP' (ArchPPC_64 _) fromRep toRep x = do FCFID dst dst ] `appOL` maybe_frsp dst - maybe_exts = case fromRep of - W8 -> unitOL $ EXTS II8 src src - W16 -> unitOL $ EXTS II16 src src - W32 -> unitOL $ EXTS II32 src src - W64 -> nilOL - _ -> panic "PPC.CodeGen.coerceInt2FP: no match" + maybe_exts + = case fromRep of + W8 -> unitOL $ EXTS II8 src src + W16 -> unitOL $ EXTS II16 src src + W32 -> unitOL $ EXTS II32 src src + W64 -> case toRep of + W32 -> toOL [ SRA II64 upper src (RIImm (ImmInt 53)) + , CLRLI II64 lower src 53 + , ADD upper upper (RIImm (ImmInt 1)) + , ADD lower lower (RIImm (ImmInt 2047)) + , CMPL II64 upper (RIImm (ImmInt 2)) + , OR lower lower (RIReg src) + , CLRRI II64 lower lower 11 + , BCC LTT l2 Nothing + , BCC ALWAYS l1 Nothing + , NEWBLOCK l1 + , MR src lower + , BCC ALWAYS l2 Nothing + , NEWBLOCK l2 + ] + _ -> nilOL + _ -> panic "PPC.CodeGen.coerceInt2FP: no match" maybe_frsp dst = case toRep of |