New x86 backend and my regstack changes...
Richard Henderson
rth@cygnus.com
Sat Jul 31 22:30:00 GMT 1999
On Fri, Jul 02, 1999 at 10:40:25AM -0700, Richard Henderson wrote:
> > I will try it. The eax case is better, because short version of test
> > instruction results (test instruciton with immediate and non-eax parameter
> > is one byte longer). Fact is that this messes up the preferences in other
> > forms of test instruction as well, so your suggestion is most probably good
> > idea. I've done this change before the peepholers, that now does most of
> > the job. W/o peepholers this change helped a bit on XaoS executable. With
> > the peepholers it is hard to see test imm at all now..
> > So please add the asterisk there...
Here's what I committed. Mostly just cosmetic changes,
mostly wrt the pent_pair definition.
r~
Index: i386.md
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.78.2.6
diff -c -p -d -r1.78.2.6 i386.md
*** i386.md 1999/07/01 19:03:24 1.78.2.6
--- i386.md 1999/07/09 02:16:40
***************
*** 3812,3855 ****
;;- Logical AND instructions
(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"))
(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")))])
(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"))
(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")))])
(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"))
(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")))])
;; ??? 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
--- 3812,3849 ----
;;- 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" "%*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" "uv,np,uv")])
(define_insn "*testhi_1"
[(set (reg:CCNO 17)
! (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" "uv,np,uv")])
(define_insn "testqi_1"
[(set (reg:CCNO 17)
! (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" "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,4184 ****
--- 4173,4204 ----
"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)
***************
*** 7697,7702 ****
--- 7717,7814 ----
[(parallel [(set (match_dup 0)
(xor:QI (match_dup 1) (const_int -1)))
(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.
More information about the Gcc-patches
mailing list