diff options
author | Jean-Baptiste Queru <jbq@google.com> | 2009-11-12 18:45:15 -0800 |
---|---|---|
committer | Jean-Baptiste Queru <jbq@google.com> | 2009-11-12 18:45:15 -0800 |
commit | 72e93344b4d1ffc71e9c832ec23de0657e5b04a5 (patch) | |
tree | 1a08d1e43d54200ea737234d865c4668c5d3535b /vm/arch | |
parent | dfd0afbcb08b871e224a28ecb4ed427a7693545c (diff) | |
download | android_dalvik-72e93344b4d1ffc71e9c832ec23de0657e5b04a5.tar.gz android_dalvik-72e93344b4d1ffc71e9c832ec23de0657e5b04a5.tar.bz2 android_dalvik-72e93344b4d1ffc71e9c832ec23de0657e5b04a5.zip |
eclair snapshot
Diffstat (limited to 'vm/arch')
-rw-r--r-- | vm/arch/arm/CallEABI.S | 7 | ||||
-rw-r--r-- | vm/arch/sh/CallSH4ABI.S | 400 | ||||
-rw-r--r-- | vm/arch/x86/Call386ABI.S | 24 |
3 files changed, 428 insertions, 3 deletions
diff --git a/vm/arch/arm/CallEABI.S b/vm/arch/arm/CallEABI.S index a98473fa2..9717e3b3d 100644 --- a/vm/arch/arm/CallEABI.S +++ b/vm/arch/arm/CallEABI.S @@ -154,7 +154,7 @@ DBG bne dvmAbort subeq r3, r3, #1 @ Do we have arg padding flags in "argInfo"? (just need to check hi bit) - teqs r2, #0 + teq r2, #0 bmi .Lno_arg_info /* @@ -239,7 +239,12 @@ DBG strcs ip, [r8] @ DEBUG DEBUG @ call the method ldr ip, [r4, #8] @ func +#ifdef __ARM_HAVE_BLX blx ip +#else + mov lr, pc + bx ip +#endif @ We're back, result is in r0 or (for long/double) r0-r1. @ diff --git a/vm/arch/sh/CallSH4ABI.S b/vm/arch/sh/CallSH4ABI.S new file mode 100644 index 000000000..f8b2ddc0b --- /dev/null +++ b/vm/arch/sh/CallSH4ABI.S @@ -0,0 +1,400 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Invoking JNI native method via SH4 ABI. + * This inplementation follows the spec found in following URL. + * http://www.ecos.sourceware.org/docs-1.3.1/ref/gnupro-ref/sh/SH_ch01.html#pgfId-461254 + + * This version supports SH4A little endian. + */ + .text + .align 4 + .type dvmPlatformInvoke, #function + .globl dvmPlatformInvoke + +/* + * @param r4 void* pEnv (used as scrach after invoking method) + * @param r5 ClassObject* clazz + * @param r6 int argInfo + * @param r7 int argc + * @param r15[0] const u4 * argv + * @param r15[1] const char * shorty + * @param r15[2] void * func + * @param r15[3] JValue * pReturn + * + * @remark r0,r1 Scratch before invoking method. + * Return value after invoking method. + * @remark r2 shorty pointer + * @remark r3 argv pointer before invoking method. + * pReturn after invoking method. + * @remark r8-11 Don't touch. + * @remark r12 status of r5-7 + * @remark r13 status of fr4-11 + * @remark r14 Keep stack pointer. + */ +dvmPlatformInvoke: + ## save preserved regsiters + mov.l r14, @-r15 + mov r15, r14 + add #4, r14 /* r14 = original r15 = stack pointer */ + mov.l r13, @-r15 + mov.l r12, @-r15 + sts.l pr, @-r15 + + # fetch arguments + mov.l @r14, r3 /* argv */ + mov.l @(4,r14), r2 /* shorty for argumnets */ + mov #1, r0 /* shorty's 1st byte specify ret value type. */ + add r0, r2 + +### initialize local variables + + ## r12 ... status of r6, and r7 + ## bit 1 << 0 : if r6 is available, it contains 1. + ## bit 1 << 1 : if r7 is available, it contains 1. + ## Note : r4 is always used to pass pEnv. + ## r5 is always used for clazz or object + mov #3, r12 /* b0000-0111 : r5-7 avialble. */ + + ## r13 ... status of fr4-fr11 + ## bit 1 << 0 : if fr4 is available, it contains 1. + ## bit 1 << 1 : if fr5 is available, it contains 1. + ## ... + ## bit 1 << 7 : if fr11 is available, it contains 1. + mov #0xFF, r13 /* b1111-1111 : fr4-11 avialble. */ + +### put arguments + + ## ... keep pEnv in r4 as is. + + ## check clazz + mov #0, r0 + cmp/eq r0, r5 + bf arg_loop /* if r5 has clazz, keep it as is */ + mov.l @r3+, r5 /* put object arg in r5 */ + + ## other args +arg_loop: +one_arg_handled: + mov.b @r2+, r0 + cmp/eq #0, r0 /* if (*shorty == '\0) */ + bf process_one_arg + bra arg_end /* no argument left */ + nop + +process_one_arg: + + ## check arg type + + cmp/eq #'F', r0 + bt jfloat_arg + + cmp/eq #'D', r0 + bt jdouble_arg + + cmp/eq #'J', r0 + bt jlong_arg + + ## other 32bit arg types + mov r12, r0 + cmp/eq #0, r0 + bt put_32bit_on_stack /* r6-7 not available */ + + tst #1, r0 + bt j32_arg_1 + mov.l @r3+, r6 /* put one arg in r6 */ + mov #1, r0 /* r6 is not available now. */ + not r0, r0 + and r0, r12 + bra one_arg_handled + nop +j32_arg_1: + tst #2, r0 + bt j32_arg_fatal_error + mov.l @r3+, r7 /* put one arg in r7 */ + mov #2, r0 /* r7 is not available now. */ + not r0, r0 + and r0, r12 + bra one_arg_handled + nop + +j32_arg_fatal_error: + bra j32_arg_fatal_error + nop + +jlong_arg: + mov r12, r0 + cmp/eq #0, r0 + bt put_64bit_on_stack /* r6-7 not available */ + + and #3, r0 + cmp/eq #3, r0 + bf put_64bit_on_stack /* consequent two registers not available. */ + mov.l @r3+, r6 /* put one arg in r6 and r7 */ + mov.l @r3+, r7 + mov #3, r0 /* r6 and r7 are not available now. */ + not r0, r0 + and r0, r12 + bra one_arg_handled + nop + + # utility routines are placed here make short range jumps available. +put_32bit_on_stack: + mov.l @r3+, r0 + mov.l r0, @-r15 + bra one_arg_handled + nop + +put_64bit_on_stack: + mov.l @r3+, r0 + mov.l r0, @-r15 /* Pay attention that the endianness is */ + mov.l @r3+, r0 /* once reversed. It is corrected when the */ + mov.l r0, @-r15 /* arguments on stack are revesred before */ + bra one_arg_handled /* jni call */ + nop + +jdouble_arg: + mov r13, r0 + cmp/eq #0, r0 + bt put_64bit_on_stack /* fr4-11 not available */ + + and #3, r0 + cmp/eq #3, r0 + bf jdouble_arg_1 + + fmov.s @r3+, fr5 /* put one arg to drX */ + fmov.s @r3+, fr4 + mov #3, r0 /* fr4-frX not available now. */ + not r0, r0 + and r0, r13 + bra one_arg_handled + nop + +jdouble_arg_1: + mov r13, r0 + and #12, r0 + cmp/eq #12, r0 + bf jdouble_arg_2 + + fmov.s @r3+, fr7 /* put one arg to drX */ + fmov.s @r3+, fr6 + mov #15, r0 /* fr4-frX not available now. */ + not r0, r0 + and r0, r13 + bra one_arg_handled + nop + +jdouble_arg_2: + mov r13, r0 + and #48, r0 + cmp/eq #48, r0 + bf jdouble_arg_3 + fmov.s @r3+, fr9 /* put one arg to drX */ + fmov.s @r3+, fr8 + mov #63, r0 /* fr4-frX not available now. */ + not r0, r0 + and r0, r13 + bra one_arg_handled + nop + +jdouble_arg_3: + mov r13, r0 + and #192, r0 + cmp/eq #192, r0 + bf put_64bit_on_stack + fmov.s @r3+, fr11 /* put one arg to drX */ + fmov.s @r3+, fr10 + mov #0, r13 /* fr4-fr11 all not available now. */ + bra one_arg_handled + nop + +jfloat_arg: + mov r13, r0 + cmp/eq #0, r0 + bt put_32bit_on_stack /* fr4-11 not available */ + + tst #2, r0 + bt jfloat_arg_1 + fmov.s @r3+, fr5 /* put one arg to frX */ + mov #2, r0 /* frX not available now. */ + not r0, r0 + and r0, r13 + bra one_arg_handled + nop + +jfloat_arg_1: + tst #1, r0 + bt jfloat_arg_2 + fmov.s @r3+, fr4 /* put one arg to frX */ + mov #1, r0 /* frX not available now. */ + not r0, r0 + and r0, r13 + bra one_arg_handled + nop + +jfloat_arg_2: + tst #8, r0 + bt jfloat_arg_3 + fmov.s @r3+, fr7 /* put one arg to frX */ + mov #8, r0 /* frX not available now. */ + not r0, r0 + and r0, r13 + bra one_arg_handled + nop + +jfloat_arg_3: + tst #4, r0 + bt jfloat_arg_4 + fmov.s @r3+, fr6 /* put one arg to frX */ + mov #4, r0 /* frX not available now. */ + not r0, r0 + and r0, r13 + bra one_arg_handled + nop + +jfloat_arg_4: + tst #32, r0 + bt jfloat_arg_5 + fmov.s @r3+, fr9 /* put one arg to frX */ + mov #32, r0 /* frX not available now. */ + not r0, r0 + and r0, r13 + bra one_arg_handled + nop + +jfloat_arg_5: + tst #16, r0 + bt jfloat_arg_6 + fmov.s @r3+, fr8 /* put one arg to frX */ + mov #16, r0 /* frX not available now. */ + not r0, r0 + and r0, r13 + bra one_arg_handled + nop + +jfloat_arg_6: + tst #128, r0 + bt jfloat_arg_7 + fmov.s @r3+, fr11 /* put one arg to frX */ + mov #127, r0 /* frX not available now. */ + not r0, r0 + and r0, r13 + bra one_arg_handled + nop + +jfloat_arg_7: + tst #64, r0 + bt jfloat_fatal_error + fmov.s @r3+, fr10 /* put one arg to frX */ + mov #64, r0 /* frX not available now. */ + not r0, r0 + and r0, r13 + bra one_arg_handled + nop + +jfloat_fatal_error: + bra jfloat_fatal_error: + nop + +arg_end: + + +### reverse the variables on stack + mov r14, r12 /* points to first arg on stack */ + add #-20, r12 + mov r15, r13 /* points to last arg on stack */ +arg_rev_loop: + cmp/hs r12, r13 /* When r13 >= r12 (unsigned), 1->T */ + bt arg_rev_end + mov.l @r12, r0 + mov.l @r13, r1 + mov.l r0, @r13 + mov.l r1, @r12 + add #-4, r12 + add #4, r13 + bra arg_rev_loop + nop + +arg_rev_end: + +### invoke the JNI function. + + mov.l @(8,r14), r0 + jsr @r0 + nop + +### pass the return value + + /* + * r0 and r1 keep return value. + */ + + ## fetch data + mov.l @(4,r14), r2 /* reload shorty */ + mov.b @r2, r2 /* first byte specifyes return value type. */ + mov.l @(12,r14), r3 /* pReturn */ + + ## check return value types + + mov #'V', r4 + cmp/eq r4, r2 + bt end + + mov #'F', r4 + cmp/eq r4, r2 + bt jfloat_ret + + mov #'D', r4 + cmp/eq r4, r2 + bt jdouble_ret + + mov #'J', r4 + cmp/eq r4, r2 + bt jlong_ret + + ## fall-through for other 32 bit java types. + + ## load return values +j32_ret: + bra end + mov.l r0, @r3 /* delay slot */ + +jfloat_ret: + bra end + fmov.s fr0, @r3 /* delay slot */ + +jdouble_ret: + fmov.s fr1, @r3 + mov #4, r0 + bra end + fmov.s fr0, @(r0,r3) /* delay slot */ + +jlong_ret: + mov.l r0, @r3 + bra end + mov.l r1, @(4,r3) /* delay slot */ + +end: + ## restore preserved registers + mov r14, r15 + add #-16, r15 + lds.l @r15+, pr + mov.l @r15+, r12 + mov.l @r15+, r13 + mov.l @r15+, r14 + + rts /* dvmPlatformInvoke returns void. */ + nop diff --git a/vm/arch/x86/Call386ABI.S b/vm/arch/x86/Call386ABI.S index 9e32bdd87..c98876c74 100644 --- a/vm/arch/x86/Call386ABI.S +++ b/vm/arch/x86/Call386ABI.S @@ -131,12 +131,32 @@ isClass: /* Is FP? */ cmpl $2,%ebx jle isFP - /* No need to distinguish between 32/64 - just save both */ + cmpl $4,%ebx /* smaller than 32-bits? */ + jg isSmall +storeRetval: + /* Blindly storing 64-bits won't hurt 32-bit case */ movl %eax,(%ecx) movl %edx,4(%ecx) jmp cleanUpAndExit +isSmall: + cmpl $7,%ebx /* S1? */ + jne checkShort + movsbl %al,%eax + movl %eax,(%ecx) + jmp cleanUpAndExit +checkShort: + cmpl $6,%ebx /* U2? */ + jne isSignedShort + movzwl %ax,%eax + movl %eax,(%ecx) + jmp cleanUpAndExit +isSignedShort: + /* Must be S2 */ + movswl %ax,%eax + movl %eax,(%ecx) + jmp cleanUpAndExit isFP: - /* Is single? */ + /* Is Float? */ cmpl $1,%ebx je saveFloat fstpl (%ecx) |