forked from Mirror/Ryujinx
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)
|
||||
{
|
||||
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);
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue