*
* Atomic_ReadSub64 --
*
- * Atomically subtracts a 64-bit integer to another
+ * Atomically subtracts a 64-bit integer from another.
+ *
+ * Note: It is expected that val <= var. If untrue, the result
+ * cannot be represented in an unsigned type.
*
* Results:
* Returns the old value just prior to the subtraction
#if defined VM_ARM_64
return _VMATOM_X(ROP, 64, TRUE, &var->value, sub, val);
#else
- return Atomic_ReadAdd64(var, -(int64)val);
+ return Atomic_ReadAdd64(var, (uint64)-(int64)val);
#endif
}
static INLINE uint16
Atomic_ReadDec16(Atomic_uint16 *var) // IN/OUT
{
- return Atomic_ReadAdd16(var, -1);
+ return Atomic_ReadAdd16(var, (uint16)-1);
}
#endif
#endif
static INLINE int
-lssb32_0(uint32 value)
+lssb32_0(uint32 v)
{
+ int value = (int)v;
#ifdef USE_ARCH_X86_CUSTOM
if (!__builtin_constant_p(value)) {
if (UNLIKELY(value == 0)) {
}
static INLINE int
-lssb64_0(const uint64 value)
+lssb64_0(const uint64 v)
{
+ int64 value = (int64)v;
+
#ifdef USE_ARCH_X86_CUSTOM
if (!__builtin_constant_p(value)) {
if (UNLIKELY(value == 0)) {
if (value <= 1 || value > (1U << 31)) {
return 1; // Match the assembly's undefined value for large inputs.
} else {
- return (2 << mssb32_0(value - 1));
+ int mssb32 = mssb32_0(value - 1);
+ /* invariant: mssb32 >= 0 */
+ return (2U << (uint32)mssb32);
}
}