i386.c (ix86_prepare_fp_compare_args): Do not force operand 0.0 into register in XFmode.
* config/i386/i386.c (ix86_prepare_fp_compare_args): Do not force operand 0.0 into register in XFmode. Also do not force operand 0.0 into register if !TARGET_CMOVE. * config/i386/i386.md (*cmpfp_0): Delete. Remove comment. (*cmpfp_0_sf, cmpfp_0_df, cmpfp_0_xf): New patterns to implement ftst x87 instruction. (*fp_jcc_7): New insn pattern. Change corresponding split pattern to handle "general_operand" instead of "nonimmediate_operand". ---------------------------------------------------------------------- From-SVN: r87173
This commit is contained in:
parent
70d5fb1c36
commit
45c8c47fde
@ -1,3 +1,15 @@
|
||||
2004-09-08 Uros Bizjak <uros@kss-loka.si>
|
||||
|
||||
* config/i386/i386.c (ix86_prepare_fp_compare_args): Do not
|
||||
force operand 0.0 into register in XFmode. Also do not force
|
||||
operand 0.0 into register if !TARGET_CMOVE.
|
||||
* config/i386/i386.md (*cmpfp_0): Delete. Remove comment.
|
||||
(*cmpfp_0_sf, cmpfp_0_df, cmpfp_0_xf): New patterns to
|
||||
implement ftst x87 instruction.
|
||||
(*fp_jcc_7): New insn pattern. Change corresponding split
|
||||
pattern to handle "general_operand" instead of
|
||||
"nonimmediate_operand".
|
||||
|
||||
2004-09-08 Ben Elliston <bje@au.ibm.com>
|
||||
|
||||
* doc/rtl.texi (Insns): Document NOTE_INSN_FUNCTION_BEG.
|
||||
|
@ -7941,12 +7941,15 @@ ix86_prepare_fp_compare_args (enum rtx_code code, rtx *pop0, rtx *pop1)
|
||||
int is_sse = SSE_REG_P (op0) | SSE_REG_P (op1);
|
||||
|
||||
/* All of the unordered compare instructions only work on registers.
|
||||
The same is true of the XFmode compare instructions. The same is
|
||||
true of the fcomi compare instructions. */
|
||||
The same is true of the fcomi compare instructions. The same is
|
||||
true of the XFmode compare instructions if not comparing with
|
||||
zero (ftst insn is used in this case). */
|
||||
|
||||
if (!is_sse
|
||||
&& (fpcmp_mode == CCFPUmode
|
||||
|| op_mode == XFmode
|
||||
|| (op_mode == XFmode
|
||||
&& ! (standard_80387_constant_p (op0) == 1
|
||||
|| standard_80387_constant_p (op1) == 1))
|
||||
|| ix86_use_fcomi_compare (code)))
|
||||
{
|
||||
op0 = force_reg (op_mode, op0);
|
||||
@ -7973,10 +7976,16 @@ ix86_prepare_fp_compare_args (enum rtx_code code, rtx *pop0, rtx *pop1)
|
||||
|
||||
if (CONSTANT_P (op1))
|
||||
{
|
||||
if (standard_80387_constant_p (op1))
|
||||
op1 = force_reg (op_mode, op1);
|
||||
else
|
||||
int tmp = standard_80387_constant_p (op1);
|
||||
if (tmp == 0)
|
||||
op1 = validize_mem (force_const_mem (op_mode, op1));
|
||||
else if (tmp == 1)
|
||||
{
|
||||
if (TARGET_CMOVE)
|
||||
op1 = force_reg (op_mode, op1);
|
||||
}
|
||||
else
|
||||
op1 = force_reg (op_mode, op1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -797,41 +797,65 @@
|
||||
;; CCFPmode compare with exceptions
|
||||
;; CCFPUmode compare with no exceptions
|
||||
|
||||
;; %%% It is an unfortunate fact that ftst has no non-popping variant,
|
||||
;; and that fp moves clobber the condition codes, and that there is
|
||||
;; currently no way to describe this fact to reg-stack. So there are
|
||||
;; no splitters yet for this.
|
||||
|
||||
;; %%% YIKES! This scheme does not retain a strong connection between
|
||||
;; the real compare and the ultimate cc0 user, so CC_REVERSE does not
|
||||
;; work! Only allow tos/mem with tos in op 0.
|
||||
;;
|
||||
;; Hmm, of course, this is what the actual _hardware_ does. Perhaps
|
||||
;; things aren't as bad as they sound...
|
||||
|
||||
(define_insn "*cmpfp_0"
|
||||
(define_insn "*cmpfp_0_sf"
|
||||
[(set (match_operand:HI 0 "register_operand" "=a")
|
||||
(unspec:HI
|
||||
[(compare:CCFP (match_operand 1 "register_operand" "f")
|
||||
(match_operand 2 "const0_operand" "X"))]
|
||||
UNSPEC_FNSTSW))]
|
||||
"TARGET_80387
|
||||
&& FLOAT_MODE_P (GET_MODE (operands[1]))
|
||||
&& GET_MODE (operands[1]) == GET_MODE (operands[2])"
|
||||
[(compare:CCFP
|
||||
(match_operand:SF 1 "register_operand" "f")
|
||||
(match_operand:SF 2 "const0_operand" "X"))]
|
||||
UNSPEC_FNSTSW))]
|
||||
"TARGET_80387"
|
||||
{
|
||||
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
|
||||
return "ftst\;fnstsw\t%0\;fstp\t%y0";
|
||||
{
|
||||
output_asm_insn ("ftst\;fnstsw\t%0", operands);
|
||||
return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
|
||||
}
|
||||
else
|
||||
return "ftst\;fnstsw\t%0";
|
||||
}
|
||||
[(set_attr "type" "multi")
|
||||
(set (attr "mode")
|
||||
(cond [(match_operand:SF 1 "" "")
|
||||
(const_string "SF")
|
||||
(match_operand:DF 1 "" "")
|
||||
(const_string "DF")
|
||||
]
|
||||
(const_string "XF")))])
|
||||
(set_attr "mode" "SF")])
|
||||
|
||||
(define_insn "*cmpfp_0_df"
|
||||
[(set (match_operand:HI 0 "register_operand" "=a")
|
||||
(unspec:HI
|
||||
[(compare:CCFP
|
||||
(match_operand:DF 1 "register_operand" "f")
|
||||
(match_operand:DF 2 "const0_operand" "X"))]
|
||||
UNSPEC_FNSTSW))]
|
||||
"TARGET_80387"
|
||||
{
|
||||
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
|
||||
{
|
||||
output_asm_insn ("ftst\;fnstsw\t%0", operands);
|
||||
return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
|
||||
}
|
||||
else
|
||||
return "ftst\;fnstsw\t%0";
|
||||
}
|
||||
[(set_attr "type" "multi")
|
||||
(set_attr "mode" "DF")])
|
||||
|
||||
(define_insn "*cmpfp_0_xf"
|
||||
[(set (match_operand:HI 0 "register_operand" "=a")
|
||||
(unspec:HI
|
||||
[(compare:CCFP
|
||||
(match_operand:XF 1 "register_operand" "f")
|
||||
(match_operand:XF 2 "const0_operand" "X"))]
|
||||
UNSPEC_FNSTSW))]
|
||||
"TARGET_80387"
|
||||
{
|
||||
if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
|
||||
{
|
||||
output_asm_insn ("ftst\;fnstsw\t%0", operands);
|
||||
return TARGET_USE_FFREEP ? "ffreep\t%y1" : "fstp\t%y1";
|
||||
}
|
||||
else
|
||||
return "ftst\;fnstsw\t%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.
|
||||
@ -13322,6 +13346,25 @@
|
||||
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
|
||||
"#")
|
||||
|
||||
(define_insn "*fp_jcc_7"
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 0 "comparison_operator"
|
||||
[(match_operand 1 "register_operand" "f")
|
||||
(match_operand 2 "const_double_operand" "C")])
|
||||
(label_ref (match_operand 3 "" ""))
|
||||
(pc)))
|
||||
(clobber (reg:CCFP FPSR_REG))
|
||||
(clobber (reg:CCFP FLAGS_REG))
|
||||
(clobber (match_scratch:HI 4 "=a"))]
|
||||
"TARGET_80387
|
||||
&& FLOAT_MODE_P (GET_MODE (operands[1]))
|
||||
&& operands[2] == CONST0_RTX (GET_MODE (operands[1]))
|
||||
&& !ix86_use_fcomi_compare (GET_CODE (operands[0]))
|
||||
&& SELECT_CC_MODE (GET_CODE (operands[0]),
|
||||
operands[1], operands[2]) == CCFPmode
|
||||
&& ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
|
||||
"#")
|
||||
|
||||
(define_split
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 0 "comparison_operator"
|
||||
@ -13343,17 +13386,14 @@
|
||||
[(set (pc)
|
||||
(if_then_else (match_operator 0 "comparison_operator"
|
||||
[(match_operand 1 "register_operand" "")
|
||||
(match_operand 2 "nonimmediate_operand" "")])
|
||||
(match_operand 2 "general_operand" "")])
|
||||
(match_operand 3 "" "")
|
||||
(match_operand 4 "" "")))
|
||||
(clobber (reg:CCFP FPSR_REG))
|
||||
(clobber (reg:CCFP FLAGS_REG))
|
||||
(clobber (match_scratch:HI 5 "=a"))]
|
||||
"reload_completed"
|
||||
[(set (pc)
|
||||
(if_then_else (match_dup 6)
|
||||
(match_dup 3)
|
||||
(match_dup 4)))]
|
||||
[(const_int 0)]
|
||||
{
|
||||
ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
|
||||
operands[3], operands[4], operands[5]);
|
||||
|
Loading…
Reference in New Issue
Block a user