Commit 3391c81801c867bc8f4dd6ce32766e4e8345813b

Authored by blueswir1
1 parent ee0b03fd

Fix Sparc64 ldfa, lddfa, stfa, and stdfa instructions


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3298 c046a42c-6fe2-441c-8c8c-71466251a162
target-sparc/exec.h
@@ -51,6 +51,8 @@ void cpu_loop_exit(void); @@ -51,6 +51,8 @@ void cpu_loop_exit(void);
51 void helper_flush(target_ulong addr); 51 void helper_flush(target_ulong addr);
52 void helper_ld_asi(int asi, int size, int sign); 52 void helper_ld_asi(int asi, int size, int sign);
53 void helper_st_asi(int asi, int size); 53 void helper_st_asi(int asi, int size);
  54 +void helper_ldf_asi(int asi, int size, int rd);
  55 +void helper_stf_asi(int asi, int size, int rd);
54 void helper_rett(void); 56 void helper_rett(void);
55 void helper_ldfsr(void); 57 void helper_ldfsr(void);
56 void set_cwp(int new_cwp); 58 void set_cwp(int new_cwp);
target-sparc/op.c
@@ -1865,6 +1865,28 @@ void OPPROTO op_st_asi_reg() @@ -1865,6 +1865,28 @@ void OPPROTO op_st_asi_reg()
1865 helper_st_asi(env->asi, PARAM2); 1865 helper_st_asi(env->asi, PARAM2);
1866 } 1866 }
1867 1867
  1868 +void OPPROTO op_ldf_asi_reg()
  1869 +{
  1870 + T0 += PARAM1;
  1871 + helper_ldf_asi(env->asi, PARAM2, PARAM3);
  1872 +}
  1873 +
  1874 +void OPPROTO op_stf_asi_reg()
  1875 +{
  1876 + T0 += PARAM1;
  1877 + helper_stf_asi(env->asi, PARAM2, PARAM3);
  1878 +}
  1879 +
  1880 +void OPPROTO op_ldf_asi()
  1881 +{
  1882 + helper_ldf_asi(PARAM1, PARAM2, PARAM3);
  1883 +}
  1884 +
  1885 +void OPPROTO op_stf_asi()
  1886 +{
  1887 + helper_stf_asi(PARAM1, PARAM2, PARAM3);
  1888 +}
  1889 +
1868 void OPPROTO op_ldstub_asi_reg() /* XXX: should be atomically */ 1890 void OPPROTO op_ldstub_asi_reg() /* XXX: should be atomically */
1869 { 1891 {
1870 target_ulong tmp; 1892 target_ulong tmp;
target-sparc/op_helper.c
@@ -1126,6 +1126,79 @@ void helper_st_asi(int asi, int size) @@ -1126,6 +1126,79 @@ void helper_st_asi(int asi, int size)
1126 } 1126 }
1127 } 1127 }
1128 #endif /* CONFIG_USER_ONLY */ 1128 #endif /* CONFIG_USER_ONLY */
  1129 +
  1130 +void helper_ldf_asi(int asi, int size, int rd)
  1131 +{
  1132 + target_ulong tmp_T0 = T0, tmp_T1 = T1;
  1133 + unsigned int i;
  1134 +
  1135 + switch (asi) {
  1136 + case 0xf0: // Block load primary
  1137 + case 0xf1: // Block load secondary
  1138 + case 0xf8: // Block load primary LE
  1139 + case 0xf9: // Block load secondary LE
  1140 + for (i = 0; i < 8; i++) {
  1141 + helper_ld_asi(asi & 0x8f, 8, 0);
  1142 + *((int64_t *)&DT0) = T1;
  1143 + T0 += 8;
  1144 + }
  1145 + T0 = tmp_T0;
  1146 + T1 = tmp_T1;
  1147 +
  1148 + return;
  1149 + default:
  1150 + break;
  1151 + }
  1152 +
  1153 + helper_ld_asi(asi, size, 0);
  1154 + switch(size) {
  1155 + default:
  1156 + case 4:
  1157 + *((uint32_t *)&FT0) = T1;
  1158 + break;
  1159 + case 8:
  1160 + *((int64_t *)&DT0) = T1;
  1161 + break;
  1162 + }
  1163 + T1 = tmp_T1;
  1164 +}
  1165 +
  1166 +void helper_stf_asi(int asi, int size, int rd)
  1167 +{
  1168 + target_ulong tmp_T0 = T0, tmp_T1 = T1;
  1169 + unsigned int i;
  1170 +
  1171 + switch (asi) {
  1172 + case 0xf0: // Block store primary
  1173 + case 0xf1: // Block store secondary
  1174 + case 0xf8: // Block store primary LE
  1175 + case 0xf9: // Block store secondary LE
  1176 + for (i = 0; i < 8; i++) {
  1177 + T1 = *((int64_t *)&DT0);
  1178 + helper_st_asi(asi & 0x8f, 8);
  1179 + T0 += 8;
  1180 + }
  1181 + T0 = tmp_T0;
  1182 + T1 = tmp_T1;
  1183 +
  1184 + return;
  1185 + default:
  1186 + break;
  1187 + }
  1188 +
  1189 + switch(size) {
  1190 + default:
  1191 + case 4:
  1192 + T1 = *((uint32_t *)&FT0);
  1193 + break;
  1194 + case 8:
  1195 + T1 = *((int64_t *)&DT0);
  1196 + break;
  1197 + }
  1198 + helper_st_asi(asi, size);
  1199 + T1 = tmp_T1;
  1200 +}
  1201 +
1129 #endif /* TARGET_SPARC64 */ 1202 #endif /* TARGET_SPARC64 */
1130 1203
1131 #ifndef TARGET_SPARC64 1204 #ifndef TARGET_SPARC64
target-sparc/translate.c
@@ -427,6 +427,34 @@ static inline void gen_st_asi(int insn, int size) @@ -427,6 +427,34 @@ static inline void gen_st_asi(int insn, int size)
427 } 427 }
428 } 428 }
429 429
  430 +static inline void gen_ldf_asi(int insn, int size)
  431 +{
  432 + int asi, offset, rd;
  433 +
  434 + rd = GET_FIELD(insn, 2, 6);
  435 + if (IS_IMM) {
  436 + offset = GET_FIELD(insn, 25, 31);
  437 + gen_op_ldf_asi_reg(offset, size, rd);
  438 + } else {
  439 + asi = GET_FIELD(insn, 19, 26);
  440 + gen_op_ldf_asi(asi, size, rd);
  441 + }
  442 +}
  443 +
  444 +static inline void gen_stf_asi(int insn, int size)
  445 +{
  446 + int asi, offset, rd;
  447 +
  448 + rd = GET_FIELD(insn, 2, 6);
  449 + if (IS_IMM) {
  450 + offset = GET_FIELD(insn, 25, 31);
  451 + gen_op_stf_asi_reg(offset, size, rd);
  452 + } else {
  453 + asi = GET_FIELD(insn, 19, 26);
  454 + gen_op_stf_asi(asi, size, rd);
  455 + }
  456 +}
  457 +
430 static inline void gen_swap_asi(int insn) 458 static inline void gen_swap_asi(int insn)
431 { 459 {
432 int asi, offset; 460 int asi, offset;
@@ -3069,11 +3097,11 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3069,11 +3097,11 @@ static void disas_sparc_insn(DisasContext * dc)
3069 #ifdef CONFIG_USER_ONLY 3097 #ifdef CONFIG_USER_ONLY
3070 gen_op_check_align_T0_3(); 3098 gen_op_check_align_T0_3();
3071 #endif 3099 #endif
3072 - gen_ld_asi(insn, 8, 0); // XXX 3100 + gen_ldf_asi(insn, 4);
3073 goto skip_move; 3101 goto skip_move;
3074 case 0x33: /* V9 lddfa */ 3102 case 0x33: /* V9 lddfa */
3075 - gen_op_check_align_T0_7();  
3076 - gen_ld_asi(insn, 8, 0); // XXX 3103 + gen_op_check_align_T0_3();
  3104 + gen_ldf_asi(insn, 8);
3077 goto skip_move; 3105 goto skip_move;
3078 case 0x3d: /* V9 prefetcha, no effect */ 3106 case 0x3d: /* V9 prefetcha, no effect */
3079 goto skip_move; 3107 goto skip_move;
@@ -3245,11 +3273,13 @@ static void disas_sparc_insn(DisasContext * dc) @@ -3245,11 +3273,13 @@ static void disas_sparc_insn(DisasContext * dc)
3245 #ifdef CONFIG_USER_ONLY 3273 #ifdef CONFIG_USER_ONLY
3246 gen_op_check_align_T0_3(); 3274 gen_op_check_align_T0_3();
3247 #endif 3275 #endif
3248 - gen_st_asi(insn, 0); // XXX 3276 + gen_op_load_fpr_FT0(rd);
  3277 + gen_stf_asi(insn, 4);
3249 break; 3278 break;
3250 case 0x37: /* V9 stdfa */ 3279 case 0x37: /* V9 stdfa */
3251 - gen_op_check_align_T0_7();  
3252 - gen_st_asi(insn, 0); // XXX 3280 + gen_op_check_align_T0_3();
  3281 + gen_op_load_fpr_DT0(DFPREG(rd));
  3282 + gen_stf_asi(insn, 8);
3253 break; 3283 break;
3254 case 0x3c: /* V9 casa */ 3284 case 0x3c: /* V9 casa */
3255 #ifdef CONFIG_USER_ONLY 3285 #ifdef CONFIG_USER_ONLY