Commit 2b0233abfb42d42c2ac1fb3d73953218f5e30b39

Authored by ths
1 parent c596defd

Switch bitfield instructions and assorted special ops to TCG.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4739 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/helper.h
... ... @@ -204,5 +204,24 @@ FOP_PROTO(ngt)
204 204 #undef FOP_PROTO
205 205  
206 206 /* Special functions */
  207 +DEF_HELPER(void, do_di, (void))
  208 +DEF_HELPER(void, do_ei, (void))
  209 +DEF_HELPER(void, do_eret, (void))
  210 +DEF_HELPER(void, do_deret, (void))
  211 +DEF_HELPER(void, do_rdhwr_cpunum, (void))
  212 +DEF_HELPER(void, do_rdhwr_synci_step, (void))
  213 +DEF_HELPER(void, do_rdhwr_cc, (void))
  214 +DEF_HELPER(void, do_rdhwr_ccres, (void))
207 215 DEF_HELPER(void, do_pmon, (int function))
208 216 DEF_HELPER(void, do_wait, (void))
  217 +
  218 +/* Bitfield operations. */
  219 +DEF_HELPER(void, do_ext, (uint32_t pos, uint32_t size))
  220 +DEF_HELPER(void, do_ins, (uint32_t pos, uint32_t size))
  221 +DEF_HELPER(void, do_wsbh, (void))
  222 +#ifdef TARGET_MIPS64
  223 +DEF_HELPER(void, do_dext, (uint32_t pos, uint32_t size))
  224 +DEF_HELPER(void, do_dins, (uint32_t pos, uint32_t size))
  225 +DEF_HELPER(void, do_dsbh, (void))
  226 +DEF_HELPER(void, do_dshd, (void))
  227 +#endif
... ...
target-mips/op.c
... ... @@ -661,153 +661,3 @@ void op_bc1any4t (void)
661 661 DEBUG_FPU_STATE();
662 662 FORCE_RET();
663 663 }
664   -
665   -/* Specials */
666   -void op_di (void)
667   -{
668   - T0 = env->CP0_Status;
669   - env->CP0_Status = T0 & ~(1 << CP0St_IE);
670   - CALL_FROM_TB1(cpu_mips_update_irq, env);
671   - FORCE_RET();
672   -}
673   -
674   -void op_ei (void)
675   -{
676   - T0 = env->CP0_Status;
677   - env->CP0_Status = T0 | (1 << CP0St_IE);
678   - CALL_FROM_TB1(cpu_mips_update_irq, env);
679   - FORCE_RET();
680   -}
681   -
682   -void debug_pre_eret (void);
683   -void debug_post_eret (void);
684   -void op_eret (void)
685   -{
686   - if (loglevel & CPU_LOG_EXEC)
687   - CALL_FROM_TB0(debug_pre_eret);
688   - if (env->CP0_Status & (1 << CP0St_ERL)) {
689   - env->PC[env->current_tc] = env->CP0_ErrorEPC;
690   - env->CP0_Status &= ~(1 << CP0St_ERL);
691   - } else {
692   - env->PC[env->current_tc] = env->CP0_EPC;
693   - env->CP0_Status &= ~(1 << CP0St_EXL);
694   - }
695   - CALL_FROM_TB1(compute_hflags, env);
696   - if (loglevel & CPU_LOG_EXEC)
697   - CALL_FROM_TB0(debug_post_eret);
698   - env->CP0_LLAddr = 1;
699   - FORCE_RET();
700   -}
701   -
702   -void op_deret (void)
703   -{
704   - if (loglevel & CPU_LOG_EXEC)
705   - CALL_FROM_TB0(debug_pre_eret);
706   - env->PC[env->current_tc] = env->CP0_DEPC;
707   - env->hflags &= MIPS_HFLAG_DM;
708   - CALL_FROM_TB1(compute_hflags, env);
709   - if (loglevel & CPU_LOG_EXEC)
710   - CALL_FROM_TB0(debug_post_eret);
711   - env->CP0_LLAddr = 1;
712   - FORCE_RET();
713   -}
714   -
715   -void op_rdhwr_cpunum(void)
716   -{
717   - if ((env->hflags & MIPS_HFLAG_CP0) ||
718   - (env->CP0_HWREna & (1 << 0)))
719   - T0 = env->CP0_EBase & 0x3ff;
720   - else
721   - CALL_FROM_TB1(do_raise_exception, EXCP_RI);
722   - FORCE_RET();
723   -}
724   -
725   -void op_rdhwr_synci_step(void)
726   -{
727   - if ((env->hflags & MIPS_HFLAG_CP0) ||
728   - (env->CP0_HWREna & (1 << 1)))
729   - T0 = env->SYNCI_Step;
730   - else
731   - CALL_FROM_TB1(do_raise_exception, EXCP_RI);
732   - FORCE_RET();
733   -}
734   -
735   -void op_rdhwr_cc(void)
736   -{
737   - if ((env->hflags & MIPS_HFLAG_CP0) ||
738   - (env->CP0_HWREna & (1 << 2)))
739   - T0 = env->CP0_Count;
740   - else
741   - CALL_FROM_TB1(do_raise_exception, EXCP_RI);
742   - FORCE_RET();
743   -}
744   -
745   -void op_rdhwr_ccres(void)
746   -{
747   - if ((env->hflags & MIPS_HFLAG_CP0) ||
748   - (env->CP0_HWREna & (1 << 3)))
749   - T0 = env->CCRes;
750   - else
751   - CALL_FROM_TB1(do_raise_exception, EXCP_RI);
752   - FORCE_RET();
753   -}
754   -
755   -/* Bitfield operations. */
756   -void op_ext(void)
757   -{
758   - unsigned int pos = PARAM1;
759   - unsigned int size = PARAM2;
760   -
761   - T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
762   - FORCE_RET();
763   -}
764   -
765   -void op_ins(void)
766   -{
767   - unsigned int pos = PARAM1;
768   - unsigned int size = PARAM2;
769   - target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
770   -
771   - T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
772   - FORCE_RET();
773   -}
774   -
775   -void op_wsbh(void)
776   -{
777   - T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
778   - FORCE_RET();
779   -}
780   -
781   -#if defined(TARGET_MIPS64)
782   -void op_dext(void)
783   -{
784   - unsigned int pos = PARAM1;
785   - unsigned int size = PARAM2;
786   -
787   - T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
788   - FORCE_RET();
789   -}
790   -
791   -void op_dins(void)
792   -{
793   - unsigned int pos = PARAM1;
794   - unsigned int size = PARAM2;
795   - target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
796   -
797   - T0 = (T0 & ~mask) | ((T1 << pos) & mask);
798   - FORCE_RET();
799   -}
800   -
801   -void op_dsbh(void)
802   -{
803   - T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
804   - FORCE_RET();
805   -}
806   -
807   -void op_dshd(void)
808   -{
809   - T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
810   - T0 = (T1 << 32) | (T1 >> 32);
811   - FORCE_RET();
812   -}
813   -#endif
... ...
target-mips/op_helper.c
... ... @@ -1348,6 +1348,21 @@ void dump_sc (void)
1348 1348 }
1349 1349 }
1350 1350  
  1351 +/* Specials */
  1352 +void do_di (void)
  1353 +{
  1354 + T0 = env->CP0_Status;
  1355 + env->CP0_Status = T0 & ~(1 << CP0St_IE);
  1356 + cpu_mips_update_irq(env);
  1357 +}
  1358 +
  1359 +void do_ei (void)
  1360 +{
  1361 + T0 = env->CP0_Status;
  1362 + env->CP0_Status = T0 | (1 << CP0St_IE);
  1363 + cpu_mips_update_irq(env);
  1364 +}
  1365 +
1351 1366 void debug_pre_eret (void)
1352 1367 {
1353 1368 fprintf(logfile, "ERET: PC " TARGET_FMT_lx " EPC " TARGET_FMT_lx,
... ... @@ -1375,6 +1390,114 @@ void debug_post_eret (void)
1375 1390 }
1376 1391 }
1377 1392  
  1393 +void do_eret (void)
  1394 +{
  1395 + if (loglevel & CPU_LOG_EXEC)
  1396 + debug_pre_eret();
  1397 + if (env->CP0_Status & (1 << CP0St_ERL)) {
  1398 + env->PC[env->current_tc] = env->CP0_ErrorEPC;
  1399 + env->CP0_Status &= ~(1 << CP0St_ERL);
  1400 + } else {
  1401 + env->PC[env->current_tc] = env->CP0_EPC;
  1402 + env->CP0_Status &= ~(1 << CP0St_EXL);
  1403 + }
  1404 + compute_hflags(env);
  1405 + if (loglevel & CPU_LOG_EXEC)
  1406 + debug_post_eret();
  1407 + env->CP0_LLAddr = 1;
  1408 +}
  1409 +
  1410 +void do_deret (void)
  1411 +{
  1412 + if (loglevel & CPU_LOG_EXEC)
  1413 + debug_pre_eret();
  1414 + env->PC[env->current_tc] = env->CP0_DEPC;
  1415 + env->hflags &= MIPS_HFLAG_DM;
  1416 + compute_hflags(env);
  1417 + if (loglevel & CPU_LOG_EXEC)
  1418 + debug_post_eret();
  1419 + env->CP0_LLAddr = 1;
  1420 +}
  1421 +
  1422 +void do_rdhwr_cpunum(void)
  1423 +{
  1424 + if ((env->hflags & MIPS_HFLAG_CP0) ||
  1425 + (env->CP0_HWREna & (1 << 0)))
  1426 + T0 = env->CP0_EBase & 0x3ff;
  1427 + else
  1428 + do_raise_exception(EXCP_RI);
  1429 +}
  1430 +
  1431 +void do_rdhwr_synci_step(void)
  1432 +{
  1433 + if ((env->hflags & MIPS_HFLAG_CP0) ||
  1434 + (env->CP0_HWREna & (1 << 1)))
  1435 + T0 = env->SYNCI_Step;
  1436 + else
  1437 + do_raise_exception(EXCP_RI);
  1438 +}
  1439 +
  1440 +void do_rdhwr_cc(void)
  1441 +{
  1442 + if ((env->hflags & MIPS_HFLAG_CP0) ||
  1443 + (env->CP0_HWREna & (1 << 2)))
  1444 + T0 = env->CP0_Count;
  1445 + else
  1446 + do_raise_exception(EXCP_RI);
  1447 +}
  1448 +
  1449 +void do_rdhwr_ccres(void)
  1450 +{
  1451 + if ((env->hflags & MIPS_HFLAG_CP0) ||
  1452 + (env->CP0_HWREna & (1 << 3)))
  1453 + T0 = env->CCRes;
  1454 + else
  1455 + do_raise_exception(EXCP_RI);
  1456 +}
  1457 +
  1458 +/* Bitfield operations. */
  1459 +void do_ext(uint32_t pos, uint32_t size)
  1460 +{
  1461 + T0 = (int32_t)((T1 >> pos) & ((size < 32) ? ((1 << size) - 1) : ~0));
  1462 +}
  1463 +
  1464 +void do_ins(uint32_t pos, uint32_t size)
  1465 +{
  1466 + target_ulong mask = ((size < 32) ? ((1 << size) - 1) : ~0) << pos;
  1467 +
  1468 + T0 = (int32_t)((T0 & ~mask) | ((T1 << pos) & mask));
  1469 +}
  1470 +
  1471 +void do_wsbh(void)
  1472 +{
  1473 + T0 = (int32_t)(((T1 << 8) & ~0x00FF00FF) | ((T1 >> 8) & 0x00FF00FF));
  1474 +}
  1475 +
  1476 +#if defined(TARGET_MIPS64)
  1477 +void do_dext(uint32_t pos, uint32_t size)
  1478 +{
  1479 + T0 = (T1 >> pos) & ((size < 64) ? ((1ULL << size) - 1) : ~0ULL);
  1480 +}
  1481 +
  1482 +void do_dins(uint32_t pos, uint32_t size)
  1483 +{
  1484 + target_ulong mask = ((size < 64) ? ((1ULL << size) - 1) : ~0ULL) << pos;
  1485 +
  1486 + T0 = (T0 & ~mask) | ((T1 << pos) & mask);
  1487 +}
  1488 +
  1489 +void do_dsbh(void)
  1490 +{
  1491 + T0 = ((T1 << 8) & ~0x00FF00FF00FF00FFULL) | ((T1 >> 8) & 0x00FF00FF00FF00FFULL);
  1492 +}
  1493 +
  1494 +void do_dshd(void)
  1495 +{
  1496 + T1 = ((T1 << 16) & ~0x0000FFFF0000FFFFULL) | ((T1 >> 16) & 0x0000FFFF0000FFFFULL);
  1497 + T0 = (T1 << 32) | (T1 >> 32);
  1498 +}
  1499 +#endif
  1500 +
1378 1501 void do_pmon (int function)
1379 1502 {
1380 1503 function /= 2;
... ...
target-mips/translate.c
... ... @@ -2512,49 +2512,49 @@ static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2512 2512 case OPC_EXT:
2513 2513 if (lsb + msb > 31)
2514 2514 goto fail;
2515   - gen_op_ext(lsb, msb + 1);
  2515 + tcg_gen_helper_0_2ii(do_ext, lsb, msb + 1);
2516 2516 break;
2517 2517 #if defined(TARGET_MIPS64)
2518 2518 case OPC_DEXTM:
2519 2519 if (lsb + msb > 63)
2520 2520 goto fail;
2521   - gen_op_dext(lsb, msb + 1 + 32);
  2521 + tcg_gen_helper_0_2ii(do_dext, lsb, msb + 1 + 32);
2522 2522 break;
2523 2523 case OPC_DEXTU:
2524 2524 if (lsb + msb > 63)
2525 2525 goto fail;
2526   - gen_op_dext(lsb + 32, msb + 1);
  2526 + tcg_gen_helper_0_2ii(do_dext, lsb + 32, msb + 1);
2527 2527 break;
2528 2528 case OPC_DEXT:
2529 2529 if (lsb + msb > 63)
2530 2530 goto fail;
2531   - gen_op_dext(lsb, msb + 1);
  2531 + tcg_gen_helper_0_2ii(do_dext, lsb, msb + 1);
2532 2532 break;
2533 2533 #endif
2534 2534 case OPC_INS:
2535 2535 if (lsb > msb)
2536 2536 goto fail;
2537 2537 gen_load_gpr(cpu_T[0], rt);
2538   - gen_op_ins(lsb, msb - lsb + 1);
  2538 + tcg_gen_helper_0_2ii(do_ins, lsb, msb - lsb + 1);
2539 2539 break;
2540 2540 #if defined(TARGET_MIPS64)
2541 2541 case OPC_DINSM:
2542 2542 if (lsb > msb)
2543 2543 goto fail;
2544 2544 gen_load_gpr(cpu_T[0], rt);
2545   - gen_op_dins(lsb, msb - lsb + 1 + 32);
  2545 + tcg_gen_helper_0_2ii(do_dins, lsb, msb - lsb + 1 + 32);
2546 2546 break;
2547 2547 case OPC_DINSU:
2548 2548 if (lsb > msb)
2549 2549 goto fail;
2550 2550 gen_load_gpr(cpu_T[0], rt);
2551   - gen_op_dins(lsb + 32, msb - lsb + 1);
  2551 + tcg_gen_helper_0_2ii(do_dins, lsb + 32, msb - lsb + 1);
2552 2552 break;
2553 2553 case OPC_DINS:
2554 2554 if (lsb > msb)
2555 2555 goto fail;
2556 2556 gen_load_gpr(cpu_T[0], rt);
2557   - gen_op_dins(lsb, msb - lsb + 1);
  2557 + tcg_gen_helper_0_2ii(do_dins, lsb, msb - lsb + 1);
2558 2558 break;
2559 2559 #endif
2560 2560 default:
... ... @@ -5348,7 +5348,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
5348 5348 opn = "eret";
5349 5349 check_insn(env, ctx, ISA_MIPS2);
5350 5350 save_cpu_state(ctx, 1);
5351   - gen_op_eret();
  5351 + tcg_gen_helper_0_0(do_eret);
5352 5352 ctx->bstate = BS_EXCP;
5353 5353 break;
5354 5354 case OPC_DERET:
... ... @@ -5359,7 +5359,7 @@ static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int
5359 5359 generate_exception(ctx, EXCP_RI);
5360 5360 } else {
5361 5361 save_cpu_state(ctx, 1);
5362   - gen_op_deret();
  5362 + tcg_gen_helper_0_0(do_deret);
5363 5363 ctx->bstate = BS_EXCP;
5364 5364 }
5365 5365 break;
... ... @@ -6792,33 +6792,33 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6792 6792 }
6793 6793 break;
6794 6794 case OPC_SPECIAL3:
6795   - op1 = MASK_SPECIAL3(ctx->opcode);
6796   - switch (op1) {
6797   - case OPC_EXT:
6798   - case OPC_INS:
6799   - check_insn(env, ctx, ISA_MIPS32R2);
6800   - gen_bitops(ctx, op1, rt, rs, sa, rd);
6801   - break;
6802   - case OPC_BSHFL:
6803   - check_insn(env, ctx, ISA_MIPS32R2);
6804   - op2 = MASK_BSHFL(ctx->opcode);
6805   - switch (op2) {
6806   - case OPC_WSBH:
6807   - gen_load_gpr(cpu_T[1], rt);
6808   - gen_op_wsbh();
6809   - break;
6810   - case OPC_SEB:
6811   - gen_load_gpr(cpu_T[1], rt);
6812   - tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]);
6813   - break;
6814   - case OPC_SEH:
6815   - gen_load_gpr(cpu_T[1], rt);
6816   - tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]);
6817   - break;
6818   - default: /* Invalid */
6819   - MIPS_INVAL("bshfl");
6820   - generate_exception(ctx, EXCP_RI);
6821   - break;
  6795 + op1 = MASK_SPECIAL3(ctx->opcode);
  6796 + switch (op1) {
  6797 + case OPC_EXT:
  6798 + case OPC_INS:
  6799 + check_insn(env, ctx, ISA_MIPS32R2);
  6800 + gen_bitops(ctx, op1, rt, rs, sa, rd);
  6801 + break;
  6802 + case OPC_BSHFL:
  6803 + check_insn(env, ctx, ISA_MIPS32R2);
  6804 + op2 = MASK_BSHFL(ctx->opcode);
  6805 + switch (op2) {
  6806 + case OPC_WSBH:
  6807 + gen_load_gpr(cpu_T[1], rt);
  6808 + tcg_gen_helper_0_0(do_wsbh);
  6809 + break;
  6810 + case OPC_SEB:
  6811 + gen_load_gpr(cpu_T[1], rt);
  6812 + tcg_gen_ext8s_tl(cpu_T[0], cpu_T[1]);
  6813 + break;
  6814 + case OPC_SEH:
  6815 + gen_load_gpr(cpu_T[1], rt);
  6816 + tcg_gen_ext16s_tl(cpu_T[0], cpu_T[1]);
  6817 + break;
  6818 + default: /* Invalid */
  6819 + MIPS_INVAL("bshfl");
  6820 + generate_exception(ctx, EXCP_RI);
  6821 + break;
6822 6822 }
6823 6823 gen_store_gpr(cpu_T[0], rd);
6824 6824 break;
... ... @@ -6827,24 +6827,26 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6827 6827 switch (rd) {
6828 6828 case 0:
6829 6829 save_cpu_state(ctx, 1);
6830   - gen_op_rdhwr_cpunum();
  6830 + tcg_gen_helper_0_0(do_rdhwr_cpunum);
6831 6831 break;
6832 6832 case 1:
6833 6833 save_cpu_state(ctx, 1);
6834   - gen_op_rdhwr_synci_step();
  6834 + tcg_gen_helper_0_0(do_rdhwr_synci_step);
6835 6835 break;
6836 6836 case 2:
6837 6837 save_cpu_state(ctx, 1);
6838   - gen_op_rdhwr_cc();
  6838 + tcg_gen_helper_0_0(do_rdhwr_cc);
6839 6839 break;
6840 6840 case 3:
6841 6841 save_cpu_state(ctx, 1);
6842   - gen_op_rdhwr_ccres();
  6842 + tcg_gen_helper_0_0(do_rdhwr_ccres);
6843 6843 break;
6844 6844 case 29:
6845 6845 #if defined (CONFIG_USER_ONLY)
6846 6846 tcg_gen_ld_tl(cpu_T[0], cpu_env, offsetof(CPUState, tls_value));
6847 6847 break;
  6848 +#else
  6849 + /* XXX: Some CPUs implement this in hardware. Not supported yet. */
6848 6850 #endif
6849 6851 default: /* Invalid */
6850 6852 MIPS_INVAL("rdhwr");
... ... @@ -6879,11 +6881,11 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6879 6881 switch (op2) {
6880 6882 case OPC_DSBH:
6881 6883 gen_load_gpr(cpu_T[1], rt);
6882   - gen_op_dsbh();
  6884 + tcg_gen_helper_0_0(do_dsbh);
6883 6885 break;
6884 6886 case OPC_DSHD:
6885 6887 gen_load_gpr(cpu_T[1], rt);
6886   - gen_op_dshd();
  6888 + tcg_gen_helper_0_0(do_dshd);
6887 6889 break;
6888 6890 default: /* Invalid */
6889 6891 MIPS_INVAL("dbshfl");
... ... @@ -6963,14 +6965,14 @@ static void decode_opc (CPUState *env, DisasContext *ctx)
6963 6965 case OPC_DI:
6964 6966 check_insn(env, ctx, ISA_MIPS32R2);
6965 6967 save_cpu_state(ctx, 1);
6966   - gen_op_di();
  6968 + tcg_gen_helper_0_0(do_di);
6967 6969 /* Stop translation as we may have switched the execution mode */
6968 6970 ctx->bstate = BS_STOP;
6969 6971 break;
6970 6972 case OPC_EI:
6971 6973 check_insn(env, ctx, ISA_MIPS32R2);
6972 6974 save_cpu_state(ctx, 1);
6973   - gen_op_ei();
  6975 + tcg_gen_helper_0_0(do_ei);
6974 6976 /* Stop translation as we may have switched the execution mode */
6975 6977 ctx->bstate = BS_STOP;
6976 6978 break;
... ...