Commit eda9b09b1df1efea4275baadb9743ff5124bd7c2
1 parent
191f9a93
sh4 fmov et al instructions (amatus)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1971 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
303 additions
and
38 deletions
target-sh4/cpu.h
| ... | ... | @@ -27,6 +27,8 @@ |
| 27 | 27 | |
| 28 | 28 | #include "cpu-defs.h" |
| 29 | 29 | |
| 30 | +#include "softfloat.h" | |
| 31 | + | |
| 30 | 32 | #define TARGET_PAGE_BITS 12 /* 4k XXXXX */ |
| 31 | 33 | |
| 32 | 34 | #define SR_MD (1 << 30) |
| ... | ... | @@ -90,6 +92,10 @@ typedef struct CPUSH4State { |
| 90 | 92 | uint32_t fpscr; /* floating point status/control register */ |
| 91 | 93 | uint32_t fpul; /* floating point communication register */ |
| 92 | 94 | |
| 95 | + /* temporary float registers */ | |
| 96 | + float32 ft0, ft1; | |
| 97 | + float64 dt0, dt1; | |
| 98 | + | |
| 93 | 99 | /* Those belong to the specific unit (SH7750) but are handled here */ |
| 94 | 100 | uint32_t mmucr; /* MMU control register */ |
| 95 | 101 | uint32_t pteh; /* page table entry high register */ | ... | ... |
target-sh4/exec.h
| ... | ... | @@ -28,6 +28,11 @@ register uint32_t T0 asm(AREG1); |
| 28 | 28 | register uint32_t T1 asm(AREG2); |
| 29 | 29 | register uint32_t T2 asm(AREG3); |
| 30 | 30 | |
| 31 | +#define FT0 (env->ft0) | |
| 32 | +#define FT1 (env->ft1) | |
| 33 | +#define DT0 (env->dt0) | |
| 34 | +#define DT1 (env->dt1) | |
| 35 | + | |
| 31 | 36 | #include "cpu.h" |
| 32 | 37 | #include "exec-all.h" |
| 33 | 38 | ... | ... |
target-sh4/op.c
| ... | ... | @@ -228,6 +228,18 @@ void OPPROTO op_sett(void) |
| 228 | 228 | RETURN(); |
| 229 | 229 | } |
| 230 | 230 | |
| 231 | +void OPPROTO op_frchg(void) | |
| 232 | +{ | |
| 233 | + env->fpscr ^= FPSCR_FR; | |
| 234 | + RETURN(); | |
| 235 | +} | |
| 236 | + | |
| 237 | +void OPPROTO op_fschg(void) | |
| 238 | +{ | |
| 239 | + env->fpscr ^= FPSCR_SZ; | |
| 240 | + RETURN(); | |
| 241 | +} | |
| 242 | + | |
| 231 | 243 | void OPPROTO op_rte(void) |
| 232 | 244 | { |
| 233 | 245 | env->sr = env->ssr; |
| ... | ... | @@ -465,6 +477,18 @@ void OPPROTO op_ldcl_rMplus_rN_bank(void) |
| 465 | 477 | RETURN(); |
| 466 | 478 | } |
| 467 | 479 | |
| 480 | +void OPPROTO op_ldc_T0_sr(void) | |
| 481 | +{ | |
| 482 | + env->sr = T0 & 0x700083f3; | |
| 483 | + RETURN(); | |
| 484 | +} | |
| 485 | + | |
| 486 | +void OPPROTO op_stc_sr_T0(void) | |
| 487 | +{ | |
| 488 | + T0 = env->sr; | |
| 489 | + RETURN(); | |
| 490 | +} | |
| 491 | + | |
| 468 | 492 | #define LDSTOPS(target,load,store) \ |
| 469 | 493 | void OPPROTO op_##load##_T0_##target (void) \ |
| 470 | 494 | { env ->target = T0; RETURN(); \ |
| ... | ... | @@ -473,7 +497,6 @@ void OPPROTO op_##store##_##target##_T0 (void) \ |
| 473 | 497 | { T0 = env->target; RETURN(); \ |
| 474 | 498 | } \ |
| 475 | 499 | |
| 476 | -LDSTOPS(sr, ldc, stc) | |
| 477 | 500 | LDSTOPS(gbr, ldc, stc) |
| 478 | 501 | LDSTOPS(vbr, ldc, stc) |
| 479 | 502 | LDSTOPS(ssr, ldc, stc) |
| ... | ... | @@ -483,6 +506,19 @@ LDSTOPS(sr, ldc, stc) |
| 483 | 506 | LDSTOPS(mach, lds, sts) |
| 484 | 507 | LDSTOPS(macl, lds, sts) |
| 485 | 508 | LDSTOPS(pr, lds, sts) |
| 509 | + LDSTOPS(fpul, lds, sts) | |
| 510 | + | |
| 511 | +void OPPROTO op_lds_T0_fpscr(void) | |
| 512 | +{ | |
| 513 | + env->fpscr = T0 & 0x003fffff; | |
| 514 | + RETURN(); | |
| 515 | +} | |
| 516 | + | |
| 517 | +void OPPROTO op_sts_fpscr_T0(void) | |
| 518 | +{ | |
| 519 | + T0 = env->fpscr & 0x003fffff; | |
| 520 | + RETURN(); | |
| 521 | +} | |
| 486 | 522 | |
| 487 | 523 | void OPPROTO op_movt_rN(void) |
| 488 | 524 | { |
| ... | ... | @@ -659,6 +695,30 @@ void OPPROTO op_movl_imm_rN(void) |
| 659 | 695 | RETURN(); |
| 660 | 696 | } |
| 661 | 697 | |
| 698 | +void OPPROTO op_fmov_frN_FT0(void) | |
| 699 | +{ | |
| 700 | + FT0 = *(float32 *)&env->fregs[PARAM1]; | |
| 701 | + RETURN(); | |
| 702 | +} | |
| 703 | + | |
| 704 | +void OPPROTO op_fmov_drN_DT0(void) | |
| 705 | +{ | |
| 706 | + DT0 = *(float64 *)&env->fregs[PARAM1]; | |
| 707 | + RETURN(); | |
| 708 | +} | |
| 709 | + | |
| 710 | +void OPPROTO op_fmov_FT0_frN(void) | |
| 711 | +{ | |
| 712 | + *(float32 *)&env->fregs[PARAM1] = FT0; | |
| 713 | + RETURN(); | |
| 714 | +} | |
| 715 | + | |
| 716 | +void OPPROTO op_fmov_DT0_drN(void) | |
| 717 | +{ | |
| 718 | + *(float64 *)&env->fregs[PARAM1] = DT0; | |
| 719 | + RETURN(); | |
| 720 | +} | |
| 721 | + | |
| 662 | 722 | void OPPROTO op_dec1_rN(void) |
| 663 | 723 | { |
| 664 | 724 | env->gregs[PARAM1] -= 1; |
| ... | ... | @@ -677,6 +737,12 @@ void OPPROTO op_dec4_rN(void) |
| 677 | 737 | RETURN(); |
| 678 | 738 | } |
| 679 | 739 | |
| 740 | +void OPPROTO op_dec8_rN(void) | |
| 741 | +{ | |
| 742 | + env->gregs[PARAM1] -= 4; | |
| 743 | + RETURN(); | |
| 744 | +} | |
| 745 | + | |
| 680 | 746 | void OPPROTO op_inc1_rN(void) |
| 681 | 747 | { |
| 682 | 748 | env->gregs[PARAM1] += 1; |
| ... | ... | @@ -695,6 +761,12 @@ void OPPROTO op_inc4_rN(void) |
| 695 | 761 | RETURN(); |
| 696 | 762 | } |
| 697 | 763 | |
| 764 | +void OPPROTO op_inc8_rN(void) | |
| 765 | +{ | |
| 766 | + env->gregs[PARAM1] += 4; | |
| 767 | + RETURN(); | |
| 768 | +} | |
| 769 | + | |
| 698 | 770 | void OPPROTO op_add_T0_rN(void) |
| 699 | 771 | { |
| 700 | 772 | env->gregs[PARAM1] += T0; |
| ... | ... | @@ -779,6 +851,18 @@ void OPPROTO op_movl_T0_T1(void) |
| 779 | 851 | RETURN(); |
| 780 | 852 | } |
| 781 | 853 | |
| 854 | +void OPPROTO op_movl_fpul_FT0(void) | |
| 855 | +{ | |
| 856 | + FT0 = *(float32 *)&env->fpul; | |
| 857 | + RETURN(); | |
| 858 | +} | |
| 859 | + | |
| 860 | +void OPPROTO op_movl_FT0_fpul(void) | |
| 861 | +{ | |
| 862 | + *(float32 *)&env->fpul = FT0; | |
| 863 | + RETURN(); | |
| 864 | +} | |
| 865 | + | |
| 782 | 866 | void OPPROTO op_goto_tb0(void) |
| 783 | 867 | { |
| 784 | 868 | GOTO_TB(op_goto_tb0, PARAM1, 0); | ... | ... |
target-sh4/op_mem.c
| ... | ... | @@ -56,3 +56,23 @@ void glue(op_stl_T0_T1, MEMSUFFIX) (void) { |
| 56 | 56 | glue(stl, MEMSUFFIX) (T1, T0); |
| 57 | 57 | RETURN(); |
| 58 | 58 | } |
| 59 | + | |
| 60 | +void glue(op_ldfl_T0_FT0, MEMSUFFIX) (void) { | |
| 61 | + FT0 = glue(ldfl, MEMSUFFIX) (T0); | |
| 62 | + RETURN(); | |
| 63 | +} | |
| 64 | + | |
| 65 | +void glue(op_stfl_FT0_T1, MEMSUFFIX) (void) { | |
| 66 | + glue(stfl, MEMSUFFIX) (T1, FT0); | |
| 67 | + RETURN(); | |
| 68 | +} | |
| 69 | + | |
| 70 | +void glue(op_ldfq_T0_DT0, MEMSUFFIX) (void) { | |
| 71 | + DT0 = glue(ldfq, MEMSUFFIX) (T0); | |
| 72 | + RETURN(); | |
| 73 | +} | |
| 74 | + | |
| 75 | +void glue(op_stfq_DT0_T1, MEMSUFFIX) (void) { | |
| 76 | + glue(stfq, MEMSUFFIX) (T1, DT0); | |
| 77 | + RETURN(); | |
| 78 | +} | ... | ... |
target-sh4/translate.c
| ... | ... | @@ -54,6 +54,7 @@ typedef struct DisasContext { |
| 54 | 54 | struct TranslationBlock *tb; |
| 55 | 55 | target_ulong pc; |
| 56 | 56 | uint32_t sr; |
| 57 | + uint32_t fpscr; | |
| 57 | 58 | uint16_t opcode; |
| 58 | 59 | uint32_t flags; |
| 59 | 60 | int memidx; |
| ... | ... | @@ -63,46 +64,50 @@ typedef struct DisasContext { |
| 63 | 64 | |
| 64 | 65 | #ifdef CONFIG_USER_ONLY |
| 65 | 66 | |
| 66 | -#define GEN_OP_LD(width) \ | |
| 67 | - void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \ | |
| 68 | - gen_op_ld##width##_T0_T0_raw(); \ | |
| 67 | +#define GEN_OP_LD(width, reg) \ | |
| 68 | + void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \ | |
| 69 | + gen_op_ld##width##_T0_##reg##_raw(); \ | |
| 69 | 70 | } |
| 70 | -#define GEN_OP_ST(width) \ | |
| 71 | - void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \ | |
| 72 | - gen_op_st##width##_T0_T1_raw(); \ | |
| 71 | +#define GEN_OP_ST(width, reg) \ | |
| 72 | + void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \ | |
| 73 | + gen_op_st##width##_##reg##_T1_raw(); \ | |
| 73 | 74 | } |
| 74 | 75 | |
| 75 | 76 | #else |
| 76 | 77 | |
| 77 | -#define GEN_OP_LD(width) \ | |
| 78 | - void gen_op_ld##width##_T0_T0 (DisasContext *ctx) { \ | |
| 79 | - if (ctx->memidx) gen_op_ld##width##_T0_T0_kernel(); \ | |
| 80 | - else gen_op_ld##width##_T0_T0_user();\ | |
| 78 | +#define GEN_OP_LD(width, reg) \ | |
| 79 | + void gen_op_ld##width##_T0_##reg (DisasContext *ctx) { \ | |
| 80 | + if (ctx->memidx) gen_op_ld##width##_T0_##reg##_kernel(); \ | |
| 81 | + else gen_op_ld##width##_T0_##reg##_user();\ | |
| 81 | 82 | } |
| 82 | -#define GEN_OP_ST(width) \ | |
| 83 | - void gen_op_st##width##_T0_T1 (DisasContext *ctx) { \ | |
| 84 | - if (ctx->memidx) gen_op_st##width##_T0_T1_kernel(); \ | |
| 85 | - else gen_op_st##width##_T0_T1_user();\ | |
| 83 | +#define GEN_OP_ST(width, reg) \ | |
| 84 | + void gen_op_st##width##_##reg##_T1 (DisasContext *ctx) { \ | |
| 85 | + if (ctx->memidx) gen_op_st##width##_##reg##_T1_kernel(); \ | |
| 86 | + else gen_op_st##width##_##reg##_T1_user();\ | |
| 86 | 87 | } |
| 87 | 88 | |
| 88 | 89 | #endif |
| 89 | 90 | |
| 90 | -GEN_OP_LD(ub) | |
| 91 | - GEN_OP_LD(b) | |
| 92 | - GEN_OP_ST(b) | |
| 93 | - GEN_OP_LD(uw) | |
| 94 | - GEN_OP_LD(w) | |
| 95 | - GEN_OP_ST(w) | |
| 96 | - GEN_OP_LD(l) | |
| 97 | - GEN_OP_ST(l) | |
| 91 | +GEN_OP_LD(ub, T0) | |
| 92 | +GEN_OP_LD(b, T0) | |
| 93 | +GEN_OP_ST(b, T0) | |
| 94 | +GEN_OP_LD(uw, T0) | |
| 95 | +GEN_OP_LD(w, T0) | |
| 96 | +GEN_OP_ST(w, T0) | |
| 97 | +GEN_OP_LD(l, T0) | |
| 98 | +GEN_OP_ST(l, T0) | |
| 99 | +GEN_OP_LD(fl, FT0) | |
| 100 | +GEN_OP_ST(fl, FT0) | |
| 101 | +GEN_OP_LD(fq, DT0) | |
| 102 | +GEN_OP_ST(fq, DT0) | |
| 98 | 103 | |
| 99 | 104 | void cpu_dump_state(CPUState * env, FILE * f, |
| 100 | 105 | int (*cpu_fprintf) (FILE * f, const char *fmt, ...), |
| 101 | 106 | int flags) |
| 102 | 107 | { |
| 103 | 108 | int i; |
| 104 | - cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x\n", | |
| 105 | - env->pc, env->sr, env->pr); | |
| 109 | + cpu_fprintf(f, "pc=0x%08x sr=0x%08x pr=0x%08x fpscr=0x%08x\n", | |
| 110 | + env->pc, env->sr, env->pr, env->fpscr); | |
| 106 | 111 | for (i = 0; i < 24; i += 4) { |
| 107 | 112 | cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n", |
| 108 | 113 | i, env->gregs[i], i + 1, env->gregs[i + 1], |
| ... | ... | @@ -242,6 +247,10 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) |
| 242 | 247 | #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \ |
| 243 | 248 | ? (x) + 16 : (x)) |
| 244 | 249 | |
| 250 | +#define FREG(x) (ctx->fpscr & FPSCR_FR ? (x) ^ 0x10 : (x)) | |
| 251 | +#define XHACK(x) (((x) & 1 ) << 4 | ((x) & 0xe ) << 1) | |
| 252 | +#define XREG(x) (ctx->fpscr & FPSCR_FR ? XHACK(x) ^ 0x10 : XHACK(x)) | |
| 253 | + | |
| 245 | 254 | #define CHECK_NOT_DELAY_SLOT \ |
| 246 | 255 | if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \ |
| 247 | 256 | {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \ |
| ... | ... | @@ -286,10 +295,12 @@ void decode_opc(DisasContext * ctx) |
| 286 | 295 | gen_op_sett(); |
| 287 | 296 | return; |
| 288 | 297 | case 0xfbfb: /* frchg */ |
| 289 | - assert(0); /* XXXXX */ | |
| 298 | + gen_op_frchg(); | |
| 299 | + ctx->flags |= MODE_CHANGE; | |
| 290 | 300 | return; |
| 291 | 301 | case 0xf3fb: /* fschg */ |
| 292 | - assert(0); /* XXXXX */ | |
| 302 | + gen_op_fschg(); | |
| 303 | + ctx->flags |= MODE_CHANGE; | |
| 293 | 304 | return; |
| 294 | 305 | case 0x0009: /* nop */ |
| 295 | 306 | return; |
| ... | ... | @@ -393,7 +404,7 @@ void decode_opc(DisasContext * ctx) |
| 393 | 404 | gen_op_movl_rN_T1(REG(B11_8)); |
| 394 | 405 | gen_op_stl_T0_T1(ctx); |
| 395 | 406 | return; |
| 396 | - case 0x6004: /* mov.l @Rm+,Rn */ | |
| 407 | + case 0x6004: /* mov.b @Rm+,Rn */ | |
| 397 | 408 | gen_op_movl_rN_T0(REG(B7_4)); |
| 398 | 409 | gen_op_ldb_T0_T0(ctx); |
| 399 | 410 | gen_op_movl_T0_rN(REG(B11_8)); |
| ... | ... | @@ -643,6 +654,134 @@ void decode_opc(DisasContext * ctx) |
| 643 | 654 | gen_op_movl_rN_T0(REG(B7_4)); |
| 644 | 655 | gen_op_xor_T0_rN(REG(B11_8)); |
| 645 | 656 | return; |
| 657 | + case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn */ | |
| 658 | + if (ctx->fpscr & FPSCR_PR) { | |
| 659 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
| 660 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
| 661 | + } else if (ctx->fpscr & FPSCR_SZ) { | |
| 662 | + if (ctx->opcode & 0x0110) | |
| 663 | + break; /* illegal instruction */ | |
| 664 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
| 665 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
| 666 | + } else { | |
| 667 | + gen_op_fmov_frN_FT0(FREG(B7_4)); | |
| 668 | + gen_op_fmov_FT0_frN(FREG(B11_8)); | |
| 669 | + } | |
| 670 | + return; | |
| 671 | + case 0xf00a: /* fmov {F,D,X}Rm,@Rn */ | |
| 672 | + if (ctx->fpscr & FPSCR_PR) { | |
| 673 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
| 674 | + gen_op_movl_rN_T1(REG(B11_8)); | |
| 675 | + gen_op_stfq_DT0_T1(ctx); | |
| 676 | + } else if (ctx->fpscr & FPSCR_SZ) { | |
| 677 | + if (ctx->opcode & 0x0010) | |
| 678 | + break; /* illegal instruction */ | |
| 679 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
| 680 | + gen_op_movl_rN_T1(REG(B11_8)); | |
| 681 | + gen_op_stfq_DT0_T1(ctx); | |
| 682 | + } else { | |
| 683 | + gen_op_fmov_frN_FT0(FREG(B7_4)); | |
| 684 | + gen_op_movl_rN_T1(REG(B11_8)); | |
| 685 | + gen_op_stfl_FT0_T1(ctx); | |
| 686 | + } | |
| 687 | + return; | |
| 688 | + case 0xf008: /* fmov @Rm,{F,D,X}Rn */ | |
| 689 | + if (ctx->fpscr & FPSCR_PR) { | |
| 690 | + gen_op_movl_rN_T0(REG(B7_4)); | |
| 691 | + gen_op_ldfq_T0_DT0(ctx); | |
| 692 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
| 693 | + } else if (ctx->fpscr & FPSCR_SZ) { | |
| 694 | + if (ctx->opcode & 0x0100) | |
| 695 | + break; /* illegal instruction */ | |
| 696 | + gen_op_movl_rN_T0(REG(B7_4)); | |
| 697 | + gen_op_ldfq_T0_DT0(ctx); | |
| 698 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
| 699 | + } else { | |
| 700 | + gen_op_movl_rN_T0(REG(B7_4)); | |
| 701 | + gen_op_ldfl_T0_FT0(ctx); | |
| 702 | + gen_op_fmov_FT0_frN(XREG(B11_8)); | |
| 703 | + } | |
| 704 | + return; | |
| 705 | + case 0xf009: /* fmov @Rm+,{F,D,X}Rn */ | |
| 706 | + if (ctx->fpscr & FPSCR_PR) { | |
| 707 | + gen_op_movl_rN_T0(REG(B7_4)); | |
| 708 | + gen_op_ldfq_T0_DT0(ctx); | |
| 709 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
| 710 | + gen_op_inc8_rN(REG(B7_4)); | |
| 711 | + } else if (ctx->fpscr & FPSCR_SZ) { | |
| 712 | + if (ctx->opcode & 0x0100) | |
| 713 | + break; /* illegal instruction */ | |
| 714 | + gen_op_movl_rN_T0(REG(B7_4)); | |
| 715 | + gen_op_ldfq_T0_DT0(ctx); | |
| 716 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
| 717 | + gen_op_inc8_rN(REG(B7_4)); | |
| 718 | + } else { | |
| 719 | + gen_op_movl_rN_T0(REG(B7_4)); | |
| 720 | + gen_op_ldfl_T0_FT0(ctx); | |
| 721 | + gen_op_fmov_FT0_frN(XREG(B11_8)); | |
| 722 | + gen_op_inc4_rN(REG(B7_4)); | |
| 723 | + } | |
| 724 | + return; | |
| 725 | + case 0xf00b: /* fmov {F,D,X}Rm,@-Rn */ | |
| 726 | + if (ctx->fpscr & FPSCR_PR) { | |
| 727 | + gen_op_dec8_rN(REG(B11_8)); | |
| 728 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
| 729 | + gen_op_movl_rN_T1(REG(B11_8)); | |
| 730 | + gen_op_stfq_DT0_T1(ctx); | |
| 731 | + } else if (ctx->fpscr & FPSCR_SZ) { | |
| 732 | + if (ctx->opcode & 0x0100) | |
| 733 | + break; /* illegal instruction */ | |
| 734 | + gen_op_dec8_rN(REG(B11_8)); | |
| 735 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
| 736 | + gen_op_movl_rN_T1(REG(B11_8)); | |
| 737 | + gen_op_stfq_DT0_T1(ctx); | |
| 738 | + } else { | |
| 739 | + gen_op_dec4_rN(REG(B11_8)); | |
| 740 | + gen_op_fmov_frN_FT0(FREG(B7_4)); | |
| 741 | + gen_op_movl_rN_T1(REG(B11_8)); | |
| 742 | + gen_op_stfl_FT0_T1(ctx); | |
| 743 | + } | |
| 744 | + return; | |
| 745 | + case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm */ | |
| 746 | + if (ctx->fpscr & FPSCR_PR) { | |
| 747 | + gen_op_movl_rN_T0(REG(B7_4)); | |
| 748 | + gen_op_add_rN_T0(REG(0)); | |
| 749 | + gen_op_ldfq_T0_DT0(ctx); | |
| 750 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
| 751 | + } else if (ctx->fpscr & FPSCR_SZ) { | |
| 752 | + if (ctx->opcode & 0x0100) | |
| 753 | + break; /* illegal instruction */ | |
| 754 | + gen_op_movl_rN_T0(REG(B7_4)); | |
| 755 | + gen_op_add_rN_T0(REG(0)); | |
| 756 | + gen_op_ldfq_T0_DT0(ctx); | |
| 757 | + gen_op_fmov_DT0_drN(XREG(B11_8)); | |
| 758 | + } else { | |
| 759 | + gen_op_movl_rN_T0(REG(B7_4)); | |
| 760 | + gen_op_add_rN_T0(REG(0)); | |
| 761 | + gen_op_ldfl_T0_FT0(ctx); | |
| 762 | + gen_op_fmov_FT0_frN(XREG(B11_8)); | |
| 763 | + } | |
| 764 | + return; | |
| 765 | + case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) */ | |
| 766 | + if (ctx->fpscr & FPSCR_PR) { | |
| 767 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
| 768 | + gen_op_movl_rN_T1(REG(B11_8)); | |
| 769 | + gen_op_add_rN_T1(REG(0)); | |
| 770 | + gen_op_stfq_DT0_T1(ctx); | |
| 771 | + } else if (ctx->fpscr & FPSCR_SZ) { | |
| 772 | + if (ctx->opcode & 0x0010) | |
| 773 | + break; /* illegal instruction */ | |
| 774 | + gen_op_fmov_drN_DT0(XREG(B7_4)); | |
| 775 | + gen_op_movl_rN_T1(REG(B11_8)); | |
| 776 | + gen_op_add_rN_T1(REG(0)); | |
| 777 | + gen_op_stfq_DT0_T1(ctx); | |
| 778 | + } else { | |
| 779 | + gen_op_fmov_frN_FT0(FREG(B7_4)); | |
| 780 | + gen_op_movl_rN_T1(REG(B11_8)); | |
| 781 | + gen_op_add_rN_T1(REG(0)); | |
| 782 | + gen_op_stfl_FT0_T1(ctx); | |
| 783 | + } | |
| 784 | + return; | |
| 646 | 785 | } |
| 647 | 786 | |
| 648 | 787 | switch (ctx->opcode & 0xff00) { |
| ... | ... | @@ -869,16 +1008,18 @@ void decode_opc(DisasContext * ctx) |
| 869 | 1008 | gen_op_stl_T0_T1 (ctx); \ |
| 870 | 1009 | return; |
| 871 | 1010 | LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |= |
| 872 | - MODE_CHANGE; | |
| 873 | - ) | |
| 874 | - LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,) | |
| 875 | - LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,) | |
| 876 | - LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,) | |
| 877 | - LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,) | |
| 878 | - LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,) | |
| 879 | - LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,) | |
| 880 | - LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,) | |
| 881 | - LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,) | |
| 1011 | + MODE_CHANGE;) | |
| 1012 | + LDST(gbr, 0x401e, 0x4017, ldc, 0x0012, 0x4013, stc,) | |
| 1013 | + LDST(vbr, 0x402e, 0x4027, ldc, 0x0022, 0x4023, stc,) | |
| 1014 | + LDST(ssr, 0x403e, 0x4037, ldc, 0x0032, 0x4033, stc,) | |
| 1015 | + LDST(spc, 0x404e, 0x4047, ldc, 0x0042, 0x4043, stc,) | |
| 1016 | + LDST(dbr, 0x40fa, 0x40f6, ldc, 0x00fa, 0x40f2, stc,) | |
| 1017 | + LDST(mach, 0x400a, 0x4006, lds, 0x000a, 0x4002, sts,) | |
| 1018 | + LDST(macl, 0x401a, 0x4016, lds, 0x001a, 0x4012, sts,) | |
| 1019 | + LDST(pr, 0x402a, 0x4026, lds, 0x002a, 0x4022, sts,) | |
| 1020 | + LDST(fpul, 0x405a, 0x4056, lds, 0x005a, 0x0052, sts,) | |
| 1021 | + LDST(fpscr, 0x406a, 0x4066, lds, 0x006a, 0x0062, sts, ctx->flags |= | |
| 1022 | + MODE_CHANGE;) | |
| 882 | 1023 | case 0x00c3: /* movca.l R0,@Rm */ |
| 883 | 1024 | gen_op_movl_rN_T0(REG(0)); |
| 884 | 1025 | gen_op_movl_rN_T1(REG(B11_8)); |
| ... | ... | @@ -944,6 +1085,14 @@ void decode_opc(DisasContext * ctx) |
| 944 | 1085 | case 0x401b: /* tas.b @Rn */ |
| 945 | 1086 | gen_op_tasb_rN(REG(B11_8)); |
| 946 | 1087 | return; |
| 1088 | + case 0xf00d: /* fsts FPUL,FRn */ | |
| 1089 | + gen_op_movl_fpul_FT0(); | |
| 1090 | + gen_op_fmov_FT0_frN(FREG(B11_8)); | |
| 1091 | + return; | |
| 1092 | + case 0xf01d: /* flds FRm.FPUL */ | |
| 1093 | + gen_op_fmov_frN_FT0(FREG(B11_8)); | |
| 1094 | + gen_op_movl_FT0_fpul(); | |
| 1095 | + return; | |
| 947 | 1096 | } |
| 948 | 1097 | |
| 949 | 1098 | fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n", |
| ... | ... | @@ -969,6 +1118,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, |
| 969 | 1118 | ctx.flags = env->flags; |
| 970 | 1119 | old_flags = 0; |
| 971 | 1120 | ctx.sr = env->sr; |
| 1121 | + ctx.fpscr = env->fpscr; | |
| 972 | 1122 | ctx.memidx = (env->sr & SR_MD) ? 1 : 0; |
| 973 | 1123 | ctx.delayed_pc = env->delayed_pc; |
| 974 | 1124 | ctx.tb = tb; | ... | ... |