Revision 1ffc346f
b/target-mips/translate.c | ||
---|---|---|
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 | 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 | 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 | 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. */ |
Also available in: Unified diff