aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1999-07-08 19:22:44 +0000
committerRichard Henderson <rth@cygnus.com>1999-07-08 19:22:44 +0000
commit4678c90678ee6d6eaf10879d0a5210c2a2c90faa (patch)
treec20d7ff57b5853ef47e44248b363b285d735755e
parent3fb867412146ca3b5db3a3c8e2bf2ac968a2536a (diff)
* i386.md (movstricthi_1): Fix parenthesis in conditional.
(movstrictqi_1): Likewise. 1999-07-08 Jan Hubicka <hubicka@freesoft.cz> * i386.md: New peep2 patterns for TEST to AND conversion. (testsi_1): Recognize "test imm,eax" as uv pairable. (testhi_1, testqi_1): Likewise. (andqi_ext_0_cc): New pattern. git-svn-id: https://gcc.gnu.org/svn/gcc/branches/new_ia32_branch@28028 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.P212
-rw-r--r--gcc/config/i386/i386.md152
2 files changed, 144 insertions, 20 deletions
diff --git a/gcc/ChangeLog.P2 b/gcc/ChangeLog.P2
index a2a0f4c6256..74ffb8faf20 100644
--- a/gcc/ChangeLog.P2
+++ b/gcc/ChangeLog.P2
@@ -1,3 +1,15 @@
+1999-07-08 Richard Henderson <rth@cygnus.com>
+
+ * i386.md (movstricthi_1): Fix parenthesis in conditional.
+ (movstrictqi_1): Likewise.
+
+1999-07-08 Jan Hubicka <hubicka@freesoft.cz>
+
+ * i386.md: New peep2 patterns for TEST to AND conversion.
+ (testsi_1): Recognize "test imm,eax" as uv pairable.
+ (testhi_1, testqi_1): Likewise.
+ (andqi_ext_0_cc): New pattern.
+
1999-07-01 Richard Henderson <rth@cygnus.com>
* i386.c (ix86_aligned_reg_p): Delete.
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index f80b2da8706..00661a22aba 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1213,7 +1213,7 @@
[(set (strict_low_part (match_operand:HI 0 "general_operand" "+g,r"))
(match_operand:HI 1 "general_operand" "rn,m"))]
"! TARGET_PARTIAL_REG_STALL
- && GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"mov{w}\\t{%1, %0|%0, %1}"
[(set_attr "type" "imov")])
@@ -1382,7 +1382,7 @@
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
(match_operand:QI 1 "general_operand" "*qn,m"))]
"! TARGET_PARTIAL_REG_STALL
- && GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"mov{b}\\t{%1, %0|%0, %1}"
[(set_attr "type" "imov")])
@@ -3812,44 +3812,38 @@
;;- Logical AND instructions
+;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
+;; Note that this excludes ah.
+
(define_insn "testsi_1"
[(set (reg:CCNO 17)
- (compare:CCNO (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
- (match_operand:SI 1 "general_operand" "rin"))
+ (compare:CCNO (and:SI (match_operand:SI 0 "nonimmediate_operand" "%*a,r,rm")
+ (match_operand:SI 1 "general_operand" "in,in,rin"))
(const_int 0)))]
""
"test{l}\\t{%1, %0|%0, %1}"
[(set_attr "type" "icmp")
- (set (attr "pent_pair")
- (if_then_else (match_operand 1 "immediate_operand" "")
- (const_string "np")
- (const_string "uv")))])
+ (set_attr "pent_pair" "uv,np,uv")])
(define_insn "*testhi_1"
[(set (reg:CCNO 17)
- (compare:CCNO (and:HI (match_operand:HI 0 "nonimmediate_operand" "%rm")
- (match_operand:HI 1 "general_operand" "rn"))
+ (compare:CCNO (and:HI (match_operand:HI 0 "nonimmediate_operand" "%*a,r,rm")
+ (match_operand:HI 1 "general_operand" "n,n,rn"))
(const_int 0)))]
""
"test{w}\\t{%1, %0|%0, %1}"
[(set_attr "type" "icmp")
- (set (attr "pent_pair")
- (if_then_else (match_operand 1 "immediate_operand" "")
- (const_string "np")
- (const_string "uv")))])
+ (set_attr "pent_pair" "uv,np,uv")])
(define_insn "testqi_1"
[(set (reg:CCNO 17)
- (compare:CCNO (and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm")
- (match_operand:QI 1 "general_operand" "qn"))
+ (compare:CCNO (and:QI (match_operand:QI 0 "nonimmediate_operand" "%*a,q,qm")
+ (match_operand:QI 1 "general_operand" "n,n,qn"))
(const_int 0)))]
""
"test{b}\\t{%1, %0|%0, %1}"
[(set_attr "type" "icmp")
- (set (attr "pent_pair")
- (if_then_else (match_operand 1 "immediate_operand" "")
- (const_string "np")
- (const_string "uv")))])
+ (set_attr "pent_pair" "uv,np,uv")])
;; ??? A bug in recog prevents it from recognizing a const_int as an
;; operand to zero_extend in andqi_ext_1. It was checking explicitly
@@ -4179,6 +4173,32 @@
"and{b}\\t{%2, %h0|%h0, %2}"
[(set_attr "type" "alu")])
+;; Generated by peephole translating test to and. This shows up
+;; often in fp comparisons.
+
+(define_insn "*andqi_ext_0_cc"
+ [(set (reg:CCNO 17)
+ (compare:CCNO
+ (and:SI
+ (zero_extract:SI
+ (match_operand 1 "ext_register_operand" "q")
+ (const_int 8)
+ (const_int 8))
+ (match_operand 2 "const_int_operand" "n"))
+ (const_int 0)))
+ (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
+ (const_int 8)
+ (const_int 8))
+ (and:SI
+ (zero_extract:SI
+ (match_dup 1)
+ (const_int 8)
+ (const_int 8))
+ (match_dup 2)))]
+ "(unsigned HOST_WIDE_INT)INTVAL (operands[2]) <= 0xff"
+ "and{b}\\t{%2, %h0|%h0, %2}"
+ [(set_attr "type" "alu")])
+
(define_insn "*andqi_ext_1"
[(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
(const_int 8)
@@ -7699,6 +7719,98 @@
(clobber (reg:CC 17))])]
"")
+;; Non pairable "test imm, reg" instructions can be translated to
+;; "and imm, reg" if reg dies. The "and" form is also shorter (one
+;; byte opcode instead of two, have a short form for byte operands),
+;; so do it for other CPUs as well. Given that the value was dead,
+;; this should not create any new dependancies. Pass on the sub-word
+;; versions if we're concerned about partial register stalls.
+
+(define_peephole2
+ [(set (reg:CCNO 17)
+ (compare:CCNO (and:SI (match_operand:SI 0 "register_operand" "")
+ (match_operand:SI 1 "immediate_operand" ""))
+ (const_int 0)))]
+ "(true_regnum (operands[0]) != 0
+ || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
+ && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
+ [(parallel
+ [(set (reg:CCNO 17)
+ (compare:CCNO (and:SI (match_dup 0)
+ (match_dup 1))
+ (const_int 0)))
+ (set (match_dup 0)
+ (and:SI (match_dup 0) (match_dup 1)))])]
+ "")
+
+(define_peephole2
+ [(set (reg:CCNO 17)
+ (compare:CCNO (and:HI (match_operand:HI 0 "register_operand" "")
+ (match_operand:HI 1 "immediate_operand" ""))
+ (const_int 0)))]
+ "! TARGET_PARTIAL_REG_STALL
+ && (true_regnum (operands[0]) != 0
+ || CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'K'))
+ && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
+ [(parallel
+ [(set (reg:CCNO 17)
+ (compare:CCNO (and:HI (match_dup 0)
+ (match_dup 1))
+ (const_int 0)))
+ (set (match_dup 0)
+ (and:HI (match_dup 0) (match_dup 1)))])]
+ "")
+
+(define_peephole2
+ [(set (reg:CCNO 17)
+ (compare:CCNO (and:QI (match_operand:QI 0 "register_operand" "")
+ (match_operand:QI 1 "immediate_operand" ""))
+ (const_int 0)))]
+ "! TARGET_PARTIAL_REG_STALL
+ && true_regnum (operands[0]) != 0
+ && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
+ [(parallel
+ [(set (reg:CCNO 17)
+ (compare:CCNO (and:QI (match_dup 0)
+ (match_dup 1))
+ (const_int 0)))
+ (set (match_dup 0)
+ (and:QI (match_dup 0) (match_dup 1)))])]
+ "")
+
+(define_peephole2
+ [(set (reg:CCNO 17)
+ (compare:CCNO
+ (and:SI
+ (zero_extract:SI
+ (match_operand 0 "ext_register_operand" "q")
+ (const_int 8)
+ (const_int 8))
+ (match_operand 1 "const_int_operand" "n"))
+ (const_int 0)))]
+ "! TARGET_PARTIAL_REG_STALL
+ && true_regnum (operands[0]) != 0
+ && find_regno_note (insn, REG_DEAD, true_regnum (operands[0]))"
+ [(parallel [(set (reg:CCNO 17)
+ (compare:CCNO
+ (and:SI
+ (zero_extract:SI
+ (match_dup 0)
+ (const_int 8)
+ (const_int 8))
+ (match_dup 1))
+ (const_int 0)))
+ (set (zero_extract:SI (match_dup 0)
+ (const_int 8)
+ (const_int 8))
+ (and:SI
+ (zero_extract:SI
+ (match_dup 0)
+ (const_int 8)
+ (const_int 8))
+ (match_dup 1)))])]
+ "")
+
;; Don't do logical operations with memory inputs.
(define_peephole2
[(parallel [(set (match_operand:SI 0 "register_operand" "")