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()); }
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()); }
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()); }
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)); }
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); */ }