From nobody Tue Apr 16 17:23:07 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1631625594807907.747390612874; Tue, 14 Sep 2021 06:19:54 -0700 (PDT) Received: from localhost ([::1]:43548 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mQ8Lq-0007ig-2e for importer@patchew.org; Tue, 14 Sep 2021 09:19:54 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37780) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mQ84G-0006Hv-3y for qemu-devel@nongnu.org; Tue, 14 Sep 2021 09:01:45 -0400 Received: from mail.loongson.cn ([114.242.206.163]:57914 helo=loongson.cn) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mQ848-00085j-7W for qemu-devel@nongnu.org; Tue, 14 Sep 2021 09:01:43 -0400 Received: from kvm-dev1.localdomain (unknown [10.2.5.134]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9DxheXvnEBhNJ0GAA--.21668S18; Tue, 14 Sep 2021 21:01:19 +0800 (CST) From: Song Gao To: qemu-devel@nongnu.org Subject: [PATCH v5 16/21] target/loongarch: Add disassembler Date: Tue, 14 Sep 2021 21:00:26 +0800 Message-Id: <1631624431-30658-17-git-send-email-gaosong@loongson.cn> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1631624431-30658-1-git-send-email-gaosong@loongson.cn> References: <1631624431-30658-1-git-send-email-gaosong@loongson.cn> X-CM-TRANSID: AQAAf9DxheXvnEBhNJ0GAA--.21668S18 X-Coremail-Antispam: 1UD129KBjvAXoWDWFy7Zw4DGF1xZF1rKw1DAwb_yoW7tF47Wo WUJrs5Xws5Ar4DXFZFyF1akayrWr95XFy7Jry8Zwnrtrs3Aw1DWr98Jas5AFy3AFs0krWx G3Z7Cry8KrZ7GFW8n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjDUYxBIdaVFxhVjvjDU0xZFpf9x0zRUUUUUUUUU= X-CM-SenderInfo: 5jdr20tqj6z05rqj20fqof0/ Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=114.242.206.163; envelope-from=gaosong@loongson.cn; helo=loongson.cn X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham 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, philmd@redhat.com, richard.henderson@linaro.org, laurent@vivier.eu, peterx@redhat.com, gaosong@loongson.cn, yangxiaojuan@loongson.cn, alistair.francis@wdc.com, maobibo@loongson.cn, pbonzini@redhat.com, bmeng.cn@gmail.com, alex.bennee@linaro.org, chenhuacai@loongson.cn Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1631625595801100001 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 diff --git a/MAINTAINERS b/MAINTAINERS index ad372a2..44b37ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -214,6 +214,7 @@ LoongArch TCG CPUS M: Song Gao S: Maintained F: target/loongarch/ +F: disas/loongarch.c =20 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 =3D 0, + la_op_clo_w =3D 1, + la_op_clz_w =3D 2, + la_op_cto_w =3D 3, + la_op_ctz_w =3D 4, + la_op_clo_d =3D 5, + la_op_clz_d =3D 6, + la_op_cto_d =3D 7, + la_op_ctz_d =3D 8, + la_op_revb_2h =3D 9, + la_op_revb_4h =3D 10, + la_op_revb_2w =3D 11, + la_op_revb_d =3D 12, + la_op_revh_2w =3D 13, + la_op_revh_d =3D 14, + la_op_bitrev_4b =3D 15, + la_op_bitrev_8b =3D 16, + la_op_bitrev_w =3D 17, + la_op_bitrev_d =3D 18, + la_op_ext_w_h =3D 19, + la_op_ext_w_b =3D 20, + la_op_rdtime_d =3D 21, + la_op_cpucfg =3D 22, + la_op_asrtle_d =3D 23, + la_op_asrtgt_d =3D 24, + la_op_alsl_w =3D 25, + la_op_alsl_wu =3D 26, + la_op_bytepick_w =3D 27, + la_op_bytepick_d =3D 28, + la_op_add_w =3D 29, + la_op_add_d =3D 30, + la_op_sub_w =3D 31, + la_op_sub_d =3D 32, + la_op_slt =3D 33, + la_op_sltu =3D 34, + la_op_maskeqz =3D 35, + la_op_masknez =3D 36, + la_op_nor =3D 37, + la_op_and =3D 38, + la_op_or =3D 39, + la_op_xor =3D 40, + la_op_orn =3D 41, + la_op_andn =3D 42, + la_op_sll_w =3D 43, + la_op_srl_w =3D 44, + la_op_sra_w =3D 45, + la_op_sll_d =3D 46, + la_op_srl_d =3D 47, + la_op_sra_d =3D 48, + la_op_rotr_w =3D 49, + la_op_rotr_d =3D 50, + la_op_mul_w =3D 51, + la_op_mulh_w =3D 52, + la_op_mulh_wu =3D 53, + la_op_mul_d =3D 54, + la_op_mulh_d =3D 55, + la_op_mulh_du =3D 56, + la_op_mulw_d_w =3D 57, + la_op_mulw_d_wu =3D 58, + la_op_div_w =3D 59, + la_op_mod_w =3D 60, + la_op_div_wu =3D 61, + la_op_mod_wu =3D 62, + la_op_div_d =3D 63, + la_op_mod_d =3D 64, + la_op_div_du =3D 65, + la_op_mod_du =3D 66, + la_op_crc_w_b_w =3D 67, + la_op_crc_w_h_w =3D 68, + la_op_crc_w_w_w =3D 69, + la_op_crc_w_d_w =3D 70, + la_op_crcc_w_b_w =3D 71, + la_op_crcc_w_h_w =3D 72, + la_op_crcc_w_w_w =3D 73, + la_op_crcc_w_d_w =3D 74, + la_op_break =3D 75, + la_op_syscall =3D 76, + la_op_alsl_d =3D 77, + la_op_slli_w =3D 78, + la_op_slli_d =3D 79, + la_op_srli_w =3D 80, + la_op_srli_d =3D 81, + la_op_srai_w =3D 82, + la_op_srai_d =3D 83, + la_op_rotri_w =3D 84, + la_op_rotri_d =3D 85, + la_op_bstrins_w =3D 86, + la_op_bstrpick_w =3D 87, + la_op_bstrins_d =3D 88, + la_op_bstrpick_d =3D 89, + la_op_fadd_s =3D 90, + la_op_fadd_d =3D 91, + la_op_fsub_s =3D 92, + la_op_fsub_d =3D 93, + la_op_fmul_s =3D 94, + la_op_fmul_d =3D 95, + la_op_fdiv_s =3D 96, + la_op_fdiv_d =3D 97, + la_op_fmax_s =3D 98, + la_op_fmax_d =3D 99, + la_op_fmin_s =3D 100, + la_op_fmin_d =3D 101, + la_op_fmaxa_s =3D 102, + la_op_fmaxa_d =3D 103, + la_op_fmina_s =3D 104, + la_op_fmina_d =3D 105, + la_op_fscaleb_s =3D 106, + la_op_fscaleb_d =3D 107, + la_op_fcopysign_s =3D 108, + la_op_fcopysign_d =3D 109, + la_op_fabs_s =3D 110, + la_op_fabs_d =3D 111, + la_op_fneg_s =3D 112, + la_op_fneg_d =3D 113, + la_op_flogb_s =3D 114, + la_op_flogb_d =3D 115, + la_op_fclass_s =3D 116, + la_op_fclass_d =3D 117, + la_op_fsqrt_s =3D 118, + la_op_fsqrt_d =3D 119, + la_op_frecip_s =3D 120, + la_op_frecip_d =3D 121, + la_op_frsqrt_s =3D 122, + la_op_frsqrt_d =3D 123, + la_op_fmov_s =3D 124, + la_op_fmov_d =3D 125, + la_op_movgr2fr_w =3D 126, + la_op_movgr2fr_d =3D 127, + la_op_movgr2frh_w =3D 128, + la_op_movfr2gr_s =3D 129, + la_op_movfr2gr_d =3D 130, + la_op_movfrh2gr_s =3D 131, + la_op_movgr2fcsr =3D 132, + la_op_movfcsr2gr =3D 133, + la_op_movfr2cf =3D 134, + la_op_movcf2fr =3D 135, + la_op_movgr2cf =3D 136, + la_op_movcf2gr =3D 137, + la_op_fcvt_s_d =3D 138, + la_op_fcvt_d_s =3D 139, + la_op_ftintrm_w_s =3D 140, + la_op_ftintrm_w_d =3D 141, + la_op_ftintrm_l_s =3D 142, + la_op_ftintrm_l_d =3D 143, + la_op_ftintrp_w_s =3D 144, + la_op_ftintrp_w_d =3D 145, + la_op_ftintrp_l_s =3D 146, + la_op_ftintrp_l_d =3D 147, + la_op_ftintrz_w_s =3D 148, + la_op_ftintrz_w_d =3D 149, + la_op_ftintrz_l_s =3D 150, + la_op_ftintrz_l_d =3D 151, + la_op_ftintrne_w_s =3D 152, + la_op_ftintrne_w_d =3D 153, + la_op_ftintrne_l_s =3D 154, + la_op_ftintrne_l_d =3D 155, + la_op_ftint_w_s =3D 156, + la_op_ftint_w_d =3D 157, + la_op_ftint_l_s =3D 158, + la_op_ftint_l_d =3D 159, + la_op_ffint_s_w =3D 160, + la_op_ffint_s_l =3D 161, + la_op_ffint_d_w =3D 162, + la_op_ffint_d_l =3D 163, + la_op_frint_s =3D 164, + la_op_frint_d =3D 165, + la_op_slti =3D 166, + la_op_sltui =3D 167, + la_op_addi_w =3D 168, + la_op_addi_d =3D 169, + la_op_lu52i_d =3D 170, + la_op_addi =3D 171, + la_op_ori =3D 172, + la_op_xori =3D 173, + la_op_rdtimel_w =3D 174, + la_op_rdtimeh_w =3D 175, + la_op_fmadd_s =3D 176, + la_op_fmadd_d =3D 177, + la_op_fmsub_s =3D 178, + la_op_fmsub_d =3D 179, + la_op_fnmadd_s =3D 180, + la_op_fnmadd_d =3D 181, + la_op_fnmsub_s =3D 182, + la_op_fnmsub_d =3D 183, + la_op_fcmp_cond_s =3D 184, + la_op_fcmp_cond_d =3D 185, + la_op_fsel =3D 186, + la_op_addu16i_d =3D 187, + la_op_lu12i_w =3D 188, + la_op_lu32i_d =3D 189, + la_op_pcaddi =3D 190, + la_op_pcalau12i =3D 191, + la_op_pcaddu12i =3D 192, + la_op_pcaddu18i =3D 193, + la_op_ll_w =3D 194, + la_op_sc_w =3D 195, + la_op_ll_d =3D 196, + la_op_sc_d =3D 197, + la_op_ldptr_w =3D 198, + la_op_stptr_w =3D 199, + la_op_ldptr_d =3D 200, + la_op_stptr_d =3D 201, + la_op_ld_b =3D 202, + la_op_ld_h =3D 203, + la_op_ld_w =3D 204, + la_op_ld_d =3D 205, + la_op_st_b =3D 206, + la_op_st_h =3D 207, + la_op_st_w =3D 208, + la_op_st_d =3D 209, + la_op_ld_bu =3D 210, + la_op_ld_hu =3D 211, + la_op_ld_wu =3D 212, + la_op_preld =3D 213, + la_op_fld_s =3D 214, + la_op_fst_s =3D 215, + la_op_fld_d =3D 216, + la_op_fst_d =3D 217, + la_op_ldx_b =3D 218, + la_op_ldx_h =3D 219, + la_op_ldx_w =3D 220, + la_op_ldx_d =3D 221, + la_op_stx_b =3D 222, + la_op_stx_h =3D 223, + la_op_stx_w =3D 224, + la_op_stx_d =3D 225, + la_op_ldx_bu =3D 226, + la_op_ldx_hu =3D 227, + la_op_ldx_wu =3D 228, + la_op_fldx_s =3D 229, + la_op_fldx_d =3D 230, + la_op_fstx_s =3D 231, + la_op_fstx_d =3D 232, + la_op_amswap_w =3D 233, + la_op_amswap_d =3D 234, + la_op_amadd_w =3D 235, + la_op_amadd_d =3D 236, + la_op_amand_w =3D 237, + la_op_amand_d =3D 238, + la_op_amor_w =3D 239, + la_op_amor_d =3D 240, + la_op_amxor_w =3D 241, + la_op_amxor_d =3D 242, + la_op_ammax_w =3D 243, + la_op_ammax_d =3D 244, + la_op_ammin_w =3D 245, + la_op_ammin_d =3D 246, + la_op_ammax_wu =3D 247, + la_op_ammax_du =3D 248, + la_op_ammin_wu =3D 249, + la_op_ammin_du =3D 250, + la_op_amswap_db_w =3D 251, + la_op_amswap_db_d =3D 252, + la_op_amadd_db_w =3D 253, + la_op_amadd_db_d =3D 254, + la_op_amand_db_w =3D 255, + la_op_amand_db_d =3D 256, + la_op_amor_db_w =3D 257, + la_op_amor_db_d =3D 258, + la_op_amxor_db_w =3D 259, + la_op_amxor_db_d =3D 260, + la_op_ammax_db_w =3D 261, + la_op_ammax_db_d =3D 262, + la_op_ammin_db_w =3D 263, + la_op_ammin_db_d =3D 264, + la_op_ammax_db_wu =3D 265, + la_op_ammax_db_du =3D 266, + la_op_ammin_db_wu =3D 267, + la_op_ammin_db_du =3D 268, + la_op_dbar =3D 269, + la_op_ibar =3D 270, + la_op_fldgt_s =3D 271, + la_op_fldgt_d =3D 272, + la_op_fldle_s =3D 273, + la_op_fldle_d =3D 274, + la_op_fstgt_s =3D 275, + la_op_fstgt_d =3D 276, + ls_op_fstle_s =3D 277, + la_op_fstle_d =3D 278, + la_op_ldgt_b =3D 279, + la_op_ldgt_h =3D 280, + la_op_ldgt_w =3D 281, + la_op_ldgt_d =3D 282, + la_op_ldle_b =3D 283, + la_op_ldle_h =3D 284, + la_op_ldle_w =3D 285, + la_op_ldle_d =3D 286, + la_op_stgt_b =3D 287, + la_op_stgt_h =3D 288, + la_op_stgt_w =3D 289, + la_op_stgt_d =3D 290, + la_op_stle_b =3D 291, + la_op_stle_h =3D 292, + la_op_stle_w =3D 293, + la_op_stle_d =3D 294, + la_op_beqz =3D 295, + la_op_bnez =3D 296, + la_op_bceqz =3D 297, + la_op_bcnez =3D 298, + la_op_jirl =3D 299, + la_op_b =3D 300, + la_op_bl =3D 301, + la_op_beq =3D 302, + la_op_bne =3D 303, + la_op_blt =3D 304, + la_op_bge =3D 305, + la_op_bltu =3D 306, + la_op_bgeu =3D 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" +#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" +#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] =3D { + "$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", +}; + +const char * const loongarch_f_normal_name[32] =3D { + "$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] =3D { + "$scr0", "$scr1", "$scr2", "$scr3", +}; + +const char * const loongarch_c_normal_name[8] =3D { + "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", "$fcc6", "$fcc7", +}; + +/* instruction data */ +static const la_opcode_data opcode_data[] =3D { + { "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 =3D dec->insn; + uint16_t op =3D 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 =3D la_op_clo_w; + break; + case 0x5: + op =3D la_op_clz_w; + break; + case 0x6: + op =3D la_op_cto_w; + break; + case 0x7: + op =3D la_op_ctz_w; + break; + case 0x8: + op =3D la_op_clo_d; + break; + case 0x9: + op =3D la_op_clz_d; + break; + case 0xa: + op =3D la_op_cto_d; + break; + case 0xb: + op =3D la_op_ctz_d; + break; + case 0xc: + op =3D la_op_revb_2h; + break; + case 0xd: + op =3D la_op_revb_4h; + break; + case 0xe: + op =3D la_op_revb_2w; + break; + case 0xf: + op =3D la_op_revb_d; + break; + case 0x10: + op =3D la_op_revh_2w; + break; + case 0x11: + op =3D la_op_revh_d; + break; + case 0x12: + op =3D la_op_bitrev_4b; + break; + case 0x13: + op =3D la_op_bitrev_8b; + break; + case 0x14: + op =3D la_op_bitrev_w; + break; + case 0x15: + op =3D la_op_bitrev_d; + break; + case 0x16: + op =3D la_op_ext_w_h; + break; + case 0x17: + op =3D la_op_ext_w_b; + break; + case 0x18: + op =3D la_op_rdtimel_w; + break; + case 0x19: + op =3D la_op_rdtimeh_w; + break; + case 0x1a: + op =3D la_op_rdtime_d; + break; + case 0x1b: + op =3D la_op_cpucfg; + break; + } + break; + case 0x2: + switch (insn & 0x0000001f) { + case 0x00000000: + op =3D la_op_asrtle_d; + break; + } + break; + case 0x3: + switch (insn & 0x0000001f) { + case 0x00000000: + op =3D la_op_asrtgt_d; + break; + } + break; + } + break; + case 0x1: + switch ((insn >> 17) & 0x1) { + case 0x0: + op =3D la_op_alsl_w; + break; + case 0x1: + op =3D la_op_alsl_wu; + break; + } + break; + case 0x2: + switch ((insn >> 17) & 0x1) { + case 0x0: + op =3D la_op_bytepick_w; + break; + } + break; + case 0x3: + op =3D la_op_bytepick_d; + break; + case 0x4: + switch ((insn >> 15) & 0x7) { + case 0x0: + op =3D la_op_add_w; + break; + case 0x1: + op =3D la_op_add_d; + break; + case 0x2: + op =3D la_op_sub_w; + break; + case 0x3: + op =3D la_op_sub_d; + break; + case 0x4: + op =3D la_op_slt; + break; + case 0x5: + op =3D la_op_sltu; + break; + case 0x6: + op =3D la_op_maskeqz; + break; + case 0x7: + op =3D la_op_masknez; + break; + } + break; + case 0x5: + switch ((insn >> 15) & 0x7) { + case 0x0: + op =3D la_op_nor; + break; + case 0x1: + op =3D la_op_and; + break; + case 0x2: + op =3D la_op_or; + break; + case 0x3: + op =3D la_op_xor; + break; + case 0x4: + op =3D la_op_orn; + break; + case 0x5: + op =3D la_op_andn; + break; + case 0x6: + op =3D la_op_sll_w; + break; + case 0x7: + op =3D la_op_srl_w; + break; + } + break; + case 0x6: + switch ((insn >> 15) & 0x7) { + case 0x0: + op =3D la_op_sra_w; + break; + case 0x1: + op =3D la_op_sll_d; + break; + case 0x2: + op =3D la_op_srl_d; + break; + case 0x3: + op =3D la_op_sra_d; + break; + case 0x6: + op =3D la_op_rotr_w; + break; + case 0x7: + op =3D la_op_rotr_d; + break; + } + break; + case 0x7: + switch ((insn >> 15) & 0x7) { + case 0x0: + op =3D la_op_mul_w; + break; + case 0x1: + op =3D la_op_mulh_w; + break; + case 0x2: + op =3D la_op_mulh_wu; + break; + case 0x3: + op =3D la_op_mul_d; + break; + case 0x4: + op =3D la_op_mulh_d; + break; + case 0x5: + op =3D la_op_mulh_du; + break; + case 0x6: + op =3D la_op_mulw_d_w; + break; + case 0x7: + op =3D la_op_mulw_d_wu; + break; + } + break; + case 0x8: + switch ((insn >> 15) & 0x7) { + case 0x0: + op =3D la_op_div_w; + break; + case 0x1: + op =3D la_op_mod_w; + break; + case 0x2: + op =3D la_op_div_wu; + break; + case 0x3: + op =3D la_op_mod_wu; + break; + case 0x4: + op =3D la_op_div_d; + break; + case 0x5: + op =3D la_op_mod_d; + break; + case 0x6: + op =3D la_op_div_du; + break; + case 0x7: + op =3D la_op_mod_du; + break; + } + break; + case 0x9: + switch ((insn >> 15) & 0x7) { + case 0x0: + op =3D la_op_crc_w_b_w; + break; + case 0x1: + op =3D la_op_crc_w_h_w; + break; + case 0x2: + op =3D la_op_crc_w_w_w; + break; + case 0x3: + op =3D la_op_crc_w_d_w; + break; + case 0x4: + op =3D la_op_crcc_w_b_w; + break; + case 0x5: + op =3D la_op_crcc_w_h_w; + break; + case 0x6: + op =3D la_op_crcc_w_w_w; + break; + case 0x7: + op =3D la_op_crcc_w_d_w; + break; + } + break; + case 0xa: + switch ((insn >> 15) & 0x7) { + case 0x4: + op =3D la_op_break; + break; + case 0x6: + op =3D la_op_syscall; + break; + } + break; + case 0xb: + switch ((insn >> 17) & 0x1) { + case 0x0: + op =3D 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 =3D la_op_slli_w; + break; + } + break; + case 0x1: + op =3D la_op_slli_d; + break; + case 0x4: + switch ((insn >> 15) & 0x1) { + case 0x1: + op =3D la_op_srli_w; + break; + } + break; + case 0x5: + op =3D la_op_srli_d; + break; + case 0x8: + switch ((insn >> 15) & 0x1) { + case 0x1: + op =3D la_op_srai_w; + break; + } + break; + case 0x9: + op =3D la_op_srai_d; + break; + case 0xc: + switch ((insn >> 15) & 0x1) { + case 0x1: + op =3D la_op_rotri_w; + break; + } + break; + case 0xd: + op =3D la_op_rotri_d; + break; + } + break; + case 0x1: + switch ((insn >> 15) & 0x1) { + case 0x0: + op =3D la_op_bstrins_w; + break; + case 0x1: + op =3D la_op_bstrpick_w; + break; + } + break; + } + break; + case 0x2: + op =3D la_op_bstrins_d; + break; + case 0x3: + op =3D la_op_bstrpick_d; + break; + case 0x4: + switch ((insn >> 15) & 0x7f) { + case 0x1: + op =3D la_op_fadd_s; + break; + case 0x2: + op =3D la_op_fadd_d; + break; + case 0x5: + op =3D la_op_fsub_s; + break; + case 0x6: + op =3D la_op_fsub_d; + break; + case 0x9: + op =3D la_op_fmul_s; + break; + case 0xa: + op =3D la_op_fmul_d; + break; + case 0xd: + op =3D la_op_fdiv_s; + break; + case 0xe: + op =3D la_op_fdiv_d; + break; + case 0x11: + op =3D la_op_fmax_s; + break; + case 0x12: + op =3D la_op_fmax_d; + break; + case 0x15: + op =3D la_op_fmin_s; + break; + case 0x16: + op =3D la_op_fmin_d; + break; + case 0x19: + op =3D la_op_fmaxa_s; + break; + case 0x1a: + op =3D la_op_fmaxa_d; + break; + case 0x1d: + op =3D la_op_fmina_s; + break; + case 0x1e: + op =3D la_op_fmina_d; + break; + case 0x21: + op =3D la_op_fscaleb_s; + break; + case 0x22: + op =3D la_op_fscaleb_d; + break; + case 0x25: + op =3D la_op_fcopysign_s; + break; + case 0x26: + op =3D la_op_fcopysign_d; + break; + case 0x28: + switch ((insn >> 10) & 0x1f) { + case 0x1: + op =3D la_op_fabs_s; + break; + case 0x2: + op =3D la_op_fabs_d; + break; + case 0x5: + op =3D la_op_fneg_s; + break; + case 0x6: + op =3D la_op_fneg_d; + break; + case 0x9: + op =3D la_op_flogb_s; + break; + case 0xa: + op =3D la_op_flogb_d; + break; + case 0xd: + op =3D la_op_fclass_s; + break; + case 0xe: + op =3D la_op_fclass_d; + break; + case 0x11: + op =3D la_op_fsqrt_s; + break; + case 0x12: + op =3D la_op_fsqrt_d; + break; + case 0x15: + op =3D la_op_frecip_s; + break; + case 0x16: + op =3D la_op_frecip_d; + break; + case 0x19: + op =3D la_op_frsqrt_s; + break; + case 0x1a: + op =3D la_op_frsqrt_d; + break; + } + break; + case 0x29: + switch ((insn >> 10) & 0x1f) { + case 0x5: + op =3D la_op_fmov_s; + break; + case 0x6: + op =3D la_op_fmov_d; + break; + case 0x9: + op =3D la_op_movgr2fr_w; + break; + case 0xa: + op =3D la_op_movgr2fr_d; + break; + case 0xb: + op =3D la_op_movgr2frh_w; + break; + case 0xd: + op =3D la_op_movfr2gr_s; + break; + case 0xe: + op =3D la_op_movfr2gr_d; + break; + case 0xf: + op =3D la_op_movfrh2gr_s; + break; + case 0x10: + op =3D la_op_movgr2fcsr; + break; + case 0x12: + op =3D la_op_movfcsr2gr; + break; + case 0x14: + switch ((insn >> 3) & 0x3) { + case 0x0: + op =3D la_op_movfr2cf; + break; + } + break; + case 0x15: + switch ((insn >> 8) & 0x3) { + case 0x0: + op =3D la_op_movcf2fr; + break; + } + break; + case 0x16: + switch ((insn >> 3) & 0x3) { + case 0x0: + op =3D la_op_movgr2cf; + break; + } + break; + case 0x17: + switch ((insn >> 8) & 0x3) { + case 0x0: + op =3D la_op_movcf2gr; + break; + } + break; + } + break; + case 0x32: + switch ((insn >> 10) & 0x1f) { + case 0x6: + op =3D la_op_fcvt_s_d; + break; + case 0x9: + op =3D la_op_fcvt_d_s; + break; + } + break; + case 0x34: + switch ((insn >> 10) & 0x1f) { + case 0x1: + op =3D la_op_ftintrm_w_s; + break; + case 0x2: + op =3D la_op_ftintrm_w_d; + break; + case 0x9: + op =3D la_op_ftintrm_l_s; + break; + case 0xa: + op =3D la_op_ftintrm_l_d; + break; + case 0x11: + op =3D la_op_ftintrp_w_s; + break; + case 0x12: + op =3D la_op_ftintrp_w_d; + break; + case 0x19: + op =3D la_op_ftintrp_l_s; + break; + case 0x1a: + op =3D la_op_ftintrp_l_d; + break; + } + break; + case 0x35: + switch ((insn >> 10) & 0x1f) { + case 0x1: + op =3D la_op_ftintrz_w_s; + break; + case 0x2: + op =3D la_op_ftintrz_w_d; + break; + case 0x9: + op =3D la_op_ftintrz_l_s; + break; + case 0xa: + op =3D la_op_ftintrz_l_d; + break; + case 0x11: + op =3D la_op_ftintrne_w_s; + break; + case 0x12: + op =3D la_op_ftintrne_w_d; + break; + case 0x19: + op =3D la_op_ftintrne_l_s; + break; + case 0x1a: + op =3D la_op_ftintrne_l_d; + break; + } + break; + case 0x36: + switch ((insn >> 10) & 0x1f) { + case 0x1: + op =3D la_op_ftint_w_s; + break; + case 0x2: + op =3D la_op_ftint_w_d; + break; + case 0x9: + op =3D la_op_ftint_l_s; + break; + case 0xa: + op =3D la_op_ftint_l_d; + break; + } + break; + case 0x3a: + switch ((insn >> 10) & 0x1f) { + case 0x4: + op =3D la_op_ffint_s_w; + break; + case 0x6: + op =3D la_op_ffint_s_l; + break; + case 0x8: + op =3D la_op_ffint_d_w; + break; + case 0xa: + op =3D la_op_ffint_d_l; + break; + } + break; + case 0x3c: + switch ((insn >> 10) & 0x1f) { + case 0x11: + op =3D la_op_frint_s; + break; + case 0x12: + op =3D la_op_frint_d; + break; + } + break; + } + break; + case 0x8: + op =3D la_op_slti; + break; + case 0x9: + op =3D la_op_sltui; + break; + case 0xa: + op =3D la_op_addi_w; + break; + case 0xb: + op =3D la_op_addi_d; + break; + case 0xc: + op =3D la_op_lu52i_d; + break; + case 0xd: + op =3D la_op_addi; + break; + case 0xe: + op =3D la_op_ori; + break; + case 0xf: + op =3D la_op_xori; + break; + } + break; + case 0x2: + switch ((insn >> 20) & 0x3f) { + case 0x1: + op =3D la_op_fmadd_s; + break; + case 0x2: + op =3D la_op_fmadd_d; + break; + case 0x5: + op =3D la_op_fmsub_s; + break; + case 0x6: + op =3D la_op_fmsub_d; + break; + case 0x9: + op =3D la_op_fnmadd_s; + break; + case 0xa: + op =3D la_op_fnmadd_d; + break; + case 0xd: + op =3D la_op_fnmsub_s; + break; + case 0xe: + op =3D la_op_fnmsub_d; + break; + } + break; + case 0x3: + switch ((insn >> 20) & 0x3f) { + case 0x1: + switch ((insn >> 3) & 0x3) { + case 0x0: + op =3D la_op_fcmp_cond_s; + break; + } + break; + case 0x2: + switch ((insn >> 3) & 0x3) { + case 0x0: + op =3D la_op_fcmp_cond_d; + break; + } + break; + case 0x10: + switch ((insn >> 18) & 0x3) { + case 0x0: + op =3D la_op_fsel; + break; + } + break; + } + break; + case 0x4: + op =3D la_op_addu16i_d; + break; + case 0x5: + switch ((insn >> 25) & 0x1) { + case 0x0: + op =3D la_op_lu12i_w; + break; + case 0x1: + op =3D la_op_lu32i_d; + break; + } + break; + case 0x6: + switch ((insn >> 25) & 0x1) { + case 0x0: + op =3D la_op_pcaddi; + break; + case 0x1: + op =3D la_op_pcalau12i; + break; + } + break; + case 0x7: + switch ((insn >> 25) & 0x1) { + case 0x0: + op =3D la_op_pcaddu12i; + break; + case 0x1: + op =3D la_op_pcaddu18i; + break; + } + break; + case 0x8: + switch ((insn >> 24) & 0x3) { + case 0x0: + op =3D la_op_ll_w; + break; + case 0x1: + op =3D la_op_sc_w; + break; + case 0x2: + op =3D la_op_ll_d; + break; + case 0x3: + op =3D la_op_sc_d; + break; + } + break; + case 0x9: + switch ((insn >> 24) & 0x3) { + case 0x0: + op =3D la_op_ldptr_w; + break; + case 0x1: + op =3D la_op_stptr_w; + break; + case 0x2: + op =3D la_op_ldptr_d; + break; + case 0x3: + op =3D la_op_stptr_d; + break; + } + break; + case 0xa: + switch ((insn >> 22) & 0xf) { + case 0x0: + op =3D la_op_ld_b; + break; + case 0x1: + op =3D la_op_ld_h; + break; + case 0x2: + op =3D la_op_ld_w; + break; + case 0x3: + op =3D la_op_ld_d; + break; + case 0x4: + op =3D la_op_st_b; + break; + case 0x5: + op =3D la_op_st_h; + break; + case 0x6: + op =3D la_op_st_w; + break; + case 0x7: + op =3D la_op_st_d; + break; + case 0x8: + op =3D la_op_ld_bu; + break; + case 0x9: + op =3D la_op_ld_hu; + break; + case 0xa: + op =3D la_op_ld_wu; + break; + case 0xb: + op =3D la_op_preld; + break; + case 0xc: + op =3D la_op_fld_s; + break; + case 0xd: + op =3D la_op_fst_s; + break; + case 0xe: + op =3D la_op_fld_d; + break; + case 0xf: + op =3D la_op_fst_d; + break; + } + break; + case 0xe: + switch ((insn >> 15) & 0x7ff) { + case 0x0: + op =3D la_op_ldx_b; + break; + case 0x8: + op =3D la_op_ldx_h; + break; + case 0x10: + op =3D la_op_ldx_w; + break; + case 0x18: + op =3D la_op_ldx_d; + break; + case 0x20: + op =3D la_op_stx_b; + break; + case 0x28: + op =3D la_op_stx_h; + break; + case 0x30: + op =3D la_op_stx_w; + break; + case 0x38: + op =3D la_op_stx_d; + break; + case 0x40: + op =3D la_op_ldx_bu; + break; + case 0x48: + op =3D la_op_ldx_hu; + break; + case 0x50: + op =3D la_op_ldx_wu; + break; + case 0x60: + op =3D la_op_fldx_s; + break; + case 0x68: + op =3D la_op_fldx_d; + break; + case 0x70: + op =3D la_op_fstx_s; + break; + case 0x78: + op =3D la_op_fstx_d; + break; + case 0xc0: + op =3D la_op_amswap_w; + break; + case 0xc1: + op =3D la_op_amswap_d; + break; + case 0xc2: + op =3D la_op_amadd_w; + break; + case 0xc3: + op =3D la_op_amadd_d; + break; + case 0xc4: + op =3D la_op_amand_w; + break; + case 0xc5: + op =3D la_op_amand_d; + break; + case 0xc6: + op =3D la_op_amor_w; + break; + case 0xc7: + op =3D la_op_amor_d; + break; + case 0xc8: + op =3D la_op_amxor_w; + break; + case 0xc9: + op =3D la_op_amxor_d; + break; + case 0xca: + op =3D la_op_ammax_w; + break; + case 0xcb: + op =3D la_op_ammax_d; + break; + case 0xcc: + op =3D la_op_ammin_w; + break; + case 0xcd: + op =3D la_op_ammin_d; + break; + case 0xce: + op =3D la_op_ammax_wu; + break; + case 0xcf: + op =3D la_op_ammax_du; + break; + case 0xd0: + op =3D la_op_ammin_wu; + break; + case 0xd1: + op =3D la_op_ammin_du; + break; + case 0xd2: + op =3D la_op_amswap_db_w; + break; + case 0xd3: + op =3D la_op_amswap_db_d; + break; + case 0xd4: + op =3D la_op_amadd_db_w; + break; + case 0xd5: + op =3D la_op_amadd_db_d; + break; + case 0xd6: + op =3D la_op_amand_db_w; + break; + case 0xd7: + op =3D la_op_amand_db_d; + break; + case 0xd8: + op =3D la_op_amor_db_w; + break; + case 0xd9: + op =3D la_op_amor_db_d; + break; + case 0xda: + op =3D la_op_amxor_db_w; + break; + case 0xdb: + op =3D la_op_amxor_db_d; + break; + case 0xdc: + op =3D la_op_ammax_db_w; + break; + case 0xdd: + op =3D la_op_ammax_db_d; + break; + case 0xde: + op =3D la_op_ammin_db_w; + break; + case 0xdf: + op =3D la_op_ammin_db_d; + break; + case 0xe0: + op =3D la_op_ammax_db_wu; + break; + case 0xe1: + op =3D la_op_ammax_db_du; + break; + case 0xe2: + op =3D la_op_ammin_db_wu; + break; + case 0xe3: + op =3D la_op_ammin_db_du; + break; + case 0xe4: + op =3D la_op_dbar; + break; + case 0xe5: + op =3D la_op_ibar; + break; + case 0xe8: + op =3D la_op_fldgt_s; + break; + case 0xe9: + op =3D la_op_fldgt_d; + break; + case 0xea: + op =3D la_op_fldle_s; + break; + case 0xeb: + op =3D la_op_fldle_d; + break; + case 0xec: + op =3D la_op_fstgt_s; + break; + case 0xed: + op =3D la_op_fstgt_d; + break; + case 0xee: + op =3D ls_op_fstle_s; + break; + case 0xef: + op =3D la_op_fstle_d; + break; + case 0xf0: + op =3D la_op_ldgt_b; + break; + case 0xf1: + op =3D la_op_ldgt_h; + break; + case 0xf2: + op =3D la_op_ldgt_w; + break; + case 0xf3: + op =3D la_op_ldgt_d; + break; + case 0xf4: + op =3D la_op_ldle_b; + break; + case 0xf5: + op =3D la_op_ldle_h; + break; + case 0xf6: + op =3D la_op_ldle_w; + break; + case 0xf7: + op =3D la_op_ldle_d; + break; + case 0xf8: + op =3D la_op_stgt_b; + break; + case 0xf9: + op =3D la_op_stgt_h; + break; + case 0xfa: + op =3D la_op_stgt_w; + break; + case 0xfb: + op =3D la_op_stgt_d; + break; + case 0xfc: + op =3D la_op_stle_b; + break; + case 0xfd: + op =3D la_op_stle_h; + break; + case 0xfe: + op =3D la_op_stle_w; + break; + case 0xff: + op =3D la_op_stle_d; + break; + } + break; + case 0x10: + op =3D la_op_beqz; + break; + case 0x11: + op =3D la_op_bnez; + break; + case 0x12: + switch ((insn >> 8) & 0x3) { + case 0x0: + op =3D la_op_bceqz; + break; + case 0x1: + op =3D la_op_bcnez; + break; + } + break; + case 0x13: + op =3D la_op_jirl; + break; + case 0x14: + op =3D la_op_b; + break; + case 0x15: + op =3D la_op_bl; + break; + case 0x16: + op =3D la_op_beq; + break; + case 0x17: + op =3D la_op_bne; + break; + case 0x18: + op =3D la_op_blt; + break; + case 0x19: + op =3D la_op_bge; + break; + case 0x1a: + op =3D la_op_bltu; + break; + case 0x1b: + op =3D la_op_bgeu; + break; + default: + op =3D la_op_illegal; + break; + } + dec->op =3D 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 =3D (int32_t)((insn >> 5) & 0xfffff); + return imm > (1 << 19) ? imm - (1 << 20) : imm; +} + +static int32_t operand_im16(uint32_t insn) +{ + int32_t imm =3D (int32_t)((insn >> 10) & 0xffff); + return imm > (1 << 15) ? imm - (1 << 16) : imm; +} + +static int32_t operand_im14(uint32_t insn) +{ + int32_t imm =3D (int32_t)((insn >> 10) & 0x3fff); + return imm > (1 << 13) ? imm - (1 << 14) : imm; +} + +static int32_t operand_im12(uint32_t insn) +{ + int32_t imm =3D (int32_t)((insn >> 10) & 0xfff); + return imm > (1 << 11) ? imm - (1 << 12) : imm; +} + +static int32_t operand_im8(uint32_t insn) +{ + int32_t imm =3D (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 =3D (int32_t)(insn & 0x7fff); + return imm > (1 << 14) ? imm - (1 << 15) : imm; +} + +static int32_t operand_invop(uint32_t insn) +{ + int32_t imm =3D (int32_t)(insn & 0x1f); + return imm > (1 << 4) ? imm - (1 << 5) : imm; +} + +static int32_t operand_ofs21(uint32_t insn) +{ + int32_t imm =3D (((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 =3D (((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 =3D dec->insn; + dec->codec =3D opcode_data[dec->op].codec; + switch (dec->codec) { + case la_codec_illegal: + case la_codec_empty: + break; + case la_codec_2r: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + break; + case la_codec_2r_u5: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_r3(insn); + break; + case la_codec_2r_u6: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_u6(insn); + break; + case la_codec_2r_2bw: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_bw1(insn); + dec->r4 =3D operand_bw2(insn); + break; + case la_codec_2r_2bd: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_bd1(insn); + dec->r4 =3D operand_bd2(insn); + break; + case la_codec_3r: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_r3(insn); + break; + case la_codec_3r_rd0: + dec->r1 =3D 0; + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_r3(insn); + break; + case la_codec_3r_sa2: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_r3(insn); + dec->r4 =3D operand_sa2(insn); + break; + case la_codec_3r_sa3: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_r3(insn); + dec->r4 =3D operand_sa3(insn); + break; + case la_codec_4r: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_r3(insn); + dec->r4 =3D operand_r4(insn); + break; + case la_codec_r_im20: + dec->r1 =3D operand_r1(insn); + dec->imm =3D operand_im20(insn); + dec->bit =3D IM_20; + break; + case la_codec_2r_im16: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->imm =3D operand_im16(insn); + dec->bit =3D IM_16; + break; + case la_codec_2r_im14: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->imm =3D operand_im14(insn); + dec->bit =3D IM_14; + break; + case la_codec_r_im14: + dec->r1 =3D operand_r1(insn); + dec->imm =3D operand_im14(insn); + dec->bit =3D IM_14; + break; + case la_codec_im5_r_im12: + dec->imm2 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->imm =3D operand_im12(insn); + dec->bit =3D IM_12; + break; + case la_codec_2r_im12: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->imm =3D operand_im12(insn); + dec->bit =3D IM_12; + break; + case la_codec_2r_im8: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->imm =3D operand_im8(insn); + dec->bit =3D IM_8; + break; + case la_codec_r_sd: + dec->r1 =3D operand_sd(insn); + dec->r2 =3D operand_r2(insn); + break; + case la_codec_r_sj: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_sj(insn); + break; + case la_codec_r_cd: + dec->r1 =3D operand_cd(insn); + dec->r2 =3D operand_r2(insn); + break; + case la_codec_r_cj: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_cj(insn); + break; + case la_codec_r_seq: + dec->r1 =3D 0; + dec->r2 =3D operand_r1(insn); + dec->imm =3D operand_im8(insn); + dec->bit =3D IM_8; + break; + case la_codec_code: + dec->code =3D operand_code(insn); + break; + case la_codec_whint: + dec->imm =3D operand_whint(insn); + dec->bit =3D IM_15; + break; + case la_codec_invtlb: + dec->imm =3D operand_invop(insn); + dec->bit =3D IM_5; + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_r3(insn); + break; + case la_codec_r_ofs21: + dec->imm =3D operand_ofs21(insn); + dec->bit =3D IM_21; + dec->r2 =3D operand_r2(insn); + break; + case la_codec_cj_ofs21: + dec->imm =3D operand_ofs21(insn); + dec->bit =3D IM_21; + dec->r2 =3D operand_cj(insn); + break; + case la_codec_ofs26: + dec->imm =3D operand_ofs26(insn); + dec->bit =3D IM_26; + break; + case la_codec_cond: + dec->r1 =3D operand_cd(insn); + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_r3(insn); + dec->r4 =3D operand_fcond(insn); + break; + case la_codec_sel: + dec->r1 =3D operand_r1(insn); + dec->r2 =3D operand_r2(insn); + dec->r3 =3D operand_r3(insn); + dec->r4 =3D operand_sel(insn); + break; + } +} + +/* format instruction */ +static void append(char *s1, const char *s2, size_t n) +{ + size_t l1 =3D 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 *d= ec) +{ + char tmp[16]; + const char *fmt; + + fmt =3D 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 =3D { 0 }; + dec.pc =3D pc; + dec.insn =3D 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] =3D { 0 }; + bfd_byte buffer[INSNLEN]; + unsigned long insn; + int status; + + status =3D (*info->read_memory_func)(memaddr, buffer, INSNLEN, info); + if (status =3D=3D 0) { + insn =3D (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_i= nfo*); 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 *); =20 #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 7d7d14a..45bd486 100644 --- a/meson.build +++ b/meson.build @@ -1501,6 +1501,7 @@ disassemblers =3D { 'sh4' : ['CONFIG_SH4_DIS'], 'sparc' : ['CONFIG_SPARC_DIS'], 'xtensa' : ['CONFIG_XTENSA_DIS'], + 'loongarch' : ['CONFIG_LOONGARCH_DIS'], } if link_language =3D=3D 'cpp' disassemblers +=3D { --=20 1.8.3.1