]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
iq2000: Fix test and branch instructions
authorRichard Sandiford <richard.sandiford@arm.com>
Fri, 21 Jun 2024 14:40:10 +0000 (15:40 +0100)
committerRichard Sandiford <richard.sandiford@arm.com>
Fri, 21 Jun 2024 14:40:10 +0000 (15:40 +0100)
The iq2000 test and branch instructions had patterns like:

  [(set (pc)
(if_then_else
 (eq (and:SI (match_operand:SI 0 "register_operand" "r")
     (match_operand:SI 1 "power_of_2_operand" "I"))
      (const_int 0))
 (match_operand 2 "pc_or_label_operand" "")
 (match_operand 3 "pc_or_label_operand" "")))]

power_of_2_operand allows any 32-bit power of 2, whereas "I" only
accepts 16-bit signed constants.  This meant that any power of 2
greater than 32768 would cause an "insn does not satisfy its
constraints" ICE.

Also, the %p operand modifier barfed on 1<<31, which is sign-
rather than zero-extended to 64 bits.  The code is inherently
limited to 32-bit operands -- power_of_2_operand contains a test
involving "unsigned" -- so this patch just ands with 0xffffffff.

gcc/
* config/iq2000/iq2000.cc (iq2000_print_operand): Make %p handle 1<<31.
* config/iq2000/iq2000.md: Remove "I" constraints on
power_of_2_operands.

gcc/config/iq2000/iq2000.cc
gcc/config/iq2000/iq2000.md

index f9f8c41784169cec16381ed15041e2954d0ed151..136675d0fbbb7e1f54eed91429074bc1d85d3994 100644 (file)
@@ -3127,7 +3127,7 @@ iq2000_print_operand (FILE *file, rtx op, int letter)
     {
       int value;
       if (code != CONST_INT
-         || (value = exact_log2 (INTVAL (op))) < 0)
+         || (value = exact_log2 (UINTVAL (op) & 0xffffffff)) < 0)
        output_operand_lossage ("invalid %%p value");
       else
        fprintf (file, "%d", value);
index 8617efac3c68efd29e3fc38d72dee76f3d3c72cf..e62c250ce8c0c59c78297627266aa0b78e2b2860 100644 (file)
   [(set (pc)
        (if_then_else
         (eq (and:SI (match_operand:SI 0 "register_operand" "r")
-                    (match_operand:SI 1 "power_of_2_operand" "I"))
+                    (match_operand:SI 1 "power_of_2_operand"))
              (const_int 0))
         (match_operand 2 "pc_or_label_operand" "")
         (match_operand 3 "pc_or_label_operand" "")))]
   [(set (pc)
        (if_then_else
         (ne (and:SI (match_operand:SI 0 "register_operand" "r")
-                    (match_operand:SI 1 "power_of_2_operand" "I"))
+                    (match_operand:SI 1 "power_of_2_operand"))
             (const_int 0))
         (match_operand 2 "pc_or_label_operand" "")
         (match_operand 3 "pc_or_label_operand" "")))]