The recent investigation of wrong code for the bswap tree optimization showed that we were not generating optical bswap sequences on PA. The PA 2.0 architecture manual shows optimized sequences for half-word, word and double word variables. The attached change implements insn patterns for these operations. The double word sequence isn't obvious.
In implementing these instructions, I noticed we could implement absqi2 and abshi2 using the nullification feature of the PA architecture saving a test and branch. Tested on hppa-unknown-linux-gnu, hppa2.0w-hp-hpux11.11 and hppa64-hp-hpux11.11 with no observed regressions. Committed to trunk. Dave -- John David Anglin dave.ang...@bell.net
2016-02-14 John David Anglin <dang...@gcc.gnu.org> * config/pa/pa.md (absqi2, absghi2, bswaphi2, bswapsi2, bswapdi2): New. Index: config/pa/pa.md =================================================================== --- config/pa/pa.md (revision 233398) +++ config/pa/pa.md (working copy) @@ -1179,6 +1179,22 @@ [(set_attr "type" "multi,multi") (set_attr "length" "8,8")]) +(define_insn "absqi2" + [(set (match_operand:QI 0 "register_operand" "=r") + (abs:QI (match_operand:QI 1 "register_operand" "r")))] + "" + "{extrs|extrw,s},>= %1,31,8,%0\;subi 0,%0,%0" + [(set_attr "type" "multi") + (set_attr "length" "8")]) + +(define_insn "abshi2" + [(set (match_operand:HI 0 "register_operand" "=r") + (abs:HI (match_operand:HI 1 "register_operand" "r")))] + "" + "{extrs|extrw,s},>= %1,31,16,%0\;subi 0,%0,%0" + [(set_attr "type" "multi") + (set_attr "length" "8")]) + (define_insn "abssi2" [(set (match_operand:SI 0 "register_operand" "=r") (abs:SI (match_operand:SI 1 "register_operand" "r")))] @@ -1195,6 +1211,30 @@ [(set_attr "type" "multi") (set_attr "length" "8")]) +(define_insn "bswaphi2" + [(set (match_operand:HI 0 "register_operand" "=&r") + (bswap:HI (match_operand:HI 1 "register_operand" "r")))] + "" + "{extru|extrw,u} %1,23,8,%0\;{dep|depw} %1,23,8,%0" + [(set_attr "type" "multi") + (set_attr "length" "8")]) + +(define_insn "bswapsi2" + [(set (match_operand:SI 0 "register_operand" "=&r") + (bswap:SI (match_operand:SI 1 "register_operand" "r")))] + "" + "{shd|shrpw} %1,%1,16,%0\;{dep|depw} %0,15,8,%0\;{shd|shrpw} %1,%0,8,%0" + [(set_attr "type" "multi") + (set_attr "length" "12")]) + +(define_insn "bswapdi2" + [(set (match_operand:DI 0 "register_operand" "=&r") + (bswap:DI (match_operand:DI 1 "register_operand" "+r")))] + "TARGET_64BIT" + "permh,3210 %1,%1\;hshl %1,8,%0\;hshr,u %1,8,%1\;or %0,%1,%0" + [(set_attr "type" "multi") + (set_attr "length" "16")]) + ;;; Experimental conditional move patterns (define_expand "movsicc"