p := s.Prog(obj.AGETCALLERPC)
p.To.Type = obj.TYPE_REG
p.To.Reg = v.Reg()
+ case ssa.OpARM64DMB:
+ p := s.Prog(v.Op.Asm())
+ p.From.Type = obj.TYPE_CONST
+ p.From.Offset = v.AuxInt
case ssa.OpARM64FlagConstant:
v.Fatalf("FlagConstant op should never make it to codegen %v", v.LongString())
case ssa.OpARM64InvertFlags:
// Write barrier.
(WB ...) => (LoweredWB ...)
+// Publication barrier (0xe is ST option)
+(PubBarrier mem) => (DMB [0xe] mem)
+
(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)
// Prefetch instruction
// Do prefetch arg0 address with option aux. arg0=addr, arg1=memory, aux=option.
{name: "PRFM", argLength: 2, aux: "Int64", reg: prefreg, asm: "PRFM", hasSideEffects: true},
+
+ // Publication barrier
+ {name: "DMB", argLength: 1, aux: "Int64", asm: "DMB", hasSideEffects: true}, // Do data barrier. arg0=memory, aux=option.
}
blocks := []blockData{
{name: "AtomicOr8Variant", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 |= arg1. arg2=memory. Returns memory.
{name: "AtomicOr32Variant", argLength: 3, typ: "Mem", hasSideEffects: true}, // *arg0 |= arg1. arg2=memory. Returns memory.
+ // Publication barrier
+ {name: "PubBarrier", argLength: 1, hasSideEffects: true}, // Do data barrier. arg0=memory.
+
// Clobber experiment op
{name: "Clobber", argLength: 0, typ: "Void", aux: "SymOff", symEffect: "None"}, // write an invalid pointer value to the given pointer slot of a stack variable
{name: "ClobberReg", argLength: 0, typ: "Void"}, // clobber a register
OpARM64LoweredPanicBoundsB
OpARM64LoweredPanicBoundsC
OpARM64PRFM
+ OpARM64DMB
OpMIPSADD
OpMIPSADDconst
OpAtomicAnd32Variant
OpAtomicOr8Variant
OpAtomicOr32Variant
+ OpPubBarrier
OpClobber
OpClobberReg
OpPrefetchCache
},
},
},
+ {
+ name: "DMB",
+ auxType: auxInt64,
+ argLen: 1,
+ hasSideEffects: true,
+ asm: arm64.ADMB,
+ reg: regInfo{},
+ },
{
name: "ADD",
hasSideEffects: true,
generic: true,
},
+ {
+ name: "PubBarrier",
+ argLen: 1,
+ hasSideEffects: true,
+ generic: true,
+ },
{
name: "Clobber",
auxType: auxSymOff,
return rewriteValueARM64_OpPrefetchCache(v)
case OpPrefetchCacheStreamed:
return rewriteValueARM64_OpPrefetchCacheStreamed(v)
+ case OpPubBarrier:
+ return rewriteValueARM64_OpPubBarrier(v)
case OpRotateLeft16:
return rewriteValueARM64_OpRotateLeft16(v)
case OpRotateLeft32:
return true
}
}
+func rewriteValueARM64_OpPubBarrier(v *Value) bool {
+ v_0 := v.Args[0]
+ // match: (PubBarrier mem)
+ // result: (DMB [0xe] mem)
+ for {
+ mem := v_0
+ v.reset(OpARM64DMB)
+ v.AuxInt = int64ToAuxInt(0xe)
+ v.AddArg(mem)
+ return true
+ }
+}
func rewriteValueARM64_OpRotateLeft16(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
},
all...)
+ addF("runtime", "publicationBarrier",
+ func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+ s.vars[memVar] = s.newValue1(ssa.OpPubBarrier, types.TypeMem, s.mem())
+ return nil
+ },
+ sys.ARM64)
+
/******** runtime/internal/sys ********/
addF("runtime/internal/sys", "Ctz32",
func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {