1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Mupen64plus - gspecial.c *
3 * Mupen64Plus homepage: http://code.google.com/p/mupen64plus/ *
4 * Copyright (C) 2002 Hacktarux *
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. *
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. *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
25 #include "interpret.h"
27 #include "r4300/recomph.h"
28 #include "r4300/recomp.h"
29 #include "r4300/r4300.h"
30 #include "r4300/ops.h"
31 #include "r4300/macros.h"
32 #include "r4300/exception.h"
37 gencallinterp((unsigned int)cached_interpreter_table.SLL, 0);
39 int rt = allocate_register((unsigned int *)dst->f.r.rt);
40 int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
42 mov_reg32_reg32(rd, rt);
43 shl_reg32_imm8(rd, dst->f.r.sa);
50 gencallinterp((unsigned int)cached_interpreter_table.SRL, 0);
52 int rt = allocate_register((unsigned int *)dst->f.r.rt);
53 int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
55 mov_reg32_reg32(rd, rt);
56 shr_reg32_imm8(rd, dst->f.r.sa);
63 gencallinterp((unsigned int)cached_interpreter_table.SRA, 0);
65 int rt = allocate_register((unsigned int *)dst->f.r.rt);
66 int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
68 mov_reg32_reg32(rd, rt);
69 sar_reg32_imm8(rd, dst->f.r.sa);
76 gencallinterp((unsigned int)cached_interpreter_table.SLLV, 0);
79 allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
81 rt = allocate_register((unsigned int *)dst->f.r.rt);
82 rd = allocate_register_w((unsigned int *)dst->f.r.rd);
86 mov_reg32_reg32(rd, rt);
91 int temp = lru_register();
93 mov_reg32_reg32(temp, rt);
95 mov_reg32_reg32(rd, temp);
102 #ifdef INTERPRET_SRLV
103 gencallinterp((unsigned int)cached_interpreter_table.SRLV, 0);
106 allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
108 rt = allocate_register((unsigned int *)dst->f.r.rt);
109 rd = allocate_register_w((unsigned int *)dst->f.r.rd);
113 mov_reg32_reg32(rd, rt);
118 int temp = lru_register();
120 mov_reg32_reg32(temp, rt);
122 mov_reg32_reg32(rd, temp);
129 #ifdef INTERPRET_SRAV
130 gencallinterp((unsigned int)cached_interpreter_table.SRAV, 0);
133 allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
135 rt = allocate_register((unsigned int *)dst->f.r.rt);
136 rd = allocate_register_w((unsigned int *)dst->f.r.rd);
140 mov_reg32_reg32(rd, rt);
145 int temp = lru_register();
147 mov_reg32_reg32(temp, rt);
149 mov_reg32_reg32(rd, temp);
157 gencallinterp((unsigned int)cached_interpreter_table.JR, 1);
159 static unsigned int precomp_instr_size = sizeof(precomp_instr);
161 (unsigned int)(&dst->local_addr) - (unsigned int)(dst);
162 unsigned int diff_need =
163 (unsigned int)(&dst->reg_cache_infos.need_map) - (unsigned int)(dst);
164 unsigned int diff_wrap =
165 (unsigned int)(&dst->reg_cache_infos.jump_wrapper) - (unsigned int)(dst);
167 if (((dst->addr & 0xFFF) == 0xFFC &&
168 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
170 gencallinterp((unsigned int)cached_interpreter_table.JR, 1);
174 free_all_registers();
176 mov_eax_memoffs32((unsigned int *)dst->f.i.rs);
177 mov_memoffs32_eax((unsigned int *)&local_rs);
181 mov_eax_memoffs32((unsigned int *)&local_rs);
182 mov_memoffs32_eax((unsigned int *)&last_addr);
184 gencheck_interupt_reg();
186 mov_eax_memoffs32((unsigned int *)&local_rs);
187 mov_reg32_reg32(EBX, EAX);
188 and_eax_imm32(0xFFFFF000);
189 cmp_eax_imm32(dst_block->start & 0xFFFFF000);
194 mov_m32_reg32(&jump_to_address, EBX);
195 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
196 mov_reg32_imm32(EAX, (unsigned int)jump_to_func);
201 mov_reg32_reg32(EAX, EBX);
202 sub_eax_imm32(dst_block->start);
203 shr_reg32_imm8(EAX, 2);
204 mul_m32((unsigned int *)(&precomp_instr_size));
206 mov_reg32_preg32pimm32(EBX, EAX, (unsigned int)(dst_block->block)+diff_need);
207 cmp_reg32_imm32(EBX, 1);
210 add_eax_imm32((unsigned int)(dst_block->block)+diff_wrap); // 5
213 mov_reg32_preg32pimm32(EAX, EAX, (unsigned int)(dst_block->block)+diff);
214 add_reg32_m32(EAX, (unsigned int *)(&dst_block->code));
222 #ifdef INTERPRET_JALR
223 gencallinterp((unsigned int)cached_interpreter_table.JALR, 0);
225 static unsigned int precomp_instr_size = sizeof(precomp_instr);
227 (unsigned int)(&dst->local_addr) - (unsigned int)(dst);
228 unsigned int diff_need =
229 (unsigned int)(&dst->reg_cache_infos.need_map) - (unsigned int)(dst);
230 unsigned int diff_wrap =
231 (unsigned int)(&dst->reg_cache_infos.jump_wrapper) - (unsigned int)(dst);
233 if (((dst->addr & 0xFFF) == 0xFFC &&
234 (dst->addr < 0x80000000 || dst->addr >= 0xC0000000))||no_compiled_jump)
236 gencallinterp((unsigned int)cached_interpreter_table.JALR, 1);
240 free_all_registers();
242 mov_eax_memoffs32((unsigned int *)dst->f.r.rs);
243 mov_memoffs32_eax((unsigned int *)&local_rs);
247 mov_m32_imm32((unsigned int *)(dst-1)->f.r.rd, dst->addr+4);
248 if ((dst->addr+4) & 0x80000000)
249 mov_m32_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0xFFFFFFFF);
251 mov_m32_imm32(((unsigned int *)(dst-1)->f.r.rd)+1, 0);
253 mov_eax_memoffs32((unsigned int *)&local_rs);
254 mov_memoffs32_eax((unsigned int *)&last_addr);
256 gencheck_interupt_reg();
258 mov_eax_memoffs32((unsigned int *)&local_rs);
259 mov_reg32_reg32(EBX, EAX);
260 and_eax_imm32(0xFFFFF000);
261 cmp_eax_imm32(dst_block->start & 0xFFFFF000);
266 mov_m32_reg32(&jump_to_address, EBX);
267 mov_m32_imm32((unsigned int*)(&PC), (unsigned int)(dst+1));
268 mov_reg32_imm32(EAX, (unsigned int)jump_to_func);
273 mov_reg32_reg32(EAX, EBX);
274 sub_eax_imm32(dst_block->start);
275 shr_reg32_imm8(EAX, 2);
276 mul_m32((unsigned int *)(&precomp_instr_size));
278 mov_reg32_preg32pimm32(EBX, EAX, (unsigned int)(dst_block->block)+diff_need);
279 cmp_reg32_imm32(EBX, 1);
282 add_eax_imm32((unsigned int)(dst_block->block)+diff_wrap); // 5
285 mov_reg32_preg32pimm32(EAX, EAX, (unsigned int)(dst_block->block)+diff);
286 add_reg32_m32(EAX, (unsigned int *)(&dst_block->code));
292 void gensyscall(void)
294 #ifdef INTERPRET_SYSCALL
295 gencallinterp((unsigned int)cached_interpreter_table.SYSCALL, 0);
297 free_all_registers();
299 mov_m32_imm32(&Cause, 8 << 2);
300 gencallinterp((unsigned int)exception_general, 0);
310 #ifdef INTERPRET_MFHI
311 gencallinterp((unsigned int)cached_interpreter_table.MFHI, 0);
313 int rd1 = allocate_64_register1_w((unsigned int*)dst->f.r.rd);
314 int rd2 = allocate_64_register2_w((unsigned int*)dst->f.r.rd);
315 int hi1 = allocate_64_register1((unsigned int*)&hi);
316 int hi2 = allocate_64_register2((unsigned int*)&hi);
318 mov_reg32_reg32(rd1, hi1);
319 mov_reg32_reg32(rd2, hi2);
325 #ifdef INTERPRET_MTHI
326 gencallinterp((unsigned int)cached_interpreter_table.MTHI, 0);
328 int hi1 = allocate_64_register1_w((unsigned int*)&hi);
329 int hi2 = allocate_64_register2_w((unsigned int*)&hi);
330 int rs1 = allocate_64_register1((unsigned int*)dst->f.r.rs);
331 int rs2 = allocate_64_register2((unsigned int*)dst->f.r.rs);
333 mov_reg32_reg32(hi1, rs1);
334 mov_reg32_reg32(hi2, rs2);
340 #ifdef INTERPRET_MFLO
341 gencallinterp((unsigned int)cached_interpreter_table.MFLO, 0);
343 int rd1 = allocate_64_register1_w((unsigned int*)dst->f.r.rd);
344 int rd2 = allocate_64_register2_w((unsigned int*)dst->f.r.rd);
345 int lo1 = allocate_64_register1((unsigned int*)&lo);
346 int lo2 = allocate_64_register2((unsigned int*)&lo);
348 mov_reg32_reg32(rd1, lo1);
349 mov_reg32_reg32(rd2, lo2);
355 #ifdef INTERPRET_MTLO
356 gencallinterp((unsigned int)cached_interpreter_table.MTLO, 0);
358 int lo1 = allocate_64_register1_w((unsigned int*)&lo);
359 int lo2 = allocate_64_register2_w((unsigned int*)&lo);
360 int rs1 = allocate_64_register1((unsigned int*)dst->f.r.rs);
361 int rs2 = allocate_64_register2((unsigned int*)dst->f.r.rs);
363 mov_reg32_reg32(lo1, rs1);
364 mov_reg32_reg32(lo2, rs2);
370 #ifdef INTERPRET_DSLLV
371 gencallinterp((unsigned int)cached_interpreter_table.DSLLV, 0);
373 int rt1, rt2, rd1, rd2;
374 allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
376 rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
377 rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
378 rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
379 rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
381 if (rd1 != ECX && rd2 != ECX)
383 mov_reg32_reg32(rd1, rt1);
384 mov_reg32_reg32(rd2, rt2);
385 shld_reg32_reg32_cl(rd2,rd1);
387 test_reg32_imm32(ECX, 0x20);
389 mov_reg32_reg32(rd2, rd1); // 2
390 xor_reg32_reg32(rd1, rd1); // 2
396 temp1 = lru_register();
397 temp2 = lru_register_exc1(temp1);
398 free_register(temp1);
399 free_register(temp2);
401 mov_reg32_reg32(temp1, rt1);
402 mov_reg32_reg32(temp2, rt2);
403 shld_reg32_reg32_cl(temp2, temp1);
405 test_reg32_imm32(ECX, 0x20);
407 mov_reg32_reg32(temp2, temp1); // 2
408 xor_reg32_reg32(temp1, temp1); // 2
410 mov_reg32_reg32(rd1, temp1);
411 mov_reg32_reg32(rd2, temp2);
418 #ifdef INTERPRET_DSRLV
419 gencallinterp((unsigned int)cached_interpreter_table.DSRLV, 0);
421 int rt1, rt2, rd1, rd2;
422 allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
424 rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
425 rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
426 rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
427 rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
429 if (rd1 != ECX && rd2 != ECX)
431 mov_reg32_reg32(rd1, rt1);
432 mov_reg32_reg32(rd2, rt2);
433 shrd_reg32_reg32_cl(rd1,rd2);
435 test_reg32_imm32(ECX, 0x20);
437 mov_reg32_reg32(rd1, rd2); // 2
438 xor_reg32_reg32(rd2, rd2); // 2
444 temp1 = lru_register();
445 temp2 = lru_register_exc1(temp1);
446 free_register(temp1);
447 free_register(temp2);
449 mov_reg32_reg32(temp1, rt1);
450 mov_reg32_reg32(temp2, rt2);
451 shrd_reg32_reg32_cl(temp1, temp2);
453 test_reg32_imm32(ECX, 0x20);
455 mov_reg32_reg32(temp1, temp2); // 2
456 xor_reg32_reg32(temp2, temp2); // 2
458 mov_reg32_reg32(rd1, temp1);
459 mov_reg32_reg32(rd2, temp2);
466 #ifdef INTERPRET_DSRAV
467 gencallinterp((unsigned int)cached_interpreter_table.DSRAV, 0);
469 int rt1, rt2, rd1, rd2;
470 allocate_register_manually(ECX, (unsigned int *)dst->f.r.rs);
472 rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
473 rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
474 rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
475 rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
477 if (rd1 != ECX && rd2 != ECX)
479 mov_reg32_reg32(rd1, rt1);
480 mov_reg32_reg32(rd2, rt2);
481 shrd_reg32_reg32_cl(rd1,rd2);
483 test_reg32_imm32(ECX, 0x20);
485 mov_reg32_reg32(rd1, rd2); // 2
486 sar_reg32_imm8(rd2, 31); // 3
492 temp1 = lru_register();
493 temp2 = lru_register_exc1(temp1);
494 free_register(temp1);
495 free_register(temp2);
497 mov_reg32_reg32(temp1, rt1);
498 mov_reg32_reg32(temp2, rt2);
499 shrd_reg32_reg32_cl(temp1, temp2);
501 test_reg32_imm32(ECX, 0x20);
503 mov_reg32_reg32(temp1, temp2); // 2
504 sar_reg32_imm8(temp2, 31); // 3
506 mov_reg32_reg32(rd1, temp1);
507 mov_reg32_reg32(rd2, temp2);
514 #ifdef INTERPRET_MULT
515 gencallinterp((unsigned int)cached_interpreter_table.MULT, 0);
518 allocate_register_manually_w(EAX, (unsigned int *)&lo, 0);
519 allocate_register_manually_w(EDX, (unsigned int *)&hi, 0);
520 rs = allocate_register((unsigned int*)dst->f.r.rs);
521 rt = allocate_register((unsigned int*)dst->f.r.rt);
522 mov_reg32_reg32(EAX, rs);
529 #ifdef INTERPRET_MULTU
530 gencallinterp((unsigned int)cached_interpreter_table.MULTU, 0);
533 allocate_register_manually_w(EAX, (unsigned int *)&lo, 0);
534 allocate_register_manually_w(EDX, (unsigned int *)&hi, 0);
535 rs = allocate_register((unsigned int*)dst->f.r.rs);
536 rt = allocate_register((unsigned int*)dst->f.r.rt);
537 mov_reg32_reg32(EAX, rs);
545 gencallinterp((unsigned int)cached_interpreter_table.DIV, 0);
548 allocate_register_manually_w(EAX, (unsigned int *)&lo, 0);
549 allocate_register_manually_w(EDX, (unsigned int *)&hi, 0);
550 rs = allocate_register((unsigned int*)dst->f.r.rs);
551 rt = allocate_register((unsigned int*)dst->f.r.rt);
552 cmp_reg32_imm32(rt, 0);
553 je_rj((rs == EAX ? 0 : 2) + 1 + 2);
554 mov_reg32_reg32(EAX, rs); // 0 or 2
562 #ifdef INTERPRET_DIVU
563 gencallinterp((unsigned int)cached_interpreter_table.DIVU, 0);
566 allocate_register_manually_w(EAX, (unsigned int *)&lo, 0);
567 allocate_register_manually_w(EDX, (unsigned int *)&hi, 0);
568 rs = allocate_register((unsigned int*)dst->f.r.rs);
569 rt = allocate_register((unsigned int*)dst->f.r.rt);
570 cmp_reg32_imm32(rt, 0);
571 je_rj((rs == EAX ? 0 : 2) + 2 + 2);
572 mov_reg32_reg32(EAX, rs); // 0 or 2
573 xor_reg32_reg32(EDX, EDX); // 2
580 gencallinterp((unsigned int)cached_interpreter_table.DMULT, 0);
585 #ifdef INTERPRET_DMULTU
586 gencallinterp((unsigned int)cached_interpreter_table.DMULTU, 0);
588 free_all_registers();
591 mov_eax_memoffs32((unsigned int *)dst->f.r.rs);
592 mul_m32((unsigned int *)dst->f.r.rt); // EDX:EAX = temp1
593 mov_memoffs32_eax((unsigned int *)(&lo));
595 mov_reg32_reg32(EBX, EDX); // EBX = temp1>>32
596 mov_eax_memoffs32((unsigned int *)dst->f.r.rs);
597 mul_m32((unsigned int *)(dst->f.r.rt)+1);
598 add_reg32_reg32(EBX, EAX);
599 adc_reg32_imm32(EDX, 0);
600 mov_reg32_reg32(ECX, EDX); // ECX:EBX = temp2
602 mov_eax_memoffs32((unsigned int *)(dst->f.r.rs)+1);
603 mul_m32((unsigned int *)dst->f.r.rt); // EDX:EAX = temp3
605 add_reg32_reg32(EBX, EAX);
606 adc_reg32_imm32(ECX, 0); // ECX:EBX = result2
607 mov_m32_reg32((unsigned int*)(&lo)+1, EBX);
609 mov_reg32_reg32(ESI, EDX); // ESI = temp3>>32
610 mov_eax_memoffs32((unsigned int *)(dst->f.r.rs)+1);
611 mul_m32((unsigned int *)(dst->f.r.rt)+1);
612 add_reg32_reg32(EAX, ESI);
613 adc_reg32_imm32(EDX, 0); // EDX:EAX = temp4
615 add_reg32_reg32(EAX, ECX);
616 adc_reg32_imm32(EDX, 0); // EDX:EAX = result3
617 mov_memoffs32_eax((unsigned int *)(&hi));
618 mov_m32_reg32((unsigned int *)(&hi)+1, EDX);
624 gencallinterp((unsigned int)cached_interpreter_table.DDIV, 0);
629 gencallinterp((unsigned int)cached_interpreter_table.DDIVU, 0);
635 gencallinterp((unsigned int)cached_interpreter_table.ADD, 0);
637 int rs = allocate_register((unsigned int *)dst->f.r.rs);
638 int rt = allocate_register((unsigned int *)dst->f.r.rt);
639 int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
641 if (rt != rd && rs != rd)
643 mov_reg32_reg32(rd, rs);
644 add_reg32_reg32(rd, rt);
648 int temp = lru_register();
650 mov_reg32_reg32(temp, rs);
651 add_reg32_reg32(temp, rt);
652 mov_reg32_reg32(rd, temp);
659 #ifdef INTERPRET_ADDU
660 gencallinterp((unsigned int)cached_interpreter_table.ADDU, 0);
662 int rs = allocate_register((unsigned int *)dst->f.r.rs);
663 int rt = allocate_register((unsigned int *)dst->f.r.rt);
664 int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
666 if (rt != rd && rs != rd)
668 mov_reg32_reg32(rd, rs);
669 add_reg32_reg32(rd, rt);
673 int temp = lru_register();
675 mov_reg32_reg32(temp, rs);
676 add_reg32_reg32(temp, rt);
677 mov_reg32_reg32(rd, temp);
685 gencallinterp((unsigned int)cached_interpreter_table.SUB, 0);
687 int rs = allocate_register((unsigned int *)dst->f.r.rs);
688 int rt = allocate_register((unsigned int *)dst->f.r.rt);
689 int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
691 if (rt != rd && rs != rd)
693 mov_reg32_reg32(rd, rs);
694 sub_reg32_reg32(rd, rt);
698 int temp = lru_register();
700 mov_reg32_reg32(temp, rs);
701 sub_reg32_reg32(temp, rt);
702 mov_reg32_reg32(rd, temp);
709 #ifdef INTERPRET_SUBU
710 gencallinterp((unsigned int)cached_interpreter_table.SUBU, 0);
712 int rs = allocate_register((unsigned int *)dst->f.r.rs);
713 int rt = allocate_register((unsigned int *)dst->f.r.rt);
714 int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
716 if (rt != rd && rs != rd)
718 mov_reg32_reg32(rd, rs);
719 sub_reg32_reg32(rd, rt);
723 int temp = lru_register();
725 mov_reg32_reg32(temp, rs);
726 sub_reg32_reg32(temp, rt);
727 mov_reg32_reg32(rd, temp);
735 gencallinterp((unsigned int)cached_interpreter_table.AND, 0);
737 int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
738 int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
739 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
740 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
741 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
742 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
744 if (rt1 != rd1 && rs1 != rd1)
746 mov_reg32_reg32(rd1, rs1);
747 mov_reg32_reg32(rd2, rs2);
748 and_reg32_reg32(rd1, rt1);
749 and_reg32_reg32(rd2, rt2);
753 int temp = lru_register();
755 mov_reg32_reg32(temp, rs1);
756 and_reg32_reg32(temp, rt1);
757 mov_reg32_reg32(rd1, temp);
758 mov_reg32_reg32(temp, rs2);
759 and_reg32_reg32(temp, rt2);
760 mov_reg32_reg32(rd2, temp);
768 gencallinterp((unsigned int)cached_interpreter_table.OR, 0);
770 int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
771 int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
772 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
773 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
774 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
775 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
777 if (rt1 != rd1 && rs1 != rd1)
779 mov_reg32_reg32(rd1, rs1);
780 mov_reg32_reg32(rd2, rs2);
781 or_reg32_reg32(rd1, rt1);
782 or_reg32_reg32(rd2, rt2);
786 int temp = lru_register();
788 mov_reg32_reg32(temp, rs1);
789 or_reg32_reg32(temp, rt1);
790 mov_reg32_reg32(rd1, temp);
791 mov_reg32_reg32(temp, rs2);
792 or_reg32_reg32(temp, rt2);
793 mov_reg32_reg32(rd2, temp);
801 gencallinterp((unsigned int)cached_interpreter_table.XOR, 0);
803 int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
804 int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
805 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
806 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
807 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
808 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
810 if (rt1 != rd1 && rs1 != rd1)
812 mov_reg32_reg32(rd1, rs1);
813 mov_reg32_reg32(rd2, rs2);
814 xor_reg32_reg32(rd1, rt1);
815 xor_reg32_reg32(rd2, rt2);
819 int temp = lru_register();
821 mov_reg32_reg32(temp, rs1);
822 xor_reg32_reg32(temp, rt1);
823 mov_reg32_reg32(rd1, temp);
824 mov_reg32_reg32(temp, rs2);
825 xor_reg32_reg32(temp, rt2);
826 mov_reg32_reg32(rd2, temp);
834 gencallinterp((unsigned int)cached_interpreter_table.NOR, 0);
836 int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
837 int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
838 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
839 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
840 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
841 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
843 if (rt1 != rd1 && rs1 != rd1)
845 mov_reg32_reg32(rd1, rs1);
846 mov_reg32_reg32(rd2, rs2);
847 or_reg32_reg32(rd1, rt1);
848 or_reg32_reg32(rd2, rt2);
854 int temp = lru_register();
856 mov_reg32_reg32(temp, rs1);
857 or_reg32_reg32(temp, rt1);
858 mov_reg32_reg32(rd1, temp);
859 mov_reg32_reg32(temp, rs2);
860 or_reg32_reg32(temp, rt2);
861 mov_reg32_reg32(rd2, temp);
871 gencallinterp((unsigned int)cached_interpreter_table.SLT, 0);
873 int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
874 int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
875 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
876 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
877 int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
879 cmp_reg32_reg32(rs2, rt2);
882 cmp_reg32_reg32(rs1, rt1); // 2
884 mov_reg32_imm32(rd, 0); // 5
885 jmp_imm_short(5); // 2
886 mov_reg32_imm32(rd, 1); // 5
892 #ifdef INTERPRET_SLTU
893 gencallinterp((unsigned int)cached_interpreter_table.SLTU, 0);
895 int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
896 int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
897 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
898 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
899 int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
901 cmp_reg32_reg32(rs2, rt2);
904 cmp_reg32_reg32(rs1, rt1); // 2
906 mov_reg32_imm32(rd, 0); // 5
907 jmp_imm_short(5); // 2
908 mov_reg32_imm32(rd, 1); // 5
914 #ifdef INTERPRET_DADD
915 gencallinterp((unsigned int)cached_interpreter_table.DADD, 0);
917 int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
918 int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
919 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
920 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
921 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
922 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
924 if (rt1 != rd1 && rs1 != rd1)
926 mov_reg32_reg32(rd1, rs1);
927 mov_reg32_reg32(rd2, rs2);
928 add_reg32_reg32(rd1, rt1);
929 adc_reg32_reg32(rd2, rt2);
933 int temp = lru_register();
935 mov_reg32_reg32(temp, rs1);
936 add_reg32_reg32(temp, rt1);
937 mov_reg32_reg32(rd1, temp);
938 mov_reg32_reg32(temp, rs2);
939 adc_reg32_reg32(temp, rt2);
940 mov_reg32_reg32(rd2, temp);
947 #ifdef INTERPRET_DADDU
948 gencallinterp((unsigned int)cached_interpreter_table.DADDU, 0);
950 int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
951 int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
952 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
953 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
954 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
955 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
957 if (rt1 != rd1 && rs1 != rd1)
959 mov_reg32_reg32(rd1, rs1);
960 mov_reg32_reg32(rd2, rs2);
961 add_reg32_reg32(rd1, rt1);
962 adc_reg32_reg32(rd2, rt2);
966 int temp = lru_register();
968 mov_reg32_reg32(temp, rs1);
969 add_reg32_reg32(temp, rt1);
970 mov_reg32_reg32(rd1, temp);
971 mov_reg32_reg32(temp, rs2);
972 adc_reg32_reg32(temp, rt2);
973 mov_reg32_reg32(rd2, temp);
980 #ifdef INTERPRET_DSUB
981 gencallinterp((unsigned int)cached_interpreter_table.DSUB, 0);
983 int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
984 int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
985 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
986 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
987 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
988 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
990 if (rt1 != rd1 && rs1 != rd1)
992 mov_reg32_reg32(rd1, rs1);
993 mov_reg32_reg32(rd2, rs2);
994 sub_reg32_reg32(rd1, rt1);
995 sbb_reg32_reg32(rd2, rt2);
999 int temp = lru_register();
1000 free_register(temp);
1001 mov_reg32_reg32(temp, rs1);
1002 sub_reg32_reg32(temp, rt1);
1003 mov_reg32_reg32(rd1, temp);
1004 mov_reg32_reg32(temp, rs2);
1005 sbb_reg32_reg32(temp, rt2);
1006 mov_reg32_reg32(rd2, temp);
1013 #ifdef INTERPRET_DSUBU
1014 gencallinterp((unsigned int)cached_interpreter_table.DSUBU, 0);
1016 int rs1 = allocate_64_register1((unsigned int *)dst->f.r.rs);
1017 int rs2 = allocate_64_register2((unsigned int *)dst->f.r.rs);
1018 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
1019 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1020 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1021 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1023 if (rt1 != rd1 && rs1 != rd1)
1025 mov_reg32_reg32(rd1, rs1);
1026 mov_reg32_reg32(rd2, rs2);
1027 sub_reg32_reg32(rd1, rt1);
1028 sbb_reg32_reg32(rd2, rt2);
1032 int temp = lru_register();
1033 free_register(temp);
1034 mov_reg32_reg32(temp, rs1);
1035 sub_reg32_reg32(temp, rt1);
1036 mov_reg32_reg32(rd1, temp);
1037 mov_reg32_reg32(temp, rs2);
1038 sbb_reg32_reg32(temp, rt2);
1039 mov_reg32_reg32(rd2, temp);
1046 gencallinterp((unsigned int)cached_interpreter_table.TEQ, 0);
1051 #ifdef INTERPRET_DSLL
1052 gencallinterp((unsigned int)cached_interpreter_table.DSLL, 0);
1054 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
1055 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1056 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1057 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1059 mov_reg32_reg32(rd1, rt1);
1060 mov_reg32_reg32(rd2, rt2);
1061 shld_reg32_reg32_imm8(rd2, rd1, dst->f.r.sa);
1062 shl_reg32_imm8(rd1, dst->f.r.sa);
1063 if (dst->f.r.sa & 0x20)
1065 mov_reg32_reg32(rd2, rd1);
1066 xor_reg32_reg32(rd1, rd1);
1073 #ifdef INTERPRET_DSRL
1074 gencallinterp((unsigned int)cached_interpreter_table.DSRL, 0);
1076 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
1077 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1078 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1079 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1081 mov_reg32_reg32(rd1, rt1);
1082 mov_reg32_reg32(rd2, rt2);
1083 shrd_reg32_reg32_imm8(rd1, rd2, dst->f.r.sa);
1084 shr_reg32_imm8(rd2, dst->f.r.sa);
1085 if (dst->f.r.sa & 0x20)
1087 mov_reg32_reg32(rd1, rd2);
1088 xor_reg32_reg32(rd2, rd2);
1095 #ifdef INTERPRET_DSRA
1096 gencallinterp((unsigned int)cached_interpreter_table.DSRA, 0);
1098 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
1099 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1100 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1101 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1103 mov_reg32_reg32(rd1, rt1);
1104 mov_reg32_reg32(rd2, rt2);
1105 shrd_reg32_reg32_imm8(rd1, rd2, dst->f.r.sa);
1106 sar_reg32_imm8(rd2, dst->f.r.sa);
1107 if (dst->f.r.sa & 0x20)
1109 mov_reg32_reg32(rd1, rd2);
1110 sar_reg32_imm8(rd2, 31);
1115 void gendsll32(void)
1117 #ifdef INTERPRET_DSLL32
1118 gencallinterp((unsigned int)cached_interpreter_table.DSLL32, 0);
1120 int rt1 = allocate_64_register1((unsigned int *)dst->f.r.rt);
1121 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1122 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1124 mov_reg32_reg32(rd2, rt1);
1125 shl_reg32_imm8(rd2, dst->f.r.sa);
1126 xor_reg32_reg32(rd1, rd1);
1130 void gendsrl32(void)
1132 #ifdef INTERPRET_DSRL32
1133 gencallinterp((unsigned int)cached_interpreter_table.DSRL32, 0);
1135 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1136 int rd1 = allocate_64_register1_w((unsigned int *)dst->f.r.rd);
1137 int rd2 = allocate_64_register2_w((unsigned int *)dst->f.r.rd);
1139 mov_reg32_reg32(rd1, rt2);
1140 shr_reg32_imm8(rd1, dst->f.r.sa);
1141 xor_reg32_reg32(rd2, rd2);
1145 void gendsra32(void)
1147 #ifdef INTERPRET_DSRA32
1148 gencallinterp((unsigned int)cached_interpreter_table.DSRA32, 0);
1150 int rt2 = allocate_64_register2((unsigned int *)dst->f.r.rt);
1151 int rd = allocate_register_w((unsigned int *)dst->f.r.rd);
1153 mov_reg32_reg32(rd, rt2);
1154 sar_reg32_imm8(rd, dst->f.r.sa);