mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-05-30 09:41:29 +00:00
Sync with latest ARAnyM changes
This commit is contained in:
parent
67dd2e6676
commit
9dc485c56a
|
@ -1961,9 +1961,9 @@ static inline void raw_pop_preserved_regs(void) {
|
|||
|
||||
// Verify!!!
|
||||
/* FLAGX is byte sized, and we *do* write it at that size */
|
||||
static inline void raw_load_flagx(uae_u32 t, uae_u32 r)
|
||||
static inline void raw_load_flagx(uae_u32 t)
|
||||
{
|
||||
raw_mov_l_rm(t,(uintptr)live.state[r].mem);
|
||||
raw_mov_l_rm(t,(uintptr)live.state[FLAGX].mem);
|
||||
}
|
||||
|
||||
static inline void raw_flags_evicted(int r)
|
||||
|
@ -2007,9 +2007,9 @@ static inline void raw_reg_to_flags(int r)
|
|||
|
||||
/* Apparently, there are enough instructions between flag store and
|
||||
flag reload to avoid the partial memory stall */
|
||||
static inline void raw_load_flagreg(uae_u32 t, uae_u32 r)
|
||||
static inline void raw_load_flagreg(uae_u32 t)
|
||||
{
|
||||
raw_mov_l_rm(t,(uintptr)live.state[r].mem);
|
||||
raw_mov_l_rm(t,(uintptr)live.state[FLAGTMP].mem);
|
||||
}
|
||||
|
||||
/* %eax register is clobbered if target processor doesn't support fucomi */
|
||||
|
@ -2606,12 +2606,14 @@ static inline void compemu_raw_call(uae_u32 t)
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(UAE)
|
||||
static inline void compemu_raw_call_r(RR4 r)
|
||||
{
|
||||
PUSH(RLR_INDEX); // push {lr}
|
||||
BLX_r(r); // blx r0
|
||||
POP(RLR_INDEX); // pop {lr}
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void compemu_raw_jcc_l_oponly(int cc)
|
||||
{
|
||||
|
@ -2706,7 +2708,18 @@ static inline void compemu_raw_jz_b_oponly(void)
|
|||
LDRSB_rRI(REG_WORK1, RPC_INDEX, 3); // ldrsb r2,[pc,#3]
|
||||
ADD_rrr(RPC_INDEX, RPC_INDEX, REG_WORK1); // add pc,pc,r2
|
||||
|
||||
skip_n_bytes(3);
|
||||
skip_n_bytes(3); /* additionally 1 byte skipped by generic code */
|
||||
|
||||
// <jp:>
|
||||
}
|
||||
|
||||
static inline void compemu_raw_jnz_b_oponly(void)
|
||||
{
|
||||
BEQ_i(2); // beq jp
|
||||
LDRSB_rRI(REG_WORK1, RPC_INDEX, 3); // ldrsb r2,[pc,#3]
|
||||
ADD_rrr(RPC_INDEX, RPC_INDEX, REG_WORK1); // add pc,pc,r2
|
||||
|
||||
skip_n_bytes(3); /* additionally 1 byte skipped by generic code */
|
||||
|
||||
// <jp:>
|
||||
}
|
||||
|
|
|
@ -267,6 +267,7 @@ static inline void x86_64_prefix(
|
|||
#define compemu_raw_jmp_r(a) raw_jmp_r(a)
|
||||
#define compemu_raw_jnz(a) raw_jnz(a)
|
||||
#define compemu_raw_jz_b_oponly() raw_jz_b_oponly()
|
||||
#define compemu_raw_jnz_b_oponly() raw_jnz_b_oponly()
|
||||
#define compemu_raw_lea_l_brr(a,b,c) raw_lea_l_brr(a,b,c)
|
||||
#define compemu_raw_lea_l_brr_indexed(a,b,c,d,e) raw_lea_l_brr_indexed(a,b,c,d,e)
|
||||
#define compemu_raw_mov_b_mr(a,b) raw_mov_b_mr(a,b)
|
||||
|
@ -921,6 +922,11 @@ LOWFUNC(WRITE,NONE,2,raw_test_b_rr,(R1 d, R1 s))
|
|||
TESTBrr(s, d);
|
||||
}
|
||||
|
||||
LOWFUNC(WRITE,READ,2,raw_test_b_mi,(IMM d, IMM s))
|
||||
{
|
||||
ADDR32 TESTBim(s, d, X86_NOREG, X86_NOREG, 1);
|
||||
}
|
||||
|
||||
LOWFUNC(WRITE,NONE,2,raw_xor_l_ri,(RW4 d, IMM i))
|
||||
{
|
||||
XORLir(i, d);
|
||||
|
@ -1185,47 +1191,38 @@ static inline void raw_jmp(uae_u32 t)
|
|||
ADDR32 JMPm(t);
|
||||
}
|
||||
|
||||
static inline void raw_jl(uae_u32 t)
|
||||
{
|
||||
emit_byte(0x0f);
|
||||
emit_byte(0x8c);
|
||||
emit_long(t-(uintptr)target-4);
|
||||
}
|
||||
|
||||
static inline void raw_jz(uae_u32 t)
|
||||
{
|
||||
emit_byte(0x0f);
|
||||
emit_byte(0x84);
|
||||
emit_long(t-(uintptr)target-4);
|
||||
}
|
||||
|
||||
static inline void raw_jnz(uae_u32 t)
|
||||
{
|
||||
emit_byte(0x0f);
|
||||
emit_byte(0x85);
|
||||
emit_long(t-(uintptr)target-4);
|
||||
}
|
||||
|
||||
static inline void raw_jnz_l_oponly(void)
|
||||
{
|
||||
emit_byte(0x0f);
|
||||
emit_byte(0x85);
|
||||
}
|
||||
|
||||
static inline void raw_jcc_l_oponly(int cc)
|
||||
{
|
||||
emit_byte(0x0f);
|
||||
emit_byte(0x80+cc);
|
||||
}
|
||||
|
||||
static inline void raw_jnz_b_oponly(void)
|
||||
static inline void raw_jz_l_oponly(void)
|
||||
{
|
||||
emit_byte(0x75);
|
||||
raw_jcc_l_oponly(NATIVE_CC_EQ);
|
||||
}
|
||||
|
||||
static inline void raw_jz_b_oponly(void)
|
||||
static inline void raw_jnz_l_oponly(void)
|
||||
{
|
||||
emit_byte(0x74);
|
||||
raw_jcc_l_oponly(NATIVE_CC_NE);
|
||||
}
|
||||
|
||||
static inline void raw_jl(uae_u32 t)
|
||||
{
|
||||
raw_jcc_l_oponly(NATIVE_CC_LT);
|
||||
emit_long(t-(uintptr)target-4);
|
||||
}
|
||||
|
||||
static inline void raw_jz(uae_u32 t)
|
||||
{
|
||||
raw_jz_l_oponly();
|
||||
emit_long(t-(uintptr)target-4);
|
||||
}
|
||||
|
||||
static inline void raw_jnz(uae_u32 t)
|
||||
{
|
||||
raw_jnz_l_oponly();
|
||||
emit_long(t-(uintptr)target-4);
|
||||
}
|
||||
|
||||
static inline void raw_jcc_b_oponly(int cc)
|
||||
|
@ -1233,6 +1230,16 @@ static inline void raw_jcc_b_oponly(int cc)
|
|||
emit_byte(0x70+cc);
|
||||
}
|
||||
|
||||
static inline void raw_jnz_b_oponly(void)
|
||||
{
|
||||
raw_jcc_b_oponly(NATIVE_CC_NE);
|
||||
}
|
||||
|
||||
static inline void raw_jz_b_oponly(void)
|
||||
{
|
||||
raw_jcc_b_oponly(NATIVE_CC_EQ);
|
||||
}
|
||||
|
||||
static inline void raw_jmp_l_oponly(void)
|
||||
{
|
||||
emit_byte(0xe9);
|
||||
|
@ -1356,7 +1363,7 @@ static inline void raw_flags_evicted(int r)
|
|||
live.nat[r].nholds=0;
|
||||
}
|
||||
|
||||
#define FLAG_NREG1_FLAGREG 0 /* Set to -1 if any register will do */
|
||||
#define FLAG_NREG1_FLAGREG EAX_INDEX /* Set to -1 if any register will do */
|
||||
static inline void raw_flags_to_reg_FLAGREG(int r)
|
||||
{
|
||||
raw_lahf(0); /* Most flags in AH */
|
||||
|
@ -1370,14 +1377,14 @@ static inline void raw_flags_to_reg_FLAGREG(int r)
|
|||
#endif
|
||||
}
|
||||
|
||||
#define FLAG_NREG2_FLAGREG 0 /* Set to -1 if any register will do */
|
||||
#define FLAG_NREG2_FLAGREG EAX_INDEX /* Set to -1 if any register will do */
|
||||
static inline void raw_reg_to_flags_FLAGREG(int r)
|
||||
{
|
||||
raw_cmp_b_ri(r,-127); /* set V */
|
||||
raw_sahf(0);
|
||||
}
|
||||
|
||||
#define FLAG_NREG3_FLAGREG 0 /* Set to -1 if any register will do */
|
||||
#define FLAG_NREG3_FLAGREG EAX_INDEX /* Set to -1 if any register will do */
|
||||
static __inline__ void raw_flags_set_zero_FLAGREG(int s, int tmp)
|
||||
{
|
||||
raw_mov_l_rr(tmp,s);
|
||||
|
@ -1429,7 +1436,7 @@ static inline void raw_flags_init_FLAGSTK(void) { }
|
|||
/* Try to use the LAHF/SETO method on x86_64 since it is faster.
|
||||
This can't be the default because some older CPUs don't support
|
||||
LAHF/SAHF in long mode. */
|
||||
static int FLAG_NREG1_FLAGGEN = 0;
|
||||
static int FLAG_NREG1_FLAGGEN = EAX_INDEX;
|
||||
static inline void raw_flags_to_reg_FLAGGEN(int r)
|
||||
{
|
||||
if (have_lahf_lm) {
|
||||
|
@ -1448,7 +1455,7 @@ static inline void raw_flags_to_reg_FLAGGEN(int r)
|
|||
raw_flags_to_reg_FLAGSTK(r);
|
||||
}
|
||||
|
||||
static int FLAG_NREG2_FLAGGEN = 0;
|
||||
static int FLAG_NREG2_FLAGGEN = EAX_INDEX;
|
||||
static inline void raw_reg_to_flags_FLAGGEN(int r)
|
||||
{
|
||||
if (have_lahf_lm) {
|
||||
|
@ -1460,7 +1467,7 @@ static inline void raw_reg_to_flags_FLAGGEN(int r)
|
|||
raw_reg_to_flags_FLAGSTK(r);
|
||||
}
|
||||
|
||||
static int FLAG_NREG3_FLAGGEN = 0;
|
||||
static int FLAG_NREG3_FLAGGEN = EAX_INDEX;
|
||||
static inline void raw_flags_set_zero_FLAGGEN(int s, int tmp)
|
||||
{
|
||||
if (have_lahf_lm)
|
||||
|
@ -1474,12 +1481,12 @@ static inline void raw_flags_init_FLAGGEN(void)
|
|||
if (have_lahf_lm) {
|
||||
FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGREG;
|
||||
FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGREG;
|
||||
FLAG_NREG1_FLAGGEN = FLAG_NREG3_FLAGREG;
|
||||
FLAG_NREG3_FLAGGEN = FLAG_NREG3_FLAGREG;
|
||||
}
|
||||
else {
|
||||
FLAG_NREG1_FLAGGEN = FLAG_NREG1_FLAGSTK;
|
||||
FLAG_NREG2_FLAGGEN = FLAG_NREG2_FLAGSTK;
|
||||
FLAG_NREG1_FLAGGEN = FLAG_NREG3_FLAGSTK;
|
||||
FLAG_NREG3_FLAGGEN = FLAG_NREG3_FLAGSTK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1506,23 +1513,23 @@ static inline void raw_flags_init_FLAGGEN(void)
|
|||
|
||||
/* Apparently, there are enough instructions between flag store and
|
||||
flag reload to avoid the partial memory stall */
|
||||
static inline void raw_load_flagreg(uae_u32 target, uae_u32 r)
|
||||
static inline void raw_load_flagreg(uae_u32 target)
|
||||
{
|
||||
/* attention: in 64bit mode, relies on LITTE_ENDIANESS of regflags.cznv */
|
||||
raw_mov_l_rm(target,(uintptr)live.state[r].mem);
|
||||
raw_mov_l_rm(target,(uintptr)live.state[FLAGTMP].mem);
|
||||
}
|
||||
|
||||
static inline void raw_load_flagx(uae_u32 target, uae_u32 r)
|
||||
static inline void raw_load_flagx(uae_u32 target)
|
||||
{
|
||||
#if FLAGBIT_X < 8
|
||||
if (live.nat[target].canbyte)
|
||||
raw_mov_b_rm(target,(uintptr)live.state[r].mem);
|
||||
raw_mov_b_rm(target,(uintptr)live.state[FLAGX].mem);
|
||||
else
|
||||
#endif
|
||||
if (live.nat[target].canword)
|
||||
raw_mov_w_rm(target,(uintptr)live.state[r].mem);
|
||||
raw_mov_w_rm(target,(uintptr)live.state[FLAGX].mem);
|
||||
else
|
||||
raw_mov_l_rm(target,(uintptr)live.state[r].mem);
|
||||
raw_mov_l_rm(target,(uintptr)live.state[FLAGX].mem);
|
||||
}
|
||||
|
||||
static inline void raw_dec_sp(int off)
|
||||
|
|
|
@ -169,6 +169,7 @@ extern void compiler_exit(void);
|
|||
extern bool compiler_use_jit(void);
|
||||
#endif
|
||||
extern void flush(int save_regs);
|
||||
void flush_reg(int reg);
|
||||
extern void set_target(uae_u8* t);
|
||||
extern uae_u8* get_target(void);
|
||||
#ifdef UAE
|
||||
|
@ -279,6 +280,7 @@ typedef struct {
|
|||
uae_u8 needflush;
|
||||
} freg_status;
|
||||
|
||||
#define SP_REG 15
|
||||
#define PC_P 16
|
||||
#define FLAGX 17
|
||||
#define FLAGTMP 18
|
||||
|
@ -427,6 +429,11 @@ 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);
|
||||
void compemu_make_sr(int sr, int tmp);
|
||||
void compemu_enter_super(int sr);
|
||||
void compemu_exc_make_frame(int format, int sr, int currpc, int nr, int tmp);
|
||||
void compemu_bkpt(void);
|
||||
extern bool disasm_this_inst;
|
||||
|
||||
#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)))
|
||||
|
|
|
@ -1676,6 +1676,7 @@ MIDFUNC(2,xor_b,(RW1 d, RR1 s))
|
|||
unlock2(s);
|
||||
}
|
||||
|
||||
#if defined(UAE)
|
||||
MIDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2))
|
||||
{
|
||||
clobber_flags();
|
||||
|
@ -1689,7 +1690,9 @@ MIDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2))
|
|||
prepare_for_call_2();
|
||||
compemu_raw_call_r(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(UAE)
|
||||
MIDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize))
|
||||
{
|
||||
clobber_flags();
|
||||
|
@ -1725,6 +1728,7 @@ MIDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize))
|
|||
live.state[out1].dirtysize=osize;
|
||||
set_status(out1,DIRTY);
|
||||
}
|
||||
#endif
|
||||
|
||||
MIDFUNC(0,nop,(void))
|
||||
{
|
||||
|
|
|
@ -1718,19 +1718,19 @@ MIDFUNC(2,mov_b_ri,(W1 d, IMM s))
|
|||
MIDFUNC(2,add_l_mi,(IMM d, IMM s))
|
||||
{
|
||||
CLOBBER_ADD;
|
||||
raw_add_l_mi(d,s) ;
|
||||
raw_add_l_mi(d,s);
|
||||
}
|
||||
|
||||
MIDFUNC(2,add_w_mi,(IMM d, IMM s))
|
||||
{
|
||||
CLOBBER_ADD;
|
||||
raw_add_w_mi(d,s) ;
|
||||
raw_add_w_mi(d,s);
|
||||
}
|
||||
|
||||
MIDFUNC(2,add_b_mi,(IMM d, IMM s))
|
||||
{
|
||||
CLOBBER_ADD;
|
||||
raw_add_b_mi(d,s) ;
|
||||
raw_add_b_mi(d,s);
|
||||
}
|
||||
|
||||
MIDFUNC(2,test_l_ri,(RR4 d, IMM i))
|
||||
|
@ -1775,6 +1775,11 @@ MIDFUNC(2,test_b_rr,(RR1 d, RR1 s))
|
|||
unlock2(s);
|
||||
}
|
||||
|
||||
MIDFUNC(2,test_b_mi,(IMM d, IMM s))
|
||||
{
|
||||
CLOBBER_TEST;
|
||||
raw_test_b_mi(d,s);
|
||||
}
|
||||
|
||||
MIDFUNC(2,and_l_ri,(RW4 d, IMM i))
|
||||
{
|
||||
|
@ -2215,6 +2220,7 @@ MIDFUNC(2,xor_b,(RW1 d, RR1 s))
|
|||
unlock2(s);
|
||||
}
|
||||
|
||||
#ifdef UAE
|
||||
MIDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize))
|
||||
{
|
||||
clobber_flags();
|
||||
|
@ -2260,7 +2266,9 @@ MIDFUNC(5,call_r_11,(W4 out1, RR4 r, RR4 in1, IMM osize, IMM isize))
|
|||
live.state[out1].dirtysize=osize;
|
||||
set_status(out1,DIRTY);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(UAE)
|
||||
MIDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2))
|
||||
{
|
||||
clobber_flags();
|
||||
|
@ -2286,6 +2294,7 @@ MIDFUNC(5,call_r_02,(RR4 r, RR4 in1, RR4 in2, IMM isize1, IMM isize2))
|
|||
raw_inc_sp(8);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* forget_about() takes a mid-layer register */
|
||||
MIDFUNC(1,forget_about,(W4 r))
|
||||
|
@ -2821,3 +2830,9 @@ static inline void write_jmp_target(uae_u32 *jmpaddr, cpuop_func* a) {
|
|||
static inline void emit_jmp_target(uae_u32 a) {
|
||||
emit_long(a-((uintptr)target+4));
|
||||
}
|
||||
|
||||
|
||||
void compemu_bkpt(void)
|
||||
{
|
||||
emit_byte(0xcc);
|
||||
}
|
||||
|
|
|
@ -141,13 +141,14 @@ DECLARE_MIDFUNC(mov_b_rm(W1 d, IMM s));
|
|||
DECLARE_MIDFUNC(mov_l_ri(W4 d, IMM s));
|
||||
DECLARE_MIDFUNC(mov_w_ri(W2 d, IMM s));
|
||||
DECLARE_MIDFUNC(mov_b_ri(W1 d, IMM s));
|
||||
DECLARE_MIDFUNC(add_l_mi(IMM d, IMM s) );
|
||||
DECLARE_MIDFUNC(add_w_mi(IMM d, IMM s) );
|
||||
DECLARE_MIDFUNC(add_b_mi(IMM d, IMM s) );
|
||||
DECLARE_MIDFUNC(add_l_mi(IMM d, IMM s));
|
||||
DECLARE_MIDFUNC(add_w_mi(IMM d, IMM s));
|
||||
DECLARE_MIDFUNC(add_b_mi(IMM d, IMM s));
|
||||
DECLARE_MIDFUNC(test_l_ri(RR4 d, IMM i));
|
||||
DECLARE_MIDFUNC(test_l_rr(RR4 d, RR4 s));
|
||||
DECLARE_MIDFUNC(test_w_rr(RR2 d, RR2 s));
|
||||
DECLARE_MIDFUNC(test_b_rr(RR1 d, RR1 s));
|
||||
DECLARE_MIDFUNC(test_b_mi(IMM d, IMM s));
|
||||
DECLARE_MIDFUNC(and_l_ri(RW4 d, IMM i));
|
||||
DECLARE_MIDFUNC(and_l(RW4 d, RR4 s));
|
||||
DECLARE_MIDFUNC(and_w(RW2 d, RR2 s));
|
||||
|
|
|
@ -231,7 +231,7 @@ void jit_abort(const char *format, ...)
|
|||
|
||||
#ifdef RECORD_REGISTER_USAGE
|
||||
static uint64 reg_count[16];
|
||||
static int reg_count_local[16];
|
||||
static uint64 reg_count_local[16];
|
||||
|
||||
static int reg_count_compare(const void *ap, const void *bp)
|
||||
{
|
||||
|
@ -455,13 +455,8 @@ static void unlock2(int r);
|
|||
static void setlock(int r);
|
||||
static int readreg_specific(int r, int size, int spec);
|
||||
static int writereg_specific(int r, int size, int spec);
|
||||
static void prepare_for_call_1(void);
|
||||
static void prepare_for_call_2(void);
|
||||
static void align_target(uae_u32 a);
|
||||
|
||||
static void inline flush_cpu_icache(void *from, void *to);
|
||||
static void inline write_jmp_target(uae_u32 *jmpaddr, cpuop_func* a);
|
||||
static void inline emit_jmp_target(uae_u32 a);
|
||||
|
||||
uae_u32 m68k_pc_offset;
|
||||
|
||||
|
@ -538,7 +533,9 @@ static inline blockinfo* get_blockinfo_addr(void* addr)
|
|||
#endif
|
||||
// #include "disasm-glue.h"
|
||||
|
||||
#ifdef JIT_DEBUG
|
||||
bool disasm_this_inst;
|
||||
|
||||
#if defined(JIT_DEBUG) || (defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K))
|
||||
static void disasm_block(int disasm_target, const uint8 *start, size_t length)
|
||||
{
|
||||
UNUSED(start);
|
||||
|
@ -606,7 +603,7 @@ static inline void disasm_m68k_block(const uint8 *start, size_t length)
|
|||
disasm_block(TARGET_M68K, start, length);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif /* WINUAE_ARANYM */
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -1552,9 +1549,9 @@ static inline void log_visused(int r)
|
|||
static inline void do_load_reg(int n, int r)
|
||||
{
|
||||
if (r == FLAGTMP)
|
||||
raw_load_flagreg(n, r);
|
||||
raw_load_flagreg(n);
|
||||
else if (r == FLAGX)
|
||||
raw_load_flagx(n, r);
|
||||
raw_load_flagx(n);
|
||||
else
|
||||
compemu_raw_mov_l_rm(n, (uintptr) live.state[r].mem);
|
||||
}
|
||||
|
@ -1775,6 +1772,7 @@ static inline void disassociate(int r)
|
|||
evict(r);
|
||||
}
|
||||
|
||||
/* XXFIXME: val may be 64bit address for PC_P */
|
||||
static inline void set_const(int r, uae_u32 val)
|
||||
{
|
||||
disassociate(r);
|
||||
|
@ -2591,6 +2589,80 @@ static inline int f_writereg(int r)
|
|||
return answer;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Support functions, internal *
|
||||
********************************************************************/
|
||||
|
||||
|
||||
static void align_target(uae_u32 a)
|
||||
{
|
||||
if (!a)
|
||||
return;
|
||||
|
||||
if (tune_nop_fillers)
|
||||
raw_emit_nop_filler(a - (((uintptr)target) & (a - 1)));
|
||||
else {
|
||||
/* Fill with NOPs --- makes debugging with gdb easier */
|
||||
while ((uintptr)target&(a-1))
|
||||
emit_byte(0x90); // Attention x86 specific code
|
||||
}
|
||||
}
|
||||
|
||||
static inline int isinrom(uintptr addr)
|
||||
{
|
||||
#ifdef UAE
|
||||
return (addr >= uae_p32(kickmem_bank.baseaddr) &&
|
||||
addr < uae_p32(kickmem_bank.baseaddr + 8 * 65536));
|
||||
#else
|
||||
return ((addr >= (uintptr)ROMBaseHost) && (addr < (uintptr)ROMBaseHost + ROMSize));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(UAE) || defined(FLIGHT_RECORDER)
|
||||
static void flush_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
log_flush();
|
||||
for (i=0;i<VREGS;i++)
|
||||
if (live.state[i].status==DIRTY) {
|
||||
if (!call_saved[live.state[i].realreg]) {
|
||||
tomem(i);
|
||||
}
|
||||
}
|
||||
for (i=0;i<VFREGS;i++)
|
||||
if (f_isinreg(i))
|
||||
f_evict(i);
|
||||
raw_fp_cleanup_drop();
|
||||
}
|
||||
|
||||
/* Make sure all registers that will get clobbered by a call are
|
||||
save and sound in memory */
|
||||
static void prepare_for_call_1(void)
|
||||
{
|
||||
flush_all(); /* If there are registers that don't get clobbered,
|
||||
* we should be a bit more selective here */
|
||||
}
|
||||
|
||||
/* We will call a C routine in a moment. That will clobber all registers,
|
||||
so we need to disassociate everything */
|
||||
static void prepare_for_call_2(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<N_REGS;i++)
|
||||
if (!call_saved[i] && live.nat[i].nholds>0)
|
||||
free_nreg(i);
|
||||
|
||||
for (i=0;i<N_FREGS;i++)
|
||||
if (live.fat[i].nholds>0)
|
||||
f_free_nreg(i);
|
||||
|
||||
live.flags_in_flags=TRASH; /* Note: We assume we already rescued the
|
||||
flags at the very start of the call_r
|
||||
functions! */
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CPU_arm)
|
||||
#include "compemu_midfunc_arm.cpp"
|
||||
|
||||
|
@ -2643,6 +2715,165 @@ void sync_m68k_pc(void)
|
|||
}
|
||||
}
|
||||
|
||||
/* for building exception frames */
|
||||
void compemu_exc_make_frame(int format, int sr, int ret, int nr, int tmp)
|
||||
{
|
||||
lea_l_brr(SP_REG, SP_REG, -2);
|
||||
mov_l_ri(tmp, (format << 12) + (nr * 4)); /* format | vector */
|
||||
writeword(SP_REG, tmp, tmp);
|
||||
|
||||
lea_l_brr(SP_REG, SP_REG, -4);
|
||||
writelong(SP_REG, ret, tmp);
|
||||
|
||||
lea_l_brr(SP_REG, SP_REG, -2);
|
||||
writeword_clobber(SP_REG, sr, tmp);
|
||||
remove_offset(SP_REG, -1);
|
||||
if (isinreg(SP_REG))
|
||||
evict(SP_REG);
|
||||
else
|
||||
flush_reg(SP_REG);
|
||||
}
|
||||
|
||||
void compemu_make_sr(int sr, int tmp)
|
||||
{
|
||||
flush_flags(); /* low level */
|
||||
flush_reg(FLAGX);
|
||||
|
||||
#ifdef OPTIMIZED_FLAGS
|
||||
|
||||
/*
|
||||
* x86 EFLAGS: (!SAHF_SETO_PROFITABLE)
|
||||
* FEDCBA98 76543210
|
||||
* ----V--- NZ-----C
|
||||
*
|
||||
* <--AH--> <--AL--> (SAHF_SETO_PROFITABLE)
|
||||
* FEDCBA98 76543210
|
||||
* NZxxxxxC xxxxxxxV
|
||||
*
|
||||
* arm RFLAGS:
|
||||
* FEDCBA98 76543210 FEDCBA98 76543210
|
||||
* NZCV---- -------- -------- --------
|
||||
*
|
||||
* -> m68k SR:
|
||||
* --S--III ---XNZVC
|
||||
*
|
||||
* Master-Bit and traceflags are ignored here,
|
||||
* since they are not emulated in JIT code
|
||||
*/
|
||||
mov_l_rm(sr, uae_p32(live.state[FLAGTMP].mem));
|
||||
mov_l_ri(tmp, FLAGVAL_N|FLAGVAL_Z|FLAGVAL_V|FLAGVAL_C);
|
||||
and_l(sr, tmp);
|
||||
mov_l_rr(tmp, sr);
|
||||
|
||||
#if (defined(CPU_i386) && defined(X86_ASSEMBLY)) || (defined(CPU_x86_64) && defined(X86_64_ASSEMBLY))
|
||||
#ifndef SAHF_SETO_PROFITABLE
|
||||
ror_b_ri(sr, FLAGBIT_N - 3); /* move NZ into position; C->4 */
|
||||
shrl_w_ri(tmp, FLAGBIT_V - 1); /* move V into position in tmp */
|
||||
or_l(sr, tmp); /* or V flag to SR */
|
||||
mov_l_rr(tmp, sr);
|
||||
shrl_b_ri(tmp, (8 - (FLAGBIT_N - 3)) - FLAGBIT_C); /* move C into position in tmp */
|
||||
or_l(sr, tmp); /* or C flag to SR */
|
||||
#else
|
||||
ror_w_ri(sr, FLAGBIT_N - 3); /* move NZ in position; V->4, C->12 */
|
||||
shrl_w_ri(tmp, (16 - (FLAGBIT_N - 3)) - FLAGBIT_V - 1); /* move V into position in tmp; C->9 */
|
||||
or_l(sr, tmp); /* or V flag to SR */
|
||||
shrl_w_ri(tmp, FLAGBIT_C + FLAGBIT_V - 1); /* move C into position in tmp */
|
||||
or_l(sr, tmp); /* or C flag to SR */
|
||||
#endif
|
||||
mov_l_ri(tmp, 0x0f);
|
||||
and_l(sr, tmp);
|
||||
|
||||
mov_b_rm(tmp, uae_p32(®flags.x));
|
||||
and_l_ri(tmp, FLAGVAL_X);
|
||||
shll_l_ri(tmp, 4);
|
||||
or_l(sr, tmp);
|
||||
|
||||
#elif defined(CPU_arm) && defined(ARM_ASSEMBLY)
|
||||
shrl_l_ri(sr, FLAGBIT_N - 3); /* move NZ into position */
|
||||
ror_l_ri(tmp, FLAGBIT_C - 1); /* move C into position in tmp; V->31 */
|
||||
and_l_ri(sr, 0xc);
|
||||
or_l(sr, tmp); /* or C flag to SR */
|
||||
shrl_l_ri(tmp, 31); /* move V into position in tmp */
|
||||
or_l(sr, tmp); /* or V flag to SR */
|
||||
|
||||
mov_b_rm(tmp, uae_p32(®flags.x));
|
||||
and_l_ri(tmp, FLAGVAL_X);
|
||||
shrl_l_ri(tmp, FLAGBIT_X - 4);
|
||||
or_l(sr, tmp);
|
||||
|
||||
#else
|
||||
#error "unknown CPU"
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
xor_l(sr, sr);
|
||||
xor_l(tmp, tmp);
|
||||
mov_b_rm(tmp, uae_p32(®s.c));
|
||||
shll_l_ri(tmp, 0);
|
||||
or_l(sr, tmp);
|
||||
mov_b_rm(tmp, uae_p32(®s.v));
|
||||
shll_l_ri(tmp, 1);
|
||||
or_l(sr, tmp);
|
||||
mov_b_rm(tmp, uae_p32(®s.z));
|
||||
shll_l_ri(tmp, 2);
|
||||
or_l(sr, tmp);
|
||||
mov_b_rm(tmp, uae_p32(®s.n));
|
||||
shll_l_ri(tmp, 3);
|
||||
or_l(sr, tmp);
|
||||
|
||||
#endif /* OPTIMIZED_FLAGS */
|
||||
|
||||
mov_b_rm(tmp, uae_p32(®s.s));
|
||||
shll_l_ri(tmp, 13);
|
||||
or_l(sr, tmp);
|
||||
mov_l_rm(tmp, uae_p32(®s.intmask));
|
||||
shll_l_ri(tmp, 8);
|
||||
or_l(sr, tmp);
|
||||
and_l_ri(sr, 0x271f);
|
||||
mov_w_mr(uae_p32(®s.sr), sr);
|
||||
}
|
||||
|
||||
void compemu_enter_super(int sr)
|
||||
{
|
||||
#if 0
|
||||
fprintf(stderr, "enter_super: isinreg=%d rr=%d nholds=%d\n", isinreg(SP_REG), live.state[SP_REG].realreg, isinreg(SP_REG) ? live.nat[live.state[SP_REG].realreg].nholds : -1);
|
||||
#endif
|
||||
remove_offset(SP_REG, -1);
|
||||
if (isinreg(SP_REG))
|
||||
evict(SP_REG);
|
||||
else
|
||||
flush_reg(SP_REG);
|
||||
/*
|
||||
* equivalent to:
|
||||
* if (!regs.s)
|
||||
* {
|
||||
* regs.usp = m68k_areg(regs, 7);
|
||||
* m68k_areg(regs, 7) = regs.isp;
|
||||
* regs.s = 1;
|
||||
* mmu_set_super(1);
|
||||
* }
|
||||
*/
|
||||
test_l_ri(sr, 0x2000);
|
||||
#if defined(CPU_i386) || defined(CPU_x86_64)
|
||||
compemu_raw_jnz_b_oponly();
|
||||
uae_u8 *branchadd = get_target();
|
||||
skip_byte();
|
||||
#elif defined(CPU_arm)
|
||||
compemu_raw_jnz_b_oponly();
|
||||
uae_u8 *branchadd = get_target();
|
||||
skip_byte();
|
||||
#endif
|
||||
mov_l_mr((uintptr)®s.usp, SP_REG);
|
||||
mov_l_rm(SP_REG, uae_p32(®s.isp));
|
||||
mov_b_mi(uae_p32(®s.s), 1);
|
||||
#if defined(CPU_i386) || defined(CPU_x86_64)
|
||||
*branchadd = get_target() - (branchadd + 1);
|
||||
#elif defined(CPU_arm)
|
||||
*((uae_u32 *)branchadd - 3) = get_target() - (branchadd + 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Scratch registers management *
|
||||
********************************************************************/
|
||||
|
@ -2941,6 +3172,39 @@ static void init_comp(void)
|
|||
raw_fp_init();
|
||||
}
|
||||
|
||||
void flush_reg(int reg)
|
||||
{
|
||||
if (live.state[reg].needflush==NF_TOMEM)
|
||||
{
|
||||
switch (live.state[reg].status)
|
||||
{
|
||||
case INMEM:
|
||||
if (live.state[reg].val)
|
||||
{
|
||||
compemu_raw_add_l_mi((uintptr)live.state[reg].mem, live.state[reg].val);
|
||||
log_vwrite(reg);
|
||||
live.state[reg].val = 0;
|
||||
}
|
||||
break;
|
||||
case CLEAN:
|
||||
case DIRTY:
|
||||
remove_offset(reg, -1);
|
||||
tomem(reg);
|
||||
break;
|
||||
case ISCONST:
|
||||
if (reg != PC_P)
|
||||
writeback_const(reg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Dif (live.state[reg].val && reg!=PC_P)
|
||||
{
|
||||
jit_log("Register %d still has val %x", reg, live.state[reg].val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Only do this if you really mean it! The next call should be to init!*/
|
||||
void flush(int save_regs)
|
||||
{
|
||||
|
@ -2958,30 +3222,7 @@ void flush(int save_regs)
|
|||
}
|
||||
}
|
||||
for (i=0;i<VREGS;i++) {
|
||||
if (live.state[i].needflush==NF_TOMEM) {
|
||||
switch(live.state[i].status) {
|
||||
case INMEM:
|
||||
if (live.state[i].val) {
|
||||
compemu_raw_add_l_mi((uintptr)live.state[i].mem,live.state[i].val);
|
||||
log_vwrite(i);
|
||||
live.state[i].val=0;
|
||||
}
|
||||
break;
|
||||
case CLEAN:
|
||||
case DIRTY:
|
||||
remove_offset(i,-1);
|
||||
tomem(i);
|
||||
break;
|
||||
case ISCONST:
|
||||
if (i!=PC_P)
|
||||
writeback_const(i);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
Dif (live.state[i].val && i!=PC_P) {
|
||||
jit_log("Register %d still has val %x", i,live.state[i].val);
|
||||
}
|
||||
}
|
||||
flush_reg(i);
|
||||
}
|
||||
for (i=0;i<VFREGS;i++) {
|
||||
if (live.fate[i].needflush==NF_TOMEM &&
|
||||
|
@ -3064,78 +3305,6 @@ static void freescratch(void)
|
|||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Support functions, internal *
|
||||
********************************************************************/
|
||||
|
||||
|
||||
static void align_target(uae_u32 a)
|
||||
{
|
||||
if (!a)
|
||||
return;
|
||||
|
||||
if (tune_nop_fillers)
|
||||
raw_emit_nop_filler(a - (((uintptr)target) & (a - 1)));
|
||||
else {
|
||||
/* Fill with NOPs --- makes debugging with gdb easier */
|
||||
while ((uintptr)target&(a-1))
|
||||
emit_byte(0x90); // Attention x86 specific code
|
||||
}
|
||||
}
|
||||
|
||||
static inline int isinrom(uintptr addr)
|
||||
{
|
||||
#ifdef UAE
|
||||
return (addr >= uae_p32(kickmem_bank.baseaddr) &&
|
||||
addr < uae_p32(kickmem_bank.baseaddr + 8 * 65536));
|
||||
#else
|
||||
return ((addr >= (uintptr)ROMBaseHost) && (addr < (uintptr)ROMBaseHost + ROMSize));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void flush_all(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
log_flush();
|
||||
for (i=0;i<VREGS;i++)
|
||||
if (live.state[i].status==DIRTY) {
|
||||
if (!call_saved[live.state[i].realreg]) {
|
||||
tomem(i);
|
||||
}
|
||||
}
|
||||
for (i=0;i<VFREGS;i++)
|
||||
if (f_isinreg(i))
|
||||
f_evict(i);
|
||||
raw_fp_cleanup_drop();
|
||||
}
|
||||
|
||||
/* Make sure all registers that will get clobbered by a call are
|
||||
save and sound in memory */
|
||||
static void prepare_for_call_1(void)
|
||||
{
|
||||
flush_all(); /* If there are registers that don't get clobbered,
|
||||
* we should be a bit more selective here */
|
||||
}
|
||||
|
||||
/* We will call a C routine in a moment. That will clobber all registers,
|
||||
so we need to disassociate everything */
|
||||
static void prepare_for_call_2(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<N_REGS;i++)
|
||||
if (!call_saved[i] && live.nat[i].nholds>0)
|
||||
free_nreg(i);
|
||||
|
||||
for (i=0;i<N_FREGS;i++)
|
||||
if (live.fat[i].nholds>0)
|
||||
f_free_nreg(i);
|
||||
|
||||
live.flags_in_flags=TRASH; /* Note: We assume we already rescued the
|
||||
flags at the very start of the call_r
|
||||
functions! */
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* Memory access and related functions, CREATE time *
|
||||
********************************************************************/
|
||||
|
@ -4522,6 +4691,75 @@ void compiler_dumpstate(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if 0 /* debugging helpers; activate as needed */
|
||||
static void print_exc_frame(uae_u32 opcode)
|
||||
{
|
||||
int nr = (opcode & 0x0f) + 32;
|
||||
if (nr != 0x45 && /* Timer-C */
|
||||
nr != 0x1c && /* VBL */
|
||||
nr != 0x46) /* ACIA */
|
||||
{
|
||||
memptr sp = m68k_areg(regs, 7);
|
||||
uae_u16 sr = get_word(sp);
|
||||
fprintf(stderr, "Exc:%02x SP: %08x USP: %08x SR: %04x PC: %08x Format: %04x", nr, sp, regs.usp, sr, get_long(sp + 2), get_word(sp + 6));
|
||||
if (nr >= 32 && nr < 48)
|
||||
{
|
||||
fprintf(stderr, " Opcode: $%04x", sr & 0x2000 ? get_word(sp + 8) : get_word(regs.usp));
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void push_all_nat(void)
|
||||
{
|
||||
raw_pushfl();
|
||||
raw_push_l_r(EAX_INDEX);
|
||||
raw_push_l_r(ECX_INDEX);
|
||||
raw_push_l_r(EDX_INDEX);
|
||||
raw_push_l_r(EBX_INDEX);
|
||||
raw_push_l_r(EBP_INDEX);
|
||||
raw_push_l_r(EDI_INDEX);
|
||||
raw_push_l_r(ESI_INDEX);
|
||||
raw_push_l_r(R8_INDEX);
|
||||
raw_push_l_r(R9_INDEX);
|
||||
raw_push_l_r(R10_INDEX);
|
||||
raw_push_l_r(R11_INDEX);
|
||||
raw_push_l_r(R12_INDEX);
|
||||
raw_push_l_r(R13_INDEX);
|
||||
raw_push_l_r(R14_INDEX);
|
||||
raw_push_l_r(R15_INDEX);
|
||||
}
|
||||
|
||||
static void pop_all_nat(void)
|
||||
{
|
||||
raw_pop_l_r(R15_INDEX);
|
||||
raw_pop_l_r(R14_INDEX);
|
||||
raw_pop_l_r(R13_INDEX);
|
||||
raw_pop_l_r(R12_INDEX);
|
||||
raw_pop_l_r(R11_INDEX);
|
||||
raw_pop_l_r(R10_INDEX);
|
||||
raw_pop_l_r(R9_INDEX);
|
||||
raw_pop_l_r(R8_INDEX);
|
||||
raw_pop_l_r(ESI_INDEX);
|
||||
raw_pop_l_r(EDI_INDEX);
|
||||
raw_pop_l_r(EBP_INDEX);
|
||||
raw_pop_l_r(EBX_INDEX);
|
||||
raw_pop_l_r(EDX_INDEX);
|
||||
raw_pop_l_r(ECX_INDEX);
|
||||
raw_pop_l_r(EAX_INDEX);
|
||||
raw_popfl();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
static void print_inst(void)
|
||||
{
|
||||
disasm_m68k_block(regs.fault_pc + (uint8 *)MEMBaseDiff, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef UAE
|
||||
void compile_block(cpu_history *pc_hist, int blocklen, int totcycles)
|
||||
{
|
||||
|
@ -4722,7 +4960,7 @@ static void compile_block(cpu_history* pc_hist, int blocklen)
|
|||
remove_all_offsets();
|
||||
prepare_for_call_1();
|
||||
prepare_for_call_2();
|
||||
raw_mov_l_ri(REG_PAR1, ((uintptr)(pc_hist[i].location)) - MEMBaseDiff);
|
||||
raw_mov_l_ri(REG_PAR1, (memptr)((uintptr)pc_hist[i].location - MEMBaseDiff));
|
||||
raw_mov_w_ri(REG_PAR2, cft_map(opcode));
|
||||
raw_dec_sp(STACK_SHADOW_SPACE);
|
||||
compemu_raw_call((uintptr)m68k_record_step);
|
||||
|
@ -4738,7 +4976,16 @@ static void compile_block(cpu_history* pc_hist, int blocklen)
|
|||
init_comp();
|
||||
}
|
||||
was_comp=1;
|
||||
|
||||
|
||||
#if defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K)
|
||||
/* debugging helpers; activate as needed */
|
||||
#if 1
|
||||
disasm_this_inst = false;
|
||||
const uae_u8 *start_m68k_thisinst = (const uae_u8 *)pc_hist[i].location;
|
||||
uae_u8 *start_native_thisinst = get_target();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef WINUAE_ARANYM
|
||||
bool isnop = do_get_mem_word(pc_hist[i].location) == 0x4e71 ||
|
||||
((i + 1) < blocklen && do_get_mem_word(pc_hist[i+1].location) == 0x4e71);
|
||||
|
@ -4769,6 +5016,44 @@ static void compile_block(cpu_history* pc_hist, int blocklen)
|
|||
nop();
|
||||
was_comp=0;
|
||||
}
|
||||
#endif
|
||||
#if defined(HAVE_DISASM_NATIVE) && defined(HAVE_DISASM_M68K)
|
||||
|
||||
/* debugging helpers; activate as needed */
|
||||
#if 0
|
||||
disasm_m68k_block(start_m68k_thisinst, 1);
|
||||
push_all_nat();
|
||||
compemu_raw_mov_l_mi(uae_p32(®s.fault_pc), (uintptr)start_m68k_thisinst - MEMBaseDiff);
|
||||
raw_dec_sp(STACK_SHADOW_SPACE);
|
||||
compemu_raw_call(uae_p32(print_instn));
|
||||
raw_inc_sp(STACK_SHADOW_SPACE);
|
||||
pop_all_nat();
|
||||
#endif
|
||||
|
||||
if (disasm_this_inst)
|
||||
{
|
||||
disasm_m68k_block(start_m68k_thisinst, 1);
|
||||
#if 1
|
||||
disasm_native_block(start_native_thisinst, get_target() - start_native_thisinst);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
push_all_nat();
|
||||
|
||||
raw_dec_sp(STACK_SHADOW_SPACE);
|
||||
compemu_raw_mov_l_ri(REG_PAR1, (uae_u32)cft_map(opcode));
|
||||
compemu_raw_call((uintptr)print_exc_frame);
|
||||
raw_inc_sp(STACK_SHADOW_SPACE);
|
||||
|
||||
pop_all_nat();
|
||||
#endif
|
||||
|
||||
if (failure)
|
||||
{
|
||||
bug("(discarded)");
|
||||
target = start_native_thisinst;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -4797,8 +5082,8 @@ static void compile_block(cpu_history* pc_hist, int blocklen)
|
|||
if (i < blocklen - 1) {
|
||||
uae_u8* branchadd;
|
||||
|
||||
/* if (SPCFLAGS_TEST(SPCFLAG_STOP)) popall_do_nothing() */
|
||||
compemu_raw_mov_l_rm(0,(uintptr)specflags);
|
||||
/* if (SPCFLAGS_TEST(SPCFLAG_ALL)) popall_do_nothing() */
|
||||
compemu_raw_mov_l_rm(0, (uintptr)specflags);
|
||||
compemu_raw_test_l_rr(0,0);
|
||||
#if defined(USE_DATA_BUFFER)
|
||||
data_check_end(8, 64); // just a pessimistic guess...
|
||||
|
@ -4810,7 +5095,7 @@ static void compile_block(cpu_history* pc_hist, int blocklen)
|
|||
raw_sub_l_mi(uae_p32(&countdown),scaled_cycles(totcycles));
|
||||
#endif
|
||||
compemu_raw_jmp((uintptr)popall_do_nothing);
|
||||
*branchadd=get_target()-branchadd-1;
|
||||
*branchadd = get_target() - (branchadd + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -262,6 +262,7 @@ finish_braces (void)
|
|||
{
|
||||
while (n_braces > 0)
|
||||
close_brace ();
|
||||
comprintf ("\n");
|
||||
}
|
||||
|
||||
static inline void gen_update_next_handler(void)
|
||||
|
@ -355,7 +356,33 @@ swap_opcode (void)
|
|||
static void
|
||||
sync_m68k_pc (void)
|
||||
{
|
||||
comprintf("\t if (m68k_pc_offset > SYNC_PC_OFFSET) sync_m68k_pc();\n");
|
||||
comprintf(" if (m68k_pc_offset > SYNC_PC_OFFSET)\n sync_m68k_pc();\n");
|
||||
}
|
||||
|
||||
|
||||
static void gen_set_fault_pc(void)
|
||||
{
|
||||
start_brace();
|
||||
comprintf("\tsync_m68k_pc();\n");
|
||||
comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
|
||||
comprintf("\tint ret=scratchie++;\n"
|
||||
"\tmov_l_ri(ret,retadd);\n"
|
||||
"\tmov_l_mr((uintptr)®s.fault_pc,ret);\n");
|
||||
}
|
||||
|
||||
|
||||
static void make_sr(void)
|
||||
{
|
||||
start_brace();
|
||||
comprintf("\tint sr = scratchie++;\n");
|
||||
comprintf("\tint tmp = scratchie++;\n");
|
||||
comprintf("\tcompemu_make_sr(sr, tmp);\n");
|
||||
}
|
||||
|
||||
|
||||
static void disasm_this_inst(void)
|
||||
{
|
||||
comprintf("\tdisasm_this_inst = true;\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -1751,7 +1778,31 @@ gen_opcode (unsigned int opcode)
|
|||
break;
|
||||
|
||||
case i_TRAP:
|
||||
#ifdef DISABLE_I_TRAP
|
||||
failure;
|
||||
#endif
|
||||
isjump;
|
||||
mayfail;
|
||||
start_brace();
|
||||
comprintf(" int trapno = srcreg + 32;\n");
|
||||
gen_set_fault_pc();
|
||||
make_sr();
|
||||
comprintf(" compemu_enter_super(sr);\n");
|
||||
comprintf(" compemu_exc_make_frame(0, sr, ret, trapno, scratchie);\n");
|
||||
comprintf(" forget_about(ret);\n");
|
||||
/* m68k_setpc (get_long (regs.vbr + 4*nr)); */
|
||||
start_brace();
|
||||
comprintf(" int srca = scratchie++;\n");
|
||||
comprintf(" mov_l_rm(srca, (uintptr)®s.vbr);\n");
|
||||
comprintf(" mov_l_brR(srca, srca, MEMBaseDiff + trapno * 4); mid_bswap_32(srca);\n");
|
||||
comprintf(" mov_l_mr((uintptr)®s.pc, srca);\n");
|
||||
comprintf(" get_n_addr_jmp(srca, PC_P, scratchie);\n");
|
||||
comprintf(" mov_l_mr((uintptr)®s.pc_oldp, PC_P);\n");
|
||||
gen_update_next_handler();
|
||||
disasm_this_inst(); /* for debugging only */
|
||||
/*
|
||||
* this currently deactivates this feature, since it does not work yet
|
||||
*/
|
||||
failure;
|
||||
break;
|
||||
|
||||
|
@ -1792,12 +1843,12 @@ gen_opcode (unsigned int opcode)
|
|||
comprintf("\tadd_l_ri(offs,4);\n");
|
||||
start_brace();
|
||||
comprintf("\tint newad=scratchie++;\n"
|
||||
"\treadlong(15,newad,scratchie);\n"
|
||||
"\treadlong(SP_REG,newad,scratchie);\n"
|
||||
"\tmov_l_mr((uintptr)®s.pc,newad);\n"
|
||||
"\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
|
||||
"\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n"
|
||||
"\tm68k_pc_offset=0;\n"
|
||||
"\tadd_l(15,offs);\n");
|
||||
"\tadd_l(SP_REG,offs);\n");
|
||||
gen_update_next_handler();
|
||||
isjump;
|
||||
break;
|
||||
|
@ -1808,12 +1859,12 @@ gen_opcode (unsigned int opcode)
|
|||
#endif
|
||||
genamode (curi->smode, "srcreg", sz_long, "src", 1, 0);
|
||||
genamode (curi->dmode, "dstreg", curi->size, "offs", 1, 0);
|
||||
comprintf("\tsub_l_ri(15,4);\n"
|
||||
"\twritelong_clobber(15,src,scratchie);\n"
|
||||
"\tmov_l_rr(src,15);\n");
|
||||
comprintf("\tsub_l_ri(SP_REG,4);\n"
|
||||
"\twritelong_clobber(SP_REG,src,scratchie);\n"
|
||||
"\tmov_l_rr(src,SP_REG);\n");
|
||||
if (curi->size==sz_word)
|
||||
comprintf("\tsign_extend_16_rr(offs,offs);\n");
|
||||
comprintf("\tadd_l(15,offs);\n");
|
||||
comprintf("\tadd_l(SP_REG,offs);\n");
|
||||
genastore ("src", curi->smode, "srcreg", sz_long, "src");
|
||||
break;
|
||||
|
||||
|
@ -1822,9 +1873,9 @@ gen_opcode (unsigned int opcode)
|
|||
failure;
|
||||
#endif
|
||||
genamode (curi->smode, "srcreg", curi->size, "src", 1, 0);
|
||||
comprintf("\tmov_l_rr(15,src);\n"
|
||||
"\treadlong(15,src,scratchie);\n"
|
||||
"\tadd_l_ri(15,4);\n");
|
||||
comprintf("\tmov_l_rr(SP_REG,src);\n"
|
||||
"\treadlong(SP_REG,src,scratchie);\n"
|
||||
"\tadd_l_ri(SP_REG,4);\n");
|
||||
genastore ("src", curi->smode, "srcreg", curi->size, "src");
|
||||
break;
|
||||
|
||||
|
@ -1833,12 +1884,12 @@ gen_opcode (unsigned int opcode)
|
|||
failure;
|
||||
#endif
|
||||
comprintf("\tint newad=scratchie++;\n"
|
||||
"\treadlong(15,newad,scratchie);\n"
|
||||
"\treadlong(SP_REG,newad,scratchie);\n"
|
||||
"\tmov_l_mr((uintptr)®s.pc,newad);\n"
|
||||
"\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
|
||||
"\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n"
|
||||
"\tm68k_pc_offset=0;\n"
|
||||
"\tlea_l_brr(15,15,4);\n");
|
||||
"\tlea_l_brr(SP_REG,SP_REG,4);\n");
|
||||
gen_update_next_handler();
|
||||
isjump;
|
||||
break;
|
||||
|
@ -1863,8 +1914,8 @@ gen_opcode (unsigned int opcode)
|
|||
comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
|
||||
comprintf("\tint ret=scratchie++;\n"
|
||||
"\tmov_l_ri(ret,retadd);\n"
|
||||
"\tsub_l_ri(15,4);\n"
|
||||
"\twritelong_clobber(15,ret,scratchie);\n");
|
||||
"\tsub_l_ri(SP_REG,4);\n"
|
||||
"\twritelong_clobber(SP_REG,ret,scratchie);\n");
|
||||
comprintf("\tmov_l_mr((uintptr)®s.pc,srca);\n"
|
||||
"\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
|
||||
"\tmov_l_mr((uintptr)®s.pc_oldp,PC_P);\n"
|
||||
|
@ -1895,13 +1946,14 @@ gen_opcode (unsigned int opcode)
|
|||
comprintf("\tuae_u32 retadd=start_pc+((char *)comp_pc_p-(char *)start_pc_p)+m68k_pc_offset;\n");
|
||||
comprintf("\tint ret=scratchie++;\n"
|
||||
"\tmov_l_ri(ret,retadd);\n"
|
||||
"\tsub_l_ri(15,4);\n"
|
||||
"\twritelong_clobber(15,ret,scratchie);\n");
|
||||
"\tsub_l_ri(SP_REG,4);\n"
|
||||
"\twritelong_clobber(SP_REG,ret,scratchie);\n");
|
||||
comprintf("\tadd_l_ri(src,m68k_pc_offset_thisinst+2);\n");
|
||||
comprintf("\tm68k_pc_offset=0;\n");
|
||||
comprintf("\tadd_l(PC_P,src);\n");
|
||||
|
||||
comprintf("\tcomp_pc_p=(uae_u8*)(uintptr)get_const(PC_P);\n");
|
||||
gen_update_next_handler();
|
||||
break;
|
||||
|
||||
case i_Bcc:
|
||||
|
@ -2029,7 +2081,7 @@ gen_opcode (unsigned int opcode)
|
|||
case 1:
|
||||
comprintf("\tstart_needflags();\n");
|
||||
comprintf("\tsub_w_ri(src,1);\n");
|
||||
comprintf("\t end_needflags();\n");
|
||||
comprintf("\tend_needflags();\n");
|
||||
start_brace();
|
||||
comprintf("\tuae_u32 v2,v;\n"
|
||||
"\tuae_u32 v1=get_const(PC_P);\n");
|
||||
|
@ -2063,9 +2115,9 @@ gen_opcode (unsigned int opcode)
|
|||
so whether we move them around doesn't matter. However,
|
||||
if cc=false, we have offs==jump_pc, and src==nsrc-1 */
|
||||
|
||||
comprintf("\t start_needflags();\n");
|
||||
comprintf("\tstart_needflags();\n");
|
||||
comprintf("\ttest_w_rr(nsrc,nsrc);\n");
|
||||
comprintf("\t end_needflags();\n");
|
||||
comprintf("\tend_needflags();\n");
|
||||
comprintf("\tcmov_l_rr(PC_P,offs,%d);\n", NATIVE_CC_NE);
|
||||
break;
|
||||
default: assert(0);
|
||||
|
@ -2174,10 +2226,11 @@ gen_opcode (unsigned int opcode)
|
|||
#endif
|
||||
mayfail;
|
||||
if (curi->smode==Dreg) {
|
||||
comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
"} \n");
|
||||
comprintf(
|
||||
" if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
" }\n");
|
||||
start_brace();
|
||||
}
|
||||
comprintf("\tdont_care_flags();\n");
|
||||
|
@ -2249,10 +2302,11 @@ gen_opcode (unsigned int opcode)
|
|||
#endif
|
||||
mayfail;
|
||||
if (curi->smode==Dreg) {
|
||||
comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
"} \n");
|
||||
comprintf(
|
||||
" if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
" }\n");
|
||||
start_brace();
|
||||
}
|
||||
comprintf("\tdont_care_flags();\n");
|
||||
|
@ -2260,10 +2314,11 @@ gen_opcode (unsigned int opcode)
|
|||
LSL. The handling of V is, uhm, unpleasant, so if it's needed,
|
||||
let the normal emulation handle it. Shoulders of giants kinda
|
||||
thing ;-) */
|
||||
comprintf("if (needed_flags & FLAG_V) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
"} \n");
|
||||
comprintf(
|
||||
" if (needed_flags & FLAG_V) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
" }\n");
|
||||
|
||||
genamode (curi->smode, "srcreg", curi->size, "cnt", 1, 0);
|
||||
genamode (curi->dmode, "dstreg", curi->size, "data", 1, 0);
|
||||
|
@ -2323,10 +2378,11 @@ gen_opcode (unsigned int opcode)
|
|||
#endif
|
||||
mayfail;
|
||||
if (curi->smode==Dreg) {
|
||||
comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
"} \n");
|
||||
comprintf(
|
||||
" if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
" }\n");
|
||||
start_brace();
|
||||
}
|
||||
comprintf("\tdont_care_flags();\n");
|
||||
|
@ -2390,10 +2446,11 @@ gen_opcode (unsigned int opcode)
|
|||
#endif
|
||||
mayfail;
|
||||
if (curi->smode==Dreg) {
|
||||
comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
"} \n");
|
||||
comprintf(
|
||||
" if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
" }\n");
|
||||
start_brace();
|
||||
}
|
||||
comprintf("\tdont_care_flags();\n");
|
||||
|
@ -2457,10 +2514,11 @@ gen_opcode (unsigned int opcode)
|
|||
#endif
|
||||
mayfail;
|
||||
if (curi->smode==Dreg) {
|
||||
comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
"} \n");
|
||||
comprintf(
|
||||
" if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
" }\n");
|
||||
start_brace();
|
||||
}
|
||||
comprintf("\tdont_care_flags();\n");
|
||||
|
@ -2469,9 +2527,9 @@ gen_opcode (unsigned int opcode)
|
|||
start_brace ();
|
||||
|
||||
switch(curi->size) {
|
||||
case sz_long: comprintf("\t rol_l_rr(data,cnt);\n"); break;
|
||||
case sz_word: comprintf("\t rol_w_rr(data,cnt);\n"); break;
|
||||
case sz_byte: comprintf("\t rol_b_rr(data,cnt);\n"); break;
|
||||
case sz_long: comprintf("\trol_l_rr(data,cnt);\n"); break;
|
||||
case sz_word: comprintf("\trol_w_rr(data,cnt);\n"); break;
|
||||
case sz_byte: comprintf("\trol_b_rr(data,cnt);\n"); break;
|
||||
}
|
||||
|
||||
if (!noflags) {
|
||||
|
@ -2481,13 +2539,13 @@ gen_opcode (unsigned int opcode)
|
|||
*/
|
||||
comprintf("\tif (needed_flags & FLAG_ZNV)\n");
|
||||
switch(curi->size) {
|
||||
case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
|
||||
case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
|
||||
case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
|
||||
case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
|
||||
case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
|
||||
case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
|
||||
}
|
||||
comprintf("\t bt_l_ri(data,0x00);\n"); /* Set C */
|
||||
comprintf("\t live_flags();\n");
|
||||
comprintf("\t end_needflags();\n");
|
||||
comprintf("\tbt_l_ri(data,0x00);\n"); /* Set C */
|
||||
comprintf("\tlive_flags();\n");
|
||||
comprintf("\tend_needflags();\n");
|
||||
}
|
||||
genastore ("data", curi->dmode, "dstreg", curi->size, "data");
|
||||
break;
|
||||
|
@ -2498,10 +2556,11 @@ gen_opcode (unsigned int opcode)
|
|||
#endif
|
||||
mayfail;
|
||||
if (curi->smode==Dreg) {
|
||||
comprintf("if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
"} \n");
|
||||
comprintf(
|
||||
" if ((uae_u32)srcreg==(uae_u32)dstreg) {\n"
|
||||
" FAIL(1);\n"
|
||||
" " RETURN "\n"
|
||||
" }\n");
|
||||
start_brace();
|
||||
}
|
||||
comprintf("\tdont_care_flags();\n");
|
||||
|
@ -2510,9 +2569,9 @@ gen_opcode (unsigned int opcode)
|
|||
start_brace ();
|
||||
|
||||
switch(curi->size) {
|
||||
case sz_long: comprintf("\t ror_l_rr(data,cnt);\n"); break;
|
||||
case sz_word: comprintf("\t ror_w_rr(data,cnt);\n"); break;
|
||||
case sz_byte: comprintf("\t ror_b_rr(data,cnt);\n"); break;
|
||||
case sz_long: comprintf("\tror_l_rr(data,cnt);\n"); break;
|
||||
case sz_word: comprintf("\tror_w_rr(data,cnt);\n"); break;
|
||||
case sz_byte: comprintf("\tror_b_rr(data,cnt);\n"); break;
|
||||
}
|
||||
|
||||
if (!noflags) {
|
||||
|
@ -2522,17 +2581,17 @@ gen_opcode (unsigned int opcode)
|
|||
*/
|
||||
comprintf("\tif (needed_flags & FLAG_ZNV)\n");
|
||||
switch(curi->size) {
|
||||
case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
|
||||
case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
|
||||
case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
|
||||
case sz_byte: comprintf("\t test_b_rr(data,data);\n"); break;
|
||||
case sz_word: comprintf("\t test_w_rr(data,data);\n"); break;
|
||||
case sz_long: comprintf("\t test_l_rr(data,data);\n"); break;
|
||||
}
|
||||
switch(curi->size) {
|
||||
case sz_byte: comprintf("\t bt_l_ri(data,0x07);\n"); break;
|
||||
case sz_word: comprintf("\t bt_l_ri(data,0x0f);\n"); break;
|
||||
case sz_long: comprintf("\t bt_l_ri(data,0x1f);\n"); break;
|
||||
case sz_byte: comprintf("\tbt_l_ri(data,0x07);\n"); break;
|
||||
case sz_word: comprintf("\tbt_l_ri(data,0x0f);\n"); break;
|
||||
case sz_long: comprintf("\tbt_l_ri(data,0x1f);\n"); break;
|
||||
}
|
||||
comprintf("\t live_flags();\n");
|
||||
comprintf("\t end_needflags();\n");
|
||||
comprintf("\tlive_flags();\n");
|
||||
comprintf("\tend_needflags();\n");
|
||||
}
|
||||
genastore ("data", curi->dmode, "dstreg", curi->size, "data");
|
||||
break;
|
||||
|
@ -2816,7 +2875,7 @@ gen_opcode (unsigned int opcode)
|
|||
finish_braces ();
|
||||
sync_m68k_pc ();
|
||||
if (global_mayfail)
|
||||
comprintf("\tif (failure) m68k_pc_offset=m68k_pc_offset_thisinst;\n");
|
||||
comprintf(" if (failure)\n m68k_pc_offset = m68k_pc_offset_thisinst;\n");
|
||||
return global_failure;
|
||||
}
|
||||
|
||||
|
@ -3284,6 +3343,7 @@ int main(void)
|
|||
free (table68k);
|
||||
fclose (stblfile);
|
||||
fclose (headerfile);
|
||||
(void)disasm_this_inst;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1409,30 +1409,9 @@ static void gen_opcode (unsigned long int opcode)
|
|||
fill_prefetch_0 ();
|
||||
printf ("\tMakeFromSR();\n");
|
||||
} else {
|
||||
int old_brace_level = n_braces;
|
||||
if (next_cpu_level < 0)
|
||||
if (next_cpu_level < 0)
|
||||
next_cpu_level = 0;
|
||||
printf ("\tuae_u16 newsr; uae_u32 newpc; for (;;) {\n");
|
||||
genamode (Aipi, "7", sz_word, "sr", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG);
|
||||
genamode (Aipi, "7", sz_long, "pc", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG);
|
||||
genamode (Aipi, "7", sz_word, "format", GENA_GETV_FETCH, GENA_MOVEM_DO_INC, XLATE_LOG);
|
||||
printf ("\tnewsr = sr; newpc = pc;\n");
|
||||
printf ("\tif ((format & 0xF000) == 0x0000) { break; }\n");
|
||||
printf ("\telse if ((format & 0xF000) == 0x1000) { ; }\n");
|
||||
printf ("\telse if ((format & 0xF000) == 0x2000) { m68k_areg(regs, 7) += 4; break; }\n");
|
||||
// printf ("\telse if ((format & 0xF000) == 0x3000) { m68k_areg(regs, 7) += 4; break; }\n");
|
||||
printf ("\telse if ((format & 0xF000) == 0x7000) { m68k_areg(regs, 7) += 52; break; }\n");
|
||||
printf ("\telse if ((format & 0xF000) == 0x8000) { m68k_areg(regs, 7) += 50; break; }\n");
|
||||
printf ("\telse if ((format & 0xF000) == 0x9000) { m68k_areg(regs, 7) += 12; break; }\n");
|
||||
printf ("\telse if ((format & 0xF000) == 0xa000) { m68k_areg(regs, 7) += 24; break; }\n");
|
||||
printf ("\telse if ((format & 0xF000) == 0xb000) { m68k_areg(regs, 7) += 84; break; }\n");
|
||||
printf ("\telse { Exception(14,0); goto %s; }\n", endlabelstr);
|
||||
printf ("\tregs.sr = newsr; MakeFromSR();\n}\n");
|
||||
pop_braces (old_brace_level);
|
||||
printf ("\tregs.sr = newsr; MakeFromSR();\n");
|
||||
printf ("\tm68k_setpc_rte(newpc);\n");
|
||||
fill_prefetch_0 ();
|
||||
need_endlabel = 1;
|
||||
printf ("\tex_rte();\n");
|
||||
}
|
||||
/* PC is set and prefetch filled. */
|
||||
m68k_pc_offset = 0;
|
||||
|
|
|
@ -38,7 +38,11 @@
|
|||
|
||||
#if (defined(CPU_i386) && defined(X86_ASSEMBLY)) || (defined(CPU_x86_64) && defined(X86_64_ASSEMBLY))
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include <cstdlib>
|
||||
#else
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifndef SAHF_SETO_PROFITABLE
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ static ALWAYS_INLINE void check_ram_boundary(uaecptr addr, int size, bool write)
|
|||
|
||||
// D(bug("BUS ERROR %s at $%x\n", (write ? "writing" : "reading"), addr));
|
||||
regs.mmu_fault_addr = addr;
|
||||
regs.mmu_ssw = ((size & 3) << 5) | (write ? 0 : (1 << 8));
|
||||
regs.mmu_ssw = ((size & 3) << 5) | (write ? 0 : (1 << 8)); /* MMU_SW_RW */
|
||||
breakpt();
|
||||
THROW(2);
|
||||
}
|
||||
|
|
|
@ -491,6 +491,65 @@ static inline void exc_make_frame(
|
|||
exc_push_word((format << 12) + (nr * 4)); /* format | vector */
|
||||
exc_push_long(currpc);
|
||||
exc_push_word(sr);
|
||||
#if 0 /* debugging helpers; activate as needed */
|
||||
if (/* nr != 0x45 && */ /* Timer-C */
|
||||
nr != 0x1c && /* VBL */
|
||||
nr != 0x46) /* ACIA */
|
||||
{
|
||||
memptr sp = m68k_areg(regs, 7);
|
||||
uae_u16 sr = get_word(sp);
|
||||
fprintf(stderr, "Exc:%02x SP: %08x USP: %08x SR: %04x PC: %08x Format: %04x", nr, sp, regs.usp, sr, get_long(sp + 2), get_word(sp + 6));
|
||||
if (nr >= 32 && nr < 48)
|
||||
{
|
||||
fprintf(stderr, " Opcode: $%04x", sr & 0x2000 ? get_word(sp + 8) : get_word(regs.usp));
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ex_rte(void)
|
||||
{
|
||||
uae_u16 newsr;
|
||||
uae_u32 newpc;
|
||||
uae_s16 format;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
newsr = get_word(m68k_areg(regs, 7));
|
||||
m68k_areg(regs, 7) += 2;
|
||||
newpc = get_long(m68k_areg(regs, 7));
|
||||
m68k_areg(regs, 7) += 4;
|
||||
format = get_word(m68k_areg(regs, 7));
|
||||
m68k_areg(regs, 7) += 2;
|
||||
if ((format & 0xF000) == 0x0000) break;
|
||||
else if ((format & 0xF000) == 0x1000) { ; }
|
||||
else if ((format & 0xF000) == 0x2000) { m68k_areg(regs, 7) += 4; break; }
|
||||
// else if ((format & 0xF000) == 0x3000) { m68k_areg(regs, 7) += 4; break; }
|
||||
else if ((format & 0xF000) == 0x7000) { m68k_areg(regs, 7) += 52; break; }
|
||||
else if ((format & 0xF000) == 0x8000) { m68k_areg(regs, 7) += 50; break; }
|
||||
else if ((format & 0xF000) == 0x9000) { m68k_areg(regs, 7) += 12; break; }
|
||||
else if ((format & 0xF000) == 0xa000) { m68k_areg(regs, 7) += 24; break; }
|
||||
else if ((format & 0xF000) == 0xb000) { m68k_areg(regs, 7) += 84; break; }
|
||||
else { Exception(14,0); return; }
|
||||
regs.sr = newsr;
|
||||
MakeFromSR();
|
||||
}
|
||||
#if 0 /* debugging helpers; activate as needed */
|
||||
{
|
||||
memptr sp = m68k_areg(regs, 7) - 8;
|
||||
int nr = (format & 0xfff) >> 2;
|
||||
if (/* nr != 0x45 && */ /* Timer-C */
|
||||
nr != 0x1c && /* VBL */
|
||||
nr != 0x46) /* ACIA */
|
||||
fprintf(stderr, "RTE SP: %08x USP: %08x SR: %04x PC: %08x Format: %04x olds=%d nr=%02x -> %08x\n", sp, regs.usp, newsr, m68k_getpc(), format, regs.s, nr, newpc);
|
||||
}
|
||||
#endif
|
||||
regs.sr = newsr;
|
||||
MakeFromSR();
|
||||
m68k_setpc_rte(newpc);
|
||||
fill_prefetch_0();
|
||||
}
|
||||
|
||||
#ifdef EXCEPTIONS_VIA_LONGJMP
|
||||
|
@ -570,7 +629,7 @@ void Exception(int nr, uaecptr oldpc)
|
|||
} else if (nr == 3) {
|
||||
exc_make_frame(2, regs.sr, last_addr_for_exception_3, nr,
|
||||
last_fault_for_exception_3 & 0xfffffffe, 0);
|
||||
} else if (nr ==5 || nr == 6 || nr == 7 || nr == 9) {
|
||||
} else if (nr == 5 || nr == 6 || nr == 7 || nr == 9) {
|
||||
/* div by zero, CHK, TRAP or TRACE */
|
||||
exc_make_frame(2, regs.sr, currpc, nr, oldpc, 0);
|
||||
} else if (regs.m && nr >= 24 && nr < 32) {
|
||||
|
|
|
@ -271,6 +271,7 @@ extern REGPARAM void put_bitfield(uae_u32 dst, uae_u32 bdata[2], uae_u32 val, ua
|
|||
extern void MakeSR (void);
|
||||
extern void MakeFromSR (void);
|
||||
extern void Exception (int, uaecptr);
|
||||
extern void ex_rte(void);
|
||||
extern void dump_counts (void);
|
||||
extern int m68k_move2c (int, uae_u32 *);
|
||||
extern int m68k_movec2 (int, uae_u32 *);
|
||||
|
|
|
@ -61,9 +61,8 @@ extern struct regstruct
|
|||
flagtype t0;
|
||||
flagtype s;
|
||||
flagtype m;
|
||||
flagtype x;
|
||||
flagtype stopped;
|
||||
int intmask;
|
||||
uint32_t intmask;
|
||||
|
||||
uae_u32 pc;
|
||||
uae_u32 fault_pc;
|
||||
|
|
Loading…
Reference in New Issue
Block a user