cinvoke-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cinvoke-svn] r57 - in trunk/cinvoke: lib lib/arch test


From: will
Subject: [cinvoke-svn] r57 - in trunk/cinvoke: lib lib/arch test
Date: 30 Jun 2006 00:39:43 -0400

Author: will
Date: 2006-06-30 00:39:43 -0400 (Fri, 30 Jun 2006)
New Revision: 57

Added:
   trunk/cinvoke/lib/Makefile
Modified:
   trunk/cinvoke/lib/Makefile.x64
   trunk/cinvoke/lib/Makefile.x86
   trunk/cinvoke/lib/arch/gcc_x64_unix.c
   trunk/cinvoke/lib/arch/gcc_x64_unix.h
   trunk/cinvoke/test/lib.c
   trunk/cinvoke/test/runtests.c
Log:
x64 port working


Added: trunk/cinvoke/lib/Makefile
===================================================================
--- trunk/cinvoke/lib/Makefile                          (rev 0)
+++ trunk/cinvoke/lib/Makefile  2006-06-30 04:39:43 UTC (rev 57)
@@ -0,0 +1,5 @@
+default:
+       echo "Use make from top-level directory"
+
+clean:
+       rm -f *.o arch/*.o libcinvoke.a

Modified: trunk/cinvoke/lib/Makefile.x64
===================================================================
--- trunk/cinvoke/lib/Makefile.x64      2006-06-30 02:56:43 UTC (rev 56)
+++ trunk/cinvoke/lib/Makefile.x64      2006-06-30 04:39:43 UTC (rev 57)
@@ -2,9 +2,6 @@
 
 all: $(TARGET)
 
-clean:
-       rm -f *.o $(TARGET)
-
 SRCS = cinvoke.c structure.c hashtable.c arch/gcc_x64_unix.c
 
 OBJS = $(SRCS:.c=.o)

Modified: trunk/cinvoke/lib/Makefile.x86
===================================================================
--- trunk/cinvoke/lib/Makefile.x86      2006-06-30 02:56:43 UTC (rev 56)
+++ trunk/cinvoke/lib/Makefile.x86      2006-06-30 04:39:43 UTC (rev 57)
@@ -2,9 +2,6 @@
 
 all: $(TARGET)
 
-clean:
-       rm -f *.o $(TARGET)
-
 SRCS = cinvoke.c structure.c hashtable.c arch/gcc_x86_unix.c
 
 OBJS = $(SRCS:.c=.o)

Modified: trunk/cinvoke/lib/arch/gcc_x64_unix.c
===================================================================
--- trunk/cinvoke/lib/arch/gcc_x64_unix.c       2006-06-30 02:56:43 UTC (rev 56)
+++ trunk/cinvoke/lib/arch/gcc_x64_unix.c       2006-06-30 04:39:43 UTC (rev 57)
@@ -77,7 +77,7 @@
 }
 
 const static int LEN = 4096;
-// XXX
+
 char *arch_callback_stub(void *functionp, void *param,
        short stacksize, cinv_callconv_t cc) {
        char *ret = mmap(0, LEN, PROT_EXEC|PROT_READ|PROT_WRITE,
@@ -85,15 +85,20 @@
        if (ret == MAP_FAILED)
                return NULL;
        
-       // void f() { ((void (*)(void *))0xAAAAAAAA)((void *)0xBBBBBBBB); }
+       //void f() {
+       //      __asm("movq %%rdi, %%r11" ::: "%r11");
+       //      ((void (*)(void *))0xAAAAAAAAAAAAAAAA)(
+       //              (void *)0xBBBBBBBBBBBBBBBB);
+       //}
        memcpy(ret,
-               "\x55\x89\xe5\x83\xec\x08\x83\xec\x0c\x68"
-               "\xbb\xbb\xbb\xbb\xb8\xaa\xaa\xaa\xaa\xff"
-               "\xd0\x83\xc4\x10\xc9\xc3",
-               26);
+               "\x55\x48\x89\xe5\x49\x89\xfb\x48\xb8"
+               "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+               "\x48\xbf\xbb\xbb\xbb\xbb\xbb\xbb\xbb\xbb"
+               "\xff\xd0\xc9\xc3",
+               31);
 
-       memcpy(ret + 10, &param, 4);
-       memcpy(ret + 15, &functionp, 4);
+       memcpy(ret + 9, &functionp, 8);
+       memcpy(ret + 19, &param, 8);
        
        return ret;
 }
@@ -101,17 +106,120 @@
        munmap(stub, LEN);
 }
 
-////////////////////////
-// XXX
+int isflt(cinv_type_t t) {
+       return (t == CINV_T_FLOAT) || (t == CINV_T_DOUBLE);
+}
 int arch_is_register_parm(cinv_callconv_t callingconvention, int index,
-       int num_params, cinv_type_t types[]) { return 0; }
+       int num_params, cinv_type_t types[]) {
+       int numints = 0, numflts = 0;
+       int i;
+       for (i = 0; i < index; i++) {
+               if (isflt(types[i]))
+                       numflts++;
+               else
+                       numints++;
+       }
+       return (isflt(types[index]) && numflts < 8) || (numints < 6);
+}
+
+void set_flt(ArchRegParms *regparms, int index, void *p, cinv_type_t type) {
+       long *toset[] = {
+               &(regparms->xmm0), &(regparms->xmm1), &(regparms->xmm2),
+               &(regparms->xmm3), &(regparms->xmm4), &(regparms->xmm5),
+               &(regparms->xmm6), &(regparms->xmm7)
+       };
+       
+       if (type == CINV_T_FLOAT)
+               *((float *)toset[index]) = *(float *)p;
+       else
+               *((double *)toset[index]) = *(double *)p;
+}
+void set_int(ArchRegParms *regparms, int index, void *p, cinv_type_t type) {
+       long *toset[] = {
+               &(regparms->rdi), &(regparms->rsi), &(regparms->rdx), 
+               &(regparms->rcx), &(regparms->r8), &(regparms->r9) 
+       };
+       
+       if (type == CINV_T_CHAR)
+               *(toset[index]) = *(char *)p;
+       else if (type == CINV_T_SHORT)
+               *(toset[index]) = *(short *)p;
+       else if (type == CINV_T_INT)
+               *(toset[index]) = *(int *)p;
+       else if (type == CINV_T_LONG)
+               *(toset[index]) = *(long *)p;
+       else if (type == CINV_T_EXTRALONG)
+               *(toset[index]) = *(long long *)p;
+       else
+               *(toset[index]) = (long)*(void **)p;
+}
+
 void arch_set_register_parms(ArchRegParms *regparms, 
        cinv_callconv_t callingconvention, int num_params, void *parameters[], 
-       cinv_type_t types[]) {}
+       cinv_type_t types[]) {
+       int numints = 0, numflts = 0;
+       int i;
+       for (i = 0; i < num_params; i++) {
+               if (isflt(types[i])) {
+                       if (numflts < 8)
+                               set_flt(regparms, numflts, parameters[i], 
types[i]);
+                       numflts++;
+               } else {
+                       if (numints < 6)
+                               set_int(regparms, numints, parameters[i], 
types[i]);
+                       numints++;
+               }
+       }
+}
+void get_flt(void *po, int index, ArchRegParms *regparms, cinv_type_t type) {
+       long *toget[] = {
+               &(regparms->xmm0), &(regparms->xmm1), &(regparms->xmm2),
+               &(regparms->xmm3), &(regparms->xmm4), &(regparms->xmm5),
+               &(regparms->xmm6), &(regparms->xmm7)
+       };
+       
+       if (type == CINV_T_FLOAT)
+               *(float *)po = *((float *)toget[index]);
+       else
+               *(double *)po = *((double *)toget[index]);
+}
+void get_int(void *po, int index, ArchRegParms *regparms, cinv_type_t type) {
+       long *toget[] = {
+               &(regparms->rdi), &(regparms->rsi), &(regparms->rdx), 
+               &(regparms->rcx), &(regparms->r8), &(regparms->r9) 
+       };
+       
+       if (type == CINV_T_CHAR)
+               *(char *)po = (char)*(toget[index]);
+       else if (type == CINV_T_SHORT)
+               *(short *)po = (short)*(toget[index]);
+       else if (type == CINV_T_INT)
+               *(int *)po = (int)*(toget[index]);
+       else if (type == CINV_T_LONG)
+               *(long *)po = *(toget[index]);
+       else if (type == CINV_T_EXTRALONG)
+               *(long long *)po = (long long)*(toget[index]);
+       else
+               *(void **)po = (void *)*(toget[index]);
+}
+
 void arch_get_register_parms(ArchRegParms *regparms,
        cinv_callconv_t callingconvention, int num_params, void 
*parameters_out[],
-       cinv_type_t types[]) {}
-////////////////////////
+       cinv_type_t types[]) {
+       int numints = 0, numflts = 0;
+       int i;
+       for (i = 0; i < num_params; i++) {
+               if (isflt(types[i])) {
+                       if (numflts < 8)
+                               get_flt(parameters_out[i], numflts, regparms, 
types[i]);
+                       numflts++;
+               } else {
+                       if (numints < 6)
+                               get_int(parameters_out[i], numints, regparms, 
types[i]);
+                       numints++;
+               }
+       }
+}
 
 void arch_getval_char(ArchRetValue *archval, char *outval) {
        *outval = archval->ival;
@@ -129,8 +237,8 @@
        *outval = archval->ival;
 }
 void arch_getval_float(ArchRetValue *archval, float *outval) {
-       double d = *(double *)&archval->dval;
-       *outval = (float)d;
+       float f = *(float *)&archval->dval;
+       *outval = f;
 }
 void arch_getval_double(ArchRetValue *archval, double *outval) {
        double d = *(double *)&archval->dval;
@@ -156,11 +264,10 @@
        archval->ival = val;
 }
 void arch_setval_float(ArchRetValue *archval, float val) {
-       double d = (double)val;
-       archval->dval = *(long *)&d;
+       *((float *)&archval->dval) = val;
 }
 void arch_setval_double(ArchRetValue *archval, double val) {
-       archval->dval = *(long *)&val;
+       *((double *)&archval->dval) = val;
 }
 void arch_setval_ptr(ArchRetValue *archval, void *val) {
        archval->ival = (long)val;

Modified: trunk/cinvoke/lib/arch/gcc_x64_unix.h
===================================================================
--- trunk/cinvoke/lib/arch/gcc_x64_unix.h       2006-06-30 02:56:43 UTC (rev 56)
+++ trunk/cinvoke/lib/arch/gcc_x64_unix.h       2006-06-30 04:39:43 UTC (rev 57)
@@ -71,13 +71,13 @@
 #define CINV_T_4BYTE CINV_T_INT
 #define CINV_T_8BYTE CINV_T_EXTRALONG
 
-// XXX aligning stack on 16-byte boundary may be important
-
 /////////////////////////////////////
 // macros
 /////////////////////////////////////
+// note we use r11 instead of rdi, this is because we
+// saved this value in the callback stub
 #define ARCH_SAVE_REGPARMS(regparms) \
-       __asm__("movq %%rdi, %0; \
+       __asm__("movq %%r11, %0; \
                movq %%rsi, %1; \
                movq %%rdx, %2; \
                movq %%rcx, %3; \
@@ -156,11 +156,15 @@
                        "%rax", "%xmm0");
 
 #define ARCH_PUT_STACK_BYTES(bcount) \
-       __asm__("subq %0, %%rsp" :: "m" (bcount) : "%rsp");
-
+{ \
+       long bc = bcount; \
+       __asm__("subq %0, %%rsp" :: "m" (bc) : "%rsp"); \
+}
 #define ARCH_REMOVE_STACK_BYTES(bcount) \
-       __asm__("addq %0, %%rsp" :: "m" (bcount) : "%rsp");
-
+{ \
+       long bc = bcount; \
+       __asm__("addq %0, %%rsp" :: "m" (bc) : "%rsp"); \
+}
 #define ARCH_GET_STACK(sp) \
        __asm__("movq %%rsp, %0" : "=m" (sp));
 

Modified: trunk/cinvoke/test/lib.c
===================================================================
--- trunk/cinvoke/test/lib.c    2006-06-30 02:56:43 UTC (rev 56)
+++ trunk/cinvoke/test/lib.c    2006-06-30 04:39:43 UTC (rev 57)
@@ -52,22 +52,29 @@
 }
 DLLEXPORT float test4() {
        printf("test4\n");
-       return .0000000000000124422f;
+       return 1.1000000000000124422f;
 }
 DLLEXPORT double test5() {
        printf("test5\n");
-       return .000000000000000000004093840394830948304983049230920124422;
+       return 1.100000000000000000004093840394830948304983049230920124422;
 }
 DLLEXPORT long long int test6(int a0, long long int a1, float a2, double a3, 
char a4) {
 #ifdef _WIN32
        char buf[20];
        _i64toa(a1, buf, 10);
-       printf("test6: %d %s %f %f %c (want 11 22 33.0 44.0 5)\n", a0, buf, a2, 
a3, a4);
+       printf("test6: %d %s %f %f %c (want 11 22 %f %f 5)\n", a0, buf, a2, a3, 
a4,
+               33.5, 44.5);
 #else
-       printf("test6: %d %lld %f %f %c (want 11 22 33.0 44.0 5)\n", a0, a1, 
a2, a3, a4);
+       printf("test6: %d %lld %f %f %c (want 11 22 %f %f 5)\n", a0, a1, a2, 
a3, a4,
+               33.5, 44.5);
 #endif
        return 0x0A0A0A0A0ALL;
 }
 DLLEXPORT void test9(float (CDECL *f)(int, char, int)) {
        printf("test9: %f (want 11.0)\n", f(22, 'A', 44));
 }
+DLLEXPORT float test10(int i1, short i2, char i3, long i4, long i5,
+       int i6, int i7, long i8, short i9) {
+       printf("test10: %d %d %c %ld %ld %d %d %ld %d (want 111 222 3 444 555 
666 777 888 999\n", i1, i2, i3, i4, i5, i6, i7, i8, i9);
+       return 0.7f;
+}

Modified: trunk/cinvoke/test/runtests.c
===================================================================
--- trunk/cinvoke/test/runtests.c       2006-06-30 02:56:43 UTC (rev 56)
+++ trunk/cinvoke/test/runtests.c       2006-06-30 04:39:43 UTC (rev 57)
@@ -98,7 +98,7 @@
                return 0;
        }
 
-       if (retval < 0 || retval > 1) {
+       if (retval < 1 || retval > 2) {
                printf("retval = %g\n", retval);
                return 0;
        }
@@ -114,7 +114,7 @@
                return 0;
        }
 
-       if (retval < 0 || retval > 1) {
+       if (retval < 1 || retval > 2) {
                printf("retval = %g\n", retval);
                return 0;
        }
@@ -127,8 +127,8 @@
 
        int arg1 = 11;
        long long int arg2 = 22;
-       float arg3 = 33.0f;
-       double arg4 = 44.0;
+       float arg3 = 33.5f;
+       double arg4 = 44.5;
        char arg5 = '5';
        
        void *args[5] = { &arg1, &arg2, &arg3, &arg4, &arg5 };
@@ -290,6 +290,35 @@
        return 1;
 }
 
+int test10(CInvContext *ctx, CInvLibrary *lib, void *ep,
+       CInvFunction *f) {
+       float retval;
+
+       int arg1 = 111;
+       short arg2 = 222;
+       char arg3 = '3';
+       long arg4 = 444;
+       long arg5 = 555;
+       int arg6 = 666;
+       int arg7 = 777;
+       long arg8 = 888;
+       short arg9 = 999;
+       
+       void *args[9] = { &arg1, &arg2, &arg3, &arg4, &arg5, &arg6, &arg7, 
&arg8, &arg9 };
+
+       if (!cinv_function_invoke(ctx, f, ep, &retval, args)) {
+               fprintf(stderr, "invoke failed: %s\n", 
cinv_context_geterrormsg(ctx));
+               return 0;
+       }
+       
+       if (retval < 0 || retval > 1) {
+               printf("retval = %f\n", retval);
+               return 0;
+       }
+       return 1;
+}
+
+
 #define UPDATE0(test) \
        if (test(ctx)) \
                succeeded++; \
@@ -348,6 +377,7 @@
        UPDATE0(test7);
        UPDATE0(test8);
        UPDATE(test9, "", "p");
+       UPDATE(test10, "f", "isclliils");
        
        if (!cinv_library_delete(ctx, lib)) {
                fprintf(stderr, "Error deleting library: %s\n",





reply via email to

[Prev in Thread] Current Thread [Next in Thread]