public CanCauseError <byte[]> GetDataUnit(IExpression <int>[] parameters, Func <string, int?> getSymbolValue, ScopeStructure <int> scope) { byte[] code = this.baseData.Clone() as byte[]; localLabels.Clear(); externLabels.Clear(); for (int index = 0; index < parameters.Length; ++index) { TemplateParameter paramTemp = this[index]; if (paramTemp.lenght > 0) { if (scope.GetRegisteredASMCLabels().Exists(o => o == parameters[index].ToString()) && !scope.IsLocalLabelExisted(parameters[index].ToString())) { paramTemp.InsertValues(new int [1], code); AddExternLabel(paramTemp.position / 8, parameters[index].ToString()); } else { CanCauseError <int[]> values = CodeTemplate.GetValues(parameters[index], paramTemp, getSymbolValue, this.pointerMaker); if (values.CausedError) { return(values.ConvertError <byte[]>()); } paramTemp.InsertValues(values.Result, code); if (scope.IsLocalLabelExisted(parameters[index].ToString())) { localLabels.Add(paramTemp.position / 8, parameters[index].ToString()); } } } } return((CanCauseError <byte[]>)code); }
private void PrintAssemblyCode(Code <int> code, ScopeStructure <int> scope, TextWriter output) { output.Write("\t"); for (int i = 0; i < code.Parameters.Length; i++) { // support EA macro in inline assembly if (!scope.IsLocalLabelExisted(code.Parameters[i].ToString()) && !scope.GetSymbolValue(code.Parameters[i].ToString()).CausedError) { output.Write(" #0x{0:X}", Folding.Fold(code.Parameters[i], (x => this.GetSymbolValue(scope, x))).Result); } else { output.Write(" {0}", code.Parameters[i].ToString()); } if (i == 0) { output.Write("\t"); if (code.Parameters[0].ToString() == "push" || code.Parameters[0].ToString() == "pop") { output.Write("{"); } } if (i != code.Parameters.Length - 1) { if (i != 0) { output.Write(","); } if (code.Parameters[0].ToString().StartsWith("ldr") || code.Parameters[0].ToString().StartsWith("str")) { if (i == 1) { output.Write("["); } } // Console.WriteLine(code.Parameters[i + 1].ToString()); if (System.Text.RegularExpressions.Regex.IsMatch(code.Parameters[i + 1].ToString(), @"^\d+$")) { output.Write("#"); } } else { if (code.Parameters[0].ToString() == "push" || code.Parameters[0].ToString() == "pop") { output.Write(" }"); } else if (code.Parameters[0].ToString().StartsWith("ldr") || code.Parameters[0].ToString().StartsWith("str")) { output.Write(" ]"); } output.Write("\n"); } } }
// private void DeclareExternASMCLabels<T>(ScopeStructure<int> scope, T output) private void DeclareExternASMCLabels(ScopeStructure <int> scope, TextWriter output) { //if (output is TextWriter) if (scope != null) { foreach (var label in scope.GetRegisteredASMCLabels()) { if (!scope.IsLocalLabelExisted(label)) { //(output as TextWriter).WriteLine("\t.global " + label); output.WriteLine("\t.global " + label); } } } }
private void ExecuteWritePass(TextWriter output, IExpression <int> expression, ScopeStructure <int> scope) { // This is to be executed *after* the layout pass switch (expression.Type) { case EAExpressionType.Scope: { ScopeStructure <int> newScope = scopeStructures [(Scope <int>)expression]; foreach (IExpression <int> child in expression.GetChildren()) { ExecuteWritePass(output, child, newScope); } break; } case EAExpressionType.Code: { Code <int> code = expression as Code <int>; // alignment. ALIGN 2^n => .align n if (!code.IsEmpty && code.CodeName.Name == offsetAligner && code.ParameterCount.IsInRange(1, 1) && !(code.Parameters[0] is ExpressionList <int>)) { output.WriteLine("\t.align {0}", Math.Ceiling(Math.Log(Folding.Fold(code.Parameters[0], (x => this.GetSymbolValue(scope, x))).Result, 2))); } if (code.IsEmpty || HandleBuiltInCodeWrite(code, scope, output)) { break; } bool TFlag = false; // bool ExtFlag = false; if (code.CodeName.Name == "ASMC") { if (code.Parameters.Length > 0 && code.Parameters[0].ToString() != "" && !scope.IsLocalLabelExisted(code.Parameters[0].ToString()) && !System.Text.RegularExpressions.Regex.IsMatch(code.Parameters[0].ToString(), @"\A\b(0[xX])?[0-9a-fA-F]+\b\Z")) { // ExtFlag = true; } else { TFlag = true; } } // Maybe all of this template lookup up can be made faster by // storing the found template from the layout pass? Types.Type[] sig = ((IEnumerable <IExpression <int> >)code.Parameters).Select(new Func <IExpression <int>, Types.Type> (Types.Type.GetType <int>)).ToArray(); CanCauseError <ICodeTemplate> templateError = this.storer.FindTemplate(code.CodeName.Name, sig); if (templateError.CausedError) { AddError <int, ICodeTemplate> ((IExpression <int>)code, templateError); break; } // We won't check for alignment as it should already have been done in the layout pass ICodeTemplate template = templateError.Result; /*if (template is CodeTemplate && code.Parameters.Length > 0) * { * for (int i = 0; i < code.Parameters.Length; i++) * { * if(scope.GetRegisteredASMCLabels().Exists(o => o == code.Parameters[i].ToString())) * { * (template as CodeTemplate).AddExternLabel(i, code.Parameters[i].ToString()); * } * } * }*/ CanCauseError <byte[]> data = template.GetData(code.Parameters, x => this.GetSymbolValue(scope, x), scope); Dictionary <int, string> localLabels = template.GetLocalLabels(); Dictionary <int, string> externLabels = template.GetExternLabels(); var labels = localLabels.Union(externLabels).ToList(); if (data.CausedError) { // Can't compute code data, so we err this.AddError <int, byte[]> (expression, data); } else { // Write data if (labels.Count == 0) { TryWrite(output, expression, currentOffset, data.Result); } else { int startIndex = 0; foreach (KeyValuePair <int, string> k in labels) { // Console.WriteLine("pos:" + k.Key + " label:" + k.Value); if (k.Key - startIndex > 0) { TryWrite(output, expression, currentOffset, data.Result.Skip(startIndex).Take(k.Key - startIndex).ToArray()); } startIndex = k.Key + 4; if (TFlag == true && scope.IsLocalLabelExisted(k.Value)) { output.WriteLine("\t.word {0}+1", k.Value); TFlag = false; } else { output.WriteLine("\t.word {0}", k.Value); } } if (data.Result.Length - startIndex > 4) { TryWrite(output, expression, currentOffset, data.Result.Skip(startIndex).Take(data.Result.Length - startIndex).ToArray()); } } } this.currentOffset += data.Result.Length; /*for (int i = 0; i < code.Parameters.Length; i++) * { * // Console.WriteLine(code.Parameters[i]); * if (scope.IsLabelExisted(code.Parameters[i].ToString())) * { * output.WriteLine("\t.word {0}", code.Parameters[i]); * this.currentOffset += 4; * } * else * { * IExpression<int>[] parameter = new IExpression<int>[] { code.Parameters[i] }; * CanCauseError<byte[]> data = template.GetDataUnit(parameter, x => this.GetSymbolValue(scope, x)); * if (data.CausedError) * // Can't compute code data, so we err * this.AddError<int, byte[]>(expression, data); * else * { * // Write data * TryWrite(output, expression, currentOffset, data.Result); * this.currentOffset += data.Result.Length; * } * } * }*/ break; } case EAExpressionType.RawData: { RawData <int> rawData = (RawData <int>)expression; TryWrite(output, expression, this.currentOffset, rawData.Data); this.currentOffset += rawData.Data.Length; break; } case EAExpressionType.Labeled: //TODO Add label attribute: ".global LabelName" output.WriteLine(((LabelExpression <int>)expression).LabelName + ":"); break; case EAExpressionType.Assignment: //TODO .set/.equ, but it doesn't matter break; default: throw new ArgumentException("Badly formed tree."); } }