• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
18// void InterpreterToCompiledCodeBridgeDyn(
19//       const BytecodeInstruction* insn,       %rdi
20//       const Frame *iframe,                   %rsi
21//       const Method*,                         %rdx
22//       ManagedThread* thread)                 %rcx
23.global InterpreterToCompiledCodeBridgeDyn
24TYPE_FUNCTION(InterpreterToCompiledCodeBridgeDyn)
25InterpreterToCompiledCodeBridgeDyn:
26    CFI_STARTPROC
27    CFI_DEF_CFA(rsp, 8)
28
29    pushq %rsi // iframe*
30    CFI_ADJUST_CFA_OFFSET(8)
31
32    movq %rsp, %rax
33    CFI_DEF_CFA_REGISTER(rax)
34
35    // According to the current frame kind set the bridge type
36    movb MANAGED_THREAD_FRAME_KIND_OFFSET(%rcx), %r10b
37    testb %r10b, %r10b
38    movq $INTERPRETER_TO_COMPILED_CODE_BRIDGE, %r11
39    movq $BYPASS_BRIDGE, %r10
40    cmovne %r10, %r11
41    pushq %r11
42
43    pushq %rbp
44    CFI_REL_OFFSET(rbp, -(2 * 8))
45
46    movq %rax, %rbp // set frame pointer
47    CFI_DEF_CFA_REGISTER(rbp)
48
49    pushq %THREAD_REG
50    CFI_REL_OFFSET(r15, -(3 * 8))
51    pushq %r14
52    CFI_REL_OFFSET(r14, -(4 * 8))
53    pushq %r13
54    CFI_REL_OFFSET(r13, -(5 * 8))
55    pushq %r12
56    CFI_REL_OFFSET(r12, -(6 * 8))
57    pushq %rbx
58    CFI_REL_OFFSET(rbx, -(7 * 8))
59
60    pushq %rcx // thread*
61    subq $16, %rsp
62    // %rsp should be 16-byte aligned here
63
64    // setup regs as follow
65    // %rax - insn_ptr, %rbx - frame.vregs, %r12 - method, %r13, %r14 - temp, %r15 - acc
66    movq %rdi, %rax // insn*
67    leaq FRAME_VREGS_OFFSET(%rsi), %rbx // frame.vregs
68    movq FRAME_ACC_OFFSET(%rsi), %r15 // acc
69    movq %rdx, %r12 // method
70
71    // the dispatch routine expects opcode in ecx
72    movzbl (%rax), %ecx
73    cmpl $MIN_PREFIX_OPCODE_INDEX, %ecx
74    jl .Lnonprefixed
75    movzwl (%rax), %ecx
76    addq $2, %rax
77    jmp .Ldispatch
78.Lnonprefixed:
79    addq $1, %rax // read opcode and advance insn_ptr
80
81.Ldispatch:
82    // The file contains code which checks opcode and jumps
83    // to the corresponding handler.
84    // At the end each handler jumps to .Lload_reg_args label.
85    // The file is autogenerated from runtime/templates/bridge_dispatch.S.erb
86    // Handlers are distinguished by format and located in the corresponding files with name:
87    // handle_call_<format>.S
88    // If you get a compilation error that there is no such file it seems
89    // new call format was introduced and you have to implement the corresponding handler.
90#include "bridge_dispatch_dyn_amd64.S"
91
92    // invoke the method
93    // since the first argument is Method* it must be in %rdi
94.Linvoke:
95    movq METHOD_COMPILED_ENTRY_POINT_OFFSET(%rdi), %rax
96    movq -64(%rbp), %THREAD_REG
97    callq *%rax
98    // sp may be modified by call
99
100    // handle the result
101    // setup registers as follow
102    // %rax, %rdx - result, %r12 - frame.acc, %rcx - temp
103    movq (%rbp), %r12 // load iframe from the stack
104    addq $FRAME_ACC_OFFSET, %r12
105
106    // store value to frame.acc
107    movq %rax, (%r12)
108
109.Lreturn:
110    leaq -56(%rbp), %rsp
111    popq %rbx
112    CFI_RESTORE(rbx)
113    popq %r12
114    CFI_RESTORE(r12)
115    popq %r13
116    CFI_RESTORE(r13)
117    popq %r14
118    CFI_RESTORE(r14)
119    popq %THREAD_REG
120    CFI_RESTORE(r15)
121    popq %rbp
122    CFI_RESTORE(rbp)
123    CFI_DEF_CFA(rsp, (3 * 8))
124    addq $16, %rsp
125    CFI_ADJUST_CFA_OFFSET(-(2 * 8))
126    retq
127    CFI_ENDPROC
128
129// void InvokeCompiledCodeWithArgArrayDyn(
130//       const coretypes::TaggedValue* values,      %rdi
131//       uint32_t num_args,                     %rsi
132//       const Frame *iframe,                   %rdx
133//       const Method*,                         %rcx
134//       ManagedThread* thread)                 %r8
135.global InvokeCompiledCodeWithArgArrayDyn
136TYPE_FUNCTION(InvokeCompiledCodeWithArgArrayDyn)
137InvokeCompiledCodeWithArgArrayDyn:
138    CFI_STARTPROC
139    CFI_DEF_CFA(rsp, 8)
140
141    pushq %rdx // iframe*
142    CFI_ADJUST_CFA_OFFSET(8)
143
144    movq %rsp, %rax
145    CFI_DEF_CFA_REGISTER(rax)
146
147    // According to the current frame kind set the bridge type
148    movb MANAGED_THREAD_FRAME_KIND_OFFSET(%r8), %r10b
149    testb %r10b, %r10b
150    movq $INTERPRETER_TO_COMPILED_CODE_BRIDGE, %r11
151    movq $BYPASS_BRIDGE, %r10
152    cmovne %r10, %r11
153    pushq %r11
154
155    pushq %rbp
156    CFI_REL_OFFSET(rbp, -(2 * 8))
157
158    movq %rax, %rbp // set frame pointer
159    CFI_DEF_CFA_REGISTER(rbp)
160
161    pushq %THREAD_REG
162    CFI_REL_OFFSET(r15, -(3 * 8))
163
164    pushq %r12
165    CFI_REL_OFFSET(r12, -(4 * 8))
166    pushq %rbx
167    CFI_REL_OFFSET(rbx, -(5 * 8))
168    subq $8, %rsp
169    // %rsp should be 16-byte aligned here
170
171    //  const coretypes::TaggedValue* values,      %rdi
172    //  uint32_t num_args,                     %rsi
173    //  const Frame *iframe,                   %rdx
174    //  const Method*,                         %rcx
175    //  ManagedThread* thread                  %r8
176
177    movq %r8, %THREAD_REG // Properly set thread register
178
179    // rax <- pointer to current arg to copy
180    movq %rdi, %rax
181
182    // ABI arg reg 0 (rdi) <- ark::Method*
183    // ABI arg reg 1 (rsi) <- num_args (already on the relevant reg, no moves required)
184    movq %rcx, %rdi
185
186    // No arguments passed to the callee
187    test %esi, %esi
188    jz .Linvoke_
189
190    // Allocate stack args
191    leal (, %esi, FRAME_VREGISTER_SIZE), %r12d
192    subq %r12, %rsp
193    andq $-16, %rsp
194
195    // Copy boxed arguments to the stack
196    // ebx <- loop counter
197    // rdx <- temp register
198    leal -FRAME_VREGISTER_SIZE(, %esi, FRAME_VREGISTER_SIZE), %ebx
199.Lloop_:
200    movq (%rax, %rbx), %rdx
201    movq %rdx, (%rsp, %rbx)
202    subl $FRAME_VREGISTER_SIZE, %ebx
203    jae .Lloop_
204
205.Linvoke_:
206    // invoke the entrypoint
207    movq METHOD_COMPILED_ENTRY_POINT_OFFSET(%rdi), %rax
208    callq *%rax
209    // sp may be modified by call
210
211    leaq -40(%rbp), %rsp
212    popq %rbx
213    CFI_RESTORE(rbx)
214    popq %r12
215    CFI_RESTORE(r12)
216    popq %THREAD_REG
217    CFI_RESTORE(r15)
218    popq %rbp
219    CFI_RESTORE(rbp)
220    CFI_DEF_CFA(rsp, (3 * 8))
221    addq $16, %rsp
222    CFI_ADJUST_CFA_OFFSET(-(2 * 8))
223    retq
224    CFI_ENDPROC
225