Commit 40569b7edc2959c7460211de0b30bbdbb87626e4

Authored by aurel32
1 parent 071fc3b1

target-ppc: Model SPE floating-point instructions more accurately

Single-precision and double-precision floating-point instructions should
be separated into their own categories, since some chips only support
single-precision instructions.

Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6575 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/translate.c
@@ -509,8 +509,10 @@ enum { @@ -509,8 +509,10 @@ enum {
509 PPC_ALTIVEC = 0x0000000001000000ULL, 509 PPC_ALTIVEC = 0x0000000001000000ULL,
510 /* PowerPC 2.03 SPE extension */ 510 /* PowerPC 2.03 SPE extension */
511 PPC_SPE = 0x0000000002000000ULL, 511 PPC_SPE = 0x0000000002000000ULL,
512 - /* PowerPC 2.03 SPE floating-point extension */  
513 - PPC_SPEFPU = 0x0000000004000000ULL, 512 + /* PowerPC 2.03 SPE single-precision floating-point extension */
  513 + PPC_SPE_SINGLE = 0x0000000004000000ULL,
  514 + /* PowerPC 2.03 SPE double-precision floating-point extension */
  515 + PPC_SPE_DOUBLE = 0x0000000008000000ULL,
514 516
515 /* Optional memory control instructions */ 517 /* Optional memory control instructions */
516 PPC_MEM_TLBIA = 0x0000000010000000ULL, 518 PPC_MEM_TLBIA = 0x0000000010000000ULL,
@@ -7886,20 +7888,20 @@ GEN_SPEFPUOP_COMP_64(evfststlt); @@ -7886,20 +7888,20 @@ GEN_SPEFPUOP_COMP_64(evfststlt);
7886 GEN_SPEFPUOP_COMP_64(evfststeq); 7888 GEN_SPEFPUOP_COMP_64(evfststeq);
7887 7889
7888 /* Opcodes definitions */ 7890 /* Opcodes definitions */
7889 -GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, PPC_SPEFPU); //  
7890 -GEN_SPE(evfsabs, evfsnabs, 0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //  
7891 -GEN_SPE(evfsneg, speundef, 0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //  
7892 -GEN_SPE(evfsmul, evfsdiv, 0x04, 0x0A, 0x00000000, PPC_SPEFPU); //  
7893 -GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, PPC_SPEFPU); //  
7894 -GEN_SPE(evfscmpeq, speundef, 0x07, 0x0A, 0x00600000, PPC_SPEFPU); //  
7895 -GEN_SPE(evfscfui, evfscfsi, 0x08, 0x0A, 0x00180000, PPC_SPEFPU); //  
7896 -GEN_SPE(evfscfuf, evfscfsf, 0x09, 0x0A, 0x00180000, PPC_SPEFPU); //  
7897 -GEN_SPE(evfsctui, evfsctsi, 0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //  
7898 -GEN_SPE(evfsctuf, evfsctsf, 0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //  
7899 -GEN_SPE(evfsctuiz, speundef, 0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //  
7900 -GEN_SPE(evfsctsiz, speundef, 0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //  
7901 -GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //  
7902 -GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, PPC_SPEFPU); // 7891 +GEN_SPE(evfsadd, evfssub, 0x00, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
  7892 +GEN_SPE(evfsabs, evfsnabs, 0x02, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
  7893 +GEN_SPE(evfsneg, speundef, 0x03, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
  7894 +GEN_SPE(evfsmul, evfsdiv, 0x04, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
  7895 +GEN_SPE(evfscmpgt, evfscmplt, 0x06, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
  7896 +GEN_SPE(evfscmpeq, speundef, 0x07, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
  7897 +GEN_SPE(evfscfui, evfscfsi, 0x08, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
  7898 +GEN_SPE(evfscfuf, evfscfsf, 0x09, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
  7899 +GEN_SPE(evfsctui, evfsctsi, 0x0A, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
  7900 +GEN_SPE(evfsctuf, evfsctsf, 0x0B, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
  7901 +GEN_SPE(evfsctuiz, speundef, 0x0C, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
  7902 +GEN_SPE(evfsctsiz, speundef, 0x0D, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
  7903 +GEN_SPE(evfststgt, evfststlt, 0x0E, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
  7904 +GEN_SPE(evfststeq, speundef, 0x0F, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
7903 7905
7904 /* Single precision floating-point operations */ 7906 /* Single precision floating-point operations */
7905 /* Arithmetic */ 7907 /* Arithmetic */
@@ -7954,20 +7956,20 @@ GEN_SPEFPUOP_COMP_32(efststlt); @@ -7954,20 +7956,20 @@ GEN_SPEFPUOP_COMP_32(efststlt);
7954 GEN_SPEFPUOP_COMP_32(efststeq); 7956 GEN_SPEFPUOP_COMP_32(efststeq);
7955 7957
7956 /* Opcodes definitions */ 7958 /* Opcodes definitions */
7957 -GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, PPC_SPEFPU); //  
7958 -GEN_SPE(efsabs, efsnabs, 0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //  
7959 -GEN_SPE(efsneg, speundef, 0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //  
7960 -GEN_SPE(efsmul, efsdiv, 0x04, 0x0B, 0x00000000, PPC_SPEFPU); //  
7961 -GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, PPC_SPEFPU); //  
7962 -GEN_SPE(efscmpeq, efscfd, 0x07, 0x0B, 0x00600000, PPC_SPEFPU); //  
7963 -GEN_SPE(efscfui, efscfsi, 0x08, 0x0B, 0x00180000, PPC_SPEFPU); //  
7964 -GEN_SPE(efscfuf, efscfsf, 0x09, 0x0B, 0x00180000, PPC_SPEFPU); //  
7965 -GEN_SPE(efsctui, efsctsi, 0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //  
7966 -GEN_SPE(efsctuf, efsctsf, 0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //  
7967 -GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //  
7968 -GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, PPC_SPEFPU); //  
7969 -GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //  
7970 -GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, PPC_SPEFPU); // 7959 +GEN_SPE(efsadd, efssub, 0x00, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
  7960 +GEN_SPE(efsabs, efsnabs, 0x02, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
  7961 +GEN_SPE(efsneg, speundef, 0x03, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
  7962 +GEN_SPE(efsmul, efsdiv, 0x04, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
  7963 +GEN_SPE(efscmpgt, efscmplt, 0x06, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
  7964 +GEN_SPE(efscmpeq, efscfd, 0x07, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
  7965 +GEN_SPE(efscfui, efscfsi, 0x08, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
  7966 +GEN_SPE(efscfuf, efscfsf, 0x09, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
  7967 +GEN_SPE(efsctui, efsctsi, 0x0A, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
  7968 +GEN_SPE(efsctuf, efsctsf, 0x0B, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
  7969 +GEN_SPE(efsctuiz, speundef, 0x0C, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
  7970 +GEN_SPE(efsctsiz, speundef, 0x0D, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
  7971 +GEN_SPE(efststgt, efststlt, 0x0E, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
  7972 +GEN_SPE(efststeq, speundef, 0x0F, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
7971 7973
7972 /* Double precision floating-point operations */ 7974 /* Double precision floating-point operations */
7973 /* Arithmetic */ 7975 /* Arithmetic */
@@ -8038,22 +8040,22 @@ GEN_SPEFPUOP_COMP_64(efdtstlt); @@ -8038,22 +8040,22 @@ GEN_SPEFPUOP_COMP_64(efdtstlt);
8038 GEN_SPEFPUOP_COMP_64(efdtsteq); 8040 GEN_SPEFPUOP_COMP_64(efdtsteq);
8039 8041
8040 /* Opcodes definitions */ 8042 /* Opcodes definitions */
8041 -GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, PPC_SPEFPU); //  
8042 -GEN_SPE(efdcfuid, efdcfsid, 0x11, 0x0B, 0x00180000, PPC_SPEFPU); //  
8043 -GEN_SPE(efdabs, efdnabs, 0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //  
8044 -GEN_SPE(efdneg, speundef, 0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //  
8045 -GEN_SPE(efdmul, efddiv, 0x14, 0x0B, 0x00000000, PPC_SPEFPU); //  
8046 -GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, PPC_SPEFPU); //  
8047 -GEN_SPE(efdcmpgt, efdcmplt, 0x16, 0x0B, 0x00600000, PPC_SPEFPU); //  
8048 -GEN_SPE(efdcmpeq, efdcfs, 0x17, 0x0B, 0x00600000, PPC_SPEFPU); //  
8049 -GEN_SPE(efdcfui, efdcfsi, 0x18, 0x0B, 0x00180000, PPC_SPEFPU); //  
8050 -GEN_SPE(efdcfuf, efdcfsf, 0x19, 0x0B, 0x00180000, PPC_SPEFPU); //  
8051 -GEN_SPE(efdctui, efdctsi, 0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //  
8052 -GEN_SPE(efdctuf, efdctsf, 0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //  
8053 -GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //  
8054 -GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //  
8055 -GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //  
8056 -GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, PPC_SPEFPU); // 8043 +GEN_SPE(efdadd, efdsub, 0x10, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
  8044 +GEN_SPE(efdcfuid, efdcfsid, 0x11, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
  8045 +GEN_SPE(efdabs, efdnabs, 0x12, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
  8046 +GEN_SPE(efdneg, speundef, 0x13, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
  8047 +GEN_SPE(efdmul, efddiv, 0x14, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
  8048 +GEN_SPE(efdctuidz, efdctsidz, 0x15, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
  8049 +GEN_SPE(efdcmpgt, efdcmplt, 0x16, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
  8050 +GEN_SPE(efdcmpeq, efdcfs, 0x17, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
  8051 +GEN_SPE(efdcfui, efdcfsi, 0x18, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
  8052 +GEN_SPE(efdcfuf, efdcfsf, 0x19, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
  8053 +GEN_SPE(efdctui, efdctsi, 0x1A, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
  8054 +GEN_SPE(efdctuf, efdctsf, 0x1B, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
  8055 +GEN_SPE(efdctuiz, speundef, 0x1C, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
  8056 +GEN_SPE(efdctsiz, speundef, 0x1D, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
  8057 +GEN_SPE(efdtstgt, efdtstlt, 0x1E, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
  8058 +GEN_SPE(efdtsteq, speundef, 0x1F, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
8057 8059
8058 /* End opcode list */ 8060 /* End opcode list */
8059 GEN_OPCODE_MARK(end); 8061 GEN_OPCODE_MARK(end);
target-ppc/translate_init.c
@@ -3984,7 +3984,7 @@ static void init_proc_G2LE (CPUPPCState *env) @@ -3984,7 +3984,7 @@ static void init_proc_G2LE (CPUPPCState *env)
3984 * all SPE multiply-accumulate instructions 3984 * all SPE multiply-accumulate instructions
3985 */ 3985 */
3986 #define POWERPC_INSNS_e200 (PPC_INSNS_BASE | PPC_ISEL | \ 3986 #define POWERPC_INSNS_e200 (PPC_INSNS_BASE | PPC_ISEL | \
3987 - PPC_SPE | PPC_SPEFPU | \ 3987 + PPC_SPE | PPC_SPE_SINGLE | \
3988 PPC_WRTEE | PPC_RFDI | \ 3988 PPC_WRTEE | PPC_RFDI | \
3989 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | \ 3989 PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | \
3990 PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \ 3990 PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
@@ -4147,13 +4147,13 @@ static void init_proc_e300 (CPUPPCState *env) @@ -4147,13 +4147,13 @@ static void init_proc_e300 (CPUPPCState *env)
4147 ppc6xx_irq_init(env); 4147 ppc6xx_irq_init(env);
4148 } 4148 }
4149 4149
4150 -/* e500 core */  
4151 -#define POWERPC_INSNS_e500 (PPC_INSNS_BASE | PPC_ISEL | \  
4152 - PPC_SPE | PPC_SPEFPU | \  
4153 - PPC_WRTEE | PPC_RFDI | \  
4154 - PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | \  
4155 - PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \  
4156 - PPC_MEM_TLBSYNC | PPC_TLBIVAX | \ 4150 +/* e500 core */
  4151 +#define POWERPC_INSNS_e500 (PPC_INSNS_BASE | PPC_ISEL | \
  4152 + PPC_SPE | PPC_SPE_SINGLE | PPC_SPE_DOUBLE | \
  4153 + PPC_WRTEE | PPC_RFDI | \
  4154 + PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI | \
  4155 + PPC_CACHE_DCBZ | PPC_CACHE_DCBA | \
  4156 + PPC_MEM_TLBSYNC | PPC_TLBIVAX | \
4157 PPC_BOOKE) 4157 PPC_BOOKE)
4158 #define POWERPC_MSRM_e500 (0x000000000606FF30ULL) 4158 #define POWERPC_MSRM_e500 (0x000000000606FF30ULL)
4159 #define POWERPC_MMU_e500 (POWERPC_MMU_BOOKE_FSL) 4159 #define POWERPC_MMU_e500 (POWERPC_MMU_BOOKE_FSL)
@@ -9431,7 +9431,7 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def) @@ -9431,7 +9431,7 @@ int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def)
9431 gdb_register_coprocessor(env, gdb_get_avr_reg, gdb_set_avr_reg, 9431 gdb_register_coprocessor(env, gdb_get_avr_reg, gdb_set_avr_reg,
9432 34, "power-altivec.xml", 0); 9432 34, "power-altivec.xml", 0);
9433 } 9433 }
9434 - if ((def->insns_flags & PPC_SPE) | (def->insns_flags & PPC_SPEFPU)) { 9434 + if (def->insns_flags & PPC_SPE) {
9435 gdb_register_coprocessor(env, gdb_get_spe_reg, gdb_set_spe_reg, 9435 gdb_register_coprocessor(env, gdb_get_spe_reg, gdb_set_spe_reg,
9436 34, "power-spe.xml", 0); 9436 34, "power-spe.xml", 0);
9437 } 9437 }