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 424 /* global register indices */
425 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 467 /* General purpose registers moves */
428 468 const unsigned char *regnames[] =
429 469 { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
... ... @@ -464,7 +504,7 @@ static inline void gen_op_store_gpr_T1(int reg)
464 504 /* Moves to/from shadow registers */
465 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 509 tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
470 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 513 tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
474 514  
475 515 tcg_gen_ld_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
  516 + dead_tmp(r_tmp);
476 517 }
477 518  
478 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 523 tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl));
483 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 527 tcg_gen_add_i32(r_tmp, cpu_env, r_tmp);
487 528  
488 529 tcg_gen_st_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg);
  530 + dead_tmp(r_tmp);
489 531 }
490 532  
491 533 /* Load immediates, zero being a special case. */
... ...