diff options
Diffstat (limited to 'qemu/target-cris')
-rw-r--r-- | qemu/target-cris/cpu-qom.h | 4 | ||||
-rw-r--r-- | qemu/target-cris/cpu.c | 10 | ||||
-rw-r--r-- | qemu/target-cris/cpu.h | 21 | ||||
-rw-r--r-- | qemu/target-cris/gdbstub.c | 2 | ||||
-rw-r--r-- | qemu/target-cris/helper.c | 1 | ||||
-rw-r--r-- | qemu/target-cris/helper.h | 1 | ||||
-rw-r--r-- | qemu/target-cris/machine.c | 168 | ||||
-rw-r--r-- | qemu/target-cris/mmu.c | 4 | ||||
-rw-r--r-- | qemu/target-cris/op_helper.c | 6 | ||||
-rw-r--r-- | qemu/target-cris/translate.c | 177 | ||||
-rw-r--r-- | qemu/target-cris/translate_v10.c | 102 |
11 files changed, 220 insertions, 276 deletions
diff --git a/qemu/target-cris/cpu-qom.h b/qemu/target-cris/cpu-qom.h index 6fc30c208..df4c0b50a 100644 --- a/qemu/target-cris/cpu-qom.h +++ b/qemu/target-cris/cpu-qom.h @@ -73,6 +73,10 @@ static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env) #define ENV_OFFSET offsetof(CRISCPU, env) +#ifndef CONFIG_USER_ONLY +extern const struct VMStateDescription vmstate_cris_cpu; +#endif + void cris_cpu_do_interrupt(CPUState *cpu); void crisv10_cpu_do_interrupt(CPUState *cpu); bool cris_cpu_exec_interrupt(CPUState *cpu, int int_req); diff --git a/qemu/target-cris/cpu.c b/qemu/target-cris/cpu.c index b17e849e2..1cb79dd97 100644 --- a/qemu/target-cris/cpu.c +++ b/qemu/target-cris/cpu.c @@ -21,6 +21,8 @@ * <http://www.gnu.org/licenses/lgpl-2.1.html> */ +#include "qemu/osdep.h" +#include "qapi/error.h" #include "cpu.h" #include "qemu-common.h" #include "mmu.h" @@ -302,12 +304,20 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data) cc->handle_mmu_fault = cris_cpu_handle_mmu_fault; #else cc->get_phys_page_debug = cris_cpu_get_phys_page_debug; + dc->vmsd = &vmstate_cris_cpu; #endif cc->gdb_num_core_regs = 49; cc->gdb_stop_before_watchpoint = true; cc->disas_set_info = cris_disas_set_info; + + /* + * Reason: cris_cpu_initfn() calls cpu_exec_init(), which saves + * the object in cpus -> dangling pointer after final + * object_unref(). + */ + dc->cannot_destroy_with_object_finalize_yet = true; } static const TypeInfo cris_cpu_type_info = { diff --git a/qemu/target-cris/cpu.h b/qemu/target-cris/cpu.h index d422e3571..415cf9143 100644 --- a/qemu/target-cris/cpu.h +++ b/qemu/target-cris/cpu.h @@ -20,7 +20,6 @@ #ifndef CPU_CRIS_H #define CPU_CRIS_H -#include "config.h" #include "qemu-common.h" #define TARGET_LONG_BITS 32 @@ -29,8 +28,6 @@ #include "exec/cpu-defs.h" -#define ELF_MACHINE EM_CRIS - #define EXCP_NMI 1 #define EXCP_GURU 2 #define EXCP_BUSFAULT 3 @@ -108,6 +105,11 @@ #define NB_MMU_MODES 2 +typedef struct { + uint32_t hi; + uint32_t lo; +} TLBSet; + typedef struct CPUCRISState { uint32_t regs[16]; /* P0 - P15 are referred to as special registers in the docs. */ @@ -151,7 +153,7 @@ typedef struct CPUCRISState { uint32_t sregs[4][16]; /* Linear feedback shift reg in the mmu. Used to provide pseudo - randomness for the 'hint' the mmu gives to sw for chosing valid + randomness for the 'hint' the mmu gives to sw for choosing valid sets on TLB refills. */ uint32_t mmu_rand_lfsr; @@ -161,11 +163,7 @@ typedef struct CPUCRISState { * * One for I and another for D. */ - struct - { - uint32_t hi; - uint32_t lo; - } tlbsets[2][4][16]; + TLBSet tlbsets[2][4][16]; CPU_COMMON @@ -224,16 +222,13 @@ enum { #define cpu_init(cpu_model) CPU(cpu_cris_init(cpu_model)) #define cpu_exec cpu_cris_exec -#define cpu_gen_code cpu_cris_gen_code #define cpu_signal_handler cpu_cris_signal_handler -#define CPU_SAVE_VERSION 1 - /* MMU modes definitions */ #define MMU_MODE0_SUFFIX _kernel #define MMU_MODE1_SUFFIX _user #define MMU_USER_IDX 1 -static inline int cpu_mmu_index (CPUCRISState *env) +static inline int cpu_mmu_index (CPUCRISState *env, bool ifetch) { return !!(env->pregs[PR_CCS] & U_FLAG); } diff --git a/qemu/target-cris/gdbstub.c b/qemu/target-cris/gdbstub.c index 5db3683ab..1bbf17b04 100644 --- a/qemu/target-cris/gdbstub.c +++ b/qemu/target-cris/gdbstub.c @@ -17,7 +17,7 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ -#include "config.h" +#include "qemu/osdep.h" #include "qemu-common.h" #include "exec/gdbstub.h" diff --git a/qemu/target-cris/helper.c b/qemu/target-cris/helper.c index df6c9fdcb..1eb9fd918 100644 --- a/qemu/target-cris/helper.c +++ b/qemu/target-cris/helper.c @@ -18,6 +18,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include "qemu/osdep.h" #include "cpu.h" #include "mmu.h" #include "qemu/host-utils.h" diff --git a/qemu/target-cris/helper.h b/qemu/target-cris/helper.h index 0b383b25a..ff3595641 100644 --- a/qemu/target-cris/helper.h +++ b/qemu/target-cris/helper.h @@ -1,7 +1,6 @@ DEF_HELPER_2(raise_exception, void, env, i32) DEF_HELPER_2(tlb_flush_pid, void, env, i32) DEF_HELPER_2(spc_write, void, env, i32) -DEF_HELPER_3(dump, void, i32, i32, i32) DEF_HELPER_1(rfe, void, env) DEF_HELPER_1(rfn, void, env) diff --git a/qemu/target-cris/machine.c b/qemu/target-cris/machine.c index 8f9c0dd59..9cc2820e8 100644 --- a/qemu/target-cris/machine.c +++ b/qemu/target-cris/machine.c @@ -1,90 +1,92 @@ -#include "hw/hw.h" -#include "hw/boards.h" - -void cpu_save(QEMUFile *f, void *opaque) -{ - CPUCRISState *env = opaque; - int i; - int s; - int mmu; - - for (i = 0; i < 16; i++) - qemu_put_be32(f, env->regs[i]); - for (i = 0; i < 16; i++) - qemu_put_be32(f, env->pregs[i]); - - qemu_put_be32(f, env->pc); - qemu_put_be32(f, env->ksp); +/* + * CRIS virtual CPU state save/load support + * + * Copyright (c) 2012 Red Hat, Inc. + * Written by Juan Quintela <quintela@redhat.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <http://www.gnu.org/licenses/>. + */ - qemu_put_be32(f, env->dslot); - qemu_put_be32(f, env->btaken); - qemu_put_be32(f, env->btarget); - - qemu_put_be32(f, env->cc_op); - qemu_put_be32(f, env->cc_mask); - qemu_put_be32(f, env->cc_dest); - qemu_put_be32(f, env->cc_src); - qemu_put_be32(f, env->cc_result); - qemu_put_be32(f, env->cc_size); - qemu_put_be32(f, env->cc_x); - - for (s = 0; s < 4; s++) { - for (i = 0; i < 16; i++) - qemu_put_be32(f, env->sregs[s][i]); - } +#include "qemu/osdep.h" +#include "hw/hw.h" - qemu_put_be32(f, env->mmu_rand_lfsr); - for (mmu = 0; mmu < 2; mmu++) { - for (s = 0; s < 4; s++) { - for (i = 0; i < 16; i++) { - qemu_put_be32(f, env->tlbsets[mmu][s][i].lo); - qemu_put_be32(f, env->tlbsets[mmu][s][i].hi); - } - } +static const VMStateDescription vmstate_tlbset = { + .name = "cpu/tlbset", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(lo, TLBSet), + VMSTATE_UINT32(hi, TLBSet), + VMSTATE_END_OF_LIST() } -} - -int cpu_load(QEMUFile *f, void *opaque, int version_id) -{ - CPUCRISState *env = opaque; - int i; - int s; - int mmu; - - for (i = 0; i < 16; i++) - env->regs[i] = qemu_get_be32(f); - for (i = 0; i < 16; i++) - env->pregs[i] = qemu_get_be32(f); - - env->pc = qemu_get_be32(f); - env->ksp = qemu_get_be32(f); +}; - env->dslot = qemu_get_be32(f); - env->btaken = qemu_get_be32(f); - env->btarget = qemu_get_be32(f); - - env->cc_op = qemu_get_be32(f); - env->cc_mask = qemu_get_be32(f); - env->cc_dest = qemu_get_be32(f); - env->cc_src = qemu_get_be32(f); - env->cc_result = qemu_get_be32(f); - env->cc_size = qemu_get_be32(f); - env->cc_x = qemu_get_be32(f); - - for (s = 0; s < 4; s++) { - for (i = 0; i < 16; i++) - env->sregs[s][i] = qemu_get_be32(f); +static const VMStateDescription vmstate_cris_env = { + .name = "env", + .version_id = 2, + .minimum_version_id = 2, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, CPUCRISState, 16), + VMSTATE_UINT32_ARRAY(pregs, CPUCRISState, 16), + VMSTATE_UINT32(pc, CPUCRISState), + VMSTATE_UINT32(ksp, CPUCRISState), + VMSTATE_INT32(dslot, CPUCRISState), + VMSTATE_INT32(btaken, CPUCRISState), + VMSTATE_UINT32(btarget, CPUCRISState), + VMSTATE_UINT32(cc_op, CPUCRISState), + VMSTATE_UINT32(cc_mask, CPUCRISState), + VMSTATE_UINT32(cc_dest, CPUCRISState), + VMSTATE_UINT32(cc_src, CPUCRISState), + VMSTATE_UINT32(cc_result, CPUCRISState), + VMSTATE_INT32(cc_size, CPUCRISState), + VMSTATE_INT32(cc_x, CPUCRISState), + VMSTATE_INT32(locked_irq, CPUCRISState), + VMSTATE_INT32(interrupt_vector, CPUCRISState), + VMSTATE_INT32(fault_vector, CPUCRISState), + VMSTATE_INT32(trap_vector, CPUCRISState), + VMSTATE_UINT32_ARRAY(sregs[0], CPUCRISState, 16), + VMSTATE_UINT32_ARRAY(sregs[1], CPUCRISState, 16), + VMSTATE_UINT32_ARRAY(sregs[2], CPUCRISState, 16), + VMSTATE_UINT32_ARRAY(sregs[3], CPUCRISState, 16), + VMSTATE_UINT32(mmu_rand_lfsr, CPUCRISState), + VMSTATE_STRUCT_ARRAY(tlbsets[0][0], CPUCRISState, 16, 0, + vmstate_tlbset, TLBSet), + VMSTATE_STRUCT_ARRAY(tlbsets[0][1], CPUCRISState, 16, 0, + vmstate_tlbset, TLBSet), + VMSTATE_STRUCT_ARRAY(tlbsets[0][2], CPUCRISState, 16, 0, + vmstate_tlbset, TLBSet), + VMSTATE_STRUCT_ARRAY(tlbsets[0][3], CPUCRISState, 16, 0, + vmstate_tlbset, TLBSet), + VMSTATE_STRUCT_ARRAY(tlbsets[1][0], CPUCRISState, 16, 0, + vmstate_tlbset, TLBSet), + VMSTATE_STRUCT_ARRAY(tlbsets[1][1], CPUCRISState, 16, 0, + vmstate_tlbset, TLBSet), + VMSTATE_STRUCT_ARRAY(tlbsets[1][2], CPUCRISState, 16, 0, + vmstate_tlbset, TLBSet), + VMSTATE_STRUCT_ARRAY(tlbsets[1][3], CPUCRISState, 16, 0, + vmstate_tlbset, TLBSet), + VMSTATE_END_OF_LIST() } +}; - env->mmu_rand_lfsr = qemu_get_be32(f); - for (mmu = 0; mmu < 2; mmu++) { - for (s = 0; s < 4; s++) { - for (i = 0; i < 16; i++) { - env->tlbsets[mmu][s][i].lo = qemu_get_be32(f); - env->tlbsets[mmu][s][i].hi = qemu_get_be32(f); - } - } +const VMStateDescription vmstate_cris_cpu = { + .name = "cpu", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_CPU(), + VMSTATE_STRUCT(env, CRISCPU, 1, vmstate_cris_env, CPUCRISState), + VMSTATE_END_OF_LIST() } - - return 0; -} +}; diff --git a/qemu/target-cris/mmu.c b/qemu/target-cris/mmu.c index 1c95a415f..4278d2dce 100644 --- a/qemu/target-cris/mmu.c +++ b/qemu/target-cris/mmu.c @@ -18,8 +18,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef CONFIG_USER_ONLY - +#include "qemu/osdep.h" #include "cpu.h" #include "mmu.h" @@ -360,4 +359,3 @@ int cris_mmu_translate(struct cris_mmu_result *res, env->pregs[PR_SRS] = old_srs; return miss; } -#endif diff --git a/qemu/target-cris/op_helper.c b/qemu/target-cris/op_helper.c index 5c0c14d99..320f2b80d 100644 --- a/qemu/target-cris/op_helper.c +++ b/qemu/target-cris/op_helper.c @@ -18,6 +18,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include "qemu/osdep.h" #include "cpu.h" #include "mmu.h" #include "exec/helper-proto.h" @@ -91,11 +92,6 @@ void helper_spc_write(CPUCRISState *env, uint32_t new_spc) #endif } -void helper_dump(uint32_t a0, uint32_t a1, uint32_t a2) -{ - qemu_log("%s: a0=%x a1=%x\n", __func__, a0, a1); -} - /* Used by the tlb decoder. */ #define EXTRACT_FIELD(src, start, end) \ (((src) >> start) & ((1 << (end - start + 1)) - 1)) diff --git a/qemu/target-cris/translate.c b/qemu/target-cris/translate.c index 3e59601eb..a73176c11 100644 --- a/qemu/target-cris/translate.c +++ b/qemu/target-cris/translate.c @@ -23,6 +23,7 @@ * The condition code translation is in need of attention. */ +#include "qemu/osdep.h" #include "cpu.h" #include "disas/disas.h" #include "tcg-op.h" @@ -34,6 +35,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" #define DISAS_CRIS 0 @@ -58,7 +60,7 @@ #define CC_MASK_NZVC 0xf #define CC_MASK_RNZV 0x10e -static TCGv_ptr cpu_env; +static TCGv_env cpu_env; static TCGv cpu_R[16]; static TCGv cpu_PR[16]; static TCGv cc_x; @@ -102,9 +104,9 @@ typedef struct DisasContext { int cc_size_uptodate; /* -1 invalid or last written value. */ - int cc_x_uptodate; /* 1 - ccs, 2 - known | X_FLAG. 0 not uptodate. */ - int flags_uptodate; /* Wether or not $ccs is uptodate. */ - int flagx_known; /* Wether or not flags_x has the x flag known at + int cc_x_uptodate; /* 1 - ccs, 2 - known | X_FLAG. 0 not up-to-date. */ + int flags_uptodate; /* Whether or not $ccs is up-to-date. */ + int flagx_known; /* Whether or not flags_x has the x flag known at translation time. */ int flags_x; @@ -130,8 +132,10 @@ typedef struct DisasContext { static void gen_BUG(DisasContext *dc, const char *file, int line) { - printf("BUG: pc=%x %s %d\n", dc->pc, file, line); - qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line); + fprintf(stderr, "BUG: pc=%x %s %d\n", dc->pc, file, line); + if (qemu_log_separate()) { + qemu_log("BUG: pc=%x %s %d\n", dc->pc, file, line); + } cpu_abort(CPU(dc->cpu), "%s:%d\n", file, line); } @@ -311,7 +315,7 @@ static void t_gen_asr(TCGv d, TCGv a, TCGv b) static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b) { - TCGLabel *l1 = gen_new_label(); + TCGv t = tcg_temp_new(); /* * d <<= 1 @@ -319,9 +323,9 @@ static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b) * d -= s; */ tcg_gen_shli_tl(d, a, 1); - tcg_gen_brcond_tl(TCG_COND_LTU, d, b, l1); - tcg_gen_sub_tl(d, d, b); - gen_set_label(l1); + tcg_gen_sub_tl(t, d, b); + tcg_gen_movcond_tl(TCG_COND_GEU, d, d, b, t, d); + tcg_temp_free(t); } static void t_gen_cris_mstep(TCGv d, TCGv a, TCGv b, TCGv ccs) @@ -769,13 +773,7 @@ static void cris_alu_op_exec(DisasContext *dc, int op, t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]); break; case CC_OP_BOUND: - { - TCGLabel *l1 = gen_new_label(); - tcg_gen_mov_tl(dst, a); - tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1); - tcg_gen_mov_tl(dst, b); - gen_set_label(l1); - } + tcg_gen_movcond_tl(TCG_COND_LEU, dst, a, b, a, b); break; case CC_OP_CMP: tcg_gen_sub_tl(dst, a, b); @@ -783,7 +781,7 @@ static void cris_alu_op_exec(DisasContext *dc, int op, t_gen_subx_carry(dc, dst); break; default: - qemu_log("illegal ALU op.\n"); + qemu_log_mask(LOG_GUEST_ERROR, "illegal ALU op.\n"); BUG(); break; } @@ -1089,7 +1087,7 @@ static inline void cris_prepare_jmp (DisasContext *dc, unsigned int type) static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr) { - int mem_index = cpu_mmu_index(&dc->cpu->env); + int mem_index = cpu_mmu_index(&dc->cpu->env, false); /* If we get a fault on a delayslot we must keep the jmp state in the cpu-state to be able to re-execute the jmp. */ @@ -1103,7 +1101,7 @@ static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr) static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, unsigned int size, int sign) { - int mem_index = cpu_mmu_index(&dc->cpu->env); + int mem_index = cpu_mmu_index(&dc->cpu->env, false); /* If we get a fault on a delayslot we must keep the jmp state in the cpu-state to be able to re-execute the jmp. */ @@ -1118,7 +1116,7 @@ static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, static void gen_store (DisasContext *dc, TCGv addr, TCGv val, unsigned int size) { - int mem_index = cpu_mmu_index(&dc->cpu->env); + int mem_index = cpu_mmu_index(&dc->cpu->env, false); /* If we get a fault on a delayslot we must keep the jmp state in the cpu-state to be able to re-execute the jmp. */ @@ -1482,15 +1480,8 @@ static int dec_scc_r(CPUCRISState *env, DisasContext *dc) LOG_DIS("s%s $r%u\n", cc_name(cond), dc->op1); - if (cond != CC_A) { - TCGLabel *l1 = gen_new_label(); - gen_tst_cc(dc, cpu_R[dc->op1], cond); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->op1], 0, l1); - tcg_gen_movi_tl(cpu_R[dc->op1], 1); - gen_set_label(l1); - } else { - tcg_gen_movi_tl(cpu_R[dc->op1], 1); - } + gen_tst_cc(dc, cpu_R[dc->op1], cond); + tcg_gen_setcondi_tl(TCG_COND_NE, cpu_R[dc->op1], cpu_R[dc->op1], 0); cris_cc_mask(dc, 0); return 2; @@ -2604,9 +2595,9 @@ static int dec_movem_mr(CPUCRISState *env, DisasContext *dc) tcg_temp_free(addr); for (i = 0; i < (nr >> 1); i++) { - tcg_gen_trunc_i64_i32(cpu_R[i * 2], tmp[i]); + tcg_gen_extrl_i64_i32(cpu_R[i * 2], tmp[i]); tcg_gen_shri_i64(tmp[i], tmp[i], 32); - tcg_gen_trunc_i64_i32(cpu_R[i * 2 + 1], tmp[i]); + tcg_gen_extrl_i64_i32(cpu_R[i * 2 + 1], tmp[i]); tcg_temp_free_i64(tmp[i]); } if (nr & 1) { @@ -3007,10 +2998,6 @@ static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc) int insn_len = 2; int i; - if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) { - tcg_gen_debug_insn_start(dc->pc); - } - /* Load a halfword onto the instruction register. */ dc->ir = cris_fetch(env, dc, dc->pc, 2, 0); @@ -3047,23 +3034,6 @@ static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc) return insn_len; } -static void check_breakpoint(CPUCRISState *env, DisasContext *dc) -{ - CPUState *cs = CPU(cris_env_get_cpu(env)); - CPUBreakpoint *bp; - - if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) { - QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { - if (bp->pc == dc->pc) { - cris_evaluate_flags(dc); - tcg_gen_movi_tl(env_pc, dc->pc); - t_gen_raise_exception(EXCP_DEBUG); - dc->is_jmp = DISAS_UPDATE; - } - } - } -} - #include "translate_v10.c" /* @@ -3101,15 +3071,12 @@ static void check_breakpoint(CPUCRISState *env, DisasContext *dc) */ /* generate intermediate code for basic block 'tb'. */ -static inline void -gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, - bool search_pc) +void gen_intermediate_code(CPUCRISState *env, struct TranslationBlock *tb) { + CRISCPU *cpu = cris_env_get_cpu(env); CPUState *cs = CPU(cpu); - CPUCRISState *env = &cpu->env; uint32_t pc_start; unsigned int insn_len; - int j, lj; struct DisasContext ctx; struct DisasContext *dc = &ctx; uint32_t next_page_start; @@ -3161,13 +3128,13 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { qemu_log( - "srch=%d pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n" + "pc=%x %x flg=%" PRIx64 " bt=%x ds=%u ccs=%x\n" "pid=%x usp=%x\n" "%x.%x.%x.%x\n" "%x.%x.%x.%x\n" "%x.%x.%x.%x\n" "%x.%x.%x.%x\n", - search_pc, dc->pc, dc->ppc, + dc->pc, dc->ppc, (uint64_t)tb->flags, env->btarget, (unsigned)tb->flags & 7, env->pregs[PR_CCS], @@ -3183,38 +3150,38 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, } next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; - lj = -1; num_insns = 0; max_insns = tb->cflags & CF_COUNT_MASK; if (max_insns == 0) { max_insns = CF_COUNT_MASK; } + if (max_insns > TCG_MAX_INSNS) { + max_insns = TCG_MAX_INSNS; + } gen_tb_start(tb); do { - check_breakpoint(env, dc); - - if (search_pc) { - j = tcg_op_buf_count(); - if (lj < j) { - lj++; - while (lj < j) { - tcg_ctx.gen_opc_instr_start[lj++] = 0; - } - } - if (dc->delayed_branch == 1) { - tcg_ctx.gen_opc_pc[lj] = dc->ppc | 1; - } else { - tcg_ctx.gen_opc_pc[lj] = dc->pc; - } - tcg_ctx.gen_opc_instr_start[lj] = 1; - tcg_ctx.gen_opc_icount[lj] = num_insns; + tcg_gen_insn_start(dc->delayed_branch == 1 + ? dc->ppc | 1 : dc->pc); + num_insns++; + + if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) { + cris_evaluate_flags(dc); + tcg_gen_movi_tl(env_pc, dc->pc); + t_gen_raise_exception(EXCP_DEBUG); + dc->is_jmp = DISAS_UPDATE; + /* The address covered by the breakpoint must be included in + [tb->pc, tb->pc + tb->size) in order to for it to be + properly cleared -- thus we increment the PC here so that + the logic setting tb->size below does the right thing. */ + dc->pc += 2; + break; } /* Pretty disas. */ LOG_DIS("%8.8x:\t", dc->pc); - if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) { + if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) { gen_io_start(); } dc->clear_x = 1; @@ -3226,7 +3193,6 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, cris_clear_x_flag(dc); } - num_insns++; /* Check for delayed branches here. If we do it before actually generating any host code, the simulator will just loop doing nothing for on this program location. */ @@ -3331,16 +3297,8 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, } gen_tb_end(tb, num_insns); - if (search_pc) { - j = tcg_op_buf_count(); - lj++; - while (lj <= j) { - tcg_ctx.gen_opc_instr_start[lj++] = 0; - } - } else { - tb->size = dc->pc - pc_start; - tb->icount = num_insns; - } + tb->size = dc->pc - pc_start; + tb->icount = num_insns; #ifdef DEBUG_DISAS #if !DISAS_CRIS @@ -3354,16 +3312,6 @@ gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, #endif } -void gen_intermediate_code (CPUCRISState *env, struct TranslationBlock *tb) -{ - gen_intermediate_code_internal(cris_env_get_cpu(env), tb, false); -} - -void gen_intermediate_code_pc (CPUCRISState *env, struct TranslationBlock *tb) -{ - gen_intermediate_code_internal(cris_env_get_cpu(env), tb, true); -} - void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, int flags) { @@ -3416,47 +3364,48 @@ void cris_initialize_tcg(void) int i; cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); - cc_x = tcg_global_mem_new(TCG_AREG0, + cc_x = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, cc_x), "cc_x"); - cc_src = tcg_global_mem_new(TCG_AREG0, + cc_src = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, cc_src), "cc_src"); - cc_dest = tcg_global_mem_new(TCG_AREG0, + cc_dest = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, cc_dest), "cc_dest"); - cc_result = tcg_global_mem_new(TCG_AREG0, + cc_result = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, cc_result), "cc_result"); - cc_op = tcg_global_mem_new(TCG_AREG0, + cc_op = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, cc_op), "cc_op"); - cc_size = tcg_global_mem_new(TCG_AREG0, + cc_size = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, cc_size), "cc_size"); - cc_mask = tcg_global_mem_new(TCG_AREG0, + cc_mask = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, cc_mask), "cc_mask"); - env_pc = tcg_global_mem_new(TCG_AREG0, + env_pc = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, pc), "pc"); - env_btarget = tcg_global_mem_new(TCG_AREG0, + env_btarget = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, btarget), "btarget"); - env_btaken = tcg_global_mem_new(TCG_AREG0, + env_btaken = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, btaken), "btaken"); for (i = 0; i < 16; i++) { - cpu_R[i] = tcg_global_mem_new(TCG_AREG0, + cpu_R[i] = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, regs[i]), regnames[i]); } for (i = 0; i < 16; i++) { - cpu_PR[i] = tcg_global_mem_new(TCG_AREG0, + cpu_PR[i] = tcg_global_mem_new(cpu_env, offsetof(CPUCRISState, pregs[i]), pregnames[i]); } } -void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, int pc_pos) +void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, + target_ulong *data) { - env->pc = tcg_ctx.gen_opc_pc[pc_pos]; + env->pc = data[0]; } diff --git a/qemu/target-cris/translate_v10.c b/qemu/target-cris/translate_v10.c index b742c4cd0..7607eadfb 100644 --- a/qemu/target-cris/translate_v10.c +++ b/qemu/target-cris/translate_v10.c @@ -18,6 +18,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ +#include "qemu/osdep.h" #include "crisv10-decode.h" static const char *regnames_v10[] = @@ -58,7 +59,7 @@ static inline int dec10_size(unsigned int size) static inline void cris_illegal_insn(DisasContext *dc) { - qemu_log("illegal insn at pc=%x\n", dc->pc); + qemu_log_mask(LOG_GUEST_ERROR, "illegal insn at pc=%x\n", dc->pc); t_gen_raise_exception(EXCP_BREAK); } @@ -96,7 +97,7 @@ static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val, static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val, unsigned int size) { - int mem_index = cpu_mmu_index(&dc->cpu->env); + int mem_index = cpu_mmu_index(&dc->cpu->env, false); /* If we get a fault on a delayslot we must keep the jmp state in the cpu-state to be able to re-execute the jmp. */ @@ -535,16 +536,8 @@ static void dec10_reg_scc(DisasContext *dc) LOG_DIS("s%s $r%u\n", cc_name(cond), dc->src); - if (cond != CC_A) - { - TCGLabel *l1 = gen_new_label(); - gen_tst_cc (dc, cpu_R[dc->src], cond); - tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->src], 0, l1); - tcg_gen_movi_tl(cpu_R[dc->src], 1); - gen_set_label(l1); - } else { - tcg_gen_movi_tl(cpu_R[dc->src], 1); - } + gen_tst_cc(dc, cpu_R[dc->src], cond); + tcg_gen_setcondi_tl(TCG_COND_NE, cpu_R[dc->src], cpu_R[dc->src], 0); cris_cc_mask(dc, 0); } @@ -1207,9 +1200,6 @@ static unsigned int crisv10_decoder(CPUCRISState *env, DisasContext *dc) { unsigned int insn_len = 2; - if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) - tcg_gen_debug_insn_start(dc->pc); - /* Load a halfword onto the instruction register. */ dc->ir = cpu_lduw_code(env, dc->pc); @@ -1257,45 +1247,45 @@ static unsigned int crisv10_decoder(CPUCRISState *env, DisasContext *dc) void cris_initialize_crisv10_tcg(void) { - int i; - - cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); - cc_x = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, cc_x), "cc_x"); - cc_src = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, cc_src), "cc_src"); - cc_dest = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, cc_dest), - "cc_dest"); - cc_result = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, cc_result), - "cc_result"); - cc_op = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, cc_op), "cc_op"); - cc_size = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, cc_size), - "cc_size"); - cc_mask = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, cc_mask), - "cc_mask"); - - env_pc = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, pc), - "pc"); - env_btarget = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, btarget), - "btarget"); - env_btaken = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, btaken), - "btaken"); - for (i = 0; i < 16; i++) { - cpu_R[i] = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, regs[i]), - regnames_v10[i]); - } - for (i = 0; i < 16; i++) { - cpu_PR[i] = tcg_global_mem_new(TCG_AREG0, - offsetof(CPUCRISState, pregs[i]), - pregnames_v10[i]); - } + int i; + + cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); + cc_x = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, cc_x), "cc_x"); + cc_src = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, cc_src), "cc_src"); + cc_dest = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, cc_dest), + "cc_dest"); + cc_result = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, cc_result), + "cc_result"); + cc_op = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, cc_op), "cc_op"); + cc_size = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, cc_size), + "cc_size"); + cc_mask = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, cc_mask), + "cc_mask"); + + env_pc = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, pc), + "pc"); + env_btarget = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, btarget), + "btarget"); + env_btaken = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, btaken), + "btaken"); + for (i = 0; i < 16; i++) { + cpu_R[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, regs[i]), + regnames_v10[i]); + } + for (i = 0; i < 16; i++) { + cpu_PR[i] = tcg_global_mem_new(cpu_env, + offsetof(CPUCRISState, pregs[i]), + pregnames_v10[i]); + } } |