i386-protos.h (ix86_split_fp_branch): New rtx argument.
* config/i386/i386-protos.h (ix86_split_fp_branch): New rtx argument. * config/i386/i386.c (output_fp_compare): Fix is_sse condition. Use EFLAGS_P only when fcomi insn should be used. Fix handling of eflags_p variable. Change alt table accordingly. For non-fcomi compare insn always use trailing fnstsw insn. Fix intmode calculation for ficom insn. (ix86_split_fp_branch): Add "rtx pushed" as new parameter. Call ix86_free_from_memory when "pushed" is specified. (ix86_expand_branch): Change call to ix86_split_fp_branch. * config/i386/i386.md (*cmpfp_0_sf, *cmpfp_0_df, *cmpfp_0_xf): Change eflags_p parameter in call to output_fp_compare. (*cmpfp_2_sf, *cmpfp_2_df, *cmpfp_2_xf): Remove. (*cmpfp_2_sf_1, *cmpfp_2_df_1, *cmpfp_2_xf_1): Rename to *cmpfp_2_sf, *cmpfp_2_df, *cmpfp_2_xf. Change eflags_p parameter in call to output_fp_compare. (*cmpfp_2_u): Remove. (*cmpfp_2_u_1): Rename to *cmpfp_2_u. Change eflags_p parameter in call to output_fp_compare. (*ficom_1): Remove insn definition and corresponding define_split. (*cmpfp_si): New insn definition. (*fp_jcc_8): New insn definition. Add new splitters for "memory_operand" and "register_operand". (define_split): Add new parameter in call to ix86_split_fp_branch. config/i386/predicates.md (float_operator): New predicate. From-SVN: r91856
This commit is contained in:
parent
ac1b13f457
commit
7c82106ff9
5 changed files with 163 additions and 143 deletions
|
@ -1,3 +1,34 @@
|
|||
2004-12-07 Uros Bizjak <uros@kss-loka.si>
|
||||
|
||||
* config/i386/i386-protos.h (ix86_split_fp_branch): New rtx
|
||||
argument.
|
||||
|
||||
* config/i386/i386.c (output_fp_compare): Fix is_sse condition.
|
||||
Use EFLAGS_P only when fcomi insn should be used. Fix handling
|
||||
of eflags_p variable. Change alt table accordingly. For non-fcomi
|
||||
compare insn always use trailing fnstsw insn. Fix intmode
|
||||
calculation for ficom insn.
|
||||
(ix86_split_fp_branch): Add "rtx pushed" as new parameter. Call
|
||||
ix86_free_from_memory when "pushed" is specified.
|
||||
(ix86_expand_branch): Change call to ix86_split_fp_branch.
|
||||
|
||||
* config/i386/i386.md (*cmpfp_0_sf, *cmpfp_0_df, *cmpfp_0_xf):
|
||||
Change eflags_p parameter in call to output_fp_compare.
|
||||
(*cmpfp_2_sf, *cmpfp_2_df, *cmpfp_2_xf): Remove.
|
||||
(*cmpfp_2_sf_1, *cmpfp_2_df_1, *cmpfp_2_xf_1): Rename to
|
||||
*cmpfp_2_sf, *cmpfp_2_df, *cmpfp_2_xf. Change eflags_p
|
||||
parameter in call to output_fp_compare.
|
||||
(*cmpfp_2_u): Remove.
|
||||
(*cmpfp_2_u_1): Rename to *cmpfp_2_u. Change eflags_p parameter
|
||||
in call to output_fp_compare.
|
||||
(*ficom_1): Remove insn definition and corresponding define_split.
|
||||
(*cmpfp_si): New insn definition.
|
||||
(*fp_jcc_8): New insn definition. Add new splitters for
|
||||
"memory_operand" and "register_operand".
|
||||
(define_split): Add new parameter in call to ix86_split_fp_branch.
|
||||
|
||||
config/i386/predicates.md (float_operator): New predicate.
|
||||
|
||||
2004-12-08 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* c-common.c (verify_tree): Don't check code length if we know
|
||||
|
|
|
@ -165,7 +165,8 @@ extern rtx ix86_va_arg (tree, tree);
|
|||
|
||||
extern rtx ix86_force_to_memory (enum machine_mode, rtx);
|
||||
extern void ix86_free_from_memory (enum machine_mode);
|
||||
extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx, rtx, rtx, rtx);
|
||||
extern void ix86_split_fp_branch (enum rtx_code code, rtx, rtx,
|
||||
rtx, rtx, rtx, rtx);
|
||||
extern int ix86_hard_regno_mode_ok (int, enum machine_mode);
|
||||
extern int ix86_register_move_cost (enum machine_mode, enum reg_class,
|
||||
enum reg_class);
|
||||
|
|
|
@ -7208,26 +7208,25 @@ output_fix_trunc (rtx insn, rtx *operands)
|
|||
}
|
||||
|
||||
/* Output code for INSN to compare OPERANDS. EFLAGS_P is 1 when fcomi
|
||||
should be used and 2 when fnstsw should be used. UNORDERED_P is true
|
||||
when fucom should be used. */
|
||||
should be used. UNORDERED_P is true when fucom should be used. */
|
||||
|
||||
const char *
|
||||
output_fp_compare (rtx insn, rtx *operands, int eflags_p, int unordered_p)
|
||||
{
|
||||
int stack_top_dies;
|
||||
rtx cmp_op0, cmp_op1;
|
||||
int is_sse = SSE_REG_P (operands[0]) | SSE_REG_P (operands[1]);
|
||||
int is_sse = SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]);
|
||||
|
||||
if (eflags_p == 2)
|
||||
{
|
||||
cmp_op0 = operands[1];
|
||||
cmp_op1 = operands[2];
|
||||
}
|
||||
else
|
||||
if (eflags_p)
|
||||
{
|
||||
cmp_op0 = operands[0];
|
||||
cmp_op1 = operands[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
cmp_op0 = operands[1];
|
||||
cmp_op1 = operands[2];
|
||||
}
|
||||
|
||||
if (is_sse)
|
||||
{
|
||||
|
@ -7268,7 +7267,7 @@ output_fp_compare (rtx insn, rtx *operands, int eflags_p, int unordered_p)
|
|||
is also a stack register that dies, then this must be a
|
||||
`fcompp' float compare */
|
||||
|
||||
if (eflags_p == 1)
|
||||
if (eflags_p)
|
||||
{
|
||||
/* There is no double popping fcomi variant. Fortunately,
|
||||
eflags is immune from the fstp's cc clobbering. */
|
||||
|
@ -7280,35 +7279,25 @@ output_fp_compare (rtx insn, rtx *operands, int eflags_p, int unordered_p)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (eflags_p == 2)
|
||||
{
|
||||
if (unordered_p)
|
||||
return "fucompp\n\tfnstsw\t%0";
|
||||
else
|
||||
return "fcompp\n\tfnstsw\t%0";
|
||||
}
|
||||
if (unordered_p)
|
||||
return "fucompp\n\tfnstsw\t%0";
|
||||
else
|
||||
{
|
||||
if (unordered_p)
|
||||
return "fucompp";
|
||||
else
|
||||
return "fcompp";
|
||||
}
|
||||
return "fcompp\n\tfnstsw\t%0";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Encoded here as eflags_p | intmode | unordered_p | stack_top_dies. */
|
||||
|
||||
static const char * const alt[24] =
|
||||
static const char * const alt[16] =
|
||||
{
|
||||
"fcom%z1\t%y1",
|
||||
"fcomp%z1\t%y1",
|
||||
"fucom%z1\t%y1",
|
||||
"fucomp%z1\t%y1",
|
||||
"fcom%z2\t%y2\n\tfnstsw\t%0",
|
||||
"fcomp%z2\t%y2\n\tfnstsw\t%0",
|
||||
"fucom%z2\t%y2\n\tfnstsw\t%0",
|
||||
"fucomp%z2\t%y2\n\tfnstsw\t%0",
|
||||
|
||||
"ficom%z1\t%y1",
|
||||
"ficomp%z1\t%y1",
|
||||
"ficom%z2\t%y2\n\tfnstsw\t%0",
|
||||
"ficomp%z2\t%y2\n\tfnstsw\t%0",
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
|
@ -7320,16 +7309,6 @@ output_fp_compare (rtx insn, rtx *operands, int eflags_p, int unordered_p)
|
|||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
"fcom%z2\t%y2\n\tfnstsw\t%0",
|
||||
"fcomp%z2\t%y2\n\tfnstsw\t%0",
|
||||
"fucom%z2\t%y2\n\tfnstsw\t%0",
|
||||
"fucomp%z2\t%y2\n\tfnstsw\t%0",
|
||||
|
||||
"ficom%z2\t%y2\n\tfnstsw\t%0",
|
||||
"ficomp%z2\t%y2\n\tfnstsw\t%0",
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -7337,11 +7316,11 @@ output_fp_compare (rtx insn, rtx *operands, int eflags_p, int unordered_p)
|
|||
const char *ret;
|
||||
|
||||
mask = eflags_p << 3;
|
||||
mask |= (GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT) << 2;
|
||||
mask |= (GET_MODE_CLASS (GET_MODE (cmp_op1)) == MODE_INT) << 2;
|
||||
mask |= unordered_p << 1;
|
||||
mask |= stack_top_dies;
|
||||
|
||||
if (mask >= 24)
|
||||
if (mask >= 16)
|
||||
abort ();
|
||||
ret = alt[mask];
|
||||
if (ret == NULL)
|
||||
|
@ -8458,7 +8437,7 @@ ix86_expand_branch (enum rtx_code code, rtx label)
|
|||
{
|
||||
ix86_split_fp_branch (code, ix86_compare_op0, ix86_compare_op1,
|
||||
gen_rtx_LABEL_REF (VOIDmode, label),
|
||||
pc_rtx, NULL_RTX);
|
||||
pc_rtx, NULL_RTX, NULL_RTX);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -8606,7 +8585,7 @@ ix86_expand_branch (enum rtx_code code, rtx label)
|
|||
/* Split branch based on floating point condition. */
|
||||
void
|
||||
ix86_split_fp_branch (enum rtx_code code, rtx op1, rtx op2,
|
||||
rtx target1, rtx target2, rtx tmp)
|
||||
rtx target1, rtx target2, rtx tmp, rtx pushed)
|
||||
{
|
||||
rtx second, bypass;
|
||||
rtx label = NULL_RTX;
|
||||
|
@ -8625,6 +8604,10 @@ ix86_split_fp_branch (enum rtx_code code, rtx op1, rtx op2,
|
|||
condition = ix86_expand_fp_compare (code, op1, op2,
|
||||
tmp, &second, &bypass);
|
||||
|
||||
/* Remove pushed operand from stack. */
|
||||
if (pushed)
|
||||
ix86_free_from_memory (GET_MODE (pushed));
|
||||
|
||||
if (split_branch_probability >= 0)
|
||||
{
|
||||
/* Distribute the probabilities across the jumps.
|
||||
|
|
|
@ -797,6 +797,9 @@
|
|||
;; CCFPmode compare with exceptions
|
||||
;; CCFPUmode compare with no exceptions
|
||||
|
||||
;; We may not use "#" to split and emit these, since the REG_DEAD notes
|
||||
;; used to manage the reg stack popping would not be preserved.
|
||||
|
||||
(define_insn "*cmpfp_0_sf"
|
||||
[(set (match_operand:HI 0 "register_operand" "=a")
|
||||
(unspec:HI
|
||||
|
@ -805,7 +808,7 @@
|
|||
(match_operand:SF 2 "const0_operand" "X"))]
|
||||
UNSPEC_FNSTSW))]
|
||||
"TARGET_80387"
|
||||
"* return output_fp_compare (insn, operands, 2, 0);"
|
||||
"* return output_fp_compare (insn, operands, 0, 0);"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "mode" "SF")])
|
||||
|
||||
|
@ -817,7 +820,7 @@
|
|||
(match_operand:DF 2 "const0_operand" "X"))]
|
||||
UNSPEC_FNSTSW))]
|
||||
"TARGET_80387"
|
||||
"* return output_fp_compare (insn, operands, 2, 0);"
|
||||
"* return output_fp_compare (insn, operands, 0, 0);"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "mode" "DF")])
|
||||
|
||||
|
@ -829,24 +832,11 @@
|
|||
(match_operand:XF 2 "const0_operand" "X"))]
|
||||
UNSPEC_FNSTSW))]
|
||||
"TARGET_80387"
|
||||
"* return output_fp_compare (insn, operands, 2, 0);"
|
||||
"* return output_fp_compare (insn, operands, 0, 0);"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "mode" "XF")])
|
||||
|
||||
;; We may not use "#" to split and emit these, since the REG_DEAD notes
|
||||
;; used to manage the reg stack popping would not be preserved.
|
||||
|
||||
(define_insn "*cmpfp_2_sf"
|
||||
[(set (reg:CCFP FPSR_REG)
|
||||
(compare:CCFP
|
||||
(match_operand:SF 0 "register_operand" "f")
|
||||
(match_operand:SF 1 "nonimmediate_operand" "fm")))]
|
||||
"TARGET_80387"
|
||||
"* return output_fp_compare (insn, operands, 0, 0);"
|
||||
[(set_attr "type" "fcmp")
|
||||
(set_attr "mode" "SF")])
|
||||
|
||||
(define_insn "*cmpfp_2_sf_1"
|
||||
(define_insn "*cmpfp_sf"
|
||||
[(set (match_operand:HI 0 "register_operand" "=a")
|
||||
(unspec:HI
|
||||
[(compare:CCFP
|
||||
|
@ -854,21 +844,11 @@
|
|||
(match_operand:SF 2 "nonimmediate_operand" "fm"))]
|
||||
UNSPEC_FNSTSW))]
|
||||
"TARGET_80387"
|
||||
"* return output_fp_compare (insn, operands, 2, 0);"
|
||||
"* return output_fp_compare (insn, operands, 0, 0);"
|
||||
[(set_attr "type" "fcmp")
|
||||
(set_attr "mode" "SF")])
|
||||
|
||||
(define_insn "*cmpfp_2_df"
|
||||
[(set (reg:CCFP FPSR_REG)
|
||||
(compare:CCFP
|
||||
(match_operand:DF 0 "register_operand" "f")
|
||||
(match_operand:DF 1 "nonimmediate_operand" "fm")))]
|
||||
"TARGET_80387"
|
||||
"* return output_fp_compare (insn, operands, 0, 0);"
|
||||
[(set_attr "type" "fcmp")
|
||||
(set_attr "mode" "DF")])
|
||||
|
||||
(define_insn "*cmpfp_2_df_1"
|
||||
(define_insn "*cmpfp_df"
|
||||
[(set (match_operand:HI 0 "register_operand" "=a")
|
||||
(unspec:HI
|
||||
[(compare:CCFP
|
||||
|
@ -876,21 +856,11 @@
|
|||
(match_operand:DF 2 "nonimmediate_operand" "fm"))]
|
||||
UNSPEC_FNSTSW))]
|
||||
"TARGET_80387"
|
||||
"* return output_fp_compare (insn, operands, 2, 0);"
|
||||
"* return output_fp_compare (insn, operands, 0, 0);"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "mode" "DF")])
|
||||
|
||||
(define_insn "*cmpfp_2_xf"
|
||||
[(set (reg:CCFP FPSR_REG)
|
||||
(compare:CCFP
|
||||
(match_operand:XF 0 "register_operand" "f")
|
||||
(match_operand:XF 1 "register_operand" "f")))]
|
||||
"TARGET_80387"
|
||||
"* return output_fp_compare (insn, operands, 0, 0);"
|
||||
[(set_attr "type" "fcmp")
|
||||
(set_attr "mode" "XF")])
|
||||
|
||||
(define_insn "*cmpfp_2_xf_1"
|
||||
(define_insn "*cmpfp_xf"
|
||||
[(set (match_operand:HI 0 "register_operand" "=a")
|
||||
(unspec:HI
|
||||
[(compare:CCFP
|
||||
|
@ -898,29 +868,11 @@
|
|||
(match_operand:XF 2 "register_operand" "f"))]
|
||||
UNSPEC_FNSTSW))]
|
||||
"TARGET_80387"
|
||||
"* return output_fp_compare (insn, operands, 2, 0);"
|
||||
"* return output_fp_compare (insn, operands, 0, 0);"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "mode" "XF")])
|
||||
|
||||
(define_insn "*cmpfp_2u"
|
||||
[(set (reg:CCFPU FPSR_REG)
|
||||
(compare:CCFPU
|
||||
(match_operand 0 "register_operand" "f")
|
||||
(match_operand 1 "register_operand" "f")))]
|
||||
"TARGET_80387
|
||||
&& FLOAT_MODE_P (GET_MODE (operands[0]))
|
||||
&& GET_MODE (operands[0]) == GET_MODE (operands[1])"
|
||||
"* return output_fp_compare (insn, operands, 0, 1);"
|
||||
[(set_attr "type" "fcmp")
|
||||
(set (attr "mode")
|
||||
(cond [(match_operand:SF 1 "" "")
|
||||
(const_string "SF")
|
||||
(match_operand:DF 1 "" "")
|
||||
(const_string "DF")
|
||||
]
|
||||
(const_string "XF")))])
|
||||
|
||||
(define_insn "*cmpfp_2u_1"
|
||||
(define_insn "*cmpfp_u"
|
||||
[(set (match_operand:HI 0 "register_operand" "=a")
|
||||
(unspec:HI
|
||||
[(compare:CCFPU
|
||||
|
@ -930,7 +882,7 @@
|
|||
"TARGET_80387
|
||||
&& FLOAT_MODE_P (GET_MODE (operands[1]))
|
||||
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
|
||||
"* return output_fp_compare (insn, operands, 2, 1);"
|
||||
"* return output_fp_compare (insn, operands, 0, 1);"
|
||||
[(set_attr "type" "multi")
|
||||
(set (attr "mode")
|
||||
(cond [(match_operand:SF 1 "" "")
|
||||
|
@ -940,40 +892,21 @@
|
|||
]
|
||||
(const_string "XF")))])
|
||||
|
||||
;; Patterns to match the SImode-in-memory ficom instructions.
|
||||
;;
|
||||
;; %%% Play games with accepting gp registers, as otherwise we have to
|
||||
;; force them to memory during rtl generation, which is no good. We
|
||||
;; can get rid of this once we teach reload to do memory input reloads
|
||||
;; via pushes.
|
||||
|
||||
(define_insn "*ficom_1"
|
||||
[(set (reg:CCFP FPSR_REG)
|
||||
(compare:CCFP
|
||||
(match_operand 0 "register_operand" "f,f")
|
||||
(float (match_operand:SI 1 "nonimmediate_operand" "m,?r"))))]
|
||||
"0 && TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[0]))
|
||||
&& GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 1)) == GET_MODE (operands[0])"
|
||||
"#")
|
||||
|
||||
;; Split the not-really-implemented gp register case into a
|
||||
;; push-op-pop sequence.
|
||||
;;
|
||||
;; %%% This is most efficient, but am I gonna get in trouble
|
||||
;; for separating cc0_setter and cc0_user?
|
||||
|
||||
(define_split
|
||||
[(set (reg:CCFP FPSR_REG)
|
||||
(compare:CCFP
|
||||
(match_operand:SF 0 "register_operand" "")
|
||||
(float (match_operand:SI 1 "register_operand" ""))))]
|
||||
"0 && TARGET_80387 && reload_completed"
|
||||
[(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 1))
|
||||
(set (reg:CCFP FPSR_REG) (compare:CCFP (match_dup 0) (match_dup 2)))
|
||||
(parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
|
||||
(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
|
||||
"operands[2] = gen_rtx_MEM (Pmode, stack_pointer_rtx);
|
||||
operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);")
|
||||
(define_insn "*cmpfp_si"
|
||||
[(set (match_operand:HI 0 "register_operand" "=a")
|
||||
(unspec:HI
|
||||
[(compare:CCFP
|
||||
(match_operand 1 "register_operand" "f")
|
||||
(match_operator 3 "float_operator"
|
||||
[(match_operand:SI 2 "memory_operand" "m")]))]
|
||||
UNSPEC_FNSTSW))]
|
||||
"TARGET_80387 && TARGET_USE_FIOP
|
||||
&& FLOAT_MODE_P (GET_MODE (operands[1]))
|
||||
&& (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
|
||||
"* return output_fp_compare (insn, operands, 0, 0);"
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "fp_int_src" "true")
|
||||
(set_attr "mode" "SI")])
|
||||
|
||||
;; FP compares, step 2
|
||||
;; Move the fpsw to ax.
|
||||
|
@ -13298,6 +13231,30 @@
|
|||
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
|
||||
"#")
|
||||
|
||||
;; The order of operands in *fp_jcc_8 is forced by combine in
|
||||
;; simplify_comparison () function. Float operator is treated as RTX_OBJ
|
||||
;; with a precedence over other operators and is always put in the first
|
||||
;; place. Swap condition and operands to match ficom instruction.
|
||||
|
||||
(define_insn "*fp_jcc_8"
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 0 "comparison_operator"
|
||||
[(match_operator 1 "float_operator"
|
||||
[(match_operand:SI 2 "nonimmediate_operand" "m,?r")])
|
||||
(match_operand 3 "register_operand" "f,f")])
|
||||
(label_ref (match_operand 4 "" ""))
|
||||
(pc)))
|
||||
(clobber (reg:CCFP FPSR_REG))
|
||||
(clobber (reg:CCFP FLAGS_REG))
|
||||
(clobber (match_scratch:HI 5 "=a,a"))]
|
||||
"TARGET_80387 && TARGET_USE_FIOP
|
||||
&& FLOAT_MODE_P (GET_MODE (operands[3]))
|
||||
&& GET_MODE (operands[1]) == GET_MODE (operands[3])
|
||||
&& !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
|
||||
&& ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
|
||||
&& ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
|
||||
"#")
|
||||
|
||||
(define_split
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 0 "comparison_operator"
|
||||
|
@ -13311,7 +13268,7 @@
|
|||
[(const_int 0)]
|
||||
{
|
||||
ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
|
||||
operands[3], operands[4], NULL_RTX);
|
||||
operands[3], operands[4], NULL_RTX, NULL_RTX);
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
@ -13329,7 +13286,51 @@
|
|||
[(const_int 0)]
|
||||
{
|
||||
ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
|
||||
operands[3], operands[4], operands[5]);
|
||||
operands[3], operands[4], operands[5], NULL_RTX);
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_split
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 0 "comparison_operator"
|
||||
[(match_operator 1 "float_operator"
|
||||
[(match_operand:SI 2 "memory_operand" "")])
|
||||
(match_operand 3 "register_operand" "")])
|
||||
(match_operand 4 "" "")
|
||||
(match_operand 5 "" "")))
|
||||
(clobber (reg:CCFP FPSR_REG))
|
||||
(clobber (reg:CCFP FLAGS_REG))
|
||||
(clobber (match_scratch:HI 6 "=a"))]
|
||||
"reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
|
||||
ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
|
||||
operands[3], operands[7],
|
||||
operands[4], operands[5], operands[6], NULL_RTX);
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; %%% Kill this when reload knows how to do it.
|
||||
(define_split
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 0 "comparison_operator"
|
||||
[(match_operator 1 "float_operator"
|
||||
[(match_operand:SI 2 "register_operand" "")])
|
||||
(match_operand 3 "register_operand" "")])
|
||||
(match_operand 4 "" "")
|
||||
(match_operand 5 "" "")))
|
||||
(clobber (reg:CCFP FPSR_REG))
|
||||
(clobber (reg:CCFP FLAGS_REG))
|
||||
(clobber (match_scratch:HI 6 "=a"))]
|
||||
"reload_completed"
|
||||
[(const_int 0)]
|
||||
{
|
||||
operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
|
||||
operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
|
||||
ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
|
||||
operands[3], operands[7],
|
||||
operands[4], operands[5], operands[6], operands[2]);
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
|
|
@ -795,6 +795,10 @@
|
|||
(define_predicate "div_operator"
|
||||
(match_code "div"))
|
||||
|
||||
;; Return true if this is a float extend operation.
|
||||
(define_predicate "float_operator"
|
||||
(match_code "float"))
|
||||
|
||||
;; Return true for ARITHMETIC_P.
|
||||
(define_predicate "arith_or_logical_operator"
|
||||
(match_code "PLUS,MULT,AND,IOR,XOR,SMIN,SMAX,UMIN,UMAX,COMPARE,MINUS,DIV,
|
||||
|
|
Loading…
Add table
Reference in a new issue