Revision e98a6e40
b/target-ppc/op.c | ||
---|---|---|
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) |
b/target-ppc/translate.c | ||
---|---|---|
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 | 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 | 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 |
} |
Also available in: Unified diff