gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/safecopy/atomic_arm64.s (about)

     1  // Copyright 2014 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  #include "textflag.h"
     6  
     7  // handleSwapUint32Fault returns the value stored in R1. Control is transferred
     8  // to it when swapUint32 below receives SIGSEGV or SIGBUS, with the signal
     9  // number stored in R1.
    10  //
    11  // It must have the same frame configuration as swapUint32 so that it can undo
    12  // any potential call frame set up by the assembler.
    13  TEXT handleSwapUint32Fault(SB), NOSPLIT, $0-24
    14  	MOVW R1, sig+20(FP)
    15  	RET
    16  
    17  // See the corresponding doc in safecopy_unsafe.go
    18  //
    19  // The code is derived from Go source runtime/internal/atomic.Xchg.
    20  //
    21  //func swapUint32(ptr unsafe.Pointer, new uint32) (old uint32, sig int32)
    22  TEXT ·swapUint32(SB), NOSPLIT, $0-24
    23  	// Store 0 as the returned signal number. If we run to completion,
    24  	// this is the value the caller will see; if a signal is received,
    25  	// handleSwapUint32Fault will store a different value in this address.
    26  	MOVW $0, sig+20(FP)
    27  again:
    28  	MOVD ptr+0(FP), R0
    29  	MOVW new+8(FP), R1
    30  	LDAXRW (R0), R2
    31  	STLXRW R1, (R0), R3
    32  	CBNZ R3, again
    33  	MOVW R2, old+16(FP)
    34  	RET
    35  
    36  // func addrOfSwapUint32() uintptr
    37  TEXT ·addrOfSwapUint32(SB), $0-8
    38  	MOVD	$·swapUint32(SB), R0
    39  	MOVD	R0, ret+0(FP)
    40  	RET
    41  
    42  // handleSwapUint64Fault returns the value stored in R1. Control is transferred
    43  // to it when swapUint64 below receives SIGSEGV or SIGBUS, with the signal
    44  // number stored in R1.
    45  //
    46  // It must have the same frame configuration as swapUint64 so that it can undo
    47  // any potential call frame set up by the assembler.
    48  TEXT handleSwapUint64Fault(SB), NOSPLIT, $0-28
    49  	MOVW R1, sig+24(FP)
    50  	RET
    51  
    52  // See the corresponding doc in safecopy_unsafe.go
    53  //
    54  // The code is derived from Go source runtime/internal/atomic.Xchg64.
    55  //
    56  //func swapUint64(ptr unsafe.Pointer, new uint64) (old uint64, sig int32)
    57  TEXT ·swapUint64(SB), NOSPLIT, $0-28
    58  	// Store 0 as the returned signal number. If we run to completion,
    59  	// this is the value the caller will see; if a signal is received,
    60  	// handleSwapUint64Fault will store a different value in this address.
    61  	MOVW $0, sig+24(FP)
    62  again:
    63  	MOVD ptr+0(FP), R0
    64  	MOVD new+8(FP), R1
    65  	LDAXR (R0), R2
    66  	STLXR R1, (R0), R3
    67  	CBNZ R3, again
    68  	MOVD R2, old+16(FP)
    69  	RET
    70  
    71  // func addrOfSwapUint64() uintptr
    72  TEXT ·addrOfSwapUint64(SB), $0-8
    73  	MOVD	$·swapUint64(SB), R0
    74  	MOVD	R0, ret+0(FP)
    75  	RET
    76  
    77  // handleCompareAndSwapUint32Fault returns the value stored in R1. Control is
    78  // transferred to it when compareAndSwapUint32 below receives SIGSEGV or SIGBUS,
    79  // with the signal number stored in R1.
    80  //
    81  // It must have the same frame configuration as compareAndSwapUint32 so that it
    82  // can undo any potential call frame set up by the assembler.
    83  TEXT handleCompareAndSwapUint32Fault(SB), NOSPLIT, $0-24
    84  	MOVW R1, sig+20(FP)
    85  	RET
    86  
    87  // See the corresponding doc in safecopy_unsafe.go
    88  //
    89  // The code is derived from Go source runtime/internal/atomic.Cas.
    90  //
    91  //func compareAndSwapUint32(ptr unsafe.Pointer, old, new uint32) (prev uint32, sig int32)
    92  TEXT ·compareAndSwapUint32(SB), NOSPLIT, $0-24
    93  	// Store 0 as the returned signal number. If we run to completion, this is
    94  	// the value the caller will see; if a signal is received,
    95  	// handleCompareAndSwapUint32Fault will store a different value in this
    96  	// address.
    97  	MOVW $0, sig+20(FP)
    98  
    99  	MOVD ptr+0(FP), R0
   100  	MOVW old+8(FP), R1
   101  	MOVW new+12(FP), R2
   102  again:
   103  	LDAXRW (R0), R3
   104  	CMPW R1, R3
   105  	BNE done
   106  	STLXRW R2, (R0), R4
   107  	CBNZ R4, again
   108  done:
   109  	MOVW R3, prev+16(FP)
   110  	RET
   111  
   112  // func addrOfCompareAndSwapUint32() uintptr
   113  TEXT ·addrOfCompareAndSwapUint32(SB), $0-8
   114  	MOVD	$·compareAndSwapUint32(SB), R0
   115  	MOVD	R0, ret+0(FP)
   116  	RET
   117  
   118  // handleLoadUint32Fault returns the value stored in DI. Control is transferred
   119  // to it when LoadUint32 below receives SIGSEGV or SIGBUS, with the signal
   120  // number stored in DI.
   121  //
   122  // It must have the same frame configuration as loadUint32 so that it can undo
   123  // any potential call frame set up by the assembler.
   124  TEXT handleLoadUint32Fault(SB), NOSPLIT, $0-16
   125  	MOVW R1, sig+12(FP)
   126  	RET
   127  
   128  // loadUint32 atomically loads *ptr and returns it. If a SIGSEGV or SIGBUS
   129  // signal is received, the value returned is unspecified, and sig is the number
   130  // of the signal that was received.
   131  //
   132  // Preconditions: ptr must be aligned to a 4-byte boundary.
   133  //
   134  //func loadUint32(ptr unsafe.Pointer) (val uint32, sig int32)
   135  TEXT ·loadUint32(SB), NOSPLIT, $0-16
   136  	// Store 0 as the returned signal number. If we run to completion,
   137  	// this is the value the caller will see; if a signal is received,
   138  	// handleLoadUint32Fault will store a different value in this address.
   139  	MOVW $0, sig+12(FP)
   140  
   141  	MOVD ptr+0(FP), R0
   142  	LDARW (R0), R1
   143  	MOVW R1, val+8(FP)
   144  	RET
   145  
   146  // func addrOfLoadUint32() uintptr
   147  TEXT ·addrOfLoadUint32(SB), $0-8
   148  	MOVD	$·loadUint32(SB), R0
   149  	MOVD	R0, ret+0(FP)
   150  	RET