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