blob: a8277f504aa431f9165229055550f3546e10127e [file] [log] [blame]
//===- SPIRVtype.cpp – Class to represent a SPIR-V type ----------*- C++ -*-===//
//
// The LLVM/SPIRV Translator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
// Copyright (c) 2014 Advanced Micro Devices, Inc. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal with the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimers.
// Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimers in the documentation
// and/or other materials provided with the distribution.
// Neither the names of Advanced Micro Devices, Inc., nor the names of its
// contributors may be used to endorse or promote products derived from this
// Software without specific prior written permission.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH
// THE SOFTWARE.
//
//===----------------------------------------------------------------------===//
/// \file
///
/// This file implements the types defined in SPIRV spec with op codes.
///
//===----------------------------------------------------------------------===//
#include "SPIRVType.h"
#include "SPIRVModule.h"
#include "SPIRVDecorate.h"
#include "SPIRVValue.h"
#include <cassert>
namespace SPIRV{
SPIRVType*
SPIRVType::getArrayElementType() const {
assert(OpCode == OpTypeArray && "Not array type");
return static_cast<const SPIRVTypeArray *const>(this)->getElementType();
}
uint64_t
SPIRVType::getArrayLength() const {
assert(OpCode == OpTypeArray && "Not array type");
return static_cast<const SPIRVTypeArray *const>(this)->getLength()->
getZExtIntValue();
}
SPIRVWord
SPIRVType::getBitWidth() const {
if (isTypeVector())
return getVectorComponentType()->getBitWidth();
if (isTypeBool())
return 1;
return isTypeInt()? getIntegerBitWidth() : getFloatBitWidth();
}
SPIRVWord
SPIRVType::getFloatBitWidth()const {
assert(OpCode == OpTypeFloat && "Not an integer type");
return static_cast<const SPIRVTypeFloat *const>(this)->getBitWidth();
}
SPIRVWord
SPIRVType::getIntegerBitWidth()const {
assert((OpCode == OpTypeInt || OpCode == OpTypeBool) &&
"Not an integer type");
if (isTypeBool())
return 1;
return static_cast<const SPIRVTypeInt *const>(this)->getBitWidth();
}
SPIRVType *
SPIRVType::getFunctionReturnType() const {
assert(OpCode == OpTypeFunction);
return static_cast<const SPIRVTypeFunction *const>(this)->getReturnType();
}
SPIRVType *
SPIRVType::getPointerElementType()const {
assert(OpCode == OpTypePointer && "Not a pointer type");
return static_cast<const SPIRVTypePointer *const>(this)->getElementType();
}
SPIRVStorageClassKind
SPIRVType::getPointerStorageClass() const {
assert(OpCode == OpTypePointer && "Not a pointer type");
return static_cast<const SPIRVTypePointer *const>(this)->getStorageClass();
}
SPIRVType*
SPIRVType::getStructMemberType(size_t Index) const {
assert(OpCode == OpTypeStruct && "Not struct type");
return static_cast<const SPIRVTypeStruct *const>(this)->getMemberType(Index);
}
SPIRVWord
SPIRVType::getStructMemberCount() const {
assert(OpCode == OpTypeStruct && "Not struct type");
return static_cast<const SPIRVTypeStruct *const>(this)->getMemberCount();
}
SPIRVWord
SPIRVType::getVectorComponentCount() const {
assert(OpCode == OpTypeVector && "Not vector type");
return static_cast<const SPIRVTypeVector *const>(this)->getComponentCount();
}
SPIRVType*
SPIRVType::getVectorComponentType() const {
assert(OpCode == OpTypeVector && "Not vector type");
return static_cast<const SPIRVTypeVector *const>(this)->getComponentType();
}
bool
SPIRVType::isTypeVoid() const {
return OpCode == OpTypeVoid;
}
bool
SPIRVType::isTypeArray() const {
return OpCode == OpTypeArray;
}
bool
SPIRVType::isTypeBool()const {
return OpCode == OpTypeBool;
}
bool
SPIRVType::isTypeComposite() const {
return isTypeVector() || isTypeArray() || isTypeStruct();
}
bool
SPIRVType::isTypeFloat(unsigned Bits)const {
return isType<SPIRVTypeFloat>(this, Bits);
}
bool
SPIRVType::isTypeOCLImage()const {
return isTypeImage() && static_cast<const SPIRVTypeImage *>(this)->
isOCLImage();
}
bool
SPIRVType::isTypePipe()const {
return OpCode == OpTypePipe;
}
bool
SPIRVType::isTypePipeStorage() const {
return OpCode == OpTypePipeStorage;
}
bool
SPIRVType::isTypeReserveId() const {
return OpCode == OpTypeReserveId;
}
bool
SPIRVType::isTypeInt(unsigned Bits)const {
return isType<SPIRVTypeInt>(this, Bits);
}
bool
SPIRVType::isTypePointer()const {
return OpCode == OpTypePointer;
}
bool
SPIRVType::isTypeOpaque()const {
return OpCode == OpTypeOpaque;
}
bool
SPIRVType::isTypeEvent()const {
return OpCode == OpTypeEvent;
}
bool
SPIRVType::isTypeDeviceEvent()const {
return OpCode == OpTypeDeviceEvent;
}
bool
SPIRVType::isTypeSampler()const {
return OpCode == OpTypeSampler;
}
bool
SPIRVType::isTypeImage()const {
return OpCode == OpTypeImage;
}
bool
SPIRVType::isTypeStruct() const {
return OpCode == OpTypeStruct;
}
bool
SPIRVType::isTypeVector() const {
return OpCode == OpTypeVector;
}
bool
SPIRVType::isTypeVectorBool() const {
return isTypeVector() && getVectorComponentType()->isTypeBool();
}
bool
SPIRVType::isTypeVectorInt() const {
return isTypeVector() && getVectorComponentType()->isTypeInt();
}
bool
SPIRVType::isTypeVectorFloat() const {
return isTypeVector() && getVectorComponentType()->isTypeFloat();
}
bool
SPIRVType::isTypeVectorOrScalarBool() const {
return isTypeBool() || isTypeVectorBool();
}
bool
SPIRVType::isTypeVectorOrScalarInt() const {
return isTypeInt() || isTypeVectorInt();
}
bool
SPIRVType::isTypeVectorOrScalarFloat() const {
return isTypeFloat() || isTypeVectorFloat();
}
bool
SPIRVTypeStruct::isPacked() const {
return hasDecorate(DecorationCPacked);
}
void
SPIRVTypeStruct::setPacked(bool Packed) {
if (Packed)
addDecorate(new SPIRVDecorate(DecorationCPacked, this));
else
eraseDecorate(DecorationCPacked);
}
SPIRVTypeArray::SPIRVTypeArray(SPIRVModule *M, SPIRVId TheId, SPIRVType *TheElemType,
SPIRVConstant* TheLength)
:SPIRVType(M, 4, OpTypeArray, TheId), ElemType(TheElemType),
Length(TheLength->getId()){
validate();
}
void
SPIRVTypeArray::validate()const {
SPIRVEntry::validate();
ElemType->validate();
assert(getValue(Length)->getType()->isTypeInt() &&
get<SPIRVConstant>(Length)->getZExtIntValue() > 0);
}
SPIRVConstant*
SPIRVTypeArray::getLength() const {
return get<SPIRVConstant>(Length);
}
_SPIRV_IMP_ENCDEC3(SPIRVTypeArray, Id, ElemType, Length)
void SPIRVTypeForwardPointer::encode(spv_ostream &O) const {
getEncoder(O) << Pointer << SC;
}
void SPIRVTypeForwardPointer::decode(std::istream &I) {
auto Decoder = getDecoder(I);
SPIRVId PointerId;
Decoder >> PointerId >> SC;
}
}