]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/mmix/mmix.c
Wrap option names in gcc internal messages with %< and %>.
[thirdparty/gcc.git] / gcc / config / mmix / mmix.c
index 6ca2fd9441cadd162c3462498f642be17b51629e..c2136e223053b679ba89161e67b7538cb381b196 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of target machine for GNU compiler, for MMIX.
-   Copyright (C) 2000-2017 Free Software Foundation, Inc.
+   Copyright (C) 2000-2019 Free Software Foundation, Inc.
    Contributed by Hans-Peter Nilsson (hp@bitrange.com)
 
 This file is part of GCC.
@@ -18,6 +18,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"
@@ -31,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "memmodel.h"
 #include "tm_p.h"
 #include "insn-config.h"
+#include "optabs.h"
 #include "regs.h"
 #include "emit-rtl.h"
 #include "recog.h"
@@ -58,19 +61,16 @@ along with GCC; see the file COPYING3.  If not see
 
 /* We have no means to tell DWARF 2 about the register stack, so we need
    to store the return address on the stack if an exception can get into
-   this function.  FIXME: Narrow condition.  Before any whole-function
-   analysis, df_regs_ever_live_p () isn't initialized.  We know it's up-to-date
-   after reload_completed; it may contain incorrect information some time
-   before that.  Within a RTL sequence (after a call to start_sequence,
-   such as in RTL expanders), leaf_function_p doesn't see all insns
-   (perhaps any insn).  But regs_ever_live is up-to-date when
-   leaf_function_p () isn't, so we "or" them together to get accurate
-   information.  FIXME: Some tweak to leaf_function_p might be
-   preferable.  */
+   this function.  We'll have an "initial value" recorded for the
+   return-register if we've seen a call instruction emitted.  This note
+   will be inaccurate before instructions are emitted, but the only caller
+   at that time is looking for modulo from stack-boundary, to which the
+   return-address does not contribute, and which is always 0 for MMIX
+   anyway.  Beware of calling leaf_function_p here, as it'll abort if
+   called within a sequence.  */
 #define MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS                        \
  (flag_exceptions                                              \
-  && ((reload_completed && df_regs_ever_live_p (MMIX_rJ_REGNUM))       \
-      || !leaf_function_p ()))
+  && has_hard_reg_initial_val (Pmode, MMIX_INCOMING_RETURN_ADDRESS_REGNUM))
 
 #define IS_MMIX_EH_RETURN_DATA_REG(REGNO)      \
  (crtl->calls_eh_return                \
@@ -127,9 +127,9 @@ static struct machine_function *mmix_init_machine_status (void);
 static void mmix_encode_section_info (tree, rtx, int);
 static const char *mmix_strip_name_encoding (const char *);
 static void mmix_emit_sp_add (HOST_WIDE_INT offset);
-static void mmix_target_asm_function_prologue (FILE *, HOST_WIDE_INT);
+static void mmix_target_asm_function_prologue (FILE *);
 static void mmix_target_asm_function_end_prologue (FILE *);
-static void mmix_target_asm_function_epilogue (FILE *, HOST_WIDE_INT);
+static void mmix_target_asm_function_epilogue (FILE *);
 static reg_class_t mmix_preferred_reload_class (rtx, reg_class_t);
 static reg_class_t mmix_preferred_output_reload_class (rtx, reg_class_t);
 static bool mmix_legitimate_address_p (machine_mode, rtx, bool);
@@ -141,6 +141,7 @@ static void mmix_setup_incoming_varargs
   (cumulative_args_t, machine_mode, tree, int *, int);
 static void mmix_file_start (void);
 static void mmix_file_end (void);
+static void mmix_init_libfuncs (void);
 static bool mmix_rtx_costs (rtx, machine_mode, int, int, int *, bool);
 static int mmix_register_move_cost (machine_mode,
                                    reg_class_t, reg_class_t);
@@ -168,6 +169,9 @@ static void mmix_print_operand (FILE *, rtx, int);
 static void mmix_print_operand_address (FILE *, machine_mode, rtx);
 static bool mmix_print_operand_punct_valid_p (unsigned char);
 static void mmix_conditional_register_usage (void);
+static HOST_WIDE_INT mmix_static_rtx_alignment (machine_mode);
+static HOST_WIDE_INT mmix_constant_alignment (const_tree, HOST_WIDE_INT);
+static HOST_WIDE_INT mmix_starting_frame_offset (void);
 
 /* Target structure macros.  Listed by node.  See `Using and Porting GCC'
    for a general description.  */
@@ -219,9 +223,15 @@ static void mmix_conditional_register_usage (void);
 #undef TARGET_ASM_OUTPUT_SOURCE_FILENAME
 #define TARGET_ASM_OUTPUT_SOURCE_FILENAME mmix_asm_output_source_filename
 
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS mmix_init_libfuncs
+
 #undef TARGET_CONDITIONAL_REGISTER_USAGE
 #define TARGET_CONDITIONAL_REGISTER_USAGE mmix_conditional_register_usage
 
+#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
+#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
+
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS mmix_rtx_costs
 #undef TARGET_ADDRESS_COST
@@ -282,6 +292,14 @@ static void mmix_conditional_register_usage (void);
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE mmix_option_override
 
+#undef TARGET_STATIC_RTX_ALIGNMENT
+#define TARGET_STATIC_RTX_ALIGNMENT mmix_static_rtx_alignment
+#undef TARGET_CONSTANT_ALIGNMENT
+#define TARGET_CONSTANT_ALIGNMENT mmix_constant_alignment
+
+#undef TARGET_STARTING_FRAME_OFFSET
+#define TARGET_STARTING_FRAME_OFFSET mmix_starting_frame_offset
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 /* Functions that are expansions for target macros.
@@ -299,7 +317,8 @@ mmix_option_override (void)
      labels.  */
   if (flag_pic)
     {
-      warning (0, "-f%s not supported: ignored", (flag_pic > 1) ? "PIC" : "pic");
+      warning (0, "%<-f%s%> not supported: ignored",
+              (flag_pic > 1) ? "PIC" : "pic");
       flag_pic = 0;
     }
 }
@@ -334,10 +353,18 @@ mmix_data_alignment (tree type ATTRIBUTE_UNUSED, int basic_align)
   return basic_align;
 }
 
-/* CONSTANT_ALIGNMENT.  */
+/* Implement TARGET_STATIC_RTX_ALIGNMENT.  */
 
-int
-mmix_constant_alignment (tree constant ATTRIBUTE_UNUSED, int basic_align)
+static HOST_WIDE_INT
+mmix_static_rtx_alignment (machine_mode mode)
+{
+  return MAX (GET_MODE_ALIGNMENT (mode), 32);
+}
+
+/* Implement tARGET_CONSTANT_ALIGNMENT.  */
+
+static HOST_WIDE_INT
+mmix_constant_alignment (const_tree, HOST_WIDE_INT basic_align)
 {
   if (basic_align < 32)
     return 32;
@@ -494,9 +521,9 @@ mmix_dynamic_chain_address (rtx frame)
   return plus_constant (Pmode, frame, -8);
 }
 
-/* STARTING_FRAME_OFFSET.  */
+/* Implement TARGET_STARTING_FRAME_OFFSET.  */
 
-int
+static HOST_WIDE_INT
 mmix_starting_frame_offset (void)
 {
   /* The old frame pointer is in the slot below the new one, so
@@ -562,7 +589,7 @@ mmix_initial_elimination_offset (int fromreg, int toreg)
      counted; the others go on the register stack.
 
      The frame-pointer is counted too if it is what is eliminated, as we
-     need to balance the offset for it from STARTING_FRAME_OFFSET.
+     need to balance the offset for it from TARGET_STARTING_FRAME_OFFSET.
 
      Also add in the slot for the register stack pointer we save if we
      have a landing pad.
@@ -821,8 +848,7 @@ mmix_asm_preferred_eh_data_format (int code ATTRIBUTE_UNUSED,
    mmix_reorg.  */
 
 static void
-mmix_target_asm_function_prologue (FILE *stream ATTRIBUTE_UNUSED,
-                                  HOST_WIDE_INT framesize ATTRIBUTE_UNUSED)
+mmix_target_asm_function_prologue (FILE *)
 {
   cfun->machine->in_prologue = 1;
 }
@@ -880,8 +906,7 @@ mmix_reorg (void)
 /* TARGET_ASM_FUNCTION_EPILOGUE.  */
 
 static void
-mmix_target_asm_function_epilogue (FILE *stream,
-                                  HOST_WIDE_INT locals_size ATTRIBUTE_UNUSED)
+mmix_target_asm_function_epilogue (FILE *stream)
 {
   /* Emit an \n for readability of the generated assembly.  */
   fputc ('\n', stream);
@@ -1289,6 +1314,20 @@ mmix_asm_output_source_filename (FILE *stream, const char *name)
   fprintf (stream, "\n");
 }
 
+/* Unfortunately, by default __builtin_ffs is expanded to ffs for
+   targets where INT_TYPE_SIZE < BITS_PER_WORD.  That together with
+   newlib since 2017-07-04 implementing ffs as __builtin_ffs leads to
+   (newlib) ffs recursively calling itself.  But, because of argument
+   promotion, and with ffs we're counting from the least bit, the
+   libgcc equivalent for ffsl works equally well for int arguments, so
+   just use that.  */
+
+static void
+mmix_init_libfuncs (void)
+{
+  set_optab_libfunc (ffs_optab, SImode, "__ffsdi2");
+}
+
 /* OUTPUT_QUOTED_STRING.  */
 
 void
@@ -1354,8 +1393,14 @@ mmix_assemble_integer (rtx x, unsigned int size, int aligned_p)
       case 1:
        if (GET_CODE (x) != CONST_INT)
          {
-           aligned_p = 0;
-           break;
+           /* There is no "unaligned byte" op or generic function to
+              which we can punt, so we have to handle this here.  As
+              the expression isn't a plain literal, the generated
+              assembly-code can't be mmixal-equivalent (i.e. "BYTE"
+              won't work) and thus it's ok to emit the default op
+              ".byte". */
+           assemble_integer_with_op ("\t.byte\t", x);
+           return true;
          }
        fputs ("\tBYTE\t", asm_out_file);
        mmix_print_operand (asm_out_file, x, 'B');
@@ -2650,12 +2695,12 @@ mmix_output_condition (FILE *stream, const_rtx x, int reversed)
 #undef CCEND
 
   static const struct cc_type_conv cc_convs[]
-    = {{CC_FUNmode, cc_fun_convs},
-       {CC_FPmode, cc_fp_convs},
-       {CC_FPEQmode, cc_fpeq_convs},
-       {CC_UNSmode, cc_uns_convs},
-       {CCmode, cc_signed_convs},
-       {DImode, cc_di_convs}};
+    = {{E_CC_FUNmode, cc_fun_convs},
+       {E_CC_FPmode, cc_fp_convs},
+       {E_CC_FPEQmode, cc_fpeq_convs},
+       {E_CC_UNSmode, cc_uns_convs},
+       {E_CCmode, cc_signed_convs},
+       {E_DImode, cc_di_convs}};
 
   size_t i;
   int j;