/* 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)
+static inline TCGv gen_load(DisasContext *s, int opsize, TCGv addr,
+ int sign, int index)
{
TCGv tmp;
- int index = IS_USER(s);
tmp = tcg_temp_new_i32();
switch(opsize) {
case OS_BYTE:
}
/* Generate a store. */
-static inline void gen_store(DisasContext *s, int opsize, TCGv addr, TCGv val)
+static inline void gen_store(DisasContext *s, int opsize, TCGv addr, TCGv val,
+ int index)
{
- int index = IS_USER(s);
switch(opsize) {
case OS_BYTE:
tcg_gen_qemu_st8(val, addr, index);
/* Generate an unsigned load if VAL is 0 a signed load if val is -1,
otherwise generate a store. */
static TCGv gen_ldst(DisasContext *s, int opsize, TCGv addr, TCGv val,
- ea_what what)
+ ea_what what, int index)
{
if (what == EA_STORE) {
- gen_store(s, opsize, addr, val);
+ gen_store(s, opsize, addr, val, index);
return store_dummy;
} else {
- return gen_load(s, opsize, addr, what == EA_LOADS);
+ return gen_load(s, opsize, addr, what == EA_LOADS, index);
}
}
}
if ((ext & 3) != 0) {
/* memory indirect */
- base = gen_load(s, OS_LONG, add, 0);
+ base = gen_load(s, OS_LONG, add, 0, IS_USER(s));
if ((ext & 0x44) == 4) {
add = gen_addr_index(s, ext, tmp);
tcg_gen_add_i32(tmp, add, base);
a write otherwise it is a read (0 == sign extend, -1 == zero extend).
ADDRP is non-null for readwrite operands. */
static TCGv gen_ea_mode(CPUM68KState *env, DisasContext *s, int mode, int reg0,
- int opsize, TCGv val, TCGv *addrp, ea_what what)
+ int opsize, TCGv val, TCGv *addrp, ea_what what,
+ int index)
{
TCGv reg, tmp, result;
int32_t offset;
}
case 2: /* Indirect register */
reg = get_areg(s, reg0);
- return gen_ldst(s, opsize, reg, val, what);
+ return gen_ldst(s, opsize, reg, val, what, index);
case 3: /* Indirect postincrement. */
reg = get_areg(s, reg0);
- result = gen_ldst(s, opsize, reg, val, what);
+ result = gen_ldst(s, opsize, reg, val, what, index);
if (what == EA_STORE || !addrp) {
TCGv tmp = tcg_temp_new();
if (reg0 == 7 && opsize == OS_BYTE &&
*addrp = tmp;
}
}
- result = gen_ldst(s, opsize, tmp, val, what);
+ result = gen_ldst(s, opsize, tmp, val, what, index);
if (what == EA_STORE || !addrp) {
delay_set_areg(s, reg0, tmp, false);
}
*addrp = tmp;
}
}
- return gen_ldst(s, opsize, tmp, val, what);
+ return gen_ldst(s, opsize, tmp, val, what, index);
case 7: /* Other */
switch (reg0) {
case 0: /* Absolute short. */
}
static TCGv gen_ea(CPUM68KState *env, DisasContext *s, uint16_t insn,
- int opsize, TCGv val, TCGv *addrp, ea_what what)
+ int opsize, TCGv val, TCGv *addrp, ea_what what, int index)
{
int mode = extract32(insn, 3, 3);
int reg0 = REG(insn, 0);
- return gen_ea_mode(env, s, mode, reg0, opsize, val, addrp, what);
+ return gen_ea_mode(env, s, mode, reg0, opsize, val, addrp, what, index);
}
static TCGv_ptr gen_fp_ptr(int freg)
tcg_temp_free_i64(t64);
}
-static void gen_load_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp)
+static void gen_load_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp,
+ int index)
{
TCGv tmp;
TCGv_i64 t64;
- int index = IS_USER(s);
t64 = tcg_temp_new_i64();
tmp = tcg_temp_new();
tcg_temp_free_i64(t64);
}
-static void gen_store_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp)
+static void gen_store_fp(DisasContext *s, int opsize, TCGv addr, TCGv_ptr fp,
+ int index)
{
TCGv tmp;
TCGv_i64 t64;
- int index = IS_USER(s);
t64 = tcg_temp_new_i64();
tmp = tcg_temp_new();
}
static void gen_ldst_fp(DisasContext *s, int opsize, TCGv addr,
- TCGv_ptr fp, ea_what what)
+ TCGv_ptr fp, ea_what what, int index)
{
if (what == EA_STORE) {
- gen_store_fp(s, opsize, addr, fp);
+ gen_store_fp(s, opsize, addr, fp, index);
} else {
- gen_load_fp(s, opsize, addr, fp);
+ gen_load_fp(s, opsize, addr, fp, index);
}
}
static int gen_ea_mode_fp(CPUM68KState *env, DisasContext *s, int mode,
- int reg0, int opsize, TCGv_ptr fp, ea_what what)
+ int reg0, int opsize, TCGv_ptr fp, ea_what what,
+ int index)
{
TCGv reg, addr, tmp;
TCGv_i64 t64;
return -1;
case 2: /* Indirect register */
addr = get_areg(s, reg0);
- gen_ldst_fp(s, opsize, addr, fp, what);
+ gen_ldst_fp(s, opsize, addr, fp, what, index);
return 0;
case 3: /* Indirect postincrement. */
addr = cpu_aregs[reg0];
- gen_ldst_fp(s, opsize, addr, fp, what);
+ gen_ldst_fp(s, opsize, addr, fp, what, index);
tcg_gen_addi_i32(addr, addr, opsize_bytes(opsize));
return 0;
case 4: /* Indirect predecrememnt. */
if (IS_NULL_QREG(addr)) {
return -1;
}
- gen_ldst_fp(s, opsize, addr, fp, what);
+ gen_ldst_fp(s, opsize, addr, fp, what, index);
tcg_gen_mov_i32(cpu_aregs[reg0], addr);
return 0;
case 5: /* Indirect displacement. */
if (IS_NULL_QREG(addr)) {
return -1;
}
- gen_ldst_fp(s, opsize, addr, fp, what);
+ gen_ldst_fp(s, opsize, addr, fp, what, index);
return 0;
case 7: /* Other */
switch (reg0) {
}
static int gen_ea_fp(CPUM68KState *env, DisasContext *s, uint16_t insn,
- int opsize, TCGv_ptr fp, ea_what what)
+ int opsize, TCGv_ptr fp, ea_what what, int index)
{
int mode = extract32(insn, 3, 3);
int reg0 = REG(insn, 0);
- return gen_ea_mode_fp(env, s, mode, reg0, opsize, fp, what);
+ return gen_ea_mode_fp(env, s, mode, reg0, opsize, fp, what, index);
}
typedef struct {
#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); \
+ op_sign ? EA_LOADS : EA_LOADU, IS_USER(s)); \
if (IS_NULL_QREG(result)) { \
gen_addr_fault(s); \
return; \
} while (0)
#define DEST_EA(env, insn, opsize, val, addrp) do { \
- TCGv ea_result = gen_ea(env, s, insn, opsize, val, addrp, EA_STORE); \
+ TCGv ea_result = gen_ea(env, s, insn, opsize, val, addrp, \
+ EA_STORE, IS_USER(s)); \
if (IS_NULL_QREG(ea_result)) { \
gen_addr_fault(s); \
return; \
/* Indirect pre-decrement load (mode 4) */
src = gen_ea_mode(env, s, 4, REG(insn, 0), OS_BYTE,
- NULL_QREG, NULL, EA_LOADU);
+ NULL_QREG, NULL, EA_LOADU, IS_USER(s));
dest = gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE,
- NULL_QREG, &addr, EA_LOADU);
+ NULL_QREG, &addr, EA_LOADU, IS_USER(s));
bcd_add(dest, src);
- gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr, EA_STORE);
+ gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr,
+ EA_STORE, IS_USER(s));
bcd_flags(dest);
}
/* Indirect pre-decrement load (mode 4) */
src = gen_ea_mode(env, s, 4, REG(insn, 0), OS_BYTE,
- NULL_QREG, NULL, EA_LOADU);
+ NULL_QREG, NULL, EA_LOADU, IS_USER(s));
dest = gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE,
- NULL_QREG, &addr, EA_LOADU);
+ NULL_QREG, &addr, EA_LOADU, IS_USER(s));
bcd_sub(dest, src);
- gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr, EA_STORE);
+ gen_ea_mode(env, s, 4, REG(insn, 9), OS_BYTE, dest, &addr,
+ EA_STORE, IS_USER(s));
bcd_flags(dest);
}
tmp = tcg_temp_new();
tcg_gen_subi_i32(tmp, QREG_SP, 4);
- gen_store(s, OS_LONG, tmp, val);
+ gen_store(s, OS_LONG, tmp, val, IS_USER(s));
tcg_gen_mov_i32(QREG_SP, tmp);
tcg_temp_free(tmp);
}
/* memory to register */
for (i = 0; i < 16; i++) {
if (mask & (1 << i)) {
- r[i] = gen_load(s, opsize, addr, 1);
+ r[i] = gen_load(s, opsize, addr, 1, IS_USER(s));
tcg_gen_add_i32(addr, addr, incr);
}
}
*/
tmp = tcg_temp_new();
tcg_gen_sub_i32(tmp, cpu_aregs[reg0], incr);
- gen_store(s, opsize, addr, tmp);
+ gen_store(s, opsize, addr, tmp, IS_USER(s));
tcg_temp_free(tmp);
} else {
- gen_store(s, opsize, addr, mreg(i));
+ gen_store(s, opsize, addr, mreg(i), IS_USER(s));
}
}
}
} else {
for (i = 0; i < 16; i++) {
if (mask & (1 << i)) {
- gen_store(s, opsize, addr, mreg(i));
+ gen_store(s, opsize, addr, mreg(i), IS_USER(s));
tcg_gen_add_i32(addr, addr, incr);
}
}
reg = AREG(insn, 0);
tmp = tcg_temp_new();
tcg_gen_subi_i32(tmp, QREG_SP, 4);
- gen_store(s, OS_LONG, tmp, reg);
+ gen_store(s, OS_LONG, tmp, reg, IS_USER(s));
if ((insn & 7) != 7) {
tcg_gen_mov_i32(reg, tmp);
}
src = tcg_temp_new();
reg = AREG(insn, 0);
tcg_gen_mov_i32(src, reg);
- tmp = gen_load(s, OS_LONG, src, 0);
+ tmp = gen_load(s, OS_LONG, src, 0, IS_USER(s));
tcg_gen_mov_i32(reg, tmp);
tcg_gen_addi_i32(QREG_SP, src, 4);
tcg_temp_free(src);
TCGv tmp;
int16_t offset = read_im16(env, s);
- tmp = gen_load(s, OS_LONG, QREG_SP, 0);
+ tmp = gen_load(s, OS_LONG, QREG_SP, 0, IS_USER(s));
tcg_gen_addi_i32(QREG_SP, QREG_SP, offset + 4);
gen_jmp(s, tmp);
}
{
TCGv tmp;
- tmp = gen_load(s, OS_LONG, QREG_SP, 0);
+ tmp = gen_load(s, OS_LONG, QREG_SP, 0, IS_USER(s));
tcg_gen_addi_i32(QREG_SP, QREG_SP, 4);
gen_jmp(s, tmp);
}
addr_src = AREG(insn, 0);
tcg_gen_subi_i32(addr_src, addr_src, opsize);
- src = gen_load(s, opsize, addr_src, 1);
+ src = gen_load(s, opsize, addr_src, 1, IS_USER(s));
addr_dest = AREG(insn, 9);
tcg_gen_subi_i32(addr_dest, addr_dest, opsize);
- dest = gen_load(s, opsize, addr_dest, 1);
+ dest = gen_load(s, opsize, addr_dest, 1, IS_USER(s));
gen_subx(s, src, dest, opsize);
- gen_store(s, opsize, addr_dest, QREG_CC_N);
+ gen_store(s, opsize, addr_dest, QREG_CC_N, IS_USER(s));
}
DISAS_INSN(mov3q)
/* Post-increment load (mode 3) from Ay. */
src = gen_ea_mode(env, s, 3, REG(insn, 0), opsize,
- NULL_QREG, NULL, EA_LOADS);
+ NULL_QREG, NULL, EA_LOADS, IS_USER(s));
/* Post-increment load (mode 3) from Ax. */
dst = gen_ea_mode(env, s, 3, REG(insn, 9), opsize,
- NULL_QREG, NULL, EA_LOADS);
+ NULL_QREG, NULL, EA_LOADS, IS_USER(s));
gen_update_cc_cmp(s, dst, src, opsize);
}
addr_src = AREG(insn, 0);
tcg_gen_subi_i32(addr_src, addr_src, opsize_bytes(opsize));
- src = gen_load(s, opsize, addr_src, 1);
+ src = gen_load(s, opsize, addr_src, 1, IS_USER(s));
addr_dest = AREG(insn, 9);
tcg_gen_subi_i32(addr_dest, addr_dest, opsize_bytes(opsize));
- dest = gen_load(s, opsize, addr_dest, 1);
+ dest = gen_load(s, opsize, addr_dest, 1, IS_USER(s));
gen_addx(s, src, dest, opsize);
- gen_store(s, opsize, addr_dest, QREG_CC_N);
+ gen_store(s, opsize, addr_dest, QREG_CC_N, IS_USER(s));
}
static inline void shift_im(DisasContext *s, uint16_t insn, int opsize)
addr2 = tcg_temp_new();
tcg_gen_addi_i32(addr2, addr1, opsize_bytes(opsize));
- bound1 = gen_load(s, opsize, addr1, 1);
+ bound1 = gen_load(s, opsize, addr1, 1, IS_USER(s));
tcg_temp_free(addr1);
- bound2 = gen_load(s, opsize, addr2, 1);
+ bound2 = gen_load(s, opsize, addr2, 1, IS_USER(s));
tcg_temp_free(addr2);
reg = tcg_temp_new();
case 3: /* fmove out */
cpu_src = gen_fp_ptr(REG(ext, 7));
opsize = ext_opsize(ext, 10);
- if (gen_ea_fp(env, s, insn, opsize, cpu_src, EA_STORE) == -1) {
+ if (gen_ea_fp(env, s, insn, opsize, cpu_src,
+ EA_STORE, IS_USER(s)) == -1) {
gen_addr_fault(s);
}
gen_helper_ftst(cpu_env, cpu_src);
/* Source effective address. */
opsize = ext_opsize(ext, 10);
cpu_src = gen_fp_result_ptr();
- if (gen_ea_fp(env, s, insn, opsize, cpu_src, EA_LOADS) == -1) {
+ if (gen_ea_fp(env, s, insn, opsize, cpu_src,
+ EA_LOADS, IS_USER(s)) == -1) {
gen_addr_fault(s);
return;
}
tcg_gen_and_i32(addr, tmp, QREG_MAC_MASK);
/* Load the value now to ensure correct exception behavior.
Perform writeback after reading the MAC inputs. */
- loadval = gen_load(s, OS_LONG, addr, 0);
+ loadval = gen_load(s, OS_LONG, addr, 0, IS_USER(s));
acc ^= 1;
rx = (ext & 0x8000) ? AREG(ext, 12) : DREG(insn, 12);