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