1 // Copyright 2017 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_ 6 #define BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_ 7 8 // IWYU pragma: private, include "base/numerics/safe_conversions.h" 9 10 #include <stdint.h> 11 12 #include <algorithm> 13 #include <concepts> 14 #include <type_traits> 15 16 #include "base/numerics/safe_conversions_impl.h" 17 18 namespace base { 19 namespace internal { 20 21 // Fast saturation to a destination type. 22 template <typename Dst, typename Src> 23 struct SaturateFastAsmOp { 24 static constexpr bool is_supported = 25 kEnableAsmCode && std::signed_integral<Src> && std::integral<Dst> && 26 kIntegerBitsPlusSign<Src> <= kIntegerBitsPlusSign<int32_t> && 27 kIntegerBitsPlusSign<Dst> <= kIntegerBitsPlusSign<int32_t> && 28 !kIsTypeInRangeForNumericType<Dst, Src>; 29 DoSaturateFastAsmOp30 __attribute__((always_inline)) static Dst Do(Src value) { 31 int32_t src = value; 32 if constexpr (std::is_signed_v<Dst>) { 33 int32_t result; 34 asm("ssat %[dst], %[shift], %[src]" 35 : [dst] "=r"(result) 36 : [src] "r"(src), [shift] "n"( 37 std::min(kIntegerBitsPlusSign<Dst>, 32))); 38 return static_cast<Dst>(result); 39 } else { 40 uint32_t result; 41 asm("usat %[dst], %[shift], %[src]" 42 : [dst] "=r"(result) 43 : [src] "r"(src), [shift] "n"( 44 std::min(kIntegerBitsPlusSign<Dst>, 31))); 45 return static_cast<Dst>(result); 46 } 47 } 48 }; 49 50 } // namespace internal 51 } // namespace base 52 53 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_ 54