Fix arguments count with struct return values, other fixes
This commit is contained in:
parent
0bacc3fd63
commit
9f8fbc1d8a
6 changed files with 37 additions and 26 deletions
|
@ -5,18 +5,15 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
public int IntUsedRegisters { get; }
|
||||
public int VecUsedRegisters { get; }
|
||||
public int SpillRegionSize { get; }
|
||||
public int MaxCallArgs { get; }
|
||||
|
||||
public AllocationResult(
|
||||
int intUsedRegisters,
|
||||
int vecUsedRegisters,
|
||||
int spillRegionSize,
|
||||
int maxCallArgs)
|
||||
int spillRegionSize)
|
||||
{
|
||||
IntUsedRegisters = intUsedRegisters;
|
||||
VecUsedRegisters = vecUsedRegisters;
|
||||
SpillRegionSize = spillRegionSize;
|
||||
MaxCallArgs = maxCallArgs;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -77,7 +77,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
|
||||
AllocationContext context = new AllocationContext(regMasks, _intervals.Count);
|
||||
|
||||
BuildIntervals(cfg, context, out int maxCallArgs);
|
||||
BuildIntervals(cfg, context);
|
||||
|
||||
for (int index = 0; index < _intervals.Count; index++)
|
||||
{
|
||||
|
@ -115,8 +115,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
return new AllocationResult(
|
||||
context.IntUsedRegisters,
|
||||
context.VecUsedRegisters,
|
||||
context.StackAlloc.TotalSize,
|
||||
maxCallArgs);
|
||||
context.StackAlloc.TotalSize);
|
||||
}
|
||||
|
||||
private void AllocateInterval(AllocationContext context, LiveInterval current, int cIndex)
|
||||
|
@ -774,10 +773,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
_parentIntervals = _intervals.ToArray();
|
||||
}
|
||||
|
||||
private void BuildIntervals(ControlFlowGraph cfg, AllocationContext context, out int maxCallArgs)
|
||||
private void BuildIntervals(ControlFlowGraph cfg, AllocationContext context)
|
||||
{
|
||||
maxCallArgs = 0;
|
||||
|
||||
_blockRanges = new LiveRange[cfg.Blocks.Count];
|
||||
|
||||
int mapSize = _intervals.Count;
|
||||
|
@ -912,11 +909,6 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
|
|||
{
|
||||
AddIntervalCallerSavedReg(context.Masks.IntCallerSavedRegisters, operationPos, RegisterType.Integer);
|
||||
AddIntervalCallerSavedReg(context.Masks.VecCallerSavedRegisters, operationPos, RegisterType.Vector);
|
||||
|
||||
if (maxCallArgs < operation.SourcesCount - 1)
|
||||
{
|
||||
maxCallArgs = operation.SourcesCount - 1;
|
||||
}
|
||||
}
|
||||
else if (operation.Inst == Instruction.StackAlloc)
|
||||
{
|
||||
|
|
|
@ -71,7 +71,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
private long _jNearPosition;
|
||||
private int _jNearLength;
|
||||
|
||||
public CodeGenContext(Stream stream, AllocationResult allocResult, int blocksCount)
|
||||
public CodeGenContext(Stream stream, AllocationResult allocResult, int maxCallArgs, int blocksCount)
|
||||
{
|
||||
_stream = stream;
|
||||
|
||||
|
@ -79,7 +79,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
Assembler = new Assembler(stream);
|
||||
|
||||
CallArgsRegionSize = GetCallArgsRegionSize(allocResult, out int vecCalleeSaveSize);
|
||||
CallArgsRegionSize = GetCallArgsRegionSize(allocResult, maxCallArgs, out int vecCalleeSaveSize);
|
||||
|
||||
VecCalleeSaveSize = vecCalleeSaveSize;
|
||||
|
||||
|
@ -88,7 +88,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
_jumps = new List<Jump>();
|
||||
}
|
||||
|
||||
private int GetCallArgsRegionSize(AllocationResult allocResult, out int vecCalleeSaveSize)
|
||||
private int GetCallArgsRegionSize(AllocationResult allocResult, int maxCallArgs, out int vecCalleeSaveSize)
|
||||
{
|
||||
//We need to add 8 bytes to the total size, as the call to this
|
||||
//function already pushed 8 bytes (the return address).
|
||||
|
@ -101,7 +101,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
int calleeSaveRegionSize = BitUtils.CountBits(intMask) * 8 + vecCalleeSaveSize + 8;
|
||||
|
||||
int argsCount = allocResult.MaxCallArgs;
|
||||
int argsCount = maxCallArgs;
|
||||
|
||||
//The ABI mandates that the space for at least 4 arguments
|
||||
//is reserved on the stack (this is called shadow space).
|
||||
|
|
|
@ -231,7 +231,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
Logger.StartPass(PassName.PreAllocation);
|
||||
|
||||
PreAllocator.RunPass(cfg, memory);
|
||||
PreAllocator.RunPass(cfg, memory, out int maxCallArgs);
|
||||
|
||||
Logger.EndPass(PassName.PreAllocation, cfg);
|
||||
|
||||
|
@ -253,7 +253,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
using (MemoryStream stream = new MemoryStream())
|
||||
{
|
||||
CodeGenContext context = new CodeGenContext(stream, allocResult, cfg.Blocks.Count);
|
||||
CodeGenContext context = new CodeGenContext(stream, allocResult, maxCallArgs, cfg.Blocks.Count);
|
||||
|
||||
WritePrologue(context);
|
||||
|
||||
|
|
|
@ -10,8 +10,10 @@ namespace ARMeilleure.CodeGen.X86
|
|||
{
|
||||
static class PreAllocator
|
||||
{
|
||||
public static void RunPass(ControlFlowGraph cfg, MemoryManager memory)
|
||||
public static void RunPass(ControlFlowGraph cfg, MemoryManager memory, out int maxCallArgs)
|
||||
{
|
||||
maxCallArgs = 0;
|
||||
|
||||
foreach (BasicBlock block in cfg.Blocks)
|
||||
{
|
||||
LinkedListNode<Node> nextNode;
|
||||
|
@ -55,6 +57,24 @@ namespace ARMeilleure.CodeGen.X86
|
|||
ReplaceNegateWithXor(node, operation);
|
||||
}
|
||||
|
||||
//Get the maximum number of arguments used on a call. On windows,
|
||||
//when a struct is returned from the call, we also need to pass
|
||||
//the pointer where the struct should be written on the first argument.
|
||||
if (inst == Instruction.Call)
|
||||
{
|
||||
int argsCount = operation.SourcesCount - 1;
|
||||
|
||||
if (operation.Dest != null && operation.Dest.Type == OperandType.V128)
|
||||
{
|
||||
argsCount++;
|
||||
}
|
||||
|
||||
if (maxCallArgs < argsCount)
|
||||
{
|
||||
maxCallArgs = argsCount;
|
||||
}
|
||||
}
|
||||
|
||||
HandleFixedRegisterCopy(node, operation);
|
||||
|
||||
HandleSameDestSrc1Copy(node, operation);
|
||||
|
@ -597,6 +617,8 @@ namespace ARMeilleure.CodeGen.X86
|
|||
{
|
||||
case Instruction.Copy:
|
||||
case Instruction.LoadFromContext:
|
||||
case Instruction.Spill:
|
||||
case Instruction.SpillArg:
|
||||
case Instruction.StoreToContext:
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -882,7 +882,7 @@ namespace ARMeilleure.Instructions
|
|||
byte[] res = new byte[16];
|
||||
byte[] table = new byte[tb.Length * 16];
|
||||
|
||||
for (byte index = 0; index < tb.Length; index++)
|
||||
for (byte index = 0; index < tb.Length; index++)
|
||||
{
|
||||
Buffer.BlockCopy(tb[index].ToArray(), 0, table, index * 16, 16);
|
||||
}
|
||||
|
@ -891,11 +891,11 @@ namespace ARMeilleure.Instructions
|
|||
|
||||
for (byte index = 0; index < bytes; index++)
|
||||
{
|
||||
byte tblIdx = v[index];
|
||||
byte tblIndex = v[index];
|
||||
|
||||
if (tblIdx < table.Length)
|
||||
if (tblIndex < table.Length)
|
||||
{
|
||||
res[index] = table[tblIdx];
|
||||
res[index] = table[tblIndex];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue