Commit 52da07d1af1884d6140cd68e0d5770f918439645
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 | ... | ... |