Commit a8cf66bb393ff420d40ae172a4c817bf2752918a

Authored by edgar_igl
1 parent 10c144e2

CRIS: Slight performance improvement for flag evaluation.

Translate sub and cmp ops separately when evaluating flags to avoid checking
for them at runtime.

Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6198 c046a42c-6fe2-441c-8c8c-71466251a162
target-cris/helper.h
@@ -14,6 +14,7 @@ DEF_HELPER_0(evaluate_flags_muls, void) @@ -14,6 +14,7 @@ DEF_HELPER_0(evaluate_flags_muls, void)
14 DEF_HELPER_0(evaluate_flags_mulu, void) 14 DEF_HELPER_0(evaluate_flags_mulu, void)
15 DEF_HELPER_0(evaluate_flags_mcp, void) 15 DEF_HELPER_0(evaluate_flags_mcp, void)
16 DEF_HELPER_0(evaluate_flags_alu_4, void) 16 DEF_HELPER_0(evaluate_flags_alu_4, void)
  17 +DEF_HELPER_0(evaluate_flags_sub_4, void)
17 DEF_HELPER_0(evaluate_flags_move_4, void) 18 DEF_HELPER_0(evaluate_flags_move_4, void)
18 DEF_HELPER_0(evaluate_flags_move_2, void) 19 DEF_HELPER_0(evaluate_flags_move_2, void)
19 DEF_HELPER_0(evaluate_flags, void) 20 DEF_HELPER_0(evaluate_flags, void)
target-cris/op_helper.c
@@ -245,17 +245,19 @@ void helper_rfn(void) @@ -245,17 +245,19 @@ void helper_rfn(void)
245 245
246 static void evaluate_flags_writeback(uint32_t flags) 246 static void evaluate_flags_writeback(uint32_t flags)
247 { 247 {
248 - int x; 248 + unsigned int x, z, mask;
249 249
250 /* Extended arithmetics, leave the z flag alone. */ 250 /* Extended arithmetics, leave the z flag alone. */
251 x = env->cc_x; 251 x = env->cc_x;
252 - if ((x || env->cc_op == CC_OP_ADDC)  
253 - && flags & Z_FLAG)  
254 - env->cc_mask &= ~Z_FLAG; 252 + mask = env->cc_mask | X_FLAG;
  253 + if (x) {
  254 + z = flags & Z_FLAG;
  255 + mask = mask & ~z;
  256 + }
  257 + flags &= mask;
255 258
256 /* all insn clear the x-flag except setf or clrf. */ 259 /* all insn clear the x-flag except setf or clrf. */
257 - env->pregs[PR_CCS] &= ~(env->cc_mask | X_FLAG);  
258 - flags &= env->cc_mask; 260 + env->pregs[PR_CCS] &= ~mask;
259 env->pregs[PR_CCS] |= flags; 261 env->pregs[PR_CCS] |= flags;
260 } 262 }
261 263
@@ -323,33 +325,25 @@ void helper_evaluate_flags_mcp(void) @@ -323,33 +325,25 @@ void helper_evaluate_flags_mcp(void)
323 uint32_t res; 325 uint32_t res;
324 uint32_t flags = 0; 326 uint32_t flags = 0;
325 327
326 - src = env->cc_src;  
327 - dst = env->cc_dest; 328 + src = env->cc_src & 0x80000000;
  329 + dst = env->cc_dest & 0x80000000;
328 res = env->cc_result; 330 res = env->cc_result;
329 331
330 if ((res & 0x80000000L) != 0L) 332 if ((res & 0x80000000L) != 0L)
331 { 333 {
332 flags |= N_FLAG; 334 flags |= N_FLAG;
333 - if (((src & 0x80000000L) == 0L)  
334 - && ((dst & 0x80000000L) == 0L))  
335 - { 335 + if (!src && !dst)
336 flags |= V_FLAG; 336 flags |= V_FLAG;
337 - }  
338 - else if (((src & 0x80000000L) != 0L) &&  
339 - ((dst & 0x80000000L) != 0L))  
340 - { 337 + else if (src & dst)
341 flags |= R_FLAG; 338 flags |= R_FLAG;
342 - }  
343 } 339 }
344 else 340 else
345 { 341 {
346 if (res == 0L) 342 if (res == 0L)
347 flags |= Z_FLAG; 343 flags |= Z_FLAG;
348 - if (((src & 0x80000000L) != 0L)  
349 - && ((dst & 0x80000000L) != 0L)) 344 + if (src & dst)
350 flags |= V_FLAG; 345 flags |= V_FLAG;
351 - if ((dst & 0x80000000L) != 0L  
352 - || (src & 0x80000000L) != 0L) 346 + if (dst | src)
353 flags |= R_FLAG; 347 flags |= R_FLAG;
354 } 348 }
355 349
@@ -363,56 +357,61 @@ void helper_evaluate_flags_alu_4(void) @@ -363,56 +357,61 @@ void helper_evaluate_flags_alu_4(void)
363 uint32_t res; 357 uint32_t res;
364 uint32_t flags = 0; 358 uint32_t flags = 0;
365 359
366 - src = env->cc_src;  
367 - dst = env->cc_dest; 360 + src = env->cc_src & 0x80000000;
  361 + dst = env->cc_dest & 0x80000000;
  362 + res = env->cc_result;
368 363
369 - /* Reconstruct the result. */  
370 - switch (env->cc_op) 364 + if ((res & 0x80000000L) != 0L)
371 { 365 {
372 - case CC_OP_SUB:  
373 - res = dst - src;  
374 - break;  
375 - case CC_OP_ADD:  
376 - res = dst + src;  
377 - break;  
378 - default:  
379 - res = env->cc_result;  
380 - break; 366 + flags |= N_FLAG;
  367 + if (!src && !dst)
  368 + flags |= V_FLAG;
  369 + else if (src & dst)
  370 + flags |= C_FLAG;
  371 + }
  372 + else
  373 + {
  374 + if (res == 0L)
  375 + flags |= Z_FLAG;
  376 + if (src & dst)
  377 + flags |= V_FLAG;
  378 + if (dst | src)
  379 + flags |= C_FLAG;
381 } 380 }
382 381
383 - if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP)  
384 - src = ~src; 382 + evaluate_flags_writeback(flags);
  383 +}
  384 +
  385 +void helper_evaluate_flags_sub_4(void)
  386 +{
  387 + uint32_t src;
  388 + uint32_t dst;
  389 + uint32_t res;
  390 + uint32_t flags = 0;
  391 +
  392 + src = (~env->cc_src) & 0x80000000;
  393 + dst = env->cc_dest & 0x80000000;
  394 + res = env->cc_result;
385 395
386 if ((res & 0x80000000L) != 0L) 396 if ((res & 0x80000000L) != 0L)
387 { 397 {
388 flags |= N_FLAG; 398 flags |= N_FLAG;
389 - if (((src & 0x80000000L) == 0L)  
390 - && ((dst & 0x80000000L) == 0L))  
391 - { 399 + if (!src && !dst)
392 flags |= V_FLAG; 400 flags |= V_FLAG;
393 - }  
394 - else if (((src & 0x80000000L) != 0L) &&  
395 - ((dst & 0x80000000L) != 0L))  
396 - { 401 + else if (src & dst)
397 flags |= C_FLAG; 402 flags |= C_FLAG;
398 - }  
399 } 403 }
400 else 404 else
401 { 405 {
402 if (res == 0L) 406 if (res == 0L)
403 flags |= Z_FLAG; 407 flags |= Z_FLAG;
404 - if (((src & 0x80000000L) != 0L)  
405 - && ((dst & 0x80000000L) != 0L)) 408 + if (src & dst)
406 flags |= V_FLAG; 409 flags |= V_FLAG;
407 - if ((dst & 0x80000000L) != 0L  
408 - || (src & 0x80000000L) != 0L) 410 + if (dst | src)
409 flags |= C_FLAG; 411 flags |= C_FLAG;
410 } 412 }
411 413
412 - if (env->cc_op == CC_OP_SUB  
413 - || env->cc_op == CC_OP_CMP) {  
414 - flags ^= C_FLAG;  
415 - } 414 + flags ^= C_FLAG;
416 evaluate_flags_writeback(flags); 415 evaluate_flags_writeback(flags);
417 } 416 }
418 417
@@ -607,6 +606,13 @@ void helper_top_evaluate_flags(void) @@ -607,6 +606,13 @@ void helper_top_evaluate_flags(void)
607 case CC_OP_FLAGS: 606 case CC_OP_FLAGS:
608 /* live. */ 607 /* live. */
609 break; 608 break;
  609 + case CC_OP_SUB:
  610 + case CC_OP_CMP:
  611 + if (env->cc_size == 4)
  612 + helper_evaluate_flags_sub_4();
  613 + else
  614 + helper_evaluate_flags();
  615 + break;
610 default: 616 default:
611 { 617 {
612 switch (env->cc_size) 618 switch (env->cc_size)
target-cris/translate.c
@@ -728,8 +728,15 @@ static void cris_evaluate_flags(DisasContext *dc) @@ -728,8 +728,15 @@ static void cris_evaluate_flags(DisasContext *dc)
728 case CC_OP_FLAGS: 728 case CC_OP_FLAGS:
729 /* live. */ 729 /* live. */
730 break; 730 break;
  731 + case CC_OP_SUB:
  732 + case CC_OP_CMP:
  733 + if (dc->cc_size == 4)
  734 + gen_helper_evaluate_flags_sub_4();
  735 + else
  736 + gen_helper_evaluate_flags();
  737 +
  738 + break;
731 default: 739 default:
732 - {  
733 switch (dc->cc_size) 740 switch (dc->cc_size)
734 { 741 {
735 case 4: 742 case 4:
@@ -739,7 +746,6 @@ static void cris_evaluate_flags(DisasContext *dc) @@ -739,7 +746,6 @@ static void cris_evaluate_flags(DisasContext *dc)
739 gen_helper_evaluate_flags(); 746 gen_helper_evaluate_flags();
740 break; 747 break;
741 } 748 }
742 - }  
743 break; 749 break;
744 } 750 }
745 if (dc->flagx_known) { 751 if (dc->flagx_known) {
@@ -821,13 +827,8 @@ static void cris_pre_alu_update_cc(DisasContext *dc, int op, @@ -821,13 +827,8 @@ static void cris_pre_alu_update_cc(DisasContext *dc, int op,
821 /* Update cc after executing ALU op. needs the result. */ 827 /* Update cc after executing ALU op. needs the result. */
822 static inline void cris_update_result(DisasContext *dc, TCGv res) 828 static inline void cris_update_result(DisasContext *dc, TCGv res)
823 { 829 {
824 - if (dc->update_cc) {  
825 - if (dc->cc_size == 4 &&  
826 - (dc->cc_op == CC_OP_SUB  
827 - || dc->cc_op == CC_OP_ADD))  
828 - return; 830 + if (dc->update_cc)
829 tcg_gen_mov_tl(cc_result, res); 831 tcg_gen_mov_tl(cc_result, res);
830 - }  
831 } 832 }
832 833
833 /* Returns one if the write back stage should execute. */ 834 /* Returns one if the write back stage should execute. */
@@ -1890,6 +1891,10 @@ static unsigned int dec_addc_r(DisasContext *dc) @@ -1890,6 +1891,10 @@ static unsigned int dec_addc_r(DisasContext *dc)
1890 DIS(fprintf (logfile, "addc $r%u, $r%u\n", 1891 DIS(fprintf (logfile, "addc $r%u, $r%u\n",
1891 dc->op1, dc->op2)); 1892 dc->op1, dc->op2));
1892 cris_evaluate_flags(dc); 1893 cris_evaluate_flags(dc);
  1894 + /* Set for this insn. */
  1895 + dc->flagx_known = 1;
  1896 + dc->flags_x = X_FLAG;
  1897 +
1893 cris_cc_mask(dc, CC_MASK_NZVC); 1898 cris_cc_mask(dc, CC_MASK_NZVC);
1894 cris_alu(dc, CC_OP_ADDC, 1899 cris_alu(dc, CC_OP_ADDC,
1895 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4); 1900 cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op1], 4);
@@ -2615,6 +2620,11 @@ static unsigned int dec_addc_mr(DisasContext *dc) @@ -2615,6 +2620,11 @@ static unsigned int dec_addc_mr(DisasContext *dc)
2615 dc->op2)); 2620 dc->op2));
2616 2621
2617 cris_evaluate_flags(dc); 2622 cris_evaluate_flags(dc);
  2623 +
  2624 + /* Set for this insn. */
  2625 + dc->flagx_known = 1;
  2626 + dc->flags_x = X_FLAG;
  2627 +
2618 cris_alu_m_alloc_temps(t); 2628 cris_alu_m_alloc_temps(t);
2619 insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]); 2629 insn_len = dec_prep_alu_m(dc, 0, 4, t[0], t[1]);
2620 cris_cc_mask(dc, CC_MASK_NZVC); 2630 cris_cc_mask(dc, CC_MASK_NZVC);