This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

i386.md splits (hope final version)


Hi

I've found bug in my code causing crash when sign_extend to memory was called with SUBREG parameter
(REG_P didn't returned true and memory to memory move was emited). This patch actually fixes it.
Also I've browsed crafty code and found that many sign extensions to memory are done. So I've added
new split for it that does shift in register, not in memory. It uses clobber, so please look at this
part if it is correct. Otherwise hope, that this patch is OK for inclusion now as soon as the copyright
stuff is done.  I will separate another patch and send it soon. Hope it will case less problems.

Compiler bootstraps and no new failures are found with this patch.

Oct 7 08:58:58 1998  Jan Hubicka <hubicka@freesoft.cz>

	* i386.md: Change ix86_cpu == PROCESSOR_PENTIUM to TARGET_PENTIUM
	(zero_extendsidi2): split it, support extending from other
	register and to memory to avoid unnecesary moves of extended value
	Use # in pattern and handle completely by splits.
	(extendsidi2): likewise, don't generate cltd at pentium.
	(ashiftrt_32): New pattern

*** gcc/config/i386/i386.md.orig	Thu Oct  1 18:29:54 1998
--- gcc/config/i386/i386.md	Wed Oct  7 15:05:52 1998
***************
*** 1252,1258 ****
       It is at least as fast as xor on any processor except a Pentium. */
  
    if (operands[1] == const1_rtx
!       && ix86_cpu == PROCESSOR_PENTIUM
        && (link = find_reg_note (insn, REG_WAS_0, 0))
        /* Make sure the insn that stored the 0 is still present.  */
        && ! INSN_DELETED_P (XEXP (link, 0))
--- 1252,1258 ----
       It is at least as fast as xor on any processor except a Pentium. */
  
    if (operands[1] == const1_rtx
!       && TARGET_PENTIUM
        && (link = find_reg_note (insn, REG_WAS_0, 0))
        /* Make sure the insn that stored the 0 is still present.  */
        && ! INSN_DELETED_P (XEXP (link, 0))
***************
*** 1313,1319 ****
    /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8.  */
  
    if (operands[1] == const1_rtx
!       && ix86_cpu == PROCESSOR_PENTIUM
        && ! NON_QI_REG_P (operands[0])
        && (link = find_reg_note (insn, REG_WAS_0, 0))
        /* Make sure the insn that stored the 0 is still present.  */
--- 1313,1319 ----
    /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8.  */
  
    if (operands[1] == const1_rtx
!       && TARGET_PENTIUM
        && ! NON_QI_REG_P (operands[0])
        && (link = find_reg_note (insn, REG_WAS_0, 0))
        /* Make sure the insn that stored the 0 is still present.  */
***************
*** 2022,2081 ****
   "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
  
  (define_insn "zero_extendsidi2"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m")
! 	(zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))]
    ""
!   "*
!   {
!   rtx high[2], low[2], xops[4];
! 
!   if (REG_P (operands[0]) && REG_P (operands[1])
!       && REGNO (operands[0]) == REGNO (operands[1]))
!     {
!       operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
!       return AS2 (xor%L0,%0,%0);
!     }
! 
!   split_di (operands, 1, low, high);
!   xops[0] = low[0];
!   xops[1] = operands[1];
!   xops[2] = high[0];
!   xops[3] = const0_rtx;
! 
!   output_asm_insn (AS2 (mov%L0,%1,%0), xops);
!   if (GET_CODE (low[0]) == MEM)
!     output_asm_insn (AS2 (mov%L2,%3,%2), xops);
!   else
!     output_asm_insn (AS2 (xor%L2,%2,%2), xops);
  
!   RET;
! }")
  
  ;;- sign extension instructions
  
  (define_insn "extendsidi2"
!   [(set (match_operand:DI 0 "register_operand" "=r")
! 	(sign_extend:DI (match_operand:SI 1 "register_operand" "0")))]
!   ""
!   "*
! {
!   if (REGNO (operands[0]) == 0)
!     {
!       /* This used to be cwtl, but that extends HI to SI somehow.  */
! #ifdef INTEL_SYNTAX
!       return \"cdq\";
! #else
!       return \"cltd\";
! #endif
!     }
! 
!   operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
!   output_asm_insn (AS2 (mov%L0,%0,%1), operands);
! 
!   operands[0] = GEN_INT (31);
!   return AS2 (sar%L1,%0,%1);
! }")
  
  ;; Note that the i386 programmers' manual says that the opcodes
  ;; are named movsx..., but the assembler on Unix does not accept that.
  ;; We use what the Unix assembler expects.
--- 2022,2093 ----
   "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));")
  
  (define_insn "zero_extendsidi2"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o")
! 	(zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))]
    ""
!   "#")
  
! (define_split 
!   [(set (match_operand:DI 0 "nonimmediate_operand" "")
! 	(zero_extend:DI (match_operand:SI 1 "general_operand" "")))]
!   "reload_completed"
!   [(set (match_dup 3) (match_dup 1))
!    (set (match_dup 4) (const_int 0))]
!   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
  
  ;;- sign extension instructions
  
  (define_insn "extendsidi2"
!   [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*?o")
! 	(sign_extend:DI (match_operand:SI 1 "general_operand" "0,0,mr,r")))
!    (clobber (match_scratch:SI 2 "=X,X,X,1"))]
!   ""
!   "#")
! 
! ;; Extend to memory case - to avoid shifting in memory, clober source register
! (define_split 
!   [(set (match_operand:DI 0 "memory_operand" "")
! 	(sign_extend:DI (match_operand:SI 1 "general_operand" "")))
!    (clobber (match_dup 1))]
!   "reload_completed
!    && (!REG_P (operands[0]) || REGNO (operands[0]) != 0
!    || (!optimize_size && TARGET_PENTIUM))"
!   [(set (match_dup 3) (match_dup 1))
!    (set (match_dup 1)
!         (ashiftrt:SI (match_dup 1) (const_int 31)))
!    (set (match_dup 4) (match_dup 1))]
!   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
! 
! ;; When parameter is in register it is better to copy from it to avoid
! ;; dependencies.
! ;; When parameter is in memory, copy it to destination and then again.
! 
! (define_split 
!   [(set (match_operand:DI 0 "nonimmediate_operand" "")
! 	(sign_extend:DI (match_operand:SI 1 "general_operand" "")))
!    (clobber (match_scratch:SI 2 "X"))]
!   "reload_completed
!    && (!REG_P (operands[0]) || REGNO (operands[0]) != 0
!    || (!optimize_size && TARGET_PENTIUM))"
!   [(set (match_dup 3) (match_dup 1))
!    (set (match_dup 4) (match_dup 5))
!    (set (match_dup 4)
!         (ashiftrt:SI (match_dup 4) (const_int 31)))]
!   "split_di (&operands[0], 1, &operands[3], &operands[4]);
!    if (GET_CODE (operands[1]) != MEM) operands[5] = operands[1]; else operands[5] = operands[3];")
  
+ (define_split 
+   [(set (match_operand:DI 0 "register_operand" "")
+ 	(sign_extend:DI (match_operand:SI 1 "general_operand" "")))
+    (clobber (match_scratch:SI 2 "X"))]
+   "reload_completed
+    && REG_P (operands[0]) && REGNO (operands[0]) == 0
+    && (optimize_size || !TARGET_PENTIUM)"
+   [(set (match_dup 3) (match_dup 1))
+    (set (match_dup 4)
+         (ashiftrt:SI (match_dup 3) (const_int 31)))]
+   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
  ;; Note that the i386 programmers' manual says that the opcodes
  ;; are named movsx..., but the assembler on Unix does not accept that.
  ;; We use what the Unix assembler expects.
*************** byte_xor_operation:
*** 4850,4855 ****
--- 4862,4876 ----
  
    RET;
  }")
+ 
+ (define_insn "ashrsi3_31"
+   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d")
+ 	(ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a")
+ 		     (const_int 31)))]
+   "!TARGET_PENTIUM || optimize_size"
+   "@
+     sar%L0 $31,%0
+     cltd")
  
  (define_insn "ashrsi3"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")

-- 
                       OK. Lets make a signature file.
+-------------------------------------------------------------------------+
|        Jan Hubicka (Jan Hubi\v{c}ka in TeX) hubicka@freesoft.cz         |
|         Czech free software foundation: http://www.freesoft.cz          |
|AA project - the new way for computer graphics - http://www.ta.jcu.cz/aa |
|  homepage: http://www.paru.cas.cz/~hubicka/, games koules, Xonix, fast  |
|  fractal zoomer XaoS, index of Czech GNU/Linux/UN*X documentation etc.  | 
+-------------------------------------------------------------------------+


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]