$OpenBSD: patch-j2sdk1_3_1_src_solaris_javavm_runtime_invokeNative_arm_s,v 1.1 2005/06/03 17:27:54 kurt Exp $
--- j2sdk1.3.1/src/solaris/javavm/runtime/invokeNative_arm.s.orig	Fri May 27 20:00:30 2005
+++ j2sdk1.3.1/src/solaris/javavm/runtime/invokeNative_arm.s	Fri May 27 21:18:05 2005
@@ -0,0 +1,272 @@
+//
+// @(#)invokeNative_arm.s	0.00 05/04/25
+//
+// Copyright 1996, 1997 by Sun Microsystems, Inc.,
+// 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
+// All rights reserved.
+//
+// This software is the confidential and proprietary information
+// of Sun Microsystems, Inc. ("Confidential Information").  You
+// shall not disclose such Confidential Information and shall use
+// it only in accordance with the terms of the license agreement
+// you entered into with Sun.
+//
+
+// ARM version adopted from invokeNative_x86.s and sparc version by Dale Rahn.
+
+// XXX Likely other BSD's have a similar header, but since I do not know that
+// XXX I have taken the safe path and provided ELF-style defaults.
+#ifdef __OpenBSD__
+#include <machine/asm.h>
+#else
+
+#define _C_LABEL(x)	x
+#define _ENTRY(x) \
+	.section .text; .align 4; .globl x; .type x,@function; x:
+#define	ENTRY(y)	_ENTRY(_C_LABEL(y))
+
+#endif
+
+	.file "invokeNative_arm.s"
+
+// This function translates the "Java" calling convention into the
+// C convention used in native methods. Java VM passes all the
+// arguments in the Java stack, and expects the results to be placed there
+// as well. We therefore have to copy the arguments into the C stack (or
+// registers), and place the return values back into the Java stack.
+//
+// With a small sacrifise in efficiency, this approach avoids having to
+// generate a stub function for every native method.
+//
+// The arm processor passes initial arguments in registers  r0-r3 , with
+// additional arguments appearing on the stack,
+//
+// The first argument to sysInvokeNative is a pointer to the JNI
+// environment, which should be passed unmodified as the first argument
+// to the native method.
+//
+// The second argument is a pointer to the "real" native method function.
+//
+// The third argument (stk) is a pointer to the Java stack, where all
+// the arguments are stored (as stk[0], stk[1], etc.).
+//
+// The fourth argument is the "terse" signature of the native method,
+// which basically collapses all objects in the long signature into
+// one byte, since they're all treated the same.  This makes the parsing
+// in this routine simpler and faster.  See classload.c and classruntime.c
+// for details.
+//
+// The fifth argument is the total size (in 32-bit words) of the
+// arguments on the Java stack. Note that the Java stack does not have
+// any alignment requirement, and stores all arguments consecutively in
+// words and double words. The argument size includes the "this" pointer
+// for non-static methods.
+//
+// The sixth argument is 0 for non-static methods, or a jclass
+// for static methods. Non-static native methods receive an object
+// reference as the second argument (passed in the Java stack as
+// stk[0]). The "real" method arguments to non-static methods begin at
+// stk[1]. Static native methods receive a class reference as the second
+// argument.
+//
+// The return value of the native method is placed at stk[0] for
+// word-sized results, or at stk[0] and stk[1] for
+// double-word-sized results. The return value of sysInvokeNative is
+// stk if the native method returns void, stk+1 if the native
+// method returns a word, or stk+2 if the native method returns a
+// double word.
+
+// #define args_again \ // I don't know how to do a macro w/ this assembler
+//	movb	(%ebx), %cl \
+//	incl	%ebx \
+//	jmp	*arg_jumps(,%ecx,4)
+
+
+
+// Arguments
+// r0 ;     JNI environment
+// r1 ;     native method function
+// r2 ;     Java stack
+// r3 ;     method signature
+// stk1	;   total argument size
+// stk2 ;  class (if static)
+//
+// Results:	
+// r0	the adjusted Java stack top
+
+#define JSTKPTR	 	r4  // local java stack addr
+#define SWITCHBASE	r5  // pointer to jump table address
+#define SIGBYTE	 	r6  // scratch to load signature (4 bits)
+#define OSTKPTR	 	r7  // old java stack
+#define SIGVAL  	r8  // scratch to load signature (byte)
+#define SIGPTR	 	r9  // pointer to signature byte (string)
+#define RETTYPE	 	r9  // pointer to signature byte (string)
+#define CSTKPTR	 	r10 // address on C stack to push args
+
+#define FUNC		r12
+
+#define SAVEREG		r4-r10,fp
+#define SAVESPACE	(8*4)
+
+#define nargs_stk	[fp, #SAVESPACE+4]
+#define class_stk	[fp, #SAVESPACE+8]
+#define result_stk	[fp, #SAVESPACE+12]
+
+#define TYPEMASK	#0xf
+
+ENTRY(sysInvokeNative)
+	stmfd	sp!, {SAVEREG, lr}	// save all volatile regs
+
+	mov	fp, sp
+
+// first 4 args in register 
+// first arg is already in r0, JNI env
+
+	mov	FUNC, r1
+	mov	JSTKPTR, r2
+	mov	OSTKPTR, r2	// save copy
+	mov	SIGPTR, r3
+
+	adr	SWITCHBASE, arg_jumps  // load jump table address
+
+	ldr	r1, nargs_stk
+	mov	r1, r1, asl #2	// nargs -> words
+	sub	sp, sp, r1
+	mov	CSTKPTR,sp
+
+	ldr	r1, class_stk
+	cmp	r1, #0 		// check if static
+	moveq	r1, JSTKPTR	// static
+	addeq   JSTKPTR, JSTKPTR, #4
+
+args_loop:
+	ldrb	SIGVAL, [SIGPTR], #1
+	and	SIGBYTE, SIGVAL, TYPEMASK
+	ldr	SIGBYTE, [SWITCHBASE, SIGBYTE, lsl #2] // load offset
+	add	pc, SWITCHBASE, SIGBYTE
+
+arg_32:		// move a 32-bit value from [JSTKPTR] to [CSTKPTR].
+	ldr	r2, [JSTKPTR], #4
+	str	r2, [CSTKPTR], #4
+
+	b	args_loop
+
+arg_64:
+	ldmia	JSTKPTR!, {r2, SIGBYTE}
+	stmia	CSTKPTR!, {r2, SIGBYTE}
+
+	b	args_loop
+
+arg_object:
+	ldr	r2, [JSTKPTR], #4
+	cmp	r2, #0
+	subne	r2, JSTKPTR, #4		// pass address of object on java stk
+	str	r2, [CSTKPTR], #4
+
+	b	args_loop
+
+args_done:
+	// load first arguments into registers, according to ABI
+	// r0 and r1 were already set
+	ldr	r2, [sp, #0]
+	ldr	r3, [sp, #4]
+
+	// CSTKPTR used as scratch now
+	ldr	CSTKPTR, nargs_stk
+	cmp	CSTKPTR, #2
+	addge	sp, sp, #8	// if more than two args, adjust stack
+
+	adr	SWITCHBASE, ret_jumps
+
+	mov	lr,pc
+	mov	pc, FUNC
+
+	ldrb	SIGVAL, [SIGPTR] 
+
+	and	RETTYPE, SIGVAL, TYPEMASK // save return value
+	mov	r3, OSTKPTR			// original java stack
+	mov	sp, fp				// restore original C stack
+
+	ldr	RETTYPE, [SWITCHBASE, RETTYPE, lsl #2]
+	add	pc, SWITCHBASE, RETTYPE
+
+ret_obj:
+	cmp	r0, #0
+	ldrne	r0,[r0]
+	str	r0,[r3]
+	add	r0, r3, #4
+	ldmfd	sp!, {SAVEREG, pc}
+
+ret_s32:
+	str	r0, [r3]
+	add	r0, r3, #4
+	ldmfd	sp!, {SAVEREG, pc}
+
+ret_s64:
+        stmia   r3, {r0,r1}
+	add	r0, r3, #8
+	ldmfd	sp!, {SAVEREG, pc}
+
+ret_s8:
+	mov	r0, r0, asl #24
+	mov	r0, r0, asr #24
+	str	r0, [r3]
+	add	r0, r3, #4
+	ldmfd	sp!, {SAVEREG, pc}
+
+ret_u8:
+	and	r0, r0, #0xff
+	str	r0, [r3]
+	add	r0, r3, #4
+	ldmfd	sp!, {SAVEREG, pc}
+
+ret_s16:
+	mov	r0, r0, asl #16
+	mov	r0, r0, asr #16
+	str	r0, [r3]
+	add	r0, r3, #4
+	ldmfd	sp!, {SAVEREG, pc}
+
+ret_u16:
+	mov	r0, r0, lsl #16
+	mov	r0, r0, lsr #16
+	str	r0, [r3]
+	add	r0, r3, #4
+	ldmfd	sp!, {SAVEREG, pc}
+
+ret_void:
+	mov	r0, r3
+	ldmfd	sp!, {SAVEREG, pc}
+
+ // keep these offsets in sync with the enum in signature.h
+ // these tables have -<base> to make the PIC happy
+ret_jumps: 
+	.long ret_void-ret_jumps // this is bogus and shouldn't get called
+	.long ret_obj-ret_jumps
+	.long ret_s64-ret_jumps
+	.long ret_s64-ret_jumps // arm does soft float
+	.long ret_u8-ret_jumps
+	.long ret_s8-ret_jumps
+	.long ret_s16-ret_jumps
+	.long ret_u16-ret_jumps
+	.long ret_s32-ret_jumps
+	.long ret_s32-ret_jumps // arm does soft float
+	.long ret_void-ret_jumps
+
+ // keep these offsets in sync with the enum in signature.h
+arg_jumps:
+	.long args_done-arg_jumps // this is bogus and shouldn't get called
+	.long arg_object-arg_jumps
+	.long arg_64-arg_jumps
+	.long arg_64-arg_jumps
+	.long arg_32-arg_jumps // bool
+	.long arg_32-arg_jumps // byte
+	.long arg_32-arg_jumps // short
+	.long arg_32-arg_jumps // char
+	.long arg_32-arg_jumps // int
+	.long arg_32-arg_jumps // float
+	.long args_done-arg_jumps // for void - remind:  shouldn't happen
+	.long args_done-arg_jumps // end-of-args
+
+	.align	4
+	.size _C_LABEL(sysInvokeNative),.-_C_LABEL(sysInvokeNative)
