xref: /linux/arch/x86/include/asm/shared/string.h (revision 40082fb4015712084df977bb8e7f0aa681a56a1a)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_X86_SHARED_STRING_H
3 #define _ASM_X86_SHARED_STRING_H
4 
__inline_memcpy(void * to,const void * from,size_t len)5 static __always_inline void *__inline_memcpy(void *to, const void *from, size_t len)
6 {
7 	void *ret = to;
8 
9 	asm volatile("rep movsb"
10 		     : "+D" (to), "+S" (from), "+c" (len)
11 		     : : "memory");
12 	return ret;
13 }
14 
__inline_memset(void * s,int v,size_t n)15 static __always_inline void *__inline_memset(void *s, int v, size_t n)
16 {
17 	void *ret = s;
18 
19 	asm volatile("rep stosb"
20 		     : "+D" (s), "+c" (n)
21 		     : "a" ((uint8_t)v)
22 		     : "memory");
23 	return ret;
24 }
25 
26 /*
27  * Returns:	0 (equal)
28  * 		1 (not equal)
29  *
30  * In contrast, the regular memcmp() follows glibc return value semantics.
31  */
__inline_memcmp(const void * s1,const void * s2,size_t len)32 static __always_inline int __inline_memcmp(const void *s1, const void *s2, size_t len)
33 {
34 	bool diff;
35 
36 	/*
37 	 * Make sure ZF is properly set in the len==0 case because in it,
38 	 * RCX==0 and the REPE; CMPSB won't get executed.
39 	 *
40 	 * The "cc" clobber has no meaning anymore, just source compatibility.
41 	 * On x86 the flag status bits are automatically added to the clobber
42 	 * set when there are no =@ccXY constraints. Keep it as documentation.
43 	 */
44 	asm volatile("test %3, %3\n\t"
45 		     "repe cmpsb"
46 		     : "=@ccnz" (diff), "+D" (s1), "+S" (s2), "+c" (len)
47 		     : : /* "cc", */ "memory");
48 
49 	return diff;
50 }
51 
52 #endif /* _ASM_X86_SHARED_STRING_H */
53