diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index e23e97ec..6ce9ef10 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -161,6 +161,7 @@ public: // VOP1 void V_MOV(const GcnInst& inst); void V_READFIRSTLANE_B32(const GcnInst& inst); + void V_CVT_I32_F64(const GcnInst& inst); void V_CVT_F64_I32(const GcnInst& inst); void V_CVT_F32_I32(const GcnInst& inst); void V_CVT_F32_U32(const GcnInst& inst); @@ -168,8 +169,11 @@ public: void V_CVT_I32_F32(const GcnInst& inst); void V_CVT_F16_F32(const GcnInst& inst); void V_CVT_F32_F16(const GcnInst& inst); + void V_CVT_RPI_I32_F32(const GcnInst& inst); void V_CVT_FLR_I32_F32(const GcnInst& inst); void V_CVT_OFF_F32_I4(const GcnInst& inst); + void V_CVT_F32_F64(const GcnInst& inst); + void V_CVT_F64_F32(const GcnInst& inst); void V_CVT_F32_UBYTE(u32 index, const GcnInst& inst); void V_FRACT_F32(const GcnInst& inst); void V_TRUNC_F32(const GcnInst& inst); diff --git a/src/shader_recompiler/frontend/translate/vector_alu.cpp b/src/shader_recompiler/frontend/translate/vector_alu.cpp index 830b020a..0da913a7 100644 --- a/src/shader_recompiler/frontend/translate/vector_alu.cpp +++ b/src/shader_recompiler/frontend/translate/vector_alu.cpp @@ -99,6 +99,8 @@ void Translator::EmitVectorAlu(const GcnInst& inst) { return V_MOV(inst); case Opcode::V_READFIRSTLANE_B32: return V_READFIRSTLANE_B32(inst); + case Opcode::V_CVT_I32_F64: + return V_CVT_I32_F64(inst); case Opcode::V_CVT_F64_I32: return V_CVT_F64_I32(inst); case Opcode::V_CVT_F32_I32: @@ -612,6 +614,11 @@ void Translator::V_MOV(const GcnInst& inst) { SetDst(inst.dst[0], GetSrc(inst.src[0])); } +void Translator::V_CVT_I32_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + SetDst(inst.dst[0], ir.ConvertFToS(32, src0)); +} + void Translator::V_CVT_F64_I32(const GcnInst& inst) { const IR::U32 src0{GetSrc(inst.src[0])}; SetDst64(inst.dst[0], ir.ConvertSToF(64, 32, src0)); @@ -649,6 +656,11 @@ void Translator::V_CVT_F32_F16(const GcnInst& inst) { SetDst(inst.dst[0], ir.FPConvert(32, ir.BitCast(src0l))); } +void Translator::V_CVT_RPI_I32_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst(inst.dst[0], ir.ConvertFToI(32, true, ir.FPFloor(ir.FPAdd(src0, ir.Imm32(0.5f))))); +} + void Translator::V_CVT_FLR_I32_F32(const GcnInst& inst) { const IR::F32 src0{GetSrc(inst.src[0])}; SetDst(inst.dst[0], ir.ConvertFToI(32, true, ir.FPFloor(src0))); @@ -663,6 +675,16 @@ void Translator::V_CVT_OFF_F32_I4(const GcnInst& inst) { SetDst(inst.dst[0], ir.Imm32(IntToFloat[src0.U32() & 0xF])); } +void Translator::V_CVT_F32_F64(const GcnInst& inst) { + const IR::F64 src0{GetSrc64(inst.src[0])}; + SetDst(inst.dst[0], ir.FPConvert(32, src0)); +} + +void Translator::V_CVT_F64_F32(const GcnInst& inst) { + const IR::F32 src0{GetSrc(inst.src[0])}; + SetDst64(inst.dst[0], ir.FPConvert(64, src0)); +} + void Translator::V_CVT_F32_UBYTE(u32 index, const GcnInst& inst) { const IR::U32 src0{GetSrc(inst.src[0])}; const IR::U32 byte = ir.BitFieldExtract(src0, ir.Imm32(8 * index), ir.Imm32(8)); diff --git a/src/shader_recompiler/ir/ir_emitter.cpp b/src/shader_recompiler/ir/ir_emitter.cpp index a7edb6d9..412c9581 100644 --- a/src/shader_recompiler/ir/ir_emitter.cpp +++ b/src/shader_recompiler/ir/ir_emitter.cpp @@ -1402,6 +1402,15 @@ F16F32F64 IREmitter::FPConvert(size_t result_bitsize, const F16F32F64& value) { switch (value.Type()) { case Type::F16: return Inst(Opcode::ConvertF32F16, value); + case Type::F64: + return Inst(Opcode::ConvertF32F64, value); + default: + break; + } + case 64: + switch (value.Type()) { + case Type::F32: + return Inst(Opcode::ConvertF64F32, value); default: break; }