add unmodified Ari64 drc to track it's changes
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / linkage_x86_64.s
CommitLineData
57871462 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - linkage_x86_64.s *
3 * Copyright (C) 2009-2010 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 .file "linkage_x86_64.s"
21 .bss
22 .align 4
23//.globl rdram
24//rdram = 0x80000000
25 .section .rodata
26 .text
27.globl dyna_linker
28 .type dyna_linker, @function
29dyna_linker:
30 /* eax = virtual target address */
31 /* ebx = instruction to patch */
32 mov %eax, %edi
33 mov %eax, %ecx
34 shr $12, %edi
35 cmp $0xC0000000, %eax
36 cmovge tlb_LUT_r(,%edi,4), %ecx
37 test %ecx, %ecx
38 cmovz %eax, %ecx
39 xor $0x80000000, %ecx
40 mov $2047, %edx
41 shr $12, %ecx
42 and %ecx, %edx
43 or $2048, %edx
44 cmp %edx, %ecx
45 cmova %edx, %ecx
46 /* jump_in lookup */
47 movq jump_in(,%ecx,8), %r12
48.A1:
49 test %r12, %r12
50 je .A3
51 mov (%r12), %edi
52 xor %eax, %edi
53 or 4(%r12), %edi
54 je .A2
55 movq 16(%r12), %r12
56 jmp .A1
57.A2:
58 mov (%ebx), %edi
59 mov %esi, %ebp
60 lea 4(%ebx,%edi,1), %esi
61 mov %eax, %edi
62 call add_link
63 mov 8(%r12), %edi
64 mov %ebp, %esi
65 lea -4(%edi), %edx
66 subl %ebx, %edx
67 movl %edx, (%ebx)
68 jmp *%rdi
69.A3:
70 /* hash_table lookup */
71 mov %eax, %edi
72 mov %eax, %edx
73 shr $16, %edi
74 shr $12, %edx
75 xor %eax, %edi
76 and $2047, %edx
77 movzwl %di, %edi
78 shl $4, %edi
79 cmp $2048, %ecx
80 cmovc %edx, %ecx
81 cmp hash_table(%edi), %eax
82 jne .A5
83.A4:
84 mov hash_table+4(%edi), %edx
85 jmp *%rdx
86.A5:
87 cmp hash_table+8(%edi), %eax
88 lea 8(%edi), %edi
89 je .A4
90 /* jump_dirty lookup */
91 movq jump_dirty(,%ecx,8), %r12
92.A6:
93 test %r12, %r12
94 je .A8
95 mov (%r12), %ecx
96 xor %eax, %ecx
97 or 4(%r12), %ecx
98 je .A7
99 movq 16(%r12), %r12
100 jmp .A6
101.A7:
102 movl 8(%r12), %edx
103 /* hash_table insert */
104 mov hash_table-8(%edi), %ebx
105 mov hash_table-4(%edi), %ecx
106 mov %eax, hash_table-8(%edi)
107 mov %edx, hash_table-4(%edi)
108 mov %ebx, hash_table(%edi)
109 mov %ecx, hash_table+4(%edi)
110 jmp *%rdx
111.A8:
112 mov %eax, %edi
113 mov %eax, %ebp /* Note: assumes %rbx and %rbp are callee-saved */
114 mov %esi, %r12d
115 call new_recompile_block
116 test %eax, %eax
117 mov %ebp, %eax
118 mov %r12d, %esi
119 je dyna_linker
120 /* pagefault */
121 mov %eax, %ebx
122 mov $0x08, %ecx
123 .size dyna_linker, .-dyna_linker
124
125.globl exec_pagefault
126 .type exec_pagefault, @function
127exec_pagefault:
128 /* eax = instruction pointer */
129 /* ebx = fault address */
130 /* ecx = cause */
131 mov reg_cop0+48, %edx
132 mov reg_cop0+16, %edi
133 or $2, %edx
134 mov %ebx, reg_cop0+32 /* BadVAddr */
135 and $0xFF80000F, %edi
136 mov %edx, reg_cop0+48 /* Status */
137 mov %ecx, reg_cop0+52 /* Cause */
138 mov %eax, reg_cop0+56 /* EPC */
139 mov %ebx, %ecx
140 shr $9, %ebx
141 and $0xFFFFE000, %ecx
142 and $0x007FFFF0, %ebx
143 mov %ecx, reg_cop0+40 /* EntryHI */
144 or %ebx, %edi
145 mov %edi, reg_cop0+16 /* Context */
146 mov %esi, %ebx
147 mov $0x80000000, %edi
148 call get_addr_ht
149 mov %ebx, %esi
150 jmp *%rax
151 .size exec_pagefault, .-exec_pagefault
152
153/* Special dynamic linker for the case where a page fault
154 may occur in a branch delay slot */
155.globl dyna_linker_ds
156 .type dyna_linker_ds, @function
157dyna_linker_ds:
158 mov %eax, %edi
159 mov %eax, %ecx
160 shr $12, %edi
161 cmp $0xC0000000, %eax
162 cmovge tlb_LUT_r(,%edi,4), %ecx
163 test %ecx, %ecx
164 cmovz %eax, %ecx
165 xor $0x80000000, %ecx
166 mov $2047, %edx
167 shr $12, %ecx
168 and %ecx, %edx
169 or $2048, %edx
170 cmp %edx, %ecx
171 cmova %edx, %ecx
172 /* jump_in lookup */
173 movq jump_in(,%ecx,8), %r12
174.B1:
175 test %r12, %r12
176 je .B3
177 mov (%r12), %edi
178 xor %eax, %edi
179 or 4(%r12), %edi
180 je .B2
181 movq 16(%r12), %r12
182 jmp .B1
183.B2:
184 mov (%ebx), %edi
185 mov %esi, %r13d
186 lea 4(%ebx,%edi,1), %esi
187 mov %eax, %edi
188 call add_link
189 mov 8(%r12), %edi
190 mov %r13d, %esi
191 lea -4(%edi), %edx
192 subl %ebx, %edx
193 movl %edx, (%ebx)
194 jmp *%rdi
195.B3:
196 /* hash_table lookup */
197 mov %eax, %edi
198 mov %eax, %edx
199 shr $16, %edi
200 shr $12, %edx
201 xor %eax, %edi
202 and $2047, %edx
203 movzwl %di, %edi
204 shl $4, %edi
205 cmp $2048, %ecx
206 cmovc %edx, %ecx
207 cmp hash_table(%edi), %eax
208 jne .B5
209.B4:
210 mov hash_table+4(%edi), %edx
211 jmp *%rdx
212.B5:
213 cmp hash_table+8(%edi), %eax
214 lea 8(%edi), %edi
215 je .B4
216 /* jump_dirty lookup */
217 movq jump_dirty(,%ecx,8), %r12
218.B6:
219 test %r12, %r12
220 je .B8
221 mov (%r12), %ecx
222 xor %eax, %ecx
223 or 4(%r12), %ecx
224 je .B7
225 movq 16(%r12), %r12
226 jmp .B6
227.B7:
228 movl 8(%r12), %edx
229 /* hash_table insert */
230 mov hash_table-8(%edi), %ebx
231 mov hash_table-4(%edi), %ecx
232 mov %eax, hash_table-8(%edi)
233 mov %edx, hash_table-4(%edi)
234 mov %ebx, hash_table(%edi)
235 mov %ecx, hash_table+4(%edi)
236 jmp *%rdx
237.B8:
238 mov %eax, %edi
239 mov %eax, %r12d /* Note: assumes %rbx and %rbp are callee-saved */
240 and $0xFFFFFFF8, %edi
241 mov %esi, %r13d
242 inc %edi
243 call new_recompile_block
244 test %eax, %eax
245 mov %r12d, %eax
246 mov %r13d, %esi
247 je dyna_linker_ds
248 /* pagefault */
249 and $0xFFFFFFF8, %eax
250 mov $0x80000008, %ecx /* High bit set indicates pagefault in delay slot */
251 mov %eax, %ebx
252 sub $4, %eax
253 jmp exec_pagefault
254 .size dyna_linker_ds, .-dyna_linker_ds
255
256.globl jump_vaddr_eax
257 .type jump_vaddr_eax, @function
258jump_vaddr_eax:
259 mov %eax, %edi
260 jmp jump_vaddr_edi
261 .size jump_vaddr_eax, .-jump_vaddr_eax
262.globl jump_vaddr_ecx
263 .type jump_vaddr_ecx, @function
264jump_vaddr_ecx:
265 mov %ecx, %edi
266 jmp jump_vaddr_edi
267 .size jump_vaddr_ecx, .-jump_vaddr_ecx
268.globl jump_vaddr_edx
269 .type jump_vaddr_edx, @function
270jump_vaddr_edx:
271 mov %edx, %edi
272 jmp jump_vaddr_edi
273 .size jump_vaddr_edx, .-jump_vaddr_edx
274.globl jump_vaddr_ebx
275 .type jump_vaddr_ebx, @function
276jump_vaddr_ebx:
277 mov %ebx, %edi
278 jmp jump_vaddr_edi
279 .size jump_vaddr_ebx, .-jump_vaddr_ebx
280.globl jump_vaddr_ebp
281 .type jump_vaddr_ebp, @function
282jump_vaddr_ebp:
283 mov %ebp, %edi
284 .size jump_vaddr_ebp, .-jump_vaddr_ebp
285.globl jump_vaddr_edi
286 .type jump_vaddr_edi, @function
287jump_vaddr_edi:
288 mov %edi, %eax
289 .size jump_vaddr_edi, .-jump_vaddr_edi
290
291.globl jump_vaddr
292 .type jump_vaddr, @function
293jump_vaddr:
294 /* Check hash table */
295 shr $16, %eax
296 xor %edi, %eax
297 movzwl %ax, %eax
298 shl $4, %eax
299 cmp hash_table(%eax), %edi
300 jne .C2
301.C1:
302 mov hash_table+4(%eax), %edi
303 jmp *%rdi
304.C2:
305 cmp hash_table+8(%eax), %edi
306 lea 8(%eax), %eax
307 je .C1
308 /* No hit on hash table, call compiler */
309 mov %esi, cycle_count /* CCREG */
310 call get_addr
311 mov cycle_count, %esi
312 jmp *%rax
313 .size jump_vaddr, .-jump_vaddr
314
315.globl verify_code_ds
316 .type verify_code_ds, @function
317verify_code_ds:
318 nop
319 .size verify_code_ds, .-verify_code_ds
320
321.globl verify_code_vm
322 .type verify_code_vm, @function
323verify_code_vm:
324 /* eax = source (virtual address) */
325 /* ebx = target */
326 /* ecx = length */
327 cmp $0xC0000000, %eax
328 jl verify_code
329 mov %eax, %edx
330 lea -1(%eax,%ecx,1), %r9d
331 shr $12, %edx
332 shr $12, %r9d
333 mov memory_map(,%edx,4), %edi
334 test %edi, %edi
335 js .D4
336 lea (%eax,%edi,4), %eax
337 mov %edi, %r8d
338.D1:
339 xor memory_map(,%edx,4), %edi
340 shl $2, %edi
341 jne .D4
342 mov %r8d, %edi
343 inc %edx
344 cmp %r9d, %edx
345 jbe .D1
346 .size verify_code_vm, .-verify_code_vm
347
348.globl verify_code
349 .type verify_code, @function
350verify_code:
351 /* eax = source */
352 /* ebx = target */
353 /* ecx = length */
354 /* r12d = instruction pointer */
355 mov -4(%eax,%ecx,1), %edi
356 xor -4(%ebx,%ecx,1), %edi
357 jne .D4
358 mov %ecx, %edx
359 add $-4, %ecx
360 je .D3
361 test $4, %edx
362 cmove %edx, %ecx
363.D2:
364 mov -8(%eax,%ecx,1), %rdi
365 cmp -8(%ebx,%ecx,1), %rdi
366 jne .D4
367 add $-8, %ecx
368 jne .D2
369.D3:
370 ret
371.D4:
372 add $8, %rsp /* pop return address, we're not returning */
373 mov %r12d, %edi
374 mov %esi, %ebx
375 call get_addr
376 mov %ebx, %esi
377 jmp *%rax
378 .size verify_code, .-verify_code
379
380.globl cc_interrupt
381 .type cc_interrupt, @function
382cc_interrupt:
383 add last_count, %esi
384 add $-8, %rsp /* Align stack */
385 mov %esi, reg_cop0+36 /* Count */
386 shr $19, %esi
387 movl $0, pending_exception
388 and $0x7f, %esi
389 cmpl $0, restore_candidate(,%esi,4)
390 jne .E4
391.E1:
392 call gen_interupt
393 mov reg_cop0+36, %esi
394 mov next_interupt, %eax
395 mov pending_exception, %ebx
396 mov stop, %ecx
397 add $8, %rsp
398 mov %eax, last_count
399 sub %eax, %esi
400 test %ecx, %ecx
401 jne .E3
402 test %ebx, %ebx
403 jne .E2
404 ret
405.E2:
406 mov pcaddr, %edi
407 mov %esi, cycle_count /* CCREG */
408 call get_addr_ht
409 mov cycle_count, %esi
410 add $8, %rsp /* pop return address */
411 jmp *%rax
412.E3:
413 pop %rbp /* pop return address and discard it */
414 pop %rbp /* pop junk */
415 pop %r15 /* restore callee-save registers */
416 pop %r14
417 pop %r13
418 pop %r12
419 pop %rbx
420 pop %rbp
421 ret /* exit dynarec */
422.E4:
423 /* Move 'dirty' blocks to the 'clean' list */
424 mov restore_candidate(,%esi,4), %ebx
425 mov %esi, %ebp
426 movl $0, restore_candidate(,%esi,4)
427 shl $5, %ebp
428.E5:
429 shr $1, %ebx
430 jnc .E6
431 mov %ebp, %edi
432 call clean_blocks
433.E6:
434 inc %ebp
435 test $31, %ebp
436 jne .E5
437 jmp .E1
438 .size cc_interrupt, .-cc_interrupt
439
440.globl do_interrupt
441 .type do_interrupt, @function
442do_interrupt:
443 mov pcaddr, %edi
444 call get_addr_ht
445 mov reg_cop0+36, %esi
446 mov next_interupt, %ebx
447 mov %ebx, last_count
448 sub %ebx, %esi
449 add $2, %esi
450 jmp *%rax
451 .size do_interrupt, .-do_interrupt
452
453.globl fp_exception
454 .type fp_exception, @function
455fp_exception:
456 mov $0x1000002c, %edx
457.E7:
458 mov reg_cop0+48, %ebx
459 or $2, %ebx
460 mov %ebx, reg_cop0+48 /* Status */
461 mov %edx, reg_cop0+52 /* Cause */
462 mov %eax, reg_cop0+56 /* EPC */
463 mov %esi, %ebx
464 mov $0x80000180, %edi
465 call get_addr_ht
466 mov %ebx, %esi
467 jmp *%rax
468 .size fp_exception, .-fp_exception
469
470.globl fp_exception_ds
471 .type fp_exception_ds, @function
472fp_exception_ds:
473 mov $0x9000002c, %edx /* Set high bit if delay slot */
474 jmp .E7
475 .size fp_exception_ds, .-fp_exception_ds
476
477.globl jump_syscall
478 .type jump_syscall, @function
479jump_syscall:
480 mov $0x20, %edx
481 mov reg_cop0+48, %ebx
482 or $2, %ebx
483 mov %ebx, reg_cop0+48 /* Status */
484 mov %edx, reg_cop0+52 /* Cause */
485 mov %eax, reg_cop0+56 /* EPC */
486 mov %esi, %ebx
487 mov $0x80000180, %edi
488 call get_addr_ht
489 mov %ebx, %esi
490 jmp *%rax
491 .size jump_syscall, .-jump_syscall
492
493.globl jump_eret
494 .type jump_eret, @function
495jump_eret:
496 mov reg_cop0+48, %ebx /* Status */
497 add last_count, %esi
498 and $0xFFFFFFFD, %ebx
499 mov %esi, reg_cop0+36 /* Count */
500 mov %ebx, reg_cop0+48 /* Status */
501 call check_interupt
502 mov next_interupt, %eax
503 mov reg_cop0+36, %esi
504 mov %eax, last_count
505 sub %eax, %esi
506 mov reg_cop0+56, %edi /* EPC */
507 jns .E11
508.E8:
509 mov %esi, %r12d
510 mov $248, %ebx
511 xor %esi, %esi
512.E9:
513 mov reg(%ebx), %ecx
514 mov reg+4(%ebx), %edx
515 sar $31, %ecx
516 xor %ecx, %edx
517 neg %edx
518 adc %esi, %esi
519 sub $8, %ebx
520 jne .E9
521 mov hi(%ebx), %ecx
522 mov hi+4(%ebx), %edx
523 sar $31, %ecx
524 xor %ecx, %edx
525 jne .E10
526 mov lo(%ebx), %ecx
527 mov lo+4(%ebx), %edx
528 sar $31, %ecx
529 xor %ecx, %edx
530.E10:
531 neg %edx
532 adc %esi, %esi
533 call get_addr_32
534 mov %r12d, %esi
535 jmp *%rax
536.E11:
537 mov %edi, pcaddr
538 call cc_interrupt
539 mov pcaddr, %edi
540 jmp .E8
541 .size jump_eret, .-jump_eret
542
543.globl new_dyna_start
544 .type new_dyna_start, @function
545new_dyna_start:
546 push %rbp
547 push %rbx
548 push %r12
549 push %r13
550 push %r14
551 push %r15
552 mov $0xa4000040, %edi
553 call new_recompile_block
554 add $-8, %rsp /* align stack */
555 movl next_interupt, %edi
556 movl reg_cop0+36, %esi
557 movl %edi, last_count
558 subl %edi, %esi
559 jmp 0x70000000
560 .size new_dyna_start, .-new_dyna_start
561
562.globl write_rdram_new
563 .type write_rdram_new, @function
564write_rdram_new:
565 mov address, %edi
566 mov word, %ecx
567 and $0x7FFFFFFF, %edi
568 mov %ecx, rdram(%rdi)
569 jmp .E12
570 .size write_rdram_new, .-write_rdram_new
571
572.globl write_rdramb_new
573 .type write_rdramb_new, @function
574write_rdramb_new:
575 mov address, %edi
576 xor $3, %edi
577 movb byte, %cl
578 and $0x7FFFFFFF, %edi
579 movb %cl, rdram(%rdi)
580 jmp .E12
581 .size write_rdramb_new, .-write_rdramb_new
582
583.globl write_rdramh_new
584 .type write_rdramh_new, @function
585write_rdramh_new:
586 mov address, %edi
587 xor $2, %edi
588 movw hword, %cx
589 and $0x7FFFFFFF, %edi
590 movw %cx, rdram(%rdi)
591 jmp .E12
592 .size write_rdramh_new, .-write_rdramh_new
593
594.globl write_rdramd_new
595 .type write_rdramd_new, @function
596write_rdramd_new:
597 mov address, %edi
598 mov dword+4, %ecx
599 mov dword, %edx
600 and $0x7FFFFFFF, %edi
601 mov %ecx, rdram(%rdi)
602 mov %edx, rdram+4(%rdi)
603 jmp .E12
604 .size write_rdramd_new, .-write_rdramd_new
605
606.globl do_invalidate
607 .type do_invalidate, @function
608do_invalidate:
609 mov address, %edi
610 mov %edi, %ebx /* Return ebx to caller */
611.E12:
612 shr $12, %edi
613 mov %edi, %r12d /* Return r12 to caller */
614 cmpb $1, invalid_code(%edi)
615 je .E13
616 call invalidate_block
617.E13:
618 ret
619 .size do_invalidate, .-do_invalidate
620
621.globl read_nomem_new
622 .type read_nomem_new, @function
623read_nomem_new:
624 mov address, %edi
625 mov %edi, %ebx
626 shr $12, %edi
627 mov memory_map(,%edi,4),%edi
628 mov $0x8, %eax
629 test %edi, %edi
630 js tlb_exception
631 mov (%ebx,%edi,4), %ecx
632 mov %ecx, readmem_dword
633 ret
634 .size read_nomem_new, .-read_nomem_new
635
636.globl read_nomemb_new
637 .type read_nomemb_new, @function
638read_nomemb_new:
639 mov address, %edi
640 mov %edi, %ebx
641 shr $12, %edi
642 mov memory_map(,%edi,4),%edi
643 mov $0x8, %eax
644 test %edi, %edi
645 js tlb_exception
646 xor $3, %ebx
647 movzbl (%ebx,%edi,4), %ecx
648 mov %ecx, readmem_dword
649 ret
650 .size read_nomemb_new, .-read_nomemb_new
651
652.globl read_nomemh_new
653 .type read_nomemh_new, @function
654read_nomemh_new:
655 mov address, %edi
656 mov %edi, %ebx
657 shr $12, %edi
658 mov memory_map(,%edi,4),%edi
659 mov $0x8, %eax
660 test %edi, %edi
661 js tlb_exception
662 xor $2, %ebx
663 movzwl (%ebx,%edi,4), %ecx
664 mov %ecx, readmem_dword
665 ret
666 .size read_nomemh_new, .-read_nomemh_new
667
668.globl read_nomemd_new
669 .type read_nomemd_new, @function
670read_nomemd_new:
671 mov address, %edi
672 mov %edi, %ebx
673 shr $12, %edi
674 mov memory_map(,%edi,4),%edi
675 mov $0x8, %eax
676 test %edi, %edi
677 js tlb_exception
678 mov 4(%ebx,%edi,4), %ecx
679 mov (%ebx,%edi,4), %edx
680 mov %ecx, readmem_dword
681 mov %edx, readmem_dword+4
682 ret
683 .size read_nomemd_new, .-read_nomemd_new
684
685.globl write_nomem_new
686 .type write_nomem_new, @function
687write_nomem_new:
688 call do_invalidate
689 mov memory_map(,%r12d,4),%edi
690 mov word, %ecx
691 mov $0xc, %eax
692 shl $2, %edi
693 jc tlb_exception
694 mov %ecx, (%ebx,%edi)
695 ret
696 .size write_nomem_new, .-write_nomem_new
697
698.globl write_nomemb_new
699 .type write_nomemb_new, @function
700write_nomemb_new:
701 call do_invalidate
702 mov memory_map(,%r12d,4),%edi
703 movb byte, %cl
704 mov $0xc, %eax
705 shl $2, %edi
706 jc tlb_exception
707 xor $3, %ebx
708 movb %cl, (%ebx,%edi)
709 ret
710 .size write_nomemb_new, .-write_nomemb_new
711
712.globl write_nomemh_new
713 .type write_nomemh_new, @function
714write_nomemh_new:
715 call do_invalidate
716 mov memory_map(,%r12d,4),%edi
717 movw hword, %cx
718 mov $0xc, %eax
719 shl $2, %edi
720 jc tlb_exception
721 xor $2, %ebx
722 movw %cx, (%ebx,%edi)
723 ret
724 .size write_nomemh_new, .-write_nomemh_new
725
726.globl write_nomemd_new
727 .type write_nomemd_new, @function
728write_nomemd_new:
729 call do_invalidate
730 mov memory_map(,%r12d,4),%edi
731 mov dword+4, %edx
732 mov dword, %ecx
733 mov $0xc, %eax
734 shl $2, %edi
735 jc tlb_exception
736 mov %edx, (%ebx,%edi)
737 mov %ecx, 4(%ebx,%edi)
738 ret
739 .size write_nomemd_new, .-write_nomemd_new
740
741.globl tlb_exception
742 .type tlb_exception, @function
743tlb_exception:
744 /* eax = cause */
745 /* ebx = address */
746 /* ebp = instr addr + flags */
747 mov 8(%rsp), %ebp
748 mov reg_cop0+48, %esi
749 mov %ebp, %ecx
750 mov %ebp, %edx
751 mov %ebp, %edi
752 shl $31, %ebp
753 shr $12, %ecx
754 or %ebp, %eax
755 sar $29, %ebp
756 and $0xFFFFFFFC, %edx
757 mov memory_map(,%ecx,4), %ecx
758 or $2, %esi
759 mov (%edx, %ecx, 4), %ecx
760 add %ebp, %edx
761 mov %esi, reg_cop0+48 /* Status */
762 mov %eax, reg_cop0+52 /* Cause */
763 mov %edx, reg_cop0+56 /* EPC */
764 add $0x48, %rsp
765 mov $0x6000022, %edx
766 mov %ecx, %ebp
767 movswl %cx, %eax
768 shr $26, %ecx
769 shr $21, %ebp
770 sub %eax, %ebx
771 and $0x1f, %ebp
772 ror %cl, %edx
773 mov reg_cop0+16, %esi
774 cmovc reg(,%ebp,8), %ebx
775 and $0xFF80000F, %esi
776 mov %ebx, reg(,%ebp,8)
777 add %ebx, %eax
778 sar $31, %ebx
779 mov %eax, reg_cop0+32 /* BadVAddr */
780 shr $9, %eax
781 test $2, %edi
782 cmove reg+4(,%ebp,8), %ebx
783 and $0x007FFFF0, %eax
784 mov $0x80000180, %edi
785 mov %ebx, reg+4(,%ebp,8)
786 or %eax, %esi
787 mov %esi, reg_cop0+16 /* Context */
788 call get_addr_ht
789 movl next_interupt, %edi
790 movl reg_cop0+36, %esi /* Count */
791 movl %edi, last_count
792 subl %edi, %esi
793 jmp *%rax
794 .size tlb_exception, .-tlb_exception