]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.power64] runtime: fix atomicor8 for power64x
authorAustin Clements <austin@google.com>
Tue, 28 Oct 2014 19:57:33 +0000 (15:57 -0400)
committerAustin Clements <austin@google.com>
Tue, 28 Oct 2014 19:57:33 +0000 (15:57 -0400)
Power64 servers do not currently support sub-word size atomic
memory access, so atomicor8 uses word size atomic access.
However, previously atomicor8 made no attempt to align this
access, resulting in errors.  Fix this by aligning the pointer
to a word boundary and shifting the value appropriately.
Since atomicor8 is used in GC, add a test to runtime·check to
make sure this doesn't break in the future.

This also fixes an incorrect branch label, an incorrectly
sized argument move, and adds argument names to help go vet.

LGTM=rsc
R=rsc, dave
CC=golang-codereviews
https://golang.org/cl/165820043

src/runtime/asm_power64x.s
src/runtime/runtime.c

index b489f6accb355819a94b51f62891794997f92e84..21220e5cb8bd113ce193e2799a1cc853da91955e 100644 (file)
@@ -557,13 +557,27 @@ TEXT runtime·atomicstore64(SB), NOSPLIT, $0-16
 
 // void        runtime·atomicor8(byte volatile*, byte);
 TEXT runtime·atomicor8(SB), NOSPLIT, $0-9
-       MOVD    0(FP), R3
-       MOVD    8(FP), R4
+       MOVD    ptr+0(FP), R3
+       MOVBZ   val+8(FP), R4
+       // Align ptr down to 4 bytes so we can use 32-bit load/store.
+       // R5 = (R3 << 0) & ~3
+       RLDCR   $0, R3, $~3, R5
+       // Compute val shift.
+#ifdef GOARCH_power64
+       // Big endian.  ptr = ptr ^ 3
+       XOR     $3, R3
+#endif
+       // R6 = ((ptr & 3) * 8) = (ptr << 3) & (3*8)
+       RLDC    $3, R3, $(3*8), R6
+       // Shift val for aligned ptr.  R4 = val << R6
+       SLD     R6, R4, R4
+
+atomicor8_again:
        SYNC
-       LWAR    (R3), R5
-       OR      R4, R5
-       STWCCC  R5, (R3)
-       BNE     -3(PC)
+       LWAR    (R5), R6
+       OR      R4, R6
+       STWCCC  R6, (R5)
+       BNE     atomicor8_again
        SYNC
        ISYNC
        RETURN
index b3503fb909a2777fbddf3bee15d9e02783f277c9..d984983ce22c553a24ca0f76174b929537a2770c 100644 (file)
@@ -185,6 +185,7 @@ runtime·check(void)
        float64 j, j1;
        byte *k, *k1;
        uint16* l;
+       byte m[4];
        struct x1 {
                byte x;
        };
@@ -236,6 +237,11 @@ runtime·check(void)
        if(k != k1)
                runtime·throw("casp3");
 
+       m[0] = m[1] = m[2] = m[3] = 0x1;
+       runtime·atomicor8(&m[1], 0xf0);
+       if (m[0] != 0x1 || m[1] != 0xf1 || m[2] != 0x1 || m[3] != 0x1)
+               runtime·throw("atomicor8");
+
        *(uint64*)&j = ~0ULL;
        if(j == j)
                runtime·throw("float64nan");