atomic_mipsx.s raw

   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  //go:build mips || mipsle
   6  
   7  #include "textflag.h"
   8  
   9  // func Cas(ptr *int32, old, new int32) bool
  10  // Atomically:
  11  //	if *ptr == old {
  12  //		*ptr = new
  13  //		return true
  14  //	} else {
  15  //		return false
  16  //	}
  17  TEXT ·Cas(SB),NOSPLIT,$0-13
  18  	MOVW	ptr+0(FP), R1
  19  	MOVW	old+4(FP), R2
  20  	MOVW	new+8(FP), R5
  21  	SYNC
  22  try_cas:
  23  	MOVW	R5, R3
  24  	LL	(R1), R4	// R4 = *R1
  25  	BNE	R2, R4, cas_fail
  26  	SC	R3, (R1)	// *R1 = R3
  27  	BEQ	R3, try_cas
  28  	SYNC
  29  	MOVB	R3, ret+12(FP)
  30  	RET
  31  cas_fail:
  32  	SYNC
  33  	MOVB	R0, ret+12(FP)
  34  	RET
  35  
  36  TEXT ·Store(SB),NOSPLIT,$0-8
  37  	MOVW	ptr+0(FP), R1
  38  	MOVW	val+4(FP), R2
  39  	SYNC
  40  	MOVW	R2, 0(R1)
  41  	SYNC
  42  	RET
  43  
  44  TEXT ·Store8(SB),NOSPLIT,$0-5
  45  	MOVW	ptr+0(FP), R1
  46  	MOVB	val+4(FP), R2
  47  	SYNC
  48  	MOVB	R2, 0(R1)
  49  	SYNC
  50  	RET
  51  
  52  TEXT ·Load(SB),NOSPLIT,$0-8
  53  	MOVW	ptr+0(FP), R1
  54  	SYNC
  55  	MOVW	0(R1), R1
  56  	SYNC
  57  	MOVW	R1, ret+4(FP)
  58  	RET
  59  
  60  TEXT ·Load8(SB),NOSPLIT,$0-5
  61  	MOVW	ptr+0(FP), R1
  62  	SYNC
  63  	MOVB	0(R1), R1
  64  	SYNC
  65  	MOVB	R1, ret+4(FP)
  66  	RET
  67  
  68  // uint32 Xadd(uint32 volatile *val, int32 delta)
  69  // Atomically:
  70  //	*val += delta;
  71  //	return *val;
  72  TEXT ·Xadd(SB),NOSPLIT,$0-12
  73  	MOVW	ptr+0(FP), R2
  74  	MOVW	delta+4(FP), R3
  75  	SYNC
  76  try_xadd:
  77  	LL	(R2), R1	// R1 = *R2
  78  	ADDU	R1, R3, R4
  79  	MOVW	R4, R1
  80  	SC	R4, (R2)	// *R2 = R4
  81  	BEQ	R4, try_xadd
  82  	SYNC
  83  	MOVW	R1, ret+8(FP)
  84  	RET
  85  
  86  // uint32 Xchg(ptr *uint32, new uint32)
  87  // Atomically:
  88  //	old := *ptr;
  89  //	*ptr = new;
  90  //	return old;
  91  TEXT ·Xchg(SB),NOSPLIT,$0-12
  92  	MOVW	ptr+0(FP), R2
  93  	MOVW	new+4(FP), R5
  94  	SYNC
  95  try_xchg:
  96  	MOVW	R5, R3
  97  	LL	(R2), R1	// R1 = *R2
  98  	SC	R3, (R2)	// *R2 = R3
  99  	BEQ	R3, try_xchg
 100  	SYNC
 101  	MOVW	R1, ret+8(FP)
 102  	RET
 103  
 104  // uint8 Xchg(ptr *uint8, new uint8)
 105  // Atomically:
 106  //	old := *ptr;
 107  //	*ptr = new;
 108  //	return old;
 109  TEXT ·Xchg8(SB), NOSPLIT, $0-9
 110  	MOVW	ptr+0(FP), R2
 111  	MOVBU	new+4(FP), R5
 112  #ifdef GOARCH_mips
 113  	// Big endian.  ptr = ptr ^ 3
 114  	XOR	$3, R2
 115  #endif
 116  	// R4 = ((ptr & 3) * 8)
 117  	AND	$3, R2, R4
 118  	SLL	$3, R4
 119  	// Shift val for aligned ptr. R7 = (0xFF << R4) ^ (-1)
 120  	MOVW	$0xFF, R7
 121  	SLL	R4, R7
 122  	XOR	$-1, R7
 123  	AND	$~3, R2
 124  	SLL	R4, R5
 125  
 126  	SYNC
 127  	LL	(R2), R9
 128  	AND	R7, R9, R8
 129  	OR	R5, R8
 130  	SC	R8, (R2)
 131  	BEQ	R8, -5(PC)
 132  	SYNC
 133  	SRL	R4, R9
 134  	MOVBU	R9, ret+8(FP)
 135  	RET
 136  
 137  TEXT ·Casint32(SB),NOSPLIT,$0-13
 138  	JMP	·Cas(SB)
 139  
 140  TEXT ·Casint64(SB),NOSPLIT,$0-21
 141  	JMP	·Cas64(SB)
 142  
 143  TEXT ·Casuintptr(SB),NOSPLIT,$0-13
 144  	JMP	·Cas(SB)
 145  
 146  TEXT ·CasRel(SB),NOSPLIT,$0-13
 147  	JMP	·Cas(SB)
 148  
 149  TEXT ·Loaduintptr(SB),NOSPLIT,$0-8
 150  	JMP	·Load(SB)
 151  
 152  TEXT ·Loaduint(SB),NOSPLIT,$0-8
 153  	JMP	·Load(SB)
 154  
 155  TEXT ·Loadp(SB),NOSPLIT,$-0-8
 156  	JMP	·Load(SB)
 157  
 158  TEXT ·Storeint32(SB),NOSPLIT,$0-8
 159  	JMP	·Store(SB)
 160  
 161  TEXT ·Storeint64(SB),NOSPLIT,$0-12
 162  	JMP	·Store64(SB)
 163  
 164  TEXT ·Storeuintptr(SB),NOSPLIT,$0-8
 165  	JMP	·Store(SB)
 166  
 167  TEXT ·Xadduintptr(SB),NOSPLIT,$0-12
 168  	JMP	·Xadd(SB)
 169  
 170  TEXT ·Loadint32(SB),NOSPLIT,$0-8
 171  	JMP	·Load(SB)
 172  
 173  TEXT ·Loadint64(SB),NOSPLIT,$0-12
 174  	JMP	·Load64(SB)
 175  
 176  TEXT ·Xaddint32(SB),NOSPLIT,$0-12
 177  	JMP	·Xadd(SB)
 178  
 179  TEXT ·Xaddint64(SB),NOSPLIT,$0-20
 180  	JMP	·Xadd64(SB)
 181  
 182  TEXT ·Casp1(SB),NOSPLIT,$0-13
 183  	JMP	·Cas(SB)
 184  
 185  TEXT ·Xchgint32(SB),NOSPLIT,$0-12
 186  	JMP	·Xchg(SB)
 187  
 188  TEXT ·Xchgint64(SB),NOSPLIT,$0-20
 189  	JMP	·Xchg64(SB)
 190  
 191  TEXT ·Xchguintptr(SB),NOSPLIT,$0-12
 192  	JMP	·Xchg(SB)
 193  
 194  TEXT ·StorepNoWB(SB),NOSPLIT,$0-8
 195  	JMP	·Store(SB)
 196  
 197  TEXT ·StoreRel(SB),NOSPLIT,$0-8
 198  	JMP	·Store(SB)
 199  
 200  TEXT ·StoreReluintptr(SB),NOSPLIT,$0-8
 201  	JMP	·Store(SB)
 202  
 203  // void	Or8(byte volatile*, byte);
 204  TEXT ·Or8(SB),NOSPLIT,$0-5
 205  	MOVW	ptr+0(FP), R1
 206  	MOVBU	val+4(FP), R2
 207  	MOVW	$~3, R3	// Align ptr down to 4 bytes so we can use 32-bit load/store.
 208  	AND	R1, R3
 209  #ifdef GOARCH_mips
 210  	// Big endian.  ptr = ptr ^ 3
 211  	XOR	$3, R1
 212  #endif
 213  	AND	$3, R1, R4	// R4 = ((ptr & 3) * 8)
 214  	SLL	$3, R4
 215  	SLL	R4, R2, R2	// Shift val for aligned ptr. R2 = val << R4
 216  	SYNC
 217  try_or8:
 218  	LL	(R3), R4	// R4 = *R3
 219  	OR	R2, R4
 220  	SC	R4, (R3)	// *R3 = R4
 221  	BEQ	R4, try_or8
 222  	SYNC
 223  	RET
 224  
 225  // void	And8(byte volatile*, byte);
 226  TEXT ·And8(SB),NOSPLIT,$0-5
 227  	MOVW	ptr+0(FP), R1
 228  	MOVBU	val+4(FP), R2
 229  	MOVW	$~3, R3
 230  	AND	R1, R3
 231  #ifdef GOARCH_mips
 232  	// Big endian.  ptr = ptr ^ 3
 233  	XOR	$3, R1
 234  #endif
 235  	AND	$3, R1, R4	// R4 = ((ptr & 3) * 8)
 236  	SLL	$3, R4
 237  	MOVW	$0xFF, R5
 238  	SLL	R4, R2
 239  	SLL	R4, R5
 240  	NOR	R0, R5
 241  	OR	R5, R2	// Shift val for aligned ptr. R2 = val << R4 | ^(0xFF << R4)
 242  	SYNC
 243  try_and8:
 244  	LL	(R3), R4	// R4 = *R3
 245  	AND	R2, R4
 246  	SC	R4, (R3)	// *R3 = R4
 247  	BEQ	R4, try_and8
 248  	SYNC
 249  	RET
 250  
 251  // func Or(addr *uint32, v uint32)
 252  TEXT ·Or(SB), NOSPLIT, $0-8
 253  	MOVW	ptr+0(FP), R1
 254  	MOVW	val+4(FP), R2
 255  
 256  	SYNC
 257  	LL	(R1), R3
 258  	OR	R2, R3
 259  	SC	R3, (R1)
 260  	BEQ	R3, -4(PC)
 261  	SYNC
 262  	RET
 263  
 264  // func And(addr *uint32, v uint32)
 265  TEXT ·And(SB), NOSPLIT, $0-8
 266  	MOVW	ptr+0(FP), R1
 267  	MOVW	val+4(FP), R2
 268  
 269  	SYNC
 270  	LL	(R1), R3
 271  	AND	R2, R3
 272  	SC	R3, (R1)
 273  	BEQ	R3, -4(PC)
 274  	SYNC
 275  	RET
 276  
 277  // func Or32(addr *uint32, v uint32) old uint32
 278  TEXT ·Or32(SB), NOSPLIT, $0-12
 279  	MOVW	ptr+0(FP), R1
 280  	MOVW	val+4(FP), R2
 281  
 282  	SYNC
 283  	LL	(R1), R3
 284  	OR	R2, R3, R4
 285  	SC	R4, (R1)
 286  	BEQ	R4, -4(PC)
 287  	SYNC
 288  	MOVW	R3, ret+8(FP)
 289  	RET
 290  
 291  // func And32(addr *uint32, v uint32) old uint32
 292  TEXT ·And32(SB), NOSPLIT, $0-12
 293  	MOVW	ptr+0(FP), R1
 294  	MOVW	val+4(FP), R2
 295  
 296  	SYNC
 297  	LL	(R1), R3
 298  	AND	R2, R3, R4
 299  	SC	R4, (R1)
 300  	BEQ	R4, -4(PC)
 301  	SYNC
 302  	MOVW	R3, ret+8(FP)
 303  	RET
 304  
 305  // func Anduintptr(addr *uintptr, v uintptr) old uintptr
 306  TEXT ·Anduintptr(SB), NOSPLIT, $0-12
 307  	JMP	·And32(SB)
 308  
 309  // func Oruintptr(addr *uintptr, v uintptr) old uintptr
 310  TEXT ·Oruintptr(SB), NOSPLIT, $0-12
 311  	JMP	·Or32(SB)
 312  
 313  TEXT ·spinLock(SB),NOSPLIT,$0-4
 314  	MOVW	state+0(FP), R1
 315  	MOVW	$1, R2
 316  	SYNC
 317  try_lock:
 318  	MOVW	R2, R3
 319  check_again:
 320  	LL	(R1), R4
 321  	BNE	R4, check_again
 322  	SC	R3, (R1)
 323  	BEQ	R3, try_lock
 324  	SYNC
 325  	RET
 326  
 327  TEXT ·spinUnlock(SB),NOSPLIT,$0-4
 328  	MOVW	state+0(FP), R1
 329  	SYNC
 330  	MOVW	R0, (R1)
 331  	SYNC
 332  	RET
 333