mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-14 00:56:05 +00:00
tint/resolver: Add builtin_structs.h / .cc
Contains the builtin structure creation logic moved out from intrinsic_table.cc. Bug: chromium:1430309 Change-Id: I2207f9ae42c6d7343c2f2ffa81effde59e6023fe Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/129481 Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Commit-Queue: Ben Clayton <bclayton@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
aae9f6bc5f
commit
d3b09b90e3
@ -281,6 +281,8 @@ libtint_source_set("libtint_program_src") {
|
|||||||
"clone_context.cc",
|
"clone_context.cc",
|
||||||
"program.cc",
|
"program.cc",
|
||||||
"program_builder.cc",
|
"program_builder.cc",
|
||||||
|
"resolver/builtin_structs.cc",
|
||||||
|
"resolver/builtin_structs.h",
|
||||||
"resolver/const_eval.cc",
|
"resolver/const_eval.cc",
|
||||||
"resolver/const_eval.h",
|
"resolver/const_eval.h",
|
||||||
"resolver/ctor_conv_intrinsic.cc",
|
"resolver/ctor_conv_intrinsic.cc",
|
||||||
|
@ -264,6 +264,8 @@ list(APPEND TINT_LIB_SRCS
|
|||||||
reflection.h
|
reflection.h
|
||||||
reader/reader.cc
|
reader/reader.cc
|
||||||
reader/reader.h
|
reader/reader.h
|
||||||
|
resolver/builtin_structs.cc
|
||||||
|
resolver/builtin_structs.h
|
||||||
resolver/const_eval.cc
|
resolver/const_eval.cc
|
||||||
resolver/const_eval.h
|
resolver/const_eval.h
|
||||||
resolver/dependency_graph.cc
|
resolver/dependency_graph.cc
|
||||||
|
194
src/tint/resolver/builtin_structs.cc
Normal file
194
src/tint/resolver/builtin_structs.cc
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
// Copyright 2023 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.
|
||||||
|
|
||||||
|
#include "src/tint/resolver/builtin_structs.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "src/tint/program_builder.h"
|
||||||
|
#include "src/tint/switch.h"
|
||||||
|
#include "src/tint/type/abstract_float.h"
|
||||||
|
#include "src/tint/type/abstract_int.h"
|
||||||
|
#include "src/tint/type/vector.h"
|
||||||
|
|
||||||
|
namespace tint::resolver {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct NameAndType {
|
||||||
|
std::string name;
|
||||||
|
const type::Type* type;
|
||||||
|
};
|
||||||
|
|
||||||
|
sem::Struct* BuildStruct(ProgramBuilder& b,
|
||||||
|
std::string name,
|
||||||
|
std::initializer_list<NameAndType> member_names_and_types) {
|
||||||
|
uint32_t offset = 0;
|
||||||
|
uint32_t max_align = 0;
|
||||||
|
utils::Vector<const sem::StructMember*, 4> members;
|
||||||
|
for (auto& m : member_names_and_types) {
|
||||||
|
uint32_t align = std::max<uint32_t>(m.type->Align(), 1);
|
||||||
|
uint32_t size = m.type->Size();
|
||||||
|
offset = utils::RoundUp(align, offset);
|
||||||
|
max_align = std::max(max_align, align);
|
||||||
|
members.Push(b.create<sem::StructMember>(
|
||||||
|
/* declaration */ nullptr,
|
||||||
|
/* source */ Source{},
|
||||||
|
/* name */ b.Sym(m.name),
|
||||||
|
/* type */ m.type,
|
||||||
|
/* index */ static_cast<uint32_t>(members.Length()),
|
||||||
|
/* offset */ offset,
|
||||||
|
/* align */ align,
|
||||||
|
/* size */ size,
|
||||||
|
/* location */ std::nullopt));
|
||||||
|
offset += size;
|
||||||
|
}
|
||||||
|
uint32_t size_without_padding = offset;
|
||||||
|
uint32_t size_with_padding = utils::RoundUp(max_align, offset);
|
||||||
|
return b.create<sem::Struct>(
|
||||||
|
/* declaration */ nullptr,
|
||||||
|
/* source */ Source{},
|
||||||
|
/* name */ b.Sym(name),
|
||||||
|
/* members */ std::move(members),
|
||||||
|
/* align */ max_align,
|
||||||
|
/* size */ size_with_padding,
|
||||||
|
/* size_no_padding */ size_without_padding);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
sem::Struct* CreateModfResult(ProgramBuilder& b, const type::Type* ty) {
|
||||||
|
return Switch(
|
||||||
|
ty,
|
||||||
|
[&](const type::F32*) {
|
||||||
|
return BuildStruct(b, "__modf_result_f32", {{"fract", ty}, {"whole", ty}});
|
||||||
|
}, //
|
||||||
|
[&](const type::F16*) {
|
||||||
|
return BuildStruct(b, "__modf_result_f16", {{"fract", ty}, {"whole", ty}});
|
||||||
|
},
|
||||||
|
[&](const type::AbstractFloat*) {
|
||||||
|
auto* abstract =
|
||||||
|
BuildStruct(b, "__modf_result_abstract", {{"fract", ty}, {"whole", ty}});
|
||||||
|
auto* f32 = b.create<type::F32>();
|
||||||
|
auto* f16 = b.create<type::F16>();
|
||||||
|
abstract->SetConcreteTypes(utils::Vector{
|
||||||
|
BuildStruct(b, "__modf_result_f32", {{"fract", f32}, {"whole", f32}}),
|
||||||
|
BuildStruct(b, "__modf_result_f16", {{"fract", f16}, {"whole", f16}}),
|
||||||
|
});
|
||||||
|
return abstract;
|
||||||
|
},
|
||||||
|
[&](const type::Vector* vec) {
|
||||||
|
auto width = vec->Width();
|
||||||
|
auto prefix = "__modf_result_vec" + std::to_string(width);
|
||||||
|
return Switch(
|
||||||
|
vec->type(), //
|
||||||
|
[&](const type::F32*) {
|
||||||
|
return BuildStruct(b, prefix + "_f32", {{"fract", vec}, {"whole", vec}});
|
||||||
|
},
|
||||||
|
[&](const type::F16*) {
|
||||||
|
return BuildStruct(b, prefix + "_f16", {{"fract", vec}, {"whole", vec}});
|
||||||
|
},
|
||||||
|
[&](const type::AbstractFloat*) {
|
||||||
|
auto* vec_f32 = b.create<type::Vector>(b.create<type::F32>(), width);
|
||||||
|
auto* vec_f16 = b.create<type::Vector>(b.create<type::F16>(), width);
|
||||||
|
auto* abstract =
|
||||||
|
BuildStruct(b, prefix + "_abstract", {{"fract", vec}, {"whole", vec}});
|
||||||
|
abstract->SetConcreteTypes(utils::Vector{
|
||||||
|
BuildStruct(b, prefix + "_f32", {{"fract", vec_f32}, {"whole", vec_f32}}),
|
||||||
|
BuildStruct(b, prefix + "_f16", {{"fract", vec_f16}, {"whole", vec_f16}}),
|
||||||
|
});
|
||||||
|
return abstract;
|
||||||
|
},
|
||||||
|
[&](Default) {
|
||||||
|
TINT_ICE(Resolver, b.Diagnostics())
|
||||||
|
<< "unhandled modf type: " << b.FriendlyName(ty);
|
||||||
|
return nullptr;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[&](Default) {
|
||||||
|
TINT_ICE(Resolver, b.Diagnostics()) << "unhandled modf type: " << b.FriendlyName(ty);
|
||||||
|
return nullptr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sem::Struct* CreateFrexpResult(ProgramBuilder& b, const type::Type* ty) {
|
||||||
|
return Switch(
|
||||||
|
ty, //
|
||||||
|
[&](const type::F32*) {
|
||||||
|
auto* i32 = b.create<type::I32>();
|
||||||
|
return BuildStruct(b, "__frexp_result_f32", {{"fract", ty}, {"exp", i32}});
|
||||||
|
},
|
||||||
|
[&](const type::F16*) {
|
||||||
|
auto* i32 = b.create<type::I32>();
|
||||||
|
return BuildStruct(b, "__frexp_result_f16", {{"fract", ty}, {"exp", i32}});
|
||||||
|
},
|
||||||
|
[&](const type::AbstractFloat*) {
|
||||||
|
auto* f32 = b.create<type::F32>();
|
||||||
|
auto* f16 = b.create<type::F16>();
|
||||||
|
auto* i32 = b.create<type::I32>();
|
||||||
|
auto* ai = b.create<type::AbstractInt>();
|
||||||
|
auto* abstract =
|
||||||
|
BuildStruct(b, "__frexp_result_abstract", {{"fract", ty}, {"exp", ai}});
|
||||||
|
abstract->SetConcreteTypes(utils::Vector{
|
||||||
|
BuildStruct(b, "__frexp_result_f32", {{"fract", f32}, {"exp", i32}}),
|
||||||
|
BuildStruct(b, "__frexp_result_f16", {{"fract", f16}, {"exp", i32}}),
|
||||||
|
});
|
||||||
|
return abstract;
|
||||||
|
},
|
||||||
|
[&](const type::Vector* vec) {
|
||||||
|
auto width = vec->Width();
|
||||||
|
auto prefix = "__frexp_result_vec" + std::to_string(width);
|
||||||
|
return Switch(
|
||||||
|
vec->type(), //
|
||||||
|
[&](const type::F32*) {
|
||||||
|
auto* vec_i32 = b.create<type::Vector>(b.create<type::I32>(), width);
|
||||||
|
return BuildStruct(b, prefix + "_f32", {{"fract", ty}, {"exp", vec_i32}});
|
||||||
|
},
|
||||||
|
[&](const type::F16*) {
|
||||||
|
auto* vec_i32 = b.create<type::Vector>(b.create<type::I32>(), width);
|
||||||
|
return BuildStruct(b, prefix + "_f16", {{"fract", ty}, {"exp", vec_i32}});
|
||||||
|
},
|
||||||
|
[&](const type::AbstractFloat*) {
|
||||||
|
auto* vec_f32 = b.create<type::Vector>(b.create<type::F32>(), width);
|
||||||
|
auto* vec_f16 = b.create<type::Vector>(b.create<type::F16>(), width);
|
||||||
|
auto* vec_i32 = b.create<type::Vector>(b.create<type::I32>(), width);
|
||||||
|
auto* vec_ai = b.create<type::Vector>(b.create<type::AbstractInt>(), width);
|
||||||
|
auto* abstract =
|
||||||
|
BuildStruct(b, prefix + "_abstract", {{"fract", ty}, {"exp", vec_ai}});
|
||||||
|
abstract->SetConcreteTypes(utils::Vector{
|
||||||
|
BuildStruct(b, prefix + "_f32", {{"fract", vec_f32}, {"exp", vec_i32}}),
|
||||||
|
BuildStruct(b, prefix + "_f16", {{"fract", vec_f16}, {"exp", vec_i32}}),
|
||||||
|
});
|
||||||
|
return abstract;
|
||||||
|
},
|
||||||
|
[&](Default) {
|
||||||
|
TINT_ICE(Resolver, b.Diagnostics())
|
||||||
|
<< "unhandled frexp type: " << b.FriendlyName(ty);
|
||||||
|
return nullptr;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[&](Default) {
|
||||||
|
TINT_ICE(Resolver, b.Diagnostics()) << "unhandled frexp type: " << b.FriendlyName(ty);
|
||||||
|
return nullptr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
sem::Struct* CreateAtomicCompareExchangeResult(ProgramBuilder& b, const type::Type* ty) {
|
||||||
|
return BuildStruct(
|
||||||
|
b, "__atomic_compare_exchange_result" + ty->FriendlyName(),
|
||||||
|
{{"old_value", const_cast<type::Type*>(ty)}, {"exchanged", b.create<type::Bool>()}});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace tint::resolver
|
51
src/tint/resolver/builtin_structs.h
Normal file
51
src/tint/resolver/builtin_structs.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 2023 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_RESOLVER_BUILTIN_STRUCTS_H_
|
||||||
|
#define SRC_TINT_RESOLVER_BUILTIN_STRUCTS_H_
|
||||||
|
|
||||||
|
// Forward declarations
|
||||||
|
namespace tint {
|
||||||
|
class ProgramBuilder;
|
||||||
|
} // namespace tint
|
||||||
|
namespace tint::sem {
|
||||||
|
class Struct;
|
||||||
|
} // namespace tint::sem
|
||||||
|
namespace tint::type {
|
||||||
|
class Type;
|
||||||
|
} // namespace tint::type
|
||||||
|
|
||||||
|
namespace tint::resolver {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ty the type of the `fract` and `whole` struct members.
|
||||||
|
* @return the builtin struct type for a modf() builtin call.
|
||||||
|
*/
|
||||||
|
sem::Struct* CreateModfResult(ProgramBuilder& b, const type::Type* ty);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fract the type of the `fract` struct member.
|
||||||
|
* @return the builtin struct type for a frexp() builtin call.
|
||||||
|
*/
|
||||||
|
sem::Struct* CreateFrexpResult(ProgramBuilder& b, const type::Type* fract);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ty the type of the `old_value` struct member.
|
||||||
|
* @return the builtin struct type for a atomic_compare_exchange() builtin call.
|
||||||
|
*/
|
||||||
|
sem::Struct* CreateAtomicCompareExchangeResult(ProgramBuilder& b, const type::Type* ty);
|
||||||
|
|
||||||
|
} // namespace tint::resolver
|
||||||
|
|
||||||
|
#endif // SRC_TINT_RESOLVER_BUILTIN_STRUCTS_H_
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "src/tint/ast/binary_expression.h"
|
#include "src/tint/ast/binary_expression.h"
|
||||||
#include "src/tint/program_builder.h"
|
#include "src/tint/program_builder.h"
|
||||||
|
#include "src/tint/resolver/builtin_structs.h"
|
||||||
#include "src/tint/sem/evaluation_stage.h"
|
#include "src/tint/sem/evaluation_stage.h"
|
||||||
#include "src/tint/sem/pipeline_stage_set.h"
|
#include "src/tint/sem/pipeline_stage_set.h"
|
||||||
#include "src/tint/sem/value_constructor.h"
|
#include "src/tint/sem/value_constructor.h"
|
||||||
@ -819,170 +820,26 @@ bool match_atomic_compare_exchange_result(MatchState&, const type::Type* ty, con
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct NameAndType {
|
|
||||||
std::string name;
|
|
||||||
const type::Type* type;
|
|
||||||
};
|
|
||||||
sem::Struct* build_struct(ProgramBuilder& b,
|
|
||||||
std::string name,
|
|
||||||
std::initializer_list<NameAndType> member_names_and_types) {
|
|
||||||
uint32_t offset = 0;
|
|
||||||
uint32_t max_align = 0;
|
|
||||||
utils::Vector<const sem::StructMember*, 4> members;
|
|
||||||
for (auto& m : member_names_and_types) {
|
|
||||||
uint32_t align = std::max<uint32_t>(m.type->Align(), 1);
|
|
||||||
uint32_t size = m.type->Size();
|
|
||||||
offset = utils::RoundUp(align, offset);
|
|
||||||
max_align = std::max(max_align, align);
|
|
||||||
members.Push(b.create<sem::StructMember>(
|
|
||||||
/* declaration */ nullptr,
|
|
||||||
/* source */ Source{},
|
|
||||||
/* name */ b.Sym(m.name),
|
|
||||||
/* type */ m.type,
|
|
||||||
/* index */ static_cast<uint32_t>(members.Length()),
|
|
||||||
/* offset */ offset,
|
|
||||||
/* align */ align,
|
|
||||||
/* size */ size,
|
|
||||||
/* location */ std::nullopt));
|
|
||||||
offset += size;
|
|
||||||
}
|
|
||||||
uint32_t size_without_padding = offset;
|
|
||||||
uint32_t size_with_padding = utils::RoundUp(max_align, offset);
|
|
||||||
return b.create<sem::Struct>(
|
|
||||||
/* declaration */ nullptr,
|
|
||||||
/* source */ Source{},
|
|
||||||
/* name */ b.Sym(name),
|
|
||||||
/* members */ std::move(members),
|
|
||||||
/* align */ max_align,
|
|
||||||
/* size */ size_with_padding,
|
|
||||||
/* size_no_padding */ size_without_padding);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sem::Struct* build_modf_result(MatchState& state, const type::Type* el) {
|
const sem::Struct* build_modf_result(MatchState& state, const type::Type* el) {
|
||||||
auto build_f32 = [&] {
|
return CreateModfResult(state.builder, el);
|
||||||
auto* ty = state.builder.create<type::F32>();
|
|
||||||
return build_struct(state.builder, "__modf_result_f32", {{"fract", ty}, {"whole", ty}});
|
|
||||||
};
|
|
||||||
auto build_f16 = [&] {
|
|
||||||
auto* ty = state.builder.create<type::F16>();
|
|
||||||
return build_struct(state.builder, "__modf_result_f16", {{"fract", ty}, {"whole", ty}});
|
|
||||||
};
|
|
||||||
|
|
||||||
return Switch(
|
|
||||||
el, //
|
|
||||||
[&](const type::F32*) { return build_f32(); }, //
|
|
||||||
[&](const type::F16*) { return build_f16(); }, //
|
|
||||||
[&](const type::AbstractFloat*) {
|
|
||||||
auto* abstract = build_struct(state.builder, "__modf_result_abstract",
|
|
||||||
{{"fract", el}, {"whole", el}});
|
|
||||||
abstract->SetConcreteTypes(utils::Vector{build_f32(), build_f16()});
|
|
||||||
return abstract;
|
|
||||||
},
|
|
||||||
[&](Default) {
|
|
||||||
TINT_ICE(Resolver, state.builder.Diagnostics())
|
|
||||||
<< "unhandled modf type: " << state.builder.FriendlyName(el);
|
|
||||||
return nullptr;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Struct* build_modf_result_vec(MatchState& state, Number& n, const type::Type* el) {
|
const sem::Struct* build_modf_result_vec(MatchState& state, Number& n, const type::Type* el) {
|
||||||
auto prefix = "__modf_result_vec" + std::to_string(n.Value());
|
auto* vec = state.builder.create<type::Vector>(el, n.Value());
|
||||||
auto build_f32 = [&] {
|
return CreateModfResult(state.builder, vec);
|
||||||
auto* vec =
|
|
||||||
state.builder.create<type::Vector>(state.builder.create<type::F32>(), n.Value());
|
|
||||||
return build_struct(state.builder, prefix + "_f32", {{"fract", vec}, {"whole", vec}});
|
|
||||||
};
|
|
||||||
auto build_f16 = [&] {
|
|
||||||
auto* vec =
|
|
||||||
state.builder.create<type::Vector>(state.builder.create<type::F16>(), n.Value());
|
|
||||||
return build_struct(state.builder, prefix + "_f16", {{"fract", vec}, {"whole", vec}});
|
|
||||||
};
|
|
||||||
|
|
||||||
return Switch(
|
|
||||||
el, //
|
|
||||||
[&](const type::F32*) { return build_f32(); }, //
|
|
||||||
[&](const type::F16*) { return build_f16(); }, //
|
|
||||||
[&](const type::AbstractFloat*) {
|
|
||||||
auto* vec = state.builder.create<type::Vector>(el, n.Value());
|
|
||||||
auto* abstract =
|
|
||||||
build_struct(state.builder, prefix + "_abstract", {{"fract", vec}, {"whole", vec}});
|
|
||||||
abstract->SetConcreteTypes(utils::Vector{build_f32(), build_f16()});
|
|
||||||
return abstract;
|
|
||||||
},
|
|
||||||
[&](Default) {
|
|
||||||
TINT_ICE(Resolver, state.builder.Diagnostics())
|
|
||||||
<< "unhandled modf type: " << state.builder.FriendlyName(el);
|
|
||||||
return nullptr;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Struct* build_frexp_result(MatchState& state, const type::Type* el) {
|
const sem::Struct* build_frexp_result(MatchState& state, const type::Type* el) {
|
||||||
auto build_f32 = [&] {
|
return CreateFrexpResult(state.builder, el);
|
||||||
auto* f = state.builder.create<type::F32>();
|
|
||||||
auto* i = state.builder.create<type::I32>();
|
|
||||||
return build_struct(state.builder, "__frexp_result_f32", {{"fract", f}, {"exp", i}});
|
|
||||||
};
|
|
||||||
auto build_f16 = [&] {
|
|
||||||
auto* f = state.builder.create<type::F16>();
|
|
||||||
auto* i = state.builder.create<type::I32>();
|
|
||||||
return build_struct(state.builder, "__frexp_result_f16", {{"fract", f}, {"exp", i}});
|
|
||||||
};
|
|
||||||
|
|
||||||
return Switch(
|
|
||||||
el, //
|
|
||||||
[&](const type::F32*) { return build_f32(); }, //
|
|
||||||
[&](const type::F16*) { return build_f16(); }, //
|
|
||||||
[&](const type::AbstractFloat*) {
|
|
||||||
auto* i = state.builder.create<type::AbstractInt>();
|
|
||||||
auto* abstract =
|
|
||||||
build_struct(state.builder, "__frexp_result_abstract", {{"fract", el}, {"exp", i}});
|
|
||||||
abstract->SetConcreteTypes(utils::Vector{build_f32(), build_f16()});
|
|
||||||
return abstract;
|
|
||||||
},
|
|
||||||
[&](Default) {
|
|
||||||
TINT_ICE(Resolver, state.builder.Diagnostics())
|
|
||||||
<< "unhandled frexp type: " << state.builder.FriendlyName(el);
|
|
||||||
return nullptr;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Struct* build_frexp_result_vec(MatchState& state, Number& n, const type::Type* el) {
|
const sem::Struct* build_frexp_result_vec(MatchState& state, Number& n, const type::Type* el) {
|
||||||
auto prefix = "__frexp_result_vec" + std::to_string(n.Value());
|
auto* vec = state.builder.create<type::Vector>(el, n.Value());
|
||||||
auto build_f32 = [&] {
|
return CreateFrexpResult(state.builder, vec);
|
||||||
auto* f = state.builder.create<type::Vector>(state.builder.create<type::F32>(), n.Value());
|
|
||||||
auto* e = state.builder.create<type::Vector>(state.builder.create<type::I32>(), n.Value());
|
|
||||||
return build_struct(state.builder, prefix + "_f32", {{"fract", f}, {"exp", e}});
|
|
||||||
};
|
|
||||||
auto build_f16 = [&] {
|
|
||||||
auto* f = state.builder.create<type::Vector>(state.builder.create<type::F16>(), n.Value());
|
|
||||||
auto* e = state.builder.create<type::Vector>(state.builder.create<type::I32>(), n.Value());
|
|
||||||
return build_struct(state.builder, prefix + "_f16", {{"fract", f}, {"exp", e}});
|
|
||||||
};
|
|
||||||
|
|
||||||
return Switch(
|
|
||||||
el, //
|
|
||||||
[&](const type::F32*) { return build_f32(); }, //
|
|
||||||
[&](const type::F16*) { return build_f16(); }, //
|
|
||||||
[&](const type::AbstractFloat*) {
|
|
||||||
auto* f = state.builder.create<type::Vector>(el, n.Value());
|
|
||||||
auto* e = state.builder.create<type::Vector>(state.builder.create<type::AbstractInt>(),
|
|
||||||
n.Value());
|
|
||||||
auto* abstract =
|
|
||||||
build_struct(state.builder, prefix + "_abstract", {{"fract", f}, {"exp", e}});
|
|
||||||
abstract->SetConcreteTypes(utils::Vector{build_f32(), build_f16()});
|
|
||||||
return abstract;
|
|
||||||
},
|
|
||||||
[&](Default) {
|
|
||||||
TINT_ICE(Resolver, state.builder.Diagnostics())
|
|
||||||
<< "unhandled frexp type: " << state.builder.FriendlyName(el);
|
|
||||||
return nullptr;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sem::Struct* build_atomic_compare_exchange_result(MatchState& state, const type::Type* ty) {
|
const sem::Struct* build_atomic_compare_exchange_result(MatchState& state, const type::Type* ty) {
|
||||||
return build_struct(state.builder, "__atomic_compare_exchange_result" + ty->FriendlyName(),
|
return CreateAtomicCompareExchangeResult(state.builder, ty);
|
||||||
{{"old_value", const_cast<type::Type*>(ty)},
|
|
||||||
{"exchanged", state.builder.create<type::Bool>()}});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParameterInfo describes a parameter
|
/// ParameterInfo describes a parameter
|
||||||
|
Loading…
x
Reference in New Issue
Block a user