diff --git a/gcc/config/mn10300/mn10300.c b/gcc/config/mn10300/mn10300.c index 5093351870d..1ae2a27b893 100644 --- a/gcc/config/mn10300/mn10300.c +++ b/gcc/config/mn10300/mn10300.c @@ -327,7 +327,8 @@ print_operand_address (file, addr) int can_use_return_insn () { - int size = get_frame_size (); + /* SIZE includes the fixed stack space needed for function calls. */ + int size = get_frame_size () + (!leaf_function_p () ? 12 : 0); return (reload_completed && size == 0 @@ -341,7 +342,17 @@ can_use_return_insn () void expand_prologue () { - unsigned int size = get_frame_size (); + 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 (); /* If this is an old-style varargs function, then its arguments need to be flushed back to the stack. */ @@ -378,7 +389,17 @@ expand_prologue () void expand_epilogue () { - unsigned int size = get_frame_size (); + 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 (); /* Cut back the stack. */ if (frame_pointer_needed) @@ -528,6 +549,8 @@ int initial_offset (from, to) int from, to; { + /* The difference between the argument pointer and the frame pointer + is the size of the callee register save area. */ if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM) { if (regs_ever_live[2] || regs_ever_live[3] @@ -538,18 +561,24 @@ initial_offset (from, to) return 0; } + /* The difference between the argument pointer and the stack pointer is + the sum of the size of this function's frame, the callee register save + area, and the fixed stack space needed for function calls (if any). */ if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM) { 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; + return (get_frame_size () + 16 + (!leaf_function_p () ? 12 : 0)); else - return get_frame_size (); + return (get_frame_size () + (!leaf_function_p () ? 12 : 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 (); + return get_frame_size () + (!leaf_function_p () ? 12 : 0); abort (); } diff --git a/gcc/config/mn10300/mn10300.h b/gcc/config/mn10300/mn10300.h index f70b6bf6a01..d850641eb65 100644 --- a/gcc/config/mn10300/mn10300.h +++ b/gcc/config/mn10300/mn10300.h @@ -423,7 +423,10 @@ 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 + +/* So we can allocate space for return pointers once for the function + instead of around every call. */ +#define STACK_POINTER_OFFSET 4 /* 1 if N is a possible register number for function argument passing. On the MN10300, no registers are used in this way. */ diff --git a/gcc/config/mn10300/mn10300.md b/gcc/config/mn10300/mn10300.md index 5db2a944b92..98f453625ab 100644 --- a/gcc/config/mn10300/mn10300.md +++ b/gcc/config/mn10300/mn10300.md @@ -962,9 +962,7 @@ { if (! call_address_operand (XEXP (operands[0], 0))) XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); - emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4))); emit_call_insn (gen_call_internal (XEXP (operands[0], 0), operands[1])); - emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (4))); DONE; }") @@ -987,11 +985,9 @@ { if (! call_address_operand (XEXP (operands[1], 0))) XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); - emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (-4))); emit_call_insn (gen_call_value_internal (operands[0], XEXP (operands[1], 0), operands[2])); - emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (4))); DONE; }") @@ -1062,19 +1058,16 @@ ;; ---------------------------------------------------------------------- (define_insn "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "=da,d,a,d,a,d,a,d") + [(set (match_operand:SI 0 "register_operand" "=da,d,d,d,d") (ashift:SI - (match_operand:SI 1 "register_operand" "0,0,0,0,0,0,0,0") - (match_operand:QI 2 "nonmemory_operand" "J,K,K,M,M,L,L,di")))] + (match_operand:SI 1 "register_operand" "0,0,0,0,0") + (match_operand:QI 2 "nonmemory_operand" "J,K,M,L,di")))] "" "@ add %0,%0 asl2 %0 - add %0,%0\;add %0,%0 asl2 %0\;add %0,%0 - add %0,%0\;add %0,%0\;add %0,%0 asl2 %0\;asl2 %0 - add %0,%0\;add %0,%0\;add %0,%0\;add %0,%0 asl %2,%0" [(set_attr "cc" "set_zn_c0")])