From patchwork Sat Feb 1 16:39:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 861255 Delivered-To: patch@linaro.org Received: by 2002:adf:fb05:0:b0:385:e875:8a9e with SMTP id c5csp1263855wrr; Sat, 1 Feb 2025 08:46:19 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCWIGpmHwQVW3+XYElJEkAhhy/twhPT6/GyXyrnuBcjIiGc1WLMbspk0g94qbajQjertT69g/Q==@linaro.org X-Google-Smtp-Source: AGHT+IGzi1SWVTmH2/Rwk6JCuBLMewaVXWSp5PFRynqmtfDVag/aT7ZG9iWY1OJVINDIBYpyEIW0 X-Received: by 2002:a05:620a:40c6:b0:7b6:f996:c507 with SMTP id af79cd13be357-7bffcd7366fmr2708531185a.40.1738428379119; Sat, 01 Feb 2025 08:46:19 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1738428379; cv=none; d=google.com; s=arc-20240605; b=d2nNk1tUCfU9KtuAzJM5i09m6WNl02YQtr/3SgDD3alR8pZcNn9wEuLVbiN7muBA+q RJfvzg2K+y7h2ctstYWgHED7rpeTcvMNcn9xUoaZGh5yvjLQ6O8v4koe9lX8cNRtG3Jx p80J1fGZj384Zckq6j2e9YkayDBMROz7RpzJ3lA7Yd8XSJBed479hzdLHIquzdkH6L8O kTA/BdWugvOH0VhZv1WrjR+kID51xp+kSUVZC+VgqOSuJAortH5VUSyOxawCvmTyu7Ha Qt/R0ryZ7YF7I9EI/n1vxDQfZN8EPGTriDlq49+TT66pKFNOREOjl6zYNWU8IIO20oMj INeg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20240605; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=oHCiuj4JVKpkS58JWQkdgF532nZyU3vTNz6sMG44ioQ=; fh=4NednJ7pYi0/QxdKs8p71bSXlAxQrHNdRtk2JRcz9Kk=; b=icIv/DMHfsMukiG/z5G/E+zIZdjqGQWnO+pxaaAR9QNyGqIdyU1GxqDXapUnOLa5cl b79An0MTY5CTQ6YJBMSyNfrWf0Mr2x7ifizUejTGdKOrUKdWqbhMcRGY+zCpgr/aI97/ oF6j6ZBxzcjxqlcvb7UQEGVRE6ZcBlyNOuOycTohwnumoZpWxdikEiEj/9x35sOsviKR 022cS9XEp1T78YQmQgP36Wz6Gd50yH7bu6WIQBbYrFGJmj9SCqwG215e6rvwxvozjjrD 5C8h7Y/iu8GXpoHm94wicc+OaR/e5D/nLXQsbmcGUJ59Cx5x0amaKuibmbhZ3o15GZyJ owdQ==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jC1uLzTi; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id af79cd13be357-7c00a924efesi605287185a.545.2025.02.01.08.46.18 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Sat, 01 Feb 2025 08:46:19 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=jC1uLzTi; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org; dara=neutral header.i=@linaro.org Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1teGXt-00063r-RO; Sat, 01 Feb 2025 11:40:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1teGXk-00060d-Lx for qemu-devel@nongnu.org; Sat, 01 Feb 2025 11:40:28 -0500 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1teGXi-00013y-VL for qemu-devel@nongnu.org; Sat, 01 Feb 2025 11:40:28 -0500 Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-438a3216fc2so30059885e9.1 for ; Sat, 01 Feb 2025 08:40:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1738428025; x=1739032825; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=oHCiuj4JVKpkS58JWQkdgF532nZyU3vTNz6sMG44ioQ=; b=jC1uLzTi5nY8CQ9aAYShjn+1855uTel7O/C5avNtckpwu2X49UGAKcCxuZgUpUyhEs SszdxF8M7BSaJnIk31JOBnzaHh5KW0NhGrl6fT/hb4uw+Opep5jlw0QH528D/4vu7Yp1 iWxluC1sAh1gVVAa23ZWklJePpaG68NJFF9A6wgr9GH+sE3Nd5IrYoZdckTlMeZcDV6t f44m0hIEZE4v1YshXedVzSoxszLVPD5hhJz57XUAseSUG4TA9t8HM9Vvly/g/2RUsAo0 j08x4iTHm9JoKwn7auLHvBCtVss7vfLt33EpSyN3KBbjyW4b8AUXHKvwCwX59z9AtvJA rsXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1738428025; x=1739032825; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oHCiuj4JVKpkS58JWQkdgF532nZyU3vTNz6sMG44ioQ=; b=q1Ywz+SihAYcVUtgKDlcTExgEJgKpWWJnG8/9SPPtkeE4mAw6VnKh38okMLwcL5QbP AM+KN6BMix0k61EoFW0h2GAgWF8e8Keg5Z+l1dbw7N1mzC5EKUlXZCVTMX4nXpFVekf8 x69WoZvFNXm9h4XQDOBRCaZCE87REaPWT4raNmxxX1lb3du74lMymdkotr/QhzBXAkNG TDHd8fIuTzZQHejUSpikICWfdtw8o9AZQqE3IonlxlywQ6dnnfHg3FZ7wuj+KjBUc0UT jJNxaiaBYXCseU8C44NoUx1vSehjp97d5zOQ2NzZmzjuocAw/B7W4QAudl7X/6hHpx0H ILmw== X-Forwarded-Encrypted: i=1; AJvYcCUrPfsmZsMv1B/EbXcZRDtlGC8dKagn/nhxiHUJRG3W++ssC4a1ZFalklRHFu4Si+d8CgJHP+2PbiZe@nongnu.org X-Gm-Message-State: AOJu0YxX7V2BgBlKulNioDXPelvsXnuRWIce2cls40vdO9tPm6iNdtwi DPg9+eNSglYIMOR4q8eCX+mfj9OW+uWI6plNYk/tVf51QkRp2Ix2tmtOyNjti+Y= X-Gm-Gg: ASbGncvzqb21gUTJyxesCfvwMhpnWdRZ/fxDBSEV7QzA3e7UwqzbHXA0MQAx5JYsuwk mu7Qs7F0X/pV4T9VL6bhpgDGeC7eZwclfiopQzsg5bL8MKsaeAUAWrVsD7Gnl2rN7YmyQPo3eEB VSUwAQXS23Ds5iw1DwBttL1EoXzC59j2P5vsIGrUCmvsg+G7qaYbCiFQiDkkvJ884SCtMtBmJhw 4NzxQ6ohSH0o4SLcvVfRDQG7tUnz+wfks/LfHuwUZT6CvMyL5q7GrD6WfYyYxNjU+rbe0aiBnjJ kYTfXM7uoT8Gay5wmB5b X-Received: by 2002:a05:600c:501e:b0:434:f297:8e78 with SMTP id 5b1f17b1804b1-438dc3be859mr141987755e9.7.1738428025400; Sat, 01 Feb 2025 08:40:25 -0800 (PST) Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-438dcc81d74sm127401525e9.37.2025.02.01.08.40.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 01 Feb 2025 08:40:24 -0800 (PST) From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v2 07/69] target/arm: Implement FPCR.FIZ handling Date: Sat, 1 Feb 2025 16:39:10 +0000 Message-Id: <20250201164012.1660228-8-peter.maydell@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20250201164012.1660228-1-peter.maydell@linaro.org> References: <20250201164012.1660228-1-peter.maydell@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::332; envelope-from=peter.maydell@linaro.org; helo=mail-wm1-x332.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org Part of FEAT_AFP is the new control bit FPCR.FIZ. This bit affects flushing of single and double precision denormal inputs to zero for AArch64 floating point instructions. (For half-precision, the existing FPCR.FZ16 control remains the only one.) FPCR.FIZ differs from FPCR.FZ in that if we flush an input denormal only because of FPCR.FIZ then we should *not* set the cumulative exception bit FPSR.IDC. FEAT_AFP also defines that in AArch64 the existing FPCR.FZ only applies when FPCR.AH is 0. We can implement this by setting the "flush inputs to zero" state appropriately when FPCR is written, and by not reflecting the float_flag_input_denormal status flag into FPSR reads when it is the result only of FPSR.FIZ. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- target/arm/vfp_helper.c | 60 ++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c index 8c79ab4fc8a..30c170ecee5 100644 --- a/target/arm/vfp_helper.c +++ b/target/arm/vfp_helper.c @@ -61,19 +61,31 @@ static inline uint32_t vfp_exceptbits_from_host(int host_bits) static uint32_t vfp_get_fpsr_from_host(CPUARMState *env) { - uint32_t i = 0; + uint32_t a32_flags = 0, a64_flags = 0; - i |= get_float_exception_flags(&env->vfp.fp_status_a32); - i |= get_float_exception_flags(&env->vfp.fp_status_a64); - i |= get_float_exception_flags(&env->vfp.standard_fp_status); + a32_flags |= get_float_exception_flags(&env->vfp.fp_status_a32); + a32_flags |= get_float_exception_flags(&env->vfp.standard_fp_status); /* FZ16 does not generate an input denormal exception. */ - i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a32) + a32_flags |= (get_float_exception_flags(&env->vfp.fp_status_f16_a32) & ~float_flag_input_denormal_flushed); - i |= (get_float_exception_flags(&env->vfp.fp_status_f16_a64) + a32_flags |= (get_float_exception_flags(&env->vfp.standard_fp_status_f16) & ~float_flag_input_denormal_flushed); - i |= (get_float_exception_flags(&env->vfp.standard_fp_status_f16) + + a64_flags |= get_float_exception_flags(&env->vfp.fp_status_a64); + a64_flags |= (get_float_exception_flags(&env->vfp.fp_status_f16_a64) & ~float_flag_input_denormal_flushed); - return vfp_exceptbits_from_host(i); + /* + * Flushing an input denormal *only* because FPCR.FIZ == 1 does + * not set FPSR.IDC; if FPCR.FZ is also set then this takes + * precedence and IDC is set (see the FPUnpackBase pseudocode). + * So squash it unless (FPCR.AH == 0 && FPCR.FZ == 1). + * We only do this for the a64 flags because FIZ has no effect + * on AArch32 even if it is set. + */ + if ((env->vfp.fpcr & (FPCR_FZ | FPCR_AH)) != FPCR_FZ) { + a64_flags &= ~float_flag_input_denormal_flushed; + } + return vfp_exceptbits_from_host(a32_flags | a64_flags); } static void vfp_clear_float_status_exc_flags(CPUARMState *env) @@ -91,6 +103,17 @@ static void vfp_clear_float_status_exc_flags(CPUARMState *env) set_float_exception_flags(0, &env->vfp.standard_fp_status_f16); } +static void vfp_sync_and_clear_float_status_exc_flags(CPUARMState *env) +{ + /* + * Synchronize any pending exception-flag information in the + * float_status values into env->vfp.fpsr, and then clear out + * the float_status data. + */ + env->vfp.fpsr |= vfp_get_fpsr_from_host(env); + vfp_clear_float_status_exc_flags(env); +} + static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) { uint64_t changed = env->vfp.fpcr; @@ -130,9 +153,18 @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) if (changed & FPCR_FZ) { bool ftz_enabled = val & FPCR_FZ; set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_a32); - set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_a32); set_flush_to_zero(ftz_enabled, &env->vfp.fp_status_a64); - set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_a64); + /* FIZ is A64 only so FZ always makes A32 code flush inputs to zero */ + set_flush_inputs_to_zero(ftz_enabled, &env->vfp.fp_status_a32); + } + if (changed & (FPCR_FZ | FPCR_AH | FPCR_FIZ)) { + /* + * A64: Flush denormalized inputs to zero if FPCR.FIZ = 1, or + * both FPCR.AH = 0 and FPCR.FZ = 1. + */ + bool fitz_enabled = (val & FPCR_FIZ) || + (val & (FPCR_FZ | FPCR_AH)) == FPCR_FZ; + set_flush_inputs_to_zero(fitz_enabled, &env->vfp.fp_status_a64); } if (changed & FPCR_DN) { bool dnan_enabled = val & FPCR_DN; @@ -141,6 +173,14 @@ static void vfp_set_fpcr_to_host(CPUARMState *env, uint32_t val, uint32_t mask) set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a32); set_default_nan_mode(dnan_enabled, &env->vfp.fp_status_f16_a64); } + /* + * If any bits changed that we look at in vfp_get_fpsr_from_host(), + * we must sync the float_status flags into vfp.fpsr now (under the + * old regime) before we update vfp.fpcr. + */ + if (changed & (FPCR_FZ | FPCR_AH | FPCR_FIZ)) { + vfp_sync_and_clear_float_status_exc_flags(env); + } } #else