2005-07-14 Paolo Bonzini * reload.c (find_reloads): Take PREFERRED_OUTPUT_RELOAD_CLASS into account. For non-registers, equate an empty preferred reload class to a `!' in the constraint; move the if clause to do so after those that reject the insn. (push_reload): Allow PREFERRED_*_RELOAD_CLASS to liberally return NO_REGS. (find_dummy_reload): Likewise. * doc/tm.texi (Register Classes): Document what it means if PREFERRED_*_RELOAD_CLASS return NO_REGS. * config/i386/i386.c (ix86_preferred_reload_class): Force using SSE registers (and return NO_REGS for floating-point constants) if math is done with SSE. (ix86_preferred_output_reload_class): New. * config/i386/i386-protos.h (ix86_preferred_output_reload_class): New. * config/i386/i386.h (PREFERRED_OUTPUT_RELOAD_CLASS): New. * config/i386/i386.md: Remove # register preferences. Index: reload.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/reload.c,v retrieving revision 1.275 diff -u -p -r1.275 reload.c --- reload.c 5 Aug 2005 16:06:35 -0000 1.275 +++ reload.c 8 Aug 2005 16:36:59 -0000 @@ -1231,15 +1231,24 @@ push_reload (rtx in, rtx out, rtx *inloc /* Narrow down the class of register wanted if that is desirable on this machine for efficiency. */ - if (in != 0) - class = PREFERRED_RELOAD_CLASS (in, class); + { + enum reg_class preferred_class = class; + + if (in != 0) + preferred_class = PREFERRED_RELOAD_CLASS (in, class); /* Output reloads may need analogous treatment, different in detail. */ #ifdef PREFERRED_OUTPUT_RELOAD_CLASS - if (out != 0) - class = PREFERRED_OUTPUT_RELOAD_CLASS (out, class); + if (out != 0) + preferred_class = PREFERRED_OUTPUT_RELOAD_CLASS (out, preferred_class); #endif + /* Discard what the target said if we cannot do it. */ + if (preferred_class != NO_REGS + || (optional && type == RELOAD_FOR_OUTPUT)) + class = preferred_class; + } + /* Make sure we use a class that can handle the actual pseudo inside any subreg. For example, on the 386, QImode regs can appear within SImode subregs. Although GENERAL_REGS @@ -1937,7 +1946,11 @@ find_dummy_reload (rtx real_in, rtx real /* Narrow down the reg class, the same way push_reload will; otherwise we might find a dummy now, but push_reload won't. */ - class = PREFERRED_RELOAD_CLASS (in, class); + { + enum reg_class preferred_class = PREFERRED_RELOAD_CLASS (in, class); + if (class != NO_REGS) + class = preferred_class; + } /* See if OUT will do. */ if (REG_P (out) @@ -3451,22 +3464,10 @@ find_reloads (rtx insn, int replace, int losers++; } - /* If we can't reload this value at all, reject this - alternative. Note that we could also lose due to - LIMIT_RELOAD_RELOAD_CLASS, but we don't check that - here. */ - - if (! CONSTANT_P (operand) - && (enum reg_class) this_alternative[i] != NO_REGS - && (PREFERRED_RELOAD_CLASS (operand, - (enum reg_class) this_alternative[i]) - == NO_REGS)) - bad = 1; - /* Alternative loses if it requires a type of reload not permitted for this insn. We can always reload SCRATCH and objects with a REG_UNUSED note. */ - else if (GET_CODE (operand) != SCRATCH + if (GET_CODE (operand) != SCRATCH && modified[i] != RELOAD_READ && no_output_reloads && ! find_reg_note (insn, REG_UNUSED, operand)) bad = 1; @@ -3474,6 +3475,28 @@ find_reloads (rtx insn, int replace, int && ! const_to_mem) bad = 1; + /* If we can't reload this value at all, reject this + alternative. Note that we could also lose due to + LIMIT_RELOAD_CLASS, but we don't check that + here. */ + + if (! CONSTANT_P (operand) + && (enum reg_class) this_alternative[i] != NO_REGS) + { + if (PREFERRED_RELOAD_CLASS + (operand, (enum reg_class) this_alternative[i]) + == NO_REGS) + reject = 600; + +#ifdef PREFERRED_OUTPUT_RELOAD_CLASS + if (operand_type[i] == RELOAD_FOR_OUTPUT + && PREFERRED_OUTPUT_RELOAD_CLASS + (operand, (enum reg_class) this_alternative[i]) + == NO_REGS) + reject = 600; +#endif + } + /* We prefer to reload pseudos over reloading other things, since such reloads may be able to be eliminated later. If we are reloading a SCRATCH, we won't be generating any Index: doc/tm.texi =================================================================== RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v retrieving revision 1.441 diff -p -u -r1.441 tm.texi *** doc/tm.texi 13 Jul 2005 16:28:25 -0000 1.441 --- doc/tm.texi 15 Jul 2005 14:13:49 -0000 *************** *** 2385,2396 **** --- 2385,2406 ---- into any kind of register, code generation will be better if @code{LEGITIMATE_CONSTANT_P} makes the constant illegitimate instead of using @code{PREFERRED_RELOAD_CLASS}. + + If an insn has pseudos in it after register allocation, reload will go + through the alternatives and call repeatedly @code{PREFERRED_RELOAD_CLASS} + to find the best one. Returning @code{NO_REGS}, in this case, makes + reload add a @code{!} in front of the constraint: the x86 back-end uses + this feature to discourage usage of 387 registers when math is done in + the SSE registers (and vice versa). @end defmac @defmac PREFERRED_OUTPUT_RELOAD_CLASS (@var{x}, @var{class}) Like @code{PREFERRED_RELOAD_CLASS}, but for output reloads instead of input reloads. If you don't define this macro, the default is to use @var{class}, unchanged. + + You can also use @code{PREFERRED_OUTPUT_RELOAD_CLASS} to discourage + reload from using some alternatives, like @code{PREFERRED_RELOAD_CLASS}. @end defmac @defmac LIMIT_RELOAD_CLASS (@var{mode}, @var{class}) Index: config/i386/i386.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v retrieving revision 1.843 diff -u -p -r1.843 i386.c *** config/i386/i386.c 18 Jul 2005 06:39:18 -0000 1.843 --- config/i386/i386.c 25 Jul 2005 15:19:03 -0000 *************** *** 15411,15425 **** enum reg_class ix86_preferred_reload_class (rtx x, enum reg_class class) { /* We're only allowed to return a subclass of CLASS. Many of the following checks fail for NO_REGS, so eliminate that early. */ if (class == NO_REGS) return NO_REGS; /* All classes can load zeros. */ ! if (x == CONST0_RTX (GET_MODE (x))) return class; /* Floating-point constants need more complex checks. */ if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode) { --- 15411,15449 ---- enum reg_class ix86_preferred_reload_class (rtx x, enum reg_class class) { + enum machine_mode mode = GET_MODE (x); + bool is_sse_math_mode; + /* We're only allowed to return a subclass of CLASS. Many of the following checks fail for NO_REGS, so eliminate that early. */ if (class == NO_REGS) return NO_REGS; /* All classes can load zeros. */ ! if (x == CONST0_RTX (mode)) return class; + is_sse_math_mode = + TARGET_SSE_MATH && !TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (mode); + + /* Force constants into memory if we are loading: a) a vector constant into + an MMX or SSE register b) a floating-point constant into an SSE register + that will be used for math. This is because there are no MMX/SSE + load-from-constant instructions. */ + + if (CONSTANT_P (x)) + { + if (MAYBE_MMX_CLASS_P (class)) + return NO_REGS; + if (MAYBE_SSE_CLASS_P (class) + && (VECTOR_MODE_P (mode) || mode == TImode || is_sse_math_mode)) + return NO_REGS; + } + + /* Prefer SSE regs only, if we can use them for math. */ + if (is_sse_math_mode) + return SSE_CLASS_P (class) ? class : NO_REGS; + /* Floating-point constants need more complex checks. */ if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != VOIDmode) { *************** *** 15431,15438 **** zero above. We only want to wind up preferring 80387 registers if we plan on doing computation with them. */ if (TARGET_80387 - && (TARGET_MIX_SSE_I387 - || !(TARGET_SSE_MATH && SSE_FLOAT_MODE_P (GET_MODE (x)))) && standard_80387_constant_p (x)) { /* Limit class to non-sse. */ --- 15459,15464 ---- *************** *** 15448,15457 **** return NO_REGS; } - if (MAYBE_MMX_CLASS_P (class) && CONSTANT_P (x)) - return NO_REGS; - if (MAYBE_SSE_CLASS_P (class) && CONSTANT_P (x)) - return NO_REGS; /* Generally when we see PLUS here, it's the function invariant (plus soft-fp const_int). Which can only be computed into general --- 15474,15479 ---- *************** *** 15473,15478 **** --- 15495,15527 ---- return class; } + /* Discourage putting floating-point values in SSE registers unless + SSE math is being used, and likewise for the 387 registers. */ + enum reg_class + ix86_preferred_output_reload_class (rtx x, enum reg_class class) + { + enum machine_mode mode = GET_MODE (x); + + /* Restrict the output reload class to the register bank that we are doing + math on. If we would like not to return a subset of CLASS, reject this + alternative: if reload cannot do this, it will still use its choice. */ + mode = GET_MODE (x); + if (TARGET_SSE_MATH && SSE_FLOAT_MODE_P (mode)) + return MAYBE_SSE_CLASS_P (class) ? SSE_REGS : NO_REGS; + + if (TARGET_80387 && SCALAR_FLOAT_MODE_P (mode)) + { + if (class == FP_TOP_SSE_REGS) + return FP_TOP_REG; + else if (class == FP_SECOND_SSE_REGS) + return FP_SECOND_REG; + else + return FLOAT_CLASS_P (class) ? class : NO_REGS; + } + + return class; + } + /* If we are copying between general and FP registers, we need a memory location. The same is true for SSE and MMX registers. Index: config/i386/i386.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.h,v retrieving revision 1.440 diff -c -r1.440 i386.h *** config/i386/i386.h 26 Jun 2005 05:18:34 -0000 1.440 --- config/i386/i386.h 14 Jul 2005 08:07:55 -0000 *************** *** 1294,1299 **** --- 1294,1305 ---- #define PREFERRED_RELOAD_CLASS(X, CLASS) \ ix86_preferred_reload_class ((X), (CLASS)) + /* Discourage putting floating-point values in SSE registers unless + SSE math is being used, and likewise for the 387 registers. */ + + #define PREFERRED_OUTPUT_RELOAD_CLASS(X, CLASS) \ + ix86_preferred_output_reload_class ((X), (CLASS)) + /* If we are copying between general and FP registers, we need a memory location. The same is true for SSE and MMX registers. */ #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ Index: config/i386/i386-protos.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/i386/i386-protos.h,v retrieving revision 1.143 diff -c -r1.143 i386-protos.h *** config/i386/i386-protos.h 29 Jun 2005 17:27:16 -0000 1.143 --- config/i386/i386-protos.h 14 Jul 2005 08:07:55 -0000 *************** *** 188,193 **** --- 188,194 ---- extern bool ix86_cannot_change_mode_class (enum machine_mode, enum machine_mode, enum reg_class); extern enum reg_class ix86_preferred_reload_class (rtx, enum reg_class); + extern enum reg_class ix86_preferred_output_reload_class (rtx, enum reg_class); extern int ix86_memory_move_cost (enum machine_mode, enum reg_class, int); extern int ix86_mode_needed (int, rtx); extern void emit_i387_cw_initialization (int); Index: config/i386/i386.md =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v retrieving revision 1.645 diff -c -r1.645 i386.md *** config/i386/i386.md 12 Jul 2005 09:20:12 -0000 1.645 --- config/i386/i386.md 14 Jul 2005 21:22:24 -0000 *************** *** 946,953 **** (define_insn "*cmpfp_i_mixed" [(set (reg:CCFP FLAGS_REG) ! (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f") ! (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))] "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (operands[0]) == GET_MODE (operands[1])" --- 946,953 ---- (define_insn "*cmpfp_i_mixed" [(set (reg:CCFP FLAGS_REG) ! (compare:CCFP (match_operand 0 "register_operand" "f,x") ! (match_operand 1 "nonimmediate_operand" "f,xm")))] "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (operands[0]) == GET_MODE (operands[1])" *************** *** 995,1002 **** (define_insn "*cmpfp_iu_mixed" [(set (reg:CCFPU FLAGS_REG) ! (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f") ! (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))] "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (operands[0]) == GET_MODE (operands[1])" --- 995,1002 ---- (define_insn "*cmpfp_iu_mixed" [(set (reg:CCFPU FLAGS_REG) ! (compare:CCFPU (match_operand 0 "register_operand" "f,x") ! (match_operand 1 "nonimmediate_operand" "f,xm")))] "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && GET_MODE (operands[0]) == GET_MODE (operands[1])" *************** *** 2197,2203 **** (define_insn "*pushsf" [(set (match_operand:SF 0 "push_operand" "=<,<,<") ! (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))] "!TARGET_64BIT" { /* Anything else should be already split before reg-stack. */ --- 2197,2203 ---- (define_insn "*pushsf" [(set (match_operand:SF 0 "push_operand" "=<,<,<") ! (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))] "!TARGET_64BIT" { /* Anything else should be already split before reg-stack. */ *************** *** 2210,2216 **** (define_insn "*pushsf_rex64" [(set (match_operand:SF 0 "push_operand" "=X,X,X") ! (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))] "TARGET_64BIT" { /* Anything else should be already split before reg-stack. */ --- 2210,2216 ---- (define_insn "*pushsf_rex64" [(set (match_operand:SF 0 "push_operand" "=X,X,X") ! (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))] "TARGET_64BIT" { /* Anything else should be already split before reg-stack. */ *************** *** 2250,2258 **** (define_insn "*movsf_1" [(set (match_operand:SF 0 "nonimmediate_operand" ! "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y") (match_operand:SF 1 "general_operand" ! "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))] "!(MEM_P (operands[0]) && MEM_P (operands[1])) && (reload_in_progress || reload_completed || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) --- 2250,2258 ---- (define_insn "*movsf_1" [(set (match_operand:SF 0 "nonimmediate_operand" ! "=f,m ,f,r,m ,x,x,x,m ,!*y,!rm,!*y") (match_operand:SF 1 "general_operand" ! "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))] "!(MEM_P (operands[0]) && MEM_P (operands[1])) && (reload_in_progress || reload_completed || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE) *************** *** 2365,2371 **** (define_insn "*pushdf_nointeger" [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") ! (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))] "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES" { /* This insn should be already split before reg-stack. */ --- 2365,2371 ---- (define_insn "*pushdf_nointeger" [(set (match_operand:DF 0 "push_operand" "=<,<,<,<") ! (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))] "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES" { /* This insn should be already split before reg-stack. */ *************** *** 2377,2383 **** (define_insn "*pushdf_integer" [(set (match_operand:DF 0 "push_operand" "=<,<,<") ! (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))] "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES" { /* This insn should be already split before reg-stack. */ --- 2377,2383 ---- (define_insn "*pushdf_integer" [(set (match_operand:DF 0 "push_operand" "=<,<,<") ! (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))] "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES" { /* This insn should be already split before reg-stack. */ *************** *** 2417,2425 **** (define_insn "*movdf_nointeger" [(set (match_operand:DF 0 "nonimmediate_operand" ! "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ") (match_operand:DF 1 "general_operand" ! "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))] "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT) && (reload_in_progress || reload_completed --- 2417,2425 ---- (define_insn "*movdf_nointeger" [(set (match_operand:DF 0 "nonimmediate_operand" ! "=f,m ,f,*r ,o ,Y*x,Y*x,Y*x,m ") (match_operand:DF 1 "general_operand" ! "fm,f,G ,*roF,F*r,C ,Y*x,HmY*x,Y*x"))] "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT) && (reload_in_progress || reload_completed *************** *** 2537,2545 **** (define_insn "*movdf_integer" [(set (match_operand:DF 0 "nonimmediate_operand" ! "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m") (match_operand:DF 1 "general_operand" ! "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))] "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT) && (reload_in_progress || reload_completed --- 2537,2545 ---- (define_insn "*movdf_integer" [(set (match_operand:DF 0 "nonimmediate_operand" ! "=f,m ,f,r,o ,Y*x,Y*x,Y*x,m") (match_operand:DF 1 "general_operand" ! "fm,f,G ,roF,Fr,C ,Y*x,m ,Y*x"))] "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT) && (reload_in_progress || reload_completed *************** *** 2712,2718 **** (define_insn "*pushxf_integer" [(set (match_operand:XF 0 "push_operand" "=<,<") ! (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))] "!optimize_size" { /* This insn should be already split before reg-stack. */ --- 2712,2718 ---- (define_insn "*pushxf_integer" [(set (match_operand:XF 0 "push_operand" "=<,<") ! (match_operand:XF 1 "general_no_elim_operand" "f,ro"))] "!optimize_size" { /* This insn should be already split before reg-stack. */ *************** *** 2784,2791 **** (set_attr "mode" "XF,XF,XF,SI,SI")]) (define_insn "*movxf_integer" ! [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o") ! (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))] "!optimize_size && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) && (reload_in_progress || reload_completed --- 2784,2791 ---- (set_attr "mode" "XF,XF,XF,SI,SI")]) (define_insn "*movxf_integer" ! [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o") ! (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))] "!optimize_size && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM) && (reload_in_progress || reload_completed *************** *** 3508,3515 **** }) (define_insn "*extendsfdf2_mixed" ! [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f") ! (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))] "TARGET_SSE2 && TARGET_MIX_SSE_I387 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" { --- 3508,3515 ---- }) (define_insn "*extendsfdf2_mixed" ! [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y") ! (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))] "TARGET_SSE2 && TARGET_MIX_SSE_I387 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" { *************** *** 3824,3830 **** }) (define_insn "*truncxfsf2_mixed" ! [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf") (float_truncate:SF (match_operand:XF 1 "register_operand" "f,f,f,f"))) (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))] --- 3824,3830 ---- }) (define_insn "*truncxfsf2_mixed" ! [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x") (float_truncate:SF (match_operand:XF 1 "register_operand" "f,f,f,f"))) (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))] *************** *** 3851,3857 **** (set_attr "mode" "SF")]) (define_insn "*truncxfsf2_i387" ! [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f") (float_truncate:SF (match_operand:XF 1 "register_operand" "f,f,f"))) (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))] --- 3851,3857 ---- (set_attr "mode" "SF")]) (define_insn "*truncxfsf2_i387" ! [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r") (float_truncate:SF (match_operand:XF 1 "register_operand" "f,f,f"))) (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))] *************** *** 3922,3928 **** }) (define_insn "*truncxfdf2_mixed" ! [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf") (float_truncate:DF (match_operand:XF 1 "register_operand" "f,f,f,f"))) (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))] --- 3922,3928 ---- }) (define_insn "*truncxfdf2_mixed" ! [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y") (float_truncate:DF (match_operand:XF 1 "register_operand" "f,f,f,f"))) (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))] *************** *** 3949,3955 **** (set_attr "mode" "DF")]) (define_insn "*truncxfdf2_i387" ! [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f") (float_truncate:DF (match_operand:XF 1 "register_operand" "f,f,f"))) (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))] --- 3949,3955 ---- (set_attr "mode" "DF")]) (define_insn "*truncxfdf2_i387" ! [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r") (float_truncate:DF (match_operand:XF 1 "register_operand" "f,f,f"))) (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))] *************** *** 4423,4429 **** "") (define_insn "*floatsisf2_mixed" ! [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f") (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] "TARGET_MIX_SSE_I387" "@ --- 4423,4429 ---- "") (define_insn "*floatsisf2_mixed" ! [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x") (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] "TARGET_MIX_SSE_I387" "@ *************** *** 4466,4472 **** "") (define_insn "*floatdisf2_mixed" ! [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f") (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] "TARGET_64BIT && TARGET_MIX_SSE_I387" "@ --- 4466,4472 ---- "") (define_insn "*floatdisf2_mixed" ! [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x") (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] "TARGET_64BIT && TARGET_MIX_SSE_I387" "@ *************** *** 4534,4540 **** "") (define_insn "*floatsidf2_mixed" ! [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f") (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] "TARGET_SSE2 && TARGET_MIX_SSE_I387" "@ --- 4534,4540 ---- "") (define_insn "*floatsidf2_mixed" ! [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y") (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))] "TARGET_SSE2 && TARGET_MIX_SSE_I387" "@ *************** *** 4577,4583 **** "") (define_insn "*floatdidf2_mixed" ! [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f") (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387" "@ --- 4577,4583 ---- "") (define_insn "*floatdidf2_mixed" ! [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y") (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))] "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387" "@ *************** *** 9383,9391 **** "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;") (define_insn "*absnegsf2_mixed" ! [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm") (match_operator:SF 3 "absneg_operator" ! [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")])) (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X")) (clobber (reg:CC FLAGS_REG))] "TARGET_SSE_MATH && TARGET_MIX_SSE_I387 --- 9383,9391 ---- "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;") (define_insn "*absnegsf2_mixed" ! [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,f,rm") (match_operator:SF 3 "absneg_operator" ! [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0 ,0")])) (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X")) (clobber (reg:CC FLAGS_REG))] "TARGET_SSE_MATH && TARGET_MIX_SSE_I387 *************** *** 9479,9487 **** "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;") (define_insn "*absnegdf2_mixed" ! [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm") (match_operator:DF 3 "absneg_operator" ! [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")])) (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X")) (clobber (reg:CC FLAGS_REG))] "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 --- 9479,9487 ---- "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;") (define_insn "*absnegdf2_mixed" ! [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm") (match_operator:DF 3 "absneg_operator" ! [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ,0")])) (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X")) (clobber (reg:CC FLAGS_REG))] "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 *************** *** 12723,12730 **** (define_insn "*fp_jcc_1_mixed" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" ! [(match_operand 1 "register_operand" "f#x,x#f") ! (match_operand 2 "nonimmediate_operand" "f#x,xm#f")]) (label_ref (match_operand 3 "" "")) (pc))) (clobber (reg:CCFP FPSR_REG)) --- 12723,12730 ---- (define_insn "*fp_jcc_1_mixed" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" ! [(match_operand 1 "register_operand" "f,x") ! (match_operand 2 "nonimmediate_operand" "f,xm")]) (label_ref (match_operand 3 "" "")) (pc))) (clobber (reg:CCFP FPSR_REG)) *************** *** 12768,12775 **** (define_insn "*fp_jcc_2_mixed" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" ! [(match_operand 1 "register_operand" "f#x,x#f") ! (match_operand 2 "nonimmediate_operand" "f#x,xm#f")]) (pc) (label_ref (match_operand 3 "" "")))) (clobber (reg:CCFP FPSR_REG)) --- 12768,12775 ---- (define_insn "*fp_jcc_2_mixed" [(set (pc) (if_then_else (match_operator 0 "comparison_operator" ! [(match_operand 1 "register_operand" "f,x") ! (match_operand 2 "nonimmediate_operand" "f,xm")]) (pc) (label_ref (match_operand 3 "" "")))) (clobber (reg:CCFP FPSR_REG)) *************** *** 13906,13915 **** ;; so use special patterns for add and mull. (define_insn "*fop_sf_comm_mixed" ! [(set (match_operand:SF 0 "register_operand" "=f#x,x#f") (match_operator:SF 3 "binary_fp_operator" [(match_operand:SF 1 "nonimmediate_operand" "%0,0") ! (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))] "TARGET_MIX_SSE_I387 && COMMUTATIVE_ARITH_P (operands[3]) && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" --- 13906,13915 ---- ;; so use special patterns for add and mull. (define_insn "*fop_sf_comm_mixed" ! [(set (match_operand:SF 0 "register_operand" "=f,x") (match_operator:SF 3 "binary_fp_operator" [(match_operand:SF 1 "nonimmediate_operand" "%0,0") ! (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))] "TARGET_MIX_SSE_I387 && COMMUTATIVE_ARITH_P (operands[3]) && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" *************** *** 13958,13964 **** [(set (match_operand:SF 0 "register_operand" "=f,f,x") (match_operator:SF 3 "binary_fp_operator" [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0") ! (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))] "TARGET_MIX_SSE_I387 && !COMMUTATIVE_ARITH_P (operands[3]) && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" --- 13958,13964 ---- [(set (match_operand:SF 0 "register_operand" "=f,f,x") (match_operator:SF 3 "binary_fp_operator" [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0") ! (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))] "TARGET_MIX_SSE_I387 && !COMMUTATIVE_ARITH_P (operands[3]) && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" *************** *** 14052,14061 **** (set_attr "mode" "")]) (define_insn "*fop_df_comm_mixed" ! [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f") (match_operator:DF 3 "binary_fp_operator" [(match_operand:DF 1 "nonimmediate_operand" "%0,0") ! (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))] "TARGET_SSE2 && TARGET_MIX_SSE_I387 && COMMUTATIVE_ARITH_P (operands[3]) && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" --- 14052,14061 ---- (set_attr "mode" "")]) (define_insn "*fop_df_comm_mixed" ! [(set (match_operand:DF 0 "register_operand" "=f,Y") (match_operator:DF 3 "binary_fp_operator" [(match_operand:DF 1 "nonimmediate_operand" "%0,0") ! (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))] "TARGET_SSE2 && TARGET_MIX_SSE_I387 && COMMUTATIVE_ARITH_P (operands[3]) && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" *************** *** 14101,14110 **** (set_attr "mode" "DF")]) (define_insn "*fop_df_1_mixed" ! [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f") (match_operator:DF 3 "binary_fp_operator" [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0") ! (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))] "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 && !COMMUTATIVE_ARITH_P (operands[3]) && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" --- 14101,14110 ---- (set_attr "mode" "DF")]) (define_insn "*fop_df_1_mixed" ! [(set (match_operand:DF 0 "register_operand" "=f,f,Y") (match_operator:DF 3 "binary_fp_operator" [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0") ! (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))] "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387 && !COMMUTATIVE_ARITH_P (operands[3]) && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)" *************** *** 14419,14426 **** }) (define_insn "*sqrtsf2_mixed" ! [(set (match_operand:SF 0 "register_operand" "=f#x,x#f") ! (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))] "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387" "@ fsqrt --- 14419,14426 ---- }) (define_insn "*sqrtsf2_mixed" ! [(set (match_operand:SF 0 "register_operand" "=f,x") ! (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))] "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387" "@ fsqrt *************** *** 14457,14464 **** }) (define_insn "*sqrtdf2_mixed" ! [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f") ! (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))] "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387" "@ fsqrt --- 14457,14464 ---- }) (define_insn "*sqrtdf2_mixed" ! [(set (match_operand:DF 0 "register_operand" "=f,Y") ! (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))] "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387" "@ fsqrt *************** *** 17921,17931 **** "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") (define_insn "*movsfcc_1_387" ! [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f") (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" [(reg FLAGS_REG) (const_int 0)]) ! (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0") ! (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))] "TARGET_80387 && TARGET_CMOVE && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" "@ --- 17921,17931 ---- "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") (define_insn "*movsfcc_1_387" ! [(set (match_operand:SF 0 "register_operand" "=f,f,r,r") (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" [(reg FLAGS_REG) (const_int 0)]) ! (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0") ! (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))] "TARGET_80387 && TARGET_CMOVE && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" "@ *************** *** 17945,17955 **** "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") (define_insn "*movdfcc_1" ! [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f") (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" [(reg FLAGS_REG) (const_int 0)]) ! (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0") ! (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))] "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" "@ --- 17945,17955 ---- "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;") (define_insn "*movdfcc_1" ! [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r") (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" [(reg FLAGS_REG) (const_int 0)]) ! (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") ! (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" "@ *************** *** 17961,17971 **** (set_attr "mode" "DF")]) (define_insn "*movdfcc_1_rex64" ! [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f") (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" [(reg FLAGS_REG) (const_int 0)]) ! (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f") ! (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))] "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" "@ --- 17961,17971 ---- (set_attr "mode" "DF")]) (define_insn "*movdfcc_1_rex64" ! [(set (match_operand:DF 0 "register_operand" "=f,f,r,r") (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" [(reg FLAGS_REG) (const_int 0)]) ! (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0") ! (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))] "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)" "@