Text file src/internal/runtime/atomic/atomic_s390x.s

     1  // Copyright 2016 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  // func Store(ptr *uint32, val uint32)
     8  TEXT ·Store(SB), NOSPLIT, $0
     9  	MOVD	ptr+0(FP), R2
    10  	MOVWZ	val+8(FP), R3
    11  	MOVW	R3, 0(R2)
    12  	SYNC
    13  	RET
    14  
    15  // func Store8(ptr *uint8, val uint8)
    16  TEXT ·Store8(SB), NOSPLIT, $0
    17  	MOVD	ptr+0(FP), R2
    18  	MOVB	val+8(FP), R3
    19  	MOVB	R3, 0(R2)
    20  	SYNC
    21  	RET
    22  
    23  // func Store64(ptr *uint64, val uint64)
    24  TEXT ·Store64(SB), NOSPLIT, $0
    25  	MOVD	ptr+0(FP), R2
    26  	MOVD	val+8(FP), R3
    27  	MOVD	R3, 0(R2)
    28  	SYNC
    29  	RET
    30  
    31  // func StorepNoWB(ptr unsafe.Pointer, val unsafe.Pointer)
    32  TEXT ·StorepNoWB(SB), NOSPLIT, $0
    33  	MOVD	ptr+0(FP), R2
    34  	MOVD	val+8(FP), R3
    35  	MOVD	R3, 0(R2)
    36  	SYNC
    37  	RET
    38  
    39  // func Cas(ptr *uint32, old, new uint32) bool
    40  // Atomically:
    41  //	if *ptr == old {
    42  //		*val = new
    43  //		return 1
    44  //	} else {
    45  //		return 0
    46  //	}
    47  TEXT ·Cas(SB), NOSPLIT, $0-17
    48  	MOVD	ptr+0(FP), R3
    49  	MOVWZ	old+8(FP), R4
    50  	MOVWZ	new+12(FP), R5
    51  	CS	R4, R5, 0(R3)    //  if (R4 == 0(R3)) then 0(R3)= R5
    52  	BNE	cas_fail
    53  	MOVB	$1, ret+16(FP)
    54  	RET
    55  cas_fail:
    56  	MOVB	$0, ret+16(FP)
    57  	RET
    58  
    59  // func Cas64(ptr *uint64, old, new uint64) bool
    60  // Atomically:
    61  //	if *ptr == old {
    62  //		*ptr = new
    63  //		return 1
    64  //	} else {
    65  //		return 0
    66  //	}
    67  TEXT ·Cas64(SB), NOSPLIT, $0-25
    68  	MOVD	ptr+0(FP), R3
    69  	MOVD	old+8(FP), R4
    70  	MOVD	new+16(FP), R5
    71  	CSG	R4, R5, 0(R3)    //  if (R4 == 0(R3)) then 0(R3)= R5
    72  	BNE	cas64_fail
    73  	MOVB	$1, ret+24(FP)
    74  	RET
    75  cas64_fail:
    76  	MOVB	$0, ret+24(FP)
    77  	RET
    78  
    79  // func Casint32(ptr *int32, old, new int32) bool
    80  TEXT ·Casint32(SB), NOSPLIT, $0-17
    81  	BR	·Cas(SB)
    82  
    83  // func Casint64(ptr *int64, old, new int64) bool
    84  TEXT ·Casint64(SB), NOSPLIT, $0-25
    85  	BR	·Cas64(SB)
    86  
    87  // func Casuintptr(ptr *uintptr, old, new uintptr) bool
    88  TEXT ·Casuintptr(SB), NOSPLIT, $0-25
    89  	BR	·Cas64(SB)
    90  
    91  // func CasRel(ptr *uint32, old, new uint32) bool
    92  TEXT ·CasRel(SB), NOSPLIT, $0-17
    93  	BR	·Cas(SB)
    94  
    95  // func Loaduintptr(ptr *uintptr) uintptr
    96  TEXT ·Loaduintptr(SB), NOSPLIT, $0-16
    97  	BR	·Load64(SB)
    98  
    99  // func Loaduint(ptr *uint) uint
   100  TEXT ·Loaduint(SB), NOSPLIT, $0-16
   101  	BR	·Load64(SB)
   102  
   103  // func Storeint32(ptr *int32, new int32)
   104  TEXT ·Storeint32(SB), NOSPLIT, $0-12
   105  	BR	·Store(SB)
   106  
   107  // func Storeint64(ptr *int64, new int64)
   108  TEXT ·Storeint64(SB), NOSPLIT, $0-16
   109  	BR	·Store64(SB)
   110  
   111  // func Storeuintptr(ptr *uintptr, new uintptr)
   112  TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
   113  	BR	·Store64(SB)
   114  
   115  // func Loadint32(ptr *int32) int32
   116  TEXT ·Loadint32(SB), NOSPLIT, $0-12
   117  	BR	·Load(SB)
   118  
   119  // func Loadint64(ptr *int64) int64
   120  TEXT ·Loadint64(SB), NOSPLIT, $0-16
   121  	BR	·Load64(SB)
   122  
   123  // func Xadduintptr(ptr *uintptr, delta uintptr) uintptr
   124  TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
   125  	BR	·Xadd64(SB)
   126  
   127  // func Xaddint32(ptr *int32, delta int32) int32
   128  TEXT ·Xaddint32(SB), NOSPLIT, $0-20
   129  	BR	·Xadd(SB)
   130  
   131  // func Xaddint64(ptr *int64, delta int64) int64
   132  TEXT ·Xaddint64(SB), NOSPLIT, $0-24
   133  	BR	·Xadd64(SB)
   134  
   135  // func Casp1(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
   136  // Atomically:
   137  //	if *ptr == old {
   138  //		*ptr = new
   139  //		return 1
   140  //	} else {
   141  //		return 0
   142  //	}
   143  TEXT ·Casp1(SB), NOSPLIT, $0-25
   144  	BR ·Cas64(SB)
   145  
   146  // func Xadd(ptr *uint32, delta int32) uint32
   147  // Atomically:
   148  //	*ptr += delta
   149  //	return *ptr
   150  TEXT ·Xadd(SB), NOSPLIT, $0-20
   151  	MOVD	ptr+0(FP), R4
   152  	MOVW	delta+8(FP), R5
   153  	MOVW	(R4), R3
   154  repeat:
   155  	ADD	R5, R3, R6
   156  	CS	R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
   157  	BNE	repeat
   158  	MOVW	R6, ret+16(FP)
   159  	RET
   160  
   161  // func Xadd64(ptr *uint64, delta int64) uint64
   162  TEXT ·Xadd64(SB), NOSPLIT, $0-24
   163  	MOVD	ptr+0(FP), R4
   164  	MOVD	delta+8(FP), R5
   165  	MOVD	(R4), R3
   166  repeat:
   167  	ADD	R5, R3, R6
   168  	CSG	R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
   169  	BNE	repeat
   170  	MOVD	R6, ret+16(FP)
   171  	RET
   172  
   173  // func Xchg(ptr *uint32, new uint32) uint32
   174  TEXT ·Xchg(SB), NOSPLIT, $0-20
   175  	MOVD	ptr+0(FP), R4
   176  	MOVW	new+8(FP), R3
   177  	MOVW	(R4), R6
   178  repeat:
   179  	CS	R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4)
   180  	BNE	repeat
   181  	MOVW	R6, ret+16(FP)
   182  	RET
   183  
   184  // func Xchg64(ptr *uint64, new uint64) uint64
   185  TEXT ·Xchg64(SB), NOSPLIT, $0-24
   186  	MOVD	ptr+0(FP), R4
   187  	MOVD	new+8(FP), R3
   188  	MOVD	(R4), R6
   189  repeat:
   190  	CSG	R6, R3, (R4) // if R6==(R4) then (R4)=R3 else R6=(R4)
   191  	BNE	repeat
   192  	MOVD	R6, ret+16(FP)
   193  	RET
   194  
   195  // func Xchgint32(ptr *int32, new int32) int32
   196  TEXT ·Xchgint32(SB), NOSPLIT, $0-20
   197  	BR	·Xchg(SB)
   198  
   199  // func Xchgint64(ptr *int64, new int64) int64
   200  TEXT ·Xchgint64(SB), NOSPLIT, $0-24
   201  	BR	·Xchg64(SB)
   202  
   203  // func Xchguintptr(ptr *uintptr, new uintptr) uintptr
   204  TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
   205  	BR	·Xchg64(SB)
   206  
   207  // func Or8(addr *uint8, v uint8)
   208  TEXT ·Or8(SB), NOSPLIT, $0-9
   209  	MOVD	ptr+0(FP), R3
   210  	MOVBZ	val+8(FP), R4
   211  	// We don't have atomic operations that work on individual bytes so we
   212  	// need to align addr down to a word boundary and create a mask
   213  	// containing v to OR with the entire word atomically.
   214  	MOVD	$(3<<3), R5
   215  	RXSBG	$59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3)
   216  	ANDW	$~3, R3              // R3 = floor(addr, 4) = addr &^ 3
   217  	SLW	R5, R4               // R4 = uint32(v) << R5
   218  	LAO	R4, R6, 0(R3)        // R6 = *R3; *R3 |= R4; (atomic)
   219  	RET
   220  
   221  // func And8(addr *uint8, v uint8)
   222  TEXT ·And8(SB), NOSPLIT, $0-9
   223  	MOVD	ptr+0(FP), R3
   224  	MOVBZ	val+8(FP), R4
   225  	// We don't have atomic operations that work on individual bytes so we
   226  	// need to align addr down to a word boundary and create a mask
   227  	// containing v to AND with the entire word atomically.
   228  	ORW	$~0xff, R4           // R4 = uint32(v) | 0xffffff00
   229  	MOVD	$(3<<3), R5
   230  	RXSBG	$59, $60, $3, R3, R5 // R5 = 24 - ((addr % 4) * 8) = ((addr & 3) << 3) ^ (3 << 3)
   231  	ANDW	$~3, R3              // R3 = floor(addr, 4) = addr &^ 3
   232  	RLL	R5, R4, R4           // R4 = rotl(R4, R5)
   233  	LAN	R4, R6, 0(R3)        // R6 = *R3; *R3 &= R4; (atomic)
   234  	RET
   235  
   236  // func Or(addr *uint32, v uint32)
   237  TEXT ·Or(SB), NOSPLIT, $0-12
   238  	MOVD	ptr+0(FP), R3
   239  	MOVW	val+8(FP), R4
   240  	LAO	R4, R6, 0(R3)        // R6 = *R3; *R3 |= R4; (atomic)
   241  	RET
   242  
   243  // func And(addr *uint32, v uint32)
   244  TEXT ·And(SB), NOSPLIT, $0-12
   245  	MOVD	ptr+0(FP), R3
   246  	MOVW	val+8(FP), R4
   247  	LAN	R4, R6, 0(R3)        // R6 = *R3; *R3 &= R4; (atomic)
   248  	RET
   249  
   250  // func Or32(addr *uint32, v uint32) old uint32
   251  TEXT ·Or32(SB), NOSPLIT, $0-20
   252  	MOVD	ptr+0(FP), R4
   253  	MOVW	val+8(FP), R5
   254  	MOVW	(R4), R3
   255  repeat:
   256  	OR	R5, R3, R6
   257  	CS	R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
   258  	BNE	repeat
   259  	MOVW	R3, ret+16(FP)
   260  	RET
   261  
   262  // func And32(addr *uint32, v uint32) old uint32
   263  TEXT ·And32(SB), NOSPLIT, $0-20
   264  	MOVD	ptr+0(FP), R4
   265  	MOVW	val+8(FP), R5
   266  	MOVW	(R4), R3
   267  repeat:
   268  	AND	R5, R3, R6
   269  	CS	R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
   270  	BNE	repeat
   271  	MOVW	R3, ret+16(FP)
   272  	RET
   273  
   274  // func Or64(addr *uint64, v uint64) old uint64
   275  TEXT ·Or64(SB), NOSPLIT, $0-24
   276  	MOVD	ptr+0(FP), R4
   277  	MOVD	val+8(FP), R5
   278  	MOVD	(R4), R3
   279  repeat:
   280  	OR	R5, R3, R6
   281  	CSG	R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
   282  	BNE	repeat
   283  	MOVD	R3, ret+16(FP)
   284  	RET
   285  
   286  // func And64(addr *uint64, v uint64) old uint64
   287  TEXT ·And64(SB), NOSPLIT, $0-24
   288  	MOVD	ptr+0(FP), R4
   289  	MOVD	val+8(FP), R5
   290  	MOVD	(R4), R3
   291  repeat:
   292  	AND	R5, R3, R6
   293  	CSG	R3, R6, (R4) // if R3==(R4) then (R4)=R6 else R3=(R4)
   294  	BNE	repeat
   295  	MOVD	R3, ret+16(FP)
   296  	RET
   297  
   298  // func Anduintptr(addr *uintptr, v uintptr) old uintptr
   299  TEXT ·Anduintptr(SB), NOSPLIT, $0-24
   300  	BR	·And64(SB)
   301  
   302  // func Oruintptr(addr *uintptr, v uintptr) old uintptr
   303  TEXT ·Oruintptr(SB), NOSPLIT, $0-24
   304  	BR	·Or64(SB)
   305  

View as plain text