public static void Atoms(EmitterContext context) { InstAtoms op = context.GetOp <InstAtoms>(); Operand offset = context.ShiftRightU32(GetSrcReg(context, op.SrcA), Const(2)); int sOffset = (op.Imm22 << 10) >> 10; offset = context.IAdd(offset, Const(sOffset)); Operand value = GetSrcReg(context, op.SrcB); AtomSize size = op.AtomsSize switch { AtomsSize.S32 => AtomSize.S32, AtomsSize.U64 => AtomSize.U64, AtomsSize.S64 => AtomSize.S64, _ => AtomSize.U32 }; Operand res = EmitAtomicOp(context, Instruction.MrShared, op.AtomOp, size, offset, Const(0), value); context.Copy(GetDest(op.Dest), res); }
private static Operand EmitAtomicOp( EmitterContext context, Instruction mr, AtomOp op, AtomSize type, Operand addrLow, Operand addrHigh, Operand value) { Operand res = Const(0); switch (op) { case AtomOp.Add: if (type == AtomSize.S32 || type == AtomSize.U32) { res = context.AtomicAdd(mr, addrLow, addrHigh, value); } else { context.Config.GpuAccessor.Log($"Invalid reduction type: {type}."); } break; case AtomOp.And: if (type == AtomSize.S32 || type == AtomSize.U32) { res = context.AtomicAnd(mr, addrLow, addrHigh, value); } else { context.Config.GpuAccessor.Log($"Invalid reduction type: {type}."); } break; case AtomOp.Xor: if (type == AtomSize.S32 || type == AtomSize.U32) { res = context.AtomicXor(mr, addrLow, addrHigh, value); } else { context.Config.GpuAccessor.Log($"Invalid reduction type: {type}."); } break; case AtomOp.Or: if (type == AtomSize.S32 || type == AtomSize.U32) { res = context.AtomicOr(mr, addrLow, addrHigh, value); } else { context.Config.GpuAccessor.Log($"Invalid reduction type: {type}."); } break; case AtomOp.Max: if (type == AtomSize.S32) { res = context.AtomicMaxS32(mr, addrLow, addrHigh, value); } else if (type == AtomSize.U32) { res = context.AtomicMaxU32(mr, addrLow, addrHigh, value); } else { context.Config.GpuAccessor.Log($"Invalid reduction type: {type}."); } break; case AtomOp.Min: if (type == AtomSize.S32) { res = context.AtomicMinS32(mr, addrLow, addrHigh, value); } else if (type == AtomSize.U32) { res = context.AtomicMinU32(mr, addrLow, addrHigh, value); } else { context.Config.GpuAccessor.Log($"Invalid reduction type: {type}."); } break; } return(res); }