Esempio n. 1
0
        public static void Frinti_V(AILEmitterCtx Context)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            int SizeF = Op.Size & 1;

            EmitVectorUnaryOpF(Context, () =>
            {
                Context.EmitLdarg(ATranslatedSub.StateArgIdx);

                Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpcr));

                if (SizeF == 0)
                {
                    AVectorHelper.EmitCall(Context, nameof(AVectorHelper.RoundF));
                }
                else if (SizeF == 1)
                {
                    AVectorHelper.EmitCall(Context, nameof(AVectorHelper.Round));
                }
                else
                {
                    throw new InvalidOperationException();
                }
            });
        }
Esempio n. 2
0
        private static void EmitMemoryCall(AILEmitterCtx Context, string Name, int Rn = -1)
        {
            Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
            Context.EmitLdarg(ATranslatedSub.StateArgIdx);

            Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Core));

            if (Rn != -1)
            {
                Context.EmitLdint(Rn);
            }

            Context.EmitCall(typeof(AMemory), Name);
        }
Esempio n. 3
0
        public static void EmitSetFpsrQCFlag(AILEmitterCtx Context)
        {
            const int QCFlagBit = 27;

            Context.EmitLdarg(ATranslatedSub.StateArgIdx);

            Context.EmitLdarg(ATranslatedSub.StateArgIdx);
            Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpsr));

            Context.EmitLdc_I4(1 << QCFlagBit);

            Context.Emit(OpCodes.Or);

            Context.EmitCallPropSet(typeof(AThreadState), nameof(AThreadState.Fpsr));
        }
Esempio n. 4
0
        private static void EmitExceptionCall(AILEmitterCtx Context, string MthdName)
        {
            AOpCodeException Op = (AOpCodeException)Context.CurrOp;

            Context.EmitStoreState();

            Context.EmitLdarg(ATranslatedSub.StateArgIdx);

            Context.EmitLdc_I4(Op.Id);

            MethodInfo MthdInfo = typeof(AThreadState).GetMethod(MthdName, Binding);

            Context.EmitCall(MthdInfo);

            //Check if the thread should still be running, if it isn't then we return 0
            //to force a return to the dispatcher and then exit the thread.
            Context.EmitLdarg(ATranslatedSub.StateArgIdx);

            Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Running));

            AILLabel LblEnd = new AILLabel();

            Context.Emit(OpCodes.Brtrue_S, LblEnd);

            Context.EmitLdc_I8(0);

            Context.Emit(OpCodes.Ret);

            Context.MarkLabel(LblEnd);

            if (Context.CurrBlock.Next != null)
            {
                Context.EmitLoadState(Context.CurrBlock.Next);
            }
            else
            {
                Context.EmitLdc_I8(Op.Position + 4);

                Context.Emit(OpCodes.Ret);
            }
        }
Esempio n. 5
0
        public static void Mrs(AILEmitterCtx Context)
        {
            AOpCodeSystem Op = (AOpCodeSystem)Context.CurrOp;

            Context.EmitLdarg(ATranslatedSub.StateArgIdx);

            string PropName;

            switch (GetPackedId(Op))
            {
            case 0b11_011_0000_0000_001: PropName = nameof(AThreadState.CtrEl0);    break;

            case 0b11_011_0000_0000_111: PropName = nameof(AThreadState.DczidEl0);  break;

            case 0b11_011_0100_0100_000: PropName = nameof(AThreadState.Fpcr);      break;

            case 0b11_011_0100_0100_001: PropName = nameof(AThreadState.Fpsr);      break;

            case 0b11_011_1101_0000_010: PropName = nameof(AThreadState.TpidrEl0);  break;

            case 0b11_011_1101_0000_011: PropName = nameof(AThreadState.Tpidr);     break;

            case 0b11_011_1110_0000_000: PropName = nameof(AThreadState.CntfrqEl0); break;

            case 0b11_011_1110_0000_001: PropName = nameof(AThreadState.CntpctEl0); break;

            default: throw new NotImplementedException($"Unknown MRS at {Op.Position:x16}");
            }

            Context.EmitCallPropGet(typeof(AThreadState), PropName);

            PropertyInfo PropInfo = typeof(AThreadState).GetProperty(PropName);

            if (PropInfo.PropertyType != typeof(long) &&
                PropInfo.PropertyType != typeof(ulong))
            {
                Context.Emit(OpCodes.Conv_U8);
            }

            Context.EmitStintzr(Op.Rt);
        }
Esempio n. 6
0
        public static void Frintx_S(AILEmitterCtx Context)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            EmitScalarUnaryOpF(Context, () =>
            {
                Context.EmitLdarg(ATranslatedSub.StateArgIdx);

                Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpcr));

                if (Op.Size == 0)
                {
                    ASoftFallback.EmitCall(Context, nameof(ASoftFallback.RoundF));
                }
                else if (Op.Size == 1)
                {
                    ASoftFallback.EmitCall(Context, nameof(ASoftFallback.Round));
                }
                else
                {
                    throw new InvalidOperationException();
                }
            });
        }
        private static void EmitQxtn(AILEmitterCtx Context, bool Signed, bool Scalar)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            int Elems = (!Scalar ? 8 >> Op.Size : 1);
            int ESize = 8 << Op.Size;

            int TMaxValue = (Signed ? (1 << (ESize - 1)) - 1 : (int)((1L << ESize) - 1L));
            int TMinValue = (Signed ? -((1 << (ESize - 1))) : 0);

            int Part = (!Scalar & (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0);

            Context.EmitLdc_I8(0L);
            Context.EmitSttmp();

            for (int Index = 0; Index < Elems; Index++)
            {
                AILLabel LblLe    = new AILLabel();
                AILLabel LblGeEnd = new AILLabel();

                EmitVectorExtract(Context, Op.Rn, Index, Op.Size + 1, Signed);

                Context.Emit(OpCodes.Dup);

                Context.EmitLdc_I4(TMaxValue);
                Context.Emit(OpCodes.Conv_U8);

                Context.Emit(Signed ? OpCodes.Ble_S : OpCodes.Ble_Un_S, LblLe);

                Context.Emit(OpCodes.Pop);

                Context.EmitLdc_I4(TMaxValue);

                Context.EmitLdc_I8(0x8000000L);
                Context.EmitSttmp();

                Context.Emit(OpCodes.Br_S, LblGeEnd);

                Context.MarkLabel(LblLe);

                Context.Emit(OpCodes.Dup);

                Context.EmitLdc_I4(TMinValue);
                Context.Emit(OpCodes.Conv_I8);

                Context.Emit(Signed ? OpCodes.Bge_S : OpCodes.Bge_Un_S, LblGeEnd);

                Context.Emit(OpCodes.Pop);

                Context.EmitLdc_I4(TMinValue);

                Context.EmitLdc_I8(0x8000000L);
                Context.EmitSttmp();

                Context.MarkLabel(LblGeEnd);

                if (Scalar)
                {
                    EmitVectorZeroLower(Context, Op.Rd);
                }

                EmitVectorInsert(Context, Op.Rd, Part + Index, Op.Size);
            }

            if (Part == 0)
            {
                EmitVectorZeroUpper(Context, Op.Rd);
            }

            Context.EmitLdarg(ATranslatedSub.StateArgIdx);
            Context.EmitLdarg(ATranslatedSub.StateArgIdx);
            Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpsr));
            Context.EmitLdtmp();
            Context.Emit(OpCodes.Conv_I4);
            Context.Emit(OpCodes.Or);
            Context.EmitCallPropSet(typeof(AThreadState), nameof(AThreadState.Fpsr));
        }
Esempio n. 8
0
        public static void EmitSaturatingNarrowOp(
            AILEmitterCtx Context,
            Action Emit,
            bool SignedSrc,
            bool SignedDst,
            bool Scalar)
        {
            AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;

            int Elems = !Scalar ? 8 >> Op.Size : 1;

            int ESize = 8 << Op.Size;

            int Part = !Scalar && (Op.RegisterSize == ARegisterSize.SIMD128) ? Elems : 0;

            long TMaxValue = SignedDst ? (1 << (ESize - 1)) - 1 : (1L << ESize) - 1L;
            long TMinValue = SignedDst ? -((1 << (ESize - 1))) : 0;

            Context.EmitLdc_I8(0L);
            Context.EmitSttmp();

            if (Part != 0)
            {
                Context.EmitLdvec(Op.Rd);
                Context.EmitStvectmp();
            }

            for (int Index = 0; Index < Elems; Index++)
            {
                AILLabel LblLe    = new AILLabel();
                AILLabel LblGeEnd = new AILLabel();

                EmitVectorExtract(Context, Op.Rn, Index, Op.Size + 1, SignedSrc);

                Emit();

                Context.Emit(OpCodes.Dup);

                Context.EmitLdc_I8(TMaxValue);

                Context.Emit(SignedSrc ? OpCodes.Ble_S : OpCodes.Ble_Un_S, LblLe);

                Context.Emit(OpCodes.Pop);

                Context.EmitLdc_I8(TMaxValue);
                Context.EmitLdc_I8(0x8000000L);
                Context.EmitSttmp();

                Context.Emit(OpCodes.Br_S, LblGeEnd);

                Context.MarkLabel(LblLe);

                Context.Emit(OpCodes.Dup);

                Context.EmitLdc_I8(TMinValue);

                Context.Emit(SignedSrc ? OpCodes.Bge_S : OpCodes.Bge_Un_S, LblGeEnd);

                Context.Emit(OpCodes.Pop);

                Context.EmitLdc_I8(TMinValue);
                Context.EmitLdc_I8(0x8000000L);
                Context.EmitSttmp();

                Context.MarkLabel(LblGeEnd);

                if (Scalar)
                {
                    EmitVectorZeroLower(Context, Op.Rd);
                }

                EmitVectorInsertTmp(Context, Part + Index, Op.Size);
            }

            Context.EmitLdvectmp();
            Context.EmitStvec(Op.Rd);

            if (Part == 0)
            {
                EmitVectorZeroUpper(Context, Op.Rd);
            }

            Context.EmitLdarg(ATranslatedSub.StateArgIdx);
            Context.EmitLdarg(ATranslatedSub.StateArgIdx);
            Context.EmitCallPropGet(typeof(AThreadState), nameof(AThreadState.Fpsr));
            Context.EmitLdtmp();
            Context.Emit(OpCodes.Conv_I4);
            Context.Emit(OpCodes.Or);
            Context.EmitCallPropSet(typeof(AThreadState), nameof(AThreadState.Fpsr));
        }