From patchwork Sat May 8 01:46:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 432517 Delivered-To: patch@linaro.org Received: by 2002:a02:c901:0:0:0:0:0 with SMTP id t1csp840414jao; Fri, 7 May 2021 18:49:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwOQN8yZ6nHXkqZBsW5iC4Xmj2OkPb34S1oqfSTQLiKRjF03LPvfmgIamAaRT6dTvXf0mA9 X-Received: by 2002:a05:6638:101a:: with SMTP id r26mr11632536jab.15.1620438562878; Fri, 07 May 2021 18:49:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620438562; cv=none; d=google.com; s=arc-20160816; b=HKePjbR2ERBIse57rghvs+gdEONgZuN74K6YyzlF+Ju2VagR+IHBiNO77Hko8D5Ryk x5K9aftrG/gmIAIU8EYOUETZ0++yXIDd/kC7uhpj3Gn/gxUZ3NOMJNtBV4iXA5Qstpks qJH4ZVxUvZexArbIwgdfSMMpn1WF8V0aO/mMHgRCMcK0JDgDdrWdMyTgDCu5otkf8bQs GYada9hC0SLozuGU05ekdnwhUwnvZsYrrMP34CAsO5X1otIITq2zZ1OovuaGSY2sHm2J 6MtQSMEFSwZjdDFuZ08m9t+sCg4MTjUkxNV/tAOdwKDWJ619HMKbm11S4bMuUzw4HmbA h/bw== 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:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dkim-signature; bh=4FUAz053Q8O4lxDctUgjdKConowhJ6wTho8iZJwG5rg=; b=fVvFjWOb+02B5KbhoM3CM+sF2VxOK2vYy06gp9TubosBNb3cTMFCBdsGYJ6meFjqG5 1Q4rkKIUBSz5j2o6irj9bB6xdRgxznnOvnLC0G1H977qhjG0QXyfkNOxfRX1PlPkGzKH hRB0UAavsuIReZ5p2t5Q+AttV5O1jRaXovyLgIUA8fYAS/UHDOQ9fmaoy9ru2eQAI4+W pyOvtqCDMUeIo46/HIkD2jO/Who7BGophhigay741DtwaGwfEdkwEVEeM/fkP2kI/63r 1Cg7iN8YysDBKDOx56fL0hDo1DQ6UrsQuz//Sm5Sgf8zx7DtjcRLo3CsOGhMWwEtbt7Y HQvw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@linaro.org header.s=google header.b=DDoqlPhH; 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=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id d2si7816170ilf.115.2021.05.07.18.49.22 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Fri, 07 May 2021 18:49:22 -0700 (PDT) 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=fail header.i=@linaro.org header.s=google header.b=DDoqlPhH; 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=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:43160 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lfC5q-0003vk-Ao for patch@linaro.org; Fri, 07 May 2021 21:49:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:40436) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lfC4e-0003v6-RF for qemu-devel@nongnu.org; Fri, 07 May 2021 21:48:08 -0400 Received: from mail-pf1-x42e.google.com ([2607:f8b0:4864:20::42e]:38562) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lfC4c-0003VN-Qn for qemu-devel@nongnu.org; Fri, 07 May 2021 21:48:08 -0400 Received: by mail-pf1-x42e.google.com with SMTP id k19so9143710pfu.5 for ; Fri, 07 May 2021 18:48:06 -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=4FUAz053Q8O4lxDctUgjdKConowhJ6wTho8iZJwG5rg=; b=DDoqlPhHgArnH3rPWW4cCfpZrOdA2CiVAMB3GupObKqU1w3vMVy3mbtHuvpDTdEfgQ oWIxgrEpNRC4AJYTNgkAypi6ETHhQgmnPh4bWEKCxISca/iFl0AVKuWhCKSswpESmz5D aQUXK1MGFn6ZUKOO1o5Ks5k8PoLLseYzRVOa3X2SYmtfSyhW6p0455SGBAR30Ux0Oz4Y hhkwDOjgHcLHMJrUr7Ua+nnDUgb/Be8zF7YecHpCAmtF+QVXVG01i41PlfO9acGQimqi xlxp0wAtx+eiZh09XI7yZwpqq6PkgyHgrCDDKbfqILa5jUwejfFUaKXu9/Uv4k1qWwUY gehg== 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=4FUAz053Q8O4lxDctUgjdKConowhJ6wTho8iZJwG5rg=; b=KBs/OfvjzdIs1PoWFF9/pcVPT8ciqfSXoerLHah3MnK3covrvr6qhVL9ubAEI8vb16 4tqvsz/g/wYbc7r1r6rybX0ZFaXD/SLTFlSZ3F0q91Q+WemTmZ1bQSHuqiFpRLUaEx2q kpCaHkjYqAb8i1h2RwnXZgjAAywrhM9vCncqaLMgtFy02dXpC9Nz2YFUBp3n5jNKzSv+ GU2XywRVbJEUabyTNhYL1UUrLuYhuqDW7lE/NN1s30NVOf8WBv0gowHKR7ioRRqrrSCa x84JQ7aW3QS6Jx5zEaPMZRuyUlXJO9TOUVhILHjqCY+opn4HBk9AOUEkIhxG+wI3wcpL 0UKA== X-Gm-Message-State: AOAM531rVQYKR7mIm7b/nwP7oiNCAgwd/40zEHAtJUOhvgDuu9gXOBqS +34kJMNBccQHTQN9NC1kEVMmsx6+AdEA+Q== X-Received: by 2002:aa7:848f:0:b029:28f:916b:a220 with SMTP id u15-20020aa7848f0000b029028f916ba220mr13722173pfn.10.1620438485411; Fri, 07 May 2021 18:48:05 -0700 (PDT) Received: from localhost.localdomain ([71.212.144.24]) by smtp.gmail.com with ESMTPSA id t4sm5819681pfq.165.2021.05.07.18.48.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 07 May 2021 18:48:05 -0700 (PDT) From: Richard Henderson To: qemu-devel@nongnu.org Subject: [PATCH 02/72] qemu/host-utils: Add wrappers for overflow builtins Date: Fri, 7 May 2021 18:46:52 -0700 Message-Id: <20210508014802.892561-3-richard.henderson@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210508014802.892561-1-richard.henderson@linaro.org> References: <20210508014802.892561-1-richard.henderson@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::42e; envelope-from=richard.henderson@linaro.org; helo=mail-pf1-x42e.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=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alex.bennee@linaro.org, david@redhat.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" These builtins came in with gcc 5 and clang 3.8, which are slightly newer than our supported minimum compiler versions. Signed-off-by: Richard Henderson --- include/qemu/host-utils.h | 225 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) -- 2.25.1 Reviewed-by: Alex Bennée diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h index f1e52851e0..fd76f0cbd3 100644 --- a/include/qemu/host-utils.h +++ b/include/qemu/host-utils.h @@ -356,6 +356,231 @@ static inline uint64_t revbit64(uint64_t x) #endif } +/** + * sadd32_overflow - addition with overflow indication + * @x, @y: addends + * @ret: Output for sum + * + * Computes *@ret = @x + @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool sadd32_overflow(int32_t x, int32_t y, int32_t *ret) +{ +#if __has_builtin(__builtin_add_overflow) || __GNUC__ >= 5 + return __builtin_add_overflow(x, y, ret); +#else + *ret = x + y; + return ((*ret ^ x) & ~(x ^ y)) < 0; +#endif +} + +/** + * sadd64_overflow - addition with overflow indication + * @x, @y: addends + * @ret: Output for sum + * + * Computes *@ret = @x + @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool sadd64_overflow(int64_t x, int64_t y, int64_t *ret) +{ +#if __has_builtin(__builtin_add_overflow) || __GNUC__ >= 5 + return __builtin_add_overflow(x, y, ret); +#else + *ret = x + y; + return ((*ret ^ x) & ~(x ^ y)) < 0; +#endif +} + +/** + * uadd32_overflow - addition with overflow indication + * @x, @y: addends + * @ret: Output for sum + * + * Computes *@ret = @x + @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool uadd32_overflow(uint32_t x, uint32_t y, uint32_t *ret) +{ +#if __has_builtin(__builtin_add_overflow) || __GNUC__ >= 5 + return __builtin_add_overflow(x, y, ret); +#else + *ret = x + y; + return *ret < x; +#endif +} + +/** + * uadd64_overflow - addition with overflow indication + * @x, @y: addends + * @ret: Output for sum + * + * Computes *@ret = @x + @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool uadd64_overflow(uint64_t x, uint64_t y, uint64_t *ret) +{ +#if __has_builtin(__builtin_add_overflow) || __GNUC__ >= 5 + return __builtin_add_overflow(x, y, ret); +#else + *ret = x + y; + return *ret < x; +#endif +} + +/** + * ssub32_overflow - subtraction with overflow indication + * @x: Minuend + * @y: Subtrahend + * @ret: Output for difference + * + * Computes *@ret = @x - @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool ssub32_overflow(int32_t x, int32_t y, int32_t *ret) +{ +#if __has_builtin(__builtin_sub_overflow) || __GNUC__ >= 5 + return __builtin_sub_overflow(x, y, ret); +#else + *ret = x - y; + return ((*ret ^ x) & (x ^ y)) < 0; +#endif +} + +/** + * ssub64_overflow - subtraction with overflow indication + * @x: Minuend + * @y: Subtrahend + * @ret: Output for sum + * + * Computes *@ret = @x - @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool ssub64_overflow(int64_t x, int64_t y, int64_t *ret) +{ +#if __has_builtin(__builtin_sub_overflow) || __GNUC__ >= 5 + return __builtin_sub_overflow(x, y, ret); +#else + *ret = x - y; + return ((*ret ^ x) & (x ^ y)) < 0; +#endif +} + +/** + * usub32_overflow - subtraction with overflow indication + * @x: Minuend + * @y: Subtrahend + * @ret: Output for sum + * + * Computes *@ret = @x - @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool usub32_overflow(uint32_t x, uint32_t y, uint32_t *ret) +{ +#if __has_builtin(__builtin_sub_overflow) || __GNUC__ >= 5 + return __builtin_sub_overflow(x, y, ret); +#else + *ret = x - y; + return x < y; +#endif +} + +/** + * usub64_overflow - subtraction with overflow indication + * @x: Minuend + * @y: Subtrahend + * @ret: Output for sum + * + * Computes *@ret = @x - @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool usub64_overflow(uint64_t x, uint64_t y, uint64_t *ret) +{ +#if __has_builtin(__builtin_sub_overflow) || __GNUC__ >= 5 + return __builtin_sub_overflow(x, y, ret); +#else + *ret = x - y; + return x < y; +#endif +} + +/** + * smul32_overflow - multiplication with overflow indication + * @x, @y: Input multipliers + * @ret: Output for product + * + * Computes *@ret = @x * @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool smul32_overflow(int32_t x, int32_t y, int32_t *ret) +{ +#if __has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5 + return __builtin_mul_overflow(x, y, ret); +#else + int64_t z = (int64_t)x * y; + *ret = z; + return *ret != z; +#endif +} + +/** + * smul64_overflow - multiplication with overflow indication + * @x, @y: Input multipliers + * @ret: Output for product + * + * Computes *@ret = @x * @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool smul64_overflow(int64_t x, int64_t y, int64_t *ret) +{ +#if __has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5 + return __builtin_mul_overflow(x, y, ret); +#else + uint64_t hi, lo; + muls64(&lo, &hi, x, y); + *ret = lo; + return hi != ((int64_t)lo >> 63); +#endif +} + +/** + * umul32_overflow - multiplication with overflow indication + * @x, @y: Input multipliers + * @ret: Output for product + * + * Computes *@ret = @x * @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool umul32_overflow(uint32_t x, uint32_t y, uint32_t *ret) +{ +#if __has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5 + return __builtin_mul_overflow(x, y, ret); +#else + uint64_t z = (uint64_t)x * y; + *ret = z; + return z > UINT32_MAX; +#endif +} + +/** + * smul64_overflow - multiplication with overflow indication + * @x, @y: Input multipliers + * @ret: Output for product + * + * Computes *@ret = @x * @y, and returns true if and only if that + * value has been truncated. + */ +static inline bool umul64_overflow(uint64_t x, uint64_t y, uint64_t *ret) +{ +#if __has_builtin(__builtin_mul_overflow) || __GNUC__ >= 5 + return __builtin_mul_overflow(x, y, ret); +#else + uint64_t hi; + mulu64(ret, &hi, x, y); + return hi != 0; +#endif +} + /* Host type specific sizes of these routines. */ #if ULONG_MAX == UINT32_MAX