コード例 #1
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void LdElemA(EmitFuncObj _)
 {
     var index = _.Stack.Pop();
     var array = _.Stack.Pop();
     var idx = _.Builder.Element(array, new[] { index });
     _.Stack.Push(idx);
 }
コード例 #2
0
 private static void Call(EmitFuncObj _)
 {
     var method = (MethodInfo)_.Argument;
     var args = method.GetParameters().Select(x => _.Stack.Pop()).Reverse().ToArray();
     var result = _.Builder.Call(EmitFunction(_.Context, _.Module, method), args);
     if (result.Type.StructuralEquals(Type.GetVoid(_.Context)) == false)
         _.Stack.Push(result);
 }
コード例 #3
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void LdVar(EmitFuncObj _, Value[] values, int index)
 {
     _.Stack.Push(_.Builder.Load(values[index]));
 }
コード例 #4
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void StVar(EmitFuncObj _, Value[] values, int index)
 {
     _.Builder.Store(_.Stack.Pop(), values[index]);
 }
コード例 #5
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
        private static Function EmitFunction(Module module, MethodBase method)
        {
            var methodInfo = method as MethodInfo;
            var methodConstructor = method as ConstructorInfo;
            var declaringType = method.DeclaringType;
            if (methodInfo == null && methodConstructor == null)
                throw new CudaSharpException("Unknown MethodBase type " + method.GetType().FullName);
            if (declaringType == null)
                throw new CudaSharpException("Could not find the declaring type of " + method.Name.StripNameToValidPtx());

            var parameters = method.GetParameters().Select(p => p.ParameterType);
            if (methodConstructor != null)
                parameters = new[] { declaringType.MakeByRefType() }.Concat(parameters);
            if (methodInfo != null && methodInfo.IsStatic == false)
            {
                if (declaringType.IsValueType == false)
                    throw new CudaSharpException("Cannot compile object instance methods (did you forget to mark the method as static?)");
                parameters = new[] { declaringType.MakeByRefType() }.Concat(parameters);
            }
            var llvmParameters =
                parameters.Select(t => ConvertType(module, t)).ToArray();
            var funcType = new FunctionType(ConvertType(module, methodInfo == null ? typeof(void) : methodInfo.ReturnType), llvmParameters);

            var intrinsic = method.GetCustomAttribute<Gpu.BuiltinAttribute>();
            if (intrinsic != null)
            {
                var name = intrinsic.Intrinsic;
                var preExisting = module.GetFunction(name);
                if (preExisting != null)
                    return preExisting;
                return module.CreateFunction(name, funcType);
            }

            var function = module.CreateFunction(methodConstructor == null ? method.Name.StripNameToValidPtx() : declaringType.Name.StripNameToValidPtx() + "_ctor", funcType);

            var block = new Block("entry", module.Context, function);
            var writer = new InstructionBuilder(module.Context, block);

            var opcodes = method.Disassemble().ToList();
            FindBranchTargets(opcodes, module.Context, function);

            var body = method.GetMethodBody();
            var efo = new EmitFuncObj(module, function, body, writer, null, new Stack<Value>(),
                body == null ? null : new Value[body.LocalVariables.Count], new Value[llvmParameters.Length]);

            PrintHeader(efo);
            foreach (var opcode in opcodes)
            {
                if (EmitFunctions.ContainsKey(opcode.Opcode) == false)
                    throw new CudaSharpException("Unsupported CIL instruction " + opcode.Opcode);
                var func = EmitFunctions[opcode.Opcode];
                efo.Argument = opcode.Parameter;
                func(efo);
            }

            return function;
        }
コード例 #6
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void Br(EmitFuncObj _)
 {
     _.Builder.GoTo((Block)_.Argument);
     _.Builder = null;
 }
コード例 #7
0
 private static void StVar(EmitFuncObj _, Value[] values, int index)
 {
     var pop = _.Stack.Pop();
     if (values[index] == null)
         values[index] = _.Builder.StackAlloc(pop.Type);
     _.Builder.Store(pop, values[index]);
 }
コード例 #8
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void CleUn(EmitFuncObj _)
 {
     FlipTopTwoStack(_);
     _.Stack.Push(_.Builder.Compare(IntegerComparison.UnsignedLessEqual, _.Stack.Pop(), _.Stack.Pop()));
 }
コード例 #9
0
 private static void Cle(EmitFuncObj _)
 {
     _.Stack.Push(_.Builder.Compare(IntegerComparison.SignedLessEqual, _.Stack.Pop(), _.Stack.Pop()));
 }
コード例 #10
0
 private static void LdVar(EmitFuncObj _, Value[] values, int index, bool isParameter)
 {
     if (values[index] == null)
     {
         if (!isParameter)
             throw new Exception("Uninitialized variable at index " + index);
         var arg = _.Function[index];
         values[index] = _.Builder.StackAlloc(_.Function[index].Type);
         _.Builder.Store(arg, values[index]);
         _.Stack.Push(arg);
     }
     else
     {
         var load = _.Builder.Load(values[index]);
         _.Stack.Push(load);
     }
 }
コード例 #11
0
 private static void CltUn(EmitFuncObj _)
 {
     _.Stack.Push(_.Builder.Compare(IntegerComparison.UnsignedLess, _.Stack.Pop(), _.Stack.Pop()));
 }
コード例 #12
0
 private static void CgeUn(EmitFuncObj _)
 {
     _.Stack.Push(_.Builder.Compare(IntegerComparison.UnsignedGreaterEqual, _.Stack.Pop(), _.Stack.Pop()));
 }
コード例 #13
0
 private static void Cgt(EmitFuncObj _)
 {
     _.Stack.Push(_.Builder.Compare(IntegerComparison.SignedGreater, _.Stack.Pop(), _.Stack.Pop()));
 }
コード例 #14
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void Ceq(EmitFuncObj _)
 {
     FlipTopTwoStack(_);
     _.Stack.Push(_.Builder.Compare(IntegerComparison.Equal, PopNoBool(_), PopNoBool(_)));
 }
コード例 #15
0
 private static void ConvertNum(EmitFuncObj _, Type target, bool integerSignedness)
 {
     //var value = _.Stack.Pop();
     //var valueType = value.Type;
     //if (valueType is IntegerType && target is FloatType)
     //{
     //    value = _.Builder.
     //}
 }
コード例 #16
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void Cge(EmitFuncObj _)
 {
     FlipTopTwoStack(_);
     _.Stack.Push(_.Builder.Compare(IntegerComparison.SignedGreaterEqual, _.Stack.Pop(), _.Stack.Pop()));
 }
コード例 #17
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void PrintHeader(EmitFuncObj _)
 {
     for (var index = 0; index < _.Parameters.Length; index++)
     {
         _.Parameters[index] = _.Builder.StackAlloc(_.Function[index].Type);
         _.Builder.Store(_.Function[index], _.Parameters[index]);
     }
     for (var index = 0; index < _.Locals.Length; index++)
         _.Locals[index] = _.Builder.StackAlloc(ConvertType(_.Module, _.CilMethod.LocalVariables[index].LocalType));
 }
コード例 #18
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static Value PopNoBool(EmitFuncObj _)
 {
     var popped = _.Stack.Pop();
     if (popped.Type.StructuralEquals(IntegerType.Get(_.Context, 1)))
         popped = _.Builder.ZeroExtend(popped, IntegerType.GetInt32(_.Context));
     return popped;
 }
コード例 #19
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void Ldfld(EmitFuncObj _)
 {
     var obj = _.Stack.Pop();
     if (obj.Type is PointerType)
         _.Stack.Push(_.Builder.Load(ElementPointer(_, obj, FieldIndex((FieldInfo)_.Argument))));
     else
         _.Stack.Push(_.Builder.Extract(obj, FieldIndex((FieldInfo)_.Argument)));
 }
コード例 #20
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void Nop(EmitFuncObj _)
 {
     var block = (Block)_.Argument;
     if (block == null)
         return;
     if (_.Builder != null)
         _.Builder.GoTo(block);
     _.Builder = new InstructionBuilder(_.Context, block);
 }
コード例 #21
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static Value ElementPointer(EmitFuncObj _, Value pointer, int index)
 {
     var zeroConstant = IntegerType.GetInt32(_.Context).Constant(0, false);
     var indexConstant = IntegerType.GetInt32(_.Context).Constant((ulong)index, false);
     return _.Builder.Element(pointer, new Value[] { zeroConstant, indexConstant }); // guarenteed to be pointer type
 }
コード例 #22
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void BrCond(EmitFuncObj _, bool isTrue)
 {
     var tuple = (Tuple<Block, Block>)_.Argument;
     var cont = tuple.Item1;
     var target = tuple.Item2;
     _.Builder.If(_.Stack.Pop(), isTrue ? target : cont, isTrue ? cont : target);
     _.Builder = new InstructionBuilder(_.Context, cont);
 }
コード例 #23
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
        private static void NewobjPreConstructor(EmitFuncObj _)
        {
            var stackalloca = _.Builder.StackAlloc(ConvertType(_.Module, ((ConstructorInfo)_.Argument).DeclaringType));

            var altstack = new Stack<Value>();
            var paramLength = ((MethodBase)_.Argument).GetParameters().Length;

            for (var i = 0; i < paramLength; i++)
                altstack.Push(_.Stack.Pop());

            _.Stack.Push(stackalloca);

            for (var i = 0; i < paramLength; i++)
                _.Stack.Push(altstack.Pop());
        }
コード例 #24
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void LdVarA(EmitFuncObj _, Value[] values, int index)
 {
     _.Stack.Push(values[index]);
 }
コード例 #25
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void Call(EmitFuncObj _)
 {
     var method = (MethodBase)_.Argument;
     var count = method.GetParameters().Length;
     if (method is ConstructorInfo || method.IsStatic == false)
         count++;
     var args = Enumerable.Range(0, count).Select(x => _.Stack.Pop()).Reverse().ToArray();
     var result = _.Builder.Call(EmitFunction(_.Module, method), args);
     if (result.Type.StructuralEquals(Type.GetVoid(_.Context)) == false)
         _.Stack.Push(result);
     else if (method is ConstructorInfo)
         _.Stack.Push(_.Builder.Load(args[0]));
 }
コード例 #26
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void StElem(EmitFuncObj _)
 {
     var value = _.Stack.Pop();
     var index = _.Stack.Pop();
     var array = _.Stack.Pop();
     var idx = _.Builder.Element(array, new[] { index });
     _.Builder.Store(value, idx);
 }
コード例 #27
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void FlipTopTwoStack(EmitFuncObj _)
 {
     var top = _.Stack.Pop();
     var bottom = _.Stack.Pop();
     _.Stack.Push(top);
     _.Stack.Push(bottom);
 }
コード例 #28
0
ファイル: Translator.cs プロジェクト: rabbitsmith/CudaSharp
 private static void ConvertNum(EmitFuncObj _, Type target, bool integerSignedness)
 {
     var value = _.Stack.Pop();
     var valueType = value.Type;
     if (valueType is IntegerType && target is FloatType)
     {
         if (integerSignedness)
             value = _.Builder.SignedIntToFloat(value, target);
         else
             value = _.Builder.UnsignedIntToFloat(value, target);
     }
     else if (valueType is FloatType && target is IntegerType)
     {
         if (integerSignedness)
             value = _.Builder.FloatToSignedInt(value, target);
         else
             value = _.Builder.FloatToUnsignedInt(value, target);
     }
     else if (valueType is IntegerType && target is IntegerType)
     {
         var valueInt = (IntegerType) valueType;
         var targetInt = (IntegerType) target;
         if (valueInt.Width > targetInt.Width)
             value = _.Builder.Trunc(value, target);
         else if (integerSignedness)
             value = _.Builder.SignExtend(value, target);
         else
             value = _.Builder.ZeroExtend(value, target);
     }
     else
     {
         throw new CudaSharpException(string.Format("Cannot convert {0} to {1}", valueType, target));
     }
     _.Stack.Push(value);
 }
コード例 #29
0
        private static Function EmitFunction(Context context, Module module, MethodInfo method)
        {
            var funcType = new FunctionType(ConvertType(context, method.ReturnType), AnalyzeArguments(context, method.GetParameters()));

            var intrinsic = method.GetCustomAttribute<Gpu.BuiltinAttribute>();
            if (intrinsic != null)
            {
                var name = intrinsic.Intrinsic;
                var preExisting = module.GetFunction(name);
                if (preExisting != null)
                    return preExisting;
                return module.CreateFunction(name, funcType);
            }

            var function = module.CreateFunction(method.Name, funcType);

            var block = new Block("entry", context, function);
            var writer = new InstructionBuilder(context, block);

            var opcodes = method.Decompile().ToList();
            FindBranchTargets(opcodes, context, function);

            var body = method.GetMethodBody();
            var efo = new EmitFuncObj(context, module, function, writer, null, new Stack<Value>(),
                body == null ? null : new Value[body.LocalVariables.Count], new Value[method.GetParameters().Length]);

            foreach (var opcode in opcodes)
            {
                if (EmitFunctions.ContainsKey(opcode.Opcode) == false)
                    throw new Exception("Unsupported CIL instruction " + opcode.Opcode);
                var func = EmitFunctions[opcode.Opcode];
                efo.Argument = opcode.Parameter;
                func(efo);
            }

            return function;
        }