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; } 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); } } } } }