]> granicus.if.org Git - clang/commitdiff
ms Intrin.h: Fix __movsw's and __stosw's inline asm.
authorNico Weber <nicolasweber@gmx.de>
Tue, 22 Sep 2015 00:46:21 +0000 (00:46 +0000)
committerNico Weber <nicolasweber@gmx.de>
Tue, 22 Sep 2015 00:46:21 +0000 (00:46 +0000)
Before, clang's internal assembler would reject the inline asm in clang's
Intrin.h.  To make sure this doesn't happen for other Intrin.h functions using
__asm__ blocks, add 32-bit and 64-bit codegen tests for Intrin.h.

Sadly, these tests discovered that __readcr3 and __writecr3 have bad
implementations in 64-bit builds.  This will have to be fixed in a follow-up.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@248234 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Headers/Intrin.h
test/Headers/ms-intrin.cpp

index fc852dcf14ba6dd1db993220699233d140b94729..b3bd1dca911dc45fe496e4d424e6e3a1382b7f85 100644 (file)
@@ -846,7 +846,7 @@ __movsd(unsigned long *__dst, unsigned long const *__src, size_t __n) {
 }
 static __inline__ void __DEFAULT_FN_ATTRS
 __movsw(unsigned short *__dst, unsigned short const *__src, size_t __n) {
-  __asm__("rep movsh" : : "D"(__dst), "S"(__src), "c"(__n)
+  __asm__("rep movsw" : : "D"(__dst), "S"(__src), "c"(__n)
                         : "%edi", "%esi", "%ecx");
 }
 static __inline__ void __DEFAULT_FN_ATTRS
@@ -861,7 +861,7 @@ __stosd(unsigned long *__dst, unsigned long __x, size_t __n) {
 }
 static __inline__ void __DEFAULT_FN_ATTRS
 __stosw(unsigned short *__dst, unsigned short __x, size_t __n) {
-  __asm__("rep stosh" : : "D"(__dst), "a"(__x), "c"(__n)
+  __asm__("rep stosw" : : "D"(__dst), "a"(__x), "c"(__n)
                         : "%edi", "%ecx");
 }
 #endif
index a83225e37f8eb2135634e499f4f65840859afb1a..9b3c6c97090a8ddc5849a2758c7535f9b28b9827 100644 (file)
@@ -5,12 +5,12 @@
 
 // RUN: %clang_cc1 -triple i386-pc-win32 -target-cpu broadwell \
 // RUN:     -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
-// RUN:     -ffreestanding -fsyntax-only -Werror \
+// RUN:     -ffreestanding -emit-obj -o /dev/null -Werror \
 // RUN:     -isystem %S/Inputs/include %s
 
 // RUN: %clang_cc1 -triple x86_64-pc-win32  \
 // RUN:     -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
-// RUN:     -ffreestanding -fsyntax-only -Werror \
+// RUN:     -ffreestanding -emit-obj -o /dev/null -Werror \
 // RUN:     -isystem %S/Inputs/include %s
 
 // RUN: %clang_cc1 -triple thumbv7--windows \
@@ -27,3 +27,35 @@ typedef __SIZE_TYPE__ size_t;
 // Use some C++ to make sure we closed the extern "C" brackets.
 template <typename T>
 void foo(T V) {}
+
+// __asm__ blocks are only checked for inline functions that end up being
+// emitted, so call functions with __asm__ blocks to make sure their inline
+// assembly parses.
+void f() {
+  __movsb(0, 0, 0);
+  __movsd(0, 0, 0);
+  __movsw(0, 0, 0);
+
+  __stosb(0, 0, 0);
+  __stosd(0, 0, 0);
+  __stosw(0, 0, 0);
+
+#ifdef _M_X64
+  __movsq(0, 0, 0);
+  __stosq(0, 0, 0);
+#endif
+
+  int info[4];
+  __cpuid(info, 0);
+  __cpuidex(info, 0, 0);
+  _xgetbv(0);
+  __halt();
+  __readmsr(0);
+
+  // FIXME: Call these in 64-bit too once the intrinsics have been fixed to
+  // work there.
+#ifndef _M_X64
+  __readcr3();
+  __writecr3(0);
+#endif
+}