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 "anglebase/numerics/safe_conversions_impl.h" 13 14 namespace angle 15 { 16 namespace base 17 { 18 namespace internal 19 { 20 21 // Fast saturation to a destination type. 22 template <typename Dst, typename Src> 23 struct SaturateFastAsmOp 24 { 25 static constexpr bool is_supported = 26 std::is_signed<Src>::value && std::is_integral<Dst>::value && 27 std::is_integral<Src>::value && 28 IntegerBitsPlusSign<Src>::value <= IntegerBitsPlusSign<int32_t>::value && 29 IntegerBitsPlusSign<Dst>::value <= IntegerBitsPlusSign<int32_t>::value && 30 !IsTypeInRangeForNumericType<Dst, Src>::value; 31 DoSaturateFastAsmOp32 __attribute__((always_inline)) static Dst Do(Src value) 33 { 34 int32_t src = value; 35 typename std::conditional<std::is_signed<Dst>::value, int32_t, uint32_t>::type result; 36 if (std::is_signed<Dst>::value) 37 { 38 asm("ssat %[dst], %[shift], %[src]" 39 : [dst] "=r"(result) 40 : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign<Dst>::value <= 32 41 ? IntegerBitsPlusSign<Dst>::value 42 : 32)); 43 } 44 else 45 { 46 asm("usat %[dst], %[shift], %[src]" 47 : [dst] "=r"(result) 48 : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign<Dst>::value < 32 49 ? IntegerBitsPlusSign<Dst>::value 50 : 31)); 51 } 52 return static_cast<Dst>(result); 53 } 54 }; 55 56 } // namespace internal 57 } // namespace base 58 } // namespace angle 59 60 #endif // BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_ 61