05e47a1
From 35a897782b6b0a252da7fdcf4921198ad4e1d96c Mon Sep 17 00:00:00 2001
05e47a1
From: James Clarke <jrtc27@jrtc27.com>
05e47a1
Date: Thu, 22 Nov 2018 11:55:17 -0500
05e47a1
Subject: [PATCH] UNREG: PprC: Add support for adjacent floats
05e47a1
05e47a1
When two 32-bit floats are adjacent for a 64-bit target, there is no
05e47a1
padding between them to force alignment, so we must combine their bit
05e47a1
representations into a single word.
05e47a1
05e47a1
Reviewers: bgamari, simonmar
05e47a1
05e47a1
Reviewed By: simonmar
05e47a1
05e47a1
Subscribers: rwbarton, carter
05e47a1
05e47a1
GHC Trac Issues: #15853
05e47a1
05e47a1
Differential Revision: https://phabricator.haskell.org/D5306
05e47a1
---
05e47a1
 compiler/cmm/PprC.hs | 24 +++++++++++++++++++++++-
05e47a1
 1 file changed, 23 insertions(+), 1 deletion(-)
05e47a1
05e47a1
diff --git a/compiler/cmm/PprC.hs b/compiler/cmm/PprC.hs
05e47a1
index 17fef7fc97..6ebfd20291 100644
05e47a1
--- a/compiler/cmm/PprC.hs
05e47a1
+++ b/compiler/cmm/PprC.hs
05e47a1
@@ -512,9 +512,12 @@ pprLit1 other = pprLit other
05e47a1
 pprStatics :: DynFlags -> [CmmStatic] -> [SDoc]
05e47a1
 pprStatics _ [] = []
05e47a1
 pprStatics dflags (CmmStaticLit (CmmFloat f W32) : rest)
05e47a1
-  -- floats are padded to a word by padLitToWord, see #1852
05e47a1
+  -- odd numbers of floats are padded to a word by mkVirtHeapOffsetsWithPadding
05e47a1
   | wORD_SIZE dflags == 8, CmmStaticLit (CmmInt 0 W32) : rest' <- rest
05e47a1
   = pprLit1 (floatToWord dflags f) : pprStatics dflags rest'
05e47a1
+  -- adjacent floats aren't padded but combined into a single word
05e47a1
+  | wORD_SIZE dflags == 8, CmmStaticLit (CmmFloat g W32) : rest' <- rest
05e47a1
+  = pprLit1 (floatPairToWord dflags f g) : pprStatics dflags rest'
05e47a1
   | wORD_SIZE dflags == 4
05e47a1
   = pprLit1 (floatToWord dflags f) : pprStatics dflags rest
05e47a1
   | otherwise
05e47a1
@@ -1270,6 +1273,25 @@ floatToWord dflags r
05e47a1
              , wORDS_BIGENDIAN dflags    = 32
05e47a1
              | otherwise                 = 0
05e47a1
 
05e47a1
+floatPairToWord :: DynFlags -> Rational -> Rational -> CmmLit
05e47a1
+floatPairToWord dflags r1 r2
05e47a1
+  = runST (do
05e47a1
+        arr <- newArray_ ((0::Int),1)
05e47a1
+        writeArray arr 0 (fromRational r1)
05e47a1
+        writeArray arr 1 (fromRational r2)
05e47a1
+        arr' <- castFloatToWord32Array arr
05e47a1
+        w32_1 <- readArray arr' 0
05e47a1
+        w32_2 <- readArray arr' 1
05e47a1
+        return (pprWord32Pair w32_1 w32_2)
05e47a1
+    )
05e47a1
+    where pprWord32Pair w32_1 w32_2
05e47a1
+              | wORDS_BIGENDIAN dflags =
05e47a1
+                  CmmInt ((shiftL i1 32) .|. i2) W64
05e47a1
+              | otherwise =
05e47a1
+                  CmmInt ((shiftL i2 32) .|. i1) W64
05e47a1
+              where i1 = toInteger w32_1
05e47a1
+                    i2 = toInteger w32_2
05e47a1
+
05e47a1
 doubleToWords :: DynFlags -> Rational -> [CmmLit]
05e47a1
 doubleToWords dflags r
05e47a1
   = runST (do
05e47a1
-- 
05e47a1
2.19.2
05e47a1