private static AVec Fcvtzu_V(AVec Vector, int FBits, int Size, int Bytes)
        {
            AVec Res = new AVec();

            int Elems = Bytes >> Size;

            if (Size == 0)
            {
                for (int Index = 0; Index < Elems; Index++)
                {
                    float Value = Vector.ExtractSingle(Index);

                    Res = InsertVec(Res, Index, Size + 2, SatSingleToUInt32(Value, FBits));
                }
            }
            else
            {
                for (int Index = 0; Index < Elems; Index++)
                {
                    double Value = Vector.ExtractDouble(Index);

                    Res = InsertVec(Res, Index, Size + 2, SatDoubleToUInt64(Value, FBits));
                }
            }

            return(Res);
        }
        public static AVec Addp_S(AVec Vector, int Size)
        {
            ulong Low  = ExtractVec(Vector, 0, Size);
            ulong High = ExtractVec(Vector, 1, Size);

            return(InsertVec(new AVec(), 0, Size, Low + High));
        }
        private static AVec Fsub(AVec LHS, AVec RHS, int Size, int Bytes)
        {
            AVec Res = new AVec();

            int Elems = Bytes >> Size;

            if (Size == 0)
            {
                for (int Index = 0; Index < Elems; Index++)
                {
                    float L = LHS.ExtractSingle(Index);
                    float R = RHS.ExtractSingle(Index);

                    Res = AVec.InsertSingle(Res, Index, L - R);
                }
            }
            else
            {
                for (int Index = 0; Index < Elems; Index++)
                {
                    double L = LHS.ExtractDouble(Index);
                    double R = RHS.ExtractDouble(Index);

                    Res = AVec.InsertDouble(Res, Index, L - R);
                }
            }

            return(Res);
        }
        private static AVec Fmla_Ve(AVec Res, AVec LHS, AVec RHS, int SIdx, int Size, int Bytes)
        {
            int Elems = Bytes >> Size;

            if (Size == 0)
            {
                float R = RHS.ExtractSingle(SIdx);

                for (int Index = 0; Index < Elems; Index++)
                {
                    float L      = LHS.ExtractSingle(Index);
                    float Addend = Res.ExtractSingle(Index);

                    Res = AVec.InsertSingle(Res, Index, Addend + L * R);
                }
            }
            else
            {
                double R = RHS.ExtractDouble(SIdx);

                for (int Index = 0; Index < Elems; Index++)
                {
                    double L      = LHS.ExtractDouble(Index);
                    double Addend = Res.ExtractDouble(Index);

                    Res = AVec.InsertDouble(Res, Index, Addend + L * R);
                }
            }

            return(Res);
        }
        public void Frintx_S(uint A, char RoundType, bool DefaultNaN, uint Result)
        {
            int FpcrTemp = 0x0;

            switch (RoundType)
            {
            case 'N':
                FpcrTemp = 0x0;
                break;

            case 'P':
                FpcrTemp = 0x400000;
                break;

            case 'M':
                FpcrTemp = 0x800000;
                break;

            case 'Z':
                FpcrTemp = 0xC00000;
                break;
            }
            if (DefaultNaN)
            {
                FpcrTemp |= 1 << 25;
            }
            AVec V1 = new AVec {
                X0 = A
            };
            AThreadState ThreadState = SingleOpcode(0x1E274020, V1: V1, Fpcr: FpcrTemp);

            Assert.AreEqual(Result, ThreadState.V0.X0);
        }
        private static AVec Scvtf_V(AVec Vector, int Size, int Bytes)
        {
            AVec Res = new AVec();

            int Elems = Bytes >> Size;

            if (Size == 0)
            {
                for (int Index = 0; Index < Elems; Index++)
                {
                    int Value = (int)ExtractSVec(Vector, Index, Size + 2);

                    Res = AVec.InsertSingle(Res, Index, Value);
                }
            }
            else
            {
                for (int Index = 0; Index < Elems; Index++)
                {
                    long Value = ExtractSVec(Vector, Index, Size + 2);

                    Res = AVec.InsertDouble(Res, Index, Value);
                }
            }

            return(Res);
        }
        private static AVec Tbl(AVec Vector, int Bytes, params AVec[] Tb)
        {
            AVec Res = new AVec();

            byte[] Table = new byte[Tb.Length * 16];

            for (int Index = 0; Index < Tb.Length; Index++)
            {
                for (int Index2 = 0; Index2 < 16; Index2++)
                {
                    Table[Index * 16 + Index2] = (byte)VectorExtractIntZx(Tb[Index], Index2, 0);
                }
            }

            for (int Index = 0; Index < Bytes; Index++)
            {
                byte TblIdx = (byte)VectorExtractIntZx(Vector, Index, 0);

                if (TblIdx < Table.Length)
                {
                    Res = VectorInsertInt(Table[TblIdx], Res, Index, 0);
                }
            }

            return(Res);
        }
Exemple #8
0
        public void Add_S_D([ValueSource("_1D_")][Random(1)] ulong A,
                            [ValueSource("_1D_")][Random(1)] ulong B)
        {
            uint Opcode = 0x5EE28420; // ADD D0, D1, D2
            Bits Op     = new Bits(Opcode);

            AVec V0 = new AVec {
                X1 = TestContext.CurrentContext.Random.NextULong()
            };
            AVec V1 = new AVec {
                X0 = A
            };
            AVec V2 = new AVec {
                X0 = B
            };
            AThreadState ThreadState = SingleOpcode(Opcode, V0: V0, V1: V1, V2: V2);

            AArch64.V(1, new Bits(A));
            AArch64.V(2, new Bits(B));
            SimdFp.Add_S(Op[23, 22], Op[20, 16], Op[9, 5], Op[4, 0]);

            Assert.Multiple(() =>
            {
                Assert.That(ThreadState.V0.X0, Is.EqualTo(AArch64.V(64, 0).ToUInt64()));
                Assert.That(ThreadState.V0.X1, Is.Zero);
            });
        }
Exemple #9
0
        public void WriteVector64(long Position, AVec Value)
        {
#if DEBUG
            EnsureAccessIsValid(Position, AMemoryPerm.Write);
#endif

            WriteUInt64(Position, Value.X0);
        }
 public static AVec Ucvtf_V_D(AVec Vector)
 {
     return(new AVec()
     {
         D0 = (ulong)Vector.X0,
         D1 = (ulong)Vector.X1
     });
 }
Exemple #11
0
        public void WriteVector8(long Position, AVec Value)
        {
#if DEBUG
            EnsureAccessIsValid(Position, AMemoryPerm.Write);
#endif

            WriteByte(Position, Value.B0);
        }
        public void Frsqrte_S(uint A, uint Result)
        {
            AVec V1 = new AVec {
                X0 = A
            };
            AThreadState ThreadState = SingleOpcode(0x7EA1D820, V1: V1);

            Assert.AreEqual(Result, ThreadState.V0.X0);
        }
 public static AVec Ucvtf_V_F(AVec Vector)
 {
     return(new AVec()
     {
         S0 = (uint)Vector.W0,
         S1 = (uint)Vector.W1,
         S2 = (uint)Vector.W2,
         S3 = (uint)Vector.W3
     });
 }
        private static AVec Dup_Gp(ulong Value, int Size, int Bytes)
        {
            AVec Res = new AVec();

            for (int Index = 0; Index < (Bytes >> Size); Index++)
            {
                Res = InsertVec(Res, Index, Size, Value);
            }

            return(Res);
        }
Exemple #15
0
        protected AThreadState SingleOpcode(uint Opcode,
                                            ulong X0      = 0, ulong X1            = 0, ulong X2 = 0, ulong X31 = 0,
                                            AVec V0       = default(AVec), AVec V1 = default(AVec), AVec V2 = default(AVec),
                                            bool Overflow = false, bool Carry      = false, bool Zero       = false, bool Negative = false)
        {
            this.Opcode(Opcode);
            this.Opcode(0xD4200000); // BRK #0
            this.Opcode(0xD65F03C0); // RET
            SetThreadState(X0, X1, X2, X31, V0, V1, V2, Overflow, Carry, Zero, Negative);
            ExecuteOpcodes();

            return(GetThreadState());
        }
        private static AVec Orr_Vi(AVec Res, ulong Imm, int Size, int Bytes)
        {
            int Elems = Bytes >> Size;

            for (int Index = 0; Index < Elems; Index++)
            {
                ulong Value = ExtractVec(Res, Index, Size);

                Res = InsertVec(Res, Index, Size, Value | Imm);
            }

            return(Res);
        }
        private static AVec Dup_V(AVec Vector, int Elem, int Size, int Bytes)
        {
            AVec Res = new AVec();

            ulong Value = ExtractVec(Vector, Elem, Size);

            for (Elem = 0; Elem < (Bytes >> Size); Elem++)
            {
                Res = InsertVec(Res, Elem, Size, Value);
            }

            return(Res);
        }
        private static AVec Uaddlv(AVec Vector, int Size, int Bytes)
        {
            int Elems = Bytes >> Size;

            ulong Sum = 0;

            for (int Index = 0; Index < Elems; Index++)
            {
                Sum += ExtractVec(Vector, Index, Size);
            }

            return(InsertVec(new AVec(), 0, 3, Sum));
        }
        private static AVec Usra(AVec Res, AVec Vector, int Shift, int Size, int Bytes)
        {
            int Elems = Bytes >> Size;

            for (int Index = 0; Index < Elems; Index++)
            {
                ulong Value  = ExtractVec(Vector, Index, Size);
                ulong Addend = ExtractVec(Res, Index, Size);

                Res = InsertVec(Res, Index, Size, Addend + (Value >> Shift));
            }

            return(Res);
        }
        public static AVec VectorInsertInt(ulong Value, AVec Vector, int Index, int Size)
        {
            switch (Size)
            {
            case 0: return(AVec.InsertByte(Vector, Index, (byte)Value));

            case 1: return(AVec.InsertUInt16(Vector, Index, (ushort)Value));

            case 2: return(AVec.InsertUInt32(Vector, Index, (uint)Value));

            case 3: return(AVec.InsertUInt64(Vector, Index, (ulong)Value));
            }

            throw new ArgumentOutOfRangeException(nameof(Size));
        }
        public static long VectorExtractIntSx(AVec Vector, int Index, int Size)
        {
            switch (Size)
            {
            case 0: return((sbyte)Vector.ExtractByte(Index));

            case 1: return((short)Vector.ExtractUInt16(Index));

            case 2: return((int)Vector.ExtractUInt32(Index));

            case 3: return((long)Vector.ExtractUInt64(Index));
            }

            throw new ArgumentOutOfRangeException(nameof(Size));
        }
Exemple #22
0
        public void Zip2_V(uint Q, uint size, ulong Result_0, ulong Result_1)
        {
            // ZIP2 V0.<T>, V1.<T>, V2.<T>
            uint Opcode = 0x0E027820 | (Q << 30) | (size << 22);
            AVec V1     = new AVec {
                X0 = 0x1716151413121110, X1 = 0x1F1E1D1C1B1A1918
            };
            AVec V2 = new AVec {
                X0 = 0x2726252423222120, X1 = 0x2F2E2D2C2B2A2928
            };
            AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);

            Assert.AreEqual(Result_0, ThreadState.V0.X0);
            Assert.AreEqual(Result_1, ThreadState.V0.X1);
        }
        private static AVec Sshr(AVec Vector, int Shift, int Size, int Bytes)
        {
            AVec Res = new AVec();

            int Elems = Bytes >> Size;

            for (int Index = 0; Index < Elems; Index++)
            {
                long Value = ExtractSVec(Vector, Index, Size);

                Res = InsertSVec(Res, Index, Size, Value >> Shift);
            }

            return(Res);
        }
        public void Frinta_S(uint A, bool DefaultNaN, uint Result)
        {
            int FpcrTemp = 0x0;

            if (DefaultNaN)
            {
                FpcrTemp = 0x2000000;
            }
            AVec V1 = new AVec {
                X0 = A
            };
            AThreadState ThreadState = SingleOpcode(0x1E264020, V1: V1, Fpcr: FpcrTemp);

            Assert.AreEqual(Result, ThreadState.V0.X0);
        }
        public static ulong ExtractVec(AVec Vector, int Index, int Size)
        {
            switch (Size)
            {
            case 0: return(Vector.ExtractByte(Index));

            case 1: return(Vector.ExtractUInt16(Index));

            case 2: return(Vector.ExtractUInt32(Index));

            case 3: return(Vector.ExtractUInt64(Index));
            }

            throw new ArgumentOutOfRangeException(nameof(Size));
        }
        public static AVec Cnt64(AVec Vector)
        {
            AVec Res = new AVec();

            Res.B0 = (byte)CountSetBits8(Vector.B0);
            Res.B1 = (byte)CountSetBits8(Vector.B1);
            Res.B2 = (byte)CountSetBits8(Vector.B2);
            Res.B3 = (byte)CountSetBits8(Vector.B3);
            Res.B4 = (byte)CountSetBits8(Vector.B4);
            Res.B5 = (byte)CountSetBits8(Vector.B5);
            Res.B6 = (byte)CountSetBits8(Vector.B6);
            Res.B7 = (byte)CountSetBits8(Vector.B7);

            return(Res);
        }
Exemple #27
0
 protected void SetThreadState(ulong X0      = 0, ulong X1            = 0, ulong X2 = 0, ulong X31 = 0,
                               AVec V0       = default(AVec), AVec V1 = default(AVec), AVec V2 = default(AVec),
                               bool Overflow = false, bool Carry      = false, bool Zero       = false, bool Negative = false)
 {
     Thread.ThreadState.X0       = X0;
     Thread.ThreadState.X1       = X1;
     Thread.ThreadState.X2       = X2;
     Thread.ThreadState.X31      = X31;
     Thread.ThreadState.V0       = V0;
     Thread.ThreadState.V1       = V1;
     Thread.ThreadState.V2       = V2;
     Thread.ThreadState.Overflow = Overflow;
     Thread.ThreadState.Carry    = Carry;
     Thread.ThreadState.Zero     = Zero;
     Thread.ThreadState.Negative = Negative;
 }
        public void Add_V(uint Opcode, ulong A0, ulong A1, ulong B0, ulong B1, ulong Result0, ulong Result1)
        {
            AVec V1 = new AVec {
                X0 = A0, X1 = A1
            };
            AVec V2 = new AVec {
                X0 = B0, X1 = B1
            };
            AThreadState ThreadState = SingleOpcode(Opcode, V1: V1, V2: V2);

            Assert.Multiple(() =>
            {
                Assert.AreEqual(Result0, ThreadState.V0.X0);
                Assert.AreEqual(Result1, ThreadState.V0.X1);
            });
        }
        private static AVec Sshll_(AVec Vector, int Shift, int Size, bool High)
        {
            AVec Res = new AVec();

            int Elems = 8 >> Size;
            int Part  = High ? Elems : 0;

            for (int Index = 0; Index < Elems; Index++)
            {
                long Value = ExtractSVec(Vector, Index + Part, Size);

                Res = InsertSVec(Res, Index, Size + 1, Value << Shift);
            }

            return(Res);
        }
        private static AVec Xtn_(AVec Vector, int Size, bool High)
        {
            AVec Res = new AVec();

            int Elems = 8 >> Size;
            int Part  = High ? Elems : 0;

            for (int Index = 0; Index < Elems; Index++)
            {
                ulong Value = ExtractVec(Vector, Index, Size + 1);

                Res = InsertVec(Res, Index + Part, Size, Value);
            }

            return(Res);
        }