⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sysdepcallmethod.h

📁 kaffe Java 解释器语言,源码,Java的子集系统,开放源代码
💻 H
字号:
/* * powerpc/sysdepCallMethod.h * Dynamically build function calls using PowerPC SVR4 ABI, AIX ABI or * Dawin ABI. * * Copyright (c) 2001 *	Edouard G. Parmelan.  All rights reserved. * * Copyright (c) 2001 *	Transvirtual Technologies, Inc.  All rights reserved. * * See the file "license.terms" for information on usage and redistribution * of this file. *//* This define will cause callMethodV and callMethodA to avoid   introducing unused slots after jlongs and jdoubles.  */#ifndef NO_HOLES# define NO_HOLES 1#endif/* ARG_TYPE is the type of a register used for passing arguments.  */#define ARG_TYPE	long/* ARG_TYPES is a parameter list declaration for a function type   that takes all possible arguments in registers.  */#define ARG_TYPES	ARG_TYPE, ARG_TYPE, ARG_TYPE, ARG_TYPE, ARG_TYPE, ARG_TYPE, ARG_TYPE, ARG_TYPE/* ARG_LIST is the argument list for such a function.  */#define ARG_LIST	a0, a1, a2, a3, a4, a5, a6, a7/* GPR_ARGS is the number of GPR (integer) registers for passing   arguments.  */#define GPR_ARGS	8/* FPR_ARGS is the number of FPR (float) registers for passing   arguments.  */#if defined(__APPLE__) || defined(_AIX)# define FPR_ARGS	13#else# define FPR_ARGS	8#endif/* ARG_DISPLACEMENT is the offset between the beginning of a   variable-sized array, allocated in the stack, and the position of   the first argument that can't be passed in a register.  */#if defined(__APPLE__)  /* -6 but __buildin_alloca() handle it */# define ARG_DISPLACEMENT	0#elif defined(_AIX)# define ARG_DISPLACEMENT	-6#else# define ARG_DISPLACEMENT	-2#endif/* ARG_GPR a case label and a statement that arranges for one integer   argument to be passed. */#define ARG_GPR(N) \    case N+1: a##N = gpr[N];/* ARG_FPR a case label and a statement that arranges for one float   argument to be passed. */#define ARG_FPR(N) \    case N+1: d##N = fpr[N];/* Make a call to a native or Java (JIT) method.  This assembly code should   build a standard C call using the passed call information.  By its   nature this is highly processor specific.  This function is mandatory   for both JIT and Interpreter (since stubs have now been deprecated).  */static inline void sysdepCallMethod(callMethodInfo* call){    void *func = call->function;    jvalue *callargs = call->args;    char *calltype = call->calltype;    jvalue *args = callargs;    jvalue *last = &callargs[call->nrargs];    int nr_gpr = 0;    int nr_fpr = 0;#if !defined(__APPLE__)    int nr_stack = 0;#endif    unsigned long *stack;    unsigned long *gpr;    double *fpr;    /* Compute gpr[], fpr[] and stack[] arrays' size */    while (args != last) {	switch (calltype[(args++) - callargs]) {	case 'D':#if defined(__APPLE__)	    if (nr_fpr < FPR_ARGS)		nr_fpr++;	    nr_gpr += 2;#else	    if (nr_fpr < FPR_ARGS) {		nr_fpr++;	    }	    else {		if (nr_stack & 1)		    nr_stack += 3;		else		    nr_stack += 2;	    }#endif	    break;	case 'F':#if defined(__APPLE__)	    if (nr_fpr < FPR_ARGS)		nr_fpr++;	    nr_gpr++;#else	    if (nr_fpr < FPR_ARGS) {		nr_fpr++;	    }	    else {		nr_stack++;	    }#endif	    break;	case 'J':#if defined(__APPLE__)	    nr_gpr += 2;#else	    if (nr_gpr & 1)		nr_gpr++;	    if ((nr_gpr + 1) < GPR_ARGS) {		nr_gpr += 2;	    }	    else {		if (nr_stack & 1)		    nr_stack += 3;		else		    nr_stack += 2;	    }#endif	    break;	default:#if defined(__APPLE__)	    nr_gpr++;#else	    if (nr_gpr < GPR_ARGS) {		nr_gpr++;	    }	    else {		nr_stack++;	    }#endif	}    }    /* Allocate all arrays with one big alloca() */#if defined(__APPLE__)    {	int nr;	/* Must allocate space of _all_ GPR_ARGS even if they are not           used.  */	if (nr_gpr < GPR_ARGS)	    nr_gpr = GPR_ARGS;	nr = nr_gpr + 2 * nr_fpr;	/* stack must be 16 bytes aligned */	nr = nr ^ (nr & 3);	stack = __builtin_alloca (4 * nr);	/* fpr[] is in callee local variables area.  */	fpr = (double*)(stack + nr_gpr);	/* gpr[] and stack[] are in called parameters area.  */	stack += ARG_DISPLACEMENT;	gpr = stack - GPR_ARGS;	stack = gpr;    }#else    {	int nr = nr_gpr + 2 * nr_fpr + nr_stack;	/* stack, if used, must be 16 bytes aligned */	if (nr_stack)	    nr = nr ^ (nr & 3);	/* stack[] is in called parameters area.  */	stack = __builtin_alloca (4 * nr);	/* gpr[] and fpr[] are in callee local variable area.  */	gpr = stack + nr_stack;	fpr = (double*)(gpr + nr_gpr);	/* if __buildin_alloc() does not handle link-area, skip it.  */	stack += ARG_DISPLACEMENT;	nr_gpr = 0;	nr_stack = 0;    }#endif    /* build gpr[], fpr[] and stack[] arrays */    nr_fpr = 0;    args = callargs;    while (args != last) {	switch (calltype[args - callargs]) {	case 'D':#if defined(__APPLE__)	    if (nr_fpr < FPR_ARGS)		fpr[nr_fpr++] = args->d;	    else		*(double*)stack = args->d;	    stack += 2;#else	    if (nr_fpr < FPR_ARGS) {		fpr[nr_fpr++] = args->d;	    }	    else {		if (((long)stack) & 4)		    stack++;		*(double*)stack = args->d;		stack += 2;	    }#endif	    break;	case 'F':#if defined(__APPLE__)	    if (nr_fpr < FPR_ARGS)		fpr[nr_fpr++] = (double)args->f;	    else		*(float*)stack = args->f;	    stack++;#else	    if (nr_fpr < FPR_ARGS) {		fpr[nr_fpr++] = (double)args->f;	    }	    else {		*(float*)stack = args->f;		stack++;	    }#endif	    break;	case 'J':#if defined(__APPLE__)	    *(long long*)stack = args->j;	    stack += 2;#else	    if (nr_gpr & 1)		nr_gpr++;	    if ((nr_gpr + 1) < GPR_ARGS) {		*((long long *) (&gpr[nr_gpr])) = args->j;		nr_gpr += 2;	    }	    else {		if (((long)stack) & 4)		    stack++;		*(long long*)stack = args->j;		stack += 2;	    }#endif	    break;	default:#if defined(__APPLE__)	    *(long*)stack = args->i;	    stack++;#else	    if (nr_gpr < GPR_ARGS) {		gpr[nr_gpr++] = args->i;	    }	    else {		*(long*)stack = args->i;		stack++;	    }#endif	}	args++;    }#if defined(__APPLE__)    nr_gpr = stack - gpr;    if (nr_gpr > GPR_ARGS)	nr_gpr = GPR_ARGS;#endif    {	register ARG_TYPE a0 asm("r3");	register ARG_TYPE a1 asm("r4");	register ARG_TYPE a2 asm("r5");	register ARG_TYPE a3 asm("r6");	register ARG_TYPE a4 asm("r7");	register ARG_TYPE a5 asm("r8");	register ARG_TYPE a6 asm("r9");	register ARG_TYPE a7 asm("r10");	register double d0 asm("fr1");	register double d1 asm("fr2");	register double d2 asm("fr3");	register double d3 asm("fr4");	register double d4 asm("fr5");	register double d5 asm("fr6");	register double d6 asm("fr7");	register double d7 asm("fr8");#if FPR_ARGS == 13	register double d8 asm("fr9");	register double d9 asm("fr10");	register double d10 asm("fr11");	register double d11 asm("fr12");	register double d12 asm("fr13");#endif	/* load FPR registers from fpr[] */	switch (nr_fpr) {#if FPR_ARGS == 13	ARG_FPR(12);	ARG_FPR(11);	ARG_FPR(10);	ARG_FPR(9);	ARG_FPR(8);#endif	ARG_FPR(7);	ARG_FPR(6);	ARG_FPR(5);	ARG_FPR(4);	ARG_FPR(3);	ARG_FPR(2);	ARG_FPR(1);	ARG_FPR(0);	/* case 0: */	}	/* load GPR registers from gpr[] */	switch (nr_gpr) {	ARG_GPR(7);	ARG_GPR(6);	ARG_GPR(5);	ARG_GPR(4);	ARG_GPR(3);	ARG_GPR(2);	ARG_GPR(1);	ARG_GPR(0);	/* case 0: */	}	/* Ensure that the assignments to f* registers won't be optimized away. */	asm ("" ::	     "f" (d0), "f" (d1), "f" (d2), "f" (d3),	     "f" (d4), "f" (d5), "f" (d6), "f" (d7));#if FPR_ARGS == 13	asm ("" ::	     "f" (d8), "f" (d9), "f" (d10), "f" (d11), "f" (d12));#endif	switch(call->retsize) {	case 0:	    /* Must be void.  */	    ((void (*)(ARG_TYPES))(func))(ARG_LIST);	    break;	case 1:	    if (call->rettype == 'F')		call->ret->f = ((jfloat (*)(ARG_TYPES))(func))(ARG_LIST);	    else /* Must be 32-bit or smaller int.  */		call->ret->i = ((jint (*)(ARG_TYPES))(func))(ARG_LIST);	    break;	default:	    /* It could've been `case 2;', but then we'd get an additional cmp	     * that we don't really need.  */	    if (call->rettype == 'D')		call->ret->d = ((jdouble (*)(ARG_TYPES))(func))(ARG_LIST);	    else /* Must be jlong.  */		call->ret->j = ((jlong (*)(ARG_TYPES))(func))(ARG_LIST);	    break;	}    }}#undef ARG_TYPE#undef ARG_TYPES#undef ARG_LIST#undef GPR_ARGS#undef FPR_ARGS#undef ARG_DISPLACEMENT#undef ARG_GPR#undef ARG_FPR

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -