Commit 6ea4a6c875a2c0902fc19d560ef33228daa88603

Authored by blueswir1
1 parent 3c4c9f9f

More alignment checks


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3060 c046a42c-6fe2-441c-8c8c-71466251a162
target-sparc/op.c
... ... @@ -1518,10 +1518,7 @@ void OPPROTO op_movl_npc_im(void)
1518 1518  
1519 1519 void OPPROTO op_movl_npc_T0(void)
1520 1520 {
1521   - if (T0 & 0x3)
1522   - raise_exception(TT_UNALIGNED);
1523   - else
1524   - env->npc = T0;
  1521 + env->npc = T0;
1525 1522 }
1526 1523  
1527 1524 void OPPROTO op_mov_pc_npc(void)
... ... @@ -2368,3 +2365,15 @@ VIS_CMPOP(op_fcmple, FCMPLE)
2368 2365 VIS_CMPOP(op_fcmpne, FCMPNE)
2369 2366  
2370 2367 #endif
  2368 +
  2369 +#define CHECK_ALIGN_OP(align) \
  2370 + void OPPROTO op_check_align_T0_ ## align (void) \
  2371 + { \
  2372 + if (T0 & align) \
  2373 + raise_exception(TT_UNALIGNED); \
  2374 + FORCE_RET(); \
  2375 + }
  2376 +
  2377 +CHECK_ALIGN_OP(1)
  2378 +CHECK_ALIGN_OP(3)
  2379 +CHECK_ALIGN_OP(7)
... ...
target-sparc/translate.c
... ... @@ -346,6 +346,13 @@ GEN32(gen_op_load_fpr_DT1, gen_op_load_fpr_DT1_fprf);
346 346 GEN32(gen_op_store_DT0_fpr, gen_op_store_DT0_fpr_fprf);
347 347 GEN32(gen_op_store_DT1_fpr, gen_op_store_DT1_fpr_fprf);
348 348  
  349 +#ifdef ALIGN_7_BUGS_FIXED
  350 +#else
  351 +#ifndef CONFIG_USER_ONLY
  352 +#define gen_op_check_align_T0_7()
  353 +#endif
  354 +#endif
  355 +
349 356 #ifdef TARGET_SPARC64
350 357 // 'a' versions allowed to user depending on asi
351 358 #if defined(CONFIG_USER_ONLY)
... ... @@ -2676,6 +2683,7 @@ static void disas_sparc_insn(DisasContext * dc)
2676 2683 }
2677 2684 gen_op_restore();
2678 2685 gen_mov_pc_npc(dc);
  2686 + gen_op_check_align_T0_3();
2679 2687 gen_op_movl_npc_T0();
2680 2688 dc->npc = DYNAMIC_PC;
2681 2689 goto jmp_insn;
... ... @@ -2720,6 +2728,7 @@ static void disas_sparc_insn(DisasContext * dc)
2720 2728 gen_movl_T1_reg(rd);
2721 2729 }
2722 2730 gen_mov_pc_npc(dc);
  2731 + gen_op_check_align_T0_3();
2723 2732 gen_op_movl_npc_T0();
2724 2733 dc->npc = DYNAMIC_PC;
2725 2734 }
... ... @@ -2730,6 +2739,7 @@ static void disas_sparc_insn(DisasContext * dc)
2730 2739 if (!supervisor(dc))
2731 2740 goto priv_insn;
2732 2741 gen_mov_pc_npc(dc);
  2742 + gen_op_check_align_T0_3();
2733 2743 gen_op_movl_npc_T0();
2734 2744 dc->npc = DYNAMIC_PC;
2735 2745 gen_op_rett();
... ... @@ -2812,6 +2822,9 @@ static void disas_sparc_insn(DisasContext * dc)
2812 2822 (xop > 0x2c && xop <= 0x33) || xop == 0x1f || xop == 0x3d) {
2813 2823 switch (xop) {
2814 2824 case 0x0: /* load word */
  2825 +#ifdef CONFIG_USER_ONLY
  2826 + gen_op_check_align_T0_3();
  2827 +#endif
2815 2828 #ifndef TARGET_SPARC64
2816 2829 gen_op_ldst(ld);
2817 2830 #else
... ... @@ -2822,9 +2835,13 @@ static void disas_sparc_insn(DisasContext * dc)
2822 2835 gen_op_ldst(ldub);
2823 2836 break;
2824 2837 case 0x2: /* load unsigned halfword */
  2838 +#ifdef CONFIG_USER_ONLY
  2839 + gen_op_check_align_T0_1();
  2840 +#endif
2825 2841 gen_op_ldst(lduh);
2826 2842 break;
2827 2843 case 0x3: /* load double word */
  2844 + gen_op_check_align_T0_7();
2828 2845 if (rd & 1)
2829 2846 goto illegal_insn;
2830 2847 gen_op_ldst(ldd);
... ... @@ -2834,12 +2851,18 @@ static void disas_sparc_insn(DisasContext * dc)
2834 2851 gen_op_ldst(ldsb);
2835 2852 break;
2836 2853 case 0xa: /* load signed halfword */
  2854 +#ifdef CONFIG_USER_ONLY
  2855 + gen_op_check_align_T0_1();
  2856 +#endif
2837 2857 gen_op_ldst(ldsh);
2838 2858 break;
2839 2859 case 0xd: /* ldstub -- XXX: should be atomically */
2840 2860 gen_op_ldst(ldstub);
2841 2861 break;
2842 2862 case 0x0f: /* swap register with memory. Also atomically */
  2863 +#ifdef CONFIG_USER_ONLY
  2864 + gen_op_check_align_T0_3();
  2865 +#endif
2843 2866 gen_movl_reg_T1(rd);
2844 2867 gen_op_ldst(swap);
2845 2868 break;
... ... @@ -2850,8 +2873,14 @@ static void disas_sparc_insn(DisasContext * dc)
2850 2873 goto illegal_insn;
2851 2874 if (!supervisor(dc))
2852 2875 goto priv_insn;
  2876 +#ifdef CONFIG_USER_ONLY
  2877 + gen_op_check_align_T0_3();
  2878 +#endif
2853 2879 gen_op_lda(insn, 1, 4, 0);
2854 2880 #else
  2881 +#ifdef CONFIG_USER_ONLY
  2882 + gen_op_check_align_T0_3();
  2883 +#endif
2855 2884 gen_op_lduwa(insn, 1, 4, 0);
2856 2885 #endif
2857 2886 break;
... ... @@ -2871,6 +2900,9 @@ static void disas_sparc_insn(DisasContext * dc)
2871 2900 if (!supervisor(dc))
2872 2901 goto priv_insn;
2873 2902 #endif
  2903 +#ifdef CONFIG_USER_ONLY
  2904 + gen_op_check_align_T0_1();
  2905 +#endif
2874 2906 gen_op_lduha(insn, 1, 2, 0);
2875 2907 break;
2876 2908 case 0x13: /* load double word alternate */
... ... @@ -2882,6 +2914,7 @@ static void disas_sparc_insn(DisasContext * dc)
2882 2914 #endif
2883 2915 if (rd & 1)
2884 2916 goto illegal_insn;
  2917 + gen_op_check_align_T0_7();
2885 2918 gen_op_ldda(insn, 1, 8, 0);
2886 2919 gen_movl_T0_reg(rd + 1);
2887 2920 break;
... ... @@ -2901,6 +2934,9 @@ static void disas_sparc_insn(DisasContext * dc)
2901 2934 if (!supervisor(dc))
2902 2935 goto priv_insn;
2903 2936 #endif
  2937 +#ifdef CONFIG_USER_ONLY
  2938 + gen_op_check_align_T0_1();
  2939 +#endif
2904 2940 gen_op_ldsha(insn, 1, 2 ,1);
2905 2941 break;
2906 2942 case 0x1d: /* ldstuba -- XXX: should be atomically */
... ... @@ -2920,6 +2956,9 @@ static void disas_sparc_insn(DisasContext * dc)
2920 2956 goto priv_insn;
2921 2957 #endif
2922 2958 gen_movl_reg_T1(rd);
  2959 +#ifdef CONFIG_USER_ONLY
  2960 + gen_op_check_align_T0_3();
  2961 +#endif
2923 2962 gen_op_swapa(insn, 1, 4, 0);
2924 2963 break;
2925 2964  
... ... @@ -2943,23 +2982,35 @@ static void disas_sparc_insn(DisasContext * dc)
2943 2982 #endif
2944 2983 #ifdef TARGET_SPARC64
2945 2984 case 0x08: /* V9 ldsw */
  2985 +#ifdef CONFIG_USER_ONLY
  2986 + gen_op_check_align_T0_3();
  2987 +#endif
2946 2988 gen_op_ldst(ldsw);
2947 2989 break;
2948 2990 case 0x0b: /* V9 ldx */
  2991 + gen_op_check_align_T0_7();
2949 2992 gen_op_ldst(ldx);
2950 2993 break;
2951 2994 case 0x18: /* V9 ldswa */
  2995 +#ifdef CONFIG_USER_ONLY
  2996 + gen_op_check_align_T0_3();
  2997 +#endif
2952 2998 gen_op_ldswa(insn, 1, 4, 1);
2953 2999 break;
2954 3000 case 0x1b: /* V9 ldxa */
  3001 + gen_op_check_align_T0_7();
2955 3002 gen_op_ldxa(insn, 1, 8, 0);
2956 3003 break;
2957 3004 case 0x2d: /* V9 prefetch, no effect */
2958 3005 goto skip_move;
2959 3006 case 0x30: /* V9 ldfa */
  3007 +#ifdef CONFIG_USER_ONLY
  3008 + gen_op_check_align_T0_3();
  3009 +#endif
2960 3010 gen_op_ldfa(insn, 1, 8, 0); // XXX
2961 3011 break;
2962 3012 case 0x33: /* V9 lddfa */
  3013 + gen_op_check_align_T0_7();
2963 3014 gen_op_lddfa(insn, 1, 8, 0); // XXX
2964 3015  
2965 3016 break;
... ... @@ -2980,16 +3031,23 @@ static void disas_sparc_insn(DisasContext * dc)
2980 3031 goto jmp_insn;
2981 3032 switch (xop) {
2982 3033 case 0x20: /* load fpreg */
  3034 +#ifdef CONFIG_USER_ONLY
  3035 + gen_op_check_align_T0_3();
  3036 +#endif
2983 3037 gen_op_ldst(ldf);
2984 3038 gen_op_store_FT0_fpr(rd);
2985 3039 break;
2986 3040 case 0x21: /* load fsr */
  3041 +#ifdef CONFIG_USER_ONLY
  3042 + gen_op_check_align_T0_3();
  3043 +#endif
2987 3044 gen_op_ldst(ldf);
2988 3045 gen_op_ldfsr();
2989 3046 break;
2990 3047 case 0x22: /* load quad fpreg */
2991 3048 goto nfpu_insn;
2992 3049 case 0x23: /* load double fpreg */
  3050 + gen_op_check_align_T0_7();
2993 3051 gen_op_ldst(lddf);
2994 3052 gen_op_store_DT0_fpr(DFPREG(rd));
2995 3053 break;
... ... @@ -3001,17 +3059,24 @@ static void disas_sparc_insn(DisasContext * dc)
3001 3059 gen_movl_reg_T1(rd);
3002 3060 switch (xop) {
3003 3061 case 0x4:
  3062 +#ifdef CONFIG_USER_ONLY
  3063 + gen_op_check_align_T0_3();
  3064 +#endif
3004 3065 gen_op_ldst(st);
3005 3066 break;
3006 3067 case 0x5:
3007 3068 gen_op_ldst(stb);
3008 3069 break;
3009 3070 case 0x6:
  3071 +#ifdef CONFIG_USER_ONLY
  3072 + gen_op_check_align_T0_1();
  3073 +#endif
3010 3074 gen_op_ldst(sth);
3011 3075 break;
3012 3076 case 0x7:
3013 3077 if (rd & 1)
3014 3078 goto illegal_insn;
  3079 + gen_op_check_align_T0_7();
3015 3080 flush_T2(dc);
3016 3081 gen_movl_reg_T2(rd + 1);
3017 3082 gen_op_ldst(std);
... ... @@ -3024,6 +3089,9 @@ static void disas_sparc_insn(DisasContext * dc)
3024 3089 if (!supervisor(dc))
3025 3090 goto priv_insn;
3026 3091 #endif
  3092 +#ifdef CONFIG_USER_ONLY
  3093 + gen_op_check_align_T0_3();
  3094 +#endif
3027 3095 gen_op_sta(insn, 0, 4, 0);
3028 3096 break;
3029 3097 case 0x15:
... ... @@ -3042,6 +3110,9 @@ static void disas_sparc_insn(DisasContext * dc)
3042 3110 if (!supervisor(dc))
3043 3111 goto priv_insn;
3044 3112 #endif
  3113 +#ifdef CONFIG_USER_ONLY
  3114 + gen_op_check_align_T0_1();
  3115 +#endif
3045 3116 gen_op_stha(insn, 0, 2, 0);
3046 3117 break;
3047 3118 case 0x17:
... ... @@ -3053,6 +3124,7 @@ static void disas_sparc_insn(DisasContext * dc)
3053 3124 #endif
3054 3125 if (rd & 1)
3055 3126 goto illegal_insn;
  3127 + gen_op_check_align_T0_7();
3056 3128 flush_T2(dc);
3057 3129 gen_movl_reg_T2(rd + 1);
3058 3130 gen_op_stda(insn, 0, 8, 0);
... ... @@ -3060,9 +3132,11 @@ static void disas_sparc_insn(DisasContext * dc)
3060 3132 #endif
3061 3133 #ifdef TARGET_SPARC64
3062 3134 case 0x0e: /* V9 stx */
  3135 + gen_op_check_align_T0_7();
3063 3136 gen_op_ldst(stx);
3064 3137 break;
3065 3138 case 0x1e: /* V9 stxa */
  3139 + gen_op_check_align_T0_7();
3066 3140 gen_op_stxa(insn, 0, 8, 0); // XXX
3067 3141 break;
3068 3142 #endif
... ... @@ -3074,10 +3148,16 @@ static void disas_sparc_insn(DisasContext * dc)
3074 3148 goto jmp_insn;
3075 3149 switch (xop) {
3076 3150 case 0x24:
  3151 +#ifdef CONFIG_USER_ONLY
  3152 + gen_op_check_align_T0_3();
  3153 +#endif
3077 3154 gen_op_load_fpr_FT0(rd);
3078 3155 gen_op_ldst(stf);
3079 3156 break;
3080 3157 case 0x25: /* stfsr, V9 stxfsr */
  3158 +#ifdef CONFIG_USER_ONLY
  3159 + gen_op_check_align_T0_3();
  3160 +#endif
3081 3161 gen_op_stfsr();
3082 3162 gen_op_ldst(stf);
3083 3163 break;
... ... @@ -3090,6 +3170,7 @@ static void disas_sparc_insn(DisasContext * dc)
3090 3170 goto nfq_insn;
3091 3171 #endif
3092 3172 case 0x27:
  3173 + gen_op_check_align_T0_7();
3093 3174 gen_op_load_fpr_DT0(DFPREG(rd));
3094 3175 gen_op_ldst(stdf);
3095 3176 break;
... ... @@ -3100,15 +3181,23 @@ static void disas_sparc_insn(DisasContext * dc)
3100 3181 switch (xop) {
3101 3182 #ifdef TARGET_SPARC64
3102 3183 case 0x34: /* V9 stfa */
  3184 +#ifdef CONFIG_USER_ONLY
  3185 + gen_op_check_align_T0_3();
  3186 +#endif
3103 3187 gen_op_stfa(insn, 0, 0, 0); // XXX
3104 3188 break;
3105 3189 case 0x37: /* V9 stdfa */
  3190 + gen_op_check_align_T0_7();
3106 3191 gen_op_stdfa(insn, 0, 0, 0); // XXX
3107 3192 break;
3108 3193 case 0x3c: /* V9 casa */
  3194 +#ifdef CONFIG_USER_ONLY
  3195 + gen_op_check_align_T0_3();
  3196 +#endif
3109 3197 gen_op_casa(insn, 0, 4, 0); // XXX
3110 3198 break;
3111 3199 case 0x3e: /* V9 casxa */
  3200 + gen_op_check_align_T0_7();
3112 3201 gen_op_casxa(insn, 0, 8, 0); // XXX
3113 3202 break;
3114 3203 case 0x36: /* V9 stqfa */
... ...