2024-05-22 00:35:12 +02:00
|
|
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <span>
|
|
|
|
#include "shader_recompiler/frontend/instruction.h"
|
|
|
|
#include "shader_recompiler/ir/basic_block.h"
|
|
|
|
#include "shader_recompiler/ir/ir_emitter.h"
|
2024-05-25 14:33:15 +02:00
|
|
|
#include "shader_recompiler/runtime_info.h"
|
2024-05-22 00:35:12 +02:00
|
|
|
|
|
|
|
namespace Shader {
|
2024-05-25 14:33:15 +02:00
|
|
|
struct Info;
|
2024-05-22 00:35:12 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
namespace Shader::Gcn {
|
|
|
|
|
|
|
|
enum class ConditionOp : u32 {
|
2024-05-29 00:28:34 +02:00
|
|
|
F,
|
2024-05-22 00:35:12 +02:00
|
|
|
EQ,
|
|
|
|
LG,
|
|
|
|
GT,
|
|
|
|
GE,
|
|
|
|
LT,
|
|
|
|
LE,
|
2024-06-01 19:25:31 +02:00
|
|
|
TRU,
|
2024-05-22 00:35:12 +02:00
|
|
|
};
|
|
|
|
|
2024-07-04 23:15:44 +02:00
|
|
|
enum class AtomicOp : u32 {
|
|
|
|
Swap,
|
|
|
|
CmpSwap,
|
|
|
|
Add,
|
|
|
|
Sub,
|
|
|
|
Smin,
|
|
|
|
Umin,
|
|
|
|
Smax,
|
|
|
|
Umax,
|
|
|
|
And,
|
|
|
|
Or,
|
|
|
|
Xor,
|
|
|
|
Inc,
|
|
|
|
Dec,
|
|
|
|
FCmpSwap,
|
|
|
|
Fmin,
|
|
|
|
Fmax,
|
|
|
|
};
|
|
|
|
|
2024-06-26 17:16:01 +02:00
|
|
|
enum class NegateMode : u32 {
|
|
|
|
None,
|
|
|
|
Src1,
|
|
|
|
Result,
|
|
|
|
};
|
|
|
|
|
2024-05-22 00:35:12 +02:00
|
|
|
class Translator {
|
|
|
|
public:
|
2024-05-25 14:33:15 +02:00
|
|
|
explicit Translator(IR::Block* block_, Info& info);
|
|
|
|
|
2024-05-29 00:28:34 +02:00
|
|
|
void EmitPrologue();
|
2024-05-25 14:33:15 +02:00
|
|
|
void EmitFetch(const GcnInst& inst);
|
2024-05-22 00:35:12 +02:00
|
|
|
|
|
|
|
// Scalar ALU
|
2024-06-16 20:26:24 +02:00
|
|
|
void S_MOVK(const GcnInst& inst);
|
2024-05-22 00:35:12 +02:00
|
|
|
void S_MOV(const GcnInst& inst);
|
|
|
|
void S_MUL_I32(const GcnInst& inst);
|
|
|
|
void S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst);
|
2024-06-01 19:25:31 +02:00
|
|
|
void S_AND_SAVEEXEC_B64(const GcnInst& inst);
|
|
|
|
void S_MOV_B64(const GcnInst& inst);
|
2024-06-29 13:05:05 +02:00
|
|
|
void S_OR_B64(NegateMode negate, bool is_xor, const GcnInst& inst);
|
2024-06-26 17:16:01 +02:00
|
|
|
void S_AND_B64(NegateMode negate, const GcnInst& inst);
|
2024-06-01 19:25:31 +02:00
|
|
|
void S_ADD_I32(const GcnInst& inst);
|
|
|
|
void S_AND_B32(const GcnInst& inst);
|
2024-07-13 11:37:25 +02:00
|
|
|
void S_ASHR_I32(const GcnInst& inst);
|
2024-06-21 16:35:53 +02:00
|
|
|
void S_OR_B32(const GcnInst& inst);
|
2024-06-01 19:25:31 +02:00
|
|
|
void S_LSHR_B32(const GcnInst& inst);
|
|
|
|
void S_CSELECT_B32(const GcnInst& inst);
|
2024-06-05 21:22:34 +02:00
|
|
|
void S_CSELECT_B64(const GcnInst& inst);
|
2024-06-01 19:25:31 +02:00
|
|
|
void S_BFE_U32(const GcnInst& inst);
|
2024-06-05 21:22:34 +02:00
|
|
|
void S_LSHL_B32(const GcnInst& inst);
|
2024-06-10 21:35:14 +02:00
|
|
|
void S_BFM_B32(const GcnInst& inst);
|
2024-06-21 16:35:53 +02:00
|
|
|
void S_NOT_B64(const GcnInst& inst);
|
2024-06-22 00:23:56 +02:00
|
|
|
void S_BREV_B32(const GcnInst& inst);
|
2024-06-26 17:03:09 +02:00
|
|
|
void S_ADD_U32(const GcnInst& inst);
|
|
|
|
void S_SUB_U32(const GcnInst& inst);
|
2024-07-04 23:15:44 +02:00
|
|
|
void S_GETPC_B64(u32 pc, const GcnInst& inst);
|
|
|
|
void S_ADDC_U32(const GcnInst& inst);
|
2024-05-22 00:35:12 +02:00
|
|
|
|
|
|
|
// Scalar Memory
|
|
|
|
void S_LOAD_DWORD(int num_dwords, const GcnInst& inst);
|
|
|
|
void S_BUFFER_LOAD_DWORD(int num_dwords, const GcnInst& inst);
|
|
|
|
|
|
|
|
// Vector ALU
|
|
|
|
void V_MOV(const GcnInst& inst);
|
|
|
|
void V_SAD(const GcnInst& inst);
|
|
|
|
void V_MAC_F32(const GcnInst& inst);
|
|
|
|
void V_CVT_PKRTZ_F16_F32(const GcnInst& inst);
|
2024-07-01 21:42:45 +02:00
|
|
|
void V_CVT_F32_F16(const GcnInst& inst);
|
2024-05-22 00:35:12 +02:00
|
|
|
void V_MUL_F32(const GcnInst& inst);
|
|
|
|
void V_CNDMASK_B32(const GcnInst& inst);
|
2024-07-01 21:42:45 +02:00
|
|
|
void V_OR_B32(bool is_xor, const GcnInst& inst);
|
2024-05-27 00:07:46 +02:00
|
|
|
void V_AND_B32(const GcnInst& inst);
|
|
|
|
void V_LSHLREV_B32(const GcnInst& inst);
|
|
|
|
void V_ADD_I32(const GcnInst& inst);
|
|
|
|
void V_CVT_F32_I32(const GcnInst& inst);
|
|
|
|
void V_CVT_F32_U32(const GcnInst& inst);
|
|
|
|
void V_MAD_F32(const GcnInst& inst);
|
2024-05-29 00:28:34 +02:00
|
|
|
void V_FRACT_F32(const GcnInst& inst);
|
|
|
|
void V_ADD_F32(const GcnInst& inst);
|
|
|
|
void V_CVT_OFF_F32_I4(const GcnInst& inst);
|
|
|
|
void V_MED3_F32(const GcnInst& inst);
|
|
|
|
void V_FLOOR_F32(const GcnInst& inst);
|
|
|
|
void V_SUB_F32(const GcnInst& inst);
|
|
|
|
void V_RCP_F32(const GcnInst& inst);
|
|
|
|
void V_FMA_F32(const GcnInst& inst);
|
2024-06-10 21:35:14 +02:00
|
|
|
void V_CMP_F32(ConditionOp op, bool set_exec, const GcnInst& inst);
|
2024-07-08 11:24:12 +02:00
|
|
|
void V_MAX_F32(const GcnInst& inst, bool is_legacy = false);
|
2024-06-16 21:34:23 +02:00
|
|
|
void V_MAX_U32(bool is_signed, const GcnInst& inst);
|
2024-05-30 09:43:49 +02:00
|
|
|
void V_RSQ_F32(const GcnInst& inst);
|
2024-05-30 17:07:36 +02:00
|
|
|
void V_SIN_F32(const GcnInst& inst);
|
|
|
|
void V_LOG_F32(const GcnInst& inst);
|
|
|
|
void V_EXP_F32(const GcnInst& inst);
|
|
|
|
void V_SQRT_F32(const GcnInst& inst);
|
2024-07-08 11:24:12 +02:00
|
|
|
void V_MIN_F32(const GcnInst& inst, bool is_legacy = false);
|
2024-05-30 17:07:36 +02:00
|
|
|
void V_MIN3_F32(const GcnInst& inst);
|
2024-06-01 19:25:31 +02:00
|
|
|
void V_MADMK_F32(const GcnInst& inst);
|
|
|
|
void V_CUBEMA_F32(const GcnInst& inst);
|
|
|
|
void V_CUBESC_F32(const GcnInst& inst);
|
|
|
|
void V_CUBETC_F32(const GcnInst& inst);
|
|
|
|
void V_CUBEID_F32(const GcnInst& inst);
|
|
|
|
void V_CVT_U32_F32(const GcnInst& inst);
|
|
|
|
void V_SUBREV_F32(const GcnInst& inst);
|
|
|
|
void V_SUBREV_I32(const GcnInst& inst);
|
|
|
|
void V_CMP_U32(ConditionOp op, bool is_signed, bool set_exec, const GcnInst& inst);
|
|
|
|
void V_LSHRREV_B32(const GcnInst& inst);
|
2024-06-16 20:39:53 +02:00
|
|
|
void V_MUL_HI_U32(bool is_signed, const GcnInst& inst);
|
2024-06-01 19:25:31 +02:00
|
|
|
void V_SAD_U32(const GcnInst& inst);
|
2024-07-01 21:42:45 +02:00
|
|
|
void V_BFE_U32(bool is_signed, const GcnInst& inst);
|
2024-07-09 00:35:01 +02:00
|
|
|
void V_MAD_I32_I24(const GcnInst& inst, bool is_signed = true);
|
2024-06-01 19:25:31 +02:00
|
|
|
void V_MUL_I32_I24(const GcnInst& inst);
|
|
|
|
void V_SUB_I32(const GcnInst& inst);
|
|
|
|
void V_LSHR_B32(const GcnInst& inst);
|
|
|
|
void V_ASHRREV_I32(const GcnInst& inst);
|
|
|
|
void V_MAD_U32_U24(const GcnInst& inst);
|
2024-06-05 21:22:34 +02:00
|
|
|
void V_RNDNE_F32(const GcnInst& inst);
|
2024-06-07 15:26:43 +02:00
|
|
|
void V_BCNT_U32_B32(const GcnInst& inst);
|
|
|
|
void V_COS_F32(const GcnInst& inst);
|
2024-06-10 21:35:14 +02:00
|
|
|
void V_MAX3_F32(const GcnInst& inst);
|
|
|
|
void V_CVT_I32_F32(const GcnInst& inst);
|
|
|
|
void V_MIN_I32(const GcnInst& inst);
|
|
|
|
void V_MUL_LO_U32(const GcnInst& inst);
|
2024-06-16 23:39:45 +02:00
|
|
|
void V_TRUNC_F32(const GcnInst& inst);
|
2024-06-21 16:35:53 +02:00
|
|
|
void V_CEIL_F32(const GcnInst& inst);
|
|
|
|
void V_MIN_U32(const GcnInst& inst);
|
|
|
|
void V_CMP_NE_U64(const GcnInst& inst);
|
2024-06-22 00:23:56 +02:00
|
|
|
void V_BFI_B32(const GcnInst& inst);
|
2024-06-29 15:44:39 +02:00
|
|
|
void V_NOT_B32(const GcnInst& inst);
|
2024-07-01 21:42:45 +02:00
|
|
|
void V_CVT_F32_UBYTE(u32 index, const GcnInst& inst);
|
|
|
|
void V_BFREV_B32(const GcnInst& inst);
|
2024-07-04 23:15:44 +02:00
|
|
|
void V_LDEXP_F32(const GcnInst& inst);
|
|
|
|
void V_CVT_FLR_I32_F32(const GcnInst& inst);
|
|
|
|
void V_CMP_CLASS_F32(const GcnInst& inst);
|
2024-05-22 00:35:12 +02:00
|
|
|
|
2024-05-26 14:51:35 +02:00
|
|
|
// Vector Memory
|
2024-05-29 00:28:34 +02:00
|
|
|
void BUFFER_LOAD_FORMAT(u32 num_dwords, bool is_typed, const GcnInst& inst);
|
|
|
|
void BUFFER_STORE_FORMAT(u32 num_dwords, bool is_typed, const GcnInst& inst);
|
2024-05-26 14:51:35 +02:00
|
|
|
|
2024-05-22 00:35:12 +02:00
|
|
|
// Vector interpolation
|
|
|
|
void V_INTERP_P2_F32(const GcnInst& inst);
|
|
|
|
|
|
|
|
// Data share
|
2024-06-10 21:35:14 +02:00
|
|
|
void DS_SWIZZLE_B32(const GcnInst& inst);
|
2024-05-22 00:35:12 +02:00
|
|
|
void DS_READ(int bit_size, bool is_signed, bool is_pair, const GcnInst& inst);
|
|
|
|
void DS_WRITE(int bit_size, bool is_signed, bool is_pair, const GcnInst& inst);
|
2024-07-04 23:15:44 +02:00
|
|
|
void V_READFIRSTLANE_B32(const GcnInst& inst);
|
|
|
|
void S_BARRIER();
|
2024-05-22 00:35:12 +02:00
|
|
|
|
|
|
|
// MIMG
|
|
|
|
void IMAGE_GET_RESINFO(const GcnInst& inst);
|
|
|
|
void IMAGE_SAMPLE(const GcnInst& inst);
|
2024-06-30 23:43:59 +02:00
|
|
|
void IMAGE_GATHER(const GcnInst& inst);
|
2024-06-10 21:35:14 +02:00
|
|
|
void IMAGE_STORE(const GcnInst& inst);
|
2024-06-21 16:35:53 +02:00
|
|
|
void IMAGE_LOAD(bool has_mip, const GcnInst& inst);
|
2024-07-01 21:42:45 +02:00
|
|
|
void IMAGE_GET_LOD(const GcnInst& inst);
|
2024-07-04 23:15:44 +02:00
|
|
|
void IMAGE_ATOMIC(AtomicOp op, const GcnInst& inst);
|
2024-05-22 00:35:12 +02:00
|
|
|
|
|
|
|
// Export
|
|
|
|
void EXP(const GcnInst& inst);
|
|
|
|
|
|
|
|
private:
|
2024-06-06 01:24:30 +02:00
|
|
|
IR::U32F32 GetSrc(const InstOperand& operand, bool flt_zero = false);
|
|
|
|
void SetDst(const InstOperand& operand, const IR::U32F32& value);
|
2024-05-22 00:35:12 +02:00
|
|
|
|
|
|
|
private:
|
|
|
|
IR::IREmitter ir;
|
2024-05-25 14:33:15 +02:00
|
|
|
Info& info;
|
2024-06-01 19:25:31 +02:00
|
|
|
static std::array<bool, IR::NumScalarRegs> exec_contexts;
|
2024-05-22 00:35:12 +02:00
|
|
|
};
|
|
|
|
|
2024-07-04 23:15:44 +02:00
|
|
|
void Translate(IR::Block* block, u32 block_base, std::span<const GcnInst> inst_list, Info& info);
|
2024-05-22 00:35:12 +02:00
|
|
|
|
|
|
|
} // namespace Shader::Gcn
|