mirror of
https://github.com/GreemDev/Ryujinx
synced 2024-11-22 17:56:59 +01: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:
parent
c8bb3cc50e
commit
47ba81c661
2 changed files with 37 additions and 47 deletions
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue