// 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. // Slightly adapted for inclusion in V8. // Copyright 2014 the V8 project authors. All rights reserved. // List of adaptations: // - include guard names // - wrap in v8 namespace // - include paths #ifndef V8_BASE_SAFE_CONVERSIONS_ARM_IMPL_H_ #define V8_BASE_SAFE_CONVERSIONS_ARM_IMPL_H_ #include <cassert> #include <limits> #include <type_traits> #include "src/base/safe_conversions_impl.h" namespace v8 { 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 } // namespace v8 #endif // V8_BASE_SAFE_CONVERSIONS_ARM_IMPL_H_