Commit 1ffc346f951f99ab85bbc75047ff79aec219595a

Authored by ths
1 parent 9c6c6662

Be more economical with local temporaries.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4384 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 44 additions and 2 deletions
target-mips/translate.c
@@ -424,6 +424,46 @@ enum { @@ -424,6 +424,46 @@ enum {
424 /* global register indices */ 424 /* global register indices */
425 static TCGv cpu_env, current_tc_gprs, cpu_T[2]; 425 static TCGv cpu_env, current_tc_gprs, cpu_T[2];
426 426
  427 +/* The code generator doesn't like lots of temporaries, so maintain our own
  428 + cache for reuse within a function. */
  429 +#define MAX_TEMPS 4
  430 +static int num_temps;
  431 +static TCGv temps[MAX_TEMPS];
  432 +
  433 +/* Allocate a temporary variable. */
  434 +static TCGv new_tmp(void)
  435 +{
  436 + TCGv tmp;
  437 + if (num_temps == MAX_TEMPS)
  438 + abort();
  439 +
  440 + if (GET_TCGV(temps[num_temps]))
  441 + return temps[num_temps++];
  442 +
  443 + tmp = tcg_temp_new(TCG_TYPE_I32);
  444 + temps[num_temps++] = tmp;
  445 + return tmp;
  446 +}
  447 +
  448 +/* Release a temporary variable. */
  449 +static void dead_tmp(TCGv tmp)
  450 +{
  451 + int i;
  452 + num_temps--;
  453 + i = num_temps;
  454 + if (GET_TCGV(temps[i]) == GET_TCGV(tmp))
  455 + return;
  456 +
  457 + /* Shuffle this temp to the last slot. */
  458 + while (GET_TCGV(temps[i]) != GET_TCGV(tmp))
  459 + i--;
  460 + while (i < num_temps) {
  461 + temps[i] = temps[i + 1];
  462 + i++;
  463 + }
  464 + temps[i] = tmp;
  465 +}
  466 +
427 /* General purpose registers moves */ 467 /* General purpose registers moves */
428 const unsigned char *regnames[] = 468 const unsigned char *regnames[] =
429 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3", 469 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
@@ -464,7 +504,7 @@ static inline void gen_op_store_gpr_T1(int reg) @@ -464,7 +504,7 @@ static inline void gen_op_store_gpr_T1(int reg)
464 /* Moves to/from shadow registers */ 504 /* Moves to/from shadow registers */
465 static inline void gen_op_load_srsgpr_T0(int reg) 505 static inline void gen_op_load_srsgpr_T0(int reg)
466 { 506 {
467 - int r_tmp = tcg_temp_new(TCG_TYPE_I32); 507 + int r_tmp = new_tmp();
468 508
469 tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl)); 509 tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
470 tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS); 510 tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
@@ -473,11 +513,12 @@ static inline void gen_op_load_srsgpr_T0(int reg) @@ -473,11 +513,12 @@ static inline void gen_op_load_srsgpr_T0(int reg)
473 tcg_gen_add_i32(r_tmp, cpu_env, r_tmp); 513 tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
474 514
475 tcg_gen_ld_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg); 515 tcg_gen_ld_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
  516 + dead_tmp(r_tmp);
476 } 517 }
477 518
478 static inline void gen_op_store_srsgpr_T0(int reg) 519 static inline void gen_op_store_srsgpr_T0(int reg)
479 { 520 {
480 - int r_tmp = tcg_temp_new(TCG_TYPE_I32); 521 + int r_tmp = new_tmp();
481 522
482 tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl)); 523 tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
483 tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS); 524 tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS);
@@ -486,6 +527,7 @@ static inline void gen_op_store_srsgpr_T0(int reg) @@ -486,6 +527,7 @@ static inline void gen_op_store_srsgpr_T0(int reg)
486 tcg_gen_add_i32(r_tmp, cpu_env, r_tmp); 527 tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
487 528
488 tcg_gen_st_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg); 529 tcg_gen_st_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
  530 + dead_tmp(r_tmp);
489 } 531 }
490 532
491 /* Load immediates, zero being a special case. */ 533 /* Load immediates, zero being a special case. */