From: jsm28 Date: Thu, 5 Jun 2008 23:03:11 +0000 (+0000) Subject: * config.gcc (powerpc-*-linux*spe*): Use t-dfprules. X-Git-Tag: upstream/4.9.2~41667 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bea66da55b33a5042ec416a2720a579270b60b4e;p=platform%2Fupstream%2Flinaro-gcc.git * config.gcc (powerpc-*-linux*spe*): Use t-dfprules. * config/rs6000/dfp.md (negdd2, absdd2, negtd2, abstd2): Do not enable for TARGET_E500_DOUBLE. (*movdd_softfloat32): Also enable for !TARGET_FPRS. * config/rs6000/rs6000.c (invalid_e500_subreg): Treat decimal floating-point modes like integer modes for E500 double. (rs6000_legitimate_offset_address_p): Likewise. (rs6000_legitimize_address): Likewise. Do not allow REG+REG addressing for DDmode for E500 double. (rs6000_hard_regno_nregs): Do not treat decimal floating-point modes as using 64-bits of registers for E500 double. (spe_build_register_parallel): Do not handle DDmode or TDmode. (rs6000_spe_function_arg): Do not handle DDmode or TDmode specially for E500 double. (function_arg): Do not call rs6000_spe_function_arg for DDmode or TDmode for E500 double. (rs6000_gimplify_va_arg): Only handle SDmode in registers specially if TARGET_HARD_FLOAT && TARGET_FPRS. (rs6000_split_multireg_move): Do not handle TDmode specially for E500 double. (spe_func_has_64bit_regs_p): Do not treat DDmode or TDmode as using 64-bit registers for E500 double. (emit_frame_save): Do not handle DDmode specially for E500 double. (gen_frame_mem_offset): Likewise. (rs6000_function_value): Do not call spe_build_register_parallel for DDmode or TDmode. (rs6000_libcall_value): Likewise. * config/rs6000/rs6000.h (LOCAL_ALIGNMENT, MEMBER_TYPE_FORCES_BLK, DATA_ALIGNMENT, CLASS_MAX_NREGS): Do not handle DDmode specially for E500 double. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@136416 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b10677e..3cb7ec5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,36 @@ +2008-06-05 Joseph Myers + + * config.gcc (powerpc-*-linux*spe*): Use t-dfprules. + * config/rs6000/dfp.md (negdd2, absdd2, negtd2, abstd2): Do not + enable for TARGET_E500_DOUBLE. + (*movdd_softfloat32): Also enable for !TARGET_FPRS. + * config/rs6000/rs6000.c (invalid_e500_subreg): Treat decimal + floating-point modes like integer modes for E500 double. + (rs6000_legitimate_offset_address_p): Likewise. + (rs6000_legitimize_address): Likewise. Do not allow REG+REG + addressing for DDmode for E500 double. + (rs6000_hard_regno_nregs): Do not treat decimal floating-point + modes as using 64-bits of registers for E500 double. + (spe_build_register_parallel): Do not handle DDmode or TDmode. + (rs6000_spe_function_arg): Do not handle DDmode or TDmode + specially for E500 double. + (function_arg): Do not call rs6000_spe_function_arg for DDmode or + TDmode for E500 double. + (rs6000_gimplify_va_arg): Only handle SDmode in registers + specially if TARGET_HARD_FLOAT && TARGET_FPRS. + (rs6000_split_multireg_move): Do not handle TDmode specially for + E500 double. + (spe_func_has_64bit_regs_p): Do not treat DDmode or TDmode as + using 64-bit registers for E500 double. + (emit_frame_save): Do not handle DDmode specially for E500 double. + (gen_frame_mem_offset): Likewise. + (rs6000_function_value): Do not call spe_build_register_parallel + for DDmode or TDmode. + (rs6000_libcall_value): Likewise. + * config/rs6000/rs6000.h (LOCAL_ALIGNMENT, MEMBER_TYPE_FORCES_BLK, + DATA_ALIGNMENT, CLASS_MAX_NREGS): Do not handle DDmode specially + for E500 double. + 2008-06-04 H.J. Lu * config/i386/i386.c (setup_incoming_varargs_64): Fix a typo diff --git a/gcc/config.gcc b/gcc/config.gcc index 8067287..399d80c 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -1989,7 +1989,7 @@ powerpc-*-linux*altivec*) powerpc-*-linux*spe*) tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/linuxspe.h rs6000/e500.h" extra_options="${extra_options} rs6000/sysv4.opt" - tmake_file="rs6000/t-fprules rs6000/t-fprules-softfp soft-fp/t-softfp rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm" + tmake_file="t-dfprules rs6000/t-fprules rs6000/t-fprules-softfp soft-fp/t-softfp rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm" ;; powerpc-*-linux*paired*) tm_file="${tm_file} dbxelf.h elfos.h svr4.h freebsd-spec.h rs6000/sysv4.h rs6000/linux.h rs6000/750cl.h" diff --git a/gcc/config/rs6000/dfp.md b/gcc/config/rs6000/dfp.md index 2d111b8..90eaa2a 100644 --- a/gcc/config/rs6000/dfp.md +++ b/gcc/config/rs6000/dfp.md @@ -155,7 +155,7 @@ (define_expand "negdd2" [(set (match_operand:DD 0 "gpc_reg_operand" "") (neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && TARGET_FPRS" "") (define_insn "*negdd2_fpr" @@ -168,7 +168,7 @@ (define_expand "absdd2" [(set (match_operand:DD 0 "gpc_reg_operand" "") (abs:DD (match_operand:DD 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && TARGET_FPRS" "") (define_insn "*absdd2_fpr" @@ -376,7 +376,7 @@ (define_insn "*movdd_softfloat32" [(set (match_operand:DD 0 "nonimmediate_operand" "=r,r,m,r,r,r") (match_operand:DD 1 "input_operand" "r,m,r,G,H,F"))] - "! TARGET_POWERPC64 && TARGET_SOFT_FLOAT + "! TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) && (gpc_reg_operand (operands[0], DDmode) || gpc_reg_operand (operands[1], DDmode))" "* @@ -486,7 +486,7 @@ (define_expand "negtd2" [(set (match_operand:TD 0 "gpc_reg_operand" "") (neg:TD (match_operand:TD 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && TARGET_FPRS" "") (define_insn "*negtd2_fpr" @@ -499,7 +499,7 @@ (define_expand "abstd2" [(set (match_operand:TD 0 "gpc_reg_operand" "") (abs:TD (match_operand:TD 1 "gpc_reg_operand" "")))] - "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)" + "TARGET_HARD_FLOAT && TARGET_FPRS" "") (define_insn "*abstd2_fpr" diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 1973476..8493e77 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -3199,24 +3199,26 @@ invalid_e500_subreg (rtx op, enum machine_mode mode) if (TARGET_E500_DOUBLE) { /* Reject (subreg:SI (reg:DF)); likewise with subreg:DI or - subreg:TI and reg:TF. */ + subreg:TI and reg:TF. Decimal float modes are like integer + modes (only low part of each register used) for this + purpose. */ if (GET_CODE (op) == SUBREG - && (mode == SImode || mode == DImode || mode == TImode) + && (mode == SImode || mode == DImode || mode == TImode + || mode == DDmode || mode == TDmode) && REG_P (SUBREG_REG (op)) && (GET_MODE (SUBREG_REG (op)) == DFmode - || GET_MODE (SUBREG_REG (op)) == TFmode - || GET_MODE (SUBREG_REG (op)) == DDmode - || GET_MODE (SUBREG_REG (op)) == TDmode)) + || GET_MODE (SUBREG_REG (op)) == TFmode)) return true; /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and reg:TI. */ if (GET_CODE (op) == SUBREG - && (mode == DFmode || mode == TFmode - || mode == DDmode || mode == TDmode) + && (mode == DFmode || mode == TFmode) && REG_P (SUBREG_REG (op)) && (GET_MODE (SUBREG_REG (op)) == DImode - || GET_MODE (SUBREG_REG (op)) == TImode)) + || GET_MODE (SUBREG_REG (op)) == TImode + || GET_MODE (SUBREG_REG (op)) == DDmode + || GET_MODE (SUBREG_REG (op)) == TDmode)) return true; } @@ -3467,10 +3469,10 @@ rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict) return SPE_CONST_OFFSET_OK (offset); case DFmode: - case DDmode: if (TARGET_E500_DOUBLE) return SPE_CONST_OFFSET_OK (offset); + case DDmode: case DImode: /* On e500v2, we may have: @@ -3487,11 +3489,11 @@ rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict) break; case TFmode: - case TDmode: if (TARGET_E500_DOUBLE) return (SPE_CONST_OFFSET_OK (offset) && SPE_CONST_OFFSET_OK (offset + 8)); + case TDmode: case TImode: if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64) extra = 12; @@ -3638,7 +3640,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, && !(SPE_VECTOR_MODE (mode) || ALTIVEC_VECTOR_MODE (mode) || (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode - || mode == DImode)))) + || mode == DImode || mode == DDmode + || mode == TDmode)))) { HOST_WIDE_INT high_int, low_int; rtx sum; @@ -3655,7 +3658,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, && ((TARGET_HARD_FLOAT && TARGET_FPRS) || TARGET_POWERPC64 || ((mode != DImode && mode != DFmode && mode != DDmode) - || TARGET_E500_DOUBLE)) + || (TARGET_E500_DOUBLE && mode != DDmode))) && (TARGET_POWERPC64 || mode != DImode) && mode != TImode && mode != TFmode @@ -3704,7 +3707,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, reg + offset] is not a legitimate addressing mode. */ y = gen_rtx_PLUS (Pmode, op1, op2); - if (GET_MODE_SIZE (mode) > 8 && REG_P (op2)) + if ((GET_MODE_SIZE (mode) > 8 || mode == DDmode) && REG_P (op2)) return force_reg (Pmode, y); else return y; @@ -4265,7 +4268,8 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict) && mode != TDmode && ((TARGET_HARD_FLOAT && TARGET_FPRS) || TARGET_POWERPC64 - || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE)) + || (mode != DFmode && mode != DDmode) + || (TARGET_E500_DOUBLE && mode != DDmode)) && (TARGET_POWERPC64 || mode != DImode) && legitimate_indexed_address_p (x, reg_ok_strict)) return 1; @@ -4389,7 +4393,8 @@ rs6000_hard_regno_nregs (int regno, enum machine_mode mode) would require function_arg and rs6000_spe_function_arg to handle SCmode so as to pass the value correctly in a pair of registers. */ - if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode) + if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode) && mode != SCmode + && !DECIMAL_FLOAT_MODE_P (mode)) return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD; return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; @@ -5664,14 +5669,12 @@ spe_build_register_parallel (enum machine_mode mode, int gregno) switch (mode) { case DFmode: - case DDmode: r1 = gen_rtx_REG (DImode, gregno); r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1)); case DCmode: case TFmode: - case TDmode: r1 = gen_rtx_REG (DImode, gregno); r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); r3 = gen_rtx_REG (DImode, gregno + 2); @@ -5704,13 +5707,12 @@ rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, /* On E500 v2, double arithmetic is done on the full 64-bit GPR, but are passed and returned in a pair of GPRs for ABI compatibility. */ if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode - || mode == DDmode || mode == TDmode || mode == DCmode || mode == TCmode)) { int n_words = rs6000_arg_size (mode, type); /* Doubles go in an odd/even register pair (r5/r6, etc). */ - if (mode == DFmode || mode == DDmode) + if (mode == DFmode) gregno += (1 - gregno) & 1; /* Multi-reg args are not split between registers and stack. */ @@ -6123,10 +6125,8 @@ function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, else if (TARGET_SPE_ABI && TARGET_SPE && (SPE_VECTOR_MODE (mode) || (TARGET_E500_DOUBLE && (mode == DFmode - || mode == DDmode || mode == DCmode || mode == TFmode - || mode == TDmode || mode == TCmode)))) return rs6000_spe_function_arg (cum, mode, type); @@ -6885,7 +6885,9 @@ rs6000_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p) /* _Decimal32 varargs are located in the second word of the 64-bit FP register for 32-bit binaries. */ - if (!TARGET_POWERPC64 && TYPE_MODE (type) == SDmode) + if (!TARGET_POWERPC64 + && TARGET_HARD_FLOAT && TARGET_FPRS + && TYPE_MODE (type) == SDmode) t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size)); t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t); @@ -14015,8 +14017,8 @@ rs6000_split_multireg_move (rtx dst, rtx src) reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode; else if (ALTIVEC_REGNO_P (reg)) reg_mode = V16QImode; - else if (TARGET_E500_DOUBLE && (mode == TFmode || mode == TDmode)) - reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode; + else if (TARGET_E500_DOUBLE && mode == TFmode) + reg_mode = DFmode; else reg_mode = word_mode; reg_mode_size = GET_MODE_SIZE (reg_mode); @@ -14757,8 +14759,7 @@ spe_func_has_64bit_regs_p (void) if (SPE_VECTOR_MODE (mode)) return true; - if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode - || mode == DDmode || mode == TDmode)) + if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode)) return true; } } @@ -15509,7 +15510,7 @@ emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode, /* Some cases that need register indexed addressing. */ if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) - || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode)) + || (TARGET_E500_DOUBLE && mode == DFmode) || (TARGET_SPE_ABI && SPE_VECTOR_MODE (mode) && !SPE_CONST_OFFSET_OK (offset))) @@ -15549,7 +15550,7 @@ gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset) int_rtx = GEN_INT (offset); if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode)) - || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode))) + || (TARGET_E500_DOUBLE && mode == DFmode)) { offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH); emit_move_insn (offset_rtx, int_rtx); @@ -21864,8 +21865,8 @@ rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED) && ALTIVEC_VECTOR_MODE (mode)) regno = ALTIVEC_ARG_RETURN; else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT - && (mode == DFmode || mode == DDmode || mode == DCmode - || mode == TFmode || mode == TDmode || mode == TCmode)) + && (mode == DFmode || mode == DCmode + || mode == TFmode || mode == TCmode)) return spe_build_register_parallel (mode, GP_ARG_RETURN); else regno = GP_ARG_RETURN; @@ -21906,8 +21907,8 @@ rs6000_libcall_value (enum machine_mode mode) else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg) return rs6000_complex_function_value (mode); else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT - && (mode == DFmode || mode == DDmode || mode == DCmode - || mode == TFmode || mode == TDmode || mode == TCmode)) + && (mode == DFmode || mode == DCmode + || mode == TFmode || mode == TCmode)) return spe_build_register_parallel (mode, GP_ARG_RETURN); else regno = GP_ARG_RETURN; diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 442f727..4c225a3 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -583,7 +583,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; #define LOCAL_ALIGNMENT(TYPE, ALIGN) \ ((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \ (TARGET_E500_DOUBLE \ - && (TYPE_MODE (TYPE) == DFmode || TYPE_MODE (TYPE) == DDmode)) ? 64 : \ + && TYPE_MODE (TYPE) == DFmode) ? 64 : \ ((TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE \ && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) || (TARGET_PAIRED_FLOAT \ && TREE_CODE (TYPE) == VECTOR_TYPE \ @@ -609,7 +609,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; fit into 1, whereas DI still needs two. */ #define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \ ((TARGET_SPE && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \ - || (TARGET_E500_DOUBLE && ((MODE) == DFmode || (MODE) == DDmode))) + || (TARGET_E500_DOUBLE && (MODE) == DFmode)) /* A bit-field declared as `int' forces `int' alignment for the struct. */ #define PCC_BITFIELD_TYPE_MATTERS 1 @@ -630,7 +630,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; (TREE_CODE (TYPE) == VECTOR_TYPE ? ((TARGET_SPE_ABI \ || TARGET_PAIRED_FLOAT) ? 64 : 128) \ : (TARGET_E500_DOUBLE \ - && (TYPE_MODE (TYPE) == DFmode || TYPE_MODE (TYPE) == DDmode)) ? 64 \ + && TYPE_MODE (TYPE) == DFmode) ? 64 \ : TREE_CODE (TYPE) == ARRAY_TYPE \ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) @@ -1212,7 +1212,7 @@ enum reg_class (((CLASS) == FLOAT_REGS) \ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \ : (TARGET_E500_DOUBLE && (CLASS) == GENERAL_REGS \ - && ((MODE) == DFmode || (MODE) == DDmode)) \ + && (MODE) == DFmode) \ ? 1 \ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))