1*795d594fSAndroid Build Coastguard Worker%def op_invoke_custom(): 2*795d594fSAndroid Build Coastguard Worker EXPORT_PC 3*795d594fSAndroid Build Coastguard Worker FETCH w0, 1 // call_site index, first argument of runtime call. 4*795d594fSAndroid Build Coastguard Worker b NterpCommonInvokeCustom 5*795d594fSAndroid Build Coastguard Worker 6*795d594fSAndroid Build Coastguard Worker%def op_invoke_custom_range(): 7*795d594fSAndroid Build Coastguard Worker EXPORT_PC 8*795d594fSAndroid Build Coastguard Worker FETCH w0, 1 // call_site index, first argument of runtime call. 9*795d594fSAndroid Build Coastguard Worker b NterpCommonInvokeCustomRange 10*795d594fSAndroid Build Coastguard Worker 11*795d594fSAndroid Build Coastguard Worker%def invoke_direct_or_super(helper="", range="", is_super=""): 12*795d594fSAndroid Build Coastguard Worker EXPORT_PC 13*795d594fSAndroid Build Coastguard Worker // Fast-path which gets the method from thread-local cache. 14*795d594fSAndroid Build Coastguard Worker% fetch_from_thread_cache("x0", miss_label="2f") 15*795d594fSAndroid Build Coastguard Worker1: 16*795d594fSAndroid Build Coastguard Worker // Load the first argument (the 'this' pointer). 17*795d594fSAndroid Build Coastguard Worker FETCH w1, 2 18*795d594fSAndroid Build Coastguard Worker .if !$range 19*795d594fSAndroid Build Coastguard Worker and w1, w1, #0xf 20*795d594fSAndroid Build Coastguard Worker .endif 21*795d594fSAndroid Build Coastguard Worker GET_VREG w1, w1 22*795d594fSAndroid Build Coastguard Worker cbz w1, common_errNullObject // bail if null 23*795d594fSAndroid Build Coastguard Worker b $helper 24*795d594fSAndroid Build Coastguard Worker2: 25*795d594fSAndroid Build Coastguard Worker mov x0, xSELF 26*795d594fSAndroid Build Coastguard Worker ldr x1, [sp] 27*795d594fSAndroid Build Coastguard Worker mov x2, xPC 28*795d594fSAndroid Build Coastguard Worker bl nterp_get_method 29*795d594fSAndroid Build Coastguard Worker .if $is_super 30*795d594fSAndroid Build Coastguard Worker b 1b 31*795d594fSAndroid Build Coastguard Worker .else 32*795d594fSAndroid Build Coastguard Worker tbz x0, #0, 1b 33*795d594fSAndroid Build Coastguard Worker and x0, x0, #-2 // Remove the extra bit that marks it's a String.<init> method. 34*795d594fSAndroid Build Coastguard Worker .if $range 35*795d594fSAndroid Build Coastguard Worker b NterpHandleStringInitRange 36*795d594fSAndroid Build Coastguard Worker .else 37*795d594fSAndroid Build Coastguard Worker b NterpHandleStringInit 38*795d594fSAndroid Build Coastguard Worker .endif 39*795d594fSAndroid Build Coastguard Worker .endif 40*795d594fSAndroid Build Coastguard Worker 41*795d594fSAndroid Build Coastguard Worker%def op_invoke_direct(): 42*795d594fSAndroid Build Coastguard Worker% invoke_direct_or_super(helper="NterpCommonInvokeInstance", range="0", is_super="0") 43*795d594fSAndroid Build Coastguard Worker 44*795d594fSAndroid Build Coastguard Worker%def op_invoke_direct_range(): 45*795d594fSAndroid Build Coastguard Worker% invoke_direct_or_super(helper="NterpCommonInvokeInstanceRange", range="1", is_super="0") 46*795d594fSAndroid Build Coastguard Worker 47*795d594fSAndroid Build Coastguard Worker%def op_invoke_super(): 48*795d594fSAndroid Build Coastguard Worker% invoke_direct_or_super(helper="NterpCommonInvokeInstance", range="0", is_super="1") 49*795d594fSAndroid Build Coastguard Worker 50*795d594fSAndroid Build Coastguard Worker%def op_invoke_super_range(): 51*795d594fSAndroid Build Coastguard Worker% invoke_direct_or_super(helper="NterpCommonInvokeInstanceRange", range="1", is_super="1") 52*795d594fSAndroid Build Coastguard Worker 53*795d594fSAndroid Build Coastguard Worker%def op_invoke_polymorphic(): 54*795d594fSAndroid Build Coastguard Worker EXPORT_PC 55*795d594fSAndroid Build Coastguard Worker // No need to fetch the target method. 56*795d594fSAndroid Build Coastguard Worker // Load the first argument (the 'this' pointer). 57*795d594fSAndroid Build Coastguard Worker FETCH w1, 2 58*795d594fSAndroid Build Coastguard Worker and w1, w1, #0xf 59*795d594fSAndroid Build Coastguard Worker GET_VREG w1, w1 60*795d594fSAndroid Build Coastguard Worker cbz w1, common_errNullObject // bail if null 61*795d594fSAndroid Build Coastguard Worker b NterpCommonInvokePolymorphic 62*795d594fSAndroid Build Coastguard Worker 63*795d594fSAndroid Build Coastguard Worker%def op_invoke_polymorphic_range(): 64*795d594fSAndroid Build Coastguard Worker EXPORT_PC 65*795d594fSAndroid Build Coastguard Worker // No need to fetch the target method. 66*795d594fSAndroid Build Coastguard Worker // Load the first argument (the 'this' pointer). 67*795d594fSAndroid Build Coastguard Worker FETCH w1, 2 68*795d594fSAndroid Build Coastguard Worker GET_VREG w1, w1 69*795d594fSAndroid Build Coastguard Worker cbz w1, common_errNullObject // bail if null 70*795d594fSAndroid Build Coastguard Worker b NterpCommonInvokePolymorphicRange 71*795d594fSAndroid Build Coastguard Worker 72*795d594fSAndroid Build Coastguard Worker%def invoke_interface(range=""): 73*795d594fSAndroid Build Coastguard Worker% slow_path = add_slow_path(invoke_interface_slow_path, range) 74*795d594fSAndroid Build Coastguard Worker EXPORT_PC 75*795d594fSAndroid Build Coastguard Worker // Fast-path which gets the method from thread-local cache. 76*795d594fSAndroid Build Coastguard Worker% fetch_from_thread_cache("x26", miss_label=slow_path) 77*795d594fSAndroid Build Coastguard Worker.L${opcode}_resume: 78*795d594fSAndroid Build Coastguard Worker // First argument is the 'this' pointer. 79*795d594fSAndroid Build Coastguard Worker FETCH w1, 2 80*795d594fSAndroid Build Coastguard Worker .if !$range 81*795d594fSAndroid Build Coastguard Worker and w1, w1, #0xf 82*795d594fSAndroid Build Coastguard Worker .endif 83*795d594fSAndroid Build Coastguard Worker GET_VREG w1, w1 84*795d594fSAndroid Build Coastguard Worker // Note: if w1 is null, this will be handled by our SIGSEGV handler. 85*795d594fSAndroid Build Coastguard Worker ldr w2, [x1, #MIRROR_OBJECT_CLASS_OFFSET] 86*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF w2 87*795d594fSAndroid Build Coastguard Worker // Test the first two bits of the fetched ArtMethod: 88*795d594fSAndroid Build Coastguard Worker // - If the first bit is set, this is a method on j.l.Object 89*795d594fSAndroid Build Coastguard Worker // - If the second bit is set, this is a default method. 90*795d594fSAndroid Build Coastguard Worker tst w26, #0x3 91*795d594fSAndroid Build Coastguard Worker b.ne 2f 92*795d594fSAndroid Build Coastguard Worker ldrh w3, [x26, #ART_METHOD_IMT_INDEX_OFFSET] 93*795d594fSAndroid Build Coastguard Worker1: 94*795d594fSAndroid Build Coastguard Worker ldr x2, [x2, #MIRROR_CLASS_IMT_PTR_OFFSET_64] 95*795d594fSAndroid Build Coastguard Worker ldr x0, [x2, w3, uxtw #3] 96*795d594fSAndroid Build Coastguard Worker .if $range 97*795d594fSAndroid Build Coastguard Worker b NterpCommonInvokeInterfaceRange 98*795d594fSAndroid Build Coastguard Worker .else 99*795d594fSAndroid Build Coastguard Worker b NterpCommonInvokeInterface 100*795d594fSAndroid Build Coastguard Worker .endif 101*795d594fSAndroid Build Coastguard Worker2: 102*795d594fSAndroid Build Coastguard Worker tbnz w26, #0, 3f 103*795d594fSAndroid Build Coastguard Worker and x26, x26, #-4 104*795d594fSAndroid Build Coastguard Worker ldrh w3, [x26, #ART_METHOD_METHOD_INDEX_OFFSET] 105*795d594fSAndroid Build Coastguard Worker and w3, w3, #ART_METHOD_IMT_MASK 106*795d594fSAndroid Build Coastguard Worker b 1b 107*795d594fSAndroid Build Coastguard Worker3: 108*795d594fSAndroid Build Coastguard Worker lsr w26, w26, #16 109*795d594fSAndroid Build Coastguard Worker add w2, w2, #MIRROR_CLASS_VTABLE_OFFSET_64 110*795d594fSAndroid Build Coastguard Worker ldr x0, [x2, w26, uxtw #3] 111*795d594fSAndroid Build Coastguard Worker .if $range 112*795d594fSAndroid Build Coastguard Worker b NterpCommonInvokeInstanceRange 113*795d594fSAndroid Build Coastguard Worker .else 114*795d594fSAndroid Build Coastguard Worker b NterpCommonInvokeInstance 115*795d594fSAndroid Build Coastguard Worker .endif 116*795d594fSAndroid Build Coastguard Worker 117*795d594fSAndroid Build Coastguard Worker%def invoke_interface_slow_path(range): 118*795d594fSAndroid Build Coastguard Worker mov x0, xSELF 119*795d594fSAndroid Build Coastguard Worker ldr x1, [sp] 120*795d594fSAndroid Build Coastguard Worker mov x2, xPC 121*795d594fSAndroid Build Coastguard Worker bl nterp_get_method 122*795d594fSAndroid Build Coastguard Worker mov x26, x0 123*795d594fSAndroid Build Coastguard Worker b .L${opcode}_resume 124*795d594fSAndroid Build Coastguard Worker 125*795d594fSAndroid Build Coastguard Worker%def op_invoke_interface(): 126*795d594fSAndroid Build Coastguard Worker% invoke_interface(range="0") 127*795d594fSAndroid Build Coastguard Worker 128*795d594fSAndroid Build Coastguard Worker%def op_invoke_interface_range(): 129*795d594fSAndroid Build Coastguard Worker% invoke_interface(range="1") 130*795d594fSAndroid Build Coastguard Worker 131*795d594fSAndroid Build Coastguard Worker%def invoke_static(helper=""): 132*795d594fSAndroid Build Coastguard Worker EXPORT_PC 133*795d594fSAndroid Build Coastguard Worker // Fast-path which gets the method from thread-local cache. 134*795d594fSAndroid Build Coastguard Worker% fetch_from_thread_cache("x0", miss_label="1f") 135*795d594fSAndroid Build Coastguard Worker b $helper 136*795d594fSAndroid Build Coastguard Worker1: 137*795d594fSAndroid Build Coastguard Worker mov x0, xSELF 138*795d594fSAndroid Build Coastguard Worker ldr x1, [sp] 139*795d594fSAndroid Build Coastguard Worker mov x2, xPC 140*795d594fSAndroid Build Coastguard Worker bl nterp_get_method 141*795d594fSAndroid Build Coastguard Worker b $helper 142*795d594fSAndroid Build Coastguard Worker 143*795d594fSAndroid Build Coastguard Worker%def op_invoke_static(): 144*795d594fSAndroid Build Coastguard Worker% invoke_static(helper="NterpCommonInvokeStatic") 145*795d594fSAndroid Build Coastguard Worker 146*795d594fSAndroid Build Coastguard Worker%def op_invoke_static_range(): 147*795d594fSAndroid Build Coastguard Worker% invoke_static(helper="NterpCommonInvokeStaticRange") 148*795d594fSAndroid Build Coastguard Worker 149*795d594fSAndroid Build Coastguard Worker%def invoke_virtual(helper="", range=""): 150*795d594fSAndroid Build Coastguard Worker EXPORT_PC 151*795d594fSAndroid Build Coastguard Worker // Fast-path which gets the method from thread-local cache. 152*795d594fSAndroid Build Coastguard Worker% fetch_from_thread_cache("x2", miss_label="2f") 153*795d594fSAndroid Build Coastguard Worker1: 154*795d594fSAndroid Build Coastguard Worker FETCH w1, 2 155*795d594fSAndroid Build Coastguard Worker .if !$range 156*795d594fSAndroid Build Coastguard Worker and w1, w1, #0xf 157*795d594fSAndroid Build Coastguard Worker .endif 158*795d594fSAndroid Build Coastguard Worker GET_VREG w1, w1 159*795d594fSAndroid Build Coastguard Worker // Note: if w1 is null, this will be handled by our SIGSEGV handler. 160*795d594fSAndroid Build Coastguard Worker ldr w0, [x1, #MIRROR_OBJECT_CLASS_OFFSET] 161*795d594fSAndroid Build Coastguard Worker UNPOISON_HEAP_REF w0 162*795d594fSAndroid Build Coastguard Worker add w0, w0, #MIRROR_CLASS_VTABLE_OFFSET_64 163*795d594fSAndroid Build Coastguard Worker ldr x0, [x0, w2, uxtw #3] 164*795d594fSAndroid Build Coastguard Worker b $helper 165*795d594fSAndroid Build Coastguard Worker2: 166*795d594fSAndroid Build Coastguard Worker mov x0, xSELF 167*795d594fSAndroid Build Coastguard Worker ldr x1, [sp] 168*795d594fSAndroid Build Coastguard Worker mov x2, xPC 169*795d594fSAndroid Build Coastguard Worker bl nterp_get_method 170*795d594fSAndroid Build Coastguard Worker mov x2, x0 171*795d594fSAndroid Build Coastguard Worker b 1b 172*795d594fSAndroid Build Coastguard Worker 173*795d594fSAndroid Build Coastguard Worker%def op_invoke_virtual(): 174*795d594fSAndroid Build Coastguard Worker% invoke_virtual(helper="NterpCommonInvokeInstance", range="0") 175*795d594fSAndroid Build Coastguard Worker 176*795d594fSAndroid Build Coastguard Worker%def op_invoke_virtual_range(): 177*795d594fSAndroid Build Coastguard Worker% invoke_virtual(helper="NterpCommonInvokeInstanceRange", range="1") 178