/*1* This program is free software; you can redistribute it and/or2* modify it under the terms of the GNU General Public License3* as published by the Free Software Foundation; version 24* of the License.5*6*/7#include <linux/linkage.h>8#include <asm/alternative-asm.h>9#include <asm/frame.h>10#include <asm/dwarf2.h>1112#ifdef CONFIG_SMP13#define SEG_PREFIX %gs:14#else15#define SEG_PREFIX16#endif1718.text1920/*21* Inputs:22* %rsi : memory location to compare23* %rax : low 64 bits of old value24* %rdx : high 64 bits of old value25* %rbx : low 64 bits of new value26* %rcx : high 64 bits of new value27* %al : Operation successful28*/29ENTRY(this_cpu_cmpxchg16b_emu)30CFI_STARTPROC3132#33# Emulate 'cmpxchg16b %gs:(%rsi)' except we return the result in %al not34# via the ZF. Caller will access %al to get result.35#36# Note that this is only useful for a cpuops operation. Meaning that we37# do *not* have a fully atomic operation but just an operation that is38# *atomic* on a single cpu (as provided by the this_cpu_xx class of39# macros).40#41this_cpu_cmpxchg16b_emu:42pushf43cli4445cmpq SEG_PREFIX(%rsi), %rax46jne not_same47cmpq SEG_PREFIX 8(%rsi), %rdx48jne not_same4950movq %rbx, SEG_PREFIX(%rsi)51movq %rcx, SEG_PREFIX 8(%rsi)5253popf54mov $1, %al55ret5657not_same:58popf59xor %al,%al60ret6162CFI_ENDPROC6364ENDPROC(this_cpu_cmpxchg16b_emu)656667