Commit 51789c410beb34423b1188a6b6e069fe8b68aebe
1 parent
e864cabd
PowerPC improvments:
- add missing 64 bits rotate instructions - safely define TARGET_PPCSPE when 64 bits registers are used a separate target will be needed to use it in 32 bits mode on 32 bits hosts. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2527 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
104 additions
and
25 deletions
target-ppc/cpu.h
| ... | ... | @@ -23,13 +23,18 @@ |
| 23 | 23 | #include "config.h" |
| 24 | 24 | #include <stdint.h> |
| 25 | 25 | |
| 26 | +#if defined(TARGET_PPC64) || (HOST_LONG_BITS >= 64) | |
| 27 | +/* When using 64 bits temporary registers, | |
| 28 | + * we can use 64 bits GPR with no extra cost | |
| 29 | + */ | |
| 30 | +#define TARGET_PPCSPE | |
| 31 | +#endif | |
| 32 | + | |
| 26 | 33 | #if defined (TARGET_PPC64) |
| 27 | 34 | typedef uint64_t ppc_gpr_t; |
| 28 | 35 | #define TARGET_LONG_BITS 64 |
| 29 | 36 | #define TARGET_GPR_BITS 64 |
| 30 | 37 | #define REGX "%016" PRIx64 |
| 31 | -/* We can safely use PowerPC SPE extension when compiling PowerPC 64 */ | |
| 32 | -#define TARGET_PPCSPE | |
| 33 | 38 | #elif defined(TARGET_PPCSPE) |
| 34 | 39 | /* GPR are 64 bits: used by vector extension */ |
| 35 | 40 | typedef uint64_t ppc_gpr_t; | ... | ... |
target-ppc/op.c
| ... | ... | @@ -1444,6 +1444,20 @@ void OPPROTO op_rotli32_T0 (void) |
| 1444 | 1444 | RETURN(); |
| 1445 | 1445 | } |
| 1446 | 1446 | |
| 1447 | +#if defined(TARGET_PPC64) | |
| 1448 | +void OPPROTO op_rotl64_T0_T1 (void) | |
| 1449 | +{ | |
| 1450 | + T0 = rotl64(T0, T1 & 0x3F); | |
| 1451 | + RETURN(); | |
| 1452 | +} | |
| 1453 | + | |
| 1454 | +void OPPROTO op_rotli64_T0 (void) | |
| 1455 | +{ | |
| 1456 | + T0 = rotl64(T0, PARAM1); | |
| 1457 | + RETURN(); | |
| 1458 | +} | |
| 1459 | +#endif | |
| 1460 | + | |
| 1447 | 1461 | /*** Integer shift ***/ |
| 1448 | 1462 | /* shift left word */ |
| 1449 | 1463 | void OPPROTO op_slw (void) | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -1109,12 +1109,10 @@ GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) |
| 1109 | 1109 | { |
| 1110 | 1110 | target_ulong mask; |
| 1111 | 1111 | uint32_t mb, me, sh; |
| 1112 | - int n; | |
| 1113 | 1112 | |
| 1114 | 1113 | mb = MB(ctx->opcode); |
| 1115 | 1114 | me = ME(ctx->opcode); |
| 1116 | 1115 | sh = SH(ctx->opcode); |
| 1117 | - n = me + 1 - mb; | |
| 1118 | 1116 | if (likely(sh == 0)) { |
| 1119 | 1117 | if (likely(mb == 0 && me == 31)) { |
| 1120 | 1118 | gen_op_load_gpr_T0(rS(ctx->opcode)); |
| ... | ... | @@ -1231,68 +1229,130 @@ GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B) \ |
| 1231 | 1229 | { \ |
| 1232 | 1230 | gen_##name(ctx, 1, 1); \ |
| 1233 | 1231 | } |
| 1232 | + | |
| 1233 | +static inline void gen_rldinm (DisasContext *ctx, uint32_t mb, uint32_t me, | |
| 1234 | + uint32_t sh) | |
| 1235 | +{ | |
| 1236 | + gen_op_load_gpr_T0(rS(ctx->opcode)); | |
| 1237 | + if (likely(sh == 0)) { | |
| 1238 | + goto do_mask; | |
| 1239 | + } | |
| 1240 | + if (likely(mb == 0)) { | |
| 1241 | + if (likely(me == 63)) { | |
| 1242 | + gen_op_rotli32_T0(sh); | |
| 1243 | + goto do_store; | |
| 1244 | + } else if (likely(me == (63 - sh))) { | |
| 1245 | + gen_op_sli_T0(sh); | |
| 1246 | + goto do_store; | |
| 1247 | + } | |
| 1248 | + } else if (likely(me == 63)) { | |
| 1249 | + if (likely(sh == (64 - mb))) { | |
| 1250 | + gen_op_srli_T0(mb); | |
| 1251 | + goto do_store; | |
| 1252 | + } | |
| 1253 | + } | |
| 1254 | + gen_op_rotli64_T0(sh); | |
| 1255 | + do_mask: | |
| 1256 | + gen_op_andi_T0(MASK(mb, me)); | |
| 1257 | + do_store: | |
| 1258 | + gen_op_store_T0_gpr(rA(ctx->opcode)); | |
| 1259 | + if (unlikely(Rc(ctx->opcode) != 0)) | |
| 1260 | + gen_set_Rc0(ctx); | |
| 1261 | +} | |
| 1234 | 1262 | /* rldicl - rldicl. */ |
| 1235 | 1263 | static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn) |
| 1236 | 1264 | { |
| 1237 | - int sh, mb; | |
| 1265 | + uint32_t sh, mb; | |
| 1238 | 1266 | |
| 1239 | 1267 | sh = SH(ctx->opcode) | (1 << shn); |
| 1240 | 1268 | mb = (MB(ctx->opcode) << 1) | mbn; |
| 1241 | - /* XXX: TODO */ | |
| 1242 | - RET_INVAL(ctx); | |
| 1269 | + gen_rldinm(ctx, mb, 63, sh); | |
| 1243 | 1270 | } |
| 1244 | -GEN_PPC64_R4(rldicl, 0x1E, 0x00) | |
| 1271 | +GEN_PPC64_R4(rldicl, 0x1E, 0x00); | |
| 1245 | 1272 | /* rldicr - rldicr. */ |
| 1246 | 1273 | static inline void gen_rldicr (DisasContext *ctx, int men, int shn) |
| 1247 | 1274 | { |
| 1248 | - int sh, me; | |
| 1275 | + uint32_t sh, me; | |
| 1249 | 1276 | |
| 1250 | 1277 | sh = SH(ctx->opcode) | (1 << shn); |
| 1251 | 1278 | me = (MB(ctx->opcode) << 1) | men; |
| 1252 | - /* XXX: TODO */ | |
| 1253 | - RET_INVAL(ctx); | |
| 1279 | + gen_rldinm(ctx, 0, me, sh); | |
| 1254 | 1280 | } |
| 1255 | -GEN_PPC64_R4(rldicr, 0x1E, 0x02) | |
| 1281 | +GEN_PPC64_R4(rldicr, 0x1E, 0x02); | |
| 1256 | 1282 | /* rldic - rldic. */ |
| 1257 | 1283 | static inline void gen_rldic (DisasContext *ctx, int mbn, int shn) |
| 1258 | 1284 | { |
| 1259 | - int sh, mb; | |
| 1285 | + uint32_t sh, mb; | |
| 1260 | 1286 | |
| 1261 | 1287 | sh = SH(ctx->opcode) | (1 << shn); |
| 1262 | 1288 | mb = (MB(ctx->opcode) << 1) | mbn; |
| 1263 | - /* XXX: TODO */ | |
| 1264 | - RET_INVAL(ctx); | |
| 1289 | + gen_rldinm(ctx, mb, 63 - sh, sh); | |
| 1265 | 1290 | } |
| 1266 | -GEN_PPC64_R4(rldic, 0x1E, 0x04) | |
| 1291 | +GEN_PPC64_R4(rldic, 0x1E, 0x04); | |
| 1292 | + | |
| 1293 | +static inline void gen_rldnm (DisasContext *ctx, uint32_t mb, uint32_t me) | |
| 1294 | +{ | |
| 1295 | + gen_op_load_gpr_T0(rS(ctx->opcode)); | |
| 1296 | + gen_op_load_gpr_T1(rB(ctx->opcode)); | |
| 1297 | + gen_op_rotl64_T0_T1(); | |
| 1298 | + if (unlikely(mb != 0 || me != 63)) { | |
| 1299 | + gen_op_andi_T0(MASK(mb, me)); | |
| 1300 | + } | |
| 1301 | + gen_op_store_T0_gpr(rA(ctx->opcode)); | |
| 1302 | + if (unlikely(Rc(ctx->opcode) != 0)) | |
| 1303 | + gen_set_Rc0(ctx); | |
| 1304 | +} | |
| 1305 | + | |
| 1267 | 1306 | /* rldcl - rldcl. */ |
| 1268 | 1307 | static inline void gen_rldcl (DisasContext *ctx, int mbn) |
| 1269 | 1308 | { |
| 1270 | - int mb; | |
| 1309 | + uint32_t mb; | |
| 1271 | 1310 | |
| 1272 | 1311 | mb = (MB(ctx->opcode) << 1) | mbn; |
| 1273 | - /* XXX: TODO */ | |
| 1274 | - RET_INVAL(ctx); | |
| 1312 | + gen_rldnm(ctx, mb, 63); | |
| 1275 | 1313 | } |
| 1276 | 1314 | GEN_PPC64_R2(rldcl, 0x1E, 0x08) |
| 1277 | 1315 | /* rldcr - rldcr. */ |
| 1278 | 1316 | static inline void gen_rldcr (DisasContext *ctx, int men) |
| 1279 | 1317 | { |
| 1280 | - int me; | |
| 1318 | + uint32_t me; | |
| 1281 | 1319 | |
| 1282 | 1320 | me = (MB(ctx->opcode) << 1) | men; |
| 1283 | - /* XXX: TODO */ | |
| 1284 | - RET_INVAL(ctx); | |
| 1321 | + gen_rldnm(ctx, 0, me); | |
| 1285 | 1322 | } |
| 1286 | 1323 | GEN_PPC64_R2(rldcr, 0x1E, 0x09) |
| 1287 | 1324 | /* rldimi - rldimi. */ |
| 1288 | 1325 | static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn) |
| 1289 | 1326 | { |
| 1290 | - int sh, mb; | |
| 1327 | + uint64_t mask; | |
| 1328 | + uint32_t sh, mb; | |
| 1291 | 1329 | |
| 1292 | 1330 | sh = SH(ctx->opcode) | (1 << shn); |
| 1293 | 1331 | mb = (MB(ctx->opcode) << 1) | mbn; |
| 1294 | - /* XXX: TODO */ | |
| 1295 | - RET_INVAL(ctx); | |
| 1332 | + if (likely(sh == 0)) { | |
| 1333 | + if (likely(mb == 0)) { | |
| 1334 | + gen_op_load_gpr_T0(rS(ctx->opcode)); | |
| 1335 | + goto do_store; | |
| 1336 | + } else if (likely(mb == 63)) { | |
| 1337 | + gen_op_load_gpr_T0(rA(ctx->opcode)); | |
| 1338 | + goto do_store; | |
| 1339 | + } | |
| 1340 | + gen_op_load_gpr_T0(rS(ctx->opcode)); | |
| 1341 | + gen_op_load_gpr_T1(rA(ctx->opcode)); | |
| 1342 | + goto do_mask; | |
| 1343 | + } | |
| 1344 | + gen_op_load_gpr_T0(rS(ctx->opcode)); | |
| 1345 | + gen_op_load_gpr_T1(rA(ctx->opcode)); | |
| 1346 | + gen_op_rotli64_T0(SH(ctx->opcode)); | |
| 1347 | + do_mask: | |
| 1348 | + mask = MASK(mb, 63 - sh); | |
| 1349 | + gen_op_andi_T0(mask); | |
| 1350 | + gen_op_andi_T1(~mask); | |
| 1351 | + gen_op_or(); | |
| 1352 | + do_store: | |
| 1353 | + gen_op_store_T0_gpr(rA(ctx->opcode)); | |
| 1354 | + if (unlikely(Rc(ctx->opcode) != 0)) | |
| 1355 | + gen_set_Rc0(ctx); | |
| 1296 | 1356 | } |
| 1297 | 1357 | GEN_PPC64_R4(rldimi, 0x1E, 0x06) |
| 1298 | 1358 | #endif | ... | ... |