1*dca69f4cSkettenis/* $OpenBSD: lse.S,v 1.1 2024/07/02 10:25:16 kettenis Exp $ */ 2*dca69f4cSkettenis/* 3*dca69f4cSkettenis * Copyright (c) 2024 Mark Kettenis <kettenis@openbsd.org> 4*dca69f4cSkettenis * 5*dca69f4cSkettenis * Permission to use, copy, modify, and distribute this software for any 6*dca69f4cSkettenis * purpose with or without fee is hereby granted, provided that the above 7*dca69f4cSkettenis * copyright notice and this permission notice appear in all copies. 8*dca69f4cSkettenis * 9*dca69f4cSkettenis * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10*dca69f4cSkettenis * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*dca69f4cSkettenis * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12*dca69f4cSkettenis * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*dca69f4cSkettenis * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*dca69f4cSkettenis * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15*dca69f4cSkettenis * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16*dca69f4cSkettenis */ 17*dca69f4cSkettenis 18*dca69f4cSkettenis#include <machine/asm.h> 19*dca69f4cSkettenis 20*dca69f4cSkettenis/* 21*dca69f4cSkettenis * Out-of-line LSE atomics helpers 22*dca69f4cSkettenis */ 23*dca69f4cSkettenis 24*dca69f4cSkettenis.arch armv8-a+lse 25*dca69f4cSkettenis 26*dca69f4cSkettenisENTRY(__aarch64_cas4_acq_rel) 27*dca69f4cSkettenis RETGUARD_SETUP(__aarch64_cas4_acq_rel, x15) 28*dca69f4cSkettenis adrp x9, arm64_has_lse 29*dca69f4cSkettenis ldr w9, [x9, :lo12:arm64_has_lse] 30*dca69f4cSkettenis cbz w9, 1f 31*dca69f4cSkettenis casal w0, w1, [x2] 32*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_cas4_acq_rel, x15) 33*dca69f4cSkettenis ret 34*dca69f4cSkettenis1: 35*dca69f4cSkettenis ldaxr w9, [x2] 36*dca69f4cSkettenis cmp w9, w0 37*dca69f4cSkettenis b.ne 2f 38*dca69f4cSkettenis stlxr w10, w1, [x2] 39*dca69f4cSkettenis cbnz w10, 1b 40*dca69f4cSkettenis2: 41*dca69f4cSkettenis mov w0, w9 42*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_cas4_acq_rel, x15) 43*dca69f4cSkettenis ret 44*dca69f4cSkettenisEND(__aarch64_cas4_acq_rel) 45*dca69f4cSkettenis 46*dca69f4cSkettenisENTRY(__aarch64_cas8_acq_rel) 47*dca69f4cSkettenis RETGUARD_SETUP(__aarch64_cas8_acq_rel, x15) 48*dca69f4cSkettenis adrp x9, arm64_has_lse 49*dca69f4cSkettenis ldr w9, [x9, :lo12:arm64_has_lse] 50*dca69f4cSkettenis cbz w9, 1f 51*dca69f4cSkettenis casal x0, x1, [x2] 52*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_cas8_acq_rel, x15) 53*dca69f4cSkettenis ret 54*dca69f4cSkettenis1: 55*dca69f4cSkettenis ldaxr x9, [x2] 56*dca69f4cSkettenis cmp x9, x0 57*dca69f4cSkettenis b.ne 2f 58*dca69f4cSkettenis stlxr w10, x1, [x2] 59*dca69f4cSkettenis cbnz w10, 1b 60*dca69f4cSkettenis2: 61*dca69f4cSkettenis mov x0, x9 62*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_cas8_acq_rel, x15) 63*dca69f4cSkettenis ret 64*dca69f4cSkettenisEND(__aarch64_cas8_acq_rel) 65*dca69f4cSkettenis 66*dca69f4cSkettenisENTRY(__aarch64_ldadd4_acq_rel) 67*dca69f4cSkettenis RETGUARD_SETUP(__aarch64_ldadd4_acq_rel, x15) 68*dca69f4cSkettenis adrp x9, arm64_has_lse 69*dca69f4cSkettenis ldr w9, [x9, :lo12:arm64_has_lse] 70*dca69f4cSkettenis cbz w9, 1f 71*dca69f4cSkettenis ldaddal w0, w0, [x1] 72*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_ldadd4_acq_rel, x15) 73*dca69f4cSkettenis ret 74*dca69f4cSkettenis1: 75*dca69f4cSkettenis ldaxr w9, [x1] 76*dca69f4cSkettenis add w11, w9, w0 77*dca69f4cSkettenis stlxr w10, w11, [x1] 78*dca69f4cSkettenis cbnz w10, 1b 79*dca69f4cSkettenis mov w0, w9 80*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_ldadd4_acq_rel, x15) 81*dca69f4cSkettenis ret 82*dca69f4cSkettenisEND(__aarch64_ldadd4_acq_rel) 83*dca69f4cSkettenis 84*dca69f4cSkettenisENTRY(__aarch64_ldadd8_acq_rel) 85*dca69f4cSkettenis RETGUARD_SETUP(__aarch64_ldadd8_acq_rel, x15) 86*dca69f4cSkettenis adrp x9, arm64_has_lse 87*dca69f4cSkettenis ldr w9, [x9, :lo12:arm64_has_lse] 88*dca69f4cSkettenis cbz w9, 1f 89*dca69f4cSkettenis ldaddal x0, x0, [x1] 90*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_ldadd8_acq_rel, x15) 91*dca69f4cSkettenis ret 92*dca69f4cSkettenis1: 93*dca69f4cSkettenis ldaxr x9, [x1] 94*dca69f4cSkettenis add x11, x9, x0 95*dca69f4cSkettenis stlxr w10, x11, [x1] 96*dca69f4cSkettenis cbnz w10, 1b 97*dca69f4cSkettenis mov x0, x9 98*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_ldadd8_acq_rel, x15) 99*dca69f4cSkettenis ret 100*dca69f4cSkettenisEND(__aarch64_ldadd8_acq_rel) 101*dca69f4cSkettenis 102*dca69f4cSkettenisENTRY(__aarch64_ldclr4_acq_rel) 103*dca69f4cSkettenis RETGUARD_SETUP(__aarch64_ldclr4_acq_rel, x15) 104*dca69f4cSkettenis adrp x9, arm64_has_lse 105*dca69f4cSkettenis ldr w9, [x9, :lo12:arm64_has_lse] 106*dca69f4cSkettenis cbz w9, 1f 107*dca69f4cSkettenis ldclral w0, w0, [x1] 108*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_ldclr4_acq_rel, x15) 109*dca69f4cSkettenis ret 110*dca69f4cSkettenis1: 111*dca69f4cSkettenis ldaxr w9, [x1] 112*dca69f4cSkettenis bic w11, w9, w0 113*dca69f4cSkettenis stlxr w10, w11, [x1] 114*dca69f4cSkettenis cbnz w10, 1b 115*dca69f4cSkettenis mov w0, w9 116*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_ldclr4_acq_rel, x15) 117*dca69f4cSkettenis ret 118*dca69f4cSkettenisEND(__aarch64_ldclr4_acq_rel) 119*dca69f4cSkettenis 120*dca69f4cSkettenisENTRY(__aarch64_ldset4_acq_rel) 121*dca69f4cSkettenis RETGUARD_SETUP(__aarch64_ldset4_acq_rel, x15) 122*dca69f4cSkettenis adrp x9, arm64_has_lse 123*dca69f4cSkettenis ldr w9, [x9, :lo12:arm64_has_lse] 124*dca69f4cSkettenis cbz w9, 1f 125*dca69f4cSkettenis ldsetal w0, w0, [x1] 126*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_ldset4_acq_rel, x15) 127*dca69f4cSkettenis ret 128*dca69f4cSkettenis1: 129*dca69f4cSkettenis ldaxr w9, [x1] 130*dca69f4cSkettenis orr w11, w9, w0 131*dca69f4cSkettenis stlxr w10, w11, [x1] 132*dca69f4cSkettenis cbnz w10, 1b 133*dca69f4cSkettenis mov w0, w9 134*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_ldset4_acq_rel, x15) 135*dca69f4cSkettenis ret 136*dca69f4cSkettenisEND(__aarch64_ldset4_acq_rel) 137*dca69f4cSkettenis 138*dca69f4cSkettenisENTRY(__aarch64_swp4_acq_rel) 139*dca69f4cSkettenis RETGUARD_SETUP(__aarch64_swp4_acq_rel, x15) 140*dca69f4cSkettenis adrp x9, arm64_has_lse 141*dca69f4cSkettenis ldr w9, [x9, :lo12:arm64_has_lse] 142*dca69f4cSkettenis cbz w9, 1f 143*dca69f4cSkettenis swpal w0, w0, [x1] 144*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_swp4_acq_rel, x15) 145*dca69f4cSkettenis ret 146*dca69f4cSkettenis1: 147*dca69f4cSkettenis ldaxr w9, [x1] 148*dca69f4cSkettenis stlxr w10, w0, [x1] 149*dca69f4cSkettenis cbnz w10, 1b 150*dca69f4cSkettenis mov w0, w9 151*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_swp4_acq_rel, x15) 152*dca69f4cSkettenis ret 153*dca69f4cSkettenisEND(__aarch64_swp4_acq_rel) 154*dca69f4cSkettenis 155*dca69f4cSkettenisENTRY(__aarch64_swp8_acq_rel) 156*dca69f4cSkettenis RETGUARD_SETUP(__aarch64_swp8_acq_rel, x15) 157*dca69f4cSkettenis adrp x9, arm64_has_lse 158*dca69f4cSkettenis ldr w9, [x9, :lo12:arm64_has_lse] 159*dca69f4cSkettenis cbz w9, 1f 160*dca69f4cSkettenis swpal x0, x0, [x1] 161*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_swp8_acq_rel, x15) 162*dca69f4cSkettenis ret 163*dca69f4cSkettenis1: 164*dca69f4cSkettenis ldaxr x9, [x1] 165*dca69f4cSkettenis stlxr w10, x0, [x1] 166*dca69f4cSkettenis cbnz w10, 1b 167*dca69f4cSkettenis mov x0, x9 168*dca69f4cSkettenis RETGUARD_CHECK(__aarch64_swp8_acq_rel, x15) 169*dca69f4cSkettenis ret 170*dca69f4cSkettenisEND(__aarch64_swp8_acq_rel) 171