1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - gspecial.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2007 Richard Goedeken (Richard42) *
5 * Copyright (C) 2002 Hacktarux *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
21 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
26 #include "interpret.h"
28 #include "r4300/recomph.h"
29 #include "r4300/recomp.h"
30 #include "r4300/r4300.h"
31 #include "r4300/ops.h"
32 #include "r4300/macros.h"
33 #include "r4300/exception.h"
35 #if !defined(offsetof)
36 # define offsetof(TYPE,MEMBER) ((unsigned int) &((TYPE*)0)->MEMBER)
41 #if defined(COUNT_INSTR)
42 inc_m32rel(&instr_count[55]);
45 gencallinterp((unsigned long long)cached_interpreter_table.SLL, 0);
47 int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
48 int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);
50 mov_reg32_reg32(rd, rt);
51 shl_reg32_imm8(rd, dst->f.r.sa);
57 #if defined(COUNT_INSTR)
58 inc_m32rel(&instr_count[56]);
61 gencallinterp((unsigned long long)cached_interpreter_table.SRL, 0);
63 int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
64 int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);
66 mov_reg32_reg32(rd, rt);
67 shr_reg32_imm8(rd, dst->f.r.sa);
73 #if defined(COUNT_INSTR)
74 inc_m32rel(&instr_count[57]);
77 gencallinterp((unsigned long long)cached_interpreter_table.SRA, 0);
79 int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
80 int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);
82 mov_reg32_reg32(rd, rt);
83 sar_reg32_imm8(rd, dst->f.r.sa);
89 #if defined(COUNT_INSTR)
90 inc_m32rel(&instr_count[58]);
93 gencallinterp((unsigned long long)cached_interpreter_table.SLLV, 0);
96 allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs);
98 rt = allocate_register_32((unsigned int *)dst->f.r.rt);
99 rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);
103 mov_reg32_reg32(rd, rt);
108 int temp = lru_register();
110 mov_reg32_reg32(temp, rt);
112 mov_reg32_reg32(rd, temp);
119 #if defined(COUNT_INSTR)
120 inc_m32rel(&instr_count[59]);
122 #ifdef INTERPRET_SRLV
123 gencallinterp((unsigned long long)cached_interpreter_table.SRLV, 0);
126 allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs);
128 rt = allocate_register_32((unsigned int *)dst->f.r.rt);
129 rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);
133 mov_reg32_reg32(rd, rt);
138 int temp = lru_register();
140 mov_reg32_reg32(temp, rt);
142 mov_reg32_reg32(rd, temp);
149 #if defined(COUNT_INSTR)
150 inc_m32rel(&instr_count[60]);
152 #ifdef INTERPRET_SRAV
153 gencallinterp((unsigned long long)cached_interpreter_table.SRAV, 0);
156 allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs);
158 rt = allocate_register_32((unsigned int *)dst->f.r.rt);
159 rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);
163 mov_reg32_reg32(rd, rt);
168 int temp = lru_register();
170 mov_reg32_reg32(temp, rt);
172 mov_reg32_reg32(rd, temp);
179 #if defined(COUNT_INSTR)
180 inc_m32rel(&instr_count[61]);
183 gencallinterp((unsigned long long)cached_interpreter_table.JR, 1);
185 static unsigned int precomp_instr_size = sizeof(precomp_instr);
186 unsigned int diff = (unsigned int) offsetof(precomp_instr, local_addr);
187 unsigned int diff_need = (unsigned int) offsetof(precomp_instr, reg_cache_infos.need_map);
188 unsigned int diff_wrap = (unsigned int) offsetof(precomp_instr, reg_cache_infos.jump_wrapper);
190 if (((dst->addr & 0xFFF) == 0xFFC &&
191 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
193 gencallinterp((unsigned long long)cached_interpreter_table.JR, 1);
197 free_registers_move_start();
199 mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.i.rs);
200 mov_m32rel_xreg32((unsigned int *)&local_rs, EAX);
204 mov_xreg32_m32rel(EAX, (unsigned int *)&local_rs);
205 mov_m32rel_xreg32((unsigned int *)&last_addr, EAX);
207 gencheck_interupt_reg();
209 mov_xreg32_m32rel(EAX, (unsigned int *)&local_rs);
210 mov_reg32_reg32(EBX, EAX);
211 and_eax_imm32(0xFFFFF000);
212 cmp_eax_imm32(dst_block->start & 0xFFFFF000);
217 mov_m32rel_xreg32(&jump_to_address, EBX);
218 mov_reg64_imm64(RAX, (unsigned long long) (dst+1));
219 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
220 mov_reg64_imm64(RAX, (unsigned long long) jump_to_func);
221 call_reg64(RAX); /* will never return from call */
225 mov_reg64_imm64(RSI, (unsigned long long) dst_block->block);
226 mov_reg32_reg32(EAX, EBX);
227 sub_eax_imm32(dst_block->start);
228 shr_reg32_imm8(EAX, 2);
229 mul_m32rel((unsigned int *)(&precomp_instr_size));
231 mov_reg32_preg64preg64pimm32(EBX, RAX, RSI, diff_need);
232 cmp_reg32_imm32(EBX, 1);
235 add_reg32_imm32(EAX, diff_wrap); // 6
236 add_reg64_reg64(RAX, RSI); // 3
239 mov_reg32_preg64preg64pimm32(EBX, RAX, RSI, diff);
240 mov_rax_memoffs64((unsigned long long *) &dst_block->code);
241 add_reg64_reg64(RAX, RBX);
248 #if defined(COUNT_INSTR)
249 inc_m32rel(&instr_count[62]);
251 #ifdef INTERPRET_JALR
252 gencallinterp((unsigned long long)cached_interpreter_table.JALR, 0);
254 static unsigned int precomp_instr_size = sizeof(precomp_instr);
255 unsigned int diff = (unsigned int) offsetof(precomp_instr, local_addr);
256 unsigned int diff_need = (unsigned int) offsetof(precomp_instr, reg_cache_infos.need_map);
257 unsigned int diff_wrap = (unsigned int) offsetof(precomp_instr, reg_cache_infos.jump_wrapper);
259 if (((dst->addr & 0xFFF) == 0xFFC &&
260 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
262 gencallinterp((unsigned long long)cached_interpreter_table.JALR, 1);
266 free_registers_move_start();
268 mov_xreg32_m32rel(EAX, (unsigned int *)dst->f.r.rs);
269 mov_m32rel_xreg32((unsigned int *)&local_rs, EAX);
273 mov_m32rel_imm32((unsigned int *)(dst-1)->f.r.rd, dst->addr+4);
274 if ((dst->addr+4) & 0x80000000)
275 mov_m32rel_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0xFFFFFFFF);
277 mov_m32rel_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0);
279 mov_xreg32_m32rel(EAX, (unsigned int *)&local_rs);
280 mov_m32rel_xreg32((unsigned int *)&last_addr, EAX);
282 gencheck_interupt_reg();
284 mov_xreg32_m32rel(EAX, (unsigned int *)&local_rs);
285 mov_reg32_reg32(EBX, EAX);
286 and_eax_imm32(0xFFFFF000);
287 cmp_eax_imm32(dst_block->start & 0xFFFFF000);
292 mov_m32rel_xreg32(&jump_to_address, EBX);
293 mov_reg64_imm64(RAX, (unsigned long long) (dst+1));
294 mov_m64rel_xreg64((unsigned long long *)(&PC), RAX);
295 mov_reg64_imm64(RAX, (unsigned long long) jump_to_func);
296 call_reg64(RAX); /* will never return from call */
300 mov_reg64_imm64(RSI, (unsigned long long) dst_block->block);
301 mov_reg32_reg32(EAX, EBX);
302 sub_eax_imm32(dst_block->start);
303 shr_reg32_imm8(EAX, 2);
304 mul_m32rel((unsigned int *)(&precomp_instr_size));
306 mov_reg32_preg64preg64pimm32(EBX, RAX, RSI, diff_need);
307 cmp_reg32_imm32(EBX, 1);
310 add_reg32_imm32(EAX, diff_wrap); // 6
311 add_reg64_reg64(RAX, RSI); // 3
314 mov_reg32_preg64preg64pimm32(EBX, RAX, RSI, diff);
315 mov_rax_memoffs64((unsigned long long *) &dst_block->code);
316 add_reg64_reg64(RAX, RBX);
321 void gensyscall(void)
323 #if defined(COUNT_INSTR)
324 inc_m32rel(&instr_count[63]);
326 #ifdef INTERPRET_SYSCALL
327 gencallinterp((unsigned long long)cached_interpreter_table.SYSCALL, 0);
329 free_registers_move_start();
331 mov_m32rel_imm32(&Cause, 8 << 2);
332 gencallinterp((unsigned long long)exception_general, 0);
342 #if defined(COUNT_INSTR)
343 inc_m32rel(&instr_count[64]);
345 #ifdef INTERPRET_MFHI
346 gencallinterp((unsigned long long)cached_interpreter_table.MFHI, 0);
348 int rd = allocate_register_64_w((unsigned long long *) dst->f.r.rd);
349 int _hi = allocate_register_64((unsigned long long *) &hi);
351 mov_reg64_reg64(rd, _hi);
357 #if defined(COUNT_INSTR)
358 inc_m32rel(&instr_count[65]);
360 #ifdef INTERPRET_MTHI
361 gencallinterp((unsigned long long)cached_interpreter_table.MTHI, 0);
363 int _hi = allocate_register_64_w((unsigned long long *) &hi);
364 int rs = allocate_register_64((unsigned long long *) dst->f.r.rs);
366 mov_reg64_reg64(_hi, rs);
372 #if defined(COUNT_INSTR)
373 inc_m32rel(&instr_count[66]);
375 #ifdef INTERPRET_MFLO
376 gencallinterp((unsigned long long)cached_interpreter_table.MFLO, 0);
378 int rd = allocate_register_64_w((unsigned long long *) dst->f.r.rd);
379 int _lo = allocate_register_64((unsigned long long *) &lo);
381 mov_reg64_reg64(rd, _lo);
387 #if defined(COUNT_INSTR)
388 inc_m32rel(&instr_count[67]);
390 #ifdef INTERPRET_MTLO
391 gencallinterp((unsigned long long)cached_interpreter_table.MTLO, 0);
393 int _lo = allocate_register_64_w((unsigned long long *)&lo);
394 int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
396 mov_reg64_reg64(_lo, rs);
402 #if defined(COUNT_INSTR)
403 inc_m32rel(&instr_count[68]);
405 #ifdef INTERPRET_DSLLV
406 gencallinterp((unsigned long long)cached_interpreter_table.DSLLV, 0);
409 allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs);
411 rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
412 rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
416 mov_reg64_reg64(rd, rt);
422 temp = lru_register();
425 mov_reg64_reg64(temp, rt);
427 mov_reg64_reg64(rd, temp);
434 #if defined(COUNT_INSTR)
435 inc_m32rel(&instr_count[69]);
437 #ifdef INTERPRET_DSRLV
438 gencallinterp((unsigned long long)cached_interpreter_table.DSRLV, 0);
441 allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs);
443 rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
444 rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
448 mov_reg64_reg64(rd, rt);
454 temp = lru_register();
457 mov_reg64_reg64(temp, rt);
459 mov_reg64_reg64(rd, temp);
466 #if defined(COUNT_INSTR)
467 inc_m32rel(&instr_count[70]);
469 #ifdef INTERPRET_DSRAV
470 gencallinterp((unsigned long long)cached_interpreter_table.DSRAV, 0);
473 allocate_register_32_manually(ECX, (unsigned int *)dst->f.r.rs);
475 rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
476 rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
480 mov_reg64_reg64(rd, rt);
486 temp = lru_register();
489 mov_reg64_reg64(temp, rt);
491 mov_reg64_reg64(rd, temp);
498 #if defined(COUNT_INSTR)
499 inc_m32rel(&instr_count[71]);
501 #ifdef INTERPRET_MULT
502 gencallinterp((unsigned long long)cached_interpreter_table.MULT, 0);
505 allocate_register_32_manually_w(EAX, (unsigned int *)&lo); /* these must be done first so they are not assigned by allocate_register() */
506 allocate_register_32_manually_w(EDX, (unsigned int *)&hi);
507 rs = allocate_register_32((unsigned int*)dst->f.r.rs);
508 rt = allocate_register_32((unsigned int*)dst->f.r.rt);
509 mov_reg32_reg32(EAX, rs);
516 #if defined(COUNT_INSTR)
517 inc_m32rel(&instr_count[72]);
519 #ifdef INTERPRET_MULTU
520 gencallinterp((unsigned long long)cached_interpreter_table.MULTU, 0);
523 allocate_register_32_manually_w(EAX, (unsigned int *)&lo);
524 allocate_register_32_manually_w(EDX, (unsigned int *)&hi);
525 rs = allocate_register_32((unsigned int*)dst->f.r.rs);
526 rt = allocate_register_32((unsigned int*)dst->f.r.rt);
527 mov_reg32_reg32(EAX, rs);
534 #if defined(COUNT_INSTR)
535 inc_m32rel(&instr_count[73]);
538 gencallinterp((unsigned long long)cached_interpreter_table.DIV, 0);
541 allocate_register_32_manually_w(EAX, (unsigned int *)&lo);
542 allocate_register_32_manually_w(EDX, (unsigned int *)&hi);
543 rs = allocate_register_32((unsigned int*)dst->f.r.rs);
544 rt = allocate_register_32((unsigned int*)dst->f.r.rt);
545 cmp_reg32_imm32(rt, 0);
546 je_rj((rs == EAX ? 0 : 2) + 1 + 2);
547 mov_reg32_reg32(EAX, rs); // 0 or 2
555 #if defined(COUNT_INSTR)
556 inc_m32rel(&instr_count[74]);
558 #ifdef INTERPRET_DIVU
559 gencallinterp((unsigned long long)cached_interpreter_table.DIVU, 0);
562 allocate_register_32_manually_w(EAX, (unsigned int *)&lo);
563 allocate_register_32_manually_w(EDX, (unsigned int *)&hi);
564 rs = allocate_register_32((unsigned int*)dst->f.r.rs);
565 rt = allocate_register_32((unsigned int*)dst->f.r.rt);
566 cmp_reg32_imm32(rt, 0);
567 je_rj((rs == EAX ? 0 : 2) + 2 + 2);
568 mov_reg32_reg32(EAX, rs); // 0 or 2
569 xor_reg32_reg32(EDX, EDX); // 2
576 #if defined(COUNT_INSTR)
577 inc_m32rel(&instr_count[75]);
579 gencallinterp((unsigned long long)cached_interpreter_table.DMULT, 0);
584 #if defined(COUNT_INSTR)
585 inc_m32rel(&instr_count[76]);
587 #ifdef INTERPRET_DMULTU
588 gencallinterp((unsigned long long)cached_interpreter_table.DMULTU, 0);
590 free_registers_move_start();
592 mov_xreg64_m64rel(RAX, (unsigned long long *) dst->f.r.rs);
593 mov_xreg64_m64rel(RDX, (unsigned long long *) dst->f.r.rt);
595 mov_m64rel_xreg64((unsigned long long *) &lo, RAX);
596 mov_m64rel_xreg64((unsigned long long *) &hi, RDX);
602 #if defined(COUNT_INSTR)
603 inc_m32rel(&instr_count[77]);
605 gencallinterp((unsigned long long)cached_interpreter_table.DDIV, 0);
610 #if defined(COUNT_INSTR)
611 inc_m32rel(&instr_count[78]);
613 gencallinterp((unsigned long long)cached_interpreter_table.DDIVU, 0);
618 #if defined(COUNT_INSTR)
619 inc_m32rel(&instr_count[79]);
622 gencallinterp((unsigned long long)cached_interpreter_table.ADD, 0);
624 int rs = allocate_register_32((unsigned int *)dst->f.r.rs);
625 int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
626 int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);
629 add_reg32_reg32(rd, rt);
631 add_reg32_reg32(rd, rs);
634 mov_reg32_reg32(rd, rs);
635 add_reg32_reg32(rd, rt);
642 #if defined(COUNT_INSTR)
643 inc_m32rel(&instr_count[80]);
645 #ifdef INTERPRET_ADDU
646 gencallinterp((unsigned long long)cached_interpreter_table.ADDU, 0);
648 int rs = allocate_register_32((unsigned int *)dst->f.r.rs);
649 int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
650 int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);
653 add_reg32_reg32(rd, rt);
655 add_reg32_reg32(rd, rs);
658 mov_reg32_reg32(rd, rs);
659 add_reg32_reg32(rd, rt);
666 #if defined(COUNT_INSTR)
667 inc_m32rel(&instr_count[81]);
670 gencallinterp((unsigned long long)cached_interpreter_table.SUB, 0);
672 int rs = allocate_register_32((unsigned int *)dst->f.r.rs);
673 int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
674 int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);
677 sub_reg32_reg32(rd, rt);
681 add_reg32_reg32(rd, rs);
685 mov_reg32_reg32(rd, rs);
686 sub_reg32_reg32(rd, rt);
693 #if defined(COUNT_INSTR)
694 inc_m32rel(&instr_count[82]);
696 #ifdef INTERPRET_SUBU
697 gencallinterp((unsigned long long)cached_interpreter_table.SUBU, 0);
699 int rs = allocate_register_32((unsigned int *)dst->f.r.rs);
700 int rt = allocate_register_32((unsigned int *)dst->f.r.rt);
701 int rd = allocate_register_32_w((unsigned int *)dst->f.r.rd);
704 sub_reg32_reg32(rd, rt);
708 add_reg32_reg32(rd, rs);
712 mov_reg32_reg32(rd, rs);
713 sub_reg32_reg32(rd, rt);
720 #if defined(COUNT_INSTR)
721 inc_m32rel(&instr_count[83]);
724 gencallinterp((unsigned long long)cached_interpreter_table.AND, 0);
726 int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
727 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
728 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
731 and_reg64_reg64(rd, rt);
733 and_reg64_reg64(rd, rs);
736 mov_reg64_reg64(rd, rs);
737 and_reg64_reg64(rd, rt);
744 #if defined(COUNT_INSTR)
745 inc_m32rel(&instr_count[84]);
748 gencallinterp((unsigned long long)cached_interpreter_table.OR, 0);
750 int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
751 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
752 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
755 or_reg64_reg64(rd, rt);
757 or_reg64_reg64(rd, rs);
760 mov_reg64_reg64(rd, rs);
761 or_reg64_reg64(rd, rt);
768 #if defined(COUNT_INSTR)
769 inc_m32rel(&instr_count[85]);
772 gencallinterp((unsigned long long)cached_interpreter_table.XOR, 0);
774 int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
775 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
776 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
779 xor_reg64_reg64(rd, rt);
781 xor_reg64_reg64(rd, rs);
784 mov_reg64_reg64(rd, rs);
785 xor_reg64_reg64(rd, rt);
792 #if defined(COUNT_INSTR)
793 inc_m32rel(&instr_count[86]);
796 gencallinterp((unsigned long long)cached_interpreter_table.NOR, 0);
798 int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
799 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
800 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
804 or_reg64_reg64(rd, rt);
809 or_reg64_reg64(rd, rs);
814 mov_reg64_reg64(rd, rs);
815 or_reg64_reg64(rd, rt);
823 #if defined(COUNT_INSTR)
824 inc_m32rel(&instr_count[87]);
827 gencallinterp((unsigned long long)cached_interpreter_table.SLT, 0);
829 int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
830 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
831 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
833 cmp_reg64_reg64(rs, rt);
835 and_reg64_imm8(rd, 1);
841 #if defined(COUNT_INSTR)
842 inc_m32rel(&instr_count[88]);
844 #ifdef INTERPRET_SLTU
845 gencallinterp((unsigned long long)cached_interpreter_table.SLTU, 0);
847 int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
848 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
849 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
851 cmp_reg64_reg64(rs, rt);
853 and_reg64_imm8(rd, 1);
859 #if defined(COUNT_INSTR)
860 inc_m32rel(&instr_count[89]);
862 #ifdef INTERPRET_DADD
863 gencallinterp((unsigned long long)cached_interpreter_table.DADD, 0);
865 int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
866 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
867 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
870 add_reg64_reg64(rd, rt);
872 add_reg64_reg64(rd, rs);
875 mov_reg64_reg64(rd, rs);
876 add_reg64_reg64(rd, rt);
883 #if defined(COUNT_INSTR)
884 inc_m32rel(&instr_count[90]);
886 #ifdef INTERPRET_DADDU
887 gencallinterp((unsigned long long)cached_interpreter_table.DADDU, 0);
889 int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
890 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
891 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
894 add_reg64_reg64(rd, rt);
896 add_reg64_reg64(rd, rs);
899 mov_reg64_reg64(rd, rs);
900 add_reg64_reg64(rd, rt);
907 #if defined(COUNT_INSTR)
908 inc_m32rel(&instr_count[91]);
910 #ifdef INTERPRET_DSUB
911 gencallinterp((unsigned long long)cached_interpreter_table.DSUB, 0);
913 int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
914 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
915 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
918 sub_reg64_reg64(rd, rt);
922 add_reg64_reg64(rd, rs);
926 mov_reg64_reg64(rd, rs);
927 sub_reg64_reg64(rd, rt);
934 #if defined(COUNT_INSTR)
935 inc_m32rel(&instr_count[92]);
937 #ifdef INTERPRET_DSUBU
938 gencallinterp((unsigned long long)cached_interpreter_table.DSUBU, 0);
940 int rs = allocate_register_64((unsigned long long *)dst->f.r.rs);
941 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
942 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
945 sub_reg64_reg64(rd, rt);
949 add_reg64_reg64(rd, rs);
953 mov_reg64_reg64(rd, rs);
954 sub_reg64_reg64(rd, rt);
961 #if defined(COUNT_INSTR)
962 inc_m32rel(&instr_count[96]);
964 gencallinterp((unsigned long long)cached_interpreter_table.TEQ, 0);
969 #if defined(COUNT_INSTR)
970 inc_m32rel(&instr_count[93]);
972 #ifdef INTERPRET_DSLL
973 gencallinterp((unsigned long long)cached_interpreter_table.DSLL, 0);
975 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
976 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
978 mov_reg64_reg64(rd, rt);
979 shl_reg64_imm8(rd, dst->f.r.sa);
985 #if defined(COUNT_INSTR)
986 inc_m32rel(&instr_count[94]);
988 #ifdef INTERPRET_DSRL
989 gencallinterp((unsigned long long)cached_interpreter_table.DSRL, 0);
991 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
992 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
994 mov_reg64_reg64(rd, rt);
995 shr_reg64_imm8(rd, dst->f.r.sa);
1001 #if defined(COUNT_INSTR)
1002 inc_m32rel(&instr_count[95]);
1004 #ifdef INTERPRET_DSRA
1005 gencallinterp((unsigned long long)cached_interpreter_table.DSRA, 0);
1007 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
1008 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
1010 mov_reg64_reg64(rd, rt);
1011 sar_reg64_imm8(rd, dst->f.r.sa);
1015 void gendsll32(void)
1017 #if defined(COUNT_INSTR)
1018 inc_m32rel(&instr_count[97]);
1020 #ifdef INTERPRET_DSLL32
1021 gencallinterp((unsigned long long)cached_interpreter_table.DSLL32, 0);
1023 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
1024 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
1026 mov_reg64_reg64(rd, rt);
1027 shl_reg64_imm8(rd, dst->f.r.sa + 32);
1031 void gendsrl32(void)
1033 #if defined(COUNT_INSTR)
1034 inc_m32rel(&instr_count[98]);
1036 #ifdef INTERPRET_DSRL32
1037 gencallinterp((unsigned long long)cached_interpreter_table.DSRL32, 0);
1039 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
1040 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
1042 mov_reg64_reg64(rd, rt);
1043 shr_reg64_imm8(rd, dst->f.r.sa + 32);
1047 void gendsra32(void)
1049 #if defined(COUNT_INSTR)
1050 inc_m32rel(&instr_count[99]);
1052 #ifdef INTERPRET_DSRA32
1053 gencallinterp((unsigned long long)cached_interpreter_table.DSRA32, 0);
1055 int rt = allocate_register_64((unsigned long long *)dst->f.r.rt);
1056 int rd = allocate_register_64_w((unsigned long long *)dst->f.r.rd);
1058 mov_reg64_reg64(rd, rt);
1059 sar_reg64_imm8(rd, dst->f.r.sa + 32);