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

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

View as plain text