Cosmos/source/Cosmos.Assembler/Instruction.cs
Andrey Kurdyumov eb8c55c597 Cache default mnemonics for assemblies.
This will speedup creation of the assembly instructions, since we do that a lot.
2015-05-07 12:41:06 +06:00

93 lines
No EOL
3 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
namespace Cosmos.Assembler {
public abstract class Instruction : BaseAssemblerElement {
/// <summary>
/// Cache for the default mnemonics.
/// </summary>
public static Dictionary<Type, string> defaultMnemonicsCache = new Dictionary<Type,string>();
protected string mMnemonic;
public string Mnemonic {
get { return mMnemonic; }
}
protected int mMethodID;
public int MethodID {
get { return mMethodID; }
}
protected int mAsmMethodIdx;
public int AsmMethodIdx {
get { return mAsmMethodIdx; }
}
public override void WriteText(Cosmos.Assembler.Assembler aAssembler, TextWriter aOutput) {
aOutput.Write(mMnemonic);
}
protected Instruction(string mnemonic = null) : this(true) {
}
protected Instruction(bool aAddToAssembler, string mnemonic=null) {
if (aAddToAssembler) {
Cosmos.Assembler.Assembler.CurrentInstance.Add(this);
}
mMnemonic = mnemonic;
if (mMnemonic == null)
{
var type = GetType();
mMnemonic = GetDefaultMnemonic(type);
}
}
/// <summary>
/// Gets default operation mnemonic for given type.
/// </summary>
/// <param name="type">Type for which gets default mnemonics.</param>
/// <returns>Default mnemonics for the type.</returns>
private static string GetDefaultMnemonic(Type type)
{
string xMnemonic;
if (defaultMnemonicsCache.TryGetValue(type, out xMnemonic))
{
return xMnemonic;
}
var xAttribs = type.GetCustomAttributes(typeof(OpCodeAttribute), false);
if (xAttribs != null && xAttribs.Length > 0)
{
var xAttrib = (OpCodeAttribute)xAttribs[0];
xMnemonic = xAttrib.Mnemonic;
}
else
{
xMnemonic = string.Empty;
}
defaultMnemonicsCache.Add(type, xMnemonic);
return xMnemonic;
}
public override ulong? ActualAddress {
get {
// TODO: for now, we dont have any data alignment
return StartAddress;
}
}
public override void UpdateAddress(Cosmos.Assembler.Assembler aAssembler, ref ulong aAddress) {
base.UpdateAddress(aAssembler, ref aAddress);
}
public override bool IsComplete(Assembler aAssembler) {
throw new NotImplementedException("Method not implemented for instruction " + this.GetType().FullName.Substring(typeof(Instruction).Namespace.Length + 1));
}
public override void WriteData(Cosmos.Assembler.Assembler aAssembler, Stream aOutput) {
throw new NotImplementedException("Method not implemented for instruction " + this.GetType().FullName.Substring(typeof(Instruction).Namespace.Length + 1));
}
}
}