• 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    // construct the frame
37    sub sp, sp, #16
38    CFI_ADJUST_CFA_OFFSET(16)
39    str lr, [sp, #12]
40    CFI_REL_OFFSET(lr, 12)
41    mov ip, #COMPILED_CODE_TO_INTERPRETER_BRIDGE
42    str ip, [sp, #8]
43    str fp, [sp, #4]
44    CFI_REL_OFFSET(fp, 4)
45    add fp, sp, #4
46    CFI_DEF_CFA(fp, 12)
47
48    // Save return address to the TLS field
49    str lr, [THREAD_REG, #MANAGED_THREAD_NATIVE_PC_OFFSET]
50
51    // save all the callee saved registers to the stack
52    // stack walker will read them during stack unwinding
53    push {r4 - r10}
54    CFI_REL_OFFSET(r10, -(2 * 4))
55    CFI_REL_OFFSET(r9,  -(3 * 4))
56    CFI_REL_OFFSET(r8,  -(4 * 4))
57    CFI_REL_OFFSET(r7,  -(5 * 4))
58    CFI_REL_OFFSET(r6,  -(6 * 4))
59    CFI_REL_OFFSET(r5,  -(7 * 4))
60    CFI_REL_OFFSET(r4,  -(8 * 4))
61    vpush {d8 - d15}
62    CFI_REL_OFFSET(d15, -(10 * 4))
63    CFI_REL_OFFSET(d14, -(12 * 4))
64    CFI_REL_OFFSET(d13, -(14 * 4))
65    CFI_REL_OFFSET(d12, -(16 * 4))
66    CFI_REL_OFFSET(d11, -(18 * 4))
67    CFI_REL_OFFSET(d10, -(20 * 4))
68    CFI_REL_OFFSET(d9,  -(22 * 4))
69    CFI_REL_OFFSET(d8,  -(24 * 4))
70
71    // align to 8
72    sub sp, sp, #4
73
74    // Before we call IncrementHotnessCounter we should set pointer to C2I frame in the TLS,
75    // because compilation may fall into safepoint, so we need to make caller's callee registers
76    // visible for the stack walker.
77    str fp, [THREAD_REG, #MANAGED_THREAD_FRAME_OFFSET]
78
79    push {r0 - r3}
80    vpush {d0 - d7}
81
82    blx IncrementHotnessCounter
83    cmp r0, #0
84    beq .Lnot_compiled
85    vpop {d0 - d7}
86    pop {r0 - r3}
87
88    // Compilation finished, so recover caller's frame in the TLS.
89    sub sp, fp, #4
90    ldr fp, [sp, #4]
91    CFI_REMEMBER_STATE
92    CFI_RESTORE(fp)
93    CFI_DEF_CFA(sp, 16)
94
95    str fp, [THREAD_REG, #MANAGED_THREAD_FRAME_OFFSET]
96    ldr lr, [sp, #12]
97    CFI_RESTORE(lr)
98    add sp, sp, #16 // c2i
99    CFI_ADJUST_CFA_OFFSET(-16)
100
101    ldr pc, [r0, #METHOD_COMPILED_ENTRY_POINT_OFFSET]
102
103    CFI_RESTORE_STATE
104    CFI_DEF_CFA(fp, 12)
105
106.Lnot_compiled:
107    vpop {d0 - d7}
108    pop {r0 - r3}
109
110    // save arguments to the stack
111    vpush {d0 - d7}
112    push {r0 - r3}
113
114    mov r4, r0 // save method to r4 to survive the call
115
116    // create an interpreter frame
117    mov r1, fp
118    blx CreateFrameForMethod
119
120    // setup regs as follow
121    // r0 - SHORTY_PTR_REG, r1 - SHORTY_REG, r2 - iframe.vregs_ + num_vregs_,
122    // r3 - gpr args begin, r4 - gpr args end, r5 - fpr args begin, r6 - fpr args end,
123    // r7 - stack args, r8 - iframe, r9, r10, r12 - temps, lr - method
124    mov r8, r0
125    ldr r5, [r8, #FRAME_NUM_VREGS_OFFSET]
126    mov r12, r5, lsl #3
127    ldr r0, [r4, #METHOD_NUM_ARGS_OFFSET]
128    sub r5, r5, r0
129    mov lr, r4
130    ldr SHORTY_PTR_REG, [lr, #METHOD_SHORTY_OFFSET]
131    INIT_SHORTY_REG
132    add r2, r8, #FRAME_VREGS_OFFSET
133    add r2, r2, r5, lsl #3
134    add r3, sp, #4 // skip Method*
135    add r4, sp, #16
136    mov r5, r4
137    add r6, r5, #64
138    add r7, fp, #12
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 r9, [lr, #METHOD_ACCESS_FLAGS_OFFSET]
146    tst r9, #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 r9
158    cmp r9, #0
159    beq .Lloopend_copy_args
160
161    cmp r9, #SHORTY_REFERENCE
162    moveq r10, #1
163    movne r10, #0
164    str r10, [r2, r12]
165    cmpne r9, #SHORTY_LAST_INT32
166    bhi 1f
167    // it is a 32bit int or reference
168    sub r9, r4, r3
169    cmp r9, #0
170    ldrne r9, [r3], #4
171    ldreq r9, [r7], #4
172    str r9, [r2]
173    add r2, r2, #FRAME_VREGISTER_SIZE
174    b .Lloop_copy_args
175
1761:  sub r9, r9, #SHORTY_FIRST_FLOAT
177    cmp r9, #(SHORTY_NUM_FLOAT_TYPES - 1)
178    bls 2f
179    // it is a 64bit int
180    //align r3
181    add r3, r3, #7
182    bic r3, r3, #7
183    sub r9, r4, r3
184    cmp r9, #0
185    beq 3f
186    ldm r3!, {r9, r10}
187    stm r2, {r9, r10}
188    add r2, r2, #FRAME_VREGISTER_SIZE
189    b .Lloop_copy_args
190
1912:  // it is a float
192    sub r9, r6, r5
193    cmp r9, #0
194    beq 3f
195    ldm r5!, {r9, r10}
196    stm r2, {r9, r10}
197    add r2, r2, #FRAME_VREGISTER_SIZE
198    b .Lloop_copy_args
199
2003:  // read arg from the stack
201    add r7, r7, #7
202    bic r7, r7, #7
203    ldm r7!, {r9, r10}
204    stm r2, {r9, r10}
205    add r2, r2, #FRAME_VREGISTER_SIZE
206    b .Lloop_copy_args
207.Lloopend_copy_args:
208    // load method.shorty to r4 to survive the call
209    ldr r4, [lr, #METHOD_SHORTY_OFFSET]
210
211    // call InterpreterEntryPoint
212    mov r0, lr
213    mov r1, r8
214    blx InterpreterEntryPoint
215
216    // handle the result
217    // setup regs as follow
218    // r0 - iframe, r1 - *method.shorty, r2 - &iframe.acc_
219    // r4, r5 - result
220    ldrb r1, [r4]
221    mov r0, r8
222    add r2, r0, #FRAME_ACC_OFFSET
223    and r1, r1, #0xF
224
225    cmp r1, #SHORTY_VOID
226    bne 1f
227    // void method
228    blx FreeFrame
229    b 4f
230
2311:  cmp r1, #SHORTY_REFERENCE
232    cmpne r1, #SHORTY_LAST_INT32
233    bhi 2f
234    // it is a 32bit int of reference
235    ldr r4, [r2]
236    blx FreeFrame
237    mov r0, r4
238    b 4f
239
2402:  ldm r2, {r4, r5}
241    sub r1, r1, #SHORTY_FIRST_FLOAT
242    cmp r1, #(SHORTY_NUM_FLOAT_TYPES - 1)
243    bls 3f
244    // it is a 64bit int
245    blx FreeFrame
246    mov r0, r4
247    mov r1, r5
248    b 4f
249
2503:  // it is a float value
251    vmov.f64 d0, r4, r5
252    blx FreeFrame
253
2544:  sub sp, fp, #(4 + 7 * 4 + 8 * 8)
255    vpop {d8 - d15}
256    CFI_RESTORE(d15)
257    CFI_RESTORE(d14)
258    CFI_RESTORE(d13)
259    CFI_RESTORE(d12)
260    CFI_RESTORE(d11)
261    CFI_RESTORE(d10)
262    CFI_RESTORE(d9)
263    CFI_RESTORE(d8)
264
265    pop {r4 - r10}
266    CFI_RESTORE(r10)
267    CFI_RESTORE(r9)
268    CFI_RESTORE(r8)
269    CFI_RESTORE(r7)
270    CFI_RESTORE(r6)
271    CFI_RESTORE(r5)
272    CFI_RESTORE(r4)
273
274    ldr fp, [sp, #4]
275    CFI_DEF_CFA(sp, 16)
276    CFI_RESTORE(fp)
277
278    ldr lr, [sp, #12]
279    CFI_RESTORE(lr)
280    add sp, sp, #16 // c2i
281    CFI_ADJUST_CFA_OFFSET(-16)
282    bx lr
283    CFI_ENDPROC
284