1 /* --------------------------------------------------------------------------
2 * Assembly code to call C and Haskell functions
4 * Copyright (c) 1994-1998.
6 * $RCSfile: callfun.S,v $
8 * $Date: 1998/12/15 13:08:03 $
9 * ------------------------------------------------------------------------*/
17 /* No longer needed - I finally figured out how to use __builtin_apply */
18 #if 0 && i386_TARGET_ARCH
21 void ccall( CFunDescriptor* d, void* fun )
23 void *rs=alloca(d->result_size);
24 void *as=alloca(d->arg_size);
25 unmarshall(d->arg_tys,as);
27 marshall(d->result_tys,rs);
35 We assume that %ebp is a callee saves register
36 and that %ecx is not used to return the result.
37 If %ecx is a callee saves register (I think it is), the code
38 can be optimised slightly - but I doubt its worth it.
42 pushl %ebp /* Save stack frame pointer */
43 pushl %ecx /* Save callee-saves register */
45 leal 8(%esp), %ebp /* ebp = frame pointer */
46 movl 4(%ebp), %ecx /* ecx = d; */
47 subl 12(%ecx), %esp /* rs = alloca(d->result_size); */
48 subl 4(%ecx), %esp /* as = alloca(d->arg_size); */
50 /* Marshall arguments off STG stack */
54 addl $8,%esp /* unmarshall(d->arg_tys,as); */
58 call *%ecx /* rs = fun(as); */
60 movl 4(%ebp), %ecx /* ecx = d; */
61 addl 4(%ecx), %esp /* free(as) */
64 /* Save result in rs - assume one or zero results for now */
65 movl 8(%ecx), %ecx /* ecx = d->result_tys */
67 cmpl $0,(%ecx) /* '\0' = no result */
70 cmpl $70,(%ecx) /* 'F' = float result */
72 flds (%esp) /* *rs = (float)f1 */
76 cmpl $68,(%ecx) /* 'D' = double result */
78 fldl (%esp) /* *rs = (double)f1 */
82 movl %eax,(%esp) /* *rs = eax */
83 /* fall through to .args_saved */
85 /* Marshall results back onto STG stack */
88 movl 4(%ebp), %ecx /* ecx = d; */
91 addl $8,%esp /* marshall(d->result_tys,rs); */
94 movl 4(%ebp), %ecx /* ecx = d; */
95 addl 12(%ecx), %esp /* free(rs) */
97 popl %ecx /* Restore callee-saves register */
98 popl %ebp /* restore stack frame pointer */
102 /* When we call a Fun, we push the arguments on the stack, push a return
103 * address and execute the instruction "call callFun_entry" which brings us
104 * here with a return address on top of the stack, a pointer to
105 * the FunDescriptor under that and the arguments under that.
106 * We swap the top arguments so that when we jmp to callFunDesc, the stack
107 * will look as though we executed "callFunDesc(fDescriptor,arg1,arg2,...)"
110 /* function call/return - standard entry point
111 * we'll have one of these for each calling convention
112 * all of which jump to callFunDesc when done
115 .type callFun_entry,@function
117 popl %eax /* FunDescriptor */
118 popl %edx /* Return address */
123 /* generic function call/return */
125 subl $8,%esp /* int/double res1; */
126 pushl %esp /* &res1 */
127 leal 20(%esp),%ecx /* &arg1 */
129 pushl 20(%esp) /* fun */
130 call call_H /* returns result type in %eax */
133 testl %eax,%eax /* '\0' = no result */
137 cmpl $70,%eax /* 'F' = float result */
142 cmpl $68,%eax /* 'D' = double result */
147 movl -8(%esp),%eax /* return r */
151 /* Some useful instructions - for later use:
152 * fstpl (%ebx) store a double
153 * fstps (%ebx) store a float
155 * fldl (%esi) load a double (ready for return)
156 * flds (%esi) load a float (ready for return)
160 #endif /* i386_TARGET_ARCH */
162 #endif /* INTERPRETER */