aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/i386/i386.md')
-rw-r--r--gcc/config/i386/i386.md891
1 files changed, 469 insertions, 422 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index d9a4ce599ed..a8d1c2bd6da 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -113,6 +113,11 @@
(UNSPEC_MOVSLDUP 75)
(UNSPEC_LDQQU 76)
(UNSPEC_MOVDDUP 77)
+ ; APPLE LOCAL begin 4121692
+ (UNSPEC_LDQ 101)
+ (UNSPEC_MOVQ 102)
+ (UNSPEC_STOQ 103)
+ ; APPLE LOCAL end 4121692
; x87 Floating point
(UNSPEC_FPATAN 65)
@@ -187,6 +192,7 @@
;; A basic instruction type. Refinements due to arguments to be
;; provided in other attributes.
+; APPLE LOCAL begin mainline 2005-03-16 4054919
(define_attr "type"
"other,multi,
alu,alu1,negnot,imov,imovx,lea,
@@ -194,11 +200,12 @@
icmp,test,ibr,setcc,icmov,
push,pop,call,callv,leave,
str,cld,
- fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint,
+ fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
sselog,sselog1,sseiadd,sseishft,sseimul,
sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
(const_string "other"))
+; APPLE LOCAL end mainline 2005-03-16 4054919
;; Main data type used by the insn
(define_attr "mode"
@@ -207,7 +214,8 @@
;; The CPU unit operations uses.
(define_attr "unit" "integer,i387,sse,mmx,unknown"
- (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,frndint")
+; APPLE LOCAL mainline 2005-03-16 4054919
+ (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
(const_string "i387")
(eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
@@ -441,6 +449,24 @@
(define_asm_attributes
[(set_attr "length" "128")
(set_attr "type" "multi")])
+; APPLE LOCAL begin mainline 2005-03-16 4054919
+
+;; All x87 floating point modes
+(define_mode_macro X87MODEF [SF DF XF])
+
+;; All integer modes handled by x87 fisttp operator.
+(define_mode_macro X87MODEI [HI SI DI])
+
+;; All integer modes handled by integer x87 operators.
+(define_mode_macro X87MODEI12 [HI SI])
+
+;; All SSE floating point modes
+(define_mode_macro SSEMODEF [SF DF])
+
+;; All integer modes handled by SSE cvtts?2si* operators.
+(define_mode_macro SSEMODEI24 [SI DI])
+
+; APPLE LOCAL end mainline 2005-03-16 4054919
;; Scheduling descriptions
@@ -1443,9 +1469,10 @@
;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
;; register stall machines with, where we use QImode instructions, since
;; partial register stall can be caused there. Then we use movzx.
+;; APPLE LOCAL begin mainline 4104248
(define_insn "*movqi_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
- (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
+ (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,m ,qn"))]
"GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
{
switch (get_attr_type (insn))
@@ -1462,7 +1489,9 @@
}
}
[(set (attr "type")
- (cond [(ne (symbol_ref "optimize_size") (const_int 0))
+ (cond [(eq_attr "alternative" "5")
+ (const_string "imovx")
+ (ne (symbol_ref "optimize_size") (const_int 0))
(const_string "imov")
(and (eq_attr "alternative" "3")
(ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
@@ -1470,7 +1499,7 @@
(eq (symbol_ref "TARGET_QIMODE_MATH")
(const_int 0))))
(const_string "imov")
- (eq_attr "alternative" "3,5")
+ (eq_attr "alternative" "3")
(const_string "imovx")
(and (ne (symbol_ref "TARGET_MOVX")
(const_int 0))
@@ -1500,6 +1529,7 @@
(const_string "SI")
]
(const_string "QI")))])
+;; APPLE LOCAL end mainline 4104248
(define_expand "reload_outqi"
[(parallel [(match_operand:QI 0 "" "=m")
@@ -3770,6 +3800,22 @@
[(set_attr "type" "fmov,multi")
(set_attr "mode" "SF")])
+(define_insn "*truncdfsf2_i387_1"
+ [(set (match_operand:SF 0 "memory_operand" "=m")
+ (float_truncate:SF
+ (match_operand:DF 1 "register_operand" "f")))]
+ "TARGET_80387
+ && !(TARGET_SSE2 && TARGET_SSE_MATH)
+ && !TARGET_MIX_SSE_I387"
+{
+ if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return "fstp%z0\t%y0";
+ else
+ return "fst%z0\t%y0";
+}
+ [(set_attr "type" "fmov")
+ (set_attr "mode" "SF")])
+
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(float_truncate:SF
@@ -3995,8 +4041,7 @@
[(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
"")
-;; %%% Break up all these bad boys.
-
+; APPLE LOCAL begin mainline 2005-03-16 4054919
;; Signed conversion to DImode.
(define_expand "fix_truncxfdi2"
@@ -4004,361 +4049,234 @@
(fix:DI (match_operand:XF 1 "register_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_80387"
- "")
-
-(define_expand "fix_truncdfdi2"
- [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (fix:DI (match_operand:DF 1 "register_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2)"
{
- if (TARGET_64BIT && TARGET_SSE2)
+ if (TARGET_FISTTP)
{
- rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
- emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
- if (out != operands[0])
- emit_move_insn (operands[0], out);
+ emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
DONE;
}
})
-(define_expand "fix_truncsfdi2"
+(define_expand "fix_trunc<mode>di2"
[(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (fix:DI (match_operand:SF 1 "register_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387 || (TARGET_64BIT && TARGET_SSE)"
+ (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
+ (clobber (reg:CC FLAGS_REG))])]
+ "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
{
- if (TARGET_64BIT && TARGET_SSE)
+ if (TARGET_FISTTP
+ && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
+ {
+ emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
+ DONE;
+ }
+ if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
{
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_trunc<mode>di_sse (out, operands[1]));
if (out != operands[0])
emit_move_insn (operands[0], out);
DONE;
}
})
-;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
-;; of the machinery.
-(define_insn_and_split "*fix_truncdi_i387"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
- (fix:DI (match_operand 1 "register_operand" "f,f")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
- && !reload_completed && !reload_in_progress
- && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
- "#"
- "&& 1"
- [(const_int 0)]
-{
- ix86_optimize_mode_switching = 1;
- 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")
- (set_attr "i387_cw" "trunc")
- (set_attr "mode" "DI")])
-
-(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:DF 5 "=&1f,&1f"))]
- "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
- && (!SSE_FLOAT_MODE_P (GET_MODE (operands[1])) || !TARGET_64BIT)"
- "#"
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "trunc")
- (set_attr "mode" "DI")])
-
-(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)"
- "* return output_fix_trunc (insn, operands);"
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "trunc")
- (set_attr "mode" "DI")])
-
-(define_split
- [(set (match_operand:DI 0 "register_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 4) (fix:DI (match_dup 1)))
- (use (match_dup 2))
- (use (match_dup 3))
- (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,r")
- (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
- "TARGET_64BIT && TARGET_SSE"
- "cvttss2si{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "sseicvt")
- (set_attr "mode" "SF")
- (set_attr "athlon_decode" "double,vector")])
-
-;; Avoid vector decoded form of the instruction.
-(define_peephole2
- [(match_scratch:SF 2 "x")
- (set (match_operand:DI 0 "register_operand" "")
- (fix:DI (match_operand:SF 1 "memory_operand" "")))]
- "TARGET_K8 && !optimize_size"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (fix:DI (match_dup 2)))]
- "")
-
-(define_insn "fix_truncdfdi_sse"
- [(set (match_operand:DI 0 "register_operand" "=r,r")
- (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
- "TARGET_64BIT && TARGET_SSE2"
- "cvttsd2si{q}\t{%1, %0|%0, %1}"
- [(set_attr "type" "sseicvt,sseicvt")
- (set_attr "mode" "DF")
- (set_attr "athlon_decode" "double,vector")])
-
-;; Avoid vector decoded form of the instruction.
-(define_peephole2
- [(match_scratch:DF 2 "Y")
- (set (match_operand:DI 0 "register_operand" "")
- (fix:DI (match_operand:DF 1 "memory_operand" "")))]
- "TARGET_K8 && !optimize_size"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (fix:DI (match_dup 2)))]
- "")
-
;; Signed conversion to SImode.
(define_expand "fix_truncxfsi2"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (fix:SI (match_operand:XF 1 "register_operand" "")))
+ (fix:SI (match_operand:XF 1 "register_operand" "")))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_80387"
- "")
-
-(define_expand "fix_truncdfsi2"
- [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (fix:SI (match_operand:DF 1 "register_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387 || TARGET_SSE2"
{
- if (TARGET_SSE2)
+ if (TARGET_FISTTP)
{
- rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
- emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
- if (out != operands[0])
- emit_move_insn (operands[0], out);
+ emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
DONE;
}
})
-(define_expand "fix_truncsfsi2"
+(define_expand "fix_trunc<mode>si2"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (fix:SI (match_operand:SF 1 "register_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387 || TARGET_SSE"
+ (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
+ (clobber (reg:CC FLAGS_REG))])]
+ "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
{
- if (TARGET_SSE)
+ if (TARGET_FISTTP
+ && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
+ {
+ emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
+ DONE;
+ }
+ if (SSE_FLOAT_MODE_P (<MODE>mode))
{
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_trunc<mode>si_sse (out, operands[1]));
if (out != operands[0])
emit_move_insn (operands[0], out);
DONE;
}
})
-;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
-;; of the machinery.
-(define_insn_and_split "*fix_truncsi_i387"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
- (fix:SI (match_operand 1 "register_operand" "f,f")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
- && !reload_completed && !reload_in_progress
- && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
- "#"
- "&& 1"
- [(const_int 0)]
+;; Signed conversion to HImode.
+
+(define_expand "fix_trunc<mode>hi2"
+ [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
+ (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
+ (clobber (reg:CC FLAGS_REG))])]
+ "TARGET_80387
+ && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
{
- ix86_optimize_mode_switching = 1;
- 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")
- (set_attr "i387_cw" "trunc")
- (set_attr "mode" "SI")])
+ if (TARGET_FISTTP)
+ {
+ emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
+ DONE;
+ }
+})
-(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]))
- && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
- "#"
- [(set_attr "type" "fistp")
- (set_attr "i387_cw" "trunc")
- (set_attr "mode" "SI")])
+;; When SSE is available, it is always faster to use it!
+(define_insn "fix_truncsfdi_sse"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
+ "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
+ "cvttss2si{q}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sseicvt")
+ (set_attr "mode" "SF")
+ (set_attr "athlon_decode" "double,vector")])
-(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" "fistp")
- (set_attr "i387_cw" "trunc")
- (set_attr "mode" "SI")])
+(define_insn "fix_truncdfdi_sse"
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
+ (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
+ "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
+ "cvttsd2si{q}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sseicvt")
+ (set_attr "mode" "DF")
+ (set_attr "athlon_decode" "double,vector")])
-;; When SSE available, it is always faster to use it!
(define_insn "fix_truncsfsi_sse"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
- "TARGET_SSE"
+ "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
"cvttss2si\t{%1, %0|%0, %1}"
[(set_attr "type" "sseicvt")
(set_attr "mode" "DF")
(set_attr "athlon_decode" "double,vector")])
-;; Avoid vector decoded form of the instruction.
-(define_peephole2
- [(match_scratch:SF 2 "x")
- (set (match_operand:SI 0 "register_operand" "")
- (fix:SI (match_operand:SF 1 "memory_operand" "")))]
- "TARGET_K8 && !optimize_size"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (fix:SI (match_dup 2)))]
- "")
-
(define_insn "fix_truncdfsi_sse"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
- "TARGET_SSE2"
+ "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
"cvttsd2si\t{%1, %0|%0, %1}"
[(set_attr "type" "sseicvt")
(set_attr "mode" "DF")
(set_attr "athlon_decode" "double,vector")])
-;; Avoid vector decoded form of the instruction.
+;; Avoid vector decoded forms of the instruction.
(define_peephole2
[(match_scratch:DF 2 "Y")
- (set (match_operand:SI 0 "register_operand" "")
- (fix:SI (match_operand:DF 1 "memory_operand" "")))]
+ (set (match_operand:SSEMODEI24 0 "register_operand" "")
+ (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
"TARGET_K8 && !optimize_size"
[(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (fix:SI (match_dup 2)))]
- "")
-
-(define_split
- [(set (match_operand:SI 0 "register_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 4) (fix:SI (match_dup 1)))
- (use (match_dup 2))
- (use (match_dup 3))])
- (set (match_dup 0) (match_dup 4))]
+ (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
"")
-(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))])]
+(define_peephole2
+ [(match_scratch:SF 2 "x")
+ (set (match_operand:SSEMODEI24 0 "register_operand" "")
+ (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
+ "TARGET_K8 && !optimize_size"
+ [(set (match_dup 2) (match_dup 1))
+ (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
"")
-;; Signed conversion to HImode.
-
-(define_expand "fix_truncxfhi2"
- [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
- (fix:HI (match_operand:XF 1 "register_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387"
- "")
+(define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
+ [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
+ (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
+ "TARGET_80387 && TARGET_FISTTP
+ && FLOAT_MODE_P (GET_MODE (operands[1]))
+ && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
+ && (TARGET_64BIT || <MODE>mode != DImode))
+ && TARGET_SSE_MATH)
+ && !(reload_completed || reload_in_progress)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ if (memory_operand (operands[0], VOIDmode))
+ emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
+ else
+ {
+ operands[2] = assign_386_stack_local (<MODE>mode, 0);
+ emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
+ operands[1],
+ operands[2]));
+ }
+ DONE;
+}
+ [(set_attr "type" "fisttp")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "fix_trunc<mode>_i387_fisttp"
+ [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
+ (fix:X87MODEI (match_operand 1 "register_operand" "f")))
+ (clobber (match_scratch:XF 2 "=&1f"))]
+ "TARGET_80387 && TARGET_FISTTP
+ && FLOAT_MODE_P (GET_MODE (operands[1]))
+ && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
+ && (TARGET_64BIT || <MODE>mode != DImode))
+ && TARGET_SSE_MATH)"
+ "* return output_fix_trunc (insn, operands, 1);"
+ [(set_attr "type" "fisttp")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
+ [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
+ (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
+ (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
+ (clobber (match_scratch:XF 3 "=&1f,&1f"))]
+ "TARGET_80387 && TARGET_FISTTP
+ && FLOAT_MODE_P (GET_MODE (operands[1]))
+ && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
+ && (TARGET_64BIT || <MODE>mode != DImode))
+ && TARGET_SSE_MATH)"
+ "#"
+ [(set_attr "type" "fisttp")
+ (set_attr "mode" "<MODE>")])
-(define_expand "fix_truncdfhi2"
- [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
- (fix:HI (match_operand:DF 1 "register_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387 && !TARGET_SSE2"
+(define_split
+ [(set (match_operand:X87MODEI 0 "register_operand" "")
+ (fix:X87MODEI (match_operand 1 "register_operand" "")))
+ (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
+ (clobber (match_scratch 3 ""))]
+ "reload_completed"
+ [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
+ (clobber (match_dup 3))])
+ (set (match_dup 0) (match_dup 2))]
"")
-(define_expand "fix_truncsfhi2"
- [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
- (fix:HI (match_operand:SF 1 "register_operand" "")))
- (clobber (reg:CC FLAGS_REG))])]
- "TARGET_80387 && !TARGET_SSE"
+(define_split
+ [(set (match_operand:X87MODEI 0 "memory_operand" "")
+ (fix:X87MODEI (match_operand 1 "register_operand" "")))
+ (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
+ (clobber (match_scratch 3 ""))]
+ "reload_completed"
+ [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
+ (clobber (match_dup 3))])]
"")
;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
-;; of the machinery.
-(define_insn_and_split "*fix_trunchi_i387"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
- (fix:HI (match_operand 1 "register_operand" "f,f")))
- (clobber (reg:CC FLAGS_REG))]
- "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
- && !reload_completed && !reload_in_progress
- && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
+;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
+;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
+;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
+;; function in i386.c.
+(define_insn_and_split "*fix_trunc<mode>_i387_1"
+ [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
+ (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_80387 && !TARGET_FISTTP
+ && FLOAT_MODE_P (GET_MODE (operands[1]))
+ && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
+ && (TARGET_64BIT || <MODE>mode != DImode))
+ && !(reload_completed || reload_in_progress)"
"#"
"&& 1"
[(const_int 0)]
@@ -4367,71 +4285,131 @@
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]));
+ emit_insn (gen_fix_trunc<mode>_i387 (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]));
+ operands[4] = assign_386_stack_local (<MODE>mode, 0);
+ emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
+ operands[2], operands[3],
+ operands[4]));
}
DONE;
}
[(set_attr "type" "fistp")
(set_attr "i387_cw" "trunc")
- (set_attr "mode" "HI")])
+ (set_attr "mode" "<MODE>")])
-(define_insn "fix_trunchi_nomemory"
- [(set (match_operand:HI 0 "nonimmediate_operand" "=m,?r")
- (fix:HI (match_operand 1 "register_operand" "f,f")))
+(define_insn "fix_truncdi_i387"
+ [(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:XF 4 "=&1f"))]
+ "TARGET_80387 && !TARGET_FISTTP
+ && FLOAT_MODE_P (GET_MODE (operands[1]))
+ && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
+ "* return output_fix_trunc (insn, operands, 0);"
+ [(set_attr "type" "fistp")
+ (set_attr "i387_cw" "trunc")
+ (set_attr "mode" "DI")])
+
+(define_insn "fix_truncdi_i387_with_temp"
+ [(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:HI 4 "memory_operand" "=m,m"))]
- "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
- && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
+ (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
+ (clobber (match_scratch:XF 5 "=&1f,&1f"))]
+ "TARGET_80387 && !TARGET_FISTTP
+ && FLOAT_MODE_P (GET_MODE (operands[1]))
+ && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
"#"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "trunc")
- (set_attr "mode" "HI")])
+ (set_attr "mode" "DI")])
-(define_insn "fix_trunchi_memory"
- [(set (match_operand:HI 0 "memory_operand" "=m")
- (fix:HI (match_operand 1 "register_operand" "f")))
+(define_split
+ [(set (match_operand:DI 0 "register_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 4) (fix:DI (match_dup 1)))
+ (use (match_dup 2))
+ (use (match_dup 3))
+ (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))])]
+ "")
+
+(define_insn "fix_trunc<mode>_i387"
+ [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
+ (fix:X87MODEI12 (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]))
+ "TARGET_80387 && !TARGET_FISTTP
+ && 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, 0);"
[(set_attr "type" "fistp")
(set_attr "i387_cw" "trunc")
- (set_attr "mode" "HI")])
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "fix_trunc<mode>_i387_with_temp"
+ [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
+ (fix:X87MODEI12 (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:X87MODEI12 4 "memory_operand" "=m,m"))]
+ "TARGET_80387 && !TARGET_FISTTP
+ && FLOAT_MODE_P (GET_MODE (operands[1]))
+ && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
+ "#"
+ [(set_attr "type" "fistp")
+ (set_attr "i387_cw" "trunc")
+ (set_attr "mode" "<MODE>")])
(define_split
- [(set (match_operand:HI 0 "memory_operand" "")
- (fix:HI (match_operand 1 "register_operand" "")))
+ [(set (match_operand:X87MODEI12 0 "register_operand" "")
+ (fix:X87MODEI12 (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" ""))]
+ (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
"reload_completed"
- [(parallel [(set (match_dup 0) (fix:HI (match_dup 1)))
+ [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
(use (match_dup 2))
- (use (match_dup 3))])]
+ (use (match_dup 3))])
+ (set (match_dup 0) (match_dup 4))]
"")
(define_split
- [(set (match_operand:HI 0 "register_operand" "")
- (fix:HI (match_operand 1 "register_operand" "")))
+ [(set (match_operand:X87MODEI12 0 "memory_operand" "")
+ (fix:X87MODEI12 (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" ""))]
+ (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
"reload_completed"
- [(parallel [(set (match_dup 4) (fix:HI (match_dup 1)))
+ [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
(use (match_dup 2))
- (use (match_dup 3))
- (clobber (match_dup 4))])
- (set (match_dup 0) (match_dup 4))]
+ (use (match_dup 3))])]
"")
+; APPLE LOCAL end mainline 2005-03-16 4054919
(define_insn "x86_fnstcw_1"
[(set (match_operand:HI 0 "memory_operand" "=m")
@@ -9749,6 +9727,7 @@
operands[1] = tmp;
})
+; APPLE LOCAL begin radar 4117515
(define_split
[(set (match_operand 0 "memory_operand" "")
(match_operator 1 "absneg_operator" [(match_dup 0)]))
@@ -9762,19 +9741,37 @@
int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
rtx tmp;
- operands[0] = adjust_address (operands[0], QImode, size - 1);
- if (GET_CODE (operands[1]) == ABS)
+ if (size == 4)
{
- tmp = gen_int_mode (0x7f, QImode);
- tmp = gen_rtx_AND (QImode, operands[0], tmp);
+ operands[0] = adjust_address (operands[0], SImode, 0);
+ if (GET_CODE (operands[1]) == ABS)
+ {
+ tmp = gen_int_mode (0x7fffffff, SImode);
+ tmp = gen_rtx_AND (SImode, operands[0], tmp);
+ }
+ else
+ {
+ tmp = gen_int_mode (0x80000000, SImode);
+ tmp = gen_rtx_XOR (SImode, operands[0], tmp);
+ }
}
else
{
- tmp = gen_int_mode (0x80, QImode);
- tmp = gen_rtx_XOR (QImode, operands[0], tmp);
+ operands[0] = adjust_address (operands[0], QImode, size - 1);
+ if (GET_CODE (operands[1]) == ABS)
+ {
+ tmp = gen_int_mode (0x7f, QImode);
+ tmp = gen_rtx_AND (QImode, operands[0], tmp);
+ }
+ else
+ {
+ tmp = gen_int_mode (0x80, QImode);
+ tmp = gen_rtx_XOR (QImode, operands[0], tmp);
+ }
}
operands[1] = tmp;
})
+; APPLE LOCAL end radar 4117515
;; Conditionalize these after reload. If they match before reload, we
;; lose the clobber and ability to use integer instructions.
@@ -16297,7 +16294,33 @@
DONE;
})
-(define_insn "frndintxf2_floor"
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_floor"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+ UNSPEC_FRNDINT_FLOOR))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_USE_FANCY_MATH_387
+ && flag_unsafe_math_optimizations
+ && !(reload_completed || reload_in_progress)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ ix86_optimize_mode_switching = 1;
+
+ operands[2] = assign_386_stack_local (HImode, 1);
+ operands[3] = assign_386_stack_local (HImode, 2);
+
+ emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
+ operands[2], operands[3]));
+ DONE;
+}
+ [(set_attr "type" "frndint")
+ (set_attr "i387_cw" "floor")
+ (set_attr "mode" "XF")])
+
+(define_insn "frndintxf2_floor_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
UNSPEC_FRNDINT_FLOOR))
@@ -16310,6 +16333,16 @@
(set_attr "i387_cw" "floor")
(set_attr "mode" "XF")])
+(define_expand "floorxf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && flag_unsafe_math_optimizations"
+{
+ emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
+ DONE;
+})
+
(define_expand "floordf2"
[(use (match_operand:DF 0 "register_operand" ""))
(use (match_operand:DF 1 "register_operand" ""))]
@@ -16319,13 +16352,9 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extenddfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_floor (op0, op1));
emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
DONE;
@@ -16340,34 +16369,41 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extendsfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_floor (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_floor (op0, op1));
emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
DONE;
})
-(define_expand "floorxf2"
- [(use (match_operand:XF 0 "register_operand" ""))
- (use (match_operand:XF 1 "register_operand" ""))]
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_ceil"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+ UNSPEC_FRNDINT_CEIL))
+ (clobber (reg:CC FLAGS_REG))]
"TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
+ && flag_unsafe_math_optimizations
+ && !(reload_completed || reload_in_progress)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
{
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
ix86_optimize_mode_switching = 1;
- emit_insn (gen_frndintxf2_floor (operands[0], operands[1], op2, op3));
+ operands[2] = assign_386_stack_local (HImode, 1);
+ operands[3] = assign_386_stack_local (HImode, 2);
+
+ emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
+ operands[2], operands[3]));
DONE;
-})
+}
+ [(set_attr "type" "frndint")
+ (set_attr "i387_cw" "ceil")
+ (set_attr "mode" "XF")])
-(define_insn "frndintxf2_ceil"
+(define_insn "frndintxf2_ceil_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
UNSPEC_FRNDINT_CEIL))
@@ -16380,6 +16416,16 @@
(set_attr "i387_cw" "ceil")
(set_attr "mode" "XF")])
+(define_expand "ceilxf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && flag_unsafe_math_optimizations"
+{
+ emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
+ DONE;
+})
+
(define_expand "ceildf2"
[(use (match_operand:DF 0 "register_operand" ""))
(use (match_operand:DF 1 "register_operand" ""))]
@@ -16389,13 +16435,9 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extenddfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_ceil (op0, op1));
emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
DONE;
@@ -16410,34 +16452,41 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extendsfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_ceil (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_ceil (op0, op1));
emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
DONE;
})
-(define_expand "ceilxf2"
- [(use (match_operand:XF 0 "register_operand" ""))
- (use (match_operand:XF 1 "register_operand" ""))]
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_trunc"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+ UNSPEC_FRNDINT_TRUNC))
+ (clobber (reg:CC FLAGS_REG))]
"TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
+ && flag_unsafe_math_optimizations
+ && !(reload_completed || reload_in_progress)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
{
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
ix86_optimize_mode_switching = 1;
- emit_insn (gen_frndintxf2_ceil (operands[0], operands[1], op2, op3));
+ operands[2] = assign_386_stack_local (HImode, 1);
+ operands[3] = assign_386_stack_local (HImode, 2);
+
+ emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
+ operands[2], operands[3]));
DONE;
-})
+}
+ [(set_attr "type" "frndint")
+ (set_attr "i387_cw" "trunc")
+ (set_attr "mode" "XF")])
-(define_insn "frndintxf2_trunc"
+(define_insn "frndintxf2_trunc_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
UNSPEC_FRNDINT_TRUNC))
@@ -16450,6 +16499,16 @@
(set_attr "i387_cw" "trunc")
(set_attr "mode" "XF")])
+(define_expand "btruncxf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && flag_unsafe_math_optimizations"
+{
+ emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
+ DONE;
+})
+
(define_expand "btruncdf2"
[(use (match_operand:DF 0 "register_operand" ""))
(use (match_operand:DF 1 "register_operand" ""))]
@@ -16459,13 +16518,9 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extenddfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_trunc (op0, op1));
emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
DONE;
@@ -16480,34 +16535,41 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extendsfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_trunc (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_trunc (op0, op1));
emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
DONE;
})
-(define_expand "btruncxf2"
- [(use (match_operand:XF 0 "register_operand" ""))
- (use (match_operand:XF 1 "register_operand" ""))]
+;; Rounding mode control word calculation could clobber FLAGS_REG.
+(define_insn_and_split "frndintxf2_mask_pm"
+ [(set (match_operand:XF 0 "register_operand" "=f")
+ (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
+ UNSPEC_FRNDINT_MASK_PM))
+ (clobber (reg:CC FLAGS_REG))]
"TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
+ && flag_unsafe_math_optimizations
+ && !(reload_completed || reload_in_progress)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
{
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
ix86_optimize_mode_switching = 1;
- emit_insn (gen_frndintxf2_trunc (operands[0], operands[1], op2, op3));
+ operands[2] = assign_386_stack_local (HImode, 1);
+ operands[3] = assign_386_stack_local (HImode, 2);
+
+ emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
+ operands[2], operands[3]));
DONE;
-})
+}
+ [(set_attr "type" "frndint")
+ (set_attr "i387_cw" "mask_pm")
+ (set_attr "mode" "XF")])
-(define_insn "frndintxf2_mask_pm"
+(define_insn "frndintxf2_mask_pm_i387"
[(set (match_operand:XF 0 "register_operand" "=f")
(unspec:XF [(match_operand:XF 1 "register_operand" "0")]
UNSPEC_FRNDINT_MASK_PM))
@@ -16520,6 +16582,17 @@
(set_attr "i387_cw" "mask_pm")
(set_attr "mode" "XF")])
+(define_expand "nearbyintxf2"
+ [(use (match_operand:XF 0 "register_operand" ""))
+ (use (match_operand:XF 1 "register_operand" ""))]
+ "TARGET_USE_FANCY_MATH_387
+ && flag_unsafe_math_optimizations"
+{
+ emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
+
+ DONE;
+})
+
(define_expand "nearbyintdf2"
[(use (match_operand:DF 0 "register_operand" ""))
(use (match_operand:DF 1 "register_operand" ""))]
@@ -16529,13 +16602,9 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extenddfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_mask_pm (op0, op1));
emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
DONE;
@@ -16550,34 +16619,14 @@
{
rtx op0 = gen_reg_rtx (XFmode);
rtx op1 = gen_reg_rtx (XFmode);
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
emit_insn (gen_extendsfxf2 (op1, operands[1]));
- emit_insn (gen_frndintxf2_mask_pm (op0, op1, op2, op3));
+ emit_insn (gen_frndintxf2_mask_pm (op0, op1));
emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
DONE;
})
-(define_expand "nearbyintxf2"
- [(use (match_operand:XF 0 "register_operand" ""))
- (use (match_operand:XF 1 "register_operand" ""))]
- "TARGET_USE_FANCY_MATH_387
- && flag_unsafe_math_optimizations"
-{
- rtx op2 = assign_386_stack_local (HImode, 1);
- rtx op3 = assign_386_stack_local (HImode, 2);
-
- ix86_optimize_mode_switching = 1;
-
- emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1],
- op2, op3));
- DONE;
-})
-
;; Block operation instructions
@@ -18537,18 +18586,16 @@
;; Attempt to always use XOR for zeroing registers.
(define_peephole2
[(set (match_operand 0 "register_operand" "")
- (const_int 0))]
- "(GET_MODE (operands[0]) == QImode
- || GET_MODE (operands[0]) == HImode
- || GET_MODE (operands[0]) == SImode
- || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
+ (match_operand 1 "const0_operand" ""))]
+ "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
&& (! TARGET_USE_MOV0 || optimize_size)
&& GENERAL_REG_P (operands[0])
&& peep2_regno_dead_p (0, FLAGS_REG)"
[(parallel [(set (match_dup 0) (const_int 0))
(clobber (reg:CC FLAGS_REG))])]
- "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
- operands[0]);")
+{
+ operands[0] = gen_lowpart (word_mode, operands[0]);
+})
(define_peephole2
[(set (strict_low_part (match_operand 0 "register_operand" ""))