drc: arm64 wip
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / linkage_arm64.S
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   linkage_arm.s for PCSX                                                *
3  *   Copyright (C) 2009-2011 Ari64                                         *
4  *   Copyright (C) 2021 notaz                                              *
5  *                                                                         *
6  *   This program is free software; you can redistribute it and/or modify  *
7  *   it under the terms of the GNU General Public License as published by  *
8  *   the Free Software Foundation; either version 2 of the License, or     *
9  *   (at your option) any later version.                                   *
10  *                                                                         *
11  *   This program is distributed in the hope that it will be useful,       *
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14  *   GNU General Public License for more details.                          *
15  *                                                                         *
16  *   You should have received a copy of the GNU General Public License     *
17  *   along with this program; if not, write to the                         *
18  *   Free Software Foundation, Inc.,                                       *
19  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
20  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22 #include "arm_features.h"
23 #include "new_dynarec_config.h"
24 #include "assem_arm64.h"
25 #include "linkage_offsets.h"
26
27 .bss
28         .align  4
29         .global dynarec_local
30         .type   dynarec_local, %object
31         .size   dynarec_local, LO_dynarec_local_size
32 dynarec_local:
33         .space  LO_dynarec_local_size
34
35 #define DRC_VAR_(name, vname, size_) \
36         vname = dynarec_local + LO_##name; \
37         .global vname; \
38         .type   vname, %object; \
39         .size   vname, size_
40
41 #define DRC_VAR(name, size_) \
42         DRC_VAR_(name, ESYM(name), size_)
43
44 DRC_VAR(next_interupt, 4)
45 DRC_VAR(cycle_count, 4)
46 DRC_VAR(last_count, 4)
47 DRC_VAR(pending_exception, 4)
48 DRC_VAR(stop, 4)
49 DRC_VAR(branch_target, 4)
50 DRC_VAR(address, 4)
51 #DRC_VAR(align0, 16) /* unused/alignment */
52 DRC_VAR(psxRegs, LO_psxRegs_end - LO_psxRegs)
53
54 /* psxRegs */
55 DRC_VAR(reg, 128)
56 DRC_VAR(lo, 4)
57 DRC_VAR(hi, 4)
58 DRC_VAR(reg_cop0, 128)
59 DRC_VAR(reg_cop2d, 128)
60 DRC_VAR(reg_cop2c, 128)
61 DRC_VAR(pcaddr, 4)
62 #DRC_VAR(code, 4)
63 #DRC_VAR(cycle, 4)
64 #DRC_VAR(interrupt, 4)
65 #DRC_VAR(intCycle, 256)
66
67 DRC_VAR(rcnts, 7*4*4)
68 DRC_VAR(inv_code_start, 4)
69 DRC_VAR(inv_code_end, 4)
70 DRC_VAR(mem_rtab, 8)
71 DRC_VAR(mem_wtab, 8)
72 DRC_VAR(psxH_ptr, 8)
73 DRC_VAR(invc_ptr, 8)
74 DRC_VAR(zeromem_ptr, 8)
75 DRC_VAR(scratch_buf_ptr, 8)
76 #DRC_VAR(align1, 16) /* unused/alignment */
77 DRC_VAR(mini_ht, 256)
78 DRC_VAR(restore_candidate, 512)
79
80
81         .text
82         .align  2
83
84 /* r0 = virtual target address */
85 /* r1 = instruction to patch */
86 .macro dyna_linker_main
87         /* XXX: should be able to do better than this... */
88         bl      get_addr_ht
89         br      x0
90 .endm
91
92
93 FUNCTION(dyna_linker):
94         /* r0 = virtual target address */
95         /* r1 = instruction to patch */
96         dyna_linker_main
97         .size   dyna_linker, .-dyna_linker
98
99 FUNCTION(exec_pagefault):
100         /* r0 = instruction pointer */
101         /* r1 = fault address */
102         /* r2 = cause */
103         bl      abort
104         .size   exec_pagefault, .-exec_pagefault
105
106 /* Special dynamic linker for the case where a page fault
107    may occur in a branch delay slot */
108 FUNCTION(dyna_linker_ds):
109         /* r0 = virtual target address */
110         /* r1 = instruction to patch */
111         dyna_linker_main
112         .size   dyna_linker_ds, .-dyna_linker_ds
113
114         .align  2
115
116 FUNCTION(jump_vaddr):
117         bl      abort
118         .size   jump_vaddr, .-jump_vaddr
119
120         .align  2
121
122 FUNCTION(verify_code_ds):
123         bl      abort
124 FUNCTION(verify_code_vm):
125 FUNCTION(verify_code):
126         /* r1 = source */
127         /* r2 = target */
128         /* r3 = length */
129         bl      abort
130         .size   verify_code, .-verify_code
131         .size   verify_code_vm, .-verify_code_vm
132
133         .align  2
134 FUNCTION(cc_interrupt):
135         bl      abort
136         .size   cc_interrupt, .-cc_interrupt
137
138         .align  2
139 FUNCTION(do_interrupt):
140         bl      abort
141         .size   do_interrupt, .-do_interrupt
142
143         .align  2
144 FUNCTION(fp_exception):
145         mov     w2, #0x10000000
146 0:
147         ldr     w1, [fp, #LO_reg_cop0+48] /* Status */
148         mov     w3, #0x80000000
149         str     w0, [fp, #LO_reg_cop0+56] /* EPC */
150         orr     w1, w1, #2
151         add     w2, w2, #0x2c
152         str     w1, [fp, #LO_reg_cop0+48] /* Status */
153         str     w2, [fp, #LO_reg_cop0+52] /* Cause */
154         add     w0, w3, #0x80
155         bl      get_addr_ht
156         br      x0
157         .size   fp_exception, .-fp_exception
158         .align  2
159 FUNCTION(fp_exception_ds):
160         mov     w2, #0x90000000 /* Set high bit if delay slot */
161         b       0b
162         .size   fp_exception_ds, .-fp_exception_ds
163
164         .align  2
165 FUNCTION(jump_syscall):
166         ldr     w1, [fp, #LO_reg_cop0+48] /* Status */
167         mov     w3, #0x80000000
168         str     w0, [fp, #LO_reg_cop0+56] /* EPC */
169         orr     w1, w1, #2
170         mov     w2, #0x20
171         str     w1, [fp, #LO_reg_cop0+48] /* Status */
172         str     w2, [fp, #LO_reg_cop0+52] /* Cause */
173         add     w0, w3, #0x80
174         bl      get_addr_ht
175         br      x0
176         .size   jump_syscall, .-jump_syscall
177         .align  2
178
179         .align  2
180 FUNCTION(jump_syscall_hle):
181         bl      abort
182
183         /* note: psxException might do recursive recompiler call from it's HLE code,
184          * so be ready for this */
185 pcsx_return:
186         bl      abort // w10
187         ldr     w1, [fp, #LO_next_interupt]
188         ldr     w10, [fp, #LO_cycle]
189         ldr     w0, [fp, #LO_pcaddr]
190         sub     w10, w10, w1
191         str     w1, [fp, #LO_last_count]
192         bl      get_addr_ht
193         br      x0
194         .size   jump_syscall_hle, .-jump_syscall_hle
195
196         .align  2
197 FUNCTION(jump_hlecall):
198         bl      abort
199         .size   jump_hlecall, .-jump_hlecall
200
201         .align  2
202 FUNCTION(jump_intcall):
203         bl      abort
204         .size   jump_intcall, .-jump_intcall
205
206         /* stack must be aligned by 16, and include space for save_regs() use */
207         .align  2
208 FUNCTION(new_dyna_start):
209         stp     x29, x30, [sp, #-SSP_ALL]!
210         ldr     w1,  [x0, #LO_next_interupt]
211         ldr     w2,  [x0, #LO_cycle]
212         stp     x19, x20, [sp, #16*1]
213         stp     x21, x22, [sp, #16*2]
214         stp     x23, x24, [sp, #16*3]
215         stp     x25, x26, [sp, #16*4]
216         stp     x27, x28, [sp, #16*5]
217         mov     rFP, x0
218         ldr     w0,  [rFP, #LO_pcaddr]
219         str     w1,  [rFP, #LO_last_count]
220         sub     rCC, w2, w1
221         bl      get_addr_ht
222         br      x0
223         .size   new_dyna_start, .-new_dyna_start
224
225         .align  2
226 FUNCTION(new_dyna_leave):
227         ldr     w0,  [rFP, #LO_last_count]
228         add     rCC, rCC, w0
229         str     rCC, [rFP, #LO_cycle]
230         ldp     x19, x20, [sp, #16*1]
231         ldp     x21, x22, [sp, #16*2]
232         ldp     x23, x24, [sp, #16*3]
233         ldp     x25, x26, [sp, #16*4]
234         ldp     x27, x28, [sp, #16*5]
235         ldp     x29, x30, [sp], #SSP_ALL
236         ret
237         .size   new_dyna_leave, .-new_dyna_leave
238
239 /* --------------------------------------- */
240
241 .align  2
242
243 FUNCTION(jump_handler_read8):
244         bl      abort
245
246 FUNCTION(jump_handler_read16):
247         bl      abort
248
249 FUNCTION(jump_handler_read32):
250         bl      abort
251
252 FUNCTION(jump_handler_write8):
253         bl      abort
254
255 FUNCTION(jump_handler_write16):
256         bl      abort
257
258 FUNCTION(jump_handler_write32):
259         bl      abort
260
261 FUNCTION(jump_handler_write_h):
262         bl      abort
263
264 FUNCTION(jump_handle_swl):
265         bl      abort
266
267 FUNCTION(jump_handle_swr):
268         bl      abort
269