diff options
Diffstat (limited to 'contrib/gcc/config/i386/i386.md')
-rw-r--r-- | contrib/gcc/config/i386/i386.md | 3357 |
1 files changed, 1867 insertions, 1490 deletions
diff --git a/contrib/gcc/config/i386/i386.md b/contrib/gcc/config/i386/i386.md index f85992f..fb3e1b2 100644 --- a/contrib/gcc/config/i386/i386.md +++ b/contrib/gcc/config/i386/i386.md @@ -64,13 +64,50 @@ ;; prevent insns referencing it being scheduled across the initial ;; decrement of the stack pointer. ;; 5 This is a `bsf' operation. +;; 6 This is the @GOT offset of a PIC address. +;; 7 This is the @GOTOFF offset of a PIC address. +;; 8 This is a reference to a symbol's @PLT address. ;; This shadows the processor_type enumeration, so changes must be made ;; to i386.h at the same time. -(define_attr "type" "integer,idiv,imul,fld,fpop,fpdiv,fpmul" +(define_attr "type" + "integer,binary,memory,test,compare,fcompare,idiv,imul,lea,fld,fpop,fpdiv,fpmul" (const_string "integer")) +(define_attr "memory" "none,load,store" + (cond [(eq_attr "type" "idiv,lea") + (const_string "none") + + (eq_attr "type" "fld") + (const_string "load") + + (eq_attr "type" "test") + (if_then_else (match_operand 0 "memory_operand" "") + (const_string "load") + (const_string "none")) + + (eq_attr "type" "compare,fcompare") + (if_then_else (ior (match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" "")) + (const_string "load") + (const_string "none")) + + (and (eq_attr "type" "integer,memory,fpop") + (match_operand 0 "memory_operand" "")) + (const_string "store") + + (and (eq_attr "type" "integer,memory,fpop") + (match_operand 1 "memory_operand" "")) + (const_string "load") + + (and (eq_attr "type" "binary,imul,fpmul,fpdiv") + (ior (match_operand 1 "memory_operand" "") + (match_operand 2 "memory_operand" ""))) + (const_string "load")] + + (const_string "none"))) + ;; Functional units ; (define_function_unit NAME MULTIPLICITY SIMULTANEITY @@ -89,11 +126,11 @@ ;; Floating point (define_function_unit "fp" 1 0 - (and (eq_attr "type" "fpop") (eq_attr "cpu" "i386,i486")) + (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "i386,i486")) 5 5) (define_function_unit "fp" 1 0 - (and (eq_attr "type" "fpop") (eq_attr "cpu" "pentium,pentiumpro")) + (and (eq_attr "type" "fpop,fcompare") (eq_attr "cpu" "pentium,pentiumpro")) 3 0) (define_function_unit "fp" 1 0 @@ -117,12 +154,69 @@ 10 10) (define_function_unit "fp" 1 0 - (eq_attr "type" "fld") + (and (eq_attr "type" "fld") (eq_attr "cpu" "!pentiumpro,k6")) 1 0) -(define_function_unit "integer" 1 0 - (and (eq_attr "type" "integer") (eq_attr "cpu" "!i386")) - 2 0) +;; K6 FPU is not pipelined. +(define_function_unit "fp" 1 0 + (and (eq_attr "type" "fpop,fpmul,fcompare") (eq_attr "cpu" "k6")) + 2 2) + +;; i386 and i486 have one integer unit, which need not be modeled + +(define_function_unit "integer" 2 0 + (and (eq_attr "type" "integer,binary,test,compare,lea") (eq_attr "cpu" "pentium,pentiumpro")) + 1 0) + +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "k6") + (and (eq_attr "type" "integer,binary,test,compare") + (eq_attr "memory" "!load"))) + 1 0) + +;; Internally, K6 converts REG OP MEM instructions into a load (2 cycles) +;; and a register operation (1 cycle). +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "k6") + (and (eq_attr "type" "integer,binary,test,compare") + (eq_attr "memory" "load"))) + 3 0) + +;; Multiplies use one of the integer units +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "pentium") (eq_attr "type" "imul")) + 11 11) + +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "k6") (eq_attr "type" "imul")) + 2 2) + +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "pentium") (eq_attr "type" "idiv")) + 25 25) + +(define_function_unit "integer" 2 0 + (and (eq_attr "cpu" "k6") (eq_attr "type" "idiv")) + 17 17) + +;; Pentium Pro and K6 have a separate load unit. +(define_function_unit "load" 1 0 + (and (eq_attr "cpu" "pentiumpro") (eq_attr "memory" "load")) + 3 0) + +(define_function_unit "load" 1 0 + (and (eq_attr "cpu" "k6") (eq_attr "memory" "load")) + 2 0) + +;; Pentium Pro and K6 have a separate store unit. +(define_function_unit "store" 1 0 + (and (eq_attr "cpu" "pentiumpro,k6") (eq_attr "memory" "store")) + 1 0) + +;; lea executes in the K6 store unit with 1 cycle latency +(define_function_unit "store" 1 0 + (and (eq_attr "cpu" "k6") (eq_attr "type" "lea")) + 1 0) ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM". @@ -140,7 +234,7 @@ ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in i386.h. -(define_attr "cpu" "i386,i486,pentium,pentiumpro" +(define_attr "cpu" "i386,i486,pentium,pentiumpro,k6" (const (symbol_ref "ix86_cpu"))) (define_insn "tstsi_1" @@ -154,7 +248,8 @@ operands[1] = const0_rtx; return AS2 (cmp%L0,%1,%0); -}") +}" + [(set_attr "type" "test")]) (define_expand "tstsi" [(set (cc0) @@ -179,7 +274,8 @@ operands[1] = const0_rtx; return AS2 (cmp%W0,%1,%0); -}") +}" + [(set_attr "type" "test")]) (define_expand "tsthi" [(set (cc0) @@ -204,7 +300,8 @@ operands[1] = const0_rtx; return AS2 (cmp%B0,%1,%0); -}") +}" + [(set_attr "type" "test")]) (define_expand "tstqi" [(set (cc0) @@ -234,7 +331,8 @@ output_asm_insn (AS1 (fstp,%y0), operands); return output_fp_cc0_set (insn); -}") +}" + [(set_attr "type" "test")]) ;; Don't generate tstsf if generating IEEE code, since the `ftst' opcode ;; isn't IEEE compliant. @@ -268,7 +366,8 @@ output_asm_insn (AS1 (fstp,%y0), operands); return output_fp_cc0_set (insn); -}") +}" + [(set_attr "type" "test")]) ;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode ;; isn't IEEE compliant. @@ -302,7 +401,8 @@ output_asm_insn (AS1 (fstp,%y0), operands); return output_fp_cc0_set (insn); -}") +}" + [(set_attr "type" "test")]) ;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode ;; isn't IEEE compliant. @@ -328,7 +428,8 @@ (compare (match_operand:SI 0 "nonimmediate_operand" "mr,r") (match_operand:SI 1 "general_operand" "ri,mr")))] "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* return AS2 (cmp%L0,%1,%0);") + "* return AS2 (cmp%L0,%1,%0);" + [(set_attr "type" "compare")]) (define_expand "cmpsi" [(set (cc0) @@ -351,7 +452,8 @@ (compare (match_operand:HI 0 "nonimmediate_operand" "mr,r") (match_operand:HI 1 "general_operand" "ri,mr")))] "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* return AS2 (cmp%W0,%1,%0);") + "* return AS2 (cmp%W0,%1,%0);" + [(set_attr "type" "compare")]) (define_expand "cmphi" [(set (cc0) @@ -374,7 +476,8 @@ (compare (match_operand:QI 0 "nonimmediate_operand" "q,mq") (match_operand:QI 1 "general_operand" "qm,nq")))] "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM" - "* return AS2 (cmp%B0,%1,%0);") + "* return AS2 (cmp%B0,%1,%0);" + [(set_attr "type" "compare")]) (define_expand "cmpqi" [(set (cc0) @@ -403,27 +506,8 @@ (match_operand:XF 1 "register_operand" "f")])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:XF 0 "register_operand" "f") - (float:XF - (match_operand:SI 1 "nonimmediate_operand" "rm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(float:XF - (match_operand:SI 0 "nonimmediate_operand" "rm")) - (match_operand:XF 1 "register_operand" "f")])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -433,7 +517,8 @@ (match_operand:DF 1 "nonimmediate_operand" "fm"))])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -443,7 +528,8 @@ (match_operand:XF 1 "register_operand" "f")])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -453,7 +539,8 @@ (match_operand:SF 1 "nonimmediate_operand" "fm"))])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -463,7 +550,8 @@ (match_operand:XF 1 "register_operand" "f")])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -471,7 +559,8 @@ (match_operand:XF 1 "register_operand" "f"))) (clobber (match_scratch:HI 2 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -481,27 +570,8 @@ (clobber (match_scratch:HI 3 "=a,a"))] "TARGET_80387 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:DF 0 "register_operand" "f") - (float:DF - (match_operand:SI 1 "nonimmediate_operand" "rm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(float:DF - (match_operand:SI 0 "nonimmediate_operand" "rm")) - (match_operand:DF 1 "register_operand" "f")])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -511,7 +581,8 @@ (match_operand:SF 1 "nonimmediate_operand" "fm"))])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -521,7 +592,8 @@ (match_operand:DF 1 "register_operand" "f")])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -531,7 +603,8 @@ (match_operand:DF 1 "nonimmediate_operand" "fm")])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -539,7 +612,8 @@ (match_operand:DF 1 "register_operand" "f"))) (clobber (match_scratch:HI 2 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) ;; These two insns will never be generated by combine due to the mode of ;; the COMPARE. @@ -561,7 +635,7 @@ ; "TARGET_80387" ; "* return output_float_compare (insn, operands);") -(define_insn "cmpsf_cc_1" +(define_insn "*cmpsf_cc_1" [(set (cc0) (match_operator 2 "VOIDmode_compare_op" [(match_operand:SF 0 "nonimmediate_operand" "f,fm") @@ -569,27 +643,8 @@ (clobber (match_scratch:HI 3 "=a,a"))] "TARGET_80387 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(match_operand:SF 0 "register_operand" "f") - (float:SF - (match_operand:SI 1 "nonimmediate_operand" "rm"))])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") - -(define_insn "" - [(set (cc0) - (match_operator 2 "VOIDmode_compare_op" - [(float:SF - (match_operand:SI 0 "nonimmediate_operand" "rm")) - (match_operand:SF 1 "register_operand" "f")])) - (clobber (match_scratch:HI 3 "=a"))] - "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_insn "" [(set (cc0) @@ -597,7 +652,8 @@ (match_operand:SF 1 "register_operand" "f"))) (clobber (match_scratch:HI 2 "=a"))] "TARGET_80387" - "* return output_float_compare (insn, operands);") + "* return output_float_compare (insn, operands);" + [(set_attr "type" "fcompare")]) (define_expand "cmpxf" [(set (cc0) @@ -711,7 +767,10 @@ /* For small integers, we may actually use testb. */ if (GET_CODE (operands[1]) == CONST_INT && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0])) - && (! REG_P (operands[0]) || QI_REG_P (operands[0]))) + && (! REG_P (operands[0]) || QI_REG_P (operands[0])) + /* A Pentium test is pairable only with eax. Not with ah or al. */ + && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM + || optimize_size)) { /* We may set the sign bit spuriously. */ @@ -757,7 +816,8 @@ return AS2 (test%L0,%1,%0); return AS2 (test%L1,%0,%1); -}") +}" + [(set_attr "type" "compare")]) (define_insn "" [(set (cc0) @@ -805,7 +865,8 @@ return AS2 (test%W0,%1,%0); return AS2 (test%W1,%0,%1); -}") +}" + [(set_attr "type" "compare")]) (define_insn "" [(set (cc0) @@ -818,7 +879,8 @@ return AS2 (test%B0,%1,%0); return AS2 (test%B1,%0,%1); -}") +}" + [(set_attr "type" "compare")]) ;; move instructions. ;; There is one for each machine mode, @@ -829,13 +891,15 @@ [(set (match_operand:SI 0 "push_operand" "=<") (match_operand:SI 1 "nonmemory_operand" "rn"))] "flag_pic" - "* return AS1 (push%L0,%1);") + "* return AS1 (push%L0,%1);" + [(set_attr "memory" "store")]) (define_insn "" [(set (match_operand:SI 0 "push_operand" "=<") (match_operand:SI 1 "nonmemory_operand" "ri"))] "!flag_pic" - "* return AS1 (push%L0,%1);") + "* return AS1 (push%L0,%1);" + [(set_attr "memory" "store")]) ;; On a 386, it is faster to push MEM directly. @@ -843,7 +907,9 @@ [(set (match_operand:SI 0 "push_operand" "=<") (match_operand:SI 1 "memory_operand" "m"))] "TARGET_PUSH_MEMORY" - "* return AS1 (push%L0,%1);") + "* return AS1 (push%L0,%1);" + [(set_attr "type" "memory") + (set_attr "memory" "load")]) ;; General case of fullword move. @@ -863,7 +929,7 @@ /* Don't generate memory->memory moves, go through a register */ else if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -874,18 +940,24 @@ ;; On i486, incl reg is faster than movl $1,reg. (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=g,r") - (match_operand:SI 1 "general_operand" "rn,im"))] + [(set (match_operand:SI 0 "general_operand" "=g,r,r") + (match_operand:SI 1 "general_operand" "rn,i,m"))] "((!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)) && flag_pic" "* { rtx link; - if (operands[1] == const0_rtx && REG_P (operands[0])) + + /* K6: mov reg,0 is slightly faster than xor reg,reg but is 3 bytes + longer. */ + if ((ix86_cpu != PROCESSOR_K6 || optimize_size) + && operands[1] == const0_rtx && REG_P (operands[0])) return AS2 (xor%L0,%0,%0); if (operands[1] == const1_rtx + /* PPRO and K6 prefer mov to inc to reduce dependencies. */ + && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! INSN_DELETED_P (XEXP (link, 0)) @@ -901,7 +973,9 @@ return AS2 (lea%L0,%a1,%0); return AS2 (mov%L0,%1,%0); -}") +}" + [(set_attr "type" "integer,integer,memory") + (set_attr "memory" "*,*,load")]) (define_insn "" [(set (match_operand:SI 0 "general_operand" "=g,r") @@ -912,10 +986,18 @@ "* { rtx link; + + /* Use of xor was disabled for AMD K6 as recommended by the Optimization + Manual. My test shows, that this generally hurts the performance, because + mov is longer and takes longer to decode and decoding is the main + bottleneck of K6 when executing GCC code. */ + if (operands[1] == const0_rtx && REG_P (operands[0])) return AS2 (xor%L0,%0,%0); if (operands[1] == const1_rtx + /* PPRO and K6 prefer mov to inc to reduce dependencies. */ + && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! INSN_DELETED_P (XEXP (link, 0)) @@ -928,19 +1010,25 @@ return AS1 (inc%L0,%0); return AS2 (mov%L0,%1,%0); -}") +}" + [(set_attr "type" "integer,memory") + (set_attr "memory" "*,load")]) (define_insn "" [(set (match_operand:HI 0 "push_operand" "=<") (match_operand:HI 1 "nonmemory_operand" "ri"))] "" - "* return AS1 (push%W0,%1);") + "* return AS1 (push%W0,%1);" + [(set_attr "type" "memory") + (set_attr "memory" "store")]) (define_insn "" [(set (match_operand:HI 0 "push_operand" "=<") (match_operand:HI 1 "memory_operand" "m"))] "TARGET_PUSH_MEMORY" - "* return AS1 (push%W0,%1);") + "* return AS1 (push%W0,%1);" + [(set_attr "type" "memory") + (set_attr "memory" "load")]) ;; On i486, an incl and movl are both faster than incw and movw. @@ -952,7 +1040,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -971,6 +1059,8 @@ return AS2 (xor%L0,%k0,%k0); if (REG_P (operands[0]) && operands[1] == const1_rtx + /* PPRO and K6 prefer mov to inc to reduce dependencies. */ + && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! INSN_DELETED_P (XEXP (link, 0)) @@ -989,7 +1079,7 @@ operands[1] = i386_sext16_if_const (operands[1]); return AS2 (mov%L0,%k1,%k0); } - if (TARGET_PENTIUMPRO) + if (! TARGET_ZERO_EXTEND_WITH_AND) { /* movzwl is faster than movw on the Pentium Pro, * although not as fast as an aligned movl. */ @@ -1002,7 +1092,9 @@ } return AS2 (mov%W0,%1,%0); -}") +}" + [(set_attr "type" "integer,memory") + (set_attr "memory" "*,load")]) (define_expand "movstricthi" [(set (strict_low_part (match_operand:HI 0 "general_operand" "")) @@ -1012,7 +1104,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1027,10 +1119,18 @@ "* { rtx link; + + /* Use of xor was disabled for AMD K6 as recommended by the Optimization + Manual. My test shows, that this generally hurts the performance, because + mov is longer and takes longer to decode and decoding is the main + bottleneck of K6 when executing GCC code. */ + if (operands[1] == const0_rtx && REG_P (operands[0])) return AS2 (xor%W0,%0,%0); if (operands[1] == const1_rtx + /* PPRO and K6 prefer mov to inc to reduce dependencies. */ + && (optimize_size || (int)ix86_cpu < (int)PROCESSOR_PENTIUMPRO) && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! INSN_DELETED_P (XEXP (link, 0)) @@ -1043,7 +1143,8 @@ return AS1 (inc%W0,%0); return AS2 (mov%W0,%1,%0); -}") +}" + [(set_attr "type" "integer,memory")]) ;; emit_push_insn when it calls move_by_pieces ;; requires an insn to "push a byte". @@ -1078,7 +1179,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1093,10 +1194,12 @@ "* { rtx link; - if (operands[1] == const0_rtx && REG_P (operands[0])) - return AS2 (xor%L0,%k0,%k0); + + /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. + It is at least as fast as xor on any processor except a Pentium. */ if (operands[1] == const1_rtx + && TARGET_PENTIUM && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ && ! INSN_DELETED_P (XEXP (link, 0)) @@ -1138,7 +1241,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1153,10 +1256,11 @@ "* { rtx link; - if (operands[1] == const0_rtx && REG_P (operands[0])) - return AS2 (xor%B0,%0,%0); + + /* movb $0,reg8 is 2 bytes, the same as xorl reg8,reg8. */ if (operands[1] == const1_rtx + && TARGET_PENTIUM && ! NON_QI_REG_P (operands[0]) && (link = find_reg_note (insn, REG_WAS_0, 0)) /* Make sure the insn that stored the 0 is still present. */ @@ -1182,7 +1286,8 @@ (define_insn "movsf_push" [(set (match_operand:SF 0 "push_operand" "=<,<") (match_operand:SF 1 "general_operand" "*rfF,m"))] - "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed" + "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM + || reload_in_progress || reload_completed" "* { if (STACK_REG_P (operands[1])) @@ -1209,11 +1314,15 @@ return AS1 (push%L0,%1); }") -(define_insn "movsf_push_memory" - [(set (match_operand:SF 0 "push_operand" "=<") - (match_operand:SF 1 "memory_operand" "m"))] - "TARGET_PUSH_MEMORY" - "* return AS1 (push%L0,%1);") +(define_split + [(set (match_operand:SF 0 "push_operand" "") + (match_operand:SF 1 "general_operand" ""))] + "reload_completed && STACK_REG_P (operands[1])" + [(set (reg:SI 7) + (minus:SI (reg:SI 7) (const_int 4))) + (set (mem:SF (reg:SI 7)) + (match_dup 1))] + "") (define_expand "movsf" [(set (match_operand:SF 0 "general_operand" "") @@ -1223,7 +1332,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1231,34 +1340,21 @@ } /* If we are loading a floating point constant that isn't 0 or 1 - into a register, indicate we need the pic register loaded. This could - be optimized into stores of constants if the target eventually moves - to memory, but better safe than sorry. */ + into a register, force the value to memory now, since we'll + get better code out the back end. */ else if ((reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) != MEM - && GET_CODE (operands[1]) == CONST_DOUBLE - && !standard_80387_constant_p (operands[1])) + && GET_CODE (operands[0]) != MEM + && GET_CODE (operands[1]) == CONST_DOUBLE + && !standard_80387_constant_p (operands[1])) { - rtx insn, note, fp_const; - - fp_const = force_const_mem (SFmode, operands[1]); - if (flag_pic) - current_function_uses_pic_offset_table = 1; - - insn = emit_insn (gen_rtx_SET (SFmode, operands[0], fp_const)); - note = find_reg_note (insn, REG_EQUAL, NULL_RTX); - - if (note) - XEXP (note, 0) = operands[1]; - else - REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn)); + operands[1] = validize_mem (force_const_mem (SFmode, operands[1])); } }") ;; For the purposes of regclass, prefer FLOAT_REGS. (define_insn "" - [(set (match_operand:SF 0 "nonimmediate_operand" "=*rfm,*rf,f,!*rm") - (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))] + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r,!m") + (match_operand:SF 1 "general_operand" "fmG,f,*rmF,*rF"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "* { @@ -1274,20 +1370,6 @@ return AS1 (fld,%y0); } - /* Handle a transfer between the 387 and a 386 register */ - - if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } - /* Handle other kinds of writes from the 387 */ if (STACK_TOP_P (operands[1])) @@ -1327,10 +1409,12 @@ return AS1 (fxch,%0); }") + (define_insn "movdf_push" [(set (match_operand:DF 0 "push_operand" "=<,<") (match_operand:DF 1 "general_operand" "*rfF,o"))] - "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed" + "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM + || reload_in_progress || reload_completed" "* { if (STACK_REG_P (operands[1])) @@ -1357,11 +1441,15 @@ return output_move_double (operands); }") -(define_insn "movdf_push_memory" - [(set (match_operand:DF 0 "push_operand" "=<") - (match_operand:DF 1 "memory_operand" "o"))] - "TARGET_PUSH_MEMORY" - "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (DFmode),0,0);") +(define_split + [(set (match_operand:DF 0 "push_operand" "") + (match_operand:DF 1 "register_operand" ""))] + "reload_completed && STACK_REG_P (operands[1])" + [(set (reg:SI 7) + (minus:SI (reg:SI 7) (const_int 8))) + (set (mem:DF (reg:SI 7)) + (match_dup 1))] + "") (define_expand "movdf" [(set (match_operand:DF 0 "general_operand" "") @@ -1371,7 +1459,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1383,30 +1471,18 @@ optimized into stores of constants if the target eventually moves to memory, but better safe than sorry. */ else if ((reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) != MEM - && GET_CODE (operands[1]) == CONST_DOUBLE - && !standard_80387_constant_p (operands[1])) + && GET_CODE (operands[0]) != MEM + && GET_CODE (operands[1]) == CONST_DOUBLE + && !standard_80387_constant_p (operands[1])) { - rtx insn, note, fp_const; - - fp_const = force_const_mem (DFmode, operands[1]); - if (flag_pic) - current_function_uses_pic_offset_table = 1; - - insn = emit_insn (gen_rtx_SET (DFmode, operands[0], fp_const)); - note = find_reg_note (insn, REG_EQUAL, NULL_RTX); - - if (note) - XEXP (note, 0) = operands[1]; - else - REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn)); + operands[1] = validize_mem (force_const_mem (DFmode, operands[1])); } }") ;; For the purposes of regclass, prefer FLOAT_REGS. (define_insn "" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm") - (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r,!o") + (match_operand:DF 1 "general_operand" "fmG,f,*roF,*rF"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "* @@ -1423,20 +1499,6 @@ return AS1 (fld,%y0); } - /* Handle a transfer between the 387 and a 386 register */ - - if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } - /* Handle other kinds of writes from the 387 */ if (STACK_TOP_P (operands[1])) @@ -1480,7 +1542,8 @@ (define_insn "movxf_push" [(set (match_operand:XF 0 "push_operand" "=<,<") (match_operand:XF 1 "general_operand" "*rfF,o"))] - "GET_CODE (operands[1]) != MEM || reload_in_progress || reload_completed" + "TARGET_PUSH_MEMORY || GET_CODE (operands[1]) != MEM + || reload_in_progress || reload_completed" "* { if (STACK_REG_P (operands[1])) @@ -1506,11 +1569,15 @@ return output_move_double (operands); }") -(define_insn "movxf_push_memory" - [(set (match_operand:XF 0 "push_operand" "=<") - (match_operand:XF 1 "memory_operand" "o"))] - "TARGET_PUSH_MEMORY" - "* return output_move_pushmem (operands, insn, GET_MODE_SIZE (XFmode),0,0);") +(define_split + [(set (match_operand:XF 0 "push_operand" "") + (match_operand:XF 1 "register_operand" ""))] + "reload_completed && STACK_REG_P (operands[1])" + [(set (reg:SI 7) + (minus:SI (reg:SI 7) (const_int 12))) + (set (mem:XF (reg:SI 7)) + (match_dup 1))] + "") (define_expand "movxf" [(set (match_operand:XF 0 "general_operand" "") @@ -1520,7 +1587,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1532,30 +1599,18 @@ be optimized into stores of constants if the target eventually moves to memory, but better safe than sorry. */ else if ((reload_in_progress | reload_completed) == 0 - && GET_CODE (operands[0]) != MEM - && GET_CODE (operands[1]) == CONST_DOUBLE - && !standard_80387_constant_p (operands[1])) + && GET_CODE (operands[0]) != MEM + && GET_CODE (operands[1]) == CONST_DOUBLE + && !standard_80387_constant_p (operands[1])) { - rtx insn, note, fp_const; - - fp_const = force_const_mem (XFmode, operands[1]); - if (flag_pic) - current_function_uses_pic_offset_table = 1; - - insn = emit_insn (gen_rtx_SET (XFmode, operands[0], fp_const)); - note = find_reg_note (insn, REG_EQUAL, NULL_RTX); - - if (note) - XEXP (note, 0) = operands[1]; - else - REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, operands[1], REG_NOTES (insn)); + operands[1] = validize_mem (force_const_mem (XFmode, operands[1])); } }") (define_insn "" - [(set (match_operand:XF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm") - (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))] + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!*r,!o") + (match_operand:XF 1 "general_operand" "fmG,f,*roF,*rF"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "* @@ -1572,20 +1627,6 @@ return AS1 (fld,%y0); } - /* Handle a transfer between the 387 and a 386 register */ - - if (STACK_TOP_P (operands[0]) && NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } - - if (STACK_TOP_P (operands[1]) && NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } - /* Handle other kinds of writes from the 387 */ if (STACK_TOP_P (operands[1])) @@ -1644,7 +1685,7 @@ { /* Don't generate memory->memory moves, go through a register */ if (TARGET_MOVE - && (reload_in_progress | reload_completed) == 0 + && no_new_pseudos == 0 && GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) { @@ -1657,8 +1698,44 @@ (match_operand:DI 1 "general_operand" "riF,m"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" - "* return output_move_double (operands);") + "* return output_move_double (operands);" + [(set_attr "type" "integer,memory") + (set_attr "memory" "*,load")]) + +(define_split + [(set (match_operand:DI 0 "nonimmediate_operand" "") + (match_operand:DI 1 "general_operand" ""))] + "reload_completed + && (offsettable_memref_p (operands[0]) + || nonmemory_operand (operands[0], DImode)) + && (offsettable_memref_p (operands[1]) + || nonmemory_operand (operands[1], DImode)) + && (! reg_overlap_mentioned_p (gen_lowpart (SImode, operands[0]), + operands[1]) + || ! reg_overlap_mentioned_p (gen_highpart (SImode, operands[0]), + operands[1]))" + [(set (match_dup 2) + (match_dup 4)) + (set (match_dup 3) + (match_dup 5))] + " +{ + split_di (&operands[0], 1, &operands[2], &operands[3]); + split_di (&operands[1], 1, &operands[4], &operands[5]); + + if (reg_overlap_mentioned_p (operands[2], operands[1])) + { + rtx tmp; + tmp = operands[2]; + operands[2] = operands[3]; + operands[3] = tmp; + + tmp = operands[4]; + operands[4] = operands[5]; + operands[5] = tmp; + } +}") ;;- conversion instructions ;;- NONE @@ -1666,10 +1743,25 @@ ;;- zero extension instructions ;; See comments by `andsi' for when andl is faster than movzx. -(define_insn "zero_extendhisi2" +(define_expand "zero_extendhisi2" + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] + "" + "") + +;; When optimizing for the PPro/PII or code size, always use movzwl. +;; We want to use a different pattern so we can use different constraints +;; than the generic pattern. +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] + "(optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" + "* return AS2 (movz%W0%L0,%1,%0);") + +(define_insn "" [(set (match_operand:SI 0 "register_operand" "=r,&r,?r") (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))] - "" + "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" "* { rtx xops[2]; @@ -1730,10 +1822,23 @@ (const_int 65535)))] "operands[2] = gen_rtx_REG (HImode, true_regnum (operands[0]));") -(define_insn "zero_extendqihi2" +(define_expand "zero_extendqihi2" + [(set (match_operand:HI 0 "register_operand" "") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] + "" + "") + +(define_insn "" + [(set (match_operand:HI 0 "register_operand" "=r") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] + "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO" + + "* return AS2 (movz%B0%W0,%1,%0);") + +(define_insn "" [(set (match_operand:HI 0 "register_operand" "=q,&q,?r") (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))] - "" + "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" "* { rtx xops[2]; @@ -1811,10 +1916,22 @@ FAIL; operands[2] = gen_rtx_REG (HImode, REGNO (operands[1]));") -(define_insn "zero_extendqisi2" +(define_expand "zero_extendqisi2" + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] + "" + "") + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] + "optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO" + "* return AS2 (movz%B0%L0,%1,%0);") + +(define_insn "" [(set (match_operand:SI 0 "register_operand" "=q,&q,?r") (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))] - "" + "! (optimize_size || (int)ix86_cpu == (int)PROCESSOR_PENTIUMPRO)" "* { rtx xops[2]; @@ -1899,58 +2016,105 @@ "operands[2] = gen_rtx_REG (SImode, true_regnum (operands[1]));") (define_insn "zero_extendsidi2" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m") - (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o") + (zero_extend:DI (match_operand:SI 1 "general_operand" "0,rm,r")))] "" - "* - { - rtx high[2], low[2], xops[4]; - - if (REG_P (operands[0]) && REG_P (operands[1]) - && REGNO (operands[0]) == REGNO (operands[1])) - { - operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - return AS2 (xor%L0,%0,%0); - } - - split_di (operands, 1, low, high); - xops[0] = low[0]; - xops[1] = operands[1]; - xops[2] = high[0]; - xops[3] = const0_rtx; - - output_asm_insn (AS2 (mov%L0,%1,%0), xops); - if (GET_CODE (low[0]) == MEM) - output_asm_insn (AS2 (mov%L2,%3,%2), xops); - else - output_asm_insn (AS2 (xor%L2,%2,%2), xops); + "#") - RET; -}") +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (zero_extend:DI (match_operand:SI 1 "register_operand" "")))] + "reload_completed && true_regnum (operands[0]) == true_regnum (operands[1])" + [(set (match_dup 4) (const_int 0))] + "split_di (&operands[0], 1, &operands[3], &operands[4]);") + +(define_split + [(set (match_operand:DI 0 "nonimmediate_operand" "") + (zero_extend:DI (match_operand:SI 1 "general_operand" "")))] + "reload_completed" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 4) (const_int 0))] + "split_di (&operands[0], 1, &operands[3], &operands[4]);") ;;- sign extension instructions (define_insn "extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=A,?r,?Ar,*o") + (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,*r"))) + (clobber (match_scratch:SI 2 "=X,X,X,&r"))] "" - "* + "#") + +;; Extend to memory case when source register does die. +(define_split + [(set (match_operand:DI 0 "memory_operand" "") + (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) + (clobber (match_operand:SI 2 "register_operand" ""))] + "(flow2_completed + && dead_or_set_p (insn, operands[1]) + && !reg_mentioned_p (operands[1], operands[0]))" + [(set (match_dup 3) (match_dup 1)) + (set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31))) + (set (match_dup 4) (match_dup 1))] + "split_di (&operands[0], 1, &operands[3], &operands[4]);") + +;; Extend to memory case when source register does not die. +(define_split + [(set (match_operand:DI 0 "memory_operand" "") + (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) + (clobber (match_operand:SI 2 "register_operand" ""))] + "flow2_completed" + [(const_int 0)] + " { - if (REGNO (operands[0]) == 0) + split_di (&operands[0], 1, &operands[3], &operands[4]); + + emit_move_insn (operands[3], operands[1]); + + /* Generate a cltd if possible and doing so it profitable. */ + if (true_regnum (operands[1]) == 0 + && true_regnum (operands[2]) == 1 + && (optimize_size || !TARGET_PENTIUM)) { - /* This used to be cwtl, but that extends HI to SI somehow. */ -#ifdef INTEL_SYNTAX - return \"cdq\"; -#else - return \"cltd\"; -#endif + emit_insn (gen_ashrsi3_31 (operands[2], operands[1])); + } + else + { + emit_move_insn (operands[2], operands[1]); + emit_insn (gen_ashrsi3_31 (operands[2], operands[2])); } + emit_move_insn (operands[4], operands[2]); + DONE; +}") - operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); - output_asm_insn (AS2 (mov%L0,%0,%1), operands); +;; Extend to register case. Optimize case where source and destination +;; registers match and cases where we can use cltd. +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (sign_extend:DI (match_operand:SI 1 "register_operand" ""))) + (clobber (match_scratch:SI 2 ""))] + "reload_completed" + [(const_int 0)] + " +{ + split_di (&operands[0], 1, &operands[3], &operands[4]); - operands[0] = GEN_INT (31); - return AS2 (sar%L1,%0,%1); + if (true_regnum (operands[3]) != true_regnum (operands[1])) + emit_move_insn (operands[3], operands[1]); + + /* Generate a cltd if possible and doing so it profitable. */ + if (true_regnum (operands[3]) == 0 + && (optimize_size || !TARGET_PENTIUM)) + { + emit_insn (gen_ashrsi3_31 (operands[4], operands[3])); + DONE; + } + + if (true_regnum (operands[4]) != true_regnum (operands[1])) + emit_move_insn (operands[4], operands[1]); + + emit_insn (gen_ashrsi3_31 (operands[4], operands[4])); + DONE; }") ;; Note that the i386 programmers' manual says that the opcodes @@ -1964,7 +2128,8 @@ "* { if (REGNO (operands[0]) == 0 - && REG_P (operands[1]) && REGNO (operands[1]) == 0) + && REG_P (operands[1]) && REGNO (operands[1]) == 0 + && (optimize_size || ix86_cpu != PROCESSOR_K6)) #ifdef INTEL_SYNTAX return \"cwde\"; #else @@ -1985,7 +2150,8 @@ "* { if (REGNO (operands[0]) == 0 - && REG_P (operands[1]) && REGNO (operands[1]) == 0) + && REG_P (operands[1]) && REGNO (operands[1]) == 0 + && (optimize_size || ix86_cpu != PROCESSOR_K6)) return \"cbtw\"; #ifdef INTEL_SYNTAX @@ -2069,110 +2235,237 @@ ;; Conversions between float and double. -(define_insn "extendsfdf2" - [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f") - (float_extend:DF - (match_operand:SF 1 "nonimmediate_operand" "f,fm")))] +(define_expand "extendsfdf2" + [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") + (float_extend:DF + (match_operand:SF 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2)) + (clobber (match_dup 3))])] "TARGET_80387" + " +{ + if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) + operands[1] = force_reg (SFmode, operands[1]); + + operands[2] = assign_386_stack_local (SFmode, 0); + operands[3] = assign_386_stack_local (DFmode, 0); +}") + +(define_insn "" + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!f,!*r") + (float_extend:DF + (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f"))) + (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m")) + (clobber (match_operand:DF 3 "memory_operand" "m,m,m,o"))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" "* { - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop,fld,fpop")]) - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float_extend:DF (match_operand:SF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:DF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float_extend:DF (match_dup 2)))] + "") - if (NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float_extend:DF (match_operand:SF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:DF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" + [(set (match_dup 3) + (float_extend:DF (match_dup 1))) + (set (match_dup 0) + (match_dup 3))] + "") - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); +(define_split + [(set (match_operand:DF 0 "nonimmediate_operand" "") + (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:DF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_extend:DF (match_dup 1)))] + "") - if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%y0); - else - return AS1 (fst%z0,%y0); - } +(define_insn "" + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m") + (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" + "* +{ + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop")]) + +(define_expand "extenddfxf2" + [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "") + (float_extend:XF + (match_operand:DF 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2)) + (clobber (match_dup 3))])] + "TARGET_80387" + " +{ + if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) + operands[1] = force_reg (DFmode, operands[1]); - abort (); + operands[2] = assign_386_stack_local (DFmode, 0); + operands[3] = assign_386_stack_local (XFmode, 0); }") -(define_insn "extenddfxf2" - [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r") +(define_insn "" + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r") (float_extend:XF - (match_operand:DF 1 "nonimmediate_operand" "f,fm,!*r,f")))] - "TARGET_80387" + (match_operand:DF 1 "nonimmediate_operand" "fm,f,*r,f"))) + (clobber (match_operand:DF 2 "memory_operand" "m,m,o,m")) + (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" "* { - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop,fld,fpop")]) - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float_extend:XF (match_operand:DF 1 "register_operand" ""))) + (clobber (match_operand:DF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float_extend:XF (match_dup 2)))] + "") - if (NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float_extend:XF (match_operand:DF 1 "register_operand" ""))) + (clobber (match_operand:DF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" + [(set (match_dup 3) + (float_extend:XF (match_dup 1))) + (set (match_dup 0) + (match_dup 3))] + "") - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); +(define_split + [(set (match_operand:XF 0 "nonimmediate_operand" "") + (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" ""))) + (clobber (match_operand:DF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_extend:XF (match_dup 1)))] + "") - if (GET_CODE (operands[0]) == MEM) - { - output_asm_insn (AS1 (fstp%z0,%y0), operands); - if (! stack_top_dies) - return AS1 (fld%z0,%y0); - RET; - } +(define_insn "" + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") + (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" + "* +{ + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop")]) + +(define_expand "extendsfxf2" + [(parallel [(set (match_operand:XF 0 "nonimmediate_operand" "") + (float_extend:XF + (match_operand:SF 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2)) + (clobber (match_dup 3))])] + "TARGET_80387" + " +{ + if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) + operands[1] = force_reg (SFmode, operands[1]); - abort (); + operands[2] = assign_386_stack_local (SFmode, 0); + operands[3] = assign_386_stack_local (XFmode, 0); }") -(define_insn "extendsfxf2" - [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r") +(define_insn "" + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,!f,!*r") (float_extend:XF - (match_operand:SF 1 "nonimmediate_operand" "f,fm,!*r,f")))] - "TARGET_80387" + (match_operand:SF 1 "nonimmediate_operand" "fm,f,*r,f"))) + (clobber (match_operand:SF 2 "memory_operand" "m,m,m,m")) + (clobber (match_operand:XF 3 "memory_operand" "m,m,m,o"))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" "* { - int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fld%z0,%y1)); - RET; - } + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop,fld,fpop")]) - if (NON_STACK_REG_P (operands[0])) - { - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float_extend:XF (match_operand:SF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[1])" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float_extend:XF (match_dup 2)))] + "") - if (STACK_TOP_P (operands[0])) - return AS1 (fld%z1,%y1); +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float_extend:XF (match_operand:SF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed && NON_STACK_REG_P (operands[0])" + [(set (match_dup 3) + (float_extend:XF (match_dup 1))) + (set (match_dup 0) + (match_dup 3))] + "") - if (GET_CODE (operands[0]) == MEM) - { - output_asm_insn (AS1 (fstp%z0,%y0), operands); - if (! stack_top_dies) - return AS1 (fld%z0,%y0); - RET; - } +(define_split + [(set (match_operand:XF 0 "nonimmediate_operand" "") + (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" "")) + (clobber (match_operand:XF 3 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_extend:XF (match_dup 1)))] + "") - abort (); -}") +(define_insn "" + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m") + (float_extend:XF + (match_operand:SF 1 "nonimmediate_operand" "fm,f")))] + "TARGET_80387 && (GET_CODE (operands[0]) != MEM + || GET_CODE (operands[1]) != MEM)" + "* +{ + output_float_extend (insn, operands); + return \"\"; +}" + [(set_attr "type" "fld,fpop")]) (define_expand "truncdfsf2" [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") @@ -2185,480 +2478,764 @@ operands[2] = (rtx) assign_386_stack_local (SFmode, 0); }") -;; This cannot output into an f-reg because there is no way to be sure -;; of truncating in that case. Otherwise this is just like a simple move -;; insn. So we pretend we can output to a reg in order to get better -;; register preferencing, but we really use a stack slot. - (define_insn "" - [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m") + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r") (float_truncate:SF - (match_operand:DF 1 "register_operand" "0,f"))) - (clobber (match_operand:SF 2 "memory_operand" "m,m"))] + (match_operand:DF 1 "register_operand" "0,f,f"))) + (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))] "TARGET_80387" "* { int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + rtx xops[1]; - if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%0); - else - return AS1 (fst%z0,%0); - } - else if (STACK_TOP_P (operands[0])) - { - output_asm_insn (AS1 (fstp%z2,%y2), operands); - return AS1 (fld%z2,%y2); - } + xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; + + if (stack_top_dies || STACK_REG_P (operands[0])) + output_asm_insn (AS1 (fstp%z0,%0), xops); else - abort (); -}") + output_asm_insn (AS1 (fst%z0,%0), xops); -(define_insn "truncxfsf2" - [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r") - (float_truncate:SF - (match_operand:XF 1 "register_operand" "f,f")))] + if (STACK_REG_P (operands[0])) + return AS1 (fld%z2,%2); + else if (NON_STACK_REG_P (operands[0])) + return AS2 (mov%L0,%2,%0); + + return \"\"; +}" + [(set_attr "type" "fpop")]) + +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (float_truncate:SF (match_operand:DF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (float_truncate:SF (match_dup 1))) + (set (match_dup 0) + (match_dup 2))] + "") + +(define_split + [(set (match_operand:SF 0 "memory_operand" "") + (float_truncate:SF (match_operand:DF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_truncate:SF (match_dup 1)))] + "") + +;; This cannot output into an f-reg because there is no way to be sure +;; of truncating in that case. + +(define_insn "" + [(set (match_operand:SF 0 "memory_operand" "=m") + (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] "TARGET_80387" "* { int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; - if (NON_STACK_REG_P (operands[0])) - { - if (stack_top_dies == 0) - { - output_asm_insn (AS1 (fld,%y1), operands); - stack_top_dies = 1; - } - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } - else if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%0); - else - { - output_asm_insn (AS1 (fld,%y1), operands); - return AS1 (fstp%z0,%0); - } - } + if (stack_top_dies) + return AS1 (fstp%z0,%0); else - abort (); + return AS1 (fst%z0,%0); +}" + [(set_attr "type" "fpop")]) + +(define_expand "truncxfsf2" + [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "") + (float_truncate:SF + (match_operand:XF 1 "register_operand" ""))) + (clobber (match_dup 2))])] + "TARGET_80387" + " +{ + operands[2] = (rtx) assign_386_stack_local (SFmode, 0); }") -(define_insn "truncxfdf2" - [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r") - (float_truncate:DF - (match_operand:XF 1 "register_operand" "f,f")))] +(define_insn "" + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,m,!*r") + (float_truncate:SF + (match_operand:XF 1 "register_operand" "0,f,f"))) + (clobber (match_operand:SF 2 "memory_operand" "m,m,m"))] "TARGET_80387" "* { int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + rtx xops[1]; - if (NON_STACK_REG_P (operands[0])) - { - if (stack_top_dies == 0) - { - output_asm_insn (AS1 (fld,%y1), operands); - stack_top_dies = 1; - } - output_to_reg (operands[0], stack_top_dies, 0); - RET; - } - else if (GET_CODE (operands[0]) == MEM) - { - if (stack_top_dies) - return AS1 (fstp%z0,%0); - else - { - output_asm_insn (AS1 (fld,%y1), operands); - return AS1 (fstp%z0,%0); - } - } + xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; + + if (stack_top_dies || STACK_REG_P (operands[0])) + output_asm_insn (AS1 (fstp%z0,%0), xops); else - abort (); -}") + output_asm_insn (AS1 (fst%z0,%0), xops); - -;; The 387 requires that the stack top dies after converting to DImode. + if (STACK_REG_P (operands[0])) + return AS1 (fld%z2,%2); + else if (NON_STACK_REG_P (operands[0])) + return AS2 (mov%L0,%2,%0); -;; Represent an unsigned conversion from SImode to MODE_FLOAT by first -;; doing a signed conversion to DImode, and then taking just the low -;; part. + return \"\"; +}" + [(set_attr "type" "fpop")]) -(define_expand "fixuns_truncxfsi2" - [(set (match_dup 4) - (match_operand:XF 1 "register_operand" "")) - (parallel [(set (match_dup 2) - (fix:DI (fix:XF (match_dup 4)))) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_scratch:SI 7 ""))]) - (set (match_operand:SI 0 "general_operand" "") - (match_dup 3))] +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (float_truncate:SF (match_operand:XF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (float_truncate:SF (match_dup 1))) + (set (match_dup 0) + (match_dup 2))] + "") + +(define_split + [(set (match_operand:SF 0 "memory_operand" "") + (float_truncate:SF (match_operand:XF 1 "register_operand" ""))) + (clobber (match_operand:SF 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_truncate:SF (match_dup 1)))] + "") + +(define_insn "" + [(set (match_operand:SF 0 "memory_operand" "=m") + (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))] "TARGET_80387" - " + "* { - operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_lowpart (SImode, operands[2]); - operands[4] = gen_reg_rtx (XFmode); - operands[5] = (rtx) assign_386_stack_local (SImode, 0); - operands[6] = (rtx) assign_386_stack_local (DImode, 1); -}") + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; -(define_expand "fixuns_truncdfsi2" - [(set (match_dup 4) - (match_operand:DF 1 "register_operand" "")) - (parallel [(set (match_dup 2) - (fix:DI (fix:DF (match_dup 4)))) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_scratch:SI 7 ""))]) - (set (match_operand:SI 0 "general_operand" "") - (match_dup 3))] + if (stack_top_dies) + return AS1 (fstp%z0,%0); + else + return AS1 (fst%z0,%0); +}" + [(set_attr "type" "fpop")]) + +(define_expand "truncxfdf2" + [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "") + (float_truncate:DF + (match_operand:XF 1 "register_operand" ""))) + (clobber (match_dup 2))])] "TARGET_80387" " { - operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_lowpart (SImode, operands[2]); - operands[4] = gen_reg_rtx (DFmode); - operands[5] = (rtx) assign_386_stack_local (SImode, 0); - operands[6] = (rtx) assign_386_stack_local (DImode, 1); + operands[2] = (rtx) assign_386_stack_local (DFmode, 0); }") -(define_expand "fixuns_truncsfsi2" - [(set (match_dup 4) - (match_operand:SF 1 "register_operand" "")) - (parallel [(set (match_dup 2) - (fix:DI (fix:SF (match_dup 4)))) - (clobber (match_dup 4)) - (clobber (match_dup 5)) - (clobber (match_dup 6)) - (clobber (match_scratch:SI 7 ""))]) - (set (match_operand:SI 0 "general_operand" "") - (match_dup 3))] +(define_insn "" + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,!*r") + (float_truncate:DF + (match_operand:XF 1 "register_operand" "0,f,f"))) + (clobber (match_operand:DF 2 "memory_operand" "m,m,o"))] "TARGET_80387" - " + "* { - operands[2] = gen_reg_rtx (DImode); - operands[3] = gen_lowpart (SImode, operands[2]); - operands[4] = gen_reg_rtx (SFmode); - operands[5] = (rtx) assign_386_stack_local (SImode, 0); - operands[6] = (rtx) assign_386_stack_local (DImode, 1); -}") + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; + rtx xops[2]; -;; Signed conversion to DImode. + xops[0] = GET_CODE (operands[0]) == MEM ? operands[0] : operands[2]; -(define_expand "fix_truncxfdi2" + if (stack_top_dies || STACK_REG_P (operands[0])) + output_asm_insn (AS1 (fstp%z0,%0), xops); + else + output_asm_insn (AS1 (fst%z0,%0), xops); + + if (STACK_REG_P (operands[0])) + return AS1 (fld%z2,%2); + else if (NON_STACK_REG_P (operands[0])) + { + xops[0] = operands[0]; + xops[1] = operands[2]; + output_asm_insn (output_move_double (xops), xops); + } + + return \"\"; +}" + [(set_attr "type" "fpop")]) + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float_truncate:DF (match_operand:XF 1 "register_operand" ""))) + (clobber (match_operand:DF 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" [(set (match_dup 2) - (match_operand:XF 1 "register_operand" "")) - (parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:XF (match_dup 2)))) - (clobber (match_dup 2)) - (clobber (match_dup 3)) - (clobber (match_dup 4)) - (clobber (match_scratch:SI 5 ""))])] + (float_truncate:DF (match_dup 1))) + (set (match_dup 0) + (match_dup 2))] + "") + +(define_split + [(set (match_operand:DF 0 "memory_operand" "") + (float_truncate:DF (match_operand:XF 1 "register_operand" ""))) + (clobber (match_operand:DF 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float_truncate:DF (match_dup 1)))] + "") + +(define_insn "" + [(set (match_operand:DF 0 "memory_operand" "=m") + (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))] "TARGET_80387" - " + "* { - operands[1] = copy_to_mode_reg (XFmode, operands[1]); - operands[2] = gen_reg_rtx (XFmode); - operands[3] = (rtx) assign_386_stack_local (SImode, 0); - operands[4] = (rtx) assign_386_stack_local (DImode, 1); -}") + int stack_top_dies = find_regno_note (insn, REG_DEAD, FIRST_STACK_REG) != 0; -(define_expand "fix_truncdfdi2" - [(set (match_dup 2) - (match_operand:DF 1 "register_operand" "")) - (parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:DF (match_dup 2)))) + if (stack_top_dies) + return AS1 (fstp%z0,%0); + else + return AS1 (fst%z0,%0); +}" + [(set_attr "type" "fpop")]) + +;; Conversions between floating point and fix point. + +(define_expand "fix_truncsfsi2" + [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") + (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "")))) (clobber (match_dup 2)) (clobber (match_dup 3)) (clobber (match_dup 4)) - (clobber (match_scratch:SI 5 ""))])] + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" " { - operands[1] = copy_to_mode_reg (DFmode, operands[1]); - operands[2] = gen_reg_rtx (DFmode); - operands[3] = (rtx) assign_386_stack_local (SImode, 0); - operands[4] = (rtx) assign_386_stack_local (DImode, 1); + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (SImode, 0); }") +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r") + (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f,f")))) + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:SI 4 "memory_operand" "m,m")) + (clobber (match_scratch:HI 5 "=&r,&r"))] + "TARGET_80387" + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) + (define_expand "fix_truncsfdi2" - [(set (match_dup 2) - (match_operand:SF 1 "register_operand" "")) - (parallel [(set (match_operand:DI 0 "general_operand" "") - (fix:DI (fix:SF (match_dup 2)))) + [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") + (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "")))) + (clobber (match_dup 1)) (clobber (match_dup 2)) (clobber (match_dup 3)) (clobber (match_dup 4)) - (clobber (match_scratch:SI 5 ""))])] + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" " { operands[1] = copy_to_mode_reg (SFmode, operands[1]); - operands[2] = gen_reg_rtx (SFmode); - operands[3] = (rtx) assign_386_stack_local (SImode, 0); - operands[4] = (rtx) assign_386_stack_local (DImode, 1); + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (DImode, 0); }") -;; These match a signed conversion of either DFmode or SFmode to DImode. - (define_insn "" - [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") - (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "+f")))) + [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r") + (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f,f")))) (clobber (match_dup 1)) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:DI 4 "memory_operand" "m,o")) + (clobber (match_scratch:HI 5 "=&r,&r"))] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) -(define_insn "" - [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") - (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "+f")))) - (clobber (match_dup 1)) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] +(define_expand "fix_truncdfsi2" + [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") + (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "")))) + (clobber (match_dup 2)) + (clobber (match_dup 3)) + (clobber (match_dup 4)) + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") + " +{ + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (SImode, 0); +}") (define_insn "" - [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") - (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "+f")))) - (clobber (match_dup 1)) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r") + (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f,f")))) + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:SI 4 "memory_operand" "m,m")) + (clobber (match_scratch:HI 5 "=&r,&r"))] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") - -;; Signed MODE_FLOAT conversion to SImode. + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) -(define_expand "fix_truncxfsi2" - [(parallel [(set (match_operand:SI 0 "general_operand" "") - (fix:SI - (fix:XF (match_operand:XF 1 "register_operand" "")))) +(define_expand "fix_truncdfdi2" + [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") + (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "")))) + (clobber (match_dup 1)) (clobber (match_dup 2)) (clobber (match_dup 3)) - (clobber (match_scratch:SI 4 ""))])] + (clobber (match_dup 4)) + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" " { - operands[2] = (rtx) assign_386_stack_local (SImode, 0); - operands[3] = (rtx) assign_386_stack_local (DImode, 1); + operands[1] = copy_to_mode_reg (DFmode, operands[1]); + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (DImode, 0); }") -(define_expand "fix_truncdfsi2" - [(parallel [(set (match_operand:SI 0 "general_operand" "") - (fix:SI - (fix:DF (match_operand:DF 1 "register_operand" "")))) +(define_insn "" + [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r") + (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f,f")))) + (clobber (match_dup 1)) + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:DI 4 "memory_operand" "m,o")) + (clobber (match_scratch:HI 5 "=&r,&r"))] + "TARGET_80387" + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) + +(define_expand "fix_truncxfsi2" + [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "") + (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "")))) (clobber (match_dup 2)) (clobber (match_dup 3)) - (clobber (match_scratch:SI 4 ""))])] + (clobber (match_dup 4)) + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" " { - operands[2] = (rtx) assign_386_stack_local (SImode, 0); - operands[3] = (rtx) assign_386_stack_local (DImode, 1); + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (SImode, 0); }") -(define_expand "fix_truncsfsi2" - [(parallel [(set (match_operand:SI 0 "general_operand" "") - (fix:SI - (fix:SF (match_operand:SF 1 "register_operand" "")))) +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=m,!r") + (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f,f")))) + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:SI 4 "memory_operand" "m,m")) + (clobber (match_scratch:HI 5 "=&r,&r"))] + "TARGET_80387" + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) + +(define_expand "fix_truncxfdi2" + [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "") + (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "")))) + (clobber (match_dup 1)) (clobber (match_dup 2)) (clobber (match_dup 3)) - (clobber (match_scratch:SI 4 ""))])] + (clobber (match_dup 4)) + (clobber (match_scratch:HI 5 ""))])] "TARGET_80387" " { - operands[2] = (rtx) assign_386_stack_local (SImode, 0); - operands[3] = (rtx) assign_386_stack_local (DImode, 1); + operands[1] = copy_to_mode_reg (XFmode, operands[1]); + operands[2] = (rtx) assign_386_stack_local (HImode, 0); + operands[3] = (rtx) assign_386_stack_local (HImode, 1); + operands[4] = (rtx) assign_386_stack_local (DImode, 0); }") (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") - (fix:SI (fix:XF (match_operand:XF 1 "register_operand" "f")))) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=m,!r") + (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f,f")))) + (clobber (match_dup 1)) + (clobber (match_operand:HI 2 "memory_operand" "m,m")) + (clobber (match_operand:HI 3 "memory_operand" "m,m")) + (clobber (match_operand:DI 4 "memory_operand" "m,o")) + (clobber (match_scratch:HI 5 "=&r,&r"))] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") + "* return output_fix_trunc (insn, operands);" + [(set_attr "type" "fpop")]) + +;; Conversion between fixed point and floating point. -(define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") - (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f")))) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] +;; ??? Possibly represent floatunssidf2 here in gcc2. + +(define_expand "floatsisf2" + [(parallel [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:SI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") + "operands[2] = assign_386_stack_local (SImode, 0);") (define_insn "" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") - (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f")))) - (clobber (match_operand:SI 2 "memory_operand" "m")) - (clobber (match_operand:DI 3 "memory_operand" "m")) - (clobber (match_scratch:SI 4 "=&q"))] + [(set (match_operand:SF 0 "register_operand" "=f,f") + (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:SI 2 "memory_operand" "m,m"))] "TARGET_80387" - "* return output_fix_trunc (insn, operands);") - -;; Conversion between fixed point and floating point. -;; The actual pattern that matches these is at the end of this file. + "#") -;; ??? Possibly represent floatunssidf2 here in gcc2. +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:SI 1 "memory_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:SF (match_dup 1)))] + "") -(define_expand "floatsisf2" +(define_split [(set (match_operand:SF 0 "register_operand" "") - (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] + (float:SF (match_operand:SI 1 "register_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:SF (match_dup 2)))] + "") + +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f") + (float:SF (match_operand:SI 1 "memory_operand" "m")))] + "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + +(define_expand "floathisf2" + [(parallel [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:HI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] "TARGET_80387" + "operands[2] = assign_386_stack_local (HImode, 0);") + +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f,f") + (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:HI 2 "memory_operand" "m,m"))] + "TARGET_80387" + "#") + +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:HI 1 "memory_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:SF (match_dup 1)))] "") -(define_expand "floatdisf2" +(define_split [(set (match_operand:SF 0 "register_operand" "") - (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))] + (float:SF (match_operand:HI 1 "register_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:SF (match_dup 2)))] + "") + +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f") + (float:SF (match_operand:HI 1 "memory_operand" "m")))] + "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + +(define_expand "floatdisf2" + [(parallel [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:DI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] "TARGET_80387" + "operands[2] = assign_386_stack_local (DImode, 0);") + +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f,f") + (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:DI 2 "memory_operand" "m,o"))] + "TARGET_80387" + "#") + +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:DI 1 "memory_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:SF (match_dup 1)))] + "") + +(define_split + [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:DI 1 "register_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:SF (match_dup 2)))] "") +(define_insn "" + [(set (match_operand:SF 0 "register_operand" "=f") + (float:SF (match_operand:DI 1 "memory_operand" "m")))] + "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + (define_expand "floatsidf2" + [(parallel [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] + "TARGET_80387" + "operands[2] = assign_386_stack_local (SImode, 0);") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f,f") + (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:SI 2 "memory_operand" "m,m"))] + "TARGET_80387" + "#") + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:SI 1 "memory_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:DF (match_dup 1)))] + "") + +(define_split [(set (match_operand:DF 0 "register_operand" "") - (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))] + (float:DF (match_operand:SI 1 "register_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:DF (match_dup 2)))] + "") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f") + (float:DF (match_operand:SI 1 "memory_operand" "m")))] + "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + +(define_expand "floathidf2" + [(parallel [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:HI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] + "TARGET_80387" + "operands[2] = assign_386_stack_local (HImode, 0);") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f,f") + (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:HI 2 "memory_operand" "m,m"))] "TARGET_80387" + "#") + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:HI 1 "memory_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:DF (match_dup 1)))] "") -(define_expand "floatdidf2" +(define_split [(set (match_operand:DF 0 "register_operand" "") - (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))] + (float:DF (match_operand:HI 1 "register_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:DF (match_dup 2)))] + "") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f") + (float:DF (match_operand:HI 1 "memory_operand" "m")))] + "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + +(define_expand "floatdidf2" + [(parallel [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:DI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] + "TARGET_80387" + "operands[2] = assign_386_stack_local (DImode, 0);") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f,f") + (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:DI 2 "memory_operand" "m,o"))] "TARGET_80387" + "#") + +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:DI 1 "memory_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:DF (match_dup 1)))] "") +(define_split + [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:DI 1 "register_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:DF (match_dup 2)))] + "") + +(define_insn "" + [(set (match_operand:DF 0 "register_operand" "=f") + (float:DF (match_operand:DI 1 "memory_operand" "m")))] + "TARGET_80387" + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + (define_expand "floatsixf2" - [(set (match_operand:XF 0 "register_operand" "") - (float:XF (match_operand:SI 1 "nonimmediate_operand" "")))] + [(parallel [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:SI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] "TARGET_80387" - "") + "operands[2] = assign_386_stack_local (SImode, 0);") -(define_expand "floatdixf2" +(define_insn "" + [(set (match_operand:XF 0 "register_operand" "=f,f") + (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:SI 2 "memory_operand" "m,m"))] + "TARGET_80387" + "#") + +(define_split [(set (match_operand:XF 0 "register_operand" "") - (float:XF (match_operand:DI 1 "nonimmediate_operand" "")))] - "TARGET_80387 && LONG_DOUBLE_TYPE_SIZE == 96" + (float:XF (match_operand:SI 1 "memory_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:XF (match_dup 1)))] "") -;; This will convert from SImode or DImode to MODE_FLOAT. +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:SI 1 "register_operand" ""))) + (clobber (match_operand:SI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:XF (match_dup 2)))] + "") (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f") - (float:XF (match_operand:DI 1 "nonimmediate_operand" "rm")))] + (float:XF (match_operand:SI 1 "memory_operand" "m")))] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) -(define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:DI 1 "nonimmediate_operand" "rm")))] +(define_expand "floathixf2" + [(parallel [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:HI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "operands[2] = assign_386_stack_local (HImode, 0);") (define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:DI 1 "nonimmediate_operand" "rm")))] + [(set (match_operand:XF 0 "register_operand" "=f,f") + (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:HI 2 "memory_operand" "m,m"))] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "#") + +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:HI 1 "memory_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:XF (match_dup 1)))] + "") + +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:HI 1 "register_operand" ""))) + (clobber (match_operand:HI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:XF (match_dup 2)))] + "") (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")))] + [(set (match_operand:XF 0 "register_operand" "=f") + (float:XF (match_operand:HI 1 "memory_operand" "m")))] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) + +(define_expand "floatdixf2" + [(parallel [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:DI 1 "nonimmediate_operand" ""))) + (clobber (match_dup 2))])] + "TARGET_80387" + "operands[2] = assign_386_stack_local (DImode, 0);") (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f,f") - (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!*r")))] + (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,!r"))) + (clobber (match_operand:DI 2 "memory_operand" "m,o"))] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "#") + +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:DI 1 "memory_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 0) + (float:XF (match_dup 1)))] + "") + +(define_split + [(set (match_operand:XF 0 "register_operand" "") + (float:XF (match_operand:DI 1 "register_operand" ""))) + (clobber (match_operand:DI 2 "memory_operand" ""))] + "TARGET_80387 && reload_completed" + [(set (match_dup 2) + (match_dup 1)) + (set (match_dup 0) + (float:XF (match_dup 2)))] + "") (define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")))] + [(set (match_operand:XF 0 "register_operand" "=f") + (float:XF (match_operand:DI 1 "memory_operand" "m")))] "TARGET_80387" - "* -{ - if (NON_STACK_REG_P (operands[1])) - { - output_op_from_reg (operands[1], AS1 (fild%z0,%1)); - RET; - } - else if (GET_CODE (operands[1]) == MEM) - return AS1 (fild%z1,%1); - else - abort (); -}") + "* return AS1 (fild%z1,%1);" + [(set_attr "type" "fpop")]) ;;- add instructions -(define_insn "addsidi3_1" +(define_insn "*addsidi3_1" [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,!&r,!r,o,!o") (plus:DI (match_operand:DI 1 "general_operand" "0,0,0,o,riF,riF,o") (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,roi,roi,ri,ri")))) @@ -2666,7 +3243,7 @@ "" "* { - rtx low[3], high[3], xops[7], temp; + rtx low[3], high[3], xops[7]; CC_STATUS_INIT; @@ -2703,8 +3280,11 @@ output_asm_insn (AS2 (add%L0,%2,%0), low); output_asm_insn (AS2 (adc%L0,%2,%0), high); + cc_status.value1 = high[0]; + cc_status.flags = CC_NO_OVERFLOW; RET; -}") +}" + [(set_attr "type" "binary")]) (define_insn "addsidi3_2" [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,!&r,&r,o,o,!o") @@ -2714,7 +3294,7 @@ "" "* { - rtx low[3], high[3], xops[7], temp; + rtx low[3], high[3], xops[7]; CC_STATUS_INIT; @@ -2781,8 +3361,11 @@ output_asm_insn (AS2 (add%L0,%2,%0), low); output_asm_insn (AS2 (adc%L0,%2,%0), high); + cc_status.value1 = high[0]; + cc_status.flags = CC_NO_OVERFLOW; RET; -}") +}" + [(set_attr "type" "binary")]) (define_insn "adddi3" [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") @@ -2831,6 +3414,9 @@ } } + cc_status.value1 = high[0]; + cc_status.flags = CC_NO_OVERFLOW; + if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG) { xops[0] = high[0]; @@ -2855,7 +3441,8 @@ output_asm_insn (AS2 (add%L0,%2,%0), high); RET; -}") +}" + [(set_attr "type" "binary")]) ;; On a 486, it is faster to do movl/addl than to do a single leal if ;; operands[1] and operands[2] are both registers. @@ -2875,7 +3462,7 @@ "* { if (REG_P (operands[0]) && REG_P (operands[1]) - && (REG_P (operands[2]) || GET_CODE (operands[2]) == CONST_INT) + && (REG_P (operands[2]) || CONSTANT_P (operands[2])) && REGNO (operands[0]) != REGNO (operands[1])) { if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2])) @@ -2920,7 +3507,8 @@ } return AS2 (add%L0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) ;; addsi3 is faster, so put this after. @@ -2949,7 +3537,8 @@ CC_STATUS_INIT; return AS2 (lea%L0,%a1,%0); -}") +}" + [(set_attr "type" "lea")]) ;; ??? `lea' here, for three operand add? If leaw is used, only %bx, ;; %si and %di can appear in SET_SRC, and output_asm_insn might not be @@ -2963,12 +3552,30 @@ "IX86_EXPAND_BINARY_OPERATOR (PLUS, HImode, operands);") (define_insn "" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") - (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") - (match_operand:HI 2 "general_operand" "ri,rm")))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,?r") + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r") + (match_operand:HI 2 "general_operand" "ri,rm,ri")))] "ix86_binary_operator_ok (PLUS, HImode, operands)" "* { + if (REG_P (operands[0]) && REG_P (operands[1]) + && (REG_P (operands[2]) || CONSTANT_P (operands[2])) + && REGNO (operands[0]) != REGNO (operands[1])) + { + if (operands[2] == stack_pointer_rtx) + abort (); + + CC_STATUS_INIT; + operands[1] + = gen_rtx_PLUS (SImode, + gen_rtx_REG (SImode, REGNO (operands[1])), + (! REG_P (operands[2]) + ? operands[2] + : gen_rtx_REG (SImode, REGNO (operands[2])))); + operands[0] = gen_rtx_REG (SImode, REGNO (operands[0])); + return AS2 (lea%L0,%a1,%0); + } + /* ??? what about offsettable memory references? */ if (!TARGET_PENTIUMPRO /* partial stalls are just too painful to risk. */ && QI_REG_P (operands[0]) @@ -3019,7 +3626,8 @@ return AS1 (dec%W0,%0); return AS2 (add%W0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_expand "addqi3" [(set (match_operand:QI 0 "general_operand" "") @@ -3029,12 +3637,31 @@ "IX86_EXPAND_BINARY_OPERATOR (PLUS, QImode, operands);") (define_insn "" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") - (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qn,qmn")))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,?q") + (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q") + (match_operand:QI 2 "general_operand" "qn,qmn,qn")))] "ix86_binary_operator_ok (PLUS, QImode, operands)" "* { + if (REG_P (operands[0]) && REG_P (operands[1]) + && (REG_P (operands[2]) || CONSTANT_P (operands[2])) + && (REGNO (operands[0]) != REGNO (operands[1]) + || NON_QI_REG_P (operands[1]) + || (REG_P (operands[2]) && NON_QI_REG_P (operands[2])))) + { + if (operands[2] == stack_pointer_rtx) + abort (); + + CC_STATUS_INIT; + operands[1] + = gen_rtx_PLUS (SImode, + gen_rtx_REG (SImode, REGNO (operands[1])), + (! REG_P (operands[2]) + ? operands[2] + : gen_rtx_REG (SImode, REGNO (operands[2])))); + operands[0] = gen_rtx_REG (SImode, REGNO (operands[0])); + return AS2 (lea%L0,%a1,%0); + } if (operands[2] == const1_rtx) return AS1 (inc%B0,%0); @@ -3044,7 +3671,8 @@ return AS1 (dec%B0,%0); return AS2 (add%B0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) ;Lennart Augustsson <augustss@cs.chalmers.se> ;says this pattern just makes slower code: @@ -3141,8 +3769,12 @@ output_asm_insn (AS2 (sub%L0,%2,%0), low); output_asm_insn (AS2 (sbb%L0,%2,%0), high); + cc_status.value1 = high[0]; + cc_status.flags = CC_NO_OVERFLOW; + RET; -}") +}" + [(set_attr "type" "binary")]) (define_insn "subdi3" [(set (match_operand:DI 0 "general_operand" "=&r,&ro,o,o,!&r,!o") @@ -3185,6 +3817,9 @@ } } + cc_status.value1 = high[0]; + cc_status.flags = CC_NO_OVERFLOW; + if (GET_CODE (operands[3]) == REG) { xops[0] = high[0]; @@ -3206,10 +3841,12 @@ } else - output_asm_insn (AS2 (sub%L0,%2,%0), high); + output_asm_insn (AS2 (sub%L0,%2,%0), high); + RET; -}") +}" + [(set_attr "type" "binary")]) (define_expand "subsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "") @@ -3223,7 +3860,8 @@ (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") (match_operand:SI 2 "general_operand" "ri,rm")))] "ix86_binary_operator_ok (MINUS, SImode, operands)" - "* return AS2 (sub%L0,%2,%0);") + "* return AS2 (sub%L0,%2,%0);" + [(set_attr "type" "binary")]) (define_expand "subhi3" [(set (match_operand:HI 0 "general_operand" "") @@ -3248,7 +3886,8 @@ return AS2 (sub%L0,%k2,%k0); } return AS2 (sub%W0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_expand "subqi3" [(set (match_operand:QI 0 "general_operand" "") @@ -3262,7 +3901,8 @@ (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") (match_operand:QI 2 "general_operand" "qn,qmn")))] "ix86_binary_operator_ok (MINUS, QImode, operands)" - "* return AS2 (sub%B0,%2,%0);") + "* return AS2 (sub%B0,%2,%0);" + [(set_attr "type" "binary")]) ;; The patterns that match these are at the end of this file. @@ -3688,7 +4328,8 @@ word_zero_and_operation: } return AS2 (and%L0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "andhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") @@ -3766,14 +4407,16 @@ word_zero_and_operation: } return AS2 (and%W0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "andqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") (match_operand:QI 2 "general_operand" "qn,qmn")))] "" - "* return AS2 (and%B0,%2,%0);") + "* return AS2 (and%B0,%2,%0);" + [(set_attr "type" "binary")]) /* I am nervous about these two.. add them later.. ;I presume this means that we have something in say op0= eax which is small @@ -3889,7 +4532,8 @@ byte_or_operation: } return AS2 (or%L0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "iorhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") @@ -3973,14 +4617,16 @@ byte_or_operation: } return AS2 (or%W0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "iorqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") (match_operand:QI 2 "general_operand" "qn,qmn")))] "" - "* return AS2 (or%B0,%2,%0);") + "* return AS2 (or%B0,%2,%0);" + [(set_attr "type" "binary")]) ;;- xor instructions @@ -4016,7 +4662,10 @@ byte_or_operation: byte_xor_operation: CC_STATUS_INIT; - if (intval == 0xff) + if (intval == 0xff + && (!TARGET_PENTIUM || optimize_size + || (GET_CODE (operands[0]) == MEM + && memory_address_info (XEXP (operands[0], 0), 1)))) return AS1 (not%B0,%b0); if (intval != INTVAL (operands[2])) @@ -4032,7 +4681,10 @@ byte_xor_operation: if (REG_P (operands[0])) { CC_STATUS_INIT; - if (intval == 0xff) + if (intval == 0xff + && (!TARGET_PENTIUM || optimize_size + || (GET_CODE (operands[0]) == MEM + && memory_address_info (XEXP (operands[0], 0), 1)))) return AS1 (not%B0,%h0); operands[2] = GEN_INT (intval); @@ -4068,7 +4720,8 @@ byte_xor_operation: } return AS2 (xor%L0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "xorhi3" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") @@ -4088,7 +4741,10 @@ byte_xor_operation: if (INTVAL (operands[2]) & 0xffff0000) operands[2] = GEN_INT (INTVAL (operands[2]) & 0xffff); - if (INTVAL (operands[2]) == 0xff) + if (INTVAL (operands[2]) == 0xff + && (!TARGET_PENTIUM || optimize_size + || (GET_CODE (operands[0]) == MEM + && memory_address_info (XEXP (operands[0], 0), 1)))) return AS1 (not%B0,%b0); return AS2 (xor%B0,%2,%b0); @@ -4102,7 +4758,10 @@ byte_xor_operation: CC_STATUS_INIT; operands[2] = GEN_INT ((INTVAL (operands[2]) >> 8) & 0xff); - if (INTVAL (operands[2]) == 0xff) + if (INTVAL (operands[2]) == 0xff + && (!TARGET_PENTIUM || optimize_size + || (GET_CODE (operands[0]) == MEM + && memory_address_info (XEXP (operands[0], 0), 1)))) return AS1 (not%B0,%h0); return AS2 (xor%B0,%2,%h0); @@ -4129,115 +4788,55 @@ byte_xor_operation: } return AS2 (xor%W0,%2,%0); -}") +}" + [(set_attr "type" "binary")]) (define_insn "xorqi3" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0") (match_operand:QI 2 "general_operand" "qn,qm")))] "" - "* return AS2 (xor%B0,%2,%0);") + "* return AS2 (xor%B0,%2,%0);" + [(set_attr "type" "binary")]) ;; logical operations for DImode - (define_insn "anddi3" - [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") - (and:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o") - (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o"))) - (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))] + [(set (match_operand:DI 0 "general_operand" "=&r,&ro") + (and:DI (match_operand:DI 1 "general_operand" "%0,0") + (match_operand:DI 2 "general_operand" "oriF,riF")))] "" - "#") + "#" + [(set_attr "type" "binary")]) + (define_insn "iordi3" - [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") - (ior:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o") - (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o"))) - (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))] + [(set (match_operand:DI 0 "general_operand" "=&r,&ro") + (ior:DI (match_operand:DI 1 "general_operand" "%0,0") + (match_operand:DI 2 "general_operand" "oriF,riF")))] "" - "#") - + "#" + [(set_attr "type" "binary")]) + (define_insn "xordi3" - [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") - (xor:DI (match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o") - (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o"))) - (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))] + [(set (match_operand:DI 0 "general_operand" "=&r,&ro") + (xor:DI (match_operand:DI 1 "general_operand" "%0,0") + (match_operand:DI 2 "general_operand" "oriF,riF")))] "" - "#") + "#" + [(set_attr "type" "binary")]) (define_split - [(set (match_operand:DI 0 "general_operand" "=&r,&ro,!r,o,!&r,!o,!o") - (match_operator:DI 4 "ix86_logical_operator" - [(match_operand:DI 1 "general_operand" "%0,0,0,0iF,or,riF,o") - (match_operand:DI 2 "general_operand" "o,riF,0,or,or,oriF,o")])) - (clobber (match_scratch:SI 3 "=X,X,X,&r,X,&r,&r"))] - "reload_completed" - [(const_int 0)] - " -{ - rtx low[3], high[3], xops[7], temp; - rtx (*genfunc)() = (GET_CODE (operands[4]) == AND ? gen_andsi3 - : GET_CODE (operands[4]) == IOR ? gen_iorsi3 - : GET_CODE (operands[4]) == XOR ? gen_xorsi3 - : 0); - - if (rtx_equal_p (operands[0], operands[2])) - { - temp = operands[1]; - operands[1] = operands[2]; - operands[2] = temp; - } - - split_di (operands, 3, low, high); - if (!rtx_equal_p (operands[0], operands[1])) - { - xops[0] = high[0]; - xops[1] = low[0]; - xops[2] = high[1]; - xops[3] = low[1]; - - if (GET_CODE (operands[0]) != MEM) - { - emit_insn (gen_movsi (xops[1], xops[3])); - emit_insn (gen_movsi (xops[0], xops[2])); - } - else - { - xops[4] = high[2]; - xops[5] = low[2]; - xops[6] = operands[3]; - emit_insn (gen_movsi (xops[6], xops[3])); - emit_insn ((*genfunc) (xops[6], xops[6], xops[5])); - emit_insn (gen_movsi (xops[1], xops[6])); - emit_insn (gen_movsi (xops[6], xops[2])); - emit_insn ((*genfunc) (xops[6], xops[6], xops[4])); - emit_insn (gen_movsi (xops[0], xops[6])); - DONE; - } - } - - if (GET_CODE (operands[3]) == REG && GET_CODE (operands[2]) != REG) - { - xops[0] = high[0]; - xops[1] = low[0]; - xops[2] = high[2]; - xops[3] = low[2]; - xops[4] = operands[3]; - - emit_insn (gen_movsi (xops[4], xops[3])); - emit_insn ((*genfunc) (xops[1], xops[1], xops[4])); - emit_insn (gen_movsi (xops[4], xops[2])); - emit_insn ((*genfunc) (xops[0], xops[0], xops[4])); - } - - else - { - emit_insn ((*genfunc) (low[0], low[0], low[2])); - emit_insn ((*genfunc) (high[0], high[0], high[2])); - } - - DONE; -}") + [(set (match_operand:DI 0 "general_operand" "") + (match_operator:DI 3 "ix86_logical_operator" + [(match_operand:DI 1 "general_operand" "") + (match_operand:DI 2 "general_operand" "")]))] + "" + [(set (match_dup 4) (match_op_dup:SI 3 [(match_dup 6) (match_dup 8)])) + (set (match_dup 5) (match_op_dup:SI 3 [(match_dup 7) (match_dup 9)]))] + "split_di (&operands[0], 1, &operands[4], &operands[5]); + split_di (&operands[1], 1, &operands[6], &operands[7]); + split_di (&operands[2], 1, &operands[8], &operands[9]);") ;;- negation instructions @@ -4271,7 +4870,13 @@ byte_xor_operation: [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] "" - "neg%W0 %0") + "* + if (REG_P (operands[0]) && i386_cc_probably_useless_p (insn)) + { + CC_STATUS_INIT; + return AS1(neg%L0,%k0); + } + return AS1(neg%W0,%0);") (define_insn "negqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") @@ -4283,31 +4888,36 @@ byte_xor_operation: [(set (match_operand:SF 0 "register_operand" "=f") (neg:SF (match_operand:SF 1 "register_operand" "0")))] "TARGET_80387" - "fchs") + "fchs" + [(set_attr "type" "fpop")]) (define_insn "negdf2" [(set (match_operand:DF 0 "register_operand" "=f") (neg:DF (match_operand:DF 1 "register_operand" "0")))] "TARGET_80387" - "fchs") + "fchs" + [(set_attr "type" "fpop")]) (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))] "TARGET_80387" - "fchs") + "fchs" + [(set_attr "type" "fpop")]) (define_insn "negxf2" [(set (match_operand:XF 0 "register_operand" "=f") (neg:XF (match_operand:XF 1 "register_operand" "0")))] "TARGET_80387" - "fchs") + "fchs" + [(set_attr "type" "fpop")]) (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f") (neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))] "TARGET_80387" - "fchs") + "fchs" + [(set_attr "type" "fpop")]) ;; Absolute value instructions @@ -4443,19 +5053,88 @@ byte_xor_operation: [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] "" - "not%L0 %0") + "* +{ + /* A Pentium NOT is not pariable. Output it only in case of complex + memory address, because XOR will be inpariable anyway because + of immediate/displacement rule. */ + + if (TARGET_PENTIUM && !optimize_size + && (GET_CODE (operands[0]) != MEM + || memory_address_info (XEXP (operands[0], 0), 1) == 0)) + { + rtx xops[2]; + xops[0] = operands[0]; + xops[1] = GEN_INT (0xffffffff); + output_asm_insn (AS2 (xor%L0,%1,%0), xops); + RET; + } + else + return AS1 (not%L0,%0); +}") (define_insn "one_cmplhi2" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] "" - "not%W0 %0") + "* +{ + /* A Pentium NOT is not pariable. Output it only in case of complex + memory address, because XOR will be inpariable anyway because + of immediate/displacement rule. */ + + if (TARGET_PENTIUM && !optimize_size + && (GET_CODE (operands[0]) != MEM + || memory_address_info (XEXP (operands[0], 0), 1) == 0)) + { + rtx xops[2]; + xops[0] = operands[0]; + xops[1] = GEN_INT (0xffff); + if (REG_P (operands[0]) + && i386_cc_probably_useless_p (insn)) + { + CC_STATUS_INIT; + output_asm_insn (AS2 (xor%L0,%1,%k0), xops); + } + else + output_asm_insn (AS2 (xor%W0,%1,%0), xops); + RET; + } + else + { + if (REG_P (operands[0]) + && i386_cc_probably_useless_p (insn)) + { + CC_STATUS_INIT; + return AS1 (not%L0,%k0); + } + return AS1 (not%W0,%0); + } +}") (define_insn "one_cmplqi2" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))] "" - "not%B0 %0") + "* +{ + /* A Pentium NOT is not pariable. Output it only in case of complex + memory address, because XOR will be inpariable anyway because + of immediate/displacement rule. */ + + if (TARGET_PENTIUM && !optimize_size + && (GET_CODE (operands[0]) != MEM + || memory_address_info (XEXP (operands[0], 0), 1) == 0)) + { + rtx xops[2]; + xops[0] = operands[0]; + xops[1] = GEN_INT (0xff); + output_asm_insn (AS2 (xor%B0,%1,%0), xops); + RET; + } + else + return AS1 (not%B0,%0); +}") ;;- arithmetic shift instructions @@ -4566,79 +5245,79 @@ byte_xor_operation: RET; }") -;; On i386 and i486, "addl reg,reg" is faster than "sall $1,reg" -;; On i486, movl/sall appears slightly faster than leal, but the leal -;; is smaller - use leal for now unless the shift count is 1. +(define_expand "ashlsi3" + [(set (match_operand:SI 0 "nonimmediate_operand" "") + (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") + (match_operand:SI 2 "nonmemory_operand" "")))] + "" + "") -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm") - (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "r,0") - (match_operand:SI 2 "nonmemory_operand" "M,cI")))] +(define_expand "ashlhi3" + [(set (match_operand:HI 0 "nonimmediate_operand" "") + (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "") + (match_operand:HI 2 "nonmemory_operand" "")))] "" - "* -{ - if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1])) - { - if (TARGET_DOUBLE_WITH_ADD && INTVAL (operands[2]) == 1) - { - output_asm_insn (AS2 (mov%L0,%1,%0), operands); - return AS2 (add%L0,%1,%0); - } - else - { - CC_STATUS_INIT; + "") - if (operands[1] == stack_pointer_rtx) - { - output_asm_insn (AS2 (mov%L0,%1,%0), operands); - operands[1] = operands[0]; - } - operands[1] = gen_rtx_MULT (SImode, operands[1], - GEN_INT (1 << INTVAL (operands[2]))); - return AS2 (lea%L0,%a1,%0); - } - } +(define_expand "ashlqi3" + [(set (match_operand:QI 0 "nonimmediate_operand" "") + (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "") + (match_operand:QI 2 "nonmemory_operand" "")))] + "" + "") - if (REG_P (operands[2])) - return AS2 (sal%L0,%b2,%0); +;; Pattern for shifts which can be encoded into an lea instruction. +;; This is kept as a separate pattern so that regmove can optimize cases +;; where we know the source and destination must match. +;; +;; Do not expose this pattern when optimizing for size since we never want +;; to use lea when optimizing for size since mov+sal is smaller than lea. - if (REG_P (operands[0]) && operands[2] == const1_rtx) - return AS2 (add%L0,%0,%0); +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r") + (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,r") + (match_operand:SI 2 "small_shift_operand" "M,M")))] + "! optimize_size" + "* return output_ashl (insn, operands);") - return AS2 (sal%L0,%2,%0); -}") +;; Generic left shift pattern to catch all cases not handled by the +;; shift pattern above. +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "cI")))] + "" + "* return output_ashl (insn, operands);") -(define_insn "ashlhi3" +(define_insn "" + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r") + (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,r") + (match_operand:HI 2 "small_shift_operand" "M,M")))] + "! optimize_size" + "* return output_ashl (insn, operands);") + +(define_insn "" [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") (match_operand:HI 2 "nonmemory_operand" "cI")))] "" - "* -{ - if (REG_P (operands[2])) - return AS2 (sal%W0,%b2,%0); + "* return output_ashl (insn, operands);") - if (REG_P (operands[0]) && operands[2] == const1_rtx) - return AS2 (add%W0,%0,%0); - - return AS2 (sal%W0,%2,%0); -}") +(define_insn "" + [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q") + (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,q") + (match_operand:QI 2 "small_shift_operand" "M,M")))] + "! optimize_size" + "* return output_ashl (insn, operands);") -(define_insn "ashlqi3" +;; Generic left shift pattern to catch all cases not handled by the +;; shift pattern above. +(define_insn "" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") (match_operand:QI 2 "nonmemory_operand" "cI")))] "" - "* -{ - if (REG_P (operands[2])) - return AS2 (sal%B0,%b2,%0); - - if (REG_P (operands[0]) && operands[2] == const1_rtx) - return AS2 (add%B0,%0,%0); - - return AS2 (sal%B0,%2,%0); -}") + "* return output_ashl (insn, operands);") ;; See comment above `ashldi3' about how this works. @@ -4755,6 +5434,15 @@ byte_xor_operation: RET; }") +(define_insn "ashrsi3_31" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,d") + (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,a") + (const_int 31)))] + "!TARGET_PENTIUM || optimize_size" + "@ + sar%L0 $31,%0 + cltd") + (define_insn "ashrsi3" [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") @@ -5177,7 +5865,10 @@ byte_xor_operation: mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); operands[1] = GEN_INT (mask); - if (QI_REG_P (operands[0])) + if (QI_REG_P (operands[0]) + /* A Pentium test is pairable only with eax. Not with ah or al. */ + && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM + || optimize_size)) { if ((mask & ~0xff) == 0) { @@ -5211,7 +5902,10 @@ byte_xor_operation: mask = ((1 << INTVAL (operands[1])) - 1) << INTVAL (operands[2]); operands[1] = GEN_INT (mask); - if (! REG_P (operands[0]) || QI_REG_P (operands[0])) + if ((! REG_P (operands[0]) || QI_REG_P (operands[0])) + /* A Pentium test is pairable only with eax. Not with ah or al. */ + && (! REG_P (operands[0]) || REGNO (operands[0]) || !TARGET_PENTIUM + || optimize_size)) { if ((mask & ~0xff) == 0) { @@ -5261,10 +5955,6 @@ byte_xor_operation: ;; For all sCOND expanders, also expand the compare or test insn that ;; generates cc0. Generate an equality comparison if `seq' or `sne'. -;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may -;; not have any input reloads. A MEM write might need an input reload -;; for the address of the MEM. So don't allow MEM as the SET_DEST. - (define_expand "seq" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5279,18 +5969,6 @@ byte_xor_operation: operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); }") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (eq:QI (cc0) (const_int 0)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return AS1 (setnb,%0); - else - return AS1 (sete,%0); -}") - (define_expand "sne" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5305,19 +5983,6 @@ byte_xor_operation: operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); }") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (ne:QI (cc0) (const_int 0)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return AS1 (setb,%0); - else - return AS1 (setne,%0); -} -") - (define_expand "sgt" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5325,19 +5990,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (gt:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (sete,%0); - - OUTPUT_JUMP (\"setg %0\", \"seta %0\", NULL_PTR); -}") - (define_expand "sgtu" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5345,12 +5997,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (gtu:QI (cc0) (const_int 0)))] - "" - "* return \"seta %0\"; ") - (define_expand "slt" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5358,19 +6004,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (lt:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (sete,%0); - - OUTPUT_JUMP (\"setl %0\", \"setb %0\", \"sets %0\"); -}") - (define_expand "sltu" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5378,12 +6011,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (ltu:QI (cc0) (const_int 0)))] - "" - "* return \"setb %0\"; ") - (define_expand "sge" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5391,19 +6018,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (ge:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (sete,%0); - - OUTPUT_JUMP (\"setge %0\", \"setae %0\", \"setns %0\"); -}") - (define_expand "sgeu" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5411,12 +6025,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (geu:QI (cc0) (const_int 0)))] - "" - "* return \"setae %0\"; ") - (define_expand "sle" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5424,19 +6032,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (le:QI (cc0) (const_int 0)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (setb,%0); - - OUTPUT_JUMP (\"setle %0\", \"setbe %0\", NULL_PTR); -}") - (define_expand "sleu" [(match_dup 1) (set (match_operand:QI 0 "register_operand" "") @@ -5444,11 +6039,69 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (match_operand:QI 0 "register_operand" "=q") - (leu:QI (cc0) (const_int 0)))] - "" - "* return \"setbe %0\"; ") +;; The 386 sCOND opcodes can write to memory. But a gcc sCOND insn may +;; not have any input reloads. A MEM write might need an input reload +;; for the address of the MEM. So don't allow MEM as the SET_DEST. + +(define_insn "*setcc" + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") + (match_operator:QI 1 "comparison_operator" [(cc0) (const_int 0)]))] + "reload_completed || register_operand (operands[0], QImode)" + "* +{ + enum rtx_code code = GET_CODE (operands[1]); + if (cc_prev_status.flags & CC_TEST_AX) + { + int eq; + HOST_WIDE_INT c; + operands[2] = gen_rtx_REG (SImode, 0); + switch (code) + { + case EQ: + c = 0x4000; + eq = 0; + break; + case NE: + c = 0x4000; + eq = 1; + break; + case GT: + c = 0x4100; + eq = 1; + break; + case LT: + c = 0x100; + eq = 0; + break; + case GE: + c = 0x100; + eq = 1; + break; + case LE: + c = 0x4100; + eq = 0; + break; + default: + abort (); + } + if (!TARGET_PENTIUM || optimize_size) + { + operands[3] = GEN_INT (c >> 8); + output_asm_insn (AS2 (test%B0,%3,%h2), operands); + } + else + { + operands[3] = GEN_INT (c); + output_asm_insn (AS2 (test%L0,%3,%2), operands); + } + return eq ? AS1 (sete,%0) : AS1 (setne, %0); + } + + if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) + return (char *)0; + return AS1(set%D1,%0); +}") + ;; Basic conditional jump instructions. ;; We ignore the overflow flag for signed branch instructions. @@ -5473,29 +6126,6 @@ byte_xor_operation: operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); }") -(define_insn "" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jnc %l0\"; - else - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4000); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); - } - - return \"je %l0\"; -}") - (define_expand "bne" [(match_dup 1) (set (pc) @@ -5513,28 +6143,6 @@ byte_xor_operation: operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1); }") -(define_insn "" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jc %l0\"; - else - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4000); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); - } - - return \"jne %l0\"; -}") (define_expand "bgt" [(match_dup 1) @@ -5546,29 +6154,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (je,%l0); - - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); - } - OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR); -}") - (define_expand "bgtu" [(match_dup 1) (set (pc) @@ -5579,15 +6164,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "ja %l0") - (define_expand "blt" [(match_dup 1) (set (pc) @@ -5598,28 +6174,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (je,%l0); - - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); - } - OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\"); -}") (define_expand "bltu" [(match_dup 1) @@ -5631,15 +6185,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jb %l0") - (define_expand "bge" [(match_dup 1) (set (pc) @@ -5650,28 +6195,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (je,%l0); - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); - } - OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\"); -}") - (define_expand "bgeu" [(match_dup 1) (set (pc) @@ -5682,15 +6205,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "jae %l0") - (define_expand "ble" [(match_dup 1) (set (pc) @@ -5701,29 +6215,6 @@ byte_xor_operation: "" "operands[1] = (*i386_compare_gen)(i386_compare_op0, i386_compare_op1);") -(define_insn "" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (jb,%l0); - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); - } - - OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR); -}") - (define_expand "bleu" [(match_dup 1) (set (pc) @@ -5736,184 +6227,127 @@ byte_xor_operation: (define_insn "" [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (label_ref (match_operand 0 "" "")) + (if_then_else (match_operator 0 "comparison_operator" + [(cc0) (const_int 0)]) + (label_ref (match_operand 1 "" "")) (pc)))] "" - "jbe %l0") - -;; Negated conditional jump instructions. - -(define_insn "" - [(set (pc) - (if_then_else (eq (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jc %l0\"; - else - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4000); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); - } - return \"jne %l0\"; -}") - -(define_insn "" - [(set (pc) - (if_then_else (ne (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" "* { - if (cc_prev_status.flags & CC_Z_IN_NOT_C) - return \"jnc %l0\"; - else + enum rtx_code code = GET_CODE (operands[0]); if (cc_prev_status.flags & CC_TEST_AX) { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4000); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); + int eq; + HOST_WIDE_INT c; + operands[2] = gen_rtx_REG (SImode, 0); + switch (code) + { + case EQ: + c = 0x4000; + eq = 0; + break; + case NE: + c = 0x4000; + eq = 1; + break; + case GT: + c = 0x4100; + eq = 1; + break; + case LT: + c = 0x100; + eq = 0; + break; + case GE: + c = 0x100; + eq = 1; + break; + case LE: + c = 0x4100; + eq = 0; + break; + default: + abort (); + } + if (!TARGET_PENTIUM || optimize_size) + { + operands[3] = GEN_INT (c >> 8); + output_asm_insn (AS2 (test%B0,%3,%h2), operands); + } + else + { + operands[3] = GEN_INT (c); + output_asm_insn (AS2 (test%L0,%3,%2), operands); + } + return eq ? AS1 (je,%l1) : AS1 (jne, %l1); } - return \"je %l0\"; -}") + if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) + return (char *)0; -(define_insn "" - [(set (pc) - (if_then_else (gt (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (jne,%l0); - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); - } - OUTPUT_JUMP (\"jle %l0\", \"jbe %l0\", NULL_PTR); + return AS1(j%D0,%l1); }") (define_insn "" [(set (pc) - (if_then_else (gtu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "jbe %l0") - -(define_insn "" - [(set (pc) - (if_then_else (lt (cc0) - (const_int 0)) + (if_then_else (match_operator 0 "comparison_operator" + [(cc0) (const_int 0)]) (pc) - (label_ref (match_operand 0 "" ""))))] + (label_ref (match_operand 1 "" ""))))] "" "* { - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (jne,%l0); + enum rtx_code code = GET_CODE (operands[0]); if (cc_prev_status.flags & CC_TEST_AX) { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); + int eq; + HOST_WIDE_INT c; + operands[2] = gen_rtx_REG (SImode, 0); + switch (code) + { + case EQ: + c = 0x4000; + eq = 1; + break; + case NE: + c = 0x4000; + eq = 0; + break; + case GT: + c = 0x4100; + eq = 0; + break; + case LT: + c = 0x100; + eq = 1; + break; + case GE: + c = 0x100; + eq = 0; + break; + case LE: + c = 0x4100; + eq = 1; + break; + default: + abort (); + } + if (!TARGET_PENTIUM || optimize_size) + { + operands[3] = GEN_INT (c >> 8); + output_asm_insn (AS2 (test%B0,%3,%h2), operands); + } + else + { + operands[3] = GEN_INT (c); + output_asm_insn (AS2 (test%L0,%3,%2), operands); + } + return eq ? AS1 (je,%l1) : AS1 (jne, %l1); } + if ((cc_status.flags & CC_NO_OVERFLOW) && (code == LE || code == GT)) + return (char *)0; - OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\"); -}") - -(define_insn "" - [(set (pc) - (if_then_else (ltu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "jae %l0") - -(define_insn "" - [(set (pc) - (if_then_else (ge (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (jne,%l0); - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (jne,%l0); - } - OUTPUT_JUMP (\"jl %l0\", \"jb %l0\", \"js %l0\"); + return AS1(j%d0,%l1); }") - -(define_insn "" - [(set (pc) - (if_then_else (geu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "jb %l0") - -(define_insn "" - [(set (pc) - (if_then_else (le (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "* -{ - if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387) - && ! (cc_prev_status.flags & CC_FCOMI)) - return AS1 (jae,%l0); - - if (cc_prev_status.flags & CC_TEST_AX) - { - operands[1] = gen_rtx_REG (SImode, 0); - operands[2] = GEN_INT (0x4100); - output_asm_insn (AS2 (testl,%2,%1), operands); - return AS1 (je,%l0); - } - OUTPUT_JUMP (\"jg %l0\", \"ja %l0\", NULL_PTR); -}") - -(define_insn "" - [(set (pc) - (if_then_else (leu (cc0) - (const_int 0)) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" - "ja %l0") ;; Unconditional and other jump instructions @@ -5921,7 +6355,8 @@ byte_xor_operation: [(set (pc) (label_ref (match_operand 0 "" "")))] "" - "jmp %l0") + "jmp %l0" + [(set_attr "memory" "none")]) (define_insn "indirect_jump" [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] @@ -5931,7 +6366,8 @@ byte_xor_operation: CC_STATUS_INIT; return AS1 (jmp,%*%0); -}") +}" + [(set_attr "memory" "none")]) ;; ??? could transform while(--i > 0) S; to if (--i > 0) do S; while(--i); ;; if S does not change i @@ -5952,7 +6388,7 @@ byte_xor_operation: (define_insn "" [(set (pc) (if_then_else (match_operator 0 "arithmetic_comparison_operator" - [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m") + [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+c*r,m") (match_operand:SI 2 "general_operand" "rmi,ri")) (const_int 0)]) (label_ref (match_operand 3 "" "")) @@ -5964,6 +6400,11 @@ byte_xor_operation: "* { CC_STATUS_INIT; + + if (GET_CODE (operands[1]) == REG && REGNO (operands[2]) == 2 && + operands[2] == constm1_rtx && ix86_cpu == PROCESSOR_K6) + return \"loop %l3\"; + if (operands[2] == constm1_rtx) output_asm_insn (AS1 (dec%L1,%1), operands); @@ -6228,6 +6669,12 @@ byte_xor_operation: { rtx addr; + if (operands[3] == const0_rtx) + { + emit_insn (gen_call (operands[0], operands[1])); + DONE; + } + if (flag_pic) current_function_uses_pic_offset_table = 1; @@ -6330,6 +6777,12 @@ byte_xor_operation: { rtx addr; + if (operands[4] == const0_rtx) + { + emit_insn (gen_call_value (operands[0], operands[1], operands[2])); + DONE; + } + if (flag_pic) current_function_uses_pic_offset_table = 1; @@ -6469,7 +6922,8 @@ byte_xor_operation: (define_insn "blockage" [(unspec_volatile [(const_int 0)] 0)] "" - "") + "" + [(set_attr "memory" "none")]) ;; Insn emitted into the body of a function to return from a function. ;; This is only done if the function's epilogue is known to be simple. @@ -6483,18 +6937,21 @@ byte_xor_operation: (define_insn "return_internal" [(return)] "reload_completed" - "ret") + "ret" + [(set_attr "memory" "none")]) (define_insn "return_pop_internal" [(return) (use (match_operand:SI 0 "const_int_operand" ""))] "reload_completed" - "ret %0") + "ret %0" + [(set_attr "memory" "none")]) (define_insn "nop" [(const_int 0)] "" - "nop") + "nop" + [(set_attr "memory" "none")]) (define_expand "prologue" [(const_int 1)] @@ -6521,7 +6978,8 @@ byte_xor_operation: xops[1] = stack_pointer_rtx; output_asm_insn (AS2 (sub%L1,%0,%1), xops); RET; -}") +}" + [(set_attr "memory" "none")]) (define_insn "prologue_set_got" [(set (match_operand:SI 0 "" "") @@ -6553,15 +7011,14 @@ byte_xor_operation: "" "* { - char buffer[64]; - output_asm_insn (AS1 (call,%X1), operands); if (! TARGET_DEEP_BRANCH_PREDICTION) { ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1])); } RET; -}") +}" + [(set_attr "memory" "none")]) (define_insn "prologue_get_pc_and_set_got" [(unspec_volatile [(match_operand:SI 0 "" "")] 3)] @@ -6573,9 +7030,10 @@ byte_xor_operation: ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (operands[1])); output_asm_insn (AS1 (pop%L0,%0), operands); - output_asm_insn (\"addl $_GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands); + output_asm_insn (\"addl $%__GLOBAL_OFFSET_TABLE_+[.-%X1],%0\", operands); RET; -}") +}" + [(set_attr "memory" "none")]) (define_expand "epilogue" [(const_int 1)] @@ -6598,14 +7056,16 @@ byte_xor_operation: xops[1] = stack_pointer_rtx; output_asm_insn (AS2 (mov%L0,%0,%1), xops); RET; -}") +}" + [(set_attr "memory" "none")]) (define_insn "leave" [(const_int 2) (clobber (reg:SI 6)) (clobber (reg:SI 7))] "" - "leave") + "leave" + [(set_attr "memory" "none")]) (define_insn "pop" [(set (match_operand:SI 0 "register_operand" "r") @@ -6616,7 +7076,8 @@ byte_xor_operation: { output_asm_insn (AS1 (pop%L0,%P0), operands); RET; -}") +}" + [(set_attr "memory" "load")]) (define_expand "movstrsi" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") @@ -6698,7 +7159,7 @@ byte_xor_operation: "" " { - rtx addr0, addr1; + rtx addr0; if (GET_CODE (operands[1]) != CONST_INT) FAIL; @@ -6715,7 +7176,7 @@ byte_xor_operation: ;; But strength reduction might offset the MEM expression. So we let ;; reload put the address into %edi. -(define_insn "" +(define_insn "*bzero" [(set (mem:BLK (match_operand:SI 0 "address_operand" "D")) (const_int 0)) (use (match_operand:SI 1 "const_int_operand" "n")) @@ -6731,17 +7192,35 @@ byte_xor_operation: output_asm_insn (\"cld\", operands); if (GET_CODE (operands[1]) == CONST_INT) { - if (INTVAL (operands[1]) & ~0x03) + unsigned int count = INTVAL (operands[1]) & 0xffffffff; + if (count & ~0x03) { - xops[0] = GEN_INT ((INTVAL (operands[1]) >> 2) & 0x3fffffff); + xops[0] = GEN_INT (count / 4); xops[1] = operands[4]; - output_asm_insn (AS2 (mov%L1,%0,%1), xops); + /* K6: stos takes 1 cycle, rep stos takes 8 + %ecx cycles. + 80386: 4/5+5n (+2 for set of ecx) + 80486: 5/7+5n (+1 for set of ecx) + */ + if (count / 4 < ((int) ix86_cpu < (int)PROCESSOR_PENTIUM ? 4 : 6)) + { + do +#ifdef INTEL_SYNTAX + output_asm_insn (\"stosd\", xops); +#else + output_asm_insn (\"stosl\", xops); +#endif + while ((count -= 4) > 3); + } + else + { + output_asm_insn (AS2 (mov%L1,%0,%1), xops); #ifdef INTEL_SYNTAX - output_asm_insn (\"rep stosd\", xops); + output_asm_insn (\"rep stosd\", xops); #else - output_asm_insn (\"rep\;stosl\", xops); + output_asm_insn (\"rep\;stosl\", xops); #endif + } } if (INTVAL (operands[1]) & 0x02) output_asm_insn (\"stosw\", operands); @@ -6910,9 +7389,7 @@ byte_xor_operation: ;; mulM3 and divM3. There are three patterns for each of DFmode and ;; SFmode. The first is the normal insn, the second the same insn but ;; with one operand a conversion, and the third the same insn but with -;; the other operand a conversion. The conversion may be SFmode or -;; SImode if the target mode DFmode, but only SImode if the target mode -;; is SFmode. +;; the other operand a conversion. (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f,f") @@ -6932,23 +7409,6 @@ byte_xor_operation: )]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 3 "binary_387_op" - [(float:DF (match_operand:SI 1 "nonimmediate_operand" "rm")) - (match_operand:DF 2 "register_operand" "0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) - -(define_insn "" [(set (match_operand:XF 0 "register_operand" "=f,f") (match_operator:XF 3 "binary_387_op" [(match_operand:XF 1 "register_operand" "0,f") @@ -6966,23 +7426,6 @@ byte_xor_operation: )]) (define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f") - (match_operator:XF 3 "binary_387_op" - [(float:XF (match_operand:SI 1 "nonimmediate_operand" "rm")) - (match_operand:XF 2 "register_operand" "0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) - -(define_insn "" [(set (match_operand:XF 0 "register_operand" "=f,f") (match_operator:XF 3 "binary_387_op" [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) @@ -7000,23 +7443,6 @@ byte_xor_operation: )]) (define_insn "" - [(set (match_operand:XF 0 "register_operand" "=f") - (match_operator:XF 3 "binary_387_op" - [(match_operand:XF 1 "register_operand" "0") - (float:XF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) - -(define_insn "" [(set (match_operand:XF 0 "register_operand" "=f,f") (match_operator:XF 3 "binary_387_op" [(match_operand:XF 1 "register_operand" "0,f") @@ -7052,23 +7478,6 @@ byte_xor_operation: )]) (define_insn "" - [(set (match_operand:DF 0 "register_operand" "=f") - (match_operator:DF 3 "binary_387_op" - [(match_operand:DF 1 "register_operand" "0") - (float:DF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) - -(define_insn "" [(set (match_operand:DF 0 "register_operand" "=f,f") (match_operator:DF 3 "binary_387_op" [(match_operand:DF 1 "register_operand" "0,f") @@ -7102,40 +7511,6 @@ byte_xor_operation: (const_string "fpop") ) )]) - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (match_operator:SF 3 "binary_387_op" - [(float:SF (match_operand:SI 1 "nonimmediate_operand" "rm")) - (match_operand:SF 2 "register_operand" "0")]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) - -(define_insn "" - [(set (match_operand:SF 0 "register_operand" "=f") - (match_operator:SF 3 "binary_387_op" - [(match_operand:SF 1 "register_operand" "0") - (float:SF (match_operand:SI 2 "nonimmediate_operand" "rm"))]))] - "TARGET_80387" - "* return output_387_binary_op (insn, operands);" - [(set (attr "type") - (cond [(match_operand:DF 3 "is_mul" "") - (const_string "fpmul") - (match_operand:DF 3 "is_div" "") - (const_string "fpdiv") - ] - (const_string "fpop") - ) - )]) (define_expand "strlensi" [(parallel [(set (match_dup 4) @@ -7258,12 +7633,12 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:SI 0 "register_operand" "=r,r") + [(set (match_operand:SI 0 "register_operand" "") (if_then_else:SI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:SI 3 "nonimmediate_operand" "rm,0") - (match_operand:SI 4 "nonimmediate_operand" "0,rm")))] + (match_operand:SI 3 "nonimmediate_operand" "") + (match_operand:SI 4 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) @@ -7273,12 +7648,12 @@ byte_xor_operation: "") (define_split - [(set (match_operand:SI 0 "register_operand" "=r,r") + [(set (match_operand:SI 0 "register_operand" "") (if_then_else:SI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:SI 4 "nonimmediate_operand" "rm,0") - (match_operand:SI 5 "nonimmediate_operand" "0,rm")))] + (match_operand:SI 4 "nonimmediate_operand" "") + (match_operand:SI 5 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) (set (match_dup 0) @@ -7332,12 +7707,12 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:HI 0 "register_operand" "=r,r") + [(set (match_operand:HI 0 "register_operand" "") (if_then_else:HI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:HI 3 "nonimmediate_operand" "rm,0") - (match_operand:HI 4 "nonimmediate_operand" "0,rm")))] + (match_operand:HI 3 "nonimmediate_operand" "") + (match_operand:HI 4 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) @@ -7347,12 +7722,12 @@ byte_xor_operation: "") (define_split - [(set (match_operand:HI 0 "register_operand" "=r,r") + [(set (match_operand:HI 0 "register_operand" "") (if_then_else:HI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:HI 4 "nonimmediate_operand" "rm,0") - (match_operand:HI 5 "nonimmediate_operand" "0,rm")))] + (match_operand:HI 4 "nonimmediate_operand" "") + (match_operand:HI 5 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) @@ -7435,12 +7810,12 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:SF 0 "register_operand" "=f,f") + [(set (match_operand:SF 0 "register_operand" "") (if_then_else:SF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:SF 3 "register_operand" "f,0") - (match_operand:SF 4 "register_operand" "0,f")))] + (match_operand:SF 3 "register_operand" "") + (match_operand:SF 4 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) @@ -7450,12 +7825,12 @@ byte_xor_operation: "") (define_split - [(set (match_operand:SF 0 "register_operand" "=f,f") + [(set (match_operand:SF 0 "register_operand" "") (if_then_else:SF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:SF 4 "register_operand" "f,0") - (match_operand:SF 5 "register_operand" "0,f")))] + (match_operand:SF 4 "register_operand" "") + (match_operand:SF 5 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) (set (match_dup 0) @@ -7537,12 +7912,12 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:DF 0 "register_operand" "=f,f") + [(set (match_operand:DF 0 "register_operand" "") (if_then_else:DF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:DF 3 "register_operand" "f,0") - (match_operand:DF 4 "register_operand" "0,f")))] + (match_operand:DF 3 "register_operand" "") + (match_operand:DF 4 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) @@ -7552,12 +7927,12 @@ byte_xor_operation: "") (define_split - [(set (match_operand:DF 0 "register_operand" "=f,f") + [(set (match_operand:DF 0 "register_operand" "") (if_then_else:DF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:DF 4 "register_operand" "f,0") - (match_operand:DF 5 "register_operand" "0,f")))] + (match_operand:DF 4 "register_operand" "") + (match_operand:DF 5 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) (set (match_dup 0) @@ -7639,12 +8014,12 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:XF 0 "register_operand" "=f,f") + [(set (match_operand:XF 0 "register_operand" "") (if_then_else:XF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:XF 3 "register_operand" "f,0") - (match_operand:XF 4 "register_operand" "0,f")))] + (match_operand:XF 3 "register_operand" "") + (match_operand:XF 4 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) @@ -7654,12 +8029,12 @@ byte_xor_operation: "") (define_split - [(set (match_operand:XF 0 "register_operand" "=f,f") + [(set (match_operand:XF 0 "register_operand" "") (if_then_else:XF (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:XF 4 "register_operand" "f,0") - (match_operand:XF 5 "register_operand" "0,f")))] + (match_operand:XF 4 "register_operand" "") + (match_operand:XF 5 "register_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) (set (match_dup 0) @@ -7713,42 +8088,43 @@ byte_xor_operation: "#") (define_split - [(set (match_operand:DI 0 "register_operand" "=&r,&r") + [(set (match_operand:DI 0 "register_operand" "") (if_then_else:DI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (const_int 0)]) - (match_operand:DI 3 "nonimmediate_operand" "ro,0") - (match_operand:DI 4 "nonimmediate_operand" "0,ro")))] + (match_operand:DI 3 "nonimmediate_operand" "") + (match_operand:DI 4 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (match_dup 2)) - (set (match_dup 0) - (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)]) - (match_dup 3) (match_dup 4)))] - "") + (set (match_dup 5) + (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) + (match_dup 7) (match_dup 9))) + (set (match_dup 6) + (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) + (match_dup 8) (match_dup 10)))] + "split_di (&operands[0], 1, &operands[5], &operands[6]); + split_di (&operands[3], 1, &operands[7], &operands[8]); + split_di (&operands[4], 1, &operands[9], &operands[10]);") (define_split - [(set (match_operand:DI 0 "register_operand" "=&r,&r") + [(set (match_operand:DI 0 "register_operand" "") (if_then_else:DI (match_operator 1 "comparison_operator" [(match_operand 2 "nonimmediate_operand" "") (match_operand 3 "general_operand" "")]) - (match_operand:DI 4 "nonimmediate_operand" "ro,0") - (match_operand:DI 5 "nonimmediate_operand" "0,ro")))] + (match_operand:DI 4 "nonimmediate_operand" "") + (match_operand:DI 5 "nonimmediate_operand" "")))] "TARGET_CMOVE && reload_completed" [(set (cc0) (compare (match_dup 2) (match_dup 3))) - (set (match_dup 0) - (if_then_else:DI (match_op_dup 1 [(cc0) (const_int 0)]) - (match_dup 4) (match_dup 5)))] - "") - -(define_insn "" - [(set (match_operand:DI 0 "register_operand" "=&r,&r") - (if_then_else:DI (match_operator 1 "comparison_operator" - [(cc0) (const_int 0)]) - (match_operand:DI 2 "nonimmediate_operand" "ro,0") - (match_operand:DI 3 "nonimmediate_operand" "0,ro")))] - "TARGET_CMOVE && reload_completed" - "* return output_int_conditional_move (which_alternative, operands);") + (set (match_dup 6) + (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) + (match_dup 8) (match_dup 10))) + (set (match_dup 7) + (if_then_else:SI (match_op_dup 1 [(cc0) (const_int 0)]) + (match_dup 9) (match_dup 11)))] + "split_di (&operands[0], 1, &operands[6], &operands[7]); + split_di (&operands[4], 1, &operands[8], &operands[9]); + split_di (&operands[5], 1, &operands[10], &operands[11]);") (define_insn "strlensi_unroll" [(set (match_operand:SI 0 "register_operand" "=&r,&r") @@ -7785,7 +8161,8 @@ byte_xor_operation: (set (reg:SI 7) (minus:SI (reg:SI 7) (match_dup 0))) (clobber (match_dup 0))] "TARGET_STACK_PROBE" - "* return AS1(call,__alloca);") + "* return AS1(call,__alloca);" + [(set_attr "memory" "none")]) (define_expand "allocate_stack" [(set (match_operand:SI 0 "register_operand" "=r") |