From patchwork Mon Jun 13 23:58:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 9174755 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 1441F6044F for ; Tue, 14 Jun 2016 00:23:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 04CFF27D45 for ; Tue, 14 Jun 2016 00:23:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EB70528047; Tue, 14 Jun 2016 00:23:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3E3AC27D45 for ; Tue, 14 Jun 2016 00:23:03 +0000 (UTC) Received: from localhost ([::1]:60111 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCc8E-000716-Dr for patchwork-qemu-devel@patchwork.kernel.org; Mon, 13 Jun 2016 20:23:02 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38819) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCblC-0002OI-MS for qemu-devel@nongnu.org; Mon, 13 Jun 2016 19:59:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bCblA-0004Uz-Tu for qemu-devel@nongnu.org; Mon, 13 Jun 2016 19:59:14 -0400 Received: from mail-qt0-x243.google.com ([2607:f8b0:400d:c0d::243]:35417) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bCblA-0004Um-Ns for qemu-devel@nongnu.org; Mon, 13 Jun 2016 19:59:12 -0400 Received: by mail-qt0-x243.google.com with SMTP id 37so5837796qtc.2 for ; Mon, 13 Jun 2016 16:59:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:subject:date:message-id:in-reply-to:references; bh=LYi6B/DaI+k5sQwDZbd+JwOB5EmQaW7iJV7/r6l7sQ4=; b=JwIEhOfhvgq8rYbDeRYRi+o9zBz5IPkgbtM/RbCYkIUa0mhdsRiRKEPlVYBQRZnS4Z CNDfmZYwXbxxfwHyPcK+/fWBW7xVXLdhQME6KtC/JYTPPjE1Oxmxc6nQ6eOnfnjPSe4i j+14QbIGsIEouimXAQsXvWk7YfrFALHHwP8c5jhEEu49oNLWieYPt8c2qmEM0+R2KEuI YnzCh5tsWzXbk0PAw3n6ghgO2t8AzT6eCWhXdY/11OHnuTjBPHi3ze7zzBAKBeEUst1D 5bYMwMBnhGIqc6EE3Tuka6Wv1erEaxefLYZ4f5D9sOZmhTCW7BK6AdOALBGqzEZQnC+H ospA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:sender:from:to:subject:date:message-id :in-reply-to:references; bh=LYi6B/DaI+k5sQwDZbd+JwOB5EmQaW7iJV7/r6l7sQ4=; b=RJ0JEtQqhFXbadMbb19L2pJhd8FThONZxweE/a0WgHWqWc/AKY6wJ9/QKtKw2yRjsI YXWgWrkFpUYX2zBUFy+aeNpK9HwO4ZUQJYpQFkK/7YeFQIz8J2dRBUwwYZ0dira7PMLk 0Ymn+YCpyoY+TII3PRe81HSozDiNAr620EctEYtheh4EZI7xARTNfT0u2uTqrN9SZdh/ LZqWmCPqbwgBu0vNJ1Ao/FKeS/HrEp2oxsoMJ82BCdPVqzPE77asadu2NH4oWDdmObst W58X0A8J5f2TiYFStvDZsuDk2+DA0BigW3x/qMrBejxU1TtYSn27sDemOM3t+CRPUKiZ uwwA== X-Gm-Message-State: ALyK8tK2cyyGgjDHvFTJ/OZve8Fl6h5S9WEoD3qH4g1//PU+AyDea0H1LAO2BB1DZp102g== X-Received: by 10.200.46.124 with SMTP id s57mr14417595qta.2.1465862352223; Mon, 13 Jun 2016 16:59:12 -0700 (PDT) Received: from bigtime.com (71-37-54-227.tukw.qwest.net. [71.37.54.227]) by smtp.gmail.com with ESMTPSA id q200sm7547234qke.31.2016.06.13.16.59.11 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Jun 2016 16:59:11 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Mon, 13 Jun 2016 16:58:19 -0700 Message-Id: <1465862305-14090-20-git-send-email-rth@twiddle.net> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1465862305-14090-1-git-send-email-rth@twiddle.net> References: <1465862305-14090-1-git-send-email-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400d:c0d::243 Subject: [Qemu-devel] [PATCH 19/25] target-openrisc: Tidy ppc/npc implementation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP The NPC SPR is really only supposed to be used for FPGA debugging. It contains the same contents as PC, unless one plays games. Follow the or1ksim implementation in flushing delayed branch state when it is changed. The PPC SPR need not be updated every instruction, merely when we exit the TB or attempt to read its contents. Signed-off-by: Richard Henderson --- target-openrisc/cpu.h | 2 +- target-openrisc/gdbstub.c | 13 +++++++++---- target-openrisc/interrupt_helper.c | 1 - target-openrisc/machine.c | 5 ++--- target-openrisc/sys_helper.c | 23 ++++++++++++++++------- target-openrisc/translate.c | 29 +++++++++++------------------ 6 files changed, 39 insertions(+), 34 deletions(-) diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h index bb9540f..70ac481 100644 --- a/target-openrisc/cpu.h +++ b/target-openrisc/cpu.h @@ -58,6 +58,7 @@ typedef struct OpenRISCCPUClass { } OpenRISCCPUClass; #define NB_MMU_MODES 3 +#define TARGET_INSN_START_EXTRA_WORDS 1 enum { MMU_NOMMU_IDX = 0, @@ -275,7 +276,6 @@ typedef struct CPUOpenRISCTLBContext { typedef struct CPUOpenRISCState { target_ulong gpr[32]; /* General registers */ target_ulong pc; /* Program counter */ - target_ulong npc; /* Next PC */ target_ulong ppc; /* Prev PC */ target_ulong jmp_pc; /* Jump PC */ diff --git a/target-openrisc/gdbstub.c b/target-openrisc/gdbstub.c index 31ea013..2a4821f 100644 --- a/target-openrisc/gdbstub.c +++ b/target-openrisc/gdbstub.c @@ -34,8 +34,8 @@ int openrisc_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) case 32: /* PPC */ return gdb_get_reg32(mem_buf, env->ppc); - case 33: /* NPC */ - return gdb_get_reg32(mem_buf, env->npc); + case 33: /* NPC (equals PC) */ + return gdb_get_reg32(mem_buf, env->pc); case 34: /* SR */ return gdb_get_reg32(mem_buf, cpu_get_sr(env)); @@ -68,8 +68,13 @@ int openrisc_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) env->ppc = tmp; break; - case 33: /* NPC */ - env->npc = tmp; + case 33: /* NPC (equals PC) */ + /* If setting PC to something different, + also clear delayed branch status. */ + if (env->pc != tmp) { + env->pc = tmp; + env->flags = 0; + } break; case 34: /* SR */ diff --git a/target-openrisc/interrupt_helper.c b/target-openrisc/interrupt_helper.c index 68d1598..00817d8 100644 --- a/target-openrisc/interrupt_helper.c +++ b/target-openrisc/interrupt_helper.c @@ -32,7 +32,6 @@ void HELPER(rfe)(CPUOpenRISCState *env) (cpu->env.esr & (SR_SM | SR_IME | SR_DME)); #endif cpu->env.pc = cpu->env.epcr; - cpu->env.npc = cpu->env.epcr; cpu_set_sr(&cpu->env, cpu->env.esr); cpu->env.lock_addr = -1; diff --git a/target-openrisc/machine.c b/target-openrisc/machine.c index 17b0c77..a984929 100644 --- a/target-openrisc/machine.c +++ b/target-openrisc/machine.c @@ -26,8 +26,8 @@ static const VMStateDescription vmstate_env = { .name = "env", - .version_id = 1, - .minimum_version_id = 1, + .version_id = 2, + .minimum_version_id = 2, .fields = (VMStateField[]) { VMSTATE_UINT32_ARRAY(gpr, CPUOpenRISCState, 32), VMSTATE_UINT32(sr, CPUOpenRISCState), @@ -36,7 +36,6 @@ static const VMStateDescription vmstate_env = { VMSTATE_UINT32(esr, CPUOpenRISCState), VMSTATE_UINT32(fpcsr, CPUOpenRISCState), VMSTATE_UINT32(pc, CPUOpenRISCState), - VMSTATE_UINT32(npc, CPUOpenRISCState), VMSTATE_UINT32(ppc, CPUOpenRISCState), VMSTATE_END_OF_LIST() } diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c index 1530558..1103a7b 100644 --- a/target-openrisc/sys_helper.c +++ b/target-openrisc/sys_helper.c @@ -27,20 +27,26 @@ void HELPER(mtspr)(CPUOpenRISCState *env, uint32_t spr, target_ulong rb) { + OpenRISCCPU *cpu = openrisc_env_get_cpu(env); + CPUState *cs = CPU(cpu); #ifndef CONFIG_USER_ONLY int idx; #endif - OpenRISCCPU *cpu = openrisc_env_get_cpu(env); - CPUState *cs = CPU(cpu); - switch (spr) { case TO_SPR(0, 0): /* VR */ env->vr = rb; break; case TO_SPR(0, 16): /* NPC */ - env->npc = rb; + cpu_restore_state(cs, GETPC()); + /* ??? Mirror or1ksim in not trashing delayed branch state + when "jumping" to the current instruction. */ + if (env->pc != rb) { + env->pc = rb; + env->flags = 0; + cpu_loop_exit(cs); + } break; case TO_SPR(0, 17): /* SR */ @@ -181,8 +187,9 @@ void HELPER(mtspr)(CPUOpenRISCState *env, uint32_t spr, target_ulong rb) target_ulong HELPER(mfspr)(CPUOpenRISCState *env, uint32_t spr) { -#ifndef CONFIG_USER_ONLY OpenRISCCPU *cpu = openrisc_env_get_cpu(env); + CPUState *cs = CPU(cpu); +#ifndef CONFIG_USER_ONLY int idx; #endif @@ -202,13 +209,15 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, uint32_t spr) case TO_SPR(0, 4): /* IMMUCFGR */ return env->immucfgr; - case TO_SPR(0, 16): /* NPC */ - return env->npc; + case TO_SPR(0, 16): /* NPC (equals PC) */ + cpu_restore_state(cs, GETPC()); + return env->pc; case TO_SPR(0, 17): /* SR */ return cpu_get_sr(env); case TO_SPR(0, 18): /* PPC */ + cpu_restore_state(cs, GETPC()); return env->ppc; case TO_SPR(0, 32): /* EPCR */ diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index 7804edd..70aadbc 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -40,7 +40,7 @@ typedef struct DisasContext { TranslationBlock *tb; - target_ulong pc, ppc, npc; + target_ulong pc; uint32_t tb_flags, synced_flags, flags; uint32_t is_jmp; uint32_t mem_idx; @@ -53,7 +53,6 @@ static TCGv cpu_sr; static TCGv cpu_R[32]; static TCGv cpu_pc; static TCGv jmp_pc; /* l.jr/l.jalr temp pc */ -static TCGv cpu_npc; static TCGv cpu_ppc; static TCGv cpu_sr_f; /* bf/bnf, F flag taken */ static TCGv cpu_sr_cy; /* carry (unsigned overflow) */ @@ -83,8 +82,6 @@ void openrisc_translate_init(void) "flags"); cpu_pc = tcg_global_mem_new(cpu_env, offsetof(CPUOpenRISCState, pc), "pc"); - cpu_npc = tcg_global_mem_new(cpu_env, - offsetof(CPUOpenRISCState, npc), "npc"); cpu_ppc = tcg_global_mem_new(cpu_env, offsetof(CPUOpenRISCState, ppc), "ppc"); jmp_pc = tcg_global_mem_new(cpu_env, @@ -1504,7 +1501,6 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) dc->tb = tb; dc->is_jmp = DISAS_NEXT; - dc->ppc = pc_start; dc->pc = pc_start; dc->flags = cpu->env.cpucfgr; dc->mem_idx = cpu_mmu_index(&cpu->env, false); @@ -1530,7 +1526,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) gen_tb_start(tb); do { - tcg_gen_insn_start(dc->pc); + tcg_gen_insn_start(dc->pc, num_insns != 0); num_insns++; if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) { @@ -1548,12 +1544,9 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) { gen_io_start(); } - dc->ppc = dc->pc - 4; - dc->npc = dc->pc + 4; - tcg_gen_movi_tl(cpu_ppc, dc->ppc); - tcg_gen_movi_tl(cpu_npc, dc->npc); disas_openrisc_insn(dc, cpu); - dc->pc = dc->npc; + dc->pc = dc->pc + 4; + /* delay slot */ if (dc->delayed_branch) { dc->delayed_branch--; @@ -1561,10 +1554,8 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) dc->tb_flags &= ~D_FLAG; gen_sync_flags(dc); tcg_gen_mov_tl(cpu_pc, jmp_pc); - tcg_gen_mov_tl(cpu_npc, jmp_pc); - tcg_gen_movi_tl(jmp_pc, 0); - tcg_gen_exit_tb(0); - dc->is_jmp = DISAS_JUMP; + tcg_gen_discard_tl(jmp_pc); + dc->is_jmp = DISAS_UPDATE; break; } } @@ -1578,14 +1569,13 @@ void gen_intermediate_code(CPUOpenRISCState *env, struct TranslationBlock *tb) if (tb->cflags & CF_LAST_IO) { gen_io_end(); } + + tcg_gen_movi_tl(cpu_ppc, dc->pc - 4); if (dc->is_jmp == DISAS_NEXT) { dc->is_jmp = DISAS_UPDATE; tcg_gen_movi_tl(cpu_pc, dc->pc); } if (unlikely(cs->singlestep_enabled)) { - if (dc->is_jmp == DISAS_NEXT) { - tcg_gen_movi_tl(cpu_pc, dc->pc); - } gen_exception(dc, EXCP_DEBUG); } else { switch (dc->is_jmp) { @@ -1641,4 +1631,7 @@ void restore_state_to_opc(CPUOpenRISCState *env, TranslationBlock *tb, target_ulong *data) { env->pc = data[0]; + if (data[1]) { + env->ppc = env->pc - 4; + } }