diff options
author | Jan Hubicka <hubicka@freesoft.cz> | 1999-11-21 02:34:22 +0100 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 1999-11-21 01:34:22 +0000 |
commit | 06a964de822dfc498ee497e253e6ca360a318d8d (patch) | |
tree | 728c66a8e34f1db456e377d1b75b916d474ec018 /gcc | |
parent | 1ce485ec4316107f1e03d147471accd1ddf9a0d2 (diff) | |
download | gcc-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/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 79 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 180 |
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")]) |