Cosmos/source2/Compiler/Cosmos.Compiler.Assembler.X86/_Infra/InstructionWithDestinationAndSource.cs
kudzu_cp 00307f851d X#
2011-07-19 04:34:37 +00:00

108 lines
No EOL
3.5 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Cosmos.Compiler.Assembler.X86 {
public abstract class InstructionWithDestinationAndSource : InstructionWithDestination, IInstructionWithSource {
public ElementReference SourceRef {
get;
set;
}
public RegistersEnum? SourceReg
{
get;
set;
}
public uint? SourceValue
{
get;
set;
}
public bool SourceIsIndirect {
get;
set;
}
public int SourceDisplacement {
get;
set;
}
public bool SourceEmpty
{
get;
set;
}
protected string GetSourceAsString() {
string xDest = "";
//if ((SourceValue.HasValue || SourceRef != null) &&
// SourceIsIndirect && SourceReg != null) {
// throw new Exception("[Scale*index+base] style addressing not supported at the moment");
//}
if (SourceRef != null) {
xDest = SourceRef.ToString();
} else {
if (SourceReg != null) {
xDest = Registers.GetRegisterName(SourceReg.Value);
} else {
if (SourceValue.HasValue)
xDest = "0x" + SourceValue.GetValueOrDefault().ToString("X").ToUpperInvariant();
}
}
if (SourceDisplacement != 0) {
xDest += (SourceDisplacement < 0 ? " - " : " + ") + Math.Abs(SourceDisplacement);
}
if (SourceIsIndirect) {
return "[" + xDest + "]";
} else {
return xDest;
}
}
public override bool IsComplete( Cosmos.Compiler.Assembler.Assembler aAssembler )
{
if (SourceRef != null) {
ulong xAddress;
return base.IsComplete(aAssembler) && SourceRef.Resolve(aAssembler, out xAddress);
}
return base.IsComplete(aAssembler);
}
public override void UpdateAddress( Cosmos.Compiler.Assembler.Assembler aAssembler, ref ulong aAddress )
{
if (SourceRef != null) {
SourceValue = 0xFFFFFFFF;
}
base.UpdateAddress(aAssembler, ref aAddress);
}
public override byte[] GetData(Cosmos.Compiler.Assembler.Assembler aAssembler) {
if (SourceRef != null) {
ulong xAddress = 0;
if (!SourceRef.Resolve(aAssembler, out xAddress)) {
throw new Exception("Cannot resolve SourceRef!");
}
SourceValue = (uint)xAddress;
}
return base.GetData(aAssembler);
}
public override void WriteText( Cosmos.Compiler.Assembler.Assembler aAssembler, System.IO.TextWriter aOutput )
{
aOutput.Write(mMnemonic);
String destination=this.GetDestinationAsString();
if (!destination.Equals("")){
aOutput.Write(" ");
aOutput.Write(destination);
string source = this.GetSourceAsString();
if (!(SourceEmpty && source.Equals(""))){
aOutput.Write(", ");
aOutput.Write(source);
}
}
}
}
}