[arm] Handle some constant comparisons using rsbs+rscs
In a small number of cases it is preferable to handle comparisons with
constants using the sequence
RSBS tmp, Xlo, constlo
RSCS tmp, Xhi, consthi
which allows us to handle a small number of LE/GT/LEU/GEU cases when
changing the code to use LT/GE/LTU/GEU would make the constant more
expensive. Sadly, we cannot do this on Thumb, since we need RSC, so we
now always use the incremented constant in that case since normally that
still works out cheaper than forcing the entire constant into a register.
Further investigation has also shown that the canonicalization of a
reverse subtract and compare is valid for signed as well as unsigned value,
so we relax the restriction on selecting CC_RSBmode to allow all types
of compare.
* config/arm/arm.c (arm_const_double_prefer_rsbs_rsc): New function.
(arm_canonicalize_comparison): For GT/LE/GTU/GEU, use the constant
unchanged only if that will be cheaper.
(arm_select_cc_mode): Recognize a swapped comparison that will
be regenerated using RSBS or RSCS. Relax restriction on selecting
CC_RSBmode.
(arm_gen_dicompare_reg): Handle LE/GT/LEU/GEU comparisons against
a constant.
(arm_gen_compare_reg): Handle compare (CONST, X) when the mode
is CC_RSBmode.
(maybe_get_arm_condition_code): CC_RSBmode now returns the same codes
as CCmode.
* config/arm/arm.md (rsb_imm_compare_scratch): New pattern.
(rscsi3_<CC_EXTEND>out_scratch): New pattern.
From-SVN: r277180