diff --git a/src/cmd/compile/internal/loong64/ssa.go b/src/cmd/compile/internal/loong64/ssa.go index bec7684378..02286b8de8 100644 --- a/src/cmd/compile/internal/loong64/ssa.go +++ b/src/cmd/compile/internal/loong64/ssa.go @@ -589,6 +589,13 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) { p.To.Name = obj.NAME_EXTERN // AuxInt encodes how many buffer entries we need. p.To.Sym = ir.Syms.GCWriteBarrier[v.AuxInt-1] + + case ssa.OpLOONG64LoweredPubBarrier: + // DBAR 0x1A + p := s.Prog(v.Op.Asm()) + p.From.Type = obj.TYPE_CONST + p.From.Offset = 0x1A + case ssa.OpLOONG64LoweredPanicBoundsA, ssa.OpLOONG64LoweredPanicBoundsB, ssa.OpLOONG64LoweredPanicBoundsC: p := s.Prog(obj.ACALL) p.To.Type = obj.TYPE_MEM diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules index 383cac40ab..69119f1d96 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64.rules +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64.rules @@ -464,6 +464,9 @@ // Write barrier. (WB ...) => (LoweredWB ...) +// Publication barrier as intrinsic +(PubBarrier ...) => (LoweredPubBarrier ...) + (PanicBounds [kind] x y mem) && boundsABI(kind) == 0 => (LoweredPanicBoundsA [kind] x y mem) (PanicBounds [kind] x y mem) && boundsABI(kind) == 1 => (LoweredPanicBoundsB [kind] x y mem) (PanicBounds [kind] x y mem) && boundsABI(kind) == 2 => (LoweredPanicBoundsC [kind] x y mem) diff --git a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go index 2d8d87fa4a..5789760683 100644 --- a/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go +++ b/src/cmd/compile/internal/ssa/_gen/LOONG64Ops.go @@ -497,6 +497,9 @@ func init() { // Returns a pointer to a write barrier buffer in R29. {name: "LoweredWB", argLength: 1, reg: regInfo{clobbers: (callerSave &^ gpg) | buildReg("R1"), outputs: []regMask{buildReg("R29")}}, clobberFlags: true, aux: "Int64"}, + // Do data barrier. arg0=memorys + {name: "LoweredPubBarrier", argLength: 1, asm: "DBAR", hasSideEffects: true}, + // There are three of these functions so that they can have three different register inputs. // When we check 0 <= c <= cap (A), then 0 <= b <= c (B), then 0 <= a <= b (C), we want the // default registers to match so we don't need to copy registers around unnecessarily. diff --git a/src/cmd/compile/internal/ssa/opGen.go b/src/cmd/compile/internal/ssa/opGen.go index 61d3b0462f..b18a4385d2 100644 --- a/src/cmd/compile/internal/ssa/opGen.go +++ b/src/cmd/compile/internal/ssa/opGen.go @@ -1917,6 +1917,7 @@ const ( OpLOONG64LoweredGetCallerSP OpLOONG64LoweredGetCallerPC OpLOONG64LoweredWB + OpLOONG64LoweredPubBarrier OpLOONG64LoweredPanicBoundsA OpLOONG64LoweredPanicBoundsB OpLOONG64LoweredPanicBoundsC @@ -25711,6 +25712,13 @@ var opcodeTable = [...]opInfo{ }, }, }, + { + name: "LoweredPubBarrier", + argLen: 1, + hasSideEffects: true, + asm: loong64.ADBAR, + reg: regInfo{}, + }, { name: "LoweredPanicBoundsA", auxType: auxInt64, diff --git a/src/cmd/compile/internal/ssa/rewriteLOONG64.go b/src/cmd/compile/internal/ssa/rewriteLOONG64.go index 14cbd25ee2..fedcd196d4 100644 --- a/src/cmd/compile/internal/ssa/rewriteLOONG64.go +++ b/src/cmd/compile/internal/ssa/rewriteLOONG64.go @@ -584,6 +584,9 @@ func rewriteValueLOONG64(v *Value) bool { return true case OpPanicBounds: return rewriteValueLOONG64_OpPanicBounds(v) + case OpPubBarrier: + v.Op = OpLOONG64LoweredPubBarrier + return true case OpRotateLeft16: return rewriteValueLOONG64_OpRotateLeft16(v) case OpRotateLeft32: diff --git a/src/cmd/compile/internal/ssagen/intrinsics.go b/src/cmd/compile/internal/ssagen/intrinsics.go index 9084c2f690..fda273b3e5 100644 --- a/src/cmd/compile/internal/ssagen/intrinsics.go +++ b/src/cmd/compile/internal/ssagen/intrinsics.go @@ -162,7 +162,7 @@ func initIntrinsics(cfg *intrinsicBuildConfig) { s.vars[memVar] = s.newValue1(ssa.OpPubBarrier, types.TypeMem, s.mem()) return nil }, - sys.ARM64, sys.PPC64, sys.RISCV64) + sys.ARM64, sys.Loong64, sys.PPC64, sys.RISCV64) /******** internal/runtime/sys ********/ add("internal/runtime/sys", "GetCallerPC", diff --git a/src/cmd/compile/internal/ssagen/intrinsics_test.go b/src/cmd/compile/internal/ssagen/intrinsics_test.go index 5e71639a29..4e59714ce7 100644 --- a/src/cmd/compile/internal/ssagen/intrinsics_test.go +++ b/src/cmd/compile/internal/ssagen/intrinsics_test.go @@ -419,6 +419,7 @@ var wantIntrinsics = map[testIntrinsicKey]struct{}{ {"loong64", "math/bits", "Sub"}: struct{}{}, {"loong64", "math/bits", "Sub64"}: struct{}{}, {"loong64", "runtime", "KeepAlive"}: struct{}{}, + {"loong64", "runtime", "publicationBarrier"}: struct{}{}, {"loong64", "runtime", "slicebytetostringtmp"}: struct{}{}, {"loong64", "sync", "runtime_LoadAcquintptr"}: struct{}{}, {"loong64", "sync", "runtime_StoreReluintptr"}: struct{}{}, diff --git a/src/runtime/atomic_loong64.s b/src/runtime/atomic_loong64.s index 4818a827de..5332d36fad 100644 --- a/src/runtime/atomic_loong64.s +++ b/src/runtime/atomic_loong64.s @@ -5,5 +5,5 @@ #include "textflag.h" TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0 - DBAR + DBAR $0x1A // StoreStore barrier RET