/// <summary>
        /// Creates the System.String::get_Chars(int32) function.
        /// </summary>
        /// <param name="builder">The builder.</param>
        private void createStringGetCharsFunction(BuilderRef builder)
        {
            const string funcName = "System_Char_System_String_get_Chars_System_Int32";

            // Create function and set linkage.
            TypeRef  type = LLVM.FunctionType(TypeHelper.Int8, new TypeRef[] { TypeHelper.String, TypeHelper.Int32 }, false);
            ValueRef func = LLVM.AddFunction(mCompiler.Module, funcName, type);

            LLVM.SetLinkage(func, Linkage.LinkOnceAnyLinkage);
            LLVM.AddAttributeAtIndex(func, (uint)LLVM.AttributeFunctionIndex, LLVM.CreateEnumAttribute(mCompiler.ModuleContext, LLVM.GetEnumAttributeKindForName("alwaysinline", 12), 1));

            // Arguments.
            ValueRef str   = LLVM.GetParam(func, 0);
            ValueRef index = LLVM.GetParam(func, 1);

            // Create function body.
            BasicBlockRef entry = LLVM.AppendBasicBlock(func, string.Empty);

            LLVM.PositionBuilderAtEnd(builder, entry);
            ValueRef ch        = LLVM.BuildGEP(builder, str, new ValueRef[] { index }, "charptr");
            ValueRef returnVal = LLVM.BuildLoad(builder, ch, "character");

            LLVM.BuildRet(builder, returnVal);

            mCompiler.Lookup.AddFunction(funcName, func);
        }
Beispiel #2
0
        /// <summary>
        /// Emits a Ldind instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            Code         code    = instruction.OpCode.Code;
            StackElement pointer = context.CurrentStack.Pop();

            ValueRef ptr     = pointer.Value;
            TypeRef  ptrType = LLVM.PointerType(TypeHelper.GetTypeRefFromStOrLdind(code), 0);

            if (pointer.Type != ptrType)
            {
                CastHelper.HelpIntAndPtrCast(builder, ref ptr, ref pointer.Type, ptrType, "ldindcast");
            }

            ValueRef res = LLVM.BuildLoad(builder, ptr, "elem");

            // Some need to be pushed as an int32 on the stack.
            if (code == Code.Ldind_I1 || code == Code.Ldind_I2 || code == Code.Ldind_I4 ||
                code == Code.Ldind_U1 || code == Code.Ldind_U2 || code == Code.Ldind_U4)
            {
                res = LLVM.BuildIntCast(builder, res, TypeHelper.Int32, "tmp");
            }

            TypeRef type = LLVM.TypeOf(res);

            context.CurrentStack.Push(new StackElement(res, TypeHelper.GetBasicTypeFromTypeRef(type), type));
        }
        /// <summary>
        /// Compiles the builtin runtime functions.
        /// </summary>
        public void Compile()
        {
            BuilderRef builder = LLVM.CreateBuilderInContext(mCompiler.ModuleContext);

            createStringGetCharsFunction(builder);
            LLVM.DisposeBuilder(builder);
        }
Beispiel #4
0
        /// <summary>
        /// Emits a rem instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement value2 = context.CurrentStack.Pop();
            StackElement value1 = context.CurrentStack.Pop();

            if (TypeHelper.IsFloatingPoint(value1) || TypeHelper.IsFloatingPoint(value2))
            {
                ValueRef result = LLVM.BuildFRem(builder, value1.Value, value2.Value, "remfp");
                context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type));
            }
            else
            {
                CastHelper.HelpIntCast(builder, ref value1, ref value2);
                ValueRef result;

                if (instruction.OpCode.Code == Code.Rem)
                {
                    result = LLVM.BuildSRem(builder, value1.Value, value2.Value, "remsi");
                }
                else /* Rem_Un */
                {
                    result = LLVM.BuildURem(builder, value1.Value, value2.Value, "remui");
                }

                context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type));
            }
        }
Beispiel #5
0
        /// <summary>
        /// Emits a stloc instruction
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            Code code = instruction.OpCode.Code;

            int index;

            if (code >= Code.Stloc_0 && code <= Code.Stloc_3)
            {
                index = instruction.OpCode.Code - Code.Stloc_0;
            }
            else
            {
                VariableDefinition def = (VariableDefinition)instruction.Operand;
                index = def.Index;
            }

            StackElement element  = context.CurrentStack.Pop();
            ValueRef     data     = element.Value;
            TypeRef      destType = context.LocalTypes[index];

            // Possible cast needed.
            if (element.Type != destType)
            {
                CastHelper.HelpIntAndPtrCast(builder, ref data, ref element.Type, destType, "stloccast");
            }

            LLVM.BuildStore(builder, data, context.LocalValues[index]);
        }
Beispiel #6
0
        /// <summary>
        /// Emits a ldfld instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement   obj   = context.CurrentStack.Pop();
            FieldReference field = (FieldReference)instruction.Operand;

            uint index = context.Compiler.Lookup.GetFieldIndex(field);

            // Create pointer if not yet a pointer.
            if (obj.ILType.IsValueType && !obj.ILType.IsPointer)
            {
                ValueRef objPtr = LLVM.BuildAlloca(builder, obj.Type, "objptr");
                LLVM.BuildStore(builder, obj.Value, objPtr);
                obj.Value = objPtr;
            }

            ValueRef ptr    = LLVM.BuildInBoundsGEP(builder, obj.Value, new ValueRef[] { LLVM.ConstInt(TypeHelper.Int32, 0, false), LLVM.ConstInt(TypeHelper.Int32, index, false) }, "field");
            ValueRef result = LLVM.BuildLoad(builder, ptr, "field");

            if (instruction.HasPrefix(Code.Volatile))
            {
                LLVM.SetVolatile(result, true);
            }

            context.CurrentStack.Push(new StackElement(result, field.FieldType));
        }
Beispiel #7
0
        /// <summary>
        /// Emits a stfld instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement   value = context.CurrentStack.Pop();
            StackElement   obj   = context.CurrentStack.Pop();
            FieldReference field = (FieldReference)instruction.Operand;

            uint index = context.Compiler.Lookup.GetFieldIndex(field);

            ValueRef ptr = LLVM.BuildInBoundsGEP(builder, obj.Value, new ValueRef[] { LLVM.ConstInt(TypeHelper.Int32, 0, false), LLVM.ConstInt(TypeHelper.Int32, index, false) }, "field");

            // Possible cast needed.
            TypeRef destType = TypeHelper.GetTypeRefFromType(field.FieldType);

            if (value.Type != destType)
            {
                CastHelper.HelpIntAndPtrCast(builder, ref value.Value, ref value.Type, destType, "stfldcast");
            }

            ValueRef store = LLVM.BuildStore(builder, value.Value, ptr);

            if (instruction.HasPrefix(Code.Volatile))
            {
                LLVM.SetVolatile(store, true);
            }
        }
Beispiel #8
0
        /// <summary>
        /// Emits a compare instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement value2 = context.CurrentStack.Pop();
            StackElement value1 = context.CurrentStack.Pop();
            ValueRef     ret;

            if (TypeHelper.IsFloatingPoint(value2) || TypeHelper.IsFloatingPoint(value1))
            {
                ret = LLVM.BuildFCmp(builder, PredicateHelper.GetRealPredicateFromCode(instruction.OpCode.Code), value1.Value, value2.Value, "fcmp");
            }
            else
            {
                if (value2.Type != value1.Type)
                {
                    ValueRef tmp = LLVM.BuildIntCast(builder, value2.Value, value1.Type, "tmp");
                    ret = LLVM.BuildICmp(builder, PredicateHelper.GetIntPredicateFromCode(instruction.OpCode.Code), value1.Value, tmp, "icmp");
                }
                else
                {
                    ret = LLVM.BuildICmp(builder, PredicateHelper.GetIntPredicateFromCode(instruction.OpCode.Code), value1.Value, value2.Value, "icmp");
                }
            }

            context.CurrentStack.Push(new StackElement(ret, typeof(bool).GetTypeReference(), TypeHelper.Boolean));
        }
Beispiel #9
0
        /// <summary>
        /// Emits a not instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement value  = context.CurrentStack.Pop();
            ValueRef     result = LLVM.BuildNot(builder, value.Value, "not");

            context.CurrentStack.Push(new StackElement(result, value.ILType, value.Type));
        }
Beispiel #10
0
        /// <summary>
        /// Prepares the arguments.
        /// </summary>
        private void prepareArguments()
        {
            BuilderRef builder = LLVM.CreateBuilderInContext(Compiler.ModuleContext);

            LLVM.PositionBuilderAtEnd(builder, Branches[0].Block);

            uint count = LLVM.CountParams(Function);

            ArgumentValues  = new ValueRef[count];
            ArgumentILTypes = new TypeReference[count];

            // It is possible that the first argument is an instance reference.
            int offset = (Method.HasThis) ? 1 : 0;

            for (int i = offset; i < count; i++)
            {
                ValueRef param = LLVM.GetParam(Function, (uint)i);
                ArgumentILTypes[i] = Method.Parameters[i - offset].ParameterType;
                ArgumentValues[i]  = LLVM.BuildAlloca(builder, LLVM.TypeOf(param), "arg" + i);
                LLVM.BuildStore(builder, param, ArgumentValues[i]);
            }

            // Instance reference.
            if (Method.HasThis)
            {
                ValueRef param = LLVM.GetParam(Function, 0);
                ArgumentILTypes[0] = new PointerType(Method.DeclaringType);
                ArgumentValues[0]  = LLVM.BuildAlloca(builder, LLVM.TypeOf(param), "arginstance");
                LLVM.BuildStore(builder, param, ArgumentValues[0]);
            }

            LLVM.DisposeBuilder(builder);
        }
Beispiel #11
0
        /// <summary>
        /// Emits a stind instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement value   = context.CurrentStack.Pop();
            StackElement pointer = context.CurrentStack.Pop();

            ValueRef val         = value.Value;
            ValueRef ptr         = pointer.Value;
            TypeRef  destType    = TypeHelper.GetTypeRefFromStOrLdind(instruction.OpCode.Code);
            TypeRef  destPtrType = LLVM.PointerType(destType, 0);

            if (destPtrType != pointer.Type)
            {
                // There is no instruction for a Stind to store a boolean, so we need to check manually.
                if (pointer.Type == LLVM.PointerType(TypeHelper.Boolean, 0))
                {
                    destType = TypeHelper.Boolean;
                }
                // We treat char as 8-bit.
                else if (pointer.Type == LLVM.PointerType(TypeHelper.Int8, 0))
                {
                    destType = TypeHelper.Int8;
                }

                val = LLVM.BuildIntCast(builder, val, destType, "stindcast");

                // If the pointer is a native int, convert to a pointer of the appropriate type.
                if (pointer.Type == TypeHelper.NativeIntType)
                {
                    ptr = LLVM.BuildIntToPtr(builder, ptr, destPtrType, "int2ptr");
                }
            }

            LLVM.BuildStore(builder, val, ptr);
        }
Beispiel #12
0
        /// <summary>
        /// Emits an add instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement value2 = context.CurrentStack.Pop();
            StackElement value1 = context.CurrentStack.Pop();

            if (TypeHelper.IsFloatingPoint(value1) || TypeHelper.IsFloatingPoint(value2))
            {
                ValueRef result = LLVM.BuildFAdd(builder, value1.Value, value2.Value, "addfp");
                context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type));
            }
            else
            {
                bool isPtrVal1, isPtrVal2;
                CastHelper.HelpPossiblePtrCast(builder, ref value1, ref value2, out isPtrVal1, out isPtrVal2, "addcast");

                // If one of the two values is a pointer, then the result will be a pointer as well.
                if (isPtrVal1 || isPtrVal2)
                {
                    ValueRef      result          = LLVM.BuildAdd(builder, value1.Value, value2.Value, "addptr");
                    TypeRef       resultingType   = (isPtrVal1 ? value1.Type : value2.Type);
                    TypeReference resultingILType = (isPtrVal1 ? value1.ILType : value2.ILType);
                    ValueRef      ptr             = LLVM.BuildIntToPtr(builder, result, resultingType, "ptr");
                    context.CurrentStack.Push(new StackElement(ptr, resultingILType, resultingType));
                }
                // Cast to different int size.
                else
                {
                    CastHelper.HelpIntCast(builder, ref value1, ref value2);
                    ValueRef result = LLVM.BuildAdd(builder, value1.Value, value2.Value, "addi");
                    context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type));
                }
            }
        }
Beispiel #13
0
        /// <summary>
        /// Helps with the pointer casting so that both values are of the same type.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <param name="value1">The first value.</param>
        /// <param name="value2">The second value.</param>
        /// <param name="isPtrVal1">If the first value was a pointer.</param>
        /// <param name="isPtrVal2">If the second value was a pointer.</param>
        /// <param name="name">The name of the cast.</param>
        public static void HelpPossiblePtrCast(BuilderRef builder, ref StackElement value1, ref StackElement value2, out bool isPtrVal1, out bool isPtrVal2, string name)
        {
            isPtrVal1 = TypeHelper.IsPointer(value1);
            isPtrVal2 = TypeHelper.IsPointer(value2);

            if (isPtrVal1 || isPtrVal2)
            {
                if (isPtrVal1)
                {
                    value1.Value = LLVM.BuildPtrToInt(builder, value1.Value, TypeHelper.NativeIntType, "tmp");
                }
                else
                {
                    value1.Value = LLVM.BuildIntCast(builder, value1.Value, TypeHelper.NativeIntType, "tmp");
                }

                if (isPtrVal2)
                {
                    value2.Value = LLVM.BuildPtrToInt(builder, value2.Value, TypeHelper.NativeIntType, "tmp");
                }
                else
                {
                    value2.Value = LLVM.BuildIntCast(builder, value2.Value, TypeHelper.NativeIntType, "tmp");
                }
            }
        }
Beispiel #14
0
        /// <summary>
        /// Helps int and ptr casting to a destination type.
        /// </summary>
        /// <param name="builder">The builder.</param>
        /// <param name="data">The data (int or pointer).</param>
        /// <param name="dataType">The data type.</param>
        /// <param name="destType">The destination type.</param>
        /// <param name="name">The name of the cast.</param>
        public static void HelpIntAndPtrCast(BuilderRef builder, ref ValueRef data, ref TypeRef dataType, TypeRef destType, string name)
        {
            // Two cases: int to different size, or int to pointer.
            TypeKind kind = LLVM.GetTypeKind(destType);

            // Convert to pointer.
            if (kind == TypeKind.PointerTypeKind)
            {
                // Two cases: pointer to pointer, or int to ptr.
                if (LLVM.GetTypeKind(dataType) == TypeKind.PointerTypeKind)
                {
                    data = LLVM.BuildPointerCast(builder, data, destType, name);
                }
                else
                {
                    data = LLVM.BuildIntToPtr(builder, data, destType, name);
                }
            }
            // Convert to int of different size.
            else
            {
                data = LLVM.BuildIntCast(builder, data, destType, name);
            }

            dataType = destType;
        }
Beispiel #15
0
        /// <summary>
        /// Emits a Ldc_I4 instruction.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            ValueRef result;

            Code code = instruction.OpCode.Code;

            if (code >= Code.Ldc_I4_0 && code <= Code.Ldc_I4_8)
            {
                result = LLVM.ConstInt(TypeHelper.Int32, (ulong)(instruction.OpCode.Code - Code.Ldc_I4_0), true);
            }
            else if (code == Code.Ldc_I4_M1)
            {
                unchecked
                {
                    result = LLVM.ConstInt(TypeHelper.Int32, (uint)-1, true);
                }
            }
            else
            {
                if (instruction.Operand is sbyte)
                {
                    result = LLVM.ConstInt(TypeHelper.Int32, (ulong)(sbyte)instruction.Operand, true);
                }
                else
                {
                    unchecked
                    {
                        result = LLVM.ConstInt(TypeHelper.Int32, (uint)(int)instruction.Operand, true);
                    }
                }
            }

            context.CurrentStack.Push(new StackElement(result, typeof(int).GetTypeReference(), TypeHelper.Int32));
        }
Beispiel #16
0
 /// <summary>
 /// Updates the stack of this branch using the incoming source branches.
 /// </summary>
 /// <param name="builder">The builder.</param>
 public void UpdateStack(BuilderRef builder)
 {
     foreach (Branch source in Sources)
     {
         Stack.Update(builder, source.Stack, source.Block, Block, References);
     }
 }
Beispiel #17
0
        /// <summary>
        /// Emits a localloc instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement size   = context.CurrentStack.Pop();
            ValueRef     result = LLVM.BuildArrayAlloca(builder, TypeHelper.Int8, size.Value, "stackalloc");

            context.CurrentStack.Push(new StackElement(result, typeof(byte[]).GetTypeReference()));
        }
Beispiel #18
0
        /// <summary>
        /// Emits a ldftn instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            MethodDefinition method  = (MethodDefinition)instruction.Operand;
            ValueRef         result  = LLVM.BuildIntToPtr(builder, context.Compiler.Lookup.GetFunction(NameHelper.CreateMethodName(method)).Value, TypeHelper.NativeIntType, "ldftn");
            StackElement     element = new StackElement(result, typeof(IntPtr).GetTypeReference(), TypeHelper.NativeIntType);

            context.CurrentStack.Push(element);
        }
Beispiel #19
0
        /// <summary>
        /// Emits a ldloca instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            Code code = instruction.OpCode.Code;

            VariableDefinition def = (VariableDefinition)instruction.Operand;
            int index = def.Index;

            context.CurrentStack.Push(new StackElement(context.LocalValues[index], new PointerType(context.LocalILTypes[index])));
        }
Beispiel #20
0
        /// <summary>
        /// Emits a ldelema instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement index = context.CurrentStack.Pop();
            StackElement array = context.CurrentStack.Pop();

            ValueRef gep = LLVM.BuildGEP(builder, array.Value, new ValueRef[] { index.Value }, "arrayelemptr");

            context.CurrentStack.Push(new StackElement(gep, array.ILType, array.Type));
        }
Beispiel #21
0
 /// <summary>
 /// Helps with the int casting so that both values are of the same type.
 /// </summary>
 /// <param name="builder">The builder.</param>
 /// <param name="value1">The first value.</param>
 /// <param name="value2">The second value.</param>
 public static void HelpIntCast(BuilderRef builder, ref StackElement value1, ref StackElement value2)
 {
     if (value1.Type != value2.Type)
     {
         value2.Value  = LLVM.BuildIntCast(builder, value2.Value, value1.Type, "tmpintcast");
         value2.Type   = value1.Type;
         value2.ILType = value1.ILType;
     }
 }
Beispiel #22
0
        public void TestORC()
        {
            LLVM.InitializeAllTargets();
            LLVM.InitializeAllTargetMCs();
            LLVM.InitializeAllTargetInfos();
            LLVM.InitializeAllAsmPrinters();

            // See http://www.doof.me.uk/2017/05/11/using-orc-with-llvms-c-api/
            ModuleRef mod = LLVM.ModuleCreateWithName("LLVMSharpIntro");

            TypeRef[]     param_types = { LLVM.Int32Type(), LLVM.Int32Type() };
            TypeRef       ret_type    = LLVM.FunctionType(LLVM.Int32Type(), param_types, false);
            ValueRef      sum         = LLVM.AddFunction(mod, "sum", ret_type);
            BasicBlockRef entry       = LLVM.AppendBasicBlock(sum, "entry");
            BuilderRef    builder     = LLVM.CreateBuilder();

            LLVM.PositionBuilderAtEnd(builder, entry);
            ValueRef tmp = LLVM.BuildAdd(builder, LLVM.GetParam(sum, 0), LLVM.GetParam(sum, 1), "tmp");

            LLVM.BuildRet(builder, tmp);
            MyString the_error = new MyString();

            LLVM.VerifyModule(mod, VerifierFailureAction.AbortProcessAction, the_error);

            //LLVM.DisposeMessage(error);
            TargetRef t2;
            string    tr2      = LLVM.GetDefaultTargetTriple();
            var       b        = LLVM.GetTargetFromTriple(tr2, out t2, the_error);
            string    triple   = "";
            string    cpu      = "";
            string    features = "";

            TargetMachineRef tmr = LLVM.CreateTargetMachine(t2, tr2, cpu, features,
                                                            CodeGenOptLevel.CodeGenLevelDefault,
                                                            RelocMode.RelocDefault,
                                                            CodeModel.CodeModelDefault);

            OrcJITStackRef ojsr = LLVM.OrcCreateInstance(tmr);
            MyString       ms   = new MyString();

            LLVM.OrcGetMangledSymbol(ojsr, ms, "sum");
            IntPtr ctx = IntPtr.Zero;

            SharedModuleRef smr       = LLVM.OrcMakeSharedModule(mod);
            OrcErrorCode    xx        = LLVM.OrcAddLazilyCompiledIR(ojsr, out uint omh, smr, null, ctx);
            OrcErrorCode    p         = LLVM.OrcGetSymbolAddress(ojsr, out IntPtr RetAddr, "sum");
            Add             addMethod = (Add)Marshal.GetDelegateForFunctionPointer(RetAddr, typeof(Add));
            int             result    = addMethod(10, 10);

            Console.WriteLine("Result of sum is: " + result);
            if (result != 20)
            {
                throw new Exception("Failed.");
            }
            LLVM.DumpModule(mod);
            LLVM.DisposeBuilder(builder);
        }
Beispiel #23
0
 /// <summary>
 /// Emits a Ldc_I8 instruction.
 /// </summary>
 /// <param name="context">The context.</param>
 /// <param name="builder">The builder.</param>
 public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
 {
     TypeRef type = TypeHelper.Int64;
     unchecked
     {
         ValueRef result = LLVM.ConstInt(type, (ulong)(long)instruction.Operand, true);
         context.CurrentStack.Push(new StackElement(result, typeof(long).GetTypeReference(), type));
     }
 }
Beispiel #24
0
        /// <summary>
        /// Emits an initobj instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement  valueTypeAddress = context.CurrentStack.Pop();
            TypeReference type             = (TypeReference)instruction.Operand;
            TypeRef       typeRef          = context.Compiler.Lookup.GetTypeRef(type);

            // We clear this using memset.
            CastHelper.HelpIntAndPtrCast(builder, ref valueTypeAddress.Value, ref valueTypeAddress.Type, TypeHelper.VoidPtr, "initobjcast");
            LLVM.BuildCall(builder, RuntimeHelper.Memset, new ValueRef[] { valueTypeAddress.Value, LLVM.ConstNull(TypeHelper.Int32), LLVM.SizeOf(typeRef) }, string.Empty);
        }
Beispiel #25
0
        /// <summary>
        /// Emits an shr_un instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement value2 = context.CurrentStack.Pop();
            StackElement value1 = context.CurrentStack.Pop();

            CastHelper.HelpIntCast(builder, ref value1, ref value2);
            ValueRef result = LLVM.BuildLShr(builder, value1.Value, value2.Value, "shrun");

            context.CurrentStack.Push(new StackElement(result, value1.ILType, value1.Type));
        }
Beispiel #26
0
        /// <summary>
        /// Emits a newobj instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            MethodReference ctor    = (MethodReference)instruction.Operand;
            TypeDefinition  objType = ctor.DeclaringType.Resolve();
            TypeRef         type    = TypeHelper.GetTypeRefFromType(ctor.DeclaringType);

            ValueRef objPtr;
            bool     ptr = (objType.IsClass && !objType.IsValueType);

            if (ptr)
            {
                // This type is a class, therefor we have a specialised "newobj" method.
                objPtr = LLVM.BuildCall(builder, context.Compiler.Lookup.GetNewobjMethod(ctor.DeclaringType.Resolve()), new ValueRef[0], "newobj");
            }
            else
            {
                // Not a class, allocate on stack.
                objPtr = LLVM.BuildAlloca(builder, type, "newobj");
            }

            // Constructor.
            ValueRef?ctorFunc = context.Compiler.Lookup.GetFunction(NameHelper.CreateMethodName(ctor));

            if (!ctorFunc.HasValue)
            {
                throw new Exception("Constructor not found: " + ctor);
            }

            // Get .ctor parameters.
            int paramCount = 1 + ctor.Parameters.Count;

            ValueRef[] values = new ValueRef[paramCount];
            values[0] = objPtr;
            for (int i = paramCount - 1; i >= 1; i--)
            {
                StackElement element = context.CurrentStack.Pop();
                values[i] = element.Value;

                // Cast needed?
                TypeRef paramType = TypeHelper.GetTypeRefFromType(ctor.Parameters[i - 1].ParameterType);
                if (element.Type != paramType)
                {
                    CastHelper.HelpIntAndPtrCast(builder, ref values[i], ref element.Type, paramType, "ctorcallcast");
                }
            }

            // Call .ctor.
            LLVM.BuildCall(builder, ctorFunc.Value, values, string.Empty);

            // Load and push object on stack.
            ValueRef obj = (ptr) ? objPtr : LLVM.BuildLoad(builder, objPtr, "obj");

            context.CurrentStack.Push(new StackElement(obj, ctor.DeclaringType, type));
        }
Beispiel #27
0
        /// <summary>
        /// Emits a starg instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement value = context.CurrentStack.Pop();

            ParameterDefinition def = (ParameterDefinition)instruction.Operand;
            int index = def.Index;

            ValueRef arg = context.ArgumentValues[index];

            CastHelper.HelpIntAndPtrCast(builder, ref value.Value, ref value.Type, TypeHelper.GetTypeRefFromType(context.ArgumentILTypes[index]), "stargcast");
            LLVM.BuildStore(builder, value.Value, arg);
        }
        /// <summary>
        /// Emits a ldelem_ref instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            StackElement index = context.CurrentStack.Pop();
            StackElement array = context.CurrentStack.Pop();

            ValueRef ptr = LLVM.BuildGEP(builder, array.Value, new ValueRef[] { index.Value }, "arrayptr");
            ValueRef res = LLVM.BuildLoad(builder, ptr, "arrayelem");

            TypeRef   type      = LLVM.TypeOf(res);
            ArrayType arrayType = (ArrayType)array.ILType;

            context.CurrentStack.Push(new StackElement(res, arrayType.ElementType, type));
        }
Beispiel #29
0
        /// <summary>
        /// Emits an instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            ICodeEmitter emitter = null;

            if (mEmitters.TryGetValue(instruction.OpCode.Code, out emitter))
            {
                emitter.Emit(instruction, context, builder);
            }
            else
            {
                throw new NotImplementedException("Instruction with opcode " + instruction.OpCode.Code + " is not implemented");
            }
        }
Beispiel #30
0
        /// <summary>
        /// Emits a ldarga instruction.
        /// </summary>
        /// <param name="instruction">The instruction.</param>
        /// <param name="context">The context.</param>
        /// <param name="builder">The builder.</param>
        public void Emit(Instruction instruction, MethodContext context, BuilderRef builder)
        {
            ParameterDefinition def = (ParameterDefinition)instruction.Operand;
            int index = def.Index;

            if (def.Method.HasThis)
            {
                index++;
            }

            ValueRef arg = context.ArgumentValues[index];

            context.CurrentStack.Push(new StackElement(arg, context.ArgumentILTypes[index]));
        }
Beispiel #31
0
 public unsafe static ValueRef BuildVAArg(BuilderRef arg0, ValueRef List, TypeRef Ty, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildVAArg(arg0.Value, List.Value, Ty.Value, Name));
   return ret;
 }
Beispiel #32
0
 public unsafe static ValueRef BuildCall(BuilderRef arg0, ValueRef Fn, ValueRef[] Args, string Name) {
   fixed (ValueRef* swig_ptrTo_Args = Args)
   {
     ValueRef ret = new ValueRef(LLVMPINVOKE.BuildCall(arg0.Value, Fn.Value, (System.IntPtr)swig_ptrTo_Args, (uint)Args.Length, Name));
     return ret;
   }
 }
Beispiel #33
0
 public unsafe static ValueRef BuildSelect(BuilderRef arg0, ValueRef If, ValueRef Then, ValueRef Else, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildSelect(arg0.Value, If.Value, Then.Value, Else.Value, Name));
   return ret;
 }
Beispiel #34
0
 public unsafe static ValueRef BuildAtomicRMW(BuilderRef B, AtomicRMWBinOp op, ValueRef PTR, ValueRef Val, AtomicOrdering ordering, bool singleThread) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildAtomicRMW(B.Value, (int)op, PTR.Value, Val.Value, (int)ordering, singleThread));
   return ret;
 }
Beispiel #35
0
 public unsafe static ValueRef BuildNUWNeg(BuilderRef B, ValueRef V, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildNUWNeg(B.Value, V.Value, Name));
   return ret;
 }
Beispiel #36
0
 public unsafe static ValueRef BuildInsertValue(BuilderRef arg0, ValueRef AggVal, ValueRef EltVal, uint Index, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildInsertValue(arg0.Value, AggVal.Value, EltVal.Value, Index, Name));
   return ret;
 }
Beispiel #37
0
 public unsafe static ValueRef BuildPtrDiff(BuilderRef arg0, ValueRef LHS, ValueRef RHS, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildPtrDiff(arg0.Value, LHS.Value, RHS.Value, Name));
   return ret;
 }
Beispiel #38
0
 public unsafe static ValueRef BuildInBoundsGEP(BuilderRef B, ValueRef Pointer, ValueRef[] Indices, string Name) {
   fixed (ValueRef* swig_ptrTo_Indices = Indices)
   {
     ValueRef ret = new ValueRef(LLVMPINVOKE.BuildInBoundsGEP(B.Value, Pointer.Value, (System.IntPtr)swig_ptrTo_Indices, (uint)Indices.Length, Name));
     return ret;
   }
 }
Beispiel #39
0
 public unsafe static ValueRef BuildStructGEP(BuilderRef B, ValueRef Pointer, uint Idx, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildStructGEP(B.Value, Pointer.Value, Idx, Name));
   return ret;
 }
Beispiel #40
0
 public unsafe static ValueRef BuildLoad(BuilderRef arg0, ValueRef PointerVal, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildLoad(arg0.Value, PointerVal.Value, Name));
   return ret;
 }
Beispiel #41
0
 public unsafe static ValueRef BuildStore(BuilderRef arg0, ValueRef Val, ValueRef Ptr) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildStore(arg0.Value, Val.Value, Ptr.Value));
   return ret;
 }
Beispiel #42
0
 public unsafe static ValueRef BuildFree(BuilderRef arg0, ValueRef PointerVal) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildFree(arg0.Value, PointerVal.Value));
   return ret;
 }
Beispiel #43
0
 public unsafe static ValueRef BuildArrayAlloca(BuilderRef arg0, TypeRef Ty, ValueRef Val, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildArrayAlloca(arg0.Value, Ty.Value, Val.Value, Name));
   return ret;
 }
Beispiel #44
0
 public unsafe static ValueRef BuildNot(BuilderRef arg0, ValueRef V, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildNot(arg0.Value, V.Value, Name));
   return ret;
 }
Beispiel #45
0
 public unsafe static ValueRef BuildInsertElement(BuilderRef arg0, ValueRef VecVal, ValueRef EltVal, ValueRef Index, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildInsertElement(arg0.Value, VecVal.Value, EltVal.Value, Index.Value, Name));
   return ret;
 }
Beispiel #46
0
 public unsafe static ValueRef BuildGlobalStringPtr(BuilderRef B, string Str, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildGlobalStringPtr(B.Value, Str, Name));
   return ret;
 }
Beispiel #47
0
 public unsafe static ValueRef BuildShuffleVector(BuilderRef arg0, ValueRef V1, ValueRef V2, ValueRef Mask, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildShuffleVector(arg0.Value, V1.Value, V2.Value, Mask.Value, Name));
   return ret;
 }
Beispiel #48
0
 public unsafe static ValueRef BuildInvoke(BuilderRef arg0, ValueRef Fn, ValueRef[] Args, BasicBlockRef Then, BasicBlockRef Catch, string Name) {
   fixed (ValueRef* swig_ptrTo_Args = Args)
   {
     ValueRef ret = new ValueRef(LLVMPINVOKE.BuildInvoke(arg0.Value, Fn.Value, (System.IntPtr)swig_ptrTo_Args, (uint)Args.Length, Then.Value, Catch.Value, Name));
     return ret;
   }
 }
Beispiel #49
0
 public unsafe static ValueRef BuildIsNotNull(BuilderRef arg0, ValueRef Val, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildIsNotNull(arg0.Value, Val.Value, Name));
   return ret;
 }
Beispiel #50
0
 public unsafe static ValueRef BuildResume(BuilderRef B, ValueRef Exn) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildResume(B.Value, Exn.Value));
   return ret;
 }
Beispiel #51
0
 public unsafe static ValueRef BuildFence(BuilderRef B, AtomicOrdering ordering, bool singleThread, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildFence(B.Value, (int)ordering, singleThread, Name));
   return ret;
 }
Beispiel #52
0
 public unsafe static ValueRef BuildIndirectBr(BuilderRef B, ValueRef Addr, uint NumDests) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildIndirectBr(B.Value, Addr.Value, NumDests));
   return ret;
 }
Beispiel #53
0
 public unsafe static ValueRef BuildUnsignedIntCast(BuilderRef arg0, ValueRef Val, TypeRef DestTy, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildUnsignedIntCast(arg0.Value, Val.Value, DestTy.Value, Name));
   return ret;
 }
Beispiel #54
0
 public unsafe static ValueRef BuildUnreachable(BuilderRef arg0) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildUnreachable(arg0.Value));
   return ret;
 }
Beispiel #55
0
 public unsafe static ValueRef BuildCast(BuilderRef B, Opcode Op, ValueRef Val, TypeRef DestTy, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildCast(B.Value, (int)Op, Val.Value, DestTy.Value, Name));
   return ret;
 }
Beispiel #56
0
 public unsafe static ValueRef BuildLandingPad(BuilderRef B, TypeRef Ty, ValueRef PersFn, uint NumClauses, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildLandingPad(B.Value, Ty.Value, PersFn.Value, NumClauses, Name));
   return ret;
 }
Beispiel #57
0
 public unsafe static ValueRef BuildFCmp(BuilderRef arg0, RealPredicate Op, ValueRef LHS, ValueRef RHS, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildFCmp(arg0.Value, (int)Op, LHS.Value, RHS.Value, Name));
   return ret;
 }
Beispiel #58
0
 public unsafe static ValueRef BuildPhi(BuilderRef arg0, TypeRef Ty, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildPhi(arg0.Value, Ty.Value, Name));
   return ret;
 }
Beispiel #59
0
 public unsafe static ValueRef BuildBinOp(BuilderRef B, Opcode Op, ValueRef LHS, ValueRef RHS, string Name) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildBinOp(B.Value, (int)Op, LHS.Value, RHS.Value, Name));
   return ret;
 }
Beispiel #60
0
 public unsafe static ValueRef BuildSwitch(BuilderRef arg0, ValueRef V, BasicBlockRef Else, uint NumCases) {
   ValueRef ret = new ValueRef(LLVMPINVOKE.BuildSwitch(arg0.Value, V.Value, Else.Value, NumCases));
   return ret;
 }