[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[cinvoke-svn] r84 - in trunk/cinvoke/lib: . arch
From: |
will |
Subject: |
[cinvoke-svn] r84 - in trunk/cinvoke/lib: . arch |
Date: |
10 Jul 2006 21:52:50 -0400 |
Author: will
Date: 2006-07-10 21:52:49 -0400 (Mon, 10 Jul 2006)
New Revision: 84
Modified:
trunk/cinvoke/lib/arch/cl_x86_win.h
trunk/cinvoke/lib/arch/empty_empty_empty.h
trunk/cinvoke/lib/arch/gcc_ppc_osx.c
trunk/cinvoke/lib/arch/gcc_ppc_osx.h
trunk/cinvoke/lib/arch/gcc_x64_unix.h
trunk/cinvoke/lib/arch/gcc_x86_unix.h
trunk/cinvoke/lib/cinvoke.c
trunk/cinvoke/lib/cinvoke.h
Log:
many ppc fixes
Modified: trunk/cinvoke/lib/arch/cl_x86_win.h
===================================================================
--- trunk/cinvoke/lib/arch/cl_x86_win.h 2006-07-09 16:50:38 UTC (rev 83)
+++ trunk/cinvoke/lib/arch/cl_x86_win.h 2006-07-11 01:52:49 UTC (rev 84)
@@ -100,6 +100,12 @@
#define ARCH_CALLBACK_ARG_OFFSET (96)
+#define ARCH_BIG_ENDIAN 0
+
#define ARCH_STACK_GROWS_DOWN 1
+#define ARCH_STACK_TOPSKIP 0
+
+#define ARCH_REGPARMS_IN_STACKSIZE 0
+
#endif
Modified: trunk/cinvoke/lib/arch/empty_empty_empty.h
===================================================================
--- trunk/cinvoke/lib/arch/empty_empty_empty.h 2006-07-09 16:50:38 UTC (rev 83)
+++ trunk/cinvoke/lib/arch/empty_empty_empty.h 2006-07-11 01:52:49 UTC (rev 84)
@@ -161,9 +161,24 @@
// you see where the first argument is stored.
#define ARCH_CALLBACK_ARG_OFFSET (96)
+// TODO: Set to 1 if CPU puts most signifigant byte
+// first in integers
+#define ARCH_BIG_ENDIAN 0
+
// TODO: Whether the stack grows larger as the
// stack pointer gets numerically smaller. Set to 1 on
// x86.
#define ARCH_STACK_GROWS_DOWN 1
+// TODO: Set this to the number of bytes to leave blank at the top
+// of the stack after the copied arguments. Usually 0. Note if you
+// set this to a value other than 0, you must allocate additional
+// space in ARCH_PUT_STACK_BYTES
+#define ARCH_STACK_TOPSKIP 0
+
+// TODO: Set this to 1 if args being passed in registers are
+// still allocated space on the stack, despite not being copied
+// there. Usually 0.
+#define ARCH_REGPARMS_IN_STACKSIZE 0
+
#endif
Modified: trunk/cinvoke/lib/arch/gcc_ppc_osx.c
===================================================================
--- trunk/cinvoke/lib/arch/gcc_ppc_osx.c 2006-07-09 16:50:38 UTC (rev 83)
+++ trunk/cinvoke/lib/arch/gcc_ppc_osx.c 2006-07-11 01:52:49 UTC (rev 84)
@@ -78,7 +78,8 @@
return CINV_SUCCESS;
}
-// XXX
+// XXX fix bug here where long long straddles registers and stack by
+// copying last integer register to stack if neccessary
const static int LEN = 4096;
char *arch_callback_stub(void *functionp, void *param,
@@ -114,34 +115,41 @@
}
int arch_is_register_parm(cinv_callconv_t callingconvention, int index,
int num_params, cinv_type_t types[]) {
-/* int numints = 0, numflts = 0;
+ int numints = 0, numflts = 0;
int i;
- for (i = 0; i < index; i++) {
- if (isflt(types[i]))
+ for (i = 0; i <= index; i++) {
+ if (isflt(types[i])) {
numflts++;
+ if (types[i] == CINV_T_FLOAT)
+ numints++;
+ else
+ numints += 2;
+ } else if (types[i] == CINV_T_EXTRALONG)
+ numints += 2;
else
numints++;
}
- return (isflt(types[index]) && numflts < 8) || (numints < 6);*/ // XXX
- return 1;
+ return (isflt(types[index]) && numflts <= 13) || (numints <= 8);
}
-/*
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)
+ double *toset[] = {
+ &(regparms->f1), &(regparms->f2), &(regparms->f3),
+ &(regparms->f4), &(regparms->f5), &(regparms->f6),
+ &(regparms->f7), &(regparms->f8), &(regparms->f9),
+ &(regparms->f10), &(regparms->f11), &(regparms->f12),
+ &(regparms->f13)
};
if (type == CINV_T_FLOAT)
- *((float *)toset[index]) = *(float *)p;
+ *toset[index] = *(float *)p;
else
- *((double *)toset[index]) = *(double *)p;
+ *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)
+ int *toset[] = {
+ &(regparms->r3), &(regparms->r4), &(regparms->r5),
+ &(regparms->r6), &(regparms->r7), &(regparms->r8),
+ &(regparms->r9), &(regparms->r10)
};
if (type == CINV_T_CHAR)
@@ -152,78 +160,99 @@
*(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
+ else if (type == CINV_T_EXTRALONG) {
+ *(toset[index]) = ((*(long long *)p) >> 32);
+ if (index < 7)
+ *(toset[index + 1]) = ((*(long long *)p) & 0xFFFFFFFF);
+ } 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[]) {
-/* int numints = 0, numflts = 0;
+ int numints = 0, numflts = 0;
int i;
for (i = 0; i < num_params; i++) {
if (isflt(types[i])) {
- if (numflts < 8)
+ if (numflts < 13)
set_flt(regparms, numflts, parameters[i],
types[i]);
numflts++;
+ if (types[i] == CINV_T_FLOAT)
+ numints++;
+ else
+ numints += 2;
} else {
- if (numints < 6)
+ if (numints < 8)
set_int(regparms, numints, parameters[i],
types[i]);
- numints++;
+ if (types[i] == CINV_T_EXTRALONG)
+ numints += 2;
+ else
+ numints++;
}
- }*/ // XXX
+ }
}
-/*
+
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)
+ double *toget[] = {
+ &(regparms->f1), &(regparms->f2), &(regparms->f3),
+ &(regparms->f4), &(regparms->f5), &(regparms->f6),
+ &(regparms->f7), &(regparms->f8), &(regparms->f9),
+ &(regparms->f10), &(regparms->f11), &(regparms->f12),
+ &(regparms->f13)
};
if (type == CINV_T_FLOAT)
- *(float *)po = *((float *)toget[index]);
+ *(float *)po = *toget[index];
else
- *(double *)po = *((double *)toget[index]);
+ *(double *)po = *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)
+ int *toget[] = {
+ &(regparms->r3), &(regparms->r4), &(regparms->r5),
+ &(regparms->r6), &(regparms->r7), &(regparms->r8),
+ &(regparms->r9), &(regparms->r10)
};
if (type == CINV_T_CHAR)
- *(char *)po = (char)*(toget[index]);
+ *(char *)po = *toget[index];
else if (type == CINV_T_SHORT)
- *(short *)po = (short)*(toget[index]);
+ *(short *)po = *toget[index];
else if (type == CINV_T_INT)
- *(int *)po = (int)*(toget[index]);
+ *(int *)po = *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]);
-}*/
+ *(long *)po = *toget[index];
+ else if (type == CINV_T_EXTRALONG) {
+ *(long long *)po = ((long long)*toget[index]) << 32;
+ if (index < 7)
+ *(long long *)po |= *toget[index + 1];
+ } 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[]) {
-/* int numints = 0, numflts = 0;
+ int numints = 0, numflts = 0;
int i;
for (i = 0; i < num_params; i++) {
if (isflt(types[i])) {
- if (numflts < 8)
+ if (numflts < 13)
get_flt(parameters_out[i], numflts, regparms,
types[i]);
numflts++;
+ if (types[i] == CINV_T_FLOAT)
+ numints++;
+ else
+ numints += 2;
} else {
- if (numints < 6)
+ if (numints < 8)
get_int(parameters_out[i], numints, regparms,
types[i]);
- numints++;
+ if (types[i] == CINV_T_EXTRALONG)
+ numints += 2;
+ else
+ numints++;
}
- }*/ // XXX
+ }
}
void arch_getval_char(ArchRetValue *archval, char *outval) {
Modified: trunk/cinvoke/lib/arch/gcc_ppc_osx.h
===================================================================
--- trunk/cinvoke/lib/arch/gcc_ppc_osx.h 2006-07-09 16:50:38 UTC (rev 83)
+++ trunk/cinvoke/lib/arch/gcc_ppc_osx.h 2006-07-11 01:52:49 UTC (rev 84)
@@ -196,25 +196,39 @@
"m" ((archvalue).ivalhi), \
"m" ((archvalue).dval) : \
"r3", "r4", "f1");
-// XXX
#define ARCH_PUT_STACK_BYTES(bcount) \
-;/*{ \
- long bc = bcount; \
- __asm__("subq %0, %%rsp" :: "m" (bc) : "%rsp"); \
-}*/
+{ \
+ int bc = bcount + 24; \
+ if (bc <= 32) \
+ __asm__("stwu r1, -32(r1)" ::: "r1"); \
+ else if (bc <= 48) \
+ __asm__("stwu r1, -48(r1)" ::: "r1"); \
+ else if (bc <= 64) \
+ __asm__("stwu r1, -64(r1)" ::: "r1"); \
+ else if (bc <= 128) \
+ __asm__("stwu r1, -128(r1)" ::: "r1"); \
+ else if (bc <= 256) \
+ __asm__("stwu r1, -256(r1)" ::: "r1"); \
+ else \
+ __asm__("stwu r1, -512(r1)" ::: "r1"); \
+}
#define ARCH_REMOVE_STACK_BYTES(bcount) \
-;/*{ \
- long bc = bcount; \
- __asm__("addq %0, %%rsp" :: "m" (bc) : "%rsp"); \
-}*/
+ __asm__("lwz r1, 0(r1)" ::: "r1");
+
#define ARCH_GET_STACK(sp) \
-;/* __asm__("movq %%rsp, %0" : "=m" (sp));*/
+ __asm__("stw r1, %0" : "=m" (sp));
#define ARCH_GET_FRAME_PTR(fp) \
;/* __asm__("movq %%rbp, %0" : "=m" (fp));*/
#define ARCH_CALLBACK_ARG_OFFSET (32)
+#define ARCH_BIG_ENDIAN 1
+
#define ARCH_STACK_GROWS_DOWN 1
+#define ARCH_STACK_TOPSKIP 24
+
+#define ARCH_REGPARMS_IN_STACKSIZE 1
+
#endif
Modified: trunk/cinvoke/lib/arch/gcc_x64_unix.h
===================================================================
--- trunk/cinvoke/lib/arch/gcc_x64_unix.h 2006-07-09 16:50:38 UTC (rev 83)
+++ trunk/cinvoke/lib/arch/gcc_x64_unix.h 2006-07-11 01:52:49 UTC (rev 84)
@@ -158,11 +158,13 @@
#define ARCH_PUT_STACK_BYTES(bcount) \
{ \
long bc = bcount; \
+ if ((bc % 16) != 0) bc += (16 - (bc % 16)); \
__asm__("subq %0, %%rsp" :: "m" (bc) : "%rsp"); \
}
#define ARCH_REMOVE_STACK_BYTES(bcount) \
{ \
long bc = bcount; \
+ if ((bc % 16) != 0) bc += (16 - (bc % 16)); \
__asm__("addq %0, %%rsp" :: "m" (bc) : "%rsp"); \
}
#define ARCH_GET_STACK(sp) \
@@ -173,6 +175,12 @@
#define ARCH_CALLBACK_ARG_OFFSET (32)
+#define ARCH_BIG_ENDIAN 0
+
#define ARCH_STACK_GROWS_DOWN 1
+#define ARCH_STACK_TOPSKIP 0
+
+#define ARCH_REGPARMS_IN_STACKSIZE 0
+
#endif
Modified: trunk/cinvoke/lib/arch/gcc_x86_unix.h
===================================================================
--- trunk/cinvoke/lib/arch/gcc_x86_unix.h 2006-07-09 16:50:38 UTC (rev 83)
+++ trunk/cinvoke/lib/arch/gcc_x86_unix.h 2006-07-11 01:52:49 UTC (rev 84)
@@ -95,6 +95,12 @@
#define ARCH_CALLBACK_ARG_OFFSET (4*10)
+#define ARCH_BIG_ENDIAN 0
+
#define ARCH_STACK_GROWS_DOWN 1
+#define ARCH_STACK_TOPSKIP 0
+
+#define ARCH_REGPARMS_IN_STACKSIZE 0
+
#endif
Modified: trunk/cinvoke/lib/cinvoke.c
===================================================================
--- trunk/cinvoke/lib/cinvoke.c 2006-07-09 16:50:38 UTC (rev 83)
+++ trunk/cinvoke/lib/cinvoke.c 2006-07-11 01:52:49 UTC (rev 84)
@@ -251,11 +251,13 @@
function->parmalignments = NULL;
function->parmmemsizes = NULL;
function->parmtypes = NULL;
+ function->regparms = NULL;
if (function->numparms > 0) {
function->parmstacksizes = malloc(function->numparms *
sizeof(int));
function->parmalignments = malloc(function->numparms *
sizeof(int));
function->parmmemsizes = malloc(function->numparms *
sizeof(int));
function->parmtypes = malloc(function->numparms *
sizeof(cinv_type_t));
+ function->regparms = malloc(function->numparms * sizeof(int));
if (!function->parmstacksizes || !function->parmalignments ||
!function->parmmemsizes || !function->parmtypes) {
@@ -263,6 +265,7 @@
free(function->parmalignments);
free(function->parmmemsizes);
free(function->parmtypes);
+ free(function->regparms);
free(function);
context_set_nomem(context);
return NULL;
@@ -276,6 +279,7 @@
free(function->parmalignments);
free(function->parmmemsizes);
free(function->parmtypes);
+ free(function->regparms);
free(function);
context_set_error(context, CINV_E_INVAL,
"The parameter format was not
recognized", 0);
@@ -290,7 +294,13 @@
}
for (index = 0; index < function->numparms; index++) {
- if (arch_is_register_parm(function->callconv, index,
function->numparms, function->parmtypes)) continue;
+ function->regparms[index] = arch_is_register_parm(
+ function->callconv, index,
+ function->numparms, function->parmtypes);
+#if !ARCH_REGPARMS_IN_STACKSIZE
+ if (function->regparms[index])
+ continue;
+#endif
if ((function->stacksize %
function->parmalignments[index]) != 0)
function->stacksize +=
(function->parmalignments[index] -
@@ -302,6 +312,7 @@
free(function->parmalignments);
free(function->parmmemsizes);
free(function->parmtypes);
+ free(function->regparms);
free(function);
context_set_error(context, CINV_E_INVAL,
"Too many parameters", 0);
@@ -319,6 +330,7 @@
free(function->parmalignments);
free(function->parmmemsizes);
free(function->parmtypes);
+ free(function->regparms);
free(function);
context_clear_error(context);
return CINV_SUCCESS;
@@ -329,55 +341,123 @@
void *returnvalout, void **parameters) {
ArchRetValue retval;
ArchRegParms regparms;
- int stacksize = 0, i;
+ int stackindex = 0, i;
+ char *stackptr;
arch_set_register_parms(®parms, function->callconv,
function->numparms, parameters, function->parmtypes);
+
+ if (function->stacksize) {
+ ARCH_PUT_STACK_BYTES(function->stacksize);
+ ARCH_GET_STACK(stackptr);
- for (i = function->numparms - 1; i >= 0; i--) {
- char *stackptr;
- int len = function->parmstacksizes[i];
- int lentmp = len;
- int align = function->parmalignments[i];
- int memsize = function->parmmemsizes[i];
- char *param = parameters[i];
+#if ARCH_STACK_SKIPTOP
+ stackindex += ARCH_STACK_SKIPTOP;
+#if ARCH_STACK_GROWS_DOWN
+ stackptr += ARCH_STACK_SKIPTOP;
+#else
+ stackptr -= ARCH_STACK_SKIPTOP;
+#endif
+#endif
- if (arch_is_register_parm(function->callconv, i,
function->numparms, function->parmtypes))
- continue;
+ for (i = function->numparms - 1; i >= 0; i--) {
+ int len = function->parmstacksizes[i];
+ int align = function->parmalignments[i];
+ int memsize = function->parmmemsizes[i];
+ int regparm = function->regparms[i];
+ int diff = len - memsize;
+ char *param = parameters[i];
+
+#if !ARCH_REGPARMS_IN_STACKSIZE
+ if (regparm)
+ continue;
+#endif
- if ((stacksize % align) != 0) {
- int s = (align - (stacksize % align));
- ARCH_PUT_STACK_BYTES(s);
- stacksize += s;
- }
+ if ((stackindex % align) != 0) {
+ int s = (align - (stackindex % align));
+ stackindex += s;
+#if ARCH_STACK_GROWS_DOWN
+ stackptr += s;
+#else
+ stackptr -= s;
+#endif
+ }
+#if ARCH_REGPARMS_IN_STACKSIZE
+ if (regparm) {
+ stackindex += len;
#if ARCH_STACK_GROWS_DOWN
- ARCH_PUT_STACK_BYTES(len);
- ARCH_GET_STACK(stackptr);
+ stackptr += len;
#else
- ARCH_GET_STACK(stackptr);
- ARCH_PUT_STACK_BYTES(len);
+ stackptr -= len;
#endif
- while (memsize) { // XXX might fail on big-endian machines
- *stackptr = *param;
- stackptr++;
- param++;
- memsize--;
- len--;
+ continue;
+ }
+#endif
+
+ stackindex += len;
+#if ARCH_STACK_GROWS_DOWN
+#if ARCH_BIG_ENDIAN
+ while (diff) {
+ *stackptr = '\0';
+ stackptr++;
+ diff--;
+ }
+ while (memsize) {
+ *stackptr = *param;
+ *stackptr++;
+ *param++;
+ memsize--;
+ }
+#else
+ while (memsize) {
+ *stackptr = *param;
+ *stackptr++;
+ *param++;
+ memsize--;
+ }
+ while (diff) {
+ *stackptr = '\0';
+ stackptr++;
+ diff--;
+ }
+#endif
+#else
+ stackptr -= len;
+#if ARCH_BIG_ENDIAN
+ while (diff) {
+ *stackptr = '\0';
+ stackptr++;
+ diff--;
+ }
+ while (memsize) {
+ *stackptr = *param;
+ *stackptr++;
+ *param++;
+ memsize--;
+ }
+#else
+ while (memsize) {
+ *stackptr = *param;
+ *stackptr++;
+ *param++;
+ memsize--;
+ }
+ while (diff) {
+ *stackptr = '\0';
+ stackptr++;
+ diff--;
+ }
+#endif
+ stackptr -= len;
+#endif
}
- while (len) {
- *stackptr = '\0';
- stackptr++;
- len--;
- }
-
- stacksize += lentmp;
}
ARCH_CALL(regparms, entrypoint)
ARCH_SAVE_RETURN(retval)
- if (function->callconv != CINV_CC_STDCALL && stacksize != 0) {
- ARCH_REMOVE_STACK_BYTES(stacksize)
+ if (function->callconv != CINV_CC_STDCALL && function->stacksize != 0) {
+ ARCH_REMOVE_STACK_BYTES(function->stacksize)
}
if (function->hasreturn)
@@ -423,11 +503,11 @@
return;
}
- if (arch_is_register_parm(cb->prototype->callconv, i,
- cb->prototype->numparms,
cb->prototype->parmtypes))
+ // XXX check regparms in stacksize
+ if (cb->prototype->regparms[i])
continue;
-
- #if ARCH_STACK_GROWS_DOWN
+ // XXX fix for stack directions/big-endian
+ #if ARCH_STACK_GROWS_DOWN
if ((numbytes %
cb->prototype->parmalignments[i]) != 0) {
int fix =
cb->prototype->parmalignments[i] -
(numbytes %
cb->prototype->parmalignments[i]);
@@ -438,7 +518,6 @@
smaller = cb->prototype->parmmemsizes[i];
if (cb->prototype->parmstacksizes[i] < smaller)
smaller =
cb->prototype->parmstacksizes[i];
- // XXX might fail on big-endian machines
memcpy(parameters[i], frameptr, smaller);
frameptr += cb->prototype->parmstacksizes[i];
numbytes += cb->prototype->parmstacksizes[i];
Modified: trunk/cinvoke/lib/cinvoke.h
===================================================================
--- trunk/cinvoke/lib/cinvoke.h 2006-07-09 16:50:38 UTC (rev 83)
+++ trunk/cinvoke/lib/cinvoke.h 2006-07-11 01:52:49 UTC (rev 84)
@@ -28,6 +28,9 @@
#ifndef _CINVOKE_H
#define _CINVOKE_H
+#define CINVOKE_VERSION_MAJOR 0
+#define CINVOKE_VERSION_MINOR 9
+
#include "cinvoke-arch.h"
#ifdef __cplusplus
@@ -124,6 +127,7 @@
int *parmalignments;
int *parmmemsizes;
cinv_type_t *parmtypes;
+ int *regparms;
short stacksize;
} CInvFunction;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [cinvoke-svn] r84 - in trunk/cinvoke/lib: . arch,
will <=