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,7 +680,7 @@ void cpu_loop (CPUSPARCState *env) | ||
680 | if (trapnr == TT_DFAULT) | 680 | if (trapnr == TT_DFAULT) |
681 | info._sifields._sigfault._addr = env->dmmuregs[4]; | 681 | info._sifields._sigfault._addr = env->dmmuregs[4]; |
682 | else | 682 | else |
683 | - info._sifields._sigfault._addr = env->tpc[env->tl]; | 683 | + info._sifields._sigfault._addr = env->tsptr->tpc; |
684 | queue_signal(info.si_signo, &info); | 684 | queue_signal(info.si_signo, &info); |
685 | } | 685 | } |
686 | break; | 686 | break; |
target-sparc/cpu.h
@@ -169,6 +169,12 @@ | @@ -169,6 +169,12 @@ | ||
169 | #define NB_MMU_MODES 2 | 169 | #define NB_MMU_MODES 2 |
170 | #else | 170 | #else |
171 | #define NB_MMU_MODES 3 | 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 | #endif | 178 | #endif |
173 | 179 | ||
174 | typedef struct CPUSPARCState { | 180 | typedef struct CPUSPARCState { |
@@ -234,10 +240,8 @@ typedef struct CPUSPARCState { | @@ -234,10 +240,8 @@ typedef struct CPUSPARCState { | ||
234 | #if defined(TARGET_SPARC64) | 240 | #if defined(TARGET_SPARC64) |
235 | #define MAXTL 4 | 241 | #define MAXTL 4 |
236 | uint64_t t0, t1, t2; | 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 | uint32_t xcc; /* Extended integer condition codes */ | 245 | uint32_t xcc; /* Extended integer condition codes */ |
242 | uint32_t asi; | 246 | uint32_t asi; |
243 | uint32_t pstate; | 247 | uint32_t pstate; |
target-sparc/op.c
@@ -805,46 +805,6 @@ void OPPROTO op_wrccr(void) | @@ -805,46 +805,6 @@ void OPPROTO op_wrccr(void) | ||
805 | PUT_CCR(env, T0); | 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 | // CWP handling is reversed in V9, but we still use the V8 register | 808 | // CWP handling is reversed in V9, but we still use the V8 register |
849 | // order. | 809 | // order. |
850 | void OPPROTO op_rdcwp(void) | 810 | void OPPROTO op_rdcwp(void) |
target-sparc/op_helper.c
@@ -1675,23 +1675,25 @@ void helper_wrpstate(target_ulong new_state) | @@ -1675,23 +1675,25 @@ void helper_wrpstate(target_ulong new_state) | ||
1675 | void helper_done(void) | 1675 | void helper_done(void) |
1676 | { | 1676 | { |
1677 | env->tl--; | 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 | void helper_retry(void) | 1687 | void helper_retry(void) |
1687 | { | 1688 | { |
1688 | env->tl--; | 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 | #endif | 1698 | #endif |
1697 | 1699 | ||
@@ -1813,11 +1815,12 @@ void do_interrupt(int intno) | @@ -1813,11 +1815,12 @@ void do_interrupt(int intno) | ||
1813 | return; | 1815 | return; |
1814 | } | 1816 | } |
1815 | #endif | 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 | change_pstate(PS_PEF | PS_PRIV | PS_AG); | 1824 | change_pstate(PS_PEF | PS_PRIV | PS_AG); |
1822 | 1825 | ||
1823 | if (intno == TT_CLRWIN) | 1826 | if (intno == TT_CLRWIN) |
@@ -1835,6 +1838,7 @@ void do_interrupt(int intno) | @@ -1835,6 +1838,7 @@ void do_interrupt(int intno) | ||
1835 | if (env->tl != MAXTL) | 1838 | if (env->tl != MAXTL) |
1836 | env->tl++; | 1839 | env->tl++; |
1837 | } | 1840 | } |
1841 | + env->tsptr = &env->ts[env->tl]; | ||
1838 | env->pc = env->tbr; | 1842 | env->pc = env->tbr; |
1839 | env->npc = env->pc + 4; | 1843 | env->npc = env->pc + 4; |
1840 | env->exception_index = 0; | 1844 | env->exception_index = 0; |
target-sparc/translate.c
@@ -1386,16 +1386,48 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -1386,16 +1386,48 @@ static void disas_sparc_insn(DisasContext * dc) | ||
1386 | rs1 = GET_FIELD(insn, 13, 17); | 1386 | rs1 = GET_FIELD(insn, 13, 17); |
1387 | switch (rs1) { | 1387 | switch (rs1) { |
1388 | case 0: // tpc | 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 | break; | 1398 | break; |
1391 | case 1: // tnpc | 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 | break; | 1409 | break; |
1394 | case 2: // tstate | 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 | break; | 1420 | break; |
1397 | case 3: // tt | 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 | break; | 1431 | break; |
1400 | case 4: // tick | 1432 | case 4: // tick |
1401 | { | 1433 | { |
@@ -2536,16 +2568,48 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -2536,16 +2568,48 @@ static void disas_sparc_insn(DisasContext * dc) | ||
2536 | #ifdef TARGET_SPARC64 | 2568 | #ifdef TARGET_SPARC64 |
2537 | switch (rd) { | 2569 | switch (rd) { |
2538 | case 0: // tpc | 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 | break; | 2580 | break; |
2541 | case 1: // tnpc | 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 | break; | 2591 | break; |
2544 | case 2: // tstate | 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 | break; | 2602 | break; |
2547 | case 3: // tt | 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 | break; | 2613 | break; |
2550 | case 4: // tick | 2614 | case 4: // tick |
2551 | { | 2615 | { |
@@ -3921,6 +3985,7 @@ void cpu_reset(CPUSPARCState *env) | @@ -3921,6 +3985,7 @@ void cpu_reset(CPUSPARCState *env) | ||
3921 | env->pstate = PS_PRIV; | 3985 | env->pstate = PS_PRIV; |
3922 | env->hpstate = HS_PRIV; | 3986 | env->hpstate = HS_PRIV; |
3923 | env->pc = 0x1fff0000000ULL; | 3987 | env->pc = 0x1fff0000000ULL; |
3988 | + env->tsptr = &env->ts[env->tl]; | ||
3924 | #else | 3989 | #else |
3925 | env->pc = 0; | 3990 | env->pc = 0; |
3926 | env->mmuregs[0] &= ~(MMU_E | MMU_NF); | 3991 | env->mmuregs[0] &= ~(MMU_E | MMU_NF); |