Commit 375ee38b4ba6c2c640a77253ffadcdcea5d76002
1 parent
21fc3cfc
Convert Sparc64 trap state ops to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4018 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
103 additions
and
70 deletions
linux-user/main.c
| ... | ... | @@ -680,7 +680,7 @@ void cpu_loop (CPUSPARCState *env) |
| 680 | 680 | if (trapnr == TT_DFAULT) |
| 681 | 681 | info._sifields._sigfault._addr = env->dmmuregs[4]; |
| 682 | 682 | else |
| 683 | - info._sifields._sigfault._addr = env->tpc[env->tl]; | |
| 683 | + info._sifields._sigfault._addr = env->tsptr->tpc; | |
| 684 | 684 | queue_signal(info.si_signo, &info); |
| 685 | 685 | } |
| 686 | 686 | break; | ... | ... |
target-sparc/cpu.h
| ... | ... | @@ -169,6 +169,12 @@ |
| 169 | 169 | #define NB_MMU_MODES 2 |
| 170 | 170 | #else |
| 171 | 171 | #define NB_MMU_MODES 3 |
| 172 | +typedef struct trap_state { | |
| 173 | + uint64_t tpc; | |
| 174 | + uint64_t tnpc; | |
| 175 | + uint64_t tstate; | |
| 176 | + uint32_t tt; | |
| 177 | +} trap_state; | |
| 172 | 178 | #endif |
| 173 | 179 | |
| 174 | 180 | typedef struct CPUSPARCState { |
| ... | ... | @@ -234,10 +240,8 @@ typedef struct CPUSPARCState { |
| 234 | 240 | #if defined(TARGET_SPARC64) |
| 235 | 241 | #define MAXTL 4 |
| 236 | 242 | uint64_t t0, t1, t2; |
| 237 | - uint64_t tpc[MAXTL]; | |
| 238 | - uint64_t tnpc[MAXTL]; | |
| 239 | - uint64_t tstate[MAXTL]; | |
| 240 | - uint32_t tt[MAXTL]; | |
| 243 | + trap_state *tsptr; | |
| 244 | + trap_state ts[MAXTL]; | |
| 241 | 245 | uint32_t xcc; /* Extended integer condition codes */ |
| 242 | 246 | uint32_t asi; |
| 243 | 247 | uint32_t pstate; | ... | ... |
target-sparc/op.c
| ... | ... | @@ -805,46 +805,6 @@ void OPPROTO op_wrccr(void) |
| 805 | 805 | PUT_CCR(env, T0); |
| 806 | 806 | } |
| 807 | 807 | |
| 808 | -void OPPROTO op_rdtpc(void) | |
| 809 | -{ | |
| 810 | - T0 = env->tpc[env->tl]; | |
| 811 | -} | |
| 812 | - | |
| 813 | -void OPPROTO op_wrtpc(void) | |
| 814 | -{ | |
| 815 | - env->tpc[env->tl] = T0; | |
| 816 | -} | |
| 817 | - | |
| 818 | -void OPPROTO op_rdtnpc(void) | |
| 819 | -{ | |
| 820 | - T0 = env->tnpc[env->tl]; | |
| 821 | -} | |
| 822 | - | |
| 823 | -void OPPROTO op_wrtnpc(void) | |
| 824 | -{ | |
| 825 | - env->tnpc[env->tl] = T0; | |
| 826 | -} | |
| 827 | - | |
| 828 | -void OPPROTO op_rdtstate(void) | |
| 829 | -{ | |
| 830 | - T0 = env->tstate[env->tl]; | |
| 831 | -} | |
| 832 | - | |
| 833 | -void OPPROTO op_wrtstate(void) | |
| 834 | -{ | |
| 835 | - env->tstate[env->tl] = T0; | |
| 836 | -} | |
| 837 | - | |
| 838 | -void OPPROTO op_rdtt(void) | |
| 839 | -{ | |
| 840 | - T0 = env->tt[env->tl]; | |
| 841 | -} | |
| 842 | - | |
| 843 | -void OPPROTO op_wrtt(void) | |
| 844 | -{ | |
| 845 | - env->tt[env->tl] = T0; | |
| 846 | -} | |
| 847 | - | |
| 848 | 808 | // CWP handling is reversed in V9, but we still use the V8 register |
| 849 | 809 | // order. |
| 850 | 810 | void OPPROTO op_rdcwp(void) | ... | ... |
target-sparc/op_helper.c
| ... | ... | @@ -1675,23 +1675,25 @@ void helper_wrpstate(target_ulong new_state) |
| 1675 | 1675 | void helper_done(void) |
| 1676 | 1676 | { |
| 1677 | 1677 | env->tl--; |
| 1678 | - env->pc = env->tnpc[env->tl]; | |
| 1679 | - env->npc = env->tnpc[env->tl] + 4; | |
| 1680 | - PUT_CCR(env, env->tstate[env->tl] >> 32); | |
| 1681 | - env->asi = (env->tstate[env->tl] >> 24) & 0xff; | |
| 1682 | - change_pstate((env->tstate[env->tl] >> 8) & 0xf3f); | |
| 1683 | - PUT_CWP64(env, env->tstate[env->tl] & 0xff); | |
| 1678 | + env->tsptr = &env->ts[env->tl]; | |
| 1679 | + env->pc = env->tsptr->tpc; | |
| 1680 | + env->npc = env->tsptr->tnpc + 4; | |
| 1681 | + PUT_CCR(env, env->tsptr->tstate >> 32); | |
| 1682 | + env->asi = (env->tsptr->tstate >> 24) & 0xff; | |
| 1683 | + change_pstate((env->tsptr->tstate >> 8) & 0xf3f); | |
| 1684 | + PUT_CWP64(env, env->tsptr->tstate & 0xff); | |
| 1684 | 1685 | } |
| 1685 | 1686 | |
| 1686 | 1687 | void helper_retry(void) |
| 1687 | 1688 | { |
| 1688 | 1689 | env->tl--; |
| 1689 | - env->pc = env->tpc[env->tl]; | |
| 1690 | - env->npc = env->tnpc[env->tl]; | |
| 1691 | - PUT_CCR(env, env->tstate[env->tl] >> 32); | |
| 1692 | - env->asi = (env->tstate[env->tl] >> 24) & 0xff; | |
| 1693 | - change_pstate((env->tstate[env->tl] >> 8) & 0xf3f); | |
| 1694 | - PUT_CWP64(env, env->tstate[env->tl] & 0xff); | |
| 1690 | + env->tsptr = &env->ts[env->tl]; | |
| 1691 | + env->pc = env->tsptr->tpc; | |
| 1692 | + env->npc = env->tsptr->tnpc; | |
| 1693 | + PUT_CCR(env, env->tsptr->tstate >> 32); | |
| 1694 | + env->asi = (env->tsptr->tstate >> 24) & 0xff; | |
| 1695 | + change_pstate((env->tsptr->tstate >> 8) & 0xf3f); | |
| 1696 | + PUT_CWP64(env, env->tsptr->tstate & 0xff); | |
| 1695 | 1697 | } |
| 1696 | 1698 | #endif |
| 1697 | 1699 | |
| ... | ... | @@ -1813,11 +1815,12 @@ void do_interrupt(int intno) |
| 1813 | 1815 | return; |
| 1814 | 1816 | } |
| 1815 | 1817 | #endif |
| 1816 | - env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) | | |
| 1817 | - ((env->pstate & 0xf3f) << 8) | GET_CWP64(env); | |
| 1818 | - env->tpc[env->tl] = env->pc; | |
| 1819 | - env->tnpc[env->tl] = env->npc; | |
| 1820 | - env->tt[env->tl] = intno; | |
| 1818 | + env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) | | |
| 1819 | + ((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) | | |
| 1820 | + GET_CWP64(env); | |
| 1821 | + env->tsptr->tpc = env->pc; | |
| 1822 | + env->tsptr->tnpc = env->npc; | |
| 1823 | + env->tsptr->tt = intno; | |
| 1821 | 1824 | change_pstate(PS_PEF | PS_PRIV | PS_AG); |
| 1822 | 1825 | |
| 1823 | 1826 | if (intno == TT_CLRWIN) |
| ... | ... | @@ -1835,6 +1838,7 @@ void do_interrupt(int intno) |
| 1835 | 1838 | if (env->tl != MAXTL) |
| 1836 | 1839 | env->tl++; |
| 1837 | 1840 | } |
| 1841 | + env->tsptr = &env->ts[env->tl]; | |
| 1838 | 1842 | env->pc = env->tbr; |
| 1839 | 1843 | env->npc = env->pc + 4; |
| 1840 | 1844 | env->exception_index = 0; | ... | ... |
target-sparc/translate.c
| ... | ... | @@ -1386,16 +1386,48 @@ static void disas_sparc_insn(DisasContext * dc) |
| 1386 | 1386 | rs1 = GET_FIELD(insn, 13, 17); |
| 1387 | 1387 | switch (rs1) { |
| 1388 | 1388 | case 0: // tpc |
| 1389 | - gen_op_rdtpc(); | |
| 1389 | + { | |
| 1390 | + TCGv r_tsptr; | |
| 1391 | + | |
| 1392 | + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 1393 | + tcg_gen_ld_ptr(r_tsptr, cpu_env, | |
| 1394 | + offsetof(CPUState, tsptr)); | |
| 1395 | + tcg_gen_ld_tl(cpu_T[0], r_tsptr, | |
| 1396 | + offsetof(trap_state, tpc)); | |
| 1397 | + } | |
| 1390 | 1398 | break; |
| 1391 | 1399 | case 1: // tnpc |
| 1392 | - gen_op_rdtnpc(); | |
| 1400 | + { | |
| 1401 | + TCGv r_tsptr; | |
| 1402 | + | |
| 1403 | + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 1404 | + tcg_gen_ld_ptr(r_tsptr, cpu_env, | |
| 1405 | + offsetof(CPUState, tsptr)); | |
| 1406 | + tcg_gen_ld_tl(cpu_T[0], r_tsptr, | |
| 1407 | + offsetof(trap_state, tnpc)); | |
| 1408 | + } | |
| 1393 | 1409 | break; |
| 1394 | 1410 | case 2: // tstate |
| 1395 | - gen_op_rdtstate(); | |
| 1411 | + { | |
| 1412 | + TCGv r_tsptr; | |
| 1413 | + | |
| 1414 | + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 1415 | + tcg_gen_ld_ptr(r_tsptr, cpu_env, | |
| 1416 | + offsetof(CPUState, tsptr)); | |
| 1417 | + tcg_gen_ld_tl(cpu_T[0], r_tsptr, | |
| 1418 | + offsetof(trap_state, tstate)); | |
| 1419 | + } | |
| 1396 | 1420 | break; |
| 1397 | 1421 | case 3: // tt |
| 1398 | - gen_op_rdtt(); | |
| 1422 | + { | |
| 1423 | + TCGv r_tsptr; | |
| 1424 | + | |
| 1425 | + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 1426 | + tcg_gen_ld_ptr(r_tsptr, cpu_env, | |
| 1427 | + offsetof(CPUState, tsptr)); | |
| 1428 | + tcg_gen_ld_i32(cpu_T[0], r_tsptr, | |
| 1429 | + offsetof(trap_state, tt)); | |
| 1430 | + } | |
| 1399 | 1431 | break; |
| 1400 | 1432 | case 4: // tick |
| 1401 | 1433 | { |
| ... | ... | @@ -2536,16 +2568,48 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2536 | 2568 | #ifdef TARGET_SPARC64 |
| 2537 | 2569 | switch (rd) { |
| 2538 | 2570 | case 0: // tpc |
| 2539 | - gen_op_wrtpc(); | |
| 2571 | + { | |
| 2572 | + TCGv r_tsptr; | |
| 2573 | + | |
| 2574 | + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 2575 | + tcg_gen_ld_ptr(r_tsptr, cpu_env, | |
| 2576 | + offsetof(CPUState, tsptr)); | |
| 2577 | + tcg_gen_st_tl(cpu_T[0], r_tsptr, | |
| 2578 | + offsetof(trap_state, tpc)); | |
| 2579 | + } | |
| 2540 | 2580 | break; |
| 2541 | 2581 | case 1: // tnpc |
| 2542 | - gen_op_wrtnpc(); | |
| 2582 | + { | |
| 2583 | + TCGv r_tsptr; | |
| 2584 | + | |
| 2585 | + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 2586 | + tcg_gen_ld_ptr(r_tsptr, cpu_env, | |
| 2587 | + offsetof(CPUState, tsptr)); | |
| 2588 | + tcg_gen_st_tl(cpu_T[0], r_tsptr, | |
| 2589 | + offsetof(trap_state, tnpc)); | |
| 2590 | + } | |
| 2543 | 2591 | break; |
| 2544 | 2592 | case 2: // tstate |
| 2545 | - gen_op_wrtstate(); | |
| 2593 | + { | |
| 2594 | + TCGv r_tsptr; | |
| 2595 | + | |
| 2596 | + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 2597 | + tcg_gen_ld_ptr(r_tsptr, cpu_env, | |
| 2598 | + offsetof(CPUState, tsptr)); | |
| 2599 | + tcg_gen_st_tl(cpu_T[0], r_tsptr, | |
| 2600 | + offsetof(trap_state, tstate)); | |
| 2601 | + } | |
| 2546 | 2602 | break; |
| 2547 | 2603 | case 3: // tt |
| 2548 | - gen_op_wrtt(); | |
| 2604 | + { | |
| 2605 | + TCGv r_tsptr; | |
| 2606 | + | |
| 2607 | + r_tsptr = tcg_temp_new(TCG_TYPE_PTR); | |
| 2608 | + tcg_gen_ld_ptr(r_tsptr, cpu_env, | |
| 2609 | + offsetof(CPUState, tsptr)); | |
| 2610 | + tcg_gen_st_i32(cpu_T[0], r_tsptr, | |
| 2611 | + offsetof(trap_state, tt)); | |
| 2612 | + } | |
| 2549 | 2613 | break; |
| 2550 | 2614 | case 4: // tick |
| 2551 | 2615 | { |
| ... | ... | @@ -3921,6 +3985,7 @@ void cpu_reset(CPUSPARCState *env) |
| 3921 | 3985 | env->pstate = PS_PRIV; |
| 3922 | 3986 | env->hpstate = HS_PRIV; |
| 3923 | 3987 | env->pc = 0x1fff0000000ULL; |
| 3988 | + env->tsptr = &env->ts[env->tl]; | |
| 3924 | 3989 | #else |
| 3925 | 3990 | env->pc = 0; |
| 3926 | 3991 | env->mmuregs[0] &= ~(MMU_E | MMU_NF); | ... | ... |