]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/nios2/nios2.c
Update copyright years.
[thirdparty/gcc.git] / gcc / config / nios2 / nios2.c
index 78d58582929732892317cad76aab0ff9b463fd4e..ba0a0a9ba43e573ebf88c2fa2cdaedbf3a54a189 100644 (file)
@@ -1,5 +1,5 @@
 /* Target machine subroutines for Altera Nios II.
-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
+   Copyright (C) 2012-2020 Free Software Foundation, Inc.
    Contributed by Jonah Graham (jgraham@altera.com), 
    Will Reece (wreece@altera.com), and Jeff DaSilva (jdasilva@altera.com).
    Contributed by Mentor Graphics, Inc.
@@ -1080,7 +1080,7 @@ prologue_saved_reg_p (unsigned regno)
 {
   gcc_assert (GP_REG_P (regno));
   
-  if (df_regs_ever_live_p (regno) && !call_used_regs[regno])
+  if (df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
     return true;
 
   if (regno == HARD_FRAME_POINTER_REGNUM && frame_pointer_needed)
@@ -1193,7 +1193,8 @@ nios2_custom_check_insns (void)
     for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
       if (N2FPU_ENABLED_P (i) && N2FPU_UNSAFE_P (i))
        warning (0, "switch %<-mcustom-%s%> has no effect unless "
-                "-funsafe-math-optimizations is specified", N2FPU_NAME (i));
+                "%<-funsafe-math-optimizations%> is specified",
+                N2FPU_NAME (i));
 
   /* Warn if the user is trying to use -mcustom-fmins et. al, that won't
      get used without -ffinite-math-only.  See fold_builtin_fmin_fmax ()
@@ -1202,7 +1203,7 @@ nios2_custom_check_insns (void)
     for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
       if (N2FPU_ENABLED_P (i) && N2FPU_FINITE_P (i))
        warning (0, "switch %<-mcustom-%s%> has no effect unless "
-                "-ffinite-math-only is specified", N2FPU_NAME (i));
+                "%<-ffinite-math-only%> is specified", N2FPU_NAME (i));
 
   /* Warn if the user is trying to use a custom rounding instruction
      that won't get used without -fno-math-errno.  See
@@ -1211,12 +1212,12 @@ nios2_custom_check_insns (void)
     for (i = 0; i < ARRAY_SIZE (nios2_fpu_insn); i++)
       if (N2FPU_ENABLED_P (i) && N2FPU_NO_ERRNO_P (i))
        warning (0, "switch %<-mcustom-%s%> has no effect unless "
-                "-fno-math-errno is specified", N2FPU_NAME (i));
+                "%<-fno-math-errno%> is specified", N2FPU_NAME (i));
 
   if (errors || custom_code_conflict)
     fatal_error (input_location,
-                "conflicting use of -mcustom switches, target attributes, "
-                "and/or __builtin_custom_ functions");
+                "conflicting use of %<-mcustom%> switches, target attributes, "
+                "and/or %<__builtin_custom_%> functions");
 }
 
 static void
@@ -1362,7 +1363,7 @@ nios2_option_override (void)
     sorry ("position-independent code requires the Linux ABI");
   if (flag_pic && stack_limit_rtx
       && GET_CODE (stack_limit_rtx) == SYMBOL_REF)
-    sorry ("PIC support for -fstack-limit-symbol");
+    sorry ("PIC support for %<-fstack-limit-symbol%>");
 
   /* Function to allocate machine-dependent function status.  */
   init_machine_status = &nios2_init_machine_status;
@@ -1384,11 +1385,11 @@ nios2_option_override (void)
   if (flag_pic)
     {
       if (nios2_gpopt_option != gpopt_none)
-       error ("-mgpopt not supported with PIC.");
+       error ("%<-mgpopt%> not supported with PIC.");
       if (nios2_gprel_sec)
-       error ("-mgprel-sec= not supported with PIC.");
+       error ("%<-mgprel-sec=%> not supported with PIC.");
       if (nios2_r0rel_sec)
-       error ("-mr0rel-sec= not supported with PIC.");
+       error ("%<-mr0rel-sec=%> not supported with PIC.");
     }
 
   /* Process -mgprel-sec= and -m0rel-sec=.  */
@@ -1396,13 +1397,13 @@ nios2_option_override (void)
     {
       if (regcomp (&nios2_gprel_sec_regex, nios2_gprel_sec, 
                   REG_EXTENDED | REG_NOSUB))
-       error ("-mgprel-sec= argument is not a valid regular expression.");
+       error ("%<-mgprel-sec=%> argument is not a valid regular expression.");
     }
   if (nios2_r0rel_sec)
     {
       if (regcomp (&nios2_r0rel_sec_regex, nios2_r0rel_sec, 
                   REG_EXTENDED | REG_NOSUB))
-       error ("-mr0rel-sec= argument is not a valid regular expression.");
+       error ("%<-mr0rel-sec=%> argument is not a valid regular expression.");
     }
 
   /* If we don't have mul, we don't have mulx either!  */
@@ -1539,6 +1540,19 @@ nios2_rtx_costs (rtx x, machine_mode mode,
            *total = COSTS_N_INSNS (2);  /* Latency adjustment.  */
          else 
            *total = COSTS_N_INSNS (1);
+         if (TARGET_HAS_MULX && GET_MODE (x) == DImode)
+           {
+             enum rtx_code c0 = GET_CODE (XEXP (x, 0));
+             enum rtx_code c1 = GET_CODE (XEXP (x, 1));
+             if ((c0 == SIGN_EXTEND && c1 == SIGN_EXTEND)
+                 || (c0 == ZERO_EXTEND && c1 == ZERO_EXTEND))
+               /* This is the <mul>sidi3 pattern, which expands into 4 insns,
+                  2 multiplies and 2 moves.  */
+               {
+                 *total = *total * 2 + COSTS_N_INSNS (2);
+                 return true;
+               }
+           }
           return false;
         }
 
@@ -2359,6 +2373,22 @@ nios2_in_small_data_p (const_tree exp)
          if (nios2_small_section_name_p (section))
            return true;
        }
+      else if (flexible_array_type_p (TREE_TYPE (exp))
+              && (!TREE_PUBLIC (exp) || DECL_EXTERNAL (exp)))
+       {
+         /* We really should not consider any objects of any flexibly-sized
+            type to be small data, but pre-GCC 10 did not test
+            for this and just fell through to the next case.  Thus older
+            code compiled with -mgpopt=global could contain GP-relative
+            accesses to objects defined in this compilation unit with
+            external linkage.  We retain the possible small-data treatment
+            of such definitions for backward ABI compatibility, but
+            no longer generate GP-relative accesses for external
+            references (so that the ABI could be changed in the future
+            with less potential impact), or objects with internal
+            linkage.  */
+         return false;
+       }
       else
        {
          HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (exp));
@@ -3348,25 +3378,18 @@ nios2_fpu_insn_asm (enum n2fpu_code code)
    push the argument on the stack, or a hard register in which to
    store the argument.
 
-   MODE is the argument's machine mode.
-   TYPE is the data type of the argument (as a tree).
-   This is null for libcalls where that information may
-   not be available.
    CUM is a variable of type CUMULATIVE_ARGS which gives info about
    the preceding args and about the function being called.
-   NAMED is nonzero if this argument is a named parameter
-   (otherwise it is an extra parameter matching an ellipsis).  */
+   ARG is a description of the argument.  */
 
 static rtx
-nios2_function_arg (cumulative_args_t cum_v, machine_mode mode,
-                   const_tree type ATTRIBUTE_UNUSED,
-                   bool named ATTRIBUTE_UNUSED)
+nios2_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 
   rtx return_rtx = NULL_RTX;
 
   if (cum->regs_used < NUM_ARG_REGS)
-    return_rtx = gen_rtx_REG (mode, FIRST_ARG_REGNO + cum->regs_used);
+    return_rtx = gen_rtx_REG (arg.mode, FIRST_ARG_REGNO + cum->regs_used);
 
   return return_rtx;
 }
@@ -3376,20 +3399,11 @@ nios2_function_arg (cumulative_args_t cum_v, machine_mode mode,
    in memory.  */
 
 static int
-nios2_arg_partial_bytes (cumulative_args_t cum_v,
-                         machine_mode mode, tree type ATTRIBUTE_UNUSED,
-                         bool named ATTRIBUTE_UNUSED)
+nios2_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 
-  HOST_WIDE_INT param_size;
-
-  if (mode == BLKmode)
-    {
-      param_size = int_size_in_bytes (type);
-      gcc_assert (param_size >= 0);
-    }
-  else
-    param_size = GET_MODE_SIZE (mode);
+  HOST_WIDE_INT param_size = arg.promoted_size_in_bytes ();
+  gcc_assert (param_size >= 0);
 
   /* Convert to words (round up).  */
   param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
@@ -3401,25 +3415,15 @@ nios2_arg_partial_bytes (cumulative_args_t cum_v,
   return 0;
 }
 
-/* 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
-nios2_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
-                           const_tree type ATTRIBUTE_UNUSED,
-                           bool named ATTRIBUTE_UNUSED)
+nios2_function_arg_advance (cumulative_args_t cum_v,
+                           const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 
-  HOST_WIDE_INT param_size;
-
-  if (mode == BLKmode)
-    {
-      param_size = int_size_in_bytes (type);
-      gcc_assert (param_size >= 0);
-    }
-  else
-    param_size = GET_MODE_SIZE (mode);
+  HOST_WIDE_INT param_size = arg.promoted_size_in_bytes ();
+  gcc_assert (param_size >= 0);
 
   /* Convert to words (round up).  */
   param_size = (UNITS_PER_WORD - 1 + param_size) / UNITS_PER_WORD;
@@ -3511,8 +3515,8 @@ nios2_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
    own va_arg type.  */
 static void
 nios2_setup_incoming_varargs (cumulative_args_t cum_v,
-                              machine_mode mode, tree type,
-                              int *pretend_size, int second_time)
+                             const function_arg_info &arg,
+                             int *pretend_size, int second_time)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); 
   CUMULATIVE_ARGS local_cum;
@@ -3522,7 +3526,7 @@ nios2_setup_incoming_varargs (cumulative_args_t cum_v,
 
   cfun->machine->uses_anonymous_args = 1;
   local_cum = *cum;
-  nios2_function_arg_advance (local_cum_v, mode, type, true);
+  nios2_function_arg_advance (local_cum_v, arg);
 
   regs_to_push = NUM_ARG_REGS - local_cum.regs_used;
 
@@ -3686,7 +3690,7 @@ nios2_expand_custom_builtin (tree exp, unsigned int index, rtx target)
        {
          if (!custom_insn_opcode (value, VOIDmode))
            error ("custom instruction opcode must be compile time "
-                  "constant in the range 0-255 for __builtin_custom_%s",
+                  "constant in the range 0-255 for %<__builtin_custom_%s%>",
                   custom_builtin_name[index]);
        }
       else
@@ -3995,7 +3999,7 @@ nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
                      int ignore ATTRIBUTE_UNUSED)
 {
   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-  unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
 
   if (fcode < nios2_fpu_builtin_base)
     {
@@ -4455,6 +4459,7 @@ nios2_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
                           HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
                           tree function)
 {
+  const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
   rtx this_rtx, funexp;
   rtx_insn *insn;
 
@@ -4504,13 +4509,14 @@ nios2_asm_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
 
   /* Run just enough of rest_of_compilation to get the insns emitted.
      There's not really enough bulk here to make other passes such as
-     instruction scheduling worth while.  Note that use_thunk calls
-     assemble_start_function and assemble_end_function.  */
+     instruction scheduling worth while.  */
   insn = get_insns ();
   shorten_branches (insn);
+  assemble_start_function (thunk_fndecl, fnname);
   final_start_function (insn, file, 1);
   final (insn, file, 1);
   final_end_function ();
+  assemble_end_function (thunk_fndecl, fnname);
 
   /* Stop pretending to be a post-reload pass.  */
   reload_completed = 0;