X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=target-m68k%2Ftranslate.c;h=0be0a96732c313b8183a4709d4db42b538f76d37;hb=8cfd04959a023f87e1e6727e608a20f168441370;hp=9fc1e3102d9157e08c74619071c8f9e8a8ca4098;hpb=33cf629a3754b58a1e2dbbe01d91d97e712b7c06;p=qemu.git diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 9fc1e3102..0be0a9673 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 @@ -42,6 +42,8 @@ #undef DEFO64 #undef DEFF64 +static TCGv_i32 cpu_halted; + static TCGv_ptr cpu_env; static char cpu_reg_names[3*8*3 + 5*4]; @@ -61,7 +63,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) { @@ -76,6 +78,10 @@ void m68k_tcg_init(void) #undef DEFO64 #undef DEFF64 + cpu_halted = tcg_global_mem_new_i32(TCG_AREG0, + -offsetof(M68kCPU, env) + + offsetof(CPUState, halted), "HALTED"); + cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); p = cpu_reg_names; @@ -150,18 +156,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 +269,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 +300,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 +310,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 +324,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 +373,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 +505,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 +528,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 +562,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) @@ -565,11 +580,11 @@ static inline TCGv gen_ea_once(DisasContext *s, uint16_t insn, int opsize, return gen_ldst(s, opsize, tmp, val, what); } -/* Generate code to load/store a value ito/from an EA. If VAL > 0 this is +/* Generate code to load/store a value from/into 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 +624,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 +641,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 +832,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 +840,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. */ @@ -851,7 +869,7 @@ static void gen_jmp_tb(DisasContext *s, int n, uint32_t dest) (s->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); tcg_gen_movi_i32(QREG_PC, dest); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { gen_jmp_im(s, dest); tcg_gen_exit_tb(0); @@ -872,8 +890,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 +907,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 +928,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 +951,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 +960,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 +990,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 +1007,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 +1037,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 +1072,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 +1103,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 +1147,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 +1189,7 @@ DISAS_INSN(bitop_im) default: /* btst */ break; } - DEST_EA(insn, opsize, tmp, &addr); + DEST_EA(env, insn, opsize, tmp, &addr); } } @@ -1185,8 +1202,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 +1242,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 +1274,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 +1285,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 +1306,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 +1331,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 +1380,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 +1401,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 +1442,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 +1488,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 +1510,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 +1525,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 +1546,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 +1590,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 +1610,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 +1637,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 +1652,7 @@ DISAS_INSN(tpf) case 4: /* No extension words. */ break; default: - disas_undef(s, insn); + disas_undef(env, s, insn); } } @@ -1649,10 +1667,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 +1709,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 +1725,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 +1741,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 +1767,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 +1795,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 +1814,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 +1829,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 +1847,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 +1863,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 +1952,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 +1988,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,11 +2026,11 @@ 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); - tcg_gen_movi_i32(QREG_HALTED, 1); + tcg_gen_movi_i32(cpu_halted, 1); gen_exception(s, s->pc, EXCP_HLT); } @@ -2035,7 +2053,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 +2118,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 +2154,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 +2180,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 +2208,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 +2218,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 +2268,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 +2293,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 +2388,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 +2399,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 +2524,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 +2749,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 +2766,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 +2774,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 +2782,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,17 +2959,23 @@ 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'. */ static inline void -gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb, - int search_pc) +gen_intermediate_code_internal(M68kCPU *cpu, TranslationBlock *tb, + bool search_pc) { + CPUState *cs = CPU(cpu); + CPUM68KState *env = &cpu->env; DisasContext dc1, *dc = &dc1; uint16_t *gen_opc_end; CPUBreakpoint *bp; @@ -2966,13 +2990,13 @@ 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; dc->pc = pc_start; dc->cc_op = CC_OP_DYNAMIC; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->fpcr = env->fpcr; dc->user = (env->sr & SR_S) == 0; dc->is_mem = 0; @@ -2983,7 +3007,7 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb, if (max_insns == 0) max_insns = CF_COUNT_MASK; - gen_icount_start(); + gen_tb_start(); do { pc_offset = dc->pc - pc_start; gen_throws_exception = NULL; @@ -2999,36 +3023,36 @@ 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 && - !env->singlestep_enabled && + } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end && + !cs->singlestep_enabled && !singlestep && (pc_offset) < (TARGET_PAGE_SIZE - 32) && num_insns < max_insns); if (tb->cflags & CF_LAST_IO) gen_io_end(); - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { /* Make sure the pc is updated, and raise a debug exception. */ if (!dc->is_jmp) { 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: @@ -3047,22 +3071,22 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb, break; } } - gen_icount_end(tb, num_insns); - *gen_opc_ptr = INDEX_op_end; + gen_tb_end(tb, num_insns); + *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; @@ -3074,17 +3098,19 @@ gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb, void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb) { - gen_intermediate_code_internal(env, tb, 0); + gen_intermediate_code_internal(m68k_env_get_cpu(env), tb, false); } void gen_intermediate_code_pc(CPUM68KState *env, TranslationBlock *tb) { - gen_intermediate_code_internal(env, tb, 1); + gen_intermediate_code_internal(m68k_env_get_cpu(env), tb, true); } -void cpu_dump_state(CPUM68KState *env, FILE *f, fprintf_function cpu_fprintf, - int flags) +void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, + int flags) { + M68kCPU *cpu = M68K_CPU(cs); + CPUM68KState *env = &cpu->env; int i; uint16_t sr; CPU_DoubleU u; @@ -3105,5 +3131,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]; }