1/** 2 * Copyright (c) 2021-2022 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 IncrementHotnessCounter(Method *method); 28.extern IncrementHotnessCounter 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 IncrementHotnessCounter 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 blx IncrementHotnessCounter 88 89 cmp r0, #0 90 beq .Lnot_compiled 91 92 pop {r0 - r3} 93 94 // Compilation finished, so recover caller's frame in the TLS. 95 sub sp, fp, #4 96 CFI_REMEMBER_STATE 97 CFI_DEF_CFA(sp, 32) 98 99 pop {r1, fp} 100 CFI_ADJUST_CFA_OFFSET(-8) 101 CFI_RESTORE(fp) 102 103 str fp, [THREAD_REG, #MANAGED_THREAD_FRAME_OFFSET] 104 pop {r1, lr} 105 CFI_ADJUST_CFA_OFFSET(-8) 106 CFI_RESTORE(lr) 107 pop {r0-r3} 108 CFI_ADJUST_CFA_OFFSET(-16) 109 110 ldr pc, [r0, #METHOD_COMPILED_ENTRY_POINT_OFFSET] 111 CFI_RESTORE_STATE 112 CFI_DEF_CFA(fp, 28) 113 114.Lnot_compiled: 115 pop {r0 - r3} 116 117 // setup regs as follow 118 // r7 - method 119 mov r7, r0 // save method to survive the call 120 121 // create an interpreter frame 122 mov r1, fp 123 blx CreateFrameForMethod 124 125 // setup regs as follow 126 // r0 - SHORTY_PTR_REG, r1 - SHORTY_REG, r2 - iframe.vregs_ + num_vregs_, 127 // r3 - args, r4, r5, r9 - temp, r6 - iframe, r7 - method, r8 - method.shorty 128 mov r6, r0 129 ldr r5, [r6, #FRAME_NUM_VREGS_OFFSET] 130 mov r9, r5, lsl #3 131 ldr r0, [r7, #METHOD_NUM_ARGS_OFFSET] 132 sub r5, r5, r0 133 ldr r8, [r7, #METHOD_SHORTY_OFFSET] 134 mov SHORTY_PTR_REG, r8 135 INIT_SHORTY_REG 136 add r2, r6, #FRAME_VREGS_OFFSET 137 add r2, r2, r5, lsl #3 138 add r3, fp, #16 139 140 // parameter 'this' of instance methods is not encoded in the shorty 141 // in case of instance method hack SHORTY_REG by replacing the return type by REF 142 // in the another case just skip the return type 143 144 // check whether the method is an instance 145 ldr r4, [r7, #METHOD_ACCESS_FLAGS_OFFSET] 146 tst r4, #ACCESS_STATIC 147 bne 1f 148 // it is an instance method 149 // replace the return type by REF 150 bic r1, r1, #0xF // clear the the least significant 4 bits 151 orr r1, r1, #SHORTY_REFERENCE 152 b .Lloop_copy_args 1531: SKIP_SHORTY 154 155 // fill in the iframe 156.Lloop_copy_args: 157 NEXT_SHORTY r4 158 cmp r4, #0 159 beq .Lloopend_copy_args 160 161 sub r4, r4, #SHORTY_FIRST_64 162 cmp r4, #(SHORTY_NUM_64BIT_TYPES - 1) 163 bls 1f 164 // it is a 32bit value of reference 165 // store the tag 166 cmp r4, #(SHORTY_REFERENCE - SHORTY_FIRST_64) 167 movne r5, #FRAME_VREGISTER_PRIMITIVE_TAG 168 moveq r5, #FRAME_VREGISTER_OBJECT_TAG 169 str r5, [r2, r9] 170 // store the value 171 ldr r4, [r3], #4 172 str r4, [r2] 173 b 2f 1741: // it is a 64bit value 175 // make r3 8 bytes aligned 176 add r3, r3, #7 177 bic r3, r3, #7 178 ldm r3!, {r4, r5} 179 stm r2, {r4, r5} 180 mov r4, #FRAME_VREGISTER_PRIMITIVE_TAG 181 str r4, [r2, r9] 1822: 183 add r2, r2, #FRAME_VREGISTER_SIZE 184 b .Lloop_copy_args 185.Lloopend_copy_args: 186 187 // call InterpreterEntryPoint 188 mov r0, r7 189 mov r1, r6 190 blx InterpreterEntryPoint 191 192 // handle the result 193 // setup regs as follow 194 // r0 - iframe, r1 - *method.shorty, r2 - &iframe.acc_ 195 // r4, r5 - result 196 mov r0, r6 197 ldrb r1, [r8] 198 add r2, r6, #FRAME_ACC_OFFSET 199 and r1, r1, #0xF 200 201 cmp r0, #SHORTY_VOID 202 bne 1f 203 // void method 204 blx FreeFrame 205 b 3f 2061: 207 sub r1, r1, #SHORTY_FIRST_64 208 cmp r1, #(SHORTY_NUM_64BIT_TYPES - 1) 209 bls 2f 210 // result is 32 bit integer or reference 211 ldr r4, [r2] 212 blx FreeFrame 213 mov r0, r4 214 b 3f 2152: // result is 64bit integer 216 ldm r2, {r4, r5} 217 blx FreeFrame 218 mov r0, r4 219 mov r1, r5 220 2213: 222#ifndef PANDA_TARGET_ARM32_ABI_SOFT 223 sub sp, fp, #(4 + 7 * 4 + 8 * 8) 224 vpop {d8 - d15} 225 CFI_RESTORE(d15) 226 CFI_RESTORE(d14) 227 CFI_RESTORE(d13) 228 CFI_RESTORE(d12) 229 CFI_RESTORE(d11) 230 CFI_RESTORE(d10) 231 CFI_RESTORE(d9) 232 CFI_RESTORE(d8) 233#else 234 sub sp, fp, #(4 + 7 * 4) 235#endif 236 237 pop {r4 - r10} 238 CFI_RESTORE(r10) 239 CFI_RESTORE(r9) 240 CFI_RESTORE(r8) 241 CFI_RESTORE(r7) 242 CFI_RESTORE(r6) 243 CFI_RESTORE(r5) 244 CFI_RESTORE(r4) 245 246 ldr fp, [sp, #4] 247 CFI_DEF_CFA(sp, 32) 248 CFI_RESTORE(fp) 249 250 ldr lr, [sp, #12] 251 CFI_RESTORE(lr) 252 add sp, sp, #32 // c2i + r0 - r3 253 CFI_ADJUST_CFA_OFFSET(-32) 254 bx lr 255 CFI_ENDPROC 256