aboutsummaryrefslogtreecommitdiffstats
path: root/runtime/x86_64/vararg.S
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/x86_64/vararg.S')
-rw-r--r--runtime/x86_64/vararg.S63
1 files changed, 61 insertions, 2 deletions
diff --git a/runtime/x86_64/vararg.S b/runtime/x86_64/vararg.S
index 9c0d787b..c5225b34 100644
--- a/runtime/x86_64/vararg.S
+++ b/runtime/x86_64/vararg.S
@@ -34,6 +34,12 @@
// Helper functions for variadic functions <stdarg.h>. x86_64 version.
+#include "sysdeps.h"
+
+// ELF ABI
+
+#if defined(SYS_linux) || defined(SYS_bsd) || defined(SYS_macosx)
+
// typedef struct {
// unsigned int gp_offset;
// unsigned int fp_offset;
@@ -60,8 +66,6 @@
// unsigned long long __compcert_va_int64(va_list ap);
// double __compcert_va_float64(va_list ap);
-#include "sysdeps.h"
-
FUNCTION(__compcert_va_int32)
movl 0(%rdi), %edx // edx = gp_offset
cmpl $48, %edx
@@ -146,3 +150,58 @@ FUNCTION(__compcert_va_saveregs)
movaps %xmm7, 160(%r10)
1: ret
ENDFUNCTION(__compcert_va_saveregs)
+
+#endif
+
+// Windows ABI
+
+#if defined(SYS_cygwin)
+
+// typedef void * va_list;
+// unsigned int __compcert_va_int32(va_list * ap);
+// unsigned long long __compcert_va_int64(va_list * ap);
+// double __compcert_va_float64(va_list * ap);
+
+FUNCTION(__compcert_va_int32) // %rcx = pointer to argument pointer
+ movq 0(%rcx), %rdx // %rdx = current argument pointer
+ movl 0(%rdx), %eax // load the int32 value there
+ addq $8, %rdx // increment argument pointer by 8
+ movq %rdx, 0(%rcx)
+ ret
+ENDFUNCTION(__compcert_va_int32)
+
+FUNCTION(__compcert_va_int64) // %rcx = pointer to argument pointer
+ movq 0(%rcx), %rdx // %rdx = current argument pointer
+ movq 0(%rdx), %rax // load the int64 value there
+ addq $8, %rdx // increment argument pointer by 8
+ movq %rdx, 0(%rcx)
+ ret
+ENDFUNCTION(__compcert_va_int64)
+
+FUNCTION(__compcert_va_float64) // %rcx = pointer to argument pointer
+ movq 0(%rcx), %rdx // %rdx = current argument pointer
+ movsd 0(%rdx), %xmm0 // load the float64 value there
+ addq $8, %rdx // increment argument pointer by 8
+ movq %rdx, 0(%rcx)
+ ret
+ENDFUNCTION(__compcert_va_float64)
+
+FUNCTION(__compcert_va_composite)
+ jmp GLOB(__compcert_va_int64) // by-ref convention, FIXME
+ENDFUNCTION(__compcert_va_composite)
+
+// Save arguments passed in register in the stack at beginning of vararg
+// function. The caller of the vararg function reserved 32 bytes of stack
+// just for this purpose.
+// FP arguments are passed both in FP registers and integer registers,
+// so it's enough to save the integer registers used for parameter passing.
+
+FUNCTION(__compcert_va_saveregs)
+ movq %rcx, 16(%rsp)
+ movq %rdx, 24(%rsp)
+ movq %r8, 32(%rsp)
+ movq %r9, 40(%rsp)
+ ret
+ENDFUNCTION(__compcert_va_saveregs)
+
+#endif