-----BEGIN PGP SIGNATURE-----

iQIcBAABAgAGBQJYD6tmAAoJEPMMOL0/L748ebQQAKxA2zQn2TPWoy/hzAC+QQIt
 VVKm3so/4WwX1JVrfLm9jAVHBsOYvHgABSxHtdwRQK2UD6QP3zh8dZNFIAJgNtGH
 SNMRm2HRyE7f16hnbz5Scqp7YGvYDp8XVolNvS/o5bBh3dS9j4V4W4DiC3bu7OZY
 FNytzlFCQvhOXNRejhlKsusYvrRECEy5Zaa3LTbYRVX7K/sHtDCD01URQKYJWZFJ
 m13juuus1rXNVuYxbs1YLwAJcN9yM4pjnZnO6meBH669+/JSbByjjXuhARwng4Z5
 o/f8+ZpyCMlNXMTt7DFu6QPxrFKCHpQ2Rwyy55uVx7lEmtZ1s6n6mF+P/Wp+kXUZ
 QzvbBSKCnNsLHGUf+0Us/U1v61WFhd4MZJF7dzWecVpLT8tCbXADFLbfgzFkz5MN
 zVd7L2uO4F3CtkwW8GFxmiVqmnHyOl/+2kz8UkejbnJQxwmr8oijVQVexaXDKHCA
 KytAz+PEW5qX6uGlfnEV2DnBpNOAzh8RspZF/mzDA5H0VM08bmeK7ySUe+BYRv2p
 GZXqdVchQrf2fYmFB1Dn4hGvc/gxtLjxkFst3koItgGeUauY35AAkDZ2B5EJ03UZ
 kpfA0grwhWTX92h+MYwXRHYaMoscCQPcjfYNbDGcOSvvwkElOf+fFMTaA9t0MGF2
 gREdnWwhl8gr7K/Mh+3t
 =uyQH
 -----END PGP SIGNATURE-----

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: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2016-10-27 11:58:43 +01:00
commit 991a97ac74
8 changed files with 895 additions and 671 deletions

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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;
new_x = (res < 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);
return res;
}
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);
}

View file

@ -1,6 +1,6 @@
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)

View file

@ -63,9 +63,9 @@ static void do_rte(CPUM68KState *env)
fmt = cpu_ldl_kernel(env, sp);
env->pc = cpu_ldl_kernel(env, sp + 4);
sp |= (fmt >> 28) & 3;
env->sr = fmt & 0xffff;
env->aregs[7] = sp + 8;
m68k_switch_sp(env);
helper_set_sr(env, fmt);
}
static void do_interrupt_all(CPUM68KState *env, int is_hw)
@ -112,6 +112,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_hw)
fmt |= 0x40000000;
fmt |= vector << 16;
fmt |= env->sr;
fmt |= cpu_m68k_get_ccr(env);
env->sr |= SR_S;
if (is_hw) {
@ -184,7 +185,6 @@ void HELPER(divu)(CPUM68KState *env, uint32_t word)
uint32_t den;
uint32_t quot;
uint32_t rem;
uint32_t flags;
num = env->div1;
den = env->div2;
@ -194,16 +194,14 @@ void HELPER(divu)(CPUM68KState *env, uint32_t word)
}
quot = num / den;
rem = num % den;
flags = 0;
if (word && quot > 0xffff)
flags |= CCF_V;
if (quot == 0)
flags |= CCF_Z;
else if ((int32_t)quot < 0)
flags |= CCF_N;
env->cc_v = (word && quot > 0xffff ? -1 : 0);
env->cc_z = quot;
env->cc_n = quot;
env->cc_c = 0;
env->div1 = quot;
env->div2 = rem;
env->cc_dest = flags;
}
void HELPER(divs)(CPUM68KState *env, uint32_t word)
@ -212,7 +210,6 @@ void HELPER(divs)(CPUM68KState *env, uint32_t word)
int32_t den;
int32_t quot;
int32_t rem;
int32_t flags;
num = env->div1;
den = env->div2;
@ -221,14 +218,12 @@ void HELPER(divs)(CPUM68KState *env, uint32_t word)
}
quot = num / den;
rem = num % den;
flags = 0;
if (word && quot != (int16_t)quot)
flags |= CCF_V;
if (quot == 0)
flags |= CCF_Z;
else if (quot < 0)
flags |= CCF_N;
env->cc_v = (word && quot != (int16_t)quot ? -1 : 0);
env->cc_z = quot;
env->cc_n = quot;
env->cc_c = 0;
env->div1 = quot;
env->div2 = rem;
env->cc_dest = flags;
}

View file

@ -2,9 +2,11 @@ DEFF64(FP_RESULT, fp_result)
DEFO32(PC, pc)
DEFO32(SR, sr)
DEFO32(CC_OP, cc_op)
DEFO32(CC_DEST, cc_dest)
DEFO32(CC_SRC, cc_src)
DEFO32(CC_X, cc_x)
DEFO32(CC_C, cc_c)
DEFO32(CC_N, cc_n)
DEFO32(CC_V, cc_v)
DEFO32(CC_Z, cc_z)
DEFO32(DIV1, div1)
DEFO32(DIV2, div2)
DEFO32(MACSR, macsr)

File diff suppressed because it is too large Load diff