aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2003-10-31 15:50:49 +0000
committerDavid Edelsohn <dje@gcc.gnu.org>2003-10-31 10:50:49 -0500
commitb78d48ddc2033b298e199c970e6fb465e288a317 (patch)
tree4710c3c4ee9d5e8de576ca6d8fdee3ea1ec01806 /gcc
parent3dc5f34a79fcc27557f1dcb0c142f487c009fe23 (diff)
downloadgcc-b78d48ddc2033b298e199c970e6fb465e288a317.zip
gcc-b78d48ddc2033b298e199c970e6fb465e288a317.tar.gz
gcc-b78d48ddc2033b298e199c970e6fb465e288a317.tar.bz2
rs6000.c (rs6000_mixed_function_arg): New.
2003-10-31 Fariborz Jahanian <fjahanian@apple.com> David Edelsohn <edelsohn@gnu.org> * 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. Co-Authored-By: David Edelsohn <edelsohn@gnu.org> From-SVN: r73151
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/rs6000/rs6000.c203
-rw-r--r--gcc/config/rs6000/rs6000.h2
3 files changed, 128 insertions, 86 deletions
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 <fjahanian@apple.com>
+ David Edelsohn <edelsohn@gnu.org>
+
+ * 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 <gerald@pfeifer.com>
* .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 d2c31099..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. */