Example #1
0
        public override bool ValueOfStack(EmitContext ec)
        {
            ec.EmitComment("ValueOf Reference Stack @BP+" + Offset);
            ec.EmitInstruction(new Mov()
            {
                DestinationReg = EmitContext.DI, SourceIsIndirect = true, Size = 16, SourceReg = EmitContext.BP, SourceDisplacement = Offset
            });
            ec.EmitInstruction(new Mov()
            {
                DestinationReg = EmitContext.SI, SourceIsIndirect = true, Size = 16, SourceReg = EmitContext.DI
            });
            ec.EmitPop(EmitContext.SI, 16, true);

            return(true);
        }
        void EmitConstantLoop(EmitContext ec)
        {
            IntegralExpression ce = null;

            if (Expression is IntegralExpression)
            {
                ce = (IntegralExpression)Expression;
            }


            bool val = ce.Value != 0;

            if (val)
            { // if true
                infinite = true;

                ec.MarkLabel(EnterLoop);

                Statement.Emit(ec);
                ec.EmitInstruction(new Jump()
                {
                    DestinationLabel = EnterLoop.Name
                });
                ec.MarkLabel(ExitLoop);
            }
        }
        public override bool Emit(EmitContext ec)
        {
            if (Expression is IntegralExpression)
            {
                EmitConstantLoop(ec);
            }
            else
            {
                ec.EmitInstruction(new Jump()
                {
                    DestinationLabel = LoopCondition.Name
                });

                ec.MarkLabel(EnterLoop);

                Statement.Emit(ec);

                ec.MarkLabel(LoopCondition);
                // emit expression branchable
                Expression.EmitBranchable(ec, EnterLoop, true);
                // exit
                ec.MarkLabel(ExitLoop);
            }
            return(true);
        }
Example #4
0
 public override bool LoadEffectiveAddress(EmitContext ec)
 {
     ec.EmitComment("AddressOf Reference @BP+" + Offset);
     ec.EmitInstruction(new Mov()
     {
         DestinationReg = EmitContext.SI, SourceIsIndirect = true, Size = 16, SourceReg = EmitContext.BP, SourceDisplacement = Offset
     });
     ec.EmitPush(EmitContext.SI);
     return(true);
 }
 public override bool EmitBranchable(EmitContext ec, Label truecase, bool v)
 {
     Emit(ec);
     ec.EmitInstruction(new Compare()
     {
         DestinationReg = EmitContext.A, SourceValue = (ushort)1
     });
     ec.EmitBooleanBranch(v, truecase, ConditionalTestEnum.Equal, ConditionalTestEnum.NotEqual);
     return(true);
 }
Example #6
0
        public override bool ValueOfStackAccess(EmitContext ec, int off)
        {
            if (ReferenceType == ReferenceKind.Field)
            {
                ec.EmitComment("ValueOf Access Field ");
                ec.EmitInstruction(new Mov()
                {
                    DestinationReg = EmitContext.SI, SourceIsIndirect = true, Size = 16, SourceRef = ElementReference.New(Signature.ToString())
                });
                ec.EmitPop(EmitContext.SI, 16, true, off);
            }
            else if (ReferenceType == ReferenceKind.LocalVariable)
            {
                ec.EmitComment("ValueOf Stack Access @BP" + Offset);
                ec.EmitInstruction(new Mov()
                {
                    DestinationReg = EmitContext.SI, SourceIsIndirect = true, Size = 16, SourceReg = EmitContext.BP, SourceDisplacement = Offset
                });
                ec.EmitPop(EmitContext.SI, 16, true, off);
            }
            else if (ReferenceType == ReferenceKind.Register)
            {
                ec.EmitComment("ValueOf Stack Access @" + Register.ToString() + Offset);
                ec.EmitInstruction(new Mov()
                {
                    DestinationReg = EmitContext.SI, SourceIsIndirect = true, Size = 16, SourceReg = Register, SourceDisplacement = Offset
                });
                ec.EmitPop(EmitContext.SI, 16, true, off);
            }
            else
            {
                ec.EmitComment("ValueOf Access Stack @BP+" + Offset);
                ec.EmitInstruction(new Mov()
                {
                    DestinationReg = EmitContext.SI, SourceIsIndirect = true, Size = 16, SourceReg = EmitContext.BP, SourceDisplacement = Offset
                });

                ec.EmitPop(EmitContext.SI, 16, true, off);
            }
            return(true);
        }
Example #7
0
        public override bool LoadEffectiveAddress(EmitContext ec)
        {
            if (ReferenceType == ReferenceKind.Field)
            {
                ec.EmitComment("AddressOf Field ");

                ec.EmitInstruction(new Lea()
                {
                    DestinationReg = EmitContext.SI, SourceIsIndirect = true, SourceDisplacement = Offset, Size = 16, SourceRef = ElementReference.New(Signature.ToString())
                });
                ec.EmitPush(EmitContext.SI);
            }
            else if (ReferenceType == ReferenceKind.LocalVariable)
            {
                ec.EmitComment("AddressOf @BP" + Offset);
                ec.EmitInstruction(new Lea()
                {
                    DestinationReg = EmitContext.SI, SourceIsIndirect = true, Size = 16, SourceReg = EmitContext.BP, SourceDisplacement = Offset
                });
                ec.EmitPush(EmitContext.SI);
            }
            else if (ReferenceType == ReferenceKind.Register)
            {
                ec.EmitComment("AddressOf @" + Register.ToString() + Offset);
                ec.EmitInstruction(new Lea()
                {
                    DestinationReg = EmitContext.SI, SourceIsIndirect = true, Size = 16, SourceReg = Register, SourceDisplacement = Offset
                });
                ec.EmitPush(EmitContext.SI);
            }
            else
            {
                ec.EmitComment("AddressOf @BP+" + Offset);
                ec.EmitInstruction(new Lea()
                {
                    DestinationReg = EmitContext.SI, SourceIsIndirect = true, Size = 16, SourceReg = EmitContext.BP, SourceDisplacement = Offset
                });
                ec.EmitPush(EmitContext.SI);
            }
            return(true);
        }
Example #8
0
        public override bool Emit(EmitContext ec)
        {
            Expression.EmitToStack(ec);
            ec.EmitComment("!" + Expression.CommentString());
            ec.EmitPop(RegistersEnum.AX);


            ec.EmitInstruction(new Not()
            {
                DestinationReg = RegistersEnum.AX, Size = 80
            });
            ec.EmitInstruction(new And()
            {
                DestinationReg = RegistersEnum.AX, SourceValue = 1, Size = 80
            });
            ec.EmitPush(RegistersEnum.AX);



            return(true);
        }
Example #9
0
        public bool PopAllToRegister(EmitContext ec, RegistersEnum rg, int size, int offset = 0)
        {
            int s = size / 2;


            for (int i = 0; i < s; i++)
            {
                ec.EmitInstruction(new Pop()
                {
                    DestinationReg = rg, DestinationDisplacement = offset + 2 * i, DestinationIsIndirect = true, Size = 16
                });
            }
            if (size % 2 != 0)
            {
                ec.EmitPop(RegistersEnum.DX);
                ec.EmitInstruction(new Mov()
                {
                    DestinationReg = rg, DestinationDisplacement = offset - 1 + size, DestinationIsIndirect = true, Size = 8, SourceReg = RegistersEnum.DL
                });
            }
            return(true);
        }
Example #10
0
        public bool PushAllFromRegister(EmitContext ec, RegistersEnum rg, int size, int offset = 0)
        {
            int s = size / 2;

            if (size % 2 != 0)
            {
                ec.EmitInstruction(new Mov()
                {
                    DestinationReg = RegistersEnum.DL, SourceReg = rg, SourceDisplacement = offset - 1 + size, SourceIsIndirect = true, Size = 8
                });
                ec.EmitPush(RegistersEnum.DX);
            }
            for (int i = s - 1; i >= 0; i--)
            {
                ec.EmitInstruction(new Push()
                {
                    DestinationReg = rg, DestinationDisplacement = offset + 2 * i, DestinationIsIndirect = true, Size = 16
                });
            }

            return(true);
        }
Example #11
0
        public bool PushAllFromRef(EmitContext ec, ElementReference re, int size, int offset = 0)
        {
            ec.EmitComment("Push Field [TypeOf " + re.Name + "] Offset=" + offset);
            int s = size / 2;

            if (size % 2 != 0)
            {
                ec.EmitInstruction(new Mov()
                {
                    DestinationReg = RegistersEnum.DL, SourceRef = re, SourceDisplacement = offset + size - 1, SourceIsIndirect = true, Size = 8
                });
                ec.EmitPush(RegistersEnum.DX);
            }

            for (int i = s - 1; i >= 0; i--)
            {
                ec.EmitInstruction(new Push()
                {
                    DestinationRef = re, DestinationDisplacement = offset + 2 * i, DestinationIsIndirect = true, Size = 16
                });
            }

            return(true);
        }
Example #12
0
 public override bool EmitToStack(EmitContext ec)
 {
     if (ReferenceType == ReferenceKind.Field)
     {
         ec.EmitComment("Push Field @" + Signature.ToString() + " " + Offset);
         ec.EmitInstruction(new Push()
         {
             DestinationRef = ElementReference.New(Signature.ToString()), DestinationDisplacement = Offset, DestinationIsIndirect = true, Size = 16
         });
     }
     else if (ReferenceType == ReferenceKind.LocalVariable)
     {
         ec.EmitComment("Push Var @BP" + Offset);
         ec.EmitInstruction(new Push()
         {
             DestinationReg = EmitContext.BP, DestinationDisplacement = Offset, DestinationIsIndirect = true, Size = 16
         });
     }
     else if (ReferenceType == ReferenceKind.Register)
     {
         ec.EmitComment("Push Var @" + Register.ToString() + Offset);
         ec.EmitInstruction(new Push()
         {
             DestinationReg = Register, DestinationDisplacement = Offset, DestinationIsIndirect = true, Size = 16
         });
     }
     else
     {
         ec.EmitComment("Push Parameter @BP " + Offset);
         ec.EmitInstruction(new Push()
         {
             DestinationReg = EmitContext.BP, Size = 16, DestinationDisplacement = Offset, DestinationIsIndirect = true
         });
     }
     return(true);
 }
Example #13
0
        public bool PopAllToRef(EmitContext ec, ElementReference re, int size, int offset = 0)
        {
            ec.EmitComment("Pop Field [TypeOf " + re.Name + "] Offset=" + offset);
            int s = size / 2;


            for (int i = 0; i < s; i++)
            {
                ec.EmitInstruction(new Pop()
                {
                    DestinationRef = re, DestinationDisplacement = offset + 2 * i, DestinationIsIndirect = true, Size = 16
                });
            }

            if (size % 2 != 0)
            {
                ec.EmitPop(RegistersEnum.DX);
                ec.EmitInstruction(new Mov()
                {
                    DestinationRef = re, DestinationDisplacement = offset - 1 + size, DestinationIsIndirect = true, Size = 8, SourceReg = RegistersEnum.DL
                });
            }
            return(true);
        }
Example #14
0
 /// <summary>
 /// Emit code
 /// </summary>
 /// <returns>Success or fail</returns>
 public override bool Emit(EmitContext ec)
 {
     if (Expression is IntegralExpression)
     {
         EmitIfConstant(ec);
     }
     else
     {
         // emit expression branchable
         ec.EmitComment("if-expression evaluation");
         Expression.EmitBranchable(ec, Else, false);
         ec.EmitComment("(" + Expression.CommentString() + ") is true");
         TrueStatement.Emit(ec);
         ec.EmitInstruction(new Jump()
         {
             DestinationLabel = ExitIf.Name
         });
         ec.MarkLabel(Else);
         ec.EmitComment("Else ");
         FalseStatement.Emit(ec);
         ec.MarkLabel(ExitIf);
     }
     return(true);
 }
Example #15
0
        /// <summary>
        /// Emit code
        /// </summary>
        /// <returns>Success or fail</returns>
        public override bool Emit(EmitContext ec)
        {
            Label mlb = ec.DefineLabel(Method.Signature.ToString());

            mlb.Method = true;
            ec.MarkLabel(mlb);
            ec.EmitComment("Method: Name = " + Method.Name);
            // create stack frame
            ec.EmitComment("create stackframe");
            ec.EmitInstruction(new Push()
            {
                DestinationReg = EmitContext.BP, Size = 80
            });
            ec.EmitInstruction(new Mov()
            {
                DestinationReg = EmitContext.BP, SourceReg = EmitContext.SP, Size = 80
            });
            // allocate variables

            ushort         size   = 0;
            List <VarSpec> locals = ec.CurrentResolve.GetLocals();

            foreach (VarSpec v in locals)
            {
                size += 2;
            }



            if (size != 0)         // no allocation
            {
                ec.EmitInstruction(new Sub()
                {
                    DestinationReg = EmitContext.SP, SourceValue = size, Size = 80
                });
            }
            //EMit params
            var parameters = new List <ParameterSpec>();

            if (Parameters.Count > 0)
            {
                ec.EmitComment("Parameters Definitions");
                foreach (var par in Parameters)
                {
                    ec.EmitComment("Parameter " + par.Name + " @BP" + par.ParameterName.StackIdx);
                    parameters.Add(par.ParameterName);
                }
            }

            if (locals.Count > 0)
            {
                ec.EmitComment("Local Vars Definitions");
                foreach (VarSpec v in locals)
                {
                    ec.EmitComment("Local " + v.Name + " @BP" + v.VariableStackIndex);
                }
            }
            ec.EmitComment("Block");
            // Emit Code
            if (Block != null)
            {
                Block.Emit(ec);
            }

            ec.EmitComment("return label");
            // Return Label
            ec.MarkLabel(ec.DefineLabel(Method.Signature + "_ret"));

            // Destroy Stack Frame
            ec.EmitComment("destroy stackframe");
            ec.EmitInstruction(new Leave());
            // ret
            ccvh.EmitDecl(ec, ref parameters, CallingConventions.StdCall);
            return(true);
        }
        /// <summary>Emit code</summary>
        /// <returns>Success or fail</returns>
        public override bool Emit(EmitContext ec)
        {
            Left.EmitToStack(ec);
            //ec.MarkOptimizable(); // Marks last instruction as last push
            Right.EmitToStack(ec);
            //ec.MarkOptimizable(); // Marks last instruction as last push


            ec.EmitComment(Left.CommentString() + " " + GetOperatorString() + " " + Right.CommentString());

            if (Operator == Operators.Add)
            {
                ec.EmitPop(RegistersEnum.CX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Add()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.CX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitPush(RegistersEnum.AX);
            }
            else if (Operator == Operators.Sub)
            {
                ec.EmitPop(RegistersEnum.CX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Sub()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.CX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitPush(RegistersEnum.AX);
            }
            else if (Operator == Operators.Mul)
            {
                ec.EmitPop(RegistersEnum.CX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Multiply()
                {
                    DestinationReg = RegistersEnum.CX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitPush(RegistersEnum.CX);
            }
            else if (Operator == Operators.Div)
            {
                ec.EmitPop(RegistersEnum.CX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Xor()
                {
                    DestinationReg = EmitContext.D, SourceReg = EmitContext.D, Size = 80
                });
                ec.EmitInstruction(new Divide()
                {
                    DestinationReg = RegistersEnum.CX, Size = 80
                });
                ec.EmitPush(RegistersEnum.CX);
            }
            else if (Operator == Operators.Mod)
            {
                ec.EmitPop(RegistersEnum.CX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Xor()
                {
                    DestinationReg = EmitContext.D, SourceReg = EmitContext.D, Size = 80
                });
                ec.EmitInstruction(new Divide()
                {
                    DestinationReg = RegistersEnum.CX, Size = 80
                });
                ec.EmitInstruction(new Mov()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.DX, Size = 80
                });
                ec.EmitPush(RegistersEnum.AX);
            }
            else if (Operator == Operators.And)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new And()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitPush(RegistersEnum.AX);
            }
            else if (Operator == Operators.Or)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Or()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitPush(RegistersEnum.AX);
            }
            // Comparison
            else if (Operator == Operators.Equal)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBoolean(RegistersEnum.AL, ConditionalTestEnum.Equal, ConditionalTestEnum.NotEqual);
                ec.EmitPush(RegistersEnum.AX);
            }
            else if (Operator == Operators.NotEqual)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBoolean(RegistersEnum.AL, ConditionalTestEnum.NotEqual, ConditionalTestEnum.Equal);
                ec.EmitPush(RegistersEnum.AX);
            }
            else if (Operator == Operators.LT)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBoolean(RegistersEnum.AL, ConditionalTestEnum.LessThan, ConditionalTestEnum.GreaterThanOrEqualTo);
                ec.EmitPush(RegistersEnum.AX);
            }
            else if (Operator == Operators.GT)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBoolean(RegistersEnum.AL, ConditionalTestEnum.GreaterThan, ConditionalTestEnum.LessThanOrEqualTo);
                ec.EmitPush(RegistersEnum.AX);
            }
            else if (Operator == Operators.GTE)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBoolean(RegistersEnum.AL, ConditionalTestEnum.GreaterThanOrEqualTo, ConditionalTestEnum.LessThan);
                ec.EmitPush(RegistersEnum.AX);
            }
            else if (Operator == Operators.LTE)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBoolean(RegistersEnum.AL, ConditionalTestEnum.LessThanOrEqualTo, ConditionalTestEnum.GreaterThan);
                ec.EmitPush(RegistersEnum.AX);
            }


            return(base.Emit(ec));
        }
        public override bool EmitBranchable(EmitContext ec, Label truecase, bool v)
        {
            Left.EmitToStack(ec);
            //ec.MarkOptimizable(); // Marks last instruction as last push
            Right.EmitToStack(ec);
            //ec.MarkOptimizable(); // Marks last instruction as last push


            ec.EmitComment(Operator + "  " + Left.CommentString() + ",  " + Right.CommentString());


            if (Operator == Operators.Equal)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBooleanBranch(v, truecase, ConditionalTestEnum.Equal, ConditionalTestEnum.NotEqual);
            }
            else if (Operator == Operators.NotEqual)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBooleanBranch(v, truecase, ConditionalTestEnum.NotEqual, ConditionalTestEnum.Equal);
            }
            else if (Operator == Operators.LT)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBooleanBranch(v, truecase, ConditionalTestEnum.LessThan, ConditionalTestEnum.GreaterThanOrEqualTo);
            }
            else if (Operator == Operators.GT)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBooleanBranch(v, truecase, ConditionalTestEnum.GreaterThan, ConditionalTestEnum.LessThanOrEqualTo);
            }
            else if (Operator == Operators.GTE)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBooleanBranch(v, truecase, ConditionalTestEnum.GreaterThanOrEqualTo, ConditionalTestEnum.LessThan);
            }
            else if (Operator == Operators.LTE)
            {
                ec.EmitPop(RegistersEnum.BX);
                ec.EmitPop(RegistersEnum.AX);
                ec.EmitInstruction(new Compare()
                {
                    DestinationReg = RegistersEnum.AX, SourceReg = RegistersEnum.BX, Size = 80, OptimizingBehaviour = OptimizationKind.PPO
                });
                ec.EmitBooleanBranch(v, truecase, ConditionalTestEnum.LessThanOrEqualTo, ConditionalTestEnum.GreaterThan);
            }

            // jumps
            ec.EmitBooleanBranch(v, truecase, ConditionalTestEnum.Equal, ConditionalTestEnum.NotEqual);

            return(true);
        }