Пример #1
0
        public void SimpleTest()
        {
            var template  = new RegisterReadTemplate();
            var templates = new List <InstructionTemplate> {
                template
            };
            var root     = new RegisterRead(new VirtualRegister());
            var tree     = new Tree(root, new Ret());
            var selector = new InstructionSelector(templates);
            var ins      = selector.GetInstructions(tree);

            Assert.AreEqual(2, ins.Count());
        }
Пример #2
0
        public void AddTest()
        {
            var templates = new List <InstructionTemplate> {
                new AddTemplate(), new RegisterReadTemplate()
            };
            var v1       = new RegisterRead(new VirtualRegister());
            var v2       = new RegisterRead(new VirtualRegister());
            var v3       = new RegisterRead(new VirtualRegister());
            var node     = new ArithmeticBinaryOperation(ArithmeticOperationType.Addition, v1, v2);
            var root     = new ArithmeticBinaryOperation(ArithmeticOperationType.Addition, v3, node);
            var tree     = new Tree(root, new Ret());
            var selector = new InstructionSelector(templates);
            var ins      = selector.GetInstructions(tree);

            Assert.AreEqual(6, ins.Count());
        }
Пример #3
0
        public void NullTest()
        {
            InstructionTemplate nullTemplate = new NullTemplate();
            var template  = new RegisterReadTemplate();
            var templates = new List <InstructionTemplate> {
                template, nullTemplate
            };
            var root       = new RegisterRead(new VirtualRegister());
            var trueTarget =
                this.labelFactory.GetLabel(new Tree(new UnitImmediateValue(), new UnconditionalJump(null)));
            var controlFlow = new ConditionalJump(trueTarget, null);
            var tree        = new Tree(root, controlFlow);
            var selector    = new InstructionSelector(templates);
            var ins         = selector.GetInstructions(tree);

            Assert.AreEqual(2, ins.Count());
        }
Пример #4
0
        public ILabel GenerateClosureCall(
            ILocation result,
            IEnumerable <VirtualRegister> callArguments,
            ILabel onReturn,
            Function.Function callerFunction,
            FunType funType,
            VirtualRegister funPtr)
        {
            var needStackOffset = funType.GetStackArgumentsCount() % 2 == 1 ? 8 : 0;
            var funPtrRead      = new RegisterRead(funPtr);
            var funCodePtr      = new MemoryRead(
                new ArithmeticBinaryOperation(AST.ArithmeticOperationType.Addition, funPtrRead, new IntegerImmediateValue(0)));
            var funClosurePtr = new MemoryRead(
                new ArithmeticBinaryOperation(AST.ArithmeticOperationType.Addition, funPtrRead, new IntegerImmediateValue(16)));
            var preCall = new List <Node>
            {
                new AlignStackPointer(needStackOffset)
            }
            .Append(new Comment("Pass arguments"))
            .Concat(this.PassClosureArguments(callArguments, funClosurePtr))
            .Append(new ClearDF())
            .Append(new Comment($"Call closure function"))
            .Append(
                new UsesDefinesNode(
                    HardwareRegisterUtils.ArgumentRegisters.Take(callArguments.Count() + 1).ToList(),
                    HardwareRegisterUtils.CallerSavedRegisters))
            .Append(new RegisterWrite(HardwareRegister.RAX, funCodePtr));

            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 * funType.GetStackArgumentsCount()))),
                new Comment("End of call"),
            };

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

            return(preCall.MakeTreeChain(this.labelFactory, controlFlow));
        }
Пример #5
0
        public void Test()
        {
            /*
             * fun a():Unit{
             *    var unused1:Int;
             *    var unused2:Int;
             *    var a:Int;
             *    fun b():Unit{
             *        var unused3:Int;
             *        var b:Int;
             *            fun c():Unit{
             *                var c:Int;
             *                var uniqueNode:Int;
             *                 c=uniqueNode;
             *                 b;
             *                 c;
             *            }
             *    }
             * }
             *
             */
            var functionInfoA = new Function(null, "a", new List <VariableDeclaration>(), false, false);

            functionInfoA.ReserveClosureLocation("dummy", IntType.Instance);
            functionInfoA.ReserveClosureLocation("dummy", IntType.Instance);
            functionInfoA.ReserveClosureLocation("dummy", IntType.Instance);
            functionInfoA.ReserveClosureLocation("dummy", IntType.Instance);
            var functionInfoB = new Function(functionInfoA, "b", new List <VariableDeclaration>(), false, false);

            functionInfoB.ReserveClosureLocation("dummy", IntType.Instance);
            functionInfoB.ReserveClosureLocation("dummy", IntType.Instance);
            functionInfoB.ReserveClosureLocation("dummy", IntType.Instance);
            var functionInfoC = new Function(functionInfoB, "c", new List <VariableDeclaration>(), false, false);

            functionInfoC.ReserveClosureLocation("dummy", IntType.Instance);
            functionInfoC.ReserveClosureLocation("dummy", IntType.Instance);

            var variableALocation = functionInfoA.ReserveClosureLocation("a", IntType.Instance);
            var variableA         = variableALocation;

            var variableBLocation = functionInfoB.ReserveClosureLocation("b", IntType.Instance);
            var variableB         = variableBLocation;

            var variableCLocation = new VirtualRegister();
            var variableC         = variableCLocation;

            var uniqueNode = new RegisterRead(new VirtualRegister());

            var readWriteGenerator = new ReadWriteGenerator();

            var cReadOperation = (RegisterRead)readWriteGenerator.GenerateRead(functionInfoC, variableC);
            var cReadOperationActualRegister = cReadOperation.Register;

            Assert.AreEqual(variableCLocation, cReadOperationActualRegister);

            var cWriteOperation = (RegisterWrite)readWriteGenerator.GenerateWrite(functionInfoC, variableC, uniqueNode);
            var writeCOperationActualRegister = cWriteOperation.Register;
            var writeCActualValue             = cWriteOperation.Value;

            Assert.AreEqual(variableCLocation, writeCOperationActualRegister);
            Assert.AreEqual(uniqueNode, writeCActualValue);

            var bRead        = (MemoryRead)readWriteGenerator.GenerateRead(functionInfoC, variableB);
            var computeBRead = (ArithmeticBinaryOperation)bRead.Addr;

/*
 *          var bReadLeft = (RegisterRead)computeBRead.Lhs;
 */
            var bReadRight = (IntegerImmediateValue)computeBRead.Rhs;

/*
 *          Assert.AreEqual(cLinkLocation, bReadLeft.Register);
 */
            Assert.AreEqual(variableBLocation.Offset, bReadRight.Value);

            var actualARead    = (MemoryRead)readWriteGenerator.GenerateRead(functionInfoC, variableA);
            var actualAAddress = (ArithmeticBinaryOperation)actualARead.Addr;

/*
 *          var actualAAddressLeft = (MemoryRead)actualAAddress.Lhs;
 */
            var actualAAddressRight = (IntegerImmediateValue)actualAAddress.Rhs;

/*
 *          var actualAStackAddress = (ArithmeticBinaryOperation)actualAAddressLeft.Addr; // bLink
 */
/*
 *          var actualAStackAddressLeft = (RegisterRead)actualAStackAddress.Lhs;
 *          var actualAStackAddressRight = (IntegerImmediateValue)actualAStackAddress.Rhs;
 */
            Assert.AreEqual(variableALocation.Offset, actualAAddressRight.Value);

/*
 *          Assert.AreEqual(functionBLinkLocation.Offset, actualAStackAddressRight.Value);
 *          Assert.AreEqual(cLinkLocation, actualAStackAddressLeft.Register);
 */
        }