*/
#include "cpu.h"
-#include "disas.h"
+#include "disas/disas.h"
#include "tcg-op.h"
#include "helper.h"
#include "microblaze-decode.h"
static TCGv env_btarget;
static TCGv env_iflags;
-#include "gen-icount.h"
+#include "exec/gen-icount.h"
/* This is the state at translation time. */
typedef struct DisasContext {
t_sync_flags(dc);
tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
- gen_helper_raise_exception(tmp);
+ gen_helper_raise_exception(cpu_env, tmp);
tcg_temp_free_i32(tmp);
dc->is_jmp = DISAS_UPDATE;
}
sr &= 7;
LOG_DIS("m%ss sr%d r%d imm=%x\n", to ? "t" : "f", sr, dc->ra, dc->imm);
if (to)
- gen_helper_mmu_write(tcg_const_tl(sr), cpu_R[dc->ra]);
+ gen_helper_mmu_write(cpu_env, tcg_const_tl(sr), cpu_R[dc->ra]);
else
- gen_helper_mmu_read(cpu_R[dc->rd], tcg_const_tl(sr));
+ gen_helper_mmu_read(cpu_R[dc->rd], cpu_env, tcg_const_tl(sr));
return;
}
#endif
}
if (u)
- gen_helper_divu(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
+ gen_helper_divu(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
+ cpu_R[dc->ra]);
else
- gen_helper_divs(cpu_R[dc->rd], *(dec_alu_op_b(dc)), cpu_R[dc->ra]);
+ gen_helper_divs(cpu_R[dc->rd], cpu_env, *(dec_alu_op_b(dc)),
+ cpu_R[dc->ra]);
if (!dc->rd)
tcg_gen_movi_tl(cpu_R[dc->rd], 0);
}
LOG_DIS("swapb r%d r%d\n", dc->rd, dc->ra);
tcg_gen_bswap32_i32(cpu_R[dc->rd], cpu_R[dc->ra]);
break;
- case 0x1e1:
+ case 0x1e2:
/*swaph */
LOG_DIS("swaph r%d r%d\n", dc->rd, dc->ra);
tcg_gen_rotri_i32(cpu_R[dc->rd], cpu_R[dc->ra], 16);
tcg_gen_add_tl(*t, cpu_R[dc->ra], cpu_R[dc->rb]);
if (stackprot) {
- gen_helper_stackprot(*t);
+ gen_helper_stackprot(cpu_env, *t);
}
return t;
}
}
if (stackprot) {
- gen_helper_stackprot(*t);
+ gen_helper_stackprot(cpu_env, *t);
}
return t;
}
gen_load(dc, v, *addr, size);
tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc);
- gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
+ gen_helper_memalign(cpu_env, *addr, tcg_const_tl(dc->rd),
tcg_const_tl(0), tcg_const_tl(size - 1));
if (dc->rd) {
if (rev) {
* the alignment checks in between the probe and the mem
* access.
*/
- gen_helper_memalign(*addr, tcg_const_tl(dc->rd),
+ gen_helper_memalign(cpu_env, *addr, tcg_const_tl(dc->rd),
tcg_const_tl(1), tcg_const_tl(size - 1));
}
/* Memory barrier. */
mbar = (dc->ir >> 16) & 31;
if (mbar == 2 && dc->imm == 4) {
+ /* mbar IMM & 16 decodes to sleep. */
+ if (dc->rd & 16) {
+ TCGv_i32 tmp_hlt = tcg_const_i32(EXCP_HLT);
+ TCGv_i32 tmp_1 = tcg_const_i32(1);
+
+ LOG_DIS("sleep\n");
+
+ t_sync_flags(dc);
+ tcg_gen_st_i32(tmp_1, cpu_env,
+ -offsetof(MicroBlazeCPU, env)
+ +offsetof(CPUState, halted));
+ tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc + 4);
+ gen_helper_raise_exception(cpu_env, tmp_hlt);
+ tcg_temp_free_i32(tmp_hlt);
+ tcg_temp_free_i32(tmp_1);
+ return;
+ }
LOG_DIS("mbar %d\n", dc->rd);
/* Break the TB. */
dc->cpustate_changed = 1;
switch (fpu_insn) {
case 0:
- gen_helper_fadd(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
+ gen_helper_fadd(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
+ cpu_R[dc->rb]);
break;
case 1:
- gen_helper_frsub(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
+ gen_helper_frsub(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
+ cpu_R[dc->rb]);
break;
case 2:
- gen_helper_fmul(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
+ gen_helper_fmul(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
+ cpu_R[dc->rb]);
break;
case 3:
- gen_helper_fdiv(cpu_R[dc->rd], cpu_R[dc->ra], cpu_R[dc->rb]);
+ gen_helper_fdiv(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra],
+ cpu_R[dc->rb]);
break;
case 4:
switch ((dc->ir >> 4) & 7) {
case 0:
- gen_helper_fcmp_un(cpu_R[dc->rd],
+ gen_helper_fcmp_un(cpu_R[dc->rd], cpu_env,
cpu_R[dc->ra], cpu_R[dc->rb]);
break;
case 1:
- gen_helper_fcmp_lt(cpu_R[dc->rd],
+ gen_helper_fcmp_lt(cpu_R[dc->rd], cpu_env,
cpu_R[dc->ra], cpu_R[dc->rb]);
break;
case 2:
- gen_helper_fcmp_eq(cpu_R[dc->rd],
+ gen_helper_fcmp_eq(cpu_R[dc->rd], cpu_env,
cpu_R[dc->ra], cpu_R[dc->rb]);
break;
case 3:
- gen_helper_fcmp_le(cpu_R[dc->rd],
+ gen_helper_fcmp_le(cpu_R[dc->rd], cpu_env,
cpu_R[dc->ra], cpu_R[dc->rb]);
break;
case 4:
- gen_helper_fcmp_gt(cpu_R[dc->rd],
+ gen_helper_fcmp_gt(cpu_R[dc->rd], cpu_env,
cpu_R[dc->ra], cpu_R[dc->rb]);
break;
case 5:
- gen_helper_fcmp_ne(cpu_R[dc->rd],
+ gen_helper_fcmp_ne(cpu_R[dc->rd], cpu_env,
cpu_R[dc->ra], cpu_R[dc->rb]);
break;
case 6:
- gen_helper_fcmp_ge(cpu_R[dc->rd],
+ gen_helper_fcmp_ge(cpu_R[dc->rd], cpu_env,
cpu_R[dc->ra], cpu_R[dc->rb]);
break;
default:
if (!dec_check_fpuv2(dc)) {
return;
}
- gen_helper_flt(cpu_R[dc->rd], cpu_R[dc->ra]);
+ gen_helper_flt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
break;
case 6:
if (!dec_check_fpuv2(dc)) {
return;
}
- gen_helper_fint(cpu_R[dc->rd], cpu_R[dc->ra]);
+ gen_helper_fint(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
break;
case 7:
if (!dec_check_fpuv2(dc)) {
return;
}
- gen_helper_fsqrt(cpu_R[dc->rd], cpu_R[dc->ra]);
+ gen_helper_fsqrt(cpu_R[dc->rd], cpu_env, cpu_R[dc->ra]);
break;
default:
{{0, 0}, dec_null}
};
-static inline void decode(DisasContext *dc)
+static inline void decode(DisasContext *dc, uint32_t ir)
{
- uint32_t ir;
int i;
- if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
+ if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
tcg_gen_debug_insn_start(dc->pc);
+ }
- dc->ir = ir = ldl_code(dc->pc);
+ dc->ir = ir;
LOG_DIS("%8.8x\t", dc->ir);
if (dc->ir)
}
/* generate intermediate code for basic block 'tb'. */
-static void
-gen_intermediate_code_internal(CPUMBState *env, TranslationBlock *tb,
- int search_pc)
+static inline void
+gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb,
+ bool search_pc)
{
+ CPUState *cs = CPU(cpu);
+ CPUMBState *env = &cpu->env;
uint16_t *gen_opc_end;
uint32_t pc_start;
int j, lj;
int num_insns;
int max_insns;
- qemu_log_try_set_file(stderr);
-
pc_start = tb->pc;
dc->env = env;
dc->tb = tb;
org_flags = dc->synced_flags = dc->tb_flags = tb->flags;
- gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
+ gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
dc->is_jmp = DISAS_NEXT;
dc->jmp = 0;
dc->jmp = JMP_INDIRECT;
}
dc->pc = pc_start;
- dc->singlestep_enabled = env->singlestep_enabled;
+ dc->singlestep_enabled = cs->singlestep_enabled;
dc->cpustate_changed = 0;
dc->abort_at_next_insn = 0;
dc->nr_nops = 0;
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
#if !SIM_COMPAT
qemu_log("--------------\n");
- log_cpu_state(env, 0);
+ log_cpu_state(CPU(cpu), 0);
#endif
}
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
- gen_icount_start();
+ gen_tb_start();
do
{
#if SIM_COMPAT
check_breakpoint(env, dc);
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
if (lj < j) {
lj++;
while (lj < j)
- gen_opc_instr_start[lj++] = 0;
+ tcg_ctx.gen_opc_instr_start[lj++] = 0;
}
- gen_opc_pc[lj] = dc->pc;
- gen_opc_instr_start[lj] = 1;
- gen_opc_icount[lj] = num_insns;
+ tcg_ctx.gen_opc_pc[lj] = dc->pc;
+ tcg_ctx.gen_opc_instr_start[lj] = 1;
+ tcg_ctx.gen_opc_icount[lj] = num_insns;
}
/* Pretty disas. */
gen_io_start();
dc->clear_imm = 1;
- decode(dc);
+ decode(dc, cpu_ldl_code(env, dc->pc));
if (dc->clear_imm)
dc->tb_flags &= ~IMM_FLAG;
dc->pc += 4;
break;
}
}
- if (env->singlestep_enabled)
+ if (cs->singlestep_enabled) {
break;
+ }
} while (!dc->is_jmp && !dc->cpustate_changed
- && gen_opc_ptr < gen_opc_end
+ && tcg_ctx.gen_opc_ptr < gen_opc_end
&& !singlestep
&& (dc->pc < next_page_start)
&& num_insns < max_insns);
}
t_sync_flags(dc);
- if (unlikely(env->singlestep_enabled)) {
+ if (unlikely(cs->singlestep_enabled)) {
TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG);
if (dc->is_jmp != DISAS_JUMP) {
tcg_gen_movi_tl(cpu_SR[SR_PC], npc);
}
- gen_helper_raise_exception(tmp);
+ gen_helper_raise_exception(cpu_env, tmp);
tcg_temp_free_i32(tmp);
} else {
switch(dc->is_jmp) {
break;
}
}
- gen_icount_end(tb, num_insns);
- *gen_opc_ptr = INDEX_op_end;
+ gen_tb_end(tb, num_insns);
+ *tcg_ctx.gen_opc_ptr = INDEX_op_end;
if (search_pc) {
- j = gen_opc_ptr - gen_opc_buf;
+ j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
lj++;
while (lj <= j)
- gen_opc_instr_start[lj++] = 0;
+ tcg_ctx.gen_opc_instr_start[lj++] = 0;
} else {
tb->size = dc->pc - pc_start;
tb->icount = num_insns;
if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
qemu_log("\n");
#if DISAS_GNU
- log_target_disas(pc_start, dc->pc - pc_start, 0);
+ log_target_disas(env, pc_start, dc->pc - pc_start, 0);
#endif
qemu_log("\nisize=%d osize=%td\n",
- dc->pc - pc_start, gen_opc_ptr - gen_opc_buf);
+ dc->pc - pc_start, tcg_ctx.gen_opc_ptr -
+ tcg_ctx.gen_opc_buf);
}
#endif
#endif
void gen_intermediate_code (CPUMBState *env, struct TranslationBlock *tb)
{
- gen_intermediate_code_internal(env, tb, 0);
+ gen_intermediate_code_internal(mb_env_get_cpu(env), tb, false);
}
void gen_intermediate_code_pc (CPUMBState *env, struct TranslationBlock *tb)
{
- gen_intermediate_code_internal(env, tb, 1);
+ gen_intermediate_code_internal(mb_env_get_cpu(env), tb, true);
}
-void cpu_dump_state (CPUMBState *env, FILE *f, fprintf_function cpu_fprintf,
- int flags)
+void mb_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
+ int flags)
{
+ MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+ CPUMBState *env = &cpu->env;
int i;
if (!env || !f)
MicroBlazeCPU *cpu_mb_init(const char *cpu_model)
{
MicroBlazeCPU *cpu;
- static int tcg_initialized = 0;
- int i;
cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU));
- cpu_reset(CPU(cpu));
- qemu_init_vcpu(&cpu->env);
+ object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
- if (tcg_initialized) {
- return cpu;
- }
+ return cpu;
+}
- tcg_initialized = 1;
+void mb_tcg_init(void)
+{
+ int i;
cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
}
#define GEN_HELPER 2
#include "helper.h"
-
- return cpu;
}
void restore_state_to_opc(CPUMBState *env, TranslationBlock *tb, int pc_pos)
{
- env->sregs[SR_PC] = gen_opc_pc[pc_pos];
+ env->sregs[SR_PC] = tcg_ctx.gen_opc_pc[pc_pos];
}