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

📄 invokenative_arm.s

📁 This is a resource based on j2me embedded,if you dont understand,you can connection with me .
💻 S
字号:
/* * @(#)invokeNative_arm.S	1.18 06/10/10 * * Copyright  1990-2008 Sun Microsystems, Inc. All Rights Reserved.   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER   *    * This program is free software; you can redistribute it and/or   * modify it under the terms of the GNU General Public License version   * 2 only, as published by the Free Software Foundation.    *    * This program is distributed in the hope that it will be useful, but   * WITHOUT ANY WARRANTY; without even the implied warranty of   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU   * General Public License version 2 for more details (a copy is   * included at /legal/license.txt).    *    * You should have received a copy of the GNU General Public License   * version 2 along with this work; if not, write to the Free Software   * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA   * 02110-1301 USA    *    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa   * Clara, CA 95054 or visit www.sun.com if you need additional   * information or have any questions.  * */#include "javavm/include/porting/defs.h"#include "javavm/include/asmmacros_cpu.h"	SET_SECTION_EXEC(invokeNative_arm)/* SUBROUTINE CVMjniInvokeNative *//* This function translates the "Java" calling convention into the "C" *//* calling 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 methods. *//* The most widely accepted StrongARM SA-100 programming model has *//* arguments passed to an invoked subroutine in registers a1-a4, with *//* any further arguments passed on the stack. *//* The first argument to CVMjniInvokeNative 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. *//* 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 (which is simply the address of *//* 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 CVMjniInvokeNative is *//* 0 if the native method returns void, 1 if the native *//* method returns a word, 2 if the native method returns a *//* double word, or -1 if the native method returns an object. */	ALIGN(4)	ENTRY(CVMjniInvokeNative)ENTRY1(CVMjniInvokeNative)/* Arguments: *//* a1	   JNI environment *//* a2	   native function *//* a3	   Java stack top *//* a4	   method descriptor *//* stk1	   number of argument words to be passed to native function *//* stk2	   class for static methods, or 0 for non-static methods *//* stk3     result pointer *//* Local registers: *//* l0 *//* l1	   return type syllable *//* l2	   sig word buffer *//* l4       dispatch base for arg/return type switch jump. *//* Results:	 *//* a1	return value word count or -1 for object */#define SIGPTR	a4#define SIGBYTE v3#define JSTKPTR v1#define CSTKPTR v7#define RETTYPE v5#define SIGBUFF  lr#define SWITCHBASE v2#define FuncPtr	ip#define TYPEMASK #0xf#define TYPESHIFT #4#define SAVESET v1-v7,fp#define SAVESIZE (8*4)    /* Set up registers for processing the signature, etc. */    stmfd   sp!, {SAVESET,lr}    /* IF YOU CHANGE THIS LINE, CHANGE THE MAP BELOW! */#define stk1	[fp, #SAVESIZE+4]#define stk2	[fp, #SAVESIZE+8]#define stk3	[fp, #SAVESIZE+12]/* transferring arguments *//* first 4 in register *//* The first argument (a1) is already the JNI env. *//* The next one is a3 or stk2 if it is non-zero (for static methods). */	mov	FuncPtr,a2	mov	JSTKPTR,a3	/* keep a backup for a3 */	mov	fp,sp	ldr	SIGBUFF, [SIGPTR], #4	/* preload signature */	and	RETTYPE,SIGBUFF,TYPEMASK /* stash return type for later use. */	mov	SIGBUFF,SIGBUFF, lsr TYPESHIFT	adr	SWITCHBASE,arg_jumps	/* load the base of the jump table */        ldr	a2, stk1	mov	a2, a2, asl #2#ifdef AAPCS	/* a2 is number of bytes of arguments. Be safe and assume all arguments */	/* will require 4 bytes of padding for alignment. */	sub	sp, sp, a2, asl #1	/* stack must be 8-byte aligned for AAPCS */	bic	sp, sp, #7#else	sub	sp, sp, a2#endif	mov	CSTKPTR,sp        ldr	a2, stk2	cmp	a2, #0	moveq	a2, JSTKPTR	addeq	JSTKPTR, JSTKPTR, #4LABEL(args_loop)	and	SIGBYTE,SIGBUFF,TYPEMASK	mov	SIGBUFF,SIGBUFF, lsr TYPESHIFT	ldr	pc, [SWITCHBASE, SIGBYTE, lsl #2]LABEL(arg_32)				/* move a 32-bit value from [JSTKPTR] to [CSTKPTR]. */	ldr	a3,[JSTKPTR], #4	and	SIGBYTE,SIGBUFF,TYPEMASK	str	a3,[CSTKPTR], #4	mov	SIGBUFF,SIGBUFF, lsr TYPESHIFT	ldr	pc, [SWITCHBASE, SIGBYTE, lsl #2]LABEL(arg_64)	ldmia	JSTKPTR!, {a3,SIGBYTE}#ifdef AAPCS	/* Round stack up to 8 byte boundary for AAPCS */	add	CSTKPTR, CSTKPTR, #4	bic	CSTKPTR, CSTKPTR, #7#endif		stmia	CSTKPTR!, {a3,SIGBYTE}	and	SIGBYTE,SIGBUFF,TYPEMASK	mov	SIGBUFF, SIGBUFF, lsr TYPESHIFT	ldr	pc, [SWITCHBASE, SIGBYTE, lsl #2]		LABEL(arg_object)	ldr	a3,[JSTKPTR],#4	cmp	a3,#0	and	SIGBYTE,SIGBUFF,TYPEMASK	beq	object_checked	sub	a3,JSTKPTR,#4LABEL(object_checked)	str	a3,[CSTKPTR], #4	mov	SIGBUFF,SIGBUFF, lsr TYPESHIFT	ldr	pc, [SWITCHBASE, SIGBYTE, lsl #2]LABEL(arg_reload)	/* get another word full of types */	/* then re-dispatch */	/* since most signatures are short, this does not happen */	/* very often. */	ldr	SIGBUFF, [SIGPTR], #4	/* preload signature */	and	SIGBYTE,SIGBUFF,TYPEMASK	mov	SIGBUFF,SIGBUFF, lsr TYPESHIFT	ldr	pc, [SWITCHBASE, SIGBYTE, lsl #2]LABEL(args_done)    /* The ARM procedure call standard we are using specifies that the first */    /* four arguments are passed in registers a1-a4.  a1 and a2 are both set. */    /* Now we just load up a3 and a4 with the first 2 arg method arguments. */    /* If there are no such args, this does not hurt anything. */	ldr	a3,[sp, #0]	ldr	a4,[sp, #4]#define TMP CSTKPTR	ldr	TMP, stk1	cmp	TMP,#2	addge	sp, sp, #8	adr	SWITCHBASE,ret_jumps		mov	lr, pc			/* for the debugger, for now */	BR_REG(FuncPtr)		ldr	a4, stk3		/* pointer to result buffer */	mov	sp, fp	/* thread the return address to the */	/* proper code for our return type */	ldr	pc,[SWITCHBASE, RETTYPE, lsl #2]LABEL(ret_obj)	str	a1,[a4]	mov	a1,#-1	/* -1 indicates object return */	ldmfd	sp!, {SAVESET, lr}	BR_REG(lr)	LABEL(ret_s32)		str	a1,[a4]	mov	a1,#1	/* 1 indicates single-word return */	ldmfd	sp!, {SAVESET, lr}	BR_REG(lr)LABEL(ret_s64)	stmia	a4, {a1,a2}	mov	a1,#2	/* 2 indicates double-word return */	ldmfd	sp!, {SAVESET, lr}	BR_REG(lr)#ifdef CVM_ARM_FLOAT_RESULT_IN_FLOAT_REGISTER	LABEL(ret_f32)		stfs	f0,[a4]	mov	a1,#1	/* 1 indicates single-word return */	ldmfd	sp!, {SAVESET, lr}	BR_REG(lr)LABEL(ret_f64)	stfd	f0,[a4]	mov	a1,#2	/* 2 indicates double-word return */	ldmfd	sp!, {SAVESET, lr}	BR_REG(lr)#endifLABEL(ret_void)	mov	a1,#0	/* 0 indicates void return */	ldmfd	sp!, {SAVESET, lr}	BR_REG(lr)LABEL(ret_jumps)			WORD(ret_void)	/* error */	WORD(ret_void)	/* ENDFUNC should not get called */	WORD(ret_void)	/* void */	WORD(ret_s32)		/* int */	WORD(ret_s32)		/* short */	WORD(ret_s32)		/* char */	WORD(ret_s64)		/* long */	WORD(ret_s32)		/* byte */#ifdef CVM_ARM_FLOAT_RESULT_IN_FLOAT_REGISTER		WORD(ret_f32)		/* float */	WORD(ret_f64)		/* double */#else	WORD(ret_s32)		/* float */	WORD(ret_s64)		/* double */#endif	WORD(ret_s32)		/* bool */	WORD(ret_obj)	WORD(ret_void)	/* this is invalid and should not get called */LABEL(arg_jumps)	WORD(arg_reload)	/* no more data this word: go get more */	WORD(args_done) 	/* end-of-args */	WORD(ret_void)	/* this is invalid and should not get called */	WORD(arg_32)		/* int */	WORD(arg_32)		/* short */	WORD(arg_32)		/* char */	WORD(arg_64)		/* long */	WORD(arg_32)		/* byte */	WORD(arg_32)		/* float */	WORD(arg_64)		/* double */	WORD(arg_32)		/* bool */	WORD(arg_object)	WORD(ret_void)	/* this is invalid and should not get called */

⌨️ 快捷键说明

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