mirror of
https://gcc.gnu.org/git/gcc.git
synced 2025-01-02 08:53:44 +08:00
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:
parent
135d50f10f
commit
22fb740dcc
@ -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.
|
||||
|
@ -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:
|
||||
|
@ -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" "")
|
||||
|
14
gcc/toplev.c
14
gcc/toplev.c
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user