Ejemplo n.º 1
0
        public OpCodeAtom(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
        {
            Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
            Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);

            Extended = opCode.Extract(48);

            AtomicOp = (AtomicOp)opCode.Extract(52, 4);
        }
Ejemplo n.º 2
0
        public OpCodeAtom(InstEmitter emitter, ulong address, long opCode) : base(emitter, address, opCode)
        {
            Rd = new Register(opCode.Extract(0, 8), RegisterType.Gpr);
            Ra = new Register(opCode.Extract(8, 8), RegisterType.Gpr);
            Rb = new Register(opCode.Extract(20, 8), RegisterType.Gpr);

            Type = (ReductionType)opCode.Extract(28, 2);

            if (Type == ReductionType.FP32FtzRn)
            {
                Type = ReductionType.S64;
            }

            Offset = opCode.Extract(30, 22);

            Extended = opCode.Extract(48);

            AtomicOp = (AtomicOp)opCode.Extract(52, 4);
        }
Ejemplo n.º 3
0
        private static Operand EmitAtomicOp(
            EmitterContext context,
            Instruction mr,
            AtomicOp op,
            ReductionType type,
            Operand addrLow,
            Operand addrHigh,
            Operand value)
        {
            Operand res = Const(0);

            switch (op)
            {
            case AtomicOp.Add:
                if (type == ReductionType.S32 || type == ReductionType.U32)
                {
                    res = context.AtomicAdd(mr, addrLow, addrHigh, value);
                }
                else
                {
                    context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
                }
                break;

            case AtomicOp.BitwiseAnd:
                if (type == ReductionType.S32 || type == ReductionType.U32)
                {
                    res = context.AtomicAnd(mr, addrLow, addrHigh, value);
                }
                else
                {
                    context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
                }
                break;

            case AtomicOp.BitwiseExclusiveOr:
                if (type == ReductionType.S32 || type == ReductionType.U32)
                {
                    res = context.AtomicXor(mr, addrLow, addrHigh, value);
                }
                else
                {
                    context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
                }
                break;

            case AtomicOp.BitwiseOr:
                if (type == ReductionType.S32 || type == ReductionType.U32)
                {
                    res = context.AtomicOr(mr, addrLow, addrHigh, value);
                }
                else
                {
                    context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
                }
                break;

            case AtomicOp.Maximum:
                if (type == ReductionType.S32)
                {
                    res = context.AtomicMaxS32(mr, addrLow, addrHigh, value);
                }
                else if (type == ReductionType.U32)
                {
                    res = context.AtomicMaxU32(mr, addrLow, addrHigh, value);
                }
                else
                {
                    context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
                }
                break;

            case AtomicOp.Minimum:
                if (type == ReductionType.S32)
                {
                    res = context.AtomicMinS32(mr, addrLow, addrHigh, value);
                }
                else if (type == ReductionType.U32)
                {
                    res = context.AtomicMinU32(mr, addrLow, addrHigh, value);
                }
                else
                {
                    context.Config.GpuAccessor.Log($"Invalid reduction type: {type}.");
                }
                break;
            }

            return(res);
        }