aboutsummaryrefslogtreecommitdiff
path: root/target/m68k
diff options
context:
space:
mode:
Diffstat (limited to 'target/m68k')
-rw-r--r--target/m68k/Kconfig2
-rw-r--r--target/m68k/cpu-param.h5
-rw-r--r--target/m68k/cpu.c100
-rw-r--r--target/m68k/cpu.h24
-rw-r--r--target/m68k/fpu_helper.c12
-rw-r--r--target/m68k/gdbstub.c2
-rw-r--r--target/m68k/helper.c28
-rw-r--r--target/m68k/meson.build5
-rw-r--r--target/m68k/op_helper.c3
-rw-r--r--target/m68k/semihosting-stub.c18
-rw-r--r--target/m68k/softfloat.c47
-rw-r--r--target/m68k/translate.c20
12 files changed, 173 insertions, 93 deletions
diff --git a/target/m68k/Kconfig b/target/m68k/Kconfig
index 9eae714..23aae24 100644
--- a/target/m68k/Kconfig
+++ b/target/m68k/Kconfig
@@ -1,3 +1,3 @@
config M68K
bool
- select SEMIHOSTING
+ imply SEMIHOSTING if TCG
diff --git a/target/m68k/cpu-param.h b/target/m68k/cpu-param.h
index 39dcbce..256a2b5 100644
--- a/target/m68k/cpu-param.h
+++ b/target/m68k/cpu-param.h
@@ -2,13 +2,12 @@
* m68k cpu parameters for qemu.
*
* Copyright (c) 2005-2007 CodeSourcery
- * SPDX-License-Identifier: LGPL-2.0+
+ * SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef M68K_CPU_PARAM_H
#define M68K_CPU_PARAM_H
-#define TARGET_LONG_BITS 32
/*
* Coldfire Linux uses 8k pages
* and m68k linux uses 4k pages
@@ -18,4 +17,6 @@
#define TARGET_PHYS_ADDR_SPACE_BITS 32
#define TARGET_VIRT_ADDR_SPACE_BITS 32
+#define TARGET_INSN_START_EXTRA_WORDS 1
+
#endif
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 1d49f4c..6a09db3 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -23,6 +23,8 @@
#include "cpu.h"
#include "migration/vmstate.h"
#include "fpu/softfloat.h"
+#include "exec/translation-block.h"
+#include "accel/tcg/cpu-ops.h"
static void m68k_cpu_set_pc(CPUState *cs, vaddr value)
{
@@ -38,6 +40,24 @@ static vaddr m68k_cpu_get_pc(CPUState *cs)
return cpu->env.pc;
}
+static TCGTBCPUState m68k_get_tb_cpu_state(CPUState *cs)
+{
+ CPUM68KState *env = cpu_env(cs);
+ uint32_t flags;
+
+ flags = (env->macsr >> 4) & TB_FLAGS_MACSR;
+ if (env->sr & SR_S) {
+ flags |= TB_FLAGS_MSR_S;
+ flags |= (env->sfc << (TB_FLAGS_SFC_S_BIT - 2)) & TB_FLAGS_SFC_S;
+ flags |= (env->dfc << (TB_FLAGS_DFC_S_BIT - 2)) & TB_FLAGS_DFC_S;
+ }
+ if (M68K_SR_TRACE(env->sr) == M68K_SR_TRACE_ANY_INS) {
+ flags |= TB_FLAGS_TRACE;
+ }
+
+ return (TCGTBCPUState){ .pc = env->pc, .flags = flags };
+}
+
static void m68k_restore_state_to_opc(CPUState *cs,
const TranslationBlock *tb,
const uint64_t *data)
@@ -51,10 +71,12 @@ static void m68k_restore_state_to_opc(CPUState *cs,
}
}
+#ifndef CONFIG_USER_ONLY
static bool m68k_cpu_has_work(CPUState *cs)
{
return cs->interrupt_request & CPU_INTERRUPT_HARD;
}
+#endif /* !CONFIG_USER_ONLY */
static int m68k_cpu_mmu_index(CPUState *cs, bool ifetch)
{
@@ -76,7 +98,7 @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
CPUState *cs = CPU(obj);
M68kCPUClass *mcc = M68K_CPU_GET_CLASS(obj);
CPUM68KState *env = cpu_env(cs);
- floatx80 nan = floatx80_default_nan(NULL);
+ floatx80 nan;
int i;
if (mcc->parent_phases.hold) {
@@ -89,6 +111,61 @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
#else
cpu_m68k_set_sr(env, SR_S | SR_I);
#endif
+ /*
+ * M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL
+ * 3.4 FLOATING-POINT INSTRUCTION DETAILS
+ * If either operand, but not both operands, of an operation is a
+ * nonsignaling NaN, then that NaN is returned as the result. If both
+ * operands are nonsignaling NaNs, then the destination operand
+ * nonsignaling NaN is returned as the result.
+ * If either operand to an operation is a signaling NaN (SNaN), then the
+ * SNaN bit is set in the FPSR EXC byte. If the SNaN exception enable bit
+ * is set in the FPCR ENABLE byte, then the exception is taken and the
+ * destination is not modified. If the SNaN exception enable bit is not
+ * set, setting the SNaN bit in the operand to a one converts the SNaN to
+ * a nonsignaling NaN. The operation then continues as described in the
+ * preceding paragraph for nonsignaling NaNs.
+ */
+ set_float_2nan_prop_rule(float_2nan_prop_ab, &env->fp_status);
+ /* Default NaN: sign bit clear, all frac bits set */
+ set_float_default_nan_pattern(0b01111111, &env->fp_status);
+ /*
+ * m68k-specific floatx80 behaviour:
+ * * default Infinity values have a zero Integer bit
+ * * input Infinities may have the Integer bit either 0 or 1
+ * * pseudo-denormals supported for input and output
+ * * don't raise Invalid for pseudo-NaN/pseudo-Inf/Unnormal
+ *
+ * With m68k, the explicit integer bit can be zero in the case of:
+ * - zeros (exp == 0, mantissa == 0)
+ * - denormalized numbers (exp == 0, mantissa != 0)
+ * - unnormalized numbers (exp != 0, exp < 0x7FFF)
+ * - infinities (exp == 0x7FFF, mantissa == 0)
+ * - not-a-numbers (exp == 0x7FFF, mantissa != 0)
+ *
+ * For infinities and NaNs, the explicit integer bit can be either one or
+ * zero.
+ *
+ * The IEEE 754 standard does not define a zero integer bit. Such a number
+ * is an unnormalized number. Hardware does not directly support
+ * denormalized and unnormalized numbers, but implicitly supports them by
+ * trapping them as unimplemented data types, allowing efficient conversion
+ * in software.
+ *
+ * See "M68000 FAMILY PROGRAMMER’S REFERENCE MANUAL",
+ * "1.6 FLOATING-POINT DATA TYPES"
+ *
+ * Note though that QEMU's fp emulation does directly handle both
+ * denormal and unnormal values, and does not trap to guest software.
+ */
+ set_floatx80_behaviour(floatx80_default_inf_int_bit_is_zero |
+ floatx80_pseudo_inf_valid |
+ floatx80_pseudo_nan_valid |
+ floatx80_unnormal_valid |
+ floatx80_pseudo_denormal_valid,
+ &env->fp_status);
+
+ nan = floatx80_default_nan(&env->fp_status);
for (i = 0; i < 8; i++) {
env->fregs[i].d = nan;
}
@@ -102,6 +179,7 @@ static void m68k_cpu_reset_hold(Object *obj, ResetType type)
static void m68k_cpu_disas_set_info(CPUState *s, disassemble_info *info)
{
info->print_insn = print_insn_m68k;
+ info->endian = BFD_ENDIAN_BIG;
info->mach = 0;
}
@@ -523,26 +601,34 @@ static const VMStateDescription vmstate_m68k_cpu = {
#include "hw/core/sysemu-cpu-ops.h"
static const struct SysemuCPUOps m68k_sysemu_ops = {
+ .has_work = m68k_cpu_has_work,
.get_phys_page_debug = m68k_cpu_get_phys_page_debug,
};
#endif /* !CONFIG_USER_ONLY */
-#include "hw/core/tcg-cpu-ops.h"
-
static const TCGCPUOps m68k_tcg_ops = {
+ /* MTTCG not yet supported: require strict ordering */
+ .guest_default_memory_order = TCG_MO_ALL,
+ .mttcg_supported = false,
+
.initialize = m68k_tcg_init,
+ .translate_code = m68k_translate_code,
+ .get_tb_cpu_state = m68k_get_tb_cpu_state,
.restore_state_to_opc = m68k_restore_state_to_opc,
+ .mmu_index = m68k_cpu_mmu_index,
#ifndef CONFIG_USER_ONLY
.tlb_fill = m68k_cpu_tlb_fill,
+ .pointer_wrap = cpu_pointer_wrap_uint32,
.cpu_exec_interrupt = m68k_cpu_exec_interrupt,
.cpu_exec_halt = m68k_cpu_has_work,
+ .cpu_exec_reset = cpu_reset,
.do_interrupt = m68k_cpu_do_interrupt,
.do_transaction_failed = m68k_cpu_transaction_failed,
#endif /* !CONFIG_USER_ONLY */
};
-static void m68k_cpu_class_init(ObjectClass *c, void *data)
+static void m68k_cpu_class_init(ObjectClass *c, const void *data)
{
M68kCPUClass *mcc = M68K_CPU_CLASS(c);
CPUClass *cc = CPU_CLASS(c);
@@ -555,8 +641,6 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
&mcc->parent_phases);
cc->class_by_name = m68k_cpu_class_by_name;
- cc->has_work = m68k_cpu_has_work;
- cc->mmu_index = m68k_cpu_mmu_index;
cc->dump_state = m68k_cpu_dump_state;
cc->set_pc = m68k_cpu_set_pc;
cc->get_pc = m68k_cpu_get_pc;
@@ -571,7 +655,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
cc->tcg_ops = &m68k_tcg_ops;
}
-static void m68k_cpu_class_init_cf_core(ObjectClass *c, void *data)
+static void m68k_cpu_class_init_cf_core(ObjectClass *c, const void *data)
{
CPUClass *cc = CPU_CLASS(c);
@@ -586,7 +670,7 @@ static void m68k_cpu_class_init_cf_core(ObjectClass *c, void *data)
.class_init = m68k_cpu_class_init_cf_core \
}
-static void m68k_cpu_class_init_m68k_core(ObjectClass *c, void *data)
+static void m68k_cpu_class_init_m68k_core(ObjectClass *c, const void *data)
{
CPUClass *cc = CPU_CLASS(c);
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index b5bbeed..d9db6a4 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -21,7 +21,9 @@
#ifndef M68K_CPU_H
#define M68K_CPU_H
+#include "exec/cpu-common.h"
#include "exec/cpu-defs.h"
+#include "exec/cpu-interrupt.h"
#include "qemu/cpu-float.h"
#include "cpu-qom.h"
@@ -76,8 +78,6 @@
#define M68K_MAX_TTR 2
#define TTR(type, index) ttr[((type & ACCESS_CODE) == ACCESS_CODE) * 2 + index]
-#define TARGET_INSN_START_EXTRA_WORDS 1
-
typedef CPU_LDoubleU FPReg;
typedef struct CPUArchState {
@@ -193,6 +193,8 @@ int m68k_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int m68k_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void m68k_tcg_init(void);
+void m68k_translate_code(CPUState *cs, TranslationBlock *tb,
+ int *max_insns, vaddr pc, void *host_pc);
void m68k_cpu_init_gdb(M68kCPU *cpu);
uint32_t cpu_m68k_get_ccr(CPUM68KState *env);
void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t);
@@ -592,8 +594,6 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
MemTxResult response, uintptr_t retaddr);
#endif
-#include "exec/cpu-all.h"
-
/* TB flags */
#define TB_FLAGS_MACSR 0x0f
#define TB_FLAGS_MSR_S_BIT 13
@@ -605,22 +605,6 @@ void m68k_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
#define TB_FLAGS_TRACE 16
#define TB_FLAGS_TRACE_BIT (1 << TB_FLAGS_TRACE)
-static inline void cpu_get_tb_cpu_state(CPUM68KState *env, vaddr *pc,
- uint64_t *cs_base, uint32_t *flags)
-{
- *pc = env->pc;
- *cs_base = 0;
- *flags = (env->macsr >> 4) & TB_FLAGS_MACSR;
- if (env->sr & SR_S) {
- *flags |= TB_FLAGS_MSR_S;
- *flags |= (env->sfc << (TB_FLAGS_SFC_S_BIT - 2)) & TB_FLAGS_SFC_S;
- *flags |= (env->dfc << (TB_FLAGS_DFC_S_BIT - 2)) & TB_FLAGS_DFC_S;
- }
- if (M68K_SR_TRACE(env->sr) == M68K_SR_TRACE_ANY_INS) {
- *flags |= TB_FLAGS_TRACE;
- }
-}
-
void dump_mmu(CPUM68KState *env);
#endif
diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c
index 8314791..5601286 100644
--- a/target/m68k/fpu_helper.c
+++ b/target/m68k/fpu_helper.c
@@ -21,8 +21,7 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
+#include "accel/tcg/cpu-ldst.h"
#include "softfloat.h"
/*
@@ -175,7 +174,7 @@ static int cpu_m68k_exceptbits_from_host(int host_bits)
if (host_bits & float_flag_overflow) {
target_bits |= 0x40;
}
- if (host_bits & (float_flag_underflow | float_flag_output_denormal)) {
+ if (host_bits & (float_flag_underflow | float_flag_output_denormal_flushed)) {
target_bits |= 0x20;
}
if (host_bits & float_flag_divbyzero) {
@@ -455,7 +454,7 @@ void HELPER(ftst)(CPUM68KState *env, FPReg *val)
if (floatx80_is_any_nan(val->d)) {
cc |= FPSR_CC_A;
- } else if (floatx80_is_infinity(val->d)) {
+ } else if (floatx80_is_infinity(val->d, &env->fp_status)) {
cc |= FPSR_CC_I;
} else if (floatx80_is_zero(val->d)) {
cc |= FPSR_CC_Z;
@@ -615,14 +614,13 @@ void HELPER(frem)(CPUM68KState *env, FPReg *res, FPReg *val0, FPReg *val1)
fp_rem = floatx80_rem(val1->d, val0->d, &env->fp_status);
if (!floatx80_is_any_nan(fp_rem)) {
- float_status fp_status = { };
+ /* Use local temporary fp_status to set different rounding mode */
+ float_status fp_status = env->fp_status;
uint32_t quotient;
int sign;
/* Calculate quotient directly using round to nearest mode */
set_float_rounding_mode(float_round_nearest_even, &fp_status);
- set_floatx80_rounding_precision(
- get_floatx80_rounding_precision(&env->fp_status), &fp_status);
fp_quot.d = floatx80_div(val1->d, val0->d, &fp_status);
sign = extractFloatx80Sign(fp_quot.d);
diff --git a/target/m68k/gdbstub.c b/target/m68k/gdbstub.c
index 15547e2..136159f 100644
--- a/target/m68k/gdbstub.c
+++ b/target/m68k/gdbstub.c
@@ -52,7 +52,7 @@ int m68k_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
CPUM68KState *env = cpu_env(cs);
uint32_t tmp;
- tmp = ldl_p(mem_buf);
+ tmp = ldl_be_p(mem_buf);
if (n < 8) {
/* D0-D7 */
diff --git a/target/m68k/helper.c b/target/m68k/helper.c
index 7967ad1..15f110f 100644
--- a/target/m68k/helper.c
+++ b/target/m68k/helper.c
@@ -20,10 +20,12 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/exec-all.h"
+#include "exec/cputlb.h"
#include "exec/page-protection.h"
+#include "exec/target_page.h"
#include "exec/gdbstub.h"
#include "exec/helper-proto.h"
+#include "system/memory.h"
#include "gdbstub/helpers.h"
#include "fpu/softfloat.h"
#include "qemu/qemu-print.h"
@@ -36,7 +38,8 @@ static int cf_fpu_gdb_get_reg(CPUState *cs, GByteArray *mem_buf, int n)
CPUM68KState *env = &cpu->env;
if (n < 8) {
- float_status s;
+ /* Use scratch float_status so any exceptions don't change CPU state */
+ float_status s = env->fp_status;
return gdb_get_reg64(mem_buf, floatx80_to_float64(env->fregs[n].d, &s));
}
switch (n) {
@@ -56,16 +59,17 @@ static int cf_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
CPUM68KState *env = &cpu->env;
if (n < 8) {
- float_status s;
- env->fregs[n].d = float64_to_floatx80(ldq_p(mem_buf), &s);
+ /* Use scratch float_status so any exceptions don't change CPU state */
+ float_status s = env->fp_status;
+ env->fregs[n].d = float64_to_floatx80(ldq_be_p(mem_buf), &s);
return 8;
}
switch (n) {
case 8: /* fpcontrol */
- cpu_m68k_set_fpcr(env, ldl_p(mem_buf));
+ cpu_m68k_set_fpcr(env, ldl_be_p(mem_buf));
return 4;
case 9: /* fpstatus */
- env->fpsr = ldl_p(mem_buf);
+ env->fpsr = ldl_be_p(mem_buf);
return 4;
case 10: /* fpiar, not implemented */
return 4;
@@ -107,10 +111,10 @@ static int m68k_fpu_gdb_set_reg(CPUState *cs, uint8_t *mem_buf, int n)
}
switch (n) {
case 8: /* fpcontrol */
- cpu_m68k_set_fpcr(env, ldl_p(mem_buf));
+ cpu_m68k_set_fpcr(env, ldl_be_p(mem_buf));
return 4;
case 9: /* fpstatus */
- cpu_m68k_set_fpsr(env, ldl_p(mem_buf));
+ cpu_m68k_set_fpsr(env, ldl_be_p(mem_buf));
return 4;
case 10: /* fpiar, not implemented */
return 4;
@@ -287,7 +291,6 @@ void HELPER(m68k_movec_to)(CPUM68KState *env, uint32_t reg, uint32_t val)
/* Invalid control registers will generate an exception. */
raise_exception_ra(env, EXCP_ILLEGAL, 0);
- return;
}
uint32_t HELPER(m68k_movec_from)(CPUM68KState *env, uint32_t reg)
@@ -479,7 +482,6 @@ static void print_address_zone(uint32_t logical, uint32_t physical,
static void dump_address_map(CPUM68KState *env, uint32_t root_pointer)
{
- int i, j, k;
int tic_size, tic_shift;
uint32_t tib_mask;
uint32_t tia, tib, tic;
@@ -502,19 +504,19 @@ static void dump_address_map(CPUM68KState *env, uint32_t root_pointer)
tic_shift = 12;
tib_mask = M68K_4K_PAGE_MASK;
}
- for (i = 0; i < M68K_ROOT_POINTER_ENTRIES; i++) {
+ for (unsigned i = 0; i < M68K_ROOT_POINTER_ENTRIES; i++) {
tia = address_space_ldl(cs->as, M68K_POINTER_BASE(root_pointer) + i * 4,
MEMTXATTRS_UNSPECIFIED, &txres);
if (txres != MEMTX_OK || !M68K_UDT_VALID(tia)) {
continue;
}
- for (j = 0; j < M68K_ROOT_POINTER_ENTRIES; j++) {
+ for (unsigned j = 0; j < M68K_ROOT_POINTER_ENTRIES; j++) {
tib = address_space_ldl(cs->as, M68K_POINTER_BASE(tia) + j * 4,
MEMTXATTRS_UNSPECIFIED, &txres);
if (txres != MEMTX_OK || !M68K_UDT_VALID(tib)) {
continue;
}
- for (k = 0; k < tic_size; k++) {
+ for (unsigned k = 0; k < tic_size; k++) {
tic = address_space_ldl(cs->as, (tib & tib_mask) + k * 4,
MEMTXATTRS_UNSPECIFIED, &txres);
if (txres != MEMTX_OK || !M68K_PDT_VALID(tic)) {
diff --git a/target/m68k/meson.build b/target/m68k/meson.build
index 8d3f9ce..4d213da 100644
--- a/target/m68k/meson.build
+++ b/target/m68k/meson.build
@@ -11,9 +11,12 @@ m68k_ss.add(files(
m68k_system_ss = ss.source_set()
m68k_system_ss.add(files(
- 'm68k-semi.c',
'monitor.c'
))
+m68k_system_ss.add(when: ['CONFIG_SEMIHOSTING'],
+ if_true: files('m68k-semi.c'),
+ if_false: files('semihosting-stub.c')
+)
target_arch += {'m68k': m68k_ss}
target_system_arch += {'m68k': m68k_system_ss}
diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c
index 15bad5d..f29ae12 100644
--- a/target/m68k/op_helper.c
+++ b/target/m68k/op_helper.c
@@ -20,8 +20,7 @@
#include "qemu/log.h"
#include "cpu.h"
#include "exec/helper-proto.h"
-#include "exec/exec-all.h"
-#include "exec/cpu_ldst.h"
+#include "accel/tcg/cpu-ldst.h"
#include "semihosting/semihost.h"
#if !defined(CONFIG_USER_ONLY)
diff --git a/target/m68k/semihosting-stub.c b/target/m68k/semihosting-stub.c
new file mode 100644
index 0000000..dbe669c
--- /dev/null
+++ b/target/m68k/semihosting-stub.c
@@ -0,0 +1,18 @@
+/*
+ * m68k/ColdFire semihosting stub
+ *
+ * Copyright (c) 2024 Linaro Ltd.
+ *
+ * Authors:
+ * Philippe Mathieu-Daudé
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+
+void do_m68k_semihosting(CPUM68KState *env, int nr)
+{
+ g_assert_not_reached();
+}
diff --git a/target/m68k/softfloat.c b/target/m68k/softfloat.c
index 02dcc03..d1f150e 100644
--- a/target/m68k/softfloat.c
+++ b/target/m68k/softfloat.c
@@ -142,8 +142,7 @@ floatx80 floatx80_scale(floatx80 a, floatx80 b, float_status *status)
if ((uint64_t) (aSig << 1)) {
return propagateFloatx80NaN(a, b, status);
}
- return packFloatx80(aSign, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(aSign, status);
}
if (aExp == 0) {
if (aSig == 0) {
@@ -245,7 +244,7 @@ floatx80 floatx80_lognp1(floatx80 a, float_status *status)
float_raise(float_flag_invalid, status);
return floatx80_default_nan(status);
}
- return packFloatx80(0, floatx80_infinity.high, floatx80_infinity.low);
+ return floatx80_default_inf(0, status);
}
if (aExp == 0 && aSig == 0) {
@@ -255,8 +254,7 @@ floatx80 floatx80_lognp1(floatx80 a, float_status *status)
if (aSign && aExp >= one_exp) {
if (aExp == one_exp && aSig == one_sig) {
float_raise(float_flag_divbyzero, status);
- return packFloatx80(aSign, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(aSign, status);
}
float_raise(float_flag_invalid, status);
return floatx80_default_nan(status);
@@ -442,8 +440,7 @@ floatx80 floatx80_logn(floatx80 a, float_status *status)
propagateFloatx80NaNOneArg(a, status);
}
if (aSign == 0) {
- return packFloatx80(0, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(0, status);
}
}
@@ -452,8 +449,7 @@ floatx80 floatx80_logn(floatx80 a, float_status *status)
if (aExp == 0) {
if (aSig == 0) { /* zero */
float_raise(float_flag_divbyzero, status);
- return packFloatx80(1, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(1, status);
}
if ((aSig & one_sig) == 0) { /* denormal */
normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
@@ -610,15 +606,13 @@ floatx80 floatx80_log10(floatx80 a, float_status *status)
propagateFloatx80NaNOneArg(a, status);
}
if (aSign == 0) {
- return packFloatx80(0, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(0, status);
}
}
if (aExp == 0 && aSig == 0) {
float_raise(float_flag_divbyzero, status);
- return packFloatx80(1, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(1, status);
}
if (aSign) {
@@ -668,16 +662,14 @@ floatx80 floatx80_log2(floatx80 a, float_status *status)
propagateFloatx80NaNOneArg(a, status);
}
if (aSign == 0) {
- return packFloatx80(0, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(0, status);
}
}
if (aExp == 0) {
if (aSig == 0) {
float_raise(float_flag_divbyzero, status);
- return packFloatx80(1, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(1, status);
}
normalizeFloatx80Subnormal(aSig, &aExp, &aSig);
}
@@ -740,8 +732,7 @@ floatx80 floatx80_etox(floatx80 a, float_status *status)
if (aSign) {
return packFloatx80(0, 0, 0);
}
- return packFloatx80(0, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(0, status);
}
if (aExp == 0 && aSig == 0) {
@@ -924,8 +915,7 @@ floatx80 floatx80_twotox(floatx80 a, float_status *status)
if (aSign) {
return packFloatx80(0, 0, 0);
}
- return packFloatx80(0, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(0, status);
}
if (aExp == 0 && aSig == 0) {
@@ -1075,8 +1065,7 @@ floatx80 floatx80_tentox(floatx80 a, float_status *status)
if (aSign) {
return packFloatx80(0, 0, 0);
}
- return packFloatx80(0, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(0, status);
}
if (aExp == 0 && aSig == 0) {
@@ -2260,8 +2249,7 @@ floatx80 floatx80_atanh(floatx80 a, float_status *status)
if (compact >= 0x3FFF8000) { /* |X| >= 1 */
if (aExp == one_exp && aSig == one_sig) { /* |X| == 1 */
float_raise(float_flag_divbyzero, status);
- return packFloatx80(aSign, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(aSign, status);
} else { /* |X| > 1 */
float_raise(float_flag_invalid, status);
return floatx80_default_nan(status);
@@ -2320,8 +2308,7 @@ floatx80 floatx80_etoxm1(floatx80 a, float_status *status)
if (aSign) {
return packFloatx80(aSign, one_exp, one_sig);
}
- return packFloatx80(0, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(0, status);
}
if (aExp == 0 && aSig == 0) {
@@ -2687,8 +2674,7 @@ floatx80 floatx80_sinh(floatx80 a, float_status *status)
if ((uint64_t) (aSig << 1)) {
return propagateFloatx80NaNOneArg(a, status);
}
- return packFloatx80(aSign, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(aSign, status);
}
if (aExp == 0 && aSig == 0) {
@@ -2774,8 +2760,7 @@ floatx80 floatx80_cosh(floatx80 a, float_status *status)
if ((uint64_t) (aSig << 1)) {
return propagateFloatx80NaNOneArg(a, status);
}
- return packFloatx80(0, floatx80_infinity.high,
- floatx80_infinity.low);
+ return floatx80_default_inf(0, status);
}
if (aExp == 0 && aSig == 0) {
diff --git a/target/m68k/translate.c b/target/m68k/translate.c
index 445966f..97afceb 100644
--- a/target/m68k/translate.c
+++ b/target/m68k/translate.c
@@ -20,7 +20,8 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/exec-all.h"
+#include "exec/translation-block.h"
+#include "exec/target_page.h"
#include "tcg/tcg-op.h"
#include "qemu/log.h"
#include "qemu/qemu-print.h"
@@ -720,7 +721,9 @@ static TCGv gen_lea_mode(CPUM68KState *env, DisasContext *s,
}
/* fallthru */
case 2: /* Indirect register */
- return get_areg(s, reg0);
+ tmp = tcg_temp_new();
+ tcg_gen_mov_i32(tmp, get_areg(s, reg0));
+ return tmp;
case 4: /* Indirect predecrememnt. */
if (opsize == OS_UNSIZED) {
return NULL_QREG;
@@ -747,20 +750,23 @@ static TCGv gen_lea_mode(CPUM68KState *env, DisasContext *s,
switch (reg0) {
case 0: /* Absolute short. */
offset = (int16_t)read_im16(env, s);
- return tcg_constant_i32(offset);
+ break;
case 1: /* Absolute long. */
offset = read_im32(env, s);
- return tcg_constant_i32(offset);
+ break;
case 2: /* pc displacement */
offset = s->pc;
offset += (int16_t)read_im16(env, s);
- return tcg_constant_i32(offset);
+ break;
case 3: /* pc index+displacement. */
return gen_lea_indexed(env, s, NULL_QREG);
case 4: /* Immediate. */
default:
return NULL_QREG;
}
+ tmp = tcg_temp_new();
+ tcg_gen_movi_i32(tmp, offset);
+ return tmp;
}
/* Should never happen. */
return NULL_QREG;
@@ -6112,8 +6118,8 @@ static const TranslatorOps m68k_tr_ops = {
.tb_stop = m68k_tr_tb_stop,
};
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
- vaddr pc, void *host_pc)
+void m68k_translate_code(CPUState *cpu, TranslationBlock *tb,
+ int *max_insns, vaddr pc, void *host_pc)
{
DisasContext dc;
translator_loop(cpu, tb, max_insns, pc, host_pc, &m68k_tr_ops, &dc.base);