diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2012-11-11 21:20:29 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2012-11-11 21:20:29 +0000 |
commit | 31e082a8f129a3e5c298ad87098ac13eb1bffe42 (patch) | |
tree | 9243d18eba06ec5bcca358b7cb6b58e8bc977bb3 /gnu/usr.bin/gcc | |
parent | 9262aaf097edd0f358c2154c50bceb03874c9220 (diff) |
The next step towards a working gcc3/m88k: remove the argument area (from gcc2),
and try to get the builtin varargs code to work. I have tried to mimic the
gcc2 varargs logic, which is optimal in the sense that no argument gets
duplicated and as many arguments as possible are passed in registers, to no
avail (read: hair-pulling ICE out of nowhere in variadic functions). So I am
now sticking to the original gcc 2.7 varargs, where an argument passed on the
stack consumes the registers it would have been passed as, if its type would
have allowed it. This spills too much memory on the stack, but on the other
hand makes the expansion of va_arg() much simpler.
This means that, should gcc3 on m88k platforms be solid enough, mixing varargs
objects compiled with gcc 2 and gcc 3 will not be possible. But we're not there
yet.
Diffstat (limited to 'gnu/usr.bin/gcc')
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/m88k/m88k.c | 121 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/m88k/m88k.h | 25 | ||||
-rw-r--r-- | gnu/usr.bin/gcc/gcc/config/m88k/openbsd.h | 2 |
3 files changed, 60 insertions, 88 deletions
diff --git a/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c b/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c index cc0beb394e5..76bab70a9a8 100644 --- a/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c +++ b/gnu/usr.bin/gcc/gcc/config/m88k/m88k.c @@ -74,6 +74,7 @@ static int m88k_adjust_cost PARAMS ((rtx, rtx, rtx, int)); static void m88k_encode_section_info PARAMS ((tree, int)); /* Initialize the GCC target structure. */ +#if !defined(OBJECT_FORMAT_ELF) #undef TARGET_ASM_BYTE_OP #define TARGET_ASM_BYTE_OP "\tbyte\t" #undef TARGET_ASM_ALIGNED_HI_OP @@ -84,6 +85,7 @@ static void m88k_encode_section_info PARAMS ((tree, int)); #define TARGET_ASM_UNALIGNED_HI_OP "\tuahalf\t" #undef TARGET_ASM_UNALIGNED_SI_OP #define TARGET_ASM_UNALIGNED_SI_OP "\tuaword\t" +#endif #undef TARGET_ASM_FUNCTION_PROLOGUE #define TARGET_ASM_FUNCTION_PROLOGUE m88k_output_function_prologue @@ -908,7 +910,9 @@ output_call (operands, addr) jump = XVECEXP (final_sequence, 0, 1); if (GET_CODE (jump) == JUMP_INSN) { +#ifndef USE_GAS rtx low, high; +#endif const char *last; rtx dest = XEXP (SET_SRC (PATTERN (jump)), 0); int delta = 4 * (INSN_ADDRESSES (INSN_UID (dest)) @@ -1778,8 +1782,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] | |----------------------------------------------| @@ -1794,8 +1796,6 @@ output_label (label_number) | [dynamically allocated space (alloca)] | |==============================================| | [callee's outgoing memory arguments] | - |==============================================| - | [callee's outgoing argument area (32 bytes)] | |==============================================| <- sp Notes: @@ -1810,14 +1810,12 @@ static rtx emit_add PARAMS ((rtx, rtx, int)); static void preserve_registers PARAMS ((int, int)); static void emit_ldst PARAMS ((int, int, enum machine_mode, int)); static void output_tdesc PARAMS ((FILE *, int)); -static int uses_arg_area_p PARAMS ((void)); static int nregs; static int nxregs; static char save_regs[FIRST_PSEUDO_REGISTER]; static int frame_laid_out; static int frame_size; -static int variable_args_p; static int epilogue_marked; static int prologue_marked; @@ -1840,15 +1838,15 @@ m88k_layout_frame () { int regno, sp_size; - frame_laid_out++; + frame_laid_out = 1; memset ((char *) &save_regs[0], 0, sizeof (save_regs)); sp_size = nregs = nxregs = 0; frame_size = get_frame_size (); - /* Since profiling requires a call, make sure r1 is saved. */ + /* Profiling requires a stack frame. */ if (current_function_profile) - save_regs[1] = 1; + frame_pointer_needed = 1; /* If we are producing debug information, store r1 and r30 where the debugger wants to find them (r30 at r30+0, r1 at r30+4). Space has @@ -1856,15 +1854,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. */ @@ -1951,35 +1945,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 - || variable_args_p) - 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; -} static void m88k_output_function_prologue (stream, size) @@ -2025,15 +1990,8 @@ 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 (warn_stack_larger_than && m88k_stack_size > stack_larger_than_size) + warning ("stack usage is %d bytes", m88k_stack_size); if (m88k_stack_size) { @@ -2131,7 +2089,6 @@ m88k_output_function_epilogue (stream, size) m88k_function_number++; m88k_prologue_done = 0; /* don't put out ln directives */ - variable_args_p = 0; /* has variable args */ frame_laid_out = 0; epilogue_marked = 0; prologue_marked = 0; @@ -2467,11 +2424,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); @@ -2505,11 +2462,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]); } } @@ -2551,8 +2508,7 @@ m88k_function_arg (args_so_far, mode, type, named) { int bytes, words; - if (type != 0 /* undo putting struct in register */ - && (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE)) + if (type != 0 && AGGREGATE_TYPE_P (type)) /* undo putting struct in register */ mode = BLKmode; if ((args_so_far & 1) != 0 @@ -2581,6 +2537,37 @@ m88k_function_arg (args_so_far, mode, type, named) return gen_rtx_REG (((mode == BLKmode) ? TYPE_MODE (type) : mode), 2 + args_so_far); } + +/* Update the summarizer variable CUM to advance past an argument in + the argument list. The values MODE, TYPE and NAMED describe that + argument. Once this is done, the variable CUM is suitable for + analyzing the *following* argument with `FUNCTION_ARG', etc. (TYPE + is null for libcalls where that information may not be available.) */ +void +m88k_function_arg_advance (args_so_far, mode, type, named) + CUMULATIVE_ARGS *args_so_far; + enum machine_mode mode; + tree type; + int named; +{ + int bytes, words; + + if ((type != 0) && AGGREGATE_TYPE_P (type)) + mode = BLKmode; + + /* Align arguments requiring more than word alignment to a double-word + boundary (or an even register number if the argument will get passed + in registers). */ + if ((*args_so_far & 1) != 0 + && (mode == DImode || mode == DFmode + || (type != 0 && TYPE_ALIGN (type) > BITS_PER_WORD))) + (*args_so_far)++; + + bytes = (mode != BLKmode) ? GET_MODE_SIZE (mode) : int_size_in_bytes (type); + words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD; + + (*args_so_far) += words; +} /* Do what is necessary for `va_start'. We look at the current function to determine if stdargs or varargs is used and spill as necessary. @@ -2597,8 +2584,6 @@ m88k_builtin_saveregs () ? -UNITS_PER_WORD : 0) + UNITS_PER_WORD - 1; int fixed; - variable_args_p = 1; - fixed = 0; if (GET_CODE (current_function_arg_offset_rtx) == CONST_INT) fixed = ((INTVAL (current_function_arg_offset_rtx) + argadj) diff --git a/gnu/usr.bin/gcc/gcc/config/m88k/m88k.h b/gnu/usr.bin/gcc/gcc/config/m88k/m88k.h index ec49987f556..49cf723f9fa 100644 --- a/gnu/usr.bin/gcc/gcc/config/m88k/m88k.h +++ b/gnu/usr.bin/gcc/gcc/config/m88k/m88k.h @@ -873,7 +873,7 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS, This space can either be allocated by the caller or be a part of the machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says which. */ -#define REG_PARM_STACK_SPACE(FNDECL) 32 +/* #undef REG_PARM_STACK_SPACE(FNDECL) */ /* Define this macro if REG_PARM_STACK_SPACE is defined but stack parameters don't skip the area specified by REG_PARM_STACK_SPACE. @@ -881,7 +881,7 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS, the stack beyond the REG_PARM_STACK_SPACE area. Defining this macro suppresses this behavior and causes the parameter to be passed on the stack in its natural location. */ -#define STACK_PARMS_IN_REG_PARM_AREA +/* #undef STACK_PARMS_IN_REG_PARM_AREA */ /* Define this if it is the responsibility of the caller to allocate the area reserved for arguments passed in registers. If @@ -967,23 +967,10 @@ enum reg_class { NO_REGS, AP_REG, XRF_REGS, GENERAL_REGS, AGRF_REGS, function whose data type is FNTYPE. For a library call, FNTYPE is 0. */ #define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) ((CUM) = 0) -/* A C statement (sans semicolon) to update the summarizer variable - CUM to advance past an argument in the argument list. The values - MODE, TYPE and NAMED describe that argument. Once this is done, - the variable CUM is suitable for analyzing the *following* argument - with `FUNCTION_ARG', etc. (TYPE is null for libcalls where that - information may not be available.) */ -#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ - do { \ - enum machine_mode __mode = (TYPE) ? TYPE_MODE (TYPE) : (MODE); \ - if ((CUM & 1) \ - && (__mode == DImode || __mode == DFmode \ - || ((TYPE) && TYPE_ALIGN (TYPE) > BITS_PER_WORD))) \ - CUM++; \ - CUM += (((__mode != BLKmode) \ - ? GET_MODE_SIZE (MODE) : int_size_in_bytes (TYPE)) \ - + 3) / 4; \ - } while (0) +/* Update the summarizer variable to advance past an argument in an + argument list. See m88k.c. */ +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \ + m88k_function_arg_advance (& (CUM), MODE, TYPE, NAMED) /* True if N is a possible register number for function argument passing. On the m88000, these are registers 2 through 9. */ diff --git a/gnu/usr.bin/gcc/gcc/config/m88k/openbsd.h b/gnu/usr.bin/gcc/gcc/config/m88k/openbsd.h index 54f3bec168f..94a560dd097 100644 --- a/gnu/usr.bin/gcc/gcc/config/m88k/openbsd.h +++ b/gnu/usr.bin/gcc/gcc/config/m88k/openbsd.h @@ -93,7 +93,7 @@ Boston, MA 02111-1307, USA. */ extern void __dcache_sync(int, int); \ void \ __dcache_sync (addr, len) \ - int addr, len; \ + int addr ATTRIBUTE_UNUSED, len ATTRIBUTE_UNUSED; \ { \ /* r2 and r3 are set by the caller and need not be modified */ \ __asm __volatile ("tb0 0, r0, 451"); \ |