451ab91e |
1 | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
2 | * Mupen64plus - linkage_arm.s * |
3 | * Copyright (C) 2009-2011 Ari64 * |
4 | * * |
5 | * This program is free software; you can redistribute it and/or modify * |
6 | * it under the terms of the GNU General Public License as published by * |
7 | * the Free Software Foundation; either version 2 of the License, or * |
8 | * (at your option) any later version. * |
9 | * * |
10 | * This program is distributed in the hope that it will be useful, * |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * |
13 | * GNU General Public License for more details. * |
14 | * * |
15 | * You should have received a copy of the GNU General Public License * |
16 | * along with this program; if not, write to the * |
17 | * Free Software Foundation, Inc., * |
18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * |
19 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
20 | .cpu arm9tdmi |
21 | .fpu softvfp |
22 | .eabi_attribute 20, 1 |
23 | .eabi_attribute 21, 1 |
24 | .eabi_attribute 23, 3 |
25 | .eabi_attribute 24, 1 |
26 | .eabi_attribute 25, 1 |
27 | .eabi_attribute 26, 2 |
28 | .eabi_attribute 30, 6 |
29 | .eabi_attribute 18, 4 |
30 | .file "linkage_arm.S" |
31 | .global extra_memory |
32 | .hidden extra_memory |
33 | .global dynarec_local |
34 | .hidden dynarec_local |
35 | .global reg |
36 | .hidden reg |
37 | .global hi |
38 | .hidden hi |
39 | .global lo |
40 | .hidden lo |
41 | .global reg_cop1_simple |
42 | .hidden reg_cop1_simple |
43 | .global reg_cop1_double |
44 | .hidden reg_cop1_double |
45 | .global reg_cop0 |
46 | .hidden reg_cop0 |
47 | .global FCR0 |
48 | .hidden FCR0 |
49 | .global FCR31 |
50 | .hidden FCR31 |
51 | .global rounding_modes |
52 | .hidden rounding_modes |
53 | .global next_interupt |
54 | .hidden next_interupt |
55 | .global cycle_count |
56 | .hidden cycle_count |
57 | .global last_count |
58 | .hidden last_count |
59 | .global pending_exception |
60 | .hidden pending_exception |
61 | .global pcaddr |
62 | .hidden pcaddr |
63 | .global stop |
64 | .hidden stop |
65 | .global invc_ptr |
66 | .hidden invc_ptr |
67 | .global address |
68 | .hidden address |
69 | .global readmem_dword |
70 | .hidden readmem_dword |
71 | .global dword |
72 | .hidden dword |
73 | .global word |
74 | .hidden word |
75 | .global hword |
76 | .hidden hword |
77 | .global cpu_byte |
78 | .hidden cpu_byte |
79 | .global branch_target |
80 | .hidden branch_target |
81 | .global PC |
82 | .hidden PC |
83 | .global fake_pc |
84 | .hidden fake_pc |
85 | .global mini_ht |
86 | .hidden mini_ht |
87 | .global restore_candidate |
88 | .hidden restore_candidate |
89 | .global ram_offset |
90 | .hidden ram_offset |
91 | .global memory_map |
92 | .hidden memory_map |
93 | .bss |
94 | .align 12 |
95 | .type extra_memory, %object |
96 | .size extra_memory, 33554432 |
97 | extra_memory: |
98 | .space 33554432+64+16+16+8+8+8+8+256+8+8+128+128+128+16+8+132+4+256+512+4194304 |
99 | dynarec_local = extra_memory + 33554432 |
100 | .type dynarec_local, %object |
101 | .size dynarec_local, 64 |
102 | next_interupt = dynarec_local + 64 |
103 | .type next_interupt, %object |
104 | .size next_interupt, 4 |
105 | cycle_count = next_interupt + 4 |
106 | .type cycle_count, %object |
107 | .size cycle_count, 4 |
108 | last_count = cycle_count + 4 |
109 | .type last_count, %object |
110 | .size last_count, 4 |
111 | pending_exception = last_count + 4 |
112 | .type pending_exception, %object |
113 | .size pending_exception, 4 |
114 | pcaddr = pending_exception + 4 |
115 | .type pcaddr, %object |
116 | .size pcaddr, 4 |
117 | stop = pcaddr + 4 |
118 | .type stop, %object |
119 | .size stop, 4 |
120 | invc_ptr = stop + 4 |
121 | .type invc_ptr, %object |
122 | .size invc_ptr, 4 |
123 | address = invc_ptr + 4 |
124 | .type address, %object |
125 | .size address, 4 |
126 | readmem_dword = address + 4 |
127 | .type readmem_dword, %object |
128 | .size readmem_dword, 8 |
129 | dword = readmem_dword + 8 |
130 | .type dword, %object |
131 | .size dword, 8 |
132 | word = dword + 8 |
133 | .type word, %object |
134 | .size word, 4 |
135 | hword = word + 4 |
136 | .type hword, %object |
137 | .size hword, 2 |
138 | cpu_byte = hword + 2 |
139 | .type cpu_byte, %object |
140 | .size cpu_byte, 1 /* 1 byte free */ |
141 | FCR0 = hword + 4 |
142 | .type FCR0, %object |
143 | .size FCR0, 4 |
144 | FCR31 = FCR0 + 4 |
145 | .type FCR31, %object |
146 | .size FCR31, 4 |
147 | reg = FCR31 + 4 |
148 | .type reg, %object |
149 | .size reg, 256 |
150 | hi = reg + 256 |
151 | .type hi, %object |
152 | .size hi, 8 |
153 | lo = hi + 8 |
154 | .type lo, %object |
155 | .size lo, 8 |
156 | reg_cop0 = lo + 8 |
157 | .type reg_cop0, %object |
158 | .size reg_cop0, 128 |
159 | reg_cop1_simple = reg_cop0 + 128 |
160 | .type reg_cop1_simple, %object |
161 | .size reg_cop1_simple, 128 |
162 | reg_cop1_double = reg_cop1_simple + 128 |
163 | .type reg_cop1_double, %object |
164 | .size reg_cop1_double, 128 |
165 | rounding_modes = reg_cop1_double + 128 |
166 | .type rounding_modes, %object |
167 | .size rounding_modes, 16 |
168 | branch_target = rounding_modes + 16 |
169 | .type branch_target, %object |
170 | .size branch_target, 4 |
171 | PC = branch_target + 4 |
172 | .type PC, %object |
173 | .size PC, 4 |
174 | fake_pc = PC + 4 |
175 | .type fake_pc, %object |
176 | .size fake_pc, 132 |
177 | ram_offset = fake_pc + 132 |
178 | .type ram_offset, %object |
179 | .size ram_offset, 4 |
180 | mini_ht = ram_offset + 4 |
181 | .type mini_ht, %object |
182 | .size mini_ht, 256 |
183 | restore_candidate = mini_ht + 256 |
184 | .type restore_candidate, %object |
185 | .size restore_candidate, 512 |
186 | memory_map = restore_candidate + 512 |
187 | .type memory_map, %object |
188 | .size memory_map, 4194304 |
189 | |
190 | .text |
191 | .align 2 |
192 | .global dyna_linker |
193 | .hidden dyna_linker |
194 | .type dyna_linker, %function |
195 | dyna_linker: |
196 | /* r0 = virtual target address */ |
197 | /* r1 = instruction to patch */ |
198 | ldr r4, .tlbptr |
199 | lsr r5, r0, #12 |
200 | mov r12, r0 |
201 | cmp r0, #0xC0000000 |
202 | mov r6, #4096 |
203 | ldrge r12, [r4, r5, lsl #2] |
204 | mov r2, #0x80000 |
205 | ldr r3, .jiptr |
206 | tst r12, r12 |
207 | sub r6, r6, #1 |
208 | moveq r12, r0 |
209 | ldr r7, [r1] |
210 | eor r2, r2, r12, lsr #12 |
211 | and r6, r6, r12, lsr #12 |
212 | cmp r2, #2048 |
213 | add r12, r7, #2 |
214 | orrcs r2, r6, #2048 |
215 | ldr r5, [r3, r2, lsl #2] |
216 | lsl r12, r12, #8 |
217 | /* jump_in lookup */ |
218 | .A1: |
219 | movs r4, r5 |
220 | beq .A3 |
221 | ldr r3, [r5] |
222 | ldr r5, [r4, #12] |
223 | teq r3, r0 |
224 | bne .A1 |
225 | ldr r3, [r4, #4] |
226 | ldr r4, [r4, #8] |
227 | tst r3, r3 |
228 | bne .A1 |
229 | .A2: |
230 | mov r5, r1 |
231 | add r1, r1, r12, asr #6 |
232 | teq r1, r4 |
233 | moveq pc, r4 /* Stale i-cache */ |
234 | bl add_link |
235 | sub r2, r4, r5 |
236 | and r1, r7, #0xff000000 |
237 | lsl r2, r2, #6 |
238 | sub r1, r1, #2 |
239 | add r1, r1, r2, lsr #8 |
240 | str r1, [r5] |
241 | mov pc, r4 |
242 | .A3: |
243 | /* hash_table lookup */ |
244 | cmp r2, #2048 |
245 | ldr r3, .jdptr |
246 | eor r4, r0, r0, lsl #16 |
247 | lslcc r2, r0, #9 |
248 | ldr r6, .htptr |
249 | lsr r4, r4, #12 |
250 | lsrcc r2, r2, #21 |
251 | bic r4, r4, #15 |
252 | ldr r5, [r3, r2, lsl #2] |
253 | ldr r7, [r6, r4]! |
254 | teq r7, r0 |
255 | ldreq pc, [r6, #4] |
256 | ldr r7, [r6, #8] |
257 | teq r7, r0 |
258 | ldreq pc, [r6, #12] |
259 | /* jump_dirty lookup */ |
260 | .A6: |
261 | movs r4, r5 |
262 | beq .A8 |
263 | ldr r3, [r5] |
264 | ldr r5, [r4, #12] |
265 | teq r3, r0 |
266 | bne .A6 |
267 | .A7: |
268 | ldr r1, [r4, #8] |
269 | /* hash_table insert */ |
270 | ldr r2, [r6] |
271 | ldr r3, [r6, #4] |
272 | str r0, [r6] |
273 | str r1, [r6, #4] |
274 | str r2, [r6, #8] |
275 | str r3, [r6, #12] |
276 | mov pc, r1 |
277 | .A8: |
278 | mov r4, r0 |
279 | mov r5, r1 |
280 | bl new_recompile_block |
281 | tst r0, r0 |
282 | mov r0, r4 |
283 | mov r1, r5 |
284 | beq dyna_linker |
285 | /* pagefault */ |
286 | mov r1, r0 |
287 | mov r2, #8 |
288 | .size dyna_linker, .-dyna_linker |
289 | .type exec_pagefault, %function |
290 | exec_pagefault: |
291 | /* r0 = instruction pointer */ |
292 | /* r1 = fault address */ |
293 | /* r2 = cause */ |
294 | ldr r3, [fp, #reg_cop0+48-dynarec_local] /* Status */ |
295 | mvn r6, #0xF000000F |
296 | ldr r4, [fp, #reg_cop0+16-dynarec_local] /* Context */ |
297 | bic r6, r6, #0x0F800000 |
298 | str r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */ |
299 | orr r3, r3, #2 |
300 | str r1, [fp, #reg_cop0+32-dynarec_local] /* BadVAddr */ |
301 | bic r4, r4, r6 |
302 | str r3, [fp, #reg_cop0+48-dynarec_local] /* Status */ |
303 | and r5, r6, r1, lsr #9 |
304 | str r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */ |
305 | and r1, r1, r6, lsl #9 |
306 | str r1, [fp, #reg_cop0+40-dynarec_local] /* EntryHi */ |
307 | orr r4, r4, r5 |
308 | str r4, [fp, #reg_cop0+16-dynarec_local] /* Context */ |
309 | mov r0, #0x80000000 |
310 | bl get_addr_ht |
311 | mov pc, r0 |
312 | .size exec_pagefault, .-exec_pagefault |
313 | /* Special dynamic linker for the case where a page fault |
314 | may occur in a branch delay slot */ |
315 | .global dyna_linker_ds |
316 | .hidden dyna_linker_ds |
317 | .type dyna_linker_ds, %function |
318 | dyna_linker_ds: |
319 | /* r0 = virtual target address */ |
320 | /* r1 = instruction to patch */ |
321 | ldr r4, .tlbptr |
322 | lsr r5, r0, #12 |
323 | mov r12, r0 |
324 | cmp r0, #0xC0000000 |
325 | mov r6, #4096 |
326 | ldrge r12, [r4, r5, lsl #2] |
327 | mov r2, #0x80000 |
328 | ldr r3, .jiptr |
329 | tst r12, r12 |
330 | sub r6, r6, #1 |
331 | moveq r12, r0 |
332 | ldr r7, [r1] |
333 | eor r2, r2, r12, lsr #12 |
334 | and r6, r6, r12, lsr #12 |
335 | cmp r2, #2048 |
336 | add r12, r7, #2 |
337 | orrcs r2, r6, #2048 |
338 | ldr r5, [r3, r2, lsl #2] |
339 | lsl r12, r12, #8 |
340 | /* jump_in lookup */ |
341 | .B1: |
342 | movs r4, r5 |
343 | beq .B3 |
344 | ldr r3, [r5] |
345 | ldr r5, [r4, #12] |
346 | teq r3, r0 |
347 | bne .B1 |
348 | ldr r3, [r4, #4] |
349 | ldr r4, [r4, #8] |
350 | tst r3, r3 |
351 | bne .B1 |
352 | .B2: |
353 | mov r5, r1 |
354 | add r1, r1, r12, asr #6 |
355 | teq r1, r4 |
356 | moveq pc, r4 /* Stale i-cache */ |
357 | bl add_link |
358 | sub r2, r4, r5 |
359 | and r1, r7, #0xff000000 |
360 | lsl r2, r2, #6 |
361 | sub r1, r1, #2 |
362 | add r1, r1, r2, lsr #8 |
363 | str r1, [r5] |
364 | mov pc, r4 |
365 | .B3: |
366 | /* hash_table lookup */ |
367 | cmp r2, #2048 |
368 | ldr r3, .jdptr |
369 | eor r4, r0, r0, lsl #16 |
370 | lslcc r2, r0, #9 |
371 | ldr r6, .htptr |
372 | lsr r4, r4, #12 |
373 | lsrcc r2, r2, #21 |
374 | bic r4, r4, #15 |
375 | ldr r5, [r3, r2, lsl #2] |
376 | ldr r7, [r6, r4]! |
377 | teq r7, r0 |
378 | ldreq pc, [r6, #4] |
379 | ldr r7, [r6, #8] |
380 | teq r7, r0 |
381 | ldreq pc, [r6, #12] |
382 | /* jump_dirty lookup */ |
383 | .B6: |
384 | movs r4, r5 |
385 | beq .B8 |
386 | ldr r3, [r5] |
387 | ldr r5, [r4, #12] |
388 | teq r3, r0 |
389 | bne .B6 |
390 | .B7: |
391 | ldr r1, [r4, #8] |
392 | /* hash_table insert */ |
393 | ldr r2, [r6] |
394 | ldr r3, [r6, #4] |
395 | str r0, [r6] |
396 | str r1, [r6, #4] |
397 | str r2, [r6, #8] |
398 | str r3, [r6, #12] |
399 | mov pc, r1 |
400 | .B8: |
401 | mov r4, r0 |
402 | bic r0, r0, #7 |
403 | mov r5, r1 |
404 | orr r0, r0, #1 |
405 | bl new_recompile_block |
406 | tst r0, r0 |
407 | mov r0, r4 |
408 | mov r1, r5 |
409 | beq dyna_linker_ds |
410 | /* pagefault */ |
411 | bic r1, r0, #7 |
412 | mov r2, #0x80000008 /* High bit set indicates pagefault in delay slot */ |
413 | sub r0, r1, #4 |
414 | b exec_pagefault |
415 | .size dyna_linker_ds, .-dyna_linker_ds |
416 | .jiptr: |
417 | .word jump_in |
418 | .jdptr: |
419 | .word jump_dirty |
420 | .tlbptr: |
421 | .word tlb_LUT_r |
422 | .htptr: |
423 | .word hash_table |
424 | .align 2 |
425 | .global jump_vaddr_r0 |
426 | .hidden jump_vaddr_r0 |
427 | .type jump_vaddr_r0, %function |
428 | jump_vaddr_r0: |
429 | eor r2, r0, r0, lsl #16 |
430 | b jump_vaddr |
431 | .size jump_vaddr_r0, .-jump_vaddr_r0 |
432 | .global jump_vaddr_r1 |
433 | .hidden jump_vaddr_r1 |
434 | .type jump_vaddr_r1, %function |
435 | jump_vaddr_r1: |
436 | eor r2, r1, r1, lsl #16 |
437 | mov r0, r1 |
438 | b jump_vaddr |
439 | .size jump_vaddr_r1, .-jump_vaddr_r1 |
440 | .global jump_vaddr_r2 |
441 | .hidden jump_vaddr_r2 |
442 | .type jump_vaddr_r2, %function |
443 | jump_vaddr_r2: |
444 | mov r0, r2 |
445 | eor r2, r2, r2, lsl #16 |
446 | b jump_vaddr |
447 | .size jump_vaddr_r2, .-jump_vaddr_r2 |
448 | .global jump_vaddr_r3 |
449 | .hidden jump_vaddr_r3 |
450 | .type jump_vaddr_r3, %function |
451 | jump_vaddr_r3: |
452 | eor r2, r3, r3, lsl #16 |
453 | mov r0, r3 |
454 | b jump_vaddr |
455 | .size jump_vaddr_r3, .-jump_vaddr_r3 |
456 | .global jump_vaddr_r4 |
457 | .hidden jump_vaddr_r4 |
458 | .type jump_vaddr_r4, %function |
459 | jump_vaddr_r4: |
460 | eor r2, r4, r4, lsl #16 |
461 | mov r0, r4 |
462 | b jump_vaddr |
463 | .size jump_vaddr_r4, .-jump_vaddr_r4 |
464 | .global jump_vaddr_r5 |
465 | .hidden jump_vaddr_r5 |
466 | .type jump_vaddr_r5, %function |
467 | jump_vaddr_r5: |
468 | eor r2, r5, r5, lsl #16 |
469 | mov r0, r5 |
470 | b jump_vaddr |
471 | .size jump_vaddr_r5, .-jump_vaddr_r5 |
472 | .global jump_vaddr_r6 |
473 | .hidden jump_vaddr_r6 |
474 | .type jump_vaddr_r6, %function |
475 | jump_vaddr_r6: |
476 | eor r2, r6, r6, lsl #16 |
477 | mov r0, r6 |
478 | b jump_vaddr |
479 | .size jump_vaddr_r6, .-jump_vaddr_r6 |
480 | .global jump_vaddr_r8 |
481 | .hidden jump_vaddr_r8 |
482 | .type jump_vaddr_r8, %function |
483 | jump_vaddr_r8: |
484 | eor r2, r8, r8, lsl #16 |
485 | mov r0, r8 |
486 | b jump_vaddr |
487 | .size jump_vaddr_r8, .-jump_vaddr_r8 |
488 | .global jump_vaddr_r9 |
489 | .hidden jump_vaddr_r9 |
490 | .type jump_vaddr_r9, %function |
491 | jump_vaddr_r9: |
492 | eor r2, r9, r9, lsl #16 |
493 | mov r0, r9 |
494 | b jump_vaddr |
495 | .size jump_vaddr_r9, .-jump_vaddr_r9 |
496 | .global jump_vaddr_r10 |
497 | .hidden jump_vaddr_r10 |
498 | .type jump_vaddr_r10, %function |
499 | jump_vaddr_r10: |
500 | eor r2, r10, r10, lsl #16 |
501 | mov r0, r10 |
502 | b jump_vaddr |
503 | .size jump_vaddr_r10, .-jump_vaddr_r10 |
504 | .global jump_vaddr_r12 |
505 | .hidden jump_vaddr_r12 |
506 | .type jump_vaddr_r12, %function |
507 | jump_vaddr_r12: |
508 | eor r2, r12, r12, lsl #16 |
509 | mov r0, r12 |
510 | b jump_vaddr |
511 | .size jump_vaddr_r12, .-jump_vaddr_r12 |
512 | .global jump_vaddr_r7 |
513 | .hidden jump_vaddr_r7 |
514 | .type jump_vaddr_r7, %function |
515 | jump_vaddr_r7: |
516 | eor r2, r7, r7, lsl #16 |
517 | add r0, r7, #0 |
518 | .size jump_vaddr_r7, .-jump_vaddr_r7 |
519 | .global jump_vaddr |
520 | .hidden jump_vaddr |
521 | .type jump_vaddr, %function |
522 | jump_vaddr: |
523 | ldr r1, .htptr |
524 | mvn r3, #15 |
525 | and r2, r3, r2, lsr #12 |
526 | ldr r2, [r1, r2]! |
527 | teq r2, r0 |
528 | ldreq pc, [r1, #4] |
529 | ldr r2, [r1, #8] |
530 | teq r2, r0 |
531 | ldreq pc, [r1, #12] |
532 | str r10, [fp, #cycle_count-dynarec_local] |
533 | bl get_addr |
534 | ldr r10, [fp, #cycle_count-dynarec_local] |
535 | mov pc, r0 |
536 | .size jump_vaddr, .-jump_vaddr |
537 | .align 2 |
538 | .global verify_code_ds |
539 | .hidden verify_code_ds |
540 | .type verify_code_ds, %function |
541 | verify_code_ds: |
542 | str r8, [fp, #branch_target-dynarec_local] |
543 | .size verify_code_ds, .-verify_code_ds |
544 | .global verify_code_vm |
545 | .hidden verify_code_vm |
546 | .type verify_code_vm, %function |
547 | verify_code_vm: |
548 | /* r0 = instruction pointer (virtual address) */ |
549 | /* r1 = source (virtual address) */ |
550 | /* r2 = target */ |
551 | /* r3 = length */ |
552 | cmp r1, #0xC0000000 |
553 | blt verify_code |
554 | add r12, fp, #memory_map-dynarec_local |
555 | lsr r4, r1, #12 |
556 | add r5, r1, r3 |
557 | sub r5, #1 |
558 | ldr r6, [r12, r4, lsl #2] |
559 | lsr r5, r5, #12 |
560 | movs r7, r6 |
561 | bmi .D5 |
562 | add r1, r1, r6, lsl #2 |
563 | lsl r6, r6, #2 |
564 | .D1: |
565 | add r4, r4, #1 |
566 | teq r6, r7, lsl #2 |
567 | bne .D5 |
568 | ldr r7, [r12, r4, lsl #2] |
569 | cmp r4, r5 |
570 | bls .D1 |
571 | .size verify_code_vm, .-verify_code_vm |
572 | .global verify_code |
573 | .hidden verify_code |
574 | .type verify_code, %function |
575 | verify_code: |
576 | /* r1 = source */ |
577 | /* r2 = target */ |
578 | /* r3 = length */ |
579 | tst r3, #4 |
580 | mov r4, #0 |
581 | add r3, r1, r3 |
582 | mov r5, #0 |
583 | ldrne r4, [r1], #4 |
584 | mov r12, #0 |
585 | ldrne r5, [r2], #4 |
586 | teq r1, r3 |
587 | beq .D3 |
588 | .D2: |
589 | ldr r7, [r1], #4 |
590 | eor r9, r4, r5 |
591 | ldr r8, [r2], #4 |
592 | orrs r9, r9, r12 |
593 | bne .D4 |
594 | ldr r4, [r1], #4 |
595 | eor r12, r7, r8 |
596 | ldr r5, [r2], #4 |
597 | cmp r1, r3 |
598 | bcc .D2 |
599 | teq r7, r8 |
600 | .D3: |
601 | teqeq r4, r5 |
602 | .D4: |
603 | ldr r8, [fp, #branch_target-dynarec_local] |
604 | moveq pc, lr |
605 | .D5: |
606 | bl get_addr |
607 | mov pc, r0 |
608 | .size verify_code, .-verify_code |
609 | .align 2 |
610 | .global cc_interrupt |
611 | .hidden cc_interrupt |
612 | .type cc_interrupt, %function |
613 | cc_interrupt: |
614 | ldr r0, [fp, #last_count-dynarec_local] |
615 | mov r1, #0 |
616 | mov r2, #0x1fc |
617 | add r10, r0, r10 |
618 | str r1, [fp, #pending_exception-dynarec_local] |
619 | and r2, r2, r10, lsr #17 |
620 | add r3, fp, #restore_candidate-dynarec_local |
621 | str r10, [fp, #reg_cop0+36-dynarec_local] /* Count */ |
622 | ldr r4, [r2, r3] |
623 | mov r10, lr |
624 | tst r4, r4 |
625 | bne .E4 |
626 | .E1: |
627 | bl gen_interupt |
628 | mov lr, r10 |
629 | ldr r10, [fp, #reg_cop0+36-dynarec_local] /* Count */ |
630 | ldr r0, [fp, #next_interupt-dynarec_local] |
631 | ldr r1, [fp, #pending_exception-dynarec_local] |
632 | ldr r2, [fp, #stop-dynarec_local] |
633 | str r0, [fp, #last_count-dynarec_local] |
634 | sub r10, r10, r0 |
635 | tst r2, r2 |
636 | bne .E3 |
637 | tst r1, r1 |
638 | moveq pc, lr |
639 | .E2: |
640 | ldr r0, [fp, #pcaddr-dynarec_local] |
641 | bl get_addr_ht |
642 | mov pc, r0 |
643 | .E3: |
644 | add r12, fp, #28 |
645 | ldmia r12, {r4, r5, r6, r7, r8, r9, sl, fp, pc} |
646 | .E4: |
647 | /* Move 'dirty' blocks to the 'clean' list */ |
648 | lsl r5, r2, #3 |
649 | str r1, [r2, r3] |
650 | .E5: |
651 | lsrs r4, r4, #1 |
652 | mov r0, r5 |
653 | add r5, r5, #1 |
654 | blcs clean_blocks |
655 | tst r5, #31 |
656 | bne .E5 |
657 | b .E1 |
658 | |
659 | .size cc_interrupt, .-cc_interrupt |
660 | .align 2 |
661 | .global do_interrupt |
662 | .hidden do_interrupt |
663 | .type do_interrupt, %function |
664 | do_interrupt: |
665 | ldr r0, [fp, #pcaddr-dynarec_local] |
666 | bl get_addr_ht |
667 | ldr r1, [fp, #next_interupt-dynarec_local] |
668 | ldr r10, [fp, #reg_cop0+36-dynarec_local] /* Count */ |
669 | str r1, [fp, #last_count-dynarec_local] |
670 | sub r10, r10, r1 |
671 | add r10, r10, #2 |
672 | mov pc, r0 |
673 | .size do_interrupt, .-do_interrupt |
674 | .align 2 |
675 | .global fp_exception |
676 | .hidden fp_exception |
677 | .type fp_exception, %function |
678 | fp_exception: |
679 | mov r2, #0x10000000 |
680 | .E7: |
681 | ldr r1, [fp, #reg_cop0+48-dynarec_local] /* Status */ |
682 | mov r3, #0x80000000 |
683 | str r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */ |
684 | orr r1, #2 |
685 | add r2, r2, #0x2c |
686 | str r1, [fp, #reg_cop0+48-dynarec_local] /* Status */ |
687 | str r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */ |
688 | add r0, r3, #0x180 |
689 | bl get_addr_ht |
690 | mov pc, r0 |
691 | .size fp_exception, .-fp_exception |
692 | .align 2 |
693 | .global fp_exception_ds |
694 | .hidden fp_exception_ds |
695 | .type fp_exception_ds, %function |
696 | fp_exception_ds: |
697 | mov r2, #0x90000000 /* Set high bit if delay slot */ |
698 | b .E7 |
699 | .size fp_exception_ds, .-fp_exception_ds |
700 | .align 2 |
701 | .global jump_syscall |
702 | .hidden jump_syscall |
703 | .type jump_syscall, %function |
704 | jump_syscall: |
705 | ldr r1, [fp, #reg_cop0+48-dynarec_local] /* Status */ |
706 | mov r3, #0x80000000 |
707 | str r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */ |
708 | orr r1, #2 |
709 | mov r2, #0x20 |
710 | str r1, [fp, #reg_cop0+48-dynarec_local] /* Status */ |
711 | str r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */ |
712 | add r0, r3, #0x180 |
713 | bl get_addr_ht |
714 | mov pc, r0 |
715 | .size jump_syscall, .-jump_syscall |
716 | .align 2 |
717 | .global indirect_jump_indexed |
718 | .hidden indirect_jump_indexed |
719 | .type indirect_jump_indexed, %function |
720 | indirect_jump_indexed: |
721 | ldr r0, [r0, r1, lsl #2] |
722 | .size indirect_jump_indexed, .-indirect_jump_indexed |
723 | .align 2 |
724 | .global indirect_jump |
725 | .hidden indirect_jump |
726 | .type indirect_jump, %function |
727 | indirect_jump: |
728 | ldr r12, [fp, #last_count-dynarec_local] |
729 | add r2, r2, r12 |
730 | str r2, [fp, #reg_cop0+36-dynarec_local] /* Count */ |
731 | mov pc, r0 |
732 | .size indirect_jump, .-indirect_jump |
733 | .align 2 |
734 | .global jump_eret |
735 | .hidden jump_eret |
736 | .type jump_eret, %function |
737 | jump_eret: |
738 | ldr r1, [fp, #reg_cop0+48-dynarec_local] /* Status */ |
739 | ldr r0, [fp, #last_count-dynarec_local] |
740 | bic r1, r1, #2 |
741 | add r10, r0, r10 |
742 | str r1, [fp, #reg_cop0+48-dynarec_local] /* Status */ |
743 | str r10, [fp, #reg_cop0+36-dynarec_local] /* Count */ |
744 | bl check_interupt |
745 | ldr r1, [fp, #next_interupt-dynarec_local] |
746 | ldr r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */ |
747 | str r1, [fp, #last_count-dynarec_local] |
748 | subs r10, r10, r1 |
749 | bpl .E11 |
750 | .E8: |
751 | add r6, fp, #reg+256-dynarec_local |
752 | mov r5, #248 |
753 | mov r1, #0 |
754 | .E9: |
755 | ldr r2, [r6, #-8]! |
756 | ldr r3, [r6, #4] |
757 | eor r3, r3, r2, asr #31 |
758 | subs r3, r3, #1 |
759 | adc r1, r1, r1 |
760 | subs r5, r5, #8 |
761 | bne .E9 |
762 | ldr r2, [fp, #hi-dynarec_local] |
763 | ldr r3, [fp, #hi+4-dynarec_local] |
764 | eors r3, r3, r2, asr #31 |
765 | ldr r2, [fp, #lo-dynarec_local] |
766 | ldreq r3, [fp, #lo+4-dynarec_local] |
767 | eoreq r3, r3, r2, asr #31 |
768 | subs r3, r3, #1 |
769 | adc r1, r1, r1 |
770 | bl get_addr_32 |
771 | mov pc, r0 |
772 | .E11: |
773 | str r0, [fp, #pcaddr-dynarec_local] |
774 | bl cc_interrupt |
775 | ldr r0, [fp, #pcaddr-dynarec_local] |
776 | b .E8 |
777 | .size jump_eret, .-jump_eret |
778 | .align 2 |
779 | .global new_dyna_start |
780 | .hidden new_dyna_start |
781 | .type new_dyna_start, %function |
782 | new_dyna_start: |
783 | ldr r12, .dlptr |
784 | ldr r1, .tgtptr |
785 | mov r0, #0xa4000000 |
786 | stmia r12, {r4, r5, r6, r7, r8, r9, sl, fp, lr} |
787 | sub fp, r12, #28 |
788 | ldr r4, [r1] |
789 | add r0, r0, #0x40 |
790 | bl new_recompile_block |
791 | ldr r0, [fp, #next_interupt-dynarec_local] |
792 | ldr r10, [fp, #reg_cop0+36-dynarec_local] /* Count */ |
793 | str r0, [fp, #last_count-dynarec_local] |
794 | sub r10, r10, r0 |
795 | mov pc, r4 |
796 | .dlptr: |
797 | .word dynarec_local+28 |
798 | .tgtptr: |
799 | .word out |
800 | .size new_dyna_start, .-new_dyna_start |
801 | .align 2 |
802 | .global invalidate_addr_r0 |
803 | .hidden invalidate_addr_r0 |
804 | .type invalidate_addr_r0, %function |
805 | invalidate_addr_r0: |
806 | stmia fp, {r0, r1, r2, r3, r12, lr} |
807 | lsr r0, r0, #12 |
808 | b invalidate_addr_call |
809 | .size invalidate_addr_r0, .-invalidate_addr_r0 |
810 | .align 2 |
811 | .global invalidate_addr_r1 |
812 | .hidden invalidate_addr_r1 |
813 | .type invalidate_addr_r1, %function |
814 | invalidate_addr_r1: |
815 | stmia fp, {r0, r1, r2, r3, r12, lr} |
816 | lsr r0, r1, #12 |
817 | b invalidate_addr_call |
818 | .size invalidate_addr_r1, .-invalidate_addr_r1 |
819 | .align 2 |
820 | .global invalidate_addr_r2 |
821 | .hidden invalidate_addr_r2 |
822 | .type invalidate_addr_r2, %function |
823 | invalidate_addr_r2: |
824 | stmia fp, {r0, r1, r2, r3, r12, lr} |
825 | lsr r0, r2, #12 |
826 | b invalidate_addr_call |
827 | .size invalidate_addr_r2, .-invalidate_addr_r2 |
828 | .align 2 |
829 | .global invalidate_addr_r3 |
830 | .hidden invalidate_addr_r3 |
831 | .type invalidate_addr_r3, %function |
832 | invalidate_addr_r3: |
833 | stmia fp, {r0, r1, r2, r3, r12, lr} |
834 | lsr r0, r3, #12 |
835 | b invalidate_addr_call |
836 | .size invalidate_addr_r3, .-invalidate_addr_r3 |
837 | .align 2 |
838 | .global invalidate_addr_r4 |
839 | .hidden invalidate_addr_r4 |
840 | .type invalidate_addr_r4, %function |
841 | invalidate_addr_r4: |
842 | stmia fp, {r0, r1, r2, r3, r12, lr} |
843 | lsr r0, r4, #12 |
844 | b invalidate_addr_call |
845 | .size invalidate_addr_r4, .-invalidate_addr_r4 |
846 | .align 2 |
847 | .global invalidate_addr_r5 |
848 | .hidden invalidate_addr_r5 |
849 | .type invalidate_addr_r5, %function |
850 | invalidate_addr_r5: |
851 | stmia fp, {r0, r1, r2, r3, r12, lr} |
852 | lsr r0, r5, #12 |
853 | b invalidate_addr_call |
854 | .size invalidate_addr_r5, .-invalidate_addr_r5 |
855 | .align 2 |
856 | .global invalidate_addr_r6 |
857 | .hidden invalidate_addr_r6 |
858 | .type invalidate_addr_r6, %function |
859 | invalidate_addr_r6: |
860 | stmia fp, {r0, r1, r2, r3, r12, lr} |
861 | lsr r0, r6, #12 |
862 | b invalidate_addr_call |
863 | .size invalidate_addr_r6, .-invalidate_addr_r6 |
864 | .align 2 |
865 | .global invalidate_addr_r7 |
866 | .hidden invalidate_addr_r7 |
867 | .type invalidate_addr_r7, %function |
868 | invalidate_addr_r7: |
869 | stmia fp, {r0, r1, r2, r3, r12, lr} |
870 | lsr r0, r7, #12 |
871 | b invalidate_addr_call |
872 | .size invalidate_addr_r7, .-invalidate_addr_r7 |
873 | .align 2 |
874 | .global invalidate_addr_r8 |
875 | .hidden invalidate_addr_r8 |
876 | .type invalidate_addr_r8, %function |
877 | invalidate_addr_r8: |
878 | stmia fp, {r0, r1, r2, r3, r12, lr} |
879 | lsr r0, r8, #12 |
880 | b invalidate_addr_call |
881 | .size invalidate_addr_r8, .-invalidate_addr_r8 |
882 | .align 2 |
883 | .global invalidate_addr_r9 |
884 | .hidden invalidate_addr_r9 |
885 | .type invalidate_addr_r9, %function |
886 | invalidate_addr_r9: |
887 | stmia fp, {r0, r1, r2, r3, r12, lr} |
888 | lsr r0, r9, #12 |
889 | b invalidate_addr_call |
890 | .size invalidate_addr_r9, .-invalidate_addr_r9 |
891 | .align 2 |
892 | .global invalidate_addr_r10 |
893 | .hidden invalidate_addr_r10 |
894 | .type invalidate_addr_r10, %function |
895 | invalidate_addr_r10: |
896 | stmia fp, {r0, r1, r2, r3, r12, lr} |
897 | lsr r0, r10, #12 |
898 | b invalidate_addr_call |
899 | .size invalidate_addr_r10, .-invalidate_addr_r10 |
900 | .align 2 |
901 | .global invalidate_addr_r12 |
902 | .hidden invalidate_addr_r12 |
903 | .type invalidate_addr_r12, %function |
904 | invalidate_addr_r12: |
905 | stmia fp, {r0, r1, r2, r3, r12, lr} |
906 | lsr r0, r12, #12 |
907 | .size invalidate_addr_r12, .-invalidate_addr_r12 |
908 | .align 2 |
909 | .type invalidate_addr_call, %function |
910 | invalidate_addr_call: |
911 | bl invalidate_block |
912 | ldmia fp, {r0, r1, r2, r3, r12, pc} |
913 | .size invalidate_addr_call, .-invalidate_addr_call |
914 | .align 2 |
915 | .global write_rdram_new |
916 | .hidden write_rdram_new |
917 | .type write_rdram_new, %function |
918 | write_rdram_new: |
919 | ldr r3, [fp, #ram_offset-dynarec_local] |
920 | ldr r2, [fp, #address-dynarec_local] |
921 | ldr r0, [fp, #word-dynarec_local] |
922 | str r0, [r2, r3, lsl #2] |
923 | b .E12 |
924 | .size write_rdram_new, .-write_rdram_new |
925 | .align 2 |
926 | .global write_rdramb_new |
927 | .hidden write_rdramb_new |
928 | .type write_rdramb_new, %function |
929 | write_rdramb_new: |
930 | ldr r3, [fp, #ram_offset-dynarec_local] |
931 | ldr r2, [fp, #address-dynarec_local] |
932 | ldrb r0, [fp, #cpu_byte-dynarec_local] |
933 | eor r2, r2, #3 |
934 | strb r0, [r2, r3, lsl #2] |
935 | b .E12 |
936 | .size write_rdramb_new, .-write_rdramb_new |
937 | .align 2 |
938 | .global write_rdramh_new |
939 | .hidden write_rdramh_new |
940 | .type write_rdramh_new, %function |
941 | write_rdramh_new: |
942 | ldr r3, [fp, #ram_offset-dynarec_local] |
943 | ldr r2, [fp, #address-dynarec_local] |
944 | ldrh r0, [fp, #hword-dynarec_local] |
945 | eor r2, r2, #2 |
946 | lsl r3, r3, #2 |
947 | strh r0, [r2, r3] |
948 | b .E12 |
949 | .size write_rdramh_new, .-write_rdramh_new |
950 | .align 2 |
951 | .global write_rdramd_new |
952 | .hidden write_rdramd_new |
953 | .type write_rdramd_new, %function |
954 | write_rdramd_new: |
955 | ldr r3, [fp, #ram_offset-dynarec_local] |
956 | ldr r2, [fp, #address-dynarec_local] |
957 | /* ldrd r0, [fp, #dword-dynarec_local]*/ |
958 | ldr r0, [fp, #dword-dynarec_local] |
959 | ldr r1, [fp, #dword+4-dynarec_local] |
960 | add r3, r2, r3, lsl #2 |
961 | str r0, [r3, #4] |
962 | str r1, [r3] |
963 | b .E12 |
964 | .size write_rdramd_new, .-write_rdramd_new |
965 | .align 2 |
966 | .type do_invalidate, %function |
967 | do_invalidate: |
968 | ldr r2, [fp, #address-dynarec_local] |
969 | .E12: |
970 | ldr r1, [fp, #invc_ptr-dynarec_local] |
971 | lsr r0, r2, #12 |
972 | ldrb r2, [r1, r0] |
973 | tst r2, r2 |
974 | beq invalidate_block |
975 | mov pc, lr |
976 | .size do_invalidate, .-do_invalidate |
977 | .align 2 |
978 | .global read_nomem_new |
979 | .hidden read_nomem_new |
980 | .type read_nomem_new, %function |
981 | read_nomem_new: |
982 | ldr r2, [fp, #address-dynarec_local] |
983 | add r12, fp, #memory_map-dynarec_local |
984 | lsr r0, r2, #12 |
985 | ldr r12, [r12, r0, lsl #2] |
986 | mov r1, #8 |
987 | tst r12, r12 |
988 | bmi tlb_exception |
989 | ldr r0, [r2, r12, lsl #2] |
990 | str r0, [fp, #readmem_dword-dynarec_local] |
991 | mov pc, lr |
992 | .size read_nomem_new, .-read_nomem_new |
993 | .align 2 |
994 | .global read_nomemb_new |
995 | .hidden read_nomemb_new |
996 | .type read_nomemb_new, %function |
997 | read_nomemb_new: |
998 | ldr r2, [fp, #address-dynarec_local] |
999 | add r12, fp, #memory_map-dynarec_local |
1000 | lsr r0, r2, #12 |
1001 | ldr r12, [r12, r0, lsl #2] |
1002 | mov r1, #8 |
1003 | tst r12, r12 |
1004 | bmi tlb_exception |
1005 | eor r2, r2, #3 |
1006 | ldrb r0, [r2, r12, lsl #2] |
1007 | str r0, [fp, #readmem_dword-dynarec_local] |
1008 | mov pc, lr |
1009 | .size read_nomemb_new, .-read_nomemb_new |
1010 | .align 2 |
1011 | .global read_nomemh_new |
1012 | .hidden read_nomemh_new |
1013 | .type read_nomemh_new, %function |
1014 | read_nomemh_new: |
1015 | ldr r2, [fp, #address-dynarec_local] |
1016 | add r12, fp, #memory_map-dynarec_local |
1017 | lsr r0, r2, #12 |
1018 | ldr r12, [r12, r0, lsl #2] |
1019 | mov r1, #8 |
1020 | tst r12, r12 |
1021 | bmi tlb_exception |
1022 | lsl r12, r12, #2 |
1023 | eor r2, r2, #2 |
1024 | ldrh r0, [r2, r12] |
1025 | str r0, [fp, #readmem_dword-dynarec_local] |
1026 | mov pc, lr |
1027 | .size read_nomemh_new, .-read_nomemh_new |
1028 | .align 2 |
1029 | .global read_nomemd_new |
1030 | .hidden read_nomemd_new |
1031 | .type read_nomemd_new, %function |
1032 | read_nomemd_new: |
1033 | ldr r2, [fp, #address-dynarec_local] |
1034 | add r12, fp, #memory_map-dynarec_local |
1035 | lsr r0, r2, #12 |
1036 | ldr r12, [r12, r0, lsl #2] |
1037 | mov r1, #8 |
1038 | tst r12, r12 |
1039 | bmi tlb_exception |
1040 | lsl r12, r12, #2 |
1041 | /* ldrd r0, [r2, r12]*/ |
1042 | add r3, r2, #4 |
1043 | ldr r0, [r2, r12] |
1044 | ldr r1, [r3, r12] |
1045 | str r0, [fp, #readmem_dword+4-dynarec_local] |
1046 | str r1, [fp, #readmem_dword-dynarec_local] |
1047 | mov pc, lr |
1048 | .size read_nomemd_new, .-read_nomemd_new |
1049 | .align 2 |
1050 | .global write_nomem_new |
1051 | .hidden write_nomem_new |
1052 | .type write_nomem_new, %function |
1053 | write_nomem_new: |
1054 | str r3, [fp, #24] |
1055 | str lr, [fp, #28] |
1056 | bl do_invalidate |
1057 | ldr r2, [fp, #address-dynarec_local] |
1058 | add r12, fp, #memory_map-dynarec_local |
1059 | ldr lr, [fp, #28] |
1060 | lsr r0, r2, #12 |
1061 | ldr r3, [fp, #24] |
1062 | ldr r12, [r12, r0, lsl #2] |
1063 | mov r1, #0xc |
1064 | tst r12, #0x40000000 |
1065 | bne tlb_exception |
1066 | ldr r0, [fp, #word-dynarec_local] |
1067 | str r0, [r2, r12, lsl #2] |
1068 | mov pc, lr |
1069 | .size write_nomem_new, .-write_nomem_new |
1070 | .align 2 |
1071 | .global write_nomemb_new |
1072 | .hidden write_nomemb_new |
1073 | .type write_nomemb_new, %function |
1074 | write_nomemb_new: |
1075 | str r3, [fp, #24] |
1076 | str lr, [fp, #28] |
1077 | bl do_invalidate |
1078 | ldr r2, [fp, #address-dynarec_local] |
1079 | add r12, fp, #memory_map-dynarec_local |
1080 | ldr lr, [fp, #28] |
1081 | lsr r0, r2, #12 |
1082 | ldr r3, [fp, #24] |
1083 | ldr r12, [r12, r0, lsl #2] |
1084 | mov r1, #0xc |
1085 | tst r12, #0x40000000 |
1086 | bne tlb_exception |
1087 | eor r2, r2, #3 |
1088 | ldrb r0, [fp, #cpu_byte-dynarec_local] |
1089 | strb r0, [r2, r12, lsl #2] |
1090 | mov pc, lr |
1091 | .size write_nomemb_new, .-write_nomemb_new |
1092 | .align 2 |
1093 | .global write_nomemh_new |
1094 | .hidden write_nomemh_new |
1095 | .type write_nomemh_new, %function |
1096 | write_nomemh_new: |
1097 | str r3, [fp, #24] |
1098 | str lr, [fp, #28] |
1099 | bl do_invalidate |
1100 | ldr r2, [fp, #address-dynarec_local] |
1101 | add r12, fp, #memory_map-dynarec_local |
1102 | ldr lr, [fp, #28] |
1103 | lsr r0, r2, #12 |
1104 | ldr r3, [fp, #24] |
1105 | ldr r12, [r12, r0, lsl #2] |
1106 | mov r1, #0xc |
1107 | lsls r12, #2 |
1108 | bcs tlb_exception |
1109 | eor r2, r2, #2 |
1110 | ldrh r0, [fp, #hword-dynarec_local] |
1111 | strh r0, [r2, r12] |
1112 | mov pc, lr |
1113 | .size write_nomemh_new, .-write_nomemh_new |
1114 | .align 2 |
1115 | .global write_nomemd_new |
1116 | .hidden write_nomemd_new |
1117 | .type write_nomemd_new, %function |
1118 | write_nomemd_new: |
1119 | str r3, [fp, #24] |
1120 | str lr, [fp, #28] |
1121 | bl do_invalidate |
1122 | ldr r2, [fp, #address-dynarec_local] |
1123 | add r12, fp, #memory_map-dynarec_local |
1124 | ldr lr, [fp, #28] |
1125 | lsr r0, r2, #12 |
1126 | ldr r3, [fp, #24] |
1127 | ldr r12, [r12, r0, lsl #2] |
1128 | mov r1, #0xc |
1129 | lsls r12, #2 |
1130 | bcs tlb_exception |
1131 | add r3, r2, #4 |
1132 | ldr r0, [fp, #dword+4-dynarec_local] |
1133 | ldr r1, [fp, #dword-dynarec_local] |
1134 | /* strd r0, [r2, r12]*/ |
1135 | str r0, [r2, r12] |
1136 | str r1, [r3, r12] |
1137 | mov pc, lr |
1138 | .size write_nomemd_new, .-write_nomemd_new |
1139 | .align 2 |
1140 | .type tlb_exception, %function |
1141 | tlb_exception: |
1142 | /* r1 = cause */ |
1143 | /* r2 = address */ |
1144 | /* r3 = instr addr/flags */ |
1145 | ldr r4, [fp, #reg_cop0+48-dynarec_local] /* Status */ |
1146 | add r5, fp, #memory_map-dynarec_local |
1147 | lsr r6, r3, #12 |
1148 | orr r1, r1, r3, lsl #31 |
1149 | orr r4, r4, #2 |
1150 | ldr r7, [r5, r6, lsl #2] |
1151 | bic r8, r3, #3 |
1152 | str r4, [fp, #reg_cop0+48-dynarec_local] /* Status */ |
1153 | mov r6, #0x6000000 |
1154 | str r1, [fp, #reg_cop0+52-dynarec_local] /* Cause */ |
1155 | orr r6, r6, #0x22 |
1156 | ldr r0, [r8, r7, lsl #2] |
1157 | add r4, r8, r1, asr #29 |
1158 | add r5, fp, #reg-dynarec_local |
1159 | str r4, [fp, #reg_cop0+56-dynarec_local] /* EPC */ |
1160 | mov r7, #0xf8 |
1161 | ldr r8, [fp, #reg_cop0+16-dynarec_local] /* Context */ |
1162 | lsl r1, r0, #16 |
1163 | lsr r4, r0, #26 |
1164 | and r7, r7, r0, lsr #18 |
1165 | mvn r9, #0xF000000F |
1166 | sub r2, r2, r1, asr #16 |
1167 | bic r9, r9, #0x0F800000 |
1168 | rors r6, r6, r4 |
1169 | mov r0, #0x80000000 |
1170 | ldrcs r2, [r5, r7] |
1171 | bic r8, r8, r9 |
1172 | tst r3, #2 |
1173 | str r2, [r5, r7] |
1174 | add r4, r2, r1, asr #16 |
1175 | add r6, fp, #reg+4-dynarec_local |
1176 | asr r3, r2, #31 |
1177 | str r4, [fp, #reg_cop0+32-dynarec_local] /* BadVAddr */ |
1178 | add r0, r0, #0x180 |
1179 | and r4, r9, r4, lsr #9 |
1180 | strne r3, [r6, r7] |
1181 | orr r8, r8, r4 |
1182 | str r8, [fp, #reg_cop0+16-dynarec_local] /* Context */ |
1183 | bl get_addr_ht |
1184 | ldr r1, [fp, #next_interupt-dynarec_local] |
1185 | ldr r10, [fp, #reg_cop0+36-dynarec_local] /* Count */ |
1186 | str r1, [fp, #last_count-dynarec_local] |
1187 | sub r10, r10, r1 |
1188 | mov pc, r0 |
1189 | .size tlb_exception, .-tlb_exception |
1190 | .align 2 |
1191 | .global breakpoint |
1192 | .hidden breakpoint |
1193 | .type breakpoint, %function |
1194 | breakpoint: |
1195 | /* Set breakpoint here for debugging */ |
1196 | mov pc, lr |
1197 | .size breakpoint, .-breakpoint |
1198 | /* The following bug-fix implements __clear_cache (missing in Android) */ |
1199 | .align 2 |
1200 | .global __clear_cache_bugfix |
1201 | .hidden __clear_cache_bugfix |
1202 | .type __clear_cache_bugfix, %function |
1203 | __clear_cache_bugfix: |
1204 | push {r7, lr} |
1205 | mov r2, #0 |
1206 | mov r7, #0x2 |
1207 | add r7, r7, #0xf0000 |
1208 | svc 0x00000000 |
1209 | pop {r7, pc} |
1210 | .size __clear_cache_bugfix, .-__clear_cache_bugfix |
1211 | /* End of bug-fix */ |
1212 | .section .note.GNU-stack,"",%progbits |