changeset 158:51b0a4544d9e

- sparc32 callbacks now complete, fixed 64bit value access alignment problems that caused SIGBUS errors
author cslag
date Thu, 29 Dec 2016 06:07:43 -0600
parents 49549739228c
children 164cf1663b7c
files dyncallback/dyncall_args_sparc32.c
diffstat 1 files changed, 14 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/dyncallback/dyncall_args_sparc32.c	Wed Dec 28 16:48:35 2016 -0600
+++ b/dyncallback/dyncall_args_sparc32.c	Thu Dec 29 06:07:43 2016 -0600
@@ -26,6 +26,13 @@
 
 #include "dyncall_args_sparc32.h"
 
+/* Compiler aligns this to 8-byte boundaries, b/c of dword members, a fact needed below */
+typedef union {
+  DCdouble    d;
+  DCulonglong L;
+  DCulong     l[2];
+} DCAligned64BitVal_t;
+
 static void* sparc_word(DCArgs* args)
 {
   return args->arg_ptr++;
@@ -38,9 +45,14 @@
   return p;
 }
 
+/* copy words so that dwords are 8-byte aligned, for 64bit value indirection; unaligned
+   access results in SIGBUS; not quite sure why compiler doesn't abstract this (maybe b/c
+   of not having any idea about our assembler code?) */
+DCulonglong dcbArgULongLong(DCArgs* p) { DCAligned64BitVal_t v; DCulong *l = (DCulong*)sparc_dword(p); v.l[0]=l[0]; v.l[1]=l[1]; return v.L; }
+DCdouble    dcbArgDouble   (DCArgs* p) { DCAligned64BitVal_t v; DCulong *l = (DCulong*)sparc_dword(p); v.l[0]=l[0]; v.l[1]=l[1]; return v.d; }
+
+/* rest of getters based on above functions */
 DCuint      dcbArgUInt     (DCArgs* p) { return *(DCuint*)sparc_word(p); }
-DCulonglong dcbArgULongLong(DCArgs* p) { return *(DCulonglong*)sparc_dword(p); }
-
 DClonglong  dcbArgLongLong (DCArgs* p) { return (DClonglong)dcbArgULongLong(p); }
 DCint       dcbArgInt      (DCArgs* p) { return (DCint)     dcbArgUInt(p); }
 DClong      dcbArgLong     (DCArgs* p) { return (DClong)    dcbArgUInt(p); }
@@ -52,6 +64,5 @@
 DCbool      dcbArgBool     (DCArgs* p) { return (DCbool)    dcbArgUInt(p); }
 DCpointer   dcbArgPointer  (DCArgs* p) { return (DCpointer) dcbArgUInt(p); }
 
-DCdouble    dcbArgDouble   (DCArgs* p) { return *(DCdouble*)sparc_dword(p); }
 DCfloat     dcbArgFloat    (DCArgs* p) { return *(DCfloat*) sparc_word(p); }