Commit 507563e85db880ff875f0a9498a1cf58a50cfad3
1 parent
49bcf33c
target-mips: optimize gen_arith()/gen_arith_imm()
Optimize code generation in gen_arith()/gen_arith_imm(): - Don't do sign extension when the value is already guaranteed to be sign extended (otherwise, results are marked as UNPREDICTABLE). - When the value is sign extended, compare the value to 0 instead of testing bit 31/63. - Temp variables are valid up to and *including* the brcond instruction. Use them instead of temp local variables. Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5680 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
32 additions
and
46 deletions
target-mips/translate.c
| ... | ... | @@ -1333,7 +1333,7 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1333 | 1333 | switch (opc) { |
| 1334 | 1334 | case OPC_ADDI: |
| 1335 | 1335 | { |
| 1336 | - TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL); | |
| 1336 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); | |
| 1337 | 1337 | TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); |
| 1338 | 1338 | int l1 = gen_new_label(); |
| 1339 | 1339 | |
| ... | ... | @@ -1341,24 +1341,21 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1341 | 1341 | tcg_gen_ext32s_tl(r_tmp1, t0); |
| 1342 | 1342 | tcg_gen_addi_tl(t0, r_tmp1, uimm); |
| 1343 | 1343 | |
| 1344 | - tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm); | |
| 1345 | - tcg_gen_xori_tl(r_tmp1, r_tmp1, -1); | |
| 1344 | + tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm); | |
| 1346 | 1345 | tcg_gen_xori_tl(r_tmp2, t0, uimm); |
| 1347 | 1346 | tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); |
| 1348 | 1347 | tcg_temp_free(r_tmp2); |
| 1349 | - tcg_gen_shri_tl(r_tmp1, r_tmp1, 31); | |
| 1350 | - tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1); | |
| 1351 | - tcg_temp_free(r_tmp1); | |
| 1348 | + tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1); | |
| 1352 | 1349 | /* operands of same sign, result different sign */ |
| 1353 | 1350 | generate_exception(ctx, EXCP_OVERFLOW); |
| 1354 | 1351 | gen_set_label(l1); |
| 1352 | + tcg_temp_free(r_tmp1); | |
| 1355 | 1353 | |
| 1356 | 1354 | tcg_gen_ext32s_tl(t0, t0); |
| 1357 | 1355 | } |
| 1358 | 1356 | opn = "addi"; |
| 1359 | 1357 | break; |
| 1360 | 1358 | case OPC_ADDIU: |
| 1361 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1362 | 1359 | tcg_gen_addi_tl(t0, t0, uimm); |
| 1363 | 1360 | tcg_gen_ext32s_tl(t0, t0); |
| 1364 | 1361 | opn = "addiu"; |
| ... | ... | @@ -1366,7 +1363,7 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1366 | 1363 | #if defined(TARGET_MIPS64) |
| 1367 | 1364 | case OPC_DADDI: |
| 1368 | 1365 | { |
| 1369 | - TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL); | |
| 1366 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); | |
| 1370 | 1367 | TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); |
| 1371 | 1368 | int l1 = gen_new_label(); |
| 1372 | 1369 | |
| ... | ... | @@ -1374,17 +1371,15 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1374 | 1371 | tcg_gen_mov_tl(r_tmp1, t0); |
| 1375 | 1372 | tcg_gen_addi_tl(t0, t0, uimm); |
| 1376 | 1373 | |
| 1377 | - tcg_gen_xori_tl(r_tmp1, r_tmp1, uimm); | |
| 1378 | - tcg_gen_xori_tl(r_tmp1, r_tmp1, -1); | |
| 1374 | + tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm); | |
| 1379 | 1375 | tcg_gen_xori_tl(r_tmp2, t0, uimm); |
| 1380 | 1376 | tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); |
| 1381 | 1377 | tcg_temp_free(r_tmp2); |
| 1382 | - tcg_gen_shri_tl(r_tmp1, r_tmp1, 63); | |
| 1383 | - tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1); | |
| 1384 | - tcg_temp_free(r_tmp1); | |
| 1378 | + tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1); | |
| 1385 | 1379 | /* operands of same sign, result different sign */ |
| 1386 | 1380 | generate_exception(ctx, EXCP_OVERFLOW); |
| 1387 | 1381 | gen_set_label(l1); |
| 1382 | + tcg_temp_free(r_tmp1); | |
| 1388 | 1383 | } |
| 1389 | 1384 | opn = "daddi"; |
| 1390 | 1385 | break; |
| ... | ... | @@ -1417,7 +1412,6 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1417 | 1412 | opn = "lui"; |
| 1418 | 1413 | break; |
| 1419 | 1414 | case OPC_SLL: |
| 1420 | - tcg_gen_ext32u_tl(t0, t0); | |
| 1421 | 1415 | tcg_gen_shli_tl(t0, t0, uimm); |
| 1422 | 1416 | tcg_gen_ext32s_tl(t0, t0); |
| 1423 | 1417 | opn = "sll"; |
| ... | ... | @@ -1425,15 +1419,17 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1425 | 1419 | case OPC_SRA: |
| 1426 | 1420 | tcg_gen_ext32s_tl(t0, t0); |
| 1427 | 1421 | tcg_gen_sari_tl(t0, t0, uimm); |
| 1428 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1429 | 1422 | opn = "sra"; |
| 1430 | 1423 | break; |
| 1431 | 1424 | case OPC_SRL: |
| 1432 | 1425 | switch ((ctx->opcode >> 21) & 0x1f) { |
| 1433 | 1426 | case 0: |
| 1434 | - tcg_gen_ext32u_tl(t0, t0); | |
| 1435 | - tcg_gen_shri_tl(t0, t0, uimm); | |
| 1436 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1427 | + if (uimm != 0) { | |
| 1428 | + tcg_gen_ext32u_tl(t0, t0); | |
| 1429 | + tcg_gen_shri_tl(t0, t0, uimm); | |
| 1430 | + } else { | |
| 1431 | + tcg_gen_ext32s_tl(t0, t0); | |
| 1432 | + } | |
| 1437 | 1433 | opn = "srl"; |
| 1438 | 1434 | break; |
| 1439 | 1435 | case 1: |
| ... | ... | @@ -1449,9 +1445,12 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1449 | 1445 | } |
| 1450 | 1446 | opn = "rotr"; |
| 1451 | 1447 | } else { |
| 1452 | - tcg_gen_ext32u_tl(t0, t0); | |
| 1453 | - tcg_gen_shri_tl(t0, t0, uimm); | |
| 1454 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1448 | + if (uimm != 0) { | |
| 1449 | + tcg_gen_ext32u_tl(t0, t0); | |
| 1450 | + tcg_gen_shri_tl(t0, t0, uimm); | |
| 1451 | + } else { | |
| 1452 | + tcg_gen_ext32s_tl(t0, t0); | |
| 1453 | + } | |
| 1455 | 1454 | opn = "srl"; |
| 1456 | 1455 | } |
| 1457 | 1456 | break; |
| ... | ... | @@ -1562,7 +1561,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1562 | 1561 | switch (opc) { |
| 1563 | 1562 | case OPC_ADD: |
| 1564 | 1563 | { |
| 1565 | - TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL); | |
| 1564 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); | |
| 1566 | 1565 | TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); |
| 1567 | 1566 | int l1 = gen_new_label(); |
| 1568 | 1567 | |
| ... | ... | @@ -1576,27 +1575,24 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1576 | 1575 | tcg_gen_xor_tl(r_tmp2, t0, t1); |
| 1577 | 1576 | tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); |
| 1578 | 1577 | tcg_temp_free(r_tmp2); |
| 1579 | - tcg_gen_shri_tl(r_tmp1, r_tmp1, 31); | |
| 1580 | - tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1); | |
| 1581 | - tcg_temp_free(r_tmp1); | |
| 1578 | + tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1); | |
| 1582 | 1579 | /* operands of same sign, result different sign */ |
| 1583 | 1580 | generate_exception(ctx, EXCP_OVERFLOW); |
| 1584 | 1581 | gen_set_label(l1); |
| 1582 | + tcg_temp_free(r_tmp1); | |
| 1585 | 1583 | |
| 1586 | 1584 | tcg_gen_ext32s_tl(t0, t0); |
| 1587 | 1585 | } |
| 1588 | 1586 | opn = "add"; |
| 1589 | 1587 | break; |
| 1590 | 1588 | case OPC_ADDU: |
| 1591 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1592 | - tcg_gen_ext32s_tl(t1, t1); | |
| 1593 | 1589 | tcg_gen_add_tl(t0, t0, t1); |
| 1594 | 1590 | tcg_gen_ext32s_tl(t0, t0); |
| 1595 | 1591 | opn = "addu"; |
| 1596 | 1592 | break; |
| 1597 | 1593 | case OPC_SUB: |
| 1598 | 1594 | { |
| 1599 | - TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL); | |
| 1595 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); | |
| 1600 | 1596 | TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); |
| 1601 | 1597 | int l1 = gen_new_label(); |
| 1602 | 1598 | |
| ... | ... | @@ -1609,20 +1605,17 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1609 | 1605 | tcg_gen_xor_tl(r_tmp1, r_tmp1, t0); |
| 1610 | 1606 | tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); |
| 1611 | 1607 | tcg_temp_free(r_tmp2); |
| 1612 | - tcg_gen_shri_tl(r_tmp1, r_tmp1, 31); | |
| 1613 | - tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1); | |
| 1614 | - tcg_temp_free(r_tmp1); | |
| 1608 | + tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1); | |
| 1615 | 1609 | /* operands of different sign, first operand and result different sign */ |
| 1616 | 1610 | generate_exception(ctx, EXCP_OVERFLOW); |
| 1617 | 1611 | gen_set_label(l1); |
| 1612 | + tcg_temp_free(r_tmp1); | |
| 1618 | 1613 | |
| 1619 | 1614 | tcg_gen_ext32s_tl(t0, t0); |
| 1620 | 1615 | } |
| 1621 | 1616 | opn = "sub"; |
| 1622 | 1617 | break; |
| 1623 | 1618 | case OPC_SUBU: |
| 1624 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1625 | - tcg_gen_ext32s_tl(t1, t1); | |
| 1626 | 1619 | tcg_gen_sub_tl(t0, t0, t1); |
| 1627 | 1620 | tcg_gen_ext32s_tl(t0, t0); |
| 1628 | 1621 | opn = "subu"; |
| ... | ... | @@ -1630,7 +1623,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1630 | 1623 | #if defined(TARGET_MIPS64) |
| 1631 | 1624 | case OPC_DADD: |
| 1632 | 1625 | { |
| 1633 | - TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL); | |
| 1626 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); | |
| 1634 | 1627 | TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); |
| 1635 | 1628 | int l1 = gen_new_label(); |
| 1636 | 1629 | |
| ... | ... | @@ -1643,12 +1636,11 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1643 | 1636 | tcg_gen_xor_tl(r_tmp2, t0, t1); |
| 1644 | 1637 | tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); |
| 1645 | 1638 | tcg_temp_free(r_tmp2); |
| 1646 | - tcg_gen_shri_tl(r_tmp1, r_tmp1, 63); | |
| 1647 | - tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1); | |
| 1648 | - tcg_temp_free(r_tmp1); | |
| 1639 | + tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1); | |
| 1649 | 1640 | /* operands of same sign, result different sign */ |
| 1650 | 1641 | generate_exception(ctx, EXCP_OVERFLOW); |
| 1651 | 1642 | gen_set_label(l1); |
| 1643 | + tcg_temp_free(r_tmp1); | |
| 1652 | 1644 | } |
| 1653 | 1645 | opn = "dadd"; |
| 1654 | 1646 | break; |
| ... | ... | @@ -1658,7 +1650,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1658 | 1650 | break; |
| 1659 | 1651 | case OPC_DSUB: |
| 1660 | 1652 | { |
| 1661 | - TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_TL); | |
| 1653 | + TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_TL); | |
| 1662 | 1654 | TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); |
| 1663 | 1655 | int l1 = gen_new_label(); |
| 1664 | 1656 | |
| ... | ... | @@ -1670,12 +1662,11 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1670 | 1662 | tcg_gen_xor_tl(r_tmp1, r_tmp1, t0); |
| 1671 | 1663 | tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); |
| 1672 | 1664 | tcg_temp_free(r_tmp2); |
| 1673 | - tcg_gen_shri_tl(r_tmp1, r_tmp1, 63); | |
| 1674 | - tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp1, 0, l1); | |
| 1675 | - tcg_temp_free(r_tmp1); | |
| 1665 | + tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1); | |
| 1676 | 1666 | /* operands of different sign, first operand and result different sign */ |
| 1677 | 1667 | generate_exception(ctx, EXCP_OVERFLOW); |
| 1678 | 1668 | gen_set_label(l1); |
| 1669 | + tcg_temp_free(r_tmp1); | |
| 1679 | 1670 | } |
| 1680 | 1671 | opn = "dsub"; |
| 1681 | 1672 | break; |
| ... | ... | @@ -1710,8 +1701,6 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1710 | 1701 | opn = "xor"; |
| 1711 | 1702 | break; |
| 1712 | 1703 | case OPC_MUL: |
| 1713 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1714 | - tcg_gen_ext32s_tl(t1, t1); | |
| 1715 | 1704 | tcg_gen_mul_tl(t0, t0, t1); |
| 1716 | 1705 | tcg_gen_ext32s_tl(t0, t0); |
| 1717 | 1706 | opn = "mul"; |
| ... | ... | @@ -1737,8 +1726,6 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1737 | 1726 | opn = "movz"; |
| 1738 | 1727 | goto print; |
| 1739 | 1728 | case OPC_SLLV: |
| 1740 | - tcg_gen_ext32u_tl(t0, t0); | |
| 1741 | - tcg_gen_ext32u_tl(t1, t1); | |
| 1742 | 1729 | tcg_gen_andi_tl(t0, t0, 0x1f); |
| 1743 | 1730 | tcg_gen_shl_tl(t0, t1, t0); |
| 1744 | 1731 | tcg_gen_ext32s_tl(t0, t0); |
| ... | ... | @@ -1748,7 +1735,6 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, |
| 1748 | 1735 | tcg_gen_ext32s_tl(t1, t1); |
| 1749 | 1736 | tcg_gen_andi_tl(t0, t0, 0x1f); |
| 1750 | 1737 | tcg_gen_sar_tl(t0, t1, t0); |
| 1751 | - tcg_gen_ext32s_tl(t0, t0); | |
| 1752 | 1738 | opn = "srav"; |
| 1753 | 1739 | break; |
| 1754 | 1740 | case OPC_SRLV: | ... | ... |