Commit 51789c410beb34423b1188a6b6e069fe8b68aebe

Authored by j_mayer
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
target-ppc/cpu.h
@@ -23,13 +23,18 @@ @@ -23,13 +23,18 @@
23 #include "config.h" 23 #include "config.h"
24 #include <stdint.h> 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 #if defined (TARGET_PPC64) 33 #if defined (TARGET_PPC64)
27 typedef uint64_t ppc_gpr_t; 34 typedef uint64_t ppc_gpr_t;
28 #define TARGET_LONG_BITS 64 35 #define TARGET_LONG_BITS 64
29 #define TARGET_GPR_BITS 64 36 #define TARGET_GPR_BITS 64
30 #define REGX "%016" PRIx64 37 #define REGX "%016" PRIx64
31 -/* We can safely use PowerPC SPE extension when compiling PowerPC 64 */  
32 -#define TARGET_PPCSPE  
33 #elif defined(TARGET_PPCSPE) 38 #elif defined(TARGET_PPCSPE)
34 /* GPR are 64 bits: used by vector extension */ 39 /* GPR are 64 bits: used by vector extension */
35 typedef uint64_t ppc_gpr_t; 40 typedef uint64_t ppc_gpr_t;
target-ppc/op.c
@@ -1444,6 +1444,20 @@ void OPPROTO op_rotli32_T0 (void) @@ -1444,6 +1444,20 @@ void OPPROTO op_rotli32_T0 (void)
1444 RETURN(); 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 /*** Integer shift ***/ 1461 /*** Integer shift ***/
1448 /* shift left word */ 1462 /* shift left word */
1449 void OPPROTO op_slw (void) 1463 void OPPROTO op_slw (void)
target-ppc/translate.c
@@ -1109,12 +1109,10 @@ GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER) @@ -1109,12 +1109,10 @@ GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
1109 { 1109 {
1110 target_ulong mask; 1110 target_ulong mask;
1111 uint32_t mb, me, sh; 1111 uint32_t mb, me, sh;
1112 - int n;  
1113 1112
1114 mb = MB(ctx->opcode); 1113 mb = MB(ctx->opcode);
1115 me = ME(ctx->opcode); 1114 me = ME(ctx->opcode);
1116 sh = SH(ctx->opcode); 1115 sh = SH(ctx->opcode);
1117 - n = me + 1 - mb;  
1118 if (likely(sh == 0)) { 1116 if (likely(sh == 0)) {
1119 if (likely(mb == 0 && me == 31)) { 1117 if (likely(mb == 0 && me == 31)) {
1120 gen_op_load_gpr_T0(rS(ctx->opcode)); 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,68 +1229,130 @@ GEN_HANDLER(name##3, opc1, opc2 | 0x11, 0xFF, 0x00000000, PPC_64B) \
1231 { \ 1229 { \
1232 gen_##name(ctx, 1, 1); \ 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 /* rldicl - rldicl. */ 1262 /* rldicl - rldicl. */
1235 static inline void gen_rldicl (DisasContext *ctx, int mbn, int shn) 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 sh = SH(ctx->opcode) | (1 << shn); 1267 sh = SH(ctx->opcode) | (1 << shn);
1240 mb = (MB(ctx->opcode) << 1) | mbn; 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 /* rldicr - rldicr. */ 1272 /* rldicr - rldicr. */
1246 static inline void gen_rldicr (DisasContext *ctx, int men, int shn) 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 sh = SH(ctx->opcode) | (1 << shn); 1277 sh = SH(ctx->opcode) | (1 << shn);
1251 me = (MB(ctx->opcode) << 1) | men; 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 /* rldic - rldic. */ 1282 /* rldic - rldic. */
1257 static inline void gen_rldic (DisasContext *ctx, int mbn, int shn) 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 sh = SH(ctx->opcode) | (1 << shn); 1287 sh = SH(ctx->opcode) | (1 << shn);
1262 mb = (MB(ctx->opcode) << 1) | mbn; 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 /* rldcl - rldcl. */ 1306 /* rldcl - rldcl. */
1268 static inline void gen_rldcl (DisasContext *ctx, int mbn) 1307 static inline void gen_rldcl (DisasContext *ctx, int mbn)
1269 { 1308 {
1270 - int mb; 1309 + uint32_t mb;
1271 1310
1272 mb = (MB(ctx->opcode) << 1) | mbn; 1311 mb = (MB(ctx->opcode) << 1) | mbn;
1273 - /* XXX: TODO */  
1274 - RET_INVAL(ctx); 1312 + gen_rldnm(ctx, mb, 63);
1275 } 1313 }
1276 GEN_PPC64_R2(rldcl, 0x1E, 0x08) 1314 GEN_PPC64_R2(rldcl, 0x1E, 0x08)
1277 /* rldcr - rldcr. */ 1315 /* rldcr - rldcr. */
1278 static inline void gen_rldcr (DisasContext *ctx, int men) 1316 static inline void gen_rldcr (DisasContext *ctx, int men)
1279 { 1317 {
1280 - int me; 1318 + uint32_t me;
1281 1319
1282 me = (MB(ctx->opcode) << 1) | men; 1320 me = (MB(ctx->opcode) << 1) | men;
1283 - /* XXX: TODO */  
1284 - RET_INVAL(ctx); 1321 + gen_rldnm(ctx, 0, me);
1285 } 1322 }
1286 GEN_PPC64_R2(rldcr, 0x1E, 0x09) 1323 GEN_PPC64_R2(rldcr, 0x1E, 0x09)
1287 /* rldimi - rldimi. */ 1324 /* rldimi - rldimi. */
1288 static inline void gen_rldimi (DisasContext *ctx, int mbn, int shn) 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 sh = SH(ctx->opcode) | (1 << shn); 1330 sh = SH(ctx->opcode) | (1 << shn);
1293 mb = (MB(ctx->opcode) << 1) | mbn; 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 GEN_PPC64_R4(rldimi, 0x1E, 0x06) 1357 GEN_PPC64_R4(rldimi, 0x1E, 0x06)
1298 #endif 1358 #endif