changeset 122:f63467916f98

- first draft of mips64 n64 callbacks, not everything working, though
author cslag
date Mon, 04 Jul 2016 01:11:08 +0200
parents f00b1f3da52e
children d203ba52c246
files dyncallback/dyncall_args.c dyncallback/dyncall_args_mips.h dyncallback/dyncall_args_mips64.c dyncallback/dyncall_callback.c dyncallback/dyncall_callback_mips_n64_gas.s
diffstat 5 files changed, 170 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/dyncallback/dyncall_args.c	Mon Jul 04 01:03:27 2016 +0200
+++ b/dyncallback/dyncall_args.c	Mon Jul 04 01:11:08 2016 +0200
@@ -27,32 +27,34 @@
 
 #if defined(DC__Arch_Intel_x86)
 #  include "dyncall_args_x86.c"
-#elif defined (DC__Arch_AMD64)
+#elif defined(DC__Arch_AMD64)
 #  include "dyncall_args_x64.c"
-#elif defined (DC__Arch_PPC32)
-#  if defined (DC__OS_Darwin)
+#elif defined(DC__Arch_PPC32)
+#  if defined(DC__OS_Darwin)
 #    include "dyncall_args_ppc32.c"
 #  else
 #    include "dyncall_args_ppc32_sysv.c"
 #  endif
-#elif defined (DC__Arch_PPC64)
+#elif defined(DC__Arch_PPC64)
 #  include "dyncall_args_ppc64.c"
-#elif defined (DC__Arch_ARM_ARM)
+#elif defined(DC__Arch_ARM_ARM)
 #  include "dyncall_args_arm32_arm.c"
-#elif defined (DC__Arch_ARM_THUMB)
+#elif defined(DC__Arch_ARM_THUMB)
 #  include "dyncall_args_arm32_thumb.c"
-#elif defined (DC__Arch_MIPS)
+#elif defined(DC__Arch_MIPS)
 #  if defined(DC__ABI_MIPS_O32)
 #    include "dyncall_args_mips_o32.c"
 #  else
 #    include "dyncall_args_mips.c"
 #  endif
-#elif defined (DC__Arch_Sparc)
+#elif defined(DC__Arch_MIPS64)
+#    include "dyncall_args_mips64.c"
+#elif defined(DC__Arch_Sparc)
 #  include "dyncall_args_sparc32.c"
-#elif defined (DC__Arch_Sparcv9)
+#elif defined(DC__Arch_Sparcv9)
 #  include "dyncall_args_sparc64.c"
-#elif defined (DC__Arch_ARM64)
-#  if defined (DC__OS_Darwin)
+#elif defined(DC__Arch_ARM64)
+#  if defined(DC__OS_Darwin)
 #    include "dyncall_args_arm64_apple.c"
 #  else
 #    include "dyncall_args_arm64.c"
--- a/dyncallback/dyncall_args_mips.h	Mon Jul 04 01:03:27 2016 +0200
+++ b/dyncallback/dyncall_args_mips.h	Mon Jul 04 01:11:08 2016 +0200
@@ -31,15 +31,21 @@
 
 struct DCArgs
 {
-	/* Don't change order! */
-#if defined(DC__ABI_MIPS_O32)
+	/* Don't change order or types, laid out for asm code to fill in! */
+#if defined(DC__Arch_MIPS) && defined(DC__ABI_MIPS_O32)
 	DCint freg_count;
 #else
 #  define DCARGS_MIPS_NUM_IREGS 8
 #  define DCARGS_MIPS_NUM_FREGS 8
+#  if defined(DC__Arch_MIPS)
 	DCint   ireg_data[DCARGS_MIPS_NUM_IREGS];
 	DCfloat freg_data[DCARGS_MIPS_NUM_FREGS];
 	struct { DCshort i; DCshort f; } reg_count;
+#  elif defined(DC__Arch_MIPS64)
+	DClonglong ireg_data[DCARGS_MIPS_NUM_IREGS];
+	DCdouble   freg_data[DCARGS_MIPS_NUM_FREGS];
+	DClonglong reg_count;
+#  endif
 #endif
 	DCuchar* stackptr;
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dyncallback/dyncall_args_mips64.c	Mon Jul 04 01:11:08 2016 +0200
@@ -0,0 +1,74 @@
+/*
+
+ Package: dyncall
+ Library: dyncallback
+ File: dyncallback/dyncall_args_mips64.c
+ Description: Callback's Arguments VM - Implementation for MIPS64 n32&n64
+ License:
+
+   Copyright (c) 2016 Tassilo Philipp <tphilipp@potion-studios.com>
+
+   Permission to use, copy, modify, and 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.
+
+   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+*/
+
+
+#include "dyncall_args_mips.h"
+
+/* @@@ test and add n32 code here, also, if needed */
+
+DClonglong dcbArgLongLong(DCArgs* p)
+{
+  DClonglong value;
+  if(p->reg_count < DCARGS_MIPS_NUM_IREGS)
+    value = p->ireg_data[p->reg_count++];
+  else {
+    value = *((DClonglong*)p->stackptr);
+    p->stackptr += sizeof(DClonglong);
+  }
+  return value;
+}
+DCulonglong dcbArgULongLong(DCArgs* p) { return (DCulonglong)dcbArgLongLong(p); }
+
+DCint       dcbArgInt    (DCArgs* p) { return (DCint)    dcbArgLongLong(p); }
+DCuint      dcbArgUInt   (DCArgs* p) { return (DCuint)   dcbArgLongLong(p); }
+DClong      dcbArgLong   (DCArgs* p) { return (DClong)   dcbArgLongLong(p); }
+DCulong     dcbArgULong  (DCArgs* p) { return (DCulong)  dcbArgLongLong(p); }
+DCchar      dcbArgChar   (DCArgs* p) { return (DCchar)   dcbArgLongLong(p); }
+DCuchar     dcbArgUChar  (DCArgs* p) { return (DCuchar)  dcbArgLongLong(p); }
+DCshort     dcbArgShort  (DCArgs* p) { return (DCshort)  dcbArgLongLong(p); }
+DCushort    dcbArgUShort (DCArgs* p) { return (DCushort) dcbArgLongLong(p); }
+DCbool      dcbArgBool   (DCArgs* p) { return (DCbool)   dcbArgLongLong(p); }
+DCpointer   dcbArgPointer(DCArgs* p) { return (DCpointer)dcbArgLongLong(p); }
+
+DCdouble dcbArgDouble(DCArgs* p)
+{
+  DCdouble result;
+  if(p->reg_count < DCARGS_MIPS_NUM_FREGS)
+    result = p->freg_data[p->reg_count++];
+  else {
+    result = *((DCdouble*)p->stackptr);
+    p->stackptr += sizeof(DCdouble);
+  }
+  return result;
+}
+DCfloat dcbArgFloat(DCArgs* p) {
+    DCdouble d = dcbArgDouble(p);
+	return ((DCfloat*)&d) // single precision are stored in double slots, but not promoted
+#if defined(DC__Endian_LITTLE)
+      [0];
+#else
+      [1];
+#endif
+}
+
--- a/dyncallback/dyncall_callback.c	Mon Jul 04 01:03:27 2016 +0200
+++ b/dyncallback/dyncall_callback.c	Mon Jul 04 01:11:08 2016 +0200
@@ -28,23 +28,23 @@
 
 #if defined(DC__Arch_Intel_x86)
 #include "dyncall_callback_x86.c"
-#elif defined (DC__Arch_AMD64)
+#elif defined(DC__Arch_AMD64)
 #include "dyncall_callback_x64.c"
-#elif defined (DC__Arch_PPC32)
+#elif defined(DC__Arch_PPC32)
 #include "dyncall_callback_ppc32.c"
-#elif defined (DC__Arch_PPC64)
+#elif defined(DC__Arch_PPC64)
 #include "dyncall_callback_ppc64.c"
-#elif defined (DC__Arch_ARM_ARM)
+#elif defined(DC__Arch_ARM_ARM)
 #include "dyncall_callback_arm32_arm.c"
-#elif defined (DC__Arch_ARM_THUMB)
+#elif defined(DC__Arch_ARM_THUMB)
 #include "dyncall_callback_arm32_thumb.c"
-#elif defined (DC__Arch_MIPS)
+#elif defined(DC__Arch_MIPS) || defined(DC__Arch_MIPS64)
 #include "dyncall_callback_mips.c"
-#elif defined (DC__Arch_Sparc)
+#elif defined(DC__Arch_Sparc)
 #include "dyncall_callback_sparc32.c"
-#elif defined (DC__Arch_Sparcv9)
+#elif defined(DC__Arch_Sparcv9)
 #include "dyncall_callback_sparc64.c"
-#elif defined (DC__Arch_ARM64)
+#elif defined(DC__Arch_ARM64)
 #include "dyncall_callback_arm64.c"
 #endif
 
--- a/dyncallback/dyncall_callback_mips_n64_gas.s	Mon Jul 04 01:03:27 2016 +0200
+++ b/dyncallback/dyncall_callback_mips_n64_gas.s	Mon Jul 04 01:11:08 2016 +0200
@@ -20,8 +20,15 @@
    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
+@@@ NOT FULLY WORKING, YET
 */
 
+	/* input:
+		$t8    -> thunk
+		$t8+56 -> cb handler
+		$t8+64 -> userdata
+	*/
+
 	.section .mdebug.abi64
 	.previous
 	.abicalls
@@ -30,6 +37,64 @@
 	.globl dcCallbackThunkEntry
 	.ent   dcCallbackThunkEntry
 dcCallbackThunkEntry:
+	.set    noreorder
 
-	.end dcCallbackThunkEntry
+	/* Prolog. */
+	/* Frame size of 160b comes from following: */
+	/*   DCargs(fregs:64 + iregs:64 + regcounts:8 + stackptr:8) + retval:8 + ra:8 */
+	subu  $sp, 160       /* open frame */
+	sd    $ra, 152($sp)  /* save link register */
+
+	.frame $fp,160,$31   /* specify our frame: fp,size,lr; creates virt $fp */
+	                     /* code below doesn't use $fp though, as n/a with -O1 */
+	/* Init return value */
+	sd $zero, 144($sp)
+
+	/* Store float and int args where our DCargs member arrays are, in local area. */
+	sd  $4,     0($sp)
+	sd  $5,     8($sp)
+	sd  $6,    16($sp)
+	sd  $7,    24($sp)
+	sd  $8,    32($sp)
+	sd  $9,    40($sp)
+	sd $10,    48($sp)
+	sd $11,    56($sp)
+	s.d $f12,  64($sp)
+	s.d $f13,  72($sp)
+	s.d $f14,  80($sp)
+	s.d $f15,  88($sp)
+	s.d $f16,  96($sp)
+	s.d $f17, 104($sp)
+	s.d $f18, 112($sp)
+	s.d $f19, 120($sp)
 
+	/* Init DCarg's reg_counts and stackptr. */
+	sd $zero, 128($sp)  /* reg_count */
+	addiu $4, $sp, 160
+	sd    $4, 136($sp)  /* stackptr */
+
+	/* Prepare callback handler call. */
+	move  $4, $24       /* Param 0 = DCCallback*, $24 ($t8) holds pointer to thunk */
+	move  $5, $sp       /* Param 1 = DCArgs*, pointer to where pointer to args is stored */
+	addiu $6, $sp, 144  /* Param 2 = results pointer to 8b of local data on stack */
+	ld    $7, 64($24)   /* Param 3 = userdata pointer */
+
+	ld    $25, 56($24)  /* store handler entry in $25 ($t9), required for PIC */
+	jalr  $25           /* jump */
+	nop                 /* branch delay nop */
+
+	/* Copy result in corresponding registers $2-$3 ($v0-$v1) and $f0 */
+	ld     $2, 144($sp)
+	/*ld     $3, 152($sp) @@@ ignoring second possible retval for now*/
+	l.d   $f0, 144($sp)
+
+	/* Epilog. Tear down frame and return. */
+	ld    $ra, 152($sp)  /* restore return address */
+	addiu $sp, $sp, 160  /* close frame */
+	j     $ra            /* return */
+	nop                  /* branch delay nop */
+
+	.set    reorder
+	.end    dcCallbackThunkEntry
+	.ident  "handwritten"
+