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 {