Пример #1
0
        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;
                }
            }
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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));
        }
Пример #9
0
        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);
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
        }
Пример #12
0
        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);
        }
Пример #13
0
 public abstract bool Assemble(AssemblyCode code, out Execute.ExecuteSetupData res, List <AssembleError> errorList);
Пример #14
0
        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);
        }
Пример #15
0
 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));
 }