]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/h8300/h8300.c
Update copyright years.
[thirdparty/gcc.git] / gcc / config / h8300 / h8300.c
index d4e8c461c800c678ca1e0ae0b3e3b125a7868b86..6c84b0abea7eca52904a17aca1d57114e61c304d 100644 (file)
@@ -1,5 +1,5 @@
 /* Subroutines for insn-output.c for Renesas H8/300.
-   Copyright (C) 1992-2017 Free Software Foundation, Inc.
+   Copyright (C) 1992-2020 Free Software Foundation, Inc.
    Contributed by Steve Chamberlain (sac@cygnus.com),
    Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
 
@@ -19,6 +19,8 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
+#define IN_TARGET_CODE 1
+
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
@@ -324,7 +326,7 @@ h8300_option_override (void)
 #ifndef OBJECT_FORMAT_ELF
   if (TARGET_H8300SX)
     {
-      error ("-msx is not supported in coff");
+      error ("%<-msx%> is not supported in coff");
       target_flags |= MASK_H8300S;
     }
 #endif
@@ -346,44 +348,44 @@ h8300_option_override (void)
 
   if (!TARGET_H8300S && TARGET_MAC)
     {
-      error ("-ms2600 is used without -ms");
+      error ("%<-ms2600%> is used without %<-ms%>");
       target_flags |= MASK_H8300S_1;
     }
 
   if (TARGET_H8300 && TARGET_NORMAL_MODE)
     {
-      error ("-mn is used without -mh or -ms or -msx");
+      error ("%<-mn%> is used without %<-mh%> or %<-ms%> or %<-msx%>");
       target_flags ^= MASK_NORMAL_MODE;
     }
 
   if (! TARGET_H8300S &&  TARGET_EXR)
     {
-      error ("-mexr is used without -ms");
+      error ("%<-mexr%> is used without %<-ms%>");
       target_flags |= MASK_H8300S_1;
     }
 
   if (TARGET_H8300 && TARGET_INT32)
    {
-      error ("-mint32 is not supported for H8300 and H8300L targets");
+      error ("%<-mint32%> is not supported for H8300 and H8300L targets");
       target_flags ^= MASK_INT32;
    }
 
  if ((!TARGET_H8300S  &&  TARGET_EXR) && (!TARGET_H8300SX && TARGET_EXR))
    {
-      error ("-mexr is used without -ms or -msx");
+      error ("%<-mexr%> is used without %<-ms%> or %<-msx%>");
       target_flags |= MASK_H8300S_1;
    }
 
  if ((!TARGET_H8300S  &&  TARGET_NEXR) && (!TARGET_H8300SX && TARGET_NEXR))
    {
-      warning (OPT_mno_exr, "-mno-exr valid only with -ms or -msx    \
-               - Option ignored!");
+      warning (OPT_mno_exr, "%<-mno-exr%> valid only with %<-ms%> or "
+              "%<-msx%> - Option ignored!");
    }
 
 #ifdef H8300_LINUX 
  if ((TARGET_NORMAL_MODE))
    {
-      error ("-mn is not supported for linux targets");
+      error ("%<-mn%> is not supported for linux targets");
       target_flags ^= MASK_NORMAL_MODE;
    }
 #endif
@@ -483,7 +485,8 @@ byte_reg (rtx x, int b)
    && ! TREE_THIS_VOLATILE (current_function_decl)                     \
    && (h8300_saveall_function_p (current_function_decl)                        \
        /* Save any call saved register that was used.  */              \
-       || (df_regs_ever_live_p (regno) && !call_used_regs[regno])      \
+       || (df_regs_ever_live_p (regno)                                 \
+          && !call_used_or_fixed_reg_p (regno))                        \
        /* Save the frame pointer if it was used.  */                   \
        || (regno == HARD_FRAME_POINTER_REGNUM && df_regs_ever_live_p (regno)) \
        /* Save any register used in an interrupt handler.  */          \
@@ -492,7 +495,7 @@ byte_reg (rtx x, int b)
        /* Save call clobbered registers in non-leaf interrupt          \
          handlers.  */                                                 \
        || (h8300_current_function_interrupt_function_p ()              \
-          && call_used_regs[regno]                                     \
+          && call_used_or_fixed_reg_p (regno)                          \
           && !crtl->is_leaf)))
 
 /* We use this to wrap all emitted insns in the prologue.  */
@@ -863,15 +866,15 @@ h8300_expand_prologue (void)
          if (TARGET_H8300S)
            {
              /* See how many registers we can push at the same time.  */
-             if ((!TARGET_H8300SX || (regno & 3) == 0)
+             if ((TARGET_H8300SX || (regno & 3) == 0)
                  && ((saved_regs >> regno) & 0x0f) == 0x0f)
                n_regs = 4;
 
-             else if ((!TARGET_H8300SX || (regno & 3) == 0)
+             else if ((TARGET_H8300SX || (regno & 3) == 0)
                       && ((saved_regs >> regno) & 0x07) == 0x07)
                n_regs = 3;
 
-             else if ((!TARGET_H8300SX || (regno & 1) == 0)
+             else if ((TARGET_H8300SX || (regno & 1) == 0)
                       && ((saved_regs >> regno) & 0x03) == 0x03)
                n_regs = 2;
            }
@@ -1079,17 +1082,16 @@ h8300_pr_saveall (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
   pragma_saveall = 1;
 }
 
-/* If the next function argument with MODE and TYPE is to be passed in
-   a register, return a reg RTX for the hard register in which to pass
-   the argument.  CUM represents the state after the last argument.
-   If the argument is to be pushed, NULL_RTX is returned.
+/* If the next function argument ARG is to be passed in a register, return
+   a reg RTX for the hard register in which to pass the argument.  CUM
+   represents the state after the last argument.  If the argument is to
+   be pushed, NULL_RTX is returned.
 
    On the H8/300 all normal args are pushed, unless -mquickcall in which
    case the first 3 arguments are passed in registers.  */
 
 static rtx
-h8300_function_arg (cumulative_args_t cum_v, machine_mode mode,
-                   const_tree type, bool named)
+h8300_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
@@ -1117,7 +1119,7 @@ h8300_function_arg (cumulative_args_t cum_v, machine_mode mode,
   int regpass = 0;
 
   /* Never pass unnamed arguments in registers.  */
-  if (!named)
+  if (!arg.named)
     return NULL_RTX;
 
   /* Pass 3 regs worth of data in regs when user asked on the command line.  */
@@ -1141,34 +1143,25 @@ h8300_function_arg (cumulative_args_t cum_v, machine_mode mode,
 
   if (regpass)
     {
-      int size;
-
-      if (mode == BLKmode)
-       size = int_size_in_bytes (type);
-      else
-       size = GET_MODE_SIZE (mode);
-
+      int size = arg.promoted_size_in_bytes ();
       if (size + cum->nbytes <= regpass * UNITS_PER_WORD
          && cum->nbytes / UNITS_PER_WORD <= 3)
-       result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
+       result = gen_rtx_REG (arg.mode, cum->nbytes / UNITS_PER_WORD);
     }
 
   return result;
 }
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-h8300_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-                           const_tree type, bool named ATTRIBUTE_UNUSED)
+h8300_function_arg_advance (cumulative_args_t cum_v,
+                           const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  cum->nbytes += (mode != BLKmode
-                 ? (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD
-                 : (int_size_in_bytes (type) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD);
+  cum->nbytes += ((arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1)
+                 & -UNITS_PER_WORD);
 }
 
 \f
@@ -1265,7 +1258,7 @@ h8300_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
            *total = 0;
            return true;
          }
-       if (-4 <= n && n <= 4)
+       if (n >= -4 && n <= 4)
          {
            switch ((int) n)
              {
@@ -2549,14 +2542,14 @@ h8300_insn_length_from_table (rtx_insn *insn, rtx * operands)
     case LENGTH_TABLE_NONE:
       gcc_unreachable ();
 
-    case LENGTH_TABLE_ADDB:
-      return h8300_binary_length (insn, &addb_length_table);
-
-    case LENGTH_TABLE_ADDW:
-      return h8300_binary_length (insn, &addw_length_table);
-
-    case LENGTH_TABLE_ADDL:
-      return h8300_binary_length (insn, &addl_length_table);
+    case LENGTH_TABLE_ADD:
+      if (GET_MODE (operands[0]) == QImode)
+        return h8300_binary_length (insn, &addb_length_table);
+      else if (GET_MODE (operands[0]) == HImode)
+        return h8300_binary_length (insn, &addw_length_table);
+      else if (GET_MODE (operands[0]) == SImode)
+        return h8300_binary_length (insn, &addl_length_table);
+      gcc_unreachable ();
 
     case LENGTH_TABLE_LOGICB:
       return h8300_binary_length (insn, &logicb_length_table);
@@ -4169,7 +4162,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
              goto end;
            }
        }
-      else if ((8 <= count && count <= 13)
+      else if ((count >= 8 && count <= 13)
               || (TARGET_H8300S && count == 14))
        {
          info->remainder = count - 8;
@@ -4249,7 +4242,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
       gcc_unreachable ();
 
     case SIshift:
-      if (TARGET_H8300 && 8 <= count && count <= 9)
+      if (TARGET_H8300 && count >= 8 && count <= 9)
        {
          info->remainder = count - 8;
 
@@ -4312,9 +4305,9 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
              gcc_unreachable ();
            }
        }
-      else if ((TARGET_H8300 && 16 <= count && count <= 20)
-              || (TARGET_H8300H && 16 <= count && count <= 19)
-              || (TARGET_H8300S && 16 <= count && count <= 21))
+      else if ((TARGET_H8300 && count >= 16 && count <= 20)
+              || (TARGET_H8300H && count >= 16 && count <= 19)
+              || (TARGET_H8300S && count >= 16 && count <= 21))
        {
          info->remainder = count - 16;
 
@@ -4351,7 +4344,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
              goto end;
            }
        }
-      else if (TARGET_H8300 && 24 <= count && count <= 28)
+      else if (TARGET_H8300 && count >= 24 && count <= 28)
        {
          info->remainder = count - 24;
 
@@ -4375,7 +4368,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
            }
        }
       else if ((TARGET_H8300H && count == 24)
-              || (TARGET_H8300S && 24 <= count && count <= 25))
+              || (TARGET_H8300S && count >= 24 && count <= 25))
        {
          info->remainder = count - 24;
 
@@ -5424,23 +5417,23 @@ h8300_insert_attributes (tree node, tree *attributes)
 
 static const struct attribute_spec h8300_attribute_table[] =
 {
-  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
-       affects_type_identity, exclusions } */
-  { "interrupt_handler", 0, 0, true,  false, false,
-    h8300_handle_fndecl_attribute, false, NULL },
-  { "saveall",           0, 0, true,  false, false,
-    h8300_handle_fndecl_attribute, false, NULL },
-  { "OS_Task",           0, 0, true,  false, false,
-    h8300_handle_fndecl_attribute, false, NULL },
-  { "monitor",           0, 0, true,  false, false,
-    h8300_handle_fndecl_attribute, false, NULL },
-  { "function_vector",   0, 0, true,  false, false,
-    h8300_handle_fndecl_attribute, false, NULL },
-  { "eightbit_data",     0, 0, true,  false, false,
-    h8300_handle_eightbit_data_attribute, false, NULL },
-  { "tiny_data",         0, 0, true,  false, false,
-    h8300_handle_tiny_data_attribute, false, NULL },
-  { NULL,                0, 0, false, false, false, NULL, false, NULL }
+  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
+       affects_type_identity, handler, exclude } */
+  { "interrupt_handler", 0, 0, true,  false, false, false,
+    h8300_handle_fndecl_attribute, NULL },
+  { "saveall",           0, 0, true,  false, false, false,
+    h8300_handle_fndecl_attribute, NULL },
+  { "OS_Task",           0, 0, true,  false, false, false,
+    h8300_handle_fndecl_attribute, NULL },
+  { "monitor",           0, 0, true,  false, false, false,
+    h8300_handle_fndecl_attribute, NULL },
+  { "function_vector",   0, 0, true,  false, false, false,
+    h8300_handle_fndecl_attribute, NULL },
+  { "eightbit_data",     0, 0, true,  false, false, false,
+    h8300_handle_eightbit_data_attribute, NULL },
+  { "tiny_data",         0, 0, true,  false, false, false,
+    h8300_handle_tiny_data_attribute, NULL },
+  { NULL,                0, 0, false, false, false, false, NULL, NULL }
 };
 
 
@@ -6042,6 +6035,21 @@ h8300_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
       emit_move_insn (mem, tem);
     }
 }
+
+/* Implement PUSH_ROUNDING.
+
+   On the H8/300, @-sp really pushes a byte if you ask it to - but that's
+   dangerous, so we claim that it always pushes a word, then we catch
+   the mov.b rx,@-sp and turn it into a mov.w rx,@-sp on output.
+
+   On the H8/300H, we simplify TARGET_QUICKCALL by setting this to 4
+   and doing a similar thing.  */
+
+poly_int64
+h8300_push_rounding (poly_int64 bytes)
+{
+  return ((bytes + PARM_BOUNDARY / 8 - 1) & (-PARM_BOUNDARY / 8));
+}
 \f
 /* Initialize the GCC target structure.  */
 #undef TARGET_ATTRIBUTE_TABLE
@@ -6131,4 +6139,7 @@ h8300_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
 #define TARGET_MODE_DEPENDENT_ADDRESS_P h8300_mode_dependent_address_p
 
+#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
+#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
+
 struct gcc_target targetm = TARGET_INITIALIZER;