diff options
Diffstat (limited to 'ARMeilleure/CodeGen')
| -rw-r--r-- | ARMeilleure/CodeGen/Optimizations/ConstantFolding.cs | 8 | ||||
| -rw-r--r-- | ARMeilleure/CodeGen/Unwinding/UnwindPseudoOp.cs | 11 | ||||
| -rw-r--r-- | ARMeilleure/CodeGen/Unwinding/UnwindPseudoOperation.cs | 11 | ||||
| -rw-r--r-- | ARMeilleure/CodeGen/X86/Assembler.cs | 28 | ||||
| -rw-r--r-- | ARMeilleure/CodeGen/X86/CodeGenContext.cs | 132 | ||||
| -rw-r--r-- | ARMeilleure/CodeGen/X86/CodeGenerator.cs | 7 |
6 files changed, 125 insertions, 72 deletions
diff --git a/ARMeilleure/CodeGen/Optimizations/ConstantFolding.cs b/ARMeilleure/CodeGen/Optimizations/ConstantFolding.cs index 84eedee0..eff53217 100644 --- a/ARMeilleure/CodeGen/Optimizations/ConstantFolding.cs +++ b/ARMeilleure/CodeGen/Optimizations/ConstantFolding.cs @@ -14,7 +14,7 @@ namespace ARMeilleure.CodeGen.Optimizations return; } - if (!AreAllSourcesConstant(operation)) + if (!AreAllSourcesConstantAndCFEnabled(operation)) { return; } @@ -212,11 +212,13 @@ namespace ARMeilleure.CodeGen.Optimizations } } - private static bool AreAllSourcesConstant(Operation operation) + private static bool AreAllSourcesConstantAndCFEnabled(Operation operation) { for (int index = 0; index < operation.SourcesCount; index++) { - if (operation.GetSource(index).Kind != OperandKind.Constant) + Operand srcOp = operation.GetSource(index); + + if (srcOp.Kind != OperandKind.Constant || srcOp.DisableCF) { return false; } diff --git a/ARMeilleure/CodeGen/Unwinding/UnwindPseudoOp.cs b/ARMeilleure/CodeGen/Unwinding/UnwindPseudoOp.cs new file mode 100644 index 00000000..4a8288a2 --- /dev/null +++ b/ARMeilleure/CodeGen/Unwinding/UnwindPseudoOp.cs @@ -0,0 +1,11 @@ +namespace ARMeilleure.CodeGen.Unwinding +{ + enum UnwindPseudoOp + { + PushReg = 0, + SetFrame = 1, + AllocStack = 2, + SaveReg = 3, + SaveXmm128 = 4 + } +}
\ No newline at end of file diff --git a/ARMeilleure/CodeGen/Unwinding/UnwindPseudoOperation.cs b/ARMeilleure/CodeGen/Unwinding/UnwindPseudoOperation.cs deleted file mode 100644 index 44ed23f5..00000000 --- a/ARMeilleure/CodeGen/Unwinding/UnwindPseudoOperation.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace ARMeilleure.CodeGen.Unwinding -{ - enum UnwindPseudoOp - { - PushReg, - SetFrame, - AllocStack, - SaveReg, - SaveXmm128 - } -}
\ No newline at end of file diff --git a/ARMeilleure/CodeGen/X86/Assembler.cs b/ARMeilleure/CodeGen/X86/Assembler.cs index 5ad54289..99df3cb5 100644 --- a/ARMeilleure/CodeGen/X86/Assembler.cs +++ b/ARMeilleure/CodeGen/X86/Assembler.cs @@ -1,4 +1,5 @@ using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.Translation.PTC; using System; using System.Diagnostics; using System.IO; @@ -64,6 +65,9 @@ namespace ARMeilleure.CodeGen.X86 private Stream _stream; + private PtcInfo _ptcInfo; + private bool _ptcDisabled; + static Assembler() { _instTable = new InstructionInfo[(int)X86Instruction.Count]; @@ -273,9 +277,12 @@ namespace ARMeilleure.CodeGen.X86 _instTable[(int)inst] = info; } - public Assembler(Stream stream) + public Assembler(Stream stream, PtcInfo ptcInfo = null) { _stream = stream; + + _ptcInfo = ptcInfo; + _ptcDisabled = ptcInfo == null; } public void Add(Operand dest, Operand source, OperandType type) @@ -456,7 +463,7 @@ namespace ARMeilleure.CodeGen.X86 public void Jcc(X86Condition condition, long offset) { - if (ConstFitsOnS8(offset)) + if (_ptcDisabled && ConstFitsOnS8(offset)) { WriteByte((byte)(0x70 | (int)condition)); @@ -477,7 +484,7 @@ namespace ARMeilleure.CodeGen.X86 public void Jmp(long offset) { - if (ConstFitsOnS8(offset)) + if (_ptcDisabled && ConstFitsOnS8(offset)) { WriteByte(0xeb); @@ -915,6 +922,8 @@ namespace ARMeilleure.CodeGen.X86 } else if (dest != null && dest.Kind == OperandKind.Register && info.OpRImm64 != BadOp) { + int? index = source.PtcIndex; + int rexPrefix = GetRexPrefix(dest, source, type, rrm: false); if (rexPrefix != 0) @@ -924,6 +933,11 @@ namespace ARMeilleure.CodeGen.X86 WriteByte((byte)(info.OpRImm64 + (dest.GetRegister().Index & 0b111))); + if (_ptcInfo != null && index != null) + { + _ptcInfo.WriteRelocEntry(new RelocEntry((int)_stream.Position, (int)index)); + } + WriteUInt64(imm); } else @@ -1316,9 +1330,9 @@ namespace ARMeilleure.CodeGen.X86 return ConstFitsOnS32(value); } - public static int GetJccLength(long offset) + public static int GetJccLength(long offset, bool ptcDisabled = true) { - if (ConstFitsOnS8(offset < 0 ? offset - 2 : offset)) + if (ptcDisabled && ConstFitsOnS8(offset < 0 ? offset - 2 : offset)) { return 2; } @@ -1332,9 +1346,9 @@ namespace ARMeilleure.CodeGen.X86 } } - public static int GetJmpLength(long offset) + public static int GetJmpLength(long offset, bool ptcDisabled = true) { - if (ConstFitsOnS8(offset < 0 ? offset - 2 : offset)) + if (ptcDisabled && ConstFitsOnS8(offset < 0 ? offset - 2 : offset)) { return 2; } diff --git a/ARMeilleure/CodeGen/X86/CodeGenContext.cs b/ARMeilleure/CodeGen/X86/CodeGenContext.cs index d719b516..da147cca 100644 --- a/ARMeilleure/CodeGen/X86/CodeGenContext.cs +++ b/ARMeilleure/CodeGen/X86/CodeGenContext.cs @@ -1,6 +1,7 @@ using ARMeilleure.CodeGen.RegisterAllocators; using ARMeilleure.Common; using ARMeilleure.IntermediateRepresentation; +using ARMeilleure.Translation.PTC; using System.Collections.Generic; using System.Diagnostics; using System.IO; @@ -13,6 +14,9 @@ namespace ARMeilleure.CodeGen.X86 private Stream _stream; + private PtcInfo _ptcInfo; + private bool _ptcDisabled; + public int StreamOffset => (int)_stream.Length; public AllocationResult AllocResult { get; } @@ -40,7 +44,7 @@ namespace ARMeilleure.CodeGen.X86 public int InstSize { get; set; } - public Jump(BasicBlock target, long jumpPosition) + public Jump(BasicBlock target, long jumpPosition, int instSize = 0) { IsConditional = false; Condition = 0; @@ -49,10 +53,10 @@ namespace ARMeilleure.CodeGen.X86 RelativeOffset = 0; - InstSize = 0; + InstSize = instSize; } - public Jump(X86Condition condition, BasicBlock target, long jumpPosition) + public Jump(X86Condition condition, BasicBlock target, long jumpPosition, int instSize = 0) { IsConditional = true; Condition = condition; @@ -61,7 +65,7 @@ namespace ARMeilleure.CodeGen.X86 RelativeOffset = 0; - InstSize = 0; + InstSize = instSize; } } @@ -72,13 +76,13 @@ namespace ARMeilleure.CodeGen.X86 private long _jNearPosition; private int _jNearLength; - public CodeGenContext(Stream stream, AllocationResult allocResult, int maxCallArgs, int blocksCount) + public CodeGenContext(Stream stream, AllocationResult allocResult, int maxCallArgs, int blocksCount, PtcInfo ptcInfo = null) { _stream = stream; AllocResult = allocResult; - Assembler = new Assembler(stream); + Assembler = new Assembler(stream, ptcInfo); CallArgsRegionSize = GetCallArgsRegionSize(allocResult, maxCallArgs, out int xmmSaveRegionSize); XmmSaveRegionSize = xmmSaveRegionSize; @@ -86,6 +90,9 @@ namespace ARMeilleure.CodeGen.X86 _blockOffsets = new long[blocksCount]; _jumps = new List<Jump>(); + + _ptcInfo = ptcInfo; + _ptcDisabled = ptcInfo == null; } private int GetCallArgsRegionSize(AllocationResult allocResult, int maxCallArgs, out int xmmSaveRegionSize) @@ -136,23 +143,41 @@ namespace ARMeilleure.CodeGen.X86 public void JumpTo(BasicBlock target) { - _jumps.Add(new Jump(target, _stream.Position)); + if (_ptcDisabled) + { + _jumps.Add(new Jump(target, _stream.Position)); - WritePadding(ReservedBytesForJump); + WritePadding(ReservedBytesForJump); + } + else + { + _jumps.Add(new Jump(target, _stream.Position, 5)); + + WritePadding(5); + } } public void JumpTo(X86Condition condition, BasicBlock target) { - _jumps.Add(new Jump(condition, target, _stream.Position)); + if (_ptcDisabled) + { + _jumps.Add(new Jump(condition, target, _stream.Position)); + + WritePadding(ReservedBytesForJump); + } + else + { + _jumps.Add(new Jump(condition, target, _stream.Position, 6)); - WritePadding(ReservedBytesForJump); + WritePadding(6); + } } public void JumpToNear(X86Condition condition) { _jNearCondition = condition; _jNearPosition = _stream.Position; - _jNearLength = Assembler.GetJccLength(0); + _jNearLength = Assembler.GetJccLength(0, _ptcDisabled); _stream.Seek(_jNearLength, SeekOrigin.Current); } @@ -165,7 +190,7 @@ namespace ARMeilleure.CodeGen.X86 long offset = currentPosition - (_jNearPosition + _jNearLength); - Debug.Assert(_jNearLength == Assembler.GetJccLength(offset), "Relative offset doesn't fit on near jump."); + Debug.Assert(_jNearLength == Assembler.GetJccLength(offset, _ptcDisabled), "Relative offset doesn't fit on near jump."); Assembler.Jcc(_jNearCondition, offset); @@ -197,56 +222,63 @@ namespace ARMeilleure.CodeGen.X86 long offset = jumpTarget - jump.JumpPosition; - if (offset < 0) + if (_ptcDisabled) { - for (int index2 = index - 1; index2 >= 0; index2--) + if (offset < 0) { - Jump jump2 = _jumps[index2]; - - if (jump2.JumpPosition < jumpTarget) + for (int index2 = index - 1; index2 >= 0; index2--) { - break; - } + Jump jump2 = _jumps[index2]; - offset -= jump2.InstSize - ReservedBytesForJump; + if (jump2.JumpPosition < jumpTarget) + { + break; + } + + offset -= jump2.InstSize - ReservedBytesForJump; + } } - } - else - { - for (int index2 = index + 1; index2 < _jumps.Count; index2++) + else { - Jump jump2 = _jumps[index2]; - - if (jump2.JumpPosition >= jumpTarget) + for (int index2 = index + 1; index2 < _jumps.Count; index2++) { - break; + Jump jump2 = _jumps[index2]; + + if (jump2.JumpPosition >= jumpTarget) + { + break; + } + + offset += jump2.InstSize - ReservedBytesForJump; } - offset += jump2.InstSize - ReservedBytesForJump; + offset -= ReservedBytesForJump; } - offset -= ReservedBytesForJump; - } + if (jump.IsConditional) + { + jump.InstSize = Assembler.GetJccLength(offset); + } + else + { + jump.InstSize = Assembler.GetJmpLength(offset); + } - if (jump.IsConditional) - { - jump.InstSize = Assembler.GetJccLength(offset); + // The jump is relative to the next instruction, not the current one. + // Since we didn't know the next instruction address when calculating + // the offset (as the size of the current jump instruction was not known), + // we now need to compensate the offset with the jump instruction size. + // It's also worth noting that: + // - This is only needed for backward jumps. + // - The GetJmpLength and GetJccLength also compensates the offset + // internally when computing the jump instruction size. + if (offset < 0) + { + offset -= jump.InstSize; + } } else { - jump.InstSize = Assembler.GetJmpLength(offset); - } - - // The jump is relative to the next instruction, not the current one. - // Since we didn't know the next instruction address when calculating - // the offset (as the size of the current jump instruction was not know), - // we now need to compensate the offset with the jump instruction size. - // It's also worth to note that: - // - This is only needed for backward jumps. - // - The GetJmpLength and GetJccLength also compensates the offset - // internally when computing the jump instruction size. - if (offset < 0) - { offset -= jump.InstSize; } @@ -267,7 +299,7 @@ namespace ARMeilleure.CodeGen.X86 using (MemoryStream codeStream = new MemoryStream()) { - Assembler assembler = new Assembler(codeStream); + Assembler assembler = new Assembler(codeStream, _ptcInfo); byte[] buffer; @@ -278,7 +310,7 @@ namespace ARMeilleure.CodeGen.X86 buffer = new byte[jump.JumpPosition - _stream.Position]; _stream.Read(buffer, 0, buffer.Length); - _stream.Seek(ReservedBytesForJump, SeekOrigin.Current); + _stream.Seek(_ptcDisabled ? ReservedBytesForJump : jump.InstSize, SeekOrigin.Current); codeStream.Write(buffer); @@ -298,6 +330,8 @@ namespace ARMeilleure.CodeGen.X86 codeStream.Write(buffer); + _ptcInfo?.WriteCode(codeStream); + return codeStream.ToArray(); } } diff --git a/ARMeilleure/CodeGen/X86/CodeGenerator.cs b/ARMeilleure/CodeGen/X86/CodeGenerator.cs index 0faba6dd..e7e7553e 100644 --- a/ARMeilleure/CodeGen/X86/CodeGenerator.cs +++ b/ARMeilleure/CodeGen/X86/CodeGenerator.cs @@ -5,6 +5,7 @@ using ARMeilleure.Common; using ARMeilleure.Diagnostics; using ARMeilleure.IntermediateRepresentation; using ARMeilleure.Translation; +using ARMeilleure.Translation.PTC; using System; using System.Collections.Generic; using System.Diagnostics; @@ -100,7 +101,7 @@ namespace ARMeilleure.CodeGen.X86 _instTable[(int)inst] = func; } - public static CompiledFunction Generate(CompilerContext cctx) + public static CompiledFunction Generate(CompilerContext cctx, PtcInfo ptcInfo = null) { ControlFlowGraph cfg = cctx.Cfg; @@ -158,10 +159,12 @@ namespace ARMeilleure.CodeGen.X86 using (MemoryStream stream = new MemoryStream()) { - CodeGenContext context = new CodeGenContext(stream, allocResult, maxCallArgs, cfg.Blocks.Count); + CodeGenContext context = new CodeGenContext(stream, allocResult, maxCallArgs, cfg.Blocks.Count, ptcInfo); UnwindInfo unwindInfo = WritePrologue(context); + ptcInfo?.WriteUnwindInfo(unwindInfo); + for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext) { context.EnterBlock(block); |
