Commit 9d53c7535f0305a537c5f0278b61cbe34074247c
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 | 1264 | { |
1265 | 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 | 1269 | gen_rldinm(ctx, mb, 63, sh); |
1270 | 1270 | } |
1271 | 1271 | GEN_PPC64_R4(rldicl, 0x1E, 0x00); |
... | ... | @@ -1274,8 +1274,8 @@ static inline void gen_rldicr (DisasContext *ctx, int men, int shn) |
1274 | 1274 | { |
1275 | 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 | 1279 | gen_rldinm(ctx, 0, me, sh); |
1280 | 1280 | } |
1281 | 1281 | GEN_PPC64_R4(rldicr, 0x1E, 0x02); |
... | ... | @@ -1284,8 +1284,8 @@ static inline void gen_rldic (DisasContext *ctx, int mbn, int shn) |
1284 | 1284 | { |
1285 | 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 | 1289 | gen_rldinm(ctx, mb, 63 - sh, sh); |
1290 | 1290 | } |
1291 | 1291 | GEN_PPC64_R4(rldic, 0x1E, 0x04); |
... | ... | @@ -1308,7 +1308,7 @@ static inline void gen_rldcl (DisasContext *ctx, int mbn) |
1308 | 1308 | { |
1309 | 1309 | uint32_t mb; |
1310 | 1310 | |
1311 | - mb = (MB(ctx->opcode) << 1) | mbn; | |
1311 | + mb = MB(ctx->opcode) | (mbn << 5); | |
1312 | 1312 | gen_rldnm(ctx, mb, 63); |
1313 | 1313 | } |
1314 | 1314 | GEN_PPC64_R2(rldcl, 0x1E, 0x08) |
... | ... | @@ -1317,7 +1317,7 @@ static inline void gen_rldcr (DisasContext *ctx, int men) |
1317 | 1317 | { |
1318 | 1318 | uint32_t me; |
1319 | 1319 | |
1320 | - me = (MB(ctx->opcode) << 1) | men; | |
1320 | + me = MB(ctx->opcode) | (men << 5); | |
1321 | 1321 | gen_rldnm(ctx, 0, me); |
1322 | 1322 | } |
1323 | 1323 | GEN_PPC64_R2(rldcr, 0x1E, 0x09) |
... | ... | @@ -1327,8 +1327,8 @@ static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn) |
1327 | 1327 | uint64_t mask; |
1328 | 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 | 1332 | if (likely(sh == 0)) { |
1333 | 1333 | if (likely(mb == 0)) { |
1334 | 1334 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
... | ... | @@ -1732,10 +1732,12 @@ GEN_HANDLER(mtfsfi, 0x3F, 0x06, 0x04, 0x006f0800, PPC_FLOAT) |
1732 | 1732 | |
1733 | 1733 | /*** Addressing modes ***/ |
1734 | 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 | 1737 | target_long simm = SIMM(ctx->opcode); |
1738 | 1738 | |
1739 | + if (maskl) | |
1740 | + simm &= ~0x03; | |
1739 | 1741 | if (rA(ctx->opcode) == 0) { |
1740 | 1742 | gen_set_T0(simm); |
1741 | 1743 | } else { |
... | ... | @@ -1856,7 +1858,7 @@ static GenOpFunc *gen_op_st##width[] = { \ |
1856 | 1858 | #define GEN_LD(width, opc, type) \ |
1857 | 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 | 1862 | op_ldst(l##width); \ |
1861 | 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 | 1871 | RET_INVAL(ctx); \ |
1870 | 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 | 1878 | op_ldst(l##width); \ |
1874 | 1879 | gen_op_store_T1_gpr(rD(ctx->opcode)); \ |
1875 | 1880 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ |
... | ... | @@ -1932,7 +1937,7 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B) |
1932 | 1937 | return; |
1933 | 1938 | } |
1934 | 1939 | } |
1935 | - gen_addr_imm_index(ctx); | |
1940 | + gen_addr_imm_index(ctx, 1); | |
1936 | 1941 | if (ctx->opcode & 0x02) { |
1937 | 1942 | /* lwa (lwau is undefined) */ |
1938 | 1943 | op_ldst(lwa); |
... | ... | @@ -1950,7 +1955,7 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B) |
1950 | 1955 | #define GEN_ST(width, opc, type) \ |
1951 | 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 | 1959 | gen_op_load_gpr_T1(rS(ctx->opcode)); \ |
1955 | 1960 | op_ldst(st##width); \ |
1956 | 1961 | } |
... | ... | @@ -1962,7 +1967,10 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type) \ |
1962 | 1967 | RET_INVAL(ctx); \ |
1963 | 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 | 1974 | gen_op_load_gpr_T1(rS(ctx->opcode)); \ |
1967 | 1975 | op_ldst(st##width); \ |
1968 | 1976 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ |
... | ... | @@ -2014,7 +2022,7 @@ GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000002, PPC_64B) |
2014 | 2022 | return; |
2015 | 2023 | } |
2016 | 2024 | } |
2017 | - gen_addr_imm_index(ctx); | |
2025 | + gen_addr_imm_index(ctx, 1); | |
2018 | 2026 | gen_op_load_gpr_T1(rS(ctx->opcode)); |
2019 | 2027 | op_ldst(std); |
2020 | 2028 | if (Rc(ctx->opcode)) |
... | ... | @@ -2102,7 +2110,7 @@ GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) |
2102 | 2110 | { |
2103 | 2111 | /* NIP cannot be restored if the memory exception comes from an helper */ |
2104 | 2112 | gen_update_nip(ctx, ctx->nip - 4); |
2105 | - gen_addr_imm_index(ctx); | |
2113 | + gen_addr_imm_index(ctx, 0); | |
2106 | 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 | 2119 | { |
2112 | 2120 | /* NIP cannot be restored if the memory exception comes from an helper */ |
2113 | 2121 | gen_update_nip(ctx, ctx->nip - 4); |
2114 | - gen_addr_imm_index(ctx); | |
2122 | + gen_addr_imm_index(ctx, 0); | |
2115 | 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 | 2443 | RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
2436 | 2444 | return; \ |
2437 | 2445 | } \ |
2438 | - gen_addr_imm_index(ctx); \ | |
2446 | + gen_addr_imm_index(ctx, 0); \ | |
2439 | 2447 | op_ldst(l##width); \ |
2440 | 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 | 2459 | RET_INVAL(ctx); \ |
2452 | 2460 | return; \ |
2453 | 2461 | } \ |
2454 | - gen_addr_imm_index(ctx); \ | |
2462 | + gen_addr_imm_index(ctx, 0); \ | |
2455 | 2463 | op_ldst(l##width); \ |
2456 | 2464 | gen_op_store_FT0_fpr(rD(ctx->opcode)); \ |
2457 | 2465 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ |
... | ... | @@ -2506,7 +2514,7 @@ GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ |
2506 | 2514 | RET_EXCP(ctx, EXCP_NO_FP, 0); \ |
2507 | 2515 | return; \ |
2508 | 2516 | } \ |
2509 | - gen_addr_imm_index(ctx); \ | |
2517 | + gen_addr_imm_index(ctx, 0); \ | |
2510 | 2518 | gen_op_load_fpr_FT0(rS(ctx->opcode)); \ |
2511 | 2519 | op_ldst(st##width); \ |
2512 | 2520 | } |
... | ... | @@ -2522,7 +2530,7 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, PPC_FLOAT) \ |
2522 | 2530 | RET_INVAL(ctx); \ |
2523 | 2531 | return; \ |
2524 | 2532 | } \ |
2525 | - gen_addr_imm_index(ctx); \ | |
2533 | + gen_addr_imm_index(ctx, 0); \ | |
2526 | 2534 | gen_op_load_fpr_FT0(rS(ctx->opcode)); \ |
2527 | 2535 | op_ldst(st##width); \ |
2528 | 2536 | gen_op_store_T0_gpr(rA(ctx->opcode)); \ |
... | ... | @@ -4102,7 +4110,7 @@ GEN_HANDLER(lfq, 0x38, 0xFF, 0xFF, 0x00000003, PPC_POWER2) |
4102 | 4110 | { |
4103 | 4111 | /* NIP cannot be restored if the memory exception comes from an helper */ |
4104 | 4112 | gen_update_nip(ctx, ctx->nip - 4); |
4105 | - gen_addr_imm_index(ctx); | |
4113 | + gen_addr_imm_index(ctx, 0); | |
4106 | 4114 | op_POWER2_lfq(); |
4107 | 4115 | gen_op_store_FT0_fpr(rD(ctx->opcode)); |
4108 | 4116 | gen_op_store_FT1_fpr(rD(ctx->opcode) + 1); |
... | ... | @@ -4115,7 +4123,7 @@ GEN_HANDLER(lfqu, 0x39, 0xFF, 0xFF, 0x00000003, PPC_POWER2) |
4115 | 4123 | |
4116 | 4124 | /* NIP cannot be restored if the memory exception comes from an helper */ |
4117 | 4125 | gen_update_nip(ctx, ctx->nip - 4); |
4118 | - gen_addr_imm_index(ctx); | |
4126 | + gen_addr_imm_index(ctx, 0); | |
4119 | 4127 | op_POWER2_lfq(); |
4120 | 4128 | gen_op_store_FT0_fpr(rD(ctx->opcode)); |
4121 | 4129 | gen_op_store_FT1_fpr(rD(ctx->opcode) + 1); |
... | ... | @@ -4154,7 +4162,7 @@ GEN_HANDLER(stfq, 0x3C, 0xFF, 0xFF, 0x00000003, PPC_POWER2) |
4154 | 4162 | { |
4155 | 4163 | /* NIP cannot be restored if the memory exception comes from an helper */ |
4156 | 4164 | gen_update_nip(ctx, ctx->nip - 4); |
4157 | - gen_addr_imm_index(ctx); | |
4165 | + gen_addr_imm_index(ctx, 0); | |
4158 | 4166 | gen_op_load_fpr_FT0(rS(ctx->opcode)); |
4159 | 4167 | gen_op_load_fpr_FT1(rS(ctx->opcode) + 1); |
4160 | 4168 | op_POWER2_stfq(); |
... | ... | @@ -4167,7 +4175,7 @@ GEN_HANDLER(stfqu, 0x3D, 0xFF, 0xFF, 0x00000003, PPC_POWER2) |
4167 | 4175 | |
4168 | 4176 | /* NIP cannot be restored if the memory exception comes from an helper */ |
4169 | 4177 | gen_update_nip(ctx, ctx->nip - 4); |
4170 | - gen_addr_imm_index(ctx); | |
4178 | + gen_addr_imm_index(ctx, 0); | |
4171 | 4179 | gen_op_load_fpr_FT0(rS(ctx->opcode)); |
4172 | 4180 | gen_op_load_fpr_FT1(rS(ctx->opcode) + 1); |
4173 | 4181 | op_POWER2_stfq(); | ... | ... |