2009-03-15 18:02:36 +00:00
|
|
|
/* Copyright (c) 2008-2009, Avian Contributors
|
2008-02-19 18:06:52 +00:00
|
|
|
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
|
|
for any purpose with or without fee is hereby granted, provided
|
|
|
|
that the above copyright notice and this permission notice appear
|
|
|
|
in all copies.
|
|
|
|
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
|
|
details. */
|
|
|
|
|
2007-09-26 23:23:03 +00:00
|
|
|
#include "types.h"
|
|
|
|
|
2008-06-15 18:49:37 +00:00
|
|
|
#define LOCAL(x) .L##x
|
|
|
|
|
2007-09-26 23:23:03 +00:00
|
|
|
.text
|
|
|
|
|
|
|
|
#ifdef __x86_64__
|
|
|
|
|
2007-10-04 00:41:54 +00:00
|
|
|
.globl vmInvoke
|
|
|
|
vmInvoke:
|
2007-09-26 23:23:03 +00:00
|
|
|
pushq %rbp
|
|
|
|
movq %rsp,%rbp
|
2007-12-11 21:26:59 +00:00
|
|
|
|
|
|
|
// %rdi: thread
|
|
|
|
// %rsi: function
|
2009-02-17 02:49:28 +00:00
|
|
|
// %rdx: arguments
|
|
|
|
// %rcx: argumentFootprint
|
|
|
|
// %r8 : frameSize
|
|
|
|
// %r9 : returnType (ignored)
|
|
|
|
|
|
|
|
// allocate stack space, adding room for callee-saved registers
|
|
|
|
subq %r8,%rsp
|
|
|
|
subq $48,%rsp
|
|
|
|
|
|
|
|
// save callee-saved registers
|
|
|
|
movq %rsp,%r9
|
|
|
|
addq %r8,%r9
|
|
|
|
|
|
|
|
movq %rbx,0(%r9)
|
|
|
|
movq %r12,8(%r9)
|
|
|
|
movq %r13,16(%r9)
|
|
|
|
movq %r14,24(%r9)
|
|
|
|
movq %r15,32(%r9)
|
2007-12-11 21:26:59 +00:00
|
|
|
|
2009-02-16 15:21:12 +00:00
|
|
|
// we use rbx to hold the thread pointer, by convention
|
2007-12-11 21:26:59 +00:00
|
|
|
mov %rdi,%rbx
|
2007-12-20 01:42:12 +00:00
|
|
|
|
2007-12-26 23:59:55 +00:00
|
|
|
// copy arguments into place
|
2007-12-11 21:26:59 +00:00
|
|
|
movq $0,%r9
|
2008-06-15 18:49:37 +00:00
|
|
|
jmp LOCAL(test)
|
2007-09-26 23:23:03 +00:00
|
|
|
|
2008-06-15 18:49:37 +00:00
|
|
|
LOCAL(loop):
|
2009-02-17 02:49:28 +00:00
|
|
|
movq (%rdx,%r9,1),%r8
|
|
|
|
movq %r8,(%rsp,%r9,1)
|
|
|
|
addq $8,%r9
|
2007-09-26 23:23:03 +00:00
|
|
|
|
2008-06-15 18:49:37 +00:00
|
|
|
LOCAL(test):
|
2007-12-11 21:26:59 +00:00
|
|
|
cmpq %rcx,%r9
|
2008-06-15 18:49:37 +00:00
|
|
|
jb LOCAL(loop)
|
2007-09-26 23:23:03 +00:00
|
|
|
|
|
|
|
// call function
|
2007-12-11 21:26:59 +00:00
|
|
|
call *%rsi
|
2007-09-26 23:23:03 +00:00
|
|
|
|
2009-02-17 02:49:28 +00:00
|
|
|
// restore stack pointer
|
|
|
|
movq %rbp,%rsp
|
2007-12-26 23:59:55 +00:00
|
|
|
|
2009-02-17 02:49:28 +00:00
|
|
|
// restore callee-saved registers
|
|
|
|
movq %rsp,%r9
|
|
|
|
subq $48,%r9
|
|
|
|
|
|
|
|
movq 0(%r9),%rbx
|
|
|
|
movq 8(%r9),%r12
|
|
|
|
movq 16(%r9),%r13
|
|
|
|
movq 24(%r9),%r14
|
|
|
|
movq 32(%r9),%r15
|
|
|
|
|
|
|
|
// return
|
2007-09-26 23:23:03 +00:00
|
|
|
popq %rbp
|
|
|
|
ret
|
2007-10-04 00:41:54 +00:00
|
|
|
|
2007-09-26 23:23:03 +00:00
|
|
|
#elif defined __i386__
|
2007-12-20 23:22:40 +00:00
|
|
|
|
2009-02-14 00:03:46 +00:00
|
|
|
# if defined __APPLE__ || defined __MINGW32__ || defined __CYGWIN32__
|
2007-12-20 23:22:40 +00:00
|
|
|
.globl _vmInvoke
|
|
|
|
_vmInvoke:
|
|
|
|
# else
|
2007-10-04 00:41:54 +00:00
|
|
|
.globl vmInvoke
|
|
|
|
vmInvoke:
|
2007-12-20 23:22:40 +00:00
|
|
|
# endif
|
2007-09-26 23:23:03 +00:00
|
|
|
pushl %ebp
|
|
|
|
movl %esp,%ebp
|
|
|
|
|
2007-12-11 21:26:59 +00:00
|
|
|
// 8(%ebp): thread
|
|
|
|
// 12(%ebp): function
|
2009-02-17 02:49:28 +00:00
|
|
|
// 16(%ebp): arguments
|
|
|
|
// 20(%ebp): argumentFootprint
|
|
|
|
// 24(%ebp): frameSize
|
|
|
|
// 28(%ebp): returnType
|
|
|
|
|
|
|
|
// allocate stack space, adding room for callee-saved registers
|
|
|
|
subl 24(%ebp),%esp
|
|
|
|
subl $16,%esp
|
|
|
|
|
|
|
|
// save callee-saved registers
|
|
|
|
movl %esp,%ecx
|
|
|
|
addl 24(%ebp),%ecx
|
|
|
|
|
|
|
|
movl %ebx,0(%ecx)
|
|
|
|
movl %esi,4(%ecx)
|
|
|
|
movl %edi,8(%ecx)
|
2007-12-11 21:26:59 +00:00
|
|
|
|
2009-02-16 15:21:12 +00:00
|
|
|
// we use ebx to hold the thread pointer, by convention
|
2007-12-12 18:59:45 +00:00
|
|
|
mov 8(%ebp),%ebx
|
2007-09-26 23:23:03 +00:00
|
|
|
|
|
|
|
// copy arguments into place
|
|
|
|
movl $0,%ecx
|
2009-02-17 02:49:28 +00:00
|
|
|
movl 16(%ebp),%edx
|
2008-06-15 18:49:37 +00:00
|
|
|
jmp LOCAL(test)
|
2007-09-26 23:23:03 +00:00
|
|
|
|
2008-06-15 18:49:37 +00:00
|
|
|
LOCAL(loop):
|
2009-02-17 02:49:28 +00:00
|
|
|
movl (%edx,%ecx,1),%eax
|
|
|
|
movl %eax,(%esp,%ecx,1)
|
|
|
|
addl $4,%ecx
|
2007-09-26 23:23:03 +00:00
|
|
|
|
2008-06-15 18:49:37 +00:00
|
|
|
LOCAL(test):
|
2007-12-11 21:26:59 +00:00
|
|
|
cmpl 20(%ebp),%ecx
|
2008-06-15 18:49:37 +00:00
|
|
|
jb LOCAL(loop)
|
2007-09-26 23:23:03 +00:00
|
|
|
|
|
|
|
// call function
|
2007-12-11 21:26:59 +00:00
|
|
|
call *12(%ebp)
|
2009-02-17 02:49:28 +00:00
|
|
|
|
|
|
|
// restore stack pointer
|
|
|
|
movl %ebp,%esp
|
|
|
|
|
|
|
|
// restore callee-saved registers
|
|
|
|
movl %esp,%ecx
|
|
|
|
subl $16,%ecx
|
2007-09-26 23:23:03 +00:00
|
|
|
|
2009-02-17 02:49:28 +00:00
|
|
|
movl 0(%ecx),%ebx
|
|
|
|
movl 4(%ecx),%esi
|
|
|
|
movl 8(%ecx),%edi
|
2007-10-12 02:52:16 +00:00
|
|
|
|
2007-09-26 23:23:03 +00:00
|
|
|
// handle return value based on expected type
|
2009-02-17 02:49:28 +00:00
|
|
|
movl 28(%ebp),%ecx
|
2007-09-26 23:23:03 +00:00
|
|
|
|
2008-06-15 18:49:37 +00:00
|
|
|
LOCAL(void):
|
2007-09-26 23:23:03 +00:00
|
|
|
cmpl $VOID_TYPE,%ecx
|
2008-06-15 18:49:37 +00:00
|
|
|
jne LOCAL(int64)
|
|
|
|
jmp LOCAL(exit)
|
2007-09-26 23:23:03 +00:00
|
|
|
|
2008-06-15 18:49:37 +00:00
|
|
|
LOCAL(int64):
|
2007-09-26 23:23:03 +00:00
|
|
|
cmpl $INT64_TYPE,%ecx
|
2008-06-15 18:49:37 +00:00
|
|
|
jne LOCAL(int32)
|
|
|
|
jmp LOCAL(exit)
|
2007-09-26 23:23:03 +00:00
|
|
|
|
2008-06-15 18:49:37 +00:00
|
|
|
LOCAL(int32):
|
2007-09-26 23:23:03 +00:00
|
|
|
movl $0,%edx
|
|
|
|
|
2008-06-15 18:49:37 +00:00
|
|
|
LOCAL(exit):
|
2007-09-26 23:23:03 +00:00
|
|
|
popl %ebp
|
|
|
|
ret
|
2007-10-04 00:41:54 +00:00
|
|
|
|
2007-09-26 23:23:03 +00:00
|
|
|
#else
|
|
|
|
# error unsupported platform
|
|
|
|
#endif
|