aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2024-08-01 10:21:53 +0200
committerGeorg-Johann Lay <avr@gjlay.de>2024-08-01 10:42:36 +0200
commit3e4c47d1088417db599a0793a6d93707228e4f70 (patch)
tree5773bdcea9ccb4c7461592ecf310835b7496a858
parentd0504847970d89d5dd7bd689ca8f7bf82fedf522 (diff)
downloadgcc-3e4c47d1088417db599a0793a6d93707228e4f70.zip
gcc-3e4c47d1088417db599a0793a6d93707228e4f70.tar.gz
gcc-3e4c47d1088417db599a0793a6d93707228e4f70.tar.bz2
AVR: Tweak unsigned comparisons against 256 resp. 65536.
u16 >= 256 can be performed by testing the hi8 part against 0. u32 >= 65536 can be performed by testing the high word against 0. The optimization is performed in split2 after register allocation because the register allocator likely spills for subregs. gcc/ * config/avr/avr.md (cbranch<mode>4_insn): Split to a test of the high part against 0 if possible.
-rw-r--r--gcc/config/avr/avr.md36
1 files changed, 34 insertions, 2 deletions
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 02d0a41..fce5349 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -6742,7 +6742,23 @@
(if_then_else (match_op_dup 0
[(reg:CC REG_CC) (const_int 0)])
(label_ref (match_dup 3))
- (pc)))])
+ (pc)))]
+ {
+ // Unsigned >= 65536 and < 65536 can be performed by testing the
+ // high word against 0.
+ if ((GET_CODE (operands[0]) == LTU
+ || GET_CODE (operands[0]) == GEU)
+ && const_operand (operands[2], <MODE>mode)
+ && INTVAL (avr_to_int_mode (operands[2])) == 65536)
+ {
+ // "cmphi3" of the high word against 0.
+ operands[0] = copy_rtx (operands[0]);
+ PUT_CODE (operands[0], GET_CODE (operands[0]) == GEU ? NE : EQ);
+ operands[1] = simplify_gen_subreg (HImode, operands[1], <MODE>mode, 2);
+ operands[2] = const0_rtx;
+ operands[4] = gen_rtx_SCRATCH (QImode);
+ }
+ })
;; "cbranchpsi4_insn"
(define_insn_and_split "cbranchpsi4_insn"
@@ -6787,7 +6803,23 @@
(if_then_else (match_op_dup 0
[(reg:CC REG_CC) (const_int 0)])
(label_ref (match_dup 3))
- (pc)))])
+ (pc)))]
+ {
+ // Unsigned >= 256 and < 256 can be performed by testing the
+ // high byte against 0.
+ if ((GET_CODE (operands[0]) == LTU
+ || GET_CODE (operands[0]) == GEU)
+ && const_operand (operands[2], <MODE>mode)
+ && INTVAL (avr_to_int_mode (operands[2])) == 256)
+ {
+ rtx_code code = GET_CODE (operands[0]) == GEU ? NE : EQ;
+ rtx hi8 = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 1);
+ rtx cmp = gen_rtx_fmt_ee (code, VOIDmode, cc_reg_rtx, const0_rtx);
+ emit (gen_cmpqi3 (hi8, const0_rtx));
+ emit (gen_branch (operands[3], cmp));
+ DONE;
+ }
+ })
;; Combiner pattern to compare sign- or zero-extended register against
;; a wider register, like comparing uint8_t against uint16_t.