Commit 7fc8105195fb154d219681b115ae1832c2a71c4b
1 parent
515e2f7e
tcg: optimize logical operations
Simplify nand/nor/eqv and move their optimizations to and/or/xor Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6805 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
60 additions
and
50 deletions
tcg/tcg-op.h
| @@ -436,7 +436,11 @@ static inline void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) | @@ -436,7 +436,11 @@ static inline void tcg_gen_subi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) | ||
| 436 | 436 | ||
| 437 | static inline void tcg_gen_and_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) | 437 | static inline void tcg_gen_and_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) |
| 438 | { | 438 | { |
| 439 | - tcg_gen_op3_i32(INDEX_op_and_i32, ret, arg1, arg2); | 439 | + if (TCGV_EQUAL_I32(arg1, arg2)) { |
| 440 | + tcg_gen_mov_i32(ret, arg1); | ||
| 441 | + } else { | ||
| 442 | + tcg_gen_op3_i32(INDEX_op_and_i32, ret, arg1, arg2); | ||
| 443 | + } | ||
| 440 | } | 444 | } |
| 441 | 445 | ||
| 442 | static inline void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) | 446 | static inline void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) |
| @@ -455,7 +459,11 @@ static inline void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) | @@ -455,7 +459,11 @@ static inline void tcg_gen_andi_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) | ||
| 455 | 459 | ||
| 456 | static inline void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) | 460 | static inline void tcg_gen_or_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) |
| 457 | { | 461 | { |
| 458 | - tcg_gen_op3_i32(INDEX_op_or_i32, ret, arg1, arg2); | 462 | + if (TCGV_EQUAL_I32(arg1, arg2)) { |
| 463 | + tcg_gen_mov_i32(ret, arg1); | ||
| 464 | + } else { | ||
| 465 | + tcg_gen_op3_i32(INDEX_op_or_i32, ret, arg1, arg2); | ||
| 466 | + } | ||
| 459 | } | 467 | } |
| 460 | 468 | ||
| 461 | static inline void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) | 469 | static inline void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) |
| @@ -474,7 +482,11 @@ static inline void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) | @@ -474,7 +482,11 @@ static inline void tcg_gen_ori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) | ||
| 474 | 482 | ||
| 475 | static inline void tcg_gen_xor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) | 483 | static inline void tcg_gen_xor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) |
| 476 | { | 484 | { |
| 477 | - tcg_gen_op3_i32(INDEX_op_xor_i32, ret, arg1, arg2); | 485 | + if (TCGV_EQUAL_I32(arg1, arg2)) { |
| 486 | + tcg_gen_movi_i32(ret, 0); | ||
| 487 | + } else { | ||
| 488 | + tcg_gen_op3_i32(INDEX_op_xor_i32, ret, arg1, arg2); | ||
| 489 | + } | ||
| 478 | } | 490 | } |
| 479 | 491 | ||
| 480 | static inline void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) | 492 | static inline void tcg_gen_xori_i32(TCGv_i32 ret, TCGv_i32 arg1, int32_t arg2) |
| @@ -745,14 +757,22 @@ static inline void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | @@ -745,14 +757,22 @@ static inline void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | ||
| 745 | 757 | ||
| 746 | static inline void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | 758 | static inline void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) |
| 747 | { | 759 | { |
| 748 | - tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); | ||
| 749 | - tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); | 760 | + if (TCGV_EQUAL_I64(arg1, arg2)) { |
| 761 | + tcg_gen_mov_i64(ret, arg1); | ||
| 762 | + } else { | ||
| 763 | + tcg_gen_andi_i32(TCGV_LOW(ret), TCGV_LOW(arg1), arg2); | ||
| 764 | + tcg_gen_andi_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), arg2 >> 32); | ||
| 765 | + } | ||
| 750 | } | 766 | } |
| 751 | 767 | ||
| 752 | static inline void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | 768 | static inline void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) |
| 753 | { | 769 | { |
| 754 | - tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); | ||
| 755 | - tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); | 770 | + if (TCGV_EQUAL_I64(arg1, arg2)) { |
| 771 | + tcg_gen_mov_i64(ret, arg1); | ||
| 772 | + } else { | ||
| 773 | + tcg_gen_or_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); | ||
| 774 | + tcg_gen_or_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); | ||
| 775 | + } | ||
| 756 | } | 776 | } |
| 757 | 777 | ||
| 758 | static inline void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | 778 | static inline void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) |
| @@ -763,8 +783,12 @@ static inline void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | @@ -763,8 +783,12 @@ static inline void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | ||
| 763 | 783 | ||
| 764 | static inline void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | 784 | static inline void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) |
| 765 | { | 785 | { |
| 766 | - tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); | ||
| 767 | - tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); | 786 | + if (TCGV_EQUAL_I64(arg1, arg2)) { |
| 787 | + tcg_gen_movi_i64(ret, 0); | ||
| 788 | + } else { | ||
| 789 | + tcg_gen_xor_i32(TCGV_LOW(ret), TCGV_LOW(arg1), TCGV_LOW(arg2)); | ||
| 790 | + tcg_gen_xor_i32(TCGV_HIGH(ret), TCGV_HIGH(arg1), TCGV_HIGH(arg2)); | ||
| 791 | + } | ||
| 768 | } | 792 | } |
| 769 | 793 | ||
| 770 | static inline void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | 794 | static inline void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) |
| @@ -943,7 +967,11 @@ static inline void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | @@ -943,7 +967,11 @@ static inline void tcg_gen_sub_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | ||
| 943 | 967 | ||
| 944 | static inline void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | 968 | static inline void tcg_gen_and_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) |
| 945 | { | 969 | { |
| 946 | - tcg_gen_op3_i64(INDEX_op_and_i64, ret, arg1, arg2); | 970 | + if (TCGV_EQUAL_I64(arg1, arg2)) { |
| 971 | + tcg_gen_mov_i64(ret, arg1); | ||
| 972 | + } else { | ||
| 973 | + tcg_gen_op3_i64(INDEX_op_and_i64, ret, arg1, arg2); | ||
| 974 | + } | ||
| 947 | } | 975 | } |
| 948 | 976 | ||
| 949 | static inline void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | 977 | static inline void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) |
| @@ -955,7 +983,11 @@ static inline void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | @@ -955,7 +983,11 @@ static inline void tcg_gen_andi_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | ||
| 955 | 983 | ||
| 956 | static inline void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | 984 | static inline void tcg_gen_or_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) |
| 957 | { | 985 | { |
| 958 | - tcg_gen_op3_i64(INDEX_op_or_i64, ret, arg1, arg2); | 986 | + if (TCGV_EQUAL_I64(arg1, arg2)) { |
| 987 | + tcg_gen_mov_i64(ret, arg1); | ||
| 988 | + } else { | ||
| 989 | + tcg_gen_op3_i64(INDEX_op_or_i64, ret, arg1, arg2); | ||
| 990 | + } | ||
| 959 | } | 991 | } |
| 960 | 992 | ||
| 961 | static inline void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | 993 | static inline void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) |
| @@ -967,7 +999,11 @@ static inline void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | @@ -967,7 +999,11 @@ static inline void tcg_gen_ori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | ||
| 967 | 999 | ||
| 968 | static inline void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | 1000 | static inline void tcg_gen_xor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) |
| 969 | { | 1001 | { |
| 970 | - tcg_gen_op3_i64(INDEX_op_xor_i64, ret, arg1, arg2); | 1002 | + if (TCGV_EQUAL_I64(arg1, arg2)) { |
| 1003 | + tcg_gen_movi_i64(ret, 0); | ||
| 1004 | + } else { | ||
| 1005 | + tcg_gen_op3_i64(INDEX_op_xor_i64, ret, arg1, arg2); | ||
| 1006 | + } | ||
| 971 | } | 1007 | } |
| 972 | 1008 | ||
| 973 | static inline void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) | 1009 | static inline void tcg_gen_xori_i64(TCGv_i64 ret, TCGv_i64 arg1, int64_t arg2) |
| @@ -1509,64 +1545,38 @@ static inline void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | @@ -1509,64 +1545,38 @@ static inline void tcg_gen_andc_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | ||
| 1509 | 1545 | ||
| 1510 | static inline void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) | 1546 | static inline void tcg_gen_eqv_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) |
| 1511 | { | 1547 | { |
| 1512 | - TCGv_i32 t0; | ||
| 1513 | - t0 = tcg_temp_new_i32(); | ||
| 1514 | - tcg_gen_xor_i32(t0, arg1, arg2); | ||
| 1515 | - tcg_gen_not_i32(ret, t0); | ||
| 1516 | - tcg_temp_free_i32(t0); | 1548 | + tcg_gen_xor_i32(ret, arg1, arg2); |
| 1549 | + tcg_gen_not_i32(ret, ret); | ||
| 1517 | } | 1550 | } |
| 1518 | 1551 | ||
| 1519 | static inline void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | 1552 | static inline void tcg_gen_eqv_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) |
| 1520 | { | 1553 | { |
| 1521 | - TCGv_i64 t0; | ||
| 1522 | - t0 = tcg_temp_new_i64(); | ||
| 1523 | - tcg_gen_xor_i64(t0, arg1, arg2); | ||
| 1524 | - tcg_gen_not_i64(ret, t0); | ||
| 1525 | - tcg_temp_free_i64(t0); | 1554 | + tcg_gen_xor_i64(ret, arg1, arg2); |
| 1555 | + tcg_gen_not_i64(ret, ret); | ||
| 1526 | } | 1556 | } |
| 1527 | 1557 | ||
| 1528 | static inline void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) | 1558 | static inline void tcg_gen_nand_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) |
| 1529 | { | 1559 | { |
| 1530 | - TCGv_i32 t0; | ||
| 1531 | - t0 = tcg_temp_new_i32(); | ||
| 1532 | - tcg_gen_and_i32(t0, arg1, arg2); | ||
| 1533 | - tcg_gen_not_i32(ret, t0); | ||
| 1534 | - tcg_temp_free_i32(t0); | 1560 | + tcg_gen_and_i32(ret, arg1, arg2); |
| 1561 | + tcg_gen_not_i32(ret, ret); | ||
| 1535 | } | 1562 | } |
| 1536 | 1563 | ||
| 1537 | static inline void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | 1564 | static inline void tcg_gen_nand_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) |
| 1538 | { | 1565 | { |
| 1539 | - TCGv_i64 t0; | ||
| 1540 | - t0 = tcg_temp_new_i64(); | ||
| 1541 | - tcg_gen_and_i64(t0, arg1, arg2); | ||
| 1542 | - tcg_gen_not_i64(ret, t0); | ||
| 1543 | - tcg_temp_free_i64(t0); | 1566 | + tcg_gen_and_i64(ret, arg1, arg2); |
| 1567 | + tcg_gen_not_i64(ret, ret); | ||
| 1544 | } | 1568 | } |
| 1545 | 1569 | ||
| 1546 | static inline void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) | 1570 | static inline void tcg_gen_nor_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) |
| 1547 | { | 1571 | { |
| 1548 | - if (TCGV_EQUAL_I32(arg1, arg2)) { | ||
| 1549 | - tcg_gen_not_i32(ret, arg1); | ||
| 1550 | - } else { | ||
| 1551 | - TCGv_i32 t0; | ||
| 1552 | - t0 = tcg_temp_new_i32(); | ||
| 1553 | - tcg_gen_or_i32(t0, arg1, arg2); | ||
| 1554 | - tcg_gen_not_i32(ret, t0); | ||
| 1555 | - tcg_temp_free_i32(t0); | ||
| 1556 | - } | 1572 | + tcg_gen_or_i32(ret, arg1, arg2); |
| 1573 | + tcg_gen_not_i32(ret, ret); | ||
| 1557 | } | 1574 | } |
| 1558 | 1575 | ||
| 1559 | static inline void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) | 1576 | static inline void tcg_gen_nor_i64(TCGv_i64 ret, TCGv_i64 arg1, TCGv_i64 arg2) |
| 1560 | { | 1577 | { |
| 1561 | - if (TCGV_EQUAL_I64(arg1, arg2)) { | ||
| 1562 | - tcg_gen_not_i64(ret, arg1); | ||
| 1563 | - } else { | ||
| 1564 | - TCGv_i64 t0; | ||
| 1565 | - t0 = tcg_temp_new_i64(); | ||
| 1566 | - tcg_gen_or_i64(t0, arg1, arg2); | ||
| 1567 | - tcg_gen_not_i64(ret, t0); | ||
| 1568 | - tcg_temp_free_i64(t0); | ||
| 1569 | - } | 1578 | + tcg_gen_or_i64(ret, arg1, arg2); |
| 1579 | + tcg_gen_not_i64(ret, ret); | ||
| 1570 | } | 1580 | } |
| 1571 | 1581 | ||
| 1572 | static inline void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) | 1582 | static inline void tcg_gen_orc_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) |