forked from Mirror/Ryujinx
Do temp constant copy for CompareAndSwap, other improvements to PreAllocator (#1126)
* Do temp constant copy for CompareAndSwap, other improvements to PreAllocator * Nit
This commit is contained in:
parent
a728610b40
commit
fe5bb439f1
1 changed files with 39 additions and 32 deletions
|
@ -22,22 +22,16 @@ 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)
|
||||||
{
|
{
|
||||||
Node nextNode;
|
for (Node node = block.Operations.First; node != null; node = node.ListNext)
|
||||||
|
|
||||||
for (Node node = block.Operations.First; node != null; node = nextNode)
|
|
||||||
{
|
{
|
||||||
nextNode = node.ListNext;
|
|
||||||
|
|
||||||
if (!(node is Operation operation))
|
if (!(node is Operation operation))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleConstantCopy(block.Operations, node, operation);
|
HandleConstantRegCopy(block.Operations, node, operation);
|
||||||
|
node = HandleDestructiveRegCopy(block.Operations, node, operation);
|
||||||
HandleSameDestSrc1Copy(block.Operations, node, operation);
|
node = HandleConstrainedRegCopy(block.Operations, node, operation);
|
||||||
|
|
||||||
HandleFixedRegisterCopy(block.Operations, node, operation);
|
|
||||||
|
|
||||||
switch (operation.Instruction)
|
switch (operation.Instruction)
|
||||||
{
|
{
|
||||||
|
@ -71,17 +65,17 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.ConvertToFPUI:
|
case Instruction.ConvertToFPUI:
|
||||||
HandleConvertToFPUI(block.Operations, node, operation);
|
node = HandleConvertToFPUI(block.Operations, node, operation);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Instruction.LoadArgument:
|
case Instruction.LoadArgument:
|
||||||
if (callConv == CallConvName.Windows)
|
if (callConv == CallConvName.Windows)
|
||||||
{
|
{
|
||||||
HandleLoadArgumentWindowsAbi(cctx, block.Operations, node, preservedArgs, operation);
|
node = HandleLoadArgumentWindowsAbi(cctx, block.Operations, node, preservedArgs, operation);
|
||||||
}
|
}
|
||||||
else /* if (callConv == CallConvName.SystemV) */
|
else /* if (callConv == CallConvName.SystemV) */
|
||||||
{
|
{
|
||||||
HandleLoadArgumentSystemVAbi(cctx, block.Operations, node, preservedArgs, operation);
|
node = HandleLoadArgumentSystemVAbi(cctx, block.Operations, node, preservedArgs, operation);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -125,7 +119,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandleConstantCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
|
private static void HandleConstantRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
|
||||||
{
|
{
|
||||||
if (operation.SourcesCount == 0 || IsIntrinsic(operation.Instruction))
|
if (operation.SourcesCount == 0 || IsIntrinsic(operation.Instruction))
|
||||||
{
|
{
|
||||||
|
@ -206,7 +200,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Node HandleFixedRegisterCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
|
private static Node HandleConstrainedRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
|
||||||
{
|
{
|
||||||
Operand dest = operation.Destination;
|
Operand dest = operation.Destination;
|
||||||
|
|
||||||
|
@ -248,14 +242,20 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
// Handle the many restrictions of the compare and exchange (32/64) instruction:
|
// Handle the many restrictions of the compare and exchange (32/64) instruction:
|
||||||
// - The expected value should be in (E/R)AX.
|
// - The expected value should be in (E/R)AX.
|
||||||
// - The value at the memory location is loaded to (E/R)AX.
|
// - The value at the memory location is loaded to (E/R)AX.
|
||||||
|
|
||||||
Operand expected = operation.GetSource(1);
|
Operand expected = operation.GetSource(1);
|
||||||
|
Operand newValue = operation.GetSource(2);
|
||||||
|
|
||||||
Operand rax = Gpr(X86Register.Rax, expected.Type);
|
Operand rax = Gpr(X86Register.Rax, expected.Type);
|
||||||
|
|
||||||
nodes.AddBefore(node, Operation(Instruction.Copy, rax, expected));
|
nodes.AddBefore(node, Operation(Instruction.Copy, rax, expected));
|
||||||
|
|
||||||
operation.SetSources(new Operand[] { operation.GetSource(0), rax, operation.GetSource(2) });
|
// We need to store the new value into a temp, since it may
|
||||||
|
// be a constant, and this instruction does not support immediate operands.
|
||||||
|
Operand temp = Local(newValue.Type);
|
||||||
|
|
||||||
|
nodes.AddBefore(node, Operation(Instruction.Copy, temp, newValue));
|
||||||
|
|
||||||
|
operation.SetSources(new Operand[] { operation.GetSource(0), rax, temp });
|
||||||
|
|
||||||
node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
|
node = nodes.AddAfter(node, Operation(Instruction.Copy, dest, rax));
|
||||||
|
|
||||||
|
@ -391,7 +391,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Node HandleSameDestSrc1Copy(IntrusiveList<Node> nodes, Node node, Operation operation)
|
private static Node HandleDestructiveRegCopy(IntrusiveList<Node> nodes, Node node, Operation operation)
|
||||||
{
|
{
|
||||||
if (operation.Destination == null || operation.SourcesCount == 0)
|
if (operation.Destination == null || operation.SourcesCount == 0)
|
||||||
{
|
{
|
||||||
|
@ -683,7 +683,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
Operation storeOp = Operation(Instruction.Store, null, stackAddr, source);
|
Operation storeOp = Operation(Instruction.Store, null, stackAddr, source);
|
||||||
|
|
||||||
HandleConstantCopy(nodes, nodes.AddBefore(node, storeOp), storeOp);
|
HandleConstantRegCopy(nodes, nodes.AddBefore(node, storeOp), storeOp);
|
||||||
|
|
||||||
operation.SetSource(index, stackAddr);
|
operation.SetSource(index, stackAddr);
|
||||||
}
|
}
|
||||||
|
@ -709,7 +709,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
Operation copyOp = Operation(Instruction.Copy, argReg, source);
|
Operation copyOp = Operation(Instruction.Copy, argReg, source);
|
||||||
|
|
||||||
HandleConstantCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
|
HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
|
||||||
|
|
||||||
sources[1 + retArgs + index] = argReg;
|
sources[1 + retArgs + index] = argReg;
|
||||||
}
|
}
|
||||||
|
@ -724,7 +724,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
Operation spillOp = Operation(Instruction.SpillArg, null, offset, source);
|
Operation spillOp = Operation(Instruction.SpillArg, null, offset, source);
|
||||||
|
|
||||||
HandleConstantCopy(nodes, nodes.AddBefore(node, spillOp), spillOp);
|
HandleConstantRegCopy(nodes, nodes.AddBefore(node, spillOp), spillOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest != null)
|
if (dest != null)
|
||||||
|
@ -818,7 +818,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
Operation copyOp = Operation(Instruction.Copy, argReg, source);
|
Operation copyOp = Operation(Instruction.Copy, argReg, source);
|
||||||
|
|
||||||
HandleConstantCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
|
HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
|
||||||
|
|
||||||
sources.Add(argReg);
|
sources.Add(argReg);
|
||||||
}
|
}
|
||||||
|
@ -828,7 +828,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
Operation spillOp = Operation(Instruction.SpillArg, null, offset, source);
|
Operation spillOp = Operation(Instruction.SpillArg, null, offset, source);
|
||||||
|
|
||||||
HandleConstantCopy(nodes, nodes.AddBefore(node, spillOp), spillOp);
|
HandleConstantRegCopy(nodes, nodes.AddBefore(node, spillOp), spillOp);
|
||||||
|
|
||||||
stackOffset += source.Type.GetSizeInBytes();
|
stackOffset += source.Type.GetSizeInBytes();
|
||||||
}
|
}
|
||||||
|
@ -867,9 +867,10 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
List<Operand> sources = new List<Operand>();
|
List<Operand> sources = new List<Operand>
|
||||||
|
{
|
||||||
sources.Add(operation.GetSource(0));
|
operation.GetSource(0)
|
||||||
|
};
|
||||||
|
|
||||||
int argsCount = operation.SourcesCount - 1;
|
int argsCount = operation.SourcesCount - 1;
|
||||||
|
|
||||||
|
@ -915,7 +916,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
Operation copyOp = Operation(Instruction.Copy, argReg, source);
|
Operation copyOp = Operation(Instruction.Copy, argReg, source);
|
||||||
|
|
||||||
HandleConstantCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
|
HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
|
||||||
|
|
||||||
sources.Add(argReg);
|
sources.Add(argReg);
|
||||||
}
|
}
|
||||||
|
@ -963,7 +964,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
Operation copyOp = Operation(Instruction.Copy, argReg, source);
|
Operation copyOp = Operation(Instruction.Copy, argReg, source);
|
||||||
|
|
||||||
HandleConstantCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
|
HandleConstantRegCopy(nodes, nodes.AddBefore(node, copyOp), copyOp);
|
||||||
|
|
||||||
sources[1 + index] = argReg;
|
sources[1 + index] = argReg;
|
||||||
}
|
}
|
||||||
|
@ -982,7 +983,7 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
operation.SetSources(sources);
|
operation.SetSources(sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandleLoadArgumentWindowsAbi(
|
private static Node HandleLoadArgumentWindowsAbi(
|
||||||
CompilerContext cctx,
|
CompilerContext cctx,
|
||||||
IntrusiveList<Node> nodes,
|
IntrusiveList<Node> nodes,
|
||||||
Node node,
|
Node node,
|
||||||
|
@ -1035,17 +1036,20 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
? Instruction.Load
|
? Instruction.Load
|
||||||
: Instruction.Copy, dest, preservedArgs[index]);
|
: Instruction.Copy, dest, preservedArgs[index]);
|
||||||
|
|
||||||
nodes.AddBefore(node, argCopyOp);
|
Node newNode = nodes.AddBefore(node, argCopyOp);
|
||||||
|
|
||||||
Delete(nodes, node, operation);
|
Delete(nodes, node, operation);
|
||||||
|
|
||||||
|
return newNode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: Pass on stack.
|
// TODO: Pass on stack.
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandleLoadArgumentSystemVAbi(
|
private static Node HandleLoadArgumentSystemVAbi(
|
||||||
CompilerContext cctx,
|
CompilerContext cctx,
|
||||||
IntrusiveList<Node> nodes,
|
IntrusiveList<Node> nodes,
|
||||||
Node node,
|
Node node,
|
||||||
|
@ -1134,13 +1138,16 @@ namespace ARMeilleure.CodeGen.X86
|
||||||
|
|
||||||
Operation argCopyOp = Operation(Instruction.Copy, dest, preservedArgs[index]);
|
Operation argCopyOp = Operation(Instruction.Copy, dest, preservedArgs[index]);
|
||||||
|
|
||||||
nodes.AddBefore(node, argCopyOp);
|
Node newNode = nodes.AddBefore(node, argCopyOp);
|
||||||
|
|
||||||
Delete(nodes, node, operation);
|
Delete(nodes, node, operation);
|
||||||
|
|
||||||
|
return newNode;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TODO: Pass on stack.
|
// TODO: Pass on stack.
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue