Commit 4d4447b5 by Peter Bergner Committed by Peter Bergner

rs6000.c (invalid_e500_subreg, [...]): Handle DDmode and TDmode similarly to DFmode and TFmode.

	* config/rs6000/rs6000.c (invalid_e500_subreg,
	rs6000_legitimate_offset_address_p, legitimate_lo_sum_address_p,
	rs6000_legitimize_address, rs6000_legitimize_reload_address,
	rs6000_legitimate_address, function_arg_advance,
	spe_build_register_parallel, rs6000_spe_function_arg,
	rs6000_split_multireg_move, spe_func_has_64bit_regs_p,
	emit_frame_save, gen_frame_mem_offset, rs6000_function_value,
	rs6000_libcall_value, rs6000_dwarf_register_span): Handle DDmode and
	TDmode similarly to DFmode and TFmode.
	* config/rs6000/rs6000.h (LOCAL_ALIGNMENT, MEMBER_TYPE_FORCES_BLK,
	DATA_ALIGNMENT, CLASS_MAX_NREGS, CANNOT_CHANGE_MODE_CLASS): Likewise.

	* gcc.dg/dfp/ddmode-ice.c: New test.

From-SVN: r130296
parent b7cfd8a4
2007-11-19 Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/rs6000.c (invalid_e500_subreg,
rs6000_legitimate_offset_address_p, legitimate_lo_sum_address_p,
rs6000_legitimize_address, rs6000_legitimize_reload_address,
rs6000_legitimate_address, function_arg_advance,
spe_build_register_parallel, rs6000_spe_function_arg,
rs6000_split_multireg_move, spe_func_has_64bit_regs_p,
emit_frame_save, gen_frame_mem_offset, rs6000_function_value,
rs6000_libcall_value, rs6000_dwarf_register_span): Handle DDmode and
TDmode similarly to DFmode and TFmode.
* config/rs6000/rs6000.h (LOCAL_ALIGNMENT, MEMBER_TYPE_FORCES_BLK,
DATA_ALIGNMENT, CLASS_MAX_NREGS, CANNOT_CHANGE_MODE_CLASS): Likewise.
2007-11-19 Eric Botcazou <ebotcazou@adacore.com> 2007-11-19 Eric Botcazou <ebotcazou@adacore.com>
* stor-layout.c (lang_adjust_rli): Delete. * stor-layout.c (lang_adjust_rli): Delete.
...@@ -3115,13 +3115,16 @@ invalid_e500_subreg (rtx op, enum machine_mode mode) ...@@ -3115,13 +3115,16 @@ invalid_e500_subreg (rtx op, enum machine_mode mode)
&& (mode == SImode || mode == DImode || mode == TImode) && (mode == SImode || mode == DImode || mode == TImode)
&& REG_P (SUBREG_REG (op)) && REG_P (SUBREG_REG (op))
&& (GET_MODE (SUBREG_REG (op)) == DFmode && (GET_MODE (SUBREG_REG (op)) == DFmode
|| GET_MODE (SUBREG_REG (op)) == TFmode)) || GET_MODE (SUBREG_REG (op)) == TFmode
|| GET_MODE (SUBREG_REG (op)) == DDmode
|| GET_MODE (SUBREG_REG (op)) == TDmode))
return true; return true;
/* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and /* Reject (subreg:DF (reg:DI)); likewise with subreg:TF and
reg:TI. */ reg:TI. */
if (GET_CODE (op) == SUBREG if (GET_CODE (op) == SUBREG
&& (mode == DFmode || mode == TFmode) && (mode == DFmode || mode == TFmode
|| mode == DDmode || mode == TDmode)
&& REG_P (SUBREG_REG (op)) && REG_P (SUBREG_REG (op))
&& (GET_MODE (SUBREG_REG (op)) == DImode && (GET_MODE (SUBREG_REG (op)) == DImode
|| GET_MODE (SUBREG_REG (op)) == TImode)) || GET_MODE (SUBREG_REG (op)) == TImode))
...@@ -3390,12 +3393,12 @@ rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict) ...@@ -3390,12 +3393,12 @@ rs6000_legitimate_offset_address_p (enum machine_mode mode, rtx x, int strict)
break; break;
case TFmode: case TFmode:
case TDmode:
if (TARGET_E500_DOUBLE) if (TARGET_E500_DOUBLE)
return (SPE_CONST_OFFSET_OK (offset) return (SPE_CONST_OFFSET_OK (offset)
&& SPE_CONST_OFFSET_OK (offset + 8)); && SPE_CONST_OFFSET_OK (offset + 8));
case TImode: case TImode:
case TDmode:
if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64) if (mode == TFmode || mode == TDmode || !TARGET_POWERPC64)
extra = 12; extra = 12;
else if (offset & 3) else if (offset & 3)
...@@ -3474,6 +3477,7 @@ legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict) ...@@ -3474,6 +3477,7 @@ legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
return false; return false;
/* Restrict addressing for DI because of our SUBREG hackery. */ /* Restrict addressing for DI because of our SUBREG hackery. */
if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
|| mode == DDmode || mode == TDmode
|| mode == DImode)) || mode == DImode))
return false; return false;
x = XEXP (x, 1); x = XEXP (x, 1);
...@@ -3488,7 +3492,8 @@ legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict) ...@@ -3488,7 +3492,8 @@ legitimate_lo_sum_address_p (enum machine_mode mode, rtx x, int strict)
return false; return false;
if (GET_MODE_BITSIZE (mode) > 64 if (GET_MODE_BITSIZE (mode) > 64
|| (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64 || (GET_MODE_BITSIZE (mode) > 32 && !TARGET_POWERPC64
&& !(TARGET_HARD_FLOAT && TARGET_FPRS && mode == DFmode))) && !(TARGET_HARD_FLOAT && TARGET_FPRS
&& (mode == DFmode || mode == DDmode))))
return false; return false;
return CONSTANT_P (x); return CONSTANT_P (x);
...@@ -3610,7 +3615,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, ...@@ -3610,7 +3615,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
&& CONSTANT_P (x) && CONSTANT_P (x)
&& GET_MODE_NUNITS (mode) == 1 && GET_MODE_NUNITS (mode) == 1
&& (GET_MODE_BITSIZE (mode) <= 32 && (GET_MODE_BITSIZE (mode) <= 32
|| ((TARGET_HARD_FLOAT && TARGET_FPRS) && mode == DFmode))) || ((TARGET_HARD_FLOAT && TARGET_FPRS)
&& (mode == DFmode || mode == DDmode))))
{ {
rtx reg = gen_reg_rtx (Pmode); rtx reg = gen_reg_rtx (Pmode);
emit_insn (gen_elf_high (reg, x)); emit_insn (gen_elf_high (reg, x));
...@@ -3624,7 +3630,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, ...@@ -3624,7 +3630,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
&& GET_CODE (x) != CONST_INT && GET_CODE (x) != CONST_INT
&& GET_CODE (x) != CONST_DOUBLE && GET_CODE (x) != CONST_DOUBLE
&& CONSTANT_P (x) && CONSTANT_P (x)
&& ((TARGET_HARD_FLOAT && TARGET_FPRS) || mode != DFmode) && ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| (mode != DFmode && mode != DDmode))
&& mode != DImode && mode != DImode
&& mode != TImode) && mode != TImode)
{ {
...@@ -3980,6 +3987,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, ...@@ -3980,6 +3987,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
&& GET_CODE (XEXP (x, 1)) == CONST_INT && GET_CODE (XEXP (x, 1)) == CONST_INT
&& !SPE_VECTOR_MODE (mode) && !SPE_VECTOR_MODE (mode)
&& !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
|| mode == DDmode || mode == TDmode
|| mode == DImode)) || mode == DImode))
&& !ALTIVEC_VECTOR_MODE (mode)) && !ALTIVEC_VECTOR_MODE (mode))
{ {
...@@ -4021,12 +4029,12 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, ...@@ -4021,12 +4029,12 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
&& !flag_pic && !flag_pic
#endif #endif
/* Don't do this for TFmode or TDmode, since the result isn't offsettable. /* Don't do this for TFmode or TDmode, since the result isn't offsettable.
The same goes for DImode without 64-bit gprs and DFmode The same goes for DImode without 64-bit gprs and DFmode and DDmode
without fprs. */ without fprs. */
&& mode != TFmode && mode != TFmode
&& mode != TDmode && mode != TDmode
&& (mode != DImode || TARGET_POWERPC64) && (mode != DImode || TARGET_POWERPC64)
&& (mode != DFmode || TARGET_POWERPC64 && ((mode != DFmode && mode != DDmode) || TARGET_POWERPC64
|| (TARGET_FPRS && TARGET_HARD_FLOAT))) || (TARGET_FPRS && TARGET_HARD_FLOAT)))
{ {
#if TARGET_MACHO #if TARGET_MACHO
...@@ -4089,11 +4097,11 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode, ...@@ -4089,11 +4097,11 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
refers to a constant pool entry of an address (or the sum of it refers to a constant pool entry of an address (or the sum of it
plus a constant), a short (16-bit signed) constant plus a register, plus a constant), a short (16-bit signed) constant plus a register,
the sum of two registers, or a register indirect, possibly with an the sum of two registers, or a register indirect, possibly with an
auto-increment. For DFmode and DImode with a constant plus register, auto-increment. For DFmode, DDmode and DImode with a constant plus
we must ensure that both words are addressable or PowerPC64 with offset register, we must ensure that both words are addressable or PowerPC64
word aligned. with offset word aligned.
For modes spanning multiple registers (DFmode in 32-bit GPRs, For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used 32-bit DImode, TImode, TFmode, TDmode), indexed addressing cannot be used
because adjacent memory cells are accessed by adding word-sized offsets because adjacent memory cells are accessed by adding word-sized offsets
during assembly output. */ during assembly output. */
...@@ -4118,8 +4126,8 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict) ...@@ -4118,8 +4126,8 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
&& mode != TFmode && mode != TFmode
&& mode != TDmode && mode != TDmode
/* Restrict addressing for DI because of our SUBREG hackery. */ /* Restrict addressing for DI because of our SUBREG hackery. */
&& !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode && !(TARGET_E500_DOUBLE
|| mode == DImode)) && (mode == DFmode || mode == DDmode || mode == DImode))
&& TARGET_UPDATE && TARGET_UPDATE
&& legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)) && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict))
return 1; return 1;
...@@ -4142,7 +4150,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict) ...@@ -4142,7 +4150,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
&& mode != TDmode && mode != TDmode
&& ((TARGET_HARD_FLOAT && TARGET_FPRS) && ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64 || TARGET_POWERPC64
|| ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode)) || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
&& (TARGET_POWERPC64 || mode != DImode) && (TARGET_POWERPC64 || mode != DImode)
&& legitimate_indexed_address_p (x, reg_ok_strict)) && legitimate_indexed_address_p (x, reg_ok_strict))
return 1; return 1;
...@@ -4152,12 +4160,13 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict) ...@@ -4152,12 +4160,13 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
&& mode != TDmode && mode != TDmode
&& ((TARGET_HARD_FLOAT && TARGET_FPRS) && ((TARGET_HARD_FLOAT && TARGET_FPRS)
|| TARGET_POWERPC64 || TARGET_POWERPC64
|| ((mode != DFmode || TARGET_E500_DOUBLE) && mode != TFmode)) || ((mode != DFmode && mode != DDmode) || TARGET_E500_DOUBLE))
&& (TARGET_POWERPC64 || mode != DImode) && (TARGET_POWERPC64 || mode != DImode)
&& !ALTIVEC_VECTOR_MODE (mode) && !ALTIVEC_VECTOR_MODE (mode)
&& !SPE_VECTOR_MODE (mode) && !SPE_VECTOR_MODE (mode)
/* Restrict addressing for DI because of our SUBREG hackery. */ /* Restrict addressing for DI because of our SUBREG hackery. */
&& !(TARGET_E500_DOUBLE && (mode == DFmode || mode == DImode)) && !(TARGET_E500_DOUBLE
&& (mode == DFmode || mode == DDmode || mode == DImode))
&& TARGET_UPDATE && TARGET_UPDATE
&& legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict) && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
&& (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict) && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
...@@ -5407,7 +5416,8 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -5407,7 +5416,8 @@ function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode,
else else
{ {
cum->fregno = FP_ARG_V4_MAX_REG + 1; cum->fregno = FP_ARG_V4_MAX_REG + 1;
if (mode == DFmode || mode == TFmode || mode == DDmode || mode == TDmode) if (mode == DFmode || mode == TFmode
|| mode == DDmode || mode == TDmode)
cum->words += cum->words & 1; cum->words += cum->words & 1;
cum->words += rs6000_arg_size (mode, type); cum->words += rs6000_arg_size (mode, type);
} }
...@@ -5490,12 +5500,14 @@ spe_build_register_parallel (enum machine_mode mode, int gregno) ...@@ -5490,12 +5500,14 @@ spe_build_register_parallel (enum machine_mode mode, int gregno)
switch (mode) switch (mode)
{ {
case DFmode: case DFmode:
case DDmode:
r1 = gen_rtx_REG (DImode, gregno); r1 = gen_rtx_REG (DImode, gregno);
r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1)); return gen_rtx_PARALLEL (mode, gen_rtvec (1, r1));
case DCmode: case DCmode:
case TFmode: case TFmode:
case TDmode:
r1 = gen_rtx_REG (DImode, gregno); r1 = gen_rtx_REG (DImode, gregno);
r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx); r1 = gen_rtx_EXPR_LIST (VOIDmode, r1, const0_rtx);
r3 = gen_rtx_REG (DImode, gregno + 2); r3 = gen_rtx_REG (DImode, gregno + 2);
...@@ -5527,13 +5539,14 @@ rs6000_spe_function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, ...@@ -5527,13 +5539,14 @@ 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 /* 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. */ are passed and returned in a pair of GPRs for ABI compatibility. */
if (TARGET_E500_DOUBLE && (mode == DFmode || mode == DCmode if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
|| mode == TFmode || mode == TCmode)) || mode == DDmode || mode == TDmode
|| mode == DCmode || mode == TCmode))
{ {
int n_words = rs6000_arg_size (mode, type); int n_words = rs6000_arg_size (mode, type);
/* Doubles go in an odd/even register pair (r5/r6, etc). */ /* Doubles go in an odd/even register pair (r5/r6, etc). */
if (mode == DFmode) if (mode == DFmode || mode == DDmode)
gregno += (1 - gregno) & 1; gregno += (1 - gregno) & 1;
/* Multi-reg args are not split between registers and stack. */ /* Multi-reg args are not split between registers and stack. */
...@@ -13718,8 +13731,8 @@ rs6000_split_multireg_move (rtx dst, rtx src) ...@@ -13718,8 +13731,8 @@ rs6000_split_multireg_move (rtx dst, rtx src)
reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode; reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
else if (ALTIVEC_REGNO_P (reg)) else if (ALTIVEC_REGNO_P (reg))
reg_mode = V16QImode; reg_mode = V16QImode;
else if (TARGET_E500_DOUBLE && mode == TFmode) else if (TARGET_E500_DOUBLE && (mode == TFmode || mode == TDmode))
reg_mode = DFmode; reg_mode = DECIMAL_FLOAT_MODE_P (mode) ? DDmode : DFmode;
else else
reg_mode = word_mode; reg_mode = word_mode;
reg_mode_size = GET_MODE_SIZE (reg_mode); reg_mode_size = GET_MODE_SIZE (reg_mode);
...@@ -14458,7 +14471,8 @@ spe_func_has_64bit_regs_p (void) ...@@ -14458,7 +14471,8 @@ spe_func_has_64bit_regs_p (void)
if (SPE_VECTOR_MODE (mode)) if (SPE_VECTOR_MODE (mode))
return true; return true;
if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode)) if (TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
|| mode == DDmode || mode == TDmode))
return true; return true;
} }
} }
...@@ -15274,7 +15288,7 @@ emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode, ...@@ -15274,7 +15288,7 @@ emit_frame_save (rtx frame_reg, rtx frame_ptr, enum machine_mode mode,
/* Some cases that need register indexed addressing. */ /* Some cases that need register indexed addressing. */
if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
|| (TARGET_E500_DOUBLE && mode == DFmode) || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode))
|| (TARGET_SPE_ABI || (TARGET_SPE_ABI
&& SPE_VECTOR_MODE (mode) && SPE_VECTOR_MODE (mode)
&& !SPE_CONST_OFFSET_OK (offset))) && !SPE_CONST_OFFSET_OK (offset)))
...@@ -15314,7 +15328,7 @@ gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset) ...@@ -15314,7 +15328,7 @@ gen_frame_mem_offset (enum machine_mode mode, rtx reg, int offset)
int_rtx = GEN_INT (offset); int_rtx = GEN_INT (offset);
if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode)) if ((TARGET_SPE_ABI && SPE_VECTOR_MODE (mode))
|| (TARGET_E500_DOUBLE && mode == DFmode)) || (TARGET_E500_DOUBLE && (mode == DFmode || mode == DDmode)))
{ {
offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH); offset_rtx = gen_rtx_REG (Pmode, FIXED_SCRATCH);
emit_move_insn (offset_rtx, int_rtx); emit_move_insn (offset_rtx, int_rtx);
...@@ -21521,8 +21535,8 @@ rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED) ...@@ -21521,8 +21535,8 @@ rs6000_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED)
&& ALTIVEC_VECTOR_MODE (mode)) && ALTIVEC_VECTOR_MODE (mode))
regno = ALTIVEC_ARG_RETURN; regno = ALTIVEC_ARG_RETURN;
else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
&& (mode == DFmode || mode == DCmode && (mode == DFmode || mode == DDmode || mode == DCmode
|| mode == TFmode || mode == TCmode)) || mode == TFmode || mode == TDmode || mode == TCmode))
return spe_build_register_parallel (mode, GP_ARG_RETURN); return spe_build_register_parallel (mode, GP_ARG_RETURN);
else else
regno = GP_ARG_RETURN; regno = GP_ARG_RETURN;
...@@ -21583,8 +21597,8 @@ rs6000_libcall_value (enum machine_mode mode) ...@@ -21583,8 +21597,8 @@ rs6000_libcall_value (enum machine_mode mode)
else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg) else if (COMPLEX_MODE_P (mode) && targetm.calls.split_complex_arg)
return rs6000_complex_function_value (mode); return rs6000_complex_function_value (mode);
else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT else if (TARGET_E500_DOUBLE && TARGET_HARD_FLOAT
&& (mode == DFmode || mode == DCmode && (mode == DFmode || mode == DDmode || mode == DCmode
|| mode == TFmode || mode == TCmode)) || mode == TFmode || mode == TDmode || mode == TCmode))
return spe_build_register_parallel (mode, GP_ARG_RETURN); return spe_build_register_parallel (mode, GP_ARG_RETURN);
else else
regno = GP_ARG_RETURN; regno = GP_ARG_RETURN;
...@@ -21642,7 +21656,8 @@ rs6000_dwarf_register_span (rtx reg) ...@@ -21642,7 +21656,8 @@ rs6000_dwarf_register_span (rtx reg)
if (TARGET_SPE if (TARGET_SPE
&& (SPE_VECTOR_MODE (GET_MODE (reg)) && (SPE_VECTOR_MODE (GET_MODE (reg))
|| (TARGET_E500_DOUBLE && GET_MODE (reg) == DFmode))) || (TARGET_E500_DOUBLE
&& (GET_MODE (reg) == DFmode || GET_MODE (reg) == DDmode))))
; ;
else else
return NULL_RTX; return NULL_RTX;
......
...@@ -559,7 +559,8 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; ...@@ -559,7 +559,8 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
that the object would ordinarily have. */ that the object would ordinarily have. */
#define LOCAL_ALIGNMENT(TYPE, ALIGN) \ #define LOCAL_ALIGNMENT(TYPE, ALIGN) \
((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \ ((TARGET_ALTIVEC && TREE_CODE (TYPE) == VECTOR_TYPE) ? 128 : \
(TARGET_E500_DOUBLE && TYPE_MODE (TYPE) == DFmode) ? 64 : \ (TARGET_E500_DOUBLE \
&& (TYPE_MODE (TYPE) == DFmode || TYPE_MODE (TYPE) == DDmode)) ? 64 : \
((TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE \ ((TARGET_SPE && TREE_CODE (TYPE) == VECTOR_TYPE \
&& SPE_VECTOR_MODE (TYPE_MODE (TYPE))) || (TARGET_PAIRED_FLOAT \ && SPE_VECTOR_MODE (TYPE_MODE (TYPE))) || (TARGET_PAIRED_FLOAT \
&& TREE_CODE (TYPE) == VECTOR_TYPE \ && TREE_CODE (TYPE) == VECTOR_TYPE \
...@@ -585,7 +586,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; ...@@ -585,7 +586,7 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
fit into 1, whereas DI still needs two. */ fit into 1, whereas DI still needs two. */
#define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \ #define MEMBER_TYPE_FORCES_BLK(FIELD, MODE) \
((TARGET_SPE && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \ ((TARGET_SPE && TREE_CODE (TREE_TYPE (FIELD)) == VECTOR_TYPE) \
|| (TARGET_E500_DOUBLE && (MODE) == DFmode)) || (TARGET_E500_DOUBLE && ((MODE) == DFmode || (MODE) == DDmode)))
/* A bit-field declared as `int' forces `int' alignment for the struct. */ /* A bit-field declared as `int' forces `int' alignment for the struct. */
#define PCC_BITFIELD_TYPE_MATTERS 1 #define PCC_BITFIELD_TYPE_MATTERS 1
...@@ -604,7 +605,8 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops; ...@@ -604,7 +605,8 @@ extern enum rs6000_nop_insertion rs6000_sched_insert_nops;
#define DATA_ALIGNMENT(TYPE, ALIGN) \ #define DATA_ALIGNMENT(TYPE, ALIGN) \
(TREE_CODE (TYPE) == VECTOR_TYPE ? ((TARGET_SPE_ABI \ (TREE_CODE (TYPE) == VECTOR_TYPE ? ((TARGET_SPE_ABI \
|| TARGET_PAIRED_FLOAT) ? 64 : 128) \ || TARGET_PAIRED_FLOAT) ? 64 : 128) \
: (TARGET_E500_DOUBLE && TYPE_MODE (TYPE) == DFmode) ? 64 \ : (TARGET_E500_DOUBLE \
&& (TYPE_MODE (TYPE) == DFmode || TYPE_MODE (TYPE) == DDmode)) ? 64 \
: TREE_CODE (TYPE) == ARRAY_TYPE \ : TREE_CODE (TYPE) == ARRAY_TYPE \
&& TYPE_MODE (TREE_TYPE (TYPE)) == QImode \ && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
&& (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN)) && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
...@@ -1178,7 +1180,8 @@ enum reg_class ...@@ -1178,7 +1180,8 @@ enum reg_class
#define CLASS_MAX_NREGS(CLASS, MODE) \ #define CLASS_MAX_NREGS(CLASS, MODE) \
(((CLASS) == FLOAT_REGS) \ (((CLASS) == FLOAT_REGS) \
? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \ ? ((GET_MODE_SIZE (MODE) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD) \
: (TARGET_E500_DOUBLE && (CLASS) == GENERAL_REGS && (MODE) == DFmode) \ : (TARGET_E500_DOUBLE && (CLASS) == GENERAL_REGS \
&& ((MODE) == DFmode || (MODE) == DDmode)) \
? 1 \ ? 1 \
: ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)) : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
...@@ -1192,6 +1195,8 @@ enum reg_class ...@@ -1192,6 +1195,8 @@ enum reg_class
: (((TARGET_E500_DOUBLE \ : (((TARGET_E500_DOUBLE \
&& ((((TO) == DFmode) + ((FROM) == DFmode)) == 1 \ && ((((TO) == DFmode) + ((FROM) == DFmode)) == 1 \
|| (((TO) == TFmode) + ((FROM) == TFmode)) == 1 \ || (((TO) == TFmode) + ((FROM) == TFmode)) == 1 \
|| (((TO) == DDmode) + ((FROM) == DDmode)) == 1 \
|| (((TO) == TDmode) + ((FROM) == TDmode)) == 1 \
|| (((TO) == DImode) + ((FROM) == DImode)) == 1)) \ || (((TO) == DImode) + ((FROM) == DImode)) == 1)) \
|| (TARGET_SPE \ || (TARGET_SPE \
&& (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1)) \ && (SPE_VECTOR_MODE (FROM) + SPE_VECTOR_MODE (TO)) == 1)) \
...@@ -1717,11 +1722,11 @@ typedef struct rs6000_args ...@@ -1717,11 +1722,11 @@ typedef struct rs6000_args
refers to a constant pool entry of an address (or the sum of it refers to a constant pool entry of an address (or the sum of it
plus a constant), a short (16-bit signed) constant plus a register, plus a constant), a short (16-bit signed) constant plus a register,
the sum of two registers, or a register indirect, possibly with an the sum of two registers, or a register indirect, possibly with an
auto-increment. For DFmode and DImode with a constant plus register, auto-increment. For DFmode, DDmode and DImode with a constant plus
we must ensure that both words are addressable or PowerPC64 with offset register, we must ensure that both words are addressable or PowerPC64
word aligned. with offset word aligned.
For modes spanning multiple registers (DFmode in 32-bit GPRs, For modes spanning multiple registers (DFmode and DDmode in 32-bit GPRs,
32-bit DImode, TImode), indexed addressing cannot be used because 32-bit DImode, TImode), indexed addressing cannot be used because
adjacent memory cells are accessed by adding word-sized offsets adjacent memory cells are accessed by adding word-sized offsets
during assembly output. */ during assembly output. */
......
2007-11-19 Peter Bergner <bergner@vnet.ibm.com>
* gcc.dg/dfp/ddmode-ice.c: New test.
2007-11-19 Eric Botcazou <ebotcazou@libertysurf.fr> 2007-11-19 Eric Botcazou <ebotcazou@libertysurf.fr>
PR tree-optimization/34036 PR tree-optimization/34036
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -O1" } */
/* This used to result in an ICE. */
_Decimal64 y[258][258];
_Decimal64 dd[258][258];
_Decimal64 ry[258][258];
_Decimal64
foo (void)
{
int i;
int j;
int m;
int im;
int jm;
int ip;
int jp;
int i2m;
int i1p;
_Decimal64 a;
_Decimal64 b;
_Decimal64 c;
_Decimal64 qi;
_Decimal64 qj;
_Decimal64 xx;
_Decimal64 yx;
_Decimal64 xy;
_Decimal64 yy;
_Decimal64 rel;
_Decimal64 qxx;
_Decimal64 qyy;
_Decimal64 qxy;
do
{
jp = j + 1;
for (i = i1p; i <= i2m; i++)
{
ip = i + 1;
yx = y[ip][j] - y[im][j];
yy = y[i][jp] - y[i][jm];
a = 0.25dd * (xy * xy + yy * yy);
b = 0.25dd * (xx * xx + yx * yx);
c = 0.125dd * (xx * xy + yx * yy);
qj = 0.0dd;
dd[i][m] = b + a * rel + b;
qxx = y[ip][j] - 2.0dd * y[i][j] + y[im][j];
qyy = y[i][jp] - 2.0dd * y[i][j] + y[i][jm];
qxy = y[ip][jp] - y[ip][jm] - y[im][jp] + y[im][jm];
ry[i][m] = a * qxx + b * qyy - c * qxy + yx * qi + yy * qj;
}
}
while (1);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment