diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2003-10-23 14:36:23 +0000 |
---|---|---|
committer | David Edelsohn <dje@gcc.gnu.org> | 2003-10-23 10:36:23 -0400 |
commit | 0e67400ab4f95d41decb49c32975f49ceb1e9f8b (patch) | |
tree | b061ab2a9bc4d3558edd1a6da9e70b7a05c3a4cc /gcc | |
parent | 00503146990fe82f1a2fcb4ee5daee776b27e882 (diff) | |
download | gcc-0e67400ab4f95d41decb49c32975f49ceb1e9f8b.zip gcc-0e67400ab4f95d41decb49c32975f49ceb1e9f8b.tar.gz gcc-0e67400ab4f95d41decb49c32975f49ceb1e9f8b.tar.bz2 |
rs6000.h (UNITS_PER_WORD): Use TARGET_32BIT, not TARGET_POWREPC64.
* config/rs6000/rs6000.h (UNITS_PER_WORD): Use TARGET_32BIT, not
TARGET_POWREPC64.
(UNITS_PER_GPR_WORD): Define.
(HARD_REGNO_NREGS): Use UNITS_PER_GPR_WORD.
(HARD_REGNO_CALL_PART_CLOBBERED): Define.
(HARD_REGNO_MODE_OK): Use UNITS_PER_GPR_WORD.
(CLASS_MAX_NREGS): Use UNITS_PER_GPR_WORD.
* config/rs6000/rs6000.c (function_arg): Generate PARALLEL for
DFmode and DImode in 32-bit ABI / 64-bit computation mode.
(rs6000_emit_prologue): Select reg_mode and reg_size using
TARGET_32BIT, not TARGET_POWERPC64.
(rs6000_function_value): Generate PARALLEL for DImode in 32-bit
ABI / 64-bit computation mode
Co-Authored-By: David Edelsohn <edelsohn@gnu.org>
From-SVN: r72851
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 100 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.h | 15 |
3 files changed, 124 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0123b86..b1132f9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2003-10-23 Fariborz Jahanian <fjahanian@apple.com> + David Edelsohn <edelsohn@gnu.org> + + * config/rs6000/rs6000.h (UNITS_PER_WORD): Use TARGET_32BIT, not + TARGET_POWREPC64. + (UNITS_PER_GPR_WORD): Define. + (HARD_REGNO_NREGS): Use UNITS_PER_GPR_WORD. + (HARD_REGNO_CALL_PART_CLOBBERED): Define. + (HARD_REGNO_MODE_OK): Use UNITS_PER_GPR_WORD. + (CLASS_MAX_NREGS): Use UNITS_PER_GPR_WORD. + * config/rs6000/rs6000.c (function_arg): Generate PARALLEL for + DFmode and DImode in 32-bit ABI / 64-bit computation mode. + (rs6000_emit_prologue): Select reg_mode and reg_size using + TARGET_32BIT, not TARGET_POWERPC64. + (rs6000_function_value): Generate PARALLEL for DImode in 32-bit + ABI / 64-bit computation mode + 2003-10-22 Andrew Haley <aph@redhat.com> * toplev.c (output_file_directive): Allow for null input_name. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 1680775..2387ea7 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -4071,6 +4071,53 @@ 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, @@ -4091,6 +4138,37 @@ 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 @@ -11278,8 +11356,8 @@ void rs6000_emit_prologue (void) { rs6000_stack_t *info = rs6000_stack_info (); - enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode; - int reg_size = TARGET_POWERPC64 ? 8 : 4; + enum machine_mode reg_mode = Pmode; + int reg_size = UNITS_PER_WORD; 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; @@ -11744,8 +11822,8 @@ rs6000_emit_epilogue (int sibcall) int sp_offset = 0; rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1); rtx frame_reg_rtx = sp_reg_rtx; - enum machine_mode reg_mode = TARGET_POWERPC64 ? DImode : SImode; - int reg_size = TARGET_POWERPC64 ? 8 : 4; + enum machine_mode reg_mode = Pmode; + int reg_size = UNITS_PER_WORD; int i; info = rs6000_stack_info (); @@ -15357,6 +15435,20 @@ rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED) enum machine_mode mode; unsigned int regno; + if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DImode) + { + /* Long long return value need be split in -mpowerpc64, 32bit ABI. */ + return gen_rtx_PARALLEL (DImode, + gen_rtvec (2, + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (SImode, GP_ARG_RETURN), + const0_rtx), + gen_rtx_EXPR_LIST (VOIDmode, + gen_rtx_REG (SImode, + GP_ARG_RETURN + 1), + GEN_INT (4)))); + } + if ((INTEGRAL_TYPE_P (valtype) && TYPE_PRECISION (valtype) < BITS_PER_WORD) || POINTER_TYPE_P (valtype)) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 8ab42b1..3665b0a 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -625,7 +625,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; #define MAX_BITS_PER_WORD 64 /* Width of a word, in units (bytes). */ -#define UNITS_PER_WORD (! TARGET_POWERPC64 ? 4 : 8) +#define UNITS_PER_WORD (TARGET_32BIT ? 4 : 8) #ifdef IN_LIBGCC2 #define MIN_UNITS_PER_WORD UNITS_PER_WORD #else @@ -988,6 +988,8 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; POWER and PowerPC GPRs hold 32 bits worth; PowerPC64 GPRs and FPRs point register holds 64 bits worth. */ +#define UNITS_PER_GPR_WORD (! TARGET_POWERPC64 ? 4 : 8) + #define HARD_REGNO_NREGS(REGNO, MODE) \ (FP_REGNO_P (REGNO) \ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \ @@ -995,7 +997,12 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; ? ((GET_MODE_SIZE (MODE) + UNITS_PER_SPE_WORD - 1) / UNITS_PER_SPE_WORD) \ : ALTIVEC_REGNO_P (REGNO) \ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_ALTIVEC_WORD - 1) / UNITS_PER_ALTIVEC_WORD) \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) + : ((GET_MODE_SIZE (MODE) + UNITS_PER_GPR_WORD - 1) / UNITS_PER_GPR_WORD)) + +#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ + ((TARGET_32BIT && TARGET_POWERPC64 \ + && (MODE == DImode || MODE == DFmode) \ + && INT_REGNO_P (REGNO)) ? 1 : 0) #define ALTIVEC_VECTOR_MODE(MODE) \ ((MODE) == V16QImode \ @@ -1035,7 +1042,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; : SPE_SIMD_REGNO_P (REGNO) && TARGET_SPE && SPE_VECTOR_MODE (MODE) ? 1 \ : CR_REGNO_P (REGNO) ? GET_MODE_CLASS (MODE) == MODE_CC \ : XER_REGNO_P (REGNO) ? (MODE) == PSImode \ - : GET_MODE_SIZE (MODE) <= UNITS_PER_WORD) + : GET_MODE_SIZE (MODE) <= UNITS_PER_GPR_WORD) /* Value is 1 if it is a good idea to tie two pseudo registers when one has mode MODE1 and one has mode MODE2. @@ -1458,7 +1465,7 @@ enum reg_class #define CLASS_MAX_NREGS(CLASS, MODE) \ (((CLASS) == FLOAT_REGS) \ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \ - : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) + : ((GET_MODE_SIZE (MODE) + UNITS_PER_GPR_WORD - 1) / UNITS_PER_GPR_WORD)) /* Return a class of registers that cannot change FROM mode to TO mode. */ |