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", |