Commit 991a97ac authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/vivier/tags/m68k-part1-pull-request' into staging



# gpg: Signature made Tue 25 Oct 2016 19:58:46 BST
# gpg:                using RSA key 0xF30C38BD3F2FBE3C
# gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>"
# gpg:                 aka "Laurent Vivier <laurent@vivier.eu>"
# gpg:                 aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>"
# Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F  5173 F30C 38BD 3F2F BE3C

* remotes/vivier/tags/m68k-part1-pull-request: (23 commits)
  target-m68k: Optimize gen_flush_flags
  target-m68k: Optimize some comparisons
  target-m68k: Use setcond for scc
  target-m68k: Introduce DisasCompare
  target-m68k: Reorg flags handling
  target-m68k: Remove incorrect clearing of cc_x
  target-m68k: Some fixes to SR and flags management
  target-m68k: Print flags properly
  target-m68k: update CPU flags management
  target-m68k: don't update cc_dest in helpers
  target-m68k: update move to/from ccr/sr
  target-m68k: remove m68k_cpu_exec_enter() and m68k_cpu_exec_exit()
  target-m68k: Replace helper_xflag_lt with setcond
  target-m68k: allow to update flags with operation on words and bytes
  target-m68k: REG() macro cleanup
  target-m68k: set PAGE_BITS to 12 for m68k
  target-m68k: define operand sizes
  target-m68k: set disassembler mode to 680x0 or coldfire
  target-m68k: introduce read_imXX() functions
  target-m68k: manage scaled index
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents ede0cbeb 36f0399d
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -151,12 +151,6 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
        && qemu_log_in_addr_range(itb->pc)) {
#if defined(TARGET_I386)
        log_cpu_state(cpu, CPU_DUMP_CCOP);
#elif defined(TARGET_M68K)
        /* ??? Should not modify env state for dumping.  */
        cpu_m68k_flush_flags(env, env->cc_op);
        env->cc_op = CC_OP_FLAGS;
        env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4);
        log_cpu_state(cpu, 0);
#else
        log_cpu_state(cpu, 0);
#endif
+63 −4
Original line number Diff line number Diff line
@@ -58,15 +58,20 @@ static void m68k_cpu_reset(CPUState *s)
#endif
    m68k_switch_sp(env);
    /* ??? FP regs should be initialized to NaN.  */
    env->cc_op = CC_OP_FLAGS;
    cpu_m68k_set_ccr(env, 0);
    /* TODO: We should set PC from the interrupt vector.  */
    env->pc = 0;
    tlb_flush(s, 1);
}

static void m68k_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
static void m68k_cpu_disas_set_info(CPUState *s, disassemble_info *info)
{
    M68kCPU *cpu = M68K_CPU(s);
    CPUM68KState *env = &cpu->env;
    info->print_insn = print_insn_m68k;
    if (m68k_feature(env, M68K_FEATURE_M68000)) {
        info->mach = bfd_mach_m68040;
    }
}

/* CPU models */
@@ -98,6 +103,57 @@ static void m5206_cpu_initfn(Object *obj)
    m68k_set_feature(env, M68K_FEATURE_CF_ISA_A);
}

static void m68000_cpu_initfn(Object *obj)
{
    M68kCPU *cpu = M68K_CPU(obj);
    CPUM68KState *env = &cpu->env;

    m68k_set_feature(env, M68K_FEATURE_M68000);
    m68k_set_feature(env, M68K_FEATURE_USP);
    m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
}

static void m68020_cpu_initfn(Object *obj)
{
    M68kCPU *cpu = M68K_CPU(obj);
    CPUM68KState *env = &cpu->env;

    m68k_set_feature(env, M68K_FEATURE_M68000);
    m68k_set_feature(env, M68K_FEATURE_USP);
    m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
    m68k_set_feature(env, M68K_FEATURE_QUAD_MULDIV);
    m68k_set_feature(env, M68K_FEATURE_BRAL);
    m68k_set_feature(env, M68K_FEATURE_BCCL);
    m68k_set_feature(env, M68K_FEATURE_BITFIELD);
    m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
    m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX);
    m68k_set_feature(env, M68K_FEATURE_LONG_MULDIV);
    m68k_set_feature(env, M68K_FEATURE_FPU);
    m68k_set_feature(env, M68K_FEATURE_CAS);
    m68k_set_feature(env, M68K_FEATURE_BKPT);
}
#define m68030_cpu_initfn m68020_cpu_initfn
#define m68040_cpu_initfn m68020_cpu_initfn

static void m68060_cpu_initfn(Object *obj)
{
    M68kCPU *cpu = M68K_CPU(obj);
    CPUM68KState *env = &cpu->env;

    m68k_set_feature(env, M68K_FEATURE_M68000);
    m68k_set_feature(env, M68K_FEATURE_USP);
    m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
    m68k_set_feature(env, M68K_FEATURE_BRAL);
    m68k_set_feature(env, M68K_FEATURE_BCCL);
    m68k_set_feature(env, M68K_FEATURE_BITFIELD);
    m68k_set_feature(env, M68K_FEATURE_EXT_FULL);
    m68k_set_feature(env, M68K_FEATURE_SCALED_INDEX);
    m68k_set_feature(env, M68K_FEATURE_LONG_MULDIV);
    m68k_set_feature(env, M68K_FEATURE_FPU);
    m68k_set_feature(env, M68K_FEATURE_CAS);
    m68k_set_feature(env, M68K_FEATURE_BKPT);
}

static void m5208_cpu_initfn(Object *obj)
{
    M68kCPU *cpu = M68K_CPU(obj);
@@ -148,6 +204,11 @@ typedef struct M68kCPUInfo {
} M68kCPUInfo;

static const M68kCPUInfo m68k_cpus[] = {
    { .name = "m68000", .instance_init = m68000_cpu_initfn },
    { .name = "m68020", .instance_init = m68020_cpu_initfn },
    { .name = "m68030", .instance_init = m68030_cpu_initfn },
    { .name = "m68040", .instance_init = m68040_cpu_initfn },
    { .name = "m68060", .instance_init = m68060_cpu_initfn },
    { .name = "m5206", .instance_init = m5206_cpu_initfn },
    { .name = "m5208", .instance_init = m5208_cpu_initfn },
    { .name = "cfv4e", .instance_init = cfv4e_cpu_initfn },
@@ -220,8 +281,6 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
#else
    cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
#endif
    cc->cpu_exec_enter = m68k_cpu_exec_enter;
    cc->cpu_exec_exit = m68k_cpu_exec_exit;
    cc->disas_set_info = m68k_cpu_disas_set_info;

    cc->gdb_num_core_regs = 18;
+50 −22
Original line number Diff line number Diff line
@@ -30,6 +30,14 @@
#include "cpu-qom.h"
#include "fpu/softfloat.h"

#define OS_BYTE     0
#define OS_WORD     1
#define OS_LONG     2
#define OS_SINGLE   3
#define OS_DOUBLE   4
#define OS_EXTENDED 5
#define OS_PACKED   6

#define MAX_QREGS 32

#define EXCP_ACCESS         2   /* Access (MMU) error.  */
@@ -53,6 +61,7 @@
#define EXCP_HALT_INSN      0x101

#define NB_MMU_MODES 2
#define TARGET_INSN_START_EXTRA_WORDS 1

typedef struct CPUM68KState {
    uint32_t dregs[8];
@@ -66,9 +75,11 @@ typedef struct CPUM68KState {

    /* Condition flags.  */
    uint32_t cc_op;
    uint32_t cc_dest;
    uint32_t cc_src;
    uint32_t cc_x;
    uint32_t cc_x; /* always 0/1 */
    uint32_t cc_n; /* in bit 31 (i.e. negative) */
    uint32_t cc_v; /* in bit 31, unused, or computed from cc_n and cc_v */
    uint32_t cc_c; /* either 0/1, unused, or computed from cc_n and cc_v */
    uint32_t cc_z; /* == 0 or unused */

    float64 fregs[8];
    float64 fp_result;
@@ -141,9 +152,6 @@ hwaddr m68k_cpu_get_phys_page_debug(CPUState *cpu, vaddr addr);
int m68k_cpu_gdb_read_register(CPUState *cpu, uint8_t *buf, int reg);
int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);

void m68k_cpu_exec_enter(CPUState *cs);
void m68k_cpu_exec_exit(CPUState *cs);

void m68k_tcg_init(void);
void m68k_cpu_init_gdb(M68kCPU *cpu);
M68kCPU *cpu_m68k_init(const char *cpu_model);
@@ -152,7 +160,8 @@ M68kCPU *cpu_m68k_init(const char *cpu_model);
   is returned if the signal was handled by the virtual CPU.  */
int cpu_m68k_signal_handler(int host_signum, void *pinfo,
                           void *puc);
void cpu_m68k_flush_flags(CPUM68KState *, int);
uint32_t cpu_m68k_get_ccr(CPUM68KState *env);
void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t);


/* Instead of computing the condition codes after each m68k instruction,
@@ -162,18 +171,25 @@ void cpu_m68k_flush_flags(CPUM68KState *, int);
 * using this information. Condition codes are not generated if they
 * are only needed for conditional branches.
 */
enum {
    CC_OP_DYNAMIC, /* Use env->cc_op  */
    CC_OP_FLAGS, /* CC_DEST = CVZN, CC_SRC = unused */
    CC_OP_LOGIC, /* CC_DEST = result, CC_SRC = unused */
    CC_OP_ADD,   /* CC_DEST = result, CC_SRC = source */
    CC_OP_SUB,   /* CC_DEST = result, CC_SRC = source */
    CC_OP_CMPB,  /* CC_DEST = result, CC_SRC = source */
    CC_OP_CMPW,  /* CC_DEST = result, CC_SRC = source */
    CC_OP_ADDX,  /* CC_DEST = result, CC_SRC = source */
    CC_OP_SUBX,  /* CC_DEST = result, CC_SRC = source */
    CC_OP_SHIFT, /* CC_DEST = result, CC_SRC = carry */
};
typedef enum {
    /* Translator only -- use env->cc_op.  */
    CC_OP_DYNAMIC = -1,

    /* Each flag bit computed into cc_[xcnvz].  */
    CC_OP_FLAGS,

    /* X in cc_x, C = X, N in cc_n, Z in cc_n, V via cc_n/cc_v.  */
    CC_OP_ADD,
    CC_OP_SUB,

    /* X in cc_x, {N,Z,C,V} via cc_n/cc_v.  */
    CC_OP_CMP,

    /* X in cc_x, C = 0, V = 0, N in cc_n, Z in cc_n.  */
    CC_OP_LOGIC,

    CC_OP_NB
} CCOp;

#define CCF_C 0x01
#define CCF_V 0x02
@@ -215,6 +231,7 @@ void do_m68k_semihosting(CPUM68KState *env, int nr);
   ISA revisions mentioned.  */

enum m68k_features {
    M68K_FEATURE_M68000,
    M68K_FEATURE_CF_ISA_A,
    M68K_FEATURE_CF_ISA_B, /* (ISA B or C).  */
    M68K_FEATURE_CF_ISA_APLUSC, /* BIT/BITREV, FF1, STRLDSR (ISA A+ or C).  */
@@ -225,7 +242,15 @@ enum m68k_features {
    M68K_FEATURE_CF_EMAC_B, /* Revision B EMAC (dual accumulate).  */
    M68K_FEATURE_USP, /* User Stack Pointer.  (ISA A+, B or C).  */
    M68K_FEATURE_EXT_FULL, /* 68020+ full extension word.  */
    M68K_FEATURE_WORD_INDEX /* word sized address index registers.  */
    M68K_FEATURE_WORD_INDEX, /* word sized address index registers.  */
    M68K_FEATURE_SCALED_INDEX, /* scaled address index registers.  */
    M68K_FEATURE_LONG_MULDIV, /* 32 bit multiply/divide. */
    M68K_FEATURE_QUAD_MULDIV, /* 64 bit multiply/divide. */
    M68K_FEATURE_BCCL, /* Long conditional branches.  */
    M68K_FEATURE_BITFIELD, /* Bit field insns.  */
    M68K_FEATURE_FPU,
    M68K_FEATURE_CAS,
    M68K_FEATURE_BKPT,
};

static inline int m68k_feature(CPUM68KState *env, int feature)
@@ -238,8 +263,11 @@ void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf);
void register_m68k_insns (CPUM68KState *env);

#ifdef CONFIG_USER_ONLY
/* Linux uses 8k pages.  */
#define TARGET_PAGE_BITS 13
/* Coldfire Linux uses 8k pages
 * and m68k linux uses 4k pages
 * use the smaller one
 */
#define TARGET_PAGE_BITS 12
#else
/* Smallest TLB entry size is 1k.  */
#define TARGET_PAGE_BITS 10
+136 −183
Original line number Diff line number Diff line
@@ -132,87 +132,6 @@ void m68k_cpu_init_gdb(M68kCPU *cpu)
    /* TODO: Add [E]MAC registers.  */
}

void cpu_m68k_flush_flags(CPUM68KState *env, int cc_op)
{
    M68kCPU *cpu = m68k_env_get_cpu(env);
    int flags;
    uint32_t src;
    uint32_t dest;
    uint32_t tmp;

#define HIGHBIT 0x80000000u

#define SET_NZ(x) do { \
    if ((x) == 0) \
        flags |= CCF_Z; \
    else if ((int32_t)(x) < 0) \
        flags |= CCF_N; \
    } while (0)

#define SET_FLAGS_SUB(type, utype) do { \
    SET_NZ((type)dest); \
    tmp = dest + src; \
    if ((utype) tmp < (utype) src) \
        flags |= CCF_C; \
    if ((1u << (sizeof(type) * 8 - 1)) & (tmp ^ dest) & (tmp ^ src)) \
        flags |= CCF_V; \
    } while (0)

    flags = 0;
    src = env->cc_src;
    dest = env->cc_dest;
    switch (cc_op) {
    case CC_OP_FLAGS:
        flags = dest;
        break;
    case CC_OP_LOGIC:
        SET_NZ(dest);
        break;
    case CC_OP_ADD:
        SET_NZ(dest);
        if (dest < src)
            flags |= CCF_C;
        tmp = dest - src;
        if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
            flags |= CCF_V;
        break;
    case CC_OP_SUB:
        SET_FLAGS_SUB(int32_t, uint32_t);
        break;
    case CC_OP_CMPB:
        SET_FLAGS_SUB(int8_t, uint8_t);
        break;
    case CC_OP_CMPW:
        SET_FLAGS_SUB(int16_t, uint16_t);
        break;
    case CC_OP_ADDX:
        SET_NZ(dest);
        if (dest <= src)
            flags |= CCF_C;
        tmp = dest - src - 1;
        if (HIGHBIT & (src ^ dest) & ~(tmp ^ src))
            flags |= CCF_V;
        break;
    case CC_OP_SUBX:
        SET_NZ(dest);
        tmp = dest + src + 1;
        if (tmp <= src)
            flags |= CCF_C;
        if (HIGHBIT & (tmp ^ dest) & (tmp ^ src))
            flags |= CCF_V;
        break;
    case CC_OP_SHIFT:
        SET_NZ(dest);
        if (src)
            flags |= CCF_C;
        break;
    default:
        cpu_abort(CPU(cpu), "Bad CC_OP %d", cc_op);
    }
    env->cc_op = CC_OP_FLAGS;
    env->cc_dest = flags;
}

void HELPER(movec)(CPUM68KState *env, uint32_t reg, uint32_t val)
{
    M68kCPU *cpu = m68k_env_get_cpu(env);
@@ -349,140 +268,111 @@ uint32_t HELPER(ff1)(uint32_t x)
    return n;
}

uint32_t HELPER(sats)(uint32_t val, uint32_t ccr)
uint32_t HELPER(sats)(uint32_t val, uint32_t v)
{
    /* The result has the opposite sign to the original value.  */
    if (ccr & CCF_V)
    if ((int32_t)v < 0) {
        val = (((int32_t)val) >> 31) ^ SIGNBIT;
    }
    return val;
}

uint32_t HELPER(subx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
{
    uint32_t res;
    uint32_t old_flags;
    uint32_t res, new_x;

    old_flags = env->cc_dest;
    if (env->cc_x) {
        env->cc_x = (op1 <= op2);
        env->cc_op = CC_OP_SUBX;
        new_x = (op1 <= op2);
        res = op1 - (op2 + 1);
    } else {
        env->cc_x = (op1 < op2);
        env->cc_op = CC_OP_SUB;
        new_x = (op1 < op2);
        res = op1 - op2;
    }
    env->cc_dest = res;
    env->cc_src = op2;
    cpu_m68k_flush_flags(env, env->cc_op);
    /* !Z is sticky.  */
    env->cc_dest &= (old_flags | ~CCF_Z);
    env->cc_x = new_x;
    env->cc_c = new_x;
    env->cc_n = res;
    env->cc_z |= res; /* !Z is sticky */
    env->cc_v = (res ^ op1) & (op1 ^ op2);

    return res;
}

uint32_t HELPER(addx_cc)(CPUM68KState *env, uint32_t op1, uint32_t op2)
{
    uint32_t res;
    uint32_t old_flags;
    uint32_t res, new_x;

    old_flags = env->cc_dest;
    if (env->cc_x) {
        res = op1 + op2 + 1;
        env->cc_x = (res <= op2);
        env->cc_op = CC_OP_ADDX;
        new_x = (res <= op2);
    } else {
        res = op1 + op2;
        env->cc_x = (res < op2);
        env->cc_op = CC_OP_ADD;
    }
    env->cc_dest = res;
    env->cc_src = op2;
    cpu_m68k_flush_flags(env, env->cc_op);
    /* !Z is sticky.  */
    env->cc_dest &= (old_flags | ~CCF_Z);
    return res;
        new_x = (res < op2);
    }
    env->cc_x = new_x;
    env->cc_c = new_x;
    env->cc_n = res;
    env->cc_z |= res; /* !Z is sticky.  */
    env->cc_v = (res ^ op1) & ~(op1 ^ op2);

uint32_t HELPER(xflag_lt)(uint32_t a, uint32_t b)
{
    return a < b;
    return res;
}

void HELPER(set_sr)(CPUM68KState *env, uint32_t val)
{
    env->sr = val & 0xffff;
    env->sr = val & 0xffe0;
    cpu_m68k_set_ccr(env, val);
    m68k_switch_sp(env);
}

uint32_t HELPER(shl_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
{
    uint32_t result;
    uint32_t cf;
    uint64_t result;

    shift &= 63;
    if (shift == 0) {
        result = val;
        cf = env->cc_src & CCF_C;
    } else if (shift < 32) {
        result = val << shift;
        cf = (val >> (32 - shift)) & 1;
    } else if (shift == 32) {
        result = 0;
        cf = val & 1;
    } else /* shift > 32 */ {
        result = 0;
        cf = 0;
    }
    env->cc_src = cf;
    env->cc_x = (cf != 0);
    env->cc_dest = result;
    result = (uint64_t)val << shift;

    env->cc_c = (result >> 32) & 1;
    env->cc_n = result;
    env->cc_z = result;
    env->cc_v = 0;
    env->cc_x = shift ? env->cc_c : env->cc_x;

    return result;
}

uint32_t HELPER(shr_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
{
    uint64_t temp;
    uint32_t result;
    uint32_t cf;

    shift &= 63;
    if (shift == 0) {
        result = val;
        cf = env->cc_src & CCF_C;
    } else if (shift < 32) {
        result = val >> shift;
        cf = (val >> (shift - 1)) & 1;
    } else if (shift == 32) {
        result = 0;
        cf = val >> 31;
    } else /* shift > 32 */ {
        result = 0;
        cf = 0;
    }
    env->cc_src = cf;
    env->cc_x = (cf != 0);
    env->cc_dest = result;
    temp = (uint64_t)val << 32 >> shift;
    result = temp >> 32;

    env->cc_c = (temp >> 31) & 1;
    env->cc_n = result;
    env->cc_z = result;
    env->cc_v = 0;
    env->cc_x = shift ? env->cc_c : env->cc_x;

    return result;
}

uint32_t HELPER(sar_cc)(CPUM68KState *env, uint32_t val, uint32_t shift)
{
    uint64_t temp;
    uint32_t result;
    uint32_t cf;

    shift &= 63;
    if (shift == 0) {
        result = val;
        cf = (env->cc_src & CCF_C) != 0;
    } else if (shift < 32) {
        result = (int32_t)val >> shift;
        cf = (val >> (shift - 1)) & 1;
    } else /* shift >= 32 */ {
        result = (int32_t)val >> 31;
        cf = val >> 31;
    }
    env->cc_src = cf;
    env->cc_x = cf;
    env->cc_dest = result;
    temp = (int64_t)val << 32 >> shift;
    result = temp >> 32;

    env->cc_c = (temp >> 31) & 1;
    env->cc_n = result;
    env->cc_z = result;
    env->cc_v = result ^ val;
    env->cc_x = shift ? env->cc_c : env->cc_x;

    return result;
}

@@ -734,9 +624,92 @@ void HELPER(mac_set_flags)(CPUM68KState *env, uint32_t acc)
    }
}


#define COMPUTE_CCR(op, x, n, z, v, c) {                                   \
    switch (op) {                                                          \
    case CC_OP_FLAGS:                                                      \
        /* Everything in place.  */                                        \
        break;                                                             \
    case CC_OP_ADD:                                                        \
        res = n;                                                           \
        src2 = v;                                                          \
        src1 = res - src2;                                                 \
        c = x;                                                             \
        z = n;                                                             \
        v = (res ^ src1) & ~(src1 ^ src2);                                 \
        break;                                                             \
    case CC_OP_SUB:                                                        \
        res = n;                                                           \
        src2 = v;                                                          \
        src1 = res + src2;                                                 \
        c = x;                                                             \
        z = n;                                                             \
        v = (res ^ src1) & (src1 ^ src2);                                  \
        break;                                                             \
    case CC_OP_CMP:                                                        \
        src1 = n;                                                          \
        src2 = v;                                                          \
        res = src1 - src2;                                                 \
        n = res;                                                           \
        z = res;                                                           \
        c = src1 < src2;                                                   \
        v = (res ^ src1) & (src1 ^ src2);                                  \
        break;                                                             \
    case CC_OP_LOGIC:                                                      \
        c = v = 0;                                                         \
        z = n;                                                             \
        break;                                                             \
    default:                                                               \
        cpu_abort(CPU(m68k_env_get_cpu(env)), "Bad CC_OP %d", op);         \
    }                                                                      \
} while (0)

uint32_t cpu_m68k_get_ccr(CPUM68KState *env)
{
    uint32_t x, c, n, z, v;
    uint32_t res, src1, src2;

    x = env->cc_x;
    c = env->cc_c;
    n = env->cc_n;
    z = env->cc_z;
    v = env->cc_v;

    COMPUTE_CCR(env->cc_op, x, n, z, v, c);

    n = n >> 31;
    v = v >> 31;
    z = (z == 0);

    return x * CCF_X + n * CCF_N + z * CCF_Z + v * CCF_V + c * CCF_C;
}

uint32_t HELPER(get_ccr)(CPUM68KState *env)
{
    return cpu_m68k_get_ccr(env);
}

void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t ccr)
{
    env->cc_x = (ccr & CCF_X ? 1 : 0);
    env->cc_n = (ccr & CCF_N ? -1 : 0);
    env->cc_z = (ccr & CCF_Z ? 0 : 1);
    env->cc_v = (ccr & CCF_V ? -1 : 0);
    env->cc_c = (ccr & CCF_C ? 1 : 0);
    env->cc_op = CC_OP_FLAGS;
}

void HELPER(set_ccr)(CPUM68KState *env, uint32_t ccr)
{
    cpu_m68k_set_ccr(env, ccr);
}

void HELPER(flush_flags)(CPUM68KState *env, uint32_t cc_op)
{
    cpu_m68k_flush_flags(env, cc_op);
    uint32_t res, src1, src2;

    COMPUTE_CCR(cc_op, env->cc_x, env->cc_n, env->cc_z, env->cc_v, env->cc_c);
    env->cc_op = CC_OP_FLAGS;
}

uint32_t HELPER(get_macf)(CPUM68KState *env, uint64_t val)
@@ -866,23 +839,3 @@ void HELPER(set_mac_extu)(CPUM68KState *env, uint32_t val, uint32_t acc)
    res |= (uint64_t)(val & 0xffff0000) << 16;
    env->macc[acc + 1] = res;
}

void m68k_cpu_exec_enter(CPUState *cs)
{
    M68kCPU *cpu = M68K_CPU(cs);
    CPUM68KState *env = &cpu->env;

    env->cc_op = CC_OP_FLAGS;
    env->cc_dest = env->sr & 0xf;
    env->cc_x = (env->sr >> 4) & 1;
}

void m68k_cpu_exec_exit(CPUState *cs)
{
    M68kCPU *cpu = M68K_CPU(cs);
    CPUM68KState *env = &cpu->env;

    cpu_m68k_flush_flags(env, env->cc_op);
    env->cc_op = CC_OP_FLAGS;
    env->sr = (env->sr & 0xffe0) | env->cc_dest | (env->cc_x << 4);
}
+3 −2
Original line number Diff line number Diff line
DEF_HELPER_1(bitrev, i32, i32)
DEF_HELPER_1(ff1, i32, i32)
DEF_HELPER_2(sats, i32, i32, i32)
DEF_HELPER_FLAGS_2(sats, TCG_CALL_NO_RWG_SE, i32, i32, i32)
DEF_HELPER_2(divu, void, env, i32)
DEF_HELPER_2(divs, void, env, i32)
DEF_HELPER_3(addx_cc, i32, env, i32, i32)
@@ -8,7 +8,6 @@ DEF_HELPER_3(subx_cc, i32, env, i32, i32)
DEF_HELPER_3(shl_cc, i32, env, i32, i32)
DEF_HELPER_3(shr_cc, i32, env, i32, i32)
DEF_HELPER_3(sar_cc, i32, env, i32, i32)
DEF_HELPER_2(xflag_lt, i32, i32, i32)
DEF_HELPER_2(set_sr, void, env, i32)
DEF_HELPER_3(movec, void, env, i32, i32)

@@ -47,4 +46,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_2(set_ccr, void, env, i32)
DEF_HELPER_FLAGS_1(get_ccr, TCG_CALL_NO_WG_SE, i32, env)
DEF_HELPER_2(raise_exception, void, env, i32)
Loading