123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 |
- // 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 <cassert>
- #include <limits>
- #include <type_traits>
- #include "base/numerics/safe_conversions_impl.h"
- namespace base {
- namespace internal {
- // Fast saturation to a destination type.
- template <typename Dst, typename Src>
- struct SaturateFastAsmOp {
- static constexpr bool is_supported =
- std::is_signed<Src>::value && std::is_integral<Dst>::value &&
- std::is_integral<Src>::value &&
- IntegerBitsPlusSign<Src>::value <= IntegerBitsPlusSign<int32_t>::value &&
- IntegerBitsPlusSign<Dst>::value <= IntegerBitsPlusSign<int32_t>::value &&
- !IsTypeInRangeForNumericType<Dst, Src>::value;
- __attribute__((always_inline)) static Dst Do(Src value) {
- int32_t src = value;
- typename std::conditional<std::is_signed<Dst>::value, int32_t,
- uint32_t>::type result;
- if (std::is_signed<Dst>::value) {
- asm("ssat %[dst], %[shift], %[src]"
- : [dst] "=r"(result)
- : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign<Dst>::value <= 32
- ? IntegerBitsPlusSign<Dst>::value
- : 32));
- } else {
- asm("usat %[dst], %[shift], %[src]"
- : [dst] "=r"(result)
- : [src] "r"(src), [shift] "n"(IntegerBitsPlusSign<Dst>::value < 32
- ? IntegerBitsPlusSign<Dst>::value
- : 31));
- }
- return static_cast<Dst>(result);
- }
- };
- } // namespace internal
- } // namespace base
- #endif // BASE_NUMERICS_SAFE_CONVERSIONS_ARM_IMPL_H_
|