blob: 14bcefbc1748bc6b6e9d6b706bab59acc9247b24 [file] [log] [blame]
// Copyright 2021 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_TINT_WRITER_SPIRV_SCALAR_CONSTANT_H_
#define SRC_TINT_WRITER_SPIRV_SCALAR_CONSTANT_H_
#include <stdint.h>
#include <cstring>
#include <functional>
#include "src/tint/utils/hash.h"
// Forward declarations
namespace tint::sem {
class Call;
} // namespace tint::sem
namespace tint::writer::spirv {
/// ScalarConstant represents a scalar constant value
struct ScalarConstant {
/// The constant value
union Value {
/// The value as a bool
bool b;
/// The value as a uint32_t
uint32_t u32;
/// The value as a int32_t
int32_t i32;
/// The value as a float
float f32;
/// The value that is wide enough to encompass all other types (including
/// future 64-bit data types).
uint64_t u64;
};
/// The kind of constant
enum class Kind { kBool, kU32, kI32, kF32 };
/// Constructor
inline ScalarConstant() { value.u64 = 0; }
/// @param value the value of the constant
/// @returns a new ScalarConstant with the provided value and kind Kind::kU32
static inline ScalarConstant U32(uint32_t value) {
ScalarConstant c;
c.value.u32 = value;
c.kind = Kind::kU32;
return c;
}
/// @param value the value of the constant
/// @returns a new ScalarConstant with the provided value and kind Kind::kI32
static inline ScalarConstant I32(int32_t value) {
ScalarConstant c;
c.value.i32 = value;
c.kind = Kind::kI32;
return c;
}
/// @param value the value of the constant
/// @returns a new ScalarConstant with the provided value and kind Kind::kI32
static inline ScalarConstant F32(float value) {
ScalarConstant c;
c.value.f32 = value;
c.kind = Kind::kF32;
return c;
}
/// @param value the value of the constant
/// @returns a new ScalarConstant with the provided value and kind Kind::kBool
static inline ScalarConstant Bool(bool value) {
ScalarConstant c;
c.value.b = value;
c.kind = Kind::kBool;
return c;
}
/// Equality operator
/// @param rhs the ScalarConstant to compare against
/// @returns true if this ScalarConstant is equal to `rhs`
inline bool operator==(const ScalarConstant& rhs) const {
return value.u64 == rhs.value.u64 && kind == rhs.kind && is_spec_op == rhs.is_spec_op &&
constant_id == rhs.constant_id;
}
/// Inequality operator
/// @param rhs the ScalarConstant to compare against
/// @returns true if this ScalarConstant is not equal to `rhs`
inline bool operator!=(const ScalarConstant& rhs) const { return !(*this == rhs); }
/// @returns this ScalarConstant as a specialization op with the given
/// specialization constant identifier
/// @param id the constant identifier
ScalarConstant AsSpecOp(uint32_t id) const {
auto ret = *this;
ret.is_spec_op = true;
ret.constant_id = id;
return ret;
}
/// The constant value
Value value;
/// The constant value kind
Kind kind = Kind::kBool;
/// True if the constant is a specialization op
bool is_spec_op = false;
/// The identifier if a specialization op
uint32_t constant_id = 0;
};
} // namespace tint::writer::spirv
namespace std {
/// Custom std::hash specialization for tint::Symbol so symbols can be used as
/// keys for std::unordered_map and std::unordered_set.
template <>
class hash<tint::writer::spirv::ScalarConstant> {
public:
/// @param c the ScalarConstant
/// @return the Symbol internal value
inline std::size_t operator()(const tint::writer::spirv::ScalarConstant& c) const {
uint32_t value = 0;
std::memcpy(&value, &c.value, sizeof(value));
return tint::utils::Hash(value, c.kind);
}
};
} // namespace std
#endif // SRC_TINT_WRITER_SPIRV_SCALAR_CONSTANT_H_