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]

better fp truncation sequence on i386



Hi
Tim Prince has noticed, that current sequence emitted for float->int
converisons on i386 is several times slower than 2.95 ones on P3/P4.
The purpose is an partial memory stall, so I've redesigned the patterns
to use back original sequence.

Moreover I've split the control word value generation from pattern itself, so
redundant initialzations are usually eliminated.

There is an important drawback still.  The FIX patterns now do use USE
and combine is not able to combine memory output to the pattern, as it loses
that uses.  I will try to fix this at combine side.

Overall it should be still better to make unconditional pre-reload splitter
pass to add the USEs and use mode_switching pass to initialize the CW values.
Unconditional pre-reload splitting can be usefull on number of other passes
as well.  Can be OK if I add one?

Bootstrapped on i686
Honza

Pá čen 22 18:47:46 CEST 2001  Jan Hubicka  <jh@suse.cz>
	* i386-protos.h (emit_i387_cw_initialization): Declare.
	* i386.md (movsi_insv_1): Remove '*'.
	(fix_trunc?f?i2): Revamp to use control word parameters.
	(fix_trunc?i_1): Likewise; update splitters.
	(fix splitter): Remove.
	* i386.c (MAX_386_STACK_LOCALS): set to 3.
	(emit_i387_cw_initialization): New function.
	(output_fix_trunc): Do not initialize control word;
	kill dead code; simplify.
*** i386.work/i386-protos.h	Fri Jun 22 17:20:12 2001
--- i386/i386-protos.h	Fri Jun 22 18:36:11 2001
*************** extern enum reg_class ix86_preferred_rel
*** 154,159 ****
--- 154,160 ----
  extern int ix86_memory_move_cost PARAMS ((enum machine_mode, enum reg_class,
  					  int));
  extern void ix86_set_move_mem_attrs PARAMS ((rtx, rtx, rtx, rtx, rtx));
+ extern void emit_i387_cw_initialization PARAMS ((rtx, rtx));
  
  
  #ifdef TREE_CODE
*** i386.work/i386.md	Fri Jun 22 17:20:13 2001
--- i386/i386.md	Fri Jun 22 18:17:36 2001
***************
*** 2313,2319 ****
  	(const_string "SI")
  	(const_string "QI")))])
  
! (define_insn "*movsi_insv_1"
    [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
  			 (const_int 8)
  			 (const_int 8))
--- 2313,2319 ----
  	(const_string "SI")
  	(const_string "QI")))])
  
! (define_insn "movsi_insv_1"
    [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
  			 (const_int 8)
  			 (const_int 8))
***************
*** 4692,4723 ****
  (define_expand "fix_truncxfdi2"
    [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
  		   (fix:DI (match_operand:XF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))
  	      (clobber (match_scratch:XF 5 ""))])]
    "TARGET_80387 && !TARGET_64BIT"
!   "operands[2] = assign_386_stack_local (SImode, 0);
!    operands[3] = assign_386_stack_local (DImode, 1);")
  
  (define_expand "fix_trunctfdi2"
    [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
  		   (fix:DI (match_operand:TF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))
! 	      (clobber (match_scratch:TF 5 ""))])]
    "TARGET_80387"
!   "operands[2] = assign_386_stack_local (SImode, 0);
!    operands[3] = assign_386_stack_local (DImode, 1);")
  
  (define_expand "fix_truncdfdi2"
    [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
  		   (fix:DI (match_operand:DF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))
! 	      (clobber (match_scratch:DF 5 ""))])]
    "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
    "
  {
--- 4692,4727 ----
  (define_expand "fix_truncxfdi2"
    [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
  		   (fix:DI (match_operand:XF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))
  	      (clobber (match_scratch:XF 5 ""))])]
    "TARGET_80387 && !TARGET_64BIT"
!   "operands[2] = assign_386_stack_local (HImode, 1);
!    operands[3] = assign_386_stack_local (HImode, 2);
!    emit_i387_cw_initialization (operands[2], operands[3]);
!    operands[4] = assign_386_stack_local (DImode, 0);")
  
  (define_expand "fix_trunctfdi2"
    [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
  		   (fix:DI (match_operand:TF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))
! 	      (clobber (match_scratch:XF 5 ""))])]
    "TARGET_80387"
!   "operands[2] = assign_386_stack_local (HImode, 1);
!    operands[3] = assign_386_stack_local (HImode, 2);
!    emit_i387_cw_initialization (operands[2], operands[3]);
!    operands[4] = assign_386_stack_local (DImode, 0);")
  
  (define_expand "fix_truncdfdi2"
    [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
  		   (fix:DI (match_operand:DF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))
! 	      (clobber (match_scratch:XF 5 ""))])]
    "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
    "
  {
***************
*** 4731,4748 ****
     }
    else
     {
!      operands[2] = assign_386_stack_local (SImode, 0);
!      operands[3] = assign_386_stack_local (DImode, 1);
     }
  }")
  
  (define_expand "fix_truncsfdi2"
    [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
  		   (fix:DI (match_operand:SF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))
! 	      (clobber (match_scratch:SF 5 ""))])]
    "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
    "
  {
--- 4735,4754 ----
     }
    else
     {
!      operands[2] = assign_386_stack_local (HImode, 1);
!      operands[3] = assign_386_stack_local (HImode, 2);
!      emit_i387_cw_initialization (operands[2], operands[3]);
!      operands[4] = assign_386_stack_local (DImode, 0);
     }
  }")
  
  (define_expand "fix_truncsfdi2"
    [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
  		   (fix:DI (match_operand:SF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))
! 	      (clobber (match_scratch:XF 5 ""))])]
    "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
    "
  {
***************
*** 4756,4773 ****
     }
    else
     {
!      operands[2] = assign_386_stack_local (SImode, 0);
!      operands[3] = assign_386_stack_local (DImode, 1);
     }
  }")
  
  (define_insn "*fix_truncdi_1"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
  	(fix:DI (match_operand 1 "register_operand" "f,f")))
!    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
!    (clobber (match_operand:DI 3 "memory_operand" "=m,m"))
!    (clobber (match_scratch:SI 4 "=&r,&r"))
!    (clobber (match_scratch 5 "=&f,&f"))]
    "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
     && (!TARGET_SSE2 || !TARGET_64BIT
         || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
--- 4762,4781 ----
     }
    else
     {
!      operands[2] = assign_386_stack_local (HImode, 1);
!      operands[3] = assign_386_stack_local (HImode, 2);
!      emit_i387_cw_initialization (operands[2], operands[3]);
!      operands[4] = assign_386_stack_local (DImode, 0);
     }
  }")
  
  (define_insn "*fix_truncdi_1"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
  	(fix:DI (match_operand 1 "register_operand" "f,f")))
!    (use (match_operand:HI 2 "memory_operand" "m,m"))
!    (use (match_operand:HI 3 "memory_operand" "m,m"))
!    (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
!    (clobber (match_scratch 5 "=&1f,&1f"))]
    "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
     && (!TARGET_SSE2 || !TARGET_64BIT
         || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
***************
*** 4777,4793 ****
  (define_split 
    [(set (match_operand:DI 0 "register_operand" "")
  	(fix:DI (match_operand 1 "register_operand" "")))
!    (clobber (match_operand:SI 2 "memory_operand" ""))
!    (clobber (match_operand:DI 3 "memory_operand" ""))
!    (clobber (match_scratch:SI 4 ""))
     (clobber (match_scratch 5 ""))]
!   "reload_completed && !reg_overlap_mentioned_p (operands[4], operands[3])"
!   [(parallel [(set (match_dup 3) (fix:DI (match_dup 1)))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
  	      (clobber (match_dup 4))
  	      (clobber (match_dup 5))])
!    (set (match_dup 0) (match_dup 3))]
    "")
  
  ;; When SSE available, it is always faster to use it!
--- 4785,4801 ----
  (define_split 
    [(set (match_operand:DI 0 "register_operand" "")
  	(fix:DI (match_operand 1 "register_operand" "")))
!    (use (match_operand:HI 2 "memory_operand" ""))
!    (use (match_operand:HI 3 "memory_operand" ""))
!    (clobber (match_operand:DI 4 "memory_operand" ""))
     (clobber (match_scratch 5 ""))]
!   "reload_completed"
!   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
  	      (clobber (match_dup 4))
  	      (clobber (match_dup 5))])
!    (set (match_dup 0) (match_dup 4))]
    "")
  
  ;; When SSE available, it is always faster to use it!
***************
*** 4810,4838 ****
  (define_expand "fix_truncxfsi2"
    [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
  		   (fix:SI (match_operand:XF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))])]
    "TARGET_80387 && !TARGET_64BIT"
!   "operands[2] = assign_386_stack_local (SImode, 0);
!    operands[3] = assign_386_stack_local (SImode, 1);")
  
  (define_expand "fix_trunctfsi2"
    [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
  		   (fix:SI (match_operand:TF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))])]
    "TARGET_80387"
!   "operands[2] = assign_386_stack_local (SImode, 0);
!    operands[3] = assign_386_stack_local (SImode, 1);")
  
  (define_expand "fix_truncdfsi2"
    [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
  		   (fix:SI (match_operand:DF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))])]
    "TARGET_80387 || TARGET_SSE2"
    "
  {
--- 4818,4850 ----
  (define_expand "fix_truncxfsi2"
    [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
  		   (fix:SI (match_operand:XF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))])]
    "TARGET_80387 && !TARGET_64BIT"
!   "operands[2] = assign_386_stack_local (HImode, 1);
!    operands[3] = assign_386_stack_local (HImode, 2);
!    emit_i387_cw_initialization (operands[2], operands[3]);
!    operands[4] = assign_386_stack_local (SImode, 0);")
  
  (define_expand "fix_trunctfsi2"
    [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
  		   (fix:SI (match_operand:TF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))])]
    "TARGET_80387"
!   "operands[2] = assign_386_stack_local (HImode, 1);
!    operands[3] = assign_386_stack_local (HImode, 2);
!    emit_i387_cw_initialization (operands[2], operands[3]);
!    operands[4] = assign_386_stack_local (SImode, 0);")
  
  (define_expand "fix_truncdfsi2"
    [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
  		   (fix:SI (match_operand:DF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))])]
    "TARGET_80387 || TARGET_SSE2"
    "
  {
***************
*** 4846,4862 ****
     }
    else
     {
!      operands[2] = assign_386_stack_local (SImode, 0);
!      operands[3] = assign_386_stack_local (SImode, 1);
     }
  }")
  
  (define_expand "fix_truncsfsi2"
    [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
  		   (fix:SI (match_operand:SF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))])]
    "TARGET_80387 || TARGET_SSE"
    "
  {
--- 4858,4876 ----
     }
    else
     {
!      operands[2] = assign_386_stack_local (HImode, 1);
!      operands[3] = assign_386_stack_local (HImode, 2);
!      emit_i387_cw_initialization (operands[2], operands[3]);
!      operands[4] = assign_386_stack_local (SImode, 0);
     }
  }")
  
  (define_expand "fix_truncsfsi2"
    [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
  		   (fix:SI (match_operand:SF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))])]
    "TARGET_80387 || TARGET_SSE"
    "
  {
***************
*** 4870,4886 ****
     }
    else
     {
!      operands[2] = assign_386_stack_local (SImode, 0);
!      operands[3] = assign_386_stack_local (SImode, 1);
     }
  }")
  
  (define_insn "*fix_truncsi_1"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
  	(fix:SI (match_operand 1 "register_operand" "f,f")))
!    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
!    (clobber (match_operand:SI 3 "memory_operand" "=m,m"))
!    (clobber (match_scratch:SI 4 "=&r,r"))]
    "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
     && (!TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
    "* return output_fix_trunc (insn, operands);"
--- 4884,4902 ----
     }
    else
     {
!      operands[2] = assign_386_stack_local (HImode, 1);
!      operands[3] = assign_386_stack_local (HImode, 2);
!      emit_i387_cw_initialization (operands[2], operands[3]);
!      operands[4] = assign_386_stack_local (SImode, 0);
     }
  }")
  
  (define_insn "*fix_truncsi_1"
    [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
  	(fix:SI (match_operand 1 "register_operand" "f,f")))
!    (use (match_operand:HI 2 "memory_operand" "m,m"))
!    (use (match_operand:HI 3 "memory_operand" "m,m"))
!    (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
    "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
     && (!TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
    "* return output_fix_trunc (insn, operands);"
***************
*** 4904,4918 ****
  (define_split 
    [(set (match_operand:SI 0 "register_operand" "")
  	(fix:SI (match_operand 1 "register_operand" "")))
!    (clobber (match_operand:SI 2 "memory_operand" ""))
!    (clobber (match_operand:SI 3 "memory_operand" ""))
!    (clobber (match_scratch:SI 4 ""))]
    "reload_completed"
!   [(parallel [(set (match_dup 3) (fix:SI (match_dup 1)))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
  	      (clobber (match_dup 4))])
!    (set (match_dup 0) (match_dup 3))]
    "")
  
  ;; Signed conversion to HImode.
--- 4920,4934 ----
  (define_split 
    [(set (match_operand:SI 0 "register_operand" "")
  	(fix:SI (match_operand 1 "register_operand" "")))
!    (use (match_operand:HI 2 "memory_operand" ""))
!    (use (match_operand:HI 3 "memory_operand" ""))
!    (clobber (match_operand:SI 4 "memory_operand" ""))]
    "reload_completed"
!   [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
  	      (clobber (match_dup 4))])
!    (set (match_dup 0) (match_dup 4))]
    "")
  
  ;; Signed conversion to HImode.
***************
*** 4920,4968 ****
  (define_expand "fix_truncxfhi2"
    [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
  		   (fix:HI (match_operand:XF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))])]
    "TARGET_80387 && !TARGET_64BIT"
!   "operands[2] = assign_386_stack_local (SImode, 0);
!    operands[3] = assign_386_stack_local (HImode, 1);")
  
  (define_expand "fix_trunctfhi2"
    [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
  		   (fix:HI (match_operand:TF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))])]
    "TARGET_80387"
!   "operands[2] = assign_386_stack_local (SImode, 0);
!    operands[3] = assign_386_stack_local (HImode, 1);")
  
  (define_expand "fix_truncdfhi2"
    [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
  		   (fix:HI (match_operand:DF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))])]
    "TARGET_80387 && !TARGET_SSE2"
!   "operands[2] = assign_386_stack_local (SImode, 0);
!    operands[3] = assign_386_stack_local (HImode, 1);")
  
  (define_expand "fix_truncsfhi2"
    [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
  		   (fix:HI (match_operand:SF 1 "register_operand" "")))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
! 	      (clobber (match_scratch:SI 4 ""))])]
    "TARGET_80387 && !TARGET_SSE"
!   "operands[2] = assign_386_stack_local (SImode, 0);
!    operands[3] = assign_386_stack_local (HImode, 1);")
  
  (define_insn "*fix_trunchi_1"
    [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
  	(fix:HI (match_operand 1 "register_operand" "f,f")))
!    (clobber (match_operand:SI 2 "memory_operand" "=o,o"))
!    (clobber (match_operand:HI 3 "memory_operand" "=m,m"))
!    (clobber (match_scratch:SI 4 "=&r,r"))]
    "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
     && (TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
    "* return output_fix_trunc (insn, operands);"
--- 4936,4992 ----
  (define_expand "fix_truncxfhi2"
    [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
  		   (fix:HI (match_operand:XF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))])]
    "TARGET_80387 && !TARGET_64BIT"
!   "operands[2] = assign_386_stack_local (HImode, 1);
!    operands[3] = assign_386_stack_local (HImode, 2);
!    emit_i387_cw_initialization (operands[2], operands[3]);
!    operands[4] = assign_386_stack_local (HImode, 0);")
  
  (define_expand "fix_trunctfhi2"
    [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
  		   (fix:HI (match_operand:TF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))])]
    "TARGET_80387"
!   "operands[2] = assign_386_stack_local (HImode, 1);
!    operands[3] = assign_386_stack_local (HImode, 2);
!    emit_i387_cw_initialization (operands[2], operands[3]);
!    operands[4] = assign_386_stack_local (HImode, 0);")
  
  (define_expand "fix_truncdfhi2"
    [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
  		   (fix:HI (match_operand:DF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))])]
    "TARGET_80387 && !TARGET_SSE2"
!   "operands[2] = assign_386_stack_local (HImode, 1);
!    operands[3] = assign_386_stack_local (HImode, 2);
!    emit_i387_cw_initialization (operands[2], operands[3]);
!    operands[4] = assign_386_stack_local (HImode, 0);")
  
  (define_expand "fix_truncsfhi2"
    [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
  		   (fix:HI (match_operand:SF 1 "register_operand" "")))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
! 	      (clobber (match_dup 4))])]
    "TARGET_80387 && !TARGET_SSE"
!   "operands[2] = assign_386_stack_local (HImode, 1);
!    operands[3] = assign_386_stack_local (HImode, 2);
!    emit_i387_cw_initialization (operands[2], operands[3]);
!    operands[4] = assign_386_stack_local (HImode, 0);")
  
  (define_insn "*fix_trunchi_1"
    [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
  	(fix:HI (match_operand 1 "register_operand" "f,f")))
!    (use (match_operand:HI 2 "memory_operand" "m,m"))
!    (use (match_operand:HI 3 "memory_operand" "m,m"))
!    (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
    "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
     && (TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
    "* return output_fix_trunc (insn, operands);"
***************
*** 4971,5003 ****
  (define_split 
    [(set (match_operand:HI 0 "register_operand" "")
  	(fix:HI (match_operand 1 "register_operand" "")))
!    (clobber (match_operand:SI 2 "memory_operand" ""))
!    (clobber (match_operand:HI 3 "memory_operand" ""))
!    (clobber (match_scratch:SI 4 ""))]
    "reload_completed"
!   [(parallel [(set (match_dup 3) (fix:HI (match_dup 1)))
! 	      (clobber (match_dup 2))
! 	      (clobber (match_dup 3))
  	      (clobber (match_dup 4))])
!    (set (match_dup 0) (match_dup 3))]
    "")
- 
- ;; %%% Kill these when reload knows how to do it.
- (define_split
-   [(set (match_operand 0 "register_operand" "")
- 	(fix (match_operand 1 "register_operand" "")))]
-   "reload_completed && FLOAT_MODE_P (GET_MODE (operands[1]))
-    && FP_REG_P (operands[1])"
-   [(const_int 0)]
-   "
- {
-   operands[2] = ix86_force_to_memory (GET_MODE (operands[0]), operands[0]);
-   operands[2] = gen_rtx_FIX (GET_MODE (operands[2]), operands[1]);
-   emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
-   emit_move_insn (operands[0], operands[2]);
-   ix86_free_from_memory (GET_MODE (operands[0]));
-   DONE;
- }")
  
  ;; %% Not used yet.
  (define_insn "x86_fnstcw_1"
--- 4995,5010 ----
  (define_split 
    [(set (match_operand:HI 0 "register_operand" "")
  	(fix:HI (match_operand 1 "register_operand" "")))
!    (use (match_operand:HI 2 "memory_operand" ""))
!    (use (match_operand:HI 3 "memory_operand" ""))
!    (clobber (match_operand:HI 4 "memory_operand" ""))]
    "reload_completed"
!   [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
! 	      (use (match_dup 2))
! 	      (use (match_dup 3))
  	      (clobber (match_dup 4))])
!    (set (match_dup 0) (match_dup 4))]
    "")
  
  ;; %% Not used yet.
  (define_insn "x86_fnstcw_1"
*** i386.work/i386.c	Fri Jun 22 17:20:14 2001
--- i386/i386.c	Fri Jun 22 18:22:04 2001
*************** int const svr4_dbx_register_map[FIRST_PS
*** 445,451 ****
  struct rtx_def *ix86_compare_op0 = NULL_RTX;
  struct rtx_def *ix86_compare_op1 = NULL_RTX;
  
! #define MAX_386_STACK_LOCALS 2
  /* Size of the register save area.  */
  #define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
  
--- 445,451 ----
  struct rtx_def *ix86_compare_op0 = NULL_RTX;
  struct rtx_def *ix86_compare_op1 = NULL_RTX;
  
! #define MAX_386_STACK_LOCALS 3
  /* Size of the register save area.  */
  #define X86_64_VARARGS_SIZE (REGPARM_MAX * UNITS_PER_WORD + SSE_REGPARM_MAX * 16)
  
*************** output_387_binary_op (insn, operands)
*** 4639,4644 ****
--- 4639,4663 ----
    return buf;
  }
  
+ /* Output code to initialize control word copies used by 
+    trunc?f?i patterns.  NORMAL is set to current control word, while ROUND_DOWN
+    is set to control word rounding downwards.  */
+ void
+ emit_i387_cw_initialization (normal, round_down)
+      rtx normal, round_down;
+ {
+   rtx reg = gen_reg_rtx (HImode);
+ 
+   emit_insn (gen_x86_fnstcw_1 (normal));
+   emit_move_insn (reg, normal);
+   if (!TARGET_PARTIAL_REG_STALL && !optimize_size
+       && !TARGET_64BIT)
+     emit_insn (gen_movsi_insv_1 (reg, GEN_INT (0xc)));
+   else
+     emit_insn (gen_iorhi3 (reg, reg, GEN_INT (0xc00)));
+   emit_move_insn (round_down, reg);
+ }
+ 
  /* Output code for INSN to convert a float to a signed int.  OPERANDS
     are the insn operands.  The output may be [HSD]Imode and the input
     operand may be [SDX]Fmode.  */
*************** output_fix_trunc (insn, operands)
*** 4658,4701 ****
    if (dimode_p && !stack_top_dies)
      output_asm_insn ("fld\t%y1", operands);
  
!   if (! STACK_TOP_P (operands[1]))
      abort ();
  
-   xops[0] = GEN_INT (12);
-   xops[1] = adj_offsettable_operand (operands[2], 1);
-   xops[1] = change_address (xops[1], QImode, NULL_RTX);
- 
-   xops[2] = operands[0];
    if (GET_CODE (operands[0]) != MEM)
!     xops[2] = operands[3];
! 
!   output_asm_insn ("fnstcw\t%2", operands);
!   output_asm_insn ("mov{l}\t{%2, %4|%4, %2}", operands);
!   output_asm_insn ("mov{b}\t{%0, %1|%1, %0}", xops);
!   output_asm_insn ("fldcw\t%2", operands);
!   output_asm_insn ("mov{l}\t{%4, %2|%2, %4}", operands);
  
    if (stack_top_dies || dimode_p)
!     output_asm_insn ("fistp%z2\t%2", xops);
    else
!     output_asm_insn ("fist%z2\t%2", xops);
! 
    output_asm_insn ("fldcw\t%2", operands);
- 
-   if (GET_CODE (operands[0]) != MEM)
-     {
-       if (dimode_p)
- 	{
- 	  split_di (operands+0, 1, xops+0, xops+1);
- 	  split_di (operands+3, 1, xops+2, xops+3);
- 	  output_asm_insn ("mov{l}\t{%2, %0|%0, %2}", xops);
- 	  output_asm_insn ("mov{l}\t{%3, %1|%1, %3}", xops);
- 	}
-       else if (GET_MODE (operands[0]) == SImode)
- 	output_asm_insn ("mov{l}\t{%3, %0|%0, %3}", operands);
-       else
- 	output_asm_insn ("mov{w}\t{%3, %0|%0, %3}", operands);
-     }
  
    return "";
  }
--- 4677,4694 ----
    if (dimode_p && !stack_top_dies)
      output_asm_insn ("fld\t%y1", operands);
  
!   if (!STACK_TOP_P (operands[1]))
      abort ();
  
    if (GET_CODE (operands[0]) != MEM)
!     abort ();
  
+   output_asm_insn ("fldcw\t%3", operands);
    if (stack_top_dies || dimode_p)
!     output_asm_insn ("fistp%z0\t%0", operands);
    else
!     output_asm_insn ("fist%z0\t%0", operands);
    output_asm_insn ("fldcw\t%2", operands);
  
    return "";
  }


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