From c2749e2df1fc0b9975377b80d1d817d1475f0d15 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 26 Jul 1999 22:53:14 -0700 Subject: [PATCH] i960.c (i960_setup_incoming_varargs): Use get_varargs_alias_set for the register spill block. * i960.c (i960_setup_incoming_varargs): Use get_varargs_alias_set for the register spill block. (i960_build_va_list): New. (i960_va_start): New. (i960_va_arg): New. * i960.h (BUILD_VA_LIST_TYPE): New. (EXPAND_BUILTIN_VA_START): New. (EXPAND_BUILTIN_VA_ARG): New. * i960.md (store_multiple): Use change_address on individul mems. From-SVN: r28284 --- gcc/ChangeLog | 12 ++++++ gcc/config/i960/i960.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++- gcc/config/i960/i960.h | 15 +++++++- gcc/config/i960/i960.md | 16 +++----- 4 files changed, 127 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 48610c3..16dfcbe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +Mon Jul 26 22:52:47 1999 Richard Henderson + + * i960.c (i960_setup_incoming_varargs): Use get_varargs_alias_set + for the register spill block. + (i960_build_va_list): New. + (i960_va_start): New. + (i960_va_arg): New. + * i960.h (BUILD_VA_LIST_TYPE): New. + (EXPAND_BUILTIN_VA_START): New. + (EXPAND_BUILTIN_VA_ARG): New. + * i960.md (store_multiple): Use change_address on individul mems. + Mon Jul 26 22:43:12 1999 Richard Henderson * builtins.c (stabilize_va_list): Don't INDIRECT_REF through diff --git a/gcc/config/i960/i960.c b/gcc/config/i960/i960.c index 45632cf..7a661e6 100644 --- a/gcc/config/i960/i960.c +++ b/gcc/config/i960/i960.c @@ -1,5 +1,6 @@ /* Subroutines used for code generation on intel 80960. - Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 Free Software Foundation, Inc. + Copyright (C) 1992, 1995, 1996, 1997, 1998, 1999 + Free Software Foundation, Inc. Contributed by Steven McGeady, Intel Corp. Additional Work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson Converted to GCC 2.0 by Jim Wilson and Michael Tiemann, Cygnus Support. @@ -2623,16 +2624,108 @@ i960_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl) emit_label (label); /* ??? Note that we unnecessarily store one extra register for stdarg - fns. We could optimize this, but it's kept as for now. */ + fns. We could optimize this, but it's kept as-is for now. */ regblock = gen_rtx (MEM, BLKmode, plus_constant (arg_pointer_rtx, first_reg * 4)); + MEM_ALIAS_SET (regblock) = get_varargs_alias_set (); move_block_from_reg (first_reg, regblock, NPARM_REGS - first_reg, (NPARM_REGS - first_reg) * UNITS_PER_WORD); } } +/* Define the `__builtin_va_list' type for the ABI. */ + +tree +i960_build_va_list () +{ + return build_array_type (unsigned_type_node, + build_index_type (size_one_node)); +} + +/* Implement `va_start' for varargs and stdarg. */ + +void +i960_va_start (stdarg_p, valist, nextarg) + int stdarg_p ATTRIBUTE_UNUSED; + tree valist; + rtx nextarg ATTRIBUTE_UNUSED; +{ + tree d, s, t; + + s = make_tree (unsigned_type_node, arg_pointer_rtx); + d = build (ARRAY_REF, unsigned_type_node, valist, size_zero_node); + t = build (MODIFY_EXPR, unsigned_type_node, d, s); + TREE_SIDE_EFFECTS (t) = 1; + expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); + + s = build_int_2 ((current_function_args_info.ca_nregparms + + current_function_args_info.ca_nstackparms) * 4, 0); + d = build (ARRAY_REF, unsigned_type_node, valist, size_one_node); + t = build (MODIFY_EXPR, unsigned_type_node, d, s); + TREE_SIDE_EFFECTS (t) = 1; + expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL); +} + +/* Implement `va_arg'. */ + +rtx +i960_va_arg (valist, type) + tree valist, type; +{ + HOST_WIDE_INT siz, ali; + tree base, num, pad, next, this, t1, t2, int48; + rtx addr_rtx; + + base = build (ARRAY_REF, unsigned_type_node, valist, size_zero_node); + num = build (ARRAY_REF, unsigned_type_node, valist, size_one_node); + + /* Round up sizeof(type) to a word. */ + siz = (int_size_in_bytes (type) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD; + + /* Round up alignment to a word. */ + ali = TYPE_ALIGN (type); + if (ali < BITS_PER_WORD) + ali = BITS_PER_WORD; + ali /= BITS_PER_UNIT; + + /* Align NUM appropriate for the argument. */ + pad = fold (build (PLUS_EXPR, unsigned_type_node, num, + build_int_2 (ali - 1, 0))); + pad = fold (build (BIT_AND_EXPR, unsigned_type_node, pad, + build_int_2 (-ali, -1))); + pad = save_expr (pad); + + /* Increment VPAD past this argument. */ + next = fold (build (PLUS_EXPR, unsigned_type_node, pad, + build_int_2 (siz, 0))); + next = save_expr (next); + + /* Find the offset for the current argument. Mind peculiar overflow + from registers to stack. */ + int48 = build_int_2 (48, 0); + if (siz > 16) + t2 = integer_one_node; + else + t2 = fold (build (GT_EXPR, integer_type_node, next, int48)); + t1 = fold (build (LE_EXPR, integer_type_node, num, int48)); + t1 = fold (build (TRUTH_AND_EXPR, integer_type_node, t1, t2)); + this = fold (build (COND_EXPR, unsigned_type_node, t1, int48, pad)); + + /* Find the address for the current argument. */ + t1 = fold (build (PLUS_EXPR, unsigned_type_node, base, this)); + t1 = build1 (NOP_EXPR, ptr_type_node, t1); + addr_rtx = expand_expr (t1, NULL_RTX, Pmode, EXPAND_NORMAL); + + /* Increment NUM. */ + t1 = build (MODIFY_EXPR, unsigned_type_node, num, next); + TREE_SIDE_EFFECTS (t1) = 1; + expand_expr (t1, const0_rtx, VOIDmode, EXPAND_NORMAL); + + return addr_rtx; +} + /* Calculate the final size of the reg parm stack space for the current function, based on how many bytes would be allocated on the stack. */ diff --git a/gcc/config/i960/i960.h b/gcc/config/i960/i960.h index fdf4199..357ccdc 100644 --- a/gcc/config/i960/i960.h +++ b/gcc/config/i960/i960.h @@ -1,5 +1,6 @@ /* Definitions of target machine for GNU compiler, for Intel 80960 - Copyright (C) 1992, 1993, 1995, 1996, 1998 Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1995, 1996, 1998, 1999 + Free Software Foundation, Inc. Contributed by Steven McGeady, Intel Corp. Additional Work by Glenn Colon-Bonet, Jonathan Shapiro, Andy Wilson Converted to GCC 2.0 by Jim Wilson and Michael Tiemann, Cygnus Support. @@ -859,6 +860,18 @@ enum reg_class { NO_REGS, GLOBAL_REGS, LOCAL_REGS, LOCAL_OR_GLOBAL_REGS, #define SETUP_INCOMING_VARARGS(CUM,MODE,TYPE,PRETEND_SIZE,NO_RTL) \ i960_setup_incoming_varargs(&CUM,MODE,TYPE,&PRETEND_SIZE,NO_RTL) + +/* Define the `__builtin_va_list' type for the ABI. */ +#define BUILD_VA_LIST_TYPE(VALIST) \ + (VALIST) = i960_build_va_list () + +/* Implement `va_start' for varargs and stdarg. */ +#define EXPAND_BUILTIN_VA_START(stdarg, valist, nextarg) \ + i960_va_start (stdarg, valist, nextarg) + +/* Implement `va_arg'. */ +#define EXPAND_BUILTIN_VA_ARG(valist, type) \ + i960_va_arg (valist, type) /* Define a data type for recording info about an argument list during the scan of that argument list. This data type should diff --git a/gcc/config/i960/i960.md b/gcc/config/i960/i960.md index 0574c57..945b514 100644 --- a/gcc/config/i960/i960.md +++ b/gcc/config/i960/i960.md @@ -972,7 +972,6 @@ int regno; int count; rtx from; - int i; if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != REG @@ -987,27 +986,24 @@ from = memory_address (SImode, XEXP (operands[0], 0)); while (count >= 4 && ((regno & 3) == 0)) { - emit_insn (gen_rtx (SET, VOIDmode, - gen_rtx (MEM, TImode, from), - gen_rtx (REG, TImode, regno))); + emit_move_insn (change_address (operands[0], TImode, from), + gen_rtx_REG (TImode, regno)); count -= 4; regno += 4; from = memory_address (TImode, plus_constant (from, 16)); } while (count >= 2 && ((regno & 1) == 0)) { - emit_insn (gen_rtx (SET, VOIDmode, - gen_rtx (MEM, DImode, from), - gen_rtx (REG, DImode, regno))); + emit_move_insn (change_address (operands[0], DImode, from), + gen_rtx_REG (DImode, regno)); count -= 2; regno += 2; from = memory_address (DImode, plus_constant (from, 8)); } while (count > 0) { - emit_insn (gen_rtx (SET, VOIDmode, - gen_rtx (MEM, SImode, from), - gen_rtx (REG, SImode, regno))); + emit_move_insn (change_address (operands[0], SImode, from), + gen_rtx_REG (SImode, regno)); count -= 1; regno += 1; from = memory_address (SImode, plus_constant (from, 4)); -- 2.7.4