Beispiel #1
0
        public Variables(bool UseRegPool, bool CalcRegUsage, Log log)
        {
            this.log = log;

            if (UseRegPool)
            {
                sRegPool = new RegPool(log);
                vRegPool = new RegPool(log);
            }

            if (CalcRegUsage)
            {
                sRegUsageCalc = new RegUsageCalc(true);
                vRegUsageCalc = new RegUsageCalc(true);
            }
        }
Beispiel #2
0
        public Variables(bool UseRegPool, bool CalcRegUsage, Log log)
        {
            this.log = log;

            if (UseRegPool)
            {
                sRegPool = new RegPool(log);
                vRegPool = new RegPool(log);
            }

            if (CalcRegUsage)
            {
                sRegUsageCalc = new RegUsageCalc(true);
                vRegUsageCalc = new RegUsageCalc(true);
            }
        }
Beispiel #3
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);
                }
            }
        }
Beispiel #4
0
        public void AssignRegNumbers(List <Stmt> gcnStmts)
        {
            foreach (Stmt stmt in gcnStmts)
            {
                // note: When using the 'free' keyword, variables are freed before the previous statement.
                // Also, vars are freed before declarations so registers can be reused in the same instruction.
                log.lineNum = stmt.lineNum;

                ////////////////////// free the vars //////////////////////
                if (UsingRegPools)
                {
                    foreach (Variable v in stmt.freeVars)
                    {
                        if (v.stmtTerminated != v.stmtDeclared)
                        {
                            (v.isScaler ? sRegPool : vRegPool).FreeReg(v.regNo);
                        }
                        else
                        {
                            log.Warning("Variable, {0}, was declared and last used in the same statement.", v.name);
                        }
                    }
                }

                ////////////////////// declare new vars //////////////////////
                // we first add variables that specify a register or variables
                foreach (Variable v in stmt.newVars)
                {
                    if (v.isRegisterNumSpecifed && !v.isRegisterFromAnotherVar)
                    {
                        // Adds a GcnVar to the Vars collection and also makes sure that it is valid.
                        // Lets add mark that register as used in the pool (if it is in the pool)
                        RegPool regPool = v.isScaler ? sRegPool : vRegPool;
                        if (UsingRegPools)
                        {
                            if (regPool.ReserveSpecificRegs(v.regNo, v.RegsRequired) < 0)
                            {
                                log.Error("The registers, {1}, used in '{0}' must was not found in the allowed register pool.", v.regNo, v.name);
                            }
                        }

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

                    // process declarations with variable as register reference
                    else if (v.isRegisterFromAnotherVar)
                    {
                        Variable lu;
                        if (!varsByName.TryGetValue(v.variablesRegToCopy, out lu))
                        {
                            log.Error("Variable, '{0}', could not be found.", v.variablesRegToCopy);
                        }
                        else if (lu.stmtTerminated == null)
                        {
                            log.Error("Variable, '{0}', can not use the same register as '{1}' because its still in use.", v.name, lu.name);
                        }
                        else
                        {
                            int     regNum  = lu.regNo + v.variablesRegToCopyIndex;
                            RegPool regPool = v.isScaler ? sRegPool : vRegPool;
                            if (UsingRegPools)
                            {
                                v.regNo = regPool.ReserveSpecificRegs(regNum, v.size);
                            }
                        }
                    }
                }

                foreach (Variable v in stmt.newVars)
                {
                    if (!v.isRegisterNumSpecifed) // exclude Registers with specified register numbers
                    {
                        v.regNo = (v.isScaler ? sRegPool : vRegPool).ReserveRegs(v.RegsRequired, v.RegsRequired);
                    }
                }

                // Replace the variables with register numbers.
                //if (stmt.vars.Count > 0)
                for (int i = stmt.vars.Count - 1; i >= 0; i--)
                {
                    VariableUsageLoc v = stmt.vars[i];
                    stmt.options = stmt.options.Remove(v.startPos, v.varLength).Insert(v.startPos, v.RegAsString);
                }
            }
        }