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