i386.md (neg, [...]): Revmap to use ix86_expand_unary_operator and ix86_unary_operato...
authorJan Hubicka <hubicka@freesoft.cz>
Sun, 21 Nov 1999 01:34:22 +0000 (02:34 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sun, 21 Nov 1999 01:34:22 +0000 (01:34 +0000)
        * 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

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.md

index 5be7711f003099083f4a2d0014ef8cea74106b95..65809bbf92185e2cba8b07aa362a78f2959831d2 100644 (file)
@@ -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.
index 4707ebff9e953b758dc97a7b2a65349b511096c1..48b88455c9a52ed0bb89edddc316cd6071e42bd6 100644 (file)
@@ -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;
 }
 
index eae220a3bb863e677d8d413e0bbe357f13394570..5f595e469e60d1e2dd214783e145ccdb68ad6168 100644 (file)
 
 (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"
   "")
 
 (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"
   "")
 
 ;; %%% 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
   "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")])
 
                 (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")])
 
                 (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")])
 
                 (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")])
 
                 (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")])
 
                 (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")])
 
                 (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
   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
   "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
 \f
 ;; 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
   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
   "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
 \f
 ;; 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")])
 
                   (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")])
 
   "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")])
 
   "")
 
 ;; %%% 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")])