Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make ScLang's integer 64bits #6242

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion QtCollider/primitives/prim_misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ QC_LANG_PRIMITIVE(QView_AddActionToView, 3, PyrSlot* r, PyrSlot* a, VMGlobals* g

if (NotNil(indexArg)) {
if (IsInt(indexArg)) {
int index = std::max(slotRawInt(indexArg), 0);
int index = std::max(slotRawInt(indexArg), int64(0));

auto actions = widget->actions();

Expand Down
2 changes: 1 addition & 1 deletion common/SC_AllocPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ class AllocPool {
return inSize >> 4;
if (inSize >= 262144)
return 127;
int bits = 28 - CLZ(inSize);
int bits = 28 - CLZ(static_cast<int32>(inSize));
return (bits << 3) + (inSize >> bits);
}

Expand Down
4 changes: 2 additions & 2 deletions common/SC_fftlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,8 @@ scfft* scfft_create(size_t fullsize, size_t winsize, SCFFT_WindowFunction wintyp

f->nfull = fullsize;
f->nwin = winsize;
f->log2nfull = LOG2CEIL(fullsize);
f->log2nwin = LOG2CEIL(winsize);
f->log2nfull = LOG2CEIL(static_cast<int32>(fullsize));
f->log2nwin = LOG2CEIL(static_cast<int32>(winsize));
f->wintype = wintype;
f->indata = indata;
f->outdata = outdata;
Expand Down
96 changes: 89 additions & 7 deletions include/common/clz.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ count leading zeroes function and those that can be derived from it

#pragma once

#include <bitset>
#include <bit>
#include <limits>
#include <immintrin.h>
#include "SC_Types.h"

#ifdef __MWERKS__
Expand All @@ -45,11 +49,18 @@ static __inline__ int32 CLZ(int32 arg) {
else
return 32;
}
static __inline__ int64 CLZ(int64 arg) {
if (arg)
return __builtin_clzl(arg);
else
return 64;
}

#elif defined(_MSC_VER)

# include <intrin.h>
# pragma intrinsic(_BitScanReverse)
# pragma intrinsic(_BitScanReverse64)

__forceinline static int32 CLZ(int32 arg) {
unsigned long idx;
Expand All @@ -58,6 +69,13 @@ __forceinline static int32 CLZ(int32 arg) {
}
return 32;
}
__forceinline static int64 CLZ(int64 arg) {
uint64 idx;
if (_BitScanReverse64(&idx, static_cast<uint64>(arg))) {
return (int64)(63 - idx);
}
return 64;
}

#elif defined(__ppc__) || defined(__powerpc__) || defined(__PPC__)

Expand Down Expand Up @@ -85,46 +103,63 @@ static __inline__ int32 CLZ(int32 arg) { return __builtin_clz(arg); }

// count trailing zeroes
inline int32 CTZ(int32 x) { return 32 - CLZ(~x & (x - 1)); }
inline int64 CTZ(int64 x) { return 64 - CLZ(~x & (x - 1)); }

// count leading ones
inline int32 CLO(int32 x) { return CLZ(~x); }
inline int64 CLO(int64 x) { return CLZ(~x); }

// count trailing ones
inline int32 CTO(int32 x) { return 32 - CLZ(x & (~x - 1)); }
inline int64 CTO(int64 x) { return 64 - CLZ(x & (~x - 1)); }

// number of bits required to represent x.
inline int32 NUMBITS(int32 x) { return 32 - CLZ(x); }
inline int64 NUMBITS(int64 x) { return 64 - CLZ(x); }

// log2 of the next power of two greater than or equal to x.
inline int32 LOG2CEIL(int32 x) { return 32 - CLZ(x - 1); }
inline int64 LOG2CEIL(int64 x) { return 64 - CLZ(x - 1); }

// is x a power of two
inline bool ISPOWEROFTWO(int32 x) { return (x & (x - 1)) == 0; }
inline bool ISPOWEROFTWO(int64 x) { return (x & (x - 1)) == 0; }

// next power of two greater than or equal to x
inline int32 NEXTPOWEROFTWO(int32 x) { return (int32)1L << LOG2CEIL(x); }
inline int64 NEXTPOWEROFTWO(int64 x) { return (int64)1L << LOG2CEIL(x); }

// previous power of two less than or equal to x
inline int32 PREVIOUSPOWEROFTWO(int32 x) {
if (ISPOWEROFTWO(x))
return x;
return (int32)1L << (LOG2CEIL(x) - 1);
}
inline int64 PREVIOUSPOWEROFTWO(int64 x) {
if (ISPOWEROFTWO(x))
return x;
return (int64)1L << (LOG2CEIL(x) - 1);
}

// input a series of counting integers, outputs a series of gray codes .
inline int32 GRAYCODE(int32 x) { return x ^ (x >> 1); }
inline int64 GRAYCODE(int64 x) { return x ^ (x >> 1); }

// find least significant bit
inline int32 LSBit(int32 x) { return x & -x; }
inline int64 LSBit(int64 x) { return x & -x; }

// find least significant bit position
inline int32 LSBitPos(int32 x) { return CTZ(x & -x); }
inline int64 LSBitPos(int64 x) { return CTZ(x & -x); }

// find most significant bit position
inline int32 MSBitPos(int32 x) { return 31 - CLZ(x); }
inline int64 MSBitPos(int64 x) { return 31 - CLZ(x); }

// find most significant bit
inline int32 MSBit(int32 x) { return (int32)1L << MSBitPos(x); }
inline int64 MSBit(int64 x) { return (int64)1L << MSBitPos(x); }

// count number of one bits
inline uint32 ONES(uint32 x) {
Expand All @@ -137,27 +172,74 @@ inline uint32 ONES(uint32 x) {
x = x + (x << 16);
return x >> 24;
}
inline uint64 ONES(uint64 x) {
std::bitset<64> bs(x); // pop count is in c++20
return bs.count();
}

// count number of zero bits
inline uint32 ZEROES(uint32 x) { return ONES(~x); }
inline uint64 ZEROES(uint64 x) { return ONES(~x); }


// reverse bits in a word
inline uint32 BitReverse(uint32 x) {
x = ((x & 0xAAAAAAAA) >> 1) | ((x & 0x55555555) << 1);
x = ((x & 0xCCCCCCCC) >> 2) | ((x & 0x33333333) << 2);
x = ((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4);
x = ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8);
return (x >> 16) | (x << 16);

#if defined(__GNUC__)
inline uint32 BitReverse(uint32 x) { return __bswap_32(x); }
inline uint64 BitReverse(uint64 x) { return __bswap_64(x); }

#elif defined(_MSC_VER)

inline uint32 BitReverse(uint32 x) { return _byteswap_ulong(x); }
inline uint64 BitReverse(uint64 x) { return _byteswap_uint64(x); }
#endif

template <typename T> constexpr T rotl(T x, int s) noexcept {
constexpr auto Nd = std::numeric_limits<T>::digits;
if ((Nd & (Nd - 1)) == 0) {
// Variant for power of two _Nd which the compiler can
// easily pattern match.
constexpr unsigned uNd = Nd;
const unsigned r = s;
return (x << (r % uNd)) | (x >> ((-r) % uNd));
}
const int r = s % Nd;
if (r == 0)
return x;
else if (r > 0)
return (x << r) | (x >> ((Nd - r) % Nd));
else
return (x >> -r) | (x << ((Nd + r) % Nd)); // rotr(x, -r)
}


template <typename Tp> constexpr Tp rotr(Tp x, int s) noexcept {
constexpr auto Nd = std::numeric_limits<Tp>::digits;
if ((Nd & (Nd - 1)) == 0) {
// Variant for power of two _Nd which the compiler can
// easily pattern match.
constexpr unsigned uNd = Nd;
const unsigned r = s;
return (x >> (r % uNd)) | (x << ((-r) % uNd));
}
const int r = s % Nd;
if (r == 0)
return x;
else if (r > 0)
return (x >> r) | (x << ((Nd - r) % Nd));
else
return (x << -r) | (x >> ((Nd + r) % Nd)); // rotl(x, -r)
}


// barrel shifts
inline uint32 RotateRight(uint32 x, uint32 s) {
s = s & 31;
return (x << (32 - s)) | (x >> s);
}

inline uint64 RotateRight(uint64 x, uint32 s) { return rotr(x, s); }
inline uint32 RotateLeft(uint32 x, uint32 s) {
s = s & 31;
return (x >> (32 - s)) | (x << s);
}
inline uint64 RotateLeft(uint64 x, uint32 s) { return rotl(x, s); }