;; 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.
;; 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'.
+\f
+;; 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)
+
\f
;; "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
;; 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)
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"
(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)"
"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")
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;
}")
(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")))]
""
"*
{
(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")))]
""
"*
{
(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")))]
""
"*
{
(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")
(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")
;; 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"
"*
{
}")
(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)"
"*
}")
(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)"
"*
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));
}
}")
;; 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)"
"*
/* 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")
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));
}
}")
;; 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)"
"*
/* 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")
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));
}
}")
"* 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)"
"*
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)
;; 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);
#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
#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);
#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;
}")
\f
;;- 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")))]
""
"*
{
;; 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")))]
""
"*
{
}")
(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")))]
""
"*
{
}")
(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")))]
""
"*
{
return AS2 (movs%B0%L0,%1,%0);
#endif
}")
+
+\f
+;; 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;
+}")
+
+
\f
;; 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"
"*
{
}")
(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"
"*
{
}")
(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"
"*
{
}")
(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"
}")
(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"
;; 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"))
"* 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"))
"* 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"))
}")
(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"))
"* 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"))
"* 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"))
(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"
"*
{
(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"
"*
{
\f
;;- 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")
;; 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);
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);
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? */
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)
;
;(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")))]
; ""
; "*
;{
; 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"
"")
\f
;;- 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")
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"
"")
;;- 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")))]
""
"*
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")))]
""
"*
}")
(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")
(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"
"")
;;- 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")
(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"
"")
(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)))]
""
(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)))]
""
(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)))]
""
(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)))]
""
(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)))]
""
;; ??? 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])))
{
}")
(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")))]
""
"*
}")
(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);")
"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")
;; ??? 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")))]
""
"*
}")
(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")))]
""
"*
}")
(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);")
;; ??? 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")))]
""
"*
}")
(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")))]
""
"*
}")
(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);")
}")
(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")
\f
(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")
(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")
(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")
\f
;;- 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")
\f
;; 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")))]
""
"*
}")
(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")))]
""
"*
}")
(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")))]
""
"*
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")
}")
(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")))]
""
"*
}")
(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")))]
""
"*
}")
(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")))]
""
"*
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")
}")
(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")))]
""
"*
}")
(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")))]
""
"*
}")
(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")))]
""
"*
;;- 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")))]
""
"*
}")
(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")))]
""
"*
}")
(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")))]
""
"*
}")
(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")))]
""
"*
}")
(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")))]
""
"*
}")
(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")))]
""
"*
;; %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"))]
""
"*
{
[(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"))]
""
"
{
;; 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"
"*
;; 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"
"*
{
}")
(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"
"*
{
(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"
"*
{
;; 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])"
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\";
}")
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\";
}")
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);
}")
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\");
}")
{
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\");
}")
{
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);
}")
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\";
}")
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\";
}")
{
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);
}")
{
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\");
}")
{
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\");
}")
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);
}")
"jmp %l0")
(define_insn "indirect_jump"
- [(set (pc) (match_operand:SI 0 "general_operand" "rm"))]
+ [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
""
"*
{
(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 "" ""))
(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 "" ""))
}")
(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 "" "")))]
""
"*
;; 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"))
""
"*
{
- rtx xops[4], label;
+ rtx xops[2], label;
label = gen_label_rtx ();
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;
}")
return \"repz\;cmps%B2\";
}")
+\f
(define_expand "ffssi2"
[(set (match_dup 2)
(plus:SI (ffs:SI (match_operand:SI 1 "general_operand" ""))
;; 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)))]
""
"*
"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)))]
""
"*
[(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")
[(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")
+ )
+ )])
\f
(define_expand "strlensi"
[(parallel [(set (match_dup 4)
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