Esempio n. 1
0
        private static void BuildStringFromSliceFunction(Module stringModule, CommonExternalFunctions externalFunctions)
        {
            LLVMValueRef      stringFromSliceFunction = stringModule.AddFunction(StringFromSliceName, CommonModuleSignatures[StringFromSliceName]);
            LLVMBasicBlockRef entryBlock = stringFromSliceFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef stringSliceReference   = stringFromSliceFunction.GetParam(0u),
                         stringPtr              = stringFromSliceFunction.GetParam(1u),
                         stringAllocationPtrPtr = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"),
                         stringSizePtr          = builder.CreateStructGEP(stringPtr, 1u, "stringSizePtr");

            LLVMValueRef sliceAllocationPtr = builder.CreateExtractValue(stringSliceReference, 0u, "sliceAllocationPtr");
            LLVMValueRef sliceSize          = builder.CreateExtractValue(stringSliceReference, 1u, "sliceSize");

            // Get a pointer to a heap allocation big enough for the string
            LLVMValueRef allocationPtr = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), sliceSize, "allocationPtr");

            builder.CreateStore(allocationPtr, stringAllocationPtrPtr);

            // Copy the data from the string slice to the heap allocation
            LLVMValueRef sizeExtend = builder.CreateSExt(sliceSize, LLVMTypeRef.Int64Type(), "sizeExtend");

            builder.CreateCall(externalFunctions.CopyMemoryFunction, new LLVMValueRef[] { allocationPtr, sliceAllocationPtr, sizeExtend }, string.Empty);

            // Copy actual size into string handle
            builder.CreateStore(sliceSize, stringSizePtr);

            builder.CreateRetVoid();
        }
Esempio n. 2
0
        static LLVMValueRef createMain()
        {
            var          context  = LLVM.GetGlobalContext();
            LLVMTypeRef  funcType = LLVMTypeRef.FunctionType(LLVMTypeRef.Int64Type(), new LLVMTypeRef[] {  }, false);
            LLVMValueRef function = LLVM.AddFunction(module, "main", funcType);

            return(function);
        }
Esempio n. 3
0
        public static LLVMTypeRef AsLLVMType(this NIType niType)
        {
            if (niType.IsInteger())
            {
                switch (niType.GetKind())
                {
                case NITypeKind.UInt8:
                case NITypeKind.Int8:
                    return(LLVMTypeRef.Int8Type());

                case NITypeKind.UInt16:
                case NITypeKind.Int16:
                    return(LLVMTypeRef.Int16Type());

                case NITypeKind.UInt32:
                case NITypeKind.Int32:
                    return(LLVMTypeRef.Int32Type());

                case NITypeKind.UInt64:
                case NITypeKind.Int64:
                    return(LLVMTypeRef.Int64Type());
                }
            }
            if (niType.IsBoolean())
            {
                return(LLVMTypeRef.Int1Type());
            }
            if (niType.IsString())
            {
                return(StringType);
            }
            if (niType.IsRebarReferenceType())
            {
                NIType referentType = niType.GetReferentType();
                if (referentType == DataTypes.StringSliceType)
                {
                    return(StringSliceReferenceType);
                }
                return(LLVMTypeRef.PointerType(referentType.AsLLVMType(), 0u));
            }
            if (niType == DataTypes.FileHandleType)
            {
                return(FileHandleType);
            }
            NIType innerType;

            if (niType.TryDestructureOptionType(out innerType))
            {
                return(CreateLLVMOptionType(innerType.AsLLVMType()));
            }
            if (niType == DataTypes.RangeIteratorType)
            {
                return(RangeIteratorType);
            }
            throw new NotSupportedException("Unsupported type: " + niType);
        }
Esempio n. 4
0
        public static LLVMTypeRef ToLLVMType(this Type type)
        {
            if (type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Vector128 <>))
            {
                var et = type.GetGenericArguments()[0];
                return(LLVMTypeRef.VectorType(et.ToLLVMType(), 16U / (uint)Marshal.SizeOf(et)));
            }
            if (typeof(MulticastDelegate).IsAssignableFrom(type))
            {
                var mi = type.GetMethod("Invoke");
                return(LLVMTypeRef.FunctionType(mi.ReturnType.ToLLVMType(),
                                                mi.GetParameters().Select(x => x.ParameterType.ToLLVMType()).ToArray(), false));
            }
            if (type == typeof(void))
            {
                return(LLVMTypeRef.VoidType());
            }
            if (type.IsPointer)
            {
                return(LLVMTypeRef.Int64Type());
            }
            switch (Activator.CreateInstance(type))
            {
            case sbyte _:
            case byte _: return(LLVMTypeRef.Int8Type());

            case short _:
            case ushort _: return(LLVMTypeRef.Int16Type());

            case int _:
            case uint _: return(LLVMTypeRef.Int32Type());

            case long _:
            case ulong _: return(LLVMTypeRef.Int64Type());

            case Int128 _:
            case UInt128 _: return(LLVMTypeRef.IntType(128));

            case float _: return(LLVMTypeRef.FloatType());

            case double _: return(LLVMTypeRef.DoubleType());

            case bool _: return(LLVMTypeRef.IntType(1));

            default: throw new NotSupportedException(type.Name);
            }
        }
Esempio n. 5
0
        private static void BuildCopySliceToPointerFunction(Module stringModule, CommonExternalFunctions externalFunctions)
        {
            _copySliceToPointerFunction = stringModule.AddFunction(CopySliceToPointerName, CommonModuleSignatures[CopySliceToPointerName]);
            LLVMBasicBlockRef entryBlock = _copySliceToPointerFunction.AppendBasicBlock("entry");
            var builder = new IRBuilder();

            builder.PositionBuilderAtEnd(entryBlock);

            LLVMValueRef slice          = _copySliceToPointerFunction.GetParam(0u),
                         sourcePtr      = builder.CreateExtractValue(slice, 0u, "sourcePtr"),
                         size           = builder.CreateExtractValue(slice, 1u, "size"),
                         sizeExtend     = builder.CreateSExt(size, LLVMTypeRef.Int64Type(), "sizeExtend"),
                         destinationPtr = _copySliceToPointerFunction.GetParam(1u);

            builder.CreateCall(externalFunctions.CopyMemoryFunction, new LLVMValueRef[] { destinationPtr, sourcePtr, sizeExtend }, string.Empty);
            builder.CreateRetVoid();
        }
Esempio n. 6
0
        public ExprAST VariableExprVisit(VariableExprAST node)
        {
            LLVMValueRef initValue;

            this.Visit(node.Value);
            initValue = valueStack.Pop();
            LLVMValueRef alloca = default(LLVMValueRef);

            switch (LLVM.GetTypeKind(LLVM.TypeOf(initValue)))
            {
            case LLVMTypeKind.LLVMIntegerTypeKind:
                alloca = CreateEntryBlockAlloca(mainFunction, LLVMTypeRef.Int64Type(), node.Name);
                break;

            case LLVMTypeKind.LLVMDoubleTypeKind:
                alloca = CreateEntryBlockAlloca(mainFunction, LLVMTypeRef.DoubleType(), node.Name);
                break;
            }
            LLVM.BuildStore(builder, initValue, alloca);
            return(node);
        }
Esempio n. 7
0
        private static LLVMTypeRef GetLlvmType([NotNull] Type lambdaTypeParam)
        {
            switch (lambdaTypeParam)
            {
            case PrimaryType primaryType:
                if (string.Equals(primaryType.Name, "f64", Ordinal))
                {
                    return(LLVMSharp.LLVM.DoubleType());
                }
                if (string.Equals(primaryType.Name, "f32", Ordinal))
                {
                    return(LLVMTypeRef.FloatType());
                }
                if (string.Equals(primaryType.Name, "i8", Ordinal))
                {
                    return(LLVMTypeRef.Int8Type());
                }
                if (string.Equals(primaryType.Name, "i16", Ordinal))
                {
                    return(LLVMTypeRef.Int16Type());
                }
                if (string.Equals(primaryType.Name, "i32", Ordinal))
                {
                    return(LLVMTypeRef.Int32Type());
                }
                if (string.Equals(primaryType.Name, "i64", Ordinal))
                {
                    return(LLVMTypeRef.Int64Type());
                }
                break;

            case LambdaType lambdaType:
                return(LLVMTypeRef.FunctionType(GetLlvmType(lambdaType.RetType),
                                                (from type in lambdaType.ParamsList select GetLlvmType(type)).ToArray(), false));

            case SecondaryType secondaryType:
                break;
            }
            throw new NotImplementedException();
        }
Esempio n. 8
0
        public CommonExternalFunctions(Module addTo)
        {
            LLVMTypeRef bytePointerType = LLVMTypeRef.PointerType(LLVMTypeRef.Int8Type(), 0);

            // NB: this will get resolved to the Win32 RtlCopyMemory function.
            LLVMTypeRef copyMemoryFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { bytePointerType, bytePointerType, LLVMTypeRef.Int64Type() },
                false);

            CopyMemoryFunction = addTo.AddFunction("CopyMemory", copyMemoryFunctionType);
            CopyMemoryFunction.SetLinkage(LLVMLinkage.LLVMExternalLinkage);

            OutputBoolFunction   = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int1Type(), "output_bool");
            OutputInt8Function   = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int8Type(), "output_int8");
            OutputUInt8Function  = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int8Type(), "output_uint8");
            OutputInt16Function  = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int16Type(), "output_int16");
            OutputUInt16Function = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int16Type(), "output_uint16");
            OutputInt32Function  = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int32Type(), "output_int32");
            OutputUInt32Function = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int32Type(), "output_uint32");
            OutputInt64Function  = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int64Type(), "output_int64");
            OutputUInt64Function = CreateSingleParameterVoidFunction(addTo, LLVMTypeRef.Int64Type(), "output_uint64");

            LLVMTypeRef outputStringFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMSharp.LLVM.VoidType(),
                new LLVMTypeRef[] { bytePointerType, LLVMTypeRef.Int32Type() },
                false);

            OutputStringFunction = addTo.AddFunction("output_string", outputStringFunctionType);
            OutputStringFunction.SetLinkage(LLVMLinkage.LLVMExternalLinkage);

            LLVMTypeRef closeHandleFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMTypeRef.Int32Type(),    // bool
                new LLVMTypeRef[] { LLVMExtensions.VoidPointerType },
                false);

            CloseHandleFunction = addTo.AddFunction("CloseHandle", closeHandleFunctionType);

            LLVMTypeRef createFileAFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMExtensions.VoidPointerType,
                new LLVMTypeRef[]
            {
                bytePointerType,                // filename
                LLVMTypeRef.Int32Type(),        // access
                LLVMTypeRef.Int32Type(),        // share
                LLVMExtensions.VoidPointerType, // securityAttributes
                LLVMTypeRef.Int32Type(),        // creationDisposition
                LLVMTypeRef.Int32Type(),        // flagsAndAttributes
                LLVMExtensions.VoidPointerType, // templateFile
            },
                false);

            CreateFileAFunction = addTo.AddFunction("CreateFileA", createFileAFunctionType);

            LLVMTypeRef readFileFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMTypeRef.Int32Type(),    // bool
                new LLVMTypeRef[]
            {
                LLVMExtensions.VoidPointerType,                      // hFile
                LLVMExtensions.VoidPointerType,                      // lpBuffer
                LLVMTypeRef.Int32Type(),                             // nNumberOfBytesToRead
                LLVMTypeRef.PointerType(LLVMTypeRef.Int32Type(), 0), // lpNumberOfBytesRead
                LLVMExtensions.VoidPointerType,                      // lpOverlapped
            },
                false);

            ReadFileFunction = addTo.AddFunction("ReadFile", readFileFunctionType);

            LLVMTypeRef writeFileFunctionType = LLVMSharp.LLVM.FunctionType(
                LLVMTypeRef.Int32Type(),    // bool
                new LLVMTypeRef[]
            {
                LLVMExtensions.VoidPointerType,                      // hFile
                LLVMExtensions.VoidPointerType,                      // lpBuffer
                LLVMTypeRef.Int32Type(),                             // nNumberOfBytesToWrite,
                LLVMTypeRef.PointerType(LLVMTypeRef.Int32Type(), 0), // lpNumberOfBytesWritten
                LLVMExtensions.VoidPointerType,                      // lpOverlapped
            },
                false);

            WriteFileFunction = addTo.AddFunction("WriteFile", writeFileFunctionType);
        }
Esempio n. 9
0
 public static LLVMValueRef AsLLVMValue(this ulong intValue)
 {
     return(LLVMSharp.LLVM.ConstInt(LLVMTypeRef.Int64Type(), intValue, false));
 }