diff options
Diffstat (limited to 'target-m68k')
-rw-r--r-- | target-m68k/Makefile.objs | 2 | ||||
-rw-r--r-- | target-m68k/cpu-qom.h | 2 | ||||
-rw-r--r-- | target-m68k/cpu.h | 15 | ||||
-rw-r--r-- | target-m68k/helper.c | 13 | ||||
-rw-r--r-- | target-m68k/helpers.h | 6 | ||||
-rw-r--r-- | target-m68k/m68k-semi.c | 197 | ||||
-rw-r--r-- | target-m68k/op_helper.c | 89 | ||||
-rw-r--r-- | target-m68k/translate.c | 318 |
8 files changed, 342 insertions, 300 deletions
diff --git a/target-m68k/Makefile.objs b/target-m68k/Makefile.objs index cda60157f5..7eccfab0e4 100644 --- a/target-m68k/Makefile.objs +++ b/target-m68k/Makefile.objs @@ -1,5 +1,3 @@ obj-y += m68k-semi.o obj-y += translate.o op_helper.o helper.o cpu.o obj-$(CONFIG_SOFTMMU) += machine.o - -$(obj)/op_helper.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h index 805786b04d..170daa7c96 100644 --- a/target-m68k/cpu-qom.h +++ b/target-m68k/cpu-qom.h @@ -20,7 +20,7 @@ #ifndef QEMU_M68K_CPU_QOM_H #define QEMU_M68K_CPU_QOM_H -#include "qemu/cpu.h" +#include "qom/cpu.h" #define TYPE_M68K_CPU "m68k-cpu" diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h index 5e6ee50969..adaf56c471 100644 --- a/target-m68k/cpu.h +++ b/target-m68k/cpu.h @@ -26,9 +26,9 @@ #include "config.h" #include "qemu-common.h" -#include "cpu-defs.h" +#include "exec/cpu-defs.h" -#include "softfloat.h" +#include "fpu/softfloat.h" #define MAX_QREGS 32 @@ -103,9 +103,6 @@ typedef struct CPUM68KState { uint32_t rambar0; uint32_t cacr; - /* ??? remove this. */ - uint32_t t1; - int pending_vector; int pending_level; @@ -245,7 +242,7 @@ static inline void cpu_clone_regs(CPUM68KState *env, target_ulong newsp) } #endif -#include "cpu-all.h" +#include "exec/cpu-all.h" static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc, target_ulong *cs_base, int *flags) @@ -257,12 +254,14 @@ static inline void cpu_get_tb_cpu_state(CPUM68KState *env, target_ulong *pc, | ((env->macsr >> 4) & 0xf); /* Bits 0-3 */ } -static inline bool cpu_has_work(CPUM68KState *env) +static inline bool cpu_has_work(CPUState *cpu) { + CPUM68KState *env = &M68K_CPU(cpu)->env; + return env->interrupt_request & CPU_INTERRUPT_HARD; } -#include "exec-all.h" +#include "exec/exec-all.h" static inline void cpu_pc_from_tb(CPUM68KState *env, TranslationBlock *tb) { diff --git a/target-m68k/helper.c b/target-m68k/helper.c index eac0053c5d..097fc789d4 100644 --- a/target-m68k/helper.c +++ b/target-m68k/helper.c @@ -19,17 +19,12 @@ */ #include "cpu.h" -#include "gdbstub.h" +#include "exec/gdbstub.h" #include "helpers.h" #define SIGNBIT (1u << 31) -typedef struct M68kCPUListState { - fprintf_function cpu_fprintf; - FILE *file; -} M68kCPUListState; - /* Sort alphabetically, except for "any". */ static gint m68k_cpu_list_compare(gconstpointer a, gconstpointer b) { @@ -51,7 +46,7 @@ static gint m68k_cpu_list_compare(gconstpointer a, gconstpointer b) static void m68k_cpu_list_entry(gpointer data, gpointer user_data) { ObjectClass *c = data; - M68kCPUListState *s = user_data; + CPUListState *s = user_data; (*s->cpu_fprintf)(s->file, "%s\n", object_class_get_name(c)); @@ -59,7 +54,7 @@ static void m68k_cpu_list_entry(gpointer data, gpointer user_data) void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf) { - M68kCPUListState s = { + CPUListState s = { .file = f, .cpu_fprintf = cpu_fprintf, }; @@ -289,7 +284,7 @@ int cpu_m68k_handle_mmu_fault (CPUM68KState *env, target_ulong address, int rw, /* MMU */ /* TODO: This will need fixing once the MMU is implemented. */ -target_phys_addr_t cpu_get_phys_page_debug(CPUM68KState *env, target_ulong addr) +hwaddr cpu_get_phys_page_debug(CPUM68KState *env, target_ulong addr) { return addr; } diff --git a/target-m68k/helpers.h b/target-m68k/helpers.h index cb8a0c7d4a..2b024502ba 100644 --- a/target-m68k/helpers.h +++ b/target-m68k/helpers.h @@ -1,4 +1,4 @@ -#include "def-helper.h" +#include "exec/def-helper.h" DEF_HELPER_1(bitrev, i32, i32) DEF_HELPER_1(ff1, i32, i32) @@ -49,6 +49,6 @@ DEF_HELPER_3(set_mac_exts, void, env, i32, i32) DEF_HELPER_3(set_mac_extu, void, env, i32, i32) DEF_HELPER_2(flush_flags, void, env, i32) -DEF_HELPER_1(raise_exception, void, i32) +DEF_HELPER_2(raise_exception, void, env, i32) -#include "def-helper.h" +#include "exec/def-helper.h" diff --git a/target-m68k/m68k-semi.c b/target-m68k/m68k-semi.c index 3bb30cd1f7..239fadbad5 100644 --- a/target-m68k/m68k-semi.c +++ b/target-m68k/m68k-semi.c @@ -33,10 +33,10 @@ #define SEMIHOSTING_HEAP_SIZE (128 * 1024 * 1024) #else #include "qemu-common.h" -#include "gdbstub.h" -#include "softmmu-semi.h" +#include "exec/gdbstub.h" +#include "exec/softmmu-semi.h" #endif -#include "sysemu.h" +#include "sysemu/sysemu.h" #define HOSTED_EXIT 0 #define HOSTED_INIT_SIM 1 @@ -133,37 +133,61 @@ static void translate_stat(CPUM68KState *env, target_ulong addr, struct stat *s) unlock_user(p, addr, sizeof(struct m68k_gdb_stat)); } +static void m68k_semi_return_u32(CPUM68KState *env, uint32_t ret, uint32_t err) +{ + target_ulong args = env->dregs[1]; + if (put_user_u32(ret, args) || + put_user_u32(err, args + 4)) { + /* The m68k semihosting ABI does not provide any way to report this + * error to the guest, so the best we can do is log it in qemu. + * It is always a guest error not to pass us a valid argument block. + */ + qemu_log_mask(LOG_GUEST_ERROR, "m68k-semihosting: return value " + "discarded because argument block not writable\n"); + } +} + +static void m68k_semi_return_u64(CPUM68KState *env, uint64_t ret, uint32_t err) +{ + target_ulong args = env->dregs[1]; + if (put_user_u32(ret >> 32, args) || + put_user_u32(ret, args + 4) || + put_user_u32(err, args + 8)) { + /* No way to report this via m68k semihosting ABI; just log it */ + qemu_log_mask(LOG_GUEST_ERROR, "m68k-semihosting: return value " + "discarded because argument block not writable\n"); + } +} + static int m68k_semi_is_fseek; static void m68k_semi_cb(CPUM68KState *env, target_ulong ret, target_ulong err) { - target_ulong args; - - args = env->dregs[1]; if (m68k_semi_is_fseek) { /* FIXME: We've already lost the high bits of the fseek return value. */ - /* FIXME - handle put_user() failure */ - put_user_u32(0, args); - args += 4; + m68k_semi_return_u64(env, ret, err); m68k_semi_is_fseek = 0; + } else { + m68k_semi_return_u32(env, ret, err); } - /* FIXME - handle put_user() failure */ - put_user_u32(ret, args); - put_user_u32(errno, args + 4); } -#define ARG(n) \ -({ \ - target_ulong __arg; \ - /* FIXME - handle get_user() failure */ \ - get_user_ual(__arg, args + (n) * 4); \ - __arg; \ -}) -#define PARG(x) ((unsigned long)ARG(x)) +/* Read the input value from the argument block; fail the semihosting + * call if the memory read fails. + */ +#define GET_ARG(n) do { \ + if (get_user_ual(arg ## n, args + (n) * 4)) { \ + result = -1; \ + errno = EFAULT; \ + goto failed; \ + } \ +} while (0) + void do_m68k_semihosting(CPUM68KState *env, int nr) { uint32_t args; + target_ulong arg0, arg1, arg2, arg3; void *p; void *q; uint32_t len; @@ -175,27 +199,33 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) gdb_exit(env, env->dregs[0]); exit(env->dregs[0]); case HOSTED_OPEN: + GET_ARG(0); + GET_ARG(1); + GET_ARG(2); + GET_ARG(3); if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "open,%s,%x,%x", ARG(0), (int)ARG(1), - ARG(2), ARG(3)); + gdb_do_syscall(m68k_semi_cb, "open,%s,%x,%x", arg0, (int)arg1, + arg2, arg3); return; } else { - if (!(p = lock_user_string(ARG(0)))) { + p = lock_user_string(arg0); + if (!p) { /* FIXME - check error code? */ result = -1; } else { - result = open(p, translate_openflags(ARG(2)), ARG(3)); - unlock_user(p, ARG(0), 0); + result = open(p, translate_openflags(arg2), arg3); + unlock_user(p, arg0, 0); } } break; case HOSTED_CLOSE: { /* Ignore attempts to close stdin/out/err. */ - int fd = ARG(0); + GET_ARG(0); + int fd = arg0; if (fd > 2) { if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "close,%x", ARG(0)); + gdb_do_syscall(m68k_semi_cb, "close,%x", arg0); return; } else { result = close(fd); @@ -206,123 +236,147 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) break; } case HOSTED_READ: - len = ARG(2); + GET_ARG(0); + GET_ARG(1); + GET_ARG(2); + len = arg2; if (use_gdb_syscalls()) { gdb_do_syscall(m68k_semi_cb, "read,%x,%x,%x", - ARG(0), ARG(1), len); + arg0, arg1, len); return; } else { - if (!(p = lock_user(VERIFY_WRITE, ARG(1), len, 0))) { + p = lock_user(VERIFY_WRITE, arg1, len, 0); + if (!p) { /* FIXME - check error code? */ result = -1; } else { - result = read(ARG(0), p, len); - unlock_user(p, ARG(1), len); + result = read(arg0, p, len); + unlock_user(p, arg1, len); } } break; case HOSTED_WRITE: - len = ARG(2); + GET_ARG(0); + GET_ARG(1); + GET_ARG(2); + len = arg2; if (use_gdb_syscalls()) { gdb_do_syscall(m68k_semi_cb, "write,%x,%x,%x", - ARG(0), ARG(1), len); + arg0, arg1, len); return; } else { - if (!(p = lock_user(VERIFY_READ, ARG(1), len, 1))) { + p = lock_user(VERIFY_READ, arg1, len, 1); + if (!p) { /* FIXME - check error code? */ result = -1; } else { - result = write(ARG(0), p, len); - unlock_user(p, ARG(0), 0); + result = write(arg0, p, len); + unlock_user(p, arg0, 0); } } break; case HOSTED_LSEEK: { uint64_t off; - off = (uint32_t)ARG(2) | ((uint64_t)ARG(1) << 32); + GET_ARG(0); + GET_ARG(1); + GET_ARG(2); + GET_ARG(3); + off = (uint32_t)arg2 | ((uint64_t)arg1 << 32); if (use_gdb_syscalls()) { m68k_semi_is_fseek = 1; gdb_do_syscall(m68k_semi_cb, "fseek,%x,%lx,%x", - ARG(0), off, ARG(3)); + arg0, off, arg3); } else { - off = lseek(ARG(0), off, ARG(3)); - /* FIXME - handle put_user() failure */ - put_user_u32(off >> 32, args); - put_user_u32(off, args + 4); - put_user_u32(errno, args + 8); + off = lseek(arg0, off, arg3); + m68k_semi_return_u64(env, off, errno); } return; } case HOSTED_RENAME: + GET_ARG(0); + GET_ARG(1); + GET_ARG(2); + GET_ARG(3); if (use_gdb_syscalls()) { gdb_do_syscall(m68k_semi_cb, "rename,%s,%s", - ARG(0), (int)ARG(1), ARG(2), (int)ARG(3)); + arg0, (int)arg1, arg2, (int)arg3); return; } else { - p = lock_user_string(ARG(0)); - q = lock_user_string(ARG(2)); + p = lock_user_string(arg0); + q = lock_user_string(arg2); if (!p || !q) { /* FIXME - check error code? */ result = -1; } else { result = rename(p, q); } - unlock_user(p, ARG(0), 0); - unlock_user(q, ARG(2), 0); + unlock_user(p, arg0, 0); + unlock_user(q, arg2, 0); } break; case HOSTED_UNLINK: + GET_ARG(0); + GET_ARG(1); if (use_gdb_syscalls()) { gdb_do_syscall(m68k_semi_cb, "unlink,%s", - ARG(0), (int)ARG(1)); + arg0, (int)arg1); return; } else { - if (!(p = lock_user_string(ARG(0)))) { + p = lock_user_string(arg0); + if (!p) { /* FIXME - check error code? */ result = -1; } else { result = unlink(p); - unlock_user(p, ARG(0), 0); + unlock_user(p, arg0, 0); } } break; case HOSTED_STAT: + GET_ARG(0); + GET_ARG(1); + GET_ARG(2); if (use_gdb_syscalls()) { gdb_do_syscall(m68k_semi_cb, "stat,%s,%x", - ARG(0), (int)ARG(1), ARG(2)); + arg0, (int)arg1, arg2); return; } else { struct stat s; - if (!(p = lock_user_string(ARG(0)))) { + p = lock_user_string(arg0); + if (!p) { /* FIXME - check error code? */ result = -1; } else { result = stat(p, &s); - unlock_user(p, ARG(0), 0); + unlock_user(p, arg0, 0); } if (result == 0) { - translate_stat(env, ARG(2), &s); + translate_stat(env, arg2, &s); } } break; case HOSTED_FSTAT: + GET_ARG(0); + GET_ARG(1); if (use_gdb_syscalls()) { gdb_do_syscall(m68k_semi_cb, "fstat,%x,%x", - ARG(0), ARG(1)); + arg0, arg1); return; } else { struct stat s; - result = fstat(ARG(0), &s); + result = fstat(arg0, &s); if (result == 0) { - translate_stat(env, ARG(1), &s); + translate_stat(env, arg1, &s); } } break; case HOSTED_GETTIMEOFDAY: + GET_ARG(0); + GET_ARG(1); if (use_gdb_syscalls()) { gdb_do_syscall(m68k_semi_cb, "gettimeofday,%x,%x", - ARG(0), ARG(1)); + arg0, arg1); return; } else { qemu_timeval tv; @@ -330,37 +384,41 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) result = qemu_gettimeofday(&tv); if (result != 0) { if (!(p = lock_user(VERIFY_WRITE, - ARG(0), sizeof(struct gdb_timeval), 0))) { + arg0, sizeof(struct gdb_timeval), 0))) { /* FIXME - check error code? */ result = -1; } else { p->tv_sec = cpu_to_be32(tv.tv_sec); p->tv_usec = cpu_to_be64(tv.tv_usec); - unlock_user(p, ARG(0), sizeof(struct gdb_timeval)); + unlock_user(p, arg0, sizeof(struct gdb_timeval)); } } } break; case HOSTED_ISATTY: + GET_ARG(0); if (use_gdb_syscalls()) { - gdb_do_syscall(m68k_semi_cb, "isatty,%x", ARG(0)); + gdb_do_syscall(m68k_semi_cb, "isatty,%x", arg0); return; } else { - result = isatty(ARG(0)); + result = isatty(arg0); } break; case HOSTED_SYSTEM: + GET_ARG(0); + GET_ARG(1); if (use_gdb_syscalls()) { gdb_do_syscall(m68k_semi_cb, "system,%s", - ARG(0), (int)ARG(1)); + arg0, (int)arg1); return; } else { - if (!(p = lock_user_string(ARG(0)))) { + p = lock_user_string(arg0); + if (!p) { /* FIXME - check error code? */ result = -1; } else { result = system(p); - unlock_user(p, ARG(0), 0); + unlock_user(p, arg0, 0); } } break; @@ -402,7 +460,6 @@ void do_m68k_semihosting(CPUM68KState *env, int nr) cpu_abort(env, "Unsupported semihosting syscall %d\n", nr); result = 0; } - /* FIXME - handle put_user() failure */ - put_user_u32(result, args); - put_user_u32(errno, args + 4); +failed: + m68k_semi_return_u32(env, result, errno); } diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c index 1971a57892..16df24c0ca 100644 --- a/target-m68k/op_helper.c +++ b/target-m68k/op_helper.c @@ -17,17 +17,16 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ #include "cpu.h" -#include "dyngen-exec.h" #include "helpers.h" #if defined(CONFIG_USER_ONLY) -void do_interrupt(CPUM68KState *env1) +void do_interrupt(CPUM68KState *env) { - env1->exception_index = -1; + env->exception_index = -1; } -void do_interrupt_m68k_hardirq(CPUM68KState *env1) +void do_interrupt_m68k_hardirq(CPUM68KState *env) { } @@ -35,66 +34,55 @@ void do_interrupt_m68k_hardirq(CPUM68KState *env1) extern int semihosting_enabled; -#include "softmmu_exec.h" +#include "exec/softmmu_exec.h" #define MMUSUFFIX _mmu #define SHIFT 0 -#include "softmmu_template.h" +#include "exec/softmmu_template.h" #define SHIFT 1 -#include "softmmu_template.h" +#include "exec/softmmu_template.h" #define SHIFT 2 -#include "softmmu_template.h" +#include "exec/softmmu_template.h" #define SHIFT 3 -#include "softmmu_template.h" +#include "exec/softmmu_template.h" /* Try to fill the TLB and return an exception if error. If retaddr is NULL, it means that the function was called in C code (i.e. not from generated code or from helper.c) */ -/* XXX: fix it to restore all registers */ -void tlb_fill(CPUM68KState *env1, target_ulong addr, int is_write, int mmu_idx, +void tlb_fill(CPUM68KState *env, target_ulong addr, int is_write, int mmu_idx, uintptr_t retaddr) { - TranslationBlock *tb; - CPUM68KState *saved_env; int ret; - saved_env = env; - env = env1; ret = cpu_m68k_handle_mmu_fault(env, addr, is_write, mmu_idx); if (unlikely(ret)) { if (retaddr) { /* now we have a real cpu fault */ - tb = tb_find_pc(retaddr); - if (tb) { - /* the PC is inside the translated code. It means that we have - a virtual CPU fault */ - cpu_restore_state(tb, env, retaddr); - } + cpu_restore_state(env, retaddr); } cpu_loop_exit(env); } - env = saved_env; } -static void do_rte(void) +static void do_rte(CPUM68KState *env) { uint32_t sp; uint32_t fmt; sp = env->aregs[7]; - fmt = ldl_kernel(sp); - env->pc = ldl_kernel(sp + 4); + fmt = cpu_ldl_kernel(env, sp); + env->pc = cpu_ldl_kernel(env, sp + 4); sp |= (fmt >> 28) & 3; env->sr = fmt & 0xffff; m68k_switch_sp(env); env->aregs[7] = sp + 8; } -static void do_interrupt_all(int is_hw) +static void do_interrupt_all(CPUM68KState *env, int is_hw) { uint32_t sp; uint32_t fmt; @@ -108,14 +96,14 @@ static void do_interrupt_all(int is_hw) switch (env->exception_index) { case EXCP_RTE: /* Return from an exception. */ - do_rte(); + do_rte(env); return; case EXCP_HALT_INSN: if (semihosting_enabled && (env->sr & SR_S) != 0 && (env->pc & 3) == 0 - && lduw_code(env->pc - 4) == 0x4e71 - && ldl_code(env->pc) == 0x4e7bf000) { + && cpu_lduw_code(env, env->pc - 4) == 0x4e71 + && cpu_ldl_code(env, env->pc) == 0x4e7bf000) { env->pc += 4; do_m68k_semihosting(env, env->dregs[0]); return; @@ -151,44 +139,34 @@ static void do_interrupt_all(int is_hw) /* ??? This could cause MMU faults. */ sp &= ~3; sp -= 4; - stl_kernel(sp, retaddr); + cpu_stl_kernel(env, sp, retaddr); sp -= 4; - stl_kernel(sp, fmt); + cpu_stl_kernel(env, sp, fmt); env->aregs[7] = sp; /* Jump to vector. */ - env->pc = ldl_kernel(env->vbr + vector); + env->pc = cpu_ldl_kernel(env, env->vbr + vector); } -void do_interrupt(CPUM68KState *env1) +void do_interrupt(CPUM68KState *env) { - CPUM68KState *saved_env; - - saved_env = env; - env = env1; - do_interrupt_all(0); - env = saved_env; + do_interrupt_all(env, 0); } -void do_interrupt_m68k_hardirq(CPUM68KState *env1) +void do_interrupt_m68k_hardirq(CPUM68KState *env) { - CPUM68KState *saved_env; - - saved_env = env; - env = env1; - do_interrupt_all(1); - env = saved_env; + do_interrupt_all(env, 1); } #endif -static void raise_exception(int tt) +static void raise_exception(CPUM68KState *env, int tt) { env->exception_index = tt; cpu_loop_exit(env); } -void HELPER(raise_exception)(uint32_t tt) +void HELPER(raise_exception)(CPUM68KState *env, uint32_t tt) { - raise_exception(tt); + raise_exception(env, tt); } void HELPER(divu)(CPUM68KState *env, uint32_t word) @@ -202,14 +180,12 @@ void HELPER(divu)(CPUM68KState *env, uint32_t word) num = env->div1; den = env->div2; /* ??? This needs to make sure the throwing location is accurate. */ - if (den == 0) - raise_exception(EXCP_DIV0); + if (den == 0) { + raise_exception(env, EXCP_DIV0); + } quot = num / den; rem = num % den; flags = 0; - /* Avoid using a PARAM1 of zero. This breaks dyngen because it uses - the address of a symbol, and gcc knows symbols can't have address - zero. */ if (word && quot > 0xffff) flags |= CCF_V; if (quot == 0) @@ -231,8 +207,9 @@ void HELPER(divs)(CPUM68KState *env, uint32_t word) num = env->div1; den = env->div2; - if (den == 0) - raise_exception(EXCP_DIV0); + if (den == 0) { + raise_exception(env, EXCP_DIV0); + } quot = num / den; rem = num % den; flags = 0; diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 9fc1e3102d..e763195f86 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -19,9 +19,9 @@ */ #include "cpu.h" -#include "disas.h" +#include "disas/disas.h" #include "tcg-op.h" -#include "qemu-log.h" +#include "qemu/log.h" #include "helpers.h" #define GEN_HELPER 1 @@ -61,7 +61,7 @@ static TCGv NULL_QREG; /* Used to distinguish stores from bad addressing modes. */ static TCGv store_dummy; -#include "gen-icount.h" +#include "exec/gen-icount.h" void m68k_tcg_init(void) { @@ -150,18 +150,24 @@ static void *gen_throws_exception; #define OS_SINGLE 4 #define OS_DOUBLE 5 -typedef void (*disas_proc)(DisasContext *, uint16_t); +typedef void (*disas_proc)(CPUM68KState *env, DisasContext *s, uint16_t insn); #ifdef DEBUG_DISPATCH -#define DISAS_INSN(name) \ - static void real_disas_##name (DisasContext *s, uint16_t insn); \ - static void disas_##name (DisasContext *s, uint16_t insn) { \ - qemu_log("Dispatch " #name "\n"); \ - real_disas_##name(s, insn); } \ - static void real_disas_##name (DisasContext *s, uint16_t insn) +#define DISAS_INSN(name) \ + static void real_disas_##name(CPUM68KState *env, DisasContext *s, \ + uint16_t insn); \ + static void disas_##name(CPUM68KState *env, DisasContext *s, \ + uint16_t insn) \ + { \ + qemu_log("Dispatch " #name "\n"); \ + real_disas_##name(s, env, insn); \ + } \ + static void real_disas_##name(CPUM68KState *env, DisasContext *s, \ + uint16_t insn) #else -#define DISAS_INSN(name) \ - static void disas_##name (DisasContext *s, uint16_t insn) +#define DISAS_INSN(name) \ + static void disas_##name(CPUM68KState *env, DisasContext *s, \ + uint16_t insn) #endif /* Generate a load from the specified address. Narrow values are @@ -257,12 +263,12 @@ static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val, } /* Read a 32-bit immediate constant. */ -static inline uint32_t read_im32(DisasContext *s) +static inline uint32_t read_im32(CPUM68KState *env, DisasContext *s) { uint32_t im; - im = ((uint32_t)lduw_code(s->pc)) << 16; + im = ((uint32_t)cpu_lduw_code(env, s->pc)) << 16; s->pc += 2; - im |= lduw_code(s->pc); + im |= cpu_lduw_code(env, s->pc); s->pc += 2; return im; } @@ -288,7 +294,8 @@ static TCGv gen_addr_index(uint16_t ext, TCGv tmp) /* Handle a base + index + displacement effective addresss. A NULL_QREG base means pc-relative. */ -static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base) +static TCGv gen_lea_indexed(CPUM68KState *env, DisasContext *s, int opsize, + TCGv base) { uint32_t offset; uint16_t ext; @@ -297,7 +304,7 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base) uint32_t bd, od; offset = s->pc; - ext = lduw_code(s->pc); + ext = cpu_lduw_code(env, s->pc); s->pc += 2; if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX)) @@ -311,10 +318,10 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base) if ((ext & 0x30) > 0x10) { /* base displacement */ if ((ext & 0x30) == 0x20) { - bd = (int16_t)lduw_code(s->pc); + bd = (int16_t)cpu_lduw_code(env, s->pc); s->pc += 2; } else { - bd = read_im32(s); + bd = read_im32(env, s); } } else { bd = 0; @@ -360,10 +367,10 @@ static TCGv gen_lea_indexed(DisasContext *s, int opsize, TCGv base) if ((ext & 3) > 1) { /* outer displacement */ if ((ext & 3) == 2) { - od = (int16_t)lduw_code(s->pc); + od = (int16_t)cpu_lduw_code(env, s->pc); s->pc += 2; } else { - od = read_im32(s); + od = read_im32(env, s); } } else { od = 0; @@ -492,7 +499,8 @@ static inline TCGv gen_extend(TCGv val, int opsize, int sign) /* Generate code for an "effective address". Does not adjust the base register for autoincrement addressing modes. */ -static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize) +static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn, + int opsize) { TCGv reg; TCGv tmp; @@ -514,29 +522,29 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize) case 5: /* Indirect displacement. */ reg = AREG(insn, 0); tmp = tcg_temp_new(); - ext = lduw_code(s->pc); + ext = cpu_lduw_code(env, s->pc); s->pc += 2; tcg_gen_addi_i32(tmp, reg, (int16_t)ext); return tmp; case 6: /* Indirect index + displacement. */ reg = AREG(insn, 0); - return gen_lea_indexed(s, opsize, reg); + return gen_lea_indexed(env, s, opsize, reg); case 7: /* Other */ switch (insn & 7) { case 0: /* Absolute short. */ - offset = ldsw_code(s->pc); + offset = cpu_ldsw_code(env, s->pc); s->pc += 2; return tcg_const_i32(offset); case 1: /* Absolute long. */ - offset = read_im32(s); + offset = read_im32(env, s); return tcg_const_i32(offset); case 2: /* pc displacement */ offset = s->pc; - offset += ldsw_code(s->pc); + offset += cpu_ldsw_code(env, s->pc); s->pc += 2; return tcg_const_i32(offset); case 3: /* pc index+displacement. */ - return gen_lea_indexed(s, opsize, NULL_QREG); + return gen_lea_indexed(env, s, opsize, NULL_QREG); case 4: /* Immediate. */ default: return NULL_QREG; @@ -548,15 +556,16 @@ static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize) /* Helper function for gen_ea. Reuse the computed address between the for read/write operands. */ -static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize, - TCGv val, TCGv *addrp, ea_what what) +static inline TCGv gen_ea_once(CPUM68KState *env, DisasContext *s, + uint16_t insn, int opsize, TCGv val, + TCGv *addrp, ea_what what) { TCGv tmp; if (addrp && what == EA_STORE) { tmp = *addrp; } else { - tmp = gen_lea(s, insn, opsize); + tmp = gen_lea(env, s, insn, opsize); if (IS_NULL_QREG(tmp)) return tmp; if (addrp) @@ -568,8 +577,8 @@ static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize, /* Generate code to load/store a value ito/from an EA. If VAL > 0 this is a write otherwise it is a read (0 == sign extend, -1 == zero extend). ADDRP is non-null for readwrite operands. */ -static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val, - TCGv *addrp, ea_what what) +static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn, + int opsize, TCGv val, TCGv *addrp, ea_what what) { TCGv reg; TCGv result; @@ -609,7 +618,7 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val, if (addrp && what == EA_STORE) { tmp = *addrp; } else { - tmp = gen_lea(s, insn, opsize); + tmp = gen_lea(env, s, insn, opsize); if (IS_NULL_QREG(tmp)) return tmp; if (addrp) @@ -626,33 +635,35 @@ static TCGv gen_ea(DisasContext *s, uint16_t insn, int opsize, TCGv val, return result; case 5: /* Indirect displacement. */ case 6: /* Indirect index + displacement. */ - return gen_ea_once(s, insn, opsize, val, addrp, what); + return gen_ea_once(env, s, insn, opsize, val, addrp, what); case 7: /* Other */ switch (insn & 7) { case 0: /* Absolute short. */ case 1: /* Absolute long. */ case 2: /* pc displacement */ case 3: /* pc index+displacement. */ - return gen_ea_once(s, insn, opsize, val, addrp, what); + return gen_ea_once(env, s, insn, opsize, val, addrp, what); case 4: /* Immediate. */ /* Sign extend values for consistency. */ switch (opsize) { case OS_BYTE: - if (what == EA_LOADS) - offset = ldsb_code(s->pc + 1); - else - offset = ldub_code(s->pc + 1); + if (what == EA_LOADS) { + offset = cpu_ldsb_code(env, s->pc + 1); + } else { + offset = cpu_ldub_code(env, s->pc + 1); + } s->pc += 2; break; case OS_WORD: - if (what == EA_LOADS) - offset = ldsw_code(s->pc); - else - offset = lduw_code(s->pc); + if (what == EA_LOADS) { + offset = cpu_ldsw_code(env, s->pc); + } else { + offset = cpu_lduw_code(env, s->pc); + } s->pc += 2; break; case OS_LONG: - offset = read_im32(s); + offset = read_im32(env, s); break; default: qemu_assert(0, "Bad immediate operand"); @@ -815,7 +826,7 @@ static void gen_exception(DisasContext *s, uint32_t where, int nr) { gen_flush_cc_op(s); gen_jmp_im(s, where); - gen_helper_raise_exception(tcg_const_i32(nr)); + gen_helper_raise_exception(cpu_env, tcg_const_i32(nr)); } static inline void gen_addr_fault(DisasContext *s) @@ -823,20 +834,21 @@ static inline void gen_addr_fault(DisasContext *s) gen_exception(s, s->insn_pc, EXCP_ADDRESS); } -#define SRC_EA(result, opsize, op_sign, addrp) do { \ - result = gen_ea(s, insn, opsize, NULL_QREG, addrp, op_sign ? EA_LOADS : EA_LOADU); \ - if (IS_NULL_QREG(result)) { \ - gen_addr_fault(s); \ - return; \ - } \ +#define SRC_EA(env, result, opsize, op_sign, addrp) do { \ + result = gen_ea(env, s, insn, opsize, NULL_QREG, addrp, \ + op_sign ? EA_LOADS : EA_LOADU); \ + if (IS_NULL_QREG(result)) { \ + gen_addr_fault(s); \ + return; \ + } \ } while (0) -#define DEST_EA(insn, opsize, val, addrp) do { \ - TCGv ea_result = gen_ea(s, insn, opsize, val, addrp, EA_STORE); \ - if (IS_NULL_QREG(ea_result)) { \ - gen_addr_fault(s); \ - return; \ - } \ +#define DEST_EA(env, insn, opsize, val, addrp) do { \ + TCGv ea_result = gen_ea(env, s, insn, opsize, val, addrp, EA_STORE); \ + if (IS_NULL_QREG(ea_result)) { \ + gen_addr_fault(s); \ + return; \ + } \ } while (0) /* Generate a jump to an immediate address. */ @@ -872,8 +884,7 @@ DISAS_INSN(undef_fpu) DISAS_INSN(undef) { gen_exception(s, s->pc - 2, EXCP_UNSUPPORTED); - cpu_abort(cpu_single_env, "Illegal instruction: %04x @ %08x", - insn, s->pc - 2); + cpu_abort(env, "Illegal instruction: %04x @ %08x", insn, s->pc - 2); } DISAS_INSN(mulw) @@ -890,7 +901,7 @@ DISAS_INSN(mulw) tcg_gen_ext16s_i32(tmp, reg); else tcg_gen_ext16u_i32(tmp, reg); - SRC_EA(src, OS_WORD, sign, NULL); + SRC_EA(env, src, OS_WORD, sign, NULL); tcg_gen_mul_i32(tmp, tmp, src); tcg_gen_mov_i32(reg, tmp); /* Unlike m68k, coldfire always clears the overflow bit. */ @@ -911,7 +922,7 @@ DISAS_INSN(divw) } else { tcg_gen_ext16u_i32(QREG_DIV1, reg); } - SRC_EA(src, OS_WORD, sign, NULL); + SRC_EA(env, src, OS_WORD, sign, NULL); tcg_gen_mov_i32(QREG_DIV2, src); if (sign) { gen_helper_divs(cpu_env, tcg_const_i32(1)); @@ -934,7 +945,7 @@ DISAS_INSN(divl) TCGv reg; uint16_t ext; - ext = lduw_code(s->pc); + ext = cpu_lduw_code(env, s->pc); s->pc += 2; if (ext & 0x87f8) { gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); @@ -943,7 +954,7 @@ DISAS_INSN(divl) num = DREG(ext, 12); reg = DREG(ext, 0); tcg_gen_mov_i32(QREG_DIV1, num); - SRC_EA(den, OS_LONG, 0, NULL); + SRC_EA(env, den, OS_LONG, 0, NULL); tcg_gen_mov_i32(QREG_DIV2, den); if (ext & 0x0800) { gen_helper_divs(cpu_env, tcg_const_i32(0)); @@ -973,11 +984,11 @@ DISAS_INSN(addsub) reg = DREG(insn, 9); dest = tcg_temp_new(); if (insn & 0x100) { - SRC_EA(tmp, OS_LONG, 0, &addr); + SRC_EA(env, tmp, OS_LONG, 0, &addr); src = reg; } else { tmp = reg; - SRC_EA(src, OS_LONG, 0, NULL); + SRC_EA(env, src, OS_LONG, 0, NULL); } if (add) { tcg_gen_add_i32(dest, tmp, src); @@ -990,7 +1001,7 @@ DISAS_INSN(addsub) } gen_update_cc_add(dest, src); if (insn & 0x100) { - DEST_EA(insn, OS_LONG, dest, &addr); + DEST_EA(env, insn, OS_LONG, dest, &addr); } else { tcg_gen_mov_i32(reg, dest); } @@ -1020,7 +1031,7 @@ DISAS_INSN(bitop_reg) else opsize = OS_LONG; op = (insn >> 6) & 3; - SRC_EA(src1, opsize, 0, op ? &addr: NULL); + SRC_EA(env, src1, opsize, 0, op ? &addr: NULL); src2 = DREG(insn, 9); dest = tcg_temp_new(); @@ -1055,7 +1066,7 @@ DISAS_INSN(bitop_reg) break; } if (op) - DEST_EA(insn, opsize, dest, &addr); + DEST_EA(env, insn, opsize, dest, &addr); } DISAS_INSN(sats) @@ -1086,9 +1097,9 @@ DISAS_INSN(movem) TCGv tmp; int is_load; - mask = lduw_code(s->pc); + mask = cpu_lduw_code(env, s->pc); s->pc += 2; - tmp = gen_lea(s, insn, OS_LONG); + tmp = gen_lea(env, s, insn, OS_LONG); if (IS_NULL_QREG(tmp)) { gen_addr_fault(s); return; @@ -1130,14 +1141,14 @@ DISAS_INSN(bitop_im) opsize = OS_LONG; op = (insn >> 6) & 3; - bitnum = lduw_code(s->pc); + bitnum = cpu_lduw_code(env, s->pc); s->pc += 2; if (bitnum & 0xff00) { - disas_undef(s, insn); + disas_undef(env, s, insn); return; } - SRC_EA(src1, opsize, 0, op ? &addr: NULL); + SRC_EA(env, src1, opsize, 0, op ? &addr: NULL); gen_flush_flags(s); if (opsize == OS_BYTE) @@ -1172,7 +1183,7 @@ DISAS_INSN(bitop_im) default: /* btst */ break; } - DEST_EA(insn, opsize, tmp, &addr); + DEST_EA(env, insn, opsize, tmp, &addr); } } @@ -1185,8 +1196,8 @@ DISAS_INSN(arith_im) TCGv addr; op = (insn >> 9) & 7; - SRC_EA(src1, OS_LONG, 0, (op == 6) ? NULL : &addr); - im = read_im32(s); + SRC_EA(env, src1, OS_LONG, 0, (op == 6) ? NULL : &addr); + im = read_im32(env, s); dest = tcg_temp_new(); switch (op) { case 0: /* ori */ @@ -1225,7 +1236,7 @@ DISAS_INSN(arith_im) abort(); } if (op != 6) { - DEST_EA(insn, OS_LONG, dest, &addr); + DEST_EA(env, insn, OS_LONG, dest, &addr); } } @@ -1257,7 +1268,7 @@ DISAS_INSN(move) default: abort(); } - SRC_EA(src, opsize, 1, NULL); + SRC_EA(env, src, opsize, 1, NULL); op = (insn >> 6) & 7; if (op == 1) { /* movea */ @@ -1268,7 +1279,7 @@ DISAS_INSN(move) /* normal move */ uint16_t dest_ea; dest_ea = ((insn >> 9) & 7) | (op << 3); - DEST_EA(dest_ea, opsize, src, NULL); + DEST_EA(env, dest_ea, opsize, src, NULL); /* This will be correct because loads sign extend. */ gen_logic_cc(s, src); } @@ -1289,7 +1300,7 @@ DISAS_INSN(lea) TCGv tmp; reg = AREG(insn, 9); - tmp = gen_lea(s, insn, OS_LONG); + tmp = gen_lea(env, s, insn, OS_LONG); if (IS_NULL_QREG(tmp)) { gen_addr_fault(s); return; @@ -1314,7 +1325,7 @@ DISAS_INSN(clr) default: abort(); } - DEST_EA(insn, opsize, tcg_const_i32(0), NULL); + DEST_EA(env, insn, opsize, tcg_const_i32(0), NULL); gen_logic_cc(s, tcg_const_i32(0)); } @@ -1363,7 +1374,8 @@ static void gen_set_sr_im(DisasContext *s, uint16_t val, int ccr_only) } } -static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only) +static void gen_set_sr(CPUM68KState *env, DisasContext *s, uint16_t insn, + int ccr_only) { TCGv tmp; TCGv reg; @@ -1383,17 +1395,17 @@ static void gen_set_sr(DisasContext *s, uint16_t insn, int ccr_only) else if ((insn & 0x3f) == 0x3c) { uint16_t val; - val = lduw_code(s->pc); + val = cpu_lduw_code(env, s->pc); s->pc += 2; gen_set_sr_im(s, val, ccr_only); } else - disas_undef(s, insn); + disas_undef(env, s, insn); } DISAS_INSN(move_to_ccr) { - gen_set_sr(s, insn, 1); + gen_set_sr(env, s, insn, 1); } DISAS_INSN(not) @@ -1424,7 +1436,7 @@ DISAS_INSN(pea) { TCGv tmp; - tmp = gen_lea(s, insn, OS_LONG); + tmp = gen_lea(env, s, insn, OS_LONG); if (IS_NULL_QREG(tmp)) { gen_addr_fault(s); return; @@ -1470,7 +1482,7 @@ DISAS_INSN(tst) default: abort(); } - SRC_EA(tmp, opsize, 1, NULL); + SRC_EA(env, tmp, opsize, 1, NULL); gen_logic_cc(s, tmp); } @@ -1492,10 +1504,10 @@ DISAS_INSN(tas) TCGv addr; dest = tcg_temp_new(); - SRC_EA(src1, OS_BYTE, 1, &addr); + SRC_EA(env, src1, OS_BYTE, 1, &addr); gen_logic_cc(s, src1); tcg_gen_ori_i32(dest, src1, 0x80); - DEST_EA(insn, OS_BYTE, dest, &addr); + DEST_EA(env, insn, OS_BYTE, dest, &addr); } DISAS_INSN(mull) @@ -1507,14 +1519,14 @@ DISAS_INSN(mull) /* The upper 32 bits of the product are discarded, so muls.l and mulu.l are functionally equivalent. */ - ext = lduw_code(s->pc); + ext = cpu_lduw_code(env, s->pc); s->pc += 2; if (ext & 0x87ff) { gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); return; } reg = DREG(ext, 12); - SRC_EA(src1, OS_LONG, 0, NULL); + SRC_EA(env, src1, OS_LONG, 0, NULL); dest = tcg_temp_new(); tcg_gen_mul_i32(dest, src1, reg); tcg_gen_mov_i32(reg, dest); @@ -1528,7 +1540,7 @@ DISAS_INSN(link) TCGv reg; TCGv tmp; - offset = ldsw_code(s->pc); + offset = cpu_ldsw_code(env, s->pc); s->pc += 2; reg = AREG(insn, 0); tmp = tcg_temp_new(); @@ -1572,7 +1584,7 @@ DISAS_INSN(jump) /* Load the target address first to ensure correct exception behavior. */ - tmp = gen_lea(s, insn, OS_LONG); + tmp = gen_lea(env, s, insn, OS_LONG); if (IS_NULL_QREG(tmp)) { gen_addr_fault(s); return; @@ -1592,7 +1604,7 @@ DISAS_INSN(addsubq) int val; TCGv addr; - SRC_EA(src1, OS_LONG, 0, &addr); + SRC_EA(env, src1, OS_LONG, 0, &addr); val = (insn >> 9) & 7; if (val == 0) val = 8; @@ -1619,7 +1631,7 @@ DISAS_INSN(addsubq) } gen_update_cc_add(dest, src2); } - DEST_EA(insn, OS_LONG, dest, &addr); + DEST_EA(env, insn, OS_LONG, dest, &addr); } DISAS_INSN(tpf) @@ -1634,7 +1646,7 @@ DISAS_INSN(tpf) case 4: /* No extension words. */ break; default: - disas_undef(s, insn); + disas_undef(env, s, insn); } } @@ -1649,10 +1661,10 @@ DISAS_INSN(branch) op = (insn >> 8) & 0xf; offset = (int8_t)insn; if (offset == 0) { - offset = ldsw_code(s->pc); + offset = cpu_ldsw_code(env, s->pc); s->pc += 2; } else if (offset == -1) { - offset = read_im32(s); + offset = read_im32(env, s); } if (op == 1) { /* bsr */ @@ -1691,7 +1703,7 @@ DISAS_INSN(mvzs) opsize = OS_WORD; else opsize = OS_BYTE; - SRC_EA(src, opsize, (insn & 0x80) == 0, NULL); + SRC_EA(env, src, opsize, (insn & 0x80) == 0, NULL); reg = DREG(insn, 9); tcg_gen_mov_i32(reg, src); gen_logic_cc(s, src); @@ -1707,11 +1719,11 @@ DISAS_INSN(or) reg = DREG(insn, 9); dest = tcg_temp_new(); if (insn & 0x100) { - SRC_EA(src, OS_LONG, 0, &addr); + SRC_EA(env, src, OS_LONG, 0, &addr); tcg_gen_or_i32(dest, src, reg); - DEST_EA(insn, OS_LONG, dest, &addr); + DEST_EA(env, insn, OS_LONG, dest, &addr); } else { - SRC_EA(src, OS_LONG, 0, NULL); + SRC_EA(env, src, OS_LONG, 0, NULL); tcg_gen_or_i32(dest, src, reg); tcg_gen_mov_i32(reg, dest); } @@ -1723,7 +1735,7 @@ DISAS_INSN(suba) TCGv src; TCGv reg; - SRC_EA(src, OS_LONG, 0, NULL); + SRC_EA(env, src, OS_LONG, 0, NULL); reg = AREG(insn, 9); tcg_gen_sub_i32(reg, reg, src); } @@ -1749,7 +1761,7 @@ DISAS_INSN(mov3q) val = -1; src = tcg_const_i32(val); gen_logic_cc(s, src); - DEST_EA(insn, OS_LONG, src, NULL); + DEST_EA(env, insn, OS_LONG, src, NULL); } DISAS_INSN(cmp) @@ -1777,7 +1789,7 @@ DISAS_INSN(cmp) default: abort(); } - SRC_EA(src, opsize, 1, NULL); + SRC_EA(env, src, opsize, 1, NULL); reg = DREG(insn, 9); dest = tcg_temp_new(); tcg_gen_sub_i32(dest, reg, src); @@ -1796,7 +1808,7 @@ DISAS_INSN(cmpa) } else { opsize = OS_WORD; } - SRC_EA(src, opsize, 1, NULL); + SRC_EA(env, src, opsize, 1, NULL); reg = AREG(insn, 9); dest = tcg_temp_new(); tcg_gen_sub_i32(dest, reg, src); @@ -1811,12 +1823,12 @@ DISAS_INSN(eor) TCGv dest; TCGv addr; - SRC_EA(src, OS_LONG, 0, &addr); + SRC_EA(env, src, OS_LONG, 0, &addr); reg = DREG(insn, 9); dest = tcg_temp_new(); tcg_gen_xor_i32(dest, src, reg); gen_logic_cc(s, dest); - DEST_EA(insn, OS_LONG, dest, &addr); + DEST_EA(env, insn, OS_LONG, dest, &addr); } DISAS_INSN(and) @@ -1829,11 +1841,11 @@ DISAS_INSN(and) reg = DREG(insn, 9); dest = tcg_temp_new(); if (insn & 0x100) { - SRC_EA(src, OS_LONG, 0, &addr); + SRC_EA(env, src, OS_LONG, 0, &addr); tcg_gen_and_i32(dest, src, reg); - DEST_EA(insn, OS_LONG, dest, &addr); + DEST_EA(env, insn, OS_LONG, dest, &addr); } else { - SRC_EA(src, OS_LONG, 0, NULL); + SRC_EA(env, src, OS_LONG, 0, NULL); tcg_gen_and_i32(dest, src, reg); tcg_gen_mov_i32(reg, dest); } @@ -1845,7 +1857,7 @@ DISAS_INSN(adda) TCGv src; TCGv reg; - SRC_EA(src, OS_LONG, 0, NULL); + SRC_EA(env, src, OS_LONG, 0, NULL); reg = AREG(insn, 9); tcg_gen_add_i32(reg, reg, src); } @@ -1934,13 +1946,13 @@ DISAS_INSN(strldsr) uint32_t addr; addr = s->pc - 2; - ext = lduw_code(s->pc); + ext = cpu_lduw_code(env, s->pc); s->pc += 2; if (ext != 0x46FC) { gen_exception(s, addr, EXCP_UNSUPPORTED); return; } - ext = lduw_code(s->pc); + ext = cpu_lduw_code(env, s->pc); s->pc += 2; if (IS_USER(s) || (ext & SR_S) == 0) { gen_exception(s, addr, EXCP_PRIVILEGE); @@ -1970,7 +1982,7 @@ DISAS_INSN(move_to_sr) gen_exception(s, s->pc - 2, EXCP_PRIVILEGE); return; } - gen_set_sr(s, insn, 0); + gen_set_sr(env, s, insn, 0); gen_lookup_tb(s); } @@ -2008,7 +2020,7 @@ DISAS_INSN(stop) return; } - ext = lduw_code(s->pc); + ext = cpu_lduw_code(env, s->pc); s->pc += 2; gen_set_sr_im(s, ext, 0); @@ -2035,7 +2047,7 @@ DISAS_INSN(movec) return; } - ext = lduw_code(s->pc); + ext = cpu_lduw_code(env, s->pc); s->pc += 2; if (ext & 0x8000) { @@ -2100,7 +2112,7 @@ DISAS_INSN(fpu) int set_dest; int opsize; - ext = lduw_code(s->pc); + ext = cpu_lduw_code(env, s->pc); s->pc += 2; opmode = ext & 0x7f; switch ((ext >> 13) & 7) { @@ -2136,7 +2148,7 @@ DISAS_INSN(fpu) tcg_gen_addi_i32(tmp32, tmp32, -8); break; case 5: - offset = ldsw_code(s->pc); + offset = cpu_ldsw_code(env, s->pc); s->pc += 2; tcg_gen_addi_i32(tmp32, tmp32, offset); break; @@ -2162,7 +2174,7 @@ DISAS_INSN(fpu) default: goto undef; } - DEST_EA(insn, opsize, tmp32, NULL); + DEST_EA(env, insn, opsize, tmp32, NULL); tcg_temp_free_i32(tmp32); return; case 4: /* fmove to control register. */ @@ -2190,7 +2202,7 @@ DISAS_INSN(fpu) (ext >> 10) & 7); goto undef; } - DEST_EA(insn, OS_LONG, tmp32, NULL); + DEST_EA(env, insn, OS_LONG, tmp32, NULL); break; case 6: /* fmovem */ case 7: @@ -2200,7 +2212,7 @@ DISAS_INSN(fpu) int i; if ((ext & 0x1f00) != 0x1000 || (ext & 0xff) == 0) goto undef; - tmp32 = gen_lea(s, insn, OS_LONG); + tmp32 = gen_lea(env, s, insn, OS_LONG); if (IS_NULL_QREG(tmp32)) { gen_addr_fault(s); return; @@ -2250,12 +2262,12 @@ DISAS_INSN(fpu) tcg_gen_addi_i32(tmp32, tmp32, -8); break; case 5: - offset = ldsw_code(s->pc); + offset = cpu_ldsw_code(env, s->pc); s->pc += 2; tcg_gen_addi_i32(tmp32, tmp32, offset); break; case 7: - offset = ldsw_code(s->pc); + offset = cpu_ldsw_code(env, s->pc); offset += s->pc - 2; s->pc += 2; tcg_gen_addi_i32(tmp32, tmp32, offset); @@ -2275,7 +2287,7 @@ DISAS_INSN(fpu) } tcg_temp_free_i32(tmp32); } else { - SRC_EA(tmp32, opsize, 1, NULL); + SRC_EA(env, tmp32, opsize, 1, NULL); src = tcg_temp_new_i64(); switch (opsize) { case OS_LONG: @@ -2370,7 +2382,7 @@ DISAS_INSN(fpu) undef: /* FIXME: Is this right for offset addressing modes? */ s->pc -= 2; - disas_undef_fpu(s, insn); + disas_undef_fpu(env, s, insn); } DISAS_INSN(fbcc) @@ -2381,10 +2393,10 @@ DISAS_INSN(fbcc) int l1; addr = s->pc; - offset = ldsw_code(s->pc); + offset = cpu_ldsw_code(env, s->pc); s->pc += 2; if (insn & (1 << 6)) { - offset = (offset << 16) | lduw_code(s->pc); + offset = (offset << 16) | cpu_lduw_code(env, s->pc); s->pc += 2; } @@ -2506,18 +2518,18 @@ DISAS_INSN(mac) s->done_mac = 1; } - ext = lduw_code(s->pc); + ext = cpu_lduw_code(env, s->pc); s->pc += 2; acc = ((insn >> 7) & 1) | ((ext >> 3) & 2); dual = ((insn & 0x30) != 0 && (ext & 3) != 0); if (dual && !m68k_feature(s->env, M68K_FEATURE_CF_EMAC_B)) { - disas_undef(s, insn); + disas_undef(env, s, insn); return; } if (insn & 0x30) { /* MAC with load. */ - tmp = gen_lea(s, insn, OS_LONG); + tmp = gen_lea(env, s, insn, OS_LONG); addr = tcg_temp_new(); tcg_gen_and_i32(addr, tmp, QREG_MAC_MASK); /* Load the value now to ensure correct exception behavior. @@ -2731,7 +2743,7 @@ DISAS_INSN(to_mac) int accnum; accnum = (insn >> 9) & 3; acc = MACREG(accnum); - SRC_EA(val, OS_LONG, 0, NULL); + SRC_EA(env, val, OS_LONG, 0, NULL); if (s->env->macsr & MACSR_FI) { tcg_gen_ext_i32_i64(acc, val); tcg_gen_shli_i64(acc, acc, 8); @@ -2748,7 +2760,7 @@ DISAS_INSN(to_mac) DISAS_INSN(to_macsr) { TCGv val; - SRC_EA(val, OS_LONG, 0, NULL); + SRC_EA(env, val, OS_LONG, 0, NULL); gen_helper_set_macsr(cpu_env, val); gen_lookup_tb(s); } @@ -2756,7 +2768,7 @@ DISAS_INSN(to_macsr) DISAS_INSN(to_mask) { TCGv val; - SRC_EA(val, OS_LONG, 0, NULL); + SRC_EA(env, val, OS_LONG, 0, NULL); tcg_gen_ori_i32(QREG_MAC_MASK, val, 0xffff0000); } @@ -2764,7 +2776,7 @@ DISAS_INSN(to_mext) { TCGv val; TCGv acc; - SRC_EA(val, OS_LONG, 0, NULL); + SRC_EA(env, val, OS_LONG, 0, NULL); acc = tcg_const_i32((insn & 0x400) ? 2 : 0); if (s->env->macsr & MACSR_FI) gen_helper_set_mac_extf(cpu_env, val, acc); @@ -2941,10 +2953,14 @@ static void disas_m68k_insn(CPUM68KState * env, DisasContext *s) { uint16_t insn; - insn = lduw_code(s->pc); + if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) { + tcg_gen_debug_insn_start(s->pc); + } + + insn = cpu_lduw_code(env, s->pc); s->pc += 2; - opcode_table[insn](s, insn); + opcode_table[insn](env, s, insn); } /* generate intermediate code for basic block 'tb'. */ @@ -2966,7 +2982,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb, dc->tb = tb; - gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; + gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; dc->env = env; dc->is_jmp = DISAS_NEXT; @@ -2999,22 +3015,22 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb, break; } if (search_pc) { - j = gen_opc_ptr - gen_opc_buf; + j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; if (lj < j) { lj++; while (lj < j) - gen_opc_instr_start[lj++] = 0; + tcg_ctx.gen_opc_instr_start[lj++] = 0; } - gen_opc_pc[lj] = dc->pc; - gen_opc_instr_start[lj] = 1; - gen_opc_icount[lj] = num_insns; + tcg_ctx.gen_opc_pc[lj] = dc->pc; + tcg_ctx.gen_opc_instr_start[lj] = 1; + tcg_ctx.gen_opc_icount[lj] = num_insns; } if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) gen_io_start(); dc->insn_pc = dc->pc; disas_m68k_insn(env, dc); num_insns++; - } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && + } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && !env->singlestep_enabled && !singlestep && (pc_offset) < (TARGET_PAGE_SIZE - 32) && @@ -3028,7 +3044,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb, gen_flush_cc_op(dc); tcg_gen_movi_i32(QREG_PC, dc->pc); } - gen_helper_raise_exception(tcg_const_i32(EXCP_DEBUG)); + gen_helper_raise_exception(cpu_env, tcg_const_i32(EXCP_DEBUG)); } else { switch(dc->is_jmp) { case DISAS_NEXT: @@ -3048,21 +3064,21 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb, } } gen_icount_end(tb, num_insns); - *gen_opc_ptr = INDEX_op_end; + *tcg_ctx.gen_opc_ptr = INDEX_op_end; #ifdef DEBUG_DISAS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { qemu_log("----------------\n"); qemu_log("IN: %s\n", lookup_symbol(pc_start)); - log_target_disas(pc_start, dc->pc - pc_start, 0); + log_target_disas(env, pc_start, dc->pc - pc_start, 0); qemu_log("\n"); } #endif if (search_pc) { - j = gen_opc_ptr - gen_opc_buf; + j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf; lj++; while (lj <= j) - gen_opc_instr_start[lj++] = 0; + tcg_ctx.gen_opc_instr_start[lj++] = 0; } else { tb->size = dc->pc - pc_start; tb->icount = num_insns; @@ -3105,5 +3121,5 @@ void cpu_dump_state(CPUM68KState *env, FILE *f, fprintf_function cpu_fprintf, void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb, int pc_pos) { - env->pc = gen_opc_pc[pc_pos]; + env->pc = tcg_ctx.gen_opc_pc[pc_pos]; } |