1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 07:27:45 +00:00

AK+Everywhere: Replace __builtin bit functions

In order to reduce our reliance on __builtin_{ffs, clz, ctz, popcount},
this commit removes all calls to these functions and replaces them with
the equivalent functions in AK/BuiltinWrappers.h.
This commit is contained in:
Nick Johnson 2021-12-19 15:46:55 -06:00 committed by Andreas Kling
parent 26bb3e1acf
commit 08e4a1a4dc
20 changed files with 108 additions and 115 deletions

View file

@ -8,6 +8,7 @@
#include "SoftCPU.h"
#include "Emulator.h"
#include <AK/Assertions.h>
#include <AK/BuiltinWrappers.h>
#include <AK/Debug.h>
#include <stdio.h>
#include <string.h>
@ -978,7 +979,7 @@ void SoftCPU::BOUND(const X86::Instruction&) { TODO_INSN(); }
template<typename T>
ALWAYS_INLINE static T op_bsf(SoftCPU&, T value)
{
return { (typename T::ValueType)__builtin_ctz(value.value()), value.shadow() };
return { (typename T::ValueType)bit_scan_forward(value.value()), value.shadow() };
}
template<typename T>

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/BuiltinWrappers.h>
#include <AK/Debug.h>
#include <AK/ScopedValueRollback.h>
#include <AK/Vector.h>
@ -437,7 +438,7 @@ void* malloc(size_t size)
// _aligned_free(), so it can be easily implemented on top of malloc().
void* _aligned_malloc(size_t size, size_t alignment)
{
if (__builtin_popcount(alignment) != 1) {
if (popcount(alignment) != 1) {
errno = EINVAL;
return nullptr;
}

View file

@ -6,6 +6,7 @@
*/
#include "UnsignedBigIntegerAlgorithms.h"
#include <AK/BuiltinWrappers.h>
namespace Crypto {
@ -153,7 +154,7 @@ FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_not_without_allocation(
auto last_word_index = right.length() - 1;
auto last_word = right.words()[last_word_index];
output.m_words[last_word_index] = ((u32)0xffffffffffffffff >> __builtin_clz(last_word)) & ~last_word;
output.m_words[last_word_index] = ((u32)0xffffffffffffffff >> count_leading_zeroes(last_word)) & ~last_word;
}
/**

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/BuiltinWrappers.h>
#include <AK/Debug.h>
#include <AK/Function.h>
#include <AK/String.h>
@ -326,9 +327,9 @@ static void populate_dib_mask_info_if_needed(BMPLoadingContext& context)
mask_sizes.append(0);
continue;
}
int trailing_zeros = count_trailing_zeroes_32(mask);
int trailing_zeros = count_trailing_zeroes(mask);
// If mask is exactly `0xFFFFFFFF`, then we might try to count the trailing zeros of 0x00000000 here, so we need the safe version:
int size = count_trailing_zeroes_32_safe(~(mask >> trailing_zeros));
int size = count_trailing_zeroes_safe(~(mask >> trailing_zeros));
if (size > 8) {
// Drop lowest bits if mask is longer than 8 bits.
trailing_zeros += size - 8;

View file

@ -6,6 +6,7 @@
#include "BitmapFont.h"
#include "Emoji.h"
#include <AK/BuiltinWrappers.h>
#include <AK/Utf32View.h>
#include <AK/Utf8View.h>
#include <LibCore/FileStream.h>
@ -95,7 +96,7 @@ NonnullRefPtr<BitmapFont> BitmapFont::masked_character_set() const
}
size_t new_glyph_count { 0 };
for (size_t i = 0; i < new_range_mask_size; ++i) {
new_glyph_count += 256 * __builtin_popcount(new_range_mask[i]);
new_glyph_count += 256 * popcount(new_range_mask[i]);
}
size_t bytes_per_glyph = sizeof(u32) * m_glyph_height;
auto* new_rows = static_cast<u8*>(calloc(new_glyph_count, bytes_per_glyph));
@ -191,7 +192,7 @@ RefPtr<BitmapFont> BitmapFont::load_from_memory(const u8* data)
size_t glyph_count { 0 };
u8* range_mask = const_cast<u8*>(data + sizeof(FontFileHeader));
for (size_t i = 0; i < header.range_mask_size; ++i)
glyph_count += 256 * __builtin_popcount(range_mask[i]);
glyph_count += 256 * popcount(range_mask[i]);
u8* rows = range_mask + header.range_mask_size;
u8* widths = (u8*)(rows) + glyph_count * bytes_per_glyph;
return adopt_ref(*new BitmapFont(String(header.name), String(header.family), rows, widths, !header.is_variable_width, header.glyph_width, header.glyph_height, header.glyph_spacing, header.range_mask_size, range_mask, header.baseline, header.mean_line, header.presentation_size, header.weight, header.slope));

View file

@ -5,6 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/BuiltinWrappers.h>
#include <AK/CharacterTypes.h>
#include <AK/Hex.h>
#include <AK/Platform.h>
@ -500,7 +501,7 @@ static ThrowCompletionOr<String> decode(JS::GlobalObject& global_object, const S
continue;
}
auto leading_ones = count_trailing_zeroes_32_safe(~decoded_code_unit) - 24;
auto leading_ones = count_trailing_zeroes_safe(static_cast<u32>(~decoded_code_unit)) - 24;
if (leading_ones == 1 || leading_ones > 4)
return global_object.vm().throw_completion<URIError>(global_object, ErrorType::URIMalformed);

View file

@ -6,6 +6,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/BuiltinWrappers.h>
#include <AK/Function.h>
#include <AK/Random.h>
#include <LibJS/Runtime/GlobalObject.h>
@ -303,7 +304,7 @@ JS_DEFINE_NATIVE_FUNCTION(MathObject::clz32)
auto number = TRY(vm.argument(0).to_u32(global_object));
if (number == 0)
return Value(32);
return Value(__builtin_clz(number));
return Value(count_leading_zeroes(number));
}
// 21.3.2.2 Math.acos ( x ), https://tc39.es/ecma262/#sec-math.acos

View file

@ -5,6 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/BuiltinWrappers.h>
#include <AK/ExtraMathConstants.h>
#include <AK/Math.h>
#include <AK/Platform.h>
@ -278,7 +279,7 @@ static FloatT internal_scalbn(FloatT x, int exponent) NOEXCEPT
return extractor.d;
}
unsigned leading_mantissa_zeroes = extractor.mantissa == 0 ? 32 : __builtin_clz(extractor.mantissa);
unsigned leading_mantissa_zeroes = extractor.mantissa == 0 ? 32 : count_leading_zeroes(extractor.mantissa);
int shift = min((int)leading_mantissa_zeroes, exponent);
exponent = max(exponent - shift, 0);

View file

@ -7,6 +7,7 @@
#pragma once
#include <AK/BitCast.h>
#include <AK/BuiltinWrappers.h>
#include <AK/Result.h>
#include <AK/StringView.h>
#include <AK/Types.h>
@ -176,10 +177,8 @@ struct CountLeadingZeros {
if (lhs == 0)
return sizeof(Lhs) * CHAR_BIT;
if constexpr (sizeof(Lhs) == 4)
return __builtin_clz(lhs);
else if constexpr (sizeof(Lhs) == 8)
return __builtin_clzll(lhs);
if constexpr (sizeof(Lhs) == 4 || sizeof(Lhs) == 8)
return count_leading_zeroes(MakeUnsigned<Lhs>(lhs));
else
VERIFY_NOT_REACHED();
}
@ -193,10 +192,8 @@ struct CountTrailingZeros {
if (lhs == 0)
return sizeof(Lhs) * CHAR_BIT;
if constexpr (sizeof(Lhs) == 4)
return __builtin_ctz(lhs);
else if constexpr (sizeof(Lhs) == 8)
return __builtin_ctzll(lhs);
if constexpr (sizeof(Lhs) == 4 || sizeof(Lhs) == 8)
return count_trailing_zeroes(MakeUnsigned<Lhs>(lhs));
else
VERIFY_NOT_REACHED();
}
@ -207,10 +204,8 @@ struct PopCount {
template<typename Lhs>
auto operator()(Lhs lhs) const
{
if constexpr (sizeof(Lhs) == 4)
return __builtin_popcount(lhs);
else if constexpr (sizeof(Lhs) == 8)
return __builtin_popcountll(lhs);
if constexpr (sizeof(Lhs) == 4 || sizeof(Lhs) == 8)
return popcount(MakeUnsigned<Lhs>(lhs));
else
VERIFY_NOT_REACHED();
}