OSDN Git Service

added/modified to support SuperH architecture
authorShin-ichiro KAWASAKI <shinichiro.kawasaki.mg@hitachi.com>
Tue, 23 Jun 2009 05:00:12 +0000 (14:00 +0900)
committerTony Sim <sim.chinyeow@renesas.com>
Tue, 23 Jun 2009 05:00:12 +0000 (14:00 +0900)
modified:   README.txt
modified:   vm/Android.mk
new file:   vm/arch/sh/CallSH4ABI.S

README.txt
vm/Android.mk
vm/arch/sh/CallSH4ABI.S [new file with mode: 0644]

index 6955945..2dccb13 100644 (file)
@@ -50,3 +50,11 @@ Here is the combined header comment:
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
+
+Native SH call bridge
+---------------------
+
+Native SH call bridge is written by
+Shin-ichiro KAWASAKI <shinichiro.kawasaki.mg@hitachi.com>
+and Contributed to Android by Hitachi, Ltd. and Renesas Solutions Corp.
index 9e559bd..e9b0200 100644 (file)
@@ -254,16 +254,25 @@ else
                mterp/out/InterpC-x86.c \
                mterp/out/InterpAsm-x86.S
   else
+    ifeq ($(TARGET_ARCH),sh)
+      LOCAL_SRC_FILES += \
+                       arch/sh/CallSH4ABI.S \
+                       arch/generic/Hints.c
+      LOCAL_SRC_FILES += \
+                       mterp/out/InterpC-allstubs.c \
+                       mterp/out/InterpAsm-allstubs.S
+    else
        # unknown architecture, try to use FFI
-    LOCAL_C_INCLUDES += external/libffi/$(TARGET_OS)-$(TARGET_ARCH)
-    LOCAL_SRC_FILES += \
-               arch/generic/Call.c \
-               arch/generic/Hints.c
-    LOCAL_SHARED_LIBRARIES += libffi
-       
-    LOCAL_SRC_FILES += \
-               mterp/out/InterpC-allstubs.c \
-               mterp/out/InterpAsm-allstubs.S
+      LOCAL_C_INCLUDES += external/libffi/$(TARGET_OS)-$(TARGET_ARCH)
+      LOCAL_SRC_FILES += \
+                       arch/generic/Call.c \
+                       arch/generic/Hints.c
+      LOCAL_SHARED_LIBRARIES += libffi
+                       
+      LOCAL_SRC_FILES += \
+                       mterp/out/InterpC-allstubs.c \
+                       mterp/out/InterpAsm-allstubs.S
+    endif
   endif
 endif
 
diff --git a/vm/arch/sh/CallSH4ABI.S b/vm/arch/sh/CallSH4ABI.S
new file mode 100644 (file)
index 0000000..f8b2ddc
--- /dev/null
@@ -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