[MLton-commit] r6688

Wesley Terpstra wesley at mlton.org
Tue Aug 5 17:16:11 PDT 2008


This patch adds preliminary support for the win64 ABI. This is sufficient to
compile much of the regression suite with native assembly.

The win64 ABI passes at most 4 parameters in registers.
It uses rcx, rdx, r8, and r9 for integers and xmm0-4 for floats.
Unlike on linux, if the 1st parameter is an integer, xmm0 is not used.
eg:
  void foo(int x, float r, float s, int y, int z) =>
  push z
  r9 = y
  xmm2 = s
  xmm1 = r
  rcx = x

Furthermore, parameters passed in registers still reserve space on the stack.
This "shadow space" is always 32 bytes even if there are less parameters.


----------------------------------------------------------------------

U   mlton/trunk/mlton/codegen/amd64-codegen/amd64-codegen.fun
U   mlton/trunk/mlton/codegen/amd64-codegen/amd64-generate-transfers.fun

----------------------------------------------------------------------

Modified: mlton/trunk/mlton/codegen/amd64-codegen/amd64-codegen.fun
===================================================================
--- mlton/trunk/mlton/codegen/amd64-codegen/amd64-codegen.fun	2008-08-06 00:09:45 UTC (rev 6687)
+++ mlton/trunk/mlton/codegen/amd64-codegen/amd64-codegen.fun	2008-08-06 00:16:10 UTC (rev 6688)
@@ -176,6 +176,10 @@
 
         fun outputJumpToSML print =
            let
+              val win64 = case !Control.Target.os of
+                             MLton.Platform.OS.Cygwin => true
+                           | MLton.Platform.OS.MinGW => true
+                           | _ => false
               val jumpToSML = amd64.Label.fromString "MLton_jumpToSML"
               val returnToC = amd64.Label.fromString "Thread_returnToC"
               val {frontierReg, stackTopReg} =
@@ -276,7 +280,9 @@
                    dst = amd64.Operand.register frontierReg,
                    size = amd64.Size.QUAD},
                   amd64.Assembly.instruction_jmp
-                  {target = amd64.Operand.register amd64.Register.rdi,
+                  {target = amd64.Operand.register 
+                            (if win64 then amd64.Register.rcx 
+                                      else amd64.Register.rdi),
                    absolute = true},
                   amd64.Assembly.pseudoop_p2align 
                   (amd64.Immediate.int 4, NONE, NONE),

Modified: mlton/trunk/mlton/codegen/amd64-codegen/amd64-generate-transfers.fun
===================================================================
--- mlton/trunk/mlton/codegen/amd64-codegen/amd64-generate-transfers.fun	2008-08-06 00:09:45 UTC (rev 6687)
+++ mlton/trunk/mlton/codegen/amd64-codegen/amd64-generate-transfers.fun	2008-08-06 00:16:10 UTC (rev 6688)
@@ -1219,28 +1219,42 @@
                                     size = #2 fptrArg}),
                                   args)
                               end
+                     val win64 = case !Control.Target.os of
+                                    MLton.Platform.OS.Cygwin => true
+                                  | MLton.Platform.OS.MinGW => true
+                                  | _ => false
                      val (setup_args,
                           (reg_args, xmmreg_args),
                           size_stack_args, _)
                        = List.fold
                          (args, (AppendList.empty,
                                  ([],[]),0,
-                                 ([Register.rdi,Register.rsi,Register.rdx,
-                                   Register.rcx,Register.r8,Register.r9],
-                                  [(XmmRegister.xmm0D,XmmRegister.xmm0S),
-                                   (XmmRegister.xmm1D,XmmRegister.xmm1S),
-                                   (XmmRegister.xmm2D,XmmRegister.xmm2S),
-                                   (XmmRegister.xmm3D,XmmRegister.xmm3S),
-                                   (XmmRegister.xmm4D,XmmRegister.xmm4S),
-                                   (XmmRegister.xmm5D,XmmRegister.xmm5S),
-                                   (XmmRegister.xmm6D,XmmRegister.xmm6S),
-                                   (XmmRegister.xmm7D,XmmRegister.xmm7S)])),
+                                 (if win64
+                                  then [Register.rcx,Register.rdx,
+                                        Register.r8,Register.r9]
+                                  else [Register.rdi,Register.rsi,Register.rdx,
+                                        Register.rcx,Register.r8,Register.r9],
+                                  if win64
+                                  then [(XmmRegister.xmm0D,XmmRegister.xmm0S),
+                                        (XmmRegister.xmm1D,XmmRegister.xmm1S),
+                                        (XmmRegister.xmm2D,XmmRegister.xmm2S),
+                                        (XmmRegister.xmm3D,XmmRegister.xmm3S)]
+                                  else [(XmmRegister.xmm0D,XmmRegister.xmm0S),
+                                        (XmmRegister.xmm1D,XmmRegister.xmm1S),
+                                        (XmmRegister.xmm2D,XmmRegister.xmm2S),
+                                        (XmmRegister.xmm3D,XmmRegister.xmm3S),
+                                        (XmmRegister.xmm4D,XmmRegister.xmm4S),
+                                        (XmmRegister.xmm5D,XmmRegister.xmm5S),
+                                        (XmmRegister.xmm6D,XmmRegister.xmm6S),
+                                        (XmmRegister.xmm7D,XmmRegister.xmm7S)])),
                           fn ((arg, size), 
                               (setup_args,
                                (reg_args, xmmreg_args),
                                size_stack_args,
                                (regs, xmmregs))) =>
                           let
+                             fun prune [] = []
+                               | prune (x::r) = if win64 then r else (x::r)
                              val (setup_arg,
                                   (reg_args, xmmreg_args),
                                   size_stack_arg,
@@ -1269,7 +1283,7 @@
                                                     (reg_args,
                                                      (mem, xmmreg)::xmmreg_args),
                                                     0,
-                                                    (regs, xmmregs))
+                                                    (prune regs, xmmregs))
                                                 end
                                            | [] =>
                                                 (AppendList.fromList
@@ -1316,7 +1330,7 @@
                                                     ((mem,reg)::reg_args,
                                                      xmmreg_args),
                                                     0,
-                                                    (regs, xmmregs))
+                                                    (regs, prune xmmregs))
                                                 end
                                            | [] =>
                                                 (AppendList.fromList
@@ -1362,6 +1376,19 @@
                                      setup_args),
                                     size_stack_args + space)
                         end
+                     (* Allocate shadow space *)
+                     val (setup_args, size_stack_args) =
+                        if win64
+                           then (AppendList.append
+                                 (setup_args,
+                                  AppendList.single
+                                  (Assembly.instruction_binal
+                                   {oper = Instruction.SUB,
+                                    dst = c_stackP,
+                                    src = Operand.immediate_int 32,
+                                    size = pointerSize})),
+                                 size_stack_args + 32)
+                           else (setup_args, size_stack_args)
                      (*
                      val reserve_args =
                         AppendList.fromList




More information about the MLton-commit mailing list