]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/lm32/lm32.c
Update copyright years.
[thirdparty/gcc.git] / gcc / config / lm32 / lm32.c
index 2e1cf445428b3c94b22d1f7ba783d983c87bba6e..6f59e370454ff2aef16d7bef709be43ee669e52c 100644 (file)
@@ -1,7 +1,7 @@
 /* Subroutines used for code generation on the Lattice Mico32 architecture.
    Contributed by Jon Beniston <jon@beniston.com>
 
-   Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
+   Copyright (C) 2009-2020 Free Software Foundation, Inc.
 
    This file is part of GCC.
 
    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"
-#include "tm.h"
+#include "backend.h"
+#include "target.h"
 #include "rtl.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "df.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "optabs.h"
 #include "regs.h"
-#include "hard-reg-set.h"
-#include "basic-block.h"
-#include "insn-config.h"
-#include "conditions.h"
-#include "insn-flags.h"
-#include "insn-attr.h"
-#include "insn-codes.h"
+#include "emit-rtl.h"
 #include "recog.h"
 #include "output.h"
-#include "tree.h"
+#include "calls.h"
+#include "alias.h"
+#include "explow.h"
 #include "expr.h"
-#include "flags.h"
-#include "reload.h"
-#include "tm_p.h"
-#include "function.h"
-#include "diagnostic-core.h"
-#include "optabs.h"
-#include "libfuncs.h"
-#include "ggc.h"
-#include "target.h"
-#include "target-def.h"
-#include "langhooks.h"
 #include "tm-constrs.h"
-#include "df.h"
+#include "builtins.h"
+
+/* This file should be included last.  */
+#include "target-def.h"
 
 struct lm32_frame_info
 {
@@ -66,27 +64,26 @@ static void expand_save_restore (struct lm32_frame_info *info, int op);
 static void stack_adjust (HOST_WIDE_INT amount);
 static bool lm32_in_small_data_p (const_tree);
 static void lm32_setup_incoming_varargs (cumulative_args_t cum,
-                                        enum machine_mode mode, tree type,
+                                        const function_arg_info &,
                                         int *pretend_size, int no_rtl);
-static bool lm32_rtx_costs (rtx x, int code, int outer_code, int opno,
+static bool lm32_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno,
                            int *total, bool speed);
 static bool lm32_can_eliminate (const int, const int);
 static bool
-lm32_legitimate_address_p (enum machine_mode mode, rtx x, bool strict);
+lm32_legitimate_address_p (machine_mode mode, rtx x, bool strict);
 static HOST_WIDE_INT lm32_compute_frame_size (int size);
 static void lm32_option_override (void);
-static rtx lm32_function_arg (cumulative_args_t cum,
-                             enum machine_mode mode, const_tree type,
-                             bool named);
+static rtx lm32_function_arg (cumulative_args_t, const function_arg_info &);
 static void lm32_function_arg_advance (cumulative_args_t cum,
-                                      enum machine_mode mode,
-                                      const_tree type, bool named);
-static bool lm32_legitimate_constant_p (enum machine_mode, rtx);
+                                      const function_arg_info &);
+static bool lm32_hard_regno_mode_ok (unsigned int, machine_mode);
+static bool lm32_modes_tieable_p (machine_mode, machine_mode);
+static HOST_WIDE_INT lm32_starting_frame_offset (void);
 
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE lm32_option_override
 #undef TARGET_ADDRESS_COST
-#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
+#define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS lm32_rtx_costs
 #undef TARGET_IN_SMALL_DATA_P
@@ -107,10 +104,20 @@ static bool lm32_legitimate_constant_p (enum machine_mode, rtx);
 #define TARGET_MAX_ANCHOR_OFFSET 0x7fff
 #undef TARGET_CAN_ELIMINATE
 #define TARGET_CAN_ELIMINATE lm32_can_eliminate
+#undef TARGET_LRA_P
+#define TARGET_LRA_P hook_bool_void_false
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P lm32_legitimate_address_p
-#undef TARGET_LEGITIMATE_CONSTANT_P
-#define TARGET_LEGITIMATE_CONSTANT_P lm32_legitimate_constant_p
+#undef TARGET_HARD_REGNO_MODE_OK
+#define TARGET_HARD_REGNO_MODE_OK lm32_hard_regno_mode_ok
+#undef TARGET_MODES_TIEABLE_P
+#define TARGET_MODES_TIEABLE_P lm32_modes_tieable_p
+
+#undef TARGET_CONSTANT_ALIGNMENT
+#define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
+
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET lm32_starting_frame_offset
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
@@ -166,11 +173,8 @@ gen_int_relational (enum rtx_code code,
                    rtx cmp1,   
                    rtx destination)    
 {
-  enum machine_mode mode;
+  machine_mode mode;
   int branch_p;
-  rtx temp;
-  rtx cond;
-  rtx label;
 
   mode = GET_MODE (cmp0);
   if (mode == VOIDmode)
@@ -213,9 +217,8 @@ gen_int_relational (enum rtx_code code,
       /* Generate conditional branch instruction.  */
       cond = gen_rtx_fmt_ee (code, mode, cmp0, cmp1);
       label = gen_rtx_LABEL_REF (VOIDmode, destination);
-      insn = gen_rtx_SET (VOIDmode, pc_rtx,
-                         gen_rtx_IF_THEN_ELSE (VOIDmode,
-                                               cond, label, pc_rtx));
+      insn = gen_rtx_SET (pc_rtx, gen_rtx_IF_THEN_ELSE (VOIDmode,
+                                                       cond, label, pc_rtx));
       emit_jump_insn (insn);
     }
   else
@@ -454,13 +457,13 @@ lm32_compute_frame_size (int size)
      and calculate size required to store them in the stack.  */
   for (regno = 1; regno < SP_REGNUM; 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))
        {
          reg_save_mask |= 1 << regno;
          callee_size += UNITS_PER_WORD;
        }
     }
-  if (df_regs_ever_live_p (RA_REGNUM) || !current_function_is_leaf
+  if (df_regs_ever_live_p (RA_REGNUM) || ! crtl->is_leaf
       || !optimize)
     {
       reg_save_mask |= 1 << RA_REGNUM;
@@ -512,7 +515,7 @@ lm32_print_operand (FILE * file, rtx op, int letter)
   else if (code == HIGH)
     output_addr_const (file, XEXP (op, 0));  
   else if (code == MEM)
-    output_address (XEXP (op, 0));
+    output_address (GET_MODE (op), XEXP (op, 0));
   else if (letter == 'z' && GET_CODE (op) == CONST_INT && INTVAL (op) == 0)
     fprintf (file, "%s", reg_names[0]);
   else if (GET_CODE (op) == CONST_DOUBLE)
@@ -565,7 +568,7 @@ lm32_print_operand_address (FILE * file, rtx addr)
       break;
 
     case MEM:
-      output_address (XEXP (addr, 0));
+      output_address (VOIDmode, XEXP (addr, 0));
       break;
 
     case PLUS:
@@ -613,39 +616,34 @@ lm32_print_operand_address (FILE * file, rtx addr)
    Value is zero to 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
-lm32_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
-                  const_tree type, bool named)
+lm32_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  if (mode == VOIDmode)
+  if (arg.end_marker_p ())
     /* Compute operand 2 of the call insn.  */
     return GEN_INT (0);
 
-  if (targetm.calls.must_pass_in_stack (mode, type))
+  if (targetm.calls.must_pass_in_stack (arg))
     return NULL_RTX;
 
-  if (!named || (*cum + LM32_NUM_REGS2 (mode, type) > LM32_NUM_ARG_REGS))
+  if (!arg.named
+      || *cum + LM32_NUM_REGS2 (arg.mode, arg.type) > LM32_NUM_ARG_REGS)
     return NULL_RTX;
 
-  return gen_rtx_REG (mode, *cum + LM32_FIRST_ARG_REG);
+  return gen_rtx_REG (arg.mode, *cum + LM32_FIRST_ARG_REG);
 }
 
 static void
-lm32_function_arg_advance (cumulative_args_t cum, enum machine_mode mode,
-                          const_tree type, bool named ATTRIBUTE_UNUSED)
+lm32_function_arg_advance (cumulative_args_t cum,
+                          const function_arg_info &arg)
 {
-  *get_cumulative_args (cum) += LM32_NUM_REGS2 (mode, type);
+  *get_cumulative_args (cum) += LM32_NUM_REGS2 (arg.mode, arg.type);
 }
 
 HOST_WIDE_INT
@@ -678,8 +676,9 @@ lm32_compute_initial_elimination_offset (int from, int to)
 }
 
 static void
-lm32_setup_incoming_varargs (cumulative_args_t cum_v, enum machine_mode mode,
-                            tree type, int *pretend_size, int no_rtl)
+lm32_setup_incoming_varargs (cumulative_args_t cum_v,
+                            const function_arg_info &arg,
+                            int *pretend_size, int no_rtl)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
   int first_anon_arg;
@@ -696,12 +695,7 @@ lm32_setup_incoming_varargs (cumulative_args_t cum_v, enum machine_mode mode,
          registers, if any used in passing this named paramter in
          order to determine which is the first registers used to pass
          anonymous arguments.  */
-      int size;
-
-      if (mode == BLKmode)
-       size = int_size_in_bytes (type);
-      else
-       size = GET_MODE_SIZE (mode);
+      int size = arg.promoted_size_in_bytes ();
 
       first_anon_arg =
        *cum + LM32_FIRST_ARG_REG +
@@ -795,7 +789,7 @@ lm32_in_small_data_p (const_tree exp)
 
   if (TREE_CODE (exp) == VAR_DECL && DECL_SECTION_NAME (exp))
     {
-      const char *section = TREE_STRING_POINTER (DECL_SECTION_NAME (exp));
+      const char *section = DECL_SECTION_NAME (exp);
       if (strcmp (section, ".sdata") == 0 || strcmp (section, ".sbss") == 0)
        return true;
     }
@@ -822,7 +816,7 @@ lm32_block_move_inline (rtx dest, rtx src, HOST_WIDE_INT length,
   HOST_WIDE_INT offset, delta;
   unsigned HOST_WIDE_INT bits;
   int i;
-  enum machine_mode mode;
+  machine_mode mode;
   rtx *regs;
 
   /* Work out how many bits to move at a time.  */
@@ -839,7 +833,7 @@ lm32_block_move_inline (rtx dest, rtx src, HOST_WIDE_INT length,
       break;
     }
 
-  mode = mode_for_size (bits, MODE_INT, 0);
+  mode = int_mode_for_size (bits, 0).require ();
   delta = bits / BITS_PER_UNIT;
 
   /* Allocate a buffer for the temporary registers.  */
@@ -862,7 +856,7 @@ lm32_block_move_inline (rtx dest, rtx src, HOST_WIDE_INT length,
       src = adjust_address (src, BLKmode, offset);
       dest = adjust_address (dest, BLKmode, offset);
       move_by_pieces (dest, src, length - offset,
-                     MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), 0);
+                     MIN (MEM_ALIGN (src), MEM_ALIGN (dest)), RETURN_BEGIN);
     }
 }
 
@@ -928,10 +922,10 @@ nonpic_symbol_mentioned_p (rtx x)
    scanned.  In either case, *TOTAL contains the cost result.  */
 
 static bool
-lm32_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
-               int *total, bool speed)
+lm32_rtx_costs (rtx x, machine_mode mode, int outer_code,
+               int opno ATTRIBUTE_UNUSED, int *total, bool speed)
 {
-  enum machine_mode mode = GET_MODE (x);
+  int code = GET_CODE (x);
   bool small_mode;
 
   const int arithmetic_latency = 1;
@@ -1198,7 +1192,7 @@ lm32_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
 /* Implement TARGET_LEGITIMATE_ADDRESS_P.  */
 
 static bool
-lm32_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x, bool strict)
+lm32_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x, bool strict)
 {  
    /* (rM) */                                                    
   if (strict && REG_P (x) && STRICT_REG_OK_FOR_BASE_P (x))
@@ -1225,20 +1219,35 @@ lm32_legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, rtx x, bool
 /* Check a move is not memory to memory.  */ 
 
 bool 
-lm32_move_ok (enum machine_mode mode, rtx operands[2]) {
+lm32_move_ok (machine_mode mode, rtx operands[2]) {
   if (memory_operand (operands[0], mode))
     return register_or_zero_operand (operands[1], mode);
   return true;
 }
 
-/* Implement TARGET_LEGITIMATE_CONSTANT_P.  */
+/* Implement TARGET_HARD_REGNO_MODE_OK.  */
 
 static bool
-lm32_legitimate_constant_p (enum machine_mode mode, rtx x)
+lm32_hard_regno_mode_ok (unsigned int regno, machine_mode)
 {
-  /* 32-bit addresses require multiple instructions.  */  
-  if (!flag_pic && reloc_operand (x, mode))
-    return false; 
-  
-  return true;
+  return G_REG_P (regno);
+}
+
+/* Implement TARGET_MODES_TIEABLE_P.  */
+
+static bool
+lm32_modes_tieable_p (machine_mode mode1, machine_mode mode2)
+{
+  return (GET_MODE_CLASS (mode1) == MODE_INT
+         && GET_MODE_CLASS (mode2) == MODE_INT
+         && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
+         && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD);
+}
+
+/* Implement TARGET_STARTING_FRAME_OFFSET.  */
+
+static HOST_WIDE_INT
+lm32_starting_frame_offset (void)
+{
+  return UNITS_PER_WORD;
 }