Commit 64a88d5d3ac0fa2280eaf1983d974628dcfb9374

Authored by blueswir1
1 parent 0828b448

CPU feature selection support

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4399 c046a42c-6fe2-441c-8c8c-71466251a162
target-sparc/cpu.h
... ... @@ -43,6 +43,7 @@
43 43 #define TT_TOVF 0x0a
44 44 #define TT_EXTINT 0x10
45 45 #define TT_CODE_ACCESS 0x21
  46 +#define TT_UNIMP_FLUSH 0x25
46 47 #define TT_DATA_ACCESS 0x29
47 48 #define TT_DIV_ZERO 0x2a
48 49 #define TT_NCP_INSN 0x24
... ... @@ -52,6 +53,7 @@
52 53 #define TT_TMISS 0x09
53 54 #define TT_CODE_ACCESS 0x0a
54 55 #define TT_ILL_INSN 0x10
  56 +#define TT_UNIMP_FLUSH TT_ILL_INSN
55 57 #define TT_PRIV_INSN 0x11
56 58 #define TT_NFPU_INSN 0x20
57 59 #define TT_FP_EXCP 0x21
... ... @@ -244,9 +246,7 @@ typedef struct CPUSPARCState {
244 246 /* temporary float registers */
245 247 float32 ft0, ft1;
246 248 float64 dt0, dt1;
247   -#if defined(CONFIG_USER_ONLY)
248 249 float128 qt0, qt1;
249   -#endif
250 250 float_status fp_status;
251 251 #if defined(TARGET_SPARC64)
252 252 #define MAXTL 4
... ... @@ -272,7 +272,32 @@ typedef struct CPUSPARCState {
272 272 void *hstick; // UA 2005
273 273 #endif
274 274 target_ulong t1, t2;
  275 + uint32_t features;
275 276 } CPUSPARCState;
  277 +
  278 +#define CPU_FEATURE_FLOAT (1 << 0)
  279 +#define CPU_FEATURE_FLOAT128 (1 << 1)
  280 +#define CPU_FEATURE_SWAP (1 << 2)
  281 +#define CPU_FEATURE_MUL (1 << 3)
  282 +#define CPU_FEATURE_DIV (1 << 4)
  283 +#define CPU_FEATURE_FLUSH (1 << 5)
  284 +#define CPU_FEATURE_FSQRT (1 << 6)
  285 +#define CPU_FEATURE_FMUL (1 << 7)
  286 +#define CPU_FEATURE_VIS1 (1 << 8)
  287 +#define CPU_FEATURE_VIS2 (1 << 9)
  288 +#ifndef TARGET_SPARC64
  289 +#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
  290 + CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
  291 + CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
  292 + CPU_FEATURE_FMUL)
  293 +#else
  294 +#define CPU_DEFAULT_FEATURES (CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | \
  295 + CPU_FEATURE_MUL | CPU_FEATURE_DIV | \
  296 + CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT | \
  297 + CPU_FEATURE_FMUL | CPU_FEATURE_VIS1 | \
  298 + CPU_FEATURE_VIS2)
  299 +#endif
  300 +
276 301 #if defined(TARGET_SPARC64)
277 302 #define GET_FSR32(env) (env->fsr & 0xcfc1ffff)
278 303 #define PUT_FSR32(env, val) do { uint32_t _tmp = val; \
... ... @@ -292,7 +317,6 @@ typedef struct CPUSPARCState {
292 317 CPUSPARCState *cpu_sparc_init(const char *cpu_model);
293 318 void gen_intermediate_code_init(CPUSPARCState *env);
294 319 int cpu_sparc_exec(CPUSPARCState *s);
295   -int cpu_sparc_close(CPUSPARCState *s);
296 320 void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt,
297 321 ...));
298 322 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu);
... ...
target-sparc/exec.h
... ... @@ -39,10 +39,8 @@ register uint32_t T2 asm(AREG3);
39 39 #define FT1 (env->ft1)
40 40 #define DT0 (env->dt0)
41 41 #define DT1 (env->dt1)
42   -#if defined(CONFIG_USER_ONLY)
43 42 #define QT0 (env->qt0)
44 43 #define QT1 (env->qt1)
45   -#endif
46 44  
47 45 #include "cpu.h"
48 46 #include "exec-all.h"
... ...
target-sparc/helper.c
... ... @@ -30,6 +30,7 @@
30 30 #include "qemu-common.h"
31 31  
32 32 //#define DEBUG_MMU
  33 +//#define DEBUG_FEATURES
33 34  
34 35 typedef struct sparc_def_t sparc_def_t;
35 36  
... ... @@ -43,9 +44,10 @@ struct sparc_def_t {
43 44 uint32_t mmu_cxr_mask;
44 45 uint32_t mmu_sfsr_mask;
45 46 uint32_t mmu_trcr_mask;
  47 + uint32_t features;
46 48 };
47 49  
48   -static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name);
  50 +static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const unsigned char *cpu_model);
49 51  
50 52 /* Sparc MMU emulation */
51 53  
... ... @@ -684,19 +686,14 @@ void cpu_reset(CPUSPARCState *env)
684 686 #endif
685 687 }
686 688  
687   -CPUSPARCState *cpu_sparc_init(const char *cpu_model)
  689 +static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
688 690 {
689   - CPUSPARCState *env;
690   - const sparc_def_t *def;
  691 + sparc_def_t def1, *def = &def1;
691 692  
692   - def = cpu_sparc_find_by_name(cpu_model);
693   - if (!def)
694   - return NULL;
  693 + if (cpu_sparc_find_by_name(def, cpu_model) < 0)
  694 + return -1;
695 695  
696   - env = qemu_mallocz(sizeof(CPUSPARCState));
697   - if (!env)
698   - return NULL;
699   - cpu_exec_init(env);
  696 + env->features = def->features;
700 697 env->cpu_model_str = cpu_model;
701 698 env->version = def->iu_version;
702 699 env->fsr = def->fpu_version;
... ... @@ -709,9 +706,29 @@ CPUSPARCState *cpu_sparc_init(const char *cpu_model)
709 706 env->mmuregs[0] |= def->mmu_version;
710 707 cpu_sparc_set_id(env, 0);
711 708 #endif
  709 + return 0;
  710 +}
  711 +
  712 +static void cpu_sparc_close(CPUSPARCState *env)
  713 +{
  714 + free(env);
  715 +}
  716 +
  717 +CPUSPARCState *cpu_sparc_init(const char *cpu_model)
  718 +{
  719 + CPUSPARCState *env;
  720 +
  721 + env = qemu_mallocz(sizeof(CPUSPARCState));
  722 + if (!env)
  723 + return NULL;
  724 + cpu_exec_init(env);
712 725  
713 726 gen_intermediate_code_init(env);
714 727  
  728 + if (cpu_sparc_register(env, cpu_model) < 0) {
  729 + cpu_sparc_close(env);
  730 + return NULL;
  731 + }
715 732 cpu_reset(env);
716 733  
717 734 return env;
... ... @@ -732,6 +749,7 @@ static const sparc_def_t sparc_defs[] = {
732 749 | (MAXTL << 8) | (NWINDOWS - 1)),
733 750 .fpu_version = 0x00000000,
734 751 .mmu_version = 0,
  752 + .features = CPU_DEFAULT_FEATURES,
735 753 },
736 754 {
737 755 .name = "Fujitsu Sparc64 III",
... ... @@ -739,6 +757,7 @@ static const sparc_def_t sparc_defs[] = {
739 757 | (MAXTL << 8) | (NWINDOWS - 1)),
740 758 .fpu_version = 0x00000000,
741 759 .mmu_version = 0,
  760 + .features = CPU_DEFAULT_FEATURES,
742 761 },
743 762 {
744 763 .name = "Fujitsu Sparc64 IV",
... ... @@ -746,6 +765,7 @@ static const sparc_def_t sparc_defs[] = {
746 765 | (MAXTL << 8) | (NWINDOWS - 1)),
747 766 .fpu_version = 0x00000000,
748 767 .mmu_version = 0,
  768 + .features = CPU_DEFAULT_FEATURES,
749 769 },
750 770 {
751 771 .name = "Fujitsu Sparc64 V",
... ... @@ -753,6 +773,7 @@ static const sparc_def_t sparc_defs[] = {
753 773 | (MAXTL << 8) | (NWINDOWS - 1)),
754 774 .fpu_version = 0x00000000,
755 775 .mmu_version = 0,
  776 + .features = CPU_DEFAULT_FEATURES,
756 777 },
757 778 {
758 779 .name = "TI UltraSparc I",
... ... @@ -760,6 +781,7 @@ static const sparc_def_t sparc_defs[] = {
760 781 | (MAXTL << 8) | (NWINDOWS - 1)),
761 782 .fpu_version = 0x00000000,
762 783 .mmu_version = 0,
  784 + .features = CPU_DEFAULT_FEATURES,
763 785 },
764 786 {
765 787 .name = "TI UltraSparc II",
... ... @@ -767,6 +789,7 @@ static const sparc_def_t sparc_defs[] = {
767 789 | (MAXTL << 8) | (NWINDOWS - 1)),
768 790 .fpu_version = 0x00000000,
769 791 .mmu_version = 0,
  792 + .features = CPU_DEFAULT_FEATURES,
770 793 },
771 794 {
772 795 .name = "TI UltraSparc IIi",
... ... @@ -774,6 +797,7 @@ static const sparc_def_t sparc_defs[] = {
774 797 | (MAXTL << 8) | (NWINDOWS - 1)),
775 798 .fpu_version = 0x00000000,
776 799 .mmu_version = 0,
  800 + .features = CPU_DEFAULT_FEATURES,
777 801 },
778 802 {
779 803 .name = "TI UltraSparc IIe",
... ... @@ -781,6 +805,7 @@ static const sparc_def_t sparc_defs[] = {
781 805 | (MAXTL << 8) | (NWINDOWS - 1)),
782 806 .fpu_version = 0x00000000,
783 807 .mmu_version = 0,
  808 + .features = CPU_DEFAULT_FEATURES,
784 809 },
785 810 {
786 811 .name = "Sun UltraSparc III",
... ... @@ -788,6 +813,7 @@ static const sparc_def_t sparc_defs[] = {
788 813 | (MAXTL << 8) | (NWINDOWS - 1)),
789 814 .fpu_version = 0x00000000,
790 815 .mmu_version = 0,
  816 + .features = CPU_DEFAULT_FEATURES,
791 817 },
792 818 {
793 819 .name = "Sun UltraSparc III Cu",
... ... @@ -795,6 +821,7 @@ static const sparc_def_t sparc_defs[] = {
795 821 | (MAXTL << 8) | (NWINDOWS - 1)),
796 822 .fpu_version = 0x00000000,
797 823 .mmu_version = 0,
  824 + .features = CPU_DEFAULT_FEATURES,
798 825 },
799 826 {
800 827 .name = "Sun UltraSparc IIIi",
... ... @@ -802,6 +829,7 @@ static const sparc_def_t sparc_defs[] = {
802 829 | (MAXTL << 8) | (NWINDOWS - 1)),
803 830 .fpu_version = 0x00000000,
804 831 .mmu_version = 0,
  832 + .features = CPU_DEFAULT_FEATURES,
805 833 },
806 834 {
807 835 .name = "Sun UltraSparc IV",
... ... @@ -809,6 +837,7 @@ static const sparc_def_t sparc_defs[] = {
809 837 | (MAXTL << 8) | (NWINDOWS - 1)),
810 838 .fpu_version = 0x00000000,
811 839 .mmu_version = 0,
  840 + .features = CPU_DEFAULT_FEATURES,
812 841 },
813 842 {
814 843 .name = "Sun UltraSparc IV+",
... ... @@ -816,6 +845,7 @@ static const sparc_def_t sparc_defs[] = {
816 845 | (MAXTL << 8) | (NWINDOWS - 1)),
817 846 .fpu_version = 0x00000000,
818 847 .mmu_version = 0,
  848 + .features = CPU_DEFAULT_FEATURES,
819 849 },
820 850 {
821 851 .name = "Sun UltraSparc IIIi+",
... ... @@ -823,6 +853,7 @@ static const sparc_def_t sparc_defs[] = {
823 853 | (MAXTL << 8) | (NWINDOWS - 1)),
824 854 .fpu_version = 0x00000000,
825 855 .mmu_version = 0,
  856 + .features = CPU_DEFAULT_FEATURES,
826 857 },
827 858 {
828 859 .name = "NEC UltraSparc I",
... ... @@ -830,6 +861,7 @@ static const sparc_def_t sparc_defs[] = {
830 861 | (MAXTL << 8) | (NWINDOWS - 1)),
831 862 .fpu_version = 0x00000000,
832 863 .mmu_version = 0,
  864 + .features = CPU_DEFAULT_FEATURES,
833 865 },
834 866 #else
835 867 {
... ... @@ -842,6 +874,7 @@ static const sparc_def_t sparc_defs[] = {
842 874 .mmu_cxr_mask = 0x0000003f,
843 875 .mmu_sfsr_mask = 0xffffffff,
844 876 .mmu_trcr_mask = 0xffffffff,
  877 + .features = CPU_FEATURE_FLOAT,
845 878 },
846 879 {
847 880 .name = "Fujitsu MB86904",
... ... @@ -853,6 +886,7 @@ static const sparc_def_t sparc_defs[] = {
853 886 .mmu_cxr_mask = 0x000000ff,
854 887 .mmu_sfsr_mask = 0x00016fff,
855 888 .mmu_trcr_mask = 0x00ffffff,
  889 + .features = CPU_DEFAULT_FEATURES,
856 890 },
857 891 {
858 892 .name = "Fujitsu MB86907",
... ... @@ -864,6 +898,7 @@ static const sparc_def_t sparc_defs[] = {
864 898 .mmu_cxr_mask = 0x000000ff,
865 899 .mmu_sfsr_mask = 0x00016fff,
866 900 .mmu_trcr_mask = 0xffffffff,
  901 + .features = CPU_DEFAULT_FEATURES,
867 902 },
868 903 {
869 904 .name = "LSI L64811",
... ... @@ -875,6 +910,7 @@ static const sparc_def_t sparc_defs[] = {
875 910 .mmu_cxr_mask = 0x0000003f,
876 911 .mmu_sfsr_mask = 0xffffffff,
877 912 .mmu_trcr_mask = 0xffffffff,
  913 + .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
878 914 },
879 915 {
880 916 .name = "Cypress CY7C601",
... ... @@ -886,6 +922,7 @@ static const sparc_def_t sparc_defs[] = {
886 922 .mmu_cxr_mask = 0x0000003f,
887 923 .mmu_sfsr_mask = 0xffffffff,
888 924 .mmu_trcr_mask = 0xffffffff,
  925 + .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
889 926 },
890 927 {
891 928 .name = "Cypress CY7C611",
... ... @@ -897,6 +934,7 @@ static const sparc_def_t sparc_defs[] = {
897 934 .mmu_cxr_mask = 0x0000003f,
898 935 .mmu_sfsr_mask = 0xffffffff,
899 936 .mmu_trcr_mask = 0xffffffff,
  937 + .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
900 938 },
901 939 {
902 940 .name = "TI SuperSparc II",
... ... @@ -908,6 +946,7 @@ static const sparc_def_t sparc_defs[] = {
908 946 .mmu_cxr_mask = 0x0000ffff,
909 947 .mmu_sfsr_mask = 0xffffffff,
910 948 .mmu_trcr_mask = 0xffffffff,
  949 + .features = CPU_DEFAULT_FEATURES,
911 950 },
912 951 {
913 952 .name = "TI MicroSparc I",
... ... @@ -919,6 +958,7 @@ static const sparc_def_t sparc_defs[] = {
919 958 .mmu_cxr_mask = 0x0000003f,
920 959 .mmu_sfsr_mask = 0x00016fff,
921 960 .mmu_trcr_mask = 0x0000003f,
  961 + .features = CPU_DEFAULT_FEATURES,
922 962 },
923 963 {
924 964 .name = "TI MicroSparc II",
... ... @@ -930,6 +970,7 @@ static const sparc_def_t sparc_defs[] = {
930 970 .mmu_cxr_mask = 0x000000ff,
931 971 .mmu_sfsr_mask = 0x00016fff,
932 972 .mmu_trcr_mask = 0x00ffffff,
  973 + .features = CPU_DEFAULT_FEATURES,
933 974 },
934 975 {
935 976 .name = "TI MicroSparc IIep",
... ... @@ -941,6 +982,7 @@ static const sparc_def_t sparc_defs[] = {
941 982 .mmu_cxr_mask = 0x000000ff,
942 983 .mmu_sfsr_mask = 0x00016bff,
943 984 .mmu_trcr_mask = 0x00ffffff,
  985 + .features = CPU_DEFAULT_FEATURES,
944 986 },
945 987 {
946 988 .name = "TI SuperSparc 51",
... ... @@ -952,6 +994,7 @@ static const sparc_def_t sparc_defs[] = {
952 994 .mmu_cxr_mask = 0x0000ffff,
953 995 .mmu_sfsr_mask = 0xffffffff,
954 996 .mmu_trcr_mask = 0xffffffff,
  997 + .features = CPU_DEFAULT_FEATURES,
955 998 },
956 999 {
957 1000 .name = "TI SuperSparc 61",
... ... @@ -963,6 +1006,7 @@ static const sparc_def_t sparc_defs[] = {
963 1006 .mmu_cxr_mask = 0x0000ffff,
964 1007 .mmu_sfsr_mask = 0xffffffff,
965 1008 .mmu_trcr_mask = 0xffffffff,
  1009 + .features = CPU_DEFAULT_FEATURES,
966 1010 },
967 1011 {
968 1012 .name = "Ross RT625",
... ... @@ -974,6 +1018,7 @@ static const sparc_def_t sparc_defs[] = {
974 1018 .mmu_cxr_mask = 0x0000003f,
975 1019 .mmu_sfsr_mask = 0xffffffff,
976 1020 .mmu_trcr_mask = 0xffffffff,
  1021 + .features = CPU_DEFAULT_FEATURES,
977 1022 },
978 1023 {
979 1024 .name = "Ross RT620",
... ... @@ -985,6 +1030,7 @@ static const sparc_def_t sparc_defs[] = {
985 1030 .mmu_cxr_mask = 0x0000003f,
986 1031 .mmu_sfsr_mask = 0xffffffff,
987 1032 .mmu_trcr_mask = 0xffffffff,
  1033 + .features = CPU_DEFAULT_FEATURES,
988 1034 },
989 1035 {
990 1036 .name = "BIT B5010",
... ... @@ -996,6 +1042,7 @@ static const sparc_def_t sparc_defs[] = {
996 1042 .mmu_cxr_mask = 0x0000003f,
997 1043 .mmu_sfsr_mask = 0xffffffff,
998 1044 .mmu_trcr_mask = 0xffffffff,
  1045 + .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT,
999 1046 },
1000 1047 {
1001 1048 .name = "Matsushita MN10501",
... ... @@ -1007,6 +1054,7 @@ static const sparc_def_t sparc_defs[] = {
1007 1054 .mmu_cxr_mask = 0x0000003f,
1008 1055 .mmu_sfsr_mask = 0xffffffff,
1009 1056 .mmu_trcr_mask = 0xffffffff,
  1057 + .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT,
1010 1058 },
1011 1059 {
1012 1060 .name = "Weitek W8601",
... ... @@ -1018,6 +1066,7 @@ static const sparc_def_t sparc_defs[] = {
1018 1066 .mmu_cxr_mask = 0x0000003f,
1019 1067 .mmu_sfsr_mask = 0xffffffff,
1020 1068 .mmu_trcr_mask = 0xffffffff,
  1069 + .features = CPU_DEFAULT_FEATURES,
1021 1070 },
1022 1071 {
1023 1072 .name = "LEON2",
... ... @@ -1029,6 +1078,7 @@ static const sparc_def_t sparc_defs[] = {
1029 1078 .mmu_cxr_mask = 0x0000003f,
1030 1079 .mmu_sfsr_mask = 0xffffffff,
1031 1080 .mmu_trcr_mask = 0xffffffff,
  1081 + .features = CPU_DEFAULT_FEATURES,
1032 1082 },
1033 1083 {
1034 1084 .name = "LEON3",
... ... @@ -1040,20 +1090,137 @@ static const sparc_def_t sparc_defs[] = {
1040 1090 .mmu_cxr_mask = 0x0000003f,
1041 1091 .mmu_sfsr_mask = 0xffffffff,
1042 1092 .mmu_trcr_mask = 0xffffffff,
  1093 + .features = CPU_DEFAULT_FEATURES,
1043 1094 },
1044 1095 #endif
1045 1096 };
1046 1097  
1047   -static const sparc_def_t *cpu_sparc_find_by_name(const unsigned char *name)
  1098 +static const char * const feature_name[] = {
  1099 + "float",
  1100 + "float128",
  1101 + "swap",
  1102 + "mul",
  1103 + "div",
  1104 + "flush",
  1105 + "fsqrt",
  1106 + "fmul",
  1107 + "vis1",
  1108 + "vis2",
  1109 +};
  1110 +
  1111 +static void print_features(FILE *f,
  1112 + int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
  1113 + uint32_t features, const char *prefix)
1048 1114 {
1049 1115 unsigned int i;
1050 1116  
  1117 + for (i = 0; i < ARRAY_SIZE(feature_name); i++)
  1118 + if (feature_name[i] && (features & (1 << i))) {
  1119 + if (prefix)
  1120 + (*cpu_fprintf)(f, "%s", prefix);
  1121 + (*cpu_fprintf)(f, "%s ", feature_name[i]);
  1122 + }
  1123 +}
  1124 +
  1125 +static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
  1126 +{
  1127 + unsigned int i;
  1128 +
  1129 + for (i = 0; i < ARRAY_SIZE(feature_name); i++)
  1130 + if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
  1131 + *features |= 1 << i;
  1132 + return;
  1133 + }
  1134 + fprintf(stderr, "CPU feature %s not found\n", flagname);
  1135 +}
  1136 +
  1137 +static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const unsigned char *cpu_model)
  1138 +{
  1139 + unsigned int i;
  1140 + const sparc_def_t *def = NULL;
  1141 + char *s = strdup(cpu_model);
  1142 + char *featurestr, *name = strtok(s, ",");
  1143 + uint32_t plus_features = 0;
  1144 + uint32_t minus_features = 0;
  1145 + long long iu_version;
  1146 + uint32_t fpu_version, mmu_version;
  1147 +
1051 1148 for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1052 1149 if (strcasecmp(name, sparc_defs[i].name) == 0) {
1053   - return &sparc_defs[i];
  1150 + def = &sparc_defs[i];
1054 1151 }
1055 1152 }
1056   - return NULL;
  1153 + if (!def)
  1154 + goto error;
  1155 + memcpy(cpu_def, def, sizeof(*def));
  1156 +
  1157 + featurestr = strtok(NULL, ",");
  1158 + while (featurestr) {
  1159 + char *val;
  1160 +
  1161 + if (featurestr[0] == '+') {
  1162 + add_flagname_to_bitmaps(featurestr + 1, &plus_features);
  1163 + } else if (featurestr[0] == '-') {
  1164 + add_flagname_to_bitmaps(featurestr + 1, &minus_features);
  1165 + } else if ((val = strchr(featurestr, '='))) {
  1166 + *val = 0; val++;
  1167 + if (!strcmp(featurestr, "iu_version")) {
  1168 + char *err;
  1169 +
  1170 + iu_version = strtoll(val, &err, 0);
  1171 + if (!*val || *err) {
  1172 + fprintf(stderr, "bad numerical value %s\n", val);
  1173 + goto error;
  1174 + }
  1175 + cpu_def->iu_version = iu_version;
  1176 +#ifdef DEBUG_FEATURES
  1177 + fprintf(stderr, "iu_version %llx\n", iu_version);
  1178 +#endif
  1179 + } else if (!strcmp(featurestr, "fpu_version")) {
  1180 + char *err;
  1181 +
  1182 + fpu_version = strtol(val, &err, 0);
  1183 + if (!*val || *err) {
  1184 + fprintf(stderr, "bad numerical value %s\n", val);
  1185 + goto error;
  1186 + }
  1187 + cpu_def->fpu_version = fpu_version;
  1188 +#ifdef DEBUG_FEATURES
  1189 + fprintf(stderr, "fpu_version %llx\n", fpu_version);
  1190 +#endif
  1191 + } else if (!strcmp(featurestr, "mmu_version")) {
  1192 + char *err;
  1193 +
  1194 + mmu_version = strtol(val, &err, 0);
  1195 + if (!*val || *err) {
  1196 + fprintf(stderr, "bad numerical value %s\n", val);
  1197 + goto error;
  1198 + }
  1199 + cpu_def->mmu_version = mmu_version;
  1200 +#ifdef DEBUG_FEATURES
  1201 + fprintf(stderr, "mmu_version %llx\n", mmu_version);
  1202 +#endif
  1203 + } else {
  1204 + fprintf(stderr, "unrecognized feature %s\n", featurestr);
  1205 + goto error;
  1206 + }
  1207 + } else {
  1208 + fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);
  1209 + goto error;
  1210 + }
  1211 + featurestr = strtok(NULL, ",");
  1212 + }
  1213 + cpu_def->features |= plus_features;
  1214 + cpu_def->features &= ~minus_features;
  1215 +#ifdef DEBUG_FEATURES
  1216 + print_features(stderr, fprintf, cpu_def->features, NULL);
  1217 +#endif
  1218 + free(s);
  1219 + return 0;
  1220 +
  1221 + error:
  1222 + free(s);
  1223 + return -1;
1057 1224 }
1058 1225  
1059 1226 void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
... ... @@ -1061,12 +1228,19 @@ void sparc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
1061 1228 unsigned int i;
1062 1229  
1063 1230 for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1064   - (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x\n",
  1231 + (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x ",
1065 1232 sparc_defs[i].name,
1066 1233 sparc_defs[i].iu_version,
1067 1234 sparc_defs[i].fpu_version,
1068 1235 sparc_defs[i].mmu_version);
  1236 + print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES & ~sparc_defs[i].features, "-");
  1237 + print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES & sparc_defs[i].features, "+");
  1238 + (*cpu_fprintf)(f, "\n");
1069 1239 }
  1240 + (*cpu_fprintf)(f, "CPU feature flags (+/-): ");
  1241 + print_features(f, cpu_fprintf, -1, NULL);
  1242 + (*cpu_fprintf)(f, "\n");
  1243 + (*cpu_fprintf)(f, "Numerical features (=): iu_version fpu_version mmu_version\n");
1070 1244 }
1071 1245  
1072 1246 #define GET_FLAG(a,b) ((env->psr & a)?b:'-')
... ...
target-sparc/helper.h
... ... @@ -48,10 +48,8 @@ uint64_t TCG_HELPER_PROTO helper_pack64(target_ulong high, target_ulong low);
48 48 void TCG_HELPER_PROTO helper_std_i386(target_ulong addr, int mem_idx);
49 49 void TCG_HELPER_PROTO helper_stdf(target_ulong addr, int mem_idx);
50 50 void TCG_HELPER_PROTO helper_lddf(target_ulong addr, int mem_idx);
51   -#if defined(CONFIG_USER_ONLY)
52   -void TCG_HELPER_PROTO helper_ldqf(target_ulong addr);
53   -void TCG_HELPER_PROTO helper_stqf(target_ulong addr);
54   -#endif
  51 +void TCG_HELPER_PROTO helper_ldqf(target_ulong addr, int mem_idx);
  52 +void TCG_HELPER_PROTO helper_stqf(target_ulong addr, int mem_idx);
55 53 uint64_t TCG_HELPER_PROTO helper_ld_asi(target_ulong addr, int asi,
56 54 int size, int sign);
57 55 void TCG_HELPER_PROTO helper_st_asi(target_ulong addr, uint64_t val, int asi,
... ... @@ -67,11 +65,9 @@ void TCG_HELPER_PROTO helper_fcmps(void);
67 65 void TCG_HELPER_PROTO helper_fcmpd(void);
68 66 void TCG_HELPER_PROTO helper_fcmpes(void);
69 67 void TCG_HELPER_PROTO helper_fcmped(void);
70   -#if defined(CONFIG_USER_ONLY)
71 68 void TCG_HELPER_PROTO helper_fsqrtq(void);
72 69 void TCG_HELPER_PROTO helper_fcmpq(void);
73 70 void TCG_HELPER_PROTO helper_fcmpeq(void);
74   -#endif
75 71 #ifdef TARGET_SPARC64
76 72 void TCG_HELPER_PROTO helper_fabsd(void);
77 73 void TCG_HELPER_PROTO helper_fcmps_fcc1(void);
... ... @@ -86,7 +82,6 @@ void TCG_HELPER_PROTO helper_fcmpes_fcc2(void);
86 82 void TCG_HELPER_PROTO helper_fcmped_fcc2(void);
87 83 void TCG_HELPER_PROTO helper_fcmpes_fcc3(void);
88 84 void TCG_HELPER_PROTO helper_fcmped_fcc3(void);
89   -#if defined(CONFIG_USER_ONLY)
90 85 void TCG_HELPER_PROTO helper_fabsq(void);
91 86 void TCG_HELPER_PROTO helper_fcmpq_fcc1(void);
92 87 void TCG_HELPER_PROTO helper_fcmpq_fcc2(void);
... ... @@ -95,19 +90,12 @@ void TCG_HELPER_PROTO helper_fcmpeq_fcc1(void);
95 90 void TCG_HELPER_PROTO helper_fcmpeq_fcc2(void);
96 91 void TCG_HELPER_PROTO helper_fcmpeq_fcc3(void);
97 92 #endif
98   -#endif
99 93 void TCG_HELPER_PROTO raise_exception(int tt);
100 94 #define F_HELPER_0_0(name) void TCG_HELPER_PROTO helper_f ## name(void)
101   -#if defined(CONFIG_USER_ONLY)
102 95 #define F_HELPER_SDQ_0_0(name) \
103 96 F_HELPER_0_0(name ## s); \
104 97 F_HELPER_0_0(name ## d); \
105 98 F_HELPER_0_0(name ## q)
106   -#else
107   -#define F_HELPER_SDQ_0_0(name) \
108   - F_HELPER_0_0(name ## s); \
109   - F_HELPER_0_0(name ## d);
110   -#endif
111 99  
112 100 F_HELPER_SDQ_0_0(add);
113 101 F_HELPER_SDQ_0_0(sub);
... ... @@ -124,23 +112,17 @@ F_HELPER_SDQ_0_0(xto);
124 112 #endif
125 113 F_HELPER_0_0(dtos);
126 114 F_HELPER_0_0(stod);
127   -#if defined(CONFIG_USER_ONLY)
128 115 F_HELPER_0_0(qtos);
129 116 F_HELPER_0_0(stoq);
130 117 F_HELPER_0_0(qtod);
131 118 F_HELPER_0_0(dtoq);
132   -#endif
133 119 F_HELPER_0_0(stoi);
134 120 F_HELPER_0_0(dtoi);
135   -#if defined(CONFIG_USER_ONLY)
136 121 F_HELPER_0_0(qtoi);
137   -#endif
138 122 #ifdef TARGET_SPARC64
139 123 F_HELPER_0_0(stox);
140 124 F_HELPER_0_0(dtox);
141   -#if defined(CONFIG_USER_ONLY)
142 125 F_HELPER_0_0(qtox);
143   -#endif
144 126 F_HELPER_0_0(aligndata);
145 127 void TCG_HELPER_PROTO helper_movl_FT0_0(void);
146 128 void TCG_HELPER_PROTO helper_movl_DT0_0(void);
... ...
target-sparc/op_helper.c
... ... @@ -61,7 +61,6 @@ void helper_check_align(target_ulong addr, uint32_t align)
61 61  
62 62 #define F_HELPER(name, p) void helper_f##name##p(void)
63 63  
64   -#if defined(CONFIG_USER_ONLY)
65 64 #define F_BINOP(name) \
66 65 F_HELPER(name, s) \
67 66 { \
... ... @@ -75,17 +74,6 @@ void helper_check_align(target_ulong addr, uint32_t align)
75 74 { \
76 75 QT0 = float128_ ## name (QT0, QT1, &env->fp_status); \
77 76 }
78   -#else
79   -#define F_BINOP(name) \
80   - F_HELPER(name, s) \
81   - { \
82   - FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \
83   - } \
84   - F_HELPER(name, d) \
85   - { \
86   - DT0 = float64_ ## name (DT0, DT1, &env->fp_status); \
87   - }
88   -#endif
89 77  
90 78 F_BINOP(add);
91 79 F_BINOP(sub);
... ... @@ -100,14 +88,12 @@ void helper_fsmuld(void)
100 88 &env->fp_status);
101 89 }
102 90  
103   -#if defined(CONFIG_USER_ONLY)
104 91 void helper_fdmulq(void)
105 92 {
106 93 QT0 = float128_mul(float64_to_float128(DT0, &env->fp_status),
107 94 float64_to_float128(DT1, &env->fp_status),
108 95 &env->fp_status);
109 96 }
110   -#endif
111 97  
112 98 F_HELPER(neg, s)
113 99 {
... ... @@ -120,13 +106,11 @@ F_HELPER(neg, d)
120 106 DT0 = float64_chs(DT1);
121 107 }
122 108  
123   -#if defined(CONFIG_USER_ONLY)
124 109 F_HELPER(neg, q)
125 110 {
126 111 QT0 = float128_chs(QT1);
127 112 }
128 113 #endif
129   -#endif
130 114  
131 115 /* Integer to float conversion. */
132 116 F_HELPER(ito, s)
... ... @@ -139,12 +123,10 @@ F_HELPER(ito, d)
139 123 DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
140 124 }
141 125  
142   -#if defined(CONFIG_USER_ONLY)
143 126 F_HELPER(ito, q)
144 127 {
145 128 QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status);
146 129 }
147   -#endif
148 130  
149 131 #ifdef TARGET_SPARC64
150 132 F_HELPER(xto, s)
... ... @@ -156,13 +138,12 @@ F_HELPER(xto, d)
156 138 {
157 139 DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
158 140 }
159   -#if defined(CONFIG_USER_ONLY)
  141 +
160 142 F_HELPER(xto, q)
161 143 {
162 144 QT0 = int64_to_float128(*((int64_t *)&DT1), &env->fp_status);
163 145 }
164 146 #endif
165   -#endif
166 147 #undef F_HELPER
167 148  
168 149 /* floating point conversion */
... ... @@ -176,7 +157,6 @@ void helper_fstod(void)
176 157 DT0 = float32_to_float64(FT1, &env->fp_status);
177 158 }
178 159  
179   -#if defined(CONFIG_USER_ONLY)
180 160 void helper_fqtos(void)
181 161 {
182 162 FT0 = float128_to_float32(QT1, &env->fp_status);
... ... @@ -196,7 +176,6 @@ void helper_fdtoq(void)
196 176 {
197 177 QT0 = float64_to_float128(DT1, &env->fp_status);
198 178 }
199   -#endif
200 179  
201 180 /* Float to integer conversion. */
202 181 void helper_fstoi(void)
... ... @@ -209,12 +188,10 @@ void helper_fdtoi(void)
209 188 *((int32_t *)&FT0) = float64_to_int32_round_to_zero(DT1, &env->fp_status);
210 189 }
211 190  
212   -#if defined(CONFIG_USER_ONLY)
213 191 void helper_fqtoi(void)
214 192 {
215 193 *((int32_t *)&FT0) = float128_to_int32_round_to_zero(QT1, &env->fp_status);
216 194 }
217   -#endif
218 195  
219 196 #ifdef TARGET_SPARC64
220 197 void helper_fstox(void)
... ... @@ -227,12 +204,10 @@ void helper_fdtox(void)
227 204 *((int64_t *)&DT0) = float64_to_int64_round_to_zero(DT1, &env->fp_status);
228 205 }
229 206  
230   -#if defined(CONFIG_USER_ONLY)
231 207 void helper_fqtox(void)
232 208 {
233 209 *((int64_t *)&DT0) = float128_to_int64_round_to_zero(QT1, &env->fp_status);
234 210 }
235   -#endif
236 211  
237 212 void helper_faligndata(void)
238 213 {
... ... @@ -722,13 +697,11 @@ void helper_fabsd(void)
722 697 DT0 = float64_abs(DT1);
723 698 }
724 699  
725   -#if defined(CONFIG_USER_ONLY)
726 700 void helper_fabsq(void)
727 701 {
728 702 QT0 = float128_abs(QT1);
729 703 }
730 704 #endif
731   -#endif
732 705  
733 706 void helper_fsqrts(void)
734 707 {
... ... @@ -740,12 +713,10 @@ void helper_fsqrtd(void)
740 713 DT0 = float64_sqrt(DT1, &env->fp_status);
741 714 }
742 715  
743   -#if defined(CONFIG_USER_ONLY)
744 716 void helper_fsqrtq(void)
745 717 {
746 718 QT0 = float128_sqrt(QT1, &env->fp_status);
747 719 }
748   -#endif
749 720  
750 721 #define GEN_FCMP(name, size, reg1, reg2, FS, TRAP) \
751 722 void glue(helper_, name) (void) \
... ... @@ -784,38 +755,34 @@ GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0);
784 755 GEN_FCMP(fcmpes, float32, FT0, FT1, 0, 1);
785 756 GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1);
786 757  
787   -#ifdef CONFIG_USER_ONLY
788 758 GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0);
789 759 GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1);
790   -#endif
791 760  
792 761 #ifdef TARGET_SPARC64
793 762 GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22, 0);
794 763 GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0);
  764 +GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
795 765  
796 766 GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24, 0);
797 767 GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0);
  768 +GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
798 769  
799 770 GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26, 0);
800 771 GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0);
  772 +GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
801 773  
802 774 GEN_FCMP(fcmpes_fcc1, float32, FT0, FT1, 22, 1);
803 775 GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1);
  776 +GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
804 777  
805 778 GEN_FCMP(fcmpes_fcc2, float32, FT0, FT1, 24, 1);
806 779 GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1);
  780 +GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
807 781  
808 782 GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1);
809 783 GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
810   -#ifdef CONFIG_USER_ONLY
811   -GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
812   -GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
813   -GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
814   -GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
815   -GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
816 784 GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
817 785 #endif
818   -#endif
819 786  
820 787 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && defined(DEBUG_MXCC)
821 788 static void dump_mxcc(CPUState *env)
... ... @@ -2074,11 +2041,9 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd)
2074 2041 case 8:
2075 2042 *((int64_t *)&DT0) = val;
2076 2043 break;
2077   -#if defined(CONFIG_USER_ONLY)
2078 2044 case 16:
2079 2045 // XXX
2080 2046 break;
2081   -#endif
2082 2047 }
2083 2048 }
2084 2049  
... ... @@ -2119,11 +2084,9 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd)
2119 2084 case 8:
2120 2085 val = *((int64_t *)&DT0);
2121 2086 break;
2122   -#if defined(CONFIG_USER_ONLY)
2123 2087 case 16:
2124 2088 // XXX
2125 2089 break;
2126   -#endif
2127 2090 }
2128 2091 helper_st_asi(addr, val, asi, size);
2129 2092 }
... ... @@ -2299,27 +2262,73 @@ void helper_lddf(target_ulong addr, int mem_idx)
2299 2262 #endif
2300 2263 }
2301 2264  
2302   -#if defined(CONFIG_USER_ONLY)
2303   -void helper_ldqf(target_ulong addr)
  2265 +void helper_ldqf(target_ulong addr, int mem_idx)
2304 2266 {
2305 2267 // XXX add 128 bit load
2306 2268 CPU_QuadU u;
2307 2269  
  2270 +#if !defined(CONFIG_USER_ONLY)
  2271 + switch (mem_idx) {
  2272 + case 0:
  2273 + u.ll.upper = ldq_user(ADDR(addr));
  2274 + u.ll.lower = ldq_user(ADDR(addr + 8));
  2275 + QT0 = u.q;
  2276 + break;
  2277 + case 1:
  2278 + u.ll.upper = ldq_kernel(ADDR(addr));
  2279 + u.ll.lower = ldq_kernel(ADDR(addr + 8));
  2280 + QT0 = u.q;
  2281 + break;
  2282 +#ifdef TARGET_SPARC64
  2283 + case 2:
  2284 + u.ll.upper = ldq_hypv(ADDR(addr));
  2285 + u.ll.lower = ldq_hypv(ADDR(addr + 8));
  2286 + QT0 = u.q;
  2287 + break;
  2288 +#endif
  2289 + default:
  2290 + break;
  2291 + }
  2292 +#else
2308 2293 u.ll.upper = ldq_raw(ADDR(addr));
2309 2294 u.ll.lower = ldq_raw(ADDR(addr + 8));
2310 2295 QT0 = u.q;
  2296 +#endif
2311 2297 }
2312 2298  
2313   -void helper_stqf(target_ulong addr)
  2299 +void helper_stqf(target_ulong addr, int mem_idx)
2314 2300 {
2315 2301 // XXX add 128 bit store
2316 2302 CPU_QuadU u;
2317 2303  
  2304 +#if !defined(CONFIG_USER_ONLY)
  2305 + switch (mem_idx) {
  2306 + case 0:
  2307 + u.q = QT0;
  2308 + stq_user(ADDR(addr), u.ll.upper);
  2309 + stq_user(ADDR(addr + 8), u.ll.lower);
  2310 + break;
  2311 + case 1:
  2312 + u.q = QT0;
  2313 + stq_kernel(ADDR(addr), u.ll.upper);
  2314 + stq_kernel(ADDR(addr + 8), u.ll.lower);
  2315 + break;
  2316 +#ifdef TARGET_SPARC64
  2317 + case 2:
  2318 + u.q = QT0;
  2319 + stq_hypv(ADDR(addr), u.ll.upper);
  2320 + stq_hypv(ADDR(addr + 8), u.ll.lower);
  2321 + break;
  2322 +#endif
  2323 + default:
  2324 + break;
  2325 + }
  2326 +#else
2318 2327 u.q = QT0;
2319 2328 stq_raw(ADDR(addr), u.ll.upper);
2320 2329 stq_raw(ADDR(addr + 8), u.ll.lower);
2321   -}
2322 2330 #endif
  2331 +}
2323 2332  
2324 2333 #undef ADDR
2325 2334  
... ...
target-sparc/translate.c
... ... @@ -63,6 +63,7 @@ typedef struct DisasContext {
63 63 int mem_idx;
64 64 int fpu_enabled;
65 65 struct TranslationBlock *tb;
  66 + uint32_t features;
66 67 } DisasContext;
67 68  
68 69 extern FILE *logfile;
... ... @@ -140,7 +141,6 @@ static void gen_op_store_DT0_fpr(unsigned int dst)
140 141 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1]));
141 142 }
142 143  
143   -#ifdef CONFIG_USER_ONLY
144 144 static void gen_op_load_fpr_QT0(unsigned int src)
145 145 {
146 146 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src]));
... ... @@ -176,7 +176,6 @@ static void gen_op_store_QT0_fpr(unsigned int dst)
176 176 tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + offsetof(CPU_QuadU, l.lowest));
177 177 tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3]));
178 178 }
179   -#endif
180 179  
181 180 /* moves */
182 181 #ifdef CONFIG_USER_ONLY
... ... @@ -1463,14 +1462,12 @@ static GenOpFunc * const gen_fcmpd[4] = {
1463 1462 helper_fcmpd_fcc3,
1464 1463 };
1465 1464  
1466   -#if defined(CONFIG_USER_ONLY)
1467 1465 static GenOpFunc * const gen_fcmpq[4] = {
1468 1466 helper_fcmpq,
1469 1467 helper_fcmpq_fcc1,
1470 1468 helper_fcmpq_fcc2,
1471 1469 helper_fcmpq_fcc3,
1472 1470 };
1473   -#endif
1474 1471  
1475 1472 static GenOpFunc * const gen_fcmpes[4] = {
1476 1473 helper_fcmpes,
... ... @@ -1486,14 +1483,12 @@ static GenOpFunc * const gen_fcmped[4] = {
1486 1483 helper_fcmped_fcc3,
1487 1484 };
1488 1485  
1489   -#if defined(CONFIG_USER_ONLY)
1490 1486 static GenOpFunc * const gen_fcmpeq[4] = {
1491 1487 helper_fcmpeq,
1492 1488 helper_fcmpeq_fcc1,
1493 1489 helper_fcmpeq_fcc2,
1494 1490 helper_fcmpeq_fcc3,
1495 1491 };
1496   -#endif
1497 1492  
1498 1493 static inline void gen_op_fcmps(int fccno)
1499 1494 {
... ... @@ -1505,12 +1500,10 @@ static inline void gen_op_fcmpd(int fccno)
1505 1500 tcg_gen_helper_0_0(gen_fcmpd[fccno]);
1506 1501 }
1507 1502  
1508   -#if defined(CONFIG_USER_ONLY)
1509 1503 static inline void gen_op_fcmpq(int fccno)
1510 1504 {
1511 1505 tcg_gen_helper_0_0(gen_fcmpq[fccno]);
1512 1506 }
1513   -#endif
1514 1507  
1515 1508 static inline void gen_op_fcmpes(int fccno)
1516 1509 {
... ... @@ -1522,12 +1515,10 @@ static inline void gen_op_fcmped(int fccno)
1522 1515 tcg_gen_helper_0_0(gen_fcmped[fccno]);
1523 1516 }
1524 1517  
1525   -#if defined(CONFIG_USER_ONLY)
1526 1518 static inline void gen_op_fcmpeq(int fccno)
1527 1519 {
1528 1520 tcg_gen_helper_0_0(gen_fcmpeq[fccno]);
1529 1521 }
1530   -#endif
1531 1522  
1532 1523 #else
1533 1524  
... ... @@ -1541,12 +1532,10 @@ static inline void gen_op_fcmpd(int fccno)
1541 1532 tcg_gen_helper_0_0(helper_fcmpd);
1542 1533 }
1543 1534  
1544   -#if defined(CONFIG_USER_ONLY)
1545 1535 static inline void gen_op_fcmpq(int fccno)
1546 1536 {
1547 1537 tcg_gen_helper_0_0(helper_fcmpq);
1548 1538 }
1549   -#endif
1550 1539  
1551 1540 static inline void gen_op_fcmpes(int fccno)
1552 1541 {
... ... @@ -1558,15 +1547,12 @@ static inline void gen_op_fcmped(int fccno)
1558 1547 tcg_gen_helper_0_0(helper_fcmped);
1559 1548 }
1560 1549  
1561   -#if defined(CONFIG_USER_ONLY)
1562 1550 static inline void gen_op_fcmpeq(int fccno)
1563 1551 {
1564 1552 tcg_gen_helper_0_0(helper_fcmpeq);
1565 1553 }
1566 1554 #endif
1567 1555  
1568   -#endif
1569   -
1570 1556 static inline void gen_op_fpexception_im(int fsr_flags)
1571 1557 {
1572 1558 tcg_gen_andi_tl(cpu_fsr, cpu_fsr, ~FSR_FTT_MASK);
... ... @@ -1820,6 +1806,13 @@ static inline TCGv get_src2(unsigned int insn, TCGv def)
1820 1806 return r_rs2;
1821 1807 }
1822 1808  
  1809 +#define CHECK_IU_FEATURE(dc, FEATURE) \
  1810 + if (!((dc)->features & CPU_FEATURE_ ## FEATURE)) \
  1811 + goto illegal_insn;
  1812 +#define CHECK_FPU_FEATURE(dc, FEATURE) \
  1813 + if (!((dc)->features & CPU_FEATURE_ ## FEATURE)) \
  1814 + goto nfpu_insn;
  1815 +
1823 1816 /* before an instruction, dc->pc must be static */
1824 1817 static void disas_sparc_insn(DisasContext * dc)
1825 1818 {
... ... @@ -2255,6 +2248,7 @@ static void disas_sparc_insn(DisasContext * dc)
2255 2248 gen_op_store_FT0_fpr(rd);
2256 2249 break;
2257 2250 case 0x29: /* fsqrts */
  2251 + CHECK_FPU_FEATURE(dc, FSQRT);
2258 2252 gen_op_load_fpr_FT1(rs2);
2259 2253 gen_clear_float_exceptions();
2260 2254 tcg_gen_helper_0_0(helper_fsqrts);
... ... @@ -2262,6 +2256,7 @@ static void disas_sparc_insn(DisasContext * dc)
2262 2256 gen_op_store_FT0_fpr(rd);
2263 2257 break;
2264 2258 case 0x2a: /* fsqrtd */
  2259 + CHECK_FPU_FEATURE(dc, FSQRT);
2265 2260 gen_op_load_fpr_DT1(DFPREG(rs2));
2266 2261 gen_clear_float_exceptions();
2267 2262 tcg_gen_helper_0_0(helper_fsqrtd);
... ... @@ -2269,16 +2264,13 @@ static void disas_sparc_insn(DisasContext * dc)
2269 2264 gen_op_store_DT0_fpr(DFPREG(rd));
2270 2265 break;
2271 2266 case 0x2b: /* fsqrtq */
2272   -#if defined(CONFIG_USER_ONLY)
  2267 + CHECK_FPU_FEATURE(dc, FLOAT128);
2273 2268 gen_op_load_fpr_QT1(QFPREG(rs2));
2274 2269 gen_clear_float_exceptions();
2275 2270 tcg_gen_helper_0_0(helper_fsqrtq);
2276 2271 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2277 2272 gen_op_store_QT0_fpr(QFPREG(rd));
2278 2273 break;
2279   -#else
2280   - goto nfpu_insn;
2281   -#endif
2282 2274 case 0x41:
2283 2275 gen_op_load_fpr_FT0(rs1);
2284 2276 gen_op_load_fpr_FT1(rs2);
... ... @@ -2296,7 +2288,7 @@ static void disas_sparc_insn(DisasContext * dc)
2296 2288 gen_op_store_DT0_fpr(DFPREG(rd));
2297 2289 break;
2298 2290 case 0x43: /* faddq */
2299   -#if defined(CONFIG_USER_ONLY)
  2291 + CHECK_FPU_FEATURE(dc, FLOAT128);
2300 2292 gen_op_load_fpr_QT0(QFPREG(rs1));
2301 2293 gen_op_load_fpr_QT1(QFPREG(rs2));
2302 2294 gen_clear_float_exceptions();
... ... @@ -2304,9 +2296,6 @@ static void disas_sparc_insn(DisasContext * dc)
2304 2296 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2305 2297 gen_op_store_QT0_fpr(QFPREG(rd));
2306 2298 break;
2307   -#else
2308   - goto nfpu_insn;
2309   -#endif
2310 2299 case 0x45:
2311 2300 gen_op_load_fpr_FT0(rs1);
2312 2301 gen_op_load_fpr_FT1(rs2);
... ... @@ -2324,7 +2313,7 @@ static void disas_sparc_insn(DisasContext * dc)
2324 2313 gen_op_store_DT0_fpr(DFPREG(rd));
2325 2314 break;
2326 2315 case 0x47: /* fsubq */
2327   -#if defined(CONFIG_USER_ONLY)
  2316 + CHECK_FPU_FEATURE(dc, FLOAT128);
2328 2317 gen_op_load_fpr_QT0(QFPREG(rs1));
2329 2318 gen_op_load_fpr_QT1(QFPREG(rs2));
2330 2319 gen_clear_float_exceptions();
... ... @@ -2332,10 +2321,8 @@ static void disas_sparc_insn(DisasContext * dc)
2332 2321 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2333 2322 gen_op_store_QT0_fpr(QFPREG(rd));
2334 2323 break;
2335   -#else
2336   - goto nfpu_insn;
2337   -#endif
2338   - case 0x49:
  2324 + case 0x49: /* fmuls */
  2325 + CHECK_FPU_FEATURE(dc, FMUL);
2339 2326 gen_op_load_fpr_FT0(rs1);
2340 2327 gen_op_load_fpr_FT1(rs2);
2341 2328 gen_clear_float_exceptions();
... ... @@ -2343,7 +2330,8 @@ static void disas_sparc_insn(DisasContext * dc)
2343 2330 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2344 2331 gen_op_store_FT0_fpr(rd);
2345 2332 break;
2346   - case 0x4a:
  2333 + case 0x4a: /* fmuld */
  2334 + CHECK_FPU_FEATURE(dc, FMUL);
2347 2335 gen_op_load_fpr_DT0(DFPREG(rs1));
2348 2336 gen_op_load_fpr_DT1(DFPREG(rs2));
2349 2337 gen_clear_float_exceptions();
... ... @@ -2352,7 +2340,8 @@ static void disas_sparc_insn(DisasContext * dc)
2352 2340 gen_op_store_DT0_fpr(DFPREG(rd));
2353 2341 break;
2354 2342 case 0x4b: /* fmulq */
2355   -#if defined(CONFIG_USER_ONLY)
  2343 + CHECK_FPU_FEATURE(dc, FLOAT128);
  2344 + CHECK_FPU_FEATURE(dc, FMUL);
2356 2345 gen_op_load_fpr_QT0(QFPREG(rs1));
2357 2346 gen_op_load_fpr_QT1(QFPREG(rs2));
2358 2347 gen_clear_float_exceptions();
... ... @@ -2360,9 +2349,6 @@ static void disas_sparc_insn(DisasContext * dc)
2360 2349 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2361 2350 gen_op_store_QT0_fpr(QFPREG(rd));
2362 2351 break;
2363   -#else
2364   - goto nfpu_insn;
2365   -#endif
2366 2352 case 0x4d:
2367 2353 gen_op_load_fpr_FT0(rs1);
2368 2354 gen_op_load_fpr_FT1(rs2);
... ... @@ -2380,7 +2366,7 @@ static void disas_sparc_insn(DisasContext * dc)
2380 2366 gen_op_store_DT0_fpr(DFPREG(rd));
2381 2367 break;
2382 2368 case 0x4f: /* fdivq */
2383   -#if defined(CONFIG_USER_ONLY)
  2369 + CHECK_FPU_FEATURE(dc, FLOAT128);
2384 2370 gen_op_load_fpr_QT0(QFPREG(rs1));
2385 2371 gen_op_load_fpr_QT1(QFPREG(rs2));
2386 2372 gen_clear_float_exceptions();
... ... @@ -2388,9 +2374,6 @@ static void disas_sparc_insn(DisasContext * dc)
2388 2374 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2389 2375 gen_op_store_QT0_fpr(QFPREG(rd));
2390 2376 break;
2391   -#else
2392   - goto nfpu_insn;
2393   -#endif
2394 2377 case 0x69:
2395 2378 gen_op_load_fpr_FT0(rs1);
2396 2379 gen_op_load_fpr_FT1(rs2);
... ... @@ -2400,7 +2383,7 @@ static void disas_sparc_insn(DisasContext * dc)
2400 2383 gen_op_store_DT0_fpr(DFPREG(rd));
2401 2384 break;
2402 2385 case 0x6e: /* fdmulq */
2403   -#if defined(CONFIG_USER_ONLY)
  2386 + CHECK_FPU_FEATURE(dc, FLOAT128);
2404 2387 gen_op_load_fpr_DT0(DFPREG(rs1));
2405 2388 gen_op_load_fpr_DT1(DFPREG(rs2));
2406 2389 gen_clear_float_exceptions();
... ... @@ -2408,9 +2391,6 @@ static void disas_sparc_insn(DisasContext * dc)
2408 2391 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2409 2392 gen_op_store_QT0_fpr(QFPREG(rd));
2410 2393 break;
2411   -#else
2412   - goto nfpu_insn;
2413   -#endif
2414 2394 case 0xc4:
2415 2395 gen_op_load_fpr_FT1(rs2);
2416 2396 gen_clear_float_exceptions();
... ... @@ -2426,16 +2406,13 @@ static void disas_sparc_insn(DisasContext * dc)
2426 2406 gen_op_store_FT0_fpr(rd);
2427 2407 break;
2428 2408 case 0xc7: /* fqtos */
2429   -#if defined(CONFIG_USER_ONLY)
  2409 + CHECK_FPU_FEATURE(dc, FLOAT128);
2430 2410 gen_op_load_fpr_QT1(QFPREG(rs2));
2431 2411 gen_clear_float_exceptions();
2432 2412 tcg_gen_helper_0_0(helper_fqtos);
2433 2413 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2434 2414 gen_op_store_FT0_fpr(rd);
2435 2415 break;
2436   -#else
2437   - goto nfpu_insn;
2438   -#endif
2439 2416 case 0xc8:
2440 2417 gen_op_load_fpr_FT1(rs2);
2441 2418 tcg_gen_helper_0_0(helper_fitod);
... ... @@ -2447,43 +2424,31 @@ static void disas_sparc_insn(DisasContext * dc)
2447 2424 gen_op_store_DT0_fpr(DFPREG(rd));
2448 2425 break;
2449 2426 case 0xcb: /* fqtod */
2450   -#if defined(CONFIG_USER_ONLY)
  2427 + CHECK_FPU_FEATURE(dc, FLOAT128);
2451 2428 gen_op_load_fpr_QT1(QFPREG(rs2));
2452 2429 gen_clear_float_exceptions();
2453 2430 tcg_gen_helper_0_0(helper_fqtod);
2454 2431 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2455 2432 gen_op_store_DT0_fpr(DFPREG(rd));
2456 2433 break;
2457   -#else
2458   - goto nfpu_insn;
2459   -#endif
2460 2434 case 0xcc: /* fitoq */
2461   -#if defined(CONFIG_USER_ONLY)
  2435 + CHECK_FPU_FEATURE(dc, FLOAT128);
2462 2436 gen_op_load_fpr_FT1(rs2);
2463 2437 tcg_gen_helper_0_0(helper_fitoq);
2464 2438 gen_op_store_QT0_fpr(QFPREG(rd));
2465 2439 break;
2466   -#else
2467   - goto nfpu_insn;
2468   -#endif
2469 2440 case 0xcd: /* fstoq */
2470   -#if defined(CONFIG_USER_ONLY)
  2441 + CHECK_FPU_FEATURE(dc, FLOAT128);
2471 2442 gen_op_load_fpr_FT1(rs2);
2472 2443 tcg_gen_helper_0_0(helper_fstoq);
2473 2444 gen_op_store_QT0_fpr(QFPREG(rd));
2474 2445 break;
2475   -#else
2476   - goto nfpu_insn;
2477   -#endif
2478 2446 case 0xce: /* fdtoq */
2479   -#if defined(CONFIG_USER_ONLY)
  2447 + CHECK_FPU_FEATURE(dc, FLOAT128);
2480 2448 gen_op_load_fpr_DT1(DFPREG(rs2));
2481 2449 tcg_gen_helper_0_0(helper_fdtoq);
2482 2450 gen_op_store_QT0_fpr(QFPREG(rd));
2483 2451 break;
2484   -#else
2485   - goto nfpu_insn;
2486   -#endif
2487 2452 case 0xd1:
2488 2453 gen_op_load_fpr_FT1(rs2);
2489 2454 gen_clear_float_exceptions();
... ... @@ -2499,57 +2464,45 @@ static void disas_sparc_insn(DisasContext * dc)
2499 2464 gen_op_store_FT0_fpr(rd);
2500 2465 break;
2501 2466 case 0xd3: /* fqtoi */
2502   -#if defined(CONFIG_USER_ONLY)
  2467 + CHECK_FPU_FEATURE(dc, FLOAT128);
2503 2468 gen_op_load_fpr_QT1(QFPREG(rs2));
2504 2469 gen_clear_float_exceptions();
2505 2470 tcg_gen_helper_0_0(helper_fqtoi);
2506 2471 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2507 2472 gen_op_store_FT0_fpr(rd);
2508 2473 break;
2509   -#else
2510   - goto nfpu_insn;
2511   -#endif
2512 2474 #ifdef TARGET_SPARC64
2513 2475 case 0x2: /* V9 fmovd */
2514 2476 gen_op_load_fpr_DT0(DFPREG(rs2));
2515 2477 gen_op_store_DT0_fpr(DFPREG(rd));
2516 2478 break;
2517 2479 case 0x3: /* V9 fmovq */
2518   -#if defined(CONFIG_USER_ONLY)
  2480 + CHECK_FPU_FEATURE(dc, FLOAT128);
2519 2481 gen_op_load_fpr_QT0(QFPREG(rs2));
2520 2482 gen_op_store_QT0_fpr(QFPREG(rd));
2521 2483 break;
2522   -#else
2523   - goto nfpu_insn;
2524   -#endif
2525 2484 case 0x6: /* V9 fnegd */
2526 2485 gen_op_load_fpr_DT1(DFPREG(rs2));
2527 2486 tcg_gen_helper_0_0(helper_fnegd);
2528 2487 gen_op_store_DT0_fpr(DFPREG(rd));
2529 2488 break;
2530 2489 case 0x7: /* V9 fnegq */
2531   -#if defined(CONFIG_USER_ONLY)
  2490 + CHECK_FPU_FEATURE(dc, FLOAT128);
2532 2491 gen_op_load_fpr_QT1(QFPREG(rs2));
2533 2492 tcg_gen_helper_0_0(helper_fnegq);
2534 2493 gen_op_store_QT0_fpr(QFPREG(rd));
2535 2494 break;
2536   -#else
2537   - goto nfpu_insn;
2538   -#endif
2539 2495 case 0xa: /* V9 fabsd */
2540 2496 gen_op_load_fpr_DT1(DFPREG(rs2));
2541 2497 tcg_gen_helper_0_0(helper_fabsd);
2542 2498 gen_op_store_DT0_fpr(DFPREG(rd));
2543 2499 break;
2544 2500 case 0xb: /* V9 fabsq */
2545   -#if defined(CONFIG_USER_ONLY)
  2501 + CHECK_FPU_FEATURE(dc, FLOAT128);
2546 2502 gen_op_load_fpr_QT1(QFPREG(rs2));
2547 2503 tcg_gen_helper_0_0(helper_fabsq);
2548 2504 gen_op_store_QT0_fpr(QFPREG(rd));
2549 2505 break;
2550   -#else
2551   - goto nfpu_insn;
2552   -#endif
2553 2506 case 0x81: /* V9 fstox */
2554 2507 gen_op_load_fpr_FT1(rs2);
2555 2508 gen_clear_float_exceptions();
... ... @@ -2565,16 +2518,13 @@ static void disas_sparc_insn(DisasContext * dc)
2565 2518 gen_op_store_DT0_fpr(DFPREG(rd));
2566 2519 break;
2567 2520 case 0x83: /* V9 fqtox */
2568   -#if defined(CONFIG_USER_ONLY)
  2521 + CHECK_FPU_FEATURE(dc, FLOAT128);
2569 2522 gen_op_load_fpr_QT1(QFPREG(rs2));
2570 2523 gen_clear_float_exceptions();
2571 2524 tcg_gen_helper_0_0(helper_fqtox);
2572 2525 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2573 2526 gen_op_store_DT0_fpr(DFPREG(rd));
2574 2527 break;
2575   -#else
2576   - goto nfpu_insn;
2577   -#endif
2578 2528 case 0x84: /* V9 fxtos */
2579 2529 gen_op_load_fpr_DT1(DFPREG(rs2));
2580 2530 gen_clear_float_exceptions();
... ... @@ -2590,16 +2540,13 @@ static void disas_sparc_insn(DisasContext * dc)
2590 2540 gen_op_store_DT0_fpr(DFPREG(rd));
2591 2541 break;
2592 2542 case 0x8c: /* V9 fxtoq */
2593   -#if defined(CONFIG_USER_ONLY)
  2543 + CHECK_FPU_FEATURE(dc, FLOAT128);
2594 2544 gen_op_load_fpr_DT1(DFPREG(rs2));
2595 2545 gen_clear_float_exceptions();
2596 2546 tcg_gen_helper_0_0(helper_fxtoq);
2597 2547 tcg_gen_helper_0_0(helper_check_ieee_exceptions);
2598 2548 gen_op_store_QT0_fpr(QFPREG(rd));
2599 2549 break;
2600   -#else
2601   - goto nfpu_insn;
2602   -#endif
2603 2550 #endif
2604 2551 default:
2605 2552 goto illegal_insn;
... ... @@ -2640,9 +2587,9 @@ static void disas_sparc_insn(DisasContext * dc)
2640 2587 gen_set_label(l1);
2641 2588 break;
2642 2589 } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr
2643   -#if defined(CONFIG_USER_ONLY)
2644 2590 int l1;
2645 2591  
  2592 + CHECK_FPU_FEATURE(dc, FLOAT128);
2646 2593 l1 = gen_new_label();
2647 2594 cond = GET_FIELD_SP(insn, 14, 17);
2648 2595 cpu_src1 = get_src1(insn, cpu_src1);
... ... @@ -2652,9 +2599,6 @@ static void disas_sparc_insn(DisasContext * dc)
2652 2599 gen_op_store_QT0_fpr(QFPREG(rd));
2653 2600 gen_set_label(l1);
2654 2601 break;
2655   -#else
2656   - goto nfpu_insn;
2657   -#endif
2658 2602 }
2659 2603 #endif
2660 2604 switch (xop) {
... ... @@ -2681,12 +2625,9 @@ static void disas_sparc_insn(DisasContext * dc)
2681 2625 FMOVCC(D, 0);
2682 2626 break;
2683 2627 case 0x003: /* V9 fmovqcc %fcc0 */
2684   -#if defined(CONFIG_USER_ONLY)
  2628 + CHECK_FPU_FEATURE(dc, FLOAT128);
2685 2629 FMOVCC(Q, 0);
2686 2630 break;
2687   -#else
2688   - goto nfpu_insn;
2689   -#endif
2690 2631 case 0x041: /* V9 fmovscc %fcc1 */
2691 2632 FMOVCC(F, 1);
2692 2633 break;
... ... @@ -2694,12 +2635,9 @@ static void disas_sparc_insn(DisasContext * dc)
2694 2635 FMOVCC(D, 1);
2695 2636 break;
2696 2637 case 0x043: /* V9 fmovqcc %fcc1 */
2697   -#if defined(CONFIG_USER_ONLY)
  2638 + CHECK_FPU_FEATURE(dc, FLOAT128);
2698 2639 FMOVCC(Q, 1);
2699 2640 break;
2700   -#else
2701   - goto nfpu_insn;
2702   -#endif
2703 2641 case 0x081: /* V9 fmovscc %fcc2 */
2704 2642 FMOVCC(F, 2);
2705 2643 break;
... ... @@ -2707,12 +2645,9 @@ static void disas_sparc_insn(DisasContext * dc)
2707 2645 FMOVCC(D, 2);
2708 2646 break;
2709 2647 case 0x083: /* V9 fmovqcc %fcc2 */
2710   -#if defined(CONFIG_USER_ONLY)
  2648 + CHECK_FPU_FEATURE(dc, FLOAT128);
2711 2649 FMOVCC(Q, 2);
2712 2650 break;
2713   -#else
2714   - goto nfpu_insn;
2715   -#endif
2716 2651 case 0x0c1: /* V9 fmovscc %fcc3 */
2717 2652 FMOVCC(F, 3);
2718 2653 break;
... ... @@ -2720,12 +2655,9 @@ static void disas_sparc_insn(DisasContext * dc)
2720 2655 FMOVCC(D, 3);
2721 2656 break;
2722 2657 case 0x0c3: /* V9 fmovqcc %fcc3 */
2723   -#if defined(CONFIG_USER_ONLY)
  2658 + CHECK_FPU_FEATURE(dc, FLOAT128);
2724 2659 FMOVCC(Q, 3);
2725 2660 break;
2726   -#else
2727   - goto nfpu_insn;
2728   -#endif
2729 2661 #undef FMOVCC
2730 2662 #define FMOVCC(size_FDQ, icc) \
2731 2663 { \
... ... @@ -2749,12 +2681,9 @@ static void disas_sparc_insn(DisasContext * dc)
2749 2681 case 0x102: /* V9 fmovdcc %icc */
2750 2682 FMOVCC(D, 0);
2751 2683 case 0x103: /* V9 fmovqcc %icc */
2752   -#if defined(CONFIG_USER_ONLY)
2753   - FMOVCC(D, 0);
  2684 + CHECK_FPU_FEATURE(dc, FLOAT128);
  2685 + FMOVCC(Q, 0);
2754 2686 break;
2755   -#else
2756   - goto nfpu_insn;
2757   -#endif
2758 2687 case 0x181: /* V9 fmovscc %xcc */
2759 2688 FMOVCC(F, 1);
2760 2689 break;
... ... @@ -2762,12 +2691,9 @@ static void disas_sparc_insn(DisasContext * dc)
2762 2691 FMOVCC(D, 1);
2763 2692 break;
2764 2693 case 0x183: /* V9 fmovqcc %xcc */
2765   -#if defined(CONFIG_USER_ONLY)
  2694 + CHECK_FPU_FEATURE(dc, FLOAT128);
2766 2695 FMOVCC(Q, 1);
2767 2696 break;
2768   -#else
2769   - goto nfpu_insn;
2770   -#endif
2771 2697 #undef FMOVCC
2772 2698 #endif
2773 2699 case 0x51: /* fcmps, V9 %fcc */
... ... @@ -2781,14 +2707,11 @@ static void disas_sparc_insn(DisasContext * dc)
2781 2707 gen_op_fcmpd(rd & 3);
2782 2708 break;
2783 2709 case 0x53: /* fcmpq, V9 %fcc */
2784   -#if defined(CONFIG_USER_ONLY)
  2710 + CHECK_FPU_FEATURE(dc, FLOAT128);
2785 2711 gen_op_load_fpr_QT0(QFPREG(rs1));
2786 2712 gen_op_load_fpr_QT1(QFPREG(rs2));
2787 2713 gen_op_fcmpq(rd & 3);
2788 2714 break;
2789   -#else /* !defined(CONFIG_USER_ONLY) */
2790   - goto nfpu_insn;
2791   -#endif
2792 2715 case 0x55: /* fcmpes, V9 %fcc */
2793 2716 gen_op_load_fpr_FT0(rs1);
2794 2717 gen_op_load_fpr_FT1(rs2);
... ... @@ -2800,14 +2723,11 @@ static void disas_sparc_insn(DisasContext * dc)
2800 2723 gen_op_fcmped(rd & 3);
2801 2724 break;
2802 2725 case 0x57: /* fcmpeq, V9 %fcc */
2803   -#if defined(CONFIG_USER_ONLY)
  2726 + CHECK_FPU_FEATURE(dc, FLOAT128);
2804 2727 gen_op_load_fpr_QT0(QFPREG(rs1));
2805 2728 gen_op_load_fpr_QT1(QFPREG(rs2));
2806 2729 gen_op_fcmpeq(rd & 3);
2807 2730 break;
2808   -#else/* !defined(CONFIG_USER_ONLY) */
2809   - goto nfpu_insn;
2810   -#endif
2811 2731 default:
2812 2732 goto illegal_insn;
2813 2733 }
... ... @@ -2979,11 +2899,13 @@ static void disas_sparc_insn(DisasContext * dc)
2979 2899 break;
2980 2900 #endif
2981 2901 case 0xa:
  2902 + CHECK_IU_FEATURE(dc, MUL);
2982 2903 gen_op_umul(cpu_dst, cpu_src1, cpu_src2);
2983 2904 if (xop & 0x10)
2984 2905 gen_op_logic_cc(cpu_dst);
2985 2906 break;
2986 2907 case 0xb:
  2908 + CHECK_IU_FEATURE(dc, MUL);
2987 2909 gen_op_smul(cpu_dst, cpu_src1, cpu_src2);
2988 2910 if (xop & 0x10)
2989 2911 gen_op_logic_cc(cpu_dst);
... ... @@ -3004,11 +2926,13 @@ static void disas_sparc_insn(DisasContext * dc)
3004 2926 break;
3005 2927 #endif
3006 2928 case 0xe:
  2929 + CHECK_IU_FEATURE(dc, DIV);
3007 2930 tcg_gen_helper_1_2(helper_udiv, cpu_dst, cpu_src1, cpu_src2);
3008 2931 if (xop & 0x10)
3009 2932 gen_op_div_cc(cpu_dst);
3010 2933 break;
3011 2934 case 0xf:
  2935 + CHECK_IU_FEATURE(dc, DIV);
3012 2936 tcg_gen_helper_1_2(helper_sdiv, cpu_dst, cpu_src1, cpu_src2);
3013 2937 if (xop & 0x10)
3014 2938 gen_op_div_cc(cpu_dst);
... ... @@ -3476,6 +3400,7 @@ static void disas_sparc_insn(DisasContext * dc)
3476 3400 // XXX
3477 3401 goto illegal_insn;
3478 3402 case 0x010: /* VIS I array8 */
  3403 + CHECK_FPU_FEATURE(dc, VIS1);
3479 3404 cpu_src1 = get_src1(insn, cpu_src1);
3480 3405 gen_movl_reg_TN(rs2, cpu_src2);
3481 3406 tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
... ... @@ -3483,6 +3408,7 @@ static void disas_sparc_insn(DisasContext * dc)
3483 3408 gen_movl_TN_reg(rd, cpu_dst);
3484 3409 break;
3485 3410 case 0x012: /* VIS I array16 */
  3411 + CHECK_FPU_FEATURE(dc, VIS1);
3486 3412 cpu_src1 = get_src1(insn, cpu_src1);
3487 3413 gen_movl_reg_TN(rs2, cpu_src2);
3488 3414 tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
... ... @@ -3491,6 +3417,7 @@ static void disas_sparc_insn(DisasContext * dc)
3491 3417 gen_movl_TN_reg(rd, cpu_dst);
3492 3418 break;
3493 3419 case 0x014: /* VIS I array32 */
  3420 + CHECK_FPU_FEATURE(dc, VIS1);
3494 3421 cpu_src1 = get_src1(insn, cpu_src1);
3495 3422 gen_movl_reg_TN(rs2, cpu_src2);
3496 3423 tcg_gen_helper_1_2(helper_array8, cpu_dst, cpu_src1,
... ... @@ -3499,6 +3426,7 @@ static void disas_sparc_insn(DisasContext * dc)
3499 3426 gen_movl_TN_reg(rd, cpu_dst);
3500 3427 break;
3501 3428 case 0x018: /* VIS I alignaddr */
  3429 + CHECK_FPU_FEATURE(dc, VIS1);
3502 3430 cpu_src1 = get_src1(insn, cpu_src1);
3503 3431 gen_movl_reg_TN(rs2, cpu_src2);
3504 3432 tcg_gen_helper_1_2(helper_alignaddr, cpu_dst, cpu_src1,
... ... @@ -3510,90 +3438,105 @@ static void disas_sparc_insn(DisasContext * dc)
3510 3438 // XXX
3511 3439 goto illegal_insn;
3512 3440 case 0x020: /* VIS I fcmple16 */
  3441 + CHECK_FPU_FEATURE(dc, VIS1);
3513 3442 gen_op_load_fpr_DT0(DFPREG(rs1));
3514 3443 gen_op_load_fpr_DT1(DFPREG(rs2));
3515 3444 tcg_gen_helper_0_0(helper_fcmple16);
3516 3445 gen_op_store_DT0_fpr(DFPREG(rd));
3517 3446 break;
3518 3447 case 0x022: /* VIS I fcmpne16 */
  3448 + CHECK_FPU_FEATURE(dc, VIS1);
3519 3449 gen_op_load_fpr_DT0(DFPREG(rs1));
3520 3450 gen_op_load_fpr_DT1(DFPREG(rs2));
3521 3451 tcg_gen_helper_0_0(helper_fcmpne16);
3522 3452 gen_op_store_DT0_fpr(DFPREG(rd));
3523 3453 break;
3524 3454 case 0x024: /* VIS I fcmple32 */
  3455 + CHECK_FPU_FEATURE(dc, VIS1);
3525 3456 gen_op_load_fpr_DT0(DFPREG(rs1));
3526 3457 gen_op_load_fpr_DT1(DFPREG(rs2));
3527 3458 tcg_gen_helper_0_0(helper_fcmple32);
3528 3459 gen_op_store_DT0_fpr(DFPREG(rd));
3529 3460 break;
3530 3461 case 0x026: /* VIS I fcmpne32 */
  3462 + CHECK_FPU_FEATURE(dc, VIS1);
3531 3463 gen_op_load_fpr_DT0(DFPREG(rs1));
3532 3464 gen_op_load_fpr_DT1(DFPREG(rs2));
3533 3465 tcg_gen_helper_0_0(helper_fcmpne32);
3534 3466 gen_op_store_DT0_fpr(DFPREG(rd));
3535 3467 break;
3536 3468 case 0x028: /* VIS I fcmpgt16 */
  3469 + CHECK_FPU_FEATURE(dc, VIS1);
3537 3470 gen_op_load_fpr_DT0(DFPREG(rs1));
3538 3471 gen_op_load_fpr_DT1(DFPREG(rs2));
3539 3472 tcg_gen_helper_0_0(helper_fcmpgt16);
3540 3473 gen_op_store_DT0_fpr(DFPREG(rd));
3541 3474 break;
3542 3475 case 0x02a: /* VIS I fcmpeq16 */
  3476 + CHECK_FPU_FEATURE(dc, VIS1);
3543 3477 gen_op_load_fpr_DT0(DFPREG(rs1));
3544 3478 gen_op_load_fpr_DT1(DFPREG(rs2));
3545 3479 tcg_gen_helper_0_0(helper_fcmpeq16);
3546 3480 gen_op_store_DT0_fpr(DFPREG(rd));
3547 3481 break;
3548 3482 case 0x02c: /* VIS I fcmpgt32 */
  3483 + CHECK_FPU_FEATURE(dc, VIS1);
3549 3484 gen_op_load_fpr_DT0(DFPREG(rs1));
3550 3485 gen_op_load_fpr_DT1(DFPREG(rs2));
3551 3486 tcg_gen_helper_0_0(helper_fcmpgt32);
3552 3487 gen_op_store_DT0_fpr(DFPREG(rd));
3553 3488 break;
3554 3489 case 0x02e: /* VIS I fcmpeq32 */
  3490 + CHECK_FPU_FEATURE(dc, VIS1);
3555 3491 gen_op_load_fpr_DT0(DFPREG(rs1));
3556 3492 gen_op_load_fpr_DT1(DFPREG(rs2));
3557 3493 tcg_gen_helper_0_0(helper_fcmpeq32);
3558 3494 gen_op_store_DT0_fpr(DFPREG(rd));
3559 3495 break;
3560 3496 case 0x031: /* VIS I fmul8x16 */
  3497 + CHECK_FPU_FEATURE(dc, VIS1);
3561 3498 gen_op_load_fpr_DT0(DFPREG(rs1));
3562 3499 gen_op_load_fpr_DT1(DFPREG(rs2));
3563 3500 tcg_gen_helper_0_0(helper_fmul8x16);
3564 3501 gen_op_store_DT0_fpr(DFPREG(rd));
3565 3502 break;
3566 3503 case 0x033: /* VIS I fmul8x16au */
  3504 + CHECK_FPU_FEATURE(dc, VIS1);
3567 3505 gen_op_load_fpr_DT0(DFPREG(rs1));
3568 3506 gen_op_load_fpr_DT1(DFPREG(rs2));
3569 3507 tcg_gen_helper_0_0(helper_fmul8x16au);
3570 3508 gen_op_store_DT0_fpr(DFPREG(rd));
3571 3509 break;
3572 3510 case 0x035: /* VIS I fmul8x16al */
  3511 + CHECK_FPU_FEATURE(dc, VIS1);
3573 3512 gen_op_load_fpr_DT0(DFPREG(rs1));
3574 3513 gen_op_load_fpr_DT1(DFPREG(rs2));
3575 3514 tcg_gen_helper_0_0(helper_fmul8x16al);
3576 3515 gen_op_store_DT0_fpr(DFPREG(rd));
3577 3516 break;
3578 3517 case 0x036: /* VIS I fmul8sux16 */
  3518 + CHECK_FPU_FEATURE(dc, VIS1);
3579 3519 gen_op_load_fpr_DT0(DFPREG(rs1));
3580 3520 gen_op_load_fpr_DT1(DFPREG(rs2));
3581 3521 tcg_gen_helper_0_0(helper_fmul8sux16);
3582 3522 gen_op_store_DT0_fpr(DFPREG(rd));
3583 3523 break;
3584 3524 case 0x037: /* VIS I fmul8ulx16 */
  3525 + CHECK_FPU_FEATURE(dc, VIS1);
3585 3526 gen_op_load_fpr_DT0(DFPREG(rs1));
3586 3527 gen_op_load_fpr_DT1(DFPREG(rs2));
3587 3528 tcg_gen_helper_0_0(helper_fmul8ulx16);
3588 3529 gen_op_store_DT0_fpr(DFPREG(rd));
3589 3530 break;
3590 3531 case 0x038: /* VIS I fmuld8sux16 */
  3532 + CHECK_FPU_FEATURE(dc, VIS1);
3591 3533 gen_op_load_fpr_DT0(DFPREG(rs1));
3592 3534 gen_op_load_fpr_DT1(DFPREG(rs2));
3593 3535 tcg_gen_helper_0_0(helper_fmuld8sux16);
3594 3536 gen_op_store_DT0_fpr(DFPREG(rd));
3595 3537 break;
3596 3538 case 0x039: /* VIS I fmuld8ulx16 */
  3539 + CHECK_FPU_FEATURE(dc, VIS1);
3597 3540 gen_op_load_fpr_DT0(DFPREG(rs1));
3598 3541 gen_op_load_fpr_DT1(DFPREG(rs2));
3599 3542 tcg_gen_helper_0_0(helper_fmuld8ulx16);
... ... @@ -3606,12 +3549,14 @@ static void disas_sparc_insn(DisasContext * dc)
3606 3549 // XXX
3607 3550 goto illegal_insn;
3608 3551 case 0x048: /* VIS I faligndata */
  3552 + CHECK_FPU_FEATURE(dc, VIS1);
3609 3553 gen_op_load_fpr_DT0(DFPREG(rs1));
3610 3554 gen_op_load_fpr_DT1(DFPREG(rs2));
3611 3555 tcg_gen_helper_0_0(helper_faligndata);
3612 3556 gen_op_store_DT0_fpr(DFPREG(rd));
3613 3557 break;
3614 3558 case 0x04b: /* VIS I fpmerge */
  3559 + CHECK_FPU_FEATURE(dc, VIS1);
3615 3560 gen_op_load_fpr_DT0(DFPREG(rs1));
3616 3561 gen_op_load_fpr_DT1(DFPREG(rs2));
3617 3562 tcg_gen_helper_0_0(helper_fpmerge);
... ... @@ -3621,228 +3566,269 @@ static void disas_sparc_insn(DisasContext * dc)
3621 3566 // XXX
3622 3567 goto illegal_insn;
3623 3568 case 0x04d: /* VIS I fexpand */
  3569 + CHECK_FPU_FEATURE(dc, VIS1);
3624 3570 gen_op_load_fpr_DT0(DFPREG(rs1));
3625 3571 gen_op_load_fpr_DT1(DFPREG(rs2));
3626 3572 tcg_gen_helper_0_0(helper_fexpand);
3627 3573 gen_op_store_DT0_fpr(DFPREG(rd));
3628 3574 break;
3629 3575 case 0x050: /* VIS I fpadd16 */
  3576 + CHECK_FPU_FEATURE(dc, VIS1);
3630 3577 gen_op_load_fpr_DT0(DFPREG(rs1));
3631 3578 gen_op_load_fpr_DT1(DFPREG(rs2));
3632 3579 tcg_gen_helper_0_0(helper_fpadd16);
3633 3580 gen_op_store_DT0_fpr(DFPREG(rd));
3634 3581 break;
3635 3582 case 0x051: /* VIS I fpadd16s */
  3583 + CHECK_FPU_FEATURE(dc, VIS1);
3636 3584 gen_op_load_fpr_FT0(rs1);
3637 3585 gen_op_load_fpr_FT1(rs2);
3638 3586 tcg_gen_helper_0_0(helper_fpadd16s);
3639 3587 gen_op_store_FT0_fpr(rd);
3640 3588 break;
3641 3589 case 0x052: /* VIS I fpadd32 */
  3590 + CHECK_FPU_FEATURE(dc, VIS1);
3642 3591 gen_op_load_fpr_DT0(DFPREG(rs1));
3643 3592 gen_op_load_fpr_DT1(DFPREG(rs2));
3644 3593 tcg_gen_helper_0_0(helper_fpadd32);
3645 3594 gen_op_store_DT0_fpr(DFPREG(rd));
3646 3595 break;
3647 3596 case 0x053: /* VIS I fpadd32s */
  3597 + CHECK_FPU_FEATURE(dc, VIS1);
3648 3598 gen_op_load_fpr_FT0(rs1);
3649 3599 gen_op_load_fpr_FT1(rs2);
3650 3600 tcg_gen_helper_0_0(helper_fpadd32s);
3651 3601 gen_op_store_FT0_fpr(rd);
3652 3602 break;
3653 3603 case 0x054: /* VIS I fpsub16 */
  3604 + CHECK_FPU_FEATURE(dc, VIS1);
3654 3605 gen_op_load_fpr_DT0(DFPREG(rs1));
3655 3606 gen_op_load_fpr_DT1(DFPREG(rs2));
3656 3607 tcg_gen_helper_0_0(helper_fpsub16);
3657 3608 gen_op_store_DT0_fpr(DFPREG(rd));
3658 3609 break;
3659 3610 case 0x055: /* VIS I fpsub16s */
  3611 + CHECK_FPU_FEATURE(dc, VIS1);
3660 3612 gen_op_load_fpr_FT0(rs1);
3661 3613 gen_op_load_fpr_FT1(rs2);
3662 3614 tcg_gen_helper_0_0(helper_fpsub16s);
3663 3615 gen_op_store_FT0_fpr(rd);
3664 3616 break;
3665 3617 case 0x056: /* VIS I fpsub32 */
  3618 + CHECK_FPU_FEATURE(dc, VIS1);
3666 3619 gen_op_load_fpr_DT0(DFPREG(rs1));
3667 3620 gen_op_load_fpr_DT1(DFPREG(rs2));
3668 3621 tcg_gen_helper_0_0(helper_fpadd32);
3669 3622 gen_op_store_DT0_fpr(DFPREG(rd));
3670 3623 break;
3671 3624 case 0x057: /* VIS I fpsub32s */
  3625 + CHECK_FPU_FEATURE(dc, VIS1);
3672 3626 gen_op_load_fpr_FT0(rs1);
3673 3627 gen_op_load_fpr_FT1(rs2);
3674 3628 tcg_gen_helper_0_0(helper_fpsub32s);
3675 3629 gen_op_store_FT0_fpr(rd);
3676 3630 break;
3677 3631 case 0x060: /* VIS I fzero */
  3632 + CHECK_FPU_FEATURE(dc, VIS1);
3678 3633 tcg_gen_helper_0_0(helper_movl_DT0_0);
3679 3634 gen_op_store_DT0_fpr(DFPREG(rd));
3680 3635 break;
3681 3636 case 0x061: /* VIS I fzeros */
  3637 + CHECK_FPU_FEATURE(dc, VIS1);
3682 3638 tcg_gen_helper_0_0(helper_movl_FT0_0);
3683 3639 gen_op_store_FT0_fpr(rd);
3684 3640 break;
3685 3641 case 0x062: /* VIS I fnor */
  3642 + CHECK_FPU_FEATURE(dc, VIS1);
3686 3643 gen_op_load_fpr_DT0(DFPREG(rs1));
3687 3644 gen_op_load_fpr_DT1(DFPREG(rs2));
3688 3645 tcg_gen_helper_0_0(helper_fnor);
3689 3646 gen_op_store_DT0_fpr(DFPREG(rd));
3690 3647 break;
3691 3648 case 0x063: /* VIS I fnors */
  3649 + CHECK_FPU_FEATURE(dc, VIS1);
3692 3650 gen_op_load_fpr_FT0(rs1);
3693 3651 gen_op_load_fpr_FT1(rs2);
3694 3652 tcg_gen_helper_0_0(helper_fnors);
3695 3653 gen_op_store_FT0_fpr(rd);
3696 3654 break;
3697 3655 case 0x064: /* VIS I fandnot2 */
  3656 + CHECK_FPU_FEATURE(dc, VIS1);
3698 3657 gen_op_load_fpr_DT1(DFPREG(rs1));
3699 3658 gen_op_load_fpr_DT0(DFPREG(rs2));
3700 3659 tcg_gen_helper_0_0(helper_fandnot);
3701 3660 gen_op_store_DT0_fpr(DFPREG(rd));
3702 3661 break;
3703 3662 case 0x065: /* VIS I fandnot2s */
  3663 + CHECK_FPU_FEATURE(dc, VIS1);
3704 3664 gen_op_load_fpr_FT1(rs1);
3705 3665 gen_op_load_fpr_FT0(rs2);
3706 3666 tcg_gen_helper_0_0(helper_fandnots);
3707 3667 gen_op_store_FT0_fpr(rd);
3708 3668 break;
3709 3669 case 0x066: /* VIS I fnot2 */
  3670 + CHECK_FPU_FEATURE(dc, VIS1);
3710 3671 gen_op_load_fpr_DT1(DFPREG(rs2));
3711 3672 tcg_gen_helper_0_0(helper_fnot);
3712 3673 gen_op_store_DT0_fpr(DFPREG(rd));
3713 3674 break;
3714 3675 case 0x067: /* VIS I fnot2s */
  3676 + CHECK_FPU_FEATURE(dc, VIS1);
3715 3677 gen_op_load_fpr_FT1(rs2);
3716 3678 tcg_gen_helper_0_0(helper_fnot);
3717 3679 gen_op_store_FT0_fpr(rd);
3718 3680 break;
3719 3681 case 0x068: /* VIS I fandnot1 */
  3682 + CHECK_FPU_FEATURE(dc, VIS1);
3720 3683 gen_op_load_fpr_DT0(DFPREG(rs1));
3721 3684 gen_op_load_fpr_DT1(DFPREG(rs2));
3722 3685 tcg_gen_helper_0_0(helper_fandnot);
3723 3686 gen_op_store_DT0_fpr(DFPREG(rd));
3724 3687 break;
3725 3688 case 0x069: /* VIS I fandnot1s */
  3689 + CHECK_FPU_FEATURE(dc, VIS1);
3726 3690 gen_op_load_fpr_FT0(rs1);
3727 3691 gen_op_load_fpr_FT1(rs2);
3728 3692 tcg_gen_helper_0_0(helper_fandnots);
3729 3693 gen_op_store_FT0_fpr(rd);
3730 3694 break;
3731 3695 case 0x06a: /* VIS I fnot1 */
  3696 + CHECK_FPU_FEATURE(dc, VIS1);
3732 3697 gen_op_load_fpr_DT1(DFPREG(rs1));
3733 3698 tcg_gen_helper_0_0(helper_fnot);
3734 3699 gen_op_store_DT0_fpr(DFPREG(rd));
3735 3700 break;
3736 3701 case 0x06b: /* VIS I fnot1s */
  3702 + CHECK_FPU_FEATURE(dc, VIS1);
3737 3703 gen_op_load_fpr_FT1(rs1);
3738 3704 tcg_gen_helper_0_0(helper_fnot);
3739 3705 gen_op_store_FT0_fpr(rd);
3740 3706 break;
3741 3707 case 0x06c: /* VIS I fxor */
  3708 + CHECK_FPU_FEATURE(dc, VIS1);
3742 3709 gen_op_load_fpr_DT0(DFPREG(rs1));
3743 3710 gen_op_load_fpr_DT1(DFPREG(rs2));
3744 3711 tcg_gen_helper_0_0(helper_fxor);
3745 3712 gen_op_store_DT0_fpr(DFPREG(rd));
3746 3713 break;
3747 3714 case 0x06d: /* VIS I fxors */
  3715 + CHECK_FPU_FEATURE(dc, VIS1);
3748 3716 gen_op_load_fpr_FT0(rs1);
3749 3717 gen_op_load_fpr_FT1(rs2);
3750 3718 tcg_gen_helper_0_0(helper_fxors);
3751 3719 gen_op_store_FT0_fpr(rd);
3752 3720 break;
3753 3721 case 0x06e: /* VIS I fnand */
  3722 + CHECK_FPU_FEATURE(dc, VIS1);
3754 3723 gen_op_load_fpr_DT0(DFPREG(rs1));
3755 3724 gen_op_load_fpr_DT1(DFPREG(rs2));
3756 3725 tcg_gen_helper_0_0(helper_fnand);
3757 3726 gen_op_store_DT0_fpr(DFPREG(rd));
3758 3727 break;
3759 3728 case 0x06f: /* VIS I fnands */
  3729 + CHECK_FPU_FEATURE(dc, VIS1);
3760 3730 gen_op_load_fpr_FT0(rs1);
3761 3731 gen_op_load_fpr_FT1(rs2);
3762 3732 tcg_gen_helper_0_0(helper_fnands);
3763 3733 gen_op_store_FT0_fpr(rd);
3764 3734 break;
3765 3735 case 0x070: /* VIS I fand */
  3736 + CHECK_FPU_FEATURE(dc, VIS1);
3766 3737 gen_op_load_fpr_DT0(DFPREG(rs1));
3767 3738 gen_op_load_fpr_DT1(DFPREG(rs2));
3768 3739 tcg_gen_helper_0_0(helper_fand);
3769 3740 gen_op_store_DT0_fpr(DFPREG(rd));
3770 3741 break;
3771 3742 case 0x071: /* VIS I fands */
  3743 + CHECK_FPU_FEATURE(dc, VIS1);
3772 3744 gen_op_load_fpr_FT0(rs1);
3773 3745 gen_op_load_fpr_FT1(rs2);
3774 3746 tcg_gen_helper_0_0(helper_fands);
3775 3747 gen_op_store_FT0_fpr(rd);
3776 3748 break;
3777 3749 case 0x072: /* VIS I fxnor */
  3750 + CHECK_FPU_FEATURE(dc, VIS1);
3778 3751 gen_op_load_fpr_DT0(DFPREG(rs1));
3779 3752 gen_op_load_fpr_DT1(DFPREG(rs2));
3780 3753 tcg_gen_helper_0_0(helper_fxnor);
3781 3754 gen_op_store_DT0_fpr(DFPREG(rd));
3782 3755 break;
3783 3756 case 0x073: /* VIS I fxnors */
  3757 + CHECK_FPU_FEATURE(dc, VIS1);
3784 3758 gen_op_load_fpr_FT0(rs1);
3785 3759 gen_op_load_fpr_FT1(rs2);
3786 3760 tcg_gen_helper_0_0(helper_fxnors);
3787 3761 gen_op_store_FT0_fpr(rd);
3788 3762 break;
3789 3763 case 0x074: /* VIS I fsrc1 */
  3764 + CHECK_FPU_FEATURE(dc, VIS1);
3790 3765 gen_op_load_fpr_DT0(DFPREG(rs1));
3791 3766 gen_op_store_DT0_fpr(DFPREG(rd));
3792 3767 break;
3793 3768 case 0x075: /* VIS I fsrc1s */
  3769 + CHECK_FPU_FEATURE(dc, VIS1);
3794 3770 gen_op_load_fpr_FT0(rs1);
3795 3771 gen_op_store_FT0_fpr(rd);
3796 3772 break;
3797 3773 case 0x076: /* VIS I fornot2 */
  3774 + CHECK_FPU_FEATURE(dc, VIS1);
3798 3775 gen_op_load_fpr_DT1(DFPREG(rs1));
3799 3776 gen_op_load_fpr_DT0(DFPREG(rs2));
3800 3777 tcg_gen_helper_0_0(helper_fornot);
3801 3778 gen_op_store_DT0_fpr(DFPREG(rd));
3802 3779 break;
3803 3780 case 0x077: /* VIS I fornot2s */
  3781 + CHECK_FPU_FEATURE(dc, VIS1);
3804 3782 gen_op_load_fpr_FT1(rs1);
3805 3783 gen_op_load_fpr_FT0(rs2);
3806 3784 tcg_gen_helper_0_0(helper_fornots);
3807 3785 gen_op_store_FT0_fpr(rd);
3808 3786 break;
3809 3787 case 0x078: /* VIS I fsrc2 */
  3788 + CHECK_FPU_FEATURE(dc, VIS1);
3810 3789 gen_op_load_fpr_DT0(DFPREG(rs2));
3811 3790 gen_op_store_DT0_fpr(DFPREG(rd));
3812 3791 break;
3813 3792 case 0x079: /* VIS I fsrc2s */
  3793 + CHECK_FPU_FEATURE(dc, VIS1);
3814 3794 gen_op_load_fpr_FT0(rs2);
3815 3795 gen_op_store_FT0_fpr(rd);
3816 3796 break;
3817 3797 case 0x07a: /* VIS I fornot1 */
  3798 + CHECK_FPU_FEATURE(dc, VIS1);
3818 3799 gen_op_load_fpr_DT0(DFPREG(rs1));
3819 3800 gen_op_load_fpr_DT1(DFPREG(rs2));
3820 3801 tcg_gen_helper_0_0(helper_fornot);
3821 3802 gen_op_store_DT0_fpr(DFPREG(rd));
3822 3803 break;
3823 3804 case 0x07b: /* VIS I fornot1s */
  3805 + CHECK_FPU_FEATURE(dc, VIS1);
3824 3806 gen_op_load_fpr_FT0(rs1);
3825 3807 gen_op_load_fpr_FT1(rs2);
3826 3808 tcg_gen_helper_0_0(helper_fornots);
3827 3809 gen_op_store_FT0_fpr(rd);
3828 3810 break;
3829 3811 case 0x07c: /* VIS I for */
  3812 + CHECK_FPU_FEATURE(dc, VIS1);
3830 3813 gen_op_load_fpr_DT0(DFPREG(rs1));
3831 3814 gen_op_load_fpr_DT1(DFPREG(rs2));
3832 3815 tcg_gen_helper_0_0(helper_for);
3833 3816 gen_op_store_DT0_fpr(DFPREG(rd));
3834 3817 break;
3835 3818 case 0x07d: /* VIS I fors */
  3819 + CHECK_FPU_FEATURE(dc, VIS1);
3836 3820 gen_op_load_fpr_FT0(rs1);
3837 3821 gen_op_load_fpr_FT1(rs2);
3838 3822 tcg_gen_helper_0_0(helper_fors);
3839 3823 gen_op_store_FT0_fpr(rd);
3840 3824 break;
3841 3825 case 0x07e: /* VIS I fone */
  3826 + CHECK_FPU_FEATURE(dc, VIS1);
3842 3827 tcg_gen_helper_0_0(helper_movl_DT0_1);
3843 3828 gen_op_store_DT0_fpr(DFPREG(rd));
3844 3829 break;
3845 3830 case 0x07f: /* VIS I fones */
  3831 + CHECK_FPU_FEATURE(dc, VIS1);
3846 3832 tcg_gen_helper_0_0(helper_movl_FT0_1);
3847 3833 gen_op_store_FT0_fpr(rd);
3848 3834 break;
... ... @@ -3921,6 +3907,8 @@ static void disas_sparc_insn(DisasContext * dc)
3921 3907 goto jmp_insn;
3922 3908 #endif
3923 3909 case 0x3b: /* flush */
  3910 + if (!((dc)->features & CPU_FEATURE_FLUSH))
  3911 + goto unimp_flush;
3924 3912 tcg_gen_helper_0_1(helper_flush, cpu_dst);
3925 3913 break;
3926 3914 case 0x3c: /* save */
... ... @@ -4034,6 +4022,7 @@ static void disas_sparc_insn(DisasContext * dc)
4034 4022 tcg_gen_qemu_st8(tcg_const_tl(0xff), cpu_addr, dc->mem_idx);
4035 4023 break;
4036 4024 case 0x0f: /* swap register with memory. Also atomically */
  4025 + CHECK_IU_FEATURE(dc, SWAP);
4037 4026 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4038 4027 gen_movl_reg_TN(rd, cpu_val);
4039 4028 ABI32_MASK(cpu_addr);
... ... @@ -4113,6 +4102,7 @@ static void disas_sparc_insn(DisasContext * dc)
4113 4102 gen_ldstub_asi(cpu_val, cpu_addr, insn);
4114 4103 break;
4115 4104 case 0x1f: /* swap reg with alt. memory. Also atomically */
  4105 + CHECK_IU_FEATURE(dc, SWAP);
4116 4106 #ifndef TARGET_SPARC64
4117 4107 if (IS_IMM)
4118 4108 goto illegal_insn;
... ... @@ -4163,13 +4153,10 @@ static void disas_sparc_insn(DisasContext * dc)
4163 4153 case 0x3d: /* V9 prefetcha, no effect */
4164 4154 goto skip_move;
4165 4155 case 0x32: /* V9 ldqfa */
4166   -#if defined(CONFIG_USER_ONLY)
  4156 + CHECK_FPU_FEATURE(dc, FLOAT128);
4167 4157 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4168 4158 gen_ldf_asi(cpu_addr, insn, 16, QFPREG(rd));
4169 4159 goto skip_move;
4170   -#else
4171   - goto nfpu_insn;
4172   -#endif
4173 4160 #endif
4174 4161 default:
4175 4162 goto illegal_insn;
... ... @@ -4196,15 +4183,12 @@ static void disas_sparc_insn(DisasContext * dc)
4196 4183 tcg_gen_helper_0_0(helper_ldfsr);
4197 4184 break;
4198 4185 case 0x22: /* load quad fpreg */
4199   -#if defined(CONFIG_USER_ONLY)
  4186 + CHECK_FPU_FEATURE(dc, FLOAT128);
4200 4187 tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4201 4188 tcg_const_i32(7));
4202   - tcg_gen_helper_0_1(helper_ldqf, cpu_addr);
  4189 + tcg_gen_helper_0_2(helper_ldqf, cpu_addr, dc->mem_idx);
4203 4190 gen_op_store_QT0_fpr(QFPREG(rd));
4204 4191 break;
4205   -#else
4206   - goto nfpu_insn;
4207   -#endif
4208 4192 case 0x23: /* load double fpreg */
4209 4193 tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4210 4194 tcg_const_i32(7));
... ... @@ -4334,16 +4318,13 @@ static void disas_sparc_insn(DisasContext * dc)
4334 4318 break;
4335 4319 case 0x26:
4336 4320 #ifdef TARGET_SPARC64
4337   -#if defined(CONFIG_USER_ONLY)
4338 4321 /* V9 stqf, store quad fpreg */
  4322 + CHECK_FPU_FEATURE(dc, FLOAT128);
4339 4323 tcg_gen_helper_0_2(helper_check_align, cpu_addr,
4340 4324 tcg_const_i32(7));
4341 4325 gen_op_load_fpr_QT0(QFPREG(rd));
4342   - tcg_gen_helper_0_1(helper_stqf, cpu_addr);
  4326 + tcg_gen_helper_0_2(helper_stqf, cpu_addr, dc->mem_idx);
4343 4327 break;
4344   -#else
4345   - goto nfpu_insn;
4346   -#endif
4347 4328 #else /* !TARGET_SPARC64 */
4348 4329 /* stdfq, store floating point queue */
4349 4330 #if defined(CONFIG_USER_ONLY)
... ... @@ -4375,14 +4356,12 @@ static void disas_sparc_insn(DisasContext * dc)
4375 4356 gen_stf_asi(cpu_addr, insn, 4, rd);
4376 4357 break;
4377 4358 case 0x36: /* V9 stqfa */
4378   -#if defined(CONFIG_USER_ONLY)
4379   - tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(7));
  4359 + CHECK_FPU_FEATURE(dc, FLOAT128);
  4360 + tcg_gen_helper_0_2(helper_check_align, cpu_addr,
  4361 + tcg_const_i32(7));
4380 4362 gen_op_load_fpr_QT0(QFPREG(rd));
4381 4363 gen_stf_asi(cpu_addr, insn, 16, QFPREG(rd));
4382 4364 break;
4383   -#else
4384   - goto nfpu_insn;
4385   -#endif
4386 4365 case 0x37: /* V9 stdfa */
4387 4366 tcg_gen_helper_0_2(helper_check_align, cpu_addr, tcg_const_i32(3));
4388 4367 gen_op_load_fpr_DT0(DFPREG(rd));
... ... @@ -4433,25 +4412,30 @@ static void disas_sparc_insn(DisasContext * dc)
4433 4412 tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_ILL_INSN));
4434 4413 dc->is_br = 1;
4435 4414 return;
  4415 + unimp_flush:
  4416 + save_state(dc, cpu_cond);
  4417 + tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_UNIMP_FLUSH));
  4418 + dc->is_br = 1;
  4419 + return;
4436 4420 #if !defined(CONFIG_USER_ONLY)
4437 4421 priv_insn:
4438 4422 save_state(dc, cpu_cond);
4439 4423 tcg_gen_helper_0_1(raise_exception, tcg_const_i32(TT_PRIV_INSN));
4440 4424 dc->is_br = 1;
4441 4425 return;
  4426 +#endif
4442 4427 nfpu_insn:
4443 4428 save_state(dc, cpu_cond);
4444 4429 gen_op_fpexception_im(FSR_FTT_UNIMPFPOP);
4445 4430 dc->is_br = 1;
4446 4431 return;
4447   -#ifndef TARGET_SPARC64
  4432 +#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
4448 4433 nfq_insn:
4449 4434 save_state(dc, cpu_cond);
4450 4435 gen_op_fpexception_im(FSR_FTT_SEQ_ERROR);
4451 4436 dc->is_br = 1;
4452 4437 return;
4453 4438 #endif
4454   -#endif
4455 4439 #ifndef TARGET_SPARC64
4456 4440 ncp_insn:
4457 4441 save_state(dc, cpu_cond);
... ... @@ -4480,7 +4464,14 @@ static inline int gen_intermediate_code_internal(TranslationBlock * tb,
4480 4464 last_pc = dc->pc;
4481 4465 dc->npc = (target_ulong) tb->cs_base;
4482 4466 dc->mem_idx = cpu_mmu_index(env);
4483   - dc->fpu_enabled = cpu_fpu_enabled(env);
  4467 + dc->features = env->features;
  4468 + if ((dc->features & CPU_FEATURE_FLOAT)) {
  4469 + dc->fpu_enabled = cpu_fpu_enabled(env);
  4470 +#if defined(CONFIG_USER_ONLY)
  4471 + dc->features |= CPU_FEATURE_FLOAT128;
  4472 +#endif
  4473 + } else
  4474 + dc->fpu_enabled = 0;
4484 4475 gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
4485 4476  
4486 4477 cpu_tmp0 = tcg_temp_new(TCG_TYPE_TL);
... ...