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; | ... | ... |