Commit eda9b09b1df1efea4275baadb9743ff5124bd7c2

Authored by bellard
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
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;