diff --git a/clang/lib/Headers/intrin.h b/clang/lib/Headers/intrin.h --- a/clang/lib/Headers/intrin.h +++ b/clang/lib/Headers/intrin.h @@ -451,24 +451,47 @@ static __inline__ void __DEFAULT_FN_ATTRS __movsb(unsigned char *__dst, unsigned char const *__src, size_t __n) { - __asm__ __volatile__("rep movsb" : "+D"(__dst), "+S"(__src), "+c"(__n) - : : "memory"); +#if defined(__x86_64__) + __asm__ __volatile__("rep movsb" + : "+D"(__dst), "+S"(__src), "+c"(__n) + : + : "memory"); +#else + __asm__ __volatile__("xchg %%esi, %1\nrep movsb\nxchg %%esi, %1" + : "+D"(__dst), "+r"(__src), "+c"(__n) + : + : "memory"); +#endif } static __inline__ void __DEFAULT_FN_ATTRS __movsd(unsigned long *__dst, unsigned long const *__src, size_t __n) { +#if defined(__x86_64__) __asm__ __volatile__("rep movsl" : "+D"(__dst), "+S"(__src), "+c"(__n) : : "memory"); +#else + __asm__ __volatile__("xchg %%esi, %1\nrep movsl\nxchg %%esi, %1" + : "+D"(__dst), "+r"(__src), "+c"(__n) + : + : "memory"); +#endif } static __inline__ void __DEFAULT_FN_ATTRS __movsw(unsigned short *__dst, unsigned short const *__src, size_t __n) { +#if defined(__x86_64__) __asm__ __volatile__("rep movsw" : "+D"(__dst), "+S"(__src), "+c"(__n) : : "memory"); +#else + __asm__ __volatile__("xchg %%esi, %1\nrep movsw\nxchg %%esi, %1" + : "+D"(__dst), "+r"(__src), "+c"(__n) + : + : "memory"); +#endif } static __inline__ void __DEFAULT_FN_ATTRS __stosd(unsigned long *__dst, unsigned long __x, diff --git a/clang/test/CodeGen/ms-intrinsics.c b/clang/test/CodeGen/ms-intrinsics.c --- a/clang/test/CodeGen/ms-intrinsics.c +++ b/clang/test/CodeGen/ms-intrinsics.c @@ -36,7 +36,7 @@ return __movsb(Dest, Src, Count); } // CHECK-I386-LABEL: define{{.*}} void @test__movsb -// CHECK-I386: call { i8*, i8*, i32 } asm sideeffect "rep movsb", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %Dest, i8* %Src, i32 %Count) +// CHECK-I386: tail call { i8*, i8*, i32 } asm sideeffect "xchg %esi, $1\0Arep movsb\0Axchg %esi, $1", "={di},=r,={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* %Dest, i8* %Src, i32 %Count) // CHECK-I386: ret void // CHECK-I386: } @@ -62,7 +62,7 @@ return __movsw(Dest, Src, Count); } // CHECK-I386-LABEL: define{{.*}} void @test__movsw -// CHECK-I386: call { i16*, i16*, i32 } asm sideeffect "rep movsw", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i16* %Dest, i16* %Src, i32 %Count) +// CHECK-I386: tail call { i16*, i16*, i32 } asm sideeffect "xchg %esi, $1\0Arep movsw\0Axchg %esi, $1", "={di},=r,={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i16* %Dest, i16* %Src, i32 %Count) // CHECK-I386: ret void // CHECK-I386: } @@ -88,7 +88,7 @@ return __movsd(Dest, Src, Count); } // CHECK-I386-LABEL: define{{.*}} void @test__movsd -// CHECK-I386: call { i32*, i32*, i32 } asm sideeffect "rep movsl", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Dest, i32* %Src, i32 %Count) +// CHECK-I386: tail call { i32*, i32*, i32 } asm sideeffect "xchg %esi, $1\0Arep movsl\0Axchg %esi, $1", "={di},=r,={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(i32* %Dest, i32* %Src, i32 %Count) // CHECK-I386: ret void // CHECK-I386: }