Commit 958fb4a92cbbb2b9b49e4b4502a836c71435570a
1 parent
b7ef7bf2
Use TCG for MIPS GPR moves.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4356 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
83 additions
and
42 deletions
target-mips/cpu.h
target-mips/exec.h
... | ... | @@ -14,8 +14,8 @@ register struct CPUMIPSState *env asm(AREG0); |
14 | 14 | #define T0 (env->t0) |
15 | 15 | #define T1 (env->t1) |
16 | 16 | #else |
17 | -register target_ulong T0 asm(AREG2); | |
18 | -register target_ulong T1 asm(AREG3); | |
17 | +register target_ulong T0 asm(AREG1); | |
18 | +register target_ulong T1 asm(AREG2); | |
19 | 19 | #endif |
20 | 20 | |
21 | 21 | #if defined (USE_HOST_FLOAT_REGS) | ... | ... |
target-mips/translate.c
... | ... | @@ -422,41 +422,71 @@ enum { |
422 | 422 | }; |
423 | 423 | |
424 | 424 | /* global register indices */ |
425 | -static TCGv cpu_env, current_tc_regs, cpu_T[2]; | |
425 | +static TCGv cpu_env, current_tc_gprs, cpu_T[2]; | |
426 | 426 | |
427 | +/* General purpose registers moves */ | |
427 | 428 | const unsigned char *regnames[] = |
428 | 429 | { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3", |
429 | 430 | "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", |
430 | 431 | "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", |
431 | 432 | "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", }; |
432 | 433 | |
433 | -/* Warning: no function for r0 register (hard wired to zero) */ | |
434 | -#define GEN32(func, NAME) \ | |
435 | -static GenOpFunc *NAME ## _table [32] = { \ | |
436 | -NULL, NAME ## 1, NAME ## 2, NAME ## 3, \ | |
437 | -NAME ## 4, NAME ## 5, NAME ## 6, NAME ## 7, \ | |
438 | -NAME ## 8, NAME ## 9, NAME ## 10, NAME ## 11, \ | |
439 | -NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15, \ | |
440 | -NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19, \ | |
441 | -NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23, \ | |
442 | -NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27, \ | |
443 | -NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31, \ | |
444 | -}; \ | |
445 | -static always_inline void func(int n) \ | |
446 | -{ \ | |
447 | - NAME ## _table[n](); \ | |
434 | +static inline void gen_op_load_gpr_TN(int t_index, int reg) | |
435 | +{ | |
436 | + tcg_gen_ld_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg); | |
448 | 437 | } |
449 | 438 | |
450 | -/* General purpose registers moves */ | |
451 | -GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr); | |
452 | -GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr); | |
439 | +static inline void gen_op_load_gpr_T0(int reg) | |
440 | +{ | |
441 | + gen_op_load_gpr_TN(0, reg); | |
442 | +} | |
443 | + | |
444 | +static inline void gen_op_load_gpr_T1(int reg) | |
445 | +{ | |
446 | + gen_op_load_gpr_TN(1, reg); | |
447 | +} | |
448 | + | |
449 | +static inline void gen_op_store_gpr_TN(int t_index, int reg) | |
450 | +{ | |
451 | + tcg_gen_st_tl(cpu_T[t_index], current_tc_gprs, sizeof(target_ulong) * reg); | |
452 | +} | |
453 | + | |
454 | +static inline void gen_op_store_gpr_T0(int reg) | |
455 | +{ | |
456 | + gen_op_store_gpr_TN(0, reg); | |
457 | +} | |
453 | 458 | |
454 | -GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr); | |
455 | -GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr); | |
459 | +static inline void gen_op_store_gpr_T1(int reg) | |
460 | +{ | |
461 | + gen_op_store_gpr_TN(1, reg); | |
462 | +} | |
456 | 463 | |
457 | 464 | /* Moves to/from shadow registers */ |
458 | -GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr); | |
459 | -GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr); | |
465 | +static inline void gen_op_load_srsgpr_T0(int reg) | |
466 | +{ | |
467 | + int r_tmp = tcg_temp_new(TCG_TYPE_I32); | |
468 | + | |
469 | + tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl)); | |
470 | + tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS); | |
471 | + tcg_gen_andi_i32(r_tmp, r_tmp, 0xf); | |
472 | + tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32); | |
473 | + tcg_gen_add_i32(r_tmp, cpu_env, r_tmp); | |
474 | + | |
475 | + tcg_gen_ld_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg); | |
476 | +} | |
477 | + | |
478 | +static inline void gen_op_store_srsgpr_T0(int reg) | |
479 | +{ | |
480 | + int r_tmp = tcg_temp_new(TCG_TYPE_I32); | |
481 | + | |
482 | + tcg_gen_ld_i32(r_tmp, cpu_env, offsetof(CPUState, CP0_SRSCtl)); | |
483 | + tcg_gen_shri_i32(r_tmp, r_tmp, CP0SRSCtl_PSS); | |
484 | + tcg_gen_andi_i32(r_tmp, r_tmp, 0xf); | |
485 | + tcg_gen_muli_i32(r_tmp, r_tmp, sizeof(target_ulong) * 32); | |
486 | + tcg_gen_add_i32(r_tmp, cpu_env, r_tmp); | |
487 | + | |
488 | + tcg_gen_st_tl(cpu_T[0], r_tmp, sizeof(target_ulong) * reg); | |
489 | +} | |
460 | 490 | |
461 | 491 | static const char *fregnames[] = |
462 | 492 | { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", |
... | ... | @@ -634,7 +664,7 @@ do { \ |
634 | 664 | #define GEN_STORE_T0_REG(Rn) \ |
635 | 665 | do { \ |
636 | 666 | if (Rn != 0) { \ |
637 | - glue(gen_op_store_T0,_gpr)(Rn); \ | |
667 | + gen_op_store_gpr_T0(Rn); \ | |
638 | 668 | ctx->glue(last_T0,_store) = gen_opc_ptr; \ |
639 | 669 | ctx->glue(last_T0,_gpr) = Rn; \ |
640 | 670 | } \ |
... | ... | @@ -643,14 +673,13 @@ do { \ |
643 | 673 | #define GEN_STORE_T1_REG(Rn) \ |
644 | 674 | do { \ |
645 | 675 | if (Rn != 0) \ |
646 | - glue(gen_op_store_T1,_gpr)(Rn); \ | |
676 | + gen_op_store_gpr_T1(Rn); \ | |
647 | 677 | } while (0) |
648 | 678 | |
649 | 679 | #define GEN_STORE_TN_SRSREG(Rn, Tn) \ |
650 | 680 | do { \ |
651 | - if (Rn != 0) { \ | |
652 | - glue(glue(gen_op_store_, Tn),_srsgpr)(Rn); \ | |
653 | - } \ | |
681 | + if (Rn != 0) \ | |
682 | + glue(gen_op_store_srsgpr_, Tn)(Rn); \ | |
654 | 683 | } while (0) |
655 | 684 | |
656 | 685 | #define GEN_LOAD_FREG_FTN(FTn, Fn) \ |
... | ... | @@ -813,6 +842,7 @@ static always_inline void check_mips_64(DisasContext *ctx) |
813 | 842 | generate_exception(ctx, EXCP_RI); |
814 | 843 | } |
815 | 844 | |
845 | +/* load/store instructions. */ | |
816 | 846 | #if defined(CONFIG_USER_ONLY) |
817 | 847 | #define op_ldst(name) gen_op_##name##_raw() |
818 | 848 | #define OP_LD_TABLE(width) |
... | ... | @@ -1638,7 +1668,7 @@ static void gen_cl (DisasContext *ctx, uint32_t opc, |
1638 | 1668 | generate_exception(ctx, EXCP_RI); |
1639 | 1669 | return; |
1640 | 1670 | } |
1641 | - gen_op_store_T0_gpr(rd); | |
1671 | + gen_op_store_gpr_T0(rd); | |
1642 | 1672 | MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]); |
1643 | 1673 | } |
1644 | 1674 | |
... | ... | @@ -1870,12 +1900,12 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, |
1870 | 1900 | return; |
1871 | 1901 | case OPC_BLTZAL: /* 0 < 0 */ |
1872 | 1902 | GEN_LOAD_IMM_TN(T0, ctx->pc + 8); |
1873 | - gen_op_store_T0_gpr(31); | |
1903 | + gen_op_store_gpr_T0(31); | |
1874 | 1904 | MIPS_DEBUG("bnever and link"); |
1875 | 1905 | return; |
1876 | 1906 | case OPC_BLTZALL: /* 0 < 0 likely */ |
1877 | 1907 | GEN_LOAD_IMM_TN(T0, ctx->pc + 8); |
1878 | - gen_op_store_T0_gpr(31); | |
1908 | + gen_op_store_gpr_T0(31); | |
1879 | 1909 | /* Skip the instruction in the delay slot */ |
1880 | 1910 | MIPS_DEBUG("bnever, link and skip"); |
1881 | 1911 | ctx->pc += 4; |
... | ... | @@ -2002,7 +2032,7 @@ static void gen_compute_branch (DisasContext *ctx, uint32_t opc, |
2002 | 2032 | ctx->btarget = btarget; |
2003 | 2033 | if (blink > 0) { |
2004 | 2034 | GEN_LOAD_IMM_TN(T0, ctx->pc + 8); |
2005 | - gen_op_store_T0_gpr(blink); | |
2035 | + gen_op_store_gpr_T0(blink); | |
2006 | 2036 | } |
2007 | 2037 | } |
2008 | 2038 | |
... | ... | @@ -4721,7 +4751,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int |
4721 | 4751 | return; |
4722 | 4752 | } |
4723 | 4753 | gen_mfc0(env, ctx, rd, ctx->opcode & 0x7); |
4724 | - gen_op_store_T0_gpr(rt); | |
4754 | + gen_op_store_gpr_T0(rt); | |
4725 | 4755 | opn = "mfc0"; |
4726 | 4756 | break; |
4727 | 4757 | case OPC_MTC0: |
... | ... | @@ -4738,7 +4768,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int |
4738 | 4768 | return; |
4739 | 4769 | } |
4740 | 4770 | gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7); |
4741 | - gen_op_store_T0_gpr(rt); | |
4771 | + gen_op_store_gpr_T0(rt); | |
4742 | 4772 | opn = "dmfc0"; |
4743 | 4773 | break; |
4744 | 4774 | case OPC_DMTC0: |
... | ... | @@ -4757,7 +4787,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int |
4757 | 4787 | } |
4758 | 4788 | gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1, |
4759 | 4789 | ctx->opcode & 0x7, (ctx->opcode >> 4) & 1); |
4760 | - gen_op_store_T0_gpr(rd); | |
4790 | + gen_op_store_gpr_T0(rd); | |
4761 | 4791 | opn = "mftr"; |
4762 | 4792 | break; |
4763 | 4793 | case OPC_MTTR: |
... | ... | @@ -6806,8 +6836,13 @@ void fpu_dump_state(CPUState *env, FILE *f, |
6806 | 6836 | void dump_fpu (CPUState *env) |
6807 | 6837 | { |
6808 | 6838 | if (loglevel) { |
6809 | - fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n", | |
6810 | - env->PC[env->current_tc], env->HI[env->current_tc][0], env->LO[env->current_tc][0], env->hflags, env->btarget, env->bcond); | |
6839 | + fprintf(logfile, | |
6840 | + "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx | |
6841 | + " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx | |
6842 | + " %04x\n", | |
6843 | + env->PC[env->current_tc], env->HI[env->current_tc][0], | |
6844 | + env->LO[env->current_tc][0], env->hflags, env->btarget, | |
6845 | + env->bcond); | |
6811 | 6846 | fpu_dump_state(env, logfile, fprintf, 0); |
6812 | 6847 | } |
6813 | 6848 | } |
... | ... | @@ -6881,15 +6916,18 @@ static void mips_tcg_init(void) |
6881 | 6916 | return; |
6882 | 6917 | |
6883 | 6918 | cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env"); |
6884 | - current_tc_regs = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG1, "current_tc_regs"); | |
6919 | + current_tc_gprs = tcg_global_mem_new(TCG_TYPE_PTR, | |
6920 | + TCG_AREG0, | |
6921 | + offsetof(CPUState, current_tc_gprs), | |
6922 | + "current_tc_gprs"); | |
6885 | 6923 | #if TARGET_LONG_BITS > HOST_LONG_BITS |
6886 | 6924 | cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL, |
6887 | 6925 | TCG_AREG0, offsetof(CPUState, t0), "T0"); |
6888 | 6926 | cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL, |
6889 | 6927 | TCG_AREG0, offsetof(CPUState, t1), "T1"); |
6890 | 6928 | #else |
6891 | - cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T0"); | |
6892 | - cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T1"); | |
6929 | + cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0"); | |
6930 | + cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1"); | |
6893 | 6931 | #endif |
6894 | 6932 | |
6895 | 6933 | inited = 1; | ... | ... |
target-mips/translate_init.c
... | ... | @@ -543,6 +543,8 @@ static int cpu_mips_register (CPUMIPSState *env, const mips_def_t *def) |
543 | 543 | env->CP0_Status_rw_bitmask = def->CP0_Status_rw_bitmask; |
544 | 544 | env->CP0_TCStatus_rw_bitmask = def->CP0_TCStatus_rw_bitmask; |
545 | 545 | env->CP0_SRSCtl = def->CP0_SRSCtl; |
546 | + env->current_tc = 0; | |
547 | + env->current_tc_gprs = &env->gpr[env->current_tc][0]; | |
546 | 548 | env->SEGBITS = def->SEGBITS; |
547 | 549 | env->SEGMask = (target_ulong)((1ULL << def->SEGBITS) - 1); |
548 | 550 | #if defined(TARGET_MIPS64) | ... | ... |