mirror of
https://github.com/Ryujinx/ChocolArm64.git
synced 2024-12-22 19:15:38 +00:00
Add MUL (vector by element), fix FCVTN, make svcs use MakeError too
This commit is contained in:
parent
3860ba6521
commit
3020de224e
|
@ -183,7 +183,7 @@ namespace ChocolArm64
|
|||
Set("000111100x1xxxxx010110xxxxxxxxxx", AInstEmit.Fmin_S, typeof(AOpCodeSimdReg));
|
||||
Set("000111100x1xxxxx011110xxxxxxxxxx", AInstEmit.Fminnm_S, typeof(AOpCodeSimdReg));
|
||||
Set("0>0011100<1xxxxx110011xxxxxxxxxx", AInstEmit.Fmla_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x0011111<<xxxxx0001x0xxxxxxxxxx", AInstEmit.Fmla_Ve, typeof(AOpCodeSimdRegElem));
|
||||
Set("0x0011111<<xxxxx0001x0xxxxxxxxxx", AInstEmit.Fmla_Ve, typeof(AOpCodeSimdRegElemF));
|
||||
Set("000111100x100000010000xxxxxxxxxx", AInstEmit.Fmov_S, typeof(AOpCodeSimd));
|
||||
Set("00011110xx1xxxxxxxx100xxxxxxxxxx", AInstEmit.Fmov_Si, typeof(AOpCodeSimdFmov));
|
||||
Set("0xx0111100000xxx111101xxxxxxxxxx", AInstEmit.Fmov_V, typeof(AOpCodeSimdImm));
|
||||
|
@ -194,7 +194,7 @@ namespace ChocolArm64
|
|||
Set("000111110x0xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Fmsub_S, typeof(AOpCodeSimdReg));
|
||||
Set("000111100x1xxxxx000010xxxxxxxxxx", AInstEmit.Fmul_S, typeof(AOpCodeSimdReg));
|
||||
Set("0>1011100<1xxxxx110111xxxxxxxxxx", AInstEmit.Fmul_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x0011111<<xxxxx1001x0xxxxxxxxxx", AInstEmit.Fmul_Ve, typeof(AOpCodeSimdRegElem));
|
||||
Set("0x0011111<<xxxxx1001x0xxxxxxxxxx", AInstEmit.Fmul_Ve, typeof(AOpCodeSimdRegElemF));
|
||||
Set("000111100x100001010000xxxxxxxxxx", AInstEmit.Fneg_S, typeof(AOpCodeSimdReg));
|
||||
Set("000111110x1xxxxx1xxxxxxxxxxxxxxx", AInstEmit.Fnmsub_S, typeof(AOpCodeSimdReg));
|
||||
Set("000111100x1xxxxx100010xxxxxxxxxx", AInstEmit.Fnmul_S, typeof(AOpCodeSimdReg));
|
||||
|
@ -225,6 +225,7 @@ namespace ChocolArm64
|
|||
Set("0x00111100000xxx110x01xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
|
||||
Set("0xx0111100000xxx111001xxxxxxxxxx", AInstEmit.Movi_V, typeof(AOpCodeSimdImm));
|
||||
Set("0x001110<<1xxxxx100111xxxxxxxxxx", AInstEmit.Mul_V, typeof(AOpCodeSimdReg));
|
||||
Set("0x001111xxxxxxxx1000x0xxxxxxxxxx", AInstEmit.Mul_Ve, typeof(AOpCodeSimdRegElem));
|
||||
Set("0x10111100000xxx0xx001xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm));
|
||||
Set("0x10111100000xxx10x001xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm));
|
||||
Set("0x10111100000xxx110x01xxxxxxxxxx", AInstEmit.Mvni_V, typeof(AOpCodeSimdImm));
|
||||
|
|
|
@ -4,9 +4,9 @@ namespace ChocolArm64.Decoder
|
|||
{
|
||||
class AOpCodeSimdReg : AOpCodeSimd
|
||||
{
|
||||
public bool Bit3 { get; private set; }
|
||||
public int Ra { get; private set; }
|
||||
public int Rm { get; private set; }
|
||||
public bool Bit3 { get; private set; }
|
||||
public int Ra { get; private set; }
|
||||
public int Rm { get; protected set; }
|
||||
|
||||
public AOpCodeSimdReg(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
|
|
|
@ -8,15 +8,27 @@ namespace ChocolArm64.Decoder
|
|||
|
||||
public AOpCodeSimdRegElem(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
if ((Size & 1) != 0)
|
||||
switch (Size)
|
||||
{
|
||||
Index = (OpCode >> 11) & 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Index = (OpCode >> 21) & 1 |
|
||||
(OpCode >> 10) & 2;
|
||||
case 1:
|
||||
Index = (OpCode >> 21) & 1 |
|
||||
(OpCode >> 10) & 2 |
|
||||
(OpCode >> 18) & 4;
|
||||
|
||||
Rm &= 0xf;
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
Index = (OpCode >> 21) & 1 |
|
||||
(OpCode >> 10) & 2;
|
||||
|
||||
break;
|
||||
|
||||
default: Emitter = AInstEmit.Und; return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
22
Decoder/AOpCodeSimdRegElemF.cs
Normal file
22
Decoder/AOpCodeSimdRegElemF.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using ChocolArm64.Instruction;
|
||||
|
||||
namespace ChocolArm64.Decoder
|
||||
{
|
||||
class AOpCodeSimdRegElemF : AOpCodeSimdReg
|
||||
{
|
||||
public int Index { get; private set; }
|
||||
|
||||
public AOpCodeSimdRegElemF(AInst Inst, long Position, int OpCode) : base(Inst, Position, OpCode)
|
||||
{
|
||||
if ((Size & 1) != 0)
|
||||
{
|
||||
Index = (OpCode >> 11) & 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Index = (OpCode >> 21) & 1 |
|
||||
(OpCode >> 10) & 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -341,6 +341,11 @@ namespace ChocolArm64.Instruction
|
|||
EmitVectorBinaryOpZx(Context, () => Context.Emit(OpCodes.Mul));
|
||||
}
|
||||
|
||||
public static void Mul_Ve(AILEmitterCtx Context)
|
||||
{
|
||||
EmitVectorBinaryOpByElemZx(Context, () => Context.Emit(OpCodes.Mul));
|
||||
}
|
||||
|
||||
public static void Neg_V(AILEmitterCtx Context)
|
||||
{
|
||||
EmitVectorUnaryOpSx(Context, () => Context.Emit(OpCodes.Neg));
|
||||
|
|
|
@ -99,6 +99,11 @@ namespace ChocolArm64.Instruction
|
|||
EmitVectorInsertF(Context, Op.Rd, Part + Index, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (Op.RegisterSize == ARegisterSize.SIMD64)
|
||||
{
|
||||
EmitVectorZeroUpper(Context, Op.Rd);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Fcvtps_Gp(AILEmitterCtx Context)
|
||||
|
|
|
@ -200,20 +200,6 @@ namespace ChocolArm64.Instruction
|
|||
EmitVectorOpF(Context, Emit, OperFlags.RdRnRm);
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpByElemF(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
AOpCodeSimdRegElem Op = (AOpCodeSimdRegElem)Context.CurrOp;
|
||||
|
||||
EmitVectorOpByElemF(Context, Emit, Op.Index, Ternary: false);
|
||||
}
|
||||
|
||||
public static void EmitVectorTernaryOpByElemF(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
AOpCodeSimdRegElem Op = (AOpCodeSimdRegElem)Context.CurrOp;
|
||||
|
||||
EmitVectorOpByElemF(Context, Emit, Op.Index, Ternary: true);
|
||||
}
|
||||
|
||||
public static void EmitVectorOpF(AILEmitterCtx Context, Action Emit, OperFlags Opers)
|
||||
{
|
||||
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
||||
|
@ -250,6 +236,20 @@ namespace ChocolArm64.Instruction
|
|||
}
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpByElemF(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
AOpCodeSimdRegElemF Op = (AOpCodeSimdRegElemF)Context.CurrOp;
|
||||
|
||||
EmitVectorOpByElemF(Context, Emit, Op.Index, Ternary: false);
|
||||
}
|
||||
|
||||
public static void EmitVectorTernaryOpByElemF(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
AOpCodeSimdRegElemF Op = (AOpCodeSimdRegElemF)Context.CurrOp;
|
||||
|
||||
EmitVectorOpByElemF(Context, Emit, Op.Index, Ternary: true);
|
||||
}
|
||||
|
||||
public static void EmitVectorOpByElemF(AILEmitterCtx Context, Action Emit, int Elem, bool Ternary)
|
||||
{
|
||||
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
||||
|
@ -341,6 +341,54 @@ namespace ChocolArm64.Instruction
|
|||
}
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpByElemSx(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
AOpCodeSimdRegElem Op = (AOpCodeSimdRegElem)Context.CurrOp;
|
||||
|
||||
EmitVectorOpByElem(Context, Emit, Op.Index, false, true);
|
||||
}
|
||||
|
||||
public static void EmitVectorBinaryOpByElemZx(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
AOpCodeSimdRegElem Op = (AOpCodeSimdRegElem)Context.CurrOp;
|
||||
|
||||
EmitVectorOpByElem(Context, Emit, Op.Index, false, false);
|
||||
}
|
||||
|
||||
public static void EmitVectorTernaryOpByElemZx(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
AOpCodeSimdRegElem Op = (AOpCodeSimdRegElem)Context.CurrOp;
|
||||
|
||||
EmitVectorOpByElem(Context, Emit, Op.Index, true, false);
|
||||
}
|
||||
|
||||
public static void EmitVectorOpByElem(AILEmitterCtx Context, Action Emit, int Elem, bool Ternary, bool Signed)
|
||||
{
|
||||
AOpCodeSimdReg Op = (AOpCodeSimdReg)Context.CurrOp;
|
||||
|
||||
int Bytes = Context.CurrOp.GetBitsCount() >> 3;
|
||||
|
||||
for (int Index = 0; Index < (Bytes >> Op.Size); Index++)
|
||||
{
|
||||
if (Ternary)
|
||||
{
|
||||
EmitVectorExtract(Context, Op.Rd, Index, Op.Size, Signed);
|
||||
}
|
||||
|
||||
EmitVectorExtract(Context, Op.Rn, Index, Op.Size, Signed);
|
||||
EmitVectorExtract(Context, Op.Rm, Index, Op.Size, Signed);
|
||||
|
||||
Emit();
|
||||
|
||||
EmitVectorInsert(Context, Op.Rd, Index, Op.Size);
|
||||
}
|
||||
|
||||
if (Op.RegisterSize == ARegisterSize.SIMD64)
|
||||
{
|
||||
EmitVectorZeroUpper(Context, Op.Rd);
|
||||
}
|
||||
}
|
||||
|
||||
public static void EmitVectorImmUnaryOp(AILEmitterCtx Context, Action Emit)
|
||||
{
|
||||
EmitVectorImmOp(Context, Emit, false);
|
||||
|
|
Loading…
Reference in a new issue