Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1HXliO-0007hB-4j for qemu-devel@nongnu.org; Sat, 31 Mar 2007 18:06:28 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1HXliL-0007gy-SK for qemu-devel@nongnu.org; Sat, 31 Mar 2007 18:06:27 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HXliL-0007gv-NN for qemu-devel@nongnu.org; Sat, 31 Mar 2007 17:06:25 -0500 Received: from farad.aurel32.net ([82.232.2.251] helo=mail.aurel32.net) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1HXlfT-0006Mx-Sa for qemu-devel@nongnu.org; Sat, 31 Mar 2007 18:03:28 -0400 Received: from amd64.aurel32.net ([2001:618:400:fc13:216:3eff:fe00:1009]) by mail.aurel32.net with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.63) (envelope-from ) id 1HXlfS-0004c5-Ar for qemu-devel@nongnu.org; Sun, 01 Apr 2007 00:03:26 +0200 Received: from aurel32 by amd64.aurel32.net with local (Exim 4.63) (envelope-from ) id 1HXlfS-0000ps-3T for qemu-devel@nongnu.org; Sun, 01 Apr 2007 00:03:26 +0200 Date: Sun, 1 Apr 2007 00:03:26 +0200 From: Aurelien Jarno Subject: Re: [Qemu-devel] [SPARC][PATCH] Add a few missing illegal_instruction traps Message-ID: <20070331220326.GA1887@amd64.aurel32.net> References: <20070331214334.GA1740@amd64.aurel32.net> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-15 Content-Disposition: inline In-Reply-To: <20070331214334.GA1740@amd64.aurel32.net> Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org On Sat, Mar 31, 2007 at 11:43:34PM +0200, Aurelien Jarno wrote: > Hi all, > > The current implementation of the SPARC CPU in QEMU does not generate > an illegal_instruction trap in a few cases: > > - The wrpsr instruction should generate an illegal_instruction trap if > CWP is greater than NWINDOWS. The current implementation ignores the > higher bits instead. > - The load or store alternate instructions does not support specifying > the ASI as an immediate value on a SPARCv8 CPU, which generates an > illegal_instruction in this case. This is however supported on a > SPARCv9 CPU. > - The STD and STDA *may* generate an illegal_instruction trap for a > mis-aligned rd. However, both emulated CPU (microSPARC II & > ultraSPARC) does actually generate a trap in this case. > The same applies for the LDD and LDDA instructions, please find an updated patch below. Index: cpu.h =================================================================== RCS file: /sources/qemu/qemu/target-sparc/cpu.h,v retrieving revision 1.30 diff -u -d -p -r1.30 cpu.h --- cpu.h 25 Mar 2007 07:55:52 -0000 1.30 +++ cpu.h 31 Mar 2007 21:56:14 -0000 @@ -268,7 +268,7 @@ void cpu_set_cwp(CPUSPARCState *env1, in env->psrs = (_tmp & PSR_S)? 1 : 0; \ env->psrps = (_tmp & PSR_PS)? 1 : 0; \ env->psret = (_tmp & PSR_ET)? 1 : 0; \ - cpu_set_cwp(env, _tmp & PSR_CWP & (NWINDOWS - 1)); \ + cpu_set_cwp(env, _tmp & PSR_CWP); \ } while (0) #ifdef TARGET_SPARC64 Index: op_helper.c =================================================================== RCS file: /sources/qemu/qemu/target-sparc/op_helper.c,v retrieving revision 1.22 diff -u -d -p -r1.22 op_helper.c --- op_helper.c 6 Dec 2006 15:51:39 -0000 1.22 +++ op_helper.c 31 Mar 2007 21:56:14 -0000 @@ -615,6 +615,9 @@ void helper_rett() { unsigned int cwp; + if (env->psret == 1) + raise_exception(TT_ILL_INSN); + env->psret = 1; cwp = (env->cwp + 1) & (NWINDOWS - 1); if (env->wim & (1 << cwp)) { @@ -655,6 +658,8 @@ void helper_debug() #ifndef TARGET_SPARC64 void do_wrpsr() { + if ((T0 & PSR_CWP) >= NWINDOWS) + raise_exception(TT_ILL_INSN); PUT_PSR(env, T0); } Index: translate.c =================================================================== RCS file: /sources/qemu/qemu/target-sparc/translate.c,v retrieving revision 1.38 diff -u -d -p -r1.38 translate.c --- translate.c 25 Mar 2007 07:55:52 -0000 1.38 +++ translate.c 31 Mar 2007 21:56:14 -0000 @@ -2313,6 +2313,8 @@ static void disas_sparc_insn(DisasContex gen_op_ldst(lduh); break; case 0x3: /* load double word */ + if (rd & 1) + goto illegal_insn; gen_op_ldst(ldd); gen_movl_T0_reg(rd + 1); break; @@ -2332,6 +2334,8 @@ static void disas_sparc_insn(DisasContex #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) case 0x10: /* load word alternate */ #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif @@ -2339,6 +2343,8 @@ static void disas_sparc_insn(DisasContex break; case 0x11: /* load unsigned byte alternate */ #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif @@ -2346,6 +2352,8 @@ static void disas_sparc_insn(DisasContex break; case 0x12: /* load unsigned halfword alternate */ #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif @@ -2353,14 +2361,20 @@ static void disas_sparc_insn(DisasContex break; case 0x13: /* load double word alternate */ #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif + if (rd & 1) + goto illegal_insn; gen_op_ldda(insn, 1, 8, 0); gen_movl_T0_reg(rd + 1); break; case 0x19: /* load signed byte alternate */ #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif @@ -2368,6 +2382,8 @@ static void disas_sparc_insn(DisasContex break; case 0x1a: /* load signed halfword alternate */ #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif @@ -2375,6 +2391,8 @@ static void disas_sparc_insn(DisasContex break; case 0x1d: /* ldstuba -- XXX: should be atomically */ #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif @@ -2382,6 +2400,8 @@ static void disas_sparc_insn(DisasContex break; case 0x1f: /* swap reg with alt. memory. Also atomically */ #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif @@ -2471,6 +2491,8 @@ static void disas_sparc_insn(DisasContex gen_op_ldst(sth); break; case 0x7: + if (rd & 1) + goto illegal_insn; flush_T2(dc); gen_movl_reg_T2(rd + 1); gen_op_ldst(std); @@ -2478,6 +2500,8 @@ static void disas_sparc_insn(DisasContex #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) case 0x14: #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif @@ -2485,6 +2509,8 @@ static void disas_sparc_insn(DisasContex break; case 0x15: #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif @@ -2492,6 +2518,8 @@ static void disas_sparc_insn(DisasContex break; case 0x16: #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif @@ -2499,9 +2527,13 @@ static void disas_sparc_insn(DisasContex break; case 0x17: #ifndef TARGET_SPARC64 + if (IS_IMM) + goto illegal_insn; if (!supervisor(dc)) goto priv_insn; #endif + if (rd & 1) + goto illegal_insn; flush_T2(dc); gen_movl_reg_T2(rd + 1); gen_op_stda(insn, 0, 8, 0); -- .''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' aurel32@debian.org | aurelien@aurel32.net `- people.debian.org/~aurel32 | www.aurel32.net