/* Copyright (c) 2000 Sinby.com
   All Rights Reserved

   This project is covered by the GNU General Public License. */

/* $Id: common.h,v 1.1.1.1 2000/12/22 07:22:06 ryos Exp $ */

/*
 * sh/common.h
 * Common sh configuration information.
 */

#ifndef __sh_common_h
#define __sh_common_h

#define	ALIGNMENT_OF_SIZE(S)	((S) < 4 ? (S) : 4)

#if NEED_sysdepCallMethod

static inline void sysdepCallMethod(callMethodInfo *call) 
{
	unsigned int tmp1,tmp2;
	unsigned long ret0,ret1;
	unsigned long long longret;

	tmp1 = 0;
	tmp2 = 0;
	ret0 = 0;
	ret1 = 0;

#if 0
	int i;

	for( i = 0 ; i < call->nrargs ; i++ ) {
		if (( call->calltype[i] == 'L' ) && ( call->args[i].l == NULL )) {
			SignalError("java.lang.NullPointerException","");
		}
	}
#endif
	 
	asm volatile("
	add #-16,r15
0:
	mov #0,%0
	cmp/eq %0,%2
	bt	1f
	add #-1,%2
	mov.l @%3,%1
	mov.l %1,@-r15
	mov.b @%4,%1
	add	#-8,%3
	add	#-1,%4

	mov #1,%0
	cmp/eq	%0,%1
	bt	0b

	mov.l @%3,%1
	mov.l %1,@-r15
	add	#-8,%3
	add	#-1,%4
	bra 0b
	add #-1,%2

1:
	"
	:
	: "r" (tmp1) , 
	  "r" (tmp2) , 
	  "r" (call->nrargs) , 
	  "r" (&call->args[call->nrargs - 1]) , 
	  "r" (&call->callsize[call->nrargs - 1]));

	asm volatile ("
	mov.l @r15+,r4
	mov.l @r15+,r5
	mov.l @r15+,r6
	jsr @%2
	mov.l @r15+,r7

	mov  r1,%1
	mov  r0,%0
	"
	: "=r" (ret0),
	  "=r" (ret1)
	: "r" (call->function) 
	: "r4","r5","r6","r7");

	asm volatile (" 
	add %0,r15
	" 
	:
	: "r" ((call->nrargs)*4));

	switch(call->retsize) {
	case 0:
		/* Must be void.  */
		break;

	case 1:
		if (call->rettype == 'F') {
			call->ret->f = (jfloat)ret0;
		} else {
			call->ret->i = (jint)ret0;
		}
		break;

	default:
		assert(call->retsize == 2);

		longret = ret0;
		longret <<= 32;
		longret |= ret1;

		if (call->rettype == 'D') {
			call->ret->d = (jdouble)longret;
		} else {
			assert(call->rettype == 'J');
			call->ret->j = (jlong)longret;
		}
		break;
	}
}

#endif /* NEED_sysdepCallMethod */

#endif
