diff options
author | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-03-11 23:22:37 +0000 |
---|---|---|
committer | aurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-03-11 23:22:37 +0000 |
commit | 24988dc24169b581fe6563d7ed619bd50a2af40b (patch) | |
tree | b9ee1602c534c243c6ed74bd3183b489c0642e15 /target-sh4/translate.c | |
parent | 0954d0d9e242b4bc122eeaefb8825cc8f8eb3ab5 (diff) |
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
Diffstat (limited to 'target-sh4/translate.c')
-rw-r--r-- | target-sh4/translate.c | 133 |
1 files changed, 82 insertions, 51 deletions
diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 0c66e0bf53..b7c5f8d0a4 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -268,11 +268,11 @@ void _decode_opc(DisasContext * ctx) case 0x0018: /* sett */ gen_op_sett(); return; - case 0xfbfb: /* frchg */ + case 0xfbfd: /* frchg */ gen_op_frchg(); ctx->bstate = BS_STOP; return; - case 0xf3fb: /* fschg */ + case 0xf3fd: /* fschg */ gen_op_fschg(); ctx->bstate = BS_STOP; return; @@ -296,7 +296,7 @@ void _decode_opc(DisasContext * ctx) gen_op_ldl_T0_T0(ctx); gen_op_movl_T0_rN(REG(B11_8)); return; - case 0xe000: /* mov.l #imm,Rn */ + case 0xe000: /* mov #imm,Rn */ gen_op_movl_imm_rN(B7_0s, REG(B11_8)); return; case 0x9000: /* mov.w @(disp,PC),Rn */ @@ -309,7 +309,7 @@ void _decode_opc(DisasContext * ctx) gen_op_ldl_T0_T0(ctx); gen_op_movl_T0_rN(REG(B11_8)); return; - case 0x7000: /* add.l #imm,Rn */ + case 0x7000: /* add #imm,Rn */ gen_op_add_imm_rN(B7_0s, REG(B11_8)); return; case 0xa000: /* bra disp */ @@ -361,20 +361,20 @@ void _decode_opc(DisasContext * ctx) gen_op_movl_T0_rN(REG(B11_8)); return; case 0x2004: /* mov.b Rm,@-Rn */ - gen_op_dec1_rN(REG(B11_8)); gen_op_movl_rN_T0(REG(B7_4)); + gen_op_dec1_rN(REG(B11_8)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stb_T0_T1(ctx); return; case 0x2005: /* mov.w Rm,@-Rn */ - gen_op_dec2_rN(REG(B11_8)); gen_op_movl_rN_T0(REG(B7_4)); + gen_op_dec2_rN(REG(B11_8)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stw_T0_T1(ctx); return; case 0x2006: /* mov.l Rm,@-Rn */ - gen_op_dec4_rN(REG(B11_8)); gen_op_movl_rN_T0(REG(B7_4)); + gen_op_dec4_rN(REG(B11_8)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stl_T0_T1(ctx); return; @@ -382,19 +382,22 @@ void _decode_opc(DisasContext * ctx) gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldb_T0_T0(ctx); gen_op_movl_T0_rN(REG(B11_8)); - gen_op_inc1_rN(REG(B7_4)); + if ( B11_8 != B7_4 ) + gen_op_inc1_rN(REG(B7_4)); return; case 0x6005: /* mov.w @Rm+,Rn */ gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldw_T0_T0(ctx); gen_op_movl_T0_rN(REG(B11_8)); - gen_op_inc2_rN(REG(B7_4)); + if ( B11_8 != B7_4 ) + gen_op_inc2_rN(REG(B7_4)); return; case 0x6006: /* mov.l @Rm+,Rn */ gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldl_T0_T0(ctx); gen_op_movl_T0_rN(REG(B11_8)); - gen_op_inc4_rN(REG(B7_4)); + if ( B11_8 != B7_4 ) + gen_op_inc4_rN(REG(B7_4)); return; case 0x0004: /* mov.b Rm,@(R0,Rn) */ gen_op_movl_rN_T0(REG(B7_4)); @@ -502,7 +505,6 @@ void _decode_opc(DisasContext * ctx) gen_op_movl_rN_T0(REG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_div0s_T0_T1(); - gen_op_movl_T1_rN(REG(B11_8)); return; case 0x3004: /* div1 Rm,Rn */ gen_op_movl_rN_T0(REG(B7_4)); @@ -536,25 +538,25 @@ void _decode_opc(DisasContext * ctx) gen_op_movuw_rN_T0(REG(B7_4)); gen_op_movl_T0_rN(REG(B11_8)); return; - case 0x000f: /* mac.l @Rm+,@Rn- */ + case 0x000f: /* mac.l @Rm+,@Rn+ */ gen_op_movl_rN_T0(REG(B11_8)); gen_op_ldl_T0_T0(ctx); gen_op_movl_T0_T1(); - gen_op_movl_rN_T1(REG(B7_4)); + gen_op_inc4_rN(REG(B11_8)); + gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldl_T0_T0(ctx); gen_op_macl_T0_T1(); gen_op_inc4_rN(REG(B7_4)); - gen_op_inc4_rN(REG(B11_8)); return; case 0x400f: /* mac.w @Rm+,@Rn+ */ gen_op_movl_rN_T0(REG(B11_8)); gen_op_ldl_T0_T0(ctx); gen_op_movl_T0_T1(); - gen_op_movl_rN_T1(REG(B7_4)); + gen_op_inc2_rN(REG(B11_8)); + gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldl_T0_T0(ctx); gen_op_macw_T0_T1(); gen_op_inc2_rN(REG(B7_4)); - gen_op_inc2_rN(REG(B11_8)); return; case 0x0007: /* mul.l Rm,Rn */ gen_op_movl_rN_T0(REG(B7_4)); @@ -629,10 +631,8 @@ void _decode_opc(DisasContext * ctx) return; case 0xf00c: /* fmov {F,D,X}Rm,{F,D,X}Rn - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_SZ) { - if (ctx->opcode & 0x0110) - break; /* illegal instruction */ - gen_op_fmov_drN_DT0(DREG(B7_4)); - gen_op_fmov_DT0_drN(DREG(B11_8)); + gen_op_fmov_drN_DT0(XREG(B7_4)); + gen_op_fmov_DT0_drN(XREG(B11_8)); } else { gen_op_fmov_frN_FT0(FREG(B7_4)); gen_op_fmov_FT0_frN(FREG(B11_8)); @@ -640,9 +640,7 @@ void _decode_opc(DisasContext * ctx) return; case 0xf00a: /* fmov {F,D,X}Rm,@Rn - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_SZ) { - if (ctx->opcode & 0x0010) - break; /* illegal instruction */ - gen_op_fmov_drN_DT0(DREG(B7_4)); + gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else { @@ -653,11 +651,9 @@ void _decode_opc(DisasContext * ctx) return; case 0xf008: /* fmov @Rm,{F,D,X}Rn - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_SZ) { - if (ctx->opcode & 0x0100) - break; /* illegal instruction */ gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfq_T0_DT0(ctx); - gen_op_fmov_DT0_drN(DREG(B11_8)); + gen_op_fmov_DT0_drN(XREG(B11_8)); } else { gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfl_T0_FT0(ctx); @@ -666,11 +662,9 @@ void _decode_opc(DisasContext * ctx) return; case 0xf009: /* fmov @Rm+,{F,D,X}Rn - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_SZ) { - if (ctx->opcode & 0x0100) - break; /* illegal instruction */ gen_op_movl_rN_T0(REG(B7_4)); gen_op_ldfq_T0_DT0(ctx); - gen_op_fmov_DT0_drN(DREG(B11_8)); + gen_op_fmov_DT0_drN(XREG(B11_8)); gen_op_inc8_rN(REG(B7_4)); } else { gen_op_movl_rN_T0(REG(B7_4)); @@ -681,10 +675,8 @@ void _decode_opc(DisasContext * ctx) return; case 0xf00b: /* fmov {F,D,X}Rm,@-Rn - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_SZ) { - if (ctx->opcode & 0x0100) - break; /* illegal instruction */ gen_op_dec8_rN(REG(B11_8)); - gen_op_fmov_drN_DT0(DREG(B7_4)); + gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_stfq_DT0_T1(ctx); } else { @@ -696,12 +688,10 @@ void _decode_opc(DisasContext * ctx) return; case 0xf006: /* fmov @(R0,Rm),{F,D,X}Rm - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_SZ) { - if (ctx->opcode & 0x0100) - break; /* illegal instruction */ gen_op_movl_rN_T0(REG(B7_4)); gen_op_add_rN_T0(REG(0)); gen_op_ldfq_T0_DT0(ctx); - gen_op_fmov_DT0_drN(DREG(B11_8)); + gen_op_fmov_DT0_drN(XREG(B11_8)); } else { gen_op_movl_rN_T0(REG(B7_4)); gen_op_add_rN_T0(REG(0)); @@ -711,9 +701,7 @@ void _decode_opc(DisasContext * ctx) return; case 0xf007: /* fmov {F,D,X}Rn,@(R0,Rn) - FPSCR: Nothing */ if (ctx->fpscr & FPSCR_SZ) { - if (ctx->opcode & 0x0010) - break; /* illegal instruction */ - gen_op_fmov_drN_DT0(DREG(B7_4)); + gen_op_fmov_drN_DT0(XREG(B7_4)); gen_op_movl_rN_T1(REG(B11_8)); gen_op_add_rN_T1(REG(0)); gen_op_stfq_DT0_T1(ctx); @@ -755,8 +743,10 @@ void _decode_opc(DisasContext * ctx) ctx->fpscr & FPSCR_PR ? gen_op_fdiv_DT() : gen_op_fdiv_FT(); break; case 0xf004: /* fcmp/eq Rm,Rn */ + ctx->fpscr & FPSCR_PR ? gen_op_fcmp_eq_DT() : gen_op_fcmp_eq_FT(); return; case 0xf005: /* fcmp/gt Rm,Rn */ + ctx->fpscr & FPSCR_PR ? gen_op_fcmp_gt_DT() : gen_op_fcmp_gt_FT(); return; } @@ -773,11 +763,11 @@ void _decode_opc(DisasContext * ctx) case 0xc900: /* and #imm,R0 */ gen_op_and_imm_rN(B7_0, REG(0)); return; - case 0xcd00: /* and.b #imm,@(R0+GBR) */ + case 0xcd00: /* and.b #imm,@(R0,GBR) */ gen_op_movl_rN_T0(REG(0)); gen_op_addl_GBR_T0(); gen_op_movl_T0_T1(); - gen_op_ldb_T0_T0(ctx); + gen_op_ldub_T0_T0(ctx); gen_op_and_imm_T0(B7_0); gen_op_stb_T0_T1(ctx); return; @@ -815,13 +805,13 @@ void _decode_opc(DisasContext * ctx) return; case 0xc500: /* mov.w @(disp,GBR),R0 */ gen_op_stc_gbr_T0(); - gen_op_addl_imm_T0(B7_0); + gen_op_addl_imm_T0(B7_0 * 2); gen_op_ldw_T0_T0(ctx); gen_op_movl_T0_rN(REG(0)); return; case 0xc600: /* mov.l @(disp,GBR),R0 */ gen_op_stc_gbr_T0(); - gen_op_addl_imm_T0(B7_0); + gen_op_addl_imm_T0(B7_0 * 4); gen_op_ldl_T0_T0(ctx); gen_op_movl_T0_rN(REG(0)); return; @@ -834,14 +824,14 @@ void _decode_opc(DisasContext * ctx) return; case 0xc100: /* mov.w R0,@(disp,GBR) */ gen_op_stc_gbr_T0(); - gen_op_addl_imm_T0(B7_0); + gen_op_addl_imm_T0(B7_0 * 2); gen_op_movl_T0_T1(); gen_op_movl_rN_T0(REG(0)); gen_op_stw_T0_T1(ctx); return; case 0xc200: /* mov.l R0,@(disp,GBR) */ gen_op_stc_gbr_T0(); - gen_op_addl_imm_T0(B7_0); + gen_op_addl_imm_T0(B7_0 * 4); gen_op_movl_T0_T1(); gen_op_movl_rN_T0(REG(0)); gen_op_stl_T0_T1(ctx); @@ -877,11 +867,11 @@ void _decode_opc(DisasContext * ctx) case 0xcb00: /* or #imm,R0 */ gen_op_or_imm_rN(B7_0, REG(0)); return; - case 0xcf00: /* or.b #imm,@(R0+GBR) */ + case 0xcf00: /* or.b #imm,@(R0,GBR) */ gen_op_movl_rN_T0(REG(0)); gen_op_addl_GBR_T0(); gen_op_movl_T0_T1(); - gen_op_ldb_T0_T0(ctx); + gen_op_ldub_T0_T0(ctx); gen_op_or_imm_T0(B7_0); gen_op_stb_T0_T1(ctx); return; @@ -893,20 +883,20 @@ void _decode_opc(DisasContext * ctx) case 0xc800: /* tst #imm,R0 */ gen_op_tst_imm_rN(B7_0, REG(0)); return; - case 0xcc00: /* tst #imm,@(R0+GBR) */ + case 0xcc00: /* tst.b #imm,@(R0,GBR) */ gen_op_movl_rN_T0(REG(0)); gen_op_addl_GBR_T0(); - gen_op_ldb_T0_T0(ctx); + gen_op_ldub_T0_T0(ctx); gen_op_tst_imm_T0(B7_0); return; case 0xca00: /* xor #imm,R0 */ gen_op_xor_imm_rN(B7_0, REG(0)); return; - case 0xce00: /* xor.b #imm,@(R0+GBR) */ + case 0xce00: /* xor.b #imm,@(R0,GBR) */ gen_op_movl_rN_T0(REG(0)); gen_op_addl_GBR_T0(); gen_op_movl_T0_T1(); - gen_op_ldb_T0_T0(ctx); + gen_op_ldub_T0_T0(ctx); gen_op_xor_imm_T0(B7_0); gen_op_stb_T0_T1(ctx); return; @@ -1017,7 +1007,7 @@ void _decode_opc(DisasContext * ctx) gen_op_movl_rN_T0(REG(B11_8)); gen_op_ldl_T0_T0(ctx); return; - case 0x00a2: /* ocbp @Rn */ + case 0x00a3: /* ocbp @Rn */ gen_op_movl_rN_T0(REG(B11_8)); gen_op_ldl_T0_T0(ctx); return; @@ -1102,6 +1092,37 @@ void _decode_opc(DisasContext * ctx) gen_op_ftrc_FT(); } return; + case 0xf04d: /* fneg FRn/DRn - FPSCR: Nothing */ + gen_op_fneg_frN(FREG(B11_8)); + return; + case 0xf05d: /* fabs FRn/DRn */ + if (ctx->fpscr & FPSCR_PR) { + if (ctx->opcode & 0x0100) + break; /* illegal instruction */ + gen_op_fmov_drN_DT0(DREG(B11_8)); + gen_op_fabs_DT(); + gen_op_fmov_DT0_drN(DREG(B11_8)); + } else { + gen_op_fmov_frN_FT0(FREG(B11_8)); + gen_op_fabs_FT(); + gen_op_fmov_FT0_frN(FREG(B11_8)); + } + return; + case 0xf06d: /* fsqrt FRn */ + if (ctx->fpscr & FPSCR_PR) { + if (ctx->opcode & 0x0100) + break; /* illegal instruction */ + gen_op_fmov_drN_DT0(FREG(B11_8)); + gen_op_fsqrt_DT(); + gen_op_fmov_DT0_drN(FREG(B11_8)); + } else { + gen_op_fmov_frN_FT0(FREG(B11_8)); + gen_op_fsqrt_FT(); + gen_op_fmov_FT0_frN(FREG(B11_8)); + } + return; + case 0xf07d: /* fsrra FRn */ + break; case 0xf08d: /* fldi0 FRn - FPSCR: R[PR] */ if (!(ctx->fpscr & FPSCR_PR)) { gen_op_movl_imm_T0(0); @@ -1116,6 +1137,16 @@ void _decode_opc(DisasContext * ctx) return; } break; + case 0xf0ad: /* fcnvsd FPUL,DRn */ + gen_op_movl_fpul_FT0(); + gen_op_fcnvsd_FT_DT(); + gen_op_fmov_DT0_drN(DREG(B11_8)); + return; + case 0xf0bd: /* fcnvds DRn,FPUL */ + gen_op_fmov_drN_DT0(DREG(B11_8)); + gen_op_fcnvds_DT_FT(); + gen_op_movl_FT0_fpul(); + return; } fprintf(stderr, "unknown instruction 0x%04x at pc 0x%08x\n", |