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/x86/shorty.S" 18 19#define SHORTY_PTR_REG DEFAULT_SHORTY_PTR_REG 20#define SHORTY_REG DEFAULT_SHORTY_REG 21 22// Frame* CreateFrameForMethod(Method* method, Frame* prev); 23.extern CreateFrameForMethod 24// void InterpreterEntryPoint(Method *method, Frame* frame); 25.extern InterpreterEntryPoint 26 27.extern DecrementHotnessCounter 28 29.global CompiledCodeToInterpreterBridge 30.type CompiledCodeToInterpreterBridge, %function 31CompiledCodeToInterpreterBridge: 32 // %esp % 16 == 12 here (-4 == 12 (mod 16)) 33 movl %esp, %eax 34 35 // construct the frame 36 pushl %ebp 37 pushl $COMPILED_CODE_TO_INTERPRETER_BRIDGE 38 39 movl %eax, %ebp // set frame pointer 40 41 pushl 4(%ebp) 42 calll DecrementHotnessCounter 43 addl $4, %esp 44 45 cmpb $0, %al 46 je .Lnot_compiled 47 48 addl $4, %esp 49 popl %ebp 50 51 movl 4(%esp), %eax 52 movl METHOD_COMPILED_ENTRY_POINT_OFFSET(%eax), %eax 53 jmp *%eax 54 55.Lnot_compiled: 56 57 // save all the callee saved registers to the stack 58 // stack walker will read them during stack unwinding 59 pushl %ebx 60 pushl %esi 61 pushl %edi 62 // %esp % 16 == 8 here 63 64 movl 4(%ebp), %ebx // method* 65 leal -8(%ebp), %ecx // prev* 66 67 pushl %ecx 68 pushl %ebx 69 // %esp should be 16-byte aligned here 70 calll CreateFrameForMethod 71 addl $8, %esp // cleanup 72 73 pushl %eax // iframe* 74 75 // setup regs as follow 76 // %eax - SHORTY_PTR_REG, %edx - SHORTY_REG, %ecx - shorty value, %edi - iframe.vregs_ + num_vregs_, 77 // %esi - args, (%esp) - iframe* 78 addl $FRAME_VREGS_OFFSET, %eax 79 movl FRAME_NUM_VREGS_OFFSET(%eax), %edi 80 subl METHOD_NUM_ARGS_OFFSET(%ebx), %edi 81 shll $3, %edi 82 addl %eax, %edi // iframe.vregs_ + num_vregs_ 83 84 leal 8(%ebp), %esi // args 85 86 movl METHOD_SHORTY_OFFSET(%ebx), %SHORTY_PTR_REG 87 INIT_SHORTY_REG 88 89 90 // fill in the iframe 91 92 // parameter 'this' of instance methods is not encoded in the shorty 93 // in case of instance method hack SHORTY_REG by replacing the return type by REF 94 // in the another case just skip the return type 95 96 // check whether the method is an instance 97 movl METHOD_ACCESS_FLAGS_OFFSET(%ebx), %ecx 98 testl $ACCESS_STATIC, %ecx 99 jne 1f 100 101 // it is an instance method 102 // replace the return type by REF 103 andl $0xFFFFFFF0, %SHORTY_REG // clear the the least significant 4 bits 104 orl $SHORTY_REFERENCE, %SHORTY_REG 105 jmp .Lloop_copy_args 106 1071: 108 SKIP_SHORTY 109 110.Lloop_copy_args: 111 NEXT_SHORTY %ecx 112 cmpl $0, %ecx 113 je .Lloopend_copy_args 114 115 subl $SHORTY_FIRST_64, %ecx 116 cmpl $(SHORTY_NUM_64BIT_TYPES - 1), %ecx 117 jbe 1f 118 119 // it is a 32bit value or reference 120 // store the tag 121 cmpl $(SHORTY_REFERENCE - SHORTY_FIRST_64), %ecx 122 movl $0, %ecx 123 sete %cl 124 movl FRAME_NUM_VREGS_OFFSET(%eax), %edx 125 movl %ecx, (%edi, %edx, 8) 126 127 movl (%esi), %ecx 128 movl %ecx, (%edi) 129 130 addl $4, %esi 131 jmp 2f 1321: 133 // it is a 64bit value 134 // store the tag 135 movl FRAME_NUM_VREGS_OFFSET(%eax), %edx 136 movl $FRAME_VREGISTER_PRIMITIVE_TAG, (%edi, %edx, 8) 137 138 movl (%esi), %ecx 139 movl %ecx, (%edi) 140 movl 4(%esi), %ecx 141 movl %ecx, 4(%edi) 142 143 addl $8, %esi 1442: 145 addl $FRAME_VREGISTER_SIZE, %edi 146 jmp .Lloop_copy_args 147.Lloopend_copy_args: 148 149 movl (%esp), %esi // iframe* 150 151 // call InterpreterEntryPoint 152 // iframe* 153 pushl %ebx // method* 154 // %esp should be 16-byte aligned here 155 calll InterpreterEntryPoint 156 addl $8, %esp // cleanup 157 158 // handle the result 159 // setup regs as follow 160 // %esi - iframe, %ebx - *method.shorty, %eax - &iframe.acc_ 161 leal FRAME_ACC_OFFSET(%esi), %eax 162 movl METHOD_SHORTY_OFFSET(%ebx), %ebx 163 movzbl (%ebx), %ebx 164 andl $0xF, %ebx 165 166 cmpl $SHORTY_VOID, %ebx 167 jne 1f 168 169 subl $4, %esp // alignment 170 pushl %esi // iframe* 171 calll FreeFrame 172 addl $8, %esp // cleanup 173 174 jmp 4f 1751: 176 movl %ebx, %ecx 177 subl $SHORTY_FIRST_FLOAT, %ecx 178 cmpl $(SHORTY_NUM_FLOAT_TYPES - 1), %ecx 179 jbe 3f 180 181 subl $SHORTY_FIRST_64, %ebx 182 cmpl $(SHORTY_NUM_64BIT_TYPES - 1), %ebx 183 jbe 2f 184 185 // result is 32 bit integer or reference 186 movl (%eax), %ebx 187 188 subl $4, %esp // alignment 189 pushl %esi // iframe* 190 calll FreeFrame 191 addl $8, %esp // cleanup 192 193 movl %ebx, %eax 194 jmp 4f 1952: 196 // result is 64bit integer 197 movl (%eax), %ebx 198 movl 4(%eax), %edi 199 200 subl $4, %esp // alignment 201 pushl %esi // iframe* 202 calll FreeFrame 203 addl $8, %esp // cleanup 204 205 movl %ebx, %eax 206 movl %edi, %edx 207 jmp 4f 2083: 209 // result is float 210 movl (%eax), %ebx 211 movl 4(%eax), %edi 212 213 subl $4, %esp // alignment 214 pushl %esi // iframe* 215 calll FreeFrame 216 addl $8, %esp // cleanup 217 218 subl $8, %esp 219 movl %ebx, (%esp) 220 movl %edi, 4(%esp) 221 fldl (%esp) 222 addl $8, %esp 2234: 224 leal -20(%ebp), %esp 225 226 popl %edi 227 popl %esi 228 popl %ebx 229 addl $4, %esp 230 popl %ebp 231 232 retl 233