16

GCC and Clang have the __int128_t and __uint128_t extensions for 128-bit integer arithmetic.

I was hopeful that __m128i would give something similar for the Intel C Compiler, but (if it's even possible) it looks to me like I'd have to write explicit SSE2 function calls in order to use __m128i, instead of using "built-in" operators like +, -, *, /, and %. I was hoping to do something like this (this doesn't work):

#if defined(__INTEL_COMPILER) && defined(__SSE2__)
  #include "xmmintrin.h"
  typedef __u128 uint128_t;
#elif defined (__GNUC__)
  typedef __uint128_t uint128_t;
#else
  #error For 128-bit arithmetic we need GCC or ICC, or uint128_t
#endif

Is there 128-bit integer support with the operators +, -, *, /, and % somewhere buried in icc?

Douglas B. Staple
  • 10,510
  • 8
  • 31
  • 58
  • I'm using icc (ICC) 12.0.0 20101006 but I'd be interested in any version of icc. I'd also be interested in other C compilers for linux supporting this. – Douglas B. Staple May 03 '13 at 19:02
  • The answer to this is almost definitely 'no'. I just [cross-posted to the Intel Developer Forum](http://software.intel.com/en-us/forums/topic/392619). – Douglas B. Staple May 15 '13 at 18:58
  • 1
    MMX, SSE and their successors are meant to be used for multiple values at a time, not for a 128-bit number. I don't think there are any 128 bit math instruction in 256-bit AVX/AVX2 or even in AVX-512 in the future. If you need 128 bit math, use a library or build your own – phuclv Jan 29 '14 at 01:46
  • @LưuVĩnhPhúc, yes you're right. I asked [a question](http://stackoverflow.com/questions/16566437/is-int128-t-arithmetic-emulated-by-gcc-even-with-sse) about that last year. Also, it seems that [there is no C compiler besides GCC](http://stackoverflow.com/questions/16424386/gcc-alternative-for-linux-supporting-openmp-and-128-bit-integers-with) supporting OpenMP and a drop-in replacement for `__int128_t` and `__uint128_t`. – Douglas B. Staple Jun 04 '14 at 23:42

1 Answers1

11

From what I can tell, at least icc 13.0.1+ support __int128_t and __uint128_t. Courtesy of Matt Godbolt's Compiler Explorer:

__int128_t ai (__int128_t x, __int128_t y) {
  return x + y;
}

__int128_t mi (__int128_t x, __int128_t y) {
  return x * y;
}

__int128_t di (__int128_t x, __int128_t y) {
  return x / y;
}

__int128_t ri (__int128_t x, __int128_t y) {
  return x % y;
}

compiles to:

L__routine_start_ai_0:
ai:
        add       rdi, rdx                                      #2.14
        mov       rax, rdi                                      #2.14
        adc       rsi, rcx                                      #2.14
        mov       rdx, rsi                                      #2.14
        ret                                                     #2.14
L__routine_start_mi_1:
mi:
        mov       rax, rdi                                      #6.14
        imul      rsi, rdx                                      #6.14
        imul      rcx, rdi                                      #6.14
        mul       rdx                                           #6.14
        add       rsi, rcx                                      #6.14
        add       rdx, rsi                                      #6.14
        ret                                                     #6.14
L__routine_start_di_2:
di:
        push      rsi                                           #9.44
        call      __divti3                                      #10.14
        pop       rcx                                           #10.14
        ret                                                     #10.14
L__routine_start_ri_3:
ri:
        push      rsi                                           #13.44
        call      __modti3                                      #14.14
        pop       rcx                                           #14.14
        ret                                                     #14.14

with icc 13.0.1 (http://goo.gl/UnxEFt).

haneefmubarak
  • 1,911
  • 1
  • 21
  • 32
  • 1
    Yes, it works! I just verified that __uint128_t is *not* available in icc 12.1.4, but *is* available in 13.0.0, 14.0.4, and 15.0.0. So the switch seems to have occurred with version 13. – Douglas B. Staple Mar 04 '15 at 14:02