From: uros Date: Mon, 12 Feb 2007 21:08:25 +0000 (+0000) Subject: * config/i386/i386.md (paritydi2, paritysi2): New expanders. X-Git-Tag: upstream/4.9.2~50421 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ec29ad3ea2f37a500974ad0740bfe4274878c3de;p=platform%2Fupstream%2Flinaro-gcc.git * config/i386/i386.md (paritydi2, paritysi2): New expanders. (paritydi2_cmp, paritydi2_cmp): New insn and split patterns. (*parityhi2_cmp, *parityqi2_cmp): New insn patterns. testsuite/ChangeLog: * gcc.target/i386/parity-1.c: New test. * gcc.target/i386/parity-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121863 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bd541e5..0b40844 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2007-02-12 Uros Bizjak + + * config/i386/i386.md (paritydi2, paritysi2): New expanders. + (paritydi2_cmp, paritydi2_cmp): New insn and split patterns. + (*parityhi2_cmp, *parityqi2_cmp): New insn patterns. + 2007-02-12 Eric Botcazou * tree.h (DECL_IGNORED_P): Document further effect for FUNCTION_DECL. @@ -173,8 +179,8 @@ mode. * config/rs6000/rs6000.c (rs6000_builtin_conversion): New. (TARGET_VECTORIZE_BUILTIN_CONVERSION): Defined. - (rs6000_expand_builtin): Add handling a case of ALTIVEC_BUILTIN_VCFUX or - ALTIVEC_BUILTIN_VCFSX. + (rs6000_expand_builtin): Add handling a case of ALTIVEC_BUILTIN_VCFUX + or ALTIVEC_BUILTIN_VCFSX. 2007-02-10 John David Anglin diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 04d0136..5e39568 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -15122,6 +15122,130 @@ [(set_attr "prefix_rep" "1") (set_attr "type" "bitmanip") (set_attr "mode" "HI")]) + +(define_expand "paritydi2" + [(set (match_operand:DI 0 "register_operand" "") + (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))] + "! TARGET_POPCNT" +{ + rtx scratch = gen_reg_rtx (QImode); + rtx cond; + + emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX, + NULL_RTX, operands[1])); + + cond = gen_rtx_fmt_ee (ORDERED, QImode, + gen_rtx_REG (CCmode, FLAGS_REG), + const0_rtx); + emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); + + if (TARGET_64BIT) + emit_insn (gen_zero_extendqidi2 (operands[0], scratch)); + else + { + rtx tmp = gen_reg_rtx (SImode); + + emit_insn (gen_zero_extendqisi2 (tmp, scratch)); + emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); + } + DONE; +}) + +(define_insn_and_split "paritydi2_cmp" + [(set (reg:CC FLAGS_REG) + (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m"))) + (clobber (match_scratch:DI 0 "=r,X")) + (clobber (match_scratch:SI 1 "=r,r")) + (clobber (match_scratch:HI 2 "=Q,Q"))] + "! TARGET_POPCNT" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 1) + (xor:SI (match_dup 1) (match_dup 4))) + (clobber (reg:CC FLAGS_REG))]) + (parallel + [(set (reg:CC FLAGS_REG) + (parity:CC (match_dup 1))) + (clobber (match_dup 1)) + (clobber (match_dup 2))])] +{ + operands[4] = gen_lowpart (SImode, operands[3]); + + if (MEM_P (operands[3])) + emit_move_insn (operands[1], gen_highpart (SImode, operands[3])); + else if (! TARGET_64BIT) + operands[1] = gen_highpart (SImode, operands[3]); + else + { + emit_move_insn (operands[1], gen_lowpart (SImode, operands[3])); + emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32))); + } +}) + +(define_expand "paritysi2" + [(set (match_operand:SI 0 "register_operand" "") + (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))] + "! TARGET_POPCNT" +{ + rtx scratch = gen_reg_rtx (QImode); + rtx cond; + + emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1])); + + cond = gen_rtx_fmt_ee (ORDERED, QImode, + gen_rtx_REG (CCmode, FLAGS_REG), + const0_rtx); + emit_insn (gen_rtx_SET (VOIDmode, scratch, cond)); + + emit_insn (gen_zero_extendqisi2 (operands[0], scratch)); + DONE; +}) + +(define_insn_and_split "paritysi2_cmp" + [(set (reg:CC FLAGS_REG) + (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m"))) + (clobber (match_scratch:SI 0 "=r,X")) + (clobber (match_scratch:HI 1 "=Q,Q"))] + "! TARGET_POPCNT" + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 1) + (xor:HI (match_dup 1) (match_dup 3))) + (clobber (reg:CC FLAGS_REG))]) + (parallel + [(set (reg:CC FLAGS_REG) + (parity:CC (match_dup 1))) + (clobber (match_dup 1))])] +{ + operands[3] = gen_lowpart (HImode, operands[2]); + + if (MEM_P (operands[2])) + emit_move_insn (operands[1], gen_highpart (HImode, operands[2])); + else + { + emit_move_insn (operands[1], gen_lowpart (HImode, operands[2])); + emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16))); + } +}) + +(define_insn "*parityhi2_cmp" + [(set (reg:CC FLAGS_REG) + (parity:CC (match_operand:HI 1 "register_operand" "0"))) + (clobber (match_scratch:HI 0 "=Q"))] + "! TARGET_POPCNT" + "xor{b}\t{%h0, %b0|%b0, %h0}" + [(set_attr "length" "2") + (set_attr "mode" "HI")]) + +(define_insn "*parityqi2_cmp" + [(set (reg:CC FLAGS_REG) + (parity:CC (match_operand:QI 0 "register_operand" "q")))] + "! TARGET_POPCNT" + "test{b}\t%0, %0" + [(set_attr "length" "2") + (set_attr "mode" "QI")]) ;; Thread-local storage patterns for ELF. ;; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2edb100..a2edb27 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-02-12 Uros Bizjak + + * gcc.target/i386/parity-1.c: New test. + * gcc.target/i386/parity-2.c: New test. + 2007-02-12 Roger Sayle * gcc.target/i386/builtin-bswap-3.c: New test case. diff --git a/gcc/testsuite/gcc.target/i386/parity-1.c b/gcc/testsuite/gcc.target/i386/parity-1.c new file mode 100644 index 0000000..f6c881b --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/parity-1.c @@ -0,0 +1,8 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "setnp" } } */ + +int foo(unsigned int x) +{ + return __builtin_parity(x); +} diff --git a/gcc/testsuite/gcc.target/i386/parity-2.c b/gcc/testsuite/gcc.target/i386/parity-2.c new file mode 100644 index 0000000..cb7855a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/parity-2.c @@ -0,0 +1,8 @@ +/* { dg-do compile { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler "setnp" } } */ + +int foo(unsigned long long int x) +{ + return __builtin_parityll(x); +}