forked from Mirror/Ryujinx
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
|
@ -152,13 +152,13 @@ namespace ChocolArm64
|
||||||
Set("x0011110xx110000000000xxxxxxxxxx", AInstEmit.Fcvtms_S, typeof(AOpCodeSimdCvt));
|
Set("x0011110xx110000000000xxxxxxxxxx", AInstEmit.Fcvtms_S, typeof(AOpCodeSimdCvt));
|
||||||
Set("x0011110xx101000000000xxxxxxxxxx", AInstEmit.Fcvtps_S, typeof(AOpCodeSimdCvt));
|
Set("x0011110xx101000000000xxxxxxxxxx", AInstEmit.Fcvtps_S, typeof(AOpCodeSimdCvt));
|
||||||
Set("x0011110xx111000000000xxxxxxxxxx", AInstEmit.Fcvtzs_S, typeof(AOpCodeSimdCvt));
|
Set("x0011110xx111000000000xxxxxxxxxx", AInstEmit.Fcvtzs_S, typeof(AOpCodeSimdCvt));
|
||||||
Set("0x0011101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzs_V, typeof(AOpCodeSimd));
|
|
||||||
Set("0x0011110>>xxxxx111111xxxxxxxxxx", AInstEmit.Fcvtzs_V_Fix, typeof(AOpCodeSimdShImm));
|
|
||||||
Set("x0011110xx111001000000xxxxxxxxxx", AInstEmit.Fcvtzu_S, typeof(AOpCodeSimdCvt));
|
|
||||||
Set("0x1011101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzu_V, typeof(AOpCodeSimd));
|
|
||||||
Set("0x1011110>>xxxxx111111xxxxxxxxxx", AInstEmit.Fcvtzu_V_Fix, typeof(AOpCodeSimdShImm));
|
|
||||||
Set("x0011110xx011000xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzs_Fix, typeof(AOpCodeSimdCvt));
|
Set("x0011110xx011000xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzs_Fix, typeof(AOpCodeSimdCvt));
|
||||||
|
Set("0x0011101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzs_V, typeof(AOpCodeSimd));
|
||||||
|
Set("0x0011110>>xxxxx111111xxxxxxxxxx", AInstEmit.Fcvtzs_V, typeof(AOpCodeSimdShImm));
|
||||||
|
Set("x0011110xx111001000000xxxxxxxxxx", AInstEmit.Fcvtzu_S, typeof(AOpCodeSimdCvt));
|
||||||
Set("x0011110xx011001xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzu_Fix, typeof(AOpCodeSimdCvt));
|
Set("x0011110xx011001xxxxxxxxxxxxxxxx", AInstEmit.Fcvtzu_Fix, typeof(AOpCodeSimdCvt));
|
||||||
|
Set("0x1011101x100001101110xxxxxxxxxx", AInstEmit.Fcvtzu_V, typeof(AOpCodeSimd));
|
||||||
|
Set("0x1011110>>xxxxx111111xxxxxxxxxx", AInstEmit.Fcvtzu_V, typeof(AOpCodeSimdShImm));
|
||||||
Set("00011110xx1xxxxx000110xxxxxxxxxx", AInstEmit.Fdiv_S, typeof(AOpCodeSimdReg));
|
Set("00011110xx1xxxxx000110xxxxxxxxxx", AInstEmit.Fdiv_S, typeof(AOpCodeSimdReg));
|
||||||
Set("00011111xx0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Fmadd_S, typeof(AOpCodeSimdReg));
|
Set("00011111xx0xxxxx0xxxxxxxxxxxxxxx", AInstEmit.Fmadd_S, typeof(AOpCodeSimdReg));
|
||||||
Set("00011110xx1xxxxx010010xxxxxxxxxx", AInstEmit.Fmax_S, typeof(AOpCodeSimdReg));
|
Set("00011110xx1xxxxx010010xxxxxxxxxx", AInstEmit.Fmax_S, typeof(AOpCodeSimdReg));
|
||||||
|
|
|
@ -1,26 +1,16 @@
|
||||||
using ChocolArm64.Instruction;
|
using ChocolArm64.Instruction;
|
||||||
using ChocolArm64.State;
|
|
||||||
|
|
||||||
namespace ChocolArm64.Decoder
|
namespace ChocolArm64.Decoder
|
||||||
{
|
{
|
||||||
class AOpCodeSimdShImm : AOpCode, IAOpCodeSimd
|
class AOpCodeSimdShImm : AOpCodeSimd
|
||||||
{
|
{
|
||||||
public int Rd { get; private set; }
|
public int Imm { get; private set; }
|
||||||
public int Rn { get; private set; }
|
|
||||||
public int Imm { get; private set; }
|
|
||||||
public int Size { get; private set; }
|
|
||||||
|
|
||||||
public AOpCodeSimdShImm(AInst Inst, long Position, int OpCode) : base(Inst, Position)
|
public AOpCodeSimdShImm(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||||
{
|
{
|
||||||
Rd = (OpCode >> 0) & 0x1f;
|
|
||||||
Rn = (OpCode >> 5) & 0x1f;
|
|
||||||
Imm = (OpCode >> 16) & 0x7f;
|
Imm = (OpCode >> 16) & 0x7f;
|
||||||
|
|
||||||
Size = ABitUtils.HighestBitSet32(Imm >> 3);
|
Size = ABitUtils.HighestBitSet32(Imm >> 3);
|
||||||
|
|
||||||
RegisterSize = ((OpCode >> 30) & 1) != 0
|
|
||||||
? ARegisterSize.SIMD128
|
|
||||||
: ARegisterSize.SIMD64;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -102,80 +102,10 @@ namespace ChocolArm64.Instruction
|
||||||
|
|
||||||
public static void Eor_V(AILEmitterCtx Context) => EmitVectorBinaryZx(Context, OpCodes.Xor);
|
public static void Eor_V(AILEmitterCtx Context) => EmitVectorBinaryZx(Context, OpCodes.Xor);
|
||||||
|
|
||||||
public static void Fadd_V(AILEmitterCtx Context)
|
public static void Fadd_V(AILEmitterCtx Context) => EmitVectorBinaryFOp(Context, OpCodes.Add);
|
||||||
{
|
|
||||||
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
|
||||||
|
|
||||||
Context.EmitLdvec(Op.Rn);
|
public static void Fcvtzs_V(AILEmitterCtx Context) => EmitVectorFcvtS(Context);
|
||||||
Context.EmitLdvec(Op.Rm);
|
public static void Fcvtzu_V(AILEmitterCtx Context) => EmitVectorFcvtU(Context);
|
||||||
Context.EmitLdc_I4(Op.SizeF);
|
|
||||||
|
|
||||||
ASoftFallback.EmitCall(Context,
|
|
||||||
nameof(ASoftFallback.Fadd64),
|
|
||||||
nameof(ASoftFallback.Fadd128));
|
|
||||||
|
|
||||||
Context.EmitStvec(Op.Rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Fcvtzs_V(AILEmitterCtx Context)
|
|
||||||
{
|
|
||||||
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
|
||||||
|
|
||||||
Context.EmitLdvec(Op.Rn);
|
|
||||||
Context.EmitLdc_I4(0);
|
|
||||||
Context.EmitLdc_I4(Op.SizeF);
|
|
||||||
|
|
||||||
ASoftFallback.EmitCall(Context,
|
|
||||||
nameof(ASoftFallback.Fcvtzs_V64),
|
|
||||||
nameof(ASoftFallback.Fcvtzs_V128));
|
|
||||||
|
|
||||||
Context.EmitStvec(Op.Rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Fcvtzs_V_Fix(AILEmitterCtx Context)
|
|
||||||
{
|
|
||||||
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
|
|
||||||
|
|
||||||
Context.EmitLdvec(Op.Rn);
|
|
||||||
Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm);
|
|
||||||
Context.EmitLdc_I4(Op.Size - 2);
|
|
||||||
|
|
||||||
ASoftFallback.EmitCall(Context,
|
|
||||||
nameof(ASoftFallback.Fcvtzs_V64),
|
|
||||||
nameof(ASoftFallback.Fcvtzs_V128));
|
|
||||||
|
|
||||||
Context.EmitStvec(Op.Rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Fcvtzu_V(AILEmitterCtx Context)
|
|
||||||
{
|
|
||||||
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
|
||||||
|
|
||||||
Context.EmitLdvec(Op.Rn);
|
|
||||||
Context.EmitLdc_I4(0);
|
|
||||||
Context.EmitLdc_I4(Op.SizeF);
|
|
||||||
|
|
||||||
ASoftFallback.EmitCall(Context,
|
|
||||||
nameof(ASoftFallback.Fcvtzu_V_64),
|
|
||||||
nameof(ASoftFallback.Fcvtzu_V_128));
|
|
||||||
|
|
||||||
Context.EmitStvec(Op.Rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Fcvtzu_V_Fix(AILEmitterCtx Context)
|
|
||||||
{
|
|
||||||
AOpCodeSimdShImm Op = (AOpCodeSimdShImm)Context.CurrOp;
|
|
||||||
|
|
||||||
Context.EmitLdvec(Op.Rn);
|
|
||||||
Context.EmitLdc_I4((8 << (Op.Size + 1)) - Op.Imm);
|
|
||||||
Context.EmitLdc_I4(Op.Size - 2);
|
|
||||||
|
|
||||||
ASoftFallback.EmitCall(Context,
|
|
||||||
nameof(ASoftFallback.Fcvtzu_V_64),
|
|
||||||
nameof(ASoftFallback.Fcvtzu_V_128));
|
|
||||||
|
|
||||||
Context.EmitStvec(Op.Rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Fmla_V(AILEmitterCtx Context)
|
public static void Fmla_V(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
|
@ -224,20 +154,7 @@ namespace ChocolArm64.Instruction
|
||||||
Context.EmitStvec(Op.Rd);
|
Context.EmitStvec(Op.Rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fmul_V(AILEmitterCtx Context)
|
public static void Fmul_V(AILEmitterCtx Context) => EmitVectorBinaryFOp(Context, OpCodes.Mul);
|
||||||
{
|
|
||||||
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
|
||||||
|
|
||||||
Context.EmitLdvec(Op.Rn);
|
|
||||||
Context.EmitLdvec(Op.Rm);
|
|
||||||
Context.EmitLdc_I4(Op.SizeF);
|
|
||||||
|
|
||||||
ASoftFallback.EmitCall(Context,
|
|
||||||
nameof(ASoftFallback.Fmul64),
|
|
||||||
nameof(ASoftFallback.Fmul128));
|
|
||||||
|
|
||||||
Context.EmitStvec(Op.Rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Fmul_Vs(AILEmitterCtx Context)
|
public static void Fmul_Vs(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
|
@ -255,20 +172,7 @@ namespace ChocolArm64.Instruction
|
||||||
Context.EmitStvec(Op.Rd);
|
Context.EmitStvec(Op.Rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Fsub_V(AILEmitterCtx Context)
|
public static void Fsub_V(AILEmitterCtx Context) => EmitVectorBinaryFOp(Context, OpCodes.Sub);
|
||||||
{
|
|
||||||
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
|
||||||
|
|
||||||
Context.EmitLdvec(Op.Rn);
|
|
||||||
Context.EmitLdvec(Op.Rm);
|
|
||||||
Context.EmitLdc_I4(Op.SizeF);
|
|
||||||
|
|
||||||
ASoftFallback.EmitCall(Context,
|
|
||||||
nameof(ASoftFallback.Fsub64),
|
|
||||||
nameof(ASoftFallback.Fsub128));
|
|
||||||
|
|
||||||
Context.EmitStvec(Op.Rd);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Ins_Gp(AILEmitterCtx Context)
|
public static void Ins_Gp(AILEmitterCtx Context)
|
||||||
{
|
{
|
||||||
|
@ -870,6 +774,114 @@ namespace ChocolArm64.Instruction
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EmitVectorFcvtS(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorCvtOp(Context, CvtDir.Fcvt, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EmitVectorFcvtU(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorCvtOp(Context, CvtDir.Fcvt, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EmitVectorCvtfS(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorCvtOp(Context, CvtDir.Cvtf, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EmitVectorCvtfU(AILEmitterCtx Context)
|
||||||
|
{
|
||||||
|
EmitVectorCvtOp(Context, CvtDir.Cvtf, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum CvtDir
|
||||||
|
{
|
||||||
|
Fcvt,
|
||||||
|
Cvtf
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EmitVectorCvtOp(AILEmitterCtx Context, CvtDir Dir, bool Signed)
|
||||||
|
{
|
||||||
|
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
|
||||||
|
|
||||||
|
int SizeF = Op.Size & 1;
|
||||||
|
int SizeI = SizeF + 2;
|
||||||
|
|
||||||
|
int FBits = 0;
|
||||||
|
|
||||||
|
if (Op is AOpCodeSimdShImm OpImm)
|
||||||
|
{
|
||||||
|
FBits = (8 << (Op.Size + 1)) - OpImm.Imm;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
||||||
|
|
||||||
|
for (int Index = 0; Index < (Bytes >> SizeI); Index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
|
||||||
|
|
||||||
|
Context.EmitLdc_I4(FBits);
|
||||||
|
|
||||||
|
if (Dir == CvtDir.Fcvt)
|
||||||
|
{
|
||||||
|
//Float to Integer.
|
||||||
|
if (SizeF == 0)
|
||||||
|
{
|
||||||
|
ASoftFallback.EmitCall(Context, Signed
|
||||||
|
? nameof(ASoftFallback.SatSingleToInt32)
|
||||||
|
: nameof(ASoftFallback.SatSingleToUInt32));
|
||||||
|
}
|
||||||
|
else if (SizeF == 1)
|
||||||
|
{
|
||||||
|
ASoftFallback.EmitCall(Context, Signed
|
||||||
|
? nameof(ASoftFallback.SatDoubleToInt64)
|
||||||
|
: nameof(ASoftFallback.SatDoubleToUInt64));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Dir == CvtDir.Cvtf)
|
||||||
|
{
|
||||||
|
//Integer to Float.
|
||||||
|
//TODO.
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitVectorInsert(Context, Op.Rd, Index, SizeI);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Op.RegisterSize == ARegisterSize.SIMD64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(Context, Op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EmitVectorBinaryFOp(AILEmitterCtx Context, OpCode ILOp)
|
||||||
|
{
|
||||||
|
EmitVectorBinaryFOp(Context, () => Context.Emit(ILOp));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EmitVectorBinaryFOp(AILEmitterCtx Context, Action Emit)
|
||||||
|
{
|
||||||
|
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
||||||
|
|
||||||
|
int SizeF = Op.Size & 1;
|
||||||
|
|
||||||
|
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
||||||
|
|
||||||
|
for (int Index = 0; Index < (Bytes >> SizeF + 2); Index++)
|
||||||
|
{
|
||||||
|
EmitVectorExtractF(Context, Op.Rn, Index, SizeF);
|
||||||
|
EmitVectorExtractF(Context, Op.Rm, Index, SizeF);
|
||||||
|
|
||||||
|
Emit();
|
||||||
|
|
||||||
|
EmitVectorInsertF(Context, Op.Rd, Index, SizeF);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Op.RegisterSize == ARegisterSize.SIMD64)
|
||||||
|
{
|
||||||
|
EmitVectorZeroUpper(Context, Op.Rd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void EmitVectorUnarySx(AILEmitterCtx Context, OpCode ILOp)
|
private static void EmitVectorUnarySx(AILEmitterCtx Context, OpCode ILOp)
|
||||||
{
|
{
|
||||||
EmitVectorUnarySx(Context, () => Context.Emit(ILOp));
|
EmitVectorUnarySx(Context, () => Context.Emit(ILOp));
|
||||||
|
@ -1047,6 +1059,25 @@ namespace ChocolArm64.Instruction
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EmitVectorExtractF(AILEmitterCtx Context, int Reg, int Index, int Size)
|
||||||
|
{
|
||||||
|
Context.EmitLdvec(Reg);
|
||||||
|
Context.EmitLdc_I4(Index);
|
||||||
|
|
||||||
|
if (Size == 0)
|
||||||
|
{
|
||||||
|
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.VectorExtractSingle));
|
||||||
|
}
|
||||||
|
else if (Size == 1)
|
||||||
|
{
|
||||||
|
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.VectorExtractDouble));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(Size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void EmitVectorExtractSx(AILEmitterCtx Context, int Reg, int Index)
|
private static void EmitVectorExtractSx(AILEmitterCtx Context, int Reg, int Index)
|
||||||
{
|
{
|
||||||
EmitVectorExtract(Context, Reg, Index, true);
|
EmitVectorExtract(Context, Reg, Index, true);
|
||||||
|
@ -1070,6 +1101,27 @@ namespace ChocolArm64.Instruction
|
||||||
: nameof(ASoftFallback.ExtractVec));
|
: nameof(ASoftFallback.ExtractVec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EmitVectorInsertF(AILEmitterCtx Context, int Reg, int Index, int Size)
|
||||||
|
{
|
||||||
|
Context.EmitLdvec(Reg);
|
||||||
|
Context.EmitLdc_I4(Index);
|
||||||
|
|
||||||
|
if (Size == 0)
|
||||||
|
{
|
||||||
|
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.VectorInsertSingle));
|
||||||
|
}
|
||||||
|
else if (Size == 1)
|
||||||
|
{
|
||||||
|
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.VectorInsertDouble));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(Size));
|
||||||
|
}
|
||||||
|
|
||||||
|
Context.EmitStvec(Reg);
|
||||||
|
}
|
||||||
|
|
||||||
private static void EmitVectorZeroLower(AILEmitterCtx Context, int Rd)
|
private static void EmitVectorZeroLower(AILEmitterCtx Context, int Rd)
|
||||||
{
|
{
|
||||||
EmitVectorInsert(Context, Rd, 0, 3, 0);
|
EmitVectorInsert(Context, Rd, 0, 3, 0);
|
||||||
|
@ -1080,6 +1132,17 @@ namespace ChocolArm64.Instruction
|
||||||
EmitVectorInsert(Context, Rd, 1, 3, 0);
|
EmitVectorInsert(Context, Rd, 1, 3, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void EmitVectorInsert(AILEmitterCtx Context, int Reg, int Index, int Size)
|
||||||
|
{
|
||||||
|
Context.EmitLdvec(Reg);
|
||||||
|
Context.EmitLdc_I4(Index);
|
||||||
|
Context.EmitLdc_I4(Size);
|
||||||
|
|
||||||
|
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.VectorInsertInt));
|
||||||
|
|
||||||
|
Context.EmitStvec(Reg);
|
||||||
|
}
|
||||||
|
|
||||||
private static void EmitVectorInsert(AILEmitterCtx Context, int Reg, int Index, int Size, long Value)
|
private static void EmitVectorInsert(AILEmitterCtx Context, int Reg, int Index, int Size, long Value)
|
||||||
{
|
{
|
||||||
Context.EmitLdvec(Reg);
|
Context.EmitLdvec(Reg);
|
||||||
|
|
|
@ -365,122 +365,6 @@ namespace ChocolArm64.Instruction
|
||||||
return Res;
|
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)
|
public static AVec Fmla64(AVec Res, AVec LHS, AVec RHS, int Size)
|
||||||
{
|
{
|
||||||
return Fmla(Res, LHS, RHS, Size, 2);
|
return Fmla(Res, LHS, RHS, Size, 2);
|
||||||
|
@ -568,46 +452,6 @@ namespace ChocolArm64.Instruction
|
||||||
return InsertVec(new AVec(), Elem, Size, Value);
|
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)
|
public static AVec Fmul_Ve64(AVec LHS, AVec RHS, int SIdx, int Size)
|
||||||
{
|
{
|
||||||
return Fmul_Ve(LHS, RHS, SIdx, Size, 2);
|
return Fmul_Ve(LHS, RHS, SIdx, Size, 2);
|
||||||
|
@ -650,46 +494,6 @@ namespace ChocolArm64.Instruction
|
||||||
return Res;
|
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)
|
public static AVec Ins_Gp(AVec Res, ulong Value, int Elem, int Size)
|
||||||
{
|
{
|
||||||
return InsertVec(Res, Elem, Size, Value);
|
return InsertVec(Res, Elem, Size, Value);
|
||||||
|
@ -1126,6 +930,39 @@ namespace ChocolArm64.Instruction
|
||||||
throw new ArgumentOutOfRangeException(nameof(Size));
|
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)
|
public static AVec InsertVec(AVec Vector, int Index, int Size, ulong Value)
|
||||||
{
|
{
|
||||||
switch (Size)
|
switch (Size)
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
using ChocolArm64.Exceptions;
|
|
||||||
using System;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace ChocolArm64.Memory
|
namespace ChocolArm64.Memory
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Ryujinx
|
namespace Ryujinx
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
using ChocolArm64.Memory;
|
using ChocolArm64.Memory;
|
||||||
|
using OpenTK.Audio;
|
||||||
|
using OpenTK.Audio.OpenAL;
|
||||||
using Ryujinx.OsHle.Handles;
|
using Ryujinx.OsHle.Handles;
|
||||||
using Ryujinx.OsHle.Ipc;
|
using Ryujinx.OsHle.Ipc;
|
||||||
using static Ryujinx.OsHle.Objects.ObjHelper;
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using OpenTK.Audio;
|
|
||||||
using OpenTK.Audio.OpenAL;
|
|
||||||
|
|
||||||
namespace Ryujinx.OsHle.Objects
|
namespace Ryujinx.OsHle.Objects
|
||||||
{
|
{
|
||||||
class AudIAudioOut
|
class AudIAudioOut
|
||||||
|
|
Reference in a new issue