Title: [177729] trunk/Source/WTF
Revision
177729
Author
[email protected]
Date
2014-12-24 18:46:32 -0800 (Wed, 24 Dec 2014)

Log Message

Simplify saturated integer add/sub
https://bugs.webkit.org/show_bug.cgi?id=139854

Reviewed by Darin Adler.

* wtf/Compiler.h:
Make a wrapper for __has_builtin for compilers that do not support it.

* wtf/SaturatedArithmetic.h:
(saturatedAddition):
(saturatedSubtraction):
Use the builtins when possible instead of reinventing the wheel.
On ARMv7, use the saturated math instructions.

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (177728 => 177729)


--- trunk/Source/WTF/ChangeLog	2014-12-25 02:31:36 UTC (rev 177728)
+++ trunk/Source/WTF/ChangeLog	2014-12-25 02:46:32 UTC (rev 177729)
@@ -1,3 +1,19 @@
+2014-12-24  Benjamin Poulain  <[email protected]>
+
+        Simplify saturated integer add/sub
+        https://bugs.webkit.org/show_bug.cgi?id=139854
+
+        Reviewed by Darin Adler.
+
+        * wtf/Compiler.h:
+        Make a wrapper for __has_builtin for compilers that do not support it.
+
+        * wtf/SaturatedArithmetic.h:
+        (saturatedAddition):
+        (saturatedSubtraction):
+        Use the builtins when possible instead of reinventing the wheel.
+        On ARMv7, use the saturated math instructions.
+
 2014-12-23  Anders Carlsson  <[email protected]>
 
         Move dynamic_objc_cast to RetainPtr.h

Modified: trunk/Source/WTF/wtf/Compiler.h (177728 => 177729)


--- trunk/Source/WTF/wtf/Compiler.h	2014-12-25 02:31:36 UTC (rev 177728)
+++ trunk/Source/WTF/wtf/Compiler.h	2014-12-25 02:46:32 UTC (rev 177729)
@@ -35,6 +35,13 @@
 /* COMPILER_QUIRK() - whether the compiler being used to build the project requires a given quirk. */
 #define COMPILER_QUIRK(WTF_COMPILER_QUIRK) (defined WTF_COMPILER_QUIRK_##WTF_COMPILER_QUIRK  && WTF_COMPILER_QUIRK_##WTF_COMPILER_QUIRK)
 
+/* COMPILER_HAS_CLANG_BUILTIN() - wether the compiler supports a particular clang builtin. */
+#ifdef __has_builtin
+#define COMPILER_HAS_CLANG_BUILTIN(x) __has_builtin(x)
+#else
+#define COMPILER_HAS_CLANG_BUILTIN(x) 0
+#endif
+
 /* ==== COMPILER() - primary detection of the compiler being used to build the project, in alphabetical order ==== */
 
 /* COMPILER(CLANG) - Clang  */

Modified: trunk/Source/WTF/wtf/SaturatedArithmetic.h (177728 => 177729)


--- trunk/Source/WTF/wtf/SaturatedArithmetic.h	2014-12-25 02:31:36 UTC (rev 177728)
+++ trunk/Source/WTF/wtf/SaturatedArithmetic.h	2014-12-25 02:46:32 UTC (rev 177729)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2012, Google Inc. All rights reserved.
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -31,35 +32,72 @@
 #ifndef SaturatedArithmetic_h
 #define SaturatedArithmetic_h
 
+#include "Compiler.h"
 #include <limits>
 #include <stdint.h>
 #include <stdlib.h>
 
-inline int32_t saturatedAddition(int32_t a, int32_t b)
+inline bool signedAddOverflows(int32_t a, int32_t b, int32_t& result)
 {
+#if COMPILER_HAS_CLANG_BUILTIN(__builtin_sadd_overflow)
+    return __builtin_sadd_overflow(a, b, &result);
+#else
     uint32_t ua = a;
     uint32_t ub = b;
-    uint32_t result = ua + ub;
+    uint32_t uresult = ua + ub;
+    result = static_cast<int32_t>(uresult);
 
     // Can only overflow if the signed bit of the two values match. If the signed
     // bit of the result and one of the values differ it did overflow.
-    if (!((ua ^ ub) >> 31) & (result ^ ua) >> 31)
-        result = std::numeric_limits<int>::max() + (ua >> 31);
+    return !((ua ^ ub) >> 31) & (uresult ^ ua) >> 31;
+#endif
+}
 
+inline int32_t saturatedAddition(int32_t a, int32_t b)
+{
+    int32_t result;
+#if CPU(ARM_THUMB2)
+    asm("qadd %[sum], %[addend], %[augend]"
+        : [sum]"=r"(result)
+        : [augend]"r"(a), [addend]"r"(b)
+        : /* Nothing is clobbered. */
+        );
+#else
+    if (signedAddOverflows(a, b, result))
+        result = std::numeric_limits<int32_t>::max() + (static_cast<uint32_t>(a) >> 31);
+#endif
     return result;
 }
 
-inline int32_t saturatedSubtraction(int32_t a, int32_t b)
+inline bool signedSubtractOverflows(int32_t a, int32_t b, int32_t& result)
 {
+#if COMPILER_HAS_CLANG_BUILTIN(__builtin_ssub_overflow)
+    return __builtin_ssub_overflow(a, b, &result);
+#else
     uint32_t ua = a;
     uint32_t ub = b;
-    uint32_t result = ua - ub;
+    uint32_t uresult = ua - ub;
+    result = static_cast<int32_t>(uresult);
 
     // Can only overflow if the signed bit of the two values do not match. If the
     // signed bit of the result and the first value differ it did overflow.
-    if ((ua ^ ub) >> 31 & (result ^ ua) >> 31)
-        result = std::numeric_limits<int>::max() + (ua >> 31);
+    return (ua ^ ub) >> 31 & (uresult ^ ua) >> 31;
+#endif
+}
 
+inline int32_t saturatedSubtraction(int32_t a, int32_t b)
+{
+    int32_t result;
+#if CPU(ARM_THUMB2)
+    asm("qsub %[difference], %[minuend], %[subtrahend]"
+        : [difference]"=r"(result)
+        : [minuend]"r"(a), [subtrahend]"r"(b)
+        : /* Nothing is clobbered. */
+        );
+#else
+    if (signedSubtractOverflows(a, b, result))
+        result = std::numeric_limits<uint32_t>::max() + (static_cast<uint32_t>(a) >> 31);
+#endif
     return result;
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to