Commit 507563e85db880ff875f0a9498a1cf58a50cfad3

Authored by aurel32
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,7 +1333,7 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1333 switch (opc) { 1333 switch (opc) {
1334 case OPC_ADDI: 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 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); 1337 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1338 int l1 = gen_new_label(); 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,24 +1341,21 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1341 tcg_gen_ext32s_tl(r_tmp1, t0); 1341 tcg_gen_ext32s_tl(r_tmp1, t0);
1342 tcg_gen_addi_tl(t0, r_tmp1, uimm); 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 tcg_gen_xori_tl(r_tmp2, t0, uimm); 1345 tcg_gen_xori_tl(r_tmp2, t0, uimm);
1347 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); 1346 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1348 tcg_temp_free(r_tmp2); 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 /* operands of same sign, result different sign */ 1349 /* operands of same sign, result different sign */
1353 generate_exception(ctx, EXCP_OVERFLOW); 1350 generate_exception(ctx, EXCP_OVERFLOW);
1354 gen_set_label(l1); 1351 gen_set_label(l1);
  1352 + tcg_temp_free(r_tmp1);
1355 1353
1356 tcg_gen_ext32s_tl(t0, t0); 1354 tcg_gen_ext32s_tl(t0, t0);
1357 } 1355 }
1358 opn = "addi"; 1356 opn = "addi";
1359 break; 1357 break;
1360 case OPC_ADDIU: 1358 case OPC_ADDIU:
1361 - tcg_gen_ext32s_tl(t0, t0);  
1362 tcg_gen_addi_tl(t0, t0, uimm); 1359 tcg_gen_addi_tl(t0, t0, uimm);
1363 tcg_gen_ext32s_tl(t0, t0); 1360 tcg_gen_ext32s_tl(t0, t0);
1364 opn = "addiu"; 1361 opn = "addiu";
@@ -1366,7 +1363,7 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1366,7 +1363,7 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1366 #if defined(TARGET_MIPS64) 1363 #if defined(TARGET_MIPS64)
1367 case OPC_DADDI: 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 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); 1367 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1371 int l1 = gen_new_label(); 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,17 +1371,15 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1374 tcg_gen_mov_tl(r_tmp1, t0); 1371 tcg_gen_mov_tl(r_tmp1, t0);
1375 tcg_gen_addi_tl(t0, t0, uimm); 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 tcg_gen_xori_tl(r_tmp2, t0, uimm); 1375 tcg_gen_xori_tl(r_tmp2, t0, uimm);
1380 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); 1376 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1381 tcg_temp_free(r_tmp2); 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 /* operands of same sign, result different sign */ 1379 /* operands of same sign, result different sign */
1386 generate_exception(ctx, EXCP_OVERFLOW); 1380 generate_exception(ctx, EXCP_OVERFLOW);
1387 gen_set_label(l1); 1381 gen_set_label(l1);
  1382 + tcg_temp_free(r_tmp1);
1388 } 1383 }
1389 opn = "daddi"; 1384 opn = "daddi";
1390 break; 1385 break;
@@ -1417,7 +1412,6 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1417,7 +1412,6 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1417 opn = "lui"; 1412 opn = "lui";
1418 break; 1413 break;
1419 case OPC_SLL: 1414 case OPC_SLL:
1420 - tcg_gen_ext32u_tl(t0, t0);  
1421 tcg_gen_shli_tl(t0, t0, uimm); 1415 tcg_gen_shli_tl(t0, t0, uimm);
1422 tcg_gen_ext32s_tl(t0, t0); 1416 tcg_gen_ext32s_tl(t0, t0);
1423 opn = "sll"; 1417 opn = "sll";
@@ -1425,15 +1419,17 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1425,15 +1419,17 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1425 case OPC_SRA: 1419 case OPC_SRA:
1426 tcg_gen_ext32s_tl(t0, t0); 1420 tcg_gen_ext32s_tl(t0, t0);
1427 tcg_gen_sari_tl(t0, t0, uimm); 1421 tcg_gen_sari_tl(t0, t0, uimm);
1428 - tcg_gen_ext32s_tl(t0, t0);  
1429 opn = "sra"; 1422 opn = "sra";
1430 break; 1423 break;
1431 case OPC_SRL: 1424 case OPC_SRL:
1432 switch ((ctx->opcode >> 21) & 0x1f) { 1425 switch ((ctx->opcode >> 21) & 0x1f) {
1433 case 0: 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 opn = "srl"; 1433 opn = "srl";
1438 break; 1434 break;
1439 case 1: 1435 case 1:
@@ -1449,9 +1445,12 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1449,9 +1445,12 @@ static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1449 } 1445 }
1450 opn = "rotr"; 1446 opn = "rotr";
1451 } else { 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 opn = "srl"; 1454 opn = "srl";
1456 } 1455 }
1457 break; 1456 break;
@@ -1562,7 +1561,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1562,7 +1561,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1562 switch (opc) { 1561 switch (opc) {
1563 case OPC_ADD: 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 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); 1565 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1567 int l1 = gen_new_label(); 1566 int l1 = gen_new_label();
1568 1567
@@ -1576,27 +1575,24 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1576,27 +1575,24 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1576 tcg_gen_xor_tl(r_tmp2, t0, t1); 1575 tcg_gen_xor_tl(r_tmp2, t0, t1);
1577 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); 1576 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1578 tcg_temp_free(r_tmp2); 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 /* operands of same sign, result different sign */ 1579 /* operands of same sign, result different sign */
1583 generate_exception(ctx, EXCP_OVERFLOW); 1580 generate_exception(ctx, EXCP_OVERFLOW);
1584 gen_set_label(l1); 1581 gen_set_label(l1);
  1582 + tcg_temp_free(r_tmp1);
1585 1583
1586 tcg_gen_ext32s_tl(t0, t0); 1584 tcg_gen_ext32s_tl(t0, t0);
1587 } 1585 }
1588 opn = "add"; 1586 opn = "add";
1589 break; 1587 break;
1590 case OPC_ADDU: 1588 case OPC_ADDU:
1591 - tcg_gen_ext32s_tl(t0, t0);  
1592 - tcg_gen_ext32s_tl(t1, t1);  
1593 tcg_gen_add_tl(t0, t0, t1); 1589 tcg_gen_add_tl(t0, t0, t1);
1594 tcg_gen_ext32s_tl(t0, t0); 1590 tcg_gen_ext32s_tl(t0, t0);
1595 opn = "addu"; 1591 opn = "addu";
1596 break; 1592 break;
1597 case OPC_SUB: 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 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); 1596 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1601 int l1 = gen_new_label(); 1597 int l1 = gen_new_label();
1602 1598
@@ -1609,20 +1605,17 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1609,20 +1605,17 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1609 tcg_gen_xor_tl(r_tmp1, r_tmp1, t0); 1605 tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1610 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); 1606 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1611 tcg_temp_free(r_tmp2); 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 /* operands of different sign, first operand and result different sign */ 1609 /* operands of different sign, first operand and result different sign */
1616 generate_exception(ctx, EXCP_OVERFLOW); 1610 generate_exception(ctx, EXCP_OVERFLOW);
1617 gen_set_label(l1); 1611 gen_set_label(l1);
  1612 + tcg_temp_free(r_tmp1);
1618 1613
1619 tcg_gen_ext32s_tl(t0, t0); 1614 tcg_gen_ext32s_tl(t0, t0);
1620 } 1615 }
1621 opn = "sub"; 1616 opn = "sub";
1622 break; 1617 break;
1623 case OPC_SUBU: 1618 case OPC_SUBU:
1624 - tcg_gen_ext32s_tl(t0, t0);  
1625 - tcg_gen_ext32s_tl(t1, t1);  
1626 tcg_gen_sub_tl(t0, t0, t1); 1619 tcg_gen_sub_tl(t0, t0, t1);
1627 tcg_gen_ext32s_tl(t0, t0); 1620 tcg_gen_ext32s_tl(t0, t0);
1628 opn = "subu"; 1621 opn = "subu";
@@ -1630,7 +1623,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1630,7 +1623,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1630 #if defined(TARGET_MIPS64) 1623 #if defined(TARGET_MIPS64)
1631 case OPC_DADD: 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 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); 1627 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1635 int l1 = gen_new_label(); 1628 int l1 = gen_new_label();
1636 1629
@@ -1643,12 +1636,11 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1643,12 +1636,11 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1643 tcg_gen_xor_tl(r_tmp2, t0, t1); 1636 tcg_gen_xor_tl(r_tmp2, t0, t1);
1644 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); 1637 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1645 tcg_temp_free(r_tmp2); 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 /* operands of same sign, result different sign */ 1640 /* operands of same sign, result different sign */
1650 generate_exception(ctx, EXCP_OVERFLOW); 1641 generate_exception(ctx, EXCP_OVERFLOW);
1651 gen_set_label(l1); 1642 gen_set_label(l1);
  1643 + tcg_temp_free(r_tmp1);
1652 } 1644 }
1653 opn = "dadd"; 1645 opn = "dadd";
1654 break; 1646 break;
@@ -1658,7 +1650,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1658,7 +1650,7 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1658 break; 1650 break;
1659 case OPC_DSUB: 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 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL); 1654 TCGv r_tmp2 = tcg_temp_new(TCG_TYPE_TL);
1663 int l1 = gen_new_label(); 1655 int l1 = gen_new_label();
1664 1656
@@ -1670,12 +1662,11 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1670,12 +1662,11 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1670 tcg_gen_xor_tl(r_tmp1, r_tmp1, t0); 1662 tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
1671 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2); 1663 tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
1672 tcg_temp_free(r_tmp2); 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 /* operands of different sign, first operand and result different sign */ 1666 /* operands of different sign, first operand and result different sign */
1677 generate_exception(ctx, EXCP_OVERFLOW); 1667 generate_exception(ctx, EXCP_OVERFLOW);
1678 gen_set_label(l1); 1668 gen_set_label(l1);
  1669 + tcg_temp_free(r_tmp1);
1679 } 1670 }
1680 opn = "dsub"; 1671 opn = "dsub";
1681 break; 1672 break;
@@ -1710,8 +1701,6 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1710,8 +1701,6 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1710 opn = "xor"; 1701 opn = "xor";
1711 break; 1702 break;
1712 case OPC_MUL: 1703 case OPC_MUL:
1713 - tcg_gen_ext32s_tl(t0, t0);  
1714 - tcg_gen_ext32s_tl(t1, t1);  
1715 tcg_gen_mul_tl(t0, t0, t1); 1704 tcg_gen_mul_tl(t0, t0, t1);
1716 tcg_gen_ext32s_tl(t0, t0); 1705 tcg_gen_ext32s_tl(t0, t0);
1717 opn = "mul"; 1706 opn = "mul";
@@ -1737,8 +1726,6 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1737,8 +1726,6 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1737 opn = "movz"; 1726 opn = "movz";
1738 goto print; 1727 goto print;
1739 case OPC_SLLV: 1728 case OPC_SLLV:
1740 - tcg_gen_ext32u_tl(t0, t0);  
1741 - tcg_gen_ext32u_tl(t1, t1);  
1742 tcg_gen_andi_tl(t0, t0, 0x1f); 1729 tcg_gen_andi_tl(t0, t0, 0x1f);
1743 tcg_gen_shl_tl(t0, t1, t0); 1730 tcg_gen_shl_tl(t0, t1, t0);
1744 tcg_gen_ext32s_tl(t0, t0); 1731 tcg_gen_ext32s_tl(t0, t0);
@@ -1748,7 +1735,6 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc, @@ -1748,7 +1735,6 @@ static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1748 tcg_gen_ext32s_tl(t1, t1); 1735 tcg_gen_ext32s_tl(t1, t1);
1749 tcg_gen_andi_tl(t0, t0, 0x1f); 1736 tcg_gen_andi_tl(t0, t0, 0x1f);
1750 tcg_gen_sar_tl(t0, t1, t0); 1737 tcg_gen_sar_tl(t0, t1, t0);
1751 - tcg_gen_ext32s_tl(t0, t0);  
1752 opn = "srav"; 1738 opn = "srav";
1753 break; 1739 break;
1754 case OPC_SRLV: 1740 case OPC_SRLV: