]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH] rx: avoid adding setpsw for rx_cmpstrn when len is const
authorKeith Packard <keithp@keithp.com>
Wed, 16 Apr 2025 20:10:18 +0000 (14:10 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Wed, 16 Apr 2025 20:10:18 +0000 (14:10 -0600)
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.

gcc/config/rx/rx.md

index edb2c96603f5b93e0e4fa30db88b880867e2e7b0..a3d966efdcc99bbf3ff1131ae9b4297d155b16ae 100644 (file)
        (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);
     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;
   }
    (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