Commit e9e80858 by Jan Hubicka Committed by Jan Hubicka

i386.md (HI to SImode promoting splitters): Rewrite.

	* i386.md (HI to SImode promoting splitters): Rewrite.
	(pushsf mem peep2): New.
	(testhi to andhi peep2): Remove.
	* i386.h (x86_promote_QImode): New.
	(TARGET_PROMOTE_QImode): New.
	(PREDICATE_CODES): Add promotable_binary_operator.
	* i386.c (x86_promote_QImode0: New.
	(promotable_binary_operator): New.
	* i386-protos.h (promotable_binary_operator): New.

From-SVN: r30985
parent a1cbdd7f
Fri Dec 17 01:32:38 MET 1999 Jan Hubicka <hubicka@freesoft.cz>
* i386.md (HI to SImode promoting splitters): Rewrite.
(pushsf mem peep2): New.
(testhi to andhi peep2): Remove.
* i386.h (x86_promote_QImode): New.
(TARGET_PROMOTE_QImode): New.
(PREDICATE_CODES): Add promotable_binary_operator.
* i386.c (x86_promote_QImode0: New.
(promotable_binary_operator): New.
* i386-protos.h (promotable_binary_operator): New.
* i386.md (test?i_1): Use "nonmemory_operand" predicate, simplify
condition.
(one_cmpl?i*): Pass "NOT" to unary_operator_ok.
......
......@@ -60,6 +60,7 @@ extern int binary_fp_operator PROTO((rtx, enum machine_mode));
extern int mult_operator PROTO((rtx, enum machine_mode));
extern int div_operator PROTO((rtx, enum machine_mode));
extern int arith_or_logical_operator PROTO((rtx, enum machine_mode));
extern int promotable_binary_operator PROTO((rtx, enum machine_mode));
extern int memory_displacement_operand PROTO((rtx, enum machine_mode));
extern int cmpsi_operand PROTO((rtx, enum machine_mode));
extern int long_memory_operand PROTO((rtx, enum machine_mode));
......
......@@ -205,6 +205,7 @@ const int x86_use_cltd = ~(m_PENT | m_K6);
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;
#define AT_BP(mode) (gen_rtx_MEM ((mode), frame_pointer_rtx))
......@@ -1177,6 +1178,30 @@ fcmov_comparison_operator (op, mode)
&& GET_CODE (op) == unsigned_condition (GET_CODE (op)));
}
/* Return 1 if OP is a binary operator that can be promoted to wider mode. */
int
promotable_binary_operator (op, mode)
register rtx op;
enum machine_mode mode ATTRIBUTE_UNUSED;
{
switch (GET_CODE (op))
{
case MULT:
/* Modern CPUs have same latency for HImode and SImode multiply,
but 386 and 486 do HImode multiply faster. */
return ix86_cpu > PROCESSOR_I486;
case PLUS:
case AND:
case IOR:
case XOR:
case ASHIFT:
return 1;
default:
return 0;
}
}
/* Nearly general operand, but accept any const_double, since we wish
to be able to drop them into memory rather than have them get pulled
into registers. */
......
......@@ -161,6 +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;
#define TARGET_USE_LEAVE (x86_use_leave & CPUMASK)
#define TARGET_PUSH_MEMORY (x86_push_memory & CPUMASK)
......@@ -182,6 +183,7 @@ extern const int x86_read_modify, x86_split_long_moves;
#define TARGET_SPLIT_LONG_MOVES (x86_split_long_moves & CPUMASK)
#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_STACK_PROBE (target_flags & MASK_STACK_PROBE)
......@@ -2437,6 +2439,7 @@ do { long l; \
UMIN, UMAX, COMPARE, MINUS, DIV, MOD, \
UDIV, UMOD, ASHIFT, ROTATE, ASHIFTRT, \
LSHIFTRT, ROTATERT}}, \
{"promotable_binary_operator", {PLUS, MULT, AND, IOR, XOR, ASHIFT}}, \
{"memory_displacement_operand", {MEM}}, \
{"cmpsi_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, \
LABEL_REF, SUBREG, REG, MEM, AND}}, \
......
......@@ -3344,19 +3344,6 @@
(const_string "incdec")
(const_string "alu")))])
;; If we know we're not touching memory, promote HImode references to SImode.
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(plus:HI (match_operand:HI 1 "register_operand" "")
(match_operand:HI 2 "nonmemory_operand" "")))
(clobber (reg:CC 17))]
"! TARGET_PARTIAL_REG_STALL && reload_completed"
[(parallel [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
(clobber (reg:CC 17))])]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_lowpart (SImode, operands[2]);")
(define_insn "*addhi_2"
[(set (reg:CCNO 17)
(compare:CCNO
......@@ -4456,18 +4443,6 @@
}"
[(set_attr "type" "alu,alu,imovx")])
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(and:HI (match_operand:HI 1 "register_operand" "")
(match_operand:HI 2 "nonmemory_operand" "")))
(clobber (reg:CC 17))]
"! TARGET_PARTIAL_REG_STALL && reload_completed"
[(parallel [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))
(clobber (reg:CC 17))])]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_lowpart (SImode, operands[2]);")
(define_insn "*andhi_2"
[(set (reg:CCNO 17)
(compare:CCNO (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
......@@ -4479,23 +4454,6 @@
"and{w}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
(define_split
[(set (reg:CCNO 17)
(compare:CCNO (and:HI (match_operand:HI 1 "register_operand" "")
(match_operand:HI 2 "immediate_operand" ""))
(const_int 0)))
(set (match_operand:HI 0 "register_operand" "")
(and:HI (match_dup 1) (match_dup 2)))]
"! TARGET_PARTIAL_REG_STALL && reload_completed"
[(parallel [(set (reg:CCNO 17)
(compare:CCNO (and:SI (match_dup 1) (match_dup 2))
(const_int 0)))
(set (match_dup 0)
(and:SI (match_dup 1) (match_dup 2)))])]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_lowpart (SImode, operands[2]);")
(define_expand "andqi3"
[(set (match_operand:QI 0 "nonimmediate_operand" "")
(and:QI (match_operand:QI 1 "nonimmediate_operand" "")
......@@ -4661,18 +4619,6 @@
"or{w}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(ior:HI (match_operand:HI 1 "register_operand" "")
(match_operand:HI 2 "nonmemory_operand" "")))
(clobber (reg:CC 17))]
"! TARGET_PARTIAL_REG_STALL && reload_completed"
[(parallel [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2)))
(clobber (reg:CC 17))])]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_lowpart (SImode, operands[2]);")
(define_insn "*iorhi_2"
[(set (reg:CCNO 17)
(compare:CCNO (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
......@@ -4766,18 +4712,6 @@
"xor{w}\\t{%2, %0|%0, %2}"
[(set_attr "type" "alu")])
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(xor:HI (match_operand:HI 1 "register_operand" "")
(match_operand:HI 2 "nonmemory_operand" "")))
(clobber (reg:CC 17))]
"! TARGET_PARTIAL_REG_STALL && reload_completed"
[(parallel [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2)))
(clobber (reg:CC 17))])]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_lowpart (SImode, operands[2]);")
(define_insn "*xorhi_2"
[(set (reg:CCNO 17)
(compare:CCNO (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
......@@ -5396,16 +5330,6 @@
"not{w}\\t%0"
[(set_attr "type" "negnot")])
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(not:HI (match_operand:HI 1 "register_operand" "")))
(clobber (reg:CC 17))]
"! TARGET_PARTIAL_REG_STALL && reload_completed"
[(parallel [(set (match_dup 0) (not:SI (match_dup 1)))
(clobber (reg:CC 17))])]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);")
(define_insn "*one_cmplhi2_2"
[(set (reg:CCNO 17)
(compare:CCNO (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
......@@ -5746,17 +5670,6 @@
]
(const_string "ishift")))])
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(ashift:HI (match_operand:HI 1 "register_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))
(clobber (reg:CC 17))]
"! TARGET_PARTIAL_REG_STALL && reload_completed"
[(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))
(clobber (reg:CC 17))])]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);")
(define_insn "*ashlhi3_cmpno"
[(set (reg:CCNO 17)
(compare:CCNO
......@@ -8277,19 +8190,6 @@
cmov%c1\\t{%3, %0|%0, %3}"
[(set_attr "type" "icmov")])
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(if_then_else:HI (match_operator 1 "comparison_operator"
[(reg 17) (const_int 0)])
(match_operand:HI 2 "register_operand" "")
(match_operand:HI 3 "register_operand" "")))]
"! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE"
[(set (match_dup 0)
(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[2] = gen_lowpart (SImode, operands[2]);
operands[3] = gen_lowpart (SImode, operands[3]);")
(define_expand "movsfcc"
[(set (match_operand:SF 0 "register_operand" "")
(if_then_else:SF (match_operand 1 "comparison_operator" "")
......@@ -8436,6 +8336,107 @@
DONE;
}")
;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
(define_split
[(set (match_operand 0 "register_operand" "")
(match_operator 3 "promotable_binary_operator"
[(match_operand 1 "register_operand" "")
(match_operand 2 "nonmemory_operand" "")]))
(clobber (reg:CC 17))]
"! TARGET_PARTIAL_REG_STALL && reload_completed
&& ((GET_MODE (operands[0]) == HImode
&& (!optimize_size || GET_CODE (operands[2]) != CONST_INT
|| CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
|| (GET_MODE (operands[0]) == QImode
&& (TARGET_PROMOTE_QImode || optimize_size)))"
[(parallel [(set (match_dup 0)
(match_op_dup 3 [(match_dup 1) (match_dup 2)]))
(clobber (reg:CC 17))])]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
if (GET_CODE (operands[3]) != ASHIFT)
operands[2] = gen_lowpart (SImode, operands[2]);
GET_MODE (operands[3]) = SImode;")
(define_split
[(set (reg:CCNO 17)
(compare:CCNO (and (match_operand 1 "register_operand" "")
(match_operand 2 "immediate_operand" ""))
(const_int 0)))
(set (match_operand 0 "register_operand" "")
(and (match_dup 1) (match_dup 2)))]
"! TARGET_PARTIAL_REG_STALL && reload_completed
&& (GET_MODE (operands[0]) == HImode
|| (GET_MODE (operands[0]) == QImode
&& (TARGET_PROMOTE_QImode || optimize_size)))"
[(parallel [(set (reg:CCNO 17)
(compare:CCNO (and:SI (match_dup 1) (match_dup 2))
(const_int 0)))
(set (match_dup 0)
(and:SI (match_dup 1) (match_dup 2)))])]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_lowpart (SImode, operands[2]);")
(define_split
[(set (reg:CCNO 17)
(compare:CCNO (and (match_operand 0 "register_operand" "")
(match_operand 1 "immediate_operand" ""))
(const_int 0)))]
"! TARGET_PARTIAL_REG_STALL && reload_completed
&& (GET_MODE (operands[0]) == HImode
|| (GET_MODE (operands[0]) == QImode
&& (TARGET_PROMOTE_QImode || optimize_size)))"
[(set (reg:CCNO 17)
(compare:CCNO (and:SI (match_dup 0) (match_dup 1))
(const_int 0)))]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);")
(define_split
[(set (match_operand 0 "register_operand" "")
(neg (match_operand 1 "register_operand" "")))
(clobber (reg:CC 17))]
"! TARGET_PARTIAL_REG_STALL && reload_completed
&& (GET_MODE (operands[0]) == HImode
|| (GET_MODE (operands[0]) == QImode
&& (TARGET_PROMOTE_QImode || optimize_size)))"
[(parallel [(set (match_dup 0)
(neg:SI (match_dup 1)))
(clobber (reg:CC 17))])]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);")
(define_split
[(set (match_operand 0 "register_operand" "")
(not (match_operand 1 "register_operand" "")))]
"! TARGET_PARTIAL_REG_STALL && reload_completed
&& (GET_MODE (operands[0]) == HImode
|| (GET_MODE (operands[0]) == QImode
&& (TARGET_PROMOTE_QImode || optimize_size)))"
[(set (match_dup 0)
(not:SI (match_dup 1)))]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);")
(define_split
[(set (match_operand 0 "register_operand" "")
(if_then_else (match_operator 1 "comparison_operator"
[(reg 17) (const_int 0)])
(match_operand 2 "register_operand" "")
(match_operand 3 "register_operand" "")))]
"! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
&& (GET_MODE (operands[0]) == HImode
|| (GET_MODE (operands[0]) == QImode
&& (TARGET_PROMOTE_QImode || optimize_size)))"
[(set (match_dup 0)
(if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[2] = gen_lowpart (SImode, operands[2]);
operands[3] = gen_lowpart (SImode, operands[3]);")
;; RTL Peephole optimizations, run before sched2. These primarily look to
;; transform a complex memory operation into two memory to register operations.
......@@ -8449,6 +8450,17 @@
(set (match_dup 0) (match_dup 2))]
"")
;; We need to handle SFmode only, because DFmode and XFmode is split to
;; SImode pushes.
(define_peephole2
[(set (match_operand:SF 0 "push_operand" "")
(match_operand:SF 1 "memory_operand" ""))
(match_scratch:SF 2 "r")]
"! optimize_size && ! TARGET_PUSH_MEMORY"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
"")
(define_peephole2
[(set (match_operand:HI 0 "push_operand" "")
(match_operand:HI 1 "memory_operand" ""))
......@@ -8626,23 +8638,8 @@
(and:SI (match_dup 0) (match_dup 1)))])]
"")
(define_peephole2
[(set (reg:CCNO 17)
(compare:CCNO (and:HI (match_operand:HI 0 "register_operand" "")
(match_operand:HI 1 "immediate_operand" ""))
(const_int 0)))]
"! TARGET_PARTIAL_REG_STALL
&& (true_regnum (operands[0]) != 0
|| CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
&& find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
[(parallel
[(set (reg:CCNO 17)
(compare:CCNO (and:HI (match_dup 0)
(match_dup 1))
(const_int 0)))
(set (match_dup 0)
(and:HI (match_dup 0) (match_dup 1)))])]
"")
;; We don't need to handle HImode case, because it will be promoted to SImode
;; on ! TARGET_PARTIAL_REG_STALL
(define_peephole2
[(set (reg:CCNO 17)
......
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