aboutsummaryrefslogtreecommitdiff
path: root/target/hppa
diff options
context:
space:
mode:
Diffstat (limited to 'target/hppa')
-rw-r--r--target/hppa/cpu-param.h8
-rw-r--r--target/hppa/cpu.c31
-rw-r--r--target/hppa/cpu.h12
-rw-r--r--target/hppa/fpu_helper.c21
-rw-r--r--target/hppa/helper.c1
-rw-r--r--target/hppa/int_helper.c4
-rw-r--r--target/hppa/machine.c2
-rw-r--r--target/hppa/mem_helper.c4
-rw-r--r--target/hppa/op_helper.c4
-rw-r--r--target/hppa/sys_helper.c1
-rw-r--r--target/hppa/translate.c19
11 files changed, 59 insertions, 48 deletions
diff --git a/target/hppa/cpu-param.h b/target/hppa/cpu-param.h
index 7ed6b57..9bf7ac7 100644
--- a/target/hppa/cpu-param.h
+++ b/target/hppa/cpu-param.h
@@ -19,12 +19,6 @@
#define TARGET_PAGE_BITS 12
-/* PA-RISC 1.x processors have a strong memory model. */
-/*
- * ??? While we do not yet implement PA-RISC 2.0, those processors have
- * a weak memory model, but with TLB bits that force ordering on a per-page
- * basis. It's probably easier to fall back to a strong memory model.
- */
-#define TCG_GUEST_DEFAULT_MO TCG_MO_ALL
+#define TARGET_INSN_START_EXTRA_WORDS 2
#endif
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 2a85495..2477772 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -24,11 +24,12 @@
#include "qemu/timer.h"
#include "cpu.h"
#include "qemu/module.h"
-#include "exec/exec-all.h"
#include "exec/translation-block.h"
+#include "exec/target_page.h"
#include "fpu/softfloat.h"
#include "tcg/tcg.h"
#include "hw/hppa/hppa_hardware.h"
+#include "accel/tcg/cpu-ops.h"
static void hppa_cpu_set_pc(CPUState *cs, vaddr value)
{
@@ -50,11 +51,12 @@ static vaddr hppa_cpu_get_pc(CPUState *cs)
env->iaoq_f & -4);
}
-void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
- uint64_t *pcsbase, uint32_t *pflags)
+static TCGTBCPUState hppa_get_tb_cpu_state(CPUState *cs)
{
+ CPUHPPAState *env = cpu_env(cs);
uint32_t flags = 0;
uint64_t cs_base = 0;
+ vaddr pc;
/*
* TB lookup assumes that PC contains the complete virtual address.
@@ -62,7 +64,7 @@ void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
* incomplete virtual address. This also means that we must separate
* out current cpu privilege from the low bits of IAOQ_F.
*/
- *pc = hppa_cpu_get_pc(env_cpu(env));
+ pc = hppa_cpu_get_pc(env_cpu(env));
flags |= (env->iaoq_f & 3) << TB_FLAG_PRIV_SHIFT;
/*
@@ -98,8 +100,7 @@ void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
}
#endif
- *pcsbase = cs_base;
- *pflags = flags;
+ return (TCGTBCPUState){ .pc = pc, .flags = flags, .cs_base = cs_base };
}
static void hppa_cpu_synchronize_from_tb(CPUState *cs,
@@ -249,25 +250,36 @@ static const struct SysemuCPUOps hppa_sysemu_ops = {
};
#endif
-#include "accel/tcg/cpu-ops.h"
-
static const TCGCPUOps hppa_tcg_ops = {
+ /* PA-RISC 1.x processors have a strong memory model. */
+ /*
+ * ??? While we do not yet implement PA-RISC 2.0, those processors have
+ * a weak memory model, but with TLB bits that force ordering on a per-page
+ * basis. It's probably easier to fall back to a strong memory model.
+ */
+ .guest_default_memory_order = TCG_MO_ALL,
+ .mttcg_supported = true,
+
.initialize = hppa_translate_init,
.translate_code = hppa_translate_code,
+ .get_tb_cpu_state = hppa_get_tb_cpu_state,
.synchronize_from_tb = hppa_cpu_synchronize_from_tb,
.restore_state_to_opc = hppa_restore_state_to_opc,
+ .mmu_index = hppa_cpu_mmu_index,
#ifndef CONFIG_USER_ONLY
.tlb_fill_align = hppa_cpu_tlb_fill_align,
+ .pointer_wrap = cpu_pointer_wrap_notreached,
.cpu_exec_interrupt = hppa_cpu_exec_interrupt,
.cpu_exec_halt = hppa_cpu_has_work,
+ .cpu_exec_reset = cpu_reset,
.do_interrupt = hppa_cpu_do_interrupt,
.do_unaligned_access = hppa_cpu_do_unaligned_access,
.do_transaction_failed = hppa_cpu_do_transaction_failed,
#endif /* !CONFIG_USER_ONLY */
};
-static void hppa_cpu_class_init(ObjectClass *oc, void *data)
+static void hppa_cpu_class_init(ObjectClass *oc, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
@@ -281,7 +293,6 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
&acc->parent_phases);
cc->class_by_name = hppa_cpu_class_by_name;
- cc->mmu_index = hppa_cpu_mmu_index;
cc->dump_state = hppa_cpu_dump_state;
cc->set_pc = hppa_cpu_set_pc;
cc->get_pc = hppa_cpu_get_pc;
diff --git a/target/hppa/cpu.h b/target/hppa/cpu.h
index 7be4a1d..11d59d1 100644
--- a/target/hppa/cpu.h
+++ b/target/hppa/cpu.h
@@ -21,7 +21,10 @@
#define HPPA_CPU_H
#include "cpu-qom.h"
+#include "exec/cpu-common.h"
#include "exec/cpu-defs.h"
+#include "exec/cpu-interrupt.h"
+#include "system/memory.h"
#include "qemu/cpu-float.h"
#include "qemu/interval-tree.h"
#include "hw/registerfields.h"
@@ -45,8 +48,6 @@
#define PRIV_KERNEL 0
#define PRIV_USER 3
-#define TARGET_INSN_START_EXTRA_WORDS 2
-
/* No need to flush MMU_ABS*_IDX */
#define HPPA_MMU_FLUSH_MASK \
(1 << MMU_KERNEL_IDX | 1 << MMU_KERNEL_P_IDX | \
@@ -303,8 +304,6 @@ struct HPPACPUClass {
ResettablePhases parent_phases;
};
-#include "exec/cpu-all.h"
-
static inline bool hppa_is_pa20(const CPUHPPAState *env)
{
return env->is_pa20;
@@ -352,9 +351,6 @@ hwaddr hppa_abs_to_phys_pa2_w1(vaddr addr);
#define CS_BASE_DIFFPAGE (1 << 12)
#define CS_BASE_DIFFSPACE (1 << 13)
-void cpu_get_tb_cpu_state(CPUHPPAState *env, vaddr *pc,
- uint64_t *cs_base, uint32_t *pflags);
-
target_ulong cpu_hppa_get_psw(CPUHPPAState *env);
void cpu_hppa_put_psw(CPUHPPAState *env, target_ulong);
void update_gva_offset_mask(CPUHPPAState *env);
@@ -391,6 +387,4 @@ void hppa_cpu_alarm_timer(void *);
#endif
G_NORETURN void hppa_dynamic_excp(CPUHPPAState *env, int excp, uintptr_t ra);
-#define CPU_RESOLVING_TYPE TYPE_HPPA_CPU
-
#endif /* HPPA_CPU_H */
diff --git a/target/hppa/fpu_helper.c b/target/hppa/fpu_helper.c
index a62d9d3..4535320 100644
--- a/target/hppa/fpu_helper.c
+++ b/target/hppa/fpu_helper.c
@@ -19,7 +19,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/exec-all.h"
#include "exec/helper-proto.h"
#include "fpu/softfloat.h"
@@ -95,7 +94,8 @@ static void update_fr0_op(CPUHPPAState *env, uintptr_t ra)
{
uint32_t soft_exp = get_float_exception_flags(&env->fp_status);
uint32_t hard_exp = 0;
- uint32_t shadow = env->fr0_shadow;
+ uint32_t shadow = env->fr0_shadow & 0x3ffffff;
+ uint32_t fr1 = 0;
if (likely(soft_exp == 0)) {
env->fr[0] = (uint64_t)shadow << 32;
@@ -108,9 +108,22 @@ static void update_fr0_op(CPUHPPAState *env, uintptr_t ra)
hard_exp |= CONVERT_BIT(soft_exp, float_flag_overflow, R_FPSR_ENA_O_MASK);
hard_exp |= CONVERT_BIT(soft_exp, float_flag_divbyzero, R_FPSR_ENA_Z_MASK);
hard_exp |= CONVERT_BIT(soft_exp, float_flag_invalid, R_FPSR_ENA_V_MASK);
- shadow |= hard_exp << (R_FPSR_FLAGS_SHIFT - R_FPSR_ENABLES_SHIFT);
+ if (hard_exp & shadow) {
+ shadow = FIELD_DP32(shadow, FPSR, T, 1);
+ /* fill exception register #1, which is lower 32-bits of fr[0] */
+#if !defined(CONFIG_USER_ONLY)
+ if (hard_exp & (R_FPSR_ENA_O_MASK | R_FPSR_ENA_U_MASK)) {
+ /* over- and underflow both set overflow flag only */
+ fr1 = FIELD_DP32(fr1, FPSR, C, 1);
+ fr1 = FIELD_DP32(fr1, FPSR, FLG_O, 1);
+ } else
+#endif
+ {
+ fr1 |= hard_exp << (R_FPSR_FLAGS_SHIFT - R_FPSR_ENABLES_SHIFT);
+ }
+ }
env->fr0_shadow = shadow;
- env->fr[0] = (uint64_t)shadow << 32;
+ env->fr[0] = (uint64_t)shadow << 32 | fr1;
if (hard_exp & shadow) {
hppa_dynamic_excp(env, EXCP_ASSIST, ra);
diff --git a/target/hppa/helper.c b/target/hppa/helper.c
index ac7f58f..d7f8495 100644
--- a/target/hppa/helper.c
+++ b/target/hppa/helper.c
@@ -21,7 +21,6 @@
#include "qemu/log.h"
#include "cpu.h"
#include "fpu/softfloat.h"
-#include "exec/exec-all.h"
#include "exec/helper-proto.h"
#include "qemu/qemu-print.h"
#include "hw/hppa/hppa_hardware.h"
diff --git a/target/hppa/int_helper.c b/target/hppa/int_helper.c
index 7d48643..191ae19 100644
--- a/target/hppa/int_helper.c
+++ b/target/hppa/int_helper.c
@@ -177,6 +177,10 @@ void hppa_cpu_do_interrupt(CPUState *cs)
}
}
env->cr[CR_IIR] = ldl_phys(cs->as, paddr);
+ if (i == EXCP_ASSIST) {
+ /* stuff insn code into bits of FP exception register #1 */
+ env->fr[0] |= (env->cr[CR_IIR] & 0x03ffffff);
+ }
}
break;
diff --git a/target/hppa/machine.c b/target/hppa/machine.c
index bb47a2e..13e5551 100644
--- a/target/hppa/machine.c
+++ b/target/hppa/machine.c
@@ -216,7 +216,7 @@ static const VMStateDescription vmstate_env = {
};
static const VMStateField vmstate_cpu_fields[] = {
- VMSTATE_CPU(),
+ VMSTATE_STRUCT(parent_obj, HPPACPU, 0, vmstate_cpu_common, CPUState),
VMSTATE_STRUCT(env, HPPACPU, 1, vmstate_env, CPUHPPAState),
VMSTATE_END_OF_LIST()
};
diff --git a/target/hppa/mem_helper.c b/target/hppa/mem_helper.c
index fb1d93e..9bdd0a6 100644
--- a/target/hppa/mem_helper.c
+++ b/target/hppa/mem_helper.c
@@ -20,9 +20,11 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h"
-#include "exec/exec-all.h"
#include "exec/cputlb.h"
+#include "accel/tcg/cpu-mmu-index.h"
+#include "accel/tcg/probe.h"
#include "exec/page-protection.h"
+#include "exec/target_page.h"
#include "exec/helper-proto.h"
#include "hw/core/cpu.h"
#include "trace.h"
diff --git a/target/hppa/op_helper.c b/target/hppa/op_helper.c
index beb8f88..0458378 100644
--- a/target/hppa/op_helper.c
+++ b/target/hppa/op_helper.c
@@ -20,9 +20,9 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h"
-#include "exec/exec-all.h"
#include "exec/helper-proto.h"
-#include "exec/cpu_ldst.h"
+#include "accel/tcg/cpu-ldst.h"
+#include "accel/tcg/probe.h"
#include "qemu/timer.h"
#include "trace.h"
#ifdef CONFIG_USER_ONLY
diff --git a/target/hppa/sys_helper.c b/target/hppa/sys_helper.c
index 052a6a8..6e65fad 100644
--- a/target/hppa/sys_helper.c
+++ b/target/hppa/sys_helper.c
@@ -20,7 +20,6 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h"
-#include "exec/exec-all.h"
#include "exec/helper-proto.h"
#include "qemu/timer.h"
#include "system/runstate.h"
diff --git a/target/hppa/translate.c b/target/hppa/translate.c
index 0d0d1bc..7a81cfc 100644
--- a/target/hppa/translate.c
+++ b/target/hppa/translate.c
@@ -20,7 +20,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "qemu/host-utils.h"
-#include "exec/exec-all.h"
#include "exec/page-protection.h"
#include "tcg/tcg-op.h"
#include "tcg/tcg-op-gvec.h"
@@ -28,6 +27,7 @@
#include "exec/helper-gen.h"
#include "exec/translator.h"
#include "exec/translation-block.h"
+#include "exec/target_page.h"
#include "exec/log.h"
#define HELPER_H "helper.h"
@@ -1208,10 +1208,10 @@ static void do_add(DisasContext *ctx, unsigned rt, TCGv_i64 orig_in1,
cb_msb = tcg_temp_new_i64();
cb = tcg_temp_new_i64();
- tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, in2, ctx->zero);
if (is_c) {
- tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb,
- get_psw_carry(ctx, d), ctx->zero);
+ tcg_gen_addcio_i64(dest, cb_msb, in1, in2, get_psw_carry(ctx, d));
+ } else {
+ tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, in2, ctx->zero);
}
tcg_gen_xor_i64(cb, in1, in2);
tcg_gen_xor_i64(cb, cb, dest);
@@ -1307,9 +1307,7 @@ static void do_sub(DisasContext *ctx, unsigned rt, TCGv_i64 in1,
if (is_b) {
/* DEST,C = IN1 + ~IN2 + C. */
tcg_gen_not_i64(cb, in2);
- tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero,
- get_psw_carry(ctx, d), ctx->zero);
- tcg_gen_add2_i64(dest, cb_msb, dest, cb_msb, cb, ctx->zero);
+ tcg_gen_addcio_i64(dest, cb_msb, in1, cb, get_psw_carry(ctx, d));
tcg_gen_xor_i64(cb, cb, in1);
tcg_gen_xor_i64(cb, cb, dest);
} else {
@@ -3007,9 +3005,7 @@ static bool trans_ds(DisasContext *ctx, arg_rrr_cf *a)
tcg_gen_xor_i64(add2, in2, addc);
tcg_gen_andi_i64(addc, addc, 1);
- tcg_gen_add2_i64(dest, cpu_psw_cb_msb, add1, ctx->zero, add2, ctx->zero);
- tcg_gen_add2_i64(dest, cpu_psw_cb_msb, dest, cpu_psw_cb_msb,
- addc, ctx->zero);
+ tcg_gen_addcio_i64(dest, cpu_psw_cb_msb, add1, add2, addc);
/* Write back the result register. */
save_gpr(ctx, a->t, dest);
@@ -3552,8 +3548,7 @@ static bool do_addb(DisasContext *ctx, unsigned r, TCGv_i64 in1,
TCGv_i64 cb = tcg_temp_new_i64();
TCGv_i64 cb_msb = tcg_temp_new_i64();
- tcg_gen_movi_i64(cb_msb, 0);
- tcg_gen_add2_i64(dest, cb_msb, in1, cb_msb, in2, cb_msb);
+ tcg_gen_add2_i64(dest, cb_msb, in1, ctx->zero, in2, ctx->zero);
tcg_gen_xor_i64(cb, in1, in2);
tcg_gen_xor_i64(cb, cb, dest);
cb_cond = get_carry(ctx, d, cb, cb_msb);