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

     1  // Copyright 2022 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  // func Cas(ptr *int32, old, new int32) bool
     9  // Atomically:
    10  //	if *ptr == old {
    11  //		*ptr = new
    12  //		return true
    13  //	} else {
    14  //		return false
    15  //	}
    16  TEXT ·Cas(SB), NOSPLIT, $0-17
    17  	MOVV	ptr+0(FP), R4
    18  	MOVW	old+8(FP), R5
    19  	MOVW	new+12(FP), R6
    20  
    21  	MOVBU	internal∕cpu·Loong64+const_offsetLOONG64HasLAMCAS(SB), R8
    22  	BEQ	R8, cas_again
    23  	MOVV	R5, R7  // backup old value
    24  	AMCASDBW	R6, (R4), R5
    25  	BNE	R7, R5, cas_fail0
    26  	MOVV	$1, R4
    27  	MOVB	R4, ret+16(FP)
    28  	RET
    29  cas_fail0:
    30  	MOVB	R0, ret+16(FP)
    31  	RET
    32  
    33  	// Implemented using the ll-sc instruction pair
    34  	DBAR	$0x14	// LoadAcquire barrier
    35  cas_again:
    36  	MOVV	R6, R7
    37  	LL	(R4), R8
    38  	BNE	R5, R8, cas_fail1
    39  	SC	R7, (R4)
    40  	BEQ	R7, cas_again
    41  	MOVV	$1, R4
    42  	MOVB	R4, ret+16(FP)
    43  	DBAR	$0x12	// StoreRelease barrier
    44  	RET
    45  cas_fail1:
    46  	MOVV	$0, R4
    47  	JMP	-4(PC)
    48  
    49  // func Cas64(ptr *uint64, old, new uint64) bool
    50  // Atomically:
    51  //	if *ptr == old {
    52  //		*ptr = new
    53  //		return true
    54  //	} else {
    55  //		return false
    56  //	}
    57  TEXT ·Cas64(SB), NOSPLIT, $0-25
    58  	MOVV	ptr+0(FP), R4
    59  	MOVV	old+8(FP), R5
    60  	MOVV	new+16(FP), R6
    61  
    62  	MOVBU	internal∕cpu·Loong64+const_offsetLOONG64HasLAMCAS(SB), R8
    63  	BEQ	R8, cas64_again
    64  	MOVV	R5, R7  // backup old value
    65  	AMCASDBV	R6, (R4), R5
    66  	BNE	R7, R5, cas64_fail0
    67  	MOVV	$1, R4
    68  	MOVB	R4, ret+24(FP)
    69  	RET
    70  cas64_fail0:
    71  	MOVB	R0, ret+24(FP)
    72  	RET
    73  
    74  	// Implemented using the ll-sc instruction pair
    75  	DBAR	$0x14
    76  cas64_again:
    77  	MOVV	R6, R7
    78  	LLV	(R4), R8
    79  	BNE	R5, R8, cas64_fail1
    80  	SCV	R7, (R4)
    81  	BEQ	R7, cas64_again
    82  	MOVV	$1, R4
    83  	MOVB	R4, ret+24(FP)
    84  	DBAR	$0x12
    85  	RET
    86  cas64_fail1:
    87  	MOVV	$0, R4
    88  	JMP	-4(PC)
    89  
    90  TEXT ·Casint32(SB),NOSPLIT,$0-17
    91  	JMP	·Cas(SB)
    92  
    93  TEXT ·Casint64(SB),NOSPLIT,$0-25
    94  	JMP	·Cas64(SB)
    95  
    96  TEXT ·Casuintptr(SB), NOSPLIT, $0-25
    97  	JMP	·Cas64(SB)
    98  
    99  TEXT ·CasRel(SB), NOSPLIT, $0-17
   100  	JMP	·Cas(SB)
   101  
   102  TEXT ·Loaduintptr(SB),  NOSPLIT|NOFRAME, $0-16
   103  	JMP	·Load64(SB)
   104  
   105  TEXT ·Loaduint(SB), NOSPLIT|NOFRAME, $0-16
   106  	JMP	·Load64(SB)
   107  
   108  TEXT ·Storeuintptr(SB), NOSPLIT, $0-16
   109  	JMP	·Store64(SB)
   110  
   111  TEXT ·Xadduintptr(SB), NOSPLIT, $0-24
   112  	JMP	·Xadd64(SB)
   113  
   114  TEXT ·Loadint64(SB), NOSPLIT, $0-16
   115  	JMP	·Load64(SB)
   116  
   117  TEXT ·Xaddint32(SB),NOSPLIT,$0-20
   118  	JMP	·Xadd(SB)
   119  
   120  TEXT ·Xaddint64(SB), NOSPLIT, $0-24
   121  	JMP	·Xadd64(SB)
   122  
   123  // func Casp(ptr *unsafe.Pointer, old, new unsafe.Pointer) bool
   124  // Atomically:
   125  //	if *ptr == old {
   126  //		*ptr = new
   127  //		return true
   128  //	} else {
   129  //		return false
   130  //	}
   131  TEXT ·Casp1(SB), NOSPLIT, $0-25
   132  	JMP	·Cas64(SB)
   133  
   134  // uint32 Xadd(uint32 volatile *ptr, int32 delta)
   135  // Atomically:
   136  //	*val += delta;
   137  //	return *val;
   138  TEXT ·Xadd(SB), NOSPLIT, $0-20
   139  	MOVV	ptr+0(FP), R4
   140  	MOVW	delta+8(FP), R5
   141  	AMADDDBW	R5, (R4), R6
   142  	ADDV	R6, R5, R4
   143  	MOVW	R4, ret+16(FP)
   144  	RET
   145  
   146  // func Xadd64(ptr *uint64, delta int64) uint64
   147  TEXT ·Xadd64(SB), NOSPLIT, $0-24
   148  	MOVV	ptr+0(FP), R4
   149  	MOVV	delta+8(FP), R5
   150  	AMADDDBV	R5, (R4), R6
   151  	ADDV	R6, R5, R4
   152  	MOVV	R4, ret+16(FP)
   153  	RET
   154  
   155  // uint8 Xchg8(ptr *uint8, new uint8)
   156  // Atomically:
   157  //     old := *ptr;
   158  //     *ptr = new;
   159  //     return old;
   160  TEXT ·Xchg8(SB), NOSPLIT, $0-17
   161  	MOVV	ptr+0(FP), R4
   162  	MOVBU	new+8(FP), R5
   163  
   164  	// R6 = ((ptr & 3) * 8)
   165  	AND	$3, R4, R6
   166  	SLLV	$3, R6
   167  
   168  	// R7 = ((0xFF) << R6) ^ (-1)
   169  	MOVV	$0xFF, R8
   170  	SLLV	R6, R8, R7
   171  	XOR	$-1, R7
   172  
   173  	// R4 = ptr & (~3)
   174  	MOVV	$~3, R8
   175  	AND	R8, R4
   176  
   177  	// R5 = ((val) << R6)
   178  	SLLV	R6, R5
   179  
   180  	DBAR	$0x14	// LoadAcquire barrier
   181  _xchg8_again:
   182  	LL	(R4), R8
   183  	MOVV	R8, R9	// backup old val
   184  	AND	R7, R8
   185  	OR	R5, R8
   186  	SC	R8, (R4)
   187  	BEQ	R8, _xchg8_again
   188  	DBAR	$0x12	// StoreRelease barrier
   189  	SRLV	R6, R9, R9
   190  	MOVBU	R9, ret+16(FP)
   191  	RET
   192  
   193  // func Xchg(ptr *uint32, new uint32) uint32
   194  TEXT ·Xchg(SB), NOSPLIT, $0-20
   195  	MOVV	ptr+0(FP), R4
   196  	MOVW	new+8(FP), R5
   197  	AMSWAPDBW	R5, (R4), R6
   198  	MOVW	R6, ret+16(FP)
   199  	RET
   200  
   201  // func Xchg64(ptr *uint64, new uint64) uint64
   202  TEXT ·Xchg64(SB), NOSPLIT, $0-24
   203  	MOVV	ptr+0(FP), R4
   204  	MOVV	new+8(FP), R5
   205  	AMSWAPDBV	R5, (R4), R6
   206  	MOVV	R6, ret+16(FP)
   207  	RET
   208  
   209  TEXT ·Xchguintptr(SB), NOSPLIT, $0-24
   210  	JMP	·Xchg64(SB)
   211  
   212  // func Xchgint32(ptr *int32, new int32) int32
   213  TEXT ·Xchgint32(SB), NOSPLIT, $0-20
   214  	JMP	·Xchg(SB)
   215  
   216  // func Xchgint64(ptr *int64, new int64) int64
   217  TEXT ·Xchgint64(SB), NOSPLIT, $0-24
   218  	JMP	·Xchg64(SB)
   219  
   220  TEXT ·StorepNoWB(SB), NOSPLIT, $0-16
   221  	JMP	·Store64(SB)
   222  
   223  TEXT ·StoreRel(SB), NOSPLIT, $0-12
   224  	JMP	·Store(SB)
   225  
   226  TEXT ·StoreRel64(SB), NOSPLIT, $0-16
   227  	JMP	·Store64(SB)
   228  
   229  TEXT ·StoreReluintptr(SB), NOSPLIT, $0-16
   230  	JMP     ·Store64(SB)
   231  
   232  TEXT ·Store(SB), NOSPLIT, $0-12
   233  	MOVV	ptr+0(FP), R4
   234  	MOVW	val+8(FP), R5
   235  	AMSWAPDBW	R5, (R4), R0
   236  	RET
   237  
   238  TEXT ·Store8(SB), NOSPLIT, $0-9
   239  	MOVV	ptr+0(FP), R4
   240  	MOVB	val+8(FP), R5
   241  	MOVBU	internal∕cpu·Loong64+const_offsetLoong64HasLAM_BH(SB), R6
   242  	BEQ	R6, _legacy_store8_
   243  	AMSWAPDBB	R5, (R4), R0
   244  	RET
   245  _legacy_store8_:
   246  	// StoreRelease barrier
   247  	DBAR	$0x12
   248  	MOVB	R5, 0(R4)
   249  	DBAR	$0x18
   250  	RET
   251  
   252  TEXT ·Store64(SB), NOSPLIT, $0-16
   253  	MOVV	ptr+0(FP), R4
   254  	MOVV	val+8(FP), R5
   255  	AMSWAPDBV	R5, (R4), R0
   256  	RET
   257  
   258  // void	Or8(byte volatile*, byte);
   259  TEXT ·Or8(SB), NOSPLIT, $0-9
   260  	MOVV	ptr+0(FP), R4
   261  	MOVBU	val+8(FP), R5
   262  	// R6 = ptr & (~3)
   263  	MOVV	$~3, R6
   264  	AND	R4, R6
   265  	// R7 = ((ptr & 3) * 8)
   266  	AND	$3, R4, R7
   267  	SLLV	$3, R7
   268  	// R5 = val << R7
   269  	SLLV	R7, R5
   270  	AMORDBW	R5, (R6), R0
   271  	RET
   272  
   273  // void	And8(byte volatile*, byte);
   274  TEXT ·And8(SB), NOSPLIT, $0-9
   275  	MOVV	ptr+0(FP), R4
   276  	MOVBU	val+8(FP), R5
   277  	// R6 = ptr & (~3)
   278  	MOVV	$~3, R6
   279  	AND	R4, R6
   280  	// R7 = ((ptr & 3) * 8)
   281  	AND	$3, R4, R7
   282  	SLLV	$3, R7
   283  	// R5 = ((val ^ 0xFF) << R7) ^ (-1)
   284  	XOR	$255, R5
   285  	SLLV	R7,  R5
   286  	XOR	$-1, R5
   287  	AMANDDBW	R5, (R6), R0
   288  	RET
   289  
   290  // func Or(addr *uint32, v uint32)
   291  TEXT ·Or(SB), NOSPLIT, $0-12
   292  	MOVV	ptr+0(FP), R4
   293  	MOVW	val+8(FP), R5
   294  	AMORDBW	R5, (R4), R0
   295  	RET
   296  
   297  // func And(addr *uint32, v uint32)
   298  TEXT ·And(SB), NOSPLIT, $0-12
   299  	MOVV	ptr+0(FP), R4
   300  	MOVW	val+8(FP), R5
   301  	AMANDDBW	R5, (R4), R0
   302  	RET
   303  
   304  // func Or32(addr *uint32, v uint32) old uint32
   305  TEXT ·Or32(SB), NOSPLIT, $0-20
   306  	MOVV	ptr+0(FP), R4
   307  	MOVW	val+8(FP), R5
   308  	AMORDBW R5, (R4), R6
   309  	MOVW	R6, ret+16(FP)
   310  	RET
   311  
   312  // func And32(addr *uint32, v uint32) old uint32
   313  TEXT ·And32(SB), NOSPLIT, $0-20
   314  	MOVV	ptr+0(FP), R4
   315  	MOVW	val+8(FP), R5
   316  	AMANDDBW	R5, (R4), R6
   317  	MOVW	R6, ret+16(FP)
   318  	RET
   319  
   320  // func Or64(addr *uint64, v uint64) old uint64
   321  TEXT ·Or64(SB), NOSPLIT, $0-24
   322  	MOVV	ptr+0(FP), R4
   323  	MOVV	val+8(FP), R5
   324  	AMORDBV	R5, (R4), R6
   325  	MOVV	R6, ret+16(FP)
   326  	RET
   327  
   328  // func And64(addr *uint64, v uint64) old uint64
   329  TEXT ·And64(SB), NOSPLIT, $0-24
   330  	MOVV	ptr+0(FP), R4
   331  	MOVV	val+8(FP), R5
   332  	AMANDDBV	R5, (R4), R6
   333  	MOVV	R6, ret+16(FP)
   334  	RET
   335  
   336  // func Anduintptr(addr *uintptr, v uintptr) old uintptr
   337  TEXT ·Anduintptr(SB), NOSPLIT, $0-24
   338  	JMP	·And64(SB)
   339  
   340  // func Oruintptr(addr *uintptr, v uintptr) old uintptr
   341  TEXT ·Oruintptr(SB), NOSPLIT, $0-24
   342  	JMP	·Or64(SB)
   343  
   344  // uint32 internal∕runtime∕atomic·Load(uint32 volatile* ptr)
   345  TEXT ·Load(SB),NOSPLIT|NOFRAME,$0-12
   346  	MOVV	ptr+0(FP), R19
   347  	MOVWU	0(R19), R19
   348  	DBAR	$0x14	// LoadAcquire barrier
   349  	MOVW	R19, ret+8(FP)
   350  	RET
   351  
   352  // uint8 internal∕runtime∕atomic·Load8(uint8 volatile* ptr)
   353  TEXT ·Load8(SB),NOSPLIT|NOFRAME,$0-9
   354  	MOVV	ptr+0(FP), R19
   355  	MOVBU	0(R19), R19
   356  	DBAR	$0x14
   357  	MOVB	R19, ret+8(FP)
   358  	RET
   359  
   360  // uint64 internal∕runtime∕atomic·Load64(uint64 volatile* ptr)
   361  TEXT ·Load64(SB),NOSPLIT|NOFRAME,$0-16
   362  	MOVV	ptr+0(FP), R19
   363  	MOVV	0(R19), R19
   364  	DBAR	$0x14
   365  	MOVV	R19, ret+8(FP)
   366  	RET
   367  
   368  // void *internal∕runtime∕atomic·Loadp(void *volatile *ptr)
   369  TEXT ·Loadp(SB),NOSPLIT|NOFRAME,$0-16
   370  	JMP     ·Load64(SB)
   371  
   372  // uint32 internal∕runtime∕atomic·LoadAcq(uint32 volatile* ptr)
   373  TEXT ·LoadAcq(SB),NOSPLIT|NOFRAME,$0-12
   374  	JMP	·Load(SB)
   375  
   376  // uint64 ·LoadAcq64(uint64 volatile* ptr)
   377  TEXT ·LoadAcq64(SB),NOSPLIT|NOFRAME,$0-16
   378  	JMP	·Load64(SB)
   379  
   380  // uintptr ·LoadAcquintptr(uintptr volatile* ptr)
   381  TEXT ·LoadAcquintptr(SB),NOSPLIT|NOFRAME,$0-16
   382  	JMP	·Load64(SB)
   383  
   384  

View as plain text