Commit 51996525c77e61a050562900a499798ded8981d0
1 parent
55aa45dd
Fix block load ASIs
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3310 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
25 additions
and
9 deletions
target-sparc/op_helper.c
| ... | ... | @@ -862,7 +862,6 @@ void helper_st_asi(int asi, int size) |
| 862 | 862 | case 0x19: // As if user secondary LE |
| 863 | 863 | case 0x1c: // Bypass LE |
| 864 | 864 | case 0x1d: // Bypass, non-cacheable LE |
| 865 | - case 0x81: // Secondary | |
| 866 | 865 | case 0x88: // Primary LE |
| 867 | 866 | case 0x89: // Secondary LE |
| 868 | 867 | switch(size) { |
| ... | ... | @@ -950,6 +949,7 @@ void helper_st_asi(int asi, int size) |
| 950 | 949 | case 0x24: // Nucleus quad LDD 128 bit atomic |
| 951 | 950 | case 0x2c: // Nucleus quad LDD 128 bit atomic |
| 952 | 951 | case 0x4a: // UPA config |
| 952 | + case 0x81: // Secondary | |
| 953 | 953 | case 0x89: // Secondary LE |
| 954 | 954 | // XXX |
| 955 | 955 | return; |
| ... | ... | @@ -1137,10 +1137,18 @@ void helper_ldf_asi(int asi, int size, int rd) |
| 1137 | 1137 | case 0xf1: // Block load secondary |
| 1138 | 1138 | case 0xf8: // Block load primary LE |
| 1139 | 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; | |
| 1140 | + if (rd & 7) { | |
| 1141 | + raise_exception(TT_ILL_INSN); | |
| 1142 | + return; | |
| 1143 | + } | |
| 1144 | + if (T0 & 0x3f) { | |
| 1145 | + raise_exception(TT_UNALIGNED); | |
| 1146 | + return; | |
| 1147 | + } | |
| 1148 | + for (i = 0; i < 16; i++) { | |
| 1149 | + helper_ld_asi(asi & 0x8f, 4, 0); | |
| 1150 | + *(uint32_t *)&env->fpr[rd++] = T1; | |
| 1151 | + T0 += 4; | |
| 1144 | 1152 | } |
| 1145 | 1153 | T0 = tmp_T0; |
| 1146 | 1154 | T1 = tmp_T1; |
| ... | ... | @@ -1173,10 +1181,18 @@ void helper_stf_asi(int asi, int size, int rd) |
| 1173 | 1181 | case 0xf1: // Block store secondary |
| 1174 | 1182 | case 0xf8: // Block store primary LE |
| 1175 | 1183 | 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; | |
| 1184 | + if (rd & 7) { | |
| 1185 | + raise_exception(TT_ILL_INSN); | |
| 1186 | + return; | |
| 1187 | + } | |
| 1188 | + if (T0 & 0x3f) { | |
| 1189 | + raise_exception(TT_UNALIGNED); | |
| 1190 | + return; | |
| 1191 | + } | |
| 1192 | + for (i = 0; i < 16; i++) { | |
| 1193 | + T1 = *(uint32_t *)&env->fpr[rd++]; | |
| 1194 | + helper_st_asi(asi & 0x8f, 4); | |
| 1195 | + T0 += 4; | |
| 1180 | 1196 | } |
| 1181 | 1197 | T0 = tmp_T0; |
| 1182 | 1198 | T1 = tmp_T1; | ... | ... |