i386.md (zero_extend?i?i2): Rewrite to expanders; new patterns rewrite splitters.
authorJan Hubicka <hubicka@freesoft.cz>
Wed, 1 Dec 1999 13:38:50 +0000 (14:38 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 1 Dec 1999 13:38:50 +0000 (13:38 +0000)
* i386.md (zero_extend?i?i2): Rewrite to expanders; new patterns
rewrite splitters.

From-SVN: r30740

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

index 2b1cd260898de7163f8152c099574f99433ef87c..8f3c7e17f03b0ea344c5be3e68ea5fe7ed26a6c8 100644 (file)
@@ -1,5 +1,8 @@
 Tue Nov 30 15:20:52 MET 1999  Jan Hubicka  <hubicka@freesoft.cz>
 
+       * i386.md (zero_extend?i?i2): Rewrite to expanders; new patterns,
+       rewrite splitters.
+
        * i386.md (neg?f2_if): Split "r" and "f" to separate alternatives.
        (abs?f2_if): Likewise.
 
index 99ba4ada8034bb2c429159a26115d8d133040820..562f08f29df77b1e642462ce1a0343c94d9689fb 100644 (file)
 \f
 ;; Zero extension instructions
 
-(define_insn "zero_extendhisi2"
-  [(set (match_operand:SI 0 "register_operand" "=r,?r")
-     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm")))
-   (clobber (reg:CC 17))]
+(define_expand "zero_extendhisi2"
+  [(set (match_operand:SI 0 "register_operand" "")
+     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
   ""
-  "*
+  "
 {
-  switch (get_attr_type (insn))
+  if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
     {
-    case TYPE_ALU1:
-      if (!REG_P (operands[1]) || REGNO (operands[0]) != REGNO (operands[1]))
-       abort ();
-      operands[1] = GEN_INT (0xffff);
-      return \"and{l}\\t{%1, %0|%0, %1}\";
-    default:
-      return \"movz{wl|x}\\t{%1, %0|%0, %1}\";
+      operands[1] = force_reg (HImode, operands[1]);
+      emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
+      DONE;
     }
-}"
-  [(set (attr "type")
-     (if_then_else (and (eq_attr "alternative" "0")
-                       (ne (symbol_ref "TARGET_ZERO_EXTEND_WITH_AND")
-                           (const_int 0)))
-       (const_string "alu1")
-       (const_string "imovx")))])
+}")
 
-(define_split
-  [(set (match_operand:SI 0 "register_operand" "")
-       (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))
+(define_insn "zero_extendhisi2_and"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+     (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
    (clobber (reg:CC 17))]
-  "reload_completed
-   && TARGET_ZERO_EXTEND_WITH_AND
-   && !reg_overlap_mentioned_p (operands[0], operands[1])"
-  [(parallel [(set (match_dup 0) (const_int 0))
-             (clobber (reg:CC 17))])
-   (set (strict_low_part (subreg:HI (match_dup 0) 0)) (match_dup 1))]
-  "")
+  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
+  "#"
+  [(set_attr "type" "alu1")])
 
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
-       (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))
+       (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
    (clobber (reg:CC 17))]
-  "reload_completed
-   && TARGET_ZERO_EXTEND_WITH_AND
-   && reg_overlap_mentioned_p (operands[0], operands[1])"
-  [(set (strict_low_part (subreg:HI (match_dup 0) 0)) (match_dup 1))
-   (parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
+  "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
+  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
              (clobber (reg:CC 17))])]
   "")
 
-(define_insn "zero_extendqihi2"
-  [(set (match_operand:HI 0 "register_operand" "=q,r,r")
-     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,0,qm")))
-   (clobber (reg:CC 17))]
+(define_insn "*zero_extendhisi2_movzwl"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+     (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
+  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
+  "movz{wl|x}\\t{%1, %0|%0, %1}"
+  [(set_attr "type" "imovx")])
+
+(define_expand "zero_extendqihi2"
+  [(parallel
+    [(set (match_operand:HI 0 "register_operand" "")
+       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
+     (clobber (reg:CC 17))])]
   ""
-  "*
-{
-  switch (get_attr_type (insn))
-    {
-    case TYPE_ALU1:
-      if (!REG_P (operands[1]) || REGNO (operands[0]) != REGNO (operands[1]))
-       abort ();
-      operands[1] = GEN_INT (0xff);
-      return \"and{l}\\t{%1, %k0|%k0, %1}\";
-    default:
-      return \"movz{bw|x}\\t{%1, %0|%0, %1}\";
-    }
-}"
-  [(set (attr "type")
-     (cond [(and (eq_attr "alternative" "0")
-                (ne (symbol_ref "TARGET_ZERO_EXTEND_WITH_AND")
-                    (const_int 0)))
-             (const_string "alu1")
-           (eq_attr "alternative" "1")
-             (const_string "alu1")
-          ]
-           (const_string "imovx")))])
+  "")
+
+(define_insn "*zero_extendqihi2_and"
+  [(set (match_operand:HI 0 "register_operand" "=r,?&q")
+     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
+   (clobber (reg:CC 17))]
+  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
+  "#"
+  [(set_attr "type" "alu1")])
+
+(define_insn "*zero_extendqihi2_movzbw_and"
+  [(set (match_operand:HI 0 "register_operand" "=r,r")
+     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
+   (clobber (reg:CC 17))]
+  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
+  "#"
+  [(set_attr "type" "imovx,alu1")])
 
+(define_insn "*zero_extendqihi2_movzbw"
+  [(set (match_operand:HI 0 "register_operand" "=r")
+     (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
+  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
+  "movz{bw|x}\\t{%1, %0|%0, %1}"
+  [(set_attr "type" "imovx")])
+
+;; For the movzbw case strip only the clobber
 (define_split
   [(set (match_operand:HI 0 "register_operand" "")
        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
    (clobber (reg:CC 17))]
-  "reload_completed
-   && QI_REG_P (operands[0])
-   && TARGET_ZERO_EXTEND_WITH_AND
-   && !reg_overlap_mentioned_p (operands[0], operands[1])"
-  [(parallel [(set (match_dup 0) (const_int 0))
-             (clobber (reg:CC 17))])
-   (set (strict_low_part (subreg:QI (match_dup 0) 0)) (match_dup 1))]
-  "")
+  "reload_completed 
+   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
+   && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
+  [(set (match_operand:HI 0 "register_operand" "")
+       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
 
+;; When source and destination does not overlap, clear destination
+;; first and then do the movb
 (define_split
   [(set (match_operand:HI 0 "register_operand" "")
-       (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))
+       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
    (clobber (reg:CC 17))]
   "reload_completed
    && QI_REG_P (operands[0])
-   && TARGET_ZERO_EXTEND_WITH_AND
-   && reg_overlap_mentioned_p (operands[0], operands[1])"
-  [(set (strict_low_part (subreg:QI (match_dup 0) 0)) (match_dup 1))
-   (parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
-             (clobber (reg:CC 17))])]
-  "")
+   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
+   && !reg_overlap_mentioned_p (operands[0], operands[1])"
+  [(set (match_dup 0) (const_int 0))
+   (set (strict_low_part (match_dup 2)) (match_dup 1))]
+  "operands[2] = gen_lowpart (QImode, operands[0]);")
 
+;; Rest is handled by single and.
 (define_split
   [(set (match_operand:HI 0 "register_operand" "")
        (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
    (clobber (reg:CC 17))]
   "reload_completed
-   && TARGET_ZERO_EXTEND_WITH_AND
-   && ! reg_overlap_mentioned_p (operands[0], operands[1])"
-  [(set (match_dup 0) (subreg:HI (match_dup 1) 0))
-   (parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
+   && true_regnum (operands[0]) == true_regnum (operands[1])"
+  [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
              (clobber (reg:CC 17))])]
   "")
 
-(define_insn "zero_extendqisi2"
-  [(set (match_operand:SI 0 "register_operand" "=q,r,r")
-     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,0,qm")))
-   (clobber (reg:CC 17))]
+(define_expand "zero_extendqisi2"
+  [(parallel
+    [(set (match_operand:SI 0 "register_operand" "")
+       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
+     (clobber (reg:CC 17))])]
   ""
-  "*
-{
-  switch (get_attr_type (insn))
-    {
-    case TYPE_ALU1:
-      if (!REG_P (operands[1]) || REGNO (operands[0]) != REGNO (operands[1]))
-       abort ();
-      operands[1] = GEN_INT (0xff);
-      return \"and{l}\\t{%1, %0|%0, %1}\";
-    default:
-      return \"movz{bl|x}\\t{%1, %0|%0, %1}\";
-    }
-}"
-  [(set (attr "type")
-     (cond [(and (eq_attr "alternative" "0")
-                (ne (symbol_ref "TARGET_ZERO_EXTEND_WITH_AND")
-                    (const_int 0)))
-             (const_string "alu1")
-           (eq_attr "alternative" "1")
-             (const_string "alu1")
-          ]
-           (const_string "imovx")))])
+  "")
+
+(define_insn "*zero_extendqisi2_and"
+  [(set (match_operand:SI 0 "register_operand" "=r,?&q")
+     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
+   (clobber (reg:CC 17))]
+  "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
+  "#"
+  [(set_attr "type" "alu1")])
+
+(define_insn "*zero_extendqisi2_movzbw_and"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
+   (clobber (reg:CC 17))]
+  "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
+  "#"
+  [(set_attr "type" "imovx,alu1")])
 
+(define_insn "*zero_extendqisi2_movzbw"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+     (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
+  "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
+  "movz{bl|x}\\t{%1, %0|%0, %1}"
+  [(set_attr "type" "imovx")])
+
+;; For the movzbl case strip only the clobber
+(define_split
+  [(set (match_operand:SI 0 "register_operand" "")
+       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
+   (clobber (reg:CC 17))]
+  "reload_completed 
+   && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
+   && (!REG_P (operands[1]) || QI_REG_P (operands[1]))"
+  [(set (match_dup 0)
+       (zero_extend:SI (match_dup 1)))])
+
+;; When source and destination does not overlap, clear destination
+;; first and then do the movb
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
    (clobber (reg:CC 17))]
   "reload_completed
-   && TARGET_ZERO_EXTEND_WITH_AND
    && QI_REG_P (operands[0])
-   && (GET_CODE (operands[1]) == MEM || QI_REG_P (operands[1]))
+   && (QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
+   && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
    && !reg_overlap_mentioned_p (operands[0], operands[1])"
-  [(parallel [(set (match_dup 0) (const_int 0))
-             (clobber (reg:CC 17))])
-   (set (strict_low_part (subreg:QI (match_dup 0) 0)) (match_dup 1))]
-  "")
+  [(set (match_dup 0) (const_int 0))
+   (set (strict_low_part (match_dup 2)) (match_dup 1))]
+  "operands[2] = gen_lowpart (QImode, operands[0]);")
 
+;; Rest is handled by single and.
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
        (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
    (clobber (reg:CC 17))]
   "reload_completed
-   && TARGET_ZERO_EXTEND_WITH_AND
-   && ! reg_overlap_mentioned_p (operands[0], operands[1])"
-  [(set (match_dup 0) (subreg:SI (match_dup 1) 0))
-   (parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
+   && true_regnum (operands[0]) == true_regnum (operands[1])"
+  [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
              (clobber (reg:CC 17))])]
   "")