* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <assert.h>
-
-#include "config.h"
+
#include "cpu.h"
-#include "exec-all.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
/* 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)
{
char *p;
int i;
-#define DEFO32(name, offset) QREG_##name = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUState, offset), #name);
-#define DEFO64(name, offset) QREG_##name = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, offset), #name);
+#define DEFO32(name, offset) QREG_##name = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUM68KState, offset), #name);
+#define DEFO64(name, offset) QREG_##name = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUM68KState, offset), #name);
#define DEFF64(name, offset) DEFO64(name, offset)
#include "qregs.def"
#undef DEFO32
#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) { \
- if (logfile) fprintf(logfile, "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
-/* FIXME: Remove this. */
-#define gen_im32(val) tcg_const_i32(val)
-
/* Generate a load from the specified address. Narrow values are
sign extended to full register width. */
static inline TCGv gen_load(DisasContext * s, int opsize, TCGv addr, int sign)
}
/* 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;
}
/* 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;
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))
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;
if ((ext & 0x80) == 0) {
/* base not suppressed */
if (IS_NULL_QREG(base)) {
- base = gen_im32(offset + bd);
+ base = tcg_const_i32(offset + bd);
bd = 0;
}
if (!IS_NULL_QREG(add)) {
add = tmp;
}
} else {
- add = gen_im32(bd);
+ add = tcg_const_i32(bd);
}
if ((ext & 3) != 0) {
/* memory indirect */
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;
}
/* Generate code for an "effective address". Does not adjust the base
- register for autoincrememnt addressing modes. */
-static TCGv gen_lea(DisasContext *s, uint16_t insn, int opsize)
+ register for autoincrement addressing modes. */
+static TCGv gen_lea(CPUM68KState *env, DisasContext *s, uint16_t insn,
+ int opsize)
{
TCGv reg;
TCGv tmp;
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 gen_im32(offset);
+ return tcg_const_i32(offset);
case 1: /* Absolute long. */
- offset = read_im32(s);
- return gen_im32(offset);
+ offset = read_im32(env, s);
+ return tcg_const_i32(offset);
case 2: /* pc displacement */
- tmp = tcg_temp_new();
offset = s->pc;
- offset += ldsw_code(s->pc);
+ offset += cpu_ldsw_code(env, s->pc);
s->pc += 2;
- return gen_im32(offset);
+ 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;
/* 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)
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;
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)
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");
{
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)
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. */
(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((long)tb + n);
+ tcg_gen_exit_tb((tcg_target_long)tb + n);
} else {
gen_jmp_im(s, dest);
tcg_gen_exit_tb(0);
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)
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. */
} 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));
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);
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));
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);
}
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);
}
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();
break;
}
if (op)
- DEST_EA(insn, opsize, dest, &addr);
+ DEST_EA(env, insn, opsize, dest, &addr);
}
DISAS_INSN(sats)
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;
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)
default: /* btst */
break;
}
- DEST_EA(insn, opsize, tmp, &addr);
+ DEST_EA(env, insn, opsize, tmp, &addr);
}
}
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 */
break;
case 2: /* subi */
tcg_gen_mov_i32(dest, src1);
- gen_helper_xflag_lt(QREG_CC_X, dest, gen_im32(im));
+ gen_helper_xflag_lt(QREG_CC_X, dest, tcg_const_i32(im));
tcg_gen_subi_i32(dest, dest, im);
- gen_update_cc_add(dest, gen_im32(im));
+ gen_update_cc_add(dest, tcg_const_i32(im));
s->cc_op = CC_OP_SUB;
break;
case 3: /* addi */
tcg_gen_mov_i32(dest, src1);
tcg_gen_addi_i32(dest, dest, im);
- gen_update_cc_add(dest, gen_im32(im));
- gen_helper_xflag_lt(QREG_CC_X, dest, gen_im32(im));
+ gen_update_cc_add(dest, tcg_const_i32(im));
+ gen_helper_xflag_lt(QREG_CC_X, dest, tcg_const_i32(im));
s->cc_op = CC_OP_ADD;
break;
case 5: /* eori */
case 6: /* cmpi */
tcg_gen_mov_i32(dest, src1);
tcg_gen_subi_i32(dest, dest, im);
- gen_update_cc_add(dest, gen_im32(im));
+ gen_update_cc_add(dest, tcg_const_i32(im));
s->cc_op = CC_OP_SUB;
break;
default:
abort();
}
if (op != 6) {
- DEST_EA(insn, OS_LONG, dest, &addr);
+ DEST_EA(env, insn, OS_LONG, dest, &addr);
}
}
TCGv reg;
reg = DREG(insn, 0);
- tcg_gen_bswap_i32(reg, reg);
+ tcg_gen_bswap32_i32(reg, reg);
}
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 */
/* 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);
}
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;
default:
abort();
}
- DEST_EA(insn, opsize, gen_im32(0), NULL);
- gen_logic_cc(s, gen_im32(0));
+ DEST_EA(env, insn, opsize, tcg_const_i32(0), NULL);
+ gen_logic_cc(s, tcg_const_i32(0));
}
static TCGv gen_get_ccr(DisasContext *s)
}
}
-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;
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)
{
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;
default:
abort();
}
- SRC_EA(tmp, opsize, 1, NULL);
+ SRC_EA(env, tmp, opsize, 1, NULL);
gen_logic_cc(s, tmp);
}
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)
/* 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);
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();
/* 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;
}
if ((insn & 0x40) == 0) {
/* jsr */
- gen_push(s, gen_im32(s->pc));
+ gen_push(s, tcg_const_i32(s->pc));
}
gen_jmp(s, tmp);
}
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;
tcg_gen_addi_i32(dest, dest, val);
}
} else {
- src2 = gen_im32(val);
+ src2 = tcg_const_i32(val);
if (insn & 0x0100) {
gen_helper_xflag_lt(QREG_CC_X, dest, src2);
tcg_gen_subi_i32(dest, dest, val);
}
gen_update_cc_add(dest, src2);
}
- DEST_EA(insn, OS_LONG, dest, &addr);
+ DEST_EA(env, insn, OS_LONG, dest, &addr);
}
DISAS_INSN(tpf)
case 4: /* No extension words. */
break;
default:
- disas_undef(s, insn);
+ disas_undef(env, s, insn);
}
}
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 */
- gen_push(s, gen_im32(s->pc));
+ gen_push(s, tcg_const_i32(s->pc));
}
gen_flush_cc_op(s);
if (op > 1) {
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);
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);
}
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);
}
val = (insn >> 9) & 7;
if (val == 0)
val = -1;
- src = gen_im32(val);
+ 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)
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);
} 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);
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)
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);
}
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);
}
tmp = (insn >> 9) & 7;
if (tmp == 0)
tmp = 8;
- shift = gen_im32(tmp);
+ shift = tcg_const_i32(tmp);
/* No need to flush flags becuse we know we will set C flag. */
if (insn & 0x100) {
gen_helper_shl_cc(reg, cpu_env, reg, shift);
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);
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);
}
return;
}
- ext = lduw_code(s->pc);
+ ext = cpu_lduw_code(env, s->pc);
s->pc += 2;
gen_set_sr_im(s, ext, 0);
return;
}
- ext = lduw_code(s->pc);
+ ext = cpu_lduw_code(env, s->pc);
s->pc += 2;
if (ext & 0x8000) {
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) {
break;
case 5: /* OS_DOUBLE */
tcg_gen_mov_i32(tmp32, AREG(insn, 0));
- switch (insn >> 3) {
+ switch ((insn >> 3) & 7) {
case 2:
case 3:
+ break;
case 4:
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;
goto undef;
}
gen_store64(s, tmp32, src);
- switch (insn >> 3) {
+ switch ((insn >> 3) & 7) {
case 3:
tcg_gen_addi_i32(tmp32, tmp32, 8);
tcg_gen_mov_i32(AREG(insn, 0), tmp32);
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. */
switch ((ext >> 10) & 7) {
case 4: /* FPCR */
/* Not implemented. Always return zero. */
- tmp32 = gen_im32(0);
+ tmp32 = tcg_const_i32(0);
break;
case 1: /* FPIAR */
case 2: /* FPSR */
(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:
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;
}
mask >>= 1;
}
- tcg_temp_free_i32(tmp32);
+ tcg_temp_free_i32(addr);
}
return;
}
if (opsize == OS_DOUBLE) {
tmp32 = tcg_temp_new_i32();
tcg_gen_mov_i32(tmp32, AREG(insn, 0));
- switch (insn >> 3) {
+ switch ((insn >> 3) & 7) {
case 2:
case 3:
+ break;
case 4:
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);
goto undef;
}
src = gen_load64(s, tmp32);
- switch (insn >> 3) {
+ switch ((insn >> 3) & 7) {
case 3:
tcg_gen_addi_i32(tmp32, tmp32, 8);
tcg_gen_mov_i32(AREG(insn, 0), tmp32);
}
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:
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)
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;
}
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.
/* Skip the accumulate if the value is already saturated. */
l1 = gen_new_label();
tmp = tcg_temp_new();
- gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
+ gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
gen_op_jmp_nz32(tmp, l1);
}
#endif
/* Skip the accumulate if the value is already saturated. */
l1 = gen_new_label();
tmp = tcg_temp_new();
- gen_op_and32(tmp, QREG_MACSR, gen_im32(MACSR_PAV0 << acc));
+ gen_op_and32(tmp, QREG_MACSR, tcg_const_i32(MACSR_PAV0 << acc));
gen_op_jmp_nz32(tmp, l1);
}
#endif
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);
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);
}
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);
}
{
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);
/* ??? Some of this implementation is not exception safe. We should always
write back the result to memory before setting the condition codes. */
-static void disas_m68k_insn(CPUState * env, DisasContext *s)
+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(CPUState *env, TranslationBlock *tb,
+gen_intermediate_code_internal(CPUM68KState *env, TranslationBlock *tb,
int search_pc)
{
DisasContext dc1, *dc = &dc1;
uint16_t *gen_opc_end;
+ CPUBreakpoint *bp;
int j, lj;
target_ulong pc_start;
int pc_offset;
- int last_cc_op;
int num_insns;
int max_insns;
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;
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;
- if (env->nb_breakpoints > 0) {
- for(j = 0; j < env->nb_breakpoints; j++) {
- if (env->breakpoints[j] == dc->pc) {
+ if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
+ QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+ if (bp->pc == dc->pc) {
gen_exception(dc, dc->pc, EXCP_DEBUG);
dc->is_jmp = DISAS_JUMP;
break;
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();
- last_cc_op = dc->cc_op;
dc->insn_pc = dc->pc;
disas_m68k_insn(env, dc);
num_insns++;
-
- /* Terminate the TB on memory ops if watchpoints are present. */
- /* FIXME: This should be replaced by the deterministic execution
- * IRQ raising bits. */
- if (dc->is_mem && env->nb_watchpoints)
- break;
- } 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) &&
num_insns < max_insns);
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:
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 (loglevel & CPU_LOG_TB_IN_ASM) {
- fprintf(logfile, "----------------\n");
- fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
- target_disas(logfile, pc_start, dc->pc - pc_start, 0);
- fprintf(logfile, "\n");
+ if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
+ qemu_log("----------------\n");
+ qemu_log("IN: %s\n", lookup_symbol(pc_start));
+ 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;
//expand_target_qops();
}
-void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
+void gen_intermediate_code(CPUM68KState *env, TranslationBlock *tb)
{
gen_intermediate_code_internal(env, tb, 0);
}
-void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
+void gen_intermediate_code_pc(CPUM68KState *env, TranslationBlock *tb)
{
gen_intermediate_code_internal(env, tb, 1);
}
-void cpu_dump_state(CPUState *env, FILE *f,
- int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state(CPUM68KState *env, FILE *f, fprintf_function cpu_fprintf,
int flags)
{
int i;
cpu_fprintf (f, "FPRESULT = %12g\n", *(double *)&env->fp_result);
}
-void gen_pc_load(CPUState *env, TranslationBlock *tb,
- unsigned long searched_pc, int pc_pos, void *puc)
+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];
}