1
0
Fork 0
forked from suyu/suyu

glasm: Implement more GLASM composite instructions

This commit is contained in:
ReinUsesLisp 2021-05-09 04:01:17 -03:00 committed by ameerj
parent 01e18581b9
commit 939dab7120
2 changed files with 63 additions and 54 deletions

View file

@ -8,60 +8,71 @@
namespace Shader::Backend::GLASM { namespace Shader::Backend::GLASM {
namespace { namespace {
template <typename... Values> template <auto read_imm, char type, typename... Values>
void CompositeConstructU32(EmitContext& ctx, IR::Inst& inst, Values&&... elements) { void CompositeConstruct(EmitContext& ctx, IR::Inst& inst, Values&&... elements) {
const Register ret{ctx.reg_alloc.Define(inst)}; const Register ret{ctx.reg_alloc.Define(inst)};
if (std::ranges::any_of(std::array{elements...}, if (std::ranges::any_of(std::array{elements...},
[](const IR::Value& value) { return value.IsImmediate(); })) { [](const IR::Value& value) { return value.IsImmediate(); })) {
const std::array<u32, 4> values{(elements.IsImmediate() ? elements.U32() : 0)...}; using Type = std::invoke_result_t<decltype(read_imm), IR::Value>;
ctx.Add("MOV.U {},{{{},{},{},{}}};", ret, fmt::to_string(values[0]), const std::array<Type, 4> values{(elements.IsImmediate() ? (elements.*read_imm)() : 0)...};
ctx.Add("MOV.{} {},{{{},{},{},{}}};", type, ret, fmt::to_string(values[0]),
fmt::to_string(values[1]), fmt::to_string(values[2]), fmt::to_string(values[3])); fmt::to_string(values[1]), fmt::to_string(values[2]), fmt::to_string(values[3]));
} }
size_t index{}; size_t index{};
for (const IR::Value& element : {elements...}) { for (const IR::Value& element : {elements...}) {
if (!element.IsImmediate()) { if (!element.IsImmediate()) {
const ScalarU32 value{ctx.reg_alloc.Consume(element)}; const ScalarU32 value{ctx.reg_alloc.Consume(element)};
ctx.Add("MOV.U {}.{},{};", ret, "xyzw"[index], value); ctx.Add("MOV.{} {}.{},{};", type, ret, "xyzw"[index], value);
} }
++index; ++index;
} }
} }
void CompositeExtractU32(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { void CompositeExtract(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index, char type) {
const Register ret{ctx.reg_alloc.Define(inst)}; const Register ret{ctx.reg_alloc.Define(inst)};
if (ret == composite && index == 0) { if (ret == composite && index == 0) {
// No need to do anything here, the source and destination are the same register // No need to do anything here, the source and destination are the same register
return; return;
} }
ctx.Add("MOV.U {}.x,{}.{};", ret, composite, "xyzw"[index]); ctx.Add("MOV.{} {}.x,{}.{};", type, ret, composite, "xyzw"[index]);
}
template <typename ObjectType>
void CompositeInsert(EmitContext& ctx, IR::Inst& inst, Register composite, ObjectType object,
u32 index, char type) {
const Register ret{ctx.reg_alloc.Define(inst)};
if (ret != composite) {
ctx.Add("MOV.{} {},{};", type, ret, composite);
}
ctx.Add("MOV.{} {}.{},{};", type, ret, "xyzw"[index], object);
} }
} // Anonymous namespace } // Anonymous namespace
void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, void EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1,
const IR::Value& e2) { const IR::Value& e2) {
CompositeConstructU32(ctx, inst, e1, e2); CompositeConstruct<&IR::Value::U32, 'U'>(ctx, inst, e1, e2);
} }
void EmitCompositeConstructU32x3(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, void EmitCompositeConstructU32x3(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1,
const IR::Value& e2, const IR::Value& e3) { const IR::Value& e2, const IR::Value& e3) {
CompositeConstructU32(ctx, inst, e1, e2, e3); CompositeConstruct<&IR::Value::U32, 'U'>(ctx, inst, e1, e2, e3);
} }
void EmitCompositeConstructU32x4(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1, void EmitCompositeConstructU32x4(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1,
const IR::Value& e2, const IR::Value& e3, const IR::Value& e4) { const IR::Value& e2, const IR::Value& e3, const IR::Value& e4) {
CompositeConstructU32(ctx, inst, e1, e2, e3, e4); CompositeConstruct<&IR::Value::U32, 'U'>(ctx, inst, e1, e2, e3, e4);
} }
void EmitCompositeExtractU32x2(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { void EmitCompositeExtractU32x2(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) {
CompositeExtractU32(ctx, inst, composite, index); CompositeExtract(ctx, inst, composite, index, 'U');
} }
void EmitCompositeExtractU32x3(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { void EmitCompositeExtractU32x3(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) {
CompositeExtractU32(ctx, inst, composite, index); CompositeExtract(ctx, inst, composite, index, 'U');
} }
void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) { void EmitCompositeExtractU32x4(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) {
CompositeExtractU32(ctx, inst, composite, index); CompositeExtract(ctx, inst, composite, index, 'U');
} }
void EmitCompositeInsertU32x2([[maybe_unused]] EmitContext& ctx, void EmitCompositeInsertU32x2([[maybe_unused]] EmitContext& ctx,
@ -131,53 +142,46 @@ void EmitCompositeInsertF16x4([[maybe_unused]] EmitContext& ctx,
throw NotImplementedException("GLASM instruction"); throw NotImplementedException("GLASM instruction");
} }
void EmitCompositeConstructF32x2([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 e1, void EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1,
[[maybe_unused]] ScalarF32 e2) { const IR::Value& e2) {
throw NotImplementedException("GLASM instruction"); CompositeConstruct<&IR::Value::F32, 'F'>(ctx, inst, e1, e2);
} }
void EmitCompositeConstructF32x3([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 e1, void EmitCompositeConstructF32x3(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1,
[[maybe_unused]] ScalarF32 e2, [[maybe_unused]] ScalarF32 e3) { const IR::Value& e2, const IR::Value& e3) {
throw NotImplementedException("GLASM instruction"); CompositeConstruct<&IR::Value::F32, 'F'>(ctx, inst, e1, e2, e3);
} }
void EmitCompositeConstructF32x4([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 e1, void EmitCompositeConstructF32x4(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1,
[[maybe_unused]] ScalarF32 e2, [[maybe_unused]] ScalarF32 e3, const IR::Value& e2, const IR::Value& e3, const IR::Value& e4) {
[[maybe_unused]] ScalarF32 e4) { CompositeConstruct<&IR::Value::F32, 'F'>(ctx, inst, e1, e2, e3, e4);
throw NotImplementedException("GLASM instruction");
} }
void EmitCompositeExtractF32x2([[maybe_unused]] EmitContext& ctx, void EmitCompositeExtractF32x2(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) {
[[maybe_unused]] Register composite, [[maybe_unused]] u32 index) { CompositeExtract(ctx, inst, composite, index, 'F');
throw NotImplementedException("GLASM instruction");
} }
void EmitCompositeExtractF32x3([[maybe_unused]] EmitContext& ctx, void EmitCompositeExtractF32x3(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) {
[[maybe_unused]] Register composite, [[maybe_unused]] u32 index) { CompositeExtract(ctx, inst, composite, index, 'F');
throw NotImplementedException("GLASM instruction");
} }
void EmitCompositeExtractF32x4([[maybe_unused]] EmitContext& ctx, void EmitCompositeExtractF32x4(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index) {
[[maybe_unused]] Register composite, [[maybe_unused]] u32 index) { CompositeExtract(ctx, inst, composite, index, 'F');
throw NotImplementedException("GLASM instruction");
} }
void EmitCompositeInsertF32x2([[maybe_unused]] EmitContext& ctx, void EmitCompositeInsertF32x2(EmitContext& ctx, IR::Inst& inst, Register composite,
[[maybe_unused]] Register composite, ScalarF32 object, u32 index) {
[[maybe_unused]] ScalarF32 object, [[maybe_unused]] u32 index) { CompositeInsert(ctx, inst, composite, object, index, 'F');
throw NotImplementedException("GLASM instruction");
} }
void EmitCompositeInsertF32x3([[maybe_unused]] EmitContext& ctx, void EmitCompositeInsertF32x3(EmitContext& ctx, IR::Inst& inst, Register composite,
[[maybe_unused]] Register composite, ScalarF32 object, u32 index) {
[[maybe_unused]] ScalarF32 object, [[maybe_unused]] u32 index) { CompositeInsert(ctx, inst, composite, object, index, 'F');
throw NotImplementedException("GLASM instruction");
} }
void EmitCompositeInsertF32x4([[maybe_unused]] EmitContext& ctx, void EmitCompositeInsertF32x4(EmitContext& ctx, IR::Inst& inst, Register composite,
[[maybe_unused]] Register composite, ScalarF32 object, u32 index) {
[[maybe_unused]] ScalarF32 object, [[maybe_unused]] u32 index) { CompositeInsert(ctx, inst, composite, object, index, 'F');
throw NotImplementedException("GLASM instruction");
} }
void EmitCompositeConstructF64x2([[maybe_unused]] EmitContext& ctx) { void EmitCompositeConstructF64x2([[maybe_unused]] EmitContext& ctx) {

View file

@ -158,16 +158,21 @@ void EmitCompositeExtractF16x4(EmitContext& ctx, Register composite, u32 index);
void EmitCompositeInsertF16x2(EmitContext& ctx, Register composite, Register object, u32 index); void EmitCompositeInsertF16x2(EmitContext& ctx, Register composite, Register object, u32 index);
void EmitCompositeInsertF16x3(EmitContext& ctx, Register composite, Register object, u32 index); void EmitCompositeInsertF16x3(EmitContext& ctx, Register composite, Register object, u32 index);
void EmitCompositeInsertF16x4(EmitContext& ctx, Register composite, Register object, u32 index); void EmitCompositeInsertF16x4(EmitContext& ctx, Register composite, Register object, u32 index);
void EmitCompositeConstructF32x2(EmitContext& ctx, ScalarF32 e1, ScalarF32 e2); void EmitCompositeConstructF32x2(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1,
void EmitCompositeConstructF32x3(EmitContext& ctx, ScalarF32 e1, ScalarF32 e2, ScalarF32 e3); const IR::Value& e2);
void EmitCompositeConstructF32x4(EmitContext& ctx, ScalarF32 e1, ScalarF32 e2, ScalarF32 e3, void EmitCompositeConstructF32x3(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1,
ScalarF32 e4); const IR::Value& e2, const IR::Value& e3);
void EmitCompositeExtractF32x2(EmitContext& ctx, Register composite, u32 index); void EmitCompositeConstructF32x4(EmitContext& ctx, IR::Inst& inst, const IR::Value& e1,
void EmitCompositeExtractF32x3(EmitContext& ctx, Register composite, u32 index); const IR::Value& e2, const IR::Value& e3, const IR::Value& e4);
void EmitCompositeExtractF32x4(EmitContext& ctx, Register composite, u32 index); void EmitCompositeExtractF32x2(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index);
void EmitCompositeInsertF32x2(EmitContext& ctx, Register composite, ScalarF32 object, u32 index); void EmitCompositeExtractF32x3(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index);
void EmitCompositeInsertF32x3(EmitContext& ctx, Register composite, ScalarF32 object, u32 index); void EmitCompositeExtractF32x4(EmitContext& ctx, IR::Inst& inst, Register composite, u32 index);
void EmitCompositeInsertF32x4(EmitContext& ctx, Register composite, ScalarF32 object, u32 index); void EmitCompositeInsertF32x2(EmitContext& ctx, IR::Inst& inst, Register composite,
ScalarF32 object, u32 index);
void EmitCompositeInsertF32x3(EmitContext& ctx, IR::Inst& inst, Register composite,
ScalarF32 object, u32 index);
void EmitCompositeInsertF32x4(EmitContext& ctx, IR::Inst& inst, Register composite,
ScalarF32 object, u32 index);
void EmitCompositeConstructF64x2(EmitContext& ctx); void EmitCompositeConstructF64x2(EmitContext& ctx);
void EmitCompositeConstructF64x3(EmitContext& ctx); void EmitCompositeConstructF64x3(EmitContext& ctx);
void EmitCompositeConstructF64x4(EmitContext& ctx); void EmitCompositeConstructF64x4(EmitContext& ctx);