From nobody Thu May 2 19:54:29 2024 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 1486429349654732.9750349855354; Mon, 6 Feb 2017 17:02:29 -0800 (PST) Received: from localhost ([::1]:51331 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauAu-000660-9K for importer@patchew.org; Mon, 06 Feb 2017 20:02:28 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32883) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau8W-0004jp-Sr for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:02 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau8S-0005vS-Pb for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:00 -0500 Received: from mout.kundenserver.de ([212.227.126.131]:61946) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau8S-0005vH-Ey for qemu-devel@nongnu.org; Mon, 06 Feb 2017 19:59:56 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MOmdm-1cY8hc2S74-0069X3; Tue, 07 Feb 2017 01:59:34 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:15 +0100 Message-Id: <20170207005930.28327-2-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K0:6ZMFMJWJPK81RVZpRZKGWjg7NUW0fmXEnRP/JMqH8W3JKPJhX/B 4OrztYjq/kafy1/Bwsve6dtLhGAe5WGt79rx4NBl2YS+6ayAxXY0WwexPqsVbSZsTeci7Ou ppR4nneRAv8uGv94TgYBYEznoT9NWrmrfpyvd1aLkAVoGXJlOVowBsx0lYlC1hIWWwhXLBs SbzwKeFrfqq5o+0lHaAxw== X-UI-Out-Filterresults: notjunk:1;V01:K0:iiZMb2FXhRM=:nKuMPRHlTpBsgXz6+73Ujc JEIAgksJ9mp358clp7KjODMSlpxGQmDtBtyFk3n9scKgSHhC7gK94D4FMumT4etGJE9NyvQ+L gqL+6p1lukRXVr6RNlrzHfsFXGrXqbX6GSWCTugD95G1Dp8VFcJziOO7JkiwJOeVLju8oZM6Y jBindV1COt4KPv4Yr/BxgS5M1+eKcQkQ3Pj9Khy1xEJ2jIepBSp/7MLEk9nSEtD96wx/0QTYV Ah59tCdiVwB6yq3oSUs6Fx80UODjpGh1zOPHNpl2j9ob507XX5o+rYF6HqeeyfZTZEaj5lp7N x69M183ghQpYVaRwxsDLT0xj2bT8iHQ38zQZcXgfN5fLQpDG8THmx5UmEkqpeJzKJtmnC6LTP trndiEQEecXpQJnglgYfuobNzDtck50IPNH8v4nIrugsKyu6HYRHo1KmGcEwkl7pBnb7Y7VzB UaLnyAeEr4+Ca/1mg1iDc5QrW//4E8+JLbf0xXrUEDg/BKIweWwYf3/45TRtzwNp7AeULAUjI BQq61Kb8Un8oE8HG+c0lYHzQL8K1eN5X1j1AQievsWAG3QEm537eUOcE67Jw1W6JxY64Bq40I ZfrBLvD91mDl053NyXzPN1Y2NT6H9L+BSDvx/qVy5SigVkvGmDaL287YZCqGXaMWhTLGczd2l +9XX09JJE3e8wlsRxYds/G6XPBxaR8Wz9M5smnpdIk9VtMO2ZFxeLOKtqLE007jc5H91wXaBS kttDCO0zcT1Abk39 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.131 Subject: [Qemu-devel] [PATCH v3 01/16] softfloat: define 680x0 specific values 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 , Laurent Vivier , Aurelien Jarno , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 CC: Peter Maydell Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson --- fpu/softfloat-specialize.h | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h index 100c8a9..fb70d32 100644 --- a/fpu/softfloat-specialize.h +++ b/fpu/softfloat-specialize.h @@ -111,7 +111,7 @@ float16 float16_default_nan(float_status *status) *-------------------------------------------------------------------------= ---*/ float32 float32_default_nan(float_status *status) { -#if defined(TARGET_SPARC) +#if defined(TARGET_SPARC) || defined(TARGET_M68K) return const_float32(0x7FFFFFFF); #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) = || \ defined(TARGET_XTENSA) || defined(TARGET_S390X) || defined(TARGET_TR= ICORE) @@ -136,7 +136,7 @@ float32 float32_default_nan(float_status *status) *-------------------------------------------------------------------------= ---*/ float64 float64_default_nan(float_status *status) { -#if defined(TARGET_SPARC) +#if defined(TARGET_SPARC) || defined(TARGET_M68K) return const_float64(LIT64(0x7FFFFFFFFFFFFFFF)); #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) = || \ defined(TARGET_S390X) @@ -162,7 +162,10 @@ float64 float64_default_nan(float_status *status) floatx80 floatx80_default_nan(float_status *status) { floatx80 r; - +#if defined(TARGET_M68K) + r.low =3D LIT64(0xFFFFFFFFFFFFFFFF); + r.high =3D 0x7FFF; +#else if (status->snan_bit_is_one) { r.low =3D LIT64(0xBFFFFFFFFFFFFFFF); r.high =3D 0x7FFF; @@ -170,6 +173,7 @@ floatx80 floatx80_default_nan(float_status *status) r.low =3D LIT64(0xC000000000000000); r.high =3D 0xFFFF; } +#endif return r; } =20 @@ -502,6 +506,30 @@ static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bI= sQNaN, flag bIsSNaN, return 1; } } +#elif defined(TARGET_M68K) +static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, + flag aIsLargerSignificand) +{ + /* M68000 FAMILY PROGRAMMER=E2=80=99S REFERENCE MANUAL + * 3.4 FLOATING-POINT INSTRUCTION DETAILS + * If either operand, but not both operands, of an operation is a + * nonsignaling NaN, then that NaN is returned as the result. If both + * operands are nonsignaling NaNs, then the destination operand + * nonsignaling NaN is returned as the result. + * If either operand to an operation is a signaling NaN (SNaN), then t= he + * SNaN bit is set in the FPSR EXC byte. If the SNaN exception enable = bit + * is set in the FPCR ENABLE byte, then the exception is taken and the + * destination is not modified. If the SNaN exception enable bit is not + * set, setting the SNaN bit in the operand to a one converts the SNaN= to + * a nonsignaling NaN. The operation then continues as described in the + * preceding paragraph for nonsignaling NaNs. + */ + if (aIsQNaN || aIsSNaN) { /* a is the destination operand */ + return 0; /* return the destination operand */ + } else { + return 1; /* return b */ + } +} #else static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, flag aIsLargerSignificand) --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486429347351615.4160357579417; Mon, 6 Feb 2017 17:02:27 -0800 (PST) Received: from localhost ([::1]:51330 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauAq-00060c-Pz for importer@patchew.org; Mon, 06 Feb 2017 20:02:24 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32861) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau8U-0004jd-LA for qemu-devel@nongnu.org; Mon, 06 Feb 2017 19:59:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau8P-0005uv-V3 for qemu-devel@nongnu.org; Mon, 06 Feb 2017 19:59:58 -0500 Received: from mout.kundenserver.de ([212.227.126.130]:63507) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau8P-0005uV-KV for qemu-devel@nongnu.org; Mon, 06 Feb 2017 19:59:53 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MBo5j-1cl77w0g6B-00AoLs; Tue, 07 Feb 2017 01:59:35 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:16 +0100 Message-Id: <20170207005930.28327-3-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K0:f4DPurCb6YceEJ0pSb0GPaqfVC1rf/pkN7iZkI7NdnU2H6x5tec ufTJq77w3RSddapb1HI9lGhwRtr+P+3irhEskIKnxOyg6IeVojDZwL9qNbXDarcZAgTeNlb ofe0AdfyLVRKQDQ24KxB2iXtlUuvzvqHUdYdVkkDFglG4hm/m9HvmE3YPAfxx1aIptB+24j /Q8746w3W+5wx8ylcozAA== X-UI-Out-Filterresults: notjunk:1;V01:K0:uKwl7rFQUEo=:v00A1KW66PDTc5ui3JAVYh VktT5KJT3OnSumqD2njYEkxvRtFkTBKFAJpx5v739CrCLCiEHB1ZrMf5rwe+hUiYe6KB1R0Jl w+xxXfu8aFI5RHyJ7f7wXCOJUVEqhbLEJ+kqwL4u7tqu5R3CLsafScmeIZBF91ybPRc7WCtz7 5mARtZfrJEciXaeNl7iOqlbchAEHx4aWXlG2W1yOxfjiLCVyZfm2iVVcmZShKwzVZpMAZ+9rS IkaeLMYmFX6cCAsVXdv3NUJmXamdej4xFeFa0lCWd/2fhiL94VoWSEV87cMe3Q1qgJIudTELg yqQ5YJW+uU9Y+OYNPwP31L2JuhrQ1EQLv+do96b2s7CpC7mm/mSSZ60jTwxXWH86j4LCeY/wy Z7FjSTNFEy403Q7tBH+wLhbRWFy2z19qz9ENLo9KxEnUBhVDXXtYZpNiHECibp97UF1EvC/kV TUQLQlyzUWJYr50JYUO17vDPm5h76rdzZ8vLPwNBzZ/CuUkjmEf0pbTU1R5eJRXxVwZ3PDDk8 W9gYL4OlATYZZJ5FBS4pNBd2ODQDz+/0F+X5aAHozRmUnArPhEacI07RBicUBTAIV25FFUKbW pshHH9atVLq2+wr+kmkRwZsrK0jz9DE1QVe5ejGPIyIoXiQYYnodhrooSfGGEtNFB+NSf8hBm jtpgvIUp+4XEY7SQ82bn48ojhGSlEpggOlRiZR8KTx8reOao3CnaRUixwdcDwVwDJZd0zBdO4 CoekiaBBrQnCcaXz 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 v3 02/16] softloat: disable floatx80_invalid_encoding() for m68k 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: Andreas Schwab , Laurent Vivier , Aurelien Jarno , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 According to the comment, this definition of invalid encoding is given by intel developer's manual, and doesn't work with the behavior of 680x0 FPU. CC: Andreas Schwab Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson --- fpu/softfloat.c | 31 +++++++++++++++++++++++++++++++ include/fpu/softfloat.h | 15 --------------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/fpu/softfloat.c b/fpu/softfloat.c index c295f31..f95b19f 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -4799,6 +4799,37 @@ int float64_unordered_quiet(float64 a, float64 b, fl= oat_status *status) } =20 /*------------------------------------------------------------------------= ---- +| Return whether the given value is an invalid floatx80 encoding. +| Invalid floatx80 encodings arise when the integer bit is not set, but +| the exponent is not zero. The only times the integer bit is permitted to +| be zero is in subnormal numbers and the value zero. +| This includes what the Intel software developer's manual calls pseudo-Na= Ns, +| pseudo-infinities and un-normal numbers. It does not include +| pseudo-denormals, which must still be correctly handled as inputs even +| if they are never generated as outputs. +*-------------------------------------------------------------------------= ---*/ +static inline bool floatx80_invalid_encoding(floatx80 a) +{ +#if defined(TARGET_M68K) + /*--------------------------------------------------------------------= ----- + | M68000 FAMILY PROGRAMMER=E2=80=99S REFERENCE MANUAL + | 1.6.2 Denormalized Numbers + | Since the extended-precision data format has an explicit integer bi= t, + | a number can be formatted with a nonzero exponent, less than the ma= ximum + | value, and a zero integer bit. The IEEE 754 standard does not defi= ne a + | zero integer bit. Such a number is an unnormalized number. Hardware= does + | not directly support denormalized and unnormalized numbers, but + | implicitly supports them by trapping them as unimplemented data typ= es, + | allowing efficient conversion in software. + *---------------------------------------------------------------------= ---*/ + return 0; +#else + return (a.low & (1ULL << 63)) =3D=3D 0 && (a.high & 0x7FFF) !=3D 0; +#endif +} + + +/*------------------------------------------------------------------------= ---- | Returns the result of converting the extended double-precision floating- | point value `a' to the 32-bit two's complement integer format. The | conversion is performed according to the IEC/IEEE Standard for Binary diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index 842ec6b..3920c0a 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -678,21 +678,6 @@ static inline int floatx80_is_any_nan(floatx80 a) return ((a.high & 0x7fff) =3D=3D 0x7fff) && (a.low<<1); } =20 -/*------------------------------------------------------------------------= ---- -| Return whether the given value is an invalid floatx80 encoding. -| Invalid floatx80 encodings arise when the integer bit is not set, but -| the exponent is not zero. The only times the integer bit is permitted to -| be zero is in subnormal numbers and the value zero. -| This includes what the Intel software developer's manual calls pseudo-Na= Ns, -| pseudo-infinities and un-normal numbers. It does not include -| pseudo-denormals, which must still be correctly handled as inputs even -| if they are never generated as outputs. -*-------------------------------------------------------------------------= ---*/ -static inline bool floatx80_invalid_encoding(floatx80 a) -{ - return (a.low & (1ULL << 63)) =3D=3D 0 && (a.high & 0x7FFF) !=3D 0; -} - #define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL) #define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL) #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL) --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486429634662307.8758103682218; Mon, 6 Feb 2017 17:07:14 -0800 (PST) Received: from localhost ([::1]:51352 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauFV-0001Nt-7w for importer@patchew.org; Mon, 06 Feb 2017 20:07:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32900) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau8a-0004lg-TK for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau8W-0005x5-OV for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:04 -0500 Received: from mout.kundenserver.de ([212.227.126.187]:51714) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau8W-0005w0-Cm for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:00 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0LtS3k-1cTRsx2rCu-010qsJ; Tue, 07 Feb 2017 01:59:35 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:17 +0100 Message-Id: <20170207005930.28327-4-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:DpNS1GGm/R9+IgsDgmu4DTxVDyIDYU9Mb+jqffN2SrXi+hU9fos qE9QHIy01mWxzwdOyT6HLbfIhfXxZAxFPJ32qNI9qQgZYkNw4wHKU/D8DpKqze+hTAGg3Rd /X1K5ZdzX0KVwcyTVtMnhR7GbA+wpF9vzGb7Z0T5iBRt7yjRExFvXOINhs43dGZt17kLyVc fO7HlJ0hY0OirR0ZGjUSw== X-UI-Out-Filterresults: notjunk:1;V01:K0:m3dPwOv4PWc=:m+M/+bNRZihCbEb1DP7vPl 407IVsCwm5ksR7g1oxtdO04Tu69YqbtNtTgwsF0DjVi0wOgFqssaNSCzTr8d9/02fHC/EatqV gvWJzBo6DTSUaCwKQzINZQH3ngZXCj2qr/rKJX6XK+vcwM2joajgfOAjFikUZWiXAaxk/iqwc X1Iml5L+szwBQFQQaImyyXHH5kbOgkR/4Kjiu2Tv1cwh/nSZDUYiz25Gs3Bcp2T31fQuQxfDl 6+q2WjkHzPG76We6IikS1cFdkRkQCo45D+kooKKYZWJ697ZY5xLR3f60KoZeZFLiBTFgl/AWw Q1XWvLUN29NQgVTpDVsc7vjAW4wfVFQ8L4KQXJxJpDFvciXm9cSv6NKpvdgOvQRoNbiowXV4e TbbsPAB26uGXCSOC4p4LNjpVOfKV07djT1Pj4SEjaUJjZGQ8bFLYu+DXlEFeMXoVdubMYsTre HIpf0WUdzBHIpsalURlIA9SSIVVUpJQqskUpjAggAxa4fri19QCLCy927IM4kglW84w65mPaG qAzLnAlN22JKE+aMlm1//8AtGI0zD7BF/FdqCQG4Lk0/gaLl1OwEr7lIs2zJv7znDWS8Lei7q XHAgcT82ZLotTkp65tl1EWv+B4ll2YmQYo4hOd844oMjJF0M8BU9g8AcjFgJ49Z7KZ1IJnGJU NOrSDvD9g4Ok0TNrpmmSJcbX0HzvvyV/JEwQ1dBe/ieiPFQ1ixIraOUQXy9NDHl+iRY0= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.187 Subject: [Qemu-devel] [PATCH v3 03/16] target-m68k: move FPU helpers to fpu_helper.c 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson --- target/m68k/Makefile.objs | 2 +- target/m68k/fpu_helper.c | 112 ++++++++++++++++++++++++++++++++++++++++++= ++++ target/m68k/helper.c | 88 ------------------------------------ 3 files changed, 113 insertions(+), 89 deletions(-) create mode 100644 target/m68k/fpu_helper.c diff --git a/target/m68k/Makefile.objs b/target/m68k/Makefile.objs index 02cf616..39141ab 100644 --- a/target/m68k/Makefile.objs +++ b/target/m68k/Makefile.objs @@ -1,3 +1,3 @@ obj-y +=3D m68k-semi.o -obj-y +=3D translate.o op_helper.o helper.o cpu.o +obj-y +=3D translate.o op_helper.o helper.o cpu.o fpu_helper.o obj-y +=3D gdbstub.o diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c new file mode 100644 index 0000000..5bf2576 --- /dev/null +++ b/target/m68k/fpu_helper.c @@ -0,0 +1,112 @@ +/* + * m68k FPU helpers + * + * Copyright (c) 2006-2007 CodeSourcery + * Written by Paul Brook + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "exec/helper-proto.h" + +uint32_t HELPER(f64_to_i32)(CPUM68KState *env, float64 val) +{ + return float64_to_int32(val, &env->fp_status); +} + +float32 HELPER(f64_to_f32)(CPUM68KState *env, float64 val) +{ + return float64_to_float32(val, &env->fp_status); +} + +float64 HELPER(i32_to_f64)(CPUM68KState *env, uint32_t val) +{ + return int32_to_float64(val, &env->fp_status); +} + +float64 HELPER(f32_to_f64)(CPUM68KState *env, float32 val) +{ + return float32_to_float64(val, &env->fp_status); +} + +float64 HELPER(iround_f64)(CPUM68KState *env, float64 val) +{ + return float64_round_to_int(val, &env->fp_status); +} + +float64 HELPER(itrunc_f64)(CPUM68KState *env, float64 val) +{ + return float64_trunc_to_int(val, &env->fp_status); +} + +float64 HELPER(sqrt_f64)(CPUM68KState *env, float64 val) +{ + return float64_sqrt(val, &env->fp_status); +} + +float64 HELPER(abs_f64)(float64 val) +{ + return float64_abs(val); +} + +float64 HELPER(chs_f64)(float64 val) +{ + return float64_chs(val); +} + +float64 HELPER(add_f64)(CPUM68KState *env, float64 a, float64 b) +{ + return float64_add(a, b, &env->fp_status); +} + +float64 HELPER(sub_f64)(CPUM68KState *env, float64 a, float64 b) +{ + return float64_sub(a, b, &env->fp_status); +} + +float64 HELPER(mul_f64)(CPUM68KState *env, float64 a, float64 b) +{ + return float64_mul(a, b, &env->fp_status); +} + +float64 HELPER(div_f64)(CPUM68KState *env, float64 a, float64 b) +{ + return float64_div(a, b, &env->fp_status); +} + +float64 HELPER(sub_cmp_f64)(CPUM68KState *env, float64 a, float64 b) +{ + /* ??? This may incorrectly raise exceptions. */ + /* ??? Should flush denormals to zero. */ + float64 res; + res =3D float64_sub(a, b, &env->fp_status); + if (float64_is_quiet_nan(res, &env->fp_status)) { + /* +/-inf compares equal against itself, but sub returns nan. */ + if (!float64_is_quiet_nan(a, &env->fp_status) + && !float64_is_quiet_nan(b, &env->fp_status)) { + res =3D float64_zero; + if (float64_lt_quiet(a, res, &env->fp_status)) { + res =3D float64_chs(res); + } + } + } + return res; +} + +uint32_t HELPER(compare_f64)(CPUM68KState *env, float64 val) +{ + return float64_compare_quiet(val, float64_zero, &env->fp_status); +} diff --git a/target/m68k/helper.c b/target/m68k/helper.c index f750d3d..5ca9911 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -284,94 +284,6 @@ void HELPER(set_sr)(CPUM68KState *env, uint32_t val) m68k_switch_sp(env); } =20 -/* FPU helpers. */ -uint32_t HELPER(f64_to_i32)(CPUM68KState *env, float64 val) -{ - return float64_to_int32(val, &env->fp_status); -} - -float32 HELPER(f64_to_f32)(CPUM68KState *env, float64 val) -{ - return float64_to_float32(val, &env->fp_status); -} - -float64 HELPER(i32_to_f64)(CPUM68KState *env, uint32_t val) -{ - return int32_to_float64(val, &env->fp_status); -} - -float64 HELPER(f32_to_f64)(CPUM68KState *env, float32 val) -{ - return float32_to_float64(val, &env->fp_status); -} - -float64 HELPER(iround_f64)(CPUM68KState *env, float64 val) -{ - return float64_round_to_int(val, &env->fp_status); -} - -float64 HELPER(itrunc_f64)(CPUM68KState *env, float64 val) -{ - return float64_trunc_to_int(val, &env->fp_status); -} - -float64 HELPER(sqrt_f64)(CPUM68KState *env, float64 val) -{ - return float64_sqrt(val, &env->fp_status); -} - -float64 HELPER(abs_f64)(float64 val) -{ - return float64_abs(val); -} - -float64 HELPER(chs_f64)(float64 val) -{ - return float64_chs(val); -} - -float64 HELPER(add_f64)(CPUM68KState *env, float64 a, float64 b) -{ - return float64_add(a, b, &env->fp_status); -} - -float64 HELPER(sub_f64)(CPUM68KState *env, float64 a, float64 b) -{ - return float64_sub(a, b, &env->fp_status); -} - -float64 HELPER(mul_f64)(CPUM68KState *env, float64 a, float64 b) -{ - return float64_mul(a, b, &env->fp_status); -} - -float64 HELPER(div_f64)(CPUM68KState *env, float64 a, float64 b) -{ - return float64_div(a, b, &env->fp_status); -} - -float64 HELPER(sub_cmp_f64)(CPUM68KState *env, float64 a, float64 b) -{ - /* ??? This may incorrectly raise exceptions. */ - /* ??? Should flush denormals to zero. */ - float64 res; - res =3D float64_sub(a, b, &env->fp_status); - if (float64_is_quiet_nan(res, &env->fp_status)) { - /* +/-inf compares equal against itself, but sub returns nan. */ - if (!float64_is_quiet_nan(a, &env->fp_status) - && !float64_is_quiet_nan(b, &env->fp_status)) { - res =3D float64_zero; - if (float64_lt_quiet(a, res, &env->fp_status)) - res =3D float64_chs(res); - } - } - return res; -} - -uint32_t HELPER(compare_f64)(CPUM68KState *env, float64 val) -{ - return float64_compare_quiet(val, float64_zero, &env->fp_status); -} =20 /* MAC unit. */ /* FIXME: The MAC unit implementation is a bit of a mess. Some helpers --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486429869229961.6501738089094; Mon, 6 Feb 2017 17:11:09 -0800 (PST) Received: from localhost ([::1]:51373 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauJH-0004wj-VN for importer@patchew.org; Mon, 06 Feb 2017 20:11:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32993) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau8v-00056g-6H for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau8q-00068G-Bw for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:25 -0500 Received: from mout.kundenserver.de ([212.227.126.134]:63498) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau8p-00067f-Vz for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:20 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MF8Xf-1cdNtD15Tf-00GJ4K; Tue, 07 Feb 2017 01:59:36 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:18 +0100 Message-Id: <20170207005930.28327-5-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:DywDuBvKiCrPTI3ST4rM215/ZHZfmasu3HXIjz93XM6IMQXRqeK y2WUwr4oxxy83g+faoJrjEKebyjNbu4yPVbFQcfvQJa7AZDdqCLQ0D/3DsIW0t+1cqsHhDN K1BkXA9bDS1ioQNFiE/xULtc7OS1MErrMEkttFuHirwUTl3EQfLX4lVvt0ZyYrSl31ysLz5 7qxZHgCa+Dr2qXcJ+oL5Q== X-UI-Out-Filterresults: notjunk:1;V01:K0:2slC5wln/HY=:hk4PS7nj02LF6X858k2qsZ 3c+d992Wut8K/X1WfDLMmqYPhTZobl0CvtTOgmUZf9jskUAqJe12Tvw2L1vxMwKJ532667Aqo BL3KFJeKfg1aMDwwUaEp8MS9CY+3j2wGiEz6+/HLI6q+zMmUF+h+w4IcyARzMGfpQf5T9t0vE ipumkNMh8grIBOuSv/zw/iaTfWQ0IDYDHp0QDrPV/Dz/hadG5V+sLaCkavJRPzI/vUPA7IvQ/ krTxOfIX9PA+vCay8+mcFwYCNNv1jBk8C9xNxiTO1R8nY+Y5RjLkvhqmGHUQFFWcTHV68FiwZ nmBp+3tqyiN3BjfB3Q2dO0C4YSf3MJ74BF+/QqMPePzWx8DBNqF6CUzNaOVfwWifJJHj+DELu VIhNl2UtRJSrT1Zr2lya6WgDYcsnyaI7twV+YISQ6tmuaDtSnXHemL6FDK/HM8B48cWMFov7l jn7WH1BSNbn/0hmARQU2IXrFGTc+AqLnVGs8QnouxTSXAGwn/Wj3pL0sbqyGxC375gjQ7rSvJ Xfa5b2aNEMAetPRAHfOO3SbZznf5cM3+R+KwYswMGootGOS94LbIrODgvwVGpzY2gOPqgOZDn jVM7cRydwKK8U07tySqESQwMwjEPiMyQYmY1pS4qQn8mK+wGb3L6IfLLtvW3sp7l0ghfwPLFb CksTc53dL4iVSTVnCRP4FmIm5cym62TOjDxrWotG11O945LwAj6TXTLUj+0u6xRhfJUU= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.134 Subject: [Qemu-devel] [PATCH v3 04/16] target-m68k: define ext_opsize 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson --- target/m68k/translate.c | 43 ++++++++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 9f60fbc..d9ba735 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -669,6 +669,21 @@ static inline int insn_opsize(int insn) } } =20 +static inline int ext_opsize(int ext, int pos) +{ + switch ((ext >> pos) & 7) { + case 0: return OS_LONG; + case 1: return OS_SINGLE; + case 2: return OS_EXTENDED; + case 3: return OS_PACKED; + case 4: return OS_WORD; + case 5: return OS_DOUBLE; + case 6: return OS_BYTE; + default: + g_assert_not_reached(); + } +} + /* Assign value to a register. If the width is less than the register wid= th only the low part of the register is set. */ static void gen_partset_reg(int opsize, TCGv reg, TCGv val) @@ -4101,20 +4116,19 @@ DISAS_INSN(fpu) tmp32 =3D tcg_temp_new_i32(); /* fmove */ /* ??? TODO: Proper behavior on overflow. */ - switch ((ext >> 10) & 7) { - case 0: - opsize =3D OS_LONG; + + opsize =3D ext_opsize(ext, 10); + switch (opsize) { + case OS_LONG: gen_helper_f64_to_i32(tmp32, cpu_env, src); break; - case 1: - opsize =3D OS_SINGLE; + case OS_SINGLE: gen_helper_f64_to_f32(tmp32, cpu_env, src); break; - case 4: - opsize =3D OS_WORD; + case OS_WORD: gen_helper_f64_to_i32(tmp32, cpu_env, src); break; - case 5: /* OS_DOUBLE */ + case OS_DOUBLE: tcg_gen_mov_i32(tmp32, AREG(insn, 0)); switch ((insn >> 3) & 7) { case 2: @@ -4143,8 +4157,7 @@ DISAS_INSN(fpu) } tcg_temp_free_i32(tmp32); return; - case 6: - opsize =3D OS_BYTE; + case OS_BYTE: gen_helper_f64_to_i32(tmp32, cpu_env, src); break; default: @@ -4217,15 +4230,7 @@ DISAS_INSN(fpu) } if (ext & (1 << 14)) { /* Source effective address. */ - switch ((ext >> 10) & 7) { - case 0: opsize =3D OS_LONG; break; - case 1: opsize =3D OS_SINGLE; break; - case 4: opsize =3D OS_WORD; break; - case 5: opsize =3D OS_DOUBLE; break; - case 6: opsize =3D OS_BYTE; break; - default: - goto undef; - } + opsize =3D ext_opsize(ext, 10); if (opsize =3D=3D OS_DOUBLE) { tmp32 =3D tcg_temp_new_i32(); tcg_gen_mov_i32(tmp32, AREG(insn, 0)); --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 148643064658078.46385216099088; Mon, 6 Feb 2017 17:24:06 -0800 (PST) Received: from localhost ([::1]:51431 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauVp-0005Oh-4A for importer@patchew.org; Mon, 06 Feb 2017 20:24:05 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33171) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau9D-0005JG-1h for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau97-0006Eu-Rj for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:43 -0500 Received: from mout.kundenserver.de ([212.227.126.135]:51378) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau97-0006D2-3e for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:37 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0M53xy-1cEXO23Cus-00zE3p; Tue, 07 Feb 2017 01:59:37 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:19 +0100 Message-Id: <20170207005930.28327-6-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:0/uQSerXVc+6E7qPGyppwMir/VndtFMl3BcmRyvAZ5HHmS0B+M+ 8DsSsJsuTglGc+jFOd99vQPyQS+eL8LdlpVzgvIj7kGviGPp1g6HO7Q45RQ1ZWPIQOIUJU1 QkDGpgwo4Yzz2TOVc0TMZNTfFISkIcF3E2CTRw5wfCFQS0AUcP1hp47VKCDOFMYRUbY2BWZ q3ERhOEbKh6qe0QiYtFPQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:0RKa0tfT7fA=:vVGLv3/t+x2Pxkll3SyubW UcAVvjXb+PmvZ3oiuyLLMrx044NUybk6PMsjqpe8u4eftOq1ZyQjmcWtSZlvPiqu81GJEQJOB 5DoEaa1ZCNZRBKFrCe5pBkpuXGd+TZQku1hAveLY7Z52odIQyZfJjMVZe5BxZ4MoWtam1MkBI wmSTFbJRVOQbzTNYMt8Bzp4Q5xZCNWSczg4RYIDGepMrw20Gr32mQ3BuTn44i5GwL3X3nPIuM +8WnXaqKrbyAlFcQaipU95UJgZN0KxjixYHfWnoAu8XqT1dPrMRppLQ7KjhdnYey315Rs3k1G RFrbpmYPUPInJVuI9lhkAHTF98qEDbD2DpvhMFepV/b/r3ZLGuby2dyjXaoF/s0bAv8EO9AFt iDpnb2WpryA7eITFRldeOxJizSo9eu4malndzAbexRPNSoHhR87XLhBD0hxH+cv//LsxTnYFH 5NEih+OjkDVjMWz0nn/zXH6Vz7FeFUz3qPmMzXw9IfXo2NJI3df9Hhw1i8kPGjdACm4Rr1HMc deZPbvxTgzMEtJ5MK1AhVYcSroTL4LMLU5qJV3RrcGY5kOsWFc0jEoU3AzBR/EN04a0j9f7mx MpyC6TO8aFCVxPg3F7c9+xyarjWSNWmcUBvuKJBmcAxRjQ3xydJiRMYVRtzEEK8pV/tpWdcEA HkfcUMO6sivW4Weq3/54qjF9fmOHJX8b0vEByA0vRI7s1XKebbTEa+iBOq8TwPBk8kBE= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.135 Subject: [Qemu-devel] [PATCH v3 05/16] target-m68k: use floatx80 internally 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" Coldfire uses float64, but 680x0 use floatx80. This patch introduces the use of floatx80 internally and enables 680x0 80bits FPU. Signed-off-by: Laurent Vivier --- target/m68k/cpu.c | 13 +- target/m68k/cpu.h | 10 +- target/m68k/fpu_helper.c | 202 +++++++++++++--- target/m68k/helper.c | 12 +- target/m68k/helper.h | 32 +-- target/m68k/qregs.def | 3 +- target/m68k/translate.c | 617 +++++++++++++++++++++++++++++++------------= ---- 7 files changed, 616 insertions(+), 273 deletions(-) diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index fa10b6e..cedc272 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -49,6 +49,8 @@ static void m68k_cpu_reset(CPUState *s) M68kCPU *cpu =3D M68K_CPU(s); M68kCPUClass *mcc =3D M68K_CPU_GET_CLASS(cpu); CPUM68KState *env =3D &cpu->env; + floatx80 nan =3D floatx80_default_nan(NULL); + int i; =20 mcc->parent_reset(s); =20 @@ -57,7 +59,16 @@ static void m68k_cpu_reset(CPUState *s) env->sr =3D 0x2700; #endif m68k_switch_sp(env); - /* ??? FP regs should be initialized to NaN. */ + for (i =3D 0; i < 8; i++) { + env->fregs[i].d =3D nan; + } + env->fp0h =3D nan.high; + env->fp0l =3D nan.low; + env->fp1h =3D nan.high; + env->fp1l =3D nan.low; + env->fpcr =3D 0; + env->fpsr =3D 0; + cpu_m68k_set_ccr(env, 0); /* TODO: We should set PC from the interrupt vector. */ env->pc =3D 0; diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 8095822..192a877 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -64,6 +64,8 @@ #define NB_MMU_MODES 2 #define TARGET_INSN_START_EXTRA_WORDS 1 =20 +typedef CPU_LDoubleU FPReg; + typedef struct CPUM68KState { uint32_t dregs[8]; uint32_t aregs[8]; @@ -82,12 +84,16 @@ typedef struct CPUM68KState { uint32_t cc_c; /* either 0/1, unused, or computed from cc_n and cc_v */ uint32_t cc_z; /* =3D=3D 0 or unused */ =20 - float64 fregs[8]; - float64 fp_result; + FPReg fregs[8]; uint32_t fpcr; uint32_t fpsr; float_status fp_status; =20 + uint32_t fp0h; + uint64_t fp0l; + uint32_t fp1h; + uint64_t fp1l; + uint64_t mactmp; /* EMAC Hardware deals with 48-bit values composed of one 32-bit and two 8-bit parts. We store a single 64-bit value and diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index 5bf2576..9260e7b 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -3,6 +3,7 @@ * * Copyright (c) 2006-2007 CodeSourcery * Written by Paul Brook + * Copyright (c) 2011-2016 Laurent Vivier * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,92 +22,215 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" +#include "exec/exec-all.h" =20 -uint32_t HELPER(f64_to_i32)(CPUM68KState *env, float64 val) +static floatx80 FP0_to_floatx80(CPUM68KState *env) { - return float64_to_int32(val, &env->fp_status); + return (floatx80){ .low =3D env->fp0l, .high =3D env->fp0h }; } =20 -float32 HELPER(f64_to_f32)(CPUM68KState *env, float64 val) +static void floatx80_to_FP0(CPUM68KState *env, floatx80 res) { - return float64_to_float32(val, &env->fp_status); + env->fp0l =3D res.low; + env->fp0h =3D res.high; } =20 -float64 HELPER(i32_to_f64)(CPUM68KState *env, uint32_t val) +static int32_t FP0_to_int32(CPUM68KState *env) { - return int32_to_float64(val, &env->fp_status); + return env->fp0h; } =20 -float64 HELPER(f32_to_f64)(CPUM68KState *env, float32 val) +static void int32_to_FP0(CPUM68KState *env, int32_t val) { - return float32_to_float64(val, &env->fp_status); + env->fp0h =3D val; } =20 -float64 HELPER(iround_f64)(CPUM68KState *env, float64 val) +static float32 FP0_to_float32(CPUM68KState *env) { - return float64_round_to_int(val, &env->fp_status); + return *(float32 *)&env->fp0h; } =20 -float64 HELPER(itrunc_f64)(CPUM68KState *env, float64 val) +static void float32_to_FP0(CPUM68KState *env, float32 val) { - return float64_trunc_to_int(val, &env->fp_status); + env->fp0h =3D *(uint32_t *)&val; } =20 -float64 HELPER(sqrt_f64)(CPUM68KState *env, float64 val) +static float64 FP0_to_float64(CPUM68KState *env) { - return float64_sqrt(val, &env->fp_status); + return *(float64 *)&env->fp0l; +} +static void float64_to_FP0(CPUM68KState *env, float64 val) +{ + env->fp0l =3D *(uint64_t *)&val; } =20 -float64 HELPER(abs_f64)(float64 val) +static floatx80 FP1_to_floatx80(CPUM68KState *env) { - return float64_abs(val); + return (floatx80){ .low =3D env->fp1l, .high =3D env->fp1h }; } =20 -float64 HELPER(chs_f64)(float64 val) +void HELPER(exts32_FP0)(CPUM68KState *env) { - return float64_chs(val); + floatx80 res; + + res =3D int32_to_floatx80(FP0_to_int32(env), &env->fp_status); + + floatx80_to_FP0(env, res); } =20 -float64 HELPER(add_f64)(CPUM68KState *env, float64 a, float64 b) +void HELPER(extf32_FP0)(CPUM68KState *env) { - return float64_add(a, b, &env->fp_status); + floatx80 res; + + res =3D float32_to_floatx80(FP0_to_float32(env), &env->fp_status); + + floatx80_to_FP0(env, res); } =20 -float64 HELPER(sub_f64)(CPUM68KState *env, float64 a, float64 b) +void HELPER(extf64_FP0)(CPUM68KState *env) { - return float64_sub(a, b, &env->fp_status); + floatx80 res; + + res =3D float64_to_floatx80(FP0_to_float64(env), &env->fp_status); + + floatx80_to_FP0(env, res); } =20 -float64 HELPER(mul_f64)(CPUM68KState *env, float64 a, float64 b) +void HELPER(reds32_FP0)(CPUM68KState *env) { - return float64_mul(a, b, &env->fp_status); + int32_t res; + + res =3D floatx80_to_int32(FP0_to_floatx80(env), &env->fp_status); + + int32_to_FP0(env, res); } =20 -float64 HELPER(div_f64)(CPUM68KState *env, float64 a, float64 b) +void HELPER(redf32_FP0)(CPUM68KState *env) { - return float64_div(a, b, &env->fp_status); + float32 res; + + res =3D floatx80_to_float32(FP0_to_floatx80(env), &env->fp_status); + + float32_to_FP0(env, res); } =20 -float64 HELPER(sub_cmp_f64)(CPUM68KState *env, float64 a, float64 b) +void HELPER(redf64_FP0)(CPUM68KState *env) { - /* ??? This may incorrectly raise exceptions. */ - /* ??? Should flush denormals to zero. */ float64 res; - res =3D float64_sub(a, b, &env->fp_status); - if (float64_is_quiet_nan(res, &env->fp_status)) { + + res =3D floatx80_to_float64(FP0_to_floatx80(env), &env->fp_status); + + float64_to_FP0(env, res); +} + +void HELPER(iround_FP0)(CPUM68KState *env) +{ + floatx80 res; + + res =3D floatx80_round_to_int(FP0_to_floatx80(env), &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(itrunc_FP0)(CPUM68KState *env) +{ + floatx80 res; + + res =3D floatx80_round_to_int(FP0_to_floatx80(env), &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(sqrt_FP0)(CPUM68KState *env) +{ + floatx80 res; + + res =3D floatx80_sqrt(FP0_to_floatx80(env), &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(abs_FP0)(CPUM68KState *env) +{ + floatx80 res; + + res =3D floatx80_abs(FP0_to_floatx80(env)); + + floatx80_to_FP0(env, res); +} + +void HELPER(chs_FP0)(CPUM68KState *env) +{ + floatx80 res; + + res =3D floatx80_chs(FP0_to_floatx80(env)); + + floatx80_to_FP0(env, res); +} + +void HELPER(add_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + res =3D floatx80_add(FP0_to_floatx80(env), FP1_to_floatx80(env), + &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(sub_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + res =3D floatx80_sub(FP1_to_floatx80(env), FP0_to_floatx80(env), + &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(mul_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + res =3D floatx80_mul(FP0_to_floatx80(env), FP1_to_floatx80(env), + &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(div_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + res =3D floatx80_div(FP1_to_floatx80(env), FP0_to_floatx80(env), + &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(cmp_FP0_FP1)(CPUM68KState *env) +{ + floatx80 fp0 =3D FP0_to_floatx80(env); + floatx80 fp1 =3D FP1_to_floatx80(env); + floatx80 res; + + res =3D floatx80_sub(fp0, fp1, &env->fp_status); + if (floatx80_is_quiet_nan(res, &env->fp_status)) { /* +/-inf compares equal against itself, but sub returns nan. */ - if (!float64_is_quiet_nan(a, &env->fp_status) - && !float64_is_quiet_nan(b, &env->fp_status)) { - res =3D float64_zero; - if (float64_lt_quiet(a, res, &env->fp_status)) { - res =3D float64_chs(res); + if (!floatx80_is_quiet_nan(fp0, &env->fp_status) + && !floatx80_is_quiet_nan(fp1, &env->fp_status)) { + res =3D floatx80_zero; + if (floatx80_lt_quiet(fp0, res, &env->fp_status)) { + res =3D floatx80_chs(res); } } } - return res; + + floatx80_to_FP0(env, res); } =20 -uint32_t HELPER(compare_f64)(CPUM68KState *env, float64 val) +uint32_t HELPER(compare_FP0)(CPUM68KState *env) { - return float64_compare_quiet(val, float64_zero, &env->fp_status); + floatx80 fp0 =3D FP0_to_floatx80(env); + return floatx80_compare_quiet(fp0, floatx80_zero, &env->fp_status); } diff --git a/target/m68k/helper.c b/target/m68k/helper.c index 5ca9911..8bfc881 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -73,10 +73,11 @@ void m68k_cpu_list(FILE *f, fprintf_function cpu_fprint= f) g_slist_free(list); } =20 -static int fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n) +static int cf_fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n) { if (n < 8) { - stfq_p(mem_buf, env->fregs[n]); + float_status s; + stfq_p(mem_buf, floatx80_to_float64(env->fregs[n].d, &s)); return 8; } if (n < 11) { @@ -87,10 +88,11 @@ static int fpu_gdb_get_reg(CPUM68KState *env, uint8_t *= mem_buf, int n) return 0; } =20 -static int fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n) +static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n) { if (n < 8) { - env->fregs[n] =3D ldfq_p(mem_buf); + float_status s; + env->fregs[n].d =3D float64_to_floatx80(ldfq_p(mem_buf), &s); return 8; } if (n < 11) { @@ -126,7 +128,7 @@ void m68k_cpu_init_gdb(M68kCPU *cpu) CPUM68KState *env =3D &cpu->env; =20 if (m68k_feature(env, M68K_FEATURE_CF_FPU)) { - gdb_register_coprocessor(cs, fpu_gdb_get_reg, fpu_gdb_set_reg, + gdb_register_coprocessor(cs, cf_fpu_gdb_get_reg, cf_fpu_gdb_set_re= g, 11, "cf-fp.xml", 18); } /* TODO: Add [E]MAC registers. */ diff --git a/target/m68k/helper.h b/target/m68k/helper.h index d7a4bf1..d52689b 100644 --- a/target/m68k/helper.h +++ b/target/m68k/helper.h @@ -12,21 +12,23 @@ DEF_HELPER_3(movec, void, env, i32, i32) DEF_HELPER_4(cas2w, void, env, i32, i32, i32) DEF_HELPER_4(cas2l, void, env, i32, i32, i32) =20 -DEF_HELPER_2(f64_to_i32, f32, env, f64) -DEF_HELPER_2(f64_to_f32, f32, env, f64) -DEF_HELPER_2(i32_to_f64, f64, env, i32) -DEF_HELPER_2(f32_to_f64, f64, env, f32) -DEF_HELPER_2(iround_f64, f64, env, f64) -DEF_HELPER_2(itrunc_f64, f64, env, f64) -DEF_HELPER_2(sqrt_f64, f64, env, f64) -DEF_HELPER_1(abs_f64, f64, f64) -DEF_HELPER_1(chs_f64, f64, f64) -DEF_HELPER_3(add_f64, f64, env, f64, f64) -DEF_HELPER_3(sub_f64, f64, env, f64, f64) -DEF_HELPER_3(mul_f64, f64, env, f64, f64) -DEF_HELPER_3(div_f64, f64, env, f64, f64) -DEF_HELPER_3(sub_cmp_f64, f64, env, f64, f64) -DEF_HELPER_2(compare_f64, i32, env, f64) +DEF_HELPER_1(exts32_FP0, void, env) +DEF_HELPER_1(extf32_FP0, void, env) +DEF_HELPER_1(extf64_FP0, void, env) +DEF_HELPER_1(redf32_FP0, void, env) +DEF_HELPER_1(redf64_FP0, void, env) +DEF_HELPER_1(reds32_FP0, void, env) +DEF_HELPER_1(iround_FP0, void, env) +DEF_HELPER_1(itrunc_FP0, void, env) +DEF_HELPER_1(sqrt_FP0, void, env) +DEF_HELPER_1(abs_FP0, void, env) +DEF_HELPER_1(chs_FP0, void, env) +DEF_HELPER_1(add_FP0_FP1, void, env) +DEF_HELPER_1(sub_FP0_FP1, void, env) +DEF_HELPER_1(mul_FP0_FP1, void, env) +DEF_HELPER_1(div_FP0_FP1, void, env) +DEF_HELPER_1(cmp_FP0_FP1, void, env) +DEF_HELPER_1(compare_FP0, i32, env) =20 DEF_HELPER_3(mac_move, void, env, i32, i32) DEF_HELPER_3(macmulf, i64, env, i32, i32) diff --git a/target/m68k/qregs.def b/target/m68k/qregs.def index 51ff43b..b6441d9 100644 --- a/target/m68k/qregs.def +++ b/target/m68k/qregs.def @@ -1,4 +1,5 @@ -DEFF64(FP_RESULT, fp_result) +DEFF96(FP0, fp0) +DEFF96(FP1, fp1) DEFO32(PC, pc) DEFO32(SR, sr) DEFO32(CC_OP, cc_op) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index d9ba735..3a56b27 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -32,37 +32,30 @@ #include "trace-tcg.h" #include "exec/log.h" =20 - //#define DEBUG_DISPATCH 1 =20 -/* Fake floating point. */ -#define tcg_gen_mov_f64 tcg_gen_mov_i64 -#define tcg_gen_qemu_ldf64 tcg_gen_qemu_ld64 -#define tcg_gen_qemu_stf64 tcg_gen_qemu_st64 - #define DEFO32(name, offset) static TCGv QREG_##name; #define DEFO64(name, offset) static TCGv_i64 QREG_##name; -#define DEFF64(name, offset) static TCGv_i64 QREG_##name; +#define DEFF96(name, offset) static TCGv_i32 QREG_##name##H; \ + static TCGv_i64 QREG_##name##L; #include "qregs.def" #undef DEFO32 #undef DEFO64 -#undef DEFF64 +#undef DEFF96 =20 static TCGv_i32 cpu_halted; static TCGv_i32 cpu_exception_index; =20 static TCGv_env cpu_env; =20 -static char cpu_reg_names[3*8*3 + 5*4]; +static char cpu_reg_names[2 * 8 * 3 + 5 * 4]; static TCGv cpu_dregs[8]; static TCGv cpu_aregs[8]; -static TCGv_i64 cpu_fregs[8]; static TCGv_i64 cpu_macc[4]; =20 #define REG(insn, pos) (((insn) >> (pos)) & 7) #define DREG(insn, pos) cpu_dregs[REG(insn, pos)] #define AREG(insn, pos) get_areg(s, REG(insn, pos)) -#define FREG(insn, pos) cpu_fregs[REG(insn, pos)] #define MACREG(acc) cpu_macc[acc] #define QREG_SP get_areg(s, 7) =20 @@ -87,11 +80,16 @@ void m68k_tcg_init(void) #define DEFO64(name, offset) \ QREG_##name =3D tcg_global_mem_new_i64(cpu_env, \ offsetof(CPUM68KState, offset), #name); -#define DEFF64(name, offset) DEFO64(name, offset) +#define DEFF96(name, offset) do { \ + QREG_##name##H =3D tcg_global_mem_new_i32(cpu_env, \ + offsetof(CPUM68KState, offset##h), #name); \ + QREG_##name##L =3D tcg_global_mem_new_i64(cpu_env, \ + offsetof(CPUM68KState, offset##l), #name); \ +} while (0); #include "qregs.def" #undef DEFO32 #undef DEFO64 -#undef DEFF64 +#undef DEFF96 =20 cpu_halted =3D tcg_global_mem_new_i32(cpu_env, -offsetof(M68kCPU, env) + @@ -111,10 +109,6 @@ void m68k_tcg_init(void) cpu_aregs[i] =3D tcg_global_mem_new(cpu_env, offsetof(CPUM68KState, aregs[i])= , p); p +=3D 3; - sprintf(p, "F%d", i); - cpu_fregs[i] =3D tcg_global_mem_new_i64(cpu_env, - offsetof(CPUM68KState, fregs[i])= , p); - p +=3D 3; } for (i =3D 0; i < 4; i++) { sprintf(p, "ACC%d", i); @@ -286,7 +280,6 @@ static inline TCGv gen_load(DisasContext * s, int opsiz= e, TCGv addr, int sign) tcg_gen_qemu_ld16u(tmp, addr, index); break; case OS_LONG: - case OS_SINGLE: tcg_gen_qemu_ld32u(tmp, addr, index); break; default: @@ -296,16 +289,6 @@ static inline TCGv gen_load(DisasContext * s, int opsi= ze, TCGv addr, int sign) return tmp; } =20 -static inline TCGv_i64 gen_load64(DisasContext * s, TCGv addr) -{ - TCGv_i64 tmp; - int index =3D IS_USER(s); - tmp =3D tcg_temp_new_i64(); - tcg_gen_qemu_ldf64(tmp, addr, index); - gen_throws_exception =3D gen_last_qop; - return tmp; -} - /* Generate a store. */ static inline void gen_store(DisasContext *s, int opsize, TCGv addr, TCGv = val) { @@ -318,7 +301,6 @@ static inline void gen_store(DisasContext *s, int opsiz= e, TCGv addr, TCGv val) tcg_gen_qemu_st16(val, addr, index); break; case OS_LONG: - case OS_SINGLE: tcg_gen_qemu_st32(val, addr, index); break; default: @@ -327,13 +309,6 @@ static inline void gen_store(DisasContext *s, int opsi= ze, TCGv addr, TCGv val) gen_throws_exception =3D gen_last_qop; } =20 -static inline void gen_store64(DisasContext *s, TCGv addr, TCGv_i64 val) -{ - int index =3D IS_USER(s); - tcg_gen_qemu_stf64(val, addr, index); - gen_throws_exception =3D gen_last_qop; -} - typedef enum { EA_STORE, EA_LOADU, @@ -377,6 +352,15 @@ static inline uint32_t read_im32(CPUM68KState *env, Di= sasContext *s) return im; } =20 +/* Read a 64-bit immediate constant. */ +static inline uint64_t read_im64(CPUM68KState *env, DisasContext *s) +{ + uint64_t im; + im =3D (uint64_t)read_im32(env, s) << 32; + im |=3D (uint64_t)read_im32(env, s); + return im; +} + /* Calculate and address index. */ static TCGv gen_addr_index(DisasContext *s, uint16_t ext, TCGv tmp) { @@ -909,6 +893,291 @@ static TCGv gen_ea(CPUM68KState *env, DisasContext *s= , uint16_t insn, return gen_ea_mode(env, s, mode, reg0, opsize, val, addrp, what); } =20 +static void gen_op_load_fpr_FP0(int freg) +{ + tcg_gen_ld16u_i32(QREG_FP0H, cpu_env, + offsetof(CPUM68KState, fregs[freg].l.upper)); + tcg_gen_ld_i64(QREG_FP0L, cpu_env, + offsetof(CPUM68KState, fregs[freg].l.lower)); +} + +static void gen_op_store_fpr_FP0(int freg) +{ + tcg_gen_st16_i32(QREG_FP0H, cpu_env, + offsetof(CPUM68KState, fregs[freg].l.upper)); + tcg_gen_st_i64(QREG_FP0L, cpu_env, + offsetof(CPUM68KState, fregs[freg].l.lower)); +} + +static void gen_op_load_fpr_FP1(int freg) +{ + tcg_gen_ld16u_i32(QREG_FP1H, cpu_env, + offsetof(CPUM68KState, fregs[freg].l.upper)); + tcg_gen_ld_i64(QREG_FP1L, cpu_env, + offsetof(CPUM68KState, fregs[freg].l.lower)); +} + +static void gen_extend_FP0(int opsize) +{ + switch (opsize) { + case OS_BYTE: + tcg_gen_ext8s_i32(QREG_FP0H, QREG_FP0H); + gen_helper_exts32_FP0(cpu_env); + break; + case OS_WORD: + tcg_gen_ext16s_i32(QREG_FP0H, QREG_FP0H); + gen_helper_exts32_FP0(cpu_env); + break; + case OS_LONG: + gen_helper_exts32_FP0(cpu_env); + break; + case OS_SINGLE: + gen_helper_extf32_FP0(cpu_env); + break; + case OS_DOUBLE: + gen_helper_extf64_FP0(cpu_env); + break; + case OS_EXTENDED: + tcg_gen_shri_i32(QREG_FP0H, QREG_FP0H, 16); + break; + case OS_PACKED: + /* nothing to do */ + break; + default: + g_assert_not_reached(); + } +} + +static void gen_reduce_FP0(int opsize) +{ + switch (opsize) { + case OS_BYTE: + case OS_WORD: + case OS_LONG: + gen_helper_reds32_FP0(cpu_env); + break; + case OS_SINGLE: + gen_helper_redf32_FP0(cpu_env); + break; + case OS_DOUBLE: + gen_helper_redf64_FP0(cpu_env); + break; + case OS_EXTENDED: + tcg_gen_shli_i32(QREG_FP0H, QREG_FP0H, 16); + break; + case OS_PACKED: + /* nothing to do */ + break; + default: + g_assert_not_reached(); + } +} + +static void gen_load_FP0(DisasContext *s, int opsize, TCGv addr) +{ + TCGv tmp; + int index =3D IS_USER(s); + switch (opsize) { + case OS_BYTE: + tcg_gen_qemu_ld8s(QREG_FP0H, addr, index); + gen_helper_exts32_FP0(cpu_env); + break; + case OS_WORD: + tcg_gen_qemu_ld16s(QREG_FP0H, addr, index); + gen_helper_exts32_FP0(cpu_env); + break; + case OS_LONG: + tcg_gen_qemu_ld32u(QREG_FP0H, addr, index); + gen_helper_exts32_FP0(cpu_env); + break; + case OS_SINGLE: + tcg_gen_qemu_ld32u(QREG_FP0H, addr, index); + gen_helper_extf32_FP0(cpu_env); + break; + case OS_DOUBLE: + tcg_gen_qemu_ld64(QREG_FP0L, addr, index); + gen_helper_extf64_FP0(cpu_env); + break; + case OS_EXTENDED: + tcg_gen_qemu_ld32u(QREG_FP0H, addr, index); + tcg_gen_shri_i32(QREG_FP0H, QREG_FP0H, 16); + tmp =3D tcg_temp_new(); + tcg_gen_addi_i32(tmp, addr, 4); + tcg_gen_qemu_ld64(QREG_FP0L, tmp, index); + tcg_temp_free(tmp); + break; + case OS_PACKED: + tcg_gen_qemu_ld32u(QREG_FP0H, addr, index); + tmp =3D tcg_temp_new(); + tcg_gen_addi_i32(tmp, addr, 4); + tcg_gen_qemu_ld64(QREG_FP0L, tmp, index); + tcg_temp_free(tmp); + break; + default: + g_assert_not_reached(); + } + gen_throws_exception =3D gen_last_qop; +} + +static void gen_store_FP0(DisasContext *s, int opsize, TCGv addr) +{ + TCGv tmp; + int index =3D IS_USER(s); + switch (opsize) { + case OS_BYTE: + gen_helper_reds32_FP0(cpu_env); + tcg_gen_qemu_st8(QREG_FP0H, addr, index); + break; + case OS_WORD: + gen_helper_reds32_FP0(cpu_env); + tcg_gen_qemu_st16(QREG_FP0H, addr, index); + break; + case OS_LONG: + gen_helper_reds32_FP0(cpu_env); + tcg_gen_qemu_st32(QREG_FP0H, addr, index); + break; + case OS_SINGLE: + gen_helper_redf32_FP0(cpu_env); + tcg_gen_qemu_st32(QREG_FP0H, addr, index); + break; + case OS_DOUBLE: + gen_helper_redf64_FP0(cpu_env); + tcg_gen_qemu_st64(QREG_FP0L, addr, index); + break; + case OS_EXTENDED: + tcg_gen_shli_i32(QREG_FP0H, QREG_FP0H, 16); + tcg_gen_qemu_st32(QREG_FP0H, addr, index); + tmp =3D tcg_temp_new(); + tcg_gen_addi_i32(tmp, addr, 4); + tcg_gen_qemu_st64(QREG_FP0L, tmp, index); + tcg_temp_free(tmp); + break; + case OS_PACKED: + tcg_gen_qemu_st32(QREG_FP0H, addr, index); + tmp =3D tcg_temp_new(); + tcg_gen_addi_i32(tmp, addr, 4); + tcg_gen_qemu_st64(QREG_FP0L, tmp, index); + tcg_temp_free(tmp); + break; + default: + g_assert_not_reached(); + } + gen_throws_exception =3D gen_last_qop; +} + +static void gen_ldst_FP0(DisasContext *s, int opsize, TCGv addr, ea_what w= hat) +{ + if (what =3D=3D EA_STORE) { + gen_store_FP0(s, opsize, addr); + } else { + gen_load_FP0(s, opsize, addr); + } +} + +static int gen_ea_mode_FP0(CPUM68KState *env, DisasContext *s, int mode, + int reg0, int opsize, ea_what what) +{ + TCGv reg, addr; + uint64_t val64; + uint32_t val32; + + switch (mode) { + case 0: /* Data register direct. */ + reg =3D cpu_dregs[reg0]; + if (what =3D=3D EA_STORE) { + gen_reduce_FP0(opsize); + tcg_gen_mov_i32(reg, QREG_FP0H); + return 0; + } else { + tcg_gen_mov_i32(QREG_FP0H, reg); + gen_extend_FP0(opsize); + return 0; + } + case 1: /* Address register direct. */ + return -1; + case 2: /* Indirect register */ + reg =3D get_areg(s, reg0); + gen_ldst_FP0(s, opsize, reg, what); + return 0; + case 3: /* Indirect postincrement. */ + reg =3D cpu_aregs[reg0]; + gen_ldst_FP0(s, opsize, reg, what); + tcg_gen_addi_i32(reg, reg, opsize_bytes(opsize)); + return 0; + case 4: /* Indirect predecrememnt. */ + addr =3D gen_lea_mode(env, s, mode, reg0, opsize); + if (IS_NULL_QREG(addr)) { + return -1; + } + gen_ldst_FP0(s, opsize, addr, what); + tcg_gen_mov_i32(cpu_aregs[reg0], addr); + return 0; + case 5: /* Indirect displacement. */ + case 6: /* Indirect index + displacement. */ + do_indirect: + addr =3D gen_lea_mode(env, s, mode, reg0, opsize); + if (IS_NULL_QREG(addr)) { + return -1; + } + gen_ldst_FP0(s, opsize, addr, what); + return 0; + case 7: /* Other */ + switch (reg0) { + case 0: /* Absolute short. */ + case 1: /* Absolute long. */ + case 2: /* pc displacement */ + case 3: /* pc index+displacement. */ + goto do_indirect; + case 4: /* Immediate. */ + if (what =3D=3D EA_STORE) { + return -1; + } + val32 =3D 0; + val64 =3D 0; + switch (opsize) { + case OS_BYTE: + val32 =3D read_im8(env, s); + break; + case OS_WORD: + val32 =3D read_im16(env, s); + break; + case OS_LONG: + case OS_SINGLE: + val32 =3D read_im32(env, s); + break; + case OS_DOUBLE: + val64 =3D read_im64(env, s); + break; + case OS_EXTENDED: + val32 =3D read_im32(env, s); + val64 =3D read_im64(env, s); + break; + case OS_PACKED: + val32 =3D read_im32(env, s); + val64 =3D read_im64(env, s); + break; + default: + g_assert_not_reached(); + } + tcg_gen_movi_i32(QREG_FP0H, val32); + tcg_gen_movi_i64(QREG_FP0L, val64); + gen_extend_FP0(opsize); + return 0; + default: + return -1; + } + } + return -1; +} + +static int gen_ea_FP0(CPUM68KState *env, DisasContext *s, uint16_t insn, + int opsize, ea_what what) +{ + int mode =3D extract32(insn, 3, 3); + int reg0 =3D REG(insn, 0); + return gen_ea_mode_FP0(env, s, mode, reg0, opsize, what); +} + typedef struct { TCGCond tcond; bool g1; @@ -4089,16 +4358,53 @@ DISAS_INSN(trap) gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf)); } =20 +static void gen_op_fmove_fcr(CPUM68KState *env, DisasContext *s, + uint32_t insn, uint32_t ext) +{ + int mask =3D (ext >> 10) & 7; + int is_write =3D (ext >> 13) & 1; + TCGv tmp; + + tmp =3D gen_lea(env, s, insn, OS_LONG); + if (IS_NULL_QREG(tmp)) { + TCGv val; + + if (is_write) { + switch (mask) { + case 1: /* FPIAR */ + case 2: /* FPSR */ + default: + cpu_abort(NULL, "Unimplemented: fmove from control %d", ma= sk); + break; + case 4: /* FPCR */ + val =3D tcg_const_i32(0); + DEST_EA(env, insn, OS_LONG, val, NULL); + tcg_temp_free(val); + break; + } + return; + } + switch (mask) { + case 1: /* FPIAR */ + case 2: /* FPSR */ + default: + cpu_abort(NULL, "Unimplemented: fmove to control %d", + mask); + break; + case 4: /* FPCR */ + /* Not implemented. Ignore writes. */ + break; + } + return; + } +} + /* ??? FP exceptions are not implemented. Most exceptions are deferred un= til immediately before the next FP instruction is executed. */ DISAS_INSN(fpu) { uint16_t ext; - int32_t offset; int opmode; - TCGv_i64 src; - TCGv_i64 dest; - TCGv_i64 res; TCGv tmp32; int round; int set_dest; @@ -4112,87 +4418,17 @@ DISAS_INSN(fpu) case 1: goto undef; case 3: /* fmove out */ - src =3D FREG(ext, 7); - tmp32 =3D tcg_temp_new_i32(); - /* fmove */ - /* ??? TODO: Proper behavior on overflow. */ - + gen_op_load_fpr_FP0(REG(ext, 7)); opsize =3D ext_opsize(ext, 10); - switch (opsize) { - case OS_LONG: - gen_helper_f64_to_i32(tmp32, cpu_env, src); - break; - case OS_SINGLE: - gen_helper_f64_to_f32(tmp32, cpu_env, src); - break; - case OS_WORD: - gen_helper_f64_to_i32(tmp32, cpu_env, src); - break; - case OS_DOUBLE: - tcg_gen_mov_i32(tmp32, AREG(insn, 0)); - switch ((insn >> 3) & 7) { - case 2: - case 3: - break; - case 4: - tcg_gen_addi_i32(tmp32, tmp32, -8); - break; - case 5: - offset =3D cpu_ldsw_code(env, s->pc); - s->pc +=3D 2; - tcg_gen_addi_i32(tmp32, tmp32, offset); - break; - default: - goto undef; - } - gen_store64(s, tmp32, src); - switch ((insn >> 3) & 7) { - case 3: - tcg_gen_addi_i32(tmp32, tmp32, 8); - tcg_gen_mov_i32(AREG(insn, 0), tmp32); - break; - case 4: - tcg_gen_mov_i32(AREG(insn, 0), tmp32); - break; - } - tcg_temp_free_i32(tmp32); + if (gen_ea_FP0(env, s, insn, opsize, EA_STORE) =3D=3D -1) { + gen_addr_fault(s); return; - case OS_BYTE: - gen_helper_f64_to_i32(tmp32, cpu_env, src); - break; - default: - goto undef; } - DEST_EA(env, insn, opsize, tmp32, NULL); - tcg_temp_free_i32(tmp32); return; case 4: /* fmove to control register. */ - switch ((ext >> 10) & 7) { - case 4: /* FPCR */ - /* Not implemented. Ignore writes. */ - break; - case 1: /* FPIAR */ - case 2: /* FPSR */ - default: - cpu_abort(NULL, "Unimplemented: fmove to control %d", - (ext >> 10) & 7); - } - break; case 5: /* fmove from control register. */ - switch ((ext >> 10) & 7) { - case 4: /* FPCR */ - /* Not implemented. Always return zero. */ - tmp32 =3D tcg_const_i32(0); - break; - case 1: /* FPIAR */ - case 2: /* FPSR */ - default: - cpu_abort(NULL, "Unimplemented: fmove from control %d", - (ext >> 10) & 7); - goto undef; - } - DEST_EA(env, insn, OS_LONG, tmp32, NULL); - break; + gen_op_fmove_fcr(env, s, insn, ext); + return; case 6: /* fmovem */ case 7: { @@ -4211,14 +4447,9 @@ DISAS_INSN(fpu) mask =3D 0x80; for (i =3D 0; i < 8; i++) { if (ext & mask) { - dest =3D FREG(i, 0); - if (ext & (1 << 13)) { - /* store */ - tcg_gen_qemu_stf64(dest, addr, IS_USER(s)); - } else { - /* load */ - tcg_gen_qemu_ldf64(dest, addr, IS_USER(s)); - } + gen_op_load_fpr_FP0(REG(i, 0)); + gen_ldst_FP0(s, OS_DOUBLE, addr, (ext & (1 << 13)) ? + EA_STORE : EA_LOADS); if (ext & (mask - 1)) tcg_gen_addi_i32(addr, addr, 8); } @@ -4231,114 +4462,66 @@ DISAS_INSN(fpu) if (ext & (1 << 14)) { /* Source effective address. */ opsize =3D ext_opsize(ext, 10); - if (opsize =3D=3D OS_DOUBLE) { - tmp32 =3D tcg_temp_new_i32(); - tcg_gen_mov_i32(tmp32, AREG(insn, 0)); - switch ((insn >> 3) & 7) { - case 2: - case 3: - break; - case 4: - tcg_gen_addi_i32(tmp32, tmp32, -8); - break; - case 5: - offset =3D cpu_ldsw_code(env, s->pc); - s->pc +=3D 2; - tcg_gen_addi_i32(tmp32, tmp32, offset); - break; - case 7: - offset =3D cpu_ldsw_code(env, s->pc); - offset +=3D s->pc - 2; - s->pc +=3D 2; - tcg_gen_addi_i32(tmp32, tmp32, offset); - break; - default: - goto undef; - } - src =3D gen_load64(s, tmp32); - switch ((insn >> 3) & 7) { - case 3: - tcg_gen_addi_i32(tmp32, tmp32, 8); - tcg_gen_mov_i32(AREG(insn, 0), tmp32); - break; - case 4: - tcg_gen_mov_i32(AREG(insn, 0), tmp32); - break; - } - tcg_temp_free_i32(tmp32); - } else { - SRC_EA(env, tmp32, opsize, 1, NULL); - src =3D tcg_temp_new_i64(); - switch (opsize) { - case OS_LONG: - case OS_WORD: - case OS_BYTE: - gen_helper_i32_to_f64(src, cpu_env, tmp32); - break; - case OS_SINGLE: - gen_helper_f32_to_f64(src, cpu_env, tmp32); - break; - } + if (gen_ea_FP0(env, s, insn, opsize, EA_LOADS) =3D=3D -1) { + gen_addr_fault(s); + return; } } else { /* Source register. */ - src =3D FREG(ext, 10); + opsize =3D OS_EXTENDED; + gen_op_load_fpr_FP0(REG(ext, 10)); } - dest =3D FREG(ext, 7); - res =3D tcg_temp_new_i64(); - if (opmode !=3D 0x3a) - tcg_gen_mov_f64(res, dest); round =3D 1; set_dest =3D 1; switch (opmode) { case 0: case 0x40: case 0x44: /* fmove */ - tcg_gen_mov_f64(res, src); break; case 1: /* fint */ - gen_helper_iround_f64(res, cpu_env, src); + gen_helper_iround_FP0(cpu_env); round =3D 0; break; case 3: /* fintrz */ - gen_helper_itrunc_f64(res, cpu_env, src); + gen_helper_itrunc_FP0(cpu_env); round =3D 0; break; case 4: case 0x41: case 0x45: /* fsqrt */ - gen_helper_sqrt_f64(res, cpu_env, src); + gen_helper_sqrt_FP0(cpu_env); break; case 0x18: case 0x58: case 0x5c: /* fabs */ - gen_helper_abs_f64(res, src); + gen_helper_abs_FP0(cpu_env); break; case 0x1a: case 0x5a: case 0x5e: /* fneg */ - gen_helper_chs_f64(res, src); + gen_helper_chs_FP0(cpu_env); break; case 0x20: case 0x60: case 0x64: /* fdiv */ - gen_helper_div_f64(res, cpu_env, res, src); + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_div_FP0_FP1(cpu_env); break; case 0x22: case 0x62: case 0x66: /* fadd */ - gen_helper_add_f64(res, cpu_env, res, src); + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_add_FP0_FP1(cpu_env); break; case 0x23: case 0x63: case 0x67: /* fmul */ - gen_helper_mul_f64(res, cpu_env, res, src); + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_mul_FP0_FP1(cpu_env); break; case 0x28: case 0x68: case 0x6c: /* fsub */ - gen_helper_sub_f64(res, cpu_env, res, src); + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_sub_FP0_FP1(cpu_env); break; case 0x38: /* fcmp */ - gen_helper_sub_cmp_f64(res, cpu_env, res, src); + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_cmp_FP0_FP1(cpu_env); set_dest =3D 0; round =3D 0; break; case 0x3a: /* ftst */ - tcg_gen_mov_f64(res, src); set_dest =3D 0; round =3D 0; break; default: goto undef; } - if (ext & (1 << 14)) { - tcg_temp_free_i64(src); - } if (round) { if (opmode & 0x40) { if ((opmode & 0x4) !=3D 0) @@ -4348,16 +4531,15 @@ DISAS_INSN(fpu) } } if (round) { - TCGv tmp =3D tcg_temp_new_i32(); - gen_helper_f64_to_f32(tmp, cpu_env, res); - gen_helper_f32_to_f64(res, cpu_env, tmp); - tcg_temp_free_i32(tmp); + gen_helper_redf32_FP0(cpu_env); + gen_helper_extf32_FP0(cpu_env); + } else { + gen_helper_redf64_FP0(cpu_env); + gen_helper_extf64_FP0(cpu_env); } - tcg_gen_mov_f64(QREG_FP_RESULT, res); if (set_dest) { - tcg_gen_mov_f64(dest, res); + gen_op_store_fpr_FP0(REG(ext, 7)); } - tcg_temp_free_i64(res); return; undef: /* FIXME: Is this right for offset addressing modes? */ @@ -4382,10 +4564,10 @@ DISAS_INSN(fbcc) l1 =3D gen_new_label(); /* TODO: Raise BSUN exception. */ flag =3D tcg_temp_new(); - gen_helper_compare_f64(flag, cpu_env, QREG_FP_RESULT); + gen_helper_compare_FP0(flag, cpu_env); /* Jump to l1 if condition is true. */ switch (insn & 0xf) { - case 0: /* f */ + case 0: /* False */ break; case 1: /* eq (=3D0) */ tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(0), l1); @@ -5011,11 +5193,15 @@ void register_m68k_insns (CPUM68KState *env) INSN(bfop_reg, eec0, fff8, BITFIELD); /* bfset */ INSN(bfop_mem, e8c0, ffc0, BITFIELD); /* bftst */ INSN(bfop_reg, e8c0, fff8, BITFIELD); /* bftst */ - INSN(undef_fpu, f000, f000, CF_ISA_A); + BASE(undef_fpu, f000, f000); INSN(fpu, f200, ffc0, CF_FPU); INSN(fbcc, f280, ffc0, CF_FPU); INSN(frestore, f340, ffc0, CF_FPU); - INSN(fsave, f340, ffc0, CF_FPU); + INSN(fsave, f300, ffc0, CF_FPU); + INSN(fpu, f200, ffc0, FPU); + INSN(fbcc, f280, ff80, FPU); + INSN(frestore, f340, ffc0, FPU); + INSN(fsave, f300, ffc0, FPU); INSN(intouch, f340, ffc0, CF_ISA_A); INSN(cpushl, f428, ff38, CF_ISA_A); INSN(wddata, fb00, ff00, CF_ISA_A); @@ -5141,6 +5327,18 @@ void gen_intermediate_code(CPUM68KState *env, Transl= ationBlock *tb) tb->icount =3D num_insns; } =20 +static double floatx80_to_double(CPUM68KState *env, uint16_t high, uint64_= t low) +{ + floatx80 a =3D { .high =3D high, .low =3D low }; + union { + float64 f64; + double d; + } u; + + u.f64 =3D floatx80_to_float64(a, &env->fp_status); + return u.d; +} + void m68k_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprin= tf, int flags) { @@ -5148,20 +5346,19 @@ void m68k_cpu_dump_state(CPUState *cs, FILE *f, fpr= intf_function cpu_fprintf, CPUM68KState *env =3D &cpu->env; int i; uint16_t sr; - CPU_DoubleU u; - for (i =3D 0; i < 8; i++) - { - u.d =3D env->fregs[i]; - cpu_fprintf(f, "D%d =3D %08x A%d =3D %08x F%d =3D %08x%08x (%1= 2g)\n", + for (i =3D 0; i < 8; i++) { + cpu_fprintf(f, "D%d =3D %08x A%d =3D %08x " + "F%d =3D %04x %016"PRIx64" (%12g)\n", i, env->dregs[i], i, env->aregs[i], - i, u.l.upper, u.l.lower, *(double *)&u.d); - } + i, env->fregs[i].l.upper, env->fregs[i].l.lower, + floatx80_to_double(env, env->fregs[i].l.upper, + env->fregs[i].l.lower)); + } cpu_fprintf (f, "PC =3D %08x ", env->pc); sr =3D env->sr | cpu_m68k_get_ccr(env); cpu_fprintf(f, "SR =3D %04x %c%c%c%c%c ", sr, (sr & CCF_X) ? 'X' : '-', (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-', (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-'); - cpu_fprintf (f, "FPRESULT =3D %12g\n", *(double *)&env->fp_result); } =20 void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb, --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486429648971329.9691525035047; Mon, 6 Feb 2017 17:07:28 -0800 (PST) Received: from localhost ([::1]:51353 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauFh-0001ev-6Y for importer@patchew.org; Mon, 06 Feb 2017 20:07:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33000) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau8v-000576-PL for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:28 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau8q-00068W-Sy for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:25 -0500 Received: from mout.kundenserver.de ([212.227.126.187]:57571) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau8q-00067p-D0 for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:20 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0LeQ93-1c4scR0DdN-00qBmo; Tue, 07 Feb 2017 01:59:38 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:20 +0100 Message-Id: <20170207005930.28327-7-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K0:qloO8AKt6gzHI1A9hIlVrUH7Lk6d3w5vV2+3iHpovU5rJP/eA6G dcWWptNaG3ZYjI75FOS8snzqjWwP3kRIIV5U3RhQJmR8BOegAg4whcL6NxmYCDRASm1t6qY Hrg09aFe/B9FHu9XgAbNtGJFgEV+YrzuZf2wRTud+krSGr5m0RkzgkHTsKmFKKZRf5CGpii 2pcflPrcQfkNdBZz5e/Cw== X-UI-Out-Filterresults: notjunk:1;V01:K0:qJj5bdtuSbk=:ZcBMNkOnLIy3DCEkBLVIEP JC8sFWZ7YuUNs+fDhINZti5etcurEi0mw8JWLJOMeJ7PfsTHR9Muav1cVnftd3q4de8NYZZT4 G5yzTKArN4Hm5jidYIa4SvQEj7ZZBWerZ0FOo24k0qno9SjPG7gEHWf/3MCquDuUGGSzTZFIJ vBe4sGtptuKRx31JRTUEo21JrJKKfQ1GHwWncb+SB75c8hVaHczsZlejJzerwehjpU9a+vq/i jo8cr605i6xHv8pc0b0kBXYMm3vRK0hTPWr4AGLfEPYttgtkJ+qeCVmz1VxGt1egQ32tpH1YR sCGsbuDZeJr2l9fq0XBj1TF21cPLNRqRYclXMZrUVNhzcSIAcuyAna4XYQIy0f0HEuPSs+Mfp ldrHRYabCxkFc2RQpYN7HEf5d9EbCuo53aFrC/lrDDLQnXRFZXpmEHlFDA9cFB46DDUwINem2 00nGeDIuATKvRLyatfYSHSXw9nYqr3H6nHTu9QdD4N7S3H8NSICV/oWNpCiZGkq1ncZvcWJsl INryryAF/T6Pc8ReL/SrFK0rBQg6L1zZcssWtFJiI8UBjDSkWRfIRvXHMZl0cXtra39EryqUv 3HKwsVC9cmY0fQXl7sLjsox9fzILfhp1THiX8PglgoveatgjvqrotWMjdzY7FaRsOGl+fKimP r/TCAK/DtPndPdOmmsCgC10bEkXLsgDXqKTLrkrh9cZhYNjn6OdNq63ESJdpC0lTKRbJ27FVb AHZFUKmqi2s4jGVA X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.187 Subject: [Qemu-devel] [PATCH v3 06/16] target-m68k: add FPCR and FPSR 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: Laurent Vivier , Aurelien Jarno , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Laurent Vivier --- target/m68k/cpu.c | 2 +- target/m68k/cpu.h | 36 +++++- target/m68k/fpu_helper.c | 116 +++++++++++++++--- target/m68k/helper.c | 20 ++- target/m68k/helper.h | 3 +- target/m68k/qregs.def | 1 + target/m68k/translate.c | 311 +++++++++++++++++++++++++++++++++++--------= ---- 7 files changed, 381 insertions(+), 108 deletions(-) diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c index cedc272..9553df4 100644 --- a/target/m68k/cpu.c +++ b/target/m68k/cpu.c @@ -66,7 +66,7 @@ static void m68k_cpu_reset(CPUState *s) env->fp0l =3D nan.low; env->fp1h =3D nan.high; env->fp1l =3D nan.low; - env->fpcr =3D 0; + cpu_m68k_set_fpcr(env, 0); env->fpsr =3D 0; =20 cpu_m68k_set_ccr(env, 0); diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 192a877..6b3cb26 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -168,6 +168,7 @@ int cpu_m68k_signal_handler(int host_signum, void *pinf= o, void *puc); uint32_t cpu_m68k_get_ccr(CPUM68KState *env); void cpu_m68k_set_ccr(CPUM68KState *env, uint32_t); +void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val); =20 =20 /* Instead of computing the condition codes after each m68k instruction, @@ -212,6 +213,36 @@ typedef enum { #define M68K_SSP 0 #define M68K_USP 1 =20 +/* Floating-Point Status Register */ + +/* Condition Code */ +#define FPSR_CC_MASK 0x0f000000 +#define FPSR_CC_A 0x01000000 /* Not-A-Number */ +#define FPSR_CC_I 0x02000000 /* Infinity */ +#define FPSR_CC_Z 0x04000000 /* Zero */ +#define FPSR_CC_N 0x08000000 /* Negative */ + +/* Quotient */ + +#define FPSR_QT_MASK 0x00ff0000 + +/* Floating-Point Control Register */ +/* Rounding mode */ +#define FPCR_RND_MASK 0x0030 +#define FPCR_RND_N 0x0000 +#define FPCR_RND_Z 0x0010 +#define FPCR_RND_M 0x0020 +#define FPCR_RND_P 0x0030 + +/* Rounding precision */ +#define FPCR_PREC_MASK 0x00c0 +#define FPCR_PREC_X 0x0000 +#define FPCR_PREC_S 0x0040 +#define FPCR_PREC_D 0x0080 +#define FPCR_PREC_U 0x00c0 + +#define FPCR_EXCP_MASK 0xff00 + /* CACR fields are implementation defined, but some bits are common. */ #define M68K_CACR_EUSP 0x10 =20 @@ -228,8 +259,6 @@ typedef enum { void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector); void m68k_switch_sp(CPUM68KState *env); =20 -#define M68K_FPCR_PREC (1 << 6) - void do_m68k_semihosting(CPUM68KState *env, int nr); =20 /* There are 4 ColdFire core ISA revisions: A, A+, B and C. @@ -306,8 +335,7 @@ static inline void cpu_get_tb_cpu_state(CPUM68KState *e= nv, target_ulong *pc, { *pc =3D env->pc; *cs_base =3D 0; - *flags =3D (env->fpcr & M68K_FPCR_PREC) /* Bit 6 */ - | (env->sr & SR_S) /* Bit 13 */ + *flags =3D (env->sr & SR_S) /* Bit 13 */ | ((env->macsr >> 4) & 0xf); /* Bits 0-3 */ } =20 diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index 9260e7b..9d39118 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -132,11 +132,75 @@ void HELPER(iround_FP0)(CPUM68KState *env) floatx80_to_FP0(env, res); } =20 +static void m68k_restore_precision_mode(CPUM68KState *env) +{ + switch (env->fpcr & FPCR_PREC_MASK) { + case FPCR_PREC_X: /* extended */ + set_floatx80_rounding_precision(80, &env->fp_status); + break; + case FPCR_PREC_S: /* single */ + set_floatx80_rounding_precision(32, &env->fp_status); + break; + case FPCR_PREC_D: /* double */ + set_floatx80_rounding_precision(64, &env->fp_status); + break; + case FPCR_PREC_U: /* undefined */ + default: + break; + } +} + +static void cf_restore_precision_mode(CPUM68KState *env) +{ + if (env->fpcr & FPCR_PREC_S) { /* single */ + set_floatx80_rounding_precision(32, &env->fp_status); + } else { /* double */ + set_floatx80_rounding_precision(64, &env->fp_status); + } +} + +static void restore_rounding_mode(CPUM68KState *env) +{ + switch (env->fpcr & FPCR_RND_MASK) { + case FPCR_RND_N: /* round to nearest */ + set_float_rounding_mode(float_round_nearest_even, &env->fp_status); + break; + case FPCR_RND_Z: /* round to zero */ + set_float_rounding_mode(float_round_to_zero, &env->fp_status); + break; + case FPCR_RND_M: /* round toward minus infinity */ + set_float_rounding_mode(float_round_down, &env->fp_status); + break; + case FPCR_RND_P: /* round toward positive infinity */ + set_float_rounding_mode(float_round_up, &env->fp_status); + break; + } +} + +void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val) +{ + env->fpcr =3D val & 0xffff; + + if (m68k_feature(env, M68K_FEATURE_CF_FPU)) { + cf_restore_precision_mode(env); + } else { + m68k_restore_precision_mode(env); + } + restore_rounding_mode(env); +} + +void HELPER(set_fpcr)(CPUM68KState *env, uint32_t val) +{ + cpu_m68k_set_fpcr(env, val); +} + void HELPER(itrunc_FP0)(CPUM68KState *env) { floatx80 res; =20 + set_float_rounding_mode(float_round_to_zero, &env->fp_status); res =3D floatx80_round_to_int(FP0_to_floatx80(env), &env->fp_status); + restore_rounding_mode(env); =20 floatx80_to_FP0(env, res); } @@ -208,29 +272,47 @@ void HELPER(div_FP0_FP1)(CPUM68KState *env) floatx80_to_FP0(env, res); } =20 +static int float_comp_to_cc(int float_compare) +{ + switch (float_compare) { + case float_relation_equal: + return FPSR_CC_Z; + case float_relation_less: + return FPSR_CC_N; + case float_relation_unordered: + return FPSR_CC_A; + case float_relation_greater: + return 0; + default: + g_assert_not_reached(); + } +} + void HELPER(cmp_FP0_FP1)(CPUM68KState *env) { floatx80 fp0 =3D FP0_to_floatx80(env); floatx80 fp1 =3D FP1_to_floatx80(env); - floatx80 res; + int float_compare; =20 - res =3D floatx80_sub(fp0, fp1, &env->fp_status); - if (floatx80_is_quiet_nan(res, &env->fp_status)) { - /* +/-inf compares equal against itself, but sub returns nan. */ - if (!floatx80_is_quiet_nan(fp0, &env->fp_status) - && !floatx80_is_quiet_nan(fp1, &env->fp_status)) { - res =3D floatx80_zero; - if (floatx80_lt_quiet(fp0, res, &env->fp_status)) { - res =3D floatx80_chs(res); - } - } - } - - floatx80_to_FP0(env, res); + float_compare =3D floatx80_compare(fp1, fp0, &env->fp_status); + env->fpsr =3D (env->fpsr & ~FPSR_CC_MASK) | float_comp_to_cc(float_com= pare); } =20 -uint32_t HELPER(compare_FP0)(CPUM68KState *env) +void HELPER(tst_FP0)(CPUM68KState *env) { - floatx80 fp0 =3D FP0_to_floatx80(env); - return floatx80_compare_quiet(fp0, floatx80_zero, &env->fp_status); + uint32_t fpsr =3D 0; + floatx80 val =3D FP0_to_floatx80(env); + + if (floatx80_is_neg(val)) { + fpsr |=3D FPSR_CC_N; + } + + if (floatx80_is_any_nan(val)) { + fpsr |=3D FPSR_CC_A; + } else if (floatx80_is_infinity(val)) { + fpsr |=3D FPSR_CC_I; + } else if (floatx80_is_zero(val)) { + fpsr |=3D FPSR_CC_Z; + } + env->fpsr =3D (env->fpsr & ~FPSR_CC_MASK) | fpsr; } diff --git a/target/m68k/helper.c b/target/m68k/helper.c index 8bfc881..cff93dc 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -80,8 +80,14 @@ static int cf_fpu_gdb_get_reg(CPUM68KState *env, uint8_t= *mem_buf, int n) stfq_p(mem_buf, floatx80_to_float64(env->fregs[n].d, &s)); return 8; } - if (n < 11) { - /* FP control registers (not implemented) */ + switch (n) { + case 8: /* fpcontrol */ + stl_be_p(mem_buf, env->fpcr); + return 4; + case 9: /* fpstatus */ + stl_be_p(mem_buf, env->fpsr); + return 4; + case 10: /* fpiar, not implemented */ memset(mem_buf, 0, 4); return 4; } @@ -95,8 +101,14 @@ static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8_= t *mem_buf, int n) env->fregs[n].d =3D float64_to_floatx80(ldfq_p(mem_buf), &s); return 8; } - if (n < 11) { - /* FP control registers (not implemented) */ + switch (n) { + case 8: /* fpcontrol */ + env->fpcr =3D ldl_p(mem_buf); + return 4; + case 9: /* fpstatus */ + env->fpsr =3D ldl_p(mem_buf); + return 4; + case 10: /* fpiar, not implemented */ return 4; } return 0; diff --git a/target/m68k/helper.h b/target/m68k/helper.h index d52689b..03fb268 100644 --- a/target/m68k/helper.h +++ b/target/m68k/helper.h @@ -28,7 +28,8 @@ DEF_HELPER_1(sub_FP0_FP1, void, env) DEF_HELPER_1(mul_FP0_FP1, void, env) DEF_HELPER_1(div_FP0_FP1, void, env) DEF_HELPER_1(cmp_FP0_FP1, void, env) -DEF_HELPER_1(compare_FP0, i32, env) +DEF_HELPER_2(set_fpcr, void, env, i32) +DEF_HELPER_1(tst_FP0, void, env) =20 DEF_HELPER_3(mac_move, void, env, i32, i32) DEF_HELPER_3(macmulf, i64, env, i32, i32) diff --git a/target/m68k/qregs.def b/target/m68k/qregs.def index b6441d9..b355e0e 100644 --- a/target/m68k/qregs.def +++ b/target/m68k/qregs.def @@ -10,3 +10,4 @@ DEFO32(CC_V, cc_v) DEFO32(CC_Z, cc_z) DEFO32(MACSR, macsr) DEFO32(MAC_MASK, mac_mask) +DEFO32(FPSR, fpsr) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 3a56b27..cce8a8f 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -52,6 +52,8 @@ static char cpu_reg_names[2 * 8 * 3 + 5 * 4]; static TCGv cpu_dregs[8]; static TCGv cpu_aregs[8]; static TCGv_i64 cpu_macc[4]; +static TCGv QEMU_FPSR; +static TCGv QEMU_FPCR; =20 #define REG(insn, pos) (((insn) >> (pos)) & 7) #define DREG(insn, pos) cpu_dregs[REG(insn, pos)] @@ -117,6 +119,11 @@ void m68k_tcg_init(void) p +=3D 5; } =20 + QEMU_FPSR =3D tcg_global_mem_new(cpu_env, offsetof(CPUM68KState, fpsr), + "FPSR"); + QEMU_FPCR =3D tcg_global_mem_new(cpu_env, offsetof(CPUM68KState, fpcr), + "FPCR"); + NULL_QREG =3D tcg_global_mem_new(cpu_env, -4, "NULL"); store_dummy =3D tcg_global_mem_new(cpu_env, -8, "NULL"); } @@ -130,7 +137,6 @@ typedef struct DisasContext { CCOp cc_op; /* Current CC operation */ int cc_op_synced; int user; - uint32_t fpcr; struct TranslationBlock *tb; int singlestep_enabled; TCGv_i64 mactmp; @@ -4358,12 +4364,49 @@ DISAS_INSN(trap) gen_exception(s, s->pc - 2, EXCP_TRAP0 + (insn & 0xf)); } =20 +static void gen_store_fcr(DisasContext *s, TCGv addr, int reg) +{ + int index =3D IS_USER(s); + + switch (reg) { + case 0: /* FPSR */ + tcg_gen_qemu_st32(QEMU_FPSR, addr, index); + break; + case 1: /* FPIAR */ + break; + case 2: /* FPCR */ + tcg_gen_qemu_st32(QEMU_FPCR, addr, index); + break; + } +} + +static void gen_load_fcr(DisasContext *s, TCGv addr, int reg) +{ + int index =3D IS_USER(s); + TCGv val; + + switch (reg) { + case 0: /* FPSR */ + tcg_gen_qemu_ld32u(QEMU_FPSR, addr, index); + break; + case 1: /* FPIAR */ + break; + case 2: /* FPCR */ + val =3D tcg_temp_new(); + tcg_gen_qemu_ld32u(val, addr, index); + gen_helper_set_fpcr(cpu_env, val); + tcg_temp_free(val); + break; + } +} + static void gen_op_fmove_fcr(CPUM68KState *env, DisasContext *s, uint32_t insn, uint32_t ext) { int mask =3D (ext >> 10) & 7; int is_write =3D (ext >> 13) & 1; - TCGv tmp; + int i; + TCGv addr, tmp; =20 tmp =3D gen_lea(env, s, insn, OS_LONG); if (IS_NULL_QREG(tmp)) { @@ -4372,31 +4415,70 @@ static void gen_op_fmove_fcr(CPUM68KState *env, Dis= asContext *s, if (is_write) { switch (mask) { case 1: /* FPIAR */ + break; case 2: /* FPSR */ - default: - cpu_abort(NULL, "Unimplemented: fmove from control %d", ma= sk); + DEST_EA(env, insn, OS_LONG, QEMU_FPSR, NULL); break; case 4: /* FPCR */ - val =3D tcg_const_i32(0); - DEST_EA(env, insn, OS_LONG, val, NULL); - tcg_temp_free(val); + DEST_EA(env, insn, OS_LONG, QEMU_FPCR, NULL); break; } return; } switch (mask) { case 1: /* FPIAR */ + break; case 2: /* FPSR */ - default: - cpu_abort(NULL, "Unimplemented: fmove to control %d", - mask); + SRC_EA(env, val, OS_LONG, 0, NULL); + tcg_gen_mov_i32(QEMU_FPSR, val); break; case 4: /* FPCR */ - /* Not implemented. Ignore writes. */ + SRC_EA(env, val, OS_LONG, 0, NULL); + gen_helper_set_fpcr(cpu_env, val); break; } return; } + + addr =3D tcg_temp_new(); + tcg_gen_mov_i32(addr, tmp); + + /* mask: + * + * 0b100 Floating-Point Control Register + * 0b010 Floating-Point Status Register + * 0b001 Floating-Point Instruction Address Register + * + */ + + if (is_write && (insn & 070) =3D=3D 040) { + for (i =3D 2; i >=3D 0; i--, mask >>=3D 1) { + if (mask & 1) { + gen_store_fcr(s, addr, i); + if (mask !=3D 1) { + tcg_gen_subi_i32(addr, addr, opsize_bytes(OS_LONG)); + } + } + } + tcg_gen_mov_i32(AREG(insn, 0), addr); + } else { + for (i =3D 0; i < 3; i++, mask >>=3D 1) { + if (mask & 1) { + if (is_write) { + gen_store_fcr(s, addr, i); + } else { + gen_load_fcr(s, addr, i); + } + if (mask !=3D 1 || (insn & 070) =3D=3D 030) { + tcg_gen_addi_i32(addr, addr, opsize_bytes(OS_LONG)); + } + } + } + if ((insn & 070) =3D=3D 030) { + tcg_gen_mov_i32(AREG(insn, 0), addr); + } + } + tcg_temp_free_i32(addr); } =20 /* ??? FP exceptions are not implemented. Most exceptions are deferred un= til @@ -4406,8 +4488,6 @@ DISAS_INSN(fpu) uint16_t ext; int opmode; TCGv tmp32; - int round; - int set_dest; int opsize; =20 ext =3D read_im16(env, s); @@ -4424,6 +4504,7 @@ DISAS_INSN(fpu) gen_addr_fault(s); return; } + gen_helper_tst_FP0(cpu_env); return; case 4: /* fmove to control register. */ case 5: /* fmove from control register. */ @@ -4471,18 +4552,14 @@ DISAS_INSN(fpu) opsize =3D OS_EXTENDED; gen_op_load_fpr_FP0(REG(ext, 10)); } - round =3D 1; - set_dest =3D 1; switch (opmode) { case 0: case 0x40: case 0x44: /* fmove */ break; case 1: /* fint */ gen_helper_iround_FP0(cpu_env); - round =3D 0; break; case 3: /* fintrz */ gen_helper_itrunc_FP0(cpu_env); - round =3D 0; break; case 4: case 0x41: case 0x45: /* fsqrt */ gen_helper_sqrt_FP0(cpu_env); @@ -4512,34 +4589,15 @@ DISAS_INSN(fpu) case 0x38: /* fcmp */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_cmp_FP0_FP1(cpu_env); - set_dest =3D 0; - round =3D 0; - break; + return; case 0x3a: /* ftst */ - set_dest =3D 0; - round =3D 0; - break; + gen_helper_tst_FP0(cpu_env); + return; default: goto undef; } - if (round) { - if (opmode & 0x40) { - if ((opmode & 0x4) !=3D 0) - round =3D 0; - } else if ((s->fpcr & M68K_FPCR_PREC) =3D=3D 0) { - round =3D 0; - } - } - if (round) { - gen_helper_redf32_FP0(cpu_env); - gen_helper_extf32_FP0(cpu_env); - } else { - gen_helper_redf64_FP0(cpu_env); - gen_helper_extf64_FP0(cpu_env); - } - if (set_dest) { - gen_op_store_fpr_FP0(REG(ext, 7)); - } + gen_op_store_fpr_FP0(REG(ext, 7)); + gen_helper_tst_FP0(cpu_env); return; undef: /* FIXME: Is this right for offset addressing modes? */ @@ -4551,8 +4609,8 @@ DISAS_INSN(fbcc) { uint32_t offset; uint32_t addr; - TCGv flag; TCGLabel *l1; + TCGv tmp; =20 addr =3D s->pc; offset =3D cpu_ldsw_code(env, s->pc); @@ -4563,57 +4621,117 @@ DISAS_INSN(fbcc) =20 l1 =3D gen_new_label(); /* TODO: Raise BSUN exception. */ - flag =3D tcg_temp_new(); - gen_helper_compare_FP0(flag, cpu_env); /* Jump to l1 if condition is true. */ - switch (insn & 0xf) { + switch (insn & 0x3f) { case 0: /* False */ + case 16: /* Signaling False */ break; - case 1: /* eq (=3D0) */ - tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(0), l1); - break; - case 2: /* ogt (=3D1) */ - tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(1), l1); - break; - case 3: /* oge (=3D0 or =3D1) */ - tcg_gen_brcond_i32(TCG_COND_LEU, flag, tcg_const_i32(1), l1); - break; - case 4: /* olt (=3D-1) */ - tcg_gen_brcond_i32(TCG_COND_LT, flag, tcg_const_i32(0), l1); - break; - case 5: /* ole (=3D-1 or =3D0) */ - tcg_gen_brcond_i32(TCG_COND_LE, flag, tcg_const_i32(0), l1); + case 1: /* EQual Z */ + case 17: /* Signaling EQual Z */ + tmp =3D tcg_temp_new(); + tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_Z); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); break; - case 6: /* ogl (=3D-1 or =3D1) */ - tcg_gen_andi_i32(flag, flag, 1); - tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(0), l1); + case 2: /* Ordered Greater Than !(A || Z || N) */ + case 18: /* Greater Than !(A || Z || N) */ + tmp =3D tcg_temp_new(); + tcg_gen_andi_i32(tmp, QREG_FPSR, + FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N); + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1); break; - case 7: /* or (=3D2) */ - tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(2), l1); + case 3: /* Ordered Greater than or Equal Z || !(A || N) */ + case 19: /* Greater than or Equal Z || !(A || N) */ + assert(FPSR_CC_A =3D=3D (FPSR_CC_N >> 3)); + tmp =3D tcg_temp_new(); + tcg_gen_shli_i32(tmp, QREG_FPSR, 3); + tcg_gen_or_i32(tmp, tmp, QREG_FPSR); + tcg_gen_xori_i32(tmp, tmp, FPSR_CC_N); + tcg_gen_andi_i32(tmp, tmp, FPSR_CC_N | FPSR_CC_Z); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + break; + case 4: /* Ordered Less Than !(!N || A || Z); */ + case 20: /* Less Than !(!N || A || Z); */ + tmp =3D tcg_temp_new(); + tcg_gen_xori_i32(tmp, QREG_FPSR, FPSR_CC_N); + tcg_gen_andi_i32(tmp, tmp, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z); + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1); break; - case 8: /* un (<2) */ - tcg_gen_brcond_i32(TCG_COND_LT, flag, tcg_const_i32(2), l1); + case 5: /* Ordered Less than or Equal Z || (N && !A) */ + case 21: /* Less than or Equal Z || (N && !A) */ + assert(FPSR_CC_A =3D=3D (FPSR_CC_N >> 3)); + tmp =3D tcg_temp_new(); + tcg_gen_xori_i32(tmp, QREG_FPSR, FPSR_CC_A); + tcg_gen_shli_i32(tmp, tmp, 3); + tcg_gen_ori_i32(tmp, tmp, FPSR_CC_Z); + tcg_gen_and_i32(tmp, tmp, QREG_FPSR); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + break; + case 6: /* Ordered Greater or Less than !(A ||=C2=A0Z) */ + case 22: /* Greater or Less than !(A ||=C2=A0Z) */ + tmp =3D tcg_temp_new(); + tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z); + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1); break; - case 9: /* ueq (=3D0 or =3D2) */ - tcg_gen_andi_i32(flag, flag, 1); - tcg_gen_brcond_i32(TCG_COND_EQ, flag, tcg_const_i32(0), l1); + case 7: /* Ordered !A */ + case 23: /* Greater, Less or Equal !A */ + tmp =3D tcg_temp_new(); + tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A); + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1); break; - case 10: /* ugt (>0) */ - tcg_gen_brcond_i32(TCG_COND_GT, flag, tcg_const_i32(0), l1); + case 8: /* Unordered A */ + case 24: /* Not Greater, Less or Equal A */ + tmp =3D tcg_temp_new(); + tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); break; - case 11: /* uge (>=3D0) */ - tcg_gen_brcond_i32(TCG_COND_GE, flag, tcg_const_i32(0), l1); + case 9: /* Unordered or Equal A || Z */ + case 25: /* Not Greater or Less then A || Z */ + tmp =3D tcg_temp_new(); + tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); break; - case 12: /* ult (=3D-1 or =3D2) */ - tcg_gen_brcond_i32(TCG_COND_GEU, flag, tcg_const_i32(2), l1); + case 10: /* Unordered or Greater Than A || !(N || Z)) */ + case 26: /* Not Less or Equal A || !(N || Z)) */ + assert(FPSR_CC_Z =3D=3D (FPSR_CC_N >> 1)); + tmp =3D tcg_temp_new(); + tcg_gen_shli_i32(tmp, QREG_FPSR, 1); + tcg_gen_or_i32(tmp, tmp, QREG_FPSR); + tcg_gen_xori_i32(tmp, tmp, FPSR_CC_N); + tcg_gen_andi_i32(tmp, tmp, FPSR_CC_N | FPSR_CC_A); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + break; + case 11: /* Unordered or Greater or Equal A || Z || !N */ + case 27: /* Not Less Than A || Z || !N */ + tmp =3D tcg_temp_new(); + tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N= ); + tcg_gen_xori_i32(tmp, tmp, FPSR_CC_N); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); break; - case 13: /* ule (!=3D1) */ - tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(1), l1); + case 12: /* Unordered or Less Than A || (N && !Z) */ + case 28: /* Not Greater than or Equal A || (N && !Z) */ + assert(FPSR_CC_Z =3D=3D (FPSR_CC_N >> 1)); + tmp =3D tcg_temp_new(); + tcg_gen_xori_i32(tmp, QREG_FPSR, FPSR_CC_Z); + tcg_gen_shli_i32(tmp, tmp, 1); + tcg_gen_ori_i32(tmp, tmp, FPSR_CC_A); + tcg_gen_and_i32(tmp, tmp, QREG_FPSR); + tcg_gen_andi_i32(tmp, tmp, FPSR_CC_A | FPSR_CC_N); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + break; + case 13: /* Unordered or Less or Equal A || Z || N */ + case 29: /* Not Greater Than A || Z || N */ + tmp =3D tcg_temp_new(); + tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N= ); + tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); break; - case 14: /* ne (!=3D0) */ - tcg_gen_brcond_i32(TCG_COND_NE, flag, tcg_const_i32(0), l1); + case 14: /* Not Equal !Z */ + case 30: /* Signaling Not Equal !Z */ + tmp =3D tcg_temp_new(); + tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_Z); + tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1); break; - case 15: /* t */ + case 15: /* True */ + case 31: /* Signaling True */ tcg_gen_br(l1); break; } @@ -5240,7 +5358,6 @@ void gen_intermediate_code(CPUM68KState *env, Transla= tionBlock *tb) dc->cc_op =3D CC_OP_DYNAMIC; dc->cc_op_synced =3D 1; dc->singlestep_enabled =3D cs->singlestep_enabled; - dc->fpcr =3D env->fpcr; dc->user =3D (env->sr & SR_S) =3D=3D 0; dc->done_mac =3D 0; dc->writeback_mask =3D 0; @@ -5359,6 +5476,38 @@ void m68k_cpu_dump_state(CPUState *cs, FILE *f, fpri= ntf_function cpu_fprintf, cpu_fprintf(f, "SR =3D %04x %c%c%c%c%c ", sr, (sr & CCF_X) ? 'X' : '-', (sr & CCF_N) ? 'N' : '-', (sr & CCF_Z) ? 'Z' : '-', (sr & CCF_V) ? 'V' : '-', (sr & CCF_C) ? 'C' : '-'); + cpu_fprintf(f, "FPSR =3D %08x %c%c%c%c ", env->fpsr, + (env->fpsr & FPSR_CC_A) ? 'A' : '-', + (env->fpsr & FPSR_CC_I) ? 'I' : '-', + (env->fpsr & FPSR_CC_Z) ? 'Z' : '-', + (env->fpsr & FPSR_CC_N) ? 'N' : '-'); + cpu_fprintf(f, "\n " + "FPCR =3D %04x ", env->fpcr); + switch (env->fpcr & FPCR_PREC_MASK) { + case FPCR_PREC_X: + cpu_fprintf(f, "X "); + break; + case FPCR_PREC_S: + cpu_fprintf(f, "S "); + break; + case FPCR_PREC_D: + cpu_fprintf(f, "D "); + break; + } + switch (env->fpcr & FPCR_RND_MASK) { + case FPCR_RND_N: + cpu_fprintf(f, "RN "); + break; + case FPCR_RND_Z: + cpu_fprintf(f, "RZ "); + break; + case FPCR_RND_M: + cpu_fprintf(f, "RM "); + break; + case FPCR_RND_P: + cpu_fprintf(f, "RP "); + break; + } } =20 void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb, --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486430417672559.3165469411133; Mon, 6 Feb 2017 17:20:17 -0800 (PST) Received: from localhost ([::1]:51413 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauS8-0003HH-DP for importer@patchew.org; Mon, 06 Feb 2017 20:20:16 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33142) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau9C-0005IZ-3h for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau97-0006EX-IC for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:40 -0500 Received: from mout.kundenserver.de ([212.227.126.130]:62078) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau97-0006Cz-2P for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:37 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MCuYR-1ck0fR46Xj-009iQC; Tue, 07 Feb 2017 01:59:39 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:21 +0100 Message-Id: <20170207005930.28327-8-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:p9zf99utwjz26q5nbsSggqTXpO7eJjSh1FzbiES+Qg2jGPZ73Vy u+N86bL9+fazL1Ybzg6pOhYBAx2wX9cQ1ABWhWkNC2sRZ9YZsShn4EUndEee09h64+yzRma eXlDKTX3TM2HV4Pr+4xfYSHhlof4ywFMuEwrXR2jXBjyteX2rQ79oiM/sA4OW+gcrXURWsv Mp2HDjiwkhFKkb0cu7q7Q== X-UI-Out-Filterresults: notjunk:1;V01:K0:56evNj0OwPc=:jAhQo3Mk993JPPffDvIiqu KVtRT0EuWiUgYBilQD9sxaFyba0JvkXki4ULDabPLIAo6XsP+/c+wtzfU3Bfn5gR/D/kqaSav SzpunbU7OIhbDBVeo6si/1/fbHe2wNpWsAkkbEszjPZAVh6IHC4VYl3+e4MnAYBcMfLSo6ChX DnbJ5phfOnN0Ycjw5r3/QbEQ+t51V8bMPl262ijt5Yy2Wg0wQEEQUY2AKogsGGDA8Wm603KhB fuhGQgzaV3eU2BNvgjh5LJh5eDN7B3ltGRqxG1rIcPm5zBLgI9tvuONGT1fZryEcfn0jxvrkD ihuZiD41yyLTRTaZuHlmCUyrbuoMMzTW7liXxbTtfTPwJXfsqRUiI/eVXbRxHtdFSf2Kyifzb n1TldpOtbQfMnDHzOdrtj+EQ1kmynH6SlyJGm7PBN9Jiux+qjOIkhky1TqagkTKbqEqJGJ/F6 6uu9Kr1LmNIkMJsOiJTyVA2WAM/IexECjN+SiKDs+8Fnqja49ZcbkPUJ4nRikDelJQk+GeQuM HMXNydw3o0HOgc495QWHdQfECX/xaE4Z8Gi0AKQZwSwH7CQrYAGNxof2qB7ZnX8DPh9nPrp7G OQSx6XDY/7e18VUkL0gIdbO0U77Nj3mU+jURows406bUqfib2KtNlFjy3RNNWcc7c0Ek6q3rD 1tqeKYG46fXtS2eG0xXNnPjEu6unpx4mVDd5PB/EqbfCnwt+URUNzR+7h/XukMiLxnvo= 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 v3 07/16] target-m68k: manage FPU exceptions 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" Signed-off-by: Laurent Vivier --- target/m68k/cpu.h | 28 +++++++++++++ target/m68k/fpu_helper.c | 107 +++++++++++++++++++++++++++++++++++++++++++= +++- target/m68k/helper.h | 1 + target/m68k/translate.c | 27 ++++++++++++ 4 files changed, 162 insertions(+), 1 deletion(-) diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 6b3cb26..7985dc3 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -57,6 +57,15 @@ #define EXCP_TRAP15 47 /* User trap #15. */ #define EXCP_UNSUPPORTED 61 #define EXCP_ICE 13 +#define EXCP_FP_BSUN 48 /* Branch Set on Unordered */ +#define EXCP_FP_INEX 49 /* Inexact result */ +#define EXCP_FP_DZ 50 /* Divide by Zero */ +#define EXCP_FP_UNFL 51 /* Underflow */ +#define EXCP_FP_OPERR 52 /* Operand Error */ +#define EXCP_FP_OVFL 53 /* Overflow */ +#define EXCP_FP_SNAN 54 /* Signaling Not-A-Number */ +#define EXCP_FP_UNIMP 55 /* Unimplemented Data type */ + =20 #define EXCP_RTE 0x100 #define EXCP_HALT_INSN 0x101 @@ -222,6 +231,25 @@ typedef enum { #define FPSR_CC_Z 0x04000000 /* Zero */ #define FPSR_CC_N 0x08000000 /* Negative */ =20 +/* Exception Status */ +#define FPSR_ES_MASK 0x0000ff00 +#define FPSR_ES_BSUN 0x00008000 /* Branch Set on Unordered */ +#define FPSR_ES_SNAN 0x00004000 /* Signaling Not-A-Number */ +#define FPSR_ES_OPERR 0x00002000 /* Operand Error */ +#define FPSR_ES_OVFL 0x00001000 /* Overflow */ +#define FPSR_ES_UNFL 0x00000800 /* Underflow */ +#define FPSR_ES_DZ 0x00000400 /* Divide by Zero */ +#define FPSR_ES_INEX2 0x00000200 /* Inexact operation */ +#define FPSR_ES_INEX 0x00000100 /* Inexact decimal input */ + +/* Accrued Exception */ +#define FPSR_AE_MASK 0x000000ff +#define FPSR_AE_IOP 0x00000080 /* Invalid Operation */ +#define FPSR_AE_OVFL 0x00000040 /* Overflow */ +#define FPSR_AE_UNFL 0x00000020 /* Underflow */ +#define FPSR_AE_DZ 0x00000010 /* Divide by Zero */ +#define FPSR_AE_INEX 0x00000008 /* Inexact */ + /* Quotient */ =20 #define FPSR_QT_MASK 0x00ff0000 diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index 9d39118..1e68c41 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -177,6 +177,70 @@ static void restore_rounding_mode(CPUM68KState *env) } } =20 +static void set_fpsr_exception(CPUM68KState *env) +{ + uint32_t fpsr =3D 0; + int flags; + + flags =3D get_float_exception_flags(&env->fp_status); + if (flags =3D=3D 0) { + return; + } + set_float_exception_flags(0, &env->fp_status); + + if (flags & float_flag_invalid) { + fpsr |=3D FPSR_AE_IOP; + } + if (flags & float_flag_divbyzero) { + fpsr |=3D FPSR_AE_DZ; + } + if (flags & float_flag_overflow) { + fpsr |=3D FPSR_AE_OVFL; + } + if (flags & float_flag_underflow) { + fpsr |=3D FPSR_AE_UNFL; + } + if (flags & float_flag_inexact) { + fpsr |=3D FPSR_AE_INEX; + } + + env->fpsr =3D (env->fpsr & ~FPSR_AE_MASK) | fpsr; +} + +static void fpu_exception(CPUM68KState *env, uint32_t exception) +{ + CPUState *cs =3D CPU(m68k_env_get_cpu(env)); + + env->fpsr =3D (env->fpsr & ~FPSR_ES_MASK) | exception; + if (env->fpcr & exception) { + switch (exception) { + case FPSR_ES_BSUN: + cs->exception_index =3D EXCP_FP_BSUN; + break; + case FPSR_ES_SNAN: + cs->exception_index =3D EXCP_FP_SNAN; + break; + case FPSR_ES_OPERR: + cs->exception_index =3D EXCP_FP_OPERR; + break; + case FPSR_ES_OVFL: + cs->exception_index =3D EXCP_FP_OVFL; + break; + case FPSR_ES_UNFL: + cs->exception_index =3D EXCP_FP_UNFL; + break; + case FPSR_ES_DZ: + cs->exception_index =3D EXCP_FP_DZ; + break; + case FPSR_ES_INEX: + case FPSR_ES_INEX2: + cs->exception_index =3D EXCP_FP_INEX; + break; + } + cpu_loop_exit_restore(cs, GETPC()); + } +} + void cpu_m68k_set_fpcr(CPUM68KState *env, uint32_t val) { env->fpcr =3D val & 0xffff; @@ -292,10 +356,16 @@ void HELPER(cmp_FP0_FP1)(CPUM68KState *env) { floatx80 fp0 =3D FP0_to_floatx80(env); floatx80 fp1 =3D FP1_to_floatx80(env); - int float_compare; + int flags, float_compare; =20 float_compare =3D floatx80_compare(fp1, fp0, &env->fp_status); env->fpsr =3D (env->fpsr & ~FPSR_CC_MASK) | float_comp_to_cc(float_com= pare); + + flags =3D get_float_exception_flags(&env->fp_status); + if (flags & float_flag_invalid) { + fpu_exception(env, FPSR_ES_OPERR); + } + set_fpsr_exception(env); } =20 void HELPER(tst_FP0)(CPUM68KState *env) @@ -315,4 +385,39 @@ void HELPER(tst_FP0)(CPUM68KState *env) fpsr |=3D FPSR_CC_Z; } env->fpsr =3D (env->fpsr & ~FPSR_CC_MASK) | fpsr; + + set_fpsr_exception(env); +} + +void HELPER(update_fpstatus)(CPUM68KState *env) +{ + int flags =3D get_float_exception_flags(&env->fp_status); + + if (env->fpsr & FPSR_AE_IOP) { + flags |=3D float_flag_invalid; + } else { + flags &=3D ~float_flag_invalid; + } + if (env->fpsr & FPSR_AE_DZ) { + flags |=3D float_flag_divbyzero; + } else { + flags &=3D ~float_flag_divbyzero; + } + if (env->fpsr & FPSR_AE_OVFL) { + flags |=3D float_flag_overflow; + } else { + flags &=3D ~float_flag_overflow; + } + if (env->fpsr & FPSR_AE_UNFL) { + flags |=3D float_flag_underflow; + } else { + flags &=3D ~float_flag_underflow; + } + if (env->fpsr & FPSR_AE_INEX) { + flags |=3D float_flag_inexact; + } else { + flags &=3D ~float_flag_inexact; + } + + set_float_exception_flags(flags, &env->fp_status); } diff --git a/target/m68k/helper.h b/target/m68k/helper.h index 03fb268..072a6d0 100644 --- a/target/m68k/helper.h +++ b/target/m68k/helper.h @@ -30,6 +30,7 @@ DEF_HELPER_1(div_FP0_FP1, void, env) DEF_HELPER_1(cmp_FP0_FP1, void, env) DEF_HELPER_2(set_fpcr, void, env, i32) DEF_HELPER_1(tst_FP0, void, env) +DEF_HELPER_1(update_fpstatus, void, env) =20 DEF_HELPER_3(mac_move, void, env, i32, i32) DEF_HELPER_3(macmulf, i64, env, i32, i32) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index cce8a8f..f9c64ff 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -4388,6 +4388,7 @@ static void gen_load_fcr(DisasContext *s, TCGv addr, = int reg) switch (reg) { case 0: /* FPSR */ tcg_gen_qemu_ld32u(QEMU_FPSR, addr, index); + gen_helper_update_fpstatus(cpu_env); break; case 1: /* FPIAR */ break; @@ -4431,6 +4432,7 @@ static void gen_op_fmove_fcr(CPUM68KState *env, Disas= Context *s, case 2: /* FPSR */ SRC_EA(env, val, OS_LONG, 0, NULL); tcg_gen_mov_i32(QEMU_FPSR, val); + gen_helper_update_fpstatus(cpu_env); break; case 4: /* FPCR */ SRC_EA(env, val, OS_LONG, 0, NULL); @@ -5481,6 +5483,21 @@ void m68k_cpu_dump_state(CPUState *cs, FILE *f, fpri= ntf_function cpu_fprintf, (env->fpsr & FPSR_CC_I) ? 'I' : '-', (env->fpsr & FPSR_CC_Z) ? 'Z' : '-', (env->fpsr & FPSR_CC_N) ? 'N' : '-'); + cpu_fprintf(f, "%c%c%c%c%c%c%c%c ", + (env->fpsr & FPSR_ES_BSUN) ? 'B' : '-', + (env->fpsr & FPSR_ES_SNAN) ? 'A' : '-', + (env->fpsr & FPSR_ES_OPERR) ? 'O' : '-', + (env->fpsr & FPSR_ES_OVFL) ? 'V' : '-', + (env->fpsr & FPSR_ES_UNFL) ? 'U' : '-', + (env->fpsr & FPSR_ES_DZ) ? 'Z' : '-', + (env->fpsr & FPSR_ES_INEX2) ? '2' : '-', + (env->fpcr & FPSR_ES_INEX) ? 'I' : '-'); + cpu_fprintf(f, "%c%c%c%c%c", + (env->fpsr & FPSR_AE_IOP) ? 'O' : '-', + (env->fpsr & FPSR_AE_OVFL) ? 'V' : '-', + (env->fpsr & FPSR_AE_UNFL) ? 'U' : '-', + (env->fpsr & FPSR_AE_DZ) ? 'Z' : '-', + (env->fpcr & FPSR_ES_INEX) ? 'I' : '-'); cpu_fprintf(f, "\n " "FPCR =3D %04x ", env->fpcr); switch (env->fpcr & FPCR_PREC_MASK) { @@ -5508,6 +5525,16 @@ void m68k_cpu_dump_state(CPUState *cs, FILE *f, fpri= ntf_function cpu_fprintf, cpu_fprintf(f, "RP "); break; } + /* FPCR exception mask uses the same bitmask as FPSR */ + cpu_fprintf(f, "%c%c%c%c%c%c%c%c\n", + (env->fpcr & FPSR_ES_BSUN) ? 'B' : '-', + (env->fpcr & FPSR_ES_SNAN) ? 'A' : '-', + (env->fpcr & FPSR_ES_OPERR) ? 'O' : '-', + (env->fpcr & FPSR_ES_OVFL) ? 'V' : '-', + (env->fpcr & FPSR_ES_UNFL) ? 'U' : '-', + (env->fpcr & FPSR_ES_DZ) ? 'Z' : '-', + (env->fpcr & FPSR_ES_INEX2) ? '2' : '-', + (env->fpcr & FPSR_ES_INEX) ? 'I' : '-'); } =20 void restore_state_to_opc(CPUM68KState *env, TranslationBlock *tb, --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486429414947360.92539960942577; Mon, 6 Feb 2017 17:03:34 -0800 (PST) Received: from localhost ([::1]:51332 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauBx-00071U-Hf for importer@patchew.org; Mon, 06 Feb 2017 20:03:33 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32991) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau8v-00056f-5S for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau8q-00068A-9P for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:25 -0500 Received: from mout.kundenserver.de ([212.227.126.134]:64342) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau8p-00067h-VS for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:20 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0Me7fW-1cnb9h2YvO-00PtJF; Tue, 07 Feb 2017 01:59:39 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:22 +0100 Message-Id: <20170207005930.28327-9-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:jNkrmYUFS9zXV8hSOhkTO3n1+7rmNg1ALy0OKIG+fdXZu0tFDLl Tb6iuGJlUYc0M0sCr+YZkrLSCNci+R2HL0g5KWOA2F9uO5MvS0GDtJTe/NMyGmMlwYAEqKO fIWaPTlo0CwmNZzaVhZR3R+B5r3VbI5FB2VVUNw/IqQwEWNQLm2Kvka77XYjEWe4kC3tukG CW943D4WpD3TjIeoxSFew== X-UI-Out-Filterresults: notjunk:1;V01:K0:cqauzoNeI+o=:w8qU8jzlzHSpVY72/f/xaD Sm5Jwu+gu9O/62YEb976YcIGQSi3sCHONYkofeFiRtcT83oznIJytYkILZcVySixsCnUi6wQy j3KJVtCnHG9vHyhmjrs+OYS6jMI5kpqdXfJFA8hcqa6UZ1HWhbvq6Ndftll5i4LIUB2ApnhD5 hWRU/4/WOJTk34iKuBFD7wbc1awMS6u13SURPIpjSXtNbRmeDrxghKfPTsMhE5Ys82P925Nef kItyTFSaSxVaQB7LUGLtg88faHxN/AF9CpE9tc4wILNvhIg2pd9Qkk5vok80tquLu7xiMG4v+ q+jZ/8X40Pv01QTG1ZrnUUsWxM0NLce2fe32Bs0wJPlwQtP0Q9czxD8jF39axPAQ35XOcVTe4 X9mNOXDgWb9MtmGDZyfDu0RLl6e2PquhWZYOloB/3xyih2cXgRW3Axhe4qxpl45YsdMVD19IO 8a5N5tREIsaas9VvyKVjfl98VOuVwRcCK5lxjUiTZSdZxPN8pNJGx/FDLoU4mbKG61sNpNjUr KEjh5hsurDMxvKl/CuR4FOmixGkPlcGZ8A2BcvuTLJMBc68dZnSzuoZNetOBG29JtH9Cu7qMM X4AAd20MpQQievXXNWBL8FXV+aa4XVwNsfj8t0PoOpeQhUot9193a34F72/W+UC7dNBuDBnnc lspAWVN5iRPET27mNJ17ki2t4n5Od87PSA7beXlfNxDWsnAALkRvq3TQ7BSbl9sM4Fl4= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.134 Subject: [Qemu-devel] [PATCH v3 08/16] target-m68k: define 96bit FP registers for gdb on 680x0 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson --- configure | 2 +- gdb-xml/m68k-fp.xml | 21 +++++++++++++++++++++ target/m68k/helper.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 gdb-xml/m68k-fp.xml diff --git a/configure b/configure index 86fd833..4373ec5 100755 --- a/configure +++ b/configure @@ -5912,7 +5912,7 @@ case "$target_name" in ;; m68k) bflt=3D"yes" - gdb_xml_files=3D"cf-core.xml cf-fp.xml" + gdb_xml_files=3D"cf-core.xml cf-fp.xml m68k-fp.xml" ;; microblaze|microblazeel) TARGET_ARCH=3Dmicroblaze diff --git a/gdb-xml/m68k-fp.xml b/gdb-xml/m68k-fp.xml new file mode 100644 index 0000000..64290d1 --- /dev/null +++ b/gdb-xml/m68k-fp.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + , + + diff --git a/target/m68k/helper.c b/target/m68k/helper.c index cff93dc..d93fad9 100644 --- a/target/m68k/helper.c +++ b/target/m68k/helper.c @@ -114,6 +114,48 @@ static int cf_fpu_gdb_set_reg(CPUM68KState *env, uint8= _t *mem_buf, int n) return 0; } =20 +static int m68k_fpu_gdb_get_reg(CPUM68KState *env, uint8_t *mem_buf, int n) +{ + if (n < 8) { + stw_be_p(mem_buf, env->fregs[n].l.upper); + memset(mem_buf + 2, 0, 2); + stq_be_p(mem_buf + 4, env->fregs[n].l.lower); + return 12; + } + switch (n) { + case 8: /* fpcontrol */ + stl_be_p(mem_buf, env->fpcr); + return 4; + case 9: /* fpstatus */ + stl_be_p(mem_buf, env->fpsr); + return 4; + case 10: /* fpiar, not implemented */ + memset(mem_buf, 0, 4); + return 4; + } + return 0; +} + +static int m68k_fpu_gdb_set_reg(CPUM68KState *env, uint8_t *mem_buf, int n) +{ + if (n < 8) { + env->fregs[n].l.upper =3D lduw_be_p(mem_buf); + env->fregs[n].l.lower =3D ldq_be_p(mem_buf + 4); + return 12; + } + switch (n) { + case 8: /* fpcontrol */ + env->fpcr =3D ldl_p(mem_buf); + return 4; + case 9: /* fpstatus */ + env->fpsr =3D ldl_p(mem_buf); + return 4; + case 10: /* fpiar, not implemented */ + return 4; + } + return 0; +} + M68kCPU *cpu_m68k_init(const char *cpu_model) { M68kCPU *cpu; @@ -142,6 +184,9 @@ void m68k_cpu_init_gdb(M68kCPU *cpu) if (m68k_feature(env, M68K_FEATURE_CF_FPU)) { gdb_register_coprocessor(cs, cf_fpu_gdb_get_reg, cf_fpu_gdb_set_re= g, 11, "cf-fp.xml", 18); + } else if (m68k_feature(env, M68K_FEATURE_FPU)) { + gdb_register_coprocessor(cs, m68k_fpu_gdb_get_reg, + m68k_fpu_gdb_set_reg, 11, "m68k-fp.xml", = 18); } /* TODO: Add [E]MAC registers. */ } --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486429633804135.94235588724587; Mon, 6 Feb 2017 17:07:13 -0800 (PST) Received: from localhost ([::1]:51351 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauFT-0001Mw-Fz for importer@patchew.org; Mon, 06 Feb 2017 20:07:11 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33084) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau95-0005E3-Rb for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau90-0006BT-Vc for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:35 -0500 Received: from mout.kundenserver.de ([212.227.126.134]:52800) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau90-0006As-JQ for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:30 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MP3ch-1cXrad0bxv-006QeC; Tue, 07 Feb 2017 01:59:40 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:23 +0100 Message-Id: <20170207005930.28327-10-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:t4bxdVULYW+vO4ebKxxwNp78eoxJHdJu/H5glUwrvRCH4GFyf/C w5zpoXX49jOX/8Ul+IhBEeMPYrQUIsnSMpycUGX2WRYjq9zyKpTaea64HOv/of6oU83wUZ2 Ob9cp0ibIadRdzNCdoN3/yvSdEli7caZWHPFtIfuXyvcC7xNKla0lR/AukrPj8dH9F/Ys2X uQ5r8UIXHCjvFB4lfUOow== X-UI-Out-Filterresults: notjunk:1;V01:K0:kpqe6iR3Cm8=:ReR3wHP65yIENOQV40YsZM C9dPnL88RLmeWaDvSEUHTcJt5DxV97bnjFHtTEL9saOobCcJ9pxzvstDSk+bgWxlmcPmvKE1n sP1LfuNwFBrXxamx0xW/9vFsKm6EkrjYZbzUsTcRiYjV3H8qG9Nx4pLHwvy4MU86ykRBWikTW 2aikSaBOx7Od/wNWqB0cnqfy7Q713SK2L0bxyLpWDHoEcjEmN/klMi4AZw1lQz0YoSzaHIIuF 80Djo2YR/IeY85v9A1vpcoe6mGQ8lKRDExPxefUyUktIBEhBsOeKN7wUvyu83fzg+OyIwl8nK K3gTlJKdbYsat501cWWq6ftU2SsiLPqtKyfOaSvu4rQ4/ZM0YTwiLM+sPsVZYE0K4FXIWmMJh wdiHVt/PtDiUr1n5hhT2378F/5uAHZD5O8pbHxPuvY8LPx5DltvBSI4aoeKMMirBQznzDZzpG hRO0vVLvwT4BjMy1r9eSGqo3sWBfNQ/aNiuCeuYvUWI7KpTQRb2mNtex5mhd0mayyF8rlyJQT Kq5Ts1XASud1bgOCs4Jnl0D5RYzyCzSMUSxu/K8cBxituJHbUEpu8zrS0UxHTq0/jb2IC8FH5 kGi9u5EM5za0MLvTXd9QU3MxWRacleymweQhonG5TeuIk3uFxhrcYNPNJQGFTOmZZihMd899t CEDMZ7IqqATkHLvvr2HsmUI1ZmGQWqOEvfZKYunVXgwadgAjWsD+iXNsRjP+k9y8d+SQ= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.134 Subject: [Qemu-devel] [PATCH v3 09/16] target-m68k: add fmovem 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" Signed-off-by: Laurent Vivier --- target/m68k/fpu_helper.c | 6 +++ target/m68k/helper.h | 1 + target/m68k/translate.c | 99 +++++++++++++++++++++++++++++++++++---------= ---- 3 files changed, 80 insertions(+), 26 deletions(-) diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index 1e68c41..aadfc82 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -421,3 +421,9 @@ void HELPER(update_fpstatus)(CPUM68KState *env) =20 set_float_exception_flags(flags, &env->fp_status); } + +void HELPER(fmovem)(CPUM68KState *env, uint32_t opsize, + uint32_t mode, uint32_t mask) +{ + fprintf(stderr, "MISSING HELPER fmovem\n"); +} diff --git a/target/m68k/helper.h b/target/m68k/helper.h index 072a6d0..58bc273 100644 --- a/target/m68k/helper.h +++ b/target/m68k/helper.h @@ -31,6 +31,7 @@ DEF_HELPER_1(cmp_FP0_FP1, void, env) DEF_HELPER_2(set_fpcr, void, env, i32) DEF_HELPER_1(tst_FP0, void, env) DEF_HELPER_1(update_fpstatus, void, env) +DEF_HELPER_4(fmovem, void, env, i32, i32, i32) =20 DEF_HELPER_3(mac_move, void, env, i32, i32) DEF_HELPER_3(macmulf, i64, env, i32, i32) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index f9c64ff..ac60f1a 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -4483,13 +4483,79 @@ static void gen_op_fmove_fcr(CPUM68KState *env, Dis= asContext *s, tcg_temp_free_i32(addr); } =20 +static void gen_op_fmovem(CPUM68KState *env, DisasContext *s, + uint32_t insn, uint32_t ext) +{ + int opsize; + uint16_t mask; + int i; + uint32_t mode; + int32_t incr; + TCGv addr, tmp; + int is_load; + + if (m68k_feature(s->env, M68K_FEATURE_FPU)) { + opsize =3D OS_EXTENDED; + } else { + opsize =3D OS_DOUBLE; /* FIXME */ + } + + mode =3D (ext >> 11) & 0x3; + if ((mode & 0x1) =3D=3D 1) { + gen_helper_fmovem(cpu_env, tcg_const_i32(opsize), + tcg_const_i32(mode), DREG(ext, 0)); + return; + } + + tmp =3D gen_lea(env, s, insn, opsize); + if (IS_NULL_QREG(tmp)) { + gen_addr_fault(s); + return; + } + + addr =3D tcg_temp_new(); + tcg_gen_mov_i32(addr, tmp); + is_load =3D ((ext & 0x2000) =3D=3D 0); + incr =3D opsize_bytes(opsize); + mask =3D ext & 0x00FF; + + if (!is_load && (mode & 2) =3D=3D 0) { + for (i =3D 7; i >=3D 0; i--, mask <<=3D 1) { + if (mask & 0x80) { + gen_op_load_fpr_FP0(i); + gen_store_FP0(s, opsize, addr); + if ((mask & 0xff) !=3D 0x80) { + tcg_gen_subi_i32(addr, addr, incr); + } + } + } + tcg_gen_mov_i32(AREG(insn, 0), addr); + } else { + for (i =3D 0; i < 8; i++, mask <<=3D 1) { + if (mask & 0x80) { + if (is_load) { + gen_load_FP0(s, opsize, addr); + gen_op_store_fpr_FP0(i); + } else { + gen_op_load_fpr_FP0(i); + gen_store_FP0(s, opsize, addr); + } + tcg_gen_addi_i32(addr, addr, incr); + } + } + if ((insn & 070) =3D=3D 030) { + tcg_gen_mov_i32(AREG(insn, 0), addr); + } + } + tcg_temp_free_i32(addr); +} + /* ??? FP exceptions are not implemented. Most exceptions are deferred un= til immediately before the next FP instruction is executed. */ DISAS_INSN(fpu) { uint16_t ext; int opmode; - TCGv tmp32; int opsize; =20 ext =3D read_im16(env, s); @@ -4514,32 +4580,13 @@ DISAS_INSN(fpu) return; case 6: /* fmovem */ case 7: - { - TCGv addr; - uint16_t mask; - int i; - if ((ext & 0x1f00) !=3D 0x1000 || (ext & 0xff) =3D=3D 0) - goto undef; - tmp32 =3D gen_lea(env, s, insn, OS_LONG); - if (IS_NULL_QREG(tmp32)) { - gen_addr_fault(s); - return; - } - addr =3D tcg_temp_new_i32(); - tcg_gen_mov_i32(addr, tmp32); - mask =3D 0x80; - for (i =3D 0; i < 8; i++) { - if (ext & mask) { - gen_op_load_fpr_FP0(REG(i, 0)); - gen_ldst_FP0(s, OS_DOUBLE, addr, (ext & (1 << 13)) ? - EA_STORE : EA_LOADS); - if (ext & (mask - 1)) - tcg_gen_addi_i32(addr, addr, 8); - } - mask >>=3D 1; - } - tcg_temp_free_i32(addr); + if ((ext & 0xf00) !=3D 0 || (ext & 0xff) =3D=3D 0) { + goto undef; + } + if ((ext & 0x1000) =3D=3D 0 && !m68k_feature(s->env, M68K_FEATURE_= FPU)) { + goto undef; } + gen_op_fmovem(env, s, insn, ext); return; } if (ext & (1 << 14)) { --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486430217482712.6447059744339; Mon, 6 Feb 2017 17:16:57 -0800 (PST) Received: from localhost ([::1]:51399 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauOu-0000gS-4R for importer@patchew.org; Mon, 06 Feb 2017 20:16:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33157) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau9C-0005Ig-90 for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau96-0006EK-QZ for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:42 -0500 Received: from mout.kundenserver.de ([212.227.126.134]:56688) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau96-0006Ck-Fb for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:36 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MFfhh-1cg9JR2qUn-00Ee6o; Tue, 07 Feb 2017 01:59:41 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:24 +0100 Message-Id: <20170207005930.28327-11-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Provags-ID: V03:K0:IbnpwA8MVdDPqZSvJ8IcRXM+QhZtRraG0GgojQj0gjvTm4KSDo0 HvP/SWBrXNQLMzmNlYxt7wbfiDOsW1QacmaIgraoRlpjoFtJMKeu7a//VrtkmZsIzYKknQv CvrFUgFrfYw+hCUDjZ49E83ib8KLNoAJXHnyN6yVN5Q09m3LJjVgpZAhqeRZZj0JYoi/QJN UFHl0jxwdVMwji56b0CVw== X-UI-Out-Filterresults: notjunk:1;V01:K0:Dm9nZ+5vvOo=:FedfMFaPxHF12XnCu97SDP AGOBCSjlpPTL53MYLU1+U+zhM1PF04m3OMT0CNTmg09rXCU5Z681wnyYuJDF/wH9VMhjNHBaU SbiXGEE8jLfDo6NX7TrcdWRsNjFHr12yjV/HoNP7iEXdohDyw4kzpgQ+7tQAx2No1GRqvFGsW 4n4sKdY8C0n9O94dHH1ZLiAIDdVfKDvT2J2eO21PArO0mTXakmh79wmk4V5VZTacKW6zSdgCZ VtpUt4X+hYVoCWXP35dkB90TZR53beh3zFzP7vyfLOURkh5qyJyu7/gJV/PHoR5fqLQHwCR2F wsVq140vfZr1VEEykx4+cpxJQj6qvOVA5Twt+VCJiJxzOhc65X6py3h+0GheugmWzo5F1/TlL zbCzfmTJdD5PSuuuFam2+NFIvq/EHM3hIs91HmEQQygZdZPQjkplQXEYEVU2c57X9ippAUCcX gOmXD9EoO/Rybc9kq/U49UCLVs7kV4mhCedCK2LgMktlh0TpMi5O/Ys2D/cUhlTyglN/uGocc 4qj7q403g3+ZQVRntQ/AAuBjNhvgHz+NIM/FLkp2hqoZtRS9YpP9eCIaoLPR6k8a9ZbJjweri x0XHUWZblfCJtb4tEX/aoMNmWVLTM/WBwEa/3nzvB3Sc5hHPAqlb3QJRzTnD1qTiEKbRcTGUL 3UrmMWFw5hANQ/KK4zq5kz5NSFwSqQsYJ3rlGYRIdFXo/g37Qwuf6SIEhf0DMOaKS3x+3TKuk YCUWaz+sCc8JLD0p X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.134 Subject: [Qemu-devel] [PATCH v3 10/16] target-m68k: add fscc. 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: Laurent Vivier , Aurelien Jarno , Richard Henderson Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 use DisasCompare with FPU conditions in fscc and fbcc. Signed-off-by: Laurent Vivier --- target/m68k/translate.c | 228 ++++++++++++++++++++++++++++++++------------= ---- 1 file changed, 153 insertions(+), 75 deletions(-) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index ac60f1a..3fdb672 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -4654,139 +4654,215 @@ undef: disas_undef_fpu(env, s, insn); } =20 -DISAS_INSN(fbcc) +static void gen_fcc_cond(DisasCompare *c, DisasContext *s, int cond) { - uint32_t offset; - uint32_t addr; - TCGLabel *l1; - TCGv tmp; - - addr =3D s->pc; - offset =3D cpu_ldsw_code(env, s->pc); - s->pc +=3D 2; - if (insn & (1 << 6)) { - offset =3D (offset << 16) | read_im16(env, s); - } - - l1 =3D gen_new_label(); + c->g1 =3D 0; + c->v2 =3D tcg_const_i32(0); + c->g2 =3D 1; /* TODO: Raise BSUN exception. */ - /* Jump to l1 if condition is true. */ - switch (insn & 0x3f) { + switch (cond) { case 0: /* False */ case 16: /* Signaling False */ + c->v1 =3D c->v2; + c->tcond =3D TCG_COND_NEVER; break; case 1: /* EQual Z */ case 17: /* Signaling EQual Z */ - tmp =3D tcg_temp_new(); - tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_Z); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_andi_i32(c->v1, QREG_FPSR, FPSR_CC_Z); + c->tcond =3D TCG_COND_NE; break; case 2: /* Ordered Greater Than !(A || Z || N) */ case 18: /* Greater Than !(A || Z || N) */ - tmp =3D tcg_temp_new(); - tcg_gen_andi_i32(tmp, QREG_FPSR, + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_andi_i32(c->v1, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1); + c->tcond =3D TCG_COND_EQ; break; case 3: /* Ordered Greater than or Equal Z || !(A || N) */ case 19: /* Greater than or Equal Z || !(A || N) */ assert(FPSR_CC_A =3D=3D (FPSR_CC_N >> 3)); - tmp =3D tcg_temp_new(); - tcg_gen_shli_i32(tmp, QREG_FPSR, 3); - tcg_gen_or_i32(tmp, tmp, QREG_FPSR); - tcg_gen_xori_i32(tmp, tmp, FPSR_CC_N); - tcg_gen_andi_i32(tmp, tmp, FPSR_CC_N | FPSR_CC_Z); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_shli_i32(c->v1, QREG_FPSR, 3); + tcg_gen_or_i32(c->v1, c->v1, QREG_FPSR); + tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N); + tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_Z); + c->tcond =3D TCG_COND_NE; break; case 4: /* Ordered Less Than !(!N || A || Z); */ case 20: /* Less Than !(!N || A || Z); */ - tmp =3D tcg_temp_new(); - tcg_gen_xori_i32(tmp, QREG_FPSR, FPSR_CC_N); - tcg_gen_andi_i32(tmp, tmp, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_xori_i32(c->v1, QREG_FPSR, FPSR_CC_N); + tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_A | FPSR_CC_Z); + c->tcond =3D TCG_COND_EQ; break; case 5: /* Ordered Less than or Equal Z || (N && !A) */ case 21: /* Less than or Equal Z || (N && !A) */ assert(FPSR_CC_A =3D=3D (FPSR_CC_N >> 3)); - tmp =3D tcg_temp_new(); - tcg_gen_xori_i32(tmp, QREG_FPSR, FPSR_CC_A); - tcg_gen_shli_i32(tmp, tmp, 3); - tcg_gen_ori_i32(tmp, tmp, FPSR_CC_Z); - tcg_gen_and_i32(tmp, tmp, QREG_FPSR); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_xori_i32(c->v1, QREG_FPSR, FPSR_CC_A); + tcg_gen_shli_i32(c->v1, c->v1, 3); + tcg_gen_ori_i32(c->v1, c->v1, FPSR_CC_Z); + tcg_gen_and_i32(c->v1, c->v1, QREG_FPSR); + c->tcond =3D TCG_COND_NE; break; case 6: /* Ordered Greater or Less than !(A ||=C2=A0Z) */ case 22: /* Greater or Less than !(A ||=C2=A0Z) */ - tmp =3D tcg_temp_new(); - tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_andi_i32(c->v1, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z); + c->tcond =3D TCG_COND_EQ; break; case 7: /* Ordered !A */ case 23: /* Greater, Less or Equal !A */ - tmp =3D tcg_temp_new(); - tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_andi_i32(c->v1, QREG_FPSR, FPSR_CC_A); + c->tcond =3D TCG_COND_EQ; break; case 8: /* Unordered A */ case 24: /* Not Greater, Less or Equal A */ - tmp =3D tcg_temp_new(); - tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_andi_i32(c->v1, QREG_FPSR, FPSR_CC_A); + c->tcond =3D TCG_COND_NE; break; case 9: /* Unordered or Equal A || Z */ case 25: /* Not Greater or Less then A || Z */ - tmp =3D tcg_temp_new(); - tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_andi_i32(c->v1, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z); + c->tcond =3D TCG_COND_NE; break; case 10: /* Unordered or Greater Than A || !(N || Z)) */ case 26: /* Not Less or Equal A || !(N || Z)) */ assert(FPSR_CC_Z =3D=3D (FPSR_CC_N >> 1)); - tmp =3D tcg_temp_new(); - tcg_gen_shli_i32(tmp, QREG_FPSR, 1); - tcg_gen_or_i32(tmp, tmp, QREG_FPSR); - tcg_gen_xori_i32(tmp, tmp, FPSR_CC_N); - tcg_gen_andi_i32(tmp, tmp, FPSR_CC_N | FPSR_CC_A); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_shli_i32(c->v1, QREG_FPSR, 1); + tcg_gen_or_i32(c->v1, c->v1, QREG_FPSR); + tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N); + tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_N | FPSR_CC_A); + c->tcond =3D TCG_COND_NE; break; case 11: /* Unordered or Greater or Equal A || Z || !N */ case 27: /* Not Less Than A || Z || !N */ - tmp =3D tcg_temp_new(); - tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N= ); - tcg_gen_xori_i32(tmp, tmp, FPSR_CC_N); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_andi_i32(c->v1, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z | FPSR_CC= _N); + tcg_gen_xori_i32(c->v1, c->v1, FPSR_CC_N); + c->tcond =3D TCG_COND_NE; break; case 12: /* Unordered or Less Than A || (N && !Z) */ case 28: /* Not Greater than or Equal A || (N && !Z) */ assert(FPSR_CC_Z =3D=3D (FPSR_CC_N >> 1)); - tmp =3D tcg_temp_new(); - tcg_gen_xori_i32(tmp, QREG_FPSR, FPSR_CC_Z); - tcg_gen_shli_i32(tmp, tmp, 1); - tcg_gen_ori_i32(tmp, tmp, FPSR_CC_A); - tcg_gen_and_i32(tmp, tmp, QREG_FPSR); - tcg_gen_andi_i32(tmp, tmp, FPSR_CC_A | FPSR_CC_N); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_xori_i32(c->v1, QREG_FPSR, FPSR_CC_Z); + tcg_gen_shli_i32(c->v1, c->v1, 1); + tcg_gen_ori_i32(c->v1, c->v1, FPSR_CC_A); + tcg_gen_and_i32(c->v1, c->v1, QREG_FPSR); + tcg_gen_andi_i32(c->v1, c->v1, FPSR_CC_A | FPSR_CC_N); + c->tcond =3D TCG_COND_NE; break; case 13: /* Unordered or Less or Equal A || Z || N */ case 29: /* Not Greater Than A || Z || N */ - tmp =3D tcg_temp_new(); - tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z | FPSR_CC_N= ); - tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_andi_i32(c->v1, QREG_FPSR, FPSR_CC_A | FPSR_CC_Z | FPSR_CC= _N); + c->tcond =3D TCG_COND_NE; break; case 14: /* Not Equal !Z */ case 30: /* Signaling Not Equal !Z */ - tmp =3D tcg_temp_new(); - tcg_gen_andi_i32(tmp, QREG_FPSR, FPSR_CC_Z); - tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, l1); + c->v1 =3D tcg_temp_new(); + c->g1 =3D 1; + tcg_gen_andi_i32(c->v1, QREG_FPSR, FPSR_CC_Z); + c->tcond =3D TCG_COND_EQ; break; case 15: /* True */ case 31: /* Signaling True */ - tcg_gen_br(l1); + c->v1 =3D c->v2; + c->tcond =3D TCG_COND_ALWAYS; break; } +} + +static void gen_fjmpcc(DisasContext *s, int cond, TCGLabel *l1) +{ + DisasCompare c; + + gen_fcc_cond(&c, s, cond); + tcg_gen_brcond_i32(c.tcond, c.v1, c.v2, l1); + free_cond(&c); +} + +DISAS_INSN(fbcc) +{ + uint32_t offset; + uint32_t base; + TCGLabel *l1; + + base =3D s->pc; + offset =3D (int16_t)read_im16(env, s); + if (insn & (1 << 6)) { + offset =3D (offset << 16) | read_im16(env, s); + } + + l1 =3D gen_new_label(); + update_cc_op(s); + gen_fjmpcc(s, insn & 0x3f, l1); gen_jmp_tb(s, 0, s->pc); gen_set_label(l1); - gen_jmp_tb(s, 1, addr + offset); + gen_jmp_tb(s, 1, base + offset); +} + +DISAS_INSN(fscc_mem) +{ + TCGLabel *l1, *l2; + TCGv taddr; + TCGv addr; + uint16_t ext; + + ext =3D read_im16(env, s); + + taddr =3D gen_lea(env, s, insn, OS_BYTE); + if (IS_NULL_QREG(taddr)) { + gen_addr_fault(s); + return; + } + addr =3D tcg_temp_local_new(); + tcg_gen_mov_i32(addr, taddr); + l1 =3D gen_new_label(); + l2 =3D gen_new_label(); + gen_fjmpcc(s, ext & 0x3f, l1); + gen_store(s, OS_BYTE, addr, tcg_const_i32(0x00)); + tcg_gen_br(l2); + gen_set_label(l1); + gen_store(s, OS_BYTE, addr, tcg_const_i32(0xff)); + gen_set_label(l2); + tcg_temp_free(addr); +} + +DISAS_INSN(fscc_reg) +{ + TCGLabel *l1; + TCGv reg; + uint16_t ext; + + ext =3D read_im16(env, s); + + reg =3D DREG(insn, 0); + + l1 =3D gen_new_label(); + tcg_gen_ori_i32(reg, reg, 0x000000ff); + gen_fjmpcc(s, ext & 0x3f, l1); + tcg_gen_andi_i32(reg, reg, 0xffffff00); + gen_set_label(l1); } =20 DISAS_INSN(frestore) @@ -5366,6 +5442,8 @@ void register_m68k_insns (CPUM68KState *env) INSN(frestore, f340, ffc0, CF_FPU); INSN(fsave, f300, ffc0, CF_FPU); INSN(fpu, f200, ffc0, FPU); + INSN(fscc_mem, f240, ffc0, FPU); + INSN(fscc_reg, f240, fff8, FPU); INSN(fbcc, f280, ff80, FPU); INSN(frestore, f340, ffc0, FPU); INSN(fsave, f300, ffc0, FPU); --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486429884415843.5924944604405; Mon, 6 Feb 2017 17:11:24 -0800 (PST) Received: from localhost ([::1]:51374 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauJX-00057v-2j for importer@patchew.org; Mon, 06 Feb 2017 20:11:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33083) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau95-0005E2-RJ for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:37 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau91-0006Bd-Hu for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:35 -0500 Received: from mout.kundenserver.de ([212.227.126.134]:61872) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau91-0006BA-6J for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:31 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0M6AQg-1cDQvP1ePq-00y889; Tue, 07 Feb 2017 01:59:41 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:25 +0100 Message-Id: <20170207005930.28327-12-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:gwBc78xZ0DvYsGPPZqJAkUHXqLTUFMIhVt76wLzzp9cxWs8IkhF BKqFVXbeziznf9d/UzATudBWxwL5ryba4n0RNq1cizP0OeO+1BAH8p4YajQHrZKe2R8dtw5 I3aiX3wwGM3Y99cXy5ClGWyWn5TWmKOnYobX2Zy5gsN91GhZV4VAnnyZiKULPDZlA9Kydlm JtbZuzHy6IGQxQPrKRfQQ== X-UI-Out-Filterresults: notjunk:1;V01:K0:VImX7yO1WBQ=:Jc0kYPwbNltC02rmK5NTFL dQOH8UVx5dVxRdksYchCYoXtM4ztt/AwEDE4OifnyU3SRne8ze8bZKd8D1OBwz9vnetMt/fOM m4YeJddwdzD9ZVXBXES2HOyr41xx5jhT3lxgYANuQEwWWL+7oOUci/ryzsZLGzG/EeLCWERog +uwTKUz2T8ICDeXGjOk0+e/zwL+wKaVrKjl5zw/OIaA/pFVcEQfhl9NZ4l81pC1Y8zMYQWULE 0EasNhkOuliuDU+AAfazO3+6SC4pqFcg00V2ejS5cwr4alk+JtZ/tkAUMuRAeLCb/QZEBsMI5 /OtOCy05YU433C/vsCN39W3HnWrXWaAuWbw5QK8tG5Os/UFIXMxdKCYJg5PRlobk7BzaTP76r ni7RPaNS2uhwjfV6vf1tMc6G1tGjQPMKDZhsVHpHA15XGEtX0ij4u3pWa0US7KejBHsm7GQDW BppXrN/itQJbePG3RZUvyQcxYGBu9RHA/P3kB6M6PSM3wXFBxNmgQ66bE7L9Sl0qFcHwU+ycF mrDLAwWnwHfCpsWToVBTdfWe17q5Nn2GMmc9V9HIA0/S2FBrm+EZr07/2Ll3vGrNd8CKl4Nck aWwUkyGnkcYd/a7pdvFACOvL6fOOA5kPLRnG42o+TRo5M99z16GQvUEJ+LEPkfRtb51KWwskK e7izLCDaxBANxUG6s+XVyuyUtILMCR0wzmFwiqflFYoPu1EHRV84SBR76pNbUHV4TpW8= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.134 Subject: [Qemu-devel] [PATCH v3 11/16] target-m68k: add fmovecr 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" fmovecr moves a floating point constant from the FPU ROM to a floating point register. Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson --- target/m68k/fpu_helper.c | 31 +++++++++++++++++++++++++++++++ target/m68k/helper.h | 1 + target/m68k/translate.c | 12 +++++++++++- 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index aadfc82..d8145e0 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -24,6 +24,31 @@ #include "exec/helper-proto.h" #include "exec/exec-all.h" =20 +static const floatx80 fpu_rom[128] =3D { + [0x00] =3D floatx80_pi, /* Pi */ + [0x0b] =3D make_floatx80(0x3ffd, 0x9a209a84fbcff798ULL), /* Log10(2) = */ + [0x0c] =3D make_floatx80(0x4000, 0xadf85458a2bb4a9aULL), /* e = */ + [0x0d] =3D make_floatx80(0x3fff, 0xb8aa3b295c17f0bcULL), /* Log2(e) = */ + [0x0e] =3D make_floatx80(0x3ffd, 0xde5bd8a937287195ULL), /* Log10(e) = */ + [0x0f] =3D floatx80_zero, /* Zero = */ + [0x30] =3D floatx80_ln2, /* ln(2) = */ + [0x31] =3D make_floatx80(0x4000, 0x935d8dddaaa8ac17ULL), /* ln(10) = */ + [0x32] =3D floatx80_one, /* 10^0 = */ + [0x33] =3D make_floatx80(0x4002, 0xa000000000000000ULL), /* 10^1 = */ + [0x34] =3D make_floatx80(0x4005, 0xc800000000000000ULL), /* 10^2 = */ + [0x35] =3D make_floatx80(0x400c, 0x9c40000000000000ULL), /* 10^4 = */ + [0x36] =3D make_floatx80(0x4019, 0xbebc200000000000ULL), /* 10^8 = */ + [0x37] =3D make_floatx80(0x4034, 0x8e1bc9bf04000000ULL), /* 10^16 = */ + [0x38] =3D make_floatx80(0x4069, 0x9dc5ada82b70b59eULL), /* 10^32 = */ + [0x39] =3D make_floatx80(0x40d3, 0xc2781f49ffcfa6d5ULL), /* 10^64 = */ + [0x3a] =3D make_floatx80(0x41a8, 0x93ba47c980e98ce0ULL), /* 10^128 = */ + [0x3b] =3D make_floatx80(0x4351, 0xaa7eebfb9df9de8eULL), /* 10^256 = */ + [0x3c] =3D make_floatx80(0x46a3, 0xe319a0aea60e91c7ULL), /* 10^512 = */ + [0x3d] =3D make_floatx80(0x4d48, 0xc976758681750c17ULL), /* 10^1024 = */ + [0x3e] =3D make_floatx80(0x5a92, 0x9e8b3b5dc53d5de5ULL), /* 10^2048 = */ + [0x3f] =3D make_floatx80(0x7525, 0xc46052028a20979bULL), /* 10^4096 = */ +}; + static floatx80 FP0_to_floatx80(CPUM68KState *env) { return (floatx80){ .low =3D env->fp0l, .high =3D env->fp0h }; @@ -427,3 +452,9 @@ void HELPER(fmovem)(CPUM68KState *env, uint32_t opsize, { fprintf(stderr, "MISSING HELPER fmovem\n"); } + +void HELPER(const_FP0)(CPUM68KState *env, uint32_t offset) +{ + env->fp0l =3D fpu_rom[offset].low; + env->fp0h =3D fpu_rom[offset].high; +} diff --git a/target/m68k/helper.h b/target/m68k/helper.h index 58bc273..4927324 100644 --- a/target/m68k/helper.h +++ b/target/m68k/helper.h @@ -32,6 +32,7 @@ DEF_HELPER_2(set_fpcr, void, env, i32) DEF_HELPER_1(tst_FP0, void, env) DEF_HELPER_1(update_fpstatus, void, env) DEF_HELPER_4(fmovem, void, env, i32, i32, i32) +DEF_HELPER_2(const_FP0, void, env, i32) =20 DEF_HELPER_3(mac_move, void, env, i32, i32) DEF_HELPER_3(macmulf, i64, env, i32, i32) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 3fdb672..23eac63 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -4555,16 +4555,26 @@ static void gen_op_fmovem(CPUM68KState *env, DisasC= ontext *s, DISAS_INSN(fpu) { uint16_t ext; + uint8_t rom_offset; int opmode; int opsize; =20 ext =3D read_im16(env, s); opmode =3D ext & 0x7f; switch ((ext >> 13) & 7) { - case 0: case 2: + case 0: break; case 1: goto undef; + case 2: + if (insn =3D=3D 0xf200 && (ext & 0xfc00) =3D=3D 0x5c00) { + /* fmovecr */ + rom_offset =3D ext & 0x7f; + gen_helper_const_FP0(cpu_env, tcg_const_i32(rom_offset)); + gen_op_store_fpr_FP0(REG(ext, 7)); + return; + } + break; case 3: /* fmove out */ gen_op_load_fpr_FP0(REG(ext, 7)); opsize =3D ext_opsize(ext, 10); --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486430231650492.5853532360853; Mon, 6 Feb 2017 17:17:11 -0800 (PST) Received: from localhost ([::1]:51400 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauP8-0000vg-Dx for importer@patchew.org; Mon, 06 Feb 2017 20:17:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33141) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau9C-0005IY-3h for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau95-0006Ce-DE for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:40 -0500 Received: from mout.kundenserver.de ([212.227.126.130]:50986) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau95-0006C8-1x for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:35 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MDl62-1celT13myE-00H7sr; Tue, 07 Feb 2017 01:59:42 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:26 +0100 Message-Id: <20170207005930.28327-13-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:xIC/yCv+VsyCaZsHg57OKbJONodNZCVUaRtXZW5aB++o4YN3hwq ajVNAyNowip4Q3CtafosBC8sBnjgcyW2cAZC7sRBBzk1zleroAK5CMXbnyGPuFQ0F54ZGWw mCdTYtsBY9Q9bspNFqEtjs8/LqMN1pcQyYz3Gj8siVEL2YtlzRh2BmJ+hdCMP9EfzcJiSxr jLLOE2e1DQDq+kOeveQ3Q== X-UI-Out-Filterresults: notjunk:1;V01:K0:7x5LWbGzzUo=:K4InEYsO8S7G0ZfTDTXuTV cQ8OPyOg4M3EaN3paLacIRJ+v6SrXqkhJv+c/dtRw/Cn2/cDF8w68dAsxhb3+AbZUTNAZjXwA kF/I/XYK0p0UIBC3PQFBu/7RG3HpGGrI9YoT9a94C8BOwamNYyZ6cF8Z2ms8Gjn6NLn1bRVpJ qVB+UVqBMqwAeZDI+pAGQW1rMdkXfDOJElF1SgQ+bYv2EfPfczGO8E+0yVPQwiUV5hUi7/0LG j5pU7BpAVmpP+drRAJ4mVS27/SpsINKhf9RiQheSpXuzh4GV/mB0+u+I93RjaMT1MrPS53XR1 cPoyZly/Wf679+SO27i7G45w/gyifT7qrlprlaauopVpZKRZz7yUV97wx3Wdbwa2unMQyzk46 A/xJhZuQvGFe1+kq9cDTlKnMJYOYsBVskyar7J0ZsLW7FMJk9PATUe5x9W4g19XEckZI2ETAr 7+94C8iyS6Vour6ZKhHxhxFW+yBrYWiX7Dr3i85YYbqLPSsNLTE7cyAGChZ3+qN2HwUsqIiPx H+8z57YbQ9JLCtK4JDt0RLkuLwJlZQ5Yuu9bXsRS/VMP2e1W5ICSPEGHw4q/vP5iX4vRRx5hv QpvNYq4VsWI00Bc8fK3daHbZ+7wAKdC5+Y9HGOQMs9cJprdE+7VCaKjJKcBqg7lk3HX7p5epB w1uVGKnuMa6qPP8oKtVqtT0g/1rzZoErv5+QehxdCcvBFQbxaodR3KSuUPUtzc5moDhU= 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 v3 12/16] target-m68k: add fscale, fgetman, fgetexp and fmod 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" Signed-off-by: Laurent Vivier --- target/m68k/cpu.h | 1 + target/m68k/fpu_helper.c | 56 ++++++++++++++++++++++++++++++++++++++++++++= ++++ target/m68k/helper.h | 4 ++++ target/m68k/translate.c | 14 ++++++++++++ 4 files changed, 75 insertions(+) diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h index 7985dc3..3042ab7 100644 --- a/target/m68k/cpu.h +++ b/target/m68k/cpu.h @@ -253,6 +253,7 @@ typedef enum { /* Quotient */ =20 #define FPSR_QT_MASK 0x00ff0000 +#define FPSR_QT_SHIFT 16 =20 /* Floating-Point Control Register */ /* Rounding mode */ diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index d8145e0..42f5b5c 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -458,3 +458,59 @@ void HELPER(const_FP0)(CPUM68KState *env, uint32_t off= set) env->fp0l =3D fpu_rom[offset].low; env->fp0h =3D fpu_rom[offset].high; } + +void HELPER(getexp_FP0)(CPUM68KState *env) +{ + int32_t exp; + floatx80 res; + + res =3D FP0_to_floatx80(env); + if (floatx80_is_zero_or_denormal(res) || floatx80_is_any_nan(res) || + floatx80_is_infinity(res)) { + return; + } + exp =3D (env->fp0h & 0x7fff) - 0x3fff; + + res =3D int32_to_floatx80(exp, &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(getman_FP0)(CPUM68KState *env) +{ + floatx80 res; + res =3D int64_to_floatx80(env->fp0l, &env->fp_status); + floatx80_to_FP0(env, res); +} + +void HELPER(scale_FP0_FP1)(CPUM68KState *env) +{ + int32_t scale; + int32_t exp; + + scale =3D floatx80_to_int32(FP0_to_floatx80(env), &env->fp_status); + + exp =3D (env->fp1h & 0x7fff) + scale; + + env->fp0h =3D (env->fp1h & 0x8000) | (exp & 0x7fff); + env->fp0l =3D env->fp1l; +} + +static void make_quotient(CPUM68KState *env, floatx80 val) +{ + uint32_t quotient =3D floatx80_to_int32(val, &env->fp_status); + uint32_t sign =3D (quotient >> 24) & 0x80; + quotient =3D sign | (quotient & 0x7f); + env->fpsr =3D (env->fpsr & ~FPSR_QT_MASK) | (quotient << FPSR_QT_SHIFT= ); +} + +void HELPER(mod_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + res =3D floatx80_rem(FP1_to_floatx80(env), FP0_to_floatx80(env), + &env->fp_status); + make_quotient(env, res); + + floatx80_to_FP0(env, res); +} diff --git a/target/m68k/helper.h b/target/m68k/helper.h index 4927324..620e707 100644 --- a/target/m68k/helper.h +++ b/target/m68k/helper.h @@ -33,6 +33,10 @@ DEF_HELPER_1(tst_FP0, void, env) DEF_HELPER_1(update_fpstatus, void, env) DEF_HELPER_4(fmovem, void, env, i32, i32, i32) DEF_HELPER_2(const_FP0, void, env, i32) +DEF_HELPER_1(getexp_FP0, void, env) +DEF_HELPER_1(getman_FP0, void, env) +DEF_HELPER_1(scale_FP0_FP1, void, env) +DEF_HELPER_1(mod_FP0_FP1, void, env) =20 DEF_HELPER_3(mac_move, void, env, i32, i32) DEF_HELPER_3(macmulf, i64, env, i32, i32) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 23eac63..be18083 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -4629,10 +4629,20 @@ DISAS_INSN(fpu) case 0x1a: case 0x5a: case 0x5e: /* fneg */ gen_helper_chs_FP0(cpu_env); break; + case 0x1e: /* fgetexp */ + gen_helper_getexp_FP0(cpu_env); + break; + case 0x1f: /* fgetman */ + gen_helper_getman_FP0(cpu_env); + break; case 0x20: case 0x60: case 0x64: /* fdiv */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_div_FP0_FP1(cpu_env); break; + case 0x21: /* fmod */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_mod_FP0_FP1(cpu_env); + break; case 0x22: case 0x62: case 0x66: /* fadd */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_add_FP0_FP1(cpu_env); @@ -4641,6 +4651,10 @@ DISAS_INSN(fpu) gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_mul_FP0_FP1(cpu_env); break; + case 0x26: /* fscale */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_scale_FP0_FP1(cpu_env); + break; case 0x28: case 0x68: case 0x6c: /* fsub */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_sub_FP0_FP1(cpu_env); --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486429695502697.3497150595497; Mon, 6 Feb 2017 17:08:15 -0800 (PST) Received: from localhost ([::1]:51354 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauGT-0002NN-R4 for importer@patchew.org; Mon, 06 Feb 2017 20:08:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33170) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau9D-0005JF-1L for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau97-0006Ej-QT for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:42 -0500 Received: from mout.kundenserver.de ([212.227.126.131]:63648) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau97-0006D3-47 for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:37 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0Lgc09-1c75Xn1lfJ-00nyrO; Tue, 07 Feb 2017 01:59:42 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:27 +0100 Message-Id: <20170207005930.28327-14-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:RJB362U9132u8JP+Yv1FTTSXZiF3Kv6SEYBpx6AdBAP3Ld5Z7o+ cQq/DoT/0r5WvtdSNXZF+4bcEi6qExi236WP2jOK4tjv1I4qJqz5cAodv+U00piy+sY/kjF RnUHLDFz3mF54Muf02iP+bdlkBZhtMfEE1UXvmjbHeTjSSnrrt6GAqolH8H1Ev5KINlqtAz CqiSQ/kXlO7w9iLgeABow== X-UI-Out-Filterresults: notjunk:1;V01:K0:nnRNPVGAiZ8=:ffou1S61kdcob1NvCTyclr wwcXqSfCH2GCBx3zBrDkN3Z9N0gSzLHve5kqv9RI3BWdEpLFk830c2aDfxkX1UmN0CPv6W/pb hI/s6NWFhIG8UrxCQbXXOG55fBNhleRpuQ4XTIMRG3bzzGwIk/TtLH41+xQbnPLGDk8ohFPzA DGslw2agXUsRidbQhP0MQaz2RHFZdBIKRIEUNU5FeMJ0roVrukToANA3pVegPBmG5PdYl/h0k LbLR+aYp83Y7n5EKuPey5lJqyxzW6RtH/d+VP2ZwZfg8/dsKsaMJgzV3lj9PuRwfP491MXxyB 00g9EpLECxGGMZ2B/XtFAUD3VStkte9np7jFGnJJ7/hzw3YTj01YIj+rLqVPFOIix8o+KG8pC nkrARCzdR4b4+yoyjKY5ud472sWj8+jlE1Yz/VEzJRUpEw0qVkF/rMVLkhv7wWBJBf3Npmg7b rVpCukDqseBAwAN4DY9QRUtS0SdBKGT63RWK1pY+zPFUGXqq9cOIBPANCCASF0sxeYflAkui4 bkv7deVbo8nWfIxASfAWOo4VYCjwR02XG2K2NvDhU6r9fzdg5K6rmtSIH0SAYeyMOoGu8oXaP l6FyI/juJ6W3mJlF5oNVwyaue7QSRceeXJIlfVeW8yQpvsMkCNQFRay4ox8JyPg3bQR5BVm7Q UhZ4E36qxliENm+B7wGzuqWQiVEEuecp+76cM1aJQptm5XeDpgRMsH6ej+W3PDlbcf4Q= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.131 Subject: [Qemu-devel] [PATCH v3 13/16] target-m68k: add fsglmul and fsgldiv 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" fsglmul and fsgldiv truncate data to single precision before computing results. Signed-off-by: Laurent Vivier --- target/m68k/fpu_helper.c | 22 ++++++++++++++++++++++ target/m68k/helper.h | 2 ++ target/m68k/translate.c | 8 ++++++++ 3 files changed, 32 insertions(+) diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index 42f5b5c..8a3eed3 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -351,6 +351,17 @@ void HELPER(mul_FP0_FP1)(CPUM68KState *env) floatx80_to_FP0(env, res); } =20 +void HELPER(sglmul_FP0_FP1)(CPUM68KState *env) +{ + float64 a, b, res; + + a =3D floatx80_to_float64(FP0_to_floatx80(env), &env->fp_status); + b =3D floatx80_to_float64(FP1_to_floatx80(env), &env->fp_status); + res =3D float64_mul(a, b, &env->fp_status); + + floatx80_to_FP0(env, float64_to_floatx80(res, &env->fp_status)); +} + void HELPER(div_FP0_FP1)(CPUM68KState *env) { floatx80 res; @@ -361,6 +372,17 @@ void HELPER(div_FP0_FP1)(CPUM68KState *env) floatx80_to_FP0(env, res); } =20 +void HELPER(sgldiv_FP0_FP1)(CPUM68KState *env) +{ + float64 a, b, res; + + a =3D floatx80_to_float64(FP1_to_floatx80(env), &env->fp_status); + b =3D floatx80_to_float64(FP0_to_floatx80(env), &env->fp_status); + res =3D float64_div(a, b, &env->fp_status); + + floatx80_to_FP0(env, float64_to_floatx80(res, &env->fp_status)); +} + static int float_comp_to_cc(int float_compare) { switch (float_compare) { diff --git a/target/m68k/helper.h b/target/m68k/helper.h index 620e707..c30e5f7 100644 --- a/target/m68k/helper.h +++ b/target/m68k/helper.h @@ -26,7 +26,9 @@ DEF_HELPER_1(chs_FP0, void, env) DEF_HELPER_1(add_FP0_FP1, void, env) DEF_HELPER_1(sub_FP0_FP1, void, env) DEF_HELPER_1(mul_FP0_FP1, void, env) +DEF_HELPER_1(sglmul_FP0_FP1, void, env) DEF_HELPER_1(div_FP0_FP1, void, env) +DEF_HELPER_1(sgldiv_FP0_FP1, void, env) DEF_HELPER_1(cmp_FP0_FP1, void, env) DEF_HELPER_2(set_fpcr, void, env, i32) DEF_HELPER_1(tst_FP0, void, env) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index be18083..99f41d3 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -4651,10 +4651,18 @@ DISAS_INSN(fpu) gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_mul_FP0_FP1(cpu_env); break; + case 0x24: /* fsgldiv */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_sgldiv_FP0_FP1(cpu_env); + break; case 0x26: /* fscale */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_scale_FP0_FP1(cpu_env); break; + case 0x27: /* fsglmul */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_sglmul_FP0_FP1(cpu_env); + break; case 0x28: case 0x68: case 0x6c: /* fsub */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_sub_FP0_FP1(cpu_env); --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486430040672170.23106005538773; Mon, 6 Feb 2017 17:14:00 -0800 (PST) Received: from localhost ([::1]:51383 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauM1-000775-Eh for importer@patchew.org; Mon, 06 Feb 2017 20:13:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33159) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau9C-0005Io-GF for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau97-0006Em-R2 for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:42 -0500 Received: from mout.kundenserver.de ([212.227.126.135]:52609) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau97-0006D9-8G for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:37 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MT3ze-1d33cW3u6g-00S45V; Tue, 07 Feb 2017 01:59:43 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:28 +0100 Message-Id: <20170207005930.28327-15-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:3M9rGsOTO3UnEmEFXRikOu9bUTH+Boe//+8F5yLURnQvhhG0bgZ Ocx/xYUe5dbSRL7Q6op233rw2DuLZo0uiMkzn7tyWJWVSlL7o6frB712OHBYgZfpvzjSk52 PJ19VpT3dNxG2/IJ/OUC8gyyLeETef6VHt4E9mSW+rhXr0rOwX84gePn3qM72fVihPT/5Ep hfTxLQJCC0xOXMpAmg9NA== X-UI-Out-Filterresults: notjunk:1;V01:K0:mNAc5rHnoz8=:SD+qljzg2ehUYEcyI195Fj gbVCwGl/A/kwkkpgQJMn9J3rg6Nv5eNM4+d9ES6eIVsaiBfxMRmAuduN7xcul3QXPsADBnZwC A0O2ioWjsjuobi9NTIsjHFsPavDs8FAVtIGlBpNlEkPxi+YgXOCD0OduQmNC5rFBuWh5/Ivsn IlwE0L4cLQkhVLWKLFFA6B0UIp3NDZvKDXal4Ca3I+7YuybYEpmIpYPw/mIyA8AThqR1NqUsy 3BNVgx22T/lHNU8owBfxYz+DTzYZmrw5LH8WzduaKHpfBEC/FBg8JwvA69qsWCaM1UmyHf0Na QPLOhQmA2DfHHPceo0zosFba7UQf0KYpo2c3lWU1X7VjptsuGK/IU0L/cpYRQU9rgSK9NXMB7 X81pS9l0QXTN3rHTHLRlJm2f9PxHXVxWzbuAT2b/wHGPi1RdYh5iDrm0r4xk+MnmEVI4mlKMl w4PtTdheEPCAnnm9bHtutMvQ2QtWlWon0k8mPnGK8ePvHCeYI3iMStia4APokY+o4YkGH+sft W9MeC3Fx8F8GE6+Ilv6s99F4gibAaamLm8upcIa0nmDN3GcTnaALDFD4P2w9yyIb4yMxEcK96 qkQV5h9S4hBK9YRtVecByAo8EJi35ODUidGx/Mary52XGxtkidjoqNEFddRXNuUIhwP7WAoFz 0LJsR1/sjja7zMJxK3f4qCyKBPNzc9RvGSQq6nV0hsR/PGteR7u2FZCSKlgZbmrahTok= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.135 Subject: [Qemu-devel] [PATCH v3 14/16] target-m68k: add explicit single and double precision operations 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" Add fssqrt, fdsqrt, fsabs, fdabs, fsneg, fdneg, fsadd, fdadd, fssub, fdsub, fsmul, fdmul, fsdiv, fddiv, fsmove and fdmove. The precision is managed using set_floatx80_rounding_precision(), except for fsmove, fdmove, fsneg, fdneg, fsabs and fdabs: the value is converted manually to the given precision and converted back to floatx80. Signed-off-by: Laurent Vivier --- target/m68k/fpu_helper.c | 178 +++++++++++++++++++++++++++++++++++++++++++= +++- target/m68k/helper.h | 16 ++++- target/m68k/translate.c | 76 +++++++++++++++++--- 3 files changed, 259 insertions(+), 11 deletions(-) diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index 8a3eed3..c69efe1 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -294,6 +294,16 @@ void HELPER(itrunc_FP0)(CPUM68KState *env) floatx80_to_FP0(env, res); } =20 +#define PREC_BEGIN(prec) \ + do { \ + int old; \ + old =3D get_floatx80_rounding_precision(&env->fp_status); \ + set_floatx80_rounding_precision(prec, &env->fp_status) \ + +#define PREC_END() \ + set_floatx80_rounding_precision(old, &env->fp_status); \ + } while (0) + void HELPER(sqrt_FP0)(CPUM68KState *env) { floatx80 res; @@ -303,6 +313,28 @@ void HELPER(sqrt_FP0)(CPUM68KState *env) floatx80_to_FP0(env, res); } =20 +void HELPER(ssqrt_FP0)(CPUM68KState *env) +{ + floatx80 res; + + PREC_BEGIN(32); + res =3D floatx80_sqrt(FP0_to_floatx80(env), &env->fp_status); + PREC_END(); + + floatx80_to_FP0(env, res); +} + +void HELPER(dsqrt_FP0)(CPUM68KState *env) +{ + floatx80 res; + + PREC_BEGIN(64); + res =3D floatx80_sqrt(FP0_to_floatx80(env), &env->fp_status); + PREC_END(); + + floatx80_to_FP0(env, res); +} + void HELPER(abs_FP0)(CPUM68KState *env) { floatx80 res; @@ -312,11 +344,59 @@ void HELPER(abs_FP0)(CPUM68KState *env) floatx80_to_FP0(env, res); } =20 -void HELPER(chs_FP0)(CPUM68KState *env) +void HELPER(sabs_FP0)(CPUM68KState *env) { floatx80 res; + float32 f32; + + res =3D floatx80_abs(FP0_to_floatx80(env)); + f32 =3D floatx80_to_float32(res, &env->fp_status); + res =3D float32_to_floatx80(f32, &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(dabs_FP0)(CPUM68KState *env) +{ + floatx80 res; + float64 f64; + + res =3D floatx80_abs(FP0_to_floatx80(env)); + f64 =3D floatx80_to_float64(res, &env->fp_status); + res =3D float64_to_floatx80(f64, &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(neg_FP0)(CPUM68KState *env) +{ + floatx80 res; + + res =3D floatx80_chs(FP0_to_floatx80(env)); + + floatx80_to_FP0(env, res); +} + +void HELPER(sneg_FP0)(CPUM68KState *env) +{ + floatx80 res; + float32 f32; + + res =3D floatx80_chs(FP0_to_floatx80(env)); + f32 =3D floatx80_to_float32(res, &env->fp_status); + res =3D float32_to_floatx80(f32, &env->fp_status); + + floatx80_to_FP0(env, res); +} + +void HELPER(dneg_FP0)(CPUM68KState *env) +{ + floatx80 res; + float64 f64; =20 res =3D floatx80_chs(FP0_to_floatx80(env)); + f64 =3D floatx80_to_float64(res, &env->fp_status); + res =3D float64_to_floatx80(f64, &env->fp_status); =20 floatx80_to_FP0(env, res); } @@ -331,6 +411,30 @@ void HELPER(add_FP0_FP1)(CPUM68KState *env) floatx80_to_FP0(env, res); } =20 +void HELPER(sadd_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + PREC_BEGIN(32); + res =3D floatx80_add(FP0_to_floatx80(env), FP1_to_floatx80(env), + &env->fp_status); + PREC_END(); + + floatx80_to_FP0(env, res); +} + +void HELPER(dadd_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + PREC_BEGIN(64); + res =3D floatx80_add(FP0_to_floatx80(env), FP1_to_floatx80(env), + &env->fp_status); + PREC_END(); + + floatx80_to_FP0(env, res); +} + void HELPER(sub_FP0_FP1)(CPUM68KState *env) { floatx80 res; @@ -341,6 +445,30 @@ void HELPER(sub_FP0_FP1)(CPUM68KState *env) floatx80_to_FP0(env, res); } =20 +void HELPER(ssub_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + PREC_BEGIN(32); + res =3D floatx80_sub(FP1_to_floatx80(env), FP0_to_floatx80(env), + &env->fp_status); + PREC_END(); + + floatx80_to_FP0(env, res); +} + +void HELPER(dsub_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + PREC_BEGIN(64); + res =3D floatx80_sub(FP1_to_floatx80(env), FP0_to_floatx80(env), + &env->fp_status); + PREC_END(); + + floatx80_to_FP0(env, res); +} + void HELPER(mul_FP0_FP1)(CPUM68KState *env) { floatx80 res; @@ -351,6 +479,30 @@ void HELPER(mul_FP0_FP1)(CPUM68KState *env) floatx80_to_FP0(env, res); } =20 +void HELPER(smul_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + PREC_BEGIN(32); + res =3D floatx80_mul(FP0_to_floatx80(env), FP1_to_floatx80(env), + &env->fp_status); + PREC_END(); + + floatx80_to_FP0(env, res); +} + +void HELPER(dmul_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + PREC_BEGIN(64); + res =3D floatx80_mul(FP0_to_floatx80(env), FP1_to_floatx80(env), + &env->fp_status); + PREC_END(); + + floatx80_to_FP0(env, res); +} + void HELPER(sglmul_FP0_FP1)(CPUM68KState *env) { float64 a, b, res; @@ -372,6 +524,30 @@ void HELPER(div_FP0_FP1)(CPUM68KState *env) floatx80_to_FP0(env, res); } =20 +void HELPER(sdiv_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + PREC_BEGIN(32); + res =3D floatx80_div(FP1_to_floatx80(env), FP0_to_floatx80(env), + &env->fp_status); + PREC_END(); + + floatx80_to_FP0(env, res); +} + +void HELPER(ddiv_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + + PREC_BEGIN(64); + res =3D floatx80_div(FP1_to_floatx80(env), FP0_to_floatx80(env), + &env->fp_status); + PREC_END(); + + floatx80_to_FP0(env, res); +} + void HELPER(sgldiv_FP0_FP1)(CPUM68KState *env) { float64 a, b, res; diff --git a/target/m68k/helper.h b/target/m68k/helper.h index c30e5f7..07aa04f 100644 --- a/target/m68k/helper.h +++ b/target/m68k/helper.h @@ -21,13 +21,27 @@ DEF_HELPER_1(reds32_FP0, void, env) DEF_HELPER_1(iround_FP0, void, env) DEF_HELPER_1(itrunc_FP0, void, env) DEF_HELPER_1(sqrt_FP0, void, env) +DEF_HELPER_1(ssqrt_FP0, void, env) +DEF_HELPER_1(dsqrt_FP0, void, env) DEF_HELPER_1(abs_FP0, void, env) -DEF_HELPER_1(chs_FP0, void, env) +DEF_HELPER_1(sabs_FP0, void, env) +DEF_HELPER_1(dabs_FP0, void, env) +DEF_HELPER_1(neg_FP0, void, env) +DEF_HELPER_1(sneg_FP0, void, env) +DEF_HELPER_1(dneg_FP0, void, env) DEF_HELPER_1(add_FP0_FP1, void, env) +DEF_HELPER_1(sadd_FP0_FP1, void, env) +DEF_HELPER_1(dadd_FP0_FP1, void, env) DEF_HELPER_1(sub_FP0_FP1, void, env) +DEF_HELPER_1(ssub_FP0_FP1, void, env) +DEF_HELPER_1(dsub_FP0_FP1, void, env) DEF_HELPER_1(mul_FP0_FP1, void, env) +DEF_HELPER_1(smul_FP0_FP1, void, env) +DEF_HELPER_1(dmul_FP0_FP1, void, env) DEF_HELPER_1(sglmul_FP0_FP1, void, env) DEF_HELPER_1(div_FP0_FP1, void, env) +DEF_HELPER_1(sdiv_FP0_FP1, void, env) +DEF_HELPER_1(ddiv_FP0_FP1, void, env) DEF_HELPER_1(sgldiv_FP0_FP1, void, env) DEF_HELPER_1(cmp_FP0_FP1, void, env) DEF_HELPER_2(set_fpcr, void, env, i32) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 99f41d3..883f4ff 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -4612,7 +4612,15 @@ DISAS_INSN(fpu) gen_op_load_fpr_FP0(REG(ext, 10)); } switch (opmode) { - case 0: case 0x40: case 0x44: /* fmove */ + case 0: /* fmove */ + break; + case 0x40: /* fsmove */ + gen_helper_redf32_FP0(cpu_env); + gen_helper_extf32_FP0(cpu_env); + break; + case 0x44: /* fdmove */ + gen_helper_redf64_FP0(cpu_env); + gen_helper_extf64_FP0(cpu_env); break; case 1: /* fint */ gen_helper_iround_FP0(cpu_env); @@ -4620,14 +4628,32 @@ DISAS_INSN(fpu) case 3: /* fintrz */ gen_helper_itrunc_FP0(cpu_env); break; - case 4: case 0x41: case 0x45: /* fsqrt */ + case 4: /* fsqrt */ gen_helper_sqrt_FP0(cpu_env); break; - case 0x18: case 0x58: case 0x5c: /* fabs */ + case 0x41: /* fssqrt */ + gen_helper_ssqrt_FP0(cpu_env); + break; + case 0x45: /* fdsqrt */ + gen_helper_dsqrt_FP0(cpu_env); + break; + case 0x18: /* fabs */ gen_helper_abs_FP0(cpu_env); break; - case 0x1a: case 0x5a: case 0x5e: /* fneg */ - gen_helper_chs_FP0(cpu_env); + case 0x58: /* fsabs */ + gen_helper_sabs_FP0(cpu_env); + break; + case 0x5c: /* fdabs */ + gen_helper_dabs_FP0(cpu_env); + break; + case 0x1a: /* fneg */ + gen_helper_neg_FP0(cpu_env); + break; + case 0x5a: /* fsneg */ + gen_helper_sneg_FP0(cpu_env); + break; + case 0x5e: /* fdneg */ + gen_helper_dneg_FP0(cpu_env); break; case 0x1e: /* fgetexp */ gen_helper_getexp_FP0(cpu_env); @@ -4635,22 +4661,46 @@ DISAS_INSN(fpu) case 0x1f: /* fgetman */ gen_helper_getman_FP0(cpu_env); break; - case 0x20: case 0x60: case 0x64: /* fdiv */ + case 0x20: /* fdiv */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_div_FP0_FP1(cpu_env); break; + case 0x60: /* fsdiv */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_sdiv_FP0_FP1(cpu_env); + break; + case 0x64: /* fddiv */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_ddiv_FP0_FP1(cpu_env); + break; case 0x21: /* fmod */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_mod_FP0_FP1(cpu_env); break; - case 0x22: case 0x62: case 0x66: /* fadd */ + case 0x22: /* fadd */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_add_FP0_FP1(cpu_env); break; - case 0x23: case 0x63: case 0x67: /* fmul */ + case 0x62: /* fsadd */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_sadd_FP0_FP1(cpu_env); + break; + case 0x66: /* fdadd */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_dadd_FP0_FP1(cpu_env); + break; + case 0x23: /* fmul */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_mul_FP0_FP1(cpu_env); break; + case 0x63: /* fsmul */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_smul_FP0_FP1(cpu_env); + break; + case 0x67: /* fdmul */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_dmul_FP0_FP1(cpu_env); + break; case 0x24: /* fsgldiv */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_sgldiv_FP0_FP1(cpu_env); @@ -4663,10 +4713,18 @@ DISAS_INSN(fpu) gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_sglmul_FP0_FP1(cpu_env); break; - case 0x28: case 0x68: case 0x6c: /* fsub */ + case 0x28: /* fsub */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_sub_FP0_FP1(cpu_env); break; + case 0x68: /* fssub */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_ssub_FP0_FP1(cpu_env); + break; + case 0x6c: /* fdsub */ + gen_op_load_fpr_FP1(REG(ext, 7)); + gen_helper_dsub_FP0_FP1(cpu_env); + break; case 0x38: /* fcmp */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_cmp_FP0_FP1(cpu_env); --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486430534760171.49578994145782; Mon, 6 Feb 2017 17:22:14 -0800 (PST) Received: from localhost ([::1]:51426 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauU1-0004UK-DV for importer@patchew.org; Mon, 06 Feb 2017 20:22:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33173) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau9D-0005JI-2G for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau97-0006Ew-RB for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:43 -0500 Received: from mout.kundenserver.de ([212.227.126.131]:56273) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau97-0006DB-8Q for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:37 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MFwx8-1cgyOP2ntm-00EuxR; Tue, 07 Feb 2017 01:59:44 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:29 +0100 Message-Id: <20170207005930.28327-16-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:otAo2MLwqEQKzwK+CeSE+zupLAG9jmZrIdu1gz5ug121GphRwEI bbWZ21oeeuCWhr5lXo4we6iC6BczcArTId392xbKvvhCUpBDRY7fUG3qv8rC/rMUuRhMXUA vmCA0WxU6cVDDBkvnlhszmzwKK57Q2GjQryM/llh0kyZzFcQuLYH7w1vRvpcGgbafICSdXC QW3dh6amYQxVqDo7GsQ1g== X-UI-Out-Filterresults: notjunk:1;V01:K0:XaoFRu3LdaU=:JooBzAW6ADtLbMa1zYmqvq 1w+YQ7jwxzF1KBMTy3t6rA2t7dzoEznc2s6+JNJiW/BaVT670ukWsnhvouap4qT0pdirqfuSF Q1m2jXIYHrLJXSguNMkPKjeNPAzXKA79T0+4PBNKikiKyI/5am+UzkvFwK7w+K6DlV2FTPal3 1mv3Bm+fOwhprs4ZLPBYSOs55m+ZlKqQJGE8HErGlN9+HjWQD6VpIyzJSxlaQI2kilGGlhjZW 4tPw/Vku65dqiZGWF+jbZ0/6lSkvI2Ha8MeTl+VWND57+qhqgAUbKA0qdGjgc2BbZVjmzgaL/ T6BdDK3ud/8d8FBaBr1M4y5RMyZt31/mS8eN/U/P8alsMuNUIDvtaYSAH/H7jQG3MJIlCPOmw KWvvB6aZNVOutWVSxvTAB22VLxhDs88QZDc0O+8nRCbnw0mcLYSm0YR6CbVXHv6vQjVFCwWig D4+TIc/Ce9E+Ctco5XwN98AJp5yhEIz5K9KVyI9xAYp5RIPv9ZDOam2Unalih+zC6mUuD8A8N RZfRt4in32Mfs+ikLsr3BMndFkQCpegswJG1s4iuCy9F0iYlSNETlesvIBqI9azFWdM9Wn75/ C8RFizEl7biNhxHivc1aBE7lieoEy9/3p6ymqTbzgNreim6pk1IJ5THn0wsXTzHHYikjLjG3q cvfiTi1uAo6W/fRyLgygRGax5eEuxEB2XfpUOWBzpdO+MOEsmLdVI3bgzcyHRJSLILW8= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.131 Subject: [Qemu-devel] [PATCH v3 15/16] target-m68k: add more FPU instructions 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" Add fsinh, flognp1, ftanh, fatan, fasin, fatanh, fsin, ftan, fetox, ftwotox, ftentox, flogn, flog10, facos, fcos. As softfloat library does not provide these functions, we us the libm of the host. Signed-off-by: Laurent Vivier --- target/m68k/fpu_helper.c | 237 +++++++++++++++++++++++++++++++++++++++++++= ++++ target/m68k/helper.h | 16 ++++ target/m68k/translate.c | 48 ++++++++++ 3 files changed, 301 insertions(+) diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index c69efe1..95d5cc4 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -23,6 +23,7 @@ #include "cpu.h" #include "exec/helper-proto.h" #include "exec/exec-all.h" +#include =20 static const floatx80 fpu_rom[128] =3D { [0x00] =3D floatx80_pi, /* Pi */ @@ -712,3 +713,239 @@ void HELPER(mod_FP0_FP1)(CPUM68KState *env) =20 floatx80_to_FP0(env, res); } + +static long double floatx80_to_ldouble(floatx80 val) +{ + if (floatx80_is_infinity(val)) { + if (floatx80_is_neg(val)) { + return -__builtin_infl(); + } + return __builtin_infl(); + } + if (floatx80_is_any_nan(val)) { + char low[20]; + sprintf(low, "0x%016"PRIx64, val.low); + + return nanl(low); + } + + return *(long double *)&val; +} + +static floatx80 ldouble_to_floatx80(long double val) +{ + floatx80 res; + + if (isinf(val)) { + res.high =3D floatx80_default_nan(NULL).high; + res.low =3D 0; + } + if (isinf(val) < 0) { + res.high |=3D 0x8000; + } + if (isnan(val)) { + res.high =3D floatx80_default_nan(NULL).high; + res.low =3D *(uint64_t *)((char *)&val + 4); + } + return *(floatx80 *)&val; +} + +void HELPER(sinh_FP0)(CPUM68KState *env) +{ + floatx80 res; + long double val; + + val =3D sinhl(floatx80_to_ldouble(FP0_to_floatx80(env))); + res =3D ldouble_to_floatx80(val); + + floatx80_to_FP0(env, res); +} + +void HELPER(lognp1_FP0)(CPUM68KState *env) +{ + floatx80 val; + long double res; + + val =3D FP0_to_floatx80(env); + res =3D logl(floatx80_to_ldouble(val) + 1.0); + + floatx80_to_FP0(env, ldouble_to_floatx80(res)); +} + +void HELPER(ln_FP0)(CPUM68KState *env) +{ + floatx80 val; + long double res; + + val =3D FP0_to_floatx80(env); + res =3D logl(floatx80_to_ldouble(val)); + + floatx80_to_FP0(env, ldouble_to_floatx80(res)); +} + +void HELPER(log10_FP0)(CPUM68KState *env) +{ + floatx80 val; + long double res; + + val =3D FP0_to_floatx80(env); + res =3D log10l(floatx80_to_ldouble(val)); + + floatx80_to_FP0(env, ldouble_to_floatx80(res)); +} + +void HELPER(atan_FP0)(CPUM68KState *env) +{ + floatx80 res; + long double val; + + val =3D floatx80_to_ldouble(FP0_to_floatx80(env)); + + val =3D atanl(val); + res =3D ldouble_to_floatx80(val); + floatx80_to_FP0(env, res); +} + +void HELPER(asin_FP0)(CPUM68KState *env) +{ + floatx80 res; + long double val; + + val =3D floatx80_to_ldouble(FP0_to_floatx80(env)); + if (val < -1.0 || val > 1.0) { + floatx80_to_FP0(env, floatx80_default_nan(NULL)); + return; + } + + val =3D asinl(val); + res =3D ldouble_to_floatx80(val); + floatx80_to_FP0(env, res); +} + +void HELPER(atanh_FP0)(CPUM68KState *env) +{ + floatx80 res; + long double val; + + val =3D floatx80_to_ldouble(FP0_to_floatx80(env)); + if (val < -1.0 || val > 1.0) { + floatx80_to_FP0(env, floatx80_default_nan(NULL)); + return; + } + + val =3D atanhl(val); + res =3D ldouble_to_floatx80(val); + floatx80_to_FP0(env, res); +} + +void HELPER(sin_FP0)(CPUM68KState *env) +{ + floatx80 res; + long double val; + + val =3D floatx80_to_ldouble(FP0_to_floatx80(env)); + + val =3D sinl(val); + res =3D ldouble_to_floatx80(val); + floatx80_to_FP0(env, res); +} + +void HELPER(tanh_FP0)(CPUM68KState *env) +{ + floatx80 res; + long double val; + + val =3D floatx80_to_ldouble(FP0_to_floatx80(env)); + + val =3D tanhl(val); + res =3D ldouble_to_floatx80(val); + floatx80_to_FP0(env, res); +} + +void HELPER(tan_FP0)(CPUM68KState *env) +{ + floatx80 res; + long double val; + + val =3D floatx80_to_ldouble(FP0_to_floatx80(env)); + + val =3D tanl(val); + res =3D ldouble_to_floatx80(val); + floatx80_to_FP0(env, res); +} + +void HELPER(exp_FP0)(CPUM68KState *env) +{ + floatx80 f; + long double res; + + f =3D FP0_to_floatx80(env); + + res =3D expl(floatx80_to_ldouble(f)); + + floatx80_to_FP0(env, ldouble_to_floatx80(res)); +} + +void HELPER(exp2_FP0)(CPUM68KState *env) +{ + floatx80 f; + long double res; + + f =3D FP0_to_floatx80(env); + + res =3D exp2l(floatx80_to_ldouble(f)); + + floatx80_to_FP0(env, ldouble_to_floatx80(res)); +} + +void HELPER(exp10_FP0)(CPUM68KState *env) +{ + floatx80 res; + long double val; + + val =3D floatx80_to_ldouble(FP0_to_floatx80(env)); + + val =3D exp10l(val); + res =3D ldouble_to_floatx80(val); + floatx80_to_FP0(env, res); +} + +void HELPER(cosh_FP0)(CPUM68KState *env) +{ + floatx80 res; + long double val; + + val =3D floatx80_to_ldouble(FP0_to_floatx80(env)); + + val =3D coshl(val); + res =3D ldouble_to_floatx80(val); + floatx80_to_FP0(env, res); +} + +void HELPER(acos_FP0)(CPUM68KState *env) +{ + floatx80 res; + long double val; + + val =3D floatx80_to_ldouble(FP0_to_floatx80(env)); + if (val < -1.0 || val > 1.0) { + floatx80_to_FP0(env, floatx80_default_nan(NULL)); + return; + } + + val =3D acosl(val); + res =3D ldouble_to_floatx80(val); + floatx80_to_FP0(env, res); +} + +void HELPER(cos_FP0)(CPUM68KState *env) +{ + floatx80 res; + long double val; + + val =3D floatx80_to_ldouble(FP0_to_floatx80(env)); + + val =3D cosl(val); + res =3D ldouble_to_floatx80(val); + floatx80_to_FP0(env, res); +} diff --git a/target/m68k/helper.h b/target/m68k/helper.h index 07aa04f..600a9a6 100644 --- a/target/m68k/helper.h +++ b/target/m68k/helper.h @@ -53,6 +53,22 @@ DEF_HELPER_1(getexp_FP0, void, env) DEF_HELPER_1(getman_FP0, void, env) DEF_HELPER_1(scale_FP0_FP1, void, env) DEF_HELPER_1(mod_FP0_FP1, void, env) +DEF_HELPER_1(sinh_FP0, void, env) +DEF_HELPER_1(lognp1_FP0, void, env) +DEF_HELPER_1(atan_FP0, void, env) +DEF_HELPER_1(asin_FP0, void, env) +DEF_HELPER_1(atanh_FP0, void, env) +DEF_HELPER_1(sin_FP0, void, env) +DEF_HELPER_1(tanh_FP0, void, env) +DEF_HELPER_1(tan_FP0, void, env) +DEF_HELPER_1(exp_FP0, void, env) +DEF_HELPER_1(exp2_FP0, void, env) +DEF_HELPER_1(exp10_FP0, void, env) +DEF_HELPER_1(ln_FP0, void, env) +DEF_HELPER_1(log10_FP0, void, env) +DEF_HELPER_1(cosh_FP0, void, env) +DEF_HELPER_1(acos_FP0, void, env) +DEF_HELPER_1(cos_FP0, void, env) =20 DEF_HELPER_3(mac_move, void, env, i32, i32) DEF_HELPER_3(macmulf, i64, env, i32, i32) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 883f4ff..7af88a2 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -4625,6 +4625,9 @@ DISAS_INSN(fpu) case 1: /* fint */ gen_helper_iround_FP0(cpu_env); break; + case 2: /* fsinh */ + gen_helper_sinh_FP0(cpu_env); + break; case 3: /* fintrz */ gen_helper_itrunc_FP0(cpu_env); break; @@ -4637,6 +4640,42 @@ DISAS_INSN(fpu) case 0x45: /* fdsqrt */ gen_helper_dsqrt_FP0(cpu_env); break; + case 0x06: /* flognp1 */ + gen_helper_lognp1_FP0(cpu_env); + break; + case 0x09: /* ftanh */ + gen_helper_tanh_FP0(cpu_env); + break; + case 0x0a: /* fatan */ + gen_helper_atan_FP0(cpu_env); + break; + case 0x0c: /* fasin */ + gen_helper_asin_FP0(cpu_env); + break; + case 0x0d: /* fatanh */ + gen_helper_atanh_FP0(cpu_env); + break; + case 0x0e: /* fsin */ + gen_helper_sin_FP0(cpu_env); + break; + case 0x0f: /* ftan */ + gen_helper_tan_FP0(cpu_env); + break; + case 0x10: /* fetox */ + gen_helper_exp_FP0(cpu_env); + break; + case 0x11: /* ftwotox */ + gen_helper_exp2_FP0(cpu_env); + break; + case 0x12: /* ftentox */ + gen_helper_exp10_FP0(cpu_env); + break; + case 0x14: /* flogn */ + gen_helper_ln_FP0(cpu_env); + break; + case 0x15: /* flog10 */ + gen_helper_log10_FP0(cpu_env); + break; case 0x18: /* fabs */ gen_helper_abs_FP0(cpu_env); break; @@ -4646,6 +4685,9 @@ DISAS_INSN(fpu) case 0x5c: /* fdabs */ gen_helper_dabs_FP0(cpu_env); break; + case 0x19: /* fcosh */ + gen_helper_cosh_FP0(cpu_env); + break; case 0x1a: /* fneg */ gen_helper_neg_FP0(cpu_env); break; @@ -4655,6 +4697,12 @@ DISAS_INSN(fpu) case 0x5e: /* fdneg */ gen_helper_dneg_FP0(cpu_env); break; + case 0x1c: /* facos */ + gen_helper_acos_FP0(cpu_env); + break; + case 0x1d: /* fcos */ + gen_helper_cos_FP0(cpu_env); + break; case 0x1e: /* fgetexp */ gen_helper_getexp_FP0(cpu_env); break; --=20 2.9.3 From nobody Thu May 2 19:54:29 2024 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 1486430050049616.1519267663994; Mon, 6 Feb 2017 17:14:10 -0800 (PST) Received: from localhost ([::1]:51384 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cauMC-0007FW-Ae for importer@patchew.org; Mon, 06 Feb 2017 20:14:08 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:33149) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cau9C-0005Ib-3e for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cau96-0006Dz-O7 for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:41 -0500 Received: from mout.kundenserver.de ([212.227.126.187]:50498) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cau96-0006Ci-CW for qemu-devel@nongnu.org; Mon, 06 Feb 2017 20:00:36 -0500 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue004 [212.227.15.167]) with ESMTPSA (Nemesis) id 0MNhFO-1cUpb81IWQ-007GWn; Tue, 07 Feb 2017 01:59:44 +0100 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Tue, 7 Feb 2017 01:59:30 +0100 Message-Id: <20170207005930.28327-17-laurent@vivier.eu> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170207005930.28327-1-laurent@vivier.eu> References: <20170207005930.28327-1-laurent@vivier.eu> X-Provags-ID: V03:K0:esumLiADSEuKLoo86pk088u0vGZGq/8UIA8v4rAhZ33p8Yw8MBx Y1Ga9M81DztfNX+yirGXYTyczLwHhOjZ0cFFe2LsgmriJ/zDke3+2ZYwwTR3w6tUb73SfFt gbhLxN9eF7Kwja8+ouxjjSqSujAamGIHD5N9TVy1k7lY47LPiUMFDb9wrphlnLDJHg2hzpI JLAdq2Zr+7NwxC9dbml+w== X-UI-Out-Filterresults: notjunk:1;V01:K0:gp01DGm+38Y=:zd6rksPKrvDpwaW9RiTsen JJ4y37nLIs/pIiFbfgbbMZXbHnBvLU9VwpekpJkyeX/MfWN6D1bC+t3S5NXxW5pfqRdDUryFs jVBTRH32tfnUiJ8my681bhWg93xEhRO0UqQsN9rfihBjs1UF5ObxokVxA7GRJVK3dLy8TCpaK RMBRzpSDzlxUf7z8tn/v0+ihFGVUAVpIKfjNlB/gr8F8c/14Z/RfCNo75cVN759mDGSxugQfF 1LAvwy6FCfuhK0cBaay7K8Ttv7043iR/xmZxT9xNHNHpwRrtMulAL3Lh7C4MWi/QYuMPfn+OW OCTWzg0vWGAku5Zei8Z2cgO06+q2l08mt8cEBeAVvI3jZtXNIf8NJ27xamOYqKbT6dA2/O5Z3 AHCNSjTHA2EdDP6DGueOHL2xHb7bddObrwej0KYYXYhWf3Pr5kLG1GNJHsC5/Kduw4iq6sojj OV4QeDRd6A3Scc7QZMsqk1NCX7CTU/AG+XgqpS3rTMaa3dTji1OK77B6uEaEjTVwwIRjETLMB VeEWYql2qO1xKbbcPUIVSBlTsImRSi/pjHDCY+2W3JIV7VjQVNDOGo+N0t84gFrWLQDnuUVDV jP9FsWx6KPLoSLmKaT2aw39I7ZPnJGedPO+5ja9BLhkKH95QuKkwEm4UOSzaUy2bUnI6eMlDN wC1ZKW6WvJNpdEkns7ay5Sm48XyuK2VCDc35hgR8QJTf+jeDziETSgCly5c0ZnDTYPeU= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.126.187 Subject: [Qemu-devel] [PATCH v3 16/16] target-m68k: add fsincos 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: Laurent Vivier , Aurelien Jarno , Richard Henderson 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" Signed-off-by: Laurent Vivier --- target/m68k/fpu_helper.c | 21 +++++++++++++++++++++ target/m68k/helper.h | 1 + target/m68k/translate.c | 15 +++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/target/m68k/fpu_helper.c b/target/m68k/fpu_helper.c index 95d5cc4..9b9d9aa 100644 --- a/target/m68k/fpu_helper.c +++ b/target/m68k/fpu_helper.c @@ -95,6 +95,12 @@ static floatx80 FP1_to_floatx80(CPUM68KState *env) return (floatx80){ .low =3D env->fp1l, .high =3D env->fp1h }; } =20 +static void floatx80_to_FP1(CPUM68KState *env, floatx80 res) +{ + env->fp1l =3D res.low; + env->fp1h =3D res.high; +} + void HELPER(exts32_FP0)(CPUM68KState *env) { floatx80 res; @@ -949,3 +955,18 @@ void HELPER(cos_FP0)(CPUM68KState *env) res =3D ldouble_to_floatx80(val); floatx80_to_FP0(env, res); } + +void HELPER(sincos_FP0_FP1)(CPUM68KState *env) +{ + floatx80 res; + long double val, valsin, valcos; + + val =3D floatx80_to_ldouble(FP0_to_floatx80(env)); + + sincosl(val, &valsin, &valcos); + res =3D ldouble_to_floatx80(valsin); + floatx80_to_FP0(env, res); + res =3D ldouble_to_floatx80(valcos); + floatx80_to_FP1(env, res); + +} diff --git a/target/m68k/helper.h b/target/m68k/helper.h index 600a9a6..16f3370 100644 --- a/target/m68k/helper.h +++ b/target/m68k/helper.h @@ -69,6 +69,7 @@ DEF_HELPER_1(log10_FP0, void, env) DEF_HELPER_1(cosh_FP0, void, env) DEF_HELPER_1(acos_FP0, void, env) DEF_HELPER_1(cos_FP0, void, env) +DEF_HELPER_1(sincos_FP0_FP1, void, env) =20 DEF_HELPER_3(mac_move, void, env, i32, i32) DEF_HELPER_3(macmulf, i64, env, i32, i32) diff --git a/target/m68k/translate.c b/target/m68k/translate.c index 7af88a2..cb4d9ce 100644 --- a/target/m68k/translate.c +++ b/target/m68k/translate.c @@ -923,6 +923,14 @@ static void gen_op_load_fpr_FP1(int freg) offsetof(CPUM68KState, fregs[freg].l.lower)); } =20 +static void gen_op_store_fpr_FP1(int freg) +{ + tcg_gen_st16_i32(QREG_FP1H, cpu_env, + offsetof(CPUM68KState, fregs[freg].l.upper)); + tcg_gen_st_i64(QREG_FP1L, cpu_env, + offsetof(CPUM68KState, fregs[freg].l.lower)); +} + static void gen_extend_FP0(int opsize) { switch (opsize) { @@ -4773,6 +4781,13 @@ DISAS_INSN(fpu) gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_dsub_FP0_FP1(cpu_env); break; + case 0x30: case 0x31: case 0x32: + case 0x33: case 0x34: case 0x35: + case 0x36: case 0x37: + gen_helper_sincos_FP0_FP1(cpu_env); + gen_op_store_fpr_FP0(REG(ext, 7)); /* sin */ + gen_op_store_fpr_FP1(REG(ext, 0)); /* cos */ + break; case 0x38: /* fcmp */ gen_op_load_fpr_FP1(REG(ext, 7)); gen_helper_cmp_FP0_FP1(cpu_env); --=20 2.9.3