aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@freesoft.cz>1999-12-01 14:38:50 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>1999-12-01 13:38:50 +0000
commit8f7661f2b80a2bf7618e4436e416ef325ebae27e (patch)
tree02608155d51aaf8345f295c5879af703653329e5
parentb5b8a0e7794975bd86d0a30b7ffb28a9d9f2f6c1 (diff)
downloadgcc-8f7661f2b80a2bf7618e4436e416ef325ebae27e.zip
gcc-8f7661f2b80a2bf7618e4436e416ef325ebae27e.tar.gz
gcc-8f7661f2b80a2bf7618e4436e416ef325ebae27e.tar.bz2
i386.md (zero_extend?i?i2): Rewrite to expanders; new patterns rewrite splitters.
* i386.md (zero_extend?i?i2): Rewrite to expanders; new patterns rewrite splitters. From-SVN: r30740
-rw-r--r--gcc/ChangeLog3
-rw-r--r--gcc/config/i386/i386.md238
2 files changed, 124 insertions, 117 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2b1cd26..8f3c7e1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 99ba4ad..562f08f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2167,172 +2167,176 @@
;; 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))])]
"")