diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ab0171ebb8..5c5b9f4b840 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-12-17 Andrew Stubbs + + * config/gcn/gcn.h (CLZ_DEFINED_VALUE_AT_ZERO): Define. + (CTZ_DEFINED_VALUE_AT_ZERO): Define. + * config/gcn/gcn.md (s_mnemonic): Add clz and ctz. + (expander): Likewise. + (countzeros): New code iterator. + (si2): New insn pattern. + (di2): New insn pattern. + 2019-12-17 Jakub Jelinek PR target/92962 diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h index bdf7188b5ff..76b449ba5cf 100644 --- a/gcc/config/gcn/gcn.h +++ b/gcc/config/gcn/gcn.h @@ -644,6 +644,10 @@ enum gcn_builtin_codes /* This needs to match gcn_function_value. */ #define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, SGPR_REGNO (RETURN_VALUE_REG)) +/* The s_ff0 and s_flbit instructions return -1 if no input bits are set. */ +#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 2) +#define CTZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = -1, 2) + /* Costs. */ diff --git a/gcc/config/gcn/gcn.md b/gcc/config/gcn/gcn.md index 36908ba45f6..b48af0dbde8 100644 --- a/gcc/config/gcn/gcn.md +++ b/gcc/config/gcn/gcn.md @@ -331,7 +331,9 @@ (define_code_attr s_mnemonic [(not "not%b") - (popcount "bcnt1_i32%b")]) + (popcount "bcnt1_i32%b") + (clz "flbit_i32%b") + (ctz "ff1_i32%b")]) (define_code_attr revmnemonic [(minus "subrev%i") @@ -356,7 +358,9 @@ (umin "umin") (umax "umax") (not "one_cmpl") - (popcount "popcount")]) + (popcount "popcount") + (clz "clz") + (ctz "ctz")]) ;; }}} ;; {{{ Miscellaneous instructions @@ -1389,6 +1393,28 @@ [(set_attr "type" "sop1,vop1") (set_attr "length" "8")]) +(define_code_iterator countzeros [clz ctz]) + +(define_insn "si2" + [(set (match_operand:SI 0 "register_operand" "=Sg,Sg") + (countzeros:SI + (match_operand:SI 1 "gcn_alu_operand" "SgA, B")))] + "" + "s_1\t%0, %1" + [(set_attr "type" "sop1") + (set_attr "length" "4,8")]) + +; The truncate ensures that a constant passed to operand 1 is treated as DImode +(define_insn "di2" + [(set (match_operand:SI 0 "register_operand" "=Sg,Sg") + (truncate:SI + (countzeros:DI + (match_operand:DI 1 "gcn_alu_operand" "SgA, B"))))] + "" + "s_1\t%0, %1" + [(set_attr "type" "sop1") + (set_attr "length" "4,8")]) + ;; }}} ;; {{{ ALU: generic 32-bit binop