From nobody Mon Feb 9 22:39:22 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487022355688675.9307870114695; Mon, 13 Feb 2017 13:45:55 -0800 (PST) Received: from localhost ([::1]:59707 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdORW-0006Jy-8y for importer@patchew.org; Mon, 13 Feb 2017 16:45:54 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45712) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cdO95-0005E0-Fe for qemu-devel@nongnu.org; Mon, 13 Feb 2017 16:26:53 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cdO93-0001i6-Nn for qemu-devel@nongnu.org; Mon, 13 Feb 2017 16:26:51 -0500 Received: from mail-qt0-x242.google.com ([2607:f8b0:400d:c0d::242]:32962) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cdO93-0001hw-IN for qemu-devel@nongnu.org; Mon, 13 Feb 2017 16:26:49 -0500 Received: by mail-qt0-x242.google.com with SMTP id n13so15082764qtc.0 for ; Mon, 13 Feb 2017 13:26:49 -0800 (PST) Received: from bigtime.twiddle.net.com ([1.129.9.91]) by smtp.gmail.com with ESMTPSA id h40sm8311480qtb.6.2017.02.13.13.26.46 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 13 Feb 2017 13:26:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=7cehKIO1CotF02L/MsXRcT+I41D6ZNP41hM3r1JuGyg=; b=C6CyK7OXyxCnDFg3Wn9oriddFkEbPgyPHrocyyobkl73qZ0BG16y4JqPtcflZ/KqNh mn8o3bxIlsa8KWGUrtzlWeHULgXCDtQeQPK6uSSgIFhWIjLxwx0u6gbvKnB3oumhp2Qj e6oP/+0qNDRgk/4zpJTMjq+/b8wdccl6QpVCx9wcrj1/gF2QOfB1/mTqNN5DnESzWl12 wLWpc5uhxql+71C5ZfG130WFShDl1Iogn/p7w1Vk3fv2gsY9eXfJMglra6SxwqWENF9Z IshHovP9/L0Uxfc/DkoE0iTlfxyhJ/Fv6gjQ/IiFoLmk7gSPVaJYP66CaV+6rfOJCz76 Ov8Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=7cehKIO1CotF02L/MsXRcT+I41D6ZNP41hM3r1JuGyg=; b=hCBT5qPTcFMYTtG6yMF1JJtLBahFnhgGs/71PF1ZMZPat+8c9dkaGogN+l9WCGLuB7 cCs4MbjjvNnEXkmExOQqjQqJKqnpl+Gvrz59VCmGfDvLClvOg7ILqCohQPnqiSFxQOn8 11bojRANI+eYPxaxMaSKAWQZaznIXXEKdn2ydK8qepGazaRYsWRylypAcv4+Sas0XKDl O/uSkVi2DwDl/Ia3TwzfKmzOLCAlALbriTxi7rHUbKRD2DDzVJXugqsPNxmG/Snsl852 i2sI2njZzp96vCea0QD3L6gksVlRhWY1TTN5TiTiPPiVaMb/XqKvy0vjX5VIL3AZhm2g QwuQ== X-Gm-Message-State: AMke39mejMaoYzhPrVf3JhLmkY4zxcEthtC9/lkhYakIxKMxXkgQqLs7GJYtg0nMVfm+Gw== X-Received: by 10.237.60.122 with SMTP id u55mr22685501qte.41.1487021208826; Mon, 13 Feb 2017 13:26:48 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Tue, 14 Feb 2017 08:25:34 +1100 Message-Id: <20170213212536.31871-23-rth@twiddle.net> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170213212536.31871-1-rth@twiddle.net> References: <20170213212536.31871-1-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::242 Subject: [Qemu-devel] [PULL 22/24] 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: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 | 44 ++++++++++++++--------------------= ---- target/openrisc/translate.c | 29 ++++++++++--------------- 6 files changed, 39 insertions(+), 55 deletions(-) diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h index 0694038..8294636 100644 --- a/target/openrisc/cpu.h +++ b/target/openrisc/cpu.h @@ -58,6 +58,7 @@ typedef struct OpenRISCCPUClass { } OpenRISCCPUClass; =20 #define NB_MMU_MODES 3 +#define TARGET_INSN_START_EXTRA_WORDS 1 =20 enum { MMU_NOMMU_IDX =3D 0, @@ -273,7 +274,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 */ =20 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); =20 - case 33: /* NPC */ - return gdb_get_reg32(mem_buf, env->npc); + case 33: /* NPC (equals PC) */ + return gdb_get_reg32(mem_buf, env->pc); =20 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 =3D tmp; break; =20 - case 33: /* NPC */ - env->npc =3D tmp; + case 33: /* NPC (equals PC) */ + /* If setting PC to something different, + also clear delayed branch status. */ + if (env->pc !=3D tmp) { + env->pc =3D tmp; + env->flags =3D 0; + } break; =20 case 34: /* SR */ diff --git a/target/openrisc/interrupt_helper.c b/target/openrisc/interrupt= _helper.c index c7fa97a..56620e0 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 =3D cpu->env.epcr; - cpu->env.npc =3D cpu->env.epcr; cpu_set_sr(&cpu->env, cpu->env.esr); cpu->env.lock_addr =3D -1; =20 diff --git a/target/openrisc/machine.c b/target/openrisc/machine.c index 4100957..686eaa3 100644 --- a/target/openrisc/machine.c +++ b/target/openrisc/machine.c @@ -47,12 +47,11 @@ static const VMStateInfo vmstate_sr =3D { =20 static const VMStateDescription vmstate_env =3D { .name =3D "env", - .version_id =3D 3, - .minimum_version_id =3D 3, + .version_id =3D 4, + .minimum_version_id =3D 4, .fields =3D (VMStateField[]) { VMSTATE_UINTTL_ARRAY(gpr, CPUOpenRISCState, 32), VMSTATE_UINTTL(pc, CPUOpenRISCState), - VMSTATE_UINTTL(npc, CPUOpenRISCState), VMSTATE_UINTTL(ppc, CPUOpenRISCState), VMSTATE_UINTTL(jmp_pc, CPUOpenRISCState), VMSTATE_UINTTL(lock_addr, CPUOpenRISCState), diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index 9841a5b..0968901 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -29,11 +29,10 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong ra, target_ulong rb, target_ulong offset) { #ifndef CONFIG_USER_ONLY - int spr =3D (ra | offset); - int idx; - OpenRISCCPU *cpu =3D openrisc_env_get_cpu(env); CPUState *cs =3D CPU(cpu); + int spr =3D (ra | offset); + int idx; =20 switch (spr) { case TO_SPR(0, 0): /* VR */ @@ -41,7 +40,14 @@ void HELPER(mtspr)(CPUOpenRISCState *env, break; =20 case TO_SPR(0, 16): /* NPC */ - env->npc =3D rb; + cpu_restore_state(cs, GETPC()); + /* ??? Mirror or1ksim in not trashing delayed branch state + when "jumping" to the current instruction. */ + if (env->pc !=3D rb) { + env->pc =3D rb; + env->flags =3D 0; + cpu_loop_exit(cs); + } break; =20 case TO_SPR(0, 17): /* SR */ @@ -170,7 +176,6 @@ void HELPER(mtspr)(CPUOpenRISCState *env, cpu_openrisc_timer_update(cpu); break; default: - break; } #endif @@ -180,11 +185,11 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, target_ulong ra, uint32_t offs= et) { #ifndef CONFIG_USER_ONLY + OpenRISCCPU *cpu =3D openrisc_env_get_cpu(env); + CPUState *cs =3D CPU(cpu); int spr =3D (ra | offset); int idx; =20 - OpenRISCCPU *cpu =3D openrisc_env_get_cpu(env); - switch (spr) { case TO_SPR(0, 0): /* VR */ return env->vr & SPR_VR; @@ -201,13 +206,15 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, case TO_SPR(0, 4): /* IMMUCFGR */ return env->immucfgr; =20 - 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; =20 case TO_SPR(0, 17): /* SR */ return cpu_get_sr(env); =20 case TO_SPR(0, 18): /* PPC */ + cpu_restore_state(cs, GETPC()); return env->ppc; =20 case TO_SPR(0, 32): /* EPCR */ @@ -276,25 +283,6 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, } #endif =20 -/*If we later need to add tracepoints (or debug printfs) for the return -value, it may be useful to structure the code like this: - -target_ulong ret =3D 0; - -switch() { -case x: - ret =3D y; - break; -case z: - ret =3D 42; - break; -... -} - -later something like trace_spr_read(ret); - -return ret;*/ - /* for rd is passed in, if rd unchanged, just keep it back. */ return rd; } diff --git a/target/openrisc/translate.c b/target/openrisc/translate.c index cda84b6..10f0633 100644 --- a/target/openrisc/translate.c +++ b/target/openrisc/translate.c @@ -39,7 +39,7 @@ =20 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; @@ -52,7 +52,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 =3D tcg_global_mem_new(cpu_env, offsetof(CPUOpenRISCState, pc), "pc"); - cpu_npc =3D tcg_global_mem_new(cpu_env, - offsetof(CPUOpenRISCState, npc), "npc"); cpu_ppc =3D tcg_global_mem_new(cpu_env, offsetof(CPUOpenRISCState, ppc), "ppc"); jmp_pc =3D tcg_global_mem_new(cpu_env, @@ -1514,7 +1511,6 @@ void gen_intermediate_code(CPUOpenRISCState *env, str= uct TranslationBlock *tb) dc->tb =3D tb; =20 dc->is_jmp =3D DISAS_NEXT; - dc->ppc =3D pc_start; dc->pc =3D pc_start; dc->flags =3D cpu->env.cpucfgr; dc->mem_idx =3D cpu_mmu_index(&cpu->env, false); @@ -1543,7 +1539,7 @@ void gen_intermediate_code(CPUOpenRISCState *env, str= uct TranslationBlock *tb) gen_tb_start(tb); =20 do { - tcg_gen_insn_start(dc->pc); + tcg_gen_insn_start(dc->pc, num_insns !=3D 0); num_insns++; =20 if (unlikely(cpu_breakpoint_test(cs, dc->pc, BP_ANY))) { @@ -1561,12 +1557,9 @@ void gen_intermediate_code(CPUOpenRISCState *env, st= ruct TranslationBlock *tb) if (num_insns =3D=3D max_insns && (tb->cflags & CF_LAST_IO)) { gen_io_start(); } - dc->ppc =3D dc->pc - 4; - dc->npc =3D 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 =3D dc->npc; + dc->pc =3D dc->pc + 4; + /* delay slot */ if (dc->delayed_branch) { dc->delayed_branch--; @@ -1574,10 +1567,8 @@ void gen_intermediate_code(CPUOpenRISCState *env, st= ruct TranslationBlock *tb) dc->tb_flags &=3D ~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 =3D DISAS_JUMP; + tcg_gen_discard_tl(jmp_pc); + dc->is_jmp =3D DISAS_UPDATE; break; } } @@ -1591,14 +1582,13 @@ void gen_intermediate_code(CPUOpenRISCState *env, s= truct TranslationBlock *tb) if (tb->cflags & CF_LAST_IO) { gen_io_end(); } + + tcg_gen_movi_tl(cpu_ppc, dc->pc - 4); if (dc->is_jmp =3D=3D DISAS_NEXT) { dc->is_jmp =3D DISAS_UPDATE; tcg_gen_movi_tl(cpu_pc, dc->pc); } if (unlikely(cs->singlestep_enabled)) { - if (dc->is_jmp =3D=3D DISAS_NEXT) { - tcg_gen_movi_tl(cpu_pc, dc->pc); - } gen_exception(dc, EXCP_DEBUG); } else { switch (dc->is_jmp) { @@ -1651,4 +1641,7 @@ void restore_state_to_opc(CPUOpenRISCState *env, Tran= slationBlock *tb, target_ulong *data) { env->pc =3D data[0]; + if (data[1]) { + env->ppc =3D env->pc - 4; + } } --=20 2.9.3