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); }
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); }); }
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 }); }
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); }
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)); }
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); }
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); }