Change placement of XMM callee save and restore code to match other compilers
This commit is contained in:
parent
a3ea200444
commit
db5e612914
4 changed files with 62 additions and 45 deletions
|
@ -22,7 +22,7 @@ namespace ARMeilleure.CodeGen.X86
|
|||
public BasicBlock CurrBlock { get; private set; }
|
||||
|
||||
public int CallArgsRegionSize { get; }
|
||||
public int VecCalleeSaveSize { get; }
|
||||
public int XmmSaveRegionSize { get; }
|
||||
|
||||
private long[] _blockOffsets;
|
||||
|
||||
|
@ -80,24 +80,24 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
Assembler = new Assembler(stream);
|
||||
|
||||
CallArgsRegionSize = GetCallArgsRegionSize(allocResult, maxCallArgs, out int vecCalleeSaveSize);
|
||||
VecCalleeSaveSize = vecCalleeSaveSize;
|
||||
CallArgsRegionSize = GetCallArgsRegionSize(allocResult, maxCallArgs, out int xmmSaveRegionSize);
|
||||
XmmSaveRegionSize = xmmSaveRegionSize;
|
||||
|
||||
_blockOffsets = new long[blocksCount];
|
||||
|
||||
_jumps = new List<Jump>();
|
||||
}
|
||||
|
||||
private int GetCallArgsRegionSize(AllocationResult allocResult, int maxCallArgs, out int vecCalleeSaveSize)
|
||||
private 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;
|
||||
|
||||
vecCalleeSaveSize = BitUtils.CountBits(vecMask) * 16;
|
||||
xmmSaveRegionSize = BitUtils.CountBits(vecMask) * 16;
|
||||
|
||||
int calleeSaveRegionSize = BitUtils.CountBits(intMask) * 8 + vecCalleeSaveSize + 8;
|
||||
int calleeSaveRegionSize = BitUtils.CountBits(intMask) * 8 + xmmSaveRegionSize + 8;
|
||||
|
||||
int argsCount = maxCallArgs;
|
||||
|
||||
|
|
|
@ -1523,9 +1523,23 @@ namespace ARMeilleure.CodeGen.X86
|
|||
mask &= ~(1 << bit);
|
||||
}
|
||||
|
||||
mask = CallingConvention.GetVecCalleeSavedRegisters() & context.AllocResult.VecUsedRegisters;
|
||||
int reservedStackSize = context.CallArgsRegionSize + context.AllocResult.SpillRegionSize;
|
||||
|
||||
int offset = 0;
|
||||
reservedStackSize += context.XmmSaveRegionSize;
|
||||
|
||||
if (reservedStackSize >= StackGuardSize)
|
||||
{
|
||||
GenerateInlineStackProbe(context, reservedStackSize);
|
||||
}
|
||||
|
||||
if (reservedStackSize != 0)
|
||||
{
|
||||
context.Assembler.Sub(rsp, new Operand(reservedStackSize), OperandType.I64);
|
||||
}
|
||||
|
||||
int offset = reservedStackSize;
|
||||
|
||||
mask = CallingConvention.GetVecCalleeSavedRegisters() & context.AllocResult.VecUsedRegisters;
|
||||
|
||||
while (mask != 0)
|
||||
{
|
||||
|
@ -1542,20 +1556,6 @@ namespace ARMeilleure.CodeGen.X86
|
|||
mask &= ~(1 << bit);
|
||||
}
|
||||
|
||||
int reservedStackSize = context.CallArgsRegionSize + context.AllocResult.SpillRegionSize;
|
||||
|
||||
reservedStackSize += context.VecCalleeSaveSize;
|
||||
|
||||
if (reservedStackSize >= StackGuardSize)
|
||||
{
|
||||
GenerateInlineStackProbe(context, reservedStackSize);
|
||||
}
|
||||
|
||||
if (reservedStackSize != 0)
|
||||
{
|
||||
context.Assembler.Sub(rsp, new Operand(reservedStackSize), OperandType.I64);
|
||||
}
|
||||
|
||||
return new UnwindInfo(pushEntries.ToArray(), context.StreamOffset, reservedStackSize);
|
||||
}
|
||||
|
||||
|
@ -1565,17 +1565,12 @@ namespace ARMeilleure.CodeGen.X86
|
|||
|
||||
int reservedStackSize = context.CallArgsRegionSize + context.AllocResult.SpillRegionSize;
|
||||
|
||||
reservedStackSize += context.VecCalleeSaveSize;
|
||||
reservedStackSize += context.XmmSaveRegionSize;
|
||||
|
||||
if (reservedStackSize != 0)
|
||||
{
|
||||
context.Assembler.Add(rsp, new Operand(reservedStackSize), OperandType.I64);
|
||||
}
|
||||
int offset = reservedStackSize;
|
||||
|
||||
int mask = CallingConvention.GetVecCalleeSavedRegisters() & context.AllocResult.VecUsedRegisters;
|
||||
|
||||
int offset = 0;
|
||||
|
||||
while (mask != 0)
|
||||
{
|
||||
int bit = BitUtils.LowestBitSet(mask);
|
||||
|
@ -1589,6 +1584,11 @@ namespace ARMeilleure.CodeGen.X86
|
|||
mask &= ~(1 << bit);
|
||||
}
|
||||
|
||||
if (reservedStackSize != 0)
|
||||
{
|
||||
context.Assembler.Add(rsp, new Operand(reservedStackSize), OperandType.I64);
|
||||
}
|
||||
|
||||
mask = CallingConvention.GetIntCalleeSavedRegisters() & context.AllocResult.IntUsedRegisters;
|
||||
|
||||
while (mask != 0)
|
||||
|
|
|
@ -58,7 +58,7 @@ namespace ARMeilleure.Translation
|
|||
{
|
||||
// Map pages that are already full as RX.
|
||||
// Map pages that are not full yet as RWX.
|
||||
// On unix, the address and size must be page aligned.
|
||||
// On unix, the address must be page aligned.
|
||||
int endOffs = offset + size;
|
||||
|
||||
int pageStart = offset & ~PageMask;
|
||||
|
|
|
@ -99,31 +99,48 @@ namespace ARMeilleure.Translation
|
|||
|
||||
var unwindInfo = funcEntry.UnwindInfo;
|
||||
|
||||
_unwindInfo->UnwindCodes[0] = PackUwop(UnwindOperation.AllocLarge, unwindInfo.PrologueSize, 1);
|
||||
_unwindInfo->UnwindCodes[1] = (ushort)(unwindInfo.FixedAllocSize >> 0);
|
||||
_unwindInfo->UnwindCodes[2] = (ushort)(unwindInfo.FixedAllocSize >> 16);
|
||||
int codeIndex = 0;
|
||||
|
||||
int codeIndex = 3;
|
||||
int spOffset = unwindInfo.FixedAllocSize;
|
||||
|
||||
int spOffset = 0;
|
||||
foreach (var entry in unwindInfo.PushEntries)
|
||||
{
|
||||
if (entry.Type == RegisterType.Vector)
|
||||
{
|
||||
spOffset -= 16;
|
||||
}
|
||||
}
|
||||
|
||||
for (int index = unwindInfo.PushEntries.Length - 1; index >= 0; index--)
|
||||
{
|
||||
var entry = unwindInfo.PushEntries[index];
|
||||
|
||||
bool isInteger = entry.Type == RegisterType.Integer;
|
||||
|
||||
UnwindOperation uwop = isInteger
|
||||
? UnwindOperation.PushNonvol
|
||||
: UnwindOperation.SaveXmm128;
|
||||
|
||||
_unwindInfo->UnwindCodes[codeIndex++] = PackUwop(uwop, entry.StreamEndOffset, entry.Index);
|
||||
|
||||
if (!isInteger)
|
||||
if (entry.Type == RegisterType.Vector)
|
||||
{
|
||||
ushort uwop = PackUwop(UnwindOperation.SaveXmm128, entry.StreamEndOffset, entry.Index);
|
||||
|
||||
_unwindInfo->UnwindCodes[codeIndex++] = uwop;
|
||||
_unwindInfo->UnwindCodes[codeIndex++] = (ushort)spOffset;
|
||||
|
||||
spOffset -= 16;
|
||||
spOffset += 16;
|
||||
}
|
||||
}
|
||||
|
||||
_unwindInfo->UnwindCodes[0] = PackUwop(UnwindOperation.AllocLarge, unwindInfo.PrologueSize, 1);
|
||||
_unwindInfo->UnwindCodes[1] = (ushort)(unwindInfo.FixedAllocSize >> 0);
|
||||
_unwindInfo->UnwindCodes[2] = (ushort)(unwindInfo.FixedAllocSize >> 16);
|
||||
|
||||
codeIndex += 3;
|
||||
|
||||
for (int index = unwindInfo.PushEntries.Length - 1; index >= 0; index--)
|
||||
{
|
||||
var entry = unwindInfo.PushEntries[index];
|
||||
|
||||
if (entry.Type == RegisterType.Integer)
|
||||
{
|
||||
ushort uwop = PackUwop(UnwindOperation.PushNonvol, entry.StreamEndOffset, entry.Index);
|
||||
|
||||
_unwindInfo->UnwindCodes[codeIndex++] = uwop;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue