From 7ec7f261b1839f31fb28a385453fa4b67fc8c35b Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 1 Sep 2021 21:07:02 +0300 Subject: [PATCH] LLVM DSL: implement fpcast --- rpcs3/Emu/CPU/CPUTranslator.h | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/rpcs3/Emu/CPU/CPUTranslator.h b/rpcs3/Emu/CPU/CPUTranslator.h index 01949a52f6..e98677ddba 100644 --- a/rpcs3/Emu/CPU/CPUTranslator.h +++ b/rpcs3/Emu/CPU/CPUTranslator.h @@ -1751,6 +1751,55 @@ struct llvm_bitcast } }; +template > +struct llvm_fpcast +{ + using type = U; + + static constexpr auto opc = + llvm_value_t::is_sint ? llvm::Instruction::SIToFP : + llvm_value_t::is_sint ? llvm::Instruction::FPToSI : + llvm_value_t::is_int ? llvm::Instruction::UIToFP : + llvm_value_t::is_int ? llvm::Instruction::FPToUI : + llvm_value_t::esize > llvm_value_t::esize ? llvm::Instruction::FPTrunc : + llvm_value_t::esize < llvm_value_t::esize ? llvm::Instruction::FPExt : llvm::Instruction::BitCast; + + llvm_expr_t a1; + static_assert(llvm_value_t::is_float || llvm_value_t::is_float, "llvm_fpcast<>: invalid type(s)"); + static_assert(opc != llvm::Instruction::BitCast, "llvm_fpcast<>: possible cast to the same type"); + static_assert(llvm_value_t::is_vector == llvm_value_t::is_vector, "llvm_fpcast<>: vector element mismatch"); + + static constexpr bool is_ok = + (llvm_value_t::is_float || llvm_value_t::is_float) && opc != llvm::Instruction::BitCast && + llvm_value_t::is_vector == llvm_value_t::is_vector; + + llvm::Value* eval(llvm::IRBuilder<>* ir) const + { + return ir->CreateCast(opc, a1.eval(ir), llvm_value_t::get_type(ir->getContext())); + } + + llvm_match_tuple match(llvm::Value*& value) const + { + llvm::Value* v1 = {}; + + if (auto i = llvm::dyn_cast_or_null(value); i && i->getOpcode() == opc) + { + v1 = i->getOperand(0); + + if (llvm_value_t::get_type(v1->getContext()) == i->getDestTy()) + { + if (auto r1 = a1.match(v1); v1) + { + return r1; + } + } + } + + value = nullptr; + return {}; + } +}; + template > struct llvm_trunc { @@ -2890,6 +2939,12 @@ public: return llvm_bitcast{std::forward(expr), m_module}; } + template ::is_ok>> + static auto fpcast(T&& expr) + { + return llvm_fpcast{std::forward(expr)}; + } + template ::is_ok>> static auto trunc(T&& expr) {