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); } }
//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); } } }
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); } } }