aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@freesoft.cz>1999-11-21 02:34:22 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>1999-11-21 01:34:22 +0000
commit06a964de822dfc498ee497e253e6ca360a318d8d (patch)
tree728c66a8e34f1db456e377d1b75b916d474ec018 /gcc
parent1ce485ec4316107f1e03d147471accd1ddf9a0d2 (diff)
downloadgcc-06a964de822dfc498ee497e253e6ca360a318d8d.zip
gcc-06a964de822dfc498ee497e253e6ca360a318d8d.tar.gz
gcc-06a964de822dfc498ee497e253e6ca360a318d8d.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/i386/i386.c79
-rw-r--r--gcc/config/i386/i386.md180
3 files changed, 209 insertions, 62 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5be7711..65809bb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,16 @@
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.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 4707ebff9..48b8845 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -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;
}
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index eae220a..5f595e4 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -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")])