0

I am trying to compile QuickJS, which is normally developed under linux and gcc has no problem with such code. However, I have troubles to compile this on Visual Studio 2019:

typedef unsigned __int128 uint128_t;

Does anyone know a trick to make this work as it is supposed to work?

enter image description here

The error is:

error C4235: Non-standard extension: The __int128 keyword is not supported for this architecture.

However, __m128 is supported, just not as unsigned, so that doesn't help with this.

kungfooman
  • 4,473
  • 1
  • 44
  • 33
  • 2
    _"I have troubles to compile"_ - what troubles? What compiler diagnostics are emitted? "_work as it is supposed to work_" Why would you expect non-standard compiler extensions for one compiler to work on another? – Clifford Jul 13 '21 at 08:39
  • 2
    Don't post _pictures of code_. Post the code. If anyone chooses to reproduce your issue, you are forcing them to retype your code. – Clifford Jul 13 '21 at 08:42
  • @Clifford 1) I posted the code PLUS image, to provide context, that this is in C and not C++ 2) The linked answer is in C++ and is about SIGNED and not UNSIGNED – kungfooman Jul 13 '21 at 09:19
  • 1
    It is largely academic re C vs C++, if the C compiler had __int128 as an extension, it would be available in the C++ compiler. The accepted answer is the point. I accept however that the answers offering C++ solutions are not useful. I'll unduplicate it. In my test the error was indicated for the preceding line; not the line you posted as text; but I take your point. – Clifford Jul 13 '21 at 09:27
  • @Clifford Thanks for testing the issue and reopening! – kungfooman Jul 13 '21 at 09:33
  • Does this answer your question? [How to enable \_\_int128 on Visual Studio?](https://stackoverflow.com/questions/6759592/how-to-enable-int128-on-visual-studio) – phuclv Jul 13 '21 at 10:03
  • There's no 128-bit int type in MSVC. You must implement it yourself or use a 3rd party library for that. Or just change to a different compiler like gcc, clang or icc. OTOH `__m128`, `__m256` and `__m512` are SIMD types so obviously they're available for use, just not for high-precision math. You can't use `__m128` for even signed 128-bit math. Also note that MSVC is a C++ compiler and doesn't support C very well. Duplicate: [Can I use 128-bit integer in MSVC++?](https://stackoverflow.com/q/23775248/995714) – phuclv Jul 13 '21 at 10:07
  • 1
    @phuclv That is the answer I originally marked as duplicate, but as the OP pointed out, it is for C++ compilation and the work-around answers are C++. MSVC in VS2019 supports C compilation to ISO C17 (with `/std:c17`), but it is true that the default compilation is an ill-defined mix of C89 with some of C99 and some MS extensions. – Clifford Jul 13 '21 at 10:45

1 Answers1

3

__m128 is defined as a union thus:

typedef union __declspec(intrin_type) __declspec(align(16)) __m128 {
     float               m128_f32[4];
     unsigned __int64    m128_u64[2];
     __int8              m128_i8[16];
     __int16             m128_i16[8];
     __int32             m128_i32[4];
     __int64             m128_i64[2];
     unsigned __int8     m128_u8[16];
     unsigned __int16    m128_u16[8];
     unsigned __int32    m128_u32[4];
 } __m128;

Clearly it can be used for unsigned operations via its m128_uXX members but it cannot be used semantically like a built-in data type - including qualifying with unsigned, and it cannot be used in built-in arithmetic operations - it requires functions/extensions defined specifically defined to operate on it. It is intended for use with SSE/SSE2 SIMD extensions

Microsoft's implementation does not include an extension 128 bit integer type.

In terms of the QuickJS code, the problem is in the preceding libbf.h code there is:

#if defined(__x86_64__)
#define LIMB_LOG2_BITS 6
#else
#define LIMB_LOG2_BITS 5
#endif

#define LIMB_BITS (1 << LIMB_LOG2_BITS)

So that for 64 bit compilation LIMB_BITS == 64. I suggest one of two solutions:

  • Use 32 bit compilation so that LIMB_BITS == 32
  • Modify libbf.h thus:
    #if defined(__x86_64__) || defined(_MSC_VER)
    
    so that the 128-bit definitions are omitted on an MS build.
  • Use a Windows compiler that has a __int128 built-in such as Mingw64.

I note that there is a QuickJS Visual Studio port here, but looking at the code and the lua script that generates the VS solution it is not immediately obvious to me how or even if this issue is resolved. The readme.md file says to download and install premake5, but the link is broken. I gave up at that point.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • Wow, thank you so much for investigating and even downloading QuickJS and trying to build it. It took me days to gets things running in Visual Studio + CMake, so I'm not surprised you stopped trying. `__MSC_VER` needs to be `_MSC_VER` (one underscore) I still have some other bugs to fix now, so I will report when I get it to work with your idea in the specific QuickJS case (decreasing `LIMB_BITS`). Thanks again! – kungfooman Jul 13 '21 at 10:36
  • I didn't experiment too much yet but from what I can observe it compiles perfectly with some other gcc/VS inconsistencies fixed and my first BigInt tests gave correct results, and I am grateful for your input. I realize this question is not really answerable when the compiler itself doesn't support it, so this specific workaround gets to the point. – kungfooman Jul 13 '21 at 15:01