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,13 +45,7 @@ void OPPROTO op_movl_imm_T0(void) | ||
45 | 45 | ||
46 | void OPPROTO op_movl_imm_T1(void) | 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 | RETURN(); | 49 | RETURN(); |
56 | } | 50 | } |
57 | 51 | ||
@@ -240,6 +234,12 @@ void OPPROTO op_xtrct_T0_T1(void) | @@ -240,6 +234,12 @@ void OPPROTO op_xtrct_T0_T1(void) | ||
240 | RETURN(); | 234 | RETURN(); |
241 | } | 235 | } |
242 | 236 | ||
237 | +void OPPROTO op_add_T0_T1(void) | ||
238 | +{ | ||
239 | + T1 += T0; | ||
240 | + RETURN(); | ||
241 | +} | ||
242 | + | ||
243 | void OPPROTO op_addc_T0_T1(void) | 243 | void OPPROTO op_addc_T0_T1(void) |
244 | { | 244 | { |
245 | helper_addc_T0_T1(); | 245 | helper_addc_T0_T1(); |
@@ -355,13 +355,13 @@ void OPPROTO op_mull_T0_T1(void) | @@ -355,13 +355,13 @@ void OPPROTO op_mull_T0_T1(void) | ||
355 | 355 | ||
356 | void OPPROTO op_mulsw_T0_T1(void) | 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 | RETURN(); | 359 | RETURN(); |
360 | } | 360 | } |
361 | 361 | ||
362 | void OPPROTO op_muluw_T0_T1(void) | 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 | RETURN(); | 365 | RETURN(); |
366 | } | 366 | } |
367 | 367 | ||
@@ -382,7 +382,7 @@ void OPPROTO op_shad_T0_T1(void) | @@ -382,7 +382,7 @@ void OPPROTO op_shad_T0_T1(void) | ||
382 | if ((T0 & 0x80000000) == 0) | 382 | if ((T0 & 0x80000000) == 0) |
383 | T1 <<= (T0 & 0x1f); | 383 | T1 <<= (T0 & 0x1f); |
384 | else if ((T0 & 0x1f) == 0) | 384 | else if ((T0 & 0x1f) == 0) |
385 | - T1 = 0; | 385 | + T1 = (T1 & 0x80000000)? 0xffffffff : 0; |
386 | else | 386 | else |
387 | T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1); | 387 | T1 = ((int32_t) T1) >> ((~T0 & 0x1f) + 1); |
388 | RETURN(); | 388 | RETURN(); |
@@ -539,7 +539,7 @@ void OPPROTO op_shal_Rn(void) | @@ -539,7 +539,7 @@ void OPPROTO op_shal_Rn(void) | ||
539 | void OPPROTO op_shar_Rn(void) | 539 | void OPPROTO op_shar_Rn(void) |
540 | { | 540 | { |
541 | cond_t(env->gregs[PARAM1] & 1); | 541 | cond_t(env->gregs[PARAM1] & 1); |
542 | - env->gregs[PARAM1] >>= 1; | 542 | + *(int32_t *)&env->gregs[PARAM1] >>= 1; |
543 | RETURN(); | 543 | RETURN(); |
544 | } | 544 | } |
545 | 545 | ||
@@ -767,6 +767,30 @@ void OPPROTO op_fdiv_DT(void) | @@ -767,6 +767,30 @@ void OPPROTO op_fdiv_DT(void) | ||
767 | RETURN(); | 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 | void OPPROTO op_float_FT(void) | 794 | void OPPROTO op_float_FT(void) |
771 | { | 795 | { |
772 | FT0 = int32_to_float32(env->fpul, &env->fp_status); | 796 | FT0 = int32_to_float32(env->fpul, &env->fp_status); |
@@ -791,9 +815,51 @@ void OPPROTO op_ftrc_DT(void) | @@ -791,9 +815,51 @@ void OPPROTO op_ftrc_DT(void) | ||
791 | RETURN(); | 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 | void OPPROTO op_fmov_T0_frN(void) | 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 | RETURN(); | 863 | RETURN(); |
798 | } | 864 | } |
799 | 865 |
target-sh4/translate.c
@@ -268,11 +268,11 @@ void _decode_opc(DisasContext * ctx) | @@ -268,11 +268,11 @@ void _decode_opc(DisasContext * ctx) | ||
268 | case 0x0018: /* sett */ | 268 | case 0x0018: /* sett */ |
269 | gen_op_sett(); | 269 | gen_op_sett(); |
270 | return; | 270 | return; |
271 | - case 0xfbfb: /* frchg */ | 271 | + case 0xfbfd: /* frchg */ |
272 | gen_op_frchg(); | 272 | gen_op_frchg(); |
273 | ctx->bstate = BS_STOP; | 273 | ctx->bstate = BS_STOP; |
274 | return; | 274 | return; |
275 | - case 0xf3fb: /* fschg */ | 275 | + case 0xf3fd: /* fschg */ |
276 | gen_op_fschg(); | 276 | gen_op_fschg(); |
277 | ctx->bstate = BS_STOP; | 277 | ctx->bstate = BS_STOP; |
278 | return; | 278 | return; |
@@ -296,7 +296,7 @@ void _decode_opc(DisasContext * ctx) | @@ -296,7 +296,7 @@ void _decode_opc(DisasContext * ctx) | ||
296 | gen_op_ldl_T0_T0(ctx); | 296 | gen_op_ldl_T0_T0(ctx); |
297 | gen_op_movl_T0_rN(REG(B11_8)); | 297 | gen_op_movl_T0_rN(REG(B11_8)); |
298 | return; | 298 | return; |
299 | - case 0xe000: /* mov.l #imm,Rn */ | 299 | + case 0xe000: /* mov #imm,Rn */ |
300 | gen_op_movl_imm_rN(B7_0s, REG(B11_8)); | 300 | gen_op_movl_imm_rN(B7_0s, REG(B11_8)); |
301 | return; | 301 | return; |
302 | case 0x9000: /* mov.w @(disp,PC),Rn */ | 302 | case 0x9000: /* mov.w @(disp,PC),Rn */ |
@@ -309,7 +309,7 @@ void _decode_opc(DisasContext * ctx) | @@ -309,7 +309,7 @@ void _decode_opc(DisasContext * ctx) | ||
309 | gen_op_ldl_T0_T0(ctx); | 309 | gen_op_ldl_T0_T0(ctx); |
310 | gen_op_movl_T0_rN(REG(B11_8)); | 310 | gen_op_movl_T0_rN(REG(B11_8)); |
311 | return; | 311 | return; |
312 | - case 0x7000: /* add.l #imm,Rn */ | 312 | + case 0x7000: /* add #imm,Rn */ |
313 | gen_op_add_imm_rN(B7_0s, REG(B11_8)); | 313 | gen_op_add_imm_rN(B7_0s, REG(B11_8)); |
314 | return; | 314 | return; |
315 | case 0xa000: /* bra disp */ | 315 | case 0xa000: /* bra disp */ |
@@ -361,20 +361,20 @@ void _decode_opc(DisasContext * ctx) | @@ -361,20 +361,20 @@ void _decode_opc(DisasContext * ctx) | ||
361 | gen_op_movl_T0_rN(REG(B11_8)); | 361 | gen_op_movl_T0_rN(REG(B11_8)); |
362 | return; | 362 | return; |
363 | case 0x2004: /* mov.b Rm,@-Rn */ | 363 | case 0x2004: /* mov.b Rm,@-Rn */ |
364 | - gen_op_dec1_rN(REG(B11_8)); | ||
365 | gen_op_movl_rN_T0(REG(B7_4)); | 364 | gen_op_movl_rN_T0(REG(B7_4)); |
365 | + gen_op_dec1_rN(REG(B11_8)); | ||
366 | gen_op_movl_rN_T1(REG(B11_8)); | 366 | gen_op_movl_rN_T1(REG(B11_8)); |
367 | gen_op_stb_T0_T1(ctx); | 367 | gen_op_stb_T0_T1(ctx); |
368 | return; | 368 | return; |
369 | case 0x2005: /* mov.w Rm,@-Rn */ | 369 | case 0x2005: /* mov.w Rm,@-Rn */ |
370 | - gen_op_dec2_rN(REG(B11_8)); | ||
371 | gen_op_movl_rN_T0(REG(B7_4)); | 370 | gen_op_movl_rN_T0(REG(B7_4)); |
371 | + gen_op_dec2_rN(REG(B11_8)); | ||
372 | gen_op_movl_rN_T1(REG(B11_8)); | 372 | gen_op_movl_rN_T1(REG(B11_8)); |
373 | gen_op_stw_T0_T1(ctx); | 373 | gen_op_stw_T0_T1(ctx); |
374 | return; | 374 | return; |
375 | case 0x2006: /* mov.l Rm,@-Rn */ | 375 | case 0x2006: /* mov.l Rm,@-Rn */ |
376 | - gen_op_dec4_rN(REG(B11_8)); | ||
377 | gen_op_movl_rN_T0(REG(B7_4)); | 376 | gen_op_movl_rN_T0(REG(B7_4)); |
377 | + gen_op_dec4_rN(REG(B11_8)); | ||
378 | gen_op_movl_rN_T1(REG(B11_8)); | 378 | gen_op_movl_rN_T1(REG(B11_8)); |
379 | gen_op_stl_T0_T1(ctx); | 379 | gen_op_stl_T0_T1(ctx); |
380 | return; | 380 | return; |
@@ -382,19 +382,22 @@ void _decode_opc(DisasContext * ctx) | @@ -382,19 +382,22 @@ void _decode_opc(DisasContext * ctx) | ||
382 | gen_op_movl_rN_T0(REG(B7_4)); | 382 | gen_op_movl_rN_T0(REG(B7_4)); |
383 | gen_op_ldb_T0_T0(ctx); | 383 | gen_op_ldb_T0_T0(ctx); |
384 | gen_op_movl_T0_rN(REG(B11_8)); | 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 | return; | 387 | return; |
387 | case 0x6005: /* mov.w @Rm+,Rn */ | 388 | case 0x6005: /* mov.w @Rm+,Rn */ |
388 | gen_op_movl_rN_T0(REG(B7_4)); | 389 | gen_op_movl_rN_T0(REG(B7_4)); |
389 | gen_op_ldw_T0_T0(ctx); | 390 | gen_op_ldw_T0_T0(ctx); |
390 | gen_op_movl_T0_rN(REG(B11_8)); | 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 | return; | 394 | return; |
393 | case 0x6006: /* mov.l @Rm+,Rn */ | 395 | case 0x6006: /* mov.l @Rm+,Rn */ |
394 | gen_op_movl_rN_T0(REG(B7_4)); | 396 | gen_op_movl_rN_T0(REG(B7_4)); |
395 | gen_op_ldl_T0_T0(ctx); | 397 | gen_op_ldl_T0_T0(ctx); |
396 | gen_op_movl_T0_rN(REG(B11_8)); | 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 | return; | 401 | return; |
399 | case 0x0004: /* mov.b Rm,@(R0,Rn) */ | 402 | case 0x0004: /* mov.b Rm,@(R0,Rn) */ |
400 | gen_op_movl_rN_T0(REG(B7_4)); | 403 | gen_op_movl_rN_T0(REG(B7_4)); |
@@ -502,7 +505,6 @@ void _decode_opc(DisasContext * ctx) | @@ -502,7 +505,6 @@ void _decode_opc(DisasContext * ctx) | ||
502 | gen_op_movl_rN_T0(REG(B7_4)); | 505 | gen_op_movl_rN_T0(REG(B7_4)); |
503 | gen_op_movl_rN_T1(REG(B11_8)); | 506 | gen_op_movl_rN_T1(REG(B11_8)); |
504 | gen_op_div0s_T0_T1(); | 507 | gen_op_div0s_T0_T1(); |
505 | - gen_op_movl_T1_rN(REG(B11_8)); | ||
506 | return; | 508 | return; |
507 | case 0x3004: /* div1 Rm,Rn */ | 509 | case 0x3004: /* div1 Rm,Rn */ |
508 | gen_op_movl_rN_T0(REG(B7_4)); | 510 | gen_op_movl_rN_T0(REG(B7_4)); |
@@ -536,25 +538,25 @@ void _decode_opc(DisasContext * ctx) | @@ -536,25 +538,25 @@ void _decode_opc(DisasContext * ctx) | ||
536 | gen_op_movuw_rN_T0(REG(B7_4)); | 538 | gen_op_movuw_rN_T0(REG(B7_4)); |
537 | gen_op_movl_T0_rN(REG(B11_8)); | 539 | gen_op_movl_T0_rN(REG(B11_8)); |
538 | return; | 540 | return; |
539 | - case 0x000f: /* mac.l @Rm+,@Rn- */ | 541 | + case 0x000f: /* mac.l @Rm+,@Rn+ */ |
540 | gen_op_movl_rN_T0(REG(B11_8)); | 542 | gen_op_movl_rN_T0(REG(B11_8)); |
541 | gen_op_ldl_T0_T0(ctx); | 543 | gen_op_ldl_T0_T0(ctx); |
542 | gen_op_movl_T0_T1(); | 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 | gen_op_ldl_T0_T0(ctx); | 547 | gen_op_ldl_T0_T0(ctx); |
545 | gen_op_macl_T0_T1(); | 548 | gen_op_macl_T0_T1(); |
546 | gen_op_inc4_rN(REG(B7_4)); | 549 | gen_op_inc4_rN(REG(B7_4)); |
547 | - gen_op_inc4_rN(REG(B11_8)); | ||
548 | return; | 550 | return; |
549 | case 0x400f: /* mac.w @Rm+,@Rn+ */ | 551 | case 0x400f: /* mac.w @Rm+,@Rn+ */ |
550 | gen_op_movl_rN_T0(REG(B11_8)); | 552 | gen_op_movl_rN_T0(REG(B11_8)); |
551 | gen_op_ldl_T0_T0(ctx); | 553 | gen_op_ldl_T0_T0(ctx); |
552 | gen_op_movl_T0_T1(); | 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 | gen_op_ldl_T0_T0(ctx); | 557 | gen_op_ldl_T0_T0(ctx); |
555 | gen_op_macw_T0_T1(); | 558 | gen_op_macw_T0_T1(); |
556 | gen_op_inc2_rN(REG(B7_4)); | 559 | gen_op_inc2_rN(REG(B7_4)); |
557 | - gen_op_inc2_rN(REG(B11_8)); | ||
558 | return; | 560 | return; |
559 | case 0x0007: /* mul.l Rm,Rn */ | 561 | case 0x0007: /* mul.l Rm,Rn */ |
560 | gen_op_movl_rN_T0(REG(B7_4)); | 562 | gen_op_movl_rN_T0(REG(B7_4)); |
@@ -629,10 +631,8 @@ void _decode_opc(DisasContext * ctx) | @@ -629,10 +631,8 @@ void _decode_opc(DisasContext * ctx) | ||
629 | return; | 631 | return; |
630 | case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */ | 632 | case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */ |
631 | if (ctx->fpscr & FPSCR_SZ) { | 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 | } else { | 636 | } else { |
637 | gen_op_fmov_frN_FT0(FREG(B7_4)); | 637 | gen_op_fmov_frN_FT0(FREG(B7_4)); |
638 | gen_op_fmov_FT0_frN(FREG(B11_8)); | 638 | gen_op_fmov_FT0_frN(FREG(B11_8)); |
@@ -640,9 +640,7 @@ void _decode_opc(DisasContext * ctx) | @@ -640,9 +640,7 @@ void _decode_opc(DisasContext * ctx) | ||
640 | return; | 640 | return; |
641 | case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */ | 641 | case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */ |
642 | if (ctx->fpscr & FPSCR_SZ) { | 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 | gen_op_movl_rN_T1(REG(B11_8)); | 644 | gen_op_movl_rN_T1(REG(B11_8)); |
647 | gen_op_stfq_DT0_T1(ctx); | 645 | gen_op_stfq_DT0_T1(ctx); |
648 | } else { | 646 | } else { |
@@ -653,11 +651,9 @@ void _decode_opc(DisasContext * ctx) | @@ -653,11 +651,9 @@ void _decode_opc(DisasContext * ctx) | ||
653 | return; | 651 | return; |
654 | case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */ | 652 | case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */ |
655 | if (ctx->fpscr & FPSCR_SZ) { | 653 | if (ctx->fpscr & FPSCR_SZ) { |
656 | - if (ctx->opcode & 0x0100) | ||
657 | - break; /* illegal instruction */ | ||
658 | gen_op_movl_rN_T0(REG(B7_4)); | 654 | gen_op_movl_rN_T0(REG(B7_4)); |
659 | gen_op_ldfq_T0_DT0(ctx); | 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 | } else { | 657 | } else { |
662 | gen_op_movl_rN_T0(REG(B7_4)); | 658 | gen_op_movl_rN_T0(REG(B7_4)); |
663 | gen_op_ldfl_T0_FT0(ctx); | 659 | gen_op_ldfl_T0_FT0(ctx); |
@@ -666,11 +662,9 @@ void _decode_opc(DisasContext * ctx) | @@ -666,11 +662,9 @@ void _decode_opc(DisasContext * ctx) | ||
666 | return; | 662 | return; |
667 | case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */ | 663 | case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */ |
668 | if (ctx->fpscr & FPSCR_SZ) { | 664 | if (ctx->fpscr & FPSCR_SZ) { |
669 | - if (ctx->opcode & 0x0100) | ||
670 | - break; /* illegal instruction */ | ||
671 | gen_op_movl_rN_T0(REG(B7_4)); | 665 | gen_op_movl_rN_T0(REG(B7_4)); |
672 | gen_op_ldfq_T0_DT0(ctx); | 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 | gen_op_inc8_rN(REG(B7_4)); | 668 | gen_op_inc8_rN(REG(B7_4)); |
675 | } else { | 669 | } else { |
676 | gen_op_movl_rN_T0(REG(B7_4)); | 670 | gen_op_movl_rN_T0(REG(B7_4)); |
@@ -681,10 +675,8 @@ void _decode_opc(DisasContext * ctx) | @@ -681,10 +675,8 @@ void _decode_opc(DisasContext * ctx) | ||
681 | return; | 675 | return; |
682 | case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */ | 676 | case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */ |
683 | if (ctx->fpscr & FPSCR_SZ) { | 677 | if (ctx->fpscr & FPSCR_SZ) { |
684 | - if (ctx->opcode & 0x0100) | ||
685 | - break; /* illegal instruction */ | ||
686 | gen_op_dec8_rN(REG(B11_8)); | 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 | gen_op_movl_rN_T1(REG(B11_8)); | 680 | gen_op_movl_rN_T1(REG(B11_8)); |
689 | gen_op_stfq_DT0_T1(ctx); | 681 | gen_op_stfq_DT0_T1(ctx); |
690 | } else { | 682 | } else { |
@@ -696,12 +688,10 @@ void _decode_opc(DisasContext * ctx) | @@ -696,12 +688,10 @@ void _decode_opc(DisasContext * ctx) | ||
696 | return; | 688 | return; |
697 | case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */ | 689 | case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */ |
698 | if (ctx->fpscr & FPSCR_SZ) { | 690 | if (ctx->fpscr & FPSCR_SZ) { |
699 | - if (ctx->opcode & 0x0100) | ||
700 | - break; /* illegal instruction */ | ||
701 | gen_op_movl_rN_T0(REG(B7_4)); | 691 | gen_op_movl_rN_T0(REG(B7_4)); |
702 | gen_op_add_rN_T0(REG(0)); | 692 | gen_op_add_rN_T0(REG(0)); |
703 | gen_op_ldfq_T0_DT0(ctx); | 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 | } else { | 695 | } else { |
706 | gen_op_movl_rN_T0(REG(B7_4)); | 696 | gen_op_movl_rN_T0(REG(B7_4)); |
707 | gen_op_add_rN_T0(REG(0)); | 697 | gen_op_add_rN_T0(REG(0)); |
@@ -711,9 +701,7 @@ void _decode_opc(DisasContext * ctx) | @@ -711,9 +701,7 @@ void _decode_opc(DisasContext * ctx) | ||
711 | return; | 701 | return; |
712 | case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */ | 702 | case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */ |
713 | if (ctx->fpscr & FPSCR_SZ) { | 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 | gen_op_movl_rN_T1(REG(B11_8)); | 705 | gen_op_movl_rN_T1(REG(B11_8)); |
718 | gen_op_add_rN_T1(REG(0)); | 706 | gen_op_add_rN_T1(REG(0)); |
719 | gen_op_stfq_DT0_T1(ctx); | 707 | gen_op_stfq_DT0_T1(ctx); |
@@ -755,8 +743,10 @@ void _decode_opc(DisasContext * ctx) | @@ -755,8 +743,10 @@ void _decode_opc(DisasContext * ctx) | ||
755 | ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT(); | 743 | ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT(); |
756 | break; | 744 | break; |
757 | case 0xf004: /* fcmp/eq Rm,Rn */ | 745 | case 0xf004: /* fcmp/eq Rm,Rn */ |
746 | + ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT(); | ||
758 | return; | 747 | return; |
759 | case 0xf005: /* fcmp/gt Rm,Rn */ | 748 | case 0xf005: /* fcmp/gt Rm,Rn */ |
749 | + ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT(); | ||
760 | return; | 750 | return; |
761 | } | 751 | } |
762 | 752 | ||
@@ -773,11 +763,11 @@ void _decode_opc(DisasContext * ctx) | @@ -773,11 +763,11 @@ void _decode_opc(DisasContext * ctx) | ||
773 | case 0xc900: /* and #imm,R0 */ | 763 | case 0xc900: /* and #imm,R0 */ |
774 | gen_op_and_imm_rN(B7_0, REG(0)); | 764 | gen_op_and_imm_rN(B7_0, REG(0)); |
775 | return; | 765 | return; |
776 | - case 0xcd00: /* and.b #imm,@(R0+GBR) */ | 766 | + case 0xcd00: /* and.b #imm,@(R0,GBR) */ |
777 | gen_op_movl_rN_T0(REG(0)); | 767 | gen_op_movl_rN_T0(REG(0)); |
778 | gen_op_addl_GBR_T0(); | 768 | gen_op_addl_GBR_T0(); |
779 | gen_op_movl_T0_T1(); | 769 | gen_op_movl_T0_T1(); |
780 | - gen_op_ldb_T0_T0(ctx); | 770 | + gen_op_ldub_T0_T0(ctx); |
781 | gen_op_and_imm_T0(B7_0); | 771 | gen_op_and_imm_T0(B7_0); |
782 | gen_op_stb_T0_T1(ctx); | 772 | gen_op_stb_T0_T1(ctx); |
783 | return; | 773 | return; |
@@ -815,13 +805,13 @@ void _decode_opc(DisasContext * ctx) | @@ -815,13 +805,13 @@ void _decode_opc(DisasContext * ctx) | ||
815 | return; | 805 | return; |
816 | case 0xc500: /* mov.w @(disp,GBR),R0 */ | 806 | case 0xc500: /* mov.w @(disp,GBR),R0 */ |
817 | gen_op_stc_gbr_T0(); | 807 | gen_op_stc_gbr_T0(); |
818 | - gen_op_addl_imm_T0(B7_0); | 808 | + gen_op_addl_imm_T0(B7_0 * 2); |
819 | gen_op_ldw_T0_T0(ctx); | 809 | gen_op_ldw_T0_T0(ctx); |
820 | gen_op_movl_T0_rN(REG(0)); | 810 | gen_op_movl_T0_rN(REG(0)); |
821 | return; | 811 | return; |
822 | case 0xc600: /* mov.l @(disp,GBR),R0 */ | 812 | case 0xc600: /* mov.l @(disp,GBR),R0 */ |
823 | gen_op_stc_gbr_T0(); | 813 | gen_op_stc_gbr_T0(); |
824 | - gen_op_addl_imm_T0(B7_0); | 814 | + gen_op_addl_imm_T0(B7_0 * 4); |
825 | gen_op_ldl_T0_T0(ctx); | 815 | gen_op_ldl_T0_T0(ctx); |
826 | gen_op_movl_T0_rN(REG(0)); | 816 | gen_op_movl_T0_rN(REG(0)); |
827 | return; | 817 | return; |
@@ -834,14 +824,14 @@ void _decode_opc(DisasContext * ctx) | @@ -834,14 +824,14 @@ void _decode_opc(DisasContext * ctx) | ||
834 | return; | 824 | return; |
835 | case 0xc100: /* mov.w R0,@(disp,GBR) */ | 825 | case 0xc100: /* mov.w R0,@(disp,GBR) */ |
836 | gen_op_stc_gbr_T0(); | 826 | gen_op_stc_gbr_T0(); |
837 | - gen_op_addl_imm_T0(B7_0); | 827 | + gen_op_addl_imm_T0(B7_0 * 2); |
838 | gen_op_movl_T0_T1(); | 828 | gen_op_movl_T0_T1(); |
839 | gen_op_movl_rN_T0(REG(0)); | 829 | gen_op_movl_rN_T0(REG(0)); |
840 | gen_op_stw_T0_T1(ctx); | 830 | gen_op_stw_T0_T1(ctx); |
841 | return; | 831 | return; |
842 | case 0xc200: /* mov.l R0,@(disp,GBR) */ | 832 | case 0xc200: /* mov.l R0,@(disp,GBR) */ |
843 | gen_op_stc_gbr_T0(); | 833 | gen_op_stc_gbr_T0(); |
844 | - gen_op_addl_imm_T0(B7_0); | 834 | + gen_op_addl_imm_T0(B7_0 * 4); |
845 | gen_op_movl_T0_T1(); | 835 | gen_op_movl_T0_T1(); |
846 | gen_op_movl_rN_T0(REG(0)); | 836 | gen_op_movl_rN_T0(REG(0)); |
847 | gen_op_stl_T0_T1(ctx); | 837 | gen_op_stl_T0_T1(ctx); |
@@ -877,11 +867,11 @@ void _decode_opc(DisasContext * ctx) | @@ -877,11 +867,11 @@ void _decode_opc(DisasContext * ctx) | ||
877 | case 0xcb00: /* or #imm,R0 */ | 867 | case 0xcb00: /* or #imm,R0 */ |
878 | gen_op_or_imm_rN(B7_0, REG(0)); | 868 | gen_op_or_imm_rN(B7_0, REG(0)); |
879 | return; | 869 | return; |
880 | - case 0xcf00: /* or.b #imm,@(R0+GBR) */ | 870 | + case 0xcf00: /* or.b #imm,@(R0,GBR) */ |
881 | gen_op_movl_rN_T0(REG(0)); | 871 | gen_op_movl_rN_T0(REG(0)); |
882 | gen_op_addl_GBR_T0(); | 872 | gen_op_addl_GBR_T0(); |
883 | gen_op_movl_T0_T1(); | 873 | gen_op_movl_T0_T1(); |
884 | - gen_op_ldb_T0_T0(ctx); | 874 | + gen_op_ldub_T0_T0(ctx); |
885 | gen_op_or_imm_T0(B7_0); | 875 | gen_op_or_imm_T0(B7_0); |
886 | gen_op_stb_T0_T1(ctx); | 876 | gen_op_stb_T0_T1(ctx); |
887 | return; | 877 | return; |
@@ -893,20 +883,20 @@ void _decode_opc(DisasContext * ctx) | @@ -893,20 +883,20 @@ void _decode_opc(DisasContext * ctx) | ||
893 | case 0xc800: /* tst #imm,R0 */ | 883 | case 0xc800: /* tst #imm,R0 */ |
894 | gen_op_tst_imm_rN(B7_0, REG(0)); | 884 | gen_op_tst_imm_rN(B7_0, REG(0)); |
895 | return; | 885 | return; |
896 | - case 0xcc00: /* tst #imm,@(R0+GBR) */ | 886 | + case 0xcc00: /* tst.b #imm,@(R0,GBR) */ |
897 | gen_op_movl_rN_T0(REG(0)); | 887 | gen_op_movl_rN_T0(REG(0)); |
898 | gen_op_addl_GBR_T0(); | 888 | gen_op_addl_GBR_T0(); |
899 | - gen_op_ldb_T0_T0(ctx); | 889 | + gen_op_ldub_T0_T0(ctx); |
900 | gen_op_tst_imm_T0(B7_0); | 890 | gen_op_tst_imm_T0(B7_0); |
901 | return; | 891 | return; |
902 | case 0xca00: /* xor #imm,R0 */ | 892 | case 0xca00: /* xor #imm,R0 */ |
903 | gen_op_xor_imm_rN(B7_0, REG(0)); | 893 | gen_op_xor_imm_rN(B7_0, REG(0)); |
904 | return; | 894 | return; |
905 | - case 0xce00: /* xor.b #imm,@(R0+GBR) */ | 895 | + case 0xce00: /* xor.b #imm,@(R0,GBR) */ |
906 | gen_op_movl_rN_T0(REG(0)); | 896 | gen_op_movl_rN_T0(REG(0)); |
907 | gen_op_addl_GBR_T0(); | 897 | gen_op_addl_GBR_T0(); |
908 | gen_op_movl_T0_T1(); | 898 | gen_op_movl_T0_T1(); |
909 | - gen_op_ldb_T0_T0(ctx); | 899 | + gen_op_ldub_T0_T0(ctx); |
910 | gen_op_xor_imm_T0(B7_0); | 900 | gen_op_xor_imm_T0(B7_0); |
911 | gen_op_stb_T0_T1(ctx); | 901 | gen_op_stb_T0_T1(ctx); |
912 | return; | 902 | return; |
@@ -1017,7 +1007,7 @@ void _decode_opc(DisasContext * ctx) | @@ -1017,7 +1007,7 @@ void _decode_opc(DisasContext * ctx) | ||
1017 | gen_op_movl_rN_T0(REG(B11_8)); | 1007 | gen_op_movl_rN_T0(REG(B11_8)); |
1018 | gen_op_ldl_T0_T0(ctx); | 1008 | gen_op_ldl_T0_T0(ctx); |
1019 | return; | 1009 | return; |
1020 | - case 0x00a2: /* ocbp @Rn */ | 1010 | + case 0x00a3: /* ocbp @Rn */ |
1021 | gen_op_movl_rN_T0(REG(B11_8)); | 1011 | gen_op_movl_rN_T0(REG(B11_8)); |
1022 | gen_op_ldl_T0_T0(ctx); | 1012 | gen_op_ldl_T0_T0(ctx); |
1023 | return; | 1013 | return; |
@@ -1102,6 +1092,37 @@ void _decode_opc(DisasContext * ctx) | @@ -1102,6 +1092,37 @@ void _decode_opc(DisasContext * ctx) | ||
1102 | gen_op_ftrc_FT(); | 1092 | gen_op_ftrc_FT(); |
1103 | } | 1093 | } |
1104 | return; | 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 | case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */ | 1126 | case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */ |
1106 | if (!(ctx->fpscr & FPSCR_PR)) { | 1127 | if (!(ctx->fpscr & FPSCR_PR)) { |
1107 | gen_op_movl_imm_T0(0); | 1128 | gen_op_movl_imm_T0(0); |
@@ -1116,6 +1137,16 @@ void _decode_opc(DisasContext * ctx) | @@ -1116,6 +1137,16 @@ void _decode_opc(DisasContext * ctx) | ||
1116 | return; | 1137 | return; |
1117 | } | 1138 | } |
1118 | break; | 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 | fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n", | 1152 | fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n", |