root/arch/csky/kernel/atomic.S
/* SPDX-License-Identifier: GPL-2.0 */
// Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.

#include <linux/linkage.h>
#include <abi/entry.h>

.text

/*
 * int csky_cmpxchg(int oldval, int newval, int *ptr)
 *
 * If *ptr != oldval && return 1,
 * else *ptr = newval return 0.
 */
ENTRY(csky_cmpxchg)
        USPTOKSP

        RD_MEH  a3
        WR_MEH  a3

        mfcr    a3, epc
        addi    a3, TRAP0_SIZE

        subi    sp, 16
        stw     a3, (sp, 0)
        mfcr    a3, epsr
        stw     a3, (sp, 4)
        mfcr    a3, usp
        stw     a3, (sp, 8)

        psrset  ee
#ifdef CONFIG_CPU_HAS_LDSTEX
1:
        ldex    a3, (a2)
        cmpne   a0, a3
        bt16    2f
        mov     a3, a1
        stex    a3, (a2)
        bez     a3, 1b
2:
        sync.is
#else
GLOBAL(csky_cmpxchg_ldw)
        ldw     a3, (a2)
        cmpne   a0, a3
        bt16    3f
GLOBAL(csky_cmpxchg_stw)
        stw     a1, (a2)
3:
#endif
        mvc     a0
        ldw     a3, (sp, 0)
        mtcr    a3, epc
        ldw     a3, (sp, 4)
        mtcr    a3, epsr
        ldw     a3, (sp, 8)
        mtcr    a3, usp
        addi    sp, 16
        KSPTOUSP
        rte
END(csky_cmpxchg)