From nobody Tue Oct 28 12:14:05 2025 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.zohomail.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 1514855868328626.5571874611189; Mon, 1 Jan 2018 17:17:48 -0800 (PST) Received: from localhost ([::1]:50806 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eWBD9-0006jN-DW for importer@patchew.org; Mon, 01 Jan 2018 20:17:47 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35960) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eWB6I-0001Ve-1u for qemu-devel@nongnu.org; Mon, 01 Jan 2018 20:10:44 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eWB6F-00053G-Su for qemu-devel@nongnu.org; Mon, 01 Jan 2018 20:10:41 -0500 Received: from mout.kundenserver.de ([212.227.126.130]:57156) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eWB6F-000522-Hk for qemu-devel@nongnu.org; Mon, 01 Jan 2018 20:10:39 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue001 [212.227.15.167]) with ESMTPSA (Nemesis) id 0Mbour-1eFslc2JKn-00J1NO; Tue, 02 Jan 2018 02:10:37 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 2 Jan 2018 02:10:21 +0100 Message-Id: <20180102011032.30056-7-laurent@vivier.eu> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180102011032.30056-1-laurent@vivier.eu> References: <20180102011032.30056-1-laurent@vivier.eu> X-Provags-ID: V03:K0:aJZVpYkW5YNDJlR6Xz+GgTJFA0URwuffw9kpgqvcRI2DzIoScFa Iyf2XohZN0mX/m/RyGPXJmsQo5bYaLjT5+hsm+UrrAAcksWv4tWpulpN6sLMZ6ewUikLdsa qkAq6Elq06jMtKrU9/hT8bpKNh4uMy1rAU3WMunZVzCnUlWuVPDibJ2iI4Kh72+A/H7Y3/5 e6nljR0ntJARBpKw4r9xA== X-UI-Out-Filterresults: notjunk:1;V01:K0:Dmi+yxkNgtk=:AMOkEu69Wn/XhcbCMhKyRr FDUzP65Y3dwvS+VvWzAqHBMr1xCc7+H7l/HxGFXHEVV8ghwnXHtUPTmJA8JwpQ5q7aWSM3tSY ZtgvalB8WkmXvycDZk9jUqPWcYghi0o41yaU02irdm/V89auCf+j47jmZ2SEelg7/WkdPOtfa AZjF+no4p8XJzfFq2Vtzuxs3sjP9s9sWd/luPEkbx9NBuY2TqyRlvW5QnJu8XiX7OTrRvahQT pm84NqKZC8AyCFlvDlSCwLRdzGxs46uz74JXJVQob1jlPkEeA7D9eqWDI0OPO8WcOE+HiAve7 W7MShzrtMoY+U77onhrrg1sUqzbaxaizVV4LQhkPS7WPj7MQf/oBLSFmErlTpTf2+zEja2wA9 yDtlXNLfsxQ3zPjkR1cGzXVi0QOR2hm7U9CVwQM7WlUvNnqx4Q7P9OVkZ5rMp0uodxx4zqZoh wGSffrq5F4BA00AlPJNfr1ePrZECzLX/Rl1nZobWR8A/BT+1pGOFa9qEJ/ZCI5KdDHbT/2z/e 5QiGJln4KIANmyHJuofLmNOrCvUkW4BYxU4iA3iEPNV/RnHo/ff5HAIsmcsFsmMQ45gJst8W5 a3zLxdOLGJfxNkjqovg7jib+qSu/+4uRMf7zw2Hflm779Hhhqm4jq5eHC51hKAztctxq3P5HS 6E+Ai2V1s55ZBgJMTIH2nOIA644cpji+P/ZdTmPlaijFKuCqqI6tUdOXldvwclOtUATtx/5qR z21W6ICeNU2s+ehm94ZmaDo3rTmw5bgpQJN0kQ== X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.130 Subject: [Qemu-devel] [PATCH v5 06/17] target/m68k: manage 680x0 stack frames 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: Thomas Huth , Laurent Vivier 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" 680x0 manages several stack frame formats: - format 0: four-word stack frame - format 1: four-word throwaway stack frame - format 2: six-word stack frame - format 3: Floating-Point post-instruction stack frame - format 4: eight-word stack frame - format 7: access-error stack frame Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson --- target/m68k/op_helper.c | 158 ++++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 155 insertions(+), 3 deletions(-) diff --git a/target/m68k/op_helper.c b/target/m68k/op_helper.c index f899b4b086..0099a92c8c 100644 --- a/target/m68k/op_helper.c +++ b/target/m68k/op_helper.c @@ -54,7 +54,7 @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessT= ype access_type, } } =20 -static void do_rte(CPUM68KState *env) +static void cf_rte(CPUM68KState *env) { uint32_t sp; uint32_t fmt; @@ -68,6 +68,45 @@ static void do_rte(CPUM68KState *env) helper_set_sr(env, fmt); } =20 +static void m68k_rte(CPUM68KState *env) +{ + uint32_t sp; + uint16_t fmt; + uint16_t sr; + + sp =3D env->aregs[7]; +throwaway: + sr =3D cpu_lduw_kernel(env, sp); + sp +=3D 2; + env->pc =3D cpu_ldl_kernel(env, sp); + sp +=3D 4; + if (m68k_feature(env, M68K_FEATURE_QUAD_MULDIV)) { + /* all except 68000 */ + fmt =3D cpu_lduw_kernel(env, sp); + sp +=3D 2; + switch (fmt >> 12) { + case 0: + break; + case 1: + env->aregs[7] =3D sp; + helper_set_sr(env, sr); + goto throwaway; + case 2: + case 3: + sp +=3D 4; + break; + case 4: + sp +=3D 8; + break; + case 7: + sp +=3D 52; + break; + } + } + env->aregs[7] =3D sp; + helper_set_sr(env, sr); +} + static const char *m68k_exception_name(int index) { switch (index) { @@ -173,7 +212,7 @@ static const char *m68k_exception_name(int index) return "Unassigned"; } =20 -static void do_interrupt_all(CPUM68KState *env, int is_hw) +static void cf_interrupt_all(CPUM68KState *env, int is_hw) { CPUState *cs =3D CPU(m68k_env_get_cpu(env)); uint32_t sp; @@ -188,7 +227,7 @@ static void do_interrupt_all(CPUM68KState *env, int is_= hw) switch (cs->exception_index) { case EXCP_RTE: /* Return from an exception. */ - do_rte(env); + cf_rte(env); return; case EXCP_HALT_INSN: if (semihosting_enabled() @@ -246,6 +285,119 @@ static void do_interrupt_all(CPUM68KState *env, int i= s_hw) env->pc =3D cpu_ldl_kernel(env, env->vbr + vector); } =20 +static inline void do_stack_frame(CPUM68KState *env, uint32_t *sp, + uint16_t format, uint16_t sr, + uint32_t addr, uint32_t retaddr) +{ + CPUState *cs =3D CPU(m68k_env_get_cpu(env)); + switch (format) { + case 4: + *sp -=3D 4; + cpu_stl_kernel(env, *sp, env->pc); + *sp -=3D 4; + cpu_stl_kernel(env, *sp, addr); + break; + case 3: + case 2: + *sp -=3D 4; + cpu_stl_kernel(env, *sp, addr); + break; + } + *sp -=3D 2; + cpu_stw_kernel(env, *sp, (format << 12) + (cs->exception_index << 2)); + *sp -=3D 4; + cpu_stl_kernel(env, *sp, retaddr); + *sp -=3D 2; + cpu_stw_kernel(env, *sp, sr); +} + +static void m68k_interrupt_all(CPUM68KState *env, int is_hw) +{ + CPUState *cs =3D CPU(m68k_env_get_cpu(env)); + uint32_t sp; + uint32_t retaddr; + uint32_t vector; + uint16_t sr, oldsr; + + retaddr =3D env->pc; + + if (!is_hw) { + switch (cs->exception_index) { + case EXCP_RTE: + /* Return from an exception. */ + m68k_rte(env); + return; + case EXCP_TRAP0 ... EXCP_TRAP15: + /* Move the PC after the trap instruction. */ + retaddr +=3D 2; + break; + } + } + + vector =3D cs->exception_index << 2; + + if (qemu_loglevel_mask(CPU_LOG_INT)) { + static int count; + qemu_log("INT %6d: %s(%#x) pc=3D%08x sp=3D%08x sr=3D%04x\n", + ++count, m68k_exception_name(cs->exception_index), + vector, env->pc, env->aregs[7], env->sr); + } + + /* + * MC68040UM/AD, chapter 9.3.10 + */ + + sr =3D env->sr | cpu_m68k_get_ccr(env); + /* "the processor first make an internal copy" */ + oldsr =3D sr; + /* "set the mode to supervisor" */ + sr |=3D SR_S; + /* "suppress tracing" */ + sr &=3D ~SR_T; + /* "sets the processor interrupt mask" */ + if (is_hw) { + sr |=3D (env->sr & ~SR_I) | (env->pending_level << SR_I_SHIFT); + } + helper_set_sr(env, sr); + sp =3D env->aregs[7]; + + sp &=3D ~1; + if (cs->exception_index =3D=3D EXCP_ADDRESS) { + do_stack_frame(env, &sp, 2, oldsr, 0, retaddr); + } else if (cs->exception_index =3D=3D EXCP_ILLEGAL || + cs->exception_index =3D=3D EXCP_DIV0 || + cs->exception_index =3D=3D EXCP_CHK || + cs->exception_index =3D=3D EXCP_TRAPCC || + cs->exception_index =3D=3D EXCP_TRACE) { + /* FIXME: addr is not only env->pc */ + do_stack_frame(env, &sp, 2, oldsr, env->pc, retaddr); + } else if (is_hw && oldsr & SR_M && + cs->exception_index >=3D EXCP_SPURIOUS && + cs->exception_index <=3D EXCP_INT_LEVEL_7) { + do_stack_frame(env, &sp, 0, oldsr, 0, retaddr); + oldsr =3D sr; + env->aregs[7] =3D sp; + helper_set_sr(env, sr &=3D ~SR_M); + sp =3D env->aregs[7] & ~1; + do_stack_frame(env, &sp, 1, oldsr, 0, retaddr); + } else { + do_stack_frame(env, &sp, 0, oldsr, 0, retaddr); + } + + env->aregs[7] =3D sp; + /* Jump to vector. */ + env->pc =3D cpu_ldl_kernel(env, env->vbr + vector); +} + +static void do_interrupt_all(CPUM68KState *env, int is_hw) +{ + if (m68k_feature(env, M68K_FEATURE_M68000)) { + m68k_interrupt_all(env, is_hw); + return; + } + cf_interrupt_all(env, is_hw); +} + void m68k_cpu_do_interrupt(CPUState *cs) { M68kCPU *cpu =3D M68K_CPU(cs); --=20 2.14.3