changeset 196:95cf20c0d1de

- sparc64 callbacks: * floating point support * fixes for many arg calls * this completes sparc64 callback support
author Tassilo Philipp
date Sun, 19 Mar 2017 19:34:34 +0100
parents be9cb092625f
children 53c42b1d9f8b
files dyncallback/dyncall_args_sparc64.c dyncallback/dyncall_args_sparc64.h dyncallback/dyncall_callback_sparc64.s
diffstat 3 files changed, 72 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/dyncallback/dyncall_args_sparc64.c	Sat Mar 18 19:10:01 2017 +0100
+++ b/dyncallback/dyncall_args_sparc64.c	Sun Mar 19 19:34:34 2017 +0100
@@ -26,7 +26,7 @@
 
 #include "dyncall_args_sparc64.h"
 
-DCulonglong dcbArgULongLong(DCArgs* p) { return *(DCulonglong*)   p->arg_ptr++; }
+DCulonglong dcbArgULongLong(DCArgs* p) { return p->arg_ptr[p->i++]; }
 DClonglong  dcbArgLongLong (DCArgs* p) { return (DClonglong)dcbArgULongLong(p); }
 DCulong     dcbArgULong    (DCArgs* p) { return (DCulong)   dcbArgULongLong(p); }
 DClong      dcbArgLong     (DCArgs* p) { return (DClong)    dcbArgULongLong(p); }
@@ -38,6 +38,18 @@
 DCshort     dcbArgShort    (DCArgs* p) { return (DCshort)   dcbArgULongLong(p); }
 DCbool      dcbArgBool     (DCArgs* p) { return (DCbool)    dcbArgULongLong(p); }
 DCpointer   dcbArgPointer  (DCArgs* p) { return (DCpointer) dcbArgULongLong(p); }
-DCdouble    dcbArgDouble   (DCArgs* p) { return *(DCdouble*)      p->arg_ptr++; }
-DCfloat     dcbArgFloat    (DCArgs* p) { return *(DCfloat*)       p->arg_ptr++; }
+
+DCdouble dcbArgDouble(DCArgs* p)
+{
+	return (p->i < DCARGS_SPARC64_NUM_DOUBLE_REGS)
+		? p->dreg_data[p->i++]
+		: *(DCdouble*)(p->arg_ptr + p->i++);
+}
 
+DCfloat dcbArgFloat(DCArgs* p)
+{
+	return (p->i < DCARGS_SPARC64_NUM_DOUBLE_REGS)
+		? *((DCfloat*)(p->dreg_data + p->i++)+1)  /* +1 bc single-prec fp args are */
+		: *((DCfloat*)(p->arg_ptr   + p->i++)+1); /* right aligned in 64bit slot   */
+}
+
--- a/dyncallback/dyncall_args_sparc64.h	Sat Mar 18 19:10:01 2017 +0100
+++ b/dyncallback/dyncall_args_sparc64.h	Sun Mar 19 19:34:34 2017 +0100
@@ -29,9 +29,13 @@
 
 #include "dyncall_args.h"
 
+#define DCARGS_SPARC64_NUM_DOUBLE_REGS 16
 struct DCArgs
 {
-  long long *arg_ptr;
+	/* Don't change order or types, laid out for asm code to fill in! */
+	DClonglong *arg_ptr;
+	DCdouble   dreg_data[DCARGS_SPARC64_NUM_DOUBLE_REGS];
+	DClonglong i; /* args fetched */
 };
 
 #endif /* DYNCALLBACK_ARGS_SPARC64_H */
--- a/dyncallback/dyncall_callback_sparc64.s	Sat Mar 18 19:10:01 2017 +0100
+++ b/dyncallback/dyncall_callback_sparc64.s	Sun Mar 19 19:34:34 2017 +0100
@@ -39,29 +39,63 @@
 dcCallbackThunkEntry:
 
 	/* Prolog. */
-	/* Frame size of 208b comes from needing storage space for the following: */
-	/*   DCargs(sparc_req_reg_save_area:128 + spill:64 + argptr:8) + retval:8 */
+	/* Frame size of 336b comes from needing storage space for the following: */
+	/*   req_reg_save_area:128 + spill:48 + dcargs:144 + retval:8 + pad:8 */
 	/* Spill area could theoretically be only 32b, b/c cbHandler function has */
- 	/* 4 arguments, and retval doesn't need stack, but let's be conservative. */
-	save %sp, -208, %sp
+ 	/* 4 arguments, but let's be conservative. */
+	save %sp, -336, %sp
 
-	/* Spill register args. */
-	add  %fp, BIAS + 136, %l0
-	stx  %i0, [ %l0 +  0 ]          /* reg arg 0 */
-	stx  %i1, [ %l0 +  8 ]          /* reg arg 1 */
-	stx  %i2, [ %l0 + 16 ]          /* reg arg 2 */
-	stx  %i3, [ %l0 + 24 ]          /* reg arg 3 */
-	stx  %i4, [ %l0 + 32 ]          /* reg arg 4 */
-	stx  %i5, [ %l0 + 40 ]          /* reg arg 5 */
-	stx  %l0, [ %sp + BIAS + 192 ]  /* init arg_ptr */
+	/* Spill register args as dcargs is based on that (in prev frame, after */
+	/* req_reg_save_area). */
+	add  %fp, BIAS + 128, %l0
+	stx  %i0,  [ %l0 +  0 ]          /* reg arg 0 */
+	stx  %i1,  [ %l0 +  8 ]          /* reg arg 1 */
+	stx  %i2,  [ %l0 + 16 ]          /* reg arg 2 */
+	stx  %i3,  [ %l0 + 24 ]          /* reg arg 3 */
+	stx  %i4,  [ %l0 + 32 ]          /* reg arg 4 */
+	stx  %i5,  [ %l0 + 40 ]          /* reg arg 5 */
+	stx  %l0,  [ %sp + BIAS + 176 ]  /* set DCArg's arg_ptr */
+	st   %f0,  [ %sp + BIAS + 184 ]  /* store fp args in DCArgs's dreg_data */
+	st   %f1,  [ %sp + BIAS + 188 ]  /* @@@ I think stx should work to store */
+	st   %f2,  [ %sp + BIAS + 192 ]  /*     all 64bits, but I get "Illegal   */
+	st   %f3,  [ %sp + BIAS + 196 ]  /*     Operands", so using single prec. */
+	st   %f4,  [ %sp + BIAS + 200 ]  /*     store (st) */
+	st   %f5,  [ %sp + BIAS + 204 ]
+	st   %f6,  [ %sp + BIAS + 208 ]
+	st   %f7,  [ %sp + BIAS + 212 ]
+	st   %f8,  [ %sp + BIAS + 216 ]
+	st   %f9,  [ %sp + BIAS + 220 ]
+	st   %f10, [ %sp + BIAS + 224 ]
+	st   %f11, [ %sp + BIAS + 228 ]
+	st   %f12, [ %sp + BIAS + 232 ]
+	st   %f13, [ %sp + BIAS + 236 ]
+	st   %f14, [ %sp + BIAS + 240 ]
+	st   %f15, [ %sp + BIAS + 244 ]
+	st   %f16, [ %sp + BIAS + 248 ]
+	st   %f17, [ %sp + BIAS + 252 ]
+	st   %f18, [ %sp + BIAS + 256 ]
+	st   %f19, [ %sp + BIAS + 260 ]
+	st   %f20, [ %sp + BIAS + 264 ]
+	st   %f21, [ %sp + BIAS + 268 ]
+	st   %f22, [ %sp + BIAS + 272 ]
+	st   %f23, [ %sp + BIAS + 276 ]
+	st   %f24, [ %sp + BIAS + 280 ]
+	st   %f25, [ %sp + BIAS + 284 ]
+	st   %f26, [ %sp + BIAS + 288 ]
+	st   %f27, [ %sp + BIAS + 292 ]
+	st   %f28, [ %sp + BIAS + 296 ]
+	st   %f29, [ %sp + BIAS + 300 ]
+	st   %f30, [ %sp + BIAS + 304 ]
+	st   %f31, [ %sp + BIAS + 308 ]
+	stx  %g0,  [ %sp + BIAS + 312 ] /* init DCArg's i */
 
 	/* Zero retval store. */
-	stx  %g0, [ %sp + BIAS + 200 ]
+	stx  %g0, [ %sp + BIAS + 320 ]
 
 	/* Prepare callback handler call. */
 	mov  %g1, %o0                   /* Param 0 = DCCallback*, %g1 holds ptr to thunk */
-	add  %sp, BIAS + 192, %o1       /* Param 1 = DCArgs* (ptr to struct with args ptr) */
-	add  %sp, BIAS + 200, %o2       /* Param 2 = results ptr to 8b of local stack data */
+	add  %sp, BIAS + 176, %o1       /* Param 1 = DCArgs* (ptr to struct with args ptr) */
+	add  %sp, BIAS + 320, %o2       /* Param 2 = results ptr to 8b of local stack data */
 	ldx  [ %g1 + 64 ], %o3          /* Param 3 = userdata ptr */
 
 	/* Fetch callback handler address (after thunk blob) and call. */
@@ -70,8 +104,8 @@
 	nop
 
 	/* Put retval in %i0 (to be in caller's %o0), and %f0. */
-	ldx  [ %sp + BIAS + 200 ], %i0
-	ldd  [ %sp + BIAS + 200 ], %f0
+	ldx  [ %sp + BIAS + 320 ], %i0
+	ldd  [ %sp + BIAS + 320 ], %f0
 
 	/* Epilog. */
 	restore                 /* unshift reg window */