aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2014-10-28 15:57:33 -0400
committerAustin Clements <austin@google.com>2014-10-28 15:57:33 -0400
commit87b4149b22feb9d8d52da1730b455e39436a3a8d (patch)
tree18ab3a6f8079b14659188eb48b086542da23f168
parentc8f50b298cdf378889cff2a1b7355f7a1cb08a0a (diff)
downloadgo-87b4149b22feb9d8d52da1730b455e39436a3a8d.tar.gz
go-87b4149b22feb9d8d52da1730b455e39436a3a8d.zip
[dev.power64] runtime: fix atomicor8 for power64x
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
-rw-r--r--src/runtime/asm_power64x.s26
-rw-r--r--src/runtime/runtime.c6
2 files changed, 26 insertions, 6 deletions
diff --git a/src/runtime/asm_power64x.s b/src/runtime/asm_power64x.s
index b489f6accb..21220e5cb8 100644
--- a/src/runtime/asm_power64x.s
+++ b/src/runtime/asm_power64x.s
@@ -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
diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c
index b3503fb909..d984983ce2 100644
--- a/src/runtime/runtime.c
+++ b/src/runtime/runtime.c
@@ -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");