From 139f0fd30e19f934aa51885a52b8e5d7c24ee460 Mon Sep 17 00:00:00 2001
From: simonm <unknown>
Date: Tue, 15 Dec 1998 13:08:03 +0000
Subject: [PATCH] [project @ 1998-12-15 13:08:03 by simonm] add missing file.

---
 ghc/rts/callfun.S | 162 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 162 insertions(+)
 create mode 100644 ghc/rts/callfun.S

diff --git a/ghc/rts/callfun.S b/ghc/rts/callfun.S
new file mode 100644
index 000000000000..926015d8dad0
--- /dev/null
+++ b/ghc/rts/callfun.S
@@ -0,0 +1,162 @@
+/* --------------------------------------------------------------------------
+ * Assembly code to call C and Haskell functions 
+ *
+ * Copyright (c) 1994-1998.
+ *
+ * $RCSfile: callfun.S,v $
+ * $Revision: 1.2 $
+ * $Date: 1998/12/15 13:08:03 $
+ * ------------------------------------------------------------------------*/
+	
+#include "config.h"
+#include "options.h"	
+	
+#ifdef INTERPRETER
+	.file "callfun.S"
+
+/* No longer needed - I finally figured out how to use __builtin_apply	*/
+#if 0 && i386_TARGET_ARCH
+
+#if 0	
+  void ccall( CFunDescriptor* d, void* fun )
+  {
+      void *rs=alloca(d->result_size);
+      void *as=alloca(d->arg_size);
+      unmarshall(d->arg_tys,as);
+      rs = fun(as)		; 
+      marshall(d->result_tys,rs);
+  }
+
+  On entry, we have:	
+    ret   =  0(%esp)
+    d     =  4(%esp)
+    fun   =  8(%esp)	
+  	  
+  We assume that %ebp is a callee saves register
+  and that %ecx is not used to return the result.
+  If %ecx is a callee saves register (I think it is), the code
+  can be optimised slightly - but I doubt its worth it.	
+#endif
+.globl ccall
+ccall:
+	pushl %ebp           /* Save stack frame pointer       */
+	pushl %ecx           /* Save callee-saves register     */
+		
+	leal  8(%esp), %ebp  /* ebp = frame pointer            */
+	movl  4(%ebp), %ecx  /* ecx = d;                       */
+	subl 12(%ecx), %esp  /* rs  = alloca(d->result_size);  */
+	subl  4(%ecx), %esp  /* as  = alloca(d->arg_size);     */
+
+	/* Marshall arguments off STG stack */	
+	pushl %esp
+	pushl 0(%ecx)
+	call  unmarshall
+	addl  $8,%esp        /* unmarshall(d->arg_tys,as);     */
+
+	/* Call function */
+	movl  8(%ebp), %ecx 
+	call  *%ecx          /* rs = fun(as);                  */
+
+	movl  4(%ebp), %ecx  /* ecx = d;                       */
+	addl  4(%ecx), %esp  /* free(as)                       */
+
+
+	/* Save result in rs - assume one or zero results for now */
+	movl  8(%ecx), %ecx  /* ecx = d->result_tys            */
+
+	cmpl  $0,(%ecx)      /* '\0' = no result               */
+	je    .args_saved
+
+	cmpl  $70,(%ecx)     /* 'F' = float result             */
+	jne   .not_float
+	flds  (%esp)         /* *rs = (float)f1                */
+	jmp   .args_saved
+
+.not_float:
+	cmpl  $68,(%ecx)     /* 'D' = double result            */
+	jne   .not_double
+	fldl  (%esp)         /* *rs = (double)f1               */
+	jmp   .args_saved
+
+.not_double:	
+	movl  %eax,(%esp)    /* *rs = eax                      */
+	/* fall through to .args_saved */
+
+	/* Marshall results back onto STG stack */
+.args_saved:
+	pushl %esp					       
+	movl  4(%ebp), %ecx  /* ecx = d;                       */
+	pushl 8(%ecx)					       
+	call  marshall					       
+	addl  $8,%esp        /* marshall(d->result_tys,rs);    */
+
+	
+	movl  4(%ebp), %ecx  /* ecx = d;                       */
+	addl  12(%ecx), %esp /* free(rs)                       */
+
+	popl %ecx            /* Restore callee-saves register  */
+	popl %ebp            /* restore stack frame pointer    */
+	ret                  
+	
+#if 0
+/* When we call a Fun, we push the arguments on the stack, push a return
+ * address and execute the instruction "call callFun_entry" which brings us
+ * here with a return address on top of the stack, a pointer to
+ * the FunDescriptor under that and the arguments under that.
+ * We swap the top arguments so that when we jmp to callFunDesc, the stack
+ * will look as though we executed "callFunDesc(fDescriptor,arg1,arg2,...)"
+ */
+	
+	/* function call/return - standard entry point
+	 * we'll have one of these for each calling convention
+	 * all of which jump to callFunDesc when done
+	 */	
+	.globl callFun_entry
+	.type  callFun_entry,@function
+callFun_entry:	
+	popl  %eax   /* FunDescriptor  */
+	popl  %edx   /* Return address */
+	pushl %eax
+	pushl %edx
+	jmp   callFunDesc
+
+	/* generic function call/return */
+callFunDesc:
+	subl  $8,%esp        /* int/double res1;  */
+	pushl %esp           /* &res1             */
+	leal  20(%esp),%ecx  /* &arg1             */
+	pushl %ecx 
+	pushl 20(%esp)       /* fun               */
+	call  call_H         /* returns result type in %eax */
+	addl  $20,%esp
+
+	testl %eax,%eax      /* '\0' = no result */
+	jne   .L1
+	ret
+.L1:
+	cmpl  $70,%eax       /* 'F' = float result */
+	jne   .L2
+	flds  -8(%esp)
+	ret
+.L2:
+	cmpl  $68,%eax       /* 'D' = double result */
+	jne   .L3
+	fldl  -8(%esp)
+	ret
+.L3:
+	movl  -8(%esp),%eax  /* return r          */
+	ret
+
+
+/* Some useful instructions - for later use:		
+ *	fstpl (%ebx)  store a double
+ *	fstps (%ebx)  store a float
+ *
+ *	fldl (%esi)   load a double (ready for return)
+ *	flds (%esi)   load a float (ready for return)
+ */
+#endif /* 0 */
+	
+#endif /* i386_TARGET_ARCH */
+	
+#endif /* INTERPRETER */
\ No newline at end of file
-- 
GitLab