From 2e6c96419d34a2921e746e14facbb403e2cf06ee Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 26 Aug 2004 17:20:20 +0000 Subject: [PATCH] Fixed several -mcpu=G5 and 'long double' issues for apple-ppc-darwin. OK'ed by David Edehlson. From-SVN: r86629 --- gcc/ChangeLog | 24 ++++++++++++++++++++++++ gcc/config/rs6000/rs6000.c | 34 +++++++++++++++++++++++++++++----- gcc/config/rs6000/rs6000.h | 2 +- gcc/config/rs6000/rs6000.md | 16 ++++++++++------ 4 files changed, 64 insertions(+), 12 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e6ca31f22bb..96bfe42a4f0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,27 @@ +2004-08-26 Fariborz Jahanian + + * config/rs6000/rs6000.h (HARD_REGNO_CALL_PART_CLOBBERED): Added + TFmode as additional register mode cloberred by call. + +2004-08-26 Fariborz Jahanian + + * config/rs6000/rs6000.c (rs6000_libcall_value): Generate + parallel pattern for library call returning DImode in + mixed mode. + +2004-08-26 Fariborz Jahanian + + * config/rs6000/rs6000.c (function_arg): Generate parallel + pattern for more split args. + +2004-08-26 Fariborz Jahanian + + * config/rs6000/rs6000.c (rs6000_split_multireg_move): Call + either gen_movdi_di_update or gen_movdi_si_update depending on + target mode. + * config/rs6000/rs6000.md (movdi_update): Changed to movdi__update, + to generate two versions. + 2004-08-26 Daniel Berlin * Makefile.in (lambda-code.o): New. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 745b4759d3b..49fe3bac77f 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -5120,11 +5120,19 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, include the portion actually in registers here. */ enum machine_mode rmode = TARGET_32BIT ? SImode : DImode; rtx off; + int i=0; + if (align_words + n_words > GP_ARG_NUM_REG + && (TARGET_32BIT && TARGET_POWERPC64)) + /* Not all of the arg fits in gprs. Say that it goes in memory too, + using a magic NULL_RTX component. Also see comment in + rs6000_mixed_function_arg for why the normal + function_arg_partial_nregs scheme doesn't work in this case. */ + rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, NULL_RTX, const0_rtx); do { r = gen_rtx_REG (rmode, GP_ARG_MIN_REG + align_words); - off = GEN_INT (k * GET_MODE_SIZE (rmode)); + off = GEN_INT (i++ * GET_MODE_SIZE (rmode)); rvec[k++] = gen_rtx_EXPR_LIST (VOIDmode, r, off); } while (++align_words < GP_ARG_NUM_REG && --n_words != 0); @@ -11383,9 +11391,11 @@ rs6000_split_multireg_move (rtx dst, rtx src) if (TARGET_UPDATE) { rtx nsrc = simplify_gen_subreg (reg_mode, src, mode, 0); - emit_insn (TARGET_32BIT - ? gen_movsi_update (breg, breg, delta_rtx, nsrc) - : gen_movdi_update (breg, breg, delta_rtx, nsrc)); + emit_insn (TARGET_32BIT + ? (TARGET_POWERPC64 + ? gen_movdi_si_update (breg, breg, delta_rtx, nsrc) + : gen_movsi_update (breg, breg, delta_rtx, nsrc)) + : gen_movdi_di_update (breg, breg, delta_rtx, nsrc)); used_update = true; } else @@ -12583,7 +12593,7 @@ rs6000_emit_allocate_stack (HOST_WIDE_INT size, int copy_r12) insn = emit_insn (TARGET_32BIT ? gen_movsi_update (stack_reg, stack_reg, todec, stack_reg) - : gen_movdi_update (stack_reg, stack_reg, + : gen_movdi_di_update (stack_reg, stack_reg, todec, stack_reg)); } else @@ -17520,6 +17530,20 @@ rs6000_libcall_value (enum machine_mode mode) { unsigned int regno; + if (TARGET_32BIT && TARGET_POWERPC64 && mode == 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 (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_HARD_FLOAT && TARGET_FPRS) regno = FP_ARG_RETURN; diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index f1bf91b5eb0..801d54fd93f 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -1016,7 +1016,7 @@ extern const char *rs6000_warn_altivec_long_switch; #define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \ ((TARGET_32BIT && TARGET_POWERPC64 \ - && (MODE == DImode || MODE == DFmode) \ + && (GET_MODE_SIZE (MODE) > 4) \ && INT_REGNO_P (REGNO)) ? 1 : 0) #define ALTIVEC_VECTOR_MODE(MODE) \ diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 149adf7e0e7..819e8a3d8e6 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -104,6 +104,10 @@ (include "darwin.md") +;; This mode macro allows :P to be used for patterns that operate on +;; pointer-sized quantities. Exactly one of the two alternatives will match. +(define_mode_macro P [(SI "Pmode == SImode") (DI "Pmode == DImode")]) + ;; Start with fixed-point load and store insns. Here we put only the more ;; complex forms. Basic data transfer is done later. @@ -9483,12 +9487,12 @@ ldu %3,%2(%0)" [(set_attr "type" "load_ux,load_u")]) -(define_insn "movdi_update" - [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") - (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))) +(define_insn "movdi__update" + [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") + (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) (match_operand:DI 3 "gpc_reg_operand" "r,r")) - (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") - (plus:DI (match_dup 1) (match_dup 2)))] + (set (match_operand:P 0 "gpc_reg_operand" "=b,b") + (plus:P (match_dup 1) (match_dup 2)))] "TARGET_POWERPC64 && TARGET_UPDATE" "@ stdux %3,%0,%2 @@ -9956,7 +9960,7 @@ neg_op0 = GEN_INT (- INTVAL (operands[1])); if (TARGET_UPDATE) - emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update : gen_movdi_update)) + emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update : gen_movdi_di_update)) (stack_pointer_rtx, stack_pointer_rtx, neg_op0, chain)); else -- 2.30.2