From 2ae0f82c69d39ceb76014746b43e9297c1bc2b6d Mon Sep 17 00:00:00 2001 From: Stan Cox Date: Fri, 9 Feb 1996 22:46:21 +0000 Subject: [PATCH] (fp, integer): Added function units for pentium. From-SVN: r11190 --- gcc/config/i386/i386.md | 1524 +++++++++++++++++++++++++++++---------- 1 file changed, 1140 insertions(+), 384 deletions(-) diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 9df676eadfc..c0a5d015c44 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -17,8 +17,7 @@ ;; You should have received a copy of the GNU General Public License ;; along with GNU CC; see the file COPYING. If not, write to ;; the Free Software Foundation, 59 Temple Place - Suite 330, -;; Boston, MA 02111-1307, USA. - +;; Boston, MA 02111-1307, USA. */ ;; The original PO technology requires these to be ordered by speed, ;; so that assigner will pick the fastest. @@ -59,6 +58,37 @@ ;; operand 0 is the argument for `sin'. ;; 2 This is a `cos' operation. The mode of the UNSPEC is MODE_FLOAT. ;; operand 0 is the argument for `cos'. + +;; This shadows the processor_type enumeration, so changes must be made +;; to i386.h at the same time. + +(define_attr "type" "integer,fld,fpop,fpdiv" + (const_string "integer")) + +;; Functional units + +;; Floating point + +(define_function_unit "fp" 1 0 + (and (eq_attr "type" "fpop") (eq_attr "cpu" "!pentium")) + 5 5) + +(define_function_unit "fp" 1 0 + (and (eq_attr "type" "fpop") (eq_attr "cpu" "pentium")) + 3 0) + +(define_function_unit "fp" 1 0 + (eq_attr "type" "fpdiv") + 10 10) + +(define_function_unit "fp" 1 0 + (eq_attr "type" "fld") + 1 0) + +(define_function_unit "integer" 1 0 + (and (eq_attr "type" "integer") (eq_attr "cpu" "!i386")) + 2 0) + ;; "movl MEM,REG / testl REG,REG" is faster on a 486 than "cmpl $0,MEM". ;; But restricting MEM here would mean that gcc could not remove a redundant @@ -76,7 +106,7 @@ ;; enumeration in rs6000.h. (define_attr "cpu" "i386,i486,pentium" - (const (symbol_ref "ix86_cpu_attr"))) + (const (symbol_ref "ix86_cpu"))) (define_insn "tstsi_1" [(set (cc0) @@ -234,7 +264,7 @@ return output_fp_cc0_set (insn); }") -;; Don't generate tstdf if generating IEEE code, since the `ftst' opcode +;; Don't generate tstxf if generating IEEE code, since the `ftst' opcode ;; isn't IEEE compliant. (define_expand "tstxf" @@ -352,8 +382,8 @@ (define_insn "" [(set (cc0) (match_operator 2 "VOIDmode_compare_op" - [(match_operand:XF 0 "nonimmediate_operand" "f") - (match_operand:XF 1 "nonimmediate_operand" "f")])) + [(match_operand:XF 0 "register_operand" "f") + (match_operand:XF 1 "register_operand" "f")])) (clobber (match_scratch:HI 3 "=a"))] "TARGET_80387 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)" @@ -457,6 +487,16 @@ "TARGET_80387" "* return output_float_compare (insn, operands);") +(define_insn "" + [(set (cc0) + (match_operator 2 "VOIDmode_compare_op" + [(float_extend:DF + (match_operand:SF 0 "register_operand" "f")) + (match_operand:DF 1 "nonimmediate_operand" "fm")])) + (clobber (match_scratch:HI 3 "=a"))] + "TARGET_80387" + "* return output_float_compare (insn, operands);") + (define_insn "" [(set (cc0) (compare:CCFPEQ (match_operand:DF 0 "register_operand" "f") @@ -533,35 +573,38 @@ i386_compare_gen = gen_cmpxf_cc; i386_compare_gen_eq = gen_cmpxf_ccfpeq; i386_compare_op0 = operands[0]; - i386_compare_op1 = operands[1]; + i386_compare_op1 = (immediate_operand (operands[1], XFmode)) + ? copy_to_mode_reg (XFmode, operands[1]) : operands[1]; DONE; }") (define_expand "cmpdf" [(set (cc0) (compare (match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "nonimmediate_operand" "")))] + (match_operand:DF 1 "general_operand" "")))] "TARGET_80387" " { i386_compare_gen = gen_cmpdf_cc; i386_compare_gen_eq = gen_cmpdf_ccfpeq; i386_compare_op0 = operands[0]; - i386_compare_op1 = operands[1]; + i386_compare_op1 = (immediate_operand (operands[1], DFmode)) + ? copy_to_mode_reg (DFmode, operands[1]) : operands[1]; DONE; }") (define_expand "cmpsf" [(set (cc0) (compare (match_operand:SF 0 "register_operand" "") - (match_operand:SF 1 "nonimmediate_operand" "")))] + (match_operand:SF 1 "general_operand" "")))] "TARGET_80387" " { i386_compare_gen = gen_cmpsf_cc; i386_compare_gen_eq = gen_cmpsf_ccfpeq; i386_compare_op0 = operands[0]; - i386_compare_op1 = operands[1]; + i386_compare_op1 = (immediate_operand (operands[1], SFmode)) + ? copy_to_mode_reg (SFmode, operands[1]) : operands[1]; DONE; }") @@ -630,7 +673,7 @@ (define_insn "" [(set (cc0) (and:SI (match_operand:SI 0 "general_operand" "%ro") - (match_operand:SI 1 "general_operand" "ri")))] + (match_operand:SI 1 "nonmemory_operand" "ri")))] "" "* { @@ -688,7 +731,7 @@ (define_insn "" [(set (cc0) (and:HI (match_operand:HI 0 "general_operand" "%ro") - (match_operand:HI 1 "general_operand" "ri")))] + (match_operand:HI 1 "nonmemory_operand" "ri")))] "" "* { @@ -729,8 +772,8 @@ (define_insn "" [(set (cc0) - (and:QI (match_operand:QI 0 "general_operand" "%qm") - (match_operand:QI 1 "general_operand" "qi")))] + (and:QI (match_operand:QI 0 "nonimmediate_operand" "%qm") + (match_operand:QI 1 "nonmemory_operand" "qi")))] "" "* { @@ -762,7 +805,7 @@ (define_insn "" [(set (match_operand:SI 0 "push_operand" "=<") - (match_operand:SI 1 "general_operand" "ri"))] + (match_operand:SI 1 "nonmemory_operand" "ri"))] "!TARGET_PUSH_MEMORY && !TARGET_MOVE" "push%L0 %1") @@ -836,7 +879,7 @@ (define_insn "" [(set (match_operand:HI 0 "push_operand" "=<") - (match_operand:HI 1 "general_operand" "ri"))] + (match_operand:HI 1 "nonmemory_operand" "ri"))] "!TARGET_PUSH_MEMORY && !TARGET_MOVE" "push%W0 %1") @@ -938,13 +981,13 @@ ;; the amount pushed up to a halfword. (define_insn "" [(set (match_operand:QI 0 "push_operand" "=<") - (match_operand:QI 1 "immediate_operand" "n"))] + (match_operand:QI 1 "const_int_operand" "n"))] "" "* return AS1 (push%W0,%1);") (define_insn "" [(set (match_operand:QI 0 "push_operand" "=<") - (match_operand:QI 1 "nonimmediate_operand" "q"))] + (match_operand:QI 1 "register_operand" "q"))] "!TARGET_MOVE" "* { @@ -984,7 +1027,7 @@ }") (define_insn "" - [(set (match_operand:QI 0 "general_operand" "=q,*r,qm") + [(set (match_operand:QI 0 "nonimmediate_operand" "=q,*r,qm") (match_operand:QI 1 "general_operand" "*g,q,qn"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "* @@ -1038,7 +1081,7 @@ }") (define_insn "" - [(set (strict_low_part (match_operand:QI 0 "general_operand" "+qm,q")) + [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q")) (match_operand:QI 1 "general_operand" "*qn,m"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "* @@ -1089,16 +1132,28 @@ DONE; } - /* 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. */ - if (flag_pic + /* 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. */ + if ((reload_in_progress | reload_completed) == 0 && GET_CODE (operands[0]) != MEM && GET_CODE (operands[1]) == CONST_DOUBLE && !standard_80387_constant_p (operands[1])) { - current_function_uses_pic_offset_table = 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)); } }") @@ -1182,7 +1237,7 @@ ;; For the purposes of regclass, prefer FLOAT_REGS. (define_insn "movsf_normal" - [(set (match_operand:SF 0 "general_operand" "=*rfm,*rf,f,!*rm") + [(set (match_operand:SF 0 "nonimmediate_operand" "=*rfm,*rf,f,!*rm") (match_operand:SF 1 "general_operand" "*rf,*rfm,fG,fF"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "* @@ -1234,7 +1289,9 @@ /* Handle all SFmode moves not involving the 387 */ return singlemove_string (operands); -}") +}" + [(set_attr "type" "fld")]) + (define_insn "swapsf" [(set (match_operand:SF 0 "register_operand" "f") @@ -1274,12 +1331,24 @@ 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. */ - if (flag_pic + if ((reload_in_progress | reload_completed) == 0 && GET_CODE (operands[0]) != MEM && GET_CODE (operands[1]) == CONST_DOUBLE && !standard_80387_constant_p (operands[1])) { - current_function_uses_pic_offset_table = 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)); } }") @@ -1353,7 +1422,7 @@ ;; For the purposes of regclass, prefer FLOAT_REGS. (define_insn "movdf_normal" - [(set (match_operand:DF 0 "general_operand" "=f,fm,!*rf,!*rm") + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm") (match_operand:DF 1 "general_operand" "fmG,f,*rfm,*rfF"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "* @@ -1405,7 +1474,10 @@ /* Handle all DFmode moves not involving the 387 */ return output_move_double (operands); -}") +}" +[(set_attr "type" "fld")]) + + (define_insn "swapdf" [(set (match_operand:DF 0 "register_operand" "f") @@ -1441,16 +1513,28 @@ DONE; } - /* 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. */ - if (flag_pic + /* 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. */ + if ((reload_in_progress | reload_completed) == 0 && GET_CODE (operands[0]) != MEM && GET_CODE (operands[1]) == CONST_DOUBLE && !standard_80387_constant_p (operands[1])) { - current_function_uses_pic_offset_table = 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)); } }") @@ -1521,7 +1605,7 @@ "* return output_move_memory (operands, insn, GET_MODE_SIZE (XFmode), 2, 4);") (define_insn "movxf_normal" - [(set (match_operand:XF 0 "general_operand" "=f,fm,!*rf,!*rm") + [(set (match_operand:XF 0 "nonimmediate_operand" "=f,fm,!*rf,!*rm") (match_operand:XF 1 "general_operand" "fmG,f,*rfm,*rfF"))] "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" "* @@ -1576,7 +1660,7 @@ return output_move_double (operands); }") -(define_insn "swapxf" +(define_insn "swapxf" [(set (match_operand:XF 0 "register_operand" "f") (match_operand:XF 1 "register_operand" "f")) (set (match_dup 1) @@ -1629,21 +1713,36 @@ ;; See comments by `andsi' for when andl is faster than movzx. (define_insn "zero_extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=r") - (zero_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "rm")))] + [(set (match_operand:SI 0 "register_operand" "=r,&r,?r") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,rm,rm")))] "" "* -{ - if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) + { + rtx xops[2]; + + if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) { - rtx xops[2]; xops[0] = operands[0]; xops[1] = GEN_INT (0xffff); output_asm_insn (AS2 (and%L0,%1,%k0), xops); RET; } + if (TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])) + { + output_asm_insn (AS2 (xor%L0,%0,%0),operands); + output_asm_insn (AS2 (mov%W0,%1,%w0),operands); + RET; + } + + if (TARGET_ZERO_EXTEND_WITH_AND) + { + xops[0] = operands[0]; + xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xffff); + output_asm_insn (AS2 (mov%W0,%1,%w0),operands); + output_asm_insn (AS2 (and%L0,%1,%k0), xops); + RET; + } #ifdef INTEL_SYNTAX return AS2 (movzx,%1,%0); @@ -1652,23 +1751,62 @@ #endif }") +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] + "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !reg_overlap_mentioned_p (operands[0], operands[1])" + [(set (match_dup 0) + (const_int 0)) + (set (strict_low_part (match_dup 2)) + (match_dup 1))] + "operands[2] = gen_rtx (REG, HImode, REGNO (operands[0]));") + + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:HI 1 "memory_operand" "")))] + "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && reg_overlap_mentioned_p (operands[0], operands[1])" + [(set (strict_low_part (match_dup 2)) + (match_dup 1)) + (set (match_dup 0) + (and:SI (match_dup 0) + (const_int 65535)))] + "operands[2] = gen_rtx (REG, HImode, REGNO (operands[0]));") + (define_insn "zero_extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=r") - (zero_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "qm")))] + [(set (match_operand:HI 0 "register_operand" "=q,&q,?r") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))] "" "* -{ + { + rtx xops[2]; + if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) - && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) + && REG_P (operands[1]) + && REGNO (operands[0]) == REGNO (operands[1])) { - rtx xops[2]; xops[0] = operands[0]; xops[1] = GEN_INT (0xff); output_asm_insn (AS2 (and%L0,%1,%k0), xops); RET; } - + if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0])) + { + if(!reg_overlap_mentioned_p(operands[0],operands[1])) + { + output_asm_insn (AS2 (xor%L0,%k0,%k0), operands); + output_asm_insn (AS2 (mov%B0,%1,%b0), operands); + } + else + { + xops[0] = operands[0]; + xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff); + output_asm_insn (AS2 (mov%B0,%1,%b0),operands); + output_asm_insn (AS2 (and%L0,%1,%k0), xops); + } + RET; + } + #ifdef INTEL_SYNTAX return AS2 (movzx,%1,%0); #else @@ -1676,22 +1814,84 @@ #endif }") +(define_split + [(set (match_operand:HI 0 "register_operand" "") + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))] + "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND + && !reg_overlap_mentioned_p (operands[0], operands[1])" + [(set (match_dup 0) + (const_int 0)) + (set (strict_low_part (match_dup 2)) + (match_dup 1))] + "operands[2] = gen_rtx (REG, QImode, REGNO (operands[0]));") + + +(define_split + [(set (match_operand:HI 0 "register_operand" "") + (zero_extend:HI (match_operand:QI 1 "memory_operand" "")))] + "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND + && reg_overlap_mentioned_p (operands[0], operands[1])" + [(set (strict_low_part (match_dup 2)) + (match_dup 1)) + (set (match_dup 0) + (and:HI (match_dup 0) + (const_int 255)))] + "operands[2] = gen_rtx (REG, QImode, REGNO (operands[0]));") + +(define_split + [(set (match_operand:HI 0 "register_operand" "") + (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] + "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && REGNO (operands[0]) != REGNO (operands[1])" + [(set (match_dup 0) + (match_dup 2)) + (set (match_dup 0) + (and:HI (match_dup 0) + (const_int 255)))] + "operands[2] = gen_rtx (REG, HImode, REGNO (operands[1]));") + (define_insn "zero_extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=r") - (zero_extend:SI - (match_operand:QI 1 "nonimmediate_operand" "qm")))] + [(set (match_operand:SI 0 "register_operand" "=q,&q,?r") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm,qm")))] "" "* -{ + { + rtx xops[2]; + if ((TARGET_ZERO_EXTEND_WITH_AND || REGNO (operands[0]) == 0) - && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])) + && REG_P (operands[1]) + && REGNO (operands[0]) == REGNO (operands[1])) { - rtx xops[2]; xops[0] = operands[0]; xops[1] = GEN_INT (0xff); output_asm_insn (AS2 (and%L0,%1,%k0), xops); RET; } + if (TARGET_ZERO_EXTEND_WITH_AND && QI_REG_P (operands[0])) + { + if(!reg_overlap_mentioned_p (operands[0], operands[1])) + { + output_asm_insn (AS2 (xor%L0,%0,%0),operands); + output_asm_insn (AS2 (mov%B0,%1,%b0),operands); + } + else + { + xops[0] = operands[0]; + xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff); + output_asm_insn (AS2 (mov%B0,%1,%b0), operands); + output_asm_insn (AS2 (and%L0,%1,%k0), xops); + } + RET; + } + + if (TARGET_ZERO_EXTEND_WITH_AND && GET_CODE (operands[1]) == REG) + { + xops[0] = operands[0]; + xops[1] = gen_rtx (CONST_INT, VOIDmode, 0xff); + operands[1] = gen_rtx (REG, SImode, REGNO (operands[1])); + output_asm_insn (AS2 (mov%L0,%1,%0), operands); + output_asm_insn (AS2 (and%L0,%1,%k0), xops); + RET; + } #ifdef INTEL_SYNTAX return AS2 (movzx,%1,%0); @@ -1700,23 +1900,76 @@ #endif }") +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] + "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND + && !reg_overlap_mentioned_p (operands[0], operands[1])" + [(set (match_dup 0) + (const_int 0)) + (set (strict_low_part (match_dup 2)) + (match_dup 1))] + "operands[2] = gen_rtx (REG, QImode, REGNO (operands[0]));") + + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:QI 1 "memory_operand" "")))] + "reload_completed && QI_REG_P (operands[0]) && TARGET_ZERO_EXTEND_WITH_AND + && reg_overlap_mentioned_p (operands[0], operands[1])" + [(set (strict_low_part (match_dup 2)) + (match_dup 1)) + (set (match_dup 0) + (and:SI (match_dup 0) + (const_int 255)))] + "operands[2] = gen_rtx (REG, QImode, REGNO (operands[0]));") + +(define_split + [(set (match_operand:SI 0 "register_operand" "") + (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] + "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && REGNO (operands[0]) != REGNO (operands[1])" + [(set (match_dup 0) + (match_dup 2)) + (set (match_dup 0) + (and:SI (match_dup 0) + (const_int 255)))] + "operands[2] = gen_rtx (REG, SImode, REGNO (operands[1]));") + (define_insn "zero_extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (match_operand:SI 1 "register_operand" "0")))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?m") + (zero_extend:DI (match_operand:SI 1 "register_operand" "0,rm,r")))] "" "* -{ - operands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1); - return AS2 (xor%L0,%0,%0); + { + 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; }") ;;- sign extension instructions (define_insn "extendsidi2" [(set (match_operand:DI 0 "register_operand" "=r") - (sign_extend:DI - (match_operand:SI 1 "register_operand" "0")))] + (sign_extend:DI (match_operand:SI 1 "register_operand" "0")))] "" "* { @@ -1742,9 +1995,8 @@ ;; We use what the Unix assembler expects. (define_insn "extendhisi2" - [(set (match_operand:SI 0 "general_operand" "=r") - (sign_extend:SI - (match_operand:HI 1 "nonimmediate_operand" "rm")))] + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))] "" "* { @@ -1764,9 +2016,8 @@ }") (define_insn "extendqihi2" - [(set (match_operand:HI 0 "general_operand" "=r") - (sign_extend:HI - (match_operand:QI 1 "nonimmediate_operand" "qm")))] + [(set (match_operand:HI 0 "register_operand" "=r") + (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))] "" "* { @@ -1782,9 +2033,8 @@ }") (define_insn "extendqisi2" - [(set (match_operand:SI 0 "general_operand" "=r") - (sign_extend:SI - (match_operand:QI 1 "nonimmediate_operand" "qm")))] + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))] "" "* { @@ -1794,13 +2044,72 @@ return AS2 (movs%B0%L0,%1,%0); #endif }") + + +;; Truncation of long long -> 32 bit + +(define_expand "truncdisi2" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") + (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))] + "" + " +{ + /* Don't generate memory->memory moves, go through a register */ + if (TARGET_MOVE + && (reload_in_progress | reload_completed) == 0 + && GET_CODE (operands[0]) == MEM + && GET_CODE (operands[1]) == MEM) + { + rtx target = gen_reg_rtx (SImode); + emit_insn (gen_truncdisi2 (target, operands[1])); + emit_move_insn (operands[0], target); + DONE; + } +}") + +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") + (truncate:SI (match_operand:DI 1 "nonimmediate_operand" "ro,r")))] + "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" + "* +{ + rtx low[2], high[2], xops[2]; + + split_di (&operands[1], 1, low, high); + xops[0] = operands[0]; + xops[1] = low[0]; + if (!rtx_equal_p (xops[0], xops[1])) + output_asm_insn (AS2 (mov%L0,%1,%0), xops); + + RET; +}") + +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,m") + (truncate:SI (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r") + (const_int 32))))] + "(!TARGET_MOVE || GET_CODE (operands[0]) != MEM) || (GET_CODE (operands[1]) != MEM)" + "* +{ + rtx low[2], high[2], xops[2]; + + split_di (&operands[1], 1, low, high); + xops[0] = operands[0]; + xops[1] = high[0]; + if (!rtx_equal_p (xops[0], xops[1])) + output_asm_insn (AS2 (mov%L0,%1,%0), xops); + + RET; +}") + + ;; Conversions between float and double. (define_insn "extendsfdf2" - [(set (match_operand:DF 0 "general_operand" "=fm,f") + [(set (match_operand:DF 0 "nonimmediate_operand" "=fm,f") (float_extend:DF - (match_operand:SF 1 "general_operand" "f,fm")))] + (match_operand:SF 1 "nonimmediate_operand" "f,fm")))] "TARGET_80387" "* { @@ -1833,9 +2142,9 @@ }") (define_insn "extenddfxf2" - [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r") + [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r") (float_extend:XF - (match_operand:DF 1 "general_operand" "f,fm,!*r,f")))] + (match_operand:DF 1 "nonimmediate_operand" "f,fm,!*r,f")))] "TARGET_80387" "* { @@ -1868,9 +2177,9 @@ }") (define_insn "extendsfxf2" - [(set (match_operand:XF 0 "general_operand" "=fm,f,f,!*r") + [(set (match_operand:XF 0 "nonimmediate_operand" "=fm,f,f,!*r") (float_extend:XF - (match_operand:SF 1 "general_operand" "f,fm,!*r,f")))] + (match_operand:SF 1 "nonimmediate_operand" "f,fm,!*r,f")))] "TARGET_80387" "* { @@ -1945,7 +2254,7 @@ }") (define_insn "truncxfsf2" - [(set (match_operand:SF 0 "general_operand" "=m,!*r") + [(set (match_operand:SF 0 "nonimmediate_operand" "=m,!*r") (float_truncate:SF (match_operand:XF 1 "register_operand" "f,f")))] "TARGET_80387" @@ -1978,7 +2287,7 @@ }") (define_insn "truncxfdf2" - [(set (match_operand:DF 0 "general_operand" "=m,!*r") + [(set (match_operand:DF 0 "nonimmediate_operand" "=m,!*r") (float_truncate:DF (match_operand:XF 1 "register_operand" "f,f")))] "TARGET_80387" @@ -2139,7 +2448,7 @@ ;; These match a signed conversion of either DFmode or SFmode to DImode. (define_insn "" - [(set (match_operand:DI 0 "general_operand" "=rm") + [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") (fix:DI (fix:XF (match_operand:XF 1 "register_operand" "f")))) (clobber (match_dup 1)) (clobber (match_operand:SI 2 "memory_operand" "m")) @@ -2149,7 +2458,7 @@ "* return output_fix_trunc (insn, operands);") (define_insn "" - [(set (match_operand:DI 0 "general_operand" "=rm") + [(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")) @@ -2159,7 +2468,7 @@ "* return output_fix_trunc (insn, operands);") (define_insn "" - [(set (match_operand:DI 0 "general_operand" "=rm") + [(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")) @@ -2213,7 +2522,7 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") + [(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:SI 3 "memory_operand" "m")) @@ -2222,7 +2531,7 @@ "* return output_fix_trunc (insn, operands);") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") + [(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:SI 3 "memory_operand" "m")) @@ -2231,7 +2540,7 @@ "* return output_fix_trunc (insn, operands);") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") + [(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:SI 3 "memory_operand" "m")) @@ -2284,7 +2593,7 @@ (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f") - (float:XF (match_operand:DI 1 "general_operand" "rm")))] + (float:XF (match_operand:DI 1 "nonimmediate_operand" "rm")))] "TARGET_80387" "* { @@ -2352,7 +2661,7 @@ (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f,f") - (float:XF (match_operand:SI 1 "general_operand" "m,!*r")))] + (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,!*r")))] "TARGET_80387" "* { @@ -2386,6 +2695,102 @@ ;;- add instructions +(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")))) + (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))] + "" + "* +{ + rtx low[3], high[3], xops[7], temp; + + CC_STATUS_INIT; + + split_di (operands, 2, low, high); + high[2] = const0_rtx; + low[2] = operands[2]; + + 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 || GET_CODE (operands[1]) != MEM) + { + output_asm_insn (AS2 (mov%L1,%3,%1), xops); + output_asm_insn (AS2 (mov%L0,%2,%0), xops); + } + else + { + xops[4] = high[2]; + xops[5] = low[2]; + xops[6] = operands[3]; + output_asm_insn (AS2 (mov%L6,%3,%6), xops); + output_asm_insn (AS2 (add%L6,%5,%6), xops); + output_asm_insn (AS2 (mov%L1,%6,%1), xops); + output_asm_insn (AS2 (mov%L6,%2,%6), xops); + output_asm_insn (AS2 (adc%L6,%4,%6), xops); + output_asm_insn (AS2 (mov%L0,%6,%0), xops); + RET; + } + } + + output_asm_insn (AS2 (add%L0,%2,%0), low); + output_asm_insn (AS2 (adc%L0,%2,%0), high); + RET; +}") + +(define_insn "addsidi3_2" + [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r,o,&r,r,o,o") + (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,ri,o,ri,ri,ri")) + (match_operand:DI 1 "general_operand" "0,0,0,roiF,roiF,riF,o"))) + (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,&r"))] + "" + "* +{ + rtx low[3], high[3], xops[7], temp; + + CC_STATUS_INIT; + + split_di (operands, 2, low, high); + high[2] = const0_rtx; + low[2] = operands[2]; + + 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 || GET_CODE (operands[1]) != MEM) + { + output_asm_insn (AS2 (mov%L1,%3,%1), xops); + output_asm_insn (AS2 (mov%L0,%2,%0), xops); + } + else + { + xops[4] = high[2]; + xops[5] = low[2]; + xops[6] = operands[3]; + output_asm_insn (AS2 (mov%L6,%3,%6), xops); + output_asm_insn (AS2 (add%L6,%5,%6), xops); + output_asm_insn (AS2 (mov%L1,%6,%1), xops); + output_asm_insn (AS2 (mov%L6,%2,%6), xops); + output_asm_insn (AS2 (adc%L6,%4,%6), xops); + output_asm_insn (AS2 (mov%L0,%6,%0), xops); + RET; + } + } + + output_asm_insn (AS2 (add%L0,%2,%0), low); + output_asm_insn (AS2 (adc%L0,%2,%0), high); + RET; +}") + (define_insn "adddi3" [(set (match_operand:DI 0 "general_operand" "=&r,ro,o,&r,ro,o,&r,o,o,o") (plus:DI (match_operand:DI 1 "general_operand" "%0,0,0,o,riF,o,or,riF,riF,o") @@ -2462,14 +2867,23 @@ ;; 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. -(define_insn "addsi3" - [(set (match_operand:SI 0 "general_operand" "=?r,rm,r") - (plus:SI (match_operand:SI 1 "general_operand" "%r,0,0") - (match_operand:SI 2 "general_operand" "ri,ri,rm")))] +(define_expand "addsi3" + [(set (match_operand:SI 0 "nonimmediate_operand" "") + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") + (match_operand:SI 2 "general_operand" "")))] "" + "IX86_EXPAND_BINARY_OPERATOR (PLUS, SImode, operands);") + +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r") + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r") + (match_operand:SI 2 "general_operand" "rmi,ri,ri")))] + "ix86_binary_operator_ok (PLUS, SImode, operands)" "* { - if (REG_P (operands[0]) && REGNO (operands[0]) != REGNO (operands[1])) + if (REG_P (operands[0]) && REG_P (operands[1]) + && (REG_P (operands[2]) || GET_CODE (operands[2]) == CONST_INT) + && REGNO (operands[0]) != REGNO (operands[1])) { if (REG_P (operands[2]) && REGNO (operands[0]) == REGNO (operands[2])) return AS2 (add%L0,%1,%0); @@ -2489,10 +2903,11 @@ operands[1] = SET_SRC (PATTERN (insn)); return AS2 (lea%L0,%a1,%0); } - - output_asm_insn (AS2 (mov%L0,%1,%0), operands); } + if (!rtx_equal_p (operands[0], operands[1])) + output_asm_insn (AS2 (mov%L0,%1,%0), operands); + if (operands[2] == const1_rtx) return AS1 (inc%L0,%0); @@ -2502,15 +2917,51 @@ return AS2 (add%L0,%2,%0); }") +;; addsi3 is faster, so put this after. + +(define_insn "movsi_lea" + [(set (match_operand:SI 0 "register_operand" "=r") + (match_operand:QI 1 "address_operand" "p"))] + "" + "* +{ + /* Adding a constant to a register is faster with an add. */ + /* ??? can this ever happen? */ + if (GET_CODE (operands[1]) == PLUS + && GET_CODE (XEXP (operands[1], 1)) == CONST_INT + && rtx_equal_p (operands[0], XEXP (operands[1], 0))) + { + operands[1] = XEXP (operands[1], 1); + + if (operands[1] == const1_rtx) + return AS1 (inc%L0,%0); + + if (operands[1] == constm1_rtx) + return AS1 (dec%L0,%0); + + return AS2 (add%L0,%1,%0); + } + + CC_STATUS_INIT; + return AS2 (lea%L0,%a1,%0); +}") + ;; ??? `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 ;; able to handle the operand. But leal always works? -(define_insn "addhi3" - [(set (match_operand:HI 0 "general_operand" "=rm,r") - (plus:HI (match_operand:HI 1 "general_operand" "%0,0") - (match_operand:HI 2 "general_operand" "ri,rm")))] +(define_expand "addhi3" + [(set (match_operand:HI 0 "general_operand" "") + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "") + (match_operand:HI 2 "general_operand" "")))] "" + "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")))] + "ix86_binary_operator_ok (PLUS, HImode, operands)" "* { /* ??? what about offsettable memory references? */ @@ -2541,11 +2992,18 @@ return AS2 (add%W0,%2,%0); }") -(define_insn "addqi3" - [(set (match_operand:QI 0 "general_operand" "=qm,q") - (plus:QI (match_operand:QI 1 "general_operand" "%0,0") - (match_operand:QI 2 "general_operand" "qn,qmn")))] +(define_expand "addqi3" + [(set (match_operand:QI 0 "general_operand" "") + (plus:QI (match_operand:QI 1 "general_operand" "") + (match_operand:QI 2 "general_operand" "")))] "" + "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")))] + "ix86_binary_operator_ok (PLUS, QImode, operands)" "* { if (operands[2] == const1_rtx) @@ -2569,8 +3027,8 @@ ; ;(define_insn "" ; [(set (match_operand:SI 0 "push_operand" "=<") -; (plus:SI (match_operand:SI 1 "general_operand" "%r") -; (match_operand:SI 2 "general_operand" "ri")))] +; (plus:SI (match_operand:SI 1 "register_operand" "%r") +; (match_operand:SI 2 "nonmemory_operand" "ri")))] ; "" ; "* ;{ @@ -2584,40 +3042,12 @@ ; RET; ;}") -;; addsi3 is faster, so put this after. - -(define_insn "movsi_lea" - [(set (match_operand:SI 0 "register_operand" "=r") - (match_operand:QI 1 "address_operand" "p"))] - "" - "* -{ - CC_STATUS_INIT; - /* Adding a constant to a register is faster with an add. */ - /* ??? can this ever happen? */ - if (GET_CODE (operands[1]) == PLUS - && GET_CODE (XEXP (operands[1], 1)) == CONST_INT - && rtx_equal_p (operands[0], XEXP (operands[1], 0))) - { - operands[1] = XEXP (operands[1], 1); - - if (operands[1] == const1_rtx) - return AS1 (inc%L0,%0); - - if (operands[1] == constm1_rtx) - return AS1 (dec%L0,%0); - - return AS2 (add%L0,%1,%0); - } - return AS2 (lea%L0,%a1,%0); -}") - ;; The patterns that match these are at the end of this file. (define_expand "addxf3" [(set (match_operand:XF 0 "register_operand" "") - (plus:XF (match_operand:XF 1 "nonimmediate_operand" "") - (match_operand:XF 2 "nonimmediate_operand" "")))] + (plus:XF (match_operand:XF 1 "register_operand" "") + (match_operand:XF 2 "register_operand" "")))] "TARGET_80387" "") @@ -2637,6 +3067,54 @@ ;;- subtract instructions +(define_insn "subsidi3" + [(set (match_operand:DI 0 "general_operand" "=&r,ro,&r,o,o") + (minus:DI (match_operand:DI 1 "general_operand" "0,0,roiF,riF,o") + (zero_extend:DI (match_operand:SI 2 "general_operand" "o,ri,roi,ri,ri")))) + (clobber (match_scratch:SI 3 "=X,X,X,X,&r"))] + "" + "* +{ + rtx low[3], high[3], xops[7]; + + CC_STATUS_INIT; + + split_di (operands, 2, low, high); + high[2] = const0_rtx; + low[2] = operands[2]; + + 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 || GET_CODE (operands[1]) != MEM) + { + output_asm_insn (AS2 (mov%L1,%3,%1), xops); + output_asm_insn (AS2 (mov%L0,%2,%0), xops); + } + else + { + xops[4] = high[2]; + xops[5] = low[2]; + xops[6] = operands[3]; + output_asm_insn (AS2 (mov%L6,%3,%6), xops); + output_asm_insn (AS2 (sub%L6,%5,%6), xops); + output_asm_insn (AS2 (mov%L1,%6,%1), xops); + output_asm_insn (AS2 (mov%L6,%2,%6), xops); + output_asm_insn (AS2 (sbb%L6,%4,%6), xops); + output_asm_insn (AS2 (mov%L0,%6,%0), xops); + RET; + } + } + + output_asm_insn (AS2 (sub%L0,%2,%0), low); + output_asm_insn (AS2 (sbb%L0,%2,%0), high); + RET; +}") + (define_insn "subdi3" [(set (match_operand:DI 0 "general_operand" "=&r,ro,&r,o,o") (minus:DI (match_operand:DI 1 "general_operand" "0,0,roiF,riF,o") @@ -2704,33 +3182,75 @@ RET; }") -(define_insn "subsi3" - [(set (match_operand:SI 0 "general_operand" "=rm,r") - (minus:SI (match_operand:SI 1 "general_operand" "0,0") - (match_operand:SI 2 "general_operand" "ri,rm")))] +(define_expand "subsi3" + [(set (match_operand:SI 0 "nonimmediate_operand" "") + (minus:SI (match_operand:SI 1 "nonimmediate_operand" "") + (match_operand:SI 2 "general_operand" "")))] "" + "IX86_EXPAND_BINARY_OPERATOR (MINUS, SImode, operands);") + +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") + (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);") -(define_insn "subhi3" - [(set (match_operand:HI 0 "general_operand" "=rm,r") - (minus:HI (match_operand:HI 1 "general_operand" "0,0") - (match_operand:HI 2 "general_operand" "ri,rm")))] +(define_insn "" + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") + (minus:SI (match_operand:SI 1 "general_operand" "ri,rm") + (match_operand:SI 2 "nonimmediate_operand" "0,0")))] + "ix86_binary_operator_ok (MINUS, SImode, operands)" + "* return AS2 (sub%L0,%2,%0);") + +(define_expand "subhi3" + [(set (match_operand:HI 0 "general_operand" "") + (minus:HI (match_operand:HI 1 "nonimmediate_operand" "") + (match_operand:HI 2 "general_operand" "")))] "" + "IX86_EXPAND_BINARY_OPERATOR (MINUS, HImode, operands);") + +(define_insn "" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") + (minus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") + (match_operand:HI 2 "general_operand" "ri,rm")))] + "ix86_binary_operator_ok (MINUS, HImode, operands)" "* return AS2 (sub%W0,%2,%0);") -(define_insn "subqi3" - [(set (match_operand:QI 0 "general_operand" "=qm,q") - (minus:QI (match_operand:QI 1 "general_operand" "0,0") - (match_operand:QI 2 "general_operand" "qn,qmn")))] +(define_insn "" + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") + (minus:HI (match_operand:HI 1 "general_operand" "ri,rm") + (match_operand:HI 2 "nonimmediate_operand" "0,0")))] + "ix86_binary_operator_ok (MINUS, HImode, operands)" + "* return AS2 (sub%W0,%2,%0);") + +(define_expand "subqi3" + [(set (match_operand:QI 0 "general_operand" "") + (minus:QI (match_operand:QI 1 "general_operand" "") + (match_operand:QI 2 "general_operand" "")))] "" + "IX86_EXPAND_BINARY_OPERATOR (MINUS, QImode, operands);") + +(define_insn "" + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") + (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);") + +(define_insn "" + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q") + (minus:QI (match_operand:QI 1 "general_operand" "qn,qmn") + (match_operand:QI 2 "nonimmediate_operand" "0,0")))] + "ix86_binary_operator_ok (MINUS, QImode, operands)" "* return AS2 (sub%B0,%2,%0);") ;; The patterns that match these are at the end of this file. (define_expand "subxf3" [(set (match_operand:XF 0 "register_operand" "") - (minus:XF (match_operand:XF 1 "nonimmediate_operand" "") - (match_operand:XF 2 "nonimmediate_operand" "")))] + (minus:XF (match_operand:XF 1 "register_operand" "") + (match_operand:XF 2 "register_operand" "")))] "TARGET_80387" "") @@ -2751,22 +3271,15 @@ ;;- multiply instructions ;(define_insn "mulqi3" -; [(set (match_operand:QI 0 "general_operand" "=a") -; (mult:QI (match_operand:QI 1 "general_operand" "%0") -; (match_operand:QI 2 "general_operand" "qm")))] +; [(set (match_operand:QI 0 "register_operand" "=a") +; (mult:QI (match_operand:QI 1 "register_operand" "%0") +; (match_operand:QI 2 "nonimmediate_operand" "qm")))] ; "" ; "imul%B0 %2,%0") -(define_insn "" - [(set (match_operand:HI 0 "general_operand" "=r") - (mult:HI (match_operand:HI 1 "general_operand" "%0") - (match_operand:HI 2 "general_operand" "r")))] - "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80" - "* return AS2 (imul%W0,%2,%0);") - (define_insn "mulhi3" - [(set (match_operand:HI 0 "general_operand" "=r,r") - (mult:HI (match_operand:HI 1 "general_operand" "%0,rm") + [(set (match_operand:HI 0 "register_operand" "=r,r") + (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%0,rm") (match_operand:HI 2 "general_operand" "g,i")))] "" "* @@ -2779,16 +3292,9 @@ return AS3 (imul%W0,%2,%1,%0); }") -(define_insn "" - [(set (match_operand:SI 0 "general_operand" "=r") - (mult:SI (match_operand:SI 1 "general_operand" "%0") - (match_operand:SI 2 "general_operand" "r")))] - "GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) == 0x80" - "* return AS2 (imul%L0,%2,%0);") - (define_insn "mulsi3" - [(set (match_operand:SI 0 "general_operand" "=r,r") - (mult:SI (match_operand:SI 1 "general_operand" "%0,rm") + [(set (match_operand:SI 0 "register_operand" "=r,r") + (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm") (match_operand:SI 2 "general_operand" "g,i")))] "" "* @@ -2802,15 +3308,15 @@ }") (define_insn "umulqihi3" - [(set (match_operand:HI 0 "general_operand" "=a") - (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) + [(set (match_operand:HI 0 "register_operand" "=a") + (mult:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%0")) (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))] "" "mul%B0 %2") (define_insn "mulqihi3" - [(set (match_operand:HI 0 "general_operand" "=a") - (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0")) + [(set (match_operand:HI 0 "register_operand" "=a") + (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%0")) (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))] "" "imul%B0 %2") @@ -2851,21 +3357,21 @@ (define_expand "mulxf3" [(set (match_operand:XF 0 "register_operand" "") - (mult:XF (match_operand:XF 1 "nonimmediate_operand" "") - (match_operand:XF 2 "nonimmediate_operand" "")))] + (mult:XF (match_operand:XF 1 "register_operand" "") + (match_operand:XF 2 "register_operand" "")))] "TARGET_80387" "") (define_expand "muldf3" [(set (match_operand:DF 0 "register_operand" "") - (mult:DF (match_operand:DF 1 "nonimmediate_operand" "") + (mult:DF (match_operand:DF 1 "register_operand" "") (match_operand:DF 2 "nonimmediate_operand" "")))] "TARGET_80387" "") (define_expand "mulsf3" [(set (match_operand:SF 0 "register_operand" "") - (mult:SF (match_operand:SF 1 "nonimmediate_operand" "") + (mult:SF (match_operand:SF 1 "register_operand" "") (match_operand:SF 2 "nonimmediate_operand" "")))] "TARGET_80387" "") @@ -2873,16 +3379,16 @@ ;;- divide instructions (define_insn "divqi3" - [(set (match_operand:QI 0 "general_operand" "=a") - (div:QI (match_operand:HI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "qm")))] + [(set (match_operand:QI 0 "register_operand" "=a") + (div:QI (match_operand:HI 1 "register_operand" "0") + (match_operand:QI 2 "nonimmediate_operand" "qm")))] "" "idiv%B0 %2") (define_insn "udivqi3" - [(set (match_operand:QI 0 "general_operand" "=a") - (udiv:QI (match_operand:HI 1 "general_operand" "0") - (match_operand:QI 2 "general_operand" "qm")))] + [(set (match_operand:QI 0 "register_operand" "=a") + (udiv:QI (match_operand:HI 1 "register_operand" "0") + (match_operand:QI 2 "nonimmediate_operand" "qm")))] "" "div%B0 %2") @@ -2890,21 +3396,14 @@ (define_expand "divxf3" [(set (match_operand:XF 0 "register_operand" "") - (div:XF (match_operand:XF 1 "nonimmediate_operand" "") - (match_operand:XF 2 "nonimmediate_operand" "")))] - "TARGET_80387" - "") - -(define_expand "divdf3" - [(set (match_operand:DF 0 "register_operand" "") - (div:DF (match_operand:DF 1 "nonimmediate_operand" "") - (match_operand:DF 2 "nonimmediate_operand" "")))] + (div:XF (match_operand:XF 1 "register_operand" "") + (match_operand:XF 2 "register_operand" "")))] "TARGET_80387" "") (define_expand "divsf3" [(set (match_operand:SF 0 "register_operand" "") - (div:SF (match_operand:SF 1 "nonimmediate_operand" "") + (div:SF (match_operand:SF 1 "register_operand" "") (match_operand:SF 2 "nonimmediate_operand" "")))] "TARGET_80387" "") @@ -2914,7 +3413,7 @@ (define_insn "divmodsi4" [(set (match_operand:SI 0 "register_operand" "=a") (div:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "rm"))) + (match_operand:SI 2 "nonimmediate_operand" "rm"))) (set (match_operand:SI 3 "register_operand" "=&d") (mod:SI (match_dup 1) (match_dup 2)))] "" @@ -2931,7 +3430,7 @@ (define_insn "divmodhi4" [(set (match_operand:HI 0 "register_operand" "=a") (div:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "general_operand" "rm"))) + (match_operand:HI 2 "nonimmediate_operand" "rm"))) (set (match_operand:HI 3 "register_operand" "=&d") (mod:HI (match_dup 1) (match_dup 2)))] "" @@ -2941,7 +3440,7 @@ (define_insn "udivmodsi4" [(set (match_operand:SI 0 "register_operand" "=a") (udiv:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "general_operand" "rm"))) + (match_operand:SI 2 "nonimmediate_operand" "rm"))) (set (match_operand:SI 3 "register_operand" "=&d") (umod:SI (match_dup 1) (match_dup 2)))] "" @@ -2955,7 +3454,7 @@ (define_insn "udivmodhi4" [(set (match_operand:HI 0 "register_operand" "=a") (udiv:HI (match_operand:HI 1 "register_operand" "0") - (match_operand:HI 2 "general_operand" "rm"))) + (match_operand:HI 2 "nonimmediate_operand" "rm"))) (set (match_operand:HI 3 "register_operand" "=&d") (umod:HI (match_dup 1) (match_dup 2)))] "" @@ -2971,7 +3470,7 @@ (define_insn "" [(set (match_operand:SI 0 "register_operand" "=a") (udiv:DI (match_operand:DI 1 "register_operand" "a") - (match_operand:SI 2 "general_operand" "rm"))) + (match_operand:SI 2 "nonimmediate_operand" "rm"))) (set (match_operand:SI 3 "register_operand" "=d") (umod:SI (match_dup 1) (match_dup 2)))] "" @@ -2997,12 +3496,20 @@ ;; ??? What if we only change one byte of an offsettable memory reference? (define_insn "andsi3" - [(set (match_operand:SI 0 "general_operand" "=r,r,rm,r") - (and:SI (match_operand:SI 1 "general_operand" "%rm,qm,0,0") - (match_operand:SI 2 "general_operand" "L,K,ri,rm")))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") + (match_operand:SI 2 "general_operand" "ri,rm")))] "" "* { + if (!rtx_equal_p (operands[0], operands[1]) + && rtx_equal_p (operands[0], operands[2])) + { + rtx tmp; + tmp = operands[1]; + operands[1] = operands[2]; + operands[2] = tmp; + } if (GET_CODE (operands[2]) == CONST_INT && ! (GET_CODE (operands[0]) == MEM && MEM_VOLATILE_P (operands[0]))) { @@ -3076,8 +3583,8 @@ }") (define_insn "andhi3" - [(set (match_operand:HI 0 "general_operand" "=rm,r") - (and:HI (match_operand:HI 1 "general_operand" "%0,0") + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") + (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") (match_operand:HI 2 "general_operand" "ri,rm")))] "" "* @@ -3122,8 +3629,8 @@ }") (define_insn "andqi3" - [(set (match_operand:QI 0 "general_operand" "=qm,q") - (and:QI (match_operand:QI 1 "general_operand" "%0,0") + [(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);") @@ -3142,10 +3649,10 @@ "and%W0 %1,%0") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=q") + [(set (match_operand:SI 0 "register_operand" "=q") (and:SI (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")) - (match_operand:SI 2 "general_operand" "0")))] + (match_operand:SI 2 "register_operand" "0")))] "GET_CODE (operands[2]) == CONST_INT && (unsigned int) INTVAL (operands[2]) < (1 << GET_MODE_BITSIZE (QImode))" "and%L0 %1,%0") @@ -3156,8 +3663,8 @@ ;; ??? What if we only change one byte of an offsettable memory reference? (define_insn "iorsi3" - [(set (match_operand:SI 0 "general_operand" "=rm,r") - (ior:SI (match_operand:SI 1 "general_operand" "%0,0") + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "ri,rm")))] "" "* @@ -3192,8 +3699,8 @@ }") (define_insn "iorhi3" - [(set (match_operand:HI 0 "general_operand" "=rm,r") - (ior:HI (match_operand:HI 1 "general_operand" "%0,0") + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") + (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") (match_operand:HI 2 "general_operand" "ri,rm")))] "" "* @@ -3234,8 +3741,8 @@ }") (define_insn "iorqi3" - [(set (match_operand:QI 0 "general_operand" "=qm,q") - (ior:QI (match_operand:QI 1 "general_operand" "%0,0") + [(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);") @@ -3244,8 +3751,8 @@ ;; ??? What if we only change one byte of an offsettable memory reference? (define_insn "xorsi3" - [(set (match_operand:SI 0 "general_operand" "=rm,r") - (xor:SI (match_operand:SI 1 "general_operand" "%0,0") + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r") + (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") (match_operand:SI 2 "general_operand" "ri,rm")))] "" "* @@ -3280,8 +3787,8 @@ }") (define_insn "xorhi3" - [(set (match_operand:HI 0 "general_operand" "=rm,r") - (xor:HI (match_operand:HI 1 "general_operand" "%0,0") + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r") + (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0") (match_operand:HI 2 "general_operand" "ri,rm")))] "" "* @@ -3322,8 +3829,8 @@ }") (define_insn "xorqi3" - [(set (match_operand:QI 0 "general_operand" "=qm,q") - (xor:QI (match_operand:QI 1 "general_operand" "%0,0") + [(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);") @@ -3351,50 +3858,50 @@ }") (define_insn "negsi2" - [(set (match_operand:SI 0 "general_operand" "=rm") - (neg:SI (match_operand:SI 1 "general_operand" "0")))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] "" "neg%L0 %0") (define_insn "neghi2" - [(set (match_operand:HI 0 "general_operand" "=rm") - (neg:HI (match_operand:HI 1 "general_operand" "0")))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] "" "neg%W0 %0") (define_insn "negqi2" - [(set (match_operand:QI 0 "general_operand" "=qm") - (neg:QI (match_operand:QI 1 "general_operand" "0")))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") + (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))] "" "neg%B0 %0") (define_insn "negsf2" [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (match_operand:SF 1 "general_operand" "0")))] + (neg:SF (match_operand:SF 1 "register_operand" "0")))] "TARGET_80387" "fchs") (define_insn "negdf2" [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (match_operand:DF 1 "general_operand" "0")))] + (neg:DF (match_operand:DF 1 "register_operand" "0")))] "TARGET_80387" "fchs") (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))] + (neg:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))] "TARGET_80387" "fchs") (define_insn "negxf2" [(set (match_operand:XF 0 "register_operand" "=f") - (neg:XF (match_operand:XF 1 "general_operand" "0")))] + (neg:XF (match_operand:XF 1 "register_operand" "0")))] "TARGET_80387" "fchs") (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f") - (neg:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))] + (neg:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))] "TARGET_80387" "fchs") @@ -3402,44 +3909,48 @@ (define_insn "abssf2" [(set (match_operand:SF 0 "register_operand" "=f") - (abs:SF (match_operand:SF 1 "general_operand" "0")))] + (abs:SF (match_operand:SF 1 "register_operand" "0")))] "TARGET_80387" - "fabs") + "fabs" + [(set_attr "type" "fpop")]) (define_insn "absdf2" [(set (match_operand:DF 0 "register_operand" "=f") - (abs:DF (match_operand:DF 1 "general_operand" "0")))] + (abs:DF (match_operand:DF 1 "register_operand" "0")))] "TARGET_80387" - "fabs") + "fabs" + [(set_attr "type" "fpop")]) (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") - (abs:DF (float_extend:DF (match_operand:SF 1 "general_operand" "0"))))] + (abs:DF (float_extend:DF (match_operand:SF 1 "register_operand" "0"))))] "TARGET_80387" - "fabs") + "fabs" + [(set_attr "type" "fpop")]) (define_insn "absxf2" [(set (match_operand:XF 0 "register_operand" "=f") - (abs:XF (match_operand:XF 1 "general_operand" "0")))] + (abs:XF (match_operand:XF 1 "register_operand" "0")))] "TARGET_80387" - "fabs") + "fabs" + [(set_attr "type" "fpop")]) (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f") - (abs:XF (float_extend:XF (match_operand:DF 1 "general_operand" "0"))))] + (abs:XF (float_extend:XF (match_operand:DF 1 "register_operand" "0"))))] "TARGET_80387" - "fabs") + "fabs" + [(set_attr "type" "fpop")]) (define_insn "sqrtsf2" [(set (match_operand:SF 0 "register_operand" "=f") - (sqrt:SF (match_operand:SF 1 "general_operand" "0")))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + (sqrt:SF (match_operand:SF 1 "register_operand" "0")))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" "fsqrt") (define_insn "sqrtdf2" [(set (match_operand:DF 0 "register_operand" "=f") - (sqrt:DF (match_operand:DF 1 "general_operand" "0")))] + (sqrt:DF (match_operand:DF 1 "register_operand" "0")))] "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math) " "fsqrt") @@ -3447,14 +3958,13 @@ (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (sqrt:DF (float_extend:DF - (match_operand:SF 1 "general_operand" "0"))))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + (match_operand:SF 1 "register_operand" "0"))))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" "fsqrt") (define_insn "sqrtxf2" [(set (match_operand:XF 0 "register_operand" "=f") - (sqrt:XF (match_operand:XF 1 "general_operand" "0")))] + (sqrt:XF (match_operand:XF 1 "register_operand" "0")))] "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && (TARGET_IEEE_FP || flag_fast_math) " "fsqrt") @@ -3462,94 +3972,84 @@ (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f") (sqrt:XF (float_extend:XF - (match_operand:DF 1 "general_operand" "0"))))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + (match_operand:DF 1 "register_operand" "0"))))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" "fsqrt") (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f") (sqrt:XF (float_extend:XF - (match_operand:SF 1 "general_operand" "0"))))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + (match_operand:SF 1 "register_operand" "0"))))] + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387" "fsqrt") (define_insn "sindf2" [(set (match_operand:DF 0 "register_operand" "=f") (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" "fsin") (define_insn "sinsf2" [(set (match_operand:SF 0 "register_operand" "=f") (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 1))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" "fsin") (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (unspec:DF [(float_extend:DF (match_operand:SF 1 "register_operand" "0"))] 1))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" "fsin") (define_insn "sinxf2" [(set (match_operand:XF 0 "register_operand" "=f") (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 1))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" "fsin") (define_insn "cosdf2" [(set (match_operand:DF 0 "register_operand" "=f") (unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" "fcos") (define_insn "cossf2" [(set (match_operand:SF 0 "register_operand" "=f") (unspec:SF [(match_operand:SF 1 "register_operand" "0")] 2))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" "fcos") (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (unspec:DF [(float_extend:DF (match_operand:SF 1 "register_operand" "0"))] 2))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" "fcos") (define_insn "cosxf2" [(set (match_operand:XF 0 "register_operand" "=f") (unspec:XF [(match_operand:XF 1 "register_operand" "0")] 2))] - "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 - && (TARGET_IEEE_FP || flag_fast_math) " + "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math" "fcos") ;;- one complement instructions (define_insn "one_cmplsi2" - [(set (match_operand:SI 0 "general_operand" "=rm") - (not:SI (match_operand:SI 1 "general_operand" "0")))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))] "" "not%L0 %0") (define_insn "one_cmplhi2" - [(set (match_operand:HI 0 "general_operand" "=rm") - (not:HI (match_operand:HI 1 "general_operand" "0")))] + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))] "" "not%W0 %0") (define_insn "one_cmplqi2" - [(set (match_operand:QI 0 "general_operand" "=qm") - (not:QI (match_operand:QI 1 "general_operand" "0")))] + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") + (not:QI (match_operand:QI 1 "nonimmediate_operand" "0")))] "" "not%B0 %0") @@ -3674,8 +4174,8 @@ ;; is smaller - use leal for now unless the shift count is 1. (define_insn "ashlsi3" - [(set (match_operand:SI 0 "general_operand" "=r,rm") - (ashift:SI (match_operand:SI 1 "general_operand" "r,0") + [(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")))] "" "* @@ -3712,8 +4212,8 @@ }") (define_insn "ashlhi3" - [(set (match_operand:HI 0 "general_operand" "=rm") - (ashift:HI (match_operand:HI 1 "general_operand" "0") + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0") (match_operand:HI 2 "nonmemory_operand" "cI")))] "" "* @@ -3728,8 +4228,8 @@ }") (define_insn "ashlqi3" - [(set (match_operand:QI 0 "general_operand" "=qm") - (ashift:QI (match_operand:QI 1 "general_operand" "0") + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") + (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0") (match_operand:QI 2 "nonmemory_operand" "cI")))] "" "* @@ -3765,6 +4265,31 @@ DONE; }") +(define_insn "ashldi3_32" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m") + (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r") + (const_int 32)))] + "" + "* +{ + rtx low[2], high[2], xops[4]; + + split_di (operands, 2, low, high); + xops[0] = high[0]; + xops[1] = low[1]; + xops[2] = low[0]; + xops[3] = const0_rtx; + if (!rtx_equal_p (xops[0], xops[1])) + 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_insn "ashrdi3_const_int" [(set (match_operand:DI 0 "register_operand" "=&r") (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") @@ -3839,8 +4364,8 @@ }") (define_insn "ashrsi3" - [(set (match_operand:SI 0 "general_operand" "=rm") - (ashiftrt:SI (match_operand:SI 1 "general_operand" "0") + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") (match_operand:SI 2 "nonmemory_operand" "cI")))] "" "* @@ -3852,8 +4377,8 @@ }") (define_insn "ashrhi3" - [(set (match_operand:HI 0 "general_operand" "=rm") - (ashiftrt:HI (match_operand:HI 1 "general_operand" "0") + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") (match_operand:HI 2 "nonmemory_operand" "cI")))] "" "* @@ -3865,8 +4390,8 @@ }") (define_insn "ashrqi3" - [(set (match_operand:QI 0 "general_operand" "=qm") - (ashiftrt:QI (match_operand:QI 1 "general_operand" "0") + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") + (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") (match_operand:QI 2 "nonmemory_operand" "cI")))] "" "* @@ -3901,6 +4426,31 @@ DONE; }") +(define_insn "lshrdi3_32" + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,m") + (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "ro,r") + (const_int 32)))] + "" + "* +{ + rtx low[2], high[2], xops[4]; + + split_di (operands, 2, low, high); + xops[0] = low[0]; + xops[1] = high[1]; + xops[2] = high[0]; + xops[3] = const0_rtx; + if (!rtx_equal_p (xops[0], xops[1])) + 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_insn "lshrdi3_const_int" [(set (match_operand:DI 0 "register_operand" "=&r") (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") @@ -3974,8 +4524,8 @@ }") (define_insn "lshrsi3" - [(set (match_operand:SI 0 "general_operand" "=rm") - (lshiftrt:SI (match_operand:SI 1 "general_operand" "0") + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0") (match_operand:SI 2 "nonmemory_operand" "cI")))] "" "* @@ -3987,8 +4537,8 @@ }") (define_insn "lshrhi3" - [(set (match_operand:HI 0 "general_operand" "=rm") - (lshiftrt:HI (match_operand:HI 1 "general_operand" "0") + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0") (match_operand:HI 2 "nonmemory_operand" "cI")))] "" "* @@ -4000,8 +4550,8 @@ }") (define_insn "lshrqi3" - [(set (match_operand:QI 0 "general_operand" "=qm") - (lshiftrt:QI (match_operand:QI 1 "general_operand" "0") + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") + (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0") (match_operand:QI 2 "nonmemory_operand" "cI")))] "" "* @@ -4015,8 +4565,8 @@ ;;- rotate instructions (define_insn "rotlsi3" - [(set (match_operand:SI 0 "general_operand" "=rm") - (rotate:SI (match_operand:SI 1 "general_operand" "0") + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0") (match_operand:SI 2 "nonmemory_operand" "cI")))] "" "* @@ -4028,8 +4578,8 @@ }") (define_insn "rotlhi3" - [(set (match_operand:HI 0 "general_operand" "=rm") - (rotate:HI (match_operand:HI 1 "general_operand" "0") + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0") (match_operand:HI 2 "nonmemory_operand" "cI")))] "" "* @@ -4041,8 +4591,8 @@ }") (define_insn "rotlqi3" - [(set (match_operand:QI 0 "general_operand" "=qm") - (rotate:QI (match_operand:QI 1 "general_operand" "0") + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") + (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0") (match_operand:QI 2 "nonmemory_operand" "cI")))] "" "* @@ -4054,8 +4604,8 @@ }") (define_insn "rotrsi3" - [(set (match_operand:SI 0 "general_operand" "=rm") - (rotatert:SI (match_operand:SI 1 "general_operand" "0") + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") (match_operand:SI 2 "nonmemory_operand" "cI")))] "" "* @@ -4067,8 +4617,8 @@ }") (define_insn "rotrhi3" - [(set (match_operand:HI 0 "general_operand" "=rm") - (rotatert:HI (match_operand:HI 1 "general_operand" "0") + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") + (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0") (match_operand:HI 2 "nonmemory_operand" "cI")))] "" "* @@ -4080,8 +4630,8 @@ }") (define_insn "rotrqi3" - [(set (match_operand:QI 0 "general_operand" "=qm") - (rotatert:QI (match_operand:QI 1 "general_operand" "0") + [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") + (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0") (match_operand:QI 2 "nonmemory_operand" "cI")))] "" "* @@ -4098,9 +4648,9 @@ ;; %ah, %bh, %ch, %dh. (define_insn "insv" [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+&r") - (match_operand:SI 1 "general_operand" "i") - (match_operand:SI 2 "general_operand" "i")) - (match_operand:SI 3 "general_operand" "ri"))] + (match_operand:SI 1 "immediate_operand" "i") + (match_operand:SI 2 "immediate_operand" "i")) + (match_operand:SI 3 "nonmemory_operand" "ri"))] "" "* { @@ -4136,7 +4686,7 @@ [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "") (match_operand:SI 1 "immediate_operand" "") (match_operand:SI 2 "immediate_operand" "")) - (match_operand:QI 3 "general_operand" "ri"))] + (match_operand:QI 3 "nonmemory_operand" "ri"))] "" " { @@ -4179,9 +4729,9 @@ ;; General bit set and clear. (define_insn "" - [(set (zero_extract:SI (match_operand:SI 0 "general_operand" "+rm") + [(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+rm") (const_int 1) - (match_operand:SI 2 "general_operand" "r")) + (match_operand:SI 2 "register_operand" "r")) (match_operand:SI 3 "const_int_operand" "n"))] "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT" "* @@ -4197,10 +4747,10 @@ ;; Bit complement. See comments on previous pattern. ;; ??? Is this really worthwhile? (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (xor:SI (ashift:SI (const_int 1) - (match_operand:SI 1 "general_operand" "r")) - (match_operand:SI 2 "general_operand" "0")))] + (match_operand:SI 1 "register_operand" "r")) + (match_operand:SI 2 "nonimmediate_operand" "0")))] "TARGET_USE_BIT_TEST && GET_CODE (operands[1]) != CONST_INT" "* { @@ -4210,10 +4760,10 @@ }") (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=rm") - (xor:SI (match_operand:SI 1 "general_operand" "0") + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") + (xor:SI (match_operand:SI 1 "nonimmediate_operand" "0") (ashift:SI (const_int 1) - (match_operand:SI 2 "general_operand" "r"))))] + (match_operand:SI 2 "register_operand" "r"))))] "TARGET_USE_BIT_TEST && GET_CODE (operands[2]) != CONST_INT" "* { @@ -4235,7 +4785,7 @@ (define_insn "" [(set (cc0) (zero_extract (match_operand:SI 0 "register_operand" "r") (const_int 1) - (match_operand:SI 1 "general_operand" "r")))] + (match_operand:SI 1 "register_operand" "r")))] "GET_CODE (operands[1]) != CONST_INT" "* { @@ -4278,7 +4828,7 @@ ;; The CPU may access unspecified bytes around the actual target byte. (define_insn "" - [(set (cc0) (zero_extract (match_operand:QI 0 "general_operand" "rm") + [(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "rm") (match_operand:SI 1 "const_int_operand" "n") (match_operand:SI 2 "const_int_operand" "n")))] "GET_CODE (operands[0]) != MEM || ! MEM_VOLATILE_P (operands[0])" @@ -4559,6 +5109,14 @@ 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\"; }") @@ -4591,6 +5149,14 @@ 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\"; }") @@ -4616,6 +5182,13 @@ if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) 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); }") @@ -4660,6 +5233,13 @@ if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) 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\"); }") @@ -4703,7 +5283,13 @@ { if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) 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\"); }") @@ -4747,6 +5333,13 @@ { if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) 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); }") @@ -4784,6 +5377,13 @@ 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\"; }") @@ -4799,6 +5399,13 @@ 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\"; }") @@ -4813,7 +5420,13 @@ { if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) 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); }") @@ -4837,6 +5450,13 @@ { if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) 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 (je,%l0); + } OUTPUT_JUMP (\"jge %l0\", \"jae %l0\", \"jns %l0\"); }") @@ -4861,7 +5481,13 @@ { if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) 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\"); }") @@ -4886,6 +5512,13 @@ if (TARGET_IEEE_FP && (cc_prev_status.flags & CC_IN_80387)) 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); }") @@ -4907,7 +5540,7 @@ "jmp %l0") (define_insn "indirect_jump" - [(set (pc) (match_operand:SI 0 "general_operand" "rm"))] + [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))] "" "* { @@ -4935,7 +5568,7 @@ (define_insn "" [(set (pc) (if_then_else (match_operator 0 "arithmetic_comparison_operator" - [(plus:SI (match_operand:SI 1 "general_operand" "+r,m") + [(plus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m") (match_operand:SI 2 "general_operand" "rmi,ri")) (const_int 0)]) (label_ref (match_operand 3 "" "")) @@ -4962,7 +5595,7 @@ (define_insn "" [(set (pc) (if_then_else (match_operator 0 "arithmetic_comparison_operator" - [(minus:SI (match_operand:SI 1 "general_operand" "+r,m") + [(minus:SI (match_operand:SI 1 "nonimmediate_operand" "+r,m") (match_operand:SI 2 "general_operand" "rmi,ri")) (const_int 0)]) (label_ref (match_operand 3 "" "")) @@ -5072,7 +5705,7 @@ }") (define_insn "tablejump" - [(set (pc) (match_operand:SI 0 "general_operand" "rm")) + [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm")) (use (label_ref (match_operand 1 "" "")))] "" "* @@ -5537,7 +6170,7 @@ ;; code to handle zero-length compares. (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=&r") + [(set (match_operand:SI 0 "register_operand" "=&r") (compare:SI (mem:BLK (match_operand:SI 1 "address_operand" "S")) (mem:BLK (match_operand:SI 2 "address_operand" "D")))) (use (match_operand:SI 3 "register_operand" "c")) @@ -5548,7 +6181,7 @@ "" "* { - rtx xops[4], label; + rtx xops[2], label; label = gen_label_rtx (); @@ -5558,16 +6191,13 @@ output_asm_insn (\"je %l0\", &label); xops[0] = operands[0]; - xops[1] = gen_rtx (MEM, QImode, - gen_rtx (PLUS, SImode, operands[1], constm1_rtx)); - xops[2] = gen_rtx (MEM, QImode, - gen_rtx (PLUS, SImode, operands[2], constm1_rtx)); - xops[3] = operands[3]; - - output_asm_insn (AS2 (movz%B1%L0,%1,%0), xops); - output_asm_insn (AS2 (movz%B2%L3,%2,%3), xops); - - output_asm_insn (AS2 (sub%L0,%3,%0), xops); + xops[1] = const1_rtx; + output_asm_insn (AS2 (sbb%L0,%0,%0), xops); + if (QI_REG_P (xops[0])) + output_asm_insn (AS2 (or%B0,%1,%b0), xops); + else + output_asm_insn (AS2 (or%L0,%1,%0), xops); + ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", CODE_LABEL_NUMBER (label)); RET; }") @@ -5596,6 +6226,7 @@ return \"repz\;cmps%B2\"; }") + (define_expand "ffssi2" [(set (match_dup 2) (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" "")) @@ -5610,8 +6241,8 @@ ;; x86 implementations do this. (define_insn "" - [(set (match_operand:SI 0 "general_operand" "=&r") - (plus:SI (ffs:SI (match_operand:SI 1 "general_operand" "rm")) + [(set (match_operand:SI 0 "register_operand" "=&r") + (plus:SI (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")) (const_int -1)))] "" "* @@ -5656,8 +6287,8 @@ "operands[2] = gen_reg_rtx (HImode);") (define_insn "" - [(set (match_operand:HI 0 "general_operand" "=&r") - (plus:HI (ffs:HI (match_operand:SI 1 "general_operand" "rm")) + [(set (match_operand:HI 0 "register_operand" "=&r") + (plus:HI (ffs:HI (match_operand:SI 1 "nonimmediate_operand" "rm")) (const_int -1)))] "" "* @@ -5706,81 +6337,171 @@ [(match_operand:DF 1 "nonimmediate_operand" "0,fm") (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))] "TARGET_80387" - "* return output_387_binary_op (insn, operands);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (match_operand:DF 3 "is_div" "") + (const_string "fpdiv") + ] + (const_string "fpop") + ) + )]) (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (match_operator:DF 3 "binary_387_op" - [(float:DF (match_operand:SI 1 "general_operand" "rm")) - (match_operand:DF 2 "general_operand" "0")]))] + [(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);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (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 "nonimmediate_operand" "0,f") - (match_operand:XF 2 "nonimmediate_operand" "f,0")]))] + [(match_operand:XF 1 "register_operand" "0,f") + (match_operand:XF 2 "register_operand" "f,0")]))] "TARGET_80387" - "* return output_387_binary_op (insn, operands);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (match_operand:DF 3 "is_div" "") + (const_string "fpdiv") + ] + (const_string "fpop") + ) + )]) (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f") (match_operator:XF 3 "binary_387_op" - [(float:XF (match_operand:SI 1 "general_operand" "rm")) - (match_operand:XF 2 "general_operand" "0")]))] + [(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);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (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 "general_operand" "fm,0")) - (match_operand:XF 2 "general_operand" "0,f")]))] + [(float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) + (match_operand:XF 2 "register_operand" "0,f")]))] "TARGET_80387" - "* return output_387_binary_op (insn, operands);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (match_operand:DF 3 "is_div" "") + (const_string "fpdiv") + ] + (const_string "fpop") + ) + )]) (define_insn "" [(set (match_operand:XF 0 "register_operand" "=f") (match_operator:XF 3 "binary_387_op" - [(match_operand:XF 1 "general_operand" "0") - (float:XF (match_operand:SI 2 "general_operand" "rm"))]))] + [(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);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (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 "general_operand" "0,f") + [(match_operand:XF 1 "register_operand" "0,f") (float_extend:XF - (match_operand:SF 2 "general_operand" "fm,0"))]))] + (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] "TARGET_80387" - "* return output_387_binary_op (insn, operands);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (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" - [(float_extend:DF (match_operand:SF 1 "general_operand" "fm,0")) - (match_operand:DF 2 "general_operand" "0,f")]))] + [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0")) + (match_operand:DF 2 "register_operand" "0,f")]))] "TARGET_80387" - "* return output_387_binary_op (insn, operands);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (match_operand:DF 3 "is_div" "") + (const_string "fpdiv") + ] + (const_string "fpop") + ) + )]) (define_insn "" [(set (match_operand:DF 0 "register_operand" "=f") (match_operator:DF 3 "binary_387_op" - [(match_operand:DF 1 "general_operand" "0") - (float:DF (match_operand:SI 2 "general_operand" "rm"))]))] + [(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);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (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 "general_operand" "0,f") + [(match_operand:DF 1 "register_operand" "0,f") (float_extend:DF - (match_operand:SF 2 "general_operand" "fm,0"))]))] + (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))] "TARGET_80387" - "* return output_387_binary_op (insn, operands);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (match_operand:DF 3 "is_div" "") + (const_string "fpdiv") + ] + (const_string "fpop") + ) + )]) (define_insn "" [(set (match_operand:SF 0 "register_operand" "=f,f") @@ -5788,23 +6509,50 @@ [(match_operand:SF 1 "nonimmediate_operand" "0,fm") (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))] "TARGET_80387" - "* return output_387_binary_op (insn, operands);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (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" - [(float:SF (match_operand:SI 1 "general_operand" "rm")) - (match_operand:SF 2 "general_operand" "0")]))] + [(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);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (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 "general_operand" "0") - (float:SF (match_operand:SI 2 "general_operand" "rm"))]))] + [(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);") + "* return output_387_binary_op (insn, operands);" + [(set (attr "type") + (cond [(match_operand:DF 3 "is_mul" "") + (const_string "fpop") + (match_operand:DF 3 "is_div" "") + (const_string "fpdiv") + ] + (const_string "fpop") + ) + )]) (define_expand "strlensi" [(parallel [(set (match_dup 4) @@ -5888,6 +6636,14 @@ return \"repnz\;scas%B2\"; }") +(define_insn "strlensi_unroll" + [(set (match_operand:SI 0 "register_operand" "=&r,&r") + (unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "r,r")) + (match_operand:SI 2 "immediate_operand" "i,i")] 0)) + (clobber (match_scratch:SI 3 "=&q,&r"))] + "optimize > 1" + "* return output_strlen_unroll (operands);") + ;; the only difference between the following patterns is the register preference ;; on a pentium using a q-register saves one clock cycle per 4 characters -- 2.30.2