1 // Copyright 2017 The Chromium Authors. All rights reserved. 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 #include <cassert> 9 #include <limits> 10 #include <type_traits> 11 12 #include "base/numerics/safe_conversions_impl.h" 13 14 namespace base { 15 namespace internal { 16 17 // Fast saturation to a destination type. 18 template <typename Dst, typename Src> 19 struct SaturateFastAsmOp { 20 static const bool is_supported = 21 std::is_signed<Src>::value && std::is_integral<Dst>::value && 22 std::is_integral<Src>::value && 23 IntegerBitsPlusSign<Src>::value <= IntegerBitsPlusSign<int32_t>::value && 24 IntegerBitsPlusSign<Dst>::value <= IntegerBitsPlusSign<int32_t>::value && 25 !IsTypeInRangeForNumericType<Dst, Src>::value; 26 DoSaturateFastAsmOp27 __attribute__((always_inline)) static Dst Do(Src value) { 28 int32_t src = value; 29 typename std::conditional<std::is_signed<Dst>::value, int32_t, 30 uint32_t>::type result; 31 if (std::is_signed<Dst>::value) { 32 asm("ssat %[dst], %[shift], %[src]" 33 : [dst] "=r"(result) 34 : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign<Dst>::value <= 32 35 ? IntegerBitsPlusSign<Dst>::value 36 : 32)); 37 } else { 38 asm("usat %[dst], %[shift], %[src]" 39 : [dst] "=r"(result) 40 : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign<Dst>::value < 32 41 ? IntegerBitsPlusSign<Dst>::value 42 : 31)); 43 } 44 return static_cast<Dst>(result); 45 } 46 }; 47 48 } // namespace internal 49 } // namespace base 50 51 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_ 52