Exemple #1
0
 protected override ExpressionTarget ComputeStatic(
     HlCompilation compilation,
     ExpressionTarget left,
     ExpressionTarget right)
 {
     return(new ExpressionTarget($"{left.StaticParse() * right.StaticParse()}", false, left.TypeDefinition));
 }
Exemple #2
0
        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);
 }
Exemple #6
0
        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);
        }
Exemple #7
0
        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());
        }