Move a few more SIMD instructions to emit CIL directly instead of a method call
This commit is contained in:
parent
12e263f8b2
commit
ccc9ce1908
7 changed files with 207 additions and 324 deletions
|
@ -365,122 +365,6 @@ namespace ChocolArm64.Instruction
|
|||
return Res;
|
||||
}
|
||||
|
||||
public static AVec Fadd64(AVec LHS, AVec RHS, int Size)
|
||||
{
|
||||
return Fadd(LHS, RHS, Size, 2);
|
||||
}
|
||||
|
||||
public static AVec Fadd128(AVec LHS, AVec RHS, int Size)
|
||||
{
|
||||
return Fadd(LHS, RHS, Size, 4);
|
||||
}
|
||||
|
||||
private static AVec Fadd(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;
|
||||
}
|
||||
|
||||
public static AVec Fcvtzs_V64(AVec Vector, int FBits, int Size)
|
||||
{
|
||||
return Fcvtzs_V(Vector, FBits, Size, 2);
|
||||
}
|
||||
|
||||
public static AVec Fcvtzs_V128(AVec Vector, int FBits, int Size)
|
||||
{
|
||||
return Fcvtzs_V(Vector, FBits, Size, 4);
|
||||
}
|
||||
|
||||
private static AVec Fcvtzs_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 = InsertSVec(Res, Index, Size + 2, SatSingleToInt32(Value, FBits));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int Index = 0; Index < Elems; Index++)
|
||||
{
|
||||
double Value = Vector.ExtractDouble(Index);
|
||||
|
||||
Res = InsertSVec(Res, Index, Size + 2, SatDoubleToInt64(Value, FBits));
|
||||
}
|
||||
}
|
||||
|
||||
return Res;
|
||||
}
|
||||
|
||||
public static AVec Fcvtzu_V_64(AVec Vector, int FBits, int Size)
|
||||
{
|
||||
return Fcvtzu_V(Vector, FBits, Size, 2);
|
||||
}
|
||||
|
||||
public static AVec Fcvtzu_V_128(AVec Vector, int FBits, int Size)
|
||||
{
|
||||
return Fcvtzu_V(Vector, FBits, Size, 4);
|
||||
}
|
||||
|
||||
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 Fmla64(AVec Res, AVec LHS, AVec RHS, int Size)
|
||||
{
|
||||
return Fmla(Res, LHS, RHS, Size, 2);
|
||||
|
@ -568,46 +452,6 @@ namespace ChocolArm64.Instruction
|
|||
return InsertVec(new AVec(), Elem, Size, Value);
|
||||
}
|
||||
|
||||
public static AVec Fmul64(AVec LHS, AVec RHS, int Size)
|
||||
{
|
||||
return Fmul(LHS, RHS, Size, 2);
|
||||
}
|
||||
|
||||
public static AVec Fmul128(AVec LHS, AVec RHS, int Size)
|
||||
{
|
||||
return Fmul(LHS, RHS, Size, 4);
|
||||
}
|
||||
|
||||
private static AVec Fmul(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;
|
||||
}
|
||||
|
||||
public static AVec Fmul_Ve64(AVec LHS, AVec RHS, int SIdx, int Size)
|
||||
{
|
||||
return Fmul_Ve(LHS, RHS, SIdx, Size, 2);
|
||||
|
@ -650,46 +494,6 @@ namespace ChocolArm64.Instruction
|
|||
return Res;
|
||||
}
|
||||
|
||||
public static AVec Fsub64(AVec LHS, AVec RHS, int Size)
|
||||
{
|
||||
return Fsub(LHS, RHS, Size, 2);
|
||||
}
|
||||
|
||||
public static AVec Fsub128(AVec LHS, AVec RHS, int Size)
|
||||
{
|
||||
return Fsub(LHS, RHS, Size, 4);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public static AVec Ins_Gp(AVec Res, ulong Value, int Elem, int Size)
|
||||
{
|
||||
return InsertVec(Res, Elem, Size, Value);
|
||||
|
@ -1126,6 +930,39 @@ namespace ChocolArm64.Instruction
|
|||
throw new ArgumentOutOfRangeException(nameof(Size));
|
||||
}
|
||||
|
||||
public static float VectorExtractSingle(AVec Vector, int Index)
|
||||
{
|
||||
return Vector.ExtractSingle(Index);
|
||||
}
|
||||
|
||||
public static double VectorExtractDouble(AVec Vector, int Index)
|
||||
{
|
||||
return Vector.ExtractDouble(Index);
|
||||
}
|
||||
|
||||
public static AVec VectorInsertSingle(float Value, AVec Vector, int Index)
|
||||
{
|
||||
return AVec.InsertSingle(Vector, Index, Value);
|
||||
}
|
||||
|
||||
public static AVec VectorInsertDouble(double Value, AVec Vector, int Index)
|
||||
{
|
||||
return AVec.InsertDouble(Vector, Index, Value);
|
||||
}
|
||||
|
||||
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 AVec InsertVec(AVec Vector, int Index, int Size, ulong Value)
|
||||
{
|
||||
switch (Size)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue