Esempio n. 1
0
        // We will use standard x86-64 conventions -> RDI, RSI, RDX, RCX, R8, R9.
        // TODO: instruction templates covering hw register modifications
        public ILabel GenerateCall(
            ILocation result,
            IEnumerable <VirtualRegister> callArguments,
            ILabel onReturn,
            Function.Function callerFunction,
            Function.Function function)
        {
            var needStackOffset = function.GetStackArgumentsCount() % 2 == 1 ? 8 : 0;
            var preCall         = new List <Node>
            {
                new AlignStackPointer(needStackOffset)
            }
            .Append(new Comment("Pass arguments"))
            .Concat(this.PassArguments(callerFunction, callArguments, function.Parent))
            .Append(new ClearDF())
            .Append(new Comment($"Call {function.MangledName}"))
            .Append(
                new UsesDefinesNode(
                    HardwareRegisterUtils.ArgumentRegisters.Take(callArguments.Count() + 1).ToList(),
                    HardwareRegisterUtils.CallerSavedRegisters));

            var postCall = new List <Node>
            {
                new Comment("Copy function result to variable"),
                this.readWriteGenerator.GenerateWrite(callerFunction, result, new RegisterRead(HardwareRegister.RAX)),
                new Comment("Restore RSP alignment"),
                new AlignStackPointer(-(needStackOffset + (8 * function.GetStackArgumentsCount()))),
                new Comment("End of call"),
            };

            var controlFlow = new FunctionCall(function, postCall.MakeTreeChain(this.labelFactory, onReturn));

            return(preCall.MakeTreeChain(this.labelFactory, controlFlow));
        }
Esempio n. 2
0
        private List <Node> GetArgumentSources(Function.Function function)
        {
            var registerArguments = HardwareRegisterUtils
                                    .ArgumentRegisters
                                    .Select(reg => new RegisterRead(reg));

            var memoryArguments = Enumerable.Range(0, function.GetStackArgumentsCount())
                                  .Select(n => (Node) new MemoryRead(HardwareRegister.RBP.OffsetAddress(n + 2)));

            return(registerArguments.Concat(memoryArguments).ToList());
        }