protected override ExpressionTarget ComputeStatic( HlCompilation compilation, ExpressionTarget left, ExpressionTarget right) { return(new ExpressionTarget($"{left.StaticParse() * right.StaticParse()}", false, left.TypeDefinition)); }
private bool IsReducable(ExpressionTarget target) { if (!target.IsAddress) { uint v = target.StaticParse(); return(v != 0 && (v & (v - 1)) == 0); //Is Power of 2? } return(false); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlBinaryOp expr) { ExpressionTarget target = compilation.Parse(expr.Left); ExpressionTarget rTarget = compilation.Parse( expr.Right ); if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeReduceExpressions&& IsReducable(rTarget)) { uint amount = GetPowLevel(rTarget.StaticParse()); string tmp = compilation.GetTempVarLoad(amount.ToString()); ExpressionTarget taddr = target.MakeAddress(compilation); compilation.EmitterResult.Emit( "SHR", taddr.ResultAddress, tmp ); compilation.ReleaseTempVar(tmp); compilation.ReleaseTempVar(taddr.ResultAddress); return(target); } string rtOrig = rTarget.ResultAddress; rTarget = rTarget.MakeAddress(compilation); string instrKey = target.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName || rTarget.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName ? InstructionKey + ".F" : InstructionKey; compilation.EmitterResult.Emit( instrKey, target.ResultAddress, rTarget.ResultAddress ); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(rtOrig); return(target); }
public override ExpressionTarget ParseExpression(HlCompilation compilation, HlWhileOp expr) { string startLabel = HlCompilation.GetUniqueName("while_start"); string endLabel = HlCompilation.GetUniqueName("while_end"); HlCompilation whileComp = new HlCompilation(compilation, HlCompilation.GetUniqueName("while")); whileComp.EmitterResult.Store($".{startLabel} linker:hide"); ExpressionTarget targetVal = whileComp.Parse(expr.Condition); if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeWhileConditionExpressions&& !targetVal.IsAddress) { if (targetVal.StaticParse() != 0) //If True we parse body without check and directly jump to condition //If False we omit the whole loop entirely { ParseBody(whileComp, expr, startLabel, endLabel); } compilation.EmitterResult.Store(whileComp.EmitVariables(false)); compilation.EmitterResult.Store(whileComp.EmitterResult.Get()); return(new ExpressionTarget()); } ExpressionTarget target = targetVal.MakeAddress(whileComp); //Make sure we have an address and not a static value whileComp.EmitterResult.Emit($"BEZ", target.ResultAddress, endLabel); ParseBody(whileComp, expr, startLabel, endLabel); whileComp.ReleaseTempVar(target.ResultAddress); whileComp.ReleaseTempVar(targetVal.ResultAddress); compilation.EmitterResult.Store(whileComp.EmitVariables(false)); compilation.EmitterResult.Store(whileComp.EmitterResult.Get()); //.while_start //LOAD tmp_condition_var 0x00 //<PARSE CONDITION EXPR HERE> //BEZ tmp_condition_var while_end //<PARSE BLOCK HERE> //JMP while_start //.while_end return(new ExpressionTarget()); }
public override uint StaticEvaluate(ExpressionTarget a, ExpressionTarget b) { return(a.StaticParse() > b.StaticParse() ? 1U : 0U); }
public override ExpressionTarget ParseExpression( HlCompilation compilation, HlBinaryOp expr, ExpressionTarget outputTarget) { ExpressionTarget targetVal = compilation.Parse(expr.Left); ExpressionTarget rTargetVal = compilation.Parse(expr.Right); if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeConstExpressions&& !targetVal.IsAddress && !rTargetVal.IsAddress) { return(ComputeStatic(compilation, targetVal, rTargetVal)); } if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeConstExpressions) { uint amount = 0; ExpressionTarget baseExpr = default; if (IsReducable(targetVal)) { baseExpr = rTargetVal.MakeAddress(compilation); amount = GetPowLevel(targetVal.StaticParse()); } else if (IsReducable(rTargetVal)) { baseExpr = targetVal.MakeAddress(compilation); amount = GetPowLevel(rTargetVal.StaticParse()); } if (amount != 0) { string tmp = compilation.GetTempVarLoad(amount.ToString()); compilation.EmitterResult.Emit( "SHL", baseExpr.ResultAddress, tmp, outputTarget.ResultAddress ); compilation.ReleaseTempVar(tmp); compilation.ReleaseTempVar(baseExpr.ResultAddress); compilation.ReleaseTempVar(targetVal.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(outputTarget); } } ExpressionTarget target = targetVal.MakeAddress(compilation); ExpressionTarget rTarget = rTargetVal.MakeAddress(compilation); string instrKey = target.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName || rTarget.TypeDefinition.Name == HLBaseTypeNames.s_FloatTypeName ? InstructionKey + ".F" : InstructionKey; if (target.IsPointer) { ExpressionTarget et = new ExpressionTarget( compilation.GetTempVarDref(target.ResultAddress), true, target.TypeDefinition ); compilation.EmitterResult.Emit( instrKey, et.ResultAddress, rTarget.ResultAddress, outputTarget.ResultAddress ); compilation.ReleaseTempVar(et.ResultAddress); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(target.ResultAddress); compilation.ReleaseTempVar(targetVal.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(outputTarget); } compilation.EmitterResult.Emit( instrKey, target.ResultAddress, rTarget.ResultAddress, outputTarget.ResultAddress ); compilation.ReleaseTempVar(rTarget.ResultAddress); compilation.ReleaseTempVar(target.ResultAddress); compilation.ReleaseTempVar(targetVal.ResultAddress); compilation.ReleaseTempVar(rTargetVal.ResultAddress); return(outputTarget); }
public override ExpressionTarget ParseExpression(HlCompilation compilation, HlIfOp expr) { string endLabel = HlCompilation.GetUniqueName("if_end"); string elseLabel = HlCompilation.GetUniqueName("if_else"); string blockLabels = HlCompilation.GetUniqueName("if_b{0}"); bool staticComputation = false; compilation.EmitterResult.Store("; Start IF"); for (int i = 0; i < expr.ConditionMap.Count; i++) { string thisLabel = string.Format(blockLabels, i); HlCompilation subIf = new HlCompilation(compilation, HlCompilation.GetUniqueName(thisLabel)); if (SettingsManager.GetSettings <HlCompilerSettings>().OptimizeIfConditionExpressions&& expr.ConditionMap[i].Item1.IsStatic()) { ExpressionTarget t = subIf.Parse( expr.ConditionMap[i].Item1 ); if (t.StaticParse() != 0) { staticComputation = true; foreach (HlExpression hlExpression in expr.ConditionMap[i].Item2) { ExpressionTarget e = subIf.Parse(hlExpression); compilation.ReleaseTempVar(e.ResultAddress); } compilation.EmitterResult.Store(subIf.EmitVariables(false)); compilation.EmitterResult.Store(subIf.EmitterResult.Get()); break; } if (i != 0) { subIf.EmitterResult.Store($".{thisLabel} linker:hide"); } continue; } if (i != 0) { subIf.EmitterResult.Store($".{thisLabel} linker:hide"); } ExpressionTarget exprTargetVal = subIf.Parse( expr.ConditionMap[i].Item1 ); ExpressionTarget exprTarget = exprTargetVal.MakeAddress(subIf); string nextLabel; if (i < expr.ConditionMap.Count - 1) { nextLabel = string.Format(blockLabels, i + 1); } else { nextLabel = expr.ElseBranch != null ? elseLabel : endLabel; } subIf.EmitterResult.Emit($"BEZ", exprTarget.ResultAddress, nextLabel); foreach (HlExpression hlExpression in expr.ConditionMap[i].Item2) { ExpressionTarget e = subIf.Parse(hlExpression); compilation.ReleaseTempVar(e.ResultAddress); } subIf.EmitterResult.Emit($"JMP", endLabel); subIf.ReleaseTempVar(exprTarget.ResultAddress); subIf.ReleaseTempVar(exprTargetVal.ResultAddress); compilation.EmitterResult.Store(subIf.EmitVariables(false)); compilation.EmitterResult.Store(subIf.EmitterResult.Get()); } if (!staticComputation && expr.ElseBranch != null) { HlCompilation subIf = new HlCompilation(compilation, elseLabel); subIf.EmitterResult.Store($".{elseLabel} linker:hide"); foreach (HlExpression hlExpression in expr.ElseBranch) { ExpressionTarget e = subIf.Parse(hlExpression); compilation.ReleaseTempVar(e.ResultAddress); } compilation.EmitterResult.Store(subIf.EmitVariables(false)); compilation.EmitterResult.Store(subIf.EmitterResult.Get()); } compilation.EmitterResult.Store($".{endLabel} linker:hide"); return(new ExpressionTarget()); }