Commit 9d53c7535f0305a537c5f0278b61cbe34074247c

Authored by j_mayer
1 parent 74aa0429

Fix for PowerPC 64 rotates.

Fix for PowerPC 64 load & store with immediate index.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2617 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 35 additions and 27 deletions
target-ppc/translate.c
@@ -1264,8 +1264,8 @@ static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn) @@ -1264,8 +1264,8 @@ static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn)
1264 { 1264 {
1265 uint32_t sh, mb; 1265 uint32_t sh, mb;
1266 1266
1267 - sh = SH(ctx->opcode) | (1 << shn);  
1268 - mb = (MB(ctx->opcode) << 1) | mbn; 1267 + sh = SH(ctx->opcode) | (shn << 5);
  1268 + mb = MB(ctx->opcode) | (mbn << 5);
1269 gen_rldinm(ctx, mb, 63, sh); 1269 gen_rldinm(ctx, mb, 63, sh);
1270 } 1270 }
1271 GEN_PPC64_R4(rldicl, 0x1E, 0x00); 1271 GEN_PPC64_R4(rldicl, 0x1E, 0x00);
@@ -1274,8 +1274,8 @@ static inline void gen_rldicr (DisasContext *ctx, int men, int shn) @@ -1274,8 +1274,8 @@ static inline void gen_rldicr (DisasContext *ctx, int men, int shn)
1274 { 1274 {
1275 uint32_t sh, me; 1275 uint32_t sh, me;
1276 1276
1277 - sh = SH(ctx->opcode) | (1 << shn);  
1278 - me = (MB(ctx->opcode) << 1) | men; 1277 + sh = SH(ctx->opcode) | (shn << 5);
  1278 + me = MB(ctx->opcode) | (men << 5);
1279 gen_rldinm(ctx, 0, me, sh); 1279 gen_rldinm(ctx, 0, me, sh);
1280 } 1280 }
1281 GEN_PPC64_R4(rldicr, 0x1E, 0x02); 1281 GEN_PPC64_R4(rldicr, 0x1E, 0x02);
@@ -1284,8 +1284,8 @@ static inline void gen_rldic (DisasContext *ctx, int mbn, int shn) @@ -1284,8 +1284,8 @@ static inline void gen_rldic (DisasContext *ctx, int mbn, int shn)
1284 { 1284 {
1285 uint32_t sh, mb; 1285 uint32_t sh, mb;
1286 1286
1287 - sh = SH(ctx->opcode) | (1 << shn);  
1288 - mb = (MB(ctx->opcode) << 1) | mbn; 1287 + sh = SH(ctx->opcode) | (shn << 5);
  1288 + mb = MB(ctx->opcode) | (mbn << 5);
1289 gen_rldinm(ctx, mb, 63 - sh, sh); 1289 gen_rldinm(ctx, mb, 63 - sh, sh);
1290 } 1290 }
1291 GEN_PPC64_R4(rldic, 0x1E, 0x04); 1291 GEN_PPC64_R4(rldic, 0x1E, 0x04);
@@ -1308,7 +1308,7 @@ static inline void gen_rldcl (DisasContext *ctx, int mbn) @@ -1308,7 +1308,7 @@ static inline void gen_rldcl (DisasContext *ctx, int mbn)
1308 { 1308 {
1309 uint32_t mb; 1309 uint32_t mb;
1310 1310
1311 - mb = (MB(ctx->opcode) << 1) | mbn; 1311 + mb = MB(ctx->opcode) | (mbn << 5);
1312 gen_rldnm(ctx, mb, 63); 1312 gen_rldnm(ctx, mb, 63);
1313 } 1313 }
1314 GEN_PPC64_R2(rldcl, 0x1E, 0x08) 1314 GEN_PPC64_R2(rldcl, 0x1E, 0x08)
@@ -1317,7 +1317,7 @@ static inline void gen_rldcr (DisasContext *ctx, int men) @@ -1317,7 +1317,7 @@ static inline void gen_rldcr (DisasContext *ctx, int men)
1317 { 1317 {
1318 uint32_t me; 1318 uint32_t me;
1319 1319
1320 - me = (MB(ctx->opcode) << 1) | men; 1320 + me = MB(ctx->opcode) | (men << 5);
1321 gen_rldnm(ctx, 0, me); 1321 gen_rldnm(ctx, 0, me);
1322 } 1322 }
1323 GEN_PPC64_R2(rldcr, 0x1E, 0x09) 1323 GEN_PPC64_R2(rldcr, 0x1E, 0x09)
@@ -1327,8 +1327,8 @@ static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn) @@ -1327,8 +1327,8 @@ static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
1327 uint64_t mask; 1327 uint64_t mask;
1328 uint32_t sh, mb; 1328 uint32_t sh, mb;
1329 1329
1330 - sh = SH(ctx->opcode) | (1 << shn);  
1331 - mb = (MB(ctx->opcode) << 1) | mbn; 1330 + sh = SH(ctx->opcode) | (shn << 5);
  1331 + mb = MB(ctx->opcode) | (mbn << 5);
1332 if (likely(sh == 0)) { 1332 if (likely(sh == 0)) {
1333 if (likely(mb == 0)) { 1333 if (likely(mb == 0)) {
1334 gen_op_load_gpr_T0(rS(ctx->opcode)); 1334 gen_op_load_gpr_T0(rS(ctx->opcode));
@@ -1732,10 +1732,12 @@ GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT) @@ -1732,10 +1732,12 @@ GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT)
1732 1732
1733 /*** Addressing modes ***/ 1733 /*** Addressing modes ***/
1734 /* Register indirect with immediate index : EA = (rA|0) + SIMM */ 1734 /* Register indirect with immediate index : EA = (rA|0) + SIMM */
1735 -static inline void gen_addr_imm_index (DisasContext *ctx) 1735 +static inline void gen_addr_imm_index (DisasContext *ctx, int maskl)
1736 { 1736 {
1737 target_long simm = SIMM(ctx->opcode); 1737 target_long simm = SIMM(ctx->opcode);
1738 1738
  1739 + if (maskl)
  1740 + simm &= ~0x03;
1739 if (rA(ctx->opcode) == 0) { 1741 if (rA(ctx->opcode) == 0) {
1740 gen_set_T0(simm); 1742 gen_set_T0(simm);
1741 } else { 1743 } else {
@@ -1856,7 +1858,7 @@ static GenOpFunc *gen_op_st##width[] = { \ @@ -1856,7 +1858,7 @@ static GenOpFunc *gen_op_st##width[] = { \
1856 #define GEN_LD(width, opc, type) \ 1858 #define GEN_LD(width, opc, type) \
1857 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type) \ 1859 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type) \
1858 { \ 1860 { \
1859 - gen_addr_imm_index(ctx); \ 1861 + gen_addr_imm_index(ctx, 0); \
1860 op_ldst(l##width); \ 1862 op_ldst(l##width); \
1861 gen_op_store_T1_gpr(rD(ctx->opcode)); \ 1863 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1862 } 1864 }
@@ -1869,7 +1871,10 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \ @@ -1869,7 +1871,10 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
1869 RET_INVAL(ctx); \ 1871 RET_INVAL(ctx); \
1870 return; \ 1872 return; \
1871 } \ 1873 } \
1872 - gen_addr_imm_index(ctx); \ 1874 + if (type == PPC_64B) \
  1875 + gen_addr_imm_index(ctx, 1); \
  1876 + else \
  1877 + gen_addr_imm_index(ctx, 0); \
1873 op_ldst(l##width); \ 1878 op_ldst(l##width); \
1874 gen_op_store_T1_gpr(rD(ctx->opcode)); \ 1879 gen_op_store_T1_gpr(rD(ctx->opcode)); \
1875 gen_op_store_T0_gpr(rA(ctx->opcode)); \ 1880 gen_op_store_T0_gpr(rA(ctx->opcode)); \
@@ -1932,7 +1937,7 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B) @@ -1932,7 +1937,7 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
1932 return; 1937 return;
1933 } 1938 }
1934 } 1939 }
1935 - gen_addr_imm_index(ctx); 1940 + gen_addr_imm_index(ctx, 1);
1936 if (ctx->opcode & 0x02) { 1941 if (ctx->opcode & 0x02) {
1937 /* lwa (lwau is undefined) */ 1942 /* lwa (lwau is undefined) */
1938 op_ldst(lwa); 1943 op_ldst(lwa);
@@ -1950,7 +1955,7 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B) @@ -1950,7 +1955,7 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
1950 #define GEN_ST(width, opc, type) \ 1955 #define GEN_ST(width, opc, type) \
1951 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \ 1956 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type) \
1952 { \ 1957 { \
1953 - gen_addr_imm_index(ctx); \ 1958 + gen_addr_imm_index(ctx, 0); \
1954 gen_op_load_gpr_T1(rS(ctx->opcode)); \ 1959 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1955 op_ldst(st##width); \ 1960 op_ldst(st##width); \
1956 } 1961 }
@@ -1962,7 +1967,10 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \ @@ -1962,7 +1967,10 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \
1962 RET_INVAL(ctx); \ 1967 RET_INVAL(ctx); \
1963 return; \ 1968 return; \
1964 } \ 1969 } \
1965 - gen_addr_imm_index(ctx); \ 1970 + if (type == PPC_64B) \
  1971 + gen_addr_imm_index(ctx, 1); \
  1972 + else \
  1973 + gen_addr_imm_index(ctx, 0); \
1966 gen_op_load_gpr_T1(rS(ctx->opcode)); \ 1974 gen_op_load_gpr_T1(rS(ctx->opcode)); \
1967 op_ldst(st##width); \ 1975 op_ldst(st##width); \
1968 gen_op_store_T0_gpr(rA(ctx->opcode)); \ 1976 gen_op_store_T0_gpr(rA(ctx->opcode)); \
@@ -2014,7 +2022,7 @@ GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B) @@ -2014,7 +2022,7 @@ GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B)
2014 return; 2022 return;
2015 } 2023 }
2016 } 2024 }
2017 - gen_addr_imm_index(ctx); 2025 + gen_addr_imm_index(ctx, 1);
2018 gen_op_load_gpr_T1(rS(ctx->opcode)); 2026 gen_op_load_gpr_T1(rS(ctx->opcode));
2019 op_ldst(std); 2027 op_ldst(std);
2020 if (Rc(ctx->opcode)) 2028 if (Rc(ctx->opcode))
@@ -2102,7 +2110,7 @@ GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) @@ -2102,7 +2110,7 @@ GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2102 { 2110 {
2103 /* NIP cannot be restored if the memory exception comes from an helper */ 2111 /* NIP cannot be restored if the memory exception comes from an helper */
2104 gen_update_nip(ctx, ctx->nip - 4); 2112 gen_update_nip(ctx, ctx->nip - 4);
2105 - gen_addr_imm_index(ctx); 2113 + gen_addr_imm_index(ctx, 0);
2106 op_ldstm(lmw, rD(ctx->opcode)); 2114 op_ldstm(lmw, rD(ctx->opcode));
2107 } 2115 }
2108 2116
@@ -2111,7 +2119,7 @@ GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) @@ -2111,7 +2119,7 @@ GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
2111 { 2119 {
2112 /* NIP cannot be restored if the memory exception comes from an helper */ 2120 /* NIP cannot be restored if the memory exception comes from an helper */
2113 gen_update_nip(ctx, ctx->nip - 4); 2121 gen_update_nip(ctx, ctx->nip - 4);
2114 - gen_addr_imm_index(ctx); 2122 + gen_addr_imm_index(ctx, 0);
2115 op_ldstm(stmw, rS(ctx->opcode)); 2123 op_ldstm(stmw, rS(ctx->opcode));
2116 } 2124 }
2117 2125
@@ -2435,7 +2443,7 @@ GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2435,7 +2443,7 @@ GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2435 RET_EXCP(ctx, EXCP_NO_FP, 0); \ 2443 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2436 return; \ 2444 return; \
2437 } \ 2445 } \
2438 - gen_addr_imm_index(ctx); \ 2446 + gen_addr_imm_index(ctx, 0); \
2439 op_ldst(l##width); \ 2447 op_ldst(l##width); \
2440 gen_op_store_FT0_fpr(rD(ctx->opcode)); \ 2448 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2441 } 2449 }
@@ -2451,7 +2459,7 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2451,7 +2459,7 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2451 RET_INVAL(ctx); \ 2459 RET_INVAL(ctx); \
2452 return; \ 2460 return; \
2453 } \ 2461 } \
2454 - gen_addr_imm_index(ctx); \ 2462 + gen_addr_imm_index(ctx, 0); \
2455 op_ldst(l##width); \ 2463 op_ldst(l##width); \
2456 gen_op_store_FT0_fpr(rD(ctx->opcode)); \ 2464 gen_op_store_FT0_fpr(rD(ctx->opcode)); \
2457 gen_op_store_T0_gpr(rA(ctx->opcode)); \ 2465 gen_op_store_T0_gpr(rA(ctx->opcode)); \
@@ -2506,7 +2514,7 @@ GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2506,7 +2514,7 @@ GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2506 RET_EXCP(ctx, EXCP_NO_FP, 0); \ 2514 RET_EXCP(ctx, EXCP_NO_FP, 0); \
2507 return; \ 2515 return; \
2508 } \ 2516 } \
2509 - gen_addr_imm_index(ctx); \ 2517 + gen_addr_imm_index(ctx, 0); \
2510 gen_op_load_fpr_FT0(rS(ctx->opcode)); \ 2518 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2511 op_ldst(st##width); \ 2519 op_ldst(st##width); \
2512 } 2520 }
@@ -2522,7 +2530,7 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ @@ -2522,7 +2530,7 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \
2522 RET_INVAL(ctx); \ 2530 RET_INVAL(ctx); \
2523 return; \ 2531 return; \
2524 } \ 2532 } \
2525 - gen_addr_imm_index(ctx); \ 2533 + gen_addr_imm_index(ctx, 0); \
2526 gen_op_load_fpr_FT0(rS(ctx->opcode)); \ 2534 gen_op_load_fpr_FT0(rS(ctx->opcode)); \
2527 op_ldst(st##width); \ 2535 op_ldst(st##width); \
2528 gen_op_store_T0_gpr(rA(ctx->opcode)); \ 2536 gen_op_store_T0_gpr(rA(ctx->opcode)); \
@@ -4102,7 +4110,7 @@ GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2) @@ -4102,7 +4110,7 @@ GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4102 { 4110 {
4103 /* NIP cannot be restored if the memory exception comes from an helper */ 4111 /* NIP cannot be restored if the memory exception comes from an helper */
4104 gen_update_nip(ctx, ctx->nip - 4); 4112 gen_update_nip(ctx, ctx->nip - 4);
4105 - gen_addr_imm_index(ctx); 4113 + gen_addr_imm_index(ctx, 0);
4106 op_POWER2_lfq(); 4114 op_POWER2_lfq();
4107 gen_op_store_FT0_fpr(rD(ctx->opcode)); 4115 gen_op_store_FT0_fpr(rD(ctx->opcode));
4108 gen_op_store_FT1_fpr(rD(ctx->opcode) + 1); 4116 gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
@@ -4115,7 +4123,7 @@ GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2) @@ -4115,7 +4123,7 @@ GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4115 4123
4116 /* NIP cannot be restored if the memory exception comes from an helper */ 4124 /* NIP cannot be restored if the memory exception comes from an helper */
4117 gen_update_nip(ctx, ctx->nip - 4); 4125 gen_update_nip(ctx, ctx->nip - 4);
4118 - gen_addr_imm_index(ctx); 4126 + gen_addr_imm_index(ctx, 0);
4119 op_POWER2_lfq(); 4127 op_POWER2_lfq();
4120 gen_op_store_FT0_fpr(rD(ctx->opcode)); 4128 gen_op_store_FT0_fpr(rD(ctx->opcode));
4121 gen_op_store_FT1_fpr(rD(ctx->opcode) + 1); 4129 gen_op_store_FT1_fpr(rD(ctx->opcode) + 1);
@@ -4154,7 +4162,7 @@ GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2) @@ -4154,7 +4162,7 @@ GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4154 { 4162 {
4155 /* NIP cannot be restored if the memory exception comes from an helper */ 4163 /* NIP cannot be restored if the memory exception comes from an helper */
4156 gen_update_nip(ctx, ctx->nip - 4); 4164 gen_update_nip(ctx, ctx->nip - 4);
4157 - gen_addr_imm_index(ctx); 4165 + gen_addr_imm_index(ctx, 0);
4158 gen_op_load_fpr_FT0(rS(ctx->opcode)); 4166 gen_op_load_fpr_FT0(rS(ctx->opcode));
4159 gen_op_load_fpr_FT1(rS(ctx->opcode) + 1); 4167 gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4160 op_POWER2_stfq(); 4168 op_POWER2_stfq();
@@ -4167,7 +4175,7 @@ GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2) @@ -4167,7 +4175,7 @@ GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2)
4167 4175
4168 /* NIP cannot be restored if the memory exception comes from an helper */ 4176 /* NIP cannot be restored if the memory exception comes from an helper */
4169 gen_update_nip(ctx, ctx->nip - 4); 4177 gen_update_nip(ctx, ctx->nip - 4);
4170 - gen_addr_imm_index(ctx); 4178 + gen_addr_imm_index(ctx, 0);
4171 gen_op_load_fpr_FT0(rS(ctx->opcode)); 4179 gen_op_load_fpr_FT0(rS(ctx->opcode));
4172 gen_op_load_fpr_FT1(rS(ctx->opcode) + 1); 4180 gen_op_load_fpr_FT1(rS(ctx->opcode) + 1);
4173 op_POWER2_stfq(); 4181 op_POWER2_stfq();