Sync with latest ARAnyM changes

This commit is contained in:
uyjulian 2020-01-12 09:50:04 -06:00
parent 67dd2e6676
commit 9dc485c56a
No known key found for this signature in database
GPG Key ID: FEA459A8CA14685B
14 changed files with 696 additions and 262 deletions

View File

@ -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:>
}

View File

@ -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)

View File

@ -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)))

View File

@ -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))
{

View File

@ -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);
}

View File

@ -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));

View File

@ -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(&regflags.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(&regflags.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(&regs.c));
shll_l_ri(tmp, 0);
or_l(sr, tmp);
mov_b_rm(tmp, uae_p32(&regs.v));
shll_l_ri(tmp, 1);
or_l(sr, tmp);
mov_b_rm(tmp, uae_p32(&regs.z));
shll_l_ri(tmp, 2);
or_l(sr, tmp);
mov_b_rm(tmp, uae_p32(&regs.n));
shll_l_ri(tmp, 3);
or_l(sr, tmp);
#endif /* OPTIMIZED_FLAGS */
mov_b_rm(tmp, uae_p32(&regs.s));
shll_l_ri(tmp, 13);
or_l(sr, tmp);
mov_l_rm(tmp, uae_p32(&regs.intmask));
shll_l_ri(tmp, 8);
or_l(sr, tmp);
and_l_ri(sr, 0x271f);
mov_w_mr(uae_p32(&regs.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)&regs.usp, SP_REG);
mov_l_rm(SP_REG, uae_p32(&regs.isp));
mov_b_mi(uae_p32(&regs.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(&regs.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);
}
}
}

View File

@ -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)&regs.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)&regs.vbr);\n");
comprintf(" mov_l_brR(srca, srca, MEMBaseDiff + trapno * 4); mid_bswap_32(srca);\n");
comprintf(" mov_l_mr((uintptr)&regs.pc, srca);\n");
comprintf(" get_n_addr_jmp(srca, PC_P, scratchie);\n");
comprintf(" mov_l_mr((uintptr)&regs.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)&regs.pc,newad);\n"
"\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
"\tmov_l_mr((uintptr)&regs.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)&regs.pc,newad);\n"
"\tget_n_addr_jmp(newad,PC_P,scratchie);\n"
"\tmov_l_mr((uintptr)&regs.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)&regs.pc,srca);\n"
"\tget_n_addr_jmp(srca,PC_P,scratchie);\n"
"\tmov_l_mr((uintptr)&regs.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;
}

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -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) {

View File

@ -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 *);

View File

@ -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;