/******************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2021-2022 Baldur Karlsson
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 ******************************************************************************/

#include "common/formatting.h"
#include "dxbc_bytecode.h"

template <>
rdcstr DoStringise(const DXBCBytecode::OpcodeType &el)
{
  BEGIN_ENUM_STRINGISE(DXBCBytecode::OpcodeType)
  {
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ADD, "add")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AND, "and")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_BREAK, "break")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_BREAKC, "breakc")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_CALL, "call")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_CALLC, "callc")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_CASE, "case")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_CONTINUE, "continue")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_CONTINUEC, "continuec")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_CUT, "cut")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DEFAULT, "default")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DERIV_RTX, "deriv_rtx")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DERIV_RTY, "deriv_rty")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DISCARD, "discard")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DIV, "div")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DP2, "dp2")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DP3, "dp3")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DP4, "dp4")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ELSE, "else")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_EMIT, "emit")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_EMITTHENCUT, "emitthencut")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ENDIF, "endif")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ENDLOOP, "endloop")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ENDSWITCH, "endswitch")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_EQ, "eq")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_EXP, "exp")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_FRC, "frc")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_FTOI, "ftoi")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_FTOU, "ftou")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_GE, "ge")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IADD, "iadd")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IF, "if")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IEQ, "ieq")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IGE, "ige")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ILT, "ilt")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMAD, "imad")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMAX, "imax")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMIN, "imin")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMUL, "imul")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_INE, "ine")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_INEG, "ineg")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ISHL, "ishl")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ISHR, "ishr")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ITOF, "itof")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LABEL, "label")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LD, "ld_indexable")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LD_MS, "ld_ms")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LOG, "log")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LOOP, "loop")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LT, "lt")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_MAD, "mad")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_MIN, "min")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_MAX, "max")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_CUSTOMDATA, "customdata")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_MOV, "mov")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_MOVC, "movc")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_MUL, "mul")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NE, "ne")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NOP, "nop")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NOT, "not")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_OR, "or")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_RESINFO, "resinfo_indexable")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_RET, "ret")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_RETC, "retc")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ROUND_NE, "round_ne")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ROUND_NI, "round_ni")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ROUND_PI, "round_pi")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ROUND_Z, "round_z")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_RSQ, "rsq")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE, "sample_indexable")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_C, "sample_c")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_C_LZ, "sample_c_lz")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_L, "sample_l")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_D, "sample_d")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_B, "sample_b")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SQRT, "sqrt")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SWITCH, "switch")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SINCOS, "sincos")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_UDIV, "udiv")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ULT, "ult")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_UGE, "uge")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_UMUL, "umul")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_UMAD, "umad")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_UMAX, "umax")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_UMIN, "umin")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_USHR, "ushr")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_UTOF, "utof")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_XOR, "xor")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_RESOURCE, "dcl_resource")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_CONSTANT_BUFFER, "dcl_constantbuffer")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_SAMPLER, "dcl_sampler")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_INDEX_RANGE, "dcl_indexRange")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY, "dcl_outputtopology")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_GS_INPUT_PRIMITIVE, "dcl_inputprimitive")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_MAX_OUTPUT_VERTEX_COUNT, "dcl_maxout")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_INPUT, "dcl_input")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_INPUT_SGV, "dcl_input_sgv")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_INPUT_SIV, "dcl_input_siv")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_INPUT_PS, "dcl_input_ps")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_INPUT_PS_SGV, "dcl_input_ps_sgv")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_INPUT_PS_SIV, "dcl_input_ps_siv")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_OUTPUT, "dcl_output")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_OUTPUT_SGV, "dcl_output_sgv")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_OUTPUT_SIV, "dcl_output_siv")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_TEMPS, "dcl_temps")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_INDEXABLE_TEMP, "dcl_indexableTemp")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_GLOBAL_FLAGS, "dcl_globalFlags")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LOD, "lod")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_GATHER4, "gather4")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_POS, "samplepos")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_INFO, "sample_info")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_HS_DECLS, "hs_decls")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_HS_CONTROL_POINT_PHASE, "hs_control_point_phase")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_HS_FORK_PHASE, "hs_fork_phase")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_HS_JOIN_PHASE, "hs_join_phase")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_EMIT_STREAM, "emit_stream")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_CUT_STREAM, "cut_stream")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_EMITTHENCUT_STREAM, "emitThenCut_stream")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_INTERFACE_CALL, "fcall")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_BUFINFO, "bufinfo")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DERIV_RTX_COARSE, "deriv_rtx_coarse")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DERIV_RTX_FINE, "deriv_rtx_fine")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DERIV_RTY_COARSE, "deriv_rty_coarse")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DERIV_RTY_FINE, "deriv_rty_fine")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_GATHER4_C, "gather4_c")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_GATHER4_PO, "gather4_po")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_GATHER4_PO_C, "gather4_po_c")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_RCP, "rcp")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_F32TOF16, "f32tof16")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_F16TOF32, "f16tof32")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_UADDC, "uaddc")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_USUBB, "usubb")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_COUNTBITS, "countbits")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_FIRSTBIT_HI, "firstbit_hi")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_FIRSTBIT_LO, "firstbit_lo")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_FIRSTBIT_SHI, "firstbit_shi")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_UBFE, "ubfe")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IBFE, "ibfe")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_BFI, "bfi")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_BFREV, "bfrev")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SWAPC, "swapc")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_STREAM, "dcl_stream")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_FUNCTION_BODY, "dcl_function_body")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_FUNCTION_TABLE, "dcl_function_table")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_INTERFACE, "dcl_interface")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_INPUT_CONTROL_POINT_COUNT,
                               "dcl_input_control_point_count")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT,
                               "dcl_output_control_point_count")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_TESS_DOMAIN, "dcl_tessellator_domain")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_TESS_PARTITIONING, "dcl_tessellator_partitioning")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_TESS_OUTPUT_PRIMITIVE, "dcl_tessellator_output_primitive")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_HS_MAX_TESSFACTOR, "dcl_hs_max_tessfactor")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_HS_FORK_PHASE_INSTANCE_COUNT,
                               "dcl_hs_fork_phase_instance_count")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_HS_JOIN_PHASE_INSTANCE_COUNT,
                               "dcl_hs_join_phase_instance_count")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_THREAD_GROUP, "dcl_thread_group")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_UNORDERED_ACCESS_VIEW_TYPED, "dcl_uav_typed")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_UNORDERED_ACCESS_VIEW_RAW, "dcl_uav_raw")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_UNORDERED_ACCESS_VIEW_STRUCTURED, "dcl_uav_structured")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_RAW, "dcl_tgsm_raw")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED,
                               "dcl_tgsm_structured")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_RESOURCE_RAW, "dcl_resource_raw")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_RESOURCE_STRUCTURED, "dcl_resource_structured")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LD_UAV_TYPED, "ld_uav_typed")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_STORE_UAV_TYPED, "store_uav_typed")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LD_RAW, "ld_raw")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_STORE_RAW, "store_raw")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LD_STRUCTURED, "ld_structured")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_STORE_STRUCTURED, "store_structured")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ATOMIC_AND, "atomic_and")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ATOMIC_OR, "atomic_or")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ATOMIC_XOR, "atomic_xor")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ATOMIC_CMP_STORE, "atomic_cmp_store")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ATOMIC_IADD, "atomic_iadd")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ATOMIC_IMAX, "atomic_imax")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ATOMIC_IMIN, "atomic_imin")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ATOMIC_UMAX, "atomic_umax")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ATOMIC_UMIN, "atomic_umin")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_ALLOC, "imm_atomic_alloc")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_CONSUME, "imm_atomic_consume")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_IADD, "imm_atomic_iadd")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_AND, "imm_atomic_and")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_OR, "imm_atomic_or")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_XOR, "imm_atomic_xor")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_EXCH, "imm_atomic_exch")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_CMP_EXCH, "imm_atomic_cmp_exch")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_IMAX, "imm_atomic_imax")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_IMIN, "imm_atomic_imin")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_UMAX, "imm_atomic_umax")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_IMM_ATOMIC_UMIN, "imm_atomic_umin")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SYNC, "sync")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DADD, "dadd")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DMAX, "dmax")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DMIN, "dmin")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DMUL, "dmul")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DEQ, "deq")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DGE, "dge")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DLT, "dlt")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DNE, "dne")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DMOV, "dmov")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DMOVC, "dmovc")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DTOF, "dtof")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_FTOD, "ftod")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_EVAL_SNAPPED, "eval_snapped")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_EVAL_SAMPLE_INDEX, "eval_sample_index")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_EVAL_CENTROID, "eval_centroid")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_GS_INSTANCE_COUNT, "dcl_gs_instance_count")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ABORT, "abort")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DEBUGBREAK, "debugbreak")

    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DDIV, "ddiv")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DFMA, "dfma")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DRCP, "drcp")

    STRINGISE_ENUM_CLASS_NAMED(OPCODE_MSAD, "msad")

    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DTOI, "dtoi")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DTOU, "dtou")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_ITOD, "itod")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_UTOD, "utod")

    STRINGISE_ENUM_CLASS_NAMED(OPCODE_GATHER4_FEEDBACK, "gather4_statusk")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_GATHER4_C_FEEDBACK, "gather4_c_status")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_GATHER4_PO_FEEDBACK, "gather4_po_statusk")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_GATHER4_PO_C_FEEDBACK, "gather4_po_c_status")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LD_FEEDBACK, "ld")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LD_MS_FEEDBACK, "ld_ms_status")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LD_UAV_TYPED_FEEDBACK, "ld_uav_typed_status")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LD_RAW_FEEDBACK, "ld_raw_status")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_LD_STRUCTURED_FEEDBACK, "ld_structured_status")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_L_FEEDBACK, "sample_l_status")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_C_LZ_FEEDBACK, "sample_c_lz_status")

    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_CLAMP_FEEDBACK, "sample_status")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_B_CLAMP_FEEDBACK, "sample_b_status")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_D_CLAMP_FEEDBACK, "sample_d_status")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SAMPLE_C_CLAMP_FEEDBACK, "sample_c_status")

    STRINGISE_ENUM_CLASS_NAMED(OPCODE_CHECK_ACCESS_FULLY_MAPPED, "check_access_fully_mapped")

    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_READFIRSTLANE, "amd_readfirstlane")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_READLANE, "amd_readlane")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_LANEID, "amd_laneid")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_SWIZZLE, "amd_swizzle")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_BALLOT, "amd_ballot")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_MBCNT, "amd_mbcnt")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_MIN3U, "amd_min3u")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_MIN3F, "amd_min3f")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_MED3U, "amd_med3u")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_MED3F, "amd_med3f")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_MAX3U, "amd_max3u")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_MAX3F, "amd_max3f")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_BARYCOORD, "amd_barycoord")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_VTXPARAM, "amd_vtxparam")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_GET_VIEWPORTINDEX, "amd_get_viewportindex")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_GET_RTARRAYSLICE, "amd_get_rtarrayslice")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_WAVE_REDUCE, "amd_wave_reduce")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_WAVE_SCAN, "amd_wave_scan")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_LOADDWATADDR, "amd_load_dw_at_addr")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_GET_DRAWINDEX, "amd_get_drawindex")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_U64_ATOMIC, "amd_u64_atomic")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_GET_WAVESIZE, "amd_get_wavesize")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_GET_BASEINSTANCE, "amd_get_baseinstance")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_AMD_GET_BASEVERTEX, "amd_get_basevertex")

    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_SHUFFLE, "nv_shuffle")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_SHUFFLE_UP, "nv_shuffle_up")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_SHUFFLE_DOWN, "nv_shuffle_down")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_SHUFFLE_XOR, "nv_shuffle_xor")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_VOTE_ALL, "nv_vote_all")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_VOTE_ANY, "nv_vote_any")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_VOTE_BALLOT, "nv_vote_ballot")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_GET_LANEID, "nv_get_laneid")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_FP16_ATOMIC, "nv_fp16_atomic")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_FP32_ATOMIC, "nv_fp32_atomic")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_GET_THREADLTMASK, "nv_get_threadltmask")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_GET_FOOTPRINT_SINGLELOD, "nv_get_footprint_singlelod")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_U64_ATOMIC, "nv_u64_atomic")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_MATCH_ANY, "nv_match_any")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_FOOTPRINT, "nv_footprint")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_FOOTPRINT_BIAS, "nv_footprint_bias")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_GET_SHADING_RATE, "nv_get_shading_rate")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_FOOTPRINT_LEVEL, "nv_footprint_level")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_FOOTPRINT_GRAD, "nv_footprint_grad")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_SHUFFLE_GENERIC, "nv_shuffle_generic")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_VPRS_EVAL_ATTRIB_SAMPLE, "nv_vprs_eval_attrib_sample")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_NV_VPRS_EVAL_ATTRIB_SNAPPED, "nv_vprs_eval_attrib_snapped")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_DCL_IMMEDIATE_CONSTANT_BUFFER, "dcl_immediateConstantBuffer")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_OPAQUE_CUSTOMDATA, "customdata")
    STRINGISE_ENUM_CLASS_NAMED(OPCODE_SHADER_MESSAGE, "error")
  }
  END_ENUM_STRINGISE();
}
template <>
rdcstr DoStringise(const DXBCBytecode::OperandType &el)
{
  BEGIN_ENUM_STRINGISE(DXBCBytecode::OperandType)
  {
    STRINGISE_ENUM_CLASS_NAMED(TYPE_TEMP, "TEMP");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT, "INPUT");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_OUTPUT, "OUTPUT");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INDEXABLE_TEMP, "INDEXABLE_TEMP");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_IMMEDIATE32, "IMMEDIATE32");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_IMMEDIATE64, "IMMEDIATE64");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_SAMPLER, "SAMPLER");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_RESOURCE, "RESOURCE");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_CONSTANT_BUFFER, "CONSTANT_BUFFER");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_IMMEDIATE_CONSTANT_BUFFER, "IMMEDIATE_CONSTANT_BUFFER");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_LABEL, "LABEL");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_PRIMITIVEID, "INPUT_PRIMITIVEID");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_OUTPUT_DEPTH, "OUTPUT_DEPTH");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_NULL, "NULL");

    STRINGISE_ENUM_CLASS_NAMED(TYPE_RASTERIZER, "RASTERIZER");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_OUTPUT_COVERAGE_MASK, "OUTPUT_COVERAGE_MASK");

    STRINGISE_ENUM_CLASS_NAMED(TYPE_STREAM, "STREAM");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_FUNCTION_BODY, "FUNCTION_BODY");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_FUNCTION_TABLE, "FUNCTION_TABLE");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INTERFACE, "INTERFACE");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_FUNCTION_INPUT, "FUNCTION_INPUT");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_FUNCTION_OUTPUT, "FUNCTION_OUTPUT");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_OUTPUT_CONTROL_POINT_ID, "OUTPUT_CONTROL_POINT_ID");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_FORK_INSTANCE_ID, "INPUT_FORK_INSTANCE_ID");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_JOIN_INSTANCE_ID, "INPUT_JOIN_INSTANCE_ID");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_CONTROL_POINT, "INPUT_CONTROL_POINT");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_OUTPUT_CONTROL_POINT, "OUTPUT_CONTROL_POINT");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_PATCH_CONSTANT, "INPUT_PATCH_CONSTANT");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_DOMAIN_POINT, "INPUT_DOMAIN_POINT");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_THIS_POINTER, "THIS_POINTER");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_UNORDERED_ACCESS_VIEW, "UNORDERED_ACCESS_VIEW");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_THREAD_GROUP_SHARED_MEMORY, "THREAD_GROUP_SHARED_MEMORY");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_THREAD_ID, "INPUT_THREAD_ID");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_THREAD_GROUP_ID, "INPUT_THREAD_GROUP_ID");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_THREAD_ID_IN_GROUP, "INPUT_THREAD_ID_IN_GROUP");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_COVERAGE_MASK, "INPUT_COVERAGE_MASK");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_THREAD_ID_IN_GROUP_FLATTENED,
                               "INPUT_THREAD_ID_IN_GROUP_FLATTENED");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INPUT_GS_INSTANCE_ID, "INPUT_GS_INSTANCE_ID");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_OUTPUT_DEPTH_GREATER_EQUAL, "OUTPUT_DEPTH_GREATER_EQUAL");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_OUTPUT_DEPTH_LESS_EQUAL, "OUTPUT_DEPTH_LESS_EQUAL");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_CYCLE_COUNTER, "CYCLE_COUNTER");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_OUTPUT_STENCIL_REF, "OUTPUT_STENCIL_REF");
    STRINGISE_ENUM_CLASS_NAMED(TYPE_INNER_COVERAGE, "INNER_COVERAGE");
  }
  END_ENUM_STRINGISE();
}

template <>
rdcstr DoStringise(const DXBCBytecode::ResourceDimension &el)
{
  BEGIN_ENUM_STRINGISE(DXBCBytecode::ResourceDimension)
  {
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_UNKNOWN, "unknown");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_BUFFER, "buffer");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_TEXTURE1D, "texture1d");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_TEXTURE2D, "texture2d");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_TEXTURE2DMS, "texture2dms");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_TEXTURE3D, "texture3d");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_TEXTURECUBE, "texturecube");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_TEXTURE1DARRAY, "texture1darray");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_TEXTURE2DARRAY, "texture2darray");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_TEXTURE2DMSARRAY, "texture2dmsarray");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_TEXTURECUBEARRAY, "texturecubearray");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_RAW_BUFFER, "rawbuffer");
    STRINGISE_ENUM_CLASS_NAMED(RESOURCE_DIMENSION_STRUCTURED_BUFFER, "structured_buffer");
  }
  END_ENUM_STRINGISE();
}

template <>
rdcstr DoStringise(const DXBC::ResourceRetType &el)
{
  BEGIN_ENUM_STRINGISE(DXBC::ResourceRetType)
  {
    STRINGISE_ENUM_CLASS_NAMED(RETURN_TYPE_UNORM, "unorm");
    STRINGISE_ENUM_CLASS_NAMED(RETURN_TYPE_SNORM, "snorm");
    STRINGISE_ENUM_CLASS_NAMED(RETURN_TYPE_SINT, "sint");
    STRINGISE_ENUM_CLASS_NAMED(RETURN_TYPE_UINT, "uint");
    STRINGISE_ENUM_CLASS_NAMED(RETURN_TYPE_FLOAT, "float");
    STRINGISE_ENUM_CLASS_NAMED(RETURN_TYPE_MIXED, "mixed");
    STRINGISE_ENUM_CLASS_NAMED(RETURN_TYPE_DOUBLE, "double");
    STRINGISE_ENUM_CLASS_NAMED(RETURN_TYPE_CONTINUED, "continued");
    STRINGISE_ENUM_CLASS_NAMED(RETURN_TYPE_UNUSED, "unused");
  }
  END_ENUM_STRINGISE();
}

template <>
rdcstr DoStringise(const DXBCBytecode::ResinfoRetType &el)
{
  BEGIN_ENUM_STRINGISE(DXBCBytecode::ResinfoRetType)
  {
    STRINGISE_ENUM_CLASS_NAMED(RETTYPE_FLOAT, "float");
    STRINGISE_ENUM_CLASS_NAMED(RETTYPE_RCPFLOAT, "rcpfloat");
    STRINGISE_ENUM_CLASS_NAMED(RETTYPE_UINT, "uint");
  }
  END_ENUM_STRINGISE();
}

template <>
rdcstr DoStringise(const DXBCBytecode::InterpolationMode &el)
{
  BEGIN_ENUM_STRINGISE(DXBCBytecode::InterpolationMode)
  {
    STRINGISE_ENUM_CLASS_NAMED(INTERPOLATION_UNDEFINED, "undefined");
    // differs slightly from fxc but it's very convenient to use the hlsl terms, which are used in
    // all other cases
    STRINGISE_ENUM_CLASS_NAMED(INTERPOLATION_CONSTANT, "nointerpolation");
    STRINGISE_ENUM_CLASS_NAMED(INTERPOLATION_LINEAR, "linear");
    STRINGISE_ENUM_CLASS_NAMED(INTERPOLATION_LINEAR_CENTROID, "linear centroid");
    STRINGISE_ENUM_CLASS_NAMED(INTERPOLATION_LINEAR_NOPERSPECTIVE, "linear noperspective");
    STRINGISE_ENUM_CLASS_NAMED(INTERPOLATION_LINEAR_NOPERSPECTIVE_CENTROID,
                               "linear noperspective centroid");
    STRINGISE_ENUM_CLASS_NAMED(INTERPOLATION_LINEAR_SAMPLE, "linear sample");
    STRINGISE_ENUM_CLASS_NAMED(INTERPOLATION_LINEAR_NOPERSPECTIVE_SAMPLE,
                               "linear noperspective sample");
  }
  END_ENUM_STRINGISE();
}

template <>
rdcstr DoStringise(const DXBC::SVSemantic &el)
{
  BEGIN_ENUM_STRINGISE(DXBC::SVSemantic)
  {
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_POSITION, "position");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_CLIP_DISTANCE, "clipdistance");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_CULL_DISTANCE, "culldistance");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_RENDER_TARGET_ARRAY_INDEX, "rendertarget_array_index");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_VIEWPORT_ARRAY_INDEX, "viewport_array_index");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_VERTEX_ID, "vertexid");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_PRIMITIVE_ID, "primitiveid");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_INSTANCE_ID, "instanceid");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_IS_FRONT_FACE, "isfrontface");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_SAMPLE_INDEX, "sampleidx");

    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_QUAD_EDGE_TESSFACTOR0, "finalQuadUeq0EdgeTessFactor");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_QUAD_EDGE_TESSFACTOR1, "finalQuadVeq0EdgeTessFactor");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_QUAD_EDGE_TESSFACTOR2, "finalQuadUeq1EdgeTessFactor");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_QUAD_EDGE_TESSFACTOR3, "finalQuadVeq1EdgeTessFactor");

    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR0, "finalQuadUInsideTessFactor");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_QUAD_INSIDE_TESSFACTOR1, "finalQuadVInsideTessFactor");

    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_TRI_EDGE_TESSFACTOR0, "finalTriUeq0EdgeTessFactor");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_TRI_EDGE_TESSFACTOR1, "finalTriVeq0EdgeTessFactor");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_TRI_EDGE_TESSFACTOR2, "finalTriWeq0EdgeTessFactor");

    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_TRI_INSIDE_TESSFACTOR, "finalTriInsideTessFactor");

    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_LINE_DETAIL_TESSFACTOR, "finalLineEdgeTessFactor");

    STRINGISE_ENUM_CLASS_NAMED(SVNAME_FINAL_LINE_DENSITY_TESSFACTOR, "finalLineInsideTessFactor");

    STRINGISE_ENUM_CLASS_NAMED(SVNAME_TARGET, "target");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_DEPTH, "depth");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_COVERAGE, "coverage");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_DEPTH_GREATER_EQUAL, "depthgreaterequal");
    STRINGISE_ENUM_CLASS_NAMED(SVNAME_DEPTH_LESS_EQUAL, "depthlessequal");
  }
  END_ENUM_STRINGISE();
}

namespace DXBCBytecode
{
rdcstr toString(const uint32_t values[], uint32_t numComps)
{
  rdcstr str = "";

  // fxc actually guesses these types it seems.
  // try setting an int value to 1085276160, it will be displayed in disasm as 5.500000.
  // I don't know the exact heuristic but I'm guessing something along the lines of
  // checking if it's float-looking.
  // My heuristic is:
  // * is exponent 0 or 0x7f8? It's either inf, NaN, other special value. OR it's 0, which is
  //   identical in int or float anyway - so interpret it as an int. Small ints display as numbers,
  //   larger ints in raw hex
  // * otherwise, assume it's a float.
  // * If any component is a float, they are all floats.
  //
  // this means this will break if an inf/nan is set as a param, and is kind of a kludge, but the
  // behaviour seems to match d3dcompiler.dll's behaviour in most cases. There are a couple of
  // exceptions that I don't follow: 0 is always displayed as a float in vectors, however
  // sometimes it can be an int.

  bool floatOutput = false;

  for(uint32_t i = 0; i < numComps; i++)
  {
    int32_t *vi = (int32_t *)&values[i];

    uint32_t exponent = vi[0] & 0x7f800000;

    if(exponent != 0 && exponent != 0x7f800000)
      floatOutput = true;
  }

  for(uint32_t i = 0; i < numComps; i++)
  {
    float *vf = (float *)&values[i];
    int32_t *vi = (int32_t *)&values[i];

    if(floatOutput)
    {
      str += ToStr(vf[0]);
    }
    else
    {
      // print small ints straight up, otherwise as hex
      if(vi[0] <= 10000 && vi[0] >= -10000)
        str += ToStr(vi[0]);
      else
        str += StringFormat::Fmt("0x%08x", vi[0]);
    }

    if(i + 1 < numComps)
      str += ", ";
  }

  return str;
}

};    // namespace DXBCBytecode
