aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/riscv64
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2020-03-16 02:51:54 +1100
committerJoel Sing <joel@sing.id.au>2020-03-25 00:06:40 +0000
commitefb0ac4ce6a95435f8fba8c7f77becf083e8eaad (patch)
tree64b275c1fd1c509402d52ae3394aa8333f90997d /src/cmd/compile/internal/riscv64
parent9f343b1942356e0c87c6994118be298f634e6b4d (diff)
downloadgo-efb0ac4ce6a95435f8fba8c7f77becf083e8eaad.tar.gz
go-efb0ac4ce6a95435f8fba8c7f77becf083e8eaad.zip
cmd/compile: provide Add/Cas/Exchange atomic intrinsics on riscv64
Provide Add32, Add64, Cas32, Cas64, Exchange32 and Exchange64 atomic intrinsics on riscv64. Updates #36765 Change-Id: I9a3b7d2ce3d49f699171fd76a0fed891d149a6bb Reviewed-on: https://go-review.googlesource.com/c/go/+/223559 Run-TryBot: Joel Sing <joel@sing.id.au> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/riscv64')
-rw-r--r--src/cmd/compile/internal/riscv64/ssa.go92
1 files changed, 92 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/riscv64/ssa.go b/src/cmd/compile/internal/riscv64/ssa.go
index 45e699ddf9..25bfd05ced 100644
--- a/src/cmd/compile/internal/riscv64/ssa.go
+++ b/src/cmd/compile/internal/riscv64/ssa.go
@@ -383,6 +383,98 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
p.To.Reg = v.Args[0].Reg()
p.RegTo2 = riscv.REG_ZERO
+ case ssa.OpRISCV64LoweredAtomicAdd32, ssa.OpRISCV64LoweredAtomicAdd64:
+ as := riscv.AAMOADDW
+ if v.Op == ssa.OpRISCV64LoweredAtomicAdd64 {
+ as = riscv.AAMOADDD
+ }
+ p := s.Prog(as)
+ 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_TMP
+
+ p2 := s.Prog(riscv.AADD)
+ p2.From.Type = obj.TYPE_REG
+ p2.From.Reg = riscv.REG_TMP
+ p2.Reg = v.Args[1].Reg()
+ p2.To.Type = obj.TYPE_REG
+ p2.To.Reg = v.Reg0()
+
+ case ssa.OpRISCV64LoweredAtomicExchange32, ssa.OpRISCV64LoweredAtomicExchange64:
+ as := riscv.AAMOSWAPW
+ if v.Op == ssa.OpRISCV64LoweredAtomicExchange64 {
+ as = riscv.AAMOSWAPD
+ }
+ p := s.Prog(as)
+ 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 = v.Reg0()
+
+ case ssa.OpRISCV64LoweredAtomicCas32, ssa.OpRISCV64LoweredAtomicCas64:
+ // MOV ZERO, Rout
+ // LR (Rarg0), Rtmp
+ // BNE Rtmp, Rarg1, 3(PC)
+ // SC Rarg2, (Rarg0), Rtmp
+ // BNE Rtmp, ZERO, -3(PC)
+ // MOV $1, Rout
+
+ lr := riscv.ALRW
+ sc := riscv.ASCW
+ if v.Op == ssa.OpRISCV64LoweredAtomicCas64 {
+ lr = riscv.ALRD
+ sc = riscv.ASCD
+ }
+
+ r0 := v.Args[0].Reg()
+ r1 := v.Args[1].Reg()
+ r2 := v.Args[2].Reg()
+ out := v.Reg0()
+
+ p := s.Prog(riscv.AMOV)
+ p.From.Type = obj.TYPE_REG
+ p.From.Reg = riscv.REG_ZERO
+ p.To.Type = obj.TYPE_REG
+ p.To.Reg = out
+
+ p1 := s.Prog(lr)
+ p1.From.Type = obj.TYPE_MEM
+ p1.From.Reg = r0
+ p1.To.Type = obj.TYPE_REG
+ p1.To.Reg = riscv.REG_TMP
+
+ p2 := s.Prog(riscv.ABNE)
+ p2.From.Type = obj.TYPE_REG
+ p2.From.Reg = r1
+ p2.Reg = riscv.REG_TMP
+ p2.To.Type = obj.TYPE_BRANCH
+
+ p3 := s.Prog(sc)
+ p3.From.Type = obj.TYPE_REG
+ p3.From.Reg = r2
+ p3.To.Type = obj.TYPE_MEM
+ p3.To.Reg = r0
+ p3.RegTo2 = riscv.REG_TMP
+
+ p4 := s.Prog(riscv.ABNE)
+ p4.From.Type = obj.TYPE_REG
+ p4.From.Reg = riscv.REG_TMP
+ p4.Reg = riscv.REG_ZERO
+ p4.To.Type = obj.TYPE_BRANCH
+ gc.Patch(p4, p1)
+
+ p5 := s.Prog(riscv.AMOV)
+ p5.From.Type = obj.TYPE_CONST
+ p5.From.Offset = 1
+ p5.To.Type = obj.TYPE_REG
+ p5.To.Reg = out
+
+ p6 := s.Prog(obj.ANOP)
+ gc.Patch(p2, p6)
+
case ssa.OpRISCV64LoweredZero:
mov, sz := largestMove(v.AuxInt)