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 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); }
private static void BuildReadLineFromFileHandleFunction(Module fileModule, CommonExternalFunctions externalFunctions) { LLVMValueRef readLineFromFileHandleFunction = fileModule.AddFunction(ReadLineFromFileHandleName, CommonModuleSignatures[ReadLineFromFileHandleName]); LLVMBasicBlockRef entryBlock = readLineFromFileHandleFunction.AppendBasicBlock("entry"); var builder = new IRBuilder(); builder.PositionBuilderAtEnd(entryBlock); LLVMBasicBlockRef loopStartBlock = readLineFromFileHandleFunction.AppendBasicBlock("loopStart"), handleByteBlock = readLineFromFileHandleFunction.AppendBasicBlock("handleByte"), byteIsCRBlock = readLineFromFileHandleFunction.AppendBasicBlock("byteIsCR"), byteIsNotCRBlock = readLineFromFileHandleFunction.AppendBasicBlock("byteIsNotCR"), notNewLineBlock = readLineFromFileHandleFunction.AppendBasicBlock("notNewLine"), appendCRBlock = readLineFromFileHandleFunction.AppendBasicBlock("appendCR"), appendByteBlock = readLineFromFileHandleFunction.AppendBasicBlock("appendByte"), loopEndBlock = readLineFromFileHandleFunction.AppendBasicBlock("loopEnd"), nonEmptyStringBlock = readLineFromFileHandleFunction.AppendBasicBlock("nonEmptyString"), emptyStringBlock = readLineFromFileHandleFunction.AppendBasicBlock("emptyString"); LLVMValueRef fileHandlePtr = readLineFromFileHandleFunction.GetParam(0u), stringPtr = builder.CreateAlloca(LLVMExtensions.StringType, "stringPtr"), carriageReturnPtr = builder.CreateAlloca(LLVMTypeRef.Int8Type(), "carriageReturnPtr"), carriageReturn = ((byte)0xD).AsLLVMValue(), byteReadPtr = builder.CreateAlloca(LLVMTypeRef.Int8Type(), "byteReadPtr"), bytesReadPtr = builder.CreateAlloca(LLVMTypeRef.Int32Type(), "bytesReadPtr"), nonEmptyStringPtr = builder.CreateAlloca(LLVMTypeRef.Int1Type(), "nonEmptyStringPtr"), seenCRPtr = builder.CreateAlloca(LLVMTypeRef.Int1Type(), "seenCRPtr"); builder.CreateStore(carriageReturn, carriageReturnPtr); builder.CreateStore(false.AsLLVMValue(), seenCRPtr); builder.CreateStore(false.AsLLVMValue(), nonEmptyStringPtr); builder.CreateCall(_createEmptyStringFunction, new LLVMValueRef[] { stringPtr }, string.Empty); builder.CreateBr(loopStartBlock); builder.PositionBuilderAtEnd(loopStartBlock); LLVMValueRef hFilePtr = builder.CreateStructGEP(fileHandlePtr, 0u, "hFilePtr"), hFile = builder.CreateLoad(hFilePtr, "hFile"); LLVMValueRef readFileResult = builder.CreateCall( externalFunctions.ReadFileFunction, new LLVMValueRef[] { hFile, byteReadPtr, 1.AsLLVMValue(), bytesReadPtr, LLVMExtensions.NullVoidPointer }, "readFileResult"), readFileResultBool = builder.CreateICmp(LLVMIntPredicate.LLVMIntNE, readFileResult, 0.AsLLVMValue(), "readFileResultBool"), bytesRead = builder.CreateLoad(bytesReadPtr, "bytesRead"), zeroBytesRead = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, bytesRead, 0.AsLLVMValue(), "zeroBytesRead"), eof = builder.CreateAnd(readFileResultBool, zeroBytesRead, "eof"); builder.CreateCondBr(eof, loopEndBlock, handleByteBlock); builder.PositionBuilderAtEnd(handleByteBlock); LLVMValueRef byteRead = builder.CreateLoad(byteReadPtr, "byteRead"), byteReadIsCR = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, byteRead, carriageReturn, "byteReadIsCR"); builder.CreateCondBr(byteReadIsCR, byteIsCRBlock, byteIsNotCRBlock); builder.PositionBuilderAtEnd(byteIsCRBlock); builder.CreateStore(true.AsLLVMValue(), seenCRPtr); builder.CreateBr(loopStartBlock); builder.PositionBuilderAtEnd(byteIsNotCRBlock); LLVMValueRef byteIsLF = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, byteRead, ((byte)0xA).AsLLVMValue(), "byteIsLF"), seenCR = builder.CreateLoad(seenCRPtr, "seenCR"), newLine = builder.CreateAnd(byteIsLF, seenCR, "newLine"); builder.CreateCondBr(newLine, loopEndBlock, notNewLineBlock); builder.PositionBuilderAtEnd(notNewLineBlock); builder.CreateCondBr(seenCR, appendCRBlock, appendByteBlock); builder.PositionBuilderAtEnd(appendCRBlock); LLVMValueRef crSlice = builder.BuildStringSliceReferenceValue(carriageReturnPtr, 1.AsLLVMValue()); builder.CreateCall(_stringAppendFunction, new LLVMValueRef[] { stringPtr, crSlice }, string.Empty); builder.CreateBr(appendByteBlock); builder.PositionBuilderAtEnd(appendByteBlock); LLVMValueRef byteSlice = builder.BuildStringSliceReferenceValue(byteReadPtr, 1.AsLLVMValue()); builder.CreateCall(_stringAppendFunction, new LLVMValueRef[] { stringPtr, byteSlice }, string.Empty); builder.CreateStore(true.AsLLVMValue(), nonEmptyStringPtr); builder.CreateStore(false.AsLLVMValue(), seenCRPtr); builder.CreateBr(loopStartBlock); builder.PositionBuilderAtEnd(loopEndBlock); LLVMValueRef optionStringPtr = readLineFromFileHandleFunction.GetParam(1u), optionStringIsSomePtr = builder.CreateStructGEP(optionStringPtr, 0u, "optionStringIsSomePtr"), nonEmptyString = builder.CreateLoad(nonEmptyStringPtr, "nonEmptyString"); builder.CreateCondBr(nonEmptyString, nonEmptyStringBlock, emptyStringBlock); builder.PositionBuilderAtEnd(nonEmptyStringBlock); builder.CreateStore(true.AsLLVMValue(), optionStringIsSomePtr); LLVMValueRef optionStringInnerValuePtr = builder.CreateStructGEP(optionStringPtr, 1u, "optionStringInnerValuePtr"), stringValue = builder.CreateLoad(stringPtr, "string"); builder.CreateStore(stringValue, optionStringInnerValuePtr); builder.CreateRetVoid(); builder.PositionBuilderAtEnd(emptyStringBlock); builder.CreateStore(false.AsLLVMValue(), optionStringIsSomePtr); builder.CreateCall(_dropStringFunction, new LLVMValueRef[] { stringPtr }, string.Empty); builder.CreateRetVoid(); }
public static LLVMValueRef AsLLVMValue(this bool booleanValue) { return(LLVMSharp.LLVM.ConstInt(LLVMTypeRef.Int1Type(), (booleanValue ? 1u : 0u), false)); }
internal static LLVMTypeRef CreateLLVMOptionType(this LLVMTypeRef innerType) { return(LLVMTypeRef.StructType(new LLVMTypeRef[] { LLVMTypeRef.Int1Type(), innerType }, false)); }