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