]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/visium/visium.c
Wrap option names in gcc internal messages with %< and %>.
[thirdparty/gcc.git] / gcc / config / visium / visium.c
index f3016f9bda7467e3c7f00f4baf5865d3f7126da5..431f64cfcad3351f39dd42c38d1d72e2f68b6f35 100644 (file)
@@ -1,5 +1,5 @@
 /* Output routines for Visium.
-   Copyright (C) 2002-2017 Free Software Foundation, Inc.
+   Copyright (C) 2002-2019 Free Software Foundation, Inc.
    Contributed by C.Nettleton, J.P.Parkes and P.Garbett.
 
    This file is part of GCC.
@@ -18,6 +18,8 @@
    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"
@@ -145,10 +147,11 @@ static inline bool current_function_has_lr_slot (void);
    interrupt -- specifies this function is an interrupt handler.   */
 static const struct attribute_spec visium_attribute_table[] =
 {
-  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
-       affects_type_identity } */
-  {"interrupt", 0, 0, true, false, false, visium_handle_interrupt_attr, false},
-  {NULL, 0, 0, false, false, false, NULL, false}
+  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
+       affects_type_identity, handler, exclude } */
+  { "interrupt", 0, 0, true, false, false, false, visium_handle_interrupt_attr,
+    NULL},
+  { NULL, 0, 0, false, false, false, false, NULL, NULL },
 };
 
 static struct machine_function *visium_init_machine_status (void);
@@ -228,10 +231,17 @@ static void visium_init_libfuncs (void);
 
 static unsigned int visium_reorg (void);
 
+static unsigned int visium_hard_regno_nregs (unsigned int, machine_mode);
+
 static bool visium_hard_regno_mode_ok (unsigned int, machine_mode);
 
 static bool visium_modes_tieable_p (machine_mode, machine_mode);
 
+static bool visium_can_change_mode_class (machine_mode, machine_mode,
+                                         reg_class_t);
+
+static HOST_WIDE_INT visium_constant_alignment (const_tree, HOST_WIDE_INT);
+
 /* Setup the global target hooks structure.  */
 
 #undef  TARGET_MAX_ANCHOR_OFFSET
@@ -270,17 +280,19 @@ static bool visium_modes_tieable_p (machine_mode, machine_mode);
 #undef  TARGET_LEGITIMATE_CONSTANT_P
 #define TARGET_LEGITIMATE_CONSTANT_P visium_legitimate_constant_p
 
-#undef TARGET_LRA_P
+#undef  TARGET_LRA_P
 #define TARGET_LRA_P hook_bool_void_false
 
 #undef  TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P visium_legitimate_address_p
 
-#undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
+#undef  TARGET_PRINT_OPERAND_PUNCT_VALID_P
 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P visium_print_operand_punct_valid_p
-#undef TARGET_PRINT_OPERAND
+
+#undef  TARGET_PRINT_OPERAND
 #define TARGET_PRINT_OPERAND visium_print_operand
-#undef TARGET_PRINT_OPERAND_ADDRESS
+
+#undef  TARGET_PRINT_OPERAND_ADDRESS
 #define TARGET_PRINT_OPERAND_ADDRESS visium_print_operand_address
 
 #undef  TARGET_ATTRIBUTE_TABLE
@@ -337,18 +349,30 @@ static bool visium_modes_tieable_p (machine_mode, machine_mode);
 #undef  TARGET_TRAMPOLINE_INIT
 #define TARGET_TRAMPOLINE_INIT visium_trampoline_init
 
-#undef TARGET_MD_ASM_ADJUST
+#undef  TARGET_MD_ASM_ADJUST
 #define TARGET_MD_ASM_ADJUST visium_md_asm_adjust
 
-#undef TARGET_FLAGS_REGNUM
+#undef  TARGET_FLAGS_REGNUM
 #define TARGET_FLAGS_REGNUM FLAGS_REGNUM
 
-#undef TARGET_HARD_REGNO_MODE_OK
+#undef  TARGET_HARD_REGNO_NREGS
+#define TARGET_HARD_REGNO_NREGS visium_hard_regno_nregs
+
+#undef  TARGET_HARD_REGNO_MODE_OK
 #define TARGET_HARD_REGNO_MODE_OK visium_hard_regno_mode_ok
 
-#undef TARGET_MODES_TIEABLE_P
+#undef  TARGET_MODES_TIEABLE_P
 #define TARGET_MODES_TIEABLE_P visium_modes_tieable_p
 
+#undef  TARGET_CAN_CHANGE_MODE_CLASS
+#define TARGET_CAN_CHANGE_MODE_CLASS visium_can_change_mode_class
+
+#undef  TARGET_CONSTANT_ALIGNMENT
+#define TARGET_CONSTANT_ALIGNMENT visium_constant_alignment
+
+#undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
+#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 namespace {
@@ -395,9 +419,9 @@ static void
 visium_option_override (void)
 {
   if (flag_pic == 1)
-    warning (OPT_fpic, "-fpic is not supported");
+    warning (OPT_fpic, "%<-fpic%> is not supported");
   if (flag_pic == 2)
-    warning (OPT_fPIC, "-fPIC is not supported");
+    warning (OPT_fPIC, "%<-fPIC%> is not supported");
 
   /* MCM is the default in the GR5/GR6 era.  */
   target_flags |= MASK_MCM;
@@ -424,12 +448,12 @@ visium_option_override (void)
 
   /* Align functions on 256-byte (32-quadword) for GR5 and 64-byte (8-quadword)
      boundaries for GR6 so they start a new burst mode window.  */
-  if (align_functions == 0)
+  if (flag_align_functions && !str_align_functions)
     {
       if (visium_cpu == PROCESSOR_GR6)
-       align_functions = 64;
+       str_align_functions = "64";
       else
-       align_functions = 256;
+       str_align_functions = "256";
 
       /* Allow the size of compilation units to double because of inlining.
         In practice the global size of the object code is hardly affected
@@ -440,41 +464,26 @@ visium_option_override (void)
     }
 
   /* Likewise for loops.  */
-  if (align_loops == 0)
+  if (flag_align_loops && !str_align_loops)
     {
       if (visium_cpu == PROCESSOR_GR6)
-       align_loops = 64;
+       str_align_loops = "64";
       else
        {
-         align_loops = 256;
          /* But not if they are too far away from a 256-byte boundary.  */
-         align_loops_max_skip = 31;
+         str_align_loops = "256:32:8";
        }
     }
 
   /* Align all jumps on quadword boundaries for the burst mode, and even
      on 8-quadword boundaries for GR6 so they start a new window.  */
-  if (align_jumps == 0)
+  if (flag_align_jumps && !str_align_jumps)
     {
       if (visium_cpu == PROCESSOR_GR6)
-       align_jumps = 64;
+       str_align_jumps = "64";
       else
-       align_jumps = 8;
+       str_align_jumps = "8";
     }
-
-  /* We register a machine-specific pass.  This pass must be scheduled as
-     late as possible so that we have the (essentially) final form of the
-     insn stream to work on.  Registering the pass must be done at start up.
-     It's convenient to do it here.  */
-  opt_pass *visium_reorg_pass = make_pass_visium_reorg (g);
-  struct register_pass_info insert_pass_visium_reorg =
-    {
-      visium_reorg_pass,               /* pass */
-      "dbr",                           /* reference_pass_name */
-      1,                               /* ref_pass_instance_number */
-      PASS_POS_INSERT_AFTER            /* po_op */
-    };
-  register_pass (&insert_pass_visium_reorg);
 }
 
 /* Register the Visium-specific libfuncs with the middle-end.  */
@@ -719,7 +728,7 @@ visium_handle_interrupt_attr (tree *node, tree name,
     }
   else if (!TARGET_SV_MODE)
     {
-      error ("an interrupt handler cannot be compiled with -muser-mode");
+      error ("an interrupt handler cannot be compiled with %<-muser-mode%>");
       *no_add_attrs = true;
     }
 
@@ -823,6 +832,14 @@ visium_data_alignment (tree type, unsigned int align)
   return align;
 }
 
+/* Implement TARGET_CONSTANT_ALIGNMENT.  */
+
+static HOST_WIDE_INT
+visium_constant_alignment (const_tree exp, HOST_WIDE_INT align)
+{
+  return visium_data_alignment (TREE_TYPE (exp), align);
+}
+
 /* Helper function for HARD_REGNO_RENAME_OK (FROM, TO).  Return non-zero if
    it is OK to rename a hard register FROM to another hard register TO.  */
 
@@ -846,6 +863,16 @@ visium_hard_regno_rename_ok (unsigned int from ATTRIBUTE_UNUSED,
   return 1;
 }
 
+/* Implement TARGET_HARD_REGNO_NREGS.  */
+
+static unsigned int
+visium_hard_regno_nregs (unsigned int regno, machine_mode mode)
+{
+  if (regno == MDB_REGNUM)
+    return CEIL (GET_MODE_SIZE (mode), 2 * UNITS_PER_WORD);
+  return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
+}
+
 /* Implement TARGET_HARD_REGNO_MODE_OK.
 
    Modes with sizes which cross from the one register class to the
@@ -863,7 +890,7 @@ visium_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
     return mode == SFmode || (mode == SImode && TARGET_FPU_IEEE);
 
   return (GET_MODE_CLASS (mode) == MODE_INT
-         && HARD_REGNO_NREGS (regno, mode) == 1);
+         && visium_hard_regno_nregs (regno, mode) == 1);
 }
 
 /* Implement TARGET_MODES_TIEABLE_P.  */
@@ -1885,7 +1912,7 @@ visium_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
       int offset_base = offset & ~mask;
 
       /* Check that all of the words can be accessed.  */
-      if (4 < size && 0x80 < size + offset - offset_base)
+      if (size > 4 && size + offset - offset_base > 0x80)
        offset_base = offset & ~0x3f;
       if (offset_base != 0 && offset_base != offset && (offset & mask1) == 0)
        {
@@ -1931,7 +1958,7 @@ visium_legitimize_reload_address (rtx x, machine_mode mode, int opnum,
       int offset_base = offset & ~mask;
 
       /* Check that all of the words can be accessed.  */
-      if (4 < size && 0x80 < size + offset - offset_base)
+      if (size > 4 && size + offset - offset_base > 0x80)
        offset_base = offset & ~0x3f;
 
       if (offset_base && (offset & mask1) == 0)
@@ -2684,6 +2711,7 @@ visium_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
 
        moviu   r9,%u FUNCTION
        movil   r9,%l FUNCTION
+       [nop]
        moviu   r20,%u STATIC
        bra     tr,r9,r9
         movil   r20,%l STATIC
@@ -2704,6 +2732,14 @@ visium_trampoline_init (rtx m_tramp, tree fndecl, rtx static_chain)
                                             NULL_RTX),
                                 0x04890000));
 
+  if (visium_cpu == PROCESSOR_GR6)
+    {
+      /* For the GR6, the BRA insn must be aligned on a 64-bit boundary.  */
+      gcc_assert (TRAMPOLINE_ALIGNMENT >= 64);
+      emit_move_insn (gen_rtx_MEM (SImode, plus_constant (Pmode, addr, 12)),
+                     gen_int_mode (0, SImode));
+    }
+
   emit_move_insn (gen_rtx_MEM (SImode, plus_constant (Pmode, addr, 8)),
                  plus_constant (SImode,
                                 expand_shift (RSHIFT_EXPR, SImode,
@@ -2904,12 +2940,6 @@ visium_select_cc_mode (enum rtx_code code, rtx op0, rtx op1)
       /* This is a btst, the result is in C instead of Z.  */
       return CCCmode;
 
-    case CONST_INT:
-      /* This is a degenerate case, typically an uninitialized variable.  */
-      gcc_assert (op0 == constm1_rtx);
-
-      /* ... fall through ... */
-
     case REG:
     case AND:
     case IOR:
@@ -2926,6 +2956,17 @@ visium_select_cc_mode (enum rtx_code code, rtx op0, rtx op1)
         when applied to a comparison with zero.  */
       return CCmode;
 
+    /* ??? Cater to the junk RTXes sent by try_merge_compare.  */
+    case ASM_OPERANDS:
+    case CALL:
+    case CONST_INT:
+    case LO_SUM:
+    case HIGH:
+    case MEM:
+    case UNSPEC:
+    case ZERO_EXTEND:
+      return CCmode;
+
     default:
       gcc_unreachable ();
     }
@@ -3013,9 +3054,9 @@ output_branch (rtx label, const char *cond, rtx_insn *insn)
   gcc_assert (cond);
   operands[0] = label;
 
-  /* If the length of the instruction is greater than 8, then this is a
+  /* If the length of the instruction is greater than 12, then this is a
      long branch and we need to work harder to emit it properly.  */
-  if (get_attr_length (insn) > 8)
+  if (get_attr_length (insn) > 12)
     {
       bool spilled;
 
@@ -3052,10 +3093,9 @@ output_branch (rtx label, const char *cond, rtx_insn *insn)
          if (final_sequence)
            {
              rtx_insn *delay = NEXT_INSN (insn);
-             int seen;
              gcc_assert (delay);
 
-             final_scan_insn (delay, asm_out_file, optimize, 0, &seen);
+             final_scan_insn (delay, asm_out_file, optimize, 0, NULL);
              PATTERN (delay) = gen_blockage ();
              INSN_CODE (delay) = -1;
            }
@@ -4278,4 +4318,24 @@ reg_or_subreg_regno (rtx op)
   return regno;
 }
 
+/* Implement TARGET_CAN_CHANGE_MODE_CLASS.
+
+   It's not obvious from the documentation of the hook that MDB cannot
+   change mode.  However difficulties arise from expressions of the form
+
+   (subreg:SI (reg:DI R_MDB) 0)
+
+   There is no way to convert that reference to a single machine
+   register and, without the following definition, reload will quietly
+   convert it to
+
+   (reg:SI R_MDB).  */
+
+static bool
+visium_can_change_mode_class (machine_mode from, machine_mode to,
+                             reg_class_t rclass)
+{
+  return (rclass != MDB || GET_MODE_SIZE (from) == GET_MODE_SIZE (to));
+}
+
 #include "gt-visium.h"