Cosmos/source2/Compiler/Cosmos.Compiler.XSharp/Memory.cs
kudzu_cp 812603b385
2011-07-18 01:09:56 +00:00

181 lines
10 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 Memory {
public MemoryAction this[Address aAddress] {
get {
var xAddrDirect = aAddress as AddressDirect;
if (xAddrDirect != null) {
if (xAddrDirect.Label != null) {
return new MemoryAction(ElementReference.New(xAddrDirect.Label));
} else {
if (xAddrDirect.Register != null) {
return new MemoryAction(xAddrDirect.Register.Value);
} else {
return new MemoryAction(xAddrDirect.Address);
}
}
} else {
var xAddrIndirect = aAddress as AddressIndirect;
if (xAddrIndirect != null) {
if (xAddrIndirect.Reference != null) {
return new MemoryAction(xAddrIndirect.Reference, xAddrIndirect.Displacement) { IsIndirect = true };
} else {
if (xAddrIndirect.Register != null) {
//TODO: HACK.... This defaults all registers without the size argument to 32. We need to really rebuild this code
return new MemoryAction(xAddrIndirect.Register.Value, xAddrIndirect.Displacement) { Size = 32, IsIndirect = true };
} else {
return new MemoryAction(xAddrIndirect.Address, xAddrIndirect.Displacement) { IsIndirect = true };
}
}
}
throw new Exception("Address type not supported!");
}
}
set {
if (value.Register!=null) {
var xAddrDirect = aAddress as AddressDirect;
if (xAddrDirect != null) {
if (xAddrDirect.Label != null) {
new Move { DestinationRef = ElementReference.New(xAddrDirect.Label), DestinationIsIndirect=true, SourceRef = value.Reference, SourceReg = value.Register, SourceIsIndirect = value.IsIndirect };
} else {
new Move { DestinationValue = xAddrDirect.Address, SourceValue = value.Value.GetValueOrDefault(), SourceRef = value.Reference, SourceReg = value.Register, SourceIsIndirect = value.IsIndirect };
}
} else {
var xAddrIndirect = aAddress as AddressIndirect;
if (xAddrIndirect != null) {
new Move { DestinationRef = xAddrIndirect.Reference, DestinationDisplacement = xAddrIndirect.Displacement, DestinationValue = xAddrIndirect.Address, DestinationReg = xAddrIndirect.Register, DestinationIsIndirect = true, SourceValue = value.Value.GetValueOrDefault(), SourceRef = value.Reference, SourceReg = value.Register, SourceIsIndirect = value.IsIndirect };
} else {
throw new Exception("Invalid Address type!");
}
}
} else {
var xAddrDirect = aAddress as AddressDirect;
if (xAddrDirect != null) {
if (xAddrDirect.Label != null) {
// Default is 32, in future save type that created the label, ie DataMemberInt vs DataMemberByte and set the size
new Move { DestinationRef = ElementReference.New(xAddrDirect.Label), SourceValue = value.Value.GetValueOrDefault(), SourceRef = value.Reference, SourceReg = value.Register, SourceIsIndirect = value.IsIndirect };
} else {
new Move { DestinationValue = xAddrDirect.Address, SourceValue = value.Value.GetValueOrDefault(), SourceRef = value.Reference, SourceReg = value.Register, SourceIsIndirect = value.IsIndirect };
}
} else {
var xAddrIndirect = aAddress as AddressIndirect;
if (xAddrIndirect != null) {
new Move { DestinationRef = xAddrIndirect.Reference, DestinationDisplacement = xAddrIndirect.Displacement, DestinationValue = xAddrIndirect.Address, DestinationReg = xAddrIndirect.Register, DestinationIsIndirect = true, SourceValue = value.Value.GetValueOrDefault(), SourceRef = value.Reference, SourceReg = value.Register, SourceIsIndirect = value.IsIndirect };
} else {
throw new Exception("Invalid Address type!");
}
}
}
}
}
public MemoryAction this[Address aAddress, byte aSize] {
get {
var xResult = this[aAddress];
xResult.Size = aSize;
if (xResult.Reference != null) {
xResult.IsIndirect = true;
}
return xResult;
}
set {
// ++ operators return ++
// Maybe later change ++ etc to return actions?
if (value != null) {
if (value.Register != null) {
var xAddrDirect = aAddress as AddressDirect;
if (xAddrDirect != null) {
if (xAddrDirect.Label != null) {
new Move {
DestinationRef = ElementReference.New(xAddrDirect.Label),
DestinationIsIndirect = true,
SourceValue = value.Value.GetValueOrDefault(),
SourceRef = value.Reference,
SourceReg = value.Register,
Size = aSize,
SourceIsIndirect = value.IsIndirect
};
} else {
new Move {
DestinationValue = xAddrDirect.Address,
SourceValue = value.Value.GetValueOrDefault(),
SourceRef = value.Reference,
Size = aSize,
SourceReg = value.Register,
SourceIsIndirect = value.IsIndirect
};
}
} else {
var xAddrIndirect = aAddress as AddressIndirect;
if (xAddrIndirect != null) {
new Move {
DestinationRef = xAddrIndirect.Reference,
DestinationDisplacement = xAddrIndirect.Displacement,
DestinationValue = (xAddrIndirect.Address != 0 ? (uint?)xAddrIndirect.Address : (uint?)null),
DestinationReg = xAddrIndirect.Register,
DestinationIsIndirect = true,
SourceValue = value.Value.GetValueOrDefault(),
Size = aSize,
SourceRef = value.Reference,
SourceReg = value.Register,
SourceIsIndirect = value.IsIndirect
};
} else {
throw new Exception("Invalid Address type!");
}
}
} else {
var xAddrDirect = aAddress as AddressDirect;
if (xAddrDirect != null) {
if (xAddrDirect.Label != null) {
new Move {
DestinationRef = ElementReference.New(xAddrDirect.Label),
DestinationIsIndirect=true,
SourceValue = value.Value.GetValueOrDefault(),
SourceRef = value.Reference,
SourceReg = value.Register,
Size = aSize,
SourceIsIndirect = value.IsIndirect
};
} else {
new Move {
DestinationValue = xAddrDirect.Address,
SourceValue = value.Value.GetValueOrDefault(),
SourceRef = value.Reference,
SourceReg = value.Register,
Size = aSize,
SourceIsIndirect = value.IsIndirect
};
}
} else {
var xAddrIndirect = aAddress as AddressIndirect;
if (xAddrIndirect != null) {
new Move {
DestinationRef = xAddrIndirect.Reference,
DestinationDisplacement = xAddrIndirect.Displacement,
DestinationValue = xAddrIndirect.Address,
DestinationReg = xAddrIndirect.Register,
DestinationIsIndirect = true,
Size = aSize,
SourceValue = value.Value.GetValueOrDefault(),
SourceRef = value.Reference,
SourceReg = value.Register,
SourceIsIndirect = value.IsIndirect
};
} else {
throw new Exception("Invalid Address type!");
}
}
}
}
}
}
}
}