From: dje Date: Fri, 31 Oct 2003 15:50:49 +0000 (+0000) Subject: 2003-10-31 Fariborz Jahanian X-Git-Tag: upstream/4.9.2~75590 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4cccb4b2698770064c64e872b5d62f34de31da57;p=platform%2Fupstream%2Flinaro-gcc.git 2003-10-31 Fariborz Jahanian David Edelsohn * config/rs6000/rs6000.c (rs6000_mixed_function_arg): New. (function_arg): Call it. (rs6000_function_value): Widen integral return value to mode based on TARGET_32BIT, not word_mode. * config/rs6000/rs6000.h (PROMOTE_MODE): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@73151 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 663f879..4b06022 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2003-10-31 Fariborz Jahanian + David Edelsohn + + * config/rs6000/rs6000.c (rs6000_mixed_function_arg): New. + (function_arg): Call it. + (rs6000_function_value): Widen integral return value to mode based + on TARGET_32BIT, not word_mode. + * config/rs6000/rs6000.h (PROMOTE_MODE): Likewise. + 2003-10-31 Gerald Pfeifer * .cvsignore: No longer ignore gengtype-lex.c, gengtype-yacc.c, diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 9452701..4297314 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -347,6 +347,8 @@ static int rs6000_get_some_local_dynamic_name_1 (rtx *, void *); static rtx rs6000_complex_function_value (enum machine_mode); static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *, enum machine_mode, tree); +static rtx rs6000_mixed_function_arg (CUMULATIVE_ARGS *, + enum machine_mode, tree, int); static void setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode, tree, int *, int); @@ -3211,7 +3213,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c1, HOST_WIDE_INT c2) || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000))) { if (ud1 & 0x8000) - emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000))); + emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000))); else emit_move_insn (dest, GEN_INT (ud1)); } @@ -3894,6 +3896,7 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, } /* Determine where to put a SIMD argument on the SPE. */ + static rtx rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type) @@ -3919,17 +3922,121 @@ rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2)); } else - return NULL; + return NULL_RTX; } else { if (cum->sysv_gregno <= GP_ARG_MAX_REG) return gen_rtx_REG (mode, cum->sysv_gregno); else - return NULL; + return NULL_RTX; } } +/* Determine where to place an argument in 64-bit mode with 32-bit ABI. */ + +static rtx +rs6000_mixed_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, + tree type, int align_words) +{ + if (mode == DFmode) + { + /* -mpowerpc64 with 32bit ABI splits up a DFmode argument + in vararg list into zero, one or two GPRs */ + if (align_words >= GP_ARG_NUM_REG) + return gen_rtx_PARALLEL (DFmode, + gen_rtvec (2, + gen_rtx_EXPR_LIST (VOIDmode, + NULL_RTX, const0_rtx), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (mode, + cum->fregno), + const0_rtx))); + else if (align_words + RS6000_ARG_SIZE (mode, type) + > GP_ARG_NUM_REG) + /* If this is partially on the stack, then we only + include the portion actually in registers here. */ + return gen_rtx_PARALLEL (DFmode, + gen_rtvec (2, + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (SImode, + GP_ARG_MIN_REG + + align_words), + const0_rtx), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (mode, + cum->fregno), + const0_rtx))); + + /* split a DFmode arg into two GPRs */ + return gen_rtx_PARALLEL (DFmode, + gen_rtvec (3, + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (SImode, + GP_ARG_MIN_REG + + align_words), + const0_rtx), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (SImode, + GP_ARG_MIN_REG + + align_words + 1), + GEN_INT (4)), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (mode, cum->fregno), + const0_rtx))); + } + /* -mpowerpc64 with 32bit ABI splits up a DImode argument into one + or two GPRs */ + else if (mode == DImode) + { + if (align_words < GP_ARG_NUM_REG - 1) + return gen_rtx_PARALLEL (DImode, + gen_rtvec (2, + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (SImode, + GP_ARG_MIN_REG + + align_words), + const0_rtx), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (SImode, + GP_ARG_MIN_REG + + align_words + 1), + GEN_INT (4)))); + else if (align_words == GP_ARG_NUM_REG - 1) + return gen_rtx_PARALLEL (DImode, + gen_rtvec (2, + gen_rtx_EXPR_LIST (VOIDmode, + NULL_RTX, const0_rtx), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (SImode, + GP_ARG_MIN_REG + + align_words), + const0_rtx))); + } + else if (mode == BLKmode && align_words <= (GP_ARG_NUM_REG - 1)) + { + int k; + int size = int_size_in_bytes (type); + int no_units = size / 4; + int max_no_words = GP_ARG_NUM_REG - align_words; + int rtlvec_len = no_units < max_no_words ? no_units : max_no_words; + rtx *rtlvec = (rtx *) alloca (rtlvec_len * sizeof (rtx)); + + memset ((char *) rtlvec, 0, rtlvec_len * sizeof (rtx)); + + for (k=0; k < rtlvec_len; k++) + rtlvec[k] = gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (SImode, + GP_ARG_MIN_REG + + align_words + k), + k == 0 ? const0_rtx : GEN_INT (k*4)); + + return gen_rtx_PARALLEL (BLKmode, gen_rtvec_v (k, rtlvec)); + } + + return NULL_RTX; +} + /* Determine where to put an argument to a function. Value is zero to push the argument on the stack, or a hard register in which to store the argument. @@ -4029,7 +4136,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, if (cum->fregno <= FP_ARG_V4_MAX_REG) return gen_rtx_REG (mode, cum->fregno); else - return NULL; + return NULL_RTX; } else { @@ -4051,7 +4158,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, if (gregno + n_words - 1 <= GP_ARG_MAX_REG) return gen_rtx_REG (mode, gregno); else - return NULL; + return NULL_RTX; } } else @@ -4063,6 +4170,10 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, if (type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) return NULL_RTX; + if (TARGET_32BIT && TARGET_POWERPC64 + && (mode == DFmode || mode == DImode || mode == BLKmode)) + return rs6000_mixed_function_arg (cum, mode, type, align_words); + if (USE_FP_FOR_ARG_P (*cum, mode, type)) { if (! type @@ -4075,53 +4186,6 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, || (align_words < GP_ARG_NUM_REG)))) return gen_rtx_REG (mode, cum->fregno); - if (TARGET_32BIT && TARGET_POWERPC64 && mode == DFmode) - { - /* -mpowerpc64 with 32bit ABI splits up a DFmode argument - in vararg list into zero, one or two GPRs */ - if (align_words >= GP_ARG_NUM_REG) - return gen_rtx_PARALLEL (DFmode, - gen_rtvec (2, - gen_rtx_EXPR_LIST (VOIDmode, - NULL_RTX, const0_rtx), - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (mode, - cum->fregno), - const0_rtx))); - else if (align_words + RS6000_ARG_SIZE (mode, type) - > GP_ARG_NUM_REG) - /* If this is partially on the stack, then we only - include the portion actually in registers here. */ - return gen_rtx_PARALLEL (DFmode, - gen_rtvec (2, - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (SImode, - GP_ARG_MIN_REG - + align_words), - const0_rtx), - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (mode, - cum->fregno), - const0_rtx))); - - /* split a DFmode arg into two GPRs */ - return gen_rtx_PARALLEL (DFmode, - gen_rtvec (3, - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (SImode, - GP_ARG_MIN_REG - + align_words), - const0_rtx), - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (SImode, - GP_ARG_MIN_REG - + align_words + 1), - GEN_INT (4)), - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (mode, cum->fregno), - const0_rtx))); - } - return gen_rtx_PARALLEL (mode, gen_rtvec (2, gen_rtx_EXPR_LIST (VOIDmode, @@ -4142,37 +4206,6 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, gen_rtx_REG (mode, cum->fregno), const0_rtx))); } - /* -mpowerpc64 with 32bit ABI splits up a DImode argument into one - or two GPRs */ - else if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode - && align_words < GP_ARG_NUM_REG - 1) - { - return gen_rtx_PARALLEL (DImode, - gen_rtvec (2, - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (SImode, - GP_ARG_MIN_REG - + align_words), - const0_rtx), - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (SImode, - GP_ARG_MIN_REG - + align_words + 1), - GEN_INT (4)))); - } - else if (TARGET_32BIT && TARGET_POWERPC64 && mode == DImode - && align_words == GP_ARG_NUM_REG - 1) - { - return gen_rtx_PARALLEL (DImode, - gen_rtvec (2, - gen_rtx_EXPR_LIST (VOIDmode, - NULL_RTX, const0_rtx), - gen_rtx_EXPR_LIST (VOIDmode, - gen_rtx_REG (SImode, - GP_ARG_MIN_REG - + align_words), - const0_rtx))); - } else if (align_words < GP_ARG_NUM_REG) return gen_rtx_REG (mode, GP_ARG_MIN_REG + align_words); else @@ -11365,7 +11398,7 @@ rs6000_emit_prologue (void) rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12); rtx frame_reg_rtx = sp_reg_rtx; - rtx cr_save_rtx = NULL; + rtx cr_save_rtx = NULL_RTX; rtx insn; int saving_FPRs_inline; int using_store_multiple; @@ -15456,7 +15489,7 @@ rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED) if ((INTEGRAL_TYPE_P (valtype) && TYPE_PRECISION (valtype) < BITS_PER_WORD) || POINTER_TYPE_P (valtype)) - mode = word_mode; + mode = TARGET_32BIT ? SImode : DImode; else mode = TYPE_MODE (valtype); diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index d2c3109..e36c6c1 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -604,7 +604,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; #define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \ if (GET_MODE_CLASS (MODE) == MODE_INT \ && GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \ - (MODE) = word_mode; + (MODE) = TARGET_32BIT ? SImode : DImode; /* Define this if most significant bit is lowest numbered in instructions that operate on numbered bit-fields. */