This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PowerPC 32/64 mode incremental step
- From: David Edelsohn <dje at watson dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 31 Oct 2003 10:53:14 -0500
- Subject: PowerPC 32/64 mode incremental step
This patch deals with most of the target-specific argument passing
changes to support the 64-bit computation / 32-bit ABI mode.
David
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.
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.537
diff -c -p -r1.537 rs6000.c
*** rs6000.c 30 Oct 2003 02:02:45 -0000 1.537
--- rs6000.c 30 Oct 2003 20:59:36 -0000
*************** static int rs6000_get_some_local_dynamic
*** 347,352 ****
--- 347,354 ----
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);
*************** rs6000_emit_set_long_const (rtx dest, HO
*** 3211,3217 ****
|| (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
{
if (ud1 & 0x8000)
! emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
else
emit_move_insn (dest, GEN_INT (ud1));
}
--- 3213,3219 ----
|| (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000)))
{
if (ud1 & 0x8000)
! emit_move_insn (dest, GEN_INT (((ud1 ^ 0x8000) - 0x8000)));
else
emit_move_insn (dest, GEN_INT (ud1));
}
*************** function_arg_advance (CUMULATIVE_ARGS *c
*** 3894,3899 ****
--- 3896,3902 ----
}
/* 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)
*************** rs6000_spe_function_arg (CUMULATIVE_ARGS
*** 3919,3933 ****
return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
}
else
! return NULL;
}
else
{
if (cum->sysv_gregno <= GP_ARG_MAX_REG)
return gen_rtx_REG (mode, cum->sysv_gregno);
else
! return NULL;
}
}
/* Determine where to put an argument to a function.
--- 3922,4040 ----
return gen_rtx_PARALLEL (mode, gen_rtvec (2, r1, r2));
}
else
! return NULL_RTX;
}
else
{
if (cum->sysv_gregno <= GP_ARG_MAX_REG)
return gen_rtx_REG (mode, cum->sysv_gregno);
else
! 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.
*************** function_arg (CUMULATIVE_ARGS *cum, enum
*** 4029,4035 ****
if (cum->fregno <= FP_ARG_V4_MAX_REG)
return gen_rtx_REG (mode, cum->fregno);
else
! return NULL;
}
else
{
--- 4136,4142 ----
if (cum->fregno <= FP_ARG_V4_MAX_REG)
return gen_rtx_REG (mode, cum->fregno);
else
! return NULL_RTX;
}
else
{
*************** function_arg (CUMULATIVE_ARGS *cum, enum
*** 4051,4057 ****
if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
return gen_rtx_REG (mode, gregno);
else
! return NULL;
}
}
else
--- 4158,4164 ----
if (gregno + n_words - 1 <= GP_ARG_MAX_REG)
return gen_rtx_REG (mode, gregno);
else
! return NULL_RTX;
}
}
else
*************** function_arg (CUMULATIVE_ARGS *cum, enum
*** 4063,4068 ****
--- 4170,4179 ----
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
*************** function_arg (CUMULATIVE_ARGS *cum, enum
*** 4075,4127 ****
|| (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,
--- 4186,4191 ----
*************** function_arg (CUMULATIVE_ARGS *cum, enum
*** 4142,4178 ****
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
--- 4206,4211 ----
*************** rs6000_emit_prologue (void)
*** 11365,11371 ****
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 insn;
int saving_FPRs_inline;
int using_store_multiple;
--- 11398,11404 ----
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;
rtx insn;
int saving_FPRs_inline;
int using_store_multiple;
*************** rs6000_function_value (tree valtype, tre
*** 15456,15462 ****
if ((INTEGRAL_TYPE_P (valtype)
&& TYPE_PRECISION (valtype) < BITS_PER_WORD)
|| POINTER_TYPE_P (valtype))
! mode = word_mode;
else
mode = TYPE_MODE (valtype);
--- 15489,15495 ----
if ((INTEGRAL_TYPE_P (valtype)
&& TYPE_PRECISION (valtype) < BITS_PER_WORD)
|| POINTER_TYPE_P (valtype))
! mode = TARGET_32BIT ? SImode : DImode;
else
mode = TYPE_MODE (valtype);
Index: rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.294
diff -c -p -r1.294 rs6000.h
*** rs6000.h 30 Oct 2003 02:02:45 -0000 1.294
--- rs6000.h 30 Oct 2003 20:59:36 -0000
*************** extern enum rs6000_nop_insertion rs6000_
*** 604,610 ****
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
! (MODE) = word_mode;
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */
--- 604,610 ----
#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
if (GET_MODE_CLASS (MODE) == MODE_INT \
&& GET_MODE_SIZE (MODE) < UNITS_PER_WORD) \
! (MODE) = TARGET_32BIT ? SImode : DImode;
/* Define this if most significant bit is lowest numbered
in instructions that operate on numbered bit-fields. */