Text file src/internal/runtime/atomic/atomic_mipsx.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  //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  

View as plain text