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) | ... | ... |