From 86342dcc9b73eac8310b9dc5fd1356bbfa5b9c8e Mon Sep 17 00:00:00 2001 From: Fathi Boudra Date: Mon, 5 Aug 2013 10:19:49 +0300 Subject: Imported Upstream version 1.5.0-2013.06+git74+20130802+ef1b0ae --- target-unicore32/cpu-qom.h | 6 +++ target-unicore32/cpu.c | 23 ++++++++++++ target-unicore32/cpu.h | 5 +-- target-unicore32/helper.c | 12 +++--- target-unicore32/softmmu.c | 6 ++- target-unicore32/translate.c | 87 +++++++------------------------------------- 6 files changed, 52 insertions(+), 87 deletions(-) (limited to 'target-unicore32') diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h index fe40b2d..ba4dee4 100644 --- a/target-unicore32/cpu-qom.h +++ b/target-unicore32/cpu-qom.h @@ -25,6 +25,7 @@ /** * UniCore32CPUClass: + * @parent_realize: The parent class' realize handler. * * A UniCore32 CPU model. */ @@ -32,6 +33,8 @@ typedef struct UniCore32CPUClass { /*< private >*/ CPUClass parent_class; /*< public >*/ + + DeviceRealize parent_realize; } UniCore32CPUClass; /** @@ -55,5 +58,8 @@ static inline UniCore32CPU *uc32_env_get_cpu(CPUUniCore32State *env) #define ENV_GET_CPU(e) CPU(uc32_env_get_cpu(e)) +#define ENV_OFFSET offsetof(UniCore32CPU, env) + +void uc32_cpu_do_interrupt(CPUState *cpu); #endif diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c index 4e4177f..66a1a74 100644 --- a/target-unicore32/cpu.c +++ b/target-unicore32/cpu.c @@ -81,11 +81,24 @@ static const UniCore32CPUInfo uc32_cpus[] = { { .name = "any", .instance_init = uc32_any_cpu_initfn }, }; +static void uc32_cpu_realizefn(DeviceState *dev, Error **errp) +{ + UniCore32CPU *cpu = UNICORE32_CPU(dev); + UniCore32CPUClass *ucc = UNICORE32_CPU_GET_CLASS(dev); + + qemu_init_vcpu(&cpu->env); + + ucc->parent_realize(dev, errp); +} + static void uc32_cpu_initfn(Object *obj) { + CPUState *cs = CPU(obj); UniCore32CPU *cpu = UNICORE32_CPU(obj); CPUUniCore32State *env = &cpu->env; + static bool inited; + cs->env_ptr = env; cpu_exec_init(env); #ifdef CONFIG_USER_ONLY @@ -97,6 +110,11 @@ static void uc32_cpu_initfn(Object *obj) #endif tlb_flush(env, 1); + + if (tcg_enabled() && !inited) { + inited = true; + uc32_translate_init(); + } } static const VMStateDescription vmstate_uc32_cpu = { @@ -108,8 +126,13 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); + UniCore32CPUClass *ucc = UNICORE32_CPU_CLASS(oc); + + ucc->parent_realize = dc->realize; + dc->realize = uc32_cpu_realizefn; cc->class_by_name = uc32_cpu_class_by_name; + cc->do_interrupt = uc32_cpu_do_interrupt; dc->vmsd = &vmstate_uc32_cpu; } diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h index ae9a9d6..5b2b9d1 100644 --- a/target-unicore32/cpu.h +++ b/target-unicore32/cpu.h @@ -176,14 +176,11 @@ static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc } void uc32_translate_init(void); -void do_interrupt(CPUUniCore32State *); void switch_mode(CPUUniCore32State *, int); static inline bool cpu_has_work(CPUState *cpu) { - CPUUniCore32State *env = &UNICORE32_CPU(cpu)->env; - - return env->interrupt_request & + return cpu->interrupt_request & (CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB); } diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c index 3a92232..61eb2c3 100644 --- a/target-unicore32/helper.c +++ b/target-unicore32/helper.c @@ -30,7 +30,6 @@ CPUUniCore32State *uc32_cpu_init(const char *cpu_model) UniCore32CPU *cpu; CPUUniCore32State *env; ObjectClass *oc; - static int inited = 1; oc = cpu_class_by_name(TYPE_UNICORE32_CPU, cpu_model); if (oc == NULL) { @@ -40,12 +39,8 @@ CPUUniCore32State *uc32_cpu_init(const char *cpu_model) env = &cpu->env; env->cpu_model_str = cpu_model; - if (inited) { - inited = 0; - uc32_translate_init(); - } + object_property_set_bool(OBJECT(cpu), true, "realized", NULL); - qemu_init_vcpu(env); return env; } @@ -247,8 +242,11 @@ void switch_mode(CPUUniCore32State *env, int mode) } } -void do_interrupt(CPUUniCore32State *env) +void uc32_cpu_do_interrupt(CPUState *cs) { + UniCore32CPU *cpu = UNICORE32_CPU(cs); + CPUUniCore32State *env = &cpu->env; + cpu_abort(env, "NO interrupt in user mode\n"); } diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c index fc27100..eadaeb1 100644 --- a/target-unicore32/softmmu.c +++ b/target-unicore32/softmmu.c @@ -72,8 +72,10 @@ void switch_mode(CPUUniCore32State *env, int mode) } /* Handle a CPU exception. */ -void do_interrupt(CPUUniCore32State *env) +void uc32_cpu_do_interrupt(CPUState *cs) { + UniCore32CPU *cpu = UNICORE32_CPU(cs); + CPUUniCore32State *env = &cpu->env; uint32_t addr; int new_mode; @@ -112,7 +114,7 @@ void do_interrupt(CPUUniCore32State *env) /* The PC already points to the proper instruction. */ env->regs[30] = env->regs[31]; env->regs[31] = addr; - env->interrupt_request |= CPU_INTERRUPT_EXITTB; + cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } static int get_phys_addr_ucv2(CPUUniCore32State *env, uint32_t address, diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c index f4498bc..151e35e 100644 --- a/target-unicore32/translate.c +++ b/target-unicore32/translate.c @@ -267,37 +267,6 @@ static void gen_exception(int excp) dead_tmp(tmp); } -/* FIXME: Most targets have native widening multiplication. - It would be good to use that instead of a full wide multiply. */ -/* 32x32->64 multiply. Marks inputs as dead. */ -static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b) -{ - TCGv_i64 tmp1 = tcg_temp_new_i64(); - TCGv_i64 tmp2 = tcg_temp_new_i64(); - - tcg_gen_extu_i32_i64(tmp1, a); - dead_tmp(a); - tcg_gen_extu_i32_i64(tmp2, b); - dead_tmp(b); - tcg_gen_mul_i64(tmp1, tmp1, tmp2); - tcg_temp_free_i64(tmp2); - return tmp1; -} - -static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b) -{ - TCGv_i64 tmp1 = tcg_temp_new_i64(); - TCGv_i64 tmp2 = tcg_temp_new_i64(); - - tcg_gen_ext_i32_i64(tmp1, a); - dead_tmp(a); - tcg_gen_ext_i32_i64(tmp2, b); - dead_tmp(b); - tcg_gen_mul_i64(tmp1, tmp1, tmp2); - tcg_temp_free_i64(tmp2); - return tmp1; -} - #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUUniCore32State, CF)) /* Set CF to the top bit of var. */ @@ -1219,38 +1188,6 @@ static void disas_coproc_insn(CPUUniCore32State *env, DisasContext *s, } } - -/* Store a 64-bit value to a register pair. Clobbers val. */ -static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val) -{ - TCGv tmp; - tmp = new_tmp(); - tcg_gen_trunc_i64_i32(tmp, val); - store_reg(s, rlow, tmp); - tmp = new_tmp(); - tcg_gen_shri_i64(val, val, 32); - tcg_gen_trunc_i64_i32(tmp, val); - store_reg(s, rhigh, tmp); -} - -/* load and add a 64-bit value from a register pair. */ -static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh) -{ - TCGv_i64 tmp; - TCGv tmpl; - TCGv tmph; - - /* Load 64-bit value rd:rn. */ - tmpl = load_reg(s, rlow); - tmph = load_reg(s, rhigh); - tmp = tcg_temp_new_i64(); - tcg_gen_concat_i32_i64(tmp, tmpl, tmph); - dead_tmp(tmpl); - dead_tmp(tmph); - tcg_gen_add_i64(val, val, tmp); - tcg_temp_free_i64(tmp); -} - /* data processing instructions */ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn) { @@ -1445,24 +1382,26 @@ static void do_datap(CPUUniCore32State *env, DisasContext *s, uint32_t insn) /* multiply */ static void do_mult(CPUUniCore32State *env, DisasContext *s, uint32_t insn) { - TCGv tmp; - TCGv tmp2; - TCGv_i64 tmp64; + TCGv tmp, tmp2, tmp3, tmp4; if (UCOP_SET(27)) { /* 64 bit mul */ tmp = load_reg(s, UCOP_REG_M); tmp2 = load_reg(s, UCOP_REG_N); if (UCOP_SET(26)) { - tmp64 = gen_muls_i64_i32(tmp, tmp2); + tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2); } else { - tmp64 = gen_mulu_i64_i32(tmp, tmp2); + tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2); } if (UCOP_SET(25)) { /* mult accumulate */ - gen_addq(s, tmp64, UCOP_REG_LO, UCOP_REG_HI); - } - gen_storeq_reg(s, UCOP_REG_LO, UCOP_REG_HI, tmp64); - tcg_temp_free_i64(tmp64); + tmp3 = load_reg(s, UCOP_REG_LO); + tmp4 = load_reg(s, UCOP_REG_HI); + tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, tmp3, tmp4); + dead_tmp(tmp3); + dead_tmp(tmp4); + } + store_reg(s, UCOP_REG_LO, tmp); + store_reg(s, UCOP_REG_HI, tmp2); } else { /* 32 bit mul */ tmp = load_reg(s, UCOP_REG_M); @@ -1982,7 +1921,7 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env, } #endif - gen_icount_start(); + gen_tb_start(); do { if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { QTAILQ_FOREACH(bp, &env->breakpoints, entry) { @@ -2102,7 +2041,7 @@ static inline void gen_intermediate_code_internal(CPUUniCore32State *env, } done_generating: - gen_icount_end(tb, num_insns); + gen_tb_end(tb, num_insns); *tcg_ctx.gen_opc_ptr = INDEX_op_end; #ifdef DEBUG_DISAS -- cgit v1.2.3