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