Exemple #1
0
        public IEnumerable <Operation> VisitBlock(Block block)
        {
            LocalVariables = TypeEvaluator.RoundBy8(TypeEvaluator.SizeOf(block.Variables));

            FunctionFrame += LocalVariables;
            yield return(Operation.Sub(Register.Rsp, LocalVariables));

            foreach (var op in block.Statements.SelectMany(s => s.AcceptVisitor(this)))
            {
                yield return(op);
            }

            yield return(Operation.Add(Register.Rsp, LocalVariables));

            FunctionFrame -= LocalVariables;
        }
Exemple #2
0
        public IEnumerable <Operation> VisitCallExpression(CallExpression callExpression)
        {
            var type   = (FunctionType)Types.TypeOf(callExpression.Function);
            var pars   = FunctionParams[type];
            var offset = TypeEvaluator.RoundBy8(TypeEvaluator.SizeOf(pars.StackStruct));

            FunctionFrame += offset;
            yield return(Operation.Sub(Register.Rsp, offset));

            var registerResults = new List <AnyRegister>();
            var arguments       = callExpression.Params;

            for (var i = 0; i < arguments.Count; i++)
            {
                var(onStack, place) = pars.Params[i];
                if (onStack)
                {
                    foreach (var op in _addressVisitor.VisitExpression(arguments[i]))
                    {
                        yield return(op);
                    }
                    var adr = LastRegister;

                    foreach (var op in MakeAssigner(
                                 new Shift(Register.Rsp, place),
                                 new Shift(adr, 0),
                                 Types.TypeOf(arguments[i])
                                 )
                             )
                    {
                        yield return(op);
                    }
                }
                else
                {
                    foreach (var op in arguments[i].AcceptVisitor(this))
                    {
                        yield return(op);
                    }
                    registerResults.Add(LastRegister);
                }
            }

            foreach (var op in callExpression.Function.AcceptVisitor(this))
            {
                yield return(op);
            }
            var func = LastRegister;

            foreach (var(res, i) in registerResults.Select((v, i) => (v, i)))
            {
                yield return(Operation.Mov(Params[i], res));
            }

            yield return(new UnaryOperation(UnaryOperation.OpCode.Call, func));

            FunctionFrame -= offset;
            yield return(Operation.Add(Register.Rsp, offset));

            if (SimpleTypeSize(type.Result) is { } size&& size > 0)
            {
                yield return(Operation.Mov(NewRegister(size), Register.Rax));
            }
        }