/// <summary> /// Preprocesses the given ASM block. /// </summary> /// <param name="theBlock">The block to preprocess.</param> private static void Preprocess(ASMBlock theBlock) { // Due to "insert 0", asm ops are constructed in reverse order here string currMethodLabel = theBlock.GenerateMethodLabel(); if (currMethodLabel != null) { ASM.ASMOp newLabelOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.Label, true); theBlock.ASMOps.Insert(0, newLabelOp); } if (currMethodLabel != null) { ASM.ASMOp newGlobalLabelOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.GlobalLabel, currMethodLabel); theBlock.ASMOps.Insert(0, newGlobalLabelOp); } foreach (string anExternalLabel in theBlock.ExternalLabels.Distinct()) { if (anExternalLabel != currMethodLabel) { ASM.ASMOp newExternalLabelOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.ExternalLabel, anExternalLabel); theBlock.ASMOps.Insert(0, newExternalLabelOp); } } ASM.ASMOp newHeaderOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.Header); theBlock.ASMOps.Insert(0, newHeaderOp); }
/// <summary> /// Generates the label itself (using the ASM block) and the line of assembly for the label. /// </summary> /// <param name="theBlock">The block for which the comment is to be generated.</param> /// <returns>The complete line of assembly code.</returns> public override string Convert(ASMBlock theBlock) { if (MethodLabel) { return theBlock.GenerateMethodLabel() + ":"; } else { return theBlock.GenerateILOpLabel(ILPosition, Extension) + ":"; } }
/// <summary> /// Preprocesses the specified ASM library. /// </summary> /// <remarks> /// <para> /// Loops over all the ASM blocks, removing empty ones, checking plug paths and /// preprocessing non-empty blocks. /// </para> /// </remarks> /// <param name="TheLibrary">The library to preprocess.</param> /// <returns>Always CompileResult.OK. In all other cases, exceptions are thrown.</returns> public static CompileResult Preprocess(ASMLibrary TheLibrary) { CompileResult result = CompileResult.OK; if (TheLibrary.ASMPreprocessed) { return(result); } TheLibrary.ASMPreprocessed = true; for (int i = 0; i < TheLibrary.ASMBlocks.Count; i++) { ASMBlock aBlock = TheLibrary.ASMBlocks[i]; if (aBlock.Plugged) { if (string.IsNullOrWhiteSpace(aBlock.PlugPath)) { TheLibrary.ASMBlocks.RemoveAt(i); i--; continue; } } else { if (aBlock.ASMOps.Count == 0) { TheLibrary.ASMBlocks.RemoveAt(i); i--; continue; } Preprocess(aBlock); } } return(result); }
/// <summary> /// Generates the complete line of assembling using the Text field. /// </summary> /// <param name="theBlock">The block for which the comment is to be generated.</param> /// <returns>The complete line of assembly code.</returns> public override string Convert(ASMBlock theBlock) { return ";" + Text; }
public override string Convert(ASMBlock theBlock) { return "mflo " + Dest; }
/// <summary> /// Generates the line of assembly for the external label. /// </summary> /// <param name="theBlock">The block for which the comment is to be generated.</param> /// <returns>The complete line of assembly code.</returns> public override string Convert(ASMBlock theBlock) { return ".extern " + Label; }
/// <summary> /// Converts the ASM op into assembly code. /// </summary> /// <param name="theBlock">The ASM block to which the ASM op belongs.</param> /// <returns>The assembly code text.</returns> public abstract string Convert(ASMBlock theBlock);
/// <summary> /// Processes the given ASM block. /// </summary> /// <param name="TheBlock">The ASM block to process.</param> private static void ProcessBlock(ASMBlock TheBlock) { string ASMText = ""; if (TheBlock.Plugged) { string ASMPlugPath = Path.Combine(Options.OutputPath, TheBlock.PlugPath); // Legacy file name support if (Options.TargetArchitecture == "x86" && !File.Exists(ASMPlugPath + "." + Options.TargetArchitecture + ".asm")) { if (!File.Exists(ASMPlugPath + ".x86_32.asm")) { throw new FileNotFoundException("Plug file not found! File name: " + ASMPlugPath + "." + Options.TargetArchitecture + ".asm", ASMPlugPath + "." + Options.TargetArchitecture + ".asm"); } else { ASMPlugPath += ".x86_32.asm"; } } else { ASMPlugPath += "." + Options.TargetArchitecture + ".asm"; } if (!File.Exists(ASMPlugPath)) { throw new FileNotFoundException("Plug file not found! File name: " + ASMPlugPath, ASMPlugPath); } ASMText = File.ReadAllText(ASMPlugPath); ASMText = ASMText.Replace("%KERNEL_CALL_STATIC_CONSTRUCTORS_METHOD%", IL.ILLibrary.SpecialMethods[typeof(Attributes.CallStaticConstructorsMethodAttribute)].First().ID); if (IL.ILLibrary.SpecialMethods.ContainsKey(typeof(Attributes.MainMethodAttribute))) { ASMText = ASMText.Replace("%KERNEL_MAIN_METHOD%", IL.ILLibrary.SpecialMethods[typeof(Attributes.MainMethodAttribute)].First().ID); } } else { foreach (ASMOp anASMOp in TheBlock.ASMOps) { if (anASMOp.RequiresILLabel) { ASMText += ((ASMLabel)TargetArchitecture.CreateASMOp(OpCodes.Label, anASMOp.ILLabelPosition, "")).Convert(TheBlock) + "\r\n"; } if (anASMOp is ASM.ASMOps.ASMLabel) { ASMLabel labelOp = (ASM.ASMOps.ASMLabel)anASMOp; if (labelOp.IsDebugOp) { DebugDataWriter.AddDebugOp(TheBlock.OriginMethodInfo.ID, TheBlock.GenerateILOpLabel(labelOp.ILPosition, labelOp.Extension)); } } ASMText += anASMOp.Convert(TheBlock) + "\r\n"; } } TargetArchitecture.TargetFunctions.CleanUpAssemblyCode(TheBlock, ref ASMText); if (!string.IsNullOrWhiteSpace(ASMText)) { string FileName = Utilities.CleanFileName(Guid.NewGuid().ToString() + "." + Options.TargetArchitecture) + ".s"; string OutputPath = GetASMOutputPath(); FileName = Path.Combine(OutputPath, FileName); TheBlock.ASMOutputFilePath = FileName; File.WriteAllText(FileName, ASMText); } else { TheBlock.ASMOutputFilePath = null; } }
public override string Convert(ASMBlock theBlock) { return "nop"; }
/// <summary> /// Generates the line of assembly for the global label. /// </summary> /// <param name="theBlock">The block for which the comment is to be generated.</param> /// <returns>The complete line of assembly code.</returns> public override string Convert(ASMBlock theBlock) { return ".globl " + Label; }
public abstract void CleanUpAssemblyCode(ASM.ASMBlock TheBlock, ref string ASMText);
/// <summary> /// Gets the order of two ASM blocks based on their priorities. /// </summary> /// <param name="a">First block to order.</param> /// <param name="b">Second block to order.</param> /// <returns>/// -1 = a before b, 0 = a or b in either order, +1 = a after b.</returns> public static int GetOrder(ASM.ASMBlock a, ASM.ASMBlock b) { return(a.Priority.CompareTo(b.Priority)); }
public override string Convert(ASMBlock theBlock) { return "la " + Dest + ", " + Label; }
/// <summary> /// Generates the line of assembly for the global label. /// </summary> /// <param name="theBlock">The block for which the comment is to be generated.</param> /// <returns>The complete line of assembly code.</returns> public override string Convert(ASMBlock theBlock) { return "global " + Label + ":" + LabelType; }