]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
mmix.md ("return"): New pattern.
authorHans-Peter Nilsson <hp@bitrange.com>
Sun, 30 Jun 2002 18:53:53 +0000 (18:53 +0000)
committerHans-Peter Nilsson <hp@gcc.gnu.org>
Sun, 30 Jun 2002 18:53:53 +0000 (18:53 +0000)
* config/mmix/mmix.md ("return"): New pattern.
* config/mmix/mmix.h (TARGET_MASK_USE_RETURN_INSN)
(TARGET_USE_RETURN_INSN): New macros.
(TARGET_DEFAULT): Include TARGET_MASK_USE_RETURN_INSN.
(TARGET_SWITCHES): Add -msingle-exit and -mno-single-exit.
* config/mmix/mmix.c (MMIX_OUTPUT_REGNO): Fix spacing.
(MMIX_POP_ARGUMENT): New macro.
(mmix_target_asm_function_prologue): When no epilogue is executed,
just emit a blank line.  Use MMIX_POP_ARGUMENT with final POP insn.
(mmix_print_operand) <case '.'>: New case.
(mmix_print_operand_punct_valid_p): Match '.'.
(mmix_use_simple_return): New function.
* config/mmix/mmix-protos.h (mmix_use_simple_return): Prototype.
* doc/invoke.texi (Option Summary) <MMIX Summary>: Add
-msingle-exit, -mno-single-exit.
(MMIX Options): Ditto.

From-SVN: r55121

gcc/ChangeLog
gcc/config/mmix/mmix-protos.h
gcc/config/mmix/mmix.c
gcc/config/mmix/mmix.h
gcc/config/mmix/mmix.md
gcc/doc/invoke.texi

index 4e5a4ab77b5da1ba6757f0e29969fe0f42f8f83f..b70fa7a72e4b85c1bcf83becb3bfa3856fadd682 100644 (file)
@@ -1,3 +1,22 @@
+2002-06-30  Hans-Peter Nilsson  <hp@bitrange.com>
+
+       * config/mmix/mmix.md ("return"): New pattern.
+       * config/mmix/mmix.h (TARGET_MASK_USE_RETURN_INSN)
+       (TARGET_USE_RETURN_INSN): New macros.
+       (TARGET_DEFAULT): Include TARGET_MASK_USE_RETURN_INSN.
+       (TARGET_SWITCHES): Add -msingle-exit and -mno-single-exit.
+       * config/mmix/mmix.c (MMIX_OUTPUT_REGNO): Fix spacing.
+       (MMIX_POP_ARGUMENT): New macro.
+       (mmix_target_asm_function_prologue): When no epilogue is executed,
+       just emit a blank line.  Use MMIX_POP_ARGUMENT with final POP insn.
+       (mmix_print_operand) <case '.'>: New case.
+       (mmix_print_operand_punct_valid_p): Match '.'.
+       (mmix_use_simple_return): New function.
+       * config/mmix/mmix-protos.h (mmix_use_simple_return): Prototype.
+       * doc/invoke.texi (Option Summary) <MMIX Summary>: Add
+       -msingle-exit, -mno-single-exit.
+       (MMIX Options): Ditto.
+
 2002-06-30  Aldy Hernandez  <aldyh@redhat.com>
 
         * config/i386/i386.c (ix86_init_mmx_sse_builtins): Fix typos.
index 895955fafb250922a3e2364b6e6692e84271b5ab..5cfe561d3d36ec0d2ff28d377a67a635e5a4b2e6 100644 (file)
@@ -82,6 +82,7 @@ extern void mmix_asm_output_aligned_local
 extern void mmix_asm_declare_register_global
   PARAMS ((FILE *, tree, int, const char *));
 extern void mmix_asm_output_mi_thunk PARAMS ((FILE *, tree, int, tree));
+extern int mmix_use_simple_return PARAMS ((void));
 
 /* Need tree.h and rtl.h */
 # ifdef RTX_CODE
index 12edac9b4edb18cb4714fe8450eefa0f23f52e09..7dbfb2e879d0fea0d6b64ffb53ad8f8c3ac15e07 100644 (file)
@@ -71,11 +71,20 @@ Boston, MA 02111-1307, USA.  */
    increasing rL and clearing unused (unset) registers with lower numbers.  */
 #define MMIX_OUTPUT_REGNO(N)                                   \
  (TARGET_ABI_GNU                                               \
-  || (int) (N) < MMIX_RETURN_VALUE_REGNUM                              \
-  || (int) (N) > MMIX_LAST_STACK_REGISTER_REGNUM                       \
+  || (int) (N) < MMIX_RETURN_VALUE_REGNUM                      \
+  || (int) (N) > MMIX_LAST_STACK_REGISTER_REGNUM               \
   ? (N) : ((N) - MMIX_RETURN_VALUE_REGNUM                      \
           + cfun->machine->highest_saved_stack_register + 1))
 
+/* The %d in "POP %d,0".  */
+#define MMIX_POP_ARGUMENT()                                            \
+ ((! TARGET_ABI_GNU                                                    \
+   && current_function_return_rtx != NULL                              \
+   && ! current_function_returns_struct)                               \
+  ? (GET_CODE (current_function_return_rtx) == PARALLEL                        \
+     ? GET_NUM_ELEM (XVEC (current_function_return_rtx, 0)) : 1)       \
+  : 0)
+
 /* The canonical saved comparison operands for non-cc0 machines, set in
    the compare expander.  */
 rtx mmix_compare_op0;
@@ -1058,6 +1067,26 @@ mmix_target_asm_function_epilogue (stream, locals_size)
   /* The first address to access is beyond the outgoing_args area.  */
   int offset = current_function_outgoing_args_size;
 
+  rtx insn = get_last_insn ();
+
+  /* If the last insn was a BARRIER, we don't have to write any code,
+     then all returns were covered by "return" insns.  */
+  if (GET_CODE (insn) == NOTE)
+    insn = prev_nonnote_insn (insn);
+  if (insn
+      && (GET_CODE (insn) == BARRIER
+         /* We must make sure that the insn really is a "return" and
+            not a conditional branch.  Try to match the return exactly,
+            and if it doesn't match, assume it is a conditional branch
+            (and output an epilogue).  */
+         || (GET_CODE (insn) == JUMP_INSN
+             && GET_CODE (PATTERN (insn)) == RETURN)))
+    {
+      /* Emit an extra \n as is done with the normal epilogue.  */
+      fputc ('\n', stream);
+      return;
+    }
+
   /* Add the space for global non-register-stack registers.
      It is assumed that the frame-pointer register can be one of these
      registers, in which case it is excluded from the count when needed.  */
@@ -1197,13 +1226,7 @@ mmix_target_asm_function_epilogue (stream, locals_size)
 
   /* The extra \n is so we have a blank line between the assembly code of
      separate functions.  */
-  fprintf (stream, "\tPOP %d,0\n\n",
-          (! TARGET_ABI_GNU
-           && current_function_return_rtx != NULL
-           && ! current_function_returns_struct)
-          ? (GET_CODE (current_function_return_rtx) == PARALLEL
-             ? GET_NUM_ELEM (XVEC (current_function_return_rtx, 0)) : 1)
-          : 0);
+  fprintf (stream, "\tPOP %d,0\n\n", MMIX_POP_ARGUMENT ());
 }
 
 /* ASM_OUTPUT_MI_THUNK.  */
@@ -2098,6 +2121,11 @@ mmix_print_operand (stream, x, code)
        }
       return;
 
+    case '.':
+      /* For the %d in POP %d,0.  */
+      fprintf (stream, "%d", MMIX_POP_ARGUMENT ());
+      return;
+
     case 'B':
       if (GET_CODE (x) != CONST_INT)
        fatal_insn ("MMIX Internal: Expected a CONST_INT, not this", x);
@@ -2303,7 +2331,9 @@ mmix_print_operand_punct_valid_p (code)
      int code ATTRIBUTE_UNUSED;
 {
   /* A '+' is used for branch prediction, similar to other ports.  */
-  return code == '+';
+  return code == '+'
+    /* A '.' is used for the %d in the POP %d,0 return insn.  */
+    || code == '.';
 }
 
 /* PRINT_OPERAND_ADDRESS.  */
@@ -2453,6 +2483,43 @@ mmix_dbx_register_number (regno)
 
    Now MMIX's own functions.  First the exported ones.  */
 
+/* Non-zero when the function epilogue is simple enough that a single
+   "POP %d,0" should be used.  */
+
+int
+mmix_use_simple_return ()
+{
+  int regno;
+
+  int stack_space_to_allocate
+    = (current_function_outgoing_args_size
+       + current_function_pretend_args_size
+       + get_frame_size () + 7) & ~7;
+
+  if (!TARGET_USE_RETURN_INSN || !reload_completed)
+    return 0;
+
+  for (regno = 255;
+       regno >= MMIX_FIRST_GLOBAL_REGNUM;
+       regno--)
+    /* Note that we assume that the frame-pointer-register is one of these
+       registers, in which case we don't count it here.  */
+    if ((((regno != MMIX_FRAME_POINTER_REGNUM || !frame_pointer_needed)
+         && regs_ever_live[regno] && !call_used_regs[regno]))
+       || IS_MMIX_EH_RETURN_DATA_REG (regno))
+      return 0;
+
+  if (frame_pointer_needed)
+    stack_space_to_allocate += 8;
+
+  if (MMIX_CFUN_HAS_LANDING_PAD)
+    stack_space_to_allocate += 16;
+  else if (MMIX_CFUN_NEEDS_SAVED_EH_RETURN_ADDRESS)
+    stack_space_to_allocate += 8;
+
+  return stack_space_to_allocate == 0;
+}
+
 /* Output an optimal sequence for setting a register to a specific
    constant.  Used in an alternative for const_ints in movdi, and when
    using large stack-frame offsets.
index e3099ac9103eb27c17ac007ea7b122b7bd126fe0..7280a3e290424d0e29cc244d0801b38be1a52419 100644 (file)
@@ -161,6 +161,7 @@ extern int target_flags;
 #define TARGET_MASK_KNUTH_DIVISION 16
 #define TARGET_MASK_TOPLEVEL_SYMBOLS 32
 #define TARGET_MASK_BRANCH_PREDICT 64
+#define TARGET_MASK_USE_RETURN_INSN 128
 
 /* We use the term "base address" since that's what Knuth uses.  The base
    address goes in a global register.  When addressing, it's more like
@@ -183,9 +184,11 @@ extern int target_flags;
 #define TARGET_TOPLEVEL_SYMBOLS (target_flags & TARGET_MASK_TOPLEVEL_SYMBOLS)
 #define TARGET_BRANCH_PREDICT (target_flags & TARGET_MASK_BRANCH_PREDICT)
 #define TARGET_BASE_ADDRESSES (target_flags & TARGET_MASK_BASE_ADDRESSES)
+#define TARGET_USE_RETURN_INSN (target_flags & TARGET_MASK_USE_RETURN_INSN)
 
 #define TARGET_DEFAULT \
- (TARGET_MASK_BRANCH_PREDICT | TARGET_MASK_BASE_ADDRESSES)
+ (TARGET_MASK_BRANCH_PREDICT | TARGET_MASK_BASE_ADDRESSES \
+  | TARGET_MASK_USE_RETURN_INSN)
 
 /* FIXME: Provide a way to *load* the epsilon register.  */
 #define TARGET_SWITCHES                                                        \
@@ -220,6 +223,10 @@ extern int target_flags;
    N_("Use addresses that allocate global registers")},                        \
   {"no-base-addresses",        -TARGET_MASK_BASE_ADDRESSES,                    \
    N_("Do not use addresses that allocate global registers")},         \
+  {"single-exit",      -TARGET_MASK_USE_RETURN_INSN,                   \
+   N_("Generate a single exit point for each function")},              \
+  {"no-single-exit",   TARGET_MASK_USE_RETURN_INSN,                    \
+   N_("Do not generate a single exit point for each function")},       \
   {"",                 TARGET_DEFAULT, ""}}
 
 /* Unfortunately, this must not reference anything in "mmix.c".  */
index ad6bd42321002ae2b0c341beb47384f35d874405..024395b7a15e0ae3f4a3341027917705b4d1a9c1 100644 (file)
@@ -1067,8 +1067,10 @@ DIVU %1,%1,%2\;GET %0,:rR\;NEGU %2,0,%0\;CSNN %0,$255,%2")
 ;; I hope untyped_call and untyped_return are not needed for MMIX.
 ;; Users of Objective C will notice.
 
-;; FIXME:  Add "return" pattern where the epilogue is just "pop
-;; 0,0" or similar.
+(define_insn "return"
+  [(return)]
+  "mmix_use_simple_return ()"
+  "POP %.,0")
 
 (define_insn "nop"
   [(const_int 0)]
index d81c4baae3294f54371eca2814a7e300e47e040d..79f184c9f3a4021bd637d35d977ad58777ef7fba 100644 (file)
@@ -600,7 +600,7 @@ in the following sections.
 -mlibfuncs -mno-libfuncs -mepsilon -mno-epsilon -mabi=gnu @gol
 -mabi=mmixware -mzero-extend -mknuthdiv -mtoplevel-symbols @gol
 -melf -mbranch-predict -mno-branch-predict -mbase-addresses @gol
--mno-base-addresses}
+-mno-base-addresses -msingle-exit -mno-single-exit}
 
 @emph{IA-64 Options}
 @gccoptlist{
@@ -9312,6 +9312,13 @@ to 255 from the value held in the register.  The generally leads to short
 and fast code, but the number of different data items that can be
 addressed is limited.  This means that a program that uses lots of static
 data may require @option{-mno-base-addresses}.
+
+@item -msingle-exit
+@itemx -mno-single-exit
+@opindex msingle-exit
+@opindex mno-single-exit
+Force (do not force) generated code to have a single exit point in each
+function.
 @end table
 
 @node PDP-11 Options