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
// 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)
// 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.
OpLOONG64LoweredGetCallerSP
OpLOONG64LoweredGetCallerPC
OpLOONG64LoweredWB
+ OpLOONG64LoweredPubBarrier
OpLOONG64LoweredPanicBoundsA
OpLOONG64LoweredPanicBoundsB
OpLOONG64LoweredPanicBoundsC
},
},
},
+ {
+ name: "LoweredPubBarrier",
+ argLen: 1,
+ hasSideEffects: true,
+ asm: loong64.ADBAR,
+ reg: regInfo{},
+ },
{
name: "LoweredPanicBoundsA",
auxType: auxInt64,
return true
case OpPanicBounds:
return rewriteValueLOONG64_OpPanicBounds(v)
+ case OpPubBarrier:
+ v.Op = OpLOONG64LoweredPubBarrier
+ return true
case OpRotateLeft16:
return rewriteValueLOONG64_OpRotateLeft16(v)
case OpRotateLeft32:
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",
{"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{}{},
#include "textflag.h"
TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
- DBAR
+ DBAR $0x1A // StoreStore barrier
RET