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