aboutsummaryrefslogtreecommitdiff
path: root/target/microblaze
diff options
context:
space:
mode:
Diffstat (limited to 'target/microblaze')
-rw-r--r--target/microblaze/cpu-param.h6
-rw-r--r--target/microblaze/cpu-qom.h23
-rw-r--r--target/microblaze/cpu.c70
-rw-r--r--target/microblaze/cpu.h73
-rw-r--r--target/microblaze/gdbstub.c60
-rw-r--r--target/microblaze/helper.c21
-rw-r--r--target/microblaze/machine.c6
-rw-r--r--target/microblaze/meson.build6
-rw-r--r--target/microblaze/mmu.c3
-rw-r--r--target/microblaze/mmu.h2
-rw-r--r--target/microblaze/op_helper.c3
-rw-r--r--target/microblaze/translate.c212
12 files changed, 231 insertions, 254 deletions
diff --git a/target/microblaze/cpu-param.h b/target/microblaze/cpu-param.h
index 4d8297fa94..e530fead1c 100644
--- a/target/microblaze/cpu-param.h
+++ b/target/microblaze/cpu-param.h
@@ -6,7 +6,7 @@
*/
#ifndef MICROBLAZE_CPU_PARAM_H
-#define MICROBLAZE_CPU_PARAM_H 1
+#define MICROBLAZE_CPU_PARAM_H
/*
* While system mode can address up to 64 bits of address space,
@@ -28,6 +28,8 @@
/* FIXME: MB uses variable pages down to 1K but linux only uses 4k. */
#define TARGET_PAGE_BITS 12
-#define NB_MMU_MODES 3
+
+/* MicroBlaze is always in-order. */
+#define TCG_GUEST_DEFAULT_MO TCG_MO_ALL
#endif
diff --git a/target/microblaze/cpu-qom.h b/target/microblaze/cpu-qom.h
index e520eefb12..92e539fb2f 100644
--- a/target/microblaze/cpu-qom.h
+++ b/target/microblaze/cpu-qom.h
@@ -1,5 +1,5 @@
/*
- * QEMU MicroBlaze CPU
+ * QEMU MicroBlaze CPU QOM header (target agnostic)
*
* Copyright (c) 2012 SUSE LINUX Products GmbH
*
@@ -21,28 +21,9 @@
#define QEMU_MICROBLAZE_CPU_QOM_H
#include "hw/core/cpu.h"
-#include "qom/object.h"
#define TYPE_MICROBLAZE_CPU "microblaze-cpu"
-OBJECT_DECLARE_TYPE(MicroBlazeCPU, MicroBlazeCPUClass,
- MICROBLAZE_CPU)
-
-/**
- * MicroBlazeCPUClass:
- * @parent_realize: The parent class' realize handler.
- * @parent_reset: The parent class' reset handler.
- *
- * A MicroBlaze CPU model.
- */
-struct MicroBlazeCPUClass {
- /*< private >*/
- CPUClass parent_class;
- /*< public >*/
-
- DeviceRealize parent_realize;
- DeviceReset parent_reset;
-};
-
+OBJECT_DECLARE_CPU_TYPE(MicroBlazeCPU, MicroBlazeCPUClass, MICROBLAZE_CPU)
#endif
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 15db277925..9eb7374ccd 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -22,12 +22,16 @@
*/
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "qapi/error.h"
#include "cpu.h"
#include "qemu/module.h"
#include "hw/qdev-properties.h"
#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
+#include "exec/gdbstub.h"
#include "fpu/softfloat-helpers.h"
+#include "tcg/tcg.h"
static const struct {
const char *name;
@@ -83,20 +87,54 @@ static void mb_cpu_set_pc(CPUState *cs, vaddr value)
cpu->env.iflags = 0;
}
+static vaddr mb_cpu_get_pc(CPUState *cs)
+{
+ MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+
+ return cpu->env.pc;
+}
+
static void mb_cpu_synchronize_from_tb(CPUState *cs,
const TranslationBlock *tb)
{
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+ tcg_debug_assert(!(cs->tcg_cflags & CF_PCREL));
cpu->env.pc = tb->pc;
cpu->env.iflags = tb->flags & IFLAGS_TB_MASK;
}
+static void mb_restore_state_to_opc(CPUState *cs,
+ const TranslationBlock *tb,
+ const uint64_t *data)
+{
+ MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+
+ cpu->env.pc = data[0];
+ cpu->env.iflags = data[1];
+}
+
static bool mb_cpu_has_work(CPUState *cs)
{
return cs->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_NMI);
}
+static int mb_cpu_mmu_index(CPUState *cs, bool ifetch)
+{
+ CPUMBState *env = cpu_env(cs);
+ MicroBlazeCPU *cpu = env_archcpu(env);
+
+ /* Are we in nommu mode?. */
+ if (!(env->msr & MSR_VM) || !cpu->cfg.use_mmu) {
+ return MMU_NOMMU_IDX;
+ }
+
+ if (env->msr & MSR_UM) {
+ return MMU_USER_IDX;
+ }
+ return MMU_KERNEL_IDX;
+}
+
#ifndef CONFIG_USER_ONLY
static void mb_cpu_ns_axi_dp(void *opaque, int irq, int level)
{
@@ -144,14 +182,16 @@ static void microblaze_cpu_set_irq(void *opaque, int irq, int level)
}
#endif
-static void mb_cpu_reset(DeviceState *dev)
+static void mb_cpu_reset_hold(Object *obj, ResetType type)
{
- CPUState *s = CPU(dev);
- MicroBlazeCPU *cpu = MICROBLAZE_CPU(s);
- MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(cpu);
+ CPUState *cs = CPU(obj);
+ MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+ MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(obj);
CPUMBState *env = &cpu->env;
- mcc->parent_reset(dev);
+ if (mcc->parent_phases.hold) {
+ mcc->parent_phases.hold(obj, type);
+ }
memset(env, 0, offsetof(CPUMBState, end_reset_fields));
env->res_addr = RES_ADDR_NONE;
@@ -273,7 +313,10 @@ static void mb_cpu_initfn(Object *obj)
MicroBlazeCPU *cpu = MICROBLAZE_CPU(obj);
CPUMBState *env = &cpu->env;
- cpu_set_cpustate_pointers(cpu);
+ gdb_register_coprocessor(CPU(cpu), mb_cpu_gdb_read_stack_protect,
+ mb_cpu_gdb_write_stack_protect,
+ gdb_find_static_feature("microblaze-stack-protect.xml"),
+ 0);
set_float_rounding_mode(float_round_nearest_even, &env->fp_status);
@@ -362,12 +405,13 @@ static const struct SysemuCPUOps mb_sysemu_ops = {
#include "hw/core/tcg-cpu-ops.h"
-static const struct TCGCPUOps mb_tcg_ops = {
+static const TCGCPUOps mb_tcg_ops = {
.initialize = mb_tcg_init,
.synchronize_from_tb = mb_cpu_synchronize_from_tb,
- .tlb_fill = mb_cpu_tlb_fill,
+ .restore_state_to_opc = mb_restore_state_to_opc,
#ifndef CONFIG_USER_ONLY
+ .tlb_fill = mb_cpu_tlb_fill,
.cpu_exec_interrupt = mb_cpu_exec_interrupt,
.do_interrupt = mb_cpu_do_interrupt,
.do_transaction_failed = mb_cpu_transaction_failed,
@@ -380,16 +424,19 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
DeviceClass *dc = DEVICE_CLASS(oc);
CPUClass *cc = CPU_CLASS(oc);
MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_CLASS(oc);
+ ResettableClass *rc = RESETTABLE_CLASS(oc);
device_class_set_parent_realize(dc, mb_cpu_realizefn,
&mcc->parent_realize);
- device_class_set_parent_reset(dc, mb_cpu_reset, &mcc->parent_reset);
+ resettable_class_set_parent_phases(rc, NULL, mb_cpu_reset_hold, NULL,
+ &mcc->parent_phases);
cc->class_by_name = mb_cpu_class_by_name;
cc->has_work = mb_cpu_has_work;
-
+ cc->mmu_index = mb_cpu_mmu_index;
cc->dump_state = mb_cpu_dump_state;
cc->set_pc = mb_cpu_set_pc;
+ cc->get_pc = mb_cpu_get_pc;
cc->gdb_read_register = mb_cpu_gdb_read_register;
cc->gdb_write_register = mb_cpu_gdb_write_register;
@@ -398,7 +445,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
cc->sysemu_ops = &mb_sysemu_ops;
#endif
device_class_set_props(dc, mb_properties);
- cc->gdb_num_core_regs = 32 + 27;
+ cc->gdb_core_xml_file = "microblaze-core.xml";
cc->disas_set_info = mb_disas_set_info;
cc->tcg_ops = &mb_tcg_ops;
@@ -408,6 +455,7 @@ static const TypeInfo mb_cpu_type_info = {
.name = TYPE_MICROBLAZE_CPU,
.parent = TYPE_CPU,
.instance_size = sizeof(MicroBlazeCPU),
+ .instance_align = __alignof(MicroBlazeCPU),
.instance_init = mb_cpu_initfn,
.class_size = sizeof(MicroBlazeCPUClass),
.class_init = mb_cpu_class_init,
diff --git a/target/microblaze/cpu.h b/target/microblaze/cpu.h
index b7a848bbae..3e5a3e5c60 100644
--- a/target/microblaze/cpu.h
+++ b/target/microblaze/cpu.h
@@ -22,9 +22,9 @@
#include "cpu-qom.h"
#include "exec/cpu-defs.h"
-#include "fpu/softfloat-types.h"
+#include "qemu/cpu-float.h"
-typedef struct CPUMBState CPUMBState;
+typedef struct CPUArchState CPUMBState;
#if !defined(CONFIG_USER_ONLY)
#include "mmu.h"
#endif
@@ -202,7 +202,7 @@ typedef struct CPUMBState CPUMBState;
#define PVR10_TARGET_FAMILY_MASK 0xFF000000
#define PVR10_ASIZE_SHIFT 18
-/* MMU descrtiption */
+/* MMU description */
#define PVR11_USE_MMU 0xC0000000
#define PVR11_MMU_ITLB_SIZE 0x38000000
#define PVR11_MMU_DTLB_SIZE 0x07000000
@@ -239,7 +239,7 @@ typedef struct CPUMBState CPUMBState;
#define USE_NON_SECURE_M_AXI_DC_MASK 0x4
#define USE_NON_SECURE_M_AXI_IC_MASK 0x8
-struct CPUMBState {
+struct CPUArchState {
uint32_t bvalue; /* TCG temporary, only valid during a TB */
uint32_t btarget; /* Full resolved branch destination */
@@ -339,34 +339,47 @@ typedef struct {
*
* A MicroBlaze CPU.
*/
-struct MicroBlazeCPU {
- /*< private >*/
+struct ArchCPU {
CPUState parent_obj;
- /*< public >*/
+ CPUMBState env;
+
bool ns_axi_dp;
bool ns_axi_ip;
bool ns_axi_dc;
bool ns_axi_ic;
- CPUNegativeOffsetState neg;
- CPUMBState env;
MicroBlazeCPUConfig cfg;
};
+/**
+ * MicroBlazeCPUClass:
+ * @parent_realize: The parent class' realize handler.
+ * @parent_phases: The parent class' reset phase handlers.
+ *
+ * A MicroBlaze CPU model.
+ */
+struct MicroBlazeCPUClass {
+ CPUClass parent_class;
+
+ DeviceRealize parent_realize;
+ ResettablePhases parent_phases;
+};
#ifndef CONFIG_USER_ONLY
void mb_cpu_do_interrupt(CPUState *cs);
bool mb_cpu_exec_interrupt(CPUState *cs, int int_req);
-#endif /* !CONFIG_USER_ONLY */
-void mb_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
- MMUAccessType access_type,
- int mmu_idx, uintptr_t retaddr) QEMU_NORETURN;
-void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
MemTxAttrs *attrs);
+#endif /* !CONFIG_USER_ONLY */
+G_NORETURN void mb_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
+ MMUAccessType access_type,
+ int mmu_idx, uintptr_t retaddr);
+void mb_cpu_dump_state(CPUState *cpu, FILE *f, int flags);
int mb_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int mb_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
+int mb_cpu_gdb_read_stack_protect(CPUState *cs, GByteArray *buf, int reg);
+int mb_cpu_gdb_write_stack_protect(CPUState *cs, uint8_t *buf, int reg);
static inline uint32_t mb_cpu_read_msr(const CPUMBState *env)
{
@@ -392,22 +405,15 @@ void mb_tcg_init(void);
#define MMU_NOMMU_IDX 0
#define MMU_KERNEL_IDX 1
#define MMU_USER_IDX 2
-/* See NB_MMU_MODES further up the file. */
-
-bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
-
-typedef CPUMBState CPUArchState;
-typedef MicroBlazeCPU ArchCPU;
+/* See NB_MMU_MODES in cpu-defs.h. */
#include "exec/cpu-all.h"
/* Ensure there is no overlap between the two masks. */
QEMU_BUILD_BUG_ON(MSR_TB_MASK & IFLAGS_TB_MASK);
-static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
- target_ulong *cs_base, uint32_t *flags)
+static inline void cpu_get_tb_cpu_state(CPUMBState *env, vaddr *pc,
+ uint64_t *cs_base, uint32_t *flags)
{
*pc = env->pc;
*flags = (env->iflags & IFLAGS_TB_MASK) | (env->msr & MSR_TB_MASK);
@@ -415,27 +421,16 @@ static inline void cpu_get_tb_cpu_state(CPUMBState *env, target_ulong *pc,
}
#if !defined(CONFIG_USER_ONLY)
+bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
+
void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
unsigned size, MMUAccessType access_type,
int mmu_idx, MemTxAttrs attrs,
MemTxResult response, uintptr_t retaddr);
#endif
-static inline int cpu_mmu_index(CPUMBState *env, bool ifetch)
-{
- MicroBlazeCPU *cpu = env_archcpu(env);
-
- /* Are we in nommu mode?. */
- if (!(env->msr & MSR_VM) || !cpu->cfg.use_mmu) {
- return MMU_NOMMU_IDX;
- }
-
- if (env->msr & MSR_UM) {
- return MMU_USER_IDX;
- }
- return MMU_KERNEL_IDX;
-}
-
#ifndef CONFIG_USER_ONLY
extern const VMStateDescription vmstate_mb_cpu;
#endif
diff --git a/target/microblaze/gdbstub.c b/target/microblaze/gdbstub.c
index 2e6e070051..09d74e164d 100644
--- a/target/microblaze/gdbstub.c
+++ b/target/microblaze/gdbstub.c
@@ -19,7 +19,7 @@
*/
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/gdbstub.h"
+#include "gdbstub/helpers.h"
/*
* GDB expects SREGs in the following order:
@@ -39,21 +39,19 @@ enum {
GDB_PVR0 = 32 + 6,
GDB_PVR11 = 32 + 17,
GDB_EDR = 32 + 18,
- GDB_SLR = 32 + 25,
- GDB_SHR = 32 + 26,
+};
+
+enum {
+ GDB_SP_SHL,
+ GDB_SP_SHR,
};
int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
{
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
- CPUClass *cc = CPU_GET_CLASS(cs);
CPUMBState *env = &cpu->env;
uint32_t val;
- if (n > cc->gdb_num_core_regs) {
- return 0;
- }
-
switch (n) {
case 1 ... 31:
val = env->regs[n];
@@ -83,25 +81,37 @@ int mb_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
case GDB_EDR:
val = env->edr;
break;
- case GDB_SLR:
+ default:
+ /* Other SRegs aren't modeled, so report a value of 0 */
+ val = 0;
+ break;
+ }
+ return gdb_get_reg32(mem_buf, val);
+}
+
+int mb_cpu_gdb_read_stack_protect(CPUState *cs, GByteArray *mem_buf, int n)
+{
+ MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+ CPUMBState *env = &cpu->env;
+ uint32_t val;
+
+ switch (n) {
+ case GDB_SP_SHL:
val = env->slr;
break;
- case GDB_SHR:
+ case GDB_SP_SHR:
val = env->shr;
break;
default:
- /* Other SRegs aren't modeled, so report a value of 0 */
- val = 0;
- break;
+ return 0;
}
return gdb_get_reg32(mem_buf, val);
}
int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
{
- MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
CPUClass *cc = CPU_GET_CLASS(cs);
- CPUMBState *env = &cpu->env;
+ CPUMBState *env = cpu_env(cs);
uint32_t tmp;
if (n > cc->gdb_num_core_regs) {
@@ -135,12 +145,24 @@ int mb_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
case GDB_EDR:
env->edr = tmp;
break;
- case GDB_SLR:
- env->slr = tmp;
+ }
+ return 4;
+}
+
+int mb_cpu_gdb_write_stack_protect(CPUState *cs, uint8_t *mem_buf, int n)
+{
+ MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+ CPUMBState *env = &cpu->env;
+
+ switch (n) {
+ case GDB_SP_SHL:
+ env->slr = ldl_p(mem_buf);
break;
- case GDB_SHR:
- env->shr = tmp;
+ case GDB_SP_SHR:
+ env->shr = ldl_p(mem_buf);
break;
+ default:
+ return 0;
}
return 4;
}
diff --git a/target/microblaze/helper.c b/target/microblaze/helper.c
index dd2aecd1d5..d25c9eb4d3 100644
--- a/target/microblaze/helper.c
+++ b/target/microblaze/helper.c
@@ -24,18 +24,7 @@
#include "qemu/host-utils.h"
#include "exec/log.h"
-#if defined(CONFIG_USER_ONLY)
-
-bool mb_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr)
-{
- cs->exception_index = 0xaa;
- cpu_loop_exit_restore(cs, retaddr);
-}
-
-#else /* !CONFIG_USER_ONLY */
-
+#ifndef CONFIG_USER_ONLY
static bool mb_cpu_access_is_secure(MicroBlazeCPU *cpu,
MMUAccessType access_type)
{
@@ -239,10 +228,9 @@ hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
MemTxAttrs *attrs)
{
MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
- CPUMBState *env = &cpu->env;
target_ulong vaddr, paddr = 0;
MicroBlazeMMULookup lu;
- int mmu_idx = cpu_mmu_index(env, false);
+ int mmu_idx = cpu_mmu_index(cs, false);
unsigned int hit;
/* Caller doesn't initialize */
@@ -264,8 +252,7 @@ hwaddr mb_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
bool mb_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
- MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
- CPUMBState *env = &cpu->env;
+ CPUMBState *env = cpu_env(cs);
if ((interrupt_request & CPU_INTERRUPT_HARD)
&& (env->msr & MSR_IE)
@@ -288,7 +275,7 @@ void mb_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
uint32_t esr, iflags;
/* Recover the pc and iflags from the corresponding insn_start. */
- cpu_restore_state(cs, retaddr, true);
+ cpu_restore_state(cs, retaddr);
iflags = cpu->env.iflags;
qemu_log_mask(CPU_LOG_INT,
diff --git a/target/microblaze/machine.c b/target/microblaze/machine.c
index d24def3992..51705e4f5c 100644
--- a/target/microblaze/machine.c
+++ b/target/microblaze/machine.c
@@ -22,7 +22,7 @@
#include "migration/cpu.h"
-static VMStateField vmstate_mmu_fields[] = {
+static const VMStateField vmstate_mmu_fields[] = {
VMSTATE_UINT64_2DARRAY(rams, MicroBlazeMMU, 2, TLB_ENTRIES),
VMSTATE_UINT8_ARRAY(tids, MicroBlazeMMU, TLB_ENTRIES),
VMSTATE_UINT32_ARRAY(regs, MicroBlazeMMU, 3),
@@ -60,7 +60,7 @@ static const VMStateInfo vmstate_msr = {
.put = put_msr,
};
-static VMStateField vmstate_env_fields[] = {
+static const VMStateField vmstate_env_fields[] = {
VMSTATE_UINT32_ARRAY(regs, CPUMBState, 32),
VMSTATE_UINT32(pc, CPUMBState),
@@ -92,7 +92,7 @@ static const VMStateDescription vmstate_env = {
.fields = vmstate_env_fields,
};
-static VMStateField vmstate_cpu_fields[] = {
+static const VMStateField vmstate_cpu_fields[] = {
VMSTATE_CPU(),
VMSTATE_STRUCT(env, MicroBlazeCPU, 1, vmstate_env, CPUMBState),
VMSTATE_END_OF_LIST()
diff --git a/target/microblaze/meson.build b/target/microblaze/meson.build
index 05ee0ec163..3ed4fbb67a 100644
--- a/target/microblaze/meson.build
+++ b/target/microblaze/meson.build
@@ -10,11 +10,11 @@ microblaze_ss.add(files(
'translate.c',
))
-microblaze_softmmu_ss = ss.source_set()
-microblaze_softmmu_ss.add(files(
+microblaze_system_ss = ss.source_set()
+microblaze_system_ss.add(files(
'mmu.c',
'machine.c',
))
target_arch += {'microblaze': microblaze_ss}
-target_softmmu_arch += {'microblaze': microblaze_softmmu_ss}
+target_system_arch += {'microblaze': microblaze_system_ss}
diff --git a/target/microblaze/mmu.c b/target/microblaze/mmu.c
index cc40f275ea..234006634e 100644
--- a/target/microblaze/mmu.c
+++ b/target/microblaze/mmu.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "cpu.h"
#include "exec/exec-all.h"
@@ -304,7 +305,7 @@ void mmu_write(CPUMBState *env, bool ext, uint32_t rn, uint32_t v)
}
hit = mmu_translate(cpu, &lu, v & TLB_EPN_MASK,
- 0, cpu_mmu_index(env, false));
+ 0, cpu_mmu_index(env_cpu(env), false));
if (hit) {
env->mmu.regs[MMU_R_TLBX] = lu.idx;
} else {
diff --git a/target/microblaze/mmu.h b/target/microblaze/mmu.h
index b6b4b9ad60..1068bd2d52 100644
--- a/target/microblaze/mmu.h
+++ b/target/microblaze/mmu.h
@@ -20,6 +20,8 @@
#ifndef TARGET_MICROBLAZE_MMU_H
#define TARGET_MICROBLAZE_MMU_H
+#include "cpu.h"
+
#define MMU_R_PID 0
#define MMU_R_ZPR 1
#define MMU_R_TLBX 2
diff --git a/target/microblaze/op_helper.c b/target/microblaze/op_helper.c
index 58d633584d..f6378030b7 100644
--- a/target/microblaze/op_helper.c
+++ b/target/microblaze/op_helper.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/log.h"
#include "cpu.h"
#include "exec/helper-proto.h"
#include "qemu/host-utils.h"
@@ -402,7 +403,7 @@ void mb_cpu_transaction_failed(CPUState *cs, hwaddr physaddr, vaddr addr,
CPUMBState *env = &cpu->env;
qemu_log_mask(CPU_LOG_INT, "Transaction failed: vaddr 0x%" VADDR_PRIx
- " physaddr 0x" TARGET_FMT_plx " size %d access type %s\n",
+ " physaddr 0x" HWADDR_FMT_plx " size %d access type %s\n",
addr, physaddr, size,
access_type == MMU_INST_FETCH ? "INST_FETCH" :
(access_type == MMU_DATA_LOAD ? "DATA_LOAD" : "DATA_STORE"));
diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
index a14ffed784..6d89c1a175 100644
--- a/target/microblaze/translate.c
+++ b/target/microblaze/translate.c
@@ -22,15 +22,19 @@
#include "cpu.h"
#include "disas/disas.h"
#include "exec/exec-all.h"
+#include "exec/cpu_ldst.h"
#include "tcg/tcg-op.h"
#include "exec/helper-proto.h"
-#include "exec/cpu_ldst.h"
#include "exec/helper-gen.h"
#include "exec/translator.h"
#include "qemu/qemu-print.h"
#include "exec/log.h"
+#define HELPER_H "helper.h"
+#include "exec/helper-info.c.inc"
+#undef HELPER_H
+
#define EXTRACT_FIELD(src, start, end) \
(((src) >> start) & ((1 << (end - start + 1)) - 1))
@@ -54,16 +58,11 @@ static TCGv_i32 cpu_iflags;
static TCGv cpu_res_addr;
static TCGv_i32 cpu_res_val;
-#include "exec/gen-icount.h"
-
/* This is the state at translation time. */
typedef struct DisasContext {
DisasContextBase base;
const MicroBlazeCPUConfig *cfg;
- /* TCG op of the current insn_start. */
- TCGOp *insn_start;
-
TCGv_i32 r0;
bool r0_set;
@@ -101,10 +100,7 @@ static void t_sync_flags(DisasContext *dc)
static void gen_raise_exception(DisasContext *dc, uint32_t index)
{
- TCGv_i32 tmp = tcg_const_i32(index);
-
- gen_helper_raise_exception(cpu_env, tmp);
- tcg_temp_free_i32(tmp);
+ gen_helper_raise_exception(tcg_env, tcg_constant_i32(index));
dc->base.is_jmp = DISAS_NORETURN;
}
@@ -117,21 +113,15 @@ static void gen_raise_exception_sync(DisasContext *dc, uint32_t index)
static void gen_raise_hw_excp(DisasContext *dc, uint32_t esr_ec)
{
- TCGv_i32 tmp = tcg_const_i32(esr_ec);
- tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUMBState, esr));
- tcg_temp_free_i32(tmp);
+ TCGv_i32 tmp = tcg_constant_i32(esr_ec);
+ tcg_gen_st_i32(tmp, tcg_env, offsetof(CPUMBState, esr));
gen_raise_exception_sync(dc, EXCP_HW_EXCP);
}
static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest)
{
- if (dc->base.singlestep_enabled) {
- TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
- tcg_gen_movi_i32(cpu_pc, dest);
- gen_helper_raise_exception(cpu_env, tmp);
- tcg_temp_free_i32(tmp);
- } else if (translator_use_goto_tb(&dc->base, dest)) {
+ if (translator_use_goto_tb(&dc->base, dest)) {
tcg_gen_goto_tb(n);
tcg_gen_movi_i32(cpu_pc, dest);
tcg_gen_exit_tb(dc->base.tb, n);
@@ -267,11 +257,9 @@ static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
rd = reg_for_write(dc, arg->rd);
ra = reg_for_read(dc, arg->ra);
- imm = tcg_const_i32(arg->imm);
+ imm = tcg_constant_i32(arg->imm);
fn(rd, ra, imm);
-
- tcg_temp_free_i32(imm);
return true;
}
@@ -305,33 +293,28 @@ static bool do_typeb_val(DisasContext *dc, arg_typeb *arg, bool side_effects,
#define ENV_WRAPPER2(NAME, HELPER) \
static void NAME(TCGv_i32 out, TCGv_i32 ina) \
- { HELPER(out, cpu_env, ina); }
+ { HELPER(out, tcg_env, ina); }
#define ENV_WRAPPER3(NAME, HELPER) \
static void NAME(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb) \
- { HELPER(out, cpu_env, ina, inb); }
+ { HELPER(out, tcg_env, ina, inb); }
/* No input carry, but output carry. */
static void gen_add(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
- TCGv_i32 zero = tcg_const_i32(0);
+ TCGv_i32 zero = tcg_constant_i32(0);
tcg_gen_add2_i32(out, cpu_msr_c, ina, zero, inb, zero);
-
- tcg_temp_free_i32(zero);
}
/* Input and output carry. */
static void gen_addc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
- TCGv_i32 zero = tcg_const_i32(0);
+ TCGv_i32 zero = tcg_constant_i32(0);
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_add2_i32(tmp, cpu_msr_c, ina, zero, cpu_msr_c, zero);
tcg_gen_add2_i32(out, cpu_msr_c, tmp, cpu_msr_c, inb, zero);
-
- tcg_temp_free_i32(tmp);
- tcg_temp_free_i32(zero);
}
/* Input carry, but no output carry. */
@@ -366,7 +349,6 @@ static void gen_bsra(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_andi_i32(tmp, inb, 31);
tcg_gen_sar_i32(out, ina, tmp);
- tcg_temp_free_i32(tmp);
}
static void gen_bsrl(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
@@ -374,7 +356,6 @@ static void gen_bsrl(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_andi_i32(tmp, inb, 31);
tcg_gen_shr_i32(out, ina, tmp);
- tcg_temp_free_i32(tmp);
}
static void gen_bsll(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
@@ -382,7 +363,6 @@ static void gen_bsll(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_andi_i32(tmp, inb, 31);
tcg_gen_shl_i32(out, ina, tmp);
- tcg_temp_free_i32(tmp);
}
static void gen_bsefi(TCGv_i32 out, TCGv_i32 ina, int32_t imm)
@@ -441,7 +421,6 @@ static void gen_cmp(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
tcg_gen_setcond_i32(TCG_COND_LT, lt, inb, ina);
tcg_gen_sub_i32(out, inb, ina);
tcg_gen_deposit_i32(out, out, lt, 31, 1);
- tcg_temp_free_i32(lt);
}
static void gen_cmpu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
@@ -451,7 +430,6 @@ static void gen_cmpu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
tcg_gen_setcond_i32(TCG_COND_LTU, lt, inb, ina);
tcg_gen_sub_i32(out, inb, ina);
tcg_gen_deposit_i32(out, out, lt, 31, 1);
- tcg_temp_free_i32(lt);
}
DO_TYPEA(cmp, false, gen_cmp)
@@ -492,12 +470,12 @@ DO_TYPEA0_CFG(fsqrt, use_fpu >= 2, true, gen_fsqrt)
/* Does not use ENV_WRAPPER3, because arguments are swapped as well. */
static void gen_idiv(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
- gen_helper_divs(out, cpu_env, inb, ina);
+ gen_helper_divs(out, tcg_env, inb, ina);
}
static void gen_idivu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
- gen_helper_divu(out, cpu_env, inb, ina);
+ gen_helper_divu(out, tcg_env, inb, ina);
}
DO_TYPEA_CFG(idiv, use_div, true, gen_idiv)
@@ -518,21 +496,18 @@ static void gen_mulh(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_muls2_i32(tmp, out, ina, inb);
- tcg_temp_free_i32(tmp);
}
static void gen_mulhu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_mulu2_i32(tmp, out, ina, inb);
- tcg_temp_free_i32(tmp);
}
static void gen_mulhsu(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_mulsu2_i32(tmp, out, ina, inb);
- tcg_temp_free_i32(tmp);
}
DO_TYPEA_CFG(mul, use_hw_mul, false, tcg_gen_mul_i32)
@@ -568,15 +543,12 @@ static void gen_rsub(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
/* Input and output carry. */
static void gen_rsubc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
{
- TCGv_i32 zero = tcg_const_i32(0);
+ TCGv_i32 zero = tcg_constant_i32(0);
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_not_i32(tmp, ina);
tcg_gen_add2_i32(tmp, cpu_msr_c, tmp, zero, cpu_msr_c, zero);
tcg_gen_add2_i32(out, cpu_msr_c, tmp, cpu_msr_c, inb, zero);
-
- tcg_temp_free_i32(zero);
- tcg_temp_free_i32(tmp);
}
/* No input or output carry. */
@@ -593,8 +565,6 @@ static void gen_rsubkc(TCGv_i32 out, TCGv_i32 ina, TCGv_i32 inb)
tcg_gen_not_i32(nota, ina);
tcg_gen_add_i32(out, inb, nota);
tcg_gen_add_i32(out, out, cpu_msr_c);
-
- tcg_temp_free_i32(nota);
}
DO_TYPEA(rsub, true, gen_rsub)
@@ -623,8 +593,6 @@ static void gen_src(TCGv_i32 out, TCGv_i32 ina)
tcg_gen_mov_i32(tmp, cpu_msr_c);
tcg_gen_andi_i32(cpu_msr_c, ina, 1);
tcg_gen_extract2_i32(out, ina, tmp, 1);
-
- tcg_temp_free_i32(tmp);
}
static void gen_srl(TCGv_i32 out, TCGv_i32 ina)
@@ -664,7 +632,6 @@ static TCGv compute_ldst_addr_typea(DisasContext *dc, int ra, int rb)
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_add_i32(tmp, cpu_R[ra], cpu_R[rb]);
tcg_gen_extu_i32_tl(ret, tmp);
- tcg_temp_free_i32(tmp);
} else if (ra) {
tcg_gen_extu_i32_tl(ret, cpu_R[ra]);
} else if (rb) {
@@ -674,7 +641,7 @@ static TCGv compute_ldst_addr_typea(DisasContext *dc, int ra, int rb)
}
if ((ra == 1 || rb == 1) && dc->cfg->stackprot) {
- gen_helper_stackprot(cpu_env, ret);
+ gen_helper_stackprot(tcg_env, ret);
}
return ret;
}
@@ -688,13 +655,12 @@ static TCGv compute_ldst_addr_typeb(DisasContext *dc, int ra, int imm)
TCGv_i32 tmp = tcg_temp_new_i32();
tcg_gen_addi_i32(tmp, cpu_R[ra], imm);
tcg_gen_extu_i32_tl(ret, tmp);
- tcg_temp_free_i32(tmp);
} else {
tcg_gen_movi_tl(ret, (uint32_t)imm);
}
if (ra == 1 && dc->cfg->stackprot) {
- gen_helper_stackprot(cpu_env, ret);
+ gen_helper_stackprot(tcg_env, ret);
}
return ret;
}
@@ -727,18 +693,20 @@ static TCGv compute_ldst_addr_ea(DisasContext *dc, int ra, int rb)
}
#endif
+#ifndef CONFIG_USER_ONLY
static void record_unaligned_ess(DisasContext *dc, int rd,
MemOp size, bool store)
{
- uint32_t iflags = tcg_get_insn_start_param(dc->insn_start, 1);
+ uint32_t iflags = tcg_get_insn_start_param(dc->base.insn_start, 1);
iflags |= ESR_ESS_FLAG;
iflags |= rd << 5;
iflags |= store * ESR_S;
iflags |= (size == MO_32) * ESR_W;
- tcg_set_insn_start_param(dc->insn_start, 1, iflags);
+ tcg_set_insn_start_param(dc->base.insn_start, 1, iflags);
}
+#endif
static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
int mem_index, bool rev)
@@ -760,16 +728,21 @@ static bool do_load(DisasContext *dc, int rd, TCGv addr, MemOp mop,
}
}
+ /*
+ * For system mode, enforce alignment if the cpu configuration
+ * requires it. For user-mode, the Linux kernel will have fixed up
+ * any unaligned access, so emulate that by *not* setting MO_ALIGN.
+ */
+#ifndef CONFIG_USER_ONLY
if (size > MO_8 &&
(dc->tb_flags & MSR_EE) &&
dc->cfg->unaligned_exceptions) {
record_unaligned_ess(dc, rd, size, false);
mop |= MO_ALIGN;
}
+#endif
tcg_gen_qemu_ld_i32(reg_for_write(dc, rd), addr, mem_index, mop);
-
- tcg_temp_free(addr);
return true;
}
@@ -875,7 +848,6 @@ static bool trans_lwx(DisasContext *dc, arg_typea *arg)
tcg_gen_qemu_ld_i32(cpu_res_val, addr, dc->mem_index, MO_TEUL);
tcg_gen_mov_tl(cpu_res_addr, addr);
- tcg_temp_free(addr);
if (arg->rd) {
tcg_gen_mov_i32(cpu_R[arg->rd], cpu_res_val);
@@ -906,16 +878,21 @@ static bool do_store(DisasContext *dc, int rd, TCGv addr, MemOp mop,
}
}
+ /*
+ * For system mode, enforce alignment if the cpu configuration
+ * requires it. For user-mode, the Linux kernel will have fixed up
+ * any unaligned access, so emulate that by *not* setting MO_ALIGN.
+ */
+#ifndef CONFIG_USER_ONLY
if (size > MO_8 &&
(dc->tb_flags & MSR_EE) &&
dc->cfg->unaligned_exceptions) {
record_unaligned_ess(dc, rd, size, true);
mop |= MO_ALIGN;
}
+#endif
tcg_gen_qemu_st_i32(reg_for_read(dc, rd), addr, mem_index, mop);
-
- tcg_temp_free(addr);
return true;
}
@@ -1029,7 +1006,6 @@ static bool trans_swx(DisasContext *dc, arg_typea *arg)
* In either case, addr is no longer needed.
*/
tcg_gen_brcond_tl(TCG_COND_NE, cpu_res_addr, addr, swx_fail);
- tcg_temp_free(addr);
/*
* Compare the value loaded during lwx with current contents of
@@ -1042,7 +1018,6 @@ static bool trans_swx(DisasContext *dc, arg_typea *arg)
dc->mem_index, MO_TEUL);
tcg_gen_brcond_i32(TCG_COND_NE, cpu_res_val, tval, swx_fail);
- tcg_temp_free_i32(tval);
/* Success */
tcg_gen_movi_i32(cpu_msr_c, 0);
@@ -1139,13 +1114,11 @@ static bool do_bcc(DisasContext *dc, int dest_rb, int dest_imm,
}
/* Compute the final destination into btarget. */
- zero = tcg_const_i32(0);
- next = tcg_const_i32(dc->base.pc_next + (delay + 1) * 4);
+ zero = tcg_constant_i32(0);
+ next = tcg_constant_i32(dc->base.pc_next + (delay + 1) * 4);
tcg_gen_movcond_i32(dc->jmp_cond, cpu_btarget,
reg_for_read(dc, ra), zero,
cpu_btarget, next);
- tcg_temp_free_i32(zero);
- tcg_temp_free_i32(next);
return true;
}
@@ -1250,8 +1223,6 @@ static bool trans_mbar(DisasContext *dc, arg_mbar *arg)
/* Sleep. */
if (mbar_imm & 16) {
- TCGv_i32 tmp_1;
-
if (trap_userspace(dc, true)) {
/* Sleep is a privileged instruction. */
return true;
@@ -1259,11 +1230,9 @@ static bool trans_mbar(DisasContext *dc, arg_mbar *arg)
t_sync_flags(dc);
- tmp_1 = tcg_const_i32(1);
- tcg_gen_st_i32(tmp_1, cpu_env,
+ tcg_gen_st_i32(tcg_constant_i32(1), tcg_env,
-offsetof(MicroBlazeCPU, env)
+offsetof(CPUState, halted));
- tcg_temp_free_i32(tmp_1);
tcg_gen_movi_i32(cpu_pc, dc->base.pc_next + 4);
@@ -1334,7 +1303,6 @@ static void msr_read(DisasContext *dc, TCGv_i32 d)
t = tcg_temp_new_i32();
tcg_gen_muli_i32(t, cpu_msr_c, MSR_C | MSR_CC);
tcg_gen_or_i32(d, cpu_msr, t);
- tcg_temp_free_i32(t);
}
static bool do_msrclrset(DisasContext *dc, arg_type_msr *arg, bool set)
@@ -1411,13 +1379,13 @@ static bool trans_mts(DisasContext *dc, arg_mts *arg)
tcg_gen_andi_i32(cpu_msr, src, ~(MSR_C | MSR_CC | MSR_PVR));
break;
case SR_FSR:
- tcg_gen_st_i32(src, cpu_env, offsetof(CPUMBState, fsr));
+ tcg_gen_st_i32(src, tcg_env, offsetof(CPUMBState, fsr));
break;
case 0x800:
- tcg_gen_st_i32(src, cpu_env, offsetof(CPUMBState, slr));
+ tcg_gen_st_i32(src, tcg_env, offsetof(CPUMBState, slr));
break;
case 0x802:
- tcg_gen_st_i32(src, cpu_env, offsetof(CPUMBState, shr));
+ tcg_gen_st_i32(src, tcg_env, offsetof(CPUMBState, shr));
break;
case 0x1000: /* PID */
@@ -1427,12 +1395,10 @@ static bool trans_mts(DisasContext *dc, arg_mts *arg)
case 0x1004: /* TLBHI */
case 0x1005: /* TLBSX */
{
- TCGv_i32 tmp_ext = tcg_const_i32(arg->e);
- TCGv_i32 tmp_reg = tcg_const_i32(arg->rs & 7);
+ TCGv_i32 tmp_ext = tcg_constant_i32(arg->e);
+ TCGv_i32 tmp_reg = tcg_constant_i32(arg->rs & 7);
- gen_helper_mmu_write(cpu_env, tmp_ext, tmp_reg, src);
- tcg_temp_free_i32(tmp_reg);
- tcg_temp_free_i32(tmp_ext);
+ gen_helper_mmu_write(tcg_env, tmp_ext, tmp_reg, src);
}
break;
@@ -1454,9 +1420,8 @@ static bool trans_mfs(DisasContext *dc, arg_mfs *arg)
case SR_EAR:
{
TCGv_i64 t64 = tcg_temp_new_i64();
- tcg_gen_ld_i64(t64, cpu_env, offsetof(CPUMBState, ear));
+ tcg_gen_ld_i64(t64, tcg_env, offsetof(CPUMBState, ear));
tcg_gen_extrh_i64_i32(dest, t64);
- tcg_temp_free_i64(t64);
}
return true;
#ifndef CONFIG_USER_ONLY
@@ -1485,28 +1450,27 @@ static bool trans_mfs(DisasContext *dc, arg_mfs *arg)
case SR_EAR:
{
TCGv_i64 t64 = tcg_temp_new_i64();
- tcg_gen_ld_i64(t64, cpu_env, offsetof(CPUMBState, ear));
+ tcg_gen_ld_i64(t64, tcg_env, offsetof(CPUMBState, ear));
tcg_gen_extrl_i64_i32(dest, t64);
- tcg_temp_free_i64(t64);
}
break;
case SR_ESR:
- tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, esr));
+ tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, esr));
break;
case SR_FSR:
- tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, fsr));
+ tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, fsr));
break;
case SR_BTR:
- tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, btr));
+ tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, btr));
break;
case SR_EDR:
- tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, edr));
+ tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, edr));
break;
case 0x800:
- tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, slr));
+ tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, slr));
break;
case 0x802:
- tcg_gen_ld_i32(dest, cpu_env, offsetof(CPUMBState, shr));
+ tcg_gen_ld_i32(dest, tcg_env, offsetof(CPUMBState, shr));
break;
#ifndef CONFIG_USER_ONLY
@@ -1517,18 +1481,16 @@ static bool trans_mfs(DisasContext *dc, arg_mfs *arg)
case 0x1004: /* TLBHI */
case 0x1005: /* TLBSX */
{
- TCGv_i32 tmp_ext = tcg_const_i32(arg->e);
- TCGv_i32 tmp_reg = tcg_const_i32(arg->rs & 7);
+ TCGv_i32 tmp_ext = tcg_constant_i32(arg->e);
+ TCGv_i32 tmp_reg = tcg_constant_i32(arg->rs & 7);
- gen_helper_mmu_read(dest, cpu_env, tmp_ext, tmp_reg);
- tcg_temp_free_i32(tmp_reg);
- tcg_temp_free_i32(tmp_ext);
+ gen_helper_mmu_read(dest, tcg_env, tmp_ext, tmp_reg);
}
break;
#endif
case 0x2000 ... 0x200c:
- tcg_gen_ld_i32(dest, cpu_env,
+ tcg_gen_ld_i32(dest, tcg_env,
offsetof(MicroBlazeCPU, cfg.pvr_regs[arg->rs - 0x2000])
- offsetof(MicroBlazeCPU, env));
break;
@@ -1548,8 +1510,6 @@ static void do_rti(DisasContext *dc)
tcg_gen_andi_i32(tmp, tmp, MSR_VM | MSR_UM);
tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM));
tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
-
- tcg_temp_free_i32(tmp);
}
static void do_rtb(DisasContext *dc)
@@ -1560,8 +1520,6 @@ static void do_rtb(DisasContext *dc)
tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM | MSR_BIP));
tcg_gen_andi_i32(tmp, tmp, (MSR_VM | MSR_UM));
tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
-
- tcg_temp_free_i32(tmp);
}
static void do_rte(DisasContext *dc)
@@ -1573,8 +1531,6 @@ static void do_rte(DisasContext *dc)
tcg_gen_andi_i32(tmp, tmp, (MSR_VM | MSR_UM));
tcg_gen_andi_i32(cpu_msr, cpu_msr, ~(MSR_VM | MSR_UM | MSR_EIP));
tcg_gen_or_i32(cpu_msr, cpu_msr, tmp);
-
- tcg_temp_free_i32(tmp);
}
/* Insns connected to FSL or AXI stream attached devices. */
@@ -1593,10 +1549,8 @@ static bool do_get(DisasContext *dc, int rd, int rb, int imm, int ctrl)
tcg_gen_movi_i32(t_id, imm);
}
- t_ctrl = tcg_const_i32(ctrl);
+ t_ctrl = tcg_constant_i32(ctrl);
gen_helper_get(reg_for_write(dc, rd), t_id, t_ctrl);
- tcg_temp_free_i32(t_id);
- tcg_temp_free_i32(t_ctrl);
return true;
}
@@ -1625,10 +1579,8 @@ static bool do_put(DisasContext *dc, int ra, int rb, int imm, int ctrl)
tcg_gen_movi_i32(t_id, imm);
}
- t_ctrl = tcg_const_i32(ctrl);
+ t_ctrl = tcg_constant_i32(ctrl);
gen_helper_put(t_id, t_ctrl, reg_for_read(dc, ra));
- tcg_temp_free_i32(t_id);
- tcg_temp_free_i32(t_ctrl);
return true;
}
@@ -1653,7 +1605,7 @@ static void mb_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
dc->ext_imm = dc->base.tb->cs_base;
dc->r0 = NULL;
dc->r0_set = false;
- dc->mem_index = cpu_mmu_index(&cpu->env, false);
+ dc->mem_index = cpu_mmu_index(cs, false);
dc->jmp_cond = dc->tb_flags & D_FLAG ? TCG_COND_ALWAYS : TCG_COND_NEVER;
dc->jmp_dest = -1;
@@ -1670,13 +1622,11 @@ static void mb_tr_insn_start(DisasContextBase *dcb, CPUState *cs)
DisasContext *dc = container_of(dcb, DisasContext, base);
tcg_gen_insn_start(dc->base.pc_next, dc->tb_flags & ~MSR_TB_MASK);
- dc->insn_start = tcg_last_op();
}
static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
{
DisasContext *dc = container_of(dcb, DisasContext, base);
- CPUMBState *env = cs->env_ptr;
uint32_t ir;
/* TODO: This should raise an exception, not terminate qemu. */
@@ -1687,13 +1637,12 @@ static void mb_tr_translate_insn(DisasContextBase *dcb, CPUState *cs)
dc->tb_flags_to_set = 0;
- ir = cpu_ldl_code(env, dc->base.pc_next);
+ ir = cpu_ldl_code(cpu_env(cs), dc->base.pc_next);
if (!decode(dc, ir)) {
trap_illegal(dc, true);
}
if (dc->r0) {
- tcg_temp_free_i32(dc->r0);
dc->r0 = NULL;
dc->r0_set = false;
}
@@ -1779,7 +1728,7 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
break;
case DISAS_JUMP:
- if (dc->jmp_dest != -1 && !cs->singlestep_enabled) {
+ if (dc->jmp_dest != -1 && !(tb_cflags(dc->base.tb) & CF_NO_GOTO_TB)) {
/* Direct jump. */
tcg_gen_discard_i32(cpu_btarget);
@@ -1804,15 +1753,10 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
return;
}
- /* Indirect jump (or direct jump w/ singlestep) */
+ /* Indirect jump (or direct jump w/ goto_tb disabled) */
tcg_gen_mov_i32(cpu_pc, cpu_btarget);
tcg_gen_discard_i32(cpu_btarget);
-
- if (unlikely(cs->singlestep_enabled)) {
- gen_raise_exception(dc, EXCP_DEBUG);
- } else {
- tcg_gen_lookup_and_goto_ptr();
- }
+ tcg_gen_lookup_and_goto_ptr();
return;
default:
@@ -1827,10 +1771,11 @@ static void mb_tr_tb_stop(DisasContextBase *dcb, CPUState *cs)
}
}
-static void mb_tr_disas_log(const DisasContextBase *dcb, CPUState *cs)
+static void mb_tr_disas_log(const DisasContextBase *dcb,
+ CPUState *cs, FILE *logfile)
{
- qemu_log("IN: %s\n", lookup_symbol(dcb->pc_first));
- log_target_disas(cs, dcb->pc_first, dcb->tb->size);
+ fprintf(logfile, "IN: %s\n", lookup_symbol(dcb->pc_first));
+ target_disas(logfile, cs, dcb->pc_first, dcb->tb->size);
}
static const TranslatorOps mb_tr_ops = {
@@ -1842,16 +1787,16 @@ static const TranslatorOps mb_tr_ops = {
.disas_log = mb_tr_disas_log,
};
-void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
+void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int *max_insns,
+ vaddr pc, void *host_pc)
{
DisasContext dc;
- translator_loop(&mb_tr_ops, &dc.base, cpu, tb, max_insns);
+ translator_loop(cpu, tb, max_insns, pc, host_pc, &mb_tr_ops, &dc.base);
}
void mb_cpu_dump_state(CPUState *cs, FILE *f, int flags)
{
- MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
- CPUMBState *env = &cpu->env;
+ CPUMBState *env = cpu_env(cs);
uint32_t iflags;
int i;
@@ -1932,16 +1877,9 @@ void mb_tcg_init(void)
for (int i = 0; i < ARRAY_SIZE(i32s); ++i) {
*i32s[i].var =
- tcg_global_mem_new_i32(cpu_env, i32s[i].ofs, i32s[i].name);
+ tcg_global_mem_new_i32(tcg_env, i32s[i].ofs, i32s[i].name);
}
cpu_res_addr =
- tcg_global_mem_new(cpu_env, offsetof(CPUMBState, res_addr), "res_addr");
-}
-
-void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb,
- target_ulong *data)
-{
- env->pc = data[0];
- env->iflags = data[1];
+ tcg_global_mem_new(tcg_env, offsetof(CPUMBState, res_addr), "res_addr");
}