Skip to content

Commit

Permalink
src: don't use __builtin_bswap16() and friends
Browse files Browse the repository at this point in the history
Said builtins are not supported by older versions of apple-gcc, breaking
the build on OS X 10.8.

Fixes: nodejs#7618
Refs: nodejs#4290
Refs: nodejs#7157
  • Loading branch information
bnoordhuis committed Jul 11, 2016
1 parent fcae5e2 commit cd020e3
Showing 1 changed file with 10 additions and 72 deletions.
82 changes: 10 additions & 72 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,38 +52,6 @@
#define BUFFER_MALLOC(length) \
zero_fill_all_buffers ? calloc(length, 1) : malloc(length)

#if defined(__GNUC__) || defined(__clang__)
#define BSWAP_INTRINSIC_2(x) __builtin_bswap16(x)
#define BSWAP_INTRINSIC_4(x) __builtin_bswap32(x)
#define BSWAP_INTRINSIC_8(x) __builtin_bswap64(x)
#elif defined(__linux__)
#include <byteswap.h>
#define BSWAP_INTRINSIC_2(x) bswap_16(x)
#define BSWAP_INTRINSIC_4(x) bswap_32(x)
#define BSWAP_INTRINSIC_8(x) bswap_64(x)
#elif defined(_MSC_VER)
#include <intrin.h>
#define BSWAP_INTRINSIC_2(x) _byteswap_ushort(x);
#define BSWAP_INTRINSIC_4(x) _byteswap_ulong(x);
#define BSWAP_INTRINSIC_8(x) _byteswap_uint64(x);
#else
#define BSWAP_INTRINSIC_2(x) ((x) << 8) | ((x) >> 8)
#define BSWAP_INTRINSIC_4(x) \
(((x) & 0xFF) << 24) | \
(((x) & 0xFF00) << 8) | \
(((x) >> 8) & 0xFF00) | \
(((x) >> 24) & 0xFF)
#define BSWAP_INTRINSIC_8(x) \
(((x) & 0xFF00000000000000ull) >> 56) | \
(((x) & 0x00FF000000000000ull) >> 40) | \
(((x) & 0x0000FF0000000000ull) >> 24) | \
(((x) & 0x000000FF00000000ull) >> 8) | \
(((x) & 0x00000000FF000000ull) << 8) | \
(((x) & 0x0000000000FF0000ull) << 24) | \
(((x) & 0x000000000000FF00ull) << 40) | \
(((x) & 0x00000000000000FFull) << 56)
#endif

namespace node {

// if true, all Buffer and SlowBuffer instances will automatically zero-fill
Expand Down Expand Up @@ -1209,18 +1177,8 @@ void Swap16(const FunctionCallbackInfo<Value>& args) {

CHECK_EQ(ts_obj_length % 2, 0);

int align = reinterpret_cast<uintptr_t>(ts_obj_data) % sizeof(uint16_t);

if (align == 0) {
uint16_t* data16 = reinterpret_cast<uint16_t*>(ts_obj_data);
size_t len16 = ts_obj_length / 2;
for (size_t i = 0; i < len16; i++) {
data16[i] = BSWAP_INTRINSIC_2(data16[i]);
}
} else {
for (size_t i = 0; i < ts_obj_length; i += 2) {
std::swap(ts_obj_data[i], ts_obj_data[i + 1]);
}
for (size_t i = 0; i < ts_obj_length; i += 2) {
std::swap(ts_obj_data[i], ts_obj_data[i + 1]);
}

args.GetReturnValue().Set(args[0]);
Expand All @@ -1234,19 +1192,9 @@ void Swap32(const FunctionCallbackInfo<Value>& args) {

CHECK_EQ(ts_obj_length % 4, 0);

int align = reinterpret_cast<uintptr_t>(ts_obj_data) % sizeof(uint32_t);

if (align == 0) {
uint32_t* data32 = reinterpret_cast<uint32_t*>(ts_obj_data);
size_t len32 = ts_obj_length / 4;
for (size_t i = 0; i < len32; i++) {
data32[i] = BSWAP_INTRINSIC_4(data32[i]);
}
} else {
for (size_t i = 0; i < ts_obj_length; i += 4) {
std::swap(ts_obj_data[i], ts_obj_data[i + 3]);
std::swap(ts_obj_data[i + 1], ts_obj_data[i + 2]);
}
for (size_t i = 0; i < ts_obj_length; i += 4) {
std::swap(ts_obj_data[i], ts_obj_data[i + 3]);
std::swap(ts_obj_data[i + 1], ts_obj_data[i + 2]);
}

args.GetReturnValue().Set(args[0]);
Expand All @@ -1260,21 +1208,11 @@ void Swap64(const FunctionCallbackInfo<Value>& args) {

CHECK_EQ(ts_obj_length % 8, 0);

int align = reinterpret_cast<uintptr_t>(ts_obj_data) % sizeof(uint64_t);

if (align == 0) {
uint64_t* data64 = reinterpret_cast<uint64_t*>(ts_obj_data);
size_t len32 = ts_obj_length / 8;
for (size_t i = 0; i < len32; i++) {
data64[i] = BSWAP_INTRINSIC_8(data64[i]);
}
} else {
for (size_t i = 0; i < ts_obj_length; i += 8) {
std::swap(ts_obj_data[i], ts_obj_data[i + 7]);
std::swap(ts_obj_data[i + 1], ts_obj_data[i + 6]);
std::swap(ts_obj_data[i + 2], ts_obj_data[i + 5]);
std::swap(ts_obj_data[i + 3], ts_obj_data[i + 4]);
}
for (size_t i = 0; i < ts_obj_length; i += 8) {
std::swap(ts_obj_data[i], ts_obj_data[i + 7]);
std::swap(ts_obj_data[i + 1], ts_obj_data[i + 6]);
std::swap(ts_obj_data[i + 2], ts_obj_data[i + 5]);
std::swap(ts_obj_data[i + 3], ts_obj_data[i + 4]);
}

args.GetReturnValue().Set(args[0]);
Expand Down

0 comments on commit cd020e3

Please sign in to comment.