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
This commit is contained in:
Jan Hubicka 2000-01-11 19:01:35 +01:00 committed by Jan Hubicka
parent 1e7a71c153
commit f90800f836
4 changed files with 154 additions and 53 deletions

View File

@ -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

View File

@ -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))

View File

@ -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)

View File

@ -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 ());
}")
;; 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.
(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))]
""
"*
{
rtx xops[2];
if (GET_CODE (operands[2]) == CONST_INT)
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)
{
xops[0] = GEN_INT ((INTVAL (operands[2]) >> 2) & 0x3fffffff);
xops[1] = operands[4];
output_asm_insn (\"mov{l}\\t{%0, %1|%1,%0}\", xops);
output_asm_insn (\"{rep\;movsl|rep movsd}\", xops);
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)
output_asm_insn (\"movsw\", operands);
emit_insn (gen_strmovhi (destreg, srcreg));
if (INTVAL (operands[2]) & 0x01)
output_asm_insn (\"movsb\", operands);
emit_insn (gen_strmovqi (destreg, srcreg));
}
else
abort ();
RET;
}"
[(set_attr "type" "multi")])
DONE;
}")
;; Most CPUs don't like single string operations
;; Handle this case here to simplify previous expander.
(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_SINGLE_STRINGOP || optimize_size)
{
emit_insn (gen_strmovhi_1 (operands[0], operands[1], operands[0],
operands[1]));
DONE;
}
else
operands[2] = gen_reg_rtx (HImode);
}")
(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
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.