Skip to content

Commit 0774389

Browse files
jjsuwa-sys3175jcmvbkbc
authored andcommitted
xtensa: Optimize bitwise AND operation with some specific forms of constants
This patch offers several insn-and-split patterns for bitwise AND with register and constant that can be represented as: i. 1's least significant N bits and the others 0's (17 <= N <= 31) ii. 1's most significant N bits and the others 0's (12 <= N <= 31) iii. M 1's sequence of bits and trailing N 0's bits, that cannot fit into a "MOVI Ax, simm12" instruction (1 <= M <= 16, 1 <= N <= 30) And also offers shortcuts for conditional branch if each of the abovementioned operations is (not) equal to zero. gcc/ChangeLog: * config/xtensa/predicates.md (shifted_mask_operand): New predicate. * config/xtensa/xtensa.md (*andsi3_const_pow2_minus_one): New insn-and-split pattern. (*andsi3_const_negative_pow2, *andsi3_const_shifted_mask, *masktrue_const_pow2_minus_one, *masktrue_const_negative_pow2, *masktrue_const_shifted_mask): Ditto.
1 parent 70ce04c commit 0774389

File tree

2 files changed

+189
-0
lines changed

2 files changed

+189
-0
lines changed

gcc/config/xtensa/predicates.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@
5252
(match_test "xtensa_mask_immediate (INTVAL (op))"))
5353
(match_operand 0 "register_operand")))
5454

55+
(define_predicate "shifted_mask_operand"
56+
(match_code "const_int")
57+
{
58+
HOST_WIDE_INT mask = INTVAL (op);
59+
int shift = ctz_hwi (mask);
60+
61+
return IN_RANGE (shift, 1, 31)
62+
&& xtensa_mask_immediate ((uint32_t)mask >> shift);
63+
})
64+
5565
(define_predicate "extui_fldsz_operand"
5666
(and (match_code "const_int")
5767
(match_test "IN_RANGE (INTVAL (op), 1, 16)")))

gcc/config/xtensa/xtensa.md

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,83 @@
645645
(set_attr "mode" "SI")
646646
(set_attr "length" "6")])
647647

648+
(define_insn_and_split "*andsi3_const_pow2_minus_one"
649+
[(set (match_operand:SI 0 "register_operand" "=a")
650+
(and:SI (match_operand:SI 1 "register_operand" "r")
651+
(match_operand:SI 2 "const_int_operand" "i")))]
652+
"IN_RANGE (exact_log2 (INTVAL (operands[2]) + 1), 17, 31)"
653+
"#"
654+
"&& 1"
655+
[(set (match_dup 0)
656+
(ashift:SI (match_dup 1)
657+
(match_dup 2)))
658+
(set (match_dup 0)
659+
(lshiftrt:SI (match_dup 0)
660+
(match_dup 2)))]
661+
{
662+
operands[2] = GEN_INT (32 - floor_log2 (INTVAL (operands[2]) + 1));
663+
}
664+
[(set_attr "type" "arith")
665+
(set_attr "mode" "SI")
666+
(set (attr "length")
667+
(if_then_else (match_test "TARGET_DENSITY
668+
&& INTVAL (operands[2]) == 0x7FFFFFFF")
669+
(const_int 5)
670+
(const_int 6)))])
671+
672+
(define_insn_and_split "*andsi3_const_negative_pow2"
673+
[(set (match_operand:SI 0 "register_operand" "=a")
674+
(and:SI (match_operand:SI 1 "register_operand" "r")
675+
(match_operand:SI 2 "const_int_operand" "i")))]
676+
"IN_RANGE (exact_log2 (-INTVAL (operands[2])), 12, 31)"
677+
"#"
678+
"&& 1"
679+
[(set (match_dup 0)
680+
(lshiftrt:SI (match_dup 1)
681+
(match_dup 2)))
682+
(set (match_dup 0)
683+
(ashift:SI (match_dup 0)
684+
(match_dup 2)))]
685+
{
686+
operands[2] = GEN_INT (floor_log2 (-INTVAL (operands[2])));
687+
}
688+
[(set_attr "type" "arith")
689+
(set_attr "mode" "SI")
690+
(set_attr "length" "6")])
691+
692+
(define_insn_and_split "*andsi3_const_shifted_mask"
693+
[(set (match_operand:SI 0 "register_operand" "=a")
694+
(and:SI (match_operand:SI 1 "register_operand" "r")
695+
(match_operand:SI 2 "shifted_mask_operand" "i")))]
696+
"! xtensa_simm12b (INTVAL (operands[2]))"
697+
"#"
698+
"&& 1"
699+
[(set (match_dup 0)
700+
(zero_extract:SI (match_dup 1)
701+
(match_dup 3)
702+
(match_dup 4)))
703+
(set (match_dup 0)
704+
(ashift:SI (match_dup 0)
705+
(match_dup 2)))]
706+
{
707+
HOST_WIDE_INT mask = INTVAL (operands[2]);
708+
int shift = ctz_hwi (mask);
709+
int mask_size = floor_log2 (((uint32_t)mask >> shift) + 1);
710+
int mask_pos = shift;
711+
if (BITS_BIG_ENDIAN)
712+
mask_pos = (32 - (mask_size + shift)) & 0x1f;
713+
operands[2] = GEN_INT (shift);
714+
operands[3] = GEN_INT (mask_size);
715+
operands[4] = GEN_INT (mask_pos);
716+
}
717+
[(set_attr "type" "arith")
718+
(set_attr "mode" "SI")
719+
(set (attr "length")
720+
(if_then_else (match_test "TARGET_DENSITY
721+
&& ctz_hwi (INTVAL (operands[2])) == 1")
722+
(const_int 5)
723+
(const_int 6)))])
724+
648725
(define_insn "iorsi3"
649726
[(set (match_operand:SI 0 "register_operand" "=a")
650727
(ior:SI (match_operand:SI 1 "register_operand" "%r")
@@ -1649,6 +1726,108 @@
16491726
(set_attr "mode" "none")
16501727
(set_attr "length" "3")])
16511728

1729+
(define_insn_and_split "*masktrue_const_pow2_minus_one"
1730+
[(set (pc)
1731+
(if_then_else (match_operator 3 "boolean_operator"
1732+
[(and:SI (match_operand:SI 0 "register_operand" "r")
1733+
(match_operand:SI 1 "const_int_operand" "i"))
1734+
(const_int 0)])
1735+
(label_ref (match_operand 2 "" ""))
1736+
(pc)))]
1737+
"IN_RANGE (exact_log2 (INTVAL (operands[1]) + 1), 17, 31)"
1738+
"#"
1739+
"&& can_create_pseudo_p ()"
1740+
[(set (match_dup 4)
1741+
(ashift:SI (match_dup 0)
1742+
(match_dup 1)))
1743+
(set (pc)
1744+
(if_then_else (match_op_dup 3
1745+
[(match_dup 4)
1746+
(const_int 0)])
1747+
(label_ref (match_dup 2))
1748+
(pc)))]
1749+
{
1750+
operands[1] = GEN_INT (32 - floor_log2 (INTVAL (operands[1]) + 1));
1751+
operands[4] = gen_reg_rtx (SImode);
1752+
}
1753+
[(set_attr "type" "jump")
1754+
(set_attr "mode" "none")
1755+
(set (attr "length")
1756+
(if_then_else (match_test "TARGET_DENSITY
1757+
&& INTVAL (operands[1]) == 0x7FFFFFFF")
1758+
(const_int 5)
1759+
(const_int 6)))])
1760+
1761+
(define_insn_and_split "*masktrue_const_negative_pow2"
1762+
[(set (pc)
1763+
(if_then_else (match_operator 3 "boolean_operator"
1764+
[(and:SI (match_operand:SI 0 "register_operand" "r")
1765+
(match_operand:SI 1 "const_int_operand" "i"))
1766+
(const_int 0)])
1767+
(label_ref (match_operand 2 "" ""))
1768+
(pc)))]
1769+
"IN_RANGE (exact_log2 (-INTVAL (operands[1])), 12, 30)"
1770+
"#"
1771+
"&& can_create_pseudo_p ()"
1772+
[(set (match_dup 4)
1773+
(lshiftrt:SI (match_dup 0)
1774+
(match_dup 1)))
1775+
(set (pc)
1776+
(if_then_else (match_op_dup 3
1777+
[(match_dup 4)
1778+
(const_int 0)])
1779+
(label_ref (match_dup 2))
1780+
(pc)))]
1781+
{
1782+
operands[1] = GEN_INT (floor_log2 (-INTVAL (operands[1])));
1783+
operands[4] = gen_reg_rtx (SImode);
1784+
}
1785+
[(set_attr "type" "jump")
1786+
(set_attr "mode" "none")
1787+
(set_attr "length" "6")])
1788+
1789+
(define_insn_and_split "*masktrue_const_shifted_mask"
1790+
[(set (pc)
1791+
(if_then_else (match_operator 4 "boolean_operator"
1792+
[(and:SI (match_operand:SI 0 "register_operand" "r")
1793+
(match_operand:SI 1 "shifted_mask_operand" "i"))
1794+
(match_operand:SI 2 "const_int_operand" "i")])
1795+
(label_ref (match_operand 3 "" ""))
1796+
(pc)))]
1797+
"(INTVAL (operands[2]) & ((1 << ctz_hwi (INTVAL (operands[1]))) - 1)) == 0
1798+
&& xtensa_b4const_or_zero ((uint32_t)INTVAL (operands[2]) >> ctz_hwi (INTVAL (operands[1])))"
1799+
"#"
1800+
"&& can_create_pseudo_p ()"
1801+
[(set (match_dup 6)
1802+
(zero_extract:SI (match_dup 0)
1803+
(match_dup 5)
1804+
(match_dup 1)))
1805+
(set (pc)
1806+
(if_then_else (match_op_dup 4
1807+
[(match_dup 6)
1808+
(match_dup 2)])
1809+
(label_ref (match_dup 3))
1810+
(pc)))]
1811+
{
1812+
HOST_WIDE_INT mask = INTVAL (operands[1]);
1813+
int shift = ctz_hwi (mask);
1814+
int mask_size = floor_log2 (((uint32_t)mask >> shift) + 1);
1815+
int mask_pos = shift;
1816+
if (BITS_BIG_ENDIAN)
1817+
mask_pos = (32 - (mask_size + shift)) & 0x1f;
1818+
operands[1] = GEN_INT (mask_pos);
1819+
operands[2] = GEN_INT ((uint32_t)INTVAL (operands[2]) >> shift);
1820+
operands[5] = GEN_INT (mask_size);
1821+
operands[6] = gen_reg_rtx (SImode);
1822+
}
1823+
[(set_attr "type" "jump")
1824+
(set_attr "mode" "none")
1825+
(set (attr "length")
1826+
(if_then_else (match_test "TARGET_DENSITY
1827+
&& (uint32_t)INTVAL (operands[2]) >> ctz_hwi (INTVAL (operands[1])) == 0")
1828+
(const_int 5)
1829+
(const_int 6)))])
1830+
16521831

16531832
;; Zero-overhead looping support.
16541833

0 commit comments

Comments
 (0)