/*
* 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);
}
}
}