示例#1
0
        public static void Ldc(EmitterContext context)
        {
            OpCodeLdc op = (OpCodeLdc)context.CurrOp;

            if (op.Size > IntegerSize.B64)
            {
                context.Config.GpuAccessor.Log($"Invalid LDC size: {op.Size}.");
            }

            bool isSmallInt = op.Size < IntegerSize.B32;

            int count = op.Size == IntegerSize.B64 ? 2 : 1;

            Operand slot = Const(op.Slot);
            Operand srcA = GetSrcA(context);

            if (op.IndexMode == CbIndexMode.Is ||
                op.IndexMode == CbIndexMode.Isl)
            {
                slot = context.IAdd(slot, context.BitfieldExtractU32(srcA, Const(16), Const(16)));
                srcA = context.BitwiseAnd(srcA, Const(0xffff));
            }

            Operand addr = context.IAdd(srcA, Const(op.Offset));

            Operand wordOffset = context.ShiftRightU32(addr, Const(2));

            Operand bitOffset = GetBitOffset(context, addr);

            for (int index = 0; index < count; index++)
            {
                Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);

                if (rd.IsRZ)
                {
                    break;
                }

                Operand offset = context.IAdd(wordOffset, Const(index));

                Operand value = context.LoadConstant(slot, offset);

                if (isSmallInt)
                {
                    value = ExtractSmallInt(context, op.Size, bitOffset, value);
                }

                context.Copy(Register(rd), value);
            }
        }
示例#2
0
        public static void Ldc(EmitterContext context)
        {
            OpCodeLdc op = (OpCodeLdc)context.CurrOp;

            if (op.Size > IntegerSize.B64)
            {
                // TODO: Warning.
            }

            bool isSmallInt = op.Size < IntegerSize.B32;

            int count = op.Size == IntegerSize.B64 ? 2 : 1;

            Operand baseOffset = context.Copy(GetSrcA(context));

            for (int index = 0; index < count; index++)
            {
                Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);

                if (rd.IsRZ)
                {
                    break;
                }

                Operand offset = context.IAdd(baseOffset, Const((op.Offset + index) * 4));

                Operand value = context.LoadConstant(Const(op.Slot), offset);

                if (isSmallInt)
                {
                    Operand shift = context.BitwiseAnd(baseOffset, Const(3));

                    value = context.ShiftRightU32(value, shift);

                    switch (op.Size)
                    {
                    case IntegerSize.U8:  value = ZeroExtendTo32(context, value, 8);  break;

                    case IntegerSize.U16: value = ZeroExtendTo32(context, value, 16); break;

                    case IntegerSize.S8:  value = SignExtendTo32(context, value, 8);  break;

                    case IntegerSize.S16: value = SignExtendTo32(context, value, 16); break;
                    }
                }

                context.Copy(Register(rd), value);
            }
        }
        public static void Ldc(EmitterContext context)
        {
            OpCodeLdc op = (OpCodeLdc)context.CurrOp;

            if (op.Size > IntegerSize.B64)
            {
                context.Config.PrintLog($"Invalid LDC size: {op.Size}.");
            }

            bool isSmallInt = op.Size < IntegerSize.B32;

            int count = op.Size == IntegerSize.B64 ? 2 : 1;

            Operand wordOffset = context.ShiftRightU32(GetSrcA(context), Const(2));

            wordOffset = context.IAdd(wordOffset, Const(op.Offset));

            Operand bitOffset = GetBitOffset(context, GetSrcA(context));

            for (int index = 0; index < count; index++)
            {
                Register rd = new Register(op.Rd.Index + index, RegisterType.Gpr);

                if (rd.IsRZ)
                {
                    break;
                }

                Operand offset = context.IAdd(wordOffset, Const(index));

                Operand value = context.LoadConstant(Const(op.Slot), offset);

                if (isSmallInt)
                {
                    value = ExtractSmallInt(context, op.Size, bitOffset, value);
                }

                context.Copy(Register(rd), value);
            }
        }