Home | History | Annotate | Download | only in atomic
      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 // +build ppc64 ppc64le
      6 
      7 #include "textflag.h"
      8 
      9 // bool cas(uint32 *ptr, uint32 old, uint32 new)
     10 // Atomically:
     11 //	if(*val == old){
     12 //		*val = new;
     13 //		return 1;
     14 //	} else
     15 //		return 0;
     16 TEXT runtimeinternalatomicCas(SB), NOSPLIT, $0-17
     17 	MOVD	ptr+0(FP), R3
     18 	MOVWZ	old+8(FP), R4
     19 	MOVWZ	new+12(FP), R5
     20 	SYNC
     21 cas_again:
     22 	LWAR	(R3), R6
     23 	CMPW	R6, R4
     24 	BNE	cas_fail
     25 	STWCCC	R5, (R3)
     26 	BNE	cas_again
     27 	MOVD	$1, R3
     28 	ISYNC
     29 	MOVB	R3, ret+16(FP)
     30 	RET
     31 cas_fail:
     32 	MOVB	R0, ret+16(FP)
     33 	RET
     34 
     35 // bool	runtimeinternalatomicCas64(uint64 *ptr, uint64 old, uint64 new)
     36 // Atomically:
     37 //	if(*val == *old){
     38 //		*val = new;
     39 //		return 1;
     40 //	} else {
     41 //		return 0;
     42 //	}
     43 TEXT runtimeinternalatomicCas64(SB), NOSPLIT, $0-25
     44 	MOVD	ptr+0(FP), R3
     45 	MOVD	old+8(FP), R4
     46 	MOVD	new+16(FP), R5
     47 	SYNC
     48 cas64_again:
     49 	LDAR	(R3), R6
     50 	CMP	R6, R4
     51 	BNE	cas64_fail
     52 	STDCCC	R5, (R3)
     53 	BNE	cas64_again
     54 	MOVD	$1, R3
     55 	ISYNC
     56 	MOVB	R3, ret+24(FP)
     57 	RET
     58 cas64_fail:
     59 	MOVB	R0, ret+24(FP)
     60 	RET
     61 
     62 TEXT runtimeinternalatomicCasuintptr(SB), NOSPLIT, $0-25
     63 	BR	runtimeinternalatomicCas64(SB)
     64 
     65 TEXT runtimeinternalatomicLoaduintptr(SB),  NOSPLIT|NOFRAME, $0-16
     66 	BR	runtimeinternalatomicLoad64(SB)
     67 
     68 TEXT runtimeinternalatomicLoaduint(SB), NOSPLIT|NOFRAME, $0-16
     69 	BR	runtimeinternalatomicLoad64(SB)
     70 
     71 TEXT runtimeinternalatomicStoreuintptr(SB), NOSPLIT, $0-16
     72 	BR	runtimeinternalatomicStore64(SB)
     73 
     74 TEXT runtimeinternalatomicXadduintptr(SB), NOSPLIT, $0-24
     75 	BR	runtimeinternalatomicXadd64(SB)
     76 
     77 TEXT runtimeinternalatomicLoadint64(SB), NOSPLIT, $0-16
     78 	BR	runtimeinternalatomicLoad64(SB)
     79 
     80 TEXT runtimeinternalatomicXaddint64(SB), NOSPLIT, $0-24
     81 	BR	runtimeinternalatomicXadd64(SB)
     82 
     83 // bool casp(void **val, void *old, void *new)
     84 // Atomically:
     85 //	if(*val == old){
     86 //		*val = new;
     87 //		return 1;
     88 //	} else
     89 //		return 0;
     90 TEXT runtimeinternalatomicCasp1(SB), NOSPLIT, $0-25
     91 	BR runtimeinternalatomicCas64(SB)
     92 
     93 // uint32 xadd(uint32 volatile *ptr, int32 delta)
     94 // Atomically:
     95 //	*val += delta;
     96 //	return *val;
     97 TEXT runtimeinternalatomicXadd(SB), NOSPLIT, $0-20
     98 	MOVD	ptr+0(FP), R4
     99 	MOVW	delta+8(FP), R5
    100 	SYNC
    101 	LWAR	(R4), R3
    102 	ADD	R5, R3
    103 	STWCCC	R3, (R4)
    104 	BNE	-3(PC)
    105 	ISYNC
    106 	MOVW	R3, ret+16(FP)
    107 	RET
    108 
    109 TEXT runtimeinternalatomicXadd64(SB), NOSPLIT, $0-24
    110 	MOVD	ptr+0(FP), R4
    111 	MOVD	delta+8(FP), R5
    112 	SYNC
    113 	LDAR	(R4), R3
    114 	ADD	R5, R3
    115 	STDCCC	R3, (R4)
    116 	BNE	-3(PC)
    117 	ISYNC
    118 	MOVD	R3, ret+16(FP)
    119 	RET
    120 
    121 TEXT runtimeinternalatomicXchg(SB), NOSPLIT, $0-20
    122 	MOVD	ptr+0(FP), R4
    123 	MOVW	new+8(FP), R5
    124 	SYNC
    125 	LWAR	(R4), R3
    126 	STWCCC	R5, (R4)
    127 	BNE	-2(PC)
    128 	ISYNC
    129 	MOVW	R3, ret+16(FP)
    130 	RET
    131 
    132 TEXT runtimeinternalatomicXchg64(SB), NOSPLIT, $0-24
    133 	MOVD	ptr+0(FP), R4
    134 	MOVD	new+8(FP), R5
    135 	SYNC
    136 	LDAR	(R4), R3
    137 	STDCCC	R5, (R4)
    138 	BNE	-2(PC)
    139 	ISYNC
    140 	MOVD	R3, ret+16(FP)
    141 	RET
    142 
    143 TEXT runtimeinternalatomicXchguintptr(SB), NOSPLIT, $0-24
    144 	BR	runtimeinternalatomicXchg64(SB)
    145 
    146 
    147 TEXT runtimeinternalatomicStorepNoWB(SB), NOSPLIT, $0-16
    148 	BR	runtimeinternalatomicStore64(SB)
    149 
    150 TEXT runtimeinternalatomicStore(SB), NOSPLIT, $0-12
    151 	MOVD	ptr+0(FP), R3
    152 	MOVW	val+8(FP), R4
    153 	SYNC
    154 	MOVW	R4, 0(R3)
    155 	RET
    156 
    157 TEXT runtimeinternalatomicStore64(SB), NOSPLIT, $0-16
    158 	MOVD	ptr+0(FP), R3
    159 	MOVD	val+8(FP), R4
    160 	SYNC
    161 	MOVD	R4, 0(R3)
    162 	RET
    163 
    164 // void runtimeinternalatomicOr8(byte volatile*, byte);
    165 TEXT runtimeinternalatomicOr8(SB), NOSPLIT, $0-9
    166 	MOVD	ptr+0(FP), R3
    167 	MOVBZ	val+8(FP), R4
    168 #ifdef  GOARCH_ppc64
    169 	// Align ptr down to 4 bytes so we can use 32-bit load/store.
    170 	// R5 = (R3 << 0) & ~3
    171 	RLDCR	$0, R3, $~3, R5
    172 	// Compute val shift.
    173 	// Big endian.  ptr = ptr ^ 3
    174 	XOR	$3, R3
    175 	// R6 = ((ptr & 3) * 8) = (ptr << 3) & (3*8)
    176 	RLDC	$3, R3, $(3*8), R6
    177 	// Shift val for aligned ptr.  R4 = val << R6
    178 	SLD	R6, R4, R4
    179 	SYNC
    180 
    181 again:
    182 	LWAR	(R5), R6
    183 	OR	R4, R6
    184 	STWCCC	R6, (R5)
    185 	BNE	again
    186 #else
    187 	SYNC
    188 again:
    189 	LBAR	(R3), R6
    190 	OR	R4, R6
    191 	STBCCC	R6, (R3)
    192 	BNE	again
    193 #endif
    194 	ISYNC
    195 	RET
    196 
    197 // void runtimeinternalatomicAnd8(byte volatile*, byte);
    198 TEXT runtimeinternalatomicAnd8(SB), NOSPLIT, $0-9
    199 	MOVD	ptr+0(FP), R3
    200 	MOVBZ	val+8(FP), R4
    201 #ifdef  GOARCH_ppc64
    202 	// Align ptr down to 4 bytes so we can use 32-bit load/store.
    203 	// R5 = (R3 << 0) & ~3
    204 	RLDCR	$0, R3, $~3, R5
    205 	// Compute val shift.
    206 	// Big endian.  ptr = ptr ^ 3
    207 	XOR	$3, R3
    208 	// R6 = ((ptr & 3) * 8) = (ptr << 3) & (3*8)
    209 	RLDC	$3, R3, $(3*8), R6
    210 	// Shift val for aligned ptr.  R4 = val << R6 | ^(0xFF << R6)
    211 	MOVD	$0xFF, R7
    212 	SLD	R6, R4
    213 	SLD	R6, R7
    214 	XOR	$-1, R7
    215 	OR	R7, R4
    216 	SYNC
    217 again:
    218 	LWAR	(R5), R6
    219 	AND	R4, R6
    220 	STWCCC	R6, (R5)
    221 	BNE	again
    222 #else
    223 	SYNC
    224 again:
    225 	LBAR	(R3),R6
    226 	AND	R4,R6
    227 	STBCCC	R6,(R3)
    228 	BNE	again
    229 #endif
    230 	ISYNC
    231 	RET
    232