diff options
author | Cherry Zhang <cherryyz@google.com> | 2018-06-11 13:41:23 -0400 |
---|---|---|
committer | Cherry Zhang <cherryyz@google.com> | 2018-06-12 20:22:50 +0000 |
commit | 44b826bb28171c473cf906413c298f3095c86451 (patch) | |
tree | ea11632bf7a375960c5de5ae4ec14ac4c27261af /src/cmd/compile/internal/ssa/gen/ARM64Ops.go | |
parent | 39ad208c13368bbd1a129c5e2ed85d6ebc22401a (diff) | |
download | go-44b826bb28171c473cf906413c298f3095c86451.tar.gz go-44b826bb28171c473cf906413c298f3095c86451.zip |
cmd/compile: use a different register for updated value in AtomicAnd8/Or8 on ARM64
ARM64 manual says it is "constrained unpredictable" if the src
and dst registers of STLXRB are same, although it doesn't seem
to cause any problem on real hardwares so far. Fix by allocating
a different register to hold the updated value for
AtomicAnd8/Or8. We do this by making the ops returns <val,mem>
like AtomicAdd, although val will not be used elsewhere.
Fixes #25823.
Change-Id: I735b9822f99877b3c7aee67a65e62b7278dc40df
Reviewed-on: https://go-review.googlesource.com/117976
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Wei Xiao <Wei.Xiao@arm.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/gen/ARM64Ops.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/gen/ARM64Ops.go | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go index b54de53f59..9e8b07ec4b 100644 --- a/src/cmd/compile/internal/ssa/gen/ARM64Ops.go +++ b/src/cmd/compile/internal/ssa/gen/ARM64Ops.go @@ -596,13 +596,13 @@ func init() { {name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, clobberFlags: true, faultOnNilArg0: true, hasSideEffects: true}, // atomic and/or. - // *arg0 &= (|=) arg1. arg2=mem. returns memory. auxint must be zero. - // LDAXRB (Rarg0), Rtmp - // AND/OR Rarg1, Rtmp - // STLXRB Rtmp, (Rarg0), Rtmp + // *arg0 &= (|=) arg1. arg2=mem. returns <new content of *arg0, memory>. auxint must be zero. + // LDAXRB (Rarg0), Rout + // AND/OR Rarg1, Rout + // STLXRB Rout, (Rarg0), Rtmp // CBNZ Rtmp, -3(PC) - {name: "LoweredAtomicAnd8", argLength: 3, reg: gpstore, asm: "AND", faultOnNilArg0: true, hasSideEffects: true}, - {name: "LoweredAtomicOr8", argLength: 3, reg: gpstore, asm: "ORR", faultOnNilArg0: true, hasSideEffects: true}, + {name: "LoweredAtomicAnd8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "AND", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true}, + {name: "LoweredAtomicOr8", argLength: 3, reg: gpxchg, resultNotInArgs: true, asm: "ORR", typ: "(UInt8,Mem)", faultOnNilArg0: true, hasSideEffects: true}, // LoweredWB invokes runtime.gcWriteBarrier. arg0=destptr, arg1=srcptr, arg2=mem, aux=runtime.gcWriteBarrier // It saves all GP registers if necessary, |