Commit 426613dbf8cd1120f9e47fb636c4c03bc1ef586c
1 parent
1b9eb036
Add missing PowerPC 64 instructions
PowerPC 64 fixes. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2530 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
8 changed files
with
326 additions
and
14 deletions
target-ppc/cpu.h
| @@ -384,6 +384,8 @@ enum { | @@ -384,6 +384,8 @@ enum { | ||
| 384 | PPC_SPE = 0x0000000100000000ULL, | 384 | PPC_SPE = 0x0000000100000000ULL, |
| 385 | /* PowerPC 2.03 SPE floating-point extension */ | 385 | /* PowerPC 2.03 SPE floating-point extension */ |
| 386 | PPC_SPEFPU = 0x0000000200000000ULL, | 386 | PPC_SPEFPU = 0x0000000200000000ULL, |
| 387 | + /* SLB management */ | ||
| 388 | + PPC_SLBI = 0x0000000400000000ULL, | ||
| 387 | }; | 389 | }; |
| 388 | 390 | ||
| 389 | /* CPU run-time flags (MMU and exception model) */ | 391 | /* CPU run-time flags (MMU and exception model) */ |
| @@ -503,11 +505,16 @@ enum { | @@ -503,11 +505,16 @@ enum { | ||
| 503 | #define PPC_INSNS_74xx (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_ALTIVEC | \ | 505 | #define PPC_INSNS_74xx (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_ALTIVEC | \ |
| 504 | PPC_MEM_TLBSYNC | PPC_TB) | 506 | PPC_MEM_TLBSYNC | PPC_TB) |
| 505 | #define PPC_FLAGS_74xx (PPC_FLAGS_MMU_32B | PPC_FLAGS_EXCP_74xx) | 507 | #define PPC_FLAGS_74xx (PPC_FLAGS_MMU_32B | PPC_FLAGS_EXCP_74xx) |
| 508 | +/* PowerPC 970 (aka G5) */ | ||
| 509 | +#define PPC_INSNS_970 (PPC_INSNS_COMMON | PPC_FLOAT_EXT | PPC_FLOAT_OPT | \ | ||
| 510 | + PPC_ALTIVEC | PPC_MEM_TLBSYNC | PPC_TB | \ | ||
| 511 | + PPC_64B | PPC_64_BRIDGE | PPC_SLBI) | ||
| 512 | +#define PPC_FLAGS_970 (PPC_FLAGS_MMU_64B | PPC_FLAGS_EXCP_970) | ||
| 506 | 513 | ||
| 507 | /* Default PowerPC will be 604/970 */ | 514 | /* Default PowerPC will be 604/970 */ |
| 508 | #define PPC_INSNS_PPC32 PPC_INSNS_604 | 515 | #define PPC_INSNS_PPC32 PPC_INSNS_604 |
| 509 | #define PPC_FLAGS_PPC32 PPC_FLAGS_604 | 516 | #define PPC_FLAGS_PPC32 PPC_FLAGS_604 |
| 510 | -#if 0 | 517 | +#if 1 |
| 511 | #define PPC_INSNS_PPC64 PPC_INSNS_970 | 518 | #define PPC_INSNS_PPC64 PPC_INSNS_970 |
| 512 | #define PPC_FLAGS_PPC64 PPC_FLAGS_970 | 519 | #define PPC_FLAGS_PPC64 PPC_FLAGS_970 |
| 513 | #endif | 520 | #endif |
| @@ -801,7 +808,7 @@ uint32_t ppc_load_xer (CPUPPCState *env); | @@ -801,7 +808,7 @@ uint32_t ppc_load_xer (CPUPPCState *env); | ||
| 801 | void ppc_store_xer (CPUPPCState *env, uint32_t value); | 808 | void ppc_store_xer (CPUPPCState *env, uint32_t value); |
| 802 | target_ulong do_load_msr (CPUPPCState *env); | 809 | target_ulong do_load_msr (CPUPPCState *env); |
| 803 | void do_store_msr (CPUPPCState *env, target_ulong value); | 810 | void do_store_msr (CPUPPCState *env, target_ulong value); |
| 804 | -void ppc_store_msr32 (CPUPPCState *env, uint32_t value); | 811 | +void ppc_store_msr_32 (CPUPPCState *env, uint32_t value); |
| 805 | 812 | ||
| 806 | void do_compute_hflags (CPUPPCState *env); | 813 | void do_compute_hflags (CPUPPCState *env); |
| 807 | 814 |
target-ppc/helper.c
| @@ -1203,9 +1203,10 @@ void do_store_msr (CPUPPCState *env, target_ulong value) | @@ -1203,9 +1203,10 @@ void do_store_msr (CPUPPCState *env, target_ulong value) | ||
| 1203 | } | 1203 | } |
| 1204 | 1204 | ||
| 1205 | #if defined(TARGET_PPC64) | 1205 | #if defined(TARGET_PPC64) |
| 1206 | -void ppc_store_msr_32 (CPUPPCState *env, target_ulong value) | 1206 | +void ppc_store_msr_32 (CPUPPCState *env, uint32_t value) |
| 1207 | { | 1207 | { |
| 1208 | - do_store_msr(env, (uint32_t)value); | 1208 | + do_store_msr(env, |
| 1209 | + (do_load_msr(env) & ~0xFFFFFFFFULL) | (value & 0xFFFFFFFF)); | ||
| 1209 | } | 1210 | } |
| 1210 | #endif | 1211 | #endif |
| 1211 | 1212 |
target-ppc/op.c
| @@ -1721,6 +1721,29 @@ PPC_OP(fctiwz) | @@ -1721,6 +1721,29 @@ PPC_OP(fctiwz) | ||
| 1721 | RETURN(); | 1721 | RETURN(); |
| 1722 | } | 1722 | } |
| 1723 | 1723 | ||
| 1724 | +#if defined(TARGET_PPC64) | ||
| 1725 | +/* fcfid - fcfid. */ | ||
| 1726 | +PPC_OP(fcfid) | ||
| 1727 | +{ | ||
| 1728 | + do_fcfid(); | ||
| 1729 | + RETURN(); | ||
| 1730 | +} | ||
| 1731 | + | ||
| 1732 | +/* fctid - fctid. */ | ||
| 1733 | +PPC_OP(fctid) | ||
| 1734 | +{ | ||
| 1735 | + do_fctid(); | ||
| 1736 | + RETURN(); | ||
| 1737 | +} | ||
| 1738 | + | ||
| 1739 | +/* fctidz - fctidz. */ | ||
| 1740 | +PPC_OP(fctidz) | ||
| 1741 | +{ | ||
| 1742 | + do_fctidz(); | ||
| 1743 | + RETURN(); | ||
| 1744 | +} | ||
| 1745 | +#endif | ||
| 1746 | + | ||
| 1724 | /*** Floating-Point compare ***/ | 1747 | /*** Floating-Point compare ***/ |
| 1725 | /* fcmpu */ | 1748 | /* fcmpu */ |
| 1726 | PPC_OP(fcmpu) | 1749 | PPC_OP(fcmpu) |
| @@ -1803,6 +1826,18 @@ void OPPROTO op_rfi_32 (void) | @@ -1803,6 +1826,18 @@ void OPPROTO op_rfi_32 (void) | ||
| 1803 | do_rfi_32(); | 1826 | do_rfi_32(); |
| 1804 | RETURN(); | 1827 | RETURN(); |
| 1805 | } | 1828 | } |
| 1829 | + | ||
| 1830 | +void OPPROTO op_rfid (void) | ||
| 1831 | +{ | ||
| 1832 | + do_rfid(); | ||
| 1833 | + RETURN(); | ||
| 1834 | +} | ||
| 1835 | + | ||
| 1836 | +void OPPROTO op_rfid_32 (void) | ||
| 1837 | +{ | ||
| 1838 | + do_rfid_32(); | ||
| 1839 | + RETURN(); | ||
| 1840 | +} | ||
| 1806 | #endif | 1841 | #endif |
| 1807 | #endif | 1842 | #endif |
| 1808 | 1843 |
target-ppc/op_helper.c
| @@ -642,6 +642,42 @@ void do_fctiwz (void) | @@ -642,6 +642,42 @@ void do_fctiwz (void) | ||
| 642 | FT0 = p.d; | 642 | FT0 = p.d; |
| 643 | } | 643 | } |
| 644 | 644 | ||
| 645 | +#if defined(TARGET_PPC64) | ||
| 646 | +void do_fcfid (void) | ||
| 647 | +{ | ||
| 648 | + union { | ||
| 649 | + double d; | ||
| 650 | + uint64_t i; | ||
| 651 | + } p; | ||
| 652 | + | ||
| 653 | + p.d = FT0; | ||
| 654 | + FT0 = int64_to_float64(p.i, &env->fp_status); | ||
| 655 | +} | ||
| 656 | + | ||
| 657 | +void do_fctid (void) | ||
| 658 | +{ | ||
| 659 | + union { | ||
| 660 | + double d; | ||
| 661 | + uint64_t i; | ||
| 662 | + } p; | ||
| 663 | + | ||
| 664 | + p.i = float64_to_int64(FT0, &env->fp_status); | ||
| 665 | + FT0 = p.d; | ||
| 666 | +} | ||
| 667 | + | ||
| 668 | +void do_fctidz (void) | ||
| 669 | +{ | ||
| 670 | + union { | ||
| 671 | + double d; | ||
| 672 | + uint64_t i; | ||
| 673 | + } p; | ||
| 674 | + | ||
| 675 | + p.i = float64_to_int64_round_to_zero(FT0, &env->fp_status); | ||
| 676 | + FT0 = p.d; | ||
| 677 | +} | ||
| 678 | + | ||
| 679 | +#endif | ||
| 680 | + | ||
| 645 | #if USE_PRECISE_EMULATION | 681 | #if USE_PRECISE_EMULATION |
| 646 | void do_fmadd (void) | 682 | void do_fmadd (void) |
| 647 | { | 683 | { |
| @@ -846,8 +882,12 @@ void do_fcmpo (void) | @@ -846,8 +882,12 @@ void do_fcmpo (void) | ||
| 846 | void do_rfi (void) | 882 | void do_rfi (void) |
| 847 | { | 883 | { |
| 848 | env->nip = (target_ulong)(env->spr[SPR_SRR0] & ~0x00000003); | 884 | env->nip = (target_ulong)(env->spr[SPR_SRR0] & ~0x00000003); |
| 849 | - T0 = (target_ulong)(env->spr[SPR_SRR1] & ~0xFFFF0000UL); | 885 | + T0 = (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL); |
| 886 | +#if defined(TARGET_PPC64) | ||
| 887 | + ppc_store_msr_32(env, T0); | ||
| 888 | +#else | ||
| 850 | do_store_msr(env, T0); | 889 | do_store_msr(env, T0); |
| 890 | +#endif | ||
| 851 | #if defined (DEBUG_OP) | 891 | #if defined (DEBUG_OP) |
| 852 | dump_rfi(); | 892 | dump_rfi(); |
| 853 | #endif | 893 | #endif |
| @@ -859,6 +899,28 @@ void do_rfi_32 (void) | @@ -859,6 +899,28 @@ void do_rfi_32 (void) | ||
| 859 | { | 899 | { |
| 860 | env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003); | 900 | env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003); |
| 861 | T0 = (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL); | 901 | T0 = (uint32_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL); |
| 902 | + ppc_store_msr_32(env, T0); | ||
| 903 | +#if defined (DEBUG_OP) | ||
| 904 | + dump_rfi(); | ||
| 905 | +#endif | ||
| 906 | + env->interrupt_request |= CPU_INTERRUPT_EXITTB; | ||
| 907 | +} | ||
| 908 | + | ||
| 909 | +void do_rfid (void) | ||
| 910 | +{ | ||
| 911 | + env->nip = (target_ulong)(env->spr[SPR_SRR0] & ~0x00000003); | ||
| 912 | + T0 = (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL); | ||
| 913 | + do_store_msr(env, T0); | ||
| 914 | +#if defined (DEBUG_OP) | ||
| 915 | + dump_rfi(); | ||
| 916 | +#endif | ||
| 917 | + env->interrupt_request |= CPU_INTERRUPT_EXITTB; | ||
| 918 | +} | ||
| 919 | + | ||
| 920 | +void do_rfid_32 (void) | ||
| 921 | +{ | ||
| 922 | + env->nip = (uint32_t)(env->spr[SPR_SRR0] & ~0x00000003); | ||
| 923 | + T0 = (uint64_t)(env->spr[SPR_SRR1] & ~0xFFFF0000UL); | ||
| 862 | do_store_msr(env, T0); | 924 | do_store_msr(env, T0); |
| 863 | #if defined (DEBUG_OP) | 925 | #if defined (DEBUG_OP) |
| 864 | dump_rfi(); | 926 | dump_rfi(); |
target-ppc/op_helper.h
| @@ -101,6 +101,11 @@ void do_fnmadd (void); | @@ -101,6 +101,11 @@ void do_fnmadd (void); | ||
| 101 | void do_fnmsub (void); | 101 | void do_fnmsub (void); |
| 102 | void do_fctiw (void); | 102 | void do_fctiw (void); |
| 103 | void do_fctiwz (void); | 103 | void do_fctiwz (void); |
| 104 | +#if defined(TARGET_PPC64) | ||
| 105 | +void do_fcfid (void); | ||
| 106 | +void do_fctid (void); | ||
| 107 | +void do_fctidz (void); | ||
| 108 | +#endif | ||
| 104 | void do_fcmpu (void); | 109 | void do_fcmpu (void); |
| 105 | void do_fcmpo (void); | 110 | void do_fcmpo (void); |
| 106 | 111 | ||
| @@ -113,6 +118,8 @@ void do_td (int flags); | @@ -113,6 +118,8 @@ void do_td (int flags); | ||
| 113 | void do_rfi (void); | 118 | void do_rfi (void); |
| 114 | #if defined(TARGET_PPC64) | 119 | #if defined(TARGET_PPC64) |
| 115 | void do_rfi_32 (void); | 120 | void do_rfi_32 (void); |
| 121 | +void do_rfid (void); | ||
| 122 | +void do_rfid_32 (void); | ||
| 116 | #endif | 123 | #endif |
| 117 | void do_tlbia (void); | 124 | void do_tlbia (void); |
| 118 | void do_tlbie (void); | 125 | void do_tlbie (void); |
target-ppc/op_mem.h
| @@ -534,6 +534,17 @@ void OPPROTO glue(op_lwarx_64, MEMSUFFIX) (void) | @@ -534,6 +534,17 @@ void OPPROTO glue(op_lwarx_64, MEMSUFFIX) (void) | ||
| 534 | RETURN(); | 534 | RETURN(); |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | +void OPPROTO glue(op_ldarx, MEMSUFFIX) (void) | ||
| 538 | +{ | ||
| 539 | + if (unlikely(T0 & 0x03)) { | ||
| 540 | + do_raise_exception(EXCP_ALIGN); | ||
| 541 | + } else { | ||
| 542 | + T1 = glue(ldq, MEMSUFFIX)((uint32_t)T0); | ||
| 543 | + regs->reserve = (uint32_t)T0; | ||
| 544 | + } | ||
| 545 | + RETURN(); | ||
| 546 | +} | ||
| 547 | + | ||
| 537 | void OPPROTO glue(op_ldarx_64, MEMSUFFIX) (void) | 548 | void OPPROTO glue(op_ldarx_64, MEMSUFFIX) (void) |
| 538 | { | 549 | { |
| 539 | if (unlikely(T0 & 0x03)) { | 550 | if (unlikely(T0 & 0x03)) { |
| @@ -569,6 +580,17 @@ void OPPROTO glue(op_lwarx_le_64, MEMSUFFIX) (void) | @@ -569,6 +580,17 @@ void OPPROTO glue(op_lwarx_le_64, MEMSUFFIX) (void) | ||
| 569 | RETURN(); | 580 | RETURN(); |
| 570 | } | 581 | } |
| 571 | 582 | ||
| 583 | +void OPPROTO glue(op_ldarx_le, MEMSUFFIX) (void) | ||
| 584 | +{ | ||
| 585 | + if (unlikely(T0 & 0x03)) { | ||
| 586 | + do_raise_exception(EXCP_ALIGN); | ||
| 587 | + } else { | ||
| 588 | + T1 = glue(ld64r, MEMSUFFIX)((uint32_t)T0); | ||
| 589 | + regs->reserve = (uint32_t)T0; | ||
| 590 | + } | ||
| 591 | + RETURN(); | ||
| 592 | +} | ||
| 593 | + | ||
| 572 | void OPPROTO glue(op_ldarx_le_64, MEMSUFFIX) (void) | 594 | void OPPROTO glue(op_ldarx_le_64, MEMSUFFIX) (void) |
| 573 | { | 595 | { |
| 574 | if (unlikely(T0 & 0x03)) { | 596 | if (unlikely(T0 & 0x03)) { |
| @@ -615,6 +637,22 @@ void OPPROTO glue(op_stwcx_64, MEMSUFFIX) (void) | @@ -615,6 +637,22 @@ void OPPROTO glue(op_stwcx_64, MEMSUFFIX) (void) | ||
| 615 | RETURN(); | 637 | RETURN(); |
| 616 | } | 638 | } |
| 617 | 639 | ||
| 640 | +void OPPROTO glue(op_stdcx, MEMSUFFIX) (void) | ||
| 641 | +{ | ||
| 642 | + if (unlikely(T0 & 0x03)) { | ||
| 643 | + do_raise_exception(EXCP_ALIGN); | ||
| 644 | + } else { | ||
| 645 | + if (unlikely(regs->reserve != (uint32_t)T0)) { | ||
| 646 | + env->crf[0] = xer_ov; | ||
| 647 | + } else { | ||
| 648 | + glue(stq, MEMSUFFIX)((uint32_t)T0, T1); | ||
| 649 | + env->crf[0] = xer_ov | 0x02; | ||
| 650 | + } | ||
| 651 | + } | ||
| 652 | + regs->reserve = -1; | ||
| 653 | + RETURN(); | ||
| 654 | +} | ||
| 655 | + | ||
| 618 | void OPPROTO glue(op_stdcx_64, MEMSUFFIX) (void) | 656 | void OPPROTO glue(op_stdcx_64, MEMSUFFIX) (void) |
| 619 | { | 657 | { |
| 620 | if (unlikely(T0 & 0x03)) { | 658 | if (unlikely(T0 & 0x03)) { |
| @@ -665,6 +703,22 @@ void OPPROTO glue(op_stwcx_le_64, MEMSUFFIX) (void) | @@ -665,6 +703,22 @@ void OPPROTO glue(op_stwcx_le_64, MEMSUFFIX) (void) | ||
| 665 | RETURN(); | 703 | RETURN(); |
| 666 | } | 704 | } |
| 667 | 705 | ||
| 706 | +void OPPROTO glue(op_stdcx_le, MEMSUFFIX) (void) | ||
| 707 | +{ | ||
| 708 | + if (unlikely(T0 & 0x03)) { | ||
| 709 | + do_raise_exception(EXCP_ALIGN); | ||
| 710 | + } else { | ||
| 711 | + if (unlikely(regs->reserve != (uint32_t)T0)) { | ||
| 712 | + env->crf[0] = xer_ov; | ||
| 713 | + } else { | ||
| 714 | + glue(st64r, MEMSUFFIX)((uint32_t)T0, T1); | ||
| 715 | + env->crf[0] = xer_ov | 0x02; | ||
| 716 | + } | ||
| 717 | + } | ||
| 718 | + regs->reserve = -1; | ||
| 719 | + RETURN(); | ||
| 720 | +} | ||
| 721 | + | ||
| 668 | void OPPROTO glue(op_stdcx_le_64, MEMSUFFIX) (void) | 722 | void OPPROTO glue(op_stdcx_le_64, MEMSUFFIX) (void) |
| 669 | { | 723 | { |
| 670 | if (unlikely(T0 & 0x03)) { | 724 | if (unlikely(T0 & 0x03)) { |
target-ppc/translate.c
| @@ -1584,6 +1584,14 @@ GEN_FLOAT_B(ctiw, 0x0E, 0x00); | @@ -1584,6 +1584,14 @@ GEN_FLOAT_B(ctiw, 0x0E, 0x00); | ||
| 1584 | GEN_FLOAT_B(ctiwz, 0x0F, 0x00); | 1584 | GEN_FLOAT_B(ctiwz, 0x0F, 0x00); |
| 1585 | /* frsp */ | 1585 | /* frsp */ |
| 1586 | GEN_FLOAT_B(rsp, 0x0C, 0x00); | 1586 | GEN_FLOAT_B(rsp, 0x0C, 0x00); |
| 1587 | +#if defined(TARGET_PPC64) | ||
| 1588 | +/* fcfid */ | ||
| 1589 | +GEN_FLOAT_B(cfid, 0x0E, 0x1A); | ||
| 1590 | +/* fctid */ | ||
| 1591 | +GEN_FLOAT_B(ctid, 0x0E, 0x19); | ||
| 1592 | +/* fctidz */ | ||
| 1593 | +GEN_FLOAT_B(ctidz, 0x0F, 0x19); | ||
| 1594 | +#endif | ||
| 1587 | 1595 | ||
| 1588 | /*** Floating-Point compare ***/ | 1596 | /*** Floating-Point compare ***/ |
| 1589 | /* fcmpo */ | 1597 | /* fcmpo */ |
| @@ -1996,8 +2004,8 @@ GEN_STS(h, 0x0C, PPC_INTEGER); | @@ -1996,8 +2004,8 @@ GEN_STS(h, 0x0C, PPC_INTEGER); | ||
| 1996 | GEN_STS(w, 0x04, PPC_INTEGER); | 2004 | GEN_STS(w, 0x04, PPC_INTEGER); |
| 1997 | #if defined(TARGET_PPC64) | 2005 | #if defined(TARGET_PPC64) |
| 1998 | OP_ST_TABLE(d); | 2006 | OP_ST_TABLE(d); |
| 1999 | -GEN_STUX(d, 0x15, 0x01, PPC_64B); | ||
| 2000 | -GEN_STX(d, 0x15, 0x00, PPC_64B); | 2007 | +GEN_STUX(d, 0x15, 0x05, PPC_64B); |
| 2008 | +GEN_STX(d, 0x15, 0x04, PPC_64B); | ||
| 2001 | GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B) | 2009 | GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B) |
| 2002 | { | 2010 | { |
| 2003 | if (Rc(ctx->opcode)) { | 2011 | if (Rc(ctx->opcode)) { |
| @@ -2358,6 +2366,62 @@ GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES) | @@ -2358,6 +2366,62 @@ GEN_HANDLER(stwcx_, 0x1F, 0x16, 0x04, 0x00000000, PPC_RES) | ||
| 2358 | op_stwcx(); | 2366 | op_stwcx(); |
| 2359 | } | 2367 | } |
| 2360 | 2368 | ||
| 2369 | +#if defined(TARGET_PPC64) | ||
| 2370 | +#define op_ldarx() (*gen_op_ldarx[ctx->mem_idx])() | ||
| 2371 | +#define op_stdcx() (*gen_op_stdcx[ctx->mem_idx])() | ||
| 2372 | +#if defined(CONFIG_USER_ONLY) | ||
| 2373 | +static GenOpFunc *gen_op_ldarx[] = { | ||
| 2374 | + &gen_op_ldarx_raw, | ||
| 2375 | + &gen_op_ldarx_le_raw, | ||
| 2376 | + &gen_op_ldarx_64_raw, | ||
| 2377 | + &gen_op_ldarx_le_64_raw, | ||
| 2378 | +}; | ||
| 2379 | +static GenOpFunc *gen_op_stdcx[] = { | ||
| 2380 | + &gen_op_stdcx_raw, | ||
| 2381 | + &gen_op_stdcx_le_raw, | ||
| 2382 | + &gen_op_stdcx_64_raw, | ||
| 2383 | + &gen_op_stdcx_le_64_raw, | ||
| 2384 | +}; | ||
| 2385 | +#else | ||
| 2386 | +static GenOpFunc *gen_op_ldarx[] = { | ||
| 2387 | + &gen_op_ldarx_user, | ||
| 2388 | + &gen_op_ldarx_le_user, | ||
| 2389 | + &gen_op_ldarx_kernel, | ||
| 2390 | + &gen_op_ldarx_le_kernel, | ||
| 2391 | + &gen_op_ldarx_64_user, | ||
| 2392 | + &gen_op_ldarx_le_64_user, | ||
| 2393 | + &gen_op_ldarx_64_kernel, | ||
| 2394 | + &gen_op_ldarx_le_64_kernel, | ||
| 2395 | +}; | ||
| 2396 | +static GenOpFunc *gen_op_stdcx[] = { | ||
| 2397 | + &gen_op_stdcx_user, | ||
| 2398 | + &gen_op_stdcx_le_user, | ||
| 2399 | + &gen_op_stdcx_kernel, | ||
| 2400 | + &gen_op_stdcx_le_kernel, | ||
| 2401 | + &gen_op_stdcx_64_user, | ||
| 2402 | + &gen_op_stdcx_le_64_user, | ||
| 2403 | + &gen_op_stdcx_64_kernel, | ||
| 2404 | + &gen_op_stdcx_le_64_kernel, | ||
| 2405 | +}; | ||
| 2406 | +#endif | ||
| 2407 | + | ||
| 2408 | +/* ldarx */ | ||
| 2409 | +GEN_HANDLER(ldarx, 0x1F, 0x14, 0x02, 0x00000001, PPC_RES) | ||
| 2410 | +{ | ||
| 2411 | + gen_addr_reg_index(ctx); | ||
| 2412 | + op_ldarx(); | ||
| 2413 | + gen_op_store_T1_gpr(rD(ctx->opcode)); | ||
| 2414 | +} | ||
| 2415 | + | ||
| 2416 | +/* stdcx. */ | ||
| 2417 | +GEN_HANDLER(stdcx_, 0x1F, 0x16, 0x06, 0x00000000, PPC_RES) | ||
| 2418 | +{ | ||
| 2419 | + gen_addr_reg_index(ctx); | ||
| 2420 | + gen_op_load_gpr_T1(rS(ctx->opcode)); | ||
| 2421 | + op_stdcx(); | ||
| 2422 | +} | ||
| 2423 | +#endif /* defined(TARGET_PPC64) */ | ||
| 2424 | + | ||
| 2361 | /* sync */ | 2425 | /* sync */ |
| 2362 | GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC) | 2426 | GEN_HANDLER(sync, 0x1F, 0x16, 0x12, 0x03FF0801, PPC_MEM_SYNC) |
| 2363 | { | 2427 | { |
| @@ -2807,6 +2871,26 @@ GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW) | @@ -2807,6 +2871,26 @@ GEN_HANDLER(rfi, 0x13, 0x12, 0x01, 0x03FF8001, PPC_FLOW) | ||
| 2807 | #endif | 2871 | #endif |
| 2808 | } | 2872 | } |
| 2809 | 2873 | ||
| 2874 | +#if defined(TARGET_PPC64) | ||
| 2875 | +GEN_HANDLER(rfid, 0x13, 0x12, 0x00, 0x03FF8001, PPC_FLOW) | ||
| 2876 | +{ | ||
| 2877 | +#if defined(CONFIG_USER_ONLY) | ||
| 2878 | + RET_PRIVOPC(ctx); | ||
| 2879 | +#else | ||
| 2880 | + /* Restore CPU state */ | ||
| 2881 | + if (unlikely(!ctx->supervisor)) { | ||
| 2882 | + RET_PRIVOPC(ctx); | ||
| 2883 | + return; | ||
| 2884 | + } | ||
| 2885 | + if (!ctx->sf_mode) | ||
| 2886 | + gen_op_rfid_32(); | ||
| 2887 | + else | ||
| 2888 | + gen_op_rfid(); | ||
| 2889 | + RET_CHG_FLOW(ctx); | ||
| 2890 | +#endif | ||
| 2891 | +} | ||
| 2892 | +#endif | ||
| 2893 | + | ||
| 2810 | /* sc */ | 2894 | /* sc */ |
| 2811 | GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW) | 2895 | GEN_HANDLER(sc, 0x11, 0xFF, 0xFF, 0x03FFFFFD, PPC_FLOW) |
| 2812 | { | 2896 | { |
| @@ -2978,6 +3062,25 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC) | @@ -2978,6 +3062,25 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC) | ||
| 2978 | } | 3062 | } |
| 2979 | 3063 | ||
| 2980 | /* mtmsr */ | 3064 | /* mtmsr */ |
| 3065 | +#if defined(TARGET_PPC64) | ||
| 3066 | +GEN_HANDLER(mtmsrd, 0x1F, 0x12, 0x05, 0x001FF801, PPC_MISC) | ||
| 3067 | +{ | ||
| 3068 | +#if defined(CONFIG_USER_ONLY) | ||
| 3069 | + RET_PRIVREG(ctx); | ||
| 3070 | +#else | ||
| 3071 | + if (unlikely(!ctx->supervisor)) { | ||
| 3072 | + RET_PRIVREG(ctx); | ||
| 3073 | + return; | ||
| 3074 | + } | ||
| 3075 | + gen_update_nip(ctx, ctx->nip); | ||
| 3076 | + gen_op_load_gpr_T0(rS(ctx->opcode)); | ||
| 3077 | + gen_op_store_msr(); | ||
| 3078 | + /* Must stop the translation as machine state (may have) changed */ | ||
| 3079 | + RET_CHG_FLOW(ctx); | ||
| 3080 | +#endif | ||
| 3081 | +} | ||
| 3082 | +#endif | ||
| 3083 | + | ||
| 2981 | GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) | 3084 | GEN_HANDLER(mtmsr, 0x1F, 0x12, 0x04, 0x001FF801, PPC_MISC) |
| 2982 | { | 3085 | { |
| 2983 | #if defined(CONFIG_USER_ONLY) | 3086 | #if defined(CONFIG_USER_ONLY) |
| @@ -3313,6 +3416,41 @@ GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC) | @@ -3313,6 +3416,41 @@ GEN_HANDLER(tlbsync, 0x1F, 0x16, 0x11, 0x03FFF801, PPC_MEM_TLBSYNC) | ||
| 3313 | #endif | 3416 | #endif |
| 3314 | } | 3417 | } |
| 3315 | 3418 | ||
| 3419 | +#if defined(TARGET_PPC64) | ||
| 3420 | +/* slbia */ | ||
| 3421 | +GEN_HANDLER(slbia, 0x1F, 0x12, 0x0F, 0x03FFFC01, PPC_SLBI) | ||
| 3422 | +{ | ||
| 3423 | +#if defined(CONFIG_USER_ONLY) | ||
| 3424 | + RET_PRIVOPC(ctx); | ||
| 3425 | +#else | ||
| 3426 | + if (unlikely(!ctx->supervisor)) { | ||
| 3427 | + if (loglevel) | ||
| 3428 | + fprintf(logfile, "%s: ! supervisor\n", __func__); | ||
| 3429 | + RET_PRIVOPC(ctx); | ||
| 3430 | + return; | ||
| 3431 | + } | ||
| 3432 | + gen_op_slbia(); | ||
| 3433 | + RET_STOP(ctx); | ||
| 3434 | +#endif | ||
| 3435 | +} | ||
| 3436 | + | ||
| 3437 | +/* slbie */ | ||
| 3438 | +GEN_HANDLER(slbie, 0x1F, 0x12, 0x0D, 0x03FF0001, PPC_SLBI) | ||
| 3439 | +{ | ||
| 3440 | +#if defined(CONFIG_USER_ONLY) | ||
| 3441 | + RET_PRIVOPC(ctx); | ||
| 3442 | +#else | ||
| 3443 | + if (unlikely(!ctx->supervisor)) { | ||
| 3444 | + RET_PRIVOPC(ctx); | ||
| 3445 | + return; | ||
| 3446 | + } | ||
| 3447 | + gen_op_load_gpr_T0(rB(ctx->opcode)); | ||
| 3448 | + gen_op_slbie(); | ||
| 3449 | + RET_STOP(ctx); | ||
| 3450 | +#endif | ||
| 3451 | +} | ||
| 3452 | +#endif | ||
| 3453 | + | ||
| 3316 | /*** External control ***/ | 3454 | /*** External control ***/ |
| 3317 | /* Optional: */ | 3455 | /* Optional: */ |
| 3318 | #define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])() | 3456 | #define op_eciwx() (*gen_op_eciwx[ctx->mem_idx])() |
target-ppc/translate_init.c
| @@ -1716,7 +1716,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | @@ -1716,7 +1716,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | ||
| 1716 | printf("%s: PVR %08x mask %08x => %08x\n", __func__, | 1716 | printf("%s: PVR %08x mask %08x => %08x\n", __func__, |
| 1717 | def->pvr, def->pvr_mask, def->pvr & def->pvr_mask); | 1717 | def->pvr, def->pvr_mask, def->pvr & def->pvr_mask); |
| 1718 | switch (def->pvr & def->pvr_mask) { | 1718 | switch (def->pvr & def->pvr_mask) { |
| 1719 | - /* Embedded PowerPC from IBM */ | 1719 | + /* Embedded PowerPC from IBM */ |
| 1720 | case CPU_PPC_401A1: /* 401 A1 family */ | 1720 | case CPU_PPC_401A1: /* 401 A1 family */ |
| 1721 | case CPU_PPC_401B2: /* 401 B2 family */ | 1721 | case CPU_PPC_401B2: /* 401 B2 family */ |
| 1722 | case CPU_PPC_401C2: /* 401 C2 family */ | 1722 | case CPU_PPC_401C2: /* 401 C2 family */ |
| @@ -1833,7 +1833,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | @@ -1833,7 +1833,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | ||
| 1833 | env->id_tlbs = 0; | 1833 | env->id_tlbs = 0; |
| 1834 | break; | 1834 | break; |
| 1835 | 1835 | ||
| 1836 | - /* Embedded PowerPC from Freescale */ | 1836 | + /* Embedded PowerPC from Freescale */ |
| 1837 | #if defined (TODO) | 1837 | #if defined (TODO) |
| 1838 | case CPU_PPC_5xx: | 1838 | case CPU_PPC_5xx: |
| 1839 | break; | 1839 | break; |
| @@ -1852,7 +1852,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | @@ -1852,7 +1852,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | ||
| 1852 | break; | 1852 | break; |
| 1853 | #endif | 1853 | #endif |
| 1854 | 1854 | ||
| 1855 | - /* XXX: Use MPC8540 PVR to implement a test PowerPC BookE target */ | 1855 | + /* XXX: Use MPC8540 PVR to implement a test PowerPC BookE target */ |
| 1856 | case CPU_PPC_e500v110: | 1856 | case CPU_PPC_e500v110: |
| 1857 | case CPU_PPC_e500v120: | 1857 | case CPU_PPC_e500v120: |
| 1858 | case CPU_PPC_e500v210: | 1858 | case CPU_PPC_e500v210: |
| @@ -1872,7 +1872,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | @@ -1872,7 +1872,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | ||
| 1872 | break; | 1872 | break; |
| 1873 | #endif | 1873 | #endif |
| 1874 | 1874 | ||
| 1875 | - /* 32 bits PowerPC */ | 1875 | + /* 32 bits PowerPC */ |
| 1876 | case CPU_PPC_601: /* PowerPC 601 */ | 1876 | case CPU_PPC_601: /* PowerPC 601 */ |
| 1877 | gen_spr_generic(env); | 1877 | gen_spr_generic(env); |
| 1878 | gen_spr_ne_601(env); | 1878 | gen_spr_ne_601(env); |
| @@ -2131,7 +2131,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | @@ -2131,7 +2131,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | ||
| 2131 | break; | 2131 | break; |
| 2132 | 2132 | ||
| 2133 | #if defined (TODO) | 2133 | #if defined (TODO) |
| 2134 | - /* G4 family */ | 2134 | + /* G4 family */ |
| 2135 | case CPU_PPC_7400: /* PowerPC 7400 */ | 2135 | case CPU_PPC_7400: /* PowerPC 7400 */ |
| 2136 | case CPU_PPC_7410C: /* PowerPC 7410 */ | 2136 | case CPU_PPC_7410C: /* PowerPC 7410 */ |
| 2137 | case CPU_PPC_7410D: | 2137 | case CPU_PPC_7410D: |
| @@ -2154,8 +2154,9 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | @@ -2154,8 +2154,9 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | ||
| 2154 | break; | 2154 | break; |
| 2155 | #endif | 2155 | #endif |
| 2156 | 2156 | ||
| 2157 | + /* 64 bits PowerPC */ | ||
| 2158 | +#if defined (TARGET_PPC64) | ||
| 2157 | #if defined (TODO) | 2159 | #if defined (TODO) |
| 2158 | - /* 64 bits PowerPC */ | ||
| 2159 | case CPU_PPC_620: /* PowerPC 620 */ | 2160 | case CPU_PPC_620: /* PowerPC 620 */ |
| 2160 | case CPU_PPC_630: /* PowerPC 630 (Power 3) */ | 2161 | case CPU_PPC_630: /* PowerPC 630 (Power 3) */ |
| 2161 | case CPU_PPC_631: /* PowerPC 631 (Power 3+) */ | 2162 | case CPU_PPC_631: /* PowerPC 631 (Power 3+) */ |
| @@ -2163,6 +2164,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | @@ -2163,6 +2164,7 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | ||
| 2163 | case CPU_PPC_POWER4P: /* Power 4+ */ | 2164 | case CPU_PPC_POWER4P: /* Power 4+ */ |
| 2164 | case CPU_PPC_POWER5: /* Power 5 */ | 2165 | case CPU_PPC_POWER5: /* Power 5 */ |
| 2165 | case CPU_PPC_POWER5P: /* Power 5+ */ | 2166 | case CPU_PPC_POWER5P: /* Power 5+ */ |
| 2167 | +#endif | ||
| 2166 | case CPU_PPC_970: /* PowerPC 970 */ | 2168 | case CPU_PPC_970: /* PowerPC 970 */ |
| 2167 | case CPU_PPC_970FX10: /* PowerPC 970 FX */ | 2169 | case CPU_PPC_970FX10: /* PowerPC 970 FX */ |
| 2168 | case CPU_PPC_970FX20: | 2170 | case CPU_PPC_970FX20: |
| @@ -2171,16 +2173,20 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | @@ -2171,16 +2173,20 @@ static void init_ppc_proc (CPUPPCState *env, ppc_def_t *def) | ||
| 2171 | case CPU_PPC_970FX31: | 2173 | case CPU_PPC_970FX31: |
| 2172 | case CPU_PPC_970MP10: /* PowerPC 970 MP */ | 2174 | case CPU_PPC_970MP10: /* PowerPC 970 MP */ |
| 2173 | case CPU_PPC_970MP11: | 2175 | case CPU_PPC_970MP11: |
| 2176 | +#if defined (TODO) | ||
| 2174 | case CPU_PPC_CELL10: /* Cell family */ | 2177 | case CPU_PPC_CELL10: /* Cell family */ |
| 2175 | case CPU_PPC_CELL20: | 2178 | case CPU_PPC_CELL20: |
| 2176 | case CPU_PPC_CELL30: | 2179 | case CPU_PPC_CELL30: |
| 2177 | case CPU_PPC_CELL31: | 2180 | case CPU_PPC_CELL31: |
| 2181 | +#endif | ||
| 2182 | +#if defined (TODO) | ||
| 2178 | case CPU_PPC_RS64: /* Apache (RS64/A35) */ | 2183 | case CPU_PPC_RS64: /* Apache (RS64/A35) */ |
| 2179 | case CPU_PPC_RS64II: /* NorthStar (RS64-II/A50) */ | 2184 | case CPU_PPC_RS64II: /* NorthStar (RS64-II/A50) */ |
| 2180 | case CPU_PPC_RS64III: /* Pulsar (RS64-III) */ | 2185 | case CPU_PPC_RS64III: /* Pulsar (RS64-III) */ |
| 2181 | case CPU_PPC_RS64IV: /* IceStar/IStar/SStar (RS64-IV) */ | 2186 | case CPU_PPC_RS64IV: /* IceStar/IStar/SStar (RS64-IV) */ |
| 2182 | - break; | ||
| 2183 | #endif | 2187 | #endif |
| 2188 | + break; | ||
| 2189 | +#endif /* defined (TARGET_PPC64) */ | ||
| 2184 | 2190 | ||
| 2185 | #if defined (TODO) | 2191 | #if defined (TODO) |
| 2186 | /* POWER */ | 2192 | /* POWER */ |
| @@ -3412,6 +3418,7 @@ static ppc_def_t ppc_defs[] = | @@ -3412,6 +3418,7 @@ static ppc_def_t ppc_defs[] = | ||
| 3412 | }, | 3418 | }, |
| 3413 | #endif | 3419 | #endif |
| 3414 | /* 64 bits PowerPC */ | 3420 | /* 64 bits PowerPC */ |
| 3421 | +#if defined (TARGET_PPC64) | ||
| 3415 | #if defined (TODO) | 3422 | #if defined (TODO) |
| 3416 | /* PowerPC 620 */ | 3423 | /* PowerPC 620 */ |
| 3417 | { | 3424 | { |
| @@ -3650,6 +3657,7 @@ static ppc_def_t ppc_defs[] = | @@ -3650,6 +3657,7 @@ static ppc_def_t ppc_defs[] = | ||
| 3650 | .msr_mask = xxx, | 3657 | .msr_mask = xxx, |
| 3651 | }, | 3658 | }, |
| 3652 | #endif | 3659 | #endif |
| 3660 | +#endif /* defined (TARGET_PPC64) */ | ||
| 3653 | #if defined (TODO) | 3661 | #if defined (TODO) |
| 3654 | /* POWER2 */ | 3662 | /* POWER2 */ |
| 3655 | { | 3663 | { |