Implement SIMD shift instruction and fix Dup_V

This commit is contained in:
gdkchan 2019-06-15 12:27:35 -03:00
parent 5d7aadd57c
commit 3c09d49067
9 changed files with 1542 additions and 103 deletions

View file

@ -180,6 +180,7 @@ namespace ARMeilleure.CodeGen.X86
Add(X86Instruction.Pshufd, new InstInfo(BadOp, BadOp, BadOp, BadOp, 0x00000f70, InstFlags.Vex | InstFlags.Prefix66));
Add(X86Instruction.Pslld, new InstInfo(BadOp, 0x06000f72, BadOp, BadOp, 0x00000ff2, InstFlags.Vex | InstFlags.Prefix66));
Add(X86Instruction.Pslldq, new InstInfo(BadOp, 0x07000f73, BadOp, BadOp, BadOp, InstFlags.Vex | InstFlags.Prefix66));
Add(X86Instruction.Psllq, new InstInfo(BadOp, 0x06000f73, BadOp, BadOp, 0x00000ff3, InstFlags.Vex | InstFlags.Prefix66));
Add(X86Instruction.Psllw, new InstInfo(BadOp, 0x06000f71, BadOp, BadOp, 0x00000ff1, InstFlags.Vex | InstFlags.Prefix66));
Add(X86Instruction.Psrad, new InstInfo(BadOp, 0x04000f72, BadOp, BadOp, 0x00000fe2, InstFlags.Vex | InstFlags.Prefix66));
Add(X86Instruction.Psraw, new InstInfo(BadOp, 0x04000f71, BadOp, BadOp, 0x00000fe1, InstFlags.Vex | InstFlags.Prefix66));
@ -951,6 +952,11 @@ namespace ARMeilleure.CodeGen.X86
WriteInstruction(source1, source, X86Instruction.Pslldq, dest);
}
public void Psllq(Operand dest, Operand source, Operand source1)
{
WriteInstruction(source1, source, X86Instruction.Psllq, dest);
}
public void Psllw(Operand dest, Operand source, Operand source1)
{
WriteInstruction(source1, source, X86Instruction.Psllw, dest);

View file

@ -159,6 +159,7 @@ namespace ARMeilleure.CodeGen.X86
Add(Instruction.X86Pshufb, GenerateX86Pshufb);
Add(Instruction.X86Pslld, GenerateX86Pslld);
Add(Instruction.X86Pslldq, GenerateX86Pslldq);
Add(Instruction.X86Psllq, GenerateX86Psllq);
Add(Instruction.X86Psllw, GenerateX86Psllw);
Add(Instruction.X86Psrad, GenerateX86Psrad);
Add(Instruction.X86Psraw, GenerateX86Psraw);
@ -447,50 +448,6 @@ namespace ARMeilleure.CodeGen.X86
}
}
private static void GenerateConvertToFPUI(CodeGenContext context, Operation operation)
{
Operand dest = operation.Dest;
Operand source = operation.GetSource(0);
Debug.Assert(dest.Type == OperandType.FP32 ||
dest.Type == OperandType.FP64);
if (dest.Type == OperandType.FP32)
{
Debug.Assert(source.Type == OperandType.I32 ||
source.Type == OperandType.FP64);
if (source.Type == OperandType.I32)
{
context.Assembler.Xorps(dest, dest, dest);
context.Assembler.Cvtsi2ss(dest, source, dest);
}
else /* if (source.Type == OperandType.FP64) */
{
context.Assembler.Cvtsd2ss(dest, source, dest);
ZeroUpper96(context, dest, dest);
}
}
else /* if (dest.Type == OperandType.FP64) */
{
Debug.Assert(source.Type == OperandType.I64 ||
source.Type == OperandType.FP32);
if (source.Type == OperandType.I64)
{
context.Assembler.Xorps(dest, dest, dest);
context.Assembler.Cvtsi2sd(dest, source, dest);
}
else /* if (source.Type == OperandType.FP32) */
{
context.Assembler.Cvtss2sd(dest, source, dest);
ZeroUpper64(context, dest, dest);
}
}
}
private static void GenerateCopy(CodeGenContext context, Operation operation)
{
Operand dest = operation.Dest;
@ -1428,6 +1385,11 @@ namespace ARMeilleure.CodeGen.X86
context.Assembler.Pslldq(operation.Dest, operation.GetSource(1), operation.GetSource(0));
}
private static void GenerateX86Psllq(CodeGenContext context, Operation operation)
{
context.Assembler.Psllq(operation.Dest, operation.GetSource(1), operation.GetSource(0));
}
private static void GenerateX86Psllw(CodeGenContext context, Operation operation)
{
context.Assembler.Psllw(operation.Dest, operation.GetSource(1), operation.GetSource(0));

View file

@ -120,6 +120,7 @@ namespace ARMeilleure.CodeGen.X86
Pshufd,
Pslld,
Pslldq,
Psllq,
Psllw,
Psrad,
Psraw,

View file

@ -397,7 +397,7 @@ namespace ARMeilleure.Decoders
SetA64("0x00111000100000000110xxxxxxxxxx", InstName.Rev16_V, InstEmit.Rev16_V, typeof(OpCodeSimd));
SetA64("0x1011100x100000000010xxxxxxxxxx", InstName.Rev32_V, InstEmit.Rev32_V, typeof(OpCodeSimd));
SetA64("0x001110<<100000000010xxxxxxxxxx", InstName.Rev64_V, InstEmit.Rev64_V, typeof(OpCodeSimd));
SetA64("0x00111100>>>xxx100011xxxxxxxxxx", InstName.Rshrn_V, null, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx100011xxxxxxxxxx", InstName.Rshrn_V, InstEmit.Rshrn_V, typeof(OpCodeSimdShImm));
SetA64("0x101110<<1xxxxx011000xxxxxxxxxx", InstName.Rsubhn_V, InstEmit.Rsubhn_V, typeof(OpCodeSimdReg));
SetA64("0x001110<<1xxxxx011111xxxxxxxxxx", InstName.Saba_V, InstEmit.Saba_V, typeof(OpCodeSimdReg));
SetA64("0x001110<<1xxxxx010100xxxxxxxxxx", InstName.Sabal_V, InstEmit.Sabal_V, typeof(OpCodeSimdReg));
@ -424,13 +424,13 @@ namespace ARMeilleure.Decoders
SetA64("0101111000101000001010xxxxxxxxxx", InstName.Sha256su0_V, null, typeof(OpCodeSimd));
SetA64("01011110000xxxxx011000xxxxxxxxxx", InstName.Sha256su1_V, null, typeof(OpCodeSimdReg));
SetA64("0x001110<<1xxxxx000001xxxxxxxxxx", InstName.Shadd_V, InstEmit.Shadd_V, typeof(OpCodeSimdReg));
SetA64("0101111101xxxxxx010101xxxxxxxxxx", InstName.Shl_S, null, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx010101xxxxxxxxxx", InstName.Shl_V, null, typeof(OpCodeSimdShImm));
SetA64("0100111101xxxxxx010101xxxxxxxxxx", InstName.Shl_V, null, typeof(OpCodeSimdShImm));
SetA64("0x101110<<100001001110xxxxxxxxxx", InstName.Shll_V, null, typeof(OpCodeSimd));
SetA64("0x00111100>>>xxx100001xxxxxxxxxx", InstName.Shrn_V, null, typeof(OpCodeSimdShImm));
SetA64("0101111101xxxxxx010101xxxxxxxxxx", InstName.Shl_S, InstEmit.Shl_S, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx010101xxxxxxxxxx", InstName.Shl_V, InstEmit.Shl_V, typeof(OpCodeSimdShImm));
SetA64("0100111101xxxxxx010101xxxxxxxxxx", InstName.Shl_V, InstEmit.Shl_V, typeof(OpCodeSimdShImm));
SetA64("0x101110<<100001001110xxxxxxxxxx", InstName.Shll_V, InstEmit.Shll_V, typeof(OpCodeSimd));
SetA64("0x00111100>>>xxx100001xxxxxxxxxx", InstName.Shrn_V, InstEmit.Shrn_V, typeof(OpCodeSimdShImm));
SetA64("0x001110<<1xxxxx001001xxxxxxxxxx", InstName.Shsub_V, InstEmit.Shsub_V, typeof(OpCodeSimdReg));
SetA64("0x1011110>>>>xxx010101xxxxxxxxxx", InstName.Sli_V, null, typeof(OpCodeSimdShImm));
SetA64("0x1011110>>>>xxx010101xxxxxxxxxx", InstName.Sli_V, InstEmit.Sli_V, typeof(OpCodeSimdShImm));
SetA64("0x001110<<1xxxxx011001xxxxxxxxxx", InstName.Smax_V, InstEmit.Smax_V, typeof(OpCodeSimdReg));
SetA64("0x001110<<1xxxxx101001xxxxxxxxxx", InstName.Smaxp_V, InstEmit.Smaxp_V, typeof(OpCodeSimdReg));
SetA64("000011100x110000101010xxxxxxxxxx", InstName.Smaxv_V, InstEmit.Smaxv_V, typeof(OpCodeSimd));
@ -460,16 +460,16 @@ namespace ARMeilleure.Decoders
SetA64("01111110101xxxxx101101xxxxxxxxxx", InstName.Sqrdmulh_S, InstEmit.Sqrdmulh_S, typeof(OpCodeSimdReg));
SetA64("0x101110011xxxxx101101xxxxxxxxxx", InstName.Sqrdmulh_V, InstEmit.Sqrdmulh_V, typeof(OpCodeSimdReg));
SetA64("0x101110101xxxxx101101xxxxxxxxxx", InstName.Sqrdmulh_V, InstEmit.Sqrdmulh_V, typeof(OpCodeSimdReg));
SetA64("0>001110<<1xxxxx010111xxxxxxxxxx", InstName.Sqrshl_V, null, typeof(OpCodeSimdReg));
SetA64("0101111100>>>xxx100111xxxxxxxxxx", InstName.Sqrshrn_S, null, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx100111xxxxxxxxxx", InstName.Sqrshrn_V, null, typeof(OpCodeSimdShImm));
SetA64("0111111100>>>xxx100011xxxxxxxxxx", InstName.Sqrshrun_S, null, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx100011xxxxxxxxxx", InstName.Sqrshrun_V, null, typeof(OpCodeSimdShImm));
SetA64("0>001110<<1xxxxx010011xxxxxxxxxx", InstName.Sqshl_V, null, typeof(OpCodeSimdReg));
SetA64("0101111100>>>xxx100101xxxxxxxxxx", InstName.Sqshrn_S, null, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx100101xxxxxxxxxx", InstName.Sqshrn_V, null, typeof(OpCodeSimdShImm));
SetA64("0111111100>>>xxx100001xxxxxxxxxx", InstName.Sqshrun_S, null, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx100001xxxxxxxxxx", InstName.Sqshrun_V, null, typeof(OpCodeSimdShImm));
SetA64("0>001110<<1xxxxx010111xxxxxxxxxx", InstName.Sqrshl_V, InstEmit.Sqrshl_V, typeof(OpCodeSimdReg));
SetA64("0101111100>>>xxx100111xxxxxxxxxx", InstName.Sqrshrn_S, InstEmit.Sqrshrn_S, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx100111xxxxxxxxxx", InstName.Sqrshrn_V, InstEmit.Sqrshrn_V, typeof(OpCodeSimdShImm));
SetA64("0111111100>>>xxx100011xxxxxxxxxx", InstName.Sqrshrun_S, InstEmit.Sqrshrun_S, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx100011xxxxxxxxxx", InstName.Sqrshrun_V, InstEmit.Sqrshrun_V, typeof(OpCodeSimdShImm));
SetA64("0>001110<<1xxxxx010011xxxxxxxxxx", InstName.Sqshl_V, InstEmit.Sqshl_V, typeof(OpCodeSimdReg));
SetA64("0101111100>>>xxx100101xxxxxxxxxx", InstName.Sqshrn_S, InstEmit.Sqshrn_S, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx100101xxxxxxxxxx", InstName.Sqshrn_V, InstEmit.Sqshrn_V, typeof(OpCodeSimdShImm));
SetA64("0111111100>>>xxx100001xxxxxxxxxx", InstName.Sqshrun_S, InstEmit.Sqshrun_S, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx100001xxxxxxxxxx", InstName.Sqshrun_V, InstEmit.Sqshrun_V, typeof(OpCodeSimdShImm));
SetA64("01011110xx1xxxxx001011xxxxxxxxxx", InstName.Sqsub_S, InstEmit.Sqsub_S, typeof(OpCodeSimdReg));
SetA64("0>001110<<1xxxxx001011xxxxxxxxxx", InstName.Sqsub_V, InstEmit.Sqsub_V, typeof(OpCodeSimdReg));
SetA64("01011110<<100001010010xxxxxxxxxx", InstName.Sqxtn_S, InstEmit.Sqxtn_S, typeof(OpCodeSimd));
@ -477,21 +477,21 @@ namespace ARMeilleure.Decoders
SetA64("01111110<<100001001010xxxxxxxxxx", InstName.Sqxtun_S, InstEmit.Sqxtun_S, typeof(OpCodeSimd));
SetA64("0x101110<<100001001010xxxxxxxxxx", InstName.Sqxtun_V, InstEmit.Sqxtun_V, typeof(OpCodeSimd));
SetA64("0x001110<<1xxxxx000101xxxxxxxxxx", InstName.Srhadd_V, InstEmit.Srhadd_V, typeof(OpCodeSimdReg));
SetA64("0>001110<<1xxxxx010101xxxxxxxxxx", InstName.Srshl_V, null, typeof(OpCodeSimdReg));
SetA64("0101111101xxxxxx001001xxxxxxxxxx", InstName.Srshr_S, null, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx001001xxxxxxxxxx", InstName.Srshr_V, null, typeof(OpCodeSimdShImm));
SetA64("0100111101xxxxxx001001xxxxxxxxxx", InstName.Srshr_V, null, typeof(OpCodeSimdShImm));
SetA64("0101111101xxxxxx001101xxxxxxxxxx", InstName.Srsra_S, null, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx001101xxxxxxxxxx", InstName.Srsra_V, null, typeof(OpCodeSimdShImm));
SetA64("0100111101xxxxxx001101xxxxxxxxxx", InstName.Srsra_V, null, typeof(OpCodeSimdShImm));
SetA64("0>001110<<1xxxxx010001xxxxxxxxxx", InstName.Sshl_V, null, typeof(OpCodeSimdReg));
SetA64("0x00111100>>>xxx101001xxxxxxxxxx", InstName.Sshll_V, null, typeof(OpCodeSimdShImm));
SetA64("0101111101xxxxxx000001xxxxxxxxxx", InstName.Sshr_S, null, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx000001xxxxxxxxxx", InstName.Sshr_V, null, typeof(OpCodeSimdShImm));
SetA64("0100111101xxxxxx000001xxxxxxxxxx", InstName.Sshr_V, null, typeof(OpCodeSimdShImm));
SetA64("0101111101xxxxxx000101xxxxxxxxxx", InstName.Ssra_S, null, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx000101xxxxxxxxxx", InstName.Ssra_V, null, typeof(OpCodeSimdShImm));
SetA64("0100111101xxxxxx000101xxxxxxxxxx", InstName.Ssra_V, null, typeof(OpCodeSimdShImm));
SetA64("0>001110<<1xxxxx010101xxxxxxxxxx", InstName.Srshl_V, InstEmit.Srshl_V, typeof(OpCodeSimdReg));
SetA64("0101111101xxxxxx001001xxxxxxxxxx", InstName.Srshr_S, InstEmit.Srshr_S, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx001001xxxxxxxxxx", InstName.Srshr_V, InstEmit.Srshr_V, typeof(OpCodeSimdShImm));
SetA64("0100111101xxxxxx001001xxxxxxxxxx", InstName.Srshr_V, InstEmit.Srshr_V, typeof(OpCodeSimdShImm));
SetA64("0101111101xxxxxx001101xxxxxxxxxx", InstName.Srsra_S, InstEmit.Srsra_S, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx001101xxxxxxxxxx", InstName.Srsra_V, InstEmit.Srsra_V, typeof(OpCodeSimdShImm));
SetA64("0100111101xxxxxx001101xxxxxxxxxx", InstName.Srsra_V, InstEmit.Srsra_V, typeof(OpCodeSimdShImm));
SetA64("0>001110<<1xxxxx010001xxxxxxxxxx", InstName.Sshl_V, InstEmit.Sshl_V, typeof(OpCodeSimdReg));
SetA64("0x00111100>>>xxx101001xxxxxxxxxx", InstName.Sshll_V, InstEmit.Sshll_V, typeof(OpCodeSimdShImm));
SetA64("0101111101xxxxxx000001xxxxxxxxxx", InstName.Sshr_S, InstEmit.Sshr_S, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx000001xxxxxxxxxx", InstName.Sshr_V, InstEmit.Sshr_V, typeof(OpCodeSimdShImm));
SetA64("0100111101xxxxxx000001xxxxxxxxxx", InstName.Sshr_V, InstEmit.Sshr_V, typeof(OpCodeSimdShImm));
SetA64("0101111101xxxxxx000101xxxxxxxxxx", InstName.Ssra_S, InstEmit.Ssra_S, typeof(OpCodeSimdShImm));
SetA64("0x00111100>>>xxx000101xxxxxxxxxx", InstName.Ssra_V, InstEmit.Ssra_V, typeof(OpCodeSimdShImm));
SetA64("0100111101xxxxxx000101xxxxxxxxxx", InstName.Ssra_V, InstEmit.Ssra_V, typeof(OpCodeSimdShImm));
SetA64("0x001110<<1xxxxx001000xxxxxxxxxx", InstName.Ssubl_V, InstEmit.Ssubl_V, typeof(OpCodeSimdReg));
SetA64("0x001110<<1xxxxx001100xxxxxxxxxx", InstName.Ssubw_V, InstEmit.Ssubw_V, typeof(OpCodeSimdReg));
SetA64("0x00110000000000xxxxxxxxxxxxxxxx", InstName.St__Vms, null, typeof(OpCodeSimdMemMs));
@ -545,34 +545,34 @@ namespace ARMeilleure.Decoders
SetA64("0x101111xxxxxxxx1010x0xxxxxxxxxx", InstName.Umull_Ve, InstEmit.Umull_Ve, typeof(OpCodeSimdRegElem));
SetA64("01111110xx1xxxxx000011xxxxxxxxxx", InstName.Uqadd_S, InstEmit.Uqadd_S, typeof(OpCodeSimdReg));
SetA64("0>101110<<1xxxxx000011xxxxxxxxxx", InstName.Uqadd_V, InstEmit.Uqadd_V, typeof(OpCodeSimdReg));
SetA64("0>101110<<1xxxxx010111xxxxxxxxxx", InstName.Uqrshl_V, null, typeof(OpCodeSimdReg));
SetA64("0111111100>>>xxx100111xxxxxxxxxx", InstName.Uqrshrn_S, null, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx100111xxxxxxxxxx", InstName.Uqrshrn_V, null, typeof(OpCodeSimdShImm));
SetA64("0>101110<<1xxxxx010011xxxxxxxxxx", InstName.Uqshl_V, null, typeof(OpCodeSimdReg));
SetA64("0111111100>>>xxx100101xxxxxxxxxx", InstName.Uqshrn_S, null, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx100101xxxxxxxxxx", InstName.Uqshrn_V, null, typeof(OpCodeSimdShImm));
SetA64("0>101110<<1xxxxx010111xxxxxxxxxx", InstName.Uqrshl_V, InstEmit.Uqrshl_V, typeof(OpCodeSimdReg));
SetA64("0111111100>>>xxx100111xxxxxxxxxx", InstName.Uqrshrn_S, InstEmit.Uqrshrn_S, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx100111xxxxxxxxxx", InstName.Uqrshrn_V, InstEmit.Uqrshrn_V, typeof(OpCodeSimdShImm));
SetA64("0>101110<<1xxxxx010011xxxxxxxxxx", InstName.Uqshl_V, InstEmit.Uqshl_V, typeof(OpCodeSimdReg));
SetA64("0111111100>>>xxx100101xxxxxxxxxx", InstName.Uqshrn_S, InstEmit.Uqshrn_S, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx100101xxxxxxxxxx", InstName.Uqshrn_V, InstEmit.Uqshrn_V, typeof(OpCodeSimdShImm));
SetA64("01111110xx1xxxxx001011xxxxxxxxxx", InstName.Uqsub_S, InstEmit.Uqsub_S, typeof(OpCodeSimdReg));
SetA64("0>101110<<1xxxxx001011xxxxxxxxxx", InstName.Uqsub_V, InstEmit.Uqsub_V, typeof(OpCodeSimdReg));
SetA64("01111110<<100001010010xxxxxxxxxx", InstName.Uqxtn_S, InstEmit.Uqxtn_S, typeof(OpCodeSimd));
SetA64("0x101110<<100001010010xxxxxxxxxx", InstName.Uqxtn_V, InstEmit.Uqxtn_V, typeof(OpCodeSimd));
SetA64("0x101110<<1xxxxx000101xxxxxxxxxx", InstName.Urhadd_V, InstEmit.Urhadd_V, typeof(OpCodeSimdReg));
SetA64("0>101110<<1xxxxx010101xxxxxxxxxx", InstName.Urshl_V, null, typeof(OpCodeSimdReg));
SetA64("0111111101xxxxxx001001xxxxxxxxxx", InstName.Urshr_S, null, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx001001xxxxxxxxxx", InstName.Urshr_V, null, typeof(OpCodeSimdShImm));
SetA64("0110111101xxxxxx001001xxxxxxxxxx", InstName.Urshr_V, null, typeof(OpCodeSimdShImm));
SetA64("0111111101xxxxxx001101xxxxxxxxxx", InstName.Ursra_S, null, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx001101xxxxxxxxxx", InstName.Ursra_V, null, typeof(OpCodeSimdShImm));
SetA64("0110111101xxxxxx001101xxxxxxxxxx", InstName.Ursra_V, null, typeof(OpCodeSimdShImm));
SetA64("0>101110<<1xxxxx010001xxxxxxxxxx", InstName.Ushl_V, null, typeof(OpCodeSimdReg));
SetA64("0x10111100>>>xxx101001xxxxxxxxxx", InstName.Ushll_V, null, typeof(OpCodeSimdShImm));
SetA64("0111111101xxxxxx000001xxxxxxxxxx", InstName.Ushr_S, null, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx000001xxxxxxxxxx", InstName.Ushr_V, null, typeof(OpCodeSimdShImm));
SetA64("0110111101xxxxxx000001xxxxxxxxxx", InstName.Ushr_V, null, typeof(OpCodeSimdShImm));
SetA64("0>101110<<1xxxxx010101xxxxxxxxxx", InstName.Urshl_V, InstEmit.Urshl_V, typeof(OpCodeSimdReg));
SetA64("0111111101xxxxxx001001xxxxxxxxxx", InstName.Urshr_S, InstEmit.Urshr_S, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx001001xxxxxxxxxx", InstName.Urshr_V, InstEmit.Urshr_V, typeof(OpCodeSimdShImm));
SetA64("0110111101xxxxxx001001xxxxxxxxxx", InstName.Urshr_V, InstEmit.Urshr_V, typeof(OpCodeSimdShImm));
SetA64("0111111101xxxxxx001101xxxxxxxxxx", InstName.Ursra_S, InstEmit.Ursra_S, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx001101xxxxxxxxxx", InstName.Ursra_V, InstEmit.Ursra_V, typeof(OpCodeSimdShImm));
SetA64("0110111101xxxxxx001101xxxxxxxxxx", InstName.Ursra_V, InstEmit.Ursra_V, typeof(OpCodeSimdShImm));
SetA64("0>101110<<1xxxxx010001xxxxxxxxxx", InstName.Ushl_V, InstEmit.Ushl_V, typeof(OpCodeSimdReg));
SetA64("0x10111100>>>xxx101001xxxxxxxxxx", InstName.Ushll_V, InstEmit.Ushll_V, typeof(OpCodeSimdShImm));
SetA64("0111111101xxxxxx000001xxxxxxxxxx", InstName.Ushr_S, InstEmit.Ushr_S, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx000001xxxxxxxxxx", InstName.Ushr_V, InstEmit.Ushr_V, typeof(OpCodeSimdShImm));
SetA64("0110111101xxxxxx000001xxxxxxxxxx", InstName.Ushr_V, InstEmit.Ushr_V, typeof(OpCodeSimdShImm));
SetA64("01111110xx100000001110xxxxxxxxxx", InstName.Usqadd_S, InstEmit.Usqadd_S, typeof(OpCodeSimd));
SetA64("0>101110<<100000001110xxxxxxxxxx", InstName.Usqadd_V, InstEmit.Usqadd_V, typeof(OpCodeSimd));
SetA64("0111111101xxxxxx000101xxxxxxxxxx", InstName.Usra_S, null, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx000101xxxxxxxxxx", InstName.Usra_V, null, typeof(OpCodeSimdShImm));
SetA64("0110111101xxxxxx000101xxxxxxxxxx", InstName.Usra_V, null, typeof(OpCodeSimdShImm));
SetA64("0111111101xxxxxx000101xxxxxxxxxx", InstName.Usra_S, InstEmit.Usra_S, typeof(OpCodeSimdShImm));
SetA64("0x10111100>>>xxx000101xxxxxxxxxx", InstName.Usra_V, InstEmit.Usra_V, typeof(OpCodeSimdShImm));
SetA64("0110111101xxxxxx000101xxxxxxxxxx", InstName.Usra_V, InstEmit.Usra_V, typeof(OpCodeSimdShImm));
SetA64("0x101110<<1xxxxx001000xxxxxxxxxx", InstName.Usubl_V, InstEmit.Usubl_V, typeof(OpCodeSimdReg));
SetA64("0x101110<<1xxxxx001100xxxxxxxxxx", InstName.Usubw_V, InstEmit.Usubw_V, typeof(OpCodeSimdReg));
SetA64("0>001110<<0xxxxx000110xxxxxxxxxx", InstName.Uzp1_V, InstEmit.Uzp1_V, typeof(OpCodeSimdReg));

View file

@ -84,6 +84,29 @@ namespace ARMeilleure.Instructions
Instruction.X86Pmovzxdq
};
public static readonly Instruction[] X86PsllInstruction = new Instruction[]
{
0,
Instruction.X86Psllw,
Instruction.X86Pslld,
Instruction.X86Psllq
};
public static readonly Instruction[] X86PsraInstruction = new Instruction[]
{
0,
Instruction.X86Psraw,
Instruction.X86Psrad
};
public static readonly Instruction[] X86PsrlInstruction = new Instruction[]
{
0,
Instruction.X86Psrlw,
Instruction.X86Psrld,
Instruction.X86Psrlq
};
public static readonly Instruction[] X86PsubInstruction = new Instruction[]
{
Instruction.X86Psubb,

View file

@ -107,20 +107,31 @@ namespace ARMeilleure.Instructions
if (op.Size == 0)
{
res = context.AddIntrinsic(Instruction.X86Psrldq, res, Const(op.DstIndex));
if (op.DstIndex != 0)
{
res = context.AddIntrinsic(Instruction.X86Psrldq, res, Const(op.DstIndex));
}
res = context.AddIntrinsic(Instruction.X86Punpcklbw, res, res);
res = context.AddIntrinsic(Instruction.X86Punpcklwd, res, res);
res = context.AddIntrinsic(Instruction.X86Shufps, res, res, Const(0));
}
else if (op.Size == 1)
{
res = context.AddIntrinsic(Instruction.X86Psrldq, res, Const(op.DstIndex * 2));
res = context.AddIntrinsic(Instruction.X86Punpcklwd, res, res);
}
if (op.DstIndex != 0)
{
res = context.AddIntrinsic(Instruction.X86Psrldq, res, Const(op.DstIndex * 2));
}
if (op.Size < 3)
{
res = context.AddIntrinsic(Instruction.X86Punpcklwd, res, res);
res = context.AddIntrinsic(Instruction.X86Shufps, res, res, Const(0));
}
else if (op.Size == 2)
{
int mask = op.DstIndex * 0b01010101;
res = context.AddIntrinsic(Instruction.X86Shufps, res, res, Const(mask));
}
else if (op.DstIndex == 0 && op.RegisterSize != RegisterSize.Simd64)
{
res = context.AddIntrinsic(Instruction.X86Movlhps, res, res);

File diff suppressed because it is too large Load diff

View file

@ -6,11 +6,370 @@ namespace ARMeilleure.Instructions
static class SoftFallback
{
#region "ShlReg"
public static long SignedShlReg(long value, long shift, bool round, int size)
{
int eSize = 8 << size;
int shiftLsB = (sbyte)shift;
if (shiftLsB < 0)
{
return SignedShrReg(value, -shiftLsB, round, eSize);
}
else if (shiftLsB > 0)
{
if (shiftLsB >= eSize)
{
return 0L;
}
return value << shiftLsB;
}
else /* if (shiftLsB == 0) */
{
return value;
}
}
public static ulong UnsignedShlReg(ulong value, ulong shift, bool round, int size)
{
int eSize = 8 << size;
int shiftLsB = (sbyte)shift;
if (shiftLsB < 0)
{
return UnsignedShrReg(value, -shiftLsB, round, eSize);
}
else if (shiftLsB > 0)
{
if (shiftLsB >= eSize)
{
return 0UL;
}
return value << shiftLsB;
}
else /* if (shiftLsB == 0) */
{
return value;
}
}
public static long SignedShlRegSatQ(long value, long shift, bool round, int size)
{
ExecutionContext context = NativeInterface.GetContext();
int eSize = 8 << size;
int shiftLsB = (sbyte)shift;
if (shiftLsB < 0)
{
return SignedShrReg(value, -shiftLsB, round, eSize);
}
else if (shiftLsB > 0)
{
if (shiftLsB >= eSize)
{
return SignedSignSatQ(value, eSize, context);
}
if (eSize == 64)
{
long shl = value << shiftLsB;
long shr = shl >> shiftLsB;
if (shr != value)
{
return SignedSignSatQ(value, eSize, context);
}
else /* if (shr == value) */
{
return shl;
}
}
else /* if (eSize != 64) */
{
return SignedSrcSignedDstSatQ(value << shiftLsB, size);
}
}
else /* if (shiftLsB == 0) */
{
return value;
}
}
public static ulong UnsignedShlRegSatQ(ulong value, ulong shift, bool round, int size)
{
ExecutionContext context = NativeInterface.GetContext();
int eSize = 8 << size;
int shiftLsB = (sbyte)shift;
if (shiftLsB < 0)
{
return UnsignedShrReg(value, -shiftLsB, round, eSize);
}
else if (shiftLsB > 0)
{
if (shiftLsB >= eSize)
{
return UnsignedSignSatQ(value, eSize, context);
}
if (eSize == 64)
{
ulong shl = value << shiftLsB;
ulong shr = shl >> shiftLsB;
if (shr != value)
{
return UnsignedSignSatQ(value, eSize, context);
}
else /* if (shr == value) */
{
return shl;
}
}
else /* if (eSize != 64) */
{
return UnsignedSrcUnsignedDstSatQ(value << shiftLsB, size);
}
}
else /* if (shiftLsB == 0) */
{
return value;
}
}
private static long SignedShrReg(long value, int shift, bool round, int eSize) // shift := [1, 128]; eSize := {8, 16, 32, 64}.
{
if (round)
{
if (shift >= eSize)
{
return 0L;
}
long roundConst = 1L << (shift - 1);
long add = value + roundConst;
if (eSize == 64)
{
if ((~value & (value ^ add)) < 0L)
{
return (long)((ulong)add >> shift);
}
else
{
return add >> shift;
}
}
else /* if (eSize != 64) */
{
return add >> shift;
}
}
else /* if (!round) */
{
if (shift >= eSize)
{
if (value < 0L)
{
return -1L;
}
else /* if (value >= 0L) */
{
return 0L;
}
}
return value >> shift;
}
}
private static ulong UnsignedShrReg(ulong value, int shift, bool round, int eSize) // shift := [1, 128]; eSize := {8, 16, 32, 64}.
{
if (round)
{
if (shift > 64)
{
return 0UL;
}
ulong roundConst = 1UL << (shift - 1);
ulong add = value + roundConst;
if (eSize == 64)
{
if ((add < value) && (add < roundConst))
{
if (shift == 64)
{
return 1UL;
}
return (add >> shift) | (0x8000000000000000UL >> (shift - 1));
}
else
{
if (shift == 64)
{
return 0UL;
}
return add >> shift;
}
}
else /* if (eSize != 64) */
{
if (shift == 64)
{
return 0UL;
}
return add >> shift;
}
}
else /* if (!round) */
{
if (shift >= eSize)
{
return 0UL;
}
return value >> shift;
}
}
private static long SignedSignSatQ(long op, int eSize, ExecutionContext context) // eSize := {8, 16, 32, 64}.
{
long tMaxValue = (1L << (eSize - 1)) - 1L;
long tMinValue = -(1L << (eSize - 1));
if (op > 0L)
{
context.Fpsr |= FPSR.Qc;
return tMaxValue;
}
else if (op < 0L)
{
context.Fpsr |= FPSR.Qc;
return tMinValue;
}
else
{
return 0L;
}
}
private static ulong UnsignedSignSatQ(ulong op, int eSize, ExecutionContext context) // eSize := {8, 16, 32, 64}.
{
ulong tMaxValue = ulong.MaxValue >> (64 - eSize);
if (op > 0UL)
{
context.Fpsr |= FPSR.Qc;
return tMaxValue;
}
else
{
return 0UL;
}
}
#endregion
#region "ShrImm64"
public static long SignedShrImm64(long value, long roundConst, int shift)
{
if (roundConst == 0L)
{
if (shift <= 63)
{
return value >> shift;
}
else /* if (shift == 64) */
{
if (value < 0L)
{
return -1L;
}
else /* if (value >= 0L) */
{
return 0L;
}
}
}
else /* if (roundConst == 1L << (shift - 1)) */
{
if (shift <= 63)
{
long add = value + roundConst;
if ((~value & (value ^ add)) < 0L)
{
return (long)((ulong)add >> shift);
}
else
{
return add >> shift;
}
}
else /* if (shift == 64) */
{
return 0L;
}
}
}
public static ulong UnsignedShrImm64(ulong value, long roundConst, int shift)
{
if (roundConst == 0L)
{
if (shift <= 63)
{
return value >> shift;
}
else /* if (shift == 64) */
{
return 0UL;
}
}
else /* if (roundConst == 1L << (shift - 1)) */
{
ulong add = value + (ulong)roundConst;
if ((add < value) && (add < (ulong)roundConst))
{
if (shift <= 63)
{
return (add >> shift) | (0x8000000000000000UL >> (shift - 1));
}
else /* if (shift == 64) */
{
return 1UL;
}
}
else
{
if (shift <= 63)
{
return add >> shift;
}
else /* if (shift == 64) */
{
return 0UL;
}
}
}
}
#endregion
#region "Rounding"

View file

@ -147,6 +147,7 @@ namespace ARMeilleure.IntermediateRepresentation
X86Pshufb,
X86Pslld,
X86Pslldq,
X86Psllq,
X86Psllw,
X86Psrad,
X86Psraw,