From nobody Wed Nov 5 18:40:06 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1536358189697142.90735263447414; Fri, 7 Sep 2018 15:09:49 -0700 (PDT) Received: from localhost ([::1]:40492 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fyOwm-0005L1-2T for importer@patchew.org; Fri, 07 Sep 2018 18:09:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39147) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fyOuo-0003wS-Er for qemu-devel@nongnu.org; Fri, 07 Sep 2018 18:07:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fyOui-0005Qw-Es for qemu-devel@nongnu.org; Fri, 07 Sep 2018 18:07:46 -0400 Received: from out1-smtp.messagingengine.com ([66.111.4.25]:36211) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fyOui-0005P6-2X for qemu-devel@nongnu.org; Fri, 07 Sep 2018 18:07:40 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 9644121D2E; Fri, 7 Sep 2018 18:07:39 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Fri, 07 Sep 2018 18:07:39 -0400 Received: from localhost (flamenco.cs.columbia.edu [128.59.20.216]) by mail.messagingengine.com (Postfix) with ESMTPA id D8BF11029C; Fri, 7 Sep 2018 18:07:38 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=braap.org; h=cc :date:from:in-reply-to:message-id:references:subject:to :x-me-sender:x-me-sender:x-sasl-enc; s=mesmtp; bh=MGRASzAz/Txinm MxiLBMrML/TTPNyu7gIyUZjz8O4Eo=; b=Aw7lRQtL6XPobESVCVMJRSzHxYy85H qVgCdwDRmoTL1FhuNPW4vs3n9ZrE+AKf0ttgmTjC5npT4VpXTrgzj5rBgYh4fbmC VKjC0wjeo1lHQBAqTmU9Koa1/4dQPibH4tqMz6qoTqA5M21MbP8jtPAeXM0s8mBm c3y1Coe91UNjU= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:date:from:in-reply-to:message-id :references:subject:to:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=MGRASzAz/TxinmMxiLBMrML/TTPNyu7gIyUZjz8O4Eo=; b=UwKhYEpA XjF8M0bUXlS65sgdUB42oGKU0+GrkLAc8wLkpwZcmoK2Il8pfj7/SWHF8SFZTe5S pUEB/WoPeeLRw6ZsLwL2Jh6kTfGZukMBbq6vIs1UrIxWY+I6Smlv7JUK1ASP+wVe WUr+Jd9Q8LTMP28SMAKYLkWnMAnN6Dx+yKRTi8g9DPgKDZNocOLzYFdMevu01Si/ MDme7YrRCUWlPad0nAMAsJQBEdywpIeKLXkPvY500Im+07AB8+jLF+c1JkXdqApN TnRvr4UMKeJP1kDxreE3YH9O9jyUijkZdMM/6gRrNoRerJjHpHzKSuxlnmSXRC5+ 4hkrGAG4WsT2zA== X-ME-Proxy: X-ME-Sender: From: "Emilio G. Cota" To: qemu-devel@nongnu.org Date: Fri, 7 Sep 2018 18:07:31 -0400 Message-Id: <20180907220731.19368-3-cota@braap.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180907220731.19368-1-cota@braap.org> References: <20180907220731.19368-1-cota@braap.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 66.111.4.25 Subject: [Qemu-devel] [PATCH 2/2] tests: add floating point tests 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: =?UTF-8?q?Alex=20Benn=C3=A9e?= , Peter Maydell , Richard Henderson , Laurent Vivier , Aurelien Jarno 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" By leveraging berkeley's softfloat and testfloat. fp-test.c is derived from testfloat's testsoftfloat.c. To ease the tracking of upstream changes to the latter file, fp-test.c keeps the original camel-case variable naming, and includes most new code via wrap.inc.c. Most changes to the original code are simple style changes, although a few hacks have been added because our implementation does not provide exactly the same features as softfloat. I've noted these hacks with XXX comments. Signed-off-by: Emilio G. Cota --- configure | 2 + tests/fp/platform.h | 41 ++ tests/fp/fp-test.c | 1052 ++++++++++++++++++++++++++++++++++++++++ tests/fp/wrap.inc.c | 599 +++++++++++++++++++++++ tests/Makefile.include | 3 + tests/fp/.gitignore | 1 + tests/fp/Makefile | 589 ++++++++++++++++++++++ 7 files changed, 2287 insertions(+) create mode 100644 tests/fp/platform.h create mode 100644 tests/fp/fp-test.c create mode 100644 tests/fp/wrap.inc.c create mode 100644 tests/fp/.gitignore create mode 100644 tests/fp/Makefile diff --git a/configure b/configure index 58862d2ae8..b02da8c0b4 100755 --- a/configure +++ b/configure @@ -7451,12 +7451,14 @@ fi =20 # build tree in object directory in case the source is not in the current = directory DIRS=3D"tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/q= api-schema tests/tcg/xtensa tests/qemu-iotests tests/vm" +DIRS=3D"$DIRS tests/fp" DIRS=3D"$DIRS docs docs/interop fsdev scsi" DIRS=3D"$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw" DIRS=3D"$DIRS roms/seabios roms/vgabios" FILES=3D"Makefile tests/tcg/Makefile qdict-test-data.txt" FILES=3D"$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit" FILES=3D"$FILES tests/tcg/lm32/Makefile tests/tcg/xtensa/Makefile po/Makef= ile" +FILES=3D"$FILES tests/fp/Makefile" FILES=3D"$FILES pc-bios/optionrom/Makefile pc-bios/keymaps" FILES=3D"$FILES pc-bios/spapr-rtas/Makefile" FILES=3D"$FILES pc-bios/s390-ccw/Makefile" diff --git a/tests/fp/platform.h b/tests/fp/platform.h new file mode 100644 index 0000000000..80af8a94b6 --- /dev/null +++ b/tests/fp/platform.h @@ -0,0 +1,41 @@ +#ifndef QEMU_TESTFLOAT_PLATFORM_H +#define QEMU_TESTFLOAT_PLATFORM_H +/* + * Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Regents of the Univers= ity of + * California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are = met: + * + * 1. Redistributions of source code must retain the above copyright noti= ce, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright n= otice, + * this list of conditions, and the following disclaimer in the docume= ntation + * and/or other materials provided with the distribution. + * + * 3. Neither the name of the University nor the names of its contributor= s may + * be used to endorse or promote products derived from this software w= ithout + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND = ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLI= ED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FO= R ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMA= GES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERV= ICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED= AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR T= ORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE O= F THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "config-host.h" + +#ifndef HOST_WORDS_BIGENDIAN +#define LITTLEENDIAN 1 +/* otherwise do not define it */ +#endif + +#define INLINE static inline + +#endif /* QEMU_TESTFLOAT_PLATFORM_H */ diff --git a/tests/fp/fp-test.c b/tests/fp/fp-test.c new file mode 100644 index 0000000000..58405fdd89 --- /dev/null +++ b/tests/fp/fp-test.c @@ -0,0 +1,1052 @@ +/* + * fp-test.c - test QEMU's softfloat implementation using Berkeley's Testf= loat + * + * Derived from testfloat/source/testsoftfloat.c. + * + * Copyright (C) 2018, Emilio G. Cota + * Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017 The Regents of the + * University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are = met: + * + * 1. Redistributions of source code must retain the above copyright noti= ce, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright n= otice, + * this list of conditions, and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the University nor the names of its contributor= s may + * be used to endorse or promote products derived from this software w= ithout + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND = ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLI= ED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FO= R ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMA= GES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERV= ICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED= AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR T= ORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE O= F THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef HW_POISON_H +#error Must define HW_POISON_H to work around TARGET_* poisoning +#endif + +#include "qemu/osdep.h" +#include "qemu/cutils.h" +#include +#include "fpu/softfloat.h" +#include "platform.h" + +#include "fail.h" +#include "slowfloat.h" +#include "functions.h" +#include "genCases.h" +#include "verCases.h" +#include "writeCase.h" +#include "testLoops.h" + +/* keep most code separate to make tracking upstream changes more easily */ +#include "wrap.inc.c" + +enum { + EXACT_FALSE =3D 1, + EXACT_TRUE +}; + +static void catchSIGINT(int signalCode) +{ + if (verCases_stop) { + exit(EXIT_FAILURE); + } + verCases_stop =3D true; +} + +static void +testFunctionInstance(int functionCode, uint_fast8_t roundingMode, bool exa= ct) +{ + float16_t (*trueFunction_abz_f16)(float16_t, float16_t); + float16_t (*subjFunction_abz_f16)(float16_t, float16_t); + bool (*trueFunction_ab_f16_z_bool)(float16_t, float16_t); + bool (*subjFunction_ab_f16_z_bool)(float16_t, float16_t); + float32_t (*trueFunction_abz_f32)(float32_t, float32_t); + float32_t (*subjFunction_abz_f32)(float32_t, float32_t); + bool (*trueFunction_ab_f32_z_bool)(float32_t, float32_t); + bool (*subjFunction_ab_f32_z_bool)(float32_t, float32_t); + float64_t (*trueFunction_abz_f64)(float64_t, float64_t); + float64_t (*subjFunction_abz_f64)(float64_t, float64_t); + bool (*trueFunction_ab_f64_z_bool)(float64_t, float64_t); + bool (*subjFunction_ab_f64_z_bool)(float64_t, float64_t); + void (*trueFunction_abz_extF80M)( + const extFloat80_t *, const extFloat80_t *, extFloat80_t *); + void (*subjFunction_abz_extF80M)( + const extFloat80_t *, const extFloat80_t *, extFloat80_t *); + bool (*trueFunction_ab_extF80M_z_bool)( + const extFloat80_t *, const extFloat80_t *); + bool (*subjFunction_ab_extF80M_z_bool)( + const extFloat80_t *, const extFloat80_t *); + void (*trueFunction_abz_f128M)( + const float128_t *, const float128_t *, float128_t *); + void (*subjFunction_abz_f128M)( + const float128_t *, const float128_t *, float128_t *); + bool (*trueFunction_ab_f128M_z_bool)( + const float128_t *, const float128_t *); + bool (*subjFunction_ab_f128M_z_bool)( + const float128_t *, const float128_t *); + + fputs("Testing ", stderr); + verCases_writeFunctionName(stderr); + fputs(".\n", stderr); + + switch (functionCode) { + /*----------------------------------------------------------------= ---- + *----------------------------------------------------------------= ----*/ + case UI32_TO_F16: + test_a_ui32_z_f16(slow_ui32_to_f16, qemu_ui32_to_f16); + break; + case UI32_TO_F32: + test_a_ui32_z_f32(slow_ui32_to_f32, qemu_ui32_to_f32); + break; + case UI32_TO_F64: + test_a_ui32_z_f64(slow_ui32_to_f64, qemu_ui32_to_f64); + break; + case UI32_TO_EXTF80: + /* not implemented */ + break; + case UI32_TO_F128: + /* not implemented */ + break; + case UI64_TO_F16: + test_a_ui64_z_f16(slow_ui64_to_f16, qemu_ui64_to_f16); + break; + case UI64_TO_F32: + test_a_ui64_z_f32(slow_ui64_to_f32, qemu_ui64_to_f32); + break; + case UI64_TO_F64: + test_a_ui64_z_f64(slow_ui64_to_f64, qemu_ui64_to_f64); + break; + case UI64_TO_EXTF80: + /* not implemented */ + break; + case UI64_TO_F128: + test_a_ui64_z_f128(slow_ui64_to_f128M, qemu_ui64_to_f128M); + break; + case I32_TO_F16: + test_a_i32_z_f16(slow_i32_to_f16, qemu_i32_to_f16); + break; + case I32_TO_F32: + test_a_i32_z_f32(slow_i32_to_f32, qemu_i32_to_f32); + break; + case I32_TO_F64: + test_a_i32_z_f64(slow_i32_to_f64, qemu_i32_to_f64); + break; + case I32_TO_EXTF80: + test_a_i32_z_extF80(slow_i32_to_extF80M, qemu_i32_to_extF80M); + break; + case I32_TO_F128: + test_a_i32_z_f128(slow_i32_to_f128M, qemu_i32_to_f128M); + break; + case I64_TO_F16: + test_a_i64_z_f16(slow_i64_to_f16, qemu_i64_to_f16); + break; + case I64_TO_F32: + test_a_i64_z_f32(slow_i64_to_f32, qemu_i64_to_f32); + break; + case I64_TO_F64: + test_a_i64_z_f64(slow_i64_to_f64, qemu_i64_to_f64); + break; + case I64_TO_EXTF80: + test_a_i64_z_extF80(slow_i64_to_extF80M, qemu_i64_to_extF80M); + break; + case I64_TO_F128: + test_a_i64_z_f128(slow_i64_to_f128M, qemu_i64_to_f128M); + break; + /*----------------------------------------------------------------= ---- + *----------------------------------------------------------------= ----*/ + case F16_TO_UI32: + test_a_f16_z_ui32_rx( + slow_f16_to_ui32, qemu_f16_to_ui32, roundingMode, exact); + break; + case F16_TO_UI64: + test_a_f16_z_ui64_rx( + slow_f16_to_ui64, qemu_f16_to_ui64, roundingMode, exact); + break; + case F16_TO_I32: + test_a_f16_z_i32_rx( + slow_f16_to_i32, qemu_f16_to_i32, roundingMode, exact); + break; + case F16_TO_I64: + test_a_f16_z_i64_rx( + slow_f16_to_i64, qemu_f16_to_i64, roundingMode, exact); + break; + case F16_TO_UI32_R_MINMAG: + /* not implemented */ + break; + case F16_TO_UI64_R_MINMAG: + /* not implemented */ + break; + case F16_TO_I32_R_MINMAG: + /* not implemented */ + break; + case F16_TO_I64_R_MINMAG: + /* not implemented */ + break; + case F16_TO_F32: + test_a_f16_z_f32(slow_f16_to_f32, qemu_f16_to_f32); + break; + case F16_TO_F64: + test_a_f16_z_f64(slow_f16_to_f64, qemu_f16_to_f64); + break; + case F16_TO_EXTF80: + /* not implemented */ + break; + case F16_TO_F128: + /* not implemented */ + break; + case F16_ROUNDTOINT: + test_az_f16_rx( + slow_f16_roundToInt, qemu_f16_roundToInt, roundingMode, exact); + break; + case F16_ADD: + trueFunction_abz_f16 =3D slow_f16_add; + subjFunction_abz_f16 =3D qemu_f16_add; + goto test_abz_f16; + case F16_SUB: + trueFunction_abz_f16 =3D slow_f16_sub; + subjFunction_abz_f16 =3D qemu_f16_sub; + goto test_abz_f16; + case F16_MUL: + trueFunction_abz_f16 =3D slow_f16_mul; + subjFunction_abz_f16 =3D qemu_f16_mul; + goto test_abz_f16; + case F16_DIV: + trueFunction_abz_f16 =3D slow_f16_div; + subjFunction_abz_f16 =3D qemu_f16_div; + goto test_abz_f16; + case F16_REM: + /* not implemented */ + break; + test_abz_f16: + test_abz_f16(trueFunction_abz_f16, subjFunction_abz_f16); + break; + case F16_MULADD: + test_abcz_f16(slow_f16_mulAdd, qemu_f16_mulAdd); + break; + case F16_SQRT: + test_az_f16(slow_f16_sqrt, qemu_f16_sqrt); + break; + case F16_EQ: + trueFunction_ab_f16_z_bool =3D slow_f16_eq; + subjFunction_ab_f16_z_bool =3D qemu_f16_eq; + goto test_ab_f16_z_bool; + case F16_LE: + trueFunction_ab_f16_z_bool =3D slow_f16_le; + subjFunction_ab_f16_z_bool =3D qemu_f16_le; + goto test_ab_f16_z_bool; + case F16_LT: + trueFunction_ab_f16_z_bool =3D slow_f16_lt; + subjFunction_ab_f16_z_bool =3D qemu_f16_lt; + goto test_ab_f16_z_bool; + case F16_EQ_SIGNALING: + trueFunction_ab_f16_z_bool =3D slow_f16_eq_signaling; + subjFunction_ab_f16_z_bool =3D qemu_f16_eq_signaling; + goto test_ab_f16_z_bool; + case F16_LE_QUIET: + trueFunction_ab_f16_z_bool =3D slow_f16_le_quiet; + subjFunction_ab_f16_z_bool =3D qemu_f16_le_quiet; + goto test_ab_f16_z_bool; + case F16_LT_QUIET: + trueFunction_ab_f16_z_bool =3D slow_f16_lt_quiet; + subjFunction_ab_f16_z_bool =3D qemu_f16_lt_quiet; + test_ab_f16_z_bool: + test_ab_f16_z_bool( + trueFunction_ab_f16_z_bool, subjFunction_ab_f16_z_bool); + break; + /*----------------------------------------------------------------= ---- + *----------------------------------------------------------------= ----*/ + case F32_TO_UI32: + test_a_f32_z_ui32_rx( + slow_f32_to_ui32, qemu_f32_to_ui32, roundingMode, exact); + break; + case F32_TO_UI64: + test_a_f32_z_ui64_rx( + slow_f32_to_ui64, qemu_f32_to_ui64, roundingMode, exact); + break; + case F32_TO_I32: + test_a_f32_z_i32_rx( + slow_f32_to_i32, qemu_f32_to_i32, roundingMode, exact); + break; + case F32_TO_I64: + test_a_f32_z_i64_rx( + slow_f32_to_i64, qemu_f32_to_i64, roundingMode, exact); + break; + case F32_TO_UI32_R_MINMAG: + /* not implemented */ + break; + case F32_TO_UI64_R_MINMAG: + /* not implemented */ + break; + case F32_TO_I32_R_MINMAG: + /* not implemented */ + break; + case F32_TO_I64_R_MINMAG: + /* not implemented */ + break; + case F32_TO_F16: + test_a_f32_z_f16(slow_f32_to_f16, qemu_f32_to_f16); + break; + case F32_TO_F64: + test_a_f32_z_f64(slow_f32_to_f64, qemu_f32_to_f64); + break; + case F32_TO_EXTF80: + test_a_f32_z_extF80(slow_f32_to_extF80M, qemu_f32_to_extF80M); + break; + case F32_TO_F128: + test_a_f32_z_f128(slow_f32_to_f128M, qemu_f32_to_f128M); + break; + case F32_ROUNDTOINT: + test_az_f32_rx( + slow_f32_roundToInt, qemu_f32_roundToInt, roundingMode, exact); + break; + case F32_ADD: + trueFunction_abz_f32 =3D slow_f32_add; + subjFunction_abz_f32 =3D qemu_f32_add; + goto test_abz_f32; + case F32_SUB: + trueFunction_abz_f32 =3D slow_f32_sub; + subjFunction_abz_f32 =3D qemu_f32_sub; + goto test_abz_f32; + case F32_MUL: + trueFunction_abz_f32 =3D slow_f32_mul; + subjFunction_abz_f32 =3D qemu_f32_mul; + goto test_abz_f32; + case F32_DIV: + trueFunction_abz_f32 =3D slow_f32_div; + subjFunction_abz_f32 =3D qemu_f32_div; + goto test_abz_f32; + case F32_REM: + trueFunction_abz_f32 =3D slow_f32_rem; + subjFunction_abz_f32 =3D qemu_f32_rem; + test_abz_f32: + test_abz_f32(trueFunction_abz_f32, subjFunction_abz_f32); + break; + case F32_MULADD: + test_abcz_f32(slow_f32_mulAdd, qemu_f32_mulAdd); + break; + case F32_SQRT: + test_az_f32(slow_f32_sqrt, qemu_f32_sqrt); + break; + case F32_EQ: + trueFunction_ab_f32_z_bool =3D slow_f32_eq; + subjFunction_ab_f32_z_bool =3D qemu_f32_eq; + goto test_ab_f32_z_bool; + case F32_LE: + trueFunction_ab_f32_z_bool =3D slow_f32_le; + subjFunction_ab_f32_z_bool =3D qemu_f32_le; + goto test_ab_f32_z_bool; + case F32_LT: + trueFunction_ab_f32_z_bool =3D slow_f32_lt; + subjFunction_ab_f32_z_bool =3D qemu_f32_lt; + goto test_ab_f32_z_bool; + case F32_EQ_SIGNALING: + trueFunction_ab_f32_z_bool =3D slow_f32_eq_signaling; + subjFunction_ab_f32_z_bool =3D qemu_f32_eq_signaling; + goto test_ab_f32_z_bool; + case F32_LE_QUIET: + trueFunction_ab_f32_z_bool =3D slow_f32_le_quiet; + subjFunction_ab_f32_z_bool =3D qemu_f32_le_quiet; + goto test_ab_f32_z_bool; + case F32_LT_QUIET: + trueFunction_ab_f32_z_bool =3D slow_f32_lt_quiet; + subjFunction_ab_f32_z_bool =3D qemu_f32_lt_quiet; + test_ab_f32_z_bool: + test_ab_f32_z_bool( + trueFunction_ab_f32_z_bool, subjFunction_ab_f32_z_bool); + break; + /*----------------------------------------------------------------= ---- + *----------------------------------------------------------------= ----*/ + case F64_TO_UI32: + test_a_f64_z_ui32_rx( + slow_f64_to_ui32, qemu_f64_to_ui32, roundingMode, exact); + break; + case F64_TO_UI64: + test_a_f64_z_ui64_rx( + slow_f64_to_ui64, qemu_f64_to_ui64, roundingMode, exact); + break; + case F64_TO_I32: + test_a_f64_z_i32_rx( + slow_f64_to_i32, qemu_f64_to_i32, roundingMode, exact); + break; + case F64_TO_I64: + test_a_f64_z_i64_rx( + slow_f64_to_i64, qemu_f64_to_i64, roundingMode, exact); + break; + case F64_TO_UI32_R_MINMAG: + /* not implemented */ + break; + case F64_TO_UI64_R_MINMAG: + /* not implemented */ + break; + case F64_TO_I32_R_MINMAG: + /* not implemented */ + break; + case F64_TO_I64_R_MINMAG: + /* not implemented */ + break; + case F64_TO_F16: + test_a_f64_z_f16(slow_f64_to_f16, qemu_f64_to_f16); + break; + case F64_TO_F32: + test_a_f64_z_f32(slow_f64_to_f32, qemu_f64_to_f32); + break; + case F64_TO_EXTF80: + test_a_f64_z_extF80(slow_f64_to_extF80M, qemu_f64_to_extF80M); + break; + case F64_TO_F128: + test_a_f64_z_f128(slow_f64_to_f128M, qemu_f64_to_f128M); + break; + case F64_ROUNDTOINT: + test_az_f64_rx( + slow_f64_roundToInt, qemu_f64_roundToInt, roundingMode, exact); + break; + case F64_ADD: + trueFunction_abz_f64 =3D slow_f64_add; + subjFunction_abz_f64 =3D qemu_f64_add; + goto test_abz_f64; + case F64_SUB: + trueFunction_abz_f64 =3D slow_f64_sub; + subjFunction_abz_f64 =3D qemu_f64_sub; + goto test_abz_f64; + case F64_MUL: + trueFunction_abz_f64 =3D slow_f64_mul; + subjFunction_abz_f64 =3D qemu_f64_mul; + goto test_abz_f64; + case F64_DIV: + trueFunction_abz_f64 =3D slow_f64_div; + subjFunction_abz_f64 =3D qemu_f64_div; + goto test_abz_f64; + case F64_REM: + trueFunction_abz_f64 =3D slow_f64_rem; + subjFunction_abz_f64 =3D qemu_f64_rem; + test_abz_f64: + test_abz_f64(trueFunction_abz_f64, subjFunction_abz_f64); + break; + case F64_MULADD: + test_abcz_f64(slow_f64_mulAdd, qemu_f64_mulAdd); + break; + case F64_SQRT: + test_az_f64(slow_f64_sqrt, qemu_f64_sqrt); + break; + case F64_EQ: + trueFunction_ab_f64_z_bool =3D slow_f64_eq; + subjFunction_ab_f64_z_bool =3D qemu_f64_eq; + goto test_ab_f64_z_bool; + case F64_LE: + trueFunction_ab_f64_z_bool =3D slow_f64_le; + subjFunction_ab_f64_z_bool =3D qemu_f64_le; + goto test_ab_f64_z_bool; + case F64_LT: + trueFunction_ab_f64_z_bool =3D slow_f64_lt; + subjFunction_ab_f64_z_bool =3D qemu_f64_lt; + goto test_ab_f64_z_bool; + case F64_EQ_SIGNALING: + trueFunction_ab_f64_z_bool =3D slow_f64_eq_signaling; + subjFunction_ab_f64_z_bool =3D qemu_f64_eq_signaling; + goto test_ab_f64_z_bool; + case F64_LE_QUIET: + trueFunction_ab_f64_z_bool =3D slow_f64_le_quiet; + subjFunction_ab_f64_z_bool =3D qemu_f64_le_quiet; + goto test_ab_f64_z_bool; + case F64_LT_QUIET: + trueFunction_ab_f64_z_bool =3D slow_f64_lt_quiet; + subjFunction_ab_f64_z_bool =3D qemu_f64_lt_quiet; + test_ab_f64_z_bool: + test_ab_f64_z_bool( + trueFunction_ab_f64_z_bool, subjFunction_ab_f64_z_bool); + break; + /*----------------------------------------------------------------= ---- + *----------------------------------------------------------------= ----*/ + case EXTF80_TO_UI32: + /* not implemented */ + break; + case EXTF80_TO_UI64: + /* not implemented */ + break; + case EXTF80_TO_I32: + test_a_extF80_z_i32_rx( + slow_extF80M_to_i32, qemu_extF80M_to_i32, roundingMode, exact); + break; + case EXTF80_TO_I64: + test_a_extF80_z_i64_rx( + slow_extF80M_to_i64, qemu_extF80M_to_i64, roundingMode, exact); + break; + case EXTF80_TO_UI32_R_MINMAG: + /* not implemented */ + break; + case EXTF80_TO_UI64_R_MINMAG: + /* not implemented */ + break; + case EXTF80_TO_I32_R_MINMAG: + /* not implemented */ + break; + case EXTF80_TO_I64_R_MINMAG: + /* not implemented */ + break; + case EXTF80_TO_F16: + /* not implemented */ + break; + case EXTF80_TO_F32: + test_a_extF80_z_f32(slow_extF80M_to_f32, qemu_extF80M_to_f32); + break; + case EXTF80_TO_F64: + test_a_extF80_z_f64(slow_extF80M_to_f64, qemu_extF80M_to_f64); + break; + case EXTF80_TO_F128: + test_a_extF80_z_f128(slow_extF80M_to_f128M, qemu_extF80M_to_f128M); + break; + case EXTF80_ROUNDTOINT: + test_az_extF80_rx( + slow_extF80M_roundToInt, qemu_extF80M_roundToInt, roundingMode, ex= act); + break; + case EXTF80_ADD: + trueFunction_abz_extF80M =3D slow_extF80M_add; + subjFunction_abz_extF80M =3D qemu_extF80M_add; + goto test_abz_extF80; + case EXTF80_SUB: + trueFunction_abz_extF80M =3D slow_extF80M_sub; + subjFunction_abz_extF80M =3D qemu_extF80M_sub; + goto test_abz_extF80; + case EXTF80_MUL: + trueFunction_abz_extF80M =3D slow_extF80M_mul; + subjFunction_abz_extF80M =3D qemu_extF80M_mul; + goto test_abz_extF80; + case EXTF80_DIV: + trueFunction_abz_extF80M =3D slow_extF80M_div; + subjFunction_abz_extF80M =3D qemu_extF80M_div; + goto test_abz_extF80; + case EXTF80_REM: + trueFunction_abz_extF80M =3D slow_extF80M_rem; + subjFunction_abz_extF80M =3D qemu_extF80M_rem; + test_abz_extF80: + test_abz_extF80(trueFunction_abz_extF80M, subjFunction_abz_extF80M= ); + break; + case EXTF80_SQRT: + test_az_extF80(slow_extF80M_sqrt, qemu_extF80M_sqrt); + break; + case EXTF80_EQ: + trueFunction_ab_extF80M_z_bool =3D slow_extF80M_eq; + subjFunction_ab_extF80M_z_bool =3D qemu_extF80M_eq; + goto test_ab_extF80_z_bool; + case EXTF80_LE: + trueFunction_ab_extF80M_z_bool =3D slow_extF80M_le; + subjFunction_ab_extF80M_z_bool =3D qemu_extF80M_le; + goto test_ab_extF80_z_bool; + case EXTF80_LT: + trueFunction_ab_extF80M_z_bool =3D slow_extF80M_lt; + subjFunction_ab_extF80M_z_bool =3D qemu_extF80M_lt; + goto test_ab_extF80_z_bool; + case EXTF80_EQ_SIGNALING: + trueFunction_ab_extF80M_z_bool =3D slow_extF80M_eq_signaling; + subjFunction_ab_extF80M_z_bool =3D qemu_extF80M_eq_signaling; + goto test_ab_extF80_z_bool; + case EXTF80_LE_QUIET: + trueFunction_ab_extF80M_z_bool =3D slow_extF80M_le_quiet; + subjFunction_ab_extF80M_z_bool =3D qemu_extF80M_le_quiet; + goto test_ab_extF80_z_bool; + case EXTF80_LT_QUIET: + trueFunction_ab_extF80M_z_bool =3D slow_extF80M_lt_quiet; + subjFunction_ab_extF80M_z_bool =3D qemu_extF80M_lt_quiet; + test_ab_extF80_z_bool: + test_ab_extF80_z_bool( + trueFunction_ab_extF80M_z_bool, subjFunction_ab_extF80M_z_bool); + break; + /*----------------------------------------------------------------= ---- + *----------------------------------------------------------------= ----*/ + case F128_TO_UI32: + /* not implemented */ + break; + case F128_TO_UI64: + test_a_f128_z_ui64_rx( + slow_f128M_to_ui64, qemu_f128M_to_ui64, roundingMode, exact); + break; + case F128_TO_I32: + test_a_f128_z_i32_rx( + slow_f128M_to_i32, qemu_f128M_to_i32, roundingMode, exact); + break; + case F128_TO_I64: + test_a_f128_z_i64_rx( + slow_f128M_to_i64, qemu_f128M_to_i64, roundingMode, exact); + break; + case F128_TO_UI32_R_MINMAG: + /* not implemented */ + break; + case F128_TO_UI64_R_MINMAG: + /* not implemented */ + break; + case F128_TO_I32_R_MINMAG: + /* not implemented */ + break; + case F128_TO_I64_R_MINMAG: + /* not implemented */ + break; + case F128_TO_F16: + /* not implemented */ + break; + case F128_TO_F32: + test_a_f128_z_f32(slow_f128M_to_f32, qemu_f128M_to_f32); + break; + case F128_TO_F64: + test_a_f128_z_f64(slow_f128M_to_f64, qemu_f128M_to_f64); + break; + case F128_TO_EXTF80: + test_a_f128_z_extF80(slow_f128M_to_extF80M, qemu_f128M_to_extF80M); + break; + case F128_ROUNDTOINT: + test_az_f128_rx( + slow_f128M_roundToInt, qemu_f128M_roundToInt, roundingMode, exact); + break; + case F128_ADD: + trueFunction_abz_f128M =3D slow_f128M_add; + subjFunction_abz_f128M =3D qemu_f128M_add; + goto test_abz_f128; + case F128_SUB: + trueFunction_abz_f128M =3D slow_f128M_sub; + subjFunction_abz_f128M =3D qemu_f128M_sub; + goto test_abz_f128; + case F128_MUL: + trueFunction_abz_f128M =3D slow_f128M_mul; + subjFunction_abz_f128M =3D qemu_f128M_mul; + goto test_abz_f128; + case F128_DIV: + trueFunction_abz_f128M =3D slow_f128M_div; + subjFunction_abz_f128M =3D qemu_f128M_div; + goto test_abz_f128; + case F128_REM: + trueFunction_abz_f128M =3D slow_f128M_rem; + subjFunction_abz_f128M =3D qemu_f128M_rem; + test_abz_f128: + test_abz_f128(trueFunction_abz_f128M, subjFunction_abz_f128M); + break; + case F128_MULADD: + /* not implemented */ + break; + case F128_SQRT: + test_az_f128(slow_f128M_sqrt, qemu_f128M_sqrt); + break; + case F128_EQ: + trueFunction_ab_f128M_z_bool =3D slow_f128M_eq; + subjFunction_ab_f128M_z_bool =3D qemu_f128M_eq; + goto test_ab_f128_z_bool; + case F128_LE: + trueFunction_ab_f128M_z_bool =3D slow_f128M_le; + subjFunction_ab_f128M_z_bool =3D qemu_f128M_le; + goto test_ab_f128_z_bool; + case F128_LT: + trueFunction_ab_f128M_z_bool =3D slow_f128M_lt; + subjFunction_ab_f128M_z_bool =3D qemu_f128M_lt; + goto test_ab_f128_z_bool; + case F128_EQ_SIGNALING: + trueFunction_ab_f128M_z_bool =3D slow_f128M_eq_signaling; + subjFunction_ab_f128M_z_bool =3D qemu_f128M_eq_signaling; + goto test_ab_f128_z_bool; + case F128_LE_QUIET: + trueFunction_ab_f128M_z_bool =3D slow_f128M_le_quiet; + subjFunction_ab_f128M_z_bool =3D qemu_f128M_le_quiet; + goto test_ab_f128_z_bool; + case F128_LT_QUIET: + trueFunction_ab_f128M_z_bool =3D slow_f128M_lt_quiet; + subjFunction_ab_f128M_z_bool =3D qemu_f128M_lt_quiet; + test_ab_f128_z_bool: + test_ab_f128_z_bool( + trueFunction_ab_f128M_z_bool, subjFunction_ab_f128M_z_bool); + break; + } + if ((verCases_errorStop && verCases_anyErrors) || verCases_stop) { + verCases_exitWithStatus(); + } +} + +static void +testFunction(int functionCode, uint_fast8_t roundingPrecisionIn, + int roundingCodeIn, int tininessCodeIn, int exactCodeIn) +{ + int functionAttribs; + uint_fast8_t roundingPrecision; + int roundingCode; + uint_fast8_t roundingMode =3D { 0 }; + int exactCode; + bool exact; + int tininessCode; + uint_fast8_t tininessMode; + + functionAttribs =3D functionInfos[functionCode].attribs; + verCases_functionNamePtr =3D functionInfos[functionCode].namePtr; + roundingPrecision =3D 32; + for (;;) { + if (functionAttribs & FUNC_EFF_ROUNDINGPRECISION) { + if (roundingPrecisionIn) { + roundingPrecision =3D roundingPrecisionIn; + } + } else { + roundingPrecision =3D 0; + } + verCases_roundingPrecision =3D roundingPrecision; + if (roundingPrecision) { + slow_extF80_roundingPrecision =3D roundingPrecision; + qsf.floatx80_rounding_precision =3D roundingPrecision; + } + /* XXX: not testing ROUND_ODD */ + for (roundingCode =3D 1; roundingCode < NUM_ROUNDINGMODES - 1; + ++roundingCode) { + if ( + functionAttribs + & (FUNC_ARG_ROUNDINGMODE | FUNC_EFF_ROUNDINGMODE) + ) { + if (roundingCodeIn) { + roundingCode =3D roundingCodeIn; + } + } else { + roundingCode =3D 0; + } + verCases_roundingCode =3D roundingCode; + if (roundingCode) { + roundingMode =3D roundingModes[roundingCode]; + if (functionAttribs & FUNC_EFF_ROUNDINGMODE) { + slowfloat_roundingMode =3D roundingMode; + qsf.float_rounding_mode =3D + softfloat_rounding_to_qemu(roundingMode); + } + } + /* + * XXX not testing EXACT_FALSE + * for (exactCode =3D EXACT_FALSE; exactCode <=3D EXACT_TRUE; + * ++exactCode) + */ + exactCode =3D EXACT_TRUE; + { + if (functionAttribs & FUNC_ARG_EXACT) { + if (exactCodeIn) { + exactCode =3D exactCodeIn; + } + } else { + exactCode =3D 0; + } + exact =3D (exactCode =3D=3D EXACT_TRUE); + verCases_usesExact =3D (exactCode !=3D 0); + verCases_exact =3D exact; + for ( + tininessCode =3D 1; + tininessCode < NUM_TININESSMODES; + ++tininessCode + ) { + if ( + (functionAttribs & FUNC_EFF_TININESSMODE) + || ((functionAttribs + & FUNC_EFF_TININESSMODE_REDUCEDPREC) + && roundingPrecision + && (roundingPrecision < 80)) + ) { + if (tininessCodeIn) { + tininessCode =3D tininessCodeIn; + } + } else { + tininessCode =3D 0; + } + verCases_tininessCode =3D tininessCode; + if (tininessCode) { + tininessMode =3D tininessModes[tininessCode]; + slowfloat_detectTininess =3D tininessMode; + qsf.float_detect_tininess =3D + softfloat_tininess_to_qemu(tininessMode); + } + testFunctionInstance(functionCode, roundingMode, exact= ); + if (tininessCodeIn || !tininessCode) { + break; + } + } + if (exactCodeIn || !exactCode) { + break; + } + } + if (roundingCodeIn || !roundingCode) { + break; + } + } + if (roundingPrecisionIn || !roundingPrecision) { + break; + } + if (roundingPrecision =3D=3D 80) { + break; + } else if (roundingPrecision =3D=3D 64) { + roundingPrecision =3D 80; + } else if (roundingPrecision =3D=3D 32) { + roundingPrecision =3D 64; + } + } + +} + +int main(int argc, char *argv[]) +{ + bool haveFunctionArg; + int functionCode, numOperands; + uint_fast8_t roundingPrecision; + int roundingCode, tininessCode, exactCode; + const char *argPtr; + unsigned long ui; + long i; + int functionMatchAttrib; + struct sigaction sigact; + + /*--------------------------------------------------------------------= ---- + *--------------------------------------------------------------------= ----*/ + fail_programName =3D (char *)"testsoftfloat"; + if (argc <=3D 1) { + goto writeHelpMessage; + } + genCases_setLevel(1); + verCases_maxErrorCount =3D 20; + testLoops_trueFlagsPtr =3D &slowfloat_exceptionFlags; + testLoops_subjFlagsFunction =3D qemu_softfloat_clearExceptionFlags; + haveFunctionArg =3D false; + functionCode =3D 0; + numOperands =3D 0; + roundingPrecision =3D 0; + roundingCode =3D 0; + tininessCode =3D 0; + exactCode =3D 0; + for (;;) { + --argc; + if (!argc) { + break; + } + argPtr =3D *++argv; + if (!argPtr) { + break; + } + if (argPtr[0] =3D=3D '-') { + ++argPtr; + } + if ( + !strcmp(argPtr, "help") || !strcmp(argPtr, "-help") + || !strcmp(argPtr, "h") + ) { + writeHelpMessage: + fputs( + "testsoftfloat [