diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/AddWithCarry.cs b/source/Tests/MathTest/Lost/JIT/AMD64/AddWithCarry.cs
index c84fbb527..d7b98c065 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/AddWithCarry.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/AddWithCarry.cs
@@ -48,5 +48,10 @@ namespace Lost.JIT.AMD64
{
get { return 0x10; }
}
+
+ public override string OpCodeFASM
+ {
+ get { return "adc"; }
+ }
}
}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/And.cs b/source/Tests/MathTest/Lost/JIT/AMD64/And.cs
index 0c0ed5d05..94c09a164 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/And.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/And.cs
@@ -49,5 +49,10 @@ namespace Lost.JIT.AMD64
{
get { return 0x20; }
}
+
+ public override string OpCodeFASM
+ {
+ get { return "and"; }
+ }
}
}
\ No newline at end of file
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/BreakPoint.cs b/source/Tests/MathTest/Lost/JIT/AMD64/BreakPoint.cs
index c62461e7b..c80f9c07f 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/BreakPoint.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/BreakPoint.cs
@@ -18,5 +18,14 @@ namespace Lost.JIT.AMD64
{
destStream.WriteByte(0xCC);
}
+
+ public override string OpCodeFASM
+ {
+ get { return "int 3"; }
+ }
+ public override string ToFASM()
+ {
+ return OpCodeFASM;
+ }
}
}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/Call.cs b/source/Tests/MathTest/Lost/JIT/AMD64/Call.cs
index 982bd5a77..c643985b6 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/Call.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/Call.cs
@@ -68,5 +68,15 @@ namespace Lost.JIT.AMD64
throw new NotImplementedException();
}
+
+ public override string OpCodeFASM
+ {
+ get { return "call"; }
+ }
+
+ public override string ToFASM()
+ {
+ return string.Format(Dest is MemoryOperand? "call qword {0}": "call {0}", Dest);
+ }
}
}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/Compare.cs b/source/Tests/MathTest/Lost/JIT/AMD64/Compare.cs
new file mode 100644
index 000000000..fc7f13f9c
--- /dev/null
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/Compare.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+
+namespace Lost.JIT.AMD64
+{
+ [Serializable]
+ public sealed class Compare : DestSourceInstruction
+ {
+ public Compare(InstructionOperand dest, InstructionOperand source)
+ : base(dest, source)
+ {
+ }
+ public Compare(InstructionOperand dest, byte source)
+ : base(dest, source)
+ {
+ }
+ public Compare(InstructionOperand dest, short source)
+ : base(dest, source)
+ {
+ }
+ public Compare(InstructionOperand dest, int source)
+ : base(dest, source)
+ {
+ }
+ public Compare(InstructionOperand dest, long source)
+ : base(dest, source)
+ {
+ }
+
+ public override byte AccumulatorOpCode
+ {
+ get
+ {
+ return 0x3C;
+ }
+ }
+ public override byte ImmediateExt
+ {
+ get { return 0x07; }
+ }
+ public override byte ImmediateOpCode
+ {
+ get { return 0x80; }
+ }
+ public override byte RegisterOpCode
+ {
+ get { return 0x38; }
+ }
+
+ public override string OpCodeFASM
+ {
+ get { return "cmp"; }
+ }
+ }
+}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/ConditionalJumpInstruction.cs b/source/Tests/MathTest/Lost/JIT/AMD64/ConditionalJumpInstruction.cs
index 0ff7db17c..318d105ae 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/ConditionalJumpInstruction.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/ConditionalJumpInstruction.cs
@@ -23,7 +23,7 @@ namespace Lost.JIT.AMD64
public override void Compile(Stream destStream)
{
- if (TargetOffset.FitsInByte())
+ if (TargetOffset.FitsInSByte())
{
destStream.WriteByte(OpcodeBase);
destStream.WriteSByte(TargetOffset);
@@ -37,5 +37,11 @@ namespace Lost.JIT.AMD64
}
protected abstract int OpcodeBase { get; }
+
+ public override string ToFASM()
+ {
+ return string.Format("{0} {1}", OpCodeFASM,
+ TargetOffset + (TargetOffset.FitsInSByte() ? 2 : 6));
+ }
}
}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/DestSourceInstruction.cs b/source/Tests/MathTest/Lost/JIT/AMD64/DestSourceInstruction.cs
index 6ca2b6861..3c83d4be1 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/DestSourceInstruction.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/DestSourceInstruction.cs
@@ -277,6 +277,11 @@ namespace Lost.JIT.AMD64
get { throw new NotImplementedException(); }
}
+ public override string ToFASM()
+ {
+ return string.Format("{0} {1}, {2}", OpCodeFASM, Dest, Source);
+ }
+
///
/// INSTR accum, imm
///
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/GeneralPurposeRegister.cs b/source/Tests/MathTest/Lost/JIT/AMD64/GeneralPurposeRegister.cs
index cbeda9e2a..91fd4ef22 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/GeneralPurposeRegister.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/GeneralPurposeRegister.cs
@@ -6,7 +6,7 @@ using System.Text;
namespace Lost.JIT.AMD64
{
[Serializable]
- public sealed class GeneralPurposeRegister: InstructionOperand
+ public sealed class GeneralPurposeRegister: InstructionOperand, IEquatable
{
public GeneralPurposeRegister(Registers register, int size)
{
@@ -17,6 +17,28 @@ namespace Lost.JIT.AMD64
public int Size { get; private set; }
public Registers Register { get; private set; }
+ public override string ToString()
+ {
+ if (Register.IsNew() && (Size == 8)) return Register.ToString();
+ if (!Register.IsNew())
+ {
+ switch(Size)
+ {
+ case 2:
+ return Register.ToString();
+ case 4:
+ return 'E' + Register.ToString();
+ case 8:
+ return 'R' + Register.ToString();
+ case 1:
+ return Register.ToString().Substring(0, 1)+ 'L';
+ default:
+ throw new NotImplementedException();
+ }
+ }
+ throw new NotImplementedException();
+ }
+
public static readonly GeneralPurposeRegister RAX = new GeneralPurposeRegister(Registers.AX, 8);
public static readonly GeneralPurposeRegister RBX = new GeneralPurposeRegister(Registers.BX, 8);
public static readonly GeneralPurposeRegister RCX = new GeneralPurposeRegister(Registers.CX, 8);
@@ -60,5 +82,15 @@ namespace Lost.JIT.AMD64
//public static readonly GeneralPurposeRegister DI = new GeneralPurposeRegister(Registers.DI, 1);
//public static readonly GeneralPurposeRegister BP = new GeneralPurposeRegister(Registers.BP, 1);
//public static readonly GeneralPurposeRegister SP = new GeneralPurposeRegister(Registers.SP, 1);
+
+ #region IEquatable Members
+
+ public bool Equals(GeneralPurposeRegister other)
+ {
+ if (other == null) return false;
+ return (other.Register == Register) && (other.Size == Size);
+ }
+
+ #endregion
}
}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/ImmediateOperand.cs b/source/Tests/MathTest/Lost/JIT/AMD64/ImmediateOperand.cs
index b595241e6..6bd767256 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/ImmediateOperand.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/ImmediateOperand.cs
@@ -32,5 +32,11 @@ namespace Lost.JIT.AMD64
public long Value { get; private set; }
public int Size { get; private set; }
+
+ public override string ToString()
+ {
+ string digs = (Size * 2).ToString();
+ return "0x" + Value.ToString("X" + digs);
+ }
}
}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/Jump.cs b/source/Tests/MathTest/Lost/JIT/AMD64/Jump.cs
index bb36cbdf2..e156a63e5 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/Jump.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/Jump.cs
@@ -40,5 +40,21 @@ namespace Lost.JIT.AMD64
throw new NotImplementedException();
}
+
+ public override string OpCodeFASM
+ {
+ get { return "jmp"; }
+ }
+
+ public override string ToFASM()
+ {
+ if (Dest is ImmediateOperand)
+ {
+ var dest = Dest as ImmediateOperand;
+ return string.Format("jmp {0}", dest.Value + (dest.Value.FitsInSByte()? 2: 5));
+ }
+
+ throw new NotImplementedException();
+ }
}
}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/JumpIfEqual.cs b/source/Tests/MathTest/Lost/JIT/AMD64/JumpIfEqual.cs
index 98e22e895..606ced9eb 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/JumpIfEqual.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/JumpIfEqual.cs
@@ -14,5 +14,10 @@ namespace Lost.JIT.AMD64
{
get { return 0x74; }
}
+
+ public override string OpCodeFASM
+ {
+ get { return "je"; }
+ }
}
}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/MemoryOperand.cs b/source/Tests/MathTest/Lost/JIT/AMD64/MemoryOperand.cs
index 1392d577f..ec19b01df 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/MemoryOperand.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/MemoryOperand.cs
@@ -44,5 +44,24 @@ namespace Lost.JIT.AMD64
}
return Base != null;
}
+
+ public override string ToString()
+ {
+ if (RipBased)
+ return string.Format("[RIP + 0x{0}]", Displacement.ToString("X8"));
+
+ var sb = new StringBuilder();
+ sb.AppendFormat("[{0}", Base);
+ if (Index != null)
+ if (Scale > 1)
+ sb.AppendFormat(" + {0}*{1}", Index, Scale);
+ else
+ sb.AppendFormat(" + {0}", Index);
+
+ if (Displacement != 0)
+ sb.AppendFormat(" + 0x{0}", Displacement.ToString("X16"));
+ sb.Append(']');
+ return sb.ToString();
+ }
}
}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/Pop.cs b/source/Tests/MathTest/Lost/JIT/AMD64/Pop.cs
index be06a70a4..967b4722b 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/Pop.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/Pop.cs
@@ -52,5 +52,14 @@ namespace Lost.JIT.AMD64
}
throw new InvalidProgramException();
}
+
+ public override string OpCodeFASM
+ {
+ get { return "pop"; }
+ }
+ public override string ToFASM()
+ {
+ return string.Format(Dest is MemoryOperand? "pop qword {0}":"pop {0}", Dest);
+ }
}
}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/ProcessorInstruction.cs b/source/Tests/MathTest/Lost/JIT/AMD64/ProcessorInstruction.cs
index 7677465a0..e3d803f9a 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/ProcessorInstruction.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/ProcessorInstruction.cs
@@ -13,8 +13,15 @@ namespace Lost.JIT.AMD64
public const byte AddressSizeOverride = 0x67;
public abstract int? Size { get; }
+ public abstract string ToFASM();
+ public abstract string OpCodeFASM { get; }
public abstract void Compile(Stream destStream);
+ public override string ToString()
+ {
+ return ToFASM();
+ }
+
public static Rex NeedsRex(MemoryOperand memory)
{
if (memory.RipBased) return Rex.None;
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64/Push.cs b/source/Tests/MathTest/Lost/JIT/AMD64/Push.cs
index 04ea71ae0..4bdfef3ed 100644
--- a/source/Tests/MathTest/Lost/JIT/AMD64/Push.cs
+++ b/source/Tests/MathTest/Lost/JIT/AMD64/Push.cs
@@ -73,5 +73,14 @@ namespace Lost.JIT.AMD64
}
}
}
+
+ public override string OpCodeFASM
+ {
+ get { return "push"; }
+ }
+ public override string ToFASM()
+ {
+ return string.Format(Source is MemoryOperand ? "push qword {0}" : "push {0}", Source);
+ }
}
}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64OLD/Enumerations.cs b/source/Tests/MathTest/Lost/JIT/AMD64OLD/Enumerations.cs
deleted file mode 100644
index 608ea556d..000000000
--- a/source/Tests/MathTest/Lost/JIT/AMD64OLD/Enumerations.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Lost.JIT.AMD64OLD
-{
- [Flags]
- enum Register: byte
- {
- Legacy = 0x07,
- AX = 0x00,
- BX = 0x03,
- CX = 0x01,
- DX = 0x02,
- SP = 0x04,
- BP = 0x05,
- SI = 0x06,
- DI = 0x07,
- R8 = 0x08,
- R9 = 0x09,
- R10 = 0x0A,
- R11 = 0x0B,
- R12 = 0x0C,
- R13 = 0x0D,
- R14 = 0x0E,
- R15 = 0x0F,
- }
-
- [Flags]
- public enum Rex : byte
- {
- None = 0x40,
- ///
- /// Use 64-bit operand size
- ///
- ///
- /// Setting the REX.W bit to 1 specifies a 64-bit operand size. Like the
- /// existing 66h operand-size prefix, the REX 64-bit operand-size override has no effect on byte
- /// operations. For non-byte operations, the REX operand-size override takes precedence over the 66h
- /// prefix. If a 66h prefix is used together with a REX prefix that has the REX.W bit set to 1, the 66h
- /// prefix is ignored. However, if a 66h prefix is used together with a REX prefix that has the REX.W bit
- /// cleared to 0, the 66h prefix is not ignored and the operand size becomes 16 bits.
- ///
- Wide = None | (1 << 3),
- ///
- /// Reg index from ModRM extension.
- ///
- ///
- /// The REX.R bit adds a 1-bit (high) extension to the ModRM reg field (page 17)
- /// when that field encodes a GPR, XMM, control, or debug register. REX.R does not modify ModRM reg
- /// when that field specifies other registers or opcodes. REX.R is ignored in such cases.
- ///
- Reg = None | (1 << 2),
- ///
- /// SIB index register extension.
- ///
- Index = None | (1 << 1),
- ///
- /// SIB index register extension.
- /// Use Index mnenonic instead.
- ///
- X = None | (1 << 1),
- ///
- /// Extension of the ModRM r/m field1, SIB base field, or opcode reg field,
- ///
- ///
- /// The REX.B bit adds a 1-bit (high) extension to either the ModRM r/m field to specify
- /// a GPR or XMM register, or to the SIB base field to specify a GPR. (See Table 2-2 on page 40 for more
- /// about the REX.B bit.)
- ///
- B = None | (1 << 0),
- }
-}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64OLD/ImmediateOperand.cs b/source/Tests/MathTest/Lost/JIT/AMD64OLD/ImmediateOperand.cs
deleted file mode 100644
index 485b2e41a..000000000
--- a/source/Tests/MathTest/Lost/JIT/AMD64OLD/ImmediateOperand.cs
+++ /dev/null
@@ -1,57 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace Lost.JIT.AMD64OLD
-{
- [Obsolete("")]
- class ImmediateOperand: InstructionOperand
- {
- internal ImmediateOperand(int size, ulong value):base(value.ToString(string.Format("0X{0}", size*2)))
- {
- switch (size)
- {
- case 1:
- byte b = checked((byte)value);
- break;
- case 2:
- ushort s = checked((ushort)value);
- break;
- case 4:
- uint i = checked((uint)value);
- break;
- case 8:
- break;
- default:
- throw new NotSupportedException("incorrect operand size");
- }
- _size = size;
- _value = (long)value;
- }
-
- int _size;
- long _value;
-
- ///
- /// Size of immediate operand, in bytes
- ///
- public int Size
- {
- get { return _size; }
- }
- ///
- /// Value of immediate operand
- ///
- public long Value
- {
- get { return _value; }
- }
-
- public override string ToString()
- {
- var val = _value.ToString(string.Format("X{0}", Size*2));
- return string.Format("0{0}h", val);
- }
- }
-}
diff --git a/source/Tests/MathTest/Lost/JIT/AMD64OLD/InstructionLabel.cs b/source/Tests/MathTest/Lost/JIT/AMD64OLD/InstructionLabel.cs
deleted file mode 100644
index 7bf7bccf6..000000000
--- a/source/Tests/MathTest/Lost/JIT/AMD64OLD/InstructionLabel.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-
-namespace Lost.JIT.AMD64OLD
-{
- class InstructionLabel
- {
- internal InstructionLabel(string name)
- {
- _name = name;
-
-#warning TODO: check label for validity
- }
-
- static readonly Regex _regex = new Regex(
- @"^(\s*(?