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 | 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. */ | ... | ... |