From: Keith Packard Date: Wed, 16 Apr 2025 20:10:18 +0000 (-0600) Subject: [PATCH] rx: avoid adding setpsw for rx_cmpstrn when len is const X-Git-Tag: basepoints/gcc-16~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83340869a21baafc889c05b6b5c632a226c509bc;p=thirdparty%2Fgcc.git [PATCH] rx: avoid adding setpsw for rx_cmpstrn when len is const pattern using rx_cmpstrn is cmpstrsi for which len is a constant -1, so we'll be moving the setpsw instructions from rx_cmpstrn to cmpstrnsi as follows: 1. Adjust the predicate on the length operand from "register_operand" to "nonmemory_operand". This will allow constants to appear here, instead of having them already transferred into a register. 2. Check to see if the len value is constant, and then check if it is actually zero. In that case, short-circuit the rest of the pattern and set the result register to 0. 3. Emit 'setpsw c' and 'setpsw z' instructions when the len is not a constant, in case it turns out to be zero at runtime. 4. Remove the two 'setpsw' instructions from rx_cmpstrn. gcc/ * config/rx/rx.md (cmpstrnsi): Allow constant length. For static length 0, just store 0 into the output register. For dynamic zero, set C/Z appropriately. (rxcmpstrn): No longer set C/Z. --- diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md index edb2c96603f..a3d966efdcc 100644 --- a/gcc/config/rx/rx.md +++ b/gcc/config/rx/rx.md @@ -2541,10 +2541,17 @@ (unspec_volatile:SI [(match_operand:BLK 1 "memory_operand") ;; String1 (match_operand:BLK 2 "memory_operand")] ;; String2 UNSPEC_CMPSTRN)) - (use (match_operand:SI 3 "register_operand")) ;; Max Length + (use (match_operand:SI 3 "nonmemory_operand")) ;; Max Length (match_operand:SI 4 "immediate_operand")] ;; Known Align "rx_allow_string_insns" { + bool const_len = CONST_INT_P (operands[3]); + if (const_len && operands[3] == CONST0_RTX (SImode)) + { + emit_move_insn (operands[0], CONST0_RTX (SImode)); + DONE; + } + rtx str1 = gen_rtx_REG (SImode, 1); rtx str2 = gen_rtx_REG (SImode, 2); rtx len = gen_rtx_REG (SImode, 3); @@ -2553,6 +2560,13 @@ emit_move_insn (str2, force_operand (XEXP (operands[2], 0), NULL_RTX)); emit_move_insn (len, operands[3]); + /* Set flags in case len is zero */ + if (!const_len) + { + emit_insn (gen_setpsw (GEN_INT ('C'))); + emit_insn (gen_setpsw (GEN_INT ('Z'))); + } + emit_insn (gen_rx_cmpstrn (operands[0], operands[1], operands[2])); DONE; } @@ -2590,9 +2604,7 @@ (clobber (reg:SI 3)) (clobber (reg:CC CC_REG))] "rx_allow_string_insns" - "setpsw z ; Set flags in case len is zero - setpsw c - scmpu ; Perform the string comparison + "scmpu ; Perform the string comparison mov #-1, %0 ; Set up -1 result (which cannot be created ; by the SC insn) bnc ?+ ; If Carry is not set skip over