mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-08 05:56:42 +08:00
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:
parent
1e7a71c153
commit
f90800f836
@ -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
|
||||
|
@ -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))
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user