/* * 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.source.SourceSection; import com.oracle.truffle.llvm.nodes.memory.LLVMLoadVectorNodeFactory.LLVMLoadDoubleVectorNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMLoadVectorNodeFactory.LLVMLoadFloatVectorNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMLoadVectorNodeFactory.LLVMLoadI16VectorNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMLoadVectorNodeFactory.LLVMLoadI1VectorNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMLoadVectorNodeFactory.LLVMLoadI32VectorNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMLoadVectorNodeFactory.LLVMLoadI64VectorNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMLoadVectorNodeFactory.LLVMLoadI8VectorNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVM80BitFloatStoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMAddressStoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMDoubleStoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMFloatStoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMFunctionStoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMGlobalVariableStoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMI16StoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMI1StoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMI32StoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMI64StoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMI8StoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMIVarBitStoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreNodeFactory.LLVMStructStoreNodeGen; import com.oracle.truffle.llvm.nodes.memory.LLVMStoreVectorNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMDirectLoadNode.LLVMGlobalVariableDirectLoadNode; import com.oracle.truffle.llvm.nodes.memory.load.LLVMDirectLoadNodeFactory.LLVM80BitFloatDirectLoadNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMDirectLoadNodeFactory.LLVMAddressDirectLoadNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMDirectLoadNodeFactory.LLVMFunctionDirectLoadNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMDirectLoadNodeFactory.LLVMIVarBitDirectLoadNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMDirectLoadNodeFactory.LLVMStructDirectLoadNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMDoubleLoadNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMFloatLoadNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMI16LoadNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMI1LoadNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMI32LoadNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMI64LoadNodeGen; import com.oracle.truffle.llvm.nodes.memory.load.LLVMI8LoadNodeGen; import com.oracle.truffle.llvm.nodes.others.LLVMAccessGlobalVariableStorageNode; import com.oracle.truffle.llvm.parser.LLVMParserRuntime; import com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode; import com.oracle.truffle.llvm.runtime.types.ArrayType; 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; final class LLVMMemoryReadWriteFactory { private LLVMMemoryReadWriteFactory() { } static LLVMExpressionNode createLoad(Type resolvedResultType, LLVMExpressionNode loadTarget) { if (resolvedResultType instanceof VectorType) { return createLoadVector((VectorType) resolvedResultType, loadTarget, ((VectorType) resolvedResultType).getNumberOfElements()); } else { int bits = resolvedResultType instanceof VariableBitWidthType ? resolvedResultType.getBitSize() : 0; return createLoad(resolvedResultType, loadTarget, bits); } } private static LLVMExpressionNode createLoad(Type resultType, LLVMExpressionNode loadTarget, int bits) { if (resultType instanceof PrimitiveType) { switch (((PrimitiveType) resultType).getPrimitiveKind()) { case I1: return LLVMI1LoadNodeGen.create(loadTarget); case I8: return LLVMI8LoadNodeGen.create(loadTarget); case I16: return LLVMI16LoadNodeGen.create(loadTarget); case I32: return LLVMI32LoadNodeGen.create(loadTarget); case I64: return LLVMI64LoadNodeGen.create(loadTarget); case FLOAT: return LLVMFloatLoadNodeGen.create(loadTarget); case DOUBLE: return LLVMDoubleLoadNodeGen.create(loadTarget); case X86_FP80: return LLVM80BitFloatDirectLoadNodeGen.create(loadTarget); default: throw new AssertionError(resultType); } } else if (resultType instanceof VariableBitWidthType) { return LLVMIVarBitDirectLoadNodeGen.create(loadTarget, bits); } else if (Type.isFunctionOrFunctionPointer(resultType)) { return LLVMFunctionDirectLoadNodeGen.create(loadTarget); } else if (resultType instanceof StructureType || resultType instanceof ArrayType) { return LLVMStructDirectLoadNodeGen.create(loadTarget); } else if (resultType instanceof PointerType) { if (loadTarget instanceof LLVMAccessGlobalVariableStorageNode) { return new LLVMGlobalVariableDirectLoadNode(((LLVMAccessGlobalVariableStorageNode) loadTarget).getDescriptor()); } else { return LLVMAddressDirectLoadNodeGen.create(loadTarget); } } else { throw new AssertionError(resultType); } } private static LLVMExpressionNode createLoadVector(VectorType resultType, LLVMExpressionNode loadTarget, int size) { switch (resultType.getElementType().getPrimitiveKind()) { case I1: return LLVMLoadI1VectorNodeGen.create(loadTarget, size); case I8: return LLVMLoadI8VectorNodeGen.create(loadTarget, size); case I16: return LLVMLoadI16VectorNodeGen.create(loadTarget, size); case I32: return LLVMLoadI32VectorNodeGen.create(loadTarget, size); case I64: return LLVMLoadI64VectorNodeGen.create(loadTarget, size); case FLOAT: return LLVMLoadFloatVectorNodeGen.create(loadTarget, size); case DOUBLE: return LLVMLoadDoubleVectorNodeGen.create(loadTarget, size); default: throw new AssertionError(resultType); } } static LLVMExpressionNode createStore(LLVMParserRuntime runtime, LLVMExpressionNode pointerNode, LLVMExpressionNode valueNode, Type type, SourceSection source) { return createStore(runtime, pointerNode, valueNode, type, runtime.getByteSize(type), source); } private static LLVMExpressionNode createStore(LLVMParserRuntime runtime, LLVMExpressionNode pointerNode, LLVMExpressionNode valueNode, Type type, int size, SourceSection source) { if (type instanceof PrimitiveType) { switch (((PrimitiveType) type).getPrimitiveKind()) { case I1: return LLVMI1StoreNodeGen.create(source, pointerNode, valueNode); case I8: return LLVMI8StoreNodeGen.create(source, pointerNode, valueNode); case I16: return LLVMI16StoreNodeGen.create(source, pointerNode, valueNode); case I32: return LLVMI32StoreNodeGen.create(source, pointerNode, valueNode); case I64: return LLVMI64StoreNodeGen.create(source, pointerNode, valueNode); case FLOAT: return LLVMFloatStoreNodeGen.create(source, pointerNode, valueNode); case DOUBLE: return LLVMDoubleStoreNodeGen.create(source, pointerNode, valueNode); case X86_FP80: return LLVM80BitFloatStoreNodeGen.create(source, pointerNode, valueNode); default: throw new AssertionError(type); } } else if (type instanceof VariableBitWidthType) { return LLVMIVarBitStoreNodeGen.create((VariableBitWidthType) type, source, pointerNode, valueNode); } else if (Type.isFunctionOrFunctionPointer(type)) { return LLVMFunctionStoreNodeGen.create(type, source, pointerNode, valueNode); } else if (type instanceof StructureType || type instanceof ArrayType) { return LLVMStructStoreNodeGen.create(runtime.getNativeFunctions(), type, source, pointerNode, valueNode, size); } else if (type instanceof PointerType) { if (pointerNode instanceof LLVMAccessGlobalVariableStorageNode) { return LLVMGlobalVariableStoreNodeGen.create(((LLVMAccessGlobalVariableStorageNode) pointerNode).getDescriptor(), source, valueNode); } else { return LLVMAddressStoreNodeGen.create(type, source, pointerNode, valueNode); } } else if (type instanceof VectorType) { return LLVMStoreVectorNodeGen.create(type, source, pointerNode, valueNode); } else { throw new AssertionError(type); } } }