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(); }
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); }
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); }
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); } }
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(); }
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); }
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(); }
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); }
public static LLVMValueRef AsLLVMValue(this ulong intValue) { return(LLVMSharp.LLVM.ConstInt(LLVMTypeRef.Int64Type(), intValue, false)); }