// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later

//     opcode name,                                         return type,    arg1 type,      arg2 type,      arg3 type,      arg4 type,      arg4 type,      ...
OPCODE(Phi,                                                 Opaque,                                                                                         )
OPCODE(Identity,                                            Opaque,         Opaque,                                                                         )
OPCODE(Void,                                                Void,                                                                                           )
OPCODE(ConditionRef,                                        U1,             U1,                                                                             )
OPCODE(Reference,                                           Void,           Opaque,                                                                         )
OPCODE(PhiMove,                                             Void,           Opaque,         Opaque,                                                         )

// Special operations
OPCODE(Prologue,                                            Void,                                                                                           )
OPCODE(Epilogue,                                            Void,                                                                                           )
OPCODE(Discard,                                             Void,                                                                                           )

// Constant memory operations
OPCODE(ReadConst,                                           U32,            U64,            U32,                                                            )
OPCODE(ReadConstBuffer,                                     F32,            Opaque,         U32,                                                            )
OPCODE(ReadConstBufferU32,                                  U32,            Opaque,         U32,                                                            )

// Context getters/setters
OPCODE(GetUserData,                                         U32,            ScalarReg,                                                                      )
OPCODE(GetThreadBitScalarReg,                               U1,             ScalarReg,                                                                      )
OPCODE(SetThreadBitScalarReg,                               Void,           ScalarReg,      U1,                                                             )
OPCODE(GetScalarRegister,                                   U32,            ScalarReg,                                                                      )
OPCODE(SetScalarRegister,                                   Void,           ScalarReg,      U32,                                                            )
OPCODE(GetVectorRegister,                                   U32,            VectorReg,                                                                      )
OPCODE(SetVectorRegister,                                   Void,           VectorReg,      U32,                                                            )
OPCODE(GetGotoVariable,                                     U1,             U32,                                                                            )
OPCODE(SetGotoVariable,                                     Void,           U32,            U1,                                                             )
OPCODE(GetAttribute,                                        F32,            Attribute,      U32,                                                            )
OPCODE(GetAttributeU32,                                     U32,            Attribute,      U32,                                                            )
OPCODE(SetAttribute,                                        Void,           Attribute,      F32,            U32,                                            )

// Flags
OPCODE(GetScc,                                             U1,             Void,                                                                            )
OPCODE(GetExec,                                            U1,             Void,                                                                            )
OPCODE(GetVcc,                                             U1,             Void,                                                                            )
OPCODE(GetVccLo,                                           U32,            Void,                                                                            )
OPCODE(GetVccHi,                                           U32,            Void,                                                                            )
OPCODE(SetScc,                                             Void,           U1,                                                                              )
OPCODE(SetExec,                                            Void,           U1,                                                                              )
OPCODE(SetVcc,                                             Void,           U1,                                                                              )
OPCODE(SetVccLo,                                           Void,           U32,                                                                             )
OPCODE(SetVccHi,                                           Void,           U32,                                                                             )

// Undefined
OPCODE(UndefU1,                                             U1,                                                                                             )
OPCODE(UndefU8,                                             U8,                                                                                             )
OPCODE(UndefU16,                                            U16,                                                                                            )
OPCODE(UndefU32,                                            U32,                                                                                            )
OPCODE(UndefU64,                                            U64,                                                                                            )

// Buffer operations
OPCODE(LoadBufferF32,                                       F32,            Opaque,         Opaque,                                                         )
OPCODE(LoadBufferF32x2,                                     F32x2,          Opaque,         Opaque,                                                         )
OPCODE(LoadBufferF32x3,                                     F32x3,          Opaque,         Opaque,                                                         )
OPCODE(LoadBufferF32x4,                                     F32x4,          Opaque,         Opaque,                                                         )
OPCODE(LoadBufferU32,                                       U32,            Opaque,         Opaque,                                                         )
OPCODE(StoreBufferF32,                                      Void,           Opaque,         Opaque,         F32,                                            )
OPCODE(StoreBufferF32x2,                                    Void,           Opaque,         Opaque,         F32x2,                                          )
OPCODE(StoreBufferF32x3,                                    Void,           Opaque,         Opaque,         F32x3,                                          )
OPCODE(StoreBufferF32x4,                                    Void,           Opaque,         Opaque,         F32x4,                                          )
OPCODE(StoreBufferU32,                                      Void,           Opaque,         Opaque,         U32,                                            )

// Vector utility
OPCODE(CompositeConstructU32x2,                             U32x2,          U32,            U32,                                                            )
OPCODE(CompositeConstructU32x3,                             U32x3,          U32,            U32,            U32,                                            )
OPCODE(CompositeConstructU32x4,                             U32x4,          U32,            U32,            U32,            U32,                            )
OPCODE(CompositeExtractU32x2,                               U32,            U32x2,          U32,                                                            )
OPCODE(CompositeExtractU32x3,                               U32,            U32x3,          U32,                                                            )
OPCODE(CompositeExtractU32x4,                               U32,            U32x4,          U32,                                                            )
OPCODE(CompositeInsertU32x2,                                U32x2,          U32x2,          U32,            U32,                                            )
OPCODE(CompositeInsertU32x3,                                U32x3,          U32x3,          U32,            U32,                                            )
OPCODE(CompositeInsertU32x4,                                U32x4,          U32x4,          U32,            U32,                                            )
OPCODE(CompositeConstructF16x2,                             F16x2,          F16,            F16,                                                            )
OPCODE(CompositeConstructF16x3,                             F16x3,          F16,            F16,            F16,                                            )
OPCODE(CompositeConstructF16x4,                             F16x4,          F16,            F16,            F16,            F16,                            )
OPCODE(CompositeExtractF16x2,                               F16,            F16x2,          U32,                                                            )
OPCODE(CompositeExtractF16x3,                               F16,            F16x3,          U32,                                                            )
OPCODE(CompositeExtractF16x4,                               F16,            F16x4,          U32,                                                            )
OPCODE(CompositeInsertF16x2,                                F16x2,          F16x2,          F16,            U32,                                            )
OPCODE(CompositeInsertF16x3,                                F16x3,          F16x3,          F16,            U32,                                            )
OPCODE(CompositeInsertF16x4,                                F16x4,          F16x4,          F16,            U32,                                            )
OPCODE(CompositeConstructF32x2,                             F32x2,          F32,            F32,                                                            )
OPCODE(CompositeConstructF32x3,                             F32x3,          F32,            F32,            F32,                                            )
OPCODE(CompositeConstructF32x4,                             F32x4,          F32,            F32,            F32,            F32,                            )
OPCODE(CompositeExtractF32x2,                               F32,            F32x2,          U32,                                                            )
OPCODE(CompositeExtractF32x3,                               F32,            F32x3,          U32,                                                            )
OPCODE(CompositeExtractF32x4,                               F32,            F32x4,          U32,                                                            )
OPCODE(CompositeInsertF32x2,                                F32x2,          F32x2,          F32,            U32,                                            )
OPCODE(CompositeInsertF32x3,                                F32x3,          F32x3,          F32,            U32,                                            )
OPCODE(CompositeInsertF32x4,                                F32x4,          F32x4,          F32,            U32,                                            )
OPCODE(CompositeConstructF64x2,                             F64x2,          F64,            F64,                                                            )
OPCODE(CompositeConstructF64x3,                             F64x3,          F64,            F64,            F64,                                            )
OPCODE(CompositeConstructF64x4,                             F64x4,          F64,            F64,            F64,            F64,                            )
OPCODE(CompositeExtractF64x2,                               F64,            F64x2,          U32,                                                            )
OPCODE(CompositeExtractF64x3,                               F64,            F64x3,          U32,                                                            )
OPCODE(CompositeExtractF64x4,                               F64,            F64x4,          U32,                                                            )
OPCODE(CompositeInsertF64x2,                                F64x2,          F64x2,          F64,            U32,                                            )
OPCODE(CompositeInsertF64x3,                                F64x3,          F64x3,          F64,            U32,                                            )
OPCODE(CompositeInsertF64x4,                                F64x4,          F64x4,          F64,            U32,                                            )

// Select operations
OPCODE(SelectU1,                                            U1,             U1,             U1,             U1,                                             )
OPCODE(SelectU8,                                            U8,             U1,             U8,             U8,                                             )
OPCODE(SelectU16,                                           U16,            U1,             U16,            U16,                                            )
OPCODE(SelectU32,                                           U32,            U1,             U32,            U32,                                            )
OPCODE(SelectU64,                                           U64,            U1,             U64,            U64,                                            )
OPCODE(SelectF32,                                           F32,            U1,             F32,            F32,                                            )
OPCODE(SelectF64,                                           F64,            U1,             F64,            F64,                                            )

// Bitwise conversions
OPCODE(BitCastU16F16,                                       U16,            F16,                                                                            )
OPCODE(BitCastU32F32,                                       U32,            F32,                                                                            )
OPCODE(BitCastU64F64,                                       U64,            F64,                                                                            )
OPCODE(BitCastF16U16,                                       F16,            U16,                                                                            )
OPCODE(BitCastF32U32,                                       F32,            U32,                                                                            )
OPCODE(BitCastF64U64,                                       F64,            U64,                                                                            )
OPCODE(PackUint2x32,                                        U64,            U32x2,                                                                          )
OPCODE(UnpackUint2x32,                                      U32x2,          U64,                                                                            )
OPCODE(PackFloat2x16,                                       U32,            F16x2,                                                                          )
OPCODE(UnpackFloat2x16,                                     F16x2,          U32,                                                                            )
OPCODE(PackHalf2x16,                                        U32,            F32x2,                                                                          )
OPCODE(UnpackHalf2x16,                                      F32x2,          U32,                                                                            )

// Floating-point operations
OPCODE(FPAbs32,                                             F32,            F32,                                                                            )
OPCODE(FPAbs64,                                             F64,            F64,                                                                            )
OPCODE(FPAdd32,                                             F32,            F32,            F32,                                                            )
OPCODE(FPAdd64,                                             F64,            F64,            F64,                                                            )
OPCODE(FPSub32,                                             F32,            F32,            F32,                                                            )
OPCODE(FPFma32,                                             F32,            F32,            F32,            F32,                                            )
OPCODE(FPFma64,                                             F64,            F64,            F64,            F64,                                            )
OPCODE(FPMax32,                                             F32,            F32,            F32,                                                            )
OPCODE(FPMax64,                                             F64,            F64,            F64,                                                            )
OPCODE(FPMin32,                                             F32,            F32,            F32,                                                            )
OPCODE(FPMin64,                                             F64,            F64,            F64,                                                            )
OPCODE(FPMul32,                                             F32,            F32,            F32,                                                            )
OPCODE(FPMul64,                                             F64,            F64,            F64,                                                            )
OPCODE(FPNeg32,                                             F32,            F32,                                                                            )
OPCODE(FPNeg64,                                             F64,            F64,                                                                            )
OPCODE(FPRecip32,                                           F32,            F32,                                                                            )
OPCODE(FPRecip64,                                           F64,            F64,                                                                            )
OPCODE(FPRecipSqrt32,                                       F32,            F32,                                                                            )
OPCODE(FPRecipSqrt64,                                       F64,            F64,                                                                            )
OPCODE(FPSqrt,                                              F32,            F32,                                                                            )
OPCODE(FPSin,                                               F32,            F32,                                                                            )
OPCODE(FPExp2,                                              F32,            F32,                                                                            )
OPCODE(FPCos,                                               F32,            F32,                                                                            )
OPCODE(FPLog2,                                              F32,            F32,                                                                            )
OPCODE(FPSaturate32,                                        F32,            F32,                                                                            )
OPCODE(FPSaturate64,                                        F64,            F64,                                                                            )
OPCODE(FPClamp32,                                           F32,            F32,            F32,            F32,                                            )
OPCODE(FPClamp64,                                           F64,            F64,            F64,            F64,                                            )
OPCODE(FPRoundEven32,                                       F32,            F32,                                                                            )
OPCODE(FPRoundEven64,                                       F64,            F64,                                                                            )
OPCODE(FPFloor32,                                           F32,            F32,                                                                            )
OPCODE(FPFloor64,                                           F64,            F64,                                                                            )
OPCODE(FPCeil32,                                            F32,            F32,                                                                            )
OPCODE(FPCeil64,                                            F64,            F64,                                                                            )
OPCODE(FPTrunc32,                                           F32,            F32,                                                                            )
OPCODE(FPTrunc64,                                           F64,            F64,                                                                            )
OPCODE(FPFract,                                             F32,            F32,                                                                            )

OPCODE(FPOrdEqual32,                                        U1,             F32,            F32,                                                            )
OPCODE(FPOrdEqual64,                                        U1,             F64,            F64,                                                            )
OPCODE(FPUnordEqual32,                                      U1,             F32,            F32,                                                            )
OPCODE(FPUnordEqual64,                                      U1,             F64,            F64,                                                            )
OPCODE(FPOrdNotEqual32,                                     U1,             F32,            F32,                                                            )
OPCODE(FPOrdNotEqual64,                                     U1,             F64,            F64,                                                            )
OPCODE(FPUnordNotEqual32,                                   U1,             F32,            F32,                                                            )
OPCODE(FPUnordNotEqual64,                                   U1,             F64,            F64,                                                            )
OPCODE(FPOrdLessThan32,                                     U1,             F32,            F32,                                                            )
OPCODE(FPOrdLessThan64,                                     U1,             F64,            F64,                                                            )
OPCODE(FPUnordLessThan32,                                   U1,             F32,            F32,                                                            )
OPCODE(FPUnordLessThan64,                                   U1,             F64,            F64,                                                            )
OPCODE(FPOrdGreaterThan32,                                  U1,             F32,            F32,                                                            )
OPCODE(FPOrdGreaterThan64,                                  U1,             F64,            F64,                                                            )
OPCODE(FPUnordGreaterThan32,                                U1,             F32,            F32,                                                            )
OPCODE(FPUnordGreaterThan64,                                U1,             F64,            F64,                                                            )
OPCODE(FPOrdLessThanEqual32,                                U1,             F32,            F32,                                                            )
OPCODE(FPOrdLessThanEqual64,                                U1,             F64,            F64,                                                            )
OPCODE(FPUnordLessThanEqual32,                              U1,             F32,            F32,                                                            )
OPCODE(FPUnordLessThanEqual64,                              U1,             F64,            F64,                                                            )
OPCODE(FPOrdGreaterThanEqual32,                             U1,             F32,            F32,                                                            )
OPCODE(FPOrdGreaterThanEqual64,                             U1,             F64,            F64,                                                            )
OPCODE(FPUnordGreaterThanEqual32,                           U1,             F32,            F32,                                                            )
OPCODE(FPUnordGreaterThanEqual64,                           U1,             F64,            F64,                                                            )
OPCODE(FPIsNan32,                                           U1,             F32,                                                                            )
OPCODE(FPIsNan64,                                           U1,             F64,                                                                            )

// Integer operations
OPCODE(IAdd32,                                              U32,            U32,            U32,                                                            )
OPCODE(IAdd64,                                              U64,            U64,            U64,                                                            )
OPCODE(ISub32,                                              U32,            U32,            U32,                                                            )
OPCODE(ISub64,                                              U64,            U64,            U64,                                                            )
OPCODE(IMul32,                                              U32,            U32,            U32,                                                            )
OPCODE(SDiv32,                                              U32,            U32,            U32,                                                            )
OPCODE(UDiv32,                                              U32,            U32,            U32,                                                            )
OPCODE(INeg32,                                              U32,            U32,                                                                            )
OPCODE(INeg64,                                              U64,            U64,                                                                            )
OPCODE(IAbs32,                                              U32,            U32,                                                                            )
OPCODE(ShiftLeftLogical32,                                  U32,            U32,            U32,                                                            )
OPCODE(ShiftLeftLogical64,                                  U64,            U64,            U32,                                                            )
OPCODE(ShiftRightLogical32,                                 U32,            U32,            U32,                                                            )
OPCODE(ShiftRightLogical64,                                 U64,            U64,            U32,                                                            )
OPCODE(ShiftRightArithmetic32,                              U32,            U32,            U32,                                                            )
OPCODE(ShiftRightArithmetic64,                              U64,            U64,            U32,                                                            )
OPCODE(BitwiseAnd32,                                        U32,            U32,            U32,                                                            )
OPCODE(BitwiseOr32,                                         U32,            U32,            U32,                                                            )
OPCODE(BitwiseXor32,                                        U32,            U32,            U32,                                                            )
OPCODE(BitFieldInsert,                                      U32,            U32,            U32,            U32,            U32,                            )
OPCODE(BitFieldSExtract,                                    U32,            U32,            U32,            U32,                                            )
OPCODE(BitFieldUExtract,                                    U32,            U32,            U32,            U32,                                            )
OPCODE(BitReverse32,                                        U32,            U32,                                                                            )
OPCODE(BitCount32,                                          U32,            U32,                                                                            )
OPCODE(BitwiseNot32,                                        U32,            U32,                                                                            )

OPCODE(FindSMsb32,                                          U32,            U32,                                                                            )
OPCODE(FindUMsb32,                                          U32,            U32,                                                                            )
OPCODE(SMin32,                                              U32,            U32,            U32,                                                            )
OPCODE(UMin32,                                              U32,            U32,            U32,                                                            )
OPCODE(SMax32,                                              U32,            U32,            U32,                                                            )
OPCODE(UMax32,                                              U32,            U32,            U32,                                                            )
OPCODE(SClamp32,                                            U32,            U32,            U32,            U32,                                            )
OPCODE(UClamp32,                                            U32,            U32,            U32,            U32,                                            )
OPCODE(SLessThan,                                           U1,             U32,            U32,                                                            )
OPCODE(ULessThan,                                           U1,             U32,            U32,                                                            )
OPCODE(IEqual,                                              U1,             U32,            U32,                                                            )
OPCODE(SLessThanEqual,                                      U1,             U32,            U32,                                                            )
OPCODE(ULessThanEqual,                                      U1,             U32,            U32,                                                            )
OPCODE(SGreaterThan,                                        U1,             U32,            U32,                                                            )
OPCODE(UGreaterThan,                                        U1,             U32,            U32,                                                            )
OPCODE(INotEqual,                                           U1,             U32,            U32,                                                            )
OPCODE(SGreaterThanEqual,                                   U1,             U32,            U32,                                                            )
OPCODE(UGreaterThanEqual,                                   U1,             U32,            U32,                                                            )

// Logical operations
OPCODE(LogicalOr,                                           U1,             U1,             U1,                                                             )
OPCODE(LogicalAnd,                                          U1,             U1,             U1,                                                             )
OPCODE(LogicalXor,                                          U1,             U1,             U1,                                                             )
OPCODE(LogicalNot,                                          U1,             U1,                                                                             )

// Conversion operations
OPCODE(ConvertS32F32,                                       U32,            F32,                                                                            )
OPCODE(ConvertS32F64,                                       U32,            F64,                                                                            )
OPCODE(ConvertU32F32,                                       U32,            F32,                                                                            )
OPCODE(ConvertF16F32,                                       F16,            F32,                                                                            )
OPCODE(ConvertF32F16,                                       F32,            F16,                                                                            )
OPCODE(ConvertF32F64,                                       F32,            F64,                                                                            )
OPCODE(ConvertF64F32,                                       F64,            F32,                                                                            )
OPCODE(ConvertF32S32,                                       F32,            U32,                                                                            )
OPCODE(ConvertF32U32,                                       F32,            U32,                                                                            )
OPCODE(ConvertF64S32,                                       F64,            U32,                                                                            )
OPCODE(ConvertF64U32,                                       F64,            U32,                                                                            )

// Image operations
OPCODE(ImageSampleImplicitLod,                              F32x4,          Opaque,         Opaque,         Opaque,         Opaque,                         )
OPCODE(ImageSampleExplicitLod,                              F32x4,          Opaque,         Opaque,         Opaque,         Opaque,                         )
OPCODE(ImageSampleDrefImplicitLod,                          F32,            Opaque,         Opaque,         F32,            Opaque,         Opaque,         )
OPCODE(ImageSampleDrefExplicitLod,                          F32,            Opaque,         Opaque,         F32,            Opaque,         Opaque,         )
OPCODE(ImageGather,                                         F32x4,          Opaque,         Opaque,         Opaque,         Opaque,                         )
OPCODE(ImageGatherDref,                                     F32x4,          Opaque,         Opaque,         Opaque,         Opaque,         F32,            )
OPCODE(ImageFetch,                                          F32x4,          Opaque,         Opaque,         Opaque,         U32,            Opaque,         )
OPCODE(ImageQueryDimensions,                                U32x4,          Opaque,         U32,            U1,                                             )
OPCODE(ImageQueryLod,                                       F32x4,          Opaque,         Opaque,                                                         )
OPCODE(ImageGradient,                                       F32x4,          Opaque,         Opaque,         Opaque,         Opaque,         Opaque,         )
OPCODE(ImageRead,                                           U32x4,          Opaque,         Opaque,                                                         )
OPCODE(ImageWrite,                                          Void,           Opaque,         Opaque,         U32x4,                                          )