|
|
@@ -279,106 +279,7 @@ namespace ChocolArm64.Instruction
|
|
|
return InsertVec(new AVec(), 0, Size, Low + High);
|
|
|
}
|
|
|
|
|
|
- public static AVec Addp64(AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Addp(LHS, RHS, Size, 8);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Addp128(AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Addp(LHS, RHS, Size, 16);
|
|
|
- }
|
|
|
-
|
|
|
- private static AVec Addp(AVec LHS, AVec RHS, int Size, int Bytes)
|
|
|
- {
|
|
|
- AVec Res = new AVec();
|
|
|
-
|
|
|
- int Elems = Bytes >> Size;
|
|
|
- int Half = Elems >> 1;
|
|
|
-
|
|
|
- for (int Index = 0; Index < Elems; Index++)
|
|
|
- {
|
|
|
- int Elem = (Index & (Half - 1)) << 1;
|
|
|
-
|
|
|
- ulong L = Index < Half
|
|
|
- ? ExtractVec(LHS, Elem + 0, Size)
|
|
|
- : ExtractVec(RHS, Elem + 0, Size);
|
|
|
-
|
|
|
- ulong R = Index < Half
|
|
|
- ? ExtractVec(LHS, Elem + 1, Size)
|
|
|
- : ExtractVec(RHS, Elem + 1, Size);
|
|
|
-
|
|
|
- Res = InsertVec(Res, Index, Size, L + R);
|
|
|
- }
|
|
|
-
|
|
|
- return Res;
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Bic_Vi64(AVec Res, ulong Imm, int Size)
|
|
|
- {
|
|
|
- return Bic_Vi(Res, Imm, Size, 8);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Bic_Vi128(AVec Res, ulong Imm, int Size)
|
|
|
- {
|
|
|
- return Bic_Vi(Res, Imm, Size, 16);
|
|
|
- }
|
|
|
-
|
|
|
- private static AVec Bic_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;
|
|
|
- }
|
|
|
-
|
|
|
- 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;
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Cnt128(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);
|
|
|
- Res.B8 = (byte)CountSetBits8(Vector.B8);
|
|
|
- Res.B9 = (byte)CountSetBits8(Vector.B9);
|
|
|
- Res.B10 = (byte)CountSetBits8(Vector.B10);
|
|
|
- Res.B11 = (byte)CountSetBits8(Vector.B11);
|
|
|
- Res.B12 = (byte)CountSetBits8(Vector.B12);
|
|
|
- Res.B13 = (byte)CountSetBits8(Vector.B13);
|
|
|
- Res.B14 = (byte)CountSetBits8(Vector.B14);
|
|
|
- Res.B15 = (byte)CountSetBits8(Vector.B15);
|
|
|
-
|
|
|
- return Res;
|
|
|
- }
|
|
|
-
|
|
|
- private static int CountSetBits8(byte Value)
|
|
|
+ public static int CountSetBits8(byte Value)
|
|
|
{
|
|
|
return (Value >> 0) & 1 + (Value >> 1) & 1 +
|
|
|
(Value >> 2) & 1 + (Value >> 3) & 1 +
|
|
|
@@ -413,248 +314,11 @@ namespace ChocolArm64.Instruction
|
|
|
return InsertVec(new AVec(), 0, Size, ExtractVec(Vector, Elem, Size));
|
|
|
}
|
|
|
|
|
|
- public static AVec Dup_V64(AVec Vector, int Elem, int Size)
|
|
|
- {
|
|
|
- return Dup_V(Vector, Elem, Size, 8);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Dup_V128(AVec Vector, int Elem, int Size)
|
|
|
- {
|
|
|
- return Dup_V(Vector, Elem, Size, 16);
|
|
|
- }
|
|
|
-
|
|
|
- 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;
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Fmla64(AVec Res, AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Fmla(Res, LHS, RHS, Size, 2);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Fmla128(AVec Res, AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Fmla(Res, LHS, RHS, Size, 4);
|
|
|
- }
|
|
|
-
|
|
|
- private static AVec Fmla(AVec Res, AVec LHS, AVec RHS, int Size, int Bytes)
|
|
|
- {
|
|
|
- int Elems = Bytes >> Size;
|
|
|
-
|
|
|
- if (Size == 0)
|
|
|
- {
|
|
|
- for (int Index = 0; Index < Elems; Index++)
|
|
|
- {
|
|
|
- float L = LHS.ExtractSingle(Index);
|
|
|
- float R = RHS.ExtractSingle(Index);
|
|
|
- float Addend = Res.ExtractSingle(Index);
|
|
|
-
|
|
|
- Res = AVec.InsertSingle(Res, Index, Addend + L * R);
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- for (int Index = 0; Index < Elems; Index++)
|
|
|
- {
|
|
|
- double L = LHS.ExtractDouble(Index);
|
|
|
- double R = RHS.ExtractDouble(Index);
|
|
|
- double Addend = Res.ExtractDouble(Index);
|
|
|
-
|
|
|
- Res = AVec.InsertDouble(Res, Index, Addend + L * R);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return Res;
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Fmla_Ve64(AVec Res, AVec LHS, AVec RHS, int SIdx, int Size)
|
|
|
- {
|
|
|
- return Fmla_Ve(Res, LHS, RHS, SIdx, Size, 2);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Fmla_Ve128(AVec Res, AVec LHS, AVec RHS, int SIdx, int Size)
|
|
|
- {
|
|
|
- return Fmla_Ve(Res, LHS, RHS, SIdx, Size, 4);
|
|
|
- }
|
|
|
-
|
|
|
- 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 static AVec Fmov_S(ulong Value, int Elem, int Size)
|
|
|
{
|
|
|
return InsertVec(new AVec(), Elem, Size, Value);
|
|
|
}
|
|
|
|
|
|
- public static AVec Fmul_Ve64(AVec LHS, AVec RHS, int SIdx, int Size)
|
|
|
- {
|
|
|
- return Fmul_Ve(LHS, RHS, SIdx, Size, 2);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Fmul_Ve128(AVec LHS, AVec RHS, int SIdx, int Size)
|
|
|
- {
|
|
|
- return Fmul_Ve(LHS, RHS, SIdx, Size, 4);
|
|
|
- }
|
|
|
-
|
|
|
- private static AVec Fmul_Ve(AVec LHS, AVec RHS, int SIdx, int Size, int Bytes)
|
|
|
- {
|
|
|
- AVec Res = new AVec();
|
|
|
-
|
|
|
- int Elems = Bytes >> Size;
|
|
|
-
|
|
|
- if (Size == 0)
|
|
|
- {
|
|
|
- float R = RHS.ExtractSingle(SIdx);
|
|
|
-
|
|
|
- for (int Index = 0; Index < Elems; Index++)
|
|
|
- {
|
|
|
- float L = LHS.ExtractSingle(Index);
|
|
|
-
|
|
|
- Res = AVec.InsertSingle(Res, Index, L * R);
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- double R = RHS.ExtractDouble(SIdx);
|
|
|
-
|
|
|
- for (int Index = 0; Index < Elems; Index++)
|
|
|
- {
|
|
|
- double L = LHS.ExtractDouble(Index);
|
|
|
-
|
|
|
- Res = AVec.InsertDouble(Res, Index, L * R);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return Res;
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Ins_Gp(AVec Res, ulong Value, int Elem, int Size)
|
|
|
- {
|
|
|
- return InsertVec(Res, Elem, Size, Value);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Ins_V(AVec Res, AVec Value, int Src, int Dst, int Size)
|
|
|
- {
|
|
|
- return InsertVec(Res, Dst, Size, ExtractVec(Value, Src, Size));;
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Orr_Vi64(AVec Res, ulong Imm, int Size)
|
|
|
- {
|
|
|
- return Orr_Vi(Res, Imm, Size, 8);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Orr_Vi128(AVec Res, ulong Imm, int Size)
|
|
|
- {
|
|
|
- return Orr_Vi(Res, Imm, Size, 16);
|
|
|
- }
|
|
|
-
|
|
|
- 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;
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Saddw(AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Saddw_(LHS, RHS, Size, false);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Saddw2(AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Saddw_(LHS, RHS, Size, true);
|
|
|
- }
|
|
|
-
|
|
|
- private static AVec Saddw_(AVec LHS, AVec RHS, 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 L = ExtractSVec(LHS, Index, Size + 1);
|
|
|
- long R = ExtractSVec(RHS, Index + Part, Size);
|
|
|
-
|
|
|
- Res = InsertSVec(Res, Index, Size + 1, L + R);
|
|
|
- }
|
|
|
-
|
|
|
- return Res;
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Sshll(AVec Vector, int Shift, int Size)
|
|
|
- {
|
|
|
- return Sshll_(Vector, Shift, Size, false);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Sshll2(AVec Vector, int Shift, int Size)
|
|
|
- {
|
|
|
- return Sshll_(Vector, Shift, Size, true);
|
|
|
- }
|
|
|
-
|
|
|
- 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;
|
|
|
- }
|
|
|
-
|
|
|
public static AVec Tbl1_V64(AVec Vector, AVec Tb0)
|
|
|
{
|
|
|
return Tbl(Vector, 8, Tb0);
|
|
|
@@ -720,173 +384,6 @@ namespace ChocolArm64.Instruction
|
|
|
return Res;
|
|
|
}
|
|
|
|
|
|
- public static AVec Uaddlv64(AVec Vector, int Size)
|
|
|
- {
|
|
|
- return Uaddlv(Vector, Size, 8);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Uaddlv128(AVec Vector, int Size)
|
|
|
- {
|
|
|
- return Uaddlv(Vector, Size, 16);
|
|
|
- }
|
|
|
-
|
|
|
- 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);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Uaddw(AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Uaddw_(LHS, RHS, Size, false);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Uaddw2(AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Uaddw_(LHS, RHS, Size, true);
|
|
|
- }
|
|
|
-
|
|
|
- private static AVec Uaddw_(AVec LHS, AVec RHS, 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 L = ExtractVec(LHS, Index, Size + 1);
|
|
|
- ulong R = ExtractVec(RHS, Index + Part, Size);
|
|
|
-
|
|
|
- Res = InsertVec(Res, Index, Size + 1, L + R);
|
|
|
- }
|
|
|
-
|
|
|
- return Res;
|
|
|
- }
|
|
|
-
|
|
|
- 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
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Ucvtf_V_D(AVec Vector)
|
|
|
- {
|
|
|
- return new AVec()
|
|
|
- {
|
|
|
- D0 = (ulong)Vector.X0,
|
|
|
- D1 = (ulong)Vector.X1
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Ushll(AVec Vector, int Shift, int Size)
|
|
|
- {
|
|
|
- return Ushll_(Vector, Shift, Size, false);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Ushll2(AVec Vector, int Shift, int Size)
|
|
|
- {
|
|
|
- return Ushll_(Vector, Shift, Size, true);
|
|
|
- }
|
|
|
-
|
|
|
- private static AVec Ushll_(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++)
|
|
|
- {
|
|
|
- ulong Value = ExtractVec(Vector, Index + Part, Size);
|
|
|
-
|
|
|
- Res = InsertVec(Res, Index, Size + 1, Value << Shift);
|
|
|
- }
|
|
|
-
|
|
|
- return Res;
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Uzp1_V64(AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Uzp(LHS, RHS, Size, 0, 8);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Uzp1_V128(AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Uzp(LHS, RHS, Size, 0, 16);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Uzp2_V64(AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Uzp(LHS, RHS, Size, 1, 8);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Uzp2_V128(AVec LHS, AVec RHS, int Size)
|
|
|
- {
|
|
|
- return Uzp(LHS, RHS, Size, 1, 16);
|
|
|
- }
|
|
|
-
|
|
|
- private static AVec Uzp(AVec LHS, AVec RHS, int Size, int Part, int Bytes)
|
|
|
- {
|
|
|
- AVec Res = new AVec();
|
|
|
-
|
|
|
- int Elems = Bytes >> Size;
|
|
|
- int Half = Elems >> 1;
|
|
|
-
|
|
|
- for (int Index = 0; Index < Elems; Index++)
|
|
|
- {
|
|
|
- int Elem = (Index & (Half - 1)) << 1;
|
|
|
-
|
|
|
- ulong Value = Index < Half
|
|
|
- ? ExtractVec(LHS, Elem + Part, Size)
|
|
|
- : ExtractVec(RHS, Elem + Part, Size);
|
|
|
-
|
|
|
- Res = InsertVec(Res, Index, Size, Value);
|
|
|
- }
|
|
|
-
|
|
|
- return Res;
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Xtn(AVec Vector, int Size)
|
|
|
- {
|
|
|
- return Xtn_(Vector, Size, false);
|
|
|
- }
|
|
|
-
|
|
|
- public static AVec Xtn2(AVec Vector, int Size)
|
|
|
- {
|
|
|
- return Xtn_(Vector, Size, true);
|
|
|
- }
|
|
|
-
|
|
|
- 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;
|
|
|
- }
|
|
|
-
|
|
|
public static ulong ExtractVec(AVec Vector, int Index, int Size)
|
|
|
{
|
|
|
switch (Size)
|