Cosmos/source/Lost/Assembler/JIT/AMD64/MemoryOperand.cs
LostTheBlack_cp 3060b02e0c AMD64 assembler:
[-] some unnecessary overloads
[+] overloaded operators in order to allow defining memory operands easily
[+] overloaded automatic conversions to allow operands
[+] Labels support
[+] code generator based on F# started
2008-05-09 11:29:38 +00:00

84 lines
2.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Lost.JIT.AMD64
{
[Serializable]
public class MemoryOperand: InstructionOperand
{
public MemoryOperand()
{
Scale = 1;
}
/// <summary>
/// Whether address is formed by next instruction pointer + disp
/// </summary>
public bool RipBased { get; set; }
public int Displacement { get; set; }
public int DisplacementSize {
get
{
if (Displacement == 0) return 0;
if (((byte)Displacement) == Displacement) return 1;
//if (((short)Displacement) == Displacement) return 2;
return 4;
}
}
public int Scale { get; set; }
public GeneralPurposeRegister Index { get; set; }
public GeneralPurposeRegister Base { get; set; }
public static MemoryOperand operator +(MemoryOperand memory, GeneralPurposeRegister register)
{
if (memory.Base != null) throw new InvalidOperationException("can't use two base registers");
return new MemoryOperand() {
Base = register,
Displacement = memory.Displacement,
//DisplacementSize = memory.DisplacementSize,
Index = memory.Index,
RipBased = memory.RipBased,
Scale = memory.Scale,
};
}
public static MemoryOperand operator +(GeneralPurposeRegister register, MemoryOperand memory)
{
return memory + register;
}
public bool RequiresSIB()
{
if (RipBased) return false;
if (Index == null)
{
if ((Displacement == 0) && ((Base.Register & Registers.OldRegsMask) == Registers.BP)) return true;
if ((Base.Register & Registers.OldRegsMask) == Registers.SP) return true;
return false;
}
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();
}
}
}