diff options
| author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2021-05-09 22:43:29 -0300 | 
|---|---|---|
| committer | ameerj <52414509+ameerj@users.noreply.github.com> | 2021-07-22 21:51:31 -0400 | 
| commit | ad61b47f80b96436ef675abcf1123668d9c1180d (patch) | |
| tree | 555fb6be6058322eae22e7088e8fbc4a615f796d | |
| parent | 7703d65f234a3032adef795037320cd30ef28a3a (diff) | |
glasm: Add conversion instructions to GLASM
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);          } | 
