Bump to WebRTC M120 release
Some API deprecation -- ExperimentalAgc and ExperimentalNs are gone. We're continuing to carry iSAC even though it's gone upstream, but maybe we'll want to drop that soon.
This commit is contained in:
111
webrtc/system_wrappers/source/denormal_disabler.cc
Normal file
111
webrtc/system_wrappers/source/denormal_disabler.cc
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "system_wrappers/include/denormal_disabler.h"
|
||||
|
||||
#include "rtc_base/checks.h"
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
|
||||
#if defined(WEBRTC_ARCH_X86_FAMILY) && defined(__clang__)
|
||||
#define WEBRTC_DENORMAL_DISABLER_X86_SUPPORTED
|
||||
#endif
|
||||
|
||||
#if defined(WEBRTC_DENORMAL_DISABLER_X86_SUPPORTED) || \
|
||||
defined(WEBRTC_ARCH_ARM_FAMILY)
|
||||
#define WEBRTC_DENORMAL_DISABLER_SUPPORTED
|
||||
#endif
|
||||
|
||||
constexpr int kUnspecifiedStatusWord = -1;
|
||||
|
||||
#if defined(WEBRTC_DENORMAL_DISABLER_SUPPORTED)
|
||||
|
||||
// Control register bit mask to disable denormals on the hardware.
|
||||
#if defined(WEBRTC_DENORMAL_DISABLER_X86_SUPPORTED)
|
||||
// On x86 two bits are used: flush-to-zero (FTZ) and denormals-are-zero (DAZ).
|
||||
constexpr int kDenormalBitMask = 0x8040;
|
||||
#elif defined(WEBRTC_ARCH_ARM_FAMILY)
|
||||
// On ARM one bit is used: flush-to-zero (FTZ).
|
||||
constexpr int kDenormalBitMask = 1 << 24;
|
||||
#endif
|
||||
|
||||
// Reads the relevant CPU control register and returns its value for supported
|
||||
// architectures and compilers. Otherwise returns `kUnspecifiedStatusWord`.
|
||||
int ReadStatusWord() {
|
||||
int result = kUnspecifiedStatusWord;
|
||||
#if defined(WEBRTC_DENORMAL_DISABLER_X86_SUPPORTED)
|
||||
asm volatile("stmxcsr %0" : "=m"(result));
|
||||
#elif defined(WEBRTC_ARCH_ARM_FAMILY) && defined(WEBRTC_ARCH_32_BITS)
|
||||
asm volatile("vmrs %[result], FPSCR" : [result] "=r"(result));
|
||||
#elif defined(WEBRTC_ARCH_ARM_FAMILY) && defined(WEBRTC_ARCH_64_BITS)
|
||||
asm volatile("mrs %x[result], FPCR" : [result] "=r"(result));
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
// Writes `status_word` in the relevant CPU control register if the architecture
|
||||
// and the compiler are supported.
|
||||
void SetStatusWord(int status_word) {
|
||||
#if defined(WEBRTC_DENORMAL_DISABLER_X86_SUPPORTED)
|
||||
asm volatile("ldmxcsr %0" : : "m"(status_word));
|
||||
#elif defined(WEBRTC_ARCH_ARM_FAMILY) && defined(WEBRTC_ARCH_32_BITS)
|
||||
asm volatile("vmsr FPSCR, %[src]" : : [src] "r"(status_word));
|
||||
#elif defined(WEBRTC_ARCH_ARM_FAMILY) && defined(WEBRTC_ARCH_64_BITS)
|
||||
asm volatile("msr FPCR, %x[src]" : : [src] "r"(status_word));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns true if the status word indicates that denormals are enabled.
|
||||
constexpr bool DenormalsEnabled(int status_word) {
|
||||
return (status_word & kDenormalBitMask) != kDenormalBitMask;
|
||||
}
|
||||
|
||||
#endif // defined(WEBRTC_DENORMAL_DISABLER_SUPPORTED)
|
||||
|
||||
} // namespace
|
||||
|
||||
#if defined(WEBRTC_DENORMAL_DISABLER_SUPPORTED)
|
||||
DenormalDisabler::DenormalDisabler() : DenormalDisabler(/*enabled=*/true) {}
|
||||
|
||||
DenormalDisabler::DenormalDisabler(bool enabled)
|
||||
: status_word_(enabled ? ReadStatusWord() : kUnspecifiedStatusWord),
|
||||
disabling_activated_(enabled && DenormalsEnabled(status_word_)) {
|
||||
if (disabling_activated_) {
|
||||
RTC_DCHECK_NE(status_word_, kUnspecifiedStatusWord);
|
||||
SetStatusWord(status_word_ | kDenormalBitMask);
|
||||
RTC_DCHECK(!DenormalsEnabled(ReadStatusWord()));
|
||||
}
|
||||
}
|
||||
|
||||
bool DenormalDisabler::IsSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
DenormalDisabler::~DenormalDisabler() {
|
||||
if (disabling_activated_) {
|
||||
RTC_DCHECK_NE(status_word_, kUnspecifiedStatusWord);
|
||||
SetStatusWord(status_word_);
|
||||
}
|
||||
}
|
||||
#else
|
||||
DenormalDisabler::DenormalDisabler() : DenormalDisabler(/*enabled=*/false) {}
|
||||
|
||||
DenormalDisabler::DenormalDisabler(bool enabled)
|
||||
: status_word_(kUnspecifiedStatusWord), disabling_activated_(false) {}
|
||||
|
||||
bool DenormalDisabler::IsSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
DenormalDisabler::~DenormalDisabler() = default;
|
||||
#endif
|
||||
|
||||
} // namespace webrtc
|
Reference in New Issue
Block a user