Commit 06a964de by Jan Hubicka Committed by Jan Hubicka

i386.md (neg, [...]): Revmap to use ix86_expand_unary_operator and ix86_unary_operator_ok.

        * i386.md (neg, not and abs patterns): Revmap to use
        ix86_expand_unary_operator and ix86_unary_operator_ok.
        (add?f and sub?f expanders): Force operand 1 to register.
        * i386.c (ix86_expand_unary_operator): Rewrite.
        (ix86_unary_operator_ok): Ensure that memory operands
        match real opcode.
        (ix86_binary_operator_ok): Do not allow operand 1 to
        come into memory and operand 0 not.
        (ix86_expand_binary_operator): Ensure that
        src1 is not non-matching memory.

From-SVN: r30597
parent 1ce485ec
Fri Nov 19 06:32:19 CET 1999 Jan Hubicka <hubicka@freesoft.cz>
* i386.md (neg, not and abs patterns): Revmap to use
ix86_expand_unary_operator and ix86_unary_operator_ok.
(add?f and sub?f expanders): Force operand 1 to register.
* i386.c (ix86_expand_unary_operator): Rewrite.
(ix86_unary_operator_ok): Ensure that memory operands
match real opcode.
(ix86_binary_operator_ok): Do not allow operand 1 to
come into memory and operand 0 not.
(ix86_expand_binary_operator): Ensure that
src1 is not non-matching memory.
* i386.md (negs?2): Rewrite to expanders, new patterns and splitters
to support integer registers and memory.
(abss?2_integer): Likewise.
......
......@@ -3726,8 +3726,11 @@ ix86_expand_binary_operator (code, mode, operands)
src1 = force_reg (mode, src1);
}
/* If the operation is not commutable, source 1 cannot be a constant. */
if (CONSTANT_P (src1) && GET_RTX_CLASS (code) != 'c')
/* If the operation is not commutable, source 1 cannot be a constant
or non-matching memory. */
if ((CONSTANT_P (src1)
|| (!matching_memory && GET_CODE (src1) == MEM))
&& GET_RTX_CLASS (code) != 'c')
src1 = force_reg (mode, src1);
/* If optimizing, copy to regs to improve CSE */
......@@ -3784,6 +3787,12 @@ ix86_binary_operator_ok (code, mode, operands)
|| (GET_RTX_CLASS (code) == 'c'
&& rtx_equal_p (operands[0], operands[2]))))
return 0;
/* If the operation is not commutable and the source 1 is memory, we must
have a matching destionation. */
if (GET_CODE (operands[1]) == MEM
&& GET_RTX_CLASS (code) != 'c'
&& ! rtx_equal_p (operands[0], operands[1]))
return 0;
return 1;
}
......@@ -3798,27 +3807,56 @@ ix86_expand_unary_operator (code, mode, operands)
enum machine_mode mode;
rtx operands[];
{
/* If optimizing, copy to regs to improve CSE */
if (optimize
&& ((reload_in_progress | reload_completed) == 0)
&& GET_CODE (operands[1]) == MEM)
operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
int matching_memory;
rtx src, dst, op, clob;
dst = operands[0];
src = operands[1];
if (! ix86_unary_operator_ok (code, mode, operands))
/* If the destination is memory, and we do not have matching source
operands, do things in registers. */
matching_memory = 0;
if (GET_CODE (dst) == MEM)
{
if (optimize == 0
&& ((reload_in_progress | reload_completed) == 0)
&& GET_CODE (operands[1]) == MEM)
{
operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
if (! ix86_unary_operator_ok (code, mode, operands))
return FALSE;
}
if (rtx_equal_p (dst, src))
matching_memory = 1;
else
return FALSE;
dst = gen_reg_rtx (mode);
}
return TRUE;
/* When source operand is memory, destination must match. */
if (!matching_memory && GET_CODE (src) == MEM)
src = force_reg (mode, src);
/* If optimizing, copy to regs to improve CSE */
if (optimize && !reload_in_progress && !reload_completed)
{
if (GET_CODE (dst) == MEM)
dst = gen_reg_rtx (mode);
if (GET_CODE (src) == MEM)
src = force_reg (mode, src);
}
/* Emit the instruction. */
op = gen_rtx_SET (VOIDmode, dst, gen_rtx_fmt_e (code, mode, src));
if (reload_in_progress || code == NOT)
{
/* Reload doesn't know about the flags register, and doesn't know that
it doesn't want to clobber it. */
if (code != NOT)
abort ();
emit_insn (op);
}
else
{
clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
}
/* Fix up the destination if needed. */
if (dst != operands[0])
emit_move_insn (operands[0], dst);
}
/* Return TRUE or FALSE depending on whether the unary operator meets the
......@@ -3830,6 +3868,11 @@ ix86_unary_operator_ok (code, mode, operands)
enum machine_mode mode ATTRIBUTE_UNUSED;
rtx operands[2] ATTRIBUTE_UNUSED;
{
/* If one of operands is memory, source and destination must match. */
if ((GET_CODE (operands[0]) == MEM
|| GET_CODE (operands[1]) == MEM)
&& ! rtx_equal_p (operands[0], operands[1]))
return FALSE;
return TRUE;
}
......
......@@ -3589,14 +3589,14 @@
(define_expand "adddf3"
[(set (match_operand:DF 0 "register_operand" "")
(plus:DF (match_operand:DF 1 "nonimmediate_operand" "")
(plus:DF (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "nonimmediate_operand" "")))]
"TARGET_80387"
"")
(define_expand "addsf3"
[(set (match_operand:SF 0 "register_operand" "")
(plus:SF (match_operand:SF 1 "nonimmediate_operand" "")
(plus:SF (match_operand:SF 1 "register_operand" "")
(match_operand:SF 2 "nonimmediate_operand" "")))]
"TARGET_80387"
"")
......@@ -3786,14 +3786,14 @@
(define_expand "subdf3"
[(set (match_operand:DF 0 "register_operand" "")
(minus:DF (match_operand:DF 1 "nonimmediate_operand" "")
(minus:DF (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "nonimmediate_operand" "")))]
"TARGET_80387"
"")
(define_expand "subsf3"
[(set (match_operand:SF 0 "register_operand" "")
(minus:SF (match_operand:SF 1 "nonimmediate_operand" "")
(minus:SF (match_operand:SF 1 "register_operand" "")
(match_operand:SF 2 "nonimmediate_operand" "")))]
"TARGET_80387"
"")
......@@ -4818,11 +4818,18 @@
;; %%% define_expand from the very first?
(define_insn "negdi2"
(define_expand "negdi2"
[(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
(neg:DI (match_operand:DI 1 "general_operand" "")))
(clobber (reg:CC 17))])]
""
"ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
(define_insn "*negdi2_1"
[(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
(neg:DI (match_operand:DI 1 "general_operand" "0")))
(clobber (reg:CC 17))]
""
"ix86_unary_operator_ok (NEG, DImode, operands)"
"#")
(define_split
......@@ -4847,11 +4854,18 @@
"split_di (operands+1, 1, operands+2, operands+3);
split_di (operands+0, 1, operands+0, operands+1);")
(define_insn "negsi2"
(define_expand "negsi2"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
(neg:SI (match_operand:SI 1 "general_operand" "")))
(clobber (reg:CC 17))])]
""
"ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
(define_insn "*negsi2_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
(clobber (reg:CC 17))]
""
"ix86_unary_operator_ok (NEG, SImode, operands)"
"neg{l}\\t%0"
[(set_attr "type" "negnot")])
......@@ -4861,7 +4875,7 @@
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(neg:SI (match_dup 1)))]
""
"ix86_unary_operator_ok (NEG, SImode, operands)"
"neg{l}\\t%0"
[(set_attr "type" "negnot")])
......@@ -4871,15 +4885,22 @@
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(neg:SI (match_dup 1)))]
""
"ix86_unary_operator_ok (NEG, SImode, operands)"
"neg{l}\\t%0"
[(set_attr "type" "negnot")])
(define_insn "neghi2"
(define_expand "neghi2"
[(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
(neg:HI (match_operand:HI 1 "general_operand" "")))
(clobber (reg:CC 17))])]
""
"ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
(define_insn "*neghi2_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
(clobber (reg:CC 17))]
""
"ix86_unary_operator_ok (NEG, HImode, operands)"
"neg{w}\\t%0"
[(set_attr "type" "negnot")])
......@@ -4889,7 +4910,7 @@
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(neg:HI (match_dup 1)))]
""
"ix86_unary_operator_ok (NEG, HImode, operands)"
"neg{w}\\t%0"
[(set_attr "type" "negnot")])
......@@ -4899,15 +4920,22 @@
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(neg:HI (match_dup 1)))]
""
"ix86_unary_operator_ok (NEG, HImode, operands)"
"neg{w}\\t%0"
[(set_attr "type" "negnot")])
(define_insn "negqi2"
(define_expand "negqi2"
[(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
(neg:QI (match_operand:QI 1 "general_operand" "")))
(clobber (reg:CC 17))])]
""
"ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
(define_insn "*negqi2_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
(clobber (reg:CC 17))]
""
"ix86_unary_operator_ok (NEG, QImode, operands)"
"neg{b}\\t%0"
[(set_attr "type" "negnot")])
......@@ -4917,7 +4945,7 @@
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(neg:QI (match_dup 1)))]
""
"ix86_unary_operator_ok (NEG, QImode, operands)"
"neg{b}\\t%0"
[(set_attr "type" "negnot")])
......@@ -4927,17 +4955,24 @@
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(neg:QI (match_dup 1)))]
""
"ix86_unary_operator_ok (NEG, QImode, operands)"
"neg{b}\\t%0"
[(set_attr "type" "negnot")])
;; Changing of sign for FP values is duable using integer unit too.
;; Changing of sign for FP values is doable using integer unit too.
(define_insn "negsf2"
(define_expand "negsf2"
[(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
(neg:SF (match_operand:SF 1 "general_operand" "")))
(clobber (reg:CC 17))])]
"TARGET_80387"
"ix86_expand_unary_operator (NEG, SFmode, operands); DONE;")
(define_insn "*negsf2_if"
[(set (match_operand:SF 0 "nonimmediate_operand" "=frm")
(neg:SF (match_operand:SF 1 "nonimmediate_operand" "0")))
(clobber (reg:CC 17))]
"TARGET_80387"
"TARGET_80387 && ix86_unary_operator_ok (NEG, SFmode, operands)"
"#")
(define_split
......@@ -4978,11 +5013,18 @@
operands[1] = GEN_INT (0x80);
}")
(define_insn "negdf2"
(define_expand "negdf2"
[(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
(neg:DF (match_operand:DF 1 "general_operand" "")))
(clobber (reg:CC 17))])]
"TARGET_80387"
"ix86_expand_unary_operator (NEG, DFmode, operands); DONE;")
(define_insn "*negdf2_if"
[(set (match_operand:DF 0 "nonimmediate_operand" "=frm")
(neg:DF (match_operand:DF 1 "nonimmediate_operand" "0")))
(clobber (reg:CC 17))]
"TARGET_80387"
"TARGET_80387 && ix86_unary_operator_ok (NEG, DFmode, operands)"
"#")
(define_split
......@@ -5004,11 +5046,18 @@
"operands[4] = GEN_INT (0x80000000);
split_di (operands+0, 1, operands+2, operands+3);")
(define_insn "negxf2"
(define_expand "negxf2"
[(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
(neg:XF (match_operand:XF 1 "general_operand" "")))
(clobber (reg:CC 17))])]
"TARGET_80387"
"ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
(define_insn "*negxf2_if"
[(set (match_operand:XF 0 "nonimmediate_operand" "=frm")
(neg:XF (match_operand:XF 1 "nonimmediate_operand" "0")))
(clobber (reg:CC 17))]
"TARGET_80387"
"TARGET_80387 && ix86_unary_operator_ok (NEG, XFmode, operands)"
"#")
(define_split
......@@ -5086,11 +5135,18 @@
;; Absolute value instructions
(define_insn "abssf2"
(define_expand "abssf2"
[(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
(neg:SF (match_operand:SF 1 "general_operand" "")))
(clobber (reg:CC 17))])]
"TARGET_80387"
"ix86_expand_unary_operator (ABS, SFmode, operands); DONE;")
(define_insn "*abssf2_if"
[(set (match_operand:SF 0 "nonimmediate_operand" "=frm")
(abs:SF (match_operand:SF 1 "nonimmediate_operand" "0")))
(clobber (reg:CC 17))]
"TARGET_80387"
"TARGET_80387 && ix86_unary_operator_ok (ABS, SFmode, operands)"
"#")
(define_split
......@@ -5131,10 +5187,18 @@
operands[1] = GEN_INT (~0x80);
}")
(define_insn "absdf2"
[(set (match_operand:DF 0 "nonimmediate_operand" "=frm")
(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0")))]
(define_expand "absdf2"
[(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
(neg:DF (match_operand:DF 1 "general_operand" "")))
(clobber (reg:CC 17))])]
"TARGET_80387"
"ix86_expand_unary_operator (ABS, DFmode, operands); DONE;")
(define_insn "*absdf2_if"
[(set (match_operand:DF 0 "nonimmediate_operand" "=frm")
(abs:DF (match_operand:DF 1 "nonimmediate_operand" "0")))
(clobber (reg:CC 17))]
"TARGET_80387 && ix86_unary_operator_ok (ABS, DFmode, operands)"
"#")
(define_split
......@@ -5156,11 +5220,18 @@
"operands[4] = GEN_INT (~0x80000000);
split_di (operands+0, 1, operands+2, operands+3);")
(define_insn "absxf2"
(define_expand "absxf2"
[(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "")
(neg:XF (match_operand:XF 1 "general_operand" "")))
(clobber (reg:CC 17))])]
"TARGET_80387"
"ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
(define_insn "*absxf2_if"
[(set (match_operand:XF 0 "nonimmediate_operand" "=frm")
(abs:XF (match_operand:XF 1 "nonimmediate_operand" "0")))
(clobber (reg:CC 17))]
"TARGET_80387"
"TARGET_80387 && ix86_unary_operator_ok (ABS, XFmode, operands)"
"#")
(define_split
......@@ -5229,20 +5300,27 @@
;; One complement instructions
(define_insn "one_cmplsi2"
(define_expand "one_cmplsi2"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
(not:SI (match_operand:SI 1 "general_operand" "")))
(clobber (reg:CC 17))])]
""
"ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
(define_insn "*one_cmplsi2_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
""
"ix86_unary_operator_ok (NEG, SImode, operands)"
"not{l}\\t%0"
[(set_attr "type" "negnot")])
(define_insn "*one_cmplsi2_1"
(define_insn "*one_cmplsi2_2"
[(set (reg:CCNO 17)
(compare:CCNO (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
(const_int 0)))
(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
(not:SI (match_dup 1)))]
""
"ix86_unary_operator_ok (NEG, SImode, operands)"
"#"
[(set_attr "type" "alu1")])
......@@ -5260,10 +5338,17 @@
(xor:SI (match_dup 1) (const_int -1)))])]
"")
(define_insn "one_cmplhi2"
(define_expand "one_cmplhi2"
[(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
(not:HI (match_operand:HI 1 "general_operand" "")))
(clobber (reg:CC 17))])]
""
"ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
(define_insn "*one_cmplhi2_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
""
"ix86_unary_operator_ok (NEG, HImode, operands)"
"not{w}\\t%0"
[(set_attr "type" "negnot")])
......@@ -5277,13 +5362,13 @@
"operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);")
(define_insn "*one_cmplhi2_1"
(define_insn "*one_cmplhi2_2"
[(set (reg:CCNO 17)
(compare:CCNO (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
(const_int 0)))
(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
(not:HI (match_dup 1)))]
""
"ix86_unary_operator_ok (NEG, HImode, operands)"
"#"
[(set_attr "type" "alu1")])
......@@ -5302,22 +5387,29 @@
"")
;; %%% Potential partial reg stall on alternative 1. What to do?
(define_insn "one_cmplqi2"
(define_expand "one_cmplqi2"
[(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
(not:QI (match_operand:QI 1 "general_operand" "")))
(clobber (reg:CC 17))])]
""
"ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
(define_insn "*one_cmplqi2_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,*r")
(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
""
"ix86_unary_operator_ok (NEG, QImode, operands)"
"@
not{b}\\t%0
not{l}\\t%k0"
[(set_attr "type" "negnot")])
(define_insn "*one_cmplqi2_1"
(define_insn "*one_cmplqi2_2"
[(set (reg:CCNO 17)
(compare:CCNO (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
(const_int 0)))
(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
(not:QI (match_dup 1)))]
""
"ix86_unary_operator_ok (NEG, QImode, operands)"
"#"
[(set_attr "type" "alu1")])
......
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