Exemplo n.º 1
0
        /// <summary>Adds 1 to the usage count for the needed register size.</summary>
        /// <param name="size">Size of reg in bytes.</param>
        /// <param name="stmt">The statement where a new register is being requested.</param>
        public void AddToCalc(int size, Stmt stmt)
        {
            // grow maxCurSz if needed
            largestSz = Math.Max(size, largestSz);

            curSizeCts[size]++;

            //lets see if there is a free spot with the exact size needed
            if (worstCaseMode)
            {
                if (maxSizeCts[size] < curSizeCts[size])
                {
                    maxSizeCts[size] = curSizeCts[size];
                    firstStmtWithMostRegs = stmt;
                }
            }
            // does curSizeCt fit in current maxSizeCts? if not then grow it
            else
            {
                int[] leftovers = new int[largestSz + 1];
                for (int i = largestSz; i > 0; i--)
                {
                    bool doesNotFit = true;
                    leftovers[i] += maxSizeCts[i] - curSizeCts[i];

                    // lets see if we can borrow from a larger register space
                    for (int j = i; j <= largestSz; j++)
                        if (leftovers[j] > 0)
                        {
                            leftovers[j]--;
                            leftovers[j - i]++;
                            doesNotFit = false;
                            break;
                        }
                    if (doesNotFit)
                    {
                        maxSizeCts[size]++;
                        firstStmtWithMostRegs = stmt;
                        break;
                    }
                }
            }
        }
Exemplo n.º 2
0
        //public bool TryGetVar(string name, out Variable variable)
        //{
        //    bool success = varsByName.TryGetValue(name, out variable);
        //    return success;
        //}

        /// <summary>Adds a GcnVar to the Vars collection while making sure it is valid.</summary>
        public void AddVariable(List<Variable> pendingNewVarsToAddToNextStmt, Stmt stmt, Log log, char type, int size, char dataType, string options)
        {
            MatchCollection r2 = Regex.Matches(options,
                @"(?<4>[a-z_][a-z_0-9]*)" +
                @"((?<8>\ +(?<5>[sv])(?:(?<6>\d+)|(?:\[(?<6>\d+):(?<7>\d+)\])))|" + // assign exact reg
                @"(?:\ +(?<9>[a-z_][a-z0-9_]*)(?:\[(?<10>\d+)\])?))?" + // Match to another Vars Reg#
                @"\s*(,|$)\s*");
            if (r2.Count <= 0) // there should be at least one match
            {
                log.Error("The new variable options could not be understood: " + options);
                return;
            }

            foreach (Match m in r2)
            {
                GroupCollection g = m.Groups;

                string name = g[4].Value;
                string varsRegToCopy = "";
                int varsRegToCopyIndex = 0;
                int requestedReg = -1;

                if (g[8].Success)
                {
                    requestedReg = Int32.Parse(g[6].Value);

                    // error checking
                    if (type != g[5].Value[0])
                        log.Warning("The variable type ({0}) does not match the register type {1}", type, g[5].Value);
                    if (g[7].Success)
                        if ((int.Parse(g[7].Value) - requestedReg + 1) != (size / 4))
                            log.Warning("The variable size({0}) does not match the size of {1}[#:#]", size, type);
                }
                else if (g[9].Success)
                {
                    varsRegToCopy = g[9].Value;
                    if (g[10].Success)
                        varsRegToCopyIndex = int.Parse(g[10].Value);

                    // make sure the name is not already added to the dictionary
                    Variable copySrc;
                    if (!varsByName.TryGetValue(varsRegToCopy, out copySrc))
                    {
                        log.Error("The past variable '{0}' cannot be found.", varsRegToCopy);
                        continue;
                    }

                    // if this is copying a reg from another variable and that variable is fixed then copy the reg now.
                    if (copySrc.isRegisterNumSpecifed)
                        requestedReg = copySrc.regNo + varsRegToCopyIndex;

                    if (type != (copySrc.isScaler ? 's' : 'v'))
                        log.Warning("'{0}' is type '{1}' however '{2}' is type '{3}'.", name, type, varsRegToCopy, copySrc.isScaler ? 's' : 'v');

                    if (requestedReg + ((size + 3) / 4) > copySrc.regNo + copySrc.RegsRequired)
                        log.Warning("The new variable '{0}' extends past the source variables last register.", name);
                }

                // make sure the reserved word is not in ISA_DATA.AsmReserveDWords, it will be added regardless
                if (Array.BinarySearch<string>(ISA_DATA.AsmReserveDWords, name) >= 0)
                {
                    log.Error("'{0}' cannot be used as a register name because it is a reserved word.", name);
                    continue;
                }

                // make sure the variable name is not a common alias
                if (ISA_DATA.sRegAliases.ContainsKey(name))
                {
                    log.Error("'{0}' cannot be used as a variable because it is a common register alias.", name);
                    continue;
                }

                // make sure the name is not already added to the dictionary
                if (varsByName.ContainsKey(name))
                {
                    log.Error("Variable '{0}' has already been declared.", name);
                    continue;
                }

                // lets now add it to the var dictionary
                Variable var = new Variable()
                {
                    name = name,
                    isScaler = (type == 's'),
                    size = size,
                    type = dataType,
                    regNo = requestedReg, // -1 for not yet assigned
                    variablesRegToCopy = varsRegToCopy,
                    variablesRegToCopyIndex = varsRegToCopyIndex,
                    isRegisterNumSpecifed = (requestedReg >= 0)
                };
                varsByName.Add(name, var);
                pendingNewVarsToAddToNextStmt.Add(var);

                // lets calculate usage 
                RegUsageCalc regUsageCalc = var.isScaler ? sRegUsageCalc : vRegUsageCalc;
                if (regUsageCalc != null)
                    regUsageCalc.AddToCalc(var.size, stmt);

            }
        }
Exemplo n.º 3
0
        public void MarkVariableUsedInStmt(Stmt stmt, string name, int index, int startPos, int length)
        {
            Variable nr;
            if (!varsByName.TryGetValue(name, out nr))
                log.Error("Variable, '{0}', is not defined.", name);
            else
            {
                if (nr.stmtTerminated == null)
                    nr.stmtsUsedIn.Add(stmt);
                else
                    log.Error("Variable, " + name + ", is being used but has already been marked terminated.");

                stmt.vars.Add(new VariableUsageLoc()
                {
                    variable = nr,
                    indexOffset = index,
                    startPos = startPos,
                    varLength = length
                });
            }

        }
Exemplo n.º 4
0
        static void Main(string[] args)
        {
            // args = "TestInput.txt output.bin /OutputUsage".Split(' '); // <---- uncomment to use testinput.txt
            // args = "TestInput.txt output.bin /showstmts".Split(' '); // <---- uncomment to use testinput.txt

            Log log = new Log(0);

            Stopwatch startedAt = new Stopwatch(); startedAt.Start();

            if (args.Count() < 2)
            {
                // process asm             -> finished bin
                // process asm,RegPool     -> finished bin
                // process asm             -> partial + binSize,vRegCt,sRegCt
                // process partial+RegPool -> finished bin
                Console.WriteLine(
                    //01234567890123456789012345678901234567890123456789012345678901234567890123456789
                    "Usage: Asm4GCN.exe <input> <output> /OutputUsage /ShowStmts\n\n" +
                    " <input>      This is an Asm text file.\n\n" +
                    //" /OutputBin   This is the finished GCN asm bin file.\n" +
                    " /OutputUsage Outputs the vector\\scalar register counts and the\n" +
                    "              binary size. When in this mode a usage file is\n" +
                    "              created and not a bin.\n\n" +
                    " /ShowStmts   Shows the statements in a friendly to read format.\n\n" +
                    " A example usage plan using the 'outputusage' option:\n" +
                    "  1) Extract Asm block from c/c++/c# code into myAsm.txt.\n" +
                    "  2) Get the register and size requirements for the block..\n" +
                    "     example: Asm4GCN.exe myAsm.txt /OutputUsage AsmBlockReq.txt\n" +
                    "  3) Using the requirements, create dummy code with the same\n" +
                    "     scalar\\vector register needs and bin size then note what\n" +
                    "     actual registers are used.\n" +
                    "  4) Now that the registers are known, the binary file can be \n" +
                    "     finished.\n" +
                    "     example: Asm4GCN.exe tempStage.int /OutputBin myBin.bin\n" +
                    "  5) Now that we have the asm block in binary form we need to\n" +
                    "     locate the dummy code and replace it with the newly\n" +
                    "     generated binaries.\n");
                return;
            }

            //string OutputBin = "", OutputUsage = "";
            string outputFilename = args[1];
            bool   doShowStmts    = false;
            bool   inUsageMode    = false;

            //bool doOutputBin = false;
            for (int i = 2; i < args.Count(); i++)
            {
                if (args[i].ToLower() == "/outputusage")
                {
                    inUsageMode = true;
                }
                else if (args[i].ToLower() == "/showstmts")
                {
                    doShowStmts = true;
                }
                else
                {
                    Console.WriteLine("Unknown command line option: " + args[i]);
                    return;
                }
            }


            /////////////////// Read the input file ///////////////////
            string[] lines = new string[0];
            try
            {
                lines = System.IO.File.ReadAllLines(args[0]);
            }
            catch (Exception e)
            {
                log.Error("Unable to open input file. Details: {0}", e.Message);
                return;
            }

            GcnBlock Asm4GCN = new GcnBlock();

            List <Stmt> gcnStmts;
            int         binSize = 0;

            if (inUsageMode)
            {
                List <RegUsage> sRegUsage, vRegUsage;
                string          logOutput;
                Asm4GCN.CompileForSpecs(lines, out gcnStmts, out sRegUsage, out vRegUsage, out binSize, out logOutput);
                log.Append(logOutput);

                // Write bin or halfway point to output file
                int stats_4ByteInstCt = 0;
                int stats_8ByteInstCt = 0;
                foreach (Stmt op in gcnStmts)
                {
                    if (op.opCode.literal.HasValue)
                    {
                        stats_8ByteInstCt++;
                    }
                    else
                    {
                        stats_4ByteInstCt++;
                    }
                }

                if (true) // lets just always show this for now
                {
                    log.WriteLine("4-Byte_Inst_Count:{0}  8-Byte_Inst_Count:{1}  Total:{2} bytes",
                                  stats_4ByteInstCt, stats_8ByteInstCt, stats_4ByteInstCt * 4 + stats_8ByteInstCt * 8);

                    //log.WriteLine("Displaying all {0} Scaler sizes:", sRegUsage.Count);
                    for (int i = 0; i < sRegUsage.Count; i++)
                    {
                        log.WriteLine("{1} Scaler reg(s) of size {0} needed", sRegUsage[i].regSize, sRegUsage[i].timesUsed);
                    }
                    //log.WriteLine("Line # on last S Reg increase: {0}", sRegUsageCalc.lineOnLastPoolIncrease);

                    //log.WriteLine("Displaying all {0} Vector sizes:", vRegUsage.Count);
                    for (int i = 0; i < vRegUsage.Count; i++)
                    {
                        log.WriteLine("{1} Vector reg(s) of size {0} needed", vRegUsage[i].regSize, vRegUsage[i].timesUsed);
                    }
                    //log.WriteLine("Line # on last S Reg increase: {0}", sRegUsageCalc.lineOnLastPoolIncrease);
                }

                // Lets save the regUsage to a file
                try
                {
                    //MemoryStream stream = new MemoryStream();
                    //BinaryWriter writer2 = new BinaryWriter(stream);
                    using (BinaryWriter writer = new BinaryWriter(File.Open(outputFilename, FileMode.Create)))
                    {
                        writer.Write(stats_4ByteInstCt);
                        writer.Write(stats_8ByteInstCt);
                        writer.Write(sRegUsage.Count);
                        for (int i = 0; i < sRegUsage.Count; i++)
                        {
                            writer.Write(sRegUsage[i].regSize);
                            writer.Write(sRegUsage[i].timesUsed);
                        }

                        writer.Write(vRegUsage.Count);
                        for (int i = 0; i < vRegUsage.Count; i++)
                        {
                            writer.Write(vRegUsage[i].regSize);
                            writer.Write(vRegUsage[i].timesUsed);
                        }
                    }
                }
                catch (Exception e)
                {
                    log.Error("Unable to write binary output file. {0}", e.Message);
                }
            }
            else // binary creating mode (not Usage-Mode)
            {
                string logOutput;
                bool   success;
                byte[] bin = Asm4GCN.CompileForBin(lines, out gcnStmts, out binSize, out logOutput, out success);
                // log.Append(logOutput);
                if (success)
                {
                    try
                    {
                        // Write bin to output file
                        File.WriteAllBytes(outputFilename, bin);

                        //// Display the output (for debugging only)
                        //using (BinaryWriter writer = new BinaryWriter(File.Open(OutputBin, FileMode.Create)))
                        //{
                        //    foreach (GcnStmt op in gcnStmts)
                        //    {
                        //        writer.Write(op.opCode.code);
                        //        if (op.opCode.literal.HasValue)
                        //            writer.Write((uint)op.opCode.literal);
                        //    }
                        //}
                    }
                    catch (Exception e)
                    {
                        log.Error("Unable to write binary output file. {0}", e.Message);
                    }
                }
                else
                {
                    log.Error("{0} not generated because of errors.", outputFilename);
                }
            }

            log.WriteLine("Time taken: {0} ms", startedAt.ElapsedMilliseconds);

            /////////// Display the opcode. ///////////
            //log.WriteLine("Starting Display the opcode: {0} ms", startedAt.ElapsedMilliseconds);
            if (doShowStmts)
            {
                log.WriteLine("ID |Line|Sz|Loc| OpCode |Params post Processing|       Source Line");
                for (int i = 0; i < gcnStmts.Count; i++)
                {
                    Stmt   stmt    = gcnStmts[i];
                    string sBefore = lines[stmt.lineNum - 1];
                    string sAfter  = stmt.options;
                    sBefore = sBefore.Substring(0, Math.Min(30, sBefore.Length));
                    sAfter  = sAfter.Substring(0, Math.Min(21, sAfter.Length));
                    sBefore = Regex.Replace(sBefore, @"\t|\n|\r", " ");
                    log.WriteLine("{0,3}|{1,4}|{2,2}|{3,3}|{4:X}| {5,-21}| {6,-30}", stmt.GcnStmtId, stmt.lineNum, stmt.opSize, stmt.locInBin, stmt.opCode.code, sAfter, sBefore);//  stmt.inst.id + " Options:" + stmt.options);
                }
            }


            //Console.WriteLine("Output file size in words (4 bytes): {0} ", new FileInfo(args[1]).Length);
            Console.WriteLine("Press any key to exit.");
            Console.ReadKey();
        }
Exemplo n.º 5
0
        private byte[] Compile(string[] srcLines, out int binSize, Log log)
        {
            // log.WriteLine("Starting Lines: {0} ms", startedAt.ElapsedMilliseconds);
            // StringBuilder sb = new StringBuilder();
            //Future: Maybe use string builder here

            // Apply #defines, strip out comments, cleanup, record last time each var is used.
            bool            inCommentMode = false;
            List <Variable> pendingNewVarsToAddToNextStmt = new List <Variable>();; // pending New Variables To Add To Next Stmt
            List <Label>    pendingLabelsToAddToNextStmt  = new List <Label>();;    // pending New Labels that need a Stmt attached

            for (int line = 1; line < srcLines.Length + 1; line++)                  // from lines 1 to Last
            {
                string curLine = srcLines[line - 1];
                while (curLine.EndsWith(@"\"))
                {
                    curLine = curLine.Remove(curLine.Length - 1) + srcLines[line++];
                }

                // cleanup comments and whitespace
                curLine = CleanupComments(curLine, ref inCommentMode, line, log);

                // cleanup defines
                curLine = ProcessDefines(curLine, log);

                // Lets split up the multiple statements that might be on this one line.
                String[] stmts = curLine.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);

                // Process each statement on this line.
                for (int stmtNumberOnLine = 0; stmtNumberOnLine < stmts.Length; stmtNumberOnLine++)
                {
                    ProcessSingleStmt(curLine, stmts[stmtNumberOnLine], line, stmtNumberOnLine, ref pendingNewVarsToAddToNextStmt, pendingLabelsToAddToNextStmt, log, stmts);
                }
            }


            // Process remaining labels that pointed to exit (since there are no stmt-headers after the last statement, exit labels need .)
            foreach (Label label in pendingLabelsToAddToNextStmt)
            {
                label.isAtEnd = true;
                labels.AddLabel(label, log);
            }

            // Process Automatic variable freeing.
            vars.ProcessAutomaticFreeing(gcnStmts);

            // Process register assignments.
            vars.AssignRegNumbers(gcnStmts);

            // Convert each statement into in to binary (delay statements with variables)
            List <Stmt> needLabelFilled = new List <Stmt>();

            foreach (Stmt gcnStmt in gcnStmts)
            {
                ProcessStmt(gcnStmt, needLabelFilled, log);
            }


            // At this point we have to finish two things:
            // (1) Find the "stmt.opSize" of each stmt and build min/max distance tables
            // (2) Fill in the "stmt.opCode" for any stmt that have a label.

            /////////// Fill in the OpSize on each statement ///////////
            FillOpSizeValue(log, needLabelFilled);


            /////////// Optional final Error checking ///////////
            int loc = 0;

            for (int i = 0; i < gcnStmts.Count; i++)
            {
                Stmt stmt = gcnStmts[i];
                if (stmt.opSize != stmt.opCode.Size)
                {
                    log.Error("ERROR: (internal) Stmt {0} on line {1} has an opSize of {2} however HasValue is {3}",
                              stmt.inst.name, stmt.lineNum, stmt.opSize, stmt.opCode.literal.HasValue);
                }
                if (stmt.opSize == 0)
                {
                    log.WriteLine("Stmt {0} had an opSizeOfZero");
                }
                if (stmt.locInBin != loc)
                {
                    log.WriteLine("stmt.locInBin ({0}) might not be correct.", stmt.locInBin);
                }
                if (stmt.GcnStmtId != i)
                {
                    log.WriteLine("stmt.GcnStmtId ({0}) might not be correct.", stmt.GcnStmtId);
                }
                loc += stmt.opSize;
            }

            /////////// Lets print all the logs & warnings ///////////
            if (log.hasErrors)
            {
                log.WriteLine("One or more Error(s) in GCN Assembly");
            }

            /////////// Get bin size ///////////
            binSize = 0;
            foreach (Stmt stmt in gcnStmts)
            {
                binSize += stmt.opSize * 4;
            }

            /////////// Create bin ///////////
            // Write bin to output file
            byte[]       bin = new byte[binSize];
            MemoryStream ms  = new MemoryStream(bin);

            using (BinaryWriter writer = new BinaryWriter(ms))
            {
                foreach (Stmt op in gcnStmts)
                {
                    //writer.Write()
                    writer.Write(op.opCode.code);
                    if (op.opCode.literal.HasValue)
                    {
                        writer.Write((uint)op.opCode.literal);
                    }
                }
            }

            return(bin);

            // code to aid debugging
            //if (doOutputInter)
            //{  try { using (BinaryWriter writer = new BinaryWriter(File.Open(OutputInter, FileMode.Create))){
            //         foreach (GcnStmt s in gcnStmts) {
            //                writer.Write(s.inst.id);
            //                writer.Write(s.GcnStmtId);
            //                writer.Write(s.options);
            //                writer.Write(s.srcLine); }
            //            writer.Close(); } }
            //    catch (Exception e) { log.Error("Unable to write intermediate output file. {0}", e.Message); } }
        }
Exemplo n.º 6
0
        private void ProcessSingleStmt(string curLine, string stmtText, int lineNum, int stmtNumberOnLine, ref List <Variable> pendingNewVarsToAddToNextStmt, List <Label> pendingLabelsToAddToNextStmt, Log log, string[] stmts)
        {
            // Split out label from statement and record any labels on the line
            Match l = Regex.Match(stmtText, @"([a-z_][a-z0-9_]*):(\s|$)");

            if (l.Success)
            {
                pendingLabelsToAddToNextStmt.Add(new Label()
                {
                    labelName = l.Groups[1].Value, lineNum = lineNum
                });
                if (l.Length == stmtText.Length)
                {
                    return;
                }
                stmtText = stmtText.Remove(0, l.Length);
            }

            // Replace Friendly statements with Asm statements
            stmtText = FriendlyConverter.FriendlyFormatToAsmFormater(stmtText, vars, ISA_Gen, log);

            // Extract first word, and options
            char[]   delimiterChars = { ',', ' ' };
            string[] commands       = stmtText.Split(delimiterChars, 2, StringSplitOptions.RemoveEmptyEntries);
            string   firstWord      = commands[0];
            //string options = commands.Count() > 1 ? commands[1].Trim() : "";

            Stmt stmt = new Stmt()
            {
                options   = commands.Count() > 1 ? commands[1].Trim() : "",
                lineNum   = lineNum,
                lineDepth = stmtNumberOnLine,
                fullStmt  = stmtText,
                GcnStmtId = gcnStmts.Count,
            };

            /////////  Process Register Reservations, Renaming and Freeing /////////
            // New Format: [sv][1248][fiub][#] VarName    Free Format: free VarName
            // ren cat dog
            if (firstWord == "free")
            {
                string[] matches = stmt.options.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);
                foreach (string name in matches)
                {
                    vars.FreeVariable(name, gcnStmts);
                }
                return;
            }

            ///////// Process #S_POOL / #V_POOL  -->  sRegPool/vRegPool /////////
            //string cmd = Regex.Match(curLine, @"(?<=^\ *\#)(define|ref|[vs]_pool)").Value;
            if (firstWord == "#v_pool" || firstWord == "#s_pool")
            {
                // skip line if #S_POOL / #V_POOL
                if (!vars.UsingRegPools)
                {
                    return;
                }

                // Show warning if there are already existing vars.
                if (vars.Count > 0)
                {
                    log.Warning("#S_POOL / #V_POOL normally occur in the header area. Having this command in the "
                                + "body can be used to clear all variable names and pool reservations.");
                }

                Match def = Regex.Match(curLine, @"^\ *#(v|s)_pool\ *(?:(?:[vs](\d+)|(\S+?))\s*,?\s*)+");
                if (!def.Groups[0].Success | !def.Groups[2].Success)
                {
                    log.Error("error processing #POOL statement in '{0}'", curLine);
                    return;
                }

                if (def.Groups[3].Success)
                {
                    log.Error("unknown value '{0}' in POOL command (skipping)", def.Groups[3]);
                }

                int[] available_Regs = new int[def.Groups[2].Captures.Count];
                for (int i = 0; i < available_Regs.Length; i++)
                {
                    available_Regs[i] = Int32.Parse(def.Groups[2].Captures[i].Value);
                }

                vars.ReloadRegPool(def.Groups[1].Value[0], available_Regs);

                return;  // we are done with this statement.
            }

            ///////// Process Variable Declarations /////////
            // Example: s_mov_b32 v8u ttt, aaa, bbb
            // Example: s_mov_b32 v8u ttt S4, aaa, bbb
            // Example: v4u myVar0 s[2:3];
            // Example: s4u myVar1 myVar0
            // Single line Declarations
            Match m = Regex.Match(firstWord, @"(?<1>s|v)(?<2>1|2|4|8|16)(?<3>[fiub])");

            if (m.Success)
            {
                char type     = m.Groups[1].Value[0];
                int  size     = Int32.Parse(m.Groups[2].Value);
                char dataType = m.Groups[3].Value[0];

                vars.AddVariable(pendingNewVarsToAddToNextStmt, stmt, log, type, size, dataType, stmt.options);
                return;
            }

            // Inline Declarations
            var inlines = Regex.Matches(stmt.options, @"(?<![a-z_0-9])(?<2>s|v)(?<3>1|2|4|8|16)(?<4>[fiub])[\t\s]+" +
                                        @"(?<5>(?<6>[a-z_][a-z_0-9]*)" +
                                        @"( [a-z_][a-z_0-9]*(\[\d+(?::\d+)\])?)?)");

            foreach (Match m3 in inlines)
            {
                char type     = m3.Groups[2].Value[0];
                int  size     = Int32.Parse(m3.Groups[3].Value);
                char dataType = m3.Groups[4].Value[0];

                vars.AddVariable(pendingNewVarsToAddToNextStmt, stmt, log, type, size, dataType, m3.Groups[5].Value);
                stmt.options = stmt.options.Remove(m3.Index, m3.Length).Insert(m3.Index, m3.Groups[6].Value);
            }

            ///////// lookup instruction details /////////
            if (!ISA_DATA.isa_inst_dic.TryGetValue(firstWord, out stmt.inst))
            {
                log.Error("'{0}' is not a recognized instruction", firstWord);
                return;
            }

            ///////// Record var names and location making sure to exclude reserved words /////////
            var foundVars = Regex.Matches(stmt.options, @"(?<=,|\ |^)(?![vs]\d+)(([a-z_][a-z0-9_]*)(?:\[(\d+)\])?)(?=,|\ |$)");

            foreach (Match r in foundVars)
            {
                //Future: save char location so we don't have to search for the variable again when we do the replacement.

                string varName = r.Value;

                // ignore reserved words
                if (Array.BinarySearch <string>(ISA_DATA.AsmReserveDWords, varName) >= 0)
                {
                    continue;
                }

                // ignore common register aliases
                if (ISA_DATA.sRegAliases.ContainsKey(varName))
                {
                    continue;
                }

                int  len      = varName.Length;
                bool hasIndex = varName.EndsWith("]");
                int  index    = 0;
                int  startPos = r.Index;

                if (hasIndex)
                {
                    varName = r.Groups[2].Value;
                    index   = int.Parse(r.Groups[3].Value);
                }

                // Lets lookup the GcnVar to make sure it exists and also retrieve it.
                vars.MarkVariableUsedInStmt(stmt, varName, index, startPos, len);
            }
            ;

            ///////// Lets add the stmt to the list /////////
            // Before adding, lets link any pending statements.
            foreach (Label label in pendingLabelsToAddToNextStmt)
            {
                label.firstStmt = stmt;
                labels.AddLabel(label, log);
            }
            pendingLabelsToAddToNextStmt.Clear();

            // Also, lets link-up any new variables
            if (pendingNewVarsToAddToNextStmt.Count > 0)
            {
                foreach (Variable v in pendingNewVarsToAddToNextStmt)
                {
                    v.stmtDeclared = stmt;
                }

                stmt.newVars = pendingNewVarsToAddToNextStmt;
                pendingNewVarsToAddToNextStmt = new List <Variable>();
            }
            gcnStmts.Add(stmt);
        }
Exemplo n.º 7
0
        //public bool TryGetVar(string name, out Variable variable)
        //{
        //    bool success = varsByName.TryGetValue(name, out variable);
        //    return success;
        //}

        /// <summary>Adds a GcnVar to the Vars collection while making sure it is valid.</summary>
        public void AddVariable(List <Variable> pendingNewVarsToAddToNextStmt, Stmt stmt, Log log, char type, int size, char dataType, string options)
        {
            MatchCollection r2 = Regex.Matches(options,
                                               @"(?<4>[a-z_][a-z_0-9]*)" +
                                               @"((?<8>\ +(?<5>[sv])(?:(?<6>\d+)|(?:\[(?<6>\d+):(?<7>\d+)\])))|" + // assign exact reg
                                               @"(?:\ +(?<9>[a-z_][a-z0-9_]*)(?:\[(?<10>\d+)\])?))?" +             // Match to another Vars Reg#
                                               @"\s*(,|$)\s*");

            if (r2.Count <= 0) // there should be at least one match
            {
                log.Error("The new variable options could not be understood: " + options);
                return;
            }

            foreach (Match m in r2)
            {
                GroupCollection g = m.Groups;

                string name               = g[4].Value;
                string varsRegToCopy      = "";
                int    varsRegToCopyIndex = 0;
                int    requestedReg       = -1;

                if (g[8].Success)
                {
                    requestedReg = Int32.Parse(g[6].Value);

                    // error checking
                    if (type != g[5].Value[0])
                    {
                        log.Warning("The variable type ({0}) does not match the register type {1}", type, g[5].Value);
                    }
                    if (g[7].Success)
                    {
                        if ((int.Parse(g[7].Value) - requestedReg + 1) != (size / 4))
                        {
                            log.Warning("The variable size({0}) does not match the size of {1}[#:#]", size, type);
                        }
                    }
                }
                else if (g[9].Success)
                {
                    varsRegToCopy = g[9].Value;
                    if (g[10].Success)
                    {
                        varsRegToCopyIndex = int.Parse(g[10].Value);
                    }

                    // make sure the name is not already added to the dictionary
                    Variable copySrc;
                    if (!varsByName.TryGetValue(varsRegToCopy, out copySrc))
                    {
                        log.Error("The past variable '{0}' cannot be found.", varsRegToCopy);
                        continue;
                    }

                    // if this is copying a reg from another variable and that variable is fixed then copy the reg now.
                    if (copySrc.isRegisterNumSpecifed)
                    {
                        requestedReg = copySrc.regNo + varsRegToCopyIndex;
                    }

                    if (type != (copySrc.isScaler ? 's' : 'v'))
                    {
                        log.Warning("'{0}' is type '{1}' however '{2}' is type '{3}'.", name, type, varsRegToCopy, copySrc.isScaler ? 's' : 'v');
                    }

                    if (requestedReg + ((size + 3) / 4) > copySrc.regNo + copySrc.RegsRequired)
                    {
                        log.Warning("The new variable '{0}' extends past the source variables last register.", name);
                    }
                }

                // make sure the reserved word is not in ISA_DATA.AsmReserveDWords, it will be added regardless
                if (Array.BinarySearch <string>(ISA_DATA.AsmReserveDWords, name) >= 0)
                {
                    log.Error("'{0}' cannot be used as a register name because it is a reserved word.", name);
                    continue;
                }

                // make sure the variable name is not a common alias
                if (ISA_DATA.sRegAliases.ContainsKey(name))
                {
                    log.Error("'{0}' cannot be used as a variable because it is a common register alias.", name);
                    continue;
                }

                // make sure the name is not already added to the dictionary
                if (varsByName.ContainsKey(name))
                {
                    log.Error("Variable '{0}' has already been declared.", name);
                    continue;
                }

                // lets now add it to the var dictionary
                Variable var = new Variable()
                {
                    name                    = name,
                    isScaler                = (type == 's'),
                    size                    = size,
                    type                    = dataType,
                    regNo                   = requestedReg, // -1 for not yet assigned
                    variablesRegToCopy      = varsRegToCopy,
                    variablesRegToCopyIndex = varsRegToCopyIndex,
                    isRegisterNumSpecifed   = (requestedReg >= 0)
                };
                varsByName.Add(name, var);
                pendingNewVarsToAddToNextStmt.Add(var);

                // lets calculate usage
                RegUsageCalc regUsageCalc = var.isScaler ? sRegUsageCalc : vRegUsageCalc;
                if (regUsageCalc != null)
                {
                    regUsageCalc.AddToCalc(var.size, stmt);
                }
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Adds a label to the label dictionary.
 /// </summary>
 /// <param name="name">The name of the label. (i.e "myLabel" in myLabel:)</param>
 /// <param name="firstStmt">The next statement following this label.</param>
 /// <param name="log">Location to write errors and warnings.</param>
 public void AddLabel(string name, int lineNum, Stmt firstStmt, Log log)
 {
     Label newLabel = new Label { labelName = name, lineNum = lineNum, firstStmt = firstStmt };
     AddLabel(newLabel, log);
 }
Exemplo n.º 9
0
        //private void ProcessLine(string curLine, List<GcnStmt> needLabelFilled, int line, Log log)
        private void ProcessStmt(Stmt stmt, List<Stmt> needLabelFilled, Log log)
        {
            log.lineNum = stmt.lineNum;

            ///////// If instruction has a destination label then lets save it for later. /////////
            if (Regex.IsMatch(stmt.options, @"(?:^|\s|,)@[a-z_][0-9a-z_]+"))
            {
                if (stmt.inst.minSize == stmt.inst.maxSize)
                    stmt.opSize = stmt.inst.minSize;
                needLabelFilled.Add(stmt);
            }
            else
            {
                stmt.opCode = Encoder.convertInstToBin(stmt.options, stmt.inst, log);
                stmt.opSize = stmt.opCode.Size;
            }

        }
Exemplo n.º 10
0
        private void ProcessSingleStmt(string curLine, string stmtText, int lineNum, int stmtNumberOnLine, ref List<Variable> pendingNewVarsToAddToNextStmt, List<Label> pendingLabelsToAddToNextStmt, Log log, string[] stmts)
        {
            // Split out label from statement and record any labels on the line
            Match l = Regex.Match(stmtText, @"([a-z_][a-z0-9_]*):(\s|$)");
            if (l.Success)
            {
                pendingLabelsToAddToNextStmt.Add(new Label() { labelName = l.Groups[1].Value, lineNum = lineNum });
                if (l.Length == stmtText.Length)
                    return;
                stmtText = stmtText.Remove(0, l.Length);
            }

            // Replace Friendly statements with Asm statements
            stmtText = FriendlyConverter.FriendlyFormatToAsmFormater(stmtText, vars, ISA_Gen, log);

            // Extract first word, and options
            char[] delimiterChars = { ',', ' ' };
            string[] commands = stmtText.Split(delimiterChars, 2, StringSplitOptions.RemoveEmptyEntries);
            string firstWord = commands[0];
            //string options = commands.Count() > 1 ? commands[1].Trim() : "";

            Stmt stmt = new Stmt()
            {
                options = commands.Count() > 1 ? commands[1].Trim() : "",
                lineNum = lineNum,
                lineDepth = stmtNumberOnLine,
                fullStmt = stmtText,
                GcnStmtId = gcnStmts.Count,
            };

            /////////  Process Register Reservations, Renaming and Freeing /////////
            // New Format: [sv][1248][fiub][#] VarName    Free Format: free VarName
            // ren cat dog
            if (firstWord == "free")
            {
                string[] matches = stmt.options.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);
                foreach (string name in matches)
                    vars.FreeVariable(name, gcnStmts);
                return;
            }

            ///////// Process #S_POOL / #V_POOL  -->  sRegPool/vRegPool /////////
            //string cmd = Regex.Match(curLine, @"(?<=^\ *\#)(define|ref|[vs]_pool)").Value;
            if (firstWord == "#v_pool" || firstWord == "#s_pool")
            {
                // skip line if #S_POOL / #V_POOL
                if (!vars.UsingRegPools)
                    return;

                // Show warning if there are already existing vars.
                if (vars.Count > 0)
                    log.Warning("#S_POOL / #V_POOL normally occur in the header area. Having this command in the "
                        + "body can be used to clear all variable names and pool reservations.");

                Match def = Regex.Match(curLine, @"^\ *#(v|s)_pool\ *(?:(?:[vs](\d+)|(\S+?))\s*,?\s*)+");
                if (!def.Groups[0].Success | !def.Groups[2].Success)
                {
                    log.Error("error processing #POOL statement in '{0}'", curLine);
                    return;
                }

                if (def.Groups[3].Success)
                    log.Error("unknown value '{0}' in POOL command (skipping)", def.Groups[3]);

                int[] available_Regs = new int[def.Groups[2].Captures.Count];
                for (int i = 0; i < available_Regs.Length; i++)
                    available_Regs[i] = Int32.Parse(def.Groups[2].Captures[i].Value);

                vars.ReloadRegPool(def.Groups[1].Value[0], available_Regs);

                return;  // we are done with this statement.
            }

            ///////// Process Variable Declarations /////////
            // Example: s_mov_b32 v8u ttt, aaa, bbb
            // Example: s_mov_b32 v8u ttt S4, aaa, bbb
            // Example: v4u myVar0 s[2:3]; 
            // Example: s4u myVar1 myVar0
            // Single line Declarations
            Match m = Regex.Match(firstWord, @"(?<1>s|v)(?<2>1|2|4|8|16)(?<3>[fiub])");
            if (m.Success)
            {
                char type = m.Groups[1].Value[0];
                int size = Int32.Parse(m.Groups[2].Value);
                char dataType = m.Groups[3].Value[0];

                vars.AddVariable(pendingNewVarsToAddToNextStmt, stmt, log, type, size, dataType, stmt.options);
                return;
            }

            // Inline Declarations
            var inlines = Regex.Matches(stmt.options, @"(?<![a-z_0-9])(?<2>s|v)(?<3>1|2|4|8|16)(?<4>[fiub])[\t\s]+" +
                @"(?<5>(?<6>[a-z_][a-z_0-9]*)" +
                @"( [a-z_][a-z_0-9]*(\[\d+(?::\d+)\])?)?)");

            foreach (Match m3 in inlines)
            {
                char type = m3.Groups[2].Value[0];
                int size = Int32.Parse(m3.Groups[3].Value);
                char dataType = m3.Groups[4].Value[0];

                vars.AddVariable(pendingNewVarsToAddToNextStmt, stmt, log, type, size, dataType, m3.Groups[5].Value);
                stmt.options = stmt.options.Remove(m3.Index, m3.Length).Insert(m3.Index, m3.Groups[6].Value);
            }

            ///////// lookup instruction details /////////
            if (!ISA_DATA.isa_inst_dic.TryGetValue(firstWord, out stmt.inst))
            {
                log.Error("'{0}' is not a recognized instruction", firstWord);
                return;
            }

            ///////// Record var names and location making sure to exclude reserved words /////////
            var foundVars = Regex.Matches(stmt.options, @"(?<=,|\ |^)(?![vs]\d+)(([a-z_][a-z0-9_]*)(?:\[(\d+)\])?)(?=,|\ |$)");
            foreach (Match r in foundVars)
            {
                //Future: save char location so we don't have to search for the variable again when we do the replacement.

                string varName = r.Value;

                // ignore reserved words
                if (Array.BinarySearch<string>(ISA_DATA.AsmReserveDWords, varName) >= 0)
                    continue;

                // ignore common register aliases
                if (ISA_DATA.sRegAliases.ContainsKey(varName))
                    continue;

                int len = varName.Length;
                bool hasIndex = varName.EndsWith("]");
                int index = 0;
                int startPos = r.Index;

                if (hasIndex)
                {
                    varName = r.Groups[2].Value;
                    index = int.Parse(r.Groups[3].Value);
                }

                // Lets lookup the GcnVar to make sure it exists and also retrieve it.
                vars.MarkVariableUsedInStmt(stmt, varName, index, startPos, len);
            };

            ///////// Lets add the stmt to the list /////////
            // Before adding, lets link any pending statements.
            foreach (Label label in pendingLabelsToAddToNextStmt)
            {
                label.firstStmt = stmt;
                labels.AddLabel(label, log);
            }
            pendingLabelsToAddToNextStmt.Clear();

            // Also, lets link-up any new variables 
            if (pendingNewVarsToAddToNextStmt.Count > 0)
            {
                foreach (Variable v in pendingNewVarsToAddToNextStmt)
                    v.stmtDeclared = stmt;

                stmt.newVars = pendingNewVarsToAddToNextStmt;
                pendingNewVarsToAddToNextStmt = new List<Variable>();
            }
            gcnStmts.Add(stmt);

        }