From e4afbea33e6907b18d6a8b6478c959b7a7e6c8a1 Mon Sep 17 00:00:00 2001 From: wargio Date: Sat, 7 Sep 2024 12:25:43 +0800 Subject: [PATCH 01/13] Remove mips gnu, rename mips_cs to mips and update the code aaa --- librz/arch/isa_gnu/mips/mips-dis.c | 2163 ----------------- librz/arch/isa_gnu/mips/mips-opc.c | 2018 --------------- librz/arch/isa_gnu/mips/mips16-opc.c | 244 -- librz/arch/meson.build | 9 +- .../{analysis_mips_cs.c => analysis_mips.c} | 398 +-- librz/arch/p/{arch_mips_cs.c => arch_mips.c} | 6 +- .../arch/p/asm/{asm_mips_cs.c => asm_mips.c} | 4 +- librz/arch/p/parse/parse_mips_pseudo.c | 2 +- librz/arch/p_gnu/analysis/analysis_mips_gnu.c | 1799 -------------- librz/arch/p_gnu/arch_mips.c | 10 - librz/arch/p_gnu/asm/asm_mips_gnu.c | 158 -- 11 files changed, 87 insertions(+), 6724 deletions(-) delete mode 100644 librz/arch/isa_gnu/mips/mips-dis.c delete mode 100644 librz/arch/isa_gnu/mips/mips-opc.c delete mode 100644 librz/arch/isa_gnu/mips/mips16-opc.c rename librz/arch/p/analysis/{analysis_mips_cs.c => analysis_mips.c} (78%) rename librz/arch/p/{arch_mips_cs.c => arch_mips.c} (65%) rename librz/arch/p/asm/{asm_mips_cs.c => asm_mips.c} (97%) delete mode 100644 librz/arch/p_gnu/arch_mips.c delete mode 100644 librz/arch/p_gnu/asm/asm_mips_gnu.c diff --git a/librz/arch/isa_gnu/mips/mips-dis.c b/librz/arch/isa_gnu/mips/mips-dis.c deleted file mode 100644 index 6dd086cd5a1..00000000000 --- a/librz/arch/isa_gnu/mips/mips-dis.c +++ /dev/null @@ -1,2163 +0,0 @@ -/* Print mips instructions for GDB, the GNU debugger, or for objdump. - Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2005, 2007 - Free Software Foundation, Inc. - Contributed by Nobuyuki Hikichi(hikichi@sra.co.jp). - - This file is part of the GNU opcodes library. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - It is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* FIXME: These are needed to figure out if the code is mips16 or - not. The low bit of the address is often a good indicator. No - symbol table is available when this code runs out in an embedded - system as when it is used for disassembler support in a monitor. */ - -#include -#if !defined(EMBEDDED_ENV) -#define SYMTAB_AVAILABLE 1 -#include -#endif - -/* Mips instructions are at maximum this many bytes long. */ -#define INSNLEN 4 - - -/* FIXME: These should be shared with gdb somehow. */ - -struct mips_cp0sel_name -{ - unsigned int cp0reg; - unsigned int sel; - const char * const name; -}; - -/* The mips16 registers. */ -static const unsigned int mips16_to_32_reg_map[] = -{ - 16, 17, 2, 3, 4, 5, 6, 7 -}; - -#define mips16_reg_names(rn) mips_gpr_names[mips16_to_32_reg_map[rn]] - - -static const char * const mips_gpr_names_numeric[32] = -{ - "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", - "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", - "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", - "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" -}; - -const char * const mips_gpr_names_oldabi[32] = -{ - "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" -}; - -const char * const mips_gpr_names_newabi[32] = -{ - "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra" -}; - -static const char * const mips_fpr_names_numeric[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" -}; - -static const char * const mips_fpr_names_32[32] = -{ - "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f", - "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f", - "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f", - "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f" -}; - -static const char * const mips_fpr_names_n32[32] = -{ - "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3", - "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3", - "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9", - "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13" -}; - -static const char * const mips_fpr_names_64[32] = -{ - "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3", - "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3", - "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11", - "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7" -}; - -static const char * const mips_cp0_names_numeric[32] = -{ - "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", - "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", - "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", - "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" -}; - -static const char * const mips_cp0_names_mips3264[32] = -{ - "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", - "c0_context", "c0_pagemask", "c0_wired", "$7", - "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", - "c0_status", "c0_cause", "c0_epc", "c0_prid", - "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", - "c0_xcontext", "$21", "$22", "c0_debug", - "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr", - "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave", -}; - -static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] = -{ - { 16, 1, "c0_config1" }, - { 16, 2, "c0_config2" }, - { 16, 3, "c0_config3" }, - { 18, 1, "c0_watchlo,1" }, - { 18, 2, "c0_watchlo,2" }, - { 18, 3, "c0_watchlo,3" }, - { 18, 4, "c0_watchlo,4" }, - { 18, 5, "c0_watchlo,5" }, - { 18, 6, "c0_watchlo,6" }, - { 18, 7, "c0_watchlo,7" }, - { 19, 1, "c0_watchhi,1" }, - { 19, 2, "c0_watchhi,2" }, - { 19, 3, "c0_watchhi,3" }, - { 19, 4, "c0_watchhi,4" }, - { 19, 5, "c0_watchhi,5" }, - { 19, 6, "c0_watchhi,6" }, - { 19, 7, "c0_watchhi,7" }, - { 25, 1, "c0_perfcnt,1" }, - { 25, 2, "c0_perfcnt,2" }, - { 25, 3, "c0_perfcnt,3" }, - { 25, 4, "c0_perfcnt,4" }, - { 25, 5, "c0_perfcnt,5" }, - { 25, 6, "c0_perfcnt,6" }, - { 25, 7, "c0_perfcnt,7" }, - { 27, 1, "c0_cacheerr,1" }, - { 27, 2, "c0_cacheerr,2" }, - { 27, 3, "c0_cacheerr,3" }, - { 28, 1, "c0_datalo" }, - { 29, 1, "c0_datahi" } -}; - -static const char * const mips_cp0_names_mips3264r2[32] = -{ - "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", - "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena", - "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", - "c0_status", "c0_cause", "c0_epc", "c0_prid", - "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", - "c0_xcontext", "$21", "$22", "c0_debug", - "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr", - "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave", -}; - -static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] = -{ - { 4, 1, "c0_contextconfig" }, - { 0, 1, "c0_mvpcontrol" }, - { 0, 2, "c0_mvpconf0" }, - { 0, 3, "c0_mvpconf1" }, - { 1, 1, "c0_vpecontrol" }, - { 1, 2, "c0_vpeconf0" }, - { 1, 3, "c0_vpeconf1" }, - { 1, 4, "c0_yqmask" }, - { 1, 5, "c0_vpeschedule" }, - { 1, 6, "c0_vpeschefback" }, - { 2, 1, "c0_tcstatus" }, - { 2, 2, "c0_tcbind" }, - { 2, 3, "c0_tcrestart" }, - { 2, 4, "c0_tchalt" }, - { 2, 5, "c0_tccontext" }, - { 2, 6, "c0_tcschedule" }, - { 2, 7, "c0_tcschefback" }, - { 5, 1, "c0_pagegrain" }, - { 6, 1, "c0_srsconf0" }, - { 6, 2, "c0_srsconf1" }, - { 6, 3, "c0_srsconf2" }, - { 6, 4, "c0_srsconf3" }, - { 6, 5, "c0_srsconf4" }, - { 12, 1, "c0_intctl" }, - { 12, 2, "c0_srsctl" }, - { 12, 3, "c0_srsmap" }, - { 15, 1, "c0_ebase" }, - { 16, 1, "c0_config1" }, - { 16, 2, "c0_config2" }, - { 16, 3, "c0_config3" }, - { 18, 1, "c0_watchlo,1" }, - { 18, 2, "c0_watchlo,2" }, - { 18, 3, "c0_watchlo,3" }, - { 18, 4, "c0_watchlo,4" }, - { 18, 5, "c0_watchlo,5" }, - { 18, 6, "c0_watchlo,6" }, - { 18, 7, "c0_watchlo,7" }, - { 19, 1, "c0_watchhi,1" }, - { 19, 2, "c0_watchhi,2" }, - { 19, 3, "c0_watchhi,3" }, - { 19, 4, "c0_watchhi,4" }, - { 19, 5, "c0_watchhi,5" }, - { 19, 6, "c0_watchhi,6" }, - { 19, 7, "c0_watchhi,7" }, - { 23, 1, "c0_tracecontrol" }, - { 23, 2, "c0_tracecontrol2" }, - { 23, 3, "c0_usertracedata" }, - { 23, 4, "c0_tracebpc" }, - { 25, 1, "c0_perfcnt,1" }, - { 25, 2, "c0_perfcnt,2" }, - { 25, 3, "c0_perfcnt,3" }, - { 25, 4, "c0_perfcnt,4" }, - { 25, 5, "c0_perfcnt,5" }, - { 25, 6, "c0_perfcnt,6" }, - { 25, 7, "c0_perfcnt,7" }, - { 27, 1, "c0_cacheerr,1" }, - { 27, 2, "c0_cacheerr,2" }, - { 27, 3, "c0_cacheerr,3" }, - { 28, 1, "c0_datalo" }, - { 28, 2, "c0_taglo1" }, - { 28, 3, "c0_datalo1" }, - { 28, 4, "c0_taglo2" }, - { 28, 5, "c0_datalo2" }, - { 28, 6, "c0_taglo3" }, - { 28, 7, "c0_datalo3" }, - { 29, 1, "c0_datahi" }, - { 29, 2, "c0_taghi1" }, - { 29, 3, "c0_datahi1" }, - { 29, 4, "c0_taghi2" }, - { 29, 5, "c0_datahi2" }, - { 29, 6, "c0_taghi3" }, - { 29, 7, "c0_datahi3" }, -}; - -/* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */ -static const char * const mips_cp0_names_sb1[32] = -{ - "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1", - "c0_context", "c0_pagemask", "c0_wired", "$7", - "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare", - "c0_status", "c0_cause", "c0_epc", "c0_prid", - "c0_config", "c0_lladdr", "c0_watchlo", "c0_watchhi", - "c0_xcontext", "$21", "$22", "c0_debug", - "c0_depc", "c0_perfcnt", "c0_errctl", "c0_cacheerr_i", - "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave", -}; - -static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] = -{ - { 16, 1, "c0_config1" }, - { 18, 1, "c0_watchlo,1" }, - { 19, 1, "c0_watchhi,1" }, - { 22, 0, "c0_perftrace" }, - { 23, 3, "c0_edebug" }, - { 25, 1, "c0_perfcnt,1" }, - { 25, 2, "c0_perfcnt,2" }, - { 25, 3, "c0_perfcnt,3" }, - { 25, 4, "c0_perfcnt,4" }, - { 25, 5, "c0_perfcnt,5" }, - { 25, 6, "c0_perfcnt,6" }, - { 25, 7, "c0_perfcnt,7" }, - { 26, 1, "c0_buserr_pa" }, - { 27, 1, "c0_cacheerr_d" }, - { 27, 3, "c0_cacheerr_d_pa" }, - { 28, 1, "c0_datalo_i" }, - { 28, 2, "c0_taglo_d" }, - { 28, 3, "c0_datalo_d" }, - { 29, 1, "c0_datahi_i" }, - { 29, 2, "c0_taghi_d" }, - { 29, 3, "c0_datahi_d" }, -}; - -static const char * const mips_hwr_names_numeric[32] = -{ - "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", - "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", - "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", - "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" -}; - -static const char * const mips_hwr_names_mips3264r2[32] = -{ - "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres", - "$4", "$5", "$6", "$7", - "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", - "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", - "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31" -}; - -struct mips_abi_choice -{ - const char * name; - const char * const *gpr_names; - const char * const *fpr_names; -}; - -struct mips_abi_choice mips_abi_choices[] = -{ - { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric }, - { "o32", mips_gpr_names_oldabi, mips_fpr_names_32 }, - { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 }, - { "n64", mips_gpr_names_newabi, mips_fpr_names_64 }, -}; - -struct mips_arch_choice -{ - const char *name; - int bfd_mach_valid; - unsigned long bfd_mach; - int processor; - int isa; - const char * const *cp0_names; - const struct mips_cp0sel_name *cp0sel_names; - unsigned int cp0sel_names_len; - const char * const *hwr_names; -}; - -const struct mips_arch_choice mips_arch_choices[] = -{ - { "numeric", 0, 0, 0, 0, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - - { "r3000", 1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r3900", 1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r4000", 1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r4010", 1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "vr4100", 1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "vr4111", 1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "vr4120", 1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r4300", 1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r4400", 1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r4600", 1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r4650", 1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r5000", 1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "vr5400", 1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "vr5500", 1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r6000", 1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "rm7000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "rm9000", 1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r8000", 1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r10000", 1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "r12000", 1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - { "mips5", 1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, - - /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs. - Note that MIPS-3D and MDMX are not applicable to MIPS32. (See - _MIPS32 Architecture For Programmers Volume I: Introduction to the - MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95), - page 1. */ - { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32, - ISA_MIPS32 | INSN_MIPS16 | INSN_SMARTMIPS, - mips_cp0_names_mips3264, - mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), - mips_hwr_names_numeric }, - - { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2, - (ISA_MIPS32R2 | INSN_MIPS16 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2 - | INSN_MIPS3D | INSN_MT), - mips_cp0_names_mips3264r2, - mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), - mips_hwr_names_mips3264r2 }, - - /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs. */ - { "mips64", 1, bfd_mach_mipsisa64, CPU_MIPS64, - ISA_MIPS64 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX, - mips_cp0_names_mips3264, - mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264), - mips_hwr_names_numeric }, - - { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2, - (ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2 - | INSN_DSP64 | INSN_MT | INSN_MDMX), - mips_cp0_names_mips3264r2, - mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2), - mips_hwr_names_mips3264r2 }, - - { "sb1", 1, bfd_mach_mips_sb1, CPU_SB1, - ISA_MIPS64 | INSN_MIPS3D | INSN_SB1, - mips_cp0_names_sb1, - mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1), - mips_hwr_names_numeric }, - - { "loongson2e", 1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E, - ISA_MIPS3 | INSN_LOONGSON_2E, - mips_cp0_names_numeric, - NULL, 0, mips_hwr_names_numeric }, - - { "loongson2f", 1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F, - ISA_MIPS64 | INSN_LOONGSON_2F, - mips_cp0_names_numeric, - NULL, 0, mips_hwr_names_numeric }, - - /* This entry, mips16, is here only for ISA/processor selection; do - not print its name. */ - { "", 1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3 | INSN_MIPS16, - mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric }, -}; - -/* ISA and processor type to disassemble for, and register names to use. - set_default_mips_dis_options and parse_mips_dis_options fill in these - values. */ -static int mips_processor; -static int mips_isa; -static const char * const *mips_gpr_names; -static const char * const *mips_fpr_names; -static const char * const *mips_cp0_names; -static const struct mips_cp0sel_name *mips_cp0sel_names; -static int mips_cp0sel_names_len; -static const char * const *mips_hwr_names; - -/* Other options */ -static int no_aliases; /* If set disassemble as most general inst. */ - -static const struct mips_abi_choice * -choose_abi_by_name (const char *name, unsigned int namelen) -{ - const struct mips_abi_choice *c; - unsigned int i; - - for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && !c; i++) { - if (strncmp (mips_abi_choices[i].name, name, namelen) == 0 && strlen (mips_abi_choices[i].name) == namelen) { - c = &mips_abi_choices[i]; - } - } - - return c; -} - -static const struct mips_arch_choice * -choose_arch_by_name (const char *name, unsigned int namelen) -{ - const struct mips_arch_choice *c = NULL; - unsigned int i; - - for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && !c; i++) { - if (strncmp (mips_arch_choices[i].name, name, namelen) == 0 && strlen (mips_arch_choices[i].name) == namelen) { - c = &mips_arch_choices[i]; - } - } - - return c; -} - -static const struct mips_arch_choice * -choose_arch_by_number (unsigned long mach) -{ - static unsigned long hint_bfd_mach; - static const struct mips_arch_choice *hint_arch_choice; - const struct mips_arch_choice *c; - unsigned int i; - - /* We optimize this because even if the user specifies no - flags, this will be done for every instruction! */ - if (hint_bfd_mach == mach && hint_arch_choice != NULL && hint_arch_choice->bfd_mach == hint_bfd_mach) { - return hint_arch_choice; - } - - for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && !c; i++) - { - if (mips_arch_choices[i].bfd_mach_valid - && mips_arch_choices[i].bfd_mach == mach) - { - c = &mips_arch_choices[i]; - hint_bfd_mach = mach; - hint_arch_choice = c; - } - } - return c; -} - -/* Check if the object uses NewABI conventions. */ - -static int -is_newabi (Elf_Internal_Ehdr *header) -{ - /* There are no old-style ABIs which use 64-bit ELF. */ - if (header->e_ident[EI_CLASS] == ELFCLASS64) { - return 1; - } - - /* If a 32-bit ELF file, n32 is a new-style ABI. */ - if ((header->e_flags & EF_MIPS_ABI2) != 0) { - return 1; - } - - return 0; -} - -static void -set_default_mips_dis_options (struct disassemble_info *info) -{ - const struct mips_arch_choice *chosen_arch; - - /* Defaults: mipsIII/r3000 (?!), (o)32-style ("oldabi") GPR names, - and numeric FPR, CP0 register, and HWR names. */ - mips_isa = ISA_MIPS3; - mips_processor = CPU_LOONGSON_2F; // R3000 - mips_gpr_names = mips_gpr_names_oldabi; - mips_fpr_names = mips_fpr_names_numeric; - mips_cp0_names = mips_cp0_names_numeric; - mips_cp0sel_names = NULL; - mips_cp0sel_names_len = 0; - mips_hwr_names = mips_hwr_names_numeric; - no_aliases = 0; - - /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */ - if (info->flavour == bfd_target_elf_flavour && info->section != NULL) - { - Elf_Internal_Ehdr *header; - - header = elf_elfheader (info->section->owner); - if (is_newabi (header)) { - mips_gpr_names = mips_gpr_names_newabi; - } - } - - /* Set ISA, architecture, and cp0 register names as best we can. */ -#if ! SYMTAB_AVAILABLE - /* This is running out on a target machine, not in a host tool. - FIXME: Where does mips_target_info come from? */ - target_processor = mips_target_info.processor; - mips_isa = mips_target_info.isa; -#else - chosen_arch = choose_arch_by_number (info->mach); - if (chosen_arch != NULL) - { - mips_processor = chosen_arch->processor; - mips_isa = chosen_arch->isa; - mips_cp0_names = chosen_arch->cp0_names; - mips_cp0sel_names = chosen_arch->cp0sel_names; - mips_cp0sel_names_len = chosen_arch->cp0sel_names_len; - mips_hwr_names = chosen_arch->hwr_names; - } -#endif -} - -static void -parse_mips_dis_option (const char *option, unsigned int len) -{ - unsigned int i, optionlen, vallen; - const char *val; - const struct mips_abi_choice *chosen_abi; - const struct mips_arch_choice *chosen_arch; - - /* Try to match options that are simple flags - if (CONST_STRNEQ (option, "no-aliases")) - { - no_aliases = 1; - return; - } */ - - /* Look for the = that delimits the end of the option name. */ - for (i = 0; i < len; i++) { - if (option[i] == '=') { - break; - } - } - - if (i == 0) { /* Invalid option: no name before '='. */ - return; - } - if (i == len) { /* Invalid option: no '='. */ - return; - } - if (i == (len - 1)) { /* Invalid option: no value after '='. */ - return; - } - - optionlen = i; - val = option + (optionlen + 1); - vallen = len - (optionlen + 1); - - if (strlen ("abi") == optionlen - && !strncmp ("abi", option, optionlen)) { - chosen_abi = choose_abi_by_name (val, vallen); - if (chosen_abi) { - mips_gpr_names = chosen_abi->gpr_names; - mips_fpr_names = chosen_abi->fpr_names; - } - return; - } - - if (strncmp ("gpr-names", option, optionlen) == 0 - && strlen ("gpr-names") == optionlen) - { - chosen_abi = choose_abi_by_name (val, vallen); - if (chosen_abi != NULL) { - mips_gpr_names = chosen_abi->gpr_names; - } - return; - } - - if (strncmp ("fpr-names", option, optionlen) == 0 - && strlen ("fpr-names") == optionlen) - { - chosen_abi = choose_abi_by_name (val, vallen); - if (chosen_abi != NULL) { - mips_fpr_names = chosen_abi->fpr_names; - } - return; - } - - if (strncmp ("cp0-names", option, optionlen) == 0 - && strlen ("cp0-names") == optionlen) - { - chosen_arch = choose_arch_by_name (val, vallen); - if (chosen_arch != NULL) - { - mips_cp0_names = chosen_arch->cp0_names; - mips_cp0sel_names = chosen_arch->cp0sel_names; - mips_cp0sel_names_len = chosen_arch->cp0sel_names_len; - } - return; - } - - if (strncmp ("hwr-names", option, optionlen) == 0 - && strlen ("hwr-names") == optionlen) - { - chosen_arch = choose_arch_by_name (val, vallen); - if (chosen_arch != NULL) { - mips_hwr_names = chosen_arch->hwr_names; - } - return; - } - - if (strncmp ("reg-names", option, optionlen) == 0 - && strlen ("reg-names") == optionlen) - { - /* We check both ABI and ARCH here unconditionally, so - that "numeric" will do the desirable thing: select - numeric register names for all registers. Other than - that, a given name probably won't match both. */ - chosen_abi = choose_abi_by_name (val, vallen); - if (chosen_abi != NULL) - { - mips_gpr_names = chosen_abi->gpr_names; - mips_fpr_names = chosen_abi->fpr_names; - } - chosen_arch = choose_arch_by_name (val, vallen); - if (chosen_arch != NULL) - { - mips_cp0_names = chosen_arch->cp0_names; - mips_cp0sel_names = chosen_arch->cp0sel_names; - mips_cp0sel_names_len = chosen_arch->cp0sel_names_len; - mips_hwr_names = chosen_arch->hwr_names; - } - return; - } - - /* Invalid option. */ -} - -void -parse_mips_dis_options (const char *options) -{ - const char *option_end; - - if (!options) { - return; - } - - while (*options != '\0') - { - /* Skip empty options. */ - if (*options == ',') - { - options++; - continue; - } - - /* We know that *options is neither NUL or a comma. */ - option_end = options + 1; - while (*option_end != ',' && *option_end != '\0') { - option_end++; - } - - parse_mips_dis_option (options, option_end - options); - - /* Go on to the next one. If option_end points to a comma, it - will be skipped above. */ - options = option_end; - } -} - -static const struct mips_cp0sel_name * -lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names, - unsigned int len, - unsigned int cp0reg, - unsigned int sel) -{ - unsigned int i; - - for (i = 0; i < len; i++) { - if (names[i].cp0reg == cp0reg && names[i].sel == sel) { - return &names[i]; - } - } - return NULL; -} - -/* Print insn arguments for 32/64-bit code. */ - -static void -print_insn_args (const char *d, - register unsigned long int l, - bfd_vma pc, - struct disassemble_info *info, - const struct mips_opcode *opp) -{ - int op, delta; - unsigned int lsb, msb, msbd; - - lsb = 0; - - for (; *d != '\0'; d++) - { - switch (*d) - { - case ',': - (*info->fprintf_func) (info->stream, "%c ", *d); - break; - case '(': - case ')': - case '[': - case ']': - (*info->fprintf_func) (info->stream, "%c", *d); - break; - - case '+': - /* Extension character; switch for second char. */ - d++; - switch (*d) - { - case '\0': - /* xgettext:c-format */ - (*info->fprintf_func) (info->stream, - _("# internal error, incomplete extension sequence (+)")); - return; - - case 'A': - lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT; - (*info->fprintf_func) (info->stream, "0x%x", lsb); - break; - - case 'B': - msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB; - (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1); - break; - - case '1': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_UDI1) & OP_MASK_UDI1); - break; - - case '2': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_UDI2) & OP_MASK_UDI2); - break; - - case '3': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_UDI3) & OP_MASK_UDI3); - break; - - case '4': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_UDI4) & OP_MASK_UDI4); - break; - - case 'C': - case 'H': - msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD; - (*info->fprintf_func) (info->stream, "0x%x", msbd + 1); - break; - - case 'D': - { - const struct mips_cp0sel_name *n; - unsigned int cp0reg, sel; - - cp0reg = (l >> OP_SH_RD) & OP_MASK_RD; - sel = (l >> OP_SH_SEL) & OP_MASK_SEL; - - /* CP0 register including 'sel' code for mtcN (et al.), to be - printed textually if known. If not known, print both - CP0 register name and sel numerically since CP0 register - with sel 0 may have a name unrelated to register being - printed. */ - n = lookup_mips_cp0sel_name(mips_cp0sel_names, - mips_cp0sel_names_len, cp0reg, sel); - if (n != NULL) { - (*info->fprintf_func) (info->stream, "%s", n->name); - } else { - (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel); - } - break; - } - - case 'E': - lsb = ((l >> OP_SH_SHAMT) & OP_MASK_SHAMT) + 32; - (*info->fprintf_func) (info->stream, "0x%x", lsb); - break; - - case 'F': - msb = ((l >> OP_SH_INSMSB) & OP_MASK_INSMSB) + 32; - (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1); - break; - - case 'G': - msbd = ((l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD) + 32; - (*info->fprintf_func) (info->stream, "0x%x", msbd + 1); - break; - - case 't': /* Coprocessor 0 reg name */ - (*info->fprintf_func) (info->stream, "%s", - mips_cp0_names[(l >> OP_SH_RT) & - OP_MASK_RT]); - break; - - case 'T': /* Coprocessor 0 reg name */ - { - const struct mips_cp0sel_name *n; - unsigned int cp0reg, sel; - - cp0reg = (l >> OP_SH_RT) & OP_MASK_RT; - sel = (l >> OP_SH_SEL) & OP_MASK_SEL; - - /* CP0 register including 'sel' code for mftc0, to be - printed textually if known. If not known, print both - CP0 register name and sel numerically since CP0 register - with sel 0 may have a name unrelated to register being - printed. */ - n = lookup_mips_cp0sel_name(mips_cp0sel_names, - mips_cp0sel_names_len, cp0reg, sel); - if (n != NULL) { - (*info->fprintf_func) (info->stream, "%s", n->name); - } else { - (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel); - } - break; - } - - default: - /* xgettext:c-format */ - (*info->fprintf_func) (info->stream, - _("# internal error, undefined extension sequence (+%c)"), - *d); - return; - } - break; - - case '2': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_BP) & OP_MASK_BP); - break; - - case '3': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_SA3) & OP_MASK_SA3); - break; - - case '4': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_SA4) & OP_MASK_SA4); - break; - - case '5': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_IMM8) & OP_MASK_IMM8); - break; - - case '6': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_RS) & OP_MASK_RS); - break; - - case '7': - (*info->fprintf_func) (info->stream, "$ac%ld", - (l >> OP_SH_DSPACC) & OP_MASK_DSPACC); - break; - - case '8': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_WRDSP) & OP_MASK_WRDSP); - break; - - case '9': - (*info->fprintf_func) (info->stream, "$ac%ld", - (l >> OP_SH_DSPACC_S) & OP_MASK_DSPACC_S); - break; - - case '0': /* dsp 6-bit signed immediate in bit 20 */ - delta = ((l >> OP_SH_DSPSFT) & OP_MASK_DSPSFT); - if (delta & 0x20) { /* test sign bit */ - delta |= ~OP_MASK_DSPSFT; - } - (*info->fprintf_func) (info->stream, "%d", delta); - break; - - case ':': /* dsp 7-bit signed immediate in bit 19 */ - delta = ((l >> OP_SH_DSPSFT_7) & OP_MASK_DSPSFT_7); - if (delta & 0x40) { /* test sign bit */ - delta |= ~OP_MASK_DSPSFT_7; - } - (*info->fprintf_func) (info->stream, "%d", delta); - break; - - case '\'': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_RDDSP) & OP_MASK_RDDSP); - break; - - case '@': /* dsp 10-bit signed immediate in bit 16 */ - delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10); - if (delta & 0x200) { /* test sign bit */ - delta |= ~OP_MASK_IMM10; - } - (*info->fprintf_func) (info->stream, "%d", delta); - break; - - case '!': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_MT_U) & OP_MASK_MT_U); - break; - - case '$': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_MT_H) & OP_MASK_MT_H); - break; - - case '*': - (*info->fprintf_func) (info->stream, "$ac%ld", - (l >> OP_SH_MTACC_T) & OP_MASK_MTACC_T); - break; - - case '&': - (*info->fprintf_func) (info->stream, "$ac%ld", - (l >> OP_SH_MTACC_D) & OP_MASK_MTACC_D); - break; - - case 'g': - /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */ - (*info->fprintf_func) (info->stream, "$%ld", - (l >> OP_SH_RD) & OP_MASK_RD); - break; - - case 's': - case 'b': - case 'r': - case 'v': - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[(l >> OP_SH_RS) & OP_MASK_RS]); - break; - - case 't': - case 'w': - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]); - break; - - case 'i': - case 'u': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE); - break; - - case 'j': /* Same as i, but sign-extended. */ - case 'o': - delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA; - if (delta & 0x8000) { - delta |= ~0xffff; - } - (*info->fprintf_func) (info->stream, "%d", - delta); - break; - - case 'h': - (*info->fprintf_func) (info->stream, "0x%x", - (unsigned int) ((l >> OP_SH_PREFX) - & OP_MASK_PREFX)); - break; - - case 'k': - (*info->fprintf_func) (info->stream, "0x%x", - (unsigned int) ((l >> OP_SH_CACHE) - & OP_MASK_CACHE)); - break; - - case 'a': - info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff) - | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2)); - /* For gdb disassembler, force odd address on jalx. */ - //if (info->flavour == bfd_target_unknown_flavour - // && strcmp (opp->name, "jalx") == 0) - //info->target |= 1; - (*info->print_address_func) (info->target, info); - break; - - case 'p': - /* Sign extend the displacement. */ - delta = (l >> OP_SH_DELTA) & OP_MASK_DELTA; - if (delta & 0x8000) { - delta |= ~0xffff; - } - info->target = (delta << 2) + pc + INSNLEN; - (*info->print_address_func) (info->target, info); - break; - - case 'd': - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[(l >> OP_SH_RD) & OP_MASK_RD]); - break; - - case 'U': - { - /* First check for both rd and rt being equal. */ - unsigned int reg = (l >> OP_SH_RD) & OP_MASK_RD; - if (reg == ((l >> OP_SH_RT) & OP_MASK_RT)) { - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[reg]); - } else { - /* If one is zero use the other. */ - if (reg == 0) { - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]); - } else if (((l >> OP_SH_RT) & OP_MASK_RT) == 0) { - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[reg]); - } else { /* Bogus, result depends on processor. */ - (*info->fprintf_func) (info->stream, "%s or %s", - mips_gpr_names[reg], - mips_gpr_names[(l >> OP_SH_RT) & OP_MASK_RT]); - } - } - } - break; - - case 'z': - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]); - break; - - case '<': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_SHAMT) & OP_MASK_SHAMT); - break; - - case 'c': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_CODE) & OP_MASK_CODE); - break; - - case 'q': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_CODE2) & OP_MASK_CODE2); - break; - - case 'C': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_COPZ) & OP_MASK_COPZ); - break; - - case 'B': - (*info->fprintf_func) (info->stream, "0x%lx", - - (l >> OP_SH_CODE20) & OP_MASK_CODE20); - break; - - case 'J': - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_CODE19) & OP_MASK_CODE19); - break; - - case 'S': - case 'V': - (*info->fprintf_func) (info->stream, "%s", - mips_fpr_names[(l >> OP_SH_FS) & OP_MASK_FS]); - break; - - case 'T': - case 'W': - (*info->fprintf_func) (info->stream, "%s", - mips_fpr_names[(l >> OP_SH_FT) & OP_MASK_FT]); - break; - - case 'D': - (*info->fprintf_func) (info->stream, "%s", - mips_fpr_names[(l >> OP_SH_FD) & OP_MASK_FD]); - break; - - case 'R': - (*info->fprintf_func) (info->stream, "%s", - mips_fpr_names[(l >> OP_SH_FR) & OP_MASK_FR]); - break; - - case 'E': - /* Coprocessor register for lwcN instructions, et al. - - Note that there is no load/store cp0 instructions, and - that FPU (cp1) instructions disassemble this field using - 'T' format. Therefore, until we gain understanding of - cp2 register names, we can simply print the register - numbers. */ - (*info->fprintf_func) (info->stream, "$%ld", - (l >> OP_SH_RT) & OP_MASK_RT); - break; - - case 'G': - /* Coprocessor register for mtcN instructions, et al. Note - that FPU (cp1) instructions disassemble this field using - 'S' format. Therefore, we only need to worry about cp0, - cp2, and cp3. */ - op = (l >> OP_SH_OP) & OP_MASK_OP; - if (op == OP_OP_COP0) { - (*info->fprintf_func) (info->stream, "%s", - mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]); - } else { - (*info->fprintf_func) (info->stream, "$%ld", - (l >> OP_SH_RD) & OP_MASK_RD); - } - break; - - case 'K': - (*info->fprintf_func) (info->stream, "%s", - mips_hwr_names[(l >> OP_SH_RD) & OP_MASK_RD]); - break; - - case 'N': - (*info->fprintf_func) (info->stream, - ((opp->pinfo & (FP_D | FP_S)) != 0 - ? "$fcc%ld" : "$cc%ld"), - (l >> OP_SH_BCC) & OP_MASK_BCC); - break; - - case 'M': - (*info->fprintf_func) (info->stream, "$fcc%ld", - (l >> OP_SH_CCC) & OP_MASK_CCC); - break; - - case 'P': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_PERFREG) & OP_MASK_PERFREG); - break; - - case 'e': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE); - break; - - case '%': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN); - break; - - case 'H': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_SEL) & OP_MASK_SEL); - break; - - case 'O': - (*info->fprintf_func) (info->stream, "%ld", - (l >> OP_SH_ALN) & OP_MASK_ALN); - break; - - case 'Q': - { - unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL; - - if ((vsel & 0x10) == 0) - { - int fmt; - - vsel &= 0x0f; - for (fmt = 0; fmt < 3; fmt++, vsel >>= 1) { - if ((vsel & 1) == 0) { - break; - } - } - (*info->fprintf_func) (info->stream, "$v%ld[%d]", - (l >> OP_SH_FT) & OP_MASK_FT, - vsel >> 1); - } - else if ((vsel & 0x08) == 0) - { - (*info->fprintf_func) (info->stream, "$v%ld", - (l >> OP_SH_FT) & OP_MASK_FT); - } - else - { - (*info->fprintf_func) (info->stream, "0x%lx", - (l >> OP_SH_FT) & OP_MASK_FT); - } - } - break; - - case 'X': - (*info->fprintf_func) (info->stream, "$v%ld", - (l >> OP_SH_FD) & OP_MASK_FD); - break; - - case 'Y': - (*info->fprintf_func) (info->stream, "$v%ld", - (l >> OP_SH_FS) & OP_MASK_FS); - break; - - case 'Z': - (*info->fprintf_func) (info->stream, "$v%ld", - (l >> OP_SH_FT) & OP_MASK_FT); - break; - - default: - /* xgettext:c-format */ - (*info->fprintf_func) (info->stream, - _("# internal error, undefined modifier(%c)"), - *d); - return; - } - } -} - -/* Print the mips instruction at address MEMADDR in debugged memory, - on using INFO. Returns length of the instruction, in bytes, which is - always INSNLEN. BIGENDIAN must be 1 if this is big-endian code, 0 if - this is little-endian code. */ - -static int -print_insn_mips (bfd_vma memaddr, - unsigned long int word, - struct disassemble_info *info) -{ - const struct mips_opcode *op; - static bfd_boolean init = 0; - static const struct mips_opcode *mips_hash[OP_MASK_OP + 1]; - - /* Build a hash table to shorten the search time. */ - if (! init) - { - unsigned int i; - - for (i = 0; i <= OP_MASK_OP; i++) - { - for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++) - { - if (op->pinfo == INSN_MACRO || (no_aliases && (op->pinfo2 & INSN2_ALIAS))) { - continue; - } - if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP)) { - mips_hash[i] = op; - break; - } - } - } - - init = 1; - } - - info->bytes_per_chunk = INSNLEN; - info->display_endian = info->endian; - info->insn_info_valid = 1; - info->branch_delay_insns = 0; - info->data_size = 0; - info->insn_type = dis_nonbranch; - info->target = 0; - info->target2 = 0; - - op = mips_hash[(word >> OP_SH_OP) & OP_MASK_OP]; - if (op != NULL) - { - for (; op < &mips_opcodes[NUMOPCODES]; op++) - { - if (op->pinfo != INSN_MACRO - && !(no_aliases && (op->pinfo2 & INSN2_ALIAS)) - && (word & op->mask) == op->match) - { - const char *d; - - /* We always allow to disassemble the jalx instruction. */ - if (!OPCODE_IS_MEMBER (op, mips_isa, mips_processor) && strcmp (op->name, "jalx")) { - continue; - } - - /* Figure out instruction type and branch delay information. */ - if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0) - { - if ((info->insn_type & INSN_WRITE_GPR_31) != 0) { - info->insn_type = dis_jsr; - } else { - info->insn_type = dis_branch; - } - info->branch_delay_insns = 1; - } - else if ((op->pinfo & (INSN_COND_BRANCH_DELAY - | INSN_COND_BRANCH_LIKELY)) != 0) - { - if ((info->insn_type & INSN_WRITE_GPR_31) != 0) { - info->insn_type = dis_condjsr; - } else { - info->insn_type = dis_condbranch; - } - info->branch_delay_insns = 1; - } else if ((op->pinfo & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY_DELAY)) != 0) { - info->insn_type = dis_dref; - } - - (*info->fprintf_func) (info->stream, "%s", op->name); - - d = op->args; - if (d != NULL && *d != '\0') { - (*info->fprintf_func) (info->stream, " "); - print_insn_args (d, word, memaddr, info, op); - } - - return INSNLEN; - } - } - } - - /* Plugin undefined instructions. */ - info->insn_type = dis_noninsn; - (*info->fprintf_func) (info->stream, "0x%lx", word); - return INSNLEN; -} - -/* Disassemble an operand for a mips16 instruction. */ - -static void -print_mips16_insn_arg (char type, - const struct mips_opcode *op, - int l, - bfd_boolean use_extend, - int extend, - bfd_vma memaddr, - struct disassemble_info *info) -{ - switch (type) - { - case ',': - case '(': - case ')': - (*info->fprintf_func) (info->stream, "%c", type); - break; - - case 'y': - case 'w': - (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names(((l >> MIPS16OP_SH_RY) - & MIPS16OP_MASK_RY))); - break; - - case 'x': - case 'v': - (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names(((l >> MIPS16OP_SH_RX) - & MIPS16OP_MASK_RX))); - break; - - case 'z': - (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names(((l >> MIPS16OP_SH_RZ) - & MIPS16OP_MASK_RZ))); - break; - - case 'Z': - (*info->fprintf_func) (info->stream, "%s", - mips16_reg_names(((l >> MIPS16OP_SH_MOVE32Z) - & MIPS16OP_MASK_MOVE32Z))); - break; - - case '0': - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[0]); - break; - - case 'S': - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[29]); - break; - - case 'P': - (*info->fprintf_func) (info->stream, "$pc"); - break; - - case 'R': - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[31]); - break; - - case 'X': - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[((l >> MIPS16OP_SH_REGR32) - & MIPS16OP_MASK_REGR32)]); - break; - - case 'Y': - (*info->fprintf_func) (info->stream, "%s", - mips_gpr_names[MIPS16OP_EXTRACT_REG32R (l)]); - break; - - case '<': - case '>': - case '[': - case ']': - case '4': - case '5': - case 'H': - case 'W': - case 'D': - case 'j': - case '6': - case '8': - case 'V': - case 'C': - case 'U': - case 'k': - case 'K': - case 'p': - case 'q': - case 'A': - case 'B': - case 'E': - { - int immed, nbits, shift, signedp, extbits, pcrel, extu, branch; - - shift = 0; - signedp = 0; - extbits = 16; - pcrel = 0; - extu = 0; - branch = 0; - switch (type) - { - case '<': - nbits = 3; - immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ; - extbits = 5; - extu = 1; - break; - case '>': - nbits = 3; - immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX; - extbits = 5; - extu = 1; - break; - case '[': - nbits = 3; - immed = (l >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ; - extbits = 6; - extu = 1; - break; - case ']': - nbits = 3; - immed = (l >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX; - extbits = 6; - extu = 1; - break; - case '4': - nbits = 4; - immed = (l >> MIPS16OP_SH_IMM4) & MIPS16OP_MASK_IMM4; - signedp = 1; - extbits = 15; - break; - case '5': - nbits = 5; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; - info->insn_type = dis_dref; - info->data_size = 1; - break; - case 'H': - nbits = 5; - shift = 1; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; - info->insn_type = dis_dref; - info->data_size = 2; - break; - case 'W': - nbits = 5; - shift = 2; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; - if ((op->pinfo & MIPS16_INSN_READ_PC) == 0 - && (op->pinfo & MIPS16_INSN_READ_SP) == 0) - { - info->insn_type = dis_dref; - info->data_size = 4; - } - break; - case 'D': - nbits = 5; - shift = 3; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; - info->insn_type = dis_dref; - info->data_size = 8; - break; - case 'j': - nbits = 5; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; - signedp = 1; - break; - case '6': - nbits = 6; - immed = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6; - break; - case '8': - nbits = 8; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; - break; - case 'V': - nbits = 8; - shift = 2; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; - /* FIXME: This might be lw, or it might be addiu to $sp or - $pc. We assume it's load. */ - info->insn_type = dis_dref; - info->data_size = 4; - break; - case 'C': - nbits = 8; - shift = 3; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; - info->insn_type = dis_dref; - info->data_size = 8; - break; - case 'U': - nbits = 8; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; - extu = 1; - break; - case 'k': - nbits = 8; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; - signedp = 1; - break; - case 'K': - nbits = 8; - shift = 3; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; - signedp = 1; - break; - case 'p': - nbits = 8; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; - signedp = 1; - pcrel = 1; - branch = 1; - info->insn_type = dis_condbranch; - break; - case 'q': - nbits = 11; - immed = (l >> MIPS16OP_SH_IMM11) & MIPS16OP_MASK_IMM11; - signedp = 1; - pcrel = 1; - branch = 1; - info->insn_type = dis_branch; - break; - case 'A': - nbits = 8; - shift = 2; - immed = (l >> MIPS16OP_SH_IMM8) & MIPS16OP_MASK_IMM8; - pcrel = 1; - /* FIXME: This can be lw or la. We assume it is lw. */ - info->insn_type = dis_dref; - info->data_size = 4; - break; - case 'B': - nbits = 5; - shift = 3; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; - pcrel = 1; - info->insn_type = dis_dref; - info->data_size = 8; - break; - case 'E': - nbits = 5; - shift = 2; - immed = (l >> MIPS16OP_SH_IMM5) & MIPS16OP_MASK_IMM5; - pcrel = 1; - break; - default: - abort (); - } - - if (! use_extend) - { - if (signedp && immed >= (1 << (nbits - 1))) { - immed -= 1 << nbits; - } - immed <<= shift; - if ((type == '<' || type == '>' || type == '[' || type == ']') && immed == 0) { - immed = 8; - } - } - else - { - if (extbits == 16) { - immed |= ((extend & 0x1f) << 11) | (extend & 0x7e0); - } else if (extbits == 15) { - immed |= ((extend & 0xf) << 11) | (extend & 0x7f0); - } else { - immed = ((extend >> 6) & 0x1f) | (extend & 0x20); - } - immed &= (1 << extbits) - 1; - if (!extu && immed >= (1 << (extbits - 1))) { - immed -= 1 << extbits; - } - } - - if (!pcrel) { - (*info->fprintf_func) (info->stream, "%d", immed); - } else { - bfd_vma baseaddr; - - if (branch) { - immed *= 2; - baseaddr = memaddr + 2; - } else if (use_extend) { - baseaddr = memaddr - 2; - } else { - int status; - bfd_byte buffer[2]; - - baseaddr = memaddr; - - /* If this instruction is in the delay slot of a jr - instruction, the base address is the address of the - jr instruction. If it is in the delay slot of jalr - instruction, the base address is the address of the - jalr instruction. This test is unreliable: we have - no way of knowing whether the previous word is - instruction or data. */ - status = (*info->read_memory_func) (memaddr - 4, buffer, 2, - info); - if (status == 0 && (((info->endian == BFD_ENDIAN_BIG - ? bfd_getb16 (buffer) - : bfd_getl16 (buffer)) & - 0xf800) == 0x1800)) { - baseaddr = memaddr - 4; - } else { - status = (*info->read_memory_func) (memaddr - 2, buffer, - 2, info); - if (status == 0 && (((info->endian == BFD_ENDIAN_BIG - ? bfd_getb16 (buffer) - : bfd_getl16 (buffer)) & - 0xf81f) == 0xe800)) { - baseaddr = memaddr - 2; - } - } - } - info->target = (baseaddr & ~((1 << shift) - 1)) + immed; - if (pcrel && branch && info->flavour == bfd_target_unknown_flavour) { - /* For gdb disassembler, maintain odd address. */ - info->target |= 1; - } - (*info->print_address_func) (info->target, info); - } - } - break; - - case 'a': - { - int jalx = l & 0x400; - - if (!use_extend) { - extend = 0; - } - l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2); - if (!jalx && info->flavour == bfd_target_unknown_flavour) { - /* For gdb disassembler, maintain odd address. */ - l |= 1; - } - } - info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l; - (*info->print_address_func) (info->target, info); - info->insn_type = dis_jsr; - info->branch_delay_insns = 1; - break; - - case 'l': - case 'L': - { - int need_comma, amask, smask; - - need_comma = 0; - - l = (l >> MIPS16OP_SH_IMM6) & MIPS16OP_MASK_IMM6; - - amask = (l >> 3) & 7; - - if (amask > 0 && amask < 5) - { - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]); - if (amask > 1) { - (*info->fprintf_func) (info->stream, "-%s", - mips_gpr_names[amask + 3]); - } - need_comma = 1; - } - - smask = (l >> 1) & 3; - if (smask == 3) - { - (*info->fprintf_func) (info->stream, "%s??", - need_comma ? ", " : ""); - need_comma = 1; - } - else if (smask > 0) - { - (*info->fprintf_func) (info->stream, "%s%s", - need_comma ? ", " : "", - mips_gpr_names[16]); - if (smask > 1) { - (*info->fprintf_func) (info->stream, "-%s", - mips_gpr_names[smask + 15]); - } - need_comma = 1; - } - - if (l & 1) - { - (*info->fprintf_func) (info->stream, "%s%s", - need_comma ? ", " : "", - mips_gpr_names[31]); - need_comma = 1; - } - - if (amask == 5 || amask == 6) - { - (*info->fprintf_func) (info->stream, "%s$f0", - need_comma ? ", " : ""); - if (amask == 6) { - (*info->fprintf_func) (info->stream, "-$f1"); - } - } - } - break; - - case 'm': - case 'M': - /* MIPS16e save/restore. */ - { - int need_comma = 0; - int amask, args, statics; - int nsreg, smask; - int framesz; - int i, j; - - l = l & 0x7f; - if (use_extend) { - l |= extend << 16; - } - - amask = (l >> 16) & 0xf; - if (amask == MIPS16_ALL_ARGS) - { - args = 4; - statics = 0; - } - else if (amask == MIPS16_ALL_STATICS) - { - args = 0; - statics = 4; - } - else - { - args = amask >> 2; - statics = amask & 3; - } - - if (args > 0) { - (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]); - if (args > 1) { - (*info->fprintf_func) (info->stream, "-%s", - mips_gpr_names[4 + args - 1]); - } - need_comma = 1; - } - - framesz = (((l >> 16) & 0xf0) | (l & 0x0f)) * 8; - if (framesz == 0 && !use_extend) { - framesz = 128; - } - - (*info->fprintf_func) (info->stream, "%s%d", - need_comma ? ", " : "", - framesz); - - if (l & 0x40) { /* $ra */ - (*info->fprintf_func) (info->stream, ", %s", mips_gpr_names[31]); - } - - nsreg = (l >> 24) & 0x7; - smask = 0; - if (l & 0x20) { /* $s0 */ - smask |= 1 << 0; - } - if (l & 0x10) { /* $s1 */ - smask |= 1 << 1; - } - if (nsreg > 0) { /* $s2-$s8 */ - smask |= ((1 << nsreg) - 1) << 2; - } - - /* Find first set static reg bit. */ - for (i = 0; i < 9; i++) - { - if (smask & (1 << i)) - { - (*info->fprintf_func) (info->stream, ", %s", - mips_gpr_names[i == 8 ? 30 : (16 + i)]); - /* Skip over string of set bits. */ - for (j = i; smask & (2 << j); j++) {} - if (j > i) { - (*info->fprintf_func) (info->stream, "-%s", - mips_gpr_names[j == 8 ? 30 : (16 + j)]); - } - i = j + 1; - } - } - - /* Statics $ax - $a3. */ - if (statics == 1) { - (*info->fprintf_func) (info->stream, ", %s", mips_gpr_names[7]); - } else if (statics > 0) { - (*info->fprintf_func) (info->stream, ", %s-%s", - mips_gpr_names[7 - statics + 1], - mips_gpr_names[7]); - } - } - break; - - default: - /* xgettext:c-format */ - (*info->fprintf_func) - (info->stream, - _("# internal disassembler error, unrecognised modifier (%c)"), - type); - abort (); - } -} - -/* Disassemble mips16 instructions. */ - -static int -print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info) -{ - int status; - bfd_byte buffer[2]; - int length; - int insn; - bfd_boolean use_extend; - int extend = 0; - const struct mips_opcode *op, *opend; - - info->bytes_per_chunk = 2; - info->display_endian = info->endian; - info->insn_info_valid = 1; - info->branch_delay_insns = 0; - info->data_size = 0; - info->insn_type = dis_nonbranch; - info->target = 0; - info->target2 = 0; - - status = (*info->read_memory_func) (memaddr, buffer, 2, info); - if (status != 0) - { - (*info->memory_error_func) (status, memaddr, info); - return -1; - } - - length = 2; - - if (info->endian == BFD_ENDIAN_BIG) { - insn = bfd_getb16 (buffer); - } else { - insn = bfd_getl16 (buffer); - } - - /* Plugin the extend opcode specially. */ - use_extend = FALSE; - if ((insn & 0xf800) == 0xf000) - { - use_extend = TRUE; - extend = insn & 0x7ff; - - memaddr += 2; - - status = (*info->read_memory_func) (memaddr, buffer, 2, info); - if (status != 0) - { - (*info->fprintf_func) (info->stream, "extend 0x%x", - (unsigned int) extend); - (*info->memory_error_func) (status, memaddr, info); - return -1; - } - - if (info->endian == BFD_ENDIAN_BIG) { - insn = bfd_getb16 (buffer); - } else { - insn = bfd_getl16 (buffer); - } - - /* Check for an extend opcode followed by an extend opcode. */ - if ((insn & 0xf800) == 0xf000) { - (*info->fprintf_func) (info->stream, "extend 0x%x", - (unsigned int)extend); - info->insn_type = dis_noninsn; - return length; - } - - length += 2; - } - - /* FIXME: Should probably use a hash table on the major opcode here. */ - - opend = mips16_opcodes + bfd_mips16_num_opcodes; - for (op = mips16_opcodes; op < opend; op++) - { - if (op->pinfo != INSN_MACRO - && !(no_aliases && (op->pinfo2 & INSN2_ALIAS)) - && (insn & op->mask) == op->match) - { - const char *s; - - if (strchr (op->args, 'a') != NULL) - { - if (use_extend) - { - (*info->fprintf_func) (info->stream, "extend 0x%x", - (unsigned int) extend); - info->insn_type = dis_noninsn; - return length - 2; - } - - use_extend = FALSE; - - memaddr += 2; - - status = (*info->read_memory_func) (memaddr, buffer, 2, - info); - if (status == 0) - { - use_extend = TRUE; - if (info->endian == BFD_ENDIAN_BIG) { - extend = bfd_getb16 (buffer); - } else { - extend = bfd_getl16 (buffer); - } - length += 2; - } - } - - (*info->fprintf_func) (info->stream, "%s", op->name); - if (op->args[0] != '\0') { - (*info->fprintf_func) (info->stream, " "); - } - - for (s = op->args; *s != '\0'; s++) - { - if (*s == ',' - && s[1] == 'w' - && (((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX) - == ((insn >> MIPS16OP_SH_RY) & MIPS16OP_MASK_RY))) - { - /* Skip the register and the comma. */ - ++s; - continue; - } - if (*s == ',' - && s[1] == 'v' - && (((insn >> MIPS16OP_SH_RZ) & MIPS16OP_MASK_RZ) - == ((insn >> MIPS16OP_SH_RX) & MIPS16OP_MASK_RX))) - { - /* Skip the register and the comma. */ - ++s; - continue; - } - print_mips16_insn_arg (*s, op, insn, use_extend, extend, memaddr, - info); - } - - if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0) - { - info->branch_delay_insns = 1; - if (info->insn_type != dis_jsr) { - info->insn_type = dis_branch; - } - } - - return length; - } - } - - if (use_extend) { - (*info->fprintf_func) (info->stream, "0x%x", extend | 0xf000); - } - (*info->fprintf_func) (info->stream, "0x%x", insn); - info->insn_type = dis_noninsn; - - return length; -} - -/* In an environment where we do not know the symbol type of the - instruction we are forced to assume that the low order bit of the - instructions' address may mark it as a mips16 instruction. If we - are single stepping, or the pc is within the disassembled function, - this works. Otherwise, we need a clue. Sometimes. */ - -static int -_print_insn_mips (bfd_vma memaddr, - struct disassemble_info *info, - enum bfd_endian endianness) -{ - bfd_byte buffer[INSNLEN]; - int status; - - set_default_mips_dis_options (info); - parse_mips_dis_options (info->disassembler_options); - -#if 1 - /* FIXME: If odd address, this is CLEARLY a mips 16 instruction. */ - /* Only a few tools will work this way. */ - if (memaddr & 0x01) { - return print_insn_mips16 (memaddr, info); - } -#endif - -#if SYMTAB_AVAILABLE - if (info->mach == bfd_mach_mips16 || (info->flavour == bfd_target_elf_flavour && info->symbols != NULL && ((*(elf_symbol_type **)info->symbols)->internal_elf_sym.st_other == STO_MIPS16))) { - return print_insn_mips16 (memaddr, info); - } -#endif - - status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info); - if (status == 0) - { - unsigned long insn; - - if (endianness == BFD_ENDIAN_BIG) { - insn = (unsigned long)bfd_getb32 (buffer); - } else { - insn = (unsigned long)bfd_getl32 (buffer); - } - - return print_insn_mips (memaddr, insn, info); - } - else - { - (*info->memory_error_func) (status, memaddr, info); - return -1; - } -} - -int -print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info) -{ - return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG); -} - -int -print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info) -{ - return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE); -} - -void -print_mips_disassembler_options (FILE *stream) -{ - unsigned int i; - - fprintf (stream, _("\n\ -The following MIPS specific disassembler options are supported for use\n\ -with the -M switch (multiple options should be separated by commas):\n")); - - fprintf (stream, _("\n\ - gpr-names=ABI Print GPR names according to specified ABI.\n\ - Default: based on binary being disassembled.\n")); - - fprintf (stream, _("\n\ - fpr-names=ABI Print FPR names according to specified ABI.\n\ - Default: numeric.\n")); - - fprintf (stream, _("\n\ - cp0-names=ARCH Print CP0 register names according to\n\ - specified architecture.\n\ - Default: based on binary being disassembled.\n")); - - fprintf (stream, _("\n\ - hwr-names=ARCH Print HWR names according to specified \n\ - architecture.\n\ - Default: based on binary being disassembled.\n")); - - fprintf (stream, _("\n\ - reg-names=ABI Print GPR and FPR names according to\n\ - specified ABI.\n")); - - fprintf (stream, _("\n\ - reg-names=ARCH Print CP0 register and HWR names according to\n\ - specified architecture.\n")); - - fprintf (stream, _("\n\ - For the options above, the following values are supported for \"ABI\":\n\ - ")); - for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++) { - fprintf (stream, " %s", mips_abi_choices[i].name); - } - fprintf (stream, _("\n")); - - fprintf (stream, _("\n\ - For the options above, The following values are supported for \"ARCH\":\n\ - ")); - for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++) { - if (*mips_arch_choices[i].name != '\0') { - fprintf (stream, " %s", mips_arch_choices[i].name); - } - } - fprintf (stream, _("\n")); - - fprintf (stream, _("\n")); -} diff --git a/librz/arch/isa_gnu/mips/mips-opc.c b/librz/arch/isa_gnu/mips/mips-opc.c deleted file mode 100644 index 9161652e4ce..00000000000 --- a/librz/arch/isa_gnu/mips/mips-opc.c +++ /dev/null @@ -1,2018 +0,0 @@ -/* mips-opc.c -- MIPS opcode list. - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 - 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. - Contributed by Ralph Campbell and OSF - Commented and modified by Ian Lance Taylor, Cygnus Support - Extended for MIPS32 support by Anders Norlander, and by SiByte, Inc. - MIPS-3D, MDMX, and MIPS32 Release 2 support added by Broadcom - Corporation (SiByte). - - This file is part of the GNU opcodes library. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - It is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING. If not, write to the - Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include -#include -#include - -/* Short hand so the lines aren't too long. */ - -#define LDD INSN_LOAD_MEMORY_DELAY -#define LCD INSN_LOAD_COPROC_DELAY -#define UBD INSN_UNCOND_BRANCH_DELAY -#define CBD INSN_COND_BRANCH_DELAY -#define COD INSN_COPROC_MOVE_DELAY -#define CLD INSN_COPROC_MEMORY_DELAY -#define CBL INSN_COND_BRANCH_LIKELY -#define TRAP INSN_TRAP -#define SM INSN_STORE_MEMORY - -#define WR_d INSN_WRITE_GPR_D -#define WR_t INSN_WRITE_GPR_T -#define WR_31 INSN_WRITE_GPR_31 -#define WR_D INSN_WRITE_FPR_D -#define WR_T INSN_WRITE_FPR_T -#define WR_S INSN_WRITE_FPR_S -#define RD_s INSN_READ_GPR_S -#define RD_b INSN_READ_GPR_S -#define RD_t INSN_READ_GPR_T -#define RD_S INSN_READ_FPR_S -#define RD_T INSN_READ_FPR_T -#define RD_R INSN_READ_FPR_R -#define WR_CC INSN_WRITE_COND_CODE -#define RD_CC INSN_READ_COND_CODE -#define RD_C0 INSN_COP -#define RD_C1 INSN_COP -#define RD_C2 INSN_COP -#define RD_C3 INSN_COP -#define WR_C0 INSN_COP -#define WR_C1 INSN_COP -#define WR_C2 INSN_COP -#define WR_C3 INSN_COP - -#define WR_HI INSN_WRITE_HI -#define RD_HI INSN_READ_HI -#define MOD_HI (WR_HI|RD_HI) - -#define WR_LO INSN_WRITE_LO -#define RD_LO INSN_READ_LO -#define MOD_LO (WR_LO|RD_LO) - -#define WR_HILO (WR_HI|WR_LO) -#define RD_HILO (RD_HI|RD_LO) -#define MOD_HILO (WR_HILO|RD_HILO) - -#define IS_M INSN_MULT - -#define WR_MACC INSN2_WRITE_MDMX_ACC -#define RD_MACC INSN2_READ_MDMX_ACC - -#define I1 INSN_ISA1 -#define I2 INSN_ISA2 -#define I3 INSN_ISA3 -#define I4 INSN_ISA4 -#define I5 INSN_ISA5 -#define I32 INSN_ISA32 -#define I64 INSN_ISA64 -#define I33 INSN_ISA32R2 -#define I65 INSN_ISA64R2 -#define I3_32 INSN_ISA3_32 -#define I3_33 INSN_ISA3_32R2 -#define I4_32 INSN_ISA4_32 -#define I4_33 INSN_ISA4_32R2 -#define I5_33 INSN_ISA5_32R2 - -/* MIPS16 ASE support. */ -#define I16 INSN_MIPS16 - -/* MIPS64 MIPS-3D ASE support. */ -#define M3D INSN_MIPS3D - -/* MIPS32 SmartMIPS ASE support. */ -#define SMT INSN_SMARTMIPS - -/* MIPS64 MDMX ASE support. */ -#define MX INSN_MDMX - -#define IL2E (INSN_LOONGSON_2E) -#define IL2F (INSN_LOONGSON_2F) - -#define P3 INSN_4650 -#define L1 INSN_4010 -#define V1 (INSN_4100 | INSN_4111 | INSN_4120) -#define T3 INSN_3900 -#define M1 INSN_10000 -#define SB1 INSN_SB1 -#define N411 INSN_4111 -#define N412 INSN_4120 -#define N5 (INSN_5400 | INSN_5500) -#define N54 INSN_5400 -#define N55 INSN_5500 -#define IOCT INSN_OCTEON - -#define G1 (T3 \ - ) - -#define G2 (T3 \ - ) - -#define G3 (I4 \ - ) - -/* MIPS DSP ASE support. - NOTE: - 1. MIPS DSP ASE includes 4 accumulators ($ac0 - $ac3). $ac0 is the pair - of original HI and LO. $ac1, $ac2 and $ac3 are new registers, and have - the same structure as $ac0 (HI + LO). For DSP instructions that write or - read accumulators (that may be $ac0), we add WR_a (WR_HILO) or RD_a - (RD_HILO) attributes, such that HILO dependencies are maintained - conservatively. - - 2. For some mul. instructions that use integer registers as destinations - but destroy HI+LO as side-effect, we add WR_HILO to their attributes. - - 3. MIPS DSP ASE includes a new DSP control register, which has 6 fields - (ccond, outflag, EFI, c, scount, pos). Many DSP instructions read or write - certain fields of the DSP control register. For simplicity, we decide not - to track dependencies of these fields. - However, "bposge32" is a branch instruction that depends on the "pos" - field. In order to make sure that GAS does not reorder DSP instructions - that writes the "pos" field and "bposge32", we add DSP_VOLA (INSN_TRAP) - attribute to those instructions that write the "pos" field. */ - -#define WR_a WR_HILO /* Write dsp accumulators (reuse WR_HILO) */ -#define RD_a RD_HILO /* Read dsp accumulators (reuse RD_HILO) */ -#define MOD_a (WR_a|RD_a) -#define DSP_VOLA INSN_TRAP -#define D32 INSN_DSP -#define D33 INSN_DSPR2 -#define D64 INSN_DSP64 - -/* MIPS MT ASE support. */ -#define MT32 INSN_MT - -/* The order of overloaded instructions matters. Label arguments and - register arguments look the same. Instructions that can have either - for arguments must apear in the correct order in this table for the - assembler to pick the right one. In other words, entries with - immediate operands must apear after the same instruction with - registers. - - Because of the lookup algorithm used, entries with the same opcode - name must be contiguous. - - Many instructions are short hand for other instructions (i.e., The - jal instruction is short for jalr ). */ - -const struct mips_opcode mips_builtin_opcodes[] = -{ -/* These instructions appear first so that the disassembler will find - them first. The assemblers uses a hash table based on the - instruction name anyhow. */ -/* name, args, match, mask, pinfo, pinfo2, membership */ -{"pref", "k,o(b)", 0xcc000000, 0xfc000000, RD_b, 0, I4_32|G3 }, -{"prefx", "h,t(b)", 0x4c00000f, 0xfc0007ff, RD_b|RD_t, 0, I4_33 }, -{"nop", "", 0x00000000, 0xffffffff, 0, INSN2_ALIAS, I1 }, /* sll */ -{"ssnop", "", 0x00000040, 0xffffffff, 0, INSN2_ALIAS, I32|N55 }, /* sll */ -{"ehb", "", 0x000000c0, 0xffffffff, 0, INSN2_ALIAS, I33 }, /* sll */ -{"li", "t,j", 0x24000000, 0xffe00000, WR_t, INSN2_ALIAS, I1 }, /* addiu */ -{"li", "t,i", 0x34000000, 0xffe00000, WR_t, INSN2_ALIAS, I1 }, /* ori */ -{"li", "t,I", 0, (int) M_LI, INSN_MACRO, 0, I1 }, -{"move", "d,s", 0, (int) M_MOVE, INSN_MACRO, 0, I1 }, -{"move", "d,s", 0x0000002d, 0xfc1f07ff, WR_d|RD_s, INSN2_ALIAS, I3 },/* daddu */ -{"move", "d,s", 0x00000021, 0xfc1f07ff, WR_d|RD_s, INSN2_ALIAS, I1 },/* addu */ -{"move", "d,s", 0x00000025, 0xfc1f07ff, WR_d|RD_s, INSN2_ALIAS, I1 },/* or */ -{"b", "p", 0x10000000, 0xffff0000, UBD, INSN2_ALIAS, I1 },/* beq 0,0 */ -{"b", "p", 0x04010000, 0xffff0000, UBD, INSN2_ALIAS, I1 },/* bgez 0 */ -{"bal", "p", 0x04110000, 0xffff0000, UBD|WR_31, INSN2_ALIAS, I1 },/* bgezal 0*/ - -{"abs", "d,v", 0, (int) M_ABS, INSN_MACRO, 0, I1 }, -{"abs.s", "D,V", 0x46000005, 0xffff003f, WR_D|RD_S|FP_S, 0, I1 }, -{"abs.d", "D,V", 0x46200005, 0xffff003f, WR_D|RD_S|FP_D, 0, I1 }, -{"abs.ps", "D,V", 0x46c00005, 0xffff003f, WR_D|RD_S|FP_D, 0, I5_33|IL2F }, -{"abs.ps", "D,V", 0x45600005, 0xffff003f, WR_D|RD_S|FP_D, 0, IL2E }, -{"add", "d,v,t", 0x00000020, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, -{"add", "t,r,I", 0, (int) M_ADD_I, INSN_MACRO, 0, I1 }, -{"add", "D,S,T", 0x45c00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2E }, -{"add", "D,S,T", 0x4b40000c, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2F }, -{"add.s", "D,V,T", 0x46000000, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I1 }, -{"add.d", "D,V,T", 0x46200000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I1 }, -{"add.ob", "X,Y,Q", 0x7800000b, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"add.ob", "D,S,T", 0x4ac0000b, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"add.ob", "D,S,T[e]", 0x4800000b, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"add.ob", "D,S,k", 0x4bc0000b, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"add.ps", "D,V,T", 0x46c00000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5_33|IL2F }, -{"add.ps", "D,V,T", 0x45600000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"add.qh", "X,Y,Q", 0x7820000b, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"adda.ob", "Y,Q", 0x78000037, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX|SB1 }, -{"adda.qh", "Y,Q", 0x78200037, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, -{"addi", "t,r,j", 0x20000000, 0xfc000000, WR_t|RD_s, 0, I1 }, -{"addiu", "t,r,j", 0x24000000, 0xfc000000, WR_t|RD_s, 0, I1 }, -{"addl.ob", "Y,Q", 0x78000437, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX|SB1 }, -{"addl.qh", "Y,Q", 0x78200437, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, -{"addr.ps", "D,S,T", 0x46c00018, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, M3D }, -{"addu", "d,v,t", 0x00000021, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, -{"addu", "t,r,I", 0, (int) M_ADDU_I, INSN_MACRO, 0, I1 }, -{"addu", "D,S,T", 0x45800000, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2E }, -{"addu", "D,S,T", 0x4b00000c, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2F }, -{"alni.ob", "X,Y,Z,O", 0x78000018, 0xff00003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"alni.ob", "D,S,T,%", 0x48000018, 0xff00003f, WR_D|RD_S|RD_T, 0, N54 }, -{"alni.qh", "X,Y,Z,O", 0x7800001a, 0xff00003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"alnv.ps", "D,V,T,s", 0x4c00001e, 0xfc00003f, WR_D|RD_S|RD_T|FP_D, 0, I5_33 }, -{"alnv.ob", "X,Y,Z,s", 0x78000019, 0xfc00003f, WR_D|RD_S|RD_T|RD_s|FP_D, 0, MX|SB1 }, -{"alnv.qh", "X,Y,Z,s", 0x7800001b, 0xfc00003f, WR_D|RD_S|RD_T|RD_s|FP_D, 0, MX }, -{"and", "d,v,t", 0x00000024, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, -{"and", "t,r,I", 0, (int) M_AND_I, INSN_MACRO, 0, I1 }, -{"and", "D,S,T", 0x47c00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"and", "D,S,T", 0x4bc00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"and.ob", "X,Y,Q", 0x7800000c, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"and.ob", "D,S,T", 0x4ac0000c, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"and.ob", "D,S,T[e]", 0x4800000c, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"and.ob", "D,S,k", 0x4bc0000c, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"and.qh", "X,Y,Q", 0x7820000c, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"andi", "t,r,i", 0x30000000, 0xfc000000, WR_t|RD_s, 0, I1 }, -/* b is at the top of the table. */ -/* bal is at the top of the table. */ -/* bc0[tf]l? are at the bottom of the table. */ -{"bc1any2f", "N,p", 0x45200000, 0xffe30000, CBD|RD_CC|FP_S, 0, M3D }, -{"bc1any2t", "N,p", 0x45210000, 0xffe30000, CBD|RD_CC|FP_S, 0, M3D }, -{"bc1any4f", "N,p", 0x45400000, 0xffe30000, CBD|RD_CC|FP_S, 0, M3D }, -{"bc1any4t", "N,p", 0x45410000, 0xffe30000, CBD|RD_CC|FP_S, 0, M3D }, -{"bc1f", "p", 0x45000000, 0xffff0000, CBD|RD_CC|FP_S, 0, I1 }, -{"bc1f", "N,p", 0x45000000, 0xffe30000, CBD|RD_CC|FP_S, 0, I4_32 }, -{"bc1fl", "p", 0x45020000, 0xffff0000, CBL|RD_CC|FP_S, 0, I2|T3 }, -{"bc1fl", "N,p", 0x45020000, 0xffe30000, CBL|RD_CC|FP_S, 0, I4_32 }, -{"bc1t", "p", 0x45010000, 0xffff0000, CBD|RD_CC|FP_S, 0, I1 }, -{"bc1t", "N,p", 0x45010000, 0xffe30000, CBD|RD_CC|FP_S, 0, I4_32 }, -{"bc1tl", "p", 0x45030000, 0xffff0000, CBL|RD_CC|FP_S, 0, I2|T3 }, -{"bc1tl", "N,p", 0x45030000, 0xffe30000, CBL|RD_CC|FP_S, 0, I4_32 }, -/* bc2* are at the bottom of the table. */ -/* bc3* are at the bottom of the table. */ -{"beqz", "s,p", 0x10000000, 0xfc1f0000, CBD|RD_s, 0, I1 }, -{"beqzl", "s,p", 0x50000000, 0xfc1f0000, CBL|RD_s, 0, I2|T3 }, -{"beq", "s,t,p", 0x10000000, 0xfc000000, CBD|RD_s|RD_t, 0, I1 }, -{"beq", "s,I,p", 0, (int) M_BEQ_I, INSN_MACRO, 0, I1 }, -{"beql", "s,t,p", 0x50000000, 0xfc000000, CBL|RD_s|RD_t, 0, I2|T3 }, -{"beql", "s,I,p", 0, (int) M_BEQL_I, INSN_MACRO, 0, I2|T3 }, -{"bge", "s,t,p", 0, (int) M_BGE, INSN_MACRO, 0, I1 }, -{"bge", "s,I,p", 0, (int) M_BGE_I, INSN_MACRO, 0, I1 }, -{"bgel", "s,t,p", 0, (int) M_BGEL, INSN_MACRO, 0, I2|T3 }, -{"bgel", "s,I,p", 0, (int) M_BGEL_I, INSN_MACRO, 0, I2|T3 }, -{"bgeu", "s,t,p", 0, (int) M_BGEU, INSN_MACRO, 0, I1 }, -{"bgeu", "s,I,p", 0, (int) M_BGEU_I, INSN_MACRO, 0, I1 }, -{"bgeul", "s,t,p", 0, (int) M_BGEUL, INSN_MACRO, 0, I2|T3 }, -{"bgeul", "s,I,p", 0, (int) M_BGEUL_I, INSN_MACRO, 0, I2|T3 }, -{"bgez", "s,p", 0x04010000, 0xfc1f0000, CBD|RD_s, 0, I1 }, -{"bgezl", "s,p", 0x04030000, 0xfc1f0000, CBL|RD_s, 0, I2|T3 }, -{"bgezal", "s,p", 0x04110000, 0xfc1f0000, CBD|RD_s|WR_31, 0, I1 }, -{"bgezall", "s,p", 0x04130000, 0xfc1f0000, CBL|RD_s|WR_31, 0, I2|T3 }, -{"bgt", "s,t,p", 0, (int) M_BGT, INSN_MACRO, 0, I1 }, -{"bgt", "s,I,p", 0, (int) M_BGT_I, INSN_MACRO, 0, I1 }, -{"bgtl", "s,t,p", 0, (int) M_BGTL, INSN_MACRO, 0, I2|T3 }, -{"bgtl", "s,I,p", 0, (int) M_BGTL_I, INSN_MACRO, 0, I2|T3 }, -{"bgtu", "s,t,p", 0, (int) M_BGTU, INSN_MACRO, 0, I1 }, -{"bgtu", "s,I,p", 0, (int) M_BGTU_I, INSN_MACRO, 0, I1 }, -{"bgtul", "s,t,p", 0, (int) M_BGTUL, INSN_MACRO, 0, I2|T3 }, -{"bgtul", "s,I,p", 0, (int) M_BGTUL_I, INSN_MACRO, 0, I2|T3 }, -{"bgtz", "s,p", 0x1c000000, 0xfc1f0000, CBD|RD_s, 0, I1 }, -{"bgtzl", "s,p", 0x5c000000, 0xfc1f0000, CBL|RD_s, 0, I2|T3 }, -{"ble", "s,t,p", 0, (int) M_BLE, INSN_MACRO, 0, I1 }, -{"ble", "s,I,p", 0, (int) M_BLE_I, INSN_MACRO, 0, I1 }, -{"blel", "s,t,p", 0, (int) M_BLEL, INSN_MACRO, 0, I2|T3 }, -{"blel", "s,I,p", 0, (int) M_BLEL_I, INSN_MACRO, 0, I2|T3 }, -{"bleu", "s,t,p", 0, (int) M_BLEU, INSN_MACRO, 0, I1 }, -{"bleu", "s,I,p", 0, (int) M_BLEU_I, INSN_MACRO, 0, I1 }, -{"bleul", "s,t,p", 0, (int) M_BLEUL, INSN_MACRO, 0, I2|T3 }, -{"bleul", "s,I,p", 0, (int) M_BLEUL_I, INSN_MACRO, 0, I2|T3 }, -{"blez", "s,p", 0x18000000, 0xfc1f0000, CBD|RD_s, 0, I1 }, -{"blezl", "s,p", 0x58000000, 0xfc1f0000, CBL|RD_s, 0, I2|T3 }, -{"blt", "s,t,p", 0, (int) M_BLT, INSN_MACRO, 0, I1 }, -{"blt", "s,I,p", 0, (int) M_BLT_I, INSN_MACRO, 0, I1 }, -{"bltl", "s,t,p", 0, (int) M_BLTL, INSN_MACRO, 0, I2|T3 }, -{"bltl", "s,I,p", 0, (int) M_BLTL_I, INSN_MACRO, 0, I2|T3 }, -{"bltu", "s,t,p", 0, (int) M_BLTU, INSN_MACRO, 0, I1 }, -{"bltu", "s,I,p", 0, (int) M_BLTU_I, INSN_MACRO, 0, I1 }, -{"bltul", "s,t,p", 0, (int) M_BLTUL, INSN_MACRO, 0, I2|T3 }, -{"bltul", "s,I,p", 0, (int) M_BLTUL_I, INSN_MACRO, 0, I2|T3 }, -{"bltz", "s,p", 0x04000000, 0xfc1f0000, CBD|RD_s, 0, I1 }, -{"bltzl", "s,p", 0x04020000, 0xfc1f0000, CBL|RD_s, 0, I2|T3 }, -{"bltzal", "s,p", 0x04100000, 0xfc1f0000, CBD|RD_s|WR_31, 0, I1 }, -{"bltzall", "s,p", 0x04120000, 0xfc1f0000, CBL|RD_s|WR_31, 0, I2|T3 }, -{"bnez", "s,p", 0x14000000, 0xfc1f0000, CBD|RD_s, 0, I1 }, -{"bnezl", "s,p", 0x54000000, 0xfc1f0000, CBL|RD_s, 0, I2|T3 }, -{"bne", "s,t,p", 0x14000000, 0xfc000000, CBD|RD_s|RD_t, 0, I1 }, -{"bne", "s,I,p", 0, (int) M_BNE_I, INSN_MACRO, 0, I1 }, -{"bnel", "s,t,p", 0x54000000, 0xfc000000, CBL|RD_s|RD_t, 0, I2|T3 }, -{"bnel", "s,I,p", 0, (int) M_BNEL_I, INSN_MACRO, 0, I2|T3 }, -{"break", "", 0x0000000d, 0xffffffff, TRAP, 0, I1 }, -{"break", "c", 0x0000000d, 0xfc00ffff, TRAP, 0, I1 }, -{"break", "c,q", 0x0000000d, 0xfc00003f, TRAP, 0, I1 }, -{"c.f.d", "S,T", 0x46200030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.f.d", "M,S,T", 0x46200030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.f.s", "S,T", 0x46000030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.f.s", "M,S,T", 0x46000030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.f.ps", "S,T", 0x46c00030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.f.ps", "S,T", 0x45600030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.f.ps", "M,S,T", 0x46c00030, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.un.d", "S,T", 0x46200031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.un.d", "M,S,T", 0x46200031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.un.s", "S,T", 0x46000031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.un.s", "M,S,T", 0x46000031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.un.ps", "S,T", 0x46c00031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.un.ps", "S,T", 0x45600031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.un.ps", "M,S,T", 0x46c00031, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.eq.d", "S,T", 0x46200032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.eq.d", "M,S,T", 0x46200032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.eq.s", "S,T", 0x46000032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.eq.s", "M,S,T", 0x46000032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.eq.ob", "Y,Q", 0x78000001, 0xfc2007ff, WR_CC|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"c.eq.ob", "S,T", 0x4ac00001, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.eq.ob", "S,T[e]", 0x48000001, 0xfe2007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.eq.ob", "S,k", 0x4bc00001, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.eq.ps", "S,T", 0x46c00032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.eq.ps", "S,T", 0x45600032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.eq.ps", "M,S,T", 0x46c00032, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.eq.qh", "Y,Q", 0x78200001, 0xfc2007ff, WR_CC|RD_S|RD_T|FP_D, 0, MX }, -{"c.ueq.d", "S,T", 0x46200033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.ueq.d", "M,S,T", 0x46200033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.ueq.s", "S,T", 0x46000033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.ueq.s", "M,S,T", 0x46000033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.ueq.ps","S,T", 0x46c00033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.ueq.ps","S,T", 0x45600033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ueq.ps","M,S,T", 0x46c00033, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.olt.d", "S,T", 0x46200034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.olt.d", "M,S,T", 0x46200034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.olt.s", "S,T", 0x46000034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.olt.s", "M,S,T", 0x46000034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.olt.ps","S,T", 0x46c00034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.olt.ps","S,T", 0x45600034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.olt.ps","M,S,T", 0x46c00034, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.ult.d", "S,T", 0x46200035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.ult.d", "M,S,T", 0x46200035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.ult.s", "S,T", 0x46000035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.ult.s", "M,S,T", 0x46000035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.ult.ps","S,T", 0x46c00035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.ult.ps","S,T", 0x45600035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ult.ps","M,S,T", 0x46c00035, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.ole.d", "S,T", 0x46200036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.ole.d", "M,S,T", 0x46200036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.ole.s", "S,T", 0x46000036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.ole.s", "M,S,T", 0x46000036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.ole.ps","S,T", 0x46c00036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.ole.ps","S,T", 0x45600036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ole.ps","M,S,T", 0x46c00036, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.ule.d", "S,T", 0x46200037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.ule.d", "M,S,T", 0x46200037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.ule.s", "S,T", 0x46000037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.ule.s", "M,S,T", 0x46000037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.ule.ps","S,T", 0x46c00037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.ule.ps","S,T", 0x45600037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ule.ps","M,S,T", 0x46c00037, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.sf.d", "S,T", 0x46200038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.sf.d", "M,S,T", 0x46200038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.sf.s", "S,T", 0x46000038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.sf.s", "M,S,T", 0x46000038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.sf.ps", "S,T", 0x46c00038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.sf.ps", "S,T", 0x45600038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.sf.ps", "M,S,T", 0x46c00038, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.ngle.d","S,T", 0x46200039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.ngle.d","M,S,T", 0x46200039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.ngle.s","S,T", 0x46000039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.ngle.s","M,S,T", 0x46000039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.ngle.ps","S,T", 0x46c00039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.ngle.ps","S,T", 0x45600039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ngle.ps","M,S,T", 0x46c00039, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.seq.d", "S,T", 0x4620003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.seq.d", "M,S,T", 0x4620003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.seq.s", "S,T", 0x4600003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.seq.s", "M,S,T", 0x4600003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.seq.ps","S,T", 0x46c0003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.seq.ps","S,T", 0x4560003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.seq.ps","M,S,T", 0x46c0003a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.ngl.d", "S,T", 0x4620003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.ngl.d", "M,S,T", 0x4620003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.ngl.s", "S,T", 0x4600003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.ngl.s", "M,S,T", 0x4600003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.ngl.ps","S,T", 0x46c0003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.ngl.ps","S,T", 0x4560003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ngl.ps","M,S,T", 0x46c0003b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.lt.d", "S,T", 0x4620003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.lt.d", "M,S,T", 0x4620003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.lt.s", "S,T", 0x4600003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.lt.s", "M,S,T", 0x4600003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.lt.ob", "Y,Q", 0x78000004, 0xfc2007ff, WR_CC|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"c.lt.ob", "S,T", 0x4ac00004, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.lt.ob", "S,T[e]", 0x48000004, 0xfe2007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.lt.ob", "S,k", 0x4bc00004, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.lt.ps", "S,T", 0x46c0003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.lt.ps", "S,T", 0x4560003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.lt.ps", "M,S,T", 0x46c0003c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.lt.qh", "Y,Q", 0x78200004, 0xfc2007ff, WR_CC|RD_S|RD_T|FP_D, 0, MX }, -{"c.nge.d", "S,T", 0x4620003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.nge.d", "M,S,T", 0x4620003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.nge.s", "S,T", 0x4600003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.nge.s", "M,S,T", 0x4600003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.nge.ps","S,T", 0x46c0003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.nge.ps","S,T", 0x4560003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.nge.ps","M,S,T", 0x46c0003d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.le.d", "S,T", 0x4620003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.le.d", "M,S,T", 0x4620003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.le.s", "S,T", 0x4600003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.le.s", "M,S,T", 0x4600003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.le.ob", "Y,Q", 0x78000005, 0xfc2007ff, WR_CC|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"c.le.ob", "S,T", 0x4ac00005, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.le.ob", "S,T[e]", 0x48000005, 0xfe2007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.le.ob", "S,k", 0x4bc00005, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"c.le.ps", "S,T", 0x46c0003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.le.ps", "S,T", 0x4560003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.le.ps", "M,S,T", 0x46c0003e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"c.le.qh", "Y,Q", 0x78200005, 0xfc2007ff, WR_CC|RD_S|RD_T|FP_D, 0, MX }, -{"c.ngt.d", "S,T", 0x4620003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I1 }, -{"c.ngt.d", "M,S,T", 0x4620003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I4_32 }, -{"c.ngt.s", "S,T", 0x4600003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_S, 0, I1 }, -{"c.ngt.s", "M,S,T", 0x4600003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, I4_32 }, -{"c.ngt.ps","S,T", 0x46c0003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33|IL2F }, -{"c.ngt.ps","S,T", 0x4560003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ngt.ps","M,S,T", 0x46c0003f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, I5_33 }, -{"cabs.eq.d", "M,S,T", 0x46200072, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.eq.ps", "M,S,T", 0x46c00072, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.eq.s", "M,S,T", 0x46000072, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.f.d", "M,S,T", 0x46200070, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.f.ps", "M,S,T", 0x46c00070, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.f.s", "M,S,T", 0x46000070, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.le.d", "M,S,T", 0x4620007e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.le.ps", "M,S,T", 0x46c0007e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.le.s", "M,S,T", 0x4600007e, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.lt.d", "M,S,T", 0x4620007c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.lt.ps", "M,S,T", 0x46c0007c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.lt.s", "M,S,T", 0x4600007c, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.nge.d", "M,S,T", 0x4620007d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.nge.ps","M,S,T", 0x46c0007d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.nge.s", "M,S,T", 0x4600007d, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.ngl.d", "M,S,T", 0x4620007b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ngl.ps","M,S,T", 0x46c0007b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ngl.s", "M,S,T", 0x4600007b, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.ngle.d","M,S,T", 0x46200079, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ngle.ps","M,S,T",0x46c00079, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ngle.s","M,S,T", 0x46000079, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.ngt.d", "M,S,T", 0x4620007f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ngt.ps","M,S,T", 0x46c0007f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ngt.s", "M,S,T", 0x4600007f, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.ole.d", "M,S,T", 0x46200076, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ole.ps","M,S,T", 0x46c00076, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ole.s", "M,S,T", 0x46000076, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.olt.d", "M,S,T", 0x46200074, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.olt.ps","M,S,T", 0x46c00074, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.olt.s", "M,S,T", 0x46000074, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.seq.d", "M,S,T", 0x4620007a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.seq.ps","M,S,T", 0x46c0007a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.seq.s", "M,S,T", 0x4600007a, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.sf.d", "M,S,T", 0x46200078, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.sf.ps", "M,S,T", 0x46c00078, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.sf.s", "M,S,T", 0x46000078, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.ueq.d", "M,S,T", 0x46200073, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ueq.ps","M,S,T", 0x46c00073, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ueq.s", "M,S,T", 0x46000073, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.ule.d", "M,S,T", 0x46200077, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ule.ps","M,S,T", 0x46c00077, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ule.s", "M,S,T", 0x46000077, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.ult.d", "M,S,T", 0x46200075, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ult.ps","M,S,T", 0x46c00075, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.ult.s", "M,S,T", 0x46000075, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -{"cabs.un.d", "M,S,T", 0x46200071, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.un.ps", "M,S,T", 0x46c00071, 0xffe000ff, RD_S|RD_T|WR_CC|FP_D, 0, M3D }, -{"cabs.un.s", "M,S,T", 0x46000071, 0xffe000ff, RD_S|RD_T|WR_CC|FP_S, 0, M3D }, -/* CW4010 instructions which are aliases for the cache instruction. */ -{"flushi", "", 0xbc010000, 0xffffffff, 0, 0, L1 }, -{"flushd", "", 0xbc020000, 0xffffffff, 0, 0, L1 }, -{"flushid", "", 0xbc030000, 0xffffffff, 0, 0, L1 }, -{"wb", "o(b)", 0xbc040000, 0xfc1f0000, SM|RD_b, 0, L1 }, -{"cache", "k,o(b)", 0xbc000000, 0xfc000000, RD_b, 0, I3_32|T3}, -{"cache", "k,A(b)", 0, (int) M_CACHE_AB, INSN_MACRO, 0, I3_32|T3}, -{"ceil.l.d", "D,S", 0x4620000a, 0xffff003f, WR_D|RD_S|FP_D, 0, I3_33 }, -{"ceil.l.s", "D,S", 0x4600000a, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3_33 }, -{"ceil.w.d", "D,S", 0x4620000e, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, -{"ceil.w.s", "D,S", 0x4600000e, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 }, -{"cfc0", "t,G", 0x40400000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I1 }, -{"cfc1", "t,G", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, 0, I1 }, -{"cfc1", "t,S", 0x44400000, 0xffe007ff, LCD|WR_t|RD_C1|FP_S, 0, I1 }, -/* cfc2 is at the bottom of the table. */ -/* cfc3 is at the bottom of the table. */ -{"cftc1", "d,E", 0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0, MT32 }, -{"cftc1", "d,T", 0x41000023, 0xffe007ff, TRAP|LCD|WR_d|RD_C1|FP_S, 0, MT32 }, -{"cftc2", "d,E", 0x41000025, 0xffe007ff, TRAP|LCD|WR_d|RD_C2, 0, MT32 }, -{"clo", "U,s", 0x70000021, 0xfc0007ff, WR_d|WR_t|RD_s, 0, I32|N55 }, -{"clz", "U,s", 0x70000020, 0xfc0007ff, WR_d|WR_t|RD_s, 0, I32|N55 }, -{"ctc0", "t,G", 0x40c00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 }, -{"ctc1", "t,G", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, 0, I1 }, -{"ctc1", "t,S", 0x44c00000, 0xffe007ff, COD|RD_t|WR_CC|FP_S, 0, I1 }, -/* ctc2 is at the bottom of the table. */ -/* ctc3 is at the bottom of the table. */ -{"cttc1", "t,g", 0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0, MT32 }, -{"cttc1", "t,S", 0x41800023, 0xffe007ff, TRAP|COD|RD_t|WR_CC|FP_S, 0, MT32 }, -{"cttc2", "t,g", 0x41800025, 0xffe007ff, TRAP|COD|RD_t|WR_CC, 0, MT32 }, -{"cvt.d.l", "D,S", 0x46a00021, 0xffff003f, WR_D|RD_S|FP_D, 0, I3_33 }, -{"cvt.d.s", "D,S", 0x46000021, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I1 }, -{"cvt.d.w", "D,S", 0x46800021, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I1 }, -{"cvt.l.d", "D,S", 0x46200025, 0xffff003f, WR_D|RD_S|FP_D, 0, I3_33 }, -{"cvt.l.s", "D,S", 0x46000025, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3_33 }, -{"cvt.s.l", "D,S", 0x46a00020, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3_33 }, -{"cvt.s.d", "D,S", 0x46200020, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I1 }, -{"cvt.s.w", "D,S", 0x46800020, 0xffff003f, WR_D|RD_S|FP_S, 0, I1 }, -{"cvt.s.pl","D,S", 0x46c00028, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I5_33 }, -{"cvt.s.pu","D,S", 0x46c00020, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I5_33 }, -{"cvt.w.d", "D,S", 0x46200024, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I1 }, -{"cvt.w.s", "D,S", 0x46000024, 0xffff003f, WR_D|RD_S|FP_S, 0, I1 }, -{"cvt.ps.pw", "D,S", 0x46800026, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, M3D }, -{"cvt.ps.s","D,V,T", 0x46000026, 0xffe0003f, WR_D|RD_S|RD_T|FP_S|FP_D, 0, I5_33 }, -{"cvt.pw.ps", "D,S", 0x46c00024, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, M3D }, -{"dabs", "d,v", 0, (int) M_DABS, INSN_MACRO, 0, I3 }, -{"dadd", "d,v,t", 0x0000002c, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I3 }, -{"dadd", "t,r,I", 0, (int) M_DADD_I, INSN_MACRO, 0, I3 }, -{"dadd", "D,S,T", 0x45e00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"dadd", "D,S,T", 0x4b60000c, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"daddi", "t,r,j", 0x60000000, 0xfc000000, WR_t|RD_s, 0, I3 }, -{"daddiu", "t,r,j", 0x64000000, 0xfc000000, WR_t|RD_s, 0, I3 }, -{"daddu", "d,v,t", 0x0000002d, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I3 }, -{"daddu", "t,r,I", 0, (int) M_DADDU_I, INSN_MACRO, 0, I3 }, -{"dbreak", "", 0x7000003f, 0xffffffff, 0, 0, N5 }, -{"dclo", "U,s", 0x70000025, 0xfc0007ff, RD_s|WR_d|WR_t, 0, I64|N55 }, -{"dclz", "U,s", 0x70000024, 0xfc0007ff, RD_s|WR_d|WR_t, 0, I64|N55 }, -/* dctr and dctw are used on the r5000. */ -{"dctr", "o(b)", 0xbc050000, 0xfc1f0000, RD_b, 0, I3 }, -{"dctw", "o(b)", 0xbc090000, 0xfc1f0000, RD_b, 0, I3 }, -{"deret", "", 0x4200001f, 0xffffffff, 0, 0, I32|G2 }, -{"dext", "t,r,I,+I", 0, (int) M_DEXT, INSN_MACRO, 0, I65 }, -{"dext", "t,r,+A,+C", 0x7c000003, 0xfc00003f, WR_t|RD_s, 0, I65 }, -{"dextm", "t,r,+A,+G", 0x7c000001, 0xfc00003f, WR_t|RD_s, 0, I65 }, -{"dextu", "t,r,+E,+H", 0x7c000002, 0xfc00003f, WR_t|RD_s, 0, I65 }, -/* For ddiv, see the comments about div. */ -{"ddiv", "z,s,t", 0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I3 }, -{"ddiv", "d,v,t", 0, (int) M_DDIV_3, INSN_MACRO, 0, I3 }, -{"ddiv", "d,v,I", 0, (int) M_DDIV_3I, INSN_MACRO, 0, I3 }, -/* For ddivu, see the comments about div. */ -{"ddivu", "z,s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I3 }, -{"ddivu", "d,v,t", 0, (int) M_DDIVU_3, INSN_MACRO, 0, I3 }, -{"ddivu", "d,v,I", 0, (int) M_DDIVU_3I, INSN_MACRO, 0, I3 }, -{"di", "", 0x41606000, 0xffffffff, WR_t|WR_C0, 0, I33 }, -{"di", "t", 0x41606000, 0xffe0ffff, WR_t|WR_C0, 0, I33 }, -{"dins", "t,r,I,+I", 0, (int) M_DINS, INSN_MACRO, 0, I65 }, -{"dins", "t,r,+A,+B", 0x7c000007, 0xfc00003f, WR_t|RD_s, 0, I65 }, -{"dinsm", "t,r,+A,+F", 0x7c000005, 0xfc00003f, WR_t|RD_s, 0, I65 }, -{"dinsu", "t,r,+E,+F", 0x7c000006, 0xfc00003f, WR_t|RD_s, 0, I65 }, -/* The MIPS assembler treats the div opcode with two operands as - though the first operand appeared twice (the first operand is both - a source and a destination). To get the div machine instruction, - you must use an explicit destination of $0. */ -{"div", "z,s,t", 0x0000001a, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I1 }, -{"div", "z,t", 0x0000001a, 0xffe0ffff, RD_s|RD_t|WR_HILO, 0, I1 }, -{"div", "d,v,t", 0, (int) M_DIV_3, INSN_MACRO, 0, I1 }, -{"div", "d,v,I", 0, (int) M_DIV_3I, INSN_MACRO, 0, I1 }, -{"div.d", "D,V,T", 0x46200003, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I1 }, -{"div.s", "D,V,T", 0x46000003, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I1 }, -{"div.ps", "D,V,T", 0x46c00003, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, SB1 }, -/* For divu, see the comments about div. */ -{"divu", "z,s,t", 0x0000001b, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I1 }, -{"divu", "z,t", 0x0000001b, 0xffe0ffff, RD_s|RD_t|WR_HILO, 0, I1 }, -{"divu", "d,v,t", 0, (int) M_DIVU_3, INSN_MACRO, 0, I1 }, -{"divu", "d,v,I", 0, (int) M_DIVU_3I, INSN_MACRO, 0, I1 }, -{"dla", "t,A(b)", 0, (int) M_DLA_AB, INSN_MACRO, 0, I3 }, -{"dlca", "t,A(b)", 0, (int) M_DLCA_AB, INSN_MACRO, 0, I3 }, -{"dli", "t,j", 0x24000000, 0xffe00000, WR_t, 0, I3 }, /* addiu */ -{"dli", "t,i", 0x34000000, 0xffe00000, WR_t, 0, I3 }, /* ori */ -{"dli", "t,I", 0, (int) M_DLI, INSN_MACRO, 0, I3 }, -{"dmacc", "d,s,t", 0x00000029, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d, 0, N412 }, -{"dmacchi", "d,s,t", 0x00000229, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d, 0, N412 }, -{"dmacchis", "d,s,t", 0x00000629, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d, 0, N412 }, -{"dmacchiu", "d,s,t", 0x00000269, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d, 0, N412 }, -{"dmacchius", "d,s,t", 0x00000669, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d, 0, N412 }, -{"dmaccs", "d,s,t", 0x00000429, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d, 0, N412 }, -{"dmaccu", "d,s,t", 0x00000069, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d, 0, N412 }, -{"dmaccus", "d,s,t", 0x00000469, 0xfc0007ff, RD_s|RD_t|WR_LO|WR_d, 0, N412 }, -{"dmadd16", "s,t", 0x00000029, 0xfc00ffff, RD_s|RD_t|MOD_LO, 0, N411 }, -{"dmfc0", "t,G", 0x40200000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I3 }, -{"dmfc0", "t,+D", 0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I64 }, -{"dmfc0", "t,G,H", 0x40200000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I64 }, -{"dmt", "", 0x41600bc1, 0xffffffff, TRAP, 0, MT32 }, -{"dmt", "t", 0x41600bc1, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, -{"dmtc0", "t,G", 0x40a00000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, 0, I3 }, -{"dmtc0", "t,+D", 0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I64 }, -{"dmtc0", "t,G,H", 0x40a00000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I64 }, -{"dmfc1", "t,S", 0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I3 }, -{"dmfc1", "t,G", 0x44200000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I3 }, -{"dmtc1", "t,S", 0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I3 }, -{"dmtc1", "t,G", 0x44a00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I3 }, -/* dmfc2 is at the bottom of the table. */ -/* dmtc2 is at the bottom of the table. */ -/* dmfc3 is at the bottom of the table. */ -/* dmtc3 is at the bottom of the table. */ -{"dmul", "d,v,t", 0, (int) M_DMUL, INSN_MACRO, 0, I3 }, -{"dmul", "d,v,I", 0, (int) M_DMUL_I, INSN_MACRO, 0, I3 }, -{"dmulo", "d,v,t", 0, (int) M_DMULO, INSN_MACRO, 0, I3 }, -{"dmulo", "d,v,I", 0, (int) M_DMULO_I, INSN_MACRO, 0, I3 }, -{"dmulou", "d,v,t", 0, (int) M_DMULOU, INSN_MACRO, 0, I3 }, -{"dmulou", "d,v,I", 0, (int) M_DMULOU_I, INSN_MACRO, 0, I3 }, -{"dmult", "s,t", 0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I3 }, -{"dmultu", "s,t", 0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I3 }, -{"dneg", "d,w", 0x0000002e, 0xffe007ff, WR_d|RD_t, 0, I3 }, /* dsub 0 */ -{"dnegu", "d,w", 0x0000002f, 0xffe007ff, WR_d|RD_t, 0, I3 }, /* dsubu 0*/ -{"drem", "z,s,t", 0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I3 }, -{"drem", "d,v,t", 3, (int) M_DREM_3, INSN_MACRO, 0, I3 }, -{"drem", "d,v,I", 3, (int) M_DREM_3I, INSN_MACRO, 0, I3 }, -{"dremu", "z,s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I3 }, -{"dremu", "d,v,t", 3, (int) M_DREMU_3, INSN_MACRO, 0, I3 }, -{"dremu", "d,v,I", 3, (int) M_DREMU_3I, INSN_MACRO, 0, I3 }, -{"dret", "", 0x7000003e, 0xffffffff, 0, 0, N5 }, -{"drol", "d,v,t", 0, (int) M_DROL, INSN_MACRO, 0, I3 }, -{"drol", "d,v,I", 0, (int) M_DROL_I, INSN_MACRO, 0, I3 }, -{"dror", "d,v,t", 0, (int) M_DROR, INSN_MACRO, 0, I3 }, -{"dror", "d,v,I", 0, (int) M_DROR_I, INSN_MACRO, 0, I3 }, -{"dror", "d,w,<", 0x0020003a, 0xffe0003f, WR_d|RD_t, 0, N5|I65 }, -{"drorv", "d,t,s", 0x00000056, 0xfc0007ff, RD_t|RD_s|WR_d, 0, N5|I65 }, -{"dror32", "d,w,<", 0x0020003e, 0xffe0003f, WR_d|RD_t, 0, N5|I65 }, -{"drotl", "d,v,t", 0, (int) M_DROL, INSN_MACRO, 0, I65 }, -{"drotl", "d,v,I", 0, (int) M_DROL_I, INSN_MACRO, 0, I65 }, -{"drotr", "d,v,t", 0, (int) M_DROR, INSN_MACRO, 0, I65 }, -{"drotr", "d,v,I", 0, (int) M_DROR_I, INSN_MACRO, 0, I65 }, -{"drotrv", "d,t,s", 0x00000056, 0xfc0007ff, RD_t|RD_s|WR_d, 0, I65 }, -{"drotr32", "d,w,<", 0x0020003e, 0xffe0003f, WR_d|RD_t, 0, I65 }, -{"dsbh", "d,w", 0x7c0000a4, 0xffe007ff, WR_d|RD_t, 0, I65 }, -{"dshd", "d,w", 0x7c000164, 0xffe007ff, WR_d|RD_t, 0, I65 }, -{"dsllv", "d,t,s", 0x00000014, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I3 }, -{"dsll32", "d,w,<", 0x0000003c, 0xffe0003f, WR_d|RD_t, 0, I3 }, -{"dsll", "d,w,s", 0x00000014, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I3 }, /* dsllv */ -{"dsll", "d,w,>", 0x0000003c, 0xffe0003f, WR_d|RD_t, 0, I3 }, /* dsll32 */ -{"dsll", "d,w,<", 0x00000038, 0xffe0003f, WR_d|RD_t, 0, I3 }, -{"dsll", "D,S,T", 0x45a00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"dsll", "D,S,T", 0x4b20000e, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"dsrav", "d,t,s", 0x00000017, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I3 }, -{"dsra32", "d,w,<", 0x0000003f, 0xffe0003f, WR_d|RD_t, 0, I3 }, -{"dsra", "d,w,s", 0x00000017, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I3 }, /* dsrav */ -{"dsra", "d,w,>", 0x0000003f, 0xffe0003f, WR_d|RD_t, 0, I3 }, /* dsra32 */ -{"dsra", "d,w,<", 0x0000003b, 0xffe0003f, WR_d|RD_t, 0, I3 }, -{"dsra", "D,S,T", 0x45e00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"dsra", "D,S,T", 0x4b60000f, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"dsrlv", "d,t,s", 0x00000016, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I3 }, -{"dsrl32", "d,w,<", 0x0000003e, 0xffe0003f, WR_d|RD_t, 0, I3 }, -{"dsrl", "d,w,s", 0x00000016, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I3 }, /* dsrlv */ -{"dsrl", "d,w,>", 0x0000003e, 0xffe0003f, WR_d|RD_t, 0, I3 }, /* dsrl32 */ -{"dsrl", "d,w,<", 0x0000003a, 0xffe0003f, WR_d|RD_t, 0, I3 }, -{"dsrl", "D,S,T", 0x45a00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"dsrl", "D,S,T", 0x4b20000f, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"dsub", "d,v,t", 0x0000002e, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I3 }, -{"dsub", "d,v,I", 0, (int) M_DSUB_I, INSN_MACRO, 0, I3 }, -{"dsub", "D,S,T", 0x45e00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"dsub", "D,S,T", 0x4b60000d, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"dsubu", "d,v,t", 0x0000002f, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I3 }, -{"dsubu", "d,v,I", 0, (int) M_DSUBU_I, INSN_MACRO, 0, I3 }, -{"dvpe", "", 0x41600001, 0xffffffff, TRAP, 0, MT32 }, -{"dvpe", "t", 0x41600001, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, -{"ei", "", 0x41606020, 0xffffffff, WR_t|WR_C0, 0, I33 }, -{"ei", "t", 0x41606020, 0xffe0ffff, WR_t|WR_C0, 0, I33 }, -{"emt", "", 0x41600be1, 0xffffffff, TRAP, 0, MT32 }, -{"emt", "t", 0x41600be1, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, -{"eret", "", 0x42000018, 0xffffffff, 0, 0, I3_32 }, -{"evpe", "", 0x41600021, 0xffffffff, TRAP, 0, MT32 }, -{"evpe", "t", 0x41600021, 0xffe0ffff, TRAP|WR_t, 0, MT32 }, -{"ext", "t,r,+A,+C", 0x7c000000, 0xfc00003f, WR_t|RD_s, 0, I33 }, -{"floor.l.d", "D,S", 0x4620000b, 0xffff003f, WR_D|RD_S|FP_D, 0, I3_33 }, -{"floor.l.s", "D,S", 0x4600000b, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3_33 }, -{"floor.w.d", "D,S", 0x4620000f, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, -{"floor.w.s", "D,S", 0x4600000f, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 }, -{"hibernate","", 0x42000023, 0xffffffff, 0, 0, V1 }, -{"ins", "t,r,+A,+B", 0x7c000004, 0xfc00003f, WR_t|RD_s, 0, I33 }, -{"jr", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 }, -/* jr.hb is officially MIPS{32,64}R2, but it works on R1 as jr with - the same hazard barrier effect. */ -{"jr.hb", "s", 0x00000408, 0xfc1fffff, UBD|RD_s, 0, I32 }, -{"j", "s", 0x00000008, 0xfc1fffff, UBD|RD_s, 0, I1 }, /* jr */ -/* SVR4 PIC code requires special handling for j, so it must be a - macro. */ -{"j", "a", 0, (int) M_J_A, INSN_MACRO, 0, I1 }, -/* This form of j is used by the disassembler and internally by the - assembler, but will never match user input (because the line above - will match first). */ -{"j", "a", 0x08000000, 0xfc000000, UBD, 0, I1 }, -{"jalr", "s", 0x0000f809, 0xfc1fffff, UBD|RD_s|WR_d, 0, I1 }, -{"jalr", "d,s", 0x00000009, 0xfc1f07ff, UBD|RD_s|WR_d, 0, I1 }, -/* jalr.hb is officially MIPS{32,64}R2, but it works on R1 as jalr - with the same hazard barrier effect. */ -{"jalr.hb", "s", 0x0000fc09, 0xfc1fffff, UBD|RD_s|WR_d, 0, I32 }, -{"jalr.hb", "d,s", 0x00000409, 0xfc1f07ff, UBD|RD_s|WR_d, 0, I32 }, -/* SVR4 PIC code requires special handling for jal, so it must be a - macro. */ -{"jal", "d,s", 0, (int) M_JAL_2, INSN_MACRO, 0, I1 }, -{"jal", "s", 0, (int) M_JAL_1, INSN_MACRO, 0, I1 }, -{"jal", "a", 0, (int) M_JAL_A, INSN_MACRO, 0, I1 }, -/* This form of jal is used by the disassembler and internally by the - assembler, but will never match user input (because the line above - will match first). */ -{"jal", "a", 0x0c000000, 0xfc000000, UBD|WR_31, 0, I1 }, -{"jalx", "a", 0x74000000, 0xfc000000, UBD|WR_31, 0, I16 }, -{"la", "t,A(b)", 0, (int) M_LA_AB, INSN_MACRO, 0, I1 }, -{"lb", "t,o(b)", 0x80000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 }, -{"lb", "t,A(b)", 0, (int) M_LB_AB, INSN_MACRO, 0, I1 }, -{"lbu", "t,o(b)", 0x90000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 }, -{"lbu", "t,A(b)", 0, (int) M_LBU_AB, INSN_MACRO, 0, I1 }, -{"lca", "t,A(b)", 0, (int) M_LCA_AB, INSN_MACRO, 0, I1 }, -{"ld", "t,o(b)", 0xdc000000, 0xfc000000, WR_t|RD_b, 0, I3 }, -{"ld", "t,o(b)", 0, (int) M_LD_OB, INSN_MACRO, 0, I1 }, -{"ld", "t,A(b)", 0, (int) M_LD_AB, INSN_MACRO, 0, I1 }, -{"ldc1", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, -{"ldc1", "E,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, -{"ldc1", "T,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, 0, I2 }, -{"ldc1", "E,A(b)", 0, (int) M_LDC1_AB, INSN_MACRO, 0, I2 }, -{"l.d", "T,o(b)", 0xd4000000, 0xfc000000, CLD|RD_b|WR_T|FP_D, 0, I2 }, /* ldc1 */ -{"l.d", "T,o(b)", 0, (int) M_L_DOB, INSN_MACRO, 0, I1 }, -{"l.d", "T,A(b)", 0, (int) M_L_DAB, INSN_MACRO, 0, I1 }, -{"ldc2", "E,o(b)", 0xd8000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I2 }, -{"ldc2", "E,A(b)", 0, (int) M_LDC2_AB, INSN_MACRO, 0, I2 }, -{"ldc3", "E,o(b)", 0xdc000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I2 }, -{"ldc3", "E,A(b)", 0, (int) M_LDC3_AB, INSN_MACRO, 0, I2 }, -{"ldl", "t,o(b)", 0x68000000, 0xfc000000, LDD|WR_t|RD_b, 0, I3 }, -{"ldl", "t,A(b)", 0, (int) M_LDL_AB, INSN_MACRO, 0, I3 }, -{"ldr", "t,o(b)", 0x6c000000, 0xfc000000, LDD|WR_t|RD_b, 0, I3 }, -{"ldr", "t,A(b)", 0, (int) M_LDR_AB, INSN_MACRO, 0, I3 }, -{"ldxc1", "D,t(b)", 0x4c000001, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0, I4_33 }, -{"lh", "t,o(b)", 0x84000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 }, -{"lh", "t,A(b)", 0, (int) M_LH_AB, INSN_MACRO, 0, I1 }, -{"lhu", "t,o(b)", 0x94000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 }, -{"lhu", "t,A(b)", 0, (int) M_LHU_AB, INSN_MACRO, 0, I1 }, -/* li is at the start of the table. */ -{"li.d", "t,F", 0, (int) M_LI_D, INSN_MACRO, 0, I1 }, -{"li.d", "T,L", 0, (int) M_LI_DD, INSN_MACRO, 0, I1 }, -{"li.s", "t,f", 0, (int) M_LI_S, INSN_MACRO, 0, I1 }, -{"li.s", "T,l", 0, (int) M_LI_SS, INSN_MACRO, 0, I1 }, -{"ll", "t,o(b)", 0xc0000000, 0xfc000000, LDD|RD_b|WR_t, 0, I2 }, -{"ll", "t,A(b)", 0, (int) M_LL_AB, INSN_MACRO, 0, I2 }, -{"lld", "t,o(b)", 0xd0000000, 0xfc000000, LDD|RD_b|WR_t, 0, I3 }, -{"lld", "t,A(b)", 0, (int) M_LLD_AB, INSN_MACRO, 0, I3 }, -{"lui", "t,u", 0x3c000000, 0xffe00000, WR_t, 0, I1 }, -{"luxc1", "D,t(b)", 0x4c000005, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_D, 0, I5_33|N55}, -{"lw", "t,o(b)", 0x8c000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 }, -{"lw", "t,A(b)", 0, (int) M_LW_AB, INSN_MACRO, 0, I1 }, -{"lwc0", "E,o(b)", 0xc0000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I1 }, -{"lwc0", "E,A(b)", 0, (int) M_LWC0_AB, INSN_MACRO, 0, I1 }, -{"lwc1", "T,o(b)", 0xc4000000, 0xfc000000, CLD|RD_b|WR_T|FP_S, 0, I1 }, -{"lwc1", "E,o(b)", 0xc4000000, 0xfc000000, CLD|RD_b|WR_T|FP_S, 0, I1 }, -{"lwc1", "T,A(b)", 0, (int) M_LWC1_AB, INSN_MACRO, 0, I1 }, -{"lwc1", "E,A(b)", 0, (int) M_LWC1_AB, INSN_MACRO, 0, I1 }, -{"l.s", "T,o(b)", 0xc4000000, 0xfc000000, CLD|RD_b|WR_T|FP_S, 0, I1 }, /* lwc1 */ -{"l.s", "T,A(b)", 0, (int) M_LWC1_AB, INSN_MACRO, 0, I1 }, -{"lwc2", "E,o(b)", 0xc8000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I1 }, -{"lwc2", "E,A(b)", 0, (int) M_LWC2_AB, INSN_MACRO, 0, I1 }, -{"lwc3", "E,o(b)", 0xcc000000, 0xfc000000, CLD|RD_b|WR_CC, 0, I1 }, -{"lwc3", "E,A(b)", 0, (int) M_LWC3_AB, INSN_MACRO, 0, I1 }, -{"lwl", "t,o(b)", 0x88000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 }, -{"lwl", "t,A(b)", 0, (int) M_LWL_AB, INSN_MACRO, 0, I1 }, -{"lcache", "t,o(b)", 0x88000000, 0xfc000000, LDD|RD_b|WR_t, 0, I2 }, /* same */ -{"lcache", "t,A(b)", 0, (int) M_LWL_AB, INSN_MACRO, 0, I2 }, /* as lwl */ -{"lwr", "t,o(b)", 0x98000000, 0xfc000000, LDD|RD_b|WR_t, 0, I1 }, -{"lwr", "t,A(b)", 0, (int) M_LWR_AB, INSN_MACRO, 0, I1 }, -{"flush", "t,o(b)", 0x98000000, 0xfc000000, LDD|RD_b|WR_t, 0, I2 }, /* same */ -{"flush", "t,A(b)", 0, (int) M_LWR_AB, INSN_MACRO, 0, I2 }, /* as lwr */ -{"fork", "d,s,t", 0x7c000008, 0xfc0007ff, TRAP|WR_d|RD_s|RD_t, 0, MT32 }, -{"lwu", "t,o(b)", 0x9c000000, 0xfc000000, LDD|RD_b|WR_t, 0, I3 }, -{"lwu", "t,A(b)", 0, (int) M_LWU_AB, INSN_MACRO, 0, I3 }, -{"lwxc1", "D,t(b)", 0x4c000000, 0xfc00f83f, LDD|WR_D|RD_t|RD_b|FP_S, 0, I4_33 }, -{"lwxs", "d,t(b)", 0x70000088, 0xfc0007ff, LDD|RD_b|RD_t|WR_d, 0, SMT }, -{"macc", "d,s,t", 0x00000028, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 }, -{"macc", "d,s,t", 0x00000158, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"maccs", "d,s,t", 0x00000428, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 }, -{"macchi", "d,s,t", 0x00000228, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 }, -{"macchi", "d,s,t", 0x00000358, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"macchis", "d,s,t", 0x00000628, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 }, -{"macchiu", "d,s,t", 0x00000268, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 }, -{"macchiu", "d,s,t", 0x00000359, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"macchius","d,s,t", 0x00000668, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 }, -{"maccu", "d,s,t", 0x00000068, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 }, -{"maccu", "d,s,t", 0x00000159, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"maccus", "d,s,t", 0x00000468, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N412 }, -{"mad", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, P3 }, -{"madu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, P3 }, -{"madd.d", "D,R,S,T", 0x4c000021, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I4_33 }, -{"madd.d", "D,S,T", 0x46200018, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"madd.d", "D,S,T", 0x72200018, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"madd.s", "D,R,S,T", 0x4c000020, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, 0, I4_33 }, -{"madd.s", "D,S,T", 0x46000018, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2E }, -{"madd.s", "D,S,T", 0x72000018, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2F }, -{"madd.ps", "D,R,S,T", 0x4c000026, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5_33 }, -{"madd.ps", "D,S,T", 0x45600018, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"madd.ps", "D,S,T", 0x71600018, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"madd", "s,t", 0x0000001c, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, -{"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, -{"madd", "s,t", 0x70000000, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, G1 }, -{"madd", "7,s,t", 0x70000000, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"madd", "d,s,t", 0x70000000, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0, G1 }, -{"maddp", "s,t", 0x70000441, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, SMT }, -{"maddu", "s,t", 0x0000001d, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, -{"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, -{"maddu", "s,t", 0x70000001, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, G1 }, -{"maddu", "7,s,t", 0x70000001, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"maddu", "d,s,t", 0x70000001, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0, G1 }, -{"madd16", "s,t", 0x00000028, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, N411 }, -{"max.ob", "X,Y,Q", 0x78000007, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"max.ob", "D,S,T", 0x4ac00007, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"max.ob", "D,S,T[e]", 0x48000007, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"max.ob", "D,S,k", 0x4bc00007, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"max.qh", "X,Y,Q", 0x78200007, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"mfpc", "t,P", 0x4000c801, 0xffe0ffc1, LCD|WR_t|RD_C0, 0, M1|N5 }, -{"mfps", "t,P", 0x4000c800, 0xffe0ffc1, LCD|WR_t|RD_C0, 0, M1|N5 }, -{"mftacx", "d", 0x41020021, 0xffff07ff, TRAP|WR_d|RD_a, 0, MT32 }, -{"mftacx", "d,*", 0x41020021, 0xfff307ff, TRAP|WR_d|RD_a, 0, MT32 }, -{"mftc0", "d,+t", 0x41000000, 0xffe007ff, TRAP|LCD|WR_d|RD_C0, 0, MT32 }, -{"mftc0", "d,+T", 0x41000000, 0xffe007f8, TRAP|LCD|WR_d|RD_C0, 0, MT32 }, -{"mftc0", "d,E,H", 0x41000000, 0xffe007f8, TRAP|LCD|WR_d|RD_C0, 0, MT32 }, -{"mftc1", "d,T", 0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0, MT32 }, -{"mftc1", "d,E", 0x41000022, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_S, 0, MT32 }, -{"mftc2", "d,E", 0x41000024, 0xffe007ff, TRAP|LCD|WR_d|RD_C2, 0, MT32 }, -{"mftdsp", "d", 0x41100021, 0xffff07ff, TRAP|WR_d, 0, MT32 }, -{"mftgpr", "d,t", 0x41000020, 0xffe007ff, TRAP|WR_d|RD_t, 0, MT32 }, -{"mfthc1", "d,T", 0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0, MT32 }, -{"mfthc1", "d,E", 0x41000032, 0xffe007ff, TRAP|LCD|WR_d|RD_T|FP_D, 0, MT32 }, -{"mfthc2", "d,E", 0x41000034, 0xffe007ff, TRAP|LCD|WR_d|RD_C2, 0, MT32 }, -{"mfthi", "d", 0x41010021, 0xffff07ff, TRAP|WR_d|RD_a, 0, MT32 }, -{"mfthi", "d,*", 0x41010021, 0xfff307ff, TRAP|WR_d|RD_a, 0, MT32 }, -{"mftlo", "d", 0x41000021, 0xffff07ff, TRAP|WR_d|RD_a, 0, MT32 }, -{"mftlo", "d,*", 0x41000021, 0xfff307ff, TRAP|WR_d|RD_a, 0, MT32 }, -{"mftr", "d,t,!,H,$", 0x41000000, 0xffe007c8, TRAP|WR_d, 0, MT32 }, -{"mfc0", "t,G", 0x40000000, 0xffe007ff, LCD|WR_t|RD_C0, 0, I1 }, -{"mfc0", "t,+D", 0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32 }, -{"mfc0", "t,G,H", 0x40000000, 0xffe007f8, LCD|WR_t|RD_C0, 0, I32 }, -{"mfc1", "t,S", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, 0, I1 }, -{"mfc1", "t,G", 0x44000000, 0xffe007ff, LCD|WR_t|RD_S|FP_S, 0, I1 }, -{"mfhc1", "t,S", 0x44600000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I33 }, -{"mfhc1", "t,G", 0x44600000, 0xffe007ff, LCD|WR_t|RD_S|FP_D, 0, I33 }, -/* mfc2 is at the bottom of the table. */ -/* mfhc2 is at the bottom of the table. */ -/* mfc3 is at the bottom of the table. */ -{"mfdr", "t,G", 0x7000003d, 0xffe007ff, LCD|WR_t|RD_C0, 0, N5 }, -{"mfhi", "d", 0x00000010, 0xffff07ff, WR_d|RD_HI, 0, I1 }, -{"mfhi", "d,9", 0x00000010, 0xff9f07ff, WR_d|RD_HI, 0, D32 }, -{"mflo", "d", 0x00000012, 0xffff07ff, WR_d|RD_LO, 0, I1 }, -{"mflo", "d,9", 0x00000012, 0xff9f07ff, WR_d|RD_LO, 0, D32 }, -{"mflhxu", "d", 0x00000052, 0xffff07ff, WR_d|MOD_HILO, 0, SMT }, -{"min.ob", "X,Y,Q", 0x78000006, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"min.ob", "D,S,T", 0x4ac00006, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"min.ob", "D,S,T[e]", 0x48000006, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"min.ob", "D,S,k", 0x4bc00006, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"min.qh", "X,Y,Q", 0x78200006, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"mov.d", "D,S", 0x46200006, 0xffff003f, WR_D|RD_S|FP_D, 0, I1 }, -{"mov.s", "D,S", 0x46000006, 0xffff003f, WR_D|RD_S|FP_S, 0, I1 }, -{"mov.ps", "D,S", 0x46c00006, 0xffff003f, WR_D|RD_S|FP_D, 0, I5_33|IL2F }, -{"mov.ps", "D,S", 0x45600006, 0xffff003f, WR_D|RD_S|FP_D, 0, IL2E }, -{"movf", "d,s,N", 0x00000001, 0xfc0307ff, WR_d|RD_s|RD_CC|FP_S|FP_D, 0, I4_32 }, -{"movf.d", "D,S,N", 0x46200011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I4_32 }, -{"movf.l", "D,S,N", 0x46a00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 }, -{"movf.l", "X,Y,N", 0x46a00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 }, -{"movf.s", "D,S,N", 0x46000011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, 0, I4_32 }, -{"movf.ps", "D,S,N", 0x46c00011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I5_33 }, -{"movn", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4_32|IL2E|IL2F }, -{"movnz", "d,v,t", 0x0000000b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, IL2E|IL2F }, -{"ffc", "d,v", 0x0000000b, 0xfc1f07ff, WR_d|RD_s, 0, L1 }, -{"movn.d", "D,S,t", 0x46200013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I4_32 }, -{"movn.l", "D,S,t", 0x46a00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, MX|SB1 }, -{"movn.l", "X,Y,t", 0x46a00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, MX|SB1 }, -{"movn.s", "D,S,t", 0x46000013, 0xffe0003f, WR_D|RD_S|RD_t|FP_S, 0, I4_32 }, -{"movn.ps", "D,S,t", 0x46c00013, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I5_33 }, -{"movt", "d,s,N", 0x00010001, 0xfc0307ff, WR_d|RD_s|RD_CC|FP_S|FP_D, 0, I4_32 }, -{"movt.d", "D,S,N", 0x46210011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I4_32 }, -{"movt.l", "D,S,N", 0x46a10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 }, -{"movt.l", "X,Y,N", 0x46a10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, MX|SB1 }, -{"movt.s", "D,S,N", 0x46010011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_S, 0, I4_32 }, -{"movt.ps", "D,S,N", 0x46c10011, 0xffe3003f, WR_D|RD_S|RD_CC|FP_D, 0, I5_33 }, -{"movz", "d,v,t", 0x0000000a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I4_32|IL2E|IL2F }, -{"ffs", "d,v", 0x0000000a, 0xfc1f07ff, WR_d|RD_s, 0, L1 }, -{"movz.d", "D,S,t", 0x46200012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I4_32 }, -{"movz.l", "D,S,t", 0x46a00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, MX|SB1 }, -{"movz.l", "X,Y,t", 0x46a00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, MX|SB1 }, -{"movz.s", "D,S,t", 0x46000012, 0xffe0003f, WR_D|RD_S|RD_t|FP_S, 0, I4_32 }, -{"movz.ps", "D,S,t", 0x46c00012, 0xffe0003f, WR_D|RD_S|RD_t|FP_D, 0, I5_33 }, -{"msac", "d,s,t", 0x000001d8, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"msacu", "d,s,t", 0x000001d9, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"msachi", "d,s,t", 0x000003d8, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"msachiu", "d,s,t", 0x000003d9, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -/* move is at the top of the table. */ -{"msgn.qh", "X,Y,Q", 0x78200000, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"msub.d", "D,R,S,T", 0x4c000029, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I4_33 }, -{"msub.d", "D,S,T", 0x46200019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"msub.d", "D,S,T", 0x72200019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"msub.s", "D,R,S,T", 0x4c000028, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, 0, I4_33 }, -{"msub.s", "D,S,T", 0x46000019, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2E }, -{"msub.s", "D,S,T", 0x72000019, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2F }, -{"msub.ps", "D,R,S,T", 0x4c00002e, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5_33 }, -{"msub.ps", "D,S,T", 0x45600019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"msub.ps", "D,S,T", 0x71600019, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"msub", "s,t", 0x0000001e, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, -{"msub", "s,t", 0x70000004, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, -{"msub", "7,s,t", 0x70000004, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"msubu", "s,t", 0x0000001f, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, L1 }, -{"msubu", "s,t", 0x70000005, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, I32|N55 }, -{"msubu", "7,s,t", 0x70000005, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"mtpc", "t,P", 0x4080c801, 0xffe0ffc1, COD|RD_t|WR_C0, 0, M1|N5 }, -{"mtps", "t,P", 0x4080c800, 0xffe0ffc1, COD|RD_t|WR_C0, 0, M1|N5 }, -{"mtc0", "t,G", 0x40800000, 0xffe007ff, COD|RD_t|WR_C0|WR_CC, 0, I1 }, -{"mtc0", "t,+D", 0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I32 }, -{"mtc0", "t,G,H", 0x40800000, 0xffe007f8, COD|RD_t|WR_C0|WR_CC, 0, I32 }, -{"mtc1", "t,S", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, 0, I1 }, -{"mtc1", "t,G", 0x44800000, 0xffe007ff, COD|RD_t|WR_S|FP_S, 0, I1 }, -{"mthc1", "t,S", 0x44e00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I33 }, -{"mthc1", "t,G", 0x44e00000, 0xffe007ff, COD|RD_t|WR_S|FP_D, 0, I33 }, -/* mtc2 is at the bottom of the table. */ -/* mthc2 is at the bottom of the table. */ -/* mtc3 is at the bottom of the table. */ -{"mtdr", "t,G", 0x7080003d, 0xffe007ff, COD|RD_t|WR_C0, 0, N5 }, -{"mthi", "s", 0x00000011, 0xfc1fffff, RD_s|WR_HI, 0, I1 }, -{"mthi", "s,7", 0x00000011, 0xfc1fe7ff, RD_s|WR_HI, 0, D32 }, -{"mtlo", "s", 0x00000013, 0xfc1fffff, RD_s|WR_LO, 0, I1 }, -{"mtlo", "s,7", 0x00000013, 0xfc1fe7ff, RD_s|WR_LO, 0, D32 }, -{"mtlhx", "s", 0x00000053, 0xfc1fffff, RD_s|MOD_HILO, 0, SMT }, -{"mttc0", "t,G", 0x41800000, 0xffe007ff, TRAP|COD|RD_t|WR_C0|WR_CC, 0, MT32 }, -{"mttc0", "t,+D", 0x41800000, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0, MT32 }, -{"mttc0", "t,G,H", 0x41800000, 0xffe007f8, TRAP|COD|RD_t|WR_C0|WR_CC, 0, MT32 }, -{"mttc1", "t,S", 0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0, MT32 }, -{"mttc1", "t,G", 0x41800022, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_S, 0, MT32 }, -{"mttc2", "t,g", 0x41800024, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0, MT32 }, -{"mttacx", "t", 0x41801021, 0xffe0ffff, TRAP|WR_a|RD_t, 0, MT32 }, -{"mttacx", "t,&", 0x41801021, 0xffe09fff, TRAP|WR_a|RD_t, 0, MT32 }, -{"mttdsp", "t", 0x41808021, 0xffe0ffff, TRAP|RD_t, 0, MT32 }, -{"mttgpr", "t,d", 0x41800020, 0xffe007ff, TRAP|WR_d|RD_t, 0, MT32 }, -{"mtthc1", "t,S", 0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0, MT32 }, -{"mtthc1", "t,G", 0x41800032, 0xffe007ff, TRAP|COD|RD_t|WR_S|FP_D, 0, MT32 }, -{"mtthc2", "t,g", 0x41800034, 0xffe007ff, TRAP|COD|RD_t|WR_C2|WR_CC, 0, MT32 }, -{"mtthi", "t", 0x41800821, 0xffe0ffff, TRAP|WR_a|RD_t, 0, MT32 }, -{"mtthi", "t,&", 0x41800821, 0xffe09fff, TRAP|WR_a|RD_t, 0, MT32 }, -{"mttlo", "t", 0x41800021, 0xffe0ffff, TRAP|WR_a|RD_t, 0, MT32 }, -{"mttlo", "t,&", 0x41800021, 0xffe09fff, TRAP|WR_a|RD_t, 0, MT32 }, -{"mttr", "t,d,!,H,$", 0x41800000, 0xffe007c8, TRAP|RD_t, 0, MT32 }, -{"mul.d", "D,V,T", 0x46200002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I1 }, -{"mul.s", "D,V,T", 0x46000002, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I1 }, -{"mul.ob", "X,Y,Q", 0x78000030, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"mul.ob", "D,S,T", 0x4ac00030, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"mul.ob", "D,S,T[e]", 0x48000030, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"mul.ob", "D,S,k", 0x4bc00030, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"mul.ps", "D,V,T", 0x46c00002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5_33|IL2F }, -{"mul.ps", "D,V,T", 0x45600002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"mul.qh", "X,Y,Q", 0x78200030, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"mul", "d,v,t", 0x70000002, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, I32|P3|N55}, -{"mul", "d,s,t", 0x00000058, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N54 }, -{"mul", "d,v,t", 0, (int) M_MUL, INSN_MACRO, 0, I1 }, -{"mul", "d,v,I", 0, (int) M_MUL_I, INSN_MACRO, 0, I1 }, -{"mula.ob", "Y,Q", 0x78000033, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX|SB1 }, -{"mula.ob", "S,T", 0x4ac00033, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"mula.ob", "S,T[e]", 0x48000033, 0xfe2007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"mula.ob", "S,k", 0x4bc00033, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"mula.qh", "Y,Q", 0x78200033, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, -{"mulhi", "d,s,t", 0x00000258, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"mulhiu", "d,s,t", 0x00000259, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"mull.ob", "Y,Q", 0x78000433, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX|SB1 }, -{"mull.ob", "S,T", 0x4ac00433, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"mull.ob", "S,T[e]", 0x48000433, 0xfe2007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"mull.ob", "S,k", 0x4bc00433, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"mull.qh", "Y,Q", 0x78200433, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, -{"mulo", "d,v,t", 0, (int) M_MULO, INSN_MACRO, 0, I1 }, -{"mulo", "d,v,I", 0, (int) M_MULO_I, INSN_MACRO, 0, I1 }, -{"mulou", "d,v,t", 0, (int) M_MULOU, INSN_MACRO, 0, I1 }, -{"mulou", "d,v,I", 0, (int) M_MULOU_I, INSN_MACRO, 0, I1 }, -{"mulr.ps", "D,S,T", 0x46c0001a, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, M3D }, -{"muls", "d,s,t", 0x000000d8, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"mulsu", "d,s,t", 0x000000d9, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"mulshi", "d,s,t", 0x000002d8, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"mulshiu", "d,s,t", 0x000002d9, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"muls.ob", "Y,Q", 0x78000032, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX|SB1 }, -{"muls.ob", "S,T", 0x4ac00032, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"muls.ob", "S,T[e]", 0x48000032, 0xfe2007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"muls.ob", "S,k", 0x4bc00032, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"muls.qh", "Y,Q", 0x78200032, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, -{"mulsl.ob", "Y,Q", 0x78000432, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX|SB1 }, -{"mulsl.ob", "S,T", 0x4ac00432, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"mulsl.ob", "S,T[e]", 0x48000432, 0xfe2007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"mulsl.ob", "S,k", 0x4bc00432, 0xffe007ff, WR_CC|RD_S|RD_T, 0, N54 }, -{"mulsl.qh", "Y,Q", 0x78200432, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, -{"mult", "s,t", 0x00000018, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, I1 }, -{"mult", "7,s,t", 0x00000018, 0xfc00e7ff, WR_a|RD_s|RD_t, 0, D33 }, -{"mult", "d,s,t", 0x00000018, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0, G1 }, -{"multp", "s,t", 0x00000459, 0xfc00ffff, RD_s|RD_t|MOD_HILO, 0, SMT }, -{"multu", "s,t", 0x00000019, 0xfc00ffff, RD_s|RD_t|WR_HILO|IS_M, 0, I1 }, -{"multu", "7,s,t", 0x00000019, 0xfc00e7ff, WR_a|RD_s|RD_t, 0, D33 }, -{"multu", "d,s,t", 0x00000019, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d|IS_M, 0, G1 }, -{"mulu", "d,s,t", 0x00000059, 0xfc0007ff, RD_s|RD_t|WR_HILO|WR_d, 0, N5 }, -{"neg", "d,w", 0x00000022, 0xffe007ff, WR_d|RD_t, 0, I1 }, /* sub 0 */ -{"negu", "d,w", 0x00000023, 0xffe007ff, WR_d|RD_t, 0, I1 }, /* subu 0 */ -{"neg.d", "D,V", 0x46200007, 0xffff003f, WR_D|RD_S|FP_D, 0, I1 }, -{"neg.s", "D,V", 0x46000007, 0xffff003f, WR_D|RD_S|FP_S, 0, I1 }, -{"neg.ps", "D,V", 0x46c00007, 0xffff003f, WR_D|RD_S|FP_D, 0, I5_33|IL2F }, -{"neg.ps", "D,V", 0x45600007, 0xffff003f, WR_D|RD_S|FP_D, 0, IL2E }, -{"nmadd.d", "D,R,S,T", 0x4c000031, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I4_33 }, -{"nmadd.d", "D,S,T", 0x4620001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"nmadd.d", "D,S,T", 0x7220001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"nmadd.s", "D,R,S,T", 0x4c000030, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, 0, I4_33 }, -{"nmadd.s", "D,S,T", 0x4600001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2E }, -{"nmadd.s", "D,S,T", 0x7200001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2F }, -{"nmadd.ps","D,R,S,T", 0x4c000036, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5_33 }, -{"nmadd.ps", "D,S,T", 0x4560001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"nmadd.ps", "D,S,T", 0x7160001a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"nmsub.d", "D,R,S,T", 0x4c000039, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I4_33 }, -{"nmsub.d", "D,S,T", 0x4620001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"nmsub.d", "D,S,T", 0x7220001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"nmsub.s", "D,R,S,T", 0x4c000038, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_S, 0, I4_33 }, -{"nmsub.s", "D,S,T", 0x4600001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2E }, -{"nmsub.s", "D,S,T", 0x7200001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2F }, -{"nmsub.ps","D,R,S,T", 0x4c00003e, 0xfc00003f, RD_R|RD_S|RD_T|WR_D|FP_D, 0, I5_33 }, -{"nmsub.ps", "D,S,T", 0x4560001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"nmsub.ps", "D,S,T", 0x7160001b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -/* nop is at the start of the table. */ -{"nor", "d,v,t", 0x00000027, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, -{"nor", "t,r,I", 0, (int) M_NOR_I, INSN_MACRO, 0, I1 }, -{"nor", "D,S,T", 0x47a00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"nor", "D,S,T", 0x4ba00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"nor.ob", "X,Y,Q", 0x7800000f, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"nor.ob", "D,S,T", 0x4ac0000f, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"nor.ob", "D,S,T[e]", 0x4800000f, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"nor.ob", "D,S,k", 0x4bc0000f, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"nor.qh", "X,Y,Q", 0x7820000f, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"not", "d,v", 0x00000027, 0xfc1f07ff, WR_d|RD_s|RD_t, 0, I1 },/*nor d,s,0*/ -{"or", "d,v,t", 0x00000025, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, -{"or", "t,r,I", 0, (int) M_OR_I, INSN_MACRO, 0, I1 }, -{"or", "D,S,T", 0x45a00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"or", "D,S,T", 0x4b20000c, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"or.ob", "X,Y,Q", 0x7800000e, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"or.ob", "D,S,T", 0x4ac0000e, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"or.ob", "D,S,T[e]", 0x4800000e, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"or.ob", "D,S,k", 0x4bc0000e, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"or.qh", "X,Y,Q", 0x7820000e, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"ori", "t,r,i", 0x34000000, 0xfc000000, WR_t|RD_s, 0, I1 }, -{"pabsdiff.ob", "X,Y,Q",0x78000009, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, SB1 }, -{"pabsdiffc.ob", "Y,Q", 0x78000035, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, SB1 }, -{"pavg.ob", "X,Y,Q", 0x78000008, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, SB1 }, -{"pickf.ob", "X,Y,Q", 0x78000002, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"pickf.ob", "D,S,T", 0x4ac00002, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"pickf.ob", "D,S,T[e]",0x48000002, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"pickf.ob", "D,S,k", 0x4bc00002, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"pickf.qh", "X,Y,Q", 0x78200002, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"pickt.ob", "X,Y,Q", 0x78000003, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"pickt.ob", "D,S,T", 0x4ac00003, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"pickt.ob", "D,S,T[e]",0x48000003, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"pickt.ob", "D,S,k", 0x4bc00003, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"pickt.qh", "X,Y,Q", 0x78200003, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"pll.ps", "D,V,T", 0x46c0002c, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5_33 }, -{"plu.ps", "D,V,T", 0x46c0002d, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5_33 }, - /* pref and prefx are at the start of the table. */ -{"pul.ps", "D,V,T", 0x46c0002e, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5_33 }, -{"puu.ps", "D,V,T", 0x46c0002f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5_33 }, -{"pperm", "s,t", 0x70000481, 0xfc00ffff, MOD_HILO|RD_s|RD_t, 0, SMT }, -{"rach.ob", "X", 0x7a00003f, 0xfffff83f, WR_D|FP_D, RD_MACC, MX|SB1 }, -{"rach.ob", "D", 0x4a00003f, 0xfffff83f, WR_D, 0, N54 }, -{"rach.qh", "X", 0x7a20003f, 0xfffff83f, WR_D|FP_D, RD_MACC, MX }, -{"racl.ob", "X", 0x7800003f, 0xfffff83f, WR_D|FP_D, RD_MACC, MX|SB1 }, -{"racl.ob", "D", 0x4800003f, 0xfffff83f, WR_D, 0, N54 }, -{"racl.qh", "X", 0x7820003f, 0xfffff83f, WR_D|FP_D, RD_MACC, MX }, -{"racm.ob", "X", 0x7900003f, 0xfffff83f, WR_D|FP_D, RD_MACC, MX|SB1 }, -{"racm.ob", "D", 0x4900003f, 0xfffff83f, WR_D, 0, N54 }, -{"racm.qh", "X", 0x7920003f, 0xfffff83f, WR_D|FP_D, RD_MACC, MX }, -{"recip.d", "D,S", 0x46200015, 0xffff003f, WR_D|RD_S|FP_D, 0, I4_33 }, -{"recip.ps","D,S", 0x46c00015, 0xffff003f, WR_D|RD_S|FP_D, 0, SB1 }, -{"recip.s", "D,S", 0x46000015, 0xffff003f, WR_D|RD_S|FP_S, 0, I4_33 }, -{"recip1.d", "D,S", 0x4620001d, 0xffff003f, WR_D|RD_S|FP_D, 0, M3D }, -{"recip1.ps", "D,S", 0x46c0001d, 0xffff003f, WR_D|RD_S|FP_S, 0, M3D }, -{"recip1.s", "D,S", 0x4600001d, 0xffff003f, WR_D|RD_S|FP_S, 0, M3D }, -{"recip2.d", "D,S,T", 0x4620001c, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, M3D }, -{"recip2.ps", "D,S,T", 0x46c0001c, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, M3D }, -{"recip2.s", "D,S,T", 0x4600001c, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, M3D }, -{"rem", "z,s,t", 0x0000001a, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I1 }, -{"rem", "d,v,t", 0, (int) M_REM_3, INSN_MACRO, 0, I1 }, -{"rem", "d,v,I", 0, (int) M_REM_3I, INSN_MACRO, 0, I1 }, -{"remu", "z,s,t", 0x0000001b, 0xfc00ffff, RD_s|RD_t|WR_HILO, 0, I1 }, -{"remu", "d,v,t", 0, (int) M_REMU_3, INSN_MACRO, 0, I1 }, -{"remu", "d,v,I", 0, (int) M_REMU_3I, INSN_MACRO, 0, I1 }, -{"rdhwr", "t,K", 0x7c00003b, 0xffe007ff, WR_t, 0, I33 }, -{"rdpgpr", "d,w", 0x41400000, 0xffe007ff, WR_d, 0, I33 }, -{"rfe", "", 0x42000010, 0xffffffff, 0, 0, I1|T3 }, -{"rnas.qh", "X,Q", 0x78200025, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX }, -{"rnau.ob", "X,Q", 0x78000021, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX|SB1 }, -{"rnau.qh", "X,Q", 0x78200021, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX }, -{"rnes.qh", "X,Q", 0x78200026, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX }, -{"rneu.ob", "X,Q", 0x78000022, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX|SB1 }, -{"rneu.qh", "X,Q", 0x78200022, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX }, -{"rol", "d,v,t", 0, (int) M_ROL, INSN_MACRO, 0, I1 }, -{"rol", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, 0, I1 }, -{"ror", "d,v,t", 0, (int) M_ROR, INSN_MACRO, 0, I1 }, -{"ror", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, 0, I1 }, -{"ror", "d,w,<", 0x00200002, 0xffe0003f, WR_d|RD_t, 0, N5|I33|SMT }, -{"rorv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, N5|I33|SMT }, -{"rotl", "d,v,t", 0, (int) M_ROL, INSN_MACRO, 0, I33|SMT }, -{"rotl", "d,v,I", 0, (int) M_ROL_I, INSN_MACRO, 0, I33|SMT }, -{"rotr", "d,v,t", 0, (int) M_ROR, INSN_MACRO, 0, I33|SMT }, -{"rotr", "d,v,I", 0, (int) M_ROR_I, INSN_MACRO, 0, I33|SMT }, -{"rotrv", "d,t,s", 0x00000046, 0xfc0007ff, RD_t|RD_s|WR_d, 0, I33|SMT }, -{"round.l.d", "D,S", 0x46200008, 0xffff003f, WR_D|RD_S|FP_D, 0, I3_33 }, -{"round.l.s", "D,S", 0x46000008, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3_33 }, -{"round.w.d", "D,S", 0x4620000c, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, -{"round.w.s", "D,S", 0x4600000c, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 }, -{"rsqrt.d", "D,S", 0x46200016, 0xffff003f, WR_D|RD_S|FP_D, 0, I4_33 }, -{"rsqrt.ps","D,S", 0x46c00016, 0xffff003f, WR_D|RD_S|FP_D, 0, SB1 }, -{"rsqrt.s", "D,S", 0x46000016, 0xffff003f, WR_D|RD_S|FP_S, 0, I4_33 }, -{"rsqrt1.d", "D,S", 0x4620001e, 0xffff003f, WR_D|RD_S|FP_D, 0, M3D }, -{"rsqrt1.ps", "D,S", 0x46c0001e, 0xffff003f, WR_D|RD_S|FP_S, 0, M3D }, -{"rsqrt1.s", "D,S", 0x4600001e, 0xffff003f, WR_D|RD_S|FP_S, 0, M3D }, -{"rsqrt2.d", "D,S,T", 0x4620001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, M3D }, -{"rsqrt2.ps", "D,S,T", 0x46c0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, M3D }, -{"rsqrt2.s", "D,S,T", 0x4600001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, M3D }, -{"rzs.qh", "X,Q", 0x78200024, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX }, -{"rzu.ob", "X,Q", 0x78000020, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX|SB1 }, -{"rzu.ob", "D,k", 0x4bc00020, 0xffe0f83f, WR_D|RD_S|RD_T, 0, N54 }, -{"rzu.qh", "X,Q", 0x78200020, 0xfc20f83f, WR_D|RD_T|FP_D, RD_MACC, MX }, -{"sb", "t,o(b)", 0xa0000000, 0xfc000000, SM|RD_t|RD_b, 0, I1 }, -{"sb", "t,A(b)", 0, (int) M_SB_AB, INSN_MACRO, 0, I1 }, -{"sc", "t,o(b)", 0xe0000000, 0xfc000000, SM|RD_t|WR_t|RD_b, 0, I2 }, -{"sc", "t,A(b)", 0, (int) M_SC_AB, INSN_MACRO, 0, I2 }, -{"scd", "t,o(b)", 0xf0000000, 0xfc000000, SM|RD_t|WR_t|RD_b, 0, I3 }, -{"scd", "t,A(b)", 0, (int) M_SCD_AB, INSN_MACRO, 0, I3 }, -{"sd", "t,o(b)", 0xfc000000, 0xfc000000, SM|RD_t|RD_b, 0, I3 }, -{"sd", "t,o(b)", 0, (int) M_SD_OB, INSN_MACRO, 0, I1 }, -{"sd", "t,A(b)", 0, (int) M_SD_AB, INSN_MACRO, 0, I1 }, -{"sdbbp", "", 0x0000000e, 0xffffffff, TRAP, 0, G2 }, -{"sdbbp", "c", 0x0000000e, 0xfc00ffff, TRAP, 0, G2 }, -{"sdbbp", "c,q", 0x0000000e, 0xfc00003f, TRAP, 0, G2 }, -{"sdbbp", "", 0x7000003f, 0xffffffff, TRAP, 0, I32 }, -{"sdbbp", "B", 0x7000003f, 0xfc00003f, TRAP, 0, I32 }, -{"sdc1", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 }, -{"sdc1", "E,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 }, -{"sdc1", "T,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, 0, I2 }, -{"sdc1", "E,A(b)", 0, (int) M_SDC1_AB, INSN_MACRO, 0, I2 }, -{"sdc2", "E,o(b)", 0xf8000000, 0xfc000000, SM|RD_C2|RD_b, 0, I2 }, -{"sdc2", "E,A(b)", 0, (int) M_SDC2_AB, INSN_MACRO, 0, I2 }, -{"sdc3", "E,o(b)", 0xfc000000, 0xfc000000, SM|RD_C3|RD_b, 0, I2 }, -{"sdc3", "E,A(b)", 0, (int) M_SDC3_AB, INSN_MACRO, 0, I2 }, -{"s.d", "T,o(b)", 0xf4000000, 0xfc000000, SM|RD_T|RD_b|FP_D, 0, I2 }, -{"s.d", "T,o(b)", 0, (int) M_S_DOB, INSN_MACRO, 0, I1 }, -{"s.d", "T,A(b)", 0, (int) M_S_DAB, INSN_MACRO, 0, I1 }, -{"sdl", "t,o(b)", 0xb0000000, 0xfc000000, SM|RD_t|RD_b, 0, I3 }, -{"sdl", "t,A(b)", 0, (int) M_SDL_AB, INSN_MACRO, 0, I3 }, -{"sdr", "t,o(b)", 0xb4000000, 0xfc000000, SM|RD_t|RD_b, 0, I3 }, -{"sdr", "t,A(b)", 0, (int) M_SDR_AB, INSN_MACRO, 0, I3 }, -{"sdxc1", "S,t(b)", 0x4c000009, 0xfc0007ff, SM|RD_S|RD_t|RD_b|FP_D, 0, I4_33 }, -{"seb", "d,w", 0x7c000420, 0xffe007ff, WR_d|RD_t, 0, I33 }, -{"seh", "d,w", 0x7c000620, 0xffe007ff, WR_d|RD_t, 0, I33 }, -{"selsl", "d,v,t", 0x00000005, 0xfc0007ff, WR_d|RD_s|RD_t, 0, L1 }, -{"selsr", "d,v,t", 0x00000001, 0xfc0007ff, WR_d|RD_s|RD_t, 0, L1 }, -{"seq", "d,v,t", 0, (int) M_SEQ, INSN_MACRO, 0, I1 }, -{"seq", "d,v,I", 0, (int) M_SEQ_I, INSN_MACRO, 0, I1 }, -{"seq", "S,T", 0x46a00032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"seq", "S,T", 0x4ba0000c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -{"sge", "d,v,t", 0, (int) M_SGE, INSN_MACRO, 0, I1 }, -{"sge", "d,v,I", 0, (int) M_SGE_I, INSN_MACRO, 0, I1 }, -{"sgeu", "d,v,t", 0, (int) M_SGEU, INSN_MACRO, 0, I1 }, -{"sgeu", "d,v,I", 0, (int) M_SGEU_I, INSN_MACRO, 0, I1 }, -{"sgt", "d,v,t", 0, (int) M_SGT, INSN_MACRO, 0, I1 }, -{"sgt", "d,v,I", 0, (int) M_SGT_I, INSN_MACRO, 0, I1 }, -{"sgtu", "d,v,t", 0, (int) M_SGTU, INSN_MACRO, 0, I1 }, -{"sgtu", "d,v,I", 0, (int) M_SGTU_I, INSN_MACRO, 0, I1 }, -{"sh", "t,o(b)", 0xa4000000, 0xfc000000, SM|RD_t|RD_b, 0, I1 }, -{"sh", "t,A(b)", 0, (int) M_SH_AB, INSN_MACRO, 0, I1 }, -{"shfl.bfla.qh", "X,Y,Z", 0x7a20001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"shfl.mixh.ob", "X,Y,Z", 0x7980001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"shfl.mixh.ob", "D,S,T", 0x4980001f, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"shfl.mixh.qh", "X,Y,Z", 0x7820001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"shfl.mixl.ob", "X,Y,Z", 0x79c0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"shfl.mixl.ob", "D,S,T", 0x49c0001f, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"shfl.mixl.qh", "X,Y,Z", 0x78a0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"shfl.pach.ob", "X,Y,Z", 0x7900001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"shfl.pach.ob", "D,S,T", 0x4900001f, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"shfl.pach.qh", "X,Y,Z", 0x7920001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"shfl.pacl.ob", "D,S,T", 0x4940001f, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"shfl.repa.qh", "X,Y,Z", 0x7b20001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"shfl.repb.qh", "X,Y,Z", 0x7ba0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"shfl.upsl.ob", "X,Y,Z", 0x78c0001f, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"sle", "d,v,t", 0, (int) M_SLE, INSN_MACRO, 0, I1 }, -{"sle", "d,v,I", 0, (int) M_SLE_I, INSN_MACRO, 0, I1 }, -{"sle", "S,T", 0x46a0003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"sle", "S,T", 0x4ba0000e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -{"sleu", "d,v,t", 0, (int) M_SLEU, INSN_MACRO, 0, I1 }, -{"sleu", "d,v,I", 0, (int) M_SLEU_I, INSN_MACRO, 0, I1 }, -{"sleu", "S,T", 0x4680003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"sleu", "S,T", 0x4b80000e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -{"sllv", "d,t,s", 0x00000004, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I1 }, -{"sll", "d,w,s", 0x00000004, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I1 }, /* sllv */ -{"sll", "d,w,<", 0x00000000, 0xffe0003f, WR_d|RD_t, 0, I1 }, -{"sll", "D,S,T", 0x45800002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"sll", "D,S,T", 0x4b00000e, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"sll.ob", "X,Y,Q", 0x78000010, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"sll.ob", "D,S,T[e]", 0x48000010, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"sll.ob", "D,S,k", 0x4bc00010, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"sll.qh", "X,Y,Q", 0x78200010, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"slt", "d,v,t", 0x0000002a, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, -{"slt", "d,v,I", 0, (int) M_SLT_I, INSN_MACRO, 0, I1 }, -{"slt", "S,T", 0x46a0003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"slt", "S,T", 0x4ba0000d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -{"slti", "t,r,j", 0x28000000, 0xfc000000, WR_t|RD_s, 0, I1 }, -{"sltiu", "t,r,j", 0x2c000000, 0xfc000000, WR_t|RD_s, 0, I1 }, -{"sltu", "d,v,t", 0x0000002b, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, -{"sltu", "d,v,I", 0, (int) M_SLTU_I, INSN_MACRO, 0, I1 }, -{"sltu", "S,T", 0x4680003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"sltu", "S,T", 0x4b80000d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -{"sne", "d,v,t", 0, (int) M_SNE, INSN_MACRO, 0, I1 }, -{"sne", "d,v,I", 0, (int) M_SNE_I, INSN_MACRO, 0, I1 }, -{"sqrt.d", "D,S", 0x46200004, 0xffff003f, WR_D|RD_S|FP_D, 0, I2 }, -{"sqrt.s", "D,S", 0x46000004, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 }, -{"sqrt.ps", "D,S", 0x46c00004, 0xffff003f, WR_D|RD_S|FP_D, 0, SB1 }, -{"srav", "d,t,s", 0x00000007, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I1 }, -{"sra", "d,w,s", 0x00000007, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I1 }, /* srav */ -{"sra", "d,w,<", 0x00000003, 0xffe0003f, WR_d|RD_t, 0, I1 }, -{"sra", "D,S,T", 0x45c00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"sra", "D,S,T", 0x4b40000f, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"sra.qh", "X,Y,Q", 0x78200013, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"srlv", "d,t,s", 0x00000006, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I1 }, -{"srl", "d,w,s", 0x00000006, 0xfc0007ff, WR_d|RD_t|RD_s, 0, I1 }, /* srlv */ -{"srl", "d,w,<", 0x00000002, 0xffe0003f, WR_d|RD_t, 0, I1 }, -{"srl", "D,S,T", 0x45800003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"srl", "D,S,T", 0x4b00000f, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"srl.ob", "X,Y,Q", 0x78000012, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"srl.ob", "D,S,T[e]", 0x48000012, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"srl.ob", "D,S,k", 0x4bc00012, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"srl.qh", "X,Y,Q", 0x78200012, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -/* ssnop is at the start of the table. */ -{"standby", "", 0x42000021, 0xffffffff, 0, 0, V1 }, -{"sub", "d,v,t", 0x00000022, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, -{"sub", "d,v,I", 0, (int) M_SUB_I, INSN_MACRO, 0, I1 }, -{"sub", "D,S,T", 0x45c00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2E }, -{"sub", "D,S,T", 0x4b40000d, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2F }, -{"sub.d", "D,V,T", 0x46200001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I1 }, -{"sub.s", "D,V,T", 0x46000001, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I1 }, -{"sub.ob", "X,Y,Q", 0x7800000a, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"sub.ob", "D,S,T", 0x4ac0000a, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"sub.ob", "D,S,T[e]", 0x4800000a, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"sub.ob", "D,S,k", 0x4bc0000a, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"sub.ps", "D,V,T", 0x46c00001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, I5_33|IL2F }, -{"sub.ps", "D,V,T", 0x45600001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"sub.qh", "X,Y,Q", 0x7820000a, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"suba.ob", "Y,Q", 0x78000036, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX|SB1 }, -{"suba.qh", "Y,Q", 0x78200036, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, -{"subl.ob", "Y,Q", 0x78000436, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX|SB1 }, -{"subl.qh", "Y,Q", 0x78200436, 0xfc2007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, -{"subu", "d,v,t", 0x00000023, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, -{"subu", "d,v,I", 0, (int) M_SUBU_I, INSN_MACRO, 0, I1 }, -{"subu", "D,S,T", 0x45800001, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2E }, -{"subu", "D,S,T", 0x4b00000d, 0xffe0003f, RD_S|RD_T|WR_D|FP_S, 0, IL2F }, -{"suspend", "", 0x42000022, 0xffffffff, 0, 0, V1 }, -{"suxc1", "S,t(b)", 0x4c00000d, 0xfc0007ff, SM|RD_S|RD_t|RD_b, 0, I5_33|N55}, -{"sw", "t,o(b)", 0xac000000, 0xfc000000, SM|RD_t|RD_b, 0, I1 }, -{"sw", "t,A(b)", 0, (int) M_SW_AB, INSN_MACRO, 0, I1 }, -{"swc0", "E,o(b)", 0xe0000000, 0xfc000000, SM|RD_C0|RD_b, 0, I1 }, -{"swc0", "E,A(b)", 0, (int) M_SWC0_AB, INSN_MACRO, 0, I1 }, -{"swc1", "T,o(b)", 0xe4000000, 0xfc000000, SM|RD_T|RD_b|FP_S, 0, I1 }, -{"swc1", "E,o(b)", 0xe4000000, 0xfc000000, SM|RD_T|RD_b|FP_S, 0, I1 }, -{"swc1", "T,A(b)", 0, (int) M_SWC1_AB, INSN_MACRO, 0, I1 }, -{"swc1", "E,A(b)", 0, (int) M_SWC1_AB, INSN_MACRO, 0, I1 }, -{"s.s", "T,o(b)", 0xe4000000, 0xfc000000, SM|RD_T|RD_b|FP_S, 0, I1 }, /* swc1 */ -{"s.s", "T,A(b)", 0, (int) M_SWC1_AB, INSN_MACRO, 0, I1 }, -{"swc2", "E,o(b)", 0xe8000000, 0xfc000000, SM|RD_C2|RD_b, 0, I1 }, -{"swc2", "E,A(b)", 0, (int) M_SWC2_AB, INSN_MACRO, 0, I1 }, -{"swc3", "E,o(b)", 0xec000000, 0xfc000000, SM|RD_C3|RD_b, 0, I1 }, -{"swc3", "E,A(b)", 0, (int) M_SWC3_AB, INSN_MACRO, 0, I1 }, -{"swl", "t,o(b)", 0xa8000000, 0xfc000000, SM|RD_t|RD_b, 0, I1 }, -{"swl", "t,A(b)", 0, (int) M_SWL_AB, INSN_MACRO, 0, I1 }, -{"scache", "t,o(b)", 0xa8000000, 0xfc000000, RD_t|RD_b, 0, I2 }, /* same */ -{"scache", "t,A(b)", 0, (int) M_SWL_AB, INSN_MACRO, 0, I2 }, /* as swl */ -{"swr", "t,o(b)", 0xb8000000, 0xfc000000, SM|RD_t|RD_b, 0, I1 }, -{"swr", "t,A(b)", 0, (int) M_SWR_AB, INSN_MACRO, 0, I1 }, -{"invalidate", "t,o(b)",0xb8000000, 0xfc000000, RD_t|RD_b, 0, I2 }, /* same */ -{"invalidate", "t,A(b)",0, (int) M_SWR_AB, INSN_MACRO, 0, I2 }, /* as swr */ -{"swxc1", "S,t(b)", 0x4c000008, 0xfc0007ff, SM|RD_S|RD_t|RD_b|FP_S, 0, I4_33 }, -{"sync", "", 0x0000000f, 0xffffffff, INSN_SYNC, 0, I2|G1 }, -{"sync.p", "", 0x0000040f, 0xffffffff, INSN_SYNC, 0, I2 }, -{"sync.l", "", 0x0000000f, 0xffffffff, INSN_SYNC, 0, I2 }, -{"synci", "o(b)", 0x041f0000, 0xfc1f0000, SM|RD_b, 0, I33 }, -{"synciobdma", "", 0x0000008f, 0xffffffff, INSN_SYNC, 0, IOCT }, -{"syscall", "", 0x0000000c, 0xffffffff, TRAP, 0, I1 }, -{"syscall", "B", 0x0000000c, 0xfc00003f, TRAP, 0, I1 }, -{"teqi", "s,j", 0x040c0000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, -{"teq", "s,t", 0x00000034, 0xfc00ffff, RD_s|RD_t|TRAP, 0, I2 }, -{"teq", "s,t,q", 0x00000034, 0xfc00003f, RD_s|RD_t|TRAP, 0, I2 }, -{"teq", "s,j", 0x040c0000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, /* teqi */ -{"teq", "s,I", 0, (int) M_TEQ_I, INSN_MACRO, 0, I2 }, -{"tgei", "s,j", 0x04080000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, -{"tge", "s,t", 0x00000030, 0xfc00ffff, RD_s|RD_t|TRAP, 0, I2 }, -{"tge", "s,t,q", 0x00000030, 0xfc00003f, RD_s|RD_t|TRAP, 0, I2 }, -{"tge", "s,j", 0x04080000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, /* tgei */ -{"tge", "s,I", 0, (int) M_TGE_I, INSN_MACRO, 0, I2 }, -{"tgeiu", "s,j", 0x04090000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, -{"tgeu", "s,t", 0x00000031, 0xfc00ffff, RD_s|RD_t|TRAP, 0, I2 }, -{"tgeu", "s,t,q", 0x00000031, 0xfc00003f, RD_s|RD_t|TRAP, 0, I2 }, -{"tgeu", "s,j", 0x04090000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, /* tgeiu */ -{"tgeu", "s,I", 0, (int) M_TGEU_I, INSN_MACRO, 0, I2 }, -{"tlbp", "", 0x42000008, 0xffffffff, INSN_TLB, 0, I1 }, -{"tlbr", "", 0x42000001, 0xffffffff, INSN_TLB, 0, I1 }, -{"tlbwi", "", 0x42000002, 0xffffffff, INSN_TLB, 0, I1 }, -{"tlbwr", "", 0x42000006, 0xffffffff, INSN_TLB, 0, I1 }, -{"tlti", "s,j", 0x040a0000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, -{"tlt", "s,t", 0x00000032, 0xfc00ffff, RD_s|RD_t|TRAP, 0, I2 }, -{"tlt", "s,t,q", 0x00000032, 0xfc00003f, RD_s|RD_t|TRAP, 0, I2 }, -{"tlt", "s,j", 0x040a0000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, /* tlti */ -{"tlt", "s,I", 0, (int) M_TLT_I, INSN_MACRO, 0, I2 }, -{"tltiu", "s,j", 0x040b0000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, -{"tltu", "s,t", 0x00000033, 0xfc00ffff, RD_s|RD_t|TRAP, 0, I2 }, -{"tltu", "s,t,q", 0x00000033, 0xfc00003f, RD_s|RD_t|TRAP, 0, I2 }, -{"tltu", "s,j", 0x040b0000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, /* tltiu */ -{"tltu", "s,I", 0, (int) M_TLTU_I, INSN_MACRO, 0, I2 }, -{"tnei", "s,j", 0x040e0000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, -{"tne", "s,t", 0x00000036, 0xfc00ffff, RD_s|RD_t|TRAP, 0, I2 }, -{"tne", "s,t,q", 0x00000036, 0xfc00003f, RD_s|RD_t|TRAP, 0, I2 }, -{"tne", "s,j", 0x040e0000, 0xfc1f0000, RD_s|TRAP, 0, I2 }, /* tnei */ -{"tne", "s,I", 0, (int) M_TNE_I, INSN_MACRO, 0, I2 }, -{"trunc.l.d", "D,S", 0x46200009, 0xffff003f, WR_D|RD_S|FP_D, 0, I3_33 }, -{"trunc.l.s", "D,S", 0x46000009, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I3_33 }, -{"trunc.w.d", "D,S", 0x4620000d, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, -{"trunc.w.d", "D,S,x", 0x4620000d, 0xffff003f, WR_D|RD_S|FP_S|FP_D, 0, I2 }, -{"trunc.w.d", "D,S,t", 0, (int) M_TRUNCWD, INSN_MACRO, 0, I1 }, -{"trunc.w.s", "D,S", 0x4600000d, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 }, -{"trunc.w.s", "D,S,x", 0x4600000d, 0xffff003f, WR_D|RD_S|FP_S, 0, I2 }, -{"trunc.w.s", "D,S,t", 0, (int) M_TRUNCWS, INSN_MACRO, 0, I1 }, -{"uld", "t,o(b)", 0, (int) M_ULD, INSN_MACRO, 0, I3 }, -{"uld", "t,A(b)", 0, (int) M_ULD_A, INSN_MACRO, 0, I3 }, -{"ulh", "t,o(b)", 0, (int) M_ULH, INSN_MACRO, 0, I1 }, -{"ulh", "t,A(b)", 0, (int) M_ULH_A, INSN_MACRO, 0, I1 }, -{"ulhu", "t,o(b)", 0, (int) M_ULHU, INSN_MACRO, 0, I1 }, -{"ulhu", "t,A(b)", 0, (int) M_ULHU_A, INSN_MACRO, 0, I1 }, -{"ulw", "t,o(b)", 0, (int) M_ULW, INSN_MACRO, 0, I1 }, -{"ulw", "t,A(b)", 0, (int) M_ULW_A, INSN_MACRO, 0, I1 }, -{"usd", "t,o(b)", 0, (int) M_USD, INSN_MACRO, 0, I3 }, -{"usd", "t,A(b)", 0, (int) M_USD_A, INSN_MACRO, 0, I3 }, -{"ush", "t,o(b)", 0, (int) M_USH, INSN_MACRO, 0, I1 }, -{"ush", "t,A(b)", 0, (int) M_USH_A, INSN_MACRO, 0, I1 }, -{"usw", "t,o(b)", 0, (int) M_USW, INSN_MACRO, 0, I1 }, -{"usw", "t,A(b)", 0, (int) M_USW_A, INSN_MACRO, 0, I1 }, -{"wach.ob", "Y", 0x7a00003e, 0xffff07ff, RD_S|FP_D, WR_MACC, MX|SB1 }, -{"wach.ob", "S", 0x4a00003e, 0xffff07ff, RD_S, 0, N54 }, -{"wach.qh", "Y", 0x7a20003e, 0xffff07ff, RD_S|FP_D, WR_MACC, MX }, -{"wacl.ob", "Y,Z", 0x7800003e, 0xffe007ff, RD_S|RD_T|FP_D, WR_MACC, MX|SB1 }, -{"wacl.ob", "S,T", 0x4800003e, 0xffe007ff, RD_S|RD_T, 0, N54 }, -{"wacl.qh", "Y,Z", 0x7820003e, 0xffe007ff, RD_S|RD_T|FP_D, WR_MACC, MX }, -{"wait", "", 0x42000020, 0xffffffff, TRAP, 0, I3_32 }, -{"wait", "J", 0x42000020, 0xfe00003f, TRAP, 0, I32|N55 }, -{"waiti", "", 0x42000020, 0xffffffff, TRAP, 0, L1 }, -{"wrpgpr", "d,w", 0x41c00000, 0xffe007ff, RD_t, 0, I33 }, -{"wsbh", "d,w", 0x7c0000a0, 0xffe007ff, WR_d|RD_t, 0, I33 }, -{"xor", "d,v,t", 0x00000026, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I1 }, -{"xor", "t,r,I", 0, (int) M_XOR_I, INSN_MACRO, 0, I1 }, -{"xor", "D,S,T", 0x47800002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"xor", "D,S,T", 0x4b800002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"xor.ob", "X,Y,Q", 0x7800000d, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX|SB1 }, -{"xor.ob", "D,S,T", 0x4ac0000d, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"xor.ob", "D,S,T[e]", 0x4800000d, 0xfe20003f, WR_D|RD_S|RD_T, 0, N54 }, -{"xor.ob", "D,S,k", 0x4bc0000d, 0xffe0003f, WR_D|RD_S|RD_T, 0, N54 }, -{"xor.qh", "X,Y,Q", 0x7820000d, 0xfc20003f, WR_D|RD_S|RD_T|FP_D, 0, MX }, -{"xori", "t,r,i", 0x38000000, 0xfc000000, WR_t|RD_s, 0, I1 }, -{"yield", "s", 0x7c000009, 0xfc1fffff, TRAP|RD_s, 0, MT32 }, -{"yield", "d,s", 0x7c000009, 0xfc1f07ff, TRAP|WR_d|RD_s, 0, MT32 }, - -/* User Defined Instruction. */ -{"udi0", "s,t,d,+1",0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi0", "s,t,+2", 0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi0", "s,+3", 0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi0", "+4", 0x70000010, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi1", "s,t,d,+1",0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi1", "s,t,+2", 0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi1", "s,+3", 0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi1", "+4", 0x70000011, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi2", "s,t,d,+1",0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi2", "s,t,+2", 0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi2", "s,+3", 0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi2", "+4", 0x70000012, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi3", "s,t,d,+1",0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi3", "s,t,+2", 0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi3", "s,+3", 0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi3", "+4", 0x70000013, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi4", "s,t,d,+1",0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi4", "s,t,+2", 0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi4", "s,+3", 0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi4", "+4", 0x70000014, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi5", "s,t,d,+1",0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi5", "s,t,+2", 0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi5", "s,+3", 0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi5", "+4", 0x70000015, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi6", "s,t,d,+1",0x70000016, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi6", "s,t,+2", 0x70000016, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi6", "s,+3", 0x70000016, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi6", "+4", 0x70000016, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi7", "s,t,d,+1",0x70000017, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi7", "s,t,+2", 0x70000017, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi7", "s,+3", 0x70000017, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi7", "+4", 0x70000017, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi8", "s,t,d,+1",0x70000018, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi8", "s,t,+2", 0x70000018, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi8", "s,+3", 0x70000018, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi8", "+4", 0x70000018, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi9", "s,t,d,+1",0x70000019, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi9", "s,t,+2", 0x70000019, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi9", "s,+3", 0x70000019, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi9", "+4", 0x70000019, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi10", "s,t,d,+1",0x7000001a, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi10", "s,t,+2", 0x7000001a, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi10", "s,+3", 0x7000001a, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi10", "+4", 0x7000001a, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi11", "s,t,d,+1",0x7000001b, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi11", "s,t,+2", 0x7000001b, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi11", "s,+3", 0x7000001b, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi11", "+4", 0x7000001b, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi12", "s,t,d,+1",0x7000001c, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi12", "s,t,+2", 0x7000001c, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi12", "s,+3", 0x7000001c, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi12", "+4", 0x7000001c, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi13", "s,t,d,+1",0x7000001d, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi13", "s,t,+2", 0x7000001d, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi13", "s,+3", 0x7000001d, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi13", "+4", 0x7000001d, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi14", "s,t,d,+1",0x7000001e, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi14", "s,t,+2", 0x7000001e, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi14", "s,+3", 0x7000001e, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi14", "+4", 0x7000001e, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi15", "s,t,d,+1",0x7000001f, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi15", "s,t,+2", 0x7000001f, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi15", "s,+3", 0x7000001f, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, -{"udi15", "+4", 0x7000001f, 0xfc00003f, WR_d|RD_s|RD_t, 0, I33 }, - -/* Coprocessor 2 move/branch operations overlap with VR5400 .ob format - instructions so they are here for the latters to take precedence. */ -{"bc2f", "p", 0x49000000, 0xffff0000, CBD|RD_CC, 0, I1 }, -{"bc2f", "N,p", 0x49000000, 0xffe30000, CBD|RD_CC, 0, I32 }, -{"bc2fl", "p", 0x49020000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, -{"bc2fl", "N,p", 0x49020000, 0xffe30000, CBL|RD_CC, 0, I32 }, -{"bc2t", "p", 0x49010000, 0xffff0000, CBD|RD_CC, 0, I1 }, -{"bc2t", "N,p", 0x49010000, 0xffe30000, CBD|RD_CC, 0, I32 }, -{"bc2tl", "p", 0x49030000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, -{"bc2tl", "N,p", 0x49030000, 0xffe30000, CBL|RD_CC, 0, I32 }, -{"cfc2", "t,G", 0x48400000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I1 }, -{"ctc2", "t,G", 0x48c00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 }, -{"dmfc2", "t,G", 0x48200000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I3 }, -{"dmfc2", "t,G,H", 0x48200000, 0xffe007f8, LCD|WR_t|RD_C2, 0, I64 }, -{"dmtc2", "t,G", 0x48a00000, 0xffe007ff, COD|RD_t|WR_C2|WR_CC, 0, I3 }, -{"dmtc2", "t,G,H", 0x48a00000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I64 }, -{"mfc2", "t,G", 0x48000000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I1 }, -{"mfc2", "t,G,H", 0x48000000, 0xffe007f8, LCD|WR_t|RD_C2, 0, I32 }, -{"mfhc2", "t,G", 0x48600000, 0xffe007ff, LCD|WR_t|RD_C2, 0, I33 }, -{"mfhc2", "t,G,H", 0x48600000, 0xffe007f8, LCD|WR_t|RD_C2, 0, I33 }, -{"mfhc2", "t,i", 0x48600000, 0xffe00000, LCD|WR_t|RD_C2, 0, I33 }, -{"mtc2", "t,G", 0x48800000, 0xffe007ff, COD|RD_t|WR_C2|WR_CC, 0, I1 }, -{"mtc2", "t,G,H", 0x48800000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I32 }, -{"mthc2", "t,G", 0x48e00000, 0xffe007ff, COD|RD_t|WR_C2|WR_CC, 0, I33 }, -{"mthc2", "t,G,H", 0x48e00000, 0xffe007f8, COD|RD_t|WR_C2|WR_CC, 0, I33 }, -{"mthc2", "t,i", 0x48e00000, 0xffe00000, COD|RD_t|WR_C2|WR_CC, 0, I33 }, - -/* Coprocessor 3 move/branch operations overlap with MIPS IV COP1X - instructions, so they are here for the latters to take precedence. */ -{"bc3f", "p", 0x4d000000, 0xffff0000, CBD|RD_CC, 0, I1 }, -{"bc3fl", "p", 0x4d020000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, -{"bc3t", "p", 0x4d010000, 0xffff0000, CBD|RD_CC, 0, I1 }, -{"bc3tl", "p", 0x4d030000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, -{"cfc3", "t,G", 0x4c400000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I1 }, -{"ctc3", "t,G", 0x4cc00000, 0xffe007ff, COD|RD_t|WR_CC, 0, I1 }, -{"dmfc3", "t,G", 0x4c200000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I3 }, -{"dmtc3", "t,G", 0x4ca00000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC, 0, I3 }, -{"mfc3", "t,G", 0x4c000000, 0xffe007ff, LCD|WR_t|RD_C3, 0, I1 }, -{"mfc3", "t,G,H", 0x4c000000, 0xffe007f8, LCD|WR_t|RD_C3, 0, I32 }, -{"mtc3", "t,G", 0x4c800000, 0xffe007ff, COD|RD_t|WR_C3|WR_CC, 0, I1 }, -{"mtc3", "t,G,H", 0x4c800000, 0xffe007f8, COD|RD_t|WR_C3|WR_CC, 0, I32 }, - - /* Conflicts with the 4650's "mul" instruction. Nobody's using the - 4010 any more, so move this insn out of the way. If the object - format gave us more info, we could do this right. */ -{"addciu", "t,r,j", 0x70000000, 0xfc000000, WR_t|RD_s, 0, L1 }, -/* MIPS DSP ASE */ -{"absq_s.ph", "d,t", 0x7c000252, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"absq_s.pw", "d,t", 0x7c000456, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"absq_s.qh", "d,t", 0x7c000256, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"absq_s.w", "d,t", 0x7c000452, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"addq.ph", "d,s,t", 0x7c000290, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"addq.pw", "d,s,t", 0x7c000494, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"addq.qh", "d,s,t", 0x7c000294, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"addq_s.ph", "d,s,t", 0x7c000390, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"addq_s.pw", "d,s,t", 0x7c000594, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"addq_s.qh", "d,s,t", 0x7c000394, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"addq_s.w", "d,s,t", 0x7c000590, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"addsc", "d,s,t", 0x7c000410, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"addu.ob", "d,s,t", 0x7c000014, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"addu.qb", "d,s,t", 0x7c000010, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"addu_s.ob", "d,s,t", 0x7c000114, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"addu_s.qb", "d,s,t", 0x7c000110, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"addwc", "d,s,t", 0x7c000450, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"bitrev", "d,t", 0x7c0006d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"bposge32", "p", 0x041c0000, 0xffff0000, CBD, 0, D32 }, -{"bposge64", "p", 0x041d0000, 0xffff0000, CBD, 0, D64 }, -{"cmp.eq.ph", "s,t", 0x7c000211, 0xfc00ffff, RD_s|RD_t, 0, D32 }, -{"cmp.eq.pw", "s,t", 0x7c000415, 0xfc00ffff, RD_s|RD_t, 0, D64 }, -{"cmp.eq.qh", "s,t", 0x7c000215, 0xfc00ffff, RD_s|RD_t, 0, D64 }, -{"cmpgu.eq.ob", "d,s,t", 0x7c000115, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"cmpgu.eq.qb", "d,s,t", 0x7c000111, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"cmpgu.le.ob", "d,s,t", 0x7c000195, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"cmpgu.le.qb", "d,s,t", 0x7c000191, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"cmpgu.lt.ob", "d,s,t", 0x7c000155, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"cmpgu.lt.qb", "d,s,t", 0x7c000151, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"cmp.le.ph", "s,t", 0x7c000291, 0xfc00ffff, RD_s|RD_t, 0, D32 }, -{"cmp.le.pw", "s,t", 0x7c000495, 0xfc00ffff, RD_s|RD_t, 0, D64 }, -{"cmp.le.qh", "s,t", 0x7c000295, 0xfc00ffff, RD_s|RD_t, 0, D64 }, -{"cmp.lt.ph", "s,t", 0x7c000251, 0xfc00ffff, RD_s|RD_t, 0, D32 }, -{"cmp.lt.pw", "s,t", 0x7c000455, 0xfc00ffff, RD_s|RD_t, 0, D64 }, -{"cmp.lt.qh", "s,t", 0x7c000255, 0xfc00ffff, RD_s|RD_t, 0, D64 }, -{"cmpu.eq.ob", "s,t", 0x7c000015, 0xfc00ffff, RD_s|RD_t, 0, D64 }, -{"cmpu.eq.qb", "s,t", 0x7c000011, 0xfc00ffff, RD_s|RD_t, 0, D32 }, -{"cmpu.le.ob", "s,t", 0x7c000095, 0xfc00ffff, RD_s|RD_t, 0, D64 }, -{"cmpu.le.qb", "s,t", 0x7c000091, 0xfc00ffff, RD_s|RD_t, 0, D32 }, -{"cmpu.lt.ob", "s,t", 0x7c000055, 0xfc00ffff, RD_s|RD_t, 0, D64 }, -{"cmpu.lt.qb", "s,t", 0x7c000051, 0xfc00ffff, RD_s|RD_t, 0, D32 }, -{"dextpdp", "t,7,6", 0x7c0002bc, 0xfc00e7ff, WR_t|RD_a|DSP_VOLA, 0, D64 }, -{"dextpdpv", "t,7,s", 0x7c0002fc, 0xfc00e7ff, WR_t|RD_a|RD_s|DSP_VOLA, 0, D64 }, -{"dextp", "t,7,6", 0x7c0000bc, 0xfc00e7ff, WR_t|RD_a, 0, D64 }, -{"dextpv", "t,7,s", 0x7c0000fc, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D64 }, -{"dextr.l", "t,7,6", 0x7c00043c, 0xfc00e7ff, WR_t|RD_a, 0, D64 }, -{"dextr_r.l", "t,7,6", 0x7c00053c, 0xfc00e7ff, WR_t|RD_a, 0, D64 }, -{"dextr_rs.l", "t,7,6", 0x7c0005bc, 0xfc00e7ff, WR_t|RD_a, 0, D64 }, -{"dextr_rs.w", "t,7,6", 0x7c0001bc, 0xfc00e7ff, WR_t|RD_a, 0, D64 }, -{"dextr_r.w", "t,7,6", 0x7c00013c, 0xfc00e7ff, WR_t|RD_a, 0, D64 }, -{"dextr_s.h", "t,7,6", 0x7c0003bc, 0xfc00e7ff, WR_t|RD_a, 0, D64 }, -{"dextrv.l", "t,7,s", 0x7c00047c, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D64 }, -{"dextrv_r.l", "t,7,s", 0x7c00057c, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D64 }, -{"dextrv_rs.l", "t,7,s", 0x7c0005fc, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D64 }, -{"dextrv_rs.w", "t,7,s", 0x7c0001fc, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D64 }, -{"dextrv_r.w", "t,7,s", 0x7c00017c, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D64 }, -{"dextrv_s.h", "t,7,s", 0x7c0003fc, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D64 }, -{"dextrv.w", "t,7,s", 0x7c00007c, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D64 }, -{"dextr.w", "t,7,6", 0x7c00003c, 0xfc00e7ff, WR_t|RD_a, 0, D64 }, -{"dinsv", "t,s", 0x7c00000d, 0xfc00ffff, WR_t|RD_s, 0, D64 }, -{"dmadd", "7,s,t", 0x7c000674, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dmaddu", "7,s,t", 0x7c000774, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dmsub", "7,s,t", 0x7c0006f4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dmsubu", "7,s,t", 0x7c0007f4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dmthlip", "s,7", 0x7c0007fc, 0xfc1fe7ff, RD_s|MOD_a|DSP_VOLA, 0, D64 }, -{"dpaq_sa.l.pw", "7,s,t", 0x7c000334, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dpaq_sa.l.w", "7,s,t", 0x7c000330, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"dpaq_s.w.ph", "7,s,t", 0x7c000130, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"dpaq_s.w.qh", "7,s,t", 0x7c000134, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dpau.h.obl", "7,s,t", 0x7c0000f4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dpau.h.obr", "7,s,t", 0x7c0001f4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dpau.h.qbl", "7,s,t", 0x7c0000f0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"dpau.h.qbr", "7,s,t", 0x7c0001f0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"dpsq_sa.l.pw", "7,s,t", 0x7c000374, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dpsq_sa.l.w", "7,s,t", 0x7c000370, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"dpsq_s.w.ph", "7,s,t", 0x7c000170, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"dpsq_s.w.qh", "7,s,t", 0x7c000174, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dpsu.h.obl", "7,s,t", 0x7c0002f4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dpsu.h.obr", "7,s,t", 0x7c0003f4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"dpsu.h.qbl", "7,s,t", 0x7c0002f0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"dpsu.h.qbr", "7,s,t", 0x7c0003f0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"dshilo", "7,:", 0x7c0006bc, 0xfc07e7ff, MOD_a, 0, D64 }, -{"dshilov", "7,s", 0x7c0006fc, 0xfc1fe7ff, MOD_a|RD_s, 0, D64 }, -{"extpdp", "t,7,6", 0x7c0002b8, 0xfc00e7ff, WR_t|RD_a|DSP_VOLA, 0, D32 }, -{"extpdpv", "t,7,s", 0x7c0002f8, 0xfc00e7ff, WR_t|RD_a|RD_s|DSP_VOLA, 0, D32 }, -{"extp", "t,7,6", 0x7c0000b8, 0xfc00e7ff, WR_t|RD_a, 0, D32 }, -{"extpv", "t,7,s", 0x7c0000f8, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D32 }, -{"extr_rs.w", "t,7,6", 0x7c0001b8, 0xfc00e7ff, WR_t|RD_a, 0, D32 }, -{"extr_r.w", "t,7,6", 0x7c000138, 0xfc00e7ff, WR_t|RD_a, 0, D32 }, -{"extr_s.h", "t,7,6", 0x7c0003b8, 0xfc00e7ff, WR_t|RD_a, 0, D32 }, -{"extrv_rs.w", "t,7,s", 0x7c0001f8, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D32 }, -{"extrv_r.w", "t,7,s", 0x7c000178, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D32 }, -{"extrv_s.h", "t,7,s", 0x7c0003f8, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D32 }, -{"extrv.w", "t,7,s", 0x7c000078, 0xfc00e7ff, WR_t|RD_a|RD_s, 0, D32 }, -{"extr.w", "t,7,6", 0x7c000038, 0xfc00e7ff, WR_t|RD_a, 0, D32 }, -{"insv", "t,s", 0x7c00000c, 0xfc00ffff, WR_t|RD_s, 0, D32 }, -{"lbux", "d,t(b)", 0x7c00018a, 0xfc0007ff, LDD|WR_d|RD_t|RD_b, 0, D32 }, -{"ldx", "d,t(b)", 0x7c00020a, 0xfc0007ff, LDD|WR_d|RD_t|RD_b, 0, D64 }, -{"lhx", "d,t(b)", 0x7c00010a, 0xfc0007ff, LDD|WR_d|RD_t|RD_b, 0, D32 }, -{"lwx", "d,t(b)", 0x7c00000a, 0xfc0007ff, LDD|WR_d|RD_t|RD_b, 0, D32 }, -{"maq_sa.w.phl", "7,s,t", 0x7c000430, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"maq_sa.w.phr", "7,s,t", 0x7c0004b0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"maq_sa.w.qhll", "7,s,t", 0x7c000434, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"maq_sa.w.qhlr", "7,s,t", 0x7c000474, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"maq_sa.w.qhrl", "7,s,t", 0x7c0004b4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"maq_sa.w.qhrr", "7,s,t", 0x7c0004f4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"maq_s.l.pwl", "7,s,t", 0x7c000734, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"maq_s.l.pwr", "7,s,t", 0x7c0007b4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"maq_s.w.phl", "7,s,t", 0x7c000530, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"maq_s.w.phr", "7,s,t", 0x7c0005b0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"maq_s.w.qhll", "7,s,t", 0x7c000534, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"maq_s.w.qhlr", "7,s,t", 0x7c000574, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"maq_s.w.qhrl", "7,s,t", 0x7c0005b4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"maq_s.w.qhrr", "7,s,t", 0x7c0005f4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"modsub", "d,s,t", 0x7c000490, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"mthlip", "s,7", 0x7c0007f8, 0xfc1fe7ff, RD_s|MOD_a|DSP_VOLA, 0, D32 }, -{"muleq_s.pw.qhl", "d,s,t", 0x7c000714, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D64 }, -{"muleq_s.pw.qhr", "d,s,t", 0x7c000754, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D64 }, -{"muleq_s.w.phl", "d,s,t", 0x7c000710, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D32 }, -{"muleq_s.w.phr", "d,s,t", 0x7c000750, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D32 }, -{"muleu_s.ph.qbl", "d,s,t", 0x7c000190, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D32 }, -{"muleu_s.ph.qbr", "d,s,t", 0x7c0001d0, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D32 }, -{"muleu_s.qh.obl", "d,s,t", 0x7c000194, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D64 }, -{"muleu_s.qh.obr", "d,s,t", 0x7c0001d4, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D64 }, -{"mulq_rs.ph", "d,s,t", 0x7c0007d0, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D32 }, -{"mulq_rs.qh", "d,s,t", 0x7c0007d4, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D64 }, -{"mulsaq_s.l.pw", "7,s,t", 0x7c0003b4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"mulsaq_s.w.ph", "7,s,t", 0x7c0001b0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D32 }, -{"mulsaq_s.w.qh", "7,s,t", 0x7c0001b4, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D64 }, -{"packrl.ph", "d,s,t", 0x7c000391, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"packrl.pw", "d,s,t", 0x7c000395, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"pick.ob", "d,s,t", 0x7c0000d5, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"pick.ph", "d,s,t", 0x7c0002d1, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"pick.pw", "d,s,t", 0x7c0004d5, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"pick.qb", "d,s,t", 0x7c0000d1, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"pick.qh", "d,s,t", 0x7c0002d5, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"preceq.pw.qhla", "d,t", 0x7c000396, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"preceq.pw.qhl", "d,t", 0x7c000316, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"preceq.pw.qhra", "d,t", 0x7c0003d6, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"preceq.pw.qhr", "d,t", 0x7c000356, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"preceq.s.l.pwl", "d,t", 0x7c000516, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"preceq.s.l.pwr", "d,t", 0x7c000556, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"precequ.ph.qbla", "d,t", 0x7c000192, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"precequ.ph.qbl", "d,t", 0x7c000112, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"precequ.ph.qbra", "d,t", 0x7c0001d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"precequ.ph.qbr", "d,t", 0x7c000152, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"precequ.pw.qhla", "d,t", 0x7c000196, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"precequ.pw.qhl", "d,t", 0x7c000116, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"precequ.pw.qhra", "d,t", 0x7c0001d6, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"precequ.pw.qhr", "d,t", 0x7c000156, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"preceq.w.phl", "d,t", 0x7c000312, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"preceq.w.phr", "d,t", 0x7c000352, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"preceu.ph.qbla", "d,t", 0x7c000792, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"preceu.ph.qbl", "d,t", 0x7c000712, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"preceu.ph.qbra", "d,t", 0x7c0007d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"preceu.ph.qbr", "d,t", 0x7c000752, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"preceu.qh.obla", "d,t", 0x7c000796, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"preceu.qh.obl", "d,t", 0x7c000716, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"preceu.qh.obra", "d,t", 0x7c0007d6, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"preceu.qh.obr", "d,t", 0x7c000756, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"precrq.ob.qh", "d,s,t", 0x7c000315, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"precrq.ph.w", "d,s,t", 0x7c000511, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"precrq.pw.l", "d,s,t", 0x7c000715, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"precrq.qb.ph", "d,s,t", 0x7c000311, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"precrq.qh.pw", "d,s,t", 0x7c000515, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"precrq_rs.ph.w", "d,s,t", 0x7c000551, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"precrq_rs.qh.pw", "d,s,t", 0x7c000555, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"precrqu_s.ob.qh", "d,s,t", 0x7c0003d5, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"precrqu_s.qb.ph", "d,s,t", 0x7c0003d1, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"raddu.l.ob", "d,s", 0x7c000514, 0xfc1f07ff, WR_d|RD_s, 0, D64 }, -{"raddu.w.qb", "d,s", 0x7c000510, 0xfc1f07ff, WR_d|RD_s, 0, D32 }, -{"rddsp", "d", 0x7fff04b8, 0xffff07ff, WR_d, 0, D32 }, -{"rddsp", "d,'", 0x7c0004b8, 0xffc007ff, WR_d, 0, D32 }, -{"repl.ob", "d,5", 0x7c000096, 0xff0007ff, WR_d, 0, D64 }, -{"repl.ph", "d,@", 0x7c000292, 0xfc0007ff, WR_d, 0, D32 }, -{"repl.pw", "d,@", 0x7c000496, 0xfc0007ff, WR_d, 0, D64 }, -{"repl.qb", "d,5", 0x7c000092, 0xff0007ff, WR_d, 0, D32 }, -{"repl.qh", "d,@", 0x7c000296, 0xfc0007ff, WR_d, 0, D64 }, -{"replv.ob", "d,t", 0x7c0000d6, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"replv.ph", "d,t", 0x7c0002d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"replv.pw", "d,t", 0x7c0004d6, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"replv.qb", "d,t", 0x7c0000d2, 0xffe007ff, WR_d|RD_t, 0, D32 }, -{"replv.qh", "d,t", 0x7c0002d6, 0xffe007ff, WR_d|RD_t, 0, D64 }, -{"shilo", "7,0", 0x7c0006b8, 0xfc0fe7ff, MOD_a, 0, D32 }, -{"shilov", "7,s", 0x7c0006f8, 0xfc1fe7ff, MOD_a|RD_s, 0, D32 }, -{"shll.ob", "d,t,3", 0x7c000017, 0xff0007ff, WR_d|RD_t, 0, D64 }, -{"shll.ph", "d,t,4", 0x7c000213, 0xfe0007ff, WR_d|RD_t, 0, D32 }, -{"shll.pw", "d,t,6", 0x7c000417, 0xfc0007ff, WR_d|RD_t, 0, D64 }, -{"shll.qb", "d,t,3", 0x7c000013, 0xff0007ff, WR_d|RD_t, 0, D32 }, -{"shll.qh", "d,t,4", 0x7c000217, 0xfe0007ff, WR_d|RD_t, 0, D64 }, -{"shll_s.ph", "d,t,4", 0x7c000313, 0xfe0007ff, WR_d|RD_t, 0, D32 }, -{"shll_s.pw", "d,t,6", 0x7c000517, 0xfc0007ff, WR_d|RD_t, 0, D64 }, -{"shll_s.qh", "d,t,4", 0x7c000317, 0xfe0007ff, WR_d|RD_t, 0, D64 }, -{"shll_s.w", "d,t,6", 0x7c000513, 0xfc0007ff, WR_d|RD_t, 0, D32 }, -{"shllv.ob", "d,t,s", 0x7c000097, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"shllv.ph", "d,t,s", 0x7c000293, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"shllv.pw", "d,t,s", 0x7c000497, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"shllv.qb", "d,t,s", 0x7c000093, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"shllv.qh", "d,t,s", 0x7c000297, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"shllv_s.ph", "d,t,s", 0x7c000393, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"shllv_s.pw", "d,t,s", 0x7c000597, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"shllv_s.qh", "d,t,s", 0x7c000397, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"shllv_s.w", "d,t,s", 0x7c000593, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"shra.ph", "d,t,4", 0x7c000253, 0xfe0007ff, WR_d|RD_t, 0, D32 }, -{"shra.pw", "d,t,6", 0x7c000457, 0xfc0007ff, WR_d|RD_t, 0, D64 }, -{"shra.qh", "d,t,4", 0x7c000257, 0xfe0007ff, WR_d|RD_t, 0, D64 }, -{"shra_r.ph", "d,t,4", 0x7c000353, 0xfe0007ff, WR_d|RD_t, 0, D32 }, -{"shra_r.pw", "d,t,6", 0x7c000557, 0xfc0007ff, WR_d|RD_t, 0, D64 }, -{"shra_r.qh", "d,t,4", 0x7c000357, 0xfe0007ff, WR_d|RD_t, 0, D64 }, -{"shra_r.w", "d,t,6", 0x7c000553, 0xfc0007ff, WR_d|RD_t, 0, D32 }, -{"shrav.ph", "d,t,s", 0x7c0002d3, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"shrav.pw", "d,t,s", 0x7c0004d7, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"shrav.qh", "d,t,s", 0x7c0002d7, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"shrav_r.ph", "d,t,s", 0x7c0003d3, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"shrav_r.pw", "d,t,s", 0x7c0005d7, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"shrav_r.qh", "d,t,s", 0x7c0003d7, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"shrav_r.w", "d,t,s", 0x7c0005d3, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"shrl.ob", "d,t,3", 0x7c000057, 0xff0007ff, WR_d|RD_t, 0, D64 }, -{"shrl.qb", "d,t,3", 0x7c000053, 0xff0007ff, WR_d|RD_t, 0, D32 }, -{"shrlv.ob", "d,t,s", 0x7c0000d7, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"shrlv.qb", "d,t,s", 0x7c0000d3, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"subq.ph", "d,s,t", 0x7c0002d0, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"subq.pw", "d,s,t", 0x7c0004d4, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"subq.qh", "d,s,t", 0x7c0002d4, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"subq_s.ph", "d,s,t", 0x7c0003d0, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"subq_s.pw", "d,s,t", 0x7c0005d4, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"subq_s.qh", "d,s,t", 0x7c0003d4, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"subq_s.w", "d,s,t", 0x7c0005d0, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"subu.ob", "d,s,t", 0x7c000054, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"subu.qb", "d,s,t", 0x7c000050, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"subu_s.ob", "d,s,t", 0x7c000154, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D64 }, -{"subu_s.qb", "d,s,t", 0x7c000150, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D32 }, -{"wrdsp", "s", 0x7c1ffcf8, 0xfc1fffff, RD_s|DSP_VOLA, 0, D32 }, -{"wrdsp", "s,8", 0x7c0004f8, 0xfc1e07ff, RD_s|DSP_VOLA, 0, D32 }, -/* MIPS DSP ASE Rev2 */ -{"absq_s.qb", "d,t", 0x7c000052, 0xffe007ff, WR_d|RD_t, 0, D33 }, -{"addu.ph", "d,s,t", 0x7c000210, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"addu_s.ph", "d,s,t", 0x7c000310, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"adduh.qb", "d,s,t", 0x7c000018, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"adduh_r.qb", "d,s,t", 0x7c000098, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"append", "t,s,h", 0x7c000031, 0xfc0007ff, WR_t|RD_t|RD_s, 0, D33 }, -{"balign", "t,s,I", 0, (int) M_BALIGN, INSN_MACRO, 0, D33 }, -{"balign", "t,s,2", 0x7c000431, 0xfc00e7ff, WR_t|RD_t|RD_s, 0, D33 }, -{"cmpgdu.eq.qb", "d,s,t", 0x7c000611, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"cmpgdu.lt.qb", "d,s,t", 0x7c000651, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"cmpgdu.le.qb", "d,s,t", 0x7c000691, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"dpa.w.ph", "7,s,t", 0x7c000030, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"dps.w.ph", "7,s,t", 0x7c000070, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"mul.ph", "d,s,t", 0x7c000318, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D33 }, -{"mul_s.ph", "d,s,t", 0x7c000398, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D33 }, -{"mulq_rs.w", "d,s,t", 0x7c0005d8, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D33 }, -{"mulq_s.ph", "d,s,t", 0x7c000790, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D33 }, -{"mulq_s.w", "d,s,t", 0x7c000598, 0xfc0007ff, WR_d|RD_s|RD_t|WR_HILO, 0, D33 }, -{"mulsa.w.ph", "7,s,t", 0x7c0000b0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"precr.qb.ph", "d,s,t", 0x7c000351, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"precr_sra.ph.w", "t,s,h", 0x7c000791, 0xfc0007ff, WR_t|RD_t|RD_s, 0, D33 }, -{"precr_sra_r.ph.w", "t,s,h", 0x7c0007d1, 0xfc0007ff, WR_t|RD_t|RD_s, 0, D33 }, -{"prepend", "t,s,h", 0x7c000071, 0xfc0007ff, WR_t|RD_t|RD_s, 0, D33 }, -{"shra.qb", "d,t,3", 0x7c000113, 0xff0007ff, WR_d|RD_t, 0, D33 }, -{"shra_r.qb", "d,t,3", 0x7c000153, 0xff0007ff, WR_d|RD_t, 0, D33 }, -{"shrav.qb", "d,t,s", 0x7c000193, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"shrav_r.qb", "d,t,s", 0x7c0001d3, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"shrl.ph", "d,t,4", 0x7c000653, 0xfe0007ff, WR_d|RD_t, 0, D33 }, -{"shrlv.ph", "d,t,s", 0x7c0006d3, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"subu.ph", "d,s,t", 0x7c000250, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"subu_s.ph", "d,s,t", 0x7c000350, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"subuh.qb", "d,s,t", 0x7c000058, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"subuh_r.qb", "d,s,t", 0x7c0000d8, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"addqh.ph", "d,s,t", 0x7c000218, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"addqh_r.ph", "d,s,t", 0x7c000298, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"addqh.w", "d,s,t", 0x7c000418, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"addqh_r.w", "d,s,t", 0x7c000498, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"subqh.ph", "d,s,t", 0x7c000258, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"subqh_r.ph", "d,s,t", 0x7c0002d8, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"subqh.w", "d,s,t", 0x7c000458, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"subqh_r.w", "d,s,t", 0x7c0004d8, 0xfc0007ff, WR_d|RD_s|RD_t, 0, D33 }, -{"dpax.w.ph", "7,s,t", 0x7c000230, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"dpsx.w.ph", "7,s,t", 0x7c000270, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"dpaqx_s.w.ph", "7,s,t", 0x7c000630, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"dpaqx_sa.w.ph", "7,s,t", 0x7c0006b0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"dpsqx_s.w.ph", "7,s,t", 0x7c000670, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -{"dpsqx_sa.w.ph", "7,s,t", 0x7c0006f0, 0xfc00e7ff, MOD_a|RD_s|RD_t, 0, D33 }, -/* Move bc0* after mftr and mttr to avoid opcode collision. */ -{"bc0f", "p", 0x41000000, 0xffff0000, CBD|RD_CC, 0, I1 }, -{"bc0fl", "p", 0x41020000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, -{"bc0t", "p", 0x41010000, 0xffff0000, CBD|RD_CC, 0, I1 }, -{"bc0tl", "p", 0x41030000, 0xffff0000, CBL|RD_CC, 0, I2|T3 }, -/* ST Microelectronics Loongson-2E and -2F. */ -{"faddu", "D,V,T", 0x45800000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"for", "D,V,T", 0x45a00000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fadd", "D,V,T", 0x45c00000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fdadd", "D,V,T", 0x45e00000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fsubu", "D,V,T", 0x45800001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fsub", "D,V,T", 0x45c00001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fdsub", "D,V,T", 0x45e00001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fsll", "D,V,T", 0x45800002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fdsll", "D,V,T", 0x45a00002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fxor", "D,V,T", 0x47800002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fnor", "D,V,T", 0x47a00002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fand", "D,V,T", 0x47c00002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fsrl", "D,V,T", 0x45800003, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fdsrl", "D,V,T", 0x45a00003, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fsra", "D,V,T", 0x45c00003, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fdsra", "D,V,T", 0x45e00003, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"fseq", "S,T", 0x46800032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"fseq1", "S,T", 0x46a00032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"fsltu", "S,T", 0x4680003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"fslt", "S,T", 0x46a0003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"fsleu", "S,T", 0x4680003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"fsle", "S,T", 0x46a0003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -/* loongson 2f */ -{"faddu", "D,V,T", 0x45800000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"for", "D,V,T", 0x45a00000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fadd", "D,V,T", 0x45c00000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fdadd", "D,V,T", 0x45e00000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fsubu", "D,V,T", 0x45800001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fsub", "D,V,T", 0x45c00001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fdsub", "D,V,T", 0x45e00001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fsll", "D,V,T", 0x45800002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fdsll", "D,V,T", 0x45a00002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fxor", "D,V,T", 0x47800002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fnor", "D,V,T", 0x47a00002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fand", "D,V,T", 0x47c00002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fsrl", "D,V,T", 0x45800003, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fdsrl", "D,V,T", 0x45a00003, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fsra", "D,V,T", 0x45c00003, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fdsra", "D,V,T", 0x45e00003, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2F }, -{"fseq", "S,T", 0x46800032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -{"fseq1", "S,T", 0x46a00032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -{"fsltu", "S,T", 0x4680003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -{"fslt", "S,T", 0x46a0003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -{"fsleu", "S,T", 0x4680003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -{"fsle", "S,T", 0x46a0003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -/* loongson2 paired single */ -{"add.gps", "D,V,T", 0x45600000, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"sub.gps", "D,V,T", 0x45600001, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"mul.gps", "D,V,T", 0x45600002, 0xffe0003f, WR_D|RD_S|RD_T|FP_D, 0, IL2E }, -{"abs.gps", "D,V", 0x45600005, 0xffff003f, WR_D|RD_S|FP_D, 0, IL2E }, -{"mov.gps", "D,S", 0x45600006, 0xffff003f, WR_D|RD_S|FP_D, 0, IL2E }, -{"neg.gps", "D,V", 0x45600007, 0xffff003f, WR_D|RD_S|FP_D, 0, IL2E }, -{"c.f.gps", "S,T", 0x45600030, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.un.gps", "S,T", 0x45600031, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.eq.gps", "S,T", 0x45600032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ueq.gps", "S,T", 0x45600033, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.olt.gps", "S,T", 0x45600034, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ult.gps", "S,T", 0x45600035, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ole.gps", "S,T", 0x45600036, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ule.gps", "S,T", 0x45600037, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.sf.gps", "S,T", 0x45600038, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ngle.gps", "S,T", 0x45600039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ngle.gps", "S,T", 0x45600039, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.seq.gps", "S,T", 0x4560003a, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ngl.gps", "S,T", 0x4560003b, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.lt.gps", "S,T", 0x4560003c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.nge.gps", "S,T", 0x4560003d, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.le.gps", "S,T", 0x4560003e, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"c.ngt.gps", "S,T", 0x4560003f, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, - -{"mult.g", "d,s,t", 0x7c000018, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"mult.g", "d,s,t", 0x70000010, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"multu.g", "d,s,t", 0x7c000019, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"multu.g", "d,s,t", 0x70000012, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"dmult.g", "d,s,t", 0x7c00001c, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"dmult.g", "d,s,t", 0x70000011, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"dmultu.g", "d,s,t", 0x7c00001d, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"dmultu.g", "d,s,t", 0x70000013, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"div.g", "d,s,t", 0x7c00001a, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"div.g", "d,s,t", 0x70000014, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"divu.g", "d,s,t", 0x7c00001b, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"divu.g", "d,s,t", 0x70000016, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"ddiv.g", "d,s,t", 0x7c00001e, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"ddiv.g", "d,s,t", 0x70000015, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"ddivu.g", "d,s,t", 0x7c00001f, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"ddivu.g", "d,s,t", 0x70000017, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"mod.g", "d,s,t", 0x7c000022, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"mod.g", "d,s,t", 0x7000001c, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"modu.g", "d,s,t", 0x7c000023, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"modu.g", "d,s,t", 0x7000001e, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"dmod.g", "d,s,t", 0x7c000026, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"dmod.g", "d,s,t", 0x7000001d, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"dmodu.g", "d,s,t", 0x7c000027, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2E }, -{"dmodu.g", "d,s,t", 0x7000001f, 0xfc0007ff, RD_s|RD_t|WR_d, 0, IL2F }, -{"packsshb", "D,S,T", 0x47400002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"packsshb", "D,S,T", 0x4b400002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"packsswh", "D,S,T", 0x47200002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"packsswh", "D,S,T", 0x4b200002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"packushb", "D,S,T", 0x47600002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"packushb", "D,S,T", 0x4b600002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"paddb", "D,S,T", 0x47c00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"paddb", "D,S,T", 0x4bc00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"paddh", "D,S,T", 0x47400000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"paddh", "D,S,T", 0x4b400000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"paddw", "D,S,T", 0x47600000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"paddw", "D,S,T", 0x4b600000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"paddd", "D,S,T", 0x47e00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"paddd", "D,S,T", 0x4be00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"paddsb", "D,S,T", 0x47800000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"paddsb", "D,S,T", 0x4b800000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"paddsh", "D,S,T", 0x47000000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"paddsh", "D,S,T", 0x4b000000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"paddusb", "D,S,T", 0x47a00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"paddusb", "D,S,T", 0x4ba00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"paddush", "D,S,T", 0x47200000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"paddush", "D,S,T", 0x4b200000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pandn", "D,S,T", 0x47e00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pandn", "D,S,T", 0x4be00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pavgb", "D,S,T", 0x46600000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pavgb", "D,S,T", 0x4b200008, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pavgh", "D,S,T", 0x46400000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pavgh", "D,S,T", 0x4b000008, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pcmpeqb", "D,S,T", 0x46c00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pcmpeqb", "D,S,T", 0x4b800009, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pcmpeqh", "D,S,T", 0x46800001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pcmpeqh", "D,S,T", 0x4b400009, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pcmpeqw", "D,S,T", 0x46400001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pcmpeqw", "D,S,T", 0x4b000009, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pcmpgtb", "D,S,T", 0x46e00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pcmpgtb", "D,S,T", 0x4ba00009, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pcmpgth", "D,S,T", 0x46a00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pcmpgth", "D,S,T", 0x4b600009, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pcmpgtw", "D,S,T", 0x46600001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pcmpgtw", "D,S,T", 0x4b200009, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pextrh", "D,S,T", 0x45c00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pextrh", "D,S,T", 0x4b40000e, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pinsrh_0", "D,S,T", 0x47800003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pinsrh_0", "D,S,T", 0x4b800003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pinsrh_1", "D,S,T", 0x47a00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pinsrh_1", "D,S,T", 0x4ba00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pinsrh_2", "D,S,T", 0x47c00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pinsrh_2", "D,S,T", 0x4bc00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pinsrh_3", "D,S,T", 0x47e00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pinsrh_3", "D,S,T", 0x4be00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pmaddhw", "D,S,T", 0x45e00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pmaddhw", "D,S,T", 0x4b60000e, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pmaxsh", "D,S,T", 0x46800000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pmaxsh", "D,S,T", 0x4b400008, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pmaxub", "D,S,T", 0x46c00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pmaxub", "D,S,T", 0x4b800008, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pminsh", "D,S,T", 0x46a00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pminsh", "D,S,T", 0x4b600008, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pminub", "D,S,T", 0x46e00000, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pminub", "D,S,T", 0x4ba00008, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pmovmskb", "D,S", 0x46a00005, 0xffff003f, RD_S|WR_D|FP_D, 0, IL2E }, -{"pmovmskb", "D,S", 0x4ba0000f, 0xffff003f, RD_S|WR_D|FP_D, 0, IL2F }, -{"pmulhuh", "D,S,T", 0x46e00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pmulhuh", "D,S,T", 0x4ba0000a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pmulhh", "D,S,T", 0x46a00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pmulhh", "D,S,T", 0x4b60000a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pmullh", "D,S,T", 0x46800002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pmullh", "D,S,T", 0x4b40000a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pmuluw", "D,S,T", 0x46c00002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pmuluw", "D,S,T", 0x4b80000a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"pasubub", "D,S,T", 0x45a00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pasubub", "D,S,T", 0x4b20000d, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"biadd", "D,S", 0x46800005, 0xffff003f, RD_S|WR_D|FP_D, 0, IL2E }, -{"biadd", "D,S", 0x4b80000f, 0xffff003f, RD_S|WR_D|FP_D, 0, IL2F }, -{"pshufh", "D,S,T", 0x47000002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"pshufh", "D,S,T", 0x4b000002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psllh", "D,S,T", 0x46600002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psllh", "D,S,T", 0x4b20000a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psllw", "D,S,T", 0x46400002, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psllw", "D,S,T", 0x4b00000a, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psrah", "D,S,T", 0x46a00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psrah", "D,S,T", 0x4b60000b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psraw", "D,S,T", 0x46800003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psraw", "D,S,T", 0x4b40000b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psrlh", "D,S,T", 0x46600003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psrlh", "D,S,T", 0x4b20000b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psrlw", "D,S,T", 0x46400003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psrlw", "D,S,T", 0x4b00000b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psubb", "D,S,T", 0x47c00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psubb", "D,S,T", 0x4bc00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psubh", "D,S,T", 0x47400001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psubh", "D,S,T", 0x4b400001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psubw", "D,S,T", 0x47600001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psubw", "D,S,T", 0x4b600001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psubd", "D,S,T", 0x47e00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psubd", "D,S,T", 0x4be00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psubsb", "D,S,T", 0x47800001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psubsb", "D,S,T", 0x4b800001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psubsh", "D,S,T", 0x47000001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psubsh", "D,S,T", 0x4b000001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psubusb", "D,S,T", 0x47a00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psubusb", "D,S,T", 0x4ba00001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"psubush", "D,S,T", 0x47200001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"psubush", "D,S,T", 0x4b200001, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"punpckhbh", "D,S,T", 0x47600003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"punpckhbh", "D,S,T", 0x4b600003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"punpckhhw", "D,S,T", 0x47200003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"punpckhhw", "D,S,T", 0x4b200003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"punpckhwd", "D,S,T", 0x46e00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"punpckhwd", "D,S,T", 0x4ba0000b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"punpcklbh", "D,S,T", 0x47400003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"punpcklbh", "D,S,T", 0x4b400003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"punpcklhw", "D,S,T", 0x47000003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"punpcklhw", "D,S,T", 0x4b000003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"punpcklwd", "D,S,T", 0x46c00003, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2E }, -{"punpcklwd", "D,S,T", 0x4b80000b, 0xffe0003f, RD_S|RD_T|WR_D|FP_D, 0, IL2F }, -{"sequ", "S,T", 0x46800032, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2E }, -{"sequ", "S,T", 0x4b80000c, 0xffe007ff, RD_S|RD_T|WR_CC|FP_D, 0, IL2F }, -/* No hazard protection on coprocessor instructions--they shouldn't - change the state of the processor and if they do it's up to the - user to put in nops as necessary. These are at the end so that the - disassembler recognizes more specific versions first. */ -{"c0", "C", 0x42000000, 0xfe000000, 0, 0, I1 }, -{"c1", "C", 0x46000000, 0xfe000000, 0, 0, I1 }, -{"c2", "C", 0x4a000000, 0xfe000000, 0, 0, I1 }, -{"c3", "C", 0x4e000000, 0xfe000000, 0, 0, I1 }, -{"cop0", "C", 0, (int) M_COP0, INSN_MACRO, 0, I1 }, -{"cop1", "C", 0, (int) M_COP1, INSN_MACRO, 0, I1 }, -{"cop2", "C", 0, (int) M_COP2, INSN_MACRO, 0, I1 }, -{"cop3", "C", 0, (int) M_COP3, INSN_MACRO, 0, I1 } -}; - -#define MIPS_NUM_OPCODES \ - ((sizeof mips_builtin_opcodes) / (sizeof (mips_builtin_opcodes[0]))) -const int bfd_mips_num_builtin_opcodes = MIPS_NUM_OPCODES; - -/* const removed from the following to allow for dynamic extensions to the - * built-in instruction set. */ -struct mips_opcode *mips_opcodes = - (struct mips_opcode *) mips_builtin_opcodes; -int bfd_mips_num_opcodes = MIPS_NUM_OPCODES; -#undef MIPS_NUM_OPCODES diff --git a/librz/arch/isa_gnu/mips/mips16-opc.c b/librz/arch/isa_gnu/mips/mips16-opc.c deleted file mode 100644 index a1eaeb3b325..00000000000 --- a/librz/arch/isa_gnu/mips/mips16-opc.c +++ /dev/null @@ -1,244 +0,0 @@ -/* mips16-opc.c. Mips16 opcode table. - Copyright 1996, 1997, 1998, 2000, 2005, 2007 Free Software Foundation, Inc. - Contributed by Ian Lance Taylor, Cygnus Support - - This file is part of the GNU opcodes library. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - It is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. - - You should have received a copy of the GNU General Public License - along with this file; see the file COPYING. If not, write to the - Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, - MA 02110-1301, USA. */ - -#include -#include -#include - -/* This is the opcodes table for the mips16 processor. The format of - this table is intentionally identical to the one in mips-opc.c. - However, the special letters that appear in the argument string are - different, and the table uses some different flags. */ - -/* Use some short hand macros to keep down the length of the lines in - the opcodes table. */ - -#define UBD INSN_UNCOND_BRANCH_DELAY -#define BR MIPS16_INSN_BRANCH - -#define WR_x MIPS16_INSN_WRITE_X -#define WR_y MIPS16_INSN_WRITE_Y -#define WR_z MIPS16_INSN_WRITE_Z -#define WR_T MIPS16_INSN_WRITE_T -#define WR_SP MIPS16_INSN_WRITE_SP -#define WR_31 MIPS16_INSN_WRITE_31 -#define WR_Y MIPS16_INSN_WRITE_GPR_Y - -#define RD_x MIPS16_INSN_READ_X -#define RD_y MIPS16_INSN_READ_Y -#define RD_Z MIPS16_INSN_READ_Z -#define RD_T MIPS16_INSN_READ_T -#define RD_SP MIPS16_INSN_READ_SP -#define RD_31 MIPS16_INSN_READ_31 -#define RD_PC MIPS16_INSN_READ_PC -#define RD_X MIPS16_INSN_READ_GPR_X - -#define WR_HI INSN_WRITE_HI -#define WR_LO INSN_WRITE_LO -#define RD_HI INSN_READ_HI -#define RD_LO INSN_READ_LO - -#define TRAP INSN_TRAP - -#define I1 INSN_ISA1 -#define I3 INSN_ISA3 -#define I32 INSN_ISA32 -#define I64 INSN_ISA64 -#define T3 INSN_3900 - -const struct mips_opcode mips16_opcodes[] = -{ -/* name, args, match, mask, pinfo, pinfo2, membership */ -{"nop", "", 0x6500, 0xffff, RD_Z, 0, I1 }, /* move $0,$Z */ -{"la", "x,A", 0x0800, 0xf800, WR_x|RD_PC, 0, I1 }, -{"abs", "x,w", 0, (int) M_ABS, INSN_MACRO, 0, I1 }, -{"addiu", "y,x,4", 0x4000, 0xf810, WR_y|RD_x, 0, I1 }, -{"addiu", "x,k", 0x4800, 0xf800, WR_x|RD_x, 0, I1 }, -{"addiu", "S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, I1 }, -{"addiu", "S,S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, I1 }, -{"addiu", "x,P,V", 0x0800, 0xf800, WR_x|RD_PC, 0, I1 }, -{"addiu", "x,S,V", 0x0000, 0xf800, WR_x|RD_SP, 0, I1 }, -{"addu", "z,v,y", 0xe001, 0xf803, WR_z|RD_x|RD_y, 0, I1 }, -{"addu", "y,x,4", 0x4000, 0xf810, WR_y|RD_x, 0, I1 }, -{"addu", "x,k", 0x4800, 0xf800, WR_x|RD_x, 0, I1 }, -{"addu", "S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, I1 }, -{"addu", "S,S,K", 0x6300, 0xff00, WR_SP|RD_SP, 0, I1 }, -{"addu", "x,P,V", 0x0800, 0xf800, WR_x|RD_PC, 0, I1 }, -{"addu", "x,S,V", 0x0000, 0xf800, WR_x|RD_SP, 0, I1 }, -{"and", "x,y", 0xe80c, 0xf81f, WR_x|RD_x|RD_y, 0, I1 }, -{"b", "q", 0x1000, 0xf800, BR, 0, I1 }, -{"beq", "x,y,p", 0, (int) M_BEQ, INSN_MACRO, 0, I1 }, -{"beq", "x,U,p", 0, (int) M_BEQ_I, INSN_MACRO, 0, I1 }, -{"beqz", "x,p", 0x2000, 0xf800, BR|RD_x, 0, I1 }, -{"bge", "x,y,p", 0, (int) M_BGE, INSN_MACRO, 0, I1 }, -{"bge", "x,8,p", 0, (int) M_BGE_I, INSN_MACRO, 0, I1 }, -{"bgeu", "x,y,p", 0, (int) M_BGEU, INSN_MACRO, 0, I1 }, -{"bgeu", "x,8,p", 0, (int) M_BGEU_I, INSN_MACRO, 0, I1 }, -{"bgt", "x,y,p", 0, (int) M_BGT, INSN_MACRO, 0, I1 }, -{"bgt", "x,8,p", 0, (int) M_BGT_I, INSN_MACRO, 0, I1 }, -{"bgtu", "x,y,p", 0, (int) M_BGTU, INSN_MACRO, 0, I1 }, -{"bgtu", "x,8,p", 0, (int) M_BGTU_I, INSN_MACRO, 0, I1 }, -{"ble", "x,y,p", 0, (int) M_BLE, INSN_MACRO, 0, I1 }, -{"ble", "x,8,p", 0, (int) M_BLE_I, INSN_MACRO, 0, I1 }, -{"bleu", "x,y,p", 0, (int) M_BLEU, INSN_MACRO, 0, I1 }, -{"bleu", "x,8,p", 0, (int) M_BLEU_I, INSN_MACRO, 0, I1 }, -{"blt", "x,y,p", 0, (int) M_BLT, INSN_MACRO, 0, I1 }, -{"blt", "x,8,p", 0, (int) M_BLT_I, INSN_MACRO, 0, I1 }, -{"bltu", "x,y,p", 0, (int) M_BLTU, INSN_MACRO, 0, I1 }, -{"bltu", "x,8,p", 0, (int) M_BLTU_I, INSN_MACRO, 0, I1 }, -{"bne", "x,y,p", 0, (int) M_BNE, INSN_MACRO, 0, I1 }, -{"bne", "x,U,p", 0, (int) M_BNE_I, INSN_MACRO, 0, I1 }, -{"bnez", "x,p", 0x2800, 0xf800, BR|RD_x, 0, I1 }, -{"break", "6", 0xe805, 0xf81f, TRAP, 0, I1 }, -{"bteqz", "p", 0x6000, 0xff00, BR|RD_T, 0, I1 }, -{"btnez", "p", 0x6100, 0xff00, BR|RD_T, 0, I1 }, -{"cmpi", "x,U", 0x7000, 0xf800, WR_T|RD_x, 0, I1 }, -{"cmp", "x,y", 0xe80a, 0xf81f, WR_T|RD_x|RD_y, 0, I1 }, -{"cmp", "x,U", 0x7000, 0xf800, WR_T|RD_x, 0, I1 }, -{"dla", "y,E", 0xfe00, 0xff00, WR_y|RD_PC, 0, I3 }, -{"daddiu", "y,x,4", 0x4010, 0xf810, WR_y|RD_x, 0, I3 }, -{"daddiu", "y,j", 0xfd00, 0xff00, WR_y|RD_y, 0, I3 }, -{"daddiu", "S,K", 0xfb00, 0xff00, WR_SP|RD_SP, 0, I3 }, -{"daddiu", "S,S,K", 0xfb00, 0xff00, WR_SP|RD_SP, 0, I3 }, -{"daddiu", "y,P,W", 0xfe00, 0xff00, WR_y|RD_PC, 0, I3 }, -{"daddiu", "y,S,W", 0xff00, 0xff00, WR_y|RD_SP, 0, I3 }, -{"daddu", "z,v,y", 0xe000, 0xf803, WR_z|RD_x|RD_y, 0, I3 }, -{"daddu", "y,x,4", 0x4010, 0xf810, WR_y|RD_x, 0, I3 }, -{"daddu", "y,j", 0xfd00, 0xff00, WR_y|RD_y, 0, I3 }, -{"daddu", "S,K", 0xfb00, 0xff00, WR_SP|RD_SP, 0, I3 }, -{"daddu", "S,S,K", 0xfb00, 0xff00, WR_SP|RD_SP, 0, I3 }, -{"daddu", "y,P,W", 0xfe00, 0xff00, WR_y|RD_PC, 0, I3 }, -{"daddu", "y,S,W", 0xff00, 0xff00, WR_y|RD_SP, 0, I3 }, -{"ddiv", "0,x,y", 0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, -{"ddiv", "z,v,y", 0, (int) M_DDIV_3, INSN_MACRO, 0, I1 }, -{"ddivu", "0,x,y", 0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, -{"ddivu", "z,v,y", 0, (int) M_DDIVU_3, INSN_MACRO, 0, I1 }, -{"div", "0,x,y", 0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, -{"div", "z,v,y", 0, (int) M_DIV_3, INSN_MACRO, 0, I1 }, -{"divu", "0,x,y", 0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, -{"divu", "z,v,y", 0, (int) M_DIVU_3, INSN_MACRO, 0, I1 }, -{"dmul", "z,v,y", 0, (int) M_DMUL, INSN_MACRO, 0, I3 }, -{"dmult", "x,y", 0xe81c, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, -{"dmultu", "x,y", 0xe81d, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, -{"drem", "0,x,y", 0xe81e, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, -{"drem", "z,v,y", 0, (int) M_DREM_3, INSN_MACRO, 0, I1 }, -{"dremu", "0,x,y", 0xe81f, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I3 }, -{"dremu", "z,v,y", 0, (int) M_DREMU_3, INSN_MACRO, 0, I1 }, -{"dsllv", "y,x", 0xe814, 0xf81f, WR_y|RD_y|RD_x, 0, I3 }, -{"dsll", "x,w,[", 0x3001, 0xf803, WR_x|RD_y, 0, I3 }, -{"dsll", "y,x", 0xe814, 0xf81f, WR_y|RD_y|RD_x, 0, I3 }, -{"dsrav", "y,x", 0xe817, 0xf81f, WR_y|RD_y|RD_x, 0, I3 }, -{"dsra", "y,]", 0xe813, 0xf81f, WR_y|RD_y, 0, I3 }, -{"dsra", "y,x", 0xe817, 0xf81f, WR_y|RD_y|RD_x, 0, I3 }, -{"dsrlv", "y,x", 0xe816, 0xf81f, WR_y|RD_y|RD_x, 0, I3 }, -{"dsrl", "y,]", 0xe808, 0xf81f, WR_y|RD_y, 0, I3 }, -{"dsrl", "y,x", 0xe816, 0xf81f, WR_y|RD_y|RD_x, 0, I3 }, -{"dsubu", "z,v,y", 0xe002, 0xf803, WR_z|RD_x|RD_y, 0, I3 }, -{"dsubu", "y,x,4", 0, (int) M_DSUBU_I, INSN_MACRO, 0, I1 }, -{"dsubu", "y,j", 0, (int) M_DSUBU_I_2, INSN_MACRO, 0, I1 }, -{"exit", "L", 0xed09, 0xff1f, TRAP, 0, I1 }, -{"exit", "L", 0xee09, 0xff1f, TRAP, 0, I1 }, -{"exit", "L", 0xef09, 0xff1f, TRAP, 0, I1 }, -{"entry", "l", 0xe809, 0xf81f, TRAP, 0, I1 }, -{"extend", "e", 0xf000, 0xf800, 0, 0, I1 }, -{"jalr", "x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1 }, -{"jalr", "R,x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1 }, -{"jal", "x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1 }, -{"jal", "R,x", 0xe840, 0xf8ff, UBD|WR_31|RD_x, 0, I1 }, -{"jal", "a", 0x1800, 0xfc00, UBD|WR_31, 0, I1 }, -{"jalx", "a", 0x1c00, 0xfc00, UBD|WR_31, 0, I1 }, -{"jr", "x", 0xe800, 0xf8ff, UBD|RD_x, 0, I1 }, -{"jr", "R", 0xe820, 0xffff, UBD|RD_31, 0, I1 }, -{"j", "x", 0xe800, 0xf8ff, UBD|RD_x, 0, I1 }, -{"j", "R", 0xe820, 0xffff, UBD|RD_31, 0, I1 }, -{"lb", "y,5(x)", 0x8000, 0xf800, WR_y|RD_x, 0, I1 }, -{"lbu", "y,5(x)", 0xa000, 0xf800, WR_y|RD_x, 0, I1 }, -{"ld", "y,D(x)", 0x3800, 0xf800, WR_y|RD_x, 0, I3 }, -{"ld", "y,B", 0xfc00, 0xff00, WR_y|RD_PC, 0, I3 }, -{"ld", "y,D(P)", 0xfc00, 0xff00, WR_y|RD_PC, 0, I3 }, -{"ld", "y,D(S)", 0xf800, 0xff00, WR_y|RD_SP, 0, I3 }, -{"lh", "y,H(x)", 0x8800, 0xf800, WR_y|RD_x, 0, I1 }, -{"lhu", "y,H(x)", 0xa800, 0xf800, WR_y|RD_x, 0, I1 }, -{"li", "x,U", 0x6800, 0xf800, WR_x, 0, I1 }, -{"lw", "y,W(x)", 0x9800, 0xf800, WR_y|RD_x, 0, I1 }, -{"lw", "x,A", 0xb000, 0xf800, WR_x|RD_PC, 0, I1 }, -{"lw", "x,V(P)", 0xb000, 0xf800, WR_x|RD_PC, 0, I1 }, -{"lw", "x,V(S)", 0x9000, 0xf800, WR_x|RD_SP, 0, I1 }, -{"lwu", "y,W(x)", 0xb800, 0xf800, WR_y|RD_x, 0, I3 }, -{"mfhi", "x", 0xe810, 0xf8ff, WR_x|RD_HI, 0, I1 }, -{"mflo", "x", 0xe812, 0xf8ff, WR_x|RD_LO, 0, I1 }, -{"move", "y,X", 0x6700, 0xff00, WR_y|RD_X, 0, I1 }, -{"move", "Y,Z", 0x6500, 0xff00, WR_Y|RD_Z, 0, I1 }, -{"mul", "z,v,y", 0, (int) M_MUL, INSN_MACRO, 0, I1 }, -{"mult", "x,y", 0xe818, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, -{"multu", "x,y", 0xe819, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, -{"neg", "x,w", 0xe80b, 0xf81f, WR_x|RD_y, 0, I1 }, -{"not", "x,w", 0xe80f, 0xf81f, WR_x|RD_y, 0, I1 }, -{"or", "x,y", 0xe80d, 0xf81f, WR_x|RD_x|RD_y, 0, I1 }, -{"rem", "0,x,y", 0xe81a, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, -{"rem", "z,v,y", 0, (int) M_REM_3, INSN_MACRO, 0, I1 }, -{"remu", "0,x,y", 0xe81b, 0xf81f, RD_x|RD_y|WR_HI|WR_LO, 0, I1 }, -{"remu", "z,v,y", 0, (int) M_REMU_3, INSN_MACRO, 0, I1 }, -{"sb", "y,5(x)", 0xc000, 0xf800, RD_y|RD_x, 0, I1 }, -{"sd", "y,D(x)", 0x7800, 0xf800, RD_y|RD_x, 0, I3 }, -{"sd", "y,D(S)", 0xf900, 0xff00, RD_y|RD_PC, 0, I3 }, -{"sd", "R,C(S)", 0xfa00, 0xff00, RD_31|RD_PC, 0, I1 }, -{"sh", "y,H(x)", 0xc800, 0xf800, RD_y|RD_x, 0, I1 }, -{"sllv", "y,x", 0xe804, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, -{"sll", "x,w,<", 0x3000, 0xf803, WR_x|RD_y, 0, I1 }, -{"sll", "y,x", 0xe804, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, -{"slti", "x,8", 0x5000, 0xf800, WR_T|RD_x, 0, I1 }, -{"slt", "x,y", 0xe802, 0xf81f, WR_T|RD_x|RD_y, 0, I1 }, -{"slt", "x,8", 0x5000, 0xf800, WR_T|RD_x, 0, I1 }, -{"sltiu", "x,8", 0x5800, 0xf800, WR_T|RD_x, 0, I1 }, -{"sltu", "x,y", 0xe803, 0xf81f, WR_T|RD_x|RD_y, 0, I1 }, -{"sltu", "x,8", 0x5800, 0xf800, WR_T|RD_x, 0, I1 }, -{"srav", "y,x", 0xe807, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, -{"sra", "x,w,<", 0x3003, 0xf803, WR_x|RD_y, 0, I1 }, -{"sra", "y,x", 0xe807, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, -{"srlv", "y,x", 0xe806, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, -{"srl", "x,w,<", 0x3002, 0xf803, WR_x|RD_y, 0, I1 }, -{"srl", "y,x", 0xe806, 0xf81f, WR_y|RD_y|RD_x, 0, I1 }, -{"subu", "z,v,y", 0xe003, 0xf803, WR_z|RD_x|RD_y, 0, I1 }, -{"subu", "y,x,4", 0, (int) M_SUBU_I, INSN_MACRO, 0, I1 }, -{"subu", "x,k", 0, (int) M_SUBU_I_2, INSN_MACRO,0, I1 }, -{"sw", "y,W(x)", 0xd800, 0xf800, RD_y|RD_x, 0, I1 }, -{"sw", "x,V(S)", 0xd000, 0xf800, RD_x|RD_SP, 0, I1 }, -{"sw", "R,V(S)", 0x6200, 0xff00, RD_31|RD_SP, 0, I1 }, -{"xor", "x,y", 0xe80e, 0xf81f, WR_x|RD_x|RD_y, 0, I1 }, - /* MIPS16e additions */ -{"jalrc", "x", 0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0, I32 }, -{"jalrc", "R,x", 0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0, I32 }, -{"jrc", "x", 0xe880, 0xf8ff, RD_x|TRAP, 0, I32 }, -{"jrc", "R", 0xe8a0, 0xffff, RD_31|TRAP, 0, I32 }, -{"restore", "M", 0x6400, 0xff80, WR_31|RD_SP|WR_SP|TRAP, 0, I32 }, -{"save", "m", 0x6480, 0xff80, RD_31|RD_SP|WR_SP|TRAP, 0, I32 }, -{"sdbbp", "6", 0xe801, 0xf81f, TRAP, 0, I32 }, -{"seb", "x", 0xe891, 0xf8ff, WR_x|RD_x, 0, I32 }, -{"seh", "x", 0xe8b1, 0xf8ff, WR_x|RD_x, 0, I32 }, -{"sew", "x", 0xe8d1, 0xf8ff, WR_x|RD_x, 0, I64 }, -{"zeb", "x", 0xe811, 0xf8ff, WR_x|RD_x, 0, I32 }, -{"zeh", "x", 0xe831, 0xf8ff, WR_x|RD_x, 0, I32 }, -{"zew", "x", 0xe851, 0xf8ff, WR_x|RD_x, 0, I64 }, -}; - -const int bfd_mips16_num_opcodes = - ((sizeof mips16_opcodes) / (sizeof (mips16_opcodes[0]))); diff --git a/librz/arch/meson.build b/librz/arch/meson.build index 0fd00351960..d777d98f0c3 100644 --- a/librz/arch/meson.build +++ b/librz/arch/meson.build @@ -31,7 +31,7 @@ arch_plugins_list = [ 'malbolge', 'mcore', 'mcs96', - 'mips_cs', + 'mips', 'msp430', 'null', 'or1k', @@ -88,7 +88,7 @@ arch_plugin_sources = [ 'p/arch_malbolge.c', 'p/arch_mcore.c', 'p/arch_mcs96.c', - 'p/arch_mips_cs.c', + 'p/arch_mips.c', 'p/arch_msp430.c', 'p/arch_null.c', 'p/arch_or1k.c', @@ -328,7 +328,6 @@ if get_option('use_gpl') 'cris_gnu', 'hppa_gnu', 'lanai_gnu', - 'mips_gnu', 'riscv_gnu', 'sparc_gnu', 'vax_gnu', @@ -342,7 +341,6 @@ if get_option('use_gpl') 'p_gnu/arch_cris.c', 'p_gnu/arch_hppa.c', 'p_gnu/arch_lanai.c', - 'p_gnu/arch_mips.c', 'p_gnu/arch_riscv.c', 'p_gnu/arch_sparc.c', 'p_gnu/arch_vax.c', @@ -361,9 +359,6 @@ if get_option('use_gpl') 'isa_gnu/hppa/hppa-dis.c', 'isa_gnu/lanai/lanai-dis.c', 'isa_gnu/lanai/lanai-opc.c', - 'isa_gnu/mips/mips-dis.c', - 'isa_gnu/mips/mips-opc.c', - 'isa_gnu/mips/mips16-opc.c', # 'isa_gnu/riscv/riscv-opc.c', # 'isa_gnu/riscv/riscv.c', 'isa_gnu/sparc/sparc-dis.c', diff --git a/librz/arch/p/analysis/analysis_mips_cs.c b/librz/arch/p/analysis/analysis_mips.c similarity index 78% rename from librz/arch/p/analysis/analysis_mips_cs.c rename to librz/arch/p/analysis/analysis_mips.c index af524566c6b..7675d97e972 100644 --- a/librz/arch/p/analysis/analysis_mips_cs.c +++ b/librz/arch/p/analysis/analysis_mips.c @@ -202,20 +202,20 @@ static const char *arg(csh *handle, cs_insn *insn, char *buf, int n) { static int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) { char str[8][32] = { { 0 } }; - int i; rz_strbuf_init(&op->esil); rz_strbuf_set(&op->esil, ""); - if (insn) { - // caching operands - for (i = 0; i < insn->detail->mips.op_count && i < 8; i++) { - *str[i] = 0; - ARG(i); - } + if (!insn) { + return 0; } - if (insn) { + // caching operands + for (int i = 0; i < insn->detail->mips.op_count && i < 8; i++) { + *str[i] = 0; + ARG(i); + } + { switch (insn->id) { case MIPS_INS_NOP: rz_strbuf_setf(&op->esil, ","); @@ -245,10 +245,28 @@ static int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 rz_strbuf_appendf(&op->esil, "%s,%s,=[1]", ARG(0), ARG(1)); break; +#if CS_NEXT_VERSION >= 6 + case MIPS_INS_CMPU_LE_QB: + case MIPS_INS_CMPGU_LE_QB: + case MIPS_INS_CMPGDU_LE_QB: + rz_strbuf_appendf(&op->esil, "%s,%s,<=", ARG(1), ARG(0)); + break; + case MIPS_INS_CMPU_LT_QB: + case MIPS_INS_CMPGU_LT_QB: + case MIPS_INS_CMPGDU_LT_QB: + rz_strbuf_appendf(&op->esil, "%s,%s,<", ARG(1), ARG(0)); + break; +#endif /* CS_NEXT_VERSION */ case MIPS_INS_CMP: +#if CS_NEXT_VERSION < 6 case MIPS_INS_CMPU: case MIPS_INS_CMPGU: case MIPS_INS_CMPGDU: +#else + case MIPS_INS_CMPU_EQ_QB: + case MIPS_INS_CMPGU_EQ_QB: + case MIPS_INS_CMPGDU_EQ_QB: +#endif /* CS_NEXT_VERSION */ case MIPS_INS_CMPI: rz_strbuf_appendf(&op->esil, "%s,%s,==", ARG(1), ARG(0)); break; @@ -257,16 +275,36 @@ static int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 "%s,%s,>>,31,%s,>>,?{,32,%s,32,-,0xffffffff,<<,0xffffffff,&,<<,}{,0,},|,%s,=", ARG(2), ARG(1), ARG(1), ARG(2), ARG(0)); break; +#if CS_NEXT_VERSION < 6 case MIPS_INS_SHRAV: case MIPS_INS_SHRAV_R: case MIPS_INS_SHRA: case MIPS_INS_SHRA_R: +#else + case MIPS_INS_SHRA_PH: + case MIPS_INS_SHRA_QB: + case MIPS_INS_SHRA_R_PH: + case MIPS_INS_SHRA_R_QB: + case MIPS_INS_SHRA_R_W: + case MIPS_INS_SHRAV_PH: + case MIPS_INS_SHRAV_QB: + case MIPS_INS_SHRAV_R_PH: + case MIPS_INS_SHRAV_R_QB: + case MIPS_INS_SHRAV_R_W: +#endif /* CS_NEXT_VERSION */ case MIPS_INS_SRA: rz_strbuf_appendf(&op->esil, "0xffffffff,%s,%s,>>,&,31,%s,>>,?{,%s,32,-,0xffffffff,<<,0xffffffff,&,}{,0,},|,%s,=", ARG(2), ARG(1), ARG(1), ARG(2), ARG(0)); break; +#if CS_NEXT_VERSION < 6 case MIPS_INS_SHRL: +#else + case MIPS_INS_SHRL_PH: + case MIPS_INS_SHRL_QB: + case MIPS_INS_SHRLV_PH: + case MIPS_INS_SHRLV_QB: +#endif /* CS_NEXT_VERSION */ // suffix 'S' forces conditional flag to be updated case MIPS_INS_SRLV: case MIPS_INS_SRL: @@ -320,7 +358,15 @@ static int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,%s,==,$z,?{," ES_J("%s") ",}", ARG(0), ARG(1), ARG(2)); break; +#if CS_NEXT_VERSION < 6 case MIPS_INS_BZ: +#else + case MIPS_INS_BZ_B: + case MIPS_INS_BZ_D: + case MIPS_INS_BZ_H: + case MIPS_INS_BZ_V: + case MIPS_INS_BZ_W: +#endif /* CS_NEXT_VERSION */ case MIPS_INS_BEQZ: case MIPS_INS_BEQZC: rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,0,==,$z,?{," ES_J("%s") ",}", @@ -383,7 +429,12 @@ static int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 case MIPS_INS_BTNEZ: rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,t,==,$z,!,?{," ES_J("%s") ",}", ARG(0)); break; +#if CS_NEXT_VERSION < 6 case MIPS_INS_MOV: +#else + case MIPS_INS_MOV_D: + case MIPS_INS_MOV_S: +#endif /* CS_NEXT_VERSION */ case MIPS_INS_MOVE: PROTECT_ZERO() { rz_strbuf_appendf(&op->esil, "%s,%s,=", ARG(1), REG(0)); @@ -402,7 +453,12 @@ static int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 ARG(2), ARG(1), REG(0)); } break; +#if CS_NEXT_VERSION < 6 case MIPS_INS_FSUB: +#else + case MIPS_INS_FSUB_D: + case MIPS_INS_FSUB_W: +#endif /* CS_NEXT_VERSION */ case MIPS_INS_SUB: case MIPS_INS_SUBU: case MIPS_INS_DSUB: @@ -412,8 +468,13 @@ static int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 ARG(2), ARG(1), ARG(0)); } break; - case MIPS_INS_NEG: +#if CS_NEXT_VERSION < 6 case MIPS_INS_NEGU: +#else + case MIPS_INS_NEG_D: + case MIPS_INS_NEG_S: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_NEG: rz_strbuf_appendf(&op->esil, "%s,0,-,%s,=,", ARG(1), ARG(0)); break; @@ -452,7 +513,14 @@ static int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 } } break; case MIPS_INS_LI: +#if CS_NEXT_VERSION < 6 case MIPS_INS_LDI: +#else + case MIPS_INS_LDI_B: + case MIPS_INS_LDI_D: + case MIPS_INS_LDI_H: + case MIPS_INS_LDI_W: +#endif /* CS_NEXT_VERSION */ rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,=", (ut64)IMM(1), ARG(0)); break; case MIPS_INS_LUI: @@ -578,18 +646,6 @@ static int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 rz_strbuf_appendf(&op->esil, "%s,hi,=", REG(0)); ES_SIGN32_64("hi"); break; -#if 0 - // could not test div - case MIPS_INS_DIV: - case MIPS_INS_DIVU: - case MIPS_INS_DDIV: - case MIPS_INS_DDIVU: - PROTECT_ZERO () { - // 32 bit needs sign extend - rz_strbuf_appendf (&op->esil, "%s,%s,/,lo,=,%s,%s,%%,hi,=", REG(1), REG(0), REG(1), REG(0)); - } - break; -#endif default: return -1; } @@ -790,302 +846,6 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u case MIPS_INS_INVALID: op->type = RZ_ANALYSIS_OP_TYPE_ILL; break; - case MIPS_INS_LB: - case MIPS_INS_LBU: - case MIPS_INS_LBUX: - op->refptr = 1; - /* fallthrough */ - case MIPS_INS_LW: - case MIPS_INS_LWC1: - case MIPS_INS_LWC2: - case MIPS_INS_LWL: - case MIPS_INS_LWR: - case MIPS_INS_LWXC1: - if (!op->refptr) { - op->refptr = 4; - } - /* fallthrough */ - case MIPS_INS_LD: - case MIPS_INS_LDC1: - case MIPS_INS_LDC2: - case MIPS_INS_LDL: - case MIPS_INS_LDR: - case MIPS_INS_LDXC1: - op->type = RZ_ANALYSIS_OP_TYPE_LOAD; - if (!op->refptr) { - op->refptr = 8; - } - switch (OPERAND(1).type) { - case MIPS_OP_MEM: - if (OPERAND(1).mem.base == MIPS_REG_GP) { - op->ptr = analysis->gp + OPERAND(1).mem.disp; - if (REGID(0) == MIPS_REG_T9) { - t9_pre = op->ptr; - } - } else if (REGID(0) == MIPS_REG_T9) { - t9_pre = UT64_MAX; - } - break; - case MIPS_OP_IMM: - op->ptr = OPERAND(1).imm; - break; - case MIPS_OP_REG: - break; - default: - break; - } - // TODO: fill - break; - case MIPS_INS_SD: - case MIPS_INS_SW: - case MIPS_INS_SB: - case MIPS_INS_SH: - case MIPS_INS_SWC1: - case MIPS_INS_SWC2: - case MIPS_INS_SWL: - case MIPS_INS_SWR: - case MIPS_INS_SWXC1: - op->type = RZ_ANALYSIS_OP_TYPE_STORE; - break; - case MIPS_INS_NOP: - op->type = RZ_ANALYSIS_OP_TYPE_NOP; - break; - case MIPS_INS_SYSCALL: - op->type = RZ_ANALYSIS_OP_TYPE_SWI; - break; - case MIPS_INS_BREAK: - op->type = RZ_ANALYSIS_OP_TYPE_TRAP; - break; - case MIPS_INS_JALR: - op->type = RZ_ANALYSIS_OP_TYPE_UCALL; - op->delay = 1; - if (REGID(0) == MIPS_REG_25) { - op->jump = t9_pre; - t9_pre = UT64_MAX; - op->type = RZ_ANALYSIS_OP_TYPE_RCALL; - } - break; - case MIPS_INS_JAL: - case MIPS_INS_JALS: - case MIPS_INS_JALX: - case MIPS_INS_JRADDIUSP: - case MIPS_INS_BAL: - // (no blezal/bgtzal or blezall/bgtzall, only blezalc/bgtzalc) - case MIPS_INS_BLTZAL: // Branch on <0 and link - case MIPS_INS_BGEZAL: // Branch on >=0 and link - case MIPS_INS_BLTZALL: // "likely" versions - case MIPS_INS_BGEZALL: - case MIPS_INS_BLTZALC: // compact versions - case MIPS_INS_BLEZALC: - case MIPS_INS_BGEZALC: - case MIPS_INS_BGTZALC: - case MIPS_INS_JIALC: - case MIPS_INS_JIC: - op->type = RZ_ANALYSIS_OP_TYPE_CALL; - op->jump = IMM(0); - - switch (insn->id) { - case MIPS_INS_JIALC: - case MIPS_INS_JIC: - case MIPS_INS_BLTZALC: - case MIPS_INS_BLEZALC: - case MIPS_INS_BGEZALC: - case MIPS_INS_BGTZALC: - // compact versions (no delay) - op->delay = 0; - op->fail = addr + 4; - break; - default: - op->delay = 1; - op->fail = addr + 8; - break; - } - break; - case MIPS_INS_LI: - case MIPS_INS_LUI: - SET_VAL(op, 1); - op->type = RZ_ANALYSIS_OP_TYPE_MOV; - break; - case MIPS_INS_MOVE: - op->type = RZ_ANALYSIS_OP_TYPE_MOV; - break; - case MIPS_INS_ADD: - case MIPS_INS_ADDI: - case MIPS_INS_ADDU: - case MIPS_INS_ADDIU: - case MIPS_INS_DADD: - case MIPS_INS_DADDI: - case MIPS_INS_DADDIU: - SET_VAL(op, 2); - op->sign = (insn->id == MIPS_INS_ADDI || insn->id == MIPS_INS_ADD); - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - if (REGID(0) == MIPS_REG_T9) { - t9_pre += IMM(2); - } - if (REGID(0) == MIPS_REG_SP) { - op->stackop = RZ_ANALYSIS_STACK_INC; - op->stackptr = -IMM(2); - } - break; - case MIPS_INS_SUB: - case MIPS_INS_SUBV: - case MIPS_INS_SUBVI: - case MIPS_INS_DSUBU: - case MIPS_INS_FSUB: - case MIPS_INS_FMSUB: - case MIPS_INS_SUBU: - case MIPS_INS_DSUB: - case MIPS_INS_SUBS_S: - case MIPS_INS_SUBS_U: - case MIPS_INS_SUBUH: - case MIPS_INS_SUBUH_R: - SET_VAL(op, 2); - op->sign = insn->id == MIPS_INS_SUB; - op->type = RZ_ANALYSIS_OP_TYPE_SUB; - break; - case MIPS_INS_MULV: - case MIPS_INS_MULT: - case MIPS_INS_MULSA: - case MIPS_INS_FMUL: - case MIPS_INS_MUL: - case MIPS_INS_DMULT: - case MIPS_INS_DMULTU: - op->type = RZ_ANALYSIS_OP_TYPE_MUL; - break; - case MIPS_INS_XOR: - case MIPS_INS_XORI: - SET_VAL(op, 2); - op->type = RZ_ANALYSIS_OP_TYPE_XOR; - break; - case MIPS_INS_AND: - case MIPS_INS_ANDI: - SET_VAL(op, 2); - op->type = RZ_ANALYSIS_OP_TYPE_AND; - if (REGID(0) == MIPS_REG_SP) { - op->stackop = RZ_ANALYSIS_STACK_ALIGN; - } - break; - case MIPS_INS_NOT: - op->type = RZ_ANALYSIS_OP_TYPE_NOT; - break; - case MIPS_INS_OR: - case MIPS_INS_ORI: - SET_VAL(op, 2); - op->type = RZ_ANALYSIS_OP_TYPE_OR; - break; - case MIPS_INS_DIV: - case MIPS_INS_DIVU: - case MIPS_INS_DDIV: - case MIPS_INS_DDIVU: - case MIPS_INS_FDIV: - case MIPS_INS_DIV_S: - case MIPS_INS_DIV_U: - op->type = RZ_ANALYSIS_OP_TYPE_DIV; - break; - case MIPS_INS_CMPGDU: - case MIPS_INS_CMPGU: - case MIPS_INS_CMPU: - case MIPS_INS_CMPI: - op->type = RZ_ANALYSIS_OP_TYPE_CMP; - break; - case MIPS_INS_J: - case MIPS_INS_B: - case MIPS_INS_BZ: - case MIPS_INS_BEQ: - case MIPS_INS_BNZ: - case MIPS_INS_BNE: - case MIPS_INS_BNEL: - case MIPS_INS_BEQL: - case MIPS_INS_BEQZ: - case MIPS_INS_BNEG: - case MIPS_INS_BNEGI: - case MIPS_INS_BNEZ: - case MIPS_INS_BTEQZ: - case MIPS_INS_BTNEZ: - case MIPS_INS_BLTZ: - case MIPS_INS_BLTZL: - case MIPS_INS_BLEZ: - case MIPS_INS_BLEZL: - case MIPS_INS_BGEZ: - case MIPS_INS_BGEZL: - case MIPS_INS_BGTZ: - case MIPS_INS_BGTZL: - case MIPS_INS_BLEZC: - case MIPS_INS_BGEZC: - case MIPS_INS_BLTZC: - case MIPS_INS_BGTZC: - if (insn->id == MIPS_INS_J || insn->id == MIPS_INS_B) { - op->type = RZ_ANALYSIS_OP_TYPE_JMP; - } else { - op->type = RZ_ANALYSIS_OP_TYPE_CJMP; - } - - if (OPERAND(0).type == MIPS_OP_IMM) { - op->jump = IMM(0); - } else if (OPERAND(1).type == MIPS_OP_IMM) { - op->jump = IMM(1); - } else if (OPERAND(2).type == MIPS_OP_IMM) { - op->jump = IMM(2); - } - - switch (insn->id) { - case MIPS_INS_BLEZC: - case MIPS_INS_BGEZC: - case MIPS_INS_BLTZC: - case MIPS_INS_BGTZC: - // compact versions (no delay) - op->delay = 0; - op->fail = addr + 4; - break; - default: - op->delay = 1; - op->fail = addr + 8; - break; - } - - break; - case MIPS_INS_JR: - case MIPS_INS_JRC: - op->type = RZ_ANALYSIS_OP_TYPE_RJMP; - op->delay = 1; - // register is $ra, so jmp is a return - if (insn->detail->mips.operands[0].reg == MIPS_REG_RA) { - op->type = RZ_ANALYSIS_OP_TYPE_RET; - t9_pre = UT64_MAX; - } - if (REGID(0) == MIPS_REG_25) { - op->jump = t9_pre; - t9_pre = UT64_MAX; - } - - break; - case MIPS_INS_SLT: - case MIPS_INS_SLTI: - op->sign = true; - SET_VAL(op, 2); - break; - case MIPS_INS_SLTIU: - SET_VAL(op, 2); - break; - case MIPS_INS_SHRAV: - case MIPS_INS_SHRAV_R: - case MIPS_INS_SHRA: - case MIPS_INS_SHRA_R: - case MIPS_INS_SRA: - op->type = RZ_ANALYSIS_OP_TYPE_SAR; - SET_VAL(op, 2); - break; - case MIPS_INS_SHRL: - case MIPS_INS_SRLV: - case MIPS_INS_SRL: - op->type = RZ_ANALYSIS_OP_TYPE_SHR; - SET_VAL(op, 2); - break; - case MIPS_INS_SLLV: - case MIPS_INS_SLL: - op->type = RZ_ANALYSIS_OP_TYPE_SHL; - SET_VAL(op, 2); - break; } beach: set_opdir(op); @@ -1244,7 +1004,7 @@ static bool mips_fini(void *user) { return true; } -RzAnalysisPlugin rz_analysis_plugin_mips_cs = { +RzAnalysisPlugin rz_analysis_plugin_mips = { .name = "mips", .desc = "Capstone MIPS analyzer", .license = "BSD", @@ -1262,7 +1022,7 @@ RzAnalysisPlugin rz_analysis_plugin_mips_cs = { #ifndef RZ_PLUGIN_INCORE RZ_API RzLibStruct rizin_plugin = { .type = RZ_LIB_TYPE_ANALYSIS, - .data = &rz_analysis_plugin_mips_cs, + .data = &rz_analysis_plugin_mips, .version = RZ_VERSION }; #endif diff --git a/librz/arch/p/arch_mips_cs.c b/librz/arch/p/arch_mips.c similarity index 65% rename from librz/arch/p/arch_mips_cs.c rename to librz/arch/p/arch_mips.c index 17e9614c4dd..aace852c432 100644 --- a/librz/arch/p/arch_mips_cs.c +++ b/librz/arch/p/arch_mips.c @@ -4,8 +4,8 @@ #include -#include "analysis/analysis_mips_cs.c" -#include "asm/asm_mips_cs.c" +#include "analysis/analysis_mips.c" +#include "asm/asm_mips.c" #include "parse/parse_mips_pseudo.c" -RZ_ARCH_WITH_PARSE_PLUGIN_DEFINE_DEPRECATED(mips_cs); +RZ_ARCH_WITH_PARSE_PLUGIN_DEFINE_DEPRECATED(mips); diff --git a/librz/arch/p/asm/asm_mips_cs.c b/librz/arch/p/asm/asm_mips.c similarity index 97% rename from librz/arch/p/asm/asm_mips_cs.c rename to librz/arch/p/asm/asm_mips.c index 94c675c24c4..6cc47f26d0b 100644 --- a/librz/arch/p/asm/asm_mips_cs.c +++ b/librz/arch/p/asm/asm_mips.c @@ -85,7 +85,7 @@ static int mips_assemble(RzAsm *a, RzAsmOp *op, const char *str) { return ret; } -RzAsmPlugin rz_asm_plugin_mips_cs = { +RzAsmPlugin rz_asm_plugin_mips = { .name = "mips", .desc = "Capstone MIPS disassembler", .license = "BSD", @@ -103,7 +103,7 @@ RzAsmPlugin rz_asm_plugin_mips_cs = { #ifndef RZ_PLUGIN_INCORE RZ_API RzLibStruct rizin_plugin = { .type = RZ_LIB_TYPE_ASM, - .data = &rz_asm_plugin_mips_cs, + .data = &rz_asm_plugin_mips, .version = RZ_VERSION }; #endif diff --git a/librz/arch/p/parse/parse_mips_pseudo.c b/librz/arch/p/parse/parse_mips_pseudo.c index 8d10c8e15e2..45b4562bd68 100644 --- a/librz/arch/p/parse/parse_mips_pseudo.c +++ b/librz/arch/p/parse/parse_mips_pseudo.c @@ -253,7 +253,7 @@ static bool subvar(RzParse *p, RzAnalysisFunction *f, RzAnalysisOp *op, char *da return ret; } -RzParsePlugin rz_parse_plugin_mips_cs_pseudo = { +RzParsePlugin rz_parse_plugin_mips_pseudo = { .name = "mips.pseudo", .desc = "MIPS pseudo syntax", .init = NULL, diff --git a/librz/arch/p_gnu/analysis/analysis_mips_gnu.c b/librz/arch/p_gnu/analysis/analysis_mips_gnu.c index b925efffddd..8b137891791 100644 --- a/librz/arch/p_gnu/analysis/analysis_mips_gnu.c +++ b/librz/arch/p_gnu/analysis/analysis_mips_gnu.c @@ -1,1800 +1 @@ -// SPDX-FileCopyrightText: 2010-2015 pancake -// SPDX-License-Identifier: LGPL-3.0-only -#include -#include -#include -#include -#include - -static ut64 t9_pre = UT64_MAX; -#define REG_BUF_MAX 32 -// ESIL macros: - -// put the sign bit on the stack -#define ES_IS_NEGATIVE(arg) "1," arg ",<<<,1,&" - -#define ES_B(x) "0xff," x ",&" -#define ES_H(x) "0xffff," x ",&" -#define ES_W(x) "0xffffffff," x ",&" -// call with delay slot -#define ES_CALL_DR(ra, addr) "pc,4,+," ra ",=," ES_J(addr) -#define ES_CALL_D(addr) ES_CALL_DR("ra", addr) - -// call without delay slot -#define ES_CALL_NDR(ra, addr) "pc," ra ",=," ES_J(addr) -#define ES_CALL_ND(addr) ES_CALL_NDR("ra", addr) - -#define USE_DS 0 -#if USE_DS -// emit ERR trap if executed in a delay slot -#define ES_TRAP_DS() "$ds,!,!,?{,$$,1,TRAP,BREAK,}," -// jump to address -#define ES_J(addr) addr ",SETJT,1,SETD" -#else -#define ES_TRAP_DS() "" -#define ES_J(addr) addr ",pc,=" -#endif - -#define ES_SIGN32_64(arg) es_sign_n_64(a, op, arg, 32) -#define ES_SIGN16_64(arg) es_sign_n_64(a, op, arg, 16) - -#define ES_ADD_CK32_OVERF(x, y, z) es_add_ck(op, x, y, z, 32) -#define ES_ADD_CK64_OVERF(x, y, z) es_add_ck(op, x, y, z, 64) - -static inline void es_sign_n_64(RzAnalysis *a, RzAnalysisOp *op, const char *arg, int bit) { - if (a->bits == 64) { - rz_strbuf_appendf(&op->esil, ",%d,%s,~,%s,=,", bit, arg, arg); - } else { - rz_strbuf_append(&op->esil, ","); - } -} - -static inline void es_add_ck(RzAnalysisOp *op, const char *a1, const char *a2, const char *re, int bit) { - ut64 mask = 1ULL << (bit - 1); - rz_strbuf_appendf(&op->esil, - "%d,0x%" PFMT64x ",%s,%s,^,&,>>,%d,0x%" PFMT64x ",%s,%s,+,&,>>,|,1,==,$z,?{,$$,1,TRAP,}{,%s,%s,+,%s,=,}", - bit - 2, mask, a1, a2, bit - 1, mask, a1, a2, a1, a2, re); -} -// MIPS instruction -typedef enum mips_insn { - MIPS_INS_INVALID = 0, - - MIPS_INS_ABSQ_S, - MIPS_INS_ADD, - MIPS_INS_ADDIUPC, - MIPS_INS_ADDIUR1SP, - MIPS_INS_ADDIUR2, - MIPS_INS_ADDIUS5, - MIPS_INS_ADDIUSP, - MIPS_INS_ADDQH, - MIPS_INS_ADDQH_R, - MIPS_INS_ADDQ, - MIPS_INS_ADDQ_S, - MIPS_INS_ADDSC, - MIPS_INS_ADDS_A, - MIPS_INS_ADDS_S, - MIPS_INS_ADDS_U, - MIPS_INS_ADDU16, - MIPS_INS_ADDUH, - MIPS_INS_ADDUH_R, - MIPS_INS_ADDU, - MIPS_INS_ADDU_S, - MIPS_INS_ADDVI, - MIPS_INS_ADDV, - MIPS_INS_ADDWC, - MIPS_INS_ADD_A, - MIPS_INS_ADDI, - MIPS_INS_ADDIU, - MIPS_INS_ALIGN, - MIPS_INS_ALUIPC, - MIPS_INS_AND, - MIPS_INS_AND16, - MIPS_INS_ANDI16, - MIPS_INS_ANDI, - MIPS_INS_APPEND, - MIPS_INS_ASUB_S, - MIPS_INS_ASUB_U, - MIPS_INS_AUI, - MIPS_INS_AUIPC, - MIPS_INS_AVER_S, - MIPS_INS_AVER_U, - MIPS_INS_AVE_S, - MIPS_INS_AVE_U, - MIPS_INS_B16, - MIPS_INS_BADDU, - MIPS_INS_BAL, - MIPS_INS_BALC, - MIPS_INS_BALIGN, - MIPS_INS_BBIT0, - MIPS_INS_BBIT032, - MIPS_INS_BBIT1, - MIPS_INS_BBIT132, - MIPS_INS_BC, - MIPS_INS_BC0F, - MIPS_INS_BC0FL, - MIPS_INS_BC0T, - MIPS_INS_BC0TL, - MIPS_INS_BC1EQZ, - MIPS_INS_BC1F, - MIPS_INS_BC1FL, - MIPS_INS_BC1NEZ, - MIPS_INS_BC1T, - MIPS_INS_BC1TL, - MIPS_INS_BC2EQZ, - MIPS_INS_BC2F, - MIPS_INS_BC2FL, - MIPS_INS_BC2NEZ, - MIPS_INS_BC2T, - MIPS_INS_BC2TL, - MIPS_INS_BC3F, - MIPS_INS_BC3FL, - MIPS_INS_BC3T, - MIPS_INS_BC3TL, - MIPS_INS_BCLRI, - MIPS_INS_BCLR, - MIPS_INS_BEQ, - MIPS_INS_BEQC, - MIPS_INS_BEQL, - MIPS_INS_BEQZ16, - MIPS_INS_BEQZALC, - MIPS_INS_BEQZC, - MIPS_INS_BGEC, - MIPS_INS_BGEUC, - MIPS_INS_BGEZ, - MIPS_INS_BGEZAL, - MIPS_INS_BGEZALC, - MIPS_INS_BGEZALL, - MIPS_INS_BGEZALS, - MIPS_INS_BGEZC, - MIPS_INS_BGEZL, - MIPS_INS_BGTZ, - MIPS_INS_BGTZALC, - MIPS_INS_BGTZC, - MIPS_INS_BGTZL, - MIPS_INS_BINSLI, - MIPS_INS_BINSL, - MIPS_INS_BINSRI, - MIPS_INS_BINSR, - MIPS_INS_BITREV, - MIPS_INS_BITSWAP, - MIPS_INS_BLEZ, - MIPS_INS_BLEZALC, - MIPS_INS_BLEZC, - MIPS_INS_BLEZL, - MIPS_INS_BLTC, - MIPS_INS_BLTUC, - MIPS_INS_BLTZ, - MIPS_INS_BLTZAL, - MIPS_INS_BLTZALC, - MIPS_INS_BLTZALL, - MIPS_INS_BLTZALS, - MIPS_INS_BLTZC, - MIPS_INS_BLTZL, - MIPS_INS_BMNZI, - MIPS_INS_BMNZ, - MIPS_INS_BMZI, - MIPS_INS_BMZ, - MIPS_INS_BNE, - MIPS_INS_BNEC, - MIPS_INS_BNEGI, - MIPS_INS_BNEG, - MIPS_INS_BNEL, - MIPS_INS_BNEZ16, - MIPS_INS_BNEZALC, - MIPS_INS_BNEZC, - MIPS_INS_BNVC, - MIPS_INS_BNZ, - MIPS_INS_BOVC, - MIPS_INS_BPOSGE32, - MIPS_INS_BREAK, - MIPS_INS_BREAK16, - MIPS_INS_BSELI, - MIPS_INS_BSEL, - MIPS_INS_BSETI, - MIPS_INS_BSET, - MIPS_INS_BZ, - MIPS_INS_BEQZ, - MIPS_INS_B, - MIPS_INS_BNEZ, - MIPS_INS_BTEQZ, - MIPS_INS_BTNEZ, - MIPS_INS_CACHE, - MIPS_INS_CEIL, - MIPS_INS_CEQI, - MIPS_INS_CEQ, - MIPS_INS_CFC1, - MIPS_INS_CFCMSA, - MIPS_INS_CINS, - MIPS_INS_CINS32, - MIPS_INS_CLASS, - MIPS_INS_CLEI_S, - MIPS_INS_CLEI_U, - MIPS_INS_CLE_S, - MIPS_INS_CLE_U, - MIPS_INS_CLO, - MIPS_INS_CLTI_S, - MIPS_INS_CLTI_U, - MIPS_INS_CLT_S, - MIPS_INS_CLT_U, - MIPS_INS_CLZ, - MIPS_INS_CMPGDU, - MIPS_INS_CMPGU, - MIPS_INS_CMPU, - MIPS_INS_CMP, - MIPS_INS_COPY_S, - MIPS_INS_COPY_U, - MIPS_INS_CTC1, - MIPS_INS_CTCMSA, - MIPS_INS_CVT, - MIPS_INS_C, - MIPS_INS_CMPI, - MIPS_INS_DADD, - MIPS_INS_DADDI, - MIPS_INS_DADDIU, - MIPS_INS_DADDU, - MIPS_INS_DAHI, - MIPS_INS_DALIGN, - MIPS_INS_DATI, - MIPS_INS_DAUI, - MIPS_INS_DBITSWAP, - MIPS_INS_DCLO, - MIPS_INS_DCLZ, - MIPS_INS_DDIV, - MIPS_INS_DDIVU, - MIPS_INS_DERET, - MIPS_INS_DEXT, - MIPS_INS_DEXTM, - MIPS_INS_DEXTU, - MIPS_INS_DI, - MIPS_INS_DINS, - MIPS_INS_DINSM, - MIPS_INS_DINSU, - MIPS_INS_DIV, - MIPS_INS_DIVU, - MIPS_INS_DIV_S, - MIPS_INS_DIV_U, - MIPS_INS_DLSA, - MIPS_INS_DMFC0, - MIPS_INS_DMFC1, - MIPS_INS_DMFC2, - MIPS_INS_DMOD, - MIPS_INS_DMODU, - MIPS_INS_DMTC0, - MIPS_INS_DMTC1, - MIPS_INS_DMTC2, - MIPS_INS_DMUH, - MIPS_INS_DMUHU, - MIPS_INS_DMUL, - MIPS_INS_DMULT, - MIPS_INS_DMULTU, - MIPS_INS_DMULU, - MIPS_INS_DOTP_S, - MIPS_INS_DOTP_U, - MIPS_INS_DPADD_S, - MIPS_INS_DPADD_U, - MIPS_INS_DPAQX_SA, - MIPS_INS_DPAQX_S, - MIPS_INS_DPAQ_SA, - MIPS_INS_DPAQ_S, - MIPS_INS_DPAU, - MIPS_INS_DPAX, - MIPS_INS_DPA, - MIPS_INS_DPOP, - MIPS_INS_DPSQX_SA, - MIPS_INS_DPSQX_S, - MIPS_INS_DPSQ_SA, - MIPS_INS_DPSQ_S, - MIPS_INS_DPSUB_S, - MIPS_INS_DPSUB_U, - MIPS_INS_DPSU, - MIPS_INS_DPSX, - MIPS_INS_DPS, - MIPS_INS_DROTR, - MIPS_INS_DROTR32, - MIPS_INS_DROTRV, - MIPS_INS_DSBH, - MIPS_INS_DSHD, - MIPS_INS_DSLL, - MIPS_INS_DSLL32, - MIPS_INS_DSLLV, - MIPS_INS_DSRA, - MIPS_INS_DSRA32, - MIPS_INS_DSRAV, - MIPS_INS_DSRL, - MIPS_INS_DSRL32, - MIPS_INS_DSRLV, - MIPS_INS_DSUB, - MIPS_INS_DSUBU, - MIPS_INS_EHB, - MIPS_INS_EI, - MIPS_INS_ERET, - MIPS_INS_EXT, - MIPS_INS_EXTP, - MIPS_INS_EXTPDP, - MIPS_INS_EXTPDPV, - MIPS_INS_EXTPV, - MIPS_INS_EXTRV_RS, - MIPS_INS_EXTRV_R, - MIPS_INS_EXTRV_S, - MIPS_INS_EXTRV, - MIPS_INS_EXTR_RS, - MIPS_INS_EXTR_R, - MIPS_INS_EXTR_S, - MIPS_INS_EXTR, - MIPS_INS_EXTS, - MIPS_INS_EXTS32, - MIPS_INS_ABS, - MIPS_INS_FADD, - MIPS_INS_FCAF, - MIPS_INS_FCEQ, - MIPS_INS_FCLASS, - MIPS_INS_FCLE, - MIPS_INS_FCLT, - MIPS_INS_FCNE, - MIPS_INS_FCOR, - MIPS_INS_FCUEQ, - MIPS_INS_FCULE, - MIPS_INS_FCULT, - MIPS_INS_FCUNE, - MIPS_INS_FCUN, - MIPS_INS_FDIV, - MIPS_INS_FEXDO, - MIPS_INS_FEXP2, - MIPS_INS_FEXUPL, - MIPS_INS_FEXUPR, - MIPS_INS_FFINT_S, - MIPS_INS_FFINT_U, - MIPS_INS_FFQL, - MIPS_INS_FFQR, - MIPS_INS_FILL, - MIPS_INS_FLOG2, - MIPS_INS_FLOOR, - MIPS_INS_FMADD, - MIPS_INS_FMAX_A, - MIPS_INS_FMAX, - MIPS_INS_FMIN_A, - MIPS_INS_FMIN, - MIPS_INS_MOV, - MIPS_INS_FMSUB, - MIPS_INS_FMUL, - MIPS_INS_MUL, - MIPS_INS_NEG, - MIPS_INS_FRCP, - MIPS_INS_FRINT, - MIPS_INS_FRSQRT, - MIPS_INS_FSAF, - MIPS_INS_FSEQ, - MIPS_INS_FSLE, - MIPS_INS_FSLT, - MIPS_INS_FSNE, - MIPS_INS_FSOR, - MIPS_INS_FSQRT, - MIPS_INS_SQRT, - MIPS_INS_FSUB, - MIPS_INS_SUB, - MIPS_INS_FSUEQ, - MIPS_INS_FSULE, - MIPS_INS_FSULT, - MIPS_INS_FSUNE, - MIPS_INS_FSUN, - MIPS_INS_FTINT_S, - MIPS_INS_FTINT_U, - MIPS_INS_FTQ, - MIPS_INS_FTRUNC_S, - MIPS_INS_FTRUNC_U, - MIPS_INS_HADD_S, - MIPS_INS_HADD_U, - MIPS_INS_HSUB_S, - MIPS_INS_HSUB_U, - MIPS_INS_ILVEV, - MIPS_INS_ILVL, - MIPS_INS_ILVOD, - MIPS_INS_ILVR, - MIPS_INS_INS, - MIPS_INS_INSERT, - MIPS_INS_INSV, - MIPS_INS_INSVE, - MIPS_INS_J, - MIPS_INS_JAL, - MIPS_INS_JALR, - MIPS_INS_JALRS16, - MIPS_INS_JALRS, - MIPS_INS_JALS, - MIPS_INS_JALX, - MIPS_INS_JIALC, - MIPS_INS_JIC, - MIPS_INS_JR, - MIPS_INS_JR16, - MIPS_INS_JRADDIUSP, - MIPS_INS_JRC, - MIPS_INS_JALRC, - MIPS_INS_LB, - MIPS_INS_LBU16, - MIPS_INS_LBUX, - MIPS_INS_LBU, - MIPS_INS_LD, - MIPS_INS_LDC1, - MIPS_INS_LDC2, - MIPS_INS_LDC3, - MIPS_INS_LDI, - MIPS_INS_LDL, - MIPS_INS_LDPC, - MIPS_INS_LDR, - MIPS_INS_LDXC1, - MIPS_INS_LH, - MIPS_INS_LHU16, - MIPS_INS_LHX, - MIPS_INS_LHU, - MIPS_INS_LI16, - MIPS_INS_LL, - MIPS_INS_LLD, - MIPS_INS_LSA, - MIPS_INS_LUXC1, - MIPS_INS_LUI, - MIPS_INS_LW, - MIPS_INS_LW16, - MIPS_INS_LWC1, - MIPS_INS_LWC2, - MIPS_INS_LWC3, - MIPS_INS_LWL, - MIPS_INS_LWM16, - MIPS_INS_LWM32, - MIPS_INS_LWPC, - MIPS_INS_LWP, - MIPS_INS_LWR, - MIPS_INS_LWUPC, - MIPS_INS_LWU, - MIPS_INS_LWX, - MIPS_INS_LWXC1, - MIPS_INS_LWXS, - MIPS_INS_LI, - MIPS_INS_MADD, - MIPS_INS_MADDF, - MIPS_INS_MADDR_Q, - MIPS_INS_MADDU, - MIPS_INS_MADDV, - MIPS_INS_MADD_Q, - MIPS_INS_MAQ_SA, - MIPS_INS_MAQ_S, - MIPS_INS_MAXA, - MIPS_INS_MAXI_S, - MIPS_INS_MAXI_U, - MIPS_INS_MAX_A, - MIPS_INS_MAX, - MIPS_INS_MAX_S, - MIPS_INS_MAX_U, - MIPS_INS_MFC0, - MIPS_INS_MFC1, - MIPS_INS_MFC2, - MIPS_INS_MFHC1, - MIPS_INS_MFHI, - MIPS_INS_MFLO, - MIPS_INS_MINA, - MIPS_INS_MINI_S, - MIPS_INS_MINI_U, - MIPS_INS_MIN_A, - MIPS_INS_MIN, - MIPS_INS_MIN_S, - MIPS_INS_MIN_U, - MIPS_INS_MOD, - MIPS_INS_MODSUB, - MIPS_INS_MODU, - MIPS_INS_MOD_S, - MIPS_INS_MOD_U, - MIPS_INS_MOVE, - MIPS_INS_MOVEP, - MIPS_INS_MOVF, - MIPS_INS_MOVN, - MIPS_INS_MOVT, - MIPS_INS_MOVZ, - MIPS_INS_MSUB, - MIPS_INS_MSUBF, - MIPS_INS_MSUBR_Q, - MIPS_INS_MSUBU, - MIPS_INS_MSUBV, - MIPS_INS_MSUB_Q, - MIPS_INS_MTC0, - MIPS_INS_MTC1, - MIPS_INS_MTC2, - MIPS_INS_MTHC1, - MIPS_INS_MTHI, - MIPS_INS_MTHLIP, - MIPS_INS_MTLO, - MIPS_INS_MTM0, - MIPS_INS_MTM1, - MIPS_INS_MTM2, - MIPS_INS_MTP0, - MIPS_INS_MTP1, - MIPS_INS_MTP2, - MIPS_INS_MUH, - MIPS_INS_MUHU, - MIPS_INS_MULEQ_S, - MIPS_INS_MULEU_S, - MIPS_INS_MULQ_RS, - MIPS_INS_MULQ_S, - MIPS_INS_MULR_Q, - MIPS_INS_MULSAQ_S, - MIPS_INS_MULSA, - MIPS_INS_MULT, - MIPS_INS_MULTU, - MIPS_INS_MULU, - MIPS_INS_MULV, - MIPS_INS_MUL_Q, - MIPS_INS_MUL_S, - MIPS_INS_NLOC, - MIPS_INS_NLZC, - MIPS_INS_NMADD, - MIPS_INS_NMSUB, - MIPS_INS_NOR, - MIPS_INS_NORI, - MIPS_INS_NOT16, - MIPS_INS_NOT, - MIPS_INS_OR, - MIPS_INS_OR16, - MIPS_INS_ORI, - MIPS_INS_PACKRL, - MIPS_INS_PAUSE, - MIPS_INS_PCKEV, - MIPS_INS_PCKOD, - MIPS_INS_PCNT, - MIPS_INS_PICK, - MIPS_INS_POP, - MIPS_INS_PRECEQU, - MIPS_INS_PRECEQ, - MIPS_INS_PRECEU, - MIPS_INS_PRECRQU_S, - MIPS_INS_PRECRQ, - MIPS_INS_PRECRQ_RS, - MIPS_INS_PRECR, - MIPS_INS_PRECR_SRA, - MIPS_INS_PRECR_SRA_R, - MIPS_INS_PREF, - MIPS_INS_PREPEND, - MIPS_INS_RADDU, - MIPS_INS_RDDSP, - MIPS_INS_RDHWR, - MIPS_INS_REPLV, - MIPS_INS_REPL, - MIPS_INS_RINT, - MIPS_INS_ROTR, - MIPS_INS_ROTRV, - MIPS_INS_ROUND, - MIPS_INS_SAT_S, - MIPS_INS_SAT_U, - MIPS_INS_SB, - MIPS_INS_SB16, - MIPS_INS_SC, - MIPS_INS_SCD, - MIPS_INS_SD, - MIPS_INS_SDBBP, - MIPS_INS_SDBBP16, - MIPS_INS_SDC1, - MIPS_INS_SDC2, - MIPS_INS_SDC3, - MIPS_INS_SDL, - MIPS_INS_SDR, - MIPS_INS_SDXC1, - MIPS_INS_SEB, - MIPS_INS_SEH, - MIPS_INS_SELEQZ, - MIPS_INS_SELNEZ, - MIPS_INS_SEL, - MIPS_INS_SEQ, - MIPS_INS_SEQI, - MIPS_INS_SH, - MIPS_INS_SH16, - MIPS_INS_SHF, - MIPS_INS_SHILO, - MIPS_INS_SHILOV, - MIPS_INS_SHLLV, - MIPS_INS_SHLLV_S, - MIPS_INS_SHLL, - MIPS_INS_SHLL_S, - MIPS_INS_SHRAV, - MIPS_INS_SHRAV_R, - MIPS_INS_SHRA, - MIPS_INS_SHRA_R, - MIPS_INS_SHRLV, - MIPS_INS_SHRL, - MIPS_INS_SLDI, - MIPS_INS_SLD, - MIPS_INS_SLL, - MIPS_INS_SLL16, - MIPS_INS_SLLI, - MIPS_INS_SLLV, - MIPS_INS_SLT, - MIPS_INS_SLTI, - MIPS_INS_SLTIU, - MIPS_INS_SLTU, - MIPS_INS_SNE, - MIPS_INS_SNEI, - MIPS_INS_SPLATI, - MIPS_INS_SPLAT, - MIPS_INS_SRA, - MIPS_INS_SRAI, - MIPS_INS_SRARI, - MIPS_INS_SRAR, - MIPS_INS_SRAV, - MIPS_INS_SRL, - MIPS_INS_SRL16, - MIPS_INS_SRLI, - MIPS_INS_SRLRI, - MIPS_INS_SRLR, - MIPS_INS_SRLV, - MIPS_INS_SSNOP, - MIPS_INS_ST, - MIPS_INS_SUBQH, - MIPS_INS_SUBQH_R, - MIPS_INS_SUBQ, - MIPS_INS_SUBQ_S, - MIPS_INS_SUBSUS_U, - MIPS_INS_SUBSUU_S, - MIPS_INS_SUBS_S, - MIPS_INS_SUBS_U, - MIPS_INS_SUBU16, - MIPS_INS_SUBUH, - MIPS_INS_SUBUH_R, - MIPS_INS_SUBU, - MIPS_INS_SUBU_S, - MIPS_INS_SUBVI, - MIPS_INS_SUBV, - MIPS_INS_SUXC1, - MIPS_INS_SW, - MIPS_INS_SW16, - MIPS_INS_SWC1, - MIPS_INS_SWC2, - MIPS_INS_SWC3, - MIPS_INS_SWL, - MIPS_INS_SWM16, - MIPS_INS_SWM32, - MIPS_INS_SWP, - MIPS_INS_SWR, - MIPS_INS_SWXC1, - MIPS_INS_SYNC, - MIPS_INS_SYNCI, - MIPS_INS_SYSCALL, - MIPS_INS_TEQ, - MIPS_INS_TEQI, - MIPS_INS_TGE, - MIPS_INS_TGEI, - MIPS_INS_TGEIU, - MIPS_INS_TGEU, - MIPS_INS_TLBP, - MIPS_INS_TLBR, - MIPS_INS_TLBWI, - MIPS_INS_TLBWR, - MIPS_INS_TLT, - MIPS_INS_TLTI, - MIPS_INS_TLTIU, - MIPS_INS_TLTU, - MIPS_INS_TNE, - MIPS_INS_TNEI, - MIPS_INS_TRUNC, - MIPS_INS_V3MULU, - MIPS_INS_VMM0, - MIPS_INS_VMULU, - MIPS_INS_VSHF, - MIPS_INS_WAIT, - MIPS_INS_WRDSP, - MIPS_INS_WSBH, - MIPS_INS_XOR, - MIPS_INS_XOR16, - MIPS_INS_XORI, - - //> some alias instructions - MIPS_INS_NOP, - MIPS_INS_NEGU, - - //> special instructions - MIPS_INS_JALR_HB, // jump and link with Hazard Barrier - MIPS_INS_JR_HB, // jump register with Hazard Barrier - - MIPS_INS_ENDING, -} mips_insn; - -struct gnu_rreg { - const char *rs; - const char *rt; - const char *rd; - ut8 sa[REG_BUF_MAX]; -}; - -struct gnu_jreg { - ut8 jump[REG_BUF_MAX]; -}; - -struct gnu_ireg { - const char *rs; - const char *rt; - union { - ut8 imm[REG_BUF_MAX]; - ut8 jump[REG_BUF_MAX]; - }; -}; - -typedef struct gnu_insn { - ut8 optype; - ut32 id; - union { - struct gnu_rreg r_reg; - struct gnu_ireg i_reg; - struct gnu_jreg j_reg; - }; -} gnu_insn; - -#define R_REG(x) ((const char *)insn->r_reg.x) -#define I_REG(x) ((const char *)insn->i_reg.x) -#define J_REG(x) ((const char *)insn->j_reg.x) - -/* Return a mapping from the register number i.e. $0 .. $31 to string name */ -static const char *mips_reg_decode(ut32 reg_num) { - /* See page 36 of "See Mips Run Linux, 2e, D. Sweetman, 2007"*/ - static const char *REGISTERS[32] = { - "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", - "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", - "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", - "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra" - }; - if (reg_num < 32) { - return REGISTERS[reg_num]; - } - return NULL; -} - -static int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, gnu_insn *insn) { - - switch (insn->id) { - case MIPS_INS_NOP: - rz_strbuf_setf(&op->esil, ","); - break; - case MIPS_INS_BREAK: - // rz_strbuf_setf (&op->esil, "%d,%d,TRAP", IMM (0), IMM (0)); - break; - case MIPS_INS_SD: - rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,=[8]", - I_REG(rt), I_REG(imm), I_REG(rs)); - break; - case MIPS_INS_SW: - case MIPS_INS_SWL: - case MIPS_INS_SWR: - rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,=[4]", - I_REG(rt), I_REG(imm), I_REG(rs)); - break; - case MIPS_INS_SH: - rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,=[2]", - I_REG(rt), I_REG(imm), I_REG(rs)); - break; - case MIPS_INS_SWC1: - case MIPS_INS_SWC2: - break; - case MIPS_INS_SB: - rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,=[1]", - I_REG(rt), I_REG(imm), I_REG(rs)); - break; - case MIPS_INS_CMP: - case MIPS_INS_CMPU: - case MIPS_INS_CMPGU: - case MIPS_INS_CMPGDU: - case MIPS_INS_CMPI: - break; - case MIPS_INS_SHRAV: - case MIPS_INS_SHRAV_R: - case MIPS_INS_SHRA: - case MIPS_INS_SHRA_R: - break; - case MIPS_INS_SRA: - rz_strbuf_appendf(&op->esil, - ES_W("%s,%s") ",>>,31,%s,>>,?{,%s,32,-,0xffffffff,<<,0xffffffff,&,}{,0,},|,%s,=", - R_REG(sa), R_REG(rt), R_REG(rt), R_REG(sa), R_REG(rd)); - break; - case MIPS_INS_DSRA: - rz_strbuf_appendf(&op->esil, - "%s,%s,>>,31,%s,>>,?{,32,%s,32,-,0xffffffff,<<,0xffffffff,&,<<,}{,0,},|,%s,=", - R_REG(sa), R_REG(rt), R_REG(rt), R_REG(sa), R_REG(rd)); - break; - case MIPS_INS_SHRL: - // suffix 'S' forces conditional flag to be updated - break; - case MIPS_INS_SRLV: - case MIPS_INS_SRL: - rz_strbuf_appendf(&op->esil, "%s,%s,>>,%s,=", - R_REG(rs) ? R_REG(rs) : R_REG(sa), R_REG(rt), R_REG(rd)); - break; - case MIPS_INS_SLLV: - case MIPS_INS_SLL: - rz_strbuf_appendf(&op->esil, "%s,%s,<<,%s,=", - R_REG(rs) ? R_REG(rs) : R_REG(sa), R_REG(rt), R_REG(rd)); - break; - case MIPS_INS_BAL: - case MIPS_INS_JAL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_D("%s"), I_REG(jump)); - break; - case MIPS_INS_JALR: - case MIPS_INS_JALRS: - if (strcmp(R_REG(rd), "rd") == 0) { - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_D("%s"), R_REG(rs)); - } else { - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_DR("%s", "%s"), R_REG(rd), R_REG(rs)); - } - break; - case MIPS_INS_JR: - case MIPS_INS_JRC: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_J("%s"), R_REG(rs)); - break; - case MIPS_INS_J: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_J("%s"), J_REG(jump)); - break; - case MIPS_INS_B: - // jump to address with conditional - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_J("%s"), I_REG(jump)); - break; - case MIPS_INS_BNE: // bne $s, $t, offset - case MIPS_INS_BNEL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,%s,==,$z,!,?{," ES_J("%s") ",}", - I_REG(rs), I_REG(rt), I_REG(jump)); - break; - case MIPS_INS_BEQ: - case MIPS_INS_BEQL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,%s,==,$z,?{," ES_J("%s") ",}", - I_REG(rs), I_REG(rt), I_REG(jump)); - break; - case MIPS_INS_BZ: - case MIPS_INS_BEQZ: - case MIPS_INS_BEQZC: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,0,==,$z,?{," ES_J("%s") ",}", - I_REG(rs), I_REG(jump)); - break; - case MIPS_INS_BNEZ: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,0,==,$z,!,?{," ES_J("%s") ",}", - I_REG(rs), I_REG(jump)); - break; - case MIPS_INS_BLEZ: - case MIPS_INS_BLEZC: - case MIPS_INS_BLEZL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,%s,==,$z,?{," ES_J("%s") ",BREAK,},", - I_REG(rs), I_REG(jump)); - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", - I_REG(rs), I_REG(jump)); - break; - case MIPS_INS_BGEZ: - case MIPS_INS_BGEZC: - case MIPS_INS_BGEZL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", - I_REG(rs), I_REG(jump)); - break; - case MIPS_INS_BGEZAL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_D("%s") ",}", - I_REG(rs), I_REG(jump)); - break; - case MIPS_INS_BLTZAL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_D("%s") ",}", - I_REG(rs), I_REG(jump)); - break; - case MIPS_INS_BLTZ: - case MIPS_INS_BLTZC: - case MIPS_INS_BLTZL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", - I_REG(rs), I_REG(jump)); - break; - case MIPS_INS_BGTZ: - case MIPS_INS_BGTZC: - case MIPS_INS_BGTZL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,%s,==,$z,?{,BREAK,},", I_REG(rs)); - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", - I_REG(rs), I_REG(jump)); - break; - case MIPS_INS_BTEQZ: - break; - case MIPS_INS_BTNEZ: - break; - case MIPS_INS_MOV: - case MIPS_INS_MOVE: - rz_strbuf_appendf(&op->esil, "%s,%s,=", R_REG(rs), R_REG(rd)); - break; - case MIPS_INS_MOVZ: - case MIPS_INS_MOVF: - rz_strbuf_appendf(&op->esil, "0,%s,==,$z,?{,%s,%s,=,}", - R_REG(rt), R_REG(rs), R_REG(rd)); - break; - case MIPS_INS_MOVT: - rz_strbuf_appendf(&op->esil, "1,%s,==,$z,?{,%s,%s,=,}", - R_REG(rt), R_REG(rs), R_REG(rd)); - break; - case MIPS_INS_FSUB: - case MIPS_INS_SUB: - case MIPS_INS_SUBU: - case MIPS_INS_DSUB: - case MIPS_INS_DSUBU: - rz_strbuf_appendf(&op->esil, "%s,%s,-,%s,=", - R_REG(rt), R_REG(rs), R_REG(rd)); - break; - case MIPS_INS_NEG: - case MIPS_INS_NEGU: - break; - /** signed -- sets overflow flag */ - case MIPS_INS_ADD: - ES_ADD_CK32_OVERF(R_REG(rs), R_REG(rt), R_REG(rd)); - break; - case MIPS_INS_ADDI: - ES_ADD_CK32_OVERF(I_REG(imm), I_REG(rs), I_REG(rt)); - break; - case MIPS_INS_DADD: - ES_ADD_CK64_OVERF(R_REG(rs), R_REG(rt), R_REG(rd)); - break; - case MIPS_INS_DADDU: - case MIPS_INS_ADDU: - rz_strbuf_appendf(&op->esil, "%s,%s,+,%s,=", - R_REG(rt), R_REG(rs), R_REG(rd)); - break; - case MIPS_INS_DADDI: - ES_ADD_CK64_OVERF(I_REG(imm), I_REG(rs), I_REG(rt)); - break; - case MIPS_INS_ADDIU: - case MIPS_INS_DADDIU: - rz_strbuf_appendf(&op->esil, "%s,%s,+,%s,=", - I_REG(imm), I_REG(rs), I_REG(rt)); - ES_SIGN32_64(I_REG(rt)); - break; - case MIPS_INS_LI: - case MIPS_INS_LDI: - rz_strbuf_appendf(&op->esil, "%s,%s,=", I_REG(imm), I_REG(rt)); - break; - case MIPS_INS_LUI: - rz_strbuf_appendf(&op->esil, "%s0000,%s,=", I_REG(imm), I_REG(rt)); - break; - case MIPS_INS_LB: - op->sign = true; // To load a byte from memory as a signed value - /* fallthrough */ - case MIPS_INS_LBU: - // one of these is wrong - rz_strbuf_appendf(&op->esil, "%s,%s,+,[1],%s,=", - I_REG(imm), I_REG(rs), I_REG(rt)); - break; - case MIPS_INS_LW: - case MIPS_INS_LWC1: - case MIPS_INS_LWC2: - case MIPS_INS_LWL: - case MIPS_INS_LWR: - case MIPS_INS_LWU: - case MIPS_INS_LL: - rz_strbuf_appendf(&op->esil, "%s,%s,+,[4],%s,=", - I_REG(imm), I_REG(rs), I_REG(rt)); - break; - case MIPS_INS_LDL: - case MIPS_INS_LDC1: - case MIPS_INS_LDC2: - case MIPS_INS_LLD: - case MIPS_INS_LD: - rz_strbuf_appendf(&op->esil, "%s,%s,+,[8],%s,=", - I_REG(imm), I_REG(rs), I_REG(rt)); - break; - case MIPS_INS_LH: - op->sign = true; // To load a byte from memory as a signed value - /* fallthrough */ - case MIPS_INS_LHU: - rz_strbuf_appendf(&op->esil, "%s,%s,+,[2],%s,=", - I_REG(imm), I_REG(rs), I_REG(rt)); - break; - case MIPS_INS_LHX: - case MIPS_INS_LWX: - break; - case MIPS_INS_AND: - rz_strbuf_appendf(&op->esil, "%s,%s,&,%s,=", R_REG(rt), R_REG(rs), R_REG(rd)); - break; - case MIPS_INS_ANDI: - rz_strbuf_appendf(&op->esil, "%s,%s,&,%s,=", I_REG(imm), I_REG(rs), I_REG(rt)); - break; - case MIPS_INS_OR: - rz_strbuf_appendf(&op->esil, "%s,%s,|,%s,=", R_REG(rt), R_REG(rs), R_REG(rd)); - break; - case MIPS_INS_ORI: - rz_strbuf_appendf(&op->esil, "%s,%s,|,%s,=", I_REG(imm), I_REG(rs), I_REG(rt)); - break; - case MIPS_INS_XOR: - rz_strbuf_appendf(&op->esil, "%s,%s,^,%s,=", R_REG(rt), R_REG(rs), R_REG(rd)); - break; - case MIPS_INS_XORI: - rz_strbuf_appendf(&op->esil, "%s,%s,^,%s,=", I_REG(imm), I_REG(rs), I_REG(rt)); - break; - case MIPS_INS_NOR: - rz_strbuf_appendf(&op->esil, "%s,%s,|,0xffffffff,^,%s,=", R_REG(rs), R_REG(rt), R_REG(rd)); - break; - case MIPS_INS_SLT: - rz_strbuf_appendf(&op->esil, "%s,%s,<,t,=", R_REG(rs), R_REG(rt)); - break; - case MIPS_INS_SLTI: - rz_strbuf_appendf(&op->esil, "%s,%s,<,%s,=", I_REG(imm), I_REG(rs), I_REG(rt)); - break; - case MIPS_INS_SLTU: - rz_strbuf_appendf(&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,t,=", - R_REG(rs), R_REG(rt)); - break; - case MIPS_INS_SLTIU: - rz_strbuf_appendf(&op->esil, "%s,0xffffffff,&,%s,0xffffffff,&,<,%s,=", - I_REG(imm), I_REG(rs), I_REG(rt)); - break; - case MIPS_INS_MUL: - rz_strbuf_appendf(&op->esil, ES_W("%s,%s,*") ",%s,=", R_REG(rs), R_REG(rt), R_REG(rd)); - ES_SIGN32_64(R_REG(rd)); - break; - case MIPS_INS_MULT: - case MIPS_INS_MULTU: - rz_strbuf_appendf(&op->esil, ES_W("%s,%s,*") ",lo,=", R_REG(rs), R_REG(rt)); - ES_SIGN32_64("lo"); - rz_strbuf_appendf(&op->esil, ES_W("32,%s,%s,*,>>") ",hi,=", R_REG(rs), R_REG(rt)); - ES_SIGN32_64("hi"); - break; - case MIPS_INS_MFLO: - rz_strbuf_appendf(&op->esil, "lo,%s,=", R_REG(rd)); - break; - case MIPS_INS_MFHI: - rz_strbuf_appendf(&op->esil, "hi,%s,=", R_REG(rd)); - break; - case MIPS_INS_MTLO: - rz_strbuf_appendf(&op->esil, "%s,lo,=,", R_REG(rs)); - ES_SIGN32_64("lo"); - break; - case MIPS_INS_MTHI: - rz_strbuf_appendf(&op->esil, "%s,hi,=,", R_REG(rs)); - ES_SIGN32_64("hi"); - break; - default: - return -1; - } - - return 0; -} - -static int mips_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, RzAnalysisOpMask mask) { - ut8 opcode[4] = { 0 }; - int optype = 0, oplen = (analysis->bits == 16) ? 2 : 4; - gnu_insn insn = { 0 }; - - if (!op || len < 4) { - return oplen; - } - - op->type = RZ_ANALYSIS_OP_TYPE_UNK; - op->size = oplen; - op->addr = addr; - - if (!buf[0] && !buf[1] && !buf[2] && !buf[3]) { - op->type = RZ_ANALYSIS_OP_TYPE_NOP; - return oplen; - } - - if (analysis->big_endian) { - memcpy(opcode, buf, oplen); - } else { - opcode[0] = buf[3]; - opcode[1] = buf[2]; - opcode[2] = buf[1]; - opcode[3] = buf[0]; - } - - optype = opcode[0] >> 2; - insn.optype = optype; - insn.id = 0; - - if (optype == 0) { - /* - R-TYPE - ====== - opcode (6) rs (5) rt (5) rd (5) sa (5) function (6) - rs = register source - rt = register target - rd = register destination - sa = - fu = - |--[0]--| |--[1]--| |--[2]--| |--[3]--| - 1111 1111 1111 1111 1111 1111 1111 1111 - \_op__/\_rs__/\_rt_/ \_rd_/\_sa__/\_fun_/ - | | | | | | - buf[0]>>2 | (buf[1]&31) | | buf[3]&63 - | (buf[2]>>3) | - (buf[0]&3)<<3)+(buf[1]>>5) (buf[2]&7)+(buf[3]>>6) -*/ - int rs = ((opcode[0] & 3) << 3) + (opcode[1] >> 5); - int rt = opcode[1] & 31; - int rd = opcode[2] >> 3; - int sa = ((opcode[2] & 7) << 2) + (opcode[3] >> 6); - int fun = opcode[3] & 63; - - insn.r_reg.rs = mips_reg_decode(rs); - insn.r_reg.rd = mips_reg_decode(rd); - insn.r_reg.rt = mips_reg_decode(rt); - snprintf((char *)insn.r_reg.sa, REG_BUF_MAX, "%" PFMT32d, sa); - - switch (fun) { - case 0: // sll - insn.id = MIPS_INS_SLL; - insn.r_reg.rs = NULL; - op->val = sa; - // fallthrough - case 4: // sllv - insn.id = MIPS_INS_SLLV; - op->type = RZ_ANALYSIS_OP_TYPE_SHL; - break; - case 2: // srl - insn.id = MIPS_INS_SRL; - insn.r_reg.rs = NULL; - op->val = sa; - // fallthrough - case 6: // srlv - insn.id = MIPS_INS_SRLV; - op->type = RZ_ANALYSIS_OP_TYPE_SHR; - break; - case 3: // sra - insn.id = MIPS_INS_SRA; - op->type = RZ_ANALYSIS_OP_TYPE_SAR; - break; - case 7: // srav - insn.id = MIPS_INS_SRAV; - op->type = RZ_ANALYSIS_OP_TYPE_SAR; - break; - case 59: // dsra - insn.id = MIPS_INS_DSRA; // TODO double - op->type = RZ_ANALYSIS_OP_TYPE_SAR; - break; - case 63: // dsra32 - insn.id = MIPS_INS_DSRA32; - op->type = RZ_ANALYSIS_OP_TYPE_SAR; - break; - case 8: // jr - // RZ_LOG_DEBUG("%" PFMT64x " jr\n", addr); - // TODO: check return value - op->delay = 1; - insn.id = MIPS_INS_JR; - if (rs == 31) { - op->type = RZ_ANALYSIS_OP_TYPE_RET; - } else if (rs == 25) { - op->type = RZ_ANALYSIS_OP_TYPE_RJMP; - op->jump = t9_pre; - break; - } else { - op->type = RZ_ANALYSIS_OP_TYPE_RJMP; - } - break; - case 9: // jalr - // RZ_LOG_DEBUG("%" PFMT64x " jalr\n", addr); - op->delay = 1; - insn.id = MIPS_INS_JALR; - if (rs == 25) { - op->type = RZ_ANALYSIS_OP_TYPE_RCALL; - op->jump = t9_pre; - break; - } - op->type = RZ_ANALYSIS_OP_TYPE_UCALL; - break; - case 10: // movz - insn.id = MIPS_INS_MOVZ; - break; - case 12: // syscall - op->type = RZ_ANALYSIS_OP_TYPE_SWI; - break; - case 13: // break - op->type = RZ_ANALYSIS_OP_TYPE_TRAP; - break; - case 16: // mfhi - insn.id = MIPS_INS_MFHI; - break; - case 18: // mflo - insn.id = MIPS_INS_MFLO; - break; - case 17: // mthi - insn.id = MIPS_INS_MTHI; - break; - case 19: // mtlo - insn.id = MIPS_INS_MTLO; - op->type = RZ_ANALYSIS_OP_TYPE_MOV; - break; - case 24: // mult - insn.id = MIPS_INS_MULT; - // fallthrough - case 25: // multu - insn.id = MIPS_INS_MULTU; - op->type = RZ_ANALYSIS_OP_TYPE_MUL; - break; - case 26: // div - case 27: // divu - op->type = RZ_ANALYSIS_OP_TYPE_DIV; - insn.id = MIPS_INS_DIV; - break; - case 32: // add - insn.id = MIPS_INS_ADD; - // fallthrough - case 33: // addu //TODO:表明位数 - insn.id = MIPS_INS_ADDU; - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - break; - case 44: // dadd - insn.id = MIPS_INS_DADD; - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - break; - case 45: // daddu move - if (rt == 0) { - op->type = RZ_ANALYSIS_OP_TYPE_MOV; - insn.id = MIPS_INS_MOV; - break; - } - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - insn.id = MIPS_INS_DADDU; - break; - case 34: // sub - case 35: // subu - insn.id = MIPS_INS_SUB; - op->type = RZ_ANALYSIS_OP_TYPE_SUB; - break; - case 46: // dsub - insn.id = MIPS_INS_SUB; - op->type = RZ_ANALYSIS_OP_TYPE_SUB; - break; - case 47: // dsubu - insn.id = MIPS_INS_SUB; - op->type = RZ_ANALYSIS_OP_TYPE_SUB; - break; - case 36: // and - insn.id = MIPS_INS_AND; - op->type = RZ_ANALYSIS_OP_TYPE_AND; - break; - case 37: // or - insn.id = MIPS_INS_OR; - op->type = RZ_ANALYSIS_OP_TYPE_OR; - break; - case 38: // xor - insn.id = MIPS_INS_XOR; - op->type = RZ_ANALYSIS_OP_TYPE_XOR; - break; - case 39: // nor - insn.id = MIPS_INS_NOR; - op->type = RZ_ANALYSIS_OP_TYPE_NOR; - break; - case 42: // slt - insn.id = MIPS_INS_SLT; - break; - case 43: // sltu - insn.id = MIPS_INS_SLTU; - break; - default: - // RZ_LOG_DEBUG("%" PFMT64x " %d\n", addr, optype); - break; - } - // family = 'R'; - } else if ((optype & 0x3e) == 2) { - /* - // J-TYPE - |--[0]--| |--[1]--| |--[2]--| |--[3]--| - 1111 1111 1111 1111 1111 1111 1111 1111 - \_op__/\______address____________________/ - | | - (buf[0]>>2) ((buf[0]&3)<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3] -*/ - // FIXME: what happens when addr is using a virtual map? - // ANS: address will be E 0x000000..0x0ffffffc - // but addr could be anywhere - // so address needs to be adjusted for that, somehow... - // MIPS is strange. For example, the same code memory may be - // mapped simultaneously to 0x00600000 and 0x80600000. The program is - // executing at 0x80600000 if we are operating in 'KSEG0' space - // (unmapped cached mode) vs 0x00600000 (KUSEG or user space) - // An immediate jump can only reach within 2^28 bits. - // HACK: if the user specified a mapping for the program - // then assume that they know which MIPS segment they - // are analysing in, and use the high order bits of addr - // to be add to the jump. - // WARNING: it is possible that this may not be the case - // in all situations! - // Maybe better solution: use a cfg. variable to do - // the offset... but I dont yet know how to get to that - // from this static function - int address = (((opcode[0] & 3) << 24) + (opcode[1] << 16) + (opcode[2] << 8) + opcode[3]) << 2; - ut64 page_hack = addr & 0xf0000000; - - switch (optype) { - case 2: // j - insn.id = MIPS_INS_J; - op->type = RZ_ANALYSIS_OP_TYPE_JMP; - op->jump = page_hack + address; - op->delay = 1; - snprintf((char *)insn.j_reg.jump, REG_BUF_MAX, "0x%" PFMT64x, op->jump); - break; - case 3: // jal - insn.id = MIPS_INS_JAL; - op->type = RZ_ANALYSIS_OP_TYPE_CALL; - op->jump = page_hack + address; - op->fail = addr + 8; - op->delay = 1; - snprintf((char *)insn.j_reg.jump, REG_BUF_MAX, "0x%" PFMT64x, op->jump); - break; - } - // family = 'J'; - } else if ((optype & 0x3c) == 0x10) { -/* - C-TYPE - ====== - opcode (6) format (5) ft (5) fs (5) fd (5) function (6) - - |--[0]--| |--[1]--| |--[2]--| |--[3]--| - 1111 1111 1111 1111 1111 1111 1111 1111 - \_op__/\_fmt_/\_ft_/ \_fs_/\_fd__/\_fun_/ - | | | | | | - buf[0]>>2 | (buf[1]&31) | | buf[3]&63 - | (buf[2]>>3) | - (buf[0]&3)<<3)+(buf[1]>>5) (buf[2]&7)+(buf[3]>>6) -*/ -#if WIP - int fmt = ((opcode[0] & 3) << 3) + (opcode[1] >> 5); - int ft = (opcode[1] & 31); - int fs = (opcode[2] >> 3); - int fd = (opcode[2] & 7) + (opcode[3] >> 6); -#endif - int fun = (opcode[3] & 63); - // family = 'C'; - switch (fun) { - case 0: // mtc1 - break; - case 1: // sub.s - break; - case 2: // mul.s - break; - case 3: // div.s - break; - // .... - } - } else { - /* - I-TYPE - ====== - all opcodes but 000000 000001x and 0100xx - opcode (6) rs (5) rt (5) immediate (16) - - |--[0]--| |--[1]--| |--[2]--| |--[3]--| - 1111 1111 1111 1111 1111 1111 1111 1111 - \_op__/\_rs__/\_rt_/ \_______imm________/ - | | | | - buf[0]>>2 | (buf[1]&31) | - | | - ((buf[0]&3)<<3)+(buf[1]>>5) (buf[2]<<8)+buf[3] -*/ - op->refptr = 0; - int rs = ((opcode[0] & 3) << 3) + (opcode[1] >> 5); - int rt = opcode[1] & 31; - int imm = (opcode[2] << 8) + opcode[3]; - if (((optype >> 2) ^ 0x3) && (imm & 0x8000)) { - imm = 0 - (0x10000 - imm); - } - - insn.i_reg.rs = mips_reg_decode(rs); - insn.i_reg.rt = mips_reg_decode(rt); - snprintf((char *)insn.i_reg.imm, REG_BUF_MAX, "%" PFMT32d, imm); - - switch (optype) { - case 1: - switch (rt) { - case 0: // bltz - insn.id = MIPS_INS_BLTZ; - break; - case 1: // bgez - insn.id = MIPS_INS_BGEZ; - break; - case 17: // bal bgezal - if (rs == 0) { - op->jump = addr + (imm << 2) + 4; - snprintf((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%" PFMT64x, op->jump); - insn.id = MIPS_INS_BAL; - } else { - op->fail = addr + 8; - insn.id = MIPS_INS_BGEZAL; - } - op->delay = 1; - op->type = RZ_ANALYSIS_OP_TYPE_CALL; - break; - default: - op->delay = 1; - op->fail = addr + 8; - break; - } - break; - case 4: // beq - if (!insn.id) { - insn.id = MIPS_INS_BEQ; - if (rt == 0) { - insn.id = MIPS_INS_BEQZ; - } - } - // fallthrough - case 5: // bne // also bnez - if (!insn.id) { - insn.id = MIPS_INS_BNE; - if (rt == 0) { - insn.id = MIPS_INS_BNEZ; - } - } - // fallthrough - case 6: // blez - if (!insn.id) { - insn.id = MIPS_INS_BLEZ; - } - // fallthrough - case 7: // bgtz - // XXX: use imm here - if (!insn.id) { - insn.id = MIPS_INS_BGTZ; - } - op->type = RZ_ANALYSIS_OP_TYPE_CJMP; - op->jump = addr + (imm << 2) + 4; - op->fail = addr + 8; - op->delay = 1; - - snprintf((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%" PFMT64x, op->jump); - break; - // The following idiom is very common in mips 32 bit: - // - // lui a0,0x8123 - // ; maybe other opcodes - // ; maybe even a jump with branch delay - // addui a0,a0,-12345 - // - // Here, a0 might typically be any a0 or s0 register, and -12345 is a signed 16-bit number - // This is used to address const or static data in a 64kb page - // 0x8123 is the upper 16 bits of the register - // The net result: a0 := 0x8122cfc7 - // The cases vary, so for now leave the smarts in a human generated macro to decide - // but the macro needs the opcode values as input - // - // TODO: this is a stop-gap. Really we need some smarts in here to tie this into the - // flags directly, as suggested here: https://github.com/rizinorg/rizin/issues/949#issuecomment-43654922 - case 15: // lui - insn.id = MIPS_INS_LUI; - snprintf((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%" PFMT32x, imm); - op->dst = rz_analysis_value_new(); - op->dst->reg = rz_reg_get(analysis->reg, mips_reg_decode(rt), RZ_REG_TYPE_GPR); - // TODO: currently there is no way for the macro to get access to this register - op->val = imm; - break; - case 9: // addiu - insn.id = MIPS_INS_ADDIU; - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - op->dst = rz_analysis_value_new(); - op->dst->reg = rz_reg_get(analysis->reg, mips_reg_decode(rt), RZ_REG_TYPE_GPR); - // TODO: currently there is no way for the macro to get access to this register - op->src[0] = rz_analysis_value_new(); - op->src[0]->reg = rz_reg_get(analysis->reg, mips_reg_decode(rs), RZ_REG_TYPE_GPR); - op->val = imm; // Beware: this one is signed... use `%vi $v` - if (rs == 0) { - insn.id = MIPS_INS_LI; - snprintf((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%" PFMT32x, imm); - } - break; - case 8: // addi - insn.id = MIPS_INS_ADDI; - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - break; - case 10: // slti - insn.id = MIPS_INS_SLTI; - break; - case 11: // sltiu - insn.id = MIPS_INS_SLTIU; - break; - case 12: // andi - insn.id = MIPS_INS_ANDI; - op->type = RZ_ANALYSIS_OP_TYPE_AND; - break; - case 13: // ori - insn.id = MIPS_INS_ORI; - op->type = RZ_ANALYSIS_OP_TYPE_OR; - break; - case 14: // xori - insn.id = MIPS_INS_XORI; - op->type = RZ_ANALYSIS_OP_TYPE_XOR; - break; - case 24: // daddi - insn.id = MIPS_INS_DADDI; - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - break; - case 25: // daddiu - insn.id = MIPS_INS_DADDIU; - op->type = RZ_ANALYSIS_OP_TYPE_ADD; - if (rs == 0) { - insn.id = MIPS_INS_LDI; - snprintf((char *)insn.i_reg.imm, REG_BUF_MAX, "0x%" PFMT32x, imm); - } - break; - case 32: // lb - op->refptr = 1; - insn.id = MIPS_INS_LB; - /* fallthrough */ - case 33: // lh - if (!op->refptr) { - op->refptr = 2; - insn.id = MIPS_INS_LB; - } - /* fallthrough */ - case 35: // lw - if (!op->refptr) { - op->refptr = 4; - insn.id = MIPS_INS_LW; - } - /* fallthrough */ - case 55: // ld - if (!op->refptr) { - op->refptr = 8; - insn.id = MIPS_INS_LD; - } - - if (rs == 28) { - op->ptr = analysis->gp + imm; - } else { - op->ptr = imm; - } - if (rt == 25) { - t9_pre = op->ptr; - } - op->type = RZ_ANALYSIS_OP_TYPE_LOAD; - break; - case 36: // lbu - insn.id = MIPS_INS_LBU; - op->type = RZ_ANALYSIS_OP_TYPE_LOAD; - break; - case 37: // lhu - insn.id = MIPS_INS_LHU; - op->type = RZ_ANALYSIS_OP_TYPE_LOAD; - break; - case 40: // sb - insn.id = MIPS_INS_SB; - op->type = RZ_ANALYSIS_OP_TYPE_STORE; - break; - case 41: // sh - insn.id = MIPS_INS_SH; - op->type = RZ_ANALYSIS_OP_TYPE_STORE; - break; - case 43: // sw - insn.id = MIPS_INS_SW; - op->type = RZ_ANALYSIS_OP_TYPE_STORE; - break; - case 63: // sd - insn.id = MIPS_INS_SD; - op->type = RZ_ANALYSIS_OP_TYPE_STORE; - break; - case 49: // lwc1 - case 57: // swc1 - break; - case 29: // jalx - insn.id = MIPS_INS_JALX; - op->type = RZ_ANALYSIS_OP_TYPE_CALL; - op->jump = addr + 4 * ((opcode[3] | opcode[2] << 8 | opcode[1] << 16)); - op->fail = addr + 8; - op->delay = 1; - snprintf((char *)insn.i_reg.jump, REG_BUF_MAX, "0x%" PFMT64x, op->jump); - - break; - } - // family = 'I'; - } - - if (mask & RZ_ANALYSIS_OP_MASK_ESIL) { - if (analyze_op_esil(analysis, op, addr, &insn)) { - rz_strbuf_fini(&op->esil); - } - } - if (mask & RZ_ANALYSIS_OP_MASK_VAL) { - // TODO: add op_fillval (analysis, op, &insn); - } - return oplen; -} - -/* - R - all instructions that only take registers as arguments (jalr, jr) - opcode 000000 - opcode (6) rs (5) rt (5) rd (5) sa (5) function (6) - add rd, rs, rt 100000 - addu rd, rs, rt 100001 - and rd, rs, rt 100100 - break 001101 - div rs, rt 011010 - divu rs, rt 011011 - jalr rd, rs 001001 - jr rs 001000 - - mfhi rd 010000 - mflo rd 010010 - mthi rs 010001 - mtlo rs 010011 - mult rs, rt 011000 - multu rs, rt 011001 - - nor rd, rs, rt 100111 - or rd, rs, rt 100101 - sll rd, rt, sa 000000 - sllv rd, rt, rs 000100 - slt rd, rs, rt 101010 - sltu rd, rs, rt 101011 - - sra rd, rt, sa 000011 - srav rd, rt, rs 000111 - - srl rd, rt, sa 000010 - srlv rd, rt, rs 000110 - - sub rd, rs, rt 100010 - subu rd, rs, rt 100011 - syscall 001100 - xor rd, rs, rt 100110 - I - instructions with immediate operand, load/store/.. - all opcodes but 000000 000001x and 0100xx - opcode (6) rs (5) rt (5) immediate (16) - addi rt, rs, immediate 001000 - addiu rt, rs, immediate 001001 - andi rt, rs, immediate 001100 - beq rs, rt, label 000100 - - bgez rs, label 000001 rt = 00001 - - bgtz rs, label 000111 rt = 00000 - blez rs, label 000110 rt = 00000 - - bltz rs, label 000001 rt = 00000 - bne rs, rt, label 000101 - lb rt, immediate(rs) 100000 - lbu rt, immediate(rs) 100100 - - lh rt, immediate(rs) 100001 - lhu rt, immediate(rs) 100101 - - lui rt, immediate 001111 - - lw rt, immediate(rs) 100011 - lwc1 rt, immediate(rs) 110001 - - ori rt, rs, immediate 001101 - sb rt, immediate(rs) 101000 - - slti rt, rs, immediate 001010 - sltiu rt, rs, immediate 001011 - sh rt, immediate(rs) 101001 - sw rt, immediate(rs) 101011 - swc1 rt, immediate(rs) 111001 - xori rt, rs, immediate 001110 - J - require memory address like j, jal - 00001x - opcode (6) target (26) - j label 000010 coded address of label - jal label 000011 coded address of label - C - coprocessor insutrctions that use cp0, cp1, .. - 0100xx - opcode (6) format (5) ft (5) fs (5) fd (5) function (6) - add.s fd, fs, ft 000000 10000 - cvt.s.w fd, fs, ft 100000 10100 - cvt.w.s fd, fs, ft 100100 10000 - div.s fd, fs, ft 000011 10000 - mfc1 ft, fs 000000 00000 - mov.s fd, fs 000110 10000 - mtc1 ft, fs 000000 00100 - mul.s fd, fs, ft 000010 10000 - sub.s fd, fs, ft 000001 10000 -*/ - -/* Set the profile register */ -static char *mips_get_reg_profile(RzAnalysis *analysis) { - const char *p = -#if 0 - "=PC pc\n" - "=SP sp\n" - "=A0 a0\n" - "=A1 a1\n" - "=A2 a2\n" - "=A3 a3\n" - "gpr zero .32 0 0\n" - "gpr at .32 4 0\n" - "gpr v0 .32 8 0\n" - "gpr v1 .32 12 0\n" - "gpr a0 .32 16 0\n" - "gpr a1 .32 20 0\n" - "gpr a2 .32 24 0\n" - "gpr a3 .32 28 0\n" - "gpr t0 .32 32 0\n" - "gpr t1 .32 36 0\n" - "gpr t2 .32 40 0\n" - "gpr t3 .32 44 0\n" - "gpr t4 .32 48 0\n" - "gpr t5 .32 52 0\n" - "gpr t6 .32 56 0\n" - "gpr t7 .32 60 0\n" - "gpr s0 .32 64 0\n" - "gpr s1 .32 68 0\n" - "gpr s2 .32 72 0\n" - "gpr s3 .32 76 0\n" - "gpr s4 .32 80 0\n" - "gpr s5 .32 84 0\n" - "gpr s6 .32 88 0\n" - "gpr s7 .32 92 0\n" - "gpr t8 .32 96 0\n" - "gpr t9 .32 100 0\n" - "gpr k0 .32 104 0\n" - "gpr k1 .32 108 0\n" - "gpr gp .32 112 0\n" - "gpr sp .32 116 0\n" - "gpr fp .32 120 0\n" - "gpr ra .32 124 0\n" - "gpr pc .32 128 0\n"; -#else - // take the one from the debugger // - "=PC pc\n" - "=SP sp\n" - "=BP fp\n" - "=A0 a0\n" - "=A1 a1\n" - "=A2 a2\n" - "=A3 a3\n" - "gpr zero .64 0 0\n" - // XXX DUPPED CAUSES FAILURE "gpr at .32 8 0\n" - "gpr at .64 8 0\n" - "gpr v0 .64 16 0\n" - "gpr v1 .64 24 0\n" - /* args */ - "gpr a0 .64 32 0\n" - "gpr a1 .64 40 0\n" - "gpr a2 .64 48 0\n" - "gpr a3 .64 56 0\n" - /* tmp */ - "gpr t0 .64 64 0\n" - "gpr t1 .64 72 0\n" - "gpr t2 .64 80 0\n" - "gpr t3 .64 88 0\n" - "gpr t4 .64 96 0\n" - "gpr t5 .64 104 0\n" - "gpr t6 .64 112 0\n" - "gpr t7 .64 120 0\n" - /* saved */ - "gpr s0 .64 128 0\n" - "gpr s1 .64 136 0\n" - "gpr s2 .64 144 0\n" - "gpr s3 .64 152 0\n" - "gpr s4 .64 160 0\n" - "gpr s5 .64 168 0\n" - "gpr s6 .64 176 0\n" - "gpr s7 .64 184 0\n" - "gpr t8 .64 192 0\n" - "gpr t9 .64 200 0\n" - /* special */ - "gpr k0 .64 208 0\n" - "gpr k1 .64 216 0\n" - "gpr gp .64 224 0\n" - "gpr sp .64 232 0\n" - "gpr fp .64 240 0\n" - "gpr ra .64 248 0\n" - /* extra */ - "gpr pc .64 272 0\n"; -#endif - return rz_str_dup(p); -} - -static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) { - switch (query) { - case RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE: - /* fall-thru */ - case RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE: - /* fall-thru */ - case RZ_ANALYSIS_ARCHINFO_TEXT_ALIGN: - /* fall-thru */ - case RZ_ANALYSIS_ARCHINFO_DATA_ALIGN: - return 4; - case RZ_ANALYSIS_ARCHINFO_CAN_USE_POINTERS: - return true; - default: - return -1; - } -} - -RzAnalysisPlugin rz_analysis_plugin_mips_gnu = { - .name = "mips.gnu", - .desc = "MIPS code analysis plugin", - .license = "LGPL3", - .arch = "mips", - .bits = 32, - .esil = true, - .archinfo = archinfo, - .op = &mips_op, - .get_reg_profile = mips_get_reg_profile, -}; diff --git a/librz/arch/p_gnu/arch_mips.c b/librz/arch/p_gnu/arch_mips.c deleted file mode 100644 index b599554a903..00000000000 --- a/librz/arch/p_gnu/arch_mips.c +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-FileCopyrightText: 2024 RizinOrg -// SPDX-FileCopyrightText: 2024 deroad -// SPDX-License-Identifier: LGPL-3.0-only - -#include - -#include "analysis/analysis_mips_gnu.c" -#include "asm/asm_mips_gnu.c" - -RZ_ARCH_PLUGIN_DEFINE_DEPRECATED(mips_gnu); diff --git a/librz/arch/p_gnu/asm/asm_mips_gnu.c b/librz/arch/p_gnu/asm/asm_mips_gnu.c deleted file mode 100644 index 86c24ada6d1..00000000000 --- a/librz/arch/p_gnu/asm/asm_mips_gnu.c +++ /dev/null @@ -1,158 +0,0 @@ -// SPDX-FileCopyrightText: 2009-2018 pancake -// SPDX-FileCopyrightText: 2009-2018 nibble -// SPDX-License-Identifier: LGPL-3.0-only - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#include - -static int mips_mode = 0; -static unsigned long Offset = 0; -static RzStrBuf *buf_global = NULL; -static unsigned char bytes[4]; -static char *pre_cpu = NULL; -static char *pre_features = NULL; - -static int mips_buffer_read_memory(bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, struct disassemble_info *info) { - int delta = (memaddr - Offset); - if (delta < 0) { - return -1; // disable backward reads - } - if ((delta + length) > 4) { - return -1; - } - memcpy(myaddr, bytes + delta, length); - return 0; -} - -static int symbol_at_address(bfd_vma addr, struct disassemble_info *info) { - return 0; -} - -static void memory_error_func(int status, bfd_vma memaddr, struct disassemble_info *info) { - //-- -} - -DECLARE_GENERIC_PRINT_ADDRESS_FUNC() -DECLARE_GENERIC_FPRINTF_FUNC() - -typedef struct { - struct disassemble_info disasm_obj; -} MIPSGnuContext; - -static int mips_gnu_disassemble(struct rz_asm_t *a, struct rz_asm_op_t *op, const ut8 *buf, int len) { - MIPSGnuContext *ctx = (MIPSGnuContext *)a->plugin_data; - if (len < 4) { - return -1; - } - buf_global = &op->buf_asm; - Offset = a->pc; - memcpy(bytes, buf, 4); // TODO handle thumb - - if ((a->cpu != pre_cpu) && (a->features != pre_features)) { - free(ctx->disasm_obj.disassembler_options); - memset(&ctx->disasm_obj, '\0', sizeof(struct disassemble_info)); - } - - /* prepare disassembler */ - if (a->cpu && (!pre_cpu || !strcmp(a->cpu, pre_cpu))) { - if (!rz_str_casecmp(a->cpu, "mips64r2")) { - ctx->disasm_obj.mach = bfd_mach_mipsisa64r2; - } else if (!rz_str_casecmp(a->cpu, "mips32r2")) { - ctx->disasm_obj.mach = bfd_mach_mipsisa32r2; - } else if (!rz_str_casecmp(a->cpu, "mips64")) { - ctx->disasm_obj.mach = bfd_mach_mipsisa64; - } else if (!rz_str_casecmp(a->cpu, "mips32")) { - ctx->disasm_obj.mach = bfd_mach_mipsisa32; - } - char *tmp = rz_str_dup(a->cpu); - free(pre_cpu); - pre_cpu = tmp; - } - - if (a->features && (!pre_features || !strcmp(a->features, pre_features))) { - free(ctx->disasm_obj.disassembler_options); - if (strstr(a->features, "n64")) { - ctx->disasm_obj.disassembler_options = rz_str_dup("abi=n64"); - } else if (strstr(a->features, "n32")) { - ctx->disasm_obj.disassembler_options = rz_str_dup("abi=n32"); - } else if (strstr(a->features, "o32")) { - ctx->disasm_obj.disassembler_options = rz_str_dup("abi=o32"); - } - char *tmp = rz_str_dup(a->features); - free(pre_features); - pre_features = tmp; - } - - mips_mode = a->bits; - ctx->disasm_obj.arch = CPU_LOONGSON_2F; - ctx->disasm_obj.buffer = bytes; - ctx->disasm_obj.read_memory_func = &mips_buffer_read_memory; - ctx->disasm_obj.symbol_at_address_func = &symbol_at_address; - ctx->disasm_obj.memory_error_func = &memory_error_func; - ctx->disasm_obj.print_address_func = &generic_print_address_func; - ctx->disasm_obj.buffer_vma = Offset; - ctx->disasm_obj.buffer_length = 4; - ctx->disasm_obj.endian = !a->big_endian; - ctx->disasm_obj.fprintf_func = &generic_fprintf_func; - ctx->disasm_obj.stream = stdout; - op->size = (ctx->disasm_obj.endian == BFD_ENDIAN_LITTLE) - ? print_insn_little_mips((bfd_vma)Offset, &ctx->disasm_obj) - : print_insn_big_mips((bfd_vma)Offset, &ctx->disasm_obj); - if (op->size == -1) { - rz_strbuf_set(&op->buf_asm, "(data)"); - } - return op->size; -} - -static int mips_gnu_assemble(RzAsm *a, RzAsmOp *op, const char *str) { - ut8 *opbuf = (ut8 *)rz_strbuf_get(&op->buf); - int ret = mips_assemble_opcode(str, a->pc, opbuf); - if (a->big_endian) { - ut8 tmp = opbuf[0]; - opbuf[0] = opbuf[3]; - opbuf[3] = tmp; - tmp = opbuf[1]; - opbuf[1] = opbuf[2]; - opbuf[2] = tmp; - } - return ret; -} - -static bool mips_gnu_init(void **user) { - MIPSGnuContext *ctx = RZ_NEW0(MIPSGnuContext); - rz_return_val_if_fail(ctx, false); - *user = ctx; - return true; -} - -static bool mips_gnu_fini(void *user) { - MIPSGnuContext *ctx = (MIPSGnuContext *)user; - if (ctx) { - RZ_FREE(ctx); - } - return true; -} - -RzAsmPlugin rz_asm_plugin_mips_gnu = { - .name = "mips.gnu", - .arch = "mips", - .license = "GPL3", - .bits = 32 | 64, - .endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG, - .desc = "MIPS CPU", - .init = mips_gnu_init, - .fini = mips_gnu_fini, - .disassemble = &mips_gnu_disassemble, - .assemble = &mips_gnu_assemble -}; From a72be4f6ffaff420ccb5befb2ba8ca631b9b9fcd Mon Sep 17 00:00:00 2001 From: wargio Date: Sun, 8 Sep 2024 10:37:59 +0800 Subject: [PATCH 02/13] Update capstone-next wrap --- subprojects/capstone-next.wrap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subprojects/capstone-next.wrap b/subprojects/capstone-next.wrap index eaf386f5954..4bcb68ac2a2 100644 --- a/subprojects/capstone-next.wrap +++ b/subprojects/capstone-next.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://github.com/capstone-engine/capstone.git -revision = eb4fc2d7612db10379adf7aeb287a7923dcc0fc7 +revision = e9b9b649cd1ee368ff39ae284947470e694bf5b1 directory = capstone-next patch_directory = capstone-next depth = 1 From 163d3f47b83351f83dd185b82592954e2347e704 Mon Sep 17 00:00:00 2001 From: wargio Date: Sat, 7 Sep 2024 16:22:27 +0800 Subject: [PATCH 03/13] Add support to various mips cpus and features --- librz/arch/isa/arm/arm_esil64.c | 34 +- librz/arch/isa/arm/arm_il64.c | 122 +++---- librz/arch/p/analysis/analysis_arm_cs.c | 65 ++-- librz/arch/p/analysis/analysis_mips.c | 457 ++++++++++++++++++++++-- librz/arch/p/arch_mips.c | 145 ++++++++ librz/arch/p/asm/asm_mips.c | 35 +- librz/bin/format/te/te.c | 26 +- librz/bin/format/te/te.h | 1 + librz/bin/p/bin_coff.c | 9 + librz/bin/p/bin_mach0.c | 3 +- librz/bin/p/bin_psxexe.c | 1 + librz/bin/p/bin_te.c | 1 + librz/core/cbin.c | 23 +- librz/core/cconfig.c | 46 ++- librz/include/rz_analysis.h | 1 + 15 files changed, 790 insertions(+), 179 deletions(-) diff --git a/librz/arch/isa/arm/arm_esil64.c b/librz/arch/isa/arm/arm_esil64.c index b76c1273a6e..f484f9ea270 100644 --- a/librz/arch/isa/arm/arm_esil64.c +++ b/librz/arch/isa/arm/arm_esil64.c @@ -294,12 +294,12 @@ static void bfm(RzAnalysisOp *op, csh *handle, cs_insn *insn) { switch (insn->alias_id) { default: return; - case AArch64_INS_ALIAS_BFI: // bfi w8, w8, 2, 1 + case AARCH64_INS_ALIAS_BFI: // bfi w8, w8, 2, 1 width += 1; // TODO Mod depends on (sf && N) bits lsb = -lsb % 32; break; - case AArch64_INS_ALIAS_BFXIL: + case AARCH64_INS_ALIAS_BFXIL: width = width - lsb + 1; break; } @@ -314,25 +314,25 @@ static void bfm(RzAnalysisOp *op, csh *handle, cs_insn *insn) { static void subfm(RzAnalysisOp *op, csh *handle, cs_insn *insn) { ut64 lsb = IMM64(2); ut64 width = IMM64(3); - if (insn->alias_id == AArch64_INS_ALIAS_SBFIZ) { + if (insn->alias_id == AARCH64_INS_ALIAS_SBFIZ) { width += 1; lsb = -lsb % 64; rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%" PFMT64d ",%s,%" PFMT64u ",&,~,<<,%s,=", lsb, IMM64(3), REG64(1), rz_num_bitmask((ut8)width), REG64(0)); - } else if (insn->alias_id == AArch64_INS_ALIAS_UBFIZ) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_UBFIZ) { width += 1; lsb = -lsb % 64; rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%s,%" PFMT64u ",&,<<,%s,=", lsb, REG64(1), rz_num_bitmask((ut8)width), REG64(0)); - } else if (insn->alias_id == AArch64_INS_ALIAS_SBFX) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_SBFX) { width = width - lsb + 1; rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%" PFMT64d ",%s,%" PFMT64d ",%" PFMT64u ",<<,&,>>,~,%s,=", IMM64(3), IMM64(2), REG64(1), IMM64(2), rz_num_bitmask((ut8)IMM64(3)), REG64(0)); - } else if (insn->alias_id == AArch64_INS_ALIAS_UBFX) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_UBFX) { width = width - lsb + 1; rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%s,%" PFMT64d ",%" PFMT64u ",<<,&,>>,%s,=", lsb, REG64(1), lsb, rz_num_bitmask((ut8)width), REG64(0)); - } else if (insn->alias_id == AArch64_INS_ALIAS_LSL) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_LSL) { // imms != 0x1f => mod 32 // imms != 0x3f => mod 64 ut32 m = IMM64(3) != 0x1f ? 32 : 64; @@ -352,7 +352,7 @@ static void subfm(RzAnalysisOp *op, csh *handle, cs_insn *insn) { ut64 i2 = IMM64(2) % m; rz_strbuf_setf(&op->esil, "%" PFMT64d ",%s,<<,%s,=", i2 % (ut64)size, r1, r0); } - } else if (insn->alias_id == AArch64_INS_ALIAS_LSR) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_LSR) { const char *r0 = REG64(0); const char *r1 = REG64(1); const int size = REGSIZE64(0) * 8; @@ -369,7 +369,7 @@ static void subfm(RzAnalysisOp *op, csh *handle, cs_insn *insn) { ut64 i2 = IMM64(2); rz_strbuf_setf(&op->esil, "%" PFMT64d ",%s,>>,%s,=", i2 % (ut64)size, r1, r0); } - } else if (insn->alias_id == AArch64_INS_ALIAS_ASR) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_ASR) { const char *r0 = REG64(0); const char *r1 = REG64(1); const int size = REGSIZE64(0) * 8; @@ -883,9 +883,9 @@ RZ_IPI int rz_arm_cs_analysis_op_64_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 a break; } #if CS_NEXT_VERSION >= 6 - case AArch64_INS_SUBS: - if (insn->alias_id != AArch64_INS_ALIAS_CMP && - insn->alias_id != AArch64_INS_ALIAS_CMN) { + case AARCH64_INS_SUBS: + if (insn->alias_id != AARCH64_INS_ALIAS_CMP && + insn->alias_id != AARCH64_INS_ALIAS_CMN) { cmp(op, handle, insn); break; } @@ -926,13 +926,13 @@ RZ_IPI int rz_arm_cs_analysis_op_64_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 a rz_strbuf_appendf(&op->esil, "%s,}{,1,%s,+,},%s,=", REG64(1), REG64(2), REG64(0)); postfix = ""; break; - case AArch64_INS_ALIAS_CSET: // cset Wd --> Wd := (cond) ? 1 : 0 + case AARCH64_INS_ALIAS_CSET: // cset Wd --> Wd := (cond) ? 1 : 0 rz_strbuf_drain_nofree(&op->esil); rz_arm64_cs_esil_prefix_cond(op, AArch64CC_getInvertedCondCode(insn->detail->CS_aarch64_.cc)); rz_strbuf_appendf(&op->esil, "1,}{,0,},%s,=", REG64(0)); postfix = ""; break; - case AArch64_INS_ALIAS_CINC: // cinc Wd, Wn --> Wd := (cond) ? (Wn+1) : Wn + case AARCH64_INS_ALIAS_CINC: // cinc Wd, Wn --> Wd := (cond) ? (Wn+1) : Wn rz_strbuf_drain_nofree(&op->esil); rz_arm64_cs_esil_prefix_cond(op, AArch64CC_getInvertedCondCode(insn->detail->CS_aarch64_.cc)); rz_strbuf_appendf(&op->esil, "1,%s,+,}{,%s,},%s,=", REG64(1), REG64(1), REG64(0)); @@ -1322,11 +1322,11 @@ RZ_IPI int rz_arm_cs_analysis_op_64_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 a } break; #else - case AArch64_INS_BFM: + case AARCH64_INS_BFM: bfm(op, handle, insn); break; - case AArch64_INS_UBFM: - case AArch64_INS_SBFM: + case AARCH64_INS_UBFM: + case AARCH64_INS_SBFM: subfm(op, handle, insn); break; #endif diff --git a/librz/arch/isa/arm/arm_il64.c b/librz/arch/isa/arm/arm_il64.c index 9ebc3c87ed3..6bc1a4032d9 100644 --- a/librz/arch/isa/arm/arm_il64.c +++ b/librz/arch/isa/arm/arm_il64.c @@ -596,8 +596,8 @@ static RzILOpEffect *shift(cs_insn *insn) { res = LOGOR(SHIFTR0(a, b), SHIFTL0(DUP(a), NEG(DUP(b)))); break; #if CS_NEXT_VERSION >= 6 - case AArch64_INS_EXTR: - if (insn->alias_id != AArch64_INS_ALIAS_ROR) { + case AARCH64_INS_EXTR: + if (insn->alias_id != AARCH64_INS_ALIAS_ROR) { return NULL; } b = ARG(3, &bits); @@ -682,14 +682,14 @@ static RzILOpEffect *bfm(cs_insn *insn) { #else ut64 lsb = IMM(2); ut64 width = IMM(3); - if (insn->alias_id == AArch64_INS_ALIAS_BFI) { + if (insn->alias_id == AARCH64_INS_ALIAS_BFI) { width += 1; // TODO Mod depends on (sf && N) bits lsb = -lsb % 32; ut64 mask_base = rz_num_bitmask(width); ut64 mask = mask_base << RZ_MIN(63, lsb); return write_reg(REGID(0), LOGOR(LOGAND(a, UN(bits, ~mask)), SHIFTL0(LOGAND(b, UN(bits, mask_base)), UN(6, lsb)))); - } else if (insn->alias_id == AArch64_INS_ALIAS_BFXIL) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_BFXIL) { width = width - lsb + 1; ut64 mask_base = rz_num_bitmask(width); ut64 mask = mask_base << RZ_MIN(63, lsb); @@ -853,8 +853,8 @@ static RzILOpEffect *cmp(cs_insn *insn) { #else RzILOpBitVector *a; RzILOpBitVector *b; - if (insn->alias_id == AArch64_INS_ALIAS_CMP || - insn->alias_id == AArch64_INS_ALIAS_CMN) { + if (insn->alias_id == AARCH64_INS_ALIAS_CMP || + insn->alias_id == AARCH64_INS_ALIAS_CMN) { // Reg at 0 is zero register a = ARG(1, &bits); b = ARG(2, &bits); @@ -871,7 +871,7 @@ static RzILOpEffect *cmp(cs_insn *insn) { #if CS_NEXT_VERSION < 6 bool is_neg = insn->id == CS_AARCH64(_INS_CMN) || insn->id == CS_AARCH64(_INS_CCMN); #else - bool is_neg = insn->alias_id == AArch64_INS_ALIAS_CMN || insn->id == CS_AARCH64(_INS_CCMN); + bool is_neg = insn->alias_id == AARCH64_INS_ALIAS_CMN || insn->id == CS_AARCH64(_INS_CCMN); #endif RzILOpEffect *eff = SEQ6( SETL("a", a), @@ -917,9 +917,9 @@ static RzILOpEffect *csinc(cs_insn *insn) { RzILOpBool *c = cond(insn->detail->CS_aarch64_.cc); #else AArch64CC_CondCode cc; - if (insn->alias_id == AArch64_INS_ALIAS_CINV || - insn->alias_id == AArch64_INS_ALIAS_CNEG || - insn->alias_id == AArch64_INS_ALIAS_CINC) { + if (insn->alias_id == AARCH64_INS_ALIAS_CINV || + insn->alias_id == AARCH64_INS_ALIAS_CNEG || + insn->alias_id == AARCH64_INS_ALIAS_CINC) { cc = AArch64CC_getInvertedCondCode(insn->detail->CS_aarch64_.cc); } else { cc = insn->detail->CS_aarch64_.cc; @@ -996,8 +996,8 @@ static RzILOpEffect *cset(cs_insn *insn) { #if CS_NEXT_VERSION < 6 c = cond(insn->detail->CS_aarch64_.cc); #else - if (insn->alias_id == AArch64_INS_ALIAS_CSET || - insn->alias_id == AArch64_INS_ALIAS_CSETM) { + if (insn->alias_id == AARCH64_INS_ALIAS_CSET || + insn->alias_id == AARCH64_INS_ALIAS_CSETM) { c = cond(AArch64CC_getInvertedCondCode(insn->detail->CS_aarch64_.cc)); } else { c = cond(insn->detail->CS_aarch64_.cc); @@ -1010,7 +1010,7 @@ static RzILOpEffect *cset(cs_insn *insn) { #if CS_NEXT_VERSION < 6 return write_reg(REGID(0), ITE(c, SN(bits, insn->id == CS_AARCH64(_INS_CSETM) ? -1 : 1), SN(bits, 0))); #else - return write_reg(REGID(0), ITE(c, SN(bits, insn->alias_id == AArch64_INS_ALIAS_CSETM ? -1 : 1), SN(bits, 0))); + return write_reg(REGID(0), ITE(c, SN(bits, insn->alias_id == AARCH64_INS_ALIAS_CSETM ? -1 : 1), SN(bits, 0))); #endif } @@ -1792,7 +1792,7 @@ static RzILOpEffect *mul(cs_insn *insn) { res = NEG(res); } #else - if (insn->alias_id == AArch64_INS_ALIAS_MNEG) { + if (insn->alias_id == AARCH64_INS_ALIAS_MNEG) { res = NEG(res); } #endif @@ -1824,8 +1824,8 @@ static RzILOpEffect *mov(cs_insn *insn) { RzILOpBitVector *src = ARG(1, &bits); #else RzILOpBitVector *src = NULL; - if ((insn->alias_id == AArch64_INS_ALIAS_MOV || insn->alias_id == AArch64_INS_ALIAS_MOVZ) && - (REGID(1) == AArch64_REG_XZR || REGID(1) == AArch64_REG_WZR)) { + if ((insn->alias_id == AARCH64_INS_ALIAS_MOV || insn->alias_id == AARCH64_INS_ALIAS_MOVZ) && + (REGID(1) == AARCH64_REG_XZR || REGID(1) == AARCH64_REG_WZR)) { // Sometimes regs are ORed with the zero register for the MOV alias. // Sometimes not. src = ARG(2, &bits); @@ -1971,29 +1971,29 @@ static RzILOpEffect *usbfm(cs_insn *insn) { } bool is_signed = insn->id == CS_AARCH64(_INS_SBFX) || insn->id == CS_AARCH64(_INS_SBFIZ); #else - if (insn->alias_id == AArch64_INS_ALIAS_SBFIZ || insn->alias_id == AArch64_INS_ALIAS_UBFIZ) { + if (insn->alias_id == AARCH64_INS_ALIAS_SBFIZ || insn->alias_id == AARCH64_INS_ALIAS_UBFIZ) { // TODO: modulo usage depends on N and SF bit. // sf == 0 && N == 0 => mod 32. // sf == 1 && N == 1 => mod 64. width += 1; lsb = -lsb % 64; res = SHIFTL0(UNSIGNED(width + lsb, src), UN(6, lsb)); - } else if (insn->alias_id == AArch64_INS_ALIAS_SBFX || insn->alias_id == AArch64_INS_ALIAS_UBFX) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_SBFX || insn->alias_id == AARCH64_INS_ALIAS_UBFX) { width = width - lsb + 1; res = UNSIGNED(width, SHIFTR0(src, UN(6, lsb))); - } else if (insn->alias_id == AArch64_INS_ALIAS_LSL) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_LSL) { // imms != 0x1f => mod 32 // imms != 0x3f => mod 64 ut32 m = IMM(3) != 0x1f ? 32 : 64; return write_reg(REGID(0), SHIFTL0(src, UN(6, -IMM(2) % m))); - } else if (insn->alias_id == AArch64_INS_ALIAS_LSR) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_LSR) { return write_reg(REGID(0), SHIFTR0(src, UN(6, IMM(2)))); - } else if (insn->alias_id == AArch64_INS_ALIAS_ASR) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_ASR) { return write_reg(REGID(0), SHIFTR(MSB(src), DUP(src), UN(6, IMM(2)))); } else { return NULL; } - bool is_signed = insn->alias_id == AArch64_INS_ALIAS_SBFX || insn->alias_id == AArch64_INS_ALIAS_SBFIZ; + bool is_signed = insn->alias_id == AARCH64_INS_ALIAS_SBFX || insn->alias_id == AARCH64_INS_ALIAS_SBFIZ; #endif res = LET("res", res, is_signed ? SIGNED(bits, VARLP("res")) : UNSIGNED(bits, VARLP("res"))); return write_reg(REGID(0), res); @@ -2067,15 +2067,15 @@ static RzILOpEffect *mvn(cs_insn *insn) { } #else switch (insn->alias_id) { - case AArch64_INS_ALIAS_NEG: - case AArch64_INS_ALIAS_NEGS: + case AARCH64_INS_ALIAS_NEG: + case AARCH64_INS_ALIAS_NEGS: res = NEG(val); break; - case AArch64_INS_ALIAS_NGC: - case AArch64_INS_ALIAS_NGCS: + case AARCH64_INS_ALIAS_NGC: + case AARCH64_INS_ALIAS_NGCS: res = NEG(ADD(val, ITE(VARG("cf"), UN(bits, 0), UN(bits, 1)))); break; - case AArch64_INS_ALIAS_MVN: + case AARCH64_INS_ALIAS_MVN: res = LOGNOT(val); break; default: @@ -2092,7 +2092,7 @@ static RzILOpEffect *mvn(cs_insn *insn) { #if CS_NEXT_VERSION < 6 RzILOpEffect *set_cf = SETG("cf", sub_carry(UN(bits, 0), VARL("b"), insn->id == CS_AARCH64(_INS_NGC), bits)); #else - RzILOpEffect *set_cf = SETG("cf", sub_carry(UN(bits, 0), VARL("b"), insn->alias_id == AArch64_INS_ALIAS_NGC, bits)); + RzILOpEffect *set_cf = SETG("cf", sub_carry(UN(bits, 0), VARL("b"), insn->alias_id == AARCH64_INS_ALIAS_NGC, bits)); #endif return SEQ5( SETL("b", DUP(val)), @@ -2316,7 +2316,7 @@ static RzILOpEffect *smull(cs_insn *insn) { #if CS_NEXT_VERSION < 6 bool is_signed = insn->id == CS_AARCH64(_INS_SMULL) || insn->id == CS_AARCH64(_INS_SMNEGL); #else - bool is_signed = insn->alias_id == AArch64_INS_ALIAS_SMULL || insn->alias_id == AArch64_INS_ALIAS_SMNEGL; + bool is_signed = insn->alias_id == AARCH64_INS_ALIAS_SMULL || insn->alias_id == AARCH64_INS_ALIAS_SMNEGL; #endif RzILOpBitVector *res = MUL(is_signed ? SIGNED(64, x) : UNSIGNED(64, x), is_signed ? SIGNED(64, y) : UNSIGNED(64, y)); #if CS_NEXT_VERSION < 6 @@ -2324,7 +2324,7 @@ static RzILOpEffect *smull(cs_insn *insn) { res = NEG(res); } #else - if (insn->alias_id == AArch64_INS_ALIAS_SMNEGL || insn->alias_id == AArch64_INS_ALIAS_UMNEGL) { + if (insn->alias_id == AARCH64_INS_ALIAS_SMNEGL || insn->alias_id == AARCH64_INS_ALIAS_UMNEGL) { res = NEG(res); } #endif @@ -2444,19 +2444,19 @@ static RzILOpEffect *sxt(cs_insn *insn) { switch (insn->alias_id) { default: return NULL; - case AArch64_INS_ALIAS_UXTB: + case AARCH64_INS_ALIAS_UXTB: is_signed = false; // fallthrough - case AArch64_INS_ALIAS_SXTB: + case AARCH64_INS_ALIAS_SXTB: bits = 8; break; - case AArch64_INS_ALIAS_UXTH: + case AARCH64_INS_ALIAS_UXTH: is_signed = false; // fallthrough - case AArch64_INS_ALIAS_SXTH: + case AARCH64_INS_ALIAS_SXTH: bits = 16; break; - case AArch64_INS_ALIAS_SXTW: + case AARCH64_INS_ALIAS_SXTW: bits = 32; break; } @@ -2612,16 +2612,16 @@ RZ_IPI RzILOpEffect *rz_arm_cs_64_il(csh *handle, cs_insn *insn) { case CS_AARCH64(_INS_SBCS): #endif #if CS_NEXT_VERSION >= 6 - if (insn->alias_id == AArch64_INS_ALIAS_MOV || - insn->alias_id == AArch64_INS_ALIAS_MOVZ) { + if (insn->alias_id == AARCH64_INS_ALIAS_MOV || + insn->alias_id == AARCH64_INS_ALIAS_MOVZ) { return mov(insn); - } else if (insn->alias_id == AArch64_INS_ALIAS_CMP || - insn->alias_id == AArch64_INS_ALIAS_CMN) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_CMP || + insn->alias_id == AARCH64_INS_ALIAS_CMN) { return cmp(insn); - } else if (insn->alias_id == AArch64_INS_ALIAS_NEG || - insn->alias_id == AArch64_INS_ALIAS_NGC || - insn->alias_id == AArch64_INS_ALIAS_NEGS || - insn->alias_id == AArch64_INS_ALIAS_NGCS) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_NEG || + insn->alias_id == AARCH64_INS_ALIAS_NGC || + insn->alias_id == AARCH64_INS_ALIAS_NEGS || + insn->alias_id == AARCH64_INS_ALIAS_NGCS) { return mvn(insn); } #endif @@ -2638,12 +2638,12 @@ RZ_IPI RzILOpEffect *rz_arm_cs_64_il(csh *handle, cs_insn *insn) { case CS_AARCH64(_INS_ORN): case CS_AARCH64(_INS_ORR): #if CS_NEXT_VERSION >= 6 - if (insn->alias_id == AArch64_INS_ALIAS_MOV || - insn->alias_id == AArch64_INS_ALIAS_MOVZ) { + if (insn->alias_id == AARCH64_INS_ALIAS_MOV || + insn->alias_id == AARCH64_INS_ALIAS_MOVZ) { return mov(insn); - } else if (insn->alias_id == AArch64_INS_ALIAS_TST) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_TST) { return tst(insn); - } else if (insn->alias_id == AArch64_INS_ALIAS_MVN) { + } else if (insn->alias_id == AARCH64_INS_ALIAS_MVN) { return mvn(insn); } #endif @@ -2728,8 +2728,8 @@ RZ_IPI RzILOpEffect *rz_arm_cs_64_il(csh *handle, cs_insn *insn) { case CS_AARCH64(_INS_CINV): case CS_AARCH64(_INS_CNEG): #else - if (insn->alias_id == AArch64_INS_ALIAS_CSET || - insn->alias_id == AArch64_INS_ALIAS_CSETM) { + if (insn->alias_id == AARCH64_INS_ALIAS_CSET || + insn->alias_id == AARCH64_INS_ALIAS_CSETM) { return cset(insn); } #endif @@ -2745,7 +2745,7 @@ RZ_IPI RzILOpEffect *rz_arm_cs_64_il(csh *handle, cs_insn *insn) { return clz(insn); case CS_AARCH64(_INS_EXTR): #if CS_NEXT_VERSION >= 6 - if (insn->alias_id == AArch64_INS_ALIAS_ROR) { + if (insn->alias_id == AARCH64_INS_ALIAS_ROR) { return shift(insn); } #endif @@ -2969,8 +2969,8 @@ RZ_IPI RzILOpEffect *rz_arm_cs_64_il(csh *handle, cs_insn *insn) { case CS_AARCH64(_INS_MADD): case CS_AARCH64(_INS_MSUB): #if CS_NEXT_VERSION >= 6 - if (insn->alias_id == AArch64_INS_ALIAS_MUL || - insn->alias_id == AArch64_INS_ALIAS_MNEG) { + if (insn->alias_id == AARCH64_INS_ALIAS_MUL || + insn->alias_id == AARCH64_INS_ALIAS_MNEG) { return mul(insn); } #endif @@ -3017,11 +3017,11 @@ RZ_IPI RzILOpEffect *rz_arm_cs_64_il(csh *handle, cs_insn *insn) { case CS_AARCH64(_INS_UBFIZ): case CS_AARCH64(_INS_UBFX): #else - if (insn->alias_id == AArch64_INS_ALIAS_UXTH || - insn->alias_id == AArch64_INS_ALIAS_UXTB || - insn->alias_id == AArch64_INS_ALIAS_SXTH || - insn->alias_id == AArch64_INS_ALIAS_SXTB || - insn->alias_id == AArch64_INS_ALIAS_SXTW) { + if (insn->alias_id == AARCH64_INS_ALIAS_UXTH || + insn->alias_id == AARCH64_INS_ALIAS_UXTB || + insn->alias_id == AARCH64_INS_ALIAS_SXTH || + insn->alias_id == AARCH64_INS_ALIAS_SXTB || + insn->alias_id == AARCH64_INS_ALIAS_SXTW) { return sxt(insn); } #endif @@ -3038,10 +3038,10 @@ RZ_IPI RzILOpEffect *rz_arm_cs_64_il(csh *handle, cs_insn *insn) { case CS_AARCH64(_INS_UMADDL): case CS_AARCH64(_INS_UMSUBL): #if CS_NEXT_VERSION >= 6 - if (insn->alias_id == AArch64_INS_ALIAS_SMULL || - insn->alias_id == AArch64_INS_ALIAS_UMULL || - insn->alias_id == AArch64_INS_ALIAS_SMNEGL || - insn->alias_id == AArch64_INS_ALIAS_UMNEGL) { + if (insn->alias_id == AARCH64_INS_ALIAS_SMULL || + insn->alias_id == AARCH64_INS_ALIAS_UMULL || + insn->alias_id == AARCH64_INS_ALIAS_SMNEGL || + insn->alias_id == AARCH64_INS_ALIAS_UMNEGL) { return smull(insn); } #endif diff --git a/librz/arch/p/analysis/analysis_arm_cs.c b/librz/arch/p/analysis/analysis_arm_cs.c index 48fd939f8ea..b4d374ac7b0 100644 --- a/librz/arch/p/analysis/analysis_arm_cs.c +++ b/librz/arch/p/analysis/analysis_arm_cs.c @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2013-2021 pancake // SPDX-License-Identifier: LGPL-3.0-only +#include "aarch64.h" #include #include #include @@ -525,37 +526,37 @@ static void opex64(RzStrBuf *buf, csh handle, cs_insn *insn) { pj_ki(pj, "value", op->barrier - 1); break; #else - case AArch64_OP_SYSALIAS: + case AARCH64_OP_SYSALIAS: switch (op->sysop.sub_type) { default: pj_ks(pj, "type", "sys"); pj_kn(pj, "value", op->sysop.alias.raw_val); break; - case AArch64_OP_PSTATEIMM0_1: + case AARCH64_OP_PSTATEIMM0_1: pj_ks(pj, "type", "pstate"); pj_ki(pj, "value", op->sysop.alias.pstateimm0_1); break; - case AArch64_OP_PSTATEIMM0_15: + case AARCH64_OP_PSTATEIMM0_15: pj_ks(pj, "type", "pstate"); switch (op->sysop.alias.pstateimm0_15) { - case AArch64_PSTATEIMM0_15_SPSEL: + case AARCH64_PSTATEIMM0_15_SPSEL: pj_ks(pj, "value", "spsel"); break; - case AArch64_PSTATEIMM0_15_DAIFSET: + case AARCH64_PSTATEIMM0_15_DAIFSET: pj_ks(pj, "value", "daifset"); break; - case AArch64_PSTATEIMM0_15_DAIFCLR: + case AARCH64_PSTATEIMM0_15_DAIFCLR: pj_ks(pj, "value", "daifclr"); break; default: pj_ki(pj, "value", op->sysop.alias.pstateimm0_15); } break; - case AArch64_OP_PRFM: + case AARCH64_OP_PRFM: pj_ks(pj, "type", "prefetch"); pj_ki(pj, "value", op->sysop.alias.prfm); break; - case AArch64_OP_DB: + case AARCH64_OP_DB: pj_ks(pj, "type", "prefetch"); pj_ki(pj, "value", op->sysop.alias.db); break; @@ -599,7 +600,7 @@ static void opex64(RzStrBuf *buf, csh handle, cs_insn *insn) { #if CS_NEXT_VERSION < 6 if (op->vas != CS_AARCH64_VL_(INVALID)) { #else - if (op->vas != AArch64Layout_Invalid) { + if (op->vas != AARCH64LAYOUT_INVALID) { #endif pj_ks(pj, "vas", vas_name(op->vas)); } @@ -689,23 +690,23 @@ static int cond_cs2rz_64(int cc) { #if CS_NEXT_VERSION >= 6 static bool is_system_hint(const cs_insn *insn) { - rz_return_val_if_fail(insn && insn->id == AArch64_INS_HINT, false); + rz_return_val_if_fail(insn && insn->id == AARCH64_INS_HINT, false); switch (insn->alias_id) { default: return false; - case AArch64_INS_ALIAS_PACIA1716: - case AArch64_INS_ALIAS_PACIASP: - case AArch64_INS_ALIAS_PACIAZ: - case AArch64_INS_ALIAS_PACIB1716: - case AArch64_INS_ALIAS_PACIBSP: - case AArch64_INS_ALIAS_PACIBZ: - case AArch64_INS_ALIAS_AUTIA1716: - case AArch64_INS_ALIAS_AUTIASP: - case AArch64_INS_ALIAS_AUTIAZ: - case AArch64_INS_ALIAS_AUTIB1716: - case AArch64_INS_ALIAS_AUTIBSP: - case AArch64_INS_ALIAS_AUTIBZ: - case AArch64_INS_ALIAS_XPACLRI: + case AARCH64_INS_ALIAS_PACIA1716: + case AARCH64_INS_ALIAS_PACIASP: + case AARCH64_INS_ALIAS_PACIAZ: + case AARCH64_INS_ALIAS_PACIB1716: + case AARCH64_INS_ALIAS_PACIBSP: + case AARCH64_INS_ALIAS_PACIBZ: + case AARCH64_INS_ALIAS_AUTIA1716: + case AARCH64_INS_ALIAS_AUTIASP: + case AARCH64_INS_ALIAS_AUTIAZ: + case AARCH64_INS_ALIAS_AUTIB1716: + case AARCH64_INS_ALIAS_AUTIBSP: + case AARCH64_INS_ALIAS_AUTIBZ: + case AARCH64_INS_ALIAS_XPACLRI: return true; } } @@ -732,17 +733,17 @@ static void anop64(AnalysisArmCSContext *ctx, RzAnalysisOp *op, cs_insn *insn) { } #else /* grab family */ - if (cs_insn_group(handle, insn, AArch64_FEATURE_HasAES)) { + if (cs_insn_group(handle, insn, AARCH64_FEATURE_HASAES)) { op->family = RZ_ANALYSIS_OP_FAMILY_CRYPTO; - } else if (cs_insn_group(handle, insn, AArch64_FEATURE_HasCRC)) { + } else if (cs_insn_group(handle, insn, AARCH64_FEATURE_HASCRC)) { op->family = RZ_ANALYSIS_OP_FAMILY_CRYPTO; - } else if (cs_insn_group(handle, insn, AArch64_GRP_PRIVILEGE)) { + } else if (cs_insn_group(handle, insn, AARCH64_GRP_PRIVILEGE)) { op->family = RZ_ANALYSIS_OP_FAMILY_PRIV; - } else if (cs_insn_group(handle, insn, AArch64_FEATURE_HasNEON)) { + } else if (cs_insn_group(handle, insn, AARCH64_FEATURE_HASNEON)) { op->family = RZ_ANALYSIS_OP_FAMILY_MMX; - } else if (cs_insn_group(handle, insn, AArch64_FEATURE_HasMTE)) { + } else if (cs_insn_group(handle, insn, AARCH64_FEATURE_HASMTE)) { op->family = RZ_ANALYSIS_OP_FAMILY_SECURITY; - } else if (cs_insn_group(handle, insn, AArch64_FEATURE_HasFPARMv8)) { + } else if (cs_insn_group(handle, insn, AARCH64_FEATURE_HASFPARMV8)) { op->family = RZ_ANALYSIS_OP_FAMILY_FPU; } else { op->family = RZ_ANALYSIS_OP_FAMILY_CPU; @@ -1012,7 +1013,7 @@ static void anop64(AnalysisArmCSContext *ctx, RzAnalysisOp *op, cs_insn *insn) { break; #if CS_NEXT_VERSION >= 6 case CS_AARCH64(_INS_ADDS): - if (is_alias64(insn, AArch64_INS_ALIAS_CMN)) { + if (is_alias64(insn, AARCH64_INS_ALIAS_CMN)) { op->type = RZ_ANALYSIS_OP_TYPE_CMP; } else { op->type = RZ_ANALYSIS_OP_TYPE_ADD; @@ -1022,7 +1023,7 @@ static void anop64(AnalysisArmCSContext *ctx, RzAnalysisOp *op, cs_insn *insn) { } break; case CS_AARCH64(_INS_SUBS): - if (is_alias64(insn, AArch64_INS_ALIAS_CMP)) { + if (is_alias64(insn, AARCH64_INS_ALIAS_CMP)) { op->type = RZ_ANALYSIS_OP_TYPE_CMP; } else { op->type = RZ_ANALYSIS_OP_TYPE_SUB; @@ -1032,7 +1033,7 @@ static void anop64(AnalysisArmCSContext *ctx, RzAnalysisOp *op, cs_insn *insn) { } break; case CS_AARCH64(_INS_ANDS): - if (is_alias64(insn, AArch64_INS_ALIAS_TST)) { + if (is_alias64(insn, AARCH64_INS_ALIAS_TST)) { op->type = RZ_ANALYSIS_OP_TYPE_CMP; } else { op->type = RZ_ANALYSIS_OP_TYPE_AND; diff --git a/librz/arch/p/analysis/analysis_mips.c b/librz/arch/p/analysis/analysis_mips.c index 7675d97e972..402f7ac7c5f 100644 --- a/librz/arch/p/analysis/analysis_mips.c +++ b/librz/arch/p/analysis/analysis_mips.c @@ -790,27 +790,8 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u int n = 0, opsize = -1; csh hndl = 0; cs_insn *insn = NULL; - int mode = analysis->big_endian ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN; - - if (analysis->cpu && *analysis->cpu) { - if (!strcmp(analysis->cpu, "micro")) { - mode |= CS_MODE_MICRO; - } else if (!strcmp(analysis->cpu, "r6")) { - mode |= CS_MODE_MIPS32R6; - } else if (!strcmp(analysis->cpu, "v3")) { - mode |= CS_MODE_MIPS3; - } else if (!strcmp(analysis->cpu, "v2")) { - mode |= CS_MODE_MIPS2; - } - } - switch (analysis->bits) { - case 64: - mode |= CS_MODE_MIPS64; - break; - case 32: - mode |= CS_MODE_MIPS32; - break; - default: + cs_mode mode = 0; + if (!cs_mode_from_cpu(analysis->cpu, analysis->features, analysis->bits, analysis->big_endian, &mode)) { return -1; } @@ -846,6 +827,434 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u case MIPS_INS_INVALID: op->type = RZ_ANALYSIS_OP_TYPE_ILL; break; + case MIPS_INS_LB: + case MIPS_INS_LBU: + case MIPS_INS_LBUX: + op->refptr = 1; + /* fallthrough */ + case MIPS_INS_LW: + case MIPS_INS_LWC1: + case MIPS_INS_LWC2: + case MIPS_INS_LWL: + case MIPS_INS_LWR: + case MIPS_INS_LWXC1: + if (!op->refptr) { + op->refptr = 4; + } + /* fallthrough */ + case MIPS_INS_LD: + case MIPS_INS_LDC1: + case MIPS_INS_LDC2: + case MIPS_INS_LDL: + case MIPS_INS_LDR: + case MIPS_INS_LDXC1: + op->type = RZ_ANALYSIS_OP_TYPE_LOAD; + if (!op->refptr) { + op->refptr = 8; + } + switch (OPERAND(1).type) { + case MIPS_OP_MEM: + if (OPERAND(1).mem.base == MIPS_REG_GP) { + op->ptr = analysis->gp + OPERAND(1).mem.disp; + if (REGID(0) == MIPS_REG_T9) { + t9_pre = op->ptr; + } +#if CS_NEXT_VERSION < 6 + } else if (REGID(0) == MIPS_REG_T9) { +#else + } else if (REGID(0) == MIPS_REG_T9 || + REGID(0) == MIPS_REG_T9_64) { +#endif + t9_pre = UT64_MAX; + } + break; + case MIPS_OP_IMM: + op->ptr = OPERAND(1).imm; + break; + case MIPS_OP_REG: + break; + default: + break; + } + // TODO: fill + break; + case MIPS_INS_SD: + case MIPS_INS_SW: + case MIPS_INS_SB: + case MIPS_INS_SH: + case MIPS_INS_SWC1: + case MIPS_INS_SWC2: + case MIPS_INS_SWL: + case MIPS_INS_SWR: + case MIPS_INS_SWXC1: + op->type = RZ_ANALYSIS_OP_TYPE_STORE; + break; + case MIPS_INS_NOP: + op->type = RZ_ANALYSIS_OP_TYPE_NOP; + break; + case MIPS_INS_SYSCALL: + op->type = RZ_ANALYSIS_OP_TYPE_SWI; + break; + case MIPS_INS_BREAK: + op->type = RZ_ANALYSIS_OP_TYPE_TRAP; + break; +#if CS_NEXT_VERSION > 5 + case MIPS_INS_JALR_HB: + case MIPS_INS_JALRC: + case MIPS_INS_JALRC_HB: + case MIPS_INS_JALRS: + case MIPS_INS_JALRS16: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_JALR: + op->type = RZ_ANALYSIS_OP_TYPE_UCALL; + op->delay = 1; +#if CS_NEXT_VERSION < 6 + if (REGID(0) == MIPS_REG_25) { +#else + if (REGID(0) == MIPS_REG_T9 || + REGID(0) == MIPS_REG_T9_64) { +#endif + op->jump = t9_pre; + t9_pre = UT64_MAX; + op->type = RZ_ANALYSIS_OP_TYPE_RCALL; + } + break; + case MIPS_INS_JAL: + case MIPS_INS_JALS: + case MIPS_INS_JALX: + case MIPS_INS_JRADDIUSP: + case MIPS_INS_BAL: + // (no blezal/bgtzal or blezall/bgtzall, only blezalc/bgtzalc) + case MIPS_INS_BLTZAL: // Branch on <0 and link + case MIPS_INS_BGEZAL: // Branch on >=0 and link + case MIPS_INS_BLTZALL: // "likely" versions + case MIPS_INS_BGEZALL: + case MIPS_INS_BLTZALC: // compact versions + case MIPS_INS_BLEZALC: + case MIPS_INS_BGEZALC: + case MIPS_INS_BGTZALC: + case MIPS_INS_JIALC: + case MIPS_INS_JIC: + op->type = RZ_ANALYSIS_OP_TYPE_CALL; + op->jump = IMM(0); + + switch (insn->id) { + case MIPS_INS_JIALC: + case MIPS_INS_JIC: + case MIPS_INS_BLTZALC: + case MIPS_INS_BLEZALC: + case MIPS_INS_BGEZALC: + case MIPS_INS_BGTZALC: + // compact versions (no delay) + op->delay = 0; + op->fail = addr + 4; + break; + default: + op->delay = 1; + op->fail = addr + 8; + break; + } + break; + case MIPS_INS_LI: + case MIPS_INS_LUI: + SET_VAL(op, 1); + op->type = RZ_ANALYSIS_OP_TYPE_MOV; + break; + case MIPS_INS_MOVE: + op->type = RZ_ANALYSIS_OP_TYPE_MOV; + break; + case MIPS_INS_ADD: + case MIPS_INS_ADDI: + case MIPS_INS_ADDU: + case MIPS_INS_ADDIU: + case MIPS_INS_DADD: + case MIPS_INS_DADDI: + case MIPS_INS_DADDIU: + SET_VAL(op, 2); + op->sign = (insn->id == MIPS_INS_ADDI || insn->id == MIPS_INS_ADD); + op->type = RZ_ANALYSIS_OP_TYPE_ADD; + if (REGID(0) == MIPS_REG_T9) { + t9_pre += IMM(2); + } + if (REGID(0) == MIPS_REG_SP) { + op->stackop = RZ_ANALYSIS_STACK_INC; + op->stackptr = -IMM(2); + } + break; + case MIPS_INS_SUB: + case MIPS_INS_SUBU: + case MIPS_INS_DSUBU: + case MIPS_INS_DSUB: +#if CS_NEXT_VERSION < 6 + case MIPS_INS_SUBV: + case MIPS_INS_SUBVI: + case MIPS_INS_FSUB: + case MIPS_INS_FMSUB: + case MIPS_INS_SUBS_S: + case MIPS_INS_SUBS_U: + case MIPS_INS_SUBUH: + case MIPS_INS_SUBUH_R: +#else + case MIPS_INS_SUBV_B: + case MIPS_INS_SUBV_D: + case MIPS_INS_SUBV_H: + case MIPS_INS_SUBV_W: + case MIPS_INS_SUBVI_B: + case MIPS_INS_SUBVI_D: + case MIPS_INS_SUBVI_H: + case MIPS_INS_SUBVI_W: + case MIPS_INS_FSUB_D: + case MIPS_INS_FSUB_W: + case MIPS_INS_FMSUB_D: + case MIPS_INS_FMSUB_W: + case MIPS_INS_SUBS_S_B: + case MIPS_INS_SUBS_S_D: + case MIPS_INS_SUBS_S_H: + case MIPS_INS_SUBS_S_W: + case MIPS_INS_SUBS_U_B: + case MIPS_INS_SUBS_U_D: + case MIPS_INS_SUBS_U_H: + case MIPS_INS_SUBS_U_W: + case MIPS_INS_SUBUH_QB: + case MIPS_INS_SUBUH_R_QB: +#endif /* CS_NEXT_VERSION */ + SET_VAL(op, 2); + op->sign = insn->id == MIPS_INS_SUB; + op->type = RZ_ANALYSIS_OP_TYPE_SUB; + break; +#if CS_NEXT_VERSION < 6 + case MIPS_INS_MULV: + case MIPS_INS_MULSA: + case MIPS_INS_FMUL: +#else + case MIPS_INS_MULV_B: + case MIPS_INS_MULV_D: + case MIPS_INS_MULV_H: + case MIPS_INS_MULV_W: + case MIPS_INS_MULSA_W_PH: + case MIPS_INS_MULSAQ_S_W_PH: + case MIPS_INS_FMUL_D: + case MIPS_INS_FMUL_W: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_MULT: + case MIPS_INS_MUL: + case MIPS_INS_DMULT: + case MIPS_INS_DMULTU: + op->type = RZ_ANALYSIS_OP_TYPE_MUL; + break; + case MIPS_INS_XOR: + case MIPS_INS_XORI: + SET_VAL(op, 2); + op->type = RZ_ANALYSIS_OP_TYPE_XOR; + break; + case MIPS_INS_AND: + case MIPS_INS_ANDI: + SET_VAL(op, 2); + op->type = RZ_ANALYSIS_OP_TYPE_AND; + if (REGID(0) == MIPS_REG_SP) { + op->stackop = RZ_ANALYSIS_STACK_ALIGN; + } + break; + case MIPS_INS_NOT: + op->type = RZ_ANALYSIS_OP_TYPE_NOT; + break; + case MIPS_INS_OR: + case MIPS_INS_ORI: + SET_VAL(op, 2); + op->type = RZ_ANALYSIS_OP_TYPE_OR; + break; + case MIPS_INS_DIV: + case MIPS_INS_DIVU: + case MIPS_INS_DDIV: + case MIPS_INS_DDIVU: +#if CS_NEXT_VERSION < 6 + case MIPS_INS_FDIV: + case MIPS_INS_DIV_U: +#else + case MIPS_INS_FDIV_D: + case MIPS_INS_FDIV_W: + case MIPS_INS_DIV_U_B: + case MIPS_INS_DIV_U_D: + case MIPS_INS_DIV_U_H: + case MIPS_INS_DIV_U_W: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_DIV_S: + op->type = RZ_ANALYSIS_OP_TYPE_DIV; + break; +#if CS_NEXT_VERSION < 6 + case MIPS_INS_CMPU: + case MIPS_INS_CMPGU: + case MIPS_INS_CMPGDU: +#else + case MIPS_INS_CMPU_EQ_QB: + case MIPS_INS_CMPGU_EQ_QB: + case MIPS_INS_CMPGDU_EQ_QB: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_CMPI: + case MIPS_INS_CMP: + op->type = RZ_ANALYSIS_OP_TYPE_CMP; + break; +#if CS_NEXT_VERSION < 6 + case MIPS_INS_BZ: + case MIPS_INS_BNZ: + case MIPS_INS_BNEG: + case MIPS_INS_BNEGI: +#else + case MIPS_INS_BZ_B: + case MIPS_INS_BZ_D: + case MIPS_INS_BZ_H: + case MIPS_INS_BZ_V: + case MIPS_INS_BZ_W: + case MIPS_INS_BNZ_B: + case MIPS_INS_BNZ_D: + case MIPS_INS_BNZ_H: + case MIPS_INS_BNZ_V: + case MIPS_INS_BNZ_W: + case MIPS_INS_BNEG_B: + case MIPS_INS_BNEG_D: + case MIPS_INS_BNEG_H: + case MIPS_INS_BNEG_W: + case MIPS_INS_BNEGI_B: + case MIPS_INS_BNEGI_D: + case MIPS_INS_BNEGI_H: + case MIPS_INS_BNEGI_W: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_J: + case MIPS_INS_B: + case MIPS_INS_BEQ: + case MIPS_INS_BNE: + case MIPS_INS_BNEL: + case MIPS_INS_BEQL: + case MIPS_INS_BEQZ: + case MIPS_INS_BNEZ: + case MIPS_INS_BTEQZ: + case MIPS_INS_BTNEZ: + case MIPS_INS_BLTZ: + case MIPS_INS_BLTZL: + case MIPS_INS_BLEZ: + case MIPS_INS_BLEZL: + case MIPS_INS_BGEZ: + case MIPS_INS_BGEZL: + case MIPS_INS_BGTZ: + case MIPS_INS_BGTZL: + case MIPS_INS_BLEZC: + case MIPS_INS_BGEZC: + case MIPS_INS_BLTZC: + case MIPS_INS_BGTZC: + if (insn->id == MIPS_INS_J || insn->id == MIPS_INS_B) { + op->type = RZ_ANALYSIS_OP_TYPE_JMP; + } else { + op->type = RZ_ANALYSIS_OP_TYPE_CJMP; + } + + if (OPERAND(0).type == MIPS_OP_IMM) { + op->jump = IMM(0); + } else if (OPERAND(1).type == MIPS_OP_IMM) { + op->jump = IMM(1); + } else if (OPERAND(2).type == MIPS_OP_IMM) { + op->jump = IMM(2); + } + + switch (insn->id) { + case MIPS_INS_BLEZC: + case MIPS_INS_BGEZC: + case MIPS_INS_BLTZC: + case MIPS_INS_BGTZC: + // compact versions (no delay) + op->delay = 0; + op->fail = addr + 4; + break; + default: + op->delay = 1; + op->fail = addr + 8; + break; + } + + break; + case MIPS_INS_JR: + case MIPS_INS_JRC: + op->type = RZ_ANALYSIS_OP_TYPE_RJMP; + op->delay = 1; + // register is $ra, so jmp is a return + if (insn->detail->mips.operands[0].reg == MIPS_REG_RA) { + op->type = RZ_ANALYSIS_OP_TYPE_RET; + t9_pre = UT64_MAX; + } +#if CS_NEXT_VERSION < 6 + if (REGID(0) == MIPS_REG_25) { +#else + if (REGID(0) == MIPS_REG_T9 || + REGID(0) == MIPS_REG_T9_64) { +#endif + op->jump = t9_pre; + t9_pre = UT64_MAX; + } + + break; + case MIPS_INS_SLT: + case MIPS_INS_SLTI: + op->sign = true; + SET_VAL(op, 2); + break; + case MIPS_INS_SLTIU: + SET_VAL(op, 2); + break; + case MIPS_INS_SRA: +#if CS_NEXT_VERSION < 6 + case MIPS_INS_SHRAV: + case MIPS_INS_SHRAV_R: + case MIPS_INS_SHRA: + case MIPS_INS_SHRA_R: +#else + case MIPS_INS_SHRA_PH: + case MIPS_INS_SHRA_QB: + case MIPS_INS_SHRA_R_PH: + case MIPS_INS_SHRA_R_QB: + case MIPS_INS_SHRA_R_W: + case MIPS_INS_SHRAV_PH: + case MIPS_INS_SHRAV_QB: + case MIPS_INS_SHRAV_R_PH: + case MIPS_INS_SHRAV_R_QB: + case MIPS_INS_SHRAV_R_W: + case MIPS_INS_SRA_B: + case MIPS_INS_SRA_D: + case MIPS_INS_SRA_H: + case MIPS_INS_SRA_W: + case MIPS_INS_SRAI_B: + case MIPS_INS_SRAI_D: + case MIPS_INS_SRAI_H: + case MIPS_INS_SRAI_W: + case MIPS_INS_SRAR_B: + case MIPS_INS_SRAR_D: + case MIPS_INS_SRAR_H: + case MIPS_INS_SRAR_W: + case MIPS_INS_SRARI_B: + case MIPS_INS_SRARI_D: + case MIPS_INS_SRARI_H: + case MIPS_INS_SRARI_W: + case MIPS_INS_SRAV: +#endif /* CS_NEXT_VERSION */ + op->type = RZ_ANALYSIS_OP_TYPE_SAR; + SET_VAL(op, 2); + break; +#if CS_NEXT_VERSION < 6 + case MIPS_INS_SHRL: +#else + case MIPS_INS_SHRL_PH: + case MIPS_INS_SHRL_QB: + case MIPS_INS_SHRLV_PH: + case MIPS_INS_SHRLV_QB: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_SRLV: + case MIPS_INS_SRL: + op->type = RZ_ANALYSIS_OP_TYPE_SHR; + SET_VAL(op, 2); + break; + case MIPS_INS_SLLV: + case MIPS_INS_SLL: + op->type = RZ_ANALYSIS_OP_TYPE_SHL; + SET_VAL(op, 2); + break; } beach: set_opdir(op); @@ -975,9 +1384,11 @@ static char *get_reg_profile(RzAnalysis *analysis) { static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) { switch (query) { case RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE: - /* fall-thru */ + // mips-16, micromips, nanomips uses 16-bits + return 2; case RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE: - /* fall-thru */ + // nanomips uses 48-bits + return 6; case RZ_ANALYSIS_ARCHINFO_TEXT_ALIGN: /* fall-thru */ case RZ_ANALYSIS_ARCHINFO_DATA_ALIGN: diff --git a/librz/arch/p/arch_mips.c b/librz/arch/p/arch_mips.c index aace852c432..7e5be6c1122 100644 --- a/librz/arch/p/arch_mips.c +++ b/librz/arch/p/arch_mips.c @@ -3,6 +3,151 @@ // SPDX-License-Identifier: LGPL-3.0-only #include +#include + +#define EXTRA_CPUS "r2300,r2600,r2800,r2000a,r2000,r3000a,r3000,r10000" + +#if CS_NEXT_VERSION < 6 +#define CAPSTONE_CPUS "micromips,mips1,mips2,mips3,mips4,mips16,mips32,mips32r6,mips64" +#define CAPSTONE_FEATURES "" +#else +#define CAPSTONE_CPUS "micromips,mips1,mips2,mips32r2,mips32r3,mips32r5,mips32r6,mips3,mips4,mips5,mips64r2,mips64r3,mips64r5,mips64r6,octeon,octeonp,nanomips,nms1,i7200,micro32r3,micro32r6" +#define CAPSTONE_FEATURES "noptr64,nofloat" +#endif + +#define MIPS_CPUS CAPSTONE_CPUS "," EXTRA_CPUS +#define MIPS_FEATURES CAPSTONE_FEATURES + +static bool cs_mode_from_cpu(const char *cpu, const char *features, int bits, bool big_endian, cs_mode *mode) { + cs_mode _mode = (big_endian) ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN; +#if CS_NEXT_VERSION < 6 + (void)features; +#define return_on_cpu(cpu_name, mode_flag) \ + do { \ + if (!strcmp(cpu, cpu_name)) { \ + *mode = _mode | mode_flag; \ + return true; \ + } \ + } while (0) + + switch (bits) { + case 64: + _mode |= CS_MODE_MIPS64; + break; + case 32: + _mode |= CS_MODE_MIPS32; + break; + default: + return false; + } + + if (RZ_STR_ISEMPTY(cpu)) { + *mode = _mode; + return true; + } + + return_on_cpu("micromips", CS_MODE_MICRO); + return_on_cpu("mips1", CS_MODE_MIPS2); // mips1 is subset of mips2 + return_on_cpu("mips2", CS_MODE_MIPS2); + return_on_cpu("mips3", CS_MODE_MIPS3); + return_on_cpu("mips4", CS_MODE_MIPS32); // old capstone uses the same + return_on_cpu("mips16", CS_MODE_MIPS32); // old capstone uses the same + return_on_cpu("mips32", CS_MODE_MIPS32); + return_on_cpu("mips32r6", CS_MODE_MIPS32R6); + return_on_cpu("mips64", CS_MODE_MIPS64); + + // extra cpus + return_on_cpu("r2300", CS_MODE_MIPS2); + return_on_cpu("r2600", CS_MODE_MIPS2); + return_on_cpu("r2800", CS_MODE_MIPS2); + return_on_cpu("r2000a", CS_MODE_MIPS2); + return_on_cpu("r2000", CS_MODE_MIPS2); + return_on_cpu("r3000a", CS_MODE_MIPS2); // ISA mips2 + return_on_cpu("r3000", CS_MODE_MIPS2); // ISA mips2 + return_on_cpu("r10000", CS_MODE_MIPS32); // old capstone uses the same + + return false; +#else +#define return_on_cpu(cpu_name, mode_flag) \ + do { \ + if (cpu_len == strlen(cpu_name) && \ + !strncmp(cpu, cpu_name, cpu_len)) { \ + *mode = _mode | mode_flag; \ + return true; \ + } \ + } while (0) + + bool is_noptr64 = RZ_STR_ISNOTEMPTY(features) && strstr(features, "noptr64"); + if (!is_noptr64 && bits > 16) { + _mode |= CS_MODE_MIPS_PTR64; + } + + bool is_nofloat = RZ_STR_ISNOTEMPTY(features) && strstr(features, "nofloat"); + if (is_nofloat) { + _mode |= CS_MODE_MIPS_NOFLOAT; + } + if (RZ_STR_ISEMPTY(cpu) || cpu[0] == '+') { + switch (bits) { + case 64: // generic mips64 + *mode = _mode | CS_MODE_MIPS64; + return true; + case 32: // generic mips32 + *mode = _mode | CS_MODE_MIPS32; + return true; + case 16: // generic mips16 + *mode = _mode | CS_MODE_MIPS16; + return true; + default: + return false; + } + return true; + } + + size_t cpu_len = strlen(cpu); + const char *plus = NULL; + if ((plus = strchr(cpu, '+'))) { + cpu_len = plus - cpu; + } + + return_on_cpu("micromips", CS_MODE_MICRO); + return_on_cpu("mips1", CS_MODE_MIPS1); + return_on_cpu("mips2", CS_MODE_MIPS2); + return_on_cpu("mips16", CS_MODE_MIPS16); + return_on_cpu("mips32", CS_MODE_MIPS32); + return_on_cpu("mips32r2", CS_MODE_MIPS32R2); + return_on_cpu("mips32r3", CS_MODE_MIPS32R3); + return_on_cpu("mips32r5", CS_MODE_MIPS32R5); + return_on_cpu("mips32r6", CS_MODE_MIPS32R6); + return_on_cpu("mips3", CS_MODE_MIPS3); + return_on_cpu("mips4", CS_MODE_MIPS4); + return_on_cpu("mips5", CS_MODE_MIPS5); + return_on_cpu("mips64", CS_MODE_MIPS64); + return_on_cpu("mips64r2", CS_MODE_MIPS64R2); + return_on_cpu("mips64r3", CS_MODE_MIPS64R3); + return_on_cpu("mips64r5", CS_MODE_MIPS64R5); + return_on_cpu("mips64r6", CS_MODE_MIPS64R6); + return_on_cpu("octeon", CS_MODE_OCTEON); + return_on_cpu("octeonp", CS_MODE_OCTEONP); + return_on_cpu("nanomips", CS_MODE_NANOMIPS); + return_on_cpu("nms1", CS_MODE_NMS1); + return_on_cpu("i7200", CS_MODE_I7200); + return_on_cpu("micro32r3", CS_MODE_MICRO32R3); + return_on_cpu("micro32r6", CS_MODE_MICRO32R6); + + // extra cpus + return_on_cpu("r2300", CS_MODE_MIPS2); + return_on_cpu("r2600", CS_MODE_MIPS2); + return_on_cpu("r2800", CS_MODE_MIPS2); + return_on_cpu("r2000a", CS_MODE_MIPS2); + return_on_cpu("r2000", CS_MODE_MIPS2); + return_on_cpu("r3000a", CS_MODE_MIPS2); // ISA mips2 + return_on_cpu("r3000", CS_MODE_MIPS2); // ISA mips2 + return_on_cpu("r10000", CS_MODE_MIPS4); + +#endif /* CS_NEXT_VERSION */ + return false; +} +#undef return_on_cpu #include "analysis/analysis_mips.c" #include "asm/asm_mips.c" diff --git a/librz/arch/p/asm/asm_mips.c b/librz/arch/p/asm/asm_mips.c index 6cc47f26d0b..aa5996b6567 100644 --- a/librz/arch/p/asm/asm_mips.c +++ b/librz/arch/p/asm/asm_mips.c @@ -4,7 +4,9 @@ #include #include #include +#include "capstone.h" #include "cs_helper.h" +#include "rz_util/rz_log.h" CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(mips_asm); @@ -12,23 +14,17 @@ static int mips_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { CapstoneContext *ctx = (CapstoneContext *)a->plugin_data; cs_insn *insn; - int mode, n, ret = -1; - mode = (a->big_endian) ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN; + cs_mode mode = 0; + int n, ret = -1; if (!op) { return 0; } - if (a->cpu && *a->cpu) { - if (!strcmp(a->cpu, "micro")) { - mode |= CS_MODE_MICRO; - } else if (!strcmp(a->cpu, "r6")) { - mode |= CS_MODE_MIPS32R6; - } else if (!strcmp(a->cpu, "v3")) { - mode |= CS_MODE_MIPS3; - } else if (!strcmp(a->cpu, "v2")) { - mode |= CS_MODE_MIPS2; - } + + if (!cs_mode_from_cpu(a->cpu, a->features, a->bits, a->big_endian, &mode)) { + rz_asm_op_set_asm(op, "invalid"); + return -1; } - mode |= (a->bits == 64) ? CS_MODE_MIPS64 : CS_MODE_MIPS32; + memset(op, 0, sizeof(RzAsmOp)); op->size = 4; if (ctx->omode != mode) { @@ -39,10 +35,14 @@ static int mips_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { if (!ctx->handle) { ret = cs_open(CS_ARCH_MIPS, mode, &ctx->handle); if (ret) { + RZ_LOG_ERROR("failed to open capstone\n"); goto fin; } ctx->omode = mode; cs_option(ctx->handle, CS_OPT_DETAIL, CS_OPT_OFF); +#if CS_NEXT_VERSION > 5 + cs_option(ctx->handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NO_DOLLAR); +#endif } if (a->syntax == RZ_ASM_SYNTAX_REGNUM) { cs_option(ctx->handle, CS_OPT_SYNTAX, CS_OPT_SYNTAX_NOREGNAME); @@ -52,7 +52,7 @@ static int mips_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { n = cs_disasm(ctx->handle, (ut8 *)buf, len, a->pc, 1, &insn); if (n < 1) { rz_asm_op_set_asm(op, "invalid"); - op->size = 4; + op->size = mode & (CS_MODE_MICRO | CS_MODE_NANOMIPS | CS_MODE_MIPS16) ? 2 : 4; goto fin; } if (insn->size < 1) { @@ -60,11 +60,15 @@ static int mips_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { } op->size = insn->size; rz_asm_op_setf_asm(op, "%s%s%s", insn->mnemonic, insn->op_str[0] ? " " : "", insn->op_str); + +#if CS_NEXT_VERSION < 6 + // CS_OPT_SYNTAX_NO_DOLLAR is not available before capstone 6 char *str = rz_asm_op_get_asm(op); if (str) { // remove the '$' in the string rz_str_replace_char(str, '$', 0); } +#endif cs_free(insn, n); fin: return op->size; @@ -90,7 +94,8 @@ RzAsmPlugin rz_asm_plugin_mips = { .desc = "Capstone MIPS disassembler", .license = "BSD", .arch = "mips", - .cpus = "mips32/64,micro,r6,v3,v2", + .cpus = MIPS_CPUS, + .features = MIPS_FEATURES, .bits = 16 | 32 | 64, .endian = RZ_SYS_ENDIAN_LITTLE | RZ_SYS_ENDIAN_BIG, .init = mips_asm_init, diff --git a/librz/bin/format/te/te.c b/librz/bin/format/te/te.c index 9ff212b8edc..baaa1982504 100644 --- a/librz/bin/format/te/te.c +++ b/librz/bin/format/te/te.c @@ -214,8 +214,31 @@ ut64 rz_bin_te_get_image_base(struct rz_bin_te_obj_t *bin) { return 0LL; } +char *rz_bin_te_get_cpu(struct rz_bin_te_obj_t *bin) { + if (!bin) { + return NULL; + } + switch (bin->header->Machine) { + case TE_IMAGE_FILE_MACHINE_MIPS16: + return rz_str_dup("mips16"); + case TE_IMAGE_FILE_MACHINE_MIPSFPU: + return rz_str_dup("mips32"); + case TE_IMAGE_FILE_MACHINE_MIPSFPU16: + return rz_str_dup("mips16"); + case TE_IMAGE_FILE_MACHINE_R10000: + return rz_str_dup("r10000"); + case TE_IMAGE_FILE_MACHINE_R3000: + return rz_str_dup("r3000"); + case TE_IMAGE_FILE_MACHINE_R4000: + return rz_str_dup("r4000"); + case TE_IMAGE_FILE_MACHINE_WCEMIPSV2: + return rz_str_dup("mips2"); + default: + return NULL; + } +} + char *rz_bin_te_get_machine(struct rz_bin_te_obj_t *bin) { - char *machine; if (!bin) { return NULL; } @@ -279,7 +302,6 @@ char *rz_bin_te_get_machine(struct rz_bin_te_obj_t *bin) { default: return rz_str_dup("unknown"); } - return machine; } char *rz_bin_te_get_os(struct rz_bin_te_obj_t *bin) { diff --git a/librz/bin/format/te/te.h b/librz/bin/format/te/te.h index a146755adcd..1fb3501b34c 100644 --- a/librz/bin/format/te/te.h +++ b/librz/bin/format/te/te.h @@ -50,6 +50,7 @@ ut64 rz_bin_te_get_main_paddr(struct rz_bin_te_obj_t *bin); ut64 rz_bin_te_get_image_base(struct rz_bin_te_obj_t *bin); int rz_bin_te_get_image_size(struct rz_bin_te_obj_t *bin); char *rz_bin_te_get_machine(struct rz_bin_te_obj_t *bin); +char *rz_bin_te_get_cpu(struct rz_bin_te_obj_t *bin); int rz_bin_te_get_bits(struct rz_bin_te_obj_t *bin); char *rz_bin_te_get_os(struct rz_bin_te_obj_t *bin); struct rz_bin_te_section_t *rz_bin_te_get_sections(struct rz_bin_te_obj_t *bin); diff --git a/librz/bin/p/bin_coff.c b/librz/bin/p/bin_coff.c index 8099e067835..1dcabdbb546 100644 --- a/librz/bin/p/bin_coff.c +++ b/librz/bin/p/bin_coff.c @@ -416,11 +416,20 @@ static RzBinInfo *info(RzBinFile *bf) { switch (obj->hdr.f_magic) { case COFF_FILE_MACHINE_R4000: + ret->cpu = rz_str_dup("mips4"); + /* fall-thru */ case COFF_FILE_MACHINE_MIPS16: + if (!ret->cpu) { + ret->cpu = rz_str_dup("mips16"); + } + /* fall-thru */ case COFF_FILE_MACHINE_MIPSFPU: case COFF_FILE_MACHINE_MIPSFPU16: ret->machine = rz_str_dup("mips"); ret->arch = rz_str_dup("mips"); + if (!ret->cpu) { + ret->cpu = rz_str_dup("mips32"); + } ret->bits = 32; break; case COFF_FILE_MACHINE_I386: diff --git a/librz/bin/p/bin_mach0.c b/librz/bin/p/bin_mach0.c index 0ff3b3ee246..841a5e429d4 100644 --- a/librz/bin/p/bin_mach0.c +++ b/librz/bin/p/bin_mach0.c @@ -470,7 +470,8 @@ static RzBinInfo *info(RzBinFile *bf) { ret->rclass = rz_str_dup("mach0"); ret->os = rz_str_dup("darwin"); ret->subsystem = rz_str_dup(MACH0_(get_platform)(bf->o->bin_obj)); - ret->arch = rz_str_dup(MACH0_(get_cputype)(bf->o->bin_obj)); + ret->arch = strdup(MACH0_(get_cputype)(bf->o->bin_obj)); + ret->cpu = MACH0_(get_cpusubtype)(bf->o->bin_obj); ret->machine = MACH0_(get_cpusubtype)(bf->o->bin_obj); ret->type = MACH0_(get_filetype)(bf->o->bin_obj); ret->big_endian = MACH0_(is_big_endian)(bf->o->bin_obj); diff --git a/librz/bin/p/bin_psxexe.c b/librz/bin/p/bin_psxexe.c index 92116989a6a..fd9cd2f7762 100644 --- a/librz/bin/p/bin_psxexe.c +++ b/librz/bin/p/bin_psxexe.c @@ -39,6 +39,7 @@ static RzBinInfo *info(RzBinFile *bf) { ret->machine = rz_str_dup("Sony PlayStation 1"); ret->os = rz_str_dup("psx"); ret->arch = rz_str_dup("mips"); + ret->cpu = strdup("mips3"); ret->bits = 32; ret->has_va = true; return ret; diff --git a/librz/bin/p/bin_te.c b/librz/bin/p/bin_te.c index cd69afcdd4a..78800d18004 100644 --- a/librz/bin/p/bin_te.c +++ b/librz/bin/p/bin_te.c @@ -128,6 +128,7 @@ static RzBinInfo *info(RzBinFile *bf) { ret->os = rz_bin_te_get_os(bf->o->bin_obj); ret->arch = rz_bin_te_get_arch(bf->o->bin_obj); ret->machine = rz_bin_te_get_machine(bf->o->bin_obj); + ret->cpu = rz_bin_te_get_cpu(bf->o->bin_obj); ret->subsystem = rz_bin_te_get_subsystem(bf->o->bin_obj); ret->type = rz_str_dup("EXEC (Executable file)"); ret->bits = rz_bin_te_get_bits(bf->o->bin_obj); diff --git a/librz/core/cbin.c b/librz/core/cbin.c index 7679ede502c..8cfff4d642f 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -13,6 +13,7 @@ #include "../bin/dwarf/dwarf_private.h" #include "core_private.h" +#include "rz_util/rz_str.h" #define is_invalid_address_va(va, vaddr, paddr) (((va) && (vaddr) == UT64_MAX) || (!(va) && (paddr) == UT64_MAX)) #define is_invalid_address_va2(va, vaddr, paddr) (((va) != VA_FALSE && (vaddr) == UT64_MAX) || ((va) == VA_FALSE && (paddr) == UT64_MAX)) @@ -24,14 +25,14 @@ #define LOAD_BSS_MALLOC 0 -#define IS_MODE_SET(mode) ((mode)&RZ_MODE_SET) -#define IS_MODE_SIMPLE(mode) ((mode)&RZ_MODE_SIMPLE) -#define IS_MODE_SIMPLEST(mode) ((mode)&RZ_MODE_SIMPLEST) -#define IS_MODE_JSON(mode) ((mode)&RZ_MODE_JSON) -#define IS_MODE_RZCMD(mode) ((mode)&RZ_MODE_RIZINCMD) -#define IS_MODE_EQUAL(mode) ((mode)&RZ_MODE_EQUAL) +#define IS_MODE_SET(mode) ((mode) & RZ_MODE_SET) +#define IS_MODE_SIMPLE(mode) ((mode) & RZ_MODE_SIMPLE) +#define IS_MODE_SIMPLEST(mode) ((mode) & RZ_MODE_SIMPLEST) +#define IS_MODE_JSON(mode) ((mode) & RZ_MODE_JSON) +#define IS_MODE_RZCMD(mode) ((mode) & RZ_MODE_RIZINCMD) +#define IS_MODE_EQUAL(mode) ((mode) & RZ_MODE_EQUAL) #define IS_MODE_NORMAL(mode) (!(mode)) -#define IS_MODE_CLASSDUMP(mode) ((mode)&RZ_MODE_CLASSDUMP) +#define IS_MODE_CLASSDUMP(mode) ((mode) & RZ_MODE_CLASSDUMP) // dup from cmd_info #define PAIR_WIDTH "9" @@ -584,10 +585,10 @@ RZ_API bool rz_core_bin_apply_config(RzCore *r, RzBinFile *binfile) { rz_config_set(r->config, "analysis.cpp.abi", "itanium"); } rz_config_set(r->config, "asm.arch", info->arch); - if (info->cpu && *info->cpu) { + if (RZ_STR_ISNOTEMPTY(info->cpu)) { rz_config_set(r->config, "asm.cpu", info->cpu); } - if (info->features && *info->features) { + if (RZ_STR_ISNOTEMPTY(info->features)) { rz_config_set(r->config, "asm.features", info->features); } rz_config_set(r->config, "analysis.arch", info->arch); @@ -5241,8 +5242,8 @@ static void print_arch(RzBin *bin, RzCmdStateOutput *state, struct arch_ctx *ctx pj_ki(state->d.pj, "bits", ctx->bits); pj_kn(state->d.pj, "offset", ctx->offset); pj_kn(state->d.pj, "size", ctx->size); - if (info && !strcmp(ctx->arch, "mips")) { - pj_ks(state->d.pj, "isa", info->cpu); + if (info) { + pj_ks(state->d.pj, "cpu", info->cpu); pj_ks(state->d.pj, "features", info->features); } if (ctx->machine) { diff --git a/librz/core/cconfig.c b/librz/core/cconfig.c index 916670c2289..2454595d21d 100644 --- a/librz/core/cconfig.c +++ b/librz/core/cconfig.c @@ -475,6 +475,27 @@ static bool cb_asm_varfold(void *core, void *node) { return false; } +static void handle_cpu_feature(RzConfig *config, const char *supported, const char *cpu) { + // strdup is required when calling rz_config_set, because it will free the old value + char *cpu_copy = rz_str_dup(cpu); + + // we need to duplicate supported because rz_str_split_list will modify the string. + char *supported_copy = rz_str_dup(supported); + RzList *cpu_list = rz_str_split_list(supported_copy, ",", 0); + RzListIter *it; + const char *lcpu; + rz_list_foreach (cpu_list, it, lcpu) { + if (!strcmp(lcpu, cpu_copy)) { + rz_config_set(config, "asm.cpu", cpu_copy); + break; + } + } + + rz_list_free(cpu_list); + free(supported_copy); + free(cpu_copy); +} + static bool cb_asmarch(void *user, void *data) { char asmparser[32]; RzCore *core = (RzCore *)user; @@ -509,25 +530,14 @@ static bool cb_asmarch(void *user, void *data) { RZ_LOG_ERROR("core: asm.arch: cannot find (%s)\n", node->value); return false; } - // we should rz_str_dup here otherwise will crash if any rz_config_set - // free the old value char *asm_cpu = rz_str_dup(rz_config_get(core->config, "asm.cpu")); if (core->rasm->cur) { - const char *newAsmCPU = core->rasm->cur->cpus; - if (newAsmCPU) { - if (*newAsmCPU) { - char *nac = rz_str_dup(newAsmCPU); - char *comma = strchr(nac, ','); - if (comma) { - if (!*asm_cpu || (*asm_cpu && !strstr(nac, asm_cpu))) { - *comma = 0; - rz_config_set(core->config, "asm.cpu", nac); - } - } - free(nac); - } else { - rz_config_set(core->config, "asm.cpu", ""); - } + const char *cpus_supported = core->rasm->cur->cpus; + if (RZ_STR_ISNOTEMPTY(cpus_supported) && + RZ_STR_ISNOTEMPTY(asm_cpu)) { + handle_cpu_feature(core->config, cpus_supported, asm_cpu); + } else { + rz_config_set(core->config, "asm.cpu", ""); } bits = core->rasm->cur->bits; if (8 & bits) { @@ -724,8 +734,10 @@ static bool cb_asmfeatures(void *user, void *data) { return 0; } RZ_FREE(core->rasm->features); + RZ_FREE(core->analysis->features); if (node->value[0]) { core->rasm->features = rz_str_dup(node->value); + core->analysis->features = rz_str_dup(node->value); } return 1; } diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index c720cc9b641..9c7023e3132 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -463,6 +463,7 @@ typedef struct { typedef struct rz_analysis_t { char *cpu; // analysis.cpu + char *features; // analysis.features char *os; // asm.os int bits; // asm.bits int lineswidth; // asm.lines.width From 05f88403f83cb854c4b7bf8799bc3510528a9cb5 Mon Sep 17 00:00:00 2001 From: wargio Date: Sun, 8 Sep 2024 13:44:35 +0800 Subject: [PATCH 04/13] Split esil from analysis_mips.c --- librz/arch/isa/mips/mips_assembler.h | 11 - librz/arch/isa/mips/mips_esil.c | 557 +++++++++++++++++++++++++ librz/arch/isa/mips/mips_internal.h | 14 + librz/arch/meson.build | 1 + librz/arch/p/analysis/analysis_mips.c | 578 +------------------------- librz/arch/p/asm/asm_mips.c | 2 +- 6 files changed, 574 insertions(+), 589 deletions(-) delete mode 100644 librz/arch/isa/mips/mips_assembler.h create mode 100644 librz/arch/isa/mips/mips_esil.c create mode 100644 librz/arch/isa/mips/mips_internal.h diff --git a/librz/arch/isa/mips/mips_assembler.h b/librz/arch/isa/mips/mips_assembler.h deleted file mode 100644 index 1436983c32d..00000000000 --- a/librz/arch/isa/mips/mips_assembler.h +++ /dev/null @@ -1,11 +0,0 @@ -// SPDX-FileCopyrightText: 2012-2018 pancake -// SPDX-License-Identifier: LGPL-3.0-only - -#ifndef ASSEMBLE_MIPS_H -#define ASSEMBLE_MIPS_H - -#include - -RZ_IPI int mips_assemble_opcode(const char *str, ut64 pc, ut8 *out); - -#endif /* ASSEMBLE_MIPS_H */ diff --git a/librz/arch/isa/mips/mips_esil.c b/librz/arch/isa/mips/mips_esil.c new file mode 100644 index 00000000000..caff85044d4 --- /dev/null +++ b/librz/arch/isa/mips/mips_esil.c @@ -0,0 +1,557 @@ +// SPDX-FileCopyrightText: 2013-2019 pancake +// SPDX-License-Identifier: LGPL-3.0-only + +#include "mips_internal.h" +#include +#include + +#define OPCOUNT() insn->detail->mips.op_count +#define REG(x) cs_reg_name(*handle, insn->detail->mips.operands[x].reg) +#define IMM(x) insn->detail->mips.operands[x].imm + +// ESIL macros: +// put the sign bit on the stack +#define ES_IS_NEGATIVE(arg) "1," arg ",<<<,1,&" + +// call with delay slot +#define ES_CALL_DR(ra, addr) "pc,4,+," ra ",=," ES_J(addr) +#define ES_CALL_D(addr) ES_CALL_DR("ra", addr) + +// call without delay slot +#define ES_CALL_NDR(ra, addr) "pc," ra ",=," ES_J(addr) +#define ES_CALL_ND(addr) ES_CALL_NDR("ra", addr) + +#define USE_DS 0 +#if USE_DS +// emit ERR trap if executed in a delay slot +#define ES_TRAP_DS() "$ds,!,!,?{,$$,1,TRAP,BREAK,}," +// jump to address +#define ES_J(addr) addr ",SETJT,1,SETD" +#else +#define ES_TRAP_DS() "" +#define ES_J(addr) addr ",pc,=" +#endif + +#define ES_B(x) "0xff," x ",&" +#define ES_H(x) "0xffff," x ",&" +#define ES_W(x) "0xffffffff," x ",&" + +// sign extend 32 -> 64 +#define ES_SIGN32_64(arg) es_sign_n_64(a, op, arg, 32) +#define ES_SIGN16_64(arg) es_sign_n_64(a, op, arg, 16) + +#define ES_ADD_CK32_OVERF(x, y, z) es_add_ck(op, x, y, z, 32) +#define ES_ADD_CK64_OVERF(x, y, z) es_add_ck(op, x, y, z, 64) + +static inline void es_sign_n_64(RzAnalysis *a, RzAnalysisOp *op, const char *arg, int bit) { + if (a->bits == 64) { + rz_strbuf_appendf(&op->esil, ",%d,%s,~,%s,=,", bit, arg, arg); + } else { + rz_strbuf_append(&op->esil, ","); + } +} + +static inline void es_add_ck(RzAnalysisOp *op, const char *a1, const char *a2, const char *re, int bit) { + ut64 mask = 1ULL << (bit - 1); + rz_strbuf_appendf(&op->esil, + "%d,0x%" PFMT64x ",%s,%s,^,&,>>,%d,0x%" PFMT64x ",%s,%s,+,&,>>,|,1,==,$z,?{,$$,1,TRAP,}{,%s,%s,+,%s,=,}", + bit - 2, mask, a1, a2, bit - 1, mask, a1, a2, a1, a2, re); +} + +#define PROTECT_ZERO() \ + if (REG(0)[0] == 'z') { \ + rz_strbuf_appendf(&op->esil, ","); \ + } else + +#define ESIL_LOAD(size) \ + PROTECT_ZERO() { \ + rz_strbuf_appendf(&op->esil, "%s,[" size "],%s,=", \ + ARG(1), REG(0)); \ + } + +static const char *arg(csh *handle, cs_insn *insn, char *buf, int n) { + *buf = 0; + switch (insn->detail->mips.operands[n].type) { + case MIPS_OP_INVALID: + break; + case MIPS_OP_REG: + sprintf(buf, "%s", + cs_reg_name(*handle, + insn->detail->mips.operands[n].reg)); + break; + case MIPS_OP_IMM: { + st64 x = (st64)insn->detail->mips.operands[n].imm; + sprintf(buf, "%" PFMT64d, x); + } break; + case MIPS_OP_MEM: { + int disp = insn->detail->mips.operands[n].mem.disp; + if (disp < 0) { + sprintf(buf, "%" PFMT64d ",%s,-", + (ut64)-insn->detail->mips.operands[n].mem.disp, + cs_reg_name(*handle, + insn->detail->mips.operands[n].mem.base)); + } else { + sprintf(buf, "0x%" PFMT64x ",%s,+", + (ut64)insn->detail->mips.operands[n].mem.disp, + cs_reg_name(*handle, + insn->detail->mips.operands[n].mem.base)); + } + } break; + } + return buf; +} + +#define ARG(x) (*str[x] != 0) ? str[x] : arg(handle, insn, str[x], x) + +RZ_IPI int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) { + char str[8][32] = { { 0 } }; + + rz_strbuf_init(&op->esil); + rz_strbuf_set(&op->esil, ""); + + if (!insn) { + return 0; + } + + // caching operands + for (int i = 0; i < insn->detail->mips.op_count && i < 8; i++) { + *str[i] = 0; + ARG(i); + } + { + switch (insn->id) { + case MIPS_INS_NOP: + rz_strbuf_setf(&op->esil, ","); + break; + case MIPS_INS_BREAK: + rz_strbuf_setf(&op->esil, "%" PFMT64d ",%" PFMT64d ",TRAP", (st64)IMM(0), (st64)IMM(0)); + break; + case MIPS_INS_SD: + rz_strbuf_appendf(&op->esil, "%s,%s,=[8]", + ARG(0), ARG(1)); + break; + case MIPS_INS_SW: + case MIPS_INS_SWL: + case MIPS_INS_SWR: + rz_strbuf_appendf(&op->esil, "%s,%s,=[4]", + ARG(0), ARG(1)); + break; + case MIPS_INS_SH: + rz_strbuf_appendf(&op->esil, "%s,%s,=[2]", + ARG(0), ARG(1)); + break; + case MIPS_INS_SWC1: + case MIPS_INS_SWC2: + rz_strbuf_setf(&op->esil, "%s,$", ARG(1)); + break; + case MIPS_INS_SB: + rz_strbuf_appendf(&op->esil, "%s,%s,=[1]", + ARG(0), ARG(1)); + break; +#if CS_NEXT_VERSION >= 6 + case MIPS_INS_CMPU_LE_QB: + case MIPS_INS_CMPGU_LE_QB: + case MIPS_INS_CMPGDU_LE_QB: + rz_strbuf_appendf(&op->esil, "%s,%s,<=", ARG(1), ARG(0)); + break; + case MIPS_INS_CMPU_LT_QB: + case MIPS_INS_CMPGU_LT_QB: + case MIPS_INS_CMPGDU_LT_QB: + rz_strbuf_appendf(&op->esil, "%s,%s,<", ARG(1), ARG(0)); + break; +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_CMP: +#if CS_NEXT_VERSION < 6 + case MIPS_INS_CMPU: + case MIPS_INS_CMPGU: + case MIPS_INS_CMPGDU: +#else + case MIPS_INS_CMPU_EQ_QB: + case MIPS_INS_CMPGU_EQ_QB: + case MIPS_INS_CMPGDU_EQ_QB: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_CMPI: + rz_strbuf_appendf(&op->esil, "%s,%s,==", ARG(1), ARG(0)); + break; + case MIPS_INS_DSRA: + rz_strbuf_appendf(&op->esil, + "%s,%s,>>,31,%s,>>,?{,32,%s,32,-,0xffffffff,<<,0xffffffff,&,<<,}{,0,},|,%s,=", + ARG(2), ARG(1), ARG(1), ARG(2), ARG(0)); + break; +#if CS_NEXT_VERSION < 6 + case MIPS_INS_SHRAV: + case MIPS_INS_SHRAV_R: + case MIPS_INS_SHRA: + case MIPS_INS_SHRA_R: +#else + case MIPS_INS_SHRA_PH: + case MIPS_INS_SHRA_QB: + case MIPS_INS_SHRA_R_PH: + case MIPS_INS_SHRA_R_QB: + case MIPS_INS_SHRA_R_W: + case MIPS_INS_SHRAV_PH: + case MIPS_INS_SHRAV_QB: + case MIPS_INS_SHRAV_R_PH: + case MIPS_INS_SHRAV_R_QB: + case MIPS_INS_SHRAV_R_W: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_SRA: + rz_strbuf_appendf(&op->esil, + "0xffffffff,%s,%s,>>,&,31,%s,>>,?{,%s,32,-,0xffffffff,<<,0xffffffff,&,}{,0,},|,%s,=", + ARG(2), ARG(1), ARG(1), ARG(2), ARG(0)); + break; +#if CS_NEXT_VERSION < 6 + case MIPS_INS_SHRL: +#else + case MIPS_INS_SHRL_PH: + case MIPS_INS_SHRL_QB: + case MIPS_INS_SHRLV_PH: + case MIPS_INS_SHRLV_QB: +#endif /* CS_NEXT_VERSION */ + // suffix 'S' forces conditional flag to be updated + case MIPS_INS_SRLV: + case MIPS_INS_SRL: + rz_strbuf_appendf(&op->esil, "%s,%s,>>,%s,=", ARG(2), ARG(1), ARG(0)); + break; + case MIPS_INS_SLLV: + case MIPS_INS_SLL: + rz_strbuf_appendf(&op->esil, "%s,%s,<<,%s,=", ARG(2), ARG(1), ARG(0)); + break; + case MIPS_INS_BAL: + case MIPS_INS_JAL: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_D("%s"), ARG(0)); + break; + case MIPS_INS_JALR: + case MIPS_INS_JALRS: + if (OPCOUNT() < 2) { + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_D("%s"), ARG(0)); + } else { + PROTECT_ZERO() { + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_DR("%s", "%s"), ARG(0), ARG(1)); + } + } + break; + case MIPS_INS_JALRC: // no delay + if (OPCOUNT() < 2) { + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_ND("%s"), ARG(0)); + } else { + PROTECT_ZERO() { + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_NDR("%s", "%s"), ARG(0), ARG(1)); + } + } + break; + case MIPS_INS_JRADDIUSP: + // increment stackpointer in X and jump to %ra + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,sp,+=," ES_J("ra"), ARG(0)); + break; + case MIPS_INS_JR: + case MIPS_INS_JRC: + case MIPS_INS_J: + case MIPS_INS_B: // ??? + // jump to address with conditional + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_J("%s"), ARG(0)); + break; + case MIPS_INS_BNE: // bne $s, $t, offset + case MIPS_INS_BNEL: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,%s,==,$z,!,?{," ES_J("%s") ",}", + ARG(0), ARG(1), ARG(2)); + break; + case MIPS_INS_BEQ: + case MIPS_INS_BEQL: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,%s,==,$z,?{," ES_J("%s") ",}", + ARG(0), ARG(1), ARG(2)); + break; +#if CS_NEXT_VERSION < 6 + case MIPS_INS_BZ: +#else + case MIPS_INS_BZ_B: + case MIPS_INS_BZ_D: + case MIPS_INS_BZ_H: + case MIPS_INS_BZ_V: + case MIPS_INS_BZ_W: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_BEQZ: + case MIPS_INS_BEQZC: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,0,==,$z,?{," ES_J("%s") ",}", + ARG(0), ARG(1)); + break; + case MIPS_INS_BNEZ: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,0,==,$z,!,?{," ES_J("%s") ",}", + ARG(0), ARG(1)); + break; + case MIPS_INS_BEQZALC: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,0,==,$z,?{," ES_CALL_ND("%s") ",}", + ARG(0), ARG(1)); + break; + case MIPS_INS_BLEZ: + case MIPS_INS_BLEZC: + case MIPS_INS_BLEZL: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,%s,==,$z,?{," ES_J("%s") ",BREAK,},", + ARG(0), ARG(1)); + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", + ARG(0), ARG(1)); + break; + case MIPS_INS_BGEZ: + case MIPS_INS_BGEZC: + case MIPS_INS_BGEZL: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", + ARG(0), ARG(1)); + break; + case MIPS_INS_BGEZAL: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_D("%s") ",}", + ARG(0), ARG(1)); + break; + case MIPS_INS_BGEZALC: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_ND("%s") ",}", + ARG(0), ARG(1)); + break; + case MIPS_INS_BGTZALC: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,%s,==,$z,?{,BREAK,},", ARG(0)); + rz_strbuf_appendf(&op->esil, "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_ND("%s") ",}", + ARG(0), ARG(1)); + break; + case MIPS_INS_BLTZAL: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_D("%s") ",}", ARG(0), ARG(1)); + break; + case MIPS_INS_BLTZ: + case MIPS_INS_BLTZC: + case MIPS_INS_BLTZL: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", + ARG(0), ARG(1)); + break; + case MIPS_INS_BGTZ: + case MIPS_INS_BGTZC: + case MIPS_INS_BGTZL: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,%s,==,$z,?{,BREAK,},", ARG(0)); + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", + ARG(0), ARG(1)); + break; + case MIPS_INS_BTEQZ: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,t,==,$z,?{," ES_J("%s") ",}", ARG(0)); + break; + case MIPS_INS_BTNEZ: + rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,t,==,$z,!,?{," ES_J("%s") ",}", ARG(0)); + break; +#if CS_NEXT_VERSION < 6 + case MIPS_INS_MOV: +#else + case MIPS_INS_MOV_D: + case MIPS_INS_MOV_S: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_MOVE: + PROTECT_ZERO() { + rz_strbuf_appendf(&op->esil, "%s,%s,=", ARG(1), REG(0)); + } + break; + case MIPS_INS_MOVZ: + case MIPS_INS_MOVF: + PROTECT_ZERO() { + rz_strbuf_appendf(&op->esil, "0,%s,==,$z,?{,%s,%s,=,}", + ARG(2), ARG(1), REG(0)); + } + break; + case MIPS_INS_MOVT: + PROTECT_ZERO() { + rz_strbuf_appendf(&op->esil, "1,%s,==,$z,?{,%s,%s,=,}", + ARG(2), ARG(1), REG(0)); + } + break; +#if CS_NEXT_VERSION < 6 + case MIPS_INS_FSUB: +#else + case MIPS_INS_FSUB_D: + case MIPS_INS_FSUB_W: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_SUB: + case MIPS_INS_SUBU: + case MIPS_INS_DSUB: + case MIPS_INS_DSUBU: + PROTECT_ZERO() { + rz_strbuf_appendf(&op->esil, "%s,%s,-,%s,=", + ARG(2), ARG(1), ARG(0)); + } + break; +#if CS_NEXT_VERSION < 6 + case MIPS_INS_NEGU: +#else + case MIPS_INS_NEG_D: + case MIPS_INS_NEG_S: +#endif /* CS_NEXT_VERSION */ + case MIPS_INS_NEG: + rz_strbuf_appendf(&op->esil, "%s,0,-,%s,=,", + ARG(1), ARG(0)); + break; + + /** signed -- sets overflow flag */ + case MIPS_INS_ADD: { + PROTECT_ZERO() { + ES_ADD_CK32_OVERF(ARG(1), ARG(2), ARG(0)); + } + } break; + case MIPS_INS_ADDI: + PROTECT_ZERO() { + ES_ADD_CK32_OVERF(ARG(1), ARG(2), ARG(0)); + } + break; + case MIPS_INS_DADD: + case MIPS_INS_DADDI: + ES_ADD_CK64_OVERF(ARG(1), ARG(2), ARG(0)); + break; + /** unsigned */ + case MIPS_INS_DADDU: + case MIPS_INS_ADDU: + case MIPS_INS_ADDIU: + case MIPS_INS_DADDIU: { + const char *arg0 = ARG(0); + const char *arg1 = ARG(1); + const char *arg2 = ARG(2); + PROTECT_ZERO() { + if (*arg2 == '-') { + rz_strbuf_appendf(&op->esil, "%s,%s,-,%s,=", + arg2 + 1, arg1, arg0); + } else { + rz_strbuf_appendf(&op->esil, "%s,%s,+,%s,=", + arg2, arg1, arg0); + } + } + } break; + case MIPS_INS_LI: +#if CS_NEXT_VERSION < 6 + case MIPS_INS_LDI: +#else + case MIPS_INS_LDI_B: + case MIPS_INS_LDI_D: + case MIPS_INS_LDI_H: + case MIPS_INS_LDI_W: +#endif /* CS_NEXT_VERSION */ + rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,=", (ut64)IMM(1), ARG(0)); + break; + case MIPS_INS_LUI: + rz_strbuf_appendf(&op->esil, "0x%" PFMT64x "0000,%s,=", (ut64)IMM(1), ARG(0)); + break; + case MIPS_INS_LB: + op->sign = true; + ESIL_LOAD("1"); + break; + case MIPS_INS_LBU: + // one of these is wrong + ESIL_LOAD("1"); + break; + case MIPS_INS_LW: + case MIPS_INS_LWC1: + case MIPS_INS_LWC2: + case MIPS_INS_LWL: + case MIPS_INS_LWR: + case MIPS_INS_LWU: + case MIPS_INS_LL: + ESIL_LOAD("4"); + break; + + case MIPS_INS_LDL: + case MIPS_INS_LDC1: + case MIPS_INS_LDC2: + case MIPS_INS_LLD: + case MIPS_INS_LD: + ESIL_LOAD("8"); + break; + + case MIPS_INS_LWX: + case MIPS_INS_LH: + case MIPS_INS_LHU: + case MIPS_INS_LHX: + ESIL_LOAD("2"); + break; + + case MIPS_INS_AND: + case MIPS_INS_ANDI: { + const char *arg0 = ARG(0); + const char *arg1 = ARG(1); + const char *arg2 = ARG(2); + if (!strcmp(arg0, arg1)) { + rz_strbuf_appendf(&op->esil, "%s,%s,&=", arg2, arg1); + } else { + rz_strbuf_appendf(&op->esil, "%s,%s,&,%s,=", arg2, arg1, arg0); + } + } break; + case MIPS_INS_OR: + case MIPS_INS_ORI: { + const char *arg0 = ARG(0); + const char *arg1 = ARG(1); + const char *arg2 = ARG(2); + PROTECT_ZERO() { + rz_strbuf_appendf(&op->esil, "%s,%s,|,%s,=", + arg2, arg1, arg0); + } + } break; + case MIPS_INS_XOR: + case MIPS_INS_XORI: { + const char *arg0 = ARG(0); + const char *arg1 = ARG(1); + const char *arg2 = ARG(2); + PROTECT_ZERO() { + rz_strbuf_appendf(&op->esil, "%s,%s,^,%s,=", + arg2, arg1, arg0); + } + } break; + case MIPS_INS_NOR: { + const char *arg0 = ARG(0); + const char *arg1 = ARG(1); + const char *arg2 = ARG(2); + PROTECT_ZERO() { + rz_strbuf_appendf(&op->esil, "%s,%s,|,0xffffffff,^,%s,=", + arg2, arg1, arg0); + } + } break; + case MIPS_INS_SLT: + case MIPS_INS_SLTI: + if (OPCOUNT() < 3) { + rz_strbuf_appendf(&op->esil, "%s,%s,<,t,=", ARG(1), ARG(0)); + } else { + rz_strbuf_appendf(&op->esil, "%s,%s,<,%s,=", ARG(2), ARG(1), ARG(0)); + } + break; + case MIPS_INS_SLTU: + case MIPS_INS_SLTIU: + if (OPCOUNT() < 3) { + rz_strbuf_appendf(&op->esil, ES_W("%s") "," ES_W("%s") ",<,t,=", + ARG(1), ARG(0)); + } else { + rz_strbuf_appendf(&op->esil, ES_W("%s") "," ES_W("%s") ",<,%s,=", + ARG(2), ARG(1), ARG(0)); + } + break; + case MIPS_INS_MUL: + rz_strbuf_appendf(&op->esil, ES_W("%s,%s,*") ",%s,=", ARG(1), ARG(2), ARG(0)); + ES_SIGN32_64(ARG(0)); + break; + case MIPS_INS_MULT: + case MIPS_INS_MULTU: + rz_strbuf_appendf(&op->esil, ES_W("%s,%s,*") ",lo,=", ARG(0), ARG(1)); + ES_SIGN32_64("lo"); + rz_strbuf_appendf(&op->esil, ES_W("32,%s,%s,*,>>") ",hi,=", ARG(0), ARG(1)); + ES_SIGN32_64("hi"); + break; + case MIPS_INS_MFLO: + PROTECT_ZERO() { + rz_strbuf_appendf(&op->esil, "lo,%s,=", REG(0)); + } + break; + case MIPS_INS_MFHI: + PROTECT_ZERO() { + rz_strbuf_appendf(&op->esil, "hi,%s,=", REG(0)); + } + break; + case MIPS_INS_MTLO: + rz_strbuf_appendf(&op->esil, "%s,lo,=", REG(0)); + ES_SIGN32_64("lo"); + break; + case MIPS_INS_MTHI: + rz_strbuf_appendf(&op->esil, "%s,hi,=", REG(0)); + ES_SIGN32_64("hi"); + break; + default: + return -1; + } + } + return 0; +} diff --git a/librz/arch/isa/mips/mips_internal.h b/librz/arch/isa/mips/mips_internal.h new file mode 100644 index 00000000000..dd2d3e5e40e --- /dev/null +++ b/librz/arch/isa/mips/mips_internal.h @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: 2012-2018 pancake +// SPDX-License-Identifier: LGPL-3.0-only + +#ifndef MIPS_INTERNAL_H +#define MIPS_INTERNAL_H + +#include +#include +#include + +RZ_IPI int mips_assemble_opcode(const char *str, ut64 pc, ut8 *out); +RZ_IPI int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn); + +#endif /* MIPS_INTERNAL_H */ diff --git a/librz/arch/meson.build b/librz/arch/meson.build index d777d98f0c3..2819cc10085 100644 --- a/librz/arch/meson.build +++ b/librz/arch/meson.build @@ -218,6 +218,7 @@ arch_isa_sources = [ 'isa/luac/v54/opcode_54.c', 'isa/mcore/mcore.c', 'isa/mips/mips_assembler.c', + 'isa/mips/mips_esil.c', 'isa/msp430/msp430_disas.c', 'isa/msp430/msp430_il.c', 'isa/or1k/or1k_disas.c', diff --git a/librz/arch/p/analysis/analysis_mips.c b/librz/arch/p/analysis/analysis_mips.c index 402f7ac7c5f..c3cfc189f4c 100644 --- a/librz/arch/p/analysis/analysis_mips.c +++ b/librz/arch/p/analysis/analysis_mips.c @@ -3,8 +3,7 @@ #include #include -#include -#include +#include static ut64 t9_pre = UT64_MAX; // http://www.mrc.uidaho.edu/mrc/people/jff/digital/MIPSir.html @@ -63,67 +62,6 @@ static ut64 t9_pre = UT64_MAX; SET_SRC_DST_3_REGS(op); \ } -// ESIL macros: - -// put the sign bit on the stack -#define ES_IS_NEGATIVE(arg) "1," arg ",<<<,1,&" - -// call with delay slot -#define ES_CALL_DR(ra, addr) "pc,4,+," ra ",=," ES_J(addr) -#define ES_CALL_D(addr) ES_CALL_DR("ra", addr) - -// call without delay slot -#define ES_CALL_NDR(ra, addr) "pc," ra ",=," ES_J(addr) -#define ES_CALL_ND(addr) ES_CALL_NDR("ra", addr) - -#define USE_DS 0 -#if USE_DS -// emit ERR trap if executed in a delay slot -#define ES_TRAP_DS() "$ds,!,!,?{,$$,1,TRAP,BREAK,}," -// jump to address -#define ES_J(addr) addr ",SETJT,1,SETD" -#else -#define ES_TRAP_DS() "" -#define ES_J(addr) addr ",pc,=" -#endif - -#define ES_B(x) "0xff," x ",&" -#define ES_H(x) "0xffff," x ",&" -#define ES_W(x) "0xffffffff," x ",&" - -// sign extend 32 -> 64 -#define ES_SIGN32_64(arg) es_sign_n_64(a, op, arg, 32) -#define ES_SIGN16_64(arg) es_sign_n_64(a, op, arg, 16) - -#define ES_ADD_CK32_OVERF(x, y, z) es_add_ck(op, x, y, z, 32) -#define ES_ADD_CK64_OVERF(x, y, z) es_add_ck(op, x, y, z, 64) - -static inline void es_sign_n_64(RzAnalysis *a, RzAnalysisOp *op, const char *arg, int bit) { - if (a->bits == 64) { - rz_strbuf_appendf(&op->esil, ",%d,%s,~,%s,=,", bit, arg, arg); - } else { - rz_strbuf_append(&op->esil, ","); - } -} - -static inline void es_add_ck(RzAnalysisOp *op, const char *a1, const char *a2, const char *re, int bit) { - ut64 mask = 1ULL << (bit - 1); - rz_strbuf_appendf(&op->esil, - "%d,0x%" PFMT64x ",%s,%s,^,&,>>,%d,0x%" PFMT64x ",%s,%s,+,&,>>,|,1,==,$z,?{,$$,1,TRAP,}{,%s,%s,+,%s,=,}", - bit - 2, mask, a1, a2, bit - 1, mask, a1, a2, a1, a2, re); -} - -#define PROTECT_ZERO() \ - if (REG(0)[0] == 'z') { \ - rz_strbuf_appendf(&op->esil, ","); \ - } else - -#define ESIL_LOAD(size) \ - PROTECT_ZERO() { \ - rz_strbuf_appendf(&op->esil, "%s,[" size "],%s,=", \ - ARG(1), REG(0)); \ - } - static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) { int i; PJ *pj = pj_new(); @@ -166,493 +104,6 @@ static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) { pj_free(pj); } -static const char *arg(csh *handle, cs_insn *insn, char *buf, int n) { - *buf = 0; - switch (insn->detail->mips.operands[n].type) { - case MIPS_OP_INVALID: - break; - case MIPS_OP_REG: - sprintf(buf, "%s", - cs_reg_name(*handle, - insn->detail->mips.operands[n].reg)); - break; - case MIPS_OP_IMM: { - st64 x = (st64)insn->detail->mips.operands[n].imm; - sprintf(buf, "%" PFMT64d, x); - } break; - case MIPS_OP_MEM: { - int disp = insn->detail->mips.operands[n].mem.disp; - if (disp < 0) { - sprintf(buf, "%" PFMT64d ",%s,-", - (ut64)-insn->detail->mips.operands[n].mem.disp, - cs_reg_name(*handle, - insn->detail->mips.operands[n].mem.base)); - } else { - sprintf(buf, "0x%" PFMT64x ",%s,+", - (ut64)insn->detail->mips.operands[n].mem.disp, - cs_reg_name(*handle, - insn->detail->mips.operands[n].mem.base)); - } - } break; - } - return buf; -} - -#define ARG(x) (*str[x] != 0) ? str[x] : arg(handle, insn, str[x], x) - -static int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn) { - char str[8][32] = { { 0 } }; - - rz_strbuf_init(&op->esil); - rz_strbuf_set(&op->esil, ""); - - if (!insn) { - return 0; - } - - // caching operands - for (int i = 0; i < insn->detail->mips.op_count && i < 8; i++) { - *str[i] = 0; - ARG(i); - } - { - switch (insn->id) { - case MIPS_INS_NOP: - rz_strbuf_setf(&op->esil, ","); - break; - case MIPS_INS_BREAK: - rz_strbuf_setf(&op->esil, "%" PFMT64d ",%" PFMT64d ",TRAP", (st64)IMM(0), (st64)IMM(0)); - break; - case MIPS_INS_SD: - rz_strbuf_appendf(&op->esil, "%s,%s,=[8]", - ARG(0), ARG(1)); - break; - case MIPS_INS_SW: - case MIPS_INS_SWL: - case MIPS_INS_SWR: - rz_strbuf_appendf(&op->esil, "%s,%s,=[4]", - ARG(0), ARG(1)); - break; - case MIPS_INS_SH: - rz_strbuf_appendf(&op->esil, "%s,%s,=[2]", - ARG(0), ARG(1)); - break; - case MIPS_INS_SWC1: - case MIPS_INS_SWC2: - rz_strbuf_setf(&op->esil, "%s,$", ARG(1)); - break; - case MIPS_INS_SB: - rz_strbuf_appendf(&op->esil, "%s,%s,=[1]", - ARG(0), ARG(1)); - break; -#if CS_NEXT_VERSION >= 6 - case MIPS_INS_CMPU_LE_QB: - case MIPS_INS_CMPGU_LE_QB: - case MIPS_INS_CMPGDU_LE_QB: - rz_strbuf_appendf(&op->esil, "%s,%s,<=", ARG(1), ARG(0)); - break; - case MIPS_INS_CMPU_LT_QB: - case MIPS_INS_CMPGU_LT_QB: - case MIPS_INS_CMPGDU_LT_QB: - rz_strbuf_appendf(&op->esil, "%s,%s,<", ARG(1), ARG(0)); - break; -#endif /* CS_NEXT_VERSION */ - case MIPS_INS_CMP: -#if CS_NEXT_VERSION < 6 - case MIPS_INS_CMPU: - case MIPS_INS_CMPGU: - case MIPS_INS_CMPGDU: -#else - case MIPS_INS_CMPU_EQ_QB: - case MIPS_INS_CMPGU_EQ_QB: - case MIPS_INS_CMPGDU_EQ_QB: -#endif /* CS_NEXT_VERSION */ - case MIPS_INS_CMPI: - rz_strbuf_appendf(&op->esil, "%s,%s,==", ARG(1), ARG(0)); - break; - case MIPS_INS_DSRA: - rz_strbuf_appendf(&op->esil, - "%s,%s,>>,31,%s,>>,?{,32,%s,32,-,0xffffffff,<<,0xffffffff,&,<<,}{,0,},|,%s,=", - ARG(2), ARG(1), ARG(1), ARG(2), ARG(0)); - break; -#if CS_NEXT_VERSION < 6 - case MIPS_INS_SHRAV: - case MIPS_INS_SHRAV_R: - case MIPS_INS_SHRA: - case MIPS_INS_SHRA_R: -#else - case MIPS_INS_SHRA_PH: - case MIPS_INS_SHRA_QB: - case MIPS_INS_SHRA_R_PH: - case MIPS_INS_SHRA_R_QB: - case MIPS_INS_SHRA_R_W: - case MIPS_INS_SHRAV_PH: - case MIPS_INS_SHRAV_QB: - case MIPS_INS_SHRAV_R_PH: - case MIPS_INS_SHRAV_R_QB: - case MIPS_INS_SHRAV_R_W: -#endif /* CS_NEXT_VERSION */ - case MIPS_INS_SRA: - rz_strbuf_appendf(&op->esil, - "0xffffffff,%s,%s,>>,&,31,%s,>>,?{,%s,32,-,0xffffffff,<<,0xffffffff,&,}{,0,},|,%s,=", - ARG(2), ARG(1), ARG(1), ARG(2), ARG(0)); - break; -#if CS_NEXT_VERSION < 6 - case MIPS_INS_SHRL: -#else - case MIPS_INS_SHRL_PH: - case MIPS_INS_SHRL_QB: - case MIPS_INS_SHRLV_PH: - case MIPS_INS_SHRLV_QB: -#endif /* CS_NEXT_VERSION */ - // suffix 'S' forces conditional flag to be updated - case MIPS_INS_SRLV: - case MIPS_INS_SRL: - rz_strbuf_appendf(&op->esil, "%s,%s,>>,%s,=", ARG(2), ARG(1), ARG(0)); - break; - case MIPS_INS_SLLV: - case MIPS_INS_SLL: - rz_strbuf_appendf(&op->esil, "%s,%s,<<,%s,=", ARG(2), ARG(1), ARG(0)); - break; - case MIPS_INS_BAL: - case MIPS_INS_JAL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_D("%s"), ARG(0)); - break; - case MIPS_INS_JALR: - case MIPS_INS_JALRS: - if (OPCOUNT() < 2) { - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_D("%s"), ARG(0)); - } else { - PROTECT_ZERO() { - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_DR("%s", "%s"), ARG(0), ARG(1)); - } - } - break; - case MIPS_INS_JALRC: // no delay - if (OPCOUNT() < 2) { - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_ND("%s"), ARG(0)); - } else { - PROTECT_ZERO() { - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_CALL_NDR("%s", "%s"), ARG(0), ARG(1)); - } - } - break; - case MIPS_INS_JRADDIUSP: - // increment stackpointer in X and jump to %ra - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,sp,+=," ES_J("ra"), ARG(0)); - break; - case MIPS_INS_JR: - case MIPS_INS_JRC: - case MIPS_INS_J: - case MIPS_INS_B: // ??? - // jump to address with conditional - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "" ES_J("%s"), ARG(0)); - break; - case MIPS_INS_BNE: // bne $s, $t, offset - case MIPS_INS_BNEL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,%s,==,$z,!,?{," ES_J("%s") ",}", - ARG(0), ARG(1), ARG(2)); - break; - case MIPS_INS_BEQ: - case MIPS_INS_BEQL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,%s,==,$z,?{," ES_J("%s") ",}", - ARG(0), ARG(1), ARG(2)); - break; -#if CS_NEXT_VERSION < 6 - case MIPS_INS_BZ: -#else - case MIPS_INS_BZ_B: - case MIPS_INS_BZ_D: - case MIPS_INS_BZ_H: - case MIPS_INS_BZ_V: - case MIPS_INS_BZ_W: -#endif /* CS_NEXT_VERSION */ - case MIPS_INS_BEQZ: - case MIPS_INS_BEQZC: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,0,==,$z,?{," ES_J("%s") ",}", - ARG(0), ARG(1)); - break; - case MIPS_INS_BNEZ: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,0,==,$z,!,?{," ES_J("%s") ",}", - ARG(0), ARG(1)); - break; - case MIPS_INS_BEQZALC: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "%s,0,==,$z,?{," ES_CALL_ND("%s") ",}", - ARG(0), ARG(1)); - break; - case MIPS_INS_BLEZ: - case MIPS_INS_BLEZC: - case MIPS_INS_BLEZL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,%s,==,$z,?{," ES_J("%s") ",BREAK,},", - ARG(0), ARG(1)); - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", - ARG(0), ARG(1)); - break; - case MIPS_INS_BGEZ: - case MIPS_INS_BGEZC: - case MIPS_INS_BGEZL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", - ARG(0), ARG(1)); - break; - case MIPS_INS_BGEZAL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_D("%s") ",}", - ARG(0), ARG(1)); - break; - case MIPS_INS_BGEZALC: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_ND("%s") ",}", - ARG(0), ARG(1)); - break; - case MIPS_INS_BGTZALC: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,%s,==,$z,?{,BREAK,},", ARG(0)); - rz_strbuf_appendf(&op->esil, "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_ND("%s") ",}", - ARG(0), ARG(1)); - break; - case MIPS_INS_BLTZAL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_CALL_D("%s") ",}", ARG(0), ARG(1)); - break; - case MIPS_INS_BLTZ: - case MIPS_INS_BLTZC: - case MIPS_INS_BLTZL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "1," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", - ARG(0), ARG(1)); - break; - case MIPS_INS_BGTZ: - case MIPS_INS_BGTZC: - case MIPS_INS_BGTZL: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,%s,==,$z,?{,BREAK,},", ARG(0)); - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0," ES_IS_NEGATIVE("%s") ",==,$z,?{," ES_J("%s") ",}", - ARG(0), ARG(1)); - break; - case MIPS_INS_BTEQZ: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,t,==,$z,?{," ES_J("%s") ",}", ARG(0)); - break; - case MIPS_INS_BTNEZ: - rz_strbuf_appendf(&op->esil, ES_TRAP_DS() "0,t,==,$z,!,?{," ES_J("%s") ",}", ARG(0)); - break; -#if CS_NEXT_VERSION < 6 - case MIPS_INS_MOV: -#else - case MIPS_INS_MOV_D: - case MIPS_INS_MOV_S: -#endif /* CS_NEXT_VERSION */ - case MIPS_INS_MOVE: - PROTECT_ZERO() { - rz_strbuf_appendf(&op->esil, "%s,%s,=", ARG(1), REG(0)); - } - break; - case MIPS_INS_MOVZ: - case MIPS_INS_MOVF: - PROTECT_ZERO() { - rz_strbuf_appendf(&op->esil, "0,%s,==,$z,?{,%s,%s,=,}", - ARG(2), ARG(1), REG(0)); - } - break; - case MIPS_INS_MOVT: - PROTECT_ZERO() { - rz_strbuf_appendf(&op->esil, "1,%s,==,$z,?{,%s,%s,=,}", - ARG(2), ARG(1), REG(0)); - } - break; -#if CS_NEXT_VERSION < 6 - case MIPS_INS_FSUB: -#else - case MIPS_INS_FSUB_D: - case MIPS_INS_FSUB_W: -#endif /* CS_NEXT_VERSION */ - case MIPS_INS_SUB: - case MIPS_INS_SUBU: - case MIPS_INS_DSUB: - case MIPS_INS_DSUBU: - PROTECT_ZERO() { - rz_strbuf_appendf(&op->esil, "%s,%s,-,%s,=", - ARG(2), ARG(1), ARG(0)); - } - break; -#if CS_NEXT_VERSION < 6 - case MIPS_INS_NEGU: -#else - case MIPS_INS_NEG_D: - case MIPS_INS_NEG_S: -#endif /* CS_NEXT_VERSION */ - case MIPS_INS_NEG: - rz_strbuf_appendf(&op->esil, "%s,0,-,%s,=,", - ARG(1), ARG(0)); - break; - - /** signed -- sets overflow flag */ - case MIPS_INS_ADD: { - PROTECT_ZERO() { - ES_ADD_CK32_OVERF(ARG(1), ARG(2), ARG(0)); - } - } break; - case MIPS_INS_ADDI: - PROTECT_ZERO() { - ES_ADD_CK32_OVERF(ARG(1), ARG(2), ARG(0)); - } - break; - case MIPS_INS_DADD: - case MIPS_INS_DADDI: - ES_ADD_CK64_OVERF(ARG(1), ARG(2), ARG(0)); - break; - /** unsigned */ - case MIPS_INS_DADDU: - case MIPS_INS_ADDU: - case MIPS_INS_ADDIU: - case MIPS_INS_DADDIU: { - const char *arg0 = ARG(0); - const char *arg1 = ARG(1); - const char *arg2 = ARG(2); - PROTECT_ZERO() { - if (*arg2 == '-') { - rz_strbuf_appendf(&op->esil, "%s,%s,-,%s,=", - arg2 + 1, arg1, arg0); - } else { - rz_strbuf_appendf(&op->esil, "%s,%s,+,%s,=", - arg2, arg1, arg0); - } - } - } break; - case MIPS_INS_LI: -#if CS_NEXT_VERSION < 6 - case MIPS_INS_LDI: -#else - case MIPS_INS_LDI_B: - case MIPS_INS_LDI_D: - case MIPS_INS_LDI_H: - case MIPS_INS_LDI_W: -#endif /* CS_NEXT_VERSION */ - rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,=", (ut64)IMM(1), ARG(0)); - break; - case MIPS_INS_LUI: - rz_strbuf_appendf(&op->esil, "0x%" PFMT64x "0000,%s,=", (ut64)IMM(1), ARG(0)); - break; - case MIPS_INS_LB: - op->sign = true; - ESIL_LOAD("1"); - break; - case MIPS_INS_LBU: - // one of these is wrong - ESIL_LOAD("1"); - break; - case MIPS_INS_LW: - case MIPS_INS_LWC1: - case MIPS_INS_LWC2: - case MIPS_INS_LWL: - case MIPS_INS_LWR: - case MIPS_INS_LWU: - case MIPS_INS_LL: - ESIL_LOAD("4"); - break; - - case MIPS_INS_LDL: - case MIPS_INS_LDC1: - case MIPS_INS_LDC2: - case MIPS_INS_LLD: - case MIPS_INS_LD: - ESIL_LOAD("8"); - break; - - case MIPS_INS_LWX: - case MIPS_INS_LH: - case MIPS_INS_LHU: - case MIPS_INS_LHX: - ESIL_LOAD("2"); - break; - - case MIPS_INS_AND: - case MIPS_INS_ANDI: { - const char *arg0 = ARG(0); - const char *arg1 = ARG(1); - const char *arg2 = ARG(2); - if (!strcmp(arg0, arg1)) { - rz_strbuf_appendf(&op->esil, "%s,%s,&=", arg2, arg1); - } else { - rz_strbuf_appendf(&op->esil, "%s,%s,&,%s,=", arg2, arg1, arg0); - } - } break; - case MIPS_INS_OR: - case MIPS_INS_ORI: { - const char *arg0 = ARG(0); - const char *arg1 = ARG(1); - const char *arg2 = ARG(2); - PROTECT_ZERO() { - rz_strbuf_appendf(&op->esil, "%s,%s,|,%s,=", - arg2, arg1, arg0); - } - } break; - case MIPS_INS_XOR: - case MIPS_INS_XORI: { - const char *arg0 = ARG(0); - const char *arg1 = ARG(1); - const char *arg2 = ARG(2); - PROTECT_ZERO() { - rz_strbuf_appendf(&op->esil, "%s,%s,^,%s,=", - arg2, arg1, arg0); - } - } break; - case MIPS_INS_NOR: { - const char *arg0 = ARG(0); - const char *arg1 = ARG(1); - const char *arg2 = ARG(2); - PROTECT_ZERO() { - rz_strbuf_appendf(&op->esil, "%s,%s,|,0xffffffff,^,%s,=", - arg2, arg1, arg0); - } - } break; - case MIPS_INS_SLT: - case MIPS_INS_SLTI: - if (OPCOUNT() < 3) { - rz_strbuf_appendf(&op->esil, "%s,%s,<,t,=", ARG(1), ARG(0)); - } else { - rz_strbuf_appendf(&op->esil, "%s,%s,<,%s,=", ARG(2), ARG(1), ARG(0)); - } - break; - case MIPS_INS_SLTU: - case MIPS_INS_SLTIU: - if (OPCOUNT() < 3) { - rz_strbuf_appendf(&op->esil, ES_W("%s") "," ES_W("%s") ",<,t,=", - ARG(1), ARG(0)); - } else { - rz_strbuf_appendf(&op->esil, ES_W("%s") "," ES_W("%s") ",<,%s,=", - ARG(2), ARG(1), ARG(0)); - } - break; - case MIPS_INS_MUL: - rz_strbuf_appendf(&op->esil, ES_W("%s,%s,*") ",%s,=", ARG(1), ARG(2), ARG(0)); - ES_SIGN32_64(ARG(0)); - break; - case MIPS_INS_MULT: - case MIPS_INS_MULTU: - rz_strbuf_appendf(&op->esil, ES_W("%s,%s,*") ",lo,=", ARG(0), ARG(1)); - ES_SIGN32_64("lo"); - rz_strbuf_appendf(&op->esil, ES_W("32,%s,%s,*,>>") ",hi,=", ARG(0), ARG(1)); - ES_SIGN32_64("hi"); - break; - case MIPS_INS_MFLO: - PROTECT_ZERO() { - rz_strbuf_appendf(&op->esil, "lo,%s,=", REG(0)); - } - break; - case MIPS_INS_MFHI: - PROTECT_ZERO() { - rz_strbuf_appendf(&op->esil, "hi,%s,=", REG(0)); - } - break; - case MIPS_INS_MTLO: - rz_strbuf_appendf(&op->esil, "%s,lo,=", REG(0)); - ES_SIGN32_64("lo"); - break; - case MIPS_INS_MTHI: - rz_strbuf_appendf(&op->esil, "%s,hi,=", REG(0)); - ES_SIGN32_64("hi"); - break; - default: - return -1; - } - } - return 0; -} - static int parse_reg_name(RzRegItem *reg, csh handle, cs_insn *insn, int reg_num) { if (!reg) { return -1; @@ -723,33 +174,6 @@ static void op_fillval(RzAnalysis *analysis, RzAnalysisOp *op, csh *handle, cs_i } break; case RZ_ANALYSIS_OP_TYPE_DIV: // UDIV -#if 0 -capstone bug ------------- - $ r2 -a mips -e cfg.bigendian=1 -c "wx 0083001b" - - // should be 3 regs, right? - [0x00000000]> aoj~{} - [ - { - "opcode": "divu zero, a0, v1", - "disasm": "divu zero, a0, v1", - "mnemonic": "divu", - "sign": false, - "prefix": 0, - "id": 192, - "opex": { - "operands": [ - { - "type": "reg", - "value": "a0" - }, - { - "type": "reg", - "value": "v1" - } - ] - }, -#endif if (OPERAND(0).type == MIPS_OP_REG && OPERAND(1).type == MIPS_OP_REG && OPERAND(2).type == MIPS_OP_REG) { SET_SRC_DST_3_REGS(op); } else if (OPERAND(0).type == MIPS_OP_REG && OPERAND(1).type == MIPS_OP_REG) { diff --git a/librz/arch/p/asm/asm_mips.c b/librz/arch/p/asm/asm_mips.c index aa5996b6567..f3372ed0d25 100644 --- a/librz/arch/p/asm/asm_mips.c +++ b/librz/arch/p/asm/asm_mips.c @@ -3,7 +3,7 @@ #include #include -#include +#include #include "capstone.h" #include "cs_helper.h" #include "rz_util/rz_log.h" From 658a0ceaf0a182a9ae8d539e10340f7bd3277864 Mon Sep 17 00:00:00 2001 From: wargio Date: Wed, 11 Sep 2024 22:49:35 +0800 Subject: [PATCH 05/13] Fix compilation and tests --- librz/arch/isa/mips/mips_esil.c | 30 +- librz/arch/p/analysis/analysis_arm_cs.c | 1 - librz/arch/p/analysis/analysis_mips.c | 259 +++++-- librz/arch/p/arch_mips.c | 179 ++--- librz/arch/p/asm/asm_mips.c | 4 + librz/bin/format/elf/elf_info.c | 185 +++-- librz/bin/format/elf/glibc_elf.h | 198 +++-- librz/bin/p/bin_elf.inc | 4 + librz/core/cbin.c | 19 +- librz/core/cconfig.c | 2 + test/db/analysis/mips | 959 ++---------------------- test/db/cmd/cmd_list | 6 +- test/db/cmd/print | 2 +- 13 files changed, 696 insertions(+), 1152 deletions(-) diff --git a/librz/arch/isa/mips/mips_esil.c b/librz/arch/isa/mips/mips_esil.c index caff85044d4..422968f2233 100644 --- a/librz/arch/isa/mips/mips_esil.c +++ b/librz/arch/isa/mips/mips_esil.c @@ -6,6 +6,7 @@ #include #define OPCOUNT() insn->detail->mips.op_count +#define REGID(x) insn->detail->mips.operands[x].reg #define REG(x) cs_reg_name(*handle, insn->detail->mips.operands[x].reg) #define IMM(x) insn->detail->mips.operands[x].imm @@ -58,10 +59,18 @@ static inline void es_add_ck(RzAnalysisOp *op, const char *a1, const char *a2, c bit - 2, mask, a1, a2, bit - 1, mask, a1, a2, a1, a2, re); } +#if CS_NEXT_VERSION < 6 +#define PROTECT_ZERO() \ + if (REGID(0) == MIPS_REG_ZERO) { \ + rz_strbuf_appendf(&op->esil, ","); \ + } else +#else #define PROTECT_ZERO() \ - if (REG(0)[0] == 'z') { \ + if (REGID(0) == MIPS_REG_ZERO || \ + REGID(0) == MIPS_REG_ZERO_64) { \ rz_strbuf_appendf(&op->esil, ","); \ } else +#endif // CS_NEXT_VERSION #define ESIL_LOAD(size) \ PROTECT_ZERO() { \ @@ -215,7 +224,16 @@ RZ_IPI int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 break; case MIPS_INS_SLLV: case MIPS_INS_SLL: +#if CS_NEXT_VERSION < 6 rz_strbuf_appendf(&op->esil, "%s,%s,<<,%s,=", ARG(2), ARG(1), ARG(0)); +#else + if (REGID(0) == MIPS_REG_INVALID) { + // NOP + rz_strbuf_setf(&op->esil, ","); + } else { + rz_strbuf_appendf(&op->esil, "%s,%s,<<,%s,=", ARG(2), ARG(1), ARG(0)); + } +#endif /* CS_NEXT_VERSION */ break; case MIPS_INS_BAL: case MIPS_INS_JAL: @@ -434,24 +452,28 @@ RZ_IPI int analyze_op_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 ESIL_LOAD("1"); break; case MIPS_INS_LBU: + case MIPS_INS_LBUX: // one of these is wrong ESIL_LOAD("1"); break; + case MIPS_INS_LL: case MIPS_INS_LW: case MIPS_INS_LWC1: case MIPS_INS_LWC2: case MIPS_INS_LWL: case MIPS_INS_LWR: case MIPS_INS_LWU: - case MIPS_INS_LL: + case MIPS_INS_LWXC1: ESIL_LOAD("4"); break; - case MIPS_INS_LDL: + case MIPS_INS_LD: case MIPS_INS_LDC1: case MIPS_INS_LDC2: + case MIPS_INS_LDL: + case MIPS_INS_LDR: + case MIPS_INS_LDXC1: case MIPS_INS_LLD: - case MIPS_INS_LD: ESIL_LOAD("8"); break; diff --git a/librz/arch/p/analysis/analysis_arm_cs.c b/librz/arch/p/analysis/analysis_arm_cs.c index b4d374ac7b0..090ea56a0af 100644 --- a/librz/arch/p/analysis/analysis_arm_cs.c +++ b/librz/arch/p/analysis/analysis_arm_cs.c @@ -1,7 +1,6 @@ // SPDX-FileCopyrightText: 2013-2021 pancake // SPDX-License-Identifier: LGPL-3.0-only -#include "aarch64.h" #include #include #include diff --git a/librz/arch/p/analysis/analysis_mips.c b/librz/arch/p/analysis/analysis_mips.c index c3cfc189f4c..e04f80e3064 100644 --- a/librz/arch/p/analysis/analysis_mips.c +++ b/librz/arch/p/analysis/analysis_mips.c @@ -219,7 +219,6 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u return -1; } - // XXX no arch->cpu ?!?! CS_MODE_MICRO, N64 op->addr = addr; if (len < 4) { return -1; @@ -272,25 +271,35 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u case MIPS_INS_LDL: case MIPS_INS_LDR: case MIPS_INS_LDXC1: + op->delay = 1; op->type = RZ_ANALYSIS_OP_TYPE_LOAD; if (!op->refptr) { op->refptr = 8; } switch (OPERAND(1).type) { case MIPS_OP_MEM: +#if CS_NEXT_VERSION < 6 if (OPERAND(1).mem.base == MIPS_REG_GP) { op->ptr = analysis->gp + OPERAND(1).mem.disp; if (REGID(0) == MIPS_REG_T9) { t9_pre = op->ptr; } -#if CS_NEXT_VERSION < 6 } else if (REGID(0) == MIPS_REG_T9) { + t9_pre = UT64_MAX; + } #else + if (OPERAND(1).mem.base == MIPS_REG_GP || + OPERAND(1).mem.base == MIPS_REG_GP_64) { + op->ptr = analysis->gp + OPERAND(1).mem.disp; + if (REGID(0) == MIPS_REG_T9 || + REGID(0) == MIPS_REG_T9_64) { + t9_pre = op->ptr; + } } else if (REGID(0) == MIPS_REG_T9 || REGID(0) == MIPS_REG_T9_64) { -#endif t9_pre = UT64_MAX; } +#endif break; case MIPS_OP_IMM: op->ptr = OPERAND(1).imm; @@ -300,7 +309,6 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u default: break; } - // TODO: fill break; case MIPS_INS_SD: case MIPS_INS_SW: @@ -311,6 +319,7 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u case MIPS_INS_SWL: case MIPS_INS_SWR: case MIPS_INS_SWXC1: + op->delay = 1; op->type = RZ_ANALYSIS_OP_TYPE_STORE; break; case MIPS_INS_NOP: @@ -330,53 +339,73 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u case MIPS_INS_JALRS16: #endif /* CS_NEXT_VERSION */ case MIPS_INS_JALR: - op->type = RZ_ANALYSIS_OP_TYPE_UCALL; op->delay = 1; + op->type = RZ_ANALYSIS_OP_TYPE_UCALL; #if CS_NEXT_VERSION < 6 if (REGID(0) == MIPS_REG_25) { + op->jump = t9_pre; + t9_pre = UT64_MAX; + op->type = RZ_ANALYSIS_OP_TYPE_RCALL; + } #else if (REGID(0) == MIPS_REG_T9 || REGID(0) == MIPS_REG_T9_64) { -#endif op->jump = t9_pre; t9_pre = UT64_MAX; op->type = RZ_ANALYSIS_OP_TYPE_RCALL; } +#endif break; +#if CS_NEXT_VERSION >= 6 + case MIPS_INS_JRCADDIUSP: + op->delay = 0; + op->type = RZ_ANALYSIS_OP_TYPE_CALL; + op->jump = IMM(0); + break; +#endif case MIPS_INS_JAL: case MIPS_INS_JALS: case MIPS_INS_JALX: case MIPS_INS_JRADDIUSP: case MIPS_INS_BAL: - // (no blezal/bgtzal or blezall/bgtzall, only blezalc/bgtzalc) - case MIPS_INS_BLTZAL: // Branch on <0 and link + op->delay = 1; + op->type = RZ_ANALYSIS_OP_TYPE_CALL; + op->jump = IMM(0); + break; + case MIPS_INS_JIALC: + op->delay = 0; + op->type = RZ_ANALYSIS_OP_TYPE_CALL; + op->jump = IMM(0); + break; case MIPS_INS_BGEZAL: // Branch on >=0 and link + case MIPS_INS_BLTZAL: // Branch on <0 and link case MIPS_INS_BLTZALL: // "likely" versions case MIPS_INS_BGEZALL: - case MIPS_INS_BLTZALC: // compact versions - case MIPS_INS_BLEZALC: + op->delay = 1; + if (OPERAND(0).type == MIPS_OP_IMM) { + // this is a JAL + op->jump = IMM(0); + op->type = RZ_ANALYSIS_OP_TYPE_CALL; + } else { + op->jump = IMM(1); + op->fail = addr + (insn->size << 1); + op->type = RZ_ANALYSIS_OP_TYPE_CCALL; + } + break; case MIPS_INS_BGEZALC: + case MIPS_INS_BLTZALC: + case MIPS_INS_BLEZALC: case MIPS_INS_BGTZALC: - case MIPS_INS_JIALC: - case MIPS_INS_JIC: - op->type = RZ_ANALYSIS_OP_TYPE_CALL; - op->jump = IMM(0); - - switch (insn->id) { - case MIPS_INS_JIALC: - case MIPS_INS_JIC: - case MIPS_INS_BLTZALC: - case MIPS_INS_BLEZALC: - case MIPS_INS_BGEZALC: - case MIPS_INS_BGTZALC: - // compact versions (no delay) - op->delay = 0; - op->fail = addr + 4; - break; - default: - op->delay = 1; - op->fail = addr + 8; - break; + // compact versions + op->delay = 0; + if (OPERAND(0).type == MIPS_OP_IMM) { + // this is a JAL + op->jump = IMM(0); + op->type = RZ_ANALYSIS_OP_TYPE_CALL; + } else { + op->jump = IMM(1); + op->fail = addr + (insn->size << 1); + op->type = RZ_ANALYSIS_OP_TYPE_CCALL; } break; case MIPS_INS_LI: @@ -518,6 +547,16 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u case MIPS_INS_CMP: op->type = RZ_ANALYSIS_OP_TYPE_CMP; break; + case MIPS_INS_JIC: + op->delay = 0; + op->jump = IMM(0); + op->type = RZ_ANALYSIS_OP_TYPE_JMP; + break; + case MIPS_INS_J: + op->delay = 1; + op->jump = IMM(0); + op->type = RZ_ANALYSIS_OP_TYPE_JMP; + break; #if CS_NEXT_VERSION < 6 case MIPS_INS_BZ: case MIPS_INS_BNZ: @@ -542,8 +581,88 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u case MIPS_INS_BNEGI_D: case MIPS_INS_BNEGI_H: case MIPS_INS_BNEGI_W: + case MIPS_INS_BGE: + case MIPS_INS_BGEL: + case MIPS_INS_BGEU: + case MIPS_INS_BGEUL: + case MIPS_INS_BGT: + case MIPS_INS_BGTL: + case MIPS_INS_BGTU: + case MIPS_INS_BGTUL: + case MIPS_INS_BLE: + case MIPS_INS_BLEL: + case MIPS_INS_BLEU: + case MIPS_INS_BLEUL: + case MIPS_INS_BLT: + case MIPS_INS_BLTL: + case MIPS_INS_BLTU: + case MIPS_INS_BLTUL: + case MIPS_INS_B16: + case MIPS_INS_BADDU: + case MIPS_INS_BALC: + case MIPS_INS_BALIGN: + case MIPS_INS_BALRSC: + case MIPS_INS_BBEQZC: + case MIPS_INS_BBIT0: + case MIPS_INS_BBIT032: + case MIPS_INS_BBIT1: + case MIPS_INS_BBIT132: + case MIPS_INS_BBNEZC: + case MIPS_INS_BC: + case MIPS_INS_BC16: + case MIPS_INS_BC1EQZ: + case MIPS_INS_BC1EQZC: + case MIPS_INS_BC1F: + case MIPS_INS_BC1FL: + case MIPS_INS_BC1NEZ: + case MIPS_INS_BC1NEZC: + case MIPS_INS_BC1T: + case MIPS_INS_BC1TL: + case MIPS_INS_BC2EQZ: + case MIPS_INS_BC2EQZC: + case MIPS_INS_BC2NEZ: + case MIPS_INS_BC2NEZC: + case MIPS_INS_BCLRI_B: + case MIPS_INS_BCLRI_D: + case MIPS_INS_BCLRI_H: + case MIPS_INS_BCLRI_W: + case MIPS_INS_BCLR_B: + case MIPS_INS_BCLR_D: + case MIPS_INS_BCLR_H: + case MIPS_INS_BCLR_W: + case MIPS_INS_BEQC: + case MIPS_INS_BEQIC: + case MIPS_INS_BEQZ16: + case MIPS_INS_BEQZALC: + case MIPS_INS_BEQZC: + case MIPS_INS_BEQZC16: + case MIPS_INS_BGEC: + case MIPS_INS_BGEIC: + case MIPS_INS_BGEIUC: + case MIPS_INS_BGEUC: + case MIPS_INS_BGEZALS: + case MIPS_INS_BLTC: + case MIPS_INS_BLTIC: + case MIPS_INS_BLTIUC: + case MIPS_INS_BLTUC: + case MIPS_INS_BLTZALS: + case MIPS_INS_BMNZI_B: + case MIPS_INS_BMNZ_V: + case MIPS_INS_BMZI_B: + case MIPS_INS_BMZ_V: + case MIPS_INS_BNEC: + case MIPS_INS_BNEIC: + case MIPS_INS_BNEZ16: + case MIPS_INS_BNEZALC: + case MIPS_INS_BNEZC: + case MIPS_INS_BNEZC16: + case MIPS_INS_BNVC: + case MIPS_INS_BOVC: + case MIPS_INS_BPOSGE32: + case MIPS_INS_BPOSGE32C: + case MIPS_INS_BREAK16: + case MIPS_INS_BRSC: #endif /* CS_NEXT_VERSION */ - case MIPS_INS_J: case MIPS_INS_B: case MIPS_INS_BEQ: case MIPS_INS_BNE: @@ -565,12 +684,6 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u case MIPS_INS_BGEZC: case MIPS_INS_BLTZC: case MIPS_INS_BGTZC: - if (insn->id == MIPS_INS_J || insn->id == MIPS_INS_B) { - op->type = RZ_ANALYSIS_OP_TYPE_JMP; - } else { - op->type = RZ_ANALYSIS_OP_TYPE_CJMP; - } - if (OPERAND(0).type == MIPS_OP_IMM) { op->jump = IMM(0); } else if (OPERAND(1).type == MIPS_OP_IMM) { @@ -578,27 +691,81 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u } else if (OPERAND(2).type == MIPS_OP_IMM) { op->jump = IMM(2); } + op->fail = addr + insn->size; + op->type = RZ_ANALYSIS_OP_TYPE_CJMP; + op->delay = 1; switch (insn->id) { +#if CS_NEXT_VERSION >= 6 + case MIPS_INS_B16: +#endif + case MIPS_INS_B: + op->fail = UT64_MAX; + op->type = RZ_ANALYSIS_OP_TYPE_JMP; + break; + case MIPS_INS_BEQ: + if (OPCOUNT() == 1) { + // BEQ $zero $zero is B + op->fail = UT64_MAX; + op->type = RZ_ANALYSIS_OP_TYPE_JMP; + } + break; +#if CS_NEXT_VERSION >= 6 + case MIPS_INS_BALC: + case MIPS_INS_BC16: + case MIPS_INS_BEQC: + case MIPS_INS_BEQIC: + case MIPS_INS_BEQZALC: + case MIPS_INS_BEQZC: + case MIPS_INS_BGEC: + case MIPS_INS_BGEIC: + case MIPS_INS_BGEIUC: + case MIPS_INS_BGEUC: + case MIPS_INS_BLTC: + case MIPS_INS_BLTIC: + case MIPS_INS_BLTIUC: + case MIPS_INS_BLTUC: + case MIPS_INS_BNEC: + case MIPS_INS_BNEIC: + case MIPS_INS_BNEZALC: + case MIPS_INS_BNEZC: + case MIPS_INS_BNVC: + case MIPS_INS_BOVC: + case MIPS_INS_BRSC: + case MIPS_INS_BEQZC16: + case MIPS_INS_BNEZC16: +#endif case MIPS_INS_BLEZC: case MIPS_INS_BGEZC: case MIPS_INS_BLTZC: case MIPS_INS_BGTZC: // compact versions (no delay) op->delay = 0; - op->fail = addr + 4; break; default: - op->delay = 1; - op->fail = addr + 8; break; } break; +#if CS_NEXT_VERSION >= 6 + case MIPS_INS_JRC16: + case MIPS_INS_JR16: + case MIPS_INS_JR_HB: +#endif case MIPS_INS_JR: case MIPS_INS_JRC: +#if CS_NEXT_VERSION < 6 + if (insn->id == MIPS_INS_JRC) { +#else + if (insn->id == MIPS_INS_JRC || + insn->id == MIPS_INS_JRC16) { +#endif + // compact versions (no delay) + op->delay = 0; + } else { + op->delay = 1; + } op->type = RZ_ANALYSIS_OP_TYPE_RJMP; - op->delay = 1; // register is $ra, so jmp is a return if (insn->detail->mips.operands[0].reg == MIPS_REG_RA) { op->type = RZ_ANALYSIS_OP_TYPE_RET; @@ -676,6 +843,14 @@ static int analyze_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const u break; case MIPS_INS_SLLV: case MIPS_INS_SLL: +#if CS_NEXT_VERSION >= 6 + op->delay = 0; + if (REGID(0) == MIPS_REG_INVALID) { + // NOP + op->type = RZ_ANALYSIS_OP_TYPE_NOP; + break; + } +#endif /* CS_NEXT_VERSION */ op->type = RZ_ANALYSIS_OP_TYPE_SHL; SET_VAL(op, 2); break; @@ -814,7 +989,7 @@ static int archinfo(RzAnalysis *a, RzAnalysisInfoType query) { // nanomips uses 48-bits return 6; case RZ_ANALYSIS_ARCHINFO_TEXT_ALIGN: - /* fall-thru */ + return 2; case RZ_ANALYSIS_ARCHINFO_DATA_ALIGN: return 4; case RZ_ANALYSIS_ARCHINFO_CAN_USE_POINTERS: diff --git a/librz/arch/p/arch_mips.c b/librz/arch/p/arch_mips.c index 7e5be6c1122..6e47b3fd139 100644 --- a/librz/arch/p/arch_mips.c +++ b/librz/arch/p/arch_mips.c @@ -18,10 +18,6 @@ #define MIPS_CPUS CAPSTONE_CPUS "," EXTRA_CPUS #define MIPS_FEATURES CAPSTONE_FEATURES -static bool cs_mode_from_cpu(const char *cpu, const char *features, int bits, bool big_endian, cs_mode *mode) { - cs_mode _mode = (big_endian) ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN; -#if CS_NEXT_VERSION < 6 - (void)features; #define return_on_cpu(cpu_name, mode_flag) \ do { \ if (!strcmp(cpu, cpu_name)) { \ @@ -30,6 +26,12 @@ static bool cs_mode_from_cpu(const char *cpu, const char *features, int bits, bo } \ } while (0) +static bool cs_mode_from_cpu(const char *cpu, const char *features, int bits, bool big_endian, cs_mode *mode) { + cs_mode _mode = (big_endian) ? CS_MODE_BIG_ENDIAN : CS_MODE_LITTLE_ENDIAN; +#if CS_NEXT_VERSION < 6 + + (void)features; + switch (bits) { case 64: _mode |= CS_MODE_MIPS64; @@ -40,41 +42,42 @@ static bool cs_mode_from_cpu(const char *cpu, const char *features, int bits, bo default: return false; } - - if (RZ_STR_ISEMPTY(cpu)) { - *mode = _mode; - return true; + *mode = _mode; + + if (RZ_STR_ISNOTEMPTY(cpu)) { + return_on_cpu("micromips", CS_MODE_MICRO); + return_on_cpu("mips1", CS_MODE_MIPS2); // mips1 is subset of mips2 + return_on_cpu("mips2", CS_MODE_MIPS2); + return_on_cpu("mips3", CS_MODE_MIPS3); + return_on_cpu("mips4", CS_MODE_MIPS32); // old capstone uses the same + return_on_cpu("mips16", CS_MODE_MIPS32); // old capstone uses the same + return_on_cpu("mips32", CS_MODE_MIPS32); + return_on_cpu("mips32r6", CS_MODE_MIPS32R6); + return_on_cpu("mips64", CS_MODE_MIPS64); + + // extra cpus + return_on_cpu("r2300", CS_MODE_MIPS2); + return_on_cpu("r2600", CS_MODE_MIPS2); + return_on_cpu("r2800", CS_MODE_MIPS2); + return_on_cpu("r2000a", CS_MODE_MIPS2); + return_on_cpu("r2000", CS_MODE_MIPS2); + return_on_cpu("r3000a", CS_MODE_MIPS2); // ISA mips2 + return_on_cpu("r3000", CS_MODE_MIPS2); // ISA mips2 + return_on_cpu("r10000", CS_MODE_MIPS32); // old capstone uses the same } - return_on_cpu("micromips", CS_MODE_MICRO); - return_on_cpu("mips1", CS_MODE_MIPS2); // mips1 is subset of mips2 - return_on_cpu("mips2", CS_MODE_MIPS2); - return_on_cpu("mips3", CS_MODE_MIPS3); - return_on_cpu("mips4", CS_MODE_MIPS32); // old capstone uses the same - return_on_cpu("mips16", CS_MODE_MIPS32); // old capstone uses the same - return_on_cpu("mips32", CS_MODE_MIPS32); - return_on_cpu("mips32r6", CS_MODE_MIPS32R6); - return_on_cpu("mips64", CS_MODE_MIPS64); - - // extra cpus - return_on_cpu("r2300", CS_MODE_MIPS2); - return_on_cpu("r2600", CS_MODE_MIPS2); - return_on_cpu("r2800", CS_MODE_MIPS2); - return_on_cpu("r2000a", CS_MODE_MIPS2); - return_on_cpu("r2000", CS_MODE_MIPS2); - return_on_cpu("r3000a", CS_MODE_MIPS2); // ISA mips2 - return_on_cpu("r3000", CS_MODE_MIPS2); // ISA mips2 - return_on_cpu("r10000", CS_MODE_MIPS32); // old capstone uses the same - - return false; -#else -#define return_on_cpu(cpu_name, mode_flag) \ +#else // CS_NEXT_VERSION >= 6 +#define return_or_add_on_cpu(cpu_name, mode_flag) \ do { \ - if (cpu_len == strlen(cpu_name) && \ - !strncmp(cpu, cpu_name, cpu_len)) { \ + if (!strcmp(cpu, cpu_name)) { \ *mode = _mode | mode_flag; \ return true; \ } \ + const size_t cpu_name_len = strlen(cpu_name); \ + const char *p = strstr(cpu, cpu_name); \ + if (p && (p[cpu_name_len] == '\0' || p[cpu_name_len] == ' ')) { \ + _add_mode |= mode_flag; \ + } \ } while (0) bool is_noptr64 = RZ_STR_ISNOTEMPTY(features) && strstr(features, "noptr64"); @@ -86,66 +89,68 @@ static bool cs_mode_from_cpu(const char *cpu, const char *features, int bits, bo if (is_nofloat) { _mode |= CS_MODE_MIPS_NOFLOAT; } - if (RZ_STR_ISEMPTY(cpu) || cpu[0] == '+') { - switch (bits) { - case 64: // generic mips64 - *mode = _mode | CS_MODE_MIPS64; - return true; - case 32: // generic mips32 - *mode = _mode | CS_MODE_MIPS32; - return true; - case 16: // generic mips16 - *mode = _mode | CS_MODE_MIPS16; + + if (RZ_STR_ISNOTEMPTY(cpu)) { + cs_mode _add_mode = 0; + return_or_add_on_cpu("micromips", CS_MODE_MICRO); + return_or_add_on_cpu("mips1", CS_MODE_MIPS1); + return_or_add_on_cpu("mips2", CS_MODE_MIPS2); + return_or_add_on_cpu("mips16", CS_MODE_MIPS16); + return_or_add_on_cpu("mips32", CS_MODE_MIPS3); // we always map the generic mips32 as mips3 + return_or_add_on_cpu("mips32r2", CS_MODE_MIPS32R2); + return_or_add_on_cpu("mips32r3", CS_MODE_MIPS32R3); + return_or_add_on_cpu("mips32r5", CS_MODE_MIPS32R5); + return_or_add_on_cpu("mips32r6", CS_MODE_MIPS32R6); + return_or_add_on_cpu("mips3", CS_MODE_MIPS3); + return_or_add_on_cpu("mips4", CS_MODE_MIPS4); + return_or_add_on_cpu("mips5", CS_MODE_MIPS5); + return_or_add_on_cpu("mips64", CS_MODE_MIPS64); + return_or_add_on_cpu("mips64r2", CS_MODE_MIPS64R2); + return_or_add_on_cpu("mips64r3", CS_MODE_MIPS64R3); + return_or_add_on_cpu("mips64r5", CS_MODE_MIPS64R5); + return_or_add_on_cpu("mips64r6", CS_MODE_MIPS64R6); + return_or_add_on_cpu("octeon", CS_MODE_OCTEON); + return_or_add_on_cpu("octeonp", CS_MODE_OCTEONP); + return_or_add_on_cpu("nanomips", CS_MODE_NANOMIPS); + return_or_add_on_cpu("nms1", CS_MODE_NMS1); + return_or_add_on_cpu("i7200", CS_MODE_I7200); +#undef return_or_add_on_cpu + + if (_add_mode) { + *mode = _add_mode; return true; - default: - return false; } - return true; - } - size_t cpu_len = strlen(cpu); - const char *plus = NULL; - if ((plus = strchr(cpu, '+'))) { - cpu_len = plus - cpu; + // special cpus. + return_on_cpu("micro32r3", CS_MODE_MICRO32R3); + return_on_cpu("micro32r6", CS_MODE_MICRO32R6); + + // extra cpus + return_on_cpu("r2300", CS_MODE_MIPS2); + return_on_cpu("r2600", CS_MODE_MIPS2); + return_on_cpu("r2800", CS_MODE_MIPS2); + return_on_cpu("r2000a", CS_MODE_MIPS2); + return_on_cpu("r2000", CS_MODE_MIPS2); + return_on_cpu("r3000a", CS_MODE_MIPS2); // ISA mips2 + return_on_cpu("r3000", CS_MODE_MIPS2); // ISA mips2 + return_on_cpu("r10000", CS_MODE_MIPS4); } - return_on_cpu("micromips", CS_MODE_MICRO); - return_on_cpu("mips1", CS_MODE_MIPS1); - return_on_cpu("mips2", CS_MODE_MIPS2); - return_on_cpu("mips16", CS_MODE_MIPS16); - return_on_cpu("mips32", CS_MODE_MIPS32); - return_on_cpu("mips32r2", CS_MODE_MIPS32R2); - return_on_cpu("mips32r3", CS_MODE_MIPS32R3); - return_on_cpu("mips32r5", CS_MODE_MIPS32R5); - return_on_cpu("mips32r6", CS_MODE_MIPS32R6); - return_on_cpu("mips3", CS_MODE_MIPS3); - return_on_cpu("mips4", CS_MODE_MIPS4); - return_on_cpu("mips5", CS_MODE_MIPS5); - return_on_cpu("mips64", CS_MODE_MIPS64); - return_on_cpu("mips64r2", CS_MODE_MIPS64R2); - return_on_cpu("mips64r3", CS_MODE_MIPS64R3); - return_on_cpu("mips64r5", CS_MODE_MIPS64R5); - return_on_cpu("mips64r6", CS_MODE_MIPS64R6); - return_on_cpu("octeon", CS_MODE_OCTEON); - return_on_cpu("octeonp", CS_MODE_OCTEONP); - return_on_cpu("nanomips", CS_MODE_NANOMIPS); - return_on_cpu("nms1", CS_MODE_NMS1); - return_on_cpu("i7200", CS_MODE_I7200); - return_on_cpu("micro32r3", CS_MODE_MICRO32R3); - return_on_cpu("micro32r6", CS_MODE_MICRO32R6); - - // extra cpus - return_on_cpu("r2300", CS_MODE_MIPS2); - return_on_cpu("r2600", CS_MODE_MIPS2); - return_on_cpu("r2800", CS_MODE_MIPS2); - return_on_cpu("r2000a", CS_MODE_MIPS2); - return_on_cpu("r2000", CS_MODE_MIPS2); - return_on_cpu("r3000a", CS_MODE_MIPS2); // ISA mips2 - return_on_cpu("r3000", CS_MODE_MIPS2); // ISA mips2 - return_on_cpu("r10000", CS_MODE_MIPS4); - + switch (bits) { + case 64: // generic mips64 + *mode = _mode | CS_MODE_MIPS64R3; + break; + case 32: // generic mips32 + *mode = _mode | CS_MODE_MIPS5; + break; + case 16: // generic mips16 + *mode = _mode | CS_MODE_MIPS16; + break; + default: + return false; + } #endif /* CS_NEXT_VERSION */ - return false; + return true; } #undef return_on_cpu diff --git a/librz/arch/p/asm/asm_mips.c b/librz/arch/p/asm/asm_mips.c index f3372ed0d25..30596524a6a 100644 --- a/librz/arch/p/asm/asm_mips.c +++ b/librz/arch/p/asm/asm_mips.c @@ -52,7 +52,11 @@ static int mips_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { n = cs_disasm(ctx->handle, (ut8 *)buf, len, a->pc, 1, &insn); if (n < 1) { rz_asm_op_set_asm(op, "invalid"); +#if CS_NEXT_VERSION < 6 + op->size = mode & CS_MODE_MICRO ? 2 : 4; +#else op->size = mode & (CS_MODE_MICRO | CS_MODE_NANOMIPS | CS_MODE_MIPS16) ? 2 : 4; +#endif goto fin; } if (insn->size < 1) { diff --git a/librz/bin/format/elf/elf_info.c b/librz/bin/format/elf/elf_info.c index 7c3c473d265..976bad78c5c 100644 --- a/librz/bin/format/elf/elf_info.c +++ b/librz/bin/format/elf/elf_info.c @@ -6,10 +6,6 @@ #include "elf.h" -#define EF_MIPS_ABI_O32 0x00001000 /* O32 ABI. */ -#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended for 64 bit. */ -#define EF_MIPS_ABI 0x0000f000 - #define VERSYM_VERSION 0x7fff struct mips_bits_translation { @@ -47,18 +43,6 @@ struct ver_flags_translation { const char *name; }; -static const struct mips_bits_translation mips_bits_translation_table[] = { - { EF_MIPS_ARCH_1, 32 }, - { EF_MIPS_ARCH_2, 32 }, - { EF_MIPS_ARCH_3, 32 }, - { EF_MIPS_ARCH_4, 32 }, - { EF_MIPS_ARCH_5, 32 }, - { EF_MIPS_ARCH_32, 32 }, - { EF_MIPS_ARCH_64, 64 }, - { EF_MIPS_ARCH_32R2, 32 }, - { EF_MIPS_ARCH_64R2, 64 } -}; - static const struct section_note_osabi_translation section_note_osabi_translation_table[] = { { ".note.openbsd.ident", "openbsd" }, { ".note.minix.ident", "minix" }, @@ -74,7 +58,7 @@ static const struct machine_name_translation machine_name_translation_table[] = { EM_68K, "Motorola m68k family" }, { EM_88K, "Motorola m88k family" }, { EM_860, "Intel 80860" }, - { EM_MIPS, "MIPS R3000" }, + { EM_MIPS, "MIPS R3000 big-endian" }, { EM_S370, "IBM System/370" }, { EM_MIPS_RS3_LE, "MIPS R3000 little-endian" }, { EM_PARISC, "HPPA" }, @@ -229,8 +213,51 @@ static const struct class_translation class_translation_table[] = { { ELFCLASS64, "ELF64" } }; -static const struct cpu_mips_translation cpu_mips_translation_table[] = { - { EF_MIPS_ARCH_1, "mips1" }, +static const struct cpu_mips_translation gnu_mips_mach_translation_table[] = { + { EF_MIPS_MACH_3900, "3900 " }, + { EF_MIPS_MACH_4010, "4010 " }, + { EF_MIPS_MACH_4100, "4100 " }, + { EF_MIPS_MACH_ALLEGREX, "allegrex " }, + { EF_MIPS_MACH_4650, "4650 " }, + { EF_MIPS_MACH_4120, "4120 " }, + { EF_MIPS_MACH_4111, "4111 " }, + { EF_MIPS_MACH_SB1, "sb1 " }, + { EF_MIPS_MACH_OCTEON, "octeon " }, + { EF_MIPS_MACH_XLR, "xlr " }, + { EF_MIPS_MACH_OCTEON2, "octeon2 " }, + { EF_MIPS_MACH_OCTEON3, "octeon3 " }, + { EF_MIPS_MACH_5400, "5400 " }, + { EF_MIPS_MACH_5900, "5900 " }, + { EF_MIPS_MACH_IAMR2, "iamr2 " }, + { EF_MIPS_MACH_5500, "5500 " }, + { EF_MIPS_MACH_9000, "9000 " }, + { EF_MIPS_MACH_LS2E, "ls2e " }, + { EF_MIPS_MACH_LS2F, "ls2f " }, + { EF_MIPS_MACH_GS464, "gs464 " }, + { EF_MIPS_MACH_GS464E, "gs464e " }, + { EF_MIPS_MACH_GS264E, "gs264e " }, +}; + +static const struct cpu_mips_translation gnu_mips_ase_translation_table[] = { + { EF_MIPS_ARCH_ASE_MDMX, "mdmx " }, + { EF_MIPS_ARCH_ASE_M16, "mips16 " }, + { EF_MIPS_ARCH_ASE_MICROMIPS, "micromips " }, +}; + +static const struct mips_bits_translation mips_bits_translation_table[] = { + { EF_MIPS_ARCH_1, 32 }, + { EF_MIPS_ARCH_2, 32 }, + { EF_MIPS_ARCH_3, 32 }, + { EF_MIPS_ARCH_4, 32 }, + { EF_MIPS_ARCH_5, 32 }, + { EF_MIPS_ARCH_32, 32 }, + { EF_MIPS_ARCH_64, 64 }, + { EF_MIPS_ARCH_32R2, 32 }, + { EF_MIPS_ARCH_64R2, 64 } +}; + +static const struct cpu_mips_translation gnu_mips_arch_translation_table[] = { + { EF_MIPS_ARCH_1, "mips5" }, // also used for generic mips, so we default to mips5 { EF_MIPS_ARCH_2, "mips2" }, { EF_MIPS_ARCH_3, "mips3" }, { EF_MIPS_ARCH_4, "mips4" }, @@ -632,17 +659,9 @@ static int get_bits_mips_common(Elf_(Word) mips_type) { return 32; } -static int is_playstation_hack(ELFOBJ *bin, Elf_(Word) mips_type) { - return Elf_(rz_bin_elf_is_executable)(bin) && Elf_(rz_bin_elf_is_static)(bin) && mips_type == EF_MIPS_ARCH_3; -} - static int get_bits_mips(ELFOBJ *bin) { const Elf_(Word) mips_type = bin->ehdr.e_flags & EF_MIPS_ARCH; - if (is_playstation_hack(bin, mips_type)) { - return 64; - } - return get_bits_mips_common(mips_type); } @@ -836,62 +855,114 @@ static char *get_file_type_basic(RZ_NONNULL ELFOBJ *bin) { static char *get_cpu_mips(ELFOBJ *bin) { Elf_(Word) mips_arch = bin->ehdr.e_flags & EF_MIPS_ARCH; + Elf_(Word) mips_ase = bin->ehdr.e_flags & EF_MIPS_ARCH_ASE; + Elf_(Word) mips_mach = bin->ehdr.e_flags & EF_MIPS_MACH; + + RzStrBuf sb; + rz_strbuf_init(&sb); + + for (size_t i = 0; i < RZ_ARRAY_SIZE(gnu_mips_mach_translation_table); i++) { + if (mips_mach == gnu_mips_mach_translation_table[i].arch) { + rz_strbuf_append(&sb, gnu_mips_mach_translation_table[i].name); + break; + } + } - for (size_t i = 0; i < RZ_ARRAY_SIZE(cpu_mips_translation_table); i++) { - if (mips_arch == cpu_mips_translation_table[i].arch) { - return rz_str_dup(cpu_mips_translation_table[i].name); + for (size_t i = 0; i < RZ_ARRAY_SIZE(gnu_mips_ase_translation_table); i++) { + if (mips_ase == gnu_mips_ase_translation_table[i].arch) { + rz_strbuf_append(&sb, gnu_mips_ase_translation_table[i].name); + break; + } + } + + for (size_t i = 0; i < RZ_ARRAY_SIZE(gnu_mips_arch_translation_table); i++) { + if (mips_arch == gnu_mips_arch_translation_table[i].arch) { + rz_strbuf_append(&sb, gnu_mips_arch_translation_table[i].name); + break; } } - return rz_str_dup(" Unknown mips ISA"); + if (rz_strbuf_is_empty(&sb)) { + return rz_str_dup("Unknown ISA"); + } + + return rz_strbuf_drain_nofree(&sb); } static bool is_elf_class64(ELFOBJ *bin) { return bin->ehdr.e_ident[EI_CLASS] == ELFCLASS64; } -static bool is_mips_o32(ELFOBJ *bin) { - if (bin->ehdr.e_ident[EI_CLASS] != ELFCLASS32) { - return false; +static bool is_elf_class32(ELFOBJ *bin) { + return bin->ehdr.e_ident[EI_CLASS] == ELFCLASS32; +} + +static char *get_abi_mips(ELFOBJ *bin) { + Elf_(Word) mips_eflags = bin->ehdr.e_flags; + Elf_(Word) mips_abi = mips_eflags & EF_MIPS_ABI; + + RzStrBuf sb; + rz_strbuf_init(&sb); + + if (mips_eflags & EF_MIPS_NOREORDER) { + rz_strbuf_append(&sb, "noreorder "); } - if ((bin->ehdr.e_flags & EF_MIPS_ABI2) != 0) { - return false; + if (mips_eflags & EF_MIPS_PIC) { + rz_strbuf_append(&sb, "pic "); } - if ((bin->ehdr.e_flags & EF_MIPS_ABI) != 0 && (bin->ehdr.e_flags & EF_MIPS_ABI) != EF_MIPS_ABI_O32) { - return false; + if (mips_eflags & EF_MIPS_CPIC) { + rz_strbuf_append(&sb, "cpic "); } - return true; -} + if (mips_eflags & EF_MIPS_XGOT) { + rz_strbuf_append(&sb, "xgot "); + } -static bool is_mips_n32(ELFOBJ *bin) { - if (bin->ehdr.e_ident[EI_CLASS] != ELFCLASS32) { - return false; + if (mips_eflags & EF_MIPS_UCODE) { + rz_strbuf_append(&sb, "ucode "); } - if ((bin->ehdr.e_flags & EF_MIPS_ABI2) == 0 || (bin->ehdr.e_flags & EF_MIPS_ABI) != 0) { - return false; + if (mips_eflags & EF_MIPS_ABI2) { + rz_strbuf_append(&sb, "abi2 "); } - return true; -} + if (mips_eflags & EF_MIPS_FP64) { + rz_strbuf_append(&sb, "fp64 "); + } -static char *get_abi_mips(ELFOBJ *bin) { - if (is_elf_class64(bin)) { - return rz_str_dup("n64"); + if (mips_eflags & EF_MIPS_NAN2008) { + rz_strbuf_append(&sb, "nan2008 "); } - if (is_mips_n32(bin)) { - return rz_str_dup("n32"); + if (mips_abi == EF_MIPS_ABI_O32) { + rz_strbuf_append(&sb, "o32 "); } - if (is_mips_o32(bin)) { - return rz_str_dup("o32"); + if (mips_abi == EF_MIPS_ABI_O64) { + rz_strbuf_append(&sb, "o64 "); } - return NULL; + if (mips_abi == EF_MIPS_ABI_EABI32) { + rz_strbuf_append(&sb, "eabi32 "); + } + + if (mips_abi == EF_MIPS_ABI_EABI64) { + rz_strbuf_append(&sb, "eabi64 "); + } + + if (is_elf_class64(bin)) { + rz_strbuf_append(&sb, "n64"); + } else if (is_elf_class32(bin)) { + rz_strbuf_append(&sb, "n32"); + } + + if (rz_strbuf_is_empty(&sb)) { + return rz_str_dup("Unknown ABI"); + } + + return rz_strbuf_drain_nofree(&sb); } /** @@ -1466,10 +1537,6 @@ RZ_OWN char *Elf_(rz_bin_elf_get_arch)(RZ_NONNULL ELFOBJ *bin) { RZ_OWN char *Elf_(rz_bin_elf_get_cpu)(RZ_NONNULL ELFOBJ *bin) { rz_return_val_if_fail(bin, NULL); - if (!Elf_(rz_bin_elf_has_segments)(bin)) { - return NULL; - } - if (bin->ehdr.e_machine == EM_MIPS) { return get_cpu_mips(bin); } diff --git a/librz/bin/format/elf/glibc_elf.h b/librz/bin/format/elf/glibc_elf.h index 070db55d1ba..b4a65074a6e 100644 --- a/librz/bin/format/elf/glibc_elf.h +++ b/librz/bin/format/elf/glibc_elf.h @@ -1624,18 +1624,38 @@ typedef struct /* MIPS R3000 specific definitions. */ -/* Legal values for e_flags field of Elf32_Ehdr. */ - -#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used. */ -#define EF_MIPS_PIC 2 /* Contains PIC code. */ -#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence. */ -#define EF_MIPS_XGOT 8 -#define EF_MIPS_64BIT_WHIRL 16 -#define EF_MIPS_ABI2 32 -#define EF_MIPS_ABI_ON32 64 -#define EF_MIPS_FP64 512 /* Uses FP64 (12 callee-saved). */ -#define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */ -#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */ +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_MIPS_NOREORDER 0x00000001 /* At least one .noreorder directive appears in the source. */ +#define EF_MIPS_PIC 0x00000002 /* File contains position independent code. */ +#define EF_MIPS_CPIC 0x00000004 /* Code in file uses the standard calling sequence for calling position independent code. */ +#define EF_MIPS_XGOT 0x00000008 /* ??? Unknown flag, set in IRIX 6's BSDdup2.o in libbsd.a. */ +#define EF_MIPS_UCODE 0x00000010 /* Code in file uses UCODE (obsolete) */ +#define EF_MIPS_ABI2 0x00000020 /* Code in file uses new ABI (-n32 on Irix 6). */ +#define EF_MIPS_OPTIONS_FIRST 0x00000080 /* Process the .MIPS.options section first by ld */ +#define EF_MIPS_32BITMODE 0x00000100 /* Indicates code compiled for a 64-bit machine in 32-bit mode (regs are 32-bits wide). */ +#define EF_MIPS_FP64 0x00000200 /* 32-bit machine but FP registers are 64 bit (-mfp64). */ +#define EF_MIPS_NAN2008 0x00000400 /* Code in file uses the IEEE 754-2008 NaN encoding convention. */ +#define EF_MIPS_ARCH_ASE 0x0f000000 /* Architectural Extensions used by this file */ +#define EF_MIPS_ARCH_ASE_MDMX 0x08000000 /* Use MDMX multimedia extensions */ +#define EF_MIPS_ARCH_ASE_M16 0x04000000 /* Use MIPS-16 ISA extensions */ +#define EF_MIPS_ARCH_ASE_MICROMIPS 0x02000000 /* Use MICROMIPS ISA extensions. */ +#define EF_MIPS_ARCH 0xf0000000 /* Four bit MIPS architecture field. */ +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_32 0x50000000 /* -mips32 code. */ +#define EF_MIPS_ARCH_64 0x60000000 /* -mips64 code. */ +#define EF_MIPS_ARCH_32R2 0x70000000 /* -mips32r2 code. */ +#define EF_MIPS_ARCH_64R2 0x80000000 /* -mips64r2 code. */ +#define EF_MIPS_ARCH_32R6 0x90000000 /* -mips32r6 code. */ +#define EF_MIPS_ARCH_64R6 0xa0000000 /* -mips64r6 code. */ +#define EF_MIPS_ABI 0x0000F000 /* The ABI of the file. Also see EF_MIPS_ABI2 above. */ +#define EF_MIPS_ABI_O32 0x00001000 /* The original o32 abi. */ +#define EF_MIPS_ABI_O64 0x00002000 /* O32 extended to work on 64 bit architectures */ +#define EF_MIPS_ABI_EABI32 0x00003000 /* EABI in 32 bit mode */ +#define EF_MIPS_ABI_EABI64 0x00004000 /* EABI in 64 bit mode */ /* Legal values for MIPS architecture level. */ @@ -1649,15 +1669,80 @@ typedef struct #define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32r2 code. */ #define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64r2 code. */ -/* The following are unofficial names and should not be used. */ - -#define E_MIPS_ARCH_1 EF_MIPS_ARCH_1 -#define E_MIPS_ARCH_2 EF_MIPS_ARCH_2 -#define E_MIPS_ARCH_3 EF_MIPS_ARCH_3 -#define E_MIPS_ARCH_4 EF_MIPS_ARCH_4 -#define E_MIPS_ARCH_5 EF_MIPS_ARCH_5 -#define E_MIPS_ARCH_32 EF_MIPS_ARCH_32 -#define E_MIPS_ARCH_64 EF_MIPS_ARCH_64 +/*In order to support backwards compatibility we also + define the old versions of some of these constants. */ +#define E_MIPS_ARCH_1 EF_MIPS_ARCH_1 +#define E_MIPS_ARCH_2 EF_MIPS_ARCH_2 +#define E_MIPS_ARCH_3 EF_MIPS_ARCH_3 +#define E_MIPS_ARCH_4 EF_MIPS_ARCH_4 +#define E_MIPS_ARCH_5 EF_MIPS_ARCH_5 +#define E_MIPS_ARCH_32 EF_MIPS_ARCH_32 +#define E_MIPS_ARCH_64 EF_MIPS_ARCH_64 +#define E_MIPS_ARCH_32R2 EF_MIPS_ARCH_32R2 +#define E_MIPS_ARCH_64R2 EF_MIPS_ARCH_64R2 +#define E_MIPS_ARCH_32R6 EF_MIPS_ARCH_32R6 +#define E_MIPS_ARCH_64R6 EF_MIPS_ARCH_64R6 +#define E_MIPS_ABI_O32 EF_MIPS_ABI_O32 +#define E_MIPS_ABI_O64 EF_MIPS_ABI_O64 +#define E_MIPS_ABI_EABI32 EF_MIPS_ABI_EABI32 +#define E_MIPS_ABI_EABI64 EF_MIPS_ABI_EABI64 + +/* Machine variant if we know it. This field was invented at Cygnus, + but it is hoped that other vendors will adopt it. If some standard + is developed, this code should be changed to follow it. */ +#define EF_MIPS_MACH 0x00FF0000 + +/* Cygnus is choosing values between 80 and 9F; + 00 - 7F should be left for a future standard; + the rest are open. */ + +#define EF_MIPS_MACH_3900 0x00810000 +#define EF_MIPS_MACH_4010 0x00820000 +#define EF_MIPS_MACH_4100 0x00830000 +#define EF_MIPS_MACH_ALLEGREX 0x00840000 +#define EF_MIPS_MACH_4650 0x00850000 +#define EF_MIPS_MACH_4120 0x00870000 +#define EF_MIPS_MACH_4111 0x00880000 +#define EF_MIPS_MACH_SB1 0x008a0000 +#define EF_MIPS_MACH_OCTEON 0x008b0000 +#define EF_MIPS_MACH_XLR 0x008c0000 +#define EF_MIPS_MACH_OCTEON2 0x008d0000 +#define EF_MIPS_MACH_OCTEON3 0x008e0000 +#define EF_MIPS_MACH_5400 0x00910000 +#define EF_MIPS_MACH_5900 0x00920000 +#define EF_MIPS_MACH_IAMR2 0x00930000 +#define EF_MIPS_MACH_5500 0x00980000 +#define EF_MIPS_MACH_9000 0x00990000 +#define EF_MIPS_MACH_LS2E 0x00A00000 +#define EF_MIPS_MACH_LS2F 0x00A10000 +#define EF_MIPS_MACH_GS464 0x00A20000 +#define EF_MIPS_MACH_GS464E 0x00A30000 +#define EF_MIPS_MACH_GS264E 0x00A40000 + +/* In order to support backwards compatibility we also + define the old versions of some of these constants. */ +#define E_MIPS_MACH_3900 EF_MIPS_MACH_3900 +#define E_MIPS_MACH_4010 EF_MIPS_MACH_4010 +#define E_MIPS_MACH_4100 EF_MIPS_MACH_4100 +#define E_MIPS_MACH_ALLEGREX EF_MIPS_MACH_ALLEGREX +#define E_MIPS_MACH_4650 EF_MIPS_MACH_4650 +#define E_MIPS_MACH_4120 EF_MIPS_MACH_4120 +#define E_MIPS_MACH_4111 EF_MIPS_MACH_4111 +#define E_MIPS_MACH_SB1 EF_MIPS_MACH_SB1 +#define E_MIPS_MACH_OCTEON EF_MIPS_MACH_OCTEON +#define E_MIPS_MACH_XLR EF_MIPS_MACH_XLR +#define E_MIPS_MACH_OCTEON2 EF_MIPS_MACH_OCTEON2 +#define E_MIPS_MACH_OCTEON3 EF_MIPS_MACH_OCTEON3 +#define E_MIPS_MACH_5400 EF_MIPS_MACH_5400 +#define E_MIPS_MACH_5900 EF_MIPS_MACH_5900 +#define E_MIPS_MACH_IAMR2 EF_MIPS_MACH_IAMR2 +#define E_MIPS_MACH_5500 EF_MIPS_MACH_5500 +#define E_MIPS_MACH_9000 EF_MIPS_MACH_9000 +#define E_MIPS_MACH_LS2E EF_MIPS_MACH_LS2E +#define E_MIPS_MACH_LS2F EF_MIPS_MACH_LS2F +#define E_MIPS_MACH_GS464 EF_MIPS_MACH_GS464 +#define E_MIPS_MACH_GS464E EF_MIPS_MACH_GS464E +#define E_MIPS_MACH_GS264E EF_MIPS_MACH_GS264E /* Special section indices. */ @@ -1667,21 +1752,20 @@ typedef struct #define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols. */ #define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols. */ -/* Legal values for sh_type field of Elf32_Shdr. */ - -#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link. */ -#define SHT_MIPS_MSYM 0x70000001 -#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols. */ -#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes. */ -#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ -#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging info. */ -#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information. */ +/* Processor specific section types. Legal values for sh_type field of Elf32_Shdr. */ +#define SHT_MIPS_LIBLIST 0x70000000 /* Section contains the set of dynamic shared objects used when statically linking. */ +#define SHT_MIPS_MSYM 0x70000001 /* I'm not sure what this is, but it's used on Irix 5. */ +#define SHT_MIPS_CONFLICT 0x70000002 /* Section contains list of symbols whose definitions conflict with symbols defined in shared objects. */ +#define SHT_MIPS_GPTAB 0x70000003 /* Section contains the global pointer table. */ +#define SHT_MIPS_UCODE 0x70000004 /* Section contains microcode information. The exact format is unspecified. */ +#define SHT_MIPS_DEBUG 0x70000005 /* Section contains some sort of debugging information. The exact format is unspecified. It's probably ECOFF symbols. */ +#define SHT_MIPS_REGINFO 0x70000006 /* Section contains register usage information. */ #define SHT_MIPS_PACKAGE 0x70000007 #define SHT_MIPS_PACKSYM 0x70000008 #define SHT_MIPS_RELD 0x70000009 -#define SHT_MIPS_IFACE 0x7000000b -#define SHT_MIPS_CONTENT 0x7000000c -#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ +#define SHT_MIPS_IFACE 0x7000000b /* Section contains interface information. */ +#define SHT_MIPS_CONTENT 0x7000000c /* Section contains description of contents of another section. */ +#define SHT_MIPS_OPTIONS 0x7000000d /* Section contains miscellaneous options. */ #define SHT_MIPS_SHDR 0x70000010 #define SHT_MIPS_FDESC 0x70000011 #define SHT_MIPS_EXTSYM 0x70000012 @@ -1693,33 +1777,33 @@ typedef struct #define SHT_MIPS_LOCSTR 0x70000018 #define SHT_MIPS_LINE 0x70000019 #define SHT_MIPS_RFDESC 0x7000001a -#define SHT_MIPS_DELTASYM 0x7000001b -#define SHT_MIPS_DELTAINST 0x7000001c -#define SHT_MIPS_DELTACLASS 0x7000001d -#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ -#define SHT_MIPS_DELTADECL 0x7000001f -#define SHT_MIPS_SYMBOL_LIB 0x70000020 -#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ +#define SHT_MIPS_DELTASYM 0x7000001b /* Delta C++: symbol table */ +#define SHT_MIPS_DELTAINST 0x7000001c /* Delta C++: instance table */ +#define SHT_MIPS_DELTACLASS 0x7000001d /* Delta C++: class table */ +#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging section. */ +#define SHT_MIPS_DELTADECL 0x7000001f /* Delta C++: declarations */ +#define SHT_MIPS_SYMBOL_LIB 0x70000020 /* List of libraries the binary depends on. Includes a time stamp, version number. */ +#define SHT_MIPS_EVENTS 0x70000021 /* Events section. */ #define SHT_MIPS_TRANSLATE 0x70000022 -#define SHT_MIPS_PIXIE 0x70000023 -#define SHT_MIPS_XLATE 0x70000024 -#define SHT_MIPS_XLATE_DEBUG 0x70000025 -#define SHT_MIPS_WHIRL 0x70000026 -#define SHT_MIPS_EH_REGION 0x70000027 -#define SHT_MIPS_XLATE_OLD 0x70000028 -#define SHT_MIPS_PDR_EXCEPTION 0x70000029 -#define SHT_MIPS_XHASH 0x7000002b +#define SHT_MIPS_PIXIE 0x70000023 /* Special pixie sections */ +#define SHT_MIPS_XLATE 0x70000024 /* Address translation table (for debug info) */ +#define SHT_MIPS_XLATE_DEBUG 0x70000025 /* SGI internal address translation table (for debug info) */ +#define SHT_MIPS_WHIRL 0x70000026 /* Intermediate code */ +#define SHT_MIPS_EH_REGION 0x70000027 /* C++ exception handling region info */ +#define SHT_MIPS_XLATE_OLD 0x70000028 /* Obsolete address translation table (for debug info) */ +#define SHT_MIPS_PDR_EXCEPTION 0x70000029 /* Runtime procedure descriptor table exception information (ucode) ??? */ +#define SHT_MIPS_ABIFLAGS 0x7000002a /* ABI related flags section. */ +#define SHT_MIPS_XHASH 0x7000002b /* GNU style symbol hash table with xlat. */ /* Legal values for sh_flags field of Elf32_Shdr. */ - -#define SHF_MIPS_GPREL 0x10000000 /* Must be in global data area. */ -#define SHF_MIPS_MERGE 0x20000000 -#define SHF_MIPS_ADDR 0x40000000 -#define SHF_MIPS_STRINGS 0x80000000 -#define SHF_MIPS_NOSTRIP 0x08000000 -#define SHF_MIPS_LOCAL 0x04000000 -#define SHF_MIPS_NAMES 0x02000000 -#define SHF_MIPS_NODUPE 0x01000000 +#define SHF_MIPS_GPREL 0x10000000 /* This section must be in the global data area. */ +#define SHF_MIPS_MERGE 0x20000000 /* This section should be merged. */ +#define SHF_MIPS_ADDR 0x40000000 /* This section contains address data of size implied by section element size. */ +#define SHF_MIPS_STRING 0x80000000 /* This section contains string data. */ +#define SHF_MIPS_NOSTRIP 0x08000000 /* This section may not be stripped. */ +#define SHF_MIPS_LOCAL 0x04000000 /* This section is local to threads. */ +#define SHF_MIPS_NAMES 0x02000000 /* Linker should generate implicit weak names for this section. */ +#define SHF_MIPS_NODUPES 0x01000000 /* Section contais text/data which may be replicated in other sections. Linker should retain only one copy. */ /* Symbol tables. */ diff --git a/librz/bin/p/bin_elf.inc b/librz/bin/p/bin_elf.inc index e7122124550..cea0b1c8a72 100644 --- a/librz/bin/p/bin_elf.inc +++ b/librz/bin/p/bin_elf.inc @@ -2034,6 +2034,10 @@ static RzBinInfo *info(RzBinFile *bf) { } if ((str = Elf_(rz_bin_elf_get_abi)(obj))) { ret->features = str; + if (!ret->has_pi) { + // Elf MIPS PIE flag is in features. + ret->has_pi = (strstr(str, "pic ")) ? 1 : 0; + } } ret->rclass = rz_str_dup("elf"); diff --git a/librz/core/cbin.c b/librz/core/cbin.c index 8cfff4d642f..41f3d2b98e8 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -25,14 +25,14 @@ #define LOAD_BSS_MALLOC 0 -#define IS_MODE_SET(mode) ((mode) & RZ_MODE_SET) -#define IS_MODE_SIMPLE(mode) ((mode) & RZ_MODE_SIMPLE) -#define IS_MODE_SIMPLEST(mode) ((mode) & RZ_MODE_SIMPLEST) -#define IS_MODE_JSON(mode) ((mode) & RZ_MODE_JSON) -#define IS_MODE_RZCMD(mode) ((mode) & RZ_MODE_RIZINCMD) -#define IS_MODE_EQUAL(mode) ((mode) & RZ_MODE_EQUAL) +#define IS_MODE_SET(mode) ((mode)&RZ_MODE_SET) +#define IS_MODE_SIMPLE(mode) ((mode)&RZ_MODE_SIMPLE) +#define IS_MODE_SIMPLEST(mode) ((mode)&RZ_MODE_SIMPLEST) +#define IS_MODE_JSON(mode) ((mode)&RZ_MODE_JSON) +#define IS_MODE_RZCMD(mode) ((mode)&RZ_MODE_RIZINCMD) +#define IS_MODE_EQUAL(mode) ((mode)&RZ_MODE_EQUAL) #define IS_MODE_NORMAL(mode) (!(mode)) -#define IS_MODE_CLASSDUMP(mode) ((mode) & RZ_MODE_CLASSDUMP) +#define IS_MODE_CLASSDUMP(mode) ((mode)&RZ_MODE_CLASSDUMP) // dup from cmd_info #define PAIR_WIDTH "9" @@ -3089,6 +3089,7 @@ RZ_API bool rz_core_bin_info_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile case RZ_OUTPUT_MODE_QUIET: rz_cons_printf("arch %s\n", info->arch); rz_cons_printf("cpu %s\n", str2na(info->cpu)); + rz_cons_printf("features %s\n", str2na(info->features)); rz_cons_printf("bits %d\n", bits); rz_cons_printf("os %s\n", info->os); rz_cons_printf("endian %s\n", info->big_endian ? "big" : "little"); @@ -3113,6 +3114,9 @@ RZ_API bool rz_core_bin_info_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile if (RZ_STR_ISNOTEMPTY(info->cpu)) { pj_ks(pj, "cpu", info->cpu); } + if (RZ_STR_ISNOTEMPTY(info->features)) { + pj_ks(pj, "features", info->features); + } pj_kn(pj, "baddr", rz_bin_get_baddr(core->bin)); pj_kn(pj, "binsz", rz_bin_get_size(core->bin)); if (RZ_STR_ISNOTEMPTY(info->rclass)) { @@ -3246,6 +3250,7 @@ RZ_API bool rz_core_bin_info_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile rz_table_add_rowf(t, "ss", "arch", str2na(info->arch)); rz_table_add_rowf(t, "ss", "cpu", str2na(info->cpu)); + rz_table_add_rowf(t, "ss", "features", str2na(info->features)); rz_table_add_rowf(t, "sX", "baddr", rz_bin_get_baddr(core->bin)); rz_table_add_rowf(t, "sX", "binsz", rz_bin_get_size(core->bin)); rz_table_add_rowf(t, "ss", "bintype", str2na(info->rclass)); diff --git a/librz/core/cconfig.c b/librz/core/cconfig.c index 2454595d21d..6a2ce2edc0e 100644 --- a/librz/core/cconfig.c +++ b/librz/core/cconfig.c @@ -550,6 +550,8 @@ static bool cb_asmarch(void *user, void *data) { bits = 64; } update_asmbits_options(core, rz_config_node_get(core->config, "asm.bits")); + } else { + rz_config_set(core->config, "asm.cpu", ""); } snprintf(asmparser, sizeof(asmparser), "%s.pseudo", node->value); rz_config_set(core->config, "asm.parser", asmparser); diff --git a/test/db/analysis/mips b/test/db/analysis/mips index aa679477880..aca78e8c50f 100644 --- a/test/db/analysis/mips +++ b/test/db/analysis/mips @@ -1,898 +1,75 @@ -NAME=mips hello reference analysis +NAME=mips ensure correct cpu is selected FILE=bins/elf/analysis/mips-hello CMDS=< /dev/null -pdf -EOF -EXPECT=< /dev/null -pd 10 -afl -EOF -EXPECT=</dev/null -pdf -EOF -EXPECT=< /dev/null -pdf -EOF -EXPECT=< /dev/null -pdf -EOF -EXPECT=< /dev/null -pdf -EOF -EXPECT=< /dev/null -pdf -EOF -EXPECT=< /dev/null -pdf -EOF -EXPECT=< /dev/null -pd 38 -EOF -EXPECT=< /dev/null -pd 38 -EOF -EXPECT=< /dev/null -pd 38 -EOF -EXPECT=< /dev/null -pd 38 -EOF -EXPECT=< 0x000804fc b 0x804fc +\ 0x00080500 nop + ; UNKNOWN XREF from section..dynsym @ +0xb4 + ; DATA XREF from sym.do_mips_start @ 0x80544 +/ int main(int argc, char **argv, char **envp); +| ; arg int argc @ a0 | ; var int32_t var_10h @ stack - 0x10 -| ; var int32_t var_ch @ stack - 0xc | ; var int32_t var_8h @ stack - 0x8 | ; var int32_t var_4h @ stack - 0x4 -| 0x00000794 lui gp, 2 -| 0x00000798 addiu gp, gp, -0x7db4 -| 0x0000079c addu gp, gp, t9 -| 0x000007a0 addiu sp, sp, -0x30 -| 0x000007a4 sw ra, 0x2c(sp) -| 0x000007a8 sw fp, 0x28(sp) -| 0x000007ac move fp, sp -| 0x000007b0 sw gp, 0x10(sp) -| 0x000007b4 addiu v0, zero, 1 -| 0x000007b8 sw v0, 0x18(fp) -| 0x000007bc addiu v0, zero, 2 -| 0x000007c0 sw v0, 0x1c(fp) -| 0x000007c4 addiu v0, zero, 3 -| 0x000007c8 sw v0, 0x20(fp) -| 0x000007cc addiu v0, zero, 4 -| 0x000007d0 sw v0, 0x24(fp) -| 0x000007d4 lw v0, -sym.leaffunc(gp) -| 0x000007d8 move t9, v0 -| 0x000007dc bal sym.leaffunc -| 0x000007e0 nop -| 0x000007e4 lw gp, 0x10(fp) -| 0x000007e8 lw v0, 0x24(fp) -| 0x000007ec sw v0, 0x1c(fp) -| 0x000007f0 lw v0, 0x18(fp) -| 0x000007f4 move sp, fp -| 0x000007f8 lw ra, 0x2c(sp) -| 0x000007fc lw fp, 0x28(sp) -| 0x00000800 addiu sp, sp, 0x30 -| 0x00000804 jr ra -\ 0x00000808 nop -afvR - var_4h 0x7f8 - var_8h 0x7fc - var_20h 0x7e4 - var_18h 0x7f0 - var_14h - var_10h - var_ch 0x7e8 -afvW - var_4h 0x7a4 - var_8h 0x7a8 - var_20h 0x7b0 - var_18h 0x7b8 - var_14h 0x7c0,0x7ec - var_10h 0x7c8 - var_ch 0x7d0 -EOF -RUN - -NAME=aav without vinfun -FILE=bins/elf/analysis/mipsbe-busybox -CMDS=< Date: Thu, 26 Sep 2024 21:22:47 +0200 Subject: [PATCH 06/13] Fix systemz with capstone 6 --- librz/arch/p/analysis/analysis_sysz.c | 175 +++++++++++++++++--------- librz/arch/p/asm/asm_sysz.c | 8 +- 2 files changed, 122 insertions(+), 61 deletions(-) diff --git a/librz/arch/p/analysis/analysis_sysz.c b/librz/arch/p/analysis/analysis_sysz.c index 855ed57a627..06c79f13a05 100644 --- a/librz/arch/p/analysis/analysis_sysz.c +++ b/librz/arch/p/analysis/analysis_sysz.c @@ -7,7 +7,18 @@ #include // instruction set: http://www.tachyonsoft.com/inst390m.htm -#define INSOP(n) insn->detail->sysz.operands[n] +#if CS_NEXT_VERSION < 6 +#define SYSTEMZ(x) SYSZ_##x +#define SYSTEMZ_ARCH CS_ARCH_SYSZ +#define cs_systemz cs_sysz +#define cs_systemz_op cs_sysz_op +#define systemz sysz +#define INSOP(n) insn->detail->sysz.operands[n] +#else +#define SYSTEMZ(x) SYSTEMZ_##x +#define SYSTEMZ_ARCH CS_ARCH_SYSTEMZ +#define INSOP(n) insn->detail->systemz.operands[n] +#endif static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) { int i; @@ -17,22 +28,22 @@ static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) { } pj_o(pj); pj_ka(pj, "operands"); - cs_sysz *x = &insn->detail->sysz; + cs_systemz *x = &insn->detail->systemz; for (i = 0; i < x->op_count; i++) { - cs_sysz_op *op = x->operands + i; + cs_systemz_op *op = x->operands + i; pj_o(pj); switch (op->type) { - case SYSZ_OP_REG: + case SYSTEMZ(OP_REG): pj_ks(pj, "type", "reg"); pj_ks(pj, "value", cs_reg_name(handle, op->reg)); break; - case SYSZ_OP_IMM: + case SYSTEMZ(OP_IMM): pj_ks(pj, "type", "imm"); pj_kN(pj, "value", op->imm); break; - case SYSZ_OP_MEM: + case SYSTEMZ(OP_MEM): pj_ks(pj, "type", "mem"); - if (op->mem.base != SYSZ_REG_INVALID) { + if (op->mem.base != SYSTEMZ(REG_INVALID)) { pj_ks(pj, "base", cs_reg_name(handle, op->mem.base)); } pj_kN(pj, "disp", op->mem.disp); @@ -55,7 +66,7 @@ static int analyze_op(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf csh handle; cs_insn *insn; int mode = CS_MODE_BIG_ENDIAN; - int ret = cs_open(CS_ARCH_SYSZ, mode, &handle); + int ret = cs_open(SYSTEMZ_ARCH, mode, &handle); if (ret == CS_ERR_OK) { cs_option(handle, CS_OPT_DETAIL, CS_OPT_ON); // capstone-next @@ -68,68 +79,112 @@ static int analyze_op(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf } op->size = insn->size; switch (insn->id) { - case SYSZ_INS_BRCL: - case SYSZ_INS_BRASL: + case SYSTEMZ(INS_BRCL): + case SYSTEMZ(INS_BRASL): op->type = RZ_ANALYSIS_OP_TYPE_CALL; break; - case SYSZ_INS_BR: + case SYSTEMZ(INS_BR): op->type = RZ_ANALYSIS_OP_TYPE_JMP; break; - case SYSZ_INS_BRC: - case SYSZ_INS_BER: - case SYSZ_INS_BHR: - case SYSZ_INS_BHER: - case SYSZ_INS_BLR: - case SYSZ_INS_BLER: - case SYSZ_INS_BLHR: - case SYSZ_INS_BNER: - case SYSZ_INS_BNHR: - case SYSZ_INS_BNHER: - case SYSZ_INS_BNLR: - case SYSZ_INS_BNLER: - case SYSZ_INS_BNLHR: - case SYSZ_INS_BNOR: - case SYSZ_INS_BOR: - case SYSZ_INS_BASR: - case SYSZ_INS_BRAS: - case SYSZ_INS_BRCT: - case SYSZ_INS_BRCTG: + case SYSTEMZ(INS_BRC): + case SYSTEMZ(INS_BER): + case SYSTEMZ(INS_BHR): + case SYSTEMZ(INS_BHER): + case SYSTEMZ(INS_BLR): + case SYSTEMZ(INS_BLER): + case SYSTEMZ(INS_BLHR): + case SYSTEMZ(INS_BNER): + case SYSTEMZ(INS_BNHR): + case SYSTEMZ(INS_BNHER): + case SYSTEMZ(INS_BNLR): + case SYSTEMZ(INS_BNLER): + case SYSTEMZ(INS_BNLHR): + case SYSTEMZ(INS_BNOR): + case SYSTEMZ(INS_BOR): + case SYSTEMZ(INS_BASR): + case SYSTEMZ(INS_BRAS): + case SYSTEMZ(INS_BRCT): + case SYSTEMZ(INS_BRCTG): op->type = RZ_ANALYSIS_OP_TYPE_CJMP; break; - case SYSZ_INS_JE: - case SYSZ_INS_JGE: - case SYSZ_INS_JHE: - case SYSZ_INS_JGHE: - case SYSZ_INS_JH: - case SYSZ_INS_JGH: - case SYSZ_INS_JLE: - case SYSZ_INS_JGLE: - case SYSZ_INS_JLH: - case SYSZ_INS_JGLH: - case SYSZ_INS_JL: - case SYSZ_INS_JGL: - case SYSZ_INS_JNE: - case SYSZ_INS_JGNE: - case SYSZ_INS_JNHE: - case SYSZ_INS_JGNHE: - case SYSZ_INS_JNH: - case SYSZ_INS_JGNH: - case SYSZ_INS_JNLE: - case SYSZ_INS_JGNLE: - case SYSZ_INS_JNLH: - case SYSZ_INS_JGNLH: - case SYSZ_INS_JNL: - case SYSZ_INS_JGNL: - case SYSZ_INS_JNO: - case SYSZ_INS_JGNO: - case SYSZ_INS_JO: - case SYSZ_INS_JGO: - case SYSZ_INS_JG: +#if CS_NEXT_VERSION < 6 + case SYSTEMZ(INS_JE): + case SYSTEMZ(INS_JGE): + case SYSTEMZ(INS_JHE): + case SYSTEMZ(INS_JGHE): + case SYSTEMZ(INS_JH): + case SYSTEMZ(INS_JGH): + case SYSTEMZ(INS_JLE): + case SYSTEMZ(INS_JGLE): + case SYSTEMZ(INS_JLH): + case SYSTEMZ(INS_JGLH): + case SYSTEMZ(INS_JL): + case SYSTEMZ(INS_JGL): + case SYSTEMZ(INS_JNE): + case SYSTEMZ(INS_JGNE): + case SYSTEMZ(INS_JNHE): + case SYSTEMZ(INS_JGNHE): + case SYSTEMZ(INS_JNH): + case SYSTEMZ(INS_JGNH): + case SYSTEMZ(INS_JNLE): + case SYSTEMZ(INS_JGNLE): + case SYSTEMZ(INS_JNLH): + case SYSTEMZ(INS_JGNLH): + case SYSTEMZ(INS_JNL): + case SYSTEMZ(INS_JGNL): + case SYSTEMZ(INS_JNO): + case SYSTEMZ(INS_JGNO): + case SYSTEMZ(INS_JO): + case SYSTEMZ(INS_JGO): + case SYSTEMZ(INS_JG): +#else + case SYSTEMZ(INS_JE): + case SYSTEMZ(INS_JH): + case SYSTEMZ(INS_JHE): + case SYSTEMZ(INS_JL): + case SYSTEMZ(INS_JLE): + case SYSTEMZ(INS_JLH): + case SYSTEMZ(INS_JM): + case SYSTEMZ(INS_JNE): + case SYSTEMZ(INS_JNH): + case SYSTEMZ(INS_JNHE): + case SYSTEMZ(INS_JNL): + case SYSTEMZ(INS_JNLE): + case SYSTEMZ(INS_JNLH): + case SYSTEMZ(INS_JNM): + case SYSTEMZ(INS_JNO): + case SYSTEMZ(INS_JNP): + case SYSTEMZ(INS_JNZ): + case SYSTEMZ(INS_JO): + case SYSTEMZ(INS_JP): + case SYSTEMZ(INS_JZ): + case SYSTEMZ(INS_J_G_LU_): + case SYSTEMZ(INS_J_G_L_E): + case SYSTEMZ(INS_J_G_L_H): + case SYSTEMZ(INS_J_G_L_HE): + case SYSTEMZ(INS_J_G_L_L): + case SYSTEMZ(INS_J_G_L_LE): + case SYSTEMZ(INS_J_G_L_LH): + case SYSTEMZ(INS_J_G_L_M): + case SYSTEMZ(INS_J_G_L_NE): + case SYSTEMZ(INS_J_G_L_NH): + case SYSTEMZ(INS_J_G_L_NHE): + case SYSTEMZ(INS_J_G_L_NL): + case SYSTEMZ(INS_J_G_L_NLE): + case SYSTEMZ(INS_J_G_L_NLH): + case SYSTEMZ(INS_J_G_L_NM): + case SYSTEMZ(INS_J_G_L_NO): + case SYSTEMZ(INS_J_G_L_NP): + case SYSTEMZ(INS_J_G_L_NZ): + case SYSTEMZ(INS_J_G_L_O): + case SYSTEMZ(INS_J_G_L_P): + case SYSTEMZ(INS_J_G_L_Z): +#endif op->type = RZ_ANALYSIS_OP_TYPE_CJMP; op->jump = INSOP(0).imm; op->fail = addr + op->size; break; - case SYSZ_INS_J: + case SYSTEMZ(INS_J): op->type = RZ_ANALYSIS_OP_TYPE_JMP; op->jump = INSOP(0).imm; op->fail = UT64_MAX; diff --git a/librz/arch/p/asm/asm_sysz.c b/librz/arch/p/asm/asm_sysz.c index 2d09897ec95..4e74975b95e 100644 --- a/librz/arch/p/asm/asm_sysz.c +++ b/librz/arch/p/asm/asm_sysz.c @@ -10,6 +10,12 @@ CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(sysz); +#if CS_NEXT_VERSION < 6 +#define SYSTEMZ_ARCH CS_ARCH_SYSZ +#else +#define SYSTEMZ_ARCH CS_ARCH_SYSTEMZ +#endif + static int sysz_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { CapstoneContext *ctx = (CapstoneContext *)a->plugin_data; int n, ret; @@ -23,7 +29,7 @@ static int sysz_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len) { ctx->omode = -1; } if (!ctx->handle) { - ret = cs_open(CS_ARCH_SYSZ, mode, &ctx->handle); + ret = cs_open(SYSTEMZ_ARCH, mode, &ctx->handle); if (ret) { return -1; } From db6f9f8481ba5d1e387adca07c9a9b2971d88c7b Mon Sep 17 00:00:00 2001 From: Rot127 Date: Sat, 28 Sep 2024 00:27:33 -0500 Subject: [PATCH 07/13] Handle ldr case without base register. --- librz/arch/isa/arm/arm_esil64.c | 9 +++++++-- librz/arch/isa/arm/arm_il64.c | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/librz/arch/isa/arm/arm_esil64.c b/librz/arch/isa/arm/arm_esil64.c index f484f9ea270..337d7efabea 100644 --- a/librz/arch/isa/arm/arm_esil64.c +++ b/librz/arch/isa/arm/arm_esil64.c @@ -713,8 +713,13 @@ RZ_IPI int rz_arm_cs_analysis_op_64_esil(RzAnalysis *a, RzAnalysisOp *op, ut64 a rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%s,-", -(st64)MEMDISP64(1), MEMBASE64(1)); } else { - rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%s,+", - MEMDISP64(1), MEMBASE64(1)); + if (insn->detail->CS_aarch64_.operands[1].mem.base == 0) { + rz_strbuf_appendf(&op->esil, "%" PFMT64d, + MEMDISP64(1)); + } else { + rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%s,+", + MEMDISP64(1), MEMBASE64(1)); + } } rz_strbuf_append(&op->esil, ",DUP,tmp,="); diff --git a/librz/arch/isa/arm/arm_il64.c b/librz/arch/isa/arm/arm_il64.c index 6bc1a4032d9..9e3337d6c91 100644 --- a/librz/arch/isa/arm/arm_il64.c +++ b/librz/arch/isa/arm/arm_il64.c @@ -246,7 +246,7 @@ static RzILOpBitVector *read_reg(CS_aarch64_reg() reg) { } const char *var = reg_var_name(reg); if (!var) { - return NULL; + return U64(0); } if (is_wreg(reg)) { return UNSIGNED(32, VARG(var)); From 7c442182deffdaf0bb96f8ccddd06a4105158e0c Mon Sep 17 00:00:00 2001 From: wargio Date: Fri, 27 Sep 2024 18:49:48 +0200 Subject: [PATCH 08/13] Fix ARM64 & ARM32 compilation with latest CS6 commit --- librz/arch/isa/arm/aarch64_meta_macros.h | 7 ++----- librz/arch/isa/arm/arm_accessors32.h | 5 ++--- librz/arch/isa/arm/arm_esil32.c | 2 ++ librz/arch/isa/arm/arm_il32.c | 4 ++++ librz/arch/p/analysis/analysis_arm_cs.c | 6 +++++- subprojects/capstone-next.wrap | 2 +- 6 files changed, 16 insertions(+), 10 deletions(-) diff --git a/librz/arch/isa/arm/aarch64_meta_macros.h b/librz/arch/isa/arm/aarch64_meta_macros.h index 540f07a42b7..fcd346cc578 100644 --- a/librz/arch/isa/arm/aarch64_meta_macros.h +++ b/librz/arch/isa/arm/aarch64_meta_macros.h @@ -4,8 +4,6 @@ #ifndef AARCH64_META_MACROS_H #define AARCH64_META_MACROS_H -#ifdef USE_SYS_CAPSTONE - /// Macro for meta programming. /// Meant for projects using Capstone and need to support multiple /// versions of it. @@ -14,7 +12,7 @@ #if CS_NEXT_VERSION < 6 #define CS_AARCH64(x) ARM64##x #else -#define CS_AARCH64(x) AArch64##x +#define CS_AARCH64(x) AARCH64##x #endif #if CS_NEXT_VERSION < 6 @@ -32,7 +30,7 @@ #if CS_NEXT_VERSION < 6 #define CS_AARCH64_VL_(x) ARM64_VAS_##x #else -#define CS_AARCH64_VL_(x) AArch64Layout_VL_##x +#define CS_AARCH64_VL_(x) AARCH64LAYOUT_VL_##x #endif #if CS_NEXT_VERSION < 6 @@ -65,5 +63,4 @@ #define CS_aarch64_vas() AArch64Layout_VectorLayout #endif -#endif // USE_SYS_CAPSTONE #endif // AARCH64_META_MACROS_H diff --git a/librz/arch/isa/arm/arm_accessors32.h b/librz/arch/isa/arm/arm_accessors32.h index 5ded7f07e28..27d478f8f80 100644 --- a/librz/arch/isa/arm/arm_accessors32.h +++ b/librz/arch/isa/arm/arm_accessors32.h @@ -27,14 +27,13 @@ #define ISMEM(x) (insn->detail->arm.operands[x].type == ARM_OP_MEM) #define ISFPIMM(x) (insn->detail->arm.operands[x].type == ARM_OP_FP) -#define LSHIFT(x) insn->detail->arm.operands[x].mem.lshift +#define LSHIFT(x) insn->detail->arm.operands[x].shift.value #define LSHIFT2(x) insn->detail->arm.operands[x].shift.value // Dangerous, returns value even if isn't LSL #define OPCOUNT() insn->detail->arm.op_count #define ISSHIFTED(x) (insn->detail->arm.operands[x].shift.type != ARM_SFT_INVALID && insn->detail->arm.operands[x].shift.value != 0) #define SHIFTTYPE(x) insn->detail->arm.operands[x].shift.type #define SHIFTTYPEREG(x) (SHIFTTYPE(x) == ARM_SFT_ASR_REG || SHIFTTYPE(x) == ARM_SFT_LSL_REG || \ - SHIFTTYPE(x) == ARM_SFT_LSR_REG || SHIFTTYPE(x) == ARM_SFT_ROR_REG || \ - SHIFTTYPE(x) == ARM_SFT_RRX_REG) + SHIFTTYPE(x) == ARM_SFT_LSR_REG || SHIFTTYPE(x) == ARM_SFT_ROR_REG) #define SHIFTVALUE(x) insn->detail->arm.operands[x].shift.value #if CS_NEXT_VERSION >= 6 diff --git a/librz/arch/isa/arm/arm_esil32.c b/librz/arch/isa/arm/arm_esil32.c index f7f931d311a..b6a9431edd9 100644 --- a/librz/arch/isa/arm/arm_esil32.c +++ b/librz/arch/isa/arm/arm_esil32.c @@ -34,7 +34,9 @@ static const char *decode_shift(arm_shifter shift) { case ARM_SFT_ROR: case ARM_SFT_RRX: case ARM_SFT_ROR_REG: +#if CS_NEXT_VERSION < 6 case ARM_SFT_RRX_REG: +#endif return E_OP_RR; default: diff --git a/librz/arch/isa/arm/arm_il32.c b/librz/arch/isa/arm/arm_il32.c index d9626787be4..b0a6d810115 100644 --- a/librz/arch/isa/arm/arm_il32.c +++ b/librz/arch/isa/arm/arm_il32.c @@ -348,7 +348,9 @@ static bool is_reg_shift(arm_shifter type) { case ARM_SFT_LSL_REG: case ARM_SFT_LSR_REG: case ARM_SFT_ROR_REG: +#if CS_NEXT_VERSION < 6 case ARM_SFT_RRX_REG: +#endif return true; default: return false; @@ -401,7 +403,9 @@ shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type SHIFTR0(val, dist), SHIFTL0(DUP(val), NEG(DUP(dist)))); case ARM_SFT_RRX: +#if CS_NEXT_VERSION < 6 case ARM_SFT_RRX_REG: +#endif if (carry_out) { *carry_out = LSB(DUP(val)); } diff --git a/librz/arch/p/analysis/analysis_arm_cs.c b/librz/arch/p/analysis/analysis_arm_cs.c index 090ea56a0af..e9630609ef6 100644 --- a/librz/arch/p/analysis/analysis_arm_cs.c +++ b/librz/arch/p/analysis/analysis_arm_cs.c @@ -93,8 +93,10 @@ static const char *shift_type_name(arm_shifter type) { return "lsr_reg"; case ARM_SFT_ROR_REG: return "ror_reg"; +#if CS_NEXT_VERSION < 6 case ARM_SFT_RRX_REG: return "rrx_reg"; +#endif default: return ""; } @@ -274,7 +276,9 @@ static void opex(RzStrBuf *buf, csh handle, cs_insn *insn) { case ARM_SFT_LSL_REG: case ARM_SFT_LSR_REG: case ARM_SFT_ROR_REG: +#if CS_NEXT_VERSION < 6 case ARM_SFT_RRX_REG: +#endif pj_ks(pj, "type", shift_type_name(op->shift.type)); pj_ks(pj, "value", cs_reg_name(handle, op->shift.value)); break; @@ -1944,7 +1948,7 @@ static void set_src_dst(RzAnalysisValue *val, RzReg *reg, csh *handle, cs_insn * break; case ARM_OP_MEM: val->type = RZ_ANALYSIS_VAL_MEM; - val->mul = armop.mem.scale << armop.mem.lshift; + val->mul = armop.mem.scale << armop.shift.value; #if CS_NEXT_VERSION >= 6 val->delta = MEMDISP(x); #else diff --git a/subprojects/capstone-next.wrap b/subprojects/capstone-next.wrap index 4bcb68ac2a2..246187157f1 100644 --- a/subprojects/capstone-next.wrap +++ b/subprojects/capstone-next.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://github.com/capstone-engine/capstone.git -revision = e9b9b649cd1ee368ff39ae284947470e694bf5b1 +revision = a34901e919157c4b0f52e3b93bd977023a97d6b7 directory = capstone-next patch_directory = capstone-next depth = 1 From 730556d06791354f8e46edb6dc12298b4deac6b7 Mon Sep 17 00:00:00 2001 From: wargio Date: Mon, 30 Sep 2024 10:00:59 +0200 Subject: [PATCH 09/13] Fix asm tests --- test/db/asm/mips.gnu_64 | 85 ----------------------- test/db/asm/mips_mips2_64 | 2 + test/db/asm/{mips_64 => mips_mips64v2_64} | 72 +++++++++---------- test/db/asm/mips_mips64v6_64 | 81 +++++++++++++++++++++ test/db/asm/mips_v2_64 | 2 - 5 files changed, 119 insertions(+), 123 deletions(-) delete mode 100644 test/db/asm/mips.gnu_64 create mode 100644 test/db/asm/mips_mips2_64 rename test/db/asm/{mips_64 => mips_mips64v2_64} (53%) create mode 100644 test/db/asm/mips_mips64v6_64 delete mode 100644 test/db/asm/mips_v2_64 diff --git a/test/db/asm/mips.gnu_64 b/test/db/asm/mips.gnu_64 deleted file mode 100644 index 07d2b61d39e..00000000000 --- a/test/db/asm/mips.gnu_64 +++ /dev/null @@ -1,85 +0,0 @@ -d "add.s $f0, $f0, $f0" 00000046 0x4 -d "addi zero, zero, 0" 00000020 0x4 -d "addiu zero, t0, -25" e7ff0025 0x4 -d "addiu zero, t0, 0" 00000025 0x4 -d "andi zero, zero, 0x0" 00000030 0x4 -d "b 0x00000008" 00000010 0x4 -d "bc0f 0x00000008" 00000041 0x4 -d "bc1f 0x00000008" 00000045 0x4 -d "bc2f 0x00000008" 00000049 0x4 -d "bc3f 0x00000008" 0000004d 0x4 -d "beq t0, s0, 0x0000444c" 11111011 0x4 -d "beql sp, t8, 0x00014008" 0050b853 0x4 -d "beqz t0, 0x00000008" 00000011 0x4 -d "beqzl zero, 0x00000008" 00000050 0x4 -d "bgez v0, 0x00000010" 02004104 0x4 -d "bgezal s1, 0x00000108" 40003106 0x4 -d "bgezall t3, 0x00000128" 48007305 0x4 -d "bgezl t6, 0x00000128" 4800c305 0x4 -d "bgtz zero, 0x00000008" 0000001c 0x4 -d "bgtzl zero, 0x00000008" 0000005c 0x4 -d "blez zero, 0x00000008" 00000018 0x4 -d "blezl zero, 0x00000008" 00000058 0x4 -d "bltz zero, 0x00000008" 00000004 0x4 -d "bltzl s6, 0x00000118" 4400c206 0x4 -d "bne t0, s0, 0x0000440c" 01111015 0x4 -d "bnel s0, s0, 0xffffffffffff4008" 00d01056 0x4 -d "bnez zero, 0x00000008" 00000014 0x4 -d "bnezl t0, 0x00000008" 00000055 0x4 -d "c0 0x0" 00000042 0x4 -d "c1 0x1000000" 00000047 0x4 -d "c2 0x0" 0000004a 0x4 -d "c3 0x0" 0000004e 0x4 -d "cache 0x0, 0(zero)" 000000bc 0x4 -d "daddi zero, zero, 0" 00000060 0x4 -d "daddiu zero, zero, 0" 00000064 0x4 -d "j 0x00000000" 00000008 0x4 -d "jal 0x00000000" 0000000c 0x4 -d "jalx 0x00000000" 00000074 0x4 -d "jalx 0x00000004" 01000074 0x4 -d "lb zero, 0(zero)" 00000080 0x4 -d "lbu zero, 0(zero)" 00000090 0x4 -d "ld zero, 0(zero)" 000000dc 0x4 -d "ldc1 $f0, 0(zero)" 000000d4 0x4 -d "ldc2 $0, 0(zero)" 000000d8 0x4 -d "ldl zero, 0(zero)" 00000068 0x4 -d "ldr zero, 0(zero)" 0000006c 0x4 -d "lh zero, 0(zero)" 00000084 0x4 -d "lhu zero, 0(zero)" 00000094 0x4 -d "li zero, 0" 00000024 0x4 -d "li zero, 0x0" 00000034 0x4 -d "ll zero, 0(zero)" 000000c0 0x4 -d "lld zero, 0(zero)" 000000d0 0x4 -d "lui zero, 0x0" 0000003c 0x4 -d "lw zero, 0(zero)" 0000008c 0x4 -d "lwc1 $f0, 0(zero)" 000000c4 0x4 -d "lwc2 $0, 0(zero)" 000000c8 0x4 -d "lwc3 $0, 0(zero)" 000000cc 0x4 -d "lwl zero, 0(zero)" 00000088 0x4 -d "lwr zero, 0(zero)" 00000098 0x4 -d "lwu zero, 0(zero)" 0000009c 0x4 -d "mfc0 zero, $0" 00000040 0x4 -d "mfc1 zero, $f0" 00000044 0x4 -d "mfc2 zero, $0" 00000048 0x4 -d "mfc3 zero, $0" 0000004c 0x4 -d "nop" 00000000 0x4 -d "ori zero, t0, 0x0" 00000035 0x4 -d "paddsh $f0, $f0, $f0" 0000004b 0x4 -d "sb zero, 0(zero)" 000000a0 0x4 -d "sc zero, 0(zero)" 000000e0 0x4 -d "scd zero, 0(zero)" 000000f0 0x4 -d "sd zero, 0(zero)" 000000fc 0x4 -d "sdc1 $f0, 0(zero)" 000000f4 0x4 -d "sdc2 $0, 0(zero)" 000000f8 0x4 -d "sdl zero, 0(zero)" 000000b0 0x4 -d "sdr zero, 0(zero)" 000000b4 0x4 -d "sh zero, 0(zero)" 000000a4 0x4 -d "slti zero, zero, 0" 00000028 0x4 -d "sltiu zero, zero, 0" 0000002c 0x4 -d "sw zero, 0(zero)" 000000ac 0x4 -d "swc1 $f0, 0(zero)" 000000e4 0x4 -d "swc2 $0, 0(zero)" 000000e8 0x4 -d "swc3 $0, 0(zero)" 000000ec 0x4 -d "swl zero, 0(zero)" 000000a8 0x4 -d "swr zero, 0(zero)" 000000b8 0x4 -d "xori zero, zero, 0x0" 00000038 0x4 \ No newline at end of file diff --git a/test/db/asm/mips_mips2_64 b/test/db/asm/mips_mips2_64 new file mode 100644 index 00000000000..96e6c8d9efd --- /dev/null +++ b/test/db/asm/mips_mips2_64 @@ -0,0 +1,2 @@ +d "lwc3 0, 0(zero)" 000000cc +d "swc3 0, 0(zero)" 000000ec \ No newline at end of file diff --git a/test/db/asm/mips_64 b/test/db/asm/mips_mips64v2_64 similarity index 53% rename from test/db/asm/mips_64 rename to test/db/asm/mips_mips64v2_64 index bd17db26021..3b25790bb29 100644 --- a/test/db/asm/mips_64 +++ b/test/db/asm/mips_mips64v2_64 @@ -4,10 +4,10 @@ d "addiu zero, t0, -0x19" e7ff0025 0x4 d "addiu zero, t0, 0" 00000025 0x4 d "andi zero, zero, 0" 00000030 0x4 d "b 8" 00000010 0x4 -d "bc0f 8" 00000041 0x4 +d "mftr zero, zero, 0, 0, 0" 00000041 0x4 d "bc1f 8" 00000045 0x4 -d "bc2f 8" 00000049 0x4 -d "bc3f 8" 0000004d 0x4 +dB "bc2f 8" 00000049 0x4 +d "lwxc1 f0, zero(t0)" 0000004d 0x4 d "beq t0, s0, 0x444c" 11111011 0x4 d "beql sp, t8, 0x14008" 0050b853 0x4 d "beqz t0, 8" 00000011 0x4 @@ -24,48 +24,48 @@ d "bltzl s6, 0x118" 4400c206 0x4 d "bne t0, s0, 0x440c" 01111015 0x4 d "bnel s0, s0, -0xbff8" 00d01056 0x4 d "bnez zero, 8" 00000014 0x4 -d "cache 0, (zero)" 000000bc 0x4 +d "cache 0, 0(zero)" 000000bc 0x4 d "daddi zero, zero, 0" 00000060 0x4 d "daddiu zero, zero, 0" 00000064 0x4 d "j 0" 00000008 0x4 d "jal 0" 0000000c 0x4 d "jalx 0" 00000074 0x4 d "jalx 4" 01000074 0x4 -d "lb zero, (zero)" 00000080 0x4 -d "lbu zero, (zero)" 00000090 0x4 -d "ldc1 f0, (zero)" 000000d4 0x4 -d "ldl zero, (zero)" 00000068 0x4 -d "ldr zero, (zero)" 0000006c 0x4 -d "lh zero, (zero)" 00000084 0x4 -d "lhu zero, (zero)" 00000094 0x4 -d "ll zero, (zero)" 000000c0 0x4 -d "lld zero, (zero)" 000000d0 0x4 +d "lb zero, 0(zero)" 00000080 0x4 +d "lbu zero, 0(zero)" 00000090 0x4 +d "ldc1 f0, 0(zero)" 000000d4 0x4 +d "ldl zero, 0(zero)" 00000068 0x4 +d "ldr zero, 0(zero)" 0000006c 0x4 +d "lh zero, 0(zero)" 00000084 0x4 +d "lhu zero, 0(zero)" 00000094 0x4 +d "ll zero, 0(zero)" 000000c0 0x4 +d "lld zero, 0(zero)" 000000d0 0x4 d "lui zero, 0" 0000003c 0x4 -d "lw zero, (zero)" 0000008c 0x4 -d "lwc1 f0, (zero)" 000000c4 0x4 -d "lwl zero, (zero)" 00000088 0x4 -d "lwr zero, (zero)" 00000098 0x4 -d "lwu zero, (zero)" 0000009c 0x4 +d "lw zero, 0(zero)" 0000008c 0x4 +d "lwc1 f0, 0(zero)" 000000c4 0x4 +d "lwl zero, 0(zero)" 00000088 0x4 +d "lwr zero, 0(zero)" 00000098 0x4 +d "lwu zero, 0(zero)" 0000009c 0x4 d "lwxc1 f0, zero(zero)" 0000004c 0x4 -d "mfc0 zero, zero, 0" 00000040 0x4 +d "mfc0 zero, 0, 0" 00000040 0x4 d "mfc1 zero, f0" 00000044 0x4 -d "mfc2 zero, zero, 0" 00000048 0x4 +d "mfc2 zero, 0, 0" 00000048 0x4 d "nop" 00000000 0x4 d "ori zero, t0, 0" 00000035 0x4 -d "sb zero, (zero)" 000000a0 0x4 -d "sc zero, (zero)" 000000e0 0x4 -d "scd zero, (zero)" 000000f0 0x4 -d "sd zero, (zero)" 000000fc 0x4 -d "sdc1 f0, (zero)" 000000f4 0x4 -d "sdl zero, (zero)" 000000b0 0x4 -d "sdr zero, (zero)" 000000b4 0x4 -d "sh zero, (zero)" 000000a4 0x4 +d "sb zero, 0(zero)" 000000a0 0x4 +d "sc zero, (0)" 000000e0 0x4 +d "scd zero, 0(zero)" 000000f0 0x4 +d "sd zero, 0(zero)" 000000fc 0x4 +d "sdc1 f0, 0(zero)" 000000f4 0x4 +d "sdl zero, 0(zero)" 000000b0 0x4 +d "sdr zero, 0(zero)" 000000b4 0x4 +d "sh zero, 0(zero)" 000000a4 0x4 d "slti zero, zero, 0" 00000028 0x4 d "sltiu zero, zero, 0" 0000002c 0x4 -d "sw zero, (zero)" 000000ac 0x4 -d "swc1 f0, (zero)" 000000e4 0x4 -d "swl zero, (zero)" 000000a8 0x4 -d "swr zero, (zero)" 000000b8 0x4 +d "sw zero, 0(zero)" 000000ac 0x4 +d "swc1 f0, 0(zero)" 000000e4 0x4 +d "swl zero, 0(zero)" 000000a8 0x4 +d "swr zero, 0(zero)" 000000b8 0x4 d "xori zero, zero, 0" 00000038 0x4 dB "beqzl zero, 8" 00000050 0x4 dB "bnezl t0, 8" 00000055 0x4 @@ -73,8 +73,8 @@ dB "c0 0x0" 00000042 0x4 dB "c1 0x1000000" 00000047 0x4 dB "c2 0x0" 0000004a 0x4 dB "ld zero, 0(zero)" 000000dc 0x4 -dB "ldc2 0, (zero)" 000000d8 0x4 -dB "lwc2 0, (zero)" 000000c8 0x4 +dB "ldc2 0, 0(zero)" 000000d8 0x4 +dB "lwc2 0, 0(zero)" 000000c8 0x4 dB "paddsh f0, f0, f0" 0000004b 0x4 -dB "sdc2 0, (zero)" 000000f8 0x4 -dB "swc2 0, (zero)" 000000e8 0x4 \ No newline at end of file +dB "sdc2 0, 0(zero)" 000000f8 0x4 +dB "swc2 0, 0(zero)" 000000e8 0x4 \ No newline at end of file diff --git a/test/db/asm/mips_mips64v6_64 b/test/db/asm/mips_mips64v6_64 new file mode 100644 index 00000000000..4c28cda68d2 --- /dev/null +++ b/test/db/asm/mips_mips64v6_64 @@ -0,0 +1,81 @@ +d "add.s f0, f0, f0" 00000046 0x4 +d "addi zero, zero, 0" 00000020 0x4 +d "addiu zero, t0, -0x19" e7ff0025 0x4 +d "addiu zero, t0, 0" 00000025 0x4 +d "andi zero, zero, 0" 00000030 0x4 +d "b 8" 00000010 0x4 +d "mftr zero, zero, 0, 0, 0" 00000041 0x4 +d "bc1f 8" 00000045 0x4 +dB "bc2f 8" 00000049 0x4 +d "lwxc1 f0, zero(t0)" 0000004d 0x4 +d "beq t0, s0, 0x444c" 11111011 0x4 +d "beql sp, t8, 0x14008" 0050b853 0x4 +d "beqz t0, 8" 00000011 0x4 +d "beqzl zero, 8" 00000050 0x4 +d "bgez v0, 0x10" 02004104 0x4 +d "bgezal s1, 0x108" 40003106 0x4 +d "bgezall t3, 0x128" 48007305 0x4 +d "bgezl t6, 0x128" 4800c305 0x4 +d "bgtz zero, 8" 0000001c 0x4 +d "bgtzl zero, 8" 0000005c 0x4 +d "blez zero, 8" 00000018 0x4 +d "blezl zero, 8" 00000058 0x4 +d "bltz zero, 8" 00000004 0x4 +d "bltzl s6, 0x118" 4400c206 0x4 +d "bne t0, s0, 0x440c" 01111015 0x4 +d "bnel s0, s0, -0xbff8" 00d01056 0x4 +d "bnez zero, 8" 00000014 0x4 +d "bnezl t0, 8" 00000055 0x4 +dB "c0 0" 00000042 0x4 +dB "c1 0x1000000" 00000047 0x4 +dB "c2 0" 0000004a 0x4 +dB "c3 0" 0000004e 0x4 +d "cache 0, 0(zero)" 000000bc 0x4 +d "daddi zero, zero, 0" 00000060 0x4 +d "daddiu zero, zero, 0" 00000064 0x4 +d "j 0" 00000008 0x4 +d "jal 0" 0000000c 0x4 +d "jalx 0" 00000074 0x4 +d "jalx 4" 01000074 0x4 +d "lb zero, 0(zero)" 00000080 0x4 +d "lbu zero, 0(zero)" 00000090 0x4 +d "ld zero, 0(zero)" 000000dc 0x4 +d "ldc1 f0, 0(zero)" 000000d4 0x4 +d "ldc2 0, 0(zero)" 000000d8 0x4 +d "ldl zero, 0(zero)" 00000068 0x4 +d "ldr zero, 0(zero)" 0000006c 0x4 +d "lh zero, 0(zero)" 00000084 0x4 +d "lhu zero, 0(zero)" 00000094 0x4 +d "addiu zero, zero, 0" 00000024 0x4 +d "ori zero, zero, 0" 00000034 0x4 +d "ll zero, 0(zero)" 000000c0 0x4 +d "lld zero, 0(zero)" 000000d0 0x4 +d "lui zero, 0" 0000003c 0x4 +d "lw zero, 0(zero)" 0000008c 0x4 +d "lwc1 f0, 0(zero)" 000000c4 0x4 +d "lwc2 0, 0(zero)" 000000c8 0x4 +d "pref 0, 0(zero)" 000000cc 0x4 +d "lwl zero, 0(zero)" 00000088 0x4 +d "lwr zero, 0(zero)" 00000098 0x4 +d "lwu zero, 0(zero)" 0000009c 0x4 +d "mfc0 zero, 0, 0" 00000040 0x4 +d "mfc1 zero, f0" 00000044 0x4 +d "mfc2 zero, 0, 0" 00000048 0x4 +d "lwxc1 f0, zero(zero)" 0000004c 0x4 +d "nop" 00000000 0x4 +d "ori zero, t0, 0" 00000035 0x4 +d "sb zero, 0(zero)" 000000a0 0x4 +d "sc zero, (0)" 000000e0 0x4 +d "scd zero, 0(zero)" 000000f0 0x4 +d "sd zero, 0(zero)" 000000fc 0x4 +d "sdc1 f0, 0(zero)" 000000f4 0x4 +d "sdc2 0, 0(zero)" 000000f8 0x4 +d "sdl zero, 0(zero)" 000000b0 0x4 +d "sdr zero, 0(zero)" 000000b4 0x4 +d "sh zero, 0(zero)" 000000a4 0x4 +d "slti zero, zero, 0" 00000028 0x4 +d "sltiu zero, zero, 0" 0000002c 0x4 +d "sw zero, 0(zero)" 000000ac 0x4 +d "swl zero, 0(zero)" 000000a8 0x4 +d "swr zero, 0(zero)" 000000b8 0x4 +d "xori zero, zero, 0" 00000038 0x4 \ No newline at end of file diff --git a/test/db/asm/mips_v2_64 b/test/db/asm/mips_v2_64 deleted file mode 100644 index b274fc9d2e2..00000000000 --- a/test/db/asm/mips_v2_64 +++ /dev/null @@ -1,2 +0,0 @@ -d "lwc3 0, (zero)" 000000cc -d "swc3 0, (zero)" 000000ec \ No newline at end of file From 4ba4538e663b24e22e6cafd8ef8f5cc21f5cb0a5 Mon Sep 17 00:00:00 2001 From: wargio Date: Mon, 30 Sep 2024 12:05:55 +0200 Subject: [PATCH 10/13] Small cleanup and upgrade of capstone --- librz/arch/p/asm/asm_mips.c | 3 +- librz/core/cbin.c | 3 +- librz/core/cconfig.c | 32 +++++++++++-------- subprojects/capstone-next.wrap | 2 +- .../packagefiles/capstone-next/meson.build | 7 ++-- 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/librz/arch/p/asm/asm_mips.c b/librz/arch/p/asm/asm_mips.c index 30596524a6a..fc5b74d0e13 100644 --- a/librz/arch/p/asm/asm_mips.c +++ b/librz/arch/p/asm/asm_mips.c @@ -4,9 +4,8 @@ #include #include #include -#include "capstone.h" +#include #include "cs_helper.h" -#include "rz_util/rz_log.h" CAPSTONE_DEFINE_PLUGIN_FUNCTIONS(mips_asm); diff --git a/librz/core/cbin.c b/librz/core/cbin.c index 41f3d2b98e8..d83494b38b1 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -13,7 +13,6 @@ #include "../bin/dwarf/dwarf_private.h" #include "core_private.h" -#include "rz_util/rz_str.h" #define is_invalid_address_va(va, vaddr, paddr) (((va) && (vaddr) == UT64_MAX) || (!(va) && (paddr) == UT64_MAX)) #define is_invalid_address_va2(va, vaddr, paddr) (((va) != VA_FALSE && (vaddr) == UT64_MAX) || ((va) == VA_FALSE && (paddr) == UT64_MAX)) @@ -304,7 +303,7 @@ RZ_API bool rz_core_bin_apply_all_info(RzCore *r, RzBinFile *binfile) { rz_config_set(r->config, "asm.arch", arch); rz_config_set_i(r->config, "asm.bits", bits); rz_config_set(r->config, "analysis.arch", arch); - if (info->cpu && *info->cpu) { + if (RZ_STR_ISNOTEMPTY(info->cpu)) { rz_config_set(r->config, "analysis.cpu", info->cpu); } else { rz_config_set(r->config, "analysis.cpu", arch); diff --git a/librz/core/cconfig.c b/librz/core/cconfig.c index 6a2ce2edc0e..1e0952e2ff9 100644 --- a/librz/core/cconfig.c +++ b/librz/core/cconfig.c @@ -382,7 +382,7 @@ static void update_asmcpu_options(RzCore *core, RzConfigNode *node) { RzListIter *iter; rz_return_if_fail(core && core->rasm); const char *arch = rz_config_get(core->config, "asm.arch"); - if (!arch || !*arch) { + if (RZ_STR_ISEMPTY(arch)) { return; } rz_list_purge(node->options); @@ -402,7 +402,7 @@ static void update_asmcpu_options(RzCore *core, RzConfigNode *node) { } } -static bool cb_asmcpu(void *user, void *data) { +static bool cb_asm_cpu(void *user, void *data) { RzCore *core = (RzCore *)user; RzConfigNode *node = (RzConfigNode *)data; if (*node->value == '?') { @@ -475,15 +475,15 @@ static bool cb_asm_varfold(void *core, void *node) { return false; } -static void handle_cpu_feature(RzConfig *config, const char *supported, const char *cpu) { +static void handle_supported_cpus(RzConfig *config, const char *supported, const char *cpu) { // strdup is required when calling rz_config_set, because it will free the old value char *cpu_copy = rz_str_dup(cpu); // we need to duplicate supported because rz_str_split_list will modify the string. char *supported_copy = rz_str_dup(supported); RzList *cpu_list = rz_str_split_list(supported_copy, ",", 0); - RzListIter *it; - const char *lcpu; + RzListIter *it = NULL; + const char *lcpu = NULL; rz_list_foreach (cpu_list, it, lcpu) { if (!strcmp(lcpu, cpu_copy)) { rz_config_set(config, "asm.cpu", cpu_copy); @@ -491,12 +491,16 @@ static void handle_cpu_feature(RzConfig *config, const char *supported, const ch } } + if (lcpu && strcmp(lcpu, cpu_copy) != 0) { + RZ_LOG_ERROR("asm.cpu: unknown cpu: %s\n", cpu_copy) + } + rz_list_free(cpu_list); free(supported_copy); free(cpu_copy); } -static bool cb_asmarch(void *user, void *data) { +static bool cb_asm_arch(void *user, void *data) { char asmparser[32]; RzCore *core = (RzCore *)user; RzConfigNode *node = (RzConfigNode *)data; @@ -535,7 +539,7 @@ static bool cb_asmarch(void *user, void *data) { const char *cpus_supported = core->rasm->cur->cpus; if (RZ_STR_ISNOTEMPTY(cpus_supported) && RZ_STR_ISNOTEMPTY(asm_cpu)) { - handle_cpu_feature(core->config, cpus_supported, asm_cpu); + handle_supported_cpus(core->config, cpus_supported, asm_cpu); } else { rz_config_set(core->config, "asm.cpu", ""); } @@ -644,7 +648,7 @@ static bool cb_dbgbtdepth(void *user, void *data) { return true; } -static bool cb_asmbits(void *user, void *data) { +static bool cb_asm_bits(void *user, void *data) { RzCore *core = (RzCore *)user; RzConfigNode *node = (RzConfigNode *)data; @@ -727,7 +731,7 @@ static bool cb_flag_realnames(void *user, void *data) { return true; } -static bool cb_asmfeatures(void *user, void *data) { +static bool cb_asm_features(void *user, void *data) { RzCore *core = (RzCore *)user; RzConfigNode *node = (RzConfigNode *)data; if (*node->value == '?') { @@ -3244,14 +3248,14 @@ RZ_API int rz_core_config_init(RzCore *core) { SETI("asm.symbol.col", 40, "Columns width to show asm.section"); SETCB("asm.assembler", "", &cb_asmassembler, "Set the plugin name to use when assembling"); SETBPREF("asm.minicols", "false", "Only show the instruction in the column disasm"); - RzConfigNode *asmcpu = NODECB("asm.cpu", RZ_SYS_ARCH, &cb_asmcpu); + RzConfigNode *asmcpu = NODECB("asm.cpu", "", &cb_asm_cpu); SETDESC(asmcpu, "Set the kind of asm.arch cpu"); - RzConfigNode *asmarch = NODECB("asm.arch", RZ_SYS_ARCH, &cb_asmarch); + RzConfigNode *asmarch = NODECB("asm.arch", RZ_SYS_ARCH, &cb_asm_arch); SETDESC(asmarch, "Set the arch to be used by asm"); /* we need to have both asm.arch and asm.cpu defined before updating options */ update_asmarch_options(core, asmarch); update_asmcpu_options(core, asmcpu); - n = NODECB("asm.features", "", &cb_asmfeatures); + n = NODECB("asm.features", "", &cb_asm_features); SETDESC(n, "Specify supported features by the target CPU"); update_asmfeatures_options(core, n); n = NODECB("asm.platform", "", &cb_asmplatform); @@ -3269,9 +3273,9 @@ RZ_API int rz_core_config_init(RzCore *core) { SETI("asm.nbytes", 6, "Number of bytes for each opcode at disassembly"); SETBPREF("asm.bytes.space", "false", "Separate hexadecimal bytes with a whitespace"); #if RZ_SYS_BITS == RZ_SYS_BITS_64 - SETICB("asm.bits", 64, &cb_asmbits, "Word size in bits at assembler"); + SETICB("asm.bits", 64, &cb_asm_bits, "Word size in bits at assembler"); #else - SETICB("asm.bits", 32, &cb_asmbits, "Word size in bits at assembler"); + SETICB("asm.bits", 32, &cb_asm_bits, "Word size in bits at assembler"); #endif n = rz_config_node_get(cfg, "asm.bits"); update_asmbits_options(core, n); diff --git a/subprojects/capstone-next.wrap b/subprojects/capstone-next.wrap index 246187157f1..1df2e624aea 100644 --- a/subprojects/capstone-next.wrap +++ b/subprojects/capstone-next.wrap @@ -1,6 +1,6 @@ [wrap-git] url = https://github.com/capstone-engine/capstone.git -revision = a34901e919157c4b0f52e3b93bd977023a97d6b7 +revision = 21f7bc85f9026ece8adc34d02b6e23863f6185ae directory = capstone-next patch_directory = capstone-next depth = 1 diff --git a/subprojects/packagefiles/capstone-next/meson.build b/subprojects/packagefiles/capstone-next/meson.build index 8fbd1488a85..d92f1ab6f3a 100644 --- a/subprojects/packagefiles/capstone-next/meson.build +++ b/subprojects/packagefiles/capstone-next/meson.build @@ -39,11 +39,12 @@ cs_files = [ 'arch/Sparc/SparcInstPrinter.c', 'arch/Sparc/SparcMapping.c', 'arch/Sparc/SparcModule.c', - 'arch/SystemZ/SystemZDisassembler.c', 'arch/SystemZ/SystemZInstPrinter.c', + 'arch/SystemZ/SystemZModule.c', 'arch/SystemZ/SystemZMapping.c', + 'arch/SystemZ/SystemZDisassemblerExtension.c', 'arch/SystemZ/SystemZMCTargetDesc.c', - 'arch/SystemZ/SystemZModule.c', + 'arch/SystemZ/SystemZDisassembler.c', 'arch/TMS320C64x/TMS320C64xDisassembler.c', 'arch/TMS320C64x/TMS320C64xInstPrinter.c', 'arch/TMS320C64x/TMS320C64xMapping.c', @@ -89,7 +90,7 @@ libcapstone_c_args = [ '-DCAPSTONE_HAS_MIPS', '-DCAPSTONE_HAS_POWERPC', '-DCAPSTONE_HAS_SPARC', - '-DCAPSTONE_HAS_SYSZ', + '-DCAPSTONE_HAS_SYSTEMZ', '-DCAPSTONE_HAS_X86', '-DCAPSTONE_HAS_XCORE', '-DCAPSTONE_HAS_TMS320C64X', From f3a8f33ae30ec2492e7019c622826008487b0034 Mon Sep 17 00:00:00 2001 From: wargio Date: Mon, 30 Sep 2024 12:06:12 +0200 Subject: [PATCH 11/13] Fix luac since it using cpu but doesn't define them --- librz/arch/p/analysis/analysis_luac.c | 4 ++-- librz/arch/p/asm/asm_luac.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/librz/arch/p/analysis/analysis_luac.c b/librz/arch/p/analysis/analysis_luac.c index aa78250a29d..e8d8ca75789 100644 --- a/librz/arch/p/analysis/analysis_luac.c +++ b/librz/arch/p/analysis/analysis_luac.c @@ -11,9 +11,9 @@ int rz_lua_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const RZ_LOG_ERROR("Cannot get lua version\n"); return 0; } - if (strcmp(analysis->cpu, "5.4") == 0) { + if (!strcmp(analysis->cpu, "5.4")) { return lua54_anal_op(analysis, op, addr, data, len); - } else if (strcmp(analysis->cpu, "5.3") == 0) { + } else if (!strcmp(analysis->cpu, "5.3")) { return lua53_anal_op(analysis, op, addr, data, len); } else { RZ_LOG_ERROR("Cannot find a suitable lua version to handle lua analysis\n"); diff --git a/librz/arch/p/asm/asm_luac.c b/librz/arch/p/asm/asm_luac.c index 30021525f76..bf2fa8b3277 100644 --- a/librz/arch/p/asm/asm_luac.c +++ b/librz/arch/p/asm/asm_luac.c @@ -60,6 +60,7 @@ RzAsmPlugin rz_asm_plugin_luac = { .name = "luac", .arch = "luac", .license = "LGPL3", + .cpus = "5.3,5.4", .bits = 8, .desc = "luac disassemble plugin", .disassemble = &rz_luac_disasm, From 335f7b5fe2cd015dcb4cd1104fb688c22bf07d87 Mon Sep 17 00:00:00 2001 From: wargio Date: Mon, 30 Sep 2024 12:06:32 +0200 Subject: [PATCH 12/13] Add sysz cpus even if they are not used yet --- librz/arch/p/asm/asm_sysz.c | 1 + 1 file changed, 1 insertion(+) diff --git a/librz/arch/p/asm/asm_sysz.c b/librz/arch/p/asm/asm_sysz.c index 4e74975b95e..1f299343470 100644 --- a/librz/arch/p/asm/asm_sysz.c +++ b/librz/arch/p/asm/asm_sysz.c @@ -65,6 +65,7 @@ RzAsmPlugin rz_asm_plugin_sysz = { .desc = "SystemZ CPU disassembler", .license = "BSD", .arch = "sysz", + .cpus = "z10,z196,zec12,z13,z14,z15,z16", .bits = 32 | 64, .endian = RZ_SYS_ENDIAN_BIG, .init = sysz_init, From bcfe896039a0df0f5dfbc2a4d9b9455d77f4b1ef Mon Sep 17 00:00:00 2001 From: wargio Date: Mon, 30 Sep 2024 12:06:43 +0200 Subject: [PATCH 13/13] Fix tests --- test/db/analysis/java | 1 + test/db/analysis/rl78 | 1 + test/db/analysis/rx | 1 + test/db/analysis/sysz | 5 ++--- test/db/cmd/cmd_i | 7 +++++++ test/db/formats/dmp/dmp | 1 + test/db/formats/dyldcache | 5 +++++ test/db/formats/elf/elf-riscv64 | 1 + test/db/formats/elf/m68k | 2 +- test/db/formats/elf/mips | 22 ++++++++++++++++++---- test/db/formats/elf/v850 | 1 + test/db/formats/mdmp | 1 + test/db/formats/n3ds | 1 + test/db/formats/ninds | 1 + test/db/formats/pe/arm | 1 + test/db/formats/prg | 1 + test/db/formats/smd | 1 + test/db/io/srec | 1 + test/db/tools/rz_bin | 4 ++++ 19 files changed, 50 insertions(+), 8 deletions(-) diff --git a/test/db/analysis/java b/test/db/analysis/java index e704617eb86..68dc9ca2591 100644 --- a/test/db/analysis/java +++ b/test/db/analysis/java @@ -194,6 +194,7 @@ block 0x100 type JAVA CLASS arch java cpu N/A +features N/A baddr 0x00000000 binsz 0x00000400 bintype class diff --git a/test/db/analysis/rl78 b/test/db/analysis/rl78 index ca21754b481..5880caa8e1d 100644 --- a/test/db/analysis/rl78 +++ b/test/db/analysis/rl78 @@ -14,6 +14,7 @@ EXPECT=<