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,121 +473,94 @@ PPC_OP(setcrfbit)
473 } 473 }
474 474
475 /* Branch */ 475 /* Branch */
476 -#if 0  
477 #define EIP regs->nip 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 /* CTR maintenance */ 565 /* CTR maintenance */
593 PPC_OP(dec_ctr) 566 PPC_OP(dec_ctr)
target-ppc/translate.c
@@ -1501,118 +1501,6 @@ GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT) @@ -1501,118 +1501,6 @@ GEN_HANDLER(stfiwx, 0x1F, 0x17, 0x1E, 0x00000001, PPC_FLOAT)
1501 } 1501 }
1502 1502
1503 /*** Branch ***/ 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 /* b ba bl bla */ 1505 /* b ba bl bla */
1618 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) 1506 GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
@@ -1626,85 +1514,127 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW) @@ -1626,85 +1514,127 @@ GEN_HANDLER(b, 0x12, 0xFF, 0xFF, 0x00000000, PPC_FLOW)
1626 target = (uint32_t)ctx->nip + li - 4; 1514 target = (uint32_t)ctx->nip + li - 4;
1627 else 1515 else
1628 target = li; 1516 target = li;
1629 -// gen_op_set_T1((uint32_t)ctx->tb);  
1630 if (LK(ctx->opcode)) { 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 ctx->exception = EXCP_BRANCH; 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 /*** Condition register logical ***/ 1639 /*** Condition register logical ***/
1710 #define GEN_CRLOGIC(op, opc) \ 1640 #define GEN_CRLOGIC(op, opc) \
@@ -3148,7 +3078,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, @@ -3148,7 +3078,7 @@ int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3148 if (gen_opc_ptr >= gen_opc_end || 3078 if (gen_opc_ptr >= gen_opc_end ||
3149 ((uint32_t)ctx.nip - pc_start) >= (TARGET_PAGE_SIZE - 32)) { 3079 ((uint32_t)ctx.nip - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
3150 if (ctx.exception == EXCP_NONE) { 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 ctx.exception = EXCP_BRANCH; 3082 ctx.exception = EXCP_BRANCH;
3153 } 3083 }
3154 } 3084 }