atomic_loong64.s raw

   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