• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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