// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_ #define BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_ #include #include #include #include "base/numerics/safe_conversions_impl.h" namespace base { namespace internal { // Fast saturation to a destination type. template struct SaturateFastAsmOp { static const bool is_supported = std::is_signed::value && std::is_integral::value && std::is_integral::value && IntegerBitsPlusSign::value <= IntegerBitsPlusSign::value && IntegerBitsPlusSign::value <= IntegerBitsPlusSign::value && !IsTypeInRangeForNumericType::value; __attribute__((always_inline)) static Dst Do(Src value) { int32_t src = value; typename std::conditional::value, int32_t, uint32_t>::type result; if (std::is_signed::value) { asm("ssat %[dst], %[shift], %[src]" : [dst] "=r"(result) : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign::value <= 32 ? IntegerBitsPlusSign::value : 32)); } else { asm("usat %[dst], %[shift], %[src]" : [dst] "=r"(result) : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign::value < 32 ? IntegerBitsPlusSign::value : 31)); } return static_cast(result); } }; } // namespace internal } // namespace base #endif // BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_