Revision 460f00c4

b/target-mips/translate.c
1452 1452
                       int rd, int rs, int rt)
1453 1453
{
1454 1454
    const char *opn = "arith";
1455
    TCGv t0 = tcg_temp_local_new();
1456
    TCGv t1 = tcg_temp_local_new();
1457 1455

  
1458 1456
    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1459 1457
       && opc != OPC_DADD && opc != OPC_DSUB) {
1460 1458
        /* If no destination, treat it as a NOP.
1461 1459
           For add & sub, we must generate the overflow exception when needed. */
1462 1460
        MIPS_DEBUG("NOP");
1463
        goto out;
1464
    }
1465
    gen_load_gpr(t0, rs);
1466
    /* Specialcase the conventional move operation. */
1467
    if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
1468
                    || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1469
        gen_store_gpr(t0, rd);
1470
        goto out;
1461
        return;
1471 1462
    }
1472
    gen_load_gpr(t1, rt);
1463

  
1473 1464
    switch (opc) {
1474 1465
    case OPC_ADD:
1475 1466
        {
1476
            TCGv r_tmp1 = tcg_temp_new();
1477
            TCGv r_tmp2 = tcg_temp_new();
1467
            TCGv t0 = tcg_temp_local_new();
1468
            TCGv t1 = tcg_temp_new();
1469
            TCGv t2 = tcg_temp_new();
1478 1470
            int l1 = gen_new_label();
1479 1471

  
1480
            save_cpu_state(ctx, 1);
1481
            tcg_gen_ext32s_tl(r_tmp1, t0);
1482
            tcg_gen_ext32s_tl(r_tmp2, t1);
1483
            tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
1484

  
1485
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1486
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1487
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1488
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1489
            tcg_temp_free(r_tmp2);
1490
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1472
            gen_load_gpr(t1, rs);
1473
            gen_load_gpr(t2, rt);
1474
            tcg_gen_add_tl(t0, t1, t2);
1475
            tcg_gen_ext32s_tl(t0, t0);
1476
            tcg_gen_xor_tl(t1, t1, t2);
1477
            tcg_gen_not_tl(t1, t1);
1478
            tcg_gen_xor_tl(t2, t0, t2);
1479
            tcg_gen_and_tl(t1, t1, t2);
1480
            tcg_temp_free(t2);
1481
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1482
            tcg_temp_free(t1);
1491 1483
            /* operands of same sign, result different sign */
1492 1484
            generate_exception(ctx, EXCP_OVERFLOW);
1493 1485
            gen_set_label(l1);
1494
            tcg_temp_free(r_tmp1);
1495

  
1496
            tcg_gen_ext32s_tl(t0, t0);
1486
            gen_store_gpr(t0, rd);
1487
            tcg_temp_free(t0);
1497 1488
        }
1498 1489
        opn = "add";
1499 1490
        break;
1500 1491
    case OPC_ADDU:
1501
        tcg_gen_add_tl(t0, t0, t1);
1502
        tcg_gen_ext32s_tl(t0, t0);
1492
        if (rs != 0 && rt != 0) {
1493
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1494
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1495
        } else if (rs == 0 && rt != 0) {
1496
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1497
        } else if (rs != 0 && rt == 0) {
1498
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1499
        } else {
1500
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1501
        }
1503 1502
        opn = "addu";
1504 1503
        break;
1505 1504
    case OPC_SUB:
1506 1505
        {
1507
            TCGv r_tmp1 = tcg_temp_new();
1508
            TCGv r_tmp2 = tcg_temp_new();
1506
            TCGv t0 = tcg_temp_local_new();
1507
            TCGv t1 = tcg_temp_new();
1508
            TCGv t2 = tcg_temp_new();
1509 1509
            int l1 = gen_new_label();
1510 1510

  
1511
            save_cpu_state(ctx, 1);
1512
            tcg_gen_ext32s_tl(r_tmp1, t0);
1513
            tcg_gen_ext32s_tl(r_tmp2, t1);
1514
            tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
1515

  
1516
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1517
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1518
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1519
            tcg_temp_free(r_tmp2);
1520
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1521
            /* operands of different sign, first operand and result different sign */
1511
            gen_load_gpr(t1, rs);
1512
            gen_load_gpr(t2, rt);
1513
            tcg_gen_sub_tl(t0, t1, t2);
1514
            tcg_gen_ext32s_tl(t0, t0);
1515
            tcg_gen_xor_tl(t2, t1, t2);
1516
            tcg_gen_xor_tl(t1, t0, t1);
1517
            tcg_gen_and_tl(t1, t1, t2);
1518
            tcg_temp_free(t2);
1519
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1520
            tcg_temp_free(t1);
1521
            /* operands of same sign, result different sign */
1522 1522
            generate_exception(ctx, EXCP_OVERFLOW);
1523 1523
            gen_set_label(l1);
1524
            tcg_temp_free(r_tmp1);
1525

  
1526
            tcg_gen_ext32s_tl(t0, t0);
1524
            gen_store_gpr(t0, rd);
1525
            tcg_temp_free(t0);
1527 1526
        }
1528 1527
        opn = "sub";
1529 1528
        break;
1530 1529
    case OPC_SUBU:
1531
        tcg_gen_sub_tl(t0, t0, t1);
1532
        tcg_gen_ext32s_tl(t0, t0);
1530
        if (rs != 0 && rt != 0) {
1531
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1532
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1533
        } else if (rs == 0 && rt != 0) {
1534
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1535
        } else if (rs != 0 && rt == 0) {
1536
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1537
        } else {
1538
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1539
        }
1533 1540
        opn = "subu";
1534 1541
        break;
1535 1542
#if defined(TARGET_MIPS64)
1536 1543
    case OPC_DADD:
1537 1544
        {
1538
            TCGv r_tmp1 = tcg_temp_new();
1539
            TCGv r_tmp2 = tcg_temp_new();
1545
            TCGv t0 = tcg_temp_local_new();
1546
            TCGv t1 = tcg_temp_new();
1547
            TCGv t2 = tcg_temp_new();
1540 1548
            int l1 = gen_new_label();
1541 1549

  
1542
            save_cpu_state(ctx, 1);
1543
            tcg_gen_mov_tl(r_tmp1, t0);
1544
            tcg_gen_add_tl(t0, t0, t1);
1545

  
1546
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
1547
            tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
1548
            tcg_gen_xor_tl(r_tmp2, t0, t1);
1549
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1550
            tcg_temp_free(r_tmp2);
1551
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1550
            gen_load_gpr(t1, rs);
1551
            gen_load_gpr(t2, rt);
1552
            tcg_gen_add_tl(t0, t1, t2);
1553
            tcg_gen_xor_tl(t1, t1, t2);
1554
            tcg_gen_not_tl(t1, t1);
1555
            tcg_gen_xor_tl(t2, t0, t2);
1556
            tcg_gen_and_tl(t1, t1, t2);
1557
            tcg_temp_free(t2);
1558
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1559
            tcg_temp_free(t1);
1552 1560
            /* operands of same sign, result different sign */
1553 1561
            generate_exception(ctx, EXCP_OVERFLOW);
1554 1562
            gen_set_label(l1);
1555
            tcg_temp_free(r_tmp1);
1563
            gen_store_gpr(t0, rd);
1564
            tcg_temp_free(t0);
1556 1565
        }
1557 1566
        opn = "dadd";
1558 1567
        break;
1559 1568
    case OPC_DADDU:
1560
        tcg_gen_add_tl(t0, t0, t1);
1569
        if (rs != 0 && rt != 0) {
1570
            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1571
        } else if (rs == 0 && rt != 0) {
1572
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1573
        } else if (rs != 0 && rt == 0) {
1574
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1575
        } else {
1576
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1577
        }
1561 1578
        opn = "daddu";
1562 1579
        break;
1563 1580
    case OPC_DSUB:
1564 1581
        {
1565
            TCGv r_tmp1 = tcg_temp_new();
1566
            TCGv r_tmp2 = tcg_temp_new();
1582
            TCGv t0 = tcg_temp_local_new();
1583
            TCGv t1 = tcg_temp_new();
1584
            TCGv t2 = tcg_temp_new();
1567 1585
            int l1 = gen_new_label();
1568 1586

  
1569
            save_cpu_state(ctx, 1);
1570
            tcg_gen_mov_tl(r_tmp1, t0);
1571
            tcg_gen_sub_tl(t0, t0, t1);
1572

  
1573
            tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
1574
            tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1575
            tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1576
            tcg_temp_free(r_tmp2);
1577
            tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
1578
            /* operands of different sign, first operand and result different sign */
1587
            gen_load_gpr(t1, rs);
1588
            gen_load_gpr(t2, rt);
1589
            tcg_gen_sub_tl(t0, t1, t2);
1590
            tcg_gen_xor_tl(t2, t1, t2);
1591
            tcg_gen_xor_tl(t1, t0, t1);
1592
            tcg_gen_and_tl(t1, t1, t2);
1593
            tcg_temp_free(t2);
1594
            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1595
            tcg_temp_free(t1);
1596
            /* operands of same sign, result different sign */
1579 1597
            generate_exception(ctx, EXCP_OVERFLOW);
1580 1598
            gen_set_label(l1);
1581
            tcg_temp_free(r_tmp1);
1599
            gen_store_gpr(t0, rd);
1600
            tcg_temp_free(t0);
1582 1601
        }
1583 1602
        opn = "dsub";
1584 1603
        break;
1585 1604
    case OPC_DSUBU:
1586
        tcg_gen_sub_tl(t0, t0, t1);
1605
        if (rs != 0 && rt != 0) {
1606
            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1607
        } else if (rs == 0 && rt != 0) {
1608
            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1609
        } else if (rs != 0 && rt == 0) {
1610
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1611
        } else {
1612
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1613
        }
1587 1614
        opn = "dsubu";
1588 1615
        break;
1589 1616
#endif
1590
    case OPC_SLT:
1591
        gen_op_lt(t0, t0, t1);
1592
        opn = "slt";
1617
    case OPC_MUL:
1618
        if (likely(rs != 0 && rt != 0)) {
1619
            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1620
            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1621
        } else {
1622
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1623
        }
1624
        opn = "mul";
1593 1625
        break;
1594
    case OPC_SLTU:
1595
        gen_op_ltu(t0, t0, t1);
1596
        opn = "sltu";
1626
    }
1627
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1628
}
1629

  
1630
/* Conditional move */
1631
static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1632
{
1633
    const char *opn = "cond move";
1634
    int l1;
1635

  
1636
    if (rd == 0) {
1637
        /* If no destination, treat it as a NOP.
1638
           For add & sub, we must generate the overflow exception when needed. */
1639
        MIPS_DEBUG("NOP");
1640
        return;
1641
    }
1642

  
1643
    l1 = gen_new_label();
1644
    switch (opc) {
1645
    case OPC_MOVN:
1646
        if (likely(rt != 0))
1647
            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1648
        else
1649
            tcg_gen_br(l1);
1650
        opn = "movn";
1651
        break;
1652
    case OPC_MOVZ:
1653
        if (likely(rt != 0))
1654
            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1655
        opn = "movz";
1597 1656
        break;
1657
    }
1658
    if (rs != 0)
1659
        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1660
    else
1661
        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1662
    gen_set_label(l1);
1663

  
1664
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1665
}
1666

  
1667
/* Logic */
1668
static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1669
{
1670
    const char *opn = "logic";
1671

  
1672
    if (rd == 0) {
1673
        /* If no destination, treat it as a NOP. */
1674
        MIPS_DEBUG("NOP");
1675
        return;
1676
    }
1677

  
1678
    switch (opc) {
1598 1679
    case OPC_AND:
1599
        tcg_gen_and_tl(t0, t0, t1);
1680
        if (likely(rs != 0 && rt != 0)) {
1681
            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1682
        } else {
1683
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1684
        }
1600 1685
        opn = "and";
1601 1686
        break;
1602 1687
    case OPC_NOR:
1603
        tcg_gen_nor_tl(t0, t0, t1);
1688
        if (rs != 0 && rt != 0) {
1689
            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1690
        } else if (rs == 0 && rt != 0) {
1691
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1692
        } else if (rs != 0 && rt == 0) {
1693
            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1694
        } else {
1695
            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1696
        }
1604 1697
        opn = "nor";
1605 1698
        break;
1606 1699
    case OPC_OR:
1607
        tcg_gen_or_tl(t0, t0, t1);
1700
        if (likely(rs != 0 && rt != 0)) {
1701
            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1702
        } else if (rs == 0 && rt != 0) {
1703
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1704
        } else if (rs != 0 && rt == 0) {
1705
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1706
        } else {
1707
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1708
        }
1608 1709
        opn = "or";
1609 1710
        break;
1610 1711
    case OPC_XOR:
1611
        tcg_gen_xor_tl(t0, t0, t1);
1712
        if (likely(rs != 0 && rt != 0)) {
1713
            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1714
        } else if (rs == 0 && rt != 0) {
1715
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1716
        } else if (rs != 0 && rt == 0) {
1717
            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1718
        } else {
1719
            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1720
        }
1612 1721
        opn = "xor";
1613 1722
        break;
1614
    case OPC_MUL:
1615
        tcg_gen_mul_tl(t0, t0, t1);
1616
        tcg_gen_ext32s_tl(t0, t0);
1617
        opn = "mul";
1723
    }
1724
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1725
}
1726

  
1727
/* Set on lower than */
1728
static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1729
{
1730
    const char *opn = "slt";
1731
    TCGv t0, t1;
1732

  
1733
    if (rd == 0) {
1734
        /* If no destination, treat it as a NOP. */
1735
        MIPS_DEBUG("NOP");
1736
        return;
1737
    }
1738

  
1739
    t0 = tcg_temp_new();
1740
    t1 = tcg_temp_new();
1741
    gen_load_gpr(t0, rs);
1742
    gen_load_gpr(t1, rt);
1743
    switch (opc) {
1744
    case OPC_SLT:
1745
        gen_op_lt(cpu_gpr[rd], t0, t1);
1746
        opn = "slt";
1618 1747
        break;
1619
    case OPC_MOVN:
1620
        {
1621
            int l1 = gen_new_label();
1748
    case OPC_SLTU:
1749
        gen_op_ltu(cpu_gpr[rd], t0, t1);
1750
        opn = "sltu";
1751
        break;
1752
    }
1753
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1754
    tcg_temp_free(t0);
1755
    tcg_temp_free(t1);
1756
}
1622 1757

  
1623
            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1624
            gen_store_gpr(t0, rd);
1625
            gen_set_label(l1);
1626
        }
1627
        opn = "movn";
1628
        goto print;
1629
    case OPC_MOVZ:
1630
        {
1631
            int l1 = gen_new_label();
1758
/* Shifts */
1759
static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1760
                       int rd, int rs, int rt)
1761
{
1762
    const char *opn = "shifts";
1763
    TCGv t0, t1;
1632 1764

  
1633
            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
1634
            gen_store_gpr(t0, rd);
1635
            gen_set_label(l1);
1636
        }
1637
        opn = "movz";
1638
        goto print;
1765
    if (rd == 0) {
1766
        /* If no destination, treat it as a NOP.
1767
           For add & sub, we must generate the overflow exception when needed. */
1768
        MIPS_DEBUG("NOP");
1769
        return;
1770
    }
1771

  
1772
    t0 = tcg_temp_new();
1773
    t1 = tcg_temp_new();
1774
    gen_load_gpr(t0, rs);
1775
    gen_load_gpr(t1, rt);
1776
    switch (opc) {
1639 1777
    case OPC_SLLV:
1640 1778
        tcg_gen_andi_tl(t0, t0, 0x1f);
1641 1779
        tcg_gen_shl_tl(t0, t1, t0);
1642
        tcg_gen_ext32s_tl(t0, t0);
1780
        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1643 1781
        opn = "sllv";
1644 1782
        break;
1645 1783
    case OPC_SRAV:
1646 1784
        tcg_gen_ext32s_tl(t1, t1);
1647 1785
        tcg_gen_andi_tl(t0, t0, 0x1f);
1648
        tcg_gen_sar_tl(t0, t1, t0);
1786
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1649 1787
        opn = "srav";
1650 1788
        break;
1651 1789
    case OPC_SRLV:
......
1654 1792
            tcg_gen_ext32u_tl(t1, t1);
1655 1793
            tcg_gen_andi_tl(t0, t0, 0x1f);
1656 1794
            tcg_gen_shr_tl(t0, t1, t0);
1657
            tcg_gen_ext32s_tl(t0, t0);
1795
            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1658 1796
            opn = "srlv";
1659 1797
            break;
1660 1798
        case 1:
1661 1799
            /* rotrv is decoded as srlv on non-R2 CPUs */
1662 1800
            if (env->insn_flags & ISA_MIPS32R2) {
1663
                int l1 = gen_new_label();
1664
                int l2 = gen_new_label();
1665

  
1666
                tcg_gen_andi_tl(t0, t0, 0x1f);
1667
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1668
                {
1669
                    TCGv_i32 r_tmp1 = tcg_temp_new_i32();
1670
                    TCGv_i32 r_tmp2 = tcg_temp_new_i32();
1671

  
1672
                    tcg_gen_trunc_tl_i32(r_tmp1, t0);
1673
                    tcg_gen_trunc_tl_i32(r_tmp2, t1);
1674
                    tcg_gen_rotr_i32(r_tmp1, r_tmp1, r_tmp2);
1675
                    tcg_temp_free_i32(r_tmp1);
1676
                    tcg_temp_free_i32(r_tmp2);
1677
                    tcg_gen_br(l2);
1678
                }
1679
                gen_set_label(l1);
1680
                tcg_gen_mov_tl(t0, t1);
1681
                gen_set_label(l2);
1801
                TCGv_i32 t2 = tcg_temp_new_i32();
1802
                TCGv_i32 t3 = tcg_temp_new_i32();
1803

  
1804
                tcg_gen_trunc_tl_i32(t2, t0);
1805
                tcg_gen_trunc_tl_i32(t3, t1);
1806
                tcg_gen_andi_i32(t2, t2, 0x1f);
1807
                tcg_gen_rotr_i32(t2, t3, t2);
1808
                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1809
                tcg_temp_free_i32(t2);
1810
                tcg_temp_free_i32(t3);
1682 1811
                opn = "rotrv";
1683 1812
            } else {
1684 1813
                tcg_gen_ext32u_tl(t1, t1);
1685 1814
                tcg_gen_andi_tl(t0, t0, 0x1f);
1686 1815
                tcg_gen_shr_tl(t0, t1, t0);
1687
                tcg_gen_ext32s_tl(t0, t0);
1816
                tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1688 1817
                opn = "srlv";
1689 1818
            }
1690 1819
            break;
......
1697 1826
#if defined(TARGET_MIPS64)
1698 1827
    case OPC_DSLLV:
1699 1828
        tcg_gen_andi_tl(t0, t0, 0x3f);
1700
        tcg_gen_shl_tl(t0, t1, t0);
1829
        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1701 1830
        opn = "dsllv";
1702 1831
        break;
1703 1832
    case OPC_DSRAV:
1704 1833
        tcg_gen_andi_tl(t0, t0, 0x3f);
1705
        tcg_gen_sar_tl(t0, t1, t0);
1834
        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1706 1835
        opn = "dsrav";
1707 1836
        break;
1708 1837
    case OPC_DSRLV:
1709 1838
        switch ((ctx->opcode >> 6) & 0x1f) {
1710 1839
        case 0:
1711 1840
            tcg_gen_andi_tl(t0, t0, 0x3f);
1712
            tcg_gen_shr_tl(t0, t1, t0);
1841
            tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1713 1842
            opn = "dsrlv";
1714 1843
            break;
1715 1844
        case 1:
1716 1845
            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1717 1846
            if (env->insn_flags & ISA_MIPS32R2) {
1718
                int l1 = gen_new_label();
1719
                int l2 = gen_new_label();
1720

  
1721 1847
                tcg_gen_andi_tl(t0, t0, 0x3f);
1722
                tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
1723
                {
1724
                    tcg_gen_rotr_tl(t0, t1, t0);
1725
                    tcg_gen_br(l2);
1726
                }
1727
                gen_set_label(l1);
1728
                tcg_gen_mov_tl(t0, t1);
1729
                gen_set_label(l2);
1848
                tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1730 1849
                opn = "drotrv";
1731 1850
            } else {
1732 1851
                tcg_gen_andi_tl(t0, t0, 0x3f);
......
1741 1860
        }
1742 1861
        break;
1743 1862
#endif
1744
    default:
1745
        MIPS_INVAL(opn);
1746
        generate_exception(ctx, EXCP_RI);
1747
        goto out;
1748 1863
    }
1749
    gen_store_gpr(t0, rd);
1750
 print:
1751 1864
    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1752
 out:
1753 1865
    tcg_temp_free(t0);
1754 1866
    tcg_temp_free(t1);
1755 1867
}
......
7465 7577
        case OPC_SRL ... OPC_SRA:
7466 7578
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7467 7579
            break;
7468
        case OPC_MOVZ ... OPC_MOVN:
7580
        case OPC_MOVN:         /* Conditional move */
7581
        case OPC_MOVZ:
7469 7582
            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7470
        case OPC_SLLV:         /* Arithmetic */
7471
        case OPC_SRLV ... OPC_SRAV:
7472
        case OPC_ADD ... OPC_NOR:
7473
        case OPC_SLT ... OPC_SLTU:
7583
            gen_cond_move(env, op1, rd, rs, rt);
7584
            break;
7585
        case OPC_ADD ... OPC_SUBU:
7474 7586
            gen_arith(env, ctx, op1, rd, rs, rt);
7475 7587
            break;
7588
        case OPC_SLLV:         /* Shifts */
7589
        case OPC_SRLV:
7590
        case OPC_SRAV:
7591
            gen_shift(env, ctx, op1, rd, rs, rt);
7592
            break;
7593
        case OPC_SLT:          /* Set on less than */
7594
        case OPC_SLTU:
7595
            gen_slt(env, op1, rd, rs, rt);
7596
            break;
7597
        case OPC_AND:          /* Logic*/
7598
        case OPC_OR:
7599
        case OPC_NOR:
7600
        case OPC_XOR:
7601
            gen_logic(env, op1, rd, rs, rt);
7602
            break;
7476 7603
        case OPC_MULT ... OPC_DIVU:
7477 7604
            if (sa) {
7478 7605
                check_insn(env, ctx, INSN_VR54XX);
......
7545 7672
            check_mips_64(ctx);
7546 7673
            gen_arith_imm(env, ctx, op1, rd, rt, sa);
7547 7674
            break;
7548
        case OPC_DSLLV:
7549
        case OPC_DSRLV ... OPC_DSRAV:
7550 7675
        case OPC_DADD ... OPC_DSUBU:
7551 7676
            check_insn(env, ctx, ISA_MIPS3);
7552 7677
            check_mips_64(ctx);
7553 7678
            gen_arith(env, ctx, op1, rd, rs, rt);
7554 7679
            break;
7680
        case OPC_DSLLV:
7681
        case OPC_DSRAV:
7682
        case OPC_DSRLV:
7683
            check_insn(env, ctx, ISA_MIPS3);
7684
            check_mips_64(ctx);
7685
            gen_shift(env, ctx, op1, rd, rs, rt);
7686
            break;
7555 7687
        case OPC_DMULT ... OPC_DDIVU:
7556 7688
            check_insn(env, ctx, ISA_MIPS3);
7557 7689
            check_mips_64(ctx);

Also available in: Unified diff