* dotnet format style --severity info Some changes were manually reverted. * dotnet format analyzers --serverity info Some changes have been minimally adapted. * Restore a few unused methods and variables * Silence dotnet format IDE0060 warnings * Silence dotnet format IDE0052 warnings * Address or silence dotnet format IDE1006 warnings * Address or silence dotnet format CA2208 warnings * Address dotnet format CA1822 warnings * Address or silence dotnet format CA1069 warnings * Silence CA1806 and CA1834 issues * Address dotnet format CA1401 warnings * Fix new dotnet-format issues after rebase * Address review comments * Address dotnet format CA2208 warnings properly * Fix formatting for switch expressions * Address most dotnet format whitespace warnings * Apply dotnet format whitespace formatting A few of them have been manually reverted and the corresponding warning was silenced * Add previously silenced warnings back I have no clue how these disappeared * Revert formatting changes for OpCodeTable.cs * Enable formatting for a few cases again * Format if-blocks correctly * Enable formatting for a few more cases again * Fix inline comment alignment * Run dotnet format after rebase and remove unused usings - analyzers - style - whitespace * Disable 'prefer switch expression' rule * Add comments to disabled warnings * Remove a few unused parameters * Adjust namespaces * Simplify properties and array initialization, Use const when possible, Remove trailing commas * Start working on disabled warnings * Fix and silence a few dotnet-format warnings again * Address IDE0251 warnings * Address a few disabled IDE0060 warnings * Silence IDE0060 in .editorconfig * Revert "Simplify properties and array initialization, Use const when possible, Remove trailing commas" This reverts commit 9462e4136c0a2100dc28b20cf9542e06790aa67e. * dotnet format whitespace after rebase * First dotnet format pass * Remove unnecessary formatting exclusion * Add unsafe dotnet format changes * Change visibility of JitSupportDarwin to internal
106 lines
3.7 KiB
C#
106 lines
3.7 KiB
C#
using ARMeilleure.CodeGen.RegisterAllocators;
|
|
using ARMeilleure.IntermediateRepresentation;
|
|
using Ryujinx.Common.Memory;
|
|
using System.IO;
|
|
using System.Numerics;
|
|
|
|
namespace ARMeilleure.CodeGen.X86
|
|
{
|
|
class CodeGenContext
|
|
{
|
|
private readonly Stream _stream;
|
|
private readonly Operand[] _blockLabels;
|
|
|
|
public int StreamOffset => (int)_stream.Length;
|
|
|
|
public AllocationResult AllocResult { get; }
|
|
|
|
public Assembler Assembler { get; }
|
|
public BasicBlock CurrBlock { get; private set; }
|
|
|
|
public int CallArgsRegionSize { get; }
|
|
public int XmmSaveRegionSize { get; }
|
|
|
|
public CodeGenContext(AllocationResult allocResult, int maxCallArgs, int blocksCount, bool relocatable)
|
|
{
|
|
_stream = MemoryStreamManager.Shared.GetStream();
|
|
_blockLabels = new Operand[blocksCount];
|
|
|
|
AllocResult = allocResult;
|
|
Assembler = new Assembler(_stream, relocatable);
|
|
|
|
CallArgsRegionSize = GetCallArgsRegionSize(allocResult, maxCallArgs, out int xmmSaveRegionSize);
|
|
XmmSaveRegionSize = xmmSaveRegionSize;
|
|
}
|
|
|
|
private static int GetCallArgsRegionSize(AllocationResult allocResult, int maxCallArgs, out int xmmSaveRegionSize)
|
|
{
|
|
// We need to add 8 bytes to the total size, as the call to this function already pushed 8 bytes (the
|
|
// return address).
|
|
int intMask = CallingConvention.GetIntCalleeSavedRegisters() & allocResult.IntUsedRegisters;
|
|
int vecMask = CallingConvention.GetVecCalleeSavedRegisters() & allocResult.VecUsedRegisters;
|
|
|
|
xmmSaveRegionSize = BitOperations.PopCount((uint)vecMask) * 16;
|
|
|
|
int calleeSaveRegionSize = BitOperations.PopCount((uint)intMask) * 8 + xmmSaveRegionSize + 8;
|
|
|
|
int argsCount = maxCallArgs;
|
|
|
|
if (argsCount < 0)
|
|
{
|
|
// When the function has no calls, argsCount is -1. In this case, we don't need to allocate the shadow
|
|
// space.
|
|
argsCount = 0;
|
|
}
|
|
else if (argsCount < 4)
|
|
{
|
|
// The ABI mandates that the space for at least 4 arguments is reserved on the stack (this is called
|
|
// shadow space).
|
|
argsCount = 4;
|
|
}
|
|
|
|
// TODO: Align XMM save region to 16 bytes because unwinding on Windows requires it.
|
|
int frameSize = calleeSaveRegionSize + allocResult.SpillRegionSize;
|
|
|
|
// TODO: Instead of always multiplying by 16 (the largest possible size of a variable, since a V128 has 16
|
|
// bytes), we should calculate the exact size consumed by the arguments passed to the called functions on
|
|
// the stack.
|
|
int callArgsAndFrameSize = frameSize + argsCount * 16;
|
|
|
|
// Ensure that the Stack Pointer will be aligned to 16 bytes.
|
|
callArgsAndFrameSize = (callArgsAndFrameSize + 0xf) & ~0xf;
|
|
|
|
return callArgsAndFrameSize - frameSize;
|
|
}
|
|
|
|
public void EnterBlock(BasicBlock block)
|
|
{
|
|
Assembler.MarkLabel(GetLabel(block));
|
|
|
|
CurrBlock = block;
|
|
}
|
|
|
|
public void JumpTo(BasicBlock target)
|
|
{
|
|
Assembler.Jmp(GetLabel(target));
|
|
}
|
|
|
|
public void JumpTo(X86Condition condition, BasicBlock target)
|
|
{
|
|
Assembler.Jcc(condition, GetLabel(target));
|
|
}
|
|
|
|
private Operand GetLabel(BasicBlock block)
|
|
{
|
|
ref Operand label = ref _blockLabels[block.Index];
|
|
|
|
if (label == default)
|
|
{
|
|
label = Operand.Factory.Label();
|
|
}
|
|
|
|
return label;
|
|
}
|
|
}
|
|
}
|