safe_conversions_arm_impl.h 1.8 KB

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