0
0
Fork 0
mirror of https://github.com/GreemDev/Ryujinx.git synced 2024-12-23 02:15:49 +00:00

Fix pre-allocator shift instruction copy on a specific case (#1752)

* Fix pre-allocator shift instruction copy on a specific case

* Fix to make shift use int rather than long for constants
This commit is contained in:
gdkchan 2020-12-14 17:56:07 -03:00 committed by GitHub
parent c8bb3cc50e
commit 47ba81c661
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 47 deletions

View file

@ -923,7 +923,7 @@ namespace ARMeilleure.CodeGen.X86
}
else if (source.Kind == OperandKind.Constant)
{
source = source.With((uint)source.Value & (dest.Type == OperandType.I32 ? 0x1f : 0x3f));
source = source.With((int)source.Value & (dest.Type == OperandType.I32 ? 0x1f : 0x3f));
}
WriteInstruction(dest, source, type, inst);

View file

@ -22,16 +22,20 @@ namespace ARMeilleure.CodeGen.X86
for (BasicBlock block = cctx.Cfg.Blocks.First; block != null; block = block.ListNext)
{
for (Node node = block.Operations.First; node != null; node = node.ListNext)
Node nextNode;
for (Node node = block.Operations.First; node != null; node = nextNode)
{
if (!(node is Operation operation))
nextNode = node.ListNext;
if (node is not Operation operation)
{
continue;
}
HandleConstantRegCopy(block.Operations, node, operation);
node = HandleDestructiveRegCopy(block.Operations, node, operation);
node = HandleConstrainedRegCopy(block.Operations, node, operation);
HandleDestructiveRegCopy(block.Operations, node, operation);
HandleConstrainedRegCopy(block.Operations, node, operation);
switch (operation.Instruction)
{
@ -56,33 +60,33 @@ namespace ARMeilleure.CodeGen.X86
// being called, as mandated by the ABI.
if (callConv == CallConvName.Windows)
{
node = HandleCallWindowsAbi(block.Operations, stackAlloc, node, operation);
HandleCallWindowsAbi(block.Operations, stackAlloc, node, operation);
}
else /* if (callConv == CallConvName.SystemV) */
{
node = HandleCallSystemVAbi(block.Operations, node, operation);
HandleCallSystemVAbi(block.Operations, node, operation);
}
break;
case Instruction.ConvertToFPUI:
node = HandleConvertToFPUI(block.Operations, node, operation);
HandleConvertToFPUI(block.Operations, node, operation);
break;
case Instruction.LoadArgument:
if (callConv == CallConvName.Windows)
{
node = HandleLoadArgumentWindowsAbi(cctx, block.Operations, node, preservedArgs, operation);
nextNode = HandleLoadArgumentWindowsAbi(cctx, block.Operations, node, preservedArgs, operation);
}
else /* if (callConv == CallConvName.SystemV) */
{
node = HandleLoadArgumentSystemVAbi(cctx, block.Operations, node, preservedArgs, operation);
nextNode = HandleLoadArgumentSystemVAbi(cctx, block.Operations, node, preservedArgs, operation);
}
break;
case Instruction.Negate:
if (!operation.GetSource(0).Type.IsInteger())
{
node = HandleNegate(block.Operations, node, operation);
HandleNegate(block.Operations, node, operation);
}
break;
@ -111,7 +115,7 @@ namespace ARMeilleure.CodeGen.X86
case Instruction.VectorInsert8:
if (!HardwareCapabilities.SupportsSse41)
{
node = HandleVectorInsert8(block.Operations, node, operation);
HandleVectorInsert8(block.Operations, node, operation);
}
break;
@ -210,7 +214,7 @@ namespace ARMeilleure.CodeGen.X86
}
}
private static Node HandleConstrainedRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
private static void HandleConstrainedRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
{
Operand dest = operation.Destination;
@ -243,7 +247,7 @@ namespace ARMeilleure.CodeGen.X86
SplitOperand(operation.GetSource(2), rbx, rcx);
node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax));
node = nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1)));
nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, rdx, Const(1)));
operation.SetDestinations(new Operand[] { rdx, rax });
@ -269,7 +273,7 @@ namespace ARMeilleure.CodeGen.X86
operation.SetSources(new Operand[] { operation.GetSource(0), rax, temp });
node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
operation.Destination = rax;
}
@ -294,7 +298,7 @@ namespace ARMeilleure.CodeGen.X86
nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1));
nodes.AddBefore(node, Operation(Instruction.Clobber, rdx));
node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
operation.SetDestinations(new Operand[] { rdx, rax });
@ -342,7 +346,7 @@ namespace ARMeilleure.CodeGen.X86
operation.SetSource(0, rax);
node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx));
nodes.AddAfter(node, Operation(Instruction.Copy, dest, rdx));
operation.SetDestinations(new Operand[] { rdx, rax });
@ -367,15 +371,13 @@ namespace ARMeilleure.CodeGen.X86
break;
}
}
return node;
}
private static Node HandleDestructiveRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
private static void HandleDestructiveRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
{
if (operation.Destination == null || operation.SourcesCount == 0)
{
return node;
return;
}
Instruction inst = operation.Instruction;
@ -412,7 +414,7 @@ namespace ARMeilleure.CodeGen.X86
operation.SetSource(0, temp);
node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp));
nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp));
operation.Destination = temp;
}
@ -436,7 +438,7 @@ namespace ARMeilleure.CodeGen.X86
operation.SetSource(2, temp);
node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp));
nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp));
operation.Destination = temp;
}
@ -447,11 +449,9 @@ namespace ARMeilleure.CodeGen.X86
operation.SetSource(2, dest);
}
}
return node;
}
private static Node HandleConvertToFPUI(IntrusiveList<Node> nodes, Node node, Operation operation)
private static void HandleConvertToFPUI(IntrusiveList<Node> nodes, Node node, Operation operation)
{
// Unsigned integer to FP conversions are not supported on X86.
// We need to turn them into signed integer to FP conversions, and
@ -499,15 +499,13 @@ namespace ARMeilleure.CodeGen.X86
node = nodes.AddAfter(node, Operation(Instruction.ConvertToFP, dest, half));
node = nodes.AddAfter(node, Operation(Instruction.Add, dest, dest, dest));
node = nodes.AddAfter(node, Operation(Instruction.Add, dest, dest, lsbF));
nodes.AddAfter(node, Operation(Instruction.Add, dest, dest, lsbF));
}
Delete(nodes, currentNode, operation);
return node;
}
private static Node HandleNegate(IntrusiveList<Node> nodes, Node node, Operation operation)
private static void HandleNegate(IntrusiveList<Node> nodes, Node node, Operation operation)
{
// There's no SSE FP negate instruction, so we need to transform that into
// a XOR of the value to be negated with a mask with the highest bit set.
@ -535,14 +533,12 @@ namespace ARMeilleure.CodeGen.X86
node = nodes.AddAfter(node, new IntrinsicOperation(Intrinsic.X86Xorps, res, res, source));
node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, res));
nodes.AddAfter(node, Operation(Instruction.Copy, dest, res));
Delete(nodes, currentNode, operation);
return node;
}
private static Node HandleVectorInsert8(IntrusiveList<Node> nodes, Node node, Operation operation)
private static void HandleVectorInsert8(IntrusiveList<Node> nodes, Node node, Operation operation)
{
// Handle vector insertion, when SSE 4.1 is not supported.
Operand dest = operation.Destination;
@ -582,14 +578,12 @@ namespace ARMeilleure.CodeGen.X86
Operation vinsOp = Operation(Instruction.VectorInsert16, dest, src1, temp1, Const(index >> 1));
node = nodes.AddAfter(node, vinsOp);
nodes.AddAfter(node, vinsOp);
Delete(nodes, currentNode, operation);
return node;
}
private static Node HandleCallWindowsAbi(IntrusiveList<Node> nodes, StackAllocator stackAlloc, Node node, Operation operation)
private static void HandleCallWindowsAbi(IntrusiveList<Node> nodes, StackAllocator stackAlloc, Node node, Operation operation)
{
Operand dest = operation.Destination;
@ -717,7 +711,7 @@ namespace ARMeilleure.CodeGen.X86
Operation loadOp = Operation(Instruction.Load, dest, retValueAddr);
node = nodes.AddAfter(node, loadOp);
nodes.AddAfter(node, loadOp);
operation.Destination = null;
}
@ -729,18 +723,16 @@ namespace ARMeilleure.CodeGen.X86
Operation copyOp = Operation(Instruction.Copy, dest, retReg);
node = nodes.AddAfter(node, copyOp);
nodes.AddAfter(node, copyOp);
operation.Destination = retReg;
}
}
operation.SetSources(sources);
return node;
}
private static Node HandleCallSystemVAbi(IntrusiveList<Node> nodes, Node node, Operation operation)
private static void HandleCallSystemVAbi(IntrusiveList<Node> nodes, Node node, Operation operation)
{
Operand dest = operation.Destination;
@ -822,7 +814,7 @@ namespace ARMeilleure.CodeGen.X86
Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64);
node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, retLReg));
node = nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, retHReg, Const(1)));
nodes.AddAfter(node, Operation(Instruction.VectorInsert, dest, dest, retHReg, Const(1)));
operation.Destination = null;
}
@ -834,15 +826,13 @@ namespace ARMeilleure.CodeGen.X86
Operation copyOp = Operation(Instruction.Copy, dest, retReg);
node = nodes.AddAfter(node, copyOp);
nodes.AddAfter(node, copyOp);
operation.Destination = retReg;
}
}
operation.SetSources(sources.ToArray());
return node;
}
private static void HandleTailcallSystemVAbi(IntrusiveList<Node> nodes, StackAllocator stackAlloc, Node node, Operation operation)