/* * Copyright (c) 2016, Oracle and/or its affiliates. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, are * permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list of * conditions and the following disclaimer in the documentation and/or other materials provided * with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors may be used to * endorse or promote products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ package com.oracle.truffle.llvm.parser.factories; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.frame.FrameSlot; import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.api.source.SourceSection; import com.oracle.truffle.llvm.nodes.base.LLVMMainFunctionReturnValueRootNode; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVM80BitFloatRetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMAddressRetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMDoubleRetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMFloatRetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMFunctionRetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMI16RetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMI1RetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMI32RetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMI64RetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMI8RetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMIVarBitRetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMStructRetNodeGen; import com.oracle.truffle.llvm.nodes.control.LLVMRetNodeFactory.LLVMVectorRetNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMArgNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallNode; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNode.LLVMVoidCallUnboxNode; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVM80BitFloatCallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMAddressCallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMDoubleCallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMFloatCallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMFunctionCallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMI16CallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMI1CallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMI32CallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMI64CallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMI8CallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMStructCallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMVarBitCallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMCallUnboxNodeFactory.LLVMVectorCallUnboxNodeGen; import com.oracle.truffle.llvm.nodes.func.LLVMInvokeNode; import com.oracle.truffle.llvm.nodes.others.LLVMValueProfilingNodeFactory.LLVMDoubleProfiledValueNodeGen; import com.oracle.truffle.llvm.nodes.others.LLVMValueProfilingNodeFactory.LLVMFloatProfiledValueNodeGen; import com.oracle.truffle.llvm.nodes.others.LLVMValueProfilingNodeFactory.LLVMI32ProfiledValueNodeGen; import com.oracle.truffle.llvm.nodes.others.LLVMValueProfilingNodeFactory.LLVMI64ProfiledValueNodeGen; import com.oracle.truffle.llvm.nodes.others.LLVMValueProfilingNodeFactory.LLVMI8ProfiledValueNodeGen; import com.oracle.truffle.llvm.parser.LLVMParserRuntime; import com.oracle.truffle.llvm.runtime.LLVMLanguage; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMControlFlowNode; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode; import com.oracle.truffle.llvm.runtime.types.FunctionType; import com.oracle.truffle.llvm.runtime.types.PointerType; import com.oracle.truffle.llvm.runtime.types.PrimitiveType; import com.oracle.truffle.llvm.runtime.types.StructureType; import com.oracle.truffle.llvm.runtime.types.Type; import com.oracle.truffle.llvm.runtime.types.VariableBitWidthType; import com.oracle.truffle.llvm.runtime.types.VectorType; import com.oracle.truffle.llvm.runtime.types.VoidType; final class LLVMFunctionFactory { private LLVMFunctionFactory() { } static LLVMControlFlowNode createNonVoidRet(LLVMParserRuntime runtime, LLVMExpressionNode retValue, Type type, SourceSection source) { if (retValue == null) { throw new AssertionError(); } if (type instanceof VectorType) { return LLVMVectorRetNodeGen.create(source, retValue); } else if (type instanceof VariableBitWidthType) { return LLVMIVarBitRetNodeGen.create(source, retValue); } else if (Type.isFunctionOrFunctionPointer(type)) { return LLVMFunctionRetNodeGen.create(source, retValue); } else if (type instanceof PointerType) { return LLVMAddressRetNodeGen.create(source, retValue); } else if (type instanceof StructureType) { int size = runtime.getByteSize(type); return LLVMStructRetNodeGen.create(runtime.getNativeFunctions(), source, retValue, size); } else if (type instanceof PrimitiveType) { switch (((PrimitiveType) type).getPrimitiveKind()) { case I1: return LLVMI1RetNodeGen.create(source, retValue); case I8: return LLVMI8RetNodeGen.create(source, retValue); case I16: return LLVMI16RetNodeGen.create(source, retValue); case I32: return LLVMI32RetNodeGen.create(source, retValue); case I64: return LLVMI64RetNodeGen.create(source, retValue); case FLOAT: return LLVMFloatRetNodeGen.create(source, retValue); case DOUBLE: return LLVMDoubleRetNodeGen.create(source, retValue); case X86_FP80: return LLVM80BitFloatRetNodeGen.create(source, retValue); default: throw new AssertionError(type); } } throw new AssertionError(type); } static LLVMExpressionNode createFunctionArgNode(int argIndex, Type paramType) { if (argIndex < 0) { throw new AssertionError(); } LLVMExpressionNode argNode = LLVMArgNodeGen.create(argIndex); if (paramType instanceof PrimitiveType) { switch (((PrimitiveType) paramType).getPrimitiveKind()) { case I8: return LLVMI8ProfiledValueNodeGen.create(argNode); case I32: return LLVMI32ProfiledValueNodeGen.create(argNode); case I64: return LLVMI64ProfiledValueNodeGen.create(argNode); case FLOAT: return LLVMFloatProfiledValueNodeGen.create(argNode); case DOUBLE: return LLVMDoubleProfiledValueNodeGen.create(argNode); default: return argNode; } } else { return argNode; } } static LLVMExpressionNode createFunctionCall(LLVMExpressionNode functionNode, LLVMExpressionNode[] argNodes, FunctionType functionType, SourceSection sourceSection) { LLVMCallNode unresolvedCallNode = new LLVMCallNode(functionType, functionNode, argNodes, sourceSection); return createUnresolvedNodeWrapping(functionType.getReturnType(), unresolvedCallNode); } static LLVMControlFlowNode createFunctionInvoke(FrameSlot resultLocation, LLVMExpressionNode functionNode, LLVMExpressionNode[] argNodes, FunctionType type, int normalIndex, int unwindIndex, LLVMExpressionNode[] normalPhiWriteNodes, LLVMExpressionNode[] unwindPhiWriteNodes, SourceSection sourceSection) { return new LLVMInvokeNode.LLVMFunctionInvokeNode(type, resultLocation, functionNode, argNodes, normalIndex, unwindIndex, normalPhiWriteNodes, unwindPhiWriteNodes, sourceSection); } private static LLVMExpressionNode createUnresolvedNodeWrapping(Type llvmType, LLVMExpressionNode unresolvedCallNode) { if (llvmType instanceof VectorType) { return LLVMVectorCallUnboxNodeGen.create(unresolvedCallNode); } else if (llvmType instanceof VariableBitWidthType) { return LLVMVarBitCallUnboxNodeGen.create(unresolvedCallNode); } else if (llvmType instanceof VoidType) { return new LLVMVoidCallUnboxNode(unresolvedCallNode); } else if (Type.isFunctionOrFunctionPointer(llvmType)) { return LLVMFunctionCallUnboxNodeGen.create(unresolvedCallNode); } else if (llvmType instanceof StructureType) { return LLVMStructCallUnboxNodeGen.create(unresolvedCallNode); } else if (llvmType instanceof PointerType) { return LLVMAddressCallUnboxNodeGen.create(unresolvedCallNode); } else if (llvmType instanceof PrimitiveType) { switch (((PrimitiveType) llvmType).getPrimitiveKind()) { case I1: return LLVMI1CallUnboxNodeGen.create(unresolvedCallNode); case I8: return LLVMI8CallUnboxNodeGen.create(unresolvedCallNode); case I16: return LLVMI16CallUnboxNodeGen.create(unresolvedCallNode); case I32: return LLVMI32CallUnboxNodeGen.create(unresolvedCallNode); case I64: return LLVMI64CallUnboxNodeGen.create(unresolvedCallNode); case FLOAT: return LLVMFloatCallUnboxNodeGen.create(unresolvedCallNode); case DOUBLE: return LLVMDoubleCallUnboxNodeGen.create(unresolvedCallNode); case X86_FP80: return LLVM80BitFloatCallUnboxNodeGen.create(unresolvedCallNode); default: throw new AssertionError(llvmType); } } throw new AssertionError(llvmType); } static RootNode createGlobalRootNodeWrapping(LLVMLanguage language, RootCallTarget mainCallTarget, Type returnType) { if (returnType instanceof VoidType) { return new LLVMMainFunctionReturnValueRootNode.LLVMMainFunctionReturnVoidRootNode(language, mainCallTarget); } else if (returnType instanceof VariableBitWidthType) { return new LLVMMainFunctionReturnValueRootNode.LLVMMainFunctionReturnIVarBitRootNode(language, mainCallTarget); } else if (returnType instanceof PrimitiveType) { switch (((PrimitiveType) returnType).getPrimitiveKind()) { case I1: return new LLVMMainFunctionReturnValueRootNode.LLVMMainFunctionReturnI1RootNode(language, mainCallTarget); case I8: case I16: case I32: case I64: case FLOAT: case DOUBLE: return new LLVMMainFunctionReturnValueRootNode.LLVMMainFunctionReturnNumberRootNode(language, mainCallTarget); default: throw new AssertionError(returnType); } } throw new AssertionError(returnType); } }