diff --git a/src/jit/codegen_arm.cpp b/src/jit/codegen_arm.cpp index 21539067..d34f364f 100644 --- a/src/jit/codegen_arm.cpp +++ b/src/jit/codegen_arm.cpp @@ -943,6 +943,48 @@ STATIC_INLINE void compemu_raw_jcc_l_oponly(int cc) // emit of target will be done by caller } +STATIC_INLINE void compemu_raw_handle_except(IMM cycles) +{ + uae_u32* branchadd; + + clobber_flags(); + + MOVW_ri16(REG_WORK2, (uae_u32)(&jit_exception)); + MOVT_ri16(REG_WORK2, ((uae_u32)(&jit_exception)) >> 16); + LDR_rR(REG_WORK1, REG_WORK2); + TST_rr(REG_WORK1, REG_WORK1); + BNE_i(1); // exception, skip LDR and target + + LDR_rRI(RPC_INDEX, RPC_INDEX, -4); // jump to next opcode + branchadd = (uae_u32*)get_target(); + skip_long(); // emit of target (next opcode handler) will be done later + + // countdown -= scaled_cycles(totcycles); + uae_s32 offs = (uae_u32)&countdown - (uae_u32)®s; + LDR_rRI(REG_WORK1, R_REGSTRUCT, offs); + if(CHECK32(cycles)) { + SUBS_rri(REG_WORK1, REG_WORK1, cycles); + } else { +#ifdef ARMV6T2 + MOVW_ri16(REG_WORK2, cycles); + if(cycles >> 16) + MOVT_ri16(REG_WORK2, cycles >> 16); +#else + int offs2 = data_long_offs(cycles); + LDR_rRI(REG_WORK2, RPC_INDEX, offs2); +#endif + SUBS_rrr(REG_WORK1, REG_WORK1, REG_WORK2); + } + STR_rRI(REG_WORK1, R_REGSTRUCT, offs); + + LDR_rRI(RPC_INDEX, RPC_INDEX, -4); // + emit_long((uintptr)popall_execute_exception); + + // Write target of next instruction + write_jmp_target(branchadd, (cpuop_func*)get_target()); + +} + STATIC_INLINE void compemu_raw_jl(uae_u32 t) { #ifdef ARMV6T2 @@ -1185,8 +1227,7 @@ LOWFUNC(NONE,NONE,2,raw_fmov_to_w_rr,(W4 d, FR s)) { VCVTR64toI_sd(SCRATCH_F32_1, s); VMOV32_rs(REG_WORK1, SCRATCH_F32_1); - SSAT_rir(REG_WORK1, 15, REG_WORK1); - BFI_rrii(d, REG_WORK1, 0, 15); + SSAT_rir(d, 15, REG_WORK1); } LENDFUNC(NONE,NONE,2,raw_fmov_to_w_rr,(W4 d, FR s)) @@ -1194,8 +1235,7 @@ LOWFUNC(NONE,NONE,2,raw_fmov_to_b_rr,(W4 d, FR s)) { VCVTR64toI_sd(SCRATCH_F32_1, s); VMOV32_rs(REG_WORK1, SCRATCH_F32_1); - SSAT_rir(REG_WORK1, 7, REG_WORK1); - BFI_rrii(d, REG_WORK1, 0, 7); + SSAT_rir(d, 7, REG_WORK1); } LENDFUNC(NONE,NONE,2,raw_fmov_to_b_rr,(W4 d, FR s)) @@ -1343,7 +1383,7 @@ LOWFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s)) VMRS_r(REG_WORK2); UBFX_rrii(REG_WORK1, REG_WORK1, 22, 2); - BFI_rrii(REG_WORK2, REG_WORK1, 22, 2); + BFI_rrii(REG_WORK2, REG_WORK1, 22, 23); VMSR_r(REG_WORK2); } LENDFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s)) @@ -1425,7 +1465,7 @@ LOWFUNC(NONE,WRITE,2,raw_fp_from_exten_mr,(RR4 adr, FR s)) ADD_rrr(REG_WORK1, adr, REG_WORK1); REV_rr(REG_WORK3, REG_WORK3); - STR_rR(REG_WORK3, REG_WORK1); // write exponent + STRH_rR(REG_WORK3, REG_WORK1); // write exponent VSHL64_ddi(SCRATCH_F64_1, s, 11); // shift mantissa to correct position VMOV64_rrd(REG_WORK3, REG_WORK2, SCRATCH_F64_1); @@ -1494,7 +1534,7 @@ LOWFUNC(NONE,READ,2,raw_fp_to_exten_rm,(FW d, RR4 adr)) MOVW_ri16(REG_WORK1, 15360); // diff of bias between double and long double SUB_rrr(REG_WORK3, REG_WORK3, REG_WORK1); // exponent done, ToDo: check for carry -> result gets Inf in double UBFX_rrii(REG_WORK2, REG_WORK2, 15, 1); // extract sign - BFI_rrii(REG_WORK3, REG_WORK2, 11, 1); // insert sign + BFI_rrii(REG_WORK3, REG_WORK2, 11, 11); // insert sign VSHR64_ddi(d, d, 11); // shift mantissa to correct position LSL_rri(REG_WORK3, REG_WORK3, 20); VMOV_I64_dimmI(0, 0x00); @@ -1503,7 +1543,7 @@ LOWFUNC(NONE,READ,2,raw_fp_to_exten_rm,(FW d, RR4 adr)) // end_of_op } -LENDFUNC(NONE,READ,2,raw_fp_from_exten_mr,(FW d, RR4 adr)) +LENDFUNC(NONE,READ,2,raw_fp_to_exten_rm,(FW d, RR4 adr)) STATIC_INLINE void raw_fflags_into_flags(int r) { @@ -1621,4 +1661,13 @@ LOWFUNC(NONE,NONE,2,raw_fp_fscc_ri,(RW4 d, int cc)) } LENDFUNC(NONE,NONE,2,raw_fp_fscc_ri,(RW4 d, int cc)) +LOWFUNC(NONE,NONE,1,raw_roundingmode,(IMM mode)) +{ + VMRS_r(REG_WORK1); + BIC_rri(REG_WORK1, REG_WORK1, 0x00c00000); + ORR_rri(REG_WORK1, REG_WORK1, mode); + VMSR_r(REG_WORK1); +} +LENDFUNC(NONE,NONE,1,raw_roundingmode,(IMM mode)) + #endif // USE_JIT_FPU diff --git a/src/jit/codegen_arm.h b/src/jit/codegen_arm.h index 7e72901d..f299324f 100644 --- a/src/jit/codegen_arm.h +++ b/src/jit/codegen_arm.h @@ -1401,11 +1401,17 @@ enum { #define CC_VCVT32toI_ss(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xd << 16) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm)) #define VCVT32toI_ss(Sd,Sm) CC_VCVT32toI_ss(NATIVE_CC_AL,Sd,Sm) +#define CC_VCVT64toIu_sd(cc,Sd,Dm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0xd << 16) | (0xb << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Dm(Dm)) +#define VCVT64toIu_sd(Sd,Dm) CC_VCVT64toIu_sd(NATIVE_CC_AL,Sd,Dm) + #define CC_VCVTIto64_ds(cc,Dd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x8 << 16) | (0xb << 8) | (0xc << 4) | MAKE_Dd(Dd) | MAKE_Sm(Sm)) #define VCVTIto64_ds(Dd,Sm) CC_VCVTIto64_ds(NATIVE_CC_AL,Dd,Sm) #define CC_VCVTIto32_ss(cc,Sd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x8 << 16) | (0xa << 8) | (0xc << 4) | MAKE_Sd(Sd) | MAKE_Sm(Sm)) #define VCVTIto32_ss(Sd,Sm) CC_VCVTIto32_ss(NATIVE_CC_AL,Dd,Sm) +#define CC_VCVTIuto64_ds(cc,Dd,Sm) _W(((cc) << 28) | (0xe << 24) | (0xb << 20) | (0x8 << 16) | (0xb << 8) | (0x4 << 4) | MAKE_Dd(Dd) | MAKE_Sm(Sm)) +#define VCVTIuto64_ds(Dd,Sm) CC_VCVTIuto64_ds(NATIVE_CC_AL,Dd,Sm) + #define CC_VADD64_ddd(cc,Dd,Dn,Dm) _W(((cc) << 28) | (0xe << 24) | (0x3 << 20) | (0xb << 8) | (0x0 << 4) | MAKE_Dd(Dd) | MAKE_Dn(Dn) | MAKE_Dm(Dm)) #define VADD64_ddd(Dd,Dn,Dm) CC_VADD64_ddd(NATIVE_CC_AL,Dd,Dn,Dm) #define CC_VADD32_sss(cc,Sd,Sn,Sm) _W(((cc) << 28) | (0xe << 24) | (0x3 << 20) | (0xa << 8) | (0x0 << 4) | MAKE_Sd(Sd) | MAKE_Sn(Sn) | MAKE_Sm(Sm)) @@ -1481,6 +1487,6 @@ enum { #define VSHL64_ddi(Dd,Dm,imm) _W((0xf << 28) | (0x2 << 24) | (0x8 << 20) | (0x5 << 8) | (0x9 << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm) | FIMM6(imm)) #define VSHR64_ddi(Dd,Dm,imm) _W((0xf << 28) | (0x3 << 24) | (0x8 << 20) | (0x0 << 8) | (0x9 << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dm) | FIMM6(64-imm)) -#define VORR_ddd(Dd,Dn,Dm) _W((0xf << 28) | (0x2 << 24) | (0x2 << 20) | (0x1 << 8) | (0x1 << 4) | MAKE_Dd(Dd) | MAKE_Dm(Dn) | MAKE_Dm(Dm)) +#define VORR_ddd(Dd,Dn,Dm) _W((0xf << 28) | (0x2 << 24) | (0x2 << 20) | (0x1 << 8) | (0x1 << 4) | MAKE_Dd(Dd) | MAKE_Dn(Dn) | MAKE_Dm(Dm)) #endif /* ARM_RTASM_H */ diff --git a/src/jit/compemu.cpp b/src/jit/compemu.cpp index 881fdc4d..83d7baef 100644 --- a/src/jit/compemu.cpp +++ b/src/jit/compemu.cpp @@ -21799,6 +21799,325 @@ uae_u32 REGPARAM2 op_80bc_0_comp_ff(uae_u32 opcode) }}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); return 0; } +/* DIVU.W Dn,Dn */ +uae_u32 REGPARAM2 op_80c0_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int src=srcreg; +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVU(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (An),Dn */ +uae_u32 REGPARAM2 op_80d0_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=dodgy?scratchie++:srcreg+8; + if (dodgy) + mov_l_rr(srca,srcreg+8); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVU(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (An)+,Dn */ +uae_u32 REGPARAM2 op_80d8_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + mov_l_rr(srca,srcreg+8); +{ int src=scratchie++; + readword(srca,src,scratchie); + arm_ADD_l_ri8(srcreg+8,2); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVU(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W -(An),Dn */ +uae_u32 REGPARAM2 op_80e0_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{{ int srca=dodgy?scratchie++:srcreg+8; + arm_SUB_l_ri8(srcreg+8,2); + if (dodgy) + mov_l_rr(srca,8+srcreg); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVU(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (d16,An),Dn */ +uae_u32 REGPARAM2 op_80e8_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + mov_l_rr(srca,8+srcreg); + lea_l_brr(srca,srca,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVU(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (d8,An,Xn),Dn */ +uae_u32 REGPARAM2 op_80f0_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + calc_disp_ea_020(srcreg+8,comp_get_iword((m68k_pc_offset+=2)-2),srca,scratchie); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVU(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (xxx).W,Dn */ +uae_u32 REGPARAM2 op_80f8_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca = scratchie++; + mov_l_ri(srca,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVU(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (xxx).L,Dn */ +uae_u32 REGPARAM2 op_80f9_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca = scratchie++; + mov_l_ri(srca,comp_get_ilong((m68k_pc_offset+=4)-4)); /* absl */ +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVU(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (d16,PC),Dn */ +uae_u32 REGPARAM2 op_80fa_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset; + uae_s32 PC16off = (uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); + mov_l_ri(srca,address+PC16off); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVU(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (d8,PC,Xn),Dn */ +uae_u32 REGPARAM2 op_80fb_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int pctmp=scratchie++; + int srca=scratchie++; + uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset; +{ mov_l_ri(pctmp,address); + calc_disp_ea_020(pctmp,comp_get_iword((m68k_pc_offset+=2)-2),srca,scratchie); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVU(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W #.W,Dn */ +uae_u32 REGPARAM2 op_80fc_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int src = scratchie++; + mov_l_ri(src,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVU(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} /* OR.B Dn,(An) */ uae_u32 REGPARAM2 op_8110_0_comp_ff(uae_u32 opcode) { @@ -22270,6 +22589,325 @@ uae_u32 REGPARAM2 op_81b9_0_comp_ff(uae_u32 opcode) }}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); return 0; } +/* DIVS.W Dn,Dn */ +uae_u32 REGPARAM2 op_81c0_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int src=srcreg; +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVS(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (An),Dn */ +uae_u32 REGPARAM2 op_81d0_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=dodgy?scratchie++:srcreg+8; + if (dodgy) + mov_l_rr(srca,srcreg+8); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVS(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (An)+,Dn */ +uae_u32 REGPARAM2 op_81d8_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + mov_l_rr(srca,srcreg+8); +{ int src=scratchie++; + readword(srca,src,scratchie); + arm_ADD_l_ri8(srcreg+8,2); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVS(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W -(An),Dn */ +uae_u32 REGPARAM2 op_81e0_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{{ int srca=dodgy?scratchie++:srcreg+8; + arm_SUB_l_ri8(srcreg+8,2); + if (dodgy) + mov_l_rr(srca,8+srcreg); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVS(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (d16,An),Dn */ +uae_u32 REGPARAM2 op_81e8_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + mov_l_rr(srca,8+srcreg); + lea_l_brr(srca,srca,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVS(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (d8,An,Xn),Dn */ +uae_u32 REGPARAM2 op_81f0_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + calc_disp_ea_020(srcreg+8,comp_get_iword((m68k_pc_offset+=2)-2),srca,scratchie); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVS(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (xxx).W,Dn */ +uae_u32 REGPARAM2 op_81f8_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca = scratchie++; + mov_l_ri(srca,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVS(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (xxx).L,Dn */ +uae_u32 REGPARAM2 op_81f9_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca = scratchie++; + mov_l_ri(srca,comp_get_ilong((m68k_pc_offset+=4)-4)); /* absl */ +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVS(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (d16,PC),Dn */ +uae_u32 REGPARAM2 op_81fa_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset; + uae_s32 PC16off = (uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); + mov_l_ri(srca,address+PC16off); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVS(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (d8,PC,Xn),Dn */ +uae_u32 REGPARAM2 op_81fb_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int pctmp=scratchie++; + int srca=scratchie++; + uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset; +{ mov_l_ri(pctmp,address); + calc_disp_ea_020(pctmp,comp_get_iword((m68k_pc_offset+=2)-2),srca,scratchie); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVS(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W #.W,Dn */ +uae_u32 REGPARAM2 op_81fc_0_comp_ff(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int src = scratchie++; + mov_l_ri(src,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jff_DIVS(tmp,dst,src); + live_flags(); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} /* SUB.B Dn,Dn */ uae_u32 REGPARAM2 op_9000_0_comp_ff(uae_u32 opcode) { @@ -52775,6 +53413,314 @@ uae_u32 REGPARAM2 op_80bc_0_comp_nf(uae_u32 opcode) }}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); return 0; } +/* DIVU.W Dn,Dn */ +uae_u32 REGPARAM2 op_80c0_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int src=srcreg; +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVU(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (An),Dn */ +uae_u32 REGPARAM2 op_80d0_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=dodgy?scratchie++:srcreg+8; + if (dodgy) + mov_l_rr(srca,srcreg+8); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVU(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (An)+,Dn */ +uae_u32 REGPARAM2 op_80d8_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + mov_l_rr(srca,srcreg+8); +{ int src=scratchie++; + readword(srca,src,scratchie); + arm_ADD_l_ri8(srcreg+8,2); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVU(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W -(An),Dn */ +uae_u32 REGPARAM2 op_80e0_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{{ int srca=dodgy?scratchie++:srcreg+8; + arm_SUB_l_ri8(srcreg+8,2); + if (dodgy) + mov_l_rr(srca,8+srcreg); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVU(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (d16,An),Dn */ +uae_u32 REGPARAM2 op_80e8_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + mov_l_rr(srca,8+srcreg); + lea_l_brr(srca,srca,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVU(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (d8,An,Xn),Dn */ +uae_u32 REGPARAM2 op_80f0_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + calc_disp_ea_020(srcreg+8,comp_get_iword((m68k_pc_offset+=2)-2),srca,scratchie); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVU(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (xxx).W,Dn */ +uae_u32 REGPARAM2 op_80f8_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca = scratchie++; + mov_l_ri(srca,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVU(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (xxx).L,Dn */ +uae_u32 REGPARAM2 op_80f9_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca = scratchie++; + mov_l_ri(srca,comp_get_ilong((m68k_pc_offset+=4)-4)); /* absl */ +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVU(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (d16,PC),Dn */ +uae_u32 REGPARAM2 op_80fa_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset; + uae_s32 PC16off = (uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); + mov_l_ri(srca,address+PC16off); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVU(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W (d8,PC,Xn),Dn */ +uae_u32 REGPARAM2 op_80fb_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int pctmp=scratchie++; + int srca=scratchie++; + uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset; +{ mov_l_ri(pctmp,address); + calc_disp_ea_020(pctmp,comp_get_iword((m68k_pc_offset+=2)-2),srca,scratchie); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVU(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVU.W #.W,Dn */ +uae_u32 REGPARAM2 op_80fc_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int src = scratchie++; + mov_l_ri(src,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVU(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} /* OR.B Dn,(An) */ uae_u32 REGPARAM2 op_8110_0_comp_nf(uae_u32 opcode) { @@ -53225,6 +54171,314 @@ uae_u32 REGPARAM2 op_81b9_0_comp_nf(uae_u32 opcode) }}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); return 0; } +/* DIVS.W Dn,Dn */ +uae_u32 REGPARAM2 op_81c0_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int src=srcreg; +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVS(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (An),Dn */ +uae_u32 REGPARAM2 op_81d0_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=dodgy?scratchie++:srcreg+8; + if (dodgy) + mov_l_rr(srca,srcreg+8); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVS(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (An)+,Dn */ +uae_u32 REGPARAM2 op_81d8_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + mov_l_rr(srca,srcreg+8); +{ int src=scratchie++; + readword(srca,src,scratchie); + arm_ADD_l_ri8(srcreg+8,2); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVS(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W -(An),Dn */ +uae_u32 REGPARAM2 op_81e0_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{{ int srca=dodgy?scratchie++:srcreg+8; + arm_SUB_l_ri8(srcreg+8,2); + if (dodgy) + mov_l_rr(srca,8+srcreg); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVS(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (d16,An),Dn */ +uae_u32 REGPARAM2 op_81e8_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + mov_l_rr(srca,8+srcreg); + lea_l_brr(srca,srca,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVS(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (d8,An,Xn),Dn */ +uae_u32 REGPARAM2 op_81f0_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_s32 srcreg = (opcode & 7); + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + calc_disp_ea_020(srcreg+8,comp_get_iword((m68k_pc_offset+=2)-2),srca,scratchie); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVS(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (xxx).W,Dn */ +uae_u32 REGPARAM2 op_81f8_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca = scratchie++; + mov_l_ri(srca,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVS(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (xxx).L,Dn */ +uae_u32 REGPARAM2 op_81f9_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca = scratchie++; + mov_l_ri(srca,comp_get_ilong((m68k_pc_offset+=4)-4)); /* absl */ +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVS(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (d16,PC),Dn */ +uae_u32 REGPARAM2 op_81fa_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int srca=scratchie++; + uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset; + uae_s32 PC16off = (uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2); + mov_l_ri(srca,address+PC16off); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVS(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W (d8,PC,Xn),Dn */ +uae_u32 REGPARAM2 op_81fb_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int pctmp=scratchie++; + int srca=scratchie++; + uae_u32 address=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset; +{ mov_l_ri(pctmp,address); + calc_disp_ea_020(pctmp,comp_get_iword((m68k_pc_offset+=2)-2),srca,scratchie); +{ int src=scratchie++; + readword(srca,src,scratchie); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVS(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} +/* DIVS.W #.W,Dn */ +uae_u32 REGPARAM2 op_81fc_0_comp_nf(uae_u32 opcode) +{ +#ifndef ARMV6T2 + FAIL(1); + return 0; +#else + uae_u32 dstreg = (opcode >> 9) & 7; + uae_u32 dodgy=0; + uae_u32 m68k_pc_offset_thisinst=m68k_pc_offset; + m68k_pc_offset+=2; +{ uae_u8 scratchie=S1; + dont_care_flags(); +{ int src = scratchie++; + mov_l_ri(src,(uae_s32)(uae_s16)comp_get_iword((m68k_pc_offset+=2)-2)); +{ int dst=dstreg; + int tmp=scratchie++; + register_possible_exception(); + jnf_DIVS(tmp,dst,src); + if(dstreg!=tmp) + mov_l_rr(dstreg,tmp); +}}} if (m68k_pc_offset>SYNC_PC_OFFSET) sync_m68k_pc(); +return 0; +#endif +} /* SUB.B Dn,Dn */ uae_u32 REGPARAM2 op_9000_0_comp_nf(uae_u32 opcode) { diff --git a/src/jit/compemu.h b/src/jit/compemu.h index eaaad979..957f24e8 100644 --- a/src/jit/compemu.h +++ b/src/jit/compemu.h @@ -129,7 +129,6 @@ typedef union { #endif #define N_FREGS 16 // We use 10 regs: 6 - FP_RESULT, 7 - SCRATCH, 8-15 - Amiga regs FP0-FP7 - /* Functions exposed to newcpu, or to what was moved from newcpu.c to * compemu_support.c */ extern void compiler_exit(void); @@ -332,6 +331,7 @@ extern void sync_m68k_pc(void); extern uae_u32 get_const(int r); extern int is_const(int r); extern void register_branch(uae_u32 not_taken, uae_u32 taken, uae_u8 cond); +extern void register_possible_exception(void); #define comp_get_ibyte(o) do_get_mem_byte((uae_u8 *)(comp_pc_p + (o) + 1)) #define comp_get_iword(o) do_get_mem_word((uae_u16 *)(comp_pc_p + (o))) @@ -403,6 +403,7 @@ typedef struct blockinfo_t { void execute_normal(void); void exec_nostats(void); void do_nothing(void); +void execute_exception(void); /* ARAnyM uses fpu_register name, used in scratch_t */ /* FIXME: check that no ARAnyM code assumes different floating point type */ diff --git a/src/jit/compemu_fpp.cpp b/src/jit/compemu_fpp.cpp index 80118207..4b75966b 100644 --- a/src/jit/compemu_fpp.cpp +++ b/src/jit/compemu_fpp.cpp @@ -497,6 +497,11 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra) int source = (extra >> 13) & 7; int opmode = extra & 0x7f; + if (special_mem) { + FAIL(1); + return; + } + if (!currprefs.compfpu) { FAIL (1); return; @@ -525,6 +530,25 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra) if (extra & 0x1000) { /* FPCR */ uae_u32 val = comp_get_ilong ((m68k_pc_offset += 4) - 4); mov_l_mi (uae_p32(®s.fpcr), val); + switch(val & 0x30) { + case 0x00: + // round to nearest + roundingmode(0x00000000); + break; + case 0x10: + // round toward minus infinity + roundingmode(0x00800000); + break; + case 0x01: + // round toward plus infinity + roundingmode(0x00400000); + break; + case 0x11: + default: + // round towards zero + roundingmode(0x00c00000); + break; + } return; } if (extra & 0x0800) { /* FPSR */ @@ -875,11 +899,6 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra) case 0x37: FAIL (1); return; -// if (dreg == (extra & 7)) -// ffunc_rr (sin, dreg, sreg); -// else -// fsincos_rr (dreg, extra & 7, sreg); -// break; case 0x38: /* FCMP */ fmov_rr (FP_RESULT, dreg); fsub_rr (FP_RESULT, sreg); diff --git a/src/jit/compemu_midfunc_arm.cpp b/src/jit/compemu_midfunc_arm.cpp index a4f7c2c3..ab9a93da 100644 --- a/src/jit/compemu_midfunc_arm.cpp +++ b/src/jit/compemu_midfunc_arm.cpp @@ -109,7 +109,7 @@ MIDFUNC(2,sign_extend_16_rr,(W4 d, RR2 s)) s = readreg(s, 2); d = writereg(d, 4); } - else { /* If we try to lock this twice, with different sizes, we are int trouble! */ + else { /* If we try to lock this twice, with different sizes, we are in trouble! */ s = d = rmw(s, 4, 2); } SIGNED16_REG_2_REG(d, s); @@ -628,7 +628,7 @@ MENDFUNC(2,fmov_to_s_rr,(W4 d, FR s)) MIDFUNC(2,fmov_to_w_rr,(W4 d, FR s)) { s = f_readreg(s); - d = rmw(d, 2, 4); + d = writereg(d, 2); raw_fmov_to_w_rr(d, s); unlock2(d); f_unlock(s); @@ -638,7 +638,7 @@ MENDFUNC(2,fmov_to_w_rr,(W4 d, FR s)) MIDFUNC(2,fmov_to_b_rr,(W4 d, FR s)) { s = f_readreg(s); - d = rmw(d, 1, 4); + d = writereg(d, 1); raw_fmov_to_b_rr(d, s); unlock2(d); f_unlock(s); @@ -864,54 +864,48 @@ MENDFUNC(2,fmovs_rr,(FW d, FR s)) MIDFUNC(3,ffunc_rr,(double (*func)(double), FW d, FR s)) { clobber_flags(); - prepare_for_call_1(); - prepare_for_call_2(); s = f_readreg(s); - d = f_writereg(d); + int reald = f_writereg(d); - raw_ffunc_rr(func, d, s); + prepare_for_call_1(); f_unlock(s); - f_unlock(d); + f_unlock(reald); + + prepare_for_call_2(); + + raw_ffunc_rr(func, reald, s); + + live.fat[reald].holds = d; + live.fat[reald].nholds = 1; + + live.fate[d].realreg = reald; + live.fate[d].status = DIRTY; } MENDFUNC(3,ffunc_rr,(double (*func)(double), FW d, FR s)) -//MIDFUNC(3,fsincos_rr,(FW d, FW c, FR s)) -//{ -// clobber_flags(); -// prepare_for_call_1(); -// prepare_for_call_2(); -// -// s = f_readreg(s); /* s for source */ -// d = f_writereg(d); /* d for sine */ -// c = f_writereg(c); /* c for cosine */ -// -// // s may be FS1, so we need to save it before we call external func -// -// raw_ffunc_rr(cos, c, s); -// raw_ffunc_rr(sin, d, s); -// -// f_unlock(s); -// f_unlock(d); -// f_unlock(c); -//} -//MENDFUNC(3,fsincos_rr,(FW d, FW c, FR s)) - MIDFUNC(3,fpowx_rr,(uae_u32 x, FW d, FR s)) { clobber_flags(); - prepare_for_call_1(); - prepare_for_call_2(); s = f_readreg(s); - d = f_writereg(d); + int reald = f_writereg(d); - raw_fpowx_rr(x, d, s); + prepare_for_call_1(); f_unlock(s); - f_unlock(d); + f_unlock(reald); + prepare_for_call_2(); + + raw_fpowx_rr(x, reald, s); + + live.fat[reald].holds = d; + live.fat[reald].nholds = 1; + + live.fate[d].realreg = reald; + live.fate[d].status = DIRTY; } MENDFUNC(3,fpowx_rr,(uae_u32 x, FW d, FR s)) @@ -954,4 +948,11 @@ MIDFUNC(2,fp_fscc_ri,(RW4 d, int cc)) } MENDFUNC(2,fp_fscc_ri,(RW4 d, int cc)) +MIDFUNC(1,roundingmode,(IMM mode)) +{ + raw_roundingmode(mode); +} +MENDFUNC(1,roundingmode,(IMM mode)) + + #endif // USE_JIT_FPU diff --git a/src/jit/compemu_midfunc_arm.h b/src/jit/compemu_midfunc_arm.h index cc52356c..c8b4f0c3 100644 --- a/src/jit/compemu_midfunc_arm.h +++ b/src/jit/compemu_midfunc_arm.h @@ -111,3 +111,4 @@ DECLARE_MIDFUNC(fflags_into_flags()); DECLARE_MIDFUNC(fp_from_exten_mr(RR4 adr, FR s)); DECLARE_MIDFUNC(fp_to_exten_rm(FW d, RR4 adr)); DECLARE_MIDFUNC(fp_fscc_ri(RW4, int cc)); +DECLARE_MIDFUNC(roundingmode(IMM mode)); diff --git a/src/jit/compemu_midfunc_arm2.cpp b/src/jit/compemu_midfunc_arm2.cpp index d0491be8..bc3717c6 100644 --- a/src/jit/compemu_midfunc_arm2.cpp +++ b/src/jit/compemu_midfunc_arm2.cpp @@ -1852,28 +1852,44 @@ MENDFUNC(2,jff_DBCC,(RR2 d, IMM cc)) * C Always cleared. * */ -// ToDo: How to handle exceptions (division by zero). Performance improvement isn't big, so this is on hold. MIDFUNC(3,jnf_DIVU,(W4 d, RR4 s1, RR4 s2)) { s1 = readreg(s1, 4); s2 = readreg(s2, 4); d = writereg(d, 4); - VMOV32_sr(0, s1); // move to s0 - VMOV32_sr(1, s2); // move to s1 - VCVTIto64_ds(2, 0); // convert s0 to d2 (int to float) - VCVTIto64_ds(3, 1); // convert s1 to d3 (int to float) - VDIV64_ddd(4, 2, 3); // d4 = d2 / d3 - VCVT64toI_sd(0, 4); // convert d4 to s0 (float to int) - VMOV32_rs(REG_WORK1, 0); // move from s0 + UNSIGNED16_REG_2_REG(REG_WORK3, s2); + TST_rr(REG_WORK3, REG_WORK3); + BNE_i(6); // src is not 0 + + // Signal exception 5 + MOV_ri(REG_WORK1, 5); + MOVW_ri16(REG_WORK2, (uae_u32)(&jit_exception)); + MOVT_ri16(REG_WORK2, ((uae_u32)(&jit_exception)) >> 16); + STR_rR(REG_WORK1, REG_WORK2); + + // simplified flag handling for div0: set Z and V (for signed DIV: Z only) + MOV_ri(REG_WORK1, ARM_Z_FLAG | ARM_V_FLAG); + MSR_CPSRf_r(REG_WORK1); + B_i(11); // end_of_op + +// src is not 0 + VMOVi_from_ARM_dr(SCRATCH_F64_1, s1, 0); + VMOVi_from_ARM_dr(SCRATCH_F64_2, REG_WORK3, 0); + VCVTIuto64_ds(SCRATCH_F64_1, SCRATCH_F32_1); + VCVTIuto64_ds(SCRATCH_F64_2, SCRATCH_F32_2); + VDIV64_ddd(SCRATCH_F64_3, SCRATCH_F64_1, SCRATCH_F64_2); + VCVT64toIu_sd(SCRATCH_F32_1, SCRATCH_F64_3); + VMOVi_to_ARM_rd(REG_WORK1, SCRATCH_F64_1, 0); LSRS_rri(REG_WORK2, REG_WORK1, 16); // if result of this is not 0, DIVU overflows -> no result BNE_i(2); // Here we have to calc reminder - MUL_rrr(REG_WORK2, REG_WORK1, s2); + MUL_rrr(REG_WORK2, REG_WORK1, REG_WORK3); SUB_rrr(REG_WORK2, s1, REG_WORK2); PKHBT_rrrLSLi(d, REG_WORK1, REG_WORK2, 16); +// end_of_op unlock2(d); unlock2(s1); @@ -1887,13 +1903,29 @@ MIDFUNC(3,jff_DIVU,(W4 d, RR4 s1, RR4 s2)) s2 = readreg(s2, 4); d = writereg(d, 4); - VMOV32_sr(0, s1); // move to s0 - VMOV32_sr(1, s2); // move to s1 - VCVTIto64_ds(2, 0); // convert s0 to d2 (int to float) - VCVTIto64_ds(3, 1); // convert s1 to d3 (int to float) - VDIV64_ddd(4, 2, 3); // d4 = d2 / d3 - VCVT64toI_sd(0, 4); // convert d4 to s0 (float to int) - VMOV32_rs(REG_WORK1, 0); // move from s0 + UNSIGNED16_REG_2_REG(REG_WORK3, s2); + TST_rr(REG_WORK3, REG_WORK3); + BNE_i(6); // src is not 0 + + // Signal exception 5 + MOV_ri(REG_WORK1, 5); + MOVW_ri16(REG_WORK2, (uae_u32)(&jit_exception)); + MOVT_ri16(REG_WORK2, ((uae_u32)(&jit_exception)) >> 16); + STR_rR(REG_WORK1, REG_WORK2); + + // simplified flag handling for div0: set Z and V (for signed DIV: Z only) + MOV_ri(REG_WORK1, ARM_Z_FLAG | ARM_V_FLAG); + MSR_CPSRf_r(REG_WORK1); + B_i(18); // end_of_op + +// src is not 0 + VMOVi_from_ARM_dr(SCRATCH_F64_1, s1, 0); + VMOVi_from_ARM_dr(SCRATCH_F64_2, REG_WORK3, 0); + VCVTIuto64_ds(SCRATCH_F64_1, SCRATCH_F32_1); + VCVTIuto64_ds(SCRATCH_F64_2, SCRATCH_F32_2); + VDIV64_ddd(SCRATCH_F64_3, SCRATCH_F64_1, SCRATCH_F64_2); + VCVT64toIu_sd(SCRATCH_F32_1, SCRATCH_F64_3); + VMOVi_to_ARM_rd(REG_WORK1, SCRATCH_F64_1, 0); LSRS_rri(REG_WORK2, REG_WORK1, 16); // if result of this is not 0, DIVU overflows BEQ_i(2); @@ -1908,9 +1940,10 @@ MIDFUNC(3,jff_DIVU,(W4 d, RR4 s1, RR4 s2)) BIC_rri(REG_WORK2, REG_WORK2, ARM_C_FLAG | ARM_V_FLAG); MSR_CPSRf_r(REG_WORK2); - MUL_rrr(REG_WORK2, REG_WORK1, s2); + MUL_rrr(REG_WORK2, REG_WORK1, REG_WORK3); SUB_rrr(REG_WORK2, s1, REG_WORK2); PKHBT_rrrLSLi(d, REG_WORK1, REG_WORK2, 16); +// end_of_op unlock2(d); unlock2(s1); @@ -1918,6 +1951,138 @@ MIDFUNC(3,jff_DIVU,(W4 d, RR4 s1, RR4 s2)) } MENDFUNC(3,jff_DIVU,(W4 d, RR4 s1, RR4 s2)) +/* + * DIVS + * + * X Not affected. + * N Set if the most significant bit of the result is set or overflow. Cleared otherwise. + * Z Set if the result is zero. Cleared otherwise. + * V Set if overflow. Cleared otherwise. + * C Always cleared. + * + */ +MIDFUNC(3,jnf_DIVS,(W4 d, RR4 s1, RR4 s2)) +{ + s1 = readreg(s1, 4); + s2 = readreg(s2, 4); + d = writereg(d, 4); + + SIGNED16_REG_2_REG(REG_WORK3, s2); + TST_rr(REG_WORK3, REG_WORK3); + BNE_i(6); // src is not 0 + + // Signal exception 5 + MOV_ri(REG_WORK1, 5); + MOVW_ri16(REG_WORK2, (uae_u32)(&jit_exception)); + MOVT_ri16(REG_WORK2, ((uae_u32)(&jit_exception)) >> 16); + STR_rR(REG_WORK1, REG_WORK2); + + // simplified flag handling for div0: set Z and V (for signed DIV: Z only) + MOV_ri(REG_WORK1, ARM_Z_FLAG); + MSR_CPSRf_r(REG_WORK1); + B_i(18); // end_of_op + +// src is not 0 + VMOVi_from_ARM_dr(SCRATCH_F64_1, s1, 0); + VMOVi_from_ARM_dr(SCRATCH_F64_2, REG_WORK3, 0); + VCVTIto64_ds(SCRATCH_F64_1, SCRATCH_F32_1); + VCVTIto64_ds(SCRATCH_F64_2, SCRATCH_F32_2); + VDIV64_ddd(SCRATCH_F64_3, SCRATCH_F64_1, SCRATCH_F64_2); + VCVT64toI_sd(SCRATCH_F32_1, SCRATCH_F64_3); + VMOVi_to_ARM_rd(REG_WORK1, SCRATCH_F64_1, 0); + + // check for overflow + MVN_ri(REG_WORK2, 0); + LSL_rri(REG_WORK2, REG_WORK2, 15); // REG_WORK2 is now 0xffff8000 + ANDS_rrr(REG_WORK3, REG_WORK1, REG_WORK2); + BEQ_i(1); // positive result, no overflow + CMP_rr(REG_WORK3, REG_WORK2); + BNE_i(5); // overflow -> end_of_op + + // Here we have to calc reminder + SIGNED16_REG_2_REG(REG_WORK3, s2); + MUL_rrr(REG_WORK2, REG_WORK1, REG_WORK3); + SUB_rrr(REG_WORK2, s1, REG_WORK2); // REG_WORK2 contains remainder + + EORS_rrr(REG_WORK3, REG_WORK2, s1); // If sign of remainder and first operand differs, change sign of remainder + CC_RSB_rri(NATIVE_CC_MI, REG_WORK2, REG_WORK2, 0); + + PKHBT_rrrLSLi(d, REG_WORK1, REG_WORK2, 16); +// end_of_op + + unlock2(d); + unlock2(s1); + unlock2(s2); +} +MENDFUNC(3,jnf_DIVS,(W4 d, RR4 s1, RR4 s2)) + +MIDFUNC(3,jff_DIVS,(W4 d, RR4 s1, RR4 s2)) +{ + s1 = readreg(s1, 4); + s2 = readreg(s2, 4); + d = writereg(d, 4); + + SIGNED16_REG_2_REG(REG_WORK3, s2); + TST_rr(REG_WORK3, REG_WORK3); + BNE_i(6); // src is not 0 + + // Signal exception 5 + MOV_ri(REG_WORK1, 5); + MOVW_ri16(REG_WORK2, (uae_u32)(&jit_exception)); + MOVT_ri16(REG_WORK2, ((uae_u32)(&jit_exception)) >> 16); + STR_rR(REG_WORK1, REG_WORK2); + + // simplified flag handling for div0: set Z and V (for signed DIV: Z only) + MOV_ri(REG_WORK1, ARM_Z_FLAG); + MSR_CPSRf_r(REG_WORK1); + B_i(25); // end_of_op + +// src is not 0 + VMOVi_from_ARM_dr(SCRATCH_F64_1, s1, 0); + VMOVi_from_ARM_dr(SCRATCH_F64_2, REG_WORK3, 0); + VCVTIto64_ds(SCRATCH_F64_1, SCRATCH_F32_1); + VCVTIto64_ds(SCRATCH_F64_2, SCRATCH_F32_2); + VDIV64_ddd(SCRATCH_F64_3, SCRATCH_F64_1, SCRATCH_F64_2); + VCVT64toI_sd(SCRATCH_F32_1, SCRATCH_F64_3); + VMOVi_to_ARM_rd(REG_WORK1, SCRATCH_F64_1, 0); + + // check for overflow + MVN_ri(REG_WORK2, 0); + LSL_rri(REG_WORK2, REG_WORK2, 15); // REG_WORK2 is now 0xffff8000 + ANDS_rrr(REG_WORK3, REG_WORK1, REG_WORK2); + BEQ_i(4); // positive result, no overflow + CMP_rr(REG_WORK3, REG_WORK2); + BEQ_i(2); // no overflow + + // Here we handle overflow + MOV_ri(REG_WORK1, ARM_V_FLAG | ARM_N_FLAG); + MSR_CPSRf_r(REG_WORK1); + B_i(9); + + // calc flags + LSLS_rri(REG_WORK2, REG_WORK1, 16); // N and Z ok + MRS_CPSR(REG_WORK2); + BIC_rri(REG_WORK2, REG_WORK2, ARM_C_FLAG | ARM_V_FLAG); + MSR_CPSRf_r(REG_WORK2); + + // calc remainder + SIGNED16_REG_2_REG(REG_WORK3, s2); + MUL_rrr(REG_WORK2, REG_WORK1, REG_WORK3); + SUB_rrr(REG_WORK2, s1, REG_WORK2); // REG_WORK2 contains remainder + + EORS_rrr(REG_WORK3, REG_WORK2, s1); // If sign of remainder and first operand differs, change sign of remainder + CC_RSB_rri(NATIVE_CC_MI, REG_WORK2, REG_WORK2, 0); + + PKHBT_rrrLSLi(d, REG_WORK1, REG_WORK2, 16); + +// end_of_op + + unlock2(d); + unlock2(s1); + unlock2(s2); +} +MENDFUNC(3,jff_DIVS,(W4 d, RR4 s1, RR4 s2)) + /* * EOR * Operand Syntax: Dn, @@ -5114,7 +5279,7 @@ MIDFUNC(2,jnf_MEM_WRITE_OFF_b,(RR4 adr, RR4 b)) LDR_rRI(REG_WORK2, R_REGSTRUCT, offs); adr = readreg(adr, 4); - b = readreg(b, 4); + b = readreg(b, 1); STRB_rRR(b, adr, REG_WORK2); @@ -5129,7 +5294,7 @@ MIDFUNC(2,jnf_MEM_WRITE_OFF_w,(RR4 adr, RR4 w)) LDR_rRI(REG_WORK2, R_REGSTRUCT, offs); adr = readreg(adr, 4); - w = readreg(w, 4); + w = readreg(w, 2); REV16_rr(REG_WORK1, w); STRH_rRR(REG_WORK1, adr, REG_WORK2); @@ -5162,7 +5327,7 @@ MIDFUNC(2,jnf_MEM_READ_OFF_b,(W4 d, RR4 adr)) LDR_rRI(REG_WORK2, R_REGSTRUCT, offs); adr = readreg(adr, 4); - d = writereg(d, 4); + d = writereg(d, 1); LDRB_rRR(d, adr, REG_WORK2); @@ -5177,7 +5342,7 @@ MIDFUNC(2,jnf_MEM_READ_OFF_w,(W4 d, RR4 adr)) LDR_rRI(REG_WORK2, R_REGSTRUCT, offs); adr = readreg(adr, 4); - d = writereg(d, 4); + d = writereg(d, 2); LDRH_rRR(REG_WORK1, adr, REG_WORK2); REV16_rr(d, REG_WORK1); @@ -5210,7 +5375,7 @@ MIDFUNC(2,jnf_MEM_WRITE24_OFF_b,(RR4 adr, RR4 b)) LDR_rRI(REG_WORK2, R_REGSTRUCT, offs); adr = readreg(adr, 4); - b = readreg(b, 4); + b = readreg(b, 1); BIC_rri(REG_WORK1, adr, 0xff000000); STRB_rRR(b, REG_WORK1, REG_WORK2); @@ -5226,7 +5391,7 @@ MIDFUNC(2,jnf_MEM_WRITE24_OFF_w,(RR4 adr, RR4 w)) LDR_rRI(REG_WORK2, R_REGSTRUCT, offs); adr = readreg(adr, 4); - w = readreg(w, 4); + w = readreg(w, 2); BIC_rri(REG_WORK1, adr, 0xff000000); REV16_rr(REG_WORK3, w); @@ -5261,7 +5426,7 @@ MIDFUNC(2,jnf_MEM_READ24_OFF_b,(W4 d, RR4 adr)) LDR_rRI(REG_WORK2, R_REGSTRUCT, offs); adr = readreg(adr, 4); - d = writereg(d, 4); + d = writereg(d, 1); BIC_rri(REG_WORK1, adr, 0xff000000); LDRB_rRR(d, REG_WORK1, REG_WORK2); @@ -5277,7 +5442,7 @@ MIDFUNC(2,jnf_MEM_READ24_OFF_w,(W4 d, RR4 adr)) LDR_rRI(REG_WORK2, R_REGSTRUCT, offs); adr = readreg(adr, 4); - d = writereg(d, 4); + d = writereg(d, 2); BIC_rri(REG_WORK1, adr, 0xff000000); LDRH_rRR(REG_WORK1, REG_WORK1, REG_WORK2); diff --git a/src/jit/compemu_midfunc_arm2.h b/src/jit/compemu_midfunc_arm2.h index 83940411..333db46e 100644 --- a/src/jit/compemu_midfunc_arm2.h +++ b/src/jit/compemu_midfunc_arm2.h @@ -161,6 +161,10 @@ DECLARE_MIDFUNC(jff_DBCC(RR2 d, IMM cc)); DECLARE_MIDFUNC(jnf_DIVU(W4 d, RR4 s1, RR4 s2)); DECLARE_MIDFUNC(jff_DIVU(W4 d, RR4 s1, RR4 s2)); +// DIVS +DECLARE_MIDFUNC(jnf_DIVS(W4 d, RR4 s1, RR4 s2)); +DECLARE_MIDFUNC(jff_DIVS(W4 d, RR4 s1, RR4 s2)); + // EOR DECLARE_MIDFUNC(jnf_EOR(W4 d, RR4 s, RR4 v)); DECLARE_MIDFUNC(jff_EOR_b(W4 d, RR1 s, RR1 v)); diff --git a/src/jit/compemu_support.cpp b/src/jit/compemu_support.cpp index 2044156d..9e67cd4b 100644 --- a/src/jit/compemu_support.cpp +++ b/src/jit/compemu_support.cpp @@ -126,6 +126,10 @@ static int optcount[10] = { op_properties prop[65536]; +uae_u32 jit_exception = 0; +bool may_raise_exception = false; + + STATIC_INLINE bool is_const_jump(uae_u32 opcode) { return (prop[opcode].cflow == fl_const_jump); @@ -160,6 +164,7 @@ static void* popall_execute_normal = NULL; static void* popall_cache_miss = NULL; static void* popall_recompile_block = NULL; static void* popall_check_checksum = NULL; +static void* popall_execute_exception = NULL; /* The 68k only ever executes from even addresses. So right now, we * waste half the entries in this array @@ -1393,7 +1398,6 @@ STATIC_INLINE void f_disassociate(int r) f_evict(r); } - static int f_alloc_reg(int r, int willclobber) { int bestreg; @@ -1651,6 +1655,8 @@ void init_comp(void) live.flags_in_flags = TRASH; live.flags_on_stack = VALID; live.flags_are_important = 1; + + jit_exception = 0; } /* Only do this if you really mean it! The next call should be to init!*/ @@ -1797,6 +1803,11 @@ void register_branch(uae_u32 not_taken, uae_u32 taken, uae_u8 cond) branch_cc = cond; } +void register_possible_exception(void) +{ + may_raise_exception = true; +} + /* Note: get_handler may fail in 64 Bit environments, if direct_handler_to_use is * outside 32 bit */ @@ -2379,6 +2390,12 @@ STATIC_INLINE void create_popalls(void) raw_pop_preserved_regs(); compemu_raw_jmp(uae_p32(check_checksum)); + align_target(align_jumps); + popall_execute_exception = get_target(); + raw_inc_sp(stack_space); + raw_pop_preserved_regs(); + compemu_raw_jmp(uae_p32(execute_exception)); + #if defined(CPU_arm) && !defined(ARMV6T2) reset_data_buffer(); #endif @@ -2776,6 +2793,7 @@ void compile_block(cpu_history* pc_hist, int blocklen, int totcycles) was_comp = 1; for (i = 0; i < blocklen && get_target_noopt() < MAX_COMPILE_PTR; i++) { + may_raise_exception = false; cpuop_func **cputbl; compop_func **comptbl; uae_u32 opcode = DO_GET_OPCODE(pc_hist[i].location); @@ -2845,6 +2863,9 @@ void compile_block(cpu_history* pc_hist, int blocklen, int totcycles) compemu_raw_jmp((uintptr)popall_do_nothing); *(branchadd - 4) = (((uintptr)get_target() - (uintptr)branchadd) - 4) >> 2; } + } else if(may_raise_exception) { + compemu_raw_handle_except(scaled_cycles(totcycles)); + may_raise_exception = false; } } diff --git a/src/jit/compstbl.cpp b/src/jit/compstbl.cpp index c04e1724..72cef950 100644 --- a/src/jit/compstbl.cpp +++ b/src/jit/compstbl.cpp @@ -1246,17 +1246,17 @@ extern const struct comptbl op_smalltbl_0_comp_ff[] = { { op_80ba_0_comp_ff, 0x00000002, 32954 }, /* OR */ { op_80bb_0_comp_ff, 0x00000002, 32955 }, /* OR */ { op_80bc_0_comp_ff, 0x00000002, 32956 }, /* OR */ -{ NULL, 0x00000001, 32960 }, /* DIVU */ -{ NULL, 0x00000001, 32976 }, /* DIVU */ -{ NULL, 0x00000001, 32984 }, /* DIVU */ -{ NULL, 0x00000001, 32992 }, /* DIVU */ -{ NULL, 0x00000003, 33000 }, /* DIVU */ -{ NULL, 0x00000003, 33008 }, /* DIVU */ -{ NULL, 0x00000003, 33016 }, /* DIVU */ -{ NULL, 0x00000003, 33017 }, /* DIVU */ -{ NULL, 0x00000003, 33018 }, /* DIVU */ -{ NULL, 0x00000003, 33019 }, /* DIVU */ -{ NULL, 0x00000003, 33020 }, /* DIVU */ +{ op_80c0_0_comp_ff, 0x00000000, 32960 }, /* DIVU */ +{ op_80d0_0_comp_ff, 0x00000000, 32976 }, /* DIVU */ +{ op_80d8_0_comp_ff, 0x00000000, 32984 }, /* DIVU */ +{ op_80e0_0_comp_ff, 0x00000000, 32992 }, /* DIVU */ +{ op_80e8_0_comp_ff, 0x00000002, 33000 }, /* DIVU */ +{ op_80f0_0_comp_ff, 0x00000002, 33008 }, /* DIVU */ +{ op_80f8_0_comp_ff, 0x00000002, 33016 }, /* DIVU */ +{ op_80f9_0_comp_ff, 0x00000002, 33017 }, /* DIVU */ +{ op_80fa_0_comp_ff, 0x00000002, 33018 }, /* DIVU */ +{ op_80fb_0_comp_ff, 0x00000002, 33019 }, /* DIVU */ +{ op_80fc_0_comp_ff, 0x00000002, 33020 }, /* DIVU */ { NULL, 0x00000000, 33024 }, /* SBCD */ { NULL, 0x00000000, 33032 }, /* SBCD */ { op_8110_0_comp_ff, 0x00000000, 33040 }, /* OR */ @@ -1284,17 +1284,17 @@ extern const struct comptbl op_smalltbl_0_comp_ff[] = { { op_81b0_0_comp_ff, 0x00000002, 33200 }, /* OR */ { op_81b8_0_comp_ff, 0x00000002, 33208 }, /* OR */ { op_81b9_0_comp_ff, 0x00000002, 33209 }, /* OR */ -{ NULL, 0x00000001, 33216 }, /* DIVS */ -{ NULL, 0x00000001, 33232 }, /* DIVS */ -{ NULL, 0x00000001, 33240 }, /* DIVS */ -{ NULL, 0x00000001, 33248 }, /* DIVS */ -{ NULL, 0x00000001, 33256 }, /* DIVS */ -{ NULL, 0x00000001, 33264 }, /* DIVS */ -{ NULL, 0x00000001, 33272 }, /* DIVS */ -{ NULL, 0x00000001, 33273 }, /* DIVS */ -{ NULL, 0x00000001, 33274 }, /* DIVS */ -{ NULL, 0x00000001, 33275 }, /* DIVS */ -{ NULL, 0x00000001, 33276 }, /* DIVS */ +{ op_81c0_0_comp_ff, 0x00000000, 33216 }, /* DIVS */ +{ op_81d0_0_comp_ff, 0x00000000, 33232 }, /* DIVS */ +{ op_81d8_0_comp_ff, 0x00000000, 33240 }, /* DIVS */ +{ op_81e0_0_comp_ff, 0x00000000, 33248 }, /* DIVS */ +{ op_81e8_0_comp_ff, 0x00000002, 33256 }, /* DIVS */ +{ op_81f0_0_comp_ff, 0x00000002, 33264 }, /* DIVS */ +{ op_81f8_0_comp_ff, 0x00000002, 33272 }, /* DIVS */ +{ op_81f9_0_comp_ff, 0x00000002, 33273 }, /* DIVS */ +{ op_81fa_0_comp_ff, 0x00000002, 33274 }, /* DIVS */ +{ op_81fb_0_comp_ff, 0x00000002, 33275 }, /* DIVS */ +{ op_81fc_0_comp_ff, 0x00000002, 33276 }, /* DIVS */ { op_9000_0_comp_ff, 0x00000000, 36864 }, /* SUB */ { op_9010_0_comp_ff, 0x00000000, 36880 }, /* SUB */ { op_9018_0_comp_ff, 0x00000000, 36888 }, /* SUB */ @@ -3118,17 +3118,17 @@ extern const struct comptbl op_smalltbl_0_comp_nf[] = { { op_80ba_0_comp_nf, 0x00000002, 32954 }, /* OR */ { op_80bb_0_comp_nf, 0x00000002, 32955 }, /* OR */ { op_80bc_0_comp_nf, 0x00000002, 32956 }, /* OR */ -{ NULL, 0x00000001, 32960 }, /* DIVU */ -{ NULL, 0x00000001, 32976 }, /* DIVU */ -{ NULL, 0x00000001, 32984 }, /* DIVU */ -{ NULL, 0x00000001, 32992 }, /* DIVU */ -{ NULL, 0x00000003, 33000 }, /* DIVU */ -{ NULL, 0x00000003, 33008 }, /* DIVU */ -{ NULL, 0x00000003, 33016 }, /* DIVU */ -{ NULL, 0x00000003, 33017 }, /* DIVU */ -{ NULL, 0x00000003, 33018 }, /* DIVU */ -{ NULL, 0x00000003, 33019 }, /* DIVU */ -{ NULL, 0x00000003, 33020 }, /* DIVU */ +{ op_80c0_0_comp_nf, 0x00000000, 32960 }, /* DIVU */ +{ op_80d0_0_comp_nf, 0x00000000, 32976 }, /* DIVU */ +{ op_80d8_0_comp_nf, 0x00000000, 32984 }, /* DIVU */ +{ op_80e0_0_comp_nf, 0x00000000, 32992 }, /* DIVU */ +{ op_80e8_0_comp_nf, 0x00000002, 33000 }, /* DIVU */ +{ op_80f0_0_comp_nf, 0x00000002, 33008 }, /* DIVU */ +{ op_80f8_0_comp_nf, 0x00000002, 33016 }, /* DIVU */ +{ op_80f9_0_comp_nf, 0x00000002, 33017 }, /* DIVU */ +{ op_80fa_0_comp_nf, 0x00000002, 33018 }, /* DIVU */ +{ op_80fb_0_comp_nf, 0x00000002, 33019 }, /* DIVU */ +{ op_80fc_0_comp_nf, 0x00000002, 33020 }, /* DIVU */ { NULL, 0x00000000, 33024 }, /* SBCD */ { NULL, 0x00000000, 33032 }, /* SBCD */ { op_8110_0_comp_nf, 0x00000000, 33040 }, /* OR */ @@ -3156,17 +3156,17 @@ extern const struct comptbl op_smalltbl_0_comp_nf[] = { { op_81b0_0_comp_nf, 0x00000002, 33200 }, /* OR */ { op_81b8_0_comp_nf, 0x00000002, 33208 }, /* OR */ { op_81b9_0_comp_nf, 0x00000002, 33209 }, /* OR */ -{ NULL, 0x00000001, 33216 }, /* DIVS */ -{ NULL, 0x00000001, 33232 }, /* DIVS */ -{ NULL, 0x00000001, 33240 }, /* DIVS */ -{ NULL, 0x00000001, 33248 }, /* DIVS */ -{ NULL, 0x00000001, 33256 }, /* DIVS */ -{ NULL, 0x00000001, 33264 }, /* DIVS */ -{ NULL, 0x00000001, 33272 }, /* DIVS */ -{ NULL, 0x00000001, 33273 }, /* DIVS */ -{ NULL, 0x00000001, 33274 }, /* DIVS */ -{ NULL, 0x00000001, 33275 }, /* DIVS */ -{ NULL, 0x00000001, 33276 }, /* DIVS */ +{ op_81c0_0_comp_nf, 0x00000000, 33216 }, /* DIVS */ +{ op_81d0_0_comp_nf, 0x00000000, 33232 }, /* DIVS */ +{ op_81d8_0_comp_nf, 0x00000000, 33240 }, /* DIVS */ +{ op_81e0_0_comp_nf, 0x00000000, 33248 }, /* DIVS */ +{ op_81e8_0_comp_nf, 0x00000002, 33256 }, /* DIVS */ +{ op_81f0_0_comp_nf, 0x00000002, 33264 }, /* DIVS */ +{ op_81f8_0_comp_nf, 0x00000002, 33272 }, /* DIVS */ +{ op_81f9_0_comp_nf, 0x00000002, 33273 }, /* DIVS */ +{ op_81fa_0_comp_nf, 0x00000002, 33274 }, /* DIVS */ +{ op_81fb_0_comp_nf, 0x00000002, 33275 }, /* DIVS */ +{ op_81fc_0_comp_nf, 0x00000002, 33276 }, /* DIVS */ { op_9000_0_comp_nf, 0x00000000, 36864 }, /* SUB */ { op_9010_0_comp_nf, 0x00000000, 36880 }, /* SUB */ { op_9018_0_comp_nf, 0x00000000, 36888 }, /* SUB */ diff --git a/src/jit/comptbl.h b/src/jit/comptbl.h index a7b1550b..9a5735db 100644 --- a/src/jit/comptbl.h +++ b/src/jit/comptbl.h @@ -1010,6 +1010,17 @@ extern compop_func op_80b9_0_comp_ff; extern compop_func op_80ba_0_comp_ff; extern compop_func op_80bb_0_comp_ff; extern compop_func op_80bc_0_comp_ff; +extern compop_func op_80c0_0_comp_ff; +extern compop_func op_80d0_0_comp_ff; +extern compop_func op_80d8_0_comp_ff; +extern compop_func op_80e0_0_comp_ff; +extern compop_func op_80e8_0_comp_ff; +extern compop_func op_80f0_0_comp_ff; +extern compop_func op_80f8_0_comp_ff; +extern compop_func op_80f9_0_comp_ff; +extern compop_func op_80fa_0_comp_ff; +extern compop_func op_80fb_0_comp_ff; +extern compop_func op_80fc_0_comp_ff; extern compop_func op_8110_0_comp_ff; extern compop_func op_8118_0_comp_ff; extern compop_func op_8120_0_comp_ff; @@ -1031,6 +1042,17 @@ extern compop_func op_81a8_0_comp_ff; extern compop_func op_81b0_0_comp_ff; extern compop_func op_81b8_0_comp_ff; extern compop_func op_81b9_0_comp_ff; +extern compop_func op_81c0_0_comp_ff; +extern compop_func op_81d0_0_comp_ff; +extern compop_func op_81d8_0_comp_ff; +extern compop_func op_81e0_0_comp_ff; +extern compop_func op_81e8_0_comp_ff; +extern compop_func op_81f0_0_comp_ff; +extern compop_func op_81f8_0_comp_ff; +extern compop_func op_81f9_0_comp_ff; +extern compop_func op_81fa_0_comp_ff; +extern compop_func op_81fb_0_comp_ff; +extern compop_func op_81fc_0_comp_ff; extern compop_func op_9000_0_comp_ff; extern compop_func op_9010_0_comp_ff; extern compop_func op_9018_0_comp_ff; @@ -2479,6 +2501,17 @@ extern compop_func op_80b9_0_comp_nf; extern compop_func op_80ba_0_comp_nf; extern compop_func op_80bb_0_comp_nf; extern compop_func op_80bc_0_comp_nf; +extern compop_func op_80c0_0_comp_nf; +extern compop_func op_80d0_0_comp_nf; +extern compop_func op_80d8_0_comp_nf; +extern compop_func op_80e0_0_comp_nf; +extern compop_func op_80e8_0_comp_nf; +extern compop_func op_80f0_0_comp_nf; +extern compop_func op_80f8_0_comp_nf; +extern compop_func op_80f9_0_comp_nf; +extern compop_func op_80fa_0_comp_nf; +extern compop_func op_80fb_0_comp_nf; +extern compop_func op_80fc_0_comp_nf; extern compop_func op_8110_0_comp_nf; extern compop_func op_8118_0_comp_nf; extern compop_func op_8120_0_comp_nf; @@ -2500,6 +2533,17 @@ extern compop_func op_81a8_0_comp_nf; extern compop_func op_81b0_0_comp_nf; extern compop_func op_81b8_0_comp_nf; extern compop_func op_81b9_0_comp_nf; +extern compop_func op_81c0_0_comp_nf; +extern compop_func op_81d0_0_comp_nf; +extern compop_func op_81d8_0_comp_nf; +extern compop_func op_81e0_0_comp_nf; +extern compop_func op_81e8_0_comp_nf; +extern compop_func op_81f0_0_comp_nf; +extern compop_func op_81f8_0_comp_nf; +extern compop_func op_81f9_0_comp_nf; +extern compop_func op_81fa_0_comp_nf; +extern compop_func op_81fb_0_comp_nf; +extern compop_func op_81fc_0_comp_nf; extern compop_func op_9000_0_comp_nf; extern compop_func op_9010_0_comp_nf; extern compop_func op_9018_0_comp_nf; diff --git a/src/jit/gencomp_arm.cpp b/src/jit/gencomp_arm.cpp index 5eb0791b..33448cff 100644 --- a/src/jit/gencomp_arm.cpp +++ b/src/jit/gencomp_arm.cpp @@ -123,7 +123,8 @@ //#define DISABLE_I_FSCC //#define DISABLE_I_MOVE16 -#define DISABLE_I_DIVU // DIVU works, but we have to think about exceptions. No big performance enhancement. +//#define DISABLE_I_DIVU +//#define DISABLE_I_DIVS #define RETURN "return 0;" @@ -1268,6 +1269,7 @@ static void gen_divu(uae_u32 opcode, struct instr *curi, char* ssize) { genamode(curi->dmode, "dstreg", sz_word, "dst", 1, 0); comprintf("\tint tmp=scratchie++;\n"); + comprintf("\tregister_possible_exception();\n"); if (!noflags) { comprintf("\tjff_DIVU(tmp,dst,src);\n"); comprintf("\tlive_flags();\n"); @@ -1275,7 +1277,27 @@ static void gen_divu(uae_u32 opcode, struct instr *curi, char* ssize) { comprintf("\tjnf_DIVU(tmp,dst,src);\n"); } - genastore("tmp", curi->dmode, "dstreg", curi->size, "dst"); + genastore("tmp", curi->dmode, "dstreg", sz_long /*curi->size*/, "dst"); +} + +static void gen_divs(uae_u32 opcode, struct instr *curi, char* ssize) { + (void)opcode; + (void)ssize; + comprintf("\t dont_care_flags();\n"); + genamode(curi->smode, "srcreg", sz_word, "src", 1, 0); + genamode(curi->dmode, "dstreg", sz_word, "dst", 1, 0); + + comprintf("\tint tmp=scratchie++;\n"); + comprintf("\tregister_possible_exception();\n"); + if (!noflags) { + comprintf("\tjff_DIVS(tmp,dst,src);\n"); + comprintf("\tlive_flags();\n"); + } + else { + comprintf("\tjnf_DIVS(tmp,dst,src);\n"); + } + + genastore("tmp", curi->dmode, "dstreg", sz_long /*curi->size*/, "dst"); } static void gen_eor(uae_u32 opcode, struct instr *curi, char* ssize) { @@ -2507,8 +2529,11 @@ gen_opcode(unsigned long int opcode) { break; case i_DIVS: +#ifdef DISABLE_I_DIVS isjump; failure; +#endif + gen_divs(opcode, curi, ssize); break; case i_MULU: @@ -3018,6 +3043,13 @@ generate_one_opcode(int rp, int noflags) dmsk = 7; next_cpu_level = -1; + if (table68k[opcode].mnemo == i_DIVU || table68k[opcode].mnemo == i_DIVS) { + comprintf("#ifndef ARMV6T2\n"); + comprintf(" FAIL(1);\n"); + comprintf(" " RETURN "\n"); + comprintf("#else\n"); + } + if (table68k[opcode].suse && table68k[opcode].smode != imm && table68k[opcode].smode != imm0 && table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2 @@ -3109,6 +3141,10 @@ generate_one_opcode(int rp, int noflags) if (global_fpu) flags |= 32; comprintf ("return 0;\n"); + if (table68k[opcode].mnemo == i_DIVU || table68k[opcode].mnemo == i_DIVS) { + comprintf("#endif\n"); + } + comprintf("}\n"); char name[100] = { 0 }; @@ -3132,6 +3168,7 @@ generate_one_opcode(int rp, int noflags) com_flush(); } } + opcode_next_clev[rp] = next_cpu_level; opcode_last_postfix[rp] = postfix; } diff --git a/src/newcpu.cpp b/src/newcpu.cpp index 6870e919..abc8be3f 100644 --- a/src/newcpu.cpp +++ b/src/newcpu.cpp @@ -1597,6 +1597,18 @@ static void m68k_run_1 (void) #ifdef JIT /* Completely different run_2 replacement */ +extern uae_u32 jit_exception; + +void execute_exception(void) +{ + Exception_cpu(jit_exception); + jit_exception = 0; + cpu_cycles = adjust_cycles(4 * CYCLE_UNIT / 2); + do_cycles (cpu_cycles); + // after leaving this function, we fall back to execute_normal() +} + + void do_nothing(void) { /* What did you expect this to do? */