From patchwork Fri Oct 5 18:01:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 148285 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp758910lji; Fri, 5 Oct 2018 11:07:52 -0700 (PDT) X-Google-Smtp-Source: ACcGV6370bk3z5g/GTfINxoZBBCbJFXhuKJMRZd7gBp4TIZZZUpnOXUX3vsgcv8ObffksjjyB2+W X-Received: by 2002:a0c:c506:: with SMTP id x6-v6mr10025096qvi.154.1538762872422; Fri, 05 Oct 2018 11:07:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538762872; cv=none; d=google.com; s=arc-20160816; b=im0Cm+ZadpE37wyIqoorkQN+86dac6q7l7zF4N0kSpFWk6fB3OaHghVkR5S2clH1L9 aPbSeWsKIEA0QIOKcwuTU0Jg/pf/PZbLmtR/5xQQHrnWszz/xDC70uMHqB3plGaAjind nYywq9E+q6QGKT1MaUas5FcOU5FOReKkjk9Tj8j3PhtpEw91hi39fZt/prr5rpIkwXo4 noK1xlLVaAOx3eNi6RICcBaPLbC57ZuCbZM3x60fudVUdhoz0VJVqHA/3dHMi2Z7EMXG YFh3z42u1Y9ycMIfIx2vT3zgdXbs9WXFgCjklV9+pTw9GvMt5GrrHo6Oy/+saxnSlrui We8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=wtgXuXwbTi5jnIUhc1c7D6B23wTZbvstWyvOoHi0AzI=; b=FgjuECbaUS/68/9Bjn1QX184ngbxB1BJPyXlDn0hZqRKh7/5JyWFzTbLhTvhpfaAkt C6D+4AXxJfTuZFUuRPDdOLRmA7Nnv134b3j55GPzTArVgqv8WIWxfaReNQVFJpb8ueO8 cedDdJi2Rsr7MJNq8YYXIGzRH5CU5kdGPtaq4UVjuzGbx0pX0rc4x5XaMfb0+HIc0Lks HTGnNFwzgfn4x7J/pjudNeQzAN1/fCGS61yy011jZ56T2/TTqaP0GtiUVMwhXu51K9N/ MRKwvpIab3ufRz9dzFsXId2D+jcXA0CVGqvG6A9vXBhDMMJnnA9bVXId7Xmc6FEZKojT RfDw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=AkUCBy6l; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id 1-v6si786098qtn.80.2018.10.05.11.07.52 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 05 Oct 2018 11:07:52 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=AkUCBy6l; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:36408 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UVz-00062v-QI for patch@linaro.org; Fri, 05 Oct 2018 14:07:51 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38470) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UQU-0000Jj-Da for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g8UQT-0003ix-CD for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:10 -0400 Received: from mail-ot1-x32d.google.com ([2607:f8b0:4864:20::32d]:43586) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g8UQT-0003ex-2a for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:09 -0400 Received: by mail-ot1-x32d.google.com with SMTP id e21-v6so13542196otk.10 for ; Fri, 05 Oct 2018 11:02:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wtgXuXwbTi5jnIUhc1c7D6B23wTZbvstWyvOoHi0AzI=; b=AkUCBy6lFhTSuAx8TUYz8XHlnB6IoKV5Jws0pKgXp2S4Xp1ZbNCS+trsec3Rr8DifO R+j3ZWb37nTfqCGVvsqaRRfT+p3ZyhpCzZVfEJkukzivgP9CkYbytGgNIRJB2Ax1vCHy edjIw5AGcrmJdEJHifwd+NLOs6vWt7lRHxQlQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wtgXuXwbTi5jnIUhc1c7D6B23wTZbvstWyvOoHi0AzI=; b=cFPOwylmpdDFo/lgVdIJ9v4mMMQ01NT+x4CCY3D3oOjr/trfqztWruHWkrFEKYhXRX KeShmYMi+Lf3xEcEP8Lyz9tmuV77GCXWiu7mR8qfFiKLYs8NivpZ7IWEfy8YHZyb+OUv OtLcBYOn8xkoxItbU3lcaRtyhGj8BEPLfRZVqUebgTRWUM+8bZCBuVYZ3qwDQhcBQ6te NwCWdWwQy7A/KTxcftzeZ59iqaOYBza9iD8IgFVK/HGkhRrsiYdKqScD8OoGEf6Jdt9c xRTHMkuCL5aYhtVDFc/SozQo5ynwiDmDRcBtoYQ+Td5jZHylIUEv+8xOEqB00cugeast EHMA== X-Gm-Message-State: ABuFfog3HeyaReT7uC/2tAbfCLViOuhcy9m3eVNjXNWy8Cs7Xw0wUncm 0uRaSJgH/pqkSIdylf6xeUaeYUUUaAOpjRkJ1S8= X-Received: by 2002:a9d:9a3:: with SMTP id q32mr6087831otd.252.1538762527903; Fri, 05 Oct 2018 11:02:07 -0700 (PDT) Received: from cloudburst.twiddle.net ([187.217.230.84]) by smtp.gmail.com with ESMTPSA id d37-v6sm2601302otb.0.2018.10.05.11.02.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 05 Oct 2018 11:02:07 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 5 Oct 2018 13:01:54 -0500 Message-Id: <20181005180201.11387-2-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181005180201.11387-1-richard.henderson@linaro.org> References: <20181005180201.11387-1-richard.henderson@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::32d Subject: [Qemu-devel] [PULL 1/8] softfloat: remove float64_trunc_to_int X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, "Emilio G. Cota" Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: "Emilio G. Cota" It has not had users since f83311e476 ("target-m68k: use floatx80 internally", 2017-06-21). Note that no other bit-width has floatX_trunc_to_int. Reviewed-by: Alex Bennée Signed-off-by: Emilio G. Cota Signed-off-by: Richard Henderson --- include/fpu/softfloat.h | 1 - fpu/softfloat.c | 7 ------- 2 files changed, 8 deletions(-) -- 2.17.1 diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h index cc1b58b029..8fd9f9bbae 100644 --- a/include/fpu/softfloat.h +++ b/include/fpu/softfloat.h @@ -535,7 +535,6 @@ float128 float64_to_float128(float64, float_status *status); | Software IEC/IEEE double-precision operations. *----------------------------------------------------------------------------*/ float64 float64_round_to_int(float64, float_status *status); -float64 float64_trunc_to_int(float64, float_status *status); float64 float64_add(float64, float64, float_status *status); float64 float64_sub(float64, float64, float_status *status); float64 float64_mul(float64, float64, float_status *status); diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 59ca356d0e..9405f12a03 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1409,13 +1409,6 @@ float64 float64_round_to_int(float64 a, float_status *s) return float64_round_pack_canonical(pr, s); } -float64 float64_trunc_to_int(float64 a, float_status *s) -{ - FloatParts pa = float64_unpack_canonical(a, s); - FloatParts pr = round_to_int(pa, float_round_to_zero, 0, s); - return float64_round_pack_canonical(pr, s); -} - /* * Returns the result of converting the floating-point value `a' to * the two's complement integer format. The conversion is performed From patchwork Fri Oct 5 18:01:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 148282 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp756629lji; Fri, 5 Oct 2018 11:05:45 -0700 (PDT) X-Google-Smtp-Source: ACcGV63gEJ3WrO+L4dHEnMOSZib1V33LsAcplvYweY9qgIcbXlr2ilHV3/EO1AJvN+M8fkndzCn1 X-Received: by 2002:a37:9f85:: with SMTP id i127-v6mr10217501qke.113.1538762745255; Fri, 05 Oct 2018 11:05:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538762745; cv=none; d=google.com; s=arc-20160816; b=fqZi4TKnnDQMn5i/zOY5PEEuI9QYdFjxBE6ZK6keHZuhJC5gitWZQs9AGXbQyDbcz8 KMq88CmIJE+nBbZbcHASWu6f7nS8vNhgIydxC5wJaJig1GG/A8gjHsqWtk//mPd37Y9E HHaBwNECm3fdJtgADYU8aDyqBABJBUQ8HFTscRXh8WzeC5JZBe7KnuW0C6pIcZjRYcJx vTRcHwNTNd2fr3irbshepcTosMslyiPgaztS90UBkcfRbxjlbqJ+Kclq9ggrAw9A42Z3 Tu49k+jH/lp/Xs/uYeS3jtAIxqhXxtThJkEipUdTg7kd7hjp5z4ujbsAeNONz/K3k3G6 uAmA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=YDY+gm7DBCWRymoZ7sej+qAIJ0qeJxy6UbMX9BzY6Pc=; b=x8WHLLKW1sUzqp3XOq1OV7rCEf9Op9N/d0/2ZGnVcZA075+/yhwrJsNlgjd9cF9KH8 qS96i2k3rNmsmvliTHHdUCVDsbvCxRQgzwpVCb7XKiD5Fc8UFFnBzbhOnylN2I+NenTV HIjsutD6Xfl3wrNLl1nUeeqrQH1cOVRcGGoheR4dBQDOBnrNjLNL0u7CMAHQt4D+U+ij 51YWW72BXTGnDNwwWjIHPCk0X7usZQSVd9RgG7VywjFSRaGMjNEK7AkzmaWiQSKchZzr V3bgxEdyz7dglQP4gtm5ePIbXnFEFXmRY46qab7IfrjgGWQkyFH6LqO+rXBmZN6NZq2/ fkDA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=kRIfJJbc; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id s3-v6si3389403qtd.154.2018.10.05.11.05.45 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 05 Oct 2018 11:05:45 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=kRIfJJbc; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:36399 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UTw-0003vN-JQ for patch@linaro.org; Fri, 05 Oct 2018 14:05:44 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38507) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UQX-0000NC-Q1 for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g8UQU-0003oU-Pn for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:13 -0400 Received: from mail-ot1-x342.google.com ([2607:f8b0:4864:20::342]:44190) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g8UQU-0003lh-Ij for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:10 -0400 Received: by mail-ot1-x342.google.com with SMTP id p23so1882901otf.11 for ; Fri, 05 Oct 2018 11:02:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=YDY+gm7DBCWRymoZ7sej+qAIJ0qeJxy6UbMX9BzY6Pc=; b=kRIfJJbcXbz7EEatrxNN2FXTGEsq1PLjtc043BI5CUK8h4R/t9Vo5lwy7hOCRISeTs a02YcJrZ02hD02vJ1ReGc+K044oQD3poDo8h42b/o2Jj6q9NAChvqVR/RozPMI6rN6hu ujReZFzK7sHy2z3AJfaE8qi9EbIXR44zEfHTE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=YDY+gm7DBCWRymoZ7sej+qAIJ0qeJxy6UbMX9BzY6Pc=; b=ZPb/O3PzgpF04rkIngBb4/NubjOxn6XtsOe8UaW+pepg8ywf8Pu9OxdOE/wVu5tdYf pLi68Xe92JE3HNAmVK2DIR2ruK6CsMfB+W8GWK5+h4/kzDDJoAlShVgww0KcSRQKtVg3 JzaOuyYkK9siiXochHbwEQOtB+DladN1U9H/RQzhuWtz8vf2HVFUqQnZqJDGIANlsTAf oGBTAne7tMQUrUg8NlQ4mk4KTopraFhjYWmiefbsuusUNmdpU8S/9b8QXf5A4CtjaQso FdJf3mDLSeRgcntJG/NxhR1YUienTeo/YmjYUHDmhLyqntjtmzbm2HsTmyqzRoBQEkw9 ceGA== X-Gm-Message-State: ABuFfohT0lbvbwemanZj4muc+TLof5TrrUToxDfu7i4h62LAmUt+I8US kXe996eGplz1Rf2HA5LQGYuvKmW709Fkbd5gfZo= X-Received: by 2002:a9d:2e41:: with SMTP id c1-v6mr7330183otd.271.1538762529557; Fri, 05 Oct 2018 11:02:09 -0700 (PDT) Received: from cloudburst.twiddle.net ([187.217.230.84]) by smtp.gmail.com with ESMTPSA id d37-v6sm2601302otb.0.2018.10.05.11.02.08 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 05 Oct 2018 11:02:08 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 5 Oct 2018 13:01:55 -0500 Message-Id: <20181005180201.11387-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181005180201.11387-1-richard.henderson@linaro.org> References: <20181005180201.11387-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::342 Subject: [Qemu-devel] [PULL 2/8] gitmodules: add berkeley's softfloat + testfloat version 3 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, "Emilio G. Cota" Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: "Emilio G. Cota" These are BSD-licensed so we can add them as submodules. Signed-off-by: Emilio G. Cota Signed-off-by: Richard Henderson --- .gitmodules | 6 ++++++ tests/fp/berkeley-softfloat-3 | 1 + tests/fp/berkeley-testfloat-3 | 1 + 3 files changed, 8 insertions(+) create mode 160000 tests/fp/berkeley-softfloat-3 create mode 160000 tests/fp/berkeley-testfloat-3 -- 2.17.1 diff --git a/.gitmodules b/.gitmodules index d108478e0a..a48d2a764c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -43,3 +43,9 @@ [submodule "roms/u-boot-sam460ex"] path = roms/u-boot-sam460ex url = git://git.qemu.org/u-boot-sam460ex.git +[submodule "tests/fp/berkeley-testfloat-3"] + path = tests/fp/berkeley-testfloat-3 + url = git://github.com/cota/berkeley-testfloat-3 +[submodule "tests/fp/berkeley-softfloat-3"] + path = tests/fp/berkeley-softfloat-3 + url = git://github.com/cota/berkeley-softfloat-3 diff --git a/tests/fp/berkeley-softfloat-3 b/tests/fp/berkeley-softfloat-3 new file mode 160000 index 0000000000..b64af41c32 --- /dev/null +++ b/tests/fp/berkeley-softfloat-3 @@ -0,0 +1 @@ +Subproject commit b64af41c3276f97f0e181920400ee056b9c88037 diff --git a/tests/fp/berkeley-testfloat-3 b/tests/fp/berkeley-testfloat-3 new file mode 160000 index 0000000000..ca9fa2ba05 --- /dev/null +++ b/tests/fp/berkeley-testfloat-3 @@ -0,0 +1 @@ +Subproject commit ca9fa2ba05625ba929958f163b01747e07dd39cc From patchwork Fri Oct 5 18:01:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 148287 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp760442lji; Fri, 5 Oct 2018 11:09:20 -0700 (PDT) X-Google-Smtp-Source: ACcGV63c/bpSWk8Uk6zSP4iYmQE60NHbRWHnwD2dtdGlQeA8RmyOF25UgiA0JZmG+eQxv2DNGi4h X-Received: by 2002:ac8:2963:: with SMTP id z32-v6mr2088861qtz.143.1538762960239; Fri, 05 Oct 2018 11:09:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538762960; cv=none; d=google.com; s=arc-20160816; b=sBugR8iu6nCYsC6q6xBsOsO37NwO114PesP0mcgN2wNSIHqT0uZ/4hmRk/NihnmZd0 kofCe+f5S2cdVMlvgvIGc9PIYZLslvi9nIWWJVGnNaVljBUxBtPEYXy5/aC9oy9K/N62 VCSU/EVLzHdLCxdv3MNA3gUGgEa0EVS2QS22pu3ddpu/Old9TTY0dHtYBnACXthHjapU JtLLKrxiQfknkL4FPYi0jzrG46QnlcF7EGVBju/FIL6mFBUaP8alWQS7l8kccBRe+zEx 7DFzgrnkjAsjnNKEkdOJq1cLamsAACAg6blT9KYZ4L2W9VsxtvxNZvI9laDSkwXW3oru AAaw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=ifVe5R2cY4KA83ygwDNNBQ3uA1mnVMIrh78jVGZ0edc=; b=qDQiP5FZgELO2ILe+f92wlw+R6cLdo6ezeoGxjJGZI4YJN8NJKcfwcLjsqQxpshF5f 4M15pI2llyJy0b6wNDMmBDXxiQA1Y14AJeS413X08bQ8i99z/WzJfNLY0Y8yPHoMpqEX wVvYYWuhyH1gOLhdAI0H2spLkyW9oW9Wxsa1Ee4Bdq2l3B7NUiX5yKJjIoQ9eqXH4NhR HKznLL9WRz4HEbx+hT+ZfcikJglcG8NaGbGkYBjLc487T+FaV5W86sb00AkqPrCLr5wu LBMZ0bgRVejb0JuB62AMuqPbe0Di945xn5Lj7JATX/dLK+AkRXI2SQXZd0oHZ8PF9Xcv U7eQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=CcBG5fL1; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id o62-v6si6251912qkl.147.2018.10.05.11.09.19 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 05 Oct 2018 11:09:20 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=CcBG5fL1; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:36412 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UXP-0007jt-DK for patch@linaro.org; Fri, 05 Oct 2018 14:09:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38625) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UQg-0000Wu-DL for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g8UQZ-0004CC-7V for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:22 -0400 Received: from mail-oi1-x243.google.com ([2607:f8b0:4864:20::243]:45551) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g8UQY-00045D-L2 for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:15 -0400 Received: by mail-oi1-x243.google.com with SMTP id e17-v6so11080552oig.12 for ; Fri, 05 Oct 2018 11:02:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ifVe5R2cY4KA83ygwDNNBQ3uA1mnVMIrh78jVGZ0edc=; b=CcBG5fL1YPoT9HFvz9oJomjTxfw8y67AIT00xEymhh5UBLUX9DR0B4eyTS39CY6sIA l6oZ1b4xLqjNaPxrPYaGfYfY8hDFlCAeHrd4eF5dM8g7AUaumBX//+iBblkJ7vxj1IjE 2fuu+xmIuakJt+XrdrKsGy6RYw9+5FhP+XnQo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ifVe5R2cY4KA83ygwDNNBQ3uA1mnVMIrh78jVGZ0edc=; b=OHZrOOMshwX7G7TCjski+6Tf8SYUgPKPlA4SIzdz+nHB2GDb18DFY+bjybUW5DjSDf baIZUBXvXEA7ITeftp/OEO6Sj48CQavfZcJJiHxWMjdgDHUkKeFQ7ZaeCsBDCaYIRY5t adtTrJ6+dmFevaZQhSHeFN02K06Z6YsTemSIgJw2YiarRTgDbPB0NSP26RlNtfJCiyvo CLZPAr17FBiF1E3PhWaw9a/w4zOhDmYWDZ7R3soTeBcCvx9pKEGVIQCPTgwSWxBvOVZz Gfvti4QCR+E0pKjiD5krCJk2faJr/Y9pF2FV3JRloPg0knc/VScmaLyDtiP5pA2ysikc CrSw== X-Gm-Message-State: ABuFfoiEiGJQhsfdiLU4cWD2bSRoIf3gskNHtW4OJ2vdU80kz+dN6tH4 E+mcnWMSnl0LlfPjjuL+CZCU8lsnk1potYSlaOo= X-Received: by 2002:aca:240b:: with SMTP id n11-v6mr39660oic.174.1538762531751; Fri, 05 Oct 2018 11:02:11 -0700 (PDT) Received: from cloudburst.twiddle.net ([187.217.230.84]) by smtp.gmail.com with ESMTPSA id d37-v6sm2601302otb.0.2018.10.05.11.02.09 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 05 Oct 2018 11:02:10 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 5 Oct 2018 13:01:56 -0500 Message-Id: <20181005180201.11387-4-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181005180201.11387-1-richard.henderson@linaro.org> References: <20181005180201.11387-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::243 Subject: [Qemu-devel] [PULL 3/8] tests/fp/fp-test: 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: peter.maydell@linaro.org, "Emilio G. Cota" Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: "Emilio G. Cota" By leveraging berkeley's softfloat and testfloat. With this we get decent coverage of softfloat.c: $ ./fp-test -r even: 67.22% coverage $ ./fp-test -r all: 73.11% coverage Note that we do not yet test parts of softfloat.c that aren't in the original softfloat library, namely: - denormal inputs - *_to_int16/uint16 conversions - scalbn for fixed point - muladd variants - min/max - exp2 - log2 - float*_compare (except float16_compare) Signed-off-by: Emilio G. Cota [rth: Add the new modules to git_submodules.] Signed-off-by: Richard Henderson --- tests/fp/platform.h | 41 ++ tests/fp/fp-test.c | 992 +++++++++++++++++++++++++++++++++++++++++ tests/fp/wrap.inc.c | 653 +++++++++++++++++++++++++++ configure | 4 + tests/Makefile.include | 3 + tests/fp/.gitignore | 1 + tests/fp/Makefile | 597 +++++++++++++++++++++++++ 7 files changed, 2291 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 -- 2.17.1 diff --git a/tests/fp/platform.h b/tests/fp/platform.h new file mode 100644 index 0000000000..c20ba70baa --- /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 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 notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * 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 contributors may + * be used to endorse or promote products derived from this software without + * 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 IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 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..fca576309c --- /dev/null +++ b/tests/fp/fp-test.c @@ -0,0 +1,992 @@ +/* + * fp-test.c - test QEMU's softfloat implementation using Berkeley's Testfloat + * + * Copyright (C) 2018, Emilio G. Cota + * + * License: GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * This file is derived from testfloat/source/testsoftfloat.c. Its copyright + * info follows: + * + * 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 notice, + * this list of conditions, and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * 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 contributors may + * be used to endorse or promote products derived from this software without + * 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 IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 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" + +typedef float16_t (*abz_f16)(float16_t, float16_t); +typedef bool (*ab_f16_z_bool)(float16_t, float16_t); +typedef float32_t (*abz_f32)(float32_t, float32_t); +typedef bool (*ab_f32_z_bool)(float32_t, float32_t); +typedef float64_t (*abz_f64)(float64_t, float64_t); +typedef bool (*ab_f64_z_bool)(float64_t, float64_t); +typedef void (*abz_extF80M)(const extFloat80_t *, const extFloat80_t *, + extFloat80_t *); +typedef bool (*ab_extF80M_z_bool)(const extFloat80_t *, const extFloat80_t *); +typedef void (*abz_f128M)(const float128_t *, const float128_t *, float128_t *); +typedef bool (*ab_f128M_z_bool)(const float128_t *, const float128_t *); + +static const char * const round_mode_names[] = { + [ROUND_NEAR_EVEN] = "even", + [ROUND_MINMAG] = "zero", + [ROUND_MIN] = "down", + [ROUND_MAX] = "up", + [ROUND_NEAR_MAXMAG] = "tieaway", + [ROUND_ODD] = "odd", +}; +static unsigned int *test_ops; +static unsigned int n_test_ops; +static unsigned int n_max_errors = 20; +static unsigned int test_round_mode = ROUND_NEAR_EVEN; +static unsigned int *round_modes; +static unsigned int n_round_modes; +static int test_level = 1; +static uint8_t slow_init_flags; +static uint8_t qemu_init_flags; + +/* qemu softfloat status */ +static float_status qsf; + +static const char commands_string[] = + "operations:\n" + " _to_ _add _eq\n" + " _to_ _sub _le\n" + " _to__r_minMag _mul _lt\n" + " _to_ _mulAdd _eq_signaling\n" + " _roundToInt _div _le_quiet\n" + " _rem _lt_quiet\n" + " _sqrt\n" + " Where : ui32, ui64, i32, i64\n" + " : f16, f32, f64, extF80, f128\n" + " If no operation is provided, all the above are tested\n" + "options:\n" + " -e = max error count per test. Default: 20. Set no limit with 0\n" + " -f = initial FP exception flags (vioux). Default: none\n" + " -l = thoroughness level (1 (default), 2)\n" + " -r = rounding mode (even (default), zero, down, up, tieaway, odd)\n" + " Set to 'all' to test all rounding modes, if applicable\n" + " -s = stop when a test fails"; + +static void usage_complete(int argc, char *argv[]) +{ + fprintf(stderr, "Usage: %s [options] [operation1 ...]\n", argv[0]); + fprintf(stderr, "%s\n", commands_string); + exit(EXIT_FAILURE); +} + +/* keep wrappers separate but do not bother defining headers for all of them */ +#include "wrap.inc.c" + +static void not_implemented(void) +{ + fprintf(stderr, "Not implemented.\n"); +} + +static bool blacklisted(unsigned op, int rmode) +{ + /* odd has only been implemented for a few 128-bit ops */ + if (rmode == softfloat_round_odd) { + switch (op) { + case F128_ADD: + case F128_SUB: + case F128_MUL: + case F128_DIV: + case F128_TO_F64: + case F128_SQRT: + return false; + default: + return true; + } + } + return false; +} + +static void do_testfloat(int op, int rmode, bool exact) +{ + abz_f16 true_abz_f16; + abz_f16 subj_abz_f16; + ab_f16_z_bool true_f16_z_bool; + ab_f16_z_bool subj_f16_z_bool; + abz_f32 true_abz_f32; + abz_f32 subj_abz_f32; + ab_f32_z_bool true_ab_f32_z_bool; + ab_f32_z_bool subj_ab_f32_z_bool; + abz_f64 true_abz_f64; + abz_f64 subj_abz_f64; + ab_f64_z_bool true_ab_f64_z_bool; + ab_f64_z_bool subj_ab_f64_z_bool; + abz_extF80M true_abz_extF80M; + abz_extF80M subj_abz_extF80M; + ab_extF80M_z_bool true_ab_extF80M_z_bool; + ab_extF80M_z_bool subj_ab_extF80M_z_bool; + abz_f128M true_abz_f128M; + abz_f128M subj_abz_f128M; + ab_f128M_z_bool true_ab_f128M_z_bool; + ab_f128M_z_bool subj_ab_f128M_z_bool; + + fputs(">> Testing ", stderr); + verCases_writeFunctionName(stderr); + fputs("\n", stderr); + + if (blacklisted(op, rmode)) { + not_implemented(); + return; + } + + switch (op) { + 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, rmode, exact); + break; + case F16_TO_UI64: + test_a_f16_z_ui64_rx(slow_f16_to_ui64, qemu_f16_to_ui64, rmode, exact); + break; + case F16_TO_I32: + test_a_f16_z_i32_rx(slow_f16_to_i32, qemu_f16_to_i32, rmode, exact); + break; + case F16_TO_I64: + test_a_f16_z_i64_rx(slow_f16_to_i64, qemu_f16_to_i64, rmode, exact); + break; + case F16_TO_UI32_R_MINMAG: + test_a_f16_z_ui32_x(slow_f16_to_ui32_r_minMag, + qemu_f16_to_ui32_r_minMag, exact); + break; + case F16_TO_UI64_R_MINMAG: + test_a_f16_z_ui64_x(slow_f16_to_ui64_r_minMag, + qemu_f16_to_ui64_r_minMag, exact); + break; + case F16_TO_I32_R_MINMAG: + test_a_f16_z_i32_x(slow_f16_to_i32_r_minMag, qemu_f16_to_i32_r_minMag, + exact); + break; + case F16_TO_I64_R_MINMAG: + test_a_f16_z_i64_x(slow_f16_to_i64_r_minMag, qemu_f16_to_i64_r_minMag, + exact); + 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, rmode, exact); + break; + case F16_ADD: + true_abz_f16 = slow_f16_add; + subj_abz_f16 = qemu_f16_add; + goto test_abz_f16; + case F16_SUB: + true_abz_f16 = slow_f16_sub; + subj_abz_f16 = qemu_f16_sub; + goto test_abz_f16; + case F16_MUL: + true_abz_f16 = slow_f16_mul; + subj_abz_f16 = qemu_f16_mul; + goto test_abz_f16; + case F16_DIV: + true_abz_f16 = slow_f16_div; + subj_abz_f16 = qemu_f16_div; + goto test_abz_f16; + case F16_REM: + not_implemented(); + break; + test_abz_f16: + test_abz_f16(true_abz_f16, subj_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: + true_f16_z_bool = slow_f16_eq; + subj_f16_z_bool = qemu_f16_eq; + goto test_ab_f16_z_bool; + case F16_LE: + true_f16_z_bool = slow_f16_le; + subj_f16_z_bool = qemu_f16_le; + goto test_ab_f16_z_bool; + case F16_LT: + true_f16_z_bool = slow_f16_lt; + subj_f16_z_bool = qemu_f16_lt; + goto test_ab_f16_z_bool; + case F16_EQ_SIGNALING: + true_f16_z_bool = slow_f16_eq_signaling; + subj_f16_z_bool = qemu_f16_eq_signaling; + goto test_ab_f16_z_bool; + case F16_LE_QUIET: + true_f16_z_bool = slow_f16_le_quiet; + subj_f16_z_bool = qemu_f16_le_quiet; + goto test_ab_f16_z_bool; + case F16_LT_QUIET: + true_f16_z_bool = slow_f16_lt_quiet; + subj_f16_z_bool = qemu_f16_lt_quiet; + test_ab_f16_z_bool: + test_ab_f16_z_bool(true_f16_z_bool, subj_f16_z_bool); + break; + case F32_TO_UI32: + test_a_f32_z_ui32_rx(slow_f32_to_ui32, qemu_f32_to_ui32, rmode, exact); + break; + case F32_TO_UI64: + test_a_f32_z_ui64_rx(slow_f32_to_ui64, qemu_f32_to_ui64, rmode, exact); + break; + case F32_TO_I32: + test_a_f32_z_i32_rx(slow_f32_to_i32, qemu_f32_to_i32, rmode, exact); + break; + case F32_TO_I64: + test_a_f32_z_i64_rx(slow_f32_to_i64, qemu_f32_to_i64, rmode, exact); + break; + case F32_TO_UI32_R_MINMAG: + test_a_f32_z_ui32_x(slow_f32_to_ui32_r_minMag, + qemu_f32_to_ui32_r_minMag, exact); + break; + case F32_TO_UI64_R_MINMAG: + test_a_f32_z_ui64_x(slow_f32_to_ui64_r_minMag, + qemu_f32_to_ui64_r_minMag, exact); + break; + case F32_TO_I32_R_MINMAG: + test_a_f32_z_i32_x(slow_f32_to_i32_r_minMag, qemu_f32_to_i32_r_minMag, + exact); + break; + case F32_TO_I64_R_MINMAG: + test_a_f32_z_i64_x(slow_f32_to_i64_r_minMag, qemu_f32_to_i64_r_minMag, + exact); + 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, rmode, exact); + break; + case F32_ADD: + true_abz_f32 = slow_f32_add; + subj_abz_f32 = qemu_f32_add; + goto test_abz_f32; + case F32_SUB: + true_abz_f32 = slow_f32_sub; + subj_abz_f32 = qemu_f32_sub; + goto test_abz_f32; + case F32_MUL: + true_abz_f32 = slow_f32_mul; + subj_abz_f32 = qemu_f32_mul; + goto test_abz_f32; + case F32_DIV: + true_abz_f32 = slow_f32_div; + subj_abz_f32 = qemu_f32_div; + goto test_abz_f32; + case F32_REM: + true_abz_f32 = slow_f32_rem; + subj_abz_f32 = qemu_f32_rem; + test_abz_f32: + test_abz_f32(true_abz_f32, subj_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: + true_ab_f32_z_bool = slow_f32_eq; + subj_ab_f32_z_bool = qemu_f32_eq; + goto test_ab_f32_z_bool; + case F32_LE: + true_ab_f32_z_bool = slow_f32_le; + subj_ab_f32_z_bool = qemu_f32_le; + goto test_ab_f32_z_bool; + case F32_LT: + true_ab_f32_z_bool = slow_f32_lt; + subj_ab_f32_z_bool = qemu_f32_lt; + goto test_ab_f32_z_bool; + case F32_EQ_SIGNALING: + true_ab_f32_z_bool = slow_f32_eq_signaling; + subj_ab_f32_z_bool = qemu_f32_eq_signaling; + goto test_ab_f32_z_bool; + case F32_LE_QUIET: + true_ab_f32_z_bool = slow_f32_le_quiet; + subj_ab_f32_z_bool = qemu_f32_le_quiet; + goto test_ab_f32_z_bool; + case F32_LT_QUIET: + true_ab_f32_z_bool = slow_f32_lt_quiet; + subj_ab_f32_z_bool = qemu_f32_lt_quiet; + test_ab_f32_z_bool: + test_ab_f32_z_bool(true_ab_f32_z_bool, subj_ab_f32_z_bool); + break; + case F64_TO_UI32: + test_a_f64_z_ui32_rx(slow_f64_to_ui32, qemu_f64_to_ui32, rmode, exact); + break; + case F64_TO_UI64: + test_a_f64_z_ui64_rx(slow_f64_to_ui64, qemu_f64_to_ui64, rmode, exact); + break; + case F64_TO_I32: + test_a_f64_z_i32_rx(slow_f64_to_i32, qemu_f64_to_i32, rmode, exact); + break; + case F64_TO_I64: + test_a_f64_z_i64_rx(slow_f64_to_i64, qemu_f64_to_i64, rmode, exact); + break; + case F64_TO_UI32_R_MINMAG: + test_a_f64_z_ui32_x(slow_f64_to_ui32_r_minMag, + qemu_f64_to_ui32_r_minMag, exact); + break; + case F64_TO_UI64_R_MINMAG: + test_a_f64_z_ui64_x(slow_f64_to_ui64_r_minMag, + qemu_f64_to_ui64_r_minMag, exact); + break; + case F64_TO_I32_R_MINMAG: + test_a_f64_z_i32_x(slow_f64_to_i32_r_minMag, qemu_f64_to_i32_r_minMag, + exact); + break; + case F64_TO_I64_R_MINMAG: + test_a_f64_z_i64_x(slow_f64_to_i64_r_minMag, qemu_f64_to_i64_r_minMag, + exact); + 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, rmode, exact); + break; + case F64_ADD: + true_abz_f64 = slow_f64_add; + subj_abz_f64 = qemu_f64_add; + goto test_abz_f64; + case F64_SUB: + true_abz_f64 = slow_f64_sub; + subj_abz_f64 = qemu_f64_sub; + goto test_abz_f64; + case F64_MUL: + true_abz_f64 = slow_f64_mul; + subj_abz_f64 = qemu_f64_mul; + goto test_abz_f64; + case F64_DIV: + true_abz_f64 = slow_f64_div; + subj_abz_f64 = qemu_f64_div; + goto test_abz_f64; + case F64_REM: + true_abz_f64 = slow_f64_rem; + subj_abz_f64 = qemu_f64_rem; + test_abz_f64: + test_abz_f64(true_abz_f64, subj_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: + true_ab_f64_z_bool = slow_f64_eq; + subj_ab_f64_z_bool = qemu_f64_eq; + goto test_ab_f64_z_bool; + case F64_LE: + true_ab_f64_z_bool = slow_f64_le; + subj_ab_f64_z_bool = qemu_f64_le; + goto test_ab_f64_z_bool; + case F64_LT: + true_ab_f64_z_bool = slow_f64_lt; + subj_ab_f64_z_bool = qemu_f64_lt; + goto test_ab_f64_z_bool; + case F64_EQ_SIGNALING: + true_ab_f64_z_bool = slow_f64_eq_signaling; + subj_ab_f64_z_bool = qemu_f64_eq_signaling; + goto test_ab_f64_z_bool; + case F64_LE_QUIET: + true_ab_f64_z_bool = slow_f64_le_quiet; + subj_ab_f64_z_bool = qemu_f64_le_quiet; + goto test_ab_f64_z_bool; + case F64_LT_QUIET: + true_ab_f64_z_bool = slow_f64_lt_quiet; + subj_ab_f64_z_bool = qemu_f64_lt_quiet; + test_ab_f64_z_bool: + test_ab_f64_z_bool(true_ab_f64_z_bool, subj_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, rmode, + exact); + break; + case EXTF80_TO_I64: + test_a_extF80_z_i64_rx(slow_extF80M_to_i64, qemu_extF80M_to_i64, rmode, + 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: + test_a_extF80_z_i32_x(slow_extF80M_to_i32_r_minMag, + qemu_extF80M_to_i32_r_minMag, exact); + break; + case EXTF80_TO_I64_R_MINMAG: + test_a_extF80_z_i64_x(slow_extF80M_to_i64_r_minMag, + qemu_extF80M_to_i64_r_minMag, exact); + 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, + rmode, exact); + break; + case EXTF80_ADD: + true_abz_extF80M = slow_extF80M_add; + subj_abz_extF80M = qemu_extF80M_add; + goto test_abz_extF80; + case EXTF80_SUB: + true_abz_extF80M = slow_extF80M_sub; + subj_abz_extF80M = qemu_extF80M_sub; + goto test_abz_extF80; + case EXTF80_MUL: + true_abz_extF80M = slow_extF80M_mul; + subj_abz_extF80M = qemu_extF80M_mul; + goto test_abz_extF80; + case EXTF80_DIV: + true_abz_extF80M = slow_extF80M_div; + subj_abz_extF80M = qemu_extF80M_div; + goto test_abz_extF80; + case EXTF80_REM: + true_abz_extF80M = slow_extF80M_rem; + subj_abz_extF80M = qemu_extF80M_rem; + test_abz_extF80: + test_abz_extF80(true_abz_extF80M, subj_abz_extF80M); + break; + case EXTF80_SQRT: + test_az_extF80(slow_extF80M_sqrt, qemu_extF80M_sqrt); + break; + case EXTF80_EQ: + true_ab_extF80M_z_bool = slow_extF80M_eq; + subj_ab_extF80M_z_bool = qemu_extF80M_eq; + goto test_ab_extF80_z_bool; + case EXTF80_LE: + true_ab_extF80M_z_bool = slow_extF80M_le; + subj_ab_extF80M_z_bool = qemu_extF80M_le; + goto test_ab_extF80_z_bool; + case EXTF80_LT: + true_ab_extF80M_z_bool = slow_extF80M_lt; + subj_ab_extF80M_z_bool = qemu_extF80M_lt; + goto test_ab_extF80_z_bool; + case EXTF80_EQ_SIGNALING: + true_ab_extF80M_z_bool = slow_extF80M_eq_signaling; + subj_ab_extF80M_z_bool = qemu_extF80M_eq_signaling; + goto test_ab_extF80_z_bool; + case EXTF80_LE_QUIET: + true_ab_extF80M_z_bool = slow_extF80M_le_quiet; + subj_ab_extF80M_z_bool = qemu_extF80M_le_quiet; + goto test_ab_extF80_z_bool; + case EXTF80_LT_QUIET: + true_ab_extF80M_z_bool = slow_extF80M_lt_quiet; + subj_ab_extF80M_z_bool = qemu_extF80M_lt_quiet; + test_ab_extF80_z_bool: + test_ab_extF80_z_bool(true_ab_extF80M_z_bool, subj_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, rmode, + exact); + break; + case F128_TO_I32: + test_a_f128_z_i32_rx(slow_f128M_to_i32, qemu_f128M_to_i32, rmode, + exact); + break; + case F128_TO_I64: + test_a_f128_z_i64_rx(slow_f128M_to_i64, qemu_f128M_to_i64, rmode, + exact); + break; + case F128_TO_UI32_R_MINMAG: + test_a_f128_z_ui32_x(slow_f128M_to_ui32_r_minMag, + qemu_f128M_to_ui32_r_minMag, exact); + break; + case F128_TO_UI64_R_MINMAG: + test_a_f128_z_ui64_x(slow_f128M_to_ui64_r_minMag, + qemu_f128M_to_ui64_r_minMag, exact); + break; + case F128_TO_I32_R_MINMAG: + test_a_f128_z_i32_x(slow_f128M_to_i32_r_minMag, + qemu_f128M_to_i32_r_minMag, exact); + break; + case F128_TO_I64_R_MINMAG: + test_a_f128_z_i64_x(slow_f128M_to_i64_r_minMag, + qemu_f128M_to_i64_r_minMag, exact); + 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, rmode, + exact); + break; + case F128_ADD: + true_abz_f128M = slow_f128M_add; + subj_abz_f128M = qemu_f128M_add; + goto test_abz_f128; + case F128_SUB: + true_abz_f128M = slow_f128M_sub; + subj_abz_f128M = qemu_f128M_sub; + goto test_abz_f128; + case F128_MUL: + true_abz_f128M = slow_f128M_mul; + subj_abz_f128M = qemu_f128M_mul; + goto test_abz_f128; + case F128_DIV: + true_abz_f128M = slow_f128M_div; + subj_abz_f128M = qemu_f128M_div; + goto test_abz_f128; + case F128_REM: + true_abz_f128M = slow_f128M_rem; + subj_abz_f128M = qemu_f128M_rem; + test_abz_f128: + test_abz_f128(true_abz_f128M, subj_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: + true_ab_f128M_z_bool = slow_f128M_eq; + subj_ab_f128M_z_bool = qemu_f128M_eq; + goto test_ab_f128_z_bool; + case F128_LE: + true_ab_f128M_z_bool = slow_f128M_le; + subj_ab_f128M_z_bool = qemu_f128M_le; + goto test_ab_f128_z_bool; + case F128_LT: + true_ab_f128M_z_bool = slow_f128M_lt; + subj_ab_f128M_z_bool = qemu_f128M_lt; + goto test_ab_f128_z_bool; + case F128_EQ_SIGNALING: + true_ab_f128M_z_bool = slow_f128M_eq_signaling; + subj_ab_f128M_z_bool = qemu_f128M_eq_signaling; + goto test_ab_f128_z_bool; + case F128_LE_QUIET: + true_ab_f128M_z_bool = slow_f128M_le_quiet; + subj_ab_f128M_z_bool = qemu_f128M_le_quiet; + goto test_ab_f128_z_bool; + case F128_LT_QUIET: + true_ab_f128M_z_bool = slow_f128M_lt_quiet; + subj_ab_f128M_z_bool = qemu_f128M_lt_quiet; + test_ab_f128_z_bool: + test_ab_f128_z_bool(true_ab_f128M_z_bool, subj_ab_f128M_z_bool); + break; + } + if ((verCases_errorStop && verCases_anyErrors)) { + verCases_exitWithStatus(); + } +} + +static unsigned int test_name_to_op(const char *arg) +{ + unsigned int i; + + /* counting begins at 1 */ + for (i = 1; i < NUM_FUNCTIONS; i++) { + const char *name = functionInfos[i].namePtr; + + if (name && !strcmp(name, arg)) { + return i; + } + } + return 0; +} + +static unsigned int round_name_to_mode(const char *name) +{ + int i; + + /* counting begins at 1 */ + for (i = 1; i < NUM_ROUNDINGMODES; i++) { + if (!strcmp(round_mode_names[i], name)) { + return i; + } + } + return 0; +} + +static int set_init_flags(const char *flags) +{ + const char *p; + + for (p = flags; *p != '\0'; p++) { + switch (*p) { + case 'v': + slow_init_flags |= softfloat_flag_invalid; + qemu_init_flags |= float_flag_invalid; + break; + case 'i': + slow_init_flags |= softfloat_flag_infinite; + qemu_init_flags |= float_flag_divbyzero; + break; + case 'o': + slow_init_flags |= softfloat_flag_overflow; + qemu_init_flags |= float_flag_overflow; + break; + case 'u': + slow_init_flags |= softfloat_flag_underflow; + qemu_init_flags |= float_flag_underflow; + break; + case 'x': + slow_init_flags |= softfloat_flag_inexact; + qemu_init_flags |= float_flag_inexact; + break; + default: + return 1; + } + } + return 0; +} + +static uint8_t slow_clear_flags(void) +{ + uint8_t prev = slowfloat_exceptionFlags; + + slowfloat_exceptionFlags = slow_init_flags; + return prev; +} + +static uint8_t qemu_clear_flags(void) +{ + uint8_t prev = qemu_flags_to_sf(qsf.float_exception_flags); + + qsf.float_exception_flags = qemu_init_flags; + return prev; +} + +static void parse_args(int argc, char *argv[]) +{ + unsigned int i; + int c; + + for (;;) { + c = getopt(argc, argv, "he:f:l:r:s"); + if (c < 0) { + break; + } + switch (c) { + case 'h': + usage_complete(argc, argv); + exit(EXIT_SUCCESS); + case 'e': + if (qemu_strtoui(optarg, NULL, 0, &n_max_errors)) { + fprintf(stderr, "fatal: invalid max error count\n"); + exit(EXIT_FAILURE); + } + break; + case 'f': + if (set_init_flags(optarg)) { + fprintf(stderr, "fatal: flags must be a subset of 'vioux'\n"); + exit(EXIT_FAILURE); + } + break; + case 'l': + if (qemu_strtoi(optarg, NULL, 0, &test_level)) { + fprintf(stderr, "fatal: invalid test level\n"); + exit(EXIT_FAILURE); + } + break; + case 'r': + if (!strcmp(optarg, "all")) { + test_round_mode = 0; + } else { + test_round_mode = round_name_to_mode(optarg); + if (test_round_mode == 0) { + fprintf(stderr, "fatal: invalid rounding mode\n"); + exit(EXIT_FAILURE); + } + } + break; + case 's': + verCases_errorStop = true; + break; + case '?': + /* invalid option or missing argument; getopt prints error info */ + exit(EXIT_FAILURE); + } + } + + /* set rounding modes */ + if (test_round_mode == 0) { + /* test all rounding modes; note that counting begins at 1 */ + n_round_modes = NUM_ROUNDINGMODES - 1; + round_modes = g_malloc_n(n_round_modes, sizeof(*round_modes)); + for (i = 0; i < n_round_modes; i++) { + round_modes[i] = i + 1; + } + } else { + n_round_modes = 1; + round_modes = g_malloc(sizeof(*round_modes)); + round_modes[0] = test_round_mode; + } + + /* set test ops */ + if (optind == argc) { + /* test all ops; note that counting begins at 1 */ + n_test_ops = NUM_FUNCTIONS - 1; + test_ops = g_malloc_n(n_test_ops, sizeof(*test_ops)); + for (i = 0; i < n_test_ops; i++) { + test_ops[i] = i + 1; + } + } else { + n_test_ops = argc - optind; + test_ops = g_malloc_n(n_test_ops, sizeof(*test_ops)); + for (i = 0; i < n_test_ops; i++) { + const char *name = argv[i + optind]; + unsigned int op = test_name_to_op(name); + + if (op == 0) { + fprintf(stderr, "fatal: invalid op '%s'\n", name); + exit(EXIT_FAILURE); + } + test_ops[i] = op; + } + } +} + +static void QEMU_NORETURN run_test(void) +{ + unsigned int i; + + genCases_setLevel(test_level); + verCases_maxErrorCount = n_max_errors; + + testLoops_trueFlagsFunction = slow_clear_flags; + testLoops_subjFlagsFunction = qemu_clear_flags; + + for (i = 0; i < n_test_ops; i++) { + unsigned int op = test_ops[i]; + int j; + + if (functionInfos[op].namePtr == NULL) { + continue; + } + verCases_functionNamePtr = functionInfos[op].namePtr; + + for (j = 0; j < n_round_modes; j++) { + int attrs = functionInfos[op].attribs; + int round = round_modes[j]; + int rmode = roundingModes[round]; + int k; + + verCases_roundingCode = 0; + slowfloat_roundingMode = rmode; + qsf.float_rounding_mode = sf_rounding_to_qemu(rmode); + + if (attrs & (FUNC_ARG_ROUNDINGMODE | FUNC_EFF_ROUNDINGMODE)) { + /* print rounding mode if the op is affected by it */ + verCases_roundingCode = round; + } else if (j > 0) { + /* if the op is not sensitive to rounding, move on */ + break; + } + + /* QEMU doesn't have !exact */ + verCases_exact = true; + verCases_usesExact = !!(attrs & FUNC_ARG_EXACT); + + for (k = 0; k < 3; k++) { + int prec80 = 32; + int l; + + if (k == 1) { + prec80 = 64; + } else if (k == 2) { + prec80 = 80; + } + + verCases_roundingPrecision = 0; + slow_extF80_roundingPrecision = prec80; + qsf.floatx80_rounding_precision = prec80; + + if (attrs & FUNC_EFF_ROUNDINGPRECISION) { + verCases_roundingPrecision = prec80; + } else if (k > 0) { + /* if the op is not sensitive to prec80, move on */ + break; + } + + /* note: the count begins at 1 */ + for (l = 1; l < NUM_TININESSMODES; l++) { + int tmode = tininessModes[l]; + + verCases_tininessCode = 0; + slowfloat_detectTininess = tmode; + qsf.float_detect_tininess = sf_tininess_to_qemu(tmode); + + if (attrs & FUNC_EFF_TININESSMODE || + ((attrs & FUNC_EFF_TININESSMODE_REDUCEDPREC) && + prec80 && prec80 < 80)) { + verCases_tininessCode = l; + } else if (l > 1) { + /* if the op is not sensitive to tininess, move on */ + break; + } + + do_testfloat(op, rmode, true); + } + } + } + } + verCases_exitWithStatus(); + /* old compilers might miss that we exited */ + g_assert_not_reached(); +} + +int main(int argc, char *argv[]) +{ + parse_args(argc, argv); + fail_programName = argv[0]; + run_test(); /* does not return */ +} diff --git a/tests/fp/wrap.inc.c b/tests/fp/wrap.inc.c new file mode 100644 index 0000000000..d3bf600cd0 --- /dev/null +++ b/tests/fp/wrap.inc.c @@ -0,0 +1,653 @@ +/* + * In this file we wrap QEMU FP functions to look like softfloat/testfloat's, + * so that we can use the testfloat infrastructure as-is. + * + * This file must be included directly from fp-test.c. We could compile it + * separately, but it would be tedious to add declarations for all the wrappers. + */ + +static signed char sf_tininess_to_qemu(uint_fast8_t mode) +{ + switch (mode) { + case softfloat_tininess_beforeRounding: + return float_tininess_before_rounding; + case softfloat_tininess_afterRounding: + return float_tininess_after_rounding; + default: + g_assert_not_reached(); + } +} + +static signed char sf_rounding_to_qemu(uint_fast8_t mode) +{ + switch (mode) { + case softfloat_round_near_even: + return float_round_nearest_even; + case softfloat_round_minMag: + return float_round_to_zero; + case softfloat_round_min: + return float_round_down; + case softfloat_round_max: + return float_round_up; + case softfloat_round_near_maxMag: + return float_round_ties_away; + case softfloat_round_odd: + return float_round_to_odd; + default: + g_assert_not_reached(); + } +} + +static uint_fast8_t qemu_flags_to_sf(uint8_t qflags) +{ + uint_fast8_t ret = 0; + + if (qflags & float_flag_invalid) { + ret |= softfloat_flag_invalid; + } + if (qflags & float_flag_divbyzero) { + ret |= softfloat_flag_infinite; + } + if (qflags & float_flag_overflow) { + ret |= softfloat_flag_overflow; + } + if (qflags & float_flag_underflow) { + ret |= softfloat_flag_underflow; + } + if (qflags & float_flag_inexact) { + ret |= softfloat_flag_inexact; + } + return ret; +} + +/* + * floatx80 and float128 cannot be cast between qemu and softfloat, because + * in softfloat the order of the fields depends on the host's endianness. + */ +static extFloat80_t qemu_to_soft80(floatx80 a) +{ + extFloat80_t ret; + + ret.signif = a.low; + ret.signExp = a.high; + return ret; +} + +static floatx80 soft_to_qemu80(extFloat80_t a) +{ + floatx80 ret; + + ret.low = a.signif; + ret.high = a.signExp; + return ret; +} + +static float128_t qemu_to_soft128(float128 a) +{ + float128_t ret; + struct uint128 *to = (struct uint128 *)&ret; + + to->v0 = a.low; + to->v64 = a.high; + return ret; +} + +static float128 soft_to_qemu128(float128_t a) +{ + struct uint128 *from = (struct uint128 *)&a; + float128 ret; + + ret.low = from->v0; + ret.high = from->v64; + return ret; +} + +/* conversions */ +#define WRAP_SF_TO_SF_IEEE(name, func, a_type, b_type) \ + static b_type##_t name(a_type##_t a) \ + { \ + a_type *ap = (a_type *)&a; \ + b_type ret; \ + \ + ret = func(*ap, true, &qsf); \ + return *(b_type##_t *)&ret; \ + } + +WRAP_SF_TO_SF_IEEE(qemu_f16_to_f32, float16_to_float32, float16, float32) +WRAP_SF_TO_SF_IEEE(qemu_f16_to_f64, float16_to_float64, float16, float64) + +WRAP_SF_TO_SF_IEEE(qemu_f32_to_f16, float32_to_float16, float32, float16) +WRAP_SF_TO_SF_IEEE(qemu_f64_to_f16, float64_to_float16, float64, float16) +#undef WRAP_SF_TO_SF_IEEE + +#define WRAP_SF_TO_SF(name, func, a_type, b_type) \ + static b_type##_t name(a_type##_t a) \ + { \ + a_type *ap = (a_type *)&a; \ + b_type ret; \ + \ + ret = func(*ap, &qsf); \ + return *(b_type##_t *)&ret; \ + } + +WRAP_SF_TO_SF(qemu_f32_to_f64, float32_to_float64, float32, float64) +WRAP_SF_TO_SF(qemu_f64_to_f32, float64_to_float32, float64, float32) +#undef WRAP_SF_TO_SF + +#define WRAP_SF_TO_80(name, func, type) \ + static void name(type##_t a, extFloat80_t *res) \ + { \ + floatx80 ret; \ + type *ap = (type *)&a; \ + \ + ret = func(*ap, &qsf); \ + *res = qemu_to_soft80(ret); \ + } + +WRAP_SF_TO_80(qemu_f32_to_extF80M, float32_to_floatx80, float32) +WRAP_SF_TO_80(qemu_f64_to_extF80M, float64_to_floatx80, float64) +#undef WRAP_SF_TO_80 + +#define WRAP_SF_TO_128(name, func, type) \ + static void name(type##_t a, float128_t *res) \ + { \ + float128 ret; \ + type *ap = (type *)&a; \ + \ + ret = func(*ap, &qsf); \ + *res = qemu_to_soft128(ret); \ + } + +WRAP_SF_TO_128(qemu_f32_to_f128M, float32_to_float128, float32) +WRAP_SF_TO_128(qemu_f64_to_f128M, float64_to_float128, float64) +#undef WRAP_SF_TO_128 + +/* Note: exact is ignored since qemu's softfloat assumes it is set */ +#define WRAP_SF_TO_INT(name, func, type, fast_type) \ + static fast_type name(type##_t a, uint_fast8_t round, bool exact) \ + { \ + type *ap = (type *)&a; \ + \ + qsf.float_rounding_mode = sf_rounding_to_qemu(round); \ + return func(*ap, &qsf); \ + } + +WRAP_SF_TO_INT(qemu_f16_to_ui32, float16_to_uint32, float16, uint_fast32_t) +WRAP_SF_TO_INT(qemu_f16_to_ui64, float16_to_uint64, float16, uint_fast64_t) + +WRAP_SF_TO_INT(qemu_f32_to_ui32, float32_to_uint32, float32, uint_fast32_t) +WRAP_SF_TO_INT(qemu_f32_to_ui64, float32_to_uint64, float32, uint_fast64_t) + +WRAP_SF_TO_INT(qemu_f64_to_ui32, float64_to_uint32, float64, uint_fast32_t) +WRAP_SF_TO_INT(qemu_f64_to_ui64, float64_to_uint64, float64, uint_fast64_t) + +WRAP_SF_TO_INT(qemu_f16_to_i32, float16_to_int32, float16, int_fast32_t) +WRAP_SF_TO_INT(qemu_f16_to_i64, float16_to_int64, float16, int_fast64_t) + +WRAP_SF_TO_INT(qemu_f32_to_i32, float32_to_int32, float32, int_fast32_t) +WRAP_SF_TO_INT(qemu_f32_to_i64, float32_to_int64, float32, int_fast64_t) + +WRAP_SF_TO_INT(qemu_f64_to_i32, float64_to_int32, float64, int_fast32_t) +WRAP_SF_TO_INT(qemu_f64_to_i64, float64_to_int64, float64, int_fast64_t) +#undef WRAP_SF_TO_INT + +/* Note: exact is ignored since qemu's softfloat assumes it is set */ +#define WRAP_SF_TO_INT_MINMAG(name, func, type, fast_type) \ + static fast_type name(type##_t a, bool exact) \ + { \ + type *ap = (type *)&a; \ + \ + return func(*ap, &qsf); \ + } + +WRAP_SF_TO_INT_MINMAG(qemu_f16_to_ui32_r_minMag, + float16_to_uint32_round_to_zero, float16, uint_fast32_t) +WRAP_SF_TO_INT_MINMAG(qemu_f16_to_ui64_r_minMag, + float16_to_uint64_round_to_zero, float16, uint_fast64_t) + +WRAP_SF_TO_INT_MINMAG(qemu_f16_to_i32_r_minMag, + float16_to_int32_round_to_zero, float16, int_fast32_t) +WRAP_SF_TO_INT_MINMAG(qemu_f16_to_i64_r_minMag, + float16_to_int64_round_to_zero, float16, int_fast64_t) + +WRAP_SF_TO_INT_MINMAG(qemu_f32_to_ui32_r_minMag, + float32_to_uint32_round_to_zero, float32, uint_fast32_t) +WRAP_SF_TO_INT_MINMAG(qemu_f32_to_ui64_r_minMag, + float32_to_uint64_round_to_zero, float32, uint_fast64_t) + +WRAP_SF_TO_INT_MINMAG(qemu_f32_to_i32_r_minMag, + float32_to_int32_round_to_zero, float32, int_fast32_t) +WRAP_SF_TO_INT_MINMAG(qemu_f32_to_i64_r_minMag, + float32_to_int64_round_to_zero, float32, int_fast64_t) + +WRAP_SF_TO_INT_MINMAG(qemu_f64_to_ui32_r_minMag, + float64_to_uint32_round_to_zero, float64, uint_fast32_t) +WRAP_SF_TO_INT_MINMAG(qemu_f64_to_ui64_r_minMag, + float64_to_uint64_round_to_zero, float64, uint_fast64_t) + +WRAP_SF_TO_INT_MINMAG(qemu_f64_to_i32_r_minMag, + float64_to_int32_round_to_zero, float64, int_fast32_t) +WRAP_SF_TO_INT_MINMAG(qemu_f64_to_i64_r_minMag, + float64_to_int64_round_to_zero, float64, int_fast64_t) +#undef WRAP_SF_TO_INT_MINMAG + +#define WRAP_80_TO_SF(name, func, type) \ + static type##_t name(const extFloat80_t *ap) \ + { \ + floatx80 a; \ + type ret; \ + \ + a = soft_to_qemu80(*ap); \ + ret = func(a, &qsf); \ + return *(type##_t *)&ret; \ + } + +WRAP_80_TO_SF(qemu_extF80M_to_f32, floatx80_to_float32, float32) +WRAP_80_TO_SF(qemu_extF80M_to_f64, floatx80_to_float64, float64) +#undef WRAP_80_TO_SF + +#define WRAP_128_TO_SF(name, func, type) \ + static type##_t name(const float128_t *ap) \ + { \ + float128 a; \ + type ret; \ + \ + a = soft_to_qemu128(*ap); \ + ret = func(a, &qsf); \ + return *(type##_t *)&ret; \ + } + +WRAP_128_TO_SF(qemu_f128M_to_f32, float128_to_float32, float32) +WRAP_128_TO_SF(qemu_f128M_to_f64, float128_to_float64, float64) +#undef WRAP_128_TO_SF + +static void qemu_extF80M_to_f128M(const extFloat80_t *from, float128_t *to) +{ + floatx80 qfrom; + float128 qto; + + qfrom = soft_to_qemu80(*from); + qto = floatx80_to_float128(qfrom, &qsf); + *to = qemu_to_soft128(qto); +} + +static void qemu_f128M_to_extF80M(const float128_t *from, extFloat80_t *to) +{ + float128 qfrom; + floatx80 qto; + + qfrom = soft_to_qemu128(*from); + qto = float128_to_floatx80(qfrom, &qsf); + *to = qemu_to_soft80(qto); +} + +#define WRAP_INT_TO_SF(name, func, int_type, type) \ + static type##_t name(int_type a) \ + { \ + type ret; \ + \ + ret = func(a, &qsf); \ + return *(type##_t *)&ret; \ + } + +WRAP_INT_TO_SF(qemu_ui32_to_f16, uint32_to_float16, uint32_t, float16) +WRAP_INT_TO_SF(qemu_ui32_to_f32, uint32_to_float32, uint32_t, float32) +WRAP_INT_TO_SF(qemu_ui32_to_f64, uint32_to_float64, uint32_t, float64) + +WRAP_INT_TO_SF(qemu_ui64_to_f16, uint64_to_float16, uint64_t, float16) +WRAP_INT_TO_SF(qemu_ui64_to_f32, uint64_to_float32, uint64_t, float32) +WRAP_INT_TO_SF(qemu_ui64_to_f64, uint64_to_float64, uint64_t, float64) + +WRAP_INT_TO_SF(qemu_i32_to_f16, int32_to_float16, int32_t, float16) +WRAP_INT_TO_SF(qemu_i32_to_f32, int32_to_float32, int32_t, float32) +WRAP_INT_TO_SF(qemu_i32_to_f64, int32_to_float64, int32_t, float64) + +WRAP_INT_TO_SF(qemu_i64_to_f16, int64_to_float16, int64_t, float16) +WRAP_INT_TO_SF(qemu_i64_to_f32, int64_to_float32, int64_t, float32) +WRAP_INT_TO_SF(qemu_i64_to_f64, int64_to_float64, int64_t, float64) +#undef WRAP_INT_TO_SF + +#define WRAP_INT_TO_80(name, func, int_type) \ + static void name(int_type a, extFloat80_t *res) \ + { \ + floatx80 ret; \ + \ + ret = func(a, &qsf); \ + *res = qemu_to_soft80(ret); \ + } + +WRAP_INT_TO_80(qemu_i32_to_extF80M, int32_to_floatx80, int32_t) +WRAP_INT_TO_80(qemu_i64_to_extF80M, int64_to_floatx80, int64_t) +#undef WRAP_INT_TO_80 + +/* Note: exact is ignored since qemu's softfloat assumes it is set */ +#define WRAP_80_TO_INT(name, func, fast_type) \ + static fast_type name(const extFloat80_t *ap, uint_fast8_t round, \ + bool exact) \ + { \ + floatx80 a; \ + \ + a = soft_to_qemu80(*ap); \ + qsf.float_rounding_mode = sf_rounding_to_qemu(round); \ + return func(a, &qsf); \ + } + +WRAP_80_TO_INT(qemu_extF80M_to_i32, floatx80_to_int32, int_fast32_t) +WRAP_80_TO_INT(qemu_extF80M_to_i64, floatx80_to_int64, int_fast64_t) +#undef WRAP_80_TO_INT + +/* Note: exact is ignored since qemu's softfloat assumes it is set */ +#define WRAP_80_TO_INT_MINMAG(name, func, fast_type) \ + static fast_type name(const extFloat80_t *ap, bool exact) \ + { \ + floatx80 a; \ + \ + a = soft_to_qemu80(*ap); \ + return func(a, &qsf); \ + } + +WRAP_80_TO_INT_MINMAG(qemu_extF80M_to_i32_r_minMag, + floatx80_to_int32_round_to_zero, int_fast32_t) +WRAP_80_TO_INT_MINMAG(qemu_extF80M_to_i64_r_minMag, + floatx80_to_int64_round_to_zero, int_fast64_t) +#undef WRAP_80_TO_INT_MINMAG + +/* Note: exact is ignored since qemu's softfloat assumes it is set */ +#define WRAP_128_TO_INT(name, func, fast_type) \ + static fast_type name(const float128_t *ap, uint_fast8_t round, \ + bool exact) \ + { \ + float128 a; \ + \ + a = soft_to_qemu128(*ap); \ + qsf.float_rounding_mode = sf_rounding_to_qemu(round); \ + return func(a, &qsf); \ + } + +WRAP_128_TO_INT(qemu_f128M_to_i32, float128_to_int32, int_fast32_t) +WRAP_128_TO_INT(qemu_f128M_to_i64, float128_to_int64, int_fast64_t) + +WRAP_128_TO_INT(qemu_f128M_to_ui64, float128_to_uint64, uint_fast64_t) +#undef WRAP_128_TO_INT + +/* Note: exact is ignored since qemu's softfloat assumes it is set */ +#define WRAP_128_TO_INT_MINMAG(name, func, fast_type) \ + static fast_type name(const float128_t *ap, bool exact) \ + { \ + float128 a; \ + \ + a = soft_to_qemu128(*ap); \ + return func(a, &qsf); \ + } + +WRAP_128_TO_INT_MINMAG(qemu_f128M_to_i32_r_minMag, + float128_to_int32_round_to_zero, int_fast32_t) +WRAP_128_TO_INT_MINMAG(qemu_f128M_to_i64_r_minMag, + float128_to_int64_round_to_zero, int_fast64_t) + +WRAP_128_TO_INT_MINMAG(qemu_f128M_to_ui32_r_minMag, + float128_to_uint32_round_to_zero, uint_fast32_t) +WRAP_128_TO_INT_MINMAG(qemu_f128M_to_ui64_r_minMag, + float128_to_uint64_round_to_zero, uint_fast64_t) +#undef WRAP_128_TO_INT_MINMAG + +#define WRAP_INT_TO_128(name, func, int_type) \ + static void name(int_type a, float128_t *res) \ + { \ + float128 ret; \ + \ + ret = func(a, &qsf); \ + *res = qemu_to_soft128(ret); \ + } + +WRAP_INT_TO_128(qemu_ui64_to_f128M, uint64_to_float128, uint64_t) + +WRAP_INT_TO_128(qemu_i32_to_f128M, int32_to_float128, int32_t) +WRAP_INT_TO_128(qemu_i64_to_f128M, int64_to_float128, int64_t) +#undef WRAP_INT_TO_128 + +/* Note: exact is ignored since qemu's softfloat assumes it is set */ +#define WRAP_ROUND_TO_INT(name, func, type) \ + static type##_t name(type##_t a, uint_fast8_t round, bool exact) \ + { \ + type *ap = (type *)&a; \ + type ret; \ + \ + qsf.float_rounding_mode = sf_rounding_to_qemu(round); \ + ret = func(*ap, &qsf); \ + return *(type##_t *)&ret; \ + } + +WRAP_ROUND_TO_INT(qemu_f16_roundToInt, float16_round_to_int, float16) +WRAP_ROUND_TO_INT(qemu_f32_roundToInt, float32_round_to_int, float32) +WRAP_ROUND_TO_INT(qemu_f64_roundToInt, float64_round_to_int, float64) +#undef WRAP_ROUND_TO_INT + +static void qemu_extF80M_roundToInt(const extFloat80_t *ap, uint_fast8_t round, + bool exact, extFloat80_t *res) +{ + floatx80 a; + floatx80 ret; + + a = soft_to_qemu80(*ap); + qsf.float_rounding_mode = sf_rounding_to_qemu(round); + ret = floatx80_round_to_int(a, &qsf); + *res = qemu_to_soft80(ret); +} + +static void qemu_f128M_roundToInt(const float128_t *ap, uint_fast8_t round, + bool exact, float128_t *res) +{ + float128 a; + float128 ret; + + a = soft_to_qemu128(*ap); + qsf.float_rounding_mode = sf_rounding_to_qemu(round); + ret = float128_round_to_int(a, &qsf); + *res = qemu_to_soft128(ret); +} + +/* operations */ +#define WRAP1(name, func, type) \ + static type##_t name(type##_t a) \ + { \ + type *ap = (type *)&a; \ + type ret; \ + \ + ret = func(*ap, &qsf); \ + return *(type##_t *)&ret; \ + } + +#define WRAP2(name, func, type) \ + static type##_t name(type##_t a, type##_t b) \ + { \ + type *ap = (type *)&a; \ + type *bp = (type *)&b; \ + type ret; \ + \ + ret = func(*ap, *bp, &qsf); \ + return *(type##_t *)&ret; \ + } + +#define WRAP_COMMON_OPS(b) \ + WRAP1(qemu_f##b##_sqrt, float##b##_sqrt, float##b) \ + WRAP2(qemu_f##b##_add, float##b##_add, float##b) \ + WRAP2(qemu_f##b##_sub, float##b##_sub, float##b) \ + WRAP2(qemu_f##b##_mul, float##b##_mul, float##b) \ + WRAP2(qemu_f##b##_div, float##b##_div, float##b) + +WRAP_COMMON_OPS(16) +WRAP_COMMON_OPS(32) +WRAP_COMMON_OPS(64) +#undef WRAP_COMMON + +WRAP2(qemu_f32_rem, float32_rem, float32) +WRAP2(qemu_f64_rem, float64_rem, float64) +#undef WRAP2 +#undef WRAP1 + +#define WRAP1_80(name, func) \ + static void name(const extFloat80_t *ap, extFloat80_t *res) \ + { \ + floatx80 a; \ + floatx80 ret; \ + \ + a = soft_to_qemu80(*ap); \ + ret = func(a, &qsf); \ + *res = qemu_to_soft80(ret); \ + } + +WRAP1_80(qemu_extF80M_sqrt, floatx80_sqrt) +#undef WRAP1_80 + +#define WRAP1_128(name, func) \ + static void name(const float128_t *ap, float128_t *res) \ + { \ + float128 a; \ + float128 ret; \ + \ + a = soft_to_qemu128(*ap); \ + ret = func(a, &qsf); \ + *res = qemu_to_soft128(ret); \ + } + +WRAP1_128(qemu_f128M_sqrt, float128_sqrt) +#undef WRAP1_128 + +#define WRAP2_80(name, func) \ + static void name(const extFloat80_t *ap, const extFloat80_t *bp, \ + extFloat80_t *res) \ + { \ + floatx80 a; \ + floatx80 b; \ + floatx80 ret; \ + \ + a = soft_to_qemu80(*ap); \ + b = soft_to_qemu80(*bp); \ + ret = func(a, b, &qsf); \ + *res = qemu_to_soft80(ret); \ + } + +WRAP2_80(qemu_extF80M_add, floatx80_add) +WRAP2_80(qemu_extF80M_sub, floatx80_sub) +WRAP2_80(qemu_extF80M_mul, floatx80_mul) +WRAP2_80(qemu_extF80M_div, floatx80_div) +WRAP2_80(qemu_extF80M_rem, floatx80_rem) +#undef WRAP2_80 + +#define WRAP2_128(name, func) \ + static void name(const float128_t *ap, const float128_t *bp, \ + float128_t *res) \ + { \ + float128 a; \ + float128 b; \ + float128 ret; \ + \ + a = soft_to_qemu128(*ap); \ + b = soft_to_qemu128(*bp); \ + ret = func(a, b, &qsf); \ + *res = qemu_to_soft128(ret); \ + } + +WRAP2_128(qemu_f128M_add, float128_add) +WRAP2_128(qemu_f128M_sub, float128_sub) +WRAP2_128(qemu_f128M_mul, float128_mul) +WRAP2_128(qemu_f128M_div, float128_div) +WRAP2_128(qemu_f128M_rem, float128_rem) +#undef WRAP2_128 + +#define WRAP_MULADD(name, func, type) \ + static type##_t name(type##_t a, type##_t b, type##_t c) \ + { \ + type *ap = (type *)&a; \ + type *bp = (type *)&b; \ + type *cp = (type *)&c; \ + type ret; \ + \ + ret = func(*ap, *bp, *cp, 0, &qsf); \ + return *(type##_t *)&ret; \ + } + +WRAP_MULADD(qemu_f16_mulAdd, float16_muladd, float16) +WRAP_MULADD(qemu_f32_mulAdd, float32_muladd, float32) +WRAP_MULADD(qemu_f64_mulAdd, float64_muladd, float64) +#undef WRAP_MULADD + +#define WRAP_CMP16(name, func, retcond) \ + static bool name(float16_t a, float16_t b) \ + { \ + float16 *ap = (float16 *)&a; \ + float16 *bp = (float16 *)&b; \ + int ret; \ + \ + ret = func(*ap, *bp, &qsf); \ + return retcond; \ + } + +WRAP_CMP16(qemu_f16_eq_signaling, float16_compare, ret == 0) +WRAP_CMP16(qemu_f16_eq, float16_compare_quiet, ret == 0) +WRAP_CMP16(qemu_f16_le, float16_compare, ret <= 0) +WRAP_CMP16(qemu_f16_lt, float16_compare, ret < 0) +WRAP_CMP16(qemu_f16_le_quiet, float16_compare_quiet, ret <= 0) +WRAP_CMP16(qemu_f16_lt_quiet, float16_compare_quiet, ret < 0) +#undef WRAP_CMP16 + +#define WRAP_CMP(name, func, type) \ + static bool name(type##_t a, type##_t b) \ + { \ + type *ap = (type *)&a; \ + type *bp = (type *)&b; \ + \ + return !!func(*ap, *bp, &qsf); \ + } + +#define GEN_WRAP_CMP(b) \ + WRAP_CMP(qemu_f##b##_eq_signaling, float##b##_eq, float##b) \ + WRAP_CMP(qemu_f##b##_eq, float##b##_eq_quiet, float##b) \ + WRAP_CMP(qemu_f##b##_le, float##b##_le, float##b) \ + WRAP_CMP(qemu_f##b##_lt, float##b##_lt, float##b) \ + WRAP_CMP(qemu_f##b##_le_quiet, float##b##_le_quiet, float##b) \ + WRAP_CMP(qemu_f##b##_lt_quiet, float##b##_lt_quiet, float##b) + +GEN_WRAP_CMP(32) +GEN_WRAP_CMP(64) +#undef GEN_WRAP_CMP +#undef WRAP_CMP + +#define WRAP_CMP80(name, func) \ + static bool name(const extFloat80_t *ap, const extFloat80_t *bp) \ + { \ + floatx80 a; \ + floatx80 b; \ + \ + a = soft_to_qemu80(*ap); \ + b = soft_to_qemu80(*bp); \ + return !!func(a, b, &qsf); \ + } + +WRAP_CMP80(qemu_extF80M_eq_signaling, floatx80_eq) +WRAP_CMP80(qemu_extF80M_eq, floatx80_eq_quiet) +WRAP_CMP80(qemu_extF80M_le, floatx80_le) +WRAP_CMP80(qemu_extF80M_lt, floatx80_lt) +WRAP_CMP80(qemu_extF80M_le_quiet, floatx80_le_quiet) +WRAP_CMP80(qemu_extF80M_lt_quiet, floatx80_le_quiet) +#undef WRAP_CMP80 + +#define WRAP_CMP128(name, func) \ + static bool name(const float128_t *ap, const float128_t *bp) \ + { \ + float128 a; \ + float128 b; \ + \ + a = soft_to_qemu128(*ap); \ + b = soft_to_qemu128(*bp); \ + return !!func(a, b, &qsf); \ + } + +WRAP_CMP128(qemu_f128M_eq_signaling, float128_eq) +WRAP_CMP128(qemu_f128M_eq, float128_eq_quiet) +WRAP_CMP128(qemu_f128M_le, float128_le) +WRAP_CMP128(qemu_f128M_lt, float128_lt) +WRAP_CMP128(qemu_f128M_le_quiet, float128_le_quiet) +WRAP_CMP128(qemu_f128M_lt_quiet, float128_lt_quiet) +#undef WRAP_CMP128 diff --git a/configure b/configure index f3d4b799a5..f89d293585 100755 --- a/configure +++ b/configure @@ -296,6 +296,8 @@ if test -e "$source_path/.git" then git_update=yes git_submodules="ui/keycodemapdb" + git_submodules="$git_submodules tests/fp/berkeley-testfloat-3" + git_submodules="$git_submodules tests/fp/berkeley-softfloat-3" else git_update=no git_submodules="" @@ -7449,12 +7451,14 @@ fi # build tree in object directory in case the source is not in the current directory DIRS="tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests tests/vm" +DIRS="$DIRS tests/fp" DIRS="$DIRS docs docs/interop fsdev scsi" DIRS="$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw" DIRS="$DIRS roms/seabios roms/vgabios" FILES="Makefile tests/tcg/Makefile qdict-test-data.txt" FILES="$FILES tests/tcg/cris/Makefile tests/tcg/cris/.gdbinit" FILES="$FILES tests/tcg/lm32/Makefile tests/tcg/xtensa/Makefile po/Makefile" +FILES="$FILES tests/fp/Makefile" FILES="$FILES pc-bios/optionrom/Makefile pc-bios/keymaps" FILES="$FILES pc-bios/spapr-rtas/Makefile" FILES="$FILES pc-bios/s390-ccw/Makefile" diff --git a/tests/Makefile.include b/tests/Makefile.include index 175d013f4a..7a3059bf6c 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -670,6 +670,9 @@ tests/test-bufferiszero$(EXESUF): tests/test-bufferiszero.o $(test-util-obj-y) tests/atomic_add-bench$(EXESUF): tests/atomic_add-bench.o $(test-util-obj-y) tests/atomic64-bench$(EXESUF): tests/atomic64-bench.o $(test-util-obj-y) +tests/fp/%: + $(MAKE) -C $(dir $@) $(notdir $@) + tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \ hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\ hw/core/bus.o \ diff --git a/tests/fp/.gitignore b/tests/fp/.gitignore new file mode 100644 index 0000000000..8d45d18ac4 --- /dev/null +++ b/tests/fp/.gitignore @@ -0,0 +1 @@ +fp-test diff --git a/tests/fp/Makefile b/tests/fp/Makefile new file mode 100644 index 0000000000..d649a5a1db --- /dev/null +++ b/tests/fp/Makefile @@ -0,0 +1,597 @@ +BUILD_DIR := $(CURDIR)/../.. + +include $(BUILD_DIR)/config-host.mak +include $(SRC_PATH)/rules.mak + +SOFTFLOAT_DIR := $(SRC_PATH)/tests/fp/berkeley-softfloat-3 +TESTFLOAT_DIR := $(SRC_PATH)/tests/fp/berkeley-testfloat-3 + +SF_SOURCE_DIR := $(SOFTFLOAT_DIR)/source +SF_INCLUDE_DIR := $(SOFTFLOAT_DIR)/source/include +# we could use any specialize here, it doesn't matter +SF_SPECIALIZE := 8086-SSE +SF_SPECIALIZE_DIR := $(SF_SOURCE_DIR)/$(SF_SPECIALIZE) + +TF_SOURCE_DIR := $(TESTFLOAT_DIR)/source + +$(call set-vpath, $(SRC_PATH)/fpu $(SRC_PATH)/tests/fp) + +LIBQEMUUTIL := $(BUILD_DIR)/libqemuutil.a + +# Use this variable to be clear when we pull in our own implementation +# We build the object with a default rule thanks to the vpath above +QEMU_SOFTFLOAT_OBJ := softfloat.o + +QEMU_INCLUDES += -I$(SRC_PATH)/tests/fp +QEMU_INCLUDES += -I$(SF_INCLUDE_DIR) +QEMU_INCLUDES += -I$(SF_SPECIALIZE_DIR) +QEMU_INCLUDES += -I$(TF_SOURCE_DIR) + +# work around TARGET_* poisoning +QEMU_CFLAGS += -DHW_POISON_H + +# capstone has a platform.h file that clashes with softfloat's +QEMU_CFLAGS := $(filter-out %capstone, $(QEMU_CFLAGS)) + +# softfloat defines +SF_OPTS := +SF_OPTS += -DSOFTFLOAT_ROUND_ODD +SF_OPTS += -DINLINE_LEVEL=5 +SF_OPTS += -DSOFTFLOAT_FAST_DIV32TO16 +SF_OPTS += -DSOFTFLOAT_FAST_DIV64TO32 +SF_OPTS += -DSOFTFLOAT_FAST_INT64 +QEMU_CFLAGS += $(SF_OPTS) + +# silence the build of softfloat objects +SF_CFLAGS += -Wno-missing-prototypes +SF_CFLAGS += -Wno-redundant-decls +SF_CFLAGS += -Wno-return-type +SF_CFLAGS += -Wno-error + +# testfloat defines +TF_OPTS := +TF_OPTS += -DFLOAT16 +TF_OPTS += -DFLOAT64 +TF_OPTS += -DEXTFLOAT80 +TF_OPTS += -DFLOAT128 +TF_OPTS += -DFLOAT_ROUND_ODD +TF_OPTS += -DLONG_DOUBLE_IS_EXTFLOAT80 +QEMU_CFLAGS += $(TF_OPTS) + +# silence the build of testfloat objects +TF_CFLAGS := +TF_CFLAGS += -Wno-strict-prototypes +TF_CFLAGS += -Wno-unknown-pragmas +TF_CFLAGS += -Wno-discarded-qualifiers +TF_CFLAGS += -Wno-maybe-uninitialized +TF_CFLAGS += -Wno-missing-prototypes +TF_CFLAGS += -Wno-return-type +TF_CFLAGS += -Wno-unused-function +TF_CFLAGS += -Wno-error + +# softfloat objects +SF_OBJS_PRIMITIVES := +SF_OBJS_PRIMITIVES += s_eq128.o +SF_OBJS_PRIMITIVES += s_le128.o +SF_OBJS_PRIMITIVES += s_lt128.o +SF_OBJS_PRIMITIVES += s_shortShiftLeft128.o +SF_OBJS_PRIMITIVES += s_shortShiftRight128.o +SF_OBJS_PRIMITIVES += s_shortShiftRightJam64.o +SF_OBJS_PRIMITIVES += s_shortShiftRightJam64Extra.o +SF_OBJS_PRIMITIVES += s_shortShiftRightJam128.o +SF_OBJS_PRIMITIVES += s_shortShiftRightJam128Extra.o +SF_OBJS_PRIMITIVES += s_shiftRightJam32.o +SF_OBJS_PRIMITIVES += s_shiftRightJam64.o +SF_OBJS_PRIMITIVES += s_shiftRightJam64Extra.o +SF_OBJS_PRIMITIVES += s_shiftRightJam128.o +SF_OBJS_PRIMITIVES += s_shiftRightJam128Extra.o +SF_OBJS_PRIMITIVES += s_shiftRightJam256M.o +SF_OBJS_PRIMITIVES += s_countLeadingZeros8.o +SF_OBJS_PRIMITIVES += s_countLeadingZeros16.o +SF_OBJS_PRIMITIVES += s_countLeadingZeros32.o +SF_OBJS_PRIMITIVES += s_countLeadingZeros64.o +SF_OBJS_PRIMITIVES += s_add128.o +SF_OBJS_PRIMITIVES += s_add256M.o +SF_OBJS_PRIMITIVES += s_sub128.o +SF_OBJS_PRIMITIVES += s_sub256M.o +SF_OBJS_PRIMITIVES += s_mul64ByShifted32To128.o +SF_OBJS_PRIMITIVES += s_mul64To128.o +SF_OBJS_PRIMITIVES += s_mul128By32.o +SF_OBJS_PRIMITIVES += s_mul128To256M.o +SF_OBJS_PRIMITIVES += s_approxRecip_1Ks.o +SF_OBJS_PRIMITIVES += s_approxRecip32_1.o +SF_OBJS_PRIMITIVES += s_approxRecipSqrt_1Ks.o +SF_OBJS_PRIMITIVES += s_approxRecipSqrt32_1.o + +SF_OBJS_SPECIALIZE := +SF_OBJS_SPECIALIZE += softfloat_raiseFlags.o +SF_OBJS_SPECIALIZE += s_f16UIToCommonNaN.o +SF_OBJS_SPECIALIZE += s_commonNaNToF16UI.o +SF_OBJS_SPECIALIZE += s_propagateNaNF16UI.o +SF_OBJS_SPECIALIZE += s_f32UIToCommonNaN.o +SF_OBJS_SPECIALIZE += s_commonNaNToF32UI.o +SF_OBJS_SPECIALIZE += s_propagateNaNF32UI.o +SF_OBJS_SPECIALIZE += s_f64UIToCommonNaN.o +SF_OBJS_SPECIALIZE += s_commonNaNToF64UI.o +SF_OBJS_SPECIALIZE += s_propagateNaNF64UI.o +SF_OBJS_SPECIALIZE += extF80M_isSignalingNaN.o +SF_OBJS_SPECIALIZE += s_extF80UIToCommonNaN.o +SF_OBJS_SPECIALIZE += s_commonNaNToExtF80UI.o +SF_OBJS_SPECIALIZE += s_propagateNaNExtF80UI.o +SF_OBJS_SPECIALIZE += f128M_isSignalingNaN.o +SF_OBJS_SPECIALIZE += s_f128UIToCommonNaN.o +SF_OBJS_SPECIALIZE += s_commonNaNToF128UI.o +SF_OBJS_SPECIALIZE += s_propagateNaNF128UI.o + +SF_OBJS_OTHERS := +SF_OBJS_OTHERS += s_roundToUI32.o +SF_OBJS_OTHERS += s_roundToUI64.o +SF_OBJS_OTHERS += s_roundToI32.o +SF_OBJS_OTHERS += s_roundToI64.o +SF_OBJS_OTHERS += s_normSubnormalF16Sig.o +SF_OBJS_OTHERS += s_roundPackToF16.o +SF_OBJS_OTHERS += s_normRoundPackToF16.o +SF_OBJS_OTHERS += s_addMagsF16.o +SF_OBJS_OTHERS += s_subMagsF16.o +SF_OBJS_OTHERS += s_mulAddF16.o +SF_OBJS_OTHERS += s_normSubnormalF32Sig.o +SF_OBJS_OTHERS += s_roundPackToF32.o +SF_OBJS_OTHERS += s_normRoundPackToF32.o +SF_OBJS_OTHERS += s_addMagsF32.o +SF_OBJS_OTHERS += s_subMagsF32.o +SF_OBJS_OTHERS += s_mulAddF32.o +SF_OBJS_OTHERS += s_normSubnormalF64Sig.o +SF_OBJS_OTHERS += s_roundPackToF64.o +SF_OBJS_OTHERS += s_normRoundPackToF64.o +SF_OBJS_OTHERS += s_addMagsF64.o +SF_OBJS_OTHERS += s_subMagsF64.o +SF_OBJS_OTHERS += s_mulAddF64.o +SF_OBJS_OTHERS += s_normSubnormalExtF80Sig.o +SF_OBJS_OTHERS += s_roundPackToExtF80.o +SF_OBJS_OTHERS += s_normRoundPackToExtF80.o +SF_OBJS_OTHERS += s_addMagsExtF80.o +SF_OBJS_OTHERS += s_subMagsExtF80.o +SF_OBJS_OTHERS += s_normSubnormalF128Sig.o +SF_OBJS_OTHERS += s_roundPackToF128.o +SF_OBJS_OTHERS += s_normRoundPackToF128.o +SF_OBJS_OTHERS += s_addMagsF128.o +SF_OBJS_OTHERS += s_subMagsF128.o +SF_OBJS_OTHERS += s_mulAddF128.o +SF_OBJS_OTHERS += softfloat_state.o +SF_OBJS_OTHERS += ui32_to_f16.o +SF_OBJS_OTHERS += ui32_to_f32.o +SF_OBJS_OTHERS += ui32_to_f64.o +SF_OBJS_OTHERS += ui32_to_extF80.o +SF_OBJS_OTHERS += ui32_to_extF80M.o +SF_OBJS_OTHERS += ui32_to_f128.o +SF_OBJS_OTHERS += ui32_to_f128M.o +SF_OBJS_OTHERS += ui64_to_f16.o +SF_OBJS_OTHERS += ui64_to_f32.o +SF_OBJS_OTHERS += ui64_to_f64.o +SF_OBJS_OTHERS += ui64_to_extF80.o +SF_OBJS_OTHERS += ui64_to_extF80M.o +SF_OBJS_OTHERS += ui64_to_f128.o +SF_OBJS_OTHERS += ui64_to_f128M.o +SF_OBJS_OTHERS += i32_to_f16.o +SF_OBJS_OTHERS += i32_to_f32.o +SF_OBJS_OTHERS += i32_to_f64.o +SF_OBJS_OTHERS += i32_to_extF80.o +SF_OBJS_OTHERS += i32_to_extF80M.o +SF_OBJS_OTHERS += i32_to_f128.o +SF_OBJS_OTHERS += i32_to_f128M.o +SF_OBJS_OTHERS += i64_to_f16.o +SF_OBJS_OTHERS += i64_to_f32.o +SF_OBJS_OTHERS += i64_to_f64.o +SF_OBJS_OTHERS += i64_to_extF80.o +SF_OBJS_OTHERS += i64_to_extF80M.o +SF_OBJS_OTHERS += i64_to_f128.o +SF_OBJS_OTHERS += i64_to_f128M.o +SF_OBJS_OTHERS += f16_to_ui32.o +SF_OBJS_OTHERS += f16_to_ui64.o +SF_OBJS_OTHERS += f16_to_i32.o +SF_OBJS_OTHERS += f16_to_i64.o +SF_OBJS_OTHERS += f16_to_ui32_r_minMag.o +SF_OBJS_OTHERS += f16_to_ui64_r_minMag.o +SF_OBJS_OTHERS += f16_to_i32_r_minMag.o +SF_OBJS_OTHERS += f16_to_i64_r_minMag.o +SF_OBJS_OTHERS += f16_to_f32.o +SF_OBJS_OTHERS += f16_to_f64.o +SF_OBJS_OTHERS += f16_to_extF80.o +SF_OBJS_OTHERS += f16_to_extF80M.o +SF_OBJS_OTHERS += f16_to_f128.o +SF_OBJS_OTHERS += f16_to_f128M.o +SF_OBJS_OTHERS += f16_roundToInt.o +SF_OBJS_OTHERS += f16_add.o +SF_OBJS_OTHERS += f16_sub.o +SF_OBJS_OTHERS += f16_mul.o +SF_OBJS_OTHERS += f16_mulAdd.o +SF_OBJS_OTHERS += f16_div.o +SF_OBJS_OTHERS += f16_rem.o +SF_OBJS_OTHERS += f16_sqrt.o +SF_OBJS_OTHERS += f16_eq.o +SF_OBJS_OTHERS += f16_le.o +SF_OBJS_OTHERS += f16_lt.o +SF_OBJS_OTHERS += f16_eq_signaling.o +SF_OBJS_OTHERS += f16_le_quiet.o +SF_OBJS_OTHERS += f16_lt_quiet.o +SF_OBJS_OTHERS += f16_isSignalingNaN.o +SF_OBJS_OTHERS += f32_to_ui32.o +SF_OBJS_OTHERS += f32_to_ui64.o +SF_OBJS_OTHERS += f32_to_i32.o +SF_OBJS_OTHERS += f32_to_i64.o +SF_OBJS_OTHERS += f32_to_ui32_r_minMag.o +SF_OBJS_OTHERS += f32_to_ui64_r_minMag.o +SF_OBJS_OTHERS += f32_to_i32_r_minMag.o +SF_OBJS_OTHERS += f32_to_i64_r_minMag.o +SF_OBJS_OTHERS += f32_to_f16.o +SF_OBJS_OTHERS += f32_to_f64.o +SF_OBJS_OTHERS += f32_to_extF80.o +SF_OBJS_OTHERS += f32_to_extF80M.o +SF_OBJS_OTHERS += f32_to_f128.o +SF_OBJS_OTHERS += f32_to_f128M.o +SF_OBJS_OTHERS += f32_roundToInt.o +SF_OBJS_OTHERS += f32_add.o +SF_OBJS_OTHERS += f32_sub.o +SF_OBJS_OTHERS += f32_mul.o +SF_OBJS_OTHERS += f32_mulAdd.o +SF_OBJS_OTHERS += f32_div.o +SF_OBJS_OTHERS += f32_rem.o +SF_OBJS_OTHERS += f32_sqrt.o +SF_OBJS_OTHERS += f32_eq.o +SF_OBJS_OTHERS += f32_le.o +SF_OBJS_OTHERS += f32_lt.o +SF_OBJS_OTHERS += f32_eq_signaling.o +SF_OBJS_OTHERS += f32_le_quiet.o +SF_OBJS_OTHERS += f32_lt_quiet.o +SF_OBJS_OTHERS += f32_isSignalingNaN.o +SF_OBJS_OTHERS += f64_to_ui32.o +SF_OBJS_OTHERS += f64_to_ui64.o +SF_OBJS_OTHERS += f64_to_i32.o +SF_OBJS_OTHERS += f64_to_i64.o +SF_OBJS_OTHERS += f64_to_ui32_r_minMag.o +SF_OBJS_OTHERS += f64_to_ui64_r_minMag.o +SF_OBJS_OTHERS += f64_to_i32_r_minMag.o +SF_OBJS_OTHERS += f64_to_i64_r_minMag.o +SF_OBJS_OTHERS += f64_to_f16.o +SF_OBJS_OTHERS += f64_to_f32.o +SF_OBJS_OTHERS += f64_to_extF80.o +SF_OBJS_OTHERS += f64_to_extF80M.o +SF_OBJS_OTHERS += f64_to_f128.o +SF_OBJS_OTHERS += f64_to_f128M.o +SF_OBJS_OTHERS += f64_roundToInt.o +SF_OBJS_OTHERS += f64_add.o +SF_OBJS_OTHERS += f64_sub.o +SF_OBJS_OTHERS += f64_mul.o +SF_OBJS_OTHERS += f64_mulAdd.o +SF_OBJS_OTHERS += f64_div.o +SF_OBJS_OTHERS += f64_rem.o +SF_OBJS_OTHERS += f64_sqrt.o +SF_OBJS_OTHERS += f64_eq.o +SF_OBJS_OTHERS += f64_le.o +SF_OBJS_OTHERS += f64_lt.o +SF_OBJS_OTHERS += f64_eq_signaling.o +SF_OBJS_OTHERS += f64_le_quiet.o +SF_OBJS_OTHERS += f64_lt_quiet.o +SF_OBJS_OTHERS += f64_isSignalingNaN.o +SF_OBJS_OTHERS += extF80_to_ui32.o +SF_OBJS_OTHERS += extF80_to_ui64.o +SF_OBJS_OTHERS += extF80_to_i32.o +SF_OBJS_OTHERS += extF80_to_i64.o +SF_OBJS_OTHERS += extF80_to_ui32_r_minMag.o +SF_OBJS_OTHERS += extF80_to_ui64_r_minMag.o +SF_OBJS_OTHERS += extF80_to_i32_r_minMag.o +SF_OBJS_OTHERS += extF80_to_i64_r_minMag.o +SF_OBJS_OTHERS += extF80_to_f16.o +SF_OBJS_OTHERS += extF80_to_f32.o +SF_OBJS_OTHERS += extF80_to_f64.o +SF_OBJS_OTHERS += extF80_to_f128.o +SF_OBJS_OTHERS += extF80_roundToInt.o +SF_OBJS_OTHERS += extF80_add.o +SF_OBJS_OTHERS += extF80_sub.o +SF_OBJS_OTHERS += extF80_mul.o +SF_OBJS_OTHERS += extF80_div.o +SF_OBJS_OTHERS += extF80_rem.o +SF_OBJS_OTHERS += extF80_sqrt.o +SF_OBJS_OTHERS += extF80_eq.o +SF_OBJS_OTHERS += extF80_le.o +SF_OBJS_OTHERS += extF80_lt.o +SF_OBJS_OTHERS += extF80_eq_signaling.o +SF_OBJS_OTHERS += extF80_le_quiet.o +SF_OBJS_OTHERS += extF80_lt_quiet.o +SF_OBJS_OTHERS += extF80_isSignalingNaN.o +SF_OBJS_OTHERS += extF80M_to_ui32.o +SF_OBJS_OTHERS += extF80M_to_ui64.o +SF_OBJS_OTHERS += extF80M_to_i32.o +SF_OBJS_OTHERS += extF80M_to_i64.o +SF_OBJS_OTHERS += extF80M_to_ui32_r_minMag.o +SF_OBJS_OTHERS += extF80M_to_ui64_r_minMag.o +SF_OBJS_OTHERS += extF80M_to_i32_r_minMag.o +SF_OBJS_OTHERS += extF80M_to_i64_r_minMag.o +SF_OBJS_OTHERS += extF80M_to_f16.o +SF_OBJS_OTHERS += extF80M_to_f32.o +SF_OBJS_OTHERS += extF80M_to_f64.o +SF_OBJS_OTHERS += extF80M_to_f128M.o +SF_OBJS_OTHERS += extF80M_roundToInt.o +SF_OBJS_OTHERS += extF80M_add.o +SF_OBJS_OTHERS += extF80M_sub.o +SF_OBJS_OTHERS += extF80M_mul.o +SF_OBJS_OTHERS += extF80M_div.o +SF_OBJS_OTHERS += extF80M_rem.o +SF_OBJS_OTHERS += extF80M_sqrt.o +SF_OBJS_OTHERS += extF80M_eq.o +SF_OBJS_OTHERS += extF80M_le.o +SF_OBJS_OTHERS += extF80M_lt.o +SF_OBJS_OTHERS += extF80M_eq_signaling.o +SF_OBJS_OTHERS += extF80M_le_quiet.o +SF_OBJS_OTHERS += extF80M_lt_quiet.o +SF_OBJS_OTHERS += f128_to_ui32.o +SF_OBJS_OTHERS += f128_to_ui64.o +SF_OBJS_OTHERS += f128_to_i32.o +SF_OBJS_OTHERS += f128_to_i64.o +SF_OBJS_OTHERS += f128_to_ui32_r_minMag.o +SF_OBJS_OTHERS += f128_to_ui64_r_minMag.o +SF_OBJS_OTHERS += f128_to_i32_r_minMag.o +SF_OBJS_OTHERS += f128_to_i64_r_minMag.o +SF_OBJS_OTHERS += f128_to_f16.o +SF_OBJS_OTHERS += f128_to_f32.o +SF_OBJS_OTHERS += f128_to_extF80.o +SF_OBJS_OTHERS += f128_to_f64.o +SF_OBJS_OTHERS += f128_roundToInt.o +SF_OBJS_OTHERS += f128_add.o +SF_OBJS_OTHERS += f128_sub.o +SF_OBJS_OTHERS += f128_mul.o +SF_OBJS_OTHERS += f128_mulAdd.o +SF_OBJS_OTHERS += f128_div.o +SF_OBJS_OTHERS += f128_rem.o +SF_OBJS_OTHERS += f128_sqrt.o +SF_OBJS_OTHERS += f128_eq.o +SF_OBJS_OTHERS += f128_le.o +SF_OBJS_OTHERS += f128_lt.o +SF_OBJS_OTHERS += f128_eq_signaling.o +SF_OBJS_OTHERS += f128_le_quiet.o +SF_OBJS_OTHERS += f128_lt_quiet.o +SF_OBJS_OTHERS += f128_isSignalingNaN.o +SF_OBJS_OTHERS += f128M_to_ui32.o +SF_OBJS_OTHERS += f128M_to_ui64.o +SF_OBJS_OTHERS += f128M_to_i32.o +SF_OBJS_OTHERS += f128M_to_i64.o +SF_OBJS_OTHERS += f128M_to_ui32_r_minMag.o +SF_OBJS_OTHERS += f128M_to_ui64_r_minMag.o +SF_OBJS_OTHERS += f128M_to_i32_r_minMag.o +SF_OBJS_OTHERS += f128M_to_i64_r_minMag.o +SF_OBJS_OTHERS += f128M_to_f16.o +SF_OBJS_OTHERS += f128M_to_f32.o +SF_OBJS_OTHERS += f128M_to_extF80M.o +SF_OBJS_OTHERS += f128M_to_f64.o +SF_OBJS_OTHERS += f128M_roundToInt.o +SF_OBJS_OTHERS += f128M_add.o +SF_OBJS_OTHERS += f128M_sub.o +SF_OBJS_OTHERS += f128M_mul.o +SF_OBJS_OTHERS += f128M_mulAdd.o +SF_OBJS_OTHERS += f128M_div.o +SF_OBJS_OTHERS += f128M_rem.o +SF_OBJS_OTHERS += f128M_sqrt.o +SF_OBJS_OTHERS += f128M_eq.o +SF_OBJS_OTHERS += f128M_le.o +SF_OBJS_OTHERS += f128M_lt.o +SF_OBJS_OTHERS += f128M_eq_signaling.o +SF_OBJS_OTHERS += f128M_le_quiet.o +SF_OBJS_OTHERS += f128M_lt_quiet.o + +SF_OBJS_ALL_NOSPEC := +SF_OBJS_ALL_NOSPEC += $(SF_OBJS_PRIMITIVES) +SF_OBJS_ALL_NOSPEC += $(SF_OBJS_OTHERS) + +SF_OBJS_ALL := +SF_OBJS_ALL += $(SF_OBJS_ALL_NOSPEC) +SF_OBJS_ALL += $(SF_OBJS_SPECIALIZE) + +# testfloat objects +TF_OBJS_GENCASES := +TF_OBJS_GENCASES += genCases_ui32.o +TF_OBJS_GENCASES += genCases_ui64.o +TF_OBJS_GENCASES += genCases_i32.o +TF_OBJS_GENCASES += genCases_i64.o +TF_OBJS_GENCASES += genCases_f16.o +TF_OBJS_GENCASES += genCases_f32.o +TF_OBJS_GENCASES += genCases_f64.o +TF_OBJS_GENCASES += genCases_extF80.o +TF_OBJS_GENCASES += genCases_f128.o + +TF_OBJS_WRITECASE := +TF_OBJS_WRITECASE += writeCase_a_ui32.o +TF_OBJS_WRITECASE += writeCase_a_ui64.o +TF_OBJS_WRITECASE += writeCase_a_f16.o +TF_OBJS_WRITECASE += writeCase_ab_f16.o +TF_OBJS_WRITECASE += writeCase_abc_f16.o +TF_OBJS_WRITECASE += writeCase_a_f32.o +TF_OBJS_WRITECASE += writeCase_ab_f32.o +TF_OBJS_WRITECASE += writeCase_abc_f32.o +TF_OBJS_WRITECASE += writeCase_a_f64.o +TF_OBJS_WRITECASE += writeCase_ab_f64.o +TF_OBJS_WRITECASE += writeCase_abc_f64.o +TF_OBJS_WRITECASE += writeCase_a_extF80M.o +TF_OBJS_WRITECASE += writeCase_ab_extF80M.o +TF_OBJS_WRITECASE += writeCase_a_f128M.o +TF_OBJS_WRITECASE += writeCase_ab_f128M.o +TF_OBJS_WRITECASE += writeCase_abc_f128M.o +TF_OBJS_WRITECASE += writeCase_z_bool.o +TF_OBJS_WRITECASE += writeCase_z_ui32.o +TF_OBJS_WRITECASE += writeCase_z_ui64.o +TF_OBJS_WRITECASE += writeCase_z_f16.o +TF_OBJS_WRITECASE += writeCase_z_f32.o +TF_OBJS_WRITECASE += writeCase_z_f64.o +TF_OBJS_WRITECASE += writeCase_z_extF80M.o +TF_OBJS_WRITECASE += writeCase_z_f128M.o + +TF_OBJS_TEST := +TF_OBJS_TEST += test_a_ui32_z_f16.o +TF_OBJS_TEST += test_a_ui32_z_f32.o +TF_OBJS_TEST += test_a_ui32_z_f64.o +TF_OBJS_TEST += test_a_ui32_z_extF80.o +TF_OBJS_TEST += test_a_ui32_z_f128.o +TF_OBJS_TEST += test_a_ui64_z_f16.o +TF_OBJS_TEST += test_a_ui64_z_f32.o +TF_OBJS_TEST += test_a_ui64_z_f64.o +TF_OBJS_TEST += test_a_ui64_z_extF80.o +TF_OBJS_TEST += test_a_ui64_z_f128.o +TF_OBJS_TEST += test_a_i32_z_f16.o +TF_OBJS_TEST += test_a_i32_z_f32.o +TF_OBJS_TEST += test_a_i32_z_f64.o +TF_OBJS_TEST += test_a_i32_z_extF80.o +TF_OBJS_TEST += test_a_i32_z_f128.o +TF_OBJS_TEST += test_a_i64_z_f16.o +TF_OBJS_TEST += test_a_i64_z_f32.o +TF_OBJS_TEST += test_a_i64_z_f64.o +TF_OBJS_TEST += test_a_i64_z_extF80.o +TF_OBJS_TEST += test_a_i64_z_f128.o +TF_OBJS_TEST += test_a_f16_z_ui32_rx.o +TF_OBJS_TEST += test_a_f16_z_ui64_rx.o +TF_OBJS_TEST += test_a_f16_z_i32_rx.o +TF_OBJS_TEST += test_a_f16_z_i64_rx.o +TF_OBJS_TEST += test_a_f16_z_ui32_x.o +TF_OBJS_TEST += test_a_f16_z_ui64_x.o +TF_OBJS_TEST += test_a_f16_z_i32_x.o +TF_OBJS_TEST += test_a_f16_z_i64_x.o +TF_OBJS_TEST += test_a_f16_z_f32.o +TF_OBJS_TEST += test_a_f16_z_f64.o +TF_OBJS_TEST += test_a_f16_z_extF80.o +TF_OBJS_TEST += test_a_f16_z_f128.o +TF_OBJS_TEST += test_az_f16.o +TF_OBJS_TEST += test_az_f16_rx.o +TF_OBJS_TEST += test_abz_f16.o +TF_OBJS_TEST += test_abcz_f16.o +TF_OBJS_TEST += test_ab_f16_z_bool.o +TF_OBJS_TEST += test_a_f32_z_ui32_rx.o +TF_OBJS_TEST += test_a_f32_z_ui64_rx.o +TF_OBJS_TEST += test_a_f32_z_i32_rx.o +TF_OBJS_TEST += test_a_f32_z_i64_rx.o +TF_OBJS_TEST += test_a_f32_z_ui32_x.o +TF_OBJS_TEST += test_a_f32_z_ui64_x.o +TF_OBJS_TEST += test_a_f32_z_i32_x.o +TF_OBJS_TEST += test_a_f32_z_i64_x.o +TF_OBJS_TEST += test_a_f32_z_f16.o +TF_OBJS_TEST += test_a_f32_z_f64.o +TF_OBJS_TEST += test_a_f32_z_extF80.o +TF_OBJS_TEST += test_a_f32_z_f128.o +TF_OBJS_TEST += test_az_f32.o +TF_OBJS_TEST += test_az_f32_rx.o +TF_OBJS_TEST += test_abz_f32.o +TF_OBJS_TEST += test_abcz_f32.o +TF_OBJS_TEST += test_ab_f32_z_bool.o +TF_OBJS_TEST += test_a_f64_z_ui32_rx.o +TF_OBJS_TEST += test_a_f64_z_ui64_rx.o +TF_OBJS_TEST += test_a_f64_z_i32_rx.o +TF_OBJS_TEST += test_a_f64_z_i64_rx.o +TF_OBJS_TEST += test_a_f64_z_ui32_x.o +TF_OBJS_TEST += test_a_f64_z_ui64_x.o +TF_OBJS_TEST += test_a_f64_z_i32_x.o +TF_OBJS_TEST += test_a_f64_z_i64_x.o +TF_OBJS_TEST += test_a_f64_z_f16.o +TF_OBJS_TEST += test_a_f64_z_f32.o +TF_OBJS_TEST += test_a_f64_z_extF80.o +TF_OBJS_TEST += test_a_f64_z_f128.o +TF_OBJS_TEST += test_az_f64.o +TF_OBJS_TEST += test_az_f64_rx.o +TF_OBJS_TEST += test_abz_f64.o +TF_OBJS_TEST += test_abcz_f64.o +TF_OBJS_TEST += test_ab_f64_z_bool.o +TF_OBJS_TEST += test_a_extF80_z_ui32_rx.o +TF_OBJS_TEST += test_a_extF80_z_ui64_rx.o +TF_OBJS_TEST += test_a_extF80_z_i32_rx.o +TF_OBJS_TEST += test_a_extF80_z_i64_rx.o +TF_OBJS_TEST += test_a_extF80_z_ui32_x.o +TF_OBJS_TEST += test_a_extF80_z_ui64_x.o +TF_OBJS_TEST += test_a_extF80_z_i32_x.o +TF_OBJS_TEST += test_a_extF80_z_i64_x.o +TF_OBJS_TEST += test_a_extF80_z_f16.o +TF_OBJS_TEST += test_a_extF80_z_f32.o +TF_OBJS_TEST += test_a_extF80_z_f64.o +TF_OBJS_TEST += test_a_extF80_z_f128.o +TF_OBJS_TEST += test_az_extF80.o +TF_OBJS_TEST += test_az_extF80_rx.o +TF_OBJS_TEST += test_abz_extF80.o +TF_OBJS_TEST += test_ab_extF80_z_bool.o +TF_OBJS_TEST += test_a_f128_z_ui32_rx.o +TF_OBJS_TEST += test_a_f128_z_ui64_rx.o +TF_OBJS_TEST += test_a_f128_z_i32_rx.o +TF_OBJS_TEST += test_a_f128_z_i64_rx.o +TF_OBJS_TEST += test_a_f128_z_ui32_x.o +TF_OBJS_TEST += test_a_f128_z_ui64_x.o +TF_OBJS_TEST += test_a_f128_z_i32_x.o +TF_OBJS_TEST += test_a_f128_z_i64_x.o +TF_OBJS_TEST += test_a_f128_z_f16.o +TF_OBJS_TEST += test_a_f128_z_f32.o +TF_OBJS_TEST += test_a_f128_z_f64.o +TF_OBJS_TEST += test_a_f128_z_extF80.o +TF_OBJS_TEST += test_az_f128.o +TF_OBJS_TEST += test_az_f128_rx.o +TF_OBJS_TEST += test_abz_f128.o +TF_OBJS_TEST += test_abcz_f128.o +TF_OBJS_TEST += test_ab_f128_z_bool.o + +TF_OBJS_LIB := +TF_OBJS_LIB += uint128_inline.o +TF_OBJS_LIB += uint128.o +TF_OBJS_LIB += fail.o +TF_OBJS_LIB += functions_common.o +TF_OBJS_LIB += functionInfos.o +TF_OBJS_LIB += standardFunctionInfos.o +TF_OBJS_LIB += random.o +TF_OBJS_LIB += genCases_common.o +TF_OBJS_LIB += $(TF_OBJS_GENCASES) +TF_OBJS_LIB += genCases_writeTestsTotal.o +TF_OBJS_LIB += verCases_inline.o +TF_OBJS_LIB += verCases_common.o +TF_OBJS_LIB += verCases_writeFunctionName.o +TF_OBJS_LIB += readHex.o +TF_OBJS_LIB += writeHex.o +TF_OBJS_LIB += $(TF_OBJS_WRITECASE) +TF_OBJS_LIB += testLoops_common.o +TF_OBJS_LIB += $(TF_OBJS_TEST) + +BINARIES := fp-test$(EXESUF) + +# everything depends on config-host.h because platform.h includes it +all: $(BUILD_DIR)/config-host.h + $(MAKE) $(BINARIES) + +$(LIBQEMUUTIL): + $(MAKE) -C $(BUILD_DIR) libqemuutil.a + +$(BUILD_DIR)/config-host.h: + $(MAKE) -C $(BUILD_DIR) config-host.h + +# libtestfloat.a depends on libsoftfloat.a, so specify it first +FP_TEST_LIBS := libtestfloat.a libsoftfloat.a $(LIBQEMUUTIL) + +fp-test$(EXESUF): fp-test.o slowfloat.o $(QEMU_SOFTFLOAT_OBJ) $(FP_TEST_LIBS) + +# Custom rule to build with SF_CFLAGS +SF_BUILD = $(call quiet-command,$(CC) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \ + $(QEMU_CFLAGS) $(SF_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) \ + $($@-cflags) -c -o $@ $<,"CC","$(TARGET_DIR)$@") + +$(SF_OBJS_ALL_NOSPEC): %.o: $(SF_SOURCE_DIR)/%.c + $(SF_BUILD) +$(SF_OBJS_SPECIALIZE): %.o: $(SF_SPECIALIZE_DIR)/%.c + $(SF_BUILD) + +libsoftfloat.a: $(SF_OBJS_ALL) + +# Custom rule to build with TF_CFLAGS +$(TF_OBJS_LIB) slowfloat.o: %.o: $(TF_SOURCE_DIR)/%.c + $(call quiet-command,$(CC) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \ + $(QEMU_CFLAGS) $(TF_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) \ + $($@-cflags) -c -o $@ $<,"CC","$(TARGET_DIR)$@") + +libtestfloat.a: $(TF_OBJS_LIB) + +clean: + rm -f *.o *.d $(BINARIES) + rm -f *.gcno *.gcda *.gcov + rm -f fp-test$(EXESUF) + rm -f libsoftfloat.a + rm -f libtestfloat.a + +-include $(wildcard *.d) From patchwork Fri Oct 5 18:01:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 148295 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp771059lji; Fri, 5 Oct 2018 11:20:22 -0700 (PDT) X-Google-Smtp-Source: ACcGV611/N6mC2RfHxpl8f/kjSBJJ2ri3ExUiYQYHNIw3vQLrDYcFdm1HMX5FiDEkom8FHgf+CBh X-Received: by 2002:a37:a512:: with SMTP id o18-v6mr9695908qke.232.1538763622170; Fri, 05 Oct 2018 11:20:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538763622; cv=none; d=google.com; s=arc-20160816; b=q+NTayhHseNXc3lxPNARtPa75KSh57xnNrnt4OoUxxjIGkqA0UD/dna9opLE0E4b3d iN31Tm2mT6Ro9+8WHTRfmel0eFfywdwI1hnjGY0zlmeFmodqayM83JXcYusNYnAYE2nV GFC5RgTZulkXhqzcTEI5+0ywGgHa+0Q5A0CWyocMVgL6D97jzy+KkRGPFNxt2NKVWrpw ItvtzfMwWAYBoPQfBOfULhKITlAhceiomSLjGb4xin+CMcikzU9Ym+CyI7QD/+FKp6lk r2MiD5v71kpA9RE9chrw+6253TThvX34sNozyPCm4O0g5fZ1ZztIGD2S//gwgl/6u8cf 9wDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=DwGVwZ74JFosJt80rbYq2MM2myPeHP9EtmhcPJDQx9A=; b=zhMjoWevZ+CmooKk39YB0Op1mbUwokPEDo//xSixGoOv5e3u7JvsH/KrzT6xgC+7+s KEwAZF/gp8aYPfsDe3v+5BiMjCtcb4EOr9it8N2Bv232AOKcgs7qGpkuNy9yxo6/21n6 zZZsRtbbtWY0bsuY+RFC75hf5zxF48iDxlGfZfVB299bXuUy8p9dAnPnCRiL/qSORI0q PlSSALf2R77AZF09Ro6u66ps90owLJfvMMntCa4WzLbUrFSL93CIkwSKXK3h867GxRUX 6NO1k8WQfQoDyAG2/nLNwMZO6bkKn/4CFhExrZpXnHE5BCAUXJEJKgZq0LbKryd5nGll kknQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=SMVivl8n; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id d188-v6si363063qkc.57.2018.10.05.11.20.21 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 05 Oct 2018 11:20:22 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=SMVivl8n; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:36489 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8Ui5-0002Y3-Jh for patch@linaro.org; Fri, 05 Oct 2018 14:20:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38560) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UQd-0000U1-4E for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g8UQZ-0004Cq-As for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:17 -0400 Received: from mail-oi1-x234.google.com ([2607:f8b0:4864:20::234]:41009) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g8UQY-00046m-SC for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:15 -0400 Received: by mail-oi1-x234.google.com with SMTP id l197-v6so11096620oib.8 for ; Fri, 05 Oct 2018 11:02:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=DwGVwZ74JFosJt80rbYq2MM2myPeHP9EtmhcPJDQx9A=; b=SMVivl8nZuNqVBj7CV4cAnTSWn0BIsrv3tSDsvJtJ3WlZFngNPlYjW59XGE/ZqRyOa P9eBiO4mBP887C88xbZ5JL4T0LXc9Hp/HY7y2m80WyTU4aQfD2Uaac1fUWGEYDH3rg5V +M2Ewkc7V9Qd6aebLxhGn8WkZfAjBqoEiH/vY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DwGVwZ74JFosJt80rbYq2MM2myPeHP9EtmhcPJDQx9A=; b=j80dF51NGOKn2fA8K20dzZepaewZtrUQhB+uDr8tjVzkbYjMQ8yMdfPzJHs9E4Tf6y j58b/wJexrGsUDgbTIwPUPZKiFiieHC9AZabiCw5ukATajbkuUo3s92+hIHryCLzJGsU EaBjFzJFBzomMmvGkg3gQZ4Oa7o4JqpjU6eaz759KVuVT2zBVWD3tSrJfhBqaIGz+Fuu F/ObRJbVccbeAFXcz48uxU2kXJ63VVDeeCAZLgy1K77KAoXLIIeUmS6RuwS3Auqbm5ih O+D1Zn0hyezu9RjuglhF2ivRNhYX8wKnQLnbnRcimbpqVTinioo/QwPU221uVi6puTJD Omuw== X-Gm-Message-State: ABuFfoib/u6Ehl8NslSqY2vNbA5CMjbv/tqi2a5KWOMJaNscV1t1vU1f gJhnqIWwVfvyNVF3lEXGOB6MR0Et3wUMm7fujyk= X-Received: by 2002:aca:50c1:: with SMTP id e184-v6mr35039oib.264.1538762533644; Fri, 05 Oct 2018 11:02:13 -0700 (PDT) Received: from cloudburst.twiddle.net ([187.217.230.84]) by smtp.gmail.com with ESMTPSA id d37-v6sm2601302otb.0.2018.10.05.11.02.12 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 05 Oct 2018 11:02:12 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 5 Oct 2018 13:01:57 -0500 Message-Id: <20181005180201.11387-5-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181005180201.11387-1-richard.henderson@linaro.org> References: <20181005180201.11387-1-richard.henderson@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::234 Subject: [Qemu-devel] [PULL 4/8] softfloat: Replace countLeadingZeros32/64 with clz32/64 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Thomas Huth Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Thomas Huth Our minimum required compiler for compiling QEMU is GCC 4.1 these days, so we can drop the support for compilers which do not provide the __builtin_clz*() functions yet. Since the countLeadingZeros32/64 are then identical to the clz32/64 functions, and we do not have to sync the softloat 2 codebase with upstream anymore (softloat 3 is a complete rewrite) we can simply replace the functions with our QEMU versions. Suggested-by: Peter Maydell Acked-by: Alex Bennée Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Thomas Huth Message-Id: <1538118095-7003-1-git-send-email-thuth@redhat.com> Signed-off-by: Richard Henderson --- include/fpu/softfloat-macros.h | 87 ---------------------------------- fpu/softfloat.c | 26 +++++----- 2 files changed, 13 insertions(+), 100 deletions(-) -- 2.17.1 diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index 35e1603a5e..edc682139e 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -79,17 +79,6 @@ this code that are retained. * version 2 or later. See the COPYING file in the top-level directory. */ -/*---------------------------------------------------------------------------- -| This macro tests for minimum version of the GNU C compiler. -*----------------------------------------------------------------------------*/ -#if defined(__GNUC__) && defined(__GNUC_MINOR__) -# define SOFTFLOAT_GNUC_PREREQ(maj, min) \ - ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) -#else -# define SOFTFLOAT_GNUC_PREREQ(maj, min) 0 -#endif - - /*---------------------------------------------------------------------------- | Shifts `a' right by the number of bits given in `count'. If any nonzero | bits are shifted off, they are ``jammed'' into the least significant bit of @@ -712,82 +701,6 @@ static inline uint32_t estimateSqrt32(int aExp, uint32_t a) } -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 32 is returned. -*----------------------------------------------------------------------------*/ - -static inline int8_t countLeadingZeros32(uint32_t a) -{ -#if SOFTFLOAT_GNUC_PREREQ(3, 4) - if (a) { - return __builtin_clz(a); - } else { - return 32; - } -#else - static const int8_t countLeadingZerosHigh[] = { - 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - int8_t shiftCount; - - shiftCount = 0; - if ( a < 0x10000 ) { - shiftCount += 16; - a <<= 16; - } - if ( a < 0x1000000 ) { - shiftCount += 8; - a <<= 8; - } - shiftCount += countLeadingZerosHigh[ a>>24 ]; - return shiftCount; -#endif -} - -/*---------------------------------------------------------------------------- -| Returns the number of leading 0 bits before the most-significant 1 bit of -| `a'. If `a' is zero, 64 is returned. -*----------------------------------------------------------------------------*/ - -static inline int8_t countLeadingZeros64(uint64_t a) -{ -#if SOFTFLOAT_GNUC_PREREQ(3, 4) - if (a) { - return __builtin_clzll(a); - } else { - return 64; - } -#else - int8_t shiftCount; - - shiftCount = 0; - if ( a < ( (uint64_t) 1 )<<32 ) { - shiftCount += 32; - } - else { - a >>= 32; - } - shiftCount += countLeadingZeros32( a ); - return shiftCount; -#endif -} - /*---------------------------------------------------------------------------- | Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' | is equal to the 128-bit value formed by concatenating `b0' and `b1'. diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 9405f12a03..71da0f68bb 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -2683,7 +2683,7 @@ static void { int8_t shiftCount; - shiftCount = countLeadingZeros32( aSig ) - 8; + shiftCount = clz32(aSig) - 8; *zSigPtr = aSig<>( - shiftCount ); *zSig1Ptr = aSig1<<( shiftCount & 63 ); @@ -3308,7 +3308,7 @@ static void *zExpPtr = - shiftCount - 63; } else { - shiftCount = countLeadingZeros64( aSig0 ) - 15; + shiftCount = clz64(aSig0) - 15; shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr ); *zExpPtr = 1 - shiftCount; } @@ -3497,7 +3497,7 @@ static float128 normalizeRoundAndPackFloat128(flag zSign, int32_t zExp, zSig1 = 0; zExp -= 64; } - shiftCount = countLeadingZeros64( zSig0 ) - 15; + shiftCount = clz64(zSig0) - 15; if ( 0 <= shiftCount ) { zSig2 = 0; shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 ); @@ -3529,7 +3529,7 @@ floatx80 int32_to_floatx80(int32_t a, float_status *status) if ( a == 0 ) return packFloatx80( 0, 0, 0 ); zSign = ( a < 0 ); absA = zSign ? - a : a; - shiftCount = countLeadingZeros32( absA ) + 32; + shiftCount = clz32(absA) + 32; zSig = absA; return packFloatx80( zSign, 0x403E - shiftCount, zSig< X-Patchwork-Id: 148292 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp765483lji; Fri, 5 Oct 2018 11:14:34 -0700 (PDT) X-Google-Smtp-Source: ACcGV63zDb2IIOJwoQxT2vbALS57MCJXgbsMbOyBywKNLSz5Hj//aTPn78SYM4I20ynj8TWH2QXb X-Received: by 2002:aed:2d86:: with SMTP id i6-v6mr10044894qtd.279.1538763274682; Fri, 05 Oct 2018 11:14:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538763274; cv=none; d=google.com; s=arc-20160816; b=d+Fi/W17uEBZubmnW+X+fqj82f60IFd4eA9NBIyGz4R7Vcpqx00XtZl35tA2ShpERt WsMRPeXHaTovXsECFGd7HzMFxjlVABEeDPSmH9cXUrMxqiMy/oR2GXYCfQxSl1lSPP4t hIQniXtzpwvr4ilImthmr3nFmqMrQ7XH318fc8hU4wf2ozmMLPrJkRdcQfjw5s+2+iCP C99iW2VP+47ND3e8A3M/pJG274/+OzqFkb/KVPNSHvPYT8LtO7GL5/Q4oW7X072mS6Eg 5+wCOzZ8e0EZ/QaO1osqO0tIsdwZ530rP+XVllliafteT8ogaRq1WG9e0rlfcog7gaPz Xz3g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=eoQfmeIbqQYNxqFOPaK1rddW7v/35ufvgMSTkPh3uTI=; b=a4N+dNSCAewyKpk/6l8p9rWNkCQK+1soTLsU0jVNUc/tKbz/n5Yoa/8AczcUDuJ7Hc 192zOPoagTdQJvxM2vxSGEZZ7PM2D+qIOOBRSeMe3KjQMtjZxwfnekcdk77qN152Kej/ zThPolDxLRCWmxXnmaOhXHxlbJ1+BixPBE2Vjvp+ChNwiwwu/v51mZEhHDrU4ix17Pxe zKgD/9U5jAm7cmZBB4Iyf7sJz1gtJu9X54xtLLHlH3C79ej32sKFB7QGs8BuRB2IFOYp 8xlGZwc083B7m1BJ45rITCsOvfHypr+wLav1nOK9M8oO13goxedYNnYe8KUEo6dyVlOJ LcsA== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Y4urqlPQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id t29-v6si1315909qvc.47.2018.10.05.11.14.34 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 05 Oct 2018 11:14:34 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=Y4urqlPQ; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:36454 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UcT-0004Xs-MR for patch@linaro.org; Fri, 05 Oct 2018 14:14:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38628) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UQg-0000Wv-K9 for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:29 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g8UQd-0004vB-Km for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:22 -0400 Received: from mail-oi1-x244.google.com ([2607:f8b0:4864:20::244]:43202) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g8UQc-0004KX-KN for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:19 -0400 Received: by mail-oi1-x244.google.com with SMTP id s69-v6so11088230oie.10 for ; Fri, 05 Oct 2018 11:02:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eoQfmeIbqQYNxqFOPaK1rddW7v/35ufvgMSTkPh3uTI=; b=Y4urqlPQlb0iVk4XHPAq48tfS6akXHDuAR9jHvemwZbleKD07q3fLctEHQjkV1u5MB EnuN22uKCoAhZdkA6+QEHuOMIrM7+rU+9ryQ6AN8omaZq3HALCciT1QeApwZEyM497bn ThP+srKswDydp+zFuWcTHcmSlcGtesOSNfJQk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eoQfmeIbqQYNxqFOPaK1rddW7v/35ufvgMSTkPh3uTI=; b=mq9fZwPUBaeeWZ9kshn6TA1H5AcyZYNdZt9biWS4YMDcZy8OxRdOqafbKkGPYTImYC BoV/k5BxCN1yshF5PmDVw/I7c2FVRL5VgXWJw5Hz0GC8Tc/Kdf8bHm/G9DlhoOh+08tG YeZ90WzZ7jiFXHk/OXobpkoATLiX/St3rGUXxCblDowh1CxxgWd+b2jQ/8Ew79lbVEHF xP7kaobQ5+zr10jxlATIpX69gfPQSZmC3Wr6tKplPJVunmqY6MSERWi5EjeJp1+DoL1j cwSzdZcFTBK7A9lTLlN8kglfOcMfHT2KN645b55f4+W6nCwfHdFe7J9OnoUroZOB7/UV I+EQ== X-Gm-Message-State: ABuFfoibAKYyNqMuV0n1ZUSWcr2fSFZYHowy+P1DG9QXr14OS4ceGj+6 5SephnJtT7V2zYUabd/MEPFH0nQfpTF2B7wOkEA= X-Received: by 2002:aca:c402:: with SMTP id u2-v6mr23988oif.141.1538762535269; Fri, 05 Oct 2018 11:02:15 -0700 (PDT) Received: from cloudburst.twiddle.net ([187.217.230.84]) by smtp.gmail.com with ESMTPSA id d37-v6sm2601302otb.0.2018.10.05.11.02.13 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 05 Oct 2018 11:02:14 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 5 Oct 2018 13:01:58 -0500 Message-Id: <20181005180201.11387-6-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181005180201.11387-1-richard.henderson@linaro.org> References: <20181005180201.11387-1-richard.henderson@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::244 Subject: [Qemu-devel] [PULL 5/8] softfloat: Fix division X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The __udiv_qrnnd primitive that we nicked from gmp requires its inputs to be normalized. We were not doing that. Because the inputs are nearly normalized already, finishing that is trivial. Replace div128to64 with a "proper" udiv_qrnnd, so that this remains a reusable primitive. Fixes: cf07323d494 Fixes: https://bugs.launchpad.net/qemu/+bug/1793119 Tested-by: Emilio G. Cota Tested-by: Alex Bennée Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- include/fpu/softfloat-macros.h | 34 ++++++++++++++++++++++++--------- fpu/softfloat.c | 35 ++++++++++++++++++++++++++-------- 2 files changed, 52 insertions(+), 17 deletions(-) -- 2.17.1 diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index edc682139e..a1d99c730d 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -329,15 +329,30 @@ static inline void | pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. *----------------------------------------------------------------------------*/ -static inline void - shortShift128Left( - uint64_t a0, uint64_t a1, int count, uint64_t *z0Ptr, uint64_t *z1Ptr) +static inline void shortShift128Left(uint64_t a0, uint64_t a1, int count, + uint64_t *z0Ptr, uint64_t *z1Ptr) { + *z1Ptr = a1 << count; + *z0Ptr = count == 0 ? a0 : (a0 << count) | (a1 >> (-count & 63)); +} - *z1Ptr = a1<>( ( - count ) & 63 ) ); +/*---------------------------------------------------------------------------- +| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the +| number of bits given in `count'. Any bits shifted off are lost. The value +| of `count' may be greater than 64. The result is broken into two 64-bit +| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. +*----------------------------------------------------------------------------*/ +static inline void shift128Left(uint64_t a0, uint64_t a1, int count, + uint64_t *z0Ptr, uint64_t *z1Ptr) +{ + if (count < 64) { + *z1Ptr = a1 << count; + *z0Ptr = count == 0 ? a0 : (a0 << count) | (a1 >> (-count & 63)); + } else { + *z1Ptr = 0; + *z0Ptr = a1 << (count - 64); + } } /*---------------------------------------------------------------------------- @@ -619,7 +634,8 @@ static inline uint64_t estimateDiv128To64(uint64_t a0, uint64_t a1, uint64_t b) * * Licensed under the GPLv2/LGPLv3 */ -static inline uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d) +static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1, + uint64_t n0, uint64_t d) { uint64_t d0, d1, q0, q1, r1, r0, m; @@ -658,8 +674,8 @@ static inline uint64_t div128To64(uint64_t n0, uint64_t n1, uint64_t d) } r0 -= m; - /* Return remainder in LSB */ - return (q1 << 32) | q0 | (r0 != 0); + *r = r0; + return (q1 << 32) | q0; } /*---------------------------------------------------------------------------- diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 71da0f68bb..46ae206172 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -1112,19 +1112,38 @@ static FloatParts div_floats(FloatParts a, FloatParts b, float_status *s) bool sign = a.sign ^ b.sign; if (a.cls == float_class_normal && b.cls == float_class_normal) { - uint64_t temp_lo, temp_hi; + uint64_t n0, n1, q, r; int exp = a.exp - b.exp; + + /* + * We want a 2*N / N-bit division to produce exactly an N-bit + * result, so that we do not lose any precision and so that we + * do not have to renormalize afterward. If A.frac < B.frac, + * then division would produce an (N-1)-bit result; shift A left + * by one to produce the an N-bit result, and decrement the + * exponent to match. + * + * The udiv_qrnnd algorithm that we're using requires normalization, + * i.e. the msb of the denominator must be set. Since we know that + * DECOMPOSED_BINARY_POINT is msb-1, the inputs must be shifted left + * by one (more), and the remainder must be shifted right by one. + */ if (a.frac < b.frac) { exp -= 1; - shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT + 1, - &temp_hi, &temp_lo); + shift128Left(0, a.frac, DECOMPOSED_BINARY_POINT + 2, &n1, &n0); } else { - shortShift128Left(0, a.frac, DECOMPOSED_BINARY_POINT, - &temp_hi, &temp_lo); + shift128Left(0, a.frac, DECOMPOSED_BINARY_POINT + 1, &n1, &n0); } - /* LSB of quot is set if inexact which roundandpack will use - * to set flags. Yet again we re-use a for the result */ - a.frac = div128To64(temp_lo, temp_hi, b.frac); + q = udiv_qrnnd(&r, n1, n0, b.frac << 1); + + /* + * Set lsb if there is a remainder, to set inexact. + * As mentioned above, to find the actual value of the remainder we + * would need to shift right, but (1) we are only concerned about + * non-zero-ness, and (2) the remainder will always be even because + * both inputs to the division primitive are even. + */ + a.frac = q | (r != 0); a.sign = sign; a.exp = exp; return a; From patchwork Fri Oct 5 18:01:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 148289 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp761795lji; Fri, 5 Oct 2018 11:10:40 -0700 (PDT) X-Google-Smtp-Source: ACcGV61KCwyrQT3PkwRW4G19IXtG4rhcHhhuaAv260P57JBXYuZgfCkKGB2dEFvk8hR+sRKvIBK8 X-Received: by 2002:a0c:b994:: with SMTP id v20-v6mr6005728qvf.110.1538763040358; Fri, 05 Oct 2018 11:10:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538763040; cv=none; d=google.com; s=arc-20160816; b=jx8cRZLtlqYkk+6U0SDlOqXneNjluk791xoi87ThroYHoMCeNlf+EVON84JY6oUOF+ kbK5OF7Z0zSGSXA+PIU7OFOGOEo34IFprZD4MvDk+F4arHW6Zvaagr652Epz6gq1mjd+ 6qkki68nnct84l/LPLuCVjtHkCNbHQJREcXQt+PlPsuiNQbkUWrhmDc0tI9nTDqYJ9Wf WhyIhoIwS3t9Uyq9H+VTcXhcpqB3kYJw2NpyXr67XCsfA0ofJjKRVGSU9pAdMquwwHOj S1LZ1kWQl7okMccFXUZwIgz0hYWXbK//NubeZsqKOhlIzSirqJ2bPwzdnzEU/nWheDtB jSkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=cRmMqmBeH6CVVhBpy5pb3rhG/pnTWg+KHZ8CbvTFIJs=; b=EFtL7Pa/vkYw0KsHXquSE2EXGutfNx2slGovWXTLBMG4yzIQCHB/XlnHDIk2FY3S4P OCvaLgDQ7YKcmkRLMNW3SNNE9ehODXzwheClFylvwKj0Of2U1uscbzynsaktrl/7h1RG isylW8yZSXk3iKOga7X7eBWrcq0ktkenqZNO2SM9X7jUGW3YFq3rGWdUdAGJvyQ+8vdC rU4aU7QxLxRKuFRNiyU7NgyllyLnfapsN56AHDxYI+uVJHF3CVB3feoDYkh6f4kDNLLD 2mhMTFI0O/ruerq5Vn7c1ydkiOEBLq2NEqDVMb3KLHpUv4RkcM/ZtSK1zmjbhro0rpTR s0Vw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=YDGPbONu; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id h52-v6si1052420qtb.233.2018.10.05.11.10.40 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 05 Oct 2018 11:10:40 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=YDGPbONu; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:36429 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UYh-0000vb-Mg for patch@linaro.org; Fri, 05 Oct 2018 14:10:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38633) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UQg-0000Wx-Mz for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g8UQd-0004wA-Oy for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:22 -0400 Received: from mail-oi1-x234.google.com ([2607:f8b0:4864:20::234]:34985) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g8UQd-0004V3-3w for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:19 -0400 Received: by mail-oi1-x234.google.com with SMTP id 22-v6so10114912oiz.2 for ; Fri, 05 Oct 2018 11:02:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cRmMqmBeH6CVVhBpy5pb3rhG/pnTWg+KHZ8CbvTFIJs=; b=YDGPbONuppbjhEjwu1q/ZTnfA2WIo6p3YCVccMgwln8K0M2VkOM11u3LfU7k0YLzZq VqEpPkxGmvJRDUJKDjyNO7R2kvFWZLFiFnBeJM76Dt35v5ygN77RCwQshVrfLn/JBq2U PlHlRJHtW9PeoCE+Gn26HBcbIXXEyFaKlR7fQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cRmMqmBeH6CVVhBpy5pb3rhG/pnTWg+KHZ8CbvTFIJs=; b=RWwr5CXBRpAiI2ncmjgzajgPTK7wmSRaYm2VTRIEOuWyd68f/E07Po5SB1DrT101tP dUNcQRyfcT1fGWQ0OPobC3MqRzkCGJVG/MZOaaOH9aGiNsKABcFLMzJCQeJ7oXzFXoie YRKKwsSzIIcP/623bRyjxLLtRX/svFrHLWnpd+G6V3mQmjf6gmmKu4hg7ZLThw+SYNpV Yx3IVF31oTkB5AV63NiYuageMoAtMZb4w/RWG51lmVb9gCXJ+XvWbH6ufmOwbki/TlpX ZqVf9noqcat2418GHmN4GmQ8A2C3RNk2Q8cFOu4u/r4HR4HJxNko802dk1joi/FfEjWV jcBQ== X-Gm-Message-State: ABuFfojTxv1AAVfMMeHsLsGrvXQTrRXL7vrt/hdY5ZKNuw5B723GhNOq aUsDVYGLmw9/T0/iMFANpWqTQAKCRKXFUXVXy7w= X-Received: by 2002:aca:5e83:: with SMTP id s125-v6mr41726oib.134.1538762536724; Fri, 05 Oct 2018 11:02:16 -0700 (PDT) Received: from cloudburst.twiddle.net ([187.217.230.84]) by smtp.gmail.com with ESMTPSA id d37-v6sm2601302otb.0.2018.10.05.11.02.15 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 05 Oct 2018 11:02:15 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 5 Oct 2018 13:01:59 -0500 Message-Id: <20181005180201.11387-7-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181005180201.11387-1-richard.henderson@linaro.org> References: <20181005180201.11387-1-richard.henderson@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::234 Subject: [Qemu-devel] [PULL 6/8] softfloat: Specialize udiv_qrnnd for x86_64 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The ISA has a 128/64-bit division instruction. Tested-by: Emilio G. Cota Tested-by: Alex Bennée Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- include/fpu/softfloat-macros.h | 6 ++++++ 1 file changed, 6 insertions(+) -- 2.17.1 diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index a1d99c730d..39eb08b4f1 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -637,6 +637,11 @@ static inline uint64_t estimateDiv128To64(uint64_t a0, uint64_t a1, uint64_t b) static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1, uint64_t n0, uint64_t d) { +#if defined(__x86_64__) + uint64_t q; + asm("divq %4" : "=a"(q), "=d"(*r) : "0"(n0), "1"(n1), "rm"(d)); + return q; +#else uint64_t d0, d1, q0, q1, r1, r0, m; d0 = (uint32_t)d; @@ -676,6 +681,7 @@ static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1, *r = r0; return (q1 << 32) | q0; +#endif } /*---------------------------------------------------------------------------- From patchwork Fri Oct 5 18:02:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 148296 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp772341lji; Fri, 5 Oct 2018 11:21:41 -0700 (PDT) X-Google-Smtp-Source: ACcGV63yRO2UOibSmotY+GKy2KflaDXONl3wZvjggSNlN1PzjZ4BSTw6Up9BvsHJmN6WhP9woLUC X-Received: by 2002:a0c:9e2a:: with SMTP id p42-v6mr2134993qve.134.1538763701336; Fri, 05 Oct 2018 11:21:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538763701; cv=none; d=google.com; s=arc-20160816; b=I+ca3r73DRMZhIrthGoHI+Ckp2seOemYXoNFQRsmpMG2fCxoG0LVjmIL1S6v7+U4uS iRuEkDpKl+D7LBiD4UzFpEYqid0lylzUu1qpdmeOah5LPfYqcuiuklt7iXDLEmJHygOW /fUfZ/ULuwTgMgzw/7HNl6IvQ0WCTmSDg9nEaaUfe81ufKnul3V34nlgpM0ofXa5h9K6 12OE+hhT5Vu5UVEFFCOroWi0GXEhOzMf9G5cOxRUZTfeGb01x06w7ZJIxSx4lAc3OYvW 4AQ/30wm3TM/MqoBsl/5q7j0FKk0z93l9DADCChbLegBi9w7dq0jlxZQX2hjy6i+AKQs lC6Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=MiYu2qxs2TIckutvBEbRpqLjWZytY+tnsLPRmBRwkMs=; b=QODqgteuHscStToGi/6PKUsjA5q3LodRCf9Znho4wC2l6FK/0FhcVPIFC1A8/9mT2B zZ3IhGqxxmfpjro0ojoDo4SuPdI/yfUI8fTQ8Ks6xjr0qk+3QfXX6IUsrcApDcxBCUZ3 nIAN1bupkc9irsScyLnEz7wpsb6SYZ8JVVynvmbVCd86DWg6iODN3Haonq0GwCAelBM6 6H7VBCfo1Y/7yHNH+Xs7dATwLpsg3oYKBlL/WhZXHChYznZqemCBm0JafUoCDAjB02cj r0wlgvZ6iYAsOJ8b9NXBZfne/cplE3XdrTAx9g3I++8vCmtKrkS5+x+CVsukPtll9znG O0Sw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=JBQSauyq; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id y10-v6si6315810qtm.166.2018.10.05.11.21.41 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 05 Oct 2018 11:21:41 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=JBQSauyq; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:36496 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UjM-0003bF-Qm for patch@linaro.org; Fri, 05 Oct 2018 14:21:40 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38629) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UQg-0000Ww-Kb for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g8UQe-0004zE-53 for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:22 -0400 Received: from mail-oi1-x242.google.com ([2607:f8b0:4864:20::242]:44313) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g8UQd-0004qk-Ot for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:19 -0400 Received: by mail-oi1-x242.google.com with SMTP id u74-v6so11073086oia.11 for ; Fri, 05 Oct 2018 11:02:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=MiYu2qxs2TIckutvBEbRpqLjWZytY+tnsLPRmBRwkMs=; b=JBQSauyqkxppjxVmfbo7j+LZgi/zJ3N7wXVYcPQYEGxix4kz3JI9qf6C5KneW3dyiN zZAKTeTqwbiHLyuZWy2oXUMzJ80wb8+ekzOXakeL7AKznrIStlKJuwfdVm0ld2ICrViG dXiZw/vWWFqdEdqVayfDP4e8QbTJCabWtopes= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=MiYu2qxs2TIckutvBEbRpqLjWZytY+tnsLPRmBRwkMs=; b=D/nYQAyUFjVo5MJbBgwMw6DkoHP0Pto3dE2YZn/5A2/iDilY5dlQnphb6HH8hFS9Xb swDraKtW0oqkCeHT89bCTwu4Gwf2NN4rGixll5UDV4/t74QbbR8/Rkfj4cJjLFsx56nu RbvDcTgM4gXTWPjjzO13gRWROPNbo4tE8AaYD0DArzBWpH2g73XRkbxJ4HdK9PqS/h5V PzR5otBwso5cgYaYnzqKi693AX2+arUSpLdc/QWfI36p4FEPXRslmz9bRbDZD+dDTqwB +ttnDzlT3Ujs3k4NVV30wINA4MXU8GWzV2pKQkG3KSP2ulHZsnqoU10Yk7L150uI2/id iaaA== X-Gm-Message-State: ABuFfojbHWJUu29jAompkcX4j5CfzQCSnEYhNJp2YDq8k+pWCrxIPW/p DUriQ2kaK9nJFvq3YiOUpTGaGkGsKJWWs+ZMUqI= X-Received: by 2002:aca:f512:: with SMTP id t18-v6mr34715oih.244.1538762538473; Fri, 05 Oct 2018 11:02:18 -0700 (PDT) Received: from cloudburst.twiddle.net ([187.217.230.84]) by smtp.gmail.com with ESMTPSA id d37-v6sm2601302otb.0.2018.10.05.11.02.17 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 05 Oct 2018 11:02:17 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 5 Oct 2018 13:02:00 -0500 Message-Id: <20181005180201.11387-8-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181005180201.11387-1-richard.henderson@linaro.org> References: <20181005180201.11387-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::242 Subject: [Qemu-devel] [PULL 7/8] softfloat: Specialize udiv_qrnnd for s390x X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The ISA has a 128/64-bit division instruction. Reviewed-by: David Hildenbrand Signed-off-by: Richard Henderson --- include/fpu/softfloat-macros.h | 6 ++++++ 1 file changed, 6 insertions(+) -- 2.17.1 diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index 39eb08b4f1..eafc68932b 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -641,6 +641,12 @@ static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1, uint64_t q; asm("divq %4" : "=a"(q), "=d"(*r) : "0"(n0), "1"(n1), "rm"(d)); return q; +#elif defined(__s390x__) + /* Need to use a TImode type to get an even register pair for DLGR. */ + unsigned __int128 n = (unsigned __int128)n1 << 64 | n0; + asm("dlgr %0, %1" : "+r"(n) : "r"(d)); + *r = n >> 64; + return n; #else uint64_t d0, d1, q0, q1, r1, r0, m; From patchwork Fri Oct 5 18:02:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 148284 Delivered-To: patch@linaro.org Received: by 2002:a2e:8595:0:0:0:0:0 with SMTP id b21-v6csp757250lji; Fri, 5 Oct 2018 11:06:19 -0700 (PDT) X-Google-Smtp-Source: ACcGV62tzQdKpf2pcSpkSbOR0O8p+zwD+G/Hv8EHlwAQ2cL/gipjY4xG4StIwQilE5fUN2oQqu5S X-Received: by 2002:ac8:26b9:: with SMTP id 54-v6mr10306423qto.281.1538762779013; Fri, 05 Oct 2018 11:06:19 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1538762779; cv=none; d=google.com; s=arc-20160816; b=ucqaxLfbQKNtTKZgWZEjshtqQwFoDy1kJYaWuhXm7874PGnUphspAVB12pJnVlNQ5D VMMUpPMohcwHDaDHTZQX8STNEvI9kqBsMM0920Ww2t5dctb2LgEPn3KpWbSkhkTxPGQv GnH1Ex7ccMrXs5JMTKTNffGu3XpfSjdZFocXj+Af7Axd8C/2FVVUUT0GNiG8tahGKKmd Yfy7rugjAdmeaX9pyVr/vGr4gBQ8SaI1tMl1bMNDBjkizsvRXxFcOO6jOBfeBEW3+1kY QjlpER43ZlPypUU5OtDEBHDfzBWcKppEwkVrVFEb6dfQZyKSfQEtjAbT3ZAlRDyMwJ8I nbVA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:dkim-signature; bh=X5a/KvnsV8gRrymCZvMRPaAHMUoAfW8yBsI+pfK7k9k=; b=K/evaSlGp2VW8HOJ2Vh0shSZILPiSbfaoP2x4x0rngj6+B1bwj4dPOgOroKQNH5KSW JRNF6sqa9+Gbp2i9HOli5+5gZQ1hmbySwk8neecxcVnayo6LGUDLEGJsovm4yA01RMmn MokMboIqie3b3tOCeaB6CqkzN4IZ8FkAbO+l5T0NaGmTWfWC9bSo6VdtuhKzXZX2dRrp WOMdbQlpuSPYkqvz/4l5x5Sytc6cKgnR9cQJy4fvTHU9WpV56Vp1K3PvSWJW0+G4ff+M tZtto5BXuUwibsWlNdVYtja8dST4SQRTS/f4jRs4pgnQyw/eE4I585tfPw2+j+ZPV1oZ 4bsQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=YmuEMIvY; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id p11-v6si487228qtj.126.2018.10.05.11.06.18 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 05 Oct 2018 11:06:19 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=YmuEMIvY; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:36401 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UUU-00041g-Ck for patch@linaro.org; Fri, 05 Oct 2018 14:06:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38661) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1g8UQi-0000X5-EQ for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1g8UQf-0005CO-IV for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:23 -0400 Received: from mail-oi1-x242.google.com ([2607:f8b0:4864:20::242]:42235) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1g8UQf-00056l-A8 for qemu-devel@nongnu.org; Fri, 05 Oct 2018 14:02:21 -0400 Received: by mail-oi1-x242.google.com with SMTP id w81-v6so11083772oiw.9 for ; Fri, 05 Oct 2018 11:02:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=X5a/KvnsV8gRrymCZvMRPaAHMUoAfW8yBsI+pfK7k9k=; b=YmuEMIvYTvMvnWt9Ua7aDBJFkf98tZ1NzUCx8Lu9n3JMWF/W1SklrcfS+LDdV3WfHN PgUI+pV4HFwspIFmvnBsd2YZxoF5yzLUjZYAZdHHeOP3QA3aZrbopFD0uBPeHFITZH+G VIWOnTACVxjtAcbc1PpTTmDt4ByW0I33Bmphw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=X5a/KvnsV8gRrymCZvMRPaAHMUoAfW8yBsI+pfK7k9k=; b=r5YuunqKoN52bnF9RttAel5bPQoCGn2DDhVswad6Nb+sU7Wnu7OWqDaPlDAwVCX7pU /VMGEIcM2hAyKjUAX1yDC6ls04ePQxNfP4cJOhekr2zqc4wUb++G0YIVX2ntW4fhudlS n0U3Fv+fjWEK3rNV+motJm4KhpiREja9JKeTlQ60BOkEob2ThAuHV0TSaCUoY8c+qnF6 U4fDH/r9rhJaE74NGua2SZ8yrv/g+UQ3KlIDNl5dsOUmuxsNCgoW+mi4Zt/2N6NJrOlV VcUSGbbqzR9XqRJ0U8BPhmC+lgdqfRsCSAM1QaOyPEqHzWxdPx3g9JK3pvqggImvt3Hr dvMw== X-Gm-Message-State: ABuFfoiMM+k67M0Atzc7/ntmLMrGdCauAajb7Y9rWB6jUVxN7bjYEIre VJb/1PEat/FZf4HTpfuQXjR4FcYM9p2y6ouqBkc= X-Received: by 2002:aca:4c4f:: with SMTP id z76-v6mr39371oia.164.1538762540181; Fri, 05 Oct 2018 11:02:20 -0700 (PDT) Received: from cloudburst.twiddle.net ([187.217.230.84]) by smtp.gmail.com with ESMTPSA id d37-v6sm2601302otb.0.2018.10.05.11.02.18 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 05 Oct 2018 11:02:19 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 5 Oct 2018 13:02:01 -0500 Message-Id: <20181005180201.11387-9-richard.henderson@linaro.org> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181005180201.11387-1-richard.henderson@linaro.org> References: <20181005180201.11387-1-richard.henderson@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4864:20::242 Subject: [Qemu-devel] [PULL 8/8] softfloat: Specialize udiv_qrnnd for ppc64 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The ISA has a 128/64-bit division instruction, though it assumes the low 64-bits of the numerator are 0, and so requires a bit more fixup than a full 128-bit division insn. Reviewed-by: David Gibson Signed-off-by: Richard Henderson --- include/fpu/softfloat-macros.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) -- 2.17.1 diff --git a/include/fpu/softfloat-macros.h b/include/fpu/softfloat-macros.h index eafc68932b..c86687fa5e 100644 --- a/include/fpu/softfloat-macros.h +++ b/include/fpu/softfloat-macros.h @@ -647,6 +647,22 @@ static inline uint64_t udiv_qrnnd(uint64_t *r, uint64_t n1, asm("dlgr %0, %1" : "+r"(n) : "r"(d)); *r = n >> 64; return n; +#elif defined(_ARCH_PPC64) + /* From Power ISA 3.0B, programming note for divdeu. */ + uint64_t q1, q2, Q, r1, r2, R; + asm("divdeu %0,%2,%4; divdu %1,%3,%4" + : "=&r"(q1), "=r"(q2) + : "r"(n1), "r"(n0), "r"(d)); + r1 = -(q1 * d); /* low part of (n1<<64) - (q1 * d) */ + r2 = n0 - (q2 * d); + Q = q1 + q2; + R = r1 + r2; + if (R >= d || R < r2) { /* overflow implies R > d */ + Q += 1; + R -= d; + } + *r = R; + return Q; #else uint64_t d0, d1, q0, q1, r1, r0, m;