]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/reload.c
poly_int: GET_MODE_SIZE
[thirdparty/gcc.git] / gcc / reload.c
index ec0c05a13db9581750c8256253717209d100670a..88299a8a9058196e6a0f88600348fc208cc8c314 100644 (file)
@@ -823,9 +823,11 @@ static bool
 complex_word_subreg_p (machine_mode outer_mode, rtx reg)
 {
   machine_mode inner_mode = GET_MODE (reg);
-  return (GET_MODE_SIZE (outer_mode) <= UNITS_PER_WORD
-         && GET_MODE_SIZE (inner_mode) > UNITS_PER_WORD
-         && GET_MODE_SIZE (inner_mode) / UNITS_PER_WORD != REG_NREGS (reg));
+  poly_uint64 reg_words = REG_NREGS (reg) * UNITS_PER_WORD;
+  return (known_le (GET_MODE_SIZE (outer_mode), UNITS_PER_WORD)
+         && maybe_gt (GET_MODE_SIZE (inner_mode), UNITS_PER_WORD)
+         && !known_equal_after_align_up (GET_MODE_SIZE (inner_mode),
+                                         reg_words, UNITS_PER_WORD));
 }
 
 /* Return true if X is a SUBREG that will need reloading of its SUBREG_REG
@@ -1061,7 +1063,7 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
                && REGNO (SUBREG_REG (in)) >= FIRST_PSEUDO_REGISTER)
               || MEM_P (SUBREG_REG (in)))
              && (paradoxical_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
-                 || (GET_MODE_SIZE (inmode) <= UNITS_PER_WORD
+                 || (known_le (GET_MODE_SIZE (inmode), UNITS_PER_WORD)
                      && is_a <scalar_int_mode> (GET_MODE (SUBREG_REG (in)),
                                                 &inner_mode)
                      && GET_MODE_SIZE (inner_mode) <= UNITS_PER_WORD
@@ -1069,9 +1071,10 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
                      && LOAD_EXTEND_OP (inner_mode) != UNKNOWN)
                  || (WORD_REGISTER_OPERATIONS
                      && partial_subreg_p (inmode, GET_MODE (SUBREG_REG (in)))
-                     && ((GET_MODE_SIZE (inmode) - 1) / UNITS_PER_WORD ==
-                         ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1)
-                          / UNITS_PER_WORD)))))
+                     && (known_equal_after_align_down
+                         (GET_MODE_SIZE (inmode) - 1,
+                          GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))) - 1,
+                          UNITS_PER_WORD)))))
          || (REG_P (SUBREG_REG (in))
              && REGNO (SUBREG_REG (in)) < FIRST_PSEUDO_REGISTER
              /* The case where out is nonzero
@@ -1099,7 +1102,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
          && MEM_P (in))
        /* This is supposed to happen only for paradoxical subregs made by
           combine.c.  (SUBREG (MEM)) isn't supposed to occur other ways.  */
-       gcc_assert (GET_MODE_SIZE (GET_MODE (in)) <= GET_MODE_SIZE (inmode));
+       gcc_assert (known_le (GET_MODE_SIZE (GET_MODE (in)),
+                             GET_MODE_SIZE (inmode)));
 
       inmode = GET_MODE (in);
     }
@@ -1158,16 +1162,17 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
              && (paradoxical_subreg_p (outmode, GET_MODE (SUBREG_REG (out)))
                  || (WORD_REGISTER_OPERATIONS
                      && partial_subreg_p (outmode, GET_MODE (SUBREG_REG (out)))
-                     && ((GET_MODE_SIZE (outmode) - 1) / UNITS_PER_WORD ==
-                         ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1)
-                          / UNITS_PER_WORD)))))
+                     && (known_equal_after_align_down
+                         (GET_MODE_SIZE (outmode) - 1,
+                          GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))) - 1,
+                          UNITS_PER_WORD)))))
          || (REG_P (SUBREG_REG (out))
              && REGNO (SUBREG_REG (out)) < FIRST_PSEUDO_REGISTER
              /* The case of a word mode subreg
                 is handled differently in the following statement.  */
-             && ! (GET_MODE_SIZE (outmode) <= UNITS_PER_WORD
-                   && (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))
-                       > UNITS_PER_WORD))
+             && ! (known_le (GET_MODE_SIZE (outmode), UNITS_PER_WORD)
+                   && maybe_gt (GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))),
+                                UNITS_PER_WORD))
              && !targetm.hard_regno_mode_ok (subreg_regno (out), outmode))
          || (secondary_reload_class (0, rclass, outmode, out) != NO_REGS
              && (secondary_reload_class (0, rclass, GET_MODE (SUBREG_REG (out)),
@@ -1185,8 +1190,8 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
       outloc = &SUBREG_REG (out);
       out = *outloc;
       gcc_assert (WORD_REGISTER_OPERATIONS || !MEM_P (out)
-                 || GET_MODE_SIZE (GET_MODE (out))
-                    <= GET_MODE_SIZE (outmode));
+                 || known_le (GET_MODE_SIZE (GET_MODE (out)),
+                              GET_MODE_SIZE (outmode)));
       outmode = GET_MODE (out);
     }
 
@@ -1593,13 +1598,13 @@ push_reload (rtx in, rtx out, rtx *inloc, rtx *outloc,
               What's going on here.  */
            && (in != out
                || (GET_CODE (in) == SUBREG
-                   && (((GET_MODE_SIZE (GET_MODE (in)) + (UNITS_PER_WORD - 1))
-                        / UNITS_PER_WORD)
-                       == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))
-                            + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
+                   && (known_equal_after_align_up
+                       (GET_MODE_SIZE (GET_MODE (in)),
+                        GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))),
+                        UNITS_PER_WORD))))
            /* Make sure the operand fits in the reg that dies.  */
-           && (GET_MODE_SIZE (rel_mode)
-               <= GET_MODE_SIZE (GET_MODE (XEXP (note, 0))))
+           && known_le (GET_MODE_SIZE (rel_mode),
+                        GET_MODE_SIZE (GET_MODE (XEXP (note, 0))))
            && targetm.hard_regno_mode_ok (regno, inmode)
            && targetm.hard_regno_mode_ok (regno, outmode))
          {
@@ -1937,9 +1942,9 @@ find_dummy_reload (rtx real_in, rtx real_out, rtx *inloc, rtx *outloc,
 
   /* If operands exceed a word, we can't use either of them
      unless they have the same size.  */
-  if (GET_MODE_SIZE (outmode) != GET_MODE_SIZE (inmode)
-      && (GET_MODE_SIZE (outmode) > UNITS_PER_WORD
-         || GET_MODE_SIZE (inmode) > UNITS_PER_WORD))
+  if (maybe_ne (GET_MODE_SIZE (outmode), GET_MODE_SIZE (inmode))
+      && (maybe_gt (GET_MODE_SIZE (outmode), UNITS_PER_WORD)
+         || maybe_gt (GET_MODE_SIZE (inmode), UNITS_PER_WORD)))
     return 0;
 
   /* Note that {in,out}_offset are needed only when 'in' or 'out'
@@ -2885,8 +2890,8 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
          if (replace
              && MEM_P (op)
              && REG_P (reg)
-             && (GET_MODE_SIZE (GET_MODE (reg))
-                 >= GET_MODE_SIZE (GET_MODE (op)))
+             && known_ge (GET_MODE_SIZE (GET_MODE (reg)),
+                          GET_MODE_SIZE (GET_MODE (op)))
              && reg_equiv_constant (REGNO (reg)) == 0)
            set_unique_reg_note (emit_insn_before (gen_rtx_USE (VOIDmode, reg),
                                                   insn),
@@ -3127,8 +3132,8 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
                                   && (paradoxical_subreg_p
                                       (operand_mode[i], GET_MODE (operand)))))
                              || BYTES_BIG_ENDIAN
-                             || ((GET_MODE_SIZE (operand_mode[i])
-                                  <= UNITS_PER_WORD)
+                             || (known_le (GET_MODE_SIZE (operand_mode[i]),
+                                           UNITS_PER_WORD)
                                  && (is_a <scalar_int_mode>
                                      (GET_MODE (operand), &inner_mode))
                                  && (GET_MODE_SIZE (inner_mode)
@@ -3625,7 +3630,7 @@ find_reloads (rtx_insn *insn, int replace, int ind_levels, int live_known,
 
              if (! win && ! did_match
                  && this_alternative[i] != NO_REGS
-                 && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
+                 && known_le (GET_MODE_SIZE (operand_mode[i]), UNITS_PER_WORD)
                  && reg_class_size [(int) preferred_class[i]] > 0
                  && ! small_register_class_p (preferred_class[i]))
                {
@@ -6146,8 +6151,9 @@ find_reloads_subreg_address (rtx x, int opnum, enum reload_type type,
 
   if (WORD_REGISTER_OPERATIONS
       && partial_subreg_p (outer_mode, inner_mode)
-      && ((GET_MODE_SIZE (outer_mode) - 1) / UNITS_PER_WORD
-          == (GET_MODE_SIZE (inner_mode) - 1) / UNITS_PER_WORD))
+      && known_equal_after_align_down (GET_MODE_SIZE (outer_mode) - 1,
+                                      GET_MODE_SIZE (inner_mode) - 1,
+                                      UNITS_PER_WORD))
     return NULL;
 
   /* Since we don't attempt to handle paradoxical subregs, we can just