Skip to content

Commit

Permalink
cmd/compile: intrinsify runtime/internal/atomic.{And,Or}{8,} on RISCV64
Browse files Browse the repository at this point in the history
The 32 bit versions are easily implement with a single instruction, while the
8 bit versions require a bit more effort but use the same atomic instructions
via rewrite rules.

Change-Id: I42e8d457b239c8f75e39a8e282fc88c1bb292a99
Reviewed-on: https://go-review.googlesource.com/c/go/+/268098
Trust: Joel Sing <joel@sing.id.au>
Run-TryBot: Joel Sing <joel@sing.id.au>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
  • Loading branch information
4a6f656c committed Mar 3, 2021
1 parent 00cb841 commit 497feff
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 1 deletion.
8 changes: 8 additions & 0 deletions src/cmd/compile/internal/riscv64/ssa.go
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,14 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
p6 := s.Prog(obj.ANOP)
p2.To.SetTarget(p6)

case ssa.OpRISCV64LoweredAtomicAnd32, ssa.OpRISCV64LoweredAtomicOr32:
p := s.Prog(v.Op.Asm())
p.From.Type = obj.TYPE_REG
p.From.Reg = v.Args[1].Reg()
p.To.Type = obj.TYPE_MEM
p.To.Reg = v.Args[0].Reg()
p.RegTo2 = riscv.REG_ZERO

case ssa.OpRISCV64LoweredZero:
mov, sz := largestMove(v.AuxInt)

Expand Down
16 changes: 16 additions & 0 deletions src/cmd/compile/internal/ssa/gen/RISCV64.rules
Original file line number Diff line number Diff line change
Expand Up @@ -564,12 +564,28 @@
(AtomicAdd32 ...) => (LoweredAtomicAdd32 ...)
(AtomicAdd64 ...) => (LoweredAtomicAdd64 ...)

// AtomicAnd8(ptr,val) => LoweredAtomicAnd32(ptr&^3, ^((uint8(val) ^ 0xff) << ((ptr & 3) * 8)))
(AtomicAnd8 ptr val mem) =>
(LoweredAtomicAnd32 (ANDI <typ.Uintptr> [^3] ptr)
(NOT <typ.UInt32> (SLL <typ.UInt32> (XORI <typ.UInt32> [0xff] (ZeroExt8to32 val))
(SLLI <typ.UInt64> [3] (ANDI <typ.UInt64> [3] ptr)))) mem)

(AtomicAnd32 ...) => (LoweredAtomicAnd32 ...)

(AtomicCompareAndSwap32 ...) => (LoweredAtomicCas32 ...)
(AtomicCompareAndSwap64 ...) => (LoweredAtomicCas64 ...)

(AtomicExchange32 ...) => (LoweredAtomicExchange32 ...)
(AtomicExchange64 ...) => (LoweredAtomicExchange64 ...)

// AtomicOr8(ptr,val) => LoweredAtomicOr32(ptr&^3, uint32(val)<<((ptr&3)*8))
(AtomicOr8 ptr val mem) =>
(LoweredAtomicOr32 (ANDI <typ.Uintptr> [^3] ptr)
(SLL <typ.UInt32> (ZeroExt8to32 val)
(SLLI <typ.UInt64> [3] (ANDI <typ.UInt64> [3] ptr))) mem)

(AtomicOr32 ...) => (LoweredAtomicOr32 ...)

// Conditional branches
(If cond yes no) => (BNEZ cond yes no)

Expand Down
8 changes: 7 additions & 1 deletion src/cmd/compile/internal/ssa/gen/RISCV64Ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func init() {
gp11sb = regInfo{inputs: []regMask{gpspsbMask}, outputs: []regMask{gpMask}}
gpxchg = regInfo{inputs: []regMask{gpspsbgMask, gpgMask}, outputs: []regMask{gpMask}}
gpcas = regInfo{inputs: []regMask{gpspsbgMask, gpgMask, gpgMask}, outputs: []regMask{gpMask}}
gpatomic = regInfo{inputs: []regMask{gpspsbgMask, gpgMask}}

fp11 = regInfo{inputs: []regMask{fpMask}, outputs: []regMask{fpMask}}
fp21 = regInfo{inputs: []regMask{fpMask, fpMask}, outputs: []regMask{fpMask}}
Expand Down Expand Up @@ -335,7 +336,7 @@ func init() {
{name: "LoweredAtomicLoad64", argLength: 2, reg: gpload, faultOnNilArg0: true},

// Atomic stores.
// store arg1 to arg0. arg2=mem. returns memory.
// store arg1 to *arg0. arg2=mem. returns memory.
{name: "LoweredAtomicStore8", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
{name: "LoweredAtomicStore32", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
{name: "LoweredAtomicStore64", argLength: 3, reg: gpstore, faultOnNilArg0: true, hasSideEffects: true},
Expand Down Expand Up @@ -367,6 +368,11 @@ func init() {
{name: "LoweredAtomicCas32", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},
{name: "LoweredAtomicCas64", argLength: 4, reg: gpcas, resultNotInArgs: true, faultOnNilArg0: true, hasSideEffects: true, unsafePoint: true},

// Atomic 32 bit AND/OR.
// *arg0 &= (|=) arg1. arg2=mem. returns nil.
{name: "LoweredAtomicAnd32", argLength: 3, reg: gpatomic, asm: "AMOANDW", faultOnNilArg0: true, hasSideEffects: true},
{name: "LoweredAtomicOr32", argLength: 3, reg: gpatomic, asm: "AMOORW", faultOnNilArg0: true, hasSideEffects: true},

// Lowering pass-throughs
{name: "LoweredNilCheck", argLength: 2, faultOnNilArg0: true, nilCheck: true, reg: regInfo{inputs: []regMask{gpspMask}}}, // arg0=ptr,arg1=mem, returns void. Faults if ptr is nil.
{name: "LoweredGetClosurePtr", reg: regInfo{outputs: []regMask{regCtxt}}}, // scheduler ensures only at beginning of entry block
Expand Down
28 changes: 28 additions & 0 deletions src/cmd/compile/internal/ssa/opGen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

75 changes: 75 additions & 0 deletions src/cmd/compile/internal/ssa/rewriteRISCV64.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 497feff

Please sign in to comment.