mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-19 20:39:01 +00:00
117 lines
3.9 KiB
C#
117 lines
3.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Cosmos.Compiler.Assembler;
|
|
using Cosmos.Compiler.Assembler.X86;
|
|
|
|
namespace Cosmos.Compiler.XSharp {
|
|
public class MemoryAction {
|
|
public uint? Value;
|
|
public readonly RegistersEnum? Register;
|
|
public readonly ElementReference Reference;
|
|
public readonly int Displacement;
|
|
|
|
public override string ToString() {
|
|
if (Value.HasValue) {
|
|
return Value.Value.ToString();
|
|
} else {
|
|
if (Reference != null) {
|
|
return Reference.ToString();
|
|
}
|
|
return Registers.GetRegisterName(Register.Value);
|
|
}
|
|
}
|
|
|
|
public static implicit operator MemoryAction(UInt32 aValue) {
|
|
return new MemoryAction(aValue);
|
|
}
|
|
|
|
public static implicit operator MemoryAction(Register aRegister) {
|
|
return new MemoryAction(aRegister.GetId());
|
|
}
|
|
|
|
public static MemoryAction operator ++(MemoryAction aTarget) {
|
|
aTarget.ApplyToDest(new Inc());
|
|
return null;
|
|
}
|
|
|
|
public static MemoryAction operator --(MemoryAction aTarget) {
|
|
aTarget.ApplyToDest(new Dec());
|
|
return null;
|
|
}
|
|
|
|
public bool IsIndirect { get; set; }
|
|
// For registers
|
|
public MemoryAction(RegistersEnum aRegister)
|
|
{
|
|
Register = aRegister;
|
|
}
|
|
|
|
public MemoryAction(RegistersEnum aRegister, int aDisplacement)
|
|
: this(aRegister)
|
|
{
|
|
Displacement = aDisplacement;
|
|
}
|
|
// This form used for reading memory - Addresses are passed in
|
|
public MemoryAction(ElementReference aValue, int aDisplacement)
|
|
: this(aValue) {
|
|
Displacement = aDisplacement;
|
|
}
|
|
public MemoryAction(ElementReference aValue) {
|
|
Reference = aValue;
|
|
}
|
|
|
|
// For constants/literals
|
|
public MemoryAction(UInt32 aValue, int aDisplacement)
|
|
: this(aValue) {
|
|
Displacement = aDisplacement;
|
|
}
|
|
|
|
public MemoryAction(UInt32 aValue) {
|
|
Value = aValue;
|
|
}
|
|
|
|
public byte Size { get; set; }
|
|
|
|
public static string SizeToString(byte aSize) {
|
|
switch (aSize) {
|
|
case 8:
|
|
return "byte";
|
|
case 16:
|
|
return "word";
|
|
case 32:
|
|
return "dword";
|
|
case 64:
|
|
return "qword";
|
|
default:
|
|
throw new Exception("Invalid size: " + aSize);
|
|
}
|
|
}
|
|
|
|
//TODO: Put memory compare here - will later have to limit it to the size
|
|
// variant and if possible to self usage, ie no assignments. May however result
|
|
// in too many class variants to be worth while.
|
|
public void Compare(UInt32 aValue) {
|
|
Value = aValue;
|
|
ApplyToDestAndSource(new Compare());
|
|
}
|
|
|
|
private void ApplyToDest(InstructionWithDestinationAndSize aDest) {
|
|
aDest.Size = Size;
|
|
aDest.DestinationReg = Register;
|
|
aDest.DestinationRef = Reference;
|
|
aDest.DestinationIsIndirect = IsIndirect;
|
|
aDest.DestinationDisplacement = Displacement;
|
|
}
|
|
|
|
private void ApplyToDestAndSource(InstructionWithDestinationAndSourceAndSize aInstruction) {
|
|
aInstruction.Size = Size;
|
|
aInstruction.DestinationReg = Register;
|
|
aInstruction.DestinationRef = Reference;
|
|
aInstruction.DestinationIsIndirect = IsIndirect;
|
|
aInstruction.DestinationDisplacement = Displacement;
|
|
aInstruction.SourceValue = Value.GetValueOrDefault();
|
|
}
|
|
}
|
|
}
|