This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH][updated] Force SDmode function args into FP registers per the ABI


Peter Bergner wrote:
On Tue, Jun 12, 2007 at 12:34:59PM -0700, Mark Mitchell wrote:
Peter Bergner wrote:
So something along the lines of the totally untested/compiled code below?
If so, I'll bootstrap and regtest the changes along with the rs6000 portion
of the patch and resubmit with ChangeLog.
Yes, that's exactly what I had in mind.

Ok, here's an updated patch that uses the target hook. Note that instead of min_stack_slot_size_for_reg like we talked about, I implemented min_stack_slot_size_for_mode which allowed me to use the target hook within the rs6000 files where we have the mode, but no reg. This passed bootstrap and regtesting. Is this ok for mainline after the freeze?

Peter

	* targhooks.c (default_min_stack_slot_size_for_mode): New default
	target hook.
	* targhooks.h (default_min_stack_slot_size_for_mode): Add prototype.
	* target.h (struct gcc_target): Add min_stack_slot_size_for_mode.
	* target-def.h (TARGET_MIN_STACK_SLOT_SIZE_FOR_MODE): Define as
	default_min_stack_slot_size_for_mode.
	(TARGET_INITIALIZER): Initialize min_stack_slot_size_for_mode with
	TARGET_MIN_STACK_SLOT_SIZE_FOR_MODE.
	* config/rs6000/rs6000.c (rs6000_hard_regno_mode_ok): Treat SDmode
	similar to the other floating point modes.
	(num_insns_constant): Likewise.
	(function_arg_advance): Likewise.
	(function_arg): Likewise.
	(rs6000_output_function_epilogue): Likewise.
	(rs6000_function_value): Likewise.  Simplify code.
	(rs6000_libcall_value): Likewise.
	(rs6000_gimplify_va_arg): Treat SDmode similar to the other floating
	point modes.  Handle 32-bit mode SDmode varargs.
	(rs6000_emit_move): Treat SDmode similar to the other floating point
	modes.  Force SDmode MEM to MEM copies through the integer registers.
	(rs6000_min_stack_slot_size_for_mode): New function.
	(TARGET_MIN_STACK_SLOT_SIZE_FOR_MODE): Use it.
	* config/rs6000/rs6000.h (SLOW_UNALIGNED_ACCESS): Treat SDmode
	similar to the other floating point modes.
	(SECONDARY_MEMORY_NEEDED): Handle SDmode.
	(SECONDARY_MEMORY_NEEDED_RTX): Define.
	* config/rs6000/dfp.md (movsd): New define_expand and splitter.
	(movsd_hardfloat, movsd_softfloat, movsd_store, movsd_load):
	New define_insn's.
	(movdd_hardfloat64): Fixup comment.
	* config/rs6000/rs6000.md (UNSPEC_MOVSD_LOAD): New constant.
	(UNSPEC_MOVSD_STORE): Likewise.
	* reload1.c (alter_reg): Use new min_stack_slot_size_for_mode target
	hook.

Index: targhooks.c
===================================================================
--- targhooks.c (revision 125765)
+++ targhooks.c (working copy)
@@ -633,4 +633,13 @@ tree default_mangle_decl_assembler_name return id;
}
+/* By default, the stack slot size used to hold a reg of mode MODE is
+ equal to its mode size. */
+
+unsigned int
+default_min_stack_slot_size_for_mode (enum machine_mode mode)
+{
+ return GET_MODE_SIZE (mode);
+}
+
#include "gt-targhooks.h"
Index: targhooks.h
===================================================================
--- targhooks.h (revision 125765)
+++ targhooks.h (working copy)
@@ -86,3 +86,4 @@ extern void hook_void_bitmap (bitmap);
extern bool default_handle_c_option (size_t, const char *, int);
extern int default_reloc_rw_mask (void);
extern tree default_mangle_decl_assembler_name (tree, tree);
+extern unsigned int default_min_stack_slot_size_for_mode (enum machine_mode);
Index: target.h
===================================================================
--- target.h (revision 125765)
+++ target.h (working copy)
@@ -798,6 +798,9 @@ struct gcc_target
enum machine_mode,
struct secondary_reload_info *);
+ /* Return the size in bytes required to hold MODE on the stack. */
+ unsigned int (* min_stack_slot_size_for_mode) (enum machine_mode mode);
+
/* Functions specific to the C++ frontend. */
struct cxx {
/* Return the integer type used for guard variables. */
Index: target-def.h
===================================================================
--- target-def.h (revision 125765)
+++ target-def.h (working copy)
@@ -578,6 +578,9 @@ Foundation, 51 Franklin Street, Fifth Fl
#define TARGET_SECONDARY_RELOAD default_secondary_reload
#endif
+#ifndef TARGET_MIN_STACK_SLOT_SIZE_FOR_MODE
+#define TARGET_MIN_STACK_SLOT_SIZE_FOR_MODE default_min_stack_slot_size_for_mode
+#endif
/* C++ specific. */
#ifndef TARGET_CXX_GUARD_TYPE
@@ -729,6 +732,7 @@ Foundation, 51 Franklin Street, Fifth Fl
TARGET_INVALID_UNARY_OP, \
TARGET_INVALID_BINARY_OP, \
TARGET_SECONDARY_RELOAD, \
+ TARGET_MIN_STACK_SLOT_SIZE_FOR_MODE, \
TARGET_CXX, \
TARGET_EXTRA_LIVE_ON_ENTRY, \
TARGET_UNWIND_TABLES_DEFAULT, \
Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c (revision 125765)
+++ config/rs6000/rs6000.c (working copy)
@@ -666,6 +666,7 @@ static void rs6000_elf_encode_section_in
ATTRIBUTE_UNUSED;
#endif
static bool rs6000_use_blocks_for_constant_p (enum machine_mode, rtx);
+static unsigned int rs6000_min_stack_slot_size_for_mode (enum machine_mode);
#if TARGET_XCOFF
static void rs6000_xcoff_asm_output_anchor (rtx);
static void rs6000_xcoff_asm_globalize_label (FILE *, const char *);
@@ -1115,6 +1116,9 @@ static const char alt_reg_names[][8] =
#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
#define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
+#undef TARGET_MIN_STACK_SLOT_SIZE_FOR_MODE
+#define TARGET_MIN_STACK_SLOT_SIZE_FOR_MODE rs6000_min_stack_slot_size_for_mode
+
struct gcc_target targetm = TARGET_INITIALIZER;

@@ -1134,7 +1138,6 @@ rs6000_hard_regno_mode_ok (int regno, en
return
(SCALAR_FLOAT_MODE_P (mode)
&& (mode != TDmode || (regno % 2) == 0)
- && mode != SDmode
&& FP_REGNO_P (regno + HARD_REGNO_NREGS (regno, mode) - 1))
|| (GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_SIZE (mode) == UNITS_PER_FP_WORD);
@@ -2290,13 +2293,16 @@ num_insns_constant (rtx op, enum machine
return num_insns_constant_wide (INTVAL (op));
case CONST_DOUBLE:
- if (mode == SFmode)
+ if (mode == SFmode || mode == SDmode)
{
long l;
REAL_VALUE_TYPE rv;
REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
- REAL_VALUE_TO_TARGET_SINGLE (rv, l);
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
+ else
+ REAL_VALUE_TO_TARGET_SINGLE (rv, l);
return num_insns_constant_wide ((HOST_WIDE_INT) l);
}
@@ -4273,6 +4279,21 @@ rs6000_emit_move (rtx dest, rtx source, return;
}
+ /* Force SDmode MEM to MEM copies to go through the integer registers
+ since non POWER6 hardware cannot load 32-bit quantities into the
+ FP registers without munging the bits. */
+ if (mode == SDmode
+ && TARGET_HARD_FLOAT && TARGET_FPRS
+ && GET_CODE (operands[0]) == MEM
+ && GET_CODE (operands[1]) == MEM
+ && ! MEM_VOLATILE_P (operands [0])
+ && ! MEM_VOLATILE_P (operands [1]))
+ {
+ emit_move_insn (adjust_address (operands[0], SImode, 0),
+ adjust_address (operands[1], SImode, 0));
+ return;
+ }
+
if (!no_new_pseudos && GET_CODE (operands[0]) == MEM
&& !gpc_reg_operand (operands[1], mode))
operands[1] = force_reg (mode, operands[1]);
@@ -4375,6 +4396,7 @@ rs6000_emit_move (rtx dest, rtx source, case DFmode:
case DDmode:
case SFmode:
+ case SDmode:
if (CONSTANT_P (operands[1])
&& ! easy_fp_constant (operands[1], mode))
operands[1] = force_const_mem (mode, operands[1]);
@@ -4585,7 +4607,6 @@ rs6000_emit_move (rtx dest, rtx source, /* Nonzero if we can use a floating-point register to pass this arg. */
#define USE_FP_FOR_ARG_P(CUM,MODE,TYPE) \
(SCALAR_FLOAT_MODE_P (MODE) \
- && (MODE) != SDmode \
&& (CUM)->fregno <= FP_ARG_MAX_REG \
&& TARGET_HARD_FLOAT && TARGET_FPRS)
@@ -5065,7 +5086,7 @@ function_arg_advance (CUMULATIVE_ARGS *c
{
if (TARGET_HARD_FLOAT && TARGET_FPRS
&& (mode == SFmode || mode == DFmode
- || mode == DDmode || mode == TDmode
+ || mode == SDmode || mode == DDmode || mode == TDmode
|| (mode == TFmode && !TARGET_IEEEQUAD)))
{
/* _Decimal128 must use an even/odd register pair. This assumes
@@ -5131,7 +5152,6 @@ function_arg_advance (CUMULATIVE_ARGS *c
cum->words = align_words + n_words;
if (SCALAR_FLOAT_MODE_P (mode)
- && mode != SDmode
&& TARGET_HARD_FLOAT && TARGET_FPRS)
{
/* _Decimal128 must be passed in an even/odd float register pair.
@@ -5630,7 +5650,7 @@ function_arg (CUMULATIVE_ARGS *cum, enum
if (TARGET_HARD_FLOAT && TARGET_FPRS
&& (mode == SFmode || mode == DFmode
|| (mode == TFmode && !TARGET_IEEEQUAD)
- || mode == DDmode || mode == TDmode))
+ || mode == SDmode || mode == DDmode || mode == TDmode))
{
/* _Decimal128 must use an even/odd register pair. This assumes
that the register number is odd when fregno is odd. */
@@ -6303,6 +6323,7 @@ rs6000_gimplify_va_arg (tree valist, tre
&& (TYPE_MODE (type) == SFmode
|| TYPE_MODE (type) == DFmode
|| TYPE_MODE (type) == TFmode
+ || TYPE_MODE (type) == SDmode
|| TYPE_MODE (type) == DDmode
|| TYPE_MODE (type) == TDmode))
{
@@ -6311,7 +6332,7 @@ rs6000_gimplify_va_arg (tree valist, tre
n_reg = (size + 7) / 8;
sav_ofs = 8*4;
sav_scale = 8;
- if (TYPE_MODE (type) != SFmode)
+ if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
align = 8;
}
else
@@ -6374,6 +6395,11 @@ rs6000_gimplify_va_arg (tree valist, tre
u = build2 (MULT_EXPR, sizetype, u, size_int (sav_scale));
t = build2 (POINTER_PLUS_EXPR, ptr_type_node, t, u);
+ /* _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)
+ t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (t), t, size_int (size));
+
t = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
gimplify_and_add (t, pre_p);
@@ -16003,6 +16029,7 @@ rs6000_output_function_epilogue (FILE *f
switch (mode)
{
case SFmode:
+ case SDmode:
bits = 0x2;
break;
@@ -19115,6 +19142,18 @@ rs6000_use_blocks_for_constant_p (enum m
{
return !ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (x, mode);
}
+
+/* Implement TARGET_MIN_STACK_SLOT_SIZE_FOR_MODE. */
+
+static unsigned int
+rs6000_min_stack_slot_size_for_mode (enum machine_mode mode)
+{
+ if (mode == SDmode)
+ return GET_MODE_SIZE (DDmode);
+
+ return GET_MODE_SIZE (mode);
+}
+

/* Return a REG that occurs in ADDR with coefficient 1.
ADDR can be effectively incremented by incrementing REG.
@@ -20652,29 +20691,9 @@ rs6000_function_value (tree valtype, tre
|| POINTER_TYPE_P (valtype))
mode = TARGET_32BIT ? SImode : DImode;
- if (DECIMAL_FLOAT_MODE_P (mode))
- {
- if (TARGET_HARD_FLOAT && TARGET_FPRS)
- {
- switch (mode)
- {
- default:
- gcc_unreachable ();
- case SDmode:
- regno = GP_ARG_RETURN;
- break;
- case DDmode:
- regno = FP_ARG_RETURN;
- break;
- case TDmode:
- /* Use f2:f3 specified by the ABI. */
- regno = FP_ARG_RETURN + 1;
- break;
- }
- }
- else
- regno = GP_ARG_RETURN;
- }
+ if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ /* _Decimal128 must use an even/odd register pair. */
+ regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
else if (SCALAR_FLOAT_TYPE_P (valtype) && TARGET_HARD_FLOAT && TARGET_FPRS)
regno = FP_ARG_RETURN;
else if (TREE_CODE (valtype) == COMPLEX_TYPE
@@ -20715,29 +20734,9 @@ rs6000_libcall_value (enum machine_mode GEN_INT (4))));
}
- if (DECIMAL_FLOAT_MODE_P (mode))
- {
- if (TARGET_HARD_FLOAT && TARGET_FPRS)
- {
- switch (mode)
- {
- default:
- gcc_unreachable ();
- case SDmode:
- regno = GP_ARG_RETURN;
- break;
- case DDmode:
- regno = FP_ARG_RETURN;
- break;
- case TDmode:
- /* Use f2:f3 specified by the ABI. */
- regno = FP_ARG_RETURN + 1;
- break;
- }
- }
- else
- regno = GP_ARG_RETURN;
- }
+ if (DECIMAL_FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ /* _Decimal128 must use an even/odd register pair. */
+ regno = (mode == TDmode) ? FP_ARG_RETURN + 1 : FP_ARG_RETURN;
else if (SCALAR_FLOAT_MODE_P (mode)
&& TARGET_HARD_FLOAT && TARGET_FPRS)
regno = FP_ARG_RETURN;
Index: config/rs6000/rs6000.h
===================================================================
--- config/rs6000/rs6000.h (revision 125765)
+++ config/rs6000/rs6000.h (working copy)
@@ -590,7 +590,7 @@ extern enum rs6000_nop_insertion rs6000_
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) \
(STRICT_ALIGNMENT \
|| (((MODE) == SFmode || (MODE) == DFmode || (MODE) == TFmode \
- || (MODE) == DDmode || (MODE) == TDmode \
+ || (MODE) == SDmode || (MODE) == DDmode || (MODE) == TDmode \
|| (MODE) == DImode) \
&& (ALIGN) < 32))

@@ -1151,7 +1151,15 @@ enum reg_class
&& (MODE != DDmode) \
&& (MODE != DImode)))) \
|| (CLASS1) == ALTIVEC_REGS \
- || (CLASS2) == ALTIVEC_REGS))
+ || (CLASS2) == ALTIVEC_REGS \
+ || (MODE) == SDmode))
+
+/* For cpus that cannot load/store SDmode values from the 64-bit
+ FP registers without using a full 64-bit load/store, we need
+ to allocate a full 64-bit stack slot for them. */
+
+#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
+ assign_stack_local (MODE, targetm.min_stack_slot_size_for_mode (MODE), 0)
/* Return the maximum number of consecutive registers
needed to represent mode MODE in a register of class CLASS.
@@ -1171,6 +1179,7 @@ enum reg_class
(GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
? ((GET_MODE_SIZE (FROM) < 8 || GET_MODE_SIZE (TO) < 8 \
|| TARGET_IEEEQUAD) \
+ && (FROM != SDmode || TO != DDmode || CLASS != FLOAT_REGS) \
&& reg_classes_intersect_p (FLOAT_REGS, CLASS)) \
: (((TARGET_E500_DOUBLE \
&& ((((TO) == DFmode) + ((FROM) == DFmode)) == 1 \
Index: config/rs6000/dfp.md
===================================================================
--- config/rs6000/dfp.md (revision 125765)
+++ config/rs6000/dfp.md (working copy)
@@ -21,6 +21,189 @@
;; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
;; MA 02110-1301, USA.
+(define_expand "movsd"
+ [(set (match_operand:SD 0 "nonimmediate_operand" "")
+ (match_operand:SD 1 "any_operand" ""))]
+ "TARGET_HARD_FLOAT && TARGET_FPRS && !no_new_pseudos"
+ "
+{
+ if (no_new_pseudos)
+ FAIL;
+ else if (MEM_P (operands[0]) && REG_P (operands[1]))
+ {
+ rtx intreg = gen_reg_rtx (SImode);
+ rtx stack = assign_stack_temp (DDmode, GET_MODE_SIZE (DDmode), 0);
+ rtx dst = adjust_address (operands[0], SImode, 0);
+ emit_insn (gen_movsd_store (stack, operands[1]));
+ emit_move_insn (intreg, adjust_address (stack, SImode, 4));
+ emit_move_insn (dst, intreg);
+ DONE;
+ }
+ else if (REG_P (operands[0]) && MEM_P (operands[1]))
+ {
+ rtx intreg = gen_reg_rtx (SImode);
+ rtx stack = assign_stack_temp (DDmode, GET_MODE_SIZE (DDmode), 0);
+ rtx src = adjust_address (operands[1], SImode, 0);
+ emit_move_insn (intreg, src);
+ emit_move_insn (adjust_address (stack, SImode, 4), intreg);
+ emit_insn (gen_movsd_load (operands[0], stack));
+ DONE;
+ }
+ else if (MEM_P (operands[0]) && MEM_P (operands[1]))
+ {
+ rtx src = adjust_address (operands[1], SImode, 0);
+ rtx dst = adjust_address (operands[0], SImode, 0);
+ emit_move_insn (dst, src);
+ DONE;
+ }
+ else if (GET_CODE (operands[0]) == SUBREG
+ && GET_CODE (SUBREG_REG (operands[0])) == REG)
+ {
+ rtx dst = SUBREG_REG (operands[0]);
+ enum machine_mode mode = GET_MODE (dst);
+
+ if (MEM_P (operands[1]))
+ {
+ rtx src = adjust_address (operands[1], mode, 0);
+ emit_move_insn (dst, src);
+ }
+ else if (GET_CODE (operands[1]) == SUBREG
+ && GET_CODE (SUBREG_REG (operands[1])) == REG
+ && mode == GET_MODE (SUBREG_REG (operands[1])))
+ {
+ rtx src = SUBREG_REG (operands[1]);
+ emit_move_insn (dst, src);
+ }
+ else
+ {
+ rtx stack = assign_stack_temp (DDmode, GET_MODE_SIZE (DDmode), 0);
+ emit_insn (gen_movsd_store (stack, operands[1]));
+ emit_move_insn (dst, adjust_address (stack, SImode, 4));
+ }
+ DONE;
+ }
+ else if (GET_CODE (operands[1]) == SUBREG
+ && GET_CODE (SUBREG_REG (operands[1])) == REG)
+ {
+ rtx src = SUBREG_REG (operands[1]);
+ enum machine_mode mode = GET_MODE (src);
+
+ if (MEM_P (operands[0]))
+ {
+ rtx dst = adjust_address (operands[0], mode, 0);
+ emit_move_insn (dst, src);
+ }
+ else
+ {
+ rtx stack = assign_stack_temp (DDmode, GET_MODE_SIZE (DDmode), 0);
+ emit_move_insn (adjust_address (stack, SImode, 4), src);
+ emit_insn (gen_movsd_load (operands[0], stack));
+ }
+ DONE;
+ }
+ else if (REG_P (operands[0]) && REGNO (operands[0]) <= 31
+ && REG_P (operands[1]) && REGNO (operands[1]) > 31)
+ {
+ rtx subreg = simplify_gen_subreg (SImode, operands[0], SDmode, 0);
+ rtx stack = assign_stack_temp (DDmode, GET_MODE_SIZE (DDmode), 0);
+ emit_insn (gen_movsd_store (stack, operands[1]));
+ emit_move_insn (subreg, adjust_address (stack, SImode, 4));
+ DONE;
+ }
+ else
+ rs6000_emit_move (operands[0], operands[1], SDmode);
+ DONE;
+}")
+
+(define_split
+ [(set (match_operand:SD 0 "gpc_reg_operand" "")
+ (match_operand:SD 1 "const_double_operand" ""))]
+ "reload_completed
+ && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
+ || (GET_CODE (operands[0]) == SUBREG
+ && GET_CODE (SUBREG_REG (operands[0])) == REG
+ && REGNO (SUBREG_REG (operands[0])) <= 31))"
+ [(set (match_dup 2) (match_dup 3))]
+ "
+{
+ long l;
+ REAL_VALUE_TYPE rv;
+
+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
+ REAL_VALUE_TO_TARGET_DECIMAL32 (rv, l);
+
+ if (! TARGET_POWERPC64)
+ operands[2] = operand_subword (operands[0], 0, 0, SDmode);
+ else
+ operands[2] = gen_lowpart (SImode, operands[0]);
+
+ operands[3] = gen_int_mode (l, SImode);
+}")
+
+(define_insn "movsd_hardfloat"
+ [(set (match_operand:SD 0 "nonimmediate_operand" "=!r,!r,m,f,*c*l,*q,!r,*h,!r,!r")
+ (match_operand:SD 1 "input_operand" "r,m,r,f,r,r,h,0,G,Fn"))]
+ "(gpc_reg_operand (operands[0], SDmode)
+ || gpc_reg_operand (operands[1], SDmode))
+ && TARGET_HARD_FLOAT && TARGET_FPRS"
+ "@
+ mr %0,%1
+ {l%U1%X1|lwz%U1%X1} %0,%1
+ {st%U0%X0|stw%U0%X0} %1,%0
+ fmr %0,%1
+ mt%0 %1
+ mt%0 %1
+ mf%1 %0
+ {cror 0,0,0|nop}
+ #
+ #"
+ [(set_attr "type" "*,load,store,fp,mtjmpr,*,mfjmpr,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,8")])
+
+(define_insn "movsd_softfloat"
+ [(set (match_operand:SD 0 "nonimmediate_operand" "=r,cl,q,r,r,m,r,r,r,r,r,*h")
+ (match_operand:SD 1 "input_operand" "r,r,r,h,m,r,I,L,R,G,Fn,0"))]
+ "(gpc_reg_operand (operands[0], SDmode)
+ || gpc_reg_operand (operands[1], SDmode))
+ && (TARGET_SOFT_FLOAT || !TARGET_FPRS)"
+ "@
+ mr %0,%1
+ mt%0 %1
+ mt%0 %1
+ mf%1 %0
+ {l%U1%X1|lwz%U1%X1} %0,%1
+ {st%U0%X0|stw%U0%X0} %1,%0
+ {lil|li} %0,%1
+ {liu|lis} %0,%v1
+ {cal|la} %0,%a1
+ #
+ #
+ {cror 0,0,0|nop}"
+ [(set_attr "type" "*,mtjmpr,*,mfjmpr,load,store,*,*,*,*,*,*")
+ (set_attr "length" "4,4,4,4,4,4,4,4,4,4,8,4")])
+
+(define_insn "movsd_store"
+ [(set (match_operand:DD 0 "nonimmediate_operand" "=m")
+ (unspec:DD [(match_operand:SD 1 "input_operand" "f")]
+ UNSPEC_MOVSD_STORE))]
+ "(gpc_reg_operand (operands[0], DDmode)
+ || gpc_reg_operand (operands[1], SDmode))
+ && TARGET_HARD_FLOAT && TARGET_FPRS"
+ "stfd%U0%X0 %1,%0"
+ [(set_attr "type" "fpstore")
+ (set_attr "length" "4")])
+
+(define_insn "movsd_load"
+ [(set (match_operand:SD 0 "nonimmediate_operand" "=f")
+ (unspec:SD [(match_operand:DD 1 "input_operand" "m")]
+ UNSPEC_MOVSD_LOAD))]
+ "(gpc_reg_operand (operands[0], SDmode)
+ || gpc_reg_operand (operands[1], DDmode))
+ && TARGET_HARD_FLOAT && TARGET_FPRS"
+ "lfd%U1%X1 %0,%1"
+ [(set_attr "type" "fpload")
+ (set_attr "length" "4")])
+
(define_expand "negdd2"
[(set (match_operand:DD 0 "gpc_reg_operand" "")
(neg:DD (match_operand:DD 1 "gpc_reg_operand" "")))]
@@ -310,7 +493,7 @@ (define_insn "*movdd_hardfloat64_mfpgpr"
(set_attr "length" "4,4,4,4,4,4,4,4,4,8,12,16,4,4")])
; ld/std require word-aligned displacements -> 'Y' constraint.
-; List Y->r and r->Y before r->r for reload.(define_insn "*movdd_hardfloat64"
+; List Y->r and r->Y before r->r for reload.
(define_insn "*movdd_hardfloat64"
[(set (match_operand:DD 0 "nonimmediate_operand" "=Y,r,!r,f,f,m,*c*l,!r,*h,!r,!r,!r")
(match_operand:DD 1 "input_operand" "r,Y,r,f,m,f,r,h,0,G,H,F"))]
Index: config/rs6000/rs6000.md
===================================================================
--- config/rs6000/rs6000.md (revision 125765)
+++ config/rs6000/rs6000.md (working copy)
@@ -72,6 +72,8 @@ (define_constants
(UNSPEC_DLMZB 45)
(UNSPEC_DLMZB_CR 46)
(UNSPEC_DLMZB_STRLEN 47)
+ (UNSPEC_MOVSD_LOAD 48)
+ (UNSPEC_MOVSD_STORE 49)
])
;;
Index: reload1.c
===================================================================
--- reload1.c (revision 125765)
+++ reload1.c (working copy)
@@ -2063,7 +2063,9 @@ alter_reg (int i, int from_reg)
enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
unsigned int inherent_size = PSEUDO_REGNO_BYTES (i);
unsigned int inherent_align = GET_MODE_ALIGNMENT (mode);
- unsigned int total_size = MAX (inherent_size, reg_max_ref_width[i]);
+ unsigned int total_size =
+ MAX (targetm.min_stack_slot_size_for_mode (mode),
+ reg_max_ref_width[i]);
unsigned int min_align = reg_max_ref_width[i] * BITS_PER_UNIT;
int adjust = 0;

This can be simplified to be just


enum machine_mode mode = PSEUDO_REGNO_MODE (i);
unsigned int inherent_size = targetm.min_stack_slot_size_for_mode (mode);
unsigned int total_size = MAX (inherent_size, reg_max_ref_width[i]);

because of these definitions

/* this is exactly how mode is computed above */
#define PSEUDO_REGNO_MODE(N) GET_MODE (regno_reg_rtx[N])

/* this is exactly the default definition of the hook.  */
#define PSEUDO_REGNO_BYTES(N) \
  GET_MODE_SIZE (PSEUDO_REGNO_MODE (N))

Sorry for the further nitpicking... I can take care of this, but I wouldn't mind preapproval since this was what Mark mentioned here:

The
default would be PSEUDO_REGNO_BYTES (REGNO (reg)).  Then, in alter reg,
use the max of reg_max_ref_width and the value of the hook?

The patch would only touch reload1.c.


Paolo


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]