[commit: ghc] master: x86: promote arguments to C functions according to the ABI (#7383) (085e814)

Ian Lynagh igloo at earth.li
Sat Feb 23 20:27:31 CET 2013


Repository : ssh://darcs.haskell.org//srv/darcs/ghc

On branch  : master

http://hackage.haskell.org/trac/ghc/changeset/085e8145f63c8f42d8bc19cd3cff52b8cd5b6455

>---------------------------------------------------------------

commit 085e8145f63c8f42d8bc19cd3cff52b8cd5b6455
Author: Simon Marlow <marlowsd at gmail.com>
Date:   Wed Feb 20 11:43:33 2013 +0000

    x86: promote arguments to C functions according to the ABI (#7383)
    
    I don't think the x86-64 version is quite right, but this ought to be
    enough to pass cgrun071.
    
    This code is terrible and needs a complete refactor.  There's a lot of
    duplication, and we ought to be specifying the ABI in a much more
    abstract way (like LLVM).

>---------------------------------------------------------------

 compiler/nativeGen/X86/CodeGen.hs |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/compiler/nativeGen/X86/CodeGen.hs b/compiler/nativeGen/X86/CodeGen.hs
index c6cdd8a..36aebea 100644
--- a/compiler/nativeGen/X86/CodeGen.hs
+++ b/compiler/nativeGen/X86/CodeGen.hs
@@ -1820,6 +1820,8 @@ genCCall32' :: DynFlags
             -> NatM InstrBlock
 genCCall32' dflags target dest_regs args = do
         let
+            prom_args = map (maybePromoteCArg dflags W32) args
+
             -- Align stack to 16n for calls, assuming a starting stack
             -- alignment of 16n - word_size on procedure entry. Which we
             -- maintiain. See Note [rts/StgCRun.c : Stack Alignment on X86]
@@ -1831,7 +1833,7 @@ genCCall32' dflags target dest_regs args = do
         setDeltaNat (delta0 - arg_pad_size)
 
         use_sse2 <- sse2Enabled
-        push_codes <- mapM (push_arg use_sse2) (reverse args)
+        push_codes <- mapM (push_arg use_sse2) (reverse prom_args)
         delta <- getDeltaNat
         MASSERT (delta == delta0 - tot_arg_size)
 
@@ -2055,12 +2057,14 @@ genCCall64' :: DynFlags
             -> NatM InstrBlock
 genCCall64' dflags target dest_regs args = do
     -- load up the register arguments
+    let prom_args = map (maybePromoteCArg dflags W32) args
+
     (stack_args, int_regs_used, fp_regs_used, load_args_code)
          <-
         if platformOS platform == OSMinGW32
-        then load_args_win args [] [] (allArgRegs platform) nilOL
+        then load_args_win prom_args [] [] (allArgRegs platform) nilOL
         else do (stack_args, aregs, fregs, load_args_code)
-                    <- load_args args (allIntArgRegs platform) (allFPArgRegs platform) nilOL
+                    <- load_args prom_args (allIntArgRegs platform) (allFPArgRegs platform) nilOL
                 let fp_regs_used  = reverse (drop (length fregs) (reverse (allFPArgRegs platform)))
                     int_regs_used = reverse (drop (length aregs) (reverse (allIntArgRegs platform)))
                 return (stack_args, int_regs_used, fp_regs_used, load_args_code)
@@ -2231,9 +2235,6 @@ genCCall64' dflags target dest_regs args = do
              push_args rest code'
 
            | otherwise = do
-           -- we only ever generate word-sized function arguments.  Promotion
-           -- has already happened: our Int8# type is kept sign-extended
-           -- in an Int#, for example.
              ASSERT(width == W64) return ()
              (arg_op, arg_code) <- getOperand arg
              delta <- getDeltaNat
@@ -2253,6 +2254,13 @@ genCCall64' dflags target dest_regs args = do
                          SUB II64 (OpImm (ImmInt (n * wORD_SIZE dflags))) (OpReg rsp),
                          DELTA (delta - n * arg_size)]
 
+maybePromoteCArg :: DynFlags -> Width -> CmmExpr -> CmmExpr
+maybePromoteCArg dflags wto arg
+ | wfrom < wto = CmmMachOp (MO_UU_Conv wfrom wto) [arg]
+ | otherwise   = arg
+ where
+   wfrom = cmmExprWidth dflags arg
+
 -- | We're willing to inline and unroll memcpy/memset calls that touch
 -- at most these many bytes.  This threshold is the same as the one
 -- used by GCC and LLVM.





More information about the ghc-commits mailing list