From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 09C82C433EF for ; Mon, 18 Oct 2021 15:41:21 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 428FD60F44 for ; Mon, 18 Oct 2021 15:41:20 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 428FD60F44 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=xen0n.name Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=nongnu.org Received: from localhost ([::1]:46220 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mcUlL-00047b-3R for qemu-devel@archiver.kernel.org; Mon, 18 Oct 2021 11:41:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:51176) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mcUiW-0000zT-CL for qemu-devel@nongnu.org; Mon, 18 Oct 2021 11:38:24 -0400 Received: from [115.28.160.31] (port=35694 helo=mailbox.box.xen0n.name) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mcUiP-00055K-MH for qemu-devel@nongnu.org; Mon, 18 Oct 2021 11:38:24 -0400 Received: from [192.168.9.172] (unknown [101.88.135.223]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits)) (No client certificate requested) by mailbox.box.xen0n.name (Postfix) with ESMTPSA id DB51F601A2; Mon, 18 Oct 2021 23:38:09 +0800 (CST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=xen0n.name; s=mail; t=1634571490; bh=SNJ+8ems1xRoFZpOFKKAuVNkiC0KpGozaEy4RokmoIY=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=uRh08STZJXFiKROgr8n3chspuqEAb5APBH7bMS1Y+BpaDGK9Vs747MnAXiZ8ErYPb N1hjCXbf+YIQ964rByAIBLRXFtndEJbbSaNFWDg0nnF1wjW8HqTCw9pKMGLNFHwgXz i/FGQV/wCGK2gTOnRBVHTn1YAkkWhFBBqAKC1B4o= Message-ID: Date: Mon, 18 Oct 2021 23:38:09 +0800 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:95.0) Gecko/20100101 Thunderbird/95.0a1 Subject: Re: [PATCH v7 16/21] target/loongarch: Add disassembler Content-Language: en-US To: Song Gao , qemu-devel@nongnu.org References: <1634561247-25499-1-git-send-email-gaosong@loongson.cn> <1634561247-25499-17-git-send-email-gaosong@loongson.cn> From: WANG Xuerui In-Reply-To: <1634561247-25499-17-git-send-email-gaosong@loongson.cn> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Host-Lookup-Failed: Reverse DNS lookup failed for 115.28.160.31 (failed) Received-SPF: pass client-ip=115.28.160.31; envelope-from=i.qemu@xen0n.name; helo=mailbox.box.xen0n.name X-Spam_score_int: -12 X-Spam_score: -1.3 X-Spam_bar: - X-Spam_report: (-1.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, NICE_REPLY_A=-0.001, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, thuth@redhat.com, alex.bennee@linaro.org, richard.henderson@linaro.org, laurent@vivier.eu, peterx@redhat.com, f4bug@amsat.org, yangxiaojuan@loongson.cn, alistair.francis@wdc.com, maobibo@loongson.cn, pbonzini@redhat.com, bmeng.cn@gmail.com, philmd@redhat.com, chenhuacai@loongson.cn Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Hi Song, On 10/18/21 20:47, Song Gao wrote: > This patch add support for disassembling via option '-d in_asm'. > > Signed-off-by: Song Gao > Signed-off-by: Xiaojuan Yang > Acked-by: Richard Henderson > --- > MAINTAINERS | 1 + > disas/loongarch.c | 2511 +++++++++++++++++++++++++++++++++++++++++++++++ > disas/meson.build | 1 + > include/disas/dis-asm.h | 2 + > meson.build | 1 + > 5 files changed, 2516 insertions(+) > create mode 100644 disas/loongarch.c Is content of this patch auto-generated from any sort of data tables, or is the big big decoder function hand-written? I didn't see similarities between this and the binutils support being upstreamed. For now any implementation would suffice, and I already saw one or two bugs in the output during my TCG host work, but it surely would be nice to switch to generated decoder in the future. The loongarch-opcodes tables could be extended to support peculiarities as exhibited in the v1.00 ISA manual and binutils implementation, via additional attributes, and I'm open to such contributions. > > diff --git a/MAINTAINERS b/MAINTAINERS > index 7df13cc..5ba80ec 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -214,6 +214,7 @@ LoongArch TCG CPUS > M: Song Gao > S: Maintained > F: target/loongarch/ > +F: disas/loongarch.c > > M68K TCG CPUs > M: Laurent Vivier > diff --git a/disas/loongarch.c b/disas/loongarch.c > new file mode 100644 > index 0000000..0647a99 > --- /dev/null > +++ b/disas/loongarch.c > @@ -0,0 +1,2511 @@ > +/* > + * QEMU LoongArch Disassembler > + * > + * Copyright (c) 2021 Loongson Technology Corporation Limited. > + * > + * SPDX-License-Identifier: LGPL-2.1+ > + */ > + > +#include "qemu/osdep.h" > +#include "disas/dis-asm.h" > + > +#define INSNLEN 4 > + > +/* enums */ > +typedef enum { > + la_op_illegal = 0, > + la_op_clo_w = 1, > + la_op_clz_w = 2, > + la_op_cto_w = 3, > + la_op_ctz_w = 4, > + la_op_clo_d = 5, > + la_op_clz_d = 6, > + la_op_cto_d = 7, > + la_op_ctz_d = 8, > + la_op_revb_2h = 9, > + la_op_revb_4h = 10, > + la_op_revb_2w = 11, > + la_op_revb_d = 12, > + la_op_revh_2w = 13, > + la_op_revh_d = 14, > + la_op_bitrev_4b = 15, > + la_op_bitrev_8b = 16, > + la_op_bitrev_w = 17, > + la_op_bitrev_d = 18, > + la_op_ext_w_h = 19, > + la_op_ext_w_b = 20, > + la_op_rdtime_d = 21, > + la_op_cpucfg = 22, > + la_op_asrtle_d = 23, > + la_op_asrtgt_d = 24, > + la_op_alsl_w = 25, > + la_op_alsl_wu = 26, > + la_op_bytepick_w = 27, > + la_op_bytepick_d = 28, > + la_op_add_w = 29, > + la_op_add_d = 30, > + la_op_sub_w = 31, > + la_op_sub_d = 32, > + la_op_slt = 33, > + la_op_sltu = 34, > + la_op_maskeqz = 35, > + la_op_masknez = 36, > + la_op_nor = 37, > + la_op_and = 38, > + la_op_or = 39, > + la_op_xor = 40, > + la_op_orn = 41, > + la_op_andn = 42, > + la_op_sll_w = 43, > + la_op_srl_w = 44, > + la_op_sra_w = 45, > + la_op_sll_d = 46, > + la_op_srl_d = 47, > + la_op_sra_d = 48, > + la_op_rotr_w = 49, > + la_op_rotr_d = 50, > + la_op_mul_w = 51, > + la_op_mulh_w = 52, > + la_op_mulh_wu = 53, > + la_op_mul_d = 54, > + la_op_mulh_d = 55, > + la_op_mulh_du = 56, > + la_op_mulw_d_w = 57, > + la_op_mulw_d_wu = 58, > + la_op_div_w = 59, > + la_op_mod_w = 60, > + la_op_div_wu = 61, > + la_op_mod_wu = 62, > + la_op_div_d = 63, > + la_op_mod_d = 64, > + la_op_div_du = 65, > + la_op_mod_du = 66, > + la_op_crc_w_b_w = 67, > + la_op_crc_w_h_w = 68, > + la_op_crc_w_w_w = 69, > + la_op_crc_w_d_w = 70, > + la_op_crcc_w_b_w = 71, > + la_op_crcc_w_h_w = 72, > + la_op_crcc_w_w_w = 73, > + la_op_crcc_w_d_w = 74, > + la_op_break = 75, > + la_op_syscall = 76, > + la_op_alsl_d = 77, > + la_op_slli_w = 78, > + la_op_slli_d = 79, > + la_op_srli_w = 80, > + la_op_srli_d = 81, > + la_op_srai_w = 82, > + la_op_srai_d = 83, > + la_op_rotri_w = 84, > + la_op_rotri_d = 85, > + la_op_bstrins_w = 86, > + la_op_bstrpick_w = 87, > + la_op_bstrins_d = 88, > + la_op_bstrpick_d = 89, > + la_op_fadd_s = 90, > + la_op_fadd_d = 91, > + la_op_fsub_s = 92, > + la_op_fsub_d = 93, > + la_op_fmul_s = 94, > + la_op_fmul_d = 95, > + la_op_fdiv_s = 96, > + la_op_fdiv_d = 97, > + la_op_fmax_s = 98, > + la_op_fmax_d = 99, > + la_op_fmin_s = 100, > + la_op_fmin_d = 101, > + la_op_fmaxa_s = 102, > + la_op_fmaxa_d = 103, > + la_op_fmina_s = 104, > + la_op_fmina_d = 105, > + la_op_fscaleb_s = 106, > + la_op_fscaleb_d = 107, > + la_op_fcopysign_s = 108, > + la_op_fcopysign_d = 109, > + la_op_fabs_s = 110, > + la_op_fabs_d = 111, > + la_op_fneg_s = 112, > + la_op_fneg_d = 113, > + la_op_flogb_s = 114, > + la_op_flogb_d = 115, > + la_op_fclass_s = 116, > + la_op_fclass_d = 117, > + la_op_fsqrt_s = 118, > + la_op_fsqrt_d = 119, > + la_op_frecip_s = 120, > + la_op_frecip_d = 121, > + la_op_frsqrt_s = 122, > + la_op_frsqrt_d = 123, > + la_op_fmov_s = 124, > + la_op_fmov_d = 125, > + la_op_movgr2fr_w = 126, > + la_op_movgr2fr_d = 127, > + la_op_movgr2frh_w = 128, > + la_op_movfr2gr_s = 129, > + la_op_movfr2gr_d = 130, > + la_op_movfrh2gr_s = 131, > + la_op_movgr2fcsr = 132, > + la_op_movfcsr2gr = 133, > + la_op_movfr2cf = 134, > + la_op_movcf2fr = 135, > + la_op_movgr2cf = 136, > + la_op_movcf2gr = 137, > + la_op_fcvt_s_d = 138, > + la_op_fcvt_d_s = 139, > + la_op_ftintrm_w_s = 140, > + la_op_ftintrm_w_d = 141, > + la_op_ftintrm_l_s = 142, > + la_op_ftintrm_l_d = 143, > + la_op_ftintrp_w_s = 144, > + la_op_ftintrp_w_d = 145, > + la_op_ftintrp_l_s = 146, > + la_op_ftintrp_l_d = 147, > + la_op_ftintrz_w_s = 148, > + la_op_ftintrz_w_d = 149, > + la_op_ftintrz_l_s = 150, > + la_op_ftintrz_l_d = 151, > + la_op_ftintrne_w_s = 152, > + la_op_ftintrne_w_d = 153, > + la_op_ftintrne_l_s = 154, > + la_op_ftintrne_l_d = 155, > + la_op_ftint_w_s = 156, > + la_op_ftint_w_d = 157, > + la_op_ftint_l_s = 158, > + la_op_ftint_l_d = 159, > + la_op_ffint_s_w = 160, > + la_op_ffint_s_l = 161, > + la_op_ffint_d_w = 162, > + la_op_ffint_d_l = 163, > + la_op_frint_s = 164, > + la_op_frint_d = 165, > + la_op_slti = 166, > + la_op_sltui = 167, > + la_op_addi_w = 168, > + la_op_addi_d = 169, > + la_op_lu52i_d = 170, > + la_op_addi = 171, > + la_op_ori = 172, > + la_op_xori = 173, > + la_op_rdtimel_w = 174, > + la_op_rdtimeh_w = 175, > + la_op_fmadd_s = 176, > + la_op_fmadd_d = 177, > + la_op_fmsub_s = 178, > + la_op_fmsub_d = 179, > + la_op_fnmadd_s = 180, > + la_op_fnmadd_d = 181, > + la_op_fnmsub_s = 182, > + la_op_fnmsub_d = 183, > + la_op_fcmp_cond_s = 184, > + la_op_fcmp_cond_d = 185, > + la_op_fsel = 186, > + la_op_addu16i_d = 187, > + la_op_lu12i_w = 188, > + la_op_lu32i_d = 189, > + la_op_pcaddi = 190, > + la_op_pcalau12i = 191, > + la_op_pcaddu12i = 192, > + la_op_pcaddu18i = 193, > + la_op_ll_w = 194, > + la_op_sc_w = 195, > + la_op_ll_d = 196, > + la_op_sc_d = 197, > + la_op_ldptr_w = 198, > + la_op_stptr_w = 199, > + la_op_ldptr_d = 200, > + la_op_stptr_d = 201, > + la_op_ld_b = 202, > + la_op_ld_h = 203, > + la_op_ld_w = 204, > + la_op_ld_d = 205, > + la_op_st_b = 206, > + la_op_st_h = 207, > + la_op_st_w = 208, > + la_op_st_d = 209, > + la_op_ld_bu = 210, > + la_op_ld_hu = 211, > + la_op_ld_wu = 212, > + la_op_preld = 213, > + la_op_fld_s = 214, > + la_op_fst_s = 215, > + la_op_fld_d = 216, > + la_op_fst_d = 217, > + la_op_ldx_b = 218, > + la_op_ldx_h = 219, > + la_op_ldx_w = 220, > + la_op_ldx_d = 221, > + la_op_stx_b = 222, > + la_op_stx_h = 223, > + la_op_stx_w = 224, > + la_op_stx_d = 225, > + la_op_ldx_bu = 226, > + la_op_ldx_hu = 227, > + la_op_ldx_wu = 228, > + la_op_fldx_s = 229, > + la_op_fldx_d = 230, > + la_op_fstx_s = 231, > + la_op_fstx_d = 232, > + la_op_amswap_w = 233, > + la_op_amswap_d = 234, > + la_op_amadd_w = 235, > + la_op_amadd_d = 236, > + la_op_amand_w = 237, > + la_op_amand_d = 238, > + la_op_amor_w = 239, > + la_op_amor_d = 240, > + la_op_amxor_w = 241, > + la_op_amxor_d = 242, > + la_op_ammax_w = 243, > + la_op_ammax_d = 244, > + la_op_ammin_w = 245, > + la_op_ammin_d = 246, > + la_op_ammax_wu = 247, > + la_op_ammax_du = 248, > + la_op_ammin_wu = 249, > + la_op_ammin_du = 250, > + la_op_amswap_db_w = 251, > + la_op_amswap_db_d = 252, > + la_op_amadd_db_w = 253, > + la_op_amadd_db_d = 254, > + la_op_amand_db_w = 255, > + la_op_amand_db_d = 256, > + la_op_amor_db_w = 257, > + la_op_amor_db_d = 258, > + la_op_amxor_db_w = 259, > + la_op_amxor_db_d = 260, > + la_op_ammax_db_w = 261, > + la_op_ammax_db_d = 262, > + la_op_ammin_db_w = 263, > + la_op_ammin_db_d = 264, > + la_op_ammax_db_wu = 265, > + la_op_ammax_db_du = 266, > + la_op_ammin_db_wu = 267, > + la_op_ammin_db_du = 268, > + la_op_dbar = 269, > + la_op_ibar = 270, > + la_op_fldgt_s = 271, > + la_op_fldgt_d = 272, > + la_op_fldle_s = 273, > + la_op_fldle_d = 274, > + la_op_fstgt_s = 275, > + la_op_fstgt_d = 276, > + ls_op_fstle_s = 277, > + la_op_fstle_d = 278, > + la_op_ldgt_b = 279, > + la_op_ldgt_h = 280, > + la_op_ldgt_w = 281, > + la_op_ldgt_d = 282, > + la_op_ldle_b = 283, > + la_op_ldle_h = 284, > + la_op_ldle_w = 285, > + la_op_ldle_d = 286, > + la_op_stgt_b = 287, > + la_op_stgt_h = 288, > + la_op_stgt_w = 289, > + la_op_stgt_d = 290, > + la_op_stle_b = 291, > + la_op_stle_h = 292, > + la_op_stle_w = 293, > + la_op_stle_d = 294, > + la_op_beqz = 295, > + la_op_bnez = 296, > + la_op_bceqz = 297, > + la_op_bcnez = 298, > + la_op_jirl = 299, > + la_op_b = 300, > + la_op_bl = 301, > + la_op_beq = 302, > + la_op_bne = 303, > + la_op_blt = 304, > + la_op_bge = 305, > + la_op_bltu = 306, > + la_op_bgeu = 307, > + > +} la_op; > + > +typedef enum { > + la_codec_illegal, > + la_codec_empty, > + la_codec_2r, > + la_codec_2r_u5, > + la_codec_2r_u6, > + la_codec_2r_2bw, > + la_codec_2r_2bd, > + la_codec_3r, > + la_codec_3r_rd0, > + la_codec_3r_sa2, > + la_codec_3r_sa3, > + la_codec_4r, > + la_codec_r_im20, > + la_codec_2r_im16, > + la_codec_2r_im14, > + la_codec_r_im14, > + la_codec_2r_im12, > + la_codec_im5_r_im12, > + la_codec_2r_im8, > + la_codec_r_sd, > + la_codec_r_sj, > + la_codec_r_cd, > + la_codec_r_cj, > + la_codec_r_seq, > + la_codec_code, > + la_codec_whint, > + la_codec_invtlb, > + la_codec_r_ofs21, > + la_codec_cj_ofs21, > + la_codec_ofs26, > + la_codec_cond, > + la_codec_sel, > + > +} la_codec; > + > +#define la_fmt_illegal "nte" > +#define la_fmt_empty "nt" > +#define la_fmt_sd_rj "ntA,1" > +#define la_fmt_rd_sj "nt0,B" These two seems to be related to the unused "scrX" register bank, and can be removed. Please remove other unused formats while you're at it. > +#define la_fmt_rd_rj "nt0,1" > +#define la_fmt_rj_rk "nt1,2" > +#define la_fmt_rj_seq "nt1,x" > +#define la_fmt_rd_si20 "nt0,i(x)" > +#define la_fmt_rd_rj_ui5 "nt0,1,C" > +#define la_fmt_rd_rj_ui6 "nt0,1.C" Dot instead of comma? > +#define la_fmt_rd_rj_level "nt0,1,x" > +#define la_fmt_rd_rj_msbw_lsbw "nt0,1,C,D" > +#define la_fmt_rd_rj_msbd_lsbd "nt0,1,C,D" > +#define la_fmt_rd_rj_si12 "nt0,1,i(x)" > +#define la_fmt_hint_rj_si12 "ntE,1,i(x)" > +#define la_fmt_rd_rj_csr "nt0,1,x" > +#define la_fmt_rd_csr "nt0,x" > +#define la_fmt_rd_rj_si14 "nt0,1,i(x)" > +#define la_fmt_rd_rj_si16 "nt0,1,i(x)" > +#define la_fmt_rd_rj_rk "nt0,1,2" > +#define la_fmt_fd_rj_rk "nt3,1,2" > +#define la_fmt_rd_rj_rk_sa2 "nt0,1,2,D" > +#define la_fmt_rd_rj_rk_sa3 "nt0,1,2,D" > +#define la_fmt_fd_rj "nt3,1" > +#define la_fmt_rd_fj "nt0,4" > +#define la_fmt_fd_fj "nt3,4" > +#define la_fmt_fd_fj_si12 "nt3,4,i(x)" > +#define la_fmt_fcsrd_rj "ntF,1" > +#define la_fmt_rd_fcsrs "nt0,G" > +#define la_fmt_cd_fj "ntH,4" > +#define la_fmt_fd_cj "nt3,I" > +#define la_fmt_fd_fj_fk "nt3,4,5" > +#define la_fmt_code "ntJ" > +#define la_fmt_whint "ntx" > +#define la_fmt_invtlb "ntx,1,2" > +#define la_fmt_offs26 "nto(X)p" > +#define la_fmt_rj_offs21 "nt1,o(X)p" > +#define la_fmt_cj_offs21 "ntQ,o(X)p" > +#define la_fmt_rd_rj_offs16 "nt0,1,o(X)" > +#define la_fmt_rj_rd_offs16 "nt1,0,o(X)p" > +#define la_fmt_s_cd_fj_fk "K.stH,4,5" > +#define la_fmt_d_cd_fj_fk "K.dtH,4,5" > +#define la_fmt_fd_fj_fk_fa "nt3,4,5,6" > +#define la_fmt_fd_fj_fk_ca "nt3,4,5,L" > +#define la_fmt_cop_rj_si12 "ntM,1,i(x)" > + > +/* structures */ > +typedef struct { > + uint32_t pc; > + uint32_t insn; > + int32_t imm; > + int32_t imm2; > + uint16_t op; > + uint16_t code; > + uint8_t codec; > + uint8_t r1; > + uint8_t r2; > + uint8_t r3; > + uint8_t r4; > + uint8_t bit; > +} la_decode; > + > +typedef struct { > + const char * const name; > + const la_codec codec; > + const char * const format; > +} la_opcode_data; > + > +/* reg names */ > +const char * const loongarch_r_normal_name[32] = { > + "$r0", "$r1", "$r2", "$r3", "$r4", "$r5", "$r6", "$r7", > + "$r8", "$r9", "$r10", "$r11", "$r12", "$r13", "$r14", "$r15", > + "$r16", "$r17", "$r18", "$r19", "$r20", "$r21", "$r22", "$r23", > + "$r24", "$r25", "$r26", "$r27", "$r28", "$r29", "$r30", "$r31", We could print ABI names for a lot more readability, what do you think? > +}; > + > +const char * const loongarch_f_normal_name[32] = { > + "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", > + "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", > + "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23", > + "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31", > +}; > + > +const char * const loongarch_cr_normal_name[4] = { > + "$scr0", "$scr1", "$scr2", "$scr3", > +}; Is this register bank used in this code? > + > +const char * const loongarch_c_normal_name[8] = { > + "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7", > +}; Register bank is named "fcc" but array name suggests "c". "loongarch_fcc_normal_names" would be better. (And fix names of the other arrays to use plural form.) > + > +/* instruction data */ > +static const la_opcode_data opcode_data[] = { Nit: 1 extra space after "const". > + { "illegal", la_codec_illegal, la_fmt_illegal }, > + { "clo.w", la_codec_2r, la_fmt_rd_rj }, > + { "clz.w", la_codec_2r, la_fmt_rd_rj }, > + { "cto.w", la_codec_2r, la_fmt_rd_rj }, > + { "ctz.w", la_codec_2r, la_fmt_rd_rj }, > + { "clo.d", la_codec_2r, la_fmt_rd_rj }, > + { "clz.d", la_codec_2r, la_fmt_rd_rj }, > + { "cto.d", la_codec_2r, la_fmt_rd_rj }, > + { "ctz_d", la_codec_2r, la_fmt_rd_rj }, > + { "revb.2h", la_codec_2r, la_fmt_rd_rj }, > + { "revb.4h", la_codec_2r, la_fmt_rd_rj }, > + { "revb.2w", la_codec_2r, la_fmt_rd_rj }, > + { "revb.d", la_codec_2r, la_fmt_rd_rj }, > + { "revh.2w", la_codec_2r, la_fmt_rd_rj }, > + { "revh.d", la_codec_2r, la_fmt_rd_rj }, > + { "bitrev.4b", la_codec_2r, la_fmt_rd_rj }, > + { "bitrev.8b", la_codec_2r, la_fmt_rd_rj }, > + { "bitrev.w", la_codec_2r, la_fmt_rd_rj }, > + { "bitrev.d", la_codec_2r, la_fmt_rd_rj }, > + { "ext.w.h", la_codec_2r, la_fmt_rd_rj }, > + { "ext.w.b", la_codec_2r, la_fmt_rd_rj }, > + { "rdtime.d", la_codec_2r, la_fmt_rd_rj }, > + { "cpucfg", la_codec_2r, la_fmt_rd_rj }, > + { "asrtle.d", la_codec_3r_rd0, la_fmt_rj_rk }, > + { "asrtgt.d", la_codec_3r_rd0, la_fmt_rj_rk }, > + { "alsl.w", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, > + { "alsl.wu", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, > + { "bytepick.w", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, > + { "bytepick.d", la_codec_3r_sa3, la_fmt_rd_rj_rk_sa3 }, > + { "add.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "add.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "sub.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "sub.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "slt", la_codec_3r, la_fmt_rd_rj_rk }, > + { "sltu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "maskeqz", la_codec_3r, la_fmt_rd_rj_rk }, > + { "masknez", la_codec_3r, la_fmt_rd_rj_rk }, > + { "nor", la_codec_3r, la_fmt_rd_rj_rk }, > + { "and", la_codec_3r, la_fmt_rd_rj_rk }, > + { "or", la_codec_3r, la_fmt_rd_rj_rk }, > + { "xor", la_codec_3r, la_fmt_rd_rj_rk }, > + { "orn", la_codec_3r, la_fmt_rd_rj_rk }, > + { "andn", la_codec_3r, la_fmt_rd_rj_rk }, > + { "sll.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "srl.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "sra.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "sll.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "srl.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "sra.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "rotr.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "rotr.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mul.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mulh.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mulh.wu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mul.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mulh.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mulh.du", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mulw.d.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mulw.d.wu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "div.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mod.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "div.wu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mod.wu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "div.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mod.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "div.du", la_codec_3r, la_fmt_rd_rj_rk }, > + { "mod.du", la_codec_3r, la_fmt_rd_rj_rk }, > + { "crc.w.b.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "crc.w.h.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "crc.w.w.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "crc.w.d.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "crcc.w.b.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "crcc.w.h.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "crcc.w.w.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "crcc.w.d.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "break", la_codec_code, la_fmt_code }, > + { "syscall", la_codec_code, la_fmt_code }, > + { "alsl.d", la_codec_3r_sa2, la_fmt_rd_rj_rk_sa2 }, > + { "slli.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, > + { "slli.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, > + { "srli.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, > + { "srli.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, > + { "srai.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, > + { "srai.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, > + { "rotri.w", la_codec_2r_u5, la_fmt_rd_rj_ui5 }, > + { "rotri.d", la_codec_2r_u6, la_fmt_rd_rj_ui6 }, > + { "bstrins.w", la_codec_2r_2bw, la_fmt_rd_rj_msbw_lsbw }, > + { "bstrpick.w", la_codec_2r_2bw, la_fmt_rd_rj_msbw_lsbw }, > + { "bstrins.d", la_codec_2r_2bd, la_fmt_rd_rj_msbd_lsbd }, > + { "bstrpick.d", la_codec_2r_2bd, la_fmt_rd_rj_msbd_lsbd }, > + { "fadd.s", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fadd.d", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fsub.s", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fsub.d", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fmul.s", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fmul.d", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fdiv.s", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fdiv.d", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fmax.s", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fmax.d", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fmin.s", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fmin.d", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fmaxa.s", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fmaxa.d", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fmina.s", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fmina.d", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fscaleb.s", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fscaleb.d", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fcopysign.s", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fcopysign.d", la_codec_3r, la_fmt_fd_fj_fk }, > + { "fabs.s", la_codec_2r, la_fmt_fd_fj }, > + { "fabs.d", la_codec_2r, la_fmt_fd_fj }, > + { "fneg.s", la_codec_2r, la_fmt_fd_fj }, > + { "fneg.d", la_codec_2r, la_fmt_fd_fj }, > + { "flogb.s", la_codec_2r, la_fmt_fd_fj }, > + { "flogb.d", la_codec_2r, la_fmt_fd_fj }, > + { "fclass.s", la_codec_2r, la_fmt_fd_fj }, > + { "fclass.d", la_codec_2r, la_fmt_fd_fj }, > + { "fsqrt.s", la_codec_2r, la_fmt_fd_fj }, > + { "fsqrt.d", la_codec_2r, la_fmt_fd_fj }, > + { "frecip.s", la_codec_2r, la_fmt_fd_fj }, > + { "frecip.d", la_codec_2r, la_fmt_fd_fj }, > + { "frsqrt.s", la_codec_2r, la_fmt_fd_fj }, > + { "frsqrt.d", la_codec_2r, la_fmt_fd_fj }, > + { "fmov.s", la_codec_2r, la_fmt_fd_fj }, > + { "fmov.d", la_codec_2r, la_fmt_fd_fj }, > + { "movgr2fr.w", la_codec_2r, la_fmt_fd_rj }, > + { "movgr2fr.d", la_codec_2r, la_fmt_fd_rj }, > + { "movgr2frh.w", la_codec_2r, la_fmt_fd_rj }, > + { "movfr2gr.s", la_codec_2r, la_fmt_rd_fj }, > + { "movfr2gr.d", la_codec_2r, la_fmt_rd_fj }, > + { "movfrh2gr.s", la_codec_2r, la_fmt_rd_fj }, > + { "movgr2fcsr", la_codec_2r, la_fmt_fcsrd_rj }, > + { "movfcsr2gr", la_codec_2r, la_fmt_rd_fcsrs }, > + { "movfr2cf", la_codec_r_cd, la_fmt_cd_fj }, > + { "movcf2fr", la_codec_r_cj, la_fmt_fd_cj }, > + { "movgr2cf", la_codec_r_cd, la_fmt_cd_fj }, > + { "movcf2gr", la_codec_r_cj, la_fmt_fd_cj }, > + { "fcvt.s.d", la_codec_2r, la_fmt_fd_fj }, > + { "fcvt.d.s", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrm.w.s", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrm.w.d", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrm.l.s", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrm.l.d", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrp.w.s", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrp.w.d", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrp.l.s", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrp.l.d", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrz.w.s", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrz.w.d", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrz.l.s", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrz.l.d", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrne.w.s", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrne.w.d", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrne.l.s", la_codec_2r, la_fmt_fd_fj }, > + { "ftintrne.l.d", la_codec_2r, la_fmt_fd_fj }, > + { "ftint.w.s", la_codec_2r, la_fmt_fd_fj }, > + { "ftint.w.d", la_codec_2r, la_fmt_fd_fj }, > + { "ftint.l.s", la_codec_2r, la_fmt_fd_fj }, > + { "ftint.l.d", la_codec_2r, la_fmt_fd_fj }, > + { "ffint.s.w", la_codec_2r, la_fmt_fd_fj }, > + { "ffint.s.l", la_codec_2r, la_fmt_fd_fj }, > + { "ffint.d.w", la_codec_2r, la_fmt_fd_fj }, > + { "ffint.d.l", la_codec_2r, la_fmt_fd_fj }, > + { "frint.s", la_codec_2r, la_fmt_fd_fj }, > + { "frint.d", la_codec_2r, la_fmt_fd_fj }, > + { "slti", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "sltui", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "addi.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "addi.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "lu52i.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "addi", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "ori", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "xori", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "rdtimel.w", la_codec_2r, la_fmt_rd_rj }, > + { "rdtimeh.w", la_codec_2r, la_fmt_rd_rj }, > + { "fmadd.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, > + { "fmadd.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, > + { "fmsub.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, > + { "fmsub.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, > + { "fnmadd.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, > + { "fnmadd.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, > + { "fnmsub.s", la_codec_4r, la_fmt_fd_fj_fk_fa }, > + { "fnmsub.d", la_codec_4r, la_fmt_fd_fj_fk_fa }, > + { "fcmp.cond.s", la_codec_cond, la_fmt_s_cd_fj_fk }, > + { "fcmp.cond.d", la_codec_cond, la_fmt_d_cd_fj_fk }, > + { "fsel", la_codec_sel, la_fmt_fd_fj_fk_ca }, > + { "addu16i.d", la_codec_2r_im16, la_fmt_rd_rj_si16 }, > + { "lu12i.w", la_codec_r_im20, la_fmt_rd_si20 }, > + { "lu32i.d", la_codec_r_im20, la_fmt_rd_si20 }, > + { "pcaddi", la_codec_r_im20, la_fmt_rd_si20 }, > + { "pcalau12i", la_codec_r_im20, la_fmt_rd_si20 }, > + { "pcaddu12i", la_codec_r_im20, la_fmt_rd_si20 }, > + { "pcaddu18i", la_codec_r_im20, la_fmt_rd_si20 }, > + { "ll.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, > + { "sc.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, > + { "ll.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, > + { "sc.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, > + { "ldptr.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, > + { "stptr.w", la_codec_2r_im14, la_fmt_rd_rj_si14 }, > + { "ldptr.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, > + { "stptr.d", la_codec_2r_im14, la_fmt_rd_rj_si14 }, > + { "ld.b", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "ld.h", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "ld.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "ld.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "st.b", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "st.h", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "st.w", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "st.d", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "ld.bu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "ld.hu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "ld.wu", la_codec_2r_im12, la_fmt_rd_rj_si12 }, > + { "preld", la_codec_2r_im12, la_fmt_hint_rj_si12 }, > + { "fld.s", la_codec_2r_im12, la_fmt_fd_fj_si12 }, > + { "fst.s", la_codec_2r_im12, la_fmt_fd_fj_si12 }, > + { "fld.d", la_codec_2r_im12, la_fmt_fd_fj_si12 }, > + { "fst.d", la_codec_2r_im12, la_fmt_fd_fj_si12 }, > + { "ldx.b", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldx.h", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldx.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldx.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stx.b", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stx.h", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stx.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stx.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldx.bu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldx.hu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldx.wu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "fldx.s", la_codec_3r, la_fmt_fd_rj_rk }, > + { "fldx.d", la_codec_3r, la_fmt_fd_rj_rk }, > + { "fstx.s", la_codec_3r, la_fmt_fd_rj_rk }, > + { "fstx.d", la_codec_3r, la_fmt_fd_rj_rk }, > + { "amswap.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amswap.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amadd.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amadd.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amand.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amand.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amor.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amor.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amxor.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amxor.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammax.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammax.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammin.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammin.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammax.wu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammax.du", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammin.wu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammin.du", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amswap.db.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amswap.db.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amadd.db.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amadd.db.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amand.db.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amand.db.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amor.db.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amor.db.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amxor.db.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "amxor.db.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammax.db.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammax.db.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammin.db.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammin.db.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammax.db.wu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammax.db.du", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammin.db.wu", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ammin.db.du", la_codec_3r, la_fmt_rd_rj_rk }, > + { "dbar", la_codec_whint, la_fmt_whint }, > + { "ibar", la_codec_whint, la_fmt_whint }, > + { "fldgt.s", la_codec_3r, la_fmt_fd_rj_rk }, > + { "fldgt.d", la_codec_3r, la_fmt_fd_rj_rk }, > + { "fldle.s", la_codec_3r, la_fmt_fd_rj_rk }, > + { "fldle.d", la_codec_3r, la_fmt_fd_rj_rk }, > + { "fstgt.s", la_codec_3r, la_fmt_fd_rj_rk }, > + { "fstgt.d", la_codec_3r, la_fmt_fd_rj_rk }, > + { "fstle.s", la_codec_3r, la_fmt_fd_rj_rk }, > + { "fstle.d", la_codec_3r, la_fmt_fd_rj_rk }, > + { "ldgt.b", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldgt.h", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldgt.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldgt.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldle.b", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldle.h", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldle.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "ldle.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stgt.b", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stgt.h", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stgt.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stgt.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stle.b", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stle.h", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stle.w", la_codec_3r, la_fmt_rd_rj_rk }, > + { "stle.d", la_codec_3r, la_fmt_rd_rj_rk }, > + { "beqz", la_codec_r_ofs21, la_fmt_rj_offs21 }, > + { "bnez", la_codec_r_ofs21, la_fmt_rj_offs21 }, > + { "bceqz", la_codec_cj_ofs21, la_fmt_cj_offs21 }, > + { "bcnez", la_codec_cj_ofs21, la_fmt_cj_offs21 }, > + { "jirl", la_codec_2r_im16, la_fmt_rd_rj_offs16 }, > + { "b", la_codec_ofs26, la_fmt_offs26 }, > + { "bl", la_codec_ofs26, la_fmt_offs26 }, > + { "beq", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, > + { "bne", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, > + { "blt", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, > + { "bge", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, > + { "bltu", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, > + { "bgeu", la_codec_2r_im16, la_fmt_rj_rd_offs16 }, > + > +}; > + > + > +/* decode opcode */ > +static void decode_insn_opcode(la_decode *dec) > +{ > + uint32_t insn = dec->insn; > + uint16_t op = la_op_illegal; > + switch ((insn >> 26) & 0x3f) { > + case 0x0: > + switch ((insn >> 22) & 0xf) { > + case 0x0: > + switch ((insn >> 18) & 0xf) { > + case 0x0: > + switch ((insn >> 15) & 0x7) { > + case 0x0: > + switch ((insn >> 10) & 0x1f) { > + case 0x4: > + op = la_op_clo_w; > + break; > + case 0x5: > + op = la_op_clz_w; > + break; > + case 0x6: > + op = la_op_cto_w; > + break; > + case 0x7: > + op = la_op_ctz_w; > + break; > + case 0x8: > + op = la_op_clo_d; > + break; > + case 0x9: > + op = la_op_clz_d; > + break; > + case 0xa: > + op = la_op_cto_d; > + break; > + case 0xb: > + op = la_op_ctz_d; > + break; > + case 0xc: > + op = la_op_revb_2h; > + break; > + case 0xd: > + op = la_op_revb_4h; > + break; > + case 0xe: > + op = la_op_revb_2w; > + break; > + case 0xf: > + op = la_op_revb_d; > + break; > + case 0x10: > + op = la_op_revh_2w; > + break; > + case 0x11: > + op = la_op_revh_d; > + break; > + case 0x12: > + op = la_op_bitrev_4b; > + break; > + case 0x13: > + op = la_op_bitrev_8b; > + break; > + case 0x14: > + op = la_op_bitrev_w; > + break; > + case 0x15: > + op = la_op_bitrev_d; > + break; > + case 0x16: > + op = la_op_ext_w_h; > + break; > + case 0x17: > + op = la_op_ext_w_b; > + break; > + case 0x18: > + op = la_op_rdtimel_w; > + break; > + case 0x19: > + op = la_op_rdtimeh_w; > + break; > + case 0x1a: > + op = la_op_rdtime_d; > + break; > + case 0x1b: > + op = la_op_cpucfg; > + break; > + } > + break; > + case 0x2: > + switch (insn & 0x0000001f) { > + case 0x00000000: > + op = la_op_asrtle_d; > + break; > + } > + break; > + case 0x3: > + switch (insn & 0x0000001f) { > + case 0x00000000: > + op = la_op_asrtgt_d; > + break; > + } > + break; > + } > + break; > + case 0x1: > + switch ((insn >> 17) & 0x1) { > + case 0x0: > + op = la_op_alsl_w; > + break; > + case 0x1: > + op = la_op_alsl_wu; > + break; > + } > + break; > + case 0x2: > + switch ((insn >> 17) & 0x1) { > + case 0x0: > + op = la_op_bytepick_w; > + break; > + } > + break; > + case 0x3: > + op = la_op_bytepick_d; > + break; > + case 0x4: > + switch ((insn >> 15) & 0x7) { > + case 0x0: > + op = la_op_add_w; > + break; > + case 0x1: > + op = la_op_add_d; > + break; > + case 0x2: > + op = la_op_sub_w; > + break; > + case 0x3: > + op = la_op_sub_d; > + break; > + case 0x4: > + op = la_op_slt; > + break; > + case 0x5: > + op = la_op_sltu; > + break; > + case 0x6: > + op = la_op_maskeqz; > + break; > + case 0x7: > + op = la_op_masknez; > + break; > + } > + break; > + case 0x5: > + switch ((insn >> 15) & 0x7) { > + case 0x0: > + op = la_op_nor; > + break; > + case 0x1: > + op = la_op_and; > + break; > + case 0x2: > + op = la_op_or; > + break; > + case 0x3: > + op = la_op_xor; > + break; > + case 0x4: > + op = la_op_orn; > + break; > + case 0x5: > + op = la_op_andn; > + break; > + case 0x6: > + op = la_op_sll_w; > + break; > + case 0x7: > + op = la_op_srl_w; > + break; > + } > + break; > + case 0x6: > + switch ((insn >> 15) & 0x7) { > + case 0x0: > + op = la_op_sra_w; > + break; > + case 0x1: > + op = la_op_sll_d; > + break; > + case 0x2: > + op = la_op_srl_d; > + break; > + case 0x3: > + op = la_op_sra_d; > + break; > + case 0x6: > + op = la_op_rotr_w; > + break; > + case 0x7: > + op = la_op_rotr_d; > + break; > + } > + break; > + case 0x7: > + switch ((insn >> 15) & 0x7) { > + case 0x0: > + op = la_op_mul_w; > + break; > + case 0x1: > + op = la_op_mulh_w; > + break; > + case 0x2: > + op = la_op_mulh_wu; > + break; > + case 0x3: > + op = la_op_mul_d; > + break; > + case 0x4: > + op = la_op_mulh_d; > + break; > + case 0x5: > + op = la_op_mulh_du; > + break; > + case 0x6: > + op = la_op_mulw_d_w; > + break; > + case 0x7: > + op = la_op_mulw_d_wu; > + break; > + } > + break; > + case 0x8: > + switch ((insn >> 15) & 0x7) { > + case 0x0: > + op = la_op_div_w; > + break; > + case 0x1: > + op = la_op_mod_w; > + break; > + case 0x2: > + op = la_op_div_wu; > + break; > + case 0x3: > + op = la_op_mod_wu; > + break; > + case 0x4: > + op = la_op_div_d; > + break; > + case 0x5: > + op = la_op_mod_d; > + break; > + case 0x6: > + op = la_op_div_du; > + break; > + case 0x7: > + op = la_op_mod_du; > + break; > + } > + break; > + case 0x9: > + switch ((insn >> 15) & 0x7) { > + case 0x0: > + op = la_op_crc_w_b_w; > + break; > + case 0x1: > + op = la_op_crc_w_h_w; > + break; > + case 0x2: > + op = la_op_crc_w_w_w; > + break; > + case 0x3: > + op = la_op_crc_w_d_w; > + break; > + case 0x4: > + op = la_op_crcc_w_b_w; > + break; > + case 0x5: > + op = la_op_crcc_w_h_w; > + break; > + case 0x6: > + op = la_op_crcc_w_w_w; > + break; > + case 0x7: > + op = la_op_crcc_w_d_w; > + break; > + } > + break; > + case 0xa: > + switch ((insn >> 15) & 0x7) { > + case 0x4: > + op = la_op_break; > + break; > + case 0x6: > + op = la_op_syscall; > + break; > + } > + break; > + case 0xb: > + switch ((insn >> 17) & 0x1) { > + case 0x0: > + op = la_op_alsl_d; > + break; > + } > + break; > + } > + break; > + case 0x1: > + switch ((insn >> 21) & 0x1) { > + case 0x0: > + switch ((insn >> 16) & 0x1f) { > + case 0x0: > + switch ((insn >> 15) & 0x1) { > + case 0x1: > + op = la_op_slli_w; > + break; > + } > + break; > + case 0x1: > + op = la_op_slli_d; > + break; > + case 0x4: > + switch ((insn >> 15) & 0x1) { > + case 0x1: > + op = la_op_srli_w; > + break; > + } > + break; > + case 0x5: > + op = la_op_srli_d; > + break; > + case 0x8: > + switch ((insn >> 15) & 0x1) { > + case 0x1: > + op = la_op_srai_w; > + break; > + } > + break; > + case 0x9: > + op = la_op_srai_d; > + break; > + case 0xc: > + switch ((insn >> 15) & 0x1) { > + case 0x1: > + op = la_op_rotri_w; > + break; > + } > + break; > + case 0xd: > + op = la_op_rotri_d; > + break; > + } > + break; > + case 0x1: > + switch ((insn >> 15) & 0x1) { > + case 0x0: > + op = la_op_bstrins_w; > + break; > + case 0x1: > + op = la_op_bstrpick_w; > + break; > + } > + break; > + } > + break; > + case 0x2: > + op = la_op_bstrins_d; > + break; > + case 0x3: > + op = la_op_bstrpick_d; > + break; > + case 0x4: > + switch ((insn >> 15) & 0x7f) { > + case 0x1: > + op = la_op_fadd_s; > + break; > + case 0x2: > + op = la_op_fadd_d; > + break; > + case 0x5: > + op = la_op_fsub_s; > + break; > + case 0x6: > + op = la_op_fsub_d; > + break; > + case 0x9: > + op = la_op_fmul_s; > + break; > + case 0xa: > + op = la_op_fmul_d; > + break; > + case 0xd: > + op = la_op_fdiv_s; > + break; > + case 0xe: > + op = la_op_fdiv_d; > + break; > + case 0x11: > + op = la_op_fmax_s; > + break; > + case 0x12: > + op = la_op_fmax_d; > + break; > + case 0x15: > + op = la_op_fmin_s; > + break; > + case 0x16: > + op = la_op_fmin_d; > + break; > + case 0x19: > + op = la_op_fmaxa_s; > + break; > + case 0x1a: > + op = la_op_fmaxa_d; > + break; > + case 0x1d: > + op = la_op_fmina_s; > + break; > + case 0x1e: > + op = la_op_fmina_d; > + break; > + case 0x21: > + op = la_op_fscaleb_s; > + break; > + case 0x22: > + op = la_op_fscaleb_d; > + break; > + case 0x25: > + op = la_op_fcopysign_s; > + break; > + case 0x26: > + op = la_op_fcopysign_d; > + break; > + case 0x28: > + switch ((insn >> 10) & 0x1f) { > + case 0x1: > + op = la_op_fabs_s; > + break; > + case 0x2: > + op = la_op_fabs_d; > + break; > + case 0x5: > + op = la_op_fneg_s; > + break; > + case 0x6: > + op = la_op_fneg_d; > + break; > + case 0x9: > + op = la_op_flogb_s; > + break; > + case 0xa: > + op = la_op_flogb_d; > + break; > + case 0xd: > + op = la_op_fclass_s; > + break; > + case 0xe: > + op = la_op_fclass_d; > + break; > + case 0x11: > + op = la_op_fsqrt_s; > + break; > + case 0x12: > + op = la_op_fsqrt_d; > + break; > + case 0x15: > + op = la_op_frecip_s; > + break; > + case 0x16: > + op = la_op_frecip_d; > + break; > + case 0x19: > + op = la_op_frsqrt_s; > + break; > + case 0x1a: > + op = la_op_frsqrt_d; > + break; > + } > + break; > + case 0x29: > + switch ((insn >> 10) & 0x1f) { > + case 0x5: > + op = la_op_fmov_s; > + break; > + case 0x6: > + op = la_op_fmov_d; > + break; > + case 0x9: > + op = la_op_movgr2fr_w; > + break; > + case 0xa: > + op = la_op_movgr2fr_d; > + break; > + case 0xb: > + op = la_op_movgr2frh_w; > + break; > + case 0xd: > + op = la_op_movfr2gr_s; > + break; > + case 0xe: > + op = la_op_movfr2gr_d; > + break; > + case 0xf: > + op = la_op_movfrh2gr_s; > + break; > + case 0x10: > + op = la_op_movgr2fcsr; > + break; > + case 0x12: > + op = la_op_movfcsr2gr; > + break; > + case 0x14: > + switch ((insn >> 3) & 0x3) { > + case 0x0: > + op = la_op_movfr2cf; > + break; > + } > + break; > + case 0x15: > + switch ((insn >> 8) & 0x3) { > + case 0x0: > + op = la_op_movcf2fr; > + break; > + } > + break; > + case 0x16: > + switch ((insn >> 3) & 0x3) { > + case 0x0: > + op = la_op_movgr2cf; > + break; > + } > + break; > + case 0x17: > + switch ((insn >> 8) & 0x3) { > + case 0x0: > + op = la_op_movcf2gr; > + break; > + } > + break; > + } > + break; > + case 0x32: > + switch ((insn >> 10) & 0x1f) { > + case 0x6: > + op = la_op_fcvt_s_d; > + break; > + case 0x9: > + op = la_op_fcvt_d_s; > + break; > + } > + break; > + case 0x34: > + switch ((insn >> 10) & 0x1f) { > + case 0x1: > + op = la_op_ftintrm_w_s; > + break; > + case 0x2: > + op = la_op_ftintrm_w_d; > + break; > + case 0x9: > + op = la_op_ftintrm_l_s; > + break; > + case 0xa: > + op = la_op_ftintrm_l_d; > + break; > + case 0x11: > + op = la_op_ftintrp_w_s; > + break; > + case 0x12: > + op = la_op_ftintrp_w_d; > + break; > + case 0x19: > + op = la_op_ftintrp_l_s; > + break; > + case 0x1a: > + op = la_op_ftintrp_l_d; > + break; > + } > + break; > + case 0x35: > + switch ((insn >> 10) & 0x1f) { > + case 0x1: > + op = la_op_ftintrz_w_s; > + break; > + case 0x2: > + op = la_op_ftintrz_w_d; > + break; > + case 0x9: > + op = la_op_ftintrz_l_s; > + break; > + case 0xa: > + op = la_op_ftintrz_l_d; > + break; > + case 0x11: > + op = la_op_ftintrne_w_s; > + break; > + case 0x12: > + op = la_op_ftintrne_w_d; > + break; > + case 0x19: > + op = la_op_ftintrne_l_s; > + break; > + case 0x1a: > + op = la_op_ftintrne_l_d; > + break; > + } > + break; > + case 0x36: > + switch ((insn >> 10) & 0x1f) { > + case 0x1: > + op = la_op_ftint_w_s; > + break; > + case 0x2: > + op = la_op_ftint_w_d; > + break; > + case 0x9: > + op = la_op_ftint_l_s; > + break; > + case 0xa: > + op = la_op_ftint_l_d; > + break; > + } > + break; > + case 0x3a: > + switch ((insn >> 10) & 0x1f) { > + case 0x4: > + op = la_op_ffint_s_w; > + break; > + case 0x6: > + op = la_op_ffint_s_l; > + break; > + case 0x8: > + op = la_op_ffint_d_w; > + break; > + case 0xa: > + op = la_op_ffint_d_l; > + break; > + } > + break; > + case 0x3c: > + switch ((insn >> 10) & 0x1f) { > + case 0x11: > + op = la_op_frint_s; > + break; > + case 0x12: > + op = la_op_frint_d; > + break; > + } > + break; > + } > + break; > + case 0x8: > + op = la_op_slti; > + break; > + case 0x9: > + op = la_op_sltui; > + break; > + case 0xa: > + op = la_op_addi_w; > + break; > + case 0xb: > + op = la_op_addi_d; > + break; > + case 0xc: > + op = la_op_lu52i_d; > + break; > + case 0xd: > + op = la_op_addi; > + break; > + case 0xe: > + op = la_op_ori; > + break; > + case 0xf: > + op = la_op_xori; > + break; > + } > + break; > + case 0x2: > + switch ((insn >> 20) & 0x3f) { > + case 0x1: > + op = la_op_fmadd_s; > + break; > + case 0x2: > + op = la_op_fmadd_d; > + break; > + case 0x5: > + op = la_op_fmsub_s; > + break; > + case 0x6: > + op = la_op_fmsub_d; > + break; > + case 0x9: > + op = la_op_fnmadd_s; > + break; > + case 0xa: > + op = la_op_fnmadd_d; > + break; > + case 0xd: > + op = la_op_fnmsub_s; > + break; > + case 0xe: > + op = la_op_fnmsub_d; > + break; > + } > + break; > + case 0x3: > + switch ((insn >> 20) & 0x3f) { > + case 0x1: > + switch ((insn >> 3) & 0x3) { > + case 0x0: > + op = la_op_fcmp_cond_s; > + break; > + } > + break; > + case 0x2: > + switch ((insn >> 3) & 0x3) { > + case 0x0: > + op = la_op_fcmp_cond_d; > + break; > + } > + break; > + case 0x10: > + switch ((insn >> 18) & 0x3) { > + case 0x0: > + op = la_op_fsel; > + break; > + } > + break; > + } > + break; > + case 0x4: > + op = la_op_addu16i_d; > + break; > + case 0x5: > + switch ((insn >> 25) & 0x1) { > + case 0x0: > + op = la_op_lu12i_w; > + break; > + case 0x1: > + op = la_op_lu32i_d; > + break; > + } > + break; > + case 0x6: > + switch ((insn >> 25) & 0x1) { > + case 0x0: > + op = la_op_pcaddi; > + break; > + case 0x1: > + op = la_op_pcalau12i; > + break; > + } > + break; > + case 0x7: > + switch ((insn >> 25) & 0x1) { > + case 0x0: > + op = la_op_pcaddu12i; > + break; > + case 0x1: > + op = la_op_pcaddu18i; > + break; > + } > + break; > + case 0x8: > + switch ((insn >> 24) & 0x3) { > + case 0x0: > + op = la_op_ll_w; > + break; > + case 0x1: > + op = la_op_sc_w; > + break; > + case 0x2: > + op = la_op_ll_d; > + break; > + case 0x3: > + op = la_op_sc_d; > + break; > + } > + break; > + case 0x9: > + switch ((insn >> 24) & 0x3) { > + case 0x0: > + op = la_op_ldptr_w; > + break; > + case 0x1: > + op = la_op_stptr_w; > + break; > + case 0x2: > + op = la_op_ldptr_d; > + break; > + case 0x3: > + op = la_op_stptr_d; > + break; > + } > + break; > + case 0xa: > + switch ((insn >> 22) & 0xf) { > + case 0x0: > + op = la_op_ld_b; > + break; > + case 0x1: > + op = la_op_ld_h; > + break; > + case 0x2: > + op = la_op_ld_w; > + break; > + case 0x3: > + op = la_op_ld_d; > + break; > + case 0x4: > + op = la_op_st_b; > + break; > + case 0x5: > + op = la_op_st_h; > + break; > + case 0x6: > + op = la_op_st_w; > + break; > + case 0x7: > + op = la_op_st_d; > + break; > + case 0x8: > + op = la_op_ld_bu; > + break; > + case 0x9: > + op = la_op_ld_hu; > + break; > + case 0xa: > + op = la_op_ld_wu; > + break; > + case 0xb: > + op = la_op_preld; > + break; > + case 0xc: > + op = la_op_fld_s; > + break; > + case 0xd: > + op = la_op_fst_s; > + break; > + case 0xe: > + op = la_op_fld_d; > + break; > + case 0xf: > + op = la_op_fst_d; > + break; > + } > + break; > + case 0xe: > + switch ((insn >> 15) & 0x7ff) { > + case 0x0: > + op = la_op_ldx_b; > + break; > + case 0x8: > + op = la_op_ldx_h; > + break; > + case 0x10: > + op = la_op_ldx_w; > + break; > + case 0x18: > + op = la_op_ldx_d; > + break; > + case 0x20: > + op = la_op_stx_b; > + break; > + case 0x28: > + op = la_op_stx_h; > + break; > + case 0x30: > + op = la_op_stx_w; > + break; > + case 0x38: > + op = la_op_stx_d; > + break; > + case 0x40: > + op = la_op_ldx_bu; > + break; > + case 0x48: > + op = la_op_ldx_hu; > + break; > + case 0x50: > + op = la_op_ldx_wu; > + break; > + case 0x60: > + op = la_op_fldx_s; > + break; > + case 0x68: > + op = la_op_fldx_d; > + break; > + case 0x70: > + op = la_op_fstx_s; > + break; > + case 0x78: > + op = la_op_fstx_d; > + break; > + case 0xc0: > + op = la_op_amswap_w; > + break; > + case 0xc1: > + op = la_op_amswap_d; > + break; > + case 0xc2: > + op = la_op_amadd_w; > + break; > + case 0xc3: > + op = la_op_amadd_d; > + break; > + case 0xc4: > + op = la_op_amand_w; > + break; > + case 0xc5: > + op = la_op_amand_d; > + break; > + case 0xc6: > + op = la_op_amor_w; > + break; > + case 0xc7: > + op = la_op_amor_d; > + break; > + case 0xc8: > + op = la_op_amxor_w; > + break; > + case 0xc9: > + op = la_op_amxor_d; > + break; > + case 0xca: > + op = la_op_ammax_w; > + break; > + case 0xcb: > + op = la_op_ammax_d; > + break; > + case 0xcc: > + op = la_op_ammin_w; > + break; > + case 0xcd: > + op = la_op_ammin_d; > + break; > + case 0xce: > + op = la_op_ammax_wu; > + break; > + case 0xcf: > + op = la_op_ammax_du; > + break; > + case 0xd0: > + op = la_op_ammin_wu; > + break; > + case 0xd1: > + op = la_op_ammin_du; > + break; > + case 0xd2: > + op = la_op_amswap_db_w; > + break; > + case 0xd3: > + op = la_op_amswap_db_d; > + break; > + case 0xd4: > + op = la_op_amadd_db_w; > + break; > + case 0xd5: > + op = la_op_amadd_db_d; > + break; > + case 0xd6: > + op = la_op_amand_db_w; > + break; > + case 0xd7: > + op = la_op_amand_db_d; > + break; > + case 0xd8: > + op = la_op_amor_db_w; > + break; > + case 0xd9: > + op = la_op_amor_db_d; > + break; > + case 0xda: > + op = la_op_amxor_db_w; > + break; > + case 0xdb: > + op = la_op_amxor_db_d; > + break; > + case 0xdc: > + op = la_op_ammax_db_w; > + break; > + case 0xdd: > + op = la_op_ammax_db_d; > + break; > + case 0xde: > + op = la_op_ammin_db_w; > + break; > + case 0xdf: > + op = la_op_ammin_db_d; > + break; > + case 0xe0: > + op = la_op_ammax_db_wu; > + break; > + case 0xe1: > + op = la_op_ammax_db_du; > + break; > + case 0xe2: > + op = la_op_ammin_db_wu; > + break; > + case 0xe3: > + op = la_op_ammin_db_du; > + break; > + case 0xe4: > + op = la_op_dbar; > + break; > + case 0xe5: > + op = la_op_ibar; > + break; > + case 0xe8: > + op = la_op_fldgt_s; > + break; > + case 0xe9: > + op = la_op_fldgt_d; > + break; > + case 0xea: > + op = la_op_fldle_s; > + break; > + case 0xeb: > + op = la_op_fldle_d; > + break; > + case 0xec: > + op = la_op_fstgt_s; > + break; > + case 0xed: > + op = la_op_fstgt_d; > + break; > + case 0xee: > + op = ls_op_fstle_s; > + break; > + case 0xef: > + op = la_op_fstle_d; > + break; > + case 0xf0: > + op = la_op_ldgt_b; > + break; > + case 0xf1: > + op = la_op_ldgt_h; > + break; > + case 0xf2: > + op = la_op_ldgt_w; > + break; > + case 0xf3: > + op = la_op_ldgt_d; > + break; > + case 0xf4: > + op = la_op_ldle_b; > + break; > + case 0xf5: > + op = la_op_ldle_h; > + break; > + case 0xf6: > + op = la_op_ldle_w; > + break; > + case 0xf7: > + op = la_op_ldle_d; > + break; > + case 0xf8: > + op = la_op_stgt_b; > + break; > + case 0xf9: > + op = la_op_stgt_h; > + break; > + case 0xfa: > + op = la_op_stgt_w; > + break; > + case 0xfb: > + op = la_op_stgt_d; > + break; > + case 0xfc: > + op = la_op_stle_b; > + break; > + case 0xfd: > + op = la_op_stle_h; > + break; > + case 0xfe: > + op = la_op_stle_w; > + break; > + case 0xff: > + op = la_op_stle_d; > + break; > + } > + break; > + case 0x10: > + op = la_op_beqz; > + break; > + case 0x11: > + op = la_op_bnez; > + break; > + case 0x12: > + switch ((insn >> 8) & 0x3) { > + case 0x0: > + op = la_op_bceqz; > + break; > + case 0x1: > + op = la_op_bcnez; > + break; > + } > + break; > + case 0x13: > + op = la_op_jirl; > + break; > + case 0x14: > + op = la_op_b; > + break; > + case 0x15: > + op = la_op_bl; > + break; > + case 0x16: > + op = la_op_beq; > + break; > + case 0x17: > + op = la_op_bne; > + break; > + case 0x18: > + op = la_op_blt; > + break; > + case 0x19: > + op = la_op_bge; > + break; > + case 0x1a: > + op = la_op_bltu; > + break; > + case 0x1b: > + op = la_op_bgeu; > + break; > + default: > + op = la_op_illegal; > + break; > + } > + dec->op = op; > +} > + > +/* operand extractors */ > +#define IM_5 5 > +#define IM_8 8 > +#define IM_12 12 > +#define IM_14 14 > +#define IM_15 15 > +#define IM_16 16 > +#define IM_20 20 > +#define IM_21 21 > +#define IM_26 26 > + > +static uint32_t operand_r1(uint32_t insn) > +{ > + return insn & 0x1f; > +} > + > +static uint32_t operand_r2(uint32_t insn) > +{ > + return (insn >> 5) & 0x1f; > +} > + > +static uint32_t operand_r3(uint32_t insn) > +{ > + return (insn >> 10) & 0x1f; > +} > + > +static uint32_t operand_r4(uint32_t insn) > +{ > + return (insn >> 15) & 0x1f; > +} > + > +static uint32_t operand_u6(uint32_t insn) > +{ > + return (insn >> 10) & 0x3f; > +} > + > +static uint32_t operand_bw1(uint32_t insn) > +{ > + return (insn >> 10) & 0x1f; > +} > + > +static uint32_t operand_bw2(uint32_t insn) > +{ > + return (insn >> 16) & 0x1f; > +} > + > +static uint32_t operand_bd1(uint32_t insn) > +{ > + return (insn >> 10) & 0x3f; > +} > + > +static uint32_t operand_bd2(uint32_t insn) > +{ > + return (insn >> 16) & 0x3f; > +} > + > +static uint32_t operand_sa2(uint32_t insn) > +{ > + return (insn >> 15) & 0x3; > +} > + > +static uint32_t operand_sa3(uint32_t insn) > +{ > + return (insn >> 15) & 0x3; > +} > + > +static int32_t operand_im20(uint32_t insn) > +{ > + int32_t imm = (int32_t)((insn >> 5) & 0xfffff); > + return imm > (1 << 19) ? imm - (1 << 20) : imm; > +} > + > +static int32_t operand_im16(uint32_t insn) > +{ > + int32_t imm = (int32_t)((insn >> 10) & 0xffff); > + return imm > (1 << 15) ? imm - (1 << 16) : imm; > +} > + > +static int32_t operand_im14(uint32_t insn) > +{ > + int32_t imm = (int32_t)((insn >> 10) & 0x3fff); > + return imm > (1 << 13) ? imm - (1 << 14) : imm; > +} > + > +static int32_t operand_im12(uint32_t insn) > +{ > + int32_t imm = (int32_t)((insn >> 10) & 0xfff); > + return imm > (1 << 11) ? imm - (1 << 12) : imm; > +} > + > +static int32_t operand_im8(uint32_t insn) > +{ > + int32_t imm = (int32_t)((insn >> 10) & 0xff); > + return imm > (1 << 7) ? imm - (1 << 8) : imm; > +} > + > +static uint32_t operand_sd(uint32_t insn) > +{ > + return insn & 0x3; > +} > + > +static uint32_t operand_sj(uint32_t insn) > +{ > + return (insn >> 5) & 0x3; > +} > + > +static uint32_t operand_cd(uint32_t insn) > +{ > + return insn & 0x7; > +} > + > +static uint32_t operand_cj(uint32_t insn) > +{ > + return (insn >> 5) & 0x7; > +} > + > +static uint32_t operand_code(uint32_t insn) > +{ > + return insn & 0x7fff; > +} > + > +static int32_t operand_whint(uint32_t insn) > +{ > + int32_t imm = (int32_t)(insn & 0x7fff); > + return imm > (1 << 14) ? imm - (1 << 15) : imm; > +} > + > +static int32_t operand_invop(uint32_t insn) > +{ > + int32_t imm = (int32_t)(insn & 0x1f); > + return imm > (1 << 4) ? imm - (1 << 5) : imm; > +} > + > +static int32_t operand_ofs21(uint32_t insn) > +{ > + int32_t imm = (((int32_t)insn & 0x1f) << 16) | > + ((insn >> 10) & 0xffff); > + return imm > (1 << 20) ? imm - (1 << 21) : imm; > +} > + > +static int32_t operand_ofs26(uint32_t insn) > +{ > + int32_t imm = (((int32_t)insn & 0x3ff) << 16) | > + ((insn >> 10) & 0xffff); > + return imm > (1 << 25) ? imm - (1 << 26) : imm; > +} > + > +static uint32_t operand_fcond(uint32_t insn) > +{ > + return (insn >> 15) & 0x1f; > +} > + > +static uint32_t operand_sel(uint32_t insn) > +{ > + return (insn >> 15) & 0x7; > +} > + > +/* decode operands */ > +static void decode_insn_operands(la_decode *dec) > +{ > + uint32_t insn = dec->insn; > + dec->codec = opcode_data[dec->op].codec; > + switch (dec->codec) { > + case la_codec_illegal: > + case la_codec_empty: > + break; > + case la_codec_2r: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + break; > + case la_codec_2r_u5: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_r3(insn); > + break; > + case la_codec_2r_u6: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_u6(insn); > + break; > + case la_codec_2r_2bw: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_bw1(insn); > + dec->r4 = operand_bw2(insn); > + break; > + case la_codec_2r_2bd: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_bd1(insn); > + dec->r4 = operand_bd2(insn); > + break; > + case la_codec_3r: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_r3(insn); > + break; > + case la_codec_3r_rd0: > + dec->r1 = 0; > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_r3(insn); > + break; > + case la_codec_3r_sa2: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_r3(insn); > + dec->r4 = operand_sa2(insn); > + break; > + case la_codec_3r_sa3: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_r3(insn); > + dec->r4 = operand_sa3(insn); > + break; > + case la_codec_4r: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_r3(insn); > + dec->r4 = operand_r4(insn); > + break; > + case la_codec_r_im20: > + dec->r1 = operand_r1(insn); > + dec->imm = operand_im20(insn); > + dec->bit = IM_20; > + break; > + case la_codec_2r_im16: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->imm = operand_im16(insn); > + dec->bit = IM_16; > + break; > + case la_codec_2r_im14: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->imm = operand_im14(insn); > + dec->bit = IM_14; > + break; > + case la_codec_r_im14: > + dec->r1 = operand_r1(insn); > + dec->imm = operand_im14(insn); > + dec->bit = IM_14; > + break; > + case la_codec_im5_r_im12: > + dec->imm2 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->imm = operand_im12(insn); > + dec->bit = IM_12; > + break; > + case la_codec_2r_im12: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->imm = operand_im12(insn); > + dec->bit = IM_12; > + break; > + case la_codec_2r_im8: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->imm = operand_im8(insn); > + dec->bit = IM_8; > + break; > + case la_codec_r_sd: > + dec->r1 = operand_sd(insn); > + dec->r2 = operand_r2(insn); > + break; > + case la_codec_r_sj: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_sj(insn); > + break; > + case la_codec_r_cd: > + dec->r1 = operand_cd(insn); > + dec->r2 = operand_r2(insn); > + break; > + case la_codec_r_cj: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_cj(insn); > + break; > + case la_codec_r_seq: > + dec->r1 = 0; > + dec->r2 = operand_r1(insn); > + dec->imm = operand_im8(insn); > + dec->bit = IM_8; > + break; > + case la_codec_code: > + dec->code = operand_code(insn); > + break; > + case la_codec_whint: > + dec->imm = operand_whint(insn); > + dec->bit = IM_15; > + break; > + case la_codec_invtlb: > + dec->imm = operand_invop(insn); > + dec->bit = IM_5; > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_r3(insn); > + break; > + case la_codec_r_ofs21: > + dec->imm = operand_ofs21(insn); > + dec->bit = IM_21; > + dec->r2 = operand_r2(insn); > + break; > + case la_codec_cj_ofs21: > + dec->imm = operand_ofs21(insn); > + dec->bit = IM_21; > + dec->r2 = operand_cj(insn); > + break; > + case la_codec_ofs26: > + dec->imm = operand_ofs26(insn); > + dec->bit = IM_26; > + break; > + case la_codec_cond: > + dec->r1 = operand_cd(insn); > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_r3(insn); > + dec->r4 = operand_fcond(insn); > + break; > + case la_codec_sel: > + dec->r1 = operand_r1(insn); > + dec->r2 = operand_r2(insn); > + dec->r3 = operand_r3(insn); > + dec->r4 = operand_sel(insn); > + break; > + } > +} > + > +/* format instruction */ > +static void append(char *s1, const char *s2, size_t n) > +{ > + size_t l1 = strlen(s1); > + if (n - l1 - 1 > 0) { > + strncat(s1, s2, n - l1); > + } > +} > + > +static void format_insn(char *buf, size_t buflen, size_t tab, la_decode *dec) > +{ > + char tmp[16]; > + const char *fmt; > + > + fmt = opcode_data[dec->op].format; > + while (*fmt) { > + switch (*fmt) { > + case 'n': /* name */ > + append(buf, opcode_data[dec->op].name, buflen); > + break; > + case 's': > + append(buf, "s", buflen); > + break; > + case 'd': > + append(buf, "d", buflen); > + break; > + case 'e': /* illegal */ > + snprintf(tmp, sizeof(tmp), "%x", dec->insn); > + append(buf, tmp, buflen); > + break; > + case 't': > + while (strlen(buf) < tab) { > + append(buf, " ", buflen); > + } > + break; > + case '(': > + append(buf, "(", buflen); > + break; > + case ',': > + append(buf, ",", buflen); > + break; > + case '.': > + append(buf, ".", buflen); > + break; > + case ')': > + append(buf, ")", buflen); > + break; > + case '0': /* rd */ > + append(buf, loongarch_r_normal_name[dec->r1], buflen); > + break; > + case '1': /* rj */ > + append(buf, loongarch_r_normal_name[dec->r2], buflen); > + break; > + case '2': /* rk */ > + append(buf, loongarch_r_normal_name[dec->r3], buflen); > + break; > + case '3': /* fd */ > + append(buf, loongarch_f_normal_name[dec->r1], buflen); > + break; > + case '4': /* fj */ > + append(buf, loongarch_f_normal_name[dec->r2], buflen); > + break; > + case '5': /* fk */ > + append(buf, loongarch_f_normal_name[dec->r3], buflen); > + break; > + case '6': /* fa */ > + append(buf, loongarch_f_normal_name[dec->r4], buflen); > + break; > + case 'A': /* sd */ > + append(buf, loongarch_cr_normal_name[dec->r1], buflen); > + break; > + case 'B': /* sj */ > + append(buf, loongarch_cr_normal_name[dec->r2], buflen); > + break; > + case 'C': /* r3 */ > + snprintf(tmp, sizeof(tmp), "%x", dec->r3); > + append(buf, tmp, buflen); > + break; > + case 'D': /* r4 */ > + snprintf(tmp, sizeof(tmp), "%x", dec->r4); > + append(buf, tmp, buflen); > + break; > + case 'E': /* r1 */ > + snprintf(tmp, sizeof(tmp), "%x", dec->r1); > + append(buf, tmp, buflen); > + break; > + case 'F': /* fcsrd */ > + append(buf, loongarch_r_normal_name[dec->r1], buflen); > + break; > + case 'G': /* fcsrs */ > + append(buf, loongarch_r_normal_name[dec->r2], buflen); > + break; > + case 'H': /* cd */ > + append(buf, loongarch_c_normal_name[dec->r1], buflen); > + break; > + case 'I': /* cj */ > + append(buf, loongarch_c_normal_name[dec->r2], buflen); > + break; > + case 'J': /* code */ > + snprintf(tmp, sizeof(tmp), "0x%x", dec->code); > + append(buf, tmp, buflen); > + break; > + case 'K': /* cond */ > + switch (dec->r4) { > + case 0x0: > + append(buf, "caf", buflen); > + break; > + case 0x1: > + append(buf, "saf", buflen); > + break; > + case 0x2: > + append(buf, "clt", buflen); > + break; > + case 0x3: > + append(buf, "slt", buflen); > + break; > + case 0x4: > + append(buf, "ceq", buflen); > + break; > + case 0x5: > + append(buf, "seq", buflen); > + break; > + case 0x6: > + append(buf, "cle", buflen); > + break; > + case 0x7: > + append(buf, "sle", buflen); > + break; > + case 0x8: > + append(buf, "cun", buflen); > + break; > + case 0x9: > + append(buf, "sun", buflen); > + break; > + case 0xA: > + append(buf, "cult", buflen); > + break; > + case 0xB: > + append(buf, "sult", buflen); > + break; > + case 0xC: > + append(buf, "cueq", buflen); > + break; > + case 0xD: > + append(buf, "sueq", buflen); > + break; > + case 0xE: > + append(buf, "cule", buflen); > + break; > + case 0xF: > + append(buf, "sule", buflen); > + break; > + case 0x10: > + append(buf, "cne", buflen); > + break; > + case 0x11: > + append(buf, "sne", buflen); > + break; > + case 0x14: > + append(buf, "cor", buflen); > + break; > + case 0x15: > + append(buf, "sor", buflen); > + break; > + case 0x18: > + append(buf, "cune", buflen); > + break; > + case 0x19: > + append(buf, "sune", buflen); > + break; > + } > + break; > + case 'L': /* ca */ > + append(buf, loongarch_c_normal_name[dec->r4], buflen); > + break; > + case 'M': /* cop */ > + snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm2) & 0x1f); > + append(buf, tmp, buflen); > + break; > + case 'i': /* sixx d */ > + snprintf(tmp, sizeof(tmp), "%d", dec->imm); > + append(buf, tmp, buflen); > + break; > + case 'o': /* offset */ > + snprintf(tmp, sizeof(tmp), "%d", (dec->imm) << 2); > + append(buf, tmp, buflen); > + break; > + case 'x': /* sixx x */ > + switch (dec->bit) { > + case IM_5: > + snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x1f); > + append(buf, tmp, buflen); > + break; > + case IM_8: > + snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xff); > + append(buf, tmp, buflen); > + break; > + case IM_12: > + snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xfff); > + append(buf, tmp, buflen); > + break; > + case IM_14: > + snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x3fff); > + append(buf, tmp, buflen); > + break; > + case IM_15: > + snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0x7fff); > + append(buf, tmp, buflen); > + break; > + case IM_16: > + snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xffff); > + append(buf, tmp, buflen); > + break; > + case IM_20: > + snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) & 0xfffff); > + append(buf, tmp, buflen); > + break; > + default: > + snprintf(tmp, sizeof(tmp), "0x%x", dec->imm); > + append(buf, tmp, buflen); > + break; > + } > + break; > + case 'X': /* offset x*/ > + switch (dec->bit) { > + case IM_16: > + snprintf(tmp, sizeof(tmp), "0x%x", > + ((dec->imm) << 2) & 0xffff); > + append(buf, tmp, buflen); > + break; > + case IM_21: > + snprintf(tmp, sizeof(tmp), "0x%x", > + ((dec->imm) << 2) & 0x1fffff); > + append(buf, tmp, buflen); > + break; > + case IM_26: > + snprintf(tmp, sizeof(tmp), "0x%x", > + ((dec->imm) << 2) & 0x3ffffff); > + append(buf, tmp, buflen); > + break; > + default: > + snprintf(tmp, sizeof(tmp), "0x%x", (dec->imm) << 2); > + append(buf, tmp, buflen); > + break; > + } > + break; > + case 'p': /* pc */ > + snprintf(tmp, sizeof(tmp), " # 0x%"PRIx32"", > + dec->pc + ((dec->imm) << 2)); > + append(buf, tmp, buflen); > + break; > + default: > + break; > + } > + fmt++; > + } > +} > + > +/* disassemble instruction */ > +static void > +disasm_insn(char *buf, size_t buflen, bfd_vma pc, unsigned long int insn) > +{ > + la_decode dec = { 0 }; > + dec.pc = pc; > + dec.insn = insn; > + decode_insn_opcode(&dec); > + decode_insn_operands(&dec); > + format_insn(buf, buflen, 16, &dec); > +} > + > +int > +print_insn_loongarch(bfd_vma memaddr, struct disassemble_info *info) > +{ > + char buf[128] = { 0 }; > + bfd_byte buffer[INSNLEN]; > + unsigned long insn; > + int status; > + > + status = (*info->read_memory_func)(memaddr, buffer, INSNLEN, info); > + if (status == 0) { > + insn = (uint32_t) bfd_getl32(buffer); > + (*info->fprintf_func)(info->stream, "%08" PRIx64 " ", insn); > + } else { > + (*info->memory_error_func)(status, memaddr, info); > + return -1; > + } > + disasm_insn(buf, sizeof(buf), memaddr, insn); > + (*info->fprintf_func)(info->stream, "\t%s", buf); > + return INSNLEN; > +} > diff --git a/disas/meson.build b/disas/meson.build > index 449f99e..a1bd8b8 100644 > --- a/disas/meson.build > +++ b/disas/meson.build > @@ -9,6 +9,7 @@ common_ss.add(when: 'CONFIG_CRIS_DIS', if_true: files('cris.c')) > common_ss.add(when: 'CONFIG_HEXAGON_DIS', if_true: files('hexagon.c')) > common_ss.add(when: 'CONFIG_HPPA_DIS', if_true: files('hppa.c')) > common_ss.add(when: 'CONFIG_I386_DIS', if_true: files('i386.c')) > +common_ss.add(when: 'CONFIG_LOONGARCH_DIS', if_true: files('loongarch.c')) > common_ss.add(when: 'CONFIG_M68K_DIS', if_true: files('m68k.c')) > common_ss.add(when: 'CONFIG_MICROBLAZE_DIS', if_true: files('microblaze.c')) > common_ss.add(when: 'CONFIG_MIPS_DIS', if_true: files('mips.c')) > diff --git a/include/disas/dis-asm.h b/include/disas/dis-asm.h > index 524f291..009a03a 100644 > --- a/include/disas/dis-asm.h > +++ b/include/disas/dis-asm.h > @@ -253,6 +253,7 @@ enum bfd_architecture > #define bfd_mach_rx 0x75 > #define bfd_mach_rx_v2 0x76 > #define bfd_mach_rx_v3 0x77 > + bfd_arch_loongarch, > bfd_arch_last > }; > #define bfd_mach_s390_31 31 > @@ -462,6 +463,7 @@ int print_insn_riscv32 (bfd_vma, disassemble_info*); > int print_insn_riscv64 (bfd_vma, disassemble_info*); > int print_insn_rx(bfd_vma, disassemble_info *); > int print_insn_hexagon(bfd_vma, disassemble_info *); > +int print_insn_loongarch(bfd_vma, disassemble_info *); > > #ifdef CONFIG_CAPSTONE > bool cap_disas_target(disassemble_info *info, uint64_t pc, size_t size); > diff --git a/meson.build b/meson.build > index 6b7487b..c272e58 100644 > --- a/meson.build > +++ b/meson.build > @@ -1797,6 +1797,7 @@ disassemblers = { > 'sh4' : ['CONFIG_SH4_DIS'], > 'sparc' : ['CONFIG_SPARC_DIS'], > 'xtensa' : ['CONFIG_XTENSA_DIS'], > + 'loongarch' : ['CONFIG_LOONGARCH_DIS'], > } > if link_language == 'cpp' > disassemblers += {