Commit 24988dc24169b581fe6563d7ed619bd50a2af40b
1 parent
0954d0d9
SH4, fix several instructions
fix instruction code for frchg, fschg, ocbp. fix addressing mode handling for @Rn+, @-Rn, @(disp,gbr). fix operation for div0s. fix comments for mov imm, add imm, @(r0+,gbr), mac.l @Rm+,@Rn+. fix ldb to ldub for or/tst/xor.b #imm,@(r0,gbr). add fmov extended operations. add fcmp/eq, fcmp/gt, fneg, fabs, fsqrt, fcnvsd, fcnvds. (Takashi Yoshii) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4040 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
160 additions
and
63 deletions
target-sh4/op.c
... | ... | @@ -45,13 +45,7 @@ void OPPROTO op_movl_imm_T0(void) |
45 | 45 | |
46 | 46 | void OPPROTO op_movl_imm_T1(void) |
47 | 47 | { |
48 | - T0 = (uint32_t) PARAM1; | |
49 | - RETURN(); | |
50 | -} | |
51 | - | |
52 | -void OPPROTO op_movl_imm_T2(void) | |
53 | -{ | |
54 | - T0 = (uint32_t) PARAM1; | |
48 | + T1 = (uint32_t) PARAM1; | |
55 | 49 | RETURN(); |
56 | 50 | } |
57 | 51 | |
... | ... | @@ -240,6 +234,12 @@ void OPPROTO op_xtrct_T0_T1(void) |
240 | 234 | RETURN(); |
241 | 235 | } |
242 | 236 | |
237 | +void OPPROTO op_add_T0_T1(void) | |
238 | +{ | |
239 | + T1 += T0; | |
240 | + RETURN(); | |
241 | +} | |
242 | + | |
243 | 243 | void OPPROTO op_addc_T0_T1(void) |
244 | 244 | { |
245 | 245 | helper_addc_T0_T1(); |
... | ... | @@ -355,13 +355,13 @@ void OPPROTO op_mull_T0_T1(void) |
355 | 355 | |
356 | 356 | void OPPROTO op_mulsw_T0_T1(void) |
357 | 357 | { |
358 | - env->macl = (int32_t) T0 *(int32_t) T1; | |
358 | + env->macl = (int32_t)(int16_t) T0 *(int32_t)(int16_t) T1; | |
359 | 359 | RETURN(); |
360 | 360 | } |
361 | 361 | |
362 | 362 | void OPPROTO op_muluw_T0_T1(void) |
363 | 363 | { |
364 | - env->macl = (uint32_t) T0 *(uint32_t) T1; | |
364 | + env->macl = (uint32_t)(uint16_t) T0 *(uint32_t)(uint16_t) T1; | |
365 | 365 | RETURN(); |
366 | 366 | } |
367 | 367 | |
... | ... | @@ -382,7 +382,7 @@ void OPPROTO op_shad_T0_T1(void) |
382 | 382 | if ((T0 & 0x80000000) == 0) |
383 | 383 | T1 <<= (T0 & 0x1f); |
384 | 384 | else if ((T0 & 0x1f) == 0) |
385 | - T1 = 0; | |
385 | + T1 = (T1 & 0x80000000)? 0xffffffff : 0; | |
386 | 386 | else |
387 | 387 | T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1); |
388 | 388 | RETURN(); |
... | ... | @@ -539,7 +539,7 @@ void OPPROTO op_shal_Rn(void) |
539 | 539 | void OPPROTO op_shar_Rn(void) |
540 | 540 | { |
541 | 541 | cond_t(env->gregs[PARAM1] & 1); |
542 | - env->gregs[PARAM1] >>= 1; | |
542 | + *(int32_t *)&env->gregs[PARAM1] >>= 1; | |
543 | 543 | RETURN(); |
544 | 544 | } |
545 | 545 | |
... | ... | @@ -767,6 +767,30 @@ void OPPROTO op_fdiv_DT(void) |
767 | 767 | RETURN(); |
768 | 768 | } |
769 | 769 | |
770 | +void OPPROTO op_fcmp_eq_FT(void) | |
771 | +{ | |
772 | + cond_t(float32_compare(FT0, FT1, &env->fp_status) == 0); | |
773 | + RETURN(); | |
774 | +} | |
775 | + | |
776 | +void OPPROTO op_fcmp_eq_DT(void) | |
777 | +{ | |
778 | + cond_t(float64_compare(DT0, DT1, &env->fp_status) == 0); | |
779 | + RETURN(); | |
780 | +} | |
781 | + | |
782 | +void OPPROTO op_fcmp_gt_FT(void) | |
783 | +{ | |
784 | + cond_t(float32_compare(FT0, FT1, &env->fp_status) == 1); | |
785 | + RETURN(); | |
786 | +} | |
787 | + | |
788 | +void OPPROTO op_fcmp_gt_DT(void) | |
789 | +{ | |
790 | + cond_t(float64_compare(DT0, DT1, &env->fp_status) == 1); | |
791 | + RETURN(); | |
792 | +} | |
793 | + | |
770 | 794 | void OPPROTO op_float_FT(void) |
771 | 795 | { |
772 | 796 | FT0 = int32_to_float32(env->fpul, &env->fp_status); |
... | ... | @@ -791,9 +815,51 @@ void OPPROTO op_ftrc_DT(void) |
791 | 815 | RETURN(); |
792 | 816 | } |
793 | 817 | |
818 | +void OPPROTO op_fneg_frN(void) | |
819 | +{ | |
820 | + env->fregs[PARAM1] = float32_chs(env->fregs[PARAM1]); | |
821 | + RETURN(); | |
822 | +} | |
823 | + | |
824 | +void OPPROTO op_fabs_FT(void) | |
825 | +{ | |
826 | + FT0 = float32_abs(FT0); | |
827 | + RETURN(); | |
828 | +} | |
829 | + | |
830 | +void OPPROTO op_fabs_DT(void) | |
831 | +{ | |
832 | + DT0 = float64_abs(DT0); | |
833 | + RETURN(); | |
834 | +} | |
835 | + | |
836 | +void OPPROTO op_fcnvsd_FT_DT(void) | |
837 | +{ | |
838 | + DT0 = float32_to_float64(FT0, &env->fp_status); | |
839 | + RETURN(); | |
840 | +} | |
841 | + | |
842 | +void OPPROTO op_fcnvds_DT_FT(void) | |
843 | +{ | |
844 | + FT0 = float64_to_float32(DT0, &env->fp_status); | |
845 | + RETURN(); | |
846 | +} | |
847 | + | |
848 | +void OPPROTO op_fsqrt_FT(void) | |
849 | +{ | |
850 | + FT0 = float32_sqrt(FT0, &env->fp_status); | |
851 | + RETURN(); | |
852 | +} | |
853 | + | |
854 | +void OPPROTO op_fsqrt_DT(void) | |
855 | +{ | |
856 | + DT0 = float64_sqrt(DT0, &env->fp_status); | |
857 | + RETURN(); | |
858 | +} | |
859 | + | |
794 | 860 | void OPPROTO op_fmov_T0_frN(void) |
795 | 861 | { |
796 | - *(unsigned int *)&env->fregs[PARAM1] = T0; | |
862 | + *(uint32_t *)&env->fregs[PARAM1] = T0; | |
797 | 863 | RETURN(); |
798 | 864 | } |
799 | 865 | ... | ... |
target-sh4/translate.c
... | ... | @@ -268,11 +268,11 @@ void _decode_opc(DisasContext * ctx) |
268 | 268 | case 0x0018: /* sett */ |
269 | 269 | gen_op_sett(); |
270 | 270 | return; |
271 | - case 0xfbfb: /* frchg */ | |
271 | + case 0xfbfd: /* frchg */ | |
272 | 272 | gen_op_frchg(); |
273 | 273 | ctx->bstate = BS_STOP; |
274 | 274 | return; |
275 | - case 0xf3fb: /* fschg */ | |
275 | + case 0xf3fd: /* fschg */ | |
276 | 276 | gen_op_fschg(); |
277 | 277 | ctx->bstate = BS_STOP; |
278 | 278 | return; |
... | ... | @@ -296,7 +296,7 @@ void _decode_opc(DisasContext * ctx) |
296 | 296 | gen_op_ldl_T0_T0(ctx); |
297 | 297 | gen_op_movl_T0_rN(REG(B11_8)); |
298 | 298 | return; |
299 | - case 0xe000: /* mov.l #imm,Rn */ | |
299 | + case 0xe000: /* mov #imm,Rn */ | |
300 | 300 | gen_op_movl_imm_rN(B7_0s, REG(B11_8)); |
301 | 301 | return; |
302 | 302 | case 0x9000: /* mov.w @(disp,PC),Rn */ |
... | ... | @@ -309,7 +309,7 @@ void _decode_opc(DisasContext * ctx) |
309 | 309 | gen_op_ldl_T0_T0(ctx); |
310 | 310 | gen_op_movl_T0_rN(REG(B11_8)); |
311 | 311 | return; |
312 | - case 0x7000: /* add.l #imm,Rn */ | |
312 | + case 0x7000: /* add #imm,Rn */ | |
313 | 313 | gen_op_add_imm_rN(B7_0s, REG(B11_8)); |
314 | 314 | return; |
315 | 315 | case 0xa000: /* bra disp */ |
... | ... | @@ -361,20 +361,20 @@ void _decode_opc(DisasContext * ctx) |
361 | 361 | gen_op_movl_T0_rN(REG(B11_8)); |
362 | 362 | return; |
363 | 363 | case 0x2004: /* mov.b Rm,@-Rn */ |
364 | - gen_op_dec1_rN(REG(B11_8)); | |
365 | 364 | gen_op_movl_rN_T0(REG(B7_4)); |
365 | + gen_op_dec1_rN(REG(B11_8)); | |
366 | 366 | gen_op_movl_rN_T1(REG(B11_8)); |
367 | 367 | gen_op_stb_T0_T1(ctx); |
368 | 368 | return; |
369 | 369 | case 0x2005: /* mov.w Rm,@-Rn */ |
370 | - gen_op_dec2_rN(REG(B11_8)); | |
371 | 370 | gen_op_movl_rN_T0(REG(B7_4)); |
371 | + gen_op_dec2_rN(REG(B11_8)); | |
372 | 372 | gen_op_movl_rN_T1(REG(B11_8)); |
373 | 373 | gen_op_stw_T0_T1(ctx); |
374 | 374 | return; |
375 | 375 | case 0x2006: /* mov.l Rm,@-Rn */ |
376 | - gen_op_dec4_rN(REG(B11_8)); | |
377 | 376 | gen_op_movl_rN_T0(REG(B7_4)); |
377 | + gen_op_dec4_rN(REG(B11_8)); | |
378 | 378 | gen_op_movl_rN_T1(REG(B11_8)); |
379 | 379 | gen_op_stl_T0_T1(ctx); |
380 | 380 | return; |
... | ... | @@ -382,19 +382,22 @@ void _decode_opc(DisasContext * ctx) |
382 | 382 | gen_op_movl_rN_T0(REG(B7_4)); |
383 | 383 | gen_op_ldb_T0_T0(ctx); |
384 | 384 | gen_op_movl_T0_rN(REG(B11_8)); |
385 | - gen_op_inc1_rN(REG(B7_4)); | |
385 | + if ( B11_8 != B7_4 ) | |
386 | + gen_op_inc1_rN(REG(B7_4)); | |
386 | 387 | return; |
387 | 388 | case 0x6005: /* mov.w @Rm+,Rn */ |
388 | 389 | gen_op_movl_rN_T0(REG(B7_4)); |
389 | 390 | gen_op_ldw_T0_T0(ctx); |
390 | 391 | gen_op_movl_T0_rN(REG(B11_8)); |
391 | - gen_op_inc2_rN(REG(B7_4)); | |
392 | + if ( B11_8 != B7_4 ) | |
393 | + gen_op_inc2_rN(REG(B7_4)); | |
392 | 394 | return; |
393 | 395 | case 0x6006: /* mov.l @Rm+,Rn */ |
394 | 396 | gen_op_movl_rN_T0(REG(B7_4)); |
395 | 397 | gen_op_ldl_T0_T0(ctx); |
396 | 398 | gen_op_movl_T0_rN(REG(B11_8)); |
397 | - gen_op_inc4_rN(REG(B7_4)); | |
399 | + if ( B11_8 != B7_4 ) | |
400 | + gen_op_inc4_rN(REG(B7_4)); | |
398 | 401 | return; |
399 | 402 | case 0x0004: /* mov.b Rm,@(R0,Rn) */ |
400 | 403 | gen_op_movl_rN_T0(REG(B7_4)); |
... | ... | @@ -502,7 +505,6 @@ void _decode_opc(DisasContext * ctx) |
502 | 505 | gen_op_movl_rN_T0(REG(B7_4)); |
503 | 506 | gen_op_movl_rN_T1(REG(B11_8)); |
504 | 507 | gen_op_div0s_T0_T1(); |
505 | - gen_op_movl_T1_rN(REG(B11_8)); | |
506 | 508 | return; |
507 | 509 | case 0x3004: /* div1 Rm,Rn */ |
508 | 510 | gen_op_movl_rN_T0(REG(B7_4)); |
... | ... | @@ -536,25 +538,25 @@ void _decode_opc(DisasContext * ctx) |
536 | 538 | gen_op_movuw_rN_T0(REG(B7_4)); |
537 | 539 | gen_op_movl_T0_rN(REG(B11_8)); |
538 | 540 | return; |
539 | - case 0x000f: /* mac.l @Rm+,@Rn- */ | |
541 | + case 0x000f: /* mac.l @Rm+,@Rn+ */ | |
540 | 542 | gen_op_movl_rN_T0(REG(B11_8)); |
541 | 543 | gen_op_ldl_T0_T0(ctx); |
542 | 544 | gen_op_movl_T0_T1(); |
543 | - gen_op_movl_rN_T1(REG(B7_4)); | |
545 | + gen_op_inc4_rN(REG(B11_8)); | |
546 | + gen_op_movl_rN_T0(REG(B7_4)); | |
544 | 547 | gen_op_ldl_T0_T0(ctx); |
545 | 548 | gen_op_macl_T0_T1(); |
546 | 549 | gen_op_inc4_rN(REG(B7_4)); |
547 | - gen_op_inc4_rN(REG(B11_8)); | |
548 | 550 | return; |
549 | 551 | case 0x400f: /* mac.w @Rm+,@Rn+ */ |
550 | 552 | gen_op_movl_rN_T0(REG(B11_8)); |
551 | 553 | gen_op_ldl_T0_T0(ctx); |
552 | 554 | gen_op_movl_T0_T1(); |
553 | - gen_op_movl_rN_T1(REG(B7_4)); | |
555 | + gen_op_inc2_rN(REG(B11_8)); | |
556 | + gen_op_movl_rN_T0(REG(B7_4)); | |
554 | 557 | gen_op_ldl_T0_T0(ctx); |
555 | 558 | gen_op_macw_T0_T1(); |
556 | 559 | gen_op_inc2_rN(REG(B7_4)); |
557 | - gen_op_inc2_rN(REG(B11_8)); | |
558 | 560 | return; |
559 | 561 | case 0x0007: /* mul.l Rm,Rn */ |
560 | 562 | gen_op_movl_rN_T0(REG(B7_4)); |
... | ... | @@ -629,10 +631,8 @@ void _decode_opc(DisasContext * ctx) |
629 | 631 | return; |
630 | 632 | case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */ |
631 | 633 | if (ctx->fpscr & FPSCR_SZ) { |
632 | - if (ctx->opcode & 0x0110) | |
633 | - break; /* illegal instruction */ | |
634 | - gen_op_fmov_drN_DT0(DREG(B7_4)); | |
635 | - gen_op_fmov_DT0_drN(DREG(B11_8)); | |
634 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
635 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
636 | 636 | } else { |
637 | 637 | gen_op_fmov_frN_FT0(FREG(B7_4)); |
638 | 638 | gen_op_fmov_FT0_frN(FREG(B11_8)); |
... | ... | @@ -640,9 +640,7 @@ void _decode_opc(DisasContext * ctx) |
640 | 640 | return; |
641 | 641 | case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */ |
642 | 642 | if (ctx->fpscr & FPSCR_SZ) { |
643 | - if (ctx->opcode & 0x0010) | |
644 | - break; /* illegal instruction */ | |
645 | - gen_op_fmov_drN_DT0(DREG(B7_4)); | |
643 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
646 | 644 | gen_op_movl_rN_T1(REG(B11_8)); |
647 | 645 | gen_op_stfq_DT0_T1(ctx); |
648 | 646 | } else { |
... | ... | @@ -653,11 +651,9 @@ void _decode_opc(DisasContext * ctx) |
653 | 651 | return; |
654 | 652 | case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */ |
655 | 653 | if (ctx->fpscr & FPSCR_SZ) { |
656 | - if (ctx->opcode & 0x0100) | |
657 | - break; /* illegal instruction */ | |
658 | 654 | gen_op_movl_rN_T0(REG(B7_4)); |
659 | 655 | gen_op_ldfq_T0_DT0(ctx); |
660 | - gen_op_fmov_DT0_drN(DREG(B11_8)); | |
656 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
661 | 657 | } else { |
662 | 658 | gen_op_movl_rN_T0(REG(B7_4)); |
663 | 659 | gen_op_ldfl_T0_FT0(ctx); |
... | ... | @@ -666,11 +662,9 @@ void _decode_opc(DisasContext * ctx) |
666 | 662 | return; |
667 | 663 | case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */ |
668 | 664 | if (ctx->fpscr & FPSCR_SZ) { |
669 | - if (ctx->opcode & 0x0100) | |
670 | - break; /* illegal instruction */ | |
671 | 665 | gen_op_movl_rN_T0(REG(B7_4)); |
672 | 666 | gen_op_ldfq_T0_DT0(ctx); |
673 | - gen_op_fmov_DT0_drN(DREG(B11_8)); | |
667 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
674 | 668 | gen_op_inc8_rN(REG(B7_4)); |
675 | 669 | } else { |
676 | 670 | gen_op_movl_rN_T0(REG(B7_4)); |
... | ... | @@ -681,10 +675,8 @@ void _decode_opc(DisasContext * ctx) |
681 | 675 | return; |
682 | 676 | case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */ |
683 | 677 | if (ctx->fpscr & FPSCR_SZ) { |
684 | - if (ctx->opcode & 0x0100) | |
685 | - break; /* illegal instruction */ | |
686 | 678 | gen_op_dec8_rN(REG(B11_8)); |
687 | - gen_op_fmov_drN_DT0(DREG(B7_4)); | |
679 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
688 | 680 | gen_op_movl_rN_T1(REG(B11_8)); |
689 | 681 | gen_op_stfq_DT0_T1(ctx); |
690 | 682 | } else { |
... | ... | @@ -696,12 +688,10 @@ void _decode_opc(DisasContext * ctx) |
696 | 688 | return; |
697 | 689 | case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */ |
698 | 690 | if (ctx->fpscr & FPSCR_SZ) { |
699 | - if (ctx->opcode & 0x0100) | |
700 | - break; /* illegal instruction */ | |
701 | 691 | gen_op_movl_rN_T0(REG(B7_4)); |
702 | 692 | gen_op_add_rN_T0(REG(0)); |
703 | 693 | gen_op_ldfq_T0_DT0(ctx); |
704 | - gen_op_fmov_DT0_drN(DREG(B11_8)); | |
694 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
705 | 695 | } else { |
706 | 696 | gen_op_movl_rN_T0(REG(B7_4)); |
707 | 697 | gen_op_add_rN_T0(REG(0)); |
... | ... | @@ -711,9 +701,7 @@ void _decode_opc(DisasContext * ctx) |
711 | 701 | return; |
712 | 702 | case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */ |
713 | 703 | if (ctx->fpscr & FPSCR_SZ) { |
714 | - if (ctx->opcode & 0x0010) | |
715 | - break; /* illegal instruction */ | |
716 | - gen_op_fmov_drN_DT0(DREG(B7_4)); | |
704 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
717 | 705 | gen_op_movl_rN_T1(REG(B11_8)); |
718 | 706 | gen_op_add_rN_T1(REG(0)); |
719 | 707 | gen_op_stfq_DT0_T1(ctx); |
... | ... | @@ -755,8 +743,10 @@ void _decode_opc(DisasContext * ctx) |
755 | 743 | ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT(); |
756 | 744 | break; |
757 | 745 | case 0xf004: /* fcmp/eq Rm,Rn */ |
746 | + ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT(); | |
758 | 747 | return; |
759 | 748 | case 0xf005: /* fcmp/gt Rm,Rn */ |
749 | + ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT(); | |
760 | 750 | return; |
761 | 751 | } |
762 | 752 | |
... | ... | @@ -773,11 +763,11 @@ void _decode_opc(DisasContext * ctx) |
773 | 763 | case 0xc900: /* and #imm,R0 */ |
774 | 764 | gen_op_and_imm_rN(B7_0, REG(0)); |
775 | 765 | return; |
776 | - case 0xcd00: /* and.b #imm,@(R0+GBR) */ | |
766 | + case 0xcd00: /* and.b #imm,@(R0,GBR) */ | |
777 | 767 | gen_op_movl_rN_T0(REG(0)); |
778 | 768 | gen_op_addl_GBR_T0(); |
779 | 769 | gen_op_movl_T0_T1(); |
780 | - gen_op_ldb_T0_T0(ctx); | |
770 | + gen_op_ldub_T0_T0(ctx); | |
781 | 771 | gen_op_and_imm_T0(B7_0); |
782 | 772 | gen_op_stb_T0_T1(ctx); |
783 | 773 | return; |
... | ... | @@ -815,13 +805,13 @@ void _decode_opc(DisasContext * ctx) |
815 | 805 | return; |
816 | 806 | case 0xc500: /* mov.w @(disp,GBR),R0 */ |
817 | 807 | gen_op_stc_gbr_T0(); |
818 | - gen_op_addl_imm_T0(B7_0); | |
808 | + gen_op_addl_imm_T0(B7_0 * 2); | |
819 | 809 | gen_op_ldw_T0_T0(ctx); |
820 | 810 | gen_op_movl_T0_rN(REG(0)); |
821 | 811 | return; |
822 | 812 | case 0xc600: /* mov.l @(disp,GBR),R0 */ |
823 | 813 | gen_op_stc_gbr_T0(); |
824 | - gen_op_addl_imm_T0(B7_0); | |
814 | + gen_op_addl_imm_T0(B7_0 * 4); | |
825 | 815 | gen_op_ldl_T0_T0(ctx); |
826 | 816 | gen_op_movl_T0_rN(REG(0)); |
827 | 817 | return; |
... | ... | @@ -834,14 +824,14 @@ void _decode_opc(DisasContext * ctx) |
834 | 824 | return; |
835 | 825 | case 0xc100: /* mov.w R0,@(disp,GBR) */ |
836 | 826 | gen_op_stc_gbr_T0(); |
837 | - gen_op_addl_imm_T0(B7_0); | |
827 | + gen_op_addl_imm_T0(B7_0 * 2); | |
838 | 828 | gen_op_movl_T0_T1(); |
839 | 829 | gen_op_movl_rN_T0(REG(0)); |
840 | 830 | gen_op_stw_T0_T1(ctx); |
841 | 831 | return; |
842 | 832 | case 0xc200: /* mov.l R0,@(disp,GBR) */ |
843 | 833 | gen_op_stc_gbr_T0(); |
844 | - gen_op_addl_imm_T0(B7_0); | |
834 | + gen_op_addl_imm_T0(B7_0 * 4); | |
845 | 835 | gen_op_movl_T0_T1(); |
846 | 836 | gen_op_movl_rN_T0(REG(0)); |
847 | 837 | gen_op_stl_T0_T1(ctx); |
... | ... | @@ -877,11 +867,11 @@ void _decode_opc(DisasContext * ctx) |
877 | 867 | case 0xcb00: /* or #imm,R0 */ |
878 | 868 | gen_op_or_imm_rN(B7_0, REG(0)); |
879 | 869 | return; |
880 | - case 0xcf00: /* or.b #imm,@(R0+GBR) */ | |
870 | + case 0xcf00: /* or.b #imm,@(R0,GBR) */ | |
881 | 871 | gen_op_movl_rN_T0(REG(0)); |
882 | 872 | gen_op_addl_GBR_T0(); |
883 | 873 | gen_op_movl_T0_T1(); |
884 | - gen_op_ldb_T0_T0(ctx); | |
874 | + gen_op_ldub_T0_T0(ctx); | |
885 | 875 | gen_op_or_imm_T0(B7_0); |
886 | 876 | gen_op_stb_T0_T1(ctx); |
887 | 877 | return; |
... | ... | @@ -893,20 +883,20 @@ void _decode_opc(DisasContext * ctx) |
893 | 883 | case 0xc800: /* tst #imm,R0 */ |
894 | 884 | gen_op_tst_imm_rN(B7_0, REG(0)); |
895 | 885 | return; |
896 | - case 0xcc00: /* tst #imm,@(R0+GBR) */ | |
886 | + case 0xcc00: /* tst.b #imm,@(R0,GBR) */ | |
897 | 887 | gen_op_movl_rN_T0(REG(0)); |
898 | 888 | gen_op_addl_GBR_T0(); |
899 | - gen_op_ldb_T0_T0(ctx); | |
889 | + gen_op_ldub_T0_T0(ctx); | |
900 | 890 | gen_op_tst_imm_T0(B7_0); |
901 | 891 | return; |
902 | 892 | case 0xca00: /* xor #imm,R0 */ |
903 | 893 | gen_op_xor_imm_rN(B7_0, REG(0)); |
904 | 894 | return; |
905 | - case 0xce00: /* xor.b #imm,@(R0+GBR) */ | |
895 | + case 0xce00: /* xor.b #imm,@(R0,GBR) */ | |
906 | 896 | gen_op_movl_rN_T0(REG(0)); |
907 | 897 | gen_op_addl_GBR_T0(); |
908 | 898 | gen_op_movl_T0_T1(); |
909 | - gen_op_ldb_T0_T0(ctx); | |
899 | + gen_op_ldub_T0_T0(ctx); | |
910 | 900 | gen_op_xor_imm_T0(B7_0); |
911 | 901 | gen_op_stb_T0_T1(ctx); |
912 | 902 | return; |
... | ... | @@ -1017,7 +1007,7 @@ void _decode_opc(DisasContext * ctx) |
1017 | 1007 | gen_op_movl_rN_T0(REG(B11_8)); |
1018 | 1008 | gen_op_ldl_T0_T0(ctx); |
1019 | 1009 | return; |
1020 | - case 0x00a2: /* ocbp @Rn */ | |
1010 | + case 0x00a3: /* ocbp @Rn */ | |
1021 | 1011 | gen_op_movl_rN_T0(REG(B11_8)); |
1022 | 1012 | gen_op_ldl_T0_T0(ctx); |
1023 | 1013 | return; |
... | ... | @@ -1102,6 +1092,37 @@ void _decode_opc(DisasContext * ctx) |
1102 | 1092 | gen_op_ftrc_FT(); |
1103 | 1093 | } |
1104 | 1094 | return; |
1095 | + case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */ | |
1096 | + gen_op_fneg_frN(FREG(B11_8)); | |
1097 | + return; | |
1098 | + case 0xf05d: /* fabs FRn/DRn */ | |
1099 | + if (ctx->fpscr & FPSCR_PR) { | |
1100 | + if (ctx->opcode & 0x0100) | |
1101 | + break; /* illegal instruction */ | |
1102 | + gen_op_fmov_drN_DT0(DREG(B11_8)); | |
1103 | + gen_op_fabs_DT(); | |
1104 | + gen_op_fmov_DT0_drN(DREG(B11_8)); | |
1105 | + } else { | |
1106 | + gen_op_fmov_frN_FT0(FREG(B11_8)); | |
1107 | + gen_op_fabs_FT(); | |
1108 | + gen_op_fmov_FT0_frN(FREG(B11_8)); | |
1109 | + } | |
1110 | + return; | |
1111 | + case 0xf06d: /* fsqrt FRn */ | |
1112 | + if (ctx->fpscr & FPSCR_PR) { | |
1113 | + if (ctx->opcode & 0x0100) | |
1114 | + break; /* illegal instruction */ | |
1115 | + gen_op_fmov_drN_DT0(FREG(B11_8)); | |
1116 | + gen_op_fsqrt_DT(); | |
1117 | + gen_op_fmov_DT0_drN(FREG(B11_8)); | |
1118 | + } else { | |
1119 | + gen_op_fmov_frN_FT0(FREG(B11_8)); | |
1120 | + gen_op_fsqrt_FT(); | |
1121 | + gen_op_fmov_FT0_frN(FREG(B11_8)); | |
1122 | + } | |
1123 | + return; | |
1124 | + case 0xf07d: /* fsrra FRn */ | |
1125 | + break; | |
1105 | 1126 | case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */ |
1106 | 1127 | if (!(ctx->fpscr & FPSCR_PR)) { |
1107 | 1128 | gen_op_movl_imm_T0(0); |
... | ... | @@ -1116,6 +1137,16 @@ void _decode_opc(DisasContext * ctx) |
1116 | 1137 | return; |
1117 | 1138 | } |
1118 | 1139 | break; |
1140 | + case 0xf0ad: /* fcnvsd FPUL,DRn */ | |
1141 | + gen_op_movl_fpul_FT0(); | |
1142 | + gen_op_fcnvsd_FT_DT(); | |
1143 | + gen_op_fmov_DT0_drN(DREG(B11_8)); | |
1144 | + return; | |
1145 | + case 0xf0bd: /* fcnvds DRn,FPUL */ | |
1146 | + gen_op_fmov_drN_DT0(DREG(B11_8)); | |
1147 | + gen_op_fcnvds_DT_FT(); | |
1148 | + gen_op_movl_FT0_fpul(); | |
1149 | + return; | |
1119 | 1150 | } |
1120 | 1151 | |
1121 | 1152 | fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n", | ... | ... |