mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-24 14:26:09 +03:00
52 lines
1.8 KiB
C++
52 lines
1.8 KiB
C++
// 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 const 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_
|