1#
2# Copyright (c) 2012, Red Hat. All rights reserved.
3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4#
5# This code is free software; you can redistribute it and/or modify it
6# under the terms of the GNU General Public License version 2 only, as
7# published by the Free Software Foundation.
8#
9# This code is distributed in the hope that it will be useful, but WITHOUT
10# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12# version 2 for more details (a copy is included in the LICENSE file that
13# accompanied this code).
14#
15# You should have received a copy of the GNU General Public License version
16# 2 along with this work; if not, write to the Free Software Foundation,
17# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18#
19# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20# or visit www.oracle.com if you need additional information or have any
21# questions.
22
23# Routines used to enable x86 VM C++ code to invoke JIT-compiled ARM code
24# -- either Java methods or generated stub -- and to allow JIT-compiled
25# ARM code to invoke x86 VM C++ code
26#
27# the code for aarch64_stub_prolog below can be copied into the start
28# of the ARM code buffer and patched with a link to the
29# C++ routine which starts execution on the simulator. the ARM
30# code can be generated immediately following the copied code.
31
32#ifdef BUILTIN_SIM
33
34	.data
35        .globl setup_arm_sim,
36	.type  setup_arm_sim,@function
37        .globl get_alt_stack,
38	.type  get_alt_stack,@function
39        .globl aarch64_stub_prolog
40        .p2align  4
41aarch64_stub_prolog:
42	// entry point
434:	lea 1f(%rip), %r11
44	mov (%r11), %r10
45	mov (%r10), %r10
46	jmp *%r10
47	.p2align 4
481:
49	.set entry_offset, . - 1b
50	.quad aarch64_prolog_ptr
51	// 64 bit int used to idenitfy called fn arg/return types
52	.set calltype_offset, . - 1b
53	.quad 0
54	// arm JIT code follows the stub
55	.set arm_code_offset, . - 1b
56	.size aarch64_stub_prolog, .-aarch64_stub_prolog
57aarch64_stub_prolog_end:
58
59	.text
60aarch64_prolog_ptr:
61	.quad aarch64_prolog
62
63        .globl aarch64_prolog
64aarch64_prolog:
65	.cfi_startproc
66	pushq	%rbp
67	.cfi_def_cfa_offset 16
68	.cfi_offset 6, -16
69	movq	%rsp, %rbp
70	.cfi_def_cfa_register 6
71	// save all registers used to pass args
72	sub $8, %rsp
73	movd %xmm7, (%rsp)
74	sub $8, %rsp
75	movd %xmm6, (%rsp)
76	sub $8, %rsp
77	movd %xmm5, (%rsp)
78	sub $8, %rsp
79	movd %xmm4, (%rsp)
80	sub $8, %rsp
81	movd %xmm3, (%rsp)
82	sub $8, %rsp
83	movd %xmm2, (%rsp)
84	sub $8, %rsp
85	movd %xmm1, (%rsp)
86	sub $8, %rsp
87	movd %xmm0, (%rsp)
88	push %r9
89	push %r8
90	push %rcx
91	push %rdx
92	push %rsi
93	push %rdi
94	// save rax -- this stack slot will be rewritten with a
95	// return value if needed
96	push %rax
97	// temporarily save r11 while we find the other stack
98	push %r11
99	// retrieve alt stack
100	call get_alt_stack@PLT
101	pop %r11
102	// push start of arm code
103	lea (arm_code_offset)(%r11), %rsi
104	push %rsi
105	// load call type code in arg reg 1
106	mov (calltype_offset)(%r11), %rsi
107	// load current stack pointer in arg reg 0
108	mov %rsp, %rdi
109	// switch to alt stack
110	mov %rax, %rsp
111	// save previous stack pointer on new stack
112	push %rdi
113	// 16-align the new stack pointer
114	push %rdi
115	// call sim setup routine
116	call setup_arm_sim@PLT
117	// switch back to old stack
118	pop %rsp
119	// pop start of arm code
120	pop %rdi
121	// pop rax -- either restores old value or installs return value
122	pop %rax
123	// pop arg registers
124	pop %rdi
125	pop %rsi
126	pop %rdx
127	pop %rcx
128	pop %r8
129	pop %r9
130	movd (%rsp), %xmm0
131	add $8, %rsp
132	movd (%rsp), %xmm1
133	add $8, %rsp
134	movd (%rsp), %xmm2
135	add $8, %rsp
136	movd (%rsp), %xmm3
137	add $8, %rsp
138	movd (%rsp), %xmm4
139	add $8, %rsp
140	movd (%rsp), %xmm5
141	add $8, %rsp
142	movd (%rsp), %xmm6
143	add $8, %rsp
144	movd (%rsp), %xmm7
145	add $8, %rsp
146	leave
147	.cfi_def_cfa 7, 8
148	ret
149	.cfi_endproc
150
151
152        .p2align  4
153get_pc:
154	// get return pc in rdi and then push it back
155	pop %rdi
156	push %rdi
157	ret
158
159	.p2align 4
160	.long
161	.globl aarch64_stub_prolog_size
162	.type  aarch64_stub_prolog_size,@function
163aarch64_stub_prolog_size:
164	leaq  aarch64_stub_prolog_end - aarch64_stub_prolog, %rax
165	ret
166
167#endif
168