Commit 52da07d1af1884d6140cd68e0d5770f918439645

Authored by ths
1 parent 2e4a88cb

MIPS disassembler update.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3119 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 437 additions and 164 deletions
mips-dis.c
... ... @@ -2758,102 +2758,91 @@ int bfd_mips_num_opcodes = MIPS_NUM_OPCODES;
2758 2758 /* Mips instructions are at maximum this many bytes long. */
2759 2759 #define INSNLEN 4
2760 2760  
2761   -static void set_default_mips_dis_options
2762   - PARAMS ((struct disassemble_info *));
2763   -static void parse_mips_dis_option
2764   - PARAMS ((const char *, unsigned int));
2765   -static void parse_mips_dis_options
2766   - PARAMS ((const char *));
2767   -static int _print_insn_mips
2768   - PARAMS ((bfd_vma, struct disassemble_info *, enum bfd_endian));
2769   -static int print_insn_mips
2770   - PARAMS ((bfd_vma, unsigned long int, struct disassemble_info *));
2771   -static void print_insn_args
2772   - PARAMS ((const char *, unsigned long, bfd_vma, struct disassemble_info *));
2773   -#if 0
2774   -static int print_insn_mips16
2775   - PARAMS ((bfd_vma, struct disassemble_info *));
2776   -#endif
2777   -#if 0
2778   -static int is_newabi
2779   - PARAMS ((Elf32_Ehdr *));
2780   -#endif
2781   -#if 0
2782   -static void print_mips16_insn_arg
2783   - PARAMS ((int, const struct mips_opcode *, int, bfd_boolean, int, bfd_vma,
2784   - struct disassemble_info *));
2785   -#endif
2786 2761  
2787 2762 /* FIXME: These should be shared with gdb somehow. */
2788 2763  
2789   -struct mips_cp0sel_name {
2790   - unsigned int cp0reg;
2791   - unsigned int sel;
2792   - const char * const name;
  2764 +struct mips_cp0sel_name
  2765 +{
  2766 + unsigned int cp0reg;
  2767 + unsigned int sel;
  2768 + const char * const name;
2793 2769 };
2794 2770  
2795   -/* The mips16 register names. */
2796   -static const char * const mips16_reg_names[] = {
2797   - "s0", "s1", "v0", "v1", "a0", "a1", "a2", "a3"
  2771 +/* The mips16 registers. */
  2772 +static const unsigned int mips16_to_32_reg_map[] =
  2773 +{
  2774 + 16, 17, 2, 3, 4, 5, 6, 7
2798 2775 };
2799 2776  
2800   -static const char * const mips_gpr_names_numeric[32] = {
  2777 +#define mips16_reg_names(rn) mips_gpr_names[mips16_to_32_reg_map[rn]]
  2778 +
  2779 +
  2780 +static const char * const mips_gpr_names_numeric[32] =
  2781 +{
2801 2782 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
2802 2783 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
2803 2784 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
2804 2785 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
2805 2786 };
2806 2787  
2807   -static const char * const mips_gpr_names_oldabi[32] = {
  2788 +static const char * const mips_gpr_names_oldabi[32] =
  2789 +{
2808 2790 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2809 2791 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2810 2792 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2811 2793 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
2812 2794 };
2813 2795  
2814   -static const char * const mips_gpr_names_newabi[32] = {
  2796 +static const char * const mips_gpr_names_newabi[32] =
  2797 +{
2815 2798 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2816 2799 "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
2817 2800 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2818 2801 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra"
2819 2802 };
2820 2803  
2821   -static const char * const mips_fpr_names_numeric[32] = {
  2804 +static const char * const mips_fpr_names_numeric[32] =
  2805 +{
2822 2806 "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
2823 2807 "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
2824 2808 "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
2825 2809 "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31"
2826 2810 };
2827 2811  
2828   -static const char * const mips_fpr_names_32[32] = {
  2812 +static const char * const mips_fpr_names_32[32] =
  2813 +{
2829 2814 "fv0", "fv0f", "fv1", "fv1f", "ft0", "ft0f", "ft1", "ft1f",
2830 2815 "ft2", "ft2f", "ft3", "ft3f", "fa0", "fa0f", "fa1", "fa1f",
2831 2816 "ft4", "ft4f", "ft5", "ft5f", "fs0", "fs0f", "fs1", "fs1f",
2832 2817 "fs2", "fs2f", "fs3", "fs3f", "fs4", "fs4f", "fs5", "fs5f"
2833 2818 };
2834 2819  
2835   -static const char * const mips_fpr_names_n32[32] = {
  2820 +static const char * const mips_fpr_names_n32[32] =
  2821 +{
2836 2822 "fv0", "ft14", "fv1", "ft15", "ft0", "ft1", "ft2", "ft3",
2837 2823 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
2838 2824 "fa4", "fa5", "fa6", "fa7", "fs0", "ft8", "fs1", "ft9",
2839 2825 "fs2", "ft10", "fs3", "ft11", "fs4", "ft12", "fs5", "ft13"
2840 2826 };
2841 2827  
2842   -static const char * const mips_fpr_names_64[32] = {
  2828 +static const char * const mips_fpr_names_64[32] =
  2829 +{
2843 2830 "fv0", "ft12", "fv1", "ft13", "ft0", "ft1", "ft2", "ft3",
2844 2831 "ft4", "ft5", "ft6", "ft7", "fa0", "fa1", "fa2", "fa3",
2845 2832 "fa4", "fa5", "fa6", "fa7", "ft8", "ft9", "ft10", "ft11",
2846 2833 "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7"
2847 2834 };
2848 2835  
2849   -static const char * const mips_cp0_names_numeric[32] = {
  2836 +static const char * const mips_cp0_names_numeric[32] =
  2837 +{
2850 2838 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
2851 2839 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
2852 2840 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
2853 2841 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
2854 2842 };
2855 2843  
2856   -static const char * const mips_cp0_names_mips3264[32] = {
  2844 +static const char * const mips_cp0_names_mips3264[32] =
  2845 +{
2857 2846 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
2858 2847 "c0_context", "c0_pagemask", "c0_wired", "$7",
2859 2848 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
... ... @@ -2864,7 +2853,35 @@ static const char * const mips_cp0_names_mips3264[32] = {
2864 2853 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
2865 2854 };
2866 2855  
2867   -static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] = {
  2856 +static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] =
  2857 +{
  2858 + { 4, 1, "c0_contextconfig" },
  2859 + { 0, 1, "c0_mvpcontrol" },
  2860 + { 0, 2, "c0_mvpconf0" },
  2861 + { 0, 3, "c0_mvpconf1" },
  2862 + { 1, 1, "c0_vpecontrol" },
  2863 + { 1, 2, "c0_vpeconf0" },
  2864 + { 1, 3, "c0_vpeconf1" },
  2865 + { 1, 4, "c0_yqmask" },
  2866 + { 1, 5, "c0_vpeschedule" },
  2867 + { 1, 6, "c0_vpeschefback" },
  2868 + { 2, 1, "c0_tcstatus" },
  2869 + { 2, 2, "c0_tcbind" },
  2870 + { 2, 3, "c0_tcrestart" },
  2871 + { 2, 4, "c0_tchalt" },
  2872 + { 2, 5, "c0_tccontext" },
  2873 + { 2, 6, "c0_tcschedule" },
  2874 + { 2, 7, "c0_tcschefback" },
  2875 + { 5, 1, "c0_pagegrain" },
  2876 + { 6, 1, "c0_srsconf0" },
  2877 + { 6, 2, "c0_srsconf1" },
  2878 + { 6, 3, "c0_srsconf2" },
  2879 + { 6, 4, "c0_srsconf3" },
  2880 + { 6, 5, "c0_srsconf4" },
  2881 + { 12, 1, "c0_intctl" },
  2882 + { 12, 2, "c0_srsctl" },
  2883 + { 12, 3, "c0_srsmap" },
  2884 + { 15, 1, "c0_ebase" },
2868 2885 { 16, 1, "c0_config1" },
2869 2886 { 16, 2, "c0_config2" },
2870 2887 { 16, 3, "c0_config3" },
... ... @@ -2882,6 +2899,10 @@ static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] = {
2882 2899 { 19, 5, "c0_watchhi,5" },
2883 2900 { 19, 6, "c0_watchhi,6" },
2884 2901 { 19, 7, "c0_watchhi,7" },
  2902 + { 23, 1, "c0_tracecontrol" },
  2903 + { 23, 2, "c0_tracecontrol2" },
  2904 + { 23, 3, "c0_usertracedata" },
  2905 + { 23, 4, "c0_tracebpc" },
2885 2906 { 25, 1, "c0_perfcnt,1" },
2886 2907 { 25, 2, "c0_perfcnt,2" },
2887 2908 { 25, 3, "c0_perfcnt,3" },
... ... @@ -2893,10 +2914,23 @@ static const struct mips_cp0sel_name mips_cp0sel_names_mips3264[] = {
2893 2914 { 27, 2, "c0_cacheerr,2" },
2894 2915 { 27, 3, "c0_cacheerr,3" },
2895 2916 { 28, 1, "c0_datalo" },
2896   - { 29, 1, "c0_datahi" }
  2917 + { 28, 2, "c0_taglo1" },
  2918 + { 28, 3, "c0_datalo1" },
  2919 + { 28, 4, "c0_taglo2" },
  2920 + { 28, 5, "c0_datalo2" },
  2921 + { 28, 6, "c0_taglo3" },
  2922 + { 28, 7, "c0_datalo3" },
  2923 + { 29, 1, "c0_datahi" },
  2924 + { 29, 2, "c0_taghi1" },
  2925 + { 29, 3, "c0_datahi1" },
  2926 + { 29, 4, "c0_taghi2" },
  2927 + { 29, 5, "c0_datahi2" },
  2928 + { 29, 6, "c0_taghi3" },
  2929 + { 29, 7, "c0_datahi3" },
2897 2930 };
2898 2931  
2899   -static const char * const mips_cp0_names_mips3264r2[32] = {
  2932 +static const char * const mips_cp0_names_mips3264r2[32] =
  2933 +{
2900 2934 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
2901 2935 "c0_context", "c0_pagemask", "c0_wired", "c0_hwrena",
2902 2936 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
... ... @@ -2907,7 +2941,8 @@ static const char * const mips_cp0_names_mips3264r2[32] = {
2907 2941 "c0_taglo", "c0_taghi", "c0_errorepc", "c0_desave",
2908 2942 };
2909 2943  
2910   -static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] = {
  2944 +static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] =
  2945 +{
2911 2946 { 4, 1, "c0_contextconfig" },
2912 2947 { 5, 1, "c0_pagegrain" },
2913 2948 { 12, 1, "c0_intctl" },
... ... @@ -2962,7 +2997,8 @@ static const struct mips_cp0sel_name mips_cp0sel_names_mips3264r2[] = {
2962 2997 };
2963 2998  
2964 2999 /* SB-1: MIPS64 (mips_cp0_names_mips3264) with minor mods. */
2965   -static const char * const mips_cp0_names_sb1[32] = {
  3000 +static const char * const mips_cp0_names_sb1[32] =
  3001 +{
2966 3002 "c0_index", "c0_random", "c0_entrylo0", "c0_entrylo1",
2967 3003 "c0_context", "c0_pagemask", "c0_wired", "$7",
2968 3004 "c0_badvaddr", "c0_count", "c0_entryhi", "c0_compare",
... ... @@ -2973,7 +3009,8 @@ static const char * const mips_cp0_names_sb1[32] = {
2973 3009 "c0_taglo_i", "c0_taghi_i", "c0_errorepc", "c0_desave",
2974 3010 };
2975 3011  
2976   -static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] = {
  3012 +static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] =
  3013 +{
2977 3014 { 16, 1, "c0_config1" },
2978 3015 { 18, 1, "c0_watchlo,1" },
2979 3016 { 19, 1, "c0_watchhi,1" },
... ... @@ -2997,14 +3034,16 @@ static const struct mips_cp0sel_name mips_cp0sel_names_sb1[] = {
2997 3034 { 29, 3, "c0_datahi_d" },
2998 3035 };
2999 3036  
3000   -static const char * const mips_hwr_names_numeric[32] = {
  3037 +static const char * const mips_hwr_names_numeric[32] =
  3038 +{
3001 3039 "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
3002 3040 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
3003 3041 "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
3004 3042 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
3005 3043 };
3006 3044  
3007   -static const char * const mips_hwr_names_mips3264r2[32] = {
  3045 +static const char * const mips_hwr_names_mips3264r2[32] =
  3046 +{
3008 3047 "hwr_cpunum", "hwr_synci_step", "hwr_cc", "hwr_ccres",
3009 3048 "$4", "$5", "$6", "$7",
3010 3049 "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
... ... @@ -3012,20 +3051,23 @@ static const char * const mips_hwr_names_mips3264r2[32] = {
3012 3051 "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31"
3013 3052 };
3014 3053  
3015   -struct mips_abi_choice {
  3054 +struct mips_abi_choice
  3055 +{
3016 3056 const char *name;
3017 3057 const char * const *gpr_names;
3018 3058 const char * const *fpr_names;
3019 3059 };
3020 3060  
3021   -struct mips_abi_choice mips_abi_choices[] = {
  3061 +struct mips_abi_choice mips_abi_choices[] =
  3062 +{
3022 3063 { "numeric", mips_gpr_names_numeric, mips_fpr_names_numeric },
3023 3064 { "32", mips_gpr_names_oldabi, mips_fpr_names_32 },
3024 3065 { "n32", mips_gpr_names_newabi, mips_fpr_names_n32 },
3025 3066 { "64", mips_gpr_names_newabi, mips_fpr_names_64 },
3026 3067 };
3027 3068  
3028   -struct mips_arch_choice {
  3069 +struct mips_arch_choice
  3070 +{
3029 3071 const char *name;
3030 3072 int bfd_mach_valid;
3031 3073 unsigned long bfd_mach;
... ... @@ -3054,6 +3096,7 @@ struct mips_arch_choice {
3054 3096 #define bfd_mach_mips6000 6000
3055 3097 #define bfd_mach_mips7000 7000
3056 3098 #define bfd_mach_mips8000 8000
  3099 +#define bfd_mach_mips9000 9000
3057 3100 #define bfd_mach_mips10000 10000
3058 3101 #define bfd_mach_mips12000 12000
3059 3102 #define bfd_mach_mips16 16
... ... @@ -3066,7 +3109,8 @@ struct mips_arch_choice {
3066 3109  
3067 3110 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
3068 3111  
3069   -const struct mips_arch_choice mips_arch_choices[] = {
  3112 +const struct mips_arch_choice mips_arch_choices[] =
  3113 +{
3070 3114 { "numeric", 0, 0, 0, 0,
3071 3115 mips_cp0_names_numeric, NULL, 0, mips_hwr_names_numeric },
3072 3116  
... ... @@ -3119,13 +3163,14 @@ const struct mips_arch_choice mips_arch_choices[] = {
3119 3163 MIPS32 Architecture_ (MIPS Document Number MD00082, Revision 0.95),
3120 3164 page 1. */
3121 3165 { "mips32", 1, bfd_mach_mipsisa32, CPU_MIPS32,
3122   - ISA_MIPS32 | INSN_MIPS16,
  3166 + ISA_MIPS32 | INSN_MIPS16 | INSN_SMARTMIPS,
3123 3167 mips_cp0_names_mips3264,
3124 3168 mips_cp0sel_names_mips3264, ARRAY_SIZE (mips_cp0sel_names_mips3264),
3125 3169 mips_hwr_names_numeric },
3126 3170  
3127 3171 { "mips32r2", 1, bfd_mach_mipsisa32r2, CPU_MIPS32R2,
3128   - ISA_MIPS32R2 | INSN_MIPS16,
  3172 + (ISA_MIPS32R2 | INSN_MIPS16 | INSN_SMARTMIPS | INSN_DSP | INSN_DSPR2
  3173 + | INSN_MIPS3D | INSN_MT),
3129 3174 mips_cp0_names_mips3264r2,
3130 3175 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
3131 3176 mips_hwr_names_mips3264r2 },
... ... @@ -3138,7 +3183,8 @@ const struct mips_arch_choice mips_arch_choices[] = {
3138 3183 mips_hwr_names_numeric },
3139 3184  
3140 3185 { "mips64r2", 1, bfd_mach_mipsisa64r2, CPU_MIPS64R2,
3141   - ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_MDMX,
  3186 + (ISA_MIPS64R2 | INSN_MIPS16 | INSN_MIPS3D | INSN_DSP | INSN_DSPR2
  3187 + | INSN_DSP64 | INSN_MT | INSN_MDMX),
3142 3188 mips_cp0_names_mips3264r2,
3143 3189 mips_cp0sel_names_mips3264r2, ARRAY_SIZE (mips_cp0sel_names_mips3264r2),
3144 3190 mips_hwr_names_mips3264r2 },
... ... @@ -3167,53 +3213,39 @@ static const struct mips_cp0sel_name *mips_cp0sel_names;
3167 3213 static int mips_cp0sel_names_len;
3168 3214 static const char * const *mips_hwr_names;
3169 3215  
3170   -static const struct mips_abi_choice *choose_abi_by_name
3171   - PARAMS ((const char *, unsigned int));
3172   -static const struct mips_arch_choice *choose_arch_by_name
3173   - PARAMS ((const char *, unsigned int));
3174   -static const struct mips_arch_choice *choose_arch_by_number
3175   - PARAMS ((unsigned long));
3176   -static const struct mips_cp0sel_name *lookup_mips_cp0sel_name
3177   - PARAMS ((const struct mips_cp0sel_name *, unsigned int, unsigned int,
3178   - unsigned int));
  3216 +/* Other options */
  3217 +static int no_aliases; /* If set disassemble as most general inst. */
3179 3218  
3180 3219 static const struct mips_abi_choice *
3181   -choose_abi_by_name (name, namelen)
3182   - const char *name;
3183   - unsigned int namelen;
  3220 +choose_abi_by_name (const char *name, unsigned int namelen)
3184 3221 {
3185 3222 const struct mips_abi_choice *c;
3186 3223 unsigned int i;
3187 3224  
3188 3225 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_abi_choices) && c == NULL; i++)
3189   - {
3190   - if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
3191   - && strlen (mips_abi_choices[i].name) == namelen)
3192   - c = &mips_abi_choices[i];
3193   - }
  3226 + if (strncmp (mips_abi_choices[i].name, name, namelen) == 0
  3227 + && strlen (mips_abi_choices[i].name) == namelen)
  3228 + c = &mips_abi_choices[i];
  3229 +
3194 3230 return c;
3195 3231 }
3196 3232  
3197 3233 static const struct mips_arch_choice *
3198   -choose_arch_by_name (name, namelen)
3199   - const char *name;
3200   - unsigned int namelen;
  3234 +choose_arch_by_name (const char *name, unsigned int namelen)
3201 3235 {
3202 3236 const struct mips_arch_choice *c = NULL;
3203 3237 unsigned int i;
3204 3238  
3205 3239 for (i = 0, c = NULL; i < ARRAY_SIZE (mips_arch_choices) && c == NULL; i++)
3206   - {
3207   - if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
3208   - && strlen (mips_arch_choices[i].name) == namelen)
3209   - c = &mips_arch_choices[i];
3210   - }
  3240 + if (strncmp (mips_arch_choices[i].name, name, namelen) == 0
  3241 + && strlen (mips_arch_choices[i].name) == namelen)
  3242 + c = &mips_arch_choices[i];
  3243 +
3211 3244 return c;
3212 3245 }
3213 3246  
3214 3247 static const struct mips_arch_choice *
3215   -choose_arch_by_number (mach)
3216   - unsigned long mach;
  3248 +choose_arch_by_number (unsigned long mach)
3217 3249 {
3218 3250 static unsigned long hint_bfd_mach;
3219 3251 static const struct mips_arch_choice *hint_arch_choice;
... ... @@ -3241,8 +3273,7 @@ choose_arch_by_number (mach)
3241 3273 }
3242 3274  
3243 3275 void
3244   -set_default_mips_dis_options (info)
3245   - struct disassemble_info *info;
  3276 +set_default_mips_dis_options (struct disassemble_info *info)
3246 3277 {
3247 3278 const struct mips_arch_choice *chosen_arch;
3248 3279  
... ... @@ -3256,6 +3287,7 @@ set_default_mips_dis_options (info)
3256 3287 mips_cp0sel_names = NULL;
3257 3288 mips_cp0sel_names_len = 0;
3258 3289 mips_hwr_names = mips_hwr_names_numeric;
  3290 + no_aliases = 0;
3259 3291  
3260 3292 /* If an ELF "newabi" binary, use the n32/(n)64 GPR names. */
3261 3293 #if 0
... ... @@ -3383,9 +3415,8 @@ parse_mips_dis_option (option, len)
3383 3415 /* Invalid option. */
3384 3416 }
3385 3417  
3386   -void
3387   -parse_mips_dis_options (options)
3388   - const char *options;
  3418 +static void
  3419 +parse_mips_dis_options (const char *options)
3389 3420 {
3390 3421 const char *option_end;
3391 3422  
... ... @@ -3415,9 +3446,10 @@ parse_mips_dis_options (options)
3415 3446 }
3416 3447  
3417 3448 static const struct mips_cp0sel_name *
3418   -lookup_mips_cp0sel_name(names, len, cp0reg, sel)
3419   - const struct mips_cp0sel_name *names;
3420   - unsigned int len, cp0reg, sel;
  3449 +lookup_mips_cp0sel_name (const struct mips_cp0sel_name *names,
  3450 + unsigned int len,
  3451 + unsigned int cp0reg,
  3452 + unsigned int sel)
3421 3453 {
3422 3454 unsigned int i;
3423 3455  
... ... @@ -3430,11 +3462,11 @@ lookup_mips_cp0sel_name(names, len, cp0reg, sel)
3430 3462 /* Print insn arguments for 32/64-bit code. */
3431 3463  
3432 3464 static void
3433   -print_insn_args (d, l, pc, info)
3434   - const char *d;
3435   - register unsigned long int l;
3436   - bfd_vma pc;
3437   - struct disassemble_info *info;
  3465 +print_insn_args (const char *d,
  3466 + register unsigned long int l,
  3467 + bfd_vma pc,
  3468 + struct disassemble_info *info,
  3469 + const struct mips_opcode *opp)
3438 3470 {
3439 3471 int op, delta;
3440 3472 unsigned int lsb, msb, msbd;
... ... @@ -3468,12 +3500,32 @@ print_insn_args (d, l, pc, info)
3468 3500 lsb = (l >> OP_SH_SHAMT) & OP_MASK_SHAMT;
3469 3501 (*info->fprintf_func) (info->stream, "0x%x", lsb);
3470 3502 break;
3471   -
  3503 +
3472 3504 case 'B':
3473 3505 msb = (l >> OP_SH_INSMSB) & OP_MASK_INSMSB;
3474 3506 (*info->fprintf_func) (info->stream, "0x%x", msb - lsb + 1);
3475 3507 break;
3476 3508  
  3509 + case '1':
  3510 + (*info->fprintf_func) (info->stream, "0x%lx",
  3511 + (l >> OP_SH_UDI1) & OP_MASK_UDI1);
  3512 + break;
  3513 +
  3514 + case '2':
  3515 + (*info->fprintf_func) (info->stream, "0x%lx",
  3516 + (l >> OP_SH_UDI2) & OP_MASK_UDI2);
  3517 + break;
  3518 +
  3519 + case '3':
  3520 + (*info->fprintf_func) (info->stream, "0x%lx",
  3521 + (l >> OP_SH_UDI3) & OP_MASK_UDI3);
  3522 + break;
  3523 +
  3524 + case '4':
  3525 + (*info->fprintf_func) (info->stream, "0x%lx",
  3526 + (l >> OP_SH_UDI4) & OP_MASK_UDI4);
  3527 + break;
  3528 +
3477 3529 case 'C':
3478 3530 case 'H':
3479 3531 msbd = (l >> OP_SH_EXTMSBD) & OP_MASK_EXTMSBD;
... ... @@ -3517,6 +3569,34 @@ print_insn_args (d, l, pc, info)
3517 3569 (*info->fprintf_func) (info->stream, "0x%x", msbd + 1);
3518 3570 break;
3519 3571  
  3572 + case 't': /* Coprocessor 0 reg name */
  3573 + (*info->fprintf_func) (info->stream, "%s",
  3574 + mips_cp0_names[(l >> OP_SH_RT) &
  3575 + OP_MASK_RT]);
  3576 + break;
  3577 +
  3578 + case 'T': /* Coprocessor 0 reg name */
  3579 + {
  3580 + const struct mips_cp0sel_name *n;
  3581 + unsigned int cp0reg, sel;
  3582 +
  3583 + cp0reg = (l >> OP_SH_RT) & OP_MASK_RT;
  3584 + sel = (l >> OP_SH_SEL) & OP_MASK_SEL;
  3585 +
  3586 + /* CP0 register including 'sel' code for mftc0, to be
  3587 + printed textually if known. If not known, print both
  3588 + CP0 register name and sel numerically since CP0 register
  3589 + with sel 0 may have a name unrelated to register being
  3590 + printed. */
  3591 + n = lookup_mips_cp0sel_name(mips_cp0sel_names,
  3592 + mips_cp0sel_names_len, cp0reg, sel);
  3593 + if (n != NULL)
  3594 + (*info->fprintf_func) (info->stream, "%s", n->name);
  3595 + else
  3596 + (*info->fprintf_func) (info->stream, "$%d,%d", cp0reg, sel);
  3597 + break;
  3598 + }
  3599 +
3520 3600 default:
3521 3601 /* xgettext:c-format */
3522 3602 (*info->fprintf_func) (info->stream,
... ... @@ -3526,6 +3606,98 @@ print_insn_args (d, l, pc, info)
3526 3606 }
3527 3607 break;
3528 3608  
  3609 + case '2':
  3610 + (*info->fprintf_func) (info->stream, "0x%lx",
  3611 + (l >> OP_SH_BP) & OP_MASK_BP);
  3612 + break;
  3613 +
  3614 + case '3':
  3615 + (*info->fprintf_func) (info->stream, "0x%lx",
  3616 + (l >> OP_SH_SA3) & OP_MASK_SA3);
  3617 + break;
  3618 +
  3619 + case '4':
  3620 + (*info->fprintf_func) (info->stream, "0x%lx",
  3621 + (l >> OP_SH_SA4) & OP_MASK_SA4);
  3622 + break;
  3623 +
  3624 + case '5':
  3625 + (*info->fprintf_func) (info->stream, "0x%lx",
  3626 + (l >> OP_SH_IMM8) & OP_MASK_IMM8);
  3627 + break;
  3628 +
  3629 + case '6':
  3630 + (*info->fprintf_func) (info->stream, "0x%lx",
  3631 + (l >> OP_SH_RS) & OP_MASK_RS);
  3632 + break;
  3633 +
  3634 + case '7':
  3635 + (*info->fprintf_func) (info->stream, "$ac%ld",
  3636 + (l >> OP_SH_DSPACC) & OP_MASK_DSPACC);
  3637 + break;
  3638 +
  3639 + case '8':
  3640 + (*info->fprintf_func) (info->stream, "0x%lx",
  3641 + (l >> OP_SH_WRDSP) & OP_MASK_WRDSP);
  3642 + break;
  3643 +
  3644 + case '9':
  3645 + (*info->fprintf_func) (info->stream, "$ac%ld",
  3646 + (l >> OP_SH_DSPACC_S) & OP_MASK_DSPACC_S);
  3647 + break;
  3648 +
  3649 + case '0': /* dsp 6-bit signed immediate in bit 20 */
  3650 + delta = ((l >> OP_SH_DSPSFT) & OP_MASK_DSPSFT);
  3651 + if (delta & 0x20) /* test sign bit */
  3652 + delta |= ~OP_MASK_DSPSFT;
  3653 + (*info->fprintf_func) (info->stream, "%d", delta);
  3654 + break;
  3655 +
  3656 + case ':': /* dsp 7-bit signed immediate in bit 19 */
  3657 + delta = ((l >> OP_SH_DSPSFT_7) & OP_MASK_DSPSFT_7);
  3658 + if (delta & 0x40) /* test sign bit */
  3659 + delta |= ~OP_MASK_DSPSFT_7;
  3660 + (*info->fprintf_func) (info->stream, "%d", delta);
  3661 + break;
  3662 +
  3663 + case '\'':
  3664 + (*info->fprintf_func) (info->stream, "0x%lx",
  3665 + (l >> OP_SH_RDDSP) & OP_MASK_RDDSP);
  3666 + break;
  3667 +
  3668 + case '@': /* dsp 10-bit signed immediate in bit 16 */
  3669 + delta = ((l >> OP_SH_IMM10) & OP_MASK_IMM10);
  3670 + if (delta & 0x200) /* test sign bit */
  3671 + delta |= ~OP_MASK_IMM10;
  3672 + (*info->fprintf_func) (info->stream, "%d", delta);
  3673 + break;
  3674 +
  3675 + case '!':
  3676 + (*info->fprintf_func) (info->stream, "%ld",
  3677 + (l >> OP_SH_MT_U) & OP_MASK_MT_U);
  3678 + break;
  3679 +
  3680 + case '$':
  3681 + (*info->fprintf_func) (info->stream, "%ld",
  3682 + (l >> OP_SH_MT_H) & OP_MASK_MT_H);
  3683 + break;
  3684 +
  3685 + case '*':
  3686 + (*info->fprintf_func) (info->stream, "$ac%ld",
  3687 + (l >> OP_SH_MTACC_T) & OP_MASK_MTACC_T);
  3688 + break;
  3689 +
  3690 + case '&':
  3691 + (*info->fprintf_func) (info->stream, "$ac%ld",
  3692 + (l >> OP_SH_MTACC_D) & OP_MASK_MTACC_D);
  3693 + break;
  3694 +
  3695 + case 'g':
  3696 + /* Coprocessor register for CTTC1, MTTC2, MTHC2, CTTC2. */
  3697 + (*info->fprintf_func) (info->stream, "$%ld",
  3698 + (l >> OP_SH_RD) & OP_MASK_RD);
  3699 + break;
  3700 +
3529 3701 case 's':
3530 3702 case 'b':
3531 3703 case 'r':
... ... @@ -3542,7 +3714,7 @@ print_insn_args (d, l, pc, info)
3542 3714  
3543 3715 case 'i':
3544 3716 case 'u':
3545   - (*info->fprintf_func) (info->stream, "0x%x",
  3717 + (*info->fprintf_func) (info->stream, "0x%lx",
3546 3718 (l >> OP_SH_IMMEDIATE) & OP_MASK_IMMEDIATE);
3547 3719 break;
3548 3720  
... ... @@ -3570,6 +3742,10 @@ print_insn_args (d, l, pc, info)
3570 3742 case 'a':
3571 3743 info->target = (((pc + 4) & ~(bfd_vma) 0x0fffffff)
3572 3744 | (((l >> OP_SH_TARGET) & OP_MASK_TARGET) << 2));
  3745 + /* For gdb disassembler, force odd address on jalx. */
  3746 + if (info->flavour == bfd_target_unknown_flavour
  3747 + && strcmp (opp->name, "jalx") == 0)
  3748 + info->target |= 1;
3573 3749 (*info->print_address_func) (info->target, info);
3574 3750 break;
3575 3751  
... ... @@ -3616,32 +3792,33 @@ print_insn_args (d, l, pc, info)
3616 3792 break;
3617 3793  
3618 3794 case '<':
3619   - (*info->fprintf_func) (info->stream, "0x%x",
  3795 + (*info->fprintf_func) (info->stream, "0x%lx",
3620 3796 (l >> OP_SH_SHAMT) & OP_MASK_SHAMT);
3621 3797 break;
3622 3798  
3623 3799 case 'c':
3624   - (*info->fprintf_func) (info->stream, "0x%x",
  3800 + (*info->fprintf_func) (info->stream, "0x%lx",
3625 3801 (l >> OP_SH_CODE) & OP_MASK_CODE);
3626 3802 break;
3627 3803  
3628 3804 case 'q':
3629   - (*info->fprintf_func) (info->stream, "0x%x",
  3805 + (*info->fprintf_func) (info->stream, "0x%lx",
3630 3806 (l >> OP_SH_CODE2) & OP_MASK_CODE2);
3631 3807 break;
3632 3808  
3633 3809 case 'C':
3634   - (*info->fprintf_func) (info->stream, "0x%x",
  3810 + (*info->fprintf_func) (info->stream, "0x%lx",
3635 3811 (l >> OP_SH_COPZ) & OP_MASK_COPZ);
3636 3812 break;
3637 3813  
3638 3814 case 'B':
3639   - (*info->fprintf_func) (info->stream, "0x%x",
  3815 + (*info->fprintf_func) (info->stream, "0x%lx",
  3816 +
3640 3817 (l >> OP_SH_CODE20) & OP_MASK_CODE20);
3641 3818 break;
3642 3819  
3643 3820 case 'J':
3644   - (*info->fprintf_func) (info->stream, "0x%x",
  3821 + (*info->fprintf_func) (info->stream, "0x%lx",
3645 3822 (l >> OP_SH_CODE19) & OP_MASK_CODE19);
3646 3823 break;
3647 3824  
... ... @@ -3675,7 +3852,7 @@ print_insn_args (d, l, pc, info)
3675 3852 'T' format. Therefore, until we gain understanding of
3676 3853 cp2 register names, we can simply print the register
3677 3854 numbers. */
3678   - (*info->fprintf_func) (info->stream, "$%d",
  3855 + (*info->fprintf_func) (info->stream, "$%ld",
3679 3856 (l >> OP_SH_RT) & OP_MASK_RT);
3680 3857 break;
3681 3858  
... ... @@ -3689,7 +3866,7 @@ print_insn_args (d, l, pc, info)
3689 3866 (*info->fprintf_func) (info->stream, "%s",
3690 3867 mips_cp0_names[(l >> OP_SH_RD) & OP_MASK_RD]);
3691 3868 else
3692   - (*info->fprintf_func) (info->stream, "$%d",
  3869 + (*info->fprintf_func) (info->stream, "$%ld",
3693 3870 (l >> OP_SH_RD) & OP_MASK_RD);
3694 3871 break;
3695 3872  
... ... @@ -3699,79 +3876,83 @@ print_insn_args (d, l, pc, info)
3699 3876 break;
3700 3877  
3701 3878 case 'N':
3702   - (*info->fprintf_func) (info->stream, "$fcc%d",
  3879 + (*info->fprintf_func) (info->stream,
  3880 + ((opp->pinfo & (FP_D | FP_S)) != 0
  3881 + ? "$fcc%ld" : "$cc%ld"),
3703 3882 (l >> OP_SH_BCC) & OP_MASK_BCC);
3704 3883 break;
3705 3884  
3706 3885 case 'M':
3707   - (*info->fprintf_func) (info->stream, "$fcc%d",
  3886 + (*info->fprintf_func) (info->stream, "$fcc%ld",
3708 3887 (l >> OP_SH_CCC) & OP_MASK_CCC);
3709 3888 break;
3710 3889  
3711 3890 case 'P':
3712   - (*info->fprintf_func) (info->stream, "%d",
  3891 + (*info->fprintf_func) (info->stream, "%ld",
3713 3892 (l >> OP_SH_PERFREG) & OP_MASK_PERFREG);
3714 3893 break;
3715 3894  
3716 3895 case 'e':
3717   - (*info->fprintf_func) (info->stream, "%d",
  3896 + (*info->fprintf_func) (info->stream, "%ld",
3718 3897 (l >> OP_SH_VECBYTE) & OP_MASK_VECBYTE);
3719 3898 break;
3720 3899  
3721 3900 case '%':
3722   - (*info->fprintf_func) (info->stream, "%d",
  3901 + (*info->fprintf_func) (info->stream, "%ld",
3723 3902 (l >> OP_SH_VECALIGN) & OP_MASK_VECALIGN);
3724 3903 break;
3725 3904  
3726 3905 case 'H':
3727   - (*info->fprintf_func) (info->stream, "%d",
  3906 + (*info->fprintf_func) (info->stream, "%ld",
3728 3907 (l >> OP_SH_SEL) & OP_MASK_SEL);
3729 3908 break;
3730 3909  
3731 3910 case 'O':
3732   - (*info->fprintf_func) (info->stream, "%d",
  3911 + (*info->fprintf_func) (info->stream, "%ld",
3733 3912 (l >> OP_SH_ALN) & OP_MASK_ALN);
3734 3913 break;
3735 3914  
3736 3915 case 'Q':
3737 3916 {
3738 3917 unsigned int vsel = (l >> OP_SH_VSEL) & OP_MASK_VSEL;
  3918 +
3739 3919 if ((vsel & 0x10) == 0)
3740 3920 {
3741 3921 int fmt;
  3922 +
3742 3923 vsel &= 0x0f;
3743 3924 for (fmt = 0; fmt < 3; fmt++, vsel >>= 1)
3744 3925 if ((vsel & 1) == 0)
3745 3926 break;
3746   - (*info->fprintf_func) (info->stream, "$v%d[%d]",
  3927 + (*info->fprintf_func) (info->stream, "$v%ld[%d]",
3747 3928 (l >> OP_SH_FT) & OP_MASK_FT,
3748 3929 vsel >> 1);
3749 3930 }
3750 3931 else if ((vsel & 0x08) == 0)
3751 3932 {
3752   - (*info->fprintf_func) (info->stream, "$v%d",
  3933 + (*info->fprintf_func) (info->stream, "$v%ld",
3753 3934 (l >> OP_SH_FT) & OP_MASK_FT);
3754 3935 }
3755 3936 else
3756 3937 {
3757   - (*info->fprintf_func) (info->stream, "0x%x",
  3938 + (*info->fprintf_func) (info->stream, "0x%lx",
3758 3939 (l >> OP_SH_FT) & OP_MASK_FT);
3759 3940 }
3760 3941 }
3761 3942 break;
3762 3943  
3763 3944 case 'X':
3764   - (*info->fprintf_func) (info->stream, "$v%d",
  3945 + (*info->fprintf_func) (info->stream, "$v%ld",
3765 3946 (l >> OP_SH_FD) & OP_MASK_FD);
3766 3947 break;
3767 3948  
3768 3949 case 'Y':
3769   - (*info->fprintf_func) (info->stream, "$v%d",
  3950 + (*info->fprintf_func) (info->stream, "$v%ld",
3770 3951 (l >> OP_SH_FS) & OP_MASK_FS);
3771 3952 break;
3772 3953  
3773 3954 case 'Z':
3774   - (*info->fprintf_func) (info->stream, "$v%d",
  3955 + (*info->fprintf_func) (info->stream, "$v%ld",
3775 3956 (l >> OP_SH_FT) & OP_MASK_FT);
3776 3957 break;
3777 3958  
... ... @@ -3809,12 +3990,11 @@ is_newabi (header)
3809 3990 this is little-endian code. */
3810 3991  
3811 3992 static int
3812   -print_insn_mips (memaddr, word, info)
3813   - bfd_vma memaddr;
3814   - unsigned long int word;
3815   - struct disassemble_info *info;
  3993 +print_insn_mips (bfd_vma memaddr,
  3994 + unsigned long int word,
  3995 + struct disassemble_info *info)
3816 3996 {
3817   - register const struct mips_opcode *op;
  3997 + const struct mips_opcode *op;
3818 3998 static bfd_boolean init = 0;
3819 3999 static const struct mips_opcode *mips_hash[OP_MASK_OP + 1];
3820 4000  
... ... @@ -3827,7 +4007,8 @@ print_insn_mips (memaddr, word, info)
3827 4007 {
3828 4008 for (op = mips_opcodes; op < &mips_opcodes[NUMOPCODES]; op++)
3829 4009 {
3830   - if (op->pinfo == INSN_MACRO)
  4010 + if (op->pinfo == INSN_MACRO
  4011 + || (no_aliases && (op->pinfo2 & INSN2_ALIAS)))
3831 4012 continue;
3832 4013 if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
3833 4014 {
... ... @@ -3854,9 +4035,11 @@ print_insn_mips (memaddr, word, info)
3854 4035 {
3855 4036 for (; op < &mips_opcodes[NUMOPCODES]; op++)
3856 4037 {
3857   - if (op->pinfo != INSN_MACRO && (word & op->mask) == op->match)
  4038 + if (op->pinfo != INSN_MACRO
  4039 + && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
  4040 + && (word & op->mask) == op->match)
3858 4041 {
3859   - register const char *d;
  4042 + const char *d;
3860 4043  
3861 4044 /* We always allow to disassemble the jalx instruction. */
3862 4045 if (! OPCODE_IS_MEMBER (op, mips_isa, mips_processor)
... ... @@ -3891,7 +4074,7 @@ print_insn_mips (memaddr, word, info)
3891 4074 if (d != NULL && *d != '\0')
3892 4075 {
3893 4076 (*info->fprintf_func) (info->stream, "\t");
3894   - print_insn_args (d, word, memaddr, info);
  4077 + print_insn_args (d, word, memaddr, info, op);
3895 4078 }
3896 4079  
3897 4080 return INSNLEN;
... ... @@ -3901,7 +4084,7 @@ print_insn_mips (memaddr, word, info)
3901 4084  
3902 4085 /* Handle undefined instructions. */
3903 4086 info->insn_type = dis_noninsn;
3904   - (*info->fprintf_func) (info->stream, "0x%x", word);
  4087 + (*info->fprintf_func) (info->stream, "0x%lx", word);
3905 4088 return INSNLEN;
3906 4089 }
3907 4090  
... ... @@ -3912,10 +4095,9 @@ print_insn_mips (memaddr, word, info)
3912 4095 this works. Otherwise, we need a clue. Sometimes. */
3913 4096  
3914 4097 static int
3915   -_print_insn_mips (memaddr, info, endianness)
3916   - bfd_vma memaddr;
3917   - struct disassemble_info *info;
3918   - enum bfd_endian endianness;
  4098 +_print_insn_mips (bfd_vma memaddr,
  4099 + struct disassemble_info *info,
  4100 + enum bfd_endian endianness)
3919 4101 {
3920 4102 bfd_byte buffer[INSNLEN];
3921 4103 int status;
... ... @@ -3961,17 +4143,13 @@ _print_insn_mips (memaddr, info, endianness)
3961 4143 }
3962 4144  
3963 4145 int
3964   -print_insn_big_mips (memaddr, info)
3965   - bfd_vma memaddr;
3966   - struct disassemble_info *info;
  4146 +print_insn_big_mips (bfd_vma memaddr, struct disassemble_info *info)
3967 4147 {
3968 4148 return _print_insn_mips (memaddr, info, BFD_ENDIAN_BIG);
3969 4149 }
3970 4150  
3971 4151 int
3972   -print_insn_little_mips (memaddr, info)
3973   - bfd_vma memaddr;
3974   - struct disassemble_info *info;
  4152 +print_insn_little_mips (bfd_vma memaddr, struct disassemble_info *info)
3975 4153 {
3976 4154 return _print_insn_mips (memaddr, info, BFD_ENDIAN_LITTLE);
3977 4155 }
... ... @@ -3979,9 +4157,7 @@ print_insn_little_mips (memaddr, info)
3979 4157 /* Disassemble mips16 instructions. */
3980 4158 #if 0
3981 4159 static int
3982   -print_insn_mips16 (memaddr, info)
3983   - bfd_vma memaddr;
3984   - struct disassemble_info *info;
  4160 +print_insn_mips16 (bfd_vma memaddr, struct disassemble_info *info)
3985 4161 {
3986 4162 int status;
3987 4163 bfd_byte buffer[2];
... ... @@ -4054,7 +4230,9 @@ print_insn_mips16 (memaddr, info)
4054 4230 opend = mips16_opcodes + bfd_mips16_num_opcodes;
4055 4231 for (op = mips16_opcodes; op < opend; op++)
4056 4232 {
4057   - if (op->pinfo != INSN_MACRO && (insn & op->mask) == op->match)
  4233 + if (op->pinfo != INSN_MACRO
  4234 + && !(no_aliases && (op->pinfo2 & INSN2_ALIAS))
  4235 + && (insn & op->mask) == op->match)
4058 4236 {
4059 4237 const char *s;
4060 4238  
... ... @@ -4135,14 +4313,13 @@ print_insn_mips16 (memaddr, info)
4135 4313 /* Disassemble an operand for a mips16 instruction. */
4136 4314  
4137 4315 static void
4138   -print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
4139   - char type;
4140   - const struct mips_opcode *op;
4141   - int l;
4142   - bfd_boolean use_extend;
4143   - int extend;
4144   - bfd_vma memaddr;
4145   - struct disassemble_info *info;
  4316 +print_mips16_insn_arg (char type,
  4317 + const struct mips_opcode *op,
  4318 + int l,
  4319 + bfd_boolean use_extend,
  4320 + int extend,
  4321 + bfd_vma memaddr,
  4322 + struct disassemble_info *info)
4146 4323 {
4147 4324 switch (type)
4148 4325 {
... ... @@ -4155,27 +4332,27 @@ print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
4155 4332 case 'y':
4156 4333 case 'w':
4157 4334 (*info->fprintf_func) (info->stream, "%s",
4158   - mips16_reg_names[((l >> MIPS16OP_SH_RY)
4159   - & MIPS16OP_MASK_RY)]);
  4335 + mips16_reg_names(((l >> MIPS16OP_SH_RY)
  4336 + & MIPS16OP_MASK_RY)));
4160 4337 break;
4161 4338  
4162 4339 case 'x':
4163 4340 case 'v':
4164 4341 (*info->fprintf_func) (info->stream, "%s",
4165   - mips16_reg_names[((l >> MIPS16OP_SH_RX)
4166   - & MIPS16OP_MASK_RX)]);
  4342 + mips16_reg_names(((l >> MIPS16OP_SH_RX)
  4343 + & MIPS16OP_MASK_RX)));
4167 4344 break;
4168 4345  
4169 4346 case 'z':
4170 4347 (*info->fprintf_func) (info->stream, "%s",
4171   - mips16_reg_names[((l >> MIPS16OP_SH_RZ)
4172   - & MIPS16OP_MASK_RZ)]);
  4348 + mips16_reg_names(((l >> MIPS16OP_SH_RZ)
  4349 + & MIPS16OP_MASK_RZ)));
4173 4350 break;
4174 4351  
4175 4352 case 'Z':
4176 4353 (*info->fprintf_func) (info->stream, "%s",
4177   - mips16_reg_names[((l >> MIPS16OP_SH_MOVE32Z)
4178   - & MIPS16OP_MASK_MOVE32Z)]);
  4354 + mips16_reg_names(((l >> MIPS16OP_SH_MOVE32Z)
  4355 + & MIPS16OP_MASK_MOVE32Z)));
4179 4356 break;
4180 4357  
4181 4358 case '0':
... ... @@ -4457,15 +4634,26 @@ print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
4457 4634 }
4458 4635 }
4459 4636 info->target = (baseaddr & ~((1 << shift) - 1)) + immed;
  4637 + if (pcrel && branch
  4638 + && info->flavour == bfd_target_unknown_flavour)
  4639 + /* For gdb disassembler, maintain odd address. */
  4640 + info->target |= 1;
4460 4641 (*info->print_address_func) (info->target, info);
4461 4642 }
4462 4643 }
4463 4644 break;
4464 4645  
4465 4646 case 'a':
4466   - if (! use_extend)
4467   - extend = 0;
4468   - l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
  4647 + {
  4648 + int jalx = l & 0x400;
  4649 +
  4650 + if (! use_extend)
  4651 + extend = 0;
  4652 + l = ((l & 0x1f) << 23) | ((l & 0x3e0) << 13) | (extend << 2);
  4653 + if (!jalx && info->flavour == bfd_target_unknown_flavour)
  4654 + /* For gdb disassembler, maintain odd address. */
  4655 + l |= 1;
  4656 + }
4469 4657 info->target = ((memaddr + 4) & ~(bfd_vma) 0x0fffffff) | l;
4470 4658 (*info->print_address_func) (info->target, info);
4471 4659 info->insn_type = dis_jsr;
... ... @@ -4528,6 +4716,92 @@ print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
4528 4716 }
4529 4717 break;
4530 4718  
  4719 + case 'm':
  4720 + case 'M':
  4721 + /* MIPS16e save/restore. */
  4722 + {
  4723 + int need_comma = 0;
  4724 + int amask, args, statics;
  4725 + int nsreg, smask;
  4726 + int framesz;
  4727 + int i, j;
  4728 +
  4729 + l = l & 0x7f;
  4730 + if (use_extend)
  4731 + l |= extend << 16;
  4732 +
  4733 + amask = (l >> 16) & 0xf;
  4734 + if (amask == MIPS16_ALL_ARGS)
  4735 + {
  4736 + args = 4;
  4737 + statics = 0;
  4738 + }
  4739 + else if (amask == MIPS16_ALL_STATICS)
  4740 + {
  4741 + args = 0;
  4742 + statics = 4;
  4743 + }
  4744 + else
  4745 + {
  4746 + args = amask >> 2;
  4747 + statics = amask & 3;
  4748 + }
  4749 +
  4750 + if (args > 0) {
  4751 + (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
  4752 + if (args > 1)
  4753 + (*info->fprintf_func) (info->stream, "-%s",
  4754 + mips_gpr_names[4 + args - 1]);
  4755 + need_comma = 1;
  4756 + }
  4757 +
  4758 + framesz = (((l >> 16) & 0xf0) | (l & 0x0f)) * 8;
  4759 + if (framesz == 0 && !use_extend)
  4760 + framesz = 128;
  4761 +
  4762 + (*info->fprintf_func) (info->stream, "%s%d",
  4763 + need_comma ? "," : "",
  4764 + framesz);
  4765 +
  4766 + if (l & 0x40) /* $ra */
  4767 + (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[31]);
  4768 +
  4769 + nsreg = (l >> 24) & 0x7;
  4770 + smask = 0;
  4771 + if (l & 0x20) /* $s0 */
  4772 + smask |= 1 << 0;
  4773 + if (l & 0x10) /* $s1 */
  4774 + smask |= 1 << 1;
  4775 + if (nsreg > 0) /* $s2-$s8 */
  4776 + smask |= ((1 << nsreg) - 1) << 2;
  4777 +
  4778 + /* Find first set static reg bit. */
  4779 + for (i = 0; i < 9; i++)
  4780 + {
  4781 + if (smask & (1 << i))
  4782 + {
  4783 + (*info->fprintf_func) (info->stream, ",%s",
  4784 + mips_gpr_names[i == 8 ? 30 : (16 + i)]);
  4785 + /* Skip over string of set bits. */
  4786 + for (j = i; smask & (2 << j); j++)
  4787 + continue;
  4788 + if (j > i)
  4789 + (*info->fprintf_func) (info->stream, "-%s",
  4790 + mips_gpr_names[j == 8 ? 30 : (16 + j)]);
  4791 + i = j + 1;
  4792 + }
  4793 + }
  4794 +
  4795 + /* Statics $ax - $a3. */
  4796 + if (statics == 1)
  4797 + (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[7]);
  4798 + else if (statics > 0)
  4799 + (*info->fprintf_func) (info->stream, ",%s-%s",
  4800 + mips_gpr_names[7 - statics + 1],
  4801 + mips_gpr_names[7]);
  4802 + }
  4803 + break;
  4804 +
4531 4805 default:
4532 4806 /* xgettext:c-format */
4533 4807 (*info->fprintf_func)
... ... @@ -4540,8 +4814,7 @@ print_mips16_insn_arg (type, op, l, use_extend, extend, memaddr, info)
4540 4814 #endif
4541 4815  
4542 4816 void
4543   -print_mips_disassembler_options (stream)
4544   - FILE *stream;
  4817 +print_mips_disassembler_options (FILE *stream)
4545 4818 {
4546 4819 unsigned int i;
4547 4820  
... ...