toplev.c (rest_of_compilation): Fix register_life_up_to_date handling...

* toplev.c (rest_of_compilation): Fix register_life_up_to_date
	handling; move unconditional splitting before mode switching.

	* i386.md (type): Add fistp type.
	(i387, length_attr, scheduling definitions): Handle this type.
	(fix_trunc?f?i2): Revamp to use mode switching.
	(fix_trunct?f?i_nonmemory, fix_trunc?f?i_memory): New patterns.
	* i386.h (fp_cw_mode): New enum
	(OPTIMIZE_MODE_SWITCHING, NUM_MODES_FOR_MODE_SWITCHING, MODE_NEEDED,
	MODE_PRIORITY_TO_MODE, ENUM_MODE_SET): New macros.

From-SVN: r44027
This commit is contained in:
Jan Hubicka 2001-07-15 18:59:06 +02:00 committed by Jan Hubicka
parent 135d50f10f
commit 22fb740dcc
4 changed files with 297 additions and 159 deletions

View File

@ -1,3 +1,16 @@
Sun Jul 15 14:07:36 CEST 2001 Jan Hubicka <jh@suse.cz>
* toplev.c (rest_of_compilation): Fix register_life_up_to_date
handling; move unconditional splitting before mode switching.
* i386.md (type): Add fistp type.
(i387, length_attr, scheduling definitions): Handle this type.
(fix_trunc?f?i2): Revamp to use mode switching.
(fix_trunct?f?i_nonmemory, fix_trunc?f?i_memory): New patterns.
* i386.h (fp_cw_mode): New enum
(OPTIMIZE_MODE_SWITCHING, NUM_MODES_FOR_MODE_SWITCHING, MODE_NEEDED,
MODE_PRIORITY_TO_MODE, ENUM_MODE_SET): New macros.
Sun Jul 15 12:53:51 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* Makefile.in (integrate.o): Add debug.h.

View File

@ -3117,6 +3117,69 @@ extern const char * const qi_high_reg_name[]; /* names for 8 bit regs (high) */
extern enum reg_class const regclass_map[]; /* smalled class containing REGNO */
extern struct rtx_def *ix86_compare_op0; /* operand 0 for comparisons */
extern struct rtx_def *ix86_compare_op1; /* operand 1 for comparisons */
/* To properly truncate FP values into integers, we need to set i387 control
word. We can't emit proper mode switching code before reload, as spills
generated by reload may truncate values incorrectly, but we still can avoid
redundant computation of new control word by the mode switching pass.
The fldcw instructions are still emitted redundantly, but this is probably
not going to be noticeable problem, as most CPUs do have fast path for
the sequence.
The machinery is to emit simple truncation instructions and split them
before reload to instructions having USEs of two memory locations that
are filled by this code to old and new control word.
Post-reload pass may be later used to eliminate the redundant fildcw if
needed. */
enum fp_cw_mode {FP_CW_STORED, FP_CW_UNINITIALIZED, FP_CW_ANY};
/* Define this macro if the port needs extra instructions inserted
for mode switching in an optimizing compilation. */
#define OPTIMIZE_MODE_SWITCHING(ENTITY) 1
/* If you define `OPTIMIZE_MODE_SWITCHING', you have to define this as
initializer for an array of integers. Each initializer element N
refers to an entity that needs mode switching, and specifies the
number of different modes that might need to be set for this
entity. The position of the initializer in the initializer -
starting counting at zero - determines the integer that is used to
refer to the mode-switched entity in question. */
#define NUM_MODES_FOR_MODE_SWITCHING { FP_CW_ANY }
/* ENTITY is an integer specifying a mode-switched entity. If
`OPTIMIZE_MODE_SWITCHING' is defined, you must define this macro to
return an integer value not larger than the corresponding element
in `NUM_MODES_FOR_MODE_SWITCHING', to denote the mode that ENTITY
must be switched into prior to the execution of INSN. */
#define MODE_NEEDED(ENTITY, I) \
(GET_CODE (I) == CALL_INSN \
|| (GET_CODE (I) == INSN && (asm_noperands (PATTERN (I)) >= 0 \
|| GET_CODE (PATTERN (I)) == ASM_INPUT))\
? FP_CW_UNINITIALIZED \
: recog_memoized (I) < 0 || get_attr_type (I) != TYPE_FISTP \
? FP_CW_ANY \
: FP_CW_STORED)
/* This macro specifies the order in which modes for ENTITY are
processed. 0 is the highest priority. */
#define MODE_PRIORITY_TO_MODE(ENTITY, N) N
/* Generate one or more insns to set ENTITY to MODE. HARD_REG_LIVE
is the set of hard registers live at the point where the insn(s)
are to be inserted. */
#define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
(MODE == FP_CW_STORED \
? emit_i387_cw_initialization (assign_386_stack_local (HImode, 1), \
assign_386_stack_local (HImode, 2)), 0\
: 0)
/*
Local variables:

View File

@ -105,7 +105,7 @@
;; A basic instruction type. Refinements due to arguments to be
;; provided in other attributes.
(define_attr "type"
"other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx"
"other,multi,alu1,negnot,alu,icmp,test,imov,imovx,lea,incdec,ishift,imul,idiv,ibr,setcc,push,pop,call,callv,icmov,fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,str,cld,sse,mmx,fistp"
(const_string "other"))
;; Main data type used by the insn
@ -114,7 +114,7 @@
;; Set for i387 operations.
(define_attr "i387" ""
(if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch")
(if_then_else (eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp")
(const_int 1)
(const_int 0)))
@ -198,8 +198,10 @@
(const_int 1)))
;; The (bounding maximum) length of an instruction in bytes.
;; ??? fistp is in fact fldcw/fistp/fldcw sequence. Later we may want
;; to split it and compute proper length as for other insns.
(define_attr "length" ""
(cond [(eq_attr "type" "other,multi")
(cond [(eq_attr "type" "other,multi,fistp")
(const_int 16)
]
(plus (plus (attr "modrm")
@ -220,6 +222,8 @@
(const_string "unknown")
(eq_attr "type" "lea,fcmov,fpspc,cld")
(const_string "none")
(eq_attr "type" "fistp")
(const_string "both")
(eq_attr "type" "push")
(if_then_else (match_operand 1 "memory_operand" "")
(const_string "both")
@ -503,9 +507,9 @@
; integer instructions, because of the inpaired fxch instruction.
(define_function_unit "pent_np" 1 0
(and (eq_attr "cpu" "pentium")
(eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp"))
(eq_attr "type" "fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp"))
2 2
[(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp")])
[(eq_attr "type" "!fmov,fop,fop1,fsgn,fmul,fpspc,fcmov,fcmp,fistp")])
(define_function_unit "fpu" 1 0
(and (eq_attr "cpu" "pentium")
@ -516,7 +520,7 @@
; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
(define_function_unit "fpu" 1 0
(and (eq_attr "cpu" "pentium")
(eq_attr "type" "fop,fop1"))
(eq_attr "type" "fop,fop1,fistp"))
3 1)
; Multiplication takes 3 cycles and is only half pipelined.
@ -614,7 +618,7 @@
(define_function_unit "ppro_p0" 1 0
(and (eq_attr "cpu" "pentiumpro")
(eq_attr "type" "fop,fop1,fsgn"))
(eq_attr "type" "fop,fop1,fsgn,fistp"))
3 1)
(define_function_unit "ppro_p0" 1 0
@ -667,7 +671,7 @@
(define_function_unit "fpu" 1 0
(and (eq_attr "cpu" "pentiumpro")
(eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov"))
(eq_attr "type" "fop,fop1,fsgn,fmov,fcmp,fcmov,fistp"))
1 1)
(define_function_unit "fpu" 1 0
@ -770,7 +774,7 @@
(define_function_unit "k6_fpu" 1 1
(and (eq_attr "cpu" "k6")
(eq_attr "type" "fop,fop1,fmov,fcmp"))
(eq_attr "type" "fop,fop1,fmov,fcmp,fistp"))
2 2)
(define_function_unit "k6_fpu" 1 1
@ -882,7 +886,7 @@
42 42)
(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any"
(cond [(eq_attr "type" "fop,fop1,fcmp")
(cond [(eq_attr "type" "fop,fop1,fcmp,fistp")
(const_string "add")
(eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
(const_string "mul")
@ -917,7 +921,7 @@
(define_function_unit "athlon_fp" 3 0
(and (eq_attr "cpu" "athlon")
(eq_attr "type" "fop,fop1,fmul"))
(eq_attr "type" "fop,fop1,fmul,fistp"))
4 1)
;; XFmode loads are slow.
@ -4620,38 +4624,20 @@
;; Signed conversion to DImode.
(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 ""))])]
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(fix:DI (match_operand:XF 1 "register_operand" "")))]
"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 ""))])]
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(fix:DI (match_operand:TF 1 "register_operand" "")))]
"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 ""))])]
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(fix:DI (match_operand:DF 1 "register_operand" "")))]
"TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
{
if (TARGET_SSE2 && TARGET_64BIT)
@ -4662,25 +4648,14 @@
emit_move_insn (operands[0], out);
DONE;
}
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 ""))])]
[(set (match_operand:DI 0 "nonimmediate_operand" "")
(fix:DI (match_operand:SF 1 "register_operand" "")))]
"TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
{
if (TARGET_SSE2 && TARGET_64BIT)
if (TARGET_SSE && TARGET_64BIT)
{
rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
@ -4688,27 +4663,58 @@
emit_move_insn (operands[0], out);
DONE;
}
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"
;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
;; of the machinery.
(define_insn_and_split "*fix_truncdi_1"
[(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
(fix:DI (match_operand 1 "register_operand" "f,f")))]
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& !reload_completed && !reload_in_progress
&& (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
"#"
""
[(const_int 0)]
{
operands[2] = assign_386_stack_local (HImode, 1);
operands[3] = assign_386_stack_local (HImode, 2);
if (memory_operand (operands[0], VOIDmode))
emit_insn (gen_fix_truncdi_memory (operands[0], operands[1],
operands[2], operands[3]));
else
{
operands[4] = assign_386_stack_local (DImode, 0);
emit_insn (gen_fix_truncdi_nomemory (operands[0], operands[1],
operands[2], operands[3],
operands[4]));
}
DONE;
}
[(set_attr "type" "fistp")])
(define_insn "fix_truncdi_nomemory"
[(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"))]
(clobber (match_scratch:DF 5 "=&1f,&1f"))]
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& (!TARGET_SSE2 || !TARGET_64BIT
|| !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
"* return output_fix_trunc (insn, operands);"
[(set_attr "type" "multi")])
&& (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
"#"
[(set_attr "type" "fistp")])
(define_insn "fix_truncdi_memory"
[(set (match_operand:DI 0 "memory_operand" "=m")
(fix:DI (match_operand 1 "register_operand" "f")))
(use (match_operand:HI 2 "memory_operand" "m"))
(use (match_operand:HI 3 "memory_operand" "m"))
(clobber (match_scratch:DF 4 "=&1f"))]
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
"* operands[5] = operands[4]; return output_fix_trunc (insn, operands);"
[(set_attr "type" "fistp")])
(define_split
[(set (match_operand:DI 0 "register_operand" "")
@ -4721,11 +4727,24 @@
[(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))]
"")
(define_split
[(set (match_operand:DI 0 "memory_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 0) (fix:DI (match_dup 1)))
(use (match_dup 2))
(use (match_dup 3))
(clobber (match_dup 5))])]
"")
;; When SSE available, it is always faster to use it!
(define_insn "fix_truncsfdi_sse"
[(set (match_operand:DI 0 "register_operand" "=r")
@ -4744,35 +4763,20 @@
;; Signed conversion to SImode.
(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))])]
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(fix:SI (match_operand:XF 1 "register_operand" "")))]
"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))])]
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(fix:SI (match_operand:TF 1 "register_operand" "")))]
"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))])]
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(fix:SI (match_operand:DF 1 "register_operand" "")))]
"TARGET_80387 || TARGET_SSE2"
{
if (TARGET_SSE2)
@ -4783,24 +4787,14 @@
emit_move_insn (operands[0], out);
DONE;
}
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))])]
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(fix:SI (match_operand:SF 1 "register_operand" "")))]
"TARGET_80387 || TARGET_SSE"
{
if (TARGET_SSE2)
if (TARGET_SSE)
{
rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
@ -4808,25 +4802,56 @@
emit_move_insn (operands[0], out);
DONE;
}
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"
;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
;; of the machinery.
(define_insn_and_split "*fix_truncsi_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
(fix:SI (match_operand 1 "register_operand" "f,f")))]
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& !reload_completed && !reload_in_progress
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
"#"
""
[(const_int 0)]
{
operands[2] = assign_386_stack_local (HImode, 1);
operands[3] = assign_386_stack_local (HImode, 2);
if (memory_operand (operands[0], VOIDmode))
emit_insn (gen_fix_truncsi_memory (operands[0], operands[1],
operands[2], operands[3]));
else
{
operands[4] = assign_386_stack_local (SImode, 0);
emit_insn (gen_fix_truncsi_nomemory (operands[0], operands[1],
operands[2], operands[3],
operands[4]));
}
DONE;
}
[(set_attr "type" "fistp")])
(define_insn "fix_truncsi_nomemory"
[(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])))"
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
"#"
[(set_attr "type" "fistp")])
(define_insn "fix_truncsi_memory"
[(set (match_operand:SI 0 "memory_operand" "=m")
(fix:SI (match_operand 1 "register_operand" "f")))
(use (match_operand:HI 2 "memory_operand" "m"))
(use (match_operand:HI 3 "memory_operand" "m"))]
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
"* return output_fix_trunc (insn, operands);"
[(set_attr "type" "multi")])
[(set_attr "type" "fistp")])
;; When SSE available, it is always faster to use it!
(define_insn "fix_truncsfsi_sse"
@ -4852,71 +4877,108 @@
"reload_completed"
[(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
(use (match_dup 2))
(use (match_dup 3))
(clobber (match_dup 4))])
(use (match_dup 3))])
(set (match_dup 0) (match_dup 4))]
"")
(define_split
[(set (match_operand:SI 0 "memory_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 0) (fix:SI (match_dup 1)))
(use (match_dup 2))
(use (match_dup 3))])]
"")
;; Signed conversion to HImode.
(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))])]
[(set (match_operand:HI 0 "nonimmediate_operand" "")
(fix:HI (match_operand:XF 1 "register_operand" "")))]
"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))])]
[(set (match_operand:HI 0 "nonimmediate_operand" "")
(fix:HI (match_operand:TF 1 "register_operand" "")))]
"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))])]
[(set (match_operand:HI 0 "nonimmediate_operand" "")
(fix:HI (match_operand:DF 1 "register_operand" "")))]
"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))])]
[(set (match_operand:HI 0 "nonimmediate_operand" "")
(fix:HI (match_operand:SF 1 "register_operand" "")))]
"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"
;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
;; of the machinery.
(define_insn_and_split "*fix_trunchi_1"
[(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
(fix:HI (match_operand 1 "register_operand" "f,f")))]
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& !reload_completed && !reload_in_progress
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
"#"
""
[(const_int 0)]
{
operands[2] = assign_386_stack_local (HImode, 1);
operands[3] = assign_386_stack_local (HImode, 2);
if (memory_operand (operands[0], VOIDmode))
emit_insn (gen_fix_trunchi_memory (operands[0], operands[1],
operands[2], operands[3]));
else
{
operands[4] = assign_386_stack_local (HImode, 0);
emit_insn (gen_fix_trunchi_nomemory (operands[0], operands[1],
operands[2], operands[3],
operands[4]));
}
DONE;
}
[(set_attr "type" "fistp")])
(define_insn "fix_trunchi_nomemory"
[(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])))"
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
"#"
[(set_attr "type" "fistp")])
(define_insn "fix_trunchi_memory"
[(set (match_operand:HI 0 "memory_operand" "=m")
(fix:HI (match_operand 1 "register_operand" "f")))
(use (match_operand:HI 2 "memory_operand" "m"))
(use (match_operand:HI 3 "memory_operand" "m"))]
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
"* return output_fix_trunc (insn, operands);"
[(set_attr "type" "multi")])
[(set_attr "type" "fistp")])
(define_split
[(set (match_operand:HI 0 "memory_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 0) (fix:HI (match_dup 1)))
(use (match_dup 2))
(use (match_dup 3))])]
"")
(define_split
[(set (match_operand:HI 0 "register_operand" "")

View File

@ -3327,7 +3327,6 @@ rest_of_compilation (decl)
life_analysis (insns, rtl_dump_file, PROP_FINAL);
timevar_pop (TV_FLOW);
register_life_up_to_date = 1;
no_new_pseudos = 1;
if (warn_uninitialized || extra_warnings)
@ -3415,15 +3414,18 @@ rest_of_compilation (decl)
ggc_collect ();
}
/* Do unconditional splitting before register allocation to allow machine
description to add extra information not needed previously. */
split_all_insns (1);
/* Any of the several passes since flow1 will have munged register
lifetime data a bit. */
if (optimize > 0)
register_life_up_to_date = 0;
register_life_up_to_date = 0;
#ifdef OPTIMIZE_MODE_SWITCHING
timevar_push (TV_GCSE);
no_new_pseudos = 1;
no_new_pseudos = 0;
if (optimize_mode_switching (NULL))
{
/* We did work, and so had to regenerate global life information.
@ -3431,15 +3433,13 @@ rest_of_compilation (decl)
information below. */
register_life_up_to_date = 1;
}
no_new_pseudos = 0;
no_new_pseudos = 1;
timevar_pop (TV_GCSE);
#endif
timevar_push (TV_SCHED);
split_all_insns (1);
#ifdef INSN_SCHEDULING
/* Print function header into sched dump now