xref: /linux/tools/arch/x86/include/asm/special_insns.h (revision 55a42f78ffd386e01a5404419f8c5ded7db70a21)
1*3fe30577SDavid Matlack /* SPDX-License-Identifier: GPL-2.0 */
2*3fe30577SDavid Matlack #ifndef _TOOLS_ASM_X86_SPECIAL_INSNS_H
3*3fe30577SDavid Matlack #define _TOOLS_ASM_X86_SPECIAL_INSNS_H
4*3fe30577SDavid Matlack 
5*3fe30577SDavid Matlack /* The dst parameter must be 64-bytes aligned */
6*3fe30577SDavid Matlack static inline void movdir64b(void *dst, const void *src)
7*3fe30577SDavid Matlack {
8*3fe30577SDavid Matlack 	const struct { char _[64]; } *__src = src;
9*3fe30577SDavid Matlack 	struct { char _[64]; } *__dst = dst;
10*3fe30577SDavid Matlack 
11*3fe30577SDavid Matlack 	/*
12*3fe30577SDavid Matlack 	 * MOVDIR64B %(rdx), rax.
13*3fe30577SDavid Matlack 	 *
14*3fe30577SDavid Matlack 	 * Both __src and __dst must be memory constraints in order to tell the
15*3fe30577SDavid Matlack 	 * compiler that no other memory accesses should be reordered around
16*3fe30577SDavid Matlack 	 * this one.
17*3fe30577SDavid Matlack 	 *
18*3fe30577SDavid Matlack 	 * Also, both must be supplied as lvalues because this tells
19*3fe30577SDavid Matlack 	 * the compiler what the object is (its size) the instruction accesses.
20*3fe30577SDavid Matlack 	 * I.e., not the pointers but what they point to, thus the deref'ing '*'.
21*3fe30577SDavid Matlack 	 */
22*3fe30577SDavid Matlack 	asm volatile(".byte 0x66, 0x0f, 0x38, 0xf8, 0x02"
23*3fe30577SDavid Matlack 		     : "+m" (*__dst)
24*3fe30577SDavid Matlack 		     :  "m" (*__src), "a" (__dst), "d" (__src));
25*3fe30577SDavid Matlack }
26*3fe30577SDavid Matlack 
27*3fe30577SDavid Matlack #endif /* _TOOLS_ASM_X86_SPECIAL_INSNS_H */
28