aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorZack Weinberg <zackw@stanford.edu>2001-05-17 00:53:25 +0000
committerZack Weinberg <zack@gcc.gnu.org>2001-05-17 00:53:25 +0000
commita3e991f29855a3d949802c7e18aa09604e9ed191 (patch)
treed46d91043ac8d0ca2c252b6699ce8f8098b1a562 /gcc/config
parent12b38507e683988f660c80b6910ec4a9231eb2a0 (diff)
downloadgcc-a3e991f29855a3d949802c7e18aa09604e9ed191.zip
gcc-a3e991f29855a3d949802c7e18aa09604e9ed191.tar.gz
gcc-a3e991f29855a3d949802c7e18aa09604e9ed191.tar.bz2
i386.md: Add two peepholes to clean up code generated by cmpstr* expanders.
* i386.md: Add two peepholes to clean up code generated by cmpstr* expanders. From-SVN: r42183
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/i386/i386.md85
1 files changed, 85 insertions, 0 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index b85e585..a5bad66 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -15463,6 +15463,91 @@
[(set_attr "type" "str")
(set_attr "mode" "QI")
(set_attr "prefix_rep" "1")])
+
+;; Peephole optimizations to clean up after cmpstr*. This should be
+;; handled in combine, but it is not currently up to the task.
+;; When used for their truth value, the cmpstr* expanders generate
+;; code like this:
+;;
+;; repz cmpsb
+;; seta %al
+;; setb %dl
+;; cmpb %al, %dl
+;; jcc label
+;;
+;; The intermediate three instructions are unnecessary.
+
+;; This one handles cmpstr*_nz_1...
+(define_peephole2
+ [(parallel[
+ (set (reg:CC 17)
+ (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
+ (mem:BLK (match_operand 5 "register_operand" ""))))
+ (use (match_operand 6 "register_operand" ""))
+ (use (match_operand:SI 3 "immediate_operand" ""))
+ (use (reg:SI 19))
+ (clobber (match_operand 0 "register_operand" ""))
+ (clobber (match_operand 1 "register_operand" ""))
+ (clobber (match_operand 2 "register_operand" ""))])
+ (set (match_operand:QI 7 "register_operand" "")
+ (gtu:QI (reg:CC 17) (const_int 0)))
+ (set (match_operand:QI 8 "register_operand" "")
+ (ltu:QI (reg:CC 17) (const_int 0)))
+ (set (reg 17)
+ (compare (match_dup 7) (match_dup 8)))
+ ]
+ ""
+ [(parallel[
+ (set (reg:CC 17)
+ (compare:CC (mem:BLK (match_dup 4))
+ (mem:BLK (match_dup 5))))
+ (use (match_dup 6))
+ (use (match_dup 3))
+ (use (reg:SI 19))
+ (clobber (match_dup 0))
+ (clobber (match_dup 1))
+ (clobber (match_dup 2))])]
+ "")
+
+;; ...and this one handles cmpstr*_1.
+(define_peephole2
+ [(parallel[
+ (set (reg:CC 17)
+ (if_then_else:CC (ne (match_operand 6 "register_operand" "")
+ (const_int 0))
+ (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
+ (mem:BLK (match_operand 5 "register_operand" "")))
+ (const_int 0)))
+ (use (match_operand:SI 3 "immediate_operand" ""))
+ (use (reg:CC 17))
+ (use (reg:SI 19))
+ (clobber (match_operand 0 "register_operand" ""))
+ (clobber (match_operand 1 "register_operand" ""))
+ (clobber (match_operand 2 "register_operand" ""))])
+ (set (match_operand:QI 7 "register_operand" "")
+ (gtu:QI (reg:CC 17) (const_int 0)))
+ (set (match_operand:QI 8 "register_operand" "")
+ (ltu:QI (reg:CC 17) (const_int 0)))
+ (set (reg 17)
+ (compare (match_dup 7) (match_dup 8)))
+ ]
+ ""
+ [(parallel[
+ (set (reg:CC 17)
+ (if_then_else:CC (ne (match_dup 6)
+ (const_int 0))
+ (compare:CC (mem:BLK (match_dup 4))
+ (mem:BLK (match_dup 5)))
+ (const_int 0)))
+ (use (match_dup 3))
+ (use (reg:CC 17))
+ (use (reg:SI 19))
+ (clobber (match_dup 0))
+ (clobber (match_dup 1))
+ (clobber (match_dup 2))])]
+ "")
+
+
;; Conditional move instructions.