/* ************************************************************************
 * Copyright (C) 2025-2026 Advanced Micro Devices, Inc.
 *
 * 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 <cstdint>
#include <iostream>
#include <string>
#include <utility>

#include "gfx/InstDefDSL.hpp"

namespace stinkytofu {
// Rocisa (tensilelite) type name -> mnemonic; original map (pre-66fabbd) for
// RocisaGfx1250Mappings.inc.
// NOLINTNEXTLINE(misc-use-internal-linkage)
void setGfx1250RocisaToArchMap(GpuArch& registry) {
    std::unordered_map<std::string, std::string> rocisaToArchMap = {
        /* branch.hpp */
        {"SBranch", "s_branch"},
        {"SCBranchSCC0", "s_cbranch_scc0"},
        {"SCBranchSCC1", "s_cbranch_scc1"},
        {"SCBranchVCCNZ", "s_cbranch_vccnz"},
        {"SCBranchVCCZ", "s_cbranch_vccz"},
        {"SSetPCB64", "s_setpc_b64"},
        {"SSwapPCB64", "s_swappc_b64"},
        {"SCBranchExecZ", "s_cbranch_execz"},
        {"SCBranchExecNZ", "s_cbranch_execnz"},
        /* cmp.hpp */
        {"SCmpEQI32", "s_cmp_eq_i32"},
        {"SCmpEQU32", "s_cmp_eq_u32"},
        {"SCmpEQU64", "s_cmp_eq_u64"},
        {"SCmpGeI32", "s_cmp_ge_i32"},
        {"SCmpGeU32", "s_cmp_ge_u32"},
        {"SCmpGtI32", "s_cmp_gt_i32"},
        {"SCmpGtU32", "s_cmp_gt_u32"},
        {"SCmpLeI32", "s_cmp_le_i32"},
        {"SCmpLeU32", "s_cmp_le_u32"},
        {"SCmpLgU32", "s_cmp_lg_u32"},
        {"SCmpLgI32", "s_cmp_lg_i32"},
        {"SCmpLgU64", "s_cmp_lg_u64"},
        {"SCmpLtI32", "s_cmp_lt_i32"},
        {"SCmpLtU32", "s_cmp_lt_u32"},
        {"SBitcmp1B32", "s_bitcmp1_b32"},
        {"VCmpEQF32", "v_cmp_eq_f32"},
        {"VCmpEQF64", "v_cmp_eq_f64"},
        {"VCmpEQU32", "v_cmp_eq_u32"},
        {"VCmpEQI32", "v_cmp_eq_i32"},
        {"VCmpGEF16", "v_cmp_ge_f16"},
        {"VCmpGTF16", "v_cmp_gt_f16"},
        {"VCmpGEF32", "v_cmp_ge_f32"},
        {"VCmpGTF32", "v_cmp_gt_f32"},
        {"VCmpGEF64", "v_cmp_ge_f64"},
        {"VCmpGTF64", "v_cmp_gt_f64"},
        {"VCmpGEI32", "v_cmp_ge_i32"},
        {"VCmpGTI32", "v_cmp_gt_i32"},
        {"VCmpGEU32", "v_cmp_ge_u32"},
        {"VCmpGtU32", "v_cmp_gt_u32"},
        {"VCmpLeU32", "v_cmp_le_u32"},
        {"VCmpLeI32", "v_cmp_le_i32"},
        {"VCmpLtI32", "v_cmp_lt_i32"},
        {"VCmpLtU32", "v_cmp_lt_u32"},
        {"VCmpUF32", "v_cmp_u_f32"},
        {"VCmpNeI32", "v_cmp_ne_i32"},
        {"VCmpNeU32", "v_cmp_ne_u32"},
        {"VCmpNeU64", "v_cmp_ne_u64"},
        {"VCmpClassF32", "v_cmp_class_f32"},
        {"VCmpXClassF32", "v_cmpx_class_f32"},
        {"VCmpXEqU32", "v_cmpx_eq_u32"},
        {"VCmpXGeU32", "v_cmpx_ge_u32"},
        {"VCmpXGtU32", "v_cmpx_gt_u32"},
        {"VCmpXLeU32", "v_cmpx_le_u32"},
        {"VCmpXLeI32", "v_cmpx_le_i32"},
        {"VCmpXLtF32", "v_cmpx_lt_f32"},
        {"VCmpXLtI32", "v_cmpx_lt_i32"},
        {"VCmpXLtU32", "v_cmpx_lt_u32"},
        {"VCmpXLtU64", "v_cmpx_lt_u64"},
        {"VCmpXNeU16", "v_cmpx_ne_u16"},
        {"VCmpXNeU32", "v_cmpx_ne_u32"},
        /* cvt.hpp */
        {"VCvtF16toF32", "v_cvt_f32_f16"},
        {"VCvtF32toF16", "v_cvt_f16_f32"},
        {"VCvtF32toU32", "v_cvt_u32_f32"},
        {"VCvtU32toF32", "v_cvt_f32_u32"},
        {"VCvtI32toF32", "v_cvt_f32_i32"},
        {"VCvtF32toI32", "v_cvt_i32_f32"},
        {"VCvtFP8toF32", "v_cvt_f32_fp8"},
        {"VCvtBF8toF32", "v_cvt_f32_bf8"},
        {"PVCvtBF16toFP32", "v_cvt_f32_bf16"},
        {"VCvtU32toF64", "v_cvt_f64_u32"},
        {"VCvtF64toU32", "v_cvt_u32_f64"},
        {"VCvtPkFP8toF32", "v_cvt_pk_f32_fp8"},
        {"VCvtPkBF8toF32", "v_cvt_pk_f32_bf8"},
        {"VCvtPkF32toFP8", "v_cvt_pk_fp8_f32"},
        {"VCvtPkF32toBF8", "v_cvt_pk_bf8_f32"},
        {"VCvtSRF32toFP8", "v_cvt_sr_fp8_f32"},
        {"VCvtSRF32toBF8", "v_cvt_sr_bf8_f32"},
        {"VCvtScalePk8F32toFP8", "v_cvt_scalef32_pk8_fp8_f32"},
        {"VCvtScalePk8F32toBF8", "v_cvt_scalef32_pk8_bf8_f32"},
        {"VCvtScaleSRPkF32toFP8", "v_cvt_scalef32_sr_pk8_fp8_f32"},
        {"VCvtPkF32toBF16", "v_cvt_pk_bf16_f32"},
        {"VCvtPkF32toF16", "v_cvt_pk_f16_f32"},
        /* mem.hpp */
        {"BufferLoadU8", "buffer_load_u8"},
        {"BufferLoadD16HIU8", "buffer_load_d16_hi_u8"},
        {"BufferLoadD16U8", "buffer_load_d16_u8"},
        {"BufferLoadD16HIB16", "buffer_load_d16_hi_b16"},
        {"BufferLoadD16B16", "buffer_load_d16_b16"},
        {"BufferLoadB32", "buffer_load_b32"},
        {"BufferLoadB64", "buffer_load_b64"},
        {"BufferLoadB96", "buffer_load_b96"},
        {"BufferLoadB128", "buffer_load_b128"},
        {"FlatLoadD16HIU8", "flat_load_d16_hi_u8"},
        {"FlatLoadD16U8", "flat_load_d16_u8"},
        {"FlatLoadD16HIB16", "flat_load_d16_hi_b16"},
        {"FlatLoadD16B16", "flat_load_d16_b16"},
        {"FlatLoadB32", "flat_load_b32"},
        {"FlatLoadB64", "flat_load_b64"},
        {"FlatLoadB128", "flat_load_b128"},
        {"TensorLoadToLds", "tensor_load_to_lds"},
        {"BufferStoreB8", "buffer_store_b8"},
        {"BufferStoreD16HIU8", "buffer_store_d16_hi_b8"},
        {"BufferStoreD16HIB16", "buffer_store_d16_hi_b16"},
        {"BufferStoreB16", "buffer_store_b16"},
        {"BufferStoreB32", "buffer_store_b32"},
        {"BufferStoreB64", "buffer_store_b64"},
        {"BufferStoreB128", "buffer_store_b128"},
        {"BufferAtomicAddF32", "buffer_atomic_add_f32"},
        {"BufferAtomicCmpswapB32", "buffer_atomic_cmpswap_b32"},
        {"BufferAtomicCmpswapB64", "buffer_atomic_cmpswap_b64"},
        {"FlatStoreD16HIB16", "flat_store_d16_hi_b16"},
        {"FlatStoreB32", "flat_store_b32"},
        {"FlatStoreB64", "flat_store_b64"},
        {"FlatStoreB128", "flat_store_b128"},
        {"FlatAtomicCmpswapB32", "flat_atomic_cmpswap_b32"},
        {"FlatAtomicDecU32", "flat_atomic_dec_u32"},
        {"DSLoadU8", "ds_load_u8"},
        {"DSLoadU16", "ds_load_u16"},
        {"DSLoadB32", "ds_load_b32"},
        {"DSLoadB64", "ds_load_b64"},
        {"DSLoadB128", "ds_load_b128"},
        {"DSLoadB192", "ds_load_b192"},
        {"DSStoreB8", "ds_store_b8"},
        {"DSStoreB16", "ds_store_b16"},
        {"DSStoreB32", "ds_store_b32"},
        {"DSStoreB64", "ds_store_b64"},
        {"DSStoreB96", "ds_store_b96"},
        {"DSStoreB128", "ds_store_b128"},
        {"DSStoreB192", "ds_store_b192"},
        {"SLoadB32", "s_load_b32"},
        {"SLoadB64", "s_load_b64"},
        {"SLoadB128", "s_load_b128"},
        {"SLoadB256", "s_load_b256"},
        {"SLoadB512", "s_load_b512"},
        {"DSLoadB128TrB16", "ds_load_tr16_b128"},
        {"DSLoadB64TrB4", "ds_load_tr4_b64"},
        {"DSLoadB96TrB6", "ds_load_tr6_b96"},
        {"DSLoadB64TrB8", "ds_load_tr8_b64"},
        {"DSBPermuteB32", "ds_bpermute_b32"},
        {"DSStoreB8HID16", "ds_store_b8_d16_hi"},
        {"DSStoreD16HIB16", "ds_store_b16_d16_hi"},
        {"GlobalPrefetchB8", "global_prefetch_b8"},
        /* common.hpp */
        {"SAbsI32", "s_abs_i32"},
        {"SMaxI32", "s_max_i32"},
        {"SMaxU32", "s_max_u32"},
        {"SMinI32", "s_min_i32"},
        {"SMinU32", "s_min_u32"},
        {"SAddI32", "s_add_i32"},
        {"SAddU32", "s_add_u32"},
        {"SAddCU32", "s_addc_u32"},
        {"SAddU64", "s_add_u64"},
        {"_SAddU64", "s_add_u64"},
        {"SMulI32", "s_mul_i32"},
        {"SMulHII32", "s_mul_hi_i32"},
        {"SMulHIU32", "s_mul_hi_u32"},
        {"SSubI32", "s_sub_i32"},
        {"SSubU32", "s_sub_u32"},
        {"SSubU64", "s_sub_u64"},
        {"SSubBU32", "s_subb_u32"},
        {"SCSelectB32", "s_cselect_b32"},
        {"SAndB32", "s_and_b32"},
        {"SAndB64", "s_and_b64"},
        {"SAndN2B32", "s_andn2_b32"},
        {"SOrB32", "s_or_b32"},
        {"SXorB32", "s_xor_b32"},
        {"SOrB64", "s_or_b64"},
        {"SGetPCB64", "s_getpc_b64"},
        {"SLShiftLeftB32", "s_lshl_b32"},
        {"SLShiftRightB32", "s_lshr_b32"},
        {"SLShiftLeftB64", "s_lshl_b64"},
        {"SLShiftRightB64", "s_lshr_b64"},
        {"SAShiftRightI32", "s_ashr_i32"},
        {"SLShiftLeft1AddU32", "s_lshl1_add_u32"},
        {"SLShiftLeft2AddU32", "s_lshl2_add_u32"},
        {"SLShiftLeft3AddU32", "s_lshl3_add_u32"},
        {"SLShiftLeft4AddU32", "s_lshl4_add_u32"},
        {"SSetMask", "s_mov_b32"},
        {"SMovB32", "s_mov_b32"},
        {"SMovB64", "s_mov_b64"},
        {"SCMovB32", "s_cmov_b32"},
        {"SCMovB64", "s_cmov_b64"},
        {"SFf1B32", "s_ff1_i32_b32"},
        {"SBfeU32", "s_bfe_u32"},
        {"SBfmB32", "s_bfm_b32"},
        {"SMovkI32", "s_movk_i32"},
        {"SSExtI16toI32", "s_sext_i32_i16"},
        {"SAndSaveExecB32", "s_and_saveexec_b32"},
        {"SAndSaveExecB64", "s_and_saveexec_b64"},
        {"SOrSaveExecB32", "s_or_saveexec_b32"},
        {"SOrSaveExecB64", "s_or_saveexec_b64"},
        {"SSetPrior", "s_setprio"},
        {"SNop", "s_nop"},
        {"SEndpgm", "s_endpgm"},
        {"SSleep", "s_sleep"},
        {"SGetRegB32", "s_getreg_b32"},
        {"SSetRegB32", "s_setreg_b32"},
        {"SSetRegIMM32B32", "s_setreg_IMM32_b32"},
        {"SWaitCnt", "s_waitcnt"},
        {"SWaitTensorcnt", "s_wait_tensorcnt"},
        {"SWaitXCnt", "s_wait_xcnt"},
        {"GlobalWb", "global_wb"},
        {"GlobalInv", "global_inv"},
        {"SDelayAlu", "s_delay_alu"},
        {"VAddF16", "v_add_f16"},
        {"VAddF32", "v_add_f32"},
        {"VAddF64", "v_add_f64"},
        {"VAddI32", "v_add_nc_i32"},
        {"VAddU32", "v_add_nc_u32"},
        {"VAdd3U32", "v_add3_u32"},
        {"VAddCOU32", "v_add_co_u32"},
        {"VAddCCOU32", "v_add_co_ci_u32"},
        {"VAddNCU64", "v_add_nc_u64"},
        {"_VAddNCU64", "v_add_nc_u64"},
        {"VNop", "v_nop"},
        {"VAddPKF32", "v_pk_add_f32"},
        {"_VAddPKF32", "v_pk_add_f32"},
        {"VMulPKF32", "v_pk_mul_f32"},
        {"_VMulPKF32", "v_pk_mul_f32"},
        {"VMulF16", "v_mul_f16"},
        {"VMulF32", "v_mul_f32"},
        {"VMulF64", "v_mul_f64"},
        {"VMulLOU32", "v_mul_lo_u32"},
        {"VMulHII32", "v_mul_hi_i32"},
        {"VMulHIU32", "v_mul_hi_u32"},
        {"VMulI32I24", "v_mul_i32_i24"},
        {"VMulU32U24", "v_mul_u32_u24"},
        {"VSubF32", "v_sub_f32"},
        {"VSubI32", "v_sub_i32"},
        {"VSubU32", "v_sub_nc_u32"},
        {"VSubCoU32", "v_sub_co_u32"},
        {"VMacF32", "v_fmac_f32"},
        {"VFmaF16", "v_fma_f16"},
        {"VFmaF32", "v_fma_f32"},
        {"VFmaF64", "v_fma_f64"},
        {"VMadI32I24", "v_mad_i32_i24"},
        {"VFmaMixF32", "v_fma_mix_f32"},
        {"VMadU32U24", "v_mad_u32_u24"},
        {"VExpF16", "v_exp_f16"},
        {"VExpF32", "v_exp_f32"},
        {"VRcpF16", "v_rcp_f16"},
        {"VRcpF32", "v_rcp_f32"},
        {"VRcpF64", "v_rcp_f64"},
        {"VRcpIFlagF32", "v_rcp_iflag_f32"},
        {"VRsqF16", "v_rsq_f16"},
        {"VRsqF32", "v_rsq_f32"},
        {"VMaxF16", "v_max_f16"},
        {"VMaxF32", "v_max_f32"},
        {"VMaxF64", "v_max_f64"},
        {"VMaxI32", "v_max_i32"},
        {"VMed3I32", "v_med3_i32"},
        {"VMed3F32", "v_med3_f32"},
        {"VMinF16", "v_min_f16"},
        {"VMinF32", "v_min_f32"},
        {"VMinF64", "v_min_f64"},
        {"VMinI32", "v_min_i32"},
        {"VAndB32", "v_and_b32"},
        {"VAndOrB32", "v_and_or_b32"},
        {"VNotB32", "v_not_b32"},
        {"VOrB32", "v_or_b32"},
        {"VXorB32", "v_xor_b32"},
        {"VCndMaskB32", "v_cndmask_b32"},
        {"VLShiftLeftB16", "v_lshlrev_b16"},
        {"VLShiftLeftB32", "v_lshlrev_b32"},
        {"VLShiftRightB32", "v_lshrrev_b32"},
        {"VLShiftLeftB64", "v_lshlrev_b64"},
        {"VLShiftRightB64", "v_lshrrev_b64"},
        {"VAShiftRightI32", "v_ashrrev_i32"},
        {"VLShiftLeftOrB32", "v_lshl_or_b32"},
        {"_VLShiftLeftOrB32", "v_lshl_or_b32"},
        {"VAddLShiftLeftU32", "v_add_lshl_u32"},
        {"_VAddLShiftLeftU32", "v_add_lshl_u32"},
        {"VLShiftLeftAddU32", "v_lshl_add_u32"},
        {"_VLShiftLeftAddU32", "v_lshl_add_u32"},
        {"VMovRelsD2B32", "v_movrelsd_2_b32"},
        {"VMovB32", "v_mov_b32"},
        {"VMovB64", "v_mov_b64"},
        {"_VMovB64", "v_mov_b64"},
        {"VSwapB32", "v_swap_b32"},
        {"VBfeI32", "v_bfe_i32"},
        {"VBfeU32", "v_bfe_u32"},
        {"VBfiB32", "v_bfi_b32"},
        {"VPackF16toB32", "v_pack_b32_f16"},
        {"VReadfirstlaneB32", "v_readfirstlane_b32"},
        {"VRndneF32", "v_rndne_f32"},
        {"VPermB32", "v_perm_b32"},
        {"VPrngB32", "v_prng_b32"},
    };
    registry.setRocisaToArchMap(std::move(rocisaToArchMap));
}

// NOLINTNEXTLINE(misc-use-internal-linkage)
void setGfx1250ConversionMap(GpuArch& registry) {
    std::unordered_map<std::string, std::string> conversion = {
        {"SSchedulingFence", "lowerRocisaSchedulingFence"},
        {"_SWaitCnt", "lowerRocisaWaitCnt"},
        {"_SWaitCntVscnt", "lowerRocisaWaitCnt"},
        {"_SWaitStorecnt", "lowerRocisaStoreWaitCnt"},
        {"_SWaitLoadcnt", "lowerRocisaWaitCnt"},
        {"_SWaitKMcnt", "lowerRocisaWaitCnt"},
        {"_SWaitDscnt", "lowerRocisaWaitCnt"},
        {"SWaitTensorcnt", "lowerRocisaWaitTensorcnt"},
        {"SWaitAlu", "lowerRocisaWaitAlu"},
        {"SBarrier", "lowerRocisaSBarrier"},

        // {"VMaxPKF16", "v_max_pk_f16"},

        /* mfma.hpp */
        {"MFMAInstruction", "lowerRocisaMFMA"},
        {"SMFMAInstruction", "lowerRocisaMFMA"},
        {"MXMFMAInstruction", "lowerRocisaMFMA"},
    };

    registry.setRocisaConversionMap(std::move(conversion));
}

}  // namespace stinkytofu
