diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-04-14 20:59:44 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-04-14 20:59:44 +0000 |
commit | 36ed44068db8a11c50e1494c752b07599e877eeb (patch) | |
tree | 9c02115a5fab37fecb33b292a41ee8321de14ddc /gcc | |
parent | d3c451dde186316692e666f3131d302c4f9cbce4 (diff) | |
download | gcc-36ed44068db8a11c50e1494c752b07599e877eeb.tar.gz |
* mn10300.c (can_use_return_insn): Include outgoing argument
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/mn10300/mn10300.c | 65 | ||||
-rw-r--r-- | gcc/config/mn10300/mn10300.h | 38 | ||||
-rw-r--r-- | gcc/config/mn10300/mn10300.md | 23 |
3 files changed, 73 insertions, 53 deletions
diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index 10e7ae36030..f2161024dc0 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -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; +} diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h index c36c6c499f6..d7ac6af3e99 100644 --- a/gcc/config/mn10300/mn10300.h +++ b/gcc/config/mn10300/mn10300.h @@ -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 (); diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md index 13628ecf1f3..d936a02df12 100644 --- a/gcc/config/mn10300/mn10300.md +++ b/gcc/config/mn10300/mn10300.md @@ -156,6 +156,22 @@ ;; 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" ""))] @@ -646,7 +662,7 @@ }") (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")))] "" @@ -657,7 +673,7 @@ 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" "")) @@ -1211,7 +1227,7 @@ }") (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")))] "" @@ -1424,3 +1440,4 @@ "dead_or_set_p (ins1, operands[0]) && REG_OK_FOR_INDEX_P (operands[0])" "add %0,%0\;bcc %1" [(set_attr "cc" "clobber")]) + |