OSDN Git Service

* mn10300.c (can_use_return_insn): Include outgoing argument
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 14 Apr 1997 20:59:44 +0000 (20:59 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 14 Apr 1997 20:59:44 +0000 (20:59 +0000)
        area in size computation.
        (expand_prologue): Likewise.  No longer diddle with sequences.
        Put register saves just before outgoing argument area.
        (expand_epilogue): Similarly.
        (impossible_plus_operand): New function.
        * mn10300.h (FRAME_POINTER_REQUIRED): Never require a frame pointer.
        (ACCUMULATE_OUTGOING_ARGS, OUTGOING_REG_PARM_STACK_SPACE): Define.
        (impossible_plus_operand): Declare.
        * mn10300.md (reload_insi): New expander to handle pathological
        reload cases.
        (addsi3): Fix CC status.

        * mn10300.h (FUNCTION_VALUE): Return addresses in $a0.
        (FUNCTION_VALUE_REGNO_P): Corresponding changes.
        * mn10300.md (call_value_internal): Allow output to be in an
        address register.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@13903 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/config/mn10300/mn10300.c
gcc/config/mn10300/mn10300.h
gcc/config/mn10300/mn10300.md

index 10e7ae3..f216102 100644 (file)
@@ -347,8 +347,11 @@ print_operand_address (file, addr)
 int
 can_use_return_insn ()
 {
-  /* SIZE includes the fixed stack space needed for function calls.  */
-  int size = get_frame_size () + (!leaf_function_p () ? 12 : 0);
+  /* size includes the fixed stack space needed for function calls.  */
+  int size = get_frame_size () + current_function_outgoing_args_size;
+
+  /* And space for the return pointer.  */
+  size += current_function_outgoing_args_size ? 4 : 0;
 
   return (reload_completed
          && size == 0
@@ -416,11 +419,6 @@ expand_prologue ()
 {
   unsigned int size;
 
-  /* We have to end the current sequence so leaf_function_p and
-     count_tst_insns will work.  We then start a new sequence to
-     hold the prologue/epilogue.  */
-  end_sequence ();
-
   /* Determine if it is profitable to put the value zero into a register
      for the entire function.  If so, set ZERO_DREG and ZERO_AREG.  */
   if (regs_ever_live[2] || regs_ever_live[3]
@@ -478,10 +476,8 @@ expand_prologue ()
     }
 
   /* SIZE includes the fixed stack space needed for function calls.  */
-  size = get_frame_size () + (!leaf_function_p () ? 12 : 0);
-
-  /* Start a new sequence for the prologue/epilogue.  */
-  start_sequence ();
+  size = get_frame_size () + current_function_outgoing_args_size;
+  size += (current_function_outgoing_args_size ? 4 : 0);
 
   /* If this is an old-style varargs function, then its arguments
      need to be flushed back to the stack.  */
@@ -527,15 +523,9 @@ expand_epilogue ()
 {
   unsigned int size;
 
-  /* We have to end the current sequence so leaf_function_p will
-     work.  We then start a new sequence to hold the prologue/epilogue.  */
-  end_sequence ();
-
   /* SIZE includes the fixed stack space needed for function calls.  */
-  size = get_frame_size () + (!leaf_function_p () ? 12 : 0);
-
-  /* Start a new sequence for the prologue/epilogue.  */
-  start_sequence ();
+  size = get_frame_size () + current_function_outgoing_args_size;
+  size += (current_function_outgoing_args_size ? 4 : 0);
 
   /* Cut back the stack.  */
   if (frame_pointer_needed)
@@ -705,16 +695,22 @@ initial_offset (from, to)
       if (regs_ever_live[2] || regs_ever_live[3]
          || regs_ever_live[6] || regs_ever_live[7]
          || frame_pointer_needed)
-       return (get_frame_size () + 16 + (!leaf_function_p () ? 12 : 0));
+       return (get_frame_size () + 16 
+               + (current_function_outgoing_args_size
+                  ? current_function_outgoing_args_size + 4 : 0)); 
       else
-       return (get_frame_size () + (!leaf_function_p () ? 12 : 0));
+       return (get_frame_size ()
+               + (current_function_outgoing_args_size
+                  ? current_function_outgoing_args_size + 4 : 0)); 
     }
 
   /* The difference between the frame pointer and stack pointer is the sum
      of the size of this function's frame and the fixed stack space needed
      for function calls (if any).  */
   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-    return get_frame_size () + (!leaf_function_p () ? 12 : 0);
+    return (get_frame_size ()
+           + (current_function_outgoing_args_size
+              ? current_function_outgoing_args_size + 4 : 0)); 
 
   abort ();
 }
@@ -934,3 +930,28 @@ output_tst (operand, insn)
     }
   return "cmp 0,%0";
 }
+
+int
+impossible_plus_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  extern rtx *reg_equiv_mem;
+  rtx reg1, reg2;
+  
+  if (GET_CODE (op) != PLUS)
+    return 0;
+
+  if ((XEXP (op, 0) == stack_pointer_rtx)
+      && ((REG_P (XEXP (op, 1)) && reg_equiv_mem [REGNO (XEXP (op, 1))])
+         || (GET_CODE (XEXP (op, 1)) == SUBREG
+             && GET_CODE (SUBREG_REG (XEXP (op, 1))) == MEM)))
+    return 1;
+
+  if ((XEXP (op, 1) == stack_pointer_rtx)
+      && ((REG_P (XEXP (op, 0)) && reg_equiv_mem [REGNO (XEXP (op, 0))])
+         || (GET_CODE (XEXP (op, 0)) == SUBREG
+             && GET_CODE (SUBREG_REG (XEXP (op, 0))) == MEM)))
+    return 1;
+  return 0;
+}
index c36c6c4..d7ac6af 100644 (file)
@@ -374,29 +374,6 @@ enum reg_class {
 /* Register in which static-chain is passed to a function.  */
 #define STATIC_CHAIN_REGNUM 5
 
-/* Value should be nonzero if functions must have frame pointers.
-   Zero means the frame pointer need not be set up (and parms
-   may be accessed via the stack pointer) in functions that seem suitable.
-   This is computed in `reload', in reload1.c.
-
-   We allow frame pointers to be eliminated when not having one will
-   not interfere with debugging.
-
-     * If this is a leaf function, then we can keep the stack pointer
-     constant throughout the function, and therefore gdb can easily
-     find the base of the current frame.
-
-     * If this function never allocates stack space for outgoing
-     args (ie calls functions with either no args, or args only
-     in registers), then the stack pointer will be constant and
-     gdb can easily find the base of the current frame.
-
-     We'd really like to define ACCUMULATE_OUTGOING_ARGS and eliminate
-     all frame pointer, but currently we can't.
-
-     We probably also want a -m option to eliminate frame pointer, even
-     if the resulting executable can not be debugged.  */
-
 #define ELIMINABLE_REGS                                \
 {{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},  \
  { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM},  \
@@ -407,8 +384,9 @@ enum reg_class {
 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
   OFFSET = initial_offset (FROM, TO)
 
-#define FRAME_POINTER_REQUIRED \
-  !(leaf_function_p () || current_function_outgoing_args_size == 0)
+/* We can debug without frame pointers on the mn10300, so eliminate
+   them whenever possible.  */
+#define FRAME_POINTER_REQUIRED 0
 #define CAN_DEBUG_WITHOUT_FP
 
 /* A guess for the MN10300.  */
@@ -426,6 +404,8 @@ enum reg_class {
 /* We use d0/d1 for passing parameters, so allocate 8 bytes of space
    for a register flushback area.  */
 #define REG_PARM_STACK_SPACE(DECL) 8
+#define OUTGOING_REG_PARM_STACK_SPACE
+#define ACCUMULATE_OUTGOING_ARGS
 
 /* So we can allocate space for return pointers once for the function
    instead of around every call.  */
@@ -500,8 +480,9 @@ extern struct rtx_def *function_arg ();
    VALTYPE is the data type of the value (as a tree).
    If the precise function being called is known, FUNC is its FUNCTION_DECL;
    otherwise, FUNC is 0.   */
-   
-#define FUNCTION_VALUE(VALTYPE, FUNC) gen_rtx (REG, TYPE_MODE (VALTYPE), 0)
+
+#define FUNCTION_VALUE(VALTYPE, FUNC) \
+  gen_rtx (REG, TYPE_MODE (VALTYPE), POINTER_TYPE_P (VALTYPE) ? 4 : 0)
 
 /* Define how to find the value returned by a library function
    assuming the value has mode MODE.  */
@@ -510,7 +491,7 @@ extern struct rtx_def *function_arg ();
 
 /* 1 if N is a possible register number for a function value.  */
 
-#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
+#define FUNCTION_VALUE_REGNO_P(N) ((N) == 0 || (N) == 4)
 
 /* Return values > 8 bytes in length in memory.  */
 #define DEFAULT_PCC_STRUCT_RETURN 0
@@ -1014,6 +995,7 @@ extern void expand_prologue ();
 extern void expand_epilogue ();
 extern void notice_update_cc ();
 extern int call_address_operand ();
+extern int impossible_plus_operand ();
 extern enum reg_class secondary_reload_class ();
 extern int initial_offset ();
 extern char *output_tst ();
index 13628ec..d936a02 100644 (file)
 
 ;; movsi and helpers
 
+;; We use this to handle addition of two values when one operand is the
+;; stack pointer and the other is a memory reference of some kind.  Reload
+;; does not handle them correctly without this expander.
+(define_expand "reload_insi"
+  [(set (match_operand:SI 0 "register_operand" "=a")
+       (match_operand:SI 1 "impossible_plus_operand" ""))
+   (clobber (match_operand:SI 2 "register_operand" "=&a"))]
+  ""
+  "
+{
+  emit_move_insn (operands[0], XEXP (operands[1], 0));
+  emit_move_insn (operands[2], XEXP (operands[1], 1));
+  emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
+  DONE;
+}")
+
 (define_expand "movsi"
   [(set (match_operand:SI 0 "general_operand" "")
        (match_operand:SI 1 "general_operand" ""))]
 }")
 
 (define_insn ""
-  [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x,!&da")
+  [(set (match_operand:SI 0 "register_operand" "=d,a,a,da,x,&!da")
        (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,0,da")
                 (match_operand:SI 2 "nonmemory_operand" "J,J,L,dai,i,da")))]
   ""
   add %2,%0
   add %2,%0
   mov %2,%0\;add %1,%0"
-  [(set_attr "cc" "set_zn_c0,none_0hit,none_0hit,set_zn_c0,none_0hit,none_0hit")])
+  [(set_attr "cc" "set_zn_c0,none_0hit,none_0hit,set_zn_c0,none_0hit,set_zn_c0")])
 
 (define_expand "adddi3"
   [(set (reg:DI 0) (match_operand:DI 1 "register_operand" ""))
 }")
 
 (define_insn "call_value_internal"
-  [(set (match_operand 0 "" "=d")
+  [(set (match_operand 0 "" "=da")
        (call (mem:QI (match_operand:SI 1 "call_address_operand" "aS"))
              (match_operand:SI 2 "general_operand" "g")))]
   ""
   "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])"
   "add %0,%0\;bcc %1"
   [(set_attr "cc" "clobber")])
+