1/** 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "arch/asm_support.h" 17#include "arch/arm/shorty.S" 18#include "shorty_values.h" 19 20#define SHORTY_PTR_REG DEFAULT_SHORTY_PTR_REG 21#define SHORTY_REG DEFAULT_SHORTY_REG 22 23// Frame* CreateFrameForMethod(Method* method, Frame* prev); 24.extern CreateFrameForMethod 25// void InterpreterEntryPoint(Method *method, Frame* frame); 26.extern InterpreterEntryPoint 27// bool DecrementHotnessCounter(Method *method); 28.extern DecrementHotnessCounter 29 30.global CompiledCodeToInterpreterBridge 31.type CompiledCodeToInterpreterBridge, %function 32CompiledCodeToInterpreterBridge: 33 CFI_STARTPROC 34 CFI_DEF_CFA(sp, 0) 35 36 // store r0-r3 before the frame to make arg array continuos with stack args 37 push {r0-r3} 38 CFI_ADJUST_CFA_OFFSET(16) 39 40 // construct the frame 41 mov r1, #COMPILED_CODE_TO_INTERPRETER_BRIDGE 42 push {r1, lr} 43 CFI_ADJUST_CFA_OFFSET(8) 44 CFI_REL_OFFSET(lr, 4) 45 push {r1, fp} 46 CFI_ADJUST_CFA_OFFSET(8) 47 CFI_REL_OFFSET(fp, 4) 48 add fp, sp, #4 49 CFI_ADJUST_CFA_OFFSET(-4) 50 CFI_DEF_CFA_REGISTER(fp) 51 52 // Save return address to the TLS field 53 str lr, [THREAD_REG, #MANAGED_THREAD_NATIVE_PC_OFFSET] 54 55 // save all the callee saved registers to the stack 56 // stack walker will read them during stack unwinding 57 push {r4 - r10} 58 CFI_REL_OFFSET(r10, -(2 * 4)) 59 CFI_REL_OFFSET(r9, -(3 * 4)) 60 CFI_REL_OFFSET(r8, -(4 * 4)) 61 CFI_REL_OFFSET(r7, -(5 * 4)) 62 CFI_REL_OFFSET(r6, -(6 * 4)) 63 CFI_REL_OFFSET(r5, -(7 * 4)) 64 CFI_REL_OFFSET(r4, -(8 * 4)) 65 66#ifndef PANDA_TARGET_ARM32_ABI_SOFT 67 vpush {d8 - d15} 68 CFI_REL_OFFSET(d15, -(10 * 4)) 69 CFI_REL_OFFSET(d14, -(12 * 4)) 70 CFI_REL_OFFSET(d13, -(14 * 4)) 71 CFI_REL_OFFSET(d12, -(16 * 4)) 72 CFI_REL_OFFSET(d11, -(18 * 4)) 73 CFI_REL_OFFSET(d10, -(20 * 4)) 74 CFI_REL_OFFSET(d9, -(22 * 4)) 75 CFI_REL_OFFSET(d8, -(24 * 4)) 76#endif 77 78 // align to 8 79 sub sp, sp, #4 80 81 // Before we call DecrementHotnessCounter we should set pointer to C2I frame in the TLS, 82 // because compilation may fall into safepoint, so we need to make caller's callee registers 83 // visible for the stack walker. 84 str fp, [THREAD_REG, #MANAGED_THREAD_FRAME_OFFSET] 85 86 push {r0 - r3} 87 mov r1, THREAD_REG 88 blx DecrementHotnessCounter 89 90 cmp r0, #0 91 beq .Lnot_compiled 92 93 pop {r0 - r3} 94 95 // Compilation finished, so recover caller's frame in the TLS. 96 sub sp, fp, #4 97 CFI_REMEMBER_STATE 98 CFI_DEF_CFA(sp, 32) 99 100 pop {r1, fp} 101 CFI_ADJUST_CFA_OFFSET(-8) 102 CFI_RESTORE(fp) 103 104 str fp, [THREAD_REG, #MANAGED_THREAD_FRAME_OFFSET] 105 pop {r1, lr} 106 CFI_ADJUST_CFA_OFFSET(-8) 107 CFI_RESTORE(lr) 108 pop {r0-r3} 109 CFI_ADJUST_CFA_OFFSET(-16) 110 111 ldr pc, [r0, #METHOD_COMPILED_ENTRY_POINT_OFFSET] 112 CFI_RESTORE_STATE 113 CFI_DEF_CFA(fp, 28) 114 115.Lnot_compiled: 116 pop {r0 - r3} 117 118 // setup regs as follow 119 // r7 - method 120 mov r7, r0 // save method to survive the call 121 122 // create an interpreter frame 123 mov r1, fp 124 blx CreateFrameForMethod 125 126 // setup regs as follow 127 // r0 - SHORTY_PTR_REG, r1 - SHORTY_REG, r2 - iframe.vregs_ + num_vregs_, 128 // r3 - args, r4, r5, r9 - temp, r6 - iframe, r7 - method, r8 - method.shorty 129 mov r6, r0 130 ldr r5, [r6, #FRAME_NUM_VREGS_OFFSET] 131 mov r9, r5, lsl #3 132 ldr r0, [r7, #METHOD_NUM_ARGS_OFFSET] 133 sub r5, r5, r0 134 ldr r8, [r7, #METHOD_SHORTY_OFFSET] 135 mov SHORTY_PTR_REG, r8 136 INIT_SHORTY_REG 137 add r2, r6, #FRAME_VREGS_OFFSET 138 add r2, r2, r5, lsl #3 139 add r3, fp, #16 140 141 // parameter 'this' of instance methods is not encoded in the shorty 142 // in case of instance method hack SHORTY_REG by replacing the return type by REF 143 // in the another case just skip the return type 144 145 // check whether the method is an instance 146 ldr r4, [r7, #METHOD_ACCESS_FLAGS_OFFSET] 147 tst r4, #ACCESS_STATIC 148 bne 1f 149 // it is an instance method 150 // replace the return type by REF 151 bic r1, r1, #0xF // clear the the least significant 4 bits 152 orr r1, r1, #SHORTY_REFERENCE 153 b .Lloop_copy_args 1541: SKIP_SHORTY 155 156 // fill in the iframe 157.Lloop_copy_args: 158 NEXT_SHORTY r4 159 cmp r4, #0 160 beq .Lloopend_copy_args 161 162 sub r4, r4, #SHORTY_FIRST_64 163 cmp r4, #(SHORTY_NUM_64BIT_TYPES - 1) 164 bls 1f 165 // it is a 32bit value of reference 166 // store the tag 167 cmp r4, #(SHORTY_REFERENCE - SHORTY_FIRST_64) 168 movne r5, #FRAME_VREGISTER_PRIMITIVE_TAG 169 moveq r5, #FRAME_VREGISTER_OBJECT_TAG 170 str r5, [r2, r9] 171 // store the value 172 ldr r4, [r3], #4 173 str r4, [r2] 174 b 2f 1751: // it is a 64bit value 176 // make r3 8 bytes aligned 177 add r3, r3, #7 178 bic r3, r3, #7 179 ldm r3!, {r4, r5} 180 stm r2, {r4, r5} 181 mov r4, #FRAME_VREGISTER_PRIMITIVE_TAG 182 str r4, [r2, r9] 1832: 184 add r2, r2, #FRAME_VREGISTER_SIZE 185 b .Lloop_copy_args 186.Lloopend_copy_args: 187 188 // call InterpreterEntryPoint 189 mov r0, r7 190 mov r1, r6 191 blx InterpreterEntryPoint 192 193 // handle the result 194 // setup regs as follow 195 // r0 - iframe, r1 - *method.shorty, r2 - &iframe.acc_ 196 // r4, r5 - result 197 mov r0, r6 198 ldrb r1, [r8] 199 add r2, r6, #FRAME_ACC_OFFSET 200 and r1, r1, #0xF 201 202 cmp r0, #SHORTY_VOID 203 bne 1f 204 // void method 205 blx FreeFrame 206 b 3f 2071: 208 sub r1, r1, #SHORTY_FIRST_64 209 cmp r1, #(SHORTY_NUM_64BIT_TYPES - 1) 210 bls 2f 211 // result is 32 bit integer or reference 212 ldr r4, [r2] 213 blx FreeFrame 214 mov r0, r4 215 b 3f 2162: // result is 64bit integer 217 ldm r2, {r4, r5} 218 blx FreeFrame 219 mov r0, r4 220 mov r1, r5 221 2223: 223#ifndef PANDA_TARGET_ARM32_ABI_SOFT 224 sub sp, fp, #(4 + 7 * 4 + 8 * 8) 225 vpop {d8 - d15} 226 CFI_RESTORE(d15) 227 CFI_RESTORE(d14) 228 CFI_RESTORE(d13) 229 CFI_RESTORE(d12) 230 CFI_RESTORE(d11) 231 CFI_RESTORE(d10) 232 CFI_RESTORE(d9) 233 CFI_RESTORE(d8) 234#else 235 sub sp, fp, #(4 + 7 * 4) 236#endif 237 238 pop {r4 - r10} 239 CFI_RESTORE(r10) 240 CFI_RESTORE(r9) 241 CFI_RESTORE(r8) 242 CFI_RESTORE(r7) 243 CFI_RESTORE(r6) 244 CFI_RESTORE(r5) 245 CFI_RESTORE(r4) 246 247 ldr fp, [sp, #4] 248 CFI_DEF_CFA(sp, 32) 249 CFI_RESTORE(fp) 250 251 ldr lr, [sp, #12] 252 CFI_RESTORE(lr) 253 add sp, sp, #32 // c2i + r0 - r3 254 CFI_ADJUST_CFA_OFFSET(-32) 255 bx lr 256 CFI_ENDPROC 257