Commit 22fb740d by Jan Hubicka Committed by Jan Hubicka

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
parent 135d50f1
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> Sun Jul 15 12:53:51 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* Makefile.in (integrate.o): Add debug.h. * Makefile.in (integrate.o): Add debug.h.
......
...@@ -3118,6 +3118,69 @@ extern enum reg_class const regclass_map[]; /* smalled class containing REGNO */ ...@@ -3118,6 +3118,69 @@ 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_op0; /* operand 0 for comparisons */
extern struct rtx_def *ix86_compare_op1; /* operand 1 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: Local variables:
version-control: t version-control: t
......
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
;; A basic instruction type. Refinements due to arguments to be ;; A basic instruction type. Refinements due to arguments to be
;; provided in other attributes. ;; provided in other attributes.
(define_attr "type" (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")) (const_string "other"))
;; Main data type used by the insn ;; Main data type used by the insn
...@@ -114,7 +114,7 @@ ...@@ -114,7 +114,7 @@
;; Set for i387 operations. ;; Set for i387 operations.
(define_attr "i387" "" (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 1)
(const_int 0))) (const_int 0)))
...@@ -198,8 +198,10 @@ ...@@ -198,8 +198,10 @@
(const_int 1))) (const_int 1)))
;; The (bounding maximum) length of an instruction in bytes. ;; 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" "" (define_attr "length" ""
(cond [(eq_attr "type" "other,multi") (cond [(eq_attr "type" "other,multi,fistp")
(const_int 16) (const_int 16)
] ]
(plus (plus (attr "modrm") (plus (plus (attr "modrm")
...@@ -220,6 +222,8 @@ ...@@ -220,6 +222,8 @@
(const_string "unknown") (const_string "unknown")
(eq_attr "type" "lea,fcmov,fpspc,cld") (eq_attr "type" "lea,fcmov,fpspc,cld")
(const_string "none") (const_string "none")
(eq_attr "type" "fistp")
(const_string "both")
(eq_attr "type" "push") (eq_attr "type" "push")
(if_then_else (match_operand 1 "memory_operand" "") (if_then_else (match_operand 1 "memory_operand" "")
(const_string "both") (const_string "both")
...@@ -503,9 +507,9 @@ ...@@ -503,9 +507,9 @@
; integer instructions, because of the inpaired fxch instruction. ; integer instructions, because of the inpaired fxch instruction.
(define_function_unit "pent_np" 1 0 (define_function_unit "pent_np" 1 0
(and (eq_attr "cpu" "pentium") (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 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 (define_function_unit "fpu" 1 0
(and (eq_attr "cpu" "pentium") (and (eq_attr "cpu" "pentium")
...@@ -516,7 +520,7 @@ ...@@ -516,7 +520,7 @@
; ??? Trivial fp operations such as fabs or fchs takes only one cycle. ; ??? Trivial fp operations such as fabs or fchs takes only one cycle.
(define_function_unit "fpu" 1 0 (define_function_unit "fpu" 1 0
(and (eq_attr "cpu" "pentium") (and (eq_attr "cpu" "pentium")
(eq_attr "type" "fop,fop1")) (eq_attr "type" "fop,fop1,fistp"))
3 1) 3 1)
; Multiplication takes 3 cycles and is only half pipelined. ; Multiplication takes 3 cycles and is only half pipelined.
...@@ -614,7 +618,7 @@ ...@@ -614,7 +618,7 @@
(define_function_unit "ppro_p0" 1 0 (define_function_unit "ppro_p0" 1 0
(and (eq_attr "cpu" "pentiumpro") (and (eq_attr "cpu" "pentiumpro")
(eq_attr "type" "fop,fop1,fsgn")) (eq_attr "type" "fop,fop1,fsgn,fistp"))
3 1) 3 1)
(define_function_unit "ppro_p0" 1 0 (define_function_unit "ppro_p0" 1 0
...@@ -667,7 +671,7 @@ ...@@ -667,7 +671,7 @@
(define_function_unit "fpu" 1 0 (define_function_unit "fpu" 1 0
(and (eq_attr "cpu" "pentiumpro") (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) 1 1)
(define_function_unit "fpu" 1 0 (define_function_unit "fpu" 1 0
...@@ -770,7 +774,7 @@ ...@@ -770,7 +774,7 @@
(define_function_unit "k6_fpu" 1 1 (define_function_unit "k6_fpu" 1 1
(and (eq_attr "cpu" "k6") (and (eq_attr "cpu" "k6")
(eq_attr "type" "fop,fop1,fmov,fcmp")) (eq_attr "type" "fop,fop1,fmov,fcmp,fistp"))
2 2) 2 2)
(define_function_unit "k6_fpu" 1 1 (define_function_unit "k6_fpu" 1 1
...@@ -882,7 +886,7 @@ ...@@ -882,7 +886,7 @@
42 42) 42 42)
(define_attr "athlon_fpunits" "none,store,mul,add,muladd,any" (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") (const_string "add")
(eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov") (eq_attr "type" "fmul,fdiv,fpspc,fsgn,fcmov")
(const_string "mul") (const_string "mul")
...@@ -917,7 +921,7 @@ ...@@ -917,7 +921,7 @@
(define_function_unit "athlon_fp" 3 0 (define_function_unit "athlon_fp" 3 0
(and (eq_attr "cpu" "athlon") (and (eq_attr "cpu" "athlon")
(eq_attr "type" "fop,fop1,fmul")) (eq_attr "type" "fop,fop1,fmul,fistp"))
4 1) 4 1)
;; XFmode loads are slow. ;; XFmode loads are slow.
...@@ -4620,38 +4624,20 @@ ...@@ -4620,38 +4624,20 @@
;; Signed conversion to DImode. ;; Signed conversion to DImode.
(define_expand "fix_truncxfdi2" (define_expand "fix_truncxfdi2"
[(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") [(set (match_operand:DI 0 "nonimmediate_operand" "")
(fix:DI (match_operand:XF 1 "register_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" "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" (define_expand "fix_trunctfdi2"
[(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") [(set (match_operand:DI 0 "nonimmediate_operand" "")
(fix:DI (match_operand:TF 1 "register_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" "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" (define_expand "fix_truncdfdi2"
[(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") [(set (match_operand:DI 0 "nonimmediate_operand" "")
(fix:DI (match_operand:DF 1 "register_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)" "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
{ {
if (TARGET_SSE2 && TARGET_64BIT) if (TARGET_SSE2 && TARGET_64BIT)
...@@ -4662,25 +4648,14 @@ ...@@ -4662,25 +4648,14 @@
emit_move_insn (operands[0], out); emit_move_insn (operands[0], out);
DONE; 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" (define_expand "fix_truncsfdi2"
[(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") [(set (match_operand:DI 0 "nonimmediate_operand" "")
(fix:DI (match_operand:SF 1 "register_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)" "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); rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
emit_insn (gen_fix_truncsfdi_sse (out, operands[1])); emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
...@@ -4688,27 +4663,58 @@ ...@@ -4688,27 +4663,58 @@
emit_move_insn (operands[0], out); emit_move_insn (operands[0], out);
DONE; 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") [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
(fix:DI (match_operand 1 "register_operand" "f,f"))) (fix:DI (match_operand 1 "register_operand" "f,f")))
(use (match_operand:HI 2 "memory_operand" "m,m")) (use (match_operand:HI 2 "memory_operand" "m,m"))
(use (match_operand:HI 3 "memory_operand" "m,m")) (use (match_operand:HI 3 "memory_operand" "m,m"))
(clobber (match_operand:DI 4 "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_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
&& (!TARGET_SSE2 || !TARGET_64BIT && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
|| !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))" "#"
"* return output_fix_trunc (insn, operands);" [(set_attr "type" "fistp")])
[(set_attr "type" "multi")])
(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 (define_split
[(set (match_operand:DI 0 "register_operand" "") [(set (match_operand:DI 0 "register_operand" "")
...@@ -4721,11 +4727,24 @@ ...@@ -4721,11 +4727,24 @@
[(parallel [(set (match_dup 4) (fix:DI (match_dup 1))) [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
(use (match_dup 2)) (use (match_dup 2))
(use (match_dup 3)) (use (match_dup 3))
(clobber (match_dup 4))
(clobber (match_dup 5))]) (clobber (match_dup 5))])
(set (match_dup 0) (match_dup 4))] (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! ;; When SSE available, it is always faster to use it!
(define_insn "fix_truncsfdi_sse" (define_insn "fix_truncsfdi_sse"
[(set (match_operand:DI 0 "register_operand" "=r") [(set (match_operand:DI 0 "register_operand" "=r")
...@@ -4744,35 +4763,20 @@ ...@@ -4744,35 +4763,20 @@
;; Signed conversion to SImode. ;; Signed conversion to SImode.
(define_expand "fix_truncxfsi2" (define_expand "fix_truncxfsi2"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") [(set (match_operand:SI 0 "nonimmediate_operand" "")
(fix:SI (match_operand:XF 1 "register_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" "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" (define_expand "fix_trunctfsi2"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") [(set (match_operand:SI 0 "nonimmediate_operand" "")
(fix:SI (match_operand:TF 1 "register_operand" ""))) (fix:SI (match_operand:TF 1 "register_operand" "")))]
(use (match_dup 2))
(use (match_dup 3))
(clobber (match_dup 4))])]
"TARGET_80387" "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" (define_expand "fix_truncdfsi2"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") [(set (match_operand:SI 0 "nonimmediate_operand" "")
(fix:SI (match_operand:DF 1 "register_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" "TARGET_80387 || TARGET_SSE2"
{ {
if (TARGET_SSE2) if (TARGET_SSE2)
...@@ -4783,24 +4787,14 @@ ...@@ -4783,24 +4787,14 @@
emit_move_insn (operands[0], out); emit_move_insn (operands[0], out);
DONE; 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" (define_expand "fix_truncsfsi2"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") [(set (match_operand:SI 0 "nonimmediate_operand" "")
(fix:SI (match_operand:SF 1 "register_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" "TARGET_80387 || TARGET_SSE"
{ {
if (TARGET_SSE2) if (TARGET_SSE)
{ {
rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode); rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
emit_insn (gen_fix_truncsfsi_sse (out, operands[1])); emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
...@@ -4808,25 +4802,56 @@ ...@@ -4808,25 +4802,56 @@
emit_move_insn (operands[0], out); emit_move_insn (operands[0], out);
DONE; 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") [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
(fix:SI (match_operand 1 "register_operand" "f,f"))) (fix:SI (match_operand 1 "register_operand" "f,f")))
(use (match_operand:HI 2 "memory_operand" "m,m")) (use (match_operand:HI 2 "memory_operand" "m,m"))
(use (match_operand:HI 3 "memory_operand" "m,m")) (use (match_operand:HI 3 "memory_operand" "m,m"))
(clobber (match_operand:SI 4 "memory_operand" "=m,m"))] (clobber (match_operand:SI 4 "memory_operand" "=m,m"))]
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1])) "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);" "* return output_fix_trunc (insn, operands);"
[(set_attr "type" "multi")]) [(set_attr "type" "fistp")])
;; When SSE available, it is always faster to use it! ;; When SSE available, it is always faster to use it!
(define_insn "fix_truncsfsi_sse" (define_insn "fix_truncsfsi_sse"
...@@ -4852,71 +4877,108 @@ ...@@ -4852,71 +4877,108 @@
"reload_completed" "reload_completed"
[(parallel [(set (match_dup 4) (fix:SI (match_dup 1))) [(parallel [(set (match_dup 4) (fix:SI (match_dup 1)))
(use (match_dup 2)) (use (match_dup 2))
(use (match_dup 3)) (use (match_dup 3))])
(clobber (match_dup 4))])
(set (match_dup 0) (match_dup 4))] (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. ;; Signed conversion to HImode.
(define_expand "fix_truncxfhi2" (define_expand "fix_truncxfhi2"
[(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") [(set (match_operand:HI 0 "nonimmediate_operand" "")
(fix:HI (match_operand:XF 1 "register_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" "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" (define_expand "fix_trunctfhi2"
[(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") [(set (match_operand:HI 0 "nonimmediate_operand" "")
(fix:HI (match_operand:TF 1 "register_operand" ""))) (fix:HI (match_operand:TF 1 "register_operand" "")))]
(use (match_dup 2))
(use (match_dup 3))
(clobber (match_dup 4))])]
"TARGET_80387" "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" (define_expand "fix_truncdfhi2"
[(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") [(set (match_operand:HI 0 "nonimmediate_operand" "")
(fix:HI (match_operand:DF 1 "register_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" "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" (define_expand "fix_truncsfhi2"
[(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "") [(set (match_operand:HI 0 "nonimmediate_operand" "")
(fix:HI (match_operand:SF 1 "register_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" "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") [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
(fix:HI (match_operand 1 "register_operand" "f,f"))) (fix:HI (match_operand 1 "register_operand" "f,f")))
(use (match_operand:HI 2 "memory_operand" "m,m")) (use (match_operand:HI 2 "memory_operand" "m,m"))
(use (match_operand:HI 3 "memory_operand" "m,m")) (use (match_operand:HI 3 "memory_operand" "m,m"))
(clobber (match_operand:HI 4 "memory_operand" "=m,m"))] (clobber (match_operand:HI 4 "memory_operand" "=m,m"))]
"TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1])) "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);" "* 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 (define_split
[(set (match_operand:HI 0 "register_operand" "") [(set (match_operand:HI 0 "register_operand" "")
......
...@@ -3327,7 +3327,6 @@ rest_of_compilation (decl) ...@@ -3327,7 +3327,6 @@ rest_of_compilation (decl)
life_analysis (insns, rtl_dump_file, PROP_FINAL); life_analysis (insns, rtl_dump_file, PROP_FINAL);
timevar_pop (TV_FLOW); timevar_pop (TV_FLOW);
register_life_up_to_date = 1;
no_new_pseudos = 1; no_new_pseudos = 1;
if (warn_uninitialized || extra_warnings) if (warn_uninitialized || extra_warnings)
...@@ -3415,15 +3414,18 @@ rest_of_compilation (decl) ...@@ -3415,15 +3414,18 @@ rest_of_compilation (decl)
ggc_collect (); 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 /* Any of the several passes since flow1 will have munged register
lifetime data a bit. */ lifetime data a bit. */
if (optimize > 0) register_life_up_to_date = 0;
register_life_up_to_date = 0;
#ifdef OPTIMIZE_MODE_SWITCHING #ifdef OPTIMIZE_MODE_SWITCHING
timevar_push (TV_GCSE); timevar_push (TV_GCSE);
no_new_pseudos = 1; no_new_pseudos = 0;
if (optimize_mode_switching (NULL)) if (optimize_mode_switching (NULL))
{ {
/* We did work, and so had to regenerate global life information. /* We did work, and so had to regenerate global life information.
...@@ -3431,15 +3433,13 @@ rest_of_compilation (decl) ...@@ -3431,15 +3433,13 @@ rest_of_compilation (decl)
information below. */ information below. */
register_life_up_to_date = 1; register_life_up_to_date = 1;
} }
no_new_pseudos = 0; no_new_pseudos = 1;
timevar_pop (TV_GCSE); timevar_pop (TV_GCSE);
#endif #endif
timevar_push (TV_SCHED); timevar_push (TV_SCHED);
split_all_insns (1);
#ifdef INSN_SCHEDULING #ifdef INSN_SCHEDULING
/* Print function header into sched dump now /* Print function header into sched dump now
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment