aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2000-01-11 19:01:35 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2000-01-11 18:01:35 +0000
commitf90800f836965874b1025412cd1690638edfce07 (patch)
treec2b4db48b098c107384d99fe3760bbd090cd10b7
parent1e7a71c15355d9e092bd76ec5eb4317a114587f5 (diff)
downloadgcc-f90800f836965874b1025412cd1690638edfce07.zip
gcc-f90800f836965874b1025412cd1690638edfce07.tar.gz
gcc-f90800f836965874b1025412cd1690638edfce07.tar.bz2
i386.md (movstrsi expander): Rewrite.
* i386.md (movstrsi expander): Rewrite. (movstrsi_1 insn): Deleted. (strmovhi, strmovqi expander): New expanders. (movshi_1, movsqi_1, rep_movsi, rep_movqi): New patterns. * i386.c (x86_single_stringop): New global variable. * i386.h (x86_single_stringop): Declare. (TARGET_SINGLE_STRINGOP): New macro. From-SVN: r31329
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/i386/i386.c1
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/config/i386/i386.md191
4 files changed, 153 insertions, 52 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index eb6600a..0640895 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+Tue Jan 11 18:59:35 MET 2000 Jan Hubicka <jh@suse.cz>
+
+ * i386.md (movstrsi expander): Rewrite.
+ (movstrsi_1 insn): Deleted.
+ (strmovhi, strmovqi expander): New expanders.
+ (movshi_1, movsqi_1, rep_movsi, rep_movqi): New patterns.
+ * i386.c (x86_single_stringop): New global variable.
+ * i386.h (x86_single_stringop): Declare.
+ (TARGET_SINGLE_STRINGOP): New macro.
+
2000-01-11 Clinton Popetz <cpopetz@cygnus.com>
* config/mips/mips.c (mips_va_arg): For EABI, emit the queued
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index d35bafb..f2d98a4 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -206,6 +206,7 @@ const int x86_read_modify_write = ~m_PENT;
const int x86_read_modify = ~(m_PENT | m_PPRO);
const int x86_split_long_moves = m_PPRO;
const int x86_promote_QImode = m_K6 | m_PENT | m_386 | m_486;
+const int x86_single_stringop = m_386;
#define AT_BP(mode) (gen_rtx_MEM ((mode), frame_pointer_rtx))
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index ed7f849..62883d7 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -161,7 +161,7 @@ extern const int x86_double_with_add, x86_partial_reg_stall, x86_movx;
extern const int x86_use_loop, x86_use_fiop, x86_use_mov0;
extern const int x86_use_cltd, x86_read_modify_write;
extern const int x86_read_modify, x86_split_long_moves;
-extern const int x86_promote_QImode;
+extern const int x86_promote_QImode, x86_single_stringop;
#define TARGET_USE_LEAVE (x86_use_leave & CPUMASK)
#define TARGET_PUSH_MEMORY (x86_push_memory & CPUMASK)
@@ -184,6 +184,7 @@ extern const int x86_promote_QImode;
#define TARGET_READ_MODIFY_WRITE (x86_read_modify_write & CPUMASK)
#define TARGET_READ_MODIFY (x86_read_modify & CPUMASK)
#define TARGET_PROMOTE_QImode (x86_promote_QImode & CPUMASK)
+#define TARGET_SINGLE_STRINGOP (x86_single_stringop & CPUMASK)
#define TARGET_STACK_PROBE (target_flags & MASK_STACK_PROBE)
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 6fd7c8e..2f7aa6a 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -7825,71 +7825,162 @@
[(set_attr "type" "cld")])
(define_expand "movstrsi"
- [(parallel [(set (match_operand:BLK 0 "memory_operand" "")
- (match_operand:BLK 1 "memory_operand" ""))
- (use (match_operand:SI 2 "const_int_operand" ""))
- (use (match_operand:SI 3 "const_int_operand" ""))
- (use (reg:SI 19))
- (clobber (match_scratch:SI 4 ""))
- (clobber (match_dup 5))
- (clobber (match_dup 6))])]
+ [(use (match_operand:BLK 0 "memory_operand" ""))
+ (use (match_operand:BLK 1 "memory_operand" ""))
+ (use (match_operand:SI 2 "const_int_operand" ""))
+ (use (match_operand:SI 3 "const_int_operand" ""))]
""
"
{
- rtx addr0, addr1;
+ rtx srcreg, destreg, countreg;
if (GET_CODE (operands[2]) != CONST_INT)
FAIL;
- addr0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
- addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
+ destreg = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
+ srcreg = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
- operands[5] = addr0;
- operands[6] = addr1;
-
- operands[0] = change_address (operands[0], VOIDmode, addr0);
- operands[1] = change_address (operands[1], VOIDmode, addr1);
- emit_insn (gen_cld ());
+ emit_insn (gen_cld());
+ /* When optimizing for size emit simple rep ; movsb instruction. */
+ if (!optimize || optimize_size)
+ {
+ countreg = copy_to_mode_reg (SImode, operands[2]);
+ emit_insn (gen_rep_movqi (destreg, srcreg, countreg,
+ destreg, srcreg, countreg));
+ }
+ else
+ {
+ if (INTVAL (operands[2]) & ~0x03)
+ {
+ countreg = copy_to_mode_reg (SImode,
+ GEN_INT ((INTVAL (operands[2]) >> 2)
+ & 0x3fffffff));
+ emit_insn (gen_rep_movsi (destreg, srcreg, countreg,
+ destreg, srcreg, countreg));
+ }
+ if (INTVAL (operands[2]) & 0x02)
+ emit_insn (gen_strmovhi (destreg, srcreg));
+ if (INTVAL (operands[2]) & 0x01)
+ emit_insn (gen_strmovqi (destreg, srcreg));
+ }
+ DONE;
}")
-;; It might seem that operands 0 & 1 could use predicate register_operand.
-;; But strength reduction might offset the MEM expression. So we let
-;; reload put the address into %edi & %esi.
+;; Most CPUs don't like single string operations
+;; Handle this case here to simplify previous expander.
-(define_insn "*movstrsi_1"
- [(set (mem:BLK (match_operand:SI 0 "address_operand" "D"))
- (mem:BLK (match_operand:SI 1 "address_operand" "S")))
- (use (match_operand:SI 2 "const_int_operand" "n"))
- (use (match_operand:SI 3 "immediate_operand" "i"))
- (use (reg:SI 19))
- (clobber (match_scratch:SI 4 "=&c"))
- (clobber (match_dup 0))
- (clobber (match_dup 1))]
+(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))])]
""
- "*
+ "
{
- rtx xops[2];
-
- if (GET_CODE (operands[2]) == CONST_INT)
+ if (TARGET_SINGLE_STRINGOP || optimize_size)
{
- if (INTVAL (operands[2]) & ~0x03)
- {
- xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
- xops[1] = operands[4];
+ emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
+ operands[1]));
+ DONE;
+ }
+ else
+ operands[2] = gen_reg_rtx (HImode);
+}")
- output_asm_insn (\"mov{l}\\t{%0, %1|%1,%0}\", xops);
- output_asm_insn (\"{rep\;movsl|rep movsd}\", xops);
- }
- if (INTVAL (operands[2]) & 0x02)
- output_asm_insn (\"movsw\", operands);
- if (INTVAL (operands[2]) & 0x01)
- output_asm_insn (\"movsb\", operands);
+(define_expand "strmovqi"
+ [(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_SINGLE_STRINGOP || optimize_size)
+ {
+ emit_insn (gen_strmovqi_1 (operands[0], operands[1], operands[0],
+ operands[1]));
+ DONE;
}
- else
- abort ();
- RET;
-}"
- [(set_attr "type" "multi")])
+ else
+ operands[2] = gen_reg_rtx (QImode);
+}")
+
+(define_insn "strmovhi_1"
+ [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
+ (mem:HI (match_operand:SI 3 "register_operand" "1")))
+ (set (match_operand:SI 0 "register_operand" "=D")
+ (plus:SI (match_dup 0)
+ (const_int 2)))
+ (set (match_operand:SI 1 "register_operand" "=S")
+ (plus:SI (match_dup 1)
+ (const_int 2)))
+ (use (reg:SI 19))]
+ "TARGET_SINGLE_STRINGOP || optimize_size"
+ "movsw"
+ [(set_attr "type" "str")
+ (set_attr "memory" "both")
+ (set_attr "length_prefix" "1")])
+
+(define_insn "strmovqi_1"
+ [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
+ (mem:QI (match_operand:SI 3 "register_operand" "1")))
+ (set (match_operand:SI 0 "register_operand" "=D")
+ (plus:SI (match_dup 0)
+ (const_int 1)))
+ (set (match_operand:SI 1 "register_operand" "=S")
+ (plus:SI (match_dup 1)
+ (const_int 1)))
+ (use (reg:SI 19))]
+ "TARGET_SINGLE_STRINGOP || optimize_size"
+ "movsb"
+ [(set_attr "type" "str")
+ (set_attr "memory" "both")])
+
+;; It might seem that operands 3 & 4 could use predicate register_operand.
+;; But strength reduction might offset the MEM expression. So we let
+;; reload put the address into %edi & %esi.
+
+(define_insn "rep_movsi"
+ [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
+ (use (match_operand:SI 5 "register_operand" "2"))
+ (set (match_operand:SI 0 "register_operand" "=D")
+ (plus:SI (match_operand:SI 3 "address_operand" "0")
+ (ashift:SI (match_dup 5) (const_int 2))))
+ (set (match_operand:SI 1 "register_operand" "=S")
+ (plus:SI (match_operand:SI 4 "address_operand" "1")
+ (ashift:SI (match_dup 5) (const_int 2))))
+ (set (mem:BLK (match_dup 3))
+ (mem:BLK (match_dup 4)))
+ (use (reg:SI 19))]
+ ""
+ "rep\;movsl|rep movsd"
+ [(set_attr "type" "str")
+ (set_attr "length_prefix" "1")
+ (set_attr "memory" "both")])
+
+(define_insn "rep_movqi"
+ [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
+ (use (match_operand:SI 5 "register_operand" "2"))
+ (set (match_operand:SI 0 "register_operand" "=D")
+ (plus:SI (match_operand:SI 3 "address_operand" "0") (match_dup 5)))
+ (set (match_operand:SI 1 "register_operand" "=S")
+ (plus:SI (match_operand:SI 4 "address_operand" "1") (match_dup 5)))
+ (set (mem:BLK (match_dup 3))
+ (mem:BLK (match_dup 4)))
+ (use (reg:SI 19))]
+ ""
+ "rep\;movsb|rep movsb"
+ [(set_attr "type" "str")
+ (set_attr "length_prefix" "1")
+ (set_attr "memory" "both")])
(define_expand "clrstrsi"
[(set (reg:SI 19) (const_int 0))
@@ -7916,8 +8007,6 @@
operands[5] = addr0;
operands[0] = gen_rtx_MEM (BLKmode, addr0);
-
- emit_insn (gen_cld ());
}")
;; It might seem that operand 0 could use predicate register_operand.