|
|
@@ -1,7 +1,7 @@
|
|
|
+using ARMeilleure.CodeGen.Linking;
|
|
|
using ARMeilleure.CodeGen.RegisterAllocators;
|
|
|
using ARMeilleure.Common;
|
|
|
using ARMeilleure.IntermediateRepresentation;
|
|
|
-using ARMeilleure.Translation.PTC;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Diagnostics;
|
|
|
@@ -13,10 +13,8 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
{
|
|
|
private const int ReservedBytesForJump = 1;
|
|
|
|
|
|
- private Stream _stream;
|
|
|
-
|
|
|
- private PtcInfo _ptcInfo;
|
|
|
- private bool _ptcDisabled;
|
|
|
+ private readonly Stream _stream;
|
|
|
+ private readonly bool _relocatable;
|
|
|
|
|
|
public int StreamOffset => (int)_stream.Length;
|
|
|
|
|
|
@@ -27,22 +25,17 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
public BasicBlock CurrBlock { get; private set; }
|
|
|
|
|
|
public int CallArgsRegionSize { get; }
|
|
|
- public int XmmSaveRegionSize { get; }
|
|
|
+ public int XmmSaveRegionSize { get; }
|
|
|
|
|
|
- private long[] _blockOffsets;
|
|
|
+ private readonly long[] _blockOffsets;
|
|
|
|
|
|
private struct Jump
|
|
|
{
|
|
|
public bool IsConditional { get; }
|
|
|
-
|
|
|
public X86Condition Condition { get; }
|
|
|
-
|
|
|
public BasicBlock Target { get; }
|
|
|
-
|
|
|
public long JumpPosition { get; }
|
|
|
-
|
|
|
public long RelativeOffset { get; set; }
|
|
|
-
|
|
|
public int InstSize { get; set; }
|
|
|
|
|
|
public Jump(BasicBlock target, long jumpPosition, int instSize = 0)
|
|
|
@@ -70,33 +63,26 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private List<Jump> _jumps;
|
|
|
+ private readonly List<Jump> _jumps;
|
|
|
|
|
|
private X86Condition _jNearCondition;
|
|
|
-
|
|
|
private long _jNearPosition;
|
|
|
- private int _jNearLength;
|
|
|
+ private int _jNearLength;
|
|
|
|
|
|
- public CodeGenContext(Stream stream, AllocationResult allocResult, int maxCallArgs, int blocksCount, PtcInfo ptcInfo = null)
|
|
|
+ public CodeGenContext(Stream stream, AllocationResult allocResult, int maxCallArgs, int blocksCount, bool relocatable)
|
|
|
{
|
|
|
_stream = stream;
|
|
|
+ _relocatable = relocatable;
|
|
|
+ _blockOffsets = new long[blocksCount];
|
|
|
+ _jumps = new List<Jump>();
|
|
|
|
|
|
AllocResult = allocResult;
|
|
|
-
|
|
|
- Assembler = new Assembler(stream, ptcInfo);
|
|
|
-
|
|
|
+ Assembler = new Assembler(stream, relocatable);
|
|
|
CallArgsRegionSize = GetCallArgsRegionSize(allocResult, maxCallArgs, out int xmmSaveRegionSize);
|
|
|
XmmSaveRegionSize = xmmSaveRegionSize;
|
|
|
-
|
|
|
- _blockOffsets = new long[blocksCount];
|
|
|
-
|
|
|
- _jumps = new List<Jump>();
|
|
|
-
|
|
|
- _ptcInfo = ptcInfo;
|
|
|
- _ptcDisabled = ptcInfo == null;
|
|
|
}
|
|
|
|
|
|
- private int GetCallArgsRegionSize(AllocationResult allocResult, int maxCallArgs, out int 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).
|
|
|
@@ -144,7 +130,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
public void JumpTo(BasicBlock target)
|
|
|
{
|
|
|
- if (_ptcDisabled)
|
|
|
+ if (!_relocatable)
|
|
|
{
|
|
|
_jumps.Add(new Jump(target, _stream.Position));
|
|
|
|
|
|
@@ -160,7 +146,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
public void JumpTo(X86Condition condition, BasicBlock target)
|
|
|
{
|
|
|
- if (_ptcDisabled)
|
|
|
+ if (!_relocatable)
|
|
|
{
|
|
|
_jumps.Add(new Jump(condition, target, _stream.Position));
|
|
|
|
|
|
@@ -178,7 +164,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
{
|
|
|
_jNearCondition = condition;
|
|
|
_jNearPosition = _stream.Position;
|
|
|
- _jNearLength = Assembler.GetJccLength(0, _ptcDisabled);
|
|
|
+ _jNearLength = Assembler.GetJccLength(0, _relocatable);
|
|
|
|
|
|
_stream.Seek(_jNearLength, SeekOrigin.Current);
|
|
|
}
|
|
|
@@ -191,7 +177,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
long offset = currentPosition - (_jNearPosition + _jNearLength);
|
|
|
|
|
|
- Debug.Assert(_jNearLength == Assembler.GetJccLength(offset, _ptcDisabled), "Relative offset doesn't fit on near jump.");
|
|
|
+ Debug.Assert(_jNearLength == Assembler.GetJccLength(offset, _relocatable), "Relative offset doesn't fit on near jump.");
|
|
|
|
|
|
Assembler.Jcc(_jNearCondition, offset);
|
|
|
|
|
|
@@ -206,7 +192,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- public byte[] GetCode()
|
|
|
+ public (byte[], RelocInfo) GetCode()
|
|
|
{
|
|
|
// Write jump relative offsets.
|
|
|
bool modified;
|
|
|
@@ -223,7 +209,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
long offset = jumpTarget - jump.JumpPosition;
|
|
|
|
|
|
- if (_ptcDisabled)
|
|
|
+ if (!_relocatable)
|
|
|
{
|
|
|
if (offset < 0)
|
|
|
{
|
|
|
@@ -300,7 +286,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
using (MemoryStream codeStream = new MemoryStream())
|
|
|
{
|
|
|
- Assembler assembler = new Assembler(codeStream, _ptcInfo);
|
|
|
+ Assembler assembler = new Assembler(codeStream, _relocatable);
|
|
|
|
|
|
for (int index = 0; index < _jumps.Count; index++)
|
|
|
{
|
|
|
@@ -309,7 +295,7 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
Span<byte> buffer = new byte[jump.JumpPosition - _stream.Position];
|
|
|
|
|
|
_stream.Read(buffer);
|
|
|
- _stream.Seek(_ptcDisabled ? ReservedBytesForJump : jump.InstSize, SeekOrigin.Current);
|
|
|
+ _stream.Seek(!_relocatable ? ReservedBytesForJump : jump.InstSize, SeekOrigin.Current);
|
|
|
|
|
|
codeStream.Write(buffer);
|
|
|
|
|
|
@@ -325,7 +311,12 @@ namespace ARMeilleure.CodeGen.X86
|
|
|
|
|
|
_stream.CopyTo(codeStream);
|
|
|
|
|
|
- return codeStream.ToArray();
|
|
|
+ var code = codeStream.ToArray();
|
|
|
+ var relocInfo = Assembler.HasRelocs
|
|
|
+ ? new RelocInfo(Assembler.Relocs.ToArray())
|
|
|
+ : RelocInfo.Empty;
|
|
|
+
|
|
|
+ return (code, relocInfo);
|
|
|
}
|
|
|
}
|
|
|
}
|