1 /* --------------------------------------------------------------------------
2 * Assembly code to call C and Haskell functions
4 * Copyright (c) 1994-2001.
6 * $Id: universal_call_c.S,v 1.11 2001/02/12 12:08:44 sewardj Exp $
7 * ------------------------------------------------------------------------*/
13 only_here_to_work_around_a_bug_in_GNU_ld_291_on_sparc:
16 #if 0 /* later: GHCI */
18 .file "universal_call_c.S"
21 Implement this. See comment in rts/ForeignCall.c for details.
23 void universal_call_c_ARCHNAME
29 You can get a crude approximation to the assembly you need by
30 compiling the following:
32 extern void pingi64 ( unsigned long long int );
33 extern void pingi32 ( unsigned int );
34 extern void pingf32 ( float f );
35 extern void pingf64 ( double d );
37 void universal_call_c_ARCHNAME ( int n_args,
43 for (i = 1; i <= n_args; i++) {
44 if (argstr[i] == 'i') {
45 unsigned int u1 = ((unsigned int*)args)[2*i];
48 if (argstr[i] == 'I') {
49 unsigned long long int uu1 = ((unsigned long long int*)args)[i];
52 if (argstr[i] == 'f') {
53 float u1 = ((float*)args)[2*i];
56 if (argstr[i] == 'F') {
57 double u1 = ((double*)args)[i];
62 if (argstr[0] == 'f' || argstr[0] == 'F') {
70 #if LEADING_UNDERSCORE
71 #define ADD_UNDERSCORE(sss) _##sss
73 #define ADD_UNDERSCORE(sss) sss
79 * Tricky! Calls the specified function using ccall convention,
80 * *and* assumes that I myself was called using ccall.
83 .globl ADD_UNDERSCORE(universal_call_c_x86_ccall)
84 ADD_UNDERSCORE(universal_call_c_x86_ccall:)
97 cmpb $105,(%ebx,%edi) # 'i'
102 cmpb $73,(%ebx,%edi) # 'I'
108 cmpb $102,(%ebx,%edi) # 'f'
110 movl (%esi,%ebx,8),%eax
114 cmpb $70,(%ebx,%edi) # 'F'
116 movl 4(%esi,%ebx,8),%eax
117 movl (%esi,%ebx,8),%edx
128 cmpb $102,(%edi) # 'f'
130 cmpb $70,(%edi) # 'F'
152 # Almost identical to the above piece of code
153 # see comments near end for differences
155 # Even more tricky! Calls the specified function using
156 # stdcall convention, *but* assumes that I myself was called
159 .globl ADD_UNDERSCORE(universal_call_c_x86_stdcall)
160 ADD_UNDERSCORE(universal_call_c_x86_stdcall:)
173 cmpb $105,(%ebx,%edi) # 'i'
178 cmpb $73,(%ebx,%edi) # 'I'
184 cmpb $102,(%ebx,%edi) # 'f'
186 movl (%esi,%ebx,8),%eax
190 cmpb $70,(%ebx,%edi) # 'F'
192 movl 4(%esi,%ebx,8),%eax
193 movl (%esi,%ebx,8),%edx
204 cmpb $102,(%edi) # 'f'
206 cmpb $70,(%edi) # 'F'
219 /* don_t clear the args -- the callee does it */
220 /* leal -12(%ebp),%esp */
225 /* ret $16 # but we have to clear our own! (no! we were ccall_d) */
228 #endif /* i386_TARGET_ARCH */