Add FVCTZS (fixed point variant) and LD1 (single structure variant) instructions

This commit is contained in:
gdkchan 2018-02-09 00:26:20 -03:00
parent ebbccfcdbf
commit 6a3aa6cd88
9 changed files with 279 additions and 22 deletions

View file

@ -122,6 +122,7 @@ namespace ChocolArm64.Instruction
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;
Context.EmitLdvec(Op.Rn);
Context.EmitLdc_I4(0);
Context.EmitLdc_I4(Op.SizeF);
ASoftFallback.EmitCall(Context,
@ -131,6 +132,21 @@ namespace ChocolArm64.Instruction
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;
@ -283,7 +299,8 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Op.Rd);
}
public static void Ld__V(AILEmitterCtx Context) => EmitSimdMultLdSt(Context, IsLoad: true);
public static void Ld__Vms(AILEmitterCtx Context) => EmitSimdMemMs(Context, IsLoad: true);
public static void Ld__Vss(AILEmitterCtx Context) => EmitSimdMemSs(Context, IsLoad: true);
public static void Mla_V(AILEmitterCtx Context) => EmitVectorMla(Context);
@ -391,7 +408,7 @@ namespace ChocolArm64.Instruction
EmitVectorImmBinarySx(Context, OpCodes.Shr, (8 << (Op.Size + 1)) - Op.Imm);
}
public static void St__V(AILEmitterCtx Context) => EmitSimdMultLdSt(Context, IsLoad: false);
public static void St__V(AILEmitterCtx Context) => EmitSimdMemMs(Context, IsLoad: false);
public static void Sub_V(AILEmitterCtx Context) => EmitVectorBinaryZx(Context, OpCodes.Sub);
@ -571,9 +588,9 @@ namespace ChocolArm64.Instruction
Context.EmitStvec(Op.Rd);
}
private static void EmitSimdMultLdSt(AILEmitterCtx Context, bool IsLoad)
private static void EmitSimdMemMs(AILEmitterCtx Context, bool IsLoad)
{
AOpCodeSimdMemMult Op = (AOpCodeSimdMemMult)Context.CurrOp;
AOpCodeSimdMemMs Op = (AOpCodeSimdMemMs)Context.CurrOp;
int Offset = 0;
@ -644,6 +661,79 @@ namespace ChocolArm64.Instruction
}
}
private static void EmitSimdMemSs(AILEmitterCtx Context, bool IsLoad)
{
AOpCodeSimdMemSs Op = (AOpCodeSimdMemSs)Context.CurrOp;
//TODO: Replicate mode.
int Offset = 0;
for (int SElem = 0; SElem < Op.SElems; SElem++)
{
int Rt = (Op.Rt + SElem) & 0x1f;
if (IsLoad)
{
Context.EmitLdvec(Rt);
Context.EmitLdc_I4(Op.Index);
Context.EmitLdc_I4(Op.Size);
Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
Context.EmitLdint(Op.Rn);
Context.EmitLdc_I8(Offset);
Context.Emit(OpCodes.Add);
EmitReadZxCall(Context, Op.Size);
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.InsertVec));
Context.EmitStvec(Rt);
if (Op.RegisterSize == ARegisterSize.SIMD64)
{
EmitVectorZeroUpper(Context, Rt);
}
}
else
{
Context.EmitLdarg(ATranslatedSub.MemoryArgIdx);
Context.EmitLdint(Op.Rn);
Context.EmitLdc_I8(Offset);
Context.Emit(OpCodes.Add);
Context.EmitLdvec(Rt);
Context.EmitLdc_I4(Op.Index);
Context.EmitLdc_I4(Op.Size);
ASoftFallback.EmitCall(Context, nameof(ASoftFallback.ExtractVec));
EmitWriteCall(Context, Op.Size);
}
Offset += 1 << Op.Size;
}
if (Op.WBack)
{
Context.EmitLdint(Op.Rn);
if (Op.Rm != ARegisters.ZRIndex)
{
Context.EmitLdint(Op.Rm);
}
else
{
Context.EmitLdc_I8(Offset);
}
Context.Emit(OpCodes.Add);
Context.EmitStint(Op.Rn);
}
}
private static void EmitVectorAddv(AILEmitterCtx Context)
{
AOpCodeSimd Op = (AOpCodeSimd)Context.CurrOp;