Commit 3cd7d1ddbba67a79854ea258cdf3a07eb0ad5136
1 parent
a73666f6
Allow use of SPE extension by all PowerPC targets,
adding gprh registers to store GPR MSBs when GPRs are 32 bits. Remove not-needed-anymore ppcemb-linux-user target. Keep ppcemb-softmmu target, which provides 1kB pages support and 36 bits physical address space. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3628 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
11 changed files
with
149 additions
and
86 deletions
configure
| ... | ... | @@ -520,7 +520,7 @@ if test -z "$target_list" ; then |
| 520 | 520 | fi |
| 521 | 521 | # the following are Linux specific |
| 522 | 522 | if [ "$linux_user" = "yes" ] ; then |
| 523 | - target_list="i386-linux-user arm-linux-user armeb-linux-user sparc-linux-user sparc64-linux-user sparc32plus-linux-user mips-linux-user mipsel-linux-user m68k-linux-user alpha-linux-user sh4-linux-user ppc-linux-user ppcemb-linux-user ppc64-linux-user ppc64abi32-linux-user x86_64-linux-user cris-linux-user $target_list" | |
| 523 | + target_list="i386-linux-user arm-linux-user armeb-linux-user sparc-linux-user sparc64-linux-user sparc32plus-linux-user mips-linux-user mipsel-linux-user m68k-linux-user alpha-linux-user sh4-linux-user ppc-linux-user ppc64-linux-user ppc64abi32-linux-user x86_64-linux-user cris-linux-user $target_list" | |
| 524 | 524 | fi |
| 525 | 525 | # the following are Darwin specific |
| 526 | 526 | if [ "$darwin_user" = "yes" ] ; then | ... | ... |
darwin-user/main.c
| ... | ... | @@ -357,7 +357,6 @@ void cpu_loop(CPUPPCState *env) |
| 357 | 357 | case POWERPC_EXCP_DEBUG: /* Debug interrupt */ |
| 358 | 358 | gdb_handlesig (env, SIGTRAP); |
| 359 | 359 | break; |
| 360 | -#if defined(TARGET_PPCEMB) | |
| 361 | 360 | case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */ |
| 362 | 361 | EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n"); |
| 363 | 362 | info.si_signo = SIGILL; |
| ... | ... | @@ -383,7 +382,6 @@ void cpu_loop(CPUPPCState *env) |
| 383 | 382 | cpu_abort(env, "Doorbell critical interrupt while in user mode. " |
| 384 | 383 | "Aborting\n"); |
| 385 | 384 | break; |
| 386 | -#endif /* defined(TARGET_PPCEMB) */ | |
| 387 | 385 | case POWERPC_EXCP_RESET: /* System reset exception */ |
| 388 | 386 | cpu_abort(env, "Reset interrupt while in user mode. " |
| 389 | 387 | "Aborting\n"); | ... | ... |
linux-user/main.c
| ... | ... | @@ -976,7 +976,6 @@ void cpu_loop(CPUPPCState *env) |
| 976 | 976 | } |
| 977 | 977 | } |
| 978 | 978 | break; |
| 979 | -#if defined(TARGET_PPCEMB) | |
| 980 | 979 | case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavail. */ |
| 981 | 980 | EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n"); |
| 982 | 981 | info.si_signo = TARGET_SIGILL; |
| ... | ... | @@ -1006,7 +1005,6 @@ void cpu_loop(CPUPPCState *env) |
| 1006 | 1005 | cpu_abort(env, "Reset interrupt while in user mode. " |
| 1007 | 1006 | "Aborting\n"); |
| 1008 | 1007 | break; |
| 1009 | -#endif /* defined(TARGET_PPCEMB) */ | |
| 1010 | 1008 | #if defined(TARGET_PPC64) && !defined(TARGET_ABI32) /* PowerPC 64 */ |
| 1011 | 1009 | case POWERPC_EXCP_DSEG: /* Data segment exception */ |
| 1012 | 1010 | cpu_abort(env, "Data segment exception while in user mode. " | ... | ... |
target-ppc/cpu.h
| ... | ... | @@ -24,46 +24,51 @@ |
| 24 | 24 | #include <inttypes.h> |
| 25 | 25 | |
| 26 | 26 | #if defined (TARGET_PPC64) |
| 27 | +/* PowerPC 64 definitions */ | |
| 27 | 28 | typedef uint64_t ppc_gpr_t; |
| 28 | 29 | #define TARGET_GPR_BITS 64 |
| 29 | 30 | #define TARGET_LONG_BITS 64 |
| 30 | 31 | #define REGX "%016" PRIx64 |
| 31 | 32 | #define TARGET_PAGE_BITS 12 |
| 32 | -#elif defined(TARGET_PPCEMB) | |
| 33 | -/* BookE have 36 bits physical address space */ | |
| 34 | -#define TARGET_PHYS_ADDR_BITS 64 | |
| 35 | -/* GPR are 64 bits: used by vector extension */ | |
| 36 | -typedef uint64_t ppc_gpr_t; | |
| 37 | -#define TARGET_GPR_BITS 64 | |
| 38 | -#define TARGET_LONG_BITS 32 | |
| 39 | -#define REGX "%016" PRIx64 | |
| 40 | -#if defined(CONFIG_USER_ONLY) | |
| 41 | -/* It looks like a lot of Linux programs assume page size | |
| 42 | - * is 4kB long. This is evil, but we have to deal with it... | |
| 43 | - */ | |
| 44 | -#define TARGET_PAGE_BITS 12 | |
| 45 | -#else | |
| 46 | -/* Pages can be 1 kB small */ | |
| 47 | -#define TARGET_PAGE_BITS 10 | |
| 48 | -#endif | |
| 49 | -#else | |
| 33 | + | |
| 34 | +#else /* defined (TARGET_PPC64) */ | |
| 35 | +/* PowerPC 32 definitions */ | |
| 50 | 36 | #if (HOST_LONG_BITS >= 64) |
| 51 | 37 | /* When using 64 bits temporary registers, |
| 52 | 38 | * we can use 64 bits GPR with no extra cost |
| 53 | - * It's even an optimization as it will prevent | |
| 39 | + * It's even an optimization as this will prevent | |
| 54 | 40 | * the compiler to do unuseful masking in the micro-ops. |
| 55 | 41 | */ |
| 56 | 42 | typedef uint64_t ppc_gpr_t; |
| 57 | 43 | #define TARGET_GPR_BITS 64 |
| 58 | 44 | #define REGX "%08" PRIx64 |
| 59 | -#else | |
| 45 | +#else /* (HOST_LONG_BITS >= 64) */ | |
| 60 | 46 | typedef uint32_t ppc_gpr_t; |
| 61 | 47 | #define TARGET_GPR_BITS 32 |
| 62 | 48 | #define REGX "%08" PRIx32 |
| 63 | -#endif | |
| 49 | +#endif /* (HOST_LONG_BITS >= 64) */ | |
| 50 | + | |
| 64 | 51 | #define TARGET_LONG_BITS 32 |
| 52 | + | |
| 53 | +#if defined(TARGET_PPCEMB) | |
| 54 | +/* Specific definitions for PowerPC embedded */ | |
| 55 | +/* BookE have 36 bits physical address space */ | |
| 56 | +#define TARGET_PHYS_ADDR_BITS 64 | |
| 57 | +#if defined(CONFIG_USER_ONLY) | |
| 58 | +/* It looks like a lot of Linux programs assume page size | |
| 59 | + * is 4kB long. This is evil, but we have to deal with it... | |
| 60 | + */ | |
| 65 | 61 | #define TARGET_PAGE_BITS 12 |
| 66 | -#endif | |
| 62 | +#else /* defined(CONFIG_USER_ONLY) */ | |
| 63 | +/* Pages can be 1 kB small */ | |
| 64 | +#define TARGET_PAGE_BITS 10 | |
| 65 | +#endif /* defined(CONFIG_USER_ONLY) */ | |
| 66 | +#else /* defined(TARGET_PPCEMB) */ | |
| 67 | +/* "standard" PowerPC 32 definitions */ | |
| 68 | +#define TARGET_PAGE_BITS 12 | |
| 69 | +#endif /* defined(TARGET_PPCEMB) */ | |
| 70 | + | |
| 71 | +#endif /* defined (TARGET_PPC64) */ | |
| 67 | 72 | |
| 68 | 73 | #include "cpu-defs.h" |
| 69 | 74 | |
| ... | ... | @@ -166,14 +171,12 @@ enum { |
| 166 | 171 | POWERPC_EXCP_ITLB = 14, /* Instruction TLB error */ |
| 167 | 172 | POWERPC_EXCP_DEBUG = 15, /* Debug interrupt */ |
| 168 | 173 | /* Vectors 16 to 31 are reserved */ |
| 169 | -#if defined(TARGET_PPCEMB) | |
| 170 | 174 | POWERPC_EXCP_SPEU = 32, /* SPE/embedded floating-point unavailable */ |
| 171 | 175 | POWERPC_EXCP_EFPDI = 33, /* Embedded floating-point data interrupt */ |
| 172 | 176 | POWERPC_EXCP_EFPRI = 34, /* Embedded floating-point round interrupt */ |
| 173 | 177 | POWERPC_EXCP_EPERFM = 35, /* Embedded performance monitor interrupt */ |
| 174 | 178 | POWERPC_EXCP_DOORI = 36, /* Embedded doorbell interrupt */ |
| 175 | 179 | POWERPC_EXCP_DOORCI = 37, /* Embedded doorbell critical interrupt */ |
| 176 | -#endif /* defined(TARGET_PPCEMB) */ | |
| 177 | 180 | /* Vectors 38 to 63 are reserved */ |
| 178 | 181 | /* Exceptions defined in the PowerPC server specification */ |
| 179 | 182 | POWERPC_EXCP_RESET = 64, /* System reset exception */ |
| ... | ... | @@ -527,6 +530,10 @@ struct CPUPPCState { |
| 527 | 530 | |
| 528 | 531 | /* general purpose registers */ |
| 529 | 532 | ppc_gpr_t gpr[32]; |
| 533 | +#if TARGET_GPR_BITS < 64 | |
| 534 | + /* Storage for GPR MSB, used by the SPE extension */ | |
| 535 | + ppc_gpr_t gprh[32]; | |
| 536 | +#endif | |
| 530 | 537 | /* LR */ |
| 531 | 538 | target_ulong lr; |
| 532 | 539 | /* CTR */ |
| ... | ... | @@ -597,12 +604,10 @@ struct CPUPPCState { |
| 597 | 604 | /* Altivec registers */ |
| 598 | 605 | ppc_avr_t avr[32]; |
| 599 | 606 | uint32_t vscr; |
| 600 | -#if defined(TARGET_PPCEMB) | |
| 601 | 607 | /* SPE registers */ |
| 602 | 608 | ppc_gpr_t spe_acc; |
| 603 | 609 | float_status spe_status; |
| 604 | 610 | uint32_t spe_fscr; |
| 605 | -#endif | |
| 606 | 611 | |
| 607 | 612 | /* Internal devices resources */ |
| 608 | 613 | /* Time base and decrementer */ | ... | ... |
target-ppc/helper.c
| ... | ... | @@ -2395,7 +2395,6 @@ static always_inline void powerpc_excp (CPUState *env, |
| 2395 | 2395 | /* XXX: TODO */ |
| 2396 | 2396 | cpu_abort(env, "Debug exception is not implemented yet !\n"); |
| 2397 | 2397 | goto store_next; |
| 2398 | -#if defined(TARGET_PPCEMB) | |
| 2399 | 2398 | case POWERPC_EXCP_SPEU: /* SPE/embedded floating-point unavailable */ |
| 2400 | 2399 | new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */ |
| 2401 | 2400 | goto store_current; |
| ... | ... | @@ -2433,7 +2432,6 @@ static always_inline void powerpc_excp (CPUState *env, |
| 2433 | 2432 | cpu_abort(env, "Embedded doorbell critical interrupt " |
| 2434 | 2433 | "is not implemented yet !\n"); |
| 2435 | 2434 | goto store_next; |
| 2436 | -#endif /* defined(TARGET_PPCEMB) */ | |
| 2437 | 2435 | case POWERPC_EXCP_RESET: /* System reset exception */ |
| 2438 | 2436 | new_msr &= ~((target_ulong)1 << MSR_RI); |
| 2439 | 2437 | #if defined(TARGET_PPC64H) |
| ... | ... | @@ -2833,26 +2831,11 @@ void ppc_hw_interrupt (CPUPPCState *env) |
| 2833 | 2831 | powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT); |
| 2834 | 2832 | return; |
| 2835 | 2833 | } |
| 2836 | -#if defined(TARGET_PPCEMB) | |
| 2837 | 2834 | if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) { |
| 2838 | 2835 | env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL); |
| 2839 | 2836 | powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI); |
| 2840 | 2837 | return; |
| 2841 | 2838 | } |
| 2842 | -#endif | |
| 2843 | -#if defined(TARGET_PPCEMB) | |
| 2844 | - /* External interrupt */ | |
| 2845 | - if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) { | |
| 2846 | - /* Taking an external interrupt does not clear the external | |
| 2847 | - * interrupt status | |
| 2848 | - */ | |
| 2849 | -#if 0 | |
| 2850 | - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT); | |
| 2851 | -#endif | |
| 2852 | - powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL); | |
| 2853 | - return; | |
| 2854 | - } | |
| 2855 | -#endif | |
| 2856 | 2839 | /* Fixed interval timer on embedded PowerPC */ |
| 2857 | 2840 | if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) { |
| 2858 | 2841 | env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT); |
| ... | ... | @@ -2871,7 +2854,6 @@ void ppc_hw_interrupt (CPUPPCState *env) |
| 2871 | 2854 | powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR); |
| 2872 | 2855 | return; |
| 2873 | 2856 | } |
| 2874 | -#if !defined(TARGET_PPCEMB) | |
| 2875 | 2857 | /* External interrupt */ |
| 2876 | 2858 | if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) { |
| 2877 | 2859 | /* Taking an external interrupt does not clear the external |
| ... | ... | @@ -2883,14 +2865,11 @@ void ppc_hw_interrupt (CPUPPCState *env) |
| 2883 | 2865 | powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL); |
| 2884 | 2866 | return; |
| 2885 | 2867 | } |
| 2886 | -#endif | |
| 2887 | -#if defined(TARGET_PPCEMB) | |
| 2888 | 2868 | if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) { |
| 2889 | 2869 | env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL); |
| 2890 | 2870 | powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI); |
| 2891 | 2871 | return; |
| 2892 | 2872 | } |
| 2893 | -#endif | |
| 2894 | 2873 | if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) { |
| 2895 | 2874 | env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM); |
| 2896 | 2875 | powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM); | ... | ... |
target-ppc/op.c
| ... | ... | @@ -2720,7 +2720,6 @@ void OPPROTO op_store_booke_tsr (void) |
| 2720 | 2720 | } |
| 2721 | 2721 | #endif /* !defined(CONFIG_USER_ONLY) */ |
| 2722 | 2722 | |
| 2723 | -#if defined(TARGET_PPCEMB) | |
| 2724 | 2723 | /* SPE extension */ |
| 2725 | 2724 | void OPPROTO op_splatw_T1_64 (void) |
| 2726 | 2725 | { |
| ... | ... | @@ -3439,4 +3438,3 @@ void OPPROTO op_efdtsteq (void) |
| 3439 | 3438 | T0 = _do_efdtsteq(T0_64, T1_64); |
| 3440 | 3439 | RETURN(); |
| 3441 | 3440 | } |
| 3442 | -#endif /* defined(TARGET_PPCEMB) */ | ... | ... |
target-ppc/op_helper.c
| ... | ... | @@ -1853,7 +1853,6 @@ void do_440_dlmzb (void) |
| 1853 | 1853 | T0 = i; |
| 1854 | 1854 | } |
| 1855 | 1855 | |
| 1856 | -#if defined(TARGET_PPCEMB) | |
| 1857 | 1856 | /* SPE extension helpers */ |
| 1858 | 1857 | /* Use a table to make this quicker */ |
| 1859 | 1858 | static uint8_t hbrev[16] = { |
| ... | ... | @@ -1872,16 +1871,16 @@ static always_inline uint32_t word_reverse (uint32_t val) |
| 1872 | 1871 | (byte_reverse(val >> 8) << 16) | (byte_reverse(val) << 24); |
| 1873 | 1872 | } |
| 1874 | 1873 | |
| 1875 | -#define MASKBITS 16 // Random value - to be fixed | |
| 1874 | +#define MASKBITS 16 // Random value - to be fixed (implementation dependant) | |
| 1876 | 1875 | void do_brinc (void) |
| 1877 | 1876 | { |
| 1878 | 1877 | uint32_t a, b, d, mask; |
| 1879 | 1878 | |
| 1880 | - mask = UINT32_MAX >> MASKBITS; | |
| 1881 | - b = T1_64 & mask; | |
| 1882 | - a = T0_64 & mask; | |
| 1883 | - d = word_reverse(1 + word_reverse(a | ~mask)); | |
| 1884 | - T0_64 = (T0_64 & ~mask) | (d & mask); | |
| 1879 | + mask = UINT32_MAX >> (32 - MASKBITS); | |
| 1880 | + a = T0 & mask; | |
| 1881 | + b = T1 & mask; | |
| 1882 | + d = word_reverse(1 + word_reverse(a | ~b)); | |
| 1883 | + T0 = (T0 & ~mask) | (d & b); | |
| 1885 | 1884 | } |
| 1886 | 1885 | |
| 1887 | 1886 | #define DO_SPE_OP2(name) \ |
| ... | ... | @@ -2713,7 +2712,6 @@ DO_SPE_OP1(fsctuiz); |
| 2713 | 2712 | DO_SPE_OP1(fsctsf); |
| 2714 | 2713 | /* evfsctuf */ |
| 2715 | 2714 | DO_SPE_OP1(fsctuf); |
| 2716 | -#endif /* defined(TARGET_PPCEMB) */ | |
| 2717 | 2715 | |
| 2718 | 2716 | /*****************************************************************************/ |
| 2719 | 2717 | /* Softmmu support */ | ... | ... |
target-ppc/op_helper.h
| ... | ... | @@ -205,7 +205,6 @@ void do_load_403_pb (int num); |
| 205 | 205 | void do_store_403_pb (int num); |
| 206 | 206 | #endif |
| 207 | 207 | |
| 208 | -#if defined(TARGET_PPCEMB) | |
| 209 | 208 | /* SPE extension helpers */ |
| 210 | 209 | void do_brinc (void); |
| 211 | 210 | /* Fixed-point vector helpers */ |
| ... | ... | @@ -286,9 +285,7 @@ void do_evfsctsi (void); |
| 286 | 285 | void do_evfsctui (void); |
| 287 | 286 | void do_evfsctsiz (void); |
| 288 | 287 | void do_evfsctuiz (void); |
| 289 | -#endif /* defined(TARGET_PPCEMB) */ | |
| 290 | 288 | |
| 291 | -#if defined(TARGET_PPCEMB) | |
| 292 | 289 | /* SPE extension */ |
| 293 | 290 | /* Single precision floating-point helpers */ |
| 294 | 291 | static always_inline uint32_t _do_efsabs (uint32_t val) |
| ... | ... | @@ -409,5 +406,4 @@ static always_inline int _do_efdtsteq (uint64_t op1, uint64_t op2) |
| 409 | 406 | u2.u = op2; |
| 410 | 407 | return float64_eq(u1.f, u2.f, &env->spe_status) ? 1 : 0; |
| 411 | 408 | } |
| 412 | -#endif /* defined(TARGET_PPCEMB) */ | |
| 413 | 409 | #endif | ... | ... |
target-ppc/op_mem.h
| ... | ... | @@ -37,7 +37,6 @@ static always_inline uint32_t glue(ld32r, MEMSUFFIX) (target_ulong EA) |
| 37 | 37 | ((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24); |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | -#if defined(TARGET_PPC64) || defined(TARGET_PPCEMB) | |
| 41 | 40 | static always_inline uint64_t glue(ld64r, MEMSUFFIX) (target_ulong EA) |
| 42 | 41 | { |
| 43 | 42 | uint64_t tmp = glue(ldq, MEMSUFFIX)(EA); |
| ... | ... | @@ -50,7 +49,6 @@ static always_inline uint64_t glue(ld64r, MEMSUFFIX) (target_ulong EA) |
| 50 | 49 | ((tmp & 0x000000000000FF00ULL) << 40) | |
| 51 | 50 | ((tmp & 0x00000000000000FFULL) << 54); |
| 52 | 51 | } |
| 53 | -#endif | |
| 54 | 52 | |
| 55 | 53 | #if defined(TARGET_PPC64) |
| 56 | 54 | static always_inline int64_t glue(ldsl, MEMSUFFIX) (target_ulong EA) |
| ... | ... | @@ -81,7 +79,6 @@ static always_inline void glue(st32r, MEMSUFFIX) (target_ulong EA, |
| 81 | 79 | glue(stl, MEMSUFFIX)(EA, tmp); |
| 82 | 80 | } |
| 83 | 81 | |
| 84 | -#if defined(TARGET_PPC64) || defined(TARGET_PPCEMB) | |
| 85 | 82 | static always_inline void glue(st64r, MEMSUFFIX) (target_ulong EA, |
| 86 | 83 | uint64_t data) |
| 87 | 84 | { |
| ... | ... | @@ -95,7 +92,6 @@ static always_inline void glue(st64r, MEMSUFFIX) (target_ulong EA, |
| 95 | 92 | ((data & 0x00000000000000FFULL) << 56); |
| 96 | 93 | glue(stq, MEMSUFFIX)(EA, tmp); |
| 97 | 94 | } |
| 98 | -#endif | |
| 99 | 95 | |
| 100 | 96 | /*** Integer load ***/ |
| 101 | 97 | #define PPC_LD_OP(name, op) \ |
| ... | ... | @@ -1123,7 +1119,6 @@ void OPPROTO glue(op_vr_stvx_le_64, MEMSUFFIX) (void) |
| 1123 | 1119 | #undef VR_DWORD0 |
| 1124 | 1120 | #undef VR_DWORD1 |
| 1125 | 1121 | |
| 1126 | -#if defined(TARGET_PPCEMB) | |
| 1127 | 1122 | /* SPE extension */ |
| 1128 | 1123 | #define _PPC_SPE_LD_OP(name, op) \ |
| 1129 | 1124 | void OPPROTO glue(glue(op_spe_l, name), MEMSUFFIX) (void) \ |
| ... | ... | @@ -1385,6 +1380,5 @@ uint64_t glue(spe_lwhsplat_le, MEMSUFFIX) (target_ulong EA) |
| 1385 | 1380 | return ret; |
| 1386 | 1381 | } |
| 1387 | 1382 | PPC_SPE_LD_OP(whsplat_le, spe_lwhsplat_le); |
| 1388 | -#endif /* defined(TARGET_PPCEMB) */ | |
| 1389 | 1383 | |
| 1390 | 1384 | #undef MEMSUFFIX | ... | ... |
target-ppc/op_template.h
| ... | ... | @@ -58,23 +58,23 @@ void OPPROTO glue(op_store_T2_gpr_gpr, REG) (void) |
| 58 | 58 | #endif |
| 59 | 59 | |
| 60 | 60 | /* General purpose registers containing vector operands moves */ |
| 61 | -#if defined(TARGET_PPCEMB) | |
| 61 | +#if TARGET_GPR_BITS < 64 | |
| 62 | 62 | void OPPROTO glue(op_load_gpr64_T0_gpr, REG) (void) |
| 63 | 63 | { |
| 64 | - T0_64 = env->gpr[REG]; | |
| 64 | + T0_64 = (uint64_t)env->gpr[REG] | ((uint64_t)env->gprh[REG] << 32); | |
| 65 | 65 | RETURN(); |
| 66 | 66 | } |
| 67 | 67 | |
| 68 | 68 | void OPPROTO glue(op_load_gpr64_T1_gpr, REG) (void) |
| 69 | 69 | { |
| 70 | - T1_64 = env->gpr[REG]; | |
| 70 | + T1_64 = (uint64_t)env->gpr[REG] | ((uint64_t)env->gprh[REG] << 32); | |
| 71 | 71 | RETURN(); |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | #if 0 // unused |
| 75 | 75 | void OPPROTO glue(op_load_gpr64_T2_gpr, REG) (void) |
| 76 | 76 | { |
| 77 | - T2_64 = env->gpr[REG]; | |
| 77 | + T2_64 = (uint64_t)env->gpr[REG] | ((uint64_t)env->gprh[REG] << 32); | |
| 78 | 78 | RETURN(); |
| 79 | 79 | } |
| 80 | 80 | #endif |
| ... | ... | @@ -82,12 +82,14 @@ void OPPROTO glue(op_load_gpr64_T2_gpr, REG) (void) |
| 82 | 82 | void OPPROTO glue(op_store_T0_gpr64_gpr, REG) (void) |
| 83 | 83 | { |
| 84 | 84 | env->gpr[REG] = T0_64; |
| 85 | + env->gprh[REG] = T0_64 >> 32; | |
| 85 | 86 | RETURN(); |
| 86 | 87 | } |
| 87 | 88 | |
| 88 | 89 | void OPPROTO glue(op_store_T1_gpr64_gpr, REG) (void) |
| 89 | 90 | { |
| 90 | 91 | env->gpr[REG] = T1_64; |
| 92 | + env->gprh[REG] = T1_64 >> 32; | |
| 91 | 93 | RETURN(); |
| 92 | 94 | } |
| 93 | 95 | |
| ... | ... | @@ -95,10 +97,11 @@ void OPPROTO glue(op_store_T1_gpr64_gpr, REG) (void) |
| 95 | 97 | void OPPROTO glue(op_store_T2_gpr64_gpr, REG) (void) |
| 96 | 98 | { |
| 97 | 99 | env->gpr[REG] = T2_64; |
| 100 | + env->gprh[REG] = T2_64 >> 32; | |
| 98 | 101 | RETURN(); |
| 99 | 102 | } |
| 100 | 103 | #endif |
| 101 | -#endif /* defined(TARGET_PPCEMB) */ | |
| 104 | +#endif /* TARGET_GPR_BITS < 64 */ | |
| 102 | 105 | |
| 103 | 106 | /* Altivec registers moves */ |
| 104 | 107 | void OPPROTO glue(op_load_avr_A0_avr, REG) (void) | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -162,9 +162,7 @@ typedef struct DisasContext { |
| 162 | 162 | #endif |
| 163 | 163 | int fpu_enabled; |
| 164 | 164 | int altivec_enabled; |
| 165 | -#if defined(TARGET_PPCEMB) | |
| 166 | 165 | int spe_enabled; |
| 167 | -#endif | |
| 168 | 166 | ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */ |
| 169 | 167 | int singlestep_enabled; |
| 170 | 168 | int dcache_line_size; |
| ... | ... | @@ -5821,10 +5819,11 @@ GEN_VR_STX(vx, 0x07, 0x07); |
| 5821 | 5819 | #define gen_op_vr_stvxl gen_op_vr_stvx |
| 5822 | 5820 | GEN_VR_STX(vxl, 0x07, 0x0F); |
| 5823 | 5821 | |
| 5824 | -#if defined(TARGET_PPCEMB) | |
| 5825 | 5822 | /*** SPE extension ***/ |
| 5826 | 5823 | |
| 5827 | 5824 | /* Register moves */ |
| 5825 | +#if TARGET_GPR_BITS < 64 | |
| 5826 | + | |
| 5828 | 5827 | GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr); |
| 5829 | 5828 | GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr); |
| 5830 | 5829 | #if 0 // unused |
| ... | ... | @@ -5837,6 +5836,23 @@ GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr); |
| 5837 | 5836 | GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr); |
| 5838 | 5837 | #endif |
| 5839 | 5838 | |
| 5839 | +#else /* TARGET_GPR_BITS < 64 */ | |
| 5840 | + | |
| 5841 | +/* No specific load/store functions: GPRs are already 64 bits */ | |
| 5842 | +#define gen_op_load_gpr64_T0 gen_op_load_gpr_T0 | |
| 5843 | +#define gen_op_load_gpr64_T1 gen_op_load_gpr_T1 | |
| 5844 | +#if 0 // unused | |
| 5845 | +#define gen_op_load_gpr64_T2 gen_op_load_gpr_T2 | |
| 5846 | +#endif | |
| 5847 | + | |
| 5848 | +#define gen_op_store_T0_gpr64 gen_op_store_T0_gpr | |
| 5849 | +#define gen_op_store_T1_gpr64 gen_op_store_T1_gpr | |
| 5850 | +#if 0 // unused | |
| 5851 | +#define gen_op_store_T2_gpr64 gen_op_store_T2_gpr | |
| 5852 | +#endif | |
| 5853 | + | |
| 5854 | +#endif /* TARGET_GPR_BITS < 64 */ | |
| 5855 | + | |
| 5840 | 5856 | #define GEN_SPE(name0, name1, opc2, opc3, inval, type) \ |
| 5841 | 5857 | GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type) \ |
| 5842 | 5858 | { \ |
| ... | ... | @@ -6105,10 +6121,10 @@ GEN_SPEOP_ARITH1(evcntlsw); |
| 6105 | 6121 | static always_inline void gen_brinc (DisasContext *ctx) |
| 6106 | 6122 | { |
| 6107 | 6123 | /* Note: brinc is usable even if SPE is disabled */ |
| 6108 | - gen_op_load_gpr64_T0(rA(ctx->opcode)); | |
| 6109 | - gen_op_load_gpr64_T1(rB(ctx->opcode)); | |
| 6124 | + gen_op_load_gpr_T0(rA(ctx->opcode)); | |
| 6125 | + gen_op_load_gpr_T1(rB(ctx->opcode)); | |
| 6110 | 6126 | gen_op_brinc(); |
| 6111 | - gen_op_store_T0_gpr64(rD(ctx->opcode)); | |
| 6127 | + gen_op_store_T0_gpr(rD(ctx->opcode)); | |
| 6112 | 6128 | } |
| 6113 | 6129 | |
| 6114 | 6130 | #define GEN_SPEOP_ARITH_IMM2(name) \ |
| ... | ... | @@ -6242,6 +6258,12 @@ GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE) |
| 6242 | 6258 | #define gen_op_spe_stdd_le_raw gen_op_std_le_raw |
| 6243 | 6259 | #define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw |
| 6244 | 6260 | #else /* defined(CONFIG_USER_ONLY) */ |
| 6261 | +#if defined(TARGET_PPC64H) | |
| 6262 | +#define gen_op_spe_ldd_hypv gen_op_ld_hypv | |
| 6263 | +#define gen_op_spe_ldd_64_hypv gen_op_ld_64_hypv | |
| 6264 | +#define gen_op_spe_ldd_le_hypv gen_op_ld_hypv | |
| 6265 | +#define gen_op_spe_ldd_le_64_hypv gen_op_ld_64_hypv | |
| 6266 | +#endif | |
| 6245 | 6267 | #define gen_op_spe_ldd_kernel gen_op_ld_kernel |
| 6246 | 6268 | #define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel |
| 6247 | 6269 | #define gen_op_spe_ldd_le_kernel gen_op_ld_kernel |
| ... | ... | @@ -6250,6 +6272,12 @@ GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE) |
| 6250 | 6272 | #define gen_op_spe_ldd_64_user gen_op_ld_64_user |
| 6251 | 6273 | #define gen_op_spe_ldd_le_user gen_op_ld_le_user |
| 6252 | 6274 | #define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user |
| 6275 | +#if defined(TARGET_PPC64H) | |
| 6276 | +#define gen_op_spe_stdd_hypv gen_op_std_hypv | |
| 6277 | +#define gen_op_spe_stdd_64_hypv gen_op_std_64_hypv | |
| 6278 | +#define gen_op_spe_stdd_le_hypv gen_op_std_hypv | |
| 6279 | +#define gen_op_spe_stdd_le_64_hypv gen_op_std_64_hypv | |
| 6280 | +#endif | |
| 6253 | 6281 | #define gen_op_spe_stdd_kernel gen_op_std_kernel |
| 6254 | 6282 | #define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel |
| 6255 | 6283 | #define gen_op_spe_stdd_le_kernel gen_op_std_kernel |
| ... | ... | @@ -6284,6 +6312,12 @@ GEN_SPEOP_ST(who, 2); |
| 6284 | 6312 | #define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel |
| 6285 | 6313 | #define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel |
| 6286 | 6314 | #define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel |
| 6315 | +#if defined(TARGET_PPC64H) | |
| 6316 | +#define gen_op_spe_stwwo_hypv gen_op_stw_hypv | |
| 6317 | +#define gen_op_spe_stwwo_le_hypv gen_op_stw_le_hypv | |
| 6318 | +#define gen_op_spe_stwwo_64_hypv gen_op_stw_64_hypv | |
| 6319 | +#define gen_op_spe_stwwo_le_64_hypv gen_op_stw_le_64_hypv | |
| 6320 | +#endif | |
| 6287 | 6321 | #endif |
| 6288 | 6322 | #endif |
| 6289 | 6323 | #define _GEN_OP_SPE_STWWE(suffix) \ |
| ... | ... | @@ -6320,6 +6354,9 @@ _GEN_OP_SPE_STWWE_LE(suffix) |
| 6320 | 6354 | #if defined(CONFIG_USER_ONLY) |
| 6321 | 6355 | GEN_OP_SPE_STWWE(raw); |
| 6322 | 6356 | #else /* defined(CONFIG_USER_ONLY) */ |
| 6357 | +#if defined(TARGET_PPC64H) | |
| 6358 | +GEN_OP_SPE_STWWE(hypv); | |
| 6359 | +#endif | |
| 6323 | 6360 | GEN_OP_SPE_STWWE(kernel); |
| 6324 | 6361 | GEN_OP_SPE_STWWE(user); |
| 6325 | 6362 | #endif /* defined(CONFIG_USER_ONLY) */ |
| ... | ... | @@ -6371,45 +6408,105 @@ GEN_OP_SPE_LHX(le_64_raw); |
| 6371 | 6408 | GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw); |
| 6372 | 6409 | #endif |
| 6373 | 6410 | #else |
| 6411 | +#if defined(TARGET_PPC64H) | |
| 6412 | +GEN_OP_SPE_LHE(hypv); | |
| 6413 | +#endif | |
| 6374 | 6414 | GEN_OP_SPE_LHE(kernel); |
| 6375 | 6415 | GEN_OP_SPE_LHE(user); |
| 6416 | +#if defined(TARGET_PPC64H) | |
| 6417 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, hypv); | |
| 6418 | +#endif | |
| 6376 | 6419 | GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel); |
| 6377 | 6420 | GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user); |
| 6421 | +#if defined(TARGET_PPC64H) | |
| 6422 | +GEN_OP_SPE_LHE(le_hypv); | |
| 6423 | +#endif | |
| 6378 | 6424 | GEN_OP_SPE_LHE(le_kernel); |
| 6379 | 6425 | GEN_OP_SPE_LHE(le_user); |
| 6426 | +#if defined(TARGET_PPC64H) | |
| 6427 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_hypv); | |
| 6428 | +#endif | |
| 6380 | 6429 | GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel); |
| 6381 | 6430 | GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user); |
| 6431 | +#if defined(TARGET_PPC64H) | |
| 6432 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, hypv); | |
| 6433 | +#endif | |
| 6382 | 6434 | GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel); |
| 6383 | 6435 | GEN_SPE_LDSPLAT(hhousplat, spe_lh, user); |
| 6436 | +#if defined(TARGET_PPC64H) | |
| 6437 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_hypv); | |
| 6438 | +#endif | |
| 6384 | 6439 | GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel); |
| 6385 | 6440 | GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user); |
| 6441 | +#if defined(TARGET_PPC64H) | |
| 6442 | +GEN_OP_SPE_LHX(hypv); | |
| 6443 | +#endif | |
| 6386 | 6444 | GEN_OP_SPE_LHX(kernel); |
| 6387 | 6445 | GEN_OP_SPE_LHX(user); |
| 6446 | +#if defined(TARGET_PPC64H) | |
| 6447 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, hypv); | |
| 6448 | +#endif | |
| 6388 | 6449 | GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel); |
| 6389 | 6450 | GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user); |
| 6451 | +#if defined(TARGET_PPC64H) | |
| 6452 | +GEN_OP_SPE_LHX(le_hypv); | |
| 6453 | +#endif | |
| 6390 | 6454 | GEN_OP_SPE_LHX(le_kernel); |
| 6391 | 6455 | GEN_OP_SPE_LHX(le_user); |
| 6456 | +#if defined(TARGET_PPC64H) | |
| 6457 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_hypv); | |
| 6458 | +#endif | |
| 6392 | 6459 | GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel); |
| 6393 | 6460 | GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user); |
| 6394 | 6461 | #if defined(TARGET_PPC64) |
| 6462 | +#if defined(TARGET_PPC64H) | |
| 6463 | +GEN_OP_SPE_LHE(64_hypv); | |
| 6464 | +#endif | |
| 6395 | 6465 | GEN_OP_SPE_LHE(64_kernel); |
| 6396 | 6466 | GEN_OP_SPE_LHE(64_user); |
| 6467 | +#if defined(TARGET_PPC64H) | |
| 6468 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_hypv); | |
| 6469 | +#endif | |
| 6397 | 6470 | GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel); |
| 6398 | 6471 | GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user); |
| 6472 | +#if defined(TARGET_PPC64H) | |
| 6473 | +GEN_OP_SPE_LHE(le_64_hypv); | |
| 6474 | +#endif | |
| 6399 | 6475 | GEN_OP_SPE_LHE(le_64_kernel); |
| 6400 | 6476 | GEN_OP_SPE_LHE(le_64_user); |
| 6477 | +#if defined(TARGET_PPC64H) | |
| 6478 | +GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_hypv); | |
| 6479 | +#endif | |
| 6401 | 6480 | GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel); |
| 6402 | 6481 | GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user); |
| 6482 | +#if defined(TARGET_PPC64H) | |
| 6483 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_hypv); | |
| 6484 | +#endif | |
| 6403 | 6485 | GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel); |
| 6404 | 6486 | GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user); |
| 6487 | +#if defined(TARGET_PPC64H) | |
| 6488 | +GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_hypv); | |
| 6489 | +#endif | |
| 6405 | 6490 | GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel); |
| 6406 | 6491 | GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user); |
| 6492 | +#if defined(TARGET_PPC64H) | |
| 6493 | +GEN_OP_SPE_LHX(64_hypv); | |
| 6494 | +#endif | |
| 6407 | 6495 | GEN_OP_SPE_LHX(64_kernel); |
| 6408 | 6496 | GEN_OP_SPE_LHX(64_user); |
| 6497 | +#if defined(TARGET_PPC64H) | |
| 6498 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_hypv); | |
| 6499 | +#endif | |
| 6409 | 6500 | GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel); |
| 6410 | 6501 | GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user); |
| 6502 | +#if defined(TARGET_PPC64H) | |
| 6503 | +GEN_OP_SPE_LHX(le_64_hypv); | |
| 6504 | +#endif | |
| 6411 | 6505 | GEN_OP_SPE_LHX(le_64_kernel); |
| 6412 | 6506 | GEN_OP_SPE_LHX(le_64_user); |
| 6507 | +#if defined(TARGET_PPC64H) | |
| 6508 | +GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_hypv); | |
| 6509 | +#endif | |
| 6413 | 6510 | GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel); |
| 6414 | 6511 | GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user); |
| 6415 | 6512 | #endif |
| ... | ... | @@ -6663,7 +6760,6 @@ GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, PPC_SPEFPU); // |
| 6663 | 6760 | GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, PPC_SPEFPU); // |
| 6664 | 6761 | GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, PPC_SPEFPU); // |
| 6665 | 6762 | GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, PPC_SPEFPU); // |
| 6666 | -#endif | |
| 6667 | 6763 | |
| 6668 | 6764 | /* End opcode list */ |
| 6669 | 6765 | GEN_OPCODE_MARK(end); |
| ... | ... | @@ -6830,12 +6926,10 @@ static always_inline int gen_intermediate_code_internal (CPUState *env, |
| 6830 | 6926 | #endif |
| 6831 | 6927 | ctx.dcache_line_size = env->dcache_line_size; |
| 6832 | 6928 | ctx.fpu_enabled = msr_fp; |
| 6833 | -#if defined(TARGET_PPCEMB) | |
| 6834 | 6929 | if ((env->flags & POWERPC_FLAG_SPE) && msr_spe) |
| 6835 | 6930 | ctx.spe_enabled = msr_spe; |
| 6836 | 6931 | else |
| 6837 | 6932 | ctx.spe_enabled = 0; |
| 6838 | -#endif | |
| 6839 | 6933 | if ((env->flags & POWERPC_FLAG_VRE) && msr_vr) |
| 6840 | 6934 | ctx.altivec_enabled = msr_vr; |
| 6841 | 6935 | else | ... | ... |