diff options
Diffstat (limited to 'gnu/egcs/gcc/config/m88k/m88k.c')
-rw-r--r-- | gnu/egcs/gcc/config/m88k/m88k.c | 196 |
1 files changed, 101 insertions, 95 deletions
diff --git a/gnu/egcs/gcc/config/m88k/m88k.c b/gnu/egcs/gcc/config/m88k/m88k.c index e8f6f66b607..6c46ff1d544 100644 --- a/gnu/egcs/gcc/config/m88k/m88k.c +++ b/gnu/egcs/gcc/config/m88k/m88k.c @@ -59,6 +59,7 @@ int m88k_function_number = 0; /* Counter unique to each function */ int m88k_fp_offset = 0; /* offset of frame pointer if used */ int m88k_stack_size = 0; /* size of allocated stack (including frame) */ int m88k_case_index; +int m88k_first_vararg; rtx m88k_compare_reg; /* cmp output pseudo register */ rtx m88k_compare_op0; /* cmpsi operand 0 */ @@ -1712,8 +1713,6 @@ output_label (label_number) | caller's frame | |==============================================| | [caller's outgoing memory arguments] | - |==============================================| - | caller's outgoing argument area (32 bytes) | sp -> |==============================================| <- ap | [local variable space] | |----------------------------------------------| @@ -1729,8 +1728,6 @@ output_label (label_number) |==============================================| | [callee's outgoing memory arguments] | |==============================================| - | [callee's outgoing argument area (32 bytes)] | - |==============================================| <- sp Notes: @@ -1787,15 +1784,11 @@ m88k_layout_frame () if (write_symbols != NO_DEBUG && !TARGET_OCS_FRAME_POSITION) save_regs[1] = 1; - /* If there is a call, alloca is used, __builtin_alloca is used, or - a dynamic-sized object is defined, add the 8 additional words - for the callee's argument area. The common denominator is that the - FP is required. may_call_alloca only gets calls to alloca; - current_function_calls_alloca gets alloca and __builtin_alloca. */ + /* If there is a call, or we need a debug frame, r1 needs to be + saved as well. */ if (regs_ever_live[1] || frame_pointer_needed) { save_regs[1] = 1; - sp_size += REG_PARM_STACK_SPACE (0); } /* If we are producing PIC, save the addressing base register and r1. */ @@ -1887,35 +1880,6 @@ null_prologue () && nxregs == 0 && m88k_stack_size == 0); } - -/* Determine if the current function has any references to the arg pointer. - This is done indirectly by examining the DECL_ARGUMENTS' DECL_RTL. - It is OK to return TRUE if there are no references, but FALSE must be - correct. */ - -static int -uses_arg_area_p () -{ - register tree parm; - - if (current_function_decl == 0 - || current_function_varargs || current_function_stdarg) - return 1; - - for (parm = DECL_ARGUMENTS (current_function_decl); - parm; - parm = TREE_CHAIN (parm)) - { - if (DECL_RTL (parm) == 0 - || GET_CODE (DECL_RTL (parm)) == MEM) - return 1; - - if (DECL_INCOMING_RTL (parm) == 0 - || GET_CODE (DECL_INCOMING_RTL (parm)) == MEM) - return 1; - } - return 0; -} void m88k_begin_prologue (stream, size) @@ -1956,16 +1920,6 @@ m88k_expand_prologue () { m88k_layout_frame (); - if (TARGET_OPTIMIZE_ARG_AREA - && m88k_stack_size - && ! uses_arg_area_p ()) - { - /* The incoming argument area is used for stack space if it is not - used (or if -mno-optimize-arg-area is given). */ - if ((m88k_stack_size -= REG_PARM_STACK_SPACE (0)) < 0) - m88k_stack_size = 0; - } - if (m88k_stack_size) emit_add (stack_pointer_rtx, stack_pointer_rtx, -m88k_stack_size); @@ -2373,11 +2327,11 @@ output_function_profiler (file, labelno, name, savep) if (savep) { - fprintf (file, "\tsubu\t %s,%s,64\n", reg_names[31], reg_names[31]); - fprintf (file, "\tst.d\t %s,%s,32\n", reg_names[2], reg_names[31]); - fprintf (file, "\tst.d\t %s,%s,40\n", reg_names[4], reg_names[31]); - fprintf (file, "\tst.d\t %s,%s,48\n", reg_names[6], reg_names[31]); - fprintf (file, "\tst.d\t %s,%s,56\n", reg_names[8], reg_names[31]); + fprintf (file, "\tsubu\t %s,%s,32\n", reg_names[31], reg_names[31]); + fprintf (file, "\tst.d\t %s,%s,0\n", reg_names[2], reg_names[31]); + fprintf (file, "\tst.d\t %s,%s,8\n", reg_names[4], reg_names[31]); + fprintf (file, "\tst.d\t %s,%s,16\n", reg_names[6], reg_names[31]); + fprintf (file, "\tst.d\t %s,%s,24\n", reg_names[8], reg_names[31]); } ASM_GENERATE_INTERNAL_LABEL (label, "LP", labelno); @@ -2411,11 +2365,11 @@ output_function_profiler (file, labelno, name, savep) if (savep) { - fprintf (file, "\tld.d\t %s,%s,32\n", reg_names[2], reg_names[31]); - fprintf (file, "\tld.d\t %s,%s,40\n", reg_names[4], reg_names[31]); - fprintf (file, "\tld.d\t %s,%s,48\n", reg_names[6], reg_names[31]); - fprintf (file, "\tld.d\t %s,%s,56\n", reg_names[8], reg_names[31]); - fprintf (file, "\taddu\t %s,%s,64\n", reg_names[31], reg_names[31]); + fprintf (file, "\tld.d\t %s,%s,0\n", reg_names[2], reg_names[31]); + fprintf (file, "\tld.d\t %s,%s,8\n", reg_names[4], reg_names[31]); + fprintf (file, "\tld.d\t %s,%s,16\n", reg_names[6], reg_names[31]); + fprintf (file, "\tld.d\t %s,%s,24\n", reg_names[8], reg_names[31]); + fprintf (file, "\taddu\t %s,%s,32\n", reg_names[31], reg_names[31]); } } @@ -2443,21 +2397,21 @@ output_function_block_profiler (file, labelno) m88k_pound_sign, &block[1]); fprintf (file, "\tbcnd\t %sne0,%s,%s\n", m88k_pound_sign, reg_names[26], &label[1]); - fprintf (file, "\tsubu\t %s,%s,64\n", reg_names[31], reg_names[31]); - fprintf (file, "\tst.d\t %s,%s,32\n", reg_names[2], reg_names[31]); - fprintf (file, "\tst.d\t %s,%s,40\n", reg_names[4], reg_names[31]); - fprintf (file, "\tst.d\t %s,%s,48\n", reg_names[6], reg_names[31]); - fprintf (file, "\tst.d\t %s,%s,56\n", reg_names[8], reg_names[31]); + fprintf (file, "\tsubu\t %s,%s,32\n", reg_names[31], reg_names[31]); + fprintf (file, "\tst.d\t %s,%s,0\n", reg_names[2], reg_names[31]); + fprintf (file, "\tst.d\t %s,%s,8\n", reg_names[4], reg_names[31]); + fprintf (file, "\tst.d\t %s,%s,16\n", reg_names[6], reg_names[31]); + fprintf (file, "\tst.d\t %s,%s,24\n", reg_names[8], reg_names[31]); fputs ("\tbsr.n\t ", file); ASM_OUTPUT_LABELREF (file, "__bb_init_func"); putc ('\n', file); fprintf (file, "\tor\t %s,%s,%slo16(%s)\n", reg_names[2], reg_names[27], m88k_pound_sign, &block[1]); - fprintf (file, "\tld.d\t %s,%s,32\n", reg_names[2], reg_names[31]); - fprintf (file, "\tld.d\t %s,%s,40\n", reg_names[4], reg_names[31]); - fprintf (file, "\tld.d\t %s,%s,48\n", reg_names[6], reg_names[31]); - fprintf (file, "\tld.d\t %s,%s,56\n", reg_names[8], reg_names[31]); - fprintf (file, "\taddu\t %s,%s,64\n", reg_names[31], reg_names[31]); + fprintf (file, "\tld.d\t %s,%s,0\n", reg_names[2], reg_names[31]); + fprintf (file, "\tld.d\t %s,%s,8\n", reg_names[4], reg_names[31]); + fprintf (file, "\tld.d\t %s,%s,16\n", reg_names[6], reg_names[31]); + fprintf (file, "\tld.d\t %s,%s,24\n", reg_names[8], reg_names[31]); + fprintf (file, "\taddu\t %s,%s,32\n", reg_names[31], reg_names[31]); ASM_OUTPUT_INTERNAL_LABEL (file, "LPY", labelno); } @@ -2592,6 +2546,49 @@ m88k_function_arg_advance (args_so_far, mode, type, named) (*args_so_far) += (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; } +/* Perform any needed actions needed for a function that is receiving a + variable number of arguments. + + CUM is as above. + + MODE and TYPE are the mode and type of the current parameter. + + PRETEND_SIZE is a variable that should be set to the amount of stack + that must be pushed by the prolog to pretend that our caller pushed + it. + + Normally, this macro will push all remaining incoming registers on the + stack and set PRETEND_SIZE to the length of the registers pushed. */ + +void +m88k_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) + CUMULATIVE_ARGS *cum; + enum machine_mode mode; + tree type; + int *pretend_size; + int no_rtl; +{ + CUMULATIVE_ARGS next_cum; + tree fntype; + int stdarg_p; + + if (no_rtl) + return; + + fntype = TREE_TYPE (current_function_decl); + stdarg_p = (TYPE_ARG_TYPES (fntype) != 0 + && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) + != void_type_node)); + + /* For varargs, we do not want to skip the dummp va_dcl argument. + For stdargs, we do want to skip the last named argument. */ + next_cum = *cum; + if (stdarg_p) + m88k_function_arg_advance(&next_cum, mode, type, 1); + + m88k_first_vararg = next_cum; +} + /* Do what is necessary for `va_start'. The argument is ignored; We look at the current function to determine if stdargs or varargs is used and fill in an initial va_list. A pointer to this constructor @@ -2599,54 +2596,61 @@ m88k_function_arg_advance (args_so_far, mode, type, named) struct rtx_def * m88k_builtin_saveregs (arglist) - tree arglist; + tree arglist ATTRIBUTE_UNUSED; { rtx valist, regblock, addr; - tree fntype = TREE_TYPE (current_function_decl); - int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0 - && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) - != void_type_node))) - ? -UNITS_PER_WORD : 0) + UNITS_PER_WORD - 1; - int fixed, delta, regno; + tree fntype; + int stdarg_p; + int regcnt, offset; + + regcnt = m88k_first_vararg < 8 ? 8 - m88k_first_vararg : 0; + + fntype = TREE_TYPE (current_function_decl); + stdarg_p = (TYPE_ARG_TYPES (fntype) != 0 + && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) + != void_type_node)); if (! CONSTANT_P (current_function_arg_offset_rtx)) abort (); - fixed = (XINT (current_function_arg_offset_rtx, 0) + argadj) / UNITS_PER_WORD; + offset = XINT (current_function_arg_offset_rtx, 0); + if (m88k_first_vararg >= 8 && ! stdarg_p) + offset -= UNITS_PER_WORD; /* Allocate the va_list constructor */ - valist = assign_stack_local (BLKmode, 4 * UNITS_PER_WORD, BITS_PER_WORD); + valist = assign_stack_local (BLKmode, 3 * UNITS_PER_WORD, BITS_PER_WORD); MEM_SET_IN_STRUCT_P (valist, 1); RTX_UNCHANGING_P (valist) = 1; RTX_UNCHANGING_P (XEXP (valist, 0)) = 1; - /* Store the argsize as the __va_arg member. */ + /* Store the __va_arg member. */ emit_move_insn (change_address (valist, SImode, XEXP (valist, 0)), - GEN_INT (fixed)); + GEN_INT (m88k_first_vararg)); /* Store the arg pointer in the __va_stk member. */ emit_move_insn (change_address (valist, Pmode, plus_constant (XEXP (valist, 0), UNITS_PER_WORD)), copy_to_reg (plus_constant (virtual_incoming_args_rtx, - REG_PARM_STACK_SPACE - (current_function_decl)))); + offset))); /* Allocate the register space, and store it as the __va_reg member. */ - if (fixed < 8) + if (regcnt) { - if (fixed == 7) + int delta, regno; + + if (regcnt == 1) { regblock = assign_stack_local (BLKmode, UNITS_PER_WORD, BITS_PER_WORD); - delta = 0; + delta = 0; } else { - delta = (fixed & 1); + delta = (regcnt & 1); regblock = assign_stack_local (BLKmode, - (8 + delta - fixed) * UNITS_PER_WORD, - -1); + (regcnt + delta) * UNITS_PER_WORD, + 2 * BITS_PER_WORD); } MEM_SET_IN_STRUCT_P (regblock, 1); @@ -2664,12 +2668,13 @@ m88k_builtin_saveregs (arglist) plus_constant (XEXP (valist, 0), 2 * UNITS_PER_WORD)), copy_to_reg (plus_constant (XEXP (regblock, 0), - (delta - fixed) * + (delta - m88k_first_vararg) * UNITS_PER_WORD))); - regno = 2 + fixed; + regno = 2 + m88k_first_vararg; + delta = regno & 1; - if (regno & 1) + if (delta) { emit_move_insn (operand_subword (addr, 0, 1, BLKmode), gen_rtx_REG (word_mode, regno)); @@ -2680,10 +2685,11 @@ m88k_builtin_saveregs (arglist) { emit_move_insn (change_address (addr, DImode, plus_constant (XEXP (addr, 0), - (regno - (2 + fixed)) * + delta * UNITS_PER_WORD)), gen_rtx_REG (DImode, regno)); regno += 2; + delta += 2; } } @@ -2691,13 +2697,13 @@ m88k_builtin_saveregs (arglist) { emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, valist, ptr_mode, - GEN_INT (4 * UNITS_PER_WORD), TYPE_MODE (sizetype), + GEN_INT (3 * UNITS_PER_WORD), TYPE_MODE (sizetype), GEN_INT (MEMORY_USE_RW), TYPE_MODE (integer_type_node)); - if (fixed < 8) + if (regcnt) emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3, addr, ptr_mode, - GEN_INT (UNITS_PER_WORD * (8 - fixed)), + GEN_INT (UNITS_PER_WORD * regcnt), TYPE_MODE (sizetype), GEN_INT (MEMORY_USE_RW), TYPE_MODE (integer_type_node)); |