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

     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 "go_asm.h"
     6  #include "textflag.h"
     7  
     8  TEXT ·Casint32(SB), NOSPLIT, $0-17
     9  	B	·Cas(SB)
    10  
    11  TEXT ·Casint64(SB), NOSPLIT, $0-25
    12  	B	·Cas64(SB)
    13  
    14  TEXT ·Casuintptr(SB), NOSPLIT, $0-25
    15  	B	·Cas64(SB)
    16  
    17  TEXT ·CasRel(SB), NOSPLIT, $0-17
    18  	B	·Cas(SB)
    19  
    20  TEXT ·Loadint32(SB), NOSPLIT, $0-12
    21  	B	·Load(SB)
    22  
    23  TEXT ·Loadint64(SB), NOSPLIT, $0-16
    24  	B	·Load64(SB)
    25  
    26  TEXT ·Loaduintptr(SB), NOSPLIT, $0-16
    27  	B	·Load64(SB)
    28  
    29  TEXT ·Loaduint(SB), NOSPLIT, $0-16
    30  	B	·Load64(SB)
    31  
    32  TEXT ·Storeint32(SB), NOSPLIT, $0-12
    33  	B	·Store(SB)
    34  
    35  TEXT ·Storeint64(SB), NOSPLIT, $0-16
    36  	B	·Store64(SB)
    37  
    38  TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
    39  	B	·Store64(SB)
    40  
    41  TEXT ·Xaddint32(SB), NOSPLIT, $0-20
    42  	B	·Xadd(SB)
    43  
    44  TEXT ·Xaddint64(SB), NOSPLIT, $0-24
    45  	B	·Xadd64(SB)
    46  
    47  TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
    48  	B	·Xadd64(SB)
    49  
    50  TEXT ·Casp1(SB), NOSPLIT, $0-25
    51  	B ·Cas64(SB)
    52  
    53  // uint32 ·Load(uint32 volatile* addr)
    54  TEXT ·Load(SB),NOSPLIT,$0-12
    55  	MOVD	ptr+0(FP), R0
    56  	LDARW	(R0), R0
    57  	MOVW	R0, ret+8(FP)
    58  	RET
    59  
    60  // uint8 ·Load8(uint8 volatile* addr)
    61  TEXT ·Load8(SB),NOSPLIT,$0-9
    62  	MOVD	ptr+0(FP), R0
    63  	LDARB	(R0), R0
    64  	MOVB	R0, ret+8(FP)
    65  	RET
    66  
    67  // uint64 ·Load64(uint64 volatile* addr)
    68  TEXT ·Load64(SB),NOSPLIT,$0-16
    69  	MOVD	ptr+0(FP), R0
    70  	LDAR	(R0), R0
    71  	MOVD	R0, ret+8(FP)
    72  	RET
    73  
    74  // void *·Loadp(void *volatile *addr)
    75  TEXT ·Loadp(SB),NOSPLIT,$0-16
    76  	MOVD	ptr+0(FP), R0
    77  	LDAR	(R0), R0
    78  	MOVD	R0, ret+8(FP)
    79  	RET
    80  
    81  // uint32 ·LoadAcq(uint32 volatile* addr)
    82  TEXT ·LoadAcq(SB),NOSPLIT,$0-12
    83  	B	·Load(SB)
    84  
    85  // uint64 ·LoadAcquintptr(uint64 volatile* addr)
    86  TEXT ·LoadAcq64(SB),NOSPLIT,$0-16
    87  	B	·Load64(SB)
    88  
    89  // uintptr ·LoadAcq64(uintptr volatile* addr)
    90  TEXT ·LoadAcquintptr(SB),NOSPLIT,$0-16
    91  	B	·Load64(SB)
    92  
    93  TEXT ·StorepNoWB(SB), NOSPLIT, $0-16
    94  	B	·Store64(SB)
    95  
    96  TEXT ·StoreRel(SB), NOSPLIT, $0-12
    97  	B	·Store(SB)
    98  
    99  TEXT ·StoreRel64(SB), NOSPLIT, $0-16
   100  	B	·Store64(SB)
   101  
   102  TEXT ·StoreReluintptr(SB), NOSPLIT, $0-16
   103  	B	·Store64(SB)
   104  
   105  TEXT ·Store(SB), NOSPLIT, $0-12
   106  	MOVD	ptr+0(FP), R0
   107  	MOVW	val+8(FP), R1
   108  	STLRW	R1, (R0)
   109  	RET
   110  
   111  TEXT ·Store8(SB), NOSPLIT, $0-9
   112  	MOVD	ptr+0(FP), R0
   113  	MOVB	val+8(FP), R1
   114  	STLRB	R1, (R0)
   115  	RET
   116  
   117  TEXT ·Store64(SB), NOSPLIT, $0-16
   118  	MOVD	ptr+0(FP), R0
   119  	MOVD	val+8(FP), R1
   120  	STLR	R1, (R0)
   121  	RET
   122  
   123  // uint8 Xchg(ptr *uint8, new uint8)
   124  // Atomically:
   125  //	old := *ptr;
   126  //	*ptr = new;
   127  //	return old;
   128  TEXT ·Xchg8(SB), NOSPLIT, $0-17
   129  	MOVD	ptr+0(FP), R0
   130  	MOVB	new+8(FP), R1
   131  #ifndef GOARM64_LSE
   132  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   133  	CBZ 	R4, load_store_loop
   134  #endif
   135  	SWPALB	R1, (R0), R2
   136  	MOVB	R2, ret+16(FP)
   137  	RET
   138  #ifndef GOARM64_LSE
   139  load_store_loop:
   140  	LDAXRB	(R0), R2
   141  	STLXRB	R1, (R0), R3
   142  	CBNZ	R3, load_store_loop
   143  	MOVB	R2, ret+16(FP)
   144  	RET
   145  #endif
   146  
   147  // uint32 Xchg(ptr *uint32, new uint32)
   148  // Atomically:
   149  //	old := *ptr;
   150  //	*ptr = new;
   151  //	return old;
   152  TEXT ·Xchg(SB), NOSPLIT, $0-20
   153  	MOVD	ptr+0(FP), R0
   154  	MOVW	new+8(FP), R1
   155  #ifndef GOARM64_LSE
   156  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   157  	CBZ 	R4, load_store_loop
   158  #endif
   159  	SWPALW	R1, (R0), R2
   160  	MOVW	R2, ret+16(FP)
   161  	RET
   162  #ifndef GOARM64_LSE
   163  load_store_loop:
   164  	LDAXRW	(R0), R2
   165  	STLXRW	R1, (R0), R3
   166  	CBNZ	R3, load_store_loop
   167  	MOVW	R2, ret+16(FP)
   168  	RET
   169  #endif
   170  
   171  // uint64 Xchg64(ptr *uint64, new uint64)
   172  // Atomically:
   173  //	old := *ptr;
   174  //	*ptr = new;
   175  //	return old;
   176  TEXT ·Xchg64(SB), NOSPLIT, $0-24
   177  	MOVD	ptr+0(FP), R0
   178  	MOVD	new+8(FP), R1
   179  #ifndef GOARM64_LSE
   180  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   181  	CBZ 	R4, load_store_loop
   182  #endif
   183  	SWPALD	R1, (R0), R2
   184  	MOVD	R2, ret+16(FP)
   185  	RET
   186  #ifndef GOARM64_LSE
   187  load_store_loop:
   188  	LDAXR	(R0), R2
   189  	STLXR	R1, (R0), R3
   190  	CBNZ	R3, load_store_loop
   191  	MOVD	R2, ret+16(FP)
   192  	RET
   193  #endif
   194  
   195  // func Cas(ptr *uint32, old, new uint32) bool
   196  // Atomically:
   197  //	if *ptr == old {
   198  //		*ptr = new
   199  //		return true
   200  //	} else {
   201  //		return false
   202  // 	}
   203  TEXT ·Cas(SB), NOSPLIT, $0-17
   204  	MOVD	ptr+0(FP), R0
   205  	MOVW	old+8(FP), R1
   206  	MOVW	new+12(FP), R2
   207  #ifndef GOARM64_LSE
   208  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   209  	CBZ 	R4, load_store_loop
   210  #endif
   211  	MOVD	R1, R3
   212  	CASALW	R3, (R0), R2
   213  	CMP 	R1, R3
   214  	CSET	EQ, R0
   215  	MOVB	R0, ret+16(FP)
   216  	RET
   217  #ifndef GOARM64_LSE
   218  load_store_loop:
   219  	LDAXRW	(R0), R3
   220  	CMPW	R1, R3
   221  	BNE	ok
   222  	STLXRW	R2, (R0), R3
   223  	CBNZ	R3, load_store_loop
   224  ok:
   225  	CSET	EQ, R0
   226  	MOVB	R0, ret+16(FP)
   227  	RET
   228  #endif
   229  
   230  // func Cas64(ptr *uint64, old, new uint64) bool
   231  // Atomically:
   232  //	if *ptr == old {
   233  //		*ptr = new
   234  //		return true
   235  //	} else {
   236  //		return false
   237  //	}
   238  TEXT ·Cas64(SB), NOSPLIT, $0-25
   239  	MOVD	ptr+0(FP), R0
   240  	MOVD	old+8(FP), R1
   241  	MOVD	new+16(FP), R2
   242  #ifndef GOARM64_LSE
   243  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   244  	CBZ 	R4, load_store_loop
   245  #endif
   246  	MOVD	R1, R3
   247  	CASALD	R3, (R0), R2
   248  	CMP 	R1, R3
   249  	CSET	EQ, R0
   250  	MOVB	R0, ret+24(FP)
   251  	RET
   252  #ifndef GOARM64_LSE
   253  load_store_loop:
   254  	LDAXR	(R0), R3
   255  	CMP	R1, R3
   256  	BNE	ok
   257  	STLXR	R2, (R0), R3
   258  	CBNZ	R3, load_store_loop
   259  ok:
   260  	CSET	EQ, R0
   261  	MOVB	R0, ret+24(FP)
   262  	RET
   263  #endif
   264  
   265  // uint32 xadd(uint32 volatile *ptr, int32 delta)
   266  // Atomically:
   267  //      *val += delta;
   268  //      return *val;
   269  TEXT ·Xadd(SB), NOSPLIT, $0-20
   270  	MOVD	ptr+0(FP), R0
   271  	MOVW	delta+8(FP), R1
   272  #ifndef GOARM64_LSE
   273  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   274  	CBZ 	R4, load_store_loop
   275  #endif
   276  	LDADDALW	R1, (R0), R2
   277  	ADD 	R1, R2
   278  	MOVW	R2, ret+16(FP)
   279  	RET
   280  #ifndef GOARM64_LSE
   281  load_store_loop:
   282  	LDAXRW	(R0), R2
   283  	ADDW	R2, R1, R2
   284  	STLXRW	R2, (R0), R3
   285  	CBNZ	R3, load_store_loop
   286  	MOVW	R2, ret+16(FP)
   287  	RET
   288  #endif
   289  
   290  // uint64 Xadd64(uint64 volatile *ptr, int64 delta)
   291  // Atomically:
   292  //      *val += delta;
   293  //      return *val;
   294  TEXT ·Xadd64(SB), NOSPLIT, $0-24
   295  	MOVD	ptr+0(FP), R0
   296  	MOVD	delta+8(FP), R1
   297  #ifndef GOARM64_LSE
   298  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   299  	CBZ 	R4, load_store_loop
   300  #endif
   301  	LDADDALD	R1, (R0), R2
   302  	ADD 	R1, R2
   303  	MOVD	R2, ret+16(FP)
   304  	RET
   305  #ifndef GOARM64_LSE
   306  load_store_loop:
   307  	LDAXR	(R0), R2
   308  	ADD	R2, R1, R2
   309  	STLXR	R2, (R0), R3
   310  	CBNZ	R3, load_store_loop
   311  	MOVD	R2, ret+16(FP)
   312  	RET
   313  #endif
   314  
   315  TEXT ·Xchgint32(SB), NOSPLIT, $0-20
   316  	B	·Xchg(SB)
   317  
   318  TEXT ·Xchgint64(SB), NOSPLIT, $0-24
   319  	B	·Xchg64(SB)
   320  
   321  TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
   322  	B	·Xchg64(SB)
   323  
   324  TEXT ·And8(SB), NOSPLIT, $0-9
   325  	MOVD	ptr+0(FP), R0
   326  	MOVB	val+8(FP), R1
   327  #ifndef GOARM64_LSE
   328  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   329  	CBZ 	R4, load_store_loop
   330  #endif
   331  	MVN 	R1, R2
   332  	LDCLRALB	R2, (R0), R3
   333  	RET
   334  #ifndef GOARM64_LSE
   335  load_store_loop:
   336  	LDAXRB	(R0), R2
   337  	AND	R1, R2
   338  	STLXRB	R2, (R0), R3
   339  	CBNZ	R3, load_store_loop
   340  	RET
   341  #endif
   342  
   343  TEXT ·Or8(SB), NOSPLIT, $0-9
   344  	MOVD	ptr+0(FP), R0
   345  	MOVB	val+8(FP), R1
   346  #ifndef GOARM64_LSE
   347  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   348  	CBZ 	R4, load_store_loop
   349  #endif
   350  	LDORALB	R1, (R0), R2
   351  	RET
   352  #ifndef GOARM64_LSE
   353  load_store_loop:
   354  	LDAXRB	(R0), R2
   355  	ORR	R1, R2
   356  	STLXRB	R2, (R0), R3
   357  	CBNZ	R3, load_store_loop
   358  	RET
   359  #endif
   360  
   361  // func And(addr *uint32, v uint32)
   362  TEXT ·And(SB), NOSPLIT, $0-12
   363  	MOVD	ptr+0(FP), R0
   364  	MOVW	val+8(FP), R1
   365  #ifndef GOARM64_LSE
   366  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   367  	CBZ 	R4, load_store_loop
   368  #endif
   369  	MVN 	R1, R2
   370  	LDCLRALW	R2, (R0), R3
   371  	RET
   372  #ifndef GOARM64_LSE
   373  load_store_loop:
   374  	LDAXRW	(R0), R2
   375  	AND	R1, R2
   376  	STLXRW	R2, (R0), R3
   377  	CBNZ	R3, load_store_loop
   378  	RET
   379  #endif
   380  
   381  // func Or(addr *uint32, v uint32)
   382  TEXT ·Or(SB), NOSPLIT, $0-12
   383  	MOVD	ptr+0(FP), R0
   384  	MOVW	val+8(FP), R1
   385  #ifndef GOARM64_LSE
   386  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   387  	CBZ 	R4, load_store_loop
   388  #endif
   389  	LDORALW	R1, (R0), R2
   390  	RET
   391  #ifndef GOARM64_LSE
   392  load_store_loop:
   393  	LDAXRW	(R0), R2
   394  	ORR	R1, R2
   395  	STLXRW	R2, (R0), R3
   396  	CBNZ	R3, load_store_loop
   397  	RET
   398  #endif
   399  
   400  // func Or32(addr *uint32, v uint32) old uint32
   401  TEXT ·Or32(SB), NOSPLIT, $0-20
   402  	MOVD	ptr+0(FP), R0
   403  	MOVW	val+8(FP), R1
   404  #ifndef GOARM64_LSE
   405  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   406  	CBZ 	R4, load_store_loop
   407  #endif
   408  	LDORALW	R1, (R0), R2
   409  	MOVD	R2, ret+16(FP)
   410  	RET
   411  #ifndef GOARM64_LSE
   412  load_store_loop:
   413  	LDAXRW	(R0), R2
   414  	ORR	R1, R2, R3
   415  	STLXRW	R3, (R0), R4
   416  	CBNZ	R4, load_store_loop
   417  	MOVD R2, ret+16(FP)
   418  	RET
   419  #endif
   420  
   421  // func And32(addr *uint32, v uint32) old uint32
   422  TEXT ·And32(SB), NOSPLIT, $0-20
   423  	MOVD	ptr+0(FP), R0
   424  	MOVW	val+8(FP), R1
   425  #ifndef GOARM64_LSE
   426  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   427  	CBZ 	R4, load_store_loop
   428  #endif
   429  	MVN 	R1, R2
   430  	LDCLRALW	R2, (R0), R3
   431  	MOVD	R3, ret+16(FP)
   432  	RET
   433  #ifndef GOARM64_LSE
   434  load_store_loop:
   435  	LDAXRW	(R0), R2
   436  	AND	R1, R2, R3
   437  	STLXRW	R3, (R0), R4
   438  	CBNZ	R4, load_store_loop
   439  	MOVD R2, ret+16(FP)
   440  	RET
   441  #endif
   442  
   443  // func Or64(addr *uint64, v uint64) old uint64
   444  TEXT ·Or64(SB), NOSPLIT, $0-24
   445  	MOVD	ptr+0(FP), R0
   446  	MOVD	val+8(FP), R1
   447  #ifndef GOARM64_LSE
   448  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   449  	CBZ 	R4, load_store_loop
   450  #endif
   451  	LDORALD	R1, (R0), R2
   452  	MOVD	R2, ret+16(FP)
   453  	RET
   454  #ifndef GOARM64_LSE
   455  load_store_loop:
   456  	LDAXR	(R0), R2
   457  	ORR	R1, R2, R3
   458  	STLXR	R3, (R0), R4
   459  	CBNZ	R4, load_store_loop
   460  	MOVD 	R2, ret+16(FP)
   461  	RET
   462  #endif
   463  
   464  // func And64(addr *uint64, v uint64) old uint64
   465  TEXT ·And64(SB), NOSPLIT, $0-24
   466  	MOVD	ptr+0(FP), R0
   467  	MOVD	val+8(FP), R1
   468  #ifndef GOARM64_LSE
   469  	MOVBU	internal∕cpu·ARM64+const_offsetARM64HasATOMICS(SB), R4
   470  	CBZ 	R4, load_store_loop
   471  #endif
   472  	MVN 	R1, R2
   473  	LDCLRALD	R2, (R0), R3
   474  	MOVD	R3, ret+16(FP)
   475  	RET
   476  #ifndef GOARM64_LSE
   477  load_store_loop:
   478  	LDAXR	(R0), R2
   479  	AND	R1, R2, R3
   480  	STLXR	R3, (R0), R4
   481  	CBNZ	R4, load_store_loop
   482  	MOVD 	R2, ret+16(FP)
   483  	RET
   484  #endif
   485  
   486  // func Anduintptr(addr *uintptr, v uintptr) old uintptr
   487  TEXT ·Anduintptr(SB), NOSPLIT, $0-24
   488  	B	·And64(SB)
   489  
   490  // func Oruintptr(addr *uintptr, v uintptr) old uintptr
   491  TEXT ·Oruintptr(SB), NOSPLIT, $0-24
   492  	B	·Or64(SB)
   493  

View as plain text