From: Nico Weber Date: Fri, 20 Jul 2018 21:02:09 +0000 (+0000) Subject: [ms] Add __shiftleft128 / __shiftright128 intrinsics X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c74a596b1d364a9ecf0d274fbdfd46e998cc59f7;p=clang [ms] Add __shiftleft128 / __shiftright128 intrinsics Carefully match the pattern matched by ISel so that this produces shld / shrd (unless Subtarget->isSHLDSlow() is true). Thanks to Craig Topper for providing the LLVM IR pattern that gets successfully matched. Fixes PR37755. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@337619 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Headers/intrin.h b/lib/Headers/intrin.h index edb947eef6..91914214e2 100644 --- a/lib/Headers/intrin.h +++ b/lib/Headers/intrin.h @@ -863,6 +863,20 @@ __nop(void) { __asm__ volatile ("nop"); } #endif +#if defined(__x86_64__) +static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS +__shiftleft128(unsigned __int64 __l, unsigned __int64 __h, unsigned char __d) { + unsigned __int128 __val = ((unsigned __int128)__h << 64) | __l; + unsigned __int128 __res = __val << (__d & 63); + return (unsigned __int64)(__res >> 64); +} +static __inline__ unsigned __int64 __DEFAULT_FN_ATTRS +__shiftright128(unsigned __int64 __l, unsigned __int64 __h, unsigned char __d) { + unsigned __int128 __val = ((unsigned __int128)__h << 64) | __l; + unsigned __int128 __res = __val >> (__d & 63); + return (unsigned __int64)__res; +} +#endif /*----------------------------------------------------------------------------*\ |* Privileged intrinsics diff --git a/test/Headers/ms-intrin.cpp b/test/Headers/ms-intrin.cpp index b0fef9cc06..d8a4d382eb 100644 --- a/test/Headers/ms-intrin.cpp +++ b/test/Headers/ms-intrin.cpp @@ -42,6 +42,8 @@ void f() { __stosw(0, 0, 0); #ifdef _M_X64 + __shiftleft128(1, 2, 3); + __shiftright128(1, 2, 3); __movsq(0, 0, 0); __stosq(0, 0, 0); #endif