コード例 #1
0
ファイル: Visualizer.cs プロジェクト: kenkendk/ac3il
        private void AddRecursive(AccCIL.IR.InstructionElement el, TreeNode parentNode)
        {
            TreeNode n = new TreeNode(el.Instruction.OpCode.ToString());
            n.Tag = el;
            parentNode.Nodes.Add(n);

            foreach (var elc in el.Childnodes)
                AddRecursive(elc, n);
        }
コード例 #2
0
ファイル: RegisterAllocator.cs プロジェクト: kenkendk/ac3il
        public List<int> AllocateRegisters(int extraRegisters, AccCIL.IRegisterAllocator allocator, AccCIL.IR.MethodEntry method)
        {
            List<int> usedRegisters = new List<int>();
            AssignFixedRegisters(usedRegisters, method);

            if (allocator != null)
            {
                Stack<int> registers = new Stack<int>(Enumerable.Range(extraRegisters, 128 - extraRegisters));
                usedRegisters.AddRange(allocator.AllocateRegisters(registers, method));
            }

            return usedRegisters.Distinct().ToList();
        }
コード例 #3
0
ファイル: BuiltInSPEMethods.cs プロジェクト: kenkendk/ac3il
        internal static uint malloc(uint[] objtable, AccCIL.KnownObjectTypes type, uint size, uint typestring_index)
        {
            if (objtable[1] >= objtable[0])
            {
                //TODO: Do garbage collection and re-check space
                //NOTE: When GC is done, re-visit the ldelema instruction
                //TODO: throw new OutOfMemoryException();
                return 0;
            }

            uint nextoffset = objtable[2];
            uint requiredSpace = (size + 15 >> 4) << 4;

            //TODO: Do not rely on SPE mem size, but rather $SP
            if (nextoffset + requiredSpace >= objtable[3])
            {
                //TODO: Do garbage collection and re-check space
                //NOTE: When GC is done, re-visit the ldelema instruction
                //TODO: throw new OutOfMemoryException();
                return 0;
            }

            uint nextel = objtable[1];
            objtable[2] = nextoffset + requiredSpace;

            uint realtype;

            //For objects, we use the upper 16 bits to encode the typestring index
            if (typestring_index == 0)
                realtype = (uint)type & 0xffu;
            else
            {
                realtype = (typestring_index << 16) | ((uint)type & 0xffu);
                objtable[typestring_index * 4 + 3]++; //Increment refcount
            }

            uint n = nextel * 4;

            objtable[1] = objtable[n + 3];

            objtable[n] = realtype;
            objtable[n + 1] = size;
            objtable[n + 2] = nextoffset;
            objtable[n + 3] = 1;

            return nextel;
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: kenkendk/ac3il
        public static void TestSuite(AccCIL.IAccellerator acc)
        {
            acc.Accelerate(CILFac.Fac.TestLogicals);
            acc.Accelerate(CILFac.Fac.TestArithmetics);
            acc.Accelerate(CILFac.Fac.TestMultiply);
            int [] n = new int[] { 4 };
            acc.Accelerate(CILArray.ArrayTest.testRef, n, n);

            n = new int[] { 42 };
            acc.Accelerate(CILArray.ArrayTest.testRef2, n, n);

            if (acc.Accelerate<object, int>(CILFac.Fac.UnboxTest, (object)42) != 42)
                throw new Exception("Unbox failed");

            acc.Accelerate(CILFac.Fac.WritelineTest, 42);
            acc.Accelerate(CILFac.Fac.WritelineTest2, (object)42);
            acc.Accelerate(CILFac.Fac.WritelineTest3, 42);

            byte[] b1 = acc.Accelerate<byte[]>(CILArray.ArrayTest.byteArrayGenerateTest);
            uint[] u1 = acc.Accelerate<uint[]>(CILArray.ArrayTest.uintArrayGenerateTest);
            int[] i1 = acc.Accelerate<int[]>(CILArray.ArrayTest.intArrayGenerateTest);
            float[] f1 = acc.Accelerate<float[]>(CILArray.ArrayTest.floatArrayGenerateTest);
            double[] d1 = acc.Accelerate<double[]>(CILArray.ArrayTest.doubleArrayGenerateTest);
            object[] o1 = acc.Accelerate<object[]>(CILArray.ArrayTest.boxedArrayGenerateTest);

            byte[] b2 = CILArray.ArrayTest.byteArrayGenerateTest();
            uint[] u2 = CILArray.ArrayTest.uintArrayGenerateTest();
            int[] i2 = CILArray.ArrayTest.intArrayGenerateTest();
            float[] f2 = CILArray.ArrayTest.floatArrayGenerateTest();
            double[] d2 = CILArray.ArrayTest.doubleArrayGenerateTest();
            object[] o2 = CILArray.ArrayTest.boxedArrayGenerateTest();

            if (b1.Length != b2.Length)
                throw new Exception("Byte array generate failed");
            if (u1.Length != u2.Length)
                throw new Exception("UInt array generate failed");
            if (i1.Length != i2.Length)
                throw new Exception("Int array generate failed");
            if (f1.Length != f2.Length)
                throw new Exception("Float array generate failed");
            if (d1.Length != d2.Length)
                throw new Exception("Double array generate failed");
            if (o1.Length != o2.Length)
                throw new Exception("Boxed array generate failed");

            for (int i = 0; i < b1.Length; i++)
                if (b1[i] != b2[i])
                    throw new Exception("Byte array generate failed, values");
            for (int i = 0; i < u1.Length; i++)
                if (u1[i] != u2[i])
                    throw new Exception("UInt array generate failed, values");
            for (int i = 0; i < i1.Length; i++)
                if (i1[i] != i2[i])
                    throw new Exception("Int array generate failed, values");
            for (int i = 0; i < f1.Length; i++)
                if (f1[i] != f2[i])
                    throw new Exception(string.Format("Float array generate failed, values: {0} vs {1} at {2}", (double)f1[i], (double)f2[i], i));
            for (int i = 0; i < d1.Length; i++)
                if (d1[i] != d2[i])
                    throw new Exception(string.Format("Double array generate failed, values: {0} vs {1} at {2}", d1[i], d2[i], i));

            for (int i = 0; i < o1.Length; i++)
            {
                if (!o1[i].Equals(o2[i]))
                    throw new Exception("Boxed array generate failed, values");
                if (o1[i].GetType() != o2[i].GetType())
                    throw new Exception("Boxed array generate failed, types");
            }

            long result = acc.Accelerate<long, long>(CILFac.Fac.Factorial, 10);
            if (result != CILFac.Fac.Factorial(10))
                throw new Exception("Failed to run fac");

            var bytesum = acc.Accelerate<byte[], byte>(CILArray.ArrayTest.sum, TestBytes);
            if (bytesum != CILArray.ArrayTest.sum(TestBytes))
                throw new Exception("Sum of bytes failed");

            var sbytesum = acc.Accelerate<sbyte[], sbyte>(CILArray.ArrayTest.sum, TestSBytes);
            if (sbytesum != CILArray.ArrayTest.sum(TestSBytes))
                throw new Exception("Sum of sbytes failed");

            var shortsum = acc.Accelerate<short[], short>(CILArray.ArrayTest.sum, TestShorts);
            if (shortsum != CILArray.ArrayTest.sum(TestShorts))
                throw new Exception("Sum of shorts failed");

            var ushortsum = acc.Accelerate<ushort[], ushort>(CILArray.ArrayTest.sum, TestUShorts);
            if (ushortsum != CILArray.ArrayTest.sum(TestUShorts))
                throw new Exception("Sum of ushorts failed");

            var intsum = acc.Accelerate<int[], int>(CILArray.ArrayTest.sum, TestInts);
            if (intsum != CILArray.ArrayTest.sum(TestInts))
                throw new Exception("Sum of ints failed");

            var uintsum = acc.Accelerate<uint[], uint>(CILArray.ArrayTest.sum, TestUInts);
            if (uintsum != CILArray.ArrayTest.sum(TestUInts))
                throw new Exception("Sum of uints failed");

            var longsum = acc.Accelerate<long[], long>(CILArray.ArrayTest.sum, TestLongs);
            if (longsum != CILArray.ArrayTest.sum(TestLongs))
                throw new Exception("Sum of longs failed");

            var ulongsum = acc.Accelerate<ulong[], ulong>(CILArray.ArrayTest.sum, TestULongs);
            if (ulongsum != CILArray.ArrayTest.sum(TestULongs))
                throw new Exception("Sum of ulongs failed");

            var floatsum = acc.Accelerate<float[], float>(CILArray.ArrayTest.sum, TestFloats);
            if (floatsum != CILArray.ArrayTest.sum(TestFloats))
                throw new Exception(string.Format("Sum of floats failed {0} vs {1}", (double)floatsum, (double)CILArray.ArrayTest.sum(TestFloats)));

            var doublesum = acc.Accelerate<double[], double>(CILArray.ArrayTest.sum, TestDoubles);
            if (doublesum != CILArray.ArrayTest.sum(TestDoubles))
                throw new Exception(string.Format("Sum of doubles failed {0} vs {1}", doublesum, CILArray.ArrayTest.sum(TestDoubles)));

            var outbytes = acc.Accelerate<byte[], byte, byte[]>(CILArray.ArrayTest.mult, TestBytes, 4);
            var cmpbytes = CILArray.ArrayTest.mult(TestBytes, 4);
            for (int i = 0; i < cmpbytes.Length; i++) if (cmpbytes[i] != outbytes[i]) throw new Exception("Error in byte multiply");

            var outsbytes = acc.Accelerate<sbyte[], sbyte, sbyte[]>(CILArray.ArrayTest.mult, TestSBytes, 4);
            var cmpsbytes = CILArray.ArrayTest.mult(TestSBytes, 4);
            for (int i = 0; i < cmpsbytes.Length; i++) if (cmpsbytes[i] != outsbytes[i]) throw new Exception("Error in sbyte multiply");

            var outshorts = acc.Accelerate<short[], short, short[]>(CILArray.ArrayTest.mult, TestShorts, 4);
            var cmpshorts = CILArray.ArrayTest.mult(TestShorts, 4);
            for (int i = 0; i < cmpshorts.Length; i++) if (cmpshorts[i] != outshorts[i]) throw new Exception("Error in short multiply");

            var outushorts = acc.Accelerate<ushort[], ushort, ushort[]>(CILArray.ArrayTest.mult, TestUShorts, 4);
            var cmpushorts = CILArray.ArrayTest.mult(TestUShorts, 4);
            for (int i = 0; i < cmpushorts.Length; i++) if (cmpushorts[i] != outushorts[i]) throw new Exception("Error in ushort multiply");

            var outints = acc.Accelerate<int[], int, int[]>(CILArray.ArrayTest.mult, TestInts, 4);
            var cmpints = CILArray.ArrayTest.mult(TestInts, 4);
            for (int i = 0; i < cmpints.Length; i++) if (cmpints[i] != outints[i]) throw new Exception("Error in int multiply");

            var outuints = acc.Accelerate<uint[], uint, uint[]>(CILArray.ArrayTest.mult, TestUInts, 4);
            var cmpuints = CILArray.ArrayTest.mult(TestUInts, 4);
            for (int i = 0; i < cmpuints.Length; i++) if (cmpuints[i] != outuints[i]) throw new Exception("Error in uints multiply");

            var outlongs = acc.Accelerate<long[], long, long[]>(CILArray.ArrayTest.mult, TestLongs, 4);
            var cmplongs = CILArray.ArrayTest.mult(TestLongs, 4);
            for (int i = 0; i < cmplongs.Length; i++) if (cmplongs[i] != outlongs[i]) throw new Exception("Error in long multiply");

            var outulongs = acc.Accelerate<ulong[], ulong, ulong[]>(CILArray.ArrayTest.mult, TestULongs, 4);
            var cmpulongs = CILArray.ArrayTest.mult(TestULongs, 4);
            for (int i = 0; i < cmpulongs.Length; i++) if (cmpulongs[i] != outulongs[i]) throw new Exception("Error in ulong multiply");

            var outfloats = acc.Accelerate<float[], float, float[]>(CILArray.ArrayTest.mult, TestFloats, 4);
            var cmpfloats = CILArray.ArrayTest.mult(TestFloats, 4);
            for (int i = 0; i < cmpfloats.Length; i++) if (cmpfloats[i] != outfloats[i]) throw new Exception("Error in float multiply");

            var outdoubles = acc.Accelerate<double[], double, double[]>(CILArray.ArrayTest.mult, TestDoubles, 4);
            var cmpdoubles = CILArray.ArrayTest.mult(TestDoubles, 4);
            for (int i = 0; i < cmpdoubles.Length; i++) if (cmpdoubles[i] != outdoubles[i]) throw new Exception("Error in double multiply");

            acc.Accelerate<byte[], byte[], byte[]>(CILArray.ArrayTest.add, TestBytes, TestBytes, outbytes);
            CILArray.ArrayTest.add(TestBytes, TestBytes, cmpbytes);
            for (int i = 0; i < cmpbytes.Length; i++) if (cmpbytes[i] != outbytes[i]) throw new Exception("Error in byte add");

            acc.Accelerate<sbyte[], sbyte[], sbyte[]>(CILArray.ArrayTest.add, TestSBytes, TestSBytes, outsbytes);
            CILArray.ArrayTest.add(TestSBytes, TestSBytes, cmpsbytes);
            for (int i = 0; i < cmpsbytes.Length; i++) if (cmpsbytes[i] != outsbytes[i]) throw new Exception("Error in sbyte add");

            acc.Accelerate<short[], short[], short[]>(CILArray.ArrayTest.add, TestShorts, TestShorts, outshorts);
            CILArray.ArrayTest.add(TestShorts, TestShorts, cmpshorts);
            for (int i = 0; i < cmpshorts.Length; i++) if (cmpshorts[i] != outshorts[i]) throw new Exception("Error in short add");

            acc.Accelerate<ushort[], ushort[], ushort[]>(CILArray.ArrayTest.add, TestUShorts, TestUShorts, outushorts);
            CILArray.ArrayTest.add(TestUShorts, TestUShorts, cmpushorts);
            for (int i = 0; i < cmpushorts.Length; i++) if (cmpushorts[i] != outushorts[i]) throw new Exception("Error in ushort add");

            acc.Accelerate<int[], int[], int[]>(CILArray.ArrayTest.add, TestInts, TestInts, outints);
            CILArray.ArrayTest.add(TestInts, TestInts, cmpints);
            for (int i = 0; i < cmpints.Length; i++) if (cmpints[i] != outints[i]) throw new Exception("Error in int add");

            acc.Accelerate<uint[], uint[], uint[]>(CILArray.ArrayTest.add, TestUInts, TestUInts, outuints);
            CILArray.ArrayTest.add(TestUInts, TestUInts, cmpuints);
            for (int i = 0; i < cmpuints.Length; i++) if (cmpuints[i] != outuints[i]) throw new Exception("Error in uint add");

            acc.Accelerate<long[], long[], long[]>(CILArray.ArrayTest.add, TestLongs, TestLongs, outlongs);
            CILArray.ArrayTest.add(TestLongs, TestLongs, cmplongs);
            for (int i = 0; i < cmplongs.Length; i++) if (cmplongs[i] != outlongs[i]) throw new Exception("Error in long add");

            acc.Accelerate<ulong[], ulong[], ulong[]>(CILArray.ArrayTest.add, TestULongs, TestULongs, outulongs);
            CILArray.ArrayTest.add(TestULongs, TestULongs, cmpulongs);
            for (int i = 0; i < cmpulongs.Length; i++) if (cmpulongs[i] != outulongs[i]) throw new Exception("Error in ulong add");

            acc.Accelerate<float[], float[], float[]>(CILArray.ArrayTest.add, TestFloats, TestFloats, outfloats);
            CILArray.ArrayTest.add(TestFloats, TestFloats, cmpfloats);
            for (int i = 0; i < cmpfloats.Length; i++) if (cmpfloats[i] != outfloats[i]) throw new Exception("Error in float add");

            acc.Accelerate<double[], double[], double[]>(CILArray.ArrayTest.add, TestDoubles, TestDoubles, outdoubles);
            CILArray.ArrayTest.add(TestDoubles, TestDoubles, cmpdoubles);
            for (int i = 0; i < cmpdoubles.Length; i++) if (cmpdoubles[i] != outdoubles[i]) throw new Exception("Error in double add");
        }
コード例 #5
0
ファイル: RegisterAllocator.cs プロジェクト: kenkendk/ac3il
        private void AssignFixedRegisters(List<int> usedRegisters, AccCIL.IR.MethodEntry method)
        {
            foreach (var i in method.FlatInstructionList)
            {
                switch (i.Instruction.OpCode.Code)
                {
                    case Mono.Cecil.Cil.Code.Ret:
                        AssignRegister(i, ABI_RETURN_REGISTER, usedRegisters, true);
                        break;
                    case Mono.Cecil.Cil.Code.Call:
                    case Mono.Cecil.Cil.Code.Calli:
                    case Mono.Cecil.Cil.Code.Callvirt:
                        AssignRegister(i, ABI_RETURN_REGISTER, usedRegisters, true);

                        //TODO: Add spill limit for arguments
                        for (int j = 0; j < i.Childnodes.Length; j++)
                            AssignRegister(i.Childnodes[j], ABI_FUNCTION_PARAMETER_REGISTER_START + j, usedRegisters, true);
                        break;

                    case Mono.Cecil.Cil.Code.Stloc_0:
                        AssignRegister(i.Childnodes[0], SPEJITCompiler._LV0, usedRegisters, true);
                        break;
                    case Mono.Cecil.Cil.Code.Stloc_1:
                        AssignRegister(i.Childnodes[0], SPEJITCompiler._LV0 + 1, usedRegisters, true);
                        break;
                    case Mono.Cecil.Cil.Code.Stloc_2:
                        AssignRegister(i.Childnodes[0], SPEJITCompiler._LV0 + 2, usedRegisters, true);
                        break;
                    case Mono.Cecil.Cil.Code.Stloc_3:
                        AssignRegister(i.Childnodes[0], SPEJITCompiler._LV0 + 3, usedRegisters, true);
                        break;
                    case Mono.Cecil.Cil.Code.Stloc_S:
                        AssignRegister(i.Childnodes[0], SPEJITCompiler._LV0 + ((Mono.Cecil.Cil.VariableReference)i.Instruction.Operand).Index, usedRegisters, true);
                        break;

                    case Mono.Cecil.Cil.Code.Ldloc_0:
                        AssignRegister(i, SPEJITCompiler._LV0, usedRegisters, false);
                        break;
                    case Mono.Cecil.Cil.Code.Ldloc_1:
                        AssignRegister(i, SPEJITCompiler._LV0 + 1, usedRegisters, false);
                        break;
                    case Mono.Cecil.Cil.Code.Ldloc_2:
                        AssignRegister(i, SPEJITCompiler._LV0 + 2, usedRegisters, false);
                        break;
                    case Mono.Cecil.Cil.Code.Ldloc_3:
                        AssignRegister(i, SPEJITCompiler._LV0 + 3, usedRegisters, false);
                        break;
                    case Mono.Cecil.Cil.Code.Ldloc_S:
                        AssignRegister(i, SPEJITCompiler._LV0 + ((Mono.Cecil.Cil.VariableReference)i.Instruction.Operand).Index, usedRegisters, false);
                        break;
                    case Mono.Cecil.Cil.Code.Ldarg_0:
                        AssignRegister(i, SPEJITCompiler._LV0 + method.Method.Body.Variables.Count, usedRegisters, false);
                        break;
                    case Mono.Cecil.Cil.Code.Ldarg_1:
                        AssignRegister(i, SPEJITCompiler._LV0 + method.Method.Body.Variables.Count + 1, usedRegisters, false);
                        break;
                    case Mono.Cecil.Cil.Code.Ldarg_2:
                        AssignRegister(i, SPEJITCompiler._LV0 + method.Method.Body.Variables.Count + 2, usedRegisters, false);
                        break;
                    case Mono.Cecil.Cil.Code.Ldarg_3:
                        AssignRegister(i, SPEJITCompiler._LV0 + method.Method.Body.Variables.Count + 3, usedRegisters, false);
                        break;
                    case Mono.Cecil.Cil.Code.Ldarg_S:
                    case Mono.Cecil.Cil.Code.Ldarg:
                        AssignRegister(i, SPEJITCompiler._LV0 + method.Method.Body.Variables.Count + method.Method.Parameters.IndexOf(((Mono.Cecil.ParameterDefinition)i.Instruction.Operand)), usedRegisters, false);
                        break;
                }
            }
        }
コード例 #6
0
ファイル: RegisterAllocator.cs プロジェクト: kenkendk/ac3il
        private void AssignRegister(AccCIL.IR.InstructionElement el, int register, List<int> usedRegisters, bool assignparent)
        {
            if (el == null || el.Register == null)
                return;

            el.Register.RegisterNumber = register;
            usedRegisters.Add(register);

            if (assignparent)
            {
                //Pass the assignment up
                while (el.Parent != null && el.Parent.Register != null && el.Parent.Register.RegisterNumber < 0)
                {
                    el.Parent.Register.RegisterNumber = register;
                    el = el.Parent;
                }
            }
        }