1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
73 (UNSPEC_TLS_LD_BASE 17)
75 ; Other random patterns
85 ; For SSE/MMX support:
86 (UNSPEC_FIX_NOTRUNC 30)
94 (UNSPEC_NOP 38) ; prevents combiner cleverness
105 ; Generic math support
107 (UNSPEC_IEEE_MIN 51) ; not commutative
108 (UNSPEC_IEEE_MAX 52) ; not commutative
121 (UNSPEC_FRNDINT_FLOOR 70)
122 (UNSPEC_FRNDINT_CEIL 71)
123 (UNSPEC_FRNDINT_TRUNC 72)
124 (UNSPEC_FRNDINT_MASK_PM 73)
125 (UNSPEC_FIST_FLOOR 74)
126 (UNSPEC_FIST_CEIL 75)
128 ; x87 Double output FP
129 (UNSPEC_SINCOS_COS 80)
130 (UNSPEC_SINCOS_SIN 81)
133 (UNSPEC_XTRACT_FRACT 84)
134 (UNSPEC_XTRACT_EXP 85)
135 (UNSPEC_FSCALE_FRACT 86)
136 (UNSPEC_FSCALE_EXP 87)
144 [(UNSPECV_BLOCKAGE 0)
145 (UNSPECV_STACK_PROBE 1)
156 ;; Registers by name.
165 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
168 ;; In C guard expressions, put expressions which may be compile-time
169 ;; constants first. This allows for better optimization. For
170 ;; example, write "TARGET_64BIT && reload_completed", not
171 ;; "reload_completed && TARGET_64BIT".
174 ;; Processor type. This attribute must exactly match the processor_type
175 ;; enumeration in i386.h.
176 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona"
177 (const (symbol_ref "ix86_tune")))
179 ;; A basic instruction type. Refinements due to arguments to be
180 ;; provided in other attributes.
183 alu,alu1,negnot,imov,imovx,lea,
184 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
185 icmp,test,ibr,setcc,icmov,
186 push,pop,call,callv,leave,
188 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
189 sselog,sselog1,sseiadd,sseishft,sseimul,
190 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
191 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
192 (const_string "other"))
194 ;; Main data type used by the insn
196 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
197 (const_string "unknown"))
199 ;; The CPU unit operations uses.
200 (define_attr "unit" "integer,i387,sse,mmx,unknown"
201 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
202 (const_string "i387")
203 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
204 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
206 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
208 (eq_attr "type" "other")
209 (const_string "unknown")]
210 (const_string "integer")))
212 ;; The (bounding maximum) length of an instruction immediate.
213 (define_attr "length_immediate" ""
214 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
216 (eq_attr "unit" "i387,sse,mmx")
218 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
220 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
221 (eq_attr "type" "imov,test")
222 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
223 (eq_attr "type" "call")
224 (if_then_else (match_operand 0 "constant_call_address_operand" "")
227 (eq_attr "type" "callv")
228 (if_then_else (match_operand 1 "constant_call_address_operand" "")
231 ;; We don't know the size before shorten_branches. Expect
232 ;; the instruction to fit for better scheduling.
233 (eq_attr "type" "ibr")
236 (symbol_ref "/* Update immediate_length and other attributes! */
239 ;; The (bounding maximum) length of an instruction address.
240 (define_attr "length_address" ""
241 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
243 (and (eq_attr "type" "call")
244 (match_operand 0 "constant_call_address_operand" ""))
246 (and (eq_attr "type" "callv")
247 (match_operand 1 "constant_call_address_operand" ""))
250 (symbol_ref "ix86_attr_length_address_default (insn)")))
252 ;; Set when length prefix is used.
253 (define_attr "prefix_data16" ""
254 (if_then_else (ior (eq_attr "mode" "HI")
255 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
259 ;; Set when string REP prefix is used.
260 (define_attr "prefix_rep" ""
261 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
265 ;; Set when 0f opcode prefix is used.
266 (define_attr "prefix_0f" ""
268 (ior (eq_attr "type" "imovx,setcc,icmov")
269 (eq_attr "unit" "sse,mmx"))
273 ;; Set when REX opcode prefix is used.
274 (define_attr "prefix_rex" ""
275 (cond [(and (eq_attr "mode" "DI")
276 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
278 (and (eq_attr "mode" "QI")
279 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
282 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
288 ;; Set when modrm byte is used.
289 (define_attr "modrm" ""
290 (cond [(eq_attr "type" "str,cld,leave")
292 (eq_attr "unit" "i387")
294 (and (eq_attr "type" "incdec")
295 (ior (match_operand:SI 1 "register_operand" "")
296 (match_operand:HI 1 "register_operand" "")))
298 (and (eq_attr "type" "push")
299 (not (match_operand 1 "memory_operand" "")))
301 (and (eq_attr "type" "pop")
302 (not (match_operand 0 "memory_operand" "")))
304 (and (eq_attr "type" "imov")
305 (and (match_operand 0 "register_operand" "")
306 (match_operand 1 "immediate_operand" "")))
308 (and (eq_attr "type" "call")
309 (match_operand 0 "constant_call_address_operand" ""))
311 (and (eq_attr "type" "callv")
312 (match_operand 1 "constant_call_address_operand" ""))
317 ;; The (bounding maximum) length of an instruction in bytes.
318 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
319 ;; Later we may want to split them and compute proper length as for
321 (define_attr "length" ""
322 (cond [(eq_attr "type" "other,multi,fistp,frndint")
324 (eq_attr "type" "fcmp")
326 (eq_attr "unit" "i387")
328 (plus (attr "prefix_data16")
329 (attr "length_address")))]
330 (plus (plus (attr "modrm")
331 (plus (attr "prefix_0f")
332 (plus (attr "prefix_rex")
334 (plus (attr "prefix_rep")
335 (plus (attr "prefix_data16")
336 (plus (attr "length_immediate")
337 (attr "length_address")))))))
339 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
340 ;; `store' if there is a simple memory reference therein, or `unknown'
341 ;; if the instruction is complex.
343 (define_attr "memory" "none,load,store,both,unknown"
344 (cond [(eq_attr "type" "other,multi,str")
345 (const_string "unknown")
346 (eq_attr "type" "lea,fcmov,fpspc,cld")
347 (const_string "none")
348 (eq_attr "type" "fistp,leave")
349 (const_string "both")
350 (eq_attr "type" "frndint")
351 (const_string "load")
352 (eq_attr "type" "push")
353 (if_then_else (match_operand 1 "memory_operand" "")
354 (const_string "both")
355 (const_string "store"))
356 (eq_attr "type" "pop")
357 (if_then_else (match_operand 0 "memory_operand" "")
358 (const_string "both")
359 (const_string "load"))
360 (eq_attr "type" "setcc")
361 (if_then_else (match_operand 0 "memory_operand" "")
362 (const_string "store")
363 (const_string "none"))
364 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
365 (if_then_else (ior (match_operand 0 "memory_operand" "")
366 (match_operand 1 "memory_operand" ""))
367 (const_string "load")
368 (const_string "none"))
369 (eq_attr "type" "ibr")
370 (if_then_else (match_operand 0 "memory_operand" "")
371 (const_string "load")
372 (const_string "none"))
373 (eq_attr "type" "call")
374 (if_then_else (match_operand 0 "constant_call_address_operand" "")
375 (const_string "none")
376 (const_string "load"))
377 (eq_attr "type" "callv")
378 (if_then_else (match_operand 1 "constant_call_address_operand" "")
379 (const_string "none")
380 (const_string "load"))
381 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
382 (match_operand 1 "memory_operand" ""))
383 (const_string "both")
384 (and (match_operand 0 "memory_operand" "")
385 (match_operand 1 "memory_operand" ""))
386 (const_string "both")
387 (match_operand 0 "memory_operand" "")
388 (const_string "store")
389 (match_operand 1 "memory_operand" "")
390 (const_string "load")
392 "!alu1,negnot,ishift1,
393 imov,imovx,icmp,test,
395 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
396 mmx,mmxmov,mmxcmp,mmxcvt")
397 (match_operand 2 "memory_operand" ""))
398 (const_string "load")
399 (and (eq_attr "type" "icmov")
400 (match_operand 3 "memory_operand" ""))
401 (const_string "load")
403 (const_string "none")))
405 ;; Indicates if an instruction has both an immediate and a displacement.
407 (define_attr "imm_disp" "false,true,unknown"
408 (cond [(eq_attr "type" "other,multi")
409 (const_string "unknown")
410 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
411 (and (match_operand 0 "memory_displacement_operand" "")
412 (match_operand 1 "immediate_operand" "")))
413 (const_string "true")
414 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
415 (and (match_operand 0 "memory_displacement_operand" "")
416 (match_operand 2 "immediate_operand" "")))
417 (const_string "true")
419 (const_string "false")))
421 ;; Indicates if an FP operation has an integer source.
423 (define_attr "fp_int_src" "false,true"
424 (const_string "false"))
426 ;; Defines rounding mode of an FP operation.
428 (define_attr "i387_cw" "floor,ceil,trunc,mask_pm,uninitialized,any"
429 (const_string "any"))
431 ;; Describe a user's asm statement.
432 (define_asm_attributes
433 [(set_attr "length" "128")
434 (set_attr "type" "multi")])
436 ;; All x87 floating point modes
437 (define_mode_macro X87MODEF [SF DF XF])
439 ;; All integer modes handled by x87 fisttp operator.
440 (define_mode_macro X87MODEI [HI SI DI])
442 ;; All integer modes handled by integer x87 operators.
443 (define_mode_macro X87MODEI12 [HI SI])
445 ;; All SSE floating point modes
446 (define_mode_macro SSEMODEF [SF DF])
448 ;; All integer modes handled by SSE cvtts?2si* operators.
449 (define_mode_macro SSEMODEI24 [SI DI])
452 ;; Scheduling descriptions
454 (include "pentium.md")
457 (include "athlon.md")
460 ;; Operand and operator predicates
462 (include "predicates.md")
465 ;; Compare instructions.
467 ;; All compare insns have expanders that save the operands away without
468 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
469 ;; after the cmp) will actually emit the cmpM.
471 (define_expand "cmpdi"
472 [(set (reg:CC FLAGS_REG)
473 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
474 (match_operand:DI 1 "x86_64_general_operand" "")))]
477 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
478 operands[0] = force_reg (DImode, operands[0]);
479 ix86_compare_op0 = operands[0];
480 ix86_compare_op1 = operands[1];
484 (define_expand "cmpsi"
485 [(set (reg:CC FLAGS_REG)
486 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
487 (match_operand:SI 1 "general_operand" "")))]
490 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
491 operands[0] = force_reg (SImode, operands[0]);
492 ix86_compare_op0 = operands[0];
493 ix86_compare_op1 = operands[1];
497 (define_expand "cmphi"
498 [(set (reg:CC FLAGS_REG)
499 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
500 (match_operand:HI 1 "general_operand" "")))]
503 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
504 operands[0] = force_reg (HImode, operands[0]);
505 ix86_compare_op0 = operands[0];
506 ix86_compare_op1 = operands[1];
510 (define_expand "cmpqi"
511 [(set (reg:CC FLAGS_REG)
512 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
513 (match_operand:QI 1 "general_operand" "")))]
516 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
517 operands[0] = force_reg (QImode, operands[0]);
518 ix86_compare_op0 = operands[0];
519 ix86_compare_op1 = operands[1];
523 (define_insn "cmpdi_ccno_1_rex64"
524 [(set (reg FLAGS_REG)
525 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
526 (match_operand:DI 1 "const0_operand" "n,n")))]
527 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
529 test{q}\t{%0, %0|%0, %0}
530 cmp{q}\t{%1, %0|%0, %1}"
531 [(set_attr "type" "test,icmp")
532 (set_attr "length_immediate" "0,1")
533 (set_attr "mode" "DI")])
535 (define_insn "*cmpdi_minus_1_rex64"
536 [(set (reg FLAGS_REG)
537 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
538 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
540 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
541 "cmp{q}\t{%1, %0|%0, %1}"
542 [(set_attr "type" "icmp")
543 (set_attr "mode" "DI")])
545 (define_expand "cmpdi_1_rex64"
546 [(set (reg:CC FLAGS_REG)
547 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
548 (match_operand:DI 1 "general_operand" "")))]
552 (define_insn "cmpdi_1_insn_rex64"
553 [(set (reg FLAGS_REG)
554 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
555 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
556 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
557 "cmp{q}\t{%1, %0|%0, %1}"
558 [(set_attr "type" "icmp")
559 (set_attr "mode" "DI")])
562 (define_insn "*cmpsi_ccno_1"
563 [(set (reg FLAGS_REG)
564 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
565 (match_operand:SI 1 "const0_operand" "n,n")))]
566 "ix86_match_ccmode (insn, CCNOmode)"
568 test{l}\t{%0, %0|%0, %0}
569 cmp{l}\t{%1, %0|%0, %1}"
570 [(set_attr "type" "test,icmp")
571 (set_attr "length_immediate" "0,1")
572 (set_attr "mode" "SI")])
574 (define_insn "*cmpsi_minus_1"
575 [(set (reg FLAGS_REG)
576 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
577 (match_operand:SI 1 "general_operand" "ri,mr"))
579 "ix86_match_ccmode (insn, CCGOCmode)"
580 "cmp{l}\t{%1, %0|%0, %1}"
581 [(set_attr "type" "icmp")
582 (set_attr "mode" "SI")])
584 (define_expand "cmpsi_1"
585 [(set (reg:CC FLAGS_REG)
586 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
587 (match_operand:SI 1 "general_operand" "ri,mr")))]
591 (define_insn "*cmpsi_1_insn"
592 [(set (reg FLAGS_REG)
593 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
594 (match_operand:SI 1 "general_operand" "ri,mr")))]
595 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
596 && ix86_match_ccmode (insn, CCmode)"
597 "cmp{l}\t{%1, %0|%0, %1}"
598 [(set_attr "type" "icmp")
599 (set_attr "mode" "SI")])
601 (define_insn "*cmphi_ccno_1"
602 [(set (reg FLAGS_REG)
603 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
604 (match_operand:HI 1 "const0_operand" "n,n")))]
605 "ix86_match_ccmode (insn, CCNOmode)"
607 test{w}\t{%0, %0|%0, %0}
608 cmp{w}\t{%1, %0|%0, %1}"
609 [(set_attr "type" "test,icmp")
610 (set_attr "length_immediate" "0,1")
611 (set_attr "mode" "HI")])
613 (define_insn "*cmphi_minus_1"
614 [(set (reg FLAGS_REG)
615 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
616 (match_operand:HI 1 "general_operand" "ri,mr"))
618 "ix86_match_ccmode (insn, CCGOCmode)"
619 "cmp{w}\t{%1, %0|%0, %1}"
620 [(set_attr "type" "icmp")
621 (set_attr "mode" "HI")])
623 (define_insn "*cmphi_1"
624 [(set (reg FLAGS_REG)
625 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
626 (match_operand:HI 1 "general_operand" "ri,mr")))]
627 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628 && ix86_match_ccmode (insn, CCmode)"
629 "cmp{w}\t{%1, %0|%0, %1}"
630 [(set_attr "type" "icmp")
631 (set_attr "mode" "HI")])
633 (define_insn "*cmpqi_ccno_1"
634 [(set (reg FLAGS_REG)
635 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
636 (match_operand:QI 1 "const0_operand" "n,n")))]
637 "ix86_match_ccmode (insn, CCNOmode)"
639 test{b}\t{%0, %0|%0, %0}
640 cmp{b}\t{$0, %0|%0, 0}"
641 [(set_attr "type" "test,icmp")
642 (set_attr "length_immediate" "0,1")
643 (set_attr "mode" "QI")])
645 (define_insn "*cmpqi_1"
646 [(set (reg FLAGS_REG)
647 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
648 (match_operand:QI 1 "general_operand" "qi,mq")))]
649 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
650 && ix86_match_ccmode (insn, CCmode)"
651 "cmp{b}\t{%1, %0|%0, %1}"
652 [(set_attr "type" "icmp")
653 (set_attr "mode" "QI")])
655 (define_insn "*cmpqi_minus_1"
656 [(set (reg FLAGS_REG)
657 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
658 (match_operand:QI 1 "general_operand" "qi,mq"))
660 "ix86_match_ccmode (insn, CCGOCmode)"
661 "cmp{b}\t{%1, %0|%0, %1}"
662 [(set_attr "type" "icmp")
663 (set_attr "mode" "QI")])
665 (define_insn "*cmpqi_ext_1"
666 [(set (reg FLAGS_REG)
668 (match_operand:QI 0 "general_operand" "Qm")
671 (match_operand 1 "ext_register_operand" "Q")
674 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
675 "cmp{b}\t{%h1, %0|%0, %h1}"
676 [(set_attr "type" "icmp")
677 (set_attr "mode" "QI")])
679 (define_insn "*cmpqi_ext_1_rex64"
680 [(set (reg FLAGS_REG)
682 (match_operand:QI 0 "register_operand" "Q")
685 (match_operand 1 "ext_register_operand" "Q")
688 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
689 "cmp{b}\t{%h1, %0|%0, %h1}"
690 [(set_attr "type" "icmp")
691 (set_attr "mode" "QI")])
693 (define_insn "*cmpqi_ext_2"
694 [(set (reg FLAGS_REG)
698 (match_operand 0 "ext_register_operand" "Q")
701 (match_operand:QI 1 "const0_operand" "n")))]
702 "ix86_match_ccmode (insn, CCNOmode)"
704 [(set_attr "type" "test")
705 (set_attr "length_immediate" "0")
706 (set_attr "mode" "QI")])
708 (define_expand "cmpqi_ext_3"
709 [(set (reg:CC FLAGS_REG)
713 (match_operand 0 "ext_register_operand" "")
716 (match_operand:QI 1 "general_operand" "")))]
720 (define_insn "cmpqi_ext_3_insn"
721 [(set (reg FLAGS_REG)
725 (match_operand 0 "ext_register_operand" "Q")
728 (match_operand:QI 1 "general_operand" "Qmn")))]
729 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730 "cmp{b}\t{%1, %h0|%h0, %1}"
731 [(set_attr "type" "icmp")
732 (set_attr "mode" "QI")])
734 (define_insn "cmpqi_ext_3_insn_rex64"
735 [(set (reg FLAGS_REG)
739 (match_operand 0 "ext_register_operand" "Q")
742 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
743 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744 "cmp{b}\t{%1, %h0|%h0, %1}"
745 [(set_attr "type" "icmp")
746 (set_attr "mode" "QI")])
748 (define_insn "*cmpqi_ext_4"
749 [(set (reg FLAGS_REG)
753 (match_operand 0 "ext_register_operand" "Q")
758 (match_operand 1 "ext_register_operand" "Q")
761 "ix86_match_ccmode (insn, CCmode)"
762 "cmp{b}\t{%h1, %h0|%h0, %h1}"
763 [(set_attr "type" "icmp")
764 (set_attr "mode" "QI")])
766 ;; These implement float point compares.
767 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
768 ;; which would allow mix and match FP modes on the compares. Which is what
769 ;; the old patterns did, but with many more of them.
771 (define_expand "cmpxf"
772 [(set (reg:CC FLAGS_REG)
773 (compare:CC (match_operand:XF 0 "cmp_fp_expander_operand" "")
774 (match_operand:XF 1 "cmp_fp_expander_operand" "")))]
777 ix86_compare_op0 = operands[0];
778 ix86_compare_op1 = operands[1];
782 (define_expand "cmpdf"
783 [(set (reg:CC FLAGS_REG)
784 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
785 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
786 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
788 ix86_compare_op0 = operands[0];
789 ix86_compare_op1 = operands[1];
793 (define_expand "cmpsf"
794 [(set (reg:CC FLAGS_REG)
795 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
796 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
797 "TARGET_80387 || TARGET_SSE_MATH"
799 ix86_compare_op0 = operands[0];
800 ix86_compare_op1 = operands[1];
804 ;; FP compares, step 1:
805 ;; Set the FP condition codes.
807 ;; CCFPmode compare with exceptions
808 ;; CCFPUmode compare with no exceptions
810 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
811 ;; used to manage the reg stack popping would not be preserved.
813 (define_insn "*cmpfp_0_sf"
814 [(set (match_operand:HI 0 "register_operand" "=a")
817 (match_operand:SF 1 "register_operand" "f")
818 (match_operand:SF 2 "const0_operand" "X"))]
821 "* return output_fp_compare (insn, operands, 0, 0);"
822 [(set_attr "type" "multi")
823 (set_attr "mode" "SF")])
825 (define_insn "*cmpfp_0_df"
826 [(set (match_operand:HI 0 "register_operand" "=a")
829 (match_operand:DF 1 "register_operand" "f")
830 (match_operand:DF 2 "const0_operand" "X"))]
833 "* return output_fp_compare (insn, operands, 0, 0);"
834 [(set_attr "type" "multi")
835 (set_attr "mode" "DF")])
837 (define_insn "*cmpfp_0_xf"
838 [(set (match_operand:HI 0 "register_operand" "=a")
841 (match_operand:XF 1 "register_operand" "f")
842 (match_operand:XF 2 "const0_operand" "X"))]
845 "* return output_fp_compare (insn, operands, 0, 0);"
846 [(set_attr "type" "multi")
847 (set_attr "mode" "XF")])
849 (define_insn "*cmpfp_sf"
850 [(set (match_operand:HI 0 "register_operand" "=a")
853 (match_operand:SF 1 "register_operand" "f")
854 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
857 "* return output_fp_compare (insn, operands, 0, 0);"
858 [(set_attr "type" "multi")
859 (set_attr "mode" "SF")])
861 (define_insn "*cmpfp_df"
862 [(set (match_operand:HI 0 "register_operand" "=a")
865 (match_operand:DF 1 "register_operand" "f")
866 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
869 "* return output_fp_compare (insn, operands, 0, 0);"
870 [(set_attr "type" "multi")
871 (set_attr "mode" "DF")])
873 (define_insn "*cmpfp_xf"
874 [(set (match_operand:HI 0 "register_operand" "=a")
877 (match_operand:XF 1 "register_operand" "f")
878 (match_operand:XF 2 "register_operand" "f"))]
881 "* return output_fp_compare (insn, operands, 0, 0);"
882 [(set_attr "type" "multi")
883 (set_attr "mode" "XF")])
885 (define_insn "*cmpfp_u"
886 [(set (match_operand:HI 0 "register_operand" "=a")
889 (match_operand 1 "register_operand" "f")
890 (match_operand 2 "register_operand" "f"))]
893 && FLOAT_MODE_P (GET_MODE (operands[1]))
894 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
895 "* return output_fp_compare (insn, operands, 0, 1);"
896 [(set_attr "type" "multi")
898 (cond [(match_operand:SF 1 "" "")
900 (match_operand:DF 1 "" "")
903 (const_string "XF")))])
905 (define_insn "*cmpfp_<mode>"
906 [(set (match_operand:HI 0 "register_operand" "=a")
909 (match_operand 1 "register_operand" "f")
910 (match_operator 3 "float_operator"
911 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
913 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
914 && FLOAT_MODE_P (GET_MODE (operands[1]))
915 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
916 "* return output_fp_compare (insn, operands, 0, 0);"
917 [(set_attr "type" "multi")
918 (set_attr "fp_int_src" "true")
919 (set_attr "mode" "<MODE>")])
921 ;; FP compares, step 2
922 ;; Move the fpsw to ax.
924 (define_insn "x86_fnstsw_1"
925 [(set (match_operand:HI 0 "register_operand" "=a")
926 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
929 [(set_attr "length" "2")
930 (set_attr "mode" "SI")
931 (set_attr "unit" "i387")])
933 ;; FP compares, step 3
934 ;; Get ax into flags, general case.
936 (define_insn "x86_sahf_1"
937 [(set (reg:CC FLAGS_REG)
938 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
941 [(set_attr "length" "1")
942 (set_attr "athlon_decode" "vector")
943 (set_attr "mode" "SI")])
945 ;; Pentium Pro can do steps 1 through 3 in one go.
947 (define_insn "*cmpfp_i_mixed"
948 [(set (reg:CCFP FLAGS_REG)
949 (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
950 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
952 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
953 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
954 "* return output_fp_compare (insn, operands, 1, 0);"
955 [(set_attr "type" "fcmp,ssecomi")
957 (if_then_else (match_operand:SF 1 "" "")
959 (const_string "DF")))
960 (set_attr "athlon_decode" "vector")])
962 (define_insn "*cmpfp_i_sse"
963 [(set (reg:CCFP FLAGS_REG)
964 (compare:CCFP (match_operand 0 "register_operand" "x")
965 (match_operand 1 "nonimmediate_operand" "xm")))]
967 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
968 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
969 "* return output_fp_compare (insn, operands, 1, 0);"
970 [(set_attr "type" "ssecomi")
972 (if_then_else (match_operand:SF 1 "" "")
974 (const_string "DF")))
975 (set_attr "athlon_decode" "vector")])
977 (define_insn "*cmpfp_i_i387"
978 [(set (reg:CCFP FLAGS_REG)
979 (compare:CCFP (match_operand 0 "register_operand" "f")
980 (match_operand 1 "register_operand" "f")))]
981 "TARGET_80387 && TARGET_CMOVE
982 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
983 && FLOAT_MODE_P (GET_MODE (operands[0]))
984 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
985 "* return output_fp_compare (insn, operands, 1, 0);"
986 [(set_attr "type" "fcmp")
988 (cond [(match_operand:SF 1 "" "")
990 (match_operand:DF 1 "" "")
993 (const_string "XF")))
994 (set_attr "athlon_decode" "vector")])
996 (define_insn "*cmpfp_iu_mixed"
997 [(set (reg:CCFPU FLAGS_REG)
998 (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
999 (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
1000 "TARGET_MIX_SSE_I387
1001 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1002 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1003 "* return output_fp_compare (insn, operands, 1, 1);"
1004 [(set_attr "type" "fcmp,ssecomi")
1006 (if_then_else (match_operand:SF 1 "" "")
1008 (const_string "DF")))
1009 (set_attr "athlon_decode" "vector")])
1011 (define_insn "*cmpfp_iu_sse"
1012 [(set (reg:CCFPU FLAGS_REG)
1013 (compare:CCFPU (match_operand 0 "register_operand" "x")
1014 (match_operand 1 "nonimmediate_operand" "xm")))]
1016 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1017 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1018 "* return output_fp_compare (insn, operands, 1, 1);"
1019 [(set_attr "type" "ssecomi")
1021 (if_then_else (match_operand:SF 1 "" "")
1023 (const_string "DF")))
1024 (set_attr "athlon_decode" "vector")])
1026 (define_insn "*cmpfp_iu_387"
1027 [(set (reg:CCFPU FLAGS_REG)
1028 (compare:CCFPU (match_operand 0 "register_operand" "f")
1029 (match_operand 1 "register_operand" "f")))]
1030 "TARGET_80387 && TARGET_CMOVE
1031 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1032 && FLOAT_MODE_P (GET_MODE (operands[0]))
1033 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1034 "* return output_fp_compare (insn, operands, 1, 1);"
1035 [(set_attr "type" "fcmp")
1037 (cond [(match_operand:SF 1 "" "")
1039 (match_operand:DF 1 "" "")
1042 (const_string "XF")))
1043 (set_attr "athlon_decode" "vector")])
1045 ;; Move instructions.
1047 ;; General case of fullword move.
1049 (define_expand "movsi"
1050 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1051 (match_operand:SI 1 "general_operand" ""))]
1053 "ix86_expand_move (SImode, operands); DONE;")
1055 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1058 ;; %%% We don't use a post-inc memory reference because x86 is not a
1059 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1060 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1061 ;; targets without our curiosities, and it is just as easy to represent
1062 ;; this differently.
1064 (define_insn "*pushsi2"
1065 [(set (match_operand:SI 0 "push_operand" "=<")
1066 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1069 [(set_attr "type" "push")
1070 (set_attr "mode" "SI")])
1072 ;; For 64BIT abi we always round up to 8 bytes.
1073 (define_insn "*pushsi2_rex64"
1074 [(set (match_operand:SI 0 "push_operand" "=X")
1075 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1078 [(set_attr "type" "push")
1079 (set_attr "mode" "SI")])
1081 (define_insn "*pushsi2_prologue"
1082 [(set (match_operand:SI 0 "push_operand" "=<")
1083 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1084 (clobber (mem:BLK (scratch)))]
1087 [(set_attr "type" "push")
1088 (set_attr "mode" "SI")])
1090 (define_insn "*popsi1_epilogue"
1091 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1092 (mem:SI (reg:SI SP_REG)))
1093 (set (reg:SI SP_REG)
1094 (plus:SI (reg:SI SP_REG) (const_int 4)))
1095 (clobber (mem:BLK (scratch)))]
1098 [(set_attr "type" "pop")
1099 (set_attr "mode" "SI")])
1101 (define_insn "popsi1"
1102 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1103 (mem:SI (reg:SI SP_REG)))
1104 (set (reg:SI SP_REG)
1105 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1108 [(set_attr "type" "pop")
1109 (set_attr "mode" "SI")])
1111 (define_insn "*movsi_xor"
1112 [(set (match_operand:SI 0 "register_operand" "=r")
1113 (match_operand:SI 1 "const0_operand" "i"))
1114 (clobber (reg:CC FLAGS_REG))]
1115 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1116 "xor{l}\t{%0, %0|%0, %0}"
1117 [(set_attr "type" "alu1")
1118 (set_attr "mode" "SI")
1119 (set_attr "length_immediate" "0")])
1121 (define_insn "*movsi_or"
1122 [(set (match_operand:SI 0 "register_operand" "=r")
1123 (match_operand:SI 1 "immediate_operand" "i"))
1124 (clobber (reg:CC FLAGS_REG))]
1126 && operands[1] == constm1_rtx
1127 && (TARGET_PENTIUM || optimize_size)"
1129 operands[1] = constm1_rtx;
1130 return "or{l}\t{%1, %0|%0, %1}";
1132 [(set_attr "type" "alu1")
1133 (set_attr "mode" "SI")
1134 (set_attr "length_immediate" "1")])
1136 (define_insn "*movsi_1"
1137 [(set (match_operand:SI 0 "nonimmediate_operand"
1138 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1139 (match_operand:SI 1 "general_operand"
1140 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1141 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1143 switch (get_attr_type (insn))
1146 if (get_attr_mode (insn) == MODE_TI)
1147 return "pxor\t%0, %0";
1148 return "xorps\t%0, %0";
1151 switch (get_attr_mode (insn))
1154 return "movdqa\t{%1, %0|%0, %1}";
1156 return "movaps\t{%1, %0|%0, %1}";
1158 return "movd\t{%1, %0|%0, %1}";
1160 return "movss\t{%1, %0|%0, %1}";
1166 return "pxor\t%0, %0";
1169 if (get_attr_mode (insn) == MODE_DI)
1170 return "movq\t{%1, %0|%0, %1}";
1171 return "movd\t{%1, %0|%0, %1}";
1174 return "lea{l}\t{%1, %0|%0, %1}";
1177 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1179 return "mov{l}\t{%1, %0|%0, %1}";
1183 (cond [(eq_attr "alternative" "2")
1184 (const_string "mmx")
1185 (eq_attr "alternative" "3,4,5")
1186 (const_string "mmxmov")
1187 (eq_attr "alternative" "6")
1188 (const_string "sselog1")
1189 (eq_attr "alternative" "7,8,9,10,11")
1190 (const_string "ssemov")
1191 (and (ne (symbol_ref "flag_pic") (const_int 0))
1192 (match_operand:SI 1 "symbolic_operand" ""))
1193 (const_string "lea")
1195 (const_string "imov")))
1197 (cond [(eq_attr "alternative" "2,3")
1199 (eq_attr "alternative" "6,7")
1201 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1202 (const_string "V4SF")
1203 (const_string "TI"))
1204 (and (eq_attr "alternative" "8,9,10,11")
1205 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1208 (const_string "SI")))])
1210 ;; Stores and loads of ax to arbitrary constant address.
1211 ;; We fake an second form of instruction to force reload to load address
1212 ;; into register when rax is not available
1213 (define_insn "*movabssi_1_rex64"
1214 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1215 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1216 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1218 movabs{l}\t{%1, %P0|%P0, %1}
1219 mov{l}\t{%1, %a0|%a0, %1}"
1220 [(set_attr "type" "imov")
1221 (set_attr "modrm" "0,*")
1222 (set_attr "length_address" "8,0")
1223 (set_attr "length_immediate" "0,*")
1224 (set_attr "memory" "store")
1225 (set_attr "mode" "SI")])
1227 (define_insn "*movabssi_2_rex64"
1228 [(set (match_operand:SI 0 "register_operand" "=a,r")
1229 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1230 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1232 movabs{l}\t{%P1, %0|%0, %P1}
1233 mov{l}\t{%a1, %0|%0, %a1}"
1234 [(set_attr "type" "imov")
1235 (set_attr "modrm" "0,*")
1236 (set_attr "length_address" "8,0")
1237 (set_attr "length_immediate" "0")
1238 (set_attr "memory" "load")
1239 (set_attr "mode" "SI")])
1241 (define_insn "*swapsi"
1242 [(set (match_operand:SI 0 "register_operand" "+r")
1243 (match_operand:SI 1 "register_operand" "+r"))
1248 [(set_attr "type" "imov")
1249 (set_attr "mode" "SI")
1250 (set_attr "pent_pair" "np")
1251 (set_attr "athlon_decode" "vector")])
1253 (define_expand "movhi"
1254 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1255 (match_operand:HI 1 "general_operand" ""))]
1257 "ix86_expand_move (HImode, operands); DONE;")
1259 (define_insn "*pushhi2"
1260 [(set (match_operand:HI 0 "push_operand" "=<,<")
1261 (match_operand:HI 1 "general_no_elim_operand" "n,r*m"))]
1264 push{w}\t{|WORD PTR }%1
1266 [(set_attr "type" "push")
1267 (set_attr "mode" "HI")])
1269 ;; For 64BIT abi we always round up to 8 bytes.
1270 (define_insn "*pushhi2_rex64"
1271 [(set (match_operand:HI 0 "push_operand" "=X")
1272 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1275 [(set_attr "type" "push")
1276 (set_attr "mode" "QI")])
1278 (define_insn "*movhi_1"
1279 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1280 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1281 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1283 switch (get_attr_type (insn))
1286 /* movzwl is faster than movw on p2 due to partial word stalls,
1287 though not as fast as an aligned movl. */
1288 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1290 if (get_attr_mode (insn) == MODE_SI)
1291 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1293 return "mov{w}\t{%1, %0|%0, %1}";
1297 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1298 (const_string "imov")
1299 (and (eq_attr "alternative" "0")
1300 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1302 (eq (symbol_ref "TARGET_HIMODE_MATH")
1304 (const_string "imov")
1305 (and (eq_attr "alternative" "1,2")
1306 (match_operand:HI 1 "aligned_operand" ""))
1307 (const_string "imov")
1308 (and (ne (symbol_ref "TARGET_MOVX")
1310 (eq_attr "alternative" "0,2"))
1311 (const_string "imovx")
1313 (const_string "imov")))
1315 (cond [(eq_attr "type" "imovx")
1317 (and (eq_attr "alternative" "1,2")
1318 (match_operand:HI 1 "aligned_operand" ""))
1320 (and (eq_attr "alternative" "0")
1321 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1323 (eq (symbol_ref "TARGET_HIMODE_MATH")
1327 (const_string "HI")))])
1329 ;; Stores and loads of ax to arbitrary constant address.
1330 ;; We fake an second form of instruction to force reload to load address
1331 ;; into register when rax is not available
1332 (define_insn "*movabshi_1_rex64"
1333 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1334 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1335 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1337 movabs{w}\t{%1, %P0|%P0, %1}
1338 mov{w}\t{%1, %a0|%a0, %1}"
1339 [(set_attr "type" "imov")
1340 (set_attr "modrm" "0,*")
1341 (set_attr "length_address" "8,0")
1342 (set_attr "length_immediate" "0,*")
1343 (set_attr "memory" "store")
1344 (set_attr "mode" "HI")])
1346 (define_insn "*movabshi_2_rex64"
1347 [(set (match_operand:HI 0 "register_operand" "=a,r")
1348 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1349 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1351 movabs{w}\t{%P1, %0|%0, %P1}
1352 mov{w}\t{%a1, %0|%0, %a1}"
1353 [(set_attr "type" "imov")
1354 (set_attr "modrm" "0,*")
1355 (set_attr "length_address" "8,0")
1356 (set_attr "length_immediate" "0")
1357 (set_attr "memory" "load")
1358 (set_attr "mode" "HI")])
1360 (define_insn "*swaphi_1"
1361 [(set (match_operand:HI 0 "register_operand" "+r")
1362 (match_operand:HI 1 "register_operand" "+r"))
1365 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1367 [(set_attr "type" "imov")
1368 (set_attr "mode" "SI")
1369 (set_attr "pent_pair" "np")
1370 (set_attr "athlon_decode" "vector")])
1372 (define_insn "*swaphi_2"
1373 [(set (match_operand:HI 0 "register_operand" "+r")
1374 (match_operand:HI 1 "register_operand" "+r"))
1377 "TARGET_PARTIAL_REG_STALL"
1379 [(set_attr "type" "imov")
1380 (set_attr "mode" "HI")
1381 (set_attr "pent_pair" "np")
1382 (set_attr "athlon_decode" "vector")])
1384 (define_expand "movstricthi"
1385 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1386 (match_operand:HI 1 "general_operand" ""))]
1387 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1389 /* Don't generate memory->memory moves, go through a register */
1390 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1391 operands[1] = force_reg (HImode, operands[1]);
1394 (define_insn "*movstricthi_1"
1395 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1396 (match_operand:HI 1 "general_operand" "rn,m"))]
1397 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1398 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1399 "mov{w}\t{%1, %0|%0, %1}"
1400 [(set_attr "type" "imov")
1401 (set_attr "mode" "HI")])
1403 (define_insn "*movstricthi_xor"
1404 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1405 (match_operand:HI 1 "const0_operand" "i"))
1406 (clobber (reg:CC FLAGS_REG))]
1408 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1409 "xor{w}\t{%0, %0|%0, %0}"
1410 [(set_attr "type" "alu1")
1411 (set_attr "mode" "HI")
1412 (set_attr "length_immediate" "0")])
1414 (define_expand "movqi"
1415 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1416 (match_operand:QI 1 "general_operand" ""))]
1418 "ix86_expand_move (QImode, operands); DONE;")
1420 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1421 ;; "push a byte". But actually we use pushw, which has the effect
1422 ;; of rounding the amount pushed up to a halfword.
1424 (define_insn "*pushqi2"
1425 [(set (match_operand:QI 0 "push_operand" "=X,X")
1426 (match_operand:QI 1 "nonmemory_no_elim_operand" "n,r"))]
1429 push{w}\t{|word ptr }%1
1431 [(set_attr "type" "push")
1432 (set_attr "mode" "HI")])
1434 ;; For 64BIT abi we always round up to 8 bytes.
1435 (define_insn "*pushqi2_rex64"
1436 [(set (match_operand:QI 0 "push_operand" "=X")
1437 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1440 [(set_attr "type" "push")
1441 (set_attr "mode" "QI")])
1443 ;; Situation is quite tricky about when to choose full sized (SImode) move
1444 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1445 ;; partial register dependency machines (such as AMD Athlon), where QImode
1446 ;; moves issue extra dependency and for partial register stalls machines
1447 ;; that don't use QImode patterns (and QImode move cause stall on the next
1450 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1451 ;; register stall machines with, where we use QImode instructions, since
1452 ;; partial register stall can be caused there. Then we use movzx.
1453 (define_insn "*movqi_1"
1454 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1455 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1456 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1458 switch (get_attr_type (insn))
1461 if (!ANY_QI_REG_P (operands[1]) && GET_CODE (operands[1]) != MEM)
1463 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1465 if (get_attr_mode (insn) == MODE_SI)
1466 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1468 return "mov{b}\t{%1, %0|%0, %1}";
1472 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1473 (const_string "imov")
1474 (and (eq_attr "alternative" "3")
1475 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1477 (eq (symbol_ref "TARGET_QIMODE_MATH")
1479 (const_string "imov")
1480 (eq_attr "alternative" "3,5")
1481 (const_string "imovx")
1482 (and (ne (symbol_ref "TARGET_MOVX")
1484 (eq_attr "alternative" "2"))
1485 (const_string "imovx")
1487 (const_string "imov")))
1489 (cond [(eq_attr "alternative" "3,4,5")
1491 (eq_attr "alternative" "6")
1493 (eq_attr "type" "imovx")
1495 (and (eq_attr "type" "imov")
1496 (and (eq_attr "alternative" "0,1")
1497 (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1500 ;; Avoid partial register stalls when not using QImode arithmetic
1501 (and (eq_attr "type" "imov")
1502 (and (eq_attr "alternative" "0,1")
1503 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1505 (eq (symbol_ref "TARGET_QIMODE_MATH")
1509 (const_string "QI")))])
1511 (define_expand "reload_outqi"
1512 [(parallel [(match_operand:QI 0 "" "=m")
1513 (match_operand:QI 1 "register_operand" "r")
1514 (match_operand:QI 2 "register_operand" "=&q")])]
1518 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1520 if (reg_overlap_mentioned_p (op2, op0))
1522 if (! q_regs_operand (op1, QImode))
1524 emit_insn (gen_movqi (op2, op1));
1527 emit_insn (gen_movqi (op0, op1));
1531 (define_insn "*swapqi_1"
1532 [(set (match_operand:QI 0 "register_operand" "+r")
1533 (match_operand:QI 1 "register_operand" "+r"))
1536 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1538 [(set_attr "type" "imov")
1539 (set_attr "mode" "SI")
1540 (set_attr "pent_pair" "np")
1541 (set_attr "athlon_decode" "vector")])
1543 (define_insn "*swapqi_2"
1544 [(set (match_operand:QI 0 "register_operand" "+q")
1545 (match_operand:QI 1 "register_operand" "+q"))
1548 "TARGET_PARTIAL_REG_STALL"
1550 [(set_attr "type" "imov")
1551 (set_attr "mode" "QI")
1552 (set_attr "pent_pair" "np")
1553 (set_attr "athlon_decode" "vector")])
1555 (define_expand "movstrictqi"
1556 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1557 (match_operand:QI 1 "general_operand" ""))]
1558 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1560 /* Don't generate memory->memory moves, go through a register. */
1561 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1562 operands[1] = force_reg (QImode, operands[1]);
1565 (define_insn "*movstrictqi_1"
1566 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1567 (match_operand:QI 1 "general_operand" "*qn,m"))]
1568 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1569 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1570 "mov{b}\t{%1, %0|%0, %1}"
1571 [(set_attr "type" "imov")
1572 (set_attr "mode" "QI")])
1574 (define_insn "*movstrictqi_xor"
1575 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1576 (match_operand:QI 1 "const0_operand" "i"))
1577 (clobber (reg:CC FLAGS_REG))]
1578 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1579 "xor{b}\t{%0, %0|%0, %0}"
1580 [(set_attr "type" "alu1")
1581 (set_attr "mode" "QI")
1582 (set_attr "length_immediate" "0")])
1584 (define_insn "*movsi_extv_1"
1585 [(set (match_operand:SI 0 "register_operand" "=R")
1586 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1590 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1591 [(set_attr "type" "imovx")
1592 (set_attr "mode" "SI")])
1594 (define_insn "*movhi_extv_1"
1595 [(set (match_operand:HI 0 "register_operand" "=R")
1596 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1600 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1601 [(set_attr "type" "imovx")
1602 (set_attr "mode" "SI")])
1604 (define_insn "*movqi_extv_1"
1605 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1606 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1611 switch (get_attr_type (insn))
1614 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1616 return "mov{b}\t{%h1, %0|%0, %h1}";
1620 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1621 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1622 (ne (symbol_ref "TARGET_MOVX")
1624 (const_string "imovx")
1625 (const_string "imov")))
1627 (if_then_else (eq_attr "type" "imovx")
1629 (const_string "QI")))])
1631 (define_insn "*movqi_extv_1_rex64"
1632 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1633 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1638 switch (get_attr_type (insn))
1641 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1643 return "mov{b}\t{%h1, %0|%0, %h1}";
1647 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1648 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1649 (ne (symbol_ref "TARGET_MOVX")
1651 (const_string "imovx")
1652 (const_string "imov")))
1654 (if_then_else (eq_attr "type" "imovx")
1656 (const_string "QI")))])
1658 ;; Stores and loads of ax to arbitrary constant address.
1659 ;; We fake an second form of instruction to force reload to load address
1660 ;; into register when rax is not available
1661 (define_insn "*movabsqi_1_rex64"
1662 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1663 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1664 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1666 movabs{b}\t{%1, %P0|%P0, %1}
1667 mov{b}\t{%1, %a0|%a0, %1}"
1668 [(set_attr "type" "imov")
1669 (set_attr "modrm" "0,*")
1670 (set_attr "length_address" "8,0")
1671 (set_attr "length_immediate" "0,*")
1672 (set_attr "memory" "store")
1673 (set_attr "mode" "QI")])
1675 (define_insn "*movabsqi_2_rex64"
1676 [(set (match_operand:QI 0 "register_operand" "=a,r")
1677 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1678 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1680 movabs{b}\t{%P1, %0|%0, %P1}
1681 mov{b}\t{%a1, %0|%0, %a1}"
1682 [(set_attr "type" "imov")
1683 (set_attr "modrm" "0,*")
1684 (set_attr "length_address" "8,0")
1685 (set_attr "length_immediate" "0")
1686 (set_attr "memory" "load")
1687 (set_attr "mode" "QI")])
1689 (define_insn "*movsi_extzv_1"
1690 [(set (match_operand:SI 0 "register_operand" "=R")
1691 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1695 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1696 [(set_attr "type" "imovx")
1697 (set_attr "mode" "SI")])
1699 (define_insn "*movqi_extzv_2"
1700 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1701 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1706 switch (get_attr_type (insn))
1709 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1711 return "mov{b}\t{%h1, %0|%0, %h1}";
1715 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1716 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1717 (ne (symbol_ref "TARGET_MOVX")
1719 (const_string "imovx")
1720 (const_string "imov")))
1722 (if_then_else (eq_attr "type" "imovx")
1724 (const_string "QI")))])
1726 (define_insn "*movqi_extzv_2_rex64"
1727 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1728 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1733 switch (get_attr_type (insn))
1736 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1738 return "mov{b}\t{%h1, %0|%0, %h1}";
1742 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1743 (ne (symbol_ref "TARGET_MOVX")
1745 (const_string "imovx")
1746 (const_string "imov")))
1748 (if_then_else (eq_attr "type" "imovx")
1750 (const_string "QI")))])
1752 (define_insn "movsi_insv_1"
1753 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1756 (match_operand:SI 1 "general_operand" "Qmn"))]
1758 "mov{b}\t{%b1, %h0|%h0, %b1}"
1759 [(set_attr "type" "imov")
1760 (set_attr "mode" "QI")])
1762 (define_insn "movdi_insv_1_rex64"
1763 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1766 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1768 "mov{b}\t{%b1, %h0|%h0, %b1}"
1769 [(set_attr "type" "imov")
1770 (set_attr "mode" "QI")])
1772 (define_insn "*movqi_insv_2"
1773 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1776 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1779 "mov{b}\t{%h1, %h0|%h0, %h1}"
1780 [(set_attr "type" "imov")
1781 (set_attr "mode" "QI")])
1783 (define_expand "movdi"
1784 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1785 (match_operand:DI 1 "general_operand" ""))]
1787 "ix86_expand_move (DImode, operands); DONE;")
1789 (define_insn "*pushdi"
1790 [(set (match_operand:DI 0 "push_operand" "=<")
1791 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1795 (define_insn "*pushdi2_rex64"
1796 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1797 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1802 [(set_attr "type" "push,multi")
1803 (set_attr "mode" "DI")])
1805 ;; Convert impossible pushes of immediate to existing instructions.
1806 ;; First try to get scratch register and go through it. In case this
1807 ;; fails, push sign extended lower part first and then overwrite
1808 ;; upper part by 32bit move.
1810 [(match_scratch:DI 2 "r")
1811 (set (match_operand:DI 0 "push_operand" "")
1812 (match_operand:DI 1 "immediate_operand" ""))]
1813 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1814 && !x86_64_immediate_operand (operands[1], DImode)"
1815 [(set (match_dup 2) (match_dup 1))
1816 (set (match_dup 0) (match_dup 2))]
1819 ;; We need to define this as both peepholer and splitter for case
1820 ;; peephole2 pass is not run.
1821 ;; "&& 1" is needed to keep it from matching the previous pattern.
1823 [(set (match_operand:DI 0 "push_operand" "")
1824 (match_operand:DI 1 "immediate_operand" ""))]
1825 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1826 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1827 [(set (match_dup 0) (match_dup 1))
1828 (set (match_dup 2) (match_dup 3))]
1829 "split_di (operands + 1, 1, operands + 2, operands + 3);
1830 operands[1] = gen_lowpart (DImode, operands[2]);
1831 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1836 [(set (match_operand:DI 0 "push_operand" "")
1837 (match_operand:DI 1 "immediate_operand" ""))]
1838 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
1839 && !symbolic_operand (operands[1], DImode)
1840 && !x86_64_immediate_operand (operands[1], DImode)"
1841 [(set (match_dup 0) (match_dup 1))
1842 (set (match_dup 2) (match_dup 3))]
1843 "split_di (operands + 1, 1, operands + 2, operands + 3);
1844 operands[1] = gen_lowpart (DImode, operands[2]);
1845 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1849 (define_insn "*pushdi2_prologue_rex64"
1850 [(set (match_operand:DI 0 "push_operand" "=<")
1851 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1852 (clobber (mem:BLK (scratch)))]
1855 [(set_attr "type" "push")
1856 (set_attr "mode" "DI")])
1858 (define_insn "*popdi1_epilogue_rex64"
1859 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1860 (mem:DI (reg:DI SP_REG)))
1861 (set (reg:DI SP_REG)
1862 (plus:DI (reg:DI SP_REG) (const_int 8)))
1863 (clobber (mem:BLK (scratch)))]
1866 [(set_attr "type" "pop")
1867 (set_attr "mode" "DI")])
1869 (define_insn "popdi1"
1870 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1871 (mem:DI (reg:DI SP_REG)))
1872 (set (reg:DI SP_REG)
1873 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1876 [(set_attr "type" "pop")
1877 (set_attr "mode" "DI")])
1879 (define_insn "*movdi_xor_rex64"
1880 [(set (match_operand:DI 0 "register_operand" "=r")
1881 (match_operand:DI 1 "const0_operand" "i"))
1882 (clobber (reg:CC FLAGS_REG))]
1883 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1884 && reload_completed"
1885 "xor{l}\t{%k0, %k0|%k0, %k0}"
1886 [(set_attr "type" "alu1")
1887 (set_attr "mode" "SI")
1888 (set_attr "length_immediate" "0")])
1890 (define_insn "*movdi_or_rex64"
1891 [(set (match_operand:DI 0 "register_operand" "=r")
1892 (match_operand:DI 1 "const_int_operand" "i"))
1893 (clobber (reg:CC FLAGS_REG))]
1894 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1896 && operands[1] == constm1_rtx"
1898 operands[1] = constm1_rtx;
1899 return "or{q}\t{%1, %0|%0, %1}";
1901 [(set_attr "type" "alu1")
1902 (set_attr "mode" "DI")
1903 (set_attr "length_immediate" "1")])
1905 (define_insn "*movdi_2"
1906 [(set (match_operand:DI 0 "nonimmediate_operand"
1907 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1908 (match_operand:DI 1 "general_operand"
1909 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1910 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1915 movq\t{%1, %0|%0, %1}
1916 movq\t{%1, %0|%0, %1}
1918 movq\t{%1, %0|%0, %1}
1919 movdqa\t{%1, %0|%0, %1}
1920 movq\t{%1, %0|%0, %1}
1922 movlps\t{%1, %0|%0, %1}
1923 movaps\t{%1, %0|%0, %1}
1924 movlps\t{%1, %0|%0, %1}"
1925 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1926 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1929 [(set (match_operand:DI 0 "push_operand" "")
1930 (match_operand:DI 1 "general_operand" ""))]
1931 "!TARGET_64BIT && reload_completed
1932 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1934 "ix86_split_long_move (operands); DONE;")
1936 ;; %%% This multiword shite has got to go.
1938 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1939 (match_operand:DI 1 "general_operand" ""))]
1940 "!TARGET_64BIT && reload_completed
1941 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1942 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1944 "ix86_split_long_move (operands); DONE;")
1946 (define_insn "*movdi_1_rex64"
1947 [(set (match_operand:DI 0 "nonimmediate_operand"
1948 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1949 (match_operand:DI 1 "general_operand"
1950 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1951 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1953 switch (get_attr_type (insn))
1956 if (which_alternative == 13)
1957 return "movq2dq\t{%1, %0|%0, %1}";
1959 return "movdq2q\t{%1, %0|%0, %1}";
1961 if (get_attr_mode (insn) == MODE_TI)
1962 return "movdqa\t{%1, %0|%0, %1}";
1965 /* Moves from and into integer register is done using movd opcode with
1967 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1968 return "movd\t{%1, %0|%0, %1}";
1969 return "movq\t{%1, %0|%0, %1}";
1972 return "pxor\t%0, %0";
1976 return "lea{q}\t{%a1, %0|%0, %a1}";
1978 if (flag_pic && !LEGITIMATE_PIC_OPERAND_P (operands[1]))
1980 if (get_attr_mode (insn) == MODE_SI)
1981 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1982 else if (which_alternative == 2)
1983 return "movabs{q}\t{%1, %0|%0, %1}";
1985 return "mov{q}\t{%1, %0|%0, %1}";
1989 (cond [(eq_attr "alternative" "5")
1990 (const_string "mmx")
1991 (eq_attr "alternative" "6,7,8")
1992 (const_string "mmxmov")
1993 (eq_attr "alternative" "9")
1994 (const_string "sselog1")
1995 (eq_attr "alternative" "10,11,12")
1996 (const_string "ssemov")
1997 (eq_attr "alternative" "13,14")
1998 (const_string "ssecvt")
1999 (eq_attr "alternative" "4")
2000 (const_string "multi")
2001 (and (ne (symbol_ref "flag_pic") (const_int 0))
2002 (match_operand:DI 1 "symbolic_operand" ""))
2003 (const_string "lea")
2005 (const_string "imov")))
2006 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2007 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2008 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2010 ;; Stores and loads of ax to arbitrary constant address.
2011 ;; We fake an second form of instruction to force reload to load address
2012 ;; into register when rax is not available
2013 (define_insn "*movabsdi_1_rex64"
2014 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2015 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2016 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2018 movabs{q}\t{%1, %P0|%P0, %1}
2019 mov{q}\t{%1, %a0|%a0, %1}"
2020 [(set_attr "type" "imov")
2021 (set_attr "modrm" "0,*")
2022 (set_attr "length_address" "8,0")
2023 (set_attr "length_immediate" "0,*")
2024 (set_attr "memory" "store")
2025 (set_attr "mode" "DI")])
2027 (define_insn "*movabsdi_2_rex64"
2028 [(set (match_operand:DI 0 "register_operand" "=a,r")
2029 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2030 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2032 movabs{q}\t{%P1, %0|%0, %P1}
2033 mov{q}\t{%a1, %0|%0, %a1}"
2034 [(set_attr "type" "imov")
2035 (set_attr "modrm" "0,*")
2036 (set_attr "length_address" "8,0")
2037 (set_attr "length_immediate" "0")
2038 (set_attr "memory" "load")
2039 (set_attr "mode" "DI")])
2041 ;; Convert impossible stores of immediate to existing instructions.
2042 ;; First try to get scratch register and go through it. In case this
2043 ;; fails, move by 32bit parts.
2045 [(match_scratch:DI 2 "r")
2046 (set (match_operand:DI 0 "memory_operand" "")
2047 (match_operand:DI 1 "immediate_operand" ""))]
2048 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2049 && !x86_64_immediate_operand (operands[1], DImode)"
2050 [(set (match_dup 2) (match_dup 1))
2051 (set (match_dup 0) (match_dup 2))]
2054 ;; We need to define this as both peepholer and splitter for case
2055 ;; peephole2 pass is not run.
2056 ;; "&& 1" is needed to keep it from matching the previous pattern.
2058 [(set (match_operand:DI 0 "memory_operand" "")
2059 (match_operand:DI 1 "immediate_operand" ""))]
2060 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2061 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2062 [(set (match_dup 2) (match_dup 3))
2063 (set (match_dup 4) (match_dup 5))]
2064 "split_di (operands, 2, operands + 2, operands + 4);")
2067 [(set (match_operand:DI 0 "memory_operand" "")
2068 (match_operand:DI 1 "immediate_operand" ""))]
2069 "TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)
2070 && !symbolic_operand (operands[1], DImode)
2071 && !x86_64_immediate_operand (operands[1], DImode)"
2072 [(set (match_dup 2) (match_dup 3))
2073 (set (match_dup 4) (match_dup 5))]
2074 "split_di (operands, 2, operands + 2, operands + 4);")
2076 (define_insn "*swapdi_rex64"
2077 [(set (match_operand:DI 0 "register_operand" "+r")
2078 (match_operand:DI 1 "register_operand" "+r"))
2083 [(set_attr "type" "imov")
2084 (set_attr "mode" "DI")
2085 (set_attr "pent_pair" "np")
2086 (set_attr "athlon_decode" "vector")])
2088 (define_expand "movti"
2089 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2090 (match_operand:TI 1 "nonimmediate_operand" ""))]
2091 "TARGET_SSE || TARGET_64BIT"
2094 ix86_expand_move (TImode, operands);
2096 ix86_expand_vector_move (TImode, operands);
2100 (define_insn "*movti_internal"
2101 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2102 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2103 "TARGET_SSE && !TARGET_64BIT
2104 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2106 switch (which_alternative)
2109 if (get_attr_mode (insn) == MODE_V4SF)
2110 return "xorps\t%0, %0";
2112 return "pxor\t%0, %0";
2115 if (get_attr_mode (insn) == MODE_V4SF)
2116 return "movaps\t{%1, %0|%0, %1}";
2118 return "movdqa\t{%1, %0|%0, %1}";
2123 [(set_attr "type" "ssemov,ssemov,ssemov")
2125 (cond [(eq (symbol_ref "TARGET_SSE2") (const_int 0))
2126 (const_string "V4SF")
2128 (eq_attr "alternative" "0,1")
2130 (ne (symbol_ref "optimize_size")
2132 (const_string "V4SF")
2133 (const_string "TI"))
2134 (eq_attr "alternative" "2")
2136 (ne (symbol_ref "optimize_size")
2138 (const_string "V4SF")
2139 (const_string "TI"))]
2140 (const_string "TI")))])
2142 (define_insn "*movti_rex64"
2143 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2144 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2146 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2148 switch (which_alternative)
2154 if (get_attr_mode (insn) == MODE_V4SF)
2155 return "xorps\t%0, %0";
2157 return "pxor\t%0, %0";
2160 if (get_attr_mode (insn) == MODE_V4SF)
2161 return "movaps\t{%1, %0|%0, %1}";
2163 return "movdqa\t{%1, %0|%0, %1}";
2168 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2170 (cond [(eq_attr "alternative" "2,3")
2172 (ne (symbol_ref "optimize_size")
2174 (const_string "V4SF")
2175 (const_string "TI"))
2176 (eq_attr "alternative" "4")
2178 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2180 (ne (symbol_ref "optimize_size")
2182 (const_string "V4SF")
2183 (const_string "TI"))]
2184 (const_string "DI")))])
2187 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2188 (match_operand:TI 1 "general_operand" ""))]
2189 "reload_completed && !SSE_REG_P (operands[0])
2190 && !SSE_REG_P (operands[1])"
2192 "ix86_split_long_move (operands); DONE;")
2194 (define_expand "movsf"
2195 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2196 (match_operand:SF 1 "general_operand" ""))]
2198 "ix86_expand_move (SFmode, operands); DONE;")
2200 (define_insn "*pushsf"
2201 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2202 (match_operand:SF 1 "general_no_elim_operand" "f#rx,rFm#fx,x#rf"))]
2205 switch (which_alternative)
2208 return "push{l}\t%1";
2211 /* This insn should be already split before reg-stack. */
2215 [(set_attr "type" "multi,push,multi")
2216 (set_attr "mode" "SF,SI,SF")])
2218 (define_insn "*pushsf_rex64"
2219 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2220 (match_operand:SF 1 "nonmemory_no_elim_operand" "f#rx,rF#fx,x#rf"))]
2223 switch (which_alternative)
2226 return "push{q}\t%q1";
2229 /* This insn should be already split before reg-stack. */
2233 [(set_attr "type" "multi,push,multi")
2234 (set_attr "mode" "SF,DI,SF")])
2237 [(set (match_operand:SF 0 "push_operand" "")
2238 (match_operand:SF 1 "memory_operand" ""))]
2240 && GET_CODE (operands[1]) == MEM
2241 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2242 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2245 "operands[1] = get_pool_constant (XEXP (operands[1], 0));")
2248 ;; %%% Kill this when call knows how to work this out.
2250 [(set (match_operand:SF 0 "push_operand" "")
2251 (match_operand:SF 1 "any_fp_register_operand" ""))]
2253 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2254 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2257 [(set (match_operand:SF 0 "push_operand" "")
2258 (match_operand:SF 1 "any_fp_register_operand" ""))]
2260 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2261 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2263 (define_insn "*movsf_1"
2264 [(set (match_operand:SF 0 "nonimmediate_operand"
2265 "=f#xr,m ,f#xr,r#xf ,m ,x#rf,x#rf,x#rf ,m ,!*y,!rm,!*y")
2266 (match_operand:SF 1 "general_operand"
2267 "fm#rx,f#rx,G ,rmF#fx,Fr#fx,C ,x ,xm#rf,x#rf,rm ,*y ,*y"))]
2268 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2269 && (reload_in_progress || reload_completed
2270 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2271 || GET_CODE (operands[1]) != CONST_DOUBLE
2272 || memory_operand (operands[0], SFmode))"
2274 switch (which_alternative)
2277 return output_387_reg_move (insn, operands);
2280 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2281 return "fstp%z0\t%y0";
2283 return "fst%z0\t%y0";
2286 return standard_80387_constant_opcode (operands[1]);
2290 return "mov{l}\t{%1, %0|%0, %1}";
2292 if (get_attr_mode (insn) == MODE_TI)
2293 return "pxor\t%0, %0";
2295 return "xorps\t%0, %0";
2297 if (get_attr_mode (insn) == MODE_V4SF)
2298 return "movaps\t{%1, %0|%0, %1}";
2300 return "movss\t{%1, %0|%0, %1}";
2303 return "movss\t{%1, %0|%0, %1}";
2307 return "movd\t{%1, %0|%0, %1}";
2310 return "movq\t{%1, %0|%0, %1}";
2316 [(set_attr "type" "fmov,fmov,fmov,imov,imov,ssemov,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2318 (cond [(eq_attr "alternative" "3,4,9,10")
2320 (eq_attr "alternative" "5")
2322 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2324 (ne (symbol_ref "TARGET_SSE2")
2326 (eq (symbol_ref "optimize_size")
2329 (const_string "V4SF"))
2330 /* For architectures resolving dependencies on
2331 whole SSE registers use APS move to break dependency
2332 chains, otherwise use short move to avoid extra work.
2334 Do the same for architectures resolving dependencies on
2335 the parts. While in DF mode it is better to always handle
2336 just register parts, the SF mode is different due to lack
2337 of instructions to load just part of the register. It is
2338 better to maintain the whole registers in single format
2339 to avoid problems on using packed logical operations. */
2340 (eq_attr "alternative" "6")
2342 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2344 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2346 (const_string "V4SF")
2347 (const_string "SF"))
2348 (eq_attr "alternative" "11")
2349 (const_string "DI")]
2350 (const_string "SF")))])
2352 (define_insn "*swapsf"
2353 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2354 (match_operand:SF 1 "fp_register_operand" "+f"))
2357 "reload_completed || TARGET_80387"
2359 if (STACK_TOP_P (operands[0]))
2364 [(set_attr "type" "fxch")
2365 (set_attr "mode" "SF")])
2367 (define_expand "movdf"
2368 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2369 (match_operand:DF 1 "general_operand" ""))]
2371 "ix86_expand_move (DFmode, operands); DONE;")
2373 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2374 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2375 ;; On the average, pushdf using integers can be still shorter. Allow this
2376 ;; pattern for optimize_size too.
2378 (define_insn "*pushdf_nointeger"
2379 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2380 (match_operand:DF 1 "general_no_elim_operand" "f#Y,Fo#fY,*r#fY,Y#f"))]
2381 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2383 /* This insn should be already split before reg-stack. */
2386 [(set_attr "type" "multi")
2387 (set_attr "mode" "DF,SI,SI,DF")])
2389 (define_insn "*pushdf_integer"
2390 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2391 (match_operand:DF 1 "general_no_elim_operand" "f#rY,rFo#fY,Y#rf"))]
2392 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2394 /* This insn should be already split before reg-stack. */
2397 [(set_attr "type" "multi")
2398 (set_attr "mode" "DF,SI,DF")])
2400 ;; %%% Kill this when call knows how to work this out.
2402 [(set (match_operand:DF 0 "push_operand" "")
2403 (match_operand:DF 1 "any_fp_register_operand" ""))]
2404 "!TARGET_64BIT && reload_completed"
2405 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2406 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2410 [(set (match_operand:DF 0 "push_operand" "")
2411 (match_operand:DF 1 "any_fp_register_operand" ""))]
2412 "TARGET_64BIT && reload_completed"
2413 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2414 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2418 [(set (match_operand:DF 0 "push_operand" "")
2419 (match_operand:DF 1 "general_operand" ""))]
2422 "ix86_split_long_move (operands); DONE;")
2424 ;; Moving is usually shorter when only FP registers are used. This separate
2425 ;; movdf pattern avoids the use of integer registers for FP operations
2426 ;; when optimizing for size.
2428 (define_insn "*movdf_nointeger"
2429 [(set (match_operand:DF 0 "nonimmediate_operand"
2430 "=f#Y,m ,f#Y,*r ,o ,Y*x#f,Y*x#f,Y*x#f ,m ")
2431 (match_operand:DF 1 "general_operand"
2432 "fm#Y,f#Y,G ,*roF,F*r,C ,Y*x#f,HmY*x#f,Y*x#f"))]
2433 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2434 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2435 && (reload_in_progress || reload_completed
2436 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2437 || GET_CODE (operands[1]) != CONST_DOUBLE
2438 || memory_operand (operands[0], DFmode))"
2440 switch (which_alternative)
2443 return output_387_reg_move (insn, operands);
2446 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2447 return "fstp%z0\t%y0";
2449 return "fst%z0\t%y0";
2452 return standard_80387_constant_opcode (operands[1]);
2458 switch (get_attr_mode (insn))
2461 return "xorps\t%0, %0";
2463 return "xorpd\t%0, %0";
2465 return "pxor\t%0, %0";
2472 switch (get_attr_mode (insn))
2475 return "movaps\t{%1, %0|%0, %1}";
2477 return "movapd\t{%1, %0|%0, %1}";
2479 return "movdqa\t{%1, %0|%0, %1}";
2481 return "movq\t{%1, %0|%0, %1}";
2483 return "movsd\t{%1, %0|%0, %1}";
2485 return "movlpd\t{%1, %0|%0, %1}";
2487 return "movlps\t{%1, %0|%0, %1}";
2496 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2498 (cond [(eq_attr "alternative" "0,1,2")
2500 (eq_attr "alternative" "3,4")
2503 /* For SSE1, we have many fewer alternatives. */
2504 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2505 (cond [(eq_attr "alternative" "5,6")
2506 (const_string "V4SF")
2508 (const_string "V2SF"))
2510 /* xorps is one byte shorter. */
2511 (eq_attr "alternative" "5")
2512 (cond [(ne (symbol_ref "optimize_size")
2514 (const_string "V4SF")
2515 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2519 (const_string "V2DF"))
2521 /* For architectures resolving dependencies on
2522 whole SSE registers use APD move to break dependency
2523 chains, otherwise use short move to avoid extra work.
2525 movaps encodes one byte shorter. */
2526 (eq_attr "alternative" "6")
2528 [(ne (symbol_ref "optimize_size")
2530 (const_string "V4SF")
2531 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2533 (const_string "V2DF")
2535 (const_string "DF"))
2536 /* For architectures resolving dependencies on register
2537 parts we may avoid extra work to zero out upper part
2539 (eq_attr "alternative" "7")
2541 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2543 (const_string "V1DF")
2544 (const_string "DF"))
2546 (const_string "DF")))])
2548 (define_insn "*movdf_integer"
2549 [(set (match_operand:DF 0 "nonimmediate_operand"
2550 "=f#Yr,m ,f#Yr,r#Yf ,o ,Y*x#rf,Y*x#rf,Y*x#rf,m")
2551 (match_operand:DF 1 "general_operand"
2552 "fm#Yr,f#Yr,G ,roF#Yf,Fr#Yf,C ,Y*x#rf,m ,Y*x#rf"))]
2553 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2554 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2555 && (reload_in_progress || reload_completed
2556 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2557 || GET_CODE (operands[1]) != CONST_DOUBLE
2558 || memory_operand (operands[0], DFmode))"
2560 switch (which_alternative)
2563 return output_387_reg_move (insn, operands);
2566 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2567 return "fstp%z0\t%y0";
2569 return "fst%z0\t%y0";
2572 return standard_80387_constant_opcode (operands[1]);
2579 switch (get_attr_mode (insn))
2582 return "xorps\t%0, %0";
2584 return "xorpd\t%0, %0";
2586 return "pxor\t%0, %0";
2593 switch (get_attr_mode (insn))
2596 return "movaps\t{%1, %0|%0, %1}";
2598 return "movapd\t{%1, %0|%0, %1}";
2600 return "movdqa\t{%1, %0|%0, %1}";
2602 return "movq\t{%1, %0|%0, %1}";
2604 return "movsd\t{%1, %0|%0, %1}";
2606 return "movlpd\t{%1, %0|%0, %1}";
2608 return "movlps\t{%1, %0|%0, %1}";
2617 [(set_attr "type" "fmov,fmov,fmov,multi,multi,ssemov,ssemov,ssemov,ssemov")
2619 (cond [(eq_attr "alternative" "0,1,2")
2621 (eq_attr "alternative" "3,4")
2624 /* For SSE1, we have many fewer alternatives. */
2625 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2626 (cond [(eq_attr "alternative" "5,6")
2627 (const_string "V4SF")
2629 (const_string "V2SF"))
2631 /* xorps is one byte shorter. */
2632 (eq_attr "alternative" "5")
2633 (cond [(ne (symbol_ref "optimize_size")
2635 (const_string "V4SF")
2636 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2640 (const_string "V2DF"))
2642 /* For architectures resolving dependencies on
2643 whole SSE registers use APD move to break dependency
2644 chains, otherwise use short move to avoid extra work.
2646 movaps encodes one byte shorter. */
2647 (eq_attr "alternative" "6")
2649 [(ne (symbol_ref "optimize_size")
2651 (const_string "V4SF")
2652 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2654 (const_string "V2DF")
2656 (const_string "DF"))
2657 /* For architectures resolving dependencies on register
2658 parts we may avoid extra work to zero out upper part
2660 (eq_attr "alternative" "7")
2662 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2664 (const_string "V1DF")
2665 (const_string "DF"))
2667 (const_string "DF")))])
2670 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2671 (match_operand:DF 1 "general_operand" ""))]
2673 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2674 && ! (ANY_FP_REG_P (operands[0]) ||
2675 (GET_CODE (operands[0]) == SUBREG
2676 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2677 && ! (ANY_FP_REG_P (operands[1]) ||
2678 (GET_CODE (operands[1]) == SUBREG
2679 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2681 "ix86_split_long_move (operands); DONE;")
2683 (define_insn "*swapdf"
2684 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2685 (match_operand:DF 1 "fp_register_operand" "+f"))
2688 "reload_completed || TARGET_80387"
2690 if (STACK_TOP_P (operands[0]))
2695 [(set_attr "type" "fxch")
2696 (set_attr "mode" "DF")])
2698 (define_expand "movxf"
2699 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2700 (match_operand:XF 1 "general_operand" ""))]
2702 "ix86_expand_move (XFmode, operands); DONE;")
2704 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2705 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2706 ;; Pushing using integer instructions is longer except for constants
2707 ;; and direct memory references.
2708 ;; (assuming that any given constant is pushed only once, but this ought to be
2709 ;; handled elsewhere).
2711 (define_insn "*pushxf_nointeger"
2712 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2713 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2716 /* This insn should be already split before reg-stack. */
2719 [(set_attr "type" "multi")
2720 (set_attr "mode" "XF,SI,SI")])
2722 (define_insn "*pushxf_integer"
2723 [(set (match_operand:XF 0 "push_operand" "=<,<")
2724 (match_operand:XF 1 "general_no_elim_operand" "f#r,ro#f"))]
2727 /* This insn should be already split before reg-stack. */
2730 [(set_attr "type" "multi")
2731 (set_attr "mode" "XF,SI")])
2734 [(set (match_operand 0 "push_operand" "")
2735 (match_operand 1 "general_operand" ""))]
2737 && (GET_MODE (operands[0]) == XFmode
2738 || GET_MODE (operands[0]) == DFmode)
2739 && !ANY_FP_REG_P (operands[1])"
2741 "ix86_split_long_move (operands); DONE;")
2744 [(set (match_operand:XF 0 "push_operand" "")
2745 (match_operand:XF 1 "any_fp_register_operand" ""))]
2747 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2748 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2749 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2752 [(set (match_operand:XF 0 "push_operand" "")
2753 (match_operand:XF 1 "any_fp_register_operand" ""))]
2755 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2756 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2757 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2759 ;; Do not use integer registers when optimizing for size
2760 (define_insn "*movxf_nointeger"
2761 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2762 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2764 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2765 && (reload_in_progress || reload_completed
2766 || GET_CODE (operands[1]) != CONST_DOUBLE
2767 || memory_operand (operands[0], XFmode))"
2769 switch (which_alternative)
2772 return output_387_reg_move (insn, operands);
2775 /* There is no non-popping store to memory for XFmode. So if
2776 we need one, follow the store with a load. */
2777 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2778 return "fstp%z0\t%y0\;fld%z0\t%y0";
2780 return "fstp%z0\t%y0";
2783 return standard_80387_constant_opcode (operands[1]);
2790 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2791 (set_attr "mode" "XF,XF,XF,SI,SI")])
2793 (define_insn "*movxf_integer"
2794 [(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
2795 (match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
2797 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2798 && (reload_in_progress || reload_completed
2799 || GET_CODE (operands[1]) != CONST_DOUBLE
2800 || memory_operand (operands[0], XFmode))"
2802 switch (which_alternative)
2805 return output_387_reg_move (insn, operands);
2808 /* There is no non-popping store to memory for XFmode. So if
2809 we need one, follow the store with a load. */
2810 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2811 return "fstp%z0\t%y0\;fld%z0\t%y0";
2813 return "fstp%z0\t%y0";
2816 return standard_80387_constant_opcode (operands[1]);
2823 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2824 (set_attr "mode" "XF,XF,XF,SI,SI")])
2827 [(set (match_operand 0 "nonimmediate_operand" "")
2828 (match_operand 1 "general_operand" ""))]
2830 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2831 && GET_MODE (operands[0]) == XFmode
2832 && ! (ANY_FP_REG_P (operands[0]) ||
2833 (GET_CODE (operands[0]) == SUBREG
2834 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2835 && ! (ANY_FP_REG_P (operands[1]) ||
2836 (GET_CODE (operands[1]) == SUBREG
2837 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2839 "ix86_split_long_move (operands); DONE;")
2842 [(set (match_operand 0 "register_operand" "")
2843 (match_operand 1 "memory_operand" ""))]
2845 && GET_CODE (operands[1]) == MEM
2846 && (GET_MODE (operands[0]) == XFmode
2847 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2848 && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
2849 && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))"
2850 [(set (match_dup 0) (match_dup 1))]
2852 rtx c = get_pool_constant (XEXP (operands[1], 0));
2853 rtx r = operands[0];
2855 if (GET_CODE (r) == SUBREG)
2860 if (!standard_sse_constant_p (c))
2863 else if (FP_REG_P (r))
2865 if (!standard_80387_constant_p (c))
2868 else if (MMX_REG_P (r))
2874 (define_insn "swapxf"
2875 [(set (match_operand:XF 0 "register_operand" "+f")
2876 (match_operand:XF 1 "register_operand" "+f"))
2881 if (STACK_TOP_P (operands[0]))
2886 [(set_attr "type" "fxch")
2887 (set_attr "mode" "XF")])
2889 (define_expand "movtf"
2890 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2891 (match_operand:TF 1 "nonimmediate_operand" ""))]
2894 ix86_expand_move (TFmode, operands);
2898 (define_insn "*movtf_internal"
2899 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2900 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2902 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2904 switch (which_alternative)
2910 if (get_attr_mode (insn) == MODE_V4SF)
2911 return "xorps\t%0, %0";
2913 return "pxor\t%0, %0";
2916 if (get_attr_mode (insn) == MODE_V4SF)
2917 return "movaps\t{%1, %0|%0, %1}";
2919 return "movdqa\t{%1, %0|%0, %1}";
2924 [(set_attr "type" "*,*,ssemov,ssemov,ssemov")
2926 (cond [(eq_attr "alternative" "2,3")
2928 (ne (symbol_ref "optimize_size")
2930 (const_string "V4SF")
2931 (const_string "TI"))
2932 (eq_attr "alternative" "4")
2934 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2936 (ne (symbol_ref "optimize_size")
2938 (const_string "V4SF")
2939 (const_string "TI"))]
2940 (const_string "DI")))])
2943 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2944 (match_operand:TF 1 "general_operand" ""))]
2945 "reload_completed && !SSE_REG_P (operands[0])
2946 && !SSE_REG_P (operands[1])"
2948 "ix86_split_long_move (operands); DONE;")
2950 ;; Zero extension instructions
2952 (define_expand "zero_extendhisi2"
2953 [(set (match_operand:SI 0 "register_operand" "")
2954 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2957 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2959 operands[1] = force_reg (HImode, operands[1]);
2960 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2965 (define_insn "zero_extendhisi2_and"
2966 [(set (match_operand:SI 0 "register_operand" "=r")
2967 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2968 (clobber (reg:CC FLAGS_REG))]
2969 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2971 [(set_attr "type" "alu1")
2972 (set_attr "mode" "SI")])
2975 [(set (match_operand:SI 0 "register_operand" "")
2976 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2977 (clobber (reg:CC FLAGS_REG))]
2978 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2979 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2980 (clobber (reg:CC FLAGS_REG))])]
2983 (define_insn "*zero_extendhisi2_movzwl"
2984 [(set (match_operand:SI 0 "register_operand" "=r")
2985 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
2986 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
2987 "movz{wl|x}\t{%1, %0|%0, %1}"
2988 [(set_attr "type" "imovx")
2989 (set_attr "mode" "SI")])
2991 (define_expand "zero_extendqihi2"
2993 [(set (match_operand:HI 0 "register_operand" "")
2994 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
2995 (clobber (reg:CC FLAGS_REG))])]
2999 (define_insn "*zero_extendqihi2_and"
3000 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3001 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3002 (clobber (reg:CC FLAGS_REG))]
3003 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3005 [(set_attr "type" "alu1")
3006 (set_attr "mode" "HI")])
3008 (define_insn "*zero_extendqihi2_movzbw_and"
3009 [(set (match_operand:HI 0 "register_operand" "=r,r")
3010 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3011 (clobber (reg:CC FLAGS_REG))]
3012 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3014 [(set_attr "type" "imovx,alu1")
3015 (set_attr "mode" "HI")])
3017 (define_insn "*zero_extendqihi2_movzbw"
3018 [(set (match_operand:HI 0 "register_operand" "=r")
3019 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3020 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3021 "movz{bw|x}\t{%1, %0|%0, %1}"
3022 [(set_attr "type" "imovx")
3023 (set_attr "mode" "HI")])
3025 ;; For the movzbw case strip only the clobber
3027 [(set (match_operand:HI 0 "register_operand" "")
3028 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3029 (clobber (reg:CC FLAGS_REG))]
3031 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3032 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3033 [(set (match_operand:HI 0 "register_operand" "")
3034 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3036 ;; When source and destination does not overlap, clear destination
3037 ;; first and then do the movb
3039 [(set (match_operand:HI 0 "register_operand" "")
3040 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3041 (clobber (reg:CC FLAGS_REG))]
3043 && ANY_QI_REG_P (operands[0])
3044 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3045 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3046 [(set (match_dup 0) (const_int 0))
3047 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3048 "operands[2] = gen_lowpart (QImode, operands[0]);")
3050 ;; Rest is handled by single and.
3052 [(set (match_operand:HI 0 "register_operand" "")
3053 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3054 (clobber (reg:CC FLAGS_REG))]
3056 && true_regnum (operands[0]) == true_regnum (operands[1])"
3057 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3058 (clobber (reg:CC FLAGS_REG))])]
3061 (define_expand "zero_extendqisi2"
3063 [(set (match_operand:SI 0 "register_operand" "")
3064 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3065 (clobber (reg:CC FLAGS_REG))])]
3069 (define_insn "*zero_extendqisi2_and"
3070 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3071 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3072 (clobber (reg:CC FLAGS_REG))]
3073 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3075 [(set_attr "type" "alu1")
3076 (set_attr "mode" "SI")])
3078 (define_insn "*zero_extendqisi2_movzbw_and"
3079 [(set (match_operand:SI 0 "register_operand" "=r,r")
3080 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3081 (clobber (reg:CC FLAGS_REG))]
3082 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3084 [(set_attr "type" "imovx,alu1")
3085 (set_attr "mode" "SI")])
3087 (define_insn "*zero_extendqisi2_movzbw"
3088 [(set (match_operand:SI 0 "register_operand" "=r")
3089 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3090 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3091 "movz{bl|x}\t{%1, %0|%0, %1}"
3092 [(set_attr "type" "imovx")
3093 (set_attr "mode" "SI")])
3095 ;; For the movzbl case strip only the clobber
3097 [(set (match_operand:SI 0 "register_operand" "")
3098 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3099 (clobber (reg:CC FLAGS_REG))]
3101 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3102 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3104 (zero_extend:SI (match_dup 1)))])
3106 ;; When source and destination does not overlap, clear destination
3107 ;; first and then do the movb
3109 [(set (match_operand:SI 0 "register_operand" "")
3110 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3111 (clobber (reg:CC FLAGS_REG))]
3113 && ANY_QI_REG_P (operands[0])
3114 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3115 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3116 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3117 [(set (match_dup 0) (const_int 0))
3118 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3119 "operands[2] = gen_lowpart (QImode, operands[0]);")
3121 ;; Rest is handled by single and.
3123 [(set (match_operand:SI 0 "register_operand" "")
3124 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3125 (clobber (reg:CC FLAGS_REG))]
3127 && true_regnum (operands[0]) == true_regnum (operands[1])"
3128 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3129 (clobber (reg:CC FLAGS_REG))])]
3132 ;; %%% Kill me once multi-word ops are sane.
3133 (define_expand "zero_extendsidi2"
3134 [(set (match_operand:DI 0 "register_operand" "=r")
3135 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3139 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3144 (define_insn "zero_extendsidi2_32"
3145 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3146 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3147 (clobber (reg:CC FLAGS_REG))]
3153 movd\t{%1, %0|%0, %1}
3154 movd\t{%1, %0|%0, %1}"
3155 [(set_attr "mode" "SI,SI,SI,DI,TI")
3156 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3158 (define_insn "zero_extendsidi2_rex64"
3159 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3160 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3163 mov\t{%k1, %k0|%k0, %k1}
3165 movd\t{%1, %0|%0, %1}
3166 movd\t{%1, %0|%0, %1}"
3167 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3168 (set_attr "mode" "SI,DI,SI,SI")])
3171 [(set (match_operand:DI 0 "memory_operand" "")
3172 (zero_extend:DI (match_dup 0)))]
3174 [(set (match_dup 4) (const_int 0))]
3175 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3178 [(set (match_operand:DI 0 "register_operand" "")
3179 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3180 (clobber (reg:CC FLAGS_REG))]
3181 "!TARGET_64BIT && reload_completed
3182 && true_regnum (operands[0]) == true_regnum (operands[1])"
3183 [(set (match_dup 4) (const_int 0))]
3184 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3187 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3188 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3189 (clobber (reg:CC FLAGS_REG))]
3190 "!TARGET_64BIT && reload_completed
3191 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3192 [(set (match_dup 3) (match_dup 1))
3193 (set (match_dup 4) (const_int 0))]
3194 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3196 (define_insn "zero_extendhidi2"
3197 [(set (match_operand:DI 0 "register_operand" "=r,r")
3198 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
3201 movz{wl|x}\t{%1, %k0|%k0, %1}
3202 movz{wq|x}\t{%1, %0|%0, %1}"
3203 [(set_attr "type" "imovx")
3204 (set_attr "mode" "SI,DI")])
3206 (define_insn "zero_extendqidi2"
3207 [(set (match_operand:DI 0 "register_operand" "=r,r")
3208 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "Q,m")))]
3211 movz{bl|x}\t{%1, %k0|%k0, %1}
3212 movz{bq|x}\t{%1, %0|%0, %1}"
3213 [(set_attr "type" "imovx")
3214 (set_attr "mode" "SI,DI")])
3216 ;; Sign extension instructions
3218 (define_expand "extendsidi2"
3219 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3220 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3221 (clobber (reg:CC FLAGS_REG))
3222 (clobber (match_scratch:SI 2 ""))])]
3227 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3232 (define_insn "*extendsidi2_1"
3233 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3234 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3235 (clobber (reg:CC FLAGS_REG))
3236 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3240 (define_insn "extendsidi2_rex64"
3241 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3242 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3246 movs{lq|x}\t{%1,%0|%0, %1}"
3247 [(set_attr "type" "imovx")
3248 (set_attr "mode" "DI")
3249 (set_attr "prefix_0f" "0")
3250 (set_attr "modrm" "0,1")])
3252 (define_insn "extendhidi2"
3253 [(set (match_operand:DI 0 "register_operand" "=r")
3254 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3256 "movs{wq|x}\t{%1,%0|%0, %1}"
3257 [(set_attr "type" "imovx")
3258 (set_attr "mode" "DI")])
3260 (define_insn "extendqidi2"
3261 [(set (match_operand:DI 0 "register_operand" "=r")
3262 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3264 "movs{bq|x}\t{%1,%0|%0, %1}"
3265 [(set_attr "type" "imovx")
3266 (set_attr "mode" "DI")])
3268 ;; Extend to memory case when source register does die.
3270 [(set (match_operand:DI 0 "memory_operand" "")
3271 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3272 (clobber (reg:CC FLAGS_REG))
3273 (clobber (match_operand:SI 2 "register_operand" ""))]
3275 && dead_or_set_p (insn, operands[1])
3276 && !reg_mentioned_p (operands[1], operands[0]))"
3277 [(set (match_dup 3) (match_dup 1))
3278 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3279 (clobber (reg:CC FLAGS_REG))])
3280 (set (match_dup 4) (match_dup 1))]
3281 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3283 ;; Extend to memory case when source register does not die.
3285 [(set (match_operand:DI 0 "memory_operand" "")
3286 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287 (clobber (reg:CC FLAGS_REG))
3288 (clobber (match_operand:SI 2 "register_operand" ""))]
3292 split_di (&operands[0], 1, &operands[3], &operands[4]);
3294 emit_move_insn (operands[3], operands[1]);
3296 /* Generate a cltd if possible and doing so it profitable. */
3297 if (true_regnum (operands[1]) == 0
3298 && true_regnum (operands[2]) == 1
3299 && (optimize_size || TARGET_USE_CLTD))
3301 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3305 emit_move_insn (operands[2], operands[1]);
3306 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3308 emit_move_insn (operands[4], operands[2]);
3312 ;; Extend to register case. Optimize case where source and destination
3313 ;; registers match and cases where we can use cltd.
3315 [(set (match_operand:DI 0 "register_operand" "")
3316 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3317 (clobber (reg:CC FLAGS_REG))
3318 (clobber (match_scratch:SI 2 ""))]
3322 split_di (&operands[0], 1, &operands[3], &operands[4]);
3324 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3325 emit_move_insn (operands[3], operands[1]);
3327 /* Generate a cltd if possible and doing so it profitable. */
3328 if (true_regnum (operands[3]) == 0
3329 && (optimize_size || TARGET_USE_CLTD))
3331 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3335 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3336 emit_move_insn (operands[4], operands[1]);
3338 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3342 (define_insn "extendhisi2"
3343 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3344 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3347 switch (get_attr_prefix_0f (insn))
3350 return "{cwtl|cwde}";
3352 return "movs{wl|x}\t{%1,%0|%0, %1}";
3355 [(set_attr "type" "imovx")
3356 (set_attr "mode" "SI")
3357 (set (attr "prefix_0f")
3358 ;; movsx is short decodable while cwtl is vector decoded.
3359 (if_then_else (and (eq_attr "cpu" "!k6")
3360 (eq_attr "alternative" "0"))
3362 (const_string "1")))
3364 (if_then_else (eq_attr "prefix_0f" "0")
3366 (const_string "1")))])
3368 (define_insn "*extendhisi2_zext"
3369 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3371 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3374 switch (get_attr_prefix_0f (insn))
3377 return "{cwtl|cwde}";
3379 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3382 [(set_attr "type" "imovx")
3383 (set_attr "mode" "SI")
3384 (set (attr "prefix_0f")
3385 ;; movsx is short decodable while cwtl is vector decoded.
3386 (if_then_else (and (eq_attr "cpu" "!k6")
3387 (eq_attr "alternative" "0"))
3389 (const_string "1")))
3391 (if_then_else (eq_attr "prefix_0f" "0")
3393 (const_string "1")))])
3395 (define_insn "extendqihi2"
3396 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3397 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3400 switch (get_attr_prefix_0f (insn))
3403 return "{cbtw|cbw}";
3405 return "movs{bw|x}\t{%1,%0|%0, %1}";
3408 [(set_attr "type" "imovx")
3409 (set_attr "mode" "HI")
3410 (set (attr "prefix_0f")
3411 ;; movsx is short decodable while cwtl is vector decoded.
3412 (if_then_else (and (eq_attr "cpu" "!k6")
3413 (eq_attr "alternative" "0"))
3415 (const_string "1")))
3417 (if_then_else (eq_attr "prefix_0f" "0")
3419 (const_string "1")))])
3421 (define_insn "extendqisi2"
3422 [(set (match_operand:SI 0 "register_operand" "=r")
3423 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3425 "movs{bl|x}\t{%1,%0|%0, %1}"
3426 [(set_attr "type" "imovx")
3427 (set_attr "mode" "SI")])
3429 (define_insn "*extendqisi2_zext"
3430 [(set (match_operand:DI 0 "register_operand" "=r")
3432 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3434 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3435 [(set_attr "type" "imovx")
3436 (set_attr "mode" "SI")])
3438 ;; Conversions between float and double.
3440 ;; These are all no-ops in the model used for the 80387. So just
3443 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3444 (define_insn "*dummy_extendsfdf2"
3445 [(set (match_operand:DF 0 "push_operand" "=<")
3446 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3451 [(set (match_operand:DF 0 "push_operand" "")
3452 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3454 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3455 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3458 [(set (match_operand:DF 0 "push_operand" "")
3459 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3461 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3462 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3464 (define_insn "*dummy_extendsfxf2"
3465 [(set (match_operand:XF 0 "push_operand" "=<")
3466 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3471 [(set (match_operand:XF 0 "push_operand" "")
3472 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3474 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3475 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3476 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3479 [(set (match_operand:XF 0 "push_operand" "")
3480 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3482 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3483 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3484 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3487 [(set (match_operand:XF 0 "push_operand" "")
3488 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3490 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3491 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3492 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3495 [(set (match_operand:XF 0 "push_operand" "")
3496 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3498 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3499 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3500 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3502 (define_expand "extendsfdf2"
3503 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3504 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3505 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3507 /* ??? Needed for compress_float_constant since all fp constants
3508 are LEGITIMATE_CONSTANT_P. */
3509 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3510 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3511 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3512 operands[1] = force_reg (SFmode, operands[1]);
3515 (define_insn "*extendsfdf2_mixed"
3516 [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,m#fY,Y#f")
3517 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f")))]
3518 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3519 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3521 switch (which_alternative)
3524 return output_387_reg_move (insn, operands);
3527 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3528 return "fstp%z0\t%y0";
3530 return "fst%z0\t%y0";
3533 return "cvtss2sd\t{%1, %0|%0, %1}";
3539 [(set_attr "type" "fmov,fmov,ssecvt")
3540 (set_attr "mode" "SF,XF,DF")])
3542 (define_insn "*extendsfdf2_sse"
3543 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3544 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3545 "TARGET_SSE2 && TARGET_SSE_MATH
3546 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3547 "cvtss2sd\t{%1, %0|%0, %1}"
3548 [(set_attr "type" "ssecvt")
3549 (set_attr "mode" "DF")])
3551 (define_insn "*extendsfdf2_i387"
3552 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3553 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3555 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3557 switch (which_alternative)
3560 return output_387_reg_move (insn, operands);
3563 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3564 return "fstp%z0\t%y0";
3566 return "fst%z0\t%y0";
3572 [(set_attr "type" "fmov")
3573 (set_attr "mode" "SF,XF")])
3575 (define_expand "extendsfxf2"
3576 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3577 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3580 /* ??? Needed for compress_float_constant since all fp constants
3581 are LEGITIMATE_CONSTANT_P. */
3582 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3583 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3584 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3585 operands[1] = force_reg (SFmode, operands[1]);
3588 (define_insn "*extendsfxf2_i387"
3589 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3590 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3592 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3594 switch (which_alternative)
3597 return output_387_reg_move (insn, operands);
3600 /* There is no non-popping store to memory for XFmode. So if
3601 we need one, follow the store with a load. */
3602 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3603 return "fstp%z0\t%y0";
3605 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3611 [(set_attr "type" "fmov")
3612 (set_attr "mode" "SF,XF")])
3614 (define_expand "extenddfxf2"
3615 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3616 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3619 /* ??? Needed for compress_float_constant since all fp constants
3620 are LEGITIMATE_CONSTANT_P. */
3621 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3622 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3623 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3624 operands[1] = force_reg (DFmode, operands[1]);
3627 (define_insn "*extenddfxf2_i387"
3628 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3629 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3631 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3633 switch (which_alternative)
3636 return output_387_reg_move (insn, operands);
3639 /* There is no non-popping store to memory for XFmode. So if
3640 we need one, follow the store with a load. */
3641 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3642 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3644 return "fstp%z0\t%y0";
3650 [(set_attr "type" "fmov")
3651 (set_attr "mode" "DF,XF")])
3653 ;; %%% This seems bad bad news.
3654 ;; This cannot output into an f-reg because there is no way to be sure
3655 ;; of truncating in that case. Otherwise this is just like a simple move
3656 ;; insn. So we pretend we can output to a reg in order to get better
3657 ;; register preferencing, but we really use a stack slot.
3659 ;; Conversion from DFmode to SFmode.
3661 (define_expand "truncdfsf2"
3662 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3664 (match_operand:DF 1 "nonimmediate_operand" "")))]
3665 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3667 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3668 operands[1] = force_reg (DFmode, operands[1]);
3670 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3672 else if (flag_unsafe_math_optimizations)
3676 rtx temp = assign_386_stack_local (SFmode, 0);
3677 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3682 (define_expand "truncdfsf2_with_temp"
3683 [(parallel [(set (match_operand:SF 0 "" "")
3684 (float_truncate:SF (match_operand:DF 1 "" "")))
3685 (clobber (match_operand:SF 2 "" ""))])]
3688 (define_insn "*truncdfsf_fast_mixed"
3689 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3691 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3692 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3694 switch (which_alternative)
3697 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3698 return "fstp%z0\t%y0";
3700 return "fst%z0\t%y0";
3702 return output_387_reg_move (insn, operands);
3704 return "cvtsd2ss\t{%1, %0|%0, %1}";
3709 [(set_attr "type" "fmov,fmov,ssecvt")
3710 (set_attr "mode" "SF")])
3712 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3713 ;; because nothing we do here is unsafe.
3714 (define_insn "*truncdfsf_fast_sse"
3715 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3717 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3718 "TARGET_SSE2 && TARGET_SSE_MATH"
3719 "cvtsd2ss\t{%1, %0|%0, %1}"
3720 [(set_attr "type" "ssecvt")
3721 (set_attr "mode" "SF")])
3723 (define_insn "*truncdfsf_fast_i387"
3724 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3726 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3727 "TARGET_80387 && flag_unsafe_math_optimizations"
3728 "* return output_387_reg_move (insn, operands);"
3729 [(set_attr "type" "fmov")
3730 (set_attr "mode" "SF")])
3732 (define_insn "*truncdfsf_mixed"
3733 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3735 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3736 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3737 "TARGET_MIX_SSE_I387"
3739 switch (which_alternative)
3742 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3743 return "fstp%z0\t%y0";
3745 return "fst%z0\t%y0";
3749 return "cvtsd2ss\t{%1, %0|%0, %1}";
3754 [(set_attr "type" "fmov,multi,ssecvt")
3755 (set_attr "mode" "SF")])
3757 (define_insn "*truncdfsf_i387"
3758 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3760 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3761 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3764 switch (which_alternative)
3767 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3768 return "fstp%z0\t%y0";
3770 return "fst%z0\t%y0";
3777 [(set_attr "type" "fmov,multi")
3778 (set_attr "mode" "SF")])
3780 (define_insn "*truncdfsf2_i387_1"
3781 [(set (match_operand:SF 0 "memory_operand" "=m")
3783 (match_operand:DF 1 "register_operand" "f")))]
3785 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3786 && !TARGET_MIX_SSE_I387"
3788 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3789 return "fstp%z0\t%y0";
3791 return "fst%z0\t%y0";
3793 [(set_attr "type" "fmov")
3794 (set_attr "mode" "SF")])
3797 [(set (match_operand:SF 0 "register_operand" "")
3799 (match_operand:DF 1 "fp_register_operand" "")))
3800 (clobber (match_operand 2 "" ""))]
3802 [(set (match_dup 2) (match_dup 1))
3803 (set (match_dup 0) (match_dup 2))]
3805 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3808 ;; Conversion from XFmode to SFmode.
3810 (define_expand "truncxfsf2"
3811 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3813 (match_operand:XF 1 "register_operand" "")))
3814 (clobber (match_dup 2))])]
3817 if (flag_unsafe_math_optimizations)
3819 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3820 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3821 if (reg != operands[0])
3822 emit_move_insn (operands[0], reg);
3826 operands[2] = assign_386_stack_local (SFmode, 0);
3829 (define_insn "*truncxfsf2_mixed"
3830 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
3832 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3833 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3834 "TARGET_MIX_SSE_I387"
3836 switch (which_alternative)
3839 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3840 return "fstp%z0\t%y0";
3842 return "fst%z0\t%y0";
3847 [(set_attr "type" "fmov,multi,multi,multi")
3848 (set_attr "mode" "SF")])
3850 (define_insn "truncxfsf2_i387_noop"
3851 [(set (match_operand:SF 0 "register_operand" "=f")
3852 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3853 "TARGET_80387 && flag_unsafe_math_optimizations"
3855 return output_387_reg_move (insn, operands);
3857 [(set_attr "type" "fmov")
3858 (set_attr "mode" "SF")])
3860 (define_insn "*truncxfsf2_i387"
3861 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3863 (match_operand:XF 1 "register_operand" "f,f,f")))
3864 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3867 switch (which_alternative)
3870 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3871 return "fstp%z0\t%y0";
3873 return "fst%z0\t%y0";
3878 [(set_attr "type" "fmov,multi,multi")
3879 (set_attr "mode" "SF")])
3881 (define_insn "*truncxfsf2_i387_1"
3882 [(set (match_operand:SF 0 "memory_operand" "=m")
3884 (match_operand:XF 1 "register_operand" "f")))]
3887 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3888 return "fstp%z0\t%y0";
3890 return "fst%z0\t%y0";
3892 [(set_attr "type" "fmov")
3893 (set_attr "mode" "SF")])
3896 [(set (match_operand:SF 0 "register_operand" "")
3898 (match_operand:XF 1 "register_operand" "")))
3899 (clobber (match_operand:SF 2 "memory_operand" ""))]
3900 "TARGET_80387 && reload_completed"
3901 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3902 (set (match_dup 0) (match_dup 2))]
3906 [(set (match_operand:SF 0 "memory_operand" "")
3908 (match_operand:XF 1 "register_operand" "")))
3909 (clobber (match_operand:SF 2 "memory_operand" ""))]
3911 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3914 ;; Conversion from XFmode to DFmode.
3916 (define_expand "truncxfdf2"
3917 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3919 (match_operand:XF 1 "register_operand" "")))
3920 (clobber (match_dup 2))])]
3923 if (flag_unsafe_math_optimizations)
3925 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3926 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3927 if (reg != operands[0])
3928 emit_move_insn (operands[0], reg);
3932 operands[2] = assign_386_stack_local (DFmode, 0);
3935 (define_insn "*truncxfdf2_mixed"
3936 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
3938 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3939 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3940 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3942 switch (which_alternative)
3945 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3946 return "fstp%z0\t%y0";
3948 return "fst%z0\t%y0";
3954 [(set_attr "type" "fmov,multi,multi,multi")
3955 (set_attr "mode" "DF")])
3957 (define_insn "truncxfdf2_i387_noop"
3958 [(set (match_operand:DF 0 "register_operand" "=f")
3959 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3960 "TARGET_80387 && flag_unsafe_math_optimizations"
3962 return output_387_reg_move (insn, operands);
3964 [(set_attr "type" "fmov")
3965 (set_attr "mode" "DF")])
3967 (define_insn "*truncxfdf2_i387"
3968 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#r,?r#f")
3970 (match_operand:XF 1 "register_operand" "f,f,f")))
3971 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
3974 switch (which_alternative)
3977 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3978 return "fstp%z0\t%y0";
3980 return "fst%z0\t%y0";
3985 [(set_attr "type" "fmov,multi,multi")
3986 (set_attr "mode" "DF")])
3988 (define_insn "*truncxfdf2_i387_1"
3989 [(set (match_operand:DF 0 "memory_operand" "=m")
3991 (match_operand:XF 1 "register_operand" "f")))]
3994 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3995 return "fstp%z0\t%y0";
3997 return "fst%z0\t%y0";
3999 [(set_attr "type" "fmov")
4000 (set_attr "mode" "DF")])
4003 [(set (match_operand:DF 0 "register_operand" "")
4005 (match_operand:XF 1 "register_operand" "")))
4006 (clobber (match_operand:DF 2 "memory_operand" ""))]
4007 "TARGET_80387 && reload_completed"
4008 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4009 (set (match_dup 0) (match_dup 2))]
4013 [(set (match_operand:DF 0 "memory_operand" "")
4015 (match_operand:XF 1 "register_operand" "")))
4016 (clobber (match_operand:DF 2 "memory_operand" ""))]
4018 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4021 ;; Signed conversion to DImode.
4023 (define_expand "fix_truncxfdi2"
4024 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4025 (fix:DI (match_operand:XF 1 "register_operand" "")))
4026 (clobber (reg:CC FLAGS_REG))])]
4031 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4036 (define_expand "fix_trunc<mode>di2"
4037 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4038 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4039 (clobber (reg:CC FLAGS_REG))])]
4040 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4043 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4045 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4048 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4050 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4051 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4052 if (out != operands[0])
4053 emit_move_insn (operands[0], out);
4058 ;; Signed conversion to SImode.
4060 (define_expand "fix_truncxfsi2"
4061 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4062 (fix:SI (match_operand:XF 1 "register_operand" "")))
4063 (clobber (reg:CC FLAGS_REG))])]
4068 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4073 (define_expand "fix_trunc<mode>si2"
4074 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4075 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4076 (clobber (reg:CC FLAGS_REG))])]
4077 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode))"
4080 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4082 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4085 if (SSE_FLOAT_MODE_P (<MODE>mode))
4087 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4088 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4089 if (out != operands[0])
4090 emit_move_insn (operands[0], out);
4095 ;; Signed conversion to HImode.
4097 (define_expand "fix_trunc<mode>hi2"
4098 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4099 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4100 (clobber (reg:CC FLAGS_REG))])]
4102 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4106 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4111 ;; When SSE is available, it is always faster to use it!
4112 (define_insn "fix_truncsfdi_sse"
4113 [(set (match_operand:DI 0 "register_operand" "=r,r")
4114 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4115 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4116 "cvttss2si{q}\t{%1, %0|%0, %1}"
4117 [(set_attr "type" "sseicvt")
4118 (set_attr "mode" "SF")
4119 (set_attr "athlon_decode" "double,vector")])
4121 (define_insn "fix_truncdfdi_sse"
4122 [(set (match_operand:DI 0 "register_operand" "=r,r")
4123 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4124 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4125 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4126 [(set_attr "type" "sseicvt")
4127 (set_attr "mode" "DF")
4128 (set_attr "athlon_decode" "double,vector")])
4130 (define_insn "fix_truncsfsi_sse"
4131 [(set (match_operand:SI 0 "register_operand" "=r,r")
4132 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4133 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4134 "cvttss2si\t{%1, %0|%0, %1}"
4135 [(set_attr "type" "sseicvt")
4136 (set_attr "mode" "DF")
4137 (set_attr "athlon_decode" "double,vector")])
4139 (define_insn "fix_truncdfsi_sse"
4140 [(set (match_operand:SI 0 "register_operand" "=r,r")
4141 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4142 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4143 "cvttsd2si\t{%1, %0|%0, %1}"
4144 [(set_attr "type" "sseicvt")
4145 (set_attr "mode" "DF")
4146 (set_attr "athlon_decode" "double,vector")])
4148 ;; Avoid vector decoded forms of the instruction.
4150 [(match_scratch:DF 2 "Y")
4151 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4152 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4153 "TARGET_K8 && !optimize_size"
4154 [(set (match_dup 2) (match_dup 1))
4155 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4159 [(match_scratch:SF 2 "x")
4160 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4161 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4162 "TARGET_K8 && !optimize_size"
4163 [(set (match_dup 2) (match_dup 1))
4164 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4167 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4168 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4169 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4170 "TARGET_80387 && TARGET_FISTTP
4171 && FLOAT_MODE_P (GET_MODE (operands[1]))
4172 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4173 && (TARGET_64BIT || <MODE>mode != DImode))
4175 && !(reload_completed || reload_in_progress)"
4180 if (memory_operand (operands[0], VOIDmode))
4181 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4184 operands[2] = assign_386_stack_local (<MODE>mode, 0);
4185 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4191 [(set_attr "type" "fisttp")
4192 (set_attr "mode" "<MODE>")])
4194 (define_insn "fix_trunc<mode>_i387_fisttp"
4195 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4196 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4197 (clobber (match_scratch:XF 2 "=&1f"))]
4198 "TARGET_80387 && TARGET_FISTTP
4199 && FLOAT_MODE_P (GET_MODE (operands[1]))
4200 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201 && (TARGET_64BIT || <MODE>mode != DImode))
4202 && TARGET_SSE_MATH)"
4203 "* return output_fix_trunc (insn, operands, 1);"
4204 [(set_attr "type" "fisttp")
4205 (set_attr "mode" "<MODE>")])
4207 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4208 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4209 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4210 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4211 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4212 "TARGET_80387 && TARGET_FISTTP
4213 && FLOAT_MODE_P (GET_MODE (operands[1]))
4214 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4215 && (TARGET_64BIT || <MODE>mode != DImode))
4216 && TARGET_SSE_MATH)"
4218 [(set_attr "type" "fisttp")
4219 (set_attr "mode" "<MODE>")])
4222 [(set (match_operand:X87MODEI 0 "register_operand" "")
4223 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4224 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4225 (clobber (match_scratch 3 ""))]
4227 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4228 (clobber (match_dup 3))])
4229 (set (match_dup 0) (match_dup 2))]
4233 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4234 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4235 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4236 (clobber (match_scratch 3 ""))]
4238 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4239 (clobber (match_dup 3))])]
4242 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4243 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4244 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4245 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4246 ;; function in i386.c.
4247 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4248 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4249 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4250 (clobber (reg:CC FLAGS_REG))]
4251 "TARGET_80387 && !TARGET_FISTTP
4252 && FLOAT_MODE_P (GET_MODE (operands[1]))
4253 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4254 && (TARGET_64BIT || <MODE>mode != DImode))
4255 && !(reload_completed || reload_in_progress)"
4260 ix86_optimize_mode_switching = 1;
4261 operands[2] = assign_386_stack_local (HImode, 1);
4262 operands[3] = assign_386_stack_local (HImode, 2);
4263 if (memory_operand (operands[0], VOIDmode))
4264 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4265 operands[2], operands[3]));
4268 operands[4] = assign_386_stack_local (<MODE>mode, 0);
4269 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4270 operands[2], operands[3],
4275 [(set_attr "type" "fistp")
4276 (set_attr "i387_cw" "trunc")
4277 (set_attr "mode" "<MODE>")])
4279 (define_insn "fix_truncdi_i387"
4280 [(set (match_operand:DI 0 "memory_operand" "=m")
4281 (fix:DI (match_operand 1 "register_operand" "f")))
4282 (use (match_operand:HI 2 "memory_operand" "m"))
4283 (use (match_operand:HI 3 "memory_operand" "m"))
4284 (clobber (match_scratch:XF 4 "=&1f"))]
4285 "TARGET_80387 && !TARGET_FISTTP
4286 && FLOAT_MODE_P (GET_MODE (operands[1]))
4287 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4288 "* return output_fix_trunc (insn, operands, 0);"
4289 [(set_attr "type" "fistp")
4290 (set_attr "i387_cw" "trunc")
4291 (set_attr "mode" "DI")])
4293 (define_insn "fix_truncdi_i387_with_temp"
4294 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4295 (fix:DI (match_operand 1 "register_operand" "f,f")))
4296 (use (match_operand:HI 2 "memory_operand" "m,m"))
4297 (use (match_operand:HI 3 "memory_operand" "m,m"))
4298 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4299 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4300 "TARGET_80387 && !TARGET_FISTTP
4301 && FLOAT_MODE_P (GET_MODE (operands[1]))
4302 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4304 [(set_attr "type" "fistp")
4305 (set_attr "i387_cw" "trunc")
4306 (set_attr "mode" "DI")])
4309 [(set (match_operand:DI 0 "register_operand" "")
4310 (fix:DI (match_operand 1 "register_operand" "")))
4311 (use (match_operand:HI 2 "memory_operand" ""))
4312 (use (match_operand:HI 3 "memory_operand" ""))
4313 (clobber (match_operand:DI 4 "memory_operand" ""))
4314 (clobber (match_scratch 5 ""))]
4316 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4319 (clobber (match_dup 5))])
4320 (set (match_dup 0) (match_dup 4))]
4324 [(set (match_operand:DI 0 "memory_operand" "")
4325 (fix:DI (match_operand 1 "register_operand" "")))
4326 (use (match_operand:HI 2 "memory_operand" ""))
4327 (use (match_operand:HI 3 "memory_operand" ""))
4328 (clobber (match_operand:DI 4 "memory_operand" ""))
4329 (clobber (match_scratch 5 ""))]
4331 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4334 (clobber (match_dup 5))])]
4337 (define_insn "fix_trunc<mode>_i387"
4338 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4339 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4340 (use (match_operand:HI 2 "memory_operand" "m"))
4341 (use (match_operand:HI 3 "memory_operand" "m"))]
4342 "TARGET_80387 && !TARGET_FISTTP
4343 && FLOAT_MODE_P (GET_MODE (operands[1]))
4344 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4345 "* return output_fix_trunc (insn, operands, 0);"
4346 [(set_attr "type" "fistp")
4347 (set_attr "i387_cw" "trunc")
4348 (set_attr "mode" "<MODE>")])
4350 (define_insn "fix_trunc<mode>_i387_with_temp"
4351 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4352 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4353 (use (match_operand:HI 2 "memory_operand" "m,m"))
4354 (use (match_operand:HI 3 "memory_operand" "m,m"))
4355 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4356 "TARGET_80387 && !TARGET_FISTTP
4357 && FLOAT_MODE_P (GET_MODE (operands[1]))
4358 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4360 [(set_attr "type" "fistp")
4361 (set_attr "i387_cw" "trunc")
4362 (set_attr "mode" "<MODE>")])
4365 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4366 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4367 (use (match_operand:HI 2 "memory_operand" ""))
4368 (use (match_operand:HI 3 "memory_operand" ""))
4369 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4371 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4373 (use (match_dup 3))])
4374 (set (match_dup 0) (match_dup 4))]
4378 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4379 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4380 (use (match_operand:HI 2 "memory_operand" ""))
4381 (use (match_operand:HI 3 "memory_operand" ""))
4382 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4384 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4386 (use (match_dup 3))])]
4389 (define_insn "x86_fnstcw_1"
4390 [(set (match_operand:HI 0 "memory_operand" "=m")
4391 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4394 [(set_attr "length" "2")
4395 (set_attr "mode" "HI")
4396 (set_attr "unit" "i387")])
4398 (define_insn "x86_fldcw_1"
4399 [(set (reg:HI FPSR_REG)
4400 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4403 [(set_attr "length" "2")
4404 (set_attr "mode" "HI")
4405 (set_attr "unit" "i387")
4406 (set_attr "athlon_decode" "vector")])
4408 ;; Conversion between fixed point and floating point.
4410 ;; Even though we only accept memory inputs, the backend _really_
4411 ;; wants to be able to do this between registers.
4413 (define_expand "floathisf2"
4414 [(set (match_operand:SF 0 "register_operand" "")
4415 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4416 "TARGET_80387 || TARGET_SSE_MATH"
4418 if (TARGET_SSE_MATH)
4420 emit_insn (gen_floatsisf2 (operands[0],
4421 convert_to_mode (SImode, operands[1], 0)));
4426 (define_insn "*floathisf2_i387"
4427 [(set (match_operand:SF 0 "register_operand" "=f,f")
4428 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4429 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4433 [(set_attr "type" "fmov,multi")
4434 (set_attr "mode" "SF")
4435 (set_attr "fp_int_src" "true")])
4437 (define_expand "floatsisf2"
4438 [(set (match_operand:SF 0 "register_operand" "")
4439 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4440 "TARGET_80387 || TARGET_SSE_MATH"
4443 (define_insn "*floatsisf2_mixed"
4444 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4445 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4446 "TARGET_MIX_SSE_I387"
4450 cvtsi2ss\t{%1, %0|%0, %1}
4451 cvtsi2ss\t{%1, %0|%0, %1}"
4452 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4453 (set_attr "mode" "SF")
4454 (set_attr "athlon_decode" "*,*,vector,double")
4455 (set_attr "fp_int_src" "true")])
4457 (define_insn "*floatsisf2_sse"
4458 [(set (match_operand:SF 0 "register_operand" "=x,x")
4459 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4461 "cvtsi2ss\t{%1, %0|%0, %1}"
4462 [(set_attr "type" "sseicvt")
4463 (set_attr "mode" "SF")
4464 (set_attr "athlon_decode" "vector,double")
4465 (set_attr "fp_int_src" "true")])
4467 (define_insn "*floatsisf2_i387"
4468 [(set (match_operand:SF 0 "register_operand" "=f,f")
4469 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4474 [(set_attr "type" "fmov,multi")
4475 (set_attr "mode" "SF")
4476 (set_attr "fp_int_src" "true")])
4478 (define_expand "floatdisf2"
4479 [(set (match_operand:SF 0 "register_operand" "")
4480 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4481 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4484 (define_insn "*floatdisf2_mixed"
4485 [(set (match_operand:SF 0 "register_operand" "=f#x,?f#x,x#f,x#f")
4486 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4487 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4491 cvtsi2ss{q}\t{%1, %0|%0, %1}
4492 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4493 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4494 (set_attr "mode" "SF")
4495 (set_attr "athlon_decode" "*,*,vector,double")
4496 (set_attr "fp_int_src" "true")])
4498 (define_insn "*floatdisf2_sse"
4499 [(set (match_operand:SF 0 "register_operand" "=x,x")
4500 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4501 "TARGET_64BIT && TARGET_SSE_MATH"
4502 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4503 [(set_attr "type" "sseicvt")
4504 (set_attr "mode" "SF")
4505 (set_attr "athlon_decode" "vector,double")
4506 (set_attr "fp_int_src" "true")])
4508 (define_insn "*floatdisf2_i387"
4509 [(set (match_operand:SF 0 "register_operand" "=f,f")
4510 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4515 [(set_attr "type" "fmov,multi")
4516 (set_attr "mode" "SF")
4517 (set_attr "fp_int_src" "true")])
4519 (define_expand "floathidf2"
4520 [(set (match_operand:DF 0 "register_operand" "")
4521 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4522 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4524 if (TARGET_SSE2 && TARGET_SSE_MATH)
4526 emit_insn (gen_floatsidf2 (operands[0],
4527 convert_to_mode (SImode, operands[1], 0)));
4532 (define_insn "*floathidf2_i387"
4533 [(set (match_operand:DF 0 "register_operand" "=f,f")
4534 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4535 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4539 [(set_attr "type" "fmov,multi")
4540 (set_attr "mode" "DF")
4541 (set_attr "fp_int_src" "true")])
4543 (define_expand "floatsidf2"
4544 [(set (match_operand:DF 0 "register_operand" "")
4545 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4546 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4549 (define_insn "*floatsidf2_mixed"
4550 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4551 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4552 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4556 cvtsi2sd\t{%1, %0|%0, %1}
4557 cvtsi2sd\t{%1, %0|%0, %1}"
4558 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4559 (set_attr "mode" "DF")
4560 (set_attr "athlon_decode" "*,*,double,direct")
4561 (set_attr "fp_int_src" "true")])
4563 (define_insn "*floatsidf2_sse"
4564 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4565 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4566 "TARGET_SSE2 && TARGET_SSE_MATH"
4567 "cvtsi2sd\t{%1, %0|%0, %1}"
4568 [(set_attr "type" "sseicvt")
4569 (set_attr "mode" "DF")
4570 (set_attr "athlon_decode" "double,direct")
4571 (set_attr "fp_int_src" "true")])
4573 (define_insn "*floatsidf2_i387"
4574 [(set (match_operand:DF 0 "register_operand" "=f,f")
4575 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4580 [(set_attr "type" "fmov,multi")
4581 (set_attr "mode" "DF")
4582 (set_attr "fp_int_src" "true")])
4584 (define_expand "floatdidf2"
4585 [(set (match_operand:DF 0 "register_operand" "")
4586 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4587 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4590 (define_insn "*floatdidf2_mixed"
4591 [(set (match_operand:DF 0 "register_operand" "=f#Y,?f#Y,Y#f,Y#f")
4592 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4593 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4597 cvtsi2sd{q}\t{%1, %0|%0, %1}
4598 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4599 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4600 (set_attr "mode" "DF")
4601 (set_attr "athlon_decode" "*,*,double,direct")
4602 (set_attr "fp_int_src" "true")])
4604 (define_insn "*floatdidf2_sse"
4605 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4606 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4607 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4608 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4609 [(set_attr "type" "sseicvt")
4610 (set_attr "mode" "DF")
4611 (set_attr "athlon_decode" "double,direct")
4612 (set_attr "fp_int_src" "true")])
4614 (define_insn "*floatdidf2_i387"
4615 [(set (match_operand:DF 0 "register_operand" "=f,f")
4616 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4621 [(set_attr "type" "fmov,multi")
4622 (set_attr "mode" "DF")
4623 (set_attr "fp_int_src" "true")])
4625 (define_insn "floathixf2"
4626 [(set (match_operand:XF 0 "register_operand" "=f,f")
4627 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4632 [(set_attr "type" "fmov,multi")
4633 (set_attr "mode" "XF")
4634 (set_attr "fp_int_src" "true")])
4636 (define_insn "floatsixf2"
4637 [(set (match_operand:XF 0 "register_operand" "=f,f")
4638 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4643 [(set_attr "type" "fmov,multi")
4644 (set_attr "mode" "XF")
4645 (set_attr "fp_int_src" "true")])
4647 (define_insn "floatdixf2"
4648 [(set (match_operand:XF 0 "register_operand" "=f,f")
4649 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4654 [(set_attr "type" "fmov,multi")
4655 (set_attr "mode" "XF")
4656 (set_attr "fp_int_src" "true")])
4658 ;; %%% Kill these when reload knows how to do it.
4660 [(set (match_operand 0 "fp_register_operand" "")
4661 (float (match_operand 1 "register_operand" "")))]
4664 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4667 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4668 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4669 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4670 ix86_free_from_memory (GET_MODE (operands[1]));
4674 (define_expand "floatunssisf2"
4675 [(use (match_operand:SF 0 "register_operand" ""))
4676 (use (match_operand:SI 1 "register_operand" ""))]
4677 "!TARGET_64BIT && TARGET_SSE_MATH"
4678 "x86_emit_floatuns (operands); DONE;")
4680 (define_expand "floatunsdisf2"
4681 [(use (match_operand:SF 0 "register_operand" ""))
4682 (use (match_operand:DI 1 "register_operand" ""))]
4683 "TARGET_64BIT && TARGET_SSE_MATH"
4684 "x86_emit_floatuns (operands); DONE;")
4686 (define_expand "floatunsdidf2"
4687 [(use (match_operand:DF 0 "register_operand" ""))
4688 (use (match_operand:DI 1 "register_operand" ""))]
4689 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4690 "x86_emit_floatuns (operands); DONE;")
4692 ;; SSE extract/set expanders
4697 ;; %%% splits for addsidi3
4698 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4699 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4700 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4702 (define_expand "adddi3"
4703 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4704 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4705 (match_operand:DI 2 "x86_64_general_operand" "")))
4706 (clobber (reg:CC FLAGS_REG))]
4708 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4710 (define_insn "*adddi3_1"
4711 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4712 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4713 (match_operand:DI 2 "general_operand" "roiF,riF")))
4714 (clobber (reg:CC FLAGS_REG))]
4715 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4719 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4720 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4721 (match_operand:DI 2 "general_operand" "")))
4722 (clobber (reg:CC FLAGS_REG))]
4723 "!TARGET_64BIT && reload_completed"
4724 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4726 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4727 (parallel [(set (match_dup 3)
4728 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4731 (clobber (reg:CC FLAGS_REG))])]
4732 "split_di (operands+0, 1, operands+0, operands+3);
4733 split_di (operands+1, 1, operands+1, operands+4);
4734 split_di (operands+2, 1, operands+2, operands+5);")
4736 (define_insn "adddi3_carry_rex64"
4737 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4738 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4739 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4740 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4741 (clobber (reg:CC FLAGS_REG))]
4742 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4743 "adc{q}\t{%2, %0|%0, %2}"
4744 [(set_attr "type" "alu")
4745 (set_attr "pent_pair" "pu")
4746 (set_attr "mode" "DI")])
4748 (define_insn "*adddi3_cc_rex64"
4749 [(set (reg:CC FLAGS_REG)
4750 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4751 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4753 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4754 (plus:DI (match_dup 1) (match_dup 2)))]
4755 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4756 "add{q}\t{%2, %0|%0, %2}"
4757 [(set_attr "type" "alu")
4758 (set_attr "mode" "DI")])
4760 (define_insn "addqi3_carry"
4761 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4762 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4763 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4764 (match_operand:QI 2 "general_operand" "qi,qm")))
4765 (clobber (reg:CC FLAGS_REG))]
4766 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4767 "adc{b}\t{%2, %0|%0, %2}"
4768 [(set_attr "type" "alu")
4769 (set_attr "pent_pair" "pu")
4770 (set_attr "mode" "QI")])
4772 (define_insn "addhi3_carry"
4773 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4774 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4775 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4776 (match_operand:HI 2 "general_operand" "ri,rm")))
4777 (clobber (reg:CC FLAGS_REG))]
4778 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4779 "adc{w}\t{%2, %0|%0, %2}"
4780 [(set_attr "type" "alu")
4781 (set_attr "pent_pair" "pu")
4782 (set_attr "mode" "HI")])
4784 (define_insn "addsi3_carry"
4785 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4786 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4787 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4788 (match_operand:SI 2 "general_operand" "ri,rm")))
4789 (clobber (reg:CC FLAGS_REG))]
4790 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4791 "adc{l}\t{%2, %0|%0, %2}"
4792 [(set_attr "type" "alu")
4793 (set_attr "pent_pair" "pu")
4794 (set_attr "mode" "SI")])
4796 (define_insn "*addsi3_carry_zext"
4797 [(set (match_operand:DI 0 "register_operand" "=r")
4799 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4800 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4801 (match_operand:SI 2 "general_operand" "rim"))))
4802 (clobber (reg:CC FLAGS_REG))]
4803 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4804 "adc{l}\t{%2, %k0|%k0, %2}"
4805 [(set_attr "type" "alu")
4806 (set_attr "pent_pair" "pu")
4807 (set_attr "mode" "SI")])
4809 (define_insn "*addsi3_cc"
4810 [(set (reg:CC FLAGS_REG)
4811 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4812 (match_operand:SI 2 "general_operand" "ri,rm")]
4814 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4815 (plus:SI (match_dup 1) (match_dup 2)))]
4816 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4817 "add{l}\t{%2, %0|%0, %2}"
4818 [(set_attr "type" "alu")
4819 (set_attr "mode" "SI")])
4821 (define_insn "addqi3_cc"
4822 [(set (reg:CC FLAGS_REG)
4823 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4824 (match_operand:QI 2 "general_operand" "qi,qm")]
4826 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4827 (plus:QI (match_dup 1) (match_dup 2)))]
4828 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4829 "add{b}\t{%2, %0|%0, %2}"
4830 [(set_attr "type" "alu")
4831 (set_attr "mode" "QI")])
4833 (define_expand "addsi3"
4834 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4835 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4836 (match_operand:SI 2 "general_operand" "")))
4837 (clobber (reg:CC FLAGS_REG))])]
4839 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4841 (define_insn "*lea_1"
4842 [(set (match_operand:SI 0 "register_operand" "=r")
4843 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4845 "lea{l}\t{%a1, %0|%0, %a1}"
4846 [(set_attr "type" "lea")
4847 (set_attr "mode" "SI")])
4849 (define_insn "*lea_1_rex64"
4850 [(set (match_operand:SI 0 "register_operand" "=r")
4851 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4853 "lea{l}\t{%a1, %0|%0, %a1}"
4854 [(set_attr "type" "lea")
4855 (set_attr "mode" "SI")])
4857 (define_insn "*lea_1_zext"
4858 [(set (match_operand:DI 0 "register_operand" "=r")
4860 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4862 "lea{l}\t{%a1, %k0|%k0, %a1}"
4863 [(set_attr "type" "lea")
4864 (set_attr "mode" "SI")])
4866 (define_insn "*lea_2_rex64"
4867 [(set (match_operand:DI 0 "register_operand" "=r")
4868 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4870 "lea{q}\t{%a1, %0|%0, %a1}"
4871 [(set_attr "type" "lea")
4872 (set_attr "mode" "DI")])
4874 ;; The lea patterns for non-Pmodes needs to be matched by several
4875 ;; insns converted to real lea by splitters.
4877 (define_insn_and_split "*lea_general_1"
4878 [(set (match_operand 0 "register_operand" "=r")
4879 (plus (plus (match_operand 1 "index_register_operand" "l")
4880 (match_operand 2 "register_operand" "r"))
4881 (match_operand 3 "immediate_operand" "i")))]
4882 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4883 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4884 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4885 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4886 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4887 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4888 || GET_MODE (operands[3]) == VOIDmode)"
4890 "&& reload_completed"
4894 operands[0] = gen_lowpart (SImode, operands[0]);
4895 operands[1] = gen_lowpart (Pmode, operands[1]);
4896 operands[2] = gen_lowpart (Pmode, operands[2]);
4897 operands[3] = gen_lowpart (Pmode, operands[3]);
4898 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4900 if (Pmode != SImode)
4901 pat = gen_rtx_SUBREG (SImode, pat, 0);
4902 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4905 [(set_attr "type" "lea")
4906 (set_attr "mode" "SI")])
4908 (define_insn_and_split "*lea_general_1_zext"
4909 [(set (match_operand:DI 0 "register_operand" "=r")
4911 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4912 (match_operand:SI 2 "register_operand" "r"))
4913 (match_operand:SI 3 "immediate_operand" "i"))))]
4916 "&& reload_completed"
4918 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4920 (match_dup 3)) 0)))]
4922 operands[1] = gen_lowpart (Pmode, operands[1]);
4923 operands[2] = gen_lowpart (Pmode, operands[2]);
4924 operands[3] = gen_lowpart (Pmode, operands[3]);
4926 [(set_attr "type" "lea")
4927 (set_attr "mode" "SI")])
4929 (define_insn_and_split "*lea_general_2"
4930 [(set (match_operand 0 "register_operand" "=r")
4931 (plus (mult (match_operand 1 "index_register_operand" "l")
4932 (match_operand 2 "const248_operand" "i"))
4933 (match_operand 3 "nonmemory_operand" "ri")))]
4934 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4935 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4936 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4937 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4938 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4939 || GET_MODE (operands[3]) == VOIDmode)"
4941 "&& reload_completed"
4945 operands[0] = gen_lowpart (SImode, operands[0]);
4946 operands[1] = gen_lowpart (Pmode, operands[1]);
4947 operands[3] = gen_lowpart (Pmode, operands[3]);
4948 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
4950 if (Pmode != SImode)
4951 pat = gen_rtx_SUBREG (SImode, pat, 0);
4952 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4955 [(set_attr "type" "lea")
4956 (set_attr "mode" "SI")])
4958 (define_insn_and_split "*lea_general_2_zext"
4959 [(set (match_operand:DI 0 "register_operand" "=r")
4961 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
4962 (match_operand:SI 2 "const248_operand" "n"))
4963 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
4966 "&& reload_completed"
4968 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
4970 (match_dup 3)) 0)))]
4972 operands[1] = gen_lowpart (Pmode, operands[1]);
4973 operands[3] = gen_lowpart (Pmode, operands[3]);
4975 [(set_attr "type" "lea")
4976 (set_attr "mode" "SI")])
4978 (define_insn_and_split "*lea_general_3"
4979 [(set (match_operand 0 "register_operand" "=r")
4980 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
4981 (match_operand 2 "const248_operand" "i"))
4982 (match_operand 3 "register_operand" "r"))
4983 (match_operand 4 "immediate_operand" "i")))]
4984 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4985 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4986 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4987 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4988 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
4990 "&& reload_completed"
4994 operands[0] = gen_lowpart (SImode, operands[0]);
4995 operands[1] = gen_lowpart (Pmode, operands[1]);
4996 operands[3] = gen_lowpart (Pmode, operands[3]);
4997 operands[4] = gen_lowpart (Pmode, operands[4]);
4998 pat = gen_rtx_PLUS (Pmode,
4999 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5003 if (Pmode != SImode)
5004 pat = gen_rtx_SUBREG (SImode, pat, 0);
5005 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5008 [(set_attr "type" "lea")
5009 (set_attr "mode" "SI")])
5011 (define_insn_and_split "*lea_general_3_zext"
5012 [(set (match_operand:DI 0 "register_operand" "=r")
5014 (plus:SI (plus:SI (mult:SI
5015 (match_operand:SI 1 "index_register_operand" "l")
5016 (match_operand:SI 2 "const248_operand" "n"))
5017 (match_operand:SI 3 "register_operand" "r"))
5018 (match_operand:SI 4 "immediate_operand" "i"))))]
5021 "&& reload_completed"
5023 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5026 (match_dup 4)) 0)))]
5028 operands[1] = gen_lowpart (Pmode, operands[1]);
5029 operands[3] = gen_lowpart (Pmode, operands[3]);
5030 operands[4] = gen_lowpart (Pmode, operands[4]);
5032 [(set_attr "type" "lea")
5033 (set_attr "mode" "SI")])
5035 (define_insn "*adddi_1_rex64"
5036 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5037 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5038 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5039 (clobber (reg:CC FLAGS_REG))]
5040 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5042 switch (get_attr_type (insn))
5045 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5046 return "lea{q}\t{%a2, %0|%0, %a2}";
5049 if (! rtx_equal_p (operands[0], operands[1]))
5051 if (operands[2] == const1_rtx)
5052 return "inc{q}\t%0";
5053 else if (operands[2] == constm1_rtx)
5054 return "dec{q}\t%0";
5059 if (! rtx_equal_p (operands[0], operands[1]))
5062 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5063 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5064 if (GET_CODE (operands[2]) == CONST_INT
5065 /* Avoid overflows. */
5066 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5067 && (INTVAL (operands[2]) == 128
5068 || (INTVAL (operands[2]) < 0
5069 && INTVAL (operands[2]) != -128)))
5071 operands[2] = GEN_INT (-INTVAL (operands[2]));
5072 return "sub{q}\t{%2, %0|%0, %2}";
5074 return "add{q}\t{%2, %0|%0, %2}";
5078 (cond [(eq_attr "alternative" "2")
5079 (const_string "lea")
5080 ; Current assemblers are broken and do not allow @GOTOFF in
5081 ; ought but a memory context.
5082 (match_operand:DI 2 "pic_symbolic_operand" "")
5083 (const_string "lea")
5084 (match_operand:DI 2 "incdec_operand" "")
5085 (const_string "incdec")
5087 (const_string "alu")))
5088 (set_attr "mode" "DI")])
5090 ;; Convert lea to the lea pattern to avoid flags dependency.
5092 [(set (match_operand:DI 0 "register_operand" "")
5093 (plus:DI (match_operand:DI 1 "register_operand" "")
5094 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5095 (clobber (reg:CC FLAGS_REG))]
5096 "TARGET_64BIT && reload_completed
5097 && true_regnum (operands[0]) != true_regnum (operands[1])"
5099 (plus:DI (match_dup 1)
5103 (define_insn "*adddi_2_rex64"
5104 [(set (reg FLAGS_REG)
5106 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5107 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5109 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5110 (plus:DI (match_dup 1) (match_dup 2)))]
5111 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5112 && ix86_binary_operator_ok (PLUS, DImode, operands)
5113 /* Current assemblers are broken and do not allow @GOTOFF in
5114 ought but a memory context. */
5115 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5117 switch (get_attr_type (insn))
5120 if (! rtx_equal_p (operands[0], operands[1]))
5122 if (operands[2] == const1_rtx)
5123 return "inc{q}\t%0";
5124 else if (operands[2] == constm1_rtx)
5125 return "dec{q}\t%0";
5130 if (! rtx_equal_p (operands[0], operands[1]))
5132 /* ???? We ought to handle there the 32bit case too
5133 - do we need new constraint? */
5134 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5135 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5136 if (GET_CODE (operands[2]) == CONST_INT
5137 /* Avoid overflows. */
5138 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5139 && (INTVAL (operands[2]) == 128
5140 || (INTVAL (operands[2]) < 0
5141 && INTVAL (operands[2]) != -128)))
5143 operands[2] = GEN_INT (-INTVAL (operands[2]));
5144 return "sub{q}\t{%2, %0|%0, %2}";
5146 return "add{q}\t{%2, %0|%0, %2}";
5150 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5151 (const_string "incdec")
5152 (const_string "alu")))
5153 (set_attr "mode" "DI")])
5155 (define_insn "*adddi_3_rex64"
5156 [(set (reg FLAGS_REG)
5157 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5158 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5159 (clobber (match_scratch:DI 0 "=r"))]
5161 && ix86_match_ccmode (insn, CCZmode)
5162 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5163 /* Current assemblers are broken and do not allow @GOTOFF in
5164 ought but a memory context. */
5165 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5167 switch (get_attr_type (insn))
5170 if (! rtx_equal_p (operands[0], operands[1]))
5172 if (operands[2] == const1_rtx)
5173 return "inc{q}\t%0";
5174 else if (operands[2] == constm1_rtx)
5175 return "dec{q}\t%0";
5180 if (! rtx_equal_p (operands[0], operands[1]))
5182 /* ???? We ought to handle there the 32bit case too
5183 - do we need new constraint? */
5184 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5185 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5186 if (GET_CODE (operands[2]) == CONST_INT
5187 /* Avoid overflows. */
5188 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5189 && (INTVAL (operands[2]) == 128
5190 || (INTVAL (operands[2]) < 0
5191 && INTVAL (operands[2]) != -128)))
5193 operands[2] = GEN_INT (-INTVAL (operands[2]));
5194 return "sub{q}\t{%2, %0|%0, %2}";
5196 return "add{q}\t{%2, %0|%0, %2}";
5200 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5201 (const_string "incdec")
5202 (const_string "alu")))
5203 (set_attr "mode" "DI")])
5205 ; For comparisons against 1, -1 and 128, we may generate better code
5206 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5207 ; is matched then. We can't accept general immediate, because for
5208 ; case of overflows, the result is messed up.
5209 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5211 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5212 ; only for comparisons not depending on it.
5213 (define_insn "*adddi_4_rex64"
5214 [(set (reg FLAGS_REG)
5215 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5216 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5217 (clobber (match_scratch:DI 0 "=rm"))]
5219 && ix86_match_ccmode (insn, CCGCmode)"
5221 switch (get_attr_type (insn))
5224 if (operands[2] == constm1_rtx)
5225 return "inc{q}\t%0";
5226 else if (operands[2] == const1_rtx)
5227 return "dec{q}\t%0";
5232 if (! rtx_equal_p (operands[0], operands[1]))
5234 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5235 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5236 if ((INTVAL (operands[2]) == -128
5237 || (INTVAL (operands[2]) > 0
5238 && INTVAL (operands[2]) != 128))
5239 /* Avoid overflows. */
5240 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5241 return "sub{q}\t{%2, %0|%0, %2}";
5242 operands[2] = GEN_INT (-INTVAL (operands[2]));
5243 return "add{q}\t{%2, %0|%0, %2}";
5247 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5248 (const_string "incdec")
5249 (const_string "alu")))
5250 (set_attr "mode" "DI")])
5252 (define_insn "*adddi_5_rex64"
5253 [(set (reg FLAGS_REG)
5255 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5256 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5258 (clobber (match_scratch:DI 0 "=r"))]
5260 && ix86_match_ccmode (insn, CCGOCmode)
5261 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5262 /* Current assemblers are broken and do not allow @GOTOFF in
5263 ought but a memory context. */
5264 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5266 switch (get_attr_type (insn))
5269 if (! rtx_equal_p (operands[0], operands[1]))
5271 if (operands[2] == const1_rtx)
5272 return "inc{q}\t%0";
5273 else if (operands[2] == constm1_rtx)
5274 return "dec{q}\t%0";
5279 if (! rtx_equal_p (operands[0], operands[1]))
5281 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5282 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5283 if (GET_CODE (operands[2]) == CONST_INT
5284 /* Avoid overflows. */
5285 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5286 && (INTVAL (operands[2]) == 128
5287 || (INTVAL (operands[2]) < 0
5288 && INTVAL (operands[2]) != -128)))
5290 operands[2] = GEN_INT (-INTVAL (operands[2]));
5291 return "sub{q}\t{%2, %0|%0, %2}";
5293 return "add{q}\t{%2, %0|%0, %2}";
5297 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5298 (const_string "incdec")
5299 (const_string "alu")))
5300 (set_attr "mode" "DI")])
5303 (define_insn "*addsi_1"
5304 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5305 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5306 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5307 (clobber (reg:CC FLAGS_REG))]
5308 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5310 switch (get_attr_type (insn))
5313 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5314 return "lea{l}\t{%a2, %0|%0, %a2}";
5317 if (! rtx_equal_p (operands[0], operands[1]))
5319 if (operands[2] == const1_rtx)
5320 return "inc{l}\t%0";
5321 else if (operands[2] == constm1_rtx)
5322 return "dec{l}\t%0";
5327 if (! rtx_equal_p (operands[0], operands[1]))
5330 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5331 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5332 if (GET_CODE (operands[2]) == CONST_INT
5333 && (INTVAL (operands[2]) == 128
5334 || (INTVAL (operands[2]) < 0
5335 && INTVAL (operands[2]) != -128)))
5337 operands[2] = GEN_INT (-INTVAL (operands[2]));
5338 return "sub{l}\t{%2, %0|%0, %2}";
5340 return "add{l}\t{%2, %0|%0, %2}";
5344 (cond [(eq_attr "alternative" "2")
5345 (const_string "lea")
5346 ; Current assemblers are broken and do not allow @GOTOFF in
5347 ; ought but a memory context.
5348 (match_operand:SI 2 "pic_symbolic_operand" "")
5349 (const_string "lea")
5350 (match_operand:SI 2 "incdec_operand" "")
5351 (const_string "incdec")
5353 (const_string "alu")))
5354 (set_attr "mode" "SI")])
5356 ;; Convert lea to the lea pattern to avoid flags dependency.
5358 [(set (match_operand 0 "register_operand" "")
5359 (plus (match_operand 1 "register_operand" "")
5360 (match_operand 2 "nonmemory_operand" "")))
5361 (clobber (reg:CC FLAGS_REG))]
5363 && true_regnum (operands[0]) != true_regnum (operands[1])"
5367 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5368 may confuse gen_lowpart. */
5369 if (GET_MODE (operands[0]) != Pmode)
5371 operands[1] = gen_lowpart (Pmode, operands[1]);
5372 operands[2] = gen_lowpart (Pmode, operands[2]);
5374 operands[0] = gen_lowpart (SImode, operands[0]);
5375 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5376 if (Pmode != SImode)
5377 pat = gen_rtx_SUBREG (SImode, pat, 0);
5378 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5382 ;; It may seem that nonimmediate operand is proper one for operand 1.
5383 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5384 ;; we take care in ix86_binary_operator_ok to not allow two memory
5385 ;; operands so proper swapping will be done in reload. This allow
5386 ;; patterns constructed from addsi_1 to match.
5387 (define_insn "addsi_1_zext"
5388 [(set (match_operand:DI 0 "register_operand" "=r,r")
5390 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5391 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5392 (clobber (reg:CC FLAGS_REG))]
5393 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5395 switch (get_attr_type (insn))
5398 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5399 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5402 if (operands[2] == const1_rtx)
5403 return "inc{l}\t%k0";
5404 else if (operands[2] == constm1_rtx)
5405 return "dec{l}\t%k0";
5410 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5411 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5412 if (GET_CODE (operands[2]) == CONST_INT
5413 && (INTVAL (operands[2]) == 128
5414 || (INTVAL (operands[2]) < 0
5415 && INTVAL (operands[2]) != -128)))
5417 operands[2] = GEN_INT (-INTVAL (operands[2]));
5418 return "sub{l}\t{%2, %k0|%k0, %2}";
5420 return "add{l}\t{%2, %k0|%k0, %2}";
5424 (cond [(eq_attr "alternative" "1")
5425 (const_string "lea")
5426 ; Current assemblers are broken and do not allow @GOTOFF in
5427 ; ought but a memory context.
5428 (match_operand:SI 2 "pic_symbolic_operand" "")
5429 (const_string "lea")
5430 (match_operand:SI 2 "incdec_operand" "")
5431 (const_string "incdec")
5433 (const_string "alu")))
5434 (set_attr "mode" "SI")])
5436 ;; Convert lea to the lea pattern to avoid flags dependency.
5438 [(set (match_operand:DI 0 "register_operand" "")
5440 (plus:SI (match_operand:SI 1 "register_operand" "")
5441 (match_operand:SI 2 "nonmemory_operand" ""))))
5442 (clobber (reg:CC FLAGS_REG))]
5443 "TARGET_64BIT && reload_completed
5444 && true_regnum (operands[0]) != true_regnum (operands[1])"
5446 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5448 operands[1] = gen_lowpart (Pmode, operands[1]);
5449 operands[2] = gen_lowpart (Pmode, operands[2]);
5452 (define_insn "*addsi_2"
5453 [(set (reg FLAGS_REG)
5455 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5456 (match_operand:SI 2 "general_operand" "rmni,rni"))
5458 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5459 (plus:SI (match_dup 1) (match_dup 2)))]
5460 "ix86_match_ccmode (insn, CCGOCmode)
5461 && ix86_binary_operator_ok (PLUS, SImode, operands)
5462 /* Current assemblers are broken and do not allow @GOTOFF in
5463 ought but a memory context. */
5464 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5466 switch (get_attr_type (insn))
5469 if (! rtx_equal_p (operands[0], operands[1]))
5471 if (operands[2] == const1_rtx)
5472 return "inc{l}\t%0";
5473 else if (operands[2] == constm1_rtx)
5474 return "dec{l}\t%0";
5479 if (! rtx_equal_p (operands[0], operands[1]))
5481 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5482 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5483 if (GET_CODE (operands[2]) == CONST_INT
5484 && (INTVAL (operands[2]) == 128
5485 || (INTVAL (operands[2]) < 0
5486 && INTVAL (operands[2]) != -128)))
5488 operands[2] = GEN_INT (-INTVAL (operands[2]));
5489 return "sub{l}\t{%2, %0|%0, %2}";
5491 return "add{l}\t{%2, %0|%0, %2}";
5495 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5496 (const_string "incdec")
5497 (const_string "alu")))
5498 (set_attr "mode" "SI")])
5500 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5501 (define_insn "*addsi_2_zext"
5502 [(set (reg FLAGS_REG)
5504 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5505 (match_operand:SI 2 "general_operand" "rmni"))
5507 (set (match_operand:DI 0 "register_operand" "=r")
5508 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5509 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5510 && ix86_binary_operator_ok (PLUS, SImode, operands)
5511 /* Current assemblers are broken and do not allow @GOTOFF in
5512 ought but a memory context. */
5513 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5515 switch (get_attr_type (insn))
5518 if (operands[2] == const1_rtx)
5519 return "inc{l}\t%k0";
5520 else if (operands[2] == constm1_rtx)
5521 return "dec{l}\t%k0";
5526 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5527 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5528 if (GET_CODE (operands[2]) == CONST_INT
5529 && (INTVAL (operands[2]) == 128
5530 || (INTVAL (operands[2]) < 0
5531 && INTVAL (operands[2]) != -128)))
5533 operands[2] = GEN_INT (-INTVAL (operands[2]));
5534 return "sub{l}\t{%2, %k0|%k0, %2}";
5536 return "add{l}\t{%2, %k0|%k0, %2}";
5540 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5541 (const_string "incdec")
5542 (const_string "alu")))
5543 (set_attr "mode" "SI")])
5545 (define_insn "*addsi_3"
5546 [(set (reg FLAGS_REG)
5547 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5548 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5549 (clobber (match_scratch:SI 0 "=r"))]
5550 "ix86_match_ccmode (insn, CCZmode)
5551 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5552 /* Current assemblers are broken and do not allow @GOTOFF in
5553 ought but a memory context. */
5554 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5556 switch (get_attr_type (insn))
5559 if (! rtx_equal_p (operands[0], operands[1]))
5561 if (operands[2] == const1_rtx)
5562 return "inc{l}\t%0";
5563 else if (operands[2] == constm1_rtx)
5564 return "dec{l}\t%0";
5569 if (! rtx_equal_p (operands[0], operands[1]))
5571 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5572 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5573 if (GET_CODE (operands[2]) == CONST_INT
5574 && (INTVAL (operands[2]) == 128
5575 || (INTVAL (operands[2]) < 0
5576 && INTVAL (operands[2]) != -128)))
5578 operands[2] = GEN_INT (-INTVAL (operands[2]));
5579 return "sub{l}\t{%2, %0|%0, %2}";
5581 return "add{l}\t{%2, %0|%0, %2}";
5585 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5586 (const_string "incdec")
5587 (const_string "alu")))
5588 (set_attr "mode" "SI")])
5590 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5591 (define_insn "*addsi_3_zext"
5592 [(set (reg FLAGS_REG)
5593 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5594 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5595 (set (match_operand:DI 0 "register_operand" "=r")
5596 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5597 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5598 && ix86_binary_operator_ok (PLUS, SImode, operands)
5599 /* Current assemblers are broken and do not allow @GOTOFF in
5600 ought but a memory context. */
5601 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5603 switch (get_attr_type (insn))
5606 if (operands[2] == const1_rtx)
5607 return "inc{l}\t%k0";
5608 else if (operands[2] == constm1_rtx)
5609 return "dec{l}\t%k0";
5614 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5615 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5616 if (GET_CODE (operands[2]) == CONST_INT
5617 && (INTVAL (operands[2]) == 128
5618 || (INTVAL (operands[2]) < 0
5619 && INTVAL (operands[2]) != -128)))
5621 operands[2] = GEN_INT (-INTVAL (operands[2]));
5622 return "sub{l}\t{%2, %k0|%k0, %2}";
5624 return "add{l}\t{%2, %k0|%k0, %2}";
5628 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5629 (const_string "incdec")
5630 (const_string "alu")))
5631 (set_attr "mode" "SI")])
5633 ; For comparisons against 1, -1 and 128, we may generate better code
5634 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5635 ; is matched then. We can't accept general immediate, because for
5636 ; case of overflows, the result is messed up.
5637 ; This pattern also don't hold of 0x80000000, since the value overflows
5639 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5640 ; only for comparisons not depending on it.
5641 (define_insn "*addsi_4"
5642 [(set (reg FLAGS_REG)
5643 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5644 (match_operand:SI 2 "const_int_operand" "n")))
5645 (clobber (match_scratch:SI 0 "=rm"))]
5646 "ix86_match_ccmode (insn, CCGCmode)
5647 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5649 switch (get_attr_type (insn))
5652 if (operands[2] == constm1_rtx)
5653 return "inc{l}\t%0";
5654 else if (operands[2] == const1_rtx)
5655 return "dec{l}\t%0";
5660 if (! rtx_equal_p (operands[0], operands[1]))
5662 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5663 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5664 if ((INTVAL (operands[2]) == -128
5665 || (INTVAL (operands[2]) > 0
5666 && INTVAL (operands[2]) != 128)))
5667 return "sub{l}\t{%2, %0|%0, %2}";
5668 operands[2] = GEN_INT (-INTVAL (operands[2]));
5669 return "add{l}\t{%2, %0|%0, %2}";
5673 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5674 (const_string "incdec")
5675 (const_string "alu")))
5676 (set_attr "mode" "SI")])
5678 (define_insn "*addsi_5"
5679 [(set (reg FLAGS_REG)
5681 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5682 (match_operand:SI 2 "general_operand" "rmni"))
5684 (clobber (match_scratch:SI 0 "=r"))]
5685 "ix86_match_ccmode (insn, CCGOCmode)
5686 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5687 /* Current assemblers are broken and do not allow @GOTOFF in
5688 ought but a memory context. */
5689 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5691 switch (get_attr_type (insn))
5694 if (! rtx_equal_p (operands[0], operands[1]))
5696 if (operands[2] == const1_rtx)
5697 return "inc{l}\t%0";
5698 else if (operands[2] == constm1_rtx)
5699 return "dec{l}\t%0";
5704 if (! rtx_equal_p (operands[0], operands[1]))
5706 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5707 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5708 if (GET_CODE (operands[2]) == CONST_INT
5709 && (INTVAL (operands[2]) == 128
5710 || (INTVAL (operands[2]) < 0
5711 && INTVAL (operands[2]) != -128)))
5713 operands[2] = GEN_INT (-INTVAL (operands[2]));
5714 return "sub{l}\t{%2, %0|%0, %2}";
5716 return "add{l}\t{%2, %0|%0, %2}";
5720 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5721 (const_string "incdec")
5722 (const_string "alu")))
5723 (set_attr "mode" "SI")])
5725 (define_expand "addhi3"
5726 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5727 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5728 (match_operand:HI 2 "general_operand" "")))
5729 (clobber (reg:CC FLAGS_REG))])]
5730 "TARGET_HIMODE_MATH"
5731 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5733 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5734 ;; type optimizations enabled by define-splits. This is not important
5735 ;; for PII, and in fact harmful because of partial register stalls.
5737 (define_insn "*addhi_1_lea"
5738 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5739 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5740 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5741 (clobber (reg:CC FLAGS_REG))]
5742 "!TARGET_PARTIAL_REG_STALL
5743 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5745 switch (get_attr_type (insn))
5750 if (operands[2] == const1_rtx)
5751 return "inc{w}\t%0";
5752 else if (operands[2] == constm1_rtx)
5753 return "dec{w}\t%0";
5757 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5758 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5759 if (GET_CODE (operands[2]) == CONST_INT
5760 && (INTVAL (operands[2]) == 128
5761 || (INTVAL (operands[2]) < 0
5762 && INTVAL (operands[2]) != -128)))
5764 operands[2] = GEN_INT (-INTVAL (operands[2]));
5765 return "sub{w}\t{%2, %0|%0, %2}";
5767 return "add{w}\t{%2, %0|%0, %2}";
5771 (if_then_else (eq_attr "alternative" "2")
5772 (const_string "lea")
5773 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5774 (const_string "incdec")
5775 (const_string "alu"))))
5776 (set_attr "mode" "HI,HI,SI")])
5778 (define_insn "*addhi_1"
5779 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5780 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5781 (match_operand:HI 2 "general_operand" "ri,rm")))
5782 (clobber (reg:CC FLAGS_REG))]
5783 "TARGET_PARTIAL_REG_STALL
5784 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5786 switch (get_attr_type (insn))
5789 if (operands[2] == const1_rtx)
5790 return "inc{w}\t%0";
5791 else if (operands[2] == constm1_rtx)
5792 return "dec{w}\t%0";
5796 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5797 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5798 if (GET_CODE (operands[2]) == CONST_INT
5799 && (INTVAL (operands[2]) == 128
5800 || (INTVAL (operands[2]) < 0
5801 && INTVAL (operands[2]) != -128)))
5803 operands[2] = GEN_INT (-INTVAL (operands[2]));
5804 return "sub{w}\t{%2, %0|%0, %2}";
5806 return "add{w}\t{%2, %0|%0, %2}";
5810 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5811 (const_string "incdec")
5812 (const_string "alu")))
5813 (set_attr "mode" "HI")])
5815 (define_insn "*addhi_2"
5816 [(set (reg FLAGS_REG)
5818 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5819 (match_operand:HI 2 "general_operand" "rmni,rni"))
5821 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5822 (plus:HI (match_dup 1) (match_dup 2)))]
5823 "ix86_match_ccmode (insn, CCGOCmode)
5824 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5826 switch (get_attr_type (insn))
5829 if (operands[2] == const1_rtx)
5830 return "inc{w}\t%0";
5831 else if (operands[2] == constm1_rtx)
5832 return "dec{w}\t%0";
5836 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5837 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5838 if (GET_CODE (operands[2]) == CONST_INT
5839 && (INTVAL (operands[2]) == 128
5840 || (INTVAL (operands[2]) < 0
5841 && INTVAL (operands[2]) != -128)))
5843 operands[2] = GEN_INT (-INTVAL (operands[2]));
5844 return "sub{w}\t{%2, %0|%0, %2}";
5846 return "add{w}\t{%2, %0|%0, %2}";
5850 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5851 (const_string "incdec")
5852 (const_string "alu")))
5853 (set_attr "mode" "HI")])
5855 (define_insn "*addhi_3"
5856 [(set (reg FLAGS_REG)
5857 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5858 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5859 (clobber (match_scratch:HI 0 "=r"))]
5860 "ix86_match_ccmode (insn, CCZmode)
5861 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5863 switch (get_attr_type (insn))
5866 if (operands[2] == const1_rtx)
5867 return "inc{w}\t%0";
5868 else if (operands[2] == constm1_rtx)
5869 return "dec{w}\t%0";
5873 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5875 if (GET_CODE (operands[2]) == CONST_INT
5876 && (INTVAL (operands[2]) == 128
5877 || (INTVAL (operands[2]) < 0
5878 && INTVAL (operands[2]) != -128)))
5880 operands[2] = GEN_INT (-INTVAL (operands[2]));
5881 return "sub{w}\t{%2, %0|%0, %2}";
5883 return "add{w}\t{%2, %0|%0, %2}";
5887 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5888 (const_string "incdec")
5889 (const_string "alu")))
5890 (set_attr "mode" "HI")])
5892 ; See comments above addsi_4 for details.
5893 (define_insn "*addhi_4"
5894 [(set (reg FLAGS_REG)
5895 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5896 (match_operand:HI 2 "const_int_operand" "n")))
5897 (clobber (match_scratch:HI 0 "=rm"))]
5898 "ix86_match_ccmode (insn, CCGCmode)
5899 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5901 switch (get_attr_type (insn))
5904 if (operands[2] == constm1_rtx)
5905 return "inc{w}\t%0";
5906 else if (operands[2] == const1_rtx)
5907 return "dec{w}\t%0";
5912 if (! rtx_equal_p (operands[0], operands[1]))
5914 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5915 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5916 if ((INTVAL (operands[2]) == -128
5917 || (INTVAL (operands[2]) > 0
5918 && INTVAL (operands[2]) != 128)))
5919 return "sub{w}\t{%2, %0|%0, %2}";
5920 operands[2] = GEN_INT (-INTVAL (operands[2]));
5921 return "add{w}\t{%2, %0|%0, %2}";
5925 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5926 (const_string "incdec")
5927 (const_string "alu")))
5928 (set_attr "mode" "SI")])
5931 (define_insn "*addhi_5"
5932 [(set (reg FLAGS_REG)
5934 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
5935 (match_operand:HI 2 "general_operand" "rmni"))
5937 (clobber (match_scratch:HI 0 "=r"))]
5938 "ix86_match_ccmode (insn, CCGOCmode)
5939 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5941 switch (get_attr_type (insn))
5944 if (operands[2] == const1_rtx)
5945 return "inc{w}\t%0";
5946 else if (operands[2] == constm1_rtx)
5947 return "dec{w}\t%0";
5951 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5952 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5953 if (GET_CODE (operands[2]) == CONST_INT
5954 && (INTVAL (operands[2]) == 128
5955 || (INTVAL (operands[2]) < 0
5956 && INTVAL (operands[2]) != -128)))
5958 operands[2] = GEN_INT (-INTVAL (operands[2]));
5959 return "sub{w}\t{%2, %0|%0, %2}";
5961 return "add{w}\t{%2, %0|%0, %2}";
5965 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5966 (const_string "incdec")
5967 (const_string "alu")))
5968 (set_attr "mode" "HI")])
5970 (define_expand "addqi3"
5971 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
5972 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
5973 (match_operand:QI 2 "general_operand" "")))
5974 (clobber (reg:CC FLAGS_REG))])]
5975 "TARGET_QIMODE_MATH"
5976 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
5978 ;; %%% Potential partial reg stall on alternative 2. What to do?
5979 (define_insn "*addqi_1_lea"
5980 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
5981 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
5982 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
5983 (clobber (reg:CC FLAGS_REG))]
5984 "!TARGET_PARTIAL_REG_STALL
5985 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5987 int widen = (which_alternative == 2);
5988 switch (get_attr_type (insn))
5993 if (operands[2] == const1_rtx)
5994 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5995 else if (operands[2] == constm1_rtx)
5996 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6000 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6001 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6002 if (GET_CODE (operands[2]) == CONST_INT
6003 && (INTVAL (operands[2]) == 128
6004 || (INTVAL (operands[2]) < 0
6005 && INTVAL (operands[2]) != -128)))
6007 operands[2] = GEN_INT (-INTVAL (operands[2]));
6009 return "sub{l}\t{%2, %k0|%k0, %2}";
6011 return "sub{b}\t{%2, %0|%0, %2}";
6014 return "add{l}\t{%k2, %k0|%k0, %k2}";
6016 return "add{b}\t{%2, %0|%0, %2}";
6020 (if_then_else (eq_attr "alternative" "3")
6021 (const_string "lea")
6022 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6023 (const_string "incdec")
6024 (const_string "alu"))))
6025 (set_attr "mode" "QI,QI,SI,SI")])
6027 (define_insn "*addqi_1"
6028 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6029 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6030 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6031 (clobber (reg:CC FLAGS_REG))]
6032 "TARGET_PARTIAL_REG_STALL
6033 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6035 int widen = (which_alternative == 2);
6036 switch (get_attr_type (insn))
6039 if (operands[2] == const1_rtx)
6040 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6041 else if (operands[2] == constm1_rtx)
6042 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6046 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6047 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6048 if (GET_CODE (operands[2]) == CONST_INT
6049 && (INTVAL (operands[2]) == 128
6050 || (INTVAL (operands[2]) < 0
6051 && INTVAL (operands[2]) != -128)))
6053 operands[2] = GEN_INT (-INTVAL (operands[2]));
6055 return "sub{l}\t{%2, %k0|%k0, %2}";
6057 return "sub{b}\t{%2, %0|%0, %2}";
6060 return "add{l}\t{%k2, %k0|%k0, %k2}";
6062 return "add{b}\t{%2, %0|%0, %2}";
6066 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6067 (const_string "incdec")
6068 (const_string "alu")))
6069 (set_attr "mode" "QI,QI,SI")])
6071 (define_insn "*addqi_1_slp"
6072 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6073 (plus:QI (match_dup 0)
6074 (match_operand:QI 1 "general_operand" "qn,qnm")))
6075 (clobber (reg:CC FLAGS_REG))]
6076 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6077 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6079 switch (get_attr_type (insn))
6082 if (operands[1] == const1_rtx)
6083 return "inc{b}\t%0";
6084 else if (operands[1] == constm1_rtx)
6085 return "dec{b}\t%0";
6089 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6090 if (GET_CODE (operands[1]) == CONST_INT
6091 && INTVAL (operands[1]) < 0)
6093 operands[1] = GEN_INT (-INTVAL (operands[1]));
6094 return "sub{b}\t{%1, %0|%0, %1}";
6096 return "add{b}\t{%1, %0|%0, %1}";
6100 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6101 (const_string "incdec")
6102 (const_string "alu1")))
6103 (set (attr "memory")
6104 (if_then_else (match_operand 1 "memory_operand" "")
6105 (const_string "load")
6106 (const_string "none")))
6107 (set_attr "mode" "QI")])
6109 (define_insn "*addqi_2"
6110 [(set (reg FLAGS_REG)
6112 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6113 (match_operand:QI 2 "general_operand" "qmni,qni"))
6115 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6116 (plus:QI (match_dup 1) (match_dup 2)))]
6117 "ix86_match_ccmode (insn, CCGOCmode)
6118 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6120 switch (get_attr_type (insn))
6123 if (operands[2] == const1_rtx)
6124 return "inc{b}\t%0";
6125 else if (operands[2] == constm1_rtx
6126 || (GET_CODE (operands[2]) == CONST_INT
6127 && INTVAL (operands[2]) == 255))
6128 return "dec{b}\t%0";
6132 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6133 if (GET_CODE (operands[2]) == CONST_INT
6134 && INTVAL (operands[2]) < 0)
6136 operands[2] = GEN_INT (-INTVAL (operands[2]));
6137 return "sub{b}\t{%2, %0|%0, %2}";
6139 return "add{b}\t{%2, %0|%0, %2}";
6143 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6144 (const_string "incdec")
6145 (const_string "alu")))
6146 (set_attr "mode" "QI")])
6148 (define_insn "*addqi_3"
6149 [(set (reg FLAGS_REG)
6150 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6151 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6152 (clobber (match_scratch:QI 0 "=q"))]
6153 "ix86_match_ccmode (insn, CCZmode)
6154 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6156 switch (get_attr_type (insn))
6159 if (operands[2] == const1_rtx)
6160 return "inc{b}\t%0";
6161 else if (operands[2] == constm1_rtx
6162 || (GET_CODE (operands[2]) == CONST_INT
6163 && INTVAL (operands[2]) == 255))
6164 return "dec{b}\t%0";
6168 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6169 if (GET_CODE (operands[2]) == CONST_INT
6170 && INTVAL (operands[2]) < 0)
6172 operands[2] = GEN_INT (-INTVAL (operands[2]));
6173 return "sub{b}\t{%2, %0|%0, %2}";
6175 return "add{b}\t{%2, %0|%0, %2}";
6179 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6180 (const_string "incdec")
6181 (const_string "alu")))
6182 (set_attr "mode" "QI")])
6184 ; See comments above addsi_4 for details.
6185 (define_insn "*addqi_4"
6186 [(set (reg FLAGS_REG)
6187 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6188 (match_operand:QI 2 "const_int_operand" "n")))
6189 (clobber (match_scratch:QI 0 "=qm"))]
6190 "ix86_match_ccmode (insn, CCGCmode)
6191 && (INTVAL (operands[2]) & 0xff) != 0x80"
6193 switch (get_attr_type (insn))
6196 if (operands[2] == constm1_rtx
6197 || (GET_CODE (operands[2]) == CONST_INT
6198 && INTVAL (operands[2]) == 255))
6199 return "inc{b}\t%0";
6200 else if (operands[2] == const1_rtx)
6201 return "dec{b}\t%0";
6206 if (! rtx_equal_p (operands[0], operands[1]))
6208 if (INTVAL (operands[2]) < 0)
6210 operands[2] = GEN_INT (-INTVAL (operands[2]));
6211 return "add{b}\t{%2, %0|%0, %2}";
6213 return "sub{b}\t{%2, %0|%0, %2}";
6217 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6218 (const_string "incdec")
6219 (const_string "alu")))
6220 (set_attr "mode" "QI")])
6223 (define_insn "*addqi_5"
6224 [(set (reg FLAGS_REG)
6226 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6227 (match_operand:QI 2 "general_operand" "qmni"))
6229 (clobber (match_scratch:QI 0 "=q"))]
6230 "ix86_match_ccmode (insn, CCGOCmode)
6231 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6233 switch (get_attr_type (insn))
6236 if (operands[2] == const1_rtx)
6237 return "inc{b}\t%0";
6238 else if (operands[2] == constm1_rtx
6239 || (GET_CODE (operands[2]) == CONST_INT
6240 && INTVAL (operands[2]) == 255))
6241 return "dec{b}\t%0";
6245 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6246 if (GET_CODE (operands[2]) == CONST_INT
6247 && INTVAL (operands[2]) < 0)
6249 operands[2] = GEN_INT (-INTVAL (operands[2]));
6250 return "sub{b}\t{%2, %0|%0, %2}";
6252 return "add{b}\t{%2, %0|%0, %2}";
6256 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6257 (const_string "incdec")
6258 (const_string "alu")))
6259 (set_attr "mode" "QI")])
6262 (define_insn "addqi_ext_1"
6263 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6268 (match_operand 1 "ext_register_operand" "0")
6271 (match_operand:QI 2 "general_operand" "Qmn")))
6272 (clobber (reg:CC FLAGS_REG))]
6275 switch (get_attr_type (insn))
6278 if (operands[2] == const1_rtx)
6279 return "inc{b}\t%h0";
6280 else if (operands[2] == constm1_rtx
6281 || (GET_CODE (operands[2]) == CONST_INT
6282 && INTVAL (operands[2]) == 255))
6283 return "dec{b}\t%h0";
6287 return "add{b}\t{%2, %h0|%h0, %2}";
6291 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6292 (const_string "incdec")
6293 (const_string "alu")))
6294 (set_attr "mode" "QI")])
6296 (define_insn "*addqi_ext_1_rex64"
6297 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6302 (match_operand 1 "ext_register_operand" "0")
6305 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6306 (clobber (reg:CC FLAGS_REG))]
6309 switch (get_attr_type (insn))
6312 if (operands[2] == const1_rtx)
6313 return "inc{b}\t%h0";
6314 else if (operands[2] == constm1_rtx
6315 || (GET_CODE (operands[2]) == CONST_INT
6316 && INTVAL (operands[2]) == 255))
6317 return "dec{b}\t%h0";
6321 return "add{b}\t{%2, %h0|%h0, %2}";
6325 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6326 (const_string "incdec")
6327 (const_string "alu")))
6328 (set_attr "mode" "QI")])
6330 (define_insn "*addqi_ext_2"
6331 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6336 (match_operand 1 "ext_register_operand" "%0")
6340 (match_operand 2 "ext_register_operand" "Q")
6343 (clobber (reg:CC FLAGS_REG))]
6345 "add{b}\t{%h2, %h0|%h0, %h2}"
6346 [(set_attr "type" "alu")
6347 (set_attr "mode" "QI")])
6349 ;; The patterns that match these are at the end of this file.
6351 (define_expand "addxf3"
6352 [(set (match_operand:XF 0 "register_operand" "")
6353 (plus:XF (match_operand:XF 1 "register_operand" "")
6354 (match_operand:XF 2 "register_operand" "")))]
6358 (define_expand "adddf3"
6359 [(set (match_operand:DF 0 "register_operand" "")
6360 (plus:DF (match_operand:DF 1 "register_operand" "")
6361 (match_operand:DF 2 "nonimmediate_operand" "")))]
6362 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6365 (define_expand "addsf3"
6366 [(set (match_operand:SF 0 "register_operand" "")
6367 (plus:SF (match_operand:SF 1 "register_operand" "")
6368 (match_operand:SF 2 "nonimmediate_operand" "")))]
6369 "TARGET_80387 || TARGET_SSE_MATH"
6372 ;; Subtract instructions
6374 ;; %%% splits for subsidi3
6376 (define_expand "subdi3"
6377 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6378 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6379 (match_operand:DI 2 "x86_64_general_operand" "")))
6380 (clobber (reg:CC FLAGS_REG))])]
6382 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6384 (define_insn "*subdi3_1"
6385 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6386 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6387 (match_operand:DI 2 "general_operand" "roiF,riF")))
6388 (clobber (reg:CC FLAGS_REG))]
6389 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6393 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6394 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6395 (match_operand:DI 2 "general_operand" "")))
6396 (clobber (reg:CC FLAGS_REG))]
6397 "!TARGET_64BIT && reload_completed"
6398 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6399 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6400 (parallel [(set (match_dup 3)
6401 (minus:SI (match_dup 4)
6402 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6404 (clobber (reg:CC FLAGS_REG))])]
6405 "split_di (operands+0, 1, operands+0, operands+3);
6406 split_di (operands+1, 1, operands+1, operands+4);
6407 split_di (operands+2, 1, operands+2, operands+5);")
6409 (define_insn "subdi3_carry_rex64"
6410 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6411 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6412 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6413 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6414 (clobber (reg:CC FLAGS_REG))]
6415 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6416 "sbb{q}\t{%2, %0|%0, %2}"
6417 [(set_attr "type" "alu")
6418 (set_attr "pent_pair" "pu")
6419 (set_attr "mode" "DI")])
6421 (define_insn "*subdi_1_rex64"
6422 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6423 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6424 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6425 (clobber (reg:CC FLAGS_REG))]
6426 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6427 "sub{q}\t{%2, %0|%0, %2}"
6428 [(set_attr "type" "alu")
6429 (set_attr "mode" "DI")])
6431 (define_insn "*subdi_2_rex64"
6432 [(set (reg FLAGS_REG)
6434 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6435 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6437 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6438 (minus:DI (match_dup 1) (match_dup 2)))]
6439 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6440 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6441 "sub{q}\t{%2, %0|%0, %2}"
6442 [(set_attr "type" "alu")
6443 (set_attr "mode" "DI")])
6445 (define_insn "*subdi_3_rex63"
6446 [(set (reg FLAGS_REG)
6447 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6448 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6449 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6450 (minus:DI (match_dup 1) (match_dup 2)))]
6451 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6452 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6453 "sub{q}\t{%2, %0|%0, %2}"
6454 [(set_attr "type" "alu")
6455 (set_attr "mode" "DI")])
6457 (define_insn "subqi3_carry"
6458 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6459 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6460 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6461 (match_operand:QI 2 "general_operand" "qi,qm"))))
6462 (clobber (reg:CC FLAGS_REG))]
6463 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6464 "sbb{b}\t{%2, %0|%0, %2}"
6465 [(set_attr "type" "alu")
6466 (set_attr "pent_pair" "pu")
6467 (set_attr "mode" "QI")])
6469 (define_insn "subhi3_carry"
6470 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6471 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6472 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6473 (match_operand:HI 2 "general_operand" "ri,rm"))))
6474 (clobber (reg:CC FLAGS_REG))]
6475 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6476 "sbb{w}\t{%2, %0|%0, %2}"
6477 [(set_attr "type" "alu")
6478 (set_attr "pent_pair" "pu")
6479 (set_attr "mode" "HI")])
6481 (define_insn "subsi3_carry"
6482 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6483 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6484 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6485 (match_operand:SI 2 "general_operand" "ri,rm"))))
6486 (clobber (reg:CC FLAGS_REG))]
6487 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6488 "sbb{l}\t{%2, %0|%0, %2}"
6489 [(set_attr "type" "alu")
6490 (set_attr "pent_pair" "pu")
6491 (set_attr "mode" "SI")])
6493 (define_insn "subsi3_carry_zext"
6494 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6496 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6497 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6498 (match_operand:SI 2 "general_operand" "ri,rm")))))
6499 (clobber (reg:CC FLAGS_REG))]
6500 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6501 "sbb{l}\t{%2, %k0|%k0, %2}"
6502 [(set_attr "type" "alu")
6503 (set_attr "pent_pair" "pu")
6504 (set_attr "mode" "SI")])
6506 (define_expand "subsi3"
6507 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6508 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6509 (match_operand:SI 2 "general_operand" "")))
6510 (clobber (reg:CC FLAGS_REG))])]
6512 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6514 (define_insn "*subsi_1"
6515 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6516 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6517 (match_operand:SI 2 "general_operand" "ri,rm")))
6518 (clobber (reg:CC FLAGS_REG))]
6519 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6520 "sub{l}\t{%2, %0|%0, %2}"
6521 [(set_attr "type" "alu")
6522 (set_attr "mode" "SI")])
6524 (define_insn "*subsi_1_zext"
6525 [(set (match_operand:DI 0 "register_operand" "=r")
6527 (minus:SI (match_operand:SI 1 "register_operand" "0")
6528 (match_operand:SI 2 "general_operand" "rim"))))
6529 (clobber (reg:CC FLAGS_REG))]
6530 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6531 "sub{l}\t{%2, %k0|%k0, %2}"
6532 [(set_attr "type" "alu")
6533 (set_attr "mode" "SI")])
6535 (define_insn "*subsi_2"
6536 [(set (reg FLAGS_REG)
6538 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6539 (match_operand:SI 2 "general_operand" "ri,rm"))
6541 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6542 (minus:SI (match_dup 1) (match_dup 2)))]
6543 "ix86_match_ccmode (insn, CCGOCmode)
6544 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6545 "sub{l}\t{%2, %0|%0, %2}"
6546 [(set_attr "type" "alu")
6547 (set_attr "mode" "SI")])
6549 (define_insn "*subsi_2_zext"
6550 [(set (reg FLAGS_REG)
6552 (minus:SI (match_operand:SI 1 "register_operand" "0")
6553 (match_operand:SI 2 "general_operand" "rim"))
6555 (set (match_operand:DI 0 "register_operand" "=r")
6557 (minus:SI (match_dup 1)
6559 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6560 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6561 "sub{l}\t{%2, %k0|%k0, %2}"
6562 [(set_attr "type" "alu")
6563 (set_attr "mode" "SI")])
6565 (define_insn "*subsi_3"
6566 [(set (reg FLAGS_REG)
6567 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6568 (match_operand:SI 2 "general_operand" "ri,rm")))
6569 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6570 (minus:SI (match_dup 1) (match_dup 2)))]
6571 "ix86_match_ccmode (insn, CCmode)
6572 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6573 "sub{l}\t{%2, %0|%0, %2}"
6574 [(set_attr "type" "alu")
6575 (set_attr "mode" "SI")])
6577 (define_insn "*subsi_3_zext"
6578 [(set (reg FLAGS_REG)
6579 (compare (match_operand:SI 1 "register_operand" "0")
6580 (match_operand:SI 2 "general_operand" "rim")))
6581 (set (match_operand:DI 0 "register_operand" "=r")
6583 (minus:SI (match_dup 1)
6585 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6586 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587 "sub{q}\t{%2, %0|%0, %2}"
6588 [(set_attr "type" "alu")
6589 (set_attr "mode" "DI")])
6591 (define_expand "subhi3"
6592 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6593 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6594 (match_operand:HI 2 "general_operand" "")))
6595 (clobber (reg:CC FLAGS_REG))])]
6596 "TARGET_HIMODE_MATH"
6597 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6599 (define_insn "*subhi_1"
6600 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6601 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6602 (match_operand:HI 2 "general_operand" "ri,rm")))
6603 (clobber (reg:CC FLAGS_REG))]
6604 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6605 "sub{w}\t{%2, %0|%0, %2}"
6606 [(set_attr "type" "alu")
6607 (set_attr "mode" "HI")])
6609 (define_insn "*subhi_2"
6610 [(set (reg FLAGS_REG)
6612 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6613 (match_operand:HI 2 "general_operand" "ri,rm"))
6615 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6616 (minus:HI (match_dup 1) (match_dup 2)))]
6617 "ix86_match_ccmode (insn, CCGOCmode)
6618 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6619 "sub{w}\t{%2, %0|%0, %2}"
6620 [(set_attr "type" "alu")
6621 (set_attr "mode" "HI")])
6623 (define_insn "*subhi_3"
6624 [(set (reg FLAGS_REG)
6625 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6626 (match_operand:HI 2 "general_operand" "ri,rm")))
6627 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6628 (minus:HI (match_dup 1) (match_dup 2)))]
6629 "ix86_match_ccmode (insn, CCmode)
6630 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6631 "sub{w}\t{%2, %0|%0, %2}"
6632 [(set_attr "type" "alu")
6633 (set_attr "mode" "HI")])
6635 (define_expand "subqi3"
6636 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6637 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6638 (match_operand:QI 2 "general_operand" "")))
6639 (clobber (reg:CC FLAGS_REG))])]
6640 "TARGET_QIMODE_MATH"
6641 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6643 (define_insn "*subqi_1"
6644 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6645 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6646 (match_operand:QI 2 "general_operand" "qn,qmn")))
6647 (clobber (reg:CC FLAGS_REG))]
6648 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6649 "sub{b}\t{%2, %0|%0, %2}"
6650 [(set_attr "type" "alu")
6651 (set_attr "mode" "QI")])
6653 (define_insn "*subqi_1_slp"
6654 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6655 (minus:QI (match_dup 0)
6656 (match_operand:QI 1 "general_operand" "qn,qmn")))
6657 (clobber (reg:CC FLAGS_REG))]
6658 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6659 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6660 "sub{b}\t{%1, %0|%0, %1}"
6661 [(set_attr "type" "alu1")
6662 (set_attr "mode" "QI")])
6664 (define_insn "*subqi_2"
6665 [(set (reg FLAGS_REG)
6667 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6668 (match_operand:QI 2 "general_operand" "qi,qm"))
6670 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6671 (minus:HI (match_dup 1) (match_dup 2)))]
6672 "ix86_match_ccmode (insn, CCGOCmode)
6673 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6674 "sub{b}\t{%2, %0|%0, %2}"
6675 [(set_attr "type" "alu")
6676 (set_attr "mode" "QI")])
6678 (define_insn "*subqi_3"
6679 [(set (reg FLAGS_REG)
6680 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6681 (match_operand:QI 2 "general_operand" "qi,qm")))
6682 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6683 (minus:HI (match_dup 1) (match_dup 2)))]
6684 "ix86_match_ccmode (insn, CCmode)
6685 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6686 "sub{b}\t{%2, %0|%0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "mode" "QI")])
6690 ;; The patterns that match these are at the end of this file.
6692 (define_expand "subxf3"
6693 [(set (match_operand:XF 0 "register_operand" "")
6694 (minus:XF (match_operand:XF 1 "register_operand" "")
6695 (match_operand:XF 2 "register_operand" "")))]
6699 (define_expand "subdf3"
6700 [(set (match_operand:DF 0 "register_operand" "")
6701 (minus:DF (match_operand:DF 1 "register_operand" "")
6702 (match_operand:DF 2 "nonimmediate_operand" "")))]
6703 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6706 (define_expand "subsf3"
6707 [(set (match_operand:SF 0 "register_operand" "")
6708 (minus:SF (match_operand:SF 1 "register_operand" "")
6709 (match_operand:SF 2 "nonimmediate_operand" "")))]
6710 "TARGET_80387 || TARGET_SSE_MATH"
6713 ;; Multiply instructions
6715 (define_expand "muldi3"
6716 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6717 (mult:DI (match_operand:DI 1 "register_operand" "")
6718 (match_operand:DI 2 "x86_64_general_operand" "")))
6719 (clobber (reg:CC FLAGS_REG))])]
6723 (define_insn "*muldi3_1_rex64"
6724 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6725 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6726 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6727 (clobber (reg:CC FLAGS_REG))]
6729 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6731 imul{q}\t{%2, %1, %0|%0, %1, %2}
6732 imul{q}\t{%2, %1, %0|%0, %1, %2}
6733 imul{q}\t{%2, %0|%0, %2}"
6734 [(set_attr "type" "imul")
6735 (set_attr "prefix_0f" "0,0,1")
6736 (set (attr "athlon_decode")
6737 (cond [(eq_attr "cpu" "athlon")
6738 (const_string "vector")
6739 (eq_attr "alternative" "1")
6740 (const_string "vector")
6741 (and (eq_attr "alternative" "2")
6742 (match_operand 1 "memory_operand" ""))
6743 (const_string "vector")]
6744 (const_string "direct")))
6745 (set_attr "mode" "DI")])
6747 (define_expand "mulsi3"
6748 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6749 (mult:SI (match_operand:SI 1 "register_operand" "")
6750 (match_operand:SI 2 "general_operand" "")))
6751 (clobber (reg:CC FLAGS_REG))])]
6755 (define_insn "*mulsi3_1"
6756 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6757 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6758 (match_operand:SI 2 "general_operand" "K,i,mr")))
6759 (clobber (reg:CC FLAGS_REG))]
6760 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6762 imul{l}\t{%2, %1, %0|%0, %1, %2}
6763 imul{l}\t{%2, %1, %0|%0, %1, %2}
6764 imul{l}\t{%2, %0|%0, %2}"
6765 [(set_attr "type" "imul")
6766 (set_attr "prefix_0f" "0,0,1")
6767 (set (attr "athlon_decode")
6768 (cond [(eq_attr "cpu" "athlon")
6769 (const_string "vector")
6770 (eq_attr "alternative" "1")
6771 (const_string "vector")
6772 (and (eq_attr "alternative" "2")
6773 (match_operand 1 "memory_operand" ""))
6774 (const_string "vector")]
6775 (const_string "direct")))
6776 (set_attr "mode" "SI")])
6778 (define_insn "*mulsi3_1_zext"
6779 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6781 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6782 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6783 (clobber (reg:CC FLAGS_REG))]
6785 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6787 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6788 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6789 imul{l}\t{%2, %k0|%k0, %2}"
6790 [(set_attr "type" "imul")
6791 (set_attr "prefix_0f" "0,0,1")
6792 (set (attr "athlon_decode")
6793 (cond [(eq_attr "cpu" "athlon")
6794 (const_string "vector")
6795 (eq_attr "alternative" "1")
6796 (const_string "vector")
6797 (and (eq_attr "alternative" "2")
6798 (match_operand 1 "memory_operand" ""))
6799 (const_string "vector")]
6800 (const_string "direct")))
6801 (set_attr "mode" "SI")])
6803 (define_expand "mulhi3"
6804 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6805 (mult:HI (match_operand:HI 1 "register_operand" "")
6806 (match_operand:HI 2 "general_operand" "")))
6807 (clobber (reg:CC FLAGS_REG))])]
6808 "TARGET_HIMODE_MATH"
6811 (define_insn "*mulhi3_1"
6812 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6813 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6814 (match_operand:HI 2 "general_operand" "K,i,mr")))
6815 (clobber (reg:CC FLAGS_REG))]
6816 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6818 imul{w}\t{%2, %1, %0|%0, %1, %2}
6819 imul{w}\t{%2, %1, %0|%0, %1, %2}
6820 imul{w}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "imul")
6822 (set_attr "prefix_0f" "0,0,1")
6823 (set (attr "athlon_decode")
6824 (cond [(eq_attr "cpu" "athlon")
6825 (const_string "vector")
6826 (eq_attr "alternative" "1,2")
6827 (const_string "vector")]
6828 (const_string "direct")))
6829 (set_attr "mode" "HI")])
6831 (define_expand "mulqi3"
6832 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6833 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6834 (match_operand:QI 2 "register_operand" "")))
6835 (clobber (reg:CC FLAGS_REG))])]
6836 "TARGET_QIMODE_MATH"
6839 (define_insn "*mulqi3_1"
6840 [(set (match_operand:QI 0 "register_operand" "=a")
6841 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6842 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6843 (clobber (reg:CC FLAGS_REG))]
6845 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6847 [(set_attr "type" "imul")
6848 (set_attr "length_immediate" "0")
6849 (set (attr "athlon_decode")
6850 (if_then_else (eq_attr "cpu" "athlon")
6851 (const_string "vector")
6852 (const_string "direct")))
6853 (set_attr "mode" "QI")])
6855 (define_expand "umulqihi3"
6856 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6857 (mult:HI (zero_extend:HI
6858 (match_operand:QI 1 "nonimmediate_operand" ""))
6860 (match_operand:QI 2 "register_operand" ""))))
6861 (clobber (reg:CC FLAGS_REG))])]
6862 "TARGET_QIMODE_MATH"
6865 (define_insn "*umulqihi3_1"
6866 [(set (match_operand:HI 0 "register_operand" "=a")
6867 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6868 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6869 (clobber (reg:CC FLAGS_REG))]
6871 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6873 [(set_attr "type" "imul")
6874 (set_attr "length_immediate" "0")
6875 (set (attr "athlon_decode")
6876 (if_then_else (eq_attr "cpu" "athlon")
6877 (const_string "vector")
6878 (const_string "direct")))
6879 (set_attr "mode" "QI")])
6881 (define_expand "mulqihi3"
6882 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6883 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
6884 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
6885 (clobber (reg:CC FLAGS_REG))])]
6886 "TARGET_QIMODE_MATH"
6889 (define_insn "*mulqihi3_insn"
6890 [(set (match_operand:HI 0 "register_operand" "=a")
6891 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
6892 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6893 (clobber (reg:CC FLAGS_REG))]
6895 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6897 [(set_attr "type" "imul")
6898 (set_attr "length_immediate" "0")
6899 (set (attr "athlon_decode")
6900 (if_then_else (eq_attr "cpu" "athlon")
6901 (const_string "vector")
6902 (const_string "direct")))
6903 (set_attr "mode" "QI")])
6905 (define_expand "umulditi3"
6906 [(parallel [(set (match_operand:TI 0 "register_operand" "")
6907 (mult:TI (zero_extend:TI
6908 (match_operand:DI 1 "nonimmediate_operand" ""))
6910 (match_operand:DI 2 "register_operand" ""))))
6911 (clobber (reg:CC FLAGS_REG))])]
6915 (define_insn "*umulditi3_insn"
6916 [(set (match_operand:TI 0 "register_operand" "=A")
6917 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6918 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6919 (clobber (reg:CC FLAGS_REG))]
6921 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6923 [(set_attr "type" "imul")
6924 (set_attr "length_immediate" "0")
6925 (set (attr "athlon_decode")
6926 (if_then_else (eq_attr "cpu" "athlon")
6927 (const_string "vector")
6928 (const_string "double")))
6929 (set_attr "mode" "DI")])
6931 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
6932 (define_expand "umulsidi3"
6933 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6934 (mult:DI (zero_extend:DI
6935 (match_operand:SI 1 "nonimmediate_operand" ""))
6937 (match_operand:SI 2 "register_operand" ""))))
6938 (clobber (reg:CC FLAGS_REG))])]
6942 (define_insn "*umulsidi3_insn"
6943 [(set (match_operand:DI 0 "register_operand" "=A")
6944 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6945 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6946 (clobber (reg:CC FLAGS_REG))]
6948 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6950 [(set_attr "type" "imul")
6951 (set_attr "length_immediate" "0")
6952 (set (attr "athlon_decode")
6953 (if_then_else (eq_attr "cpu" "athlon")
6954 (const_string "vector")
6955 (const_string "double")))
6956 (set_attr "mode" "SI")])
6958 (define_expand "mulditi3"
6959 [(parallel [(set (match_operand:TI 0 "register_operand" "")
6960 (mult:TI (sign_extend:TI
6961 (match_operand:DI 1 "nonimmediate_operand" ""))
6963 (match_operand:DI 2 "register_operand" ""))))
6964 (clobber (reg:CC FLAGS_REG))])]
6968 (define_insn "*mulditi3_insn"
6969 [(set (match_operand:TI 0 "register_operand" "=A")
6970 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
6971 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
6972 (clobber (reg:CC FLAGS_REG))]
6974 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6976 [(set_attr "type" "imul")
6977 (set_attr "length_immediate" "0")
6978 (set (attr "athlon_decode")
6979 (if_then_else (eq_attr "cpu" "athlon")
6980 (const_string "vector")
6981 (const_string "double")))
6982 (set_attr "mode" "DI")])
6984 (define_expand "mulsidi3"
6985 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6986 (mult:DI (sign_extend:DI
6987 (match_operand:SI 1 "nonimmediate_operand" ""))
6989 (match_operand:SI 2 "register_operand" ""))))
6990 (clobber (reg:CC FLAGS_REG))])]
6994 (define_insn "*mulsidi3_insn"
6995 [(set (match_operand:DI 0 "register_operand" "=A")
6996 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
6997 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
6998 (clobber (reg:CC FLAGS_REG))]
7000 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7002 [(set_attr "type" "imul")
7003 (set_attr "length_immediate" "0")
7004 (set (attr "athlon_decode")
7005 (if_then_else (eq_attr "cpu" "athlon")
7006 (const_string "vector")
7007 (const_string "double")))
7008 (set_attr "mode" "SI")])
7010 (define_expand "umuldi3_highpart"
7011 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7014 (mult:TI (zero_extend:TI
7015 (match_operand:DI 1 "nonimmediate_operand" ""))
7017 (match_operand:DI 2 "register_operand" "")))
7019 (clobber (match_scratch:DI 3 ""))
7020 (clobber (reg:CC FLAGS_REG))])]
7024 (define_insn "*umuldi3_highpart_rex64"
7025 [(set (match_operand:DI 0 "register_operand" "=d")
7028 (mult:TI (zero_extend:TI
7029 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7031 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7033 (clobber (match_scratch:DI 3 "=1"))
7034 (clobber (reg:CC FLAGS_REG))]
7036 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7038 [(set_attr "type" "imul")
7039 (set_attr "length_immediate" "0")
7040 (set (attr "athlon_decode")
7041 (if_then_else (eq_attr "cpu" "athlon")
7042 (const_string "vector")
7043 (const_string "double")))
7044 (set_attr "mode" "DI")])
7046 (define_expand "umulsi3_highpart"
7047 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7050 (mult:DI (zero_extend:DI
7051 (match_operand:SI 1 "nonimmediate_operand" ""))
7053 (match_operand:SI 2 "register_operand" "")))
7055 (clobber (match_scratch:SI 3 ""))
7056 (clobber (reg:CC FLAGS_REG))])]
7060 (define_insn "*umulsi3_highpart_insn"
7061 [(set (match_operand:SI 0 "register_operand" "=d")
7064 (mult:DI (zero_extend:DI
7065 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7067 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7069 (clobber (match_scratch:SI 3 "=1"))
7070 (clobber (reg:CC FLAGS_REG))]
7071 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7073 [(set_attr "type" "imul")
7074 (set_attr "length_immediate" "0")
7075 (set (attr "athlon_decode")
7076 (if_then_else (eq_attr "cpu" "athlon")
7077 (const_string "vector")
7078 (const_string "double")))
7079 (set_attr "mode" "SI")])
7081 (define_insn "*umulsi3_highpart_zext"
7082 [(set (match_operand:DI 0 "register_operand" "=d")
7083 (zero_extend:DI (truncate:SI
7085 (mult:DI (zero_extend:DI
7086 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7088 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7090 (clobber (match_scratch:SI 3 "=1"))
7091 (clobber (reg:CC FLAGS_REG))]
7093 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7095 [(set_attr "type" "imul")
7096 (set_attr "length_immediate" "0")
7097 (set (attr "athlon_decode")
7098 (if_then_else (eq_attr "cpu" "athlon")
7099 (const_string "vector")
7100 (const_string "double")))
7101 (set_attr "mode" "SI")])
7103 (define_expand "smuldi3_highpart"
7104 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7107 (mult:TI (sign_extend:TI
7108 (match_operand:DI 1 "nonimmediate_operand" ""))
7110 (match_operand:DI 2 "register_operand" "")))
7112 (clobber (match_scratch:DI 3 ""))
7113 (clobber (reg:CC FLAGS_REG))])]
7117 (define_insn "*smuldi3_highpart_rex64"
7118 [(set (match_operand:DI 0 "register_operand" "=d")
7121 (mult:TI (sign_extend:TI
7122 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7124 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7126 (clobber (match_scratch:DI 3 "=1"))
7127 (clobber (reg:CC FLAGS_REG))]
7129 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7131 [(set_attr "type" "imul")
7132 (set (attr "athlon_decode")
7133 (if_then_else (eq_attr "cpu" "athlon")
7134 (const_string "vector")
7135 (const_string "double")))
7136 (set_attr "mode" "DI")])
7138 (define_expand "smulsi3_highpart"
7139 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7142 (mult:DI (sign_extend:DI
7143 (match_operand:SI 1 "nonimmediate_operand" ""))
7145 (match_operand:SI 2 "register_operand" "")))
7147 (clobber (match_scratch:SI 3 ""))
7148 (clobber (reg:CC FLAGS_REG))])]
7152 (define_insn "*smulsi3_highpart_insn"
7153 [(set (match_operand:SI 0 "register_operand" "=d")
7156 (mult:DI (sign_extend:DI
7157 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7159 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7161 (clobber (match_scratch:SI 3 "=1"))
7162 (clobber (reg:CC FLAGS_REG))]
7163 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7165 [(set_attr "type" "imul")
7166 (set (attr "athlon_decode")
7167 (if_then_else (eq_attr "cpu" "athlon")
7168 (const_string "vector")
7169 (const_string "double")))
7170 (set_attr "mode" "SI")])
7172 (define_insn "*smulsi3_highpart_zext"
7173 [(set (match_operand:DI 0 "register_operand" "=d")
7174 (zero_extend:DI (truncate:SI
7176 (mult:DI (sign_extend:DI
7177 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7179 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7181 (clobber (match_scratch:SI 3 "=1"))
7182 (clobber (reg:CC FLAGS_REG))]
7184 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7186 [(set_attr "type" "imul")
7187 (set (attr "athlon_decode")
7188 (if_then_else (eq_attr "cpu" "athlon")
7189 (const_string "vector")
7190 (const_string "double")))
7191 (set_attr "mode" "SI")])
7193 ;; The patterns that match these are at the end of this file.
7195 (define_expand "mulxf3"
7196 [(set (match_operand:XF 0 "register_operand" "")
7197 (mult:XF (match_operand:XF 1 "register_operand" "")
7198 (match_operand:XF 2 "register_operand" "")))]
7202 (define_expand "muldf3"
7203 [(set (match_operand:DF 0 "register_operand" "")
7204 (mult:DF (match_operand:DF 1 "register_operand" "")
7205 (match_operand:DF 2 "nonimmediate_operand" "")))]
7206 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7209 (define_expand "mulsf3"
7210 [(set (match_operand:SF 0 "register_operand" "")
7211 (mult:SF (match_operand:SF 1 "register_operand" "")
7212 (match_operand:SF 2 "nonimmediate_operand" "")))]
7213 "TARGET_80387 || TARGET_SSE_MATH"
7216 ;; Divide instructions
7218 (define_insn "divqi3"
7219 [(set (match_operand:QI 0 "register_operand" "=a")
7220 (div:QI (match_operand:HI 1 "register_operand" "0")
7221 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7222 (clobber (reg:CC FLAGS_REG))]
7223 "TARGET_QIMODE_MATH"
7225 [(set_attr "type" "idiv")
7226 (set_attr "mode" "QI")])
7228 (define_insn "udivqi3"
7229 [(set (match_operand:QI 0 "register_operand" "=a")
7230 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7231 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7232 (clobber (reg:CC FLAGS_REG))]
7233 "TARGET_QIMODE_MATH"
7235 [(set_attr "type" "idiv")
7236 (set_attr "mode" "QI")])
7238 ;; The patterns that match these are at the end of this file.
7240 (define_expand "divxf3"
7241 [(set (match_operand:XF 0 "register_operand" "")
7242 (div:XF (match_operand:XF 1 "register_operand" "")
7243 (match_operand:XF 2 "register_operand" "")))]
7247 (define_expand "divdf3"
7248 [(set (match_operand:DF 0 "register_operand" "")
7249 (div:DF (match_operand:DF 1 "register_operand" "")
7250 (match_operand:DF 2 "nonimmediate_operand" "")))]
7251 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7254 (define_expand "divsf3"
7255 [(set (match_operand:SF 0 "register_operand" "")
7256 (div:SF (match_operand:SF 1 "register_operand" "")
7257 (match_operand:SF 2 "nonimmediate_operand" "")))]
7258 "TARGET_80387 || TARGET_SSE_MATH"
7261 ;; Remainder instructions.
7263 (define_expand "divmoddi4"
7264 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7265 (div:DI (match_operand:DI 1 "register_operand" "")
7266 (match_operand:DI 2 "nonimmediate_operand" "")))
7267 (set (match_operand:DI 3 "register_operand" "")
7268 (mod:DI (match_dup 1) (match_dup 2)))
7269 (clobber (reg:CC FLAGS_REG))])]
7273 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7274 ;; Penalize eax case slightly because it results in worse scheduling
7276 (define_insn "*divmoddi4_nocltd_rex64"
7277 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7278 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7279 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7280 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7281 (mod:DI (match_dup 2) (match_dup 3)))
7282 (clobber (reg:CC FLAGS_REG))]
7283 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7285 [(set_attr "type" "multi")])
7287 (define_insn "*divmoddi4_cltd_rex64"
7288 [(set (match_operand:DI 0 "register_operand" "=a")
7289 (div:DI (match_operand:DI 2 "register_operand" "a")
7290 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7291 (set (match_operand:DI 1 "register_operand" "=&d")
7292 (mod:DI (match_dup 2) (match_dup 3)))
7293 (clobber (reg:CC FLAGS_REG))]
7294 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7296 [(set_attr "type" "multi")])
7298 (define_insn "*divmoddi_noext_rex64"
7299 [(set (match_operand:DI 0 "register_operand" "=a")
7300 (div:DI (match_operand:DI 1 "register_operand" "0")
7301 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7302 (set (match_operand:DI 3 "register_operand" "=d")
7303 (mod:DI (match_dup 1) (match_dup 2)))
7304 (use (match_operand:DI 4 "register_operand" "3"))
7305 (clobber (reg:CC FLAGS_REG))]
7308 [(set_attr "type" "idiv")
7309 (set_attr "mode" "DI")])
7312 [(set (match_operand:DI 0 "register_operand" "")
7313 (div:DI (match_operand:DI 1 "register_operand" "")
7314 (match_operand:DI 2 "nonimmediate_operand" "")))
7315 (set (match_operand:DI 3 "register_operand" "")
7316 (mod:DI (match_dup 1) (match_dup 2)))
7317 (clobber (reg:CC FLAGS_REG))]
7318 "TARGET_64BIT && reload_completed"
7319 [(parallel [(set (match_dup 3)
7320 (ashiftrt:DI (match_dup 4) (const_int 63)))
7321 (clobber (reg:CC FLAGS_REG))])
7322 (parallel [(set (match_dup 0)
7323 (div:DI (reg:DI 0) (match_dup 2)))
7325 (mod:DI (reg:DI 0) (match_dup 2)))
7327 (clobber (reg:CC FLAGS_REG))])]
7329 /* Avoid use of cltd in favor of a mov+shift. */
7330 if (!TARGET_USE_CLTD && !optimize_size)
7332 if (true_regnum (operands[1]))
7333 emit_move_insn (operands[0], operands[1]);
7335 emit_move_insn (operands[3], operands[1]);
7336 operands[4] = operands[3];
7340 if (true_regnum (operands[1]))
7342 operands[4] = operands[1];
7347 (define_expand "divmodsi4"
7348 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7349 (div:SI (match_operand:SI 1 "register_operand" "")
7350 (match_operand:SI 2 "nonimmediate_operand" "")))
7351 (set (match_operand:SI 3 "register_operand" "")
7352 (mod:SI (match_dup 1) (match_dup 2)))
7353 (clobber (reg:CC FLAGS_REG))])]
7357 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7358 ;; Penalize eax case slightly because it results in worse scheduling
7360 (define_insn "*divmodsi4_nocltd"
7361 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7362 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7363 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7364 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7365 (mod:SI (match_dup 2) (match_dup 3)))
7366 (clobber (reg:CC FLAGS_REG))]
7367 "!optimize_size && !TARGET_USE_CLTD"
7369 [(set_attr "type" "multi")])
7371 (define_insn "*divmodsi4_cltd"
7372 [(set (match_operand:SI 0 "register_operand" "=a")
7373 (div:SI (match_operand:SI 2 "register_operand" "a")
7374 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7375 (set (match_operand:SI 1 "register_operand" "=&d")
7376 (mod:SI (match_dup 2) (match_dup 3)))
7377 (clobber (reg:CC FLAGS_REG))]
7378 "optimize_size || TARGET_USE_CLTD"
7380 [(set_attr "type" "multi")])
7382 (define_insn "*divmodsi_noext"
7383 [(set (match_operand:SI 0 "register_operand" "=a")
7384 (div:SI (match_operand:SI 1 "register_operand" "0")
7385 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7386 (set (match_operand:SI 3 "register_operand" "=d")
7387 (mod:SI (match_dup 1) (match_dup 2)))
7388 (use (match_operand:SI 4 "register_operand" "3"))
7389 (clobber (reg:CC FLAGS_REG))]
7392 [(set_attr "type" "idiv")
7393 (set_attr "mode" "SI")])
7396 [(set (match_operand:SI 0 "register_operand" "")
7397 (div:SI (match_operand:SI 1 "register_operand" "")
7398 (match_operand:SI 2 "nonimmediate_operand" "")))
7399 (set (match_operand:SI 3 "register_operand" "")
7400 (mod:SI (match_dup 1) (match_dup 2)))
7401 (clobber (reg:CC FLAGS_REG))]
7403 [(parallel [(set (match_dup 3)
7404 (ashiftrt:SI (match_dup 4) (const_int 31)))
7405 (clobber (reg:CC FLAGS_REG))])
7406 (parallel [(set (match_dup 0)
7407 (div:SI (reg:SI 0) (match_dup 2)))
7409 (mod:SI (reg:SI 0) (match_dup 2)))
7411 (clobber (reg:CC FLAGS_REG))])]
7413 /* Avoid use of cltd in favor of a mov+shift. */
7414 if (!TARGET_USE_CLTD && !optimize_size)
7416 if (true_regnum (operands[1]))
7417 emit_move_insn (operands[0], operands[1]);
7419 emit_move_insn (operands[3], operands[1]);
7420 operands[4] = operands[3];
7424 if (true_regnum (operands[1]))
7426 operands[4] = operands[1];
7430 (define_insn "divmodhi4"
7431 [(set (match_operand:HI 0 "register_operand" "=a")
7432 (div:HI (match_operand:HI 1 "register_operand" "0")
7433 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7434 (set (match_operand:HI 3 "register_operand" "=&d")
7435 (mod:HI (match_dup 1) (match_dup 2)))
7436 (clobber (reg:CC FLAGS_REG))]
7437 "TARGET_HIMODE_MATH"
7439 [(set_attr "type" "multi")
7440 (set_attr "length_immediate" "0")
7441 (set_attr "mode" "SI")])
7443 (define_insn "udivmoddi4"
7444 [(set (match_operand:DI 0 "register_operand" "=a")
7445 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7446 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7447 (set (match_operand:DI 3 "register_operand" "=&d")
7448 (umod:DI (match_dup 1) (match_dup 2)))
7449 (clobber (reg:CC FLAGS_REG))]
7451 "xor{q}\t%3, %3\;div{q}\t%2"
7452 [(set_attr "type" "multi")
7453 (set_attr "length_immediate" "0")
7454 (set_attr "mode" "DI")])
7456 (define_insn "*udivmoddi4_noext"
7457 [(set (match_operand:DI 0 "register_operand" "=a")
7458 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7459 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7460 (set (match_operand:DI 3 "register_operand" "=d")
7461 (umod:DI (match_dup 1) (match_dup 2)))
7463 (clobber (reg:CC FLAGS_REG))]
7466 [(set_attr "type" "idiv")
7467 (set_attr "mode" "DI")])
7470 [(set (match_operand:DI 0 "register_operand" "")
7471 (udiv:DI (match_operand:DI 1 "register_operand" "")
7472 (match_operand:DI 2 "nonimmediate_operand" "")))
7473 (set (match_operand:DI 3 "register_operand" "")
7474 (umod:DI (match_dup 1) (match_dup 2)))
7475 (clobber (reg:CC FLAGS_REG))]
7476 "TARGET_64BIT && reload_completed"
7477 [(set (match_dup 3) (const_int 0))
7478 (parallel [(set (match_dup 0)
7479 (udiv:DI (match_dup 1) (match_dup 2)))
7481 (umod:DI (match_dup 1) (match_dup 2)))
7483 (clobber (reg:CC FLAGS_REG))])]
7486 (define_insn "udivmodsi4"
7487 [(set (match_operand:SI 0 "register_operand" "=a")
7488 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7489 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7490 (set (match_operand:SI 3 "register_operand" "=&d")
7491 (umod:SI (match_dup 1) (match_dup 2)))
7492 (clobber (reg:CC FLAGS_REG))]
7494 "xor{l}\t%3, %3\;div{l}\t%2"
7495 [(set_attr "type" "multi")
7496 (set_attr "length_immediate" "0")
7497 (set_attr "mode" "SI")])
7499 (define_insn "*udivmodsi4_noext"
7500 [(set (match_operand:SI 0 "register_operand" "=a")
7501 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7502 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7503 (set (match_operand:SI 3 "register_operand" "=d")
7504 (umod:SI (match_dup 1) (match_dup 2)))
7506 (clobber (reg:CC FLAGS_REG))]
7509 [(set_attr "type" "idiv")
7510 (set_attr "mode" "SI")])
7513 [(set (match_operand:SI 0 "register_operand" "")
7514 (udiv:SI (match_operand:SI 1 "register_operand" "")
7515 (match_operand:SI 2 "nonimmediate_operand" "")))
7516 (set (match_operand:SI 3 "register_operand" "")
7517 (umod:SI (match_dup 1) (match_dup 2)))
7518 (clobber (reg:CC FLAGS_REG))]
7520 [(set (match_dup 3) (const_int 0))
7521 (parallel [(set (match_dup 0)
7522 (udiv:SI (match_dup 1) (match_dup 2)))
7524 (umod:SI (match_dup 1) (match_dup 2)))
7526 (clobber (reg:CC FLAGS_REG))])]
7529 (define_expand "udivmodhi4"
7530 [(set (match_dup 4) (const_int 0))
7531 (parallel [(set (match_operand:HI 0 "register_operand" "")
7532 (udiv:HI (match_operand:HI 1 "register_operand" "")
7533 (match_operand:HI 2 "nonimmediate_operand" "")))
7534 (set (match_operand:HI 3 "register_operand" "")
7535 (umod:HI (match_dup 1) (match_dup 2)))
7537 (clobber (reg:CC FLAGS_REG))])]
7538 "TARGET_HIMODE_MATH"
7539 "operands[4] = gen_reg_rtx (HImode);")
7541 (define_insn "*udivmodhi_noext"
7542 [(set (match_operand:HI 0 "register_operand" "=a")
7543 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7544 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7545 (set (match_operand:HI 3 "register_operand" "=d")
7546 (umod:HI (match_dup 1) (match_dup 2)))
7547 (use (match_operand:HI 4 "register_operand" "3"))
7548 (clobber (reg:CC FLAGS_REG))]
7551 [(set_attr "type" "idiv")
7552 (set_attr "mode" "HI")])
7554 ;; We cannot use div/idiv for double division, because it causes
7555 ;; "division by zero" on the overflow and that's not what we expect
7556 ;; from truncate. Because true (non truncating) double division is
7557 ;; never generated, we can't create this insn anyway.
7560 ; [(set (match_operand:SI 0 "register_operand" "=a")
7562 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7564 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7565 ; (set (match_operand:SI 3 "register_operand" "=d")
7567 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7568 ; (clobber (reg:CC FLAGS_REG))]
7570 ; "div{l}\t{%2, %0|%0, %2}"
7571 ; [(set_attr "type" "idiv")])
7573 ;;- Logical AND instructions
7575 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7576 ;; Note that this excludes ah.
7578 (define_insn "*testdi_1_rex64"
7579 [(set (reg FLAGS_REG)
7581 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7582 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7584 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7585 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7587 test{l}\t{%k1, %k0|%k0, %k1}
7588 test{l}\t{%k1, %k0|%k0, %k1}
7589 test{q}\t{%1, %0|%0, %1}
7590 test{q}\t{%1, %0|%0, %1}
7591 test{q}\t{%1, %0|%0, %1}"
7592 [(set_attr "type" "test")
7593 (set_attr "modrm" "0,1,0,1,1")
7594 (set_attr "mode" "SI,SI,DI,DI,DI")
7595 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7597 (define_insn "testsi_1"
7598 [(set (reg FLAGS_REG)
7600 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7601 (match_operand:SI 1 "general_operand" "in,in,rin"))
7603 "ix86_match_ccmode (insn, CCNOmode)
7604 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7605 "test{l}\t{%1, %0|%0, %1}"
7606 [(set_attr "type" "test")
7607 (set_attr "modrm" "0,1,1")
7608 (set_attr "mode" "SI")
7609 (set_attr "pent_pair" "uv,np,uv")])
7611 (define_expand "testsi_ccno_1"
7612 [(set (reg:CCNO FLAGS_REG)
7614 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7615 (match_operand:SI 1 "nonmemory_operand" ""))
7620 (define_insn "*testhi_1"
7621 [(set (reg FLAGS_REG)
7622 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7623 (match_operand:HI 1 "general_operand" "n,n,rn"))
7625 "ix86_match_ccmode (insn, CCNOmode)
7626 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7627 "test{w}\t{%1, %0|%0, %1}"
7628 [(set_attr "type" "test")
7629 (set_attr "modrm" "0,1,1")
7630 (set_attr "mode" "HI")
7631 (set_attr "pent_pair" "uv,np,uv")])
7633 (define_expand "testqi_ccz_1"
7634 [(set (reg:CCZ FLAGS_REG)
7635 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7636 (match_operand:QI 1 "nonmemory_operand" ""))
7641 (define_insn "*testqi_1_maybe_si"
7642 [(set (reg FLAGS_REG)
7645 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7646 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7648 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7649 && ix86_match_ccmode (insn,
7650 GET_CODE (operands[1]) == CONST_INT
7651 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7653 if (which_alternative == 3)
7655 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7656 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7657 return "test{l}\t{%1, %k0|%k0, %1}";
7659 return "test{b}\t{%1, %0|%0, %1}";
7661 [(set_attr "type" "test")
7662 (set_attr "modrm" "0,1,1,1")
7663 (set_attr "mode" "QI,QI,QI,SI")
7664 (set_attr "pent_pair" "uv,np,uv,np")])
7666 (define_insn "*testqi_1"
7667 [(set (reg FLAGS_REG)
7670 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7671 (match_operand:QI 1 "general_operand" "n,n,qn"))
7673 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7674 && ix86_match_ccmode (insn, CCNOmode)"
7675 "test{b}\t{%1, %0|%0, %1}"
7676 [(set_attr "type" "test")
7677 (set_attr "modrm" "0,1,1")
7678 (set_attr "mode" "QI")
7679 (set_attr "pent_pair" "uv,np,uv")])
7681 (define_expand "testqi_ext_ccno_0"
7682 [(set (reg:CCNO FLAGS_REG)
7686 (match_operand 0 "ext_register_operand" "")
7689 (match_operand 1 "const_int_operand" ""))
7694 (define_insn "*testqi_ext_0"
7695 [(set (reg FLAGS_REG)
7699 (match_operand 0 "ext_register_operand" "Q")
7702 (match_operand 1 "const_int_operand" "n"))
7704 "ix86_match_ccmode (insn, CCNOmode)"
7705 "test{b}\t{%1, %h0|%h0, %1}"
7706 [(set_attr "type" "test")
7707 (set_attr "mode" "QI")
7708 (set_attr "length_immediate" "1")
7709 (set_attr "pent_pair" "np")])
7711 (define_insn "*testqi_ext_1"
7712 [(set (reg FLAGS_REG)
7716 (match_operand 0 "ext_register_operand" "Q")
7720 (match_operand:QI 1 "general_operand" "Qm")))
7722 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7723 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7724 "test{b}\t{%1, %h0|%h0, %1}"
7725 [(set_attr "type" "test")
7726 (set_attr "mode" "QI")])
7728 (define_insn "*testqi_ext_1_rex64"
7729 [(set (reg FLAGS_REG)
7733 (match_operand 0 "ext_register_operand" "Q")
7737 (match_operand:QI 1 "register_operand" "Q")))
7739 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7740 "test{b}\t{%1, %h0|%h0, %1}"
7741 [(set_attr "type" "test")
7742 (set_attr "mode" "QI")])
7744 (define_insn "*testqi_ext_2"
7745 [(set (reg FLAGS_REG)
7749 (match_operand 0 "ext_register_operand" "Q")
7753 (match_operand 1 "ext_register_operand" "Q")
7757 "ix86_match_ccmode (insn, CCNOmode)"
7758 "test{b}\t{%h1, %h0|%h0, %h1}"
7759 [(set_attr "type" "test")
7760 (set_attr "mode" "QI")])
7762 ;; Combine likes to form bit extractions for some tests. Humor it.
7763 (define_insn "*testqi_ext_3"
7764 [(set (reg FLAGS_REG)
7765 (compare (zero_extract:SI
7766 (match_operand 0 "nonimmediate_operand" "rm")
7767 (match_operand:SI 1 "const_int_operand" "")
7768 (match_operand:SI 2 "const_int_operand" ""))
7770 "ix86_match_ccmode (insn, CCNOmode)
7771 && (GET_MODE (operands[0]) == SImode
7772 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7773 || GET_MODE (operands[0]) == HImode
7774 || GET_MODE (operands[0]) == QImode)"
7777 (define_insn "*testqi_ext_3_rex64"
7778 [(set (reg FLAGS_REG)
7779 (compare (zero_extract:DI
7780 (match_operand 0 "nonimmediate_operand" "rm")
7781 (match_operand:DI 1 "const_int_operand" "")
7782 (match_operand:DI 2 "const_int_operand" ""))
7785 && ix86_match_ccmode (insn, CCNOmode)
7786 /* The code below cannot deal with constants outside HOST_WIDE_INT. */
7787 && INTVAL (operands[1]) + INTVAL (operands[2]) < HOST_BITS_PER_WIDE_INT
7788 /* Ensure that resulting mask is zero or sign extended operand. */
7789 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7790 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7791 && INTVAL (operands[1]) > 32))
7792 && (GET_MODE (operands[0]) == SImode
7793 || GET_MODE (operands[0]) == DImode
7794 || GET_MODE (operands[0]) == HImode
7795 || GET_MODE (operands[0]) == QImode)"
7799 [(set (match_operand 0 "flags_reg_operand" "")
7800 (match_operator 1 "compare_operator"
7802 (match_operand 2 "nonimmediate_operand" "")
7803 (match_operand 3 "const_int_operand" "")
7804 (match_operand 4 "const_int_operand" ""))
7806 "ix86_match_ccmode (insn, CCNOmode)"
7807 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7809 rtx val = operands[2];
7810 HOST_WIDE_INT len = INTVAL (operands[3]);
7811 HOST_WIDE_INT pos = INTVAL (operands[4]);
7813 enum machine_mode mode, submode;
7815 mode = GET_MODE (val);
7816 if (GET_CODE (val) == MEM)
7818 /* ??? Combine likes to put non-volatile mem extractions in QImode
7819 no matter the size of the test. So find a mode that works. */
7820 if (! MEM_VOLATILE_P (val))
7822 mode = smallest_mode_for_size (pos + len, MODE_INT);
7823 val = adjust_address (val, mode, 0);
7826 else if (GET_CODE (val) == SUBREG
7827 && (submode = GET_MODE (SUBREG_REG (val)),
7828 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7829 && pos + len <= GET_MODE_BITSIZE (submode))
7831 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7833 val = SUBREG_REG (val);
7835 else if (mode == HImode && pos + len <= 8)
7837 /* Small HImode tests can be converted to QImode. */
7839 val = gen_lowpart (QImode, val);
7842 mask = ((HOST_WIDE_INT)1 << (pos + len)) - 1;
7843 mask &= ~(((HOST_WIDE_INT)1 << pos) - 1);
7845 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7848 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7849 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7850 ;; this is relatively important trick.
7851 ;; Do the conversion only post-reload to avoid limiting of the register class
7854 [(set (match_operand 0 "flags_reg_operand" "")
7855 (match_operator 1 "compare_operator"
7856 [(and (match_operand 2 "register_operand" "")
7857 (match_operand 3 "const_int_operand" ""))
7860 && QI_REG_P (operands[2])
7861 && GET_MODE (operands[2]) != QImode
7862 && ((ix86_match_ccmode (insn, CCZmode)
7863 && !(INTVAL (operands[3]) & ~(255 << 8)))
7864 || (ix86_match_ccmode (insn, CCNOmode)
7865 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7868 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7871 "operands[2] = gen_lowpart (SImode, operands[2]);
7872 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7875 [(set (match_operand 0 "flags_reg_operand" "")
7876 (match_operator 1 "compare_operator"
7877 [(and (match_operand 2 "nonimmediate_operand" "")
7878 (match_operand 3 "const_int_operand" ""))
7881 && GET_MODE (operands[2]) != QImode
7882 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7883 && ((ix86_match_ccmode (insn, CCZmode)
7884 && !(INTVAL (operands[3]) & ~255))
7885 || (ix86_match_ccmode (insn, CCNOmode)
7886 && !(INTVAL (operands[3]) & ~127)))"
7888 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7890 "operands[2] = gen_lowpart (QImode, operands[2]);
7891 operands[3] = gen_lowpart (QImode, operands[3]);")
7894 ;; %%% This used to optimize known byte-wide and operations to memory,
7895 ;; and sometimes to QImode registers. If this is considered useful,
7896 ;; it should be done with splitters.
7898 (define_expand "anddi3"
7899 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7900 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7901 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
7902 (clobber (reg:CC FLAGS_REG))]
7904 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
7906 (define_insn "*anddi_1_rex64"
7907 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7908 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7909 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7910 (clobber (reg:CC FLAGS_REG))]
7911 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7913 switch (get_attr_type (insn))
7917 enum machine_mode mode;
7919 if (GET_CODE (operands[2]) != CONST_INT)
7921 if (INTVAL (operands[2]) == 0xff)
7923 else if (INTVAL (operands[2]) == 0xffff)
7928 operands[1] = gen_lowpart (mode, operands[1]);
7930 return "movz{bq|x}\t{%1,%0|%0, %1}";
7932 return "movz{wq|x}\t{%1,%0|%0, %1}";
7936 if (! rtx_equal_p (operands[0], operands[1]))
7938 if (get_attr_mode (insn) == MODE_SI)
7939 return "and{l}\t{%k2, %k0|%k0, %k2}";
7941 return "and{q}\t{%2, %0|%0, %2}";
7944 [(set_attr "type" "alu,alu,alu,imovx")
7945 (set_attr "length_immediate" "*,*,*,0")
7946 (set_attr "mode" "SI,DI,DI,DI")])
7948 (define_insn "*anddi_2"
7949 [(set (reg FLAGS_REG)
7950 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7951 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7953 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7954 (and:DI (match_dup 1) (match_dup 2)))]
7955 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7956 && ix86_binary_operator_ok (AND, DImode, operands)"
7958 and{l}\t{%k2, %k0|%k0, %k2}
7959 and{q}\t{%2, %0|%0, %2}
7960 and{q}\t{%2, %0|%0, %2}"
7961 [(set_attr "type" "alu")
7962 (set_attr "mode" "SI,DI,DI")])
7964 (define_expand "andsi3"
7965 [(set (match_operand:SI 0 "nonimmediate_operand" "")
7966 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7967 (match_operand:SI 2 "general_operand" "")))
7968 (clobber (reg:CC FLAGS_REG))]
7970 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
7972 (define_insn "*andsi_1"
7973 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7974 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7975 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7976 (clobber (reg:CC FLAGS_REG))]
7977 "ix86_binary_operator_ok (AND, SImode, operands)"
7979 switch (get_attr_type (insn))
7983 enum machine_mode mode;
7985 if (GET_CODE (operands[2]) != CONST_INT)
7987 if (INTVAL (operands[2]) == 0xff)
7989 else if (INTVAL (operands[2]) == 0xffff)
7994 operands[1] = gen_lowpart (mode, operands[1]);
7996 return "movz{bl|x}\t{%1,%0|%0, %1}";
7998 return "movz{wl|x}\t{%1,%0|%0, %1}";
8002 if (! rtx_equal_p (operands[0], operands[1]))
8004 return "and{l}\t{%2, %0|%0, %2}";
8007 [(set_attr "type" "alu,alu,imovx")
8008 (set_attr "length_immediate" "*,*,0")
8009 (set_attr "mode" "SI")])
8012 [(set (match_operand 0 "register_operand" "")
8014 (const_int -65536)))
8015 (clobber (reg:CC FLAGS_REG))]
8016 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8017 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8018 "operands[1] = gen_lowpart (HImode, operands[0]);")
8021 [(set (match_operand 0 "ext_register_operand" "")
8024 (clobber (reg:CC FLAGS_REG))]
8025 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8026 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8027 "operands[1] = gen_lowpart (QImode, operands[0]);")
8030 [(set (match_operand 0 "ext_register_operand" "")
8032 (const_int -65281)))
8033 (clobber (reg:CC FLAGS_REG))]
8034 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8035 [(parallel [(set (zero_extract:SI (match_dup 0)
8039 (zero_extract:SI (match_dup 0)
8042 (zero_extract:SI (match_dup 0)
8045 (clobber (reg:CC FLAGS_REG))])]
8046 "operands[0] = gen_lowpart (SImode, operands[0]);")
8048 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8049 (define_insn "*andsi_1_zext"
8050 [(set (match_operand:DI 0 "register_operand" "=r")
8052 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8053 (match_operand:SI 2 "general_operand" "rim"))))
8054 (clobber (reg:CC FLAGS_REG))]
8055 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8056 "and{l}\t{%2, %k0|%k0, %2}"
8057 [(set_attr "type" "alu")
8058 (set_attr "mode" "SI")])
8060 (define_insn "*andsi_2"
8061 [(set (reg FLAGS_REG)
8062 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8063 (match_operand:SI 2 "general_operand" "rim,ri"))
8065 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8066 (and:SI (match_dup 1) (match_dup 2)))]
8067 "ix86_match_ccmode (insn, CCNOmode)
8068 && ix86_binary_operator_ok (AND, SImode, operands)"
8069 "and{l}\t{%2, %0|%0, %2}"
8070 [(set_attr "type" "alu")
8071 (set_attr "mode" "SI")])
8073 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8074 (define_insn "*andsi_2_zext"
8075 [(set (reg FLAGS_REG)
8076 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8077 (match_operand:SI 2 "general_operand" "rim"))
8079 (set (match_operand:DI 0 "register_operand" "=r")
8080 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8081 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8082 && ix86_binary_operator_ok (AND, SImode, operands)"
8083 "and{l}\t{%2, %k0|%k0, %2}"
8084 [(set_attr "type" "alu")
8085 (set_attr "mode" "SI")])
8087 (define_expand "andhi3"
8088 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8089 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8090 (match_operand:HI 2 "general_operand" "")))
8091 (clobber (reg:CC FLAGS_REG))]
8092 "TARGET_HIMODE_MATH"
8093 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8095 (define_insn "*andhi_1"
8096 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8097 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8098 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8099 (clobber (reg:CC FLAGS_REG))]
8100 "ix86_binary_operator_ok (AND, HImode, operands)"
8102 switch (get_attr_type (insn))
8105 if (GET_CODE (operands[2]) != CONST_INT)
8107 if (INTVAL (operands[2]) == 0xff)
8108 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8112 if (! rtx_equal_p (operands[0], operands[1]))
8115 return "and{w}\t{%2, %0|%0, %2}";
8118 [(set_attr "type" "alu,alu,imovx")
8119 (set_attr "length_immediate" "*,*,0")
8120 (set_attr "mode" "HI,HI,SI")])
8122 (define_insn "*andhi_2"
8123 [(set (reg FLAGS_REG)
8124 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8125 (match_operand:HI 2 "general_operand" "rim,ri"))
8127 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8128 (and:HI (match_dup 1) (match_dup 2)))]
8129 "ix86_match_ccmode (insn, CCNOmode)
8130 && ix86_binary_operator_ok (AND, HImode, operands)"
8131 "and{w}\t{%2, %0|%0, %2}"
8132 [(set_attr "type" "alu")
8133 (set_attr "mode" "HI")])
8135 (define_expand "andqi3"
8136 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8137 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8138 (match_operand:QI 2 "general_operand" "")))
8139 (clobber (reg:CC FLAGS_REG))]
8140 "TARGET_QIMODE_MATH"
8141 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8143 ;; %%% Potential partial reg stall on alternative 2. What to do?
8144 (define_insn "*andqi_1"
8145 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8146 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8147 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8148 (clobber (reg:CC FLAGS_REG))]
8149 "ix86_binary_operator_ok (AND, QImode, operands)"
8151 and{b}\t{%2, %0|%0, %2}
8152 and{b}\t{%2, %0|%0, %2}
8153 and{l}\t{%k2, %k0|%k0, %k2}"
8154 [(set_attr "type" "alu")
8155 (set_attr "mode" "QI,QI,SI")])
8157 (define_insn "*andqi_1_slp"
8158 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8159 (and:QI (match_dup 0)
8160 (match_operand:QI 1 "general_operand" "qi,qmi")))
8161 (clobber (reg:CC FLAGS_REG))]
8162 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8163 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8164 "and{b}\t{%1, %0|%0, %1}"
8165 [(set_attr "type" "alu1")
8166 (set_attr "mode" "QI")])
8168 (define_insn "*andqi_2_maybe_si"
8169 [(set (reg FLAGS_REG)
8171 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8172 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8174 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8175 (and:QI (match_dup 1) (match_dup 2)))]
8176 "ix86_binary_operator_ok (AND, QImode, operands)
8177 && ix86_match_ccmode (insn,
8178 GET_CODE (operands[2]) == CONST_INT
8179 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8181 if (which_alternative == 2)
8183 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8184 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8185 return "and{l}\t{%2, %k0|%k0, %2}";
8187 return "and{b}\t{%2, %0|%0, %2}";
8189 [(set_attr "type" "alu")
8190 (set_attr "mode" "QI,QI,SI")])
8192 (define_insn "*andqi_2"
8193 [(set (reg FLAGS_REG)
8195 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8196 (match_operand:QI 2 "general_operand" "qim,qi"))
8198 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8199 (and:QI (match_dup 1) (match_dup 2)))]
8200 "ix86_match_ccmode (insn, CCNOmode)
8201 && ix86_binary_operator_ok (AND, QImode, operands)"
8202 "and{b}\t{%2, %0|%0, %2}"
8203 [(set_attr "type" "alu")
8204 (set_attr "mode" "QI")])
8206 (define_insn "*andqi_2_slp"
8207 [(set (reg FLAGS_REG)
8209 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8210 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8212 (set (strict_low_part (match_dup 0))
8213 (and:QI (match_dup 0) (match_dup 1)))]
8214 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8215 && ix86_match_ccmode (insn, CCNOmode)
8216 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8217 "and{b}\t{%1, %0|%0, %1}"
8218 [(set_attr "type" "alu1")
8219 (set_attr "mode" "QI")])
8221 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8222 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8223 ;; for a QImode operand, which of course failed.
8225 (define_insn "andqi_ext_0"
8226 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8231 (match_operand 1 "ext_register_operand" "0")
8234 (match_operand 2 "const_int_operand" "n")))
8235 (clobber (reg:CC FLAGS_REG))]
8237 "and{b}\t{%2, %h0|%h0, %2}"
8238 [(set_attr "type" "alu")
8239 (set_attr "length_immediate" "1")
8240 (set_attr "mode" "QI")])
8242 ;; Generated by peephole translating test to and. This shows up
8243 ;; often in fp comparisons.
8245 (define_insn "*andqi_ext_0_cc"
8246 [(set (reg FLAGS_REG)
8250 (match_operand 1 "ext_register_operand" "0")
8253 (match_operand 2 "const_int_operand" "n"))
8255 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8264 "ix86_match_ccmode (insn, CCNOmode)"
8265 "and{b}\t{%2, %h0|%h0, %2}"
8266 [(set_attr "type" "alu")
8267 (set_attr "length_immediate" "1")
8268 (set_attr "mode" "QI")])
8270 (define_insn "*andqi_ext_1"
8271 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8276 (match_operand 1 "ext_register_operand" "0")
8280 (match_operand:QI 2 "general_operand" "Qm"))))
8281 (clobber (reg:CC FLAGS_REG))]
8283 "and{b}\t{%2, %h0|%h0, %2}"
8284 [(set_attr "type" "alu")
8285 (set_attr "length_immediate" "0")
8286 (set_attr "mode" "QI")])
8288 (define_insn "*andqi_ext_1_rex64"
8289 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8294 (match_operand 1 "ext_register_operand" "0")
8298 (match_operand 2 "ext_register_operand" "Q"))))
8299 (clobber (reg:CC FLAGS_REG))]
8301 "and{b}\t{%2, %h0|%h0, %2}"
8302 [(set_attr "type" "alu")
8303 (set_attr "length_immediate" "0")
8304 (set_attr "mode" "QI")])
8306 (define_insn "*andqi_ext_2"
8307 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8312 (match_operand 1 "ext_register_operand" "%0")
8316 (match_operand 2 "ext_register_operand" "Q")
8319 (clobber (reg:CC FLAGS_REG))]
8321 "and{b}\t{%h2, %h0|%h0, %h2}"
8322 [(set_attr "type" "alu")
8323 (set_attr "length_immediate" "0")
8324 (set_attr "mode" "QI")])
8326 ;; Convert wide AND instructions with immediate operand to shorter QImode
8327 ;; equivalents when possible.
8328 ;; Don't do the splitting with memory operands, since it introduces risk
8329 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8330 ;; for size, but that can (should?) be handled by generic code instead.
8332 [(set (match_operand 0 "register_operand" "")
8333 (and (match_operand 1 "register_operand" "")
8334 (match_operand 2 "const_int_operand" "")))
8335 (clobber (reg:CC FLAGS_REG))]
8337 && QI_REG_P (operands[0])
8338 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8339 && !(~INTVAL (operands[2]) & ~(255 << 8))
8340 && GET_MODE (operands[0]) != QImode"
8341 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8342 (and:SI (zero_extract:SI (match_dup 1)
8343 (const_int 8) (const_int 8))
8345 (clobber (reg:CC FLAGS_REG))])]
8346 "operands[0] = gen_lowpart (SImode, operands[0]);
8347 operands[1] = gen_lowpart (SImode, operands[1]);
8348 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8350 ;; Since AND can be encoded with sign extended immediate, this is only
8351 ;; profitable when 7th bit is not set.
8353 [(set (match_operand 0 "register_operand" "")
8354 (and (match_operand 1 "general_operand" "")
8355 (match_operand 2 "const_int_operand" "")))
8356 (clobber (reg:CC FLAGS_REG))]
8358 && ANY_QI_REG_P (operands[0])
8359 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8360 && !(~INTVAL (operands[2]) & ~255)
8361 && !(INTVAL (operands[2]) & 128)
8362 && GET_MODE (operands[0]) != QImode"
8363 [(parallel [(set (strict_low_part (match_dup 0))
8364 (and:QI (match_dup 1)
8366 (clobber (reg:CC FLAGS_REG))])]
8367 "operands[0] = gen_lowpart (QImode, operands[0]);
8368 operands[1] = gen_lowpart (QImode, operands[1]);
8369 operands[2] = gen_lowpart (QImode, operands[2]);")
8371 ;; Logical inclusive OR instructions
8373 ;; %%% This used to optimize known byte-wide and operations to memory.
8374 ;; If this is considered useful, it should be done with splitters.
8376 (define_expand "iordi3"
8377 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8378 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8379 (match_operand:DI 2 "x86_64_general_operand" "")))
8380 (clobber (reg:CC FLAGS_REG))]
8382 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8384 (define_insn "*iordi_1_rex64"
8385 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8386 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8387 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8388 (clobber (reg:CC FLAGS_REG))]
8390 && ix86_binary_operator_ok (IOR, DImode, operands)"
8391 "or{q}\t{%2, %0|%0, %2}"
8392 [(set_attr "type" "alu")
8393 (set_attr "mode" "DI")])
8395 (define_insn "*iordi_2_rex64"
8396 [(set (reg FLAGS_REG)
8397 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8398 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8400 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8401 (ior:DI (match_dup 1) (match_dup 2)))]
8403 && ix86_match_ccmode (insn, CCNOmode)
8404 && ix86_binary_operator_ok (IOR, DImode, operands)"
8405 "or{q}\t{%2, %0|%0, %2}"
8406 [(set_attr "type" "alu")
8407 (set_attr "mode" "DI")])
8409 (define_insn "*iordi_3_rex64"
8410 [(set (reg FLAGS_REG)
8411 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8412 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8414 (clobber (match_scratch:DI 0 "=r"))]
8416 && ix86_match_ccmode (insn, CCNOmode)
8417 && ix86_binary_operator_ok (IOR, DImode, operands)"
8418 "or{q}\t{%2, %0|%0, %2}"
8419 [(set_attr "type" "alu")
8420 (set_attr "mode" "DI")])
8423 (define_expand "iorsi3"
8424 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8425 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8426 (match_operand:SI 2 "general_operand" "")))
8427 (clobber (reg:CC FLAGS_REG))]
8429 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8431 (define_insn "*iorsi_1"
8432 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8433 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8434 (match_operand:SI 2 "general_operand" "ri,rmi")))
8435 (clobber (reg:CC FLAGS_REG))]
8436 "ix86_binary_operator_ok (IOR, SImode, operands)"
8437 "or{l}\t{%2, %0|%0, %2}"
8438 [(set_attr "type" "alu")
8439 (set_attr "mode" "SI")])
8441 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8442 (define_insn "*iorsi_1_zext"
8443 [(set (match_operand:DI 0 "register_operand" "=rm")
8445 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8446 (match_operand:SI 2 "general_operand" "rim"))))
8447 (clobber (reg:CC FLAGS_REG))]
8448 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8449 "or{l}\t{%2, %k0|%k0, %2}"
8450 [(set_attr "type" "alu")
8451 (set_attr "mode" "SI")])
8453 (define_insn "*iorsi_1_zext_imm"
8454 [(set (match_operand:DI 0 "register_operand" "=rm")
8455 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8456 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8457 (clobber (reg:CC FLAGS_REG))]
8459 "or{l}\t{%2, %k0|%k0, %2}"
8460 [(set_attr "type" "alu")
8461 (set_attr "mode" "SI")])
8463 (define_insn "*iorsi_2"
8464 [(set (reg FLAGS_REG)
8465 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8466 (match_operand:SI 2 "general_operand" "rim,ri"))
8468 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8469 (ior:SI (match_dup 1) (match_dup 2)))]
8470 "ix86_match_ccmode (insn, CCNOmode)
8471 && ix86_binary_operator_ok (IOR, SImode, operands)"
8472 "or{l}\t{%2, %0|%0, %2}"
8473 [(set_attr "type" "alu")
8474 (set_attr "mode" "SI")])
8476 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8477 ;; ??? Special case for immediate operand is missing - it is tricky.
8478 (define_insn "*iorsi_2_zext"
8479 [(set (reg FLAGS_REG)
8480 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8481 (match_operand:SI 2 "general_operand" "rim"))
8483 (set (match_operand:DI 0 "register_operand" "=r")
8484 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8485 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8486 && ix86_binary_operator_ok (IOR, SImode, operands)"
8487 "or{l}\t{%2, %k0|%k0, %2}"
8488 [(set_attr "type" "alu")
8489 (set_attr "mode" "SI")])
8491 (define_insn "*iorsi_2_zext_imm"
8492 [(set (reg FLAGS_REG)
8493 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8494 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8496 (set (match_operand:DI 0 "register_operand" "=r")
8497 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8498 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8499 && ix86_binary_operator_ok (IOR, SImode, operands)"
8500 "or{l}\t{%2, %k0|%k0, %2}"
8501 [(set_attr "type" "alu")
8502 (set_attr "mode" "SI")])
8504 (define_insn "*iorsi_3"
8505 [(set (reg FLAGS_REG)
8506 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8507 (match_operand:SI 2 "general_operand" "rim"))
8509 (clobber (match_scratch:SI 0 "=r"))]
8510 "ix86_match_ccmode (insn, CCNOmode)
8511 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8512 "or{l}\t{%2, %0|%0, %2}"
8513 [(set_attr "type" "alu")
8514 (set_attr "mode" "SI")])
8516 (define_expand "iorhi3"
8517 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8518 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8519 (match_operand:HI 2 "general_operand" "")))
8520 (clobber (reg:CC FLAGS_REG))]
8521 "TARGET_HIMODE_MATH"
8522 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8524 (define_insn "*iorhi_1"
8525 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8526 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8527 (match_operand:HI 2 "general_operand" "rmi,ri")))
8528 (clobber (reg:CC FLAGS_REG))]
8529 "ix86_binary_operator_ok (IOR, HImode, operands)"
8530 "or{w}\t{%2, %0|%0, %2}"
8531 [(set_attr "type" "alu")
8532 (set_attr "mode" "HI")])
8534 (define_insn "*iorhi_2"
8535 [(set (reg FLAGS_REG)
8536 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8537 (match_operand:HI 2 "general_operand" "rim,ri"))
8539 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8540 (ior:HI (match_dup 1) (match_dup 2)))]
8541 "ix86_match_ccmode (insn, CCNOmode)
8542 && ix86_binary_operator_ok (IOR, HImode, operands)"
8543 "or{w}\t{%2, %0|%0, %2}"
8544 [(set_attr "type" "alu")
8545 (set_attr "mode" "HI")])
8547 (define_insn "*iorhi_3"
8548 [(set (reg FLAGS_REG)
8549 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8550 (match_operand:HI 2 "general_operand" "rim"))
8552 (clobber (match_scratch:HI 0 "=r"))]
8553 "ix86_match_ccmode (insn, CCNOmode)
8554 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8555 "or{w}\t{%2, %0|%0, %2}"
8556 [(set_attr "type" "alu")
8557 (set_attr "mode" "HI")])
8559 (define_expand "iorqi3"
8560 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8561 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8562 (match_operand:QI 2 "general_operand" "")))
8563 (clobber (reg:CC FLAGS_REG))]
8564 "TARGET_QIMODE_MATH"
8565 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8567 ;; %%% Potential partial reg stall on alternative 2. What to do?
8568 (define_insn "*iorqi_1"
8569 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8570 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8571 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8572 (clobber (reg:CC FLAGS_REG))]
8573 "ix86_binary_operator_ok (IOR, QImode, operands)"
8575 or{b}\t{%2, %0|%0, %2}
8576 or{b}\t{%2, %0|%0, %2}
8577 or{l}\t{%k2, %k0|%k0, %k2}"
8578 [(set_attr "type" "alu")
8579 (set_attr "mode" "QI,QI,SI")])
8581 (define_insn "*iorqi_1_slp"
8582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8583 (ior:QI (match_dup 0)
8584 (match_operand:QI 1 "general_operand" "qmi,qi")))
8585 (clobber (reg:CC FLAGS_REG))]
8586 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8587 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8588 "or{b}\t{%1, %0|%0, %1}"
8589 [(set_attr "type" "alu1")
8590 (set_attr "mode" "QI")])
8592 (define_insn "*iorqi_2"
8593 [(set (reg FLAGS_REG)
8594 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8595 (match_operand:QI 2 "general_operand" "qim,qi"))
8597 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8598 (ior:QI (match_dup 1) (match_dup 2)))]
8599 "ix86_match_ccmode (insn, CCNOmode)
8600 && ix86_binary_operator_ok (IOR, QImode, operands)"
8601 "or{b}\t{%2, %0|%0, %2}"
8602 [(set_attr "type" "alu")
8603 (set_attr "mode" "QI")])
8605 (define_insn "*iorqi_2_slp"
8606 [(set (reg FLAGS_REG)
8607 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8608 (match_operand:QI 1 "general_operand" "qim,qi"))
8610 (set (strict_low_part (match_dup 0))
8611 (ior:QI (match_dup 0) (match_dup 1)))]
8612 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8613 && ix86_match_ccmode (insn, CCNOmode)
8614 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8615 "or{b}\t{%1, %0|%0, %1}"
8616 [(set_attr "type" "alu1")
8617 (set_attr "mode" "QI")])
8619 (define_insn "*iorqi_3"
8620 [(set (reg FLAGS_REG)
8621 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8622 (match_operand:QI 2 "general_operand" "qim"))
8624 (clobber (match_scratch:QI 0 "=q"))]
8625 "ix86_match_ccmode (insn, CCNOmode)
8626 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8627 "or{b}\t{%2, %0|%0, %2}"
8628 [(set_attr "type" "alu")
8629 (set_attr "mode" "QI")])
8631 (define_insn "iorqi_ext_0"
8632 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8637 (match_operand 1 "ext_register_operand" "0")
8640 (match_operand 2 "const_int_operand" "n")))
8641 (clobber (reg:CC FLAGS_REG))]
8642 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8643 "or{b}\t{%2, %h0|%h0, %2}"
8644 [(set_attr "type" "alu")
8645 (set_attr "length_immediate" "1")
8646 (set_attr "mode" "QI")])
8648 (define_insn "*iorqi_ext_1"
8649 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8654 (match_operand 1 "ext_register_operand" "0")
8658 (match_operand:QI 2 "general_operand" "Qm"))))
8659 (clobber (reg:CC FLAGS_REG))]
8661 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8662 "or{b}\t{%2, %h0|%h0, %2}"
8663 [(set_attr "type" "alu")
8664 (set_attr "length_immediate" "0")
8665 (set_attr "mode" "QI")])
8667 (define_insn "*iorqi_ext_1_rex64"
8668 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8673 (match_operand 1 "ext_register_operand" "0")
8677 (match_operand 2 "ext_register_operand" "Q"))))
8678 (clobber (reg:CC FLAGS_REG))]
8680 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8681 "or{b}\t{%2, %h0|%h0, %2}"
8682 [(set_attr "type" "alu")
8683 (set_attr "length_immediate" "0")
8684 (set_attr "mode" "QI")])
8686 (define_insn "*iorqi_ext_2"
8687 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8691 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8694 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8697 (clobber (reg:CC FLAGS_REG))]
8698 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8699 "ior{b}\t{%h2, %h0|%h0, %h2}"
8700 [(set_attr "type" "alu")
8701 (set_attr "length_immediate" "0")
8702 (set_attr "mode" "QI")])
8705 [(set (match_operand 0 "register_operand" "")
8706 (ior (match_operand 1 "register_operand" "")
8707 (match_operand 2 "const_int_operand" "")))
8708 (clobber (reg:CC FLAGS_REG))]
8710 && QI_REG_P (operands[0])
8711 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8712 && !(INTVAL (operands[2]) & ~(255 << 8))
8713 && GET_MODE (operands[0]) != QImode"
8714 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8715 (ior:SI (zero_extract:SI (match_dup 1)
8716 (const_int 8) (const_int 8))
8718 (clobber (reg:CC FLAGS_REG))])]
8719 "operands[0] = gen_lowpart (SImode, operands[0]);
8720 operands[1] = gen_lowpart (SImode, operands[1]);
8721 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8723 ;; Since OR can be encoded with sign extended immediate, this is only
8724 ;; profitable when 7th bit is set.
8726 [(set (match_operand 0 "register_operand" "")
8727 (ior (match_operand 1 "general_operand" "")
8728 (match_operand 2 "const_int_operand" "")))
8729 (clobber (reg:CC FLAGS_REG))]
8731 && ANY_QI_REG_P (operands[0])
8732 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8733 && !(INTVAL (operands[2]) & ~255)
8734 && (INTVAL (operands[2]) & 128)
8735 && GET_MODE (operands[0]) != QImode"
8736 [(parallel [(set (strict_low_part (match_dup 0))
8737 (ior:QI (match_dup 1)
8739 (clobber (reg:CC FLAGS_REG))])]
8740 "operands[0] = gen_lowpart (QImode, operands[0]);
8741 operands[1] = gen_lowpart (QImode, operands[1]);
8742 operands[2] = gen_lowpart (QImode, operands[2]);")
8744 ;; Logical XOR instructions
8746 ;; %%% This used to optimize known byte-wide and operations to memory.
8747 ;; If this is considered useful, it should be done with splitters.
8749 (define_expand "xordi3"
8750 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8751 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8752 (match_operand:DI 2 "x86_64_general_operand" "")))
8753 (clobber (reg:CC FLAGS_REG))]
8755 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8757 (define_insn "*xordi_1_rex64"
8758 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8759 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8760 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8761 (clobber (reg:CC FLAGS_REG))]
8763 && ix86_binary_operator_ok (XOR, DImode, operands)"
8765 xor{q}\t{%2, %0|%0, %2}
8766 xor{q}\t{%2, %0|%0, %2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "DI,DI")])
8770 (define_insn "*xordi_2_rex64"
8771 [(set (reg FLAGS_REG)
8772 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8773 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8775 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8776 (xor:DI (match_dup 1) (match_dup 2)))]
8778 && ix86_match_ccmode (insn, CCNOmode)
8779 && ix86_binary_operator_ok (XOR, DImode, operands)"
8781 xor{q}\t{%2, %0|%0, %2}
8782 xor{q}\t{%2, %0|%0, %2}"
8783 [(set_attr "type" "alu")
8784 (set_attr "mode" "DI,DI")])
8786 (define_insn "*xordi_3_rex64"
8787 [(set (reg FLAGS_REG)
8788 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8789 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8791 (clobber (match_scratch:DI 0 "=r"))]
8793 && ix86_match_ccmode (insn, CCNOmode)
8794 && ix86_binary_operator_ok (XOR, DImode, operands)"
8795 "xor{q}\t{%2, %0|%0, %2}"
8796 [(set_attr "type" "alu")
8797 (set_attr "mode" "DI")])
8799 (define_expand "xorsi3"
8800 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8801 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8802 (match_operand:SI 2 "general_operand" "")))
8803 (clobber (reg:CC FLAGS_REG))]
8805 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8807 (define_insn "*xorsi_1"
8808 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8809 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8810 (match_operand:SI 2 "general_operand" "ri,rm")))
8811 (clobber (reg:CC FLAGS_REG))]
8812 "ix86_binary_operator_ok (XOR, SImode, operands)"
8813 "xor{l}\t{%2, %0|%0, %2}"
8814 [(set_attr "type" "alu")
8815 (set_attr "mode" "SI")])
8817 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8818 ;; Add speccase for immediates
8819 (define_insn "*xorsi_1_zext"
8820 [(set (match_operand:DI 0 "register_operand" "=r")
8822 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8823 (match_operand:SI 2 "general_operand" "rim"))))
8824 (clobber (reg:CC FLAGS_REG))]
8825 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8826 "xor{l}\t{%2, %k0|%k0, %2}"
8827 [(set_attr "type" "alu")
8828 (set_attr "mode" "SI")])
8830 (define_insn "*xorsi_1_zext_imm"
8831 [(set (match_operand:DI 0 "register_operand" "=r")
8832 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8833 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8834 (clobber (reg:CC FLAGS_REG))]
8835 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8836 "xor{l}\t{%2, %k0|%k0, %2}"
8837 [(set_attr "type" "alu")
8838 (set_attr "mode" "SI")])
8840 (define_insn "*xorsi_2"
8841 [(set (reg FLAGS_REG)
8842 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8843 (match_operand:SI 2 "general_operand" "rim,ri"))
8845 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8846 (xor:SI (match_dup 1) (match_dup 2)))]
8847 "ix86_match_ccmode (insn, CCNOmode)
8848 && ix86_binary_operator_ok (XOR, SImode, operands)"
8849 "xor{l}\t{%2, %0|%0, %2}"
8850 [(set_attr "type" "alu")
8851 (set_attr "mode" "SI")])
8853 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8854 ;; ??? Special case for immediate operand is missing - it is tricky.
8855 (define_insn "*xorsi_2_zext"
8856 [(set (reg FLAGS_REG)
8857 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8858 (match_operand:SI 2 "general_operand" "rim"))
8860 (set (match_operand:DI 0 "register_operand" "=r")
8861 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8862 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8863 && ix86_binary_operator_ok (XOR, SImode, operands)"
8864 "xor{l}\t{%2, %k0|%k0, %2}"
8865 [(set_attr "type" "alu")
8866 (set_attr "mode" "SI")])
8868 (define_insn "*xorsi_2_zext_imm"
8869 [(set (reg FLAGS_REG)
8870 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8871 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8873 (set (match_operand:DI 0 "register_operand" "=r")
8874 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8875 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8876 && ix86_binary_operator_ok (XOR, SImode, operands)"
8877 "xor{l}\t{%2, %k0|%k0, %2}"
8878 [(set_attr "type" "alu")
8879 (set_attr "mode" "SI")])
8881 (define_insn "*xorsi_3"
8882 [(set (reg FLAGS_REG)
8883 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8884 (match_operand:SI 2 "general_operand" "rim"))
8886 (clobber (match_scratch:SI 0 "=r"))]
8887 "ix86_match_ccmode (insn, CCNOmode)
8888 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8889 "xor{l}\t{%2, %0|%0, %2}"
8890 [(set_attr "type" "alu")
8891 (set_attr "mode" "SI")])
8893 (define_expand "xorhi3"
8894 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8895 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8896 (match_operand:HI 2 "general_operand" "")))
8897 (clobber (reg:CC FLAGS_REG))]
8898 "TARGET_HIMODE_MATH"
8899 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
8901 (define_insn "*xorhi_1"
8902 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8903 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8904 (match_operand:HI 2 "general_operand" "rmi,ri")))
8905 (clobber (reg:CC FLAGS_REG))]
8906 "ix86_binary_operator_ok (XOR, HImode, operands)"
8907 "xor{w}\t{%2, %0|%0, %2}"
8908 [(set_attr "type" "alu")
8909 (set_attr "mode" "HI")])
8911 (define_insn "*xorhi_2"
8912 [(set (reg FLAGS_REG)
8913 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8914 (match_operand:HI 2 "general_operand" "rim,ri"))
8916 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8917 (xor:HI (match_dup 1) (match_dup 2)))]
8918 "ix86_match_ccmode (insn, CCNOmode)
8919 && ix86_binary_operator_ok (XOR, HImode, operands)"
8920 "xor{w}\t{%2, %0|%0, %2}"
8921 [(set_attr "type" "alu")
8922 (set_attr "mode" "HI")])
8924 (define_insn "*xorhi_3"
8925 [(set (reg FLAGS_REG)
8926 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8927 (match_operand:HI 2 "general_operand" "rim"))
8929 (clobber (match_scratch:HI 0 "=r"))]
8930 "ix86_match_ccmode (insn, CCNOmode)
8931 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8932 "xor{w}\t{%2, %0|%0, %2}"
8933 [(set_attr "type" "alu")
8934 (set_attr "mode" "HI")])
8936 (define_expand "xorqi3"
8937 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8938 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8939 (match_operand:QI 2 "general_operand" "")))
8940 (clobber (reg:CC FLAGS_REG))]
8941 "TARGET_QIMODE_MATH"
8942 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
8944 ;; %%% Potential partial reg stall on alternative 2. What to do?
8945 (define_insn "*xorqi_1"
8946 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8947 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8948 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8949 (clobber (reg:CC FLAGS_REG))]
8950 "ix86_binary_operator_ok (XOR, QImode, operands)"
8952 xor{b}\t{%2, %0|%0, %2}
8953 xor{b}\t{%2, %0|%0, %2}
8954 xor{l}\t{%k2, %k0|%k0, %k2}"
8955 [(set_attr "type" "alu")
8956 (set_attr "mode" "QI,QI,SI")])
8958 (define_insn "*xorqi_1_slp"
8959 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8960 (xor:QI (match_dup 0)
8961 (match_operand:QI 1 "general_operand" "qi,qmi")))
8962 (clobber (reg:CC FLAGS_REG))]
8963 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8964 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8965 "xor{b}\t{%1, %0|%0, %1}"
8966 [(set_attr "type" "alu1")
8967 (set_attr "mode" "QI")])
8969 (define_insn "xorqi_ext_0"
8970 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8975 (match_operand 1 "ext_register_operand" "0")
8978 (match_operand 2 "const_int_operand" "n")))
8979 (clobber (reg:CC FLAGS_REG))]
8980 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8981 "xor{b}\t{%2, %h0|%h0, %2}"
8982 [(set_attr "type" "alu")
8983 (set_attr "length_immediate" "1")
8984 (set_attr "mode" "QI")])
8986 (define_insn "*xorqi_ext_1"
8987 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8992 (match_operand 1 "ext_register_operand" "0")
8996 (match_operand:QI 2 "general_operand" "Qm"))))
8997 (clobber (reg:CC FLAGS_REG))]
8999 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9000 "xor{b}\t{%2, %h0|%h0, %2}"
9001 [(set_attr "type" "alu")
9002 (set_attr "length_immediate" "0")
9003 (set_attr "mode" "QI")])
9005 (define_insn "*xorqi_ext_1_rex64"
9006 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9011 (match_operand 1 "ext_register_operand" "0")
9015 (match_operand 2 "ext_register_operand" "Q"))))
9016 (clobber (reg:CC FLAGS_REG))]
9018 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9019 "xor{b}\t{%2, %h0|%h0, %2}"
9020 [(set_attr "type" "alu")
9021 (set_attr "length_immediate" "0")
9022 (set_attr "mode" "QI")])
9024 (define_insn "*xorqi_ext_2"
9025 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9029 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9032 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9035 (clobber (reg:CC FLAGS_REG))]
9036 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9037 "xor{b}\t{%h2, %h0|%h0, %h2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "length_immediate" "0")
9040 (set_attr "mode" "QI")])
9042 (define_insn "*xorqi_cc_1"
9043 [(set (reg FLAGS_REG)
9045 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9046 (match_operand:QI 2 "general_operand" "qim,qi"))
9048 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9049 (xor:QI (match_dup 1) (match_dup 2)))]
9050 "ix86_match_ccmode (insn, CCNOmode)
9051 && ix86_binary_operator_ok (XOR, QImode, operands)"
9052 "xor{b}\t{%2, %0|%0, %2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "mode" "QI")])
9056 (define_insn "*xorqi_2_slp"
9057 [(set (reg FLAGS_REG)
9058 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9059 (match_operand:QI 1 "general_operand" "qim,qi"))
9061 (set (strict_low_part (match_dup 0))
9062 (xor:QI (match_dup 0) (match_dup 1)))]
9063 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9064 && ix86_match_ccmode (insn, CCNOmode)
9065 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9066 "xor{b}\t{%1, %0|%0, %1}"
9067 [(set_attr "type" "alu1")
9068 (set_attr "mode" "QI")])
9070 (define_insn "*xorqi_cc_2"
9071 [(set (reg FLAGS_REG)
9073 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9074 (match_operand:QI 2 "general_operand" "qim"))
9076 (clobber (match_scratch:QI 0 "=q"))]
9077 "ix86_match_ccmode (insn, CCNOmode)
9078 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9079 "xor{b}\t{%2, %0|%0, %2}"
9080 [(set_attr "type" "alu")
9081 (set_attr "mode" "QI")])
9083 (define_insn "*xorqi_cc_ext_1"
9084 [(set (reg FLAGS_REG)
9088 (match_operand 1 "ext_register_operand" "0")
9091 (match_operand:QI 2 "general_operand" "qmn"))
9093 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9097 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9099 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9100 "xor{b}\t{%2, %h0|%h0, %2}"
9101 [(set_attr "type" "alu")
9102 (set_attr "mode" "QI")])
9104 (define_insn "*xorqi_cc_ext_1_rex64"
9105 [(set (reg FLAGS_REG)
9109 (match_operand 1 "ext_register_operand" "0")
9112 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9114 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9118 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9120 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9121 "xor{b}\t{%2, %h0|%h0, %2}"
9122 [(set_attr "type" "alu")
9123 (set_attr "mode" "QI")])
9125 (define_expand "xorqi_cc_ext_1"
9127 (set (reg:CCNO FLAGS_REG)
9131 (match_operand 1 "ext_register_operand" "")
9134 (match_operand:QI 2 "general_operand" ""))
9136 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9140 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9146 [(set (match_operand 0 "register_operand" "")
9147 (xor (match_operand 1 "register_operand" "")
9148 (match_operand 2 "const_int_operand" "")))
9149 (clobber (reg:CC FLAGS_REG))]
9151 && QI_REG_P (operands[0])
9152 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9153 && !(INTVAL (operands[2]) & ~(255 << 8))
9154 && GET_MODE (operands[0]) != QImode"
9155 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9156 (xor:SI (zero_extract:SI (match_dup 1)
9157 (const_int 8) (const_int 8))
9159 (clobber (reg:CC FLAGS_REG))])]
9160 "operands[0] = gen_lowpart (SImode, operands[0]);
9161 operands[1] = gen_lowpart (SImode, operands[1]);
9162 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9164 ;; Since XOR can be encoded with sign extended immediate, this is only
9165 ;; profitable when 7th bit is set.
9167 [(set (match_operand 0 "register_operand" "")
9168 (xor (match_operand 1 "general_operand" "")
9169 (match_operand 2 "const_int_operand" "")))
9170 (clobber (reg:CC FLAGS_REG))]
9172 && ANY_QI_REG_P (operands[0])
9173 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9174 && !(INTVAL (operands[2]) & ~255)
9175 && (INTVAL (operands[2]) & 128)
9176 && GET_MODE (operands[0]) != QImode"
9177 [(parallel [(set (strict_low_part (match_dup 0))
9178 (xor:QI (match_dup 1)
9180 (clobber (reg:CC FLAGS_REG))])]
9181 "operands[0] = gen_lowpart (QImode, operands[0]);
9182 operands[1] = gen_lowpart (QImode, operands[1]);
9183 operands[2] = gen_lowpart (QImode, operands[2]);")
9185 ;; Negation instructions
9187 (define_expand "negdi2"
9188 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9189 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9190 (clobber (reg:CC FLAGS_REG))])]
9192 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9194 (define_insn "*negdi2_1"
9195 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9196 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9197 (clobber (reg:CC FLAGS_REG))]
9199 && ix86_unary_operator_ok (NEG, DImode, operands)"
9203 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9204 (neg:DI (match_operand:DI 1 "general_operand" "")))
9205 (clobber (reg:CC FLAGS_REG))]
9206 "!TARGET_64BIT && reload_completed"
9208 [(set (reg:CCZ FLAGS_REG)
9209 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9210 (set (match_dup 0) (neg:SI (match_dup 2)))])
9213 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9216 (clobber (reg:CC FLAGS_REG))])
9219 (neg:SI (match_dup 1)))
9220 (clobber (reg:CC FLAGS_REG))])]
9221 "split_di (operands+1, 1, operands+2, operands+3);
9222 split_di (operands+0, 1, operands+0, operands+1);")
9224 (define_insn "*negdi2_1_rex64"
9225 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9226 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9227 (clobber (reg:CC FLAGS_REG))]
9228 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9230 [(set_attr "type" "negnot")
9231 (set_attr "mode" "DI")])
9233 ;; The problem with neg is that it does not perform (compare x 0),
9234 ;; it really performs (compare 0 x), which leaves us with the zero
9235 ;; flag being the only useful item.
9237 (define_insn "*negdi2_cmpz_rex64"
9238 [(set (reg:CCZ FLAGS_REG)
9239 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9241 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9242 (neg:DI (match_dup 1)))]
9243 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9245 [(set_attr "type" "negnot")
9246 (set_attr "mode" "DI")])
9249 (define_expand "negsi2"
9250 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9251 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9252 (clobber (reg:CC FLAGS_REG))])]
9254 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9256 (define_insn "*negsi2_1"
9257 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9258 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9259 (clobber (reg:CC FLAGS_REG))]
9260 "ix86_unary_operator_ok (NEG, SImode, operands)"
9262 [(set_attr "type" "negnot")
9263 (set_attr "mode" "SI")])
9265 ;; Combine is quite creative about this pattern.
9266 (define_insn "*negsi2_1_zext"
9267 [(set (match_operand:DI 0 "register_operand" "=r")
9268 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9271 (clobber (reg:CC FLAGS_REG))]
9272 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9274 [(set_attr "type" "negnot")
9275 (set_attr "mode" "SI")])
9277 ;; The problem with neg is that it does not perform (compare x 0),
9278 ;; it really performs (compare 0 x), which leaves us with the zero
9279 ;; flag being the only useful item.
9281 (define_insn "*negsi2_cmpz"
9282 [(set (reg:CCZ FLAGS_REG)
9283 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9285 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9286 (neg:SI (match_dup 1)))]
9287 "ix86_unary_operator_ok (NEG, SImode, operands)"
9289 [(set_attr "type" "negnot")
9290 (set_attr "mode" "SI")])
9292 (define_insn "*negsi2_cmpz_zext"
9293 [(set (reg:CCZ FLAGS_REG)
9294 (compare:CCZ (lshiftrt:DI
9296 (match_operand:DI 1 "register_operand" "0")
9300 (set (match_operand:DI 0 "register_operand" "=r")
9301 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9304 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9306 [(set_attr "type" "negnot")
9307 (set_attr "mode" "SI")])
9309 (define_expand "neghi2"
9310 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9311 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9312 (clobber (reg:CC FLAGS_REG))])]
9313 "TARGET_HIMODE_MATH"
9314 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9316 (define_insn "*neghi2_1"
9317 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9318 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9319 (clobber (reg:CC FLAGS_REG))]
9320 "ix86_unary_operator_ok (NEG, HImode, operands)"
9322 [(set_attr "type" "negnot")
9323 (set_attr "mode" "HI")])
9325 (define_insn "*neghi2_cmpz"
9326 [(set (reg:CCZ FLAGS_REG)
9327 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9329 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9330 (neg:HI (match_dup 1)))]
9331 "ix86_unary_operator_ok (NEG, HImode, operands)"
9333 [(set_attr "type" "negnot")
9334 (set_attr "mode" "HI")])
9336 (define_expand "negqi2"
9337 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9338 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9339 (clobber (reg:CC FLAGS_REG))])]
9340 "TARGET_QIMODE_MATH"
9341 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9343 (define_insn "*negqi2_1"
9344 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9345 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9346 (clobber (reg:CC FLAGS_REG))]
9347 "ix86_unary_operator_ok (NEG, QImode, operands)"
9349 [(set_attr "type" "negnot")
9350 (set_attr "mode" "QI")])
9352 (define_insn "*negqi2_cmpz"
9353 [(set (reg:CCZ FLAGS_REG)
9354 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9356 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9357 (neg:QI (match_dup 1)))]
9358 "ix86_unary_operator_ok (NEG, QImode, operands)"
9360 [(set_attr "type" "negnot")
9361 (set_attr "mode" "QI")])
9363 ;; Changing of sign for FP values is doable using integer unit too.
9365 (define_expand "negsf2"
9366 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9367 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9368 "TARGET_80387 || TARGET_SSE_MATH"
9369 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9371 (define_expand "abssf2"
9372 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9373 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9374 "TARGET_80387 || TARGET_SSE_MATH"
9375 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9377 (define_insn "*absnegsf2_mixed"
9378 [(set (match_operand:SF 0 "nonimmediate_operand" "=x#f,x#f,f#x,rm")
9379 (match_operator:SF 3 "absneg_operator"
9380 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x#f,0 ,0")]))
9381 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0 ,X ,X"))
9382 (clobber (reg:CC FLAGS_REG))]
9383 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9384 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9387 (define_insn "*absnegsf2_sse"
9388 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9389 (match_operator:SF 3 "absneg_operator"
9390 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9391 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9392 (clobber (reg:CC FLAGS_REG))]
9394 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9397 (define_insn "*absnegsf2_i387"
9398 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9399 (match_operator:SF 3 "absneg_operator"
9400 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9401 (use (match_operand 2 "" ""))
9402 (clobber (reg:CC FLAGS_REG))]
9403 "TARGET_80387 && !TARGET_SSE_MATH
9404 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9407 (define_expand "copysignsf3"
9408 [(match_operand:SF 0 "register_operand" "")
9409 (match_operand:SF 1 "nonmemory_operand" "")
9410 (match_operand:SF 2 "register_operand" "")]
9413 ix86_expand_copysign (operands);
9417 (define_insn_and_split "copysignsf3_const"
9418 [(set (match_operand:SF 0 "register_operand" "=x")
9420 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9421 (match_operand:SF 2 "register_operand" "0")
9422 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9426 "&& reload_completed"
9429 ix86_split_copysign_const (operands);
9433 (define_insn "copysignsf3_var"
9434 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9436 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9437 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9438 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9439 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9441 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9446 [(set (match_operand:SF 0 "register_operand" "")
9448 [(match_operand:SF 2 "register_operand" "")
9449 (match_operand:SF 3 "register_operand" "")
9450 (match_operand:V4SF 4 "" "")
9451 (match_operand:V4SF 5 "" "")]
9453 (clobber (match_scratch:V4SF 1 ""))]
9454 "TARGET_SSE_MATH && reload_completed"
9457 ix86_split_copysign_var (operands);
9461 (define_expand "negdf2"
9462 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9463 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9464 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9465 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9467 (define_expand "absdf2"
9468 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9469 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9470 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9471 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9473 (define_insn "*absnegdf2_mixed"
9474 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y#f,Y#f,f#Y,rm")
9475 (match_operator:DF 3 "absneg_operator"
9476 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y#f,0 ,0")]))
9477 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym ,0 ,X ,X"))
9478 (clobber (reg:CC FLAGS_REG))]
9479 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9480 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9483 (define_insn "*absnegdf2_sse"
9484 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9485 (match_operator:DF 3 "absneg_operator"
9486 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0")]))
9487 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X"))
9488 (clobber (reg:CC FLAGS_REG))]
9489 "TARGET_SSE2 && TARGET_SSE_MATH
9490 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9493 (define_insn "*absnegdf2_i387"
9494 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9495 (match_operator:DF 3 "absneg_operator"
9496 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9497 (use (match_operand 2 "" ""))
9498 (clobber (reg:CC FLAGS_REG))]
9499 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9500 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9503 (define_expand "copysigndf3"
9504 [(match_operand:DF 0 "register_operand" "")
9505 (match_operand:DF 1 "nonmemory_operand" "")
9506 (match_operand:DF 2 "register_operand" "")]
9507 "TARGET_SSE2 && TARGET_SSE_MATH"
9509 ix86_expand_copysign (operands);
9513 (define_insn_and_split "copysigndf3_const"
9514 [(set (match_operand:DF 0 "register_operand" "=x")
9516 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9517 (match_operand:DF 2 "register_operand" "0")
9518 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9520 "TARGET_SSE2 && TARGET_SSE_MATH"
9522 "&& reload_completed"
9525 ix86_split_copysign_const (operands);
9529 (define_insn "copysigndf3_var"
9530 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9532 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9533 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9534 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9535 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9537 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9538 "TARGET_SSE2 && TARGET_SSE_MATH"
9542 [(set (match_operand:DF 0 "register_operand" "")
9544 [(match_operand:DF 2 "register_operand" "")
9545 (match_operand:DF 3 "register_operand" "")
9546 (match_operand:V2DF 4 "" "")
9547 (match_operand:V2DF 5 "" "")]
9549 (clobber (match_scratch:V2DF 1 ""))]
9550 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9553 ix86_split_copysign_var (operands);
9557 (define_expand "negxf2"
9558 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9559 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9561 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9563 (define_expand "absxf2"
9564 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9565 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9567 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9569 (define_insn "*absnegxf2_i387"
9570 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9571 (match_operator:XF 3 "absneg_operator"
9572 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9573 (use (match_operand 2 "" ""))
9574 (clobber (reg:CC FLAGS_REG))]
9576 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9579 ;; Splitters for fp abs and neg.
9582 [(set (match_operand 0 "fp_register_operand" "")
9583 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9584 (use (match_operand 2 "" ""))
9585 (clobber (reg:CC FLAGS_REG))]
9587 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9590 [(set (match_operand 0 "register_operand" "")
9591 (match_operator 3 "absneg_operator"
9592 [(match_operand 1 "register_operand" "")]))
9593 (use (match_operand 2 "nonimmediate_operand" ""))
9594 (clobber (reg:CC FLAGS_REG))]
9595 "reload_completed && SSE_REG_P (operands[0])"
9596 [(set (match_dup 0) (match_dup 3))]
9598 enum machine_mode mode = GET_MODE (operands[0]);
9599 enum machine_mode vmode = GET_MODE (operands[2]);
9602 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9603 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9604 if (operands_match_p (operands[0], operands[2]))
9607 operands[1] = operands[2];
9610 if (GET_CODE (operands[3]) == ABS)
9611 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9613 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9618 [(set (match_operand:SF 0 "register_operand" "")
9619 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9620 (use (match_operand:V4SF 2 "" ""))
9621 (clobber (reg:CC FLAGS_REG))]
9623 [(parallel [(set (match_dup 0) (match_dup 1))
9624 (clobber (reg:CC FLAGS_REG))])]
9627 operands[0] = gen_lowpart (SImode, operands[0]);
9628 if (GET_CODE (operands[1]) == ABS)
9630 tmp = gen_int_mode (0x7fffffff, SImode);
9631 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9635 tmp = gen_int_mode (0x80000000, SImode);
9636 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9642 [(set (match_operand:DF 0 "register_operand" "")
9643 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9644 (use (match_operand 2 "" ""))
9645 (clobber (reg:CC FLAGS_REG))]
9647 [(parallel [(set (match_dup 0) (match_dup 1))
9648 (clobber (reg:CC FLAGS_REG))])]
9653 tmp = gen_lowpart (DImode, operands[0]);
9654 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9657 if (GET_CODE (operands[1]) == ABS)
9660 tmp = gen_rtx_NOT (DImode, tmp);
9664 operands[0] = gen_highpart (SImode, operands[0]);
9665 if (GET_CODE (operands[1]) == ABS)
9667 tmp = gen_int_mode (0x7fffffff, SImode);
9668 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9672 tmp = gen_int_mode (0x80000000, SImode);
9673 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9680 [(set (match_operand:XF 0 "register_operand" "")
9681 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9682 (use (match_operand 2 "" ""))
9683 (clobber (reg:CC FLAGS_REG))]
9685 [(parallel [(set (match_dup 0) (match_dup 1))
9686 (clobber (reg:CC FLAGS_REG))])]
9689 operands[0] = gen_rtx_REG (SImode,
9690 true_regnum (operands[0])
9691 + (TARGET_64BIT ? 1 : 2));
9692 if (GET_CODE (operands[1]) == ABS)
9694 tmp = GEN_INT (0x7fff);
9695 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9699 tmp = GEN_INT (0x8000);
9700 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9706 [(set (match_operand 0 "memory_operand" "")
9707 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9708 (use (match_operand 2 "" ""))
9709 (clobber (reg:CC FLAGS_REG))]
9711 [(parallel [(set (match_dup 0) (match_dup 1))
9712 (clobber (reg:CC FLAGS_REG))])]
9714 enum machine_mode mode = GET_MODE (operands[0]);
9715 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9718 operands[0] = adjust_address (operands[0], QImode, size - 1);
9719 if (GET_CODE (operands[1]) == ABS)
9721 tmp = gen_int_mode (0x7f, QImode);
9722 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9726 tmp = gen_int_mode (0x80, QImode);
9727 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9732 ;; Conditionalize these after reload. If they match before reload, we
9733 ;; lose the clobber and ability to use integer instructions.
9735 (define_insn "*negsf2_1"
9736 [(set (match_operand:SF 0 "register_operand" "=f")
9737 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9738 "TARGET_80387 && reload_completed"
9740 [(set_attr "type" "fsgn")
9741 (set_attr "mode" "SF")])
9743 (define_insn "*negdf2_1"
9744 [(set (match_operand:DF 0 "register_operand" "=f")
9745 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9746 "TARGET_80387 && reload_completed"
9748 [(set_attr "type" "fsgn")
9749 (set_attr "mode" "DF")])
9751 (define_insn "*negxf2_1"
9752 [(set (match_operand:XF 0 "register_operand" "=f")
9753 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9754 "TARGET_80387 && reload_completed"
9756 [(set_attr "type" "fsgn")
9757 (set_attr "mode" "XF")])
9759 (define_insn "*abssf2_1"
9760 [(set (match_operand:SF 0 "register_operand" "=f")
9761 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9762 "TARGET_80387 && reload_completed"
9764 [(set_attr "type" "fsgn")
9765 (set_attr "mode" "SF")])
9767 (define_insn "*absdf2_1"
9768 [(set (match_operand:DF 0 "register_operand" "=f")
9769 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9770 "TARGET_80387 && reload_completed"
9772 [(set_attr "type" "fsgn")
9773 (set_attr "mode" "DF")])
9775 (define_insn "*absxf2_1"
9776 [(set (match_operand:XF 0 "register_operand" "=f")
9777 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9778 "TARGET_80387 && reload_completed"
9780 [(set_attr "type" "fsgn")
9781 (set_attr "mode" "DF")])
9783 (define_insn "*negextendsfdf2"
9784 [(set (match_operand:DF 0 "register_operand" "=f")
9785 (neg:DF (float_extend:DF
9786 (match_operand:SF 1 "register_operand" "0"))))]
9787 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9789 [(set_attr "type" "fsgn")
9790 (set_attr "mode" "DF")])
9792 (define_insn "*negextenddfxf2"
9793 [(set (match_operand:XF 0 "register_operand" "=f")
9794 (neg:XF (float_extend:XF
9795 (match_operand:DF 1 "register_operand" "0"))))]
9798 [(set_attr "type" "fsgn")
9799 (set_attr "mode" "XF")])
9801 (define_insn "*negextendsfxf2"
9802 [(set (match_operand:XF 0 "register_operand" "=f")
9803 (neg:XF (float_extend:XF
9804 (match_operand:SF 1 "register_operand" "0"))))]
9807 [(set_attr "type" "fsgn")
9808 (set_attr "mode" "XF")])
9810 (define_insn "*absextendsfdf2"
9811 [(set (match_operand:DF 0 "register_operand" "=f")
9812 (abs:DF (float_extend:DF
9813 (match_operand:SF 1 "register_operand" "0"))))]
9814 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9816 [(set_attr "type" "fsgn")
9817 (set_attr "mode" "DF")])
9819 (define_insn "*absextenddfxf2"
9820 [(set (match_operand:XF 0 "register_operand" "=f")
9821 (abs:XF (float_extend:XF
9822 (match_operand:DF 1 "register_operand" "0"))))]
9825 [(set_attr "type" "fsgn")
9826 (set_attr "mode" "XF")])
9828 (define_insn "*absextendsfxf2"
9829 [(set (match_operand:XF 0 "register_operand" "=f")
9830 (abs:XF (float_extend:XF
9831 (match_operand:SF 1 "register_operand" "0"))))]
9834 [(set_attr "type" "fsgn")
9835 (set_attr "mode" "XF")])
9837 ;; One complement instructions
9839 (define_expand "one_cmpldi2"
9840 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9841 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9843 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
9845 (define_insn "*one_cmpldi2_1_rex64"
9846 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9847 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9848 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
9850 [(set_attr "type" "negnot")
9851 (set_attr "mode" "DI")])
9853 (define_insn "*one_cmpldi2_2_rex64"
9854 [(set (reg FLAGS_REG)
9855 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9857 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9858 (not:DI (match_dup 1)))]
9859 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9860 && ix86_unary_operator_ok (NOT, DImode, operands)"
9862 [(set_attr "type" "alu1")
9863 (set_attr "mode" "DI")])
9866 [(set (match_operand 0 "flags_reg_operand" "")
9867 (match_operator 2 "compare_operator"
9868 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
9870 (set (match_operand:DI 1 "nonimmediate_operand" "")
9871 (not:DI (match_dup 3)))]
9872 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9873 [(parallel [(set (match_dup 0)
9875 [(xor:DI (match_dup 3) (const_int -1))
9878 (xor:DI (match_dup 3) (const_int -1)))])]
9881 (define_expand "one_cmplsi2"
9882 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9883 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9885 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
9887 (define_insn "*one_cmplsi2_1"
9888 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9889 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
9890 "ix86_unary_operator_ok (NOT, SImode, operands)"
9892 [(set_attr "type" "negnot")
9893 (set_attr "mode" "SI")])
9895 ;; ??? Currently never generated - xor is used instead.
9896 (define_insn "*one_cmplsi2_1_zext"
9897 [(set (match_operand:DI 0 "register_operand" "=r")
9898 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9899 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9901 [(set_attr "type" "negnot")
9902 (set_attr "mode" "SI")])
9904 (define_insn "*one_cmplsi2_2"
9905 [(set (reg FLAGS_REG)
9906 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9908 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9909 (not:SI (match_dup 1)))]
9910 "ix86_match_ccmode (insn, CCNOmode)
9911 && ix86_unary_operator_ok (NOT, SImode, operands)"
9913 [(set_attr "type" "alu1")
9914 (set_attr "mode" "SI")])
9917 [(set (match_operand 0 "flags_reg_operand" "")
9918 (match_operator 2 "compare_operator"
9919 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
9921 (set (match_operand:SI 1 "nonimmediate_operand" "")
9922 (not:SI (match_dup 3)))]
9923 "ix86_match_ccmode (insn, CCNOmode)"
9924 [(parallel [(set (match_dup 0)
9925 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9928 (xor:SI (match_dup 3) (const_int -1)))])]
9931 ;; ??? Currently never generated - xor is used instead.
9932 (define_insn "*one_cmplsi2_2_zext"
9933 [(set (reg FLAGS_REG)
9934 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9936 (set (match_operand:DI 0 "register_operand" "=r")
9937 (zero_extend:DI (not:SI (match_dup 1))))]
9938 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9939 && ix86_unary_operator_ok (NOT, SImode, operands)"
9941 [(set_attr "type" "alu1")
9942 (set_attr "mode" "SI")])
9945 [(set (match_operand 0 "flags_reg_operand" "")
9946 (match_operator 2 "compare_operator"
9947 [(not:SI (match_operand:SI 3 "register_operand" ""))
9949 (set (match_operand:DI 1 "register_operand" "")
9950 (zero_extend:DI (not:SI (match_dup 3))))]
9951 "ix86_match_ccmode (insn, CCNOmode)"
9952 [(parallel [(set (match_dup 0)
9953 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9956 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9959 (define_expand "one_cmplhi2"
9960 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9961 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9962 "TARGET_HIMODE_MATH"
9963 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
9965 (define_insn "*one_cmplhi2_1"
9966 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9967 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
9968 "ix86_unary_operator_ok (NOT, HImode, operands)"
9970 [(set_attr "type" "negnot")
9971 (set_attr "mode" "HI")])
9973 (define_insn "*one_cmplhi2_2"
9974 [(set (reg FLAGS_REG)
9975 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9977 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9978 (not:HI (match_dup 1)))]
9979 "ix86_match_ccmode (insn, CCNOmode)
9980 && ix86_unary_operator_ok (NEG, HImode, operands)"
9982 [(set_attr "type" "alu1")
9983 (set_attr "mode" "HI")])
9986 [(set (match_operand 0 "flags_reg_operand" "")
9987 (match_operator 2 "compare_operator"
9988 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
9990 (set (match_operand:HI 1 "nonimmediate_operand" "")
9991 (not:HI (match_dup 3)))]
9992 "ix86_match_ccmode (insn, CCNOmode)"
9993 [(parallel [(set (match_dup 0)
9994 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
9997 (xor:HI (match_dup 3) (const_int -1)))])]
10000 ;; %%% Potential partial reg stall on alternative 1. What to do?
10001 (define_expand "one_cmplqi2"
10002 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10003 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10004 "TARGET_QIMODE_MATH"
10005 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10007 (define_insn "*one_cmplqi2_1"
10008 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10009 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10010 "ix86_unary_operator_ok (NOT, QImode, operands)"
10014 [(set_attr "type" "negnot")
10015 (set_attr "mode" "QI,SI")])
10017 (define_insn "*one_cmplqi2_2"
10018 [(set (reg FLAGS_REG)
10019 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10021 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10022 (not:QI (match_dup 1)))]
10023 "ix86_match_ccmode (insn, CCNOmode)
10024 && ix86_unary_operator_ok (NOT, QImode, operands)"
10026 [(set_attr "type" "alu1")
10027 (set_attr "mode" "QI")])
10030 [(set (match_operand 0 "flags_reg_operand" "")
10031 (match_operator 2 "compare_operator"
10032 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10034 (set (match_operand:QI 1 "nonimmediate_operand" "")
10035 (not:QI (match_dup 3)))]
10036 "ix86_match_ccmode (insn, CCNOmode)"
10037 [(parallel [(set (match_dup 0)
10038 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10041 (xor:QI (match_dup 3) (const_int -1)))])]
10044 ;; Arithmetic shift instructions
10046 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10047 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10048 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10049 ;; from the assembler input.
10051 ;; This instruction shifts the target reg/mem as usual, but instead of
10052 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10053 ;; is a left shift double, bits are taken from the high order bits of
10054 ;; reg, else if the insn is a shift right double, bits are taken from the
10055 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10056 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10058 ;; Since sh[lr]d does not change the `reg' operand, that is done
10059 ;; separately, making all shifts emit pairs of shift double and normal
10060 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10061 ;; support a 63 bit shift, each shift where the count is in a reg expands
10062 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10064 ;; If the shift count is a constant, we need never emit more than one
10065 ;; shift pair, instead using moves and sign extension for counts greater
10068 (define_expand "ashldi3"
10069 [(set (match_operand:DI 0 "shiftdi_operand" "")
10070 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10071 (match_operand:QI 2 "nonmemory_operand" "")))]
10073 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10075 (define_insn "*ashldi3_1_rex64"
10076 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10077 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10078 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10079 (clobber (reg:CC FLAGS_REG))]
10080 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10082 switch (get_attr_type (insn))
10085 if (operands[2] != const1_rtx)
10087 if (!rtx_equal_p (operands[0], operands[1]))
10089 return "add{q}\t{%0, %0|%0, %0}";
10092 if (GET_CODE (operands[2]) != CONST_INT
10093 || (unsigned HOST_WIDE_INT) INTVAL (operands[2]) > 3)
10095 operands[1] = gen_rtx_MULT (DImode, operands[1],
10096 GEN_INT (1 << INTVAL (operands[2])));
10097 return "lea{q}\t{%a1, %0|%0, %a1}";
10100 if (REG_P (operands[2]))
10101 return "sal{q}\t{%b2, %0|%0, %b2}";
10102 else if (operands[2] == const1_rtx
10103 && (TARGET_SHIFT1 || optimize_size))
10104 return "sal{q}\t%0";
10106 return "sal{q}\t{%2, %0|%0, %2}";
10109 [(set (attr "type")
10110 (cond [(eq_attr "alternative" "1")
10111 (const_string "lea")
10112 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10114 (match_operand 0 "register_operand" ""))
10115 (match_operand 2 "const1_operand" ""))
10116 (const_string "alu")
10118 (const_string "ishift")))
10119 (set_attr "mode" "DI")])
10121 ;; Convert lea to the lea pattern to avoid flags dependency.
10123 [(set (match_operand:DI 0 "register_operand" "")
10124 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10125 (match_operand:QI 2 "immediate_operand" "")))
10126 (clobber (reg:CC FLAGS_REG))]
10127 "TARGET_64BIT && reload_completed
10128 && true_regnum (operands[0]) != true_regnum (operands[1])"
10129 [(set (match_dup 0)
10130 (mult:DI (match_dup 1)
10132 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10134 ;; This pattern can't accept a variable shift count, since shifts by
10135 ;; zero don't affect the flags. We assume that shifts by constant
10136 ;; zero are optimized away.
10137 (define_insn "*ashldi3_cmp_rex64"
10138 [(set (reg FLAGS_REG)
10140 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10141 (match_operand:QI 2 "immediate_operand" "e"))
10143 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10144 (ashift:DI (match_dup 1) (match_dup 2)))]
10145 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10146 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10148 switch (get_attr_type (insn))
10151 if (operands[2] != const1_rtx)
10153 return "add{q}\t{%0, %0|%0, %0}";
10156 if (REG_P (operands[2]))
10157 return "sal{q}\t{%b2, %0|%0, %b2}";
10158 else if (operands[2] == const1_rtx
10159 && (TARGET_SHIFT1 || optimize_size))
10160 return "sal{q}\t%0";
10162 return "sal{q}\t{%2, %0|%0, %2}";
10165 [(set (attr "type")
10166 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10168 (match_operand 0 "register_operand" ""))
10169 (match_operand 2 "const1_operand" ""))
10170 (const_string "alu")
10172 (const_string "ishift")))
10173 (set_attr "mode" "DI")])
10175 (define_insn "*ashldi3_1"
10176 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10177 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10178 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10179 (clobber (reg:CC FLAGS_REG))]
10182 [(set_attr "type" "multi")])
10184 ;; By default we don't ask for a scratch register, because when DImode
10185 ;; values are manipulated, registers are already at a premium. But if
10186 ;; we have one handy, we won't turn it away.
10188 [(match_scratch:SI 3 "r")
10189 (parallel [(set (match_operand:DI 0 "register_operand" "")
10190 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10191 (match_operand:QI 2 "nonmemory_operand" "")))
10192 (clobber (reg:CC FLAGS_REG))])
10194 "!TARGET_64BIT && TARGET_CMOVE"
10196 "ix86_split_ashldi (operands, operands[3]); DONE;")
10199 [(set (match_operand:DI 0 "register_operand" "")
10200 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10201 (match_operand:QI 2 "nonmemory_operand" "")))
10202 (clobber (reg:CC FLAGS_REG))]
10203 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10205 "ix86_split_ashldi (operands, NULL_RTX); DONE;")
10207 (define_insn "x86_shld_1"
10208 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10209 (ior:SI (ashift:SI (match_dup 0)
10210 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10211 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10212 (minus:QI (const_int 32) (match_dup 2)))))
10213 (clobber (reg:CC FLAGS_REG))]
10216 shld{l}\t{%2, %1, %0|%0, %1, %2}
10217 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10218 [(set_attr "type" "ishift")
10219 (set_attr "prefix_0f" "1")
10220 (set_attr "mode" "SI")
10221 (set_attr "pent_pair" "np")
10222 (set_attr "athlon_decode" "vector")])
10224 (define_expand "x86_shift_adj_1"
10225 [(set (reg:CCZ FLAGS_REG)
10226 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10229 (set (match_operand:SI 0 "register_operand" "")
10230 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10231 (match_operand:SI 1 "register_operand" "")
10234 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10235 (match_operand:SI 3 "register_operand" "r")
10240 (define_expand "x86_shift_adj_2"
10241 [(use (match_operand:SI 0 "register_operand" ""))
10242 (use (match_operand:SI 1 "register_operand" ""))
10243 (use (match_operand:QI 2 "register_operand" ""))]
10246 rtx label = gen_label_rtx ();
10249 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10251 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10252 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10253 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10254 gen_rtx_LABEL_REF (VOIDmode, label),
10256 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10257 JUMP_LABEL (tmp) = label;
10259 emit_move_insn (operands[0], operands[1]);
10260 ix86_expand_clear (operands[1]);
10262 emit_label (label);
10263 LABEL_NUSES (label) = 1;
10268 (define_expand "ashlsi3"
10269 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10270 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10271 (match_operand:QI 2 "nonmemory_operand" "")))
10272 (clobber (reg:CC FLAGS_REG))]
10274 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10276 (define_insn "*ashlsi3_1"
10277 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10278 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10279 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10280 (clobber (reg:CC FLAGS_REG))]
10281 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10283 switch (get_attr_type (insn))
10286 if (operands[2] != const1_rtx)
10288 if (!rtx_equal_p (operands[0], operands[1]))
10290 return "add{l}\t{%0, %0|%0, %0}";
10296 if (REG_P (operands[2]))
10297 return "sal{l}\t{%b2, %0|%0, %b2}";
10298 else if (operands[2] == const1_rtx
10299 && (TARGET_SHIFT1 || optimize_size))
10300 return "sal{l}\t%0";
10302 return "sal{l}\t{%2, %0|%0, %2}";
10305 [(set (attr "type")
10306 (cond [(eq_attr "alternative" "1")
10307 (const_string "lea")
10308 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10310 (match_operand 0 "register_operand" ""))
10311 (match_operand 2 "const1_operand" ""))
10312 (const_string "alu")
10314 (const_string "ishift")))
10315 (set_attr "mode" "SI")])
10317 ;; Convert lea to the lea pattern to avoid flags dependency.
10319 [(set (match_operand 0 "register_operand" "")
10320 (ashift (match_operand 1 "index_register_operand" "")
10321 (match_operand:QI 2 "const_int_operand" "")))
10322 (clobber (reg:CC FLAGS_REG))]
10324 && true_regnum (operands[0]) != true_regnum (operands[1])
10325 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10329 enum machine_mode mode = GET_MODE (operands[0]);
10331 if (GET_MODE_SIZE (mode) < 4)
10332 operands[0] = gen_lowpart (SImode, operands[0]);
10334 operands[1] = gen_lowpart (Pmode, operands[1]);
10335 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10337 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10338 if (Pmode != SImode)
10339 pat = gen_rtx_SUBREG (SImode, pat, 0);
10340 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10344 ;; Rare case of shifting RSP is handled by generating move and shift
10346 [(set (match_operand 0 "register_operand" "")
10347 (ashift (match_operand 1 "register_operand" "")
10348 (match_operand:QI 2 "const_int_operand" "")))
10349 (clobber (reg:CC FLAGS_REG))]
10351 && true_regnum (operands[0]) != true_regnum (operands[1])"
10355 emit_move_insn (operands[1], operands[0]);
10356 pat = gen_rtx_SET (VOIDmode, operands[0],
10357 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10358 operands[0], operands[2]));
10359 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10360 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10364 (define_insn "*ashlsi3_1_zext"
10365 [(set (match_operand:DI 0 "register_operand" "=r,r")
10366 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10367 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10368 (clobber (reg:CC FLAGS_REG))]
10369 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10371 switch (get_attr_type (insn))
10374 if (operands[2] != const1_rtx)
10376 return "add{l}\t{%k0, %k0|%k0, %k0}";
10382 if (REG_P (operands[2]))
10383 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10384 else if (operands[2] == const1_rtx
10385 && (TARGET_SHIFT1 || optimize_size))
10386 return "sal{l}\t%k0";
10388 return "sal{l}\t{%2, %k0|%k0, %2}";
10391 [(set (attr "type")
10392 (cond [(eq_attr "alternative" "1")
10393 (const_string "lea")
10394 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10396 (match_operand 2 "const1_operand" ""))
10397 (const_string "alu")
10399 (const_string "ishift")))
10400 (set_attr "mode" "SI")])
10402 ;; Convert lea to the lea pattern to avoid flags dependency.
10404 [(set (match_operand:DI 0 "register_operand" "")
10405 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10406 (match_operand:QI 2 "const_int_operand" ""))))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "TARGET_64BIT && reload_completed
10409 && true_regnum (operands[0]) != true_regnum (operands[1])"
10410 [(set (match_dup 0) (zero_extend:DI
10411 (subreg:SI (mult:SI (match_dup 1)
10412 (match_dup 2)) 0)))]
10414 operands[1] = gen_lowpart (Pmode, operands[1]);
10415 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10418 ;; This pattern can't accept a variable shift count, since shifts by
10419 ;; zero don't affect the flags. We assume that shifts by constant
10420 ;; zero are optimized away.
10421 (define_insn "*ashlsi3_cmp"
10422 [(set (reg FLAGS_REG)
10424 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10425 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10427 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10428 (ashift:SI (match_dup 1) (match_dup 2)))]
10429 "ix86_match_ccmode (insn, CCGOCmode)
10430 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10432 switch (get_attr_type (insn))
10435 if (operands[2] != const1_rtx)
10437 return "add{l}\t{%0, %0|%0, %0}";
10440 if (REG_P (operands[2]))
10441 return "sal{l}\t{%b2, %0|%0, %b2}";
10442 else if (operands[2] == const1_rtx
10443 && (TARGET_SHIFT1 || optimize_size))
10444 return "sal{l}\t%0";
10446 return "sal{l}\t{%2, %0|%0, %2}";
10449 [(set (attr "type")
10450 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10452 (match_operand 0 "register_operand" ""))
10453 (match_operand 2 "const1_operand" ""))
10454 (const_string "alu")
10456 (const_string "ishift")))
10457 (set_attr "mode" "SI")])
10459 (define_insn "*ashlsi3_cmp_zext"
10460 [(set (reg FLAGS_REG)
10462 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10463 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10465 (set (match_operand:DI 0 "register_operand" "=r")
10466 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10467 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10468 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10470 switch (get_attr_type (insn))
10473 if (operands[2] != const1_rtx)
10475 return "add{l}\t{%k0, %k0|%k0, %k0}";
10478 if (REG_P (operands[2]))
10479 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10480 else if (operands[2] == const1_rtx
10481 && (TARGET_SHIFT1 || optimize_size))
10482 return "sal{l}\t%k0";
10484 return "sal{l}\t{%2, %k0|%k0, %2}";
10487 [(set (attr "type")
10488 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10490 (match_operand 2 "const1_operand" ""))
10491 (const_string "alu")
10493 (const_string "ishift")))
10494 (set_attr "mode" "SI")])
10496 (define_expand "ashlhi3"
10497 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10498 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10499 (match_operand:QI 2 "nonmemory_operand" "")))
10500 (clobber (reg:CC FLAGS_REG))]
10501 "TARGET_HIMODE_MATH"
10502 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10504 (define_insn "*ashlhi3_1_lea"
10505 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10506 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10507 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10508 (clobber (reg:CC FLAGS_REG))]
10509 "!TARGET_PARTIAL_REG_STALL
10510 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10512 switch (get_attr_type (insn))
10517 if (operands[2] != const1_rtx)
10519 return "add{w}\t{%0, %0|%0, %0}";
10522 if (REG_P (operands[2]))
10523 return "sal{w}\t{%b2, %0|%0, %b2}";
10524 else if (operands[2] == const1_rtx
10525 && (TARGET_SHIFT1 || optimize_size))
10526 return "sal{w}\t%0";
10528 return "sal{w}\t{%2, %0|%0, %2}";
10531 [(set (attr "type")
10532 (cond [(eq_attr "alternative" "1")
10533 (const_string "lea")
10534 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10536 (match_operand 0 "register_operand" ""))
10537 (match_operand 2 "const1_operand" ""))
10538 (const_string "alu")
10540 (const_string "ishift")))
10541 (set_attr "mode" "HI,SI")])
10543 (define_insn "*ashlhi3_1"
10544 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10545 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10546 (match_operand:QI 2 "nonmemory_operand" "cI")))
10547 (clobber (reg:CC FLAGS_REG))]
10548 "TARGET_PARTIAL_REG_STALL
10549 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10551 switch (get_attr_type (insn))
10554 if (operands[2] != const1_rtx)
10556 return "add{w}\t{%0, %0|%0, %0}";
10559 if (REG_P (operands[2]))
10560 return "sal{w}\t{%b2, %0|%0, %b2}";
10561 else if (operands[2] == const1_rtx
10562 && (TARGET_SHIFT1 || optimize_size))
10563 return "sal{w}\t%0";
10565 return "sal{w}\t{%2, %0|%0, %2}";
10568 [(set (attr "type")
10569 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10571 (match_operand 0 "register_operand" ""))
10572 (match_operand 2 "const1_operand" ""))
10573 (const_string "alu")
10575 (const_string "ishift")))
10576 (set_attr "mode" "HI")])
10578 ;; This pattern can't accept a variable shift count, since shifts by
10579 ;; zero don't affect the flags. We assume that shifts by constant
10580 ;; zero are optimized away.
10581 (define_insn "*ashlhi3_cmp"
10582 [(set (reg FLAGS_REG)
10584 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10585 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10587 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10588 (ashift:HI (match_dup 1) (match_dup 2)))]
10589 "ix86_match_ccmode (insn, CCGOCmode)
10590 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10592 switch (get_attr_type (insn))
10595 if (operands[2] != const1_rtx)
10597 return "add{w}\t{%0, %0|%0, %0}";
10600 if (REG_P (operands[2]))
10601 return "sal{w}\t{%b2, %0|%0, %b2}";
10602 else if (operands[2] == const1_rtx
10603 && (TARGET_SHIFT1 || optimize_size))
10604 return "sal{w}\t%0";
10606 return "sal{w}\t{%2, %0|%0, %2}";
10609 [(set (attr "type")
10610 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10612 (match_operand 0 "register_operand" ""))
10613 (match_operand 2 "const1_operand" ""))
10614 (const_string "alu")
10616 (const_string "ishift")))
10617 (set_attr "mode" "HI")])
10619 (define_expand "ashlqi3"
10620 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10621 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10622 (match_operand:QI 2 "nonmemory_operand" "")))
10623 (clobber (reg:CC FLAGS_REG))]
10624 "TARGET_QIMODE_MATH"
10625 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10627 ;; %%% Potential partial reg stall on alternative 2. What to do?
10629 (define_insn "*ashlqi3_1_lea"
10630 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10631 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10632 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10633 (clobber (reg:CC FLAGS_REG))]
10634 "!TARGET_PARTIAL_REG_STALL
10635 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10637 switch (get_attr_type (insn))
10642 if (operands[2] != const1_rtx)
10644 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10645 return "add{l}\t{%k0, %k0|%k0, %k0}";
10647 return "add{b}\t{%0, %0|%0, %0}";
10650 if (REG_P (operands[2]))
10652 if (get_attr_mode (insn) == MODE_SI)
10653 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10655 return "sal{b}\t{%b2, %0|%0, %b2}";
10657 else if (operands[2] == const1_rtx
10658 && (TARGET_SHIFT1 || optimize_size))
10660 if (get_attr_mode (insn) == MODE_SI)
10661 return "sal{l}\t%0";
10663 return "sal{b}\t%0";
10667 if (get_attr_mode (insn) == MODE_SI)
10668 return "sal{l}\t{%2, %k0|%k0, %2}";
10670 return "sal{b}\t{%2, %0|%0, %2}";
10674 [(set (attr "type")
10675 (cond [(eq_attr "alternative" "2")
10676 (const_string "lea")
10677 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10679 (match_operand 0 "register_operand" ""))
10680 (match_operand 2 "const1_operand" ""))
10681 (const_string "alu")
10683 (const_string "ishift")))
10684 (set_attr "mode" "QI,SI,SI")])
10686 (define_insn "*ashlqi3_1"
10687 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10688 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10689 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10690 (clobber (reg:CC FLAGS_REG))]
10691 "TARGET_PARTIAL_REG_STALL
10692 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10694 switch (get_attr_type (insn))
10697 if (operands[2] != const1_rtx)
10699 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10700 return "add{l}\t{%k0, %k0|%k0, %k0}";
10702 return "add{b}\t{%0, %0|%0, %0}";
10705 if (REG_P (operands[2]))
10707 if (get_attr_mode (insn) == MODE_SI)
10708 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10710 return "sal{b}\t{%b2, %0|%0, %b2}";
10712 else if (operands[2] == const1_rtx
10713 && (TARGET_SHIFT1 || optimize_size))
10715 if (get_attr_mode (insn) == MODE_SI)
10716 return "sal{l}\t%0";
10718 return "sal{b}\t%0";
10722 if (get_attr_mode (insn) == MODE_SI)
10723 return "sal{l}\t{%2, %k0|%k0, %2}";
10725 return "sal{b}\t{%2, %0|%0, %2}";
10729 [(set (attr "type")
10730 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10732 (match_operand 0 "register_operand" ""))
10733 (match_operand 2 "const1_operand" ""))
10734 (const_string "alu")
10736 (const_string "ishift")))
10737 (set_attr "mode" "QI,SI")])
10739 ;; This pattern can't accept a variable shift count, since shifts by
10740 ;; zero don't affect the flags. We assume that shifts by constant
10741 ;; zero are optimized away.
10742 (define_insn "*ashlqi3_cmp"
10743 [(set (reg FLAGS_REG)
10745 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10746 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10748 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10749 (ashift:QI (match_dup 1) (match_dup 2)))]
10750 "ix86_match_ccmode (insn, CCGOCmode)
10751 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10753 switch (get_attr_type (insn))
10756 if (operands[2] != const1_rtx)
10758 return "add{b}\t{%0, %0|%0, %0}";
10761 if (REG_P (operands[2]))
10762 return "sal{b}\t{%b2, %0|%0, %b2}";
10763 else if (operands[2] == const1_rtx
10764 && (TARGET_SHIFT1 || optimize_size))
10765 return "sal{b}\t%0";
10767 return "sal{b}\t{%2, %0|%0, %2}";
10770 [(set (attr "type")
10771 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10773 (match_operand 0 "register_operand" ""))
10774 (match_operand 2 "const1_operand" ""))
10775 (const_string "alu")
10777 (const_string "ishift")))
10778 (set_attr "mode" "QI")])
10780 ;; See comment above `ashldi3' about how this works.
10782 (define_expand "ashrdi3"
10783 [(set (match_operand:DI 0 "shiftdi_operand" "")
10784 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10785 (match_operand:QI 2 "nonmemory_operand" "")))]
10787 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10789 (define_insn "*ashrdi3_63_rex64"
10790 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10791 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10792 (match_operand:DI 2 "const_int_operand" "i,i")))
10793 (clobber (reg:CC FLAGS_REG))]
10794 "TARGET_64BIT && INTVAL (operands[2]) == 63
10795 && (TARGET_USE_CLTD || optimize_size)
10796 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10799 sar{q}\t{%2, %0|%0, %2}"
10800 [(set_attr "type" "imovx,ishift")
10801 (set_attr "prefix_0f" "0,*")
10802 (set_attr "length_immediate" "0,*")
10803 (set_attr "modrm" "0,1")
10804 (set_attr "mode" "DI")])
10806 (define_insn "*ashrdi3_1_one_bit_rex64"
10807 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10808 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10809 (match_operand:QI 2 "const1_operand" "")))
10810 (clobber (reg:CC FLAGS_REG))]
10811 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
10812 && (TARGET_SHIFT1 || optimize_size)"
10814 [(set_attr "type" "ishift")
10815 (set (attr "length")
10816 (if_then_else (match_operand:DI 0 "register_operand" "")
10818 (const_string "*")))])
10820 (define_insn "*ashrdi3_1_rex64"
10821 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10822 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10823 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10824 (clobber (reg:CC FLAGS_REG))]
10825 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10827 sar{q}\t{%2, %0|%0, %2}
10828 sar{q}\t{%b2, %0|%0, %b2}"
10829 [(set_attr "type" "ishift")
10830 (set_attr "mode" "DI")])
10832 ;; This pattern can't accept a variable shift count, since shifts by
10833 ;; zero don't affect the flags. We assume that shifts by constant
10834 ;; zero are optimized away.
10835 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10836 [(set (reg FLAGS_REG)
10838 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10839 (match_operand:QI 2 "const1_operand" ""))
10841 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10842 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10843 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10844 && (TARGET_SHIFT1 || optimize_size)
10845 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10847 [(set_attr "type" "ishift")
10848 (set (attr "length")
10849 (if_then_else (match_operand:DI 0 "register_operand" "")
10851 (const_string "*")))])
10853 ;; This pattern can't accept a variable shift count, since shifts by
10854 ;; zero don't affect the flags. We assume that shifts by constant
10855 ;; zero are optimized away.
10856 (define_insn "*ashrdi3_cmp_rex64"
10857 [(set (reg FLAGS_REG)
10859 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10860 (match_operand:QI 2 "const_int_operand" "n"))
10862 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10863 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10864 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10865 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10866 "sar{q}\t{%2, %0|%0, %2}"
10867 [(set_attr "type" "ishift")
10868 (set_attr "mode" "DI")])
10870 (define_insn "*ashrdi3_1"
10871 [(set (match_operand:DI 0 "register_operand" "=r")
10872 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10873 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10874 (clobber (reg:CC FLAGS_REG))]
10877 [(set_attr "type" "multi")])
10879 ;; By default we don't ask for a scratch register, because when DImode
10880 ;; values are manipulated, registers are already at a premium. But if
10881 ;; we have one handy, we won't turn it away.
10883 [(match_scratch:SI 3 "r")
10884 (parallel [(set (match_operand:DI 0 "register_operand" "")
10885 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10886 (match_operand:QI 2 "nonmemory_operand" "")))
10887 (clobber (reg:CC FLAGS_REG))])
10889 "!TARGET_64BIT && TARGET_CMOVE"
10891 "ix86_split_ashrdi (operands, operands[3]); DONE;")
10894 [(set (match_operand:DI 0 "register_operand" "")
10895 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10896 (match_operand:QI 2 "nonmemory_operand" "")))
10897 (clobber (reg:CC FLAGS_REG))]
10898 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
10900 "ix86_split_ashrdi (operands, NULL_RTX); DONE;")
10902 (define_insn "x86_shrd_1"
10903 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10904 (ior:SI (ashiftrt:SI (match_dup 0)
10905 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10906 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
10907 (minus:QI (const_int 32) (match_dup 2)))))
10908 (clobber (reg:CC FLAGS_REG))]
10911 shrd{l}\t{%2, %1, %0|%0, %1, %2}
10912 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10913 [(set_attr "type" "ishift")
10914 (set_attr "prefix_0f" "1")
10915 (set_attr "pent_pair" "np")
10916 (set_attr "mode" "SI")])
10918 (define_expand "x86_shift_adj_3"
10919 [(use (match_operand:SI 0 "register_operand" ""))
10920 (use (match_operand:SI 1 "register_operand" ""))
10921 (use (match_operand:QI 2 "register_operand" ""))]
10924 rtx label = gen_label_rtx ();
10927 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10929 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10930 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10931 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10932 gen_rtx_LABEL_REF (VOIDmode, label),
10934 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10935 JUMP_LABEL (tmp) = label;
10937 emit_move_insn (operands[0], operands[1]);
10938 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10940 emit_label (label);
10941 LABEL_NUSES (label) = 1;
10946 (define_insn "ashrsi3_31"
10947 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10948 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10949 (match_operand:SI 2 "const_int_operand" "i,i")))
10950 (clobber (reg:CC FLAGS_REG))]
10951 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
10952 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10955 sar{l}\t{%2, %0|%0, %2}"
10956 [(set_attr "type" "imovx,ishift")
10957 (set_attr "prefix_0f" "0,*")
10958 (set_attr "length_immediate" "0,*")
10959 (set_attr "modrm" "0,1")
10960 (set_attr "mode" "SI")])
10962 (define_insn "*ashrsi3_31_zext"
10963 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10964 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10965 (match_operand:SI 2 "const_int_operand" "i,i"))))
10966 (clobber (reg:CC FLAGS_REG))]
10967 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
10968 && INTVAL (operands[2]) == 31
10969 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10972 sar{l}\t{%2, %k0|%k0, %2}"
10973 [(set_attr "type" "imovx,ishift")
10974 (set_attr "prefix_0f" "0,*")
10975 (set_attr "length_immediate" "0,*")
10976 (set_attr "modrm" "0,1")
10977 (set_attr "mode" "SI")])
10979 (define_expand "ashrsi3"
10980 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10981 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10982 (match_operand:QI 2 "nonmemory_operand" "")))
10983 (clobber (reg:CC FLAGS_REG))]
10985 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10987 (define_insn "*ashrsi3_1_one_bit"
10988 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10989 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10990 (match_operand:QI 2 "const1_operand" "")))
10991 (clobber (reg:CC FLAGS_REG))]
10992 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
10993 && (TARGET_SHIFT1 || optimize_size)"
10995 [(set_attr "type" "ishift")
10996 (set (attr "length")
10997 (if_then_else (match_operand:SI 0 "register_operand" "")
10999 (const_string "*")))])
11001 (define_insn "*ashrsi3_1_one_bit_zext"
11002 [(set (match_operand:DI 0 "register_operand" "=r")
11003 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11004 (match_operand:QI 2 "const1_operand" ""))))
11005 (clobber (reg:CC FLAGS_REG))]
11006 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11007 && (TARGET_SHIFT1 || optimize_size)"
11009 [(set_attr "type" "ishift")
11010 (set_attr "length" "2")])
11012 (define_insn "*ashrsi3_1"
11013 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11014 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11015 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11016 (clobber (reg:CC FLAGS_REG))]
11017 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11019 sar{l}\t{%2, %0|%0, %2}
11020 sar{l}\t{%b2, %0|%0, %b2}"
11021 [(set_attr "type" "ishift")
11022 (set_attr "mode" "SI")])
11024 (define_insn "*ashrsi3_1_zext"
11025 [(set (match_operand:DI 0 "register_operand" "=r,r")
11026 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11027 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11028 (clobber (reg:CC FLAGS_REG))]
11029 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11031 sar{l}\t{%2, %k0|%k0, %2}
11032 sar{l}\t{%b2, %k0|%k0, %b2}"
11033 [(set_attr "type" "ishift")
11034 (set_attr "mode" "SI")])
11036 ;; This pattern can't accept a variable shift count, since shifts by
11037 ;; zero don't affect the flags. We assume that shifts by constant
11038 ;; zero are optimized away.
11039 (define_insn "*ashrsi3_one_bit_cmp"
11040 [(set (reg FLAGS_REG)
11042 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11043 (match_operand:QI 2 "const1_operand" ""))
11045 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11046 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11047 "ix86_match_ccmode (insn, CCGOCmode)
11048 && (TARGET_SHIFT1 || optimize_size)
11049 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11051 [(set_attr "type" "ishift")
11052 (set (attr "length")
11053 (if_then_else (match_operand:SI 0 "register_operand" "")
11055 (const_string "*")))])
11057 (define_insn "*ashrsi3_one_bit_cmp_zext"
11058 [(set (reg FLAGS_REG)
11060 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11061 (match_operand:QI 2 "const1_operand" ""))
11063 (set (match_operand:DI 0 "register_operand" "=r")
11064 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11065 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11066 && (TARGET_SHIFT1 || optimize_size)
11067 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11069 [(set_attr "type" "ishift")
11070 (set_attr "length" "2")])
11072 ;; This pattern can't accept a variable shift count, since shifts by
11073 ;; zero don't affect the flags. We assume that shifts by constant
11074 ;; zero are optimized away.
11075 (define_insn "*ashrsi3_cmp"
11076 [(set (reg FLAGS_REG)
11078 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11079 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11081 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11082 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11083 "ix86_match_ccmode (insn, CCGOCmode)
11084 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11085 "sar{l}\t{%2, %0|%0, %2}"
11086 [(set_attr "type" "ishift")
11087 (set_attr "mode" "SI")])
11089 (define_insn "*ashrsi3_cmp_zext"
11090 [(set (reg FLAGS_REG)
11092 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11093 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11095 (set (match_operand:DI 0 "register_operand" "=r")
11096 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11097 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11098 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11099 "sar{l}\t{%2, %k0|%k0, %2}"
11100 [(set_attr "type" "ishift")
11101 (set_attr "mode" "SI")])
11103 (define_expand "ashrhi3"
11104 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11105 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11106 (match_operand:QI 2 "nonmemory_operand" "")))
11107 (clobber (reg:CC FLAGS_REG))]
11108 "TARGET_HIMODE_MATH"
11109 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11111 (define_insn "*ashrhi3_1_one_bit"
11112 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11113 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11114 (match_operand:QI 2 "const1_operand" "")))
11115 (clobber (reg:CC FLAGS_REG))]
11116 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11117 && (TARGET_SHIFT1 || optimize_size)"
11119 [(set_attr "type" "ishift")
11120 (set (attr "length")
11121 (if_then_else (match_operand 0 "register_operand" "")
11123 (const_string "*")))])
11125 (define_insn "*ashrhi3_1"
11126 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11127 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11128 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11129 (clobber (reg:CC FLAGS_REG))]
11130 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11132 sar{w}\t{%2, %0|%0, %2}
11133 sar{w}\t{%b2, %0|%0, %b2}"
11134 [(set_attr "type" "ishift")
11135 (set_attr "mode" "HI")])
11137 ;; This pattern can't accept a variable shift count, since shifts by
11138 ;; zero don't affect the flags. We assume that shifts by constant
11139 ;; zero are optimized away.
11140 (define_insn "*ashrhi3_one_bit_cmp"
11141 [(set (reg FLAGS_REG)
11143 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11144 (match_operand:QI 2 "const1_operand" ""))
11146 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11147 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11148 "ix86_match_ccmode (insn, CCGOCmode)
11149 && (TARGET_SHIFT1 || optimize_size)
11150 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11152 [(set_attr "type" "ishift")
11153 (set (attr "length")
11154 (if_then_else (match_operand 0 "register_operand" "")
11156 (const_string "*")))])
11158 ;; This pattern can't accept a variable shift count, since shifts by
11159 ;; zero don't affect the flags. We assume that shifts by constant
11160 ;; zero are optimized away.
11161 (define_insn "*ashrhi3_cmp"
11162 [(set (reg FLAGS_REG)
11164 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11165 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11167 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11168 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11169 "ix86_match_ccmode (insn, CCGOCmode)
11170 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11171 "sar{w}\t{%2, %0|%0, %2}"
11172 [(set_attr "type" "ishift")
11173 (set_attr "mode" "HI")])
11175 (define_expand "ashrqi3"
11176 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11177 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11178 (match_operand:QI 2 "nonmemory_operand" "")))
11179 (clobber (reg:CC FLAGS_REG))]
11180 "TARGET_QIMODE_MATH"
11181 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11183 (define_insn "*ashrqi3_1_one_bit"
11184 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11185 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11186 (match_operand:QI 2 "const1_operand" "")))
11187 (clobber (reg:CC FLAGS_REG))]
11188 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11189 && (TARGET_SHIFT1 || optimize_size)"
11191 [(set_attr "type" "ishift")
11192 (set (attr "length")
11193 (if_then_else (match_operand 0 "register_operand" "")
11195 (const_string "*")))])
11197 (define_insn "*ashrqi3_1_one_bit_slp"
11198 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11199 (ashiftrt:QI (match_dup 0)
11200 (match_operand:QI 1 "const1_operand" "")))
11201 (clobber (reg:CC FLAGS_REG))]
11202 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11203 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11204 && (TARGET_SHIFT1 || optimize_size)"
11206 [(set_attr "type" "ishift1")
11207 (set (attr "length")
11208 (if_then_else (match_operand 0 "register_operand" "")
11210 (const_string "*")))])
11212 (define_insn "*ashrqi3_1"
11213 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11214 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11215 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11216 (clobber (reg:CC FLAGS_REG))]
11217 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11219 sar{b}\t{%2, %0|%0, %2}
11220 sar{b}\t{%b2, %0|%0, %b2}"
11221 [(set_attr "type" "ishift")
11222 (set_attr "mode" "QI")])
11224 (define_insn "*ashrqi3_1_slp"
11225 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11226 (ashiftrt:QI (match_dup 0)
11227 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11228 (clobber (reg:CC FLAGS_REG))]
11229 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11230 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11232 sar{b}\t{%1, %0|%0, %1}
11233 sar{b}\t{%b1, %0|%0, %b1}"
11234 [(set_attr "type" "ishift1")
11235 (set_attr "mode" "QI")])
11237 ;; This pattern can't accept a variable shift count, since shifts by
11238 ;; zero don't affect the flags. We assume that shifts by constant
11239 ;; zero are optimized away.
11240 (define_insn "*ashrqi3_one_bit_cmp"
11241 [(set (reg FLAGS_REG)
11243 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11244 (match_operand:QI 2 "const1_operand" "I"))
11246 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11247 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11248 "ix86_match_ccmode (insn, CCGOCmode)
11249 && (TARGET_SHIFT1 || optimize_size)
11250 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11252 [(set_attr "type" "ishift")
11253 (set (attr "length")
11254 (if_then_else (match_operand 0 "register_operand" "")
11256 (const_string "*")))])
11258 ;; This pattern can't accept a variable shift count, since shifts by
11259 ;; zero don't affect the flags. We assume that shifts by constant
11260 ;; zero are optimized away.
11261 (define_insn "*ashrqi3_cmp"
11262 [(set (reg FLAGS_REG)
11264 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11265 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11267 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11268 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11269 "ix86_match_ccmode (insn, CCGOCmode)
11270 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11271 "sar{b}\t{%2, %0|%0, %2}"
11272 [(set_attr "type" "ishift")
11273 (set_attr "mode" "QI")])
11275 ;; Logical shift instructions
11277 ;; See comment above `ashldi3' about how this works.
11279 (define_expand "lshrdi3"
11280 [(set (match_operand:DI 0 "shiftdi_operand" "")
11281 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11282 (match_operand:QI 2 "nonmemory_operand" "")))]
11284 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11286 (define_insn "*lshrdi3_1_one_bit_rex64"
11287 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11288 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11289 (match_operand:QI 2 "const1_operand" "")))
11290 (clobber (reg:CC FLAGS_REG))]
11291 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11292 && (TARGET_SHIFT1 || optimize_size)"
11294 [(set_attr "type" "ishift")
11295 (set (attr "length")
11296 (if_then_else (match_operand:DI 0 "register_operand" "")
11298 (const_string "*")))])
11300 (define_insn "*lshrdi3_1_rex64"
11301 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11302 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11303 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11304 (clobber (reg:CC FLAGS_REG))]
11305 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11307 shr{q}\t{%2, %0|%0, %2}
11308 shr{q}\t{%b2, %0|%0, %b2}"
11309 [(set_attr "type" "ishift")
11310 (set_attr "mode" "DI")])
11312 ;; This pattern can't accept a variable shift count, since shifts by
11313 ;; zero don't affect the flags. We assume that shifts by constant
11314 ;; zero are optimized away.
11315 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11316 [(set (reg FLAGS_REG)
11318 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11319 (match_operand:QI 2 "const1_operand" ""))
11321 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11322 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11323 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11324 && (TARGET_SHIFT1 || optimize_size)
11325 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11327 [(set_attr "type" "ishift")
11328 (set (attr "length")
11329 (if_then_else (match_operand:DI 0 "register_operand" "")
11331 (const_string "*")))])
11333 ;; This pattern can't accept a variable shift count, since shifts by
11334 ;; zero don't affect the flags. We assume that shifts by constant
11335 ;; zero are optimized away.
11336 (define_insn "*lshrdi3_cmp_rex64"
11337 [(set (reg FLAGS_REG)
11339 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11340 (match_operand:QI 2 "const_int_operand" "e"))
11342 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11343 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11344 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11345 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11346 "shr{q}\t{%2, %0|%0, %2}"
11347 [(set_attr "type" "ishift")
11348 (set_attr "mode" "DI")])
11350 (define_insn "*lshrdi3_1"
11351 [(set (match_operand:DI 0 "register_operand" "=r")
11352 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11353 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11354 (clobber (reg:CC FLAGS_REG))]
11357 [(set_attr "type" "multi")])
11359 ;; By default we don't ask for a scratch register, because when DImode
11360 ;; values are manipulated, registers are already at a premium. But if
11361 ;; we have one handy, we won't turn it away.
11363 [(match_scratch:SI 3 "r")
11364 (parallel [(set (match_operand:DI 0 "register_operand" "")
11365 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11366 (match_operand:QI 2 "nonmemory_operand" "")))
11367 (clobber (reg:CC FLAGS_REG))])
11369 "!TARGET_64BIT && TARGET_CMOVE"
11371 "ix86_split_lshrdi (operands, operands[3]); DONE;")
11374 [(set (match_operand:DI 0 "register_operand" "")
11375 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11376 (match_operand:QI 2 "nonmemory_operand" "")))
11377 (clobber (reg:CC FLAGS_REG))]
11378 "!TARGET_64BIT && (flag_peephole2 ? flow2_completed : reload_completed)"
11380 "ix86_split_lshrdi (operands, NULL_RTX); DONE;")
11382 (define_expand "lshrsi3"
11383 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11384 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11385 (match_operand:QI 2 "nonmemory_operand" "")))
11386 (clobber (reg:CC FLAGS_REG))]
11388 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11390 (define_insn "*lshrsi3_1_one_bit"
11391 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11392 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11393 (match_operand:QI 2 "const1_operand" "")))
11394 (clobber (reg:CC FLAGS_REG))]
11395 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11396 && (TARGET_SHIFT1 || optimize_size)"
11398 [(set_attr "type" "ishift")
11399 (set (attr "length")
11400 (if_then_else (match_operand:SI 0 "register_operand" "")
11402 (const_string "*")))])
11404 (define_insn "*lshrsi3_1_one_bit_zext"
11405 [(set (match_operand:DI 0 "register_operand" "=r")
11406 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11407 (match_operand:QI 2 "const1_operand" "")))
11408 (clobber (reg:CC FLAGS_REG))]
11409 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11410 && (TARGET_SHIFT1 || optimize_size)"
11412 [(set_attr "type" "ishift")
11413 (set_attr "length" "2")])
11415 (define_insn "*lshrsi3_1"
11416 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11417 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11418 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11419 (clobber (reg:CC FLAGS_REG))]
11420 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11422 shr{l}\t{%2, %0|%0, %2}
11423 shr{l}\t{%b2, %0|%0, %b2}"
11424 [(set_attr "type" "ishift")
11425 (set_attr "mode" "SI")])
11427 (define_insn "*lshrsi3_1_zext"
11428 [(set (match_operand:DI 0 "register_operand" "=r,r")
11430 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11431 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11432 (clobber (reg:CC FLAGS_REG))]
11433 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11435 shr{l}\t{%2, %k0|%k0, %2}
11436 shr{l}\t{%b2, %k0|%k0, %b2}"
11437 [(set_attr "type" "ishift")
11438 (set_attr "mode" "SI")])
11440 ;; This pattern can't accept a variable shift count, since shifts by
11441 ;; zero don't affect the flags. We assume that shifts by constant
11442 ;; zero are optimized away.
11443 (define_insn "*lshrsi3_one_bit_cmp"
11444 [(set (reg FLAGS_REG)
11446 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11447 (match_operand:QI 2 "const1_operand" ""))
11449 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11450 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11451 "ix86_match_ccmode (insn, CCGOCmode)
11452 && (TARGET_SHIFT1 || optimize_size)
11453 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11455 [(set_attr "type" "ishift")
11456 (set (attr "length")
11457 (if_then_else (match_operand:SI 0 "register_operand" "")
11459 (const_string "*")))])
11461 (define_insn "*lshrsi3_cmp_one_bit_zext"
11462 [(set (reg FLAGS_REG)
11464 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11465 (match_operand:QI 2 "const1_operand" ""))
11467 (set (match_operand:DI 0 "register_operand" "=r")
11468 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11469 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11470 && (TARGET_SHIFT1 || optimize_size)
11471 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11473 [(set_attr "type" "ishift")
11474 (set_attr "length" "2")])
11476 ;; This pattern can't accept a variable shift count, since shifts by
11477 ;; zero don't affect the flags. We assume that shifts by constant
11478 ;; zero are optimized away.
11479 (define_insn "*lshrsi3_cmp"
11480 [(set (reg FLAGS_REG)
11482 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11483 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11485 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11486 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11487 "ix86_match_ccmode (insn, CCGOCmode)
11488 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11489 "shr{l}\t{%2, %0|%0, %2}"
11490 [(set_attr "type" "ishift")
11491 (set_attr "mode" "SI")])
11493 (define_insn "*lshrsi3_cmp_zext"
11494 [(set (reg FLAGS_REG)
11496 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11497 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11499 (set (match_operand:DI 0 "register_operand" "=r")
11500 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11501 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11502 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11503 "shr{l}\t{%2, %k0|%k0, %2}"
11504 [(set_attr "type" "ishift")
11505 (set_attr "mode" "SI")])
11507 (define_expand "lshrhi3"
11508 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11509 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11510 (match_operand:QI 2 "nonmemory_operand" "")))
11511 (clobber (reg:CC FLAGS_REG))]
11512 "TARGET_HIMODE_MATH"
11513 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11515 (define_insn "*lshrhi3_1_one_bit"
11516 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11517 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11518 (match_operand:QI 2 "const1_operand" "")))
11519 (clobber (reg:CC FLAGS_REG))]
11520 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11521 && (TARGET_SHIFT1 || optimize_size)"
11523 [(set_attr "type" "ishift")
11524 (set (attr "length")
11525 (if_then_else (match_operand 0 "register_operand" "")
11527 (const_string "*")))])
11529 (define_insn "*lshrhi3_1"
11530 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11531 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11532 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11533 (clobber (reg:CC FLAGS_REG))]
11534 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11536 shr{w}\t{%2, %0|%0, %2}
11537 shr{w}\t{%b2, %0|%0, %b2}"
11538 [(set_attr "type" "ishift")
11539 (set_attr "mode" "HI")])
11541 ;; This pattern can't accept a variable shift count, since shifts by
11542 ;; zero don't affect the flags. We assume that shifts by constant
11543 ;; zero are optimized away.
11544 (define_insn "*lshrhi3_one_bit_cmp"
11545 [(set (reg FLAGS_REG)
11547 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11548 (match_operand:QI 2 "const1_operand" ""))
11550 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11551 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11552 "ix86_match_ccmode (insn, CCGOCmode)
11553 && (TARGET_SHIFT1 || optimize_size)
11554 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11556 [(set_attr "type" "ishift")
11557 (set (attr "length")
11558 (if_then_else (match_operand:SI 0 "register_operand" "")
11560 (const_string "*")))])
11562 ;; This pattern can't accept a variable shift count, since shifts by
11563 ;; zero don't affect the flags. We assume that shifts by constant
11564 ;; zero are optimized away.
11565 (define_insn "*lshrhi3_cmp"
11566 [(set (reg FLAGS_REG)
11568 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11569 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11571 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11572 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11573 "ix86_match_ccmode (insn, CCGOCmode)
11574 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11575 "shr{w}\t{%2, %0|%0, %2}"
11576 [(set_attr "type" "ishift")
11577 (set_attr "mode" "HI")])
11579 (define_expand "lshrqi3"
11580 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11581 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11582 (match_operand:QI 2 "nonmemory_operand" "")))
11583 (clobber (reg:CC FLAGS_REG))]
11584 "TARGET_QIMODE_MATH"
11585 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11587 (define_insn "*lshrqi3_1_one_bit"
11588 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11589 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11590 (match_operand:QI 2 "const1_operand" "")))
11591 (clobber (reg:CC FLAGS_REG))]
11592 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
11593 && (TARGET_SHIFT1 || optimize_size)"
11595 [(set_attr "type" "ishift")
11596 (set (attr "length")
11597 (if_then_else (match_operand 0 "register_operand" "")
11599 (const_string "*")))])
11601 (define_insn "*lshrqi3_1_one_bit_slp"
11602 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11603 (lshiftrt:QI (match_dup 0)
11604 (match_operand:QI 1 "const1_operand" "")))
11605 (clobber (reg:CC FLAGS_REG))]
11606 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11607 && (TARGET_SHIFT1 || optimize_size)"
11609 [(set_attr "type" "ishift1")
11610 (set (attr "length")
11611 (if_then_else (match_operand 0 "register_operand" "")
11613 (const_string "*")))])
11615 (define_insn "*lshrqi3_1"
11616 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11617 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11618 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11619 (clobber (reg:CC FLAGS_REG))]
11620 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11622 shr{b}\t{%2, %0|%0, %2}
11623 shr{b}\t{%b2, %0|%0, %b2}"
11624 [(set_attr "type" "ishift")
11625 (set_attr "mode" "QI")])
11627 (define_insn "*lshrqi3_1_slp"
11628 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11629 (lshiftrt:QI (match_dup 0)
11630 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11631 (clobber (reg:CC FLAGS_REG))]
11632 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11633 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11635 shr{b}\t{%1, %0|%0, %1}
11636 shr{b}\t{%b1, %0|%0, %b1}"
11637 [(set_attr "type" "ishift1")
11638 (set_attr "mode" "QI")])
11640 ;; This pattern can't accept a variable shift count, since shifts by
11641 ;; zero don't affect the flags. We assume that shifts by constant
11642 ;; zero are optimized away.
11643 (define_insn "*lshrqi2_one_bit_cmp"
11644 [(set (reg FLAGS_REG)
11646 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11647 (match_operand:QI 2 "const1_operand" ""))
11649 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11650 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11651 "ix86_match_ccmode (insn, CCGOCmode)
11652 && (TARGET_SHIFT1 || optimize_size)
11653 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11655 [(set_attr "type" "ishift")
11656 (set (attr "length")
11657 (if_then_else (match_operand:SI 0 "register_operand" "")
11659 (const_string "*")))])
11661 ;; This pattern can't accept a variable shift count, since shifts by
11662 ;; zero don't affect the flags. We assume that shifts by constant
11663 ;; zero are optimized away.
11664 (define_insn "*lshrqi2_cmp"
11665 [(set (reg FLAGS_REG)
11667 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11668 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11670 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11671 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11672 "ix86_match_ccmode (insn, CCGOCmode)
11673 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11674 "shr{b}\t{%2, %0|%0, %2}"
11675 [(set_attr "type" "ishift")
11676 (set_attr "mode" "QI")])
11678 ;; Rotate instructions
11680 (define_expand "rotldi3"
11681 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11682 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "")
11683 (match_operand:QI 2 "nonmemory_operand" "")))
11684 (clobber (reg:CC FLAGS_REG))]
11686 "ix86_expand_binary_operator (ROTATE, DImode, operands); DONE;")
11688 (define_insn "*rotlsi3_1_one_bit_rex64"
11689 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11690 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11691 (match_operand:QI 2 "const1_operand" "")))
11692 (clobber (reg:CC FLAGS_REG))]
11693 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
11694 && (TARGET_SHIFT1 || optimize_size)"
11696 [(set_attr "type" "rotate")
11697 (set (attr "length")
11698 (if_then_else (match_operand:DI 0 "register_operand" "")
11700 (const_string "*")))])
11702 (define_insn "*rotldi3_1_rex64"
11703 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11704 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11705 (match_operand:QI 2 "nonmemory_operand" "e,c")))
11706 (clobber (reg:CC FLAGS_REG))]
11707 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11709 rol{q}\t{%2, %0|%0, %2}
11710 rol{q}\t{%b2, %0|%0, %b2}"
11711 [(set_attr "type" "rotate")
11712 (set_attr "mode" "DI")])
11714 (define_expand "rotlsi3"
11715 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11716 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11717 (match_operand:QI 2 "nonmemory_operand" "")))
11718 (clobber (reg:CC FLAGS_REG))]
11720 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11722 (define_insn "*rotlsi3_1_one_bit"
11723 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11724 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11725 (match_operand:QI 2 "const1_operand" "")))
11726 (clobber (reg:CC FLAGS_REG))]
11727 "ix86_binary_operator_ok (ROTATE, SImode, operands)
11728 && (TARGET_SHIFT1 || optimize_size)"
11730 [(set_attr "type" "rotate")
11731 (set (attr "length")
11732 (if_then_else (match_operand:SI 0 "register_operand" "")
11734 (const_string "*")))])
11736 (define_insn "*rotlsi3_1_one_bit_zext"
11737 [(set (match_operand:DI 0 "register_operand" "=r")
11739 (rotate:SI (match_operand:SI 1 "register_operand" "0")
11740 (match_operand:QI 2 "const1_operand" ""))))
11741 (clobber (reg:CC FLAGS_REG))]
11742 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
11743 && (TARGET_SHIFT1 || optimize_size)"
11745 [(set_attr "type" "rotate")
11746 (set_attr "length" "2")])
11748 (define_insn "*rotlsi3_1"
11749 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11750 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11751 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11752 (clobber (reg:CC FLAGS_REG))]
11753 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
11755 rol{l}\t{%2, %0|%0, %2}
11756 rol{l}\t{%b2, %0|%0, %b2}"
11757 [(set_attr "type" "rotate")
11758 (set_attr "mode" "SI")])
11760 (define_insn "*rotlsi3_1_zext"
11761 [(set (match_operand:DI 0 "register_operand" "=r,r")
11763 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
11764 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11765 (clobber (reg:CC FLAGS_REG))]
11766 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11768 rol{l}\t{%2, %k0|%k0, %2}
11769 rol{l}\t{%b2, %k0|%k0, %b2}"
11770 [(set_attr "type" "rotate")
11771 (set_attr "mode" "SI")])
11773 (define_expand "rotlhi3"
11774 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11775 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
11776 (match_operand:QI 2 "nonmemory_operand" "")))
11777 (clobber (reg:CC FLAGS_REG))]
11778 "TARGET_HIMODE_MATH"
11779 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
11781 (define_insn "*rotlhi3_1_one_bit"
11782 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11783 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11784 (match_operand:QI 2 "const1_operand" "")))
11785 (clobber (reg:CC FLAGS_REG))]
11786 "ix86_binary_operator_ok (ROTATE, HImode, operands)
11787 && (TARGET_SHIFT1 || optimize_size)"
11789 [(set_attr "type" "rotate")
11790 (set (attr "length")
11791 (if_then_else (match_operand 0 "register_operand" "")
11793 (const_string "*")))])
11795 (define_insn "*rotlhi3_1"
11796 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11797 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11798 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11799 (clobber (reg:CC FLAGS_REG))]
11800 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
11802 rol{w}\t{%2, %0|%0, %2}
11803 rol{w}\t{%b2, %0|%0, %b2}"
11804 [(set_attr "type" "rotate")
11805 (set_attr "mode" "HI")])
11807 (define_expand "rotlqi3"
11808 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11809 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
11810 (match_operand:QI 2 "nonmemory_operand" "")))
11811 (clobber (reg:CC FLAGS_REG))]
11812 "TARGET_QIMODE_MATH"
11813 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
11815 (define_insn "*rotlqi3_1_one_bit_slp"
11816 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11817 (rotate:QI (match_dup 0)
11818 (match_operand:QI 1 "const1_operand" "")))
11819 (clobber (reg:CC FLAGS_REG))]
11820 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11821 && (TARGET_SHIFT1 || optimize_size)"
11823 [(set_attr "type" "rotate1")
11824 (set (attr "length")
11825 (if_then_else (match_operand 0 "register_operand" "")
11827 (const_string "*")))])
11829 (define_insn "*rotlqi3_1_one_bit"
11830 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11831 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11832 (match_operand:QI 2 "const1_operand" "")))
11833 (clobber (reg:CC FLAGS_REG))]
11834 "ix86_binary_operator_ok (ROTATE, QImode, operands)
11835 && (TARGET_SHIFT1 || optimize_size)"
11837 [(set_attr "type" "rotate")
11838 (set (attr "length")
11839 (if_then_else (match_operand 0 "register_operand" "")
11841 (const_string "*")))])
11843 (define_insn "*rotlqi3_1_slp"
11844 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11845 (rotate:QI (match_dup 0)
11846 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11847 (clobber (reg:CC FLAGS_REG))]
11848 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11849 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11851 rol{b}\t{%1, %0|%0, %1}
11852 rol{b}\t{%b1, %0|%0, %b1}"
11853 [(set_attr "type" "rotate1")
11854 (set_attr "mode" "QI")])
11856 (define_insn "*rotlqi3_1"
11857 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11858 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11859 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11860 (clobber (reg:CC FLAGS_REG))]
11861 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
11863 rol{b}\t{%2, %0|%0, %2}
11864 rol{b}\t{%b2, %0|%0, %b2}"
11865 [(set_attr "type" "rotate")
11866 (set_attr "mode" "QI")])
11868 (define_expand "rotrdi3"
11869 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11870 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "")
11871 (match_operand:QI 2 "nonmemory_operand" "")))
11872 (clobber (reg:CC FLAGS_REG))]
11874 "ix86_expand_binary_operator (ROTATERT, DImode, operands); DONE;")
11876 (define_insn "*rotrdi3_1_one_bit_rex64"
11877 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11878 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11879 (match_operand:QI 2 "const1_operand" "")))
11880 (clobber (reg:CC FLAGS_REG))]
11881 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
11882 && (TARGET_SHIFT1 || optimize_size)"
11884 [(set_attr "type" "rotate")
11885 (set (attr "length")
11886 (if_then_else (match_operand:DI 0 "register_operand" "")
11888 (const_string "*")))])
11890 (define_insn "*rotrdi3_1_rex64"
11891 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11892 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11893 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11894 (clobber (reg:CC FLAGS_REG))]
11895 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
11897 ror{q}\t{%2, %0|%0, %2}
11898 ror{q}\t{%b2, %0|%0, %b2}"
11899 [(set_attr "type" "rotate")
11900 (set_attr "mode" "DI")])
11902 (define_expand "rotrsi3"
11903 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11904 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
11905 (match_operand:QI 2 "nonmemory_operand" "")))
11906 (clobber (reg:CC FLAGS_REG))]
11908 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
11910 (define_insn "*rotrsi3_1_one_bit"
11911 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11912 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11913 (match_operand:QI 2 "const1_operand" "")))
11914 (clobber (reg:CC FLAGS_REG))]
11915 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
11916 && (TARGET_SHIFT1 || optimize_size)"
11918 [(set_attr "type" "rotate")
11919 (set (attr "length")
11920 (if_then_else (match_operand:SI 0 "register_operand" "")
11922 (const_string "*")))])
11924 (define_insn "*rotrsi3_1_one_bit_zext"
11925 [(set (match_operand:DI 0 "register_operand" "=r")
11927 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
11928 (match_operand:QI 2 "const1_operand" ""))))
11929 (clobber (reg:CC FLAGS_REG))]
11930 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
11931 && (TARGET_SHIFT1 || optimize_size)"
11933 [(set_attr "type" "rotate")
11934 (set (attr "length")
11935 (if_then_else (match_operand:SI 0 "register_operand" "")
11937 (const_string "*")))])
11939 (define_insn "*rotrsi3_1"
11940 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11941 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11942 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11943 (clobber (reg:CC FLAGS_REG))]
11944 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11946 ror{l}\t{%2, %0|%0, %2}
11947 ror{l}\t{%b2, %0|%0, %b2}"
11948 [(set_attr "type" "rotate")
11949 (set_attr "mode" "SI")])
11951 (define_insn "*rotrsi3_1_zext"
11952 [(set (match_operand:DI 0 "register_operand" "=r,r")
11954 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
11955 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11956 (clobber (reg:CC FLAGS_REG))]
11957 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
11959 ror{l}\t{%2, %k0|%k0, %2}
11960 ror{l}\t{%b2, %k0|%k0, %b2}"
11961 [(set_attr "type" "rotate")
11962 (set_attr "mode" "SI")])
11964 (define_expand "rotrhi3"
11965 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11966 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
11967 (match_operand:QI 2 "nonmemory_operand" "")))
11968 (clobber (reg:CC FLAGS_REG))]
11969 "TARGET_HIMODE_MATH"
11970 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
11972 (define_insn "*rotrhi3_one_bit"
11973 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11974 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11975 (match_operand:QI 2 "const1_operand" "")))
11976 (clobber (reg:CC FLAGS_REG))]
11977 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
11978 && (TARGET_SHIFT1 || optimize_size)"
11980 [(set_attr "type" "rotate")
11981 (set (attr "length")
11982 (if_then_else (match_operand 0 "register_operand" "")
11984 (const_string "*")))])
11986 (define_insn "*rotrhi3"
11987 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11988 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11989 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11990 (clobber (reg:CC FLAGS_REG))]
11991 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
11993 ror{w}\t{%2, %0|%0, %2}
11994 ror{w}\t{%b2, %0|%0, %b2}"
11995 [(set_attr "type" "rotate")
11996 (set_attr "mode" "HI")])
11998 (define_expand "rotrqi3"
11999 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12000 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12001 (match_operand:QI 2 "nonmemory_operand" "")))
12002 (clobber (reg:CC FLAGS_REG))]
12003 "TARGET_QIMODE_MATH"
12004 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12006 (define_insn "*rotrqi3_1_one_bit"
12007 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12008 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12009 (match_operand:QI 2 "const1_operand" "")))
12010 (clobber (reg:CC FLAGS_REG))]
12011 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12012 && (TARGET_SHIFT1 || optimize_size)"
12014 [(set_attr "type" "rotate")
12015 (set (attr "length")
12016 (if_then_else (match_operand 0 "register_operand" "")
12018 (const_string "*")))])
12020 (define_insn "*rotrqi3_1_one_bit_slp"
12021 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12022 (rotatert:QI (match_dup 0)
12023 (match_operand:QI 1 "const1_operand" "")))
12024 (clobber (reg:CC FLAGS_REG))]
12025 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12026 && (TARGET_SHIFT1 || optimize_size)"
12028 [(set_attr "type" "rotate1")
12029 (set (attr "length")
12030 (if_then_else (match_operand 0 "register_operand" "")
12032 (const_string "*")))])
12034 (define_insn "*rotrqi3_1"
12035 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12036 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12037 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12038 (clobber (reg:CC FLAGS_REG))]
12039 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12041 ror{b}\t{%2, %0|%0, %2}
12042 ror{b}\t{%b2, %0|%0, %b2}"
12043 [(set_attr "type" "rotate")
12044 (set_attr "mode" "QI")])
12046 (define_insn "*rotrqi3_1_slp"
12047 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12048 (rotatert:QI (match_dup 0)
12049 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12050 (clobber (reg:CC FLAGS_REG))]
12051 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12052 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12054 ror{b}\t{%1, %0|%0, %1}
12055 ror{b}\t{%b1, %0|%0, %b1}"
12056 [(set_attr "type" "rotate1")
12057 (set_attr "mode" "QI")])
12059 ;; Bit set / bit test instructions
12061 (define_expand "extv"
12062 [(set (match_operand:SI 0 "register_operand" "")
12063 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12064 (match_operand:SI 2 "immediate_operand" "")
12065 (match_operand:SI 3 "immediate_operand" "")))]
12068 /* Handle extractions from %ah et al. */
12069 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12072 /* From mips.md: extract_bit_field doesn't verify that our source
12073 matches the predicate, so check it again here. */
12074 if (! ext_register_operand (operands[1], VOIDmode))
12078 (define_expand "extzv"
12079 [(set (match_operand:SI 0 "register_operand" "")
12080 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12081 (match_operand:SI 2 "immediate_operand" "")
12082 (match_operand:SI 3 "immediate_operand" "")))]
12085 /* Handle extractions from %ah et al. */
12086 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12089 /* From mips.md: extract_bit_field doesn't verify that our source
12090 matches the predicate, so check it again here. */
12091 if (! ext_register_operand (operands[1], VOIDmode))
12095 (define_expand "insv"
12096 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12097 (match_operand 1 "immediate_operand" "")
12098 (match_operand 2 "immediate_operand" ""))
12099 (match_operand 3 "register_operand" ""))]
12102 /* Handle extractions from %ah et al. */
12103 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12106 /* From mips.md: insert_bit_field doesn't verify that our source
12107 matches the predicate, so check it again here. */
12108 if (! ext_register_operand (operands[0], VOIDmode))
12112 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12114 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12119 ;; %%% bts, btr, btc, bt.
12120 ;; In general these instructions are *slow* when applied to memory,
12121 ;; since they enforce atomic operation. When applied to registers,
12122 ;; it depends on the cpu implementation. They're never faster than
12123 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12124 ;; no point. But in 64-bit, we can't hold the relevant immediates
12125 ;; within the instruction itself, so operating on bits in the high
12126 ;; 32-bits of a register becomes easier.
12128 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12129 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12130 ;; negdf respectively, so they can never be disabled entirely.
12132 (define_insn "*btsq"
12133 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12135 (match_operand:DI 1 "const_0_to_63_operand" ""))
12137 (clobber (reg:CC FLAGS_REG))]
12138 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12140 [(set_attr "type" "alu1")])
12142 (define_insn "*btrq"
12143 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12145 (match_operand:DI 1 "const_0_to_63_operand" ""))
12147 (clobber (reg:CC FLAGS_REG))]
12148 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12150 [(set_attr "type" "alu1")])
12152 (define_insn "*btcq"
12153 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12155 (match_operand:DI 1 "const_0_to_63_operand" ""))
12156 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12157 (clobber (reg:CC FLAGS_REG))]
12158 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12160 [(set_attr "type" "alu1")])
12162 ;; Allow Nocona to avoid these instructions if a register is available.
12165 [(match_scratch:DI 2 "r")
12166 (parallel [(set (zero_extract:DI
12167 (match_operand:DI 0 "register_operand" "")
12169 (match_operand:DI 1 "const_0_to_63_operand" ""))
12171 (clobber (reg:CC FLAGS_REG))])]
12172 "TARGET_64BIT && !TARGET_USE_BT"
12175 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12178 if (HOST_BITS_PER_WIDE_INT >= 64)
12179 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12180 else if (i < HOST_BITS_PER_WIDE_INT)
12181 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12183 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12185 op1 = immed_double_const (lo, hi, DImode);
12188 emit_move_insn (operands[2], op1);
12192 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12197 [(match_scratch:DI 2 "r")
12198 (parallel [(set (zero_extract:DI
12199 (match_operand:DI 0 "register_operand" "")
12201 (match_operand:DI 1 "const_0_to_63_operand" ""))
12203 (clobber (reg:CC FLAGS_REG))])]
12204 "TARGET_64BIT && !TARGET_USE_BT"
12207 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12210 if (HOST_BITS_PER_WIDE_INT >= 64)
12211 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12212 else if (i < HOST_BITS_PER_WIDE_INT)
12213 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12215 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12217 op1 = immed_double_const (~lo, ~hi, DImode);
12220 emit_move_insn (operands[2], op1);
12224 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12229 [(match_scratch:DI 2 "r")
12230 (parallel [(set (zero_extract:DI
12231 (match_operand:DI 0 "register_operand" "")
12233 (match_operand:DI 1 "const_0_to_63_operand" ""))
12234 (not:DI (zero_extract:DI
12235 (match_dup 0) (const_int 1) (match_dup 1))))
12236 (clobber (reg:CC FLAGS_REG))])]
12237 "TARGET_64BIT && !TARGET_USE_BT"
12240 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12243 if (HOST_BITS_PER_WIDE_INT >= 64)
12244 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12245 else if (i < HOST_BITS_PER_WIDE_INT)
12246 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12248 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12250 op1 = immed_double_const (lo, hi, DImode);
12253 emit_move_insn (operands[2], op1);
12257 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12261 ;; Store-flag instructions.
12263 ;; For all sCOND expanders, also expand the compare or test insn that
12264 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12266 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
12267 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
12268 ;; way, which can later delete the movzx if only QImode is needed.
12270 (define_expand "seq"
12271 [(set (match_operand:QI 0 "register_operand" "")
12272 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12274 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
12276 (define_expand "sne"
12277 [(set (match_operand:QI 0 "register_operand" "")
12278 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
12280 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
12282 (define_expand "sgt"
12283 [(set (match_operand:QI 0 "register_operand" "")
12284 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12286 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
12288 (define_expand "sgtu"
12289 [(set (match_operand:QI 0 "register_operand" "")
12290 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12292 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
12294 (define_expand "slt"
12295 [(set (match_operand:QI 0 "register_operand" "")
12296 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12298 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
12300 (define_expand "sltu"
12301 [(set (match_operand:QI 0 "register_operand" "")
12302 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12304 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
12306 (define_expand "sge"
12307 [(set (match_operand:QI 0 "register_operand" "")
12308 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12310 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
12312 (define_expand "sgeu"
12313 [(set (match_operand:QI 0 "register_operand" "")
12314 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12316 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
12318 (define_expand "sle"
12319 [(set (match_operand:QI 0 "register_operand" "")
12320 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
12322 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
12324 (define_expand "sleu"
12325 [(set (match_operand:QI 0 "register_operand" "")
12326 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
12328 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
12330 (define_expand "sunordered"
12331 [(set (match_operand:QI 0 "register_operand" "")
12332 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12333 "TARGET_80387 || TARGET_SSE"
12334 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
12336 (define_expand "sordered"
12337 [(set (match_operand:QI 0 "register_operand" "")
12338 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
12340 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
12342 (define_expand "suneq"
12343 [(set (match_operand:QI 0 "register_operand" "")
12344 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
12345 "TARGET_80387 || TARGET_SSE"
12346 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
12348 (define_expand "sunge"
12349 [(set (match_operand:QI 0 "register_operand" "")
12350 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
12351 "TARGET_80387 || TARGET_SSE"
12352 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
12354 (define_expand "sungt"
12355 [(set (match_operand:QI 0 "register_operand" "")
12356 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12357 "TARGET_80387 || TARGET_SSE"
12358 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
12360 (define_expand "sunle"
12361 [(set (match_operand:QI 0 "register_operand" "")
12362 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
12363 "TARGET_80387 || TARGET_SSE"
12364 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
12366 (define_expand "sunlt"
12367 [(set (match_operand:QI 0 "register_operand" "")
12368 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12369 "TARGET_80387 || TARGET_SSE"
12370 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
12372 (define_expand "sltgt"
12373 [(set (match_operand:QI 0 "register_operand" "")
12374 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
12375 "TARGET_80387 || TARGET_SSE"
12376 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
12378 (define_insn "*setcc_1"
12379 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12380 (match_operator:QI 1 "ix86_comparison_operator"
12381 [(reg FLAGS_REG) (const_int 0)]))]
12384 [(set_attr "type" "setcc")
12385 (set_attr "mode" "QI")])
12387 (define_insn "*setcc_2"
12388 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12389 (match_operator:QI 1 "ix86_comparison_operator"
12390 [(reg FLAGS_REG) (const_int 0)]))]
12393 [(set_attr "type" "setcc")
12394 (set_attr "mode" "QI")])
12396 ;; In general it is not safe to assume too much about CCmode registers,
12397 ;; so simplify-rtx stops when it sees a second one. Under certain
12398 ;; conditions this is safe on x86, so help combine not create
12405 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12406 (ne:QI (match_operator 1 "ix86_comparison_operator"
12407 [(reg FLAGS_REG) (const_int 0)])
12410 [(set (match_dup 0) (match_dup 1))]
12412 PUT_MODE (operands[1], QImode);
12416 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12417 (ne:QI (match_operator 1 "ix86_comparison_operator"
12418 [(reg FLAGS_REG) (const_int 0)])
12421 [(set (match_dup 0) (match_dup 1))]
12423 PUT_MODE (operands[1], QImode);
12427 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12428 (eq:QI (match_operator 1 "ix86_comparison_operator"
12429 [(reg FLAGS_REG) (const_int 0)])
12432 [(set (match_dup 0) (match_dup 1))]
12434 rtx new_op1 = copy_rtx (operands[1]);
12435 operands[1] = new_op1;
12436 PUT_MODE (new_op1, QImode);
12437 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12438 GET_MODE (XEXP (new_op1, 0))));
12440 /* Make sure that (a) the CCmode we have for the flags is strong
12441 enough for the reversed compare or (b) we have a valid FP compare. */
12442 if (! ix86_comparison_operator (new_op1, VOIDmode))
12447 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12448 (eq:QI (match_operator 1 "ix86_comparison_operator"
12449 [(reg FLAGS_REG) (const_int 0)])
12452 [(set (match_dup 0) (match_dup 1))]
12454 rtx new_op1 = copy_rtx (operands[1]);
12455 operands[1] = new_op1;
12456 PUT_MODE (new_op1, QImode);
12457 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12458 GET_MODE (XEXP (new_op1, 0))));
12460 /* Make sure that (a) the CCmode we have for the flags is strong
12461 enough for the reversed compare or (b) we have a valid FP compare. */
12462 if (! ix86_comparison_operator (new_op1, VOIDmode))
12466 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12467 ;; subsequent logical operations are used to imitate conditional moves.
12468 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12471 (define_insn "*sse_setccsf"
12472 [(set (match_operand:SF 0 "register_operand" "=x")
12473 (match_operator:SF 1 "sse_comparison_operator"
12474 [(match_operand:SF 2 "register_operand" "0")
12475 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
12477 "cmp%D1ss\t{%3, %0|%0, %3}"
12478 [(set_attr "type" "ssecmp")
12479 (set_attr "mode" "SF")])
12481 (define_insn "*sse_setccdf"
12482 [(set (match_operand:DF 0 "register_operand" "=Y")
12483 (match_operator:DF 1 "sse_comparison_operator"
12484 [(match_operand:DF 2 "register_operand" "0")
12485 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
12487 "cmp%D1sd\t{%3, %0|%0, %3}"
12488 [(set_attr "type" "ssecmp")
12489 (set_attr "mode" "DF")])
12491 ;; Basic conditional jump instructions.
12492 ;; We ignore the overflow flag for signed branch instructions.
12494 ;; For all bCOND expanders, also expand the compare or test insn that
12495 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
12497 (define_expand "beq"
12499 (if_then_else (match_dup 1)
12500 (label_ref (match_operand 0 "" ""))
12503 "ix86_expand_branch (EQ, operands[0]); DONE;")
12505 (define_expand "bne"
12507 (if_then_else (match_dup 1)
12508 (label_ref (match_operand 0 "" ""))
12511 "ix86_expand_branch (NE, operands[0]); DONE;")
12513 (define_expand "bgt"
12515 (if_then_else (match_dup 1)
12516 (label_ref (match_operand 0 "" ""))
12519 "ix86_expand_branch (GT, operands[0]); DONE;")
12521 (define_expand "bgtu"
12523 (if_then_else (match_dup 1)
12524 (label_ref (match_operand 0 "" ""))
12527 "ix86_expand_branch (GTU, operands[0]); DONE;")
12529 (define_expand "blt"
12531 (if_then_else (match_dup 1)
12532 (label_ref (match_operand 0 "" ""))
12535 "ix86_expand_branch (LT, operands[0]); DONE;")
12537 (define_expand "bltu"
12539 (if_then_else (match_dup 1)
12540 (label_ref (match_operand 0 "" ""))
12543 "ix86_expand_branch (LTU, operands[0]); DONE;")
12545 (define_expand "bge"
12547 (if_then_else (match_dup 1)
12548 (label_ref (match_operand 0 "" ""))
12551 "ix86_expand_branch (GE, operands[0]); DONE;")
12553 (define_expand "bgeu"
12555 (if_then_else (match_dup 1)
12556 (label_ref (match_operand 0 "" ""))
12559 "ix86_expand_branch (GEU, operands[0]); DONE;")
12561 (define_expand "ble"
12563 (if_then_else (match_dup 1)
12564 (label_ref (match_operand 0 "" ""))
12567 "ix86_expand_branch (LE, operands[0]); DONE;")
12569 (define_expand "bleu"
12571 (if_then_else (match_dup 1)
12572 (label_ref (match_operand 0 "" ""))
12575 "ix86_expand_branch (LEU, operands[0]); DONE;")
12577 (define_expand "bunordered"
12579 (if_then_else (match_dup 1)
12580 (label_ref (match_operand 0 "" ""))
12582 "TARGET_80387 || TARGET_SSE_MATH"
12583 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
12585 (define_expand "bordered"
12587 (if_then_else (match_dup 1)
12588 (label_ref (match_operand 0 "" ""))
12590 "TARGET_80387 || TARGET_SSE_MATH"
12591 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
12593 (define_expand "buneq"
12595 (if_then_else (match_dup 1)
12596 (label_ref (match_operand 0 "" ""))
12598 "TARGET_80387 || TARGET_SSE_MATH"
12599 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
12601 (define_expand "bunge"
12603 (if_then_else (match_dup 1)
12604 (label_ref (match_operand 0 "" ""))
12606 "TARGET_80387 || TARGET_SSE_MATH"
12607 "ix86_expand_branch (UNGE, operands[0]); DONE;")
12609 (define_expand "bungt"
12611 (if_then_else (match_dup 1)
12612 (label_ref (match_operand 0 "" ""))
12614 "TARGET_80387 || TARGET_SSE_MATH"
12615 "ix86_expand_branch (UNGT, operands[0]); DONE;")
12617 (define_expand "bunle"
12619 (if_then_else (match_dup 1)
12620 (label_ref (match_operand 0 "" ""))
12622 "TARGET_80387 || TARGET_SSE_MATH"
12623 "ix86_expand_branch (UNLE, operands[0]); DONE;")
12625 (define_expand "bunlt"
12627 (if_then_else (match_dup 1)
12628 (label_ref (match_operand 0 "" ""))
12630 "TARGET_80387 || TARGET_SSE_MATH"
12631 "ix86_expand_branch (UNLT, operands[0]); DONE;")
12633 (define_expand "bltgt"
12635 (if_then_else (match_dup 1)
12636 (label_ref (match_operand 0 "" ""))
12638 "TARGET_80387 || TARGET_SSE_MATH"
12639 "ix86_expand_branch (LTGT, operands[0]); DONE;")
12641 (define_insn "*jcc_1"
12643 (if_then_else (match_operator 1 "ix86_comparison_operator"
12644 [(reg FLAGS_REG) (const_int 0)])
12645 (label_ref (match_operand 0 "" ""))
12649 [(set_attr "type" "ibr")
12650 (set_attr "modrm" "0")
12651 (set (attr "length")
12652 (if_then_else (and (ge (minus (match_dup 0) (pc))
12654 (lt (minus (match_dup 0) (pc))
12659 (define_insn "*jcc_2"
12661 (if_then_else (match_operator 1 "ix86_comparison_operator"
12662 [(reg FLAGS_REG) (const_int 0)])
12664 (label_ref (match_operand 0 "" ""))))]
12667 [(set_attr "type" "ibr")
12668 (set_attr "modrm" "0")
12669 (set (attr "length")
12670 (if_then_else (and (ge (minus (match_dup 0) (pc))
12672 (lt (minus (match_dup 0) (pc))
12677 ;; In general it is not safe to assume too much about CCmode registers,
12678 ;; so simplify-rtx stops when it sees a second one. Under certain
12679 ;; conditions this is safe on x86, so help combine not create
12687 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12688 [(reg FLAGS_REG) (const_int 0)])
12690 (label_ref (match_operand 1 "" ""))
12694 (if_then_else (match_dup 0)
12695 (label_ref (match_dup 1))
12698 PUT_MODE (operands[0], VOIDmode);
12703 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12704 [(reg FLAGS_REG) (const_int 0)])
12706 (label_ref (match_operand 1 "" ""))
12710 (if_then_else (match_dup 0)
12711 (label_ref (match_dup 1))
12714 rtx new_op0 = copy_rtx (operands[0]);
12715 operands[0] = new_op0;
12716 PUT_MODE (new_op0, VOIDmode);
12717 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12718 GET_MODE (XEXP (new_op0, 0))));
12720 /* Make sure that (a) the CCmode we have for the flags is strong
12721 enough for the reversed compare or (b) we have a valid FP compare. */
12722 if (! ix86_comparison_operator (new_op0, VOIDmode))
12726 ;; Define combination compare-and-branch fp compare instructions to use
12727 ;; during early optimization. Splitting the operation apart early makes
12728 ;; for bad code when we want to reverse the operation.
12730 (define_insn "*fp_jcc_1_mixed"
12732 (if_then_else (match_operator 0 "comparison_operator"
12733 [(match_operand 1 "register_operand" "f#x,x#f")
12734 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12735 (label_ref (match_operand 3 "" ""))
12737 (clobber (reg:CCFP FPSR_REG))
12738 (clobber (reg:CCFP FLAGS_REG))]
12739 "TARGET_MIX_SSE_I387
12740 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12741 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12742 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12745 (define_insn "*fp_jcc_1_sse"
12747 (if_then_else (match_operator 0 "comparison_operator"
12748 [(match_operand 1 "register_operand" "x")
12749 (match_operand 2 "nonimmediate_operand" "xm")])
12750 (label_ref (match_operand 3 "" ""))
12752 (clobber (reg:CCFP FPSR_REG))
12753 (clobber (reg:CCFP FLAGS_REG))]
12755 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12756 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12757 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12760 (define_insn "*fp_jcc_1_387"
12762 (if_then_else (match_operator 0 "comparison_operator"
12763 [(match_operand 1 "register_operand" "f")
12764 (match_operand 2 "register_operand" "f")])
12765 (label_ref (match_operand 3 "" ""))
12767 (clobber (reg:CCFP FPSR_REG))
12768 (clobber (reg:CCFP FLAGS_REG))]
12769 "TARGET_CMOVE && TARGET_80387
12770 && FLOAT_MODE_P (GET_MODE (operands[1]))
12771 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12772 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12775 (define_insn "*fp_jcc_2_mixed"
12777 (if_then_else (match_operator 0 "comparison_operator"
12778 [(match_operand 1 "register_operand" "f#x,x#f")
12779 (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
12781 (label_ref (match_operand 3 "" ""))))
12782 (clobber (reg:CCFP FPSR_REG))
12783 (clobber (reg:CCFP FLAGS_REG))]
12784 "TARGET_MIX_SSE_I387
12785 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12786 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12787 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12790 (define_insn "*fp_jcc_2_sse"
12792 (if_then_else (match_operator 0 "comparison_operator"
12793 [(match_operand 1 "register_operand" "x")
12794 (match_operand 2 "nonimmediate_operand" "xm")])
12796 (label_ref (match_operand 3 "" ""))))
12797 (clobber (reg:CCFP FPSR_REG))
12798 (clobber (reg:CCFP FLAGS_REG))]
12800 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
12801 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12802 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12805 (define_insn "*fp_jcc_2_387"
12807 (if_then_else (match_operator 0 "comparison_operator"
12808 [(match_operand 1 "register_operand" "f")
12809 (match_operand 2 "register_operand" "f")])
12811 (label_ref (match_operand 3 "" ""))))
12812 (clobber (reg:CCFP FPSR_REG))
12813 (clobber (reg:CCFP FLAGS_REG))]
12814 "TARGET_CMOVE && TARGET_80387
12815 && FLOAT_MODE_P (GET_MODE (operands[1]))
12816 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12817 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12820 (define_insn "*fp_jcc_3_387"
12822 (if_then_else (match_operator 0 "comparison_operator"
12823 [(match_operand 1 "register_operand" "f")
12824 (match_operand 2 "nonimmediate_operand" "fm")])
12825 (label_ref (match_operand 3 "" ""))
12827 (clobber (reg:CCFP FPSR_REG))
12828 (clobber (reg:CCFP FLAGS_REG))
12829 (clobber (match_scratch:HI 4 "=a"))]
12831 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12832 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12833 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12834 && SELECT_CC_MODE (GET_CODE (operands[0]),
12835 operands[1], operands[2]) == CCFPmode
12836 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12839 (define_insn "*fp_jcc_4_387"
12841 (if_then_else (match_operator 0 "comparison_operator"
12842 [(match_operand 1 "register_operand" "f")
12843 (match_operand 2 "nonimmediate_operand" "fm")])
12845 (label_ref (match_operand 3 "" ""))))
12846 (clobber (reg:CCFP FPSR_REG))
12847 (clobber (reg:CCFP FLAGS_REG))
12848 (clobber (match_scratch:HI 4 "=a"))]
12850 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
12851 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12852 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12853 && SELECT_CC_MODE (GET_CODE (operands[0]),
12854 operands[1], operands[2]) == CCFPmode
12855 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12858 (define_insn "*fp_jcc_5_387"
12860 (if_then_else (match_operator 0 "comparison_operator"
12861 [(match_operand 1 "register_operand" "f")
12862 (match_operand 2 "register_operand" "f")])
12863 (label_ref (match_operand 3 "" ""))
12865 (clobber (reg:CCFP FPSR_REG))
12866 (clobber (reg:CCFP FLAGS_REG))
12867 (clobber (match_scratch:HI 4 "=a"))]
12869 && FLOAT_MODE_P (GET_MODE (operands[1]))
12870 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12871 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12874 (define_insn "*fp_jcc_6_387"
12876 (if_then_else (match_operator 0 "comparison_operator"
12877 [(match_operand 1 "register_operand" "f")
12878 (match_operand 2 "register_operand" "f")])
12880 (label_ref (match_operand 3 "" ""))))
12881 (clobber (reg:CCFP FPSR_REG))
12882 (clobber (reg:CCFP FLAGS_REG))
12883 (clobber (match_scratch:HI 4 "=a"))]
12885 && FLOAT_MODE_P (GET_MODE (operands[1]))
12886 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12887 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12890 (define_insn "*fp_jcc_7_387"
12892 (if_then_else (match_operator 0 "comparison_operator"
12893 [(match_operand 1 "register_operand" "f")
12894 (match_operand 2 "const0_operand" "X")])
12895 (label_ref (match_operand 3 "" ""))
12897 (clobber (reg:CCFP FPSR_REG))
12898 (clobber (reg:CCFP FLAGS_REG))
12899 (clobber (match_scratch:HI 4 "=a"))]
12901 && FLOAT_MODE_P (GET_MODE (operands[1]))
12902 && GET_MODE (operands[1]) == GET_MODE (operands[2])
12903 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
12904 && SELECT_CC_MODE (GET_CODE (operands[0]),
12905 operands[1], operands[2]) == CCFPmode
12906 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
12909 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
12910 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
12911 ;; with a precedence over other operators and is always put in the first
12912 ;; place. Swap condition and operands to match ficom instruction.
12914 (define_insn "*fp_jcc_8<mode>_387"
12916 (if_then_else (match_operator 0 "comparison_operator"
12917 [(match_operator 1 "float_operator"
12918 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
12919 (match_operand 3 "register_operand" "f,f")])
12920 (label_ref (match_operand 4 "" ""))
12922 (clobber (reg:CCFP FPSR_REG))
12923 (clobber (reg:CCFP FLAGS_REG))
12924 (clobber (match_scratch:HI 5 "=a,a"))]
12925 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
12926 && FLOAT_MODE_P (GET_MODE (operands[3]))
12927 && GET_MODE (operands[1]) == GET_MODE (operands[3])
12928 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
12929 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
12930 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
12935 (if_then_else (match_operator 0 "comparison_operator"
12936 [(match_operand 1 "register_operand" "")
12937 (match_operand 2 "nonimmediate_operand" "")])
12938 (match_operand 3 "" "")
12939 (match_operand 4 "" "")))
12940 (clobber (reg:CCFP FPSR_REG))
12941 (clobber (reg:CCFP FLAGS_REG))]
12945 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12946 operands[3], operands[4], NULL_RTX, NULL_RTX);
12952 (if_then_else (match_operator 0 "comparison_operator"
12953 [(match_operand 1 "register_operand" "")
12954 (match_operand 2 "general_operand" "")])
12955 (match_operand 3 "" "")
12956 (match_operand 4 "" "")))
12957 (clobber (reg:CCFP FPSR_REG))
12958 (clobber (reg:CCFP FLAGS_REG))
12959 (clobber (match_scratch:HI 5 "=a"))]
12963 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
12964 operands[3], operands[4], operands[5], NULL_RTX);
12970 (if_then_else (match_operator 0 "comparison_operator"
12971 [(match_operator 1 "float_operator"
12972 [(match_operand:X87MODEI12 2 "memory_operand" "")])
12973 (match_operand 3 "register_operand" "")])
12974 (match_operand 4 "" "")
12975 (match_operand 5 "" "")))
12976 (clobber (reg:CCFP FPSR_REG))
12977 (clobber (reg:CCFP FLAGS_REG))
12978 (clobber (match_scratch:HI 6 "=a"))]
12982 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
12983 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
12984 operands[3], operands[7],
12985 operands[4], operands[5], operands[6], NULL_RTX);
12989 ;; %%% Kill this when reload knows how to do it.
12992 (if_then_else (match_operator 0 "comparison_operator"
12993 [(match_operator 1 "float_operator"
12994 [(match_operand:X87MODEI12 2 "register_operand" "")])
12995 (match_operand 3 "register_operand" "")])
12996 (match_operand 4 "" "")
12997 (match_operand 5 "" "")))
12998 (clobber (reg:CCFP FPSR_REG))
12999 (clobber (reg:CCFP FLAGS_REG))
13000 (clobber (match_scratch:HI 6 "=a"))]
13004 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13005 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13006 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13007 operands[3], operands[7],
13008 operands[4], operands[5], operands[6], operands[2]);
13012 ;; Unconditional and other jump instructions
13014 (define_insn "jump"
13016 (label_ref (match_operand 0 "" "")))]
13019 [(set_attr "type" "ibr")
13020 (set (attr "length")
13021 (if_then_else (and (ge (minus (match_dup 0) (pc))
13023 (lt (minus (match_dup 0) (pc))
13027 (set_attr "modrm" "0")])
13029 (define_expand "indirect_jump"
13030 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13034 (define_insn "*indirect_jump"
13035 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13038 [(set_attr "type" "ibr")
13039 (set_attr "length_immediate" "0")])
13041 (define_insn "*indirect_jump_rtx64"
13042 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13045 [(set_attr "type" "ibr")
13046 (set_attr "length_immediate" "0")])
13048 (define_expand "tablejump"
13049 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13050 (use (label_ref (match_operand 1 "" "")))])]
13053 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13054 relative. Convert the relative address to an absolute address. */
13058 enum rtx_code code;
13064 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13066 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13070 op1 = pic_offset_table_rtx;
13075 op0 = pic_offset_table_rtx;
13079 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13084 (define_insn "*tablejump_1"
13085 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13086 (use (label_ref (match_operand 1 "" "")))]
13089 [(set_attr "type" "ibr")
13090 (set_attr "length_immediate" "0")])
13092 (define_insn "*tablejump_1_rtx64"
13093 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13094 (use (label_ref (match_operand 1 "" "")))]
13097 [(set_attr "type" "ibr")
13098 (set_attr "length_immediate" "0")])
13100 ;; Loop instruction
13102 ;; This is all complicated by the fact that since this is a jump insn
13103 ;; we must handle our own reloads.
13105 (define_expand "doloop_end"
13106 [(use (match_operand 0 "" "")) ; loop pseudo
13107 (use (match_operand 1 "" "")) ; iterations; zero if unknown
13108 (use (match_operand 2 "" "")) ; max iterations
13109 (use (match_operand 3 "" "")) ; loop level
13110 (use (match_operand 4 "" ""))] ; label
13111 "!TARGET_64BIT && TARGET_USE_LOOP"
13114 /* Only use cloop on innermost loops. */
13115 if (INTVAL (operands[3]) > 1)
13117 if (GET_MODE (operands[0]) != SImode)
13119 emit_jump_insn (gen_doloop_end_internal (operands[4], operands[0],
13124 (define_insn "doloop_end_internal"
13126 (if_then_else (ne (match_operand:SI 1 "register_operand" "c,?*r,?*r")
13128 (label_ref (match_operand 0 "" ""))
13130 (set (match_operand:SI 2 "nonimmediate_operand" "=1,1,*m*r")
13131 (plus:SI (match_dup 1)
13133 (clobber (match_scratch:SI 3 "=X,X,r"))
13134 (clobber (reg:CC FLAGS_REG))]
13135 "!TARGET_64BIT && TARGET_USE_LOOP
13136 && (reload_in_progress || reload_completed
13137 || register_operand (operands[2], VOIDmode))"
13139 if (which_alternative != 0)
13141 if (get_attr_length (insn) == 2)
13142 return "%+loop\t%l0";
13144 return "dec{l}\t%1\;%+jne\t%l0";
13146 [(set (attr "length")
13147 (if_then_else (and (eq_attr "alternative" "0")
13148 (and (ge (minus (match_dup 0) (pc))
13150 (lt (minus (match_dup 0) (pc))
13154 ;; We don't know the type before shorten branches. Optimistically expect
13155 ;; the loop instruction to match.
13156 (set (attr "type") (const_string "ibr"))])
13160 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13162 (match_operand 0 "" "")
13165 (plus:SI (match_dup 1)
13167 (clobber (match_scratch:SI 2 ""))
13168 (clobber (reg:CC FLAGS_REG))]
13169 "!TARGET_64BIT && TARGET_USE_LOOP
13170 && reload_completed
13171 && REGNO (operands[1]) != 2"
13172 [(parallel [(set (reg:CCZ FLAGS_REG)
13173 (compare:CCZ (plus:SI (match_dup 1) (const_int -1))
13175 (set (match_dup 1) (plus:SI (match_dup 1) (const_int -1)))])
13176 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13183 (if_then_else (ne (match_operand:SI 1 "register_operand" "")
13185 (match_operand 0 "" "")
13187 (set (match_operand:SI 2 "nonimmediate_operand" "")
13188 (plus:SI (match_dup 1)
13190 (clobber (match_scratch:SI 3 ""))
13191 (clobber (reg:CC FLAGS_REG))]
13192 "!TARGET_64BIT && TARGET_USE_LOOP
13193 && reload_completed
13194 && (! REG_P (operands[2])
13195 || ! rtx_equal_p (operands[1], operands[2]))"
13196 [(set (match_dup 3) (match_dup 1))
13197 (parallel [(set (reg:CCZ FLAGS_REG)
13198 (compare:CCZ (plus:SI (match_dup 3) (const_int -1))
13200 (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
13201 (set (match_dup 2) (match_dup 3))
13202 (set (pc) (if_then_else (ne (reg:CCZ FLAGS_REG) (const_int 0))
13207 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13210 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13211 (set (match_operand:QI 1 "register_operand" "")
13212 (match_operator:QI 2 "ix86_comparison_operator"
13213 [(reg FLAGS_REG) (const_int 0)]))
13214 (set (match_operand 3 "q_regs_operand" "")
13215 (zero_extend (match_dup 1)))]
13216 "(peep2_reg_dead_p (3, operands[1])
13217 || operands_match_p (operands[1], operands[3]))
13218 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13219 [(set (match_dup 4) (match_dup 0))
13220 (set (strict_low_part (match_dup 5))
13223 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13224 operands[5] = gen_lowpart (QImode, operands[3]);
13225 ix86_expand_clear (operands[3]);
13228 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13231 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13232 (set (match_operand:QI 1 "register_operand" "")
13233 (match_operator:QI 2 "ix86_comparison_operator"
13234 [(reg FLAGS_REG) (const_int 0)]))
13235 (parallel [(set (match_operand 3 "q_regs_operand" "")
13236 (zero_extend (match_dup 1)))
13237 (clobber (reg:CC FLAGS_REG))])]
13238 "(peep2_reg_dead_p (3, operands[1])
13239 || operands_match_p (operands[1], operands[3]))
13240 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13241 [(set (match_dup 4) (match_dup 0))
13242 (set (strict_low_part (match_dup 5))
13245 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), 17);
13246 operands[5] = gen_lowpart (QImode, operands[3]);
13247 ix86_expand_clear (operands[3]);
13250 ;; Call instructions.
13252 ;; The predicates normally associated with named expanders are not properly
13253 ;; checked for calls. This is a bug in the generic code, but it isn't that
13254 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13256 ;; Call subroutine returning no value.
13258 (define_expand "call_pop"
13259 [(parallel [(call (match_operand:QI 0 "" "")
13260 (match_operand:SI 1 "" ""))
13261 (set (reg:SI SP_REG)
13262 (plus:SI (reg:SI SP_REG)
13263 (match_operand:SI 3 "" "")))])]
13266 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
13270 (define_insn "*call_pop_0"
13271 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13272 (match_operand:SI 1 "" ""))
13273 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13274 (match_operand:SI 2 "immediate_operand" "")))]
13277 if (SIBLING_CALL_P (insn))
13280 return "call\t%P0";
13282 [(set_attr "type" "call")])
13284 (define_insn "*call_pop_1"
13285 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13286 (match_operand:SI 1 "" ""))
13287 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
13288 (match_operand:SI 2 "immediate_operand" "i")))]
13291 if (constant_call_address_operand (operands[0], Pmode))
13293 if (SIBLING_CALL_P (insn))
13296 return "call\t%P0";
13298 if (SIBLING_CALL_P (insn))
13301 return "call\t%A0";
13303 [(set_attr "type" "call")])
13305 (define_expand "call"
13306 [(call (match_operand:QI 0 "" "")
13307 (match_operand 1 "" ""))
13308 (use (match_operand 2 "" ""))]
13311 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13315 (define_expand "sibcall"
13316 [(call (match_operand:QI 0 "" "")
13317 (match_operand 1 "" ""))
13318 (use (match_operand 2 "" ""))]
13321 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13325 (define_insn "*call_0"
13326 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13327 (match_operand 1 "" ""))]
13330 if (SIBLING_CALL_P (insn))
13333 return "call\t%P0";
13335 [(set_attr "type" "call")])
13337 (define_insn "*call_1"
13338 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
13339 (match_operand 1 "" ""))]
13340 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
13342 if (constant_call_address_operand (operands[0], Pmode))
13343 return "call\t%P0";
13344 return "call\t%A0";
13346 [(set_attr "type" "call")])
13348 (define_insn "*sibcall_1"
13349 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
13350 (match_operand 1 "" ""))]
13351 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
13353 if (constant_call_address_operand (operands[0], Pmode))
13357 [(set_attr "type" "call")])
13359 (define_insn "*call_1_rex64"
13360 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13361 (match_operand 1 "" ""))]
13362 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
13364 if (constant_call_address_operand (operands[0], Pmode))
13365 return "call\t%P0";
13366 return "call\t%A0";
13368 [(set_attr "type" "call")])
13370 (define_insn "*sibcall_1_rex64"
13371 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
13372 (match_operand 1 "" ""))]
13373 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13375 [(set_attr "type" "call")])
13377 (define_insn "*sibcall_1_rex64_v"
13378 [(call (mem:QI (reg:DI 40))
13379 (match_operand 0 "" ""))]
13380 "SIBLING_CALL_P (insn) && TARGET_64BIT"
13382 [(set_attr "type" "call")])
13385 ;; Call subroutine, returning value in operand 0
13387 (define_expand "call_value_pop"
13388 [(parallel [(set (match_operand 0 "" "")
13389 (call (match_operand:QI 1 "" "")
13390 (match_operand:SI 2 "" "")))
13391 (set (reg:SI SP_REG)
13392 (plus:SI (reg:SI SP_REG)
13393 (match_operand:SI 4 "" "")))])]
13396 ix86_expand_call (operands[0], operands[1], operands[2],
13397 operands[3], operands[4], 0);
13401 (define_expand "call_value"
13402 [(set (match_operand 0 "" "")
13403 (call (match_operand:QI 1 "" "")
13404 (match_operand:SI 2 "" "")))
13405 (use (match_operand:SI 3 "" ""))]
13406 ;; Operand 2 not used on the i386.
13409 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
13413 (define_expand "sibcall_value"
13414 [(set (match_operand 0 "" "")
13415 (call (match_operand:QI 1 "" "")
13416 (match_operand:SI 2 "" "")))
13417 (use (match_operand:SI 3 "" ""))]
13418 ;; Operand 2 not used on the i386.
13421 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
13425 ;; Call subroutine returning any type.
13427 (define_expand "untyped_call"
13428 [(parallel [(call (match_operand 0 "" "")
13430 (match_operand 1 "" "")
13431 (match_operand 2 "" "")])]
13436 /* In order to give reg-stack an easier job in validating two
13437 coprocessor registers as containing a possible return value,
13438 simply pretend the untyped call returns a complex long double
13441 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13442 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13443 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
13446 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13448 rtx set = XVECEXP (operands[2], 0, i);
13449 emit_move_insn (SET_DEST (set), SET_SRC (set));
13452 /* The optimizer does not know that the call sets the function value
13453 registers we stored in the result block. We avoid problems by
13454 claiming that all hard registers are used and clobbered at this
13456 emit_insn (gen_blockage (const0_rtx));
13461 ;; Prologue and epilogue instructions
13463 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13464 ;; all of memory. This blocks insns from being moved across this point.
13466 (define_insn "blockage"
13467 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
13470 [(set_attr "length" "0")])
13472 ;; Insn emitted into the body of a function to return from a function.
13473 ;; This is only done if the function's epilogue is known to be simple.
13474 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13476 (define_expand "return"
13478 "ix86_can_use_return_insn_p ()"
13480 if (current_function_pops_args)
13482 rtx popc = GEN_INT (current_function_pops_args);
13483 emit_jump_insn (gen_return_pop_internal (popc));
13488 (define_insn "return_internal"
13492 [(set_attr "length" "1")
13493 (set_attr "length_immediate" "0")
13494 (set_attr "modrm" "0")])
13496 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13497 ;; instruction Athlon and K8 have.
13499 (define_insn "return_internal_long"
13501 (unspec [(const_int 0)] UNSPEC_REP)]
13504 [(set_attr "length" "1")
13505 (set_attr "length_immediate" "0")
13506 (set_attr "prefix_rep" "1")
13507 (set_attr "modrm" "0")])
13509 (define_insn "return_pop_internal"
13511 (use (match_operand:SI 0 "const_int_operand" ""))]
13514 [(set_attr "length" "3")
13515 (set_attr "length_immediate" "2")
13516 (set_attr "modrm" "0")])
13518 (define_insn "return_indirect_internal"
13520 (use (match_operand:SI 0 "register_operand" "r"))]
13523 [(set_attr "type" "ibr")
13524 (set_attr "length_immediate" "0")])
13530 [(set_attr "length" "1")
13531 (set_attr "length_immediate" "0")
13532 (set_attr "modrm" "0")])
13534 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
13535 ;; branch prediction penalty for the third jump in a 16-byte
13538 (define_insn "align"
13539 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13542 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
13543 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
13545 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13546 The align insn is used to avoid 3 jump instructions in the row to improve
13547 branch prediction and the benefits hardly outweight the cost of extra 8
13548 nops on the average inserted by full alignment pseudo operation. */
13552 [(set_attr "length" "16")])
13554 (define_expand "prologue"
13557 "ix86_expand_prologue (); DONE;")
13559 (define_insn "set_got"
13560 [(set (match_operand:SI 0 "register_operand" "=r")
13561 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13562 (clobber (reg:CC FLAGS_REG))]
13564 { return output_set_got (operands[0]); }
13565 [(set_attr "type" "multi")
13566 (set_attr "length" "12")])
13568 (define_expand "epilogue"
13571 "ix86_expand_epilogue (1); DONE;")
13573 (define_expand "sibcall_epilogue"
13576 "ix86_expand_epilogue (0); DONE;")
13578 (define_expand "eh_return"
13579 [(use (match_operand 0 "register_operand" ""))]
13582 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13584 /* Tricky bit: we write the address of the handler to which we will
13585 be returning into someone else's stack frame, one word below the
13586 stack address we wish to restore. */
13587 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13588 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13589 tmp = gen_rtx_MEM (Pmode, tmp);
13590 emit_move_insn (tmp, ra);
13592 if (Pmode == SImode)
13593 emit_jump_insn (gen_eh_return_si (sa));
13595 emit_jump_insn (gen_eh_return_di (sa));
13600 (define_insn_and_split "eh_return_si"
13602 (unspec [(match_operand:SI 0 "register_operand" "c")]
13603 UNSPEC_EH_RETURN))]
13608 "ix86_expand_epilogue (2); DONE;")
13610 (define_insn_and_split "eh_return_di"
13612 (unspec [(match_operand:DI 0 "register_operand" "c")]
13613 UNSPEC_EH_RETURN))]
13618 "ix86_expand_epilogue (2); DONE;")
13620 (define_insn "leave"
13621 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13622 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13623 (clobber (mem:BLK (scratch)))]
13626 [(set_attr "type" "leave")])
13628 (define_insn "leave_rex64"
13629 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13630 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13631 (clobber (mem:BLK (scratch)))]
13634 [(set_attr "type" "leave")])
13636 (define_expand "ffssi2"
13638 [(set (match_operand:SI 0 "register_operand" "")
13639 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13640 (clobber (match_scratch:SI 2 ""))
13641 (clobber (reg:CC FLAGS_REG))])]
13645 (define_insn_and_split "*ffs_cmove"
13646 [(set (match_operand:SI 0 "register_operand" "=r")
13647 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13648 (clobber (match_scratch:SI 2 "=&r"))
13649 (clobber (reg:CC FLAGS_REG))]
13652 "&& reload_completed"
13653 [(set (match_dup 2) (const_int -1))
13654 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13655 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13656 (set (match_dup 0) (if_then_else:SI
13657 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13660 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13661 (clobber (reg:CC FLAGS_REG))])]
13664 (define_insn_and_split "*ffs_no_cmove"
13665 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
13666 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13667 (clobber (match_scratch:SI 2 "=&q"))
13668 (clobber (reg:CC FLAGS_REG))]
13672 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
13673 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13674 (set (strict_low_part (match_dup 3))
13675 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13676 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13677 (clobber (reg:CC FLAGS_REG))])
13678 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13679 (clobber (reg:CC FLAGS_REG))])
13680 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13681 (clobber (reg:CC FLAGS_REG))])]
13683 operands[3] = gen_lowpart (QImode, operands[2]);
13684 ix86_expand_clear (operands[2]);
13687 (define_insn "*ffssi_1"
13688 [(set (reg:CCZ FLAGS_REG)
13689 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13691 (set (match_operand:SI 0 "register_operand" "=r")
13692 (ctz:SI (match_dup 1)))]
13694 "bsf{l}\t{%1, %0|%0, %1}"
13695 [(set_attr "prefix_0f" "1")])
13697 (define_expand "ffsdi2"
13699 [(set (match_operand:DI 0 "register_operand" "")
13700 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
13701 (clobber (match_scratch:DI 2 ""))
13702 (clobber (reg:CC FLAGS_REG))])]
13703 "TARGET_64BIT && TARGET_CMOVE"
13706 (define_insn_and_split "*ffs_rex64"
13707 [(set (match_operand:DI 0 "register_operand" "=r")
13708 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13709 (clobber (match_scratch:DI 2 "=&r"))
13710 (clobber (reg:CC FLAGS_REG))]
13711 "TARGET_64BIT && TARGET_CMOVE"
13713 "&& reload_completed"
13714 [(set (match_dup 2) (const_int -1))
13715 (parallel [(set (reg:CCZ FLAGS_REG)
13716 (compare:CCZ (match_dup 1) (const_int 0)))
13717 (set (match_dup 0) (ctz:DI (match_dup 1)))])
13718 (set (match_dup 0) (if_then_else:DI
13719 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13722 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13723 (clobber (reg:CC FLAGS_REG))])]
13726 (define_insn "*ffsdi_1"
13727 [(set (reg:CCZ FLAGS_REG)
13728 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13730 (set (match_operand:DI 0 "register_operand" "=r")
13731 (ctz:DI (match_dup 1)))]
13733 "bsf{q}\t{%1, %0|%0, %1}"
13734 [(set_attr "prefix_0f" "1")])
13736 (define_insn "ctzsi2"
13737 [(set (match_operand:SI 0 "register_operand" "=r")
13738 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13739 (clobber (reg:CC FLAGS_REG))]
13741 "bsf{l}\t{%1, %0|%0, %1}"
13742 [(set_attr "prefix_0f" "1")])
13744 (define_insn "ctzdi2"
13745 [(set (match_operand:DI 0 "register_operand" "=r")
13746 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13747 (clobber (reg:CC FLAGS_REG))]
13749 "bsf{q}\t{%1, %0|%0, %1}"
13750 [(set_attr "prefix_0f" "1")])
13752 (define_expand "clzsi2"
13754 [(set (match_operand:SI 0 "register_operand" "")
13755 (minus:SI (const_int 31)
13756 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13757 (clobber (reg:CC FLAGS_REG))])
13759 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13760 (clobber (reg:CC FLAGS_REG))])]
13764 (define_insn "*bsr"
13765 [(set (match_operand:SI 0 "register_operand" "=r")
13766 (minus:SI (const_int 31)
13767 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13768 (clobber (reg:CC FLAGS_REG))]
13770 "bsr{l}\t{%1, %0|%0, %1}"
13771 [(set_attr "prefix_0f" "1")])
13773 (define_expand "clzdi2"
13775 [(set (match_operand:DI 0 "register_operand" "")
13776 (minus:DI (const_int 63)
13777 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
13778 (clobber (reg:CC FLAGS_REG))])
13780 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
13781 (clobber (reg:CC FLAGS_REG))])]
13785 (define_insn "*bsr_rex64"
13786 [(set (match_operand:DI 0 "register_operand" "=r")
13787 (minus:DI (const_int 63)
13788 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13789 (clobber (reg:CC FLAGS_REG))]
13791 "bsr{q}\t{%1, %0|%0, %1}"
13792 [(set_attr "prefix_0f" "1")])
13794 ;; Thread-local storage patterns for ELF.
13796 ;; Note that these code sequences must appear exactly as shown
13797 ;; in order to allow linker relaxation.
13799 (define_insn "*tls_global_dynamic_32_gnu"
13800 [(set (match_operand:SI 0 "register_operand" "=a")
13801 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13802 (match_operand:SI 2 "tls_symbolic_operand" "")
13803 (match_operand:SI 3 "call_insn_operand" "")]
13805 (clobber (match_scratch:SI 4 "=d"))
13806 (clobber (match_scratch:SI 5 "=c"))
13807 (clobber (reg:CC FLAGS_REG))]
13808 "!TARGET_64BIT && TARGET_GNU_TLS"
13809 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
13810 [(set_attr "type" "multi")
13811 (set_attr "length" "12")])
13813 (define_insn "*tls_global_dynamic_32_sun"
13814 [(set (match_operand:SI 0 "register_operand" "=a")
13815 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13816 (match_operand:SI 2 "tls_symbolic_operand" "")
13817 (match_operand:SI 3 "call_insn_operand" "")]
13819 (clobber (match_scratch:SI 4 "=d"))
13820 (clobber (match_scratch:SI 5 "=c"))
13821 (clobber (reg:CC FLAGS_REG))]
13822 "!TARGET_64BIT && TARGET_SUN_TLS"
13823 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
13824 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
13825 [(set_attr "type" "multi")
13826 (set_attr "length" "14")])
13828 (define_expand "tls_global_dynamic_32"
13829 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13832 (match_operand:SI 1 "tls_symbolic_operand" "")
13835 (clobber (match_scratch:SI 4 ""))
13836 (clobber (match_scratch:SI 5 ""))
13837 (clobber (reg:CC FLAGS_REG))])]
13841 operands[2] = pic_offset_table_rtx;
13844 operands[2] = gen_reg_rtx (Pmode);
13845 emit_insn (gen_set_got (operands[2]));
13847 operands[3] = ix86_tls_get_addr ();
13850 (define_insn "*tls_global_dynamic_64"
13851 [(set (match_operand:DI 0 "register_operand" "=a")
13852 (call (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
13853 (match_operand:DI 3 "" "")))
13854 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13857 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
13858 [(set_attr "type" "multi")
13859 (set_attr "length" "16")])
13861 (define_expand "tls_global_dynamic_64"
13862 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13863 (call (mem:QI (match_dup 2)) (const_int 0)))
13864 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13868 operands[2] = ix86_tls_get_addr ();
13871 (define_insn "*tls_local_dynamic_base_32_gnu"
13872 [(set (match_operand:SI 0 "register_operand" "=a")
13873 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13874 (match_operand:SI 2 "call_insn_operand" "")]
13875 UNSPEC_TLS_LD_BASE))
13876 (clobber (match_scratch:SI 3 "=d"))
13877 (clobber (match_scratch:SI 4 "=c"))
13878 (clobber (reg:CC FLAGS_REG))]
13879 "!TARGET_64BIT && TARGET_GNU_TLS"
13880 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
13881 [(set_attr "type" "multi")
13882 (set_attr "length" "11")])
13884 (define_insn "*tls_local_dynamic_base_32_sun"
13885 [(set (match_operand:SI 0 "register_operand" "=a")
13886 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13887 (match_operand:SI 2 "call_insn_operand" "")]
13888 UNSPEC_TLS_LD_BASE))
13889 (clobber (match_scratch:SI 3 "=d"))
13890 (clobber (match_scratch:SI 4 "=c"))
13891 (clobber (reg:CC FLAGS_REG))]
13892 "!TARGET_64BIT && TARGET_SUN_TLS"
13893 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
13894 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
13895 [(set_attr "type" "multi")
13896 (set_attr "length" "13")])
13898 (define_expand "tls_local_dynamic_base_32"
13899 [(parallel [(set (match_operand:SI 0 "register_operand" "")
13900 (unspec:SI [(match_dup 1) (match_dup 2)]
13901 UNSPEC_TLS_LD_BASE))
13902 (clobber (match_scratch:SI 3 ""))
13903 (clobber (match_scratch:SI 4 ""))
13904 (clobber (reg:CC FLAGS_REG))])]
13908 operands[1] = pic_offset_table_rtx;
13911 operands[1] = gen_reg_rtx (Pmode);
13912 emit_insn (gen_set_got (operands[1]));
13914 operands[2] = ix86_tls_get_addr ();
13917 (define_insn "*tls_local_dynamic_base_64"
13918 [(set (match_operand:DI 0 "register_operand" "=a")
13919 (call (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
13920 (match_operand:DI 2 "" "")))
13921 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13923 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
13924 [(set_attr "type" "multi")
13925 (set_attr "length" "12")])
13927 (define_expand "tls_local_dynamic_base_64"
13928 [(parallel [(set (match_operand:DI 0 "register_operand" "")
13929 (call (mem:QI (match_dup 1)) (const_int 0)))
13930 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13933 operands[1] = ix86_tls_get_addr ();
13936 ;; Local dynamic of a single variable is a lose. Show combine how
13937 ;; to convert that back to global dynamic.
13939 (define_insn_and_split "*tls_local_dynamic_32_once"
13940 [(set (match_operand:SI 0 "register_operand" "=a")
13941 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13942 (match_operand:SI 2 "call_insn_operand" "")]
13943 UNSPEC_TLS_LD_BASE)
13944 (const:SI (unspec:SI
13945 [(match_operand:SI 3 "tls_symbolic_operand" "")]
13947 (clobber (match_scratch:SI 4 "=d"))
13948 (clobber (match_scratch:SI 5 "=c"))
13949 (clobber (reg:CC FLAGS_REG))]
13953 [(parallel [(set (match_dup 0)
13954 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
13956 (clobber (match_dup 4))
13957 (clobber (match_dup 5))
13958 (clobber (reg:CC FLAGS_REG))])]
13961 ;; Load and add the thread base pointer from %gs:0.
13963 (define_insn "*load_tp_si"
13964 [(set (match_operand:SI 0 "register_operand" "=r")
13965 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13967 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13968 [(set_attr "type" "imov")
13969 (set_attr "modrm" "0")
13970 (set_attr "length" "7")
13971 (set_attr "memory" "load")
13972 (set_attr "imm_disp" "false")])
13974 (define_insn "*add_tp_si"
13975 [(set (match_operand:SI 0 "register_operand" "=r")
13976 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13977 (match_operand:SI 1 "register_operand" "0")))
13978 (clobber (reg:CC FLAGS_REG))]
13980 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
13981 [(set_attr "type" "alu")
13982 (set_attr "modrm" "0")
13983 (set_attr "length" "7")
13984 (set_attr "memory" "load")
13985 (set_attr "imm_disp" "false")])
13987 (define_insn "*load_tp_di"
13988 [(set (match_operand:DI 0 "register_operand" "=r")
13989 (unspec:DI [(const_int 0)] UNSPEC_TP))]
13991 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
13992 [(set_attr "type" "imov")
13993 (set_attr "modrm" "0")
13994 (set_attr "length" "7")
13995 (set_attr "memory" "load")
13996 (set_attr "imm_disp" "false")])
13998 (define_insn "*add_tp_di"
13999 [(set (match_operand:DI 0 "register_operand" "=r")
14000 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14001 (match_operand:DI 1 "register_operand" "0")))
14002 (clobber (reg:CC FLAGS_REG))]
14004 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14005 [(set_attr "type" "alu")
14006 (set_attr "modrm" "0")
14007 (set_attr "length" "7")
14008 (set_attr "memory" "load")
14009 (set_attr "imm_disp" "false")])
14011 ;; These patterns match the binary 387 instructions for addM3, subM3,
14012 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14013 ;; SFmode. The first is the normal insn, the second the same insn but
14014 ;; with one operand a conversion, and the third the same insn but with
14015 ;; the other operand a conversion. The conversion may be SFmode or
14016 ;; SImode if the target mode DFmode, but only SImode if the target mode
14019 ;; Gcc is slightly more smart about handling normal two address instructions
14020 ;; so use special patterns for add and mull.
14022 (define_insn "*fop_sf_comm_mixed"
14023 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14024 (match_operator:SF 3 "binary_fp_operator"
14025 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14026 (match_operand:SF 2 "nonimmediate_operand" "fm#x,xm#f")]))]
14027 "TARGET_MIX_SSE_I387
14028 && COMMUTATIVE_ARITH_P (operands[3])
14029 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14030 "* return output_387_binary_op (insn, operands);"
14031 [(set (attr "type")
14032 (if_then_else (eq_attr "alternative" "1")
14033 (if_then_else (match_operand:SF 3 "mult_operator" "")
14034 (const_string "ssemul")
14035 (const_string "sseadd"))
14036 (if_then_else (match_operand:SF 3 "mult_operator" "")
14037 (const_string "fmul")
14038 (const_string "fop"))))
14039 (set_attr "mode" "SF")])
14041 (define_insn "*fop_sf_comm_sse"
14042 [(set (match_operand:SF 0 "register_operand" "=x")
14043 (match_operator:SF 3 "binary_fp_operator"
14044 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14045 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14047 && COMMUTATIVE_ARITH_P (operands[3])
14048 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14049 "* return output_387_binary_op (insn, operands);"
14050 [(set (attr "type")
14051 (if_then_else (match_operand:SF 3 "mult_operator" "")
14052 (const_string "ssemul")
14053 (const_string "sseadd")))
14054 (set_attr "mode" "SF")])
14056 (define_insn "*fop_sf_comm_i387"
14057 [(set (match_operand:SF 0 "register_operand" "=f")
14058 (match_operator:SF 3 "binary_fp_operator"
14059 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14060 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
14062 && COMMUTATIVE_ARITH_P (operands[3])
14063 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14064 "* return output_387_binary_op (insn, operands);"
14065 [(set (attr "type")
14066 (if_then_else (match_operand:SF 3 "mult_operator" "")
14067 (const_string "fmul")
14068 (const_string "fop")))
14069 (set_attr "mode" "SF")])
14071 (define_insn "*fop_sf_1_mixed"
14072 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
14073 (match_operator:SF 3 "binary_fp_operator"
14074 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
14075 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm#f")]))]
14076 "TARGET_MIX_SSE_I387
14077 && !COMMUTATIVE_ARITH_P (operands[3])
14078 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14079 "* return output_387_binary_op (insn, operands);"
14080 [(set (attr "type")
14081 (cond [(and (eq_attr "alternative" "2")
14082 (match_operand:SF 3 "mult_operator" ""))
14083 (const_string "ssemul")
14084 (and (eq_attr "alternative" "2")
14085 (match_operand:SF 3 "div_operator" ""))
14086 (const_string "ssediv")
14087 (eq_attr "alternative" "2")
14088 (const_string "sseadd")
14089 (match_operand:SF 3 "mult_operator" "")
14090 (const_string "fmul")
14091 (match_operand:SF 3 "div_operator" "")
14092 (const_string "fdiv")
14094 (const_string "fop")))
14095 (set_attr "mode" "SF")])
14097 (define_insn "*fop_sf_1_sse"
14098 [(set (match_operand:SF 0 "register_operand" "=x")
14099 (match_operator:SF 3 "binary_fp_operator"
14100 [(match_operand:SF 1 "register_operand" "0")
14101 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14103 && !COMMUTATIVE_ARITH_P (operands[3])"
14104 "* return output_387_binary_op (insn, operands);"
14105 [(set (attr "type")
14106 (cond [(match_operand:SF 3 "mult_operator" "")
14107 (const_string "ssemul")
14108 (match_operand:SF 3 "div_operator" "")
14109 (const_string "ssediv")
14111 (const_string "sseadd")))
14112 (set_attr "mode" "SF")])
14114 ;; This pattern is not fully shadowed by the pattern above.
14115 (define_insn "*fop_sf_1_i387"
14116 [(set (match_operand:SF 0 "register_operand" "=f,f")
14117 (match_operator:SF 3 "binary_fp_operator"
14118 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
14119 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
14120 "TARGET_80387 && !TARGET_SSE_MATH
14121 && !COMMUTATIVE_ARITH_P (operands[3])
14122 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14123 "* return output_387_binary_op (insn, operands);"
14124 [(set (attr "type")
14125 (cond [(match_operand:SF 3 "mult_operator" "")
14126 (const_string "fmul")
14127 (match_operand:SF 3 "div_operator" "")
14128 (const_string "fdiv")
14130 (const_string "fop")))
14131 (set_attr "mode" "SF")])
14133 ;; ??? Add SSE splitters for these!
14134 (define_insn "*fop_sf_2<mode>_i387"
14135 [(set (match_operand:SF 0 "register_operand" "=f,f")
14136 (match_operator:SF 3 "binary_fp_operator"
14137 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14138 (match_operand:SF 2 "register_operand" "0,0")]))]
14139 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14140 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14141 [(set (attr "type")
14142 (cond [(match_operand:SF 3 "mult_operator" "")
14143 (const_string "fmul")
14144 (match_operand:SF 3 "div_operator" "")
14145 (const_string "fdiv")
14147 (const_string "fop")))
14148 (set_attr "fp_int_src" "true")
14149 (set_attr "mode" "<MODE>")])
14151 (define_insn "*fop_sf_3<mode>_i387"
14152 [(set (match_operand:SF 0 "register_operand" "=f,f")
14153 (match_operator:SF 3 "binary_fp_operator"
14154 [(match_operand:SF 1 "register_operand" "0,0")
14155 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14156 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
14157 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14158 [(set (attr "type")
14159 (cond [(match_operand:SF 3 "mult_operator" "")
14160 (const_string "fmul")
14161 (match_operand:SF 3 "div_operator" "")
14162 (const_string "fdiv")
14164 (const_string "fop")))
14165 (set_attr "fp_int_src" "true")
14166 (set_attr "mode" "<MODE>")])
14168 (define_insn "*fop_df_comm_mixed"
14169 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14170 (match_operator:DF 3 "binary_fp_operator"
14171 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
14172 (match_operand:DF 2 "nonimmediate_operand" "fm#Y,Ym#f")]))]
14173 "TARGET_SSE2 && TARGET_MIX_SSE_I387
14174 && COMMUTATIVE_ARITH_P (operands[3])
14175 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14176 "* return output_387_binary_op (insn, operands);"
14177 [(set (attr "type")
14178 (if_then_else (eq_attr "alternative" "1")
14179 (if_then_else (match_operand:SF 3 "mult_operator" "")
14180 (const_string "ssemul")
14181 (const_string "sseadd"))
14182 (if_then_else (match_operand:SF 3 "mult_operator" "")
14183 (const_string "fmul")
14184 (const_string "fop"))))
14185 (set_attr "mode" "DF")])
14187 (define_insn "*fop_df_comm_sse"
14188 [(set (match_operand:DF 0 "register_operand" "=Y")
14189 (match_operator:DF 3 "binary_fp_operator"
14190 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14191 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14192 "TARGET_SSE2 && TARGET_SSE_MATH
14193 && COMMUTATIVE_ARITH_P (operands[3])
14194 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14195 "* return output_387_binary_op (insn, operands);"
14196 [(set (attr "type")
14197 (if_then_else (match_operand:SF 3 "mult_operator" "")
14198 (const_string "ssemul")
14199 (const_string "sseadd")))
14200 (set_attr "mode" "DF")])
14202 (define_insn "*fop_df_comm_i387"
14203 [(set (match_operand:DF 0 "register_operand" "=f")
14204 (match_operator:DF 3 "binary_fp_operator"
14205 [(match_operand:DF 1 "nonimmediate_operand" "%0")
14206 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
14208 && COMMUTATIVE_ARITH_P (operands[3])
14209 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14210 "* return output_387_binary_op (insn, operands);"
14211 [(set (attr "type")
14212 (if_then_else (match_operand:SF 3 "mult_operator" "")
14213 (const_string "fmul")
14214 (const_string "fop")))
14215 (set_attr "mode" "DF")])
14217 (define_insn "*fop_df_1_mixed"
14218 [(set (match_operand:DF 0 "register_operand" "=f#Y,f#Y,Y#f")
14219 (match_operator:DF 3 "binary_fp_operator"
14220 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
14221 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym#f")]))]
14222 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
14223 && !COMMUTATIVE_ARITH_P (operands[3])
14224 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14225 "* return output_387_binary_op (insn, operands);"
14226 [(set (attr "type")
14227 (cond [(and (eq_attr "alternative" "2")
14228 (match_operand:SF 3 "mult_operator" ""))
14229 (const_string "ssemul")
14230 (and (eq_attr "alternative" "2")
14231 (match_operand:SF 3 "div_operator" ""))
14232 (const_string "ssediv")
14233 (eq_attr "alternative" "2")
14234 (const_string "sseadd")
14235 (match_operand:DF 3 "mult_operator" "")
14236 (const_string "fmul")
14237 (match_operand:DF 3 "div_operator" "")
14238 (const_string "fdiv")
14240 (const_string "fop")))
14241 (set_attr "mode" "DF")])
14243 (define_insn "*fop_df_1_sse"
14244 [(set (match_operand:DF 0 "register_operand" "=Y")
14245 (match_operator:DF 3 "binary_fp_operator"
14246 [(match_operand:DF 1 "register_operand" "0")
14247 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
14248 "TARGET_SSE2 && TARGET_SSE_MATH
14249 && !COMMUTATIVE_ARITH_P (operands[3])"
14250 "* return output_387_binary_op (insn, operands);"
14251 [(set_attr "mode" "DF")
14253 (cond [(match_operand:SF 3 "mult_operator" "")
14254 (const_string "ssemul")
14255 (match_operand:SF 3 "div_operator" "")
14256 (const_string "ssediv")
14258 (const_string "sseadd")))])
14260 ;; This pattern is not fully shadowed by the pattern above.
14261 (define_insn "*fop_df_1_i387"
14262 [(set (match_operand:DF 0 "register_operand" "=f,f")
14263 (match_operator:DF 3 "binary_fp_operator"
14264 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
14265 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
14266 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14267 && !COMMUTATIVE_ARITH_P (operands[3])
14268 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14269 "* return output_387_binary_op (insn, operands);"
14270 [(set (attr "type")
14271 (cond [(match_operand:DF 3 "mult_operator" "")
14272 (const_string "fmul")
14273 (match_operand:DF 3 "div_operator" "")
14274 (const_string "fdiv")
14276 (const_string "fop")))
14277 (set_attr "mode" "DF")])
14279 ;; ??? Add SSE splitters for these!
14280 (define_insn "*fop_df_2<mode>_i387"
14281 [(set (match_operand:DF 0 "register_operand" "=f,f")
14282 (match_operator:DF 3 "binary_fp_operator"
14283 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14284 (match_operand:DF 2 "register_operand" "0,0")]))]
14285 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14286 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14287 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14288 [(set (attr "type")
14289 (cond [(match_operand:DF 3 "mult_operator" "")
14290 (const_string "fmul")
14291 (match_operand:DF 3 "div_operator" "")
14292 (const_string "fdiv")
14294 (const_string "fop")))
14295 (set_attr "fp_int_src" "true")
14296 (set_attr "mode" "<MODE>")])
14298 (define_insn "*fop_df_3<mode>_i387"
14299 [(set (match_operand:DF 0 "register_operand" "=f,f")
14300 (match_operator:DF 3 "binary_fp_operator"
14301 [(match_operand:DF 1 "register_operand" "0,0")
14302 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14303 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14304 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14305 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14306 [(set (attr "type")
14307 (cond [(match_operand:DF 3 "mult_operator" "")
14308 (const_string "fmul")
14309 (match_operand:DF 3 "div_operator" "")
14310 (const_string "fdiv")
14312 (const_string "fop")))
14313 (set_attr "fp_int_src" "true")
14314 (set_attr "mode" "<MODE>")])
14316 (define_insn "*fop_df_4_i387"
14317 [(set (match_operand:DF 0 "register_operand" "=f,f")
14318 (match_operator:DF 3 "binary_fp_operator"
14319 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14320 (match_operand:DF 2 "register_operand" "0,f")]))]
14321 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14322 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14323 "* return output_387_binary_op (insn, operands);"
14324 [(set (attr "type")
14325 (cond [(match_operand:DF 3 "mult_operator" "")
14326 (const_string "fmul")
14327 (match_operand:DF 3 "div_operator" "")
14328 (const_string "fdiv")
14330 (const_string "fop")))
14331 (set_attr "mode" "SF")])
14333 (define_insn "*fop_df_5_i387"
14334 [(set (match_operand:DF 0 "register_operand" "=f,f")
14335 (match_operator:DF 3 "binary_fp_operator"
14336 [(match_operand:DF 1 "register_operand" "0,f")
14338 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14339 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14340 "* return output_387_binary_op (insn, operands);"
14341 [(set (attr "type")
14342 (cond [(match_operand:DF 3 "mult_operator" "")
14343 (const_string "fmul")
14344 (match_operand:DF 3 "div_operator" "")
14345 (const_string "fdiv")
14347 (const_string "fop")))
14348 (set_attr "mode" "SF")])
14350 (define_insn "*fop_df_6_i387"
14351 [(set (match_operand:DF 0 "register_operand" "=f,f")
14352 (match_operator:DF 3 "binary_fp_operator"
14354 (match_operand:SF 1 "register_operand" "0,f"))
14356 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14357 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14358 "* return output_387_binary_op (insn, operands);"
14359 [(set (attr "type")
14360 (cond [(match_operand:DF 3 "mult_operator" "")
14361 (const_string "fmul")
14362 (match_operand:DF 3 "div_operator" "")
14363 (const_string "fdiv")
14365 (const_string "fop")))
14366 (set_attr "mode" "SF")])
14368 (define_insn "*fop_xf_comm_i387"
14369 [(set (match_operand:XF 0 "register_operand" "=f")
14370 (match_operator:XF 3 "binary_fp_operator"
14371 [(match_operand:XF 1 "register_operand" "%0")
14372 (match_operand:XF 2 "register_operand" "f")]))]
14374 && COMMUTATIVE_ARITH_P (operands[3])"
14375 "* return output_387_binary_op (insn, operands);"
14376 [(set (attr "type")
14377 (if_then_else (match_operand:XF 3 "mult_operator" "")
14378 (const_string "fmul")
14379 (const_string "fop")))
14380 (set_attr "mode" "XF")])
14382 (define_insn "*fop_xf_1_i387"
14383 [(set (match_operand:XF 0 "register_operand" "=f,f")
14384 (match_operator:XF 3 "binary_fp_operator"
14385 [(match_operand:XF 1 "register_operand" "0,f")
14386 (match_operand:XF 2 "register_operand" "f,0")]))]
14388 && !COMMUTATIVE_ARITH_P (operands[3])"
14389 "* return output_387_binary_op (insn, operands);"
14390 [(set (attr "type")
14391 (cond [(match_operand:XF 3 "mult_operator" "")
14392 (const_string "fmul")
14393 (match_operand:XF 3 "div_operator" "")
14394 (const_string "fdiv")
14396 (const_string "fop")))
14397 (set_attr "mode" "XF")])
14399 (define_insn "*fop_xf_2<mode>_i387"
14400 [(set (match_operand:XF 0 "register_operand" "=f,f")
14401 (match_operator:XF 3 "binary_fp_operator"
14402 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14403 (match_operand:XF 2 "register_operand" "0,0")]))]
14404 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14405 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14406 [(set (attr "type")
14407 (cond [(match_operand:XF 3 "mult_operator" "")
14408 (const_string "fmul")
14409 (match_operand:XF 3 "div_operator" "")
14410 (const_string "fdiv")
14412 (const_string "fop")))
14413 (set_attr "fp_int_src" "true")
14414 (set_attr "mode" "<MODE>")])
14416 (define_insn "*fop_xf_3<mode>_i387"
14417 [(set (match_operand:XF 0 "register_operand" "=f,f")
14418 (match_operator:XF 3 "binary_fp_operator"
14419 [(match_operand:XF 1 "register_operand" "0,0")
14420 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14421 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
14422 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14423 [(set (attr "type")
14424 (cond [(match_operand:XF 3 "mult_operator" "")
14425 (const_string "fmul")
14426 (match_operand:XF 3 "div_operator" "")
14427 (const_string "fdiv")
14429 (const_string "fop")))
14430 (set_attr "fp_int_src" "true")
14431 (set_attr "mode" "<MODE>")])
14433 (define_insn "*fop_xf_4_i387"
14434 [(set (match_operand:XF 0 "register_operand" "=f,f")
14435 (match_operator:XF 3 "binary_fp_operator"
14436 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
14437 (match_operand:XF 2 "register_operand" "0,f")]))]
14439 "* return output_387_binary_op (insn, operands);"
14440 [(set (attr "type")
14441 (cond [(match_operand:XF 3 "mult_operator" "")
14442 (const_string "fmul")
14443 (match_operand:XF 3 "div_operator" "")
14444 (const_string "fdiv")
14446 (const_string "fop")))
14447 (set_attr "mode" "SF")])
14449 (define_insn "*fop_xf_5_i387"
14450 [(set (match_operand:XF 0 "register_operand" "=f,f")
14451 (match_operator:XF 3 "binary_fp_operator"
14452 [(match_operand:XF 1 "register_operand" "0,f")
14454 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14456 "* return output_387_binary_op (insn, operands);"
14457 [(set (attr "type")
14458 (cond [(match_operand:XF 3 "mult_operator" "")
14459 (const_string "fmul")
14460 (match_operand:XF 3 "div_operator" "")
14461 (const_string "fdiv")
14463 (const_string "fop")))
14464 (set_attr "mode" "SF")])
14466 (define_insn "*fop_xf_6_i387"
14467 [(set (match_operand:XF 0 "register_operand" "=f,f")
14468 (match_operator:XF 3 "binary_fp_operator"
14470 (match_operand 1 "register_operand" "0,f"))
14472 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
14474 "* return output_387_binary_op (insn, operands);"
14475 [(set (attr "type")
14476 (cond [(match_operand:XF 3 "mult_operator" "")
14477 (const_string "fmul")
14478 (match_operand:XF 3 "div_operator" "")
14479 (const_string "fdiv")
14481 (const_string "fop")))
14482 (set_attr "mode" "SF")])
14485 [(set (match_operand 0 "register_operand" "")
14486 (match_operator 3 "binary_fp_operator"
14487 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
14488 (match_operand 2 "register_operand" "")]))]
14489 "TARGET_80387 && reload_completed
14490 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14493 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
14494 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14495 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14496 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14497 GET_MODE (operands[3]),
14500 ix86_free_from_memory (GET_MODE (operands[1]));
14505 [(set (match_operand 0 "register_operand" "")
14506 (match_operator 3 "binary_fp_operator"
14507 [(match_operand 1 "register_operand" "")
14508 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
14509 "TARGET_80387 && reload_completed
14510 && FLOAT_MODE_P (GET_MODE (operands[0]))"
14513 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14514 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
14515 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
14516 gen_rtx_fmt_ee (GET_CODE (operands[3]),
14517 GET_MODE (operands[3]),
14520 ix86_free_from_memory (GET_MODE (operands[2]));
14524 ;; FPU special functions.
14526 (define_expand "sqrtsf2"
14527 [(set (match_operand:SF 0 "register_operand" "")
14528 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
14529 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
14531 if (!TARGET_SSE_MATH)
14532 operands[1] = force_reg (SFmode, operands[1]);
14535 (define_insn "*sqrtsf2_mixed"
14536 [(set (match_operand:SF 0 "register_operand" "=f#x,x#f")
14537 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0#x,xm#f")))]
14538 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
14541 sqrtss\t{%1, %0|%0, %1}"
14542 [(set_attr "type" "fpspc,sse")
14543 (set_attr "mode" "SF,SF")
14544 (set_attr "athlon_decode" "direct,*")])
14546 (define_insn "*sqrtsf2_sse"
14547 [(set (match_operand:SF 0 "register_operand" "=x")
14548 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
14550 "sqrtss\t{%1, %0|%0, %1}"
14551 [(set_attr "type" "sse")
14552 (set_attr "mode" "SF")
14553 (set_attr "athlon_decode" "*")])
14555 (define_insn "*sqrtsf2_i387"
14556 [(set (match_operand:SF 0 "register_operand" "=f")
14557 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
14558 "TARGET_USE_FANCY_MATH_387"
14560 [(set_attr "type" "fpspc")
14561 (set_attr "mode" "SF")
14562 (set_attr "athlon_decode" "direct")])
14564 (define_expand "sqrtdf2"
14565 [(set (match_operand:DF 0 "register_operand" "")
14566 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
14567 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
14569 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
14570 operands[1] = force_reg (DFmode, operands[1]);
14573 (define_insn "*sqrtdf2_mixed"
14574 [(set (match_operand:DF 0 "register_operand" "=f#Y,Y#f")
14575 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0#Y,Ym#f")))]
14576 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
14579 sqrtsd\t{%1, %0|%0, %1}"
14580 [(set_attr "type" "fpspc,sse")
14581 (set_attr "mode" "DF,DF")
14582 (set_attr "athlon_decode" "direct,*")])
14584 (define_insn "*sqrtdf2_sse"
14585 [(set (match_operand:DF 0 "register_operand" "=Y")
14586 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
14587 "TARGET_SSE2 && TARGET_SSE_MATH"
14588 "sqrtsd\t{%1, %0|%0, %1}"
14589 [(set_attr "type" "sse")
14590 (set_attr "mode" "DF")
14591 (set_attr "athlon_decode" "*")])
14593 (define_insn "*sqrtdf2_i387"
14594 [(set (match_operand:DF 0 "register_operand" "=f")
14595 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
14596 "TARGET_USE_FANCY_MATH_387"
14598 [(set_attr "type" "fpspc")
14599 (set_attr "mode" "DF")
14600 (set_attr "athlon_decode" "direct")])
14602 (define_insn "*sqrtextendsfdf2_i387"
14603 [(set (match_operand:DF 0 "register_operand" "=f")
14604 (sqrt:DF (float_extend:DF
14605 (match_operand:SF 1 "register_operand" "0"))))]
14606 "TARGET_USE_FANCY_MATH_387
14607 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
14609 [(set_attr "type" "fpspc")
14610 (set_attr "mode" "DF")
14611 (set_attr "athlon_decode" "direct")])
14613 (define_insn "sqrtxf2"
14614 [(set (match_operand:XF 0 "register_operand" "=f")
14615 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14616 "TARGET_USE_FANCY_MATH_387
14617 && (TARGET_IEEE_FP || flag_unsafe_math_optimizations) "
14619 [(set_attr "type" "fpspc")
14620 (set_attr "mode" "XF")
14621 (set_attr "athlon_decode" "direct")])
14623 (define_insn "*sqrtextendsfxf2_i387"
14624 [(set (match_operand:XF 0 "register_operand" "=f")
14625 (sqrt:XF (float_extend:XF
14626 (match_operand:SF 1 "register_operand" "0"))))]
14627 "TARGET_USE_FANCY_MATH_387"
14629 [(set_attr "type" "fpspc")
14630 (set_attr "mode" "XF")
14631 (set_attr "athlon_decode" "direct")])
14633 (define_insn "*sqrtextenddfxf2_i387"
14634 [(set (match_operand:XF 0 "register_operand" "=f")
14635 (sqrt:XF (float_extend:XF
14636 (match_operand:DF 1 "register_operand" "0"))))]
14637 "TARGET_USE_FANCY_MATH_387"
14639 [(set_attr "type" "fpspc")
14640 (set_attr "mode" "XF")
14641 (set_attr "athlon_decode" "direct")])
14643 (define_insn "fpremxf4"
14644 [(set (match_operand:XF 0 "register_operand" "=f")
14645 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14646 (match_operand:XF 3 "register_operand" "1")]
14648 (set (match_operand:XF 1 "register_operand" "=u")
14649 (unspec:XF [(match_dup 2) (match_dup 3)]
14651 (set (reg:CCFP FPSR_REG)
14652 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14653 "TARGET_USE_FANCY_MATH_387
14654 && flag_unsafe_math_optimizations"
14656 [(set_attr "type" "fpspc")
14657 (set_attr "mode" "XF")])
14659 (define_expand "fmodsf3"
14660 [(use (match_operand:SF 0 "register_operand" ""))
14661 (use (match_operand:SF 1 "register_operand" ""))
14662 (use (match_operand:SF 2 "register_operand" ""))]
14663 "TARGET_USE_FANCY_MATH_387
14664 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14665 && flag_unsafe_math_optimizations"
14667 rtx label = gen_label_rtx ();
14669 rtx op1 = gen_reg_rtx (XFmode);
14670 rtx op2 = gen_reg_rtx (XFmode);
14672 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14673 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14675 emit_label (label);
14677 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14678 ix86_emit_fp_unordered_jump (label);
14680 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14684 (define_expand "fmoddf3"
14685 [(use (match_operand:DF 0 "register_operand" ""))
14686 (use (match_operand:DF 1 "register_operand" ""))
14687 (use (match_operand:DF 2 "register_operand" ""))]
14688 "TARGET_USE_FANCY_MATH_387
14689 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14690 && flag_unsafe_math_optimizations"
14692 rtx label = gen_label_rtx ();
14694 rtx op1 = gen_reg_rtx (XFmode);
14695 rtx op2 = gen_reg_rtx (XFmode);
14697 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14698 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14700 emit_label (label);
14702 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
14703 ix86_emit_fp_unordered_jump (label);
14705 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14709 (define_expand "fmodxf3"
14710 [(use (match_operand:XF 0 "register_operand" ""))
14711 (use (match_operand:XF 1 "register_operand" ""))
14712 (use (match_operand:XF 2 "register_operand" ""))]
14713 "TARGET_USE_FANCY_MATH_387
14714 && flag_unsafe_math_optimizations"
14716 rtx label = gen_label_rtx ();
14718 emit_label (label);
14720 emit_insn (gen_fpremxf4 (operands[1], operands[2],
14721 operands[1], operands[2]));
14722 ix86_emit_fp_unordered_jump (label);
14724 emit_move_insn (operands[0], operands[1]);
14728 (define_insn "fprem1xf4"
14729 [(set (match_operand:XF 0 "register_operand" "=f")
14730 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14731 (match_operand:XF 3 "register_operand" "1")]
14733 (set (match_operand:XF 1 "register_operand" "=u")
14734 (unspec:XF [(match_dup 2) (match_dup 3)]
14736 (set (reg:CCFP FPSR_REG)
14737 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
14738 "TARGET_USE_FANCY_MATH_387
14739 && flag_unsafe_math_optimizations"
14741 [(set_attr "type" "fpspc")
14742 (set_attr "mode" "XF")])
14744 (define_expand "dremsf3"
14745 [(use (match_operand:SF 0 "register_operand" ""))
14746 (use (match_operand:SF 1 "register_operand" ""))
14747 (use (match_operand:SF 2 "register_operand" ""))]
14748 "TARGET_USE_FANCY_MATH_387
14749 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14750 && flag_unsafe_math_optimizations"
14752 rtx label = gen_label_rtx ();
14754 rtx op1 = gen_reg_rtx (XFmode);
14755 rtx op2 = gen_reg_rtx (XFmode);
14757 emit_insn(gen_extendsfxf2 (op1, operands[1]));
14758 emit_insn(gen_extendsfxf2 (op2, operands[2]));
14760 emit_label (label);
14762 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14763 ix86_emit_fp_unordered_jump (label);
14765 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
14769 (define_expand "dremdf3"
14770 [(use (match_operand:DF 0 "register_operand" ""))
14771 (use (match_operand:DF 1 "register_operand" ""))
14772 (use (match_operand:DF 2 "register_operand" ""))]
14773 "TARGET_USE_FANCY_MATH_387
14774 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14775 && flag_unsafe_math_optimizations"
14777 rtx label = gen_label_rtx ();
14779 rtx op1 = gen_reg_rtx (XFmode);
14780 rtx op2 = gen_reg_rtx (XFmode);
14782 emit_insn (gen_extenddfxf2 (op1, operands[1]));
14783 emit_insn (gen_extenddfxf2 (op2, operands[2]));
14785 emit_label (label);
14787 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
14788 ix86_emit_fp_unordered_jump (label);
14790 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
14794 (define_expand "dremxf3"
14795 [(use (match_operand:XF 0 "register_operand" ""))
14796 (use (match_operand:XF 1 "register_operand" ""))
14797 (use (match_operand:XF 2 "register_operand" ""))]
14798 "TARGET_USE_FANCY_MATH_387
14799 && flag_unsafe_math_optimizations"
14801 rtx label = gen_label_rtx ();
14803 emit_label (label);
14805 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
14806 operands[1], operands[2]));
14807 ix86_emit_fp_unordered_jump (label);
14809 emit_move_insn (operands[0], operands[1]);
14813 (define_insn "*sindf2"
14814 [(set (match_operand:DF 0 "register_operand" "=f")
14815 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
14816 "TARGET_USE_FANCY_MATH_387
14817 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14818 && flag_unsafe_math_optimizations"
14820 [(set_attr "type" "fpspc")
14821 (set_attr "mode" "DF")])
14823 (define_insn "*sinsf2"
14824 [(set (match_operand:SF 0 "register_operand" "=f")
14825 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
14826 "TARGET_USE_FANCY_MATH_387
14827 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14828 && flag_unsafe_math_optimizations"
14830 [(set_attr "type" "fpspc")
14831 (set_attr "mode" "SF")])
14833 (define_insn "*sinextendsfdf2"
14834 [(set (match_operand:DF 0 "register_operand" "=f")
14835 (unspec:DF [(float_extend:DF
14836 (match_operand:SF 1 "register_operand" "0"))]
14838 "TARGET_USE_FANCY_MATH_387
14839 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14840 && flag_unsafe_math_optimizations"
14842 [(set_attr "type" "fpspc")
14843 (set_attr "mode" "DF")])
14845 (define_insn "*sinxf2"
14846 [(set (match_operand:XF 0 "register_operand" "=f")
14847 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
14848 "TARGET_USE_FANCY_MATH_387
14849 && flag_unsafe_math_optimizations"
14851 [(set_attr "type" "fpspc")
14852 (set_attr "mode" "XF")])
14854 (define_insn "*cosdf2"
14855 [(set (match_operand:DF 0 "register_operand" "=f")
14856 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
14857 "TARGET_USE_FANCY_MATH_387
14858 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14859 && flag_unsafe_math_optimizations"
14861 [(set_attr "type" "fpspc")
14862 (set_attr "mode" "DF")])
14864 (define_insn "*cossf2"
14865 [(set (match_operand:SF 0 "register_operand" "=f")
14866 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
14867 "TARGET_USE_FANCY_MATH_387
14868 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14869 && flag_unsafe_math_optimizations"
14871 [(set_attr "type" "fpspc")
14872 (set_attr "mode" "SF")])
14874 (define_insn "*cosextendsfdf2"
14875 [(set (match_operand:DF 0 "register_operand" "=f")
14876 (unspec:DF [(float_extend:DF
14877 (match_operand:SF 1 "register_operand" "0"))]
14879 "TARGET_USE_FANCY_MATH_387
14880 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14881 && flag_unsafe_math_optimizations"
14883 [(set_attr "type" "fpspc")
14884 (set_attr "mode" "DF")])
14886 (define_insn "*cosxf2"
14887 [(set (match_operand:XF 0 "register_operand" "=f")
14888 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
14889 "TARGET_USE_FANCY_MATH_387
14890 && flag_unsafe_math_optimizations"
14892 [(set_attr "type" "fpspc")
14893 (set_attr "mode" "XF")])
14895 ;; With sincos pattern defined, sin and cos builtin function will be
14896 ;; expanded to sincos pattern with one of its outputs left unused.
14897 ;; Cse pass will detected, if two sincos patterns can be combined,
14898 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14899 ;; depending on the unused output.
14901 (define_insn "sincosdf3"
14902 [(set (match_operand:DF 0 "register_operand" "=f")
14903 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
14904 UNSPEC_SINCOS_COS))
14905 (set (match_operand:DF 1 "register_operand" "=u")
14906 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14907 "TARGET_USE_FANCY_MATH_387
14908 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14909 && flag_unsafe_math_optimizations"
14911 [(set_attr "type" "fpspc")
14912 (set_attr "mode" "DF")])
14915 [(set (match_operand:DF 0 "register_operand" "")
14916 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14917 UNSPEC_SINCOS_COS))
14918 (set (match_operand:DF 1 "register_operand" "")
14919 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14920 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14921 && !reload_completed && !reload_in_progress"
14922 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
14926 [(set (match_operand:DF 0 "register_operand" "")
14927 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
14928 UNSPEC_SINCOS_COS))
14929 (set (match_operand:DF 1 "register_operand" "")
14930 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14931 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14932 && !reload_completed && !reload_in_progress"
14933 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
14936 (define_insn "sincossf3"
14937 [(set (match_operand:SF 0 "register_operand" "=f")
14938 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
14939 UNSPEC_SINCOS_COS))
14940 (set (match_operand:SF 1 "register_operand" "=u")
14941 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14942 "TARGET_USE_FANCY_MATH_387
14943 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14944 && flag_unsafe_math_optimizations"
14946 [(set_attr "type" "fpspc")
14947 (set_attr "mode" "SF")])
14950 [(set (match_operand:SF 0 "register_operand" "")
14951 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14952 UNSPEC_SINCOS_COS))
14953 (set (match_operand:SF 1 "register_operand" "")
14954 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14955 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14956 && !reload_completed && !reload_in_progress"
14957 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
14961 [(set (match_operand:SF 0 "register_operand" "")
14962 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
14963 UNSPEC_SINCOS_COS))
14964 (set (match_operand:SF 1 "register_operand" "")
14965 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14966 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14967 && !reload_completed && !reload_in_progress"
14968 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
14971 (define_insn "*sincosextendsfdf3"
14972 [(set (match_operand:DF 0 "register_operand" "=f")
14973 (unspec:DF [(float_extend:DF
14974 (match_operand:SF 2 "register_operand" "0"))]
14975 UNSPEC_SINCOS_COS))
14976 (set (match_operand:DF 1 "register_operand" "=u")
14977 (unspec:DF [(float_extend:DF
14978 (match_dup 2))] UNSPEC_SINCOS_SIN))]
14979 "TARGET_USE_FANCY_MATH_387
14980 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
14981 && flag_unsafe_math_optimizations"
14983 [(set_attr "type" "fpspc")
14984 (set_attr "mode" "DF")])
14987 [(set (match_operand:DF 0 "register_operand" "")
14988 (unspec:DF [(float_extend:DF
14989 (match_operand:SF 2 "register_operand" ""))]
14990 UNSPEC_SINCOS_COS))
14991 (set (match_operand:DF 1 "register_operand" "")
14992 (unspec:DF [(float_extend:DF
14993 (match_dup 2))] UNSPEC_SINCOS_SIN))]
14994 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14995 && !reload_completed && !reload_in_progress"
14996 [(set (match_dup 1) (unspec:DF [(float_extend:DF
14997 (match_dup 2))] UNSPEC_SIN))]
15001 [(set (match_operand:DF 0 "register_operand" "")
15002 (unspec:DF [(float_extend:DF
15003 (match_operand:SF 2 "register_operand" ""))]
15004 UNSPEC_SINCOS_COS))
15005 (set (match_operand:DF 1 "register_operand" "")
15006 (unspec:DF [(float_extend:DF
15007 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15008 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15009 && !reload_completed && !reload_in_progress"
15010 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15011 (match_dup 2))] UNSPEC_COS))]
15014 (define_insn "sincosxf3"
15015 [(set (match_operand:XF 0 "register_operand" "=f")
15016 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15017 UNSPEC_SINCOS_COS))
15018 (set (match_operand:XF 1 "register_operand" "=u")
15019 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15020 "TARGET_USE_FANCY_MATH_387
15021 && flag_unsafe_math_optimizations"
15023 [(set_attr "type" "fpspc")
15024 (set_attr "mode" "XF")])
15027 [(set (match_operand:XF 0 "register_operand" "")
15028 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15029 UNSPEC_SINCOS_COS))
15030 (set (match_operand:XF 1 "register_operand" "")
15031 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15032 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15033 && !reload_completed && !reload_in_progress"
15034 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15038 [(set (match_operand:XF 0 "register_operand" "")
15039 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15040 UNSPEC_SINCOS_COS))
15041 (set (match_operand:XF 1 "register_operand" "")
15042 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15043 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15044 && !reload_completed && !reload_in_progress"
15045 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15048 (define_insn "*tandf3_1"
15049 [(set (match_operand:DF 0 "register_operand" "=f")
15050 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15052 (set (match_operand:DF 1 "register_operand" "=u")
15053 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15054 "TARGET_USE_FANCY_MATH_387
15055 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15056 && flag_unsafe_math_optimizations"
15058 [(set_attr "type" "fpspc")
15059 (set_attr "mode" "DF")])
15061 ;; optimize sequence: fptan
15064 ;; into fptan insn.
15067 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15068 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15070 (set (match_operand:DF 1 "register_operand" "")
15071 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15073 (match_operand:DF 3 "immediate_operand" ""))]
15074 "standard_80387_constant_p (operands[3]) == 2"
15075 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15076 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15079 (define_expand "tandf2"
15080 [(parallel [(set (match_dup 2)
15081 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15083 (set (match_operand:DF 0 "register_operand" "")
15084 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15085 "TARGET_USE_FANCY_MATH_387
15086 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15087 && flag_unsafe_math_optimizations"
15089 operands[2] = gen_reg_rtx (DFmode);
15092 (define_insn "*tansf3_1"
15093 [(set (match_operand:SF 0 "register_operand" "=f")
15094 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15096 (set (match_operand:SF 1 "register_operand" "=u")
15097 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15098 "TARGET_USE_FANCY_MATH_387
15099 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15100 && flag_unsafe_math_optimizations"
15102 [(set_attr "type" "fpspc")
15103 (set_attr "mode" "SF")])
15105 ;; optimize sequence: fptan
15108 ;; into fptan insn.
15111 [(parallel[(set (match_operand:SF 0 "register_operand" "")
15112 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15114 (set (match_operand:SF 1 "register_operand" "")
15115 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
15117 (match_operand:SF 3 "immediate_operand" ""))]
15118 "standard_80387_constant_p (operands[3]) == 2"
15119 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
15120 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15123 (define_expand "tansf2"
15124 [(parallel [(set (match_dup 2)
15125 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
15127 (set (match_operand:SF 0 "register_operand" "")
15128 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15129 "TARGET_USE_FANCY_MATH_387
15130 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15131 && flag_unsafe_math_optimizations"
15133 operands[2] = gen_reg_rtx (SFmode);
15136 (define_insn "*tanxf3_1"
15137 [(set (match_operand:XF 0 "register_operand" "=f")
15138 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15140 (set (match_operand:XF 1 "register_operand" "=u")
15141 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
15142 "TARGET_USE_FANCY_MATH_387
15143 && flag_unsafe_math_optimizations"
15145 [(set_attr "type" "fpspc")
15146 (set_attr "mode" "XF")])
15148 ;; optimize sequence: fptan
15151 ;; into fptan insn.
15154 [(parallel[(set (match_operand:XF 0 "register_operand" "")
15155 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15157 (set (match_operand:XF 1 "register_operand" "")
15158 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
15160 (match_operand:XF 3 "immediate_operand" ""))]
15161 "standard_80387_constant_p (operands[3]) == 2"
15162 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
15163 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15166 (define_expand "tanxf2"
15167 [(parallel [(set (match_dup 2)
15168 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15170 (set (match_operand:XF 0 "register_operand" "")
15171 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15172 "TARGET_USE_FANCY_MATH_387
15173 && flag_unsafe_math_optimizations"
15175 operands[2] = gen_reg_rtx (XFmode);
15178 (define_insn "atan2df3_1"
15179 [(set (match_operand:DF 0 "register_operand" "=f")
15180 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
15181 (match_operand:DF 1 "register_operand" "u")]
15183 (clobber (match_scratch:DF 3 "=1"))]
15184 "TARGET_USE_FANCY_MATH_387
15185 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15186 && flag_unsafe_math_optimizations"
15188 [(set_attr "type" "fpspc")
15189 (set_attr "mode" "DF")])
15191 (define_expand "atan2df3"
15192 [(use (match_operand:DF 0 "register_operand" ""))
15193 (use (match_operand:DF 2 "register_operand" ""))
15194 (use (match_operand:DF 1 "register_operand" ""))]
15195 "TARGET_USE_FANCY_MATH_387
15196 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15197 && flag_unsafe_math_optimizations"
15199 rtx copy = gen_reg_rtx (DFmode);
15200 emit_move_insn (copy, operands[1]);
15201 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
15205 (define_expand "atandf2"
15206 [(parallel [(set (match_operand:DF 0 "register_operand" "")
15207 (unspec:DF [(match_dup 2)
15208 (match_operand:DF 1 "register_operand" "")]
15210 (clobber (match_scratch:DF 3 ""))])]
15211 "TARGET_USE_FANCY_MATH_387
15212 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15213 && flag_unsafe_math_optimizations"
15215 operands[2] = gen_reg_rtx (DFmode);
15216 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
15219 (define_insn "atan2sf3_1"
15220 [(set (match_operand:SF 0 "register_operand" "=f")
15221 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
15222 (match_operand:SF 1 "register_operand" "u")]
15224 (clobber (match_scratch:SF 3 "=1"))]
15225 "TARGET_USE_FANCY_MATH_387
15226 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15227 && flag_unsafe_math_optimizations"
15229 [(set_attr "type" "fpspc")
15230 (set_attr "mode" "SF")])
15232 (define_expand "atan2sf3"
15233 [(use (match_operand:SF 0 "register_operand" ""))
15234 (use (match_operand:SF 2 "register_operand" ""))
15235 (use (match_operand:SF 1 "register_operand" ""))]
15236 "TARGET_USE_FANCY_MATH_387
15237 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15238 && flag_unsafe_math_optimizations"
15240 rtx copy = gen_reg_rtx (SFmode);
15241 emit_move_insn (copy, operands[1]);
15242 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
15246 (define_expand "atansf2"
15247 [(parallel [(set (match_operand:SF 0 "register_operand" "")
15248 (unspec:SF [(match_dup 2)
15249 (match_operand:SF 1 "register_operand" "")]
15251 (clobber (match_scratch:SF 3 ""))])]
15252 "TARGET_USE_FANCY_MATH_387
15253 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15254 && flag_unsafe_math_optimizations"
15256 operands[2] = gen_reg_rtx (SFmode);
15257 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
15260 (define_insn "atan2xf3_1"
15261 [(set (match_operand:XF 0 "register_operand" "=f")
15262 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15263 (match_operand:XF 1 "register_operand" "u")]
15265 (clobber (match_scratch:XF 3 "=1"))]
15266 "TARGET_USE_FANCY_MATH_387
15267 && flag_unsafe_math_optimizations"
15269 [(set_attr "type" "fpspc")
15270 (set_attr "mode" "XF")])
15272 (define_expand "atan2xf3"
15273 [(use (match_operand:XF 0 "register_operand" ""))
15274 (use (match_operand:XF 2 "register_operand" ""))
15275 (use (match_operand:XF 1 "register_operand" ""))]
15276 "TARGET_USE_FANCY_MATH_387
15277 && flag_unsafe_math_optimizations"
15279 rtx copy = gen_reg_rtx (XFmode);
15280 emit_move_insn (copy, operands[1]);
15281 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
15285 (define_expand "atanxf2"
15286 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15287 (unspec:XF [(match_dup 2)
15288 (match_operand:XF 1 "register_operand" "")]
15290 (clobber (match_scratch:XF 3 ""))])]
15291 "TARGET_USE_FANCY_MATH_387
15292 && flag_unsafe_math_optimizations"
15294 operands[2] = gen_reg_rtx (XFmode);
15295 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15298 (define_expand "asindf2"
15299 [(set (match_dup 2)
15300 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15301 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15302 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15303 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15304 (parallel [(set (match_dup 7)
15305 (unspec:XF [(match_dup 6) (match_dup 2)]
15307 (clobber (match_scratch:XF 8 ""))])
15308 (set (match_operand:DF 0 "register_operand" "")
15309 (float_truncate:DF (match_dup 7)))]
15310 "TARGET_USE_FANCY_MATH_387
15311 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15312 && flag_unsafe_math_optimizations"
15316 for (i=2; i<8; i++)
15317 operands[i] = gen_reg_rtx (XFmode);
15319 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15322 (define_expand "asinsf2"
15323 [(set (match_dup 2)
15324 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15325 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15326 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15327 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15328 (parallel [(set (match_dup 7)
15329 (unspec:XF [(match_dup 6) (match_dup 2)]
15331 (clobber (match_scratch:XF 8 ""))])
15332 (set (match_operand:SF 0 "register_operand" "")
15333 (float_truncate:SF (match_dup 7)))]
15334 "TARGET_USE_FANCY_MATH_387
15335 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15336 && flag_unsafe_math_optimizations"
15340 for (i=2; i<8; i++)
15341 operands[i] = gen_reg_rtx (XFmode);
15343 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15346 (define_expand "asinxf2"
15347 [(set (match_dup 2)
15348 (mult:XF (match_operand:XF 1 "register_operand" "")
15350 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15351 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15352 (parallel [(set (match_operand:XF 0 "register_operand" "")
15353 (unspec:XF [(match_dup 5) (match_dup 1)]
15355 (clobber (match_scratch:XF 6 ""))])]
15356 "TARGET_USE_FANCY_MATH_387
15357 && flag_unsafe_math_optimizations"
15361 for (i=2; i<6; i++)
15362 operands[i] = gen_reg_rtx (XFmode);
15364 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15367 (define_expand "acosdf2"
15368 [(set (match_dup 2)
15369 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15370 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15371 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15372 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15373 (parallel [(set (match_dup 7)
15374 (unspec:XF [(match_dup 2) (match_dup 6)]
15376 (clobber (match_scratch:XF 8 ""))])
15377 (set (match_operand:DF 0 "register_operand" "")
15378 (float_truncate:DF (match_dup 7)))]
15379 "TARGET_USE_FANCY_MATH_387
15380 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15381 && flag_unsafe_math_optimizations"
15385 for (i=2; i<8; i++)
15386 operands[i] = gen_reg_rtx (XFmode);
15388 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15391 (define_expand "acossf2"
15392 [(set (match_dup 2)
15393 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15394 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
15395 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
15396 (set (match_dup 6) (sqrt:XF (match_dup 5)))
15397 (parallel [(set (match_dup 7)
15398 (unspec:XF [(match_dup 2) (match_dup 6)]
15400 (clobber (match_scratch:XF 8 ""))])
15401 (set (match_operand:SF 0 "register_operand" "")
15402 (float_truncate:SF (match_dup 7)))]
15403 "TARGET_USE_FANCY_MATH_387
15404 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15405 && flag_unsafe_math_optimizations"
15409 for (i=2; i<8; i++)
15410 operands[i] = gen_reg_rtx (XFmode);
15412 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
15415 (define_expand "acosxf2"
15416 [(set (match_dup 2)
15417 (mult:XF (match_operand:XF 1 "register_operand" "")
15419 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15420 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15421 (parallel [(set (match_operand:XF 0 "register_operand" "")
15422 (unspec:XF [(match_dup 1) (match_dup 5)]
15424 (clobber (match_scratch:XF 6 ""))])]
15425 "TARGET_USE_FANCY_MATH_387
15426 && flag_unsafe_math_optimizations"
15430 for (i=2; i<6; i++)
15431 operands[i] = gen_reg_rtx (XFmode);
15433 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15436 (define_insn "fyl2x_xf3"
15437 [(set (match_operand:XF 0 "register_operand" "=f")
15438 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15439 (match_operand:XF 1 "register_operand" "u")]
15441 (clobber (match_scratch:XF 3 "=1"))]
15442 "TARGET_USE_FANCY_MATH_387
15443 && flag_unsafe_math_optimizations"
15445 [(set_attr "type" "fpspc")
15446 (set_attr "mode" "XF")])
15448 (define_expand "logsf2"
15449 [(set (match_dup 2)
15450 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15451 (parallel [(set (match_dup 4)
15452 (unspec:XF [(match_dup 2)
15453 (match_dup 3)] UNSPEC_FYL2X))
15454 (clobber (match_scratch:XF 5 ""))])
15455 (set (match_operand:SF 0 "register_operand" "")
15456 (float_truncate:SF (match_dup 4)))]
15457 "TARGET_USE_FANCY_MATH_387
15458 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15459 && flag_unsafe_math_optimizations"
15463 operands[2] = gen_reg_rtx (XFmode);
15464 operands[3] = gen_reg_rtx (XFmode);
15465 operands[4] = gen_reg_rtx (XFmode);
15467 temp = standard_80387_constant_rtx (4); /* fldln2 */
15468 emit_move_insn (operands[3], temp);
15471 (define_expand "logdf2"
15472 [(set (match_dup 2)
15473 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15474 (parallel [(set (match_dup 4)
15475 (unspec:XF [(match_dup 2)
15476 (match_dup 3)] UNSPEC_FYL2X))
15477 (clobber (match_scratch:XF 5 ""))])
15478 (set (match_operand:DF 0 "register_operand" "")
15479 (float_truncate:DF (match_dup 4)))]
15480 "TARGET_USE_FANCY_MATH_387
15481 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15482 && flag_unsafe_math_optimizations"
15486 operands[2] = gen_reg_rtx (XFmode);
15487 operands[3] = gen_reg_rtx (XFmode);
15488 operands[4] = gen_reg_rtx (XFmode);
15490 temp = standard_80387_constant_rtx (4); /* fldln2 */
15491 emit_move_insn (operands[3], temp);
15494 (define_expand "logxf2"
15495 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15496 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15497 (match_dup 2)] UNSPEC_FYL2X))
15498 (clobber (match_scratch:XF 3 ""))])]
15499 "TARGET_USE_FANCY_MATH_387
15500 && flag_unsafe_math_optimizations"
15504 operands[2] = gen_reg_rtx (XFmode);
15505 temp = standard_80387_constant_rtx (4); /* fldln2 */
15506 emit_move_insn (operands[2], temp);
15509 (define_expand "log10sf2"
15510 [(set (match_dup 2)
15511 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15512 (parallel [(set (match_dup 4)
15513 (unspec:XF [(match_dup 2)
15514 (match_dup 3)] UNSPEC_FYL2X))
15515 (clobber (match_scratch:XF 5 ""))])
15516 (set (match_operand:SF 0 "register_operand" "")
15517 (float_truncate:SF (match_dup 4)))]
15518 "TARGET_USE_FANCY_MATH_387
15519 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15520 && flag_unsafe_math_optimizations"
15524 operands[2] = gen_reg_rtx (XFmode);
15525 operands[3] = gen_reg_rtx (XFmode);
15526 operands[4] = gen_reg_rtx (XFmode);
15528 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15529 emit_move_insn (operands[3], temp);
15532 (define_expand "log10df2"
15533 [(set (match_dup 2)
15534 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15535 (parallel [(set (match_dup 4)
15536 (unspec:XF [(match_dup 2)
15537 (match_dup 3)] UNSPEC_FYL2X))
15538 (clobber (match_scratch:XF 5 ""))])
15539 (set (match_operand:DF 0 "register_operand" "")
15540 (float_truncate:DF (match_dup 4)))]
15541 "TARGET_USE_FANCY_MATH_387
15542 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15543 && flag_unsafe_math_optimizations"
15547 operands[2] = gen_reg_rtx (XFmode);
15548 operands[3] = gen_reg_rtx (XFmode);
15549 operands[4] = gen_reg_rtx (XFmode);
15551 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15552 emit_move_insn (operands[3], temp);
15555 (define_expand "log10xf2"
15556 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15557 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15558 (match_dup 2)] UNSPEC_FYL2X))
15559 (clobber (match_scratch:XF 3 ""))])]
15560 "TARGET_USE_FANCY_MATH_387
15561 && flag_unsafe_math_optimizations"
15565 operands[2] = gen_reg_rtx (XFmode);
15566 temp = standard_80387_constant_rtx (3); /* fldlg2 */
15567 emit_move_insn (operands[2], temp);
15570 (define_expand "log2sf2"
15571 [(set (match_dup 2)
15572 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15573 (parallel [(set (match_dup 4)
15574 (unspec:XF [(match_dup 2)
15575 (match_dup 3)] UNSPEC_FYL2X))
15576 (clobber (match_scratch:XF 5 ""))])
15577 (set (match_operand:SF 0 "register_operand" "")
15578 (float_truncate:SF (match_dup 4)))]
15579 "TARGET_USE_FANCY_MATH_387
15580 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15581 && flag_unsafe_math_optimizations"
15583 operands[2] = gen_reg_rtx (XFmode);
15584 operands[3] = gen_reg_rtx (XFmode);
15585 operands[4] = gen_reg_rtx (XFmode);
15587 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15590 (define_expand "log2df2"
15591 [(set (match_dup 2)
15592 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15593 (parallel [(set (match_dup 4)
15594 (unspec:XF [(match_dup 2)
15595 (match_dup 3)] UNSPEC_FYL2X))
15596 (clobber (match_scratch:XF 5 ""))])
15597 (set (match_operand:DF 0 "register_operand" "")
15598 (float_truncate:DF (match_dup 4)))]
15599 "TARGET_USE_FANCY_MATH_387
15600 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15601 && flag_unsafe_math_optimizations"
15603 operands[2] = gen_reg_rtx (XFmode);
15604 operands[3] = gen_reg_rtx (XFmode);
15605 operands[4] = gen_reg_rtx (XFmode);
15607 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15610 (define_expand "log2xf2"
15611 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15612 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15613 (match_dup 2)] UNSPEC_FYL2X))
15614 (clobber (match_scratch:XF 3 ""))])]
15615 "TARGET_USE_FANCY_MATH_387
15616 && flag_unsafe_math_optimizations"
15618 operands[2] = gen_reg_rtx (XFmode);
15619 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15622 (define_insn "fyl2xp1_xf3"
15623 [(set (match_operand:XF 0 "register_operand" "=f")
15624 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15625 (match_operand:XF 1 "register_operand" "u")]
15627 (clobber (match_scratch:XF 3 "=1"))]
15628 "TARGET_USE_FANCY_MATH_387
15629 && flag_unsafe_math_optimizations"
15631 [(set_attr "type" "fpspc")
15632 (set_attr "mode" "XF")])
15634 (define_expand "log1psf2"
15635 [(use (match_operand:SF 0 "register_operand" ""))
15636 (use (match_operand:SF 1 "register_operand" ""))]
15637 "TARGET_USE_FANCY_MATH_387
15638 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15639 && flag_unsafe_math_optimizations"
15641 rtx op0 = gen_reg_rtx (XFmode);
15642 rtx op1 = gen_reg_rtx (XFmode);
15644 emit_insn (gen_extendsfxf2 (op1, operands[1]));
15645 ix86_emit_i387_log1p (op0, op1);
15646 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
15650 (define_expand "log1pdf2"
15651 [(use (match_operand:DF 0 "register_operand" ""))
15652 (use (match_operand:DF 1 "register_operand" ""))]
15653 "TARGET_USE_FANCY_MATH_387
15654 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15655 && flag_unsafe_math_optimizations"
15657 rtx op0 = gen_reg_rtx (XFmode);
15658 rtx op1 = gen_reg_rtx (XFmode);
15660 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15661 ix86_emit_i387_log1p (op0, op1);
15662 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
15666 (define_expand "log1pxf2"
15667 [(use (match_operand:XF 0 "register_operand" ""))
15668 (use (match_operand:XF 1 "register_operand" ""))]
15669 "TARGET_USE_FANCY_MATH_387
15670 && flag_unsafe_math_optimizations"
15672 ix86_emit_i387_log1p (operands[0], operands[1]);
15676 (define_insn "*fxtractxf3"
15677 [(set (match_operand:XF 0 "register_operand" "=f")
15678 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15679 UNSPEC_XTRACT_FRACT))
15680 (set (match_operand:XF 1 "register_operand" "=u")
15681 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15682 "TARGET_USE_FANCY_MATH_387
15683 && flag_unsafe_math_optimizations"
15685 [(set_attr "type" "fpspc")
15686 (set_attr "mode" "XF")])
15688 (define_expand "logbsf2"
15689 [(set (match_dup 2)
15690 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15691 (parallel [(set (match_dup 3)
15692 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15694 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15695 (set (match_operand:SF 0 "register_operand" "")
15696 (float_truncate:SF (match_dup 4)))]
15697 "TARGET_USE_FANCY_MATH_387
15698 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15699 && flag_unsafe_math_optimizations"
15701 operands[2] = gen_reg_rtx (XFmode);
15702 operands[3] = gen_reg_rtx (XFmode);
15703 operands[4] = gen_reg_rtx (XFmode);
15706 (define_expand "logbdf2"
15707 [(set (match_dup 2)
15708 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15709 (parallel [(set (match_dup 3)
15710 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
15712 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
15713 (set (match_operand:DF 0 "register_operand" "")
15714 (float_truncate:DF (match_dup 4)))]
15715 "TARGET_USE_FANCY_MATH_387
15716 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15717 && flag_unsafe_math_optimizations"
15719 operands[2] = gen_reg_rtx (XFmode);
15720 operands[3] = gen_reg_rtx (XFmode);
15721 operands[4] = gen_reg_rtx (XFmode);
15724 (define_expand "logbxf2"
15725 [(parallel [(set (match_dup 2)
15726 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15727 UNSPEC_XTRACT_FRACT))
15728 (set (match_operand:XF 0 "register_operand" "")
15729 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15730 "TARGET_USE_FANCY_MATH_387
15731 && flag_unsafe_math_optimizations"
15733 operands[2] = gen_reg_rtx (XFmode);
15736 (define_expand "ilogbsi2"
15737 [(parallel [(set (match_dup 2)
15738 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15739 UNSPEC_XTRACT_FRACT))
15740 (set (match_operand:XF 3 "register_operand" "")
15741 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
15742 (parallel [(set (match_operand:SI 0 "register_operand" "")
15743 (fix:SI (match_dup 3)))
15744 (clobber (reg:CC FLAGS_REG))])]
15745 "TARGET_USE_FANCY_MATH_387
15746 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15747 && flag_unsafe_math_optimizations"
15749 operands[2] = gen_reg_rtx (XFmode);
15750 operands[3] = gen_reg_rtx (XFmode);
15753 (define_insn "*f2xm1xf2"
15754 [(set (match_operand:XF 0 "register_operand" "=f")
15755 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15757 "TARGET_USE_FANCY_MATH_387
15758 && flag_unsafe_math_optimizations"
15760 [(set_attr "type" "fpspc")
15761 (set_attr "mode" "XF")])
15763 (define_insn "*fscalexf4"
15764 [(set (match_operand:XF 0 "register_operand" "=f")
15765 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15766 (match_operand:XF 3 "register_operand" "1")]
15767 UNSPEC_FSCALE_FRACT))
15768 (set (match_operand:XF 1 "register_operand" "=u")
15769 (unspec:XF [(match_dup 2) (match_dup 3)]
15770 UNSPEC_FSCALE_EXP))]
15771 "TARGET_USE_FANCY_MATH_387
15772 && flag_unsafe_math_optimizations"
15774 [(set_attr "type" "fpspc")
15775 (set_attr "mode" "XF")])
15777 (define_expand "expsf2"
15778 [(set (match_dup 2)
15779 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15780 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15781 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15782 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15783 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15784 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15785 (parallel [(set (match_dup 10)
15786 (unspec:XF [(match_dup 9) (match_dup 5)]
15787 UNSPEC_FSCALE_FRACT))
15788 (set (match_dup 11)
15789 (unspec:XF [(match_dup 9) (match_dup 5)]
15790 UNSPEC_FSCALE_EXP))])
15791 (set (match_operand:SF 0 "register_operand" "")
15792 (float_truncate:SF (match_dup 10)))]
15793 "TARGET_USE_FANCY_MATH_387
15794 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15795 && flag_unsafe_math_optimizations"
15800 for (i=2; i<12; i++)
15801 operands[i] = gen_reg_rtx (XFmode);
15802 temp = standard_80387_constant_rtx (5); /* fldl2e */
15803 emit_move_insn (operands[3], temp);
15804 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15807 (define_expand "expdf2"
15808 [(set (match_dup 2)
15809 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15810 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15811 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15812 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15813 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15814 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15815 (parallel [(set (match_dup 10)
15816 (unspec:XF [(match_dup 9) (match_dup 5)]
15817 UNSPEC_FSCALE_FRACT))
15818 (set (match_dup 11)
15819 (unspec:XF [(match_dup 9) (match_dup 5)]
15820 UNSPEC_FSCALE_EXP))])
15821 (set (match_operand:DF 0 "register_operand" "")
15822 (float_truncate:DF (match_dup 10)))]
15823 "TARGET_USE_FANCY_MATH_387
15824 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15825 && flag_unsafe_math_optimizations"
15830 for (i=2; i<12; i++)
15831 operands[i] = gen_reg_rtx (XFmode);
15832 temp = standard_80387_constant_rtx (5); /* fldl2e */
15833 emit_move_insn (operands[3], temp);
15834 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15837 (define_expand "expxf2"
15838 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15840 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15841 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15842 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15843 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15844 (parallel [(set (match_operand:XF 0 "register_operand" "")
15845 (unspec:XF [(match_dup 8) (match_dup 4)]
15846 UNSPEC_FSCALE_FRACT))
15848 (unspec:XF [(match_dup 8) (match_dup 4)]
15849 UNSPEC_FSCALE_EXP))])]
15850 "TARGET_USE_FANCY_MATH_387
15851 && flag_unsafe_math_optimizations"
15856 for (i=2; i<10; i++)
15857 operands[i] = gen_reg_rtx (XFmode);
15858 temp = standard_80387_constant_rtx (5); /* fldl2e */
15859 emit_move_insn (operands[2], temp);
15860 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15863 (define_expand "exp10sf2"
15864 [(set (match_dup 2)
15865 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15866 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15867 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15868 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15869 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15870 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15871 (parallel [(set (match_dup 10)
15872 (unspec:XF [(match_dup 9) (match_dup 5)]
15873 UNSPEC_FSCALE_FRACT))
15874 (set (match_dup 11)
15875 (unspec:XF [(match_dup 9) (match_dup 5)]
15876 UNSPEC_FSCALE_EXP))])
15877 (set (match_operand:SF 0 "register_operand" "")
15878 (float_truncate:SF (match_dup 10)))]
15879 "TARGET_USE_FANCY_MATH_387
15880 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15881 && flag_unsafe_math_optimizations"
15886 for (i=2; i<12; i++)
15887 operands[i] = gen_reg_rtx (XFmode);
15888 temp = standard_80387_constant_rtx (6); /* fldl2t */
15889 emit_move_insn (operands[3], temp);
15890 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15893 (define_expand "exp10df2"
15894 [(set (match_dup 2)
15895 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15896 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
15897 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
15898 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
15899 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
15900 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
15901 (parallel [(set (match_dup 10)
15902 (unspec:XF [(match_dup 9) (match_dup 5)]
15903 UNSPEC_FSCALE_FRACT))
15904 (set (match_dup 11)
15905 (unspec:XF [(match_dup 9) (match_dup 5)]
15906 UNSPEC_FSCALE_EXP))])
15907 (set (match_operand:DF 0 "register_operand" "")
15908 (float_truncate:DF (match_dup 10)))]
15909 "TARGET_USE_FANCY_MATH_387
15910 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15911 && flag_unsafe_math_optimizations"
15916 for (i=2; i<12; i++)
15917 operands[i] = gen_reg_rtx (XFmode);
15918 temp = standard_80387_constant_rtx (6); /* fldl2t */
15919 emit_move_insn (operands[3], temp);
15920 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
15923 (define_expand "exp10xf2"
15924 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
15926 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15927 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15928 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15929 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15930 (parallel [(set (match_operand:XF 0 "register_operand" "")
15931 (unspec:XF [(match_dup 8) (match_dup 4)]
15932 UNSPEC_FSCALE_FRACT))
15934 (unspec:XF [(match_dup 8) (match_dup 4)]
15935 UNSPEC_FSCALE_EXP))])]
15936 "TARGET_USE_FANCY_MATH_387
15937 && flag_unsafe_math_optimizations"
15942 for (i=2; i<10; i++)
15943 operands[i] = gen_reg_rtx (XFmode);
15944 temp = standard_80387_constant_rtx (6); /* fldl2t */
15945 emit_move_insn (operands[2], temp);
15946 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15949 (define_expand "exp2sf2"
15950 [(set (match_dup 2)
15951 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
15952 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15953 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15954 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15955 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15956 (parallel [(set (match_dup 8)
15957 (unspec:XF [(match_dup 7) (match_dup 3)]
15958 UNSPEC_FSCALE_FRACT))
15960 (unspec:XF [(match_dup 7) (match_dup 3)]
15961 UNSPEC_FSCALE_EXP))])
15962 (set (match_operand:SF 0 "register_operand" "")
15963 (float_truncate:SF (match_dup 8)))]
15964 "TARGET_USE_FANCY_MATH_387
15965 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15966 && flag_unsafe_math_optimizations"
15970 for (i=2; i<10; i++)
15971 operands[i] = gen_reg_rtx (XFmode);
15972 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
15975 (define_expand "exp2df2"
15976 [(set (match_dup 2)
15977 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
15978 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
15979 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
15980 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
15981 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
15982 (parallel [(set (match_dup 8)
15983 (unspec:XF [(match_dup 7) (match_dup 3)]
15984 UNSPEC_FSCALE_FRACT))
15986 (unspec:XF [(match_dup 7) (match_dup 3)]
15987 UNSPEC_FSCALE_EXP))])
15988 (set (match_operand:DF 0 "register_operand" "")
15989 (float_truncate:DF (match_dup 8)))]
15990 "TARGET_USE_FANCY_MATH_387
15991 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15992 && flag_unsafe_math_optimizations"
15996 for (i=2; i<10; i++)
15997 operands[i] = gen_reg_rtx (XFmode);
15998 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16001 (define_expand "exp2xf2"
16002 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16003 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16004 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16005 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16006 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16007 (parallel [(set (match_operand:XF 0 "register_operand" "")
16008 (unspec:XF [(match_dup 7) (match_dup 3)]
16009 UNSPEC_FSCALE_FRACT))
16011 (unspec:XF [(match_dup 7) (match_dup 3)]
16012 UNSPEC_FSCALE_EXP))])]
16013 "TARGET_USE_FANCY_MATH_387
16014 && flag_unsafe_math_optimizations"
16018 for (i=2; i<9; i++)
16019 operands[i] = gen_reg_rtx (XFmode);
16020 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16023 (define_expand "expm1df2"
16024 [(set (match_dup 2)
16025 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16026 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16027 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16028 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16029 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16030 (parallel [(set (match_dup 8)
16031 (unspec:XF [(match_dup 7) (match_dup 5)]
16032 UNSPEC_FSCALE_FRACT))
16034 (unspec:XF [(match_dup 7) (match_dup 5)]
16035 UNSPEC_FSCALE_EXP))])
16036 (parallel [(set (match_dup 11)
16037 (unspec:XF [(match_dup 10) (match_dup 9)]
16038 UNSPEC_FSCALE_FRACT))
16039 (set (match_dup 12)
16040 (unspec:XF [(match_dup 10) (match_dup 9)]
16041 UNSPEC_FSCALE_EXP))])
16042 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16043 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16044 (set (match_operand:DF 0 "register_operand" "")
16045 (float_truncate:DF (match_dup 14)))]
16046 "TARGET_USE_FANCY_MATH_387
16047 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16048 && flag_unsafe_math_optimizations"
16053 for (i=2; i<15; i++)
16054 operands[i] = gen_reg_rtx (XFmode);
16055 temp = standard_80387_constant_rtx (5); /* fldl2e */
16056 emit_move_insn (operands[3], temp);
16057 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16060 (define_expand "expm1sf2"
16061 [(set (match_dup 2)
16062 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16063 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16064 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16065 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16066 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16067 (parallel [(set (match_dup 8)
16068 (unspec:XF [(match_dup 7) (match_dup 5)]
16069 UNSPEC_FSCALE_FRACT))
16071 (unspec:XF [(match_dup 7) (match_dup 5)]
16072 UNSPEC_FSCALE_EXP))])
16073 (parallel [(set (match_dup 11)
16074 (unspec:XF [(match_dup 10) (match_dup 9)]
16075 UNSPEC_FSCALE_FRACT))
16076 (set (match_dup 12)
16077 (unspec:XF [(match_dup 10) (match_dup 9)]
16078 UNSPEC_FSCALE_EXP))])
16079 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16080 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16081 (set (match_operand:SF 0 "register_operand" "")
16082 (float_truncate:SF (match_dup 14)))]
16083 "TARGET_USE_FANCY_MATH_387
16084 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16085 && flag_unsafe_math_optimizations"
16090 for (i=2; i<15; i++)
16091 operands[i] = gen_reg_rtx (XFmode);
16092 temp = standard_80387_constant_rtx (5); /* fldl2e */
16093 emit_move_insn (operands[3], temp);
16094 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16097 (define_expand "expm1xf2"
16098 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16100 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16101 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16102 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16103 (parallel [(set (match_dup 7)
16104 (unspec:XF [(match_dup 6) (match_dup 4)]
16105 UNSPEC_FSCALE_FRACT))
16107 (unspec:XF [(match_dup 6) (match_dup 4)]
16108 UNSPEC_FSCALE_EXP))])
16109 (parallel [(set (match_dup 10)
16110 (unspec:XF [(match_dup 9) (match_dup 8)]
16111 UNSPEC_FSCALE_FRACT))
16112 (set (match_dup 11)
16113 (unspec:XF [(match_dup 9) (match_dup 8)]
16114 UNSPEC_FSCALE_EXP))])
16115 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16116 (set (match_operand:XF 0 "register_operand" "")
16117 (plus:XF (match_dup 12) (match_dup 7)))]
16118 "TARGET_USE_FANCY_MATH_387
16119 && flag_unsafe_math_optimizations"
16124 for (i=2; i<13; i++)
16125 operands[i] = gen_reg_rtx (XFmode);
16126 temp = standard_80387_constant_rtx (5); /* fldl2e */
16127 emit_move_insn (operands[2], temp);
16128 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16131 (define_expand "ldexpdf3"
16132 [(set (match_dup 3)
16133 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16135 (float:XF (match_operand:SI 2 "register_operand" "")))
16136 (parallel [(set (match_dup 5)
16137 (unspec:XF [(match_dup 3) (match_dup 4)]
16138 UNSPEC_FSCALE_FRACT))
16140 (unspec:XF [(match_dup 3) (match_dup 4)]
16141 UNSPEC_FSCALE_EXP))])
16142 (set (match_operand:DF 0 "register_operand" "")
16143 (float_truncate:DF (match_dup 5)))]
16144 "TARGET_USE_FANCY_MATH_387
16145 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16146 && flag_unsafe_math_optimizations"
16150 for (i=3; i<7; i++)
16151 operands[i] = gen_reg_rtx (XFmode);
16154 (define_expand "ldexpsf3"
16155 [(set (match_dup 3)
16156 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16158 (float:XF (match_operand:SI 2 "register_operand" "")))
16159 (parallel [(set (match_dup 5)
16160 (unspec:XF [(match_dup 3) (match_dup 4)]
16161 UNSPEC_FSCALE_FRACT))
16163 (unspec:XF [(match_dup 3) (match_dup 4)]
16164 UNSPEC_FSCALE_EXP))])
16165 (set (match_operand:SF 0 "register_operand" "")
16166 (float_truncate:SF (match_dup 5)))]
16167 "TARGET_USE_FANCY_MATH_387
16168 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16169 && flag_unsafe_math_optimizations"
16173 for (i=3; i<7; i++)
16174 operands[i] = gen_reg_rtx (XFmode);
16177 (define_expand "ldexpxf3"
16178 [(set (match_dup 3)
16179 (float:XF (match_operand:SI 2 "register_operand" "")))
16180 (parallel [(set (match_operand:XF 0 " register_operand" "")
16181 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16183 UNSPEC_FSCALE_FRACT))
16185 (unspec:XF [(match_dup 1) (match_dup 3)]
16186 UNSPEC_FSCALE_EXP))])]
16187 "TARGET_USE_FANCY_MATH_387
16188 && flag_unsafe_math_optimizations"
16192 for (i=3; i<5; i++)
16193 operands[i] = gen_reg_rtx (XFmode);
16197 (define_insn "frndintxf2"
16198 [(set (match_operand:XF 0 "register_operand" "=f")
16199 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16201 "TARGET_USE_FANCY_MATH_387
16202 && flag_unsafe_math_optimizations"
16204 [(set_attr "type" "fpspc")
16205 (set_attr "mode" "XF")])
16207 (define_expand "rintdf2"
16208 [(use (match_operand:DF 0 "register_operand" ""))
16209 (use (match_operand:DF 1 "register_operand" ""))]
16210 "TARGET_USE_FANCY_MATH_387
16211 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16212 && flag_unsafe_math_optimizations"
16214 rtx op0 = gen_reg_rtx (XFmode);
16215 rtx op1 = gen_reg_rtx (XFmode);
16217 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16218 emit_insn (gen_frndintxf2 (op0, op1));
16220 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16224 (define_expand "rintsf2"
16225 [(use (match_operand:SF 0 "register_operand" ""))
16226 (use (match_operand:SF 1 "register_operand" ""))]
16227 "TARGET_USE_FANCY_MATH_387
16228 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16229 && flag_unsafe_math_optimizations"
16231 rtx op0 = gen_reg_rtx (XFmode);
16232 rtx op1 = gen_reg_rtx (XFmode);
16234 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16235 emit_insn (gen_frndintxf2 (op0, op1));
16237 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16241 (define_expand "rintxf2"
16242 [(use (match_operand:XF 0 "register_operand" ""))
16243 (use (match_operand:XF 1 "register_operand" ""))]
16244 "TARGET_USE_FANCY_MATH_387
16245 && flag_unsafe_math_optimizations"
16247 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16251 (define_insn "fistdi2"
16252 [(set (match_operand:DI 0 "memory_operand" "=m")
16253 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16255 (clobber (match_scratch:XF 2 "=&1f"))]
16256 "TARGET_USE_FANCY_MATH_387
16257 && flag_unsafe_math_optimizations"
16258 "* return output_fix_trunc (insn, operands, 0);"
16259 [(set_attr "type" "fpspc")
16260 (set_attr "mode" "DI")])
16262 (define_insn "fistdi2_with_temp"
16263 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16264 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16266 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16267 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16268 "TARGET_USE_FANCY_MATH_387
16269 && flag_unsafe_math_optimizations"
16271 [(set_attr "type" "fpspc")
16272 (set_attr "mode" "DI")])
16275 [(set (match_operand:DI 0 "register_operand" "")
16276 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16278 (clobber (match_operand:DI 2 "memory_operand" ""))
16279 (clobber (match_scratch 3 ""))]
16281 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16282 (clobber (match_dup 3))])
16283 (set (match_dup 0) (match_dup 2))]
16287 [(set (match_operand:DI 0 "memory_operand" "")
16288 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16290 (clobber (match_operand:DI 2 "memory_operand" ""))
16291 (clobber (match_scratch 3 ""))]
16293 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16294 (clobber (match_dup 3))])]
16297 (define_insn "fist<mode>2"
16298 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16299 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16301 "TARGET_USE_FANCY_MATH_387
16302 && flag_unsafe_math_optimizations"
16303 "* return output_fix_trunc (insn, operands, 0);"
16304 [(set_attr "type" "fpspc")
16305 (set_attr "mode" "<MODE>")])
16307 (define_insn "fist<mode>2_with_temp"
16308 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16309 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16311 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m,m"))]
16312 "TARGET_USE_FANCY_MATH_387
16313 && flag_unsafe_math_optimizations"
16315 [(set_attr "type" "fpspc")
16316 (set_attr "mode" "<MODE>")])
16319 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16320 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16322 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16324 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16326 (set (match_dup 0) (match_dup 2))]
16330 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16331 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16333 (clobber (match_scratch 2 ""))]
16335 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16339 (define_expand "lrint<mode>2"
16340 [(use (match_operand:X87MODEI 0 "nonimmediate_operand" ""))
16341 (use (match_operand:XF 1 "register_operand" ""))]
16342 "TARGET_USE_FANCY_MATH_387
16343 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16344 && flag_unsafe_math_optimizations"
16346 if (memory_operand (operands[0], VOIDmode))
16347 emit_insn (gen_fist<mode>2 (operands[0], operands[1]));
16350 operands[2] = assign_386_stack_local (<MODE>mode, 0);
16351 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16357 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16358 (define_insn_and_split "frndintxf2_floor"
16359 [(set (match_operand:XF 0 "register_operand" "=f")
16360 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16361 UNSPEC_FRNDINT_FLOOR))
16362 (clobber (reg:CC FLAGS_REG))]
16363 "TARGET_USE_FANCY_MATH_387
16364 && flag_unsafe_math_optimizations
16365 && !(reload_completed || reload_in_progress)"
16370 ix86_optimize_mode_switching = 1;
16372 operands[2] = assign_386_stack_local (HImode, 1);
16373 operands[3] = assign_386_stack_local (HImode, 2);
16375 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16376 operands[2], operands[3]));
16379 [(set_attr "type" "frndint")
16380 (set_attr "i387_cw" "floor")
16381 (set_attr "mode" "XF")])
16383 (define_insn "frndintxf2_floor_i387"
16384 [(set (match_operand:XF 0 "register_operand" "=f")
16385 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16386 UNSPEC_FRNDINT_FLOOR))
16387 (use (match_operand:HI 2 "memory_operand" "m"))
16388 (use (match_operand:HI 3 "memory_operand" "m"))]
16389 "TARGET_USE_FANCY_MATH_387
16390 && flag_unsafe_math_optimizations"
16391 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16392 [(set_attr "type" "frndint")
16393 (set_attr "i387_cw" "floor")
16394 (set_attr "mode" "XF")])
16396 (define_expand "floorxf2"
16397 [(use (match_operand:XF 0 "register_operand" ""))
16398 (use (match_operand:XF 1 "register_operand" ""))]
16399 "TARGET_USE_FANCY_MATH_387
16400 && flag_unsafe_math_optimizations"
16402 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16406 (define_expand "floordf2"
16407 [(use (match_operand:DF 0 "register_operand" ""))
16408 (use (match_operand:DF 1 "register_operand" ""))]
16409 "TARGET_USE_FANCY_MATH_387
16410 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16411 && flag_unsafe_math_optimizations"
16413 rtx op0 = gen_reg_rtx (XFmode);
16414 rtx op1 = gen_reg_rtx (XFmode);
16416 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16417 emit_insn (gen_frndintxf2_floor (op0, op1));
16419 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16423 (define_expand "floorsf2"
16424 [(use (match_operand:SF 0 "register_operand" ""))
16425 (use (match_operand:SF 1 "register_operand" ""))]
16426 "TARGET_USE_FANCY_MATH_387
16427 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16428 && flag_unsafe_math_optimizations"
16430 rtx op0 = gen_reg_rtx (XFmode);
16431 rtx op1 = gen_reg_rtx (XFmode);
16433 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16434 emit_insn (gen_frndintxf2_floor (op0, op1));
16436 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16440 (define_insn_and_split "*fist<mode>2_floor_1"
16441 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16442 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16443 UNSPEC_FIST_FLOOR))
16444 (clobber (reg:CC FLAGS_REG))]
16445 "TARGET_USE_FANCY_MATH_387
16446 && flag_unsafe_math_optimizations
16447 && !(reload_completed || reload_in_progress)"
16452 ix86_optimize_mode_switching = 1;
16453 operands[2] = assign_386_stack_local (HImode, 1);
16454 operands[3] = assign_386_stack_local (HImode, 2);
16455 if (memory_operand (operands[0], VOIDmode))
16456 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16457 operands[2], operands[3]));
16460 operands[4] = assign_386_stack_local (<MODE>mode, 0);
16461 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16462 operands[2], operands[3],
16467 [(set_attr "type" "fistp")
16468 (set_attr "i387_cw" "floor")
16469 (set_attr "mode" "<MODE>")])
16471 (define_insn "fistdi2_floor"
16472 [(set (match_operand:DI 0 "memory_operand" "=m")
16473 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16474 UNSPEC_FIST_FLOOR))
16475 (use (match_operand:HI 2 "memory_operand" "m"))
16476 (use (match_operand:HI 3 "memory_operand" "m"))
16477 (clobber (match_scratch:XF 4 "=&1f"))]
16478 "TARGET_USE_FANCY_MATH_387
16479 && flag_unsafe_math_optimizations"
16480 "* return output_fix_trunc (insn, operands, 0);"
16481 [(set_attr "type" "fistp")
16482 (set_attr "i387_cw" "floor")
16483 (set_attr "mode" "DI")])
16485 (define_insn "fistdi2_floor_with_temp"
16486 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16487 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16488 UNSPEC_FIST_FLOOR))
16489 (use (match_operand:HI 2 "memory_operand" "m,m"))
16490 (use (match_operand:HI 3 "memory_operand" "m,m"))
16491 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16492 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16493 "TARGET_USE_FANCY_MATH_387
16494 && flag_unsafe_math_optimizations"
16496 [(set_attr "type" "fistp")
16497 (set_attr "i387_cw" "floor")
16498 (set_attr "mode" "DI")])
16501 [(set (match_operand:DI 0 "register_operand" "")
16502 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16503 UNSPEC_FIST_FLOOR))
16504 (use (match_operand:HI 2 "memory_operand" ""))
16505 (use (match_operand:HI 3 "memory_operand" ""))
16506 (clobber (match_operand:DI 4 "memory_operand" ""))
16507 (clobber (match_scratch 5 ""))]
16509 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16510 (use (match_dup 2))
16511 (use (match_dup 3))
16512 (clobber (match_dup 5))])
16513 (set (match_dup 0) (match_dup 4))]
16517 [(set (match_operand:DI 0 "memory_operand" "")
16518 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16519 UNSPEC_FIST_FLOOR))
16520 (use (match_operand:HI 2 "memory_operand" ""))
16521 (use (match_operand:HI 3 "memory_operand" ""))
16522 (clobber (match_operand:DI 4 "memory_operand" ""))
16523 (clobber (match_scratch 5 ""))]
16525 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16526 (use (match_dup 2))
16527 (use (match_dup 3))
16528 (clobber (match_dup 5))])]
16531 (define_insn "fist<mode>2_floor"
16532 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16533 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16534 UNSPEC_FIST_FLOOR))
16535 (use (match_operand:HI 2 "memory_operand" "m"))
16536 (use (match_operand:HI 3 "memory_operand" "m"))]
16537 "TARGET_USE_FANCY_MATH_387
16538 && flag_unsafe_math_optimizations"
16539 "* return output_fix_trunc (insn, operands, 0);"
16540 [(set_attr "type" "fistp")
16541 (set_attr "i387_cw" "floor")
16542 (set_attr "mode" "<MODE>")])
16544 (define_insn "fist<mode>2_floor_with_temp"
16545 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16546 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16547 UNSPEC_FIST_FLOOR))
16548 (use (match_operand:HI 2 "memory_operand" "m,m"))
16549 (use (match_operand:HI 3 "memory_operand" "m,m"))
16550 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16551 "TARGET_USE_FANCY_MATH_387
16552 && flag_unsafe_math_optimizations"
16554 [(set_attr "type" "fistp")
16555 (set_attr "i387_cw" "floor")
16556 (set_attr "mode" "<MODE>")])
16559 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16560 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16561 UNSPEC_FIST_FLOOR))
16562 (use (match_operand:HI 2 "memory_operand" ""))
16563 (use (match_operand:HI 3 "memory_operand" ""))
16564 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16566 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16567 UNSPEC_FIST_FLOOR))
16568 (use (match_dup 2))
16569 (use (match_dup 3))])
16570 (set (match_dup 0) (match_dup 4))]
16574 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16575 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16576 UNSPEC_FIST_FLOOR))
16577 (use (match_operand:HI 2 "memory_operand" ""))
16578 (use (match_operand:HI 3 "memory_operand" ""))
16579 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16581 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16582 UNSPEC_FIST_FLOOR))
16583 (use (match_dup 2))
16584 (use (match_dup 3))])]
16587 (define_expand "lfloor<mode>2"
16588 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16589 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16590 UNSPEC_FIST_FLOOR))
16591 (clobber (reg:CC FLAGS_REG))])]
16592 "TARGET_USE_FANCY_MATH_387
16593 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16594 && flag_unsafe_math_optimizations"
16597 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16598 (define_insn_and_split "frndintxf2_ceil"
16599 [(set (match_operand:XF 0 "register_operand" "=f")
16600 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16601 UNSPEC_FRNDINT_CEIL))
16602 (clobber (reg:CC FLAGS_REG))]
16603 "TARGET_USE_FANCY_MATH_387
16604 && flag_unsafe_math_optimizations
16605 && !(reload_completed || reload_in_progress)"
16610 ix86_optimize_mode_switching = 1;
16612 operands[2] = assign_386_stack_local (HImode, 1);
16613 operands[3] = assign_386_stack_local (HImode, 2);
16615 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16616 operands[2], operands[3]));
16619 [(set_attr "type" "frndint")
16620 (set_attr "i387_cw" "ceil")
16621 (set_attr "mode" "XF")])
16623 (define_insn "frndintxf2_ceil_i387"
16624 [(set (match_operand:XF 0 "register_operand" "=f")
16625 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16626 UNSPEC_FRNDINT_CEIL))
16627 (use (match_operand:HI 2 "memory_operand" "m"))
16628 (use (match_operand:HI 3 "memory_operand" "m"))]
16629 "TARGET_USE_FANCY_MATH_387
16630 && flag_unsafe_math_optimizations"
16631 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16632 [(set_attr "type" "frndint")
16633 (set_attr "i387_cw" "ceil")
16634 (set_attr "mode" "XF")])
16636 (define_expand "ceilxf2"
16637 [(use (match_operand:XF 0 "register_operand" ""))
16638 (use (match_operand:XF 1 "register_operand" ""))]
16639 "TARGET_USE_FANCY_MATH_387
16640 && flag_unsafe_math_optimizations"
16642 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16646 (define_expand "ceildf2"
16647 [(use (match_operand:DF 0 "register_operand" ""))
16648 (use (match_operand:DF 1 "register_operand" ""))]
16649 "TARGET_USE_FANCY_MATH_387
16650 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16651 && flag_unsafe_math_optimizations"
16653 rtx op0 = gen_reg_rtx (XFmode);
16654 rtx op1 = gen_reg_rtx (XFmode);
16656 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16657 emit_insn (gen_frndintxf2_ceil (op0, op1));
16659 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16663 (define_expand "ceilsf2"
16664 [(use (match_operand:SF 0 "register_operand" ""))
16665 (use (match_operand:SF 1 "register_operand" ""))]
16666 "TARGET_USE_FANCY_MATH_387
16667 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16668 && flag_unsafe_math_optimizations"
16670 rtx op0 = gen_reg_rtx (XFmode);
16671 rtx op1 = gen_reg_rtx (XFmode);
16673 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16674 emit_insn (gen_frndintxf2_ceil (op0, op1));
16676 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16680 (define_insn_and_split "*fist<mode>2_ceil_1"
16681 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16682 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16684 (clobber (reg:CC FLAGS_REG))]
16685 "TARGET_USE_FANCY_MATH_387
16686 && flag_unsafe_math_optimizations
16687 && !(reload_completed || reload_in_progress)"
16692 ix86_optimize_mode_switching = 1;
16693 operands[2] = assign_386_stack_local (HImode, 1);
16694 operands[3] = assign_386_stack_local (HImode, 2);
16695 if (memory_operand (operands[0], VOIDmode))
16696 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16697 operands[2], operands[3]));
16700 operands[4] = assign_386_stack_local (<MODE>mode, 0);
16701 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16702 operands[2], operands[3],
16707 [(set_attr "type" "fistp")
16708 (set_attr "i387_cw" "ceil")
16709 (set_attr "mode" "<MODE>")])
16711 (define_insn "fistdi2_ceil"
16712 [(set (match_operand:DI 0 "memory_operand" "=m")
16713 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16715 (use (match_operand:HI 2 "memory_operand" "m"))
16716 (use (match_operand:HI 3 "memory_operand" "m"))
16717 (clobber (match_scratch:XF 4 "=&1f"))]
16718 "TARGET_USE_FANCY_MATH_387
16719 && flag_unsafe_math_optimizations"
16720 "* return output_fix_trunc (insn, operands, 0);"
16721 [(set_attr "type" "fistp")
16722 (set_attr "i387_cw" "ceil")
16723 (set_attr "mode" "DI")])
16725 (define_insn "fistdi2_ceil_with_temp"
16726 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16727 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16729 (use (match_operand:HI 2 "memory_operand" "m,m"))
16730 (use (match_operand:HI 3 "memory_operand" "m,m"))
16731 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
16732 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16733 "TARGET_USE_FANCY_MATH_387
16734 && flag_unsafe_math_optimizations"
16736 [(set_attr "type" "fistp")
16737 (set_attr "i387_cw" "ceil")
16738 (set_attr "mode" "DI")])
16741 [(set (match_operand:DI 0 "register_operand" "")
16742 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16744 (use (match_operand:HI 2 "memory_operand" ""))
16745 (use (match_operand:HI 3 "memory_operand" ""))
16746 (clobber (match_operand:DI 4 "memory_operand" ""))
16747 (clobber (match_scratch 5 ""))]
16749 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16750 (use (match_dup 2))
16751 (use (match_dup 3))
16752 (clobber (match_dup 5))])
16753 (set (match_dup 0) (match_dup 4))]
16757 [(set (match_operand:DI 0 "memory_operand" "")
16758 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16760 (use (match_operand:HI 2 "memory_operand" ""))
16761 (use (match_operand:HI 3 "memory_operand" ""))
16762 (clobber (match_operand:DI 4 "memory_operand" ""))
16763 (clobber (match_scratch 5 ""))]
16765 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
16766 (use (match_dup 2))
16767 (use (match_dup 3))
16768 (clobber (match_dup 5))])]
16771 (define_insn "fist<mode>2_ceil"
16772 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16773 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16775 (use (match_operand:HI 2 "memory_operand" "m"))
16776 (use (match_operand:HI 3 "memory_operand" "m"))]
16777 "TARGET_USE_FANCY_MATH_387
16778 && flag_unsafe_math_optimizations"
16779 "* return output_fix_trunc (insn, operands, 0);"
16780 [(set_attr "type" "fistp")
16781 (set_attr "i387_cw" "ceil")
16782 (set_attr "mode" "<MODE>")])
16784 (define_insn "fist<mode>2_ceil_with_temp"
16785 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16786 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16788 (use (match_operand:HI 2 "memory_operand" "m,m"))
16789 (use (match_operand:HI 3 "memory_operand" "m,m"))
16790 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
16791 "TARGET_USE_FANCY_MATH_387
16792 && flag_unsafe_math_optimizations"
16794 [(set_attr "type" "fistp")
16795 (set_attr "i387_cw" "ceil")
16796 (set_attr "mode" "<MODE>")])
16799 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16800 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16802 (use (match_operand:HI 2 "memory_operand" ""))
16803 (use (match_operand:HI 3 "memory_operand" ""))
16804 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16806 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16808 (use (match_dup 2))
16809 (use (match_dup 3))])
16810 (set (match_dup 0) (match_dup 4))]
16814 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16815 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16817 (use (match_operand:HI 2 "memory_operand" ""))
16818 (use (match_operand:HI 3 "memory_operand" ""))
16819 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16821 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16823 (use (match_dup 2))
16824 (use (match_dup 3))])]
16827 (define_expand "lceil<mode>2"
16828 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16829 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16831 (clobber (reg:CC FLAGS_REG))])]
16832 "TARGET_USE_FANCY_MATH_387
16833 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16834 && flag_unsafe_math_optimizations"
16837 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16838 (define_insn_and_split "frndintxf2_trunc"
16839 [(set (match_operand:XF 0 "register_operand" "=f")
16840 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16841 UNSPEC_FRNDINT_TRUNC))
16842 (clobber (reg:CC FLAGS_REG))]
16843 "TARGET_USE_FANCY_MATH_387
16844 && flag_unsafe_math_optimizations
16845 && !(reload_completed || reload_in_progress)"
16850 ix86_optimize_mode_switching = 1;
16852 operands[2] = assign_386_stack_local (HImode, 1);
16853 operands[3] = assign_386_stack_local (HImode, 2);
16855 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
16856 operands[2], operands[3]));
16859 [(set_attr "type" "frndint")
16860 (set_attr "i387_cw" "trunc")
16861 (set_attr "mode" "XF")])
16863 (define_insn "frndintxf2_trunc_i387"
16864 [(set (match_operand:XF 0 "register_operand" "=f")
16865 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16866 UNSPEC_FRNDINT_TRUNC))
16867 (use (match_operand:HI 2 "memory_operand" "m"))
16868 (use (match_operand:HI 3 "memory_operand" "m"))]
16869 "TARGET_USE_FANCY_MATH_387
16870 && flag_unsafe_math_optimizations"
16871 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16872 [(set_attr "type" "frndint")
16873 (set_attr "i387_cw" "trunc")
16874 (set_attr "mode" "XF")])
16876 (define_expand "btruncxf2"
16877 [(use (match_operand:XF 0 "register_operand" ""))
16878 (use (match_operand:XF 1 "register_operand" ""))]
16879 "TARGET_USE_FANCY_MATH_387
16880 && flag_unsafe_math_optimizations"
16882 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
16886 (define_expand "btruncdf2"
16887 [(use (match_operand:DF 0 "register_operand" ""))
16888 (use (match_operand:DF 1 "register_operand" ""))]
16889 "TARGET_USE_FANCY_MATH_387
16890 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16891 && flag_unsafe_math_optimizations"
16893 rtx op0 = gen_reg_rtx (XFmode);
16894 rtx op1 = gen_reg_rtx (XFmode);
16896 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16897 emit_insn (gen_frndintxf2_trunc (op0, op1));
16899 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16903 (define_expand "btruncsf2"
16904 [(use (match_operand:SF 0 "register_operand" ""))
16905 (use (match_operand:SF 1 "register_operand" ""))]
16906 "TARGET_USE_FANCY_MATH_387
16907 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16908 && flag_unsafe_math_optimizations"
16910 rtx op0 = gen_reg_rtx (XFmode);
16911 rtx op1 = gen_reg_rtx (XFmode);
16913 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16914 emit_insn (gen_frndintxf2_trunc (op0, op1));
16916 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16920 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16921 (define_insn_and_split "frndintxf2_mask_pm"
16922 [(set (match_operand:XF 0 "register_operand" "=f")
16923 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16924 UNSPEC_FRNDINT_MASK_PM))
16925 (clobber (reg:CC FLAGS_REG))]
16926 "TARGET_USE_FANCY_MATH_387
16927 && flag_unsafe_math_optimizations
16928 && !(reload_completed || reload_in_progress)"
16933 ix86_optimize_mode_switching = 1;
16935 operands[2] = assign_386_stack_local (HImode, 1);
16936 operands[3] = assign_386_stack_local (HImode, 2);
16938 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16939 operands[2], operands[3]));
16942 [(set_attr "type" "frndint")
16943 (set_attr "i387_cw" "mask_pm")
16944 (set_attr "mode" "XF")])
16946 (define_insn "frndintxf2_mask_pm_i387"
16947 [(set (match_operand:XF 0 "register_operand" "=f")
16948 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16949 UNSPEC_FRNDINT_MASK_PM))
16950 (use (match_operand:HI 2 "memory_operand" "m"))
16951 (use (match_operand:HI 3 "memory_operand" "m"))]
16952 "TARGET_USE_FANCY_MATH_387
16953 && flag_unsafe_math_optimizations"
16954 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16955 [(set_attr "type" "frndint")
16956 (set_attr "i387_cw" "mask_pm")
16957 (set_attr "mode" "XF")])
16959 (define_expand "nearbyintxf2"
16960 [(use (match_operand:XF 0 "register_operand" ""))
16961 (use (match_operand:XF 1 "register_operand" ""))]
16962 "TARGET_USE_FANCY_MATH_387
16963 && flag_unsafe_math_optimizations"
16965 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
16970 (define_expand "nearbyintdf2"
16971 [(use (match_operand:DF 0 "register_operand" ""))
16972 (use (match_operand:DF 1 "register_operand" ""))]
16973 "TARGET_USE_FANCY_MATH_387
16974 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16975 && flag_unsafe_math_optimizations"
16977 rtx op0 = gen_reg_rtx (XFmode);
16978 rtx op1 = gen_reg_rtx (XFmode);
16980 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16981 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16983 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16987 (define_expand "nearbyintsf2"
16988 [(use (match_operand:SF 0 "register_operand" ""))
16989 (use (match_operand:SF 1 "register_operand" ""))]
16990 "TARGET_USE_FANCY_MATH_387
16991 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16992 && flag_unsafe_math_optimizations"
16994 rtx op0 = gen_reg_rtx (XFmode);
16995 rtx op1 = gen_reg_rtx (XFmode);
16997 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16998 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17000 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17005 ;; Block operation instructions
17008 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17011 [(set_attr "type" "cld")])
17013 (define_expand "movmemsi"
17014 [(use (match_operand:BLK 0 "memory_operand" ""))
17015 (use (match_operand:BLK 1 "memory_operand" ""))
17016 (use (match_operand:SI 2 "nonmemory_operand" ""))
17017 (use (match_operand:SI 3 "const_int_operand" ""))]
17020 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17026 (define_expand "movmemdi"
17027 [(use (match_operand:BLK 0 "memory_operand" ""))
17028 (use (match_operand:BLK 1 "memory_operand" ""))
17029 (use (match_operand:DI 2 "nonmemory_operand" ""))
17030 (use (match_operand:DI 3 "const_int_operand" ""))]
17033 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
17039 ;; Most CPUs don't like single string operations
17040 ;; Handle this case here to simplify previous expander.
17042 (define_expand "strmov"
17043 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17044 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17045 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17046 (clobber (reg:CC FLAGS_REG))])
17047 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17048 (clobber (reg:CC FLAGS_REG))])]
17051 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17053 /* If .md ever supports :P for Pmode, these can be directly
17054 in the pattern above. */
17055 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17056 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17058 if (TARGET_SINGLE_STRINGOP || optimize_size)
17060 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17061 operands[2], operands[3],
17062 operands[5], operands[6]));
17066 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17069 (define_expand "strmov_singleop"
17070 [(parallel [(set (match_operand 1 "memory_operand" "")
17071 (match_operand 3 "memory_operand" ""))
17072 (set (match_operand 0 "register_operand" "")
17073 (match_operand 4 "" ""))
17074 (set (match_operand 2 "register_operand" "")
17075 (match_operand 5 "" ""))
17076 (use (reg:SI DIRFLAG_REG))])]
17077 "TARGET_SINGLE_STRINGOP || optimize_size"
17080 (define_insn "*strmovdi_rex_1"
17081 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17082 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17083 (set (match_operand:DI 0 "register_operand" "=D")
17084 (plus:DI (match_dup 2)
17086 (set (match_operand:DI 1 "register_operand" "=S")
17087 (plus:DI (match_dup 3)
17089 (use (reg:SI DIRFLAG_REG))]
17090 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17092 [(set_attr "type" "str")
17093 (set_attr "mode" "DI")
17094 (set_attr "memory" "both")])
17096 (define_insn "*strmovsi_1"
17097 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17098 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17099 (set (match_operand:SI 0 "register_operand" "=D")
17100 (plus:SI (match_dup 2)
17102 (set (match_operand:SI 1 "register_operand" "=S")
17103 (plus:SI (match_dup 3)
17105 (use (reg:SI DIRFLAG_REG))]
17106 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17108 [(set_attr "type" "str")
17109 (set_attr "mode" "SI")
17110 (set_attr "memory" "both")])
17112 (define_insn "*strmovsi_rex_1"
17113 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17114 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17115 (set (match_operand:DI 0 "register_operand" "=D")
17116 (plus:DI (match_dup 2)
17118 (set (match_operand:DI 1 "register_operand" "=S")
17119 (plus:DI (match_dup 3)
17121 (use (reg:SI DIRFLAG_REG))]
17122 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17124 [(set_attr "type" "str")
17125 (set_attr "mode" "SI")
17126 (set_attr "memory" "both")])
17128 (define_insn "*strmovhi_1"
17129 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17130 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17131 (set (match_operand:SI 0 "register_operand" "=D")
17132 (plus:SI (match_dup 2)
17134 (set (match_operand:SI 1 "register_operand" "=S")
17135 (plus:SI (match_dup 3)
17137 (use (reg:SI DIRFLAG_REG))]
17138 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17140 [(set_attr "type" "str")
17141 (set_attr "memory" "both")
17142 (set_attr "mode" "HI")])
17144 (define_insn "*strmovhi_rex_1"
17145 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17146 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17147 (set (match_operand:DI 0 "register_operand" "=D")
17148 (plus:DI (match_dup 2)
17150 (set (match_operand:DI 1 "register_operand" "=S")
17151 (plus:DI (match_dup 3)
17153 (use (reg:SI DIRFLAG_REG))]
17154 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17156 [(set_attr "type" "str")
17157 (set_attr "memory" "both")
17158 (set_attr "mode" "HI")])
17160 (define_insn "*strmovqi_1"
17161 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17162 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17163 (set (match_operand:SI 0 "register_operand" "=D")
17164 (plus:SI (match_dup 2)
17166 (set (match_operand:SI 1 "register_operand" "=S")
17167 (plus:SI (match_dup 3)
17169 (use (reg:SI DIRFLAG_REG))]
17170 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17172 [(set_attr "type" "str")
17173 (set_attr "memory" "both")
17174 (set_attr "mode" "QI")])
17176 (define_insn "*strmovqi_rex_1"
17177 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17178 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17179 (set (match_operand:DI 0 "register_operand" "=D")
17180 (plus:DI (match_dup 2)
17182 (set (match_operand:DI 1 "register_operand" "=S")
17183 (plus:DI (match_dup 3)
17185 (use (reg:SI DIRFLAG_REG))]
17186 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17188 [(set_attr "type" "str")
17189 (set_attr "memory" "both")
17190 (set_attr "mode" "QI")])
17192 (define_expand "rep_mov"
17193 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17194 (set (match_operand 0 "register_operand" "")
17195 (match_operand 5 "" ""))
17196 (set (match_operand 2 "register_operand" "")
17197 (match_operand 6 "" ""))
17198 (set (match_operand 1 "memory_operand" "")
17199 (match_operand 3 "memory_operand" ""))
17200 (use (match_dup 4))
17201 (use (reg:SI DIRFLAG_REG))])]
17205 (define_insn "*rep_movdi_rex64"
17206 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17207 (set (match_operand:DI 0 "register_operand" "=D")
17208 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17210 (match_operand:DI 3 "register_operand" "0")))
17211 (set (match_operand:DI 1 "register_operand" "=S")
17212 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17213 (match_operand:DI 4 "register_operand" "1")))
17214 (set (mem:BLK (match_dup 3))
17215 (mem:BLK (match_dup 4)))
17216 (use (match_dup 5))
17217 (use (reg:SI DIRFLAG_REG))]
17219 "{rep\;movsq|rep movsq}"
17220 [(set_attr "type" "str")
17221 (set_attr "prefix_rep" "1")
17222 (set_attr "memory" "both")
17223 (set_attr "mode" "DI")])
17225 (define_insn "*rep_movsi"
17226 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17227 (set (match_operand:SI 0 "register_operand" "=D")
17228 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17230 (match_operand:SI 3 "register_operand" "0")))
17231 (set (match_operand:SI 1 "register_operand" "=S")
17232 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17233 (match_operand:SI 4 "register_operand" "1")))
17234 (set (mem:BLK (match_dup 3))
17235 (mem:BLK (match_dup 4)))
17236 (use (match_dup 5))
17237 (use (reg:SI DIRFLAG_REG))]
17239 "{rep\;movsl|rep movsd}"
17240 [(set_attr "type" "str")
17241 (set_attr "prefix_rep" "1")
17242 (set_attr "memory" "both")
17243 (set_attr "mode" "SI")])
17245 (define_insn "*rep_movsi_rex64"
17246 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17247 (set (match_operand:DI 0 "register_operand" "=D")
17248 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17250 (match_operand:DI 3 "register_operand" "0")))
17251 (set (match_operand:DI 1 "register_operand" "=S")
17252 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17253 (match_operand:DI 4 "register_operand" "1")))
17254 (set (mem:BLK (match_dup 3))
17255 (mem:BLK (match_dup 4)))
17256 (use (match_dup 5))
17257 (use (reg:SI DIRFLAG_REG))]
17259 "{rep\;movsl|rep movsd}"
17260 [(set_attr "type" "str")
17261 (set_attr "prefix_rep" "1")
17262 (set_attr "memory" "both")
17263 (set_attr "mode" "SI")])
17265 (define_insn "*rep_movqi"
17266 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17267 (set (match_operand:SI 0 "register_operand" "=D")
17268 (plus:SI (match_operand:SI 3 "register_operand" "0")
17269 (match_operand:SI 5 "register_operand" "2")))
17270 (set (match_operand:SI 1 "register_operand" "=S")
17271 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17272 (set (mem:BLK (match_dup 3))
17273 (mem:BLK (match_dup 4)))
17274 (use (match_dup 5))
17275 (use (reg:SI DIRFLAG_REG))]
17277 "{rep\;movsb|rep movsb}"
17278 [(set_attr "type" "str")
17279 (set_attr "prefix_rep" "1")
17280 (set_attr "memory" "both")
17281 (set_attr "mode" "SI")])
17283 (define_insn "*rep_movqi_rex64"
17284 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17285 (set (match_operand:DI 0 "register_operand" "=D")
17286 (plus:DI (match_operand:DI 3 "register_operand" "0")
17287 (match_operand:DI 5 "register_operand" "2")))
17288 (set (match_operand:DI 1 "register_operand" "=S")
17289 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17290 (set (mem:BLK (match_dup 3))
17291 (mem:BLK (match_dup 4)))
17292 (use (match_dup 5))
17293 (use (reg:SI DIRFLAG_REG))]
17295 "{rep\;movsb|rep movsb}"
17296 [(set_attr "type" "str")
17297 (set_attr "prefix_rep" "1")
17298 (set_attr "memory" "both")
17299 (set_attr "mode" "SI")])
17301 (define_expand "clrmemsi"
17302 [(use (match_operand:BLK 0 "memory_operand" ""))
17303 (use (match_operand:SI 1 "nonmemory_operand" ""))
17304 (use (match_operand 2 "const_int_operand" ""))]
17307 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17313 (define_expand "clrmemdi"
17314 [(use (match_operand:BLK 0 "memory_operand" ""))
17315 (use (match_operand:DI 1 "nonmemory_operand" ""))
17316 (use (match_operand 2 "const_int_operand" ""))]
17319 if (ix86_expand_clrmem (operands[0], operands[1], operands[2]))
17325 ;; Most CPUs don't like single string operations
17326 ;; Handle this case here to simplify previous expander.
17328 (define_expand "strset"
17329 [(set (match_operand 1 "memory_operand" "")
17330 (match_operand 2 "register_operand" ""))
17331 (parallel [(set (match_operand 0 "register_operand" "")
17333 (clobber (reg:CC FLAGS_REG))])]
17336 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17337 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17339 /* If .md ever supports :P for Pmode, this can be directly
17340 in the pattern above. */
17341 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17342 GEN_INT (GET_MODE_SIZE (GET_MODE
17344 if (TARGET_SINGLE_STRINGOP || optimize_size)
17346 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17352 (define_expand "strset_singleop"
17353 [(parallel [(set (match_operand 1 "memory_operand" "")
17354 (match_operand 2 "register_operand" ""))
17355 (set (match_operand 0 "register_operand" "")
17356 (match_operand 3 "" ""))
17357 (use (reg:SI DIRFLAG_REG))])]
17358 "TARGET_SINGLE_STRINGOP || optimize_size"
17361 (define_insn "*strsetdi_rex_1"
17362 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17363 (match_operand:DI 2 "register_operand" "a"))
17364 (set (match_operand:DI 0 "register_operand" "=D")
17365 (plus:DI (match_dup 1)
17367 (use (reg:SI DIRFLAG_REG))]
17368 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17370 [(set_attr "type" "str")
17371 (set_attr "memory" "store")
17372 (set_attr "mode" "DI")])
17374 (define_insn "*strsetsi_1"
17375 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17376 (match_operand:SI 2 "register_operand" "a"))
17377 (set (match_operand:SI 0 "register_operand" "=D")
17378 (plus:SI (match_dup 1)
17380 (use (reg:SI DIRFLAG_REG))]
17381 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17383 [(set_attr "type" "str")
17384 (set_attr "memory" "store")
17385 (set_attr "mode" "SI")])
17387 (define_insn "*strsetsi_rex_1"
17388 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17389 (match_operand:SI 2 "register_operand" "a"))
17390 (set (match_operand:DI 0 "register_operand" "=D")
17391 (plus:DI (match_dup 1)
17393 (use (reg:SI DIRFLAG_REG))]
17394 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17396 [(set_attr "type" "str")
17397 (set_attr "memory" "store")
17398 (set_attr "mode" "SI")])
17400 (define_insn "*strsethi_1"
17401 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17402 (match_operand:HI 2 "register_operand" "a"))
17403 (set (match_operand:SI 0 "register_operand" "=D")
17404 (plus:SI (match_dup 1)
17406 (use (reg:SI DIRFLAG_REG))]
17407 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17409 [(set_attr "type" "str")
17410 (set_attr "memory" "store")
17411 (set_attr "mode" "HI")])
17413 (define_insn "*strsethi_rex_1"
17414 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17415 (match_operand:HI 2 "register_operand" "a"))
17416 (set (match_operand:DI 0 "register_operand" "=D")
17417 (plus:DI (match_dup 1)
17419 (use (reg:SI DIRFLAG_REG))]
17420 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17422 [(set_attr "type" "str")
17423 (set_attr "memory" "store")
17424 (set_attr "mode" "HI")])
17426 (define_insn "*strsetqi_1"
17427 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17428 (match_operand:QI 2 "register_operand" "a"))
17429 (set (match_operand:SI 0 "register_operand" "=D")
17430 (plus:SI (match_dup 1)
17432 (use (reg:SI DIRFLAG_REG))]
17433 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17435 [(set_attr "type" "str")
17436 (set_attr "memory" "store")
17437 (set_attr "mode" "QI")])
17439 (define_insn "*strsetqi_rex_1"
17440 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17441 (match_operand:QI 2 "register_operand" "a"))
17442 (set (match_operand:DI 0 "register_operand" "=D")
17443 (plus:DI (match_dup 1)
17445 (use (reg:SI DIRFLAG_REG))]
17446 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17448 [(set_attr "type" "str")
17449 (set_attr "memory" "store")
17450 (set_attr "mode" "QI")])
17452 (define_expand "rep_stos"
17453 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17454 (set (match_operand 0 "register_operand" "")
17455 (match_operand 4 "" ""))
17456 (set (match_operand 2 "memory_operand" "") (const_int 0))
17457 (use (match_operand 3 "register_operand" ""))
17458 (use (match_dup 1))
17459 (use (reg:SI DIRFLAG_REG))])]
17463 (define_insn "*rep_stosdi_rex64"
17464 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17465 (set (match_operand:DI 0 "register_operand" "=D")
17466 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17468 (match_operand:DI 3 "register_operand" "0")))
17469 (set (mem:BLK (match_dup 3))
17471 (use (match_operand:DI 2 "register_operand" "a"))
17472 (use (match_dup 4))
17473 (use (reg:SI DIRFLAG_REG))]
17475 "{rep\;stosq|rep stosq}"
17476 [(set_attr "type" "str")
17477 (set_attr "prefix_rep" "1")
17478 (set_attr "memory" "store")
17479 (set_attr "mode" "DI")])
17481 (define_insn "*rep_stossi"
17482 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17483 (set (match_operand:SI 0 "register_operand" "=D")
17484 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17486 (match_operand:SI 3 "register_operand" "0")))
17487 (set (mem:BLK (match_dup 3))
17489 (use (match_operand:SI 2 "register_operand" "a"))
17490 (use (match_dup 4))
17491 (use (reg:SI DIRFLAG_REG))]
17493 "{rep\;stosl|rep stosd}"
17494 [(set_attr "type" "str")
17495 (set_attr "prefix_rep" "1")
17496 (set_attr "memory" "store")
17497 (set_attr "mode" "SI")])
17499 (define_insn "*rep_stossi_rex64"
17500 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17501 (set (match_operand:DI 0 "register_operand" "=D")
17502 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17504 (match_operand:DI 3 "register_operand" "0")))
17505 (set (mem:BLK (match_dup 3))
17507 (use (match_operand:SI 2 "register_operand" "a"))
17508 (use (match_dup 4))
17509 (use (reg:SI DIRFLAG_REG))]
17511 "{rep\;stosl|rep stosd}"
17512 [(set_attr "type" "str")
17513 (set_attr "prefix_rep" "1")
17514 (set_attr "memory" "store")
17515 (set_attr "mode" "SI")])
17517 (define_insn "*rep_stosqi"
17518 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17519 (set (match_operand:SI 0 "register_operand" "=D")
17520 (plus:SI (match_operand:SI 3 "register_operand" "0")
17521 (match_operand:SI 4 "register_operand" "1")))
17522 (set (mem:BLK (match_dup 3))
17524 (use (match_operand:QI 2 "register_operand" "a"))
17525 (use (match_dup 4))
17526 (use (reg:SI DIRFLAG_REG))]
17528 "{rep\;stosb|rep stosb}"
17529 [(set_attr "type" "str")
17530 (set_attr "prefix_rep" "1")
17531 (set_attr "memory" "store")
17532 (set_attr "mode" "QI")])
17534 (define_insn "*rep_stosqi_rex64"
17535 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17536 (set (match_operand:DI 0 "register_operand" "=D")
17537 (plus:DI (match_operand:DI 3 "register_operand" "0")
17538 (match_operand:DI 4 "register_operand" "1")))
17539 (set (mem:BLK (match_dup 3))
17541 (use (match_operand:QI 2 "register_operand" "a"))
17542 (use (match_dup 4))
17543 (use (reg:SI DIRFLAG_REG))]
17545 "{rep\;stosb|rep stosb}"
17546 [(set_attr "type" "str")
17547 (set_attr "prefix_rep" "1")
17548 (set_attr "memory" "store")
17549 (set_attr "mode" "QI")])
17551 (define_expand "cmpstrsi"
17552 [(set (match_operand:SI 0 "register_operand" "")
17553 (compare:SI (match_operand:BLK 1 "general_operand" "")
17554 (match_operand:BLK 2 "general_operand" "")))
17555 (use (match_operand 3 "general_operand" ""))
17556 (use (match_operand 4 "immediate_operand" ""))]
17557 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
17559 rtx addr1, addr2, out, outlow, count, countreg, align;
17561 /* Can't use this if the user has appropriated esi or edi. */
17562 if (global_regs[4] || global_regs[5])
17566 if (GET_CODE (out) != REG)
17567 out = gen_reg_rtx (SImode);
17569 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17570 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17571 if (addr1 != XEXP (operands[1], 0))
17572 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17573 if (addr2 != XEXP (operands[2], 0))
17574 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17576 count = operands[3];
17577 countreg = ix86_zero_extend_to_Pmode (count);
17579 /* %%% Iff we are testing strict equality, we can use known alignment
17580 to good advantage. This may be possible with combine, particularly
17581 once cc0 is dead. */
17582 align = operands[4];
17584 emit_insn (gen_cld ());
17585 if (GET_CODE (count) == CONST_INT)
17587 if (INTVAL (count) == 0)
17589 emit_move_insn (operands[0], const0_rtx);
17592 emit_insn (gen_cmpstrqi_nz_1 (addr1, addr2, countreg, align,
17593 operands[1], operands[2]));
17598 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
17600 emit_insn (gen_cmpsi_1 (countreg, countreg));
17601 emit_insn (gen_cmpstrqi_1 (addr1, addr2, countreg, align,
17602 operands[1], operands[2]));
17605 outlow = gen_lowpart (QImode, out);
17606 emit_insn (gen_cmpintqi (outlow));
17607 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17609 if (operands[0] != out)
17610 emit_move_insn (operands[0], out);
17615 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17617 (define_expand "cmpintqi"
17618 [(set (match_dup 1)
17619 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17621 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17622 (parallel [(set (match_operand:QI 0 "register_operand" "")
17623 (minus:QI (match_dup 1)
17625 (clobber (reg:CC FLAGS_REG))])]
17627 "operands[1] = gen_reg_rtx (QImode);
17628 operands[2] = gen_reg_rtx (QImode);")
17630 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17631 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17633 (define_expand "cmpstrqi_nz_1"
17634 [(parallel [(set (reg:CC FLAGS_REG)
17635 (compare:CC (match_operand 4 "memory_operand" "")
17636 (match_operand 5 "memory_operand" "")))
17637 (use (match_operand 2 "register_operand" ""))
17638 (use (match_operand:SI 3 "immediate_operand" ""))
17639 (use (reg:SI DIRFLAG_REG))
17640 (clobber (match_operand 0 "register_operand" ""))
17641 (clobber (match_operand 1 "register_operand" ""))
17642 (clobber (match_dup 2))])]
17646 (define_insn "*cmpstrqi_nz_1"
17647 [(set (reg:CC FLAGS_REG)
17648 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17649 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
17650 (use (match_operand:SI 6 "register_operand" "2"))
17651 (use (match_operand:SI 3 "immediate_operand" "i"))
17652 (use (reg:SI DIRFLAG_REG))
17653 (clobber (match_operand:SI 0 "register_operand" "=S"))
17654 (clobber (match_operand:SI 1 "register_operand" "=D"))
17655 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17658 [(set_attr "type" "str")
17659 (set_attr "mode" "QI")
17660 (set_attr "prefix_rep" "1")])
17662 (define_insn "*cmpstrqi_nz_rex_1"
17663 [(set (reg:CC FLAGS_REG)
17664 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17665 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
17666 (use (match_operand:DI 6 "register_operand" "2"))
17667 (use (match_operand:SI 3 "immediate_operand" "i"))
17668 (use (reg:SI DIRFLAG_REG))
17669 (clobber (match_operand:DI 0 "register_operand" "=S"))
17670 (clobber (match_operand:DI 1 "register_operand" "=D"))
17671 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17674 [(set_attr "type" "str")
17675 (set_attr "mode" "QI")
17676 (set_attr "prefix_rep" "1")])
17678 ;; The same, but the count is not known to not be zero.
17680 (define_expand "cmpstrqi_1"
17681 [(parallel [(set (reg:CC FLAGS_REG)
17682 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
17684 (compare:CC (match_operand 4 "memory_operand" "")
17685 (match_operand 5 "memory_operand" ""))
17687 (use (match_operand:SI 3 "immediate_operand" ""))
17688 (use (reg:CC FLAGS_REG))
17689 (use (reg:SI DIRFLAG_REG))
17690 (clobber (match_operand 0 "register_operand" ""))
17691 (clobber (match_operand 1 "register_operand" ""))
17692 (clobber (match_dup 2))])]
17696 (define_insn "*cmpstrqi_1"
17697 [(set (reg:CC FLAGS_REG)
17698 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
17700 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
17701 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
17703 (use (match_operand:SI 3 "immediate_operand" "i"))
17704 (use (reg:CC FLAGS_REG))
17705 (use (reg:SI DIRFLAG_REG))
17706 (clobber (match_operand:SI 0 "register_operand" "=S"))
17707 (clobber (match_operand:SI 1 "register_operand" "=D"))
17708 (clobber (match_operand:SI 2 "register_operand" "=c"))]
17711 [(set_attr "type" "str")
17712 (set_attr "mode" "QI")
17713 (set_attr "prefix_rep" "1")])
17715 (define_insn "*cmpstrqi_rex_1"
17716 [(set (reg:CC FLAGS_REG)
17717 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
17719 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
17720 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
17722 (use (match_operand:SI 3 "immediate_operand" "i"))
17723 (use (reg:CC FLAGS_REG))
17724 (use (reg:SI DIRFLAG_REG))
17725 (clobber (match_operand:DI 0 "register_operand" "=S"))
17726 (clobber (match_operand:DI 1 "register_operand" "=D"))
17727 (clobber (match_operand:DI 2 "register_operand" "=c"))]
17730 [(set_attr "type" "str")
17731 (set_attr "mode" "QI")
17732 (set_attr "prefix_rep" "1")])
17734 (define_expand "strlensi"
17735 [(set (match_operand:SI 0 "register_operand" "")
17736 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
17737 (match_operand:QI 2 "immediate_operand" "")
17738 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17741 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17747 (define_expand "strlendi"
17748 [(set (match_operand:DI 0 "register_operand" "")
17749 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
17750 (match_operand:QI 2 "immediate_operand" "")
17751 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
17754 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17760 (define_expand "strlenqi_1"
17761 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
17762 (use (reg:SI DIRFLAG_REG))
17763 (clobber (match_operand 1 "register_operand" ""))
17764 (clobber (reg:CC FLAGS_REG))])]
17768 (define_insn "*strlenqi_1"
17769 [(set (match_operand:SI 0 "register_operand" "=&c")
17770 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
17771 (match_operand:QI 2 "register_operand" "a")
17772 (match_operand:SI 3 "immediate_operand" "i")
17773 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
17774 (use (reg:SI DIRFLAG_REG))
17775 (clobber (match_operand:SI 1 "register_operand" "=D"))
17776 (clobber (reg:CC FLAGS_REG))]
17779 [(set_attr "type" "str")
17780 (set_attr "mode" "QI")
17781 (set_attr "prefix_rep" "1")])
17783 (define_insn "*strlenqi_rex_1"
17784 [(set (match_operand:DI 0 "register_operand" "=&c")
17785 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
17786 (match_operand:QI 2 "register_operand" "a")
17787 (match_operand:DI 3 "immediate_operand" "i")
17788 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
17789 (use (reg:SI DIRFLAG_REG))
17790 (clobber (match_operand:DI 1 "register_operand" "=D"))
17791 (clobber (reg:CC FLAGS_REG))]
17794 [(set_attr "type" "str")
17795 (set_attr "mode" "QI")
17796 (set_attr "prefix_rep" "1")])
17798 ;; Peephole optimizations to clean up after cmpstr*. This should be
17799 ;; handled in combine, but it is not currently up to the task.
17800 ;; When used for their truth value, the cmpstr* expanders generate
17809 ;; The intermediate three instructions are unnecessary.
17811 ;; This one handles cmpstr*_nz_1...
17814 (set (reg:CC FLAGS_REG)
17815 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17816 (mem:BLK (match_operand 5 "register_operand" ""))))
17817 (use (match_operand 6 "register_operand" ""))
17818 (use (match_operand:SI 3 "immediate_operand" ""))
17819 (use (reg:SI DIRFLAG_REG))
17820 (clobber (match_operand 0 "register_operand" ""))
17821 (clobber (match_operand 1 "register_operand" ""))
17822 (clobber (match_operand 2 "register_operand" ""))])
17823 (set (match_operand:QI 7 "register_operand" "")
17824 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17825 (set (match_operand:QI 8 "register_operand" "")
17826 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17827 (set (reg FLAGS_REG)
17828 (compare (match_dup 7) (match_dup 8)))
17830 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17832 (set (reg:CC FLAGS_REG)
17833 (compare:CC (mem:BLK (match_dup 4))
17834 (mem:BLK (match_dup 5))))
17835 (use (match_dup 6))
17836 (use (match_dup 3))
17837 (use (reg:SI DIRFLAG_REG))
17838 (clobber (match_dup 0))
17839 (clobber (match_dup 1))
17840 (clobber (match_dup 2))])]
17843 ;; ...and this one handles cmpstr*_1.
17846 (set (reg:CC FLAGS_REG)
17847 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
17849 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
17850 (mem:BLK (match_operand 5 "register_operand" "")))
17852 (use (match_operand:SI 3 "immediate_operand" ""))
17853 (use (reg:CC FLAGS_REG))
17854 (use (reg:SI DIRFLAG_REG))
17855 (clobber (match_operand 0 "register_operand" ""))
17856 (clobber (match_operand 1 "register_operand" ""))
17857 (clobber (match_operand 2 "register_operand" ""))])
17858 (set (match_operand:QI 7 "register_operand" "")
17859 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17860 (set (match_operand:QI 8 "register_operand" "")
17861 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17862 (set (reg FLAGS_REG)
17863 (compare (match_dup 7) (match_dup 8)))
17865 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17867 (set (reg:CC FLAGS_REG)
17868 (if_then_else:CC (ne (match_dup 6)
17870 (compare:CC (mem:BLK (match_dup 4))
17871 (mem:BLK (match_dup 5)))
17873 (use (match_dup 3))
17874 (use (reg:CC FLAGS_REG))
17875 (use (reg:SI DIRFLAG_REG))
17876 (clobber (match_dup 0))
17877 (clobber (match_dup 1))
17878 (clobber (match_dup 2))])]
17883 ;; Conditional move instructions.
17885 (define_expand "movdicc"
17886 [(set (match_operand:DI 0 "register_operand" "")
17887 (if_then_else:DI (match_operand 1 "comparison_operator" "")
17888 (match_operand:DI 2 "general_operand" "")
17889 (match_operand:DI 3 "general_operand" "")))]
17891 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17893 (define_insn "x86_movdicc_0_m1_rex64"
17894 [(set (match_operand:DI 0 "register_operand" "=r")
17895 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
17898 (clobber (reg:CC FLAGS_REG))]
17901 ; Since we don't have the proper number of operands for an alu insn,
17902 ; fill in all the blanks.
17903 [(set_attr "type" "alu")
17904 (set_attr "pent_pair" "pu")
17905 (set_attr "memory" "none")
17906 (set_attr "imm_disp" "false")
17907 (set_attr "mode" "DI")
17908 (set_attr "length_immediate" "0")])
17910 (define_insn "*movdicc_c_rex64"
17911 [(set (match_operand:DI 0 "register_operand" "=r,r")
17912 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17913 [(reg FLAGS_REG) (const_int 0)])
17914 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
17915 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
17916 "TARGET_64BIT && TARGET_CMOVE
17917 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17919 cmov%O2%C1\t{%2, %0|%0, %2}
17920 cmov%O2%c1\t{%3, %0|%0, %3}"
17921 [(set_attr "type" "icmov")
17922 (set_attr "mode" "DI")])
17924 (define_expand "movsicc"
17925 [(set (match_operand:SI 0 "register_operand" "")
17926 (if_then_else:SI (match_operand 1 "comparison_operator" "")
17927 (match_operand:SI 2 "general_operand" "")
17928 (match_operand:SI 3 "general_operand" "")))]
17930 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17932 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17933 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17934 ;; So just document what we're doing explicitly.
17936 (define_insn "x86_movsicc_0_m1"
17937 [(set (match_operand:SI 0 "register_operand" "=r")
17938 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
17941 (clobber (reg:CC FLAGS_REG))]
17944 ; Since we don't have the proper number of operands for an alu insn,
17945 ; fill in all the blanks.
17946 [(set_attr "type" "alu")
17947 (set_attr "pent_pair" "pu")
17948 (set_attr "memory" "none")
17949 (set_attr "imm_disp" "false")
17950 (set_attr "mode" "SI")
17951 (set_attr "length_immediate" "0")])
17953 (define_insn "*movsicc_noc"
17954 [(set (match_operand:SI 0 "register_operand" "=r,r")
17955 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
17956 [(reg FLAGS_REG) (const_int 0)])
17957 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
17958 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
17960 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17962 cmov%O2%C1\t{%2, %0|%0, %2}
17963 cmov%O2%c1\t{%3, %0|%0, %3}"
17964 [(set_attr "type" "icmov")
17965 (set_attr "mode" "SI")])
17967 (define_expand "movhicc"
17968 [(set (match_operand:HI 0 "register_operand" "")
17969 (if_then_else:HI (match_operand 1 "comparison_operator" "")
17970 (match_operand:HI 2 "general_operand" "")
17971 (match_operand:HI 3 "general_operand" "")))]
17972 "TARGET_HIMODE_MATH"
17973 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17975 (define_insn "*movhicc_noc"
17976 [(set (match_operand:HI 0 "register_operand" "=r,r")
17977 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
17978 [(reg FLAGS_REG) (const_int 0)])
17979 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
17980 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
17982 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
17984 cmov%O2%C1\t{%2, %0|%0, %2}
17985 cmov%O2%c1\t{%3, %0|%0, %3}"
17986 [(set_attr "type" "icmov")
17987 (set_attr "mode" "HI")])
17989 (define_expand "movqicc"
17990 [(set (match_operand:QI 0 "register_operand" "")
17991 (if_then_else:QI (match_operand 1 "comparison_operator" "")
17992 (match_operand:QI 2 "general_operand" "")
17993 (match_operand:QI 3 "general_operand" "")))]
17994 "TARGET_QIMODE_MATH"
17995 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
17997 (define_insn_and_split "*movqicc_noc"
17998 [(set (match_operand:QI 0 "register_operand" "=r,r")
17999 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18000 [(match_operand 4 "flags_reg_operand" "")
18002 (match_operand:QI 2 "register_operand" "r,0")
18003 (match_operand:QI 3 "register_operand" "0,r")))]
18004 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18006 "&& reload_completed"
18007 [(set (match_dup 0)
18008 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18011 "operands[0] = gen_lowpart (SImode, operands[0]);
18012 operands[2] = gen_lowpart (SImode, operands[2]);
18013 operands[3] = gen_lowpart (SImode, operands[3]);"
18014 [(set_attr "type" "icmov")
18015 (set_attr "mode" "SI")])
18017 (define_expand "movsfcc"
18018 [(set (match_operand:SF 0 "register_operand" "")
18019 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18020 (match_operand:SF 2 "register_operand" "")
18021 (match_operand:SF 3 "register_operand" "")))]
18022 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18023 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18025 (define_insn "*movsfcc_1_387"
18026 [(set (match_operand:SF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18027 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18028 [(reg FLAGS_REG) (const_int 0)])
18029 (match_operand:SF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18030 (match_operand:SF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18031 "TARGET_80387 && TARGET_CMOVE
18032 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18034 fcmov%F1\t{%2, %0|%0, %2}
18035 fcmov%f1\t{%3, %0|%0, %3}
18036 cmov%O2%C1\t{%2, %0|%0, %2}
18037 cmov%O2%c1\t{%3, %0|%0, %3}"
18038 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18039 (set_attr "mode" "SF,SF,SI,SI")])
18041 (define_expand "movdfcc"
18042 [(set (match_operand:DF 0 "register_operand" "")
18043 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18044 (match_operand:DF 2 "register_operand" "")
18045 (match_operand:DF 3 "register_operand" "")))]
18046 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18047 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18049 (define_insn "*movdfcc_1"
18050 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,&r#f,&r#f")
18051 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18052 [(reg FLAGS_REG) (const_int 0)])
18053 (match_operand:DF 2 "nonimmediate_operand" "f#r,0,rm#f,0")
18054 (match_operand:DF 3 "nonimmediate_operand" "0,f#r,0,rm#f")))]
18055 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18056 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18058 fcmov%F1\t{%2, %0|%0, %2}
18059 fcmov%f1\t{%3, %0|%0, %3}
18062 [(set_attr "type" "fcmov,fcmov,multi,multi")
18063 (set_attr "mode" "DF")])
18065 (define_insn "*movdfcc_1_rex64"
18066 [(set (match_operand:DF 0 "register_operand" "=f#r,f#r,r#f,r#f")
18067 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18068 [(reg FLAGS_REG) (const_int 0)])
18069 (match_operand:DF 2 "nonimmediate_operand" "f#r,0#r,rm#f,0#f")
18070 (match_operand:DF 3 "nonimmediate_operand" "0#r,f#r,0#f,rm#f")))]
18071 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18072 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18074 fcmov%F1\t{%2, %0|%0, %2}
18075 fcmov%f1\t{%3, %0|%0, %3}
18076 cmov%O2%C1\t{%2, %0|%0, %2}
18077 cmov%O2%c1\t{%3, %0|%0, %3}"
18078 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18079 (set_attr "mode" "DF")])
18082 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18083 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18084 [(match_operand 4 "flags_reg_operand" "")
18086 (match_operand:DF 2 "nonimmediate_operand" "")
18087 (match_operand:DF 3 "nonimmediate_operand" "")))]
18088 "!TARGET_64BIT && reload_completed"
18089 [(set (match_dup 2)
18090 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18094 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18097 "split_di (operands+2, 1, operands+5, operands+6);
18098 split_di (operands+3, 1, operands+7, operands+8);
18099 split_di (operands, 1, operands+2, operands+3);")
18101 (define_expand "movxfcc"
18102 [(set (match_operand:XF 0 "register_operand" "")
18103 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18104 (match_operand:XF 2 "register_operand" "")
18105 (match_operand:XF 3 "register_operand" "")))]
18106 "TARGET_80387 && TARGET_CMOVE"
18107 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18109 (define_insn "*movxfcc_1"
18110 [(set (match_operand:XF 0 "register_operand" "=f,f")
18111 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18112 [(reg FLAGS_REG) (const_int 0)])
18113 (match_operand:XF 2 "register_operand" "f,0")
18114 (match_operand:XF 3 "register_operand" "0,f")))]
18115 "TARGET_80387 && TARGET_CMOVE"
18117 fcmov%F1\t{%2, %0|%0, %2}
18118 fcmov%f1\t{%3, %0|%0, %3}"
18119 [(set_attr "type" "fcmov")
18120 (set_attr "mode" "XF")])
18122 ;; These versions of the min/max patterns are intentionally ignorant of
18123 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18124 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18125 ;; are undefined in this condition, we're certain this is correct.
18127 (define_insn "sminsf3"
18128 [(set (match_operand:SF 0 "register_operand" "=x")
18129 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18130 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18132 "minss\t{%2, %0|%0, %2}"
18133 [(set_attr "type" "sseadd")
18134 (set_attr "mode" "SF")])
18136 (define_insn "smaxsf3"
18137 [(set (match_operand:SF 0 "register_operand" "=x")
18138 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18139 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18141 "maxss\t{%2, %0|%0, %2}"
18142 [(set_attr "type" "sseadd")
18143 (set_attr "mode" "SF")])
18145 (define_insn "smindf3"
18146 [(set (match_operand:DF 0 "register_operand" "=x")
18147 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18148 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18149 "TARGET_SSE2 && TARGET_SSE_MATH"
18150 "minsd\t{%2, %0|%0, %2}"
18151 [(set_attr "type" "sseadd")
18152 (set_attr "mode" "DF")])
18154 (define_insn "smaxdf3"
18155 [(set (match_operand:DF 0 "register_operand" "=x")
18156 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18157 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18158 "TARGET_SSE2 && TARGET_SSE_MATH"
18159 "maxsd\t{%2, %0|%0, %2}"
18160 [(set_attr "type" "sseadd")
18161 (set_attr "mode" "DF")])
18163 ;; These versions of the min/max patterns implement exactly the operations
18164 ;; min = (op1 < op2 ? op1 : op2)
18165 ;; max = (!(op1 < op2) ? op1 : op2)
18166 ;; Their operands are not commutative, and thus they may be used in the
18167 ;; presence of -0.0 and NaN.
18169 (define_insn "*ieee_sminsf3"
18170 [(set (match_operand:SF 0 "register_operand" "=x")
18171 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18172 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18175 "minss\t{%2, %0|%0, %2}"
18176 [(set_attr "type" "sseadd")
18177 (set_attr "mode" "SF")])
18179 (define_insn "*ieee_smaxsf3"
18180 [(set (match_operand:SF 0 "register_operand" "=x")
18181 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18182 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18185 "maxss\t{%2, %0|%0, %2}"
18186 [(set_attr "type" "sseadd")
18187 (set_attr "mode" "SF")])
18189 (define_insn "*ieee_smindf3"
18190 [(set (match_operand:DF 0 "register_operand" "=x")
18191 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18192 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18194 "TARGET_SSE2 && TARGET_SSE_MATH"
18195 "minsd\t{%2, %0|%0, %2}"
18196 [(set_attr "type" "sseadd")
18197 (set_attr "mode" "DF")])
18199 (define_insn "*ieee_smaxdf3"
18200 [(set (match_operand:DF 0 "register_operand" "=x")
18201 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18202 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18204 "TARGET_SSE2 && TARGET_SSE_MATH"
18205 "maxsd\t{%2, %0|%0, %2}"
18206 [(set_attr "type" "sseadd")
18207 (set_attr "mode" "DF")])
18209 ;; Conditional addition patterns
18210 (define_expand "addqicc"
18211 [(match_operand:QI 0 "register_operand" "")
18212 (match_operand 1 "comparison_operator" "")
18213 (match_operand:QI 2 "register_operand" "")
18214 (match_operand:QI 3 "const_int_operand" "")]
18216 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18218 (define_expand "addhicc"
18219 [(match_operand:HI 0 "register_operand" "")
18220 (match_operand 1 "comparison_operator" "")
18221 (match_operand:HI 2 "register_operand" "")
18222 (match_operand:HI 3 "const_int_operand" "")]
18224 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18226 (define_expand "addsicc"
18227 [(match_operand:SI 0 "register_operand" "")
18228 (match_operand 1 "comparison_operator" "")
18229 (match_operand:SI 2 "register_operand" "")
18230 (match_operand:SI 3 "const_int_operand" "")]
18232 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18234 (define_expand "adddicc"
18235 [(match_operand:DI 0 "register_operand" "")
18236 (match_operand 1 "comparison_operator" "")
18237 (match_operand:DI 2 "register_operand" "")
18238 (match_operand:DI 3 "const_int_operand" "")]
18240 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18243 ;; Misc patterns (?)
18245 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18246 ;; Otherwise there will be nothing to keep
18248 ;; [(set (reg ebp) (reg esp))]
18249 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18250 ;; (clobber (eflags)]
18251 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18253 ;; in proper program order.
18254 (define_insn "pro_epilogue_adjust_stack_1"
18255 [(set (match_operand:SI 0 "register_operand" "=r,r")
18256 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18257 (match_operand:SI 2 "immediate_operand" "i,i")))
18258 (clobber (reg:CC FLAGS_REG))
18259 (clobber (mem:BLK (scratch)))]
18262 switch (get_attr_type (insn))
18265 return "mov{l}\t{%1, %0|%0, %1}";
18268 if (GET_CODE (operands[2]) == CONST_INT
18269 && (INTVAL (operands[2]) == 128
18270 || (INTVAL (operands[2]) < 0
18271 && INTVAL (operands[2]) != -128)))
18273 operands[2] = GEN_INT (-INTVAL (operands[2]));
18274 return "sub{l}\t{%2, %0|%0, %2}";
18276 return "add{l}\t{%2, %0|%0, %2}";
18279 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18280 return "lea{l}\t{%a2, %0|%0, %a2}";
18286 [(set (attr "type")
18287 (cond [(eq_attr "alternative" "0")
18288 (const_string "alu")
18289 (match_operand:SI 2 "const0_operand" "")
18290 (const_string "imov")
18292 (const_string "lea")))
18293 (set_attr "mode" "SI")])
18295 (define_insn "pro_epilogue_adjust_stack_rex64"
18296 [(set (match_operand:DI 0 "register_operand" "=r,r")
18297 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18298 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18299 (clobber (reg:CC FLAGS_REG))
18300 (clobber (mem:BLK (scratch)))]
18303 switch (get_attr_type (insn))
18306 return "mov{q}\t{%1, %0|%0, %1}";
18309 if (GET_CODE (operands[2]) == CONST_INT
18310 /* Avoid overflows. */
18311 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18312 && (INTVAL (operands[2]) == 128
18313 || (INTVAL (operands[2]) < 0
18314 && INTVAL (operands[2]) != -128)))
18316 operands[2] = GEN_INT (-INTVAL (operands[2]));
18317 return "sub{q}\t{%2, %0|%0, %2}";
18319 return "add{q}\t{%2, %0|%0, %2}";
18322 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18323 return "lea{q}\t{%a2, %0|%0, %a2}";
18329 [(set (attr "type")
18330 (cond [(eq_attr "alternative" "0")
18331 (const_string "alu")
18332 (match_operand:DI 2 "const0_operand" "")
18333 (const_string "imov")
18335 (const_string "lea")))
18336 (set_attr "mode" "DI")])
18338 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18339 [(set (match_operand:DI 0 "register_operand" "=r,r")
18340 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18341 (match_operand:DI 3 "immediate_operand" "i,i")))
18342 (use (match_operand:DI 2 "register_operand" "r,r"))
18343 (clobber (reg:CC FLAGS_REG))
18344 (clobber (mem:BLK (scratch)))]
18347 switch (get_attr_type (insn))
18350 return "add{q}\t{%2, %0|%0, %2}";
18353 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18354 return "lea{q}\t{%a2, %0|%0, %a2}";
18360 [(set_attr "type" "alu,lea")
18361 (set_attr "mode" "DI")])
18363 (define_expand "allocate_stack_worker"
18364 [(match_operand:SI 0 "register_operand" "")]
18365 "TARGET_STACK_PROBE"
18367 if (reload_completed)
18370 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
18372 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
18377 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
18379 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
18384 (define_insn "allocate_stack_worker_1"
18385 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18386 UNSPECV_STACK_PROBE)
18387 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18388 (clobber (match_scratch:SI 1 "=0"))
18389 (clobber (reg:CC FLAGS_REG))]
18390 "!TARGET_64BIT && TARGET_STACK_PROBE"
18392 [(set_attr "type" "multi")
18393 (set_attr "length" "5")])
18395 (define_expand "allocate_stack_worker_postreload"
18396 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
18397 UNSPECV_STACK_PROBE)
18398 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
18399 (clobber (match_dup 0))
18400 (clobber (reg:CC FLAGS_REG))])]
18404 (define_insn "allocate_stack_worker_rex64"
18405 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18406 UNSPECV_STACK_PROBE)
18407 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18408 (clobber (match_scratch:DI 1 "=0"))
18409 (clobber (reg:CC FLAGS_REG))]
18410 "TARGET_64BIT && TARGET_STACK_PROBE"
18412 [(set_attr "type" "multi")
18413 (set_attr "length" "5")])
18415 (define_expand "allocate_stack_worker_rex64_postreload"
18416 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
18417 UNSPECV_STACK_PROBE)
18418 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
18419 (clobber (match_dup 0))
18420 (clobber (reg:CC FLAGS_REG))])]
18424 (define_expand "allocate_stack"
18425 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
18426 (minus:SI (reg:SI SP_REG)
18427 (match_operand:SI 1 "general_operand" "")))
18428 (clobber (reg:CC FLAGS_REG))])
18429 (parallel [(set (reg:SI SP_REG)
18430 (minus:SI (reg:SI SP_REG) (match_dup 1)))
18431 (clobber (reg:CC FLAGS_REG))])]
18432 "TARGET_STACK_PROBE"
18434 #ifdef CHECK_STACK_LIMIT
18435 if (GET_CODE (operands[1]) == CONST_INT
18436 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18437 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
18441 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
18444 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18448 (define_expand "builtin_setjmp_receiver"
18449 [(label_ref (match_operand 0 "" ""))]
18450 "!TARGET_64BIT && flag_pic"
18452 emit_insn (gen_set_got (pic_offset_table_rtx));
18456 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18459 [(set (match_operand 0 "register_operand" "")
18460 (match_operator 3 "promotable_binary_operator"
18461 [(match_operand 1 "register_operand" "")
18462 (match_operand 2 "aligned_operand" "")]))
18463 (clobber (reg:CC FLAGS_REG))]
18464 "! TARGET_PARTIAL_REG_STALL && reload_completed
18465 && ((GET_MODE (operands[0]) == HImode
18466 && ((!optimize_size && !TARGET_FAST_PREFIX)
18467 || GET_CODE (operands[2]) != CONST_INT
18468 || CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')))
18469 || (GET_MODE (operands[0]) == QImode
18470 && (TARGET_PROMOTE_QImode || optimize_size)))"
18471 [(parallel [(set (match_dup 0)
18472 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18473 (clobber (reg:CC FLAGS_REG))])]
18474 "operands[0] = gen_lowpart (SImode, operands[0]);
18475 operands[1] = gen_lowpart (SImode, operands[1]);
18476 if (GET_CODE (operands[3]) != ASHIFT)
18477 operands[2] = gen_lowpart (SImode, operands[2]);
18478 PUT_MODE (operands[3], SImode);")
18480 ; Promote the QImode tests, as i386 has encoding of the AND
18481 ; instruction with 32-bit sign-extended immediate and thus the
18482 ; instruction size is unchanged, except in the %eax case for
18483 ; which it is increased by one byte, hence the ! optimize_size.
18485 [(set (match_operand 0 "flags_reg_operand" "")
18486 (match_operator 2 "compare_operator"
18487 [(and (match_operand 3 "aligned_operand" "")
18488 (match_operand 4 "const_int_operand" ""))
18490 (set (match_operand 1 "register_operand" "")
18491 (and (match_dup 3) (match_dup 4)))]
18492 "! TARGET_PARTIAL_REG_STALL && reload_completed
18493 /* Ensure that the operand will remain sign-extended immediate. */
18494 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
18496 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18497 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
18498 [(parallel [(set (match_dup 0)
18499 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18502 (and:SI (match_dup 3) (match_dup 4)))])]
18505 = gen_int_mode (INTVAL (operands[4])
18506 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18507 operands[1] = gen_lowpart (SImode, operands[1]);
18508 operands[3] = gen_lowpart (SImode, operands[3]);
18511 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18512 ; the TEST instruction with 32-bit sign-extended immediate and thus
18513 ; the instruction size would at least double, which is not what we
18514 ; want even with ! optimize_size.
18516 [(set (match_operand 0 "flags_reg_operand" "")
18517 (match_operator 1 "compare_operator"
18518 [(and (match_operand:HI 2 "aligned_operand" "")
18519 (match_operand:HI 3 "const_int_operand" ""))
18521 "! TARGET_PARTIAL_REG_STALL && reload_completed
18522 /* Ensure that the operand will remain sign-extended immediate. */
18523 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
18524 && ! TARGET_FAST_PREFIX
18525 && ! optimize_size"
18526 [(set (match_dup 0)
18527 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18531 = gen_int_mode (INTVAL (operands[3])
18532 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18533 operands[2] = gen_lowpart (SImode, operands[2]);
18537 [(set (match_operand 0 "register_operand" "")
18538 (neg (match_operand 1 "register_operand" "")))
18539 (clobber (reg:CC FLAGS_REG))]
18540 "! TARGET_PARTIAL_REG_STALL && reload_completed
18541 && (GET_MODE (operands[0]) == HImode
18542 || (GET_MODE (operands[0]) == QImode
18543 && (TARGET_PROMOTE_QImode || optimize_size)))"
18544 [(parallel [(set (match_dup 0)
18545 (neg:SI (match_dup 1)))
18546 (clobber (reg:CC FLAGS_REG))])]
18547 "operands[0] = gen_lowpart (SImode, operands[0]);
18548 operands[1] = gen_lowpart (SImode, operands[1]);")
18551 [(set (match_operand 0 "register_operand" "")
18552 (not (match_operand 1 "register_operand" "")))]
18553 "! TARGET_PARTIAL_REG_STALL && reload_completed
18554 && (GET_MODE (operands[0]) == HImode
18555 || (GET_MODE (operands[0]) == QImode
18556 && (TARGET_PROMOTE_QImode || optimize_size)))"
18557 [(set (match_dup 0)
18558 (not:SI (match_dup 1)))]
18559 "operands[0] = gen_lowpart (SImode, operands[0]);
18560 operands[1] = gen_lowpart (SImode, operands[1]);")
18563 [(set (match_operand 0 "register_operand" "")
18564 (if_then_else (match_operator 1 "comparison_operator"
18565 [(reg FLAGS_REG) (const_int 0)])
18566 (match_operand 2 "register_operand" "")
18567 (match_operand 3 "register_operand" "")))]
18568 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18569 && (GET_MODE (operands[0]) == HImode
18570 || (GET_MODE (operands[0]) == QImode
18571 && (TARGET_PROMOTE_QImode || optimize_size)))"
18572 [(set (match_dup 0)
18573 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18574 "operands[0] = gen_lowpart (SImode, operands[0]);
18575 operands[2] = gen_lowpart (SImode, operands[2]);
18576 operands[3] = gen_lowpart (SImode, operands[3]);")
18579 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18580 ;; transform a complex memory operation into two memory to register operations.
18582 ;; Don't push memory operands
18584 [(set (match_operand:SI 0 "push_operand" "")
18585 (match_operand:SI 1 "memory_operand" ""))
18586 (match_scratch:SI 2 "r")]
18587 "! optimize_size && ! TARGET_PUSH_MEMORY"
18588 [(set (match_dup 2) (match_dup 1))
18589 (set (match_dup 0) (match_dup 2))]
18593 [(set (match_operand:DI 0 "push_operand" "")
18594 (match_operand:DI 1 "memory_operand" ""))
18595 (match_scratch:DI 2 "r")]
18596 "! optimize_size && ! TARGET_PUSH_MEMORY"
18597 [(set (match_dup 2) (match_dup 1))
18598 (set (match_dup 0) (match_dup 2))]
18601 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18604 [(set (match_operand:SF 0 "push_operand" "")
18605 (match_operand:SF 1 "memory_operand" ""))
18606 (match_scratch:SF 2 "r")]
18607 "! optimize_size && ! TARGET_PUSH_MEMORY"
18608 [(set (match_dup 2) (match_dup 1))
18609 (set (match_dup 0) (match_dup 2))]
18613 [(set (match_operand:HI 0 "push_operand" "")
18614 (match_operand:HI 1 "memory_operand" ""))
18615 (match_scratch:HI 2 "r")]
18616 "! optimize_size && ! TARGET_PUSH_MEMORY"
18617 [(set (match_dup 2) (match_dup 1))
18618 (set (match_dup 0) (match_dup 2))]
18622 [(set (match_operand:QI 0 "push_operand" "")
18623 (match_operand:QI 1 "memory_operand" ""))
18624 (match_scratch:QI 2 "q")]
18625 "! optimize_size && ! TARGET_PUSH_MEMORY"
18626 [(set (match_dup 2) (match_dup 1))
18627 (set (match_dup 0) (match_dup 2))]
18630 ;; Don't move an immediate directly to memory when the instruction
18633 [(match_scratch:SI 1 "r")
18634 (set (match_operand:SI 0 "memory_operand" "")
18637 && ! TARGET_USE_MOV0
18638 && TARGET_SPLIT_LONG_MOVES
18639 && get_attr_length (insn) >= ix86_cost->large_insn
18640 && peep2_regno_dead_p (0, FLAGS_REG)"
18641 [(parallel [(set (match_dup 1) (const_int 0))
18642 (clobber (reg:CC FLAGS_REG))])
18643 (set (match_dup 0) (match_dup 1))]
18647 [(match_scratch:HI 1 "r")
18648 (set (match_operand:HI 0 "memory_operand" "")
18651 && ! TARGET_USE_MOV0
18652 && TARGET_SPLIT_LONG_MOVES
18653 && get_attr_length (insn) >= ix86_cost->large_insn
18654 && peep2_regno_dead_p (0, FLAGS_REG)"
18655 [(parallel [(set (match_dup 2) (const_int 0))
18656 (clobber (reg:CC FLAGS_REG))])
18657 (set (match_dup 0) (match_dup 1))]
18658 "operands[2] = gen_lowpart (SImode, operands[1]);")
18661 [(match_scratch:QI 1 "q")
18662 (set (match_operand:QI 0 "memory_operand" "")
18665 && ! TARGET_USE_MOV0
18666 && TARGET_SPLIT_LONG_MOVES
18667 && get_attr_length (insn) >= ix86_cost->large_insn
18668 && peep2_regno_dead_p (0, FLAGS_REG)"
18669 [(parallel [(set (match_dup 2) (const_int 0))
18670 (clobber (reg:CC FLAGS_REG))])
18671 (set (match_dup 0) (match_dup 1))]
18672 "operands[2] = gen_lowpart (SImode, operands[1]);")
18675 [(match_scratch:SI 2 "r")
18676 (set (match_operand:SI 0 "memory_operand" "")
18677 (match_operand:SI 1 "immediate_operand" ""))]
18679 && get_attr_length (insn) >= ix86_cost->large_insn
18680 && TARGET_SPLIT_LONG_MOVES"
18681 [(set (match_dup 2) (match_dup 1))
18682 (set (match_dup 0) (match_dup 2))]
18686 [(match_scratch:HI 2 "r")
18687 (set (match_operand:HI 0 "memory_operand" "")
18688 (match_operand:HI 1 "immediate_operand" ""))]
18689 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18690 && TARGET_SPLIT_LONG_MOVES"
18691 [(set (match_dup 2) (match_dup 1))
18692 (set (match_dup 0) (match_dup 2))]
18696 [(match_scratch:QI 2 "q")
18697 (set (match_operand:QI 0 "memory_operand" "")
18698 (match_operand:QI 1 "immediate_operand" ""))]
18699 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
18700 && TARGET_SPLIT_LONG_MOVES"
18701 [(set (match_dup 2) (match_dup 1))
18702 (set (match_dup 0) (match_dup 2))]
18705 ;; Don't compare memory with zero, load and use a test instead.
18707 [(set (match_operand 0 "flags_reg_operand" "")
18708 (match_operator 1 "compare_operator"
18709 [(match_operand:SI 2 "memory_operand" "")
18711 (match_scratch:SI 3 "r")]
18712 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
18713 [(set (match_dup 3) (match_dup 2))
18714 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
18717 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18718 ;; Don't split NOTs with a displacement operand, because resulting XOR
18719 ;; will not be pairable anyway.
18721 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18722 ;; represented using a modRM byte. The XOR replacement is long decoded,
18723 ;; so this split helps here as well.
18725 ;; Note: Can't do this as a regular split because we can't get proper
18726 ;; lifetime information then.
18729 [(set (match_operand:SI 0 "nonimmediate_operand" "")
18730 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
18732 && peep2_regno_dead_p (0, FLAGS_REG)
18733 && ((TARGET_PENTIUM
18734 && (GET_CODE (operands[0]) != MEM
18735 || !memory_displacement_operand (operands[0], SImode)))
18736 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
18737 [(parallel [(set (match_dup 0)
18738 (xor:SI (match_dup 1) (const_int -1)))
18739 (clobber (reg:CC FLAGS_REG))])]
18743 [(set (match_operand:HI 0 "nonimmediate_operand" "")
18744 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
18746 && peep2_regno_dead_p (0, FLAGS_REG)
18747 && ((TARGET_PENTIUM
18748 && (GET_CODE (operands[0]) != MEM
18749 || !memory_displacement_operand (operands[0], HImode)))
18750 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
18751 [(parallel [(set (match_dup 0)
18752 (xor:HI (match_dup 1) (const_int -1)))
18753 (clobber (reg:CC FLAGS_REG))])]
18757 [(set (match_operand:QI 0 "nonimmediate_operand" "")
18758 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
18760 && peep2_regno_dead_p (0, FLAGS_REG)
18761 && ((TARGET_PENTIUM
18762 && (GET_CODE (operands[0]) != MEM
18763 || !memory_displacement_operand (operands[0], QImode)))
18764 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
18765 [(parallel [(set (match_dup 0)
18766 (xor:QI (match_dup 1) (const_int -1)))
18767 (clobber (reg:CC FLAGS_REG))])]
18770 ;; Non pairable "test imm, reg" instructions can be translated to
18771 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18772 ;; byte opcode instead of two, have a short form for byte operands),
18773 ;; so do it for other CPUs as well. Given that the value was dead,
18774 ;; this should not create any new dependencies. Pass on the sub-word
18775 ;; versions if we're concerned about partial register stalls.
18778 [(set (match_operand 0 "flags_reg_operand" "")
18779 (match_operator 1 "compare_operator"
18780 [(and:SI (match_operand:SI 2 "register_operand" "")
18781 (match_operand:SI 3 "immediate_operand" ""))
18783 "ix86_match_ccmode (insn, CCNOmode)
18784 && (true_regnum (operands[2]) != 0
18785 || (GET_CODE (operands[3]) == CONST_INT
18786 && CONST_OK_FOR_LETTER_P (INTVAL (operands[3]), 'K')))
18787 && peep2_reg_dead_p (1, operands[2])"
18789 [(set (match_dup 0)
18790 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18793 (and:SI (match_dup 2) (match_dup 3)))])]
18796 ;; We don't need to handle HImode case, because it will be promoted to SImode
18797 ;; on ! TARGET_PARTIAL_REG_STALL
18800 [(set (match_operand 0 "flags_reg_operand" "")
18801 (match_operator 1 "compare_operator"
18802 [(and:QI (match_operand:QI 2 "register_operand" "")
18803 (match_operand:QI 3 "immediate_operand" ""))
18805 "! TARGET_PARTIAL_REG_STALL
18806 && ix86_match_ccmode (insn, CCNOmode)
18807 && true_regnum (operands[2]) != 0
18808 && peep2_reg_dead_p (1, operands[2])"
18810 [(set (match_dup 0)
18811 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18814 (and:QI (match_dup 2) (match_dup 3)))])]
18818 [(set (match_operand 0 "flags_reg_operand" "")
18819 (match_operator 1 "compare_operator"
18822 (match_operand 2 "ext_register_operand" "")
18825 (match_operand 3 "const_int_operand" ""))
18827 "! TARGET_PARTIAL_REG_STALL
18828 && ix86_match_ccmode (insn, CCNOmode)
18829 && true_regnum (operands[2]) != 0
18830 && peep2_reg_dead_p (1, operands[2])"
18831 [(parallel [(set (match_dup 0)
18840 (set (zero_extract:SI (match_dup 2)
18851 ;; Don't do logical operations with memory inputs.
18853 [(match_scratch:SI 2 "r")
18854 (parallel [(set (match_operand:SI 0 "register_operand" "")
18855 (match_operator:SI 3 "arith_or_logical_operator"
18857 (match_operand:SI 1 "memory_operand" "")]))
18858 (clobber (reg:CC FLAGS_REG))])]
18859 "! optimize_size && ! TARGET_READ_MODIFY"
18860 [(set (match_dup 2) (match_dup 1))
18861 (parallel [(set (match_dup 0)
18862 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18863 (clobber (reg:CC FLAGS_REG))])]
18867 [(match_scratch:SI 2 "r")
18868 (parallel [(set (match_operand:SI 0 "register_operand" "")
18869 (match_operator:SI 3 "arith_or_logical_operator"
18870 [(match_operand:SI 1 "memory_operand" "")
18872 (clobber (reg:CC FLAGS_REG))])]
18873 "! optimize_size && ! TARGET_READ_MODIFY"
18874 [(set (match_dup 2) (match_dup 1))
18875 (parallel [(set (match_dup 0)
18876 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18877 (clobber (reg:CC FLAGS_REG))])]
18880 ; Don't do logical operations with memory outputs
18882 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18883 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18884 ; the same decoder scheduling characteristics as the original.
18887 [(match_scratch:SI 2 "r")
18888 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18889 (match_operator:SI 3 "arith_or_logical_operator"
18891 (match_operand:SI 1 "nonmemory_operand" "")]))
18892 (clobber (reg:CC FLAGS_REG))])]
18893 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18894 [(set (match_dup 2) (match_dup 0))
18895 (parallel [(set (match_dup 2)
18896 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18897 (clobber (reg:CC FLAGS_REG))])
18898 (set (match_dup 0) (match_dup 2))]
18902 [(match_scratch:SI 2 "r")
18903 (parallel [(set (match_operand:SI 0 "memory_operand" "")
18904 (match_operator:SI 3 "arith_or_logical_operator"
18905 [(match_operand:SI 1 "nonmemory_operand" "")
18907 (clobber (reg:CC FLAGS_REG))])]
18908 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
18909 [(set (match_dup 2) (match_dup 0))
18910 (parallel [(set (match_dup 2)
18911 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18912 (clobber (reg:CC FLAGS_REG))])
18913 (set (match_dup 0) (match_dup 2))]
18916 ;; Attempt to always use XOR for zeroing registers.
18918 [(set (match_operand 0 "register_operand" "")
18919 (match_operand 1 "const0_operand" ""))]
18920 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18921 && (! TARGET_USE_MOV0 || optimize_size)
18922 && GENERAL_REG_P (operands[0])
18923 && peep2_regno_dead_p (0, FLAGS_REG)"
18924 [(parallel [(set (match_dup 0) (const_int 0))
18925 (clobber (reg:CC FLAGS_REG))])]
18927 operands[0] = gen_lowpart (word_mode, operands[0]);
18931 [(set (strict_low_part (match_operand 0 "register_operand" ""))
18933 "(GET_MODE (operands[0]) == QImode
18934 || GET_MODE (operands[0]) == HImode)
18935 && (! TARGET_USE_MOV0 || optimize_size)
18936 && peep2_regno_dead_p (0, FLAGS_REG)"
18937 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18938 (clobber (reg:CC FLAGS_REG))])])
18940 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
18942 [(set (match_operand 0 "register_operand" "")
18944 "(GET_MODE (operands[0]) == HImode
18945 || GET_MODE (operands[0]) == SImode
18946 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
18947 && (optimize_size || TARGET_PENTIUM)
18948 && peep2_regno_dead_p (0, FLAGS_REG)"
18949 [(parallel [(set (match_dup 0) (const_int -1))
18950 (clobber (reg:CC FLAGS_REG))])]
18951 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
18954 ;; Attempt to convert simple leas to adds. These can be created by
18957 [(set (match_operand:SI 0 "register_operand" "")
18958 (plus:SI (match_dup 0)
18959 (match_operand:SI 1 "nonmemory_operand" "")))]
18960 "peep2_regno_dead_p (0, FLAGS_REG)"
18961 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
18962 (clobber (reg:CC FLAGS_REG))])]
18966 [(set (match_operand:SI 0 "register_operand" "")
18967 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
18968 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
18969 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
18970 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
18971 (clobber (reg:CC FLAGS_REG))])]
18972 "operands[2] = gen_lowpart (SImode, operands[2]);")
18975 [(set (match_operand:DI 0 "register_operand" "")
18976 (plus:DI (match_dup 0)
18977 (match_operand:DI 1 "x86_64_general_operand" "")))]
18978 "peep2_regno_dead_p (0, FLAGS_REG)"
18979 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
18980 (clobber (reg:CC FLAGS_REG))])]
18984 [(set (match_operand:SI 0 "register_operand" "")
18985 (mult:SI (match_dup 0)
18986 (match_operand:SI 1 "const_int_operand" "")))]
18987 "exact_log2 (INTVAL (operands[1])) >= 0
18988 && peep2_regno_dead_p (0, FLAGS_REG)"
18989 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
18990 (clobber (reg:CC FLAGS_REG))])]
18991 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18994 [(set (match_operand:DI 0 "register_operand" "")
18995 (mult:DI (match_dup 0)
18996 (match_operand:DI 1 "const_int_operand" "")))]
18997 "exact_log2 (INTVAL (operands[1])) >= 0
18998 && peep2_regno_dead_p (0, FLAGS_REG)"
18999 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19000 (clobber (reg:CC FLAGS_REG))])]
19001 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19004 [(set (match_operand:SI 0 "register_operand" "")
19005 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19006 (match_operand:DI 2 "const_int_operand" "")) 0))]
19007 "exact_log2 (INTVAL (operands[2])) >= 0
19008 && REGNO (operands[0]) == REGNO (operands[1])
19009 && peep2_regno_dead_p (0, FLAGS_REG)"
19010 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19011 (clobber (reg:CC FLAGS_REG))])]
19012 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19014 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19015 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19016 ;; many CPUs it is also faster, since special hardware to avoid esp
19017 ;; dependencies is present.
19019 ;; While some of these conversions may be done using splitters, we use peepholes
19020 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19022 ;; Convert prologue esp subtractions to push.
19023 ;; We need register to push. In order to keep verify_flow_info happy we have
19025 ;; - use scratch and clobber it in order to avoid dependencies
19026 ;; - use already live register
19027 ;; We can't use the second way right now, since there is no reliable way how to
19028 ;; verify that given register is live. First choice will also most likely in
19029 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19030 ;; call clobbered registers are dead. We may want to use base pointer as an
19031 ;; alternative when no register is available later.
19034 [(match_scratch:SI 0 "r")
19035 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19036 (clobber (reg:CC FLAGS_REG))
19037 (clobber (mem:BLK (scratch)))])]
19038 "optimize_size || !TARGET_SUB_ESP_4"
19039 [(clobber (match_dup 0))
19040 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19041 (clobber (mem:BLK (scratch)))])])
19044 [(match_scratch:SI 0 "r")
19045 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19046 (clobber (reg:CC FLAGS_REG))
19047 (clobber (mem:BLK (scratch)))])]
19048 "optimize_size || !TARGET_SUB_ESP_8"
19049 [(clobber (match_dup 0))
19050 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19051 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19052 (clobber (mem:BLK (scratch)))])])
19054 ;; Convert esp subtractions to push.
19056 [(match_scratch:SI 0 "r")
19057 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19058 (clobber (reg:CC FLAGS_REG))])]
19059 "optimize_size || !TARGET_SUB_ESP_4"
19060 [(clobber (match_dup 0))
19061 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19064 [(match_scratch:SI 0 "r")
19065 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19066 (clobber (reg:CC FLAGS_REG))])]
19067 "optimize_size || !TARGET_SUB_ESP_8"
19068 [(clobber (match_dup 0))
19069 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19070 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19072 ;; Convert epilogue deallocator to pop.
19074 [(match_scratch:SI 0 "r")
19075 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19076 (clobber (reg:CC FLAGS_REG))
19077 (clobber (mem:BLK (scratch)))])]
19078 "optimize_size || !TARGET_ADD_ESP_4"
19079 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19080 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19081 (clobber (mem:BLK (scratch)))])]
19084 ;; Two pops case is tricky, since pop causes dependency on destination register.
19085 ;; We use two registers if available.
19087 [(match_scratch:SI 0 "r")
19088 (match_scratch:SI 1 "r")
19089 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19090 (clobber (reg:CC FLAGS_REG))
19091 (clobber (mem:BLK (scratch)))])]
19092 "optimize_size || !TARGET_ADD_ESP_8"
19093 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19094 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19095 (clobber (mem:BLK (scratch)))])
19096 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19097 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19101 [(match_scratch:SI 0 "r")
19102 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19103 (clobber (reg:CC FLAGS_REG))
19104 (clobber (mem:BLK (scratch)))])]
19106 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19107 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19108 (clobber (mem:BLK (scratch)))])
19109 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19110 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19113 ;; Convert esp additions to pop.
19115 [(match_scratch:SI 0 "r")
19116 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19117 (clobber (reg:CC FLAGS_REG))])]
19119 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19120 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19123 ;; Two pops case is tricky, since pop causes dependency on destination register.
19124 ;; We use two registers if available.
19126 [(match_scratch:SI 0 "r")
19127 (match_scratch:SI 1 "r")
19128 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19129 (clobber (reg:CC FLAGS_REG))])]
19131 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19132 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19133 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19134 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19138 [(match_scratch:SI 0 "r")
19139 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19140 (clobber (reg:CC FLAGS_REG))])]
19142 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19143 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19144 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19145 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19148 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19149 ;; required and register dies. Similarly for 128 to plus -128.
19151 [(set (match_operand 0 "flags_reg_operand" "")
19152 (match_operator 1 "compare_operator"
19153 [(match_operand 2 "register_operand" "")
19154 (match_operand 3 "const_int_operand" "")]))]
19155 "(INTVAL (operands[3]) == -1
19156 || INTVAL (operands[3]) == 1
19157 || INTVAL (operands[3]) == 128)
19158 && ix86_match_ccmode (insn, CCGCmode)
19159 && peep2_reg_dead_p (1, operands[2])"
19160 [(parallel [(set (match_dup 0)
19161 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19162 (clobber (match_dup 2))])]
19166 [(match_scratch:DI 0 "r")
19167 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19168 (clobber (reg:CC FLAGS_REG))
19169 (clobber (mem:BLK (scratch)))])]
19170 "optimize_size || !TARGET_SUB_ESP_4"
19171 [(clobber (match_dup 0))
19172 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19173 (clobber (mem:BLK (scratch)))])])
19176 [(match_scratch:DI 0 "r")
19177 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19178 (clobber (reg:CC FLAGS_REG))
19179 (clobber (mem:BLK (scratch)))])]
19180 "optimize_size || !TARGET_SUB_ESP_8"
19181 [(clobber (match_dup 0))
19182 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19183 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19184 (clobber (mem:BLK (scratch)))])])
19186 ;; Convert esp subtractions to push.
19188 [(match_scratch:DI 0 "r")
19189 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19190 (clobber (reg:CC FLAGS_REG))])]
19191 "optimize_size || !TARGET_SUB_ESP_4"
19192 [(clobber (match_dup 0))
19193 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19196 [(match_scratch:DI 0 "r")
19197 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19198 (clobber (reg:CC FLAGS_REG))])]
19199 "optimize_size || !TARGET_SUB_ESP_8"
19200 [(clobber (match_dup 0))
19201 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19202 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19204 ;; Convert epilogue deallocator to pop.
19206 [(match_scratch:DI 0 "r")
19207 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19208 (clobber (reg:CC FLAGS_REG))
19209 (clobber (mem:BLK (scratch)))])]
19210 "optimize_size || !TARGET_ADD_ESP_4"
19211 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19212 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19213 (clobber (mem:BLK (scratch)))])]
19216 ;; Two pops case is tricky, since pop causes dependency on destination register.
19217 ;; We use two registers if available.
19219 [(match_scratch:DI 0 "r")
19220 (match_scratch:DI 1 "r")
19221 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19222 (clobber (reg:CC FLAGS_REG))
19223 (clobber (mem:BLK (scratch)))])]
19224 "optimize_size || !TARGET_ADD_ESP_8"
19225 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19226 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19227 (clobber (mem:BLK (scratch)))])
19228 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19229 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19233 [(match_scratch:DI 0 "r")
19234 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19235 (clobber (reg:CC FLAGS_REG))
19236 (clobber (mem:BLK (scratch)))])]
19238 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19239 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19240 (clobber (mem:BLK (scratch)))])
19241 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19242 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19245 ;; Convert esp additions to pop.
19247 [(match_scratch:DI 0 "r")
19248 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19249 (clobber (reg:CC FLAGS_REG))])]
19251 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19252 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19255 ;; Two pops case is tricky, since pop causes dependency on destination register.
19256 ;; We use two registers if available.
19258 [(match_scratch:DI 0 "r")
19259 (match_scratch:DI 1 "r")
19260 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19261 (clobber (reg:CC FLAGS_REG))])]
19263 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19264 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19265 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19266 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19270 [(match_scratch:DI 0 "r")
19271 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19272 (clobber (reg:CC FLAGS_REG))])]
19274 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19275 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19276 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19277 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19280 ;; Convert imul by three, five and nine into lea
19283 [(set (match_operand:SI 0 "register_operand" "")
19284 (mult:SI (match_operand:SI 1 "register_operand" "")
19285 (match_operand:SI 2 "const_int_operand" "")))
19286 (clobber (reg:CC FLAGS_REG))])]
19287 "INTVAL (operands[2]) == 3
19288 || INTVAL (operands[2]) == 5
19289 || INTVAL (operands[2]) == 9"
19290 [(set (match_dup 0)
19291 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19293 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19297 [(set (match_operand:SI 0 "register_operand" "")
19298 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19299 (match_operand:SI 2 "const_int_operand" "")))
19300 (clobber (reg:CC FLAGS_REG))])]
19302 && (INTVAL (operands[2]) == 3
19303 || INTVAL (operands[2]) == 5
19304 || INTVAL (operands[2]) == 9)"
19305 [(set (match_dup 0) (match_dup 1))
19307 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19309 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19313 [(set (match_operand:DI 0 "register_operand" "")
19314 (mult:DI (match_operand:DI 1 "register_operand" "")
19315 (match_operand:DI 2 "const_int_operand" "")))
19316 (clobber (reg:CC FLAGS_REG))])]
19318 && (INTVAL (operands[2]) == 3
19319 || INTVAL (operands[2]) == 5
19320 || INTVAL (operands[2]) == 9)"
19321 [(set (match_dup 0)
19322 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19324 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19328 [(set (match_operand:DI 0 "register_operand" "")
19329 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19330 (match_operand:DI 2 "const_int_operand" "")))
19331 (clobber (reg:CC FLAGS_REG))])]
19334 && (INTVAL (operands[2]) == 3
19335 || INTVAL (operands[2]) == 5
19336 || INTVAL (operands[2]) == 9)"
19337 [(set (match_dup 0) (match_dup 1))
19339 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19341 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19343 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19344 ;; imul $32bit_imm, reg, reg is direct decoded.
19346 [(match_scratch:DI 3 "r")
19347 (parallel [(set (match_operand:DI 0 "register_operand" "")
19348 (mult:DI (match_operand:DI 1 "memory_operand" "")
19349 (match_operand:DI 2 "immediate_operand" "")))
19350 (clobber (reg:CC FLAGS_REG))])]
19351 "TARGET_K8 && !optimize_size
19352 && (GET_CODE (operands[2]) != CONST_INT
19353 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19354 [(set (match_dup 3) (match_dup 1))
19355 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19356 (clobber (reg:CC FLAGS_REG))])]
19360 [(match_scratch:SI 3 "r")
19361 (parallel [(set (match_operand:SI 0 "register_operand" "")
19362 (mult:SI (match_operand:SI 1 "memory_operand" "")
19363 (match_operand:SI 2 "immediate_operand" "")))
19364 (clobber (reg:CC FLAGS_REG))])]
19365 "TARGET_K8 && !optimize_size
19366 && (GET_CODE (operands[2]) != CONST_INT
19367 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19368 [(set (match_dup 3) (match_dup 1))
19369 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19370 (clobber (reg:CC FLAGS_REG))])]
19374 [(match_scratch:SI 3 "r")
19375 (parallel [(set (match_operand:DI 0 "register_operand" "")
19377 (mult:SI (match_operand:SI 1 "memory_operand" "")
19378 (match_operand:SI 2 "immediate_operand" ""))))
19379 (clobber (reg:CC FLAGS_REG))])]
19380 "TARGET_K8 && !optimize_size
19381 && (GET_CODE (operands[2]) != CONST_INT
19382 || !CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K'))"
19383 [(set (match_dup 3) (match_dup 1))
19384 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19385 (clobber (reg:CC FLAGS_REG))])]
19388 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19389 ;; Convert it into imul reg, reg
19390 ;; It would be better to force assembler to encode instruction using long
19391 ;; immediate, but there is apparently no way to do so.
19393 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19394 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19395 (match_operand:DI 2 "const_int_operand" "")))
19396 (clobber (reg:CC FLAGS_REG))])
19397 (match_scratch:DI 3 "r")]
19398 "TARGET_K8 && !optimize_size
19399 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19400 [(set (match_dup 3) (match_dup 2))
19401 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19402 (clobber (reg:CC FLAGS_REG))])]
19404 if (!rtx_equal_p (operands[0], operands[1]))
19405 emit_move_insn (operands[0], operands[1]);
19409 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19410 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19411 (match_operand:SI 2 "const_int_operand" "")))
19412 (clobber (reg:CC FLAGS_REG))])
19413 (match_scratch:SI 3 "r")]
19414 "TARGET_K8 && !optimize_size
19415 && CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
19416 [(set (match_dup 3) (match_dup 2))
19417 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19418 (clobber (reg:CC FLAGS_REG))])]
19420 if (!rtx_equal_p (operands[0], operands[1]))
19421 emit_move_insn (operands[0], operands[1]);
19425 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19426 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19427 (match_operand:HI 2 "immediate_operand" "")))
19428 (clobber (reg:CC FLAGS_REG))])
19429 (match_scratch:HI 3 "r")]
19430 "TARGET_K8 && !optimize_size"
19431 [(set (match_dup 3) (match_dup 2))
19432 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19433 (clobber (reg:CC FLAGS_REG))])]
19435 if (!rtx_equal_p (operands[0], operands[1]))
19436 emit_move_insn (operands[0], operands[1]);
19439 ;; Call-value patterns last so that the wildcard operand does not
19440 ;; disrupt insn-recog's switch tables.
19442 (define_insn "*call_value_pop_0"
19443 [(set (match_operand 0 "" "")
19444 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19445 (match_operand:SI 2 "" "")))
19446 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19447 (match_operand:SI 3 "immediate_operand" "")))]
19450 if (SIBLING_CALL_P (insn))
19453 return "call\t%P1";
19455 [(set_attr "type" "callv")])
19457 (define_insn "*call_value_pop_1"
19458 [(set (match_operand 0 "" "")
19459 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19460 (match_operand:SI 2 "" "")))
19461 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
19462 (match_operand:SI 3 "immediate_operand" "i")))]
19465 if (constant_call_address_operand (operands[1], Pmode))
19467 if (SIBLING_CALL_P (insn))
19470 return "call\t%P1";
19472 if (SIBLING_CALL_P (insn))
19475 return "call\t%A1";
19477 [(set_attr "type" "callv")])
19479 (define_insn "*call_value_0"
19480 [(set (match_operand 0 "" "")
19481 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19482 (match_operand:SI 2 "" "")))]
19485 if (SIBLING_CALL_P (insn))
19488 return "call\t%P1";
19490 [(set_attr "type" "callv")])
19492 (define_insn "*call_value_0_rex64"
19493 [(set (match_operand 0 "" "")
19494 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19495 (match_operand:DI 2 "const_int_operand" "")))]
19498 if (SIBLING_CALL_P (insn))
19501 return "call\t%P1";
19503 [(set_attr "type" "callv")])
19505 (define_insn "*call_value_1"
19506 [(set (match_operand 0 "" "")
19507 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
19508 (match_operand:SI 2 "" "")))]
19509 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
19511 if (constant_call_address_operand (operands[1], Pmode))
19512 return "call\t%P1";
19513 return "call\t%A1";
19515 [(set_attr "type" "callv")])
19517 (define_insn "*sibcall_value_1"
19518 [(set (match_operand 0 "" "")
19519 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
19520 (match_operand:SI 2 "" "")))]
19521 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
19523 if (constant_call_address_operand (operands[1], Pmode))
19527 [(set_attr "type" "callv")])
19529 (define_insn "*call_value_1_rex64"
19530 [(set (match_operand 0 "" "")
19531 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
19532 (match_operand:DI 2 "" "")))]
19533 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
19535 if (constant_call_address_operand (operands[1], Pmode))
19536 return "call\t%P1";
19537 return "call\t%A1";
19539 [(set_attr "type" "callv")])
19541 (define_insn "*sibcall_value_1_rex64"
19542 [(set (match_operand 0 "" "")
19543 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19544 (match_operand:DI 2 "" "")))]
19545 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19547 [(set_attr "type" "callv")])
19549 (define_insn "*sibcall_value_1_rex64_v"
19550 [(set (match_operand 0 "" "")
19551 (call (mem:QI (reg:DI 40))
19552 (match_operand:DI 1 "" "")))]
19553 "SIBLING_CALL_P (insn) && TARGET_64BIT"
19555 [(set_attr "type" "callv")])
19557 (define_insn "trap"
19558 [(trap_if (const_int 1) (const_int 5))]
19562 ;;; ix86 doesn't have conditional trap instructions, but we fake them
19563 ;;; for the sake of bounds checking. By emitting bounds checks as
19564 ;;; conditional traps rather than as conditional jumps around
19565 ;;; unconditional traps we avoid introducing spurious basic-block
19566 ;;; boundaries and facilitate elimination of redundant checks. In
19567 ;;; honor of the too-inflexible-for-BPs `bound' instruction, we use
19570 ;;; FIXME: Static branch prediction rules for ix86 are such that
19571 ;;; forward conditional branches predict as untaken. As implemented
19572 ;;; below, pseudo conditional traps violate that rule. We should use
19573 ;;; .pushsection/.popsection to place all of the `int 5's in a special
19574 ;;; section loaded at the end of the text segment and branch forward
19575 ;;; there on bounds-failure, and then jump back immediately (in case
19576 ;;; the system chooses to ignore bounds violations, or to report
19577 ;;; violations and continue execution).
19579 (define_expand "conditional_trap"
19580 [(trap_if (match_operator 0 "comparison_operator"
19581 [(match_dup 2) (const_int 0)])
19582 (match_operand 1 "const_int_operand" ""))]
19585 emit_insn (gen_rtx_TRAP_IF (VOIDmode,
19586 ix86_expand_compare (GET_CODE (operands[0]),
19592 (define_insn "*conditional_trap_1"
19593 [(trap_if (match_operator 0 "comparison_operator"
19594 [(reg FLAGS_REG) (const_int 0)])
19595 (match_operand 1 "const_int_operand" ""))]
19598 operands[2] = gen_label_rtx ();
19599 output_asm_insn ("j%c0\t%l2\; int\t%1", operands);
19600 (*targetm.asm_out.internal_label) (asm_out_file, "L",
19601 CODE_LABEL_NUMBER (operands[2]));
19605 (define_expand "sse_prologue_save"
19606 [(parallel [(set (match_operand:BLK 0 "" "")
19607 (unspec:BLK [(reg:DI 21)
19614 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19615 (use (match_operand:DI 1 "register_operand" ""))
19616 (use (match_operand:DI 2 "immediate_operand" ""))
19617 (use (label_ref:DI (match_operand 3 "" "")))])]
19621 (define_insn "*sse_prologue_save_insn"
19622 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
19623 (match_operand:DI 4 "const_int_operand" "n")))
19624 (unspec:BLK [(reg:DI 21)
19631 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
19632 (use (match_operand:DI 1 "register_operand" "r"))
19633 (use (match_operand:DI 2 "const_int_operand" "i"))
19634 (use (label_ref:DI (match_operand 3 "" "X")))]
19636 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
19637 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
19641 operands[0] = gen_rtx_MEM (Pmode,
19642 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
19643 output_asm_insn (\"jmp\\t%A1\", operands);
19644 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
19646 operands[4] = adjust_address (operands[0], DImode, i*16);
19647 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
19648 PUT_MODE (operands[4], TImode);
19649 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
19650 output_asm_insn (\"rex\", operands);
19651 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
19653 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
19654 CODE_LABEL_NUMBER (operands[3]));
19658 [(set_attr "type" "other")
19659 (set_attr "length_immediate" "0")
19660 (set_attr "length_address" "0")
19661 (set_attr "length" "135")
19662 (set_attr "memory" "store")
19663 (set_attr "modrm" "0")
19664 (set_attr "mode" "DI")])
19666 (define_expand "prefetch"
19667 [(prefetch (match_operand 0 "address_operand" "")
19668 (match_operand:SI 1 "const_int_operand" "")
19669 (match_operand:SI 2 "const_int_operand" ""))]
19670 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
19672 int rw = INTVAL (operands[1]);
19673 int locality = INTVAL (operands[2]);
19675 if (rw != 0 && rw != 1)
19677 if (locality < 0 || locality > 3)
19679 if (GET_MODE (operands[0]) != Pmode && GET_MODE (operands[0]) != VOIDmode)
19682 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19683 supported by SSE counterpart or the SSE prefetch is not available
19684 (K6 machines). Otherwise use SSE prefetch as it allows specifying
19686 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
19687 operands[2] = GEN_INT (3);
19689 operands[1] = const0_rtx;
19692 (define_insn "*prefetch_sse"
19693 [(prefetch (match_operand:SI 0 "address_operand" "p")
19695 (match_operand:SI 1 "const_int_operand" ""))]
19696 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
19698 static const char * const patterns[4] = {
19699 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19702 int locality = INTVAL (operands[1]);
19703 if (locality < 0 || locality > 3)
19706 return patterns[locality];
19708 [(set_attr "type" "sse")
19709 (set_attr "memory" "none")])
19711 (define_insn "*prefetch_sse_rex"
19712 [(prefetch (match_operand:DI 0 "address_operand" "p")
19714 (match_operand:SI 1 "const_int_operand" ""))]
19715 "TARGET_PREFETCH_SSE && TARGET_64BIT"
19717 static const char * const patterns[4] = {
19718 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19721 int locality = INTVAL (operands[1]);
19722 if (locality < 0 || locality > 3)
19725 return patterns[locality];
19727 [(set_attr "type" "sse")
19728 (set_attr "memory" "none")])
19730 (define_insn "*prefetch_3dnow"
19731 [(prefetch (match_operand:SI 0 "address_operand" "p")
19732 (match_operand:SI 1 "const_int_operand" "n")
19734 "TARGET_3DNOW && !TARGET_64BIT"
19736 if (INTVAL (operands[1]) == 0)
19737 return "prefetch\t%a0";
19739 return "prefetchw\t%a0";
19741 [(set_attr "type" "mmx")
19742 (set_attr "memory" "none")])
19744 (define_insn "*prefetch_3dnow_rex"
19745 [(prefetch (match_operand:DI 0 "address_operand" "p")
19746 (match_operand:SI 1 "const_int_operand" "n")
19748 "TARGET_3DNOW && TARGET_64BIT"
19750 if (INTVAL (operands[1]) == 0)
19751 return "prefetch\t%a0";
19753 return "prefetchw\t%a0";
19755 [(set_attr "type" "mmx")
19756 (set_attr "memory" "none")])