18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#include <linux/linkage.h>
48c2ecf20Sopenharmony_ci#include <asm/export.h>
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci.text
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci/*
98c2ecf20Sopenharmony_ci * Inputs:
108c2ecf20Sopenharmony_ci * %esi : memory location to compare
118c2ecf20Sopenharmony_ci * %eax : low 32 bits of old value
128c2ecf20Sopenharmony_ci * %edx : high 32 bits of old value
138c2ecf20Sopenharmony_ci * %ebx : low 32 bits of new value
148c2ecf20Sopenharmony_ci * %ecx : high 32 bits of new value
158c2ecf20Sopenharmony_ci */
168c2ecf20Sopenharmony_ciSYM_FUNC_START(cmpxchg8b_emu)
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#
198c2ecf20Sopenharmony_ci# Emulate 'cmpxchg8b (%esi)' on UP except we don't
208c2ecf20Sopenharmony_ci# set the whole ZF thing (caller will just compare
218c2ecf20Sopenharmony_ci# eax:edx with the expected value)
228c2ecf20Sopenharmony_ci#
238c2ecf20Sopenharmony_ci	pushfl
248c2ecf20Sopenharmony_ci	cli
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci	cmpl  (%esi), %eax
278c2ecf20Sopenharmony_ci	jne .Lnot_same
288c2ecf20Sopenharmony_ci	cmpl 4(%esi), %edx
298c2ecf20Sopenharmony_ci	jne .Lhalf_same
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	movl %ebx,  (%esi)
328c2ecf20Sopenharmony_ci	movl %ecx, 4(%esi)
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci	popfl
358c2ecf20Sopenharmony_ci	RET
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci.Lnot_same:
388c2ecf20Sopenharmony_ci	movl  (%esi), %eax
398c2ecf20Sopenharmony_ci.Lhalf_same:
408c2ecf20Sopenharmony_ci	movl 4(%esi), %edx
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	popfl
438c2ecf20Sopenharmony_ci	RET
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ciSYM_FUNC_END(cmpxchg8b_emu)
468c2ecf20Sopenharmony_ciEXPORT_SYMBOL(cmpxchg8b_emu)
47