(AtomicStorePtrNoWB ptr val mem) => (Select1 (XCHGQ <types.NewTuple(typ.BytePtr,types.TypeMem)> val ptr mem))
// Atomic exchanges.
+(AtomicExchange8 ptr val mem) => (XCHGB val ptr mem)
(AtomicExchange32 ptr val mem) => (XCHGL val ptr mem)
(AtomicExchange64 ptr val mem) => (XCHGQ val ptr mem)
{name: "AtomicStorePtrNoWB", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns memory.
{name: "AtomicStoreRel32", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Lock release, returns memory.
{name: "AtomicStoreRel64", argLength: 3, typ: "Mem", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Lock release, returns memory.
+ {name: "AtomicExchange8", argLength: 3, typ: "(UInt8,Mem)", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns old contents of *arg0 and new memory.
{name: "AtomicExchange32", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns old contents of *arg0 and new memory.
{name: "AtomicExchange64", argLength: 3, typ: "(UInt64,Mem)", hasSideEffects: true}, // Store arg1 to *arg0. arg2=memory. Returns old contents of *arg0 and new memory.
{name: "AtomicAdd32", argLength: 3, typ: "(UInt32,Mem)", hasSideEffects: true}, // Do *arg0 += arg1. arg2=memory. Returns sum and new memory.
OpAtomicStorePtrNoWB
OpAtomicStoreRel32
OpAtomicStoreRel64
+ OpAtomicExchange8
OpAtomicExchange32
OpAtomicExchange64
OpAtomicAdd32
hasSideEffects: true,
generic: true,
},
+ {
+ name: "AtomicExchange8",
+ argLen: 3,
+ hasSideEffects: true,
+ generic: true,
+ },
{
name: "AtomicExchange32",
argLen: 3,
return rewriteValueAMD64_OpAtomicExchange32(v)
case OpAtomicExchange64:
return rewriteValueAMD64_OpAtomicExchange64(v)
+ case OpAtomicExchange8:
+ return rewriteValueAMD64_OpAtomicExchange8(v)
case OpAtomicLoad32:
return rewriteValueAMD64_OpAtomicLoad32(v)
case OpAtomicLoad64:
return true
}
}
+func rewriteValueAMD64_OpAtomicExchange8(v *Value) bool {
+ v_2 := v.Args[2]
+ v_1 := v.Args[1]
+ v_0 := v.Args[0]
+ // match: (AtomicExchange8 ptr val mem)
+ // result: (XCHGB val ptr mem)
+ for {
+ ptr := v_0
+ val := v_1
+ mem := v_2
+ v.reset(OpAMD64XCHGB)
+ v.AddArg3(val, ptr, mem)
+ return true
+ }
+}
func rewriteValueAMD64_OpAtomicLoad32(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
},
sys.PPC64)
+ addF("internal/runtime/atomic", "Xchg8",
+ func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
+ v := s.newValue3(ssa.OpAtomicExchange8, types.NewTuple(types.Types[types.TUINT8], types.TypeMem), args[0], args[1], s.mem())
+ s.vars[memVar] = s.newValue1(ssa.OpSelect1, types.TypeMem, v)
+ return s.newValue1(ssa.OpSelect0, types.Types[types.TUINT8], v)
+ },
+ sys.AMD64)
addF("internal/runtime/atomic", "Xchg",
func(s *state, n *ir.CallExpr, args []*ssa.Value) *ssa.Value {
v := s.newValue3(ssa.OpAtomicExchange32, types.NewTuple(types.Types[types.TUINT32], types.TypeMem), args[0], args[1], s.mem())
{"amd64", "internal/runtime/atomic", "Xadduintptr"}: struct{}{},
{"amd64", "internal/runtime/atomic", "Xchg"}: struct{}{},
{"amd64", "internal/runtime/atomic", "Xchg64"}: struct{}{},
+ {"amd64", "internal/runtime/atomic", "Xchg8"}: struct{}{},
{"amd64", "internal/runtime/atomic", "Xchgint32"}: struct{}{},
{"amd64", "internal/runtime/atomic", "Xchgint64"}: struct{}{},
{"amd64", "internal/runtime/atomic", "Xchguintptr"}: struct{}{},