1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "executed"
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "null object"
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class cast exception thrown, with correct class name"
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class cast exception not thrown on same class"
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class cast exception not thrown on subclass"
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class not resolved"
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%verify "class already resolved"
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Check to see if a cast from one class to another is allowed.
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* check-cast vAA, class@BBBB */
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r3, rINST, lsr #8           @ r3<- AA
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FETCH(r2, 1)                        @ r2<- BBBB
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_VREG(r9, r3)                    @ r9<- object
159f601a917c8878204482c37aec7005054b6776fabuzbee    ldr     r0, [rSELF, #offThread_methodClassDex]    @ r0<- pDvmDex
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmp     r9, #0                      @ is object null?
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ldr     r0, [r0, #offDvmDex_pResClasses]    @ r0<- pDvmDex->pResClasses
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    beq     .L${opcode}_okay            @ null obj, cast always succeeds
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ldr     r1, [r0, r2, lsl #2]        @ r1<- resolved class
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmp     r1, #0                      @ have we resolved this before?
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    beq     .L${opcode}_resolve         @ not resolved, do it now
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_resolved:
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmp     r0, r1                      @ same class (trivial success)?
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bne     .L${opcode}_fullcheck       @ no, do full check
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_okay:
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    FETCH_ADVANCE_INST(2)               @ advance rPC, load rINST
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_INST_OPCODE(ip)                 @ extract opcode from rINST
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GOTO_OPCODE(ip)                     @ jump to next instruction
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project%break
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Trivial test failed, need to perform full check.  This is common.
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  r0 holds obj->clazz
35c560e30f68265068bed9eadf174d1e76288d2952Elliott Hughes     *  r1 holds desired class resolved from BBBB
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  r9 holds object
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_fullcheck:
39c560e30f68265068bed9eadf174d1e76288d2952Elliott Hughes    mov     r10, r1                     @ avoid ClassObject getting clobbered
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bl      dvmInstanceofNonTrivial     @ r0<- boolean result
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmp     r0, #0                      @ failed?
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bne     .L${opcode}_okay            @ no, success
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
44c560e30f68265068bed9eadf174d1e76288d2952Elliott Hughes    @ A cast has failed.  We need to throw a ClassCastException.
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    EXPORT_PC()                         @ about to throw
46c560e30f68265068bed9eadf174d1e76288d2952Elliott Hughes    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz (actual class)
47c560e30f68265068bed9eadf174d1e76288d2952Elliott Hughes    mov     r1, r10                     @ r1<- desired class
48c560e30f68265068bed9eadf174d1e76288d2952Elliott Hughes    bl      dvmThrowClassCastException
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    b       common_exceptionThrown
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Resolution required.  This is the least-likely path.
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  r2 holds BBBB
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *  r9 holds object
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project.L${opcode}_resolve:
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    EXPORT_PC()                         @ resolve() could throw
599f601a917c8878204482c37aec7005054b6776fabuzbee    ldr     r3, [rSELF, #offThread_method] @ r3<- self->method
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r1, r2                      @ r1<- BBBB
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r2, #0                      @ r2<- false
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ldr     r0, [r3, #offMethod_clazz]  @ r0<- method->clazz
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bl      dvmResolveClass             @ r0<- resolved ClassObject ptr
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cmp     r0, #0                      @ got null?
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    beq     common_exceptionThrown      @ yes, handle exception
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    mov     r1, r0                      @ r1<- class resolved from BBB
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ldr     r0, [r9, #offObject_clazz]  @ r0<- obj->clazz
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    b       .L${opcode}_resolved        @ pick up where we left off
69