From e5898c1911a416e782994c4668d2eba26da069fe Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Fri, 20 Jul 2018 21:02:09 +0000 Subject: [PATCH] [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. llvm-svn: 337619 --- clang/lib/Headers/intrin.h | 14 ++++++++++++++ clang/test/Headers/ms-intrin.cpp | 2 ++ 2 files changed, 16 insertions(+) diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h index edb947e..9191421 100644 --- a/clang/lib/Headers/intrin.h +++ b/clang/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/clang/test/Headers/ms-intrin.cpp b/clang/test/Headers/ms-intrin.cpp index b0fef9c..d8a4d38 100644 --- a/clang/test/Headers/ms-intrin.cpp +++ b/clang/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 -- 2.7.4