Commit 4e44c1ef by Jakub Jelinek Committed by Jakub Jelinek

re PR rtl-optimization/13424 (gcc.dg/20031202-1.c is miscompiled)

	PR optimization/13424
	* expr.c (store_constructor): Revert 2003-12-03 change.

	* emit-rtl.c (change_address): Check also if MEM_ATTRS is set as
	expected before returning early.  Avoid sharing RTL if they
	need to be changed.

	* config/i386/i386.c (ix86_expand_movstr): Rework rep_mov and strmov
	handling so that memory attributes are preserved.  Don't call
	ix86_set_move_mem_attrs.
	(ix86_set_move_mem_attrs_1, ix86_set_move_mem_attrs): Removed.
	(ix86_expand_clrstr): Rename src argument to
	dst.  Rework rep_stos and strset handling so that memory attributes
	are preserved.
	(ix86_expand_strlen): Pass src argument to
	ix86_expand_strlensi_unroll_1.  Rework strlenqi_1 handling so that
	memory attributes are preserved.
	(ix86_expand_strlensi_unroll_1): Add src argument.  Use
	change_address instead of gen_rtx_MEM.
	* config/i386/i386.md (strmov, strmov_singleop, rep_mov): New
	expanders.
	(strmovdi_rex64, strmovsi, strmovsi_rex64, strmovhi, strmovhi_rex64,
	strmovqi, strmovqi_rex64): Remove.
	(rep_mov*, strmov*): Prefix insn names with *.
	(strset, strset_singleop, rep_stos): New expanders.
	(strsetdi_rex64, strsetsi, strsetsi_rex64, strsethi, strsethi_rex64,
	strsetqi, strsetqi_rex64): Remove.
	(rep_stos*, strset*): Prefix insn names with *.
	(rep_stosqi_rex64): Likewise.  Fix mode of dirflag reg from DImode
	to SImode.
	(cmpstrsi): Rework cmpstrqi_1 handling so that memory attributes
	are preserved.
	(cmpstrqi_nz_1, cmpstrqi_nz_rex_1, cmpstrqi_1, cmpstrqi_rex_1):
	Prefix insn names with *.
	(cmpstrqi_nz_1, cmpstrqi_1): New expanders.
	(strlenqi_1, strlenqi_rex_1): Prefix insn names with *.
	(strlenqi_1): New expander.
	* config/i386/i386.h (ix86_set_move_mem_attrs): Remove prototype.

From-SVN: r76852
parent f470c378
2004-01-29 Jakub Jelinek <jakub@redhat.com>
PR optimization/13424
* expr.c (store_constructor): Revert 2003-12-03 change.
* emit-rtl.c (change_address): Check also if MEM_ATTRS is set as
expected before returning early. Avoid sharing RTL if they
need to be changed.
* config/i386/i386.c (ix86_expand_movstr): Rework rep_mov and strmov
handling so that memory attributes are preserved. Don't call
ix86_set_move_mem_attrs.
(ix86_set_move_mem_attrs_1, ix86_set_move_mem_attrs): Removed.
(ix86_expand_clrstr): Rename src argument to
dst. Rework rep_stos and strset handling so that memory attributes
are preserved.
(ix86_expand_strlen): Pass src argument to
ix86_expand_strlensi_unroll_1. Rework strlenqi_1 handling so that
memory attributes are preserved.
(ix86_expand_strlensi_unroll_1): Add src argument. Use
change_address instead of gen_rtx_MEM.
* config/i386/i386.md (strmov, strmov_singleop, rep_mov): New
expanders.
(strmovdi_rex64, strmovsi, strmovsi_rex64, strmovhi, strmovhi_rex64,
strmovqi, strmovqi_rex64): Remove.
(rep_mov*, strmov*): Prefix insn names with *.
(strset, strset_singleop, rep_stos): New expanders.
(strsetdi_rex64, strsetsi, strsetsi_rex64, strsethi, strsethi_rex64,
strsetqi, strsetqi_rex64): Remove.
(rep_stos*, strset*): Prefix insn names with *.
(rep_stosqi_rex64): Likewise. Fix mode of dirflag reg from DImode
to SImode.
(cmpstrsi): Rework cmpstrqi_1 handling so that memory attributes
are preserved.
(cmpstrqi_nz_1, cmpstrqi_nz_rex_1, cmpstrqi_1, cmpstrqi_rex_1):
Prefix insn names with *.
(cmpstrqi_nz_1, cmpstrqi_1): New expanders.
(strlenqi_1, strlenqi_rex_1): Prefix insn names with *.
(strlenqi_1): New expander.
* config/i386/i386.h (ix86_set_move_mem_attrs): Remove prototype.
2004-01-29 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz> 2004-01-29 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* Makefile.in (cfghooks.o): Add TIMEVAR_H and toplev.h dependency. * Makefile.in (cfghooks.o): Add TIMEVAR_H and toplev.h dependency.
......
...@@ -178,7 +178,6 @@ extern int ix86_secondary_memory_needed (enum reg_class, enum reg_class, ...@@ -178,7 +178,6 @@ extern int ix86_secondary_memory_needed (enum reg_class, enum reg_class,
enum machine_mode, int); enum machine_mode, int);
extern enum reg_class ix86_preferred_reload_class (rtx, enum reg_class); extern enum reg_class ix86_preferred_reload_class (rtx, enum reg_class);
extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int); extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int);
extern void ix86_set_move_mem_attrs (rtx, rtx, rtx, rtx, rtx);
extern void emit_i387_cw_initialization (rtx, rtx); extern void emit_i387_cw_initialization (rtx, rtx);
extern bool ix86_fp_jump_nontrivial_p (enum rtx_code); extern bool ix86_fp_jump_nontrivial_p (enum rtx_code);
extern void x86_order_regs_for_local_alloc (void); extern void x86_order_regs_for_local_alloc (void);
......
...@@ -813,12 +813,11 @@ static void ix86_emit_save_regs (void); ...@@ -813,12 +813,11 @@ static void ix86_emit_save_regs (void);
static void ix86_emit_save_regs_using_mov (rtx, HOST_WIDE_INT); static void ix86_emit_save_regs_using_mov (rtx, HOST_WIDE_INT);
static void ix86_emit_restore_regs_using_mov (rtx, HOST_WIDE_INT, int); static void ix86_emit_restore_regs_using_mov (rtx, HOST_WIDE_INT, int);
static void ix86_output_function_epilogue (FILE *, HOST_WIDE_INT); static void ix86_output_function_epilogue (FILE *, HOST_WIDE_INT);
static void ix86_set_move_mem_attrs_1 (rtx, rtx, rtx, rtx, rtx);
static void ix86_sched_reorder_ppro (rtx *, rtx *); static void ix86_sched_reorder_ppro (rtx *, rtx *);
static HOST_WIDE_INT ix86_GOT_alias_set (void); static HOST_WIDE_INT ix86_GOT_alias_set (void);
static void ix86_adjust_counter (rtx, HOST_WIDE_INT); static void ix86_adjust_counter (rtx, HOST_WIDE_INT);
static rtx ix86_expand_aligntest (rtx, int); static rtx ix86_expand_aligntest (rtx, int);
static void ix86_expand_strlensi_unroll_1 (rtx, rtx); static void ix86_expand_strlensi_unroll_1 (rtx, rtx, rtx);
static int ix86_issue_rate (void); static int ix86_issue_rate (void);
static int ix86_adjust_cost (rtx, rtx, rtx, int); static int ix86_adjust_cost (rtx, rtx, rtx, int);
static void ix86_sched_init (FILE *, int, int); static void ix86_sched_init (FILE *, int, int);
...@@ -11020,11 +11019,10 @@ ix86_zero_extend_to_Pmode (rtx exp) ...@@ -11020,11 +11019,10 @@ ix86_zero_extend_to_Pmode (rtx exp)
int int
ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp) ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp)
{ {
rtx srcreg, destreg, countreg; rtx srcreg, destreg, countreg, srcexp, destexp;
enum machine_mode counter_mode; enum machine_mode counter_mode;
HOST_WIDE_INT align = 0; HOST_WIDE_INT align = 0;
unsigned HOST_WIDE_INT count = 0; unsigned HOST_WIDE_INT count = 0;
rtx insns;
if (GET_CODE (align_exp) == CONST_INT) if (GET_CODE (align_exp) == CONST_INT)
align = INTVAL (align_exp); align = INTVAL (align_exp);
...@@ -11053,28 +11051,27 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp) ...@@ -11053,28 +11051,27 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp)
else else
counter_mode = DImode; counter_mode = DImode;
start_sequence ();
if (counter_mode != SImode && counter_mode != DImode) if (counter_mode != SImode && counter_mode != DImode)
abort (); abort ();
destreg = copy_to_mode_reg (Pmode, XEXP (dst, 0)); destreg = copy_to_mode_reg (Pmode, XEXP (dst, 0));
if (destreg != XEXP (dst, 0))
dst = replace_equiv_address_nv (dst, destreg);
srcreg = copy_to_mode_reg (Pmode, XEXP (src, 0)); srcreg = copy_to_mode_reg (Pmode, XEXP (src, 0));
if (srcreg != XEXP (src, 0))
emit_insn (gen_cld ()); src = replace_equiv_address_nv (src, srcreg);
/* When optimizing for size emit simple rep ; movsb instruction for /* When optimizing for size emit simple rep ; movsb instruction for
counts not divisible by 4. */ counts not divisible by 4. */
if ((!optimize || optimize_size) && (count == 0 || (count & 0x03))) if ((!optimize || optimize_size) && (count == 0 || (count & 0x03)))
{ {
emit_insn (gen_cld ());
countreg = ix86_zero_extend_to_Pmode (count_exp); countreg = ix86_zero_extend_to_Pmode (count_exp);
if (TARGET_64BIT) destexp = gen_rtx_PLUS (Pmode, destreg, countreg);
emit_insn (gen_rep_movqi_rex64 (destreg, srcreg, countreg, srcexp = gen_rtx_PLUS (Pmode, srcreg, countreg);
destreg, srcreg, countreg)); emit_insn (gen_rep_mov (destreg, dst, srcreg, src, countreg,
else destexp, srcexp));
emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
destreg, srcreg, countreg));
} }
/* For constant aligned (or small unaligned) copies use rep movsl /* For constant aligned (or small unaligned) copies use rep movsl
...@@ -11086,32 +11083,53 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp) ...@@ -11086,32 +11083,53 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp)
|| (!TARGET_PENTIUMPRO && !TARGET_64BIT && align >= 4) || (!TARGET_PENTIUMPRO && !TARGET_64BIT && align >= 4)
|| optimize_size || count < (unsigned int) 64)) || optimize_size || count < (unsigned int) 64))
{ {
unsigned HOST_WIDE_INT offset = 0;
int size = TARGET_64BIT && !optimize_size ? 8 : 4; int size = TARGET_64BIT && !optimize_size ? 8 : 4;
rtx srcmem, dstmem;
emit_insn (gen_cld ());
if (count & ~(size - 1)) if (count & ~(size - 1))
{ {
countreg = copy_to_mode_reg (counter_mode, countreg = copy_to_mode_reg (counter_mode,
GEN_INT ((count >> (size == 4 ? 2 : 3)) GEN_INT ((count >> (size == 4 ? 2 : 3))
& (TARGET_64BIT ? -1 : 0x3fffffff))); & (TARGET_64BIT ? -1 : 0x3fffffff)));
countreg = ix86_zero_extend_to_Pmode (countreg); countreg = ix86_zero_extend_to_Pmode (countreg);
if (size == 4)
{ destexp = gen_rtx_ASHIFT (Pmode, countreg,
if (TARGET_64BIT) GEN_INT (size == 4 ? 2 : 3));
emit_insn (gen_rep_movsi_rex64 (destreg, srcreg, countreg, srcexp = gen_rtx_PLUS (Pmode, destexp, srcreg);
destreg, srcreg, countreg)); destexp = gen_rtx_PLUS (Pmode, destexp, destreg);
else
emit_insn (gen_rep_movsi (destreg, srcreg, countreg, emit_insn (gen_rep_mov (destreg, dst, srcreg, src,
destreg, srcreg, countreg)); countreg, destexp, srcexp));
} offset = count & ~(size - 1);
else
emit_insn (gen_rep_movdi_rex64 (destreg, srcreg, countreg,
destreg, srcreg, countreg));
} }
if (size == 8 && (count & 0x04)) if (size == 8 && (count & 0x04))
emit_insn (gen_strmovsi (destreg, srcreg)); {
srcmem = adjust_automodify_address_nv (src, SImode, srcreg,
offset);
dstmem = adjust_automodify_address_nv (dst, SImode, destreg,
offset);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
offset += 4;
}
if (count & 0x02) if (count & 0x02)
emit_insn (gen_strmovhi (destreg, srcreg)); {
srcmem = adjust_automodify_address_nv (src, HImode, srcreg,
offset);
dstmem = adjust_automodify_address_nv (dst, HImode, destreg,
offset);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
offset += 2;
}
if (count & 0x01) if (count & 0x01)
emit_insn (gen_strmovqi (destreg, srcreg)); {
srcmem = adjust_automodify_address_nv (src, QImode, srcreg,
offset);
dstmem = adjust_automodify_address_nv (dst, QImode, destreg,
offset);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
}
} }
/* The generic code based on the glibc implementation: /* The generic code based on the glibc implementation:
- align destination to 4 bytes (8 byte alignment is used for PentiumPro - align destination to 4 bytes (8 byte alignment is used for PentiumPro
...@@ -11122,9 +11140,13 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp) ...@@ -11122,9 +11140,13 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp)
{ {
rtx countreg2; rtx countreg2;
rtx label = NULL; rtx label = NULL;
rtx srcmem, dstmem;
int desired_alignment = (TARGET_PENTIUMPRO int desired_alignment = (TARGET_PENTIUMPRO
&& (count == 0 || count >= (unsigned int) 260) && (count == 0 || count >= (unsigned int) 260)
? 8 : UNITS_PER_WORD); ? 8 : UNITS_PER_WORD);
/* Get rid of MEM_OFFSETs, they won't be accurate. */
dst = change_address (dst, BLKmode, destreg);
src = change_address (src, BLKmode, srcreg);
/* In case we don't know anything about the alignment, default to /* In case we don't know anything about the alignment, default to
library version, since it is usually equally fast and result in library version, since it is usually equally fast and result in
...@@ -11134,10 +11156,7 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp) ...@@ -11134,10 +11156,7 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp)
will not be important. */ will not be important. */
if (!TARGET_INLINE_ALL_STRINGOPS if (!TARGET_INLINE_ALL_STRINGOPS
&& (align < UNITS_PER_WORD || !TARGET_REP_MOVL_OPTIMAL)) && (align < UNITS_PER_WORD || !TARGET_REP_MOVL_OPTIMAL))
{
end_sequence ();
return 0; return 0;
}
if (TARGET_SINGLE_STRINGOP) if (TARGET_SINGLE_STRINGOP)
emit_insn (gen_cld ()); emit_insn (gen_cld ());
...@@ -11167,7 +11186,9 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp) ...@@ -11167,7 +11186,9 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp)
if (align <= 1) if (align <= 1)
{ {
rtx label = ix86_expand_aligntest (destreg, 1); rtx label = ix86_expand_aligntest (destreg, 1);
emit_insn (gen_strmovqi (destreg, srcreg)); srcmem = change_address (src, QImode, srcreg);
dstmem = change_address (dst, QImode, destreg);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
ix86_adjust_counter (countreg, 1); ix86_adjust_counter (countreg, 1);
emit_label (label); emit_label (label);
LABEL_NUSES (label) = 1; LABEL_NUSES (label) = 1;
...@@ -11175,7 +11196,9 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp) ...@@ -11175,7 +11196,9 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp)
if (align <= 2) if (align <= 2)
{ {
rtx label = ix86_expand_aligntest (destreg, 2); rtx label = ix86_expand_aligntest (destreg, 2);
emit_insn (gen_strmovhi (destreg, srcreg)); srcmem = change_address (src, HImode, srcreg);
dstmem = change_address (dst, HImode, destreg);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
ix86_adjust_counter (countreg, 2); ix86_adjust_counter (countreg, 2);
emit_label (label); emit_label (label);
LABEL_NUSES (label) = 1; LABEL_NUSES (label) = 1;
...@@ -11183,7 +11206,9 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp) ...@@ -11183,7 +11206,9 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp)
if (align <= 4 && desired_alignment > 4) if (align <= 4 && desired_alignment > 4)
{ {
rtx label = ix86_expand_aligntest (destreg, 4); rtx label = ix86_expand_aligntest (destreg, 4);
emit_insn (gen_strmovsi (destreg, srcreg)); srcmem = change_address (src, SImode, srcreg);
dstmem = change_address (dst, SImode, destreg);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
ix86_adjust_counter (countreg, 4); ix86_adjust_counter (countreg, 4);
emit_label (label); emit_label (label);
LABEL_NUSES (label) = 1; LABEL_NUSES (label) = 1;
...@@ -11201,15 +11226,17 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp) ...@@ -11201,15 +11226,17 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp)
{ {
emit_insn (gen_lshrdi3 (countreg2, ix86_zero_extend_to_Pmode (countreg), emit_insn (gen_lshrdi3 (countreg2, ix86_zero_extend_to_Pmode (countreg),
GEN_INT (3))); GEN_INT (3)));
emit_insn (gen_rep_movdi_rex64 (destreg, srcreg, countreg2, destexp = gen_rtx_ASHIFT (Pmode, countreg2, GEN_INT (3));
destreg, srcreg, countreg2));
} }
else else
{ {
emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2))); emit_insn (gen_lshrsi3 (countreg2, countreg, const2_rtx));
emit_insn (gen_rep_movsi (destreg, srcreg, countreg2, destexp = gen_rtx_ASHIFT (Pmode, countreg2, const2_rtx);
destreg, srcreg, countreg2));
} }
srcexp = gen_rtx_PLUS (Pmode, destexp, srcreg);
destexp = gen_rtx_PLUS (Pmode, destexp, destreg);
emit_insn (gen_rep_mov (destreg, dst, srcreg, src,
countreg2, destexp, srcexp));
if (label) if (label)
{ {
...@@ -11217,48 +11244,61 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp) ...@@ -11217,48 +11244,61 @@ ix86_expand_movstr (rtx dst, rtx src, rtx count_exp, rtx align_exp)
LABEL_NUSES (label) = 1; LABEL_NUSES (label) = 1;
} }
if (TARGET_64BIT && align > 4 && count != 0 && (count & 4)) if (TARGET_64BIT && align > 4 && count != 0 && (count & 4))
emit_insn (gen_strmovsi (destreg, srcreg)); {
srcmem = change_address (src, SImode, srcreg);
dstmem = change_address (dst, SImode, destreg);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
}
if ((align <= 4 || count == 0) && TARGET_64BIT) if ((align <= 4 || count == 0) && TARGET_64BIT)
{ {
rtx label = ix86_expand_aligntest (countreg, 4); rtx label = ix86_expand_aligntest (countreg, 4);
emit_insn (gen_strmovsi (destreg, srcreg)); srcmem = change_address (src, SImode, srcreg);
dstmem = change_address (dst, SImode, destreg);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
emit_label (label); emit_label (label);
LABEL_NUSES (label) = 1; LABEL_NUSES (label) = 1;
} }
if (align > 2 && count != 0 && (count & 2)) if (align > 2 && count != 0 && (count & 2))
emit_insn (gen_strmovhi (destreg, srcreg)); {
srcmem = change_address (src, HImode, srcreg);
dstmem = change_address (dst, HImode, destreg);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
}
if (align <= 2 || count == 0) if (align <= 2 || count == 0)
{ {
rtx label = ix86_expand_aligntest (countreg, 2); rtx label = ix86_expand_aligntest (countreg, 2);
emit_insn (gen_strmovhi (destreg, srcreg)); srcmem = change_address (src, HImode, srcreg);
dstmem = change_address (dst, HImode, destreg);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
emit_label (label); emit_label (label);
LABEL_NUSES (label) = 1; LABEL_NUSES (label) = 1;
} }
if (align > 1 && count != 0 && (count & 1)) if (align > 1 && count != 0 && (count & 1))
emit_insn (gen_strmovqi (destreg, srcreg)); {
srcmem = change_address (src, QImode, srcreg);
dstmem = change_address (dst, QImode, destreg);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
}
if (align <= 1 || count == 0) if (align <= 1 || count == 0)
{ {
rtx label = ix86_expand_aligntest (countreg, 1); rtx label = ix86_expand_aligntest (countreg, 1);
emit_insn (gen_strmovqi (destreg, srcreg)); srcmem = change_address (src, QImode, srcreg);
dstmem = change_address (dst, QImode, destreg);
emit_insn (gen_strmov (destreg, dstmem, srcreg, srcmem));
emit_label (label); emit_label (label);
LABEL_NUSES (label) = 1; LABEL_NUSES (label) = 1;
} }
} }
insns = get_insns ();
end_sequence ();
ix86_set_move_mem_attrs (insns, dst, src, destreg, srcreg);
emit_insn (insns);
return 1; return 1;
} }
/* Expand string clear operation (bzero). Use i386 string operations when /* Expand string clear operation (bzero). Use i386 string operations when
profitable. expand_movstr contains similar code. */ profitable. expand_movstr contains similar code. */
int int
ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ix86_expand_clrstr (rtx dst, rtx count_exp, rtx align_exp)
{ {
rtx destreg, zeroreg, countreg; rtx destreg, zeroreg, countreg, destexp;
enum machine_mode counter_mode; enum machine_mode counter_mode;
HOST_WIDE_INT align = 0; HOST_WIDE_INT align = 0;
unsigned HOST_WIDE_INT count = 0; unsigned HOST_WIDE_INT count = 0;
...@@ -11289,7 +11329,9 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ...@@ -11289,7 +11329,9 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp)
else else
counter_mode = DImode; counter_mode = DImode;
destreg = copy_to_mode_reg (Pmode, XEXP (src, 0)); destreg = copy_to_mode_reg (Pmode, XEXP (dst, 0));
if (destreg != XEXP (dst, 0))
dst = replace_equiv_address_nv (dst, destreg);
emit_insn (gen_cld ()); emit_insn (gen_cld ());
...@@ -11300,12 +11342,8 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ...@@ -11300,12 +11342,8 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp)
{ {
countreg = ix86_zero_extend_to_Pmode (count_exp); countreg = ix86_zero_extend_to_Pmode (count_exp);
zeroreg = copy_to_mode_reg (QImode, const0_rtx); zeroreg = copy_to_mode_reg (QImode, const0_rtx);
if (TARGET_64BIT) destexp = gen_rtx_PLUS (Pmode, destreg, countreg);
emit_insn (gen_rep_stosqi_rex64 (destreg, countreg, zeroreg, emit_insn (gen_rep_stos (destreg, countreg, dst, zeroreg, destexp));
destreg, countreg));
else
emit_insn (gen_rep_stosqi (destreg, countreg, zeroreg,
destreg, countreg));
} }
else if (count != 0 else if (count != 0
&& (align >= 8 && (align >= 8
...@@ -11313,6 +11351,8 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ...@@ -11313,6 +11351,8 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp)
|| optimize_size || count < (unsigned int) 64)) || optimize_size || count < (unsigned int) 64))
{ {
int size = TARGET_64BIT && !optimize_size ? 8 : 4; int size = TARGET_64BIT && !optimize_size ? 8 : 4;
unsigned HOST_WIDE_INT offset = 0;
zeroreg = copy_to_mode_reg (size == 4 ? SImode : DImode, const0_rtx); zeroreg = copy_to_mode_reg (size == 4 ? SImode : DImode, const0_rtx);
if (count & ~(size - 1)) if (count & ~(size - 1))
{ {
...@@ -11320,29 +11360,35 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ...@@ -11320,29 +11360,35 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp)
GEN_INT ((count >> (size == 4 ? 2 : 3)) GEN_INT ((count >> (size == 4 ? 2 : 3))
& (TARGET_64BIT ? -1 : 0x3fffffff))); & (TARGET_64BIT ? -1 : 0x3fffffff)));
countreg = ix86_zero_extend_to_Pmode (countreg); countreg = ix86_zero_extend_to_Pmode (countreg);
if (size == 4) destexp = gen_rtx_ASHIFT (Pmode, countreg, GEN_INT (size == 4 ? 2 : 3));
{ destexp = gen_rtx_PLUS (Pmode, destexp, destreg);
if (TARGET_64BIT) emit_insn (gen_rep_stos (destreg, countreg, dst, zeroreg, destexp));
emit_insn (gen_rep_stossi_rex64 (destreg, countreg, zeroreg, offset = count & ~(size - 1);
destreg, countreg));
else
emit_insn (gen_rep_stossi (destreg, countreg, zeroreg,
destreg, countreg));
}
else
emit_insn (gen_rep_stosdi_rex64 (destreg, countreg, zeroreg,
destreg, countreg));
} }
if (size == 8 && (count & 0x04)) if (size == 8 && (count & 0x04))
emit_insn (gen_strsetsi (destreg, {
rtx mem = adjust_automodify_address_nv (dst, SImode, destreg,
offset);
emit_insn (gen_strset (destreg, mem,
gen_rtx_SUBREG (SImode, zeroreg, 0))); gen_rtx_SUBREG (SImode, zeroreg, 0)));
offset += 4;
}
if (count & 0x02) if (count & 0x02)
emit_insn (gen_strsethi (destreg, {
rtx mem = adjust_automodify_address_nv (dst, HImode, destreg,
offset);
emit_insn (gen_strset (destreg, mem,
gen_rtx_SUBREG (HImode, zeroreg, 0))); gen_rtx_SUBREG (HImode, zeroreg, 0)));
offset += 2;
}
if (count & 0x01) if (count & 0x01)
emit_insn (gen_strsetqi (destreg, {
rtx mem = adjust_automodify_address_nv (dst, QImode, destreg,
offset);
emit_insn (gen_strset (destreg, mem,
gen_rtx_SUBREG (QImode, zeroreg, 0))); gen_rtx_SUBREG (QImode, zeroreg, 0)));
} }
}
else else
{ {
rtx countreg2; rtx countreg2;
...@@ -11368,6 +11414,8 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ...@@ -11368,6 +11414,8 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp)
countreg2 = gen_reg_rtx (Pmode); countreg2 = gen_reg_rtx (Pmode);
countreg = copy_to_mode_reg (counter_mode, count_exp); countreg = copy_to_mode_reg (counter_mode, count_exp);
zeroreg = copy_to_mode_reg (Pmode, const0_rtx); zeroreg = copy_to_mode_reg (Pmode, const0_rtx);
/* Get rid of MEM_OFFSET, it won't be accurate. */
dst = change_address (dst, BLKmode, destreg);
if (count == 0 && align < desired_alignment) if (count == 0 && align < desired_alignment)
{ {
...@@ -11378,7 +11426,7 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ...@@ -11378,7 +11426,7 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp)
if (align <= 1) if (align <= 1)
{ {
rtx label = ix86_expand_aligntest (destreg, 1); rtx label = ix86_expand_aligntest (destreg, 1);
emit_insn (gen_strsetqi (destreg, emit_insn (gen_strset (destreg, dst,
gen_rtx_SUBREG (QImode, zeroreg, 0))); gen_rtx_SUBREG (QImode, zeroreg, 0)));
ix86_adjust_counter (countreg, 1); ix86_adjust_counter (countreg, 1);
emit_label (label); emit_label (label);
...@@ -11387,7 +11435,7 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ...@@ -11387,7 +11435,7 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp)
if (align <= 2) if (align <= 2)
{ {
rtx label = ix86_expand_aligntest (destreg, 2); rtx label = ix86_expand_aligntest (destreg, 2);
emit_insn (gen_strsethi (destreg, emit_insn (gen_strset (destreg, dst,
gen_rtx_SUBREG (HImode, zeroreg, 0))); gen_rtx_SUBREG (HImode, zeroreg, 0)));
ix86_adjust_counter (countreg, 2); ix86_adjust_counter (countreg, 2);
emit_label (label); emit_label (label);
...@@ -11396,7 +11444,8 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ...@@ -11396,7 +11444,8 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp)
if (align <= 4 && desired_alignment > 4) if (align <= 4 && desired_alignment > 4)
{ {
rtx label = ix86_expand_aligntest (destreg, 4); rtx label = ix86_expand_aligntest (destreg, 4);
emit_insn (gen_strsetsi (destreg, (TARGET_64BIT emit_insn (gen_strset (destreg, dst,
(TARGET_64BIT
? gen_rtx_SUBREG (SImode, zeroreg, 0) ? gen_rtx_SUBREG (SImode, zeroreg, 0)
: zeroreg))); : zeroreg)));
ix86_adjust_counter (countreg, 4); ix86_adjust_counter (countreg, 4);
...@@ -11417,15 +11466,16 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ...@@ -11417,15 +11466,16 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp)
{ {
emit_insn (gen_lshrdi3 (countreg2, ix86_zero_extend_to_Pmode (countreg), emit_insn (gen_lshrdi3 (countreg2, ix86_zero_extend_to_Pmode (countreg),
GEN_INT (3))); GEN_INT (3)));
emit_insn (gen_rep_stosdi_rex64 (destreg, countreg2, zeroreg, destexp = gen_rtx_ASHIFT (Pmode, countreg2, GEN_INT (3));
destreg, countreg2));
} }
else else
{ {
emit_insn (gen_lshrsi3 (countreg2, countreg, GEN_INT (2))); emit_insn (gen_lshrsi3 (countreg2, countreg, const2_rtx));
emit_insn (gen_rep_stossi (destreg, countreg2, zeroreg, destexp = gen_rtx_ASHIFT (Pmode, countreg2, const2_rtx);
destreg, countreg2));
} }
destexp = gen_rtx_PLUS (Pmode, destexp, destreg);
emit_insn (gen_rep_stos (destreg, countreg2, dst, zeroreg, destexp));
if (label) if (label)
{ {
emit_label (label); emit_label (label);
...@@ -11433,34 +11483,34 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ...@@ -11433,34 +11483,34 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp)
} }
if (TARGET_64BIT && align > 4 && count != 0 && (count & 4)) if (TARGET_64BIT && align > 4 && count != 0 && (count & 4))
emit_insn (gen_strsetsi (destreg, emit_insn (gen_strset (destreg, dst,
gen_rtx_SUBREG (SImode, zeroreg, 0))); gen_rtx_SUBREG (SImode, zeroreg, 0)));
if (TARGET_64BIT && (align <= 4 || count == 0)) if (TARGET_64BIT && (align <= 4 || count == 0))
{ {
rtx label = ix86_expand_aligntest (countreg, 4); rtx label = ix86_expand_aligntest (countreg, 4);
emit_insn (gen_strsetsi (destreg, emit_insn (gen_strset (destreg, dst,
gen_rtx_SUBREG (SImode, zeroreg, 0))); gen_rtx_SUBREG (SImode, zeroreg, 0)));
emit_label (label); emit_label (label);
LABEL_NUSES (label) = 1; LABEL_NUSES (label) = 1;
} }
if (align > 2 && count != 0 && (count & 2)) if (align > 2 && count != 0 && (count & 2))
emit_insn (gen_strsethi (destreg, emit_insn (gen_strset (destreg, dst,
gen_rtx_SUBREG (HImode, zeroreg, 0))); gen_rtx_SUBREG (HImode, zeroreg, 0)));
if (align <= 2 || count == 0) if (align <= 2 || count == 0)
{ {
rtx label = ix86_expand_aligntest (countreg, 2); rtx label = ix86_expand_aligntest (countreg, 2);
emit_insn (gen_strsethi (destreg, emit_insn (gen_strset (destreg, dst,
gen_rtx_SUBREG (HImode, zeroreg, 0))); gen_rtx_SUBREG (HImode, zeroreg, 0)));
emit_label (label); emit_label (label);
LABEL_NUSES (label) = 1; LABEL_NUSES (label) = 1;
} }
if (align > 1 && count != 0 && (count & 1)) if (align > 1 && count != 0 && (count & 1))
emit_insn (gen_strsetqi (destreg, emit_insn (gen_strset (destreg, dst,
gen_rtx_SUBREG (QImode, zeroreg, 0))); gen_rtx_SUBREG (QImode, zeroreg, 0)));
if (align <= 1 || count == 0) if (align <= 1 || count == 0)
{ {
rtx label = ix86_expand_aligntest (countreg, 1); rtx label = ix86_expand_aligntest (countreg, 1);
emit_insn (gen_strsetqi (destreg, emit_insn (gen_strset (destreg, dst,
gen_rtx_SUBREG (QImode, zeroreg, 0))); gen_rtx_SUBREG (QImode, zeroreg, 0)));
emit_label (label); emit_label (label);
LABEL_NUSES (label) = 1; LABEL_NUSES (label) = 1;
...@@ -11468,6 +11518,7 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp) ...@@ -11468,6 +11518,7 @@ ix86_expand_clrstr (rtx src, rtx count_exp, rtx align_exp)
} }
return 1; return 1;
} }
/* Expand strlen. */ /* Expand strlen. */
int int
ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align) ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align)
...@@ -11499,7 +11550,7 @@ ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align) ...@@ -11499,7 +11550,7 @@ ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align)
emit_move_insn (out, addr); emit_move_insn (out, addr);
ix86_expand_strlensi_unroll_1 (out, align); ix86_expand_strlensi_unroll_1 (out, src, align);
/* strlensi_unroll_1 returns the address of the zero at the end of /* strlensi_unroll_1 returns the address of the zero at the end of
the string, like memchr(), so compute the length by subtracting the string, like memchr(), so compute the length by subtracting
...@@ -11511,6 +11562,7 @@ ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align) ...@@ -11511,6 +11562,7 @@ ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align)
} }
else else
{ {
rtx unspec;
scratch2 = gen_reg_rtx (Pmode); scratch2 = gen_reg_rtx (Pmode);
scratch3 = gen_reg_rtx (Pmode); scratch3 = gen_reg_rtx (Pmode);
scratch4 = force_reg (Pmode, constm1_rtx); scratch4 = force_reg (Pmode, constm1_rtx);
...@@ -11519,17 +11571,19 @@ ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align) ...@@ -11519,17 +11571,19 @@ ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align)
eoschar = force_reg (QImode, eoschar); eoschar = force_reg (QImode, eoschar);
emit_insn (gen_cld ()); emit_insn (gen_cld ());
src = replace_equiv_address_nv (src, scratch3);
/* If .md starts supporting :P, this can be done in .md. */
unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (4, src, eoschar, align,
scratch4), UNSPEC_SCAS);
emit_insn (gen_strlenqi_1 (scratch1, scratch3, unspec));
if (TARGET_64BIT) if (TARGET_64BIT)
{ {
emit_insn (gen_strlenqi_rex_1 (scratch1, scratch3, eoschar,
align, scratch4, scratch3));
emit_insn (gen_one_cmpldi2 (scratch2, scratch1)); emit_insn (gen_one_cmpldi2 (scratch2, scratch1));
emit_insn (gen_adddi3 (out, scratch2, constm1_rtx)); emit_insn (gen_adddi3 (out, scratch2, constm1_rtx));
} }
else else
{ {
emit_insn (gen_strlenqi_1 (scratch1, scratch3, eoschar,
align, scratch4, scratch3));
emit_insn (gen_one_cmplsi2 (scratch2, scratch1)); emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
emit_insn (gen_addsi3 (out, scratch2, constm1_rtx)); emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
} }
...@@ -11549,7 +11603,7 @@ ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align) ...@@ -11549,7 +11603,7 @@ ix86_expand_strlen (rtx out, rtx src, rtx eoschar, rtx align)
some address computing at the end. These things are done in i386.md. */ some address computing at the end. These things are done in i386.md. */
static void static void
ix86_expand_strlensi_unroll_1 (rtx out, rtx align_rtx) ix86_expand_strlensi_unroll_1 (rtx out, rtx src, rtx align_rtx)
{ {
int align; int align;
rtx tmp; rtx tmp;
...@@ -11602,7 +11656,7 @@ ix86_expand_strlensi_unroll_1 (rtx out, rtx align_rtx) ...@@ -11602,7 +11656,7 @@ ix86_expand_strlensi_unroll_1 (rtx out, rtx align_rtx)
Pmode, 1, align_4_label); Pmode, 1, align_4_label);
} }
mem = gen_rtx_MEM (QImode, out); mem = change_address (src, QImode, out);
/* Now compare the bytes. */ /* Now compare the bytes. */
...@@ -11646,7 +11700,7 @@ ix86_expand_strlensi_unroll_1 (rtx out, rtx align_rtx) ...@@ -11646,7 +11700,7 @@ ix86_expand_strlensi_unroll_1 (rtx out, rtx align_rtx)
speed up. */ speed up. */
emit_label (align_4_label); emit_label (align_4_label);
mem = gen_rtx_MEM (SImode, out); mem = change_address (src, SImode, out);
emit_move_insn (scratch, mem); emit_move_insn (scratch, mem);
if (TARGET_64BIT) if (TARGET_64BIT)
emit_insn (gen_adddi3 (out, out, GEN_INT (4))); emit_insn (gen_adddi3 (out, out, GEN_INT (4)));
...@@ -12511,50 +12565,6 @@ ia32_multipass_dfa_lookahead (void) ...@@ -12511,50 +12565,6 @@ ia32_multipass_dfa_lookahead (void)
} }
/* Walk through INSNS and look for MEM references whose address is DSTREG or
SRCREG and set the memory attribute to those of DSTREF and SRCREF, as
appropriate. */
void
ix86_set_move_mem_attrs (rtx insns, rtx dstref, rtx srcref, rtx dstreg,
rtx srcreg)
{
rtx insn;
for (insn = insns; insn != 0 ; insn = NEXT_INSN (insn))
if (INSN_P (insn))
ix86_set_move_mem_attrs_1 (PATTERN (insn), dstref, srcref,
dstreg, srcreg);
}
/* Subroutine of above to actually do the updating by recursively walking
the rtx. */
static void
ix86_set_move_mem_attrs_1 (rtx x, rtx dstref, rtx srcref, rtx dstreg,
rtx srcreg)
{
enum rtx_code code = GET_CODE (x);
const char *format_ptr = GET_RTX_FORMAT (code);
int i, j;
if (code == MEM && XEXP (x, 0) == dstreg)
MEM_COPY_ATTRIBUTES (x, dstref);
else if (code == MEM && XEXP (x, 0) == srcreg)
MEM_COPY_ATTRIBUTES (x, srcref);
for (i = 0; i < GET_RTX_LENGTH (code); i++, format_ptr++)
{
if (*format_ptr == 'e')
ix86_set_move_mem_attrs_1 (XEXP (x, i), dstref, srcref,
dstreg, srcreg);
else if (*format_ptr == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
ix86_set_move_mem_attrs_1 (XVECEXP (x, i, j), dstref, srcref,
dstreg, srcreg);
}
}
/* Compute the alignment given to a constant that is being placed in memory. /* Compute the alignment given to a constant that is being placed in memory.
EXP is the constant and ALIGN is the alignment that the object would EXP is the constant and ALIGN is the alignment that the object would
ordinarily have. ordinarily have.
......
...@@ -15357,170 +15357,45 @@ ...@@ -15357,170 +15357,45 @@
;; Most CPUs don't like single string operations ;; Most CPUs don't like single string operations
;; Handle this case here to simplify previous expander. ;; Handle this case here to simplify previous expander.
(define_expand "strmovdi_rex64" (define_expand "strmov"
[(set (match_dup 2) [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
(mem:DI (match_operand:DI 1 "register_operand" ""))) (set (match_operand 1 "memory_operand" "") (match_dup 4))
(set (mem:DI (match_operand:DI 0 "register_operand" "")) (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
(match_dup 2))
(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8)))
(clobber (reg:CC 17))]) (clobber (reg:CC 17))])
(parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 8))) (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
(clobber (reg:CC 17))])]
"TARGET_64BIT"
{
if (TARGET_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strmovdi_rex_1 (operands[0], operands[1], operands[0],
operands[1]));
DONE;
}
else
operands[2] = gen_reg_rtx (DImode);
})
(define_expand "strmovsi"
[(set (match_dup 2)
(mem:SI (match_operand:SI 1 "register_operand" "")))
(set (mem:SI (match_operand:SI 0 "register_operand" ""))
(match_dup 2))
(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
(clobber (reg:CC 17))])
(parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 4)))
(clobber (reg:CC 17))])] (clobber (reg:CC 17))])]
"" ""
{ {
if (TARGET_64BIT) rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
{
emit_insn (gen_strmovsi_rex64 (operands[0], operands[1]));
DONE;
}
if (TARGET_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strmovsi_1 (operands[0], operands[1], operands[0],
operands[1]));
DONE;
}
else
operands[2] = gen_reg_rtx (SImode);
})
(define_expand "strmovsi_rex64" /* If .md ever supports :P for Pmode, these can be directly
[(set (match_dup 2) in the pattern above. */
(mem:SI (match_operand:DI 1 "register_operand" ""))) operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
(set (mem:SI (match_operand:DI 0 "register_operand" "")) operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
(match_dup 2))
(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
(clobber (reg:CC 17))])
(parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 4)))
(clobber (reg:CC 17))])]
"TARGET_64BIT"
{
if (TARGET_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strmovsi_rex_1 (operands[0], operands[1], operands[0],
operands[1]));
DONE;
}
else
operands[2] = gen_reg_rtx (SImode);
})
(define_expand "strmovhi"
[(set (match_dup 2)
(mem:HI (match_operand:SI 1 "register_operand" "")))
(set (mem:HI (match_operand:SI 0 "register_operand" ""))
(match_dup 2))
(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
(clobber (reg:CC 17))])
(parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 2)))
(clobber (reg:CC 17))])]
""
{
if (TARGET_64BIT)
{
emit_insn (gen_strmovhi_rex64 (operands[0], operands[1]));
DONE;
}
if (TARGET_SINGLE_STRINGOP || optimize_size) if (TARGET_SINGLE_STRINGOP || optimize_size)
{ {
emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0], emit_insn (gen_strmov_singleop (operands[0], operands[1],
operands[1])); operands[2], operands[3],
DONE; operands[5], operands[6]));
}
else
operands[2] = gen_reg_rtx (HImode);
})
(define_expand "strmovhi_rex64"
[(set (match_dup 2)
(mem:HI (match_operand:DI 1 "register_operand" "")))
(set (mem:HI (match_operand:DI 0 "register_operand" ""))
(match_dup 2))
(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2)))
(clobber (reg:CC 17))])
(parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 2)))
(clobber (reg:CC 17))])]
"TARGET_64BIT"
{
if (TARGET_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strmovhi_rex_1 (operands[0], operands[1], operands[0],
operands[1]));
DONE; DONE;
} }
else
operands[2] = gen_reg_rtx (HImode);
})
(define_expand "strmovqi" operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
[(set (match_dup 2)
(mem:QI (match_operand:SI 1 "register_operand" "")))
(set (mem:QI (match_operand:SI 0 "register_operand" ""))
(match_dup 2))
(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
(clobber (reg:CC 17))])
(parallel [(set (match_dup 1) (plus:SI (match_dup 1) (const_int 1)))
(clobber (reg:CC 17))])]
""
{
if (TARGET_64BIT)
{
emit_insn (gen_strmovqi_rex64 (operands[0], operands[1]));
DONE;
}
if (TARGET_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
operands[1]));
DONE;
}
else
operands[2] = gen_reg_rtx (QImode);
}) })
(define_expand "strmovqi_rex64" (define_expand "strmov_singleop"
[(set (match_dup 2) [(parallel [(set (match_operand 1 "memory_operand" "")
(mem:QI (match_operand:DI 1 "register_operand" ""))) (match_operand 3 "memory_operand" ""))
(set (mem:QI (match_operand:DI 0 "register_operand" "")) (set (match_operand 0 "register_operand" "")
(match_dup 2)) (match_operand 4 "" ""))
(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1))) (set (match_operand 2 "register_operand" "")
(clobber (reg:CC 17))]) (match_operand 5 "" ""))
(parallel [(set (match_dup 1) (plus:DI (match_dup 1) (const_int 1))) (use (reg:SI 19))])]
(clobber (reg:CC 17))])] "TARGET_SINGLE_STRINGOP || optimize_size"
"TARGET_64BIT" "")
{
if (TARGET_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strmovqi_rex_1 (operands[0], operands[1], operands[0],
operands[1]));
DONE;
}
else
operands[2] = gen_reg_rtx (QImode);
})
(define_insn "strmovdi_rex_1" (define_insn "*strmovdi_rex_1"
[(set (mem:DI (match_operand:DI 2 "register_operand" "0")) [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
(mem:DI (match_operand:DI 3 "register_operand" "1"))) (mem:DI (match_operand:DI 3 "register_operand" "1")))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
...@@ -15536,7 +15411,7 @@ ...@@ -15536,7 +15411,7 @@
(set_attr "mode" "DI") (set_attr "mode" "DI")
(set_attr "memory" "both")]) (set_attr "memory" "both")])
(define_insn "strmovsi_1" (define_insn "*strmovsi_1"
[(set (mem:SI (match_operand:SI 2 "register_operand" "0")) [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
(mem:SI (match_operand:SI 3 "register_operand" "1"))) (mem:SI (match_operand:SI 3 "register_operand" "1")))
(set (match_operand:SI 0 "register_operand" "=D") (set (match_operand:SI 0 "register_operand" "=D")
...@@ -15552,7 +15427,7 @@ ...@@ -15552,7 +15427,7 @@
(set_attr "mode" "SI") (set_attr "mode" "SI")
(set_attr "memory" "both")]) (set_attr "memory" "both")])
(define_insn "strmovsi_rex_1" (define_insn "*strmovsi_rex_1"
[(set (mem:SI (match_operand:DI 2 "register_operand" "0")) [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
(mem:SI (match_operand:DI 3 "register_operand" "1"))) (mem:SI (match_operand:DI 3 "register_operand" "1")))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
...@@ -15568,7 +15443,7 @@ ...@@ -15568,7 +15443,7 @@
(set_attr "mode" "SI") (set_attr "mode" "SI")
(set_attr "memory" "both")]) (set_attr "memory" "both")])
(define_insn "strmovhi_1" (define_insn "*strmovhi_1"
[(set (mem:HI (match_operand:SI 2 "register_operand" "0")) [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
(mem:HI (match_operand:SI 3 "register_operand" "1"))) (mem:HI (match_operand:SI 3 "register_operand" "1")))
(set (match_operand:SI 0 "register_operand" "=D") (set (match_operand:SI 0 "register_operand" "=D")
...@@ -15584,7 +15459,7 @@ ...@@ -15584,7 +15459,7 @@
(set_attr "memory" "both") (set_attr "memory" "both")
(set_attr "mode" "HI")]) (set_attr "mode" "HI")])
(define_insn "strmovhi_rex_1" (define_insn "*strmovhi_rex_1"
[(set (mem:HI (match_operand:DI 2 "register_operand" "0")) [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
(mem:HI (match_operand:DI 3 "register_operand" "1"))) (mem:HI (match_operand:DI 3 "register_operand" "1")))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
...@@ -15600,7 +15475,7 @@ ...@@ -15600,7 +15475,7 @@
(set_attr "memory" "both") (set_attr "memory" "both")
(set_attr "mode" "HI")]) (set_attr "mode" "HI")])
(define_insn "strmovqi_1" (define_insn "*strmovqi_1"
[(set (mem:QI (match_operand:SI 2 "register_operand" "0")) [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
(mem:QI (match_operand:SI 3 "register_operand" "1"))) (mem:QI (match_operand:SI 3 "register_operand" "1")))
(set (match_operand:SI 0 "register_operand" "=D") (set (match_operand:SI 0 "register_operand" "=D")
...@@ -15616,7 +15491,7 @@ ...@@ -15616,7 +15491,7 @@
(set_attr "memory" "both") (set_attr "memory" "both")
(set_attr "mode" "QI")]) (set_attr "mode" "QI")])
(define_insn "strmovqi_rex_1" (define_insn "*strmovqi_rex_1"
[(set (mem:QI (match_operand:DI 2 "register_operand" "0")) [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
(mem:QI (match_operand:DI 3 "register_operand" "1"))) (mem:QI (match_operand:DI 3 "register_operand" "1")))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
...@@ -15632,7 +15507,20 @@ ...@@ -15632,7 +15507,20 @@
(set_attr "memory" "both") (set_attr "memory" "both")
(set_attr "mode" "QI")]) (set_attr "mode" "QI")])
(define_insn "rep_movdi_rex64" (define_expand "rep_mov"
[(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
(set (match_operand 0 "register_operand" "")
(match_operand 5 "" ""))
(set (match_operand 2 "register_operand" "")
(match_operand 6 "" ""))
(set (match_operand 1 "memory_operand" "")
(match_operand 3 "memory_operand" ""))
(use (match_dup 4))
(use (reg:SI 19))])]
""
"")
(define_insn "*rep_movdi_rex64"
[(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
...@@ -15652,7 +15540,7 @@ ...@@ -15652,7 +15540,7 @@
(set_attr "memory" "both") (set_attr "memory" "both")
(set_attr "mode" "DI")]) (set_attr "mode" "DI")])
(define_insn "rep_movsi" (define_insn "*rep_movsi"
[(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
(set (match_operand:SI 0 "register_operand" "=D") (set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2") (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
...@@ -15672,7 +15560,7 @@ ...@@ -15672,7 +15560,7 @@
(set_attr "memory" "both") (set_attr "memory" "both")
(set_attr "mode" "SI")]) (set_attr "mode" "SI")])
(define_insn "rep_movsi_rex64" (define_insn "*rep_movsi_rex64"
[(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2") (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
...@@ -15692,7 +15580,7 @@ ...@@ -15692,7 +15580,7 @@
(set_attr "memory" "both") (set_attr "memory" "both")
(set_attr "mode" "SI")]) (set_attr "mode" "SI")])
(define_insn "rep_movqi" (define_insn "*rep_movqi"
[(set (match_operand:SI 2 "register_operand" "=c") (const_int 0)) [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
(set (match_operand:SI 0 "register_operand" "=D") (set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_operand:SI 3 "register_operand" "0") (plus:SI (match_operand:SI 3 "register_operand" "0")
...@@ -15710,7 +15598,7 @@ ...@@ -15710,7 +15598,7 @@
(set_attr "memory" "both") (set_attr "memory" "both")
(set_attr "mode" "SI")]) (set_attr "mode" "SI")])
(define_insn "rep_movqi_rex64" (define_insn "*rep_movqi_rex64"
[(set (match_operand:DI 2 "register_operand" "=c") (const_int 0)) [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (match_operand:DI 3 "register_operand" "0") (plus:DI (match_operand:DI 3 "register_operand" "0")
...@@ -15755,120 +15643,40 @@ ...@@ -15755,120 +15643,40 @@
;; Most CPUs don't like single string operations ;; Most CPUs don't like single string operations
;; Handle this case here to simplify previous expander. ;; Handle this case here to simplify previous expander.
(define_expand "strsetdi_rex64" (define_expand "strset"
[(set (mem:DI (match_operand:DI 0 "register_operand" "")) [(set (match_operand 1 "memory_operand" "")
(match_operand:DI 1 "register_operand" "")) (match_operand 2 "register_operand" ""))
(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 8))) (parallel [(set (match_operand 0 "register_operand" "")
(clobber (reg:CC 17))])] (match_dup 3))
"TARGET_64BIT"
{
if (TARGET_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strsetdi_rex_1 (operands[0], operands[0], operands[1]));
DONE;
}
})
(define_expand "strsetsi"
[(set (mem:SI (match_operand:SI 0 "register_operand" ""))
(match_operand:SI 1 "register_operand" ""))
(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 4)))
(clobber (reg:CC 17))])]
""
{
if (TARGET_64BIT)
{
emit_insn (gen_strsetsi_rex64 (operands[0], operands[1]));
DONE;
}
else if (TARGET_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strsetsi_1 (operands[0], operands[0], operands[1]));
DONE;
}
})
(define_expand "strsetsi_rex64"
[(set (mem:SI (match_operand:DI 0 "register_operand" ""))
(match_operand:SI 1 "register_operand" ""))
(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 4)))
(clobber (reg:CC 17))])]
"TARGET_64BIT"
{
if (TARGET_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strsetsi_rex_1 (operands[0], operands[0], operands[1]));
DONE;
}
})
(define_expand "strsethi"
[(set (mem:HI (match_operand:SI 0 "register_operand" ""))
(match_operand:HI 1 "register_operand" ""))
(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 2)))
(clobber (reg:CC 17))])] (clobber (reg:CC 17))])]
"" ""
{ {
if (TARGET_64BIT) if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
{ operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
emit_insn (gen_strsethi_rex64 (operands[0], operands[1]));
DONE;
}
else if (TARGET_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strsethi_1 (operands[0], operands[0], operands[1]));
DONE;
}
})
(define_expand "strsethi_rex64" /* If .md ever supports :P for Pmode, this can be directly
[(set (mem:HI (match_operand:DI 0 "register_operand" "")) in the pattern above. */
(match_operand:HI 1 "register_operand" "")) operands[3] = gen_rtx_PLUS (Pmode, operands[0],
(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 2))) GEN_INT (GET_MODE_SIZE (GET_MODE
(clobber (reg:CC 17))])] (operands[2]))));
"TARGET_64BIT"
{
if (TARGET_SINGLE_STRINGOP || optimize_size) if (TARGET_SINGLE_STRINGOP || optimize_size)
{ {
emit_insn (gen_strsethi_rex_1 (operands[0], operands[0], operands[1])); emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
DONE; operands[3]));
}
})
(define_expand "strsetqi"
[(set (mem:QI (match_operand:SI 0 "register_operand" ""))
(match_operand:QI 1 "register_operand" ""))
(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
(clobber (reg:CC 17))])]
""
{
if (TARGET_64BIT)
{
emit_insn (gen_strsetqi_rex64 (operands[0], operands[1]));
DONE;
}
else if (TARGET_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strsetqi_1 (operands[0], operands[0], operands[1]));
DONE; DONE;
} }
}) })
(define_expand "strsetqi_rex64" (define_expand "strset_singleop"
[(set (mem:QI (match_operand:DI 0 "register_operand" "")) [(parallel [(set (match_operand 1 "memory_operand" "")
(match_operand:QI 1 "register_operand" "")) (match_operand 2 "register_operand" ""))
(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1))) (set (match_operand 0 "register_operand" "")
(clobber (reg:CC 17))])] (match_operand 3 "" ""))
"TARGET_64BIT" (use (reg:SI 19))])]
{ "TARGET_SINGLE_STRINGOP || optimize_size"
if (TARGET_SINGLE_STRINGOP || optimize_size) "")
{
emit_insn (gen_strsetqi_rex_1 (operands[0], operands[0], operands[1]));
DONE;
}
})
(define_insn "strsetdi_rex_1" (define_insn "*strsetdi_rex_1"
[(set (mem:SI (match_operand:DI 1 "register_operand" "0")) [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
(match_operand:SI 2 "register_operand" "a")) (match_operand:SI 2 "register_operand" "a"))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
...@@ -15881,7 +15689,7 @@ ...@@ -15881,7 +15689,7 @@
(set_attr "memory" "store") (set_attr "memory" "store")
(set_attr "mode" "DI")]) (set_attr "mode" "DI")])
(define_insn "strsetsi_1" (define_insn "*strsetsi_1"
[(set (mem:SI (match_operand:SI 1 "register_operand" "0")) [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
(match_operand:SI 2 "register_operand" "a")) (match_operand:SI 2 "register_operand" "a"))
(set (match_operand:SI 0 "register_operand" "=D") (set (match_operand:SI 0 "register_operand" "=D")
...@@ -15894,7 +15702,7 @@ ...@@ -15894,7 +15702,7 @@
(set_attr "memory" "store") (set_attr "memory" "store")
(set_attr "mode" "SI")]) (set_attr "mode" "SI")])
(define_insn "strsetsi_rex_1" (define_insn "*strsetsi_rex_1"
[(set (mem:SI (match_operand:DI 1 "register_operand" "0")) [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
(match_operand:SI 2 "register_operand" "a")) (match_operand:SI 2 "register_operand" "a"))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
...@@ -15907,7 +15715,7 @@ ...@@ -15907,7 +15715,7 @@
(set_attr "memory" "store") (set_attr "memory" "store")
(set_attr "mode" "SI")]) (set_attr "mode" "SI")])
(define_insn "strsethi_1" (define_insn "*strsethi_1"
[(set (mem:HI (match_operand:SI 1 "register_operand" "0")) [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
(match_operand:HI 2 "register_operand" "a")) (match_operand:HI 2 "register_operand" "a"))
(set (match_operand:SI 0 "register_operand" "=D") (set (match_operand:SI 0 "register_operand" "=D")
...@@ -15920,7 +15728,7 @@ ...@@ -15920,7 +15728,7 @@
(set_attr "memory" "store") (set_attr "memory" "store")
(set_attr "mode" "HI")]) (set_attr "mode" "HI")])
(define_insn "strsethi_rex_1" (define_insn "*strsethi_rex_1"
[(set (mem:HI (match_operand:DI 1 "register_operand" "0")) [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
(match_operand:HI 2 "register_operand" "a")) (match_operand:HI 2 "register_operand" "a"))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
...@@ -15933,7 +15741,7 @@ ...@@ -15933,7 +15741,7 @@
(set_attr "memory" "store") (set_attr "memory" "store")
(set_attr "mode" "HI")]) (set_attr "mode" "HI")])
(define_insn "strsetqi_1" (define_insn "*strsetqi_1"
[(set (mem:QI (match_operand:SI 1 "register_operand" "0")) [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
(match_operand:QI 2 "register_operand" "a")) (match_operand:QI 2 "register_operand" "a"))
(set (match_operand:SI 0 "register_operand" "=D") (set (match_operand:SI 0 "register_operand" "=D")
...@@ -15946,7 +15754,7 @@ ...@@ -15946,7 +15754,7 @@
(set_attr "memory" "store") (set_attr "memory" "store")
(set_attr "mode" "QI")]) (set_attr "mode" "QI")])
(define_insn "strsetqi_rex_1" (define_insn "*strsetqi_rex_1"
[(set (mem:QI (match_operand:DI 1 "register_operand" "0")) [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
(match_operand:QI 2 "register_operand" "a")) (match_operand:QI 2 "register_operand" "a"))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
...@@ -15959,7 +15767,18 @@ ...@@ -15959,7 +15767,18 @@
(set_attr "memory" "store") (set_attr "memory" "store")
(set_attr "mode" "QI")]) (set_attr "mode" "QI")])
(define_insn "rep_stosdi_rex64" (define_expand "rep_stos"
[(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
(set (match_operand 0 "register_operand" "")
(match_operand 4 "" ""))
(set (match_operand 2 "memory_operand" "") (const_int 0))
(use (match_operand 3 "register_operand" ""))
(use (match_dup 1))
(use (reg:SI 19))])]
""
"")
(define_insn "*rep_stosdi_rex64"
[(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
...@@ -15977,7 +15796,7 @@ ...@@ -15977,7 +15796,7 @@
(set_attr "memory" "store") (set_attr "memory" "store")
(set_attr "mode" "DI")]) (set_attr "mode" "DI")])
(define_insn "rep_stossi" (define_insn "*rep_stossi"
[(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
(set (match_operand:SI 0 "register_operand" "=D") (set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1") (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
...@@ -15995,7 +15814,7 @@ ...@@ -15995,7 +15814,7 @@
(set_attr "memory" "store") (set_attr "memory" "store")
(set_attr "mode" "SI")]) (set_attr "mode" "SI")])
(define_insn "rep_stossi_rex64" (define_insn "*rep_stossi_rex64"
[(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1") (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
...@@ -16013,7 +15832,7 @@ ...@@ -16013,7 +15832,7 @@
(set_attr "memory" "store") (set_attr "memory" "store")
(set_attr "mode" "SI")]) (set_attr "mode" "SI")])
(define_insn "rep_stosqi" (define_insn "*rep_stosqi"
[(set (match_operand:SI 1 "register_operand" "=c") (const_int 0)) [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
(set (match_operand:SI 0 "register_operand" "=D") (set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_operand:SI 3 "register_operand" "0") (plus:SI (match_operand:SI 3 "register_operand" "0")
...@@ -16030,7 +15849,7 @@ ...@@ -16030,7 +15849,7 @@
(set_attr "memory" "store") (set_attr "memory" "store")
(set_attr "mode" "QI")]) (set_attr "mode" "QI")])
(define_insn "rep_stosqi_rex64" (define_insn "*rep_stosqi_rex64"
[(set (match_operand:DI 1 "register_operand" "=c") (const_int 0)) [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
(set (match_operand:DI 0 "register_operand" "=D") (set (match_operand:DI 0 "register_operand" "=D")
(plus:DI (match_operand:DI 3 "register_operand" "0") (plus:DI (match_operand:DI 3 "register_operand" "0")
...@@ -16039,7 +15858,7 @@ ...@@ -16039,7 +15858,7 @@
(const_int 0)) (const_int 0))
(use (match_operand:QI 2 "register_operand" "a")) (use (match_operand:QI 2 "register_operand" "a"))
(use (match_dup 4)) (use (match_dup 4))
(use (reg:DI 19))] (use (reg:SI 19))]
"TARGET_64BIT" "TARGET_64BIT"
"{rep\;stosb|rep stosb}" "{rep\;stosb|rep stosb}"
[(set_attr "type" "str") [(set_attr "type" "str")
...@@ -16067,6 +15886,10 @@ ...@@ -16067,6 +15886,10 @@
addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0)); addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0)); addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
if (addr1 != XEXP (operands[1], 0))
operands[1] = replace_equiv_address_nv (operands[1], addr1);
if (addr2 != XEXP (operands[2], 0))
operands[2] = replace_equiv_address_nv (operands[2], addr2);
count = operands[3]; count = operands[3];
countreg = ix86_zero_extend_to_Pmode (count); countreg = ix86_zero_extend_to_Pmode (count);
...@@ -16084,27 +15907,17 @@ ...@@ -16084,27 +15907,17 @@
emit_move_insn (operands[0], const0_rtx); emit_move_insn (operands[0], const0_rtx);
DONE; DONE;
} }
if (TARGET_64BIT)
emit_insn (gen_cmpstrqi_nz_rex_1 (addr1, addr2, countreg, align,
addr1, addr2, countreg));
else
emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align, emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
addr1, addr2, countreg)); operands[1], operands[2]));
} }
else else
{ {
if (TARGET_64BIT) if (TARGET_64BIT)
{
emit_insn (gen_cmpdi_1_rex64 (countreg, countreg)); emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
emit_insn (gen_cmpstrqi_rex_1 (addr1, addr2, countreg, align,
addr1, addr2, countreg));
}
else else
{
emit_insn (gen_cmpsi_1 (countreg, countreg)); emit_insn (gen_cmpsi_1 (countreg, countreg));
emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align, emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
addr1, addr2, countreg)); operands[1], operands[2]));
}
} }
outlow = gen_lowpart (QImode, out); outlow = gen_lowpart (QImode, out);
...@@ -16135,7 +15948,20 @@ ...@@ -16135,7 +15948,20 @@
;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
;; zero. Emit extra code to make sure that a zero-length compare is EQ. ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
(define_insn "cmpstrqi_nz_1" (define_expand "cmpstrqi_nz_1"
[(parallel [(set (reg:CC 17)
(compare:CC (match_operand 4 "memory_operand" "")
(match_operand 5 "memory_operand" "")))
(use (match_operand 2 "register_operand" ""))
(use (match_operand:SI 3 "immediate_operand" ""))
(use (reg:SI 19))
(clobber (match_operand 0 "register_operand" ""))
(clobber (match_operand 1 "register_operand" ""))
(clobber (match_dup 2))])]
""
"")
(define_insn "*cmpstrqi_nz_1"
[(set (reg:CC 17) [(set (reg:CC 17)
(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0")) (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
(mem:BLK (match_operand:SI 5 "register_operand" "1")))) (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
...@@ -16151,7 +15977,7 @@ ...@@ -16151,7 +15977,7 @@
(set_attr "mode" "QI") (set_attr "mode" "QI")
(set_attr "prefix_rep" "1")]) (set_attr "prefix_rep" "1")])
(define_insn "cmpstrqi_nz_rex_1" (define_insn "*cmpstrqi_nz_rex_1"
[(set (reg:CC 17) [(set (reg:CC 17)
(compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0")) (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
(mem:BLK (match_operand:DI 5 "register_operand" "1")))) (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
...@@ -16169,7 +15995,23 @@ ...@@ -16169,7 +15995,23 @@
;; The same, but the count is not known to not be zero. ;; The same, but the count is not known to not be zero.
(define_insn "cmpstrqi_1" (define_expand "cmpstrqi_1"
[(parallel [(set (reg:CC 17)
(if_then_else:CC (ne (match_operand 2 "register_operand" "")
(const_int 0))
(compare:CC (match_operand 4 "memory_operand" "")
(match_operand 5 "memory_operand" ""))
(const_int 0)))
(use (match_operand:SI 3 "immediate_operand" ""))
(use (reg:CC 17))
(use (reg:SI 19))
(clobber (match_operand 0 "register_operand" ""))
(clobber (match_operand 1 "register_operand" ""))
(clobber (match_dup 2))])]
""
"")
(define_insn "*cmpstrqi_1"
[(set (reg:CC 17) [(set (reg:CC 17)
(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2") (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
(const_int 0)) (const_int 0))
...@@ -16188,7 +16030,7 @@ ...@@ -16188,7 +16030,7 @@
(set_attr "mode" "QI") (set_attr "mode" "QI")
(set_attr "prefix_rep" "1")]) (set_attr "prefix_rep" "1")])
(define_insn "cmpstrqi_rex_1" (define_insn "*cmpstrqi_rex_1"
[(set (reg:CC 17) [(set (reg:CC 17)
(if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2") (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
(const_int 0)) (const_int 0))
...@@ -16233,7 +16075,15 @@ ...@@ -16233,7 +16075,15 @@
FAIL; FAIL;
}) })
(define_insn "strlenqi_1" (define_expand "strlenqi_1"
[(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
(use (reg:SI 19))
(clobber (match_operand 1 "register_operand" ""))
(clobber (reg:CC 17))])]
""
"")
(define_insn "*strlenqi_1"
[(set (match_operand:SI 0 "register_operand" "=&c") [(set (match_operand:SI 0 "register_operand" "=&c")
(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1")) (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
(match_operand:QI 2 "register_operand" "a") (match_operand:QI 2 "register_operand" "a")
...@@ -16248,7 +16098,7 @@ ...@@ -16248,7 +16098,7 @@
(set_attr "mode" "QI") (set_attr "mode" "QI")
(set_attr "prefix_rep" "1")]) (set_attr "prefix_rep" "1")])
(define_insn "strlenqi_rex_1" (define_insn "*strlenqi_rex_1"
[(set (match_operand:DI 0 "register_operand" "=&c") [(set (match_operand:DI 0 "register_operand" "=&c")
(unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1")) (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
(match_operand:QI 2 "register_operand" "a") (match_operand:QI 2 "register_operand" "a")
......
...@@ -1869,19 +1869,29 @@ change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate) ...@@ -1869,19 +1869,29 @@ change_address_1 (rtx memref, enum machine_mode mode, rtx addr, int validate)
rtx rtx
change_address (rtx memref, enum machine_mode mode, rtx addr) change_address (rtx memref, enum machine_mode mode, rtx addr)
{ {
rtx new = change_address_1 (memref, mode, addr, 1); rtx new = change_address_1 (memref, mode, addr, 1), size;
enum machine_mode mmode = GET_MODE (new); enum machine_mode mmode = GET_MODE (new);
unsigned int align;
size = mmode == BLKmode ? 0 : GEN_INT (GET_MODE_SIZE (mmode));
align = mmode == BLKmode ? BITS_PER_UNIT : GET_MODE_ALIGNMENT (mmode);
/* If there are no changes, just return the original memory reference. */ /* If there are no changes, just return the original memory reference. */
if (new == memref) if (new == memref)
{
if (MEM_ATTRS (memref) == 0
|| (MEM_EXPR (memref) == NULL
&& MEM_OFFSET (memref) == NULL
&& MEM_SIZE (memref) == size
&& MEM_ALIGN (memref) == align))
return new; return new;
new = gen_rtx_MEM (mmode, addr);
MEM_COPY_ATTRIBUTES (new, memref);
}
MEM_ATTRS (new) MEM_ATTRS (new)
= get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, = get_mem_attrs (MEM_ALIAS_SET (memref), 0, 0, size, align, mmode);
mmode == BLKmode ? 0 : GEN_INT (GET_MODE_SIZE (mmode)),
(mmode == BLKmode ? BITS_PER_UNIT
: GET_MODE_ALIGNMENT (mmode)),
mmode);
return new; return new;
} }
......
...@@ -4619,10 +4619,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size) ...@@ -4619,10 +4619,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size)
highest_pow2_factor (offset)); highest_pow2_factor (offset));
} }
/* If the constructor has been cleared, setting RTX_UNCHANGING_P if (TREE_READONLY (field))
on the MEM might lead to scheduling the clearing after the
store. */
if (TREE_READONLY (field) && !cleared)
{ {
if (GET_CODE (to_rtx) == MEM) if (GET_CODE (to_rtx) == MEM)
to_rtx = copy_rtx (to_rtx); to_rtx = copy_rtx (to_rtx);
......
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