Commit 1ffc346f951f99ab85bbc75047ff79aec219595a
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. */ |