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,6 +27,8 @@ | ||
| 27 | 27 | ||
| 28 | #include "cpu-defs.h" | 28 | #include "cpu-defs.h" |
| 29 | 29 | ||
| 30 | +#include "softfloat.h" | ||
| 31 | + | ||
| 30 | #define TARGET_PAGE_BITS 12 /* 4k XXXXX */ | 32 | #define TARGET_PAGE_BITS 12 /* 4k XXXXX */ |
| 31 | 33 | ||
| 32 | #define SR_MD (1 << 30) | 34 | #define SR_MD (1 << 30) |
| @@ -90,6 +92,10 @@ typedef struct CPUSH4State { | @@ -90,6 +92,10 @@ typedef struct CPUSH4State { | ||
| 90 | uint32_t fpscr; /* floating point status/control register */ | 92 | uint32_t fpscr; /* floating point status/control register */ |
| 91 | uint32_t fpul; /* floating point communication register */ | 93 | uint32_t fpul; /* floating point communication register */ |
| 92 | 94 | ||
| 95 | + /* temporary float registers */ | ||
| 96 | + float32 ft0, ft1; | ||
| 97 | + float64 dt0, dt1; | ||
| 98 | + | ||
| 93 | /* Those belong to the specific unit (SH7750) but are handled here */ | 99 | /* Those belong to the specific unit (SH7750) but are handled here */ |
| 94 | uint32_t mmucr; /* MMU control register */ | 100 | uint32_t mmucr; /* MMU control register */ |
| 95 | uint32_t pteh; /* page table entry high register */ | 101 | uint32_t pteh; /* page table entry high register */ |
target-sh4/exec.h
| @@ -28,6 +28,11 @@ register uint32_t T0 asm(AREG1); | @@ -28,6 +28,11 @@ register uint32_t T0 asm(AREG1); | ||
| 28 | register uint32_t T1 asm(AREG2); | 28 | register uint32_t T1 asm(AREG2); |
| 29 | register uint32_t T2 asm(AREG3); | 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 | #include "cpu.h" | 36 | #include "cpu.h" |
| 32 | #include "exec-all.h" | 37 | #include "exec-all.h" |
| 33 | 38 |
target-sh4/op.c
| @@ -228,6 +228,18 @@ void OPPROTO op_sett(void) | @@ -228,6 +228,18 @@ void OPPROTO op_sett(void) | ||
| 228 | RETURN(); | 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 | void OPPROTO op_rte(void) | 243 | void OPPROTO op_rte(void) |
| 232 | { | 244 | { |
| 233 | env->sr = env->ssr; | 245 | env->sr = env->ssr; |
| @@ -465,6 +477,18 @@ void OPPROTO op_ldcl_rMplus_rN_bank(void) | @@ -465,6 +477,18 @@ void OPPROTO op_ldcl_rMplus_rN_bank(void) | ||
| 465 | RETURN(); | 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 | #define LDSTOPS(target,load,store) \ | 492 | #define LDSTOPS(target,load,store) \ |
| 469 | void OPPROTO op_##load##_T0_##target (void) \ | 493 | void OPPROTO op_##load##_T0_##target (void) \ |
| 470 | { env ->target = T0; RETURN(); \ | 494 | { env ->target = T0; RETURN(); \ |
| @@ -473,7 +497,6 @@ void OPPROTO op_##store##_##target##_T0 (void) \ | @@ -473,7 +497,6 @@ void OPPROTO op_##store##_##target##_T0 (void) \ | ||
| 473 | { T0 = env->target; RETURN(); \ | 497 | { T0 = env->target; RETURN(); \ |
| 474 | } \ | 498 | } \ |
| 475 | 499 | ||
| 476 | -LDSTOPS(sr, ldc, stc) | ||
| 477 | LDSTOPS(gbr, ldc, stc) | 500 | LDSTOPS(gbr, ldc, stc) |
| 478 | LDSTOPS(vbr, ldc, stc) | 501 | LDSTOPS(vbr, ldc, stc) |
| 479 | LDSTOPS(ssr, ldc, stc) | 502 | LDSTOPS(ssr, ldc, stc) |
| @@ -483,6 +506,19 @@ LDSTOPS(sr, ldc, stc) | @@ -483,6 +506,19 @@ LDSTOPS(sr, ldc, stc) | ||
| 483 | LDSTOPS(mach, lds, sts) | 506 | LDSTOPS(mach, lds, sts) |
| 484 | LDSTOPS(macl, lds, sts) | 507 | LDSTOPS(macl, lds, sts) |
| 485 | LDSTOPS(pr, lds, sts) | 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 | void OPPROTO op_movt_rN(void) | 523 | void OPPROTO op_movt_rN(void) |
| 488 | { | 524 | { |
| @@ -659,6 +695,30 @@ void OPPROTO op_movl_imm_rN(void) | @@ -659,6 +695,30 @@ void OPPROTO op_movl_imm_rN(void) | ||
| 659 | RETURN(); | 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 | void OPPROTO op_dec1_rN(void) | 722 | void OPPROTO op_dec1_rN(void) |
| 663 | { | 723 | { |
| 664 | env->gregs[PARAM1] -= 1; | 724 | env->gregs[PARAM1] -= 1; |
| @@ -677,6 +737,12 @@ void OPPROTO op_dec4_rN(void) | @@ -677,6 +737,12 @@ void OPPROTO op_dec4_rN(void) | ||
| 677 | RETURN(); | 737 | RETURN(); |
| 678 | } | 738 | } |
| 679 | 739 | ||
| 740 | +void OPPROTO op_dec8_rN(void) | ||
| 741 | +{ | ||
| 742 | + env->gregs[PARAM1] -= 4; | ||
| 743 | + RETURN(); | ||
| 744 | +} | ||
| 745 | + | ||
| 680 | void OPPROTO op_inc1_rN(void) | 746 | void OPPROTO op_inc1_rN(void) |
| 681 | { | 747 | { |
| 682 | env->gregs[PARAM1] += 1; | 748 | env->gregs[PARAM1] += 1; |
| @@ -695,6 +761,12 @@ void OPPROTO op_inc4_rN(void) | @@ -695,6 +761,12 @@ void OPPROTO op_inc4_rN(void) | ||
| 695 | RETURN(); | 761 | RETURN(); |
| 696 | } | 762 | } |
| 697 | 763 | ||
| 764 | +void OPPROTO op_inc8_rN(void) | ||
| 765 | +{ | ||
| 766 | + env->gregs[PARAM1] += 4; | ||
| 767 | + RETURN(); | ||
| 768 | +} | ||
| 769 | + | ||
| 698 | void OPPROTO op_add_T0_rN(void) | 770 | void OPPROTO op_add_T0_rN(void) |
| 699 | { | 771 | { |
| 700 | env->gregs[PARAM1] += T0; | 772 | env->gregs[PARAM1] += T0; |
| @@ -779,6 +851,18 @@ void OPPROTO op_movl_T0_T1(void) | @@ -779,6 +851,18 @@ void OPPROTO op_movl_T0_T1(void) | ||
| 779 | RETURN(); | 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 | void OPPROTO op_goto_tb0(void) | 866 | void OPPROTO op_goto_tb0(void) |
| 783 | { | 867 | { |
| 784 | GOTO_TB(op_goto_tb0, PARAM1, 0); | 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,3 +56,23 @@ void glue(op_stl_T0_T1, MEMSUFFIX) (void) { | ||
| 56 | glue(stl, MEMSUFFIX) (T1, T0); | 56 | glue(stl, MEMSUFFIX) (T1, T0); |
| 57 | RETURN(); | 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,6 +54,7 @@ typedef struct DisasContext { | ||
| 54 | struct TranslationBlock *tb; | 54 | struct TranslationBlock *tb; |
| 55 | target_ulong pc; | 55 | target_ulong pc; |
| 56 | uint32_t sr; | 56 | uint32_t sr; |
| 57 | + uint32_t fpscr; | ||
| 57 | uint16_t opcode; | 58 | uint16_t opcode; |
| 58 | uint32_t flags; | 59 | uint32_t flags; |
| 59 | int memidx; | 60 | int memidx; |
| @@ -63,46 +64,50 @@ typedef struct DisasContext { | @@ -63,46 +64,50 @@ typedef struct DisasContext { | ||
| 63 | 64 | ||
| 64 | #ifdef CONFIG_USER_ONLY | 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 | #else | 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 | #endif | 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 | void cpu_dump_state(CPUState * env, FILE * f, | 104 | void cpu_dump_state(CPUState * env, FILE * f, |
| 100 | int (*cpu_fprintf) (FILE * f, const char *fmt, ...), | 105 | int (*cpu_fprintf) (FILE * f, const char *fmt, ...), |
| 101 | int flags) | 106 | int flags) |
| 102 | { | 107 | { |
| 103 | int i; | 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 | for (i = 0; i < 24; i += 4) { | 111 | for (i = 0; i < 24; i += 4) { |
| 107 | cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n", | 112 | cpu_fprintf(f, "r%d=0x%08x r%d=0x%08x r%d=0x%08x r%d=0x%08x\n", |
| 108 | i, env->gregs[i], i + 1, env->gregs[i + 1], | 113 | i, env->gregs[i], i + 1, env->gregs[i + 1], |
| @@ -242,6 +247,10 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) | @@ -242,6 +247,10 @@ static void gen_delayed_conditional_jump(DisasContext * ctx) | ||
| 242 | #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \ | 247 | #define ALTREG(x) ((x) < 8 && (ctx->sr & (SR_MD | SR_RB)) != (SR_MD | SR_RB) \ |
| 243 | ? (x) + 16 : (x)) | 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 | #define CHECK_NOT_DELAY_SLOT \ | 254 | #define CHECK_NOT_DELAY_SLOT \ |
| 246 | if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \ | 255 | if (ctx->flags & (DELAY_SLOT | DELAY_SLOT_CONDITIONAL)) \ |
| 247 | {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \ | 256 | {gen_op_raise_slot_illegal_instruction (); ctx->flags |= BRANCH_EXCEPTION; \ |
| @@ -286,10 +295,12 @@ void decode_opc(DisasContext * ctx) | @@ -286,10 +295,12 @@ void decode_opc(DisasContext * ctx) | ||
| 286 | gen_op_sett(); | 295 | gen_op_sett(); |
| 287 | return; | 296 | return; |
| 288 | case 0xfbfb: /* frchg */ | 297 | case 0xfbfb: /* frchg */ |
| 289 | - assert(0); /* XXXXX */ | 298 | + gen_op_frchg(); |
| 299 | + ctx->flags |= MODE_CHANGE; | ||
| 290 | return; | 300 | return; |
| 291 | case 0xf3fb: /* fschg */ | 301 | case 0xf3fb: /* fschg */ |
| 292 | - assert(0); /* XXXXX */ | 302 | + gen_op_fschg(); |
| 303 | + ctx->flags |= MODE_CHANGE; | ||
| 293 | return; | 304 | return; |
| 294 | case 0x0009: /* nop */ | 305 | case 0x0009: /* nop */ |
| 295 | return; | 306 | return; |
| @@ -393,7 +404,7 @@ void decode_opc(DisasContext * ctx) | @@ -393,7 +404,7 @@ void decode_opc(DisasContext * ctx) | ||
| 393 | gen_op_movl_rN_T1(REG(B11_8)); | 404 | gen_op_movl_rN_T1(REG(B11_8)); |
| 394 | gen_op_stl_T0_T1(ctx); | 405 | gen_op_stl_T0_T1(ctx); |
| 395 | return; | 406 | return; |
| 396 | - case 0x6004: /* mov.l @Rm+,Rn */ | 407 | + case 0x6004: /* mov.b @Rm+,Rn */ |
| 397 | gen_op_movl_rN_T0(REG(B7_4)); | 408 | gen_op_movl_rN_T0(REG(B7_4)); |
| 398 | gen_op_ldb_T0_T0(ctx); | 409 | gen_op_ldb_T0_T0(ctx); |
| 399 | gen_op_movl_T0_rN(REG(B11_8)); | 410 | gen_op_movl_T0_rN(REG(B11_8)); |
| @@ -643,6 +654,134 @@ void decode_opc(DisasContext * ctx) | @@ -643,6 +654,134 @@ void decode_opc(DisasContext * ctx) | ||
| 643 | gen_op_movl_rN_T0(REG(B7_4)); | 654 | gen_op_movl_rN_T0(REG(B7_4)); |
| 644 | gen_op_xor_T0_rN(REG(B11_8)); | 655 | gen_op_xor_T0_rN(REG(B11_8)); |
| 645 | return; | 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 | switch (ctx->opcode & 0xff00) { | 787 | switch (ctx->opcode & 0xff00) { |
| @@ -869,16 +1008,18 @@ void decode_opc(DisasContext * ctx) | @@ -869,16 +1008,18 @@ void decode_opc(DisasContext * ctx) | ||
| 869 | gen_op_stl_T0_T1 (ctx); \ | 1008 | gen_op_stl_T0_T1 (ctx); \ |
| 870 | return; | 1009 | return; |
| 871 | LDST(sr, 0x400e, 0x4007, ldc, 0x0002, 0x4003, stc, ctx->flags |= | 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 | case 0x00c3: /* movca.l R0,@Rm */ | 1023 | case 0x00c3: /* movca.l R0,@Rm */ |
| 883 | gen_op_movl_rN_T0(REG(0)); | 1024 | gen_op_movl_rN_T0(REG(0)); |
| 884 | gen_op_movl_rN_T1(REG(B11_8)); | 1025 | gen_op_movl_rN_T1(REG(B11_8)); |
| @@ -944,6 +1085,14 @@ void decode_opc(DisasContext * ctx) | @@ -944,6 +1085,14 @@ void decode_opc(DisasContext * ctx) | ||
| 944 | case 0x401b: /* tas.b @Rn */ | 1085 | case 0x401b: /* tas.b @Rn */ |
| 945 | gen_op_tasb_rN(REG(B11_8)); | 1086 | gen_op_tasb_rN(REG(B11_8)); |
| 946 | return; | 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 | fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n", | 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,6 +1118,7 @@ int gen_intermediate_code_internal(CPUState * env, TranslationBlock * tb, | ||
| 969 | ctx.flags = env->flags; | 1118 | ctx.flags = env->flags; |
| 970 | old_flags = 0; | 1119 | old_flags = 0; |
| 971 | ctx.sr = env->sr; | 1120 | ctx.sr = env->sr; |
| 1121 | + ctx.fpscr = env->fpscr; | ||
| 972 | ctx.memidx = (env->sr & SR_MD) ? 1 : 0; | 1122 | ctx.memidx = (env->sr & SR_MD) ? 1 : 0; |
| 973 | ctx.delayed_pc = env->delayed_pc; | 1123 | ctx.delayed_pc = env->delayed_pc; |
| 974 | ctx.tb = tb; | 1124 | ctx.tb = tb; |