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 | ... | ... |