Commit e98a6e40a9d56e16e52a4a839eaa698b658b94e0

Authored by bellard
1 parent 28fbe299

adding direct block chaining support - simplified branch code gen


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@630 c046a42c-6fe2-441c-8c8c-71466251a162
target-ppc/op.c
... ... @@ -473,121 +473,94 @@ PPC_OP(setcrfbit)
473 473 }
474 474  
475 475 /* Branch */
476   -#if 0
477 476 #define EIP regs->nip
478   -#define TB_DO_JUMP(name, tb, n, target) JUMP_TB(name, tb, n, target)
479   -#else
480   -#define TB_DO_JUMP(name, tb, n, target) regs->nip = target;
481   -#endif
482 477  
483   -#define __PPC_OP_B(name, target) \
484   -PPC_OP(name) \
485   -{ \
486   - TB_DO_JUMP(glue(op_, name), T1, 0, (target)); \
487   - RETURN(); \
488   -}
489   -
490   -#define __PPC_OP_BL(name, target, link) \
491   -PPC_OP(name) \
492   -{ \
493   - regs->lr = (link); \
494   - TB_DO_JUMP(glue(op_, name), T1, 0, (target)); \
495   - RETURN(); \
496   -}
497   -
498   -#define PPC_OP_B(name, target, link) \
499   -__PPC_OP_B(name, target); \
500   -__PPC_OP_BL(glue(name, l), target, link)
501   -
502   -#define __PPC_OP_BC(name, cond, target) \
503   -PPC_OP(name) \
504   -{ \
505   - if (cond) { \
506   - TB_DO_JUMP(glue(op_, name), T1, 1, (target)); \
507   - } else { \
508   - TB_DO_JUMP(glue(op_, name), T1, 0, PARAM(1)); \
509   - } \
510   - RETURN(); \
511   -}
512   -
513   -#define __PPC_OP_BCL(name, cond, target) \
514   -PPC_OP(name) \
515   -{ \
516   - regs->lr = PARAM(1); \
517   - if (cond) { \
518   - TB_DO_JUMP(glue(op_, name), T1, 1, (target)); \
519   - } else { \
520   - TB_DO_JUMP(glue(op_, name), T1, 0, PARAM(1)); \
521   - } \
522   - RETURN(); \
523   -}
524   -
525   -#define __PPC_OP_BCLRL(name, cond, target) \
526   -PPC_OP(name) \
527   -{ \
528   - T2 = (target); \
529   - regs->lr = PARAM(1); \
530   - if (cond) { \
531   - TB_DO_JUMP(glue(op_, name), T1, 1, T2); \
532   - } else { \
533   - TB_DO_JUMP(glue(op_, name), T1, 0, PARAM(1)); \
534   - } \
535   - RETURN(); \
536   -}
537   -
538   -#define _PPC_OP_BC(name, namel, cond, target) \
539   -__PPC_OP_BC(name, cond, target); \
540   -__PPC_OP_BCL(namel, cond, target)
541   -
542   -/* Branch to target */
543   -#define PPC_OP_BC(name, cond) \
544   -_PPC_OP_BC(b_##name, bl_##name, cond, PARAM(2))
545   -
546   -PPC_OP_B(b, PARAM(1), PARAM(2));
547   -PPC_OP_BC(ctr, (regs->ctr != 0));
548   -PPC_OP_BC(ctr_true, (regs->ctr != 0 && (T0 & PARAM(3)) != 0));
549   -PPC_OP_BC(ctr_false, (regs->ctr != 0 && (T0 & PARAM(3)) == 0));
550   -PPC_OP_BC(ctrz, (regs->ctr == 0));
551   -PPC_OP_BC(ctrz_true, (regs->ctr == 0 && (T0 & PARAM(3)) != 0));
552   -PPC_OP_BC(ctrz_false, (regs->ctr == 0 && (T0 & PARAM(3)) == 0));
553   -PPC_OP_BC(true, ((T0 & PARAM(3)) != 0));
554   -PPC_OP_BC(false, ((T0 & PARAM(3)) == 0));
555   -
556   -/* Branch to CTR */
557   -#define PPC_OP_BCCTR(name, cond) \
558   -_PPC_OP_BC(bctr_##name, bctrl_##name, cond, regs->ctr & ~0x03)
559   -
560   -PPC_OP_B(bctr, regs->ctr & ~0x03, PARAM(1));
561   -PPC_OP_BCCTR(ctr, (regs->ctr != 0));
562   -PPC_OP_BCCTR(ctr_true, (regs->ctr != 0 && (T0 & PARAM(2)) != 0));
563   -PPC_OP_BCCTR(ctr_false, (regs->ctr != 0 && (T0 & PARAM(2)) == 0));
564   -PPC_OP_BCCTR(ctrz, (regs->ctr == 0));
565   -PPC_OP_BCCTR(ctrz_true, (regs->ctr == 0 && (T0 & PARAM(2)) != 0));
566   -PPC_OP_BCCTR(ctrz_false, (regs->ctr == 0 && (T0 & PARAM(2)) == 0));
567   -PPC_OP_BCCTR(true, ((T0 & PARAM(2)) != 0));
568   -PPC_OP_BCCTR(false, ((T0 & PARAM(2)) == 0));
569   -
570   -/* Branch to LR */
571   -#define PPC_OP_BCLR(name, cond) \
572   -__PPC_OP_BC(blr_##name, cond, regs->lr & ~0x03); \
573   -__PPC_OP_BCLRL(blrl_##name, cond, regs->lr & ~0x03)
574   -
575   -__PPC_OP_B(blr, regs->lr & ~0x03);
576   -PPC_OP(blrl)
577   -{
578   - T0 = regs->lr & ~0x03;
579   - regs->lr = PARAM(1);
580   - TB_DO_JUMP(op_blrl, T1, 0, T0);
581   - RETURN();
582   -}
583   -PPC_OP_BCLR(ctr, (regs->ctr != 0));
584   -PPC_OP_BCLR(ctr_true, (regs->ctr != 0 && (T0 & PARAM(2)) != 0));
585   -PPC_OP_BCLR(ctr_false, (regs->ctr != 0 && (T0 & PARAM(2)) == 0));
586   -PPC_OP_BCLR(ctrz, (regs->ctr == 0));
587   -PPC_OP_BCLR(ctrz_true, (regs->ctr == 0 && (T0 & PARAM(2)) != 0));
588   -PPC_OP_BCLR(ctrz_false, (regs->ctr == 0 && (T0 & PARAM(2)) == 0));
589   -PPC_OP_BCLR(true, ((T0 & PARAM(2)) != 0));
590   -PPC_OP_BCLR(false, ((T0 & PARAM(2)) == 0));
  478 +PPC_OP(setlr)
  479 +{
  480 + regs->lr = PARAM1;
  481 +}
  482 +
  483 +PPC_OP(b)
  484 +{
  485 + JUMP_TB(b1, PARAM1, 0, PARAM2);
  486 +}
  487 +
  488 +PPC_OP(b_T1)
  489 +{
  490 + regs->nip = T1;
  491 +}
  492 +
  493 +PPC_OP(btest)
  494 +{
  495 + if (T0) {
  496 + JUMP_TB(btest, PARAM1, 0, PARAM2);
  497 + } else {
  498 + JUMP_TB(btest, PARAM1, 1, PARAM3);
  499 + }
  500 + RETURN();
  501 +}
  502 +
  503 +PPC_OP(btest_T1)
  504 +{
  505 + if (T0) {
  506 + regs->nip = T1 & ~3;
  507 + } else {
  508 + regs->nip = PARAM1;
  509 + }
  510 + RETURN();
  511 +}
  512 +
  513 +PPC_OP(movl_T1_ctr)
  514 +{
  515 + T1 = regs->ctr;
  516 +}
  517 +
  518 +PPC_OP(movl_T1_lr)
  519 +{
  520 + T1 = regs->lr;
  521 +}
  522 +
  523 +/* tests with result in T0 */
  524 +
  525 +PPC_OP(test_ctr)
  526 +{
  527 + T0 = (regs->ctr != 0);
  528 +}
  529 +
  530 +PPC_OP(test_ctr_true)
  531 +{
  532 + T0 = (regs->ctr != 0 && (T0 & PARAM(1)) != 0);
  533 +}
  534 +
  535 +PPC_OP(test_ctr_false)
  536 +{
  537 + T0 = (regs->ctr != 0 && (T0 & PARAM(1)) == 0);
  538 +}
  539 +
  540 +PPC_OP(test_ctrz)
  541 +{
  542 + T0 = (regs->ctr == 0);
  543 +}
  544 +
  545 +PPC_OP(test_ctrz_true)
  546 +{
  547 + T0 = (regs->ctr == 0 && (T0 & PARAM(1)) != 0);
  548 +}
  549 +
  550 +PPC_OP(test_ctrz_false)
  551 +{
  552 + T0 = (regs->ctr == 0 && (T0 & PARAM(1)) == 0);
  553 +}
  554 +
  555 +PPC_OP(test_true)
  556 +{
  557 + T0 = ((T0 & PARAM(1)) != 0);
  558 +}
  559 +
  560 +PPC_OP(test_false)
  561 +{
  562 + T0 = ((T0 & PARAM(1)) == 0);
  563 +}
591 564  
592 565 /* CTR maintenance */
593 566 PPC_OP(dec_ctr)
... ...
target-ppc/translate.c
... ... @@ -1501,118 +1501,6 @@ GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1501 1501 }
1502 1502  
1503 1503 /*** Branch ***/
1504   -#define GEN_BCOND(name, opc1, opc2, opc3, prologue, \
1505   - bl_ctr, b_ctr, bl_ctrz, b_ctrz, b, bl, \
1506   - bl_ctr_true, b_ctr_true, bl_ctrz_true, b_ctrz_true, bl_true, b_true, \
1507   - bl_ctr_false, b_ctr_false, bl_ctrz_false, b_ctrz_false, bl_false, b_false) \
1508   -GEN_HANDLER(name, opc1, opc2, opc3, 0x00000000, PPC_FLOW) \
1509   -{ \
1510   - __attribute__ ((unused)) uint32_t target; \
1511   - uint32_t bo = BO(ctx->opcode); \
1512   - uint32_t bi = BI(ctx->opcode); \
1513   - uint32_t mask; \
1514   - gen_op_update_tb(ctx->tb_offset); \
1515   - gen_op_update_decr(ctx->decr_offset); \
1516   - gen_op_process_exceptions((uint32_t)ctx->nip - 4); \
1517   - prologue; \
1518   -/* gen_op_set_T1((uint32_t)ctx->tb);*/ \
1519   - if ((bo & 0x4) == 0) \
1520   - gen_op_dec_ctr(); \
1521   - if (bo & 0x10) { \
1522   - /* No CR condition */ \
1523   - switch (bo & 0x6) { \
1524   - case 0: \
1525   - if (LK(ctx->opcode)) { \
1526   - bl_ctr; \
1527   - } else { \
1528   - b_ctr; \
1529   - } \
1530   - break; \
1531   - case 2: \
1532   - if (LK(ctx->opcode)) { \
1533   - bl_ctrz; \
1534   - } else { \
1535   - b_ctrz; \
1536   - } \
1537   - break; \
1538   - case 4: \
1539   - case 6: \
1540   - if (LK(ctx->opcode)) { \
1541   - bl; \
1542   - } else { \
1543   - b; \
1544   - } \
1545   - break; \
1546   - default: \
1547   - printf("ERROR: %s: unhandled ba case (%d)\n", __func__, bo); \
1548   - RET_INVAL(); \
1549   - break; \
1550   - } \
1551   - } else { \
1552   - mask = 1 << (3 - (bi & 0x03)); \
1553   - gen_op_load_crf_T0(bi >> 2); \
1554   - if (bo & 0x8) { \
1555   - switch (bo & 0x6) { \
1556   - case 0: \
1557   - if (LK(ctx->opcode)) { \
1558   - bl_ctr_true; \
1559   - } else { \
1560   - b_ctr_true; \
1561   - } \
1562   - break; \
1563   - case 2: \
1564   - if (LK(ctx->opcode)) { \
1565   - bl_ctrz_true; \
1566   - } else { \
1567   - b_ctrz_true; \
1568   - } \
1569   - break; \
1570   - case 4: \
1571   - case 6: \
1572   - if (LK(ctx->opcode)) { \
1573   - bl_true; \
1574   - } else { \
1575   - b_true; \
1576   - } \
1577   - break; \
1578   - default: \
1579   - printf("ERROR: %s: unhandled b case (%d)\n", __func__, bo); \
1580   - RET_INVAL(); \
1581   - break; \
1582   - } \
1583   - } else { \
1584   - switch (bo & 0x6) { \
1585   - case 0: \
1586   - if (LK(ctx->opcode)) { \
1587   - bl_ctr_false; \
1588   - } else { \
1589   - b_ctr_false; \
1590   - } \
1591   - break; \
1592   - case 2: \
1593   - if (LK(ctx->opcode)) { \
1594   - bl_ctrz_false; \
1595   - } else { \
1596   - b_ctrz_false; \
1597   - } \
1598   - break; \
1599   - case 4: \
1600   - case 6: \
1601   - if (LK(ctx->opcode)) { \
1602   - bl_false; \
1603   - } else { \
1604   - b_false; \
1605   - } \
1606   - break; \
1607   - default: \
1608   - printf("ERROR: %s: unhandled bn case (%d)\n", __func__, bo); \
1609   - RET_INVAL(); \
1610   - break; \
1611   - } \
1612   - } \
1613   - } \
1614   - ctx->exception = EXCP_BRANCH; \
1615   -}
1616 1504  
1617 1505 /* b ba bl bla */
1618 1506 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
... ... @@ -1626,85 +1514,127 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1626 1514 target = (uint32_t)ctx->nip + li - 4;
1627 1515 else
1628 1516 target = li;
1629   -// gen_op_set_T1((uint32_t)ctx->tb);
1630 1517 if (LK(ctx->opcode)) {
1631   - gen_op_bl(target, (uint32_t)ctx->nip);
1632   - } else {
1633   - gen_op_b(target);
  1518 + gen_op_setlr((uint32_t)ctx->nip);
1634 1519 }
  1520 + gen_op_b((long)ctx->tb, target);
1635 1521 ctx->exception = EXCP_BRANCH;
1636 1522 }
1637 1523  
1638   -/* bc bca bcl bcla */
1639   -GEN_BCOND(bc, 0x10, 0xFF, 0xFF,
1640   - do {
1641   - uint32_t li = s_ext16(BD(ctx->opcode));
1642   - if (AA(ctx->opcode) == 0) {
1643   - target = (uint32_t)ctx->nip + li - 4;
1644   - } else {
1645   - target = li;
1646   - }
1647   - } while (0),
1648   - gen_op_bl_ctr((uint32_t)ctx->nip, target),
1649   - gen_op_b_ctr((uint32_t)ctx->nip, target),
1650   - gen_op_bl_ctrz((uint32_t)ctx->nip, target),
1651   - gen_op_b_ctrz((uint32_t)ctx->nip, target),
1652   - gen_op_b(target),
1653   - gen_op_bl(target, (uint32_t)ctx->nip),
1654   - gen_op_bl_ctr_true((uint32_t)ctx->nip, target, mask),
1655   - gen_op_b_ctr_true((uint32_t)ctx->nip, target, mask),
1656   - gen_op_bl_ctrz_true((uint32_t)ctx->nip, target, mask),
1657   - gen_op_b_ctrz_true((uint32_t)ctx->nip, target, mask),
1658   - gen_op_bl_true((uint32_t)ctx->nip, target, mask),
1659   - gen_op_b_true((uint32_t)ctx->nip, target, mask),
1660   - gen_op_bl_ctr_false((uint32_t)ctx->nip, target, mask),
1661   - gen_op_b_ctr_false((uint32_t)ctx->nip, target, mask),
1662   - gen_op_bl_ctrz_false((uint32_t)ctx->nip, target, mask),
1663   - gen_op_b_ctrz_false((uint32_t)ctx->nip, target, mask),
1664   - gen_op_bl_false((uint32_t)ctx->nip, target, mask),
1665   - gen_op_b_false((uint32_t)ctx->nip, target, mask));
1666   -
1667   -/* bcctr bcctrl */
1668   -GEN_BCOND(bcctr, 0x13, 0x10, 0x10, do { } while (0),
1669   - gen_op_bctrl_ctr((uint32_t)ctx->nip),
1670   - gen_op_bctr_ctr((uint32_t)ctx->nip),
1671   - gen_op_bctrl_ctrz((uint32_t)ctx->nip),
1672   - gen_op_bctr_ctrz((uint32_t)ctx->nip),
1673   - gen_op_bctr(),
1674   - gen_op_bctrl((uint32_t)ctx->nip),
1675   - gen_op_bctrl_ctr_true((uint32_t)ctx->nip, mask),
1676   - gen_op_bctr_ctr_true((uint32_t)ctx->nip, mask),
1677   - gen_op_bctrl_ctrz_true((uint32_t)ctx->nip, mask),
1678   - gen_op_bctr_ctrz_true((uint32_t)ctx->nip, mask),
1679   - gen_op_bctrl_true((uint32_t)ctx->nip, mask),
1680   - gen_op_bctr_true((uint32_t)ctx->nip, mask),
1681   - gen_op_bctrl_ctr_false((uint32_t)ctx->nip, mask),
1682   - gen_op_bctr_ctr_false((uint32_t)ctx->nip, mask),
1683   - gen_op_bctrl_ctrz_false((uint32_t)ctx->nip, mask),
1684   - gen_op_bctr_ctrz_false((uint32_t)ctx->nip, mask),
1685   - gen_op_bctrl_false((uint32_t)ctx->nip, mask),
1686   - gen_op_bctr_false((uint32_t)ctx->nip, mask))
1687   -
1688   -/* bclr bclrl */
1689   -GEN_BCOND(bclr, 0x13, 0x10, 0x00, do { } while (0),
1690   - gen_op_blrl_ctr((uint32_t)ctx->nip),
1691   - gen_op_blr_ctr((uint32_t)ctx->nip),
1692   - gen_op_blrl_ctrz((uint32_t)ctx->nip),
1693   - gen_op_blr_ctrz((uint32_t)ctx->nip),
1694   - gen_op_blr(),
1695   - gen_op_blrl((uint32_t)ctx->nip),
1696   - gen_op_blrl_ctr_true((uint32_t)ctx->nip, mask),
1697   - gen_op_blr_ctr_true((uint32_t)ctx->nip, mask),
1698   - gen_op_blrl_ctrz_true((uint32_t)ctx->nip, mask),
1699   - gen_op_blr_ctrz_true((uint32_t)ctx->nip, mask),
1700   - gen_op_blrl_true((uint32_t)ctx->nip, mask),
1701   - gen_op_blr_true((uint32_t)ctx->nip, mask),
1702   - gen_op_blrl_ctr_false((uint32_t)ctx->nip, mask),
1703   - gen_op_blr_ctr_false((uint32_t)ctx->nip, mask),
1704   - gen_op_blrl_ctrz_false((uint32_t)ctx->nip, mask),
1705   - gen_op_blr_ctrz_false((uint32_t)ctx->nip, mask),
1706   - gen_op_blrl_false((uint32_t)ctx->nip, mask),
1707   - gen_op_blr_false((uint32_t)ctx->nip, mask))
  1524 +#define BCOND_IM 0
  1525 +#define BCOND_LR 1
  1526 +#define BCOND_CTR 2
  1527 +
  1528 +static inline void gen_bcond(DisasContext *ctx, int type)
  1529 +{
  1530 + uint32_t target = 0;
  1531 + uint32_t bo = BO(ctx->opcode);
  1532 + uint32_t bi = BI(ctx->opcode);
  1533 + uint32_t mask;
  1534 + uint32_t li;
  1535 +
  1536 + gen_op_update_tb(ctx->tb_offset);
  1537 + gen_op_update_decr(ctx->decr_offset);
  1538 + gen_op_process_exceptions((uint32_t)ctx->nip - 4);
  1539 +
  1540 + if ((bo & 0x4) == 0)
  1541 + gen_op_dec_ctr();
  1542 + switch(type) {
  1543 + case BCOND_IM:
  1544 + li = s_ext16(BD(ctx->opcode));
  1545 + if (AA(ctx->opcode) == 0) {
  1546 + target = (uint32_t)ctx->nip + li - 4;
  1547 + } else {
  1548 + target = li;
  1549 + }
  1550 + break;
  1551 + case BCOND_CTR:
  1552 + gen_op_movl_T1_ctr();
  1553 + break;
  1554 + default:
  1555 + case BCOND_LR:
  1556 + gen_op_movl_T1_lr();
  1557 + break;
  1558 + }
  1559 + if (LK(ctx->opcode)) {
  1560 + gen_op_setlr((uint32_t)ctx->nip);
  1561 + }
  1562 + if (bo & 0x10) {
  1563 + /* No CR condition */
  1564 + switch (bo & 0x6) {
  1565 + case 0:
  1566 + gen_op_test_ctr();
  1567 + break;
  1568 + case 2:
  1569 + gen_op_test_ctrz();
  1570 + break;
  1571 + default:
  1572 + case 4:
  1573 + case 6:
  1574 + if (type == BCOND_IM) {
  1575 + gen_op_b((long)ctx->tb, target);
  1576 + } else {
  1577 + gen_op_b_T1();
  1578 + break;
  1579 + }
  1580 + goto no_test;
  1581 + }
  1582 + } else {
  1583 + mask = 1 << (3 - (bi & 0x03));
  1584 + gen_op_load_crf_T0(bi >> 2);
  1585 + if (bo & 0x8) {
  1586 + switch (bo & 0x6) {
  1587 + case 0:
  1588 + gen_op_test_ctr_true(mask);
  1589 + break;
  1590 + case 2:
  1591 + gen_op_test_ctrz_true(mask);
  1592 + break;
  1593 + default:
  1594 + case 4:
  1595 + case 6:
  1596 + gen_op_test_true(mask);
  1597 + break;
  1598 + }
  1599 + } else {
  1600 + switch (bo & 0x6) {
  1601 + case 0:
  1602 + gen_op_test_ctr_false(mask);
  1603 + break;
  1604 + case 2:
  1605 + gen_op_test_ctrz_false(mask);
  1606 + break;
  1607 + default:
  1608 + case 4:
  1609 + case 6:
  1610 + gen_op_test_false(mask);
  1611 + break;
  1612 + }
  1613 + }
  1614 + }
  1615 + if (type == BCOND_IM) {
  1616 + gen_op_btest((long)ctx->tb, target, (uint32_t)ctx->nip);
  1617 + } else {
  1618 + gen_op_btest_T1((uint32_t)ctx->nip);
  1619 + }
  1620 + no_test:
  1621 + ctx->exception = EXCP_BRANCH;
  1622 +}
  1623 +
  1624 +GEN_HANDLER(bc, 0x10, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
  1625 +{
  1626 + gen_bcond(ctx, BCOND_IM);
  1627 +}
  1628 +
  1629 +GEN_HANDLER(bcctr, 0x13, 0x10, 0x10, 0x00000000, PPC_FLOW)
  1630 +{
  1631 + gen_bcond(ctx, BCOND_CTR);
  1632 +}
  1633 +
  1634 +GEN_HANDLER(bclr, 0x13, 0x10, 0x00, 0x00000000, PPC_FLOW)
  1635 +{
  1636 + gen_bcond(ctx, BCOND_LR);
  1637 +}
1708 1638  
1709 1639 /*** Condition register logical ***/
1710 1640 #define GEN_CRLOGIC(op, opc) \
... ... @@ -3148,7 +3078,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3148 3078 if (gen_opc_ptr >= gen_opc_end ||
3149 3079 ((uint32_t)ctx.nip - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
3150 3080 if (ctx.exception == EXCP_NONE) {
3151   - gen_op_b((uint32_t)ctx.nip);
  3081 + gen_op_b((long)ctx.tb, (uint32_t)ctx.nip);
3152 3082 ctx.exception = EXCP_BRANCH;
3153 3083 }
3154 3084 }
... ...