private void AssignAddressForSectionInstruction(AssemblyCode code, int sectionIndex, ref uint ramBottomByteAddress) { var sect = code.Sections[sectionIndex]; for (int instrIdx = 0; instrIdx < sect.AllInstructions.Length; instrIdx++) { Instruction instr = sect.AllInstructions[instrIdx]; InstructionAnalyzeInfo analyzeInfo = InstructionAnalyzeInfos[sectionIndex][instrIdx]; //Alignment (If needed) if (analyzeInfo.NeedToAlign && (ramBottomByteAddress % 4) != 0) { ramBottomByteAddress += 4 - (ramBottomByteAddress % 4); } //Assign instr.PlacedInfo.MemoryNumber = 0; instr.PlacedInfo.Address = new Misc.AddressRange() { From = ramBottomByteAddress, To = ramBottomByteAddress + (uint)analyzeInfo.LengthInHalfWord * 2 - 1 }; //Update ramBottomByteAddress += (uint)analyzeInfo.LengthInHalfWord * 2; //This process is not necessary for (int oprIdx = 0; oprIdx < instr.Operands.Length; oprIdx++) { instr.Operands[oprIdx].PlacedInfo.MemoryNumber = 0; instr.Operands[oprIdx].PlacedInfo.Address = instr.PlacedInfo.Address; } } }
public override bool Assemble(AssemblyCode code, out Execute.ExecuteSetupData res, List <AssembleError> errorList) { res = new Execute.ExecuteSetupData(1); //Search section marked as startup MessageManager.ShowLine($"Determining entry point...", enumMessageLevel.DetailProgressLog); Section startupSection = null; foreach (var sect in code.Sections) { if ((sect.Attributes & Section.enumAttribute.Startup) == 0) { continue; } if (startupSection != null) { errorList.Add(new Interface.Assemble.AssembleError() { Title = "Assembler", Detail = $"More than 2 sections are marked as startup sections. \"{ startupSection.Name }\" and \"{ sect.Name }\" are so.", Position = sect.AssemblePosition }); return(false); } startupSection = sect; } //Assign addresses MessageManager.ShowLine($"Assigning memory address...", enumMessageLevel.DetailProgressLog); uint ramWordSize; if (!AssignAddresses(code, startupSection, errorList, out ramWordSize)) { return(false); } //Allocate memory region on slot.0 MessageManager.ShowLine($"Allocating memory regions...", enumMessageLevel.DetailProgressLog); res.MemoryContents[0].ExpandCapacity((int)ramWordSize); //Garantee minimum of memory size if (ramWordSize < code.MinMemorySize) { res.MemoryContents[0].ExpandCapacityForStack(code.MinMemorySize - (int)ramWordSize); } //Generate contents MessageManager.ShowLine($"Generating memory initial contents...", enumMessageLevel.DetailProgressLog); if (!GenerateMemoryContents(code, res, errorList)) { return(false); } res.StartupAddress = 0; res.IsSixteenBitArch = IsSixteenArch; return(true); }
private bool AnalyzeInstructionType(AssemblyCode code, List <AssembleError> errorList) { InstructionAnalyzeInfos = new InstructionAnalyzeInfo[code.Sections.Count][]; for (int sectIdx = 0; sectIdx < code.Sections.Count; sectIdx++) { var sect = code.Sections[sectIdx]; InstructionAnalyzeInfos[sectIdx] = new InstructionAnalyzeInfo[sect.AllInstructions.Length]; for (int instrIdx = 0; instrIdx < sect.AllInstructions.Length; instrIdx++) { var instr = sect.AllInstructions[instrIdx]; int type; if (!InstructionAssembler.SearchAssemblerType(instr, out type, errorList)) { return(false); } InstructionAnalyzeInfos[sectIdx][instrIdx].Type = type; int length; bool needToAlign; if (!InstructionAssembler.EstimateInstructionLength(instr, type, out length, out needToAlign, errorList)) { return(false); } InstructionAnalyzeInfos[sectIdx][instrIdx].LengthInHalfWord = length; InstructionAnalyzeInfos[sectIdx][instrIdx].NeedToAlign = needToAlign; } } return(true); }
public static bool TryParseFromFile(string filePath, out AssemblyCode res, List <AssembleError> errorList) { if (!System.IO.File.Exists(filePath)) { errorList.Add(new AssembleError() { Title = "Assemble", Detail = $"Including file { filePath } not found.", Position = new AssemblePosition() { FilePath = filePath } }); res = null; return(false); } string asmSource = System.IO.File.ReadAllText(filePath); if (!TryParse(asmSource, filePath, out res, errorList)) { MessageManager.ShowErrors(errorList); return(false); } return(true); }
private bool GenerateMemoryContentForVariable(VariableAnalyzeInfo.ElementBase varblElem, Execute.ExecuteSetupData setupData, List <AssembleError> errorList) { //Genarate if (varblElem.GroupedVariables.Count == 1 && varblElem.GroupedVariables[0].InitialValues.Length > 1) { //Array type Variable varbl = varblElem.GroupedVariables[0]; setupData.MemoryContents[varblElem.PlacedInfo.MemoryNumber][(int)varblElem.PlacedInfo.Address.From] = new Execute.ExecuteSetupData.MemoryContent.WordElement() { InitialValue = varblElem.GetInitialValue(), DebugInfoCount = 1, DebugInfos = new Execute.ExecuteSetupData.MemoryContent.DebugInfoElements() { Element0 = new Execute.ExecuteSetupData.MemoryContent.DebugInfoElement() { Usage = (varblElem == varbl.AnalyzeResults[0]) ? Execute.ExecuteSetupData.MemoryContent.WordElement.enumUsage.VariableArray : Execute.ExecuteSetupData.MemoryContent.WordElement.enumUsage.FollowHead, IsDebugMarked = false, DebugInfo = AssemblyCode.GetBlockPathPrefix(varbl.DefinedBlock) + varbl.Name + "[" + Array.IndexOf(varbl.AnalyzeResults, varblElem) + "]" } } }; } else { //Single type string debugInfo = ""; foreach (var e in varblElem.GroupedVariables) { if (e.InitialValues.Length == 1) { debugInfo += AssemblyCode.GetBlockPathPrefix(e.DefinedBlock) + e.Name + " "; } else { debugInfo += AssemblyCode.GetBlockPathPrefix(e.DefinedBlock) + e.Name + "[" + Array.IndexOf(e.AnalyzeResults, varblElem) + "]" + " "; } } setupData.MemoryContents[varblElem.PlacedInfo.MemoryNumber][(int)varblElem.PlacedInfo.Address.From] = new Execute.ExecuteSetupData.MemoryContent.WordElement() { InitialValue = varblElem.GetInitialValue(), DebugInfoCount = 1, DebugInfos = new Execute.ExecuteSetupData.MemoryContent.DebugInfoElements() { Element0 = new Execute.ExecuteSetupData.MemoryContent.DebugInfoElement() { Usage = Execute.ExecuteSetupData.MemoryContent.WordElement.enumUsage.Variable, IsDebugMarked = false, DebugInfo = debugInfo } } }; } return(true); }
public bool Assemble(AssemblyCode code, out Execute.ExecuteSetupData res) { List <AssembleError> errorList = new List <Interface.Assemble.AssembleError>(); if (!Assemble(code, out res, errorList)) { MessageManager.ShowErrors(errorList); return(false); } return(true); }
public static bool TryParseFromFile(string filePath, out AssemblyCode res) { List <AssembleError> errorList = new List <Assemble.AssembleError>(); if (!TryParseFromFile(filePath, out res, errorList)) { MessageManager.ShowErrors(errorList); return(false); } return(true); }
public static bool TryParseAndAddFromFile(string filePath, ref AssemblyCode res, List <AssembleError> errorList) { if (!System.IO.File.Exists(filePath)) { errorList.Add(new AssembleError() { Title = "Assemble", Detail = $"Including file { filePath } not found.", Position = new AssemblePosition() { FilePath = filePath } }); return(false); } string asmSource = System.IO.File.ReadAllText(filePath); return(TryParseAndAdd(asmSource, filePath, ref res, errorList)); }
private bool AssignAddresses(AssemblyCode code, Section startupSection, List <AssembleError> errorList, out uint ramBottomWordAddress) { ramBottomWordAddress = 0; //Assign address of instructions { if (startupSection != null) { //From section marked as startup AssignAddressForSectionInstruction(startupSection, ref ramBottomWordAddress); } for (int sectIdx = 0; sectIdx < code.Sections.Count; sectIdx++) { Section sect = code.Sections[sectIdx]; if (sect == startupSection) { continue; } AssignAddressForSectionInstruction(sect, ref ramBottomWordAddress); } } //Assign address of variables { //Read-only variables foreach (var e in code.VariableAnalyzeResult.Readonlys) { AddressSymbolInfo placeInfo = new Interface.Assemble.AddressSymbolInfo() { MemoryNumber = 0, Address = new Misc.AddressRange() { From = ramBottomWordAddress, To = ramBottomWordAddress } }; ramBottomWordAddress += 1; e.PlacedInfo = placeInfo; } //Read-write variables foreach (var e in code.VariableAnalyzeResult.Readwrites) { AddressSymbolInfo placeInfo = new Interface.Assemble.AddressSymbolInfo() { MemoryNumber = 0, Address = new Misc.AddressRange() { From = ramBottomWordAddress, To = ramBottomWordAddress } }; ramBottomWordAddress += 1; e.PlacedInfo = placeInfo; } } return(true); }
private bool GenerateMemoryContents(AssemblyCode code, Execute.ExecuteSetupData setupData, List <AssembleError> errorList) { //Generate memory contents of instructions { for (int sectIdx = 0; sectIdx < code.Sections.Count; sectIdx++) { Section sect = code.Sections[sectIdx]; for (int instrIdx = 0; instrIdx < sect.AllInstructions.Length; instrIdx++) { Instruction instr = sect.AllInstructions[instrIdx]; if (!GenerateMemoryContentForInstruction(instr, setupData, errorList)) { return(false); } } } } bool failed = false; int[] notifier = new int[2] { 0, 1 }; System.Threading.Tasks.Task genThread = new System.Threading.Tasks.Task(() => { notifier[1] = code.VariableAnalyzeResult.Readonlys.Count + code.VariableAnalyzeResult.Readwrites.Count; //Assign address of variables { //Read-only variables for (int i = 0; i < code.VariableAnalyzeResult.Readonlys.Count; i++) { if (!GenerateMemoryContentForVariable(code.VariableAnalyzeResult.Readonlys[i], setupData, errorList)) { failed = true; return; } notifier[0] = i; } //Read-write variables for (int i = 0; i < code.VariableAnalyzeResult.Readwrites.Count; i++) { if (!GenerateMemoryContentForVariable(code.VariableAnalyzeResult.Readwrites[i], setupData, errorList)) { failed = true; return; } notifier[0] = i + code.VariableAnalyzeResult.Readonlys.Count; } } }); genThread.Start(); MessageManager.ShowLine(""); System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew(); while (!genThread.Wait(333)) { Console.Write($"\r Processing { notifier[0] } / { notifier[1] }..."); } if (failed) { return(false); } return(true); }
public override bool Assemble(AssemblyCode code, out ExecuteSetupData res, List <AssembleError> errorList) { res = new Execute.ExecuteSetupData(1); //Search section marked as startup MessageManager.ShowLine($"Determining entry point...", enumMessageLevel.DetailProgressLog); Section startupSection = null; int startupSectionIndex = -1; for (int sectIdx = 0; sectIdx < code.Sections.Count; sectIdx++) { var sect = code.Sections[sectIdx]; if ((sect.Attributes & Section.enumAttribute.Startup) == 0) { continue; } if (startupSection != null) { errorList.Add(new Interface.Assemble.AssembleError() { Title = "Assembler", Detail = $"More than 2 sections are marked as startup sections. \"{ startupSection.Name }\" and \"{ sect.Name }\" are so.", Position = sect.AssemblePosition }); return(false); } startupSection = sect; startupSectionIndex = sectIdx; } //Analyze instruction type and length if (!AnalyzeInstructionType(code, errorList)) { return(false); } //Assign addresses MessageManager.ShowLine($"Assigning memory address...", enumMessageLevel.DetailProgressLog); uint ramByteSize; uint instructionByteSize; if (!AssignAddresses(code, startupSectionIndex, errorList, out ramByteSize, out instructionByteSize)) { return(false); } //Allocate memory region on slot.0 MessageManager.ShowLine($"Allocating memory regions...", enumMessageLevel.DetailProgressLog); res.MemoryContents[0].ExpandCapacity((int)ramByteSize / 4); //Garantee minimum of memory size if (ramByteSize / 4 < code.MinMemorySize) { res.MemoryContents[0].ExpandCapacityForStack(code.MinMemorySize - (int)ramByteSize / 4); } //Generate contents MessageManager.ShowLine($"Generating memory initial contents...", enumMessageLevel.DetailProgressLog); if (!GenerateMemoryContents(code, res, errorList)) { return(false); } res.StartupAddress = 0; return(true); }
private bool AssignAddresses(AssemblyCode code, int startupSectionIndex, List <AssembleError> errorList, out uint ramBottomByteAddress, out uint instructionByteSize) { ramBottomByteAddress = 0; instructionByteSize = 0; //Assign address of instructions { if (startupSectionIndex >= 0) { //From section marked as startup AssignAddressForSectionInstruction(code, startupSectionIndex, ref ramBottomByteAddress); } for (int sectIdx = 0; sectIdx < code.Sections.Count; sectIdx++) { if (sectIdx == startupSectionIndex) { continue; } Section sect = code.Sections[sectIdx]; AssignAddressForSectionInstruction(code, sectIdx, ref ramBottomByteAddress); } } instructionByteSize = ramBottomByteAddress; //Alignment if (ramBottomByteAddress % 4 != 0) { ramBottomByteAddress += 4 - (ramBottomByteAddress % 4); } //Assign address of variables { //Read-only variables foreach (var e in code.VariableAnalyzeResult.Readonlys) { AddressSymbolInfo placeInfo = new Interface.Assemble.AddressSymbolInfo() { MemoryNumber = 0, Address = new Misc.AddressRange() { From = ramBottomByteAddress, To = ramBottomByteAddress } }; ramBottomByteAddress += 1 * 4; e.PlacedInfo = placeInfo; } //Read-write variables foreach (var e in code.VariableAnalyzeResult.Readwrites) { AddressSymbolInfo placeInfo = new Interface.Assemble.AddressSymbolInfo() { MemoryNumber = 0, Address = new Misc.AddressRange() { From = ramBottomByteAddress, To = ramBottomByteAddress } }; ramBottomByteAddress += 1 * 4; e.PlacedInfo = placeInfo; } } return(true); }
public abstract bool Assemble(AssemblyCode code, out Execute.ExecuteSetupData res, List <AssembleError> errorList);
public static bool TryParseAndAdd(string source, string filePath, ref AssemblyCode res, List <AssembleError> errorList) { //Convert filePath to absolute one filePath = System.IO.Path.GetFullPath(filePath); MessageManager.ShowLine($"Reading assembly file \"{ filePath }\" ...", enumMessageLevel.DetailProgressLog); //Parse text MessageManager.ShowLine($"Parsing text...", enumMessageLevel.DetailProgressLog); Grammar grammar = new Parsing.AssemblyGrammar(); Parser parser = new Parser(grammar); ParseTree tree = parser.Parse(source); if (tree.HasErrors()) { foreach (var e in tree.ParserMessages) { errorList.Add(new Assemble.AssembleError() { Title = "Text parser", Detail = e.Message + $" at { e.ParserState.Name } state", Position = new Assemble.AssemblePosition(filePath, e.Location.Line, e.Location.Column) }); } res = null; return(false); } //Parse tree MessageManager.ShowLine($"Parsing grammer tree...", enumMessageLevel.DetailProgressLog); ParseTreeNode root = tree.Root; Parsing.AssemblyParser asmParser = new Parsing.AssemblyParser(); List <string> includeFiles; if (!asmParser.ParseAndAdd(root, filePath, res, out includeFiles)) { return(false); } res.LoadedFiles.Add(filePath); //Process include files MessageManager.ShowLine($"Analyze include files...", enumMessageLevel.DetailProgressLog); for (int idx = 0; idx < includeFiles.Count; idx++) { string includeFilePath = includeFiles[idx]; //Convert filePath to absolute one includeFilePath = System.IO.Path.GetDirectoryName(filePath) + "/" + includeFilePath; includeFilePath = System.IO.Path.GetFullPath(includeFilePath); //Avoid include loop if (res.LoadedFiles.Contains(includeFilePath)) { continue; } if (!TryParseAndAddFromFile(includeFilePath, ref res, errorList)) { return(false); } res.LoadedFiles.Add(includeFilePath); } return(true); }
public static bool TryParse(string source, string filePath, out AssemblyCode res, List <AssembleError> errorList) { res = new Assemble.AssemblyCode(); return(TryParseAndAdd(source, filePath, ref res, errorList)); }