Home | History | Annotate | Line # | Download | only in opcodes
mips-dis.c revision 1.5
      1  1.1     skrll /* Print mips instructions for GDB, the GNU debugger, or for objdump.
      2  1.5  christos    Copyright (C) 1989-2015 Free Software Foundation, Inc.
      3  1.1     skrll    Contributed by Nobuyuki Hikichi(hikichi (at) sra.co.jp).
      4  1.1     skrll 
      5  1.1     skrll    This file is part of the GNU opcodes library.
      6  1.1     skrll 
      7  1.1     skrll    This library is free software; you can redistribute it and/or modify
      8  1.1     skrll    it under the terms of the GNU General Public License as published by
      9  1.1     skrll    the Free Software Foundation; either version 3, or (at your option)
     10  1.1     skrll    any later version.
     11  1.1     skrll 
     12  1.1     skrll    It is distributed in the hope that it will be useful, but WITHOUT
     13  1.1     skrll    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     14  1.1     skrll    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
     15  1.1     skrll    License for more details.
     16  1.1     skrll 
     17  1.1     skrll    You should have received a copy of the GNU General Public License
     18  1.1     skrll    along with this program; if not, write to the Free Software
     19  1.1     skrll    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     20  1.1     skrll    MA 02110-1301, USA.  */
     21  1.1     skrll 
     22  1.1     skrll #include "sysdep.h"
     23  1.1     skrll #include "dis-asm.h"
     24  1.1     skrll #include "libiberty.h"
     25  1.1     skrll #include "opcode/mips.h"
     26  1.1     skrll #include "opintl.h"
     27  1.1     skrll 
     28  1.1     skrll /* FIXME: These are needed to figure out if the code is mips16 or
     29  1.1     skrll    not. The low bit of the address is often a good indicator.  No
     30  1.1     skrll    symbol table is available when this code runs out in an embedded
     31  1.1     skrll    system as when it is used for disassembler support in a monitor.  */
     32  1.1     skrll 
     33  1.1     skrll #if !defined(EMBEDDED_ENV)
     34  1.1     skrll #define SYMTAB_AVAILABLE 1
     35  1.1     skrll #include "elf-bfd.h"
     36  1.1     skrll #include "elf/mips.h"
     37  1.1     skrll #endif
     38  1.1     skrll 
     39  1.1     skrll /* Mips instructions are at maximum this many bytes long.  */
     40  1.1     skrll #define INSNLEN 4
     41  1.1     skrll 
     42  1.1     skrll 
     43  1.1     skrll /* FIXME: These should be shared with gdb somehow.  */
     45  1.1     skrll 
     46  1.1     skrll struct mips_cp0sel_name
     47  1.1     skrll {
     48  1.1     skrll   unsigned int cp0reg;
     49  1.1     skrll   unsigned int sel;
     50  1.1     skrll   const char * const name;
     51  1.1     skrll };
     52  1.1     skrll 
     53  1.1     skrll static const char * const mips_gpr_names_numeric[32] =
     54  1.1     skrll {
     55  1.1     skrll   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
     56  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
     57  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
     58  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
     59  1.1     skrll };
     60  1.1     skrll 
     61  1.1     skrll static const char * const mips_gpr_names_oldabi[32] =
     62  1.1     skrll {
     63  1.1     skrll   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
     64  1.1     skrll   "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
     65  1.1     skrll   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
     66  1.1     skrll   "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
     67  1.1     skrll };
     68  1.1     skrll 
     69  1.1     skrll static const char * const mips_gpr_names_newabi[32] =
     70  1.1     skrll {
     71  1.1     skrll   "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
     72  1.1     skrll   "a4",   "a5",   "a6",   "a7",   "t0",   "t1",   "t2",   "t3",
     73  1.1     skrll   "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
     74  1.1     skrll   "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
     75  1.1     skrll };
     76  1.1     skrll 
     77  1.1     skrll static const char * const mips_fpr_names_numeric[32] =
     78  1.1     skrll {
     79  1.1     skrll   "$f0",  "$f1",  "$f2",  "$f3",  "$f4",  "$f5",  "$f6",  "$f7",
     80  1.1     skrll   "$f8",  "$f9",  "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
     81  1.1     skrll   "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
     82  1.1     skrll   "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
     83  1.1     skrll };
     84  1.1     skrll 
     85  1.1     skrll static const char * const mips_fpr_names_32[32] =
     86  1.1     skrll {
     87  1.1     skrll   "fv0",  "fv0f", "fv1",  "fv1f", "ft0",  "ft0f", "ft1",  "ft1f",
     88  1.1     skrll   "ft2",  "ft2f", "ft3",  "ft3f", "fa0",  "fa0f", "fa1",  "fa1f",
     89  1.1     skrll   "ft4",  "ft4f", "ft5",  "ft5f", "fs0",  "fs0f", "fs1",  "fs1f",
     90  1.1     skrll   "fs2",  "fs2f", "fs3",  "fs3f", "fs4",  "fs4f", "fs5",  "fs5f"
     91  1.1     skrll };
     92  1.1     skrll 
     93  1.1     skrll static const char * const mips_fpr_names_n32[32] =
     94  1.1     skrll {
     95  1.1     skrll   "fv0",  "ft14", "fv1",  "ft15", "ft0",  "ft1",  "ft2",  "ft3",
     96  1.1     skrll   "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
     97  1.1     skrll   "fa4",  "fa5",  "fa6",  "fa7",  "fs0",  "ft8",  "fs1",  "ft9",
     98  1.1     skrll   "fs2",  "ft10", "fs3",  "ft11", "fs4",  "ft12", "fs5",  "ft13"
     99  1.1     skrll };
    100  1.1     skrll 
    101  1.1     skrll static const char * const mips_fpr_names_64[32] =
    102  1.1     skrll {
    103  1.1     skrll   "fv0",  "ft12", "fv1",  "ft13", "ft0",  "ft1",  "ft2",  "ft3",
    104  1.1     skrll   "ft4",  "ft5",  "ft6",  "ft7",  "fa0",  "fa1",  "fa2",  "fa3",
    105  1.1     skrll   "fa4",  "fa5",  "fa6",  "fa7",  "ft8",  "ft9",  "ft10", "ft11",
    106  1.1     skrll   "fs0",  "fs1",  "fs2",  "fs3",  "fs4",  "fs5",  "fs6",  "fs7"
    107  1.1     skrll };
    108  1.1     skrll 
    109  1.1     skrll static const char * const mips_cp0_names_numeric[32] =
    110  1.1     skrll {
    111  1.1     skrll   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
    112  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    113  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    114  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    115  1.1     skrll };
    116  1.5  christos 
    117  1.5  christos static const char * const mips_cp1_names_numeric[32] =
    118  1.5  christos {
    119  1.5  christos   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
    120  1.5  christos   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    121  1.5  christos   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    122  1.5  christos   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    123  1.5  christos };
    124  1.1     skrll 
    125  1.1     skrll static const char * const mips_cp0_names_r3000[32] =
    126  1.1     skrll {
    127  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo",   "$3",
    128  1.1     skrll   "c0_context",   "$5",           "$6",           "$7",
    129  1.1     skrll   "c0_badvaddr",  "$9",           "c0_entryhi",   "$11",
    130  1.1     skrll   "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
    131  1.1     skrll   "$16",          "$17",          "$18",          "$19",
    132  1.1     skrll   "$20",          "$21",          "$22",          "$23",
    133  1.1     skrll   "$24",          "$25",          "$26",          "$27",
    134  1.1     skrll   "$28",          "$29",          "$30",          "$31",
    135  1.1     skrll };
    136  1.1     skrll 
    137  1.1     skrll static const char * const mips_cp0_names_r4000[32] =
    138  1.1     skrll {
    139  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    140  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    141  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    142  1.1     skrll   "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
    143  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    144  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "$23",
    145  1.1     skrll   "$24",          "$25",          "c0_ecc",       "c0_cacheerr",
    146  1.1     skrll   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "$31",
    147  1.1     skrll };
    148  1.5  christos 
    149  1.5  christos static const char * const mips_cp0_names_r5900[32] =
    150  1.5  christos {
    151  1.5  christos   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    152  1.5  christos   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    153  1.5  christos   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    154  1.5  christos   "c0_sr",        "c0_cause",     "c0_epc",       "c0_prid",
    155  1.5  christos   "c0_config",    "$17",          "$18",          "$19",
    156  1.5  christos   "$20",          "$21",          "$22",          "c0_badpaddr",
    157  1.5  christos   "c0_depc",      "c0_perfcnt",   "$26",          "$27",
    158  1.5  christos   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "$31"
    159  1.5  christos };
    160  1.1     skrll 
    161  1.1     skrll static const char * const mips_cp0_names_mips3264[32] =
    162  1.1     skrll {
    163  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    164  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    165  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    166  1.1     skrll   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    167  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    168  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    169  1.1     skrll   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
    170  1.1     skrll   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
    171  1.1     skrll };
    172  1.5  christos 
    173  1.5  christos static const char * const mips_cp1_names_mips3264[32] =
    174  1.5  christos {
    175  1.5  christos   "c1_fir",       "c1_ufr",       "$2",           "$3",
    176  1.5  christos   "c1_unfr",      "$5",           "$6",           "$7",
    177  1.5  christos   "$8",           "$9",           "$10",          "$11",
    178  1.5  christos   "$12",          "$13",          "$14",          "$15",
    179  1.5  christos   "$16",          "$17",          "$18",          "$19",
    180  1.5  christos   "$20",          "$21",          "$22",          "$23",
    181  1.5  christos   "$24",          "c1_fccr",      "c1_fexr",      "$27",
    182  1.5  christos   "c1_fenr",      "$29",          "$30",          "c1_fcsr"
    183  1.5  christos };
    184  1.1     skrll 
    185  1.1     skrll static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
    186  1.1     skrll {
    187  1.1     skrll   { 16, 1, "c0_config1"		},
    188  1.1     skrll   { 16, 2, "c0_config2"		},
    189  1.1     skrll   { 16, 3, "c0_config3"		},
    190  1.1     skrll   { 18, 1, "c0_watchlo,1"	},
    191  1.1     skrll   { 18, 2, "c0_watchlo,2"	},
    192  1.1     skrll   { 18, 3, "c0_watchlo,3"	},
    193  1.1     skrll   { 18, 4, "c0_watchlo,4"	},
    194  1.1     skrll   { 18, 5, "c0_watchlo,5"	},
    195  1.1     skrll   { 18, 6, "c0_watchlo,6"	},
    196  1.1     skrll   { 18, 7, "c0_watchlo,7"	},
    197  1.1     skrll   { 19, 1, "c0_watchhi,1"	},
    198  1.1     skrll   { 19, 2, "c0_watchhi,2"	},
    199  1.1     skrll   { 19, 3, "c0_watchhi,3"	},
    200  1.1     skrll   { 19, 4, "c0_watchhi,4"	},
    201  1.1     skrll   { 19, 5, "c0_watchhi,5"	},
    202  1.1     skrll   { 19, 6, "c0_watchhi,6"	},
    203  1.1     skrll   { 19, 7, "c0_watchhi,7"	},
    204  1.1     skrll   { 25, 1, "c0_perfcnt,1"	},
    205  1.1     skrll   { 25, 2, "c0_perfcnt,2"	},
    206  1.1     skrll   { 25, 3, "c0_perfcnt,3"	},
    207  1.1     skrll   { 25, 4, "c0_perfcnt,4"	},
    208  1.1     skrll   { 25, 5, "c0_perfcnt,5"	},
    209  1.1     skrll   { 25, 6, "c0_perfcnt,6"	},
    210  1.1     skrll   { 25, 7, "c0_perfcnt,7"	},
    211  1.1     skrll   { 27, 1, "c0_cacheerr,1"	},
    212  1.1     skrll   { 27, 2, "c0_cacheerr,2"	},
    213  1.1     skrll   { 27, 3, "c0_cacheerr,3"	},
    214  1.1     skrll   { 28, 1, "c0_datalo"		},
    215  1.1     skrll   { 29, 1, "c0_datahi"		}
    216  1.1     skrll };
    217  1.1     skrll 
    218  1.1     skrll static const char * const mips_cp0_names_mips3264r2[32] =
    219  1.1     skrll {
    220  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    221  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "c0_hwrena",
    222  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    223  1.1     skrll   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    224  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    225  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    226  1.1     skrll   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr",
    227  1.1     skrll   "c0_taglo",     "c0_taghi",     "c0_errorepc",  "c0_desave",
    228  1.1     skrll };
    229  1.1     skrll 
    230  1.1     skrll static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
    231  1.1     skrll {
    232  1.1     skrll   {  4, 1, "c0_contextconfig"	},
    233  1.1     skrll   {  0, 1, "c0_mvpcontrol"	},
    234  1.1     skrll   {  0, 2, "c0_mvpconf0"	},
    235  1.1     skrll   {  0, 3, "c0_mvpconf1"	},
    236  1.1     skrll   {  1, 1, "c0_vpecontrol"	},
    237  1.1     skrll   {  1, 2, "c0_vpeconf0"	},
    238  1.1     skrll   {  1, 3, "c0_vpeconf1"	},
    239  1.1     skrll   {  1, 4, "c0_yqmask"		},
    240  1.1     skrll   {  1, 5, "c0_vpeschedule"	},
    241  1.1     skrll   {  1, 6, "c0_vpeschefback"	},
    242  1.1     skrll   {  2, 1, "c0_tcstatus"	},
    243  1.1     skrll   {  2, 2, "c0_tcbind"		},
    244  1.1     skrll   {  2, 3, "c0_tcrestart"	},
    245  1.1     skrll   {  2, 4, "c0_tchalt"		},
    246  1.1     skrll   {  2, 5, "c0_tccontext"	},
    247  1.1     skrll   {  2, 6, "c0_tcschedule"	},
    248  1.1     skrll   {  2, 7, "c0_tcschefback"	},
    249  1.1     skrll   {  5, 1, "c0_pagegrain"	},
    250  1.1     skrll   {  6, 1, "c0_srsconf0"	},
    251  1.1     skrll   {  6, 2, "c0_srsconf1"	},
    252  1.1     skrll   {  6, 3, "c0_srsconf2"	},
    253  1.1     skrll   {  6, 4, "c0_srsconf3"	},
    254  1.1     skrll   {  6, 5, "c0_srsconf4"	},
    255  1.1     skrll   { 12, 1, "c0_intctl"		},
    256  1.1     skrll   { 12, 2, "c0_srsctl"		},
    257  1.1     skrll   { 12, 3, "c0_srsmap"		},
    258  1.1     skrll   { 15, 1, "c0_ebase"		},
    259  1.1     skrll   { 16, 1, "c0_config1"		},
    260  1.1     skrll   { 16, 2, "c0_config2"		},
    261  1.1     skrll   { 16, 3, "c0_config3"		},
    262  1.1     skrll   { 18, 1, "c0_watchlo,1"	},
    263  1.1     skrll   { 18, 2, "c0_watchlo,2"	},
    264  1.1     skrll   { 18, 3, "c0_watchlo,3"	},
    265  1.1     skrll   { 18, 4, "c0_watchlo,4"	},
    266  1.1     skrll   { 18, 5, "c0_watchlo,5"	},
    267  1.1     skrll   { 18, 6, "c0_watchlo,6"	},
    268  1.1     skrll   { 18, 7, "c0_watchlo,7"	},
    269  1.1     skrll   { 19, 1, "c0_watchhi,1"	},
    270  1.1     skrll   { 19, 2, "c0_watchhi,2"	},
    271  1.1     skrll   { 19, 3, "c0_watchhi,3"	},
    272  1.1     skrll   { 19, 4, "c0_watchhi,4"	},
    273  1.1     skrll   { 19, 5, "c0_watchhi,5"	},
    274  1.1     skrll   { 19, 6, "c0_watchhi,6"	},
    275  1.1     skrll   { 19, 7, "c0_watchhi,7"	},
    276  1.1     skrll   { 23, 1, "c0_tracecontrol"	},
    277  1.1     skrll   { 23, 2, "c0_tracecontrol2"	},
    278  1.1     skrll   { 23, 3, "c0_usertracedata"	},
    279  1.1     skrll   { 23, 4, "c0_tracebpc"	},
    280  1.1     skrll   { 25, 1, "c0_perfcnt,1"	},
    281  1.1     skrll   { 25, 2, "c0_perfcnt,2"	},
    282  1.1     skrll   { 25, 3, "c0_perfcnt,3"	},
    283  1.1     skrll   { 25, 4, "c0_perfcnt,4"	},
    284  1.1     skrll   { 25, 5, "c0_perfcnt,5"	},
    285  1.1     skrll   { 25, 6, "c0_perfcnt,6"	},
    286  1.1     skrll   { 25, 7, "c0_perfcnt,7"	},
    287  1.1     skrll   { 27, 1, "c0_cacheerr,1"	},
    288  1.1     skrll   { 27, 2, "c0_cacheerr,2"	},
    289  1.1     skrll   { 27, 3, "c0_cacheerr,3"	},
    290  1.1     skrll   { 28, 1, "c0_datalo"		},
    291  1.1     skrll   { 28, 2, "c0_taglo1"		},
    292  1.1     skrll   { 28, 3, "c0_datalo1"		},
    293  1.1     skrll   { 28, 4, "c0_taglo2"		},
    294  1.1     skrll   { 28, 5, "c0_datalo2"		},
    295  1.1     skrll   { 28, 6, "c0_taglo3"		},
    296  1.1     skrll   { 28, 7, "c0_datalo3"		},
    297  1.1     skrll   { 29, 1, "c0_datahi"		},
    298  1.1     skrll   { 29, 2, "c0_taghi1"		},
    299  1.1     skrll   { 29, 3, "c0_datahi1"		},
    300  1.1     skrll   { 29, 4, "c0_taghi2"		},
    301  1.1     skrll   { 29, 5, "c0_datahi2"		},
    302  1.1     skrll   { 29, 6, "c0_taghi3"		},
    303  1.1     skrll   { 29, 7, "c0_datahi3"		},
    304  1.1     skrll };
    305  1.1     skrll 
    306  1.1     skrll /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods.  */
    307  1.1     skrll static const char * const mips_cp0_names_sb1[32] =
    308  1.1     skrll {
    309  1.1     skrll   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    310  1.1     skrll   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    311  1.1     skrll   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    312  1.1     skrll   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    313  1.1     skrll   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    314  1.1     skrll   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    315  1.1     skrll   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
    316  1.1     skrll   "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
    317  1.1     skrll };
    318  1.1     skrll 
    319  1.1     skrll static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
    320  1.1     skrll {
    321  1.1     skrll   { 16, 1, "c0_config1"		},
    322  1.1     skrll   { 18, 1, "c0_watchlo,1"	},
    323  1.1     skrll   { 19, 1, "c0_watchhi,1"	},
    324  1.1     skrll   { 22, 0, "c0_perftrace"	},
    325  1.1     skrll   { 23, 3, "c0_edebug"		},
    326  1.1     skrll   { 25, 1, "c0_perfcnt,1"	},
    327  1.1     skrll   { 25, 2, "c0_perfcnt,2"	},
    328  1.1     skrll   { 25, 3, "c0_perfcnt,3"	},
    329  1.1     skrll   { 25, 4, "c0_perfcnt,4"	},
    330  1.1     skrll   { 25, 5, "c0_perfcnt,5"	},
    331  1.1     skrll   { 25, 6, "c0_perfcnt,6"	},
    332  1.1     skrll   { 25, 7, "c0_perfcnt,7"	},
    333  1.1     skrll   { 26, 1, "c0_buserr_pa"	},
    334  1.1     skrll   { 27, 1, "c0_cacheerr_d"	},
    335  1.1     skrll   { 27, 3, "c0_cacheerr_d_pa"	},
    336  1.1     skrll   { 28, 1, "c0_datalo_i"	},
    337  1.1     skrll   { 28, 2, "c0_taglo_d"		},
    338  1.1     skrll   { 28, 3, "c0_datalo_d"	},
    339  1.1     skrll   { 29, 1, "c0_datahi_i"	},
    340  1.1     skrll   { 29, 2, "c0_taghi_d"		},
    341  1.1     skrll   { 29, 3, "c0_datahi_d"	},
    342  1.1     skrll };
    343  1.2      matt 
    344  1.2      matt /* Xlr cop0 register names.  */
    345  1.2      matt static const char * const mips_cp0_names_xlr[32] = {
    346  1.3  christos   "c0_index",     "c0_random",    "c0_entrylo0",  "c0_entrylo1",
    347  1.2      matt   "c0_context",   "c0_pagemask",  "c0_wired",     "$7",
    348  1.2      matt   "c0_badvaddr",  "c0_count",     "c0_entryhi",   "c0_compare",
    349  1.2      matt   "c0_status",    "c0_cause",     "c0_epc",       "c0_prid",
    350  1.3  christos   "c0_config",    "c0_lladdr",    "c0_watchlo",   "c0_watchhi",
    351  1.2      matt   "c0_xcontext",  "$21",          "$22",          "c0_debug",
    352  1.2      matt   "c0_depc",      "c0_perfcnt",   "c0_errctl",    "c0_cacheerr_i",
    353  1.2      matt   "c0_taglo_i",   "c0_taghi_i",   "c0_errorepc",  "c0_desave",
    354  1.2      matt };
    355  1.2      matt 
    356  1.2      matt /* XLR's CP0 Select Registers.  */
    357  1.2      matt 
    358  1.2      matt static const struct mips_cp0sel_name mips_cp0sel_names_xlr[] = {
    359  1.2      matt   {  9, 6, "c0_extintreq"       },
    360  1.2      matt   {  9, 7, "c0_extintmask"      },
    361  1.2      matt   { 15, 1, "c0_ebase"           },
    362  1.2      matt   { 16, 1, "c0_config1"         },
    363  1.2      matt   { 16, 2, "c0_config2"         },
    364  1.2      matt   { 16, 3, "c0_config3"         },
    365  1.2      matt   { 16, 7, "c0_procid2"         },
    366  1.2      matt   { 18, 1, "c0_watchlo,1"       },
    367  1.2      matt   { 18, 2, "c0_watchlo,2"       },
    368  1.2      matt   { 18, 3, "c0_watchlo,3"       },
    369  1.2      matt   { 18, 4, "c0_watchlo,4"       },
    370  1.2      matt   { 18, 5, "c0_watchlo,5"       },
    371  1.2      matt   { 18, 6, "c0_watchlo,6"       },
    372  1.2      matt   { 18, 7, "c0_watchlo,7"       },
    373  1.2      matt   { 19, 1, "c0_watchhi,1"       },
    374  1.2      matt   { 19, 2, "c0_watchhi,2"       },
    375  1.2      matt   { 19, 3, "c0_watchhi,3"       },
    376  1.2      matt   { 19, 4, "c0_watchhi,4"       },
    377  1.2      matt   { 19, 5, "c0_watchhi,5"       },
    378  1.2      matt   { 19, 6, "c0_watchhi,6"       },
    379  1.2      matt   { 19, 7, "c0_watchhi,7"       },
    380  1.2      matt   { 25, 1, "c0_perfcnt,1"       },
    381  1.2      matt   { 25, 2, "c0_perfcnt,2"       },
    382  1.2      matt   { 25, 3, "c0_perfcnt,3"       },
    383  1.2      matt   { 25, 4, "c0_perfcnt,4"       },
    384  1.2      matt   { 25, 5, "c0_perfcnt,5"       },
    385  1.2      matt   { 25, 6, "c0_perfcnt,6"       },
    386  1.2      matt   { 25, 7, "c0_perfcnt,7"       },
    387  1.2      matt   { 27, 1, "c0_cacheerr,1"      },
    388  1.2      matt   { 27, 2, "c0_cacheerr,2"      },
    389  1.2      matt   { 27, 3, "c0_cacheerr,3"      },
    390  1.2      matt   { 28, 1, "c0_datalo"          },
    391  1.2      matt   { 29, 1, "c0_datahi"          }
    392  1.2      matt };
    393  1.1     skrll 
    394  1.1     skrll static const char * const mips_hwr_names_numeric[32] =
    395  1.1     skrll {
    396  1.1     skrll   "$0",   "$1",   "$2",   "$3",   "$4",   "$5",   "$6",   "$7",
    397  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    398  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    399  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    400  1.1     skrll };
    401  1.1     skrll 
    402  1.1     skrll static const char * const mips_hwr_names_mips3264r2[32] =
    403  1.1     skrll {
    404  1.1     skrll   "hwr_cpunum",   "hwr_synci_step", "hwr_cc",     "hwr_ccres",
    405  1.1     skrll   "$4",          "$5",            "$6",           "$7",
    406  1.1     skrll   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    407  1.1     skrll   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    408  1.1     skrll   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    409  1.1     skrll };
    410  1.5  christos 
    411  1.5  christos static const char * const msa_control_names[32] =
    412  1.5  christos {
    413  1.5  christos   "msa_ir",	"msa_csr",	"msa_access",	"msa_save",
    414  1.5  christos   "msa_modify",	"msa_request",	"msa_map",	"msa_unmap",
    415  1.5  christos   "$8",   "$9",   "$10",  "$11",  "$12",  "$13",  "$14",  "$15",
    416  1.5  christos   "$16",  "$17",  "$18",  "$19",  "$20",  "$21",  "$22",  "$23",
    417  1.5  christos   "$24",  "$25",  "$26",  "$27",  "$28",  "$29",  "$30",  "$31"
    418  1.5  christos };
    419  1.1     skrll 
    420  1.1     skrll struct mips_abi_choice
    421  1.1     skrll {
    422  1.1     skrll   const char * name;
    423  1.1     skrll   const char * const *gpr_names;
    424  1.1     skrll   const char * const *fpr_names;
    425  1.1     skrll };
    426  1.1     skrll 
    427  1.1     skrll struct mips_abi_choice mips_abi_choices[] =
    428  1.1     skrll {
    429  1.1     skrll   { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
    430  1.1     skrll   { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
    431  1.1     skrll   { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
    432  1.1     skrll   { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
    433  1.1     skrll };
    434  1.1     skrll 
    435  1.1     skrll struct mips_arch_choice
    436  1.1     skrll {
    437  1.1     skrll   const char *name;
    438  1.1     skrll   int bfd_mach_valid;
    439  1.1     skrll   unsigned long bfd_mach;
    440  1.1     skrll   int processor;
    441  1.5  christos   int isa;
    442  1.1     skrll   int ase;
    443  1.1     skrll   const char * const *cp0_names;
    444  1.1     skrll   const struct mips_cp0sel_name *cp0sel_names;
    445  1.5  christos   unsigned int cp0sel_names_len;
    446  1.1     skrll   const char * const *cp1_names;
    447  1.1     skrll   const char * const *hwr_names;
    448  1.1     skrll };
    449  1.1     skrll 
    450  1.1     skrll const struct mips_arch_choice mips_arch_choices[] =
    451  1.5  christos {
    452  1.5  christos   { "numeric",	0, 0, 0, 0, 0,
    453  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    454  1.1     skrll     mips_hwr_names_numeric },
    455  1.5  christos 
    456  1.5  christos   { "r3000",	1, bfd_mach_mips3000, CPU_R3000, ISA_MIPS1, 0,
    457  1.5  christos     mips_cp0_names_r3000, NULL, 0, mips_cp1_names_numeric,
    458  1.5  christos     mips_hwr_names_numeric },
    459  1.5  christos   { "r3900",	1, bfd_mach_mips3900, CPU_R3900, ISA_MIPS1, 0,
    460  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    461  1.5  christos     mips_hwr_names_numeric },
    462  1.5  christos   { "r4000",	1, bfd_mach_mips4000, CPU_R4000, ISA_MIPS3, 0,
    463  1.5  christos     mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
    464  1.5  christos     mips_hwr_names_numeric },
    465  1.5  christos   { "r4010",	1, bfd_mach_mips4010, CPU_R4010, ISA_MIPS2, 0,
    466  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    467  1.5  christos     mips_hwr_names_numeric },
    468  1.5  christos   { "vr4100",	1, bfd_mach_mips4100, CPU_VR4100, ISA_MIPS3, 0,
    469  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    470  1.5  christos     mips_hwr_names_numeric },
    471  1.5  christos   { "vr4111",	1, bfd_mach_mips4111, CPU_R4111, ISA_MIPS3, 0,
    472  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    473  1.5  christos     mips_hwr_names_numeric },
    474  1.5  christos   { "vr4120",	1, bfd_mach_mips4120, CPU_VR4120, ISA_MIPS3, 0,
    475  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    476  1.5  christos     mips_hwr_names_numeric },
    477  1.5  christos   { "r4300",	1, bfd_mach_mips4300, CPU_R4300, ISA_MIPS3, 0,
    478  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    479  1.5  christos     mips_hwr_names_numeric },
    480  1.5  christos   { "r4400",	1, bfd_mach_mips4400, CPU_R4400, ISA_MIPS3, 0,
    481  1.5  christos     mips_cp0_names_r4000, NULL, 0, mips_cp1_names_numeric,
    482  1.5  christos     mips_hwr_names_numeric },
    483  1.5  christos   { "r4600",	1, bfd_mach_mips4600, CPU_R4600, ISA_MIPS3, 0,
    484  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    485  1.5  christos     mips_hwr_names_numeric },
    486  1.5  christos   { "r4650",	1, bfd_mach_mips4650, CPU_R4650, ISA_MIPS3, 0,
    487  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    488  1.5  christos     mips_hwr_names_numeric },
    489  1.5  christos   { "r5000",	1, bfd_mach_mips5000, CPU_R5000, ISA_MIPS4, 0,
    490  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    491  1.5  christos     mips_hwr_names_numeric },
    492  1.5  christos   { "vr5400",	1, bfd_mach_mips5400, CPU_VR5400, ISA_MIPS4, 0,
    493  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    494  1.5  christos     mips_hwr_names_numeric },
    495  1.5  christos   { "vr5500",	1, bfd_mach_mips5500, CPU_VR5500, ISA_MIPS4, 0,
    496  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    497  1.5  christos     mips_hwr_names_numeric },
    498  1.5  christos   { "r5900",	1, bfd_mach_mips5900, CPU_R5900, ISA_MIPS3, 0,
    499  1.5  christos     mips_cp0_names_r5900, NULL, 0, mips_cp1_names_numeric,
    500  1.5  christos     mips_hwr_names_numeric },
    501  1.5  christos   { "r6000",	1, bfd_mach_mips6000, CPU_R6000, ISA_MIPS2, 0,
    502  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    503  1.5  christos     mips_hwr_names_numeric },
    504  1.5  christos   { "rm7000",	1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
    505  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    506  1.5  christos     mips_hwr_names_numeric },
    507  1.5  christos   { "rm9000",	1, bfd_mach_mips7000, CPU_RM7000, ISA_MIPS4, 0,
    508  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    509  1.5  christos     mips_hwr_names_numeric },
    510  1.5  christos   { "r8000",	1, bfd_mach_mips8000, CPU_R8000, ISA_MIPS4, 0,
    511  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    512  1.5  christos     mips_hwr_names_numeric },
    513  1.5  christos   { "r10000",	1, bfd_mach_mips10000, CPU_R10000, ISA_MIPS4, 0,
    514  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    515  1.5  christos     mips_hwr_names_numeric },
    516  1.5  christos   { "r12000",	1, bfd_mach_mips12000, CPU_R12000, ISA_MIPS4, 0,
    517  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    518  1.5  christos     mips_hwr_names_numeric },
    519  1.5  christos   { "r14000",	1, bfd_mach_mips14000, CPU_R14000, ISA_MIPS4, 0,
    520  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    521  1.5  christos     mips_hwr_names_numeric },
    522  1.5  christos   { "r16000",	1, bfd_mach_mips16000, CPU_R16000, ISA_MIPS4, 0,
    523  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    524  1.5  christos     mips_hwr_names_numeric },
    525  1.5  christos   { "mips5",	1, bfd_mach_mips5, CPU_MIPS5, ISA_MIPS5, 0,
    526  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    527  1.1     skrll     mips_hwr_names_numeric },
    528  1.1     skrll 
    529  1.1     skrll   /* For stock MIPS32, disassemble all applicable MIPS-specified ASEs.
    530  1.1     skrll      Note that MIPS-3D and MDMX are not applicable to MIPS32.  (See
    531  1.1     skrll      _MIPS32 Architecture For Programmers Volume I: Introduction to the
    532  1.1     skrll      MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
    533  1.1     skrll      page 1.  */
    534  1.5  christos   { "mips32",	1, bfd_mach_mipsisa32, CPU_MIPS32,
    535  1.1     skrll     ISA_MIPS32,  ASE_SMARTMIPS,
    536  1.1     skrll     mips_cp0_names_mips3264,
    537  1.5  christos     mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
    538  1.1     skrll     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    539  1.1     skrll 
    540  1.5  christos   { "mips32r2",	1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
    541  1.5  christos     ISA_MIPS32R2,
    542  1.5  christos     (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
    543  1.5  christos      | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
    544  1.5  christos     mips_cp0_names_mips3264r2,
    545  1.5  christos     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    546  1.5  christos     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    547  1.5  christos 
    548  1.5  christos   { "mips32r3",	1, bfd_mach_mipsisa32r3, CPU_MIPS32R3,
    549  1.5  christos     ISA_MIPS32R3,
    550  1.5  christos     (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
    551  1.5  christos      | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
    552  1.5  christos     mips_cp0_names_mips3264r2,
    553  1.5  christos     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    554  1.5  christos     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    555  1.5  christos 
    556  1.5  christos   { "mips32r5",	1, bfd_mach_mipsisa32r5, CPU_MIPS32R5,
    557  1.5  christos     ISA_MIPS32R5,
    558  1.5  christos     (ASE_SMARTMIPS | ASE_DSP | ASE_DSPR2 | ASE_EVA | ASE_MIPS3D
    559  1.5  christos      | ASE_MT | ASE_MCU | ASE_VIRT | ASE_MSA | ASE_XPA),
    560  1.5  christos     mips_cp0_names_mips3264r2,
    561  1.5  christos     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    562  1.5  christos     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    563  1.5  christos 
    564  1.5  christos   { "mips32r6",	1, bfd_mach_mipsisa32r6, CPU_MIPS32R6,
    565  1.5  christos     ISA_MIPS32R6,
    566  1.5  christos     (ASE_EVA | ASE_MSA | ASE_VIRT | ASE_XPA | ASE_MCU | ASE_MT | ASE_DSP
    567  1.1     skrll      | ASE_DSPR2),
    568  1.1     skrll     mips_cp0_names_mips3264r2,
    569  1.5  christos     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    570  1.1     skrll     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    571  1.1     skrll 
    572  1.1     skrll   /* For stock MIPS64, disassemble all applicable MIPS-specified ASEs.  */
    573  1.5  christos   { "mips64",	1, bfd_mach_mipsisa64, CPU_MIPS64,
    574  1.1     skrll     ISA_MIPS64,  ASE_MIPS3D | ASE_MDMX,
    575  1.1     skrll     mips_cp0_names_mips3264,
    576  1.5  christos     mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
    577  1.1     skrll     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    578  1.1     skrll 
    579  1.5  christos   { "mips64r2",	1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
    580  1.5  christos     ISA_MIPS64R2,
    581  1.5  christos     (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
    582  1.5  christos      | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
    583  1.5  christos     mips_cp0_names_mips3264r2,
    584  1.5  christos     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    585  1.5  christos     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    586  1.5  christos 
    587  1.5  christos   { "mips64r3",	1, bfd_mach_mipsisa64r3, CPU_MIPS64R3,
    588  1.5  christos     ISA_MIPS64R3,
    589  1.5  christos     (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
    590  1.5  christos      | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
    591  1.5  christos     mips_cp0_names_mips3264r2,
    592  1.5  christos     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    593  1.5  christos     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    594  1.5  christos 
    595  1.5  christos   { "mips64r5",	1, bfd_mach_mipsisa64r5, CPU_MIPS64R5,
    596  1.5  christos     ISA_MIPS64R5,
    597  1.5  christos     (ASE_MIPS3D | ASE_DSP | ASE_DSPR2 | ASE_DSP64 | ASE_EVA | ASE_MT
    598  1.5  christos      | ASE_MCU | ASE_VIRT | ASE_VIRT64 | ASE_MSA | ASE_MSA64 | ASE_XPA),
    599  1.5  christos     mips_cp0_names_mips3264r2,
    600  1.5  christos     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    601  1.5  christos     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    602  1.5  christos 
    603  1.5  christos   { "mips64r6",	1, bfd_mach_mipsisa64r6, CPU_MIPS64R6,
    604  1.5  christos     ISA_MIPS64R6,
    605  1.5  christos     (ASE_EVA | ASE_MSA | ASE_MSA64 | ASE_XPA | ASE_VIRT | ASE_VIRT64
    606  1.1     skrll      | ASE_MCU | ASE_MT | ASE_DSP | ASE_DSPR2),
    607  1.1     skrll     mips_cp0_names_mips3264r2,
    608  1.5  christos     mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
    609  1.1     skrll     mips_cp1_names_mips3264, mips_hwr_names_mips3264r2 },
    610  1.1     skrll 
    611  1.5  christos   { "sb1",	1, bfd_mach_mips_sb1, CPU_SB1,
    612  1.1     skrll     ISA_MIPS64 | INSN_SB1,  ASE_MIPS3D,
    613  1.1     skrll     mips_cp0_names_sb1,
    614  1.5  christos     mips_cp0sel_names_sb1, ARRAY_SIZE (mips_cp0sel_names_sb1),
    615  1.1     skrll     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    616  1.1     skrll 
    617  1.5  christos   { "loongson2e",   1, bfd_mach_mips_loongson_2e, CPU_LOONGSON_2E,
    618  1.5  christos     ISA_MIPS3 | INSN_LOONGSON_2E, 0, mips_cp0_names_numeric,
    619  1.1     skrll     NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
    620  1.1     skrll 
    621  1.5  christos   { "loongson2f",   1, bfd_mach_mips_loongson_2f, CPU_LOONGSON_2F,
    622  1.5  christos     ISA_MIPS3 | INSN_LOONGSON_2F, 0, mips_cp0_names_numeric,
    623  1.1     skrll     NULL, 0, mips_cp1_names_numeric, mips_hwr_names_numeric },
    624  1.4  christos 
    625  1.5  christos   { "loongson3a",   1, bfd_mach_mips_loongson_3a, CPU_LOONGSON_3A,
    626  1.5  christos     ISA_MIPS64R2 | INSN_LOONGSON_3A, 0, mips_cp0_names_numeric,
    627  1.4  christos     NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
    628  1.1     skrll 
    629  1.5  christos   { "octeon",   1, bfd_mach_mips_octeon, CPU_OCTEON,
    630  1.5  christos     ISA_MIPS64R2 | INSN_OCTEON, 0, mips_cp0_names_numeric, NULL, 0,
    631  1.1     skrll     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    632  1.4  christos 
    633  1.5  christos   { "octeon+",   1, bfd_mach_mips_octeonp, CPU_OCTEONP,
    634  1.5  christos     ISA_MIPS64R2 | INSN_OCTEONP, 0, mips_cp0_names_numeric,
    635  1.4  christos     NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
    636  1.4  christos 
    637  1.5  christos   { "octeon2",   1, bfd_mach_mips_octeon2, CPU_OCTEON2,
    638  1.5  christos     ISA_MIPS64R2 | INSN_OCTEON2, 0, mips_cp0_names_numeric,
    639  1.5  christos     NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
    640  1.5  christos 
    641  1.5  christos   { "octeon3",   1, bfd_mach_mips_octeon3, CPU_OCTEON3,
    642  1.5  christos     ISA_MIPS64R5 | INSN_OCTEON3, ASE_VIRT | ASE_VIRT64,
    643  1.5  christos     mips_cp0_names_numeric,
    644  1.4  christos     NULL, 0, mips_cp1_names_mips3264, mips_hwr_names_numeric },
    645  1.2      matt 
    646  1.5  christos   { "xlr", 1, bfd_mach_mips_xlr, CPU_XLR,
    647  1.2      matt     ISA_MIPS64 | INSN_XLR, 0,
    648  1.2      matt     mips_cp0_names_xlr,
    649  1.5  christos     mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
    650  1.2      matt     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    651  1.4  christos 
    652  1.4  christos   /* XLP is mostly like XLR, with the prominent exception it is being
    653  1.4  christos      MIPS64R2.  */
    654  1.5  christos   { "xlp", 1, bfd_mach_mips_xlr, CPU_XLR,
    655  1.4  christos     ISA_MIPS64R2 | INSN_XLR, 0,
    656  1.4  christos     mips_cp0_names_xlr,
    657  1.5  christos     mips_cp0sel_names_xlr, ARRAY_SIZE (mips_cp0sel_names_xlr),
    658  1.4  christos     mips_cp1_names_mips3264, mips_hwr_names_numeric },
    659  1.1     skrll 
    660  1.1     skrll   /* This entry, mips16, is here only for ISA/processor selection; do
    661  1.5  christos      not print its name.  */
    662  1.5  christos   { "",		1, bfd_mach_mips16, CPU_MIPS16, ISA_MIPS3, 0,
    663  1.5  christos     mips_cp0_names_numeric, NULL, 0, mips_cp1_names_numeric,
    664  1.1     skrll     mips_hwr_names_numeric },
    665  1.1     skrll };
    666  1.1     skrll 
    667  1.1     skrll /* ISA and processor type to disassemble for, and register names to use.
    668  1.1     skrll    set_default_mips_dis_options and parse_mips_dis_options fill in these
    669  1.1     skrll    values.  */
    670  1.1     skrll static int mips_processor;
    671  1.5  christos static int mips_isa;
    672  1.4  christos static int mips_ase;
    673  1.1     skrll static int micromips_ase;
    674  1.1     skrll static const char * const *mips_gpr_names;
    675  1.1     skrll static const char * const *mips_fpr_names;
    676  1.1     skrll static const char * const *mips_cp0_names;
    677  1.1     skrll static const struct mips_cp0sel_name *mips_cp0sel_names;
    678  1.5  christos static int mips_cp0sel_names_len;
    679  1.1     skrll static const char * const *mips_cp1_names;
    680  1.1     skrll static const char * const *mips_hwr_names;
    681  1.1     skrll 
    682  1.1     skrll /* Other options */
    683  1.1     skrll static int no_aliases;	/* If set disassemble as most general inst.  */
    684  1.1     skrll 
    685  1.1     skrll static const struct mips_abi_choice *
    687  1.1     skrll choose_abi_by_name (const char *name, unsigned int namelen)
    688  1.1     skrll {
    689  1.1     skrll   const struct mips_abi_choice *c;
    690  1.1     skrll   unsigned int i;
    691  1.1     skrll 
    692  1.1     skrll   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
    693  1.1     skrll     if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
    694  1.1     skrll 	&& strlen (mips_abi_choices[i].name) == namelen)
    695  1.1     skrll       c = &mips_abi_choices[i];
    696  1.1     skrll 
    697  1.1     skrll   return c;
    698  1.1     skrll }
    699  1.1     skrll 
    700  1.1     skrll static const struct mips_arch_choice *
    701  1.1     skrll choose_arch_by_name (const char *name, unsigned int namelen)
    702  1.1     skrll {
    703  1.1     skrll   const struct mips_arch_choice *c = NULL;
    704  1.1     skrll   unsigned int i;
    705  1.1     skrll 
    706  1.1     skrll   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
    707  1.1     skrll     if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
    708  1.1     skrll 	&& strlen (mips_arch_choices[i].name) == namelen)
    709  1.1     skrll       c = &mips_arch_choices[i];
    710  1.1     skrll 
    711  1.1     skrll   return c;
    712  1.1     skrll }
    713  1.1     skrll 
    714  1.1     skrll static const struct mips_arch_choice *
    715  1.1     skrll choose_arch_by_number (unsigned long mach)
    716  1.1     skrll {
    717  1.1     skrll   static unsigned long hint_bfd_mach;
    718  1.1     skrll   static const struct mips_arch_choice *hint_arch_choice;
    719  1.1     skrll   const struct mips_arch_choice *c;
    720  1.1     skrll   unsigned int i;
    721  1.1     skrll 
    722  1.1     skrll   /* We optimize this because even if the user specifies no
    723  1.1     skrll      flags, this will be done for every instruction!  */
    724  1.1     skrll   if (hint_bfd_mach == mach
    725  1.1     skrll       && hint_arch_choice != NULL
    726  1.1     skrll       && hint_arch_choice->bfd_mach == hint_bfd_mach)
    727  1.1     skrll     return hint_arch_choice;
    728  1.1     skrll 
    729  1.1     skrll   for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
    730  1.1     skrll     {
    731  1.1     skrll       if (mips_arch_choices[i].bfd_mach_valid
    732  1.1     skrll 	  && mips_arch_choices[i].bfd_mach == mach)
    733  1.1     skrll 	{
    734  1.1     skrll 	  c = &mips_arch_choices[i];
    735  1.1     skrll 	  hint_bfd_mach = mach;
    736  1.1     skrll 	  hint_arch_choice = c;
    737  1.1     skrll 	}
    738  1.1     skrll     }
    739  1.1     skrll   return c;
    740  1.1     skrll }
    741  1.1     skrll 
    742  1.1     skrll /* Check if the object uses NewABI conventions.  */
    743  1.1     skrll 
    744  1.1     skrll static int
    745  1.1     skrll is_newabi (Elf_Internal_Ehdr *header)
    746  1.1     skrll {
    747  1.1     skrll   /* There are no old-style ABIs which use 64-bit ELF.  */
    748  1.1     skrll   if (header->e_ident[EI_CLASS] == ELFCLASS64)
    749  1.1     skrll     return 1;
    750  1.1     skrll 
    751  1.1     skrll   /* If a 32-bit ELF file, n32 is a new-style ABI.  */
    752  1.1     skrll   if ((header->e_flags & EF_MIPS_ABI2) != 0)
    753  1.1     skrll     return 1;
    754  1.1     skrll 
    755  1.1     skrll   return 0;
    756  1.4  christos }
    757  1.4  christos 
    758  1.4  christos /* Check if the object has microMIPS ASE code.  */
    759  1.4  christos 
    760  1.4  christos static int
    761  1.4  christos is_micromips (Elf_Internal_Ehdr *header)
    762  1.4  christos {
    763  1.4  christos   if ((header->e_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0)
    764  1.4  christos     return 1;
    765  1.4  christos 
    766  1.4  christos   return 0;
    767  1.1     skrll }
    768  1.1     skrll 
    769  1.1     skrll static void
    770  1.1     skrll set_default_mips_dis_options (struct disassemble_info *info)
    771  1.1     skrll {
    772  1.4  christos   const struct mips_arch_choice *chosen_arch;
    773  1.4  christos 
    774  1.4  christos   /* Defaults: mipsIII/r3000 (?!), no microMIPS ASE (any compressed code
    775  1.1     skrll      is MIPS16 ASE) (o)32-style ("oldabi") GPR names, and numeric FPR,
    776  1.4  christos      CP0 register, and HWR names.  */
    777  1.4  christos   mips_isa = ISA_MIPS3;
    778  1.5  christos   mips_processor = CPU_R3000;
    779  1.1     skrll   micromips_ase = 0;
    780  1.1     skrll   mips_ase = 0;
    781  1.1     skrll   mips_gpr_names = mips_gpr_names_oldabi;
    782  1.1     skrll   mips_fpr_names = mips_fpr_names_numeric;
    783  1.1     skrll   mips_cp0_names = mips_cp0_names_numeric;
    784  1.5  christos   mips_cp0sel_names = NULL;
    785  1.1     skrll   mips_cp0sel_names_len = 0;
    786  1.1     skrll   mips_cp1_names = mips_cp1_names_numeric;
    787  1.1     skrll   mips_hwr_names = mips_hwr_names_numeric;
    788  1.4  christos   no_aliases = 0;
    789  1.1     skrll 
    790  1.1     skrll   /* Update settings according to the ELF file header flags.  */
    791  1.1     skrll   if (info->flavour == bfd_target_elf_flavour && info->section != NULL)
    792  1.1     skrll     {
    793  1.1     skrll       Elf_Internal_Ehdr *header;
    794  1.4  christos 
    795  1.1     skrll       header = elf_elfheader (info->section->owner);
    796  1.1     skrll       /* If an ELF "newabi" binary, use the n32/(n)64 GPR names.  */
    797  1.4  christos       if (is_newabi (header))
    798  1.4  christos 	mips_gpr_names = mips_gpr_names_newabi;
    799  1.1     skrll       /* If a microMIPS binary, then don't use MIPS16 bindings.  */
    800  1.1     skrll       micromips_ase = is_micromips (header);
    801  1.1     skrll     }
    802  1.1     skrll 
    803  1.1     skrll   /* Set ISA, architecture, and cp0 register names as best we can.  */
    804  1.1     skrll #if ! SYMTAB_AVAILABLE
    805  1.1     skrll   /* This is running out on a target machine, not in a host tool.
    806  1.1     skrll      FIXME: Where does mips_target_info come from?  */
    807  1.5  christos   target_processor = mips_target_info.processor;
    808  1.1     skrll   mips_isa = mips_target_info.isa;
    809  1.1     skrll   mips_ase = mips_target_info.ase;
    810  1.1     skrll #else
    811  1.1     skrll   chosen_arch = choose_arch_by_number (info->mach);
    812  1.1     skrll   if (chosen_arch != NULL)
    813  1.1     skrll     {
    814  1.5  christos       mips_processor = chosen_arch->processor;
    815  1.1     skrll       mips_isa = chosen_arch->isa;
    816  1.1     skrll       mips_ase = chosen_arch->ase;
    817  1.1     skrll       mips_cp0_names = chosen_arch->cp0_names;
    818  1.5  christos       mips_cp0sel_names = chosen_arch->cp0sel_names;
    819  1.1     skrll       mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
    820  1.1     skrll       mips_cp1_names = chosen_arch->cp1_names;
    821  1.1     skrll       mips_hwr_names = chosen_arch->hwr_names;
    822  1.1     skrll     }
    823  1.1     skrll #endif
    824  1.1     skrll }
    825  1.1     skrll 
    826  1.1     skrll static void
    827  1.1     skrll parse_mips_dis_option (const char *option, unsigned int len)
    828  1.1     skrll {
    829  1.1     skrll   unsigned int i, optionlen, vallen;
    830  1.1     skrll   const char *val;
    831  1.1     skrll   const struct mips_abi_choice *chosen_abi;
    832  1.1     skrll   const struct mips_arch_choice *chosen_arch;
    833  1.1     skrll 
    834  1.1     skrll   /* Try to match options that are simple flags */
    835  1.1     skrll   if (CONST_STRNEQ (option, "no-aliases"))
    836  1.1     skrll     {
    837  1.1     skrll       no_aliases = 1;
    838  1.5  christos       return;
    839  1.5  christos     }
    840  1.5  christos 
    841  1.5  christos   if (CONST_STRNEQ (option, "msa"))
    842  1.5  christos     {
    843  1.5  christos       mips_ase |= ASE_MSA;
    844  1.5  christos       if ((mips_isa & INSN_ISA_MASK) == ISA_MIPS64R2
    845  1.5  christos 	   || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R3
    846  1.5  christos 	   || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R5
    847  1.5  christos 	   || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6)
    848  1.5  christos 	  mips_ase |= ASE_MSA64;
    849  1.5  christos       return;
    850  1.5  christos     }
    851  1.5  christos 
    852  1.5  christos   if (CONST_STRNEQ (option, "virt"))
    853  1.5  christos     {
    854  1.5  christos       mips_ase |= ASE_VIRT;
    855  1.5  christos       if (mips_isa & ISA_MIPS64R2
    856  1.5  christos 	  || mips_isa & ISA_MIPS64R3
    857  1.5  christos 	  || mips_isa & ISA_MIPS64R5
    858  1.5  christos 	  || mips_isa & ISA_MIPS64R6)
    859  1.5  christos 	mips_ase |= ASE_VIRT64;
    860  1.5  christos       return;
    861  1.5  christos     }
    862  1.5  christos 
    863  1.5  christos   if (CONST_STRNEQ (option, "xpa"))
    864  1.5  christos     {
    865  1.5  christos       mips_ase |= ASE_XPA;
    866  1.5  christos       return;
    867  1.5  christos     }
    868  1.1     skrll 
    869  1.1     skrll 
    870  1.1     skrll   /* Look for the = that delimits the end of the option name.  */
    871  1.1     skrll   for (i = 0; i < len; i++)
    872  1.1     skrll     if (option[i] == '=')
    873  1.1     skrll       break;
    874  1.1     skrll 
    875  1.1     skrll   if (i == 0)		/* Invalid option: no name before '='.  */
    876  1.1     skrll     return;
    877  1.1     skrll   if (i == len)		/* Invalid option: no '='.  */
    878  1.1     skrll     return;
    879  1.1     skrll   if (i == (len - 1))	/* Invalid option: no value after '='.  */
    880  1.1     skrll     return;
    881  1.1     skrll 
    882  1.1     skrll   optionlen = i;
    883  1.1     skrll   val = option + (optionlen + 1);
    884  1.1     skrll   vallen = len - (optionlen + 1);
    885  1.1     skrll 
    886  1.1     skrll   if (strncmp ("gpr-names", option, optionlen) == 0
    887  1.1     skrll       && strlen ("gpr-names") == optionlen)
    888  1.1     skrll     {
    889  1.1     skrll       chosen_abi = choose_abi_by_name (val, vallen);
    890  1.1     skrll       if (chosen_abi != NULL)
    891  1.1     skrll 	mips_gpr_names = chosen_abi->gpr_names;
    892  1.1     skrll       return;
    893  1.1     skrll     }
    894  1.1     skrll 
    895  1.1     skrll   if (strncmp ("fpr-names", option, optionlen) == 0
    896  1.1     skrll       && strlen ("fpr-names") == optionlen)
    897  1.1     skrll     {
    898  1.1     skrll       chosen_abi = choose_abi_by_name (val, vallen);
    899  1.1     skrll       if (chosen_abi != NULL)
    900  1.1     skrll 	mips_fpr_names = chosen_abi->fpr_names;
    901  1.1     skrll       return;
    902  1.1     skrll     }
    903  1.1     skrll 
    904  1.1     skrll   if (strncmp ("cp0-names", option, optionlen) == 0
    905  1.1     skrll       && strlen ("cp0-names") == optionlen)
    906  1.1     skrll     {
    907  1.1     skrll       chosen_arch = choose_arch_by_name (val, vallen);
    908  1.1     skrll       if (chosen_arch != NULL)
    909  1.1     skrll 	{
    910  1.1     skrll 	  mips_cp0_names = chosen_arch->cp0_names;
    911  1.1     skrll 	  mips_cp0sel_names = chosen_arch->cp0sel_names;
    912  1.1     skrll 	  mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
    913  1.1     skrll 	}
    914  1.1     skrll       return;
    915  1.5  christos     }
    916  1.5  christos 
    917  1.5  christos   if (strncmp ("cp1-names", option, optionlen) == 0
    918  1.5  christos       && strlen ("cp1-names") == optionlen)
    919  1.5  christos     {
    920  1.5  christos       chosen_arch = choose_arch_by_name (val, vallen);
    921  1.5  christos       if (chosen_arch != NULL)
    922  1.5  christos 	mips_cp1_names = chosen_arch->cp1_names;
    923  1.5  christos       return;
    924  1.1     skrll     }
    925  1.1     skrll 
    926  1.1     skrll   if (strncmp ("hwr-names", option, optionlen) == 0
    927  1.1     skrll       && strlen ("hwr-names") == optionlen)
    928  1.1     skrll     {
    929  1.1     skrll       chosen_arch = choose_arch_by_name (val, vallen);
    930  1.1     skrll       if (chosen_arch != NULL)
    931  1.1     skrll 	mips_hwr_names = chosen_arch->hwr_names;
    932  1.1     skrll       return;
    933  1.1     skrll     }
    934  1.1     skrll 
    935  1.1     skrll   if (strncmp ("reg-names", option, optionlen) == 0
    936  1.1     skrll       && strlen ("reg-names") == optionlen)
    937  1.1     skrll     {
    938  1.1     skrll       /* We check both ABI and ARCH here unconditionally, so
    939  1.1     skrll 	 that "numeric" will do the desirable thing: select
    940  1.1     skrll 	 numeric register names for all registers.  Other than
    941  1.1     skrll 	 that, a given name probably won't match both.  */
    942  1.1     skrll       chosen_abi = choose_abi_by_name (val, vallen);
    943  1.1     skrll       if (chosen_abi != NULL)
    944  1.1     skrll 	{
    945  1.1     skrll 	  mips_gpr_names = chosen_abi->gpr_names;
    946  1.1     skrll 	  mips_fpr_names = chosen_abi->fpr_names;
    947  1.1     skrll 	}
    948  1.1     skrll       chosen_arch = choose_arch_by_name (val, vallen);
    949  1.1     skrll       if (chosen_arch != NULL)
    950  1.1     skrll 	{
    951  1.1     skrll 	  mips_cp0_names = chosen_arch->cp0_names;
    952  1.5  christos 	  mips_cp0sel_names = chosen_arch->cp0sel_names;
    953  1.1     skrll 	  mips_cp0sel_names_len = chosen_arch->cp0sel_names_len;
    954  1.1     skrll 	  mips_cp1_names = chosen_arch->cp1_names;
    955  1.1     skrll 	  mips_hwr_names = chosen_arch->hwr_names;
    956  1.1     skrll 	}
    957  1.1     skrll       return;
    958  1.1     skrll     }
    959  1.1     skrll 
    960  1.1     skrll   /* Invalid option.  */
    961  1.1     skrll }
    962  1.1     skrll 
    963  1.1     skrll static void
    964  1.1     skrll parse_mips_dis_options (const char *options)
    965  1.1     skrll {
    966  1.1     skrll   const char *option_end;
    967  1.1     skrll 
    968  1.1     skrll   if (options == NULL)
    969  1.1     skrll     return;
    970  1.1     skrll 
    971  1.1     skrll   while (*options != '\0')
    972  1.1     skrll     {
    973  1.1     skrll       /* Skip empty options.  */
    974  1.1     skrll       if (*options == ',')
    975  1.1     skrll 	{
    976  1.1     skrll 	  options++;
    977  1.1     skrll 	  continue;
    978  1.1     skrll 	}
    979  1.1     skrll 
    980  1.1     skrll       /* We know that *options is neither NUL or a comma.  */
    981  1.1     skrll       option_end = options + 1;
    982  1.1     skrll       while (*option_end != ',' && *option_end != '\0')
    983  1.1     skrll 	option_end++;
    984  1.1     skrll 
    985  1.1     skrll       parse_mips_dis_option (options, option_end - options);
    986  1.1     skrll 
    987  1.1     skrll       /* Go on to the next one.  If option_end points to a comma, it
    988  1.1     skrll 	 will be skipped above.  */
    989  1.1     skrll       options = option_end;
    990  1.1     skrll     }
    991  1.1     skrll }
    992  1.1     skrll 
    993  1.1     skrll static const struct mips_cp0sel_name *
    994  1.1     skrll lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
    995  1.1     skrll 			 unsigned int len,
    996  1.1     skrll 			 unsigned int cp0reg,
    997  1.1     skrll 			 unsigned int sel)
    998  1.1     skrll {
    999  1.1     skrll   unsigned int i;
   1000  1.1     skrll 
   1001  1.1     skrll   for (i = 0; i < len; i++)
   1002  1.1     skrll     if (names[i].cp0reg == cp0reg && names[i].sel == sel)
   1003  1.1     skrll       return &names[i];
   1004  1.5  christos   return NULL;
   1005  1.5  christos }
   1006  1.1     skrll 
   1007  1.1     skrll /* Print register REGNO, of type TYPE, for instruction OPCODE.  */
   1008  1.5  christos 
   1009  1.5  christos static void
   1010  1.1     skrll print_reg (struct disassemble_info *info, const struct mips_opcode *opcode,
   1011  1.5  christos 	   enum mips_reg_operand_type type, int regno)
   1012  1.5  christos {
   1013  1.5  christos   switch (type)
   1014  1.5  christos     {
   1015  1.5  christos     case OP_REG_GP:
   1016  1.5  christos       info->fprintf_func (info->stream, "%s", mips_gpr_names[regno]);
   1017  1.5  christos       break;
   1018  1.5  christos 
   1019  1.5  christos     case OP_REG_FP:
   1020  1.5  christos       info->fprintf_func (info->stream, "%s", mips_fpr_names[regno]);
   1021  1.5  christos       break;
   1022  1.5  christos 
   1023  1.5  christos     case OP_REG_CCC:
   1024  1.5  christos       if (opcode->pinfo & (FP_D | FP_S))
   1025  1.5  christos 	info->fprintf_func (info->stream, "$fcc%d", regno);
   1026  1.5  christos       else
   1027  1.1     skrll 	info->fprintf_func (info->stream, "$cc%d", regno);
   1028  1.5  christos       break;
   1029  1.5  christos 
   1030  1.5  christos     case OP_REG_VEC:
   1031  1.5  christos       if (opcode->membership & INSN_5400)
   1032  1.5  christos 	info->fprintf_func (info->stream, "$f%d", regno);
   1033  1.5  christos       else
   1034  1.1     skrll 	info->fprintf_func (info->stream, "$v%d", regno);
   1035  1.5  christos       break;
   1036  1.5  christos 
   1037  1.5  christos     case OP_REG_ACC:
   1038  1.1     skrll       info->fprintf_func (info->stream, "$ac%d", regno);
   1039  1.5  christos       break;
   1040  1.5  christos 
   1041  1.5  christos     case OP_REG_COPRO:
   1042  1.5  christos       if (opcode->name[strlen (opcode->name) - 1] == '0')
   1043  1.5  christos 	info->fprintf_func (info->stream, "%s", mips_cp0_names[regno]);
   1044  1.5  christos       else if (opcode->name[strlen (opcode->name) - 1] == '1')
   1045  1.5  christos 	info->fprintf_func (info->stream, "%s", mips_cp1_names[regno]);
   1046  1.5  christos       else
   1047  1.1     skrll 	info->fprintf_func (info->stream, "$%d", regno);
   1048  1.5  christos       break;
   1049  1.5  christos 
   1050  1.5  christos     case OP_REG_HW:
   1051  1.1     skrll       info->fprintf_func (info->stream, "%s", mips_hwr_names[regno]);
   1052  1.5  christos       break;
   1053  1.5  christos 
   1054  1.5  christos     case OP_REG_VF:
   1055  1.1     skrll       info->fprintf_func (info->stream, "$vf%d", regno);
   1056  1.5  christos       break;
   1057  1.5  christos 
   1058  1.5  christos     case OP_REG_VI:
   1059  1.1     skrll       info->fprintf_func (info->stream, "$vi%d", regno);
   1060  1.5  christos       break;
   1061  1.5  christos 
   1062  1.5  christos     case OP_REG_R5900_I:
   1063  1.1     skrll       info->fprintf_func (info->stream, "$I");
   1064  1.5  christos       break;
   1065  1.5  christos 
   1066  1.5  christos     case OP_REG_R5900_Q:
   1067  1.1     skrll       info->fprintf_func (info->stream, "$Q");
   1068  1.5  christos       break;
   1069  1.5  christos 
   1070  1.5  christos     case OP_REG_R5900_R:
   1071  1.1     skrll       info->fprintf_func (info->stream, "$R");
   1072  1.5  christos       break;
   1073  1.5  christos 
   1074  1.5  christos     case OP_REG_R5900_ACC:
   1075  1.1     skrll       info->fprintf_func (info->stream, "$ACC");
   1076  1.5  christos       break;
   1077  1.5  christos 
   1078  1.5  christos     case OP_REG_MSA:
   1079  1.1     skrll       info->fprintf_func (info->stream, "$w%d", regno);
   1080  1.5  christos       break;
   1081  1.5  christos 
   1082  1.5  christos     case OP_REG_MSA_CTRL:
   1083  1.1     skrll       info->fprintf_func (info->stream, "%s", msa_control_names[regno]);
   1084  1.5  christos       break;
   1085  1.5  christos 
   1086  1.5  christos     }
   1087  1.5  christos }
   1088  1.5  christos 
   1089  1.5  christos /* Used to track the state carried over from previous operands in
   1091  1.5  christos    an instruction.  */
   1092  1.5  christos struct mips_print_arg_state {
   1093  1.5  christos   /* The value of the last OP_INT seen.  We only use this for OP_MSB,
   1094  1.5  christos      where the value is known to be unsigned and small.  */
   1095  1.5  christos   unsigned int last_int;
   1096  1.5  christos 
   1097  1.5  christos   /* The type and number of the last OP_REG seen.  We only use this for
   1098  1.5  christos      OP_REPEAT_DEST_REG and OP_REPEAT_PREV_REG.  */
   1099  1.5  christos   enum mips_reg_operand_type last_reg_type;
   1100  1.5  christos   unsigned int last_regno;
   1101  1.1     skrll   unsigned int dest_regno;
   1102  1.5  christos   unsigned int seen_dest;
   1103  1.1     skrll };
   1104  1.5  christos 
   1105  1.5  christos /* Initialize STATE for the start of an instruction.  */
   1106  1.5  christos 
   1107  1.5  christos static inline void
   1108  1.5  christos init_print_arg_state (struct mips_print_arg_state *state)
   1109  1.1     skrll {
   1110  1.5  christos   memset (state, 0, sizeof (*state));
   1111  1.5  christos }
   1112  1.1     skrll 
   1113  1.5  christos /* Print OP_VU0_SUFFIX or OP_VU0_MATCH_SUFFIX operand OPERAND,
   1114  1.5  christos    whose value is given by UVAL.  */
   1115  1.5  christos 
   1116  1.5  christos static void
   1117  1.5  christos print_vu0_channel (struct disassemble_info *info,
   1118  1.5  christos 		   const struct mips_operand *operand, unsigned int uval)
   1119  1.5  christos {
   1120  1.5  christos   if (operand->size == 4)
   1121  1.5  christos     info->fprintf_func (info->stream, "%s%s%s%s",
   1122  1.5  christos 			uval & 8 ? "x" : "",
   1123  1.5  christos 			uval & 4 ? "y" : "",
   1124  1.5  christos 			uval & 2 ? "z" : "",
   1125  1.5  christos 			uval & 1 ? "w" : "");
   1126  1.5  christos   else if (operand->size == 2)
   1127  1.5  christos     info->fprintf_func (info->stream, "%c", "xyzw"[uval]);
   1128  1.1     skrll   else
   1129  1.5  christos     abort ();
   1130  1.1     skrll }
   1131  1.5  christos 
   1132  1.5  christos /* Record information about a register operand.  */
   1133  1.5  christos 
   1134  1.5  christos static void
   1135  1.5  christos mips_seen_register (struct mips_print_arg_state *state,
   1136  1.5  christos 		    unsigned int regno,
   1137  1.5  christos 		    enum mips_reg_operand_type reg_type)
   1138  1.1     skrll {
   1139  1.5  christos   state->last_reg_type = reg_type;
   1140  1.5  christos   state->last_regno = regno;
   1141  1.5  christos 
   1142  1.5  christos   if (!state->seen_dest)
   1143  1.5  christos     {
   1144  1.5  christos       state->seen_dest = 1;
   1145  1.1     skrll       state->dest_regno = regno;
   1146  1.5  christos     }
   1147  1.5  christos }
   1148  1.5  christos 
   1149  1.1     skrll /* Print operand OPERAND of OPCODE, using STATE to track inter-operand state.
   1150  1.5  christos    UVAL is the encoding of the operand (shifted into bit 0) and BASE_PC is
   1151  1.5  christos    the base address for OP_PCREL operands.  */
   1152  1.5  christos 
   1153  1.5  christos static void
   1154  1.5  christos print_insn_arg (struct disassemble_info *info,
   1155  1.5  christos 		struct mips_print_arg_state *state,
   1156  1.5  christos 		const struct mips_opcode *opcode,
   1157  1.5  christos 		const struct mips_operand *operand,
   1158  1.5  christos 		bfd_vma base_pc,
   1159  1.5  christos 		unsigned int uval)
   1160  1.1     skrll {
   1161  1.5  christos   const fprintf_ftype infprintf = info->fprintf_func;
   1162  1.5  christos   void *is = info->stream;
   1163  1.5  christos 
   1164  1.5  christos   switch (operand->type)
   1165  1.5  christos     {
   1166  1.4  christos     case OP_INT:
   1167  1.5  christos       {
   1168  1.5  christos 	const struct mips_int_operand *int_op;
   1169  1.5  christos 
   1170  1.5  christos 	int_op = (const struct mips_int_operand *) operand;
   1171  1.5  christos 	uval = mips_decode_int_operand (int_op, uval);
   1172  1.5  christos 	state->last_int = uval;
   1173  1.5  christos 	if (int_op->print_hex)
   1174  1.5  christos 	  infprintf (is, "0x%x", uval);
   1175  1.5  christos 	else
   1176  1.4  christos 	  infprintf (is, "%d", uval);
   1177  1.5  christos       }
   1178  1.5  christos       break;
   1179  1.5  christos 
   1180  1.1     skrll     case OP_MAPPED_INT:
   1181  1.5  christos       {
   1182  1.5  christos 	const struct mips_mapped_int_operand *mint_op;
   1183  1.5  christos 
   1184  1.5  christos 	mint_op = (const struct mips_mapped_int_operand *) operand;
   1185  1.5  christos 	uval = mint_op->int_map[uval];
   1186  1.5  christos 	state->last_int = uval;
   1187  1.5  christos 	if (mint_op->print_hex)
   1188  1.5  christos 	  infprintf (is, "0x%x", uval);
   1189  1.5  christos 	else
   1190  1.1     skrll 	  infprintf (is, "%d", uval);
   1191  1.5  christos       }
   1192  1.5  christos       break;
   1193  1.5  christos 
   1194  1.1     skrll     case OP_MSB:
   1195  1.5  christos       {
   1196  1.5  christos 	const struct mips_msb_operand *msb_op;
   1197  1.5  christos 
   1198  1.5  christos 	msb_op = (const struct mips_msb_operand *) operand;
   1199  1.5  christos 	uval += msb_op->bias;
   1200  1.5  christos 	if (msb_op->add_lsb)
   1201  1.5  christos 	  uval -= state->last_int;
   1202  1.1     skrll 	infprintf (is, "0x%x", uval);
   1203  1.5  christos       }
   1204  1.5  christos       break;
   1205  1.5  christos 
   1206  1.5  christos     case OP_REG:
   1207  1.1     skrll     case OP_OPTIONAL_REG:
   1208  1.5  christos       {
   1209  1.5  christos 	const struct mips_reg_operand *reg_op;
   1210  1.5  christos 
   1211  1.1     skrll 	reg_op = (const struct mips_reg_operand *) operand;
   1212  1.5  christos 	uval = mips_decode_reg_operand (reg_op, uval);
   1213  1.5  christos 	print_reg (info, opcode, reg_op->reg_type, uval);
   1214  1.5  christos 
   1215  1.1     skrll 	mips_seen_register (state, uval, reg_op->reg_type);
   1216  1.5  christos       }
   1217  1.5  christos       break;
   1218  1.5  christos 
   1219  1.1     skrll     case OP_REG_PAIR:
   1220  1.5  christos       {
   1221  1.5  christos 	const struct mips_reg_pair_operand *pair_op;
   1222  1.5  christos 
   1223  1.5  christos 	pair_op = (const struct mips_reg_pair_operand *) operand;
   1224  1.5  christos 	print_reg (info, opcode, pair_op->reg_type,
   1225  1.5  christos 		   pair_op->reg1_map[uval]);
   1226  1.5  christos 	infprintf (is, ",");
   1227  1.5  christos 	print_reg (info, opcode, pair_op->reg_type,
   1228  1.1     skrll 		   pair_op->reg2_map[uval]);
   1229  1.5  christos       }
   1230  1.5  christos       break;
   1231  1.5  christos 
   1232  1.1     skrll     case OP_PCREL:
   1233  1.5  christos       {
   1234  1.5  christos 	const struct mips_pcrel_operand *pcrel_op;
   1235  1.1     skrll 
   1236  1.5  christos 	pcrel_op = (const struct mips_pcrel_operand *) operand;
   1237  1.5  christos 	info->target = mips_decode_pcrel_operand (pcrel_op, base_pc, uval);
   1238  1.5  christos 
   1239  1.5  christos 	/* Preserve the ISA bit for the GDB disassembler,
   1240  1.1     skrll 	   otherwise clear it.  */
   1241  1.5  christos 	if (info->flavour != bfd_target_unknown_flavour)
   1242  1.5  christos 	  info->target &= -2;
   1243  1.5  christos 
   1244  1.1     skrll 	(*info->print_address_func) (info->target, info);
   1245  1.5  christos       }
   1246  1.5  christos       break;
   1247  1.5  christos 
   1248  1.1     skrll     case OP_PERF_REG:
   1249  1.5  christos       infprintf (is, "%d", uval);
   1250  1.5  christos       break;
   1251  1.5  christos 
   1252  1.1     skrll     case OP_ADDIUSP_INT:
   1253  1.5  christos       {
   1254  1.5  christos 	int sval;
   1255  1.5  christos 
   1256  1.5  christos 	sval = mips_signed_operand (operand, uval) * 4;
   1257  1.5  christos 	if (sval >= -8 && sval < 8)
   1258  1.5  christos 	  sval ^= 0x400;
   1259  1.1     skrll 	infprintf (is, "%d", sval);
   1260  1.5  christos 	break;
   1261  1.5  christos       }
   1262  1.5  christos 
   1263  1.1     skrll     case OP_CLO_CLZ_DEST:
   1264  1.5  christos       {
   1265  1.5  christos 	unsigned int reg1, reg2;
   1266  1.5  christos 
   1267  1.5  christos 	reg1 = uval & 31;
   1268  1.5  christos 	reg2 = uval >> 5;
   1269  1.5  christos 	/* If one is zero use the other.  */
   1270  1.5  christos 	if (reg1 == reg2 || reg2 == 0)
   1271  1.5  christos 	  infprintf (is, "%s", mips_gpr_names[reg1]);
   1272  1.5  christos 	else if (reg1 == 0)
   1273  1.5  christos 	  infprintf (is, "%s", mips_gpr_names[reg2]);
   1274  1.5  christos 	else
   1275  1.5  christos 	  /* Bogus, result depends on processor.  */
   1276  1.5  christos 	  infprintf (is, "%s or %s", mips_gpr_names[reg1],
   1277  1.5  christos 		     mips_gpr_names[reg2]);
   1278  1.5  christos       }
   1279  1.5  christos       break;
   1280  1.5  christos 
   1281  1.5  christos     case OP_SAME_RS_RT:
   1282  1.5  christos     case OP_CHECK_PREV:
   1283  1.5  christos     case OP_NON_ZERO_REG:
   1284  1.5  christos       {
   1285  1.5  christos 	print_reg (info, opcode, OP_REG_GP, uval & 31);
   1286  1.5  christos 	mips_seen_register (state, uval, OP_REG_GP);
   1287  1.5  christos       }
   1288  1.5  christos       break;
   1289  1.5  christos 
   1290  1.5  christos     case OP_LWM_SWM_LIST:
   1291  1.5  christos       if (operand->size == 2)
   1292  1.5  christos 	{
   1293  1.5  christos 	  if (uval == 0)
   1294  1.5  christos 	    infprintf (is, "%s,%s",
   1295  1.5  christos 		       mips_gpr_names[16],
   1296  1.5  christos 		       mips_gpr_names[31]);
   1297  1.5  christos 	  else
   1298  1.5  christos 	    infprintf (is, "%s-%s,%s",
   1299  1.5  christos 		       mips_gpr_names[16],
   1300  1.5  christos 		       mips_gpr_names[16 + uval],
   1301  1.5  christos 		       mips_gpr_names[31]);
   1302  1.5  christos 	}
   1303  1.5  christos       else
   1304  1.5  christos 	{
   1305  1.5  christos 	  int s_reg_encode;
   1306  1.5  christos 
   1307  1.5  christos 	  s_reg_encode = uval & 0xf;
   1308  1.5  christos 	  if (s_reg_encode != 0)
   1309  1.5  christos 	    {
   1310  1.5  christos 	      if (s_reg_encode == 1)
   1311  1.5  christos 		infprintf (is, "%s", mips_gpr_names[16]);
   1312  1.5  christos 	      else if (s_reg_encode < 9)
   1313  1.5  christos 		infprintf (is, "%s-%s",
   1314  1.5  christos 			   mips_gpr_names[16],
   1315  1.5  christos 			   mips_gpr_names[15 + s_reg_encode]);
   1316  1.5  christos 	      else if (s_reg_encode == 9)
   1317  1.5  christos 		infprintf (is, "%s-%s,%s",
   1318  1.5  christos 			   mips_gpr_names[16],
   1319  1.5  christos 			   mips_gpr_names[23],
   1320  1.5  christos 			   mips_gpr_names[30]);
   1321  1.5  christos 	      else
   1322  1.5  christos 		infprintf (is, "UNKNOWN");
   1323  1.5  christos 	    }
   1324  1.5  christos 
   1325  1.5  christos 	  if (uval & 0x10) /* For ra.  */
   1326  1.5  christos 	    {
   1327  1.5  christos 	      if (s_reg_encode == 0)
   1328  1.5  christos 		infprintf (is, "%s", mips_gpr_names[31]);
   1329  1.5  christos 	      else
   1330  1.5  christos 		infprintf (is, ",%s", mips_gpr_names[31]);
   1331  1.5  christos 	    }
   1332  1.5  christos 	}
   1333  1.5  christos       break;
   1334  1.5  christos 
   1335  1.5  christos     case OP_ENTRY_EXIT_LIST:
   1336  1.5  christos       {
   1337  1.5  christos 	const char *sep;
   1338  1.5  christos 	unsigned int amask, smask;
   1339  1.5  christos 
   1340  1.1     skrll 	sep = "";
   1341  1.5  christos 	amask = (uval >> 3) & 7;
   1342  1.5  christos 	if (amask > 0 && amask < 5)
   1343  1.5  christos 	  {
   1344  1.5  christos 	    infprintf (is, "%s", mips_gpr_names[4]);
   1345  1.5  christos 	    if (amask > 1)
   1346  1.5  christos 	      infprintf (is, "-%s", mips_gpr_names[amask + 3]);
   1347  1.5  christos 	    sep = ",";
   1348  1.5  christos 	  }
   1349  1.5  christos 
   1350  1.5  christos 	smask = (uval >> 1) & 3;
   1351  1.5  christos 	if (smask == 3)
   1352  1.5  christos 	  {
   1353  1.5  christos 	    infprintf (is, "%s??", sep);
   1354  1.5  christos 	    sep = ",";
   1355  1.5  christos 	  }
   1356  1.5  christos 	else if (smask > 0)
   1357  1.5  christos 	  {
   1358  1.5  christos 	    infprintf (is, "%s%s", sep, mips_gpr_names[16]);
   1359  1.5  christos 	    if (smask > 1)
   1360  1.5  christos 	      infprintf (is, "-%s", mips_gpr_names[smask + 15]);
   1361  1.5  christos 	    sep = ",";
   1362  1.5  christos 	  }
   1363  1.5  christos 
   1364  1.5  christos 	if (uval & 1)
   1365  1.5  christos 	  {
   1366  1.5  christos 	    infprintf (is, "%s%s", sep, mips_gpr_names[31]);
   1367  1.5  christos 	    sep = ",";
   1368  1.5  christos 	  }
   1369  1.5  christos 
   1370  1.5  christos 	if (amask == 5 || amask == 6)
   1371  1.5  christos 	  {
   1372  1.5  christos 	    infprintf (is, "%s%s", sep, mips_fpr_names[0]);
   1373  1.5  christos 	    if (amask == 6)
   1374  1.5  christos 	      infprintf (is, "-%s", mips_fpr_names[1]);
   1375  1.5  christos 	  }
   1376  1.5  christos       }
   1377  1.5  christos       break;
   1378  1.5  christos 
   1379  1.5  christos     case OP_SAVE_RESTORE_LIST:
   1380  1.5  christos       /* Should be handled by the caller due to extend behavior.  */
   1381  1.5  christos       abort ();
   1382  1.5  christos 
   1383  1.5  christos     case OP_MDMX_IMM_REG:
   1384  1.5  christos       {
   1385  1.5  christos 	unsigned int vsel;
   1386  1.5  christos 
   1387  1.5  christos 	vsel = uval >> 5;
   1388  1.5  christos 	uval &= 31;
   1389  1.5  christos 	if ((vsel & 0x10) == 0)
   1390  1.5  christos 	  {
   1391  1.5  christos 	    int fmt;
   1392  1.5  christos 
   1393  1.5  christos 	    vsel &= 0x0f;
   1394  1.5  christos 	    for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
   1395  1.5  christos 	      if ((vsel & 1) == 0)
   1396  1.1     skrll 		break;
   1397  1.5  christos 	    print_reg (info, opcode, OP_REG_VEC, uval);
   1398  1.5  christos 	    infprintf (is, "[%d]", vsel >> 1);
   1399  1.5  christos 	  }
   1400  1.5  christos 	else if ((vsel & 0x08) == 0)
   1401  1.5  christos 	  print_reg (info, opcode, OP_REG_VEC, uval);
   1402  1.5  christos 	else
   1403  1.1     skrll 	  infprintf (is, "0x%x", uval);
   1404  1.5  christos       }
   1405  1.5  christos       break;
   1406  1.5  christos 
   1407  1.1     skrll     case OP_REPEAT_PREV_REG:
   1408  1.5  christos       print_reg (info, opcode, state->last_reg_type, state->last_regno);
   1409  1.5  christos       break;
   1410  1.5  christos 
   1411  1.1     skrll     case OP_REPEAT_DEST_REG:
   1412  1.5  christos       print_reg (info, opcode, state->last_reg_type, state->dest_regno);
   1413  1.5  christos       break;
   1414  1.5  christos 
   1415  1.1     skrll     case OP_PC:
   1416  1.5  christos       infprintf (is, "$pc");
   1417  1.5  christos       break;
   1418  1.5  christos 
   1419  1.5  christos     case OP_VU0_SUFFIX:
   1420  1.1     skrll     case OP_VU0_MATCH_SUFFIX:
   1421  1.5  christos       print_vu0_channel (info, operand, uval);
   1422  1.5  christos       break;
   1423  1.5  christos 
   1424  1.1     skrll     case OP_IMM_INDEX:
   1425  1.5  christos       infprintf (is, "[%d]", uval);
   1426  1.5  christos       break;
   1427  1.5  christos 
   1428  1.5  christos     case OP_REG_INDEX:
   1429  1.5  christos       infprintf (is, "[");
   1430  1.5  christos       print_reg (info, opcode, OP_REG_GP, uval);
   1431  1.5  christos       infprintf (is, "]");
   1432  1.1     skrll       break;
   1433  1.5  christos     }
   1434  1.5  christos }
   1435  1.1     skrll 
   1436  1.5  christos /* Validate the arguments for INSN, which is described by OPCODE.
   1437  1.5  christos    Use DECODE_OPERAND to get the encoding of each operand.  */
   1438  1.5  christos 
   1439  1.5  christos static bfd_boolean
   1440  1.5  christos validate_insn_args (const struct mips_opcode *opcode,
   1441  1.5  christos 		    const struct mips_operand *(*decode_operand) (const char *),
   1442  1.5  christos 		    unsigned int insn)
   1443  1.5  christos {
   1444  1.5  christos   struct mips_print_arg_state state;
   1445  1.1     skrll   const struct mips_operand *operand;
   1446  1.5  christos   const char *s;
   1447  1.5  christos   unsigned int uval;
   1448  1.5  christos 
   1449  1.5  christos   init_print_arg_state (&state);
   1450  1.5  christos   for (s = opcode->args; *s; ++s)
   1451  1.5  christos     {
   1452  1.5  christos       switch (*s)
   1453  1.5  christos 	{
   1454  1.1     skrll 	case ',':
   1455  1.1     skrll 	case '(':
   1456  1.5  christos 	case ')':
   1457  1.5  christos 	  break;
   1458  1.1     skrll 
   1459  1.1     skrll 	case '#':
   1460  1.5  christos 	  ++s;
   1461  1.5  christos 	  break;
   1462  1.1     skrll 
   1463  1.5  christos 	default:
   1464  1.5  christos 	  operand = decode_operand (s);
   1465  1.5  christos 
   1466  1.5  christos 	  if (operand)
   1467  1.5  christos 	    {
   1468  1.5  christos 	      uval = mips_extract_operand (operand, insn);
   1469  1.5  christos 	      switch (operand->type)
   1470  1.5  christos 		{
   1471  1.5  christos 		case OP_REG:
   1472  1.1     skrll 		case OP_OPTIONAL_REG:
   1473  1.5  christos 		  {
   1474  1.5  christos 		    const struct mips_reg_operand *reg_op;
   1475  1.5  christos 
   1476  1.5  christos 		    reg_op = (const struct mips_reg_operand *) operand;
   1477  1.5  christos 		    uval = mips_decode_reg_operand (reg_op, uval);
   1478  1.1     skrll 		    mips_seen_register (&state, uval, reg_op->reg_type);
   1479  1.5  christos 		  }
   1480  1.5  christos 		break;
   1481  1.5  christos 
   1482  1.1     skrll 		case OP_SAME_RS_RT:
   1483  1.5  christos 		  {
   1484  1.5  christos 		    unsigned int reg1, reg2;
   1485  1.1     skrll 
   1486  1.5  christos 		    reg1 = uval & 31;
   1487  1.5  christos 		    reg2 = uval >> 5;
   1488  1.5  christos 
   1489  1.5  christos 		    if (reg1 != reg2 || reg1 == 0)
   1490  1.1     skrll 		      return FALSE;
   1491  1.5  christos 		  }
   1492  1.5  christos 		break;
   1493  1.5  christos 
   1494  1.1     skrll 		case OP_CHECK_PREV:
   1495  1.5  christos 		  {
   1496  1.1     skrll 		    const struct mips_check_prev_operand *prev_op;
   1497  1.5  christos 
   1498  1.5  christos 		    prev_op = (const struct mips_check_prev_operand *) operand;
   1499  1.1     skrll 
   1500  1.5  christos 		    if (!prev_op->zero_ok && uval == 0)
   1501  1.5  christos 		      return FALSE;
   1502  1.5  christos 
   1503  1.5  christos 		    if (((prev_op->less_than_ok && uval < state.last_regno)
   1504  1.1     skrll 			|| (prev_op->greater_than_ok && uval > state.last_regno)
   1505  1.5  christos 			|| (prev_op->equal_ok && uval == state.last_regno)))
   1506  1.5  christos 		      break;
   1507  1.1     skrll 
   1508  1.5  christos 		    return FALSE;
   1509  1.5  christos 		  }
   1510  1.5  christos 
   1511  1.5  christos 		case OP_NON_ZERO_REG:
   1512  1.5  christos 		  {
   1513  1.5  christos 		    if (uval == 0)
   1514  1.1     skrll 		      return FALSE;
   1515  1.5  christos 		  }
   1516  1.5  christos 		break;
   1517  1.5  christos 
   1518  1.5  christos 		case OP_INT:
   1519  1.5  christos 		case OP_MAPPED_INT:
   1520  1.5  christos 		case OP_MSB:
   1521  1.5  christos 		case OP_REG_PAIR:
   1522  1.5  christos 		case OP_PCREL:
   1523  1.5  christos 		case OP_PERF_REG:
   1524  1.5  christos 		case OP_ADDIUSP_INT:
   1525  1.5  christos 		case OP_CLO_CLZ_DEST:
   1526  1.5  christos 		case OP_LWM_SWM_LIST:
   1527  1.5  christos 		case OP_ENTRY_EXIT_LIST:
   1528  1.5  christos 		case OP_MDMX_IMM_REG:
   1529  1.5  christos 		case OP_REPEAT_PREV_REG:
   1530  1.5  christos 		case OP_REPEAT_DEST_REG:
   1531  1.5  christos 		case OP_PC:
   1532  1.5  christos 		case OP_VU0_SUFFIX:
   1533  1.5  christos 		case OP_VU0_MATCH_SUFFIX:
   1534  1.1     skrll 		case OP_IMM_INDEX:
   1535  1.5  christos 		case OP_REG_INDEX:
   1536  1.5  christos 		  break;
   1537  1.5  christos 
   1538  1.5  christos 		case OP_SAVE_RESTORE_LIST:
   1539  1.5  christos 		/* Should be handled by the caller due to extend behavior.  */
   1540  1.5  christos 		  abort ();
   1541  1.5  christos 		}
   1542  1.5  christos 	    }
   1543  1.5  christos 	  if (*s == 'm' || *s == '+' || *s == '-')
   1544  1.5  christos 	    ++s;
   1545  1.5  christos 	}
   1546  1.1     skrll     }
   1547  1.5  christos   return TRUE;
   1548  1.5  christos }
   1549  1.5  christos 
   1550  1.5  christos /* Print the arguments for INSN, which is described by OPCODE.
   1551  1.1     skrll    Use DECODE_OPERAND to get the encoding of each operand.  Use BASE_PC
   1552  1.5  christos    as the base of OP_PCREL operands, adjusting by LENGTH if the OP_PCREL
   1553  1.5  christos    operand is for a branch or jump.  */
   1554  1.5  christos 
   1555  1.5  christos static void
   1556  1.5  christos print_insn_args (struct disassemble_info *info,
   1557  1.5  christos 		 const struct mips_opcode *opcode,
   1558  1.5  christos 		 const struct mips_operand *(*decode_operand) (const char *),
   1559  1.5  christos 		 unsigned int insn, bfd_vma insn_pc, unsigned int length)
   1560  1.5  christos {
   1561  1.5  christos   const fprintf_ftype infprintf = info->fprintf_func;
   1562  1.5  christos   void *is = info->stream;
   1563  1.1     skrll   struct mips_print_arg_state state;
   1564  1.5  christos   const struct mips_operand *operand;
   1565  1.5  christos   const char *s;
   1566  1.5  christos 
   1567  1.5  christos   init_print_arg_state (&state);
   1568  1.5  christos   for (s = opcode->args; *s; ++s)
   1569  1.5  christos     {
   1570  1.5  christos       switch (*s)
   1571  1.5  christos 	{
   1572  1.5  christos 	case ',':
   1573  1.1     skrll 	case '(':
   1574  1.1     skrll 	case ')':
   1575  1.5  christos 	  infprintf (is, "%c", *s);
   1576  1.5  christos 	  break;
   1577  1.5  christos 
   1578  1.1     skrll 	case '#':
   1579  1.1     skrll 	  ++s;
   1580  1.1     skrll 	  infprintf (is, "%c%c", *s, *s);
   1581  1.5  christos 	  break;
   1582  1.5  christos 
   1583  1.5  christos 	default:
   1584  1.5  christos 	  operand = decode_operand (s);
   1585  1.5  christos 	  if (!operand)
   1586  1.5  christos 	    {
   1587  1.5  christos 	      /* xgettext:c-format */
   1588  1.5  christos 	      infprintf (is,
   1589  1.5  christos 			 _("# internal error, undefined operand in `%s %s'"),
   1590  1.5  christos 			 opcode->name, opcode->args);
   1591  1.5  christos 	      return;
   1592  1.5  christos 	    }
   1593  1.5  christos 	  if (operand->type == OP_REG
   1594  1.5  christos 	      && s[1] == ','
   1595  1.5  christos 	      && s[2] == 'H'
   1596  1.5  christos 	      && opcode->name[strlen (opcode->name) - 1] == '0')
   1597  1.5  christos 	    {
   1598  1.5  christos 	      /* Coprocessor register 0 with sel field (MT ASE).  */
   1599  1.5  christos 	      const struct mips_cp0sel_name *n;
   1600  1.5  christos 	      unsigned int reg, sel;
   1601  1.5  christos 
   1602  1.5  christos 	      reg = mips_extract_operand (operand, insn);
   1603  1.5  christos 	      s += 2;
   1604  1.5  christos 	      operand = decode_operand (s);
   1605  1.5  christos 	      sel = mips_extract_operand (operand, insn);
   1606  1.5  christos 
   1607  1.5  christos 	      /* CP0 register including 'sel' code for mftc0, to be
   1608  1.5  christos 		 printed textually if known.  If not known, print both
   1609  1.5  christos 		 CP0 register name and sel numerically since CP0 register
   1610  1.5  christos 		 with sel 0 may have a name unrelated to register being
   1611  1.5  christos 		 printed.  */
   1612  1.5  christos 	      n = lookup_mips_cp0sel_name (mips_cp0sel_names,
   1613  1.5  christos 					   mips_cp0sel_names_len,
   1614  1.5  christos 					   reg, sel);
   1615  1.5  christos 	      if (n != NULL)
   1616  1.5  christos 		infprintf (is, "%s", n->name);
   1617  1.5  christos 	      else
   1618  1.5  christos 		infprintf (is, "$%d,%d", reg, sel);
   1619  1.5  christos 	    }
   1620  1.5  christos 	  else
   1621  1.5  christos 	    {
   1622  1.5  christos 	      bfd_vma base_pc = insn_pc;
   1623  1.5  christos 
   1624  1.5  christos 	      /* Adjust the PC relative base so that branch/jump insns use
   1625  1.5  christos 		 the following PC as the base but genuinely PC relative
   1626  1.5  christos 		 operands use the current PC.  */
   1627  1.5  christos 	      if (operand->type == OP_PCREL)
   1628  1.5  christos 		{
   1629  1.5  christos 		  const struct mips_pcrel_operand *pcrel_op;
   1630  1.5  christos 
   1631  1.5  christos 		  pcrel_op = (const struct mips_pcrel_operand *) operand;
   1632  1.5  christos 		  /* The include_isa_bit flag is sufficient to distinguish
   1633  1.5  christos 		     branch/jump from other PC relative operands.  */
   1634  1.5  christos 		  if (pcrel_op->include_isa_bit)
   1635  1.5  christos 		    base_pc += length;
   1636  1.5  christos 		}
   1637  1.5  christos 
   1638  1.5  christos 	      print_insn_arg (info, &state, opcode, operand, base_pc,
   1639  1.5  christos 			      mips_extract_operand (operand, insn));
   1640  1.5  christos 	    }
   1641  1.1     skrll 	  if (*s == 'm' || *s == '+' || *s == '-')
   1642  1.1     skrll 	    ++s;
   1643  1.1     skrll 	  break;
   1644  1.1     skrll 	}
   1645  1.1     skrll     }
   1646  1.1     skrll }
   1647  1.1     skrll 
   1648  1.1     skrll /* Print the mips instruction at address MEMADDR in debugged memory,
   1650  1.1     skrll    on using INFO.  Returns length of the instruction, in bytes, which is
   1651  1.1     skrll    always INSNLEN.  BIGENDIAN must be 1 if this is big-endian code, 0 if
   1652  1.4  christos    this is little-endian code.  */
   1653  1.1     skrll 
   1654  1.1     skrll static int
   1655  1.5  christos print_insn_mips (bfd_vma memaddr,
   1656  1.5  christos 		 int word,
   1657  1.4  christos 		 struct disassemble_info *info)
   1658  1.4  christos {
   1659  1.1     skrll #define GET_OP(insn, field)			\
   1660  1.1     skrll   (((insn) >> OP_SH_##field) & OP_MASK_##field)
   1661  1.4  christos   static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
   1662  1.1     skrll   const fprintf_ftype infprintf = info->fprintf_func;
   1663  1.1     skrll   const struct mips_opcode *op;
   1664  1.1     skrll   static bfd_boolean init = 0;
   1665  1.1     skrll   void *is = info->stream;
   1666  1.1     skrll 
   1667  1.1     skrll   /* Build a hash table to shorten the search time.  */
   1668  1.1     skrll   if (! init)
   1669  1.1     skrll     {
   1670  1.1     skrll       unsigned int i;
   1671  1.1     skrll 
   1672  1.1     skrll       for (i = 0; i <= OP_MASK_OP; i++)
   1673  1.1     skrll 	{
   1674  1.1     skrll 	  for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
   1675  1.4  christos 	    {
   1676  1.1     skrll 	      if (op->pinfo == INSN_MACRO
   1677  1.1     skrll 		  || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
   1678  1.1     skrll 		continue;
   1679  1.1     skrll 	      if (i == GET_OP (op->match, OP))
   1680  1.1     skrll 		{
   1681  1.1     skrll 		  mips_hash[i] = op;
   1682  1.1     skrll 		  break;
   1683  1.1     skrll 		}
   1684  1.1     skrll 	    }
   1685  1.1     skrll 	}
   1686  1.1     skrll 
   1687  1.1     skrll       init = 1;
   1688  1.1     skrll     }
   1689  1.1     skrll 
   1690  1.1     skrll   info->bytes_per_chunk = INSNLEN;
   1691  1.1     skrll   info->display_endian = info->endian;
   1692  1.1     skrll   info->insn_info_valid = 1;
   1693  1.1     skrll   info->branch_delay_insns = 0;
   1694  1.1     skrll   info->data_size = 0;
   1695  1.4  christos   info->insn_type = dis_nonbranch;
   1696  1.1     skrll   info->target = 0;
   1697  1.1     skrll   info->target2 = 0;
   1698  1.1     skrll 
   1699  1.1     skrll   op = mips_hash[GET_OP (word, OP)];
   1700  1.5  christos   if (op != NULL)
   1701  1.1     skrll     {
   1702  1.1     skrll       for (; op < &mips_opcodes[NUMOPCODES]; op++)
   1703  1.1     skrll 	{
   1704  1.5  christos 	  if (op->pinfo != INSN_MACRO
   1705  1.5  christos 	      && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
   1706  1.5  christos 	      && (word & op->mask) == op->match)
   1707  1.5  christos 	    {
   1708  1.5  christos 	      /* We always disassemble the jalx instruction, except for MIPS r6.  */
   1709  1.1     skrll 	      if (!opcode_is_member (op, mips_isa, mips_ase, mips_processor)
   1710  1.1     skrll 		 && (strcmp (op->name, "jalx")
   1711  1.1     skrll 		     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS32R6
   1712  1.1     skrll 		     || (mips_isa & INSN_ISA_MASK) == ISA_MIPS64R6))
   1713  1.1     skrll 		continue;
   1714  1.5  christos 
   1715  1.1     skrll 	      /* Figure out instruction type and branch delay information.  */
   1716  1.1     skrll 	      if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
   1717  1.1     skrll 	        {
   1718  1.1     skrll 		  if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
   1719  1.1     skrll 		    info->insn_type = dis_jsr;
   1720  1.1     skrll 		  else
   1721  1.1     skrll 		    info->insn_type = dis_branch;
   1722  1.1     skrll 		  info->branch_delay_insns = 1;
   1723  1.3  christos 		}
   1724  1.1     skrll 	      else if ((op->pinfo & (INSN_COND_BRANCH_DELAY
   1725  1.1     skrll 				     | INSN_COND_BRANCH_LIKELY)) != 0)
   1726  1.1     skrll 		{
   1727  1.1     skrll 		  if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
   1728  1.1     skrll 		    info->insn_type = dis_condjsr;
   1729  1.1     skrll 		  else
   1730  1.5  christos 		    info->insn_type = dis_condbranch;
   1731  1.1     skrll 		  info->branch_delay_insns = 1;
   1732  1.1     skrll 		}
   1733  1.5  christos 	      else if ((op->pinfo & (INSN_STORE_MEMORY
   1734  1.5  christos 				     | INSN_LOAD_MEMORY)) != 0)
   1735  1.5  christos 		info->insn_type = dis_dref;
   1736  1.4  christos 
   1737  1.5  christos 	      if (!validate_insn_args (op, decode_mips_operand, word))
   1738  1.5  christos 		continue;
   1739  1.5  christos 
   1740  1.5  christos 	      infprintf (is, "%s", op->name);
   1741  1.5  christos 	      if (op->pinfo2 & INSN2_VU0_CHANNEL_SUFFIX)
   1742  1.5  christos 		{
   1743  1.5  christos 		  unsigned int uval;
   1744  1.5  christos 
   1745  1.1     skrll 		  infprintf (is, ".");
   1746  1.5  christos 		  uval = mips_extract_operand (&mips_vu0_channel_mask, word);
   1747  1.1     skrll 		  print_vu0_channel (info, &mips_vu0_channel_mask, uval);
   1748  1.4  christos 		}
   1749  1.5  christos 
   1750  1.5  christos 	      if (op->args[0])
   1751  1.1     skrll 		{
   1752  1.1     skrll 		  infprintf (is, "\t");
   1753  1.1     skrll 		  print_insn_args (info, op, decode_mips_operand, word,
   1754  1.1     skrll 				   memaddr, 4);
   1755  1.1     skrll 		}
   1756  1.1     skrll 
   1757  1.4  christos 	      return INSNLEN;
   1758  1.1     skrll 	    }
   1759  1.1     skrll 	}
   1760  1.1     skrll     }
   1761  1.4  christos #undef GET_OP
   1762  1.1     skrll 
   1763  1.1     skrll   /* Handle undefined instructions.  */
   1764  1.1     skrll   info->insn_type = dis_noninsn;
   1765  1.1     skrll   infprintf (is, "0x%x", word);
   1766  1.1     skrll   return INSNLEN;
   1767  1.1     skrll }
   1768  1.5  christos 
   1769  1.5  christos /* Disassemble an operand for a mips16 instruction.  */
   1771  1.5  christos 
   1772  1.5  christos static void
   1773  1.5  christos print_mips16_insn_arg (struct disassemble_info *info,
   1774  1.1     skrll 		       struct mips_print_arg_state *state,
   1775  1.4  christos 		       const struct mips_opcode *opcode,
   1776  1.4  christos 		       char type, bfd_vma memaddr,
   1777  1.5  christos 		       unsigned insn, bfd_boolean use_extend,
   1778  1.5  christos 		       unsigned extend, bfd_boolean is_offset)
   1779  1.5  christos {
   1780  1.5  christos   const fprintf_ftype infprintf = info->fprintf_func;
   1781  1.5  christos   void *is = info->stream;
   1782  1.5  christos   const struct mips_operand *operand, *ext_operand;
   1783  1.4  christos   unsigned int uval;
   1784  1.1     skrll   bfd_vma baseaddr;
   1785  1.1     skrll 
   1786  1.1     skrll   if (!use_extend)
   1787  1.1     skrll     extend = 0;
   1788  1.1     skrll 
   1789  1.4  christos   switch (type)
   1790  1.1     skrll     {
   1791  1.1     skrll     case ',':
   1792  1.5  christos     case '(':
   1793  1.5  christos     case ')':
   1794  1.5  christos       infprintf (is, "%c", type);
   1795  1.5  christos       break;
   1796  1.5  christos 
   1797  1.5  christos     default:
   1798  1.5  christos       operand = decode_mips16_operand (type, FALSE);
   1799  1.5  christos       if (!operand)
   1800  1.5  christos 	{
   1801  1.1     skrll 	  /* xgettext:c-format */
   1802  1.5  christos 	  infprintf (is, _("# internal error, undefined operand in `%s %s'"),
   1803  1.5  christos 		     opcode->name, opcode->args);
   1804  1.5  christos 	  return;
   1805  1.5  christos 	}
   1806  1.5  christos 
   1807  1.5  christos       if (operand->type == OP_SAVE_RESTORE_LIST)
   1808  1.1     skrll 	{
   1809  1.5  christos 	  /* Handle this case here because of the complex interation
   1810  1.5  christos 	     with the EXTEND opcode.  */
   1811  1.5  christos 	  unsigned int amask, nargs, nstatics, nsreg, smask, frame_size, i, j;
   1812  1.5  christos 	  const char *sep;
   1813  1.5  christos 
   1814  1.5  christos 	  amask = extend & 0xf;
   1815  1.5  christos 	  if (amask == MIPS16_ALL_ARGS)
   1816  1.5  christos 	    {
   1817  1.5  christos 	      nargs = 4;
   1818  1.5  christos 	      nstatics = 0;
   1819  1.5  christos 	    }
   1820  1.5  christos 	  else if (amask == MIPS16_ALL_STATICS)
   1821  1.5  christos 	    {
   1822  1.5  christos 	      nargs = 0;
   1823  1.5  christos 	      nstatics = 4;
   1824  1.5  christos 	    }
   1825  1.1     skrll 	  else
   1826  1.5  christos 	    {
   1827  1.5  christos 	      nargs = amask >> 2;
   1828  1.5  christos 	      nstatics = amask & 3;
   1829  1.5  christos 	    }
   1830  1.5  christos 
   1831  1.5  christos 	  sep = "";
   1832  1.5  christos 	  if (nargs > 0)
   1833  1.5  christos 	    {
   1834  1.1     skrll 	      infprintf (is, "%s", mips_gpr_names[4]);
   1835  1.5  christos 	      if (nargs > 1)
   1836  1.5  christos 		infprintf (is, "-%s", mips_gpr_names[4 + nargs - 1]);
   1837  1.5  christos 	      sep = ",";
   1838  1.5  christos 	    }
   1839  1.5  christos 
   1840  1.5  christos 	  frame_size = ((extend & 0xf0) | (insn & 0x0f)) * 8;
   1841  1.5  christos 	  if (frame_size == 0 && !use_extend)
   1842  1.5  christos 	    frame_size = 128;
   1843  1.5  christos 	  infprintf (is, "%s%d", sep, frame_size);
   1844  1.5  christos 
   1845  1.5  christos 	  if (insn & 0x40)		/* $ra */
   1846  1.5  christos 	    infprintf (is, ",%s", mips_gpr_names[31]);
   1847  1.5  christos 
   1848  1.5  christos 	  nsreg = (extend >> 8) & 0x7;
   1849  1.5  christos 	  smask = 0;
   1850  1.5  christos 	  if (insn & 0x20)		/* $s0 */
   1851  1.1     skrll 	    smask |= 1 << 0;
   1852  1.5  christos 	  if (insn & 0x10)		/* $s1 */
   1853  1.5  christos 	    smask |= 1 << 1;
   1854  1.1     skrll 	  if (nsreg > 0)		/* $s2-$s8 */
   1855  1.5  christos 	    smask |= ((1 << nsreg) - 1) << 2;
   1856  1.5  christos 
   1857  1.5  christos 	  for (i = 0; i < 9; i++)
   1858  1.5  christos 	    if (smask & (1 << i))
   1859  1.5  christos 	      {
   1860  1.5  christos 		infprintf (is, ",%s", mips_gpr_names[i == 8 ? 30 : (16 + i)]);
   1861  1.5  christos 		/* Skip over string of set bits.  */
   1862  1.1     skrll 		for (j = i; smask & (2 << j); j++)
   1863  1.5  christos 		  continue;
   1864  1.5  christos 		if (j > i)
   1865  1.5  christos 		  infprintf (is, "-%s", mips_gpr_names[j == 8 ? 30 : (16 + j)]);
   1866  1.5  christos 		i = j + 1;
   1867  1.5  christos 	      }
   1868  1.5  christos 	  /* Statics $ax - $a3.  */
   1869  1.5  christos 	  if (nstatics == 1)
   1870  1.5  christos 	    infprintf (is, ",%s", mips_gpr_names[7]);
   1871  1.5  christos 	  else if (nstatics > 0)
   1872  1.1     skrll 	    infprintf (is, ",%s-%s",
   1873  1.5  christos 		       mips_gpr_names[7 - nstatics + 1],
   1874  1.5  christos 		       mips_gpr_names[7]);
   1875  1.5  christos 	  break;
   1876  1.1     skrll 	}
   1877  1.5  christos 
   1878  1.5  christos       if (is_offset && operand->type == OP_INT)
   1879  1.5  christos 	{
   1880  1.5  christos 	  const struct mips_int_operand *int_op;
   1881  1.1     skrll 
   1882  1.5  christos 	  int_op = (const struct mips_int_operand *) operand;
   1883  1.5  christos 	  info->insn_type = dis_dref;
   1884  1.5  christos 	  info->data_size = 1 << int_op->shift;
   1885  1.5  christos 	}
   1886  1.5  christos 
   1887  1.5  christos       if (operand->size == 26)
   1888  1.5  christos 	/* In this case INSN is the first two bytes of the instruction
   1889  1.5  christos 	   and EXTEND is the second two bytes.  */
   1890  1.5  christos 	uval = ((insn & 0x1f) << 21) | ((insn & 0x3e0) << 11) | extend;
   1891  1.5  christos       else
   1892  1.5  christos 	{
   1893  1.5  christos 	  /* Calculate the full field value.  */
   1894  1.5  christos 	  uval = mips_extract_operand (operand, insn);
   1895  1.5  christos 	  if (use_extend)
   1896  1.5  christos 	    {
   1897  1.5  christos 	      ext_operand = decode_mips16_operand (type, TRUE);
   1898  1.5  christos 	      if (ext_operand != operand)
   1899  1.5  christos 		{
   1900  1.5  christos 		  operand = ext_operand;
   1901  1.5  christos 		  if (operand->size == 16)
   1902  1.5  christos 		    uval |= ((extend & 0x1f) << 11) | (extend & 0x7e0);
   1903  1.5  christos 		  else if (operand->size == 15)
   1904  1.5  christos 		    uval |= ((extend & 0xf) << 11) | (extend & 0x7f0);
   1905  1.1     skrll 		  else
   1906  1.5  christos 		    uval = ((extend >> 6) & 0x1f) | (extend & 0x20);
   1907  1.5  christos 		}
   1908  1.5  christos 	    }
   1909  1.5  christos 	}
   1910  1.1     skrll 
   1911  1.5  christos       baseaddr = memaddr + 2;
   1912  1.5  christos       if (operand->type == OP_PCREL)
   1913  1.5  christos 	{
   1914  1.5  christos 	  const struct mips_pcrel_operand *pcrel_op;
   1915  1.5  christos 
   1916  1.5  christos 	  pcrel_op = (const struct mips_pcrel_operand *) operand;
   1917  1.5  christos 	  if (!pcrel_op->include_isa_bit && use_extend)
   1918  1.5  christos 	    baseaddr = memaddr - 2;
   1919  1.5  christos 	  else if (!pcrel_op->include_isa_bit)
   1920  1.5  christos 	     {
   1921  1.5  christos 	       bfd_byte buffer[2];
   1922  1.5  christos 
   1923  1.5  christos 	       /* If this instruction is in the delay slot of a JR
   1924  1.5  christos 		  instruction, the base address is the address of the
   1925  1.5  christos 		  JR instruction.  If it is in the delay slot of a JALR
   1926  1.5  christos 		  instruction, the base address is the address of the
   1927  1.5  christos 		  JALR instruction.  This test is unreliable: we have
   1928  1.5  christos 		  no way of knowing whether the previous word is
   1929  1.5  christos 		  instruction or data.  */
   1930  1.5  christos 	       if (info->read_memory_func (memaddr - 4, buffer, 2, info) == 0
   1931  1.5  christos 		   && (((info->endian == BFD_ENDIAN_BIG
   1932  1.5  christos 			 ? bfd_getb16 (buffer)
   1933  1.5  christos 			 : bfd_getl16 (buffer))
   1934  1.5  christos 			& 0xf800) == 0x1800))
   1935  1.5  christos 		 baseaddr = memaddr - 4;
   1936  1.5  christos 	       else if (info->read_memory_func (memaddr - 2, buffer, 2,
   1937  1.5  christos 						info) == 0
   1938  1.5  christos 			&& (((info->endian == BFD_ENDIAN_BIG
   1939  1.5  christos 			      ? bfd_getb16 (buffer)
   1940  1.5  christos 			      : bfd_getl16 (buffer))
   1941  1.5  christos 			     & 0xf81f) == 0xe800))
   1942  1.1     skrll 		 baseaddr = memaddr - 2;
   1943  1.5  christos 	       else
   1944  1.1     skrll 		 baseaddr = memaddr;
   1945  1.5  christos 	     }
   1946  1.5  christos 	}
   1947  1.1     skrll 
   1948  1.1     skrll       print_insn_arg (info, state, opcode, operand, baseaddr + 1, uval);
   1949  1.5  christos       break;
   1950  1.5  christos     }
   1951  1.5  christos }
   1952  1.5  christos 
   1953  1.5  christos 
   1954  1.5  christos /* Check if the given address is the last word of a MIPS16 PLT entry.
   1955  1.5  christos    This word is data and depending on the value it may interfere with
   1956  1.5  christos    disassembly of further PLT entries.  We make use of the fact PLT
   1957  1.5  christos    symbols are marked BSF_SYNTHETIC.  */
   1958  1.5  christos static bfd_boolean
   1959  1.5  christos is_mips16_plt_tail (struct disassemble_info *info, bfd_vma addr)
   1960  1.5  christos {
   1961  1.1     skrll   if (info->symbols
   1962  1.5  christos       && info->symbols[0]
   1963  1.1     skrll       && (info->symbols[0]->flags & BSF_SYNTHETIC)
   1964  1.1     skrll       && addr == bfd_asymbol_value (info->symbols[0]) + 12)
   1965  1.1     skrll     return TRUE;
   1966  1.1     skrll 
   1967  1.1     skrll   return FALSE;
   1968  1.1     skrll }
   1969  1.1     skrll 
   1970  1.4  christos /* Disassemble mips16 instructions.  */
   1971  1.1     skrll 
   1972  1.5  christos static int
   1973  1.1     skrll print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
   1974  1.1     skrll {
   1975  1.1     skrll   const fprintf_ftype infprintf = info->fprintf_func;
   1976  1.1     skrll   int status;
   1977  1.1     skrll   bfd_byte buffer[4];
   1978  1.5  christos   int length;
   1979  1.4  christos   int insn;
   1980  1.1     skrll   bfd_boolean use_extend;
   1981  1.1     skrll   int extend = 0;
   1982  1.1     skrll   const struct mips_opcode *op, *opend;
   1983  1.1     skrll   struct mips_print_arg_state state;
   1984  1.1     skrll   void *is = info->stream;
   1985  1.1     skrll 
   1986  1.1     skrll   info->bytes_per_chunk = 2;
   1987  1.1     skrll   info->display_endian = info->endian;
   1988  1.1     skrll   info->insn_info_valid = 1;
   1989  1.5  christos   info->branch_delay_insns = 0;
   1990  1.5  christos   info->data_size = 0;
   1991  1.5  christos   info->target = 0;
   1992  1.5  christos   info->target2 = 0;
   1993  1.5  christos 
   1994  1.5  christos #define GET_OP(insn, field) \
   1995  1.5  christos   (((insn) >> MIPS16OP_SH_##field) & MIPS16OP_MASK_##field)
   1996  1.5  christos   /* Decode PLT entry's GOT slot address word.  */
   1997  1.5  christos   if (is_mips16_plt_tail (info, memaddr))
   1998  1.5  christos     {
   1999  1.5  christos       info->insn_type = dis_noninsn;
   2000  1.5  christos       status = (*info->read_memory_func) (memaddr, buffer, 4, info);
   2001  1.5  christos       if (status == 0)
   2002  1.5  christos 	{
   2003  1.5  christos 	  unsigned int gotslot;
   2004  1.5  christos 
   2005  1.5  christos 	  if (info->endian == BFD_ENDIAN_BIG)
   2006  1.5  christos 	    gotslot = bfd_getb32 (buffer);
   2007  1.5  christos 	  else
   2008  1.5  christos 	    gotslot = bfd_getl32 (buffer);
   2009  1.5  christos 	  infprintf (is, ".word\t0x%x", gotslot);
   2010  1.5  christos 
   2011  1.5  christos 	  return 4;
   2012  1.5  christos 	}
   2013  1.5  christos     }
   2014  1.1     skrll   else
   2015  1.1     skrll     {
   2016  1.1     skrll       info->insn_type = dis_nonbranch;
   2017  1.1     skrll       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
   2018  1.1     skrll     }
   2019  1.1     skrll   if (status != 0)
   2020  1.1     skrll     {
   2021  1.1     skrll       (*info->memory_error_func) (status, memaddr, info);
   2022  1.1     skrll       return -1;
   2023  1.1     skrll     }
   2024  1.1     skrll 
   2025  1.1     skrll   length = 2;
   2026  1.1     skrll 
   2027  1.1     skrll   if (info->endian == BFD_ENDIAN_BIG)
   2028  1.1     skrll     insn = bfd_getb16 (buffer);
   2029  1.1     skrll   else
   2030  1.1     skrll     insn = bfd_getl16 (buffer);
   2031  1.1     skrll 
   2032  1.1     skrll   /* Handle the extend opcode specially.  */
   2033  1.1     skrll   use_extend = FALSE;
   2034  1.1     skrll   if ((insn & 0xf800) == 0xf000)
   2035  1.1     skrll     {
   2036  1.1     skrll       use_extend = TRUE;
   2037  1.1     skrll       extend = insn & 0x7ff;
   2038  1.1     skrll 
   2039  1.4  christos       memaddr += 2;
   2040  1.1     skrll 
   2041  1.1     skrll       status = (*info->read_memory_func) (memaddr, buffer, 2, info);
   2042  1.1     skrll       if (status != 0)
   2043  1.1     skrll 	{
   2044  1.1     skrll 	  infprintf (is, "extend 0x%x", (unsigned int) extend);
   2045  1.1     skrll 	  (*info->memory_error_func) (status, memaddr, info);
   2046  1.1     skrll 	  return -1;
   2047  1.1     skrll 	}
   2048  1.1     skrll 
   2049  1.1     skrll       if (info->endian == BFD_ENDIAN_BIG)
   2050  1.1     skrll 	insn = bfd_getb16 (buffer);
   2051  1.1     skrll       else
   2052  1.4  christos 	insn = bfd_getl16 (buffer);
   2053  1.1     skrll 
   2054  1.1     skrll       /* Check for an extend opcode followed by an extend opcode.  */
   2055  1.1     skrll       if ((insn & 0xf800) == 0xf000)
   2056  1.1     skrll 	{
   2057  1.1     skrll 	  infprintf (is, "extend 0x%x", (unsigned int) extend);
   2058  1.1     skrll 	  info->insn_type = dis_noninsn;
   2059  1.1     skrll 	  return length;
   2060  1.1     skrll 	}
   2061  1.1     skrll 
   2062  1.1     skrll       length += 2;
   2063  1.1     skrll     }
   2064  1.1     skrll 
   2065  1.1     skrll   /* FIXME: Should probably use a hash table on the major opcode here.  */
   2066  1.1     skrll 
   2067  1.1     skrll   opend = mips16_opcodes + bfd_mips16_num_opcodes;
   2068  1.1     skrll   for (op = mips16_opcodes; op < opend; op++)
   2069  1.1     skrll     {
   2070  1.1     skrll       if (op->pinfo != INSN_MACRO
   2071  1.5  christos 	  && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
   2072  1.1     skrll 	  && (insn & op->mask) == op->match)
   2073  1.1     skrll 	{
   2074  1.1     skrll 	  const char *s;
   2075  1.4  christos 
   2076  1.1     skrll 	  if (op->args[0] == 'a' || op->args[0] == 'i')
   2077  1.1     skrll 	    {
   2078  1.1     skrll 	      if (use_extend)
   2079  1.1     skrll 		{
   2080  1.1     skrll 		  infprintf (is, "extend 0x%x", (unsigned int) extend);
   2081  1.1     skrll 		  info->insn_type = dis_noninsn;
   2082  1.1     skrll 		  return length - 2;
   2083  1.1     skrll 		}
   2084  1.1     skrll 
   2085  1.1     skrll 	      use_extend = FALSE;
   2086  1.1     skrll 
   2087  1.1     skrll 	      memaddr += 2;
   2088  1.1     skrll 
   2089  1.1     skrll 	      status = (*info->read_memory_func) (memaddr, buffer, 2,
   2090  1.1     skrll 						  info);
   2091  1.1     skrll 	      if (status == 0)
   2092  1.1     skrll 		{
   2093  1.1     skrll 		  use_extend = TRUE;
   2094  1.1     skrll 		  if (info->endian == BFD_ENDIAN_BIG)
   2095  1.1     skrll 		    extend = bfd_getb16 (buffer);
   2096  1.1     skrll 		  else
   2097  1.4  christos 		    extend = bfd_getl16 (buffer);
   2098  1.1     skrll 		  length += 2;
   2099  1.4  christos 		}
   2100  1.1     skrll 	    }
   2101  1.5  christos 
   2102  1.1     skrll 	  infprintf (is, "%s", op->name);
   2103  1.1     skrll 	  if (op->args[0] != '\0')
   2104  1.1     skrll 	    infprintf (is, "\t");
   2105  1.1     skrll 
   2106  1.4  christos 	  init_print_arg_state (&state);
   2107  1.1     skrll 	  for (s = op->args; *s != '\0'; s++)
   2108  1.1     skrll 	    {
   2109  1.1     skrll 	      if (*s == ','
   2110  1.1     skrll 		  && s[1] == 'w'
   2111  1.1     skrll 		  && GET_OP (insn, RX) == GET_OP (insn, RY))
   2112  1.1     skrll 		{
   2113  1.1     skrll 		  /* Skip the register and the comma.  */
   2114  1.4  christos 		  ++s;
   2115  1.1     skrll 		  continue;
   2116  1.1     skrll 		}
   2117  1.1     skrll 	      if (*s == ','
   2118  1.1     skrll 		  && s[1] == 'v'
   2119  1.1     skrll 		  && GET_OP (insn, RZ) == GET_OP (insn, RX))
   2120  1.5  christos 		{
   2121  1.5  christos 		  /* Skip the register and the comma.  */
   2122  1.1     skrll 		  ++s;
   2123  1.1     skrll 		  continue;
   2124  1.3  christos 		}
   2125  1.1     skrll 	      print_mips16_insn_arg (info, &state, op, *s, memaddr, insn,
   2126  1.3  christos 				     use_extend, extend, s[1] == '(');
   2127  1.5  christos 	    }
   2128  1.5  christos 
   2129  1.1     skrll 	  /* Figure out branch instruction type and delay slot information.  */
   2130  1.3  christos 	  if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0)
   2131  1.3  christos 	    info->branch_delay_insns = 1;
   2132  1.3  christos 	  if ((op->pinfo & INSN_UNCOND_BRANCH_DELAY) != 0
   2133  1.1     skrll 	      || (op->pinfo2 & INSN2_UNCOND_BRANCH) != 0)
   2134  1.1     skrll 	    {
   2135  1.5  christos 	      if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
   2136  1.3  christos 		info->insn_type = dis_jsr;
   2137  1.1     skrll 	      else
   2138  1.1     skrll 		info->insn_type = dis_branch;
   2139  1.1     skrll 	    }
   2140  1.1     skrll 	  else if ((op->pinfo2 & INSN2_COND_BRANCH) != 0)
   2141  1.4  christos 	    info->insn_type = dis_condbranch;
   2142  1.1     skrll 
   2143  1.1     skrll 	  return length;
   2144  1.4  christos 	}
   2145  1.4  christos     }
   2146  1.4  christos #undef GET_OP
   2147  1.4  christos 
   2148  1.4  christos   if (use_extend)
   2149  1.4  christos     infprintf (is, "0x%x", extend | 0xf000);
   2150  1.4  christos   infprintf (is, "0x%x", insn);
   2151  1.4  christos   info->insn_type = dis_noninsn;
   2152  1.4  christos 
   2153  1.4  christos   return length;
   2154  1.4  christos }
   2155  1.4  christos 
   2156  1.4  christos /* Disassemble microMIPS instructions.  */
   2157  1.4  christos 
   2158  1.4  christos static int
   2159  1.4  christos print_insn_micromips (bfd_vma memaddr, struct disassemble_info *info)
   2160  1.5  christos {
   2161  1.5  christos   const fprintf_ftype infprintf = info->fprintf_func;
   2162  1.4  christos   const struct mips_opcode *op, *opend;
   2163  1.5  christos   void *is = info->stream;
   2164  1.4  christos   bfd_byte buffer[2];
   2165  1.4  christos   unsigned int higher;
   2166  1.4  christos   unsigned int length;
   2167  1.4  christos   int status;
   2168  1.4  christos   unsigned int insn;
   2169  1.4  christos 
   2170  1.4  christos   info->bytes_per_chunk = 2;
   2171  1.4  christos   info->display_endian = info->endian;
   2172  1.4  christos   info->insn_info_valid = 1;
   2173  1.4  christos   info->branch_delay_insns = 0;
   2174  1.4  christos   info->data_size = 0;
   2175  1.4  christos   info->insn_type = dis_nonbranch;
   2176  1.4  christos   info->target = 0;
   2177  1.4  christos   info->target2 = 0;
   2178  1.4  christos 
   2179  1.4  christos   status = (*info->read_memory_func) (memaddr, buffer, 2, info);
   2180  1.4  christos   if (status != 0)
   2181  1.4  christos     {
   2182  1.4  christos       (*info->memory_error_func) (status, memaddr, info);
   2183  1.4  christos       return -1;
   2184  1.4  christos     }
   2185  1.4  christos 
   2186  1.4  christos   length = 2;
   2187  1.4  christos 
   2188  1.4  christos   if (info->endian == BFD_ENDIAN_BIG)
   2189  1.4  christos     insn = bfd_getb16 (buffer);
   2190  1.4  christos   else
   2191  1.4  christos     insn = bfd_getl16 (buffer);
   2192  1.4  christos 
   2193  1.4  christos   if ((insn & 0xfc00) == 0x7c00)
   2194  1.4  christos     {
   2195  1.4  christos       /* This is a 48-bit microMIPS instruction.  */
   2196  1.4  christos       higher = insn;
   2197  1.4  christos 
   2198  1.4  christos       status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
   2199  1.4  christos       if (status != 0)
   2200  1.4  christos 	{
   2201  1.4  christos 	  infprintf (is, "micromips 0x%x", higher);
   2202  1.4  christos 	  (*info->memory_error_func) (status, memaddr + 2, info);
   2203  1.4  christos 	  return -1;
   2204  1.4  christos 	}
   2205  1.4  christos       if (info->endian == BFD_ENDIAN_BIG)
   2206  1.4  christos 	insn = bfd_getb16 (buffer);
   2207  1.4  christos       else
   2208  1.4  christos 	insn = bfd_getl16 (buffer);
   2209  1.4  christos       higher = (higher << 16) | insn;
   2210  1.4  christos 
   2211  1.4  christos       status = (*info->read_memory_func) (memaddr + 4, buffer, 2, info);
   2212  1.4  christos       if (status != 0)
   2213  1.4  christos 	{
   2214  1.4  christos 	  infprintf (is, "micromips 0x%x", higher);
   2215  1.4  christos 	  (*info->memory_error_func) (status, memaddr + 4, info);
   2216  1.4  christos 	  return -1;
   2217  1.4  christos 	}
   2218  1.4  christos       if (info->endian == BFD_ENDIAN_BIG)
   2219  1.4  christos 	insn = bfd_getb16 (buffer);
   2220  1.4  christos       else
   2221  1.4  christos 	insn = bfd_getl16 (buffer);
   2222  1.4  christos       infprintf (is, "0x%x%04x (48-bit insn)", higher, insn);
   2223  1.4  christos 
   2224  1.4  christos       info->insn_type = dis_noninsn;
   2225  1.4  christos       return 6;
   2226  1.4  christos     }
   2227  1.4  christos   else if ((insn & 0x1c00) == 0x0000 || (insn & 0x1000) == 0x1000)
   2228  1.4  christos     {
   2229  1.4  christos       /* This is a 32-bit microMIPS instruction.  */
   2230  1.4  christos       higher = insn;
   2231  1.4  christos 
   2232  1.4  christos       status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
   2233  1.4  christos       if (status != 0)
   2234  1.4  christos 	{
   2235  1.4  christos 	  infprintf (is, "micromips 0x%x", higher);
   2236  1.4  christos 	  (*info->memory_error_func) (status, memaddr + 2, info);
   2237  1.4  christos 	  return -1;
   2238  1.4  christos 	}
   2239  1.4  christos 
   2240  1.4  christos       if (info->endian == BFD_ENDIAN_BIG)
   2241  1.4  christos 	insn = bfd_getb16 (buffer);
   2242  1.4  christos       else
   2243  1.4  christos 	insn = bfd_getl16 (buffer);
   2244  1.4  christos 
   2245  1.4  christos       insn = insn | (higher << 16);
   2246  1.4  christos 
   2247  1.4  christos       length += 2;
   2248  1.4  christos     }
   2249  1.4  christos 
   2250  1.4  christos   /* FIXME: Should probably use a hash table on the major opcode here.  */
   2251  1.4  christos 
   2252  1.4  christos   opend = micromips_opcodes + bfd_micromips_num_opcodes;
   2253  1.4  christos   for (op = micromips_opcodes; op < opend; op++)
   2254  1.4  christos     {
   2255  1.4  christos       if (op->pinfo != INSN_MACRO
   2256  1.5  christos 	  && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
   2257  1.5  christos 	  && (insn & op->mask) == op->match
   2258  1.4  christos 	  && ((length == 2 && (op->mask & 0xffff0000) == 0)
   2259  1.4  christos 	      || (length == 4 && (op->mask & 0xffff0000) != 0)))
   2260  1.4  christos 	{
   2261  1.5  christos 	  if (!validate_insn_args (op, decode_micromips_operand, insn))
   2262  1.4  christos 	    continue;
   2263  1.5  christos 
   2264  1.5  christos 	  infprintf (is, "%s", op->name);
   2265  1.5  christos 
   2266  1.4  christos 	  if (op->args[0])
   2267  1.4  christos 	    {
   2268  1.4  christos 	      infprintf (is, "\t");
   2269  1.4  christos 	      print_insn_args (info, op, decode_micromips_operand, insn,
   2270  1.4  christos 			       memaddr + 1, length);
   2271  1.4  christos 	    }
   2272  1.4  christos 
   2273  1.4  christos 	  /* Figure out instruction type and branch delay information.  */
   2274  1.4  christos 	  if ((op->pinfo
   2275  1.5  christos 	       & (INSN_UNCOND_BRANCH_DELAY | INSN_COND_BRANCH_DELAY)) != 0)
   2276  1.4  christos 	    info->branch_delay_insns = 1;
   2277  1.4  christos 	  if (((op->pinfo & INSN_UNCOND_BRANCH_DELAY)
   2278  1.4  christos 	       | (op->pinfo2 & INSN2_UNCOND_BRANCH)) != 0)
   2279  1.4  christos 	    {
   2280  1.4  christos 	      if ((op->pinfo & (INSN_WRITE_GPR_31 | INSN_WRITE_1)) != 0)
   2281  1.4  christos 		info->insn_type = dis_jsr;
   2282  1.4  christos 	      else
   2283  1.4  christos 		info->insn_type = dis_branch;
   2284  1.4  christos 	    }
   2285  1.4  christos 	  else if (((op->pinfo & INSN_COND_BRANCH_DELAY)
   2286  1.4  christos 		    | (op->pinfo2 & INSN2_COND_BRANCH)) != 0)
   2287  1.4  christos 	    {
   2288  1.4  christos 	      if ((op->pinfo & INSN_WRITE_GPR_31) != 0)
   2289  1.5  christos 		info->insn_type = dis_condjsr;
   2290  1.4  christos 	      else
   2291  1.4  christos 		info->insn_type = dis_condbranch;
   2292  1.4  christos 	    }
   2293  1.4  christos 	  else if ((op->pinfo
   2294  1.4  christos 		    & (INSN_STORE_MEMORY | INSN_LOAD_MEMORY)) != 0)
   2295  1.4  christos 	    info->insn_type = dis_dref;
   2296  1.4  christos 
   2297  1.1     skrll 	  return length;
   2298  1.1     skrll 	}
   2299  1.1     skrll     }
   2300  1.1     skrll 
   2301  1.1     skrll   infprintf (is, "0x%x", insn);
   2302  1.4  christos   info->insn_type = dis_noninsn;
   2303  1.4  christos 
   2304  1.4  christos   return length;
   2305  1.4  christos }
   2306  1.4  christos 
   2307  1.4  christos /* Return 1 if a symbol associated with the location being disassembled
   2308  1.4  christos    indicates a compressed (MIPS16 or microMIPS) mode.  We iterate over
   2309  1.4  christos    all the symbols at the address being considered assuming if at least
   2310  1.4  christos    one of them indicates code compression, then such code has been
   2311  1.4  christos    genuinely produced here (other symbols could have been derived from
   2312  1.4  christos    function symbols defined elsewhere or could define data).  Otherwise,
   2313  1.4  christos    return 0.  */
   2314  1.5  christos 
   2315  1.4  christos static bfd_boolean
   2316  1.5  christos is_compressed_mode_p (struct disassemble_info *info)
   2317  1.5  christos {
   2318  1.5  christos   int i;
   2319  1.5  christos   int l;
   2320  1.5  christos 
   2321  1.5  christos   for (i = info->symtab_pos, l = i + info->num_symbols; i < l; i++)
   2322  1.5  christos     if (((info->symtab[i])->flags & BSF_SYNTHETIC) != 0
   2323  1.5  christos 	&& ((!micromips_ase
   2324  1.5  christos 	     && ELF_ST_IS_MIPS16 ((*info->symbols)->udata.i))
   2325  1.5  christos 	    || (micromips_ase
   2326  1.5  christos 		&& ELF_ST_IS_MICROMIPS ((*info->symbols)->udata.i))))
   2327  1.5  christos       return 1;
   2328  1.5  christos     else if (bfd_asymbol_flavour (info->symtab[i]) == bfd_target_elf_flavour
   2329  1.5  christos 	      && info->symtab[i]->section == info->section)
   2330  1.5  christos       {
   2331  1.5  christos 	elf_symbol_type *symbol = (elf_symbol_type *) info->symtab[i];
   2332  1.5  christos 	if ((!micromips_ase
   2333  1.4  christos 	     && ELF_ST_IS_MIPS16 (symbol->internal_elf_sym.st_other))
   2334  1.4  christos 	    || (micromips_ase
   2335  1.4  christos 		&& ELF_ST_IS_MICROMIPS (symbol->internal_elf_sym.st_other)))
   2336  1.4  christos 	  return 1;
   2337  1.1     skrll       }
   2338  1.1     skrll 
   2339  1.1     skrll   return 0;
   2340  1.1     skrll }
   2341  1.1     skrll 
   2342  1.1     skrll /* In an environment where we do not know the symbol type of the
   2343  1.1     skrll    instruction we are forced to assume that the low order bit of the
   2344  1.1     skrll    instructions' address may mark it as a mips16 instruction.  If we
   2345  1.1     skrll    are single stepping, or the pc is within the disassembled function,
   2346  1.1     skrll    this works.  Otherwise, we need a clue.  Sometimes.  */
   2347  1.1     skrll 
   2348  1.4  christos static int
   2349  1.1     skrll _print_insn_mips (bfd_vma memaddr,
   2350  1.1     skrll 		  struct disassemble_info *info,
   2351  1.1     skrll 		  enum bfd_endian endianness)
   2352  1.1     skrll {
   2353  1.1     skrll   int (*print_insn_compr) (bfd_vma, struct disassemble_info *);
   2354  1.1     skrll   bfd_byte buffer[INSNLEN];
   2355  1.4  christos   int status;
   2356  1.4  christos 
   2357  1.4  christos   set_default_mips_dis_options (info);
   2358  1.4  christos   parse_mips_dis_options (info->disassembler_options);
   2359  1.4  christos 
   2360  1.4  christos   if (info->mach == bfd_mach_mips16)
   2361  1.4  christos     return print_insn_mips16 (memaddr, info);
   2362  1.1     skrll   if (info->mach == bfd_mach_mips_micromips)
   2363  1.4  christos     return print_insn_micromips (memaddr, info);
   2364  1.1     skrll 
   2365  1.1     skrll   print_insn_compr = !micromips_ase ? print_insn_mips16 : print_insn_micromips;
   2366  1.4  christos 
   2367  1.1     skrll #if 1
   2368  1.1     skrll   /* FIXME: If odd address, this is CLEARLY a compressed instruction.  */
   2369  1.1     skrll   /* Only a few tools will work this way.  */
   2370  1.4  christos   if (memaddr & 0x01)
   2371  1.4  christos     return print_insn_compr (memaddr, info);
   2372  1.1     skrll #endif
   2373  1.1     skrll 
   2374  1.1     skrll #if SYMTAB_AVAILABLE
   2375  1.1     skrll   if (is_compressed_mode_p (info))
   2376  1.1     skrll     return print_insn_compr (memaddr, info);
   2377  1.4  christos #endif
   2378  1.1     skrll 
   2379  1.1     skrll   status = (*info->read_memory_func) (memaddr, buffer, INSNLEN, info);
   2380  1.4  christos   if (status == 0)
   2381  1.1     skrll     {
   2382  1.4  christos       int insn;
   2383  1.1     skrll 
   2384  1.1     skrll       if (endianness == BFD_ENDIAN_BIG)
   2385  1.1     skrll 	insn = bfd_getb32 (buffer);
   2386  1.1     skrll       else
   2387  1.1     skrll 	insn = bfd_getl32 (buffer);
   2388  1.1     skrll 
   2389  1.1     skrll       return print_insn_mips (memaddr, insn, info);
   2390  1.1     skrll     }
   2391  1.1     skrll   else
   2392  1.1     skrll     {
   2393  1.1     skrll       (*info->memory_error_func) (status, memaddr, info);
   2394  1.1     skrll       return -1;
   2395  1.1     skrll     }
   2396  1.1     skrll }
   2397  1.1     skrll 
   2398  1.1     skrll int
   2399  1.1     skrll print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
   2400  1.1     skrll {
   2401  1.1     skrll   return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
   2402  1.1     skrll }
   2403  1.1     skrll 
   2404  1.1     skrll int
   2405  1.1     skrll print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
   2406  1.1     skrll {
   2407  1.1     skrll   return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
   2408  1.1     skrll }
   2409  1.1     skrll 
   2410  1.1     skrll void
   2412  1.1     skrll print_mips_disassembler_options (FILE *stream)
   2413  1.1     skrll {
   2414  1.1     skrll   unsigned int i;
   2415  1.5  christos 
   2416  1.5  christos   fprintf (stream, _("\n\
   2417  1.5  christos The following MIPS specific disassembler options are supported for use\n\
   2418  1.5  christos with the -M switch (multiple options should be separated by commas):\n"));
   2419  1.5  christos 
   2420  1.5  christos   fprintf (stream, _("\n\
   2421  1.5  christos   msa             Recognize MSA instructions.\n"));
   2422  1.5  christos 
   2423  1.5  christos   fprintf (stream, _("\n\
   2424  1.1     skrll   virt            Recognize the virtualization ASE instructions.\n"));
   2425  1.1     skrll 
   2426  1.1     skrll   fprintf (stream, _("\n\
   2427  1.1     skrll   xpa            Recognize the eXtended Physical Address (XPA) ASE instructions.\n"));
   2428  1.1     skrll 
   2429  1.1     skrll   fprintf (stream, _("\n\
   2430  1.1     skrll   gpr-names=ABI            Print GPR names according to  specified ABI.\n\
   2431  1.1     skrll                            Default: based on binary being disassembled.\n"));
   2432  1.1     skrll 
   2433  1.1     skrll   fprintf (stream, _("\n\
   2434  1.1     skrll   fpr-names=ABI            Print FPR names according to specified ABI.\n\
   2435  1.1     skrll                            Default: numeric.\n"));
   2436  1.1     skrll 
   2437  1.1     skrll   fprintf (stream, _("\n\
   2438  1.1     skrll   cp0-names=ARCH           Print CP0 register names according to\n\
   2439  1.1     skrll                            specified architecture.\n\
   2440  1.1     skrll                            Default: based on binary being disassembled.\n"));
   2441  1.1     skrll 
   2442  1.1     skrll   fprintf (stream, _("\n\
   2443  1.1     skrll   hwr-names=ARCH           Print HWR names according to specified \n\
   2444  1.1     skrll 			   architecture.\n\
   2445  1.1     skrll                            Default: based on binary being disassembled.\n"));
   2446  1.1     skrll 
   2447  1.1     skrll   fprintf (stream, _("\n\
   2448  1.1     skrll   reg-names=ABI            Print GPR and FPR names according to\n\
   2449  1.1     skrll                            specified ABI.\n"));
   2450  1.1     skrll 
   2451  1.1     skrll   fprintf (stream, _("\n\
   2452  1.1     skrll   reg-names=ARCH           Print CP0 register and HWR names according to\n\
   2453  1.1     skrll                            specified architecture.\n"));
   2454  1.1     skrll 
   2455  1.1     skrll   fprintf (stream, _("\n\
   2456  1.1     skrll   For the options above, the following values are supported for \"ABI\":\n\
   2457  1.1     skrll    "));
   2458  1.1     skrll   for (i = 0; i < ARRAY_SIZE (mips_abi_choices); i++)
   2459  1.1     skrll     fprintf (stream, " %s", mips_abi_choices[i].name);
   2460  1.1     skrll   fprintf (stream, _("\n"));
   2461  1.1     skrll 
   2462  1.1     skrll   fprintf (stream, _("\n\
   2463  1.1     skrll   For the options above, The following values are supported for \"ARCH\":\n\
   2464  1.1     skrll    "));
   2465  1.1     skrll   for (i = 0; i < ARRAY_SIZE (mips_arch_choices); i++)
   2466                    if (*mips_arch_choices[i].name != '\0')
   2467                      fprintf (stream, " %s", mips_arch_choices[i].name);
   2468                  fprintf (stream, _("\n"));
   2469                
   2470                  fprintf (stream, _("\n"));
   2471                }
   2472