corda/src/compile-x86.S

250 lines
5.3 KiB
ArmAsm
Raw Normal View History

2009-03-15 18:02:36 +00:00
/* Copyright (c) 2008-2009, Avian Contributors
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. */
#include "types.h"
#define LOCAL(x) .L##x
.text
#ifdef __x86_64__
2009-05-05 01:04:17 +00:00
#define THREAD_CONTINUATION 168
#define THREAD_EXCEPTION 64
#define THREAD_EXCEPTION_STACK 176
#define THREAD_EXCEPTION_OFFSET 184
#define THREAD_EXCEPTION_HANDLER 192
#define CONTINUATION_NEXT 8
#define CONTINUATION_ADDRESS 24
#define CONTINUATION_RETURN_ADDRESS_OFFSET 32
#define CONTINUATION_FRAME_POINTER_OFFSET 40
#define CONTINUATION_LENGTH 48
#define CONTINUATION_BODY 56
2007-10-04 00:41:54 +00:00
.globl vmInvoke
vmInvoke:
pushq %rbp
movq %rsp,%rbp
2007-12-11 21:26:59 +00:00
// %rdi: thread
// %rsi: function
// %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
// 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
// copy arguments into place
2007-12-11 21:26:59 +00:00
movq $0,%r9
2009-05-03 20:57:11 +00:00
jmp LOCAL(vmInvoke_argumentTest)
2009-05-03 20:57:11 +00:00
LOCAL(vmInvoke_argumentLoop):
movq (%rdx,%r9,1),%r8
movq %r8,(%rsp,%r9,1)
addq $8,%r9
2009-05-03 20:57:11 +00:00
LOCAL(vmInvoke_argumentTest):
2007-12-11 21:26:59 +00:00
cmpq %rcx,%r9
2009-05-03 20:57:11 +00:00
jb LOCAL(vmInvoke_argumentLoop)
// call function
2007-12-11 21:26:59 +00:00
call *%rsi
.globl vmInvoke_returnAddress
vmInvoke_returnAddress:
// restore stack pointer
movq %rbp,%rsp
2009-05-03 20:57:11 +00:00
2009-05-05 01:04:17 +00:00
// call the next continuation, if any
2009-05-03 20:57:11 +00:00
movq THREAD_CONTINUATION(%rbx),%rcx
cmpq $0,%rcx
je LOCAL(vmInvoke_exit)
2009-05-05 01:04:17 +00:00
movq CONTINUATION_LENGTH(%rcx),%rsi
shlq $3,%rsi
subq %rsi,%rsp
2009-05-03 20:57:11 +00:00
leaq CONTINUATION_BODY(%rcx),%rdi
2009-05-03 20:57:11 +00:00
movq $0,%r9
jmp LOCAL(vmInvoke_continuationTest)
LOCAL(vmInvoke_continuationLoop):
movq (%rdi,%r9,1),%r8
movq %r8,(%rsp,%r9,1)
addq $8,%r9
LOCAL(vmInvoke_continuationTest):
cmpq %rsi,%r9
jb LOCAL(vmInvoke_continuationLoop)
2009-05-03 20:57:11 +00:00
movq CONTINUATION_RETURN_ADDRESS_OFFSET(%rcx),%rdi
movq vmInvoke_returnAddress@GOTPCREL(%rip),%r10
2009-05-05 01:04:17 +00:00
movq %r10,(%rsp,%rdi,1)
2009-05-03 20:57:11 +00:00
movq CONTINUATION_FRAME_POINTER_OFFSET(%rcx),%rdi
movq %rbp,(%rsp,%rdi,1)
addq %rsp,%rdi
movq %rdi,%rbp
2009-05-03 20:57:11 +00:00
movq CONTINUATION_NEXT(%rcx),%rdi
movq %rdi,THREAD_CONTINUATION(%rbx)
// call the continuation unless we're handling an exception
movq THREAD_EXCEPTION(%rbx),%rsi
cmpq $0,%rsi
2009-05-05 01:04:17 +00:00
jne LOCAL(vmInvoke_handleException)
jmp *CONTINUATION_ADDRESS(%rcx)
2009-05-03 20:57:11 +00:00
2009-05-05 01:04:17 +00:00
LOCAL(vmInvoke_handleException):
2009-05-03 20:57:11 +00:00
// we're handling an exception - call the exception handler instead
movq $0,THREAD_EXCEPTION(%rbx)
movq THREAD_EXCEPTION_STACK(%rbx),%rsp
movq THREAD_EXCEPTION_OFFSET(%rbx),%rdi
movq %rsi,(%rsp,%rdi,1)
jmp *THREAD_EXCEPTION_HANDLER(%rbx)
LOCAL(vmInvoke_exit):
// 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
popq %rbp
ret
2009-05-03 20:57:11 +00:00
.globl vmCallWithContinuation
vmCallWithContinuation:
// %rdi: thread
// %rsi: address
// %rdx: targetObject
// %rcx: continuation
// %r8 : base
// %r9 : stack
movq %rdi,%rbx
2009-05-03 20:57:11 +00:00
movq %r8,%rbp
movq %r9,%rsp
movq vmInvoke_returnAddress@GOTPCREL(%rip),%r10
2009-05-05 01:04:17 +00:00
movq %r10,(%rsp)
movq %rdx,8(%rsp)
movq %rcx,16(%rsp)
2009-05-03 20:57:11 +00:00
jmp *%rsi
#elif defined __i386__
2009-02-14 00:03:46 +00:00
# if defined __APPLE__ || defined __MINGW32__ || defined __CYGWIN32__
.globl _vmInvoke
_vmInvoke:
# else
2007-10-04 00:41:54 +00:00
.globl vmInvoke
vmInvoke:
# endif
pushl %ebp
movl %esp,%ebp
2007-12-11 21:26:59 +00:00
// 8(%ebp): thread
// 12(%ebp): function
// 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
// we use ebx to hold the thread pointer, by convention
mov 8(%ebp),%ebx
// copy arguments into place
movl $0,%ecx
movl 16(%ebp),%edx
jmp LOCAL(test)
LOCAL(loop):
movl (%edx,%ecx,1),%eax
movl %eax,(%esp,%ecx,1)
addl $4,%ecx
LOCAL(test):
2007-12-11 21:26:59 +00:00
cmpl 20(%ebp),%ecx
jb LOCAL(loop)
// call function
2007-12-11 21:26:59 +00:00
call *12(%ebp)
// restore stack pointer and callee-saved registers
movl %ebp,%ecx
subl $16,%ecx
movl %ecx,%esp
movl 0(%esp),%ebx
movl 4(%esp),%esi
movl 8(%esp),%edi
// handle return value based on expected type
movl 28(%ebp),%ecx
addl $16,%esp
LOCAL(void):
cmpl $VOID_TYPE,%ecx
jne LOCAL(int64)
jmp LOCAL(exit)
LOCAL(int64):
cmpl $INT64_TYPE,%ecx
jne LOCAL(int32)
jmp LOCAL(exit)
LOCAL(int32):
movl $0,%edx
LOCAL(exit):
popl %ebp
ret
2007-10-04 00:41:54 +00:00
#else
# error unsupported platform
#endif