Commit 182608d44cc64bfec3f82e7895b7572db60b7c92
1 parent
74637406
target-ppc: convert 405 MAC instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5591 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
72 additions
and
140 deletions
target-ppc/op.c
... | ... | @@ -326,34 +326,6 @@ void OPPROTO op_store_fpscr (void) |
326 | 326 | RETURN(); |
327 | 327 | } |
328 | 328 | |
329 | -/*** Integer arithmetic ***/ | |
330 | -/* add */ | |
331 | -void OPPROTO op_check_addo (void) | |
332 | -{ | |
333 | - int ov = (((uint32_t)T2 ^ (uint32_t)T1 ^ UINT32_MAX) & | |
334 | - ((uint32_t)T2 ^ (uint32_t)T0)) >> 31; | |
335 | - if (ov) { | |
336 | - env->xer |= (1 << XER_OV) | (1 << XER_SO); | |
337 | - } else { | |
338 | - env->xer &= ~(1 << XER_OV); | |
339 | - } | |
340 | - RETURN(); | |
341 | -} | |
342 | - | |
343 | -#if defined(TARGET_PPC64) | |
344 | -void OPPROTO op_check_addo_64 (void) | |
345 | -{ | |
346 | - int ov = (((uint64_t)T2 ^ (uint64_t)T1 ^ UINT64_MAX) & | |
347 | - ((uint64_t)T2 ^ (uint64_t)T0)) >> 63; | |
348 | - if (ov) { | |
349 | - env->xer |= (1 << XER_OV) | (1 << XER_SO); | |
350 | - } else { | |
351 | - env->xer &= ~(1 << XER_OV); | |
352 | - } | |
353 | - RETURN(); | |
354 | -} | |
355 | -#endif | |
356 | - | |
357 | 329 | /*** Integer shift ***/ |
358 | 330 | void OPPROTO op_srli_T1 (void) |
359 | 331 | { |
... | ... | @@ -1062,73 +1034,6 @@ void OPPROTO op_602_mfrom (void) |
1062 | 1034 | #endif |
1063 | 1035 | |
1064 | 1036 | /* PowerPC 4xx specific micro-ops */ |
1065 | -void OPPROTO op_405_add_T0_T2 (void) | |
1066 | -{ | |
1067 | - T0 = (int32_t)T0 + (int32_t)T2; | |
1068 | - RETURN(); | |
1069 | -} | |
1070 | - | |
1071 | -void OPPROTO op_405_mulchw (void) | |
1072 | -{ | |
1073 | - T0 = ((int16_t)T0) * ((int16_t)(T1 >> 16)); | |
1074 | - RETURN(); | |
1075 | -} | |
1076 | - | |
1077 | -void OPPROTO op_405_mulchwu (void) | |
1078 | -{ | |
1079 | - T0 = ((uint16_t)T0) * ((uint16_t)(T1 >> 16)); | |
1080 | - RETURN(); | |
1081 | -} | |
1082 | - | |
1083 | -void OPPROTO op_405_mulhhw (void) | |
1084 | -{ | |
1085 | - T0 = ((int16_t)(T0 >> 16)) * ((int16_t)(T1 >> 16)); | |
1086 | - RETURN(); | |
1087 | -} | |
1088 | - | |
1089 | -void OPPROTO op_405_mulhhwu (void) | |
1090 | -{ | |
1091 | - T0 = ((uint16_t)(T0 >> 16)) * ((uint16_t)(T1 >> 16)); | |
1092 | - RETURN(); | |
1093 | -} | |
1094 | - | |
1095 | -void OPPROTO op_405_mullhw (void) | |
1096 | -{ | |
1097 | - T0 = ((int16_t)T0) * ((int16_t)T1); | |
1098 | - RETURN(); | |
1099 | -} | |
1100 | - | |
1101 | -void OPPROTO op_405_mullhwu (void) | |
1102 | -{ | |
1103 | - T0 = ((uint16_t)T0) * ((uint16_t)T1); | |
1104 | - RETURN(); | |
1105 | -} | |
1106 | - | |
1107 | -void OPPROTO op_405_check_sat (void) | |
1108 | -{ | |
1109 | - do_405_check_sat(); | |
1110 | - RETURN(); | |
1111 | -} | |
1112 | - | |
1113 | -void OPPROTO op_405_check_ovu (void) | |
1114 | -{ | |
1115 | - if (likely(T0 >= T2)) { | |
1116 | - env->xer &= ~(1 << XER_OV); | |
1117 | - } else { | |
1118 | - env->xer |= (1 << XER_OV) | (1 << XER_SO); | |
1119 | - } | |
1120 | - RETURN(); | |
1121 | -} | |
1122 | - | |
1123 | -void OPPROTO op_405_check_satu (void) | |
1124 | -{ | |
1125 | - if (unlikely(T0 < T2)) { | |
1126 | - /* Saturate result */ | |
1127 | - T0 = UINT32_MAX; | |
1128 | - } | |
1129 | - RETURN(); | |
1130 | -} | |
1131 | - | |
1132 | 1037 | void OPPROTO op_load_dcr (void) |
1133 | 1038 | { |
1134 | 1039 | do_load_dcr(); | ... | ... |
target-ppc/op_helper.c
... | ... | @@ -1510,18 +1510,6 @@ void do_op_602_mfrom (void) |
1510 | 1510 | |
1511 | 1511 | /*****************************************************************************/ |
1512 | 1512 | /* Embedded PowerPC specific helpers */ |
1513 | -void do_405_check_sat (void) | |
1514 | -{ | |
1515 | - if (!likely((((uint32_t)T1 ^ (uint32_t)T2) >> 31) || | |
1516 | - !(((uint32_t)T0 ^ (uint32_t)T2) >> 31))) { | |
1517 | - /* Saturate result */ | |
1518 | - if (T2 >> 31) { | |
1519 | - T0 = INT32_MIN; | |
1520 | - } else { | |
1521 | - T0 = INT32_MAX; | |
1522 | - } | |
1523 | - } | |
1524 | -} | |
1525 | 1513 | |
1526 | 1514 | /* XXX: to be improved to check access rights when in user-mode */ |
1527 | 1515 | void do_load_dcr (void) | ... | ... |
target-ppc/op_helper.h
target-ppc/translate.c
... | ... | @@ -5214,8 +5214,11 @@ static always_inline void gen_405_mulladd_insn (DisasContext *ctx, |
5214 | 5214 | int opc2, int opc3, |
5215 | 5215 | int ra, int rb, int rt, int Rc) |
5216 | 5216 | { |
5217 | - tcg_gen_mov_tl(cpu_T[0], cpu_gpr[ra]); | |
5218 | - tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rb]); | |
5217 | + TCGv t0, t1; | |
5218 | + | |
5219 | + t0 = tcg_temp_local_new(TCG_TYPE_TL); | |
5220 | + t1 = tcg_temp_local_new(TCG_TYPE_TL); | |
5221 | + | |
5219 | 5222 | switch (opc3 & 0x0D) { |
5220 | 5223 | case 0x05: |
5221 | 5224 | /* macchw - macchw. - macchwo - macchwo. */ |
... | ... | @@ -5223,13 +5226,17 @@ static always_inline void gen_405_mulladd_insn (DisasContext *ctx, |
5223 | 5226 | /* nmacchw - nmacchw. - nmacchwo - nmacchwo. */ |
5224 | 5227 | /* nmacchws - nmacchws. - nmacchwso - nmacchwso. */ |
5225 | 5228 | /* mulchw - mulchw. */ |
5226 | - gen_op_405_mulchw(); | |
5229 | + tcg_gen_ext16s_tl(t0, cpu_gpr[ra]); | |
5230 | + tcg_gen_sari_tl(t1, cpu_gpr[rb], 16); | |
5231 | + tcg_gen_ext16s_tl(t1, t1); | |
5227 | 5232 | break; |
5228 | 5233 | case 0x04: |
5229 | 5234 | /* macchwu - macchwu. - macchwuo - macchwuo. */ |
5230 | 5235 | /* macchwsu - macchwsu. - macchwsuo - macchwsuo. */ |
5231 | 5236 | /* mulchwu - mulchwu. */ |
5232 | - gen_op_405_mulchwu(); | |
5237 | + tcg_gen_ext16u_tl(t0, cpu_gpr[ra]); | |
5238 | + tcg_gen_shri_tl(t1, cpu_gpr[rb], 16); | |
5239 | + tcg_gen_ext16u_tl(t1, t1); | |
5233 | 5240 | break; |
5234 | 5241 | case 0x01: |
5235 | 5242 | /* machhw - machhw. - machhwo - machhwo. */ |
... | ... | @@ -5237,13 +5244,19 @@ static always_inline void gen_405_mulladd_insn (DisasContext *ctx, |
5237 | 5244 | /* nmachhw - nmachhw. - nmachhwo - nmachhwo. */ |
5238 | 5245 | /* nmachhws - nmachhws. - nmachhwso - nmachhwso. */ |
5239 | 5246 | /* mulhhw - mulhhw. */ |
5240 | - gen_op_405_mulhhw(); | |
5247 | + tcg_gen_sari_tl(t0, cpu_gpr[ra], 16); | |
5248 | + tcg_gen_ext16s_tl(t0, t0); | |
5249 | + tcg_gen_sari_tl(t1, cpu_gpr[rb], 16); | |
5250 | + tcg_gen_ext16s_tl(t1, t1); | |
5241 | 5251 | break; |
5242 | 5252 | case 0x00: |
5243 | 5253 | /* machhwu - machhwu. - machhwuo - machhwuo. */ |
5244 | 5254 | /* machhwsu - machhwsu. - machhwsuo - machhwsuo. */ |
5245 | 5255 | /* mulhhwu - mulhhwu. */ |
5246 | - gen_op_405_mulhhwu(); | |
5256 | + tcg_gen_shri_tl(t0, cpu_gpr[ra], 16); | |
5257 | + tcg_gen_ext16u_tl(t0, t0); | |
5258 | + tcg_gen_shri_tl(t1, cpu_gpr[rb], 16); | |
5259 | + tcg_gen_ext16u_tl(t1, t1); | |
5247 | 5260 | break; |
5248 | 5261 | case 0x0D: |
5249 | 5262 | /* maclhw - maclhw. - maclhwo - maclhwo. */ |
... | ... | @@ -5251,43 +5264,70 @@ static always_inline void gen_405_mulladd_insn (DisasContext *ctx, |
5251 | 5264 | /* nmaclhw - nmaclhw. - nmaclhwo - nmaclhwo. */ |
5252 | 5265 | /* nmaclhws - nmaclhws. - nmaclhwso - nmaclhwso. */ |
5253 | 5266 | /* mullhw - mullhw. */ |
5254 | - gen_op_405_mullhw(); | |
5267 | + tcg_gen_ext16s_tl(t0, cpu_gpr[ra]); | |
5268 | + tcg_gen_ext16s_tl(t1, cpu_gpr[rb]); | |
5255 | 5269 | break; |
5256 | 5270 | case 0x0C: |
5257 | 5271 | /* maclhwu - maclhwu. - maclhwuo - maclhwuo. */ |
5258 | 5272 | /* maclhwsu - maclhwsu. - maclhwsuo - maclhwsuo. */ |
5259 | 5273 | /* mullhwu - mullhwu. */ |
5260 | - gen_op_405_mullhwu(); | |
5274 | + tcg_gen_ext16u_tl(t0, cpu_gpr[ra]); | |
5275 | + tcg_gen_ext16u_tl(t1, cpu_gpr[rb]); | |
5261 | 5276 | break; |
5262 | 5277 | } |
5263 | - if (opc2 & 0x02) { | |
5264 | - /* nmultiply-and-accumulate (0x0E) */ | |
5265 | - tcg_gen_neg_tl(cpu_T[0], cpu_T[0]); | |
5266 | - } | |
5267 | 5278 | if (opc2 & 0x04) { |
5268 | - /* (n)multiply-and-accumulate (0x0C - 0x0E) */ | |
5269 | - tcg_gen_mov_tl(cpu_T[2], cpu_gpr[rt]); | |
5270 | - tcg_gen_mov_tl(cpu_T[1], cpu_T[0]); | |
5271 | - gen_op_405_add_T0_T2(); | |
5272 | - } | |
5273 | - if (opc3 & 0x10) { | |
5274 | - /* Check overflow */ | |
5275 | - if (opc3 & 0x01) | |
5276 | - gen_op_check_addo(); | |
5277 | - else | |
5278 | - gen_op_405_check_ovu(); | |
5279 | - } | |
5280 | - if (opc3 & 0x02) { | |
5281 | - /* Saturate */ | |
5282 | - if (opc3 & 0x01) | |
5283 | - gen_op_405_check_sat(); | |
5284 | - else | |
5285 | - gen_op_405_check_satu(); | |
5279 | + /* (n)multiply-and-accumulate (0x0C / 0x0E) */ | |
5280 | + tcg_gen_mul_tl(t1, t0, t1); | |
5281 | + if (opc2 & 0x02) { | |
5282 | + /* nmultiply-and-accumulate (0x0E) */ | |
5283 | + tcg_gen_sub_tl(t0, cpu_gpr[rt], t1); | |
5284 | + } else { | |
5285 | + /* multiply-and-accumulate (0x0C) */ | |
5286 | + tcg_gen_add_tl(t0, cpu_gpr[rt], t1); | |
5287 | + } | |
5288 | + | |
5289 | + if (opc3 & 0x12) { | |
5290 | + /* Check overflow and/or saturate */ | |
5291 | + int l1 = gen_new_label(); | |
5292 | + | |
5293 | + if (opc3 & 0x10) { | |
5294 | + /* Start with XER OV disabled, the most likely case */ | |
5295 | + tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV)); | |
5296 | + } | |
5297 | + if (opc3 & 0x01) { | |
5298 | + /* Signed */ | |
5299 | + tcg_gen_xor_tl(t1, cpu_gpr[rt], t1); | |
5300 | + tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1); | |
5301 | + tcg_gen_xor_tl(t1, cpu_gpr[rt], t0); | |
5302 | + tcg_gen_brcondi_tl(TCG_COND_LT, t1, 0, l1); | |
5303 | + if (opc3 & 0x02) { | |
5304 | + /* Saturate */ | |
5305 | + tcg_gen_sari_tl(t0, cpu_gpr[rt], 31); | |
5306 | + tcg_gen_xori_tl(t0, t0, 0x7fffffff); | |
5307 | + } | |
5308 | + } else { | |
5309 | + /* Unsigned */ | |
5310 | + tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1); | |
5311 | + if (opc3 & 0x02) { | |
5312 | + /* Saturate */ | |
5313 | + tcg_gen_movi_tl(t0, UINT32_MAX); | |
5314 | + } | |
5315 | + } | |
5316 | + if (opc3 & 0x10) { | |
5317 | + /* Check overflow */ | |
5318 | + tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO)); | |
5319 | + } | |
5320 | + gen_set_label(l1); | |
5321 | + tcg_gen_mov_tl(cpu_gpr[rt], t0); | |
5322 | + } | |
5323 | + } else { | |
5324 | + tcg_gen_mul_tl(cpu_gpr[rt], t0, t1); | |
5286 | 5325 | } |
5287 | - tcg_gen_mov_tl(cpu_gpr[rt], cpu_T[0]); | |
5326 | + tcg_temp_free(t0); | |
5327 | + tcg_temp_free(t1); | |
5288 | 5328 | if (unlikely(Rc) != 0) { |
5289 | 5329 | /* Update Rc0 */ |
5290 | - gen_set_Rc0(ctx, cpu_T[0]); | |
5330 | + gen_set_Rc0(ctx, cpu_gpr[rt]); | |
5291 | 5331 | } |
5292 | 5332 | } |
5293 | 5333 | ... | ... |