From: Richard Henderson
Separate all ccr bits. Continue to batch updates via cc_op.
Signed-off-by: Richard Henderson
Fix gen_logic_cc() to really extend the size of the result.
Fix gen_get_ccr(): update cc_op as it is used by the helper.
Signed-off-by: Laurent Vivier
---
target-m68k/cpu.c | 2 +-
target-m68k/cpu.h | 46 +++---
target-m68k/helper.c| 402 +---
target-m68k/helper.h| 6 +-
target-m68k/op_helper.c | 30 ++--
target-m68k/qregs.def | 6 +-
target-m68k/translate.c | 384 -
7 files changed, 389 insertions(+), 487 deletions(-)
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 81f1579..5ea154f 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -57,7 +57,7 @@ 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);
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 8347d04..9415d2b 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -74,9 +74,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;
@@ -133,27 +135,23 @@ uint32_t cpu_m68k_get_ccr(CPUM68KState *env);
void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t);
typedef enum {
-CC_OP_DYNAMIC, /* Use env->cc_op */
-CC_OP_FLAGS, /* CC_DEST = CVZN, CC_SRC = unused */
-CC_OP_LOGICB, /* CC_DEST = result, CC_SRC = unused */
-CC_OP_LOGICW, /* CC_DEST = result, CC_SRC = unused */
-CC_OP_LOGIC, /* CC_DEST = result, CC_SRC = unused */
-CC_OP_ADDB, /* CC_DEST = result, CC_SRC = source */
-CC_OP_ADDW, /* CC_DEST = result, CC_SRC = source */
-CC_OP_ADD, /* CC_DEST = result, CC_SRC = source */
-CC_OP_SUBB, /* CC_DEST = result, CC_SRC = source */
-CC_OP_SUBW, /* CC_DEST = result, CC_SRC = source */
-CC_OP_SUB, /* CC_DEST = result, CC_SRC = source */
-CC_OP_ADDXB, /* CC_DEST = result, CC_SRC = source */
-CC_OP_ADDXW, /* CC_DEST = result, CC_SRC = source */
-CC_OP_ADDX, /* CC_DEST = result, CC_SRC = source */
-CC_OP_SUBXB, /* CC_DEST = result, CC_SRC = source */
-CC_OP_SUBXW, /* CC_DEST = result, CC_SRC = source */
-CC_OP_SUBX, /* CC_DEST = result, CC_SRC = source */
-CC_OP_SHIFTB, /* CC_DEST = result, CC_SRC = carry */
-CC_OP_SHIFTW, /* CC_DEST = result, CC_SRC = carry */
-CC_OP_SHIFT, /* CC_DEST = result, CC_SRC = carry */
-CC_OP_NB,
+/* 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
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index 9c14d6f..8758016 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -131,151 +131,6 @@ void m68k_cpu_init_gdb(M68kCPU *cpu)
/* TODO: Add [E]MAC registers. */
}
-static uint32_t cpu_m68k_flush_flags(CPUM68KState *env, int op)
-{
-int flags;
-uint32_t src;
-uint32_t dest;
-uint32_t tmp;
-
-#define HIGHBIT(type) (1u << (sizeof(type) * 8 - 1))
-
-#define SET_NZ(x, type) do { \
-if ((type)(x) == 0) { \
-flags |= CCF_Z; \
-} else if ((type)(x) < 0) { \
-flags |= CCF_N; \
-} \
-} while (0)
-
-#define SET_FLAGS_SUB(type, utype) do { \
-SET_NZ(dest, type); \
-tmp = dest + src; \
-if ((utype) tmp < (utype) src) { \
-flags |= CCF_C; \
-} \
-if (HIGHBIT(type) & (tmp ^ dest) & (tmp ^ src)) { \
-flags |= CCF_V; \
-} \
-} while (0)
-
-#define SET_FLAGS_ADD(type, utype) do { \
-SET_NZ(dest, type); \
-if ((utype) dest < (utype) src) { \
-flags |= CCF_C; \
-} \
-tmp = dest - src; \
-if (HIGHBIT(type) & (src ^ dest) & ~(tmp ^ src)) { \
-flags |= CCF_V; \
-} \
-} while (0)
-
-#define SET_FLAGS_ADDX(type, utype) do { \
-SET_NZ(dest, type); \
-if ((utype) dest <= (utype) src) { \
-flags |= CCF_C; \
-} \
-tmp = dest - src - 1; \
-if (HIGHBIT(type) & (src ^ dest) & ~(tm