summaryrefslogtreecommitdiffstats
path: root/src/shader_recompiler/backend/glasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/shader_recompiler/backend/glasm')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm.cpp3
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp8
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp231
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp50
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_instructions.h122
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp10
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp192
-rw-r--r--src/shader_recompiler/backend/glasm/reg_alloc.cpp4
-rw-r--r--src/shader_recompiler/backend/glasm/reg_alloc.h13
9 files changed, 351 insertions, 282 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm.cpp b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
index 9db6eb4a0..0e4b189c9 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm.cpp
@@ -59,6 +59,9 @@ struct RegWrapper {
case Type::F32:
ctx.Add("MOV.F {}.x,{};", reg, value.imm_f32);
break;
+ case Type::U64:
+ ctx.Add("MOV.U64 {}.x,{};", reg, value.imm_u64);
+ break;
case Type::F64:
ctx.Add("MOV.F64 {}.x,{};", reg, value.imm_f64);
break;
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp
index eb6140954..a6c66b826 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_bitwise_conversion.cpp
@@ -48,12 +48,12 @@ void EmitBitCastF64U64(EmitContext&, IR::Inst& inst, const IR::Value& value) {
Alias(inst, value);
}
-void EmitPackUint2x32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
- throw NotImplementedException("GLASM instruction");
+void EmitPackUint2x32(EmitContext& ctx, IR::Inst& inst, Register value) {
+ ctx.LongAdd("PK64.U {}.x,{};", inst, value);
}
-void EmitUnpackUint2x32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
- throw NotImplementedException("GLASM instruction");
+void EmitUnpackUint2x32(EmitContext& ctx, IR::Inst& inst, Register value) {
+ ctx.Add("UP64.U {}.xy,{}.x;", inst, value);
}
void EmitPackFloat2x16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp
index e69de29bb..ccdf1cbc8 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_convert.cpp
@@ -0,0 +1,231 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <string_view>
+
+#include "shader_recompiler/backend/glasm/emit_context.h"
+#include "shader_recompiler/backend/glasm/emit_glasm_instructions.h"
+#include "shader_recompiler/frontend/ir/modifiers.h"
+#include "shader_recompiler/frontend/ir/value.h"
+
+namespace Shader::Backend::GLASM {
+namespace {
+std::string_view FpRounding(IR::FpRounding fp_rounding) {
+ switch (fp_rounding) {
+ case IR::FpRounding::DontCare:
+ return "";
+ case IR::FpRounding::RN:
+ return ".ROUND";
+ case IR::FpRounding::RZ:
+ return ".TRUNC";
+ case IR::FpRounding::RM:
+ return ".FLR";
+ case IR::FpRounding::RP:
+ return ".CEIL";
+ }
+ throw InvalidArgument("Invalid floating-point rounding {}", fp_rounding);
+}
+
+template <typename InputType>
+void Convert(EmitContext& ctx, IR::Inst& inst, InputType value, std::string_view dest,
+ std::string_view src, bool is_long_result) {
+ const std::string_view fp_rounding{FpRounding(inst.Flags<IR::FpControl>().rounding)};
+ const auto ret{is_long_result ? ctx.reg_alloc.LongDefine(inst) : ctx.reg_alloc.Define(inst)};
+ ctx.Add("CVT.{}.{}{} {}.x,{};", dest, src, fp_rounding, ret, value);
+}
+} // Anonymous namespace
+
+void EmitConvertS16F16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "S16", "F16", false);
+}
+
+void EmitConvertS16F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ Convert(ctx, inst, value, "S16", "F32", false);
+}
+
+void EmitConvertS16F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
+ Convert(ctx, inst, value, "S16", "F64", false);
+}
+
+void EmitConvertS32F16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "S32", "F16", false);
+}
+
+void EmitConvertS32F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ Convert(ctx, inst, value, "S32", "F32", false);
+}
+
+void EmitConvertS32F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
+ Convert(ctx, inst, value, "S32", "F64", false);
+}
+
+void EmitConvertS64F16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "S64", "F16", true);
+}
+
+void EmitConvertS64F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ Convert(ctx, inst, value, "S64", "F32", true);
+}
+
+void EmitConvertS64F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
+ Convert(ctx, inst, value, "S64", "F64", true);
+}
+
+void EmitConvertU16F16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "U16", "F16", false);
+}
+
+void EmitConvertU16F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ Convert(ctx, inst, value, "U16", "F32", false);
+}
+
+void EmitConvertU16F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
+ Convert(ctx, inst, value, "U16", "F64", false);
+}
+
+void EmitConvertU32F16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "U32", "F16", false);
+}
+
+void EmitConvertU32F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ Convert(ctx, inst, value, "U32", "F32", false);
+}
+
+void EmitConvertU32F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
+ Convert(ctx, inst, value, "U32", "F64", false);
+}
+
+void EmitConvertU64F16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "U64", "F16", true);
+}
+
+void EmitConvertU64F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ Convert(ctx, inst, value, "U64", "F32", true);
+}
+
+void EmitConvertU64F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
+ Convert(ctx, inst, value, "U64", "F64", true);
+}
+
+void EmitConvertU64U32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value) {
+ Convert(ctx, inst, value, "U64", "U32", true);
+}
+
+void EmitConvertU32U64(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "U32", "U64", false);
+}
+
+void EmitConvertF16F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ Convert(ctx, inst, value, "F16", "F32", false);
+}
+
+void EmitConvertF32F16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F32", "F16", false);
+}
+
+void EmitConvertF32F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
+ Convert(ctx, inst, value, "F32", "F64", false);
+}
+
+void EmitConvertF64F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ Convert(ctx, inst, value, "F64", "F32", true);
+}
+
+void EmitConvertF16S8(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F16", "S8", false);
+}
+
+void EmitConvertF16S16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F16", "S16", false);
+}
+
+void EmitConvertF16S32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) {
+ Convert(ctx, inst, value, "F16", "S32", false);
+}
+
+void EmitConvertF16S64(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F16", "S64", false);
+}
+
+void EmitConvertF16U8(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F16", "U8", false);
+}
+
+void EmitConvertF16U16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F16", "U16", false);
+}
+
+void EmitConvertF16U32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value) {
+ Convert(ctx, inst, value, "F16", "U32", false);
+}
+
+void EmitConvertF16U64(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F16", "U64", false);
+}
+
+void EmitConvertF32S8(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F32", "S8", false);
+}
+
+void EmitConvertF32S16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F32", "S16", false);
+}
+
+void EmitConvertF32S32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) {
+ Convert(ctx, inst, value, "F32", "S32", false);
+}
+
+void EmitConvertF32S64(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F32", "S64", false);
+}
+
+void EmitConvertF32U8(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F32", "U8", false);
+}
+
+void EmitConvertF32U16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F32", "U16", false);
+}
+
+void EmitConvertF32U32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value) {
+ Convert(ctx, inst, value, "F32", "U32", false);
+}
+
+void EmitConvertF32U64(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F32", "U64", false);
+}
+
+void EmitConvertF64S8(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F64", "S8", true);
+}
+
+void EmitConvertF64S16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F64", "S16", true);
+}
+
+void EmitConvertF64S32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) {
+ Convert(ctx, inst, value, "F64", "S32", true);
+}
+
+void EmitConvertF64S64(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F64", "S64", true);
+}
+
+void EmitConvertF64U8(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F64", "U8", true);
+}
+
+void EmitConvertF64U16(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F64", "U16", true);
+}
+
+void EmitConvertF64U32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value) {
+ Convert(ctx, inst, value, "F64", "U32", true);
+}
+
+void EmitConvertF64U64(EmitContext& ctx, IR::Inst& inst, Register value) {
+ Convert(ctx, inst, value, "F64", "U64", true);
+}
+
+} // namespace Shader::Backend::GLASM
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp
index aab506109..2aee5a56c 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_floating_point.cpp
@@ -169,62 +169,68 @@ void EmitFPClamp16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register
throw NotImplementedException("GLASM instruction");
}
-void EmitFPClamp32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value,
- [[maybe_unused]] ScalarF32 min_value, [[maybe_unused]] ScalarF32 max_value) {
- throw NotImplementedException("GLASM instruction");
+void EmitFPClamp32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value, ScalarF32 min_value,
+ ScalarF32 max_value) {
+ const Register ret{ctx.reg_alloc.Define(inst)};
+ ctx.Add("MIN.F {}.x,{},{};"
+ "MAX.F {}.x,{},{};",
+ ret, max_value, value, ret, ret, min_value);
}
-void EmitFPClamp64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value,
- [[maybe_unused]] Register min_value, [[maybe_unused]] Register max_value) {
- throw NotImplementedException("GLASM instruction");
+void EmitFPClamp64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value, ScalarF64 min_value,
+ ScalarF64 max_value) {
+ const Register ret{ctx.reg_alloc.LongDefine(inst)};
+ ctx.Add("MIN.F64 {}.x,{},{};"
+ "MAX.F64 {}.x,{},{};",
+ ret, max_value, value, ret, ret, min_value);
}
void EmitFPRoundEven16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
throw NotImplementedException("GLASM instruction");
}
-void EmitFPRoundEven32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
- throw NotImplementedException("GLASM instruction");
+void EmitFPRoundEven32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ ctx.Add("ROUND.F {}.x,{};", inst, value);
}
-void EmitFPRoundEven64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
- throw NotImplementedException("GLASM instruction");
+void EmitFPRoundEven64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
+ ctx.LongAdd("ROUND.F64 {}.x,{};", inst, value);
}
void EmitFPFloor16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
throw NotImplementedException("GLASM instruction");
}
-void EmitFPFloor32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
- throw NotImplementedException("GLASM instruction");
+void EmitFPFloor32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ ctx.Add("FLR.F {}.x,{};", inst, value);
}
-void EmitFPFloor64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
- throw NotImplementedException("GLASM instruction");
+void EmitFPFloor64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
+ ctx.LongAdd("FLR.F64 {}.x,{};", inst, value);
}
void EmitFPCeil16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
throw NotImplementedException("GLASM instruction");
}
-void EmitFPCeil32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
- throw NotImplementedException("GLASM instruction");
+void EmitFPCeil32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ ctx.Add("CEIL.F {}.x,{};", inst, value);
}
-void EmitFPCeil64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
- throw NotImplementedException("GLASM instruction");
+void EmitFPCeil64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
+ ctx.LongAdd("CEIL.F64 {}.x,{};", inst, value);
}
void EmitFPTrunc16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
throw NotImplementedException("GLASM instruction");
}
-void EmitFPTrunc32([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] ScalarF32 value) {
- throw NotImplementedException("GLASM instruction");
+void EmitFPTrunc32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value) {
+ ctx.Add("TRUNC.F {}.x,{};", inst, value);
}
-void EmitFPTrunc64([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register value) {
- throw NotImplementedException("GLASM instruction");
+void EmitFPTrunc64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value) {
+ ctx.LongAdd("TRUNC.F64 {}.x,{};", inst, value);
}
void EmitFPOrdEqual16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] Register lhs,
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
index 5d94f21a6..94843cc60 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_instructions.h
@@ -198,8 +198,8 @@ void EmitBitCastU64F64(EmitContext& ctx, IR::Inst& inst, const IR::Value& value)
void EmitBitCastF16U16(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
void EmitBitCastF32U32(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
void EmitBitCastF64U64(EmitContext& ctx, IR::Inst& inst, const IR::Value& value);
-void EmitPackUint2x32(EmitContext& ctx, Register value);
-void EmitUnpackUint2x32(EmitContext& ctx, Register value);
+void EmitPackUint2x32(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitUnpackUint2x32(EmitContext& ctx, IR::Inst& inst, Register value);
void EmitPackFloat2x16(EmitContext& ctx, Register value);
void EmitUnpackFloat2x16(EmitContext& ctx, Register value);
void EmitPackHalf2x16(EmitContext& ctx, IR::Inst& inst, Register value);
@@ -244,20 +244,22 @@ void EmitFPSaturate16(EmitContext& ctx, Register value);
void EmitFPSaturate32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
void EmitFPSaturate64(EmitContext& ctx, Register value);
void EmitFPClamp16(EmitContext& ctx, Register value, Register min_value, Register max_value);
-void EmitFPClamp32(EmitContext& ctx, ScalarF32 value, ScalarF32 min_value, ScalarF32 max_value);
-void EmitFPClamp64(EmitContext& ctx, Register value, Register min_value, Register max_value);
+void EmitFPClamp32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value, ScalarF32 min_value,
+ ScalarF32 max_value);
+void EmitFPClamp64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value, ScalarF64 min_value,
+ ScalarF64 max_value);
void EmitFPRoundEven16(EmitContext& ctx, Register value);
-void EmitFPRoundEven32(EmitContext& ctx, ScalarF32 value);
-void EmitFPRoundEven64(EmitContext& ctx, Register value);
+void EmitFPRoundEven32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitFPRoundEven64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value);
void EmitFPFloor16(EmitContext& ctx, Register value);
-void EmitFPFloor32(EmitContext& ctx, ScalarF32 value);
-void EmitFPFloor64(EmitContext& ctx, Register value);
+void EmitFPFloor32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitFPFloor64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value);
void EmitFPCeil16(EmitContext& ctx, Register value);
-void EmitFPCeil32(EmitContext& ctx, ScalarF32 value);
-void EmitFPCeil64(EmitContext& ctx, Register value);
+void EmitFPCeil32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitFPCeil64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value);
void EmitFPTrunc16(EmitContext& ctx, Register value);
-void EmitFPTrunc32(EmitContext& ctx, ScalarF32 value);
-void EmitFPTrunc64(EmitContext& ctx, Register value);
+void EmitFPTrunc32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitFPTrunc64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value);
void EmitFPOrdEqual16(EmitContext& ctx, Register lhs, Register rhs);
void EmitFPOrdEqual32(EmitContext& ctx, IR::Inst& inst, ScalarF32 lhs, ScalarF32 rhs);
void EmitFPOrdEqual64(EmitContext& ctx, IR::Inst& inst, ScalarF64 lhs, ScalarF64 rhs);
@@ -441,54 +443,54 @@ void EmitLogicalOr(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b);
void EmitLogicalAnd(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b);
void EmitLogicalXor(EmitContext& ctx, IR::Inst& inst, ScalarS32 a, ScalarS32 b);
void EmitLogicalNot(EmitContext& ctx, IR::Inst& inst, ScalarS32 value);
-void EmitConvertS16F16(EmitContext& ctx, Register value);
-void EmitConvertS16F32(EmitContext& ctx, Register value);
-void EmitConvertS16F64(EmitContext& ctx, Register value);
-void EmitConvertS32F16(EmitContext& ctx, Register value);
-void EmitConvertS32F32(EmitContext& ctx, Register value);
-void EmitConvertS32F64(EmitContext& ctx, Register value);
-void EmitConvertS64F16(EmitContext& ctx, Register value);
-void EmitConvertS64F32(EmitContext& ctx, Register value);
-void EmitConvertS64F64(EmitContext& ctx, Register value);
-void EmitConvertU16F16(EmitContext& ctx, Register value);
-void EmitConvertU16F32(EmitContext& ctx, Register value);
-void EmitConvertU16F64(EmitContext& ctx, Register value);
-void EmitConvertU32F16(EmitContext& ctx, Register value);
-void EmitConvertU32F32(EmitContext& ctx, Register value);
-void EmitConvertU32F64(EmitContext& ctx, Register value);
-void EmitConvertU64F16(EmitContext& ctx, Register value);
-void EmitConvertU64F32(EmitContext& ctx, Register value);
-void EmitConvertU64F64(EmitContext& ctx, Register value);
-void EmitConvertU64U32(EmitContext& ctx, Register value);
-void EmitConvertU32U64(EmitContext& ctx, Register value);
-void EmitConvertF16F32(EmitContext& ctx, Register value);
-void EmitConvertF32F16(EmitContext& ctx, Register value);
-void EmitConvertF32F64(EmitContext& ctx, Register value);
-void EmitConvertF64F32(EmitContext& ctx, Register value);
-void EmitConvertF16S8(EmitContext& ctx, Register value);
-void EmitConvertF16S16(EmitContext& ctx, Register value);
-void EmitConvertF16S32(EmitContext& ctx, Register value);
-void EmitConvertF16S64(EmitContext& ctx, Register value);
-void EmitConvertF16U8(EmitContext& ctx, Register value);
-void EmitConvertF16U16(EmitContext& ctx, Register value);
-void EmitConvertF16U32(EmitContext& ctx, Register value);
-void EmitConvertF16U64(EmitContext& ctx, Register value);
-void EmitConvertF32S8(EmitContext& ctx, Register value);
-void EmitConvertF32S16(EmitContext& ctx, Register value);
-void EmitConvertF32S32(EmitContext& ctx, Register value);
-void EmitConvertF32S64(EmitContext& ctx, Register value);
-void EmitConvertF32U8(EmitContext& ctx, Register value);
-void EmitConvertF32U16(EmitContext& ctx, Register value);
-void EmitConvertF32U32(EmitContext& ctx, Register value);
-void EmitConvertF32U64(EmitContext& ctx, Register value);
-void EmitConvertF64S8(EmitContext& ctx, Register value);
-void EmitConvertF64S16(EmitContext& ctx, Register value);
-void EmitConvertF64S32(EmitContext& ctx, Register value);
-void EmitConvertF64S64(EmitContext& ctx, Register value);
-void EmitConvertF64U8(EmitContext& ctx, Register value);
-void EmitConvertF64U16(EmitContext& ctx, Register value);
-void EmitConvertF64U32(EmitContext& ctx, Register value);
-void EmitConvertF64U64(EmitContext& ctx, Register value);
+void EmitConvertS16F16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertS16F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitConvertS16F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value);
+void EmitConvertS32F16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertS32F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitConvertS32F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value);
+void EmitConvertS64F16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertS64F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitConvertS64F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value);
+void EmitConvertU16F16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertU16F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitConvertU16F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value);
+void EmitConvertU32F16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertU32F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitConvertU32F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value);
+void EmitConvertU64F16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertU64F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitConvertU64F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value);
+void EmitConvertU64U32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value);
+void EmitConvertU32U64(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF16F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitConvertF32F16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF32F64(EmitContext& ctx, IR::Inst& inst, ScalarF64 value);
+void EmitConvertF64F32(EmitContext& ctx, IR::Inst& inst, ScalarF32 value);
+void EmitConvertF16S8(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF16S16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF16S32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value);
+void EmitConvertF16S64(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF16U8(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF16U16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF16U32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value);
+void EmitConvertF16U64(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF32S8(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF32S16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF32S32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value);
+void EmitConvertF32S64(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF32U8(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF32U16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF32U32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value);
+void EmitConvertF32U64(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF64S8(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF64S16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF64S32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value);
+void EmitConvertF64S64(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF64U8(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF64U16(EmitContext& ctx, IR::Inst& inst, Register value);
+void EmitConvertF64U32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value);
+void EmitConvertF64U64(EmitContext& ctx, IR::Inst& inst, Register value);
void EmitBindlessImageSampleImplicitLod(EmitContext&);
void EmitBindlessImageSampleExplicitLod(EmitContext&);
void EmitBindlessImageSampleDrefImplicitLod(EmitContext&);
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp
index c9386805a..40f48a091 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_integer.cpp
@@ -141,14 +141,16 @@ void EmitUMax32(EmitContext& ctx, IR::Inst& inst, ScalarU32 a, ScalarU32 b) {
void EmitSClamp32(EmitContext& ctx, IR::Inst& inst, ScalarS32 value, ScalarS32 min, ScalarS32 max) {
const Register ret{ctx.reg_alloc.Define(inst)};
- ctx.Add("MIN.S {}.x,{},{};", ret, max, value);
- ctx.Add("MAX.S {}.x,{},{};", ret, ret, min);
+ ctx.Add("MIN.S {}.x,{},{};"
+ "MAX.S {}.x,{},{};",
+ ret, max, value, ret, ret, min);
}
void EmitUClamp32(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 min, ScalarU32 max) {
const Register ret{ctx.reg_alloc.Define(inst)};
- ctx.Add("MIN.U {}.x,{},{};", ret, max, value);
- ctx.Add("MAX.U {}.x,{},{};", ret, ret, min);
+ ctx.Add("MIN.U {}.x,{},{};"
+ "MAX.U {}.x,{},{};",
+ ret, max, value, ret, ret, min);
}
void EmitSLessThan(EmitContext& ctx, IR::Inst& inst, ScalarS32 lhs, ScalarS32 rhs) {
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
index 29eb75c6a..ebdbbcf5f 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_not_implemented.cpp
@@ -588,198 +588,6 @@ void EmitLogicalNot(EmitContext& ctx, IR::Inst& inst, ScalarS32 value) {
ctx.Add("SEQ.S {},{},0;", inst, value);
}
-void EmitConvertS16F16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertS16F32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertS16F64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertS32F16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertS32F32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertS32F64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertS64F16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertS64F32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertS64F64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertU16F16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertU16F32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertU16F64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertU32F16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertU32F32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertU32F64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertU64F16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertU64F32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertU64F64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertU64U32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertU32U64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF16F32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF32F16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF32F64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF64F32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF16S8(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF16S16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF16S32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF16S64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF16U8(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF16U16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF16U32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF16U64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF32S8(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF32S16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF32S32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF32S64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF32U8(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF32U16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF32U32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF32U64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF64S8(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF64S16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF64S32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF64S64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF64U8(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF64U16(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF64U32(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
-void EmitConvertF64U64(EmitContext& ctx, Register value) {
- NotImplemented();
-}
-
void EmitBindlessImageSampleImplicitLod(EmitContext&) {
NotImplemented();
}
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.cpp b/src/shader_recompiler/backend/glasm/reg_alloc.cpp
index 82b627500..1a65a5e7d 100644
--- a/src/shader_recompiler/backend/glasm/reg_alloc.cpp
+++ b/src/shader_recompiler/backend/glasm/reg_alloc.cpp
@@ -39,6 +39,10 @@ Value RegAlloc::Consume(const IR::Value& value) {
ret.type = Type::F32;
ret.imm_f32 = value.F32();
break;
+ case IR::Type::U64:
+ ret.type = Type::U64;
+ ret.imm_u64 = value.U64();
+ break;
case IR::Type::F64:
ret.type = Type::F64;
ret.imm_f64 = value.F64();
diff --git a/src/shader_recompiler/backend/glasm/reg_alloc.h b/src/shader_recompiler/backend/glasm/reg_alloc.h
index f1899eae1..200c51610 100644
--- a/src/shader_recompiler/backend/glasm/reg_alloc.h
+++ b/src/shader_recompiler/backend/glasm/reg_alloc.h
@@ -27,6 +27,7 @@ enum class Type : u32 {
U32,
S32,
F32,
+ U64,
F64,
};
@@ -55,6 +56,7 @@ struct Value {
u32 imm_u32;
s32 imm_s32;
f32 imm_f32;
+ u64 imm_u64;
f64 imm_f64;
};
@@ -71,6 +73,8 @@ struct Value {
return imm_s32 == rhs.imm_s32;
case Type::F32:
return Common::BitCast<u32>(imm_f32) == Common::BitCast<u32>(rhs.imm_f32);
+ case Type::U64:
+ return imm_u64 == rhs.imm_u64;
case Type::F64:
return Common::BitCast<u64>(imm_f64) == Common::BitCast<u64>(rhs.imm_f64);
}
@@ -103,6 +107,10 @@ public:
void FreeReg(Register reg);
+ void InvalidateConditionCodes() {
+ // This does nothing for now
+ }
+
[[nodiscard]] size_t NumUsedRegisters() const noexcept {
return num_used_registers;
}
@@ -210,6 +218,7 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarU32> {
return fmt::format_to(ctx.out(), "{}", static_cast<u32>(value.imm_s32));
case Shader::Backend::GLASM::Type::F32:
return fmt::format_to(ctx.out(), "{}", Common::BitCast<u32>(value.imm_f32));
+ case Shader::Backend::GLASM::Type::U64:
case Shader::Backend::GLASM::Type::F64:
break;
}
@@ -233,6 +242,7 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarS32> {
return fmt::format_to(ctx.out(), "{}", value.imm_s32);
case Shader::Backend::GLASM::Type::F32:
return fmt::format_to(ctx.out(), "{}", Common::BitCast<s32>(value.imm_f32));
+ case Shader::Backend::GLASM::Type::U64:
case Shader::Backend::GLASM::Type::F64:
break;
}
@@ -256,6 +266,7 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarF32> {
return fmt::format_to(ctx.out(), "{}", Common::BitCast<s32>(value.imm_s32));
case Shader::Backend::GLASM::Type::F32:
return fmt::format_to(ctx.out(), "{}", value.imm_f32);
+ case Shader::Backend::GLASM::Type::U64:
case Shader::Backend::GLASM::Type::F64:
break;
}
@@ -277,6 +288,8 @@ struct fmt::formatter<Shader::Backend::GLASM::ScalarF64> {
case Shader::Backend::GLASM::Type::S32:
case Shader::Backend::GLASM::Type::F32:
break;
+ case Shader::Backend::GLASM::Type::U64:
+ return format_to(ctx.out(), "{}", Common::BitCast<f64>(value.imm_u64));
case Shader::Backend::GLASM::Type::F64:
return format_to(ctx.out(), "{}", value.imm_f64);
}