1
0
Fork 0
mirror of https://github.com/Ryujinx/Ryujinx.git synced 2024-10-01 12:30:00 +02: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) 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); 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 (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; continue;
} }
HandleConstantRegCopy(block.Operations, node, operation); HandleConstantRegCopy(block.Operations, node, operation);
node = HandleDestructiveRegCopy(block.Operations, node, operation); HandleDestructiveRegCopy(block.Operations, node, operation);
node = HandleConstrainedRegCopy(block.Operations, node, operation); HandleConstrainedRegCopy(block.Operations, node, operation);
switch (operation.Instruction) switch (operation.Instruction)
{ {
@ -56,33 +60,33 @@ namespace ARMeilleure.CodeGen.X86
// being called, as mandated by the ABI. // being called, as mandated by the ABI.
if (callConv == CallConvName.Windows) if (callConv == CallConvName.Windows)
{ {
node = HandleCallWindowsAbi(block.Operations, stackAlloc, node, operation); HandleCallWindowsAbi(block.Operations, stackAlloc, node, operation);
} }
else /* if (callConv == CallConvName.SystemV) */ else /* if (callConv == CallConvName.SystemV) */
{ {
node = HandleCallSystemVAbi(block.Operations, node, operation); HandleCallSystemVAbi(block.Operations, node, operation);
} }
break; break;
case Instruction.ConvertToFPUI: case Instruction.ConvertToFPUI:
node = HandleConvertToFPUI(block.Operations, node, operation); HandleConvertToFPUI(block.Operations, node, operation);
break; break;
case Instruction.LoadArgument: case Instruction.LoadArgument:
if (callConv == CallConvName.Windows) 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) */ else /* if (callConv == CallConvName.SystemV) */
{ {
node = HandleLoadArgumentSystemVAbi(cctx, block.Operations, node, preservedArgs, operation); nextNode = HandleLoadArgumentSystemVAbi(cctx, block.Operations, node, preservedArgs, operation);
} }
break; break;
case Instruction.Negate: case Instruction.Negate:
if (!operation.GetSource(0).Type.IsInteger()) if (!operation.GetSource(0).Type.IsInteger())
{ {
node = HandleNegate(block.Operations, node, operation); HandleNegate(block.Operations, node, operation);
} }
break; break;
@ -111,7 +115,7 @@ namespace ARMeilleure.CodeGen.X86
case Instruction.VectorInsert8: case Instruction.VectorInsert8:
if (!HardwareCapabilities.SupportsSse41) if (!HardwareCapabilities.SupportsSse41)
{ {
node = HandleVectorInsert8(block.Operations, node, operation); HandleVectorInsert8(block.Operations, node, operation);
} }
break; 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; Operand dest = operation.Destination;
@ -243,7 +247,7 @@ namespace ARMeilleure.CodeGen.X86
SplitOperand(operation.GetSource(2), rbx, rcx); SplitOperand(operation.GetSource(2), rbx, rcx);
node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, rax)); 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 }); operation.SetDestinations(new Operand[] { rdx, rax });
@ -269,7 +273,7 @@ namespace ARMeilleure.CodeGen.X86
operation.SetSources(new Operand[] { operation.GetSource(0), rax, temp }); 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; operation.Destination = rax;
} }
@ -294,7 +298,7 @@ namespace ARMeilleure.CodeGen.X86
nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1)); nodes.AddBefore(node, Operation(Instruction.Copy, rax, src1));
nodes.AddBefore(node, Operation(Instruction.Clobber, rdx)); 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 }); operation.SetDestinations(new Operand[] { rdx, rax });
@ -342,7 +346,7 @@ namespace ARMeilleure.CodeGen.X86
operation.SetSource(0, rax); 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 }); operation.SetDestinations(new Operand[] { rdx, rax });
@ -367,15 +371,13 @@ namespace ARMeilleure.CodeGen.X86
break; 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) if (operation.Destination == null || operation.SourcesCount == 0)
{ {
return node; return;
} }
Instruction inst = operation.Instruction; Instruction inst = operation.Instruction;
@ -412,7 +414,7 @@ namespace ARMeilleure.CodeGen.X86
operation.SetSource(0, temp); operation.SetSource(0, temp);
node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp)); nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp));
operation.Destination = temp; operation.Destination = temp;
} }
@ -436,7 +438,7 @@ namespace ARMeilleure.CodeGen.X86
operation.SetSource(2, temp); operation.SetSource(2, temp);
node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp)); nodes.AddAfter(node, Operation(Instruction.Copy, dest, temp));
operation.Destination = temp; operation.Destination = temp;
} }
@ -447,11 +449,9 @@ namespace ARMeilleure.CodeGen.X86
operation.SetSource(2, dest); 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. // Unsigned integer to FP conversions are not supported on X86.
// We need to turn them into signed integer to FP conversions, and // 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.ConvertToFP, dest, half));
node = nodes.AddAfter(node, Operation(Instruction.Add, dest, dest, dest)); 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); 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 // 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. // 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, 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); 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. // Handle vector insertion, when SSE 4.1 is not supported.
Operand dest = operation.Destination; Operand dest = operation.Destination;
@ -582,14 +578,12 @@ namespace ARMeilleure.CodeGen.X86
Operation vinsOp = Operation(Instruction.VectorInsert16, dest, src1, temp1, Const(index >> 1)); Operation vinsOp = Operation(Instruction.VectorInsert16, dest, src1, temp1, Const(index >> 1));
node = nodes.AddAfter(node, vinsOp); nodes.AddAfter(node, vinsOp);
Delete(nodes, currentNode, operation); 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; Operand dest = operation.Destination;
@ -717,7 +711,7 @@ namespace ARMeilleure.CodeGen.X86
Operation loadOp = Operation(Instruction.Load, dest, retValueAddr); Operation loadOp = Operation(Instruction.Load, dest, retValueAddr);
node = nodes.AddAfter(node, loadOp); nodes.AddAfter(node, loadOp);
operation.Destination = null; operation.Destination = null;
} }
@ -729,18 +723,16 @@ namespace ARMeilleure.CodeGen.X86
Operation copyOp = Operation(Instruction.Copy, dest, retReg); Operation copyOp = Operation(Instruction.Copy, dest, retReg);
node = nodes.AddAfter(node, copyOp); nodes.AddAfter(node, copyOp);
operation.Destination = retReg; operation.Destination = retReg;
} }
} }
operation.SetSources(sources); 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; Operand dest = operation.Destination;
@ -822,7 +814,7 @@ namespace ARMeilleure.CodeGen.X86
Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64); Operand retHReg = Gpr(CallingConvention.GetIntReturnRegisterHigh(), OperandType.I64);
node = nodes.AddAfter(node, Operation(Instruction.VectorCreateScalar, dest, retLReg)); 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; operation.Destination = null;
} }
@ -834,15 +826,13 @@ namespace ARMeilleure.CodeGen.X86
Operation copyOp = Operation(Instruction.Copy, dest, retReg); Operation copyOp = Operation(Instruction.Copy, dest, retReg);
node = nodes.AddAfter(node, copyOp); nodes.AddAfter(node, copyOp);
operation.Destination = retReg; operation.Destination = retReg;
} }
} }
operation.SetSources(sources.ToArray()); operation.SetSources(sources.ToArray());
return node;
} }
private static void HandleTailcallSystemVAbi(IntrusiveList<Node> nodes, StackAllocator stackAlloc, Node node, Operation operation) private static void HandleTailcallSystemVAbi(IntrusiveList<Node> nodes, StackAllocator stackAlloc, Node node, Operation operation)