Fixed JIT FPU bugs (Starstruck demo corruption, etc.)
This commit is contained in:
parent
88316d7916
commit
b9dc57af87
14 changed files with 1735 additions and 121 deletions
|
@ -943,6 +943,48 @@ STATIC_INLINE void compemu_raw_jcc_l_oponly(int cc)
|
||||||
// emit of target will be done by caller
|
// 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); // <popall_execute_exception>
|
||||||
|
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)
|
STATIC_INLINE void compemu_raw_jl(uae_u32 t)
|
||||||
{
|
{
|
||||||
#ifdef ARMV6T2
|
#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);
|
VCVTR64toI_sd(SCRATCH_F32_1, s);
|
||||||
VMOV32_rs(REG_WORK1, SCRATCH_F32_1);
|
VMOV32_rs(REG_WORK1, SCRATCH_F32_1);
|
||||||
SSAT_rir(REG_WORK1, 15, REG_WORK1);
|
SSAT_rir(d, 15, REG_WORK1);
|
||||||
BFI_rrii(d, REG_WORK1, 0, 15);
|
|
||||||
}
|
}
|
||||||
LENDFUNC(NONE,NONE,2,raw_fmov_to_w_rr,(W4 d, FR s))
|
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);
|
VCVTR64toI_sd(SCRATCH_F32_1, s);
|
||||||
VMOV32_rs(REG_WORK1, SCRATCH_F32_1);
|
VMOV32_rs(REG_WORK1, SCRATCH_F32_1);
|
||||||
SSAT_rir(REG_WORK1, 7, REG_WORK1);
|
SSAT_rir(d, 7, REG_WORK1);
|
||||||
BFI_rrii(d, REG_WORK1, 0, 7);
|
|
||||||
}
|
}
|
||||||
LENDFUNC(NONE,NONE,2,raw_fmov_to_b_rr,(W4 d, FR s))
|
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);
|
VMRS_r(REG_WORK2);
|
||||||
UBFX_rrii(REG_WORK1, REG_WORK1, 22, 2);
|
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);
|
VMSR_r(REG_WORK2);
|
||||||
}
|
}
|
||||||
LENDFUNC(NONE,NONE,2,raw_frem1_rr,(FRW d, FR s))
|
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);
|
ADD_rrr(REG_WORK1, adr, REG_WORK1);
|
||||||
|
|
||||||
REV_rr(REG_WORK3, REG_WORK3);
|
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
|
VSHL64_ddi(SCRATCH_F64_1, s, 11); // shift mantissa to correct position
|
||||||
VMOV64_rrd(REG_WORK3, REG_WORK2, SCRATCH_F64_1);
|
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
|
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
|
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
|
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
|
VSHR64_ddi(d, d, 11); // shift mantissa to correct position
|
||||||
LSL_rri(REG_WORK3, REG_WORK3, 20);
|
LSL_rri(REG_WORK3, REG_WORK3, 20);
|
||||||
VMOV_I64_dimmI(0, 0x00);
|
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
|
// 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)
|
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))
|
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
|
#endif // USE_JIT_FPU
|
||||||
|
|
|
@ -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 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 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 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 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 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 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 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 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))
|
#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 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 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 */
|
#endif /* ARM_RTASM_H */
|
||||||
|
|
1254
src/jit/compemu.cpp
1254
src/jit/compemu.cpp
File diff suppressed because it is too large
Load diff
|
@ -129,7 +129,6 @@ typedef union {
|
||||||
#endif
|
#endif
|
||||||
#define N_FREGS 16 // We use 10 regs: 6 - FP_RESULT, 7 - SCRATCH, 8-15 - Amiga regs FP0-FP7
|
#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
|
/* Functions exposed to newcpu, or to what was moved from newcpu.c to
|
||||||
* compemu_support.c */
|
* compemu_support.c */
|
||||||
extern void compiler_exit(void);
|
extern void compiler_exit(void);
|
||||||
|
@ -332,6 +331,7 @@ extern void sync_m68k_pc(void);
|
||||||
extern uae_u32 get_const(int r);
|
extern uae_u32 get_const(int r);
|
||||||
extern int is_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_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_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)))
|
#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 execute_normal(void);
|
||||||
void exec_nostats(void);
|
void exec_nostats(void);
|
||||||
void do_nothing(void);
|
void do_nothing(void);
|
||||||
|
void execute_exception(void);
|
||||||
|
|
||||||
/* ARAnyM uses fpu_register name, used in scratch_t */
|
/* ARAnyM uses fpu_register name, used in scratch_t */
|
||||||
/* FIXME: check that no ARAnyM code assumes different floating point type */
|
/* FIXME: check that no ARAnyM code assumes different floating point type */
|
||||||
|
|
|
@ -497,6 +497,11 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra)
|
||||||
int source = (extra >> 13) & 7;
|
int source = (extra >> 13) & 7;
|
||||||
int opmode = extra & 0x7f;
|
int opmode = extra & 0x7f;
|
||||||
|
|
||||||
|
if (special_mem) {
|
||||||
|
FAIL(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!currprefs.compfpu) {
|
if (!currprefs.compfpu) {
|
||||||
FAIL (1);
|
FAIL (1);
|
||||||
return;
|
return;
|
||||||
|
@ -525,6 +530,25 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra)
|
||||||
if (extra & 0x1000) { /* FPCR */
|
if (extra & 0x1000) { /* FPCR */
|
||||||
uae_u32 val = comp_get_ilong ((m68k_pc_offset += 4) - 4);
|
uae_u32 val = comp_get_ilong ((m68k_pc_offset += 4) - 4);
|
||||||
mov_l_mi (uae_p32(®s.fpcr), val);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
if (extra & 0x0800) { /* FPSR */
|
if (extra & 0x0800) { /* FPSR */
|
||||||
|
@ -875,11 +899,6 @@ void comp_fpp_opp (uae_u32 opcode, uae_u16 extra)
|
||||||
case 0x37:
|
case 0x37:
|
||||||
FAIL (1);
|
FAIL (1);
|
||||||
return;
|
return;
|
||||||
// if (dreg == (extra & 7))
|
|
||||||
// ffunc_rr (sin, dreg, sreg);
|
|
||||||
// else
|
|
||||||
// fsincos_rr (dreg, extra & 7, sreg);
|
|
||||||
// break;
|
|
||||||
case 0x38: /* FCMP */
|
case 0x38: /* FCMP */
|
||||||
fmov_rr (FP_RESULT, dreg);
|
fmov_rr (FP_RESULT, dreg);
|
||||||
fsub_rr (FP_RESULT, sreg);
|
fsub_rr (FP_RESULT, sreg);
|
||||||
|
|
|
@ -109,7 +109,7 @@ MIDFUNC(2,sign_extend_16_rr,(W4 d, RR2 s))
|
||||||
s = readreg(s, 2);
|
s = readreg(s, 2);
|
||||||
d = writereg(d, 4);
|
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);
|
s = d = rmw(s, 4, 2);
|
||||||
}
|
}
|
||||||
SIGNED16_REG_2_REG(d, s);
|
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))
|
MIDFUNC(2,fmov_to_w_rr,(W4 d, FR s))
|
||||||
{
|
{
|
||||||
s = f_readreg(s);
|
s = f_readreg(s);
|
||||||
d = rmw(d, 2, 4);
|
d = writereg(d, 2);
|
||||||
raw_fmov_to_w_rr(d, s);
|
raw_fmov_to_w_rr(d, s);
|
||||||
unlock2(d);
|
unlock2(d);
|
||||||
f_unlock(s);
|
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))
|
MIDFUNC(2,fmov_to_b_rr,(W4 d, FR s))
|
||||||
{
|
{
|
||||||
s = f_readreg(s);
|
s = f_readreg(s);
|
||||||
d = rmw(d, 1, 4);
|
d = writereg(d, 1);
|
||||||
raw_fmov_to_b_rr(d, s);
|
raw_fmov_to_b_rr(d, s);
|
||||||
unlock2(d);
|
unlock2(d);
|
||||||
f_unlock(s);
|
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))
|
MIDFUNC(3,ffunc_rr,(double (*func)(double), FW d, FR s))
|
||||||
{
|
{
|
||||||
clobber_flags();
|
clobber_flags();
|
||||||
prepare_for_call_1();
|
|
||||||
prepare_for_call_2();
|
|
||||||
|
|
||||||
s = f_readreg(s);
|
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(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))
|
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))
|
MIDFUNC(3,fpowx_rr,(uae_u32 x, FW d, FR s))
|
||||||
{
|
{
|
||||||
clobber_flags();
|
clobber_flags();
|
||||||
prepare_for_call_1();
|
|
||||||
prepare_for_call_2();
|
|
||||||
|
|
||||||
s = f_readreg(s);
|
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(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))
|
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))
|
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
|
#endif // USE_JIT_FPU
|
||||||
|
|
|
@ -111,3 +111,4 @@ DECLARE_MIDFUNC(fflags_into_flags());
|
||||||
DECLARE_MIDFUNC(fp_from_exten_mr(RR4 adr, FR s));
|
DECLARE_MIDFUNC(fp_from_exten_mr(RR4 adr, FR s));
|
||||||
DECLARE_MIDFUNC(fp_to_exten_rm(FW d, RR4 adr));
|
DECLARE_MIDFUNC(fp_to_exten_rm(FW d, RR4 adr));
|
||||||
DECLARE_MIDFUNC(fp_fscc_ri(RW4, int cc));
|
DECLARE_MIDFUNC(fp_fscc_ri(RW4, int cc));
|
||||||
|
DECLARE_MIDFUNC(roundingmode(IMM mode));
|
||||||
|
|
|
@ -1852,28 +1852,44 @@ MENDFUNC(2,jff_DBCC,(RR2 d, IMM cc))
|
||||||
* C Always cleared.
|
* 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))
|
MIDFUNC(3,jnf_DIVU,(W4 d, RR4 s1, RR4 s2))
|
||||||
{
|
{
|
||||||
s1 = readreg(s1, 4);
|
s1 = readreg(s1, 4);
|
||||||
s2 = readreg(s2, 4);
|
s2 = readreg(s2, 4);
|
||||||
d = writereg(d, 4);
|
d = writereg(d, 4);
|
||||||
|
|
||||||
VMOV32_sr(0, s1); // move to s0
|
UNSIGNED16_REG_2_REG(REG_WORK3, s2);
|
||||||
VMOV32_sr(1, s2); // move to s1
|
TST_rr(REG_WORK3, REG_WORK3);
|
||||||
VCVTIto64_ds(2, 0); // convert s0 to d2 (int to float)
|
BNE_i(6); // src is not 0
|
||||||
VCVTIto64_ds(3, 1); // convert s1 to d3 (int to float)
|
|
||||||
VDIV64_ddd(4, 2, 3); // d4 = d2 / d3
|
// Signal exception 5
|
||||||
VCVT64toI_sd(0, 4); // convert d4 to s0 (float to int)
|
MOV_ri(REG_WORK1, 5);
|
||||||
VMOV32_rs(REG_WORK1, 0); // move from s0
|
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
|
LSRS_rri(REG_WORK2, REG_WORK1, 16); // if result of this is not 0, DIVU overflows -> no result
|
||||||
BNE_i(2);
|
BNE_i(2);
|
||||||
|
|
||||||
// Here we have to calc reminder
|
// 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);
|
SUB_rrr(REG_WORK2, s1, REG_WORK2);
|
||||||
PKHBT_rrrLSLi(d, REG_WORK1, REG_WORK2, 16);
|
PKHBT_rrrLSLi(d, REG_WORK1, REG_WORK2, 16);
|
||||||
|
// end_of_op
|
||||||
|
|
||||||
unlock2(d);
|
unlock2(d);
|
||||||
unlock2(s1);
|
unlock2(s1);
|
||||||
|
@ -1887,13 +1903,29 @@ MIDFUNC(3,jff_DIVU,(W4 d, RR4 s1, RR4 s2))
|
||||||
s2 = readreg(s2, 4);
|
s2 = readreg(s2, 4);
|
||||||
d = writereg(d, 4);
|
d = writereg(d, 4);
|
||||||
|
|
||||||
VMOV32_sr(0, s1); // move to s0
|
UNSIGNED16_REG_2_REG(REG_WORK3, s2);
|
||||||
VMOV32_sr(1, s2); // move to s1
|
TST_rr(REG_WORK3, REG_WORK3);
|
||||||
VCVTIto64_ds(2, 0); // convert s0 to d2 (int to float)
|
BNE_i(6); // src is not 0
|
||||||
VCVTIto64_ds(3, 1); // convert s1 to d3 (int to float)
|
|
||||||
VDIV64_ddd(4, 2, 3); // d4 = d2 / d3
|
// Signal exception 5
|
||||||
VCVT64toI_sd(0, 4); // convert d4 to s0 (float to int)
|
MOV_ri(REG_WORK1, 5);
|
||||||
VMOV32_rs(REG_WORK1, 0); // move from s0
|
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
|
LSRS_rri(REG_WORK2, REG_WORK1, 16); // if result of this is not 0, DIVU overflows
|
||||||
BEQ_i(2);
|
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);
|
BIC_rri(REG_WORK2, REG_WORK2, ARM_C_FLAG | ARM_V_FLAG);
|
||||||
MSR_CPSRf_r(REG_WORK2);
|
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);
|
SUB_rrr(REG_WORK2, s1, REG_WORK2);
|
||||||
PKHBT_rrrLSLi(d, REG_WORK1, REG_WORK2, 16);
|
PKHBT_rrrLSLi(d, REG_WORK1, REG_WORK2, 16);
|
||||||
|
// end_of_op
|
||||||
|
|
||||||
unlock2(d);
|
unlock2(d);
|
||||||
unlock2(s1);
|
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))
|
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
|
* EOR
|
||||||
* Operand Syntax: Dn, <ea>
|
* Operand Syntax: Dn, <ea>
|
||||||
|
@ -5114,7 +5279,7 @@ MIDFUNC(2,jnf_MEM_WRITE_OFF_b,(RR4 adr, RR4 b))
|
||||||
LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
|
LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
|
||||||
|
|
||||||
adr = readreg(adr, 4);
|
adr = readreg(adr, 4);
|
||||||
b = readreg(b, 4);
|
b = readreg(b, 1);
|
||||||
|
|
||||||
STRB_rRR(b, adr, REG_WORK2);
|
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);
|
LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
|
||||||
|
|
||||||
adr = readreg(adr, 4);
|
adr = readreg(adr, 4);
|
||||||
w = readreg(w, 4);
|
w = readreg(w, 2);
|
||||||
|
|
||||||
REV16_rr(REG_WORK1, w);
|
REV16_rr(REG_WORK1, w);
|
||||||
STRH_rRR(REG_WORK1, adr, REG_WORK2);
|
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);
|
LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
|
||||||
|
|
||||||
adr = readreg(adr, 4);
|
adr = readreg(adr, 4);
|
||||||
d = writereg(d, 4);
|
d = writereg(d, 1);
|
||||||
|
|
||||||
LDRB_rRR(d, adr, REG_WORK2);
|
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);
|
LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
|
||||||
|
|
||||||
adr = readreg(adr, 4);
|
adr = readreg(adr, 4);
|
||||||
d = writereg(d, 4);
|
d = writereg(d, 2);
|
||||||
|
|
||||||
LDRH_rRR(REG_WORK1, adr, REG_WORK2);
|
LDRH_rRR(REG_WORK1, adr, REG_WORK2);
|
||||||
REV16_rr(d, REG_WORK1);
|
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);
|
LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
|
||||||
|
|
||||||
adr = readreg(adr, 4);
|
adr = readreg(adr, 4);
|
||||||
b = readreg(b, 4);
|
b = readreg(b, 1);
|
||||||
|
|
||||||
BIC_rri(REG_WORK1, adr, 0xff000000);
|
BIC_rri(REG_WORK1, adr, 0xff000000);
|
||||||
STRB_rRR(b, REG_WORK1, REG_WORK2);
|
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);
|
LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
|
||||||
|
|
||||||
adr = readreg(adr, 4);
|
adr = readreg(adr, 4);
|
||||||
w = readreg(w, 4);
|
w = readreg(w, 2);
|
||||||
|
|
||||||
BIC_rri(REG_WORK1, adr, 0xff000000);
|
BIC_rri(REG_WORK1, adr, 0xff000000);
|
||||||
REV16_rr(REG_WORK3, w);
|
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);
|
LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
|
||||||
|
|
||||||
adr = readreg(adr, 4);
|
adr = readreg(adr, 4);
|
||||||
d = writereg(d, 4);
|
d = writereg(d, 1);
|
||||||
|
|
||||||
BIC_rri(REG_WORK1, adr, 0xff000000);
|
BIC_rri(REG_WORK1, adr, 0xff000000);
|
||||||
LDRB_rRR(d, REG_WORK1, REG_WORK2);
|
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);
|
LDR_rRI(REG_WORK2, R_REGSTRUCT, offs);
|
||||||
|
|
||||||
adr = readreg(adr, 4);
|
adr = readreg(adr, 4);
|
||||||
d = writereg(d, 4);
|
d = writereg(d, 2);
|
||||||
|
|
||||||
BIC_rri(REG_WORK1, adr, 0xff000000);
|
BIC_rri(REG_WORK1, adr, 0xff000000);
|
||||||
LDRH_rRR(REG_WORK1, REG_WORK1, REG_WORK2);
|
LDRH_rRR(REG_WORK1, REG_WORK1, REG_WORK2);
|
||||||
|
|
|
@ -161,6 +161,10 @@ DECLARE_MIDFUNC(jff_DBCC(RR2 d, IMM cc));
|
||||||
DECLARE_MIDFUNC(jnf_DIVU(W4 d, RR4 s1, RR4 s2));
|
DECLARE_MIDFUNC(jnf_DIVU(W4 d, RR4 s1, RR4 s2));
|
||||||
DECLARE_MIDFUNC(jff_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
|
// EOR
|
||||||
DECLARE_MIDFUNC(jnf_EOR(W4 d, RR4 s, RR4 v));
|
DECLARE_MIDFUNC(jnf_EOR(W4 d, RR4 s, RR4 v));
|
||||||
DECLARE_MIDFUNC(jff_EOR_b(W4 d, RR1 s, RR1 v));
|
DECLARE_MIDFUNC(jff_EOR_b(W4 d, RR1 s, RR1 v));
|
||||||
|
|
|
@ -126,6 +126,10 @@ static int optcount[10] = {
|
||||||
|
|
||||||
op_properties prop[65536];
|
op_properties prop[65536];
|
||||||
|
|
||||||
|
uae_u32 jit_exception = 0;
|
||||||
|
bool may_raise_exception = false;
|
||||||
|
|
||||||
|
|
||||||
STATIC_INLINE bool is_const_jump(uae_u32 opcode)
|
STATIC_INLINE bool is_const_jump(uae_u32 opcode)
|
||||||
{
|
{
|
||||||
return (prop[opcode].cflow == fl_const_jump);
|
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_cache_miss = NULL;
|
||||||
static void* popall_recompile_block = NULL;
|
static void* popall_recompile_block = NULL;
|
||||||
static void* popall_check_checksum = 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
|
/* The 68k only ever executes from even addresses. So right now, we
|
||||||
* waste half the entries in this array
|
* waste half the entries in this array
|
||||||
|
@ -1393,7 +1398,6 @@ STATIC_INLINE void f_disassociate(int r)
|
||||||
f_evict(r);
|
f_evict(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int f_alloc_reg(int r, int willclobber)
|
static int f_alloc_reg(int r, int willclobber)
|
||||||
{
|
{
|
||||||
int bestreg;
|
int bestreg;
|
||||||
|
@ -1651,6 +1655,8 @@ void init_comp(void)
|
||||||
live.flags_in_flags = TRASH;
|
live.flags_in_flags = TRASH;
|
||||||
live.flags_on_stack = VALID;
|
live.flags_on_stack = VALID;
|
||||||
live.flags_are_important = 1;
|
live.flags_are_important = 1;
|
||||||
|
|
||||||
|
jit_exception = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only do this if you really mean it! The next call should be to init!*/
|
/* 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;
|
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
|
/* Note: get_handler may fail in 64 Bit environments, if direct_handler_to_use is
|
||||||
* outside 32 bit
|
* outside 32 bit
|
||||||
*/
|
*/
|
||||||
|
@ -2379,6 +2390,12 @@ STATIC_INLINE void create_popalls(void)
|
||||||
raw_pop_preserved_regs();
|
raw_pop_preserved_regs();
|
||||||
compemu_raw_jmp(uae_p32(check_checksum));
|
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)
|
#if defined(CPU_arm) && !defined(ARMV6T2)
|
||||||
reset_data_buffer();
|
reset_data_buffer();
|
||||||
#endif
|
#endif
|
||||||
|
@ -2776,6 +2793,7 @@ void compile_block(cpu_history* pc_hist, int blocklen, int totcycles)
|
||||||
was_comp = 1;
|
was_comp = 1;
|
||||||
|
|
||||||
for (i = 0; i < blocklen && get_target_noopt() < MAX_COMPILE_PTR; i++) {
|
for (i = 0; i < blocklen && get_target_noopt() < MAX_COMPILE_PTR; i++) {
|
||||||
|
may_raise_exception = false;
|
||||||
cpuop_func **cputbl;
|
cpuop_func **cputbl;
|
||||||
compop_func **comptbl;
|
compop_func **comptbl;
|
||||||
uae_u32 opcode = DO_GET_OPCODE(pc_hist[i].location);
|
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);
|
compemu_raw_jmp((uintptr)popall_do_nothing);
|
||||||
*(branchadd - 4) = (((uintptr)get_target() - (uintptr)branchadd) - 4) >> 2;
|
*(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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1246,17 +1246,17 @@ extern const struct comptbl op_smalltbl_0_comp_ff[] = {
|
||||||
{ op_80ba_0_comp_ff, 0x00000002, 32954 }, /* OR */
|
{ op_80ba_0_comp_ff, 0x00000002, 32954 }, /* OR */
|
||||||
{ op_80bb_0_comp_ff, 0x00000002, 32955 }, /* OR */
|
{ op_80bb_0_comp_ff, 0x00000002, 32955 }, /* OR */
|
||||||
{ op_80bc_0_comp_ff, 0x00000002, 32956 }, /* OR */
|
{ op_80bc_0_comp_ff, 0x00000002, 32956 }, /* OR */
|
||||||
{ NULL, 0x00000001, 32960 }, /* DIVU */
|
{ op_80c0_0_comp_ff, 0x00000000, 32960 }, /* DIVU */
|
||||||
{ NULL, 0x00000001, 32976 }, /* DIVU */
|
{ op_80d0_0_comp_ff, 0x00000000, 32976 }, /* DIVU */
|
||||||
{ NULL, 0x00000001, 32984 }, /* DIVU */
|
{ op_80d8_0_comp_ff, 0x00000000, 32984 }, /* DIVU */
|
||||||
{ NULL, 0x00000001, 32992 }, /* DIVU */
|
{ op_80e0_0_comp_ff, 0x00000000, 32992 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33000 }, /* DIVU */
|
{ op_80e8_0_comp_ff, 0x00000002, 33000 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33008 }, /* DIVU */
|
{ op_80f0_0_comp_ff, 0x00000002, 33008 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33016 }, /* DIVU */
|
{ op_80f8_0_comp_ff, 0x00000002, 33016 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33017 }, /* DIVU */
|
{ op_80f9_0_comp_ff, 0x00000002, 33017 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33018 }, /* DIVU */
|
{ op_80fa_0_comp_ff, 0x00000002, 33018 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33019 }, /* DIVU */
|
{ op_80fb_0_comp_ff, 0x00000002, 33019 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33020 }, /* DIVU */
|
{ op_80fc_0_comp_ff, 0x00000002, 33020 }, /* DIVU */
|
||||||
{ NULL, 0x00000000, 33024 }, /* SBCD */
|
{ NULL, 0x00000000, 33024 }, /* SBCD */
|
||||||
{ NULL, 0x00000000, 33032 }, /* SBCD */
|
{ NULL, 0x00000000, 33032 }, /* SBCD */
|
||||||
{ op_8110_0_comp_ff, 0x00000000, 33040 }, /* OR */
|
{ 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_81b0_0_comp_ff, 0x00000002, 33200 }, /* OR */
|
||||||
{ op_81b8_0_comp_ff, 0x00000002, 33208 }, /* OR */
|
{ op_81b8_0_comp_ff, 0x00000002, 33208 }, /* OR */
|
||||||
{ op_81b9_0_comp_ff, 0x00000002, 33209 }, /* OR */
|
{ op_81b9_0_comp_ff, 0x00000002, 33209 }, /* OR */
|
||||||
{ NULL, 0x00000001, 33216 }, /* DIVS */
|
{ op_81c0_0_comp_ff, 0x00000000, 33216 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33232 }, /* DIVS */
|
{ op_81d0_0_comp_ff, 0x00000000, 33232 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33240 }, /* DIVS */
|
{ op_81d8_0_comp_ff, 0x00000000, 33240 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33248 }, /* DIVS */
|
{ op_81e0_0_comp_ff, 0x00000000, 33248 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33256 }, /* DIVS */
|
{ op_81e8_0_comp_ff, 0x00000002, 33256 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33264 }, /* DIVS */
|
{ op_81f0_0_comp_ff, 0x00000002, 33264 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33272 }, /* DIVS */
|
{ op_81f8_0_comp_ff, 0x00000002, 33272 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33273 }, /* DIVS */
|
{ op_81f9_0_comp_ff, 0x00000002, 33273 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33274 }, /* DIVS */
|
{ op_81fa_0_comp_ff, 0x00000002, 33274 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33275 }, /* DIVS */
|
{ op_81fb_0_comp_ff, 0x00000002, 33275 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33276 }, /* DIVS */
|
{ op_81fc_0_comp_ff, 0x00000002, 33276 }, /* DIVS */
|
||||||
{ op_9000_0_comp_ff, 0x00000000, 36864 }, /* SUB */
|
{ op_9000_0_comp_ff, 0x00000000, 36864 }, /* SUB */
|
||||||
{ op_9010_0_comp_ff, 0x00000000, 36880 }, /* SUB */
|
{ op_9010_0_comp_ff, 0x00000000, 36880 }, /* SUB */
|
||||||
{ op_9018_0_comp_ff, 0x00000000, 36888 }, /* 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_80ba_0_comp_nf, 0x00000002, 32954 }, /* OR */
|
||||||
{ op_80bb_0_comp_nf, 0x00000002, 32955 }, /* OR */
|
{ op_80bb_0_comp_nf, 0x00000002, 32955 }, /* OR */
|
||||||
{ op_80bc_0_comp_nf, 0x00000002, 32956 }, /* OR */
|
{ op_80bc_0_comp_nf, 0x00000002, 32956 }, /* OR */
|
||||||
{ NULL, 0x00000001, 32960 }, /* DIVU */
|
{ op_80c0_0_comp_nf, 0x00000000, 32960 }, /* DIVU */
|
||||||
{ NULL, 0x00000001, 32976 }, /* DIVU */
|
{ op_80d0_0_comp_nf, 0x00000000, 32976 }, /* DIVU */
|
||||||
{ NULL, 0x00000001, 32984 }, /* DIVU */
|
{ op_80d8_0_comp_nf, 0x00000000, 32984 }, /* DIVU */
|
||||||
{ NULL, 0x00000001, 32992 }, /* DIVU */
|
{ op_80e0_0_comp_nf, 0x00000000, 32992 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33000 }, /* DIVU */
|
{ op_80e8_0_comp_nf, 0x00000002, 33000 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33008 }, /* DIVU */
|
{ op_80f0_0_comp_nf, 0x00000002, 33008 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33016 }, /* DIVU */
|
{ op_80f8_0_comp_nf, 0x00000002, 33016 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33017 }, /* DIVU */
|
{ op_80f9_0_comp_nf, 0x00000002, 33017 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33018 }, /* DIVU */
|
{ op_80fa_0_comp_nf, 0x00000002, 33018 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33019 }, /* DIVU */
|
{ op_80fb_0_comp_nf, 0x00000002, 33019 }, /* DIVU */
|
||||||
{ NULL, 0x00000003, 33020 }, /* DIVU */
|
{ op_80fc_0_comp_nf, 0x00000002, 33020 }, /* DIVU */
|
||||||
{ NULL, 0x00000000, 33024 }, /* SBCD */
|
{ NULL, 0x00000000, 33024 }, /* SBCD */
|
||||||
{ NULL, 0x00000000, 33032 }, /* SBCD */
|
{ NULL, 0x00000000, 33032 }, /* SBCD */
|
||||||
{ op_8110_0_comp_nf, 0x00000000, 33040 }, /* OR */
|
{ 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_81b0_0_comp_nf, 0x00000002, 33200 }, /* OR */
|
||||||
{ op_81b8_0_comp_nf, 0x00000002, 33208 }, /* OR */
|
{ op_81b8_0_comp_nf, 0x00000002, 33208 }, /* OR */
|
||||||
{ op_81b9_0_comp_nf, 0x00000002, 33209 }, /* OR */
|
{ op_81b9_0_comp_nf, 0x00000002, 33209 }, /* OR */
|
||||||
{ NULL, 0x00000001, 33216 }, /* DIVS */
|
{ op_81c0_0_comp_nf, 0x00000000, 33216 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33232 }, /* DIVS */
|
{ op_81d0_0_comp_nf, 0x00000000, 33232 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33240 }, /* DIVS */
|
{ op_81d8_0_comp_nf, 0x00000000, 33240 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33248 }, /* DIVS */
|
{ op_81e0_0_comp_nf, 0x00000000, 33248 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33256 }, /* DIVS */
|
{ op_81e8_0_comp_nf, 0x00000002, 33256 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33264 }, /* DIVS */
|
{ op_81f0_0_comp_nf, 0x00000002, 33264 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33272 }, /* DIVS */
|
{ op_81f8_0_comp_nf, 0x00000002, 33272 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33273 }, /* DIVS */
|
{ op_81f9_0_comp_nf, 0x00000002, 33273 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33274 }, /* DIVS */
|
{ op_81fa_0_comp_nf, 0x00000002, 33274 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33275 }, /* DIVS */
|
{ op_81fb_0_comp_nf, 0x00000002, 33275 }, /* DIVS */
|
||||||
{ NULL, 0x00000001, 33276 }, /* DIVS */
|
{ op_81fc_0_comp_nf, 0x00000002, 33276 }, /* DIVS */
|
||||||
{ op_9000_0_comp_nf, 0x00000000, 36864 }, /* SUB */
|
{ op_9000_0_comp_nf, 0x00000000, 36864 }, /* SUB */
|
||||||
{ op_9010_0_comp_nf, 0x00000000, 36880 }, /* SUB */
|
{ op_9010_0_comp_nf, 0x00000000, 36880 }, /* SUB */
|
||||||
{ op_9018_0_comp_nf, 0x00000000, 36888 }, /* SUB */
|
{ op_9018_0_comp_nf, 0x00000000, 36888 }, /* SUB */
|
||||||
|
|
|
@ -1010,6 +1010,17 @@ extern compop_func op_80b9_0_comp_ff;
|
||||||
extern compop_func op_80ba_0_comp_ff;
|
extern compop_func op_80ba_0_comp_ff;
|
||||||
extern compop_func op_80bb_0_comp_ff;
|
extern compop_func op_80bb_0_comp_ff;
|
||||||
extern compop_func op_80bc_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_8110_0_comp_ff;
|
||||||
extern compop_func op_8118_0_comp_ff;
|
extern compop_func op_8118_0_comp_ff;
|
||||||
extern compop_func op_8120_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_81b0_0_comp_ff;
|
||||||
extern compop_func op_81b8_0_comp_ff;
|
extern compop_func op_81b8_0_comp_ff;
|
||||||
extern compop_func op_81b9_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_9000_0_comp_ff;
|
||||||
extern compop_func op_9010_0_comp_ff;
|
extern compop_func op_9010_0_comp_ff;
|
||||||
extern compop_func op_9018_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_80ba_0_comp_nf;
|
||||||
extern compop_func op_80bb_0_comp_nf;
|
extern compop_func op_80bb_0_comp_nf;
|
||||||
extern compop_func op_80bc_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_8110_0_comp_nf;
|
||||||
extern compop_func op_8118_0_comp_nf;
|
extern compop_func op_8118_0_comp_nf;
|
||||||
extern compop_func op_8120_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_81b0_0_comp_nf;
|
||||||
extern compop_func op_81b8_0_comp_nf;
|
extern compop_func op_81b8_0_comp_nf;
|
||||||
extern compop_func op_81b9_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_9000_0_comp_nf;
|
||||||
extern compop_func op_9010_0_comp_nf;
|
extern compop_func op_9010_0_comp_nf;
|
||||||
extern compop_func op_9018_0_comp_nf;
|
extern compop_func op_9018_0_comp_nf;
|
||||||
|
|
|
@ -123,7 +123,8 @@
|
||||||
//#define DISABLE_I_FSCC
|
//#define DISABLE_I_FSCC
|
||||||
//#define DISABLE_I_MOVE16
|
//#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;"
|
#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);
|
genamode(curi->dmode, "dstreg", sz_word, "dst", 1, 0);
|
||||||
|
|
||||||
comprintf("\tint tmp=scratchie++;\n");
|
comprintf("\tint tmp=scratchie++;\n");
|
||||||
|
comprintf("\tregister_possible_exception();\n");
|
||||||
if (!noflags) {
|
if (!noflags) {
|
||||||
comprintf("\tjff_DIVU(tmp,dst,src);\n");
|
comprintf("\tjff_DIVU(tmp,dst,src);\n");
|
||||||
comprintf("\tlive_flags();\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");
|
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) {
|
static void gen_eor(uae_u32 opcode, struct instr *curi, char* ssize) {
|
||||||
|
@ -2507,8 +2529,11 @@ gen_opcode(unsigned long int opcode) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case i_DIVS:
|
case i_DIVS:
|
||||||
|
#ifdef DISABLE_I_DIVS
|
||||||
isjump;
|
isjump;
|
||||||
failure;
|
failure;
|
||||||
|
#endif
|
||||||
|
gen_divs(opcode, curi, ssize);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case i_MULU:
|
case i_MULU:
|
||||||
|
@ -3018,6 +3043,13 @@ generate_one_opcode(int rp, int noflags)
|
||||||
dmsk = 7;
|
dmsk = 7;
|
||||||
|
|
||||||
next_cpu_level = -1;
|
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
|
if (table68k[opcode].suse
|
||||||
&& table68k[opcode].smode != imm && table68k[opcode].smode != imm0
|
&& table68k[opcode].smode != imm && table68k[opcode].smode != imm0
|
||||||
&& table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
|
&& table68k[opcode].smode != imm1 && table68k[opcode].smode != imm2
|
||||||
|
@ -3109,6 +3141,10 @@ generate_one_opcode(int rp, int noflags)
|
||||||
if (global_fpu) flags |= 32;
|
if (global_fpu) flags |= 32;
|
||||||
|
|
||||||
comprintf ("return 0;\n");
|
comprintf ("return 0;\n");
|
||||||
|
if (table68k[opcode].mnemo == i_DIVU || table68k[opcode].mnemo == i_DIVS) {
|
||||||
|
comprintf("#endif\n");
|
||||||
|
}
|
||||||
|
|
||||||
comprintf("}\n");
|
comprintf("}\n");
|
||||||
|
|
||||||
char name[100] = { 0 };
|
char name[100] = { 0 };
|
||||||
|
@ -3132,6 +3168,7 @@ generate_one_opcode(int rp, int noflags)
|
||||||
com_flush();
|
com_flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
opcode_next_clev[rp] = next_cpu_level;
|
opcode_next_clev[rp] = next_cpu_level;
|
||||||
opcode_last_postfix[rp] = postfix;
|
opcode_last_postfix[rp] = postfix;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1597,6 +1597,18 @@ static void m68k_run_1 (void)
|
||||||
|
|
||||||
#ifdef JIT /* Completely different run_2 replacement */
|
#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)
|
void do_nothing(void)
|
||||||
{
|
{
|
||||||
/* What did you expect this to do? */
|
/* What did you expect this to do? */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue