xref: /OK3568_Linux_fs/kernel/arch/x86/lib/cmpxchg8b_emu.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun#include <linux/linkage.h>
4*4882a593Smuzhiyun#include <asm/export.h>
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun.text
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun/*
9*4882a593Smuzhiyun * Inputs:
10*4882a593Smuzhiyun * %esi : memory location to compare
11*4882a593Smuzhiyun * %eax : low 32 bits of old value
12*4882a593Smuzhiyun * %edx : high 32 bits of old value
13*4882a593Smuzhiyun * %ebx : low 32 bits of new value
14*4882a593Smuzhiyun * %ecx : high 32 bits of new value
15*4882a593Smuzhiyun */
16*4882a593SmuzhiyunSYM_FUNC_START(cmpxchg8b_emu)
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun#
19*4882a593Smuzhiyun# Emulate 'cmpxchg8b (%esi)' on UP except we don't
20*4882a593Smuzhiyun# set the whole ZF thing (caller will just compare
21*4882a593Smuzhiyun# eax:edx with the expected value)
22*4882a593Smuzhiyun#
23*4882a593Smuzhiyun	pushfl
24*4882a593Smuzhiyun	cli
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun	cmpl  (%esi), %eax
27*4882a593Smuzhiyun	jne .Lnot_same
28*4882a593Smuzhiyun	cmpl 4(%esi), %edx
29*4882a593Smuzhiyun	jne .Lhalf_same
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun	movl %ebx,  (%esi)
32*4882a593Smuzhiyun	movl %ecx, 4(%esi)
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun	popfl
35*4882a593Smuzhiyun	RET
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun.Lnot_same:
38*4882a593Smuzhiyun	movl  (%esi), %eax
39*4882a593Smuzhiyun.Lhalf_same:
40*4882a593Smuzhiyun	movl 4(%esi), %edx
41*4882a593Smuzhiyun
42*4882a593Smuzhiyun	popfl
43*4882a593Smuzhiyun	RET
44*4882a593Smuzhiyun
45*4882a593SmuzhiyunSYM_FUNC_END(cmpxchg8b_emu)
46*4882a593SmuzhiyunEXPORT_SYMBOL(cmpxchg8b_emu)
47