X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/ad1db3b341d3d55e6d722ad868bd48ed4425c9fb..9397a7c8318d727cea2ac62dbb14493a0e3e5f4b:/target-cris/translate.c diff --git a/target-cris/translate.c b/target-cris/translate.c index 0b0e86dbd1..ab0e47962b 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -24,14 +24,14 @@ */ #include "cpu.h" -#include "disas.h" +#include "disas/disas.h" #include "tcg-op.h" -#include "helper.h" +#include "exec/helper-proto.h" #include "mmu.h" +#include "exec/cpu_ldst.h" #include "crisv32-decode.h" -#define GEN_HELPER 1 -#include "helper.h" +#include "exec/helper-gen.h" #define DISAS_CRIS 0 #if DISAS_CRIS @@ -70,11 +70,11 @@ static TCGv env_btaken; static TCGv env_btarget; static TCGv env_pc; -#include "gen-icount.h" +#include "exec/gen-icount.h" /* This is the state at translation time. */ typedef struct DisasContext { - CPUCRISState *env; + CRISCPU *cpu; target_ulong pc, ppc; /* Decoder. */ @@ -129,7 +129,7 @@ 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); - cpu_abort(dc->env, "%s:%d\n", file, line); + cpu_abort(CPU(dc->cpu), "%s:%d\n", file, line); } static const char *regnames[] = @@ -160,39 +160,9 @@ static int preg_sizes[] = { }; #define t_gen_mov_TN_env(tn, member) \ - _t_gen_mov_TN_env((tn), offsetof(CPUCRISState, member)) + tcg_gen_ld_tl(tn, cpu_env, offsetof(CPUCRISState, member)) #define t_gen_mov_env_TN(member, tn) \ - _t_gen_mov_env_TN(offsetof(CPUCRISState, member), (tn)) - -static inline void t_gen_mov_TN_reg(TCGv tn, int r) -{ - if (r < 0 || r > 15) { - fprintf(stderr, "wrong register read $r%d\n", r); - } - tcg_gen_mov_tl(tn, cpu_R[r]); -} -static inline void t_gen_mov_reg_TN(int r, TCGv tn) -{ - if (r < 0 || r > 15) { - fprintf(stderr, "wrong register write $r%d\n", r); - } - tcg_gen_mov_tl(cpu_R[r], tn); -} - -static inline void _t_gen_mov_TN_env(TCGv tn, int offset) -{ - if (offset > sizeof(CPUCRISState)) { - fprintf(stderr, "wrong load from env from off=%d\n", offset); - } - tcg_gen_ld_tl(tn, cpu_env, offset); -} -static inline void _t_gen_mov_env_TN(int offset, TCGv tn) -{ - if (offset > sizeof(CPUCRISState)) { - fprintf(stderr, "wrong store to env at off=%d\n", offset); - } - tcg_gen_st_tl(tn, cpu_env, offset); -} + tcg_gen_st_tl(tn, cpu_env, offsetof(CPUCRISState, member)) static inline void t_gen_mov_TN_preg(TCGv tn, int r) { @@ -272,7 +242,7 @@ static int cris_fetch(CPUCRISState *env, DisasContext *dc, uint32_t addr, break; } default: - cpu_abort(dc->env, "Invalid fetch size %d\n", size); + cpu_abort(CPU(dc->cpu), "Invalid fetch size %d\n", size); break; } return r; @@ -340,46 +310,6 @@ static void t_gen_asr(TCGv d, TCGv a, TCGv b) tcg_temp_free(t_31); } -/* 64-bit signed mul, lower result in d and upper in d2. */ -static void t_gen_muls(TCGv d, TCGv d2, TCGv a, TCGv b) -{ - TCGv_i64 t0, t1; - - t0 = tcg_temp_new_i64(); - t1 = tcg_temp_new_i64(); - - tcg_gen_ext_i32_i64(t0, a); - tcg_gen_ext_i32_i64(t1, b); - tcg_gen_mul_i64(t0, t0, t1); - - tcg_gen_trunc_i64_i32(d, t0); - tcg_gen_shri_i64(t0, t0, 32); - tcg_gen_trunc_i64_i32(d2, t0); - - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -} - -/* 64-bit unsigned muls, lower result in d and upper in d2. */ -static void t_gen_mulu(TCGv d, TCGv d2, TCGv a, TCGv b) -{ - TCGv_i64 t0, t1; - - t0 = tcg_temp_new_i64(); - t1 = tcg_temp_new_i64(); - - tcg_gen_extu_i32_i64(t0, a); - tcg_gen_extu_i32_i64(t1, b); - tcg_gen_mul_i64(t0, t0, t1); - - tcg_gen_trunc_i64_i32(d, t0); - tcg_gen_shri_i64(t0, t0, 32); - tcg_gen_trunc_i64_i32(d2, t0); - - tcg_temp_free_i64(t0); - tcg_temp_free_i64(t1); -} - static void t_gen_cris_dstep(TCGv d, TCGv a, TCGv b) { int l1; @@ -598,7 +528,7 @@ static void gen_goto_tb(DisasContext *dc, int n, target_ulong dest) if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) { tcg_gen_goto_tb(n); tcg_gen_movi_tl(env_pc, dest); - tcg_gen_exit_tb((tcg_target_long)tb + n); + tcg_gen_exit_tb((uintptr_t)tb + n); } else { tcg_gen_movi_tl(env_pc, dest); tcg_gen_exit_tb(0); @@ -832,10 +762,10 @@ static void cris_alu_op_exec(DisasContext *dc, int op, gen_helper_lz(dst, b); break; case CC_OP_MULS: - t_gen_muls(dst, cpu_PR[PR_MOF], a, b); + tcg_gen_muls2_tl(dst, cpu_PR[PR_MOF], a, b); break; case CC_OP_MULU: - t_gen_mulu(dst, cpu_PR[PR_MOF], a, b); + tcg_gen_mulu2_tl(dst, cpu_PR[PR_MOF], a, b); break; case CC_OP_DSTEP: t_gen_cris_dstep(dst, a, b); @@ -1165,7 +1095,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->env); + int mem_index = cpu_mmu_index(&dc->cpu->env); /* 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. */ @@ -1173,13 +1103,13 @@ static void gen_load64(DisasContext *dc, TCGv_i64 dst, TCGv addr) cris_store_direct_jmp(dc); } - tcg_gen_qemu_ld64(dst, addr, mem_index); + tcg_gen_qemu_ld_i64(dst, addr, mem_index, MO_TEQ); } static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, unsigned int size, int sign) { - int mem_index = cpu_mmu_index(dc->env); + int mem_index = cpu_mmu_index(&dc->cpu->env); /* 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. */ @@ -1187,29 +1117,14 @@ static void gen_load(DisasContext *dc, TCGv dst, TCGv addr, cris_store_direct_jmp(dc); } - if (size == 1) { - if (sign) { - tcg_gen_qemu_ld8s(dst, addr, mem_index); - } else { - tcg_gen_qemu_ld8u(dst, addr, mem_index); - } - } else if (size == 2) { - if (sign) { - tcg_gen_qemu_ld16s(dst, addr, mem_index); - } else { - tcg_gen_qemu_ld16u(dst, addr, mem_index); - } - } else if (size == 4) { - tcg_gen_qemu_ld32u(dst, addr, mem_index); - } else { - abort(); - } + tcg_gen_qemu_ld_tl(dst, addr, mem_index, + MO_TE + ctz32(size) + (sign ? MO_SIGN : 0)); } static void gen_store (DisasContext *dc, TCGv addr, TCGv val, unsigned int size) { - int mem_index = cpu_mmu_index(dc->env); + int mem_index = cpu_mmu_index(&dc->cpu->env); /* 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. */ @@ -1227,13 +1142,7 @@ static void gen_store (DisasContext *dc, TCGv addr, TCGv val, return; } - if (size == 1) { - tcg_gen_qemu_st8(val, addr, mem_index); - } else if (size == 2) { - tcg_gen_qemu_st16(val, addr, mem_index); - } else { - tcg_gen_qemu_st32(val, addr, mem_index); - } + tcg_gen_qemu_st_tl(val, addr, mem_index, MO_TE + ctz32(size)); if (dc->flagx_known && dc->flags_x) { cris_evaluate_flags(dc); @@ -1873,7 +1782,7 @@ static int dec_swap_r(CPUCRISState *env, DisasContext *dc) cris_cc_mask(dc, CC_MASK_NZ); t0 = tcg_temp_new(); - t_gen_mov_TN_reg(t0, dc->op1); + tcg_gen_mov_tl(t0, cpu_R[dc->op1]); if (dc->op2 & 8) { tcg_gen_not_tl(t0, t0); } @@ -2181,7 +2090,7 @@ static int dec_move_rp(CPUCRISState *env, DisasContext *dc) t[0] = tcg_temp_new(); if (dc->op2 == PR_CCS) { cris_evaluate_flags(dc); - t_gen_mov_TN_reg(t[0], dc->op1); + tcg_gen_mov_tl(t[0], cpu_R[dc->op1]); if (dc->tb_flags & U_FLAG) { t[1] = tcg_temp_new(); /* User space is not allowed to touch all flags. */ @@ -2191,7 +2100,7 @@ static int dec_move_rp(CPUCRISState *env, DisasContext *dc) tcg_temp_free(t[1]); } } else { - t_gen_mov_TN_reg(t[0], dc->op1); + tcg_gen_mov_tl(t[0], cpu_R[dc->op1]); } t_gen_mov_preg_TN(dc, dc->op2, t[0]); @@ -2928,7 +2837,8 @@ static int dec_rfe_etc(CPUCRISState *env, DisasContext *dc) cris_cc_mask(dc, 0); if (dc->op2 == 15) { - t_gen_mov_env_TN(halted, tcg_const_tl(1)); + tcg_gen_st_i32(tcg_const_i32(1), cpu_env, + -offsetof(CRISCPU, env) + offsetof(CPUState, halted)); tcg_gen_movi_tl(env_pc, dc->pc + 2); t_gen_raise_exception(EXCP_HLT); return 2; @@ -3149,10 +3059,11 @@ static unsigned int crisv32_decoder(CPUCRISState *env, DisasContext *dc) static void check_breakpoint(CPUCRISState *env, DisasContext *dc) { + CPUState *cs = CPU(cris_env_get_cpu(env)); CPUBreakpoint *bp; - if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) { - QTAILQ_FOREACH(bp, &env->breakpoints, entry) { + 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); @@ -3200,10 +3111,12 @@ static void check_breakpoint(CPUCRISState *env, DisasContext *dc) */ /* generate intermediate code for basic block 'tb'. */ -static void -gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, - int search_pc) +static inline void +gen_intermediate_code_internal(CRISCPU *cpu, TranslationBlock *tb, + bool search_pc) { + CPUState *cs = CPU(cpu); + CPUCRISState *env = &cpu->env; uint16_t *gen_opc_end; uint32_t pc_start; unsigned int insn_len; @@ -3215,8 +3128,6 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, int num_insns; int max_insns; - qemu_log_try_set_file(stderr); - if (env->pregs[PR_VR] == 32) { dc->decoder = crisv32_decoder; dc->clear_locked_irq = 0; @@ -3229,7 +3140,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, * delayslot, like in real hw. */ pc_start = tb->pc & ~1; - dc->env = env; + dc->cpu = cpu; dc->tb = tb; gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE; @@ -3237,7 +3148,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, dc->is_jmp = DISAS_NEXT; dc->ppc = pc_start; dc->pc = pc_start; - dc->singlestep_enabled = env->singlestep_enabled; + dc->singlestep_enabled = cs->singlestep_enabled; dc->flags_uptodate = 1; dc->flagx_known = 1; dc->flags_x = tb->flags & X_FLAG; @@ -3292,7 +3203,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, max_insns = CF_COUNT_MASK; } - gen_icount_start(); + gen_tb_start(); do { check_breakpoint(env, dc); @@ -3301,16 +3212,16 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, if (lj < j) { lj++; while (lj < j) { - gen_opc_instr_start[lj++] = 0; + tcg_ctx.gen_opc_instr_start[lj++] = 0; } } if (dc->delayed_branch == 1) { - gen_opc_pc[lj] = dc->ppc | 1; + tcg_ctx.gen_opc_pc[lj] = dc->ppc | 1; } else { - gen_opc_pc[lj] = dc->pc; + tcg_ctx.gen_opc_pc[lj] = dc->pc; } - gen_opc_instr_start[lj] = 1; - gen_opc_icount[lj] = num_insns; + tcg_ctx.gen_opc_instr_start[lj] = 1; + tcg_ctx.gen_opc_icount[lj] = num_insns; } /* Pretty disas. */ @@ -3377,7 +3288,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, /* If we are rexecuting a branch due to exceptions on delay slots dont break. */ - if (!(tb->pc & 1) && env->singlestep_enabled) { + if (!(tb->pc & 1) && cs->singlestep_enabled) { break; } } while (!dc->is_jmp && !dc->cpustate_changed @@ -3410,7 +3321,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, cris_evaluate_flags(dc); - if (unlikely(env->singlestep_enabled)) { + if (unlikely(cs->singlestep_enabled)) { if (dc->is_jmp == DISAS_NEXT) { tcg_gen_movi_tl(env_pc, npc); } @@ -3433,13 +3344,13 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, break; } } - gen_icount_end(tb, num_insns); + gen_tb_end(tb, num_insns); *tcg_ctx.gen_opc_ptr = INDEX_op_end; if (search_pc) { 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; @@ -3450,7 +3361,7 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, #if !DISAS_CRIS if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { log_target_disas(env, pc_start, dc->pc - pc_start, - dc->env->pregs[PR_VR]); + env->pregs[PR_VR]); qemu_log("\nisize=%d osize=%td\n", dc->pc - pc_start, tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf); } @@ -3460,17 +3371,19 @@ gen_intermediate_code_internal(CPUCRISState *env, TranslationBlock *tb, void gen_intermediate_code (CPUCRISState *env, struct TranslationBlock *tb) { - gen_intermediate_code_internal(env, tb, 0); + 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(env, tb, 1); + gen_intermediate_code_internal(cris_env_get_cpu(env), tb, true); } -void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf, - int flags) +void cris_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf, + int flags) { + CRISCPU *cpu = CRIS_CPU(cs); + CPUCRISState *env = &cpu->env; int i; uint32_t srs; @@ -3513,69 +3426,10 @@ void cpu_dump_state (CPUCRISState *env, FILE *f, fprintf_function cpu_fprintf, } -struct -{ - uint32_t vr; - const char *name; -} cris_cores[] = { - {8, "crisv8"}, - {9, "crisv9"}, - {10, "crisv10"}, - {11, "crisv11"}, - {32, "crisv32"}, -}; - -void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf) -{ - unsigned int i; - - (*cpu_fprintf)(f, "Available CPUs:\n"); - for (i = 0; i < ARRAY_SIZE(cris_cores); i++) { - (*cpu_fprintf)(f, " %s\n", cris_cores[i].name); - } -} - -static uint32_t vr_by_name(const char *name) +void cris_initialize_tcg(void) { - unsigned int i; - for (i = 0; i < ARRAY_SIZE(cris_cores); i++) { - if (strcmp(name, cris_cores[i].name) == 0) { - return cris_cores[i].vr; - } - } - return 32; -} - -CRISCPU *cpu_cris_init(const char *cpu_model) -{ - CRISCPU *cpu; - CPUCRISState *env; - static int tcg_initialized = 0; int i; - cpu = CRIS_CPU(object_new(TYPE_CRIS_CPU)); - env = &cpu->env; - - env->pregs[PR_VR] = vr_by_name(cpu_model); - - cpu_reset(CPU(cpu)); - qemu_init_vcpu(env); - - if (tcg_initialized) { - return cpu; - } - - tcg_initialized = 1; - -#define GEN_HELPER 2 -#include "helper.h" - - if (env->pregs[PR_VR] < 32) { - cpu_crisv10_init(env); - return cpu; - } - - cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env"); cc_x = tcg_global_mem_new(TCG_AREG0, offsetof(CPUCRISState, cc_x), "cc_x"); @@ -3615,11 +3469,9 @@ CRISCPU *cpu_cris_init(const char *cpu_model) offsetof(CPUCRISState, pregs[i]), pregnames[i]); } - - return cpu; } void restore_state_to_opc(CPUCRISState *env, TranslationBlock *tb, int pc_pos) { - env->pc = gen_opc_pc[pc_pos]; + env->pc = tcg_ctx.gen_opc_pc[pc_pos]; }