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, 2006, 2007
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, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, 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)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 29)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 30)
99 (UNSPEC_NOP 38) ; prevents combiner cleverness
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
128 (UNSPEC_FRNDINT_FLOOR 70)
129 (UNSPEC_FRNDINT_CEIL 71)
130 (UNSPEC_FRNDINT_TRUNC 72)
131 (UNSPEC_FRNDINT_MASK_PM 73)
132 (UNSPEC_FIST_FLOOR 74)
133 (UNSPEC_FIST_CEIL 75)
135 ; x87 Double output FP
136 (UNSPEC_SINCOS_COS 80)
137 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
161 (UNSPEC_INSERTQI 132)
166 [(UNSPECV_BLOCKAGE 0)
167 (UNSPECV_STACK_PROBE 1)
176 (UNSPECV_CMPXCHG_1 10)
177 (UNSPECV_CMPXCHG_2 11)
182 ;; Registers by name.
193 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
196 ;; In C guard expressions, put expressions which may be compile-time
197 ;; constants first. This allows for better optimization. For
198 ;; example, write "TARGET_64BIT && reload_completed", not
199 ;; "reload_completed && TARGET_64BIT".
202 ;; Processor type. This attribute must exactly match the processor_type
203 ;; enumeration in i386.h.
204 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
205 nocona,core2,generic32,generic64,amdfam10"
206 (const (symbol_ref "ix86_tune")))
208 ;; A basic instruction type. Refinements due to arguments to be
209 ;; provided in other attributes.
212 alu,alu1,negnot,imov,imovx,lea,
213 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
214 icmp,test,ibr,setcc,icmov,
215 push,pop,call,callv,leave,
217 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
218 sselog,sselog1,sseiadd,sseishft,sseimul,
219 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
220 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
221 (const_string "other"))
223 ;; Main data type used by the insn
225 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
226 (const_string "unknown"))
228 ;; The CPU unit operations uses.
229 (define_attr "unit" "integer,i387,sse,mmx,unknown"
230 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
231 (const_string "i387")
232 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
233 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
235 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
237 (eq_attr "type" "other")
238 (const_string "unknown")]
239 (const_string "integer")))
241 ;; The (bounding maximum) length of an instruction immediate.
242 (define_attr "length_immediate" ""
243 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
246 (eq_attr "unit" "i387,sse,mmx")
248 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
250 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
251 (eq_attr "type" "imov,test")
252 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
253 (eq_attr "type" "call")
254 (if_then_else (match_operand 0 "constant_call_address_operand" "")
257 (eq_attr "type" "callv")
258 (if_then_else (match_operand 1 "constant_call_address_operand" "")
261 ;; We don't know the size before shorten_branches. Expect
262 ;; the instruction to fit for better scheduling.
263 (eq_attr "type" "ibr")
266 (symbol_ref "/* Update immediate_length and other attributes! */
267 gcc_unreachable (),1")))
269 ;; The (bounding maximum) length of an instruction address.
270 (define_attr "length_address" ""
271 (cond [(eq_attr "type" "str,other,multi,fxch")
273 (and (eq_attr "type" "call")
274 (match_operand 0 "constant_call_address_operand" ""))
276 (and (eq_attr "type" "callv")
277 (match_operand 1 "constant_call_address_operand" ""))
280 (symbol_ref "ix86_attr_length_address_default (insn)")))
282 ;; Set when length prefix is used.
283 (define_attr "prefix_data16" ""
284 (if_then_else (ior (eq_attr "mode" "HI")
285 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
289 ;; Set when string REP prefix is used.
290 (define_attr "prefix_rep" ""
291 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
295 ;; Set when 0f opcode prefix is used.
296 (define_attr "prefix_0f" ""
298 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
299 (eq_attr "unit" "sse,mmx"))
303 ;; Set when REX opcode prefix is used.
304 (define_attr "prefix_rex" ""
305 (cond [(and (eq_attr "mode" "DI")
306 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
308 (and (eq_attr "mode" "QI")
309 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
312 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
318 ;; Set when modrm byte is used.
319 (define_attr "modrm" ""
320 (cond [(eq_attr "type" "str,leave")
322 (eq_attr "unit" "i387")
324 (and (eq_attr "type" "incdec")
325 (ior (match_operand:SI 1 "register_operand" "")
326 (match_operand:HI 1 "register_operand" "")))
328 (and (eq_attr "type" "push")
329 (not (match_operand 1 "memory_operand" "")))
331 (and (eq_attr "type" "pop")
332 (not (match_operand 0 "memory_operand" "")))
334 (and (eq_attr "type" "imov")
335 (ior (and (match_operand 0 "register_operand" "")
336 (match_operand 1 "immediate_operand" ""))
337 (ior (and (match_operand 0 "ax_reg_operand" "")
338 (match_operand 1 "memory_displacement_only_operand" ""))
339 (and (match_operand 0 "memory_displacement_only_operand" "")
340 (match_operand 1 "ax_reg_operand" "")))))
342 (and (eq_attr "type" "call")
343 (match_operand 0 "constant_call_address_operand" ""))
345 (and (eq_attr "type" "callv")
346 (match_operand 1 "constant_call_address_operand" ""))
351 ;; The (bounding maximum) length of an instruction in bytes.
352 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
353 ;; Later we may want to split them and compute proper length as for
355 (define_attr "length" ""
356 (cond [(eq_attr "type" "other,multi,fistp,frndint")
358 (eq_attr "type" "fcmp")
360 (eq_attr "unit" "i387")
362 (plus (attr "prefix_data16")
363 (attr "length_address")))]
364 (plus (plus (attr "modrm")
365 (plus (attr "prefix_0f")
366 (plus (attr "prefix_rex")
368 (plus (attr "prefix_rep")
369 (plus (attr "prefix_data16")
370 (plus (attr "length_immediate")
371 (attr "length_address")))))))
373 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
374 ;; `store' if there is a simple memory reference therein, or `unknown'
375 ;; if the instruction is complex.
377 (define_attr "memory" "none,load,store,both,unknown"
378 (cond [(eq_attr "type" "other,multi,str")
379 (const_string "unknown")
380 (eq_attr "type" "lea,fcmov,fpspc")
381 (const_string "none")
382 (eq_attr "type" "fistp,leave")
383 (const_string "both")
384 (eq_attr "type" "frndint")
385 (const_string "load")
386 (eq_attr "type" "push")
387 (if_then_else (match_operand 1 "memory_operand" "")
388 (const_string "both")
389 (const_string "store"))
390 (eq_attr "type" "pop")
391 (if_then_else (match_operand 0 "memory_operand" "")
392 (const_string "both")
393 (const_string "load"))
394 (eq_attr "type" "setcc")
395 (if_then_else (match_operand 0 "memory_operand" "")
396 (const_string "store")
397 (const_string "none"))
398 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
399 (if_then_else (ior (match_operand 0 "memory_operand" "")
400 (match_operand 1 "memory_operand" ""))
401 (const_string "load")
402 (const_string "none"))
403 (eq_attr "type" "ibr")
404 (if_then_else (match_operand 0 "memory_operand" "")
405 (const_string "load")
406 (const_string "none"))
407 (eq_attr "type" "call")
408 (if_then_else (match_operand 0 "constant_call_address_operand" "")
409 (const_string "none")
410 (const_string "load"))
411 (eq_attr "type" "callv")
412 (if_then_else (match_operand 1 "constant_call_address_operand" "")
413 (const_string "none")
414 (const_string "load"))
415 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
416 (match_operand 1 "memory_operand" ""))
417 (const_string "both")
418 (and (match_operand 0 "memory_operand" "")
419 (match_operand 1 "memory_operand" ""))
420 (const_string "both")
421 (match_operand 0 "memory_operand" "")
422 (const_string "store")
423 (match_operand 1 "memory_operand" "")
424 (const_string "load")
426 "!alu1,negnot,ishift1,
427 imov,imovx,icmp,test,bitmanip,
429 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
430 mmx,mmxmov,mmxcmp,mmxcvt")
431 (match_operand 2 "memory_operand" ""))
432 (const_string "load")
433 (and (eq_attr "type" "icmov")
434 (match_operand 3 "memory_operand" ""))
435 (const_string "load")
437 (const_string "none")))
439 ;; Indicates if an instruction has both an immediate and a displacement.
441 (define_attr "imm_disp" "false,true,unknown"
442 (cond [(eq_attr "type" "other,multi")
443 (const_string "unknown")
444 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
445 (and (match_operand 0 "memory_displacement_operand" "")
446 (match_operand 1 "immediate_operand" "")))
447 (const_string "true")
448 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
449 (and (match_operand 0 "memory_displacement_operand" "")
450 (match_operand 2 "immediate_operand" "")))
451 (const_string "true")
453 (const_string "false")))
455 ;; Indicates if an FP operation has an integer source.
457 (define_attr "fp_int_src" "false,true"
458 (const_string "false"))
460 ;; Defines rounding mode of an FP operation.
462 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
463 (const_string "any"))
465 ;; Describe a user's asm statement.
466 (define_asm_attributes
467 [(set_attr "length" "128")
468 (set_attr "type" "multi")])
470 ;; All x87 floating point modes
471 (define_mode_macro X87MODEF [SF DF XF])
473 ;; x87 SFmode and DFMode floating point modes
474 (define_mode_macro X87MODEF12 [SF DF])
476 ;; All integer modes handled by x87 fisttp operator.
477 (define_mode_macro X87MODEI [HI SI DI])
479 ;; All integer modes handled by integer x87 operators.
480 (define_mode_macro X87MODEI12 [HI SI])
482 ;; All SSE floating point modes
483 (define_mode_macro SSEMODEF [SF DF])
485 ;; All integer modes handled by SSE cvtts?2si* operators.
486 (define_mode_macro SSEMODEI24 [SI DI])
488 ;; SSE asm suffix for floating point modes
489 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
492 ;; Scheduling descriptions
494 (include "pentium.md")
497 (include "athlon.md")
501 ;; Operand and operator predicates and constraints
503 (include "predicates.md")
504 (include "constraints.md")
507 ;; Compare instructions.
509 ;; All compare insns have expanders that save the operands away without
510 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
511 ;; after the cmp) will actually emit the cmpM.
513 (define_expand "cmpti"
514 [(set (reg:CC FLAGS_REG)
515 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
516 (match_operand:TI 1 "x86_64_general_operand" "")))]
519 if (MEM_P (operands[0]) && MEM_P (operands[1]))
520 operands[0] = force_reg (TImode, operands[0]);
521 ix86_compare_op0 = operands[0];
522 ix86_compare_op1 = operands[1];
526 (define_expand "cmpdi"
527 [(set (reg:CC FLAGS_REG)
528 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
529 (match_operand:DI 1 "x86_64_general_operand" "")))]
532 if (MEM_P (operands[0]) && MEM_P (operands[1]))
533 operands[0] = force_reg (DImode, operands[0]);
534 ix86_compare_op0 = operands[0];
535 ix86_compare_op1 = operands[1];
539 (define_expand "cmpsi"
540 [(set (reg:CC FLAGS_REG)
541 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
542 (match_operand:SI 1 "general_operand" "")))]
545 if (MEM_P (operands[0]) && MEM_P (operands[1]))
546 operands[0] = force_reg (SImode, operands[0]);
547 ix86_compare_op0 = operands[0];
548 ix86_compare_op1 = operands[1];
552 (define_expand "cmphi"
553 [(set (reg:CC FLAGS_REG)
554 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
555 (match_operand:HI 1 "general_operand" "")))]
558 if (MEM_P (operands[0]) && MEM_P (operands[1]))
559 operands[0] = force_reg (HImode, operands[0]);
560 ix86_compare_op0 = operands[0];
561 ix86_compare_op1 = operands[1];
565 (define_expand "cmpqi"
566 [(set (reg:CC FLAGS_REG)
567 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
568 (match_operand:QI 1 "general_operand" "")))]
571 if (MEM_P (operands[0]) && MEM_P (operands[1]))
572 operands[0] = force_reg (QImode, operands[0]);
573 ix86_compare_op0 = operands[0];
574 ix86_compare_op1 = operands[1];
578 (define_insn "cmpdi_ccno_1_rex64"
579 [(set (reg FLAGS_REG)
580 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
581 (match_operand:DI 1 "const0_operand" "n,n")))]
582 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
584 test{q}\t{%0, %0|%0, %0}
585 cmp{q}\t{%1, %0|%0, %1}"
586 [(set_attr "type" "test,icmp")
587 (set_attr "length_immediate" "0,1")
588 (set_attr "mode" "DI")])
590 (define_insn "*cmpdi_minus_1_rex64"
591 [(set (reg FLAGS_REG)
592 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
593 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
595 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
596 "cmp{q}\t{%1, %0|%0, %1}"
597 [(set_attr "type" "icmp")
598 (set_attr "mode" "DI")])
600 (define_expand "cmpdi_1_rex64"
601 [(set (reg:CC FLAGS_REG)
602 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
603 (match_operand:DI 1 "general_operand" "")))]
607 (define_insn "cmpdi_1_insn_rex64"
608 [(set (reg FLAGS_REG)
609 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
610 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
611 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
612 "cmp{q}\t{%1, %0|%0, %1}"
613 [(set_attr "type" "icmp")
614 (set_attr "mode" "DI")])
617 (define_insn "*cmpsi_ccno_1"
618 [(set (reg FLAGS_REG)
619 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
620 (match_operand:SI 1 "const0_operand" "n,n")))]
621 "ix86_match_ccmode (insn, CCNOmode)"
623 test{l}\t{%0, %0|%0, %0}
624 cmp{l}\t{%1, %0|%0, %1}"
625 [(set_attr "type" "test,icmp")
626 (set_attr "length_immediate" "0,1")
627 (set_attr "mode" "SI")])
629 (define_insn "*cmpsi_minus_1"
630 [(set (reg FLAGS_REG)
631 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
632 (match_operand:SI 1 "general_operand" "ri,mr"))
634 "ix86_match_ccmode (insn, CCGOCmode)"
635 "cmp{l}\t{%1, %0|%0, %1}"
636 [(set_attr "type" "icmp")
637 (set_attr "mode" "SI")])
639 (define_expand "cmpsi_1"
640 [(set (reg:CC FLAGS_REG)
641 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
642 (match_operand:SI 1 "general_operand" "ri,mr")))]
646 (define_insn "*cmpsi_1_insn"
647 [(set (reg FLAGS_REG)
648 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
649 (match_operand:SI 1 "general_operand" "ri,mr")))]
650 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
651 && ix86_match_ccmode (insn, CCmode)"
652 "cmp{l}\t{%1, %0|%0, %1}"
653 [(set_attr "type" "icmp")
654 (set_attr "mode" "SI")])
656 (define_insn "*cmphi_ccno_1"
657 [(set (reg FLAGS_REG)
658 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
659 (match_operand:HI 1 "const0_operand" "n,n")))]
660 "ix86_match_ccmode (insn, CCNOmode)"
662 test{w}\t{%0, %0|%0, %0}
663 cmp{w}\t{%1, %0|%0, %1}"
664 [(set_attr "type" "test,icmp")
665 (set_attr "length_immediate" "0,1")
666 (set_attr "mode" "HI")])
668 (define_insn "*cmphi_minus_1"
669 [(set (reg FLAGS_REG)
670 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
671 (match_operand:HI 1 "general_operand" "ri,mr"))
673 "ix86_match_ccmode (insn, CCGOCmode)"
674 "cmp{w}\t{%1, %0|%0, %1}"
675 [(set_attr "type" "icmp")
676 (set_attr "mode" "HI")])
678 (define_insn "*cmphi_1"
679 [(set (reg FLAGS_REG)
680 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
681 (match_operand:HI 1 "general_operand" "ri,mr")))]
682 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
683 && ix86_match_ccmode (insn, CCmode)"
684 "cmp{w}\t{%1, %0|%0, %1}"
685 [(set_attr "type" "icmp")
686 (set_attr "mode" "HI")])
688 (define_insn "*cmpqi_ccno_1"
689 [(set (reg FLAGS_REG)
690 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
691 (match_operand:QI 1 "const0_operand" "n,n")))]
692 "ix86_match_ccmode (insn, CCNOmode)"
694 test{b}\t{%0, %0|%0, %0}
695 cmp{b}\t{$0, %0|%0, 0}"
696 [(set_attr "type" "test,icmp")
697 (set_attr "length_immediate" "0,1")
698 (set_attr "mode" "QI")])
700 (define_insn "*cmpqi_1"
701 [(set (reg FLAGS_REG)
702 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
703 (match_operand:QI 1 "general_operand" "qi,mq")))]
704 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
705 && ix86_match_ccmode (insn, CCmode)"
706 "cmp{b}\t{%1, %0|%0, %1}"
707 [(set_attr "type" "icmp")
708 (set_attr "mode" "QI")])
710 (define_insn "*cmpqi_minus_1"
711 [(set (reg FLAGS_REG)
712 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
713 (match_operand:QI 1 "general_operand" "qi,mq"))
715 "ix86_match_ccmode (insn, CCGOCmode)"
716 "cmp{b}\t{%1, %0|%0, %1}"
717 [(set_attr "type" "icmp")
718 (set_attr "mode" "QI")])
720 (define_insn "*cmpqi_ext_1"
721 [(set (reg FLAGS_REG)
723 (match_operand:QI 0 "general_operand" "Qm")
726 (match_operand 1 "ext_register_operand" "Q")
729 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
730 "cmp{b}\t{%h1, %0|%0, %h1}"
731 [(set_attr "type" "icmp")
732 (set_attr "mode" "QI")])
734 (define_insn "*cmpqi_ext_1_rex64"
735 [(set (reg FLAGS_REG)
737 (match_operand:QI 0 "register_operand" "Q")
740 (match_operand 1 "ext_register_operand" "Q")
743 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
744 "cmp{b}\t{%h1, %0|%0, %h1}"
745 [(set_attr "type" "icmp")
746 (set_attr "mode" "QI")])
748 (define_insn "*cmpqi_ext_2"
749 [(set (reg FLAGS_REG)
753 (match_operand 0 "ext_register_operand" "Q")
756 (match_operand:QI 1 "const0_operand" "n")))]
757 "ix86_match_ccmode (insn, CCNOmode)"
759 [(set_attr "type" "test")
760 (set_attr "length_immediate" "0")
761 (set_attr "mode" "QI")])
763 (define_expand "cmpqi_ext_3"
764 [(set (reg:CC FLAGS_REG)
768 (match_operand 0 "ext_register_operand" "")
771 (match_operand:QI 1 "general_operand" "")))]
775 (define_insn "cmpqi_ext_3_insn"
776 [(set (reg FLAGS_REG)
780 (match_operand 0 "ext_register_operand" "Q")
783 (match_operand:QI 1 "general_operand" "Qmn")))]
784 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
785 "cmp{b}\t{%1, %h0|%h0, %1}"
786 [(set_attr "type" "icmp")
787 (set_attr "mode" "QI")])
789 (define_insn "cmpqi_ext_3_insn_rex64"
790 [(set (reg FLAGS_REG)
794 (match_operand 0 "ext_register_operand" "Q")
797 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
798 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
799 "cmp{b}\t{%1, %h0|%h0, %1}"
800 [(set_attr "type" "icmp")
801 (set_attr "mode" "QI")])
803 (define_insn "*cmpqi_ext_4"
804 [(set (reg FLAGS_REG)
808 (match_operand 0 "ext_register_operand" "Q")
813 (match_operand 1 "ext_register_operand" "Q")
816 "ix86_match_ccmode (insn, CCmode)"
817 "cmp{b}\t{%h1, %h0|%h0, %h1}"
818 [(set_attr "type" "icmp")
819 (set_attr "mode" "QI")])
821 ;; These implement float point compares.
822 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
823 ;; which would allow mix and match FP modes on the compares. Which is what
824 ;; the old patterns did, but with many more of them.
826 (define_expand "cmpxf"
827 [(set (reg:CC FLAGS_REG)
828 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
829 (match_operand:XF 1 "nonmemory_operand" "")))]
832 ix86_compare_op0 = operands[0];
833 ix86_compare_op1 = operands[1];
837 (define_expand "cmpdf"
838 [(set (reg:CC FLAGS_REG)
839 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
840 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
841 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
843 ix86_compare_op0 = operands[0];
844 ix86_compare_op1 = operands[1];
848 (define_expand "cmpsf"
849 [(set (reg:CC FLAGS_REG)
850 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
851 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
852 "TARGET_80387 || TARGET_SSE_MATH"
854 ix86_compare_op0 = operands[0];
855 ix86_compare_op1 = operands[1];
859 ;; FP compares, step 1:
860 ;; Set the FP condition codes.
862 ;; CCFPmode compare with exceptions
863 ;; CCFPUmode compare with no exceptions
865 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
866 ;; used to manage the reg stack popping would not be preserved.
868 (define_insn "*cmpfp_0"
869 [(set (match_operand:HI 0 "register_operand" "=a")
872 (match_operand 1 "register_operand" "f")
873 (match_operand 2 "const0_operand" "X"))]
876 && FLOAT_MODE_P (GET_MODE (operands[1]))
877 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
878 "* return output_fp_compare (insn, operands, 0, 0);"
879 [(set_attr "type" "multi")
880 (set_attr "unit" "i387")
882 (cond [(match_operand:SF 1 "" "")
884 (match_operand:DF 1 "" "")
887 (const_string "XF")))])
889 (define_insn "*cmpfp_sf"
890 [(set (match_operand:HI 0 "register_operand" "=a")
893 (match_operand:SF 1 "register_operand" "f")
894 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
897 "* return output_fp_compare (insn, operands, 0, 0);"
898 [(set_attr "type" "multi")
899 (set_attr "unit" "i387")
900 (set_attr "mode" "SF")])
902 (define_insn "*cmpfp_df"
903 [(set (match_operand:HI 0 "register_operand" "=a")
906 (match_operand:DF 1 "register_operand" "f")
907 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
910 "* return output_fp_compare (insn, operands, 0, 0);"
911 [(set_attr "type" "multi")
912 (set_attr "unit" "i387")
913 (set_attr "mode" "DF")])
915 (define_insn "*cmpfp_xf"
916 [(set (match_operand:HI 0 "register_operand" "=a")
919 (match_operand:XF 1 "register_operand" "f")
920 (match_operand:XF 2 "register_operand" "f"))]
923 "* return output_fp_compare (insn, operands, 0, 0);"
924 [(set_attr "type" "multi")
925 (set_attr "unit" "i387")
926 (set_attr "mode" "XF")])
928 (define_insn "*cmpfp_u"
929 [(set (match_operand:HI 0 "register_operand" "=a")
932 (match_operand 1 "register_operand" "f")
933 (match_operand 2 "register_operand" "f"))]
936 && FLOAT_MODE_P (GET_MODE (operands[1]))
937 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
938 "* return output_fp_compare (insn, operands, 0, 1);"
939 [(set_attr "type" "multi")
940 (set_attr "unit" "i387")
942 (cond [(match_operand:SF 1 "" "")
944 (match_operand:DF 1 "" "")
947 (const_string "XF")))])
949 (define_insn "*cmpfp_<mode>"
950 [(set (match_operand:HI 0 "register_operand" "=a")
953 (match_operand 1 "register_operand" "f")
954 (match_operator 3 "float_operator"
955 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
957 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
958 && FLOAT_MODE_P (GET_MODE (operands[1]))
959 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
960 "* return output_fp_compare (insn, operands, 0, 0);"
961 [(set_attr "type" "multi")
962 (set_attr "unit" "i387")
963 (set_attr "fp_int_src" "true")
964 (set_attr "mode" "<MODE>")])
966 ;; FP compares, step 2
967 ;; Move the fpsw to ax.
969 (define_insn "x86_fnstsw_1"
970 [(set (match_operand:HI 0 "register_operand" "=a")
971 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
974 [(set_attr "length" "2")
975 (set_attr "mode" "SI")
976 (set_attr "unit" "i387")])
978 ;; FP compares, step 3
979 ;; Get ax into flags, general case.
981 (define_insn "x86_sahf_1"
982 [(set (reg:CC FLAGS_REG)
983 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
986 [(set_attr "length" "1")
987 (set_attr "athlon_decode" "vector")
988 (set_attr "amdfam10_decode" "direct")
989 (set_attr "mode" "SI")])
991 ;; Pentium Pro can do steps 1 through 3 in one go.
992 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
993 (define_insn "*cmpfp_i_mixed"
994 [(set (reg:CCFP FLAGS_REG)
995 (compare:CCFP (match_operand 0 "register_operand" "f,x")
996 (match_operand 1 "nonimmediate_operand" "f,xm")))]
998 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
999 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1000 "* return output_fp_compare (insn, operands, 1, 0);"
1001 [(set_attr "type" "fcmp,ssecomi")
1003 (if_then_else (match_operand:SF 1 "" "")
1005 (const_string "DF")))
1006 (set_attr "athlon_decode" "vector")
1007 (set_attr "amdfam10_decode" "direct")])
1009 (define_insn "*cmpfp_i_sse"
1010 [(set (reg:CCFP FLAGS_REG)
1011 (compare:CCFP (match_operand 0 "register_operand" "x")
1012 (match_operand 1 "nonimmediate_operand" "xm")))]
1014 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1015 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1016 "* return output_fp_compare (insn, operands, 1, 0);"
1017 [(set_attr "type" "ssecomi")
1019 (if_then_else (match_operand:SF 1 "" "")
1021 (const_string "DF")))
1022 (set_attr "athlon_decode" "vector")
1023 (set_attr "amdfam10_decode" "direct")])
1025 (define_insn "*cmpfp_i_i387"
1026 [(set (reg:CCFP FLAGS_REG)
1027 (compare:CCFP (match_operand 0 "register_operand" "f")
1028 (match_operand 1 "register_operand" "f")))]
1029 "TARGET_80387 && TARGET_CMOVE
1030 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1031 && FLOAT_MODE_P (GET_MODE (operands[0]))
1032 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1033 "* return output_fp_compare (insn, operands, 1, 0);"
1034 [(set_attr "type" "fcmp")
1036 (cond [(match_operand:SF 1 "" "")
1038 (match_operand:DF 1 "" "")
1041 (const_string "XF")))
1042 (set_attr "athlon_decode" "vector")
1043 (set_attr "amdfam10_decode" "direct")])
1045 (define_insn "*cmpfp_iu_mixed"
1046 [(set (reg:CCFPU FLAGS_REG)
1047 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1048 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1049 "TARGET_MIX_SSE_I387
1050 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1051 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1052 "* return output_fp_compare (insn, operands, 1, 1);"
1053 [(set_attr "type" "fcmp,ssecomi")
1055 (if_then_else (match_operand:SF 1 "" "")
1057 (const_string "DF")))
1058 (set_attr "athlon_decode" "vector")
1059 (set_attr "amdfam10_decode" "direct")])
1061 (define_insn "*cmpfp_iu_sse"
1062 [(set (reg:CCFPU FLAGS_REG)
1063 (compare:CCFPU (match_operand 0 "register_operand" "x")
1064 (match_operand 1 "nonimmediate_operand" "xm")))]
1066 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1067 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1068 "* return output_fp_compare (insn, operands, 1, 1);"
1069 [(set_attr "type" "ssecomi")
1071 (if_then_else (match_operand:SF 1 "" "")
1073 (const_string "DF")))
1074 (set_attr "athlon_decode" "vector")
1075 (set_attr "amdfam10_decode" "direct")])
1077 (define_insn "*cmpfp_iu_387"
1078 [(set (reg:CCFPU FLAGS_REG)
1079 (compare:CCFPU (match_operand 0 "register_operand" "f")
1080 (match_operand 1 "register_operand" "f")))]
1081 "TARGET_80387 && TARGET_CMOVE
1082 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1083 && FLOAT_MODE_P (GET_MODE (operands[0]))
1084 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1085 "* return output_fp_compare (insn, operands, 1, 1);"
1086 [(set_attr "type" "fcmp")
1088 (cond [(match_operand:SF 1 "" "")
1090 (match_operand:DF 1 "" "")
1093 (const_string "XF")))
1094 (set_attr "athlon_decode" "vector")
1095 (set_attr "amdfam10_decode" "direct")])
1097 ;; Move instructions.
1099 ;; General case of fullword move.
1101 (define_expand "movsi"
1102 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1103 (match_operand:SI 1 "general_operand" ""))]
1105 "ix86_expand_move (SImode, operands); DONE;")
1107 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1110 ;; %%% We don't use a post-inc memory reference because x86 is not a
1111 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1112 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1113 ;; targets without our curiosities, and it is just as easy to represent
1114 ;; this differently.
1116 (define_insn "*pushsi2"
1117 [(set (match_operand:SI 0 "push_operand" "=<")
1118 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1121 [(set_attr "type" "push")
1122 (set_attr "mode" "SI")])
1124 ;; For 64BIT abi we always round up to 8 bytes.
1125 (define_insn "*pushsi2_rex64"
1126 [(set (match_operand:SI 0 "push_operand" "=X")
1127 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1130 [(set_attr "type" "push")
1131 (set_attr "mode" "SI")])
1133 (define_insn "*pushsi2_prologue"
1134 [(set (match_operand:SI 0 "push_operand" "=<")
1135 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1136 (clobber (mem:BLK (scratch)))]
1139 [(set_attr "type" "push")
1140 (set_attr "mode" "SI")])
1142 (define_insn "*popsi1_epilogue"
1143 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1144 (mem:SI (reg:SI SP_REG)))
1145 (set (reg:SI SP_REG)
1146 (plus:SI (reg:SI SP_REG) (const_int 4)))
1147 (clobber (mem:BLK (scratch)))]
1150 [(set_attr "type" "pop")
1151 (set_attr "mode" "SI")])
1153 (define_insn "popsi1"
1154 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1155 (mem:SI (reg:SI SP_REG)))
1156 (set (reg:SI SP_REG)
1157 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1160 [(set_attr "type" "pop")
1161 (set_attr "mode" "SI")])
1163 (define_insn "*movsi_xor"
1164 [(set (match_operand:SI 0 "register_operand" "=r")
1165 (match_operand:SI 1 "const0_operand" "i"))
1166 (clobber (reg:CC FLAGS_REG))]
1167 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1168 "xor{l}\t{%0, %0|%0, %0}"
1169 [(set_attr "type" "alu1")
1170 (set_attr "mode" "SI")
1171 (set_attr "length_immediate" "0")])
1173 (define_insn "*movsi_or"
1174 [(set (match_operand:SI 0 "register_operand" "=r")
1175 (match_operand:SI 1 "immediate_operand" "i"))
1176 (clobber (reg:CC FLAGS_REG))]
1178 && operands[1] == constm1_rtx
1179 && (TARGET_PENTIUM || optimize_size)"
1181 operands[1] = constm1_rtx;
1182 return "or{l}\t{%1, %0|%0, %1}";
1184 [(set_attr "type" "alu1")
1185 (set_attr "mode" "SI")
1186 (set_attr "length_immediate" "1")])
1188 (define_insn "*movsi_1"
1189 [(set (match_operand:SI 0 "nonimmediate_operand"
1190 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1191 (match_operand:SI 1 "general_operand"
1192 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1193 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1195 switch (get_attr_type (insn))
1198 if (get_attr_mode (insn) == MODE_TI)
1199 return "pxor\t%0, %0";
1200 return "xorps\t%0, %0";
1203 switch (get_attr_mode (insn))
1206 return "movdqa\t{%1, %0|%0, %1}";
1208 return "movaps\t{%1, %0|%0, %1}";
1210 return "movd\t{%1, %0|%0, %1}";
1212 return "movss\t{%1, %0|%0, %1}";
1218 return "pxor\t%0, %0";
1221 if (get_attr_mode (insn) == MODE_DI)
1222 return "movq\t{%1, %0|%0, %1}";
1223 return "movd\t{%1, %0|%0, %1}";
1226 return "lea{l}\t{%1, %0|%0, %1}";
1229 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1230 return "mov{l}\t{%1, %0|%0, %1}";
1234 (cond [(eq_attr "alternative" "2")
1235 (const_string "mmxadd")
1236 (eq_attr "alternative" "3,4,5")
1237 (const_string "mmxmov")
1238 (eq_attr "alternative" "6")
1239 (const_string "sselog1")
1240 (eq_attr "alternative" "7,8,9,10,11")
1241 (const_string "ssemov")
1242 (match_operand:DI 1 "pic_32bit_operand" "")
1243 (const_string "lea")
1245 (const_string "imov")))
1247 (cond [(eq_attr "alternative" "2,3")
1249 (eq_attr "alternative" "6,7")
1251 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1252 (const_string "V4SF")
1253 (const_string "TI"))
1254 (and (eq_attr "alternative" "8,9,10,11")
1255 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1258 (const_string "SI")))])
1260 ;; Stores and loads of ax to arbitrary constant address.
1261 ;; We fake an second form of instruction to force reload to load address
1262 ;; into register when rax is not available
1263 (define_insn "*movabssi_1_rex64"
1264 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1265 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1266 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1268 movabs{l}\t{%1, %P0|%P0, %1}
1269 mov{l}\t{%1, %a0|%a0, %1}"
1270 [(set_attr "type" "imov")
1271 (set_attr "modrm" "0,*")
1272 (set_attr "length_address" "8,0")
1273 (set_attr "length_immediate" "0,*")
1274 (set_attr "memory" "store")
1275 (set_attr "mode" "SI")])
1277 (define_insn "*movabssi_2_rex64"
1278 [(set (match_operand:SI 0 "register_operand" "=a,r")
1279 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1280 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1282 movabs{l}\t{%P1, %0|%0, %P1}
1283 mov{l}\t{%a1, %0|%0, %a1}"
1284 [(set_attr "type" "imov")
1285 (set_attr "modrm" "0,*")
1286 (set_attr "length_address" "8,0")
1287 (set_attr "length_immediate" "0")
1288 (set_attr "memory" "load")
1289 (set_attr "mode" "SI")])
1291 (define_insn "*swapsi"
1292 [(set (match_operand:SI 0 "register_operand" "+r")
1293 (match_operand:SI 1 "register_operand" "+r"))
1298 [(set_attr "type" "imov")
1299 (set_attr "mode" "SI")
1300 (set_attr "pent_pair" "np")
1301 (set_attr "athlon_decode" "vector")
1302 (set_attr "amdfam10_decode" "double")])
1304 (define_expand "movhi"
1305 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1306 (match_operand:HI 1 "general_operand" ""))]
1308 "ix86_expand_move (HImode, operands); DONE;")
1310 (define_insn "*pushhi2"
1311 [(set (match_operand:HI 0 "push_operand" "=X")
1312 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1315 [(set_attr "type" "push")
1316 (set_attr "mode" "SI")])
1318 ;; For 64BIT abi we always round up to 8 bytes.
1319 (define_insn "*pushhi2_rex64"
1320 [(set (match_operand:HI 0 "push_operand" "=X")
1321 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1324 [(set_attr "type" "push")
1325 (set_attr "mode" "DI")])
1327 (define_insn "*movhi_1"
1328 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1329 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1332 switch (get_attr_type (insn))
1335 /* movzwl is faster than movw on p2 due to partial word stalls,
1336 though not as fast as an aligned movl. */
1337 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1339 if (get_attr_mode (insn) == MODE_SI)
1340 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1342 return "mov{w}\t{%1, %0|%0, %1}";
1346 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1347 (const_string "imov")
1348 (and (eq_attr "alternative" "0")
1349 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1351 (eq (symbol_ref "TARGET_HIMODE_MATH")
1353 (const_string "imov")
1354 (and (eq_attr "alternative" "1,2")
1355 (match_operand:HI 1 "aligned_operand" ""))
1356 (const_string "imov")
1357 (and (ne (symbol_ref "TARGET_MOVX")
1359 (eq_attr "alternative" "0,2"))
1360 (const_string "imovx")
1362 (const_string "imov")))
1364 (cond [(eq_attr "type" "imovx")
1366 (and (eq_attr "alternative" "1,2")
1367 (match_operand:HI 1 "aligned_operand" ""))
1369 (and (eq_attr "alternative" "0")
1370 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1372 (eq (symbol_ref "TARGET_HIMODE_MATH")
1376 (const_string "HI")))])
1378 ;; Stores and loads of ax to arbitrary constant address.
1379 ;; We fake an second form of instruction to force reload to load address
1380 ;; into register when rax is not available
1381 (define_insn "*movabshi_1_rex64"
1382 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1383 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1384 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1386 movabs{w}\t{%1, %P0|%P0, %1}
1387 mov{w}\t{%1, %a0|%a0, %1}"
1388 [(set_attr "type" "imov")
1389 (set_attr "modrm" "0,*")
1390 (set_attr "length_address" "8,0")
1391 (set_attr "length_immediate" "0,*")
1392 (set_attr "memory" "store")
1393 (set_attr "mode" "HI")])
1395 (define_insn "*movabshi_2_rex64"
1396 [(set (match_operand:HI 0 "register_operand" "=a,r")
1397 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1398 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1400 movabs{w}\t{%P1, %0|%0, %P1}
1401 mov{w}\t{%a1, %0|%0, %a1}"
1402 [(set_attr "type" "imov")
1403 (set_attr "modrm" "0,*")
1404 (set_attr "length_address" "8,0")
1405 (set_attr "length_immediate" "0")
1406 (set_attr "memory" "load")
1407 (set_attr "mode" "HI")])
1409 (define_insn "*swaphi_1"
1410 [(set (match_operand:HI 0 "register_operand" "+r")
1411 (match_operand:HI 1 "register_operand" "+r"))
1414 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1416 [(set_attr "type" "imov")
1417 (set_attr "mode" "SI")
1418 (set_attr "pent_pair" "np")
1419 (set_attr "athlon_decode" "vector")
1420 (set_attr "amdfam10_decode" "double")])
1422 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1423 (define_insn "*swaphi_2"
1424 [(set (match_operand:HI 0 "register_operand" "+r")
1425 (match_operand:HI 1 "register_operand" "+r"))
1428 "TARGET_PARTIAL_REG_STALL"
1430 [(set_attr "type" "imov")
1431 (set_attr "mode" "HI")
1432 (set_attr "pent_pair" "np")
1433 (set_attr "athlon_decode" "vector")])
1435 (define_expand "movstricthi"
1436 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1437 (match_operand:HI 1 "general_operand" ""))]
1438 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1440 /* Don't generate memory->memory moves, go through a register */
1441 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1442 operands[1] = force_reg (HImode, operands[1]);
1445 (define_insn "*movstricthi_1"
1446 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1447 (match_operand:HI 1 "general_operand" "rn,m"))]
1448 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1449 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450 "mov{w}\t{%1, %0|%0, %1}"
1451 [(set_attr "type" "imov")
1452 (set_attr "mode" "HI")])
1454 (define_insn "*movstricthi_xor"
1455 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1456 (match_operand:HI 1 "const0_operand" "i"))
1457 (clobber (reg:CC FLAGS_REG))]
1459 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1460 "xor{w}\t{%0, %0|%0, %0}"
1461 [(set_attr "type" "alu1")
1462 (set_attr "mode" "HI")
1463 (set_attr "length_immediate" "0")])
1465 (define_expand "movqi"
1466 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1467 (match_operand:QI 1 "general_operand" ""))]
1469 "ix86_expand_move (QImode, operands); DONE;")
1471 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1472 ;; "push a byte". But actually we use pushl, which has the effect
1473 ;; of rounding the amount pushed up to a word.
1475 (define_insn "*pushqi2"
1476 [(set (match_operand:QI 0 "push_operand" "=X")
1477 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1480 [(set_attr "type" "push")
1481 (set_attr "mode" "SI")])
1483 ;; For 64BIT abi we always round up to 8 bytes.
1484 (define_insn "*pushqi2_rex64"
1485 [(set (match_operand:QI 0 "push_operand" "=X")
1486 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1489 [(set_attr "type" "push")
1490 (set_attr "mode" "DI")])
1492 ;; Situation is quite tricky about when to choose full sized (SImode) move
1493 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1494 ;; partial register dependency machines (such as AMD Athlon), where QImode
1495 ;; moves issue extra dependency and for partial register stalls machines
1496 ;; that don't use QImode patterns (and QImode move cause stall on the next
1499 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1500 ;; register stall machines with, where we use QImode instructions, since
1501 ;; partial register stall can be caused there. Then we use movzx.
1502 (define_insn "*movqi_1"
1503 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1504 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1505 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1507 switch (get_attr_type (insn))
1510 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1511 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1513 if (get_attr_mode (insn) == MODE_SI)
1514 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1516 return "mov{b}\t{%1, %0|%0, %1}";
1520 (cond [(and (eq_attr "alternative" "5")
1521 (not (match_operand:QI 1 "aligned_operand" "")))
1522 (const_string "imovx")
1523 (ne (symbol_ref "optimize_size") (const_int 0))
1524 (const_string "imov")
1525 (and (eq_attr "alternative" "3")
1526 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1528 (eq (symbol_ref "TARGET_QIMODE_MATH")
1530 (const_string "imov")
1531 (eq_attr "alternative" "3,5")
1532 (const_string "imovx")
1533 (and (ne (symbol_ref "TARGET_MOVX")
1535 (eq_attr "alternative" "2"))
1536 (const_string "imovx")
1538 (const_string "imov")))
1540 (cond [(eq_attr "alternative" "3,4,5")
1542 (eq_attr "alternative" "6")
1544 (eq_attr "type" "imovx")
1546 (and (eq_attr "type" "imov")
1547 (and (eq_attr "alternative" "0,1")
1548 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1550 (and (eq (symbol_ref "optimize_size")
1552 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1555 ;; Avoid partial register stalls when not using QImode arithmetic
1556 (and (eq_attr "type" "imov")
1557 (and (eq_attr "alternative" "0,1")
1558 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1560 (eq (symbol_ref "TARGET_QIMODE_MATH")
1564 (const_string "QI")))])
1566 (define_expand "reload_outqi"
1567 [(parallel [(match_operand:QI 0 "" "=m")
1568 (match_operand:QI 1 "register_operand" "r")
1569 (match_operand:QI 2 "register_operand" "=&q")])]
1573 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1575 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1576 if (! q_regs_operand (op1, QImode))
1578 emit_insn (gen_movqi (op2, op1));
1581 emit_insn (gen_movqi (op0, op1));
1585 (define_insn "*swapqi_1"
1586 [(set (match_operand:QI 0 "register_operand" "+r")
1587 (match_operand:QI 1 "register_operand" "+r"))
1590 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1592 [(set_attr "type" "imov")
1593 (set_attr "mode" "SI")
1594 (set_attr "pent_pair" "np")
1595 (set_attr "athlon_decode" "vector")
1596 (set_attr "amdfam10_decode" "vector")])
1598 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1599 (define_insn "*swapqi_2"
1600 [(set (match_operand:QI 0 "register_operand" "+q")
1601 (match_operand:QI 1 "register_operand" "+q"))
1604 "TARGET_PARTIAL_REG_STALL"
1606 [(set_attr "type" "imov")
1607 (set_attr "mode" "QI")
1608 (set_attr "pent_pair" "np")
1609 (set_attr "athlon_decode" "vector")])
1611 (define_expand "movstrictqi"
1612 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1613 (match_operand:QI 1 "general_operand" ""))]
1614 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1616 /* Don't generate memory->memory moves, go through a register. */
1617 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1618 operands[1] = force_reg (QImode, operands[1]);
1621 (define_insn "*movstrictqi_1"
1622 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1623 (match_operand:QI 1 "general_operand" "*qn,m"))]
1624 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1625 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626 "mov{b}\t{%1, %0|%0, %1}"
1627 [(set_attr "type" "imov")
1628 (set_attr "mode" "QI")])
1630 (define_insn "*movstrictqi_xor"
1631 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1632 (match_operand:QI 1 "const0_operand" "i"))
1633 (clobber (reg:CC FLAGS_REG))]
1634 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1635 "xor{b}\t{%0, %0|%0, %0}"
1636 [(set_attr "type" "alu1")
1637 (set_attr "mode" "QI")
1638 (set_attr "length_immediate" "0")])
1640 (define_insn "*movsi_extv_1"
1641 [(set (match_operand:SI 0 "register_operand" "=R")
1642 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1646 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1647 [(set_attr "type" "imovx")
1648 (set_attr "mode" "SI")])
1650 (define_insn "*movhi_extv_1"
1651 [(set (match_operand:HI 0 "register_operand" "=R")
1652 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1656 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1657 [(set_attr "type" "imovx")
1658 (set_attr "mode" "SI")])
1660 (define_insn "*movqi_extv_1"
1661 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1662 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1667 switch (get_attr_type (insn))
1670 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1672 return "mov{b}\t{%h1, %0|%0, %h1}";
1676 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1677 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1678 (ne (symbol_ref "TARGET_MOVX")
1680 (const_string "imovx")
1681 (const_string "imov")))
1683 (if_then_else (eq_attr "type" "imovx")
1685 (const_string "QI")))])
1687 (define_insn "*movqi_extv_1_rex64"
1688 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1689 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1694 switch (get_attr_type (insn))
1697 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1699 return "mov{b}\t{%h1, %0|%0, %h1}";
1703 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1704 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1705 (ne (symbol_ref "TARGET_MOVX")
1707 (const_string "imovx")
1708 (const_string "imov")))
1710 (if_then_else (eq_attr "type" "imovx")
1712 (const_string "QI")))])
1714 ;; Stores and loads of ax to arbitrary constant address.
1715 ;; We fake an second form of instruction to force reload to load address
1716 ;; into register when rax is not available
1717 (define_insn "*movabsqi_1_rex64"
1718 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1719 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1720 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1722 movabs{b}\t{%1, %P0|%P0, %1}
1723 mov{b}\t{%1, %a0|%a0, %1}"
1724 [(set_attr "type" "imov")
1725 (set_attr "modrm" "0,*")
1726 (set_attr "length_address" "8,0")
1727 (set_attr "length_immediate" "0,*")
1728 (set_attr "memory" "store")
1729 (set_attr "mode" "QI")])
1731 (define_insn "*movabsqi_2_rex64"
1732 [(set (match_operand:QI 0 "register_operand" "=a,r")
1733 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1734 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1736 movabs{b}\t{%P1, %0|%0, %P1}
1737 mov{b}\t{%a1, %0|%0, %a1}"
1738 [(set_attr "type" "imov")
1739 (set_attr "modrm" "0,*")
1740 (set_attr "length_address" "8,0")
1741 (set_attr "length_immediate" "0")
1742 (set_attr "memory" "load")
1743 (set_attr "mode" "QI")])
1745 (define_insn "*movdi_extzv_1"
1746 [(set (match_operand:DI 0 "register_operand" "=R")
1747 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1751 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1752 [(set_attr "type" "imovx")
1753 (set_attr "mode" "DI")])
1755 (define_insn "*movsi_extzv_1"
1756 [(set (match_operand:SI 0 "register_operand" "=R")
1757 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1761 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1762 [(set_attr "type" "imovx")
1763 (set_attr "mode" "SI")])
1765 (define_insn "*movqi_extzv_2"
1766 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1767 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1772 switch (get_attr_type (insn))
1775 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1777 return "mov{b}\t{%h1, %0|%0, %h1}";
1781 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1782 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1783 (ne (symbol_ref "TARGET_MOVX")
1785 (const_string "imovx")
1786 (const_string "imov")))
1788 (if_then_else (eq_attr "type" "imovx")
1790 (const_string "QI")))])
1792 (define_insn "*movqi_extzv_2_rex64"
1793 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1794 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1799 switch (get_attr_type (insn))
1802 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1804 return "mov{b}\t{%h1, %0|%0, %h1}";
1808 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1809 (ne (symbol_ref "TARGET_MOVX")
1811 (const_string "imovx")
1812 (const_string "imov")))
1814 (if_then_else (eq_attr "type" "imovx")
1816 (const_string "QI")))])
1818 (define_insn "movsi_insv_1"
1819 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1822 (match_operand:SI 1 "general_operand" "Qmn"))]
1824 "mov{b}\t{%b1, %h0|%h0, %b1}"
1825 [(set_attr "type" "imov")
1826 (set_attr "mode" "QI")])
1828 (define_insn "*movsi_insv_1_rex64"
1829 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1832 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1834 "mov{b}\t{%b1, %h0|%h0, %b1}"
1835 [(set_attr "type" "imov")
1836 (set_attr "mode" "QI")])
1838 (define_insn "movdi_insv_1_rex64"
1839 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1842 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1844 "mov{b}\t{%b1, %h0|%h0, %b1}"
1845 [(set_attr "type" "imov")
1846 (set_attr "mode" "QI")])
1848 (define_insn "*movqi_insv_2"
1849 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1852 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1855 "mov{b}\t{%h1, %h0|%h0, %h1}"
1856 [(set_attr "type" "imov")
1857 (set_attr "mode" "QI")])
1859 (define_expand "movdi"
1860 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1861 (match_operand:DI 1 "general_operand" ""))]
1863 "ix86_expand_move (DImode, operands); DONE;")
1865 (define_insn "*pushdi"
1866 [(set (match_operand:DI 0 "push_operand" "=<")
1867 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1871 (define_insn "*pushdi2_rex64"
1872 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1873 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1878 [(set_attr "type" "push,multi")
1879 (set_attr "mode" "DI")])
1881 ;; Convert impossible pushes of immediate to existing instructions.
1882 ;; First try to get scratch register and go through it. In case this
1883 ;; fails, push sign extended lower part first and then overwrite
1884 ;; upper part by 32bit move.
1886 [(match_scratch:DI 2 "r")
1887 (set (match_operand:DI 0 "push_operand" "")
1888 (match_operand:DI 1 "immediate_operand" ""))]
1889 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1890 && !x86_64_immediate_operand (operands[1], DImode)"
1891 [(set (match_dup 2) (match_dup 1))
1892 (set (match_dup 0) (match_dup 2))]
1895 ;; We need to define this as both peepholer and splitter for case
1896 ;; peephole2 pass is not run.
1897 ;; "&& 1" is needed to keep it from matching the previous pattern.
1899 [(set (match_operand:DI 0 "push_operand" "")
1900 (match_operand:DI 1 "immediate_operand" ""))]
1901 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1902 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1903 [(set (match_dup 0) (match_dup 1))
1904 (set (match_dup 2) (match_dup 3))]
1905 "split_di (operands + 1, 1, operands + 2, operands + 3);
1906 operands[1] = gen_lowpart (DImode, operands[2]);
1907 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1912 [(set (match_operand:DI 0 "push_operand" "")
1913 (match_operand:DI 1 "immediate_operand" ""))]
1914 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1915 ? flow2_completed : reload_completed)
1916 && !symbolic_operand (operands[1], DImode)
1917 && !x86_64_immediate_operand (operands[1], DImode)"
1918 [(set (match_dup 0) (match_dup 1))
1919 (set (match_dup 2) (match_dup 3))]
1920 "split_di (operands + 1, 1, operands + 2, operands + 3);
1921 operands[1] = gen_lowpart (DImode, operands[2]);
1922 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1926 (define_insn "*pushdi2_prologue_rex64"
1927 [(set (match_operand:DI 0 "push_operand" "=<")
1928 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1929 (clobber (mem:BLK (scratch)))]
1932 [(set_attr "type" "push")
1933 (set_attr "mode" "DI")])
1935 (define_insn "*popdi1_epilogue_rex64"
1936 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1937 (mem:DI (reg:DI SP_REG)))
1938 (set (reg:DI SP_REG)
1939 (plus:DI (reg:DI SP_REG) (const_int 8)))
1940 (clobber (mem:BLK (scratch)))]
1943 [(set_attr "type" "pop")
1944 (set_attr "mode" "DI")])
1946 (define_insn "popdi1"
1947 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1948 (mem:DI (reg:DI SP_REG)))
1949 (set (reg:DI SP_REG)
1950 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1953 [(set_attr "type" "pop")
1954 (set_attr "mode" "DI")])
1956 (define_insn "*movdi_xor_rex64"
1957 [(set (match_operand:DI 0 "register_operand" "=r")
1958 (match_operand:DI 1 "const0_operand" "i"))
1959 (clobber (reg:CC FLAGS_REG))]
1960 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1961 && reload_completed"
1962 "xor{l}\t{%k0, %k0|%k0, %k0}"
1963 [(set_attr "type" "alu1")
1964 (set_attr "mode" "SI")
1965 (set_attr "length_immediate" "0")])
1967 (define_insn "*movdi_or_rex64"
1968 [(set (match_operand:DI 0 "register_operand" "=r")
1969 (match_operand:DI 1 "const_int_operand" "i"))
1970 (clobber (reg:CC FLAGS_REG))]
1971 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1973 && operands[1] == constm1_rtx"
1975 operands[1] = constm1_rtx;
1976 return "or{q}\t{%1, %0|%0, %1}";
1978 [(set_attr "type" "alu1")
1979 (set_attr "mode" "DI")
1980 (set_attr "length_immediate" "1")])
1982 (define_insn "*movdi_2"
1983 [(set (match_operand:DI 0 "nonimmediate_operand"
1984 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
1985 (match_operand:DI 1 "general_operand"
1986 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
1987 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1992 movq\t{%1, %0|%0, %1}
1993 movq\t{%1, %0|%0, %1}
1995 movq\t{%1, %0|%0, %1}
1996 movdqa\t{%1, %0|%0, %1}
1997 movq\t{%1, %0|%0, %1}
1999 movlps\t{%1, %0|%0, %1}
2000 movaps\t{%1, %0|%0, %1}
2001 movlps\t{%1, %0|%0, %1}"
2002 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2003 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2006 [(set (match_operand:DI 0 "push_operand" "")
2007 (match_operand:DI 1 "general_operand" ""))]
2008 "!TARGET_64BIT && reload_completed
2009 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2011 "ix86_split_long_move (operands); DONE;")
2013 ;; %%% This multiword shite has got to go.
2015 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2016 (match_operand:DI 1 "general_operand" ""))]
2017 "!TARGET_64BIT && reload_completed
2018 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2019 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2021 "ix86_split_long_move (operands); DONE;")
2023 (define_insn "*movdi_1_rex64"
2024 [(set (match_operand:DI 0 "nonimmediate_operand"
2025 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2026 (match_operand:DI 1 "general_operand"
2027 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2028 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2030 switch (get_attr_type (insn))
2033 if (SSE_REG_P (operands[0]))
2034 return "movq2dq\t{%1, %0|%0, %1}";
2036 return "movdq2q\t{%1, %0|%0, %1}";
2039 if (get_attr_mode (insn) == MODE_TI)
2040 return "movdqa\t{%1, %0|%0, %1}";
2044 /* Moves from and into integer register is done using movd
2045 opcode with REX prefix. */
2046 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2047 return "movd\t{%1, %0|%0, %1}";
2048 return "movq\t{%1, %0|%0, %1}";
2052 return "pxor\t%0, %0";
2058 return "lea{q}\t{%a1, %0|%0, %a1}";
2061 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2062 if (get_attr_mode (insn) == MODE_SI)
2063 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2064 else if (which_alternative == 2)
2065 return "movabs{q}\t{%1, %0|%0, %1}";
2067 return "mov{q}\t{%1, %0|%0, %1}";
2071 (cond [(eq_attr "alternative" "5")
2072 (const_string "mmxadd")
2073 (eq_attr "alternative" "6,7,8,9,10")
2074 (const_string "mmxmov")
2075 (eq_attr "alternative" "11")
2076 (const_string "sselog1")
2077 (eq_attr "alternative" "12,13,14,15,16")
2078 (const_string "ssemov")
2079 (eq_attr "alternative" "17,18")
2080 (const_string "ssecvt")
2081 (eq_attr "alternative" "4")
2082 (const_string "multi")
2083 (match_operand:DI 1 "pic_32bit_operand" "")
2084 (const_string "lea")
2086 (const_string "imov")))
2087 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2088 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2091 ;; Stores and loads of ax to arbitrary constant address.
2092 ;; We fake an second form of instruction to force reload to load address
2093 ;; into register when rax is not available
2094 (define_insn "*movabsdi_1_rex64"
2095 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2096 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2097 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2099 movabs{q}\t{%1, %P0|%P0, %1}
2100 mov{q}\t{%1, %a0|%a0, %1}"
2101 [(set_attr "type" "imov")
2102 (set_attr "modrm" "0,*")
2103 (set_attr "length_address" "8,0")
2104 (set_attr "length_immediate" "0,*")
2105 (set_attr "memory" "store")
2106 (set_attr "mode" "DI")])
2108 (define_insn "*movabsdi_2_rex64"
2109 [(set (match_operand:DI 0 "register_operand" "=a,r")
2110 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2111 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2113 movabs{q}\t{%P1, %0|%0, %P1}
2114 mov{q}\t{%a1, %0|%0, %a1}"
2115 [(set_attr "type" "imov")
2116 (set_attr "modrm" "0,*")
2117 (set_attr "length_address" "8,0")
2118 (set_attr "length_immediate" "0")
2119 (set_attr "memory" "load")
2120 (set_attr "mode" "DI")])
2122 ;; Convert impossible stores of immediate to existing instructions.
2123 ;; First try to get scratch register and go through it. In case this
2124 ;; fails, move by 32bit parts.
2126 [(match_scratch:DI 2 "r")
2127 (set (match_operand:DI 0 "memory_operand" "")
2128 (match_operand:DI 1 "immediate_operand" ""))]
2129 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode)"
2131 [(set (match_dup 2) (match_dup 1))
2132 (set (match_dup 0) (match_dup 2))]
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2139 [(set (match_operand:DI 0 "memory_operand" "")
2140 (match_operand:DI 1 "immediate_operand" ""))]
2141 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143 [(set (match_dup 2) (match_dup 3))
2144 (set (match_dup 4) (match_dup 5))]
2145 "split_di (operands, 2, operands + 2, operands + 4);")
2148 [(set (match_operand:DI 0 "memory_operand" "")
2149 (match_operand:DI 1 "immediate_operand" ""))]
2150 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151 ? flow2_completed : reload_completed)
2152 && !symbolic_operand (operands[1], DImode)
2153 && !x86_64_immediate_operand (operands[1], DImode)"
2154 [(set (match_dup 2) (match_dup 3))
2155 (set (match_dup 4) (match_dup 5))]
2156 "split_di (operands, 2, operands + 2, operands + 4);")
2158 (define_insn "*swapdi_rex64"
2159 [(set (match_operand:DI 0 "register_operand" "+r")
2160 (match_operand:DI 1 "register_operand" "+r"))
2165 [(set_attr "type" "imov")
2166 (set_attr "mode" "DI")
2167 (set_attr "pent_pair" "np")
2168 (set_attr "athlon_decode" "vector")
2169 (set_attr "amdfam10_decode" "double")])
2171 (define_expand "movti"
2172 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2173 (match_operand:TI 1 "nonimmediate_operand" ""))]
2174 "TARGET_SSE || TARGET_64BIT"
2177 ix86_expand_move (TImode, operands);
2179 ix86_expand_vector_move (TImode, operands);
2183 (define_insn "*movti_internal"
2184 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2185 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2186 "TARGET_SSE && !TARGET_64BIT
2187 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189 switch (which_alternative)
2192 if (get_attr_mode (insn) == MODE_V4SF)
2193 return "xorps\t%0, %0";
2195 return "pxor\t%0, %0";
2198 if (get_attr_mode (insn) == MODE_V4SF)
2199 return "movaps\t{%1, %0|%0, %1}";
2201 return "movdqa\t{%1, %0|%0, %1}";
2206 [(set_attr "type" "sselog1,ssemov,ssemov")
2208 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2209 (ne (symbol_ref "optimize_size") (const_int 0)))
2210 (const_string "V4SF")
2211 (and (eq_attr "alternative" "2")
2212 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2214 (const_string "V4SF")]
2215 (const_string "TI")))])
2217 (define_insn "*movti_rex64"
2218 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2219 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2221 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2223 switch (which_alternative)
2229 if (get_attr_mode (insn) == MODE_V4SF)
2230 return "xorps\t%0, %0";
2232 return "pxor\t%0, %0";
2235 if (get_attr_mode (insn) == MODE_V4SF)
2236 return "movaps\t{%1, %0|%0, %1}";
2238 return "movdqa\t{%1, %0|%0, %1}";
2243 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2245 (cond [(eq_attr "alternative" "2,3")
2247 (ne (symbol_ref "optimize_size")
2249 (const_string "V4SF")
2250 (const_string "TI"))
2251 (eq_attr "alternative" "4")
2253 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2255 (ne (symbol_ref "optimize_size")
2257 (const_string "V4SF")
2258 (const_string "TI"))]
2259 (const_string "DI")))])
2262 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2263 (match_operand:TI 1 "general_operand" ""))]
2264 "reload_completed && !SSE_REG_P (operands[0])
2265 && !SSE_REG_P (operands[1])"
2267 "ix86_split_long_move (operands); DONE;")
2269 (define_expand "movsf"
2270 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2271 (match_operand:SF 1 "general_operand" ""))]
2273 "ix86_expand_move (SFmode, operands); DONE;")
2275 (define_insn "*pushsf"
2276 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2277 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2280 /* Anything else should be already split before reg-stack. */
2281 gcc_assert (which_alternative == 1);
2282 return "push{l}\t%1";
2284 [(set_attr "type" "multi,push,multi")
2285 (set_attr "unit" "i387,*,*")
2286 (set_attr "mode" "SF,SI,SF")])
2288 (define_insn "*pushsf_rex64"
2289 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2290 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2293 /* Anything else should be already split before reg-stack. */
2294 gcc_assert (which_alternative == 1);
2295 return "push{q}\t%q1";
2297 [(set_attr "type" "multi,push,multi")
2298 (set_attr "unit" "i387,*,*")
2299 (set_attr "mode" "SF,DI,SF")])
2302 [(set (match_operand:SF 0 "push_operand" "")
2303 (match_operand:SF 1 "memory_operand" ""))]
2305 && MEM_P (operands[1])
2306 && constant_pool_reference_p (operands[1])"
2309 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2312 ;; %%% Kill this when call knows how to work this out.
2314 [(set (match_operand:SF 0 "push_operand" "")
2315 (match_operand:SF 1 "any_fp_register_operand" ""))]
2317 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2318 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2321 [(set (match_operand:SF 0 "push_operand" "")
2322 (match_operand:SF 1 "any_fp_register_operand" ""))]
2324 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2325 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2327 (define_insn "*movsf_1"
2328 [(set (match_operand:SF 0 "nonimmediate_operand"
2329 "=f,m,f,r ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r ")
2330 (match_operand:SF 1 "general_operand"
2331 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r ,*Ym"))]
2332 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2333 && (reload_in_progress || reload_completed
2334 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2335 || (!TARGET_SSE_MATH && optimize_size
2336 && standard_80387_constant_p (operands[1]))
2337 || GET_CODE (operands[1]) != CONST_DOUBLE
2338 || memory_operand (operands[0], SFmode))"
2340 switch (which_alternative)
2343 return output_387_reg_move (insn, operands);
2346 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2347 return "fstp%z0\t%y0";
2349 return "fst%z0\t%y0";
2352 return standard_80387_constant_opcode (operands[1]);
2356 return "mov{l}\t{%1, %0|%0, %1}";
2358 if (get_attr_mode (insn) == MODE_TI)
2359 return "pxor\t%0, %0";
2361 return "xorps\t%0, %0";
2363 if (get_attr_mode (insn) == MODE_V4SF)
2364 return "movaps\t{%1, %0|%0, %1}";
2366 return "movss\t{%1, %0|%0, %1}";
2368 return "movss\t{%1, %0|%0, %1}";
2371 case 12: case 13: case 14: case 15:
2372 return "movd\t{%1, %0|%0, %1}";
2375 return "movq\t{%1, %0|%0, %1}";
2381 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2383 (cond [(eq_attr "alternative" "3,4,9,10")
2385 (eq_attr "alternative" "5")
2387 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2389 (ne (symbol_ref "TARGET_SSE2")
2391 (eq (symbol_ref "optimize_size")
2394 (const_string "V4SF"))
2395 /* For architectures resolving dependencies on
2396 whole SSE registers use APS move to break dependency
2397 chains, otherwise use short move to avoid extra work.
2399 Do the same for architectures resolving dependencies on
2400 the parts. While in DF mode it is better to always handle
2401 just register parts, the SF mode is different due to lack
2402 of instructions to load just part of the register. It is
2403 better to maintain the whole registers in single format
2404 to avoid problems on using packed logical operations. */
2405 (eq_attr "alternative" "6")
2407 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2409 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2411 (const_string "V4SF")
2412 (const_string "SF"))
2413 (eq_attr "alternative" "11")
2414 (const_string "DI")]
2415 (const_string "SF")))])
2417 (define_insn "*swapsf"
2418 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2419 (match_operand:SF 1 "fp_register_operand" "+f"))
2422 "reload_completed || TARGET_80387"
2424 if (STACK_TOP_P (operands[0]))
2429 [(set_attr "type" "fxch")
2430 (set_attr "mode" "SF")])
2432 (define_expand "movdf"
2433 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2434 (match_operand:DF 1 "general_operand" ""))]
2436 "ix86_expand_move (DFmode, operands); DONE;")
2438 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2439 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2440 ;; On the average, pushdf using integers can be still shorter. Allow this
2441 ;; pattern for optimize_size too.
2443 (define_insn "*pushdf_nointeger"
2444 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2445 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2446 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2448 /* This insn should be already split before reg-stack. */
2451 [(set_attr "type" "multi")
2452 (set_attr "unit" "i387,*,*,*")
2453 (set_attr "mode" "DF,SI,SI,DF")])
2455 (define_insn "*pushdf_integer"
2456 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2457 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2458 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2460 /* This insn should be already split before reg-stack. */
2463 [(set_attr "type" "multi")
2464 (set_attr "unit" "i387,*,*")
2465 (set_attr "mode" "DF,SI,DF")])
2467 ;; %%% Kill this when call knows how to work this out.
2469 [(set (match_operand:DF 0 "push_operand" "")
2470 (match_operand:DF 1 "any_fp_register_operand" ""))]
2471 "!TARGET_64BIT && reload_completed"
2472 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2473 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2477 [(set (match_operand:DF 0 "push_operand" "")
2478 (match_operand:DF 1 "any_fp_register_operand" ""))]
2479 "TARGET_64BIT && reload_completed"
2480 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2481 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2485 [(set (match_operand:DF 0 "push_operand" "")
2486 (match_operand:DF 1 "general_operand" ""))]
2489 "ix86_split_long_move (operands); DONE;")
2491 ;; Moving is usually shorter when only FP registers are used. This separate
2492 ;; movdf pattern avoids the use of integer registers for FP operations
2493 ;; when optimizing for size.
2495 (define_insn "*movdf_nointeger"
2496 [(set (match_operand:DF 0 "nonimmediate_operand"
2497 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2498 (match_operand:DF 1 "general_operand"
2499 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
2500 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2501 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2502 && (reload_in_progress || reload_completed
2503 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2504 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2505 && standard_80387_constant_p (operands[1]))
2506 || GET_CODE (operands[1]) != CONST_DOUBLE
2507 || memory_operand (operands[0], DFmode))"
2509 switch (which_alternative)
2512 return output_387_reg_move (insn, operands);
2515 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2516 return "fstp%z0\t%y0";
2518 return "fst%z0\t%y0";
2521 return standard_80387_constant_opcode (operands[1]);
2527 switch (get_attr_mode (insn))
2530 return "xorps\t%0, %0";
2532 return "xorpd\t%0, %0";
2534 return "pxor\t%0, %0";
2541 switch (get_attr_mode (insn))
2544 return "movaps\t{%1, %0|%0, %1}";
2546 return "movapd\t{%1, %0|%0, %1}";
2548 return "movdqa\t{%1, %0|%0, %1}";
2550 return "movq\t{%1, %0|%0, %1}";
2552 return "movsd\t{%1, %0|%0, %1}";
2554 return "movlpd\t{%1, %0|%0, %1}";
2556 return "movlps\t{%1, %0|%0, %1}";
2565 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2567 (cond [(eq_attr "alternative" "0,1,2")
2569 (eq_attr "alternative" "3,4")
2572 /* For SSE1, we have many fewer alternatives. */
2573 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2574 (cond [(eq_attr "alternative" "5,6")
2575 (const_string "V4SF")
2577 (const_string "V2SF"))
2579 /* xorps is one byte shorter. */
2580 (eq_attr "alternative" "5")
2581 (cond [(ne (symbol_ref "optimize_size")
2583 (const_string "V4SF")
2584 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2588 (const_string "V2DF"))
2590 /* For architectures resolving dependencies on
2591 whole SSE registers use APD move to break dependency
2592 chains, otherwise use short move to avoid extra work.
2594 movaps encodes one byte shorter. */
2595 (eq_attr "alternative" "6")
2597 [(ne (symbol_ref "optimize_size")
2599 (const_string "V4SF")
2600 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2602 (const_string "V2DF")
2604 (const_string "DF"))
2605 /* For architectures resolving dependencies on register
2606 parts we may avoid extra work to zero out upper part
2608 (eq_attr "alternative" "7")
2610 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2612 (const_string "V1DF")
2613 (const_string "DF"))
2615 (const_string "DF")))])
2617 (define_insn "*movdf_integer_rex64"
2618 [(set (match_operand:DF 0 "nonimmediate_operand"
2619 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2620 (match_operand:DF 1 "general_operand"
2621 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2622 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2623 && (reload_in_progress || reload_completed
2624 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2625 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2626 && standard_80387_constant_p (operands[1]))
2627 || GET_CODE (operands[1]) != CONST_DOUBLE
2628 || memory_operand (operands[0], DFmode))"
2630 switch (which_alternative)
2633 return output_387_reg_move (insn, operands);
2636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2637 return "fstp%z0\t%y0";
2639 return "fst%z0\t%y0";
2642 return standard_80387_constant_opcode (operands[1]);
2649 switch (get_attr_mode (insn))
2652 return "xorps\t%0, %0";
2654 return "xorpd\t%0, %0";
2656 return "pxor\t%0, %0";
2663 switch (get_attr_mode (insn))
2666 return "movaps\t{%1, %0|%0, %1}";
2668 return "movapd\t{%1, %0|%0, %1}";
2670 return "movdqa\t{%1, %0|%0, %1}";
2672 return "movq\t{%1, %0|%0, %1}";
2674 return "movsd\t{%1, %0|%0, %1}";
2676 return "movlpd\t{%1, %0|%0, %1}";
2678 return "movlps\t{%1, %0|%0, %1}";
2685 return "movd\t{%1, %0|%0, %1}";
2691 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2693 (cond [(eq_attr "alternative" "0,1,2")
2695 (eq_attr "alternative" "3,4,9,10")
2698 /* For SSE1, we have many fewer alternatives. */
2699 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700 (cond [(eq_attr "alternative" "5,6")
2701 (const_string "V4SF")
2703 (const_string "V2SF"))
2705 /* xorps is one byte shorter. */
2706 (eq_attr "alternative" "5")
2707 (cond [(ne (symbol_ref "optimize_size")
2709 (const_string "V4SF")
2710 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2714 (const_string "V2DF"))
2716 /* For architectures resolving dependencies on
2717 whole SSE registers use APD move to break dependency
2718 chains, otherwise use short move to avoid extra work.
2720 movaps encodes one byte shorter. */
2721 (eq_attr "alternative" "6")
2723 [(ne (symbol_ref "optimize_size")
2725 (const_string "V4SF")
2726 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2728 (const_string "V2DF")
2730 (const_string "DF"))
2731 /* For architectures resolving dependencies on register
2732 parts we may avoid extra work to zero out upper part
2734 (eq_attr "alternative" "7")
2736 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2738 (const_string "V1DF")
2739 (const_string "DF"))
2741 (const_string "DF")))])
2743 (define_insn "*movdf_integer"
2744 [(set (match_operand:DF 0 "nonimmediate_operand"
2745 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2746 (match_operand:DF 1 "general_operand"
2747 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2748 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2749 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2750 && (reload_in_progress || reload_completed
2751 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2752 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2753 && standard_80387_constant_p (operands[1]))
2754 || GET_CODE (operands[1]) != CONST_DOUBLE
2755 || memory_operand (operands[0], DFmode))"
2757 switch (which_alternative)
2760 return output_387_reg_move (insn, operands);
2763 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764 return "fstp%z0\t%y0";
2766 return "fst%z0\t%y0";
2769 return standard_80387_constant_opcode (operands[1]);
2776 switch (get_attr_mode (insn))
2779 return "xorps\t%0, %0";
2781 return "xorpd\t%0, %0";
2783 return "pxor\t%0, %0";
2790 switch (get_attr_mode (insn))
2793 return "movaps\t{%1, %0|%0, %1}";
2795 return "movapd\t{%1, %0|%0, %1}";
2797 return "movdqa\t{%1, %0|%0, %1}";
2799 return "movq\t{%1, %0|%0, %1}";
2801 return "movsd\t{%1, %0|%0, %1}";
2803 return "movlpd\t{%1, %0|%0, %1}";
2805 return "movlps\t{%1, %0|%0, %1}";
2814 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2816 (cond [(eq_attr "alternative" "0,1,2")
2818 (eq_attr "alternative" "3,4")
2821 /* For SSE1, we have many fewer alternatives. */
2822 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2823 (cond [(eq_attr "alternative" "5,6")
2824 (const_string "V4SF")
2826 (const_string "V2SF"))
2828 /* xorps is one byte shorter. */
2829 (eq_attr "alternative" "5")
2830 (cond [(ne (symbol_ref "optimize_size")
2832 (const_string "V4SF")
2833 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2837 (const_string "V2DF"))
2839 /* For architectures resolving dependencies on
2840 whole SSE registers use APD move to break dependency
2841 chains, otherwise use short move to avoid extra work.
2843 movaps encodes one byte shorter. */
2844 (eq_attr "alternative" "6")
2846 [(ne (symbol_ref "optimize_size")
2848 (const_string "V4SF")
2849 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2851 (const_string "V2DF")
2853 (const_string "DF"))
2854 /* For architectures resolving dependencies on register
2855 parts we may avoid extra work to zero out upper part
2857 (eq_attr "alternative" "7")
2859 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2861 (const_string "V1DF")
2862 (const_string "DF"))
2864 (const_string "DF")))])
2867 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2868 (match_operand:DF 1 "general_operand" ""))]
2870 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871 && ! (ANY_FP_REG_P (operands[0]) ||
2872 (GET_CODE (operands[0]) == SUBREG
2873 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874 && ! (ANY_FP_REG_P (operands[1]) ||
2875 (GET_CODE (operands[1]) == SUBREG
2876 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2878 "ix86_split_long_move (operands); DONE;")
2880 (define_insn "*swapdf"
2881 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2882 (match_operand:DF 1 "fp_register_operand" "+f"))
2885 "reload_completed || TARGET_80387"
2887 if (STACK_TOP_P (operands[0]))
2892 [(set_attr "type" "fxch")
2893 (set_attr "mode" "DF")])
2895 (define_expand "movxf"
2896 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2897 (match_operand:XF 1 "general_operand" ""))]
2899 "ix86_expand_move (XFmode, operands); DONE;")
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2903 ;; Pushing using integer instructions is longer except for constants
2904 ;; and direct memory references.
2905 ;; (assuming that any given constant is pushed only once, but this ought to be
2906 ;; handled elsewhere).
2908 (define_insn "*pushxf_nointeger"
2909 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2910 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2913 /* This insn should be already split before reg-stack. */
2916 [(set_attr "type" "multi")
2917 (set_attr "unit" "i387,*,*")
2918 (set_attr "mode" "XF,SI,SI")])
2920 (define_insn "*pushxf_integer"
2921 [(set (match_operand:XF 0 "push_operand" "=<,<")
2922 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2925 /* This insn should be already split before reg-stack. */
2928 [(set_attr "type" "multi")
2929 (set_attr "unit" "i387,*")
2930 (set_attr "mode" "XF,SI")])
2933 [(set (match_operand 0 "push_operand" "")
2934 (match_operand 1 "general_operand" ""))]
2936 && (GET_MODE (operands[0]) == XFmode
2937 || GET_MODE (operands[0]) == DFmode)
2938 && !ANY_FP_REG_P (operands[1])"
2940 "ix86_split_long_move (operands); DONE;")
2943 [(set (match_operand:XF 0 "push_operand" "")
2944 (match_operand:XF 1 "any_fp_register_operand" ""))]
2946 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2947 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2948 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2951 [(set (match_operand:XF 0 "push_operand" "")
2952 (match_operand:XF 1 "any_fp_register_operand" ""))]
2954 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2955 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2956 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2958 ;; Do not use integer registers when optimizing for size
2959 (define_insn "*movxf_nointeger"
2960 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2961 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2963 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2964 && (reload_in_progress || reload_completed
2965 || (optimize_size && standard_80387_constant_p (operands[1]))
2966 || GET_CODE (operands[1]) != CONST_DOUBLE
2967 || memory_operand (operands[0], XFmode))"
2969 switch (which_alternative)
2972 return output_387_reg_move (insn, operands);
2975 /* There is no non-popping store to memory for XFmode. So if
2976 we need one, follow the store with a load. */
2977 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2978 return "fstp%z0\t%y0\;fld%z0\t%y0";
2980 return "fstp%z0\t%y0";
2983 return standard_80387_constant_opcode (operands[1]);
2991 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2992 (set_attr "mode" "XF,XF,XF,SI,SI")])
2994 (define_insn "*movxf_integer"
2995 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2996 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2998 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2999 && (reload_in_progress || reload_completed
3000 || (optimize_size && standard_80387_constant_p (operands[1]))
3001 || GET_CODE (operands[1]) != CONST_DOUBLE
3002 || memory_operand (operands[0], XFmode))"
3004 switch (which_alternative)
3007 return output_387_reg_move (insn, operands);
3010 /* There is no non-popping store to memory for XFmode. So if
3011 we need one, follow the store with a load. */
3012 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013 return "fstp%z0\t%y0\;fld%z0\t%y0";
3015 return "fstp%z0\t%y0";
3018 return standard_80387_constant_opcode (operands[1]);
3027 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3028 (set_attr "mode" "XF,XF,XF,SI,SI")])
3031 [(set (match_operand 0 "nonimmediate_operand" "")
3032 (match_operand 1 "general_operand" ""))]
3034 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3035 && GET_MODE (operands[0]) == XFmode
3036 && ! (ANY_FP_REG_P (operands[0]) ||
3037 (GET_CODE (operands[0]) == SUBREG
3038 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3039 && ! (ANY_FP_REG_P (operands[1]) ||
3040 (GET_CODE (operands[1]) == SUBREG
3041 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3043 "ix86_split_long_move (operands); DONE;")
3046 [(set (match_operand 0 "register_operand" "")
3047 (match_operand 1 "memory_operand" ""))]
3049 && MEM_P (operands[1])
3050 && (GET_MODE (operands[0]) == XFmode
3051 || GET_MODE (operands[0]) == SFmode
3052 || GET_MODE (operands[0]) == DFmode)
3053 && constant_pool_reference_p (operands[1])"
3054 [(set (match_dup 0) (match_dup 1))]
3056 rtx c = avoid_constant_pool_reference (operands[1]);
3057 rtx r = operands[0];
3059 if (GET_CODE (r) == SUBREG)
3064 if (!standard_sse_constant_p (c))
3067 else if (FP_REG_P (r))
3069 if (!standard_80387_constant_p (c))
3072 else if (MMX_REG_P (r))
3079 [(set (match_operand 0 "register_operand" "")
3080 (float_extend (match_operand 1 "memory_operand" "")))]
3082 && MEM_P (operands[1])
3083 && (GET_MODE (operands[0]) == XFmode
3084 || GET_MODE (operands[0]) == SFmode
3085 || GET_MODE (operands[0]) == DFmode)
3086 && constant_pool_reference_p (operands[1])"
3087 [(set (match_dup 0) (match_dup 1))]
3089 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3090 rtx r = operands[0];
3092 if (GET_CODE (r) == SUBREG)
3097 if (!standard_sse_constant_p (c))
3100 else if (FP_REG_P (r))
3102 if (!standard_80387_constant_p (c))
3105 else if (MMX_REG_P (r))
3111 (define_insn "swapxf"
3112 [(set (match_operand:XF 0 "register_operand" "+f")
3113 (match_operand:XF 1 "register_operand" "+f"))
3118 if (STACK_TOP_P (operands[0]))
3123 [(set_attr "type" "fxch")
3124 (set_attr "mode" "XF")])
3126 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3128 [(set (match_operand:X87MODEF 0 "register_operand" "")
3129 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3130 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3131 && (standard_80387_constant_p (operands[1]) == 8
3132 || standard_80387_constant_p (operands[1]) == 9)"
3133 [(set (match_dup 0)(match_dup 1))
3135 (neg:X87MODEF (match_dup 0)))]
3139 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3140 if (real_isnegzero (&r))
3141 operands[1] = CONST0_RTX (<MODE>mode);
3143 operands[1] = CONST1_RTX (<MODE>mode);
3146 (define_expand "movtf"
3147 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3148 (match_operand:TF 1 "nonimmediate_operand" ""))]
3151 ix86_expand_move (TFmode, operands);
3155 (define_insn "*movtf_internal"
3156 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3157 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3159 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3161 switch (which_alternative)
3167 if (get_attr_mode (insn) == MODE_V4SF)
3168 return "xorps\t%0, %0";
3170 return "pxor\t%0, %0";
3173 if (get_attr_mode (insn) == MODE_V4SF)
3174 return "movaps\t{%1, %0|%0, %1}";
3176 return "movdqa\t{%1, %0|%0, %1}";
3181 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3183 (cond [(eq_attr "alternative" "2,3")
3185 (ne (symbol_ref "optimize_size")
3187 (const_string "V4SF")
3188 (const_string "TI"))
3189 (eq_attr "alternative" "4")
3191 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3193 (ne (symbol_ref "optimize_size")
3195 (const_string "V4SF")
3196 (const_string "TI"))]
3197 (const_string "DI")))])
3200 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201 (match_operand:TF 1 "general_operand" ""))]
3202 "reload_completed && !SSE_REG_P (operands[0])
3203 && !SSE_REG_P (operands[1])"
3205 "ix86_split_long_move (operands); DONE;")
3207 ;; Zero extension instructions
3209 (define_expand "zero_extendhisi2"
3210 [(set (match_operand:SI 0 "register_operand" "")
3211 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3214 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3216 operands[1] = force_reg (HImode, operands[1]);
3217 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3222 (define_insn "zero_extendhisi2_and"
3223 [(set (match_operand:SI 0 "register_operand" "=r")
3224 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3225 (clobber (reg:CC FLAGS_REG))]
3226 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3228 [(set_attr "type" "alu1")
3229 (set_attr "mode" "SI")])
3232 [(set (match_operand:SI 0 "register_operand" "")
3233 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3234 (clobber (reg:CC FLAGS_REG))]
3235 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3236 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3237 (clobber (reg:CC FLAGS_REG))])]
3240 (define_insn "*zero_extendhisi2_movzwl"
3241 [(set (match_operand:SI 0 "register_operand" "=r")
3242 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3244 "movz{wl|x}\t{%1, %0|%0, %1}"
3245 [(set_attr "type" "imovx")
3246 (set_attr "mode" "SI")])
3248 (define_expand "zero_extendqihi2"
3250 [(set (match_operand:HI 0 "register_operand" "")
3251 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3252 (clobber (reg:CC FLAGS_REG))])]
3256 (define_insn "*zero_extendqihi2_and"
3257 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3258 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3259 (clobber (reg:CC FLAGS_REG))]
3260 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3262 [(set_attr "type" "alu1")
3263 (set_attr "mode" "HI")])
3265 (define_insn "*zero_extendqihi2_movzbw_and"
3266 [(set (match_operand:HI 0 "register_operand" "=r,r")
3267 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3268 (clobber (reg:CC FLAGS_REG))]
3269 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3271 [(set_attr "type" "imovx,alu1")
3272 (set_attr "mode" "HI")])
3274 ; zero extend to SImode here to avoid partial register stalls
3275 (define_insn "*zero_extendqihi2_movzbl"
3276 [(set (match_operand:HI 0 "register_operand" "=r")
3277 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3279 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3280 [(set_attr "type" "imovx")
3281 (set_attr "mode" "SI")])
3283 ;; For the movzbw case strip only the clobber
3285 [(set (match_operand:HI 0 "register_operand" "")
3286 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3287 (clobber (reg:CC FLAGS_REG))]
3289 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3290 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3291 [(set (match_operand:HI 0 "register_operand" "")
3292 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3294 ;; When source and destination does not overlap, clear destination
3295 ;; first and then do the movb
3297 [(set (match_operand:HI 0 "register_operand" "")
3298 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3299 (clobber (reg:CC FLAGS_REG))]
3301 && ANY_QI_REG_P (operands[0])
3302 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3303 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3304 [(set (match_dup 0) (const_int 0))
3305 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3306 "operands[2] = gen_lowpart (QImode, operands[0]);")
3308 ;; Rest is handled by single and.
3310 [(set (match_operand:HI 0 "register_operand" "")
3311 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3312 (clobber (reg:CC FLAGS_REG))]
3314 && true_regnum (operands[0]) == true_regnum (operands[1])"
3315 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3316 (clobber (reg:CC FLAGS_REG))])]
3319 (define_expand "zero_extendqisi2"
3321 [(set (match_operand:SI 0 "register_operand" "")
3322 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3323 (clobber (reg:CC FLAGS_REG))])]
3327 (define_insn "*zero_extendqisi2_and"
3328 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3329 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3330 (clobber (reg:CC FLAGS_REG))]
3331 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3333 [(set_attr "type" "alu1")
3334 (set_attr "mode" "SI")])
3336 (define_insn "*zero_extendqisi2_movzbw_and"
3337 [(set (match_operand:SI 0 "register_operand" "=r,r")
3338 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3339 (clobber (reg:CC FLAGS_REG))]
3340 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3342 [(set_attr "type" "imovx,alu1")
3343 (set_attr "mode" "SI")])
3345 (define_insn "*zero_extendqisi2_movzbw"
3346 [(set (match_operand:SI 0 "register_operand" "=r")
3347 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3348 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3349 "movz{bl|x}\t{%1, %0|%0, %1}"
3350 [(set_attr "type" "imovx")
3351 (set_attr "mode" "SI")])
3353 ;; For the movzbl case strip only the clobber
3355 [(set (match_operand:SI 0 "register_operand" "")
3356 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3357 (clobber (reg:CC FLAGS_REG))]
3359 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3360 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3362 (zero_extend:SI (match_dup 1)))])
3364 ;; When source and destination does not overlap, clear destination
3365 ;; first and then do the movb
3367 [(set (match_operand:SI 0 "register_operand" "")
3368 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3369 (clobber (reg:CC FLAGS_REG))]
3371 && ANY_QI_REG_P (operands[0])
3372 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3373 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3374 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3375 [(set (match_dup 0) (const_int 0))
3376 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3377 "operands[2] = gen_lowpart (QImode, operands[0]);")
3379 ;; Rest is handled by single and.
3381 [(set (match_operand:SI 0 "register_operand" "")
3382 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3383 (clobber (reg:CC FLAGS_REG))]
3385 && true_regnum (operands[0]) == true_regnum (operands[1])"
3386 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3387 (clobber (reg:CC FLAGS_REG))])]
3390 ;; %%% Kill me once multi-word ops are sane.
3391 (define_expand "zero_extendsidi2"
3392 [(set (match_operand:DI 0 "register_operand" "=r")
3393 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3398 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3403 (define_insn "zero_extendsidi2_32"
3404 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3406 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3407 (clobber (reg:CC FLAGS_REG))]
3413 movd\t{%1, %0|%0, %1}
3414 movd\t{%1, %0|%0, %1}
3415 movd\t{%1, %0|%0, %1}
3416 movd\t{%1, %0|%0, %1}"
3417 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3418 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3420 (define_insn "zero_extendsidi2_rex64"
3421 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3423 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3426 mov\t{%k1, %k0|%k0, %k1}
3428 movd\t{%1, %0|%0, %1}
3429 movd\t{%1, %0|%0, %1}
3430 movd\t{%1, %0|%0, %1}
3431 movd\t{%1, %0|%0, %1}"
3432 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3433 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3436 [(set (match_operand:DI 0 "memory_operand" "")
3437 (zero_extend:DI (match_dup 0)))]
3439 [(set (match_dup 4) (const_int 0))]
3440 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3443 [(set (match_operand:DI 0 "register_operand" "")
3444 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3445 (clobber (reg:CC FLAGS_REG))]
3446 "!TARGET_64BIT && reload_completed
3447 && true_regnum (operands[0]) == true_regnum (operands[1])"
3448 [(set (match_dup 4) (const_int 0))]
3449 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3452 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3453 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3454 (clobber (reg:CC FLAGS_REG))]
3455 "!TARGET_64BIT && reload_completed
3456 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3457 [(set (match_dup 3) (match_dup 1))
3458 (set (match_dup 4) (const_int 0))]
3459 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3461 (define_insn "zero_extendhidi2"
3462 [(set (match_operand:DI 0 "register_operand" "=r")
3463 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3465 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3466 [(set_attr "type" "imovx")
3467 (set_attr "mode" "DI")])
3469 (define_insn "zero_extendqidi2"
3470 [(set (match_operand:DI 0 "register_operand" "=r")
3471 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3473 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3474 [(set_attr "type" "imovx")
3475 (set_attr "mode" "DI")])
3477 ;; Sign extension instructions
3479 (define_expand "extendsidi2"
3480 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3481 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3482 (clobber (reg:CC FLAGS_REG))
3483 (clobber (match_scratch:SI 2 ""))])]
3488 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3493 (define_insn "*extendsidi2_1"
3494 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496 (clobber (reg:CC FLAGS_REG))
3497 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3501 (define_insn "extendsidi2_rex64"
3502 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3503 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3507 movs{lq|x}\t{%1,%0|%0, %1}"
3508 [(set_attr "type" "imovx")
3509 (set_attr "mode" "DI")
3510 (set_attr "prefix_0f" "0")
3511 (set_attr "modrm" "0,1")])
3513 (define_insn "extendhidi2"
3514 [(set (match_operand:DI 0 "register_operand" "=r")
3515 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3517 "movs{wq|x}\t{%1,%0|%0, %1}"
3518 [(set_attr "type" "imovx")
3519 (set_attr "mode" "DI")])
3521 (define_insn "extendqidi2"
3522 [(set (match_operand:DI 0 "register_operand" "=r")
3523 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3525 "movs{bq|x}\t{%1,%0|%0, %1}"
3526 [(set_attr "type" "imovx")
3527 (set_attr "mode" "DI")])
3529 ;; Extend to memory case when source register does die.
3531 [(set (match_operand:DI 0 "memory_operand" "")
3532 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533 (clobber (reg:CC FLAGS_REG))
3534 (clobber (match_operand:SI 2 "register_operand" ""))]
3536 && dead_or_set_p (insn, operands[1])
3537 && !reg_mentioned_p (operands[1], operands[0]))"
3538 [(set (match_dup 3) (match_dup 1))
3539 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3540 (clobber (reg:CC FLAGS_REG))])
3541 (set (match_dup 4) (match_dup 1))]
3542 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3544 ;; Extend to memory case when source register does not die.
3546 [(set (match_operand:DI 0 "memory_operand" "")
3547 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3548 (clobber (reg:CC FLAGS_REG))
3549 (clobber (match_operand:SI 2 "register_operand" ""))]
3553 split_di (&operands[0], 1, &operands[3], &operands[4]);
3555 emit_move_insn (operands[3], operands[1]);
3557 /* Generate a cltd if possible and doing so it profitable. */
3558 if (true_regnum (operands[1]) == 0
3559 && true_regnum (operands[2]) == 1
3560 && (optimize_size || TARGET_USE_CLTD))
3562 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3566 emit_move_insn (operands[2], operands[1]);
3567 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3569 emit_move_insn (operands[4], operands[2]);
3573 ;; Extend to register case. Optimize case where source and destination
3574 ;; registers match and cases where we can use cltd.
3576 [(set (match_operand:DI 0 "register_operand" "")
3577 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3578 (clobber (reg:CC FLAGS_REG))
3579 (clobber (match_scratch:SI 2 ""))]
3583 split_di (&operands[0], 1, &operands[3], &operands[4]);
3585 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3586 emit_move_insn (operands[3], operands[1]);
3588 /* Generate a cltd if possible and doing so it profitable. */
3589 if (true_regnum (operands[3]) == 0
3590 && (optimize_size || TARGET_USE_CLTD))
3592 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3596 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3597 emit_move_insn (operands[4], operands[1]);
3599 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3603 (define_insn "extendhisi2"
3604 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3605 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3608 switch (get_attr_prefix_0f (insn))
3611 return "{cwtl|cwde}";
3613 return "movs{wl|x}\t{%1,%0|%0, %1}";
3616 [(set_attr "type" "imovx")
3617 (set_attr "mode" "SI")
3618 (set (attr "prefix_0f")
3619 ;; movsx is short decodable while cwtl is vector decoded.
3620 (if_then_else (and (eq_attr "cpu" "!k6")
3621 (eq_attr "alternative" "0"))
3623 (const_string "1")))
3625 (if_then_else (eq_attr "prefix_0f" "0")
3627 (const_string "1")))])
3629 (define_insn "*extendhisi2_zext"
3630 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3632 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3635 switch (get_attr_prefix_0f (insn))
3638 return "{cwtl|cwde}";
3640 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3643 [(set_attr "type" "imovx")
3644 (set_attr "mode" "SI")
3645 (set (attr "prefix_0f")
3646 ;; movsx is short decodable while cwtl is vector decoded.
3647 (if_then_else (and (eq_attr "cpu" "!k6")
3648 (eq_attr "alternative" "0"))
3650 (const_string "1")))
3652 (if_then_else (eq_attr "prefix_0f" "0")
3654 (const_string "1")))])
3656 (define_insn "extendqihi2"
3657 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3658 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3661 switch (get_attr_prefix_0f (insn))
3664 return "{cbtw|cbw}";
3666 return "movs{bw|x}\t{%1,%0|%0, %1}";
3669 [(set_attr "type" "imovx")
3670 (set_attr "mode" "HI")
3671 (set (attr "prefix_0f")
3672 ;; movsx is short decodable while cwtl is vector decoded.
3673 (if_then_else (and (eq_attr "cpu" "!k6")
3674 (eq_attr "alternative" "0"))
3676 (const_string "1")))
3678 (if_then_else (eq_attr "prefix_0f" "0")
3680 (const_string "1")))])
3682 (define_insn "extendqisi2"
3683 [(set (match_operand:SI 0 "register_operand" "=r")
3684 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3686 "movs{bl|x}\t{%1,%0|%0, %1}"
3687 [(set_attr "type" "imovx")
3688 (set_attr "mode" "SI")])
3690 (define_insn "*extendqisi2_zext"
3691 [(set (match_operand:DI 0 "register_operand" "=r")
3693 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3695 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3696 [(set_attr "type" "imovx")
3697 (set_attr "mode" "SI")])
3699 ;; Conversions between float and double.
3701 ;; These are all no-ops in the model used for the 80387. So just
3704 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3705 (define_insn "*dummy_extendsfdf2"
3706 [(set (match_operand:DF 0 "push_operand" "=<")
3707 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3712 [(set (match_operand:DF 0 "push_operand" "")
3713 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3715 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3716 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3719 [(set (match_operand:DF 0 "push_operand" "")
3720 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3722 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3723 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3725 (define_insn "*dummy_extendsfxf2"
3726 [(set (match_operand:XF 0 "push_operand" "=<")
3727 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3732 [(set (match_operand:XF 0 "push_operand" "")
3733 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3735 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3736 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3737 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3740 [(set (match_operand:XF 0 "push_operand" "")
3741 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3743 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3744 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3745 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3748 [(set (match_operand:XF 0 "push_operand" "")
3749 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3751 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3752 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3753 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3756 [(set (match_operand:XF 0 "push_operand" "")
3757 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3759 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3760 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3761 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3763 (define_expand "extendsfdf2"
3764 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3765 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3766 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3768 /* ??? Needed for compress_float_constant since all fp constants
3769 are LEGITIMATE_CONSTANT_P. */
3770 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3772 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3773 && standard_80387_constant_p (operands[1]) > 0)
3775 operands[1] = simplify_const_unary_operation
3776 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3777 emit_move_insn_1 (operands[0], operands[1]);
3780 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3784 (define_insn "*extendsfdf2_mixed"
3785 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3787 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3788 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3790 switch (which_alternative)
3793 return output_387_reg_move (insn, operands);
3796 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3797 return "fstp%z0\t%y0";
3799 return "fst%z0\t%y0";
3802 return "cvtss2sd\t{%1, %0|%0, %1}";
3808 [(set_attr "type" "fmov,fmov,ssecvt")
3809 (set_attr "mode" "SF,XF,DF")])
3811 (define_insn "*extendsfdf2_sse"
3812 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3813 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3814 "TARGET_SSE2 && TARGET_SSE_MATH"
3815 "cvtss2sd\t{%1, %0|%0, %1}"
3816 [(set_attr "type" "ssecvt")
3817 (set_attr "mode" "DF")])
3819 (define_insn "*extendsfdf2_i387"
3820 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3821 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3824 switch (which_alternative)
3827 return output_387_reg_move (insn, operands);
3830 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3831 return "fstp%z0\t%y0";
3833 return "fst%z0\t%y0";
3839 [(set_attr "type" "fmov")
3840 (set_attr "mode" "SF,XF")])
3842 (define_expand "extendsfxf2"
3843 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3844 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3847 /* ??? Needed for compress_float_constant since all fp constants
3848 are LEGITIMATE_CONSTANT_P. */
3849 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3851 if (standard_80387_constant_p (operands[1]) > 0)
3853 operands[1] = simplify_const_unary_operation
3854 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3855 emit_move_insn_1 (operands[0], operands[1]);
3858 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3862 (define_insn "*extendsfxf2_i387"
3863 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3864 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3867 switch (which_alternative)
3870 return output_387_reg_move (insn, operands);
3873 /* There is no non-popping store to memory for XFmode. So if
3874 we need one, follow the store with a load. */
3875 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876 return "fstp%z0\t%y0";
3878 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3884 [(set_attr "type" "fmov")
3885 (set_attr "mode" "SF,XF")])
3887 (define_expand "extenddfxf2"
3888 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3889 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3892 /* ??? Needed for compress_float_constant since all fp constants
3893 are LEGITIMATE_CONSTANT_P. */
3894 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3896 if (standard_80387_constant_p (operands[1]) > 0)
3898 operands[1] = simplify_const_unary_operation
3899 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3900 emit_move_insn_1 (operands[0], operands[1]);
3903 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3907 (define_insn "*extenddfxf2_i387"
3908 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3909 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3912 switch (which_alternative)
3915 return output_387_reg_move (insn, operands);
3918 /* There is no non-popping store to memory for XFmode. So if
3919 we need one, follow the store with a load. */
3920 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3923 return "fstp%z0\t%y0";
3929 [(set_attr "type" "fmov")
3930 (set_attr "mode" "DF,XF")])
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case. Otherwise this is just like a simple move
3935 ;; insn. So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3938 ;; Conversion from DFmode to SFmode.
3940 (define_expand "truncdfsf2"
3941 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3943 (match_operand:DF 1 "nonimmediate_operand" "")))]
3944 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3946 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3948 else if (flag_unsafe_math_optimizations)
3952 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3953 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3958 (define_expand "truncdfsf2_with_temp"
3959 [(parallel [(set (match_operand:SF 0 "" "")
3960 (float_truncate:SF (match_operand:DF 1 "" "")))
3961 (clobber (match_operand:SF 2 "" ""))])]
3964 (define_insn "*truncdfsf_fast_mixed"
3965 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
3967 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3968 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3970 switch (which_alternative)
3973 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974 return "fstp%z0\t%y0";
3976 return "fst%z0\t%y0";
3978 return output_387_reg_move (insn, operands);
3980 return "cvtsd2ss\t{%1, %0|%0, %1}";
3985 [(set_attr "type" "fmov,fmov,ssecvt")
3986 (set_attr "mode" "SF")])
3988 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3989 ;; because nothing we do here is unsafe.
3990 (define_insn "*truncdfsf_fast_sse"
3991 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3993 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3994 "TARGET_SSE2 && TARGET_SSE_MATH"
3995 "cvtsd2ss\t{%1, %0|%0, %1}"
3996 [(set_attr "type" "ssecvt")
3997 (set_attr "mode" "SF")])
3999 (define_insn "*truncdfsf_fast_i387"
4000 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4002 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4003 "TARGET_80387 && flag_unsafe_math_optimizations"
4004 "* return output_387_reg_move (insn, operands);"
4005 [(set_attr "type" "fmov")
4006 (set_attr "mode" "SF")])
4008 (define_insn "*truncdfsf_mixed"
4009 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4011 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4012 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4013 "TARGET_MIX_SSE_I387"
4015 switch (which_alternative)
4018 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4019 return "fstp%z0\t%y0";
4021 return "fst%z0\t%y0";
4025 return "cvtsd2ss\t{%1, %0|%0, %1}";
4030 [(set_attr "type" "fmov,multi,ssecvt")
4031 (set_attr "unit" "*,i387,*")
4032 (set_attr "mode" "SF")])
4034 (define_insn "*truncdfsf_i387"
4035 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4037 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4038 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4041 switch (which_alternative)
4044 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4045 return "fstp%z0\t%y0";
4047 return "fst%z0\t%y0";
4054 [(set_attr "type" "fmov,multi")
4055 (set_attr "unit" "*,i387")
4056 (set_attr "mode" "SF")])
4058 (define_insn "*truncdfsf2_i387_1"
4059 [(set (match_operand:SF 0 "memory_operand" "=m")
4061 (match_operand:DF 1 "register_operand" "f")))]
4063 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4064 && !TARGET_MIX_SSE_I387"
4066 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067 return "fstp%z0\t%y0";
4069 return "fst%z0\t%y0";
4071 [(set_attr "type" "fmov")
4072 (set_attr "mode" "SF")])
4075 [(set (match_operand:SF 0 "register_operand" "")
4077 (match_operand:DF 1 "fp_register_operand" "")))
4078 (clobber (match_operand 2 "" ""))]
4080 [(set (match_dup 2) (match_dup 1))
4081 (set (match_dup 0) (match_dup 2))]
4083 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4086 ;; Conversion from XFmode to SFmode.
4088 (define_expand "truncxfsf2"
4089 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4091 (match_operand:XF 1 "register_operand" "")))
4092 (clobber (match_dup 2))])]
4095 if (flag_unsafe_math_optimizations)
4097 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4098 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4099 if (reg != operands[0])
4100 emit_move_insn (operands[0], reg);
4104 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4107 (define_insn "*truncxfsf2_mixed"
4108 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4110 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4111 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4114 gcc_assert (!which_alternative);
4115 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4116 return "fstp%z0\t%y0";
4118 return "fst%z0\t%y0";
4120 [(set_attr "type" "fmov,multi,multi,multi")
4121 (set_attr "unit" "*,i387,i387,i387")
4122 (set_attr "mode" "SF")])
4124 (define_insn "truncxfsf2_i387_noop"
4125 [(set (match_operand:SF 0 "register_operand" "=f")
4126 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4127 "TARGET_80387 && flag_unsafe_math_optimizations"
4128 "* return output_387_reg_move (insn, operands);"
4129 [(set_attr "type" "fmov")
4130 (set_attr "mode" "SF")])
4132 (define_insn "*truncxfsf2_i387"
4133 [(set (match_operand:SF 0 "memory_operand" "=m")
4135 (match_operand:XF 1 "register_operand" "f")))]
4138 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4139 return "fstp%z0\t%y0";
4141 return "fst%z0\t%y0";
4143 [(set_attr "type" "fmov")
4144 (set_attr "mode" "SF")])
4147 [(set (match_operand:SF 0 "register_operand" "")
4149 (match_operand:XF 1 "register_operand" "")))
4150 (clobber (match_operand:SF 2 "memory_operand" ""))]
4151 "TARGET_80387 && reload_completed"
4152 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4153 (set (match_dup 0) (match_dup 2))]
4157 [(set (match_operand:SF 0 "memory_operand" "")
4159 (match_operand:XF 1 "register_operand" "")))
4160 (clobber (match_operand:SF 2 "memory_operand" ""))]
4162 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4165 ;; Conversion from XFmode to DFmode.
4167 (define_expand "truncxfdf2"
4168 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4170 (match_operand:XF 1 "register_operand" "")))
4171 (clobber (match_dup 2))])]
4174 if (flag_unsafe_math_optimizations)
4176 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4177 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4178 if (reg != operands[0])
4179 emit_move_insn (operands[0], reg);
4183 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4186 (define_insn "*truncxfdf2_mixed"
4187 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4189 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4190 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4193 gcc_assert (!which_alternative);
4194 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4195 return "fstp%z0\t%y0";
4197 return "fst%z0\t%y0";
4199 [(set_attr "type" "fmov,multi,multi,multi")
4200 (set_attr "unit" "*,i387,i387,i387")
4201 (set_attr "mode" "DF")])
4203 (define_insn "truncxfdf2_i387_noop"
4204 [(set (match_operand:DF 0 "register_operand" "=f")
4205 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4206 "TARGET_80387 && flag_unsafe_math_optimizations"
4207 "* return output_387_reg_move (insn, operands);"
4208 [(set_attr "type" "fmov")
4209 (set_attr "mode" "DF")])
4211 (define_insn "*truncxfdf2_i387"
4212 [(set (match_operand:DF 0 "memory_operand" "=m")
4214 (match_operand:XF 1 "register_operand" "f")))]
4217 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4218 return "fstp%z0\t%y0";
4220 return "fst%z0\t%y0";
4222 [(set_attr "type" "fmov")
4223 (set_attr "mode" "DF")])
4226 [(set (match_operand:DF 0 "register_operand" "")
4228 (match_operand:XF 1 "register_operand" "")))
4229 (clobber (match_operand:DF 2 "memory_operand" ""))]
4230 "TARGET_80387 && reload_completed"
4231 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4232 (set (match_dup 0) (match_dup 2))]
4236 [(set (match_operand:DF 0 "memory_operand" "")
4238 (match_operand:XF 1 "register_operand" "")))
4239 (clobber (match_operand:DF 2 "memory_operand" ""))]
4241 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4244 ;; Signed conversion to DImode.
4246 (define_expand "fix_truncxfdi2"
4247 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248 (fix:DI (match_operand:XF 1 "register_operand" "")))
4249 (clobber (reg:CC FLAGS_REG))])]
4254 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4259 (define_expand "fix_trunc<mode>di2"
4260 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4262 (clobber (reg:CC FLAGS_REG))])]
4263 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4266 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4268 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4271 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4273 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275 if (out != operands[0])
4276 emit_move_insn (operands[0], out);
4281 ;; Signed conversion to SImode.
4283 (define_expand "fix_truncxfsi2"
4284 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285 (fix:SI (match_operand:XF 1 "register_operand" "")))
4286 (clobber (reg:CC FLAGS_REG))])]
4291 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4296 (define_expand "fix_trunc<mode>si2"
4297 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4299 (clobber (reg:CC FLAGS_REG))])]
4300 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4303 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4305 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4308 if (SSE_FLOAT_MODE_P (<MODE>mode))
4310 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312 if (out != operands[0])
4313 emit_move_insn (operands[0], out);
4318 ;; Signed conversion to HImode.
4320 (define_expand "fix_trunc<mode>hi2"
4321 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323 (clobber (reg:CC FLAGS_REG))])]
4325 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4329 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4334 ;; Unsigned conversion to SImode.
4336 (define_expand "fixuns_trunc<mode>si2"
4337 [(set (match_operand:SI 0 "nonimmediate_operand" "")
4338 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))]
4339 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4340 && TARGET_KEEPS_VECTOR_ALIGNED_STACK && !optimize_size"
4342 ix86_expand_convert_uns_si_sse (operands[0], operands[1]);
4346 ;; Unsigned conversion to HImode.
4347 ;; Without these patterns, we'll try the unsigned SI conversion which
4348 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4350 (define_expand "fixuns_truncsfhi2"
4352 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4353 (set (match_operand:HI 0 "nonimmediate_operand" "")
4354 (subreg:HI (match_dup 2) 0))]
4356 "operands[2] = gen_reg_rtx (SImode);")
4358 (define_expand "fixuns_truncdfhi2"
4360 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4361 (set (match_operand:HI 0 "nonimmediate_operand" "")
4362 (subreg:HI (match_dup 2) 0))]
4364 "operands[2] = gen_reg_rtx (SImode);")
4366 ;; When SSE is available, it is always faster to use it!
4367 (define_insn "fix_truncsfdi_sse"
4368 [(set (match_operand:DI 0 "register_operand" "=r,r")
4369 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4370 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4371 "cvttss2si{q}\t{%1, %0|%0, %1}"
4372 [(set_attr "type" "sseicvt")
4373 (set_attr "mode" "SF")
4374 (set_attr "athlon_decode" "double,vector")
4375 (set_attr "amdfam10_decode" "double,double")])
4377 (define_insn "fix_truncdfdi_sse"
4378 [(set (match_operand:DI 0 "register_operand" "=r,r")
4379 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4380 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4381 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4382 [(set_attr "type" "sseicvt")
4383 (set_attr "mode" "DF")
4384 (set_attr "athlon_decode" "double,vector")
4385 (set_attr "amdfam10_decode" "double,double")])
4387 (define_insn "fix_truncsfsi_sse"
4388 [(set (match_operand:SI 0 "register_operand" "=r,r")
4389 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4390 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4391 "cvttss2si\t{%1, %0|%0, %1}"
4392 [(set_attr "type" "sseicvt")
4393 (set_attr "mode" "DF")
4394 (set_attr "athlon_decode" "double,vector")
4395 (set_attr "amdfam10_decode" "double,double")])
4397 (define_insn "fix_truncdfsi_sse"
4398 [(set (match_operand:SI 0 "register_operand" "=r,r")
4399 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4400 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4401 "cvttsd2si\t{%1, %0|%0, %1}"
4402 [(set_attr "type" "sseicvt")
4403 (set_attr "mode" "DF")
4404 (set_attr "athlon_decode" "double,vector")
4405 (set_attr "amdfam10_decode" "double,double")])
4407 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4409 [(set (match_operand:DF 0 "register_operand" "")
4410 (match_operand:DF 1 "memory_operand" ""))
4411 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4412 (fix:SSEMODEI24 (match_dup 0)))]
4414 && peep2_reg_dead_p (2, operands[0])"
4415 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4419 [(set (match_operand:SF 0 "register_operand" "")
4420 (match_operand:SF 1 "memory_operand" ""))
4421 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4422 (fix:SSEMODEI24 (match_dup 0)))]
4424 && peep2_reg_dead_p (2, operands[0])"
4425 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4428 ;; Avoid vector decoded forms of the instruction.
4430 [(match_scratch:DF 2 "Y")
4431 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4432 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4433 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4434 [(set (match_dup 2) (match_dup 1))
4435 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4439 [(match_scratch:SF 2 "x")
4440 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4441 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4442 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4443 [(set (match_dup 2) (match_dup 1))
4444 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4447 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4448 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4449 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4451 && FLOAT_MODE_P (GET_MODE (operands[1]))
4452 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4453 && (TARGET_64BIT || <MODE>mode != DImode))
4455 && !(reload_completed || reload_in_progress)"
4460 if (memory_operand (operands[0], VOIDmode))
4461 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4464 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4465 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4471 [(set_attr "type" "fisttp")
4472 (set_attr "mode" "<MODE>")])
4474 (define_insn "fix_trunc<mode>_i387_fisttp"
4475 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4476 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4477 (clobber (match_scratch:XF 2 "=&1f"))]
4479 && FLOAT_MODE_P (GET_MODE (operands[1]))
4480 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4481 && (TARGET_64BIT || <MODE>mode != DImode))
4482 && TARGET_SSE_MATH)"
4483 "* return output_fix_trunc (insn, operands, 1);"
4484 [(set_attr "type" "fisttp")
4485 (set_attr "mode" "<MODE>")])
4487 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4488 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4489 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4490 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4491 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4493 && FLOAT_MODE_P (GET_MODE (operands[1]))
4494 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && (TARGET_64BIT || <MODE>mode != DImode))
4496 && TARGET_SSE_MATH)"
4498 [(set_attr "type" "fisttp")
4499 (set_attr "mode" "<MODE>")])
4502 [(set (match_operand:X87MODEI 0 "register_operand" "")
4503 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4504 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4505 (clobber (match_scratch 3 ""))]
4507 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4508 (clobber (match_dup 3))])
4509 (set (match_dup 0) (match_dup 2))]
4513 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4514 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4515 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4516 (clobber (match_scratch 3 ""))]
4518 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4519 (clobber (match_dup 3))])]
4522 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4523 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4524 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4525 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4526 ;; function in i386.c.
4527 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4528 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4529 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4530 (clobber (reg:CC FLAGS_REG))]
4531 "TARGET_80387 && !TARGET_FISTTP
4532 && FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && (TARGET_64BIT || <MODE>mode != DImode))
4535 && !(reload_completed || reload_in_progress)"
4540 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4542 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4543 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4544 if (memory_operand (operands[0], VOIDmode))
4545 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4546 operands[2], operands[3]));
4549 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4550 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4551 operands[2], operands[3],
4556 [(set_attr "type" "fistp")
4557 (set_attr "i387_cw" "trunc")
4558 (set_attr "mode" "<MODE>")])
4560 (define_insn "fix_truncdi_i387"
4561 [(set (match_operand:DI 0 "memory_operand" "=m")
4562 (fix:DI (match_operand 1 "register_operand" "f")))
4563 (use (match_operand:HI 2 "memory_operand" "m"))
4564 (use (match_operand:HI 3 "memory_operand" "m"))
4565 (clobber (match_scratch:XF 4 "=&1f"))]
4566 "TARGET_80387 && !TARGET_FISTTP
4567 && FLOAT_MODE_P (GET_MODE (operands[1]))
4568 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4569 "* return output_fix_trunc (insn, operands, 0);"
4570 [(set_attr "type" "fistp")
4571 (set_attr "i387_cw" "trunc")
4572 (set_attr "mode" "DI")])
4574 (define_insn "fix_truncdi_i387_with_temp"
4575 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4576 (fix:DI (match_operand 1 "register_operand" "f,f")))
4577 (use (match_operand:HI 2 "memory_operand" "m,m"))
4578 (use (match_operand:HI 3 "memory_operand" "m,m"))
4579 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4580 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4581 "TARGET_80387 && !TARGET_FISTTP
4582 && FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4585 [(set_attr "type" "fistp")
4586 (set_attr "i387_cw" "trunc")
4587 (set_attr "mode" "DI")])
4590 [(set (match_operand:DI 0 "register_operand" "")
4591 (fix:DI (match_operand 1 "register_operand" "")))
4592 (use (match_operand:HI 2 "memory_operand" ""))
4593 (use (match_operand:HI 3 "memory_operand" ""))
4594 (clobber (match_operand:DI 4 "memory_operand" ""))
4595 (clobber (match_scratch 5 ""))]
4597 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4600 (clobber (match_dup 5))])
4601 (set (match_dup 0) (match_dup 4))]
4605 [(set (match_operand:DI 0 "memory_operand" "")
4606 (fix:DI (match_operand 1 "register_operand" "")))
4607 (use (match_operand:HI 2 "memory_operand" ""))
4608 (use (match_operand:HI 3 "memory_operand" ""))
4609 (clobber (match_operand:DI 4 "memory_operand" ""))
4610 (clobber (match_scratch 5 ""))]
4612 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4615 (clobber (match_dup 5))])]
4618 (define_insn "fix_trunc<mode>_i387"
4619 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4620 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4621 (use (match_operand:HI 2 "memory_operand" "m"))
4622 (use (match_operand:HI 3 "memory_operand" "m"))]
4623 "TARGET_80387 && !TARGET_FISTTP
4624 && FLOAT_MODE_P (GET_MODE (operands[1]))
4625 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4626 "* return output_fix_trunc (insn, operands, 0);"
4627 [(set_attr "type" "fistp")
4628 (set_attr "i387_cw" "trunc")
4629 (set_attr "mode" "<MODE>")])
4631 (define_insn "fix_trunc<mode>_i387_with_temp"
4632 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4633 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4634 (use (match_operand:HI 2 "memory_operand" "m,m"))
4635 (use (match_operand:HI 3 "memory_operand" "m,m"))
4636 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4637 "TARGET_80387 && !TARGET_FISTTP
4638 && FLOAT_MODE_P (GET_MODE (operands[1]))
4639 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4641 [(set_attr "type" "fistp")
4642 (set_attr "i387_cw" "trunc")
4643 (set_attr "mode" "<MODE>")])
4646 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4647 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4648 (use (match_operand:HI 2 "memory_operand" ""))
4649 (use (match_operand:HI 3 "memory_operand" ""))
4650 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4652 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4654 (use (match_dup 3))])
4655 (set (match_dup 0) (match_dup 4))]
4659 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4660 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4661 (use (match_operand:HI 2 "memory_operand" ""))
4662 (use (match_operand:HI 3 "memory_operand" ""))
4663 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4665 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4667 (use (match_dup 3))])]
4670 (define_insn "x86_fnstcw_1"
4671 [(set (match_operand:HI 0 "memory_operand" "=m")
4672 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4675 [(set_attr "length" "2")
4676 (set_attr "mode" "HI")
4677 (set_attr "unit" "i387")])
4679 (define_insn "x86_fldcw_1"
4680 [(set (reg:HI FPCR_REG)
4681 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4684 [(set_attr "length" "2")
4685 (set_attr "mode" "HI")
4686 (set_attr "unit" "i387")
4687 (set_attr "athlon_decode" "vector")
4688 (set_attr "amdfam10_decode" "vector")])
4690 ;; Conversion between fixed point and floating point.
4692 ;; Even though we only accept memory inputs, the backend _really_
4693 ;; wants to be able to do this between registers.
4695 (define_expand "floathisf2"
4696 [(set (match_operand:SF 0 "register_operand" "")
4697 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4698 "TARGET_80387 || TARGET_SSE_MATH"
4700 if (TARGET_SSE_MATH)
4702 emit_insn (gen_floatsisf2 (operands[0],
4703 convert_to_mode (SImode, operands[1], 0)));
4708 (define_insn "*floathisf2_i387"
4709 [(set (match_operand:SF 0 "register_operand" "=f,f")
4710 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4711 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4715 [(set_attr "type" "fmov,multi")
4716 (set_attr "mode" "SF")
4717 (set_attr "unit" "*,i387")
4718 (set_attr "fp_int_src" "true")])
4720 (define_expand "floatsisf2"
4721 [(set (match_operand:SF 0 "register_operand" "")
4722 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4723 "TARGET_80387 || TARGET_SSE_MATH"
4726 (define_insn "*floatsisf2_mixed"
4727 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4728 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4729 "TARGET_MIX_SSE_I387"
4733 cvtsi2ss\t{%1, %0|%0, %1}
4734 cvtsi2ss\t{%1, %0|%0, %1}"
4735 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4736 (set_attr "mode" "SF")
4737 (set_attr "unit" "*,i387,*,*")
4738 (set_attr "athlon_decode" "*,*,vector,double")
4739 (set_attr "amdfam10_decode" "*,*,vector,double")
4740 (set_attr "fp_int_src" "true")])
4742 (define_insn "*floatsisf2_sse"
4743 [(set (match_operand:SF 0 "register_operand" "=x,x")
4744 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4746 "cvtsi2ss\t{%1, %0|%0, %1}"
4747 [(set_attr "type" "sseicvt")
4748 (set_attr "mode" "SF")
4749 (set_attr "athlon_decode" "vector,double")
4750 (set_attr "amdfam10_decode" "vector,double")
4751 (set_attr "fp_int_src" "true")])
4753 (define_insn "*floatsisf2_i387"
4754 [(set (match_operand:SF 0 "register_operand" "=f,f")
4755 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4760 [(set_attr "type" "fmov,multi")
4761 (set_attr "mode" "SF")
4762 (set_attr "unit" "*,i387")
4763 (set_attr "fp_int_src" "true")])
4765 (define_expand "floatdisf2"
4766 [(set (match_operand:SF 0 "register_operand" "")
4767 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4768 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4771 (define_insn "*floatdisf2_mixed"
4772 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4773 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4774 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4778 cvtsi2ss{q}\t{%1, %0|%0, %1}
4779 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4780 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4781 (set_attr "mode" "SF")
4782 (set_attr "unit" "*,i387,*,*")
4783 (set_attr "athlon_decode" "*,*,vector,double")
4784 (set_attr "amdfam10_decode" "*,*,vector,double")
4785 (set_attr "fp_int_src" "true")])
4787 (define_insn "*floatdisf2_sse"
4788 [(set (match_operand:SF 0 "register_operand" "=x,x")
4789 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4790 "TARGET_64BIT && TARGET_SSE_MATH"
4791 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4792 [(set_attr "type" "sseicvt")
4793 (set_attr "mode" "SF")
4794 (set_attr "athlon_decode" "vector,double")
4795 (set_attr "amdfam10_decode" "vector,double")
4796 (set_attr "fp_int_src" "true")])
4798 (define_insn "*floatdisf2_i387"
4799 [(set (match_operand:SF 0 "register_operand" "=f,f")
4800 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4805 [(set_attr "type" "fmov,multi")
4806 (set_attr "mode" "SF")
4807 (set_attr "unit" "*,i387")
4808 (set_attr "fp_int_src" "true")])
4810 (define_expand "floathidf2"
4811 [(set (match_operand:DF 0 "register_operand" "")
4812 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4813 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4815 if (TARGET_SSE2 && TARGET_SSE_MATH)
4817 emit_insn (gen_floatsidf2 (operands[0],
4818 convert_to_mode (SImode, operands[1], 0)));
4823 (define_insn "*floathidf2_i387"
4824 [(set (match_operand:DF 0 "register_operand" "=f,f")
4825 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4826 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4830 [(set_attr "type" "fmov,multi")
4831 (set_attr "mode" "DF")
4832 (set_attr "unit" "*,i387")
4833 (set_attr "fp_int_src" "true")])
4835 (define_expand "floatsidf2"
4836 [(set (match_operand:DF 0 "register_operand" "")
4837 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4838 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4841 (define_insn "*floatsidf2_mixed"
4842 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4843 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4844 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4848 cvtsi2sd\t{%1, %0|%0, %1}
4849 cvtsi2sd\t{%1, %0|%0, %1}"
4850 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4851 (set_attr "mode" "DF")
4852 (set_attr "unit" "*,i387,*,*")
4853 (set_attr "athlon_decode" "*,*,double,direct")
4854 (set_attr "amdfam10_decode" "*,*,vector,double")
4855 (set_attr "fp_int_src" "true")])
4857 (define_insn "*floatsidf2_sse"
4858 [(set (match_operand:DF 0 "register_operand" "=x,x")
4859 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4860 "TARGET_SSE2 && TARGET_SSE_MATH"
4861 "cvtsi2sd\t{%1, %0|%0, %1}"
4862 [(set_attr "type" "sseicvt")
4863 (set_attr "mode" "DF")
4864 (set_attr "athlon_decode" "double,direct")
4865 (set_attr "amdfam10_decode" "vector,double")
4866 (set_attr "fp_int_src" "true")])
4868 (define_insn "*floatsidf2_i387"
4869 [(set (match_operand:DF 0 "register_operand" "=f,f")
4870 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4875 [(set_attr "type" "fmov,multi")
4876 (set_attr "mode" "DF")
4877 (set_attr "unit" "*,i387")
4878 (set_attr "fp_int_src" "true")])
4880 (define_expand "floatdidf2"
4881 [(set (match_operand:DF 0 "register_operand" "")
4882 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4883 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4885 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4887 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4892 (define_insn "*floatdidf2_mixed"
4893 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4894 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4895 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4899 cvtsi2sd{q}\t{%1, %0|%0, %1}
4900 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4901 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4902 (set_attr "mode" "DF")
4903 (set_attr "unit" "*,i387,*,*")
4904 (set_attr "athlon_decode" "*,*,double,direct")
4905 (set_attr "amdfam10_decode" "*,*,vector,double")
4906 (set_attr "fp_int_src" "true")])
4908 (define_insn "*floatdidf2_sse"
4909 [(set (match_operand:DF 0 "register_operand" "=x,x")
4910 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4911 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4912 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4913 [(set_attr "type" "sseicvt")
4914 (set_attr "mode" "DF")
4915 (set_attr "athlon_decode" "double,direct")
4916 (set_attr "amdfam10_decode" "vector,double")
4917 (set_attr "fp_int_src" "true")])
4919 (define_insn "*floatdidf2_i387"
4920 [(set (match_operand:DF 0 "register_operand" "=f,f")
4921 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4926 [(set_attr "type" "fmov,multi")
4927 (set_attr "mode" "DF")
4928 (set_attr "unit" "*,i387")
4929 (set_attr "fp_int_src" "true")])
4931 (define_insn "floathixf2"
4932 [(set (match_operand:XF 0 "register_operand" "=f,f")
4933 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4938 [(set_attr "type" "fmov,multi")
4939 (set_attr "mode" "XF")
4940 (set_attr "unit" "*,i387")
4941 (set_attr "fp_int_src" "true")])
4943 (define_insn "floatsixf2"
4944 [(set (match_operand:XF 0 "register_operand" "=f,f")
4945 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4950 [(set_attr "type" "fmov,multi")
4951 (set_attr "mode" "XF")
4952 (set_attr "unit" "*,i387")
4953 (set_attr "fp_int_src" "true")])
4955 (define_insn "floatdixf2"
4956 [(set (match_operand:XF 0 "register_operand" "=f,f")
4957 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4962 [(set_attr "type" "fmov,multi")
4963 (set_attr "mode" "XF")
4964 (set_attr "unit" "*,i387")
4965 (set_attr "fp_int_src" "true")])
4967 ;; %%% Kill these when reload knows how to do it.
4969 [(set (match_operand 0 "fp_register_operand" "")
4970 (float (match_operand 1 "register_operand" "")))]
4973 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4976 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4977 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4978 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4979 ix86_free_from_memory (GET_MODE (operands[1]));
4983 (define_expand "floatunssisf2"
4984 [(use (match_operand:SF 0 "register_operand" ""))
4985 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4988 if (TARGET_SSE_MATH && TARGET_SSE2)
4989 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
4991 x86_emit_floatuns (operands);
4995 (define_expand "floatunssidf2"
4996 [(use (match_operand:DF 0 "register_operand" ""))
4997 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
4998 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
4999 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5001 (define_expand "floatunsdisf2"
5002 [(use (match_operand:SF 0 "register_operand" ""))
5003 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5004 "TARGET_64BIT && TARGET_SSE_MATH"
5005 "x86_emit_floatuns (operands); DONE;")
5007 (define_expand "floatunsdidf2"
5008 [(use (match_operand:DF 0 "register_operand" ""))
5009 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5010 "TARGET_SSE_MATH && TARGET_SSE2
5011 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5014 x86_emit_floatuns (operands);
5016 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5020 ;; SSE extract/set expanders
5025 ;; %%% splits for addditi3
5027 (define_expand "addti3"
5028 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5029 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5030 (match_operand:TI 2 "x86_64_general_operand" "")))
5031 (clobber (reg:CC FLAGS_REG))]
5033 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5035 (define_insn "*addti3_1"
5036 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5037 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5038 (match_operand:TI 2 "general_operand" "roiF,riF")))
5039 (clobber (reg:CC FLAGS_REG))]
5040 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5044 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5045 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5046 (match_operand:TI 2 "general_operand" "")))
5047 (clobber (reg:CC FLAGS_REG))]
5048 "TARGET_64BIT && reload_completed"
5049 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5051 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5052 (parallel [(set (match_dup 3)
5053 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5056 (clobber (reg:CC FLAGS_REG))])]
5057 "split_ti (operands+0, 1, operands+0, operands+3);
5058 split_ti (operands+1, 1, operands+1, operands+4);
5059 split_ti (operands+2, 1, operands+2, operands+5);")
5061 ;; %%% splits for addsidi3
5062 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5063 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5064 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5066 (define_expand "adddi3"
5067 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5068 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5069 (match_operand:DI 2 "x86_64_general_operand" "")))
5070 (clobber (reg:CC FLAGS_REG))]
5072 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5074 (define_insn "*adddi3_1"
5075 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5076 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5077 (match_operand:DI 2 "general_operand" "roiF,riF")))
5078 (clobber (reg:CC FLAGS_REG))]
5079 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5083 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5084 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5085 (match_operand:DI 2 "general_operand" "")))
5086 (clobber (reg:CC FLAGS_REG))]
5087 "!TARGET_64BIT && reload_completed"
5088 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5090 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5091 (parallel [(set (match_dup 3)
5092 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5095 (clobber (reg:CC FLAGS_REG))])]
5096 "split_di (operands+0, 1, operands+0, operands+3);
5097 split_di (operands+1, 1, operands+1, operands+4);
5098 split_di (operands+2, 1, operands+2, operands+5);")
5100 (define_insn "adddi3_carry_rex64"
5101 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5102 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5103 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5104 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5105 (clobber (reg:CC FLAGS_REG))]
5106 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5107 "adc{q}\t{%2, %0|%0, %2}"
5108 [(set_attr "type" "alu")
5109 (set_attr "pent_pair" "pu")
5110 (set_attr "mode" "DI")])
5112 (define_insn "*adddi3_cc_rex64"
5113 [(set (reg:CC FLAGS_REG)
5114 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5115 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5117 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5118 (plus:DI (match_dup 1) (match_dup 2)))]
5119 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120 "add{q}\t{%2, %0|%0, %2}"
5121 [(set_attr "type" "alu")
5122 (set_attr "mode" "DI")])
5124 (define_insn "addqi3_carry"
5125 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5126 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5127 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5128 (match_operand:QI 2 "general_operand" "qi,qm")))
5129 (clobber (reg:CC FLAGS_REG))]
5130 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5131 "adc{b}\t{%2, %0|%0, %2}"
5132 [(set_attr "type" "alu")
5133 (set_attr "pent_pair" "pu")
5134 (set_attr "mode" "QI")])
5136 (define_insn "addhi3_carry"
5137 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5138 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5139 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5140 (match_operand:HI 2 "general_operand" "ri,rm")))
5141 (clobber (reg:CC FLAGS_REG))]
5142 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5143 "adc{w}\t{%2, %0|%0, %2}"
5144 [(set_attr "type" "alu")
5145 (set_attr "pent_pair" "pu")
5146 (set_attr "mode" "HI")])
5148 (define_insn "addsi3_carry"
5149 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5150 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5151 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5152 (match_operand:SI 2 "general_operand" "ri,rm")))
5153 (clobber (reg:CC FLAGS_REG))]
5154 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5155 "adc{l}\t{%2, %0|%0, %2}"
5156 [(set_attr "type" "alu")
5157 (set_attr "pent_pair" "pu")
5158 (set_attr "mode" "SI")])
5160 (define_insn "*addsi3_carry_zext"
5161 [(set (match_operand:DI 0 "register_operand" "=r")
5163 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5164 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5165 (match_operand:SI 2 "general_operand" "rim"))))
5166 (clobber (reg:CC FLAGS_REG))]
5167 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5168 "adc{l}\t{%2, %k0|%k0, %2}"
5169 [(set_attr "type" "alu")
5170 (set_attr "pent_pair" "pu")
5171 (set_attr "mode" "SI")])
5173 (define_insn "*addsi3_cc"
5174 [(set (reg:CC FLAGS_REG)
5175 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5176 (match_operand:SI 2 "general_operand" "ri,rm")]
5178 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5179 (plus:SI (match_dup 1) (match_dup 2)))]
5180 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5181 "add{l}\t{%2, %0|%0, %2}"
5182 [(set_attr "type" "alu")
5183 (set_attr "mode" "SI")])
5185 (define_insn "addqi3_cc"
5186 [(set (reg:CC FLAGS_REG)
5187 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5188 (match_operand:QI 2 "general_operand" "qi,qm")]
5190 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5191 (plus:QI (match_dup 1) (match_dup 2)))]
5192 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5193 "add{b}\t{%2, %0|%0, %2}"
5194 [(set_attr "type" "alu")
5195 (set_attr "mode" "QI")])
5197 (define_expand "addsi3"
5198 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5199 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5200 (match_operand:SI 2 "general_operand" "")))
5201 (clobber (reg:CC FLAGS_REG))])]
5203 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5205 (define_insn "*lea_1"
5206 [(set (match_operand:SI 0 "register_operand" "=r")
5207 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5209 "lea{l}\t{%a1, %0|%0, %a1}"
5210 [(set_attr "type" "lea")
5211 (set_attr "mode" "SI")])
5213 (define_insn "*lea_1_rex64"
5214 [(set (match_operand:SI 0 "register_operand" "=r")
5215 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5217 "lea{l}\t{%a1, %0|%0, %a1}"
5218 [(set_attr "type" "lea")
5219 (set_attr "mode" "SI")])
5221 (define_insn "*lea_1_zext"
5222 [(set (match_operand:DI 0 "register_operand" "=r")
5224 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5226 "lea{l}\t{%a1, %k0|%k0, %a1}"
5227 [(set_attr "type" "lea")
5228 (set_attr "mode" "SI")])
5230 (define_insn "*lea_2_rex64"
5231 [(set (match_operand:DI 0 "register_operand" "=r")
5232 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5234 "lea{q}\t{%a1, %0|%0, %a1}"
5235 [(set_attr "type" "lea")
5236 (set_attr "mode" "DI")])
5238 ;; The lea patterns for non-Pmodes needs to be matched by several
5239 ;; insns converted to real lea by splitters.
5241 (define_insn_and_split "*lea_general_1"
5242 [(set (match_operand 0 "register_operand" "=r")
5243 (plus (plus (match_operand 1 "index_register_operand" "l")
5244 (match_operand 2 "register_operand" "r"))
5245 (match_operand 3 "immediate_operand" "i")))]
5246 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5247 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5248 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5249 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5250 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5251 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5252 || GET_MODE (operands[3]) == VOIDmode)"
5254 "&& reload_completed"
5258 operands[0] = gen_lowpart (SImode, operands[0]);
5259 operands[1] = gen_lowpart (Pmode, operands[1]);
5260 operands[2] = gen_lowpart (Pmode, operands[2]);
5261 operands[3] = gen_lowpart (Pmode, operands[3]);
5262 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5264 if (Pmode != SImode)
5265 pat = gen_rtx_SUBREG (SImode, pat, 0);
5266 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5269 [(set_attr "type" "lea")
5270 (set_attr "mode" "SI")])
5272 (define_insn_and_split "*lea_general_1_zext"
5273 [(set (match_operand:DI 0 "register_operand" "=r")
5275 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5276 (match_operand:SI 2 "register_operand" "r"))
5277 (match_operand:SI 3 "immediate_operand" "i"))))]
5280 "&& reload_completed"
5282 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5284 (match_dup 3)) 0)))]
5286 operands[1] = gen_lowpart (Pmode, operands[1]);
5287 operands[2] = gen_lowpart (Pmode, operands[2]);
5288 operands[3] = gen_lowpart (Pmode, operands[3]);
5290 [(set_attr "type" "lea")
5291 (set_attr "mode" "SI")])
5293 (define_insn_and_split "*lea_general_2"
5294 [(set (match_operand 0 "register_operand" "=r")
5295 (plus (mult (match_operand 1 "index_register_operand" "l")
5296 (match_operand 2 "const248_operand" "i"))
5297 (match_operand 3 "nonmemory_operand" "ri")))]
5298 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5299 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5300 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5301 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5302 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5303 || GET_MODE (operands[3]) == VOIDmode)"
5305 "&& reload_completed"
5309 operands[0] = gen_lowpart (SImode, operands[0]);
5310 operands[1] = gen_lowpart (Pmode, operands[1]);
5311 operands[3] = gen_lowpart (Pmode, operands[3]);
5312 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5314 if (Pmode != SImode)
5315 pat = gen_rtx_SUBREG (SImode, pat, 0);
5316 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5319 [(set_attr "type" "lea")
5320 (set_attr "mode" "SI")])
5322 (define_insn_and_split "*lea_general_2_zext"
5323 [(set (match_operand:DI 0 "register_operand" "=r")
5325 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5326 (match_operand:SI 2 "const248_operand" "n"))
5327 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5330 "&& reload_completed"
5332 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5334 (match_dup 3)) 0)))]
5336 operands[1] = gen_lowpart (Pmode, operands[1]);
5337 operands[3] = gen_lowpart (Pmode, operands[3]);
5339 [(set_attr "type" "lea")
5340 (set_attr "mode" "SI")])
5342 (define_insn_and_split "*lea_general_3"
5343 [(set (match_operand 0 "register_operand" "=r")
5344 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5345 (match_operand 2 "const248_operand" "i"))
5346 (match_operand 3 "register_operand" "r"))
5347 (match_operand 4 "immediate_operand" "i")))]
5348 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5349 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5350 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5351 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5352 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5354 "&& reload_completed"
5358 operands[0] = gen_lowpart (SImode, operands[0]);
5359 operands[1] = gen_lowpart (Pmode, operands[1]);
5360 operands[3] = gen_lowpart (Pmode, operands[3]);
5361 operands[4] = gen_lowpart (Pmode, operands[4]);
5362 pat = gen_rtx_PLUS (Pmode,
5363 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5367 if (Pmode != SImode)
5368 pat = gen_rtx_SUBREG (SImode, pat, 0);
5369 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5372 [(set_attr "type" "lea")
5373 (set_attr "mode" "SI")])
5375 (define_insn_and_split "*lea_general_3_zext"
5376 [(set (match_operand:DI 0 "register_operand" "=r")
5378 (plus:SI (plus:SI (mult:SI
5379 (match_operand:SI 1 "index_register_operand" "l")
5380 (match_operand:SI 2 "const248_operand" "n"))
5381 (match_operand:SI 3 "register_operand" "r"))
5382 (match_operand:SI 4 "immediate_operand" "i"))))]
5385 "&& reload_completed"
5387 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5390 (match_dup 4)) 0)))]
5392 operands[1] = gen_lowpart (Pmode, operands[1]);
5393 operands[3] = gen_lowpart (Pmode, operands[3]);
5394 operands[4] = gen_lowpart (Pmode, operands[4]);
5396 [(set_attr "type" "lea")
5397 (set_attr "mode" "SI")])
5399 (define_insn "*adddi_1_rex64"
5400 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5401 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5402 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5403 (clobber (reg:CC FLAGS_REG))]
5404 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5406 switch (get_attr_type (insn))
5409 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5410 return "lea{q}\t{%a2, %0|%0, %a2}";
5413 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5414 if (operands[2] == const1_rtx)
5415 return "inc{q}\t%0";
5418 gcc_assert (operands[2] == constm1_rtx);
5419 return "dec{q}\t%0";
5423 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5425 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5426 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5427 if (CONST_INT_P (operands[2])
5428 /* Avoid overflows. */
5429 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5430 && (INTVAL (operands[2]) == 128
5431 || (INTVAL (operands[2]) < 0
5432 && INTVAL (operands[2]) != -128)))
5434 operands[2] = GEN_INT (-INTVAL (operands[2]));
5435 return "sub{q}\t{%2, %0|%0, %2}";
5437 return "add{q}\t{%2, %0|%0, %2}";
5441 (cond [(eq_attr "alternative" "2")
5442 (const_string "lea")
5443 ; Current assemblers are broken and do not allow @GOTOFF in
5444 ; ought but a memory context.
5445 (match_operand:DI 2 "pic_symbolic_operand" "")
5446 (const_string "lea")
5447 (match_operand:DI 2 "incdec_operand" "")
5448 (const_string "incdec")
5450 (const_string "alu")))
5451 (set_attr "mode" "DI")])
5453 ;; Convert lea to the lea pattern to avoid flags dependency.
5455 [(set (match_operand:DI 0 "register_operand" "")
5456 (plus:DI (match_operand:DI 1 "register_operand" "")
5457 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5458 (clobber (reg:CC FLAGS_REG))]
5459 "TARGET_64BIT && reload_completed
5460 && true_regnum (operands[0]) != true_regnum (operands[1])"
5462 (plus:DI (match_dup 1)
5466 (define_insn "*adddi_2_rex64"
5467 [(set (reg FLAGS_REG)
5469 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5470 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5472 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5473 (plus:DI (match_dup 1) (match_dup 2)))]
5474 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5475 && ix86_binary_operator_ok (PLUS, DImode, operands)
5476 /* Current assemblers are broken and do not allow @GOTOFF in
5477 ought but a memory context. */
5478 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5480 switch (get_attr_type (insn))
5483 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5484 if (operands[2] == const1_rtx)
5485 return "inc{q}\t%0";
5488 gcc_assert (operands[2] == constm1_rtx);
5489 return "dec{q}\t%0";
5493 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5494 /* ???? We ought to handle there the 32bit case too
5495 - do we need new constraint? */
5496 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5497 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5498 if (CONST_INT_P (operands[2])
5499 /* Avoid overflows. */
5500 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5501 && (INTVAL (operands[2]) == 128
5502 || (INTVAL (operands[2]) < 0
5503 && INTVAL (operands[2]) != -128)))
5505 operands[2] = GEN_INT (-INTVAL (operands[2]));
5506 return "sub{q}\t{%2, %0|%0, %2}";
5508 return "add{q}\t{%2, %0|%0, %2}";
5512 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5513 (const_string "incdec")
5514 (const_string "alu")))
5515 (set_attr "mode" "DI")])
5517 (define_insn "*adddi_3_rex64"
5518 [(set (reg FLAGS_REG)
5519 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5520 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5521 (clobber (match_scratch:DI 0 "=r"))]
5523 && ix86_match_ccmode (insn, CCZmode)
5524 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5525 /* Current assemblers are broken and do not allow @GOTOFF in
5526 ought but a memory context. */
5527 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5529 switch (get_attr_type (insn))
5532 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5533 if (operands[2] == const1_rtx)
5534 return "inc{q}\t%0";
5537 gcc_assert (operands[2] == constm1_rtx);
5538 return "dec{q}\t%0";
5542 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5543 /* ???? We ought to handle there the 32bit case too
5544 - do we need new constraint? */
5545 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5546 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5547 if (CONST_INT_P (operands[2])
5548 /* Avoid overflows. */
5549 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5550 && (INTVAL (operands[2]) == 128
5551 || (INTVAL (operands[2]) < 0
5552 && INTVAL (operands[2]) != -128)))
5554 operands[2] = GEN_INT (-INTVAL (operands[2]));
5555 return "sub{q}\t{%2, %0|%0, %2}";
5557 return "add{q}\t{%2, %0|%0, %2}";
5561 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5562 (const_string "incdec")
5563 (const_string "alu")))
5564 (set_attr "mode" "DI")])
5566 ; For comparisons against 1, -1 and 128, we may generate better code
5567 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5568 ; is matched then. We can't accept general immediate, because for
5569 ; case of overflows, the result is messed up.
5570 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5572 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5573 ; only for comparisons not depending on it.
5574 (define_insn "*adddi_4_rex64"
5575 [(set (reg FLAGS_REG)
5576 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5577 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5578 (clobber (match_scratch:DI 0 "=rm"))]
5580 && ix86_match_ccmode (insn, CCGCmode)"
5582 switch (get_attr_type (insn))
5585 if (operands[2] == constm1_rtx)
5586 return "inc{q}\t%0";
5589 gcc_assert (operands[2] == const1_rtx);
5590 return "dec{q}\t%0";
5594 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5595 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5596 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5597 if ((INTVAL (operands[2]) == -128
5598 || (INTVAL (operands[2]) > 0
5599 && INTVAL (operands[2]) != 128))
5600 /* Avoid overflows. */
5601 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5602 return "sub{q}\t{%2, %0|%0, %2}";
5603 operands[2] = GEN_INT (-INTVAL (operands[2]));
5604 return "add{q}\t{%2, %0|%0, %2}";
5608 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5609 (const_string "incdec")
5610 (const_string "alu")))
5611 (set_attr "mode" "DI")])
5613 (define_insn "*adddi_5_rex64"
5614 [(set (reg FLAGS_REG)
5616 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5617 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5619 (clobber (match_scratch:DI 0 "=r"))]
5621 && ix86_match_ccmode (insn, CCGOCmode)
5622 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5623 /* Current assemblers are broken and do not allow @GOTOFF in
5624 ought but a memory context. */
5625 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5627 switch (get_attr_type (insn))
5630 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5631 if (operands[2] == const1_rtx)
5632 return "inc{q}\t%0";
5635 gcc_assert (operands[2] == constm1_rtx);
5636 return "dec{q}\t%0";
5640 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5642 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5643 if (CONST_INT_P (operands[2])
5644 /* Avoid overflows. */
5645 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5646 && (INTVAL (operands[2]) == 128
5647 || (INTVAL (operands[2]) < 0
5648 && INTVAL (operands[2]) != -128)))
5650 operands[2] = GEN_INT (-INTVAL (operands[2]));
5651 return "sub{q}\t{%2, %0|%0, %2}";
5653 return "add{q}\t{%2, %0|%0, %2}";
5657 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5658 (const_string "incdec")
5659 (const_string "alu")))
5660 (set_attr "mode" "DI")])
5663 (define_insn "*addsi_1"
5664 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5665 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5666 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5667 (clobber (reg:CC FLAGS_REG))]
5668 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5670 switch (get_attr_type (insn))
5673 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5674 return "lea{l}\t{%a2, %0|%0, %a2}";
5677 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5678 if (operands[2] == const1_rtx)
5679 return "inc{l}\t%0";
5682 gcc_assert (operands[2] == constm1_rtx);
5683 return "dec{l}\t%0";
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5689 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5690 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5691 if (CONST_INT_P (operands[2])
5692 && (INTVAL (operands[2]) == 128
5693 || (INTVAL (operands[2]) < 0
5694 && INTVAL (operands[2]) != -128)))
5696 operands[2] = GEN_INT (-INTVAL (operands[2]));
5697 return "sub{l}\t{%2, %0|%0, %2}";
5699 return "add{l}\t{%2, %0|%0, %2}";
5703 (cond [(eq_attr "alternative" "2")
5704 (const_string "lea")
5705 ; Current assemblers are broken and do not allow @GOTOFF in
5706 ; ought but a memory context.
5707 (match_operand:SI 2 "pic_symbolic_operand" "")
5708 (const_string "lea")
5709 (match_operand:SI 2 "incdec_operand" "")
5710 (const_string "incdec")
5712 (const_string "alu")))
5713 (set_attr "mode" "SI")])
5715 ;; Convert lea to the lea pattern to avoid flags dependency.
5717 [(set (match_operand 0 "register_operand" "")
5718 (plus (match_operand 1 "register_operand" "")
5719 (match_operand 2 "nonmemory_operand" "")))
5720 (clobber (reg:CC FLAGS_REG))]
5722 && true_regnum (operands[0]) != true_regnum (operands[1])"
5726 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5727 may confuse gen_lowpart. */
5728 if (GET_MODE (operands[0]) != Pmode)
5730 operands[1] = gen_lowpart (Pmode, operands[1]);
5731 operands[2] = gen_lowpart (Pmode, operands[2]);
5733 operands[0] = gen_lowpart (SImode, operands[0]);
5734 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5735 if (Pmode != SImode)
5736 pat = gen_rtx_SUBREG (SImode, pat, 0);
5737 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5741 ;; It may seem that nonimmediate operand is proper one for operand 1.
5742 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5743 ;; we take care in ix86_binary_operator_ok to not allow two memory
5744 ;; operands so proper swapping will be done in reload. This allow
5745 ;; patterns constructed from addsi_1 to match.
5746 (define_insn "addsi_1_zext"
5747 [(set (match_operand:DI 0 "register_operand" "=r,r")
5749 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5750 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5751 (clobber (reg:CC FLAGS_REG))]
5752 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5754 switch (get_attr_type (insn))
5757 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5758 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5761 if (operands[2] == const1_rtx)
5762 return "inc{l}\t%k0";
5765 gcc_assert (operands[2] == constm1_rtx);
5766 return "dec{l}\t%k0";
5770 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5771 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5772 if (CONST_INT_P (operands[2])
5773 && (INTVAL (operands[2]) == 128
5774 || (INTVAL (operands[2]) < 0
5775 && INTVAL (operands[2]) != -128)))
5777 operands[2] = GEN_INT (-INTVAL (operands[2]));
5778 return "sub{l}\t{%2, %k0|%k0, %2}";
5780 return "add{l}\t{%2, %k0|%k0, %2}";
5784 (cond [(eq_attr "alternative" "1")
5785 (const_string "lea")
5786 ; Current assemblers are broken and do not allow @GOTOFF in
5787 ; ought but a memory context.
5788 (match_operand:SI 2 "pic_symbolic_operand" "")
5789 (const_string "lea")
5790 (match_operand:SI 2 "incdec_operand" "")
5791 (const_string "incdec")
5793 (const_string "alu")))
5794 (set_attr "mode" "SI")])
5796 ;; Convert lea to the lea pattern to avoid flags dependency.
5798 [(set (match_operand:DI 0 "register_operand" "")
5800 (plus:SI (match_operand:SI 1 "register_operand" "")
5801 (match_operand:SI 2 "nonmemory_operand" ""))))
5802 (clobber (reg:CC FLAGS_REG))]
5803 "TARGET_64BIT && reload_completed
5804 && true_regnum (operands[0]) != true_regnum (operands[1])"
5806 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5808 operands[1] = gen_lowpart (Pmode, operands[1]);
5809 operands[2] = gen_lowpart (Pmode, operands[2]);
5812 (define_insn "*addsi_2"
5813 [(set (reg FLAGS_REG)
5815 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5816 (match_operand:SI 2 "general_operand" "rmni,rni"))
5818 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5819 (plus:SI (match_dup 1) (match_dup 2)))]
5820 "ix86_match_ccmode (insn, CCGOCmode)
5821 && ix86_binary_operator_ok (PLUS, SImode, operands)
5822 /* Current assemblers are broken and do not allow @GOTOFF in
5823 ought but a memory context. */
5824 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5826 switch (get_attr_type (insn))
5829 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5830 if (operands[2] == const1_rtx)
5831 return "inc{l}\t%0";
5834 gcc_assert (operands[2] == constm1_rtx);
5835 return "dec{l}\t%0";
5839 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5840 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5841 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5842 if (CONST_INT_P (operands[2])
5843 && (INTVAL (operands[2]) == 128
5844 || (INTVAL (operands[2]) < 0
5845 && INTVAL (operands[2]) != -128)))
5847 operands[2] = GEN_INT (-INTVAL (operands[2]));
5848 return "sub{l}\t{%2, %0|%0, %2}";
5850 return "add{l}\t{%2, %0|%0, %2}";
5854 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5855 (const_string "incdec")
5856 (const_string "alu")))
5857 (set_attr "mode" "SI")])
5859 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5860 (define_insn "*addsi_2_zext"
5861 [(set (reg FLAGS_REG)
5863 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5864 (match_operand:SI 2 "general_operand" "rmni"))
5866 (set (match_operand:DI 0 "register_operand" "=r")
5867 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5868 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5869 && ix86_binary_operator_ok (PLUS, SImode, operands)
5870 /* Current assemblers are broken and do not allow @GOTOFF in
5871 ought but a memory context. */
5872 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5874 switch (get_attr_type (insn))
5877 if (operands[2] == const1_rtx)
5878 return "inc{l}\t%k0";
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{l}\t%k0";
5886 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5888 if (CONST_INT_P (operands[2])
5889 && (INTVAL (operands[2]) == 128
5890 || (INTVAL (operands[2]) < 0
5891 && INTVAL (operands[2]) != -128)))
5893 operands[2] = GEN_INT (-INTVAL (operands[2]));
5894 return "sub{l}\t{%2, %k0|%k0, %2}";
5896 return "add{l}\t{%2, %k0|%k0, %2}";
5900 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set_attr "mode" "SI")])
5905 (define_insn "*addsi_3"
5906 [(set (reg FLAGS_REG)
5907 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5908 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5909 (clobber (match_scratch:SI 0 "=r"))]
5910 "ix86_match_ccmode (insn, CCZmode)
5911 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5912 /* Current assemblers are broken and do not allow @GOTOFF in
5913 ought but a memory context. */
5914 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5916 switch (get_attr_type (insn))
5919 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5920 if (operands[2] == const1_rtx)
5921 return "inc{l}\t%0";
5924 gcc_assert (operands[2] == constm1_rtx);
5925 return "dec{l}\t%0";
5929 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5930 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5931 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5932 if (CONST_INT_P (operands[2])
5933 && (INTVAL (operands[2]) == 128
5934 || (INTVAL (operands[2]) < 0
5935 && INTVAL (operands[2]) != -128)))
5937 operands[2] = GEN_INT (-INTVAL (operands[2]));
5938 return "sub{l}\t{%2, %0|%0, %2}";
5940 return "add{l}\t{%2, %0|%0, %2}";
5944 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5945 (const_string "incdec")
5946 (const_string "alu")))
5947 (set_attr "mode" "SI")])
5949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5950 (define_insn "*addsi_3_zext"
5951 [(set (reg FLAGS_REG)
5952 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5953 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5954 (set (match_operand:DI 0 "register_operand" "=r")
5955 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5956 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5957 && ix86_binary_operator_ok (PLUS, SImode, operands)
5958 /* Current assemblers are broken and do not allow @GOTOFF in
5959 ought but a memory context. */
5960 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5962 switch (get_attr_type (insn))
5965 if (operands[2] == const1_rtx)
5966 return "inc{l}\t%k0";
5969 gcc_assert (operands[2] == constm1_rtx);
5970 return "dec{l}\t%k0";
5974 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5976 if (CONST_INT_P (operands[2])
5977 && (INTVAL (operands[2]) == 128
5978 || (INTVAL (operands[2]) < 0
5979 && INTVAL (operands[2]) != -128)))
5981 operands[2] = GEN_INT (-INTVAL (operands[2]));
5982 return "sub{l}\t{%2, %k0|%k0, %2}";
5984 return "add{l}\t{%2, %k0|%k0, %2}";
5988 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5989 (const_string "incdec")
5990 (const_string "alu")))
5991 (set_attr "mode" "SI")])
5993 ; For comparisons against 1, -1 and 128, we may generate better code
5994 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5995 ; is matched then. We can't accept general immediate, because for
5996 ; case of overflows, the result is messed up.
5997 ; This pattern also don't hold of 0x80000000, since the value overflows
5999 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6000 ; only for comparisons not depending on it.
6001 (define_insn "*addsi_4"
6002 [(set (reg FLAGS_REG)
6003 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6004 (match_operand:SI 2 "const_int_operand" "n")))
6005 (clobber (match_scratch:SI 0 "=rm"))]
6006 "ix86_match_ccmode (insn, CCGCmode)
6007 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6009 switch (get_attr_type (insn))
6012 if (operands[2] == constm1_rtx)
6013 return "inc{l}\t%0";
6016 gcc_assert (operands[2] == const1_rtx);
6017 return "dec{l}\t%0";
6021 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6022 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6023 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6024 if ((INTVAL (operands[2]) == -128
6025 || (INTVAL (operands[2]) > 0
6026 && INTVAL (operands[2]) != 128)))
6027 return "sub{l}\t{%2, %0|%0, %2}";
6028 operands[2] = GEN_INT (-INTVAL (operands[2]));
6029 return "add{l}\t{%2, %0|%0, %2}";
6033 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6034 (const_string "incdec")
6035 (const_string "alu")))
6036 (set_attr "mode" "SI")])
6038 (define_insn "*addsi_5"
6039 [(set (reg FLAGS_REG)
6041 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6042 (match_operand:SI 2 "general_operand" "rmni"))
6044 (clobber (match_scratch:SI 0 "=r"))]
6045 "ix86_match_ccmode (insn, CCGOCmode)
6046 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6047 /* Current assemblers are broken and do not allow @GOTOFF in
6048 ought but a memory context. */
6049 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6051 switch (get_attr_type (insn))
6054 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6055 if (operands[2] == const1_rtx)
6056 return "inc{l}\t%0";
6059 gcc_assert (operands[2] == constm1_rtx);
6060 return "dec{l}\t%0";
6064 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6065 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6066 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6067 if (CONST_INT_P (operands[2])
6068 && (INTVAL (operands[2]) == 128
6069 || (INTVAL (operands[2]) < 0
6070 && INTVAL (operands[2]) != -128)))
6072 operands[2] = GEN_INT (-INTVAL (operands[2]));
6073 return "sub{l}\t{%2, %0|%0, %2}";
6075 return "add{l}\t{%2, %0|%0, %2}";
6079 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6080 (const_string "incdec")
6081 (const_string "alu")))
6082 (set_attr "mode" "SI")])
6084 (define_expand "addhi3"
6085 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6086 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6087 (match_operand:HI 2 "general_operand" "")))
6088 (clobber (reg:CC FLAGS_REG))])]
6089 "TARGET_HIMODE_MATH"
6090 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6092 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6093 ;; type optimizations enabled by define-splits. This is not important
6094 ;; for PII, and in fact harmful because of partial register stalls.
6096 (define_insn "*addhi_1_lea"
6097 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6098 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6099 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6100 (clobber (reg:CC FLAGS_REG))]
6101 "!TARGET_PARTIAL_REG_STALL
6102 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6104 switch (get_attr_type (insn))
6109 if (operands[2] == const1_rtx)
6110 return "inc{w}\t%0";
6113 gcc_assert (operands[2] == constm1_rtx);
6114 return "dec{w}\t%0";
6118 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6119 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6120 if (CONST_INT_P (operands[2])
6121 && (INTVAL (operands[2]) == 128
6122 || (INTVAL (operands[2]) < 0
6123 && INTVAL (operands[2]) != -128)))
6125 operands[2] = GEN_INT (-INTVAL (operands[2]));
6126 return "sub{w}\t{%2, %0|%0, %2}";
6128 return "add{w}\t{%2, %0|%0, %2}";
6132 (if_then_else (eq_attr "alternative" "2")
6133 (const_string "lea")
6134 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6135 (const_string "incdec")
6136 (const_string "alu"))))
6137 (set_attr "mode" "HI,HI,SI")])
6139 (define_insn "*addhi_1"
6140 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6141 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6142 (match_operand:HI 2 "general_operand" "ri,rm")))
6143 (clobber (reg:CC FLAGS_REG))]
6144 "TARGET_PARTIAL_REG_STALL
6145 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6147 switch (get_attr_type (insn))
6150 if (operands[2] == const1_rtx)
6151 return "inc{w}\t%0";
6154 gcc_assert (operands[2] == constm1_rtx);
6155 return "dec{w}\t%0";
6159 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6160 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6161 if (CONST_INT_P (operands[2])
6162 && (INTVAL (operands[2]) == 128
6163 || (INTVAL (operands[2]) < 0
6164 && INTVAL (operands[2]) != -128)))
6166 operands[2] = GEN_INT (-INTVAL (operands[2]));
6167 return "sub{w}\t{%2, %0|%0, %2}";
6169 return "add{w}\t{%2, %0|%0, %2}";
6173 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6174 (const_string "incdec")
6175 (const_string "alu")))
6176 (set_attr "mode" "HI")])
6178 (define_insn "*addhi_2"
6179 [(set (reg FLAGS_REG)
6181 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6182 (match_operand:HI 2 "general_operand" "rmni,rni"))
6184 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6185 (plus:HI (match_dup 1) (match_dup 2)))]
6186 "ix86_match_ccmode (insn, CCGOCmode)
6187 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6189 switch (get_attr_type (insn))
6192 if (operands[2] == const1_rtx)
6193 return "inc{w}\t%0";
6196 gcc_assert (operands[2] == constm1_rtx);
6197 return "dec{w}\t%0";
6201 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6202 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6203 if (CONST_INT_P (operands[2])
6204 && (INTVAL (operands[2]) == 128
6205 || (INTVAL (operands[2]) < 0
6206 && INTVAL (operands[2]) != -128)))
6208 operands[2] = GEN_INT (-INTVAL (operands[2]));
6209 return "sub{w}\t{%2, %0|%0, %2}";
6211 return "add{w}\t{%2, %0|%0, %2}";
6215 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6216 (const_string "incdec")
6217 (const_string "alu")))
6218 (set_attr "mode" "HI")])
6220 (define_insn "*addhi_3"
6221 [(set (reg FLAGS_REG)
6222 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6223 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6224 (clobber (match_scratch:HI 0 "=r"))]
6225 "ix86_match_ccmode (insn, CCZmode)
6226 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6228 switch (get_attr_type (insn))
6231 if (operands[2] == const1_rtx)
6232 return "inc{w}\t%0";
6235 gcc_assert (operands[2] == constm1_rtx);
6236 return "dec{w}\t%0";
6240 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6241 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6242 if (CONST_INT_P (operands[2])
6243 && (INTVAL (operands[2]) == 128
6244 || (INTVAL (operands[2]) < 0
6245 && INTVAL (operands[2]) != -128)))
6247 operands[2] = GEN_INT (-INTVAL (operands[2]));
6248 return "sub{w}\t{%2, %0|%0, %2}";
6250 return "add{w}\t{%2, %0|%0, %2}";
6254 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6255 (const_string "incdec")
6256 (const_string "alu")))
6257 (set_attr "mode" "HI")])
6259 ; See comments above addsi_4 for details.
6260 (define_insn "*addhi_4"
6261 [(set (reg FLAGS_REG)
6262 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6263 (match_operand:HI 2 "const_int_operand" "n")))
6264 (clobber (match_scratch:HI 0 "=rm"))]
6265 "ix86_match_ccmode (insn, CCGCmode)
6266 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6268 switch (get_attr_type (insn))
6271 if (operands[2] == constm1_rtx)
6272 return "inc{w}\t%0";
6275 gcc_assert (operands[2] == const1_rtx);
6276 return "dec{w}\t%0";
6280 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6281 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6282 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6283 if ((INTVAL (operands[2]) == -128
6284 || (INTVAL (operands[2]) > 0
6285 && INTVAL (operands[2]) != 128)))
6286 return "sub{w}\t{%2, %0|%0, %2}";
6287 operands[2] = GEN_INT (-INTVAL (operands[2]));
6288 return "add{w}\t{%2, %0|%0, %2}";
6292 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6293 (const_string "incdec")
6294 (const_string "alu")))
6295 (set_attr "mode" "SI")])
6298 (define_insn "*addhi_5"
6299 [(set (reg FLAGS_REG)
6301 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6302 (match_operand:HI 2 "general_operand" "rmni"))
6304 (clobber (match_scratch:HI 0 "=r"))]
6305 "ix86_match_ccmode (insn, CCGOCmode)
6306 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6308 switch (get_attr_type (insn))
6311 if (operands[2] == const1_rtx)
6312 return "inc{w}\t%0";
6315 gcc_assert (operands[2] == constm1_rtx);
6316 return "dec{w}\t%0";
6320 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6321 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6322 if (CONST_INT_P (operands[2])
6323 && (INTVAL (operands[2]) == 128
6324 || (INTVAL (operands[2]) < 0
6325 && INTVAL (operands[2]) != -128)))
6327 operands[2] = GEN_INT (-INTVAL (operands[2]));
6328 return "sub{w}\t{%2, %0|%0, %2}";
6330 return "add{w}\t{%2, %0|%0, %2}";
6334 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6335 (const_string "incdec")
6336 (const_string "alu")))
6337 (set_attr "mode" "HI")])
6339 (define_expand "addqi3"
6340 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6341 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6342 (match_operand:QI 2 "general_operand" "")))
6343 (clobber (reg:CC FLAGS_REG))])]
6344 "TARGET_QIMODE_MATH"
6345 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6347 ;; %%% Potential partial reg stall on alternative 2. What to do?
6348 (define_insn "*addqi_1_lea"
6349 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6350 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6351 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6352 (clobber (reg:CC FLAGS_REG))]
6353 "!TARGET_PARTIAL_REG_STALL
6354 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6356 int widen = (which_alternative == 2);
6357 switch (get_attr_type (insn))
6362 if (operands[2] == const1_rtx)
6363 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6366 gcc_assert (operands[2] == constm1_rtx);
6367 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6371 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6372 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6373 if (CONST_INT_P (operands[2])
6374 && (INTVAL (operands[2]) == 128
6375 || (INTVAL (operands[2]) < 0
6376 && INTVAL (operands[2]) != -128)))
6378 operands[2] = GEN_INT (-INTVAL (operands[2]));
6380 return "sub{l}\t{%2, %k0|%k0, %2}";
6382 return "sub{b}\t{%2, %0|%0, %2}";
6385 return "add{l}\t{%k2, %k0|%k0, %k2}";
6387 return "add{b}\t{%2, %0|%0, %2}";
6391 (if_then_else (eq_attr "alternative" "3")
6392 (const_string "lea")
6393 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6394 (const_string "incdec")
6395 (const_string "alu"))))
6396 (set_attr "mode" "QI,QI,SI,SI")])
6398 (define_insn "*addqi_1"
6399 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6400 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6401 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6402 (clobber (reg:CC FLAGS_REG))]
6403 "TARGET_PARTIAL_REG_STALL
6404 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6406 int widen = (which_alternative == 2);
6407 switch (get_attr_type (insn))
6410 if (operands[2] == const1_rtx)
6411 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6414 gcc_assert (operands[2] == constm1_rtx);
6415 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6419 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6420 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6421 if (CONST_INT_P (operands[2])
6422 && (INTVAL (operands[2]) == 128
6423 || (INTVAL (operands[2]) < 0
6424 && INTVAL (operands[2]) != -128)))
6426 operands[2] = GEN_INT (-INTVAL (operands[2]));
6428 return "sub{l}\t{%2, %k0|%k0, %2}";
6430 return "sub{b}\t{%2, %0|%0, %2}";
6433 return "add{l}\t{%k2, %k0|%k0, %k2}";
6435 return "add{b}\t{%2, %0|%0, %2}";
6439 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6440 (const_string "incdec")
6441 (const_string "alu")))
6442 (set_attr "mode" "QI,QI,SI")])
6444 (define_insn "*addqi_1_slp"
6445 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6446 (plus:QI (match_dup 0)
6447 (match_operand:QI 1 "general_operand" "qn,qnm")))
6448 (clobber (reg:CC FLAGS_REG))]
6449 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6450 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6452 switch (get_attr_type (insn))
6455 if (operands[1] == const1_rtx)
6456 return "inc{b}\t%0";
6459 gcc_assert (operands[1] == constm1_rtx);
6460 return "dec{b}\t%0";
6464 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6465 if (CONST_INT_P (operands[1])
6466 && INTVAL (operands[1]) < 0)
6468 operands[1] = GEN_INT (-INTVAL (operands[1]));
6469 return "sub{b}\t{%1, %0|%0, %1}";
6471 return "add{b}\t{%1, %0|%0, %1}";
6475 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6476 (const_string "incdec")
6477 (const_string "alu1")))
6478 (set (attr "memory")
6479 (if_then_else (match_operand 1 "memory_operand" "")
6480 (const_string "load")
6481 (const_string "none")))
6482 (set_attr "mode" "QI")])
6484 (define_insn "*addqi_2"
6485 [(set (reg FLAGS_REG)
6487 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6488 (match_operand:QI 2 "general_operand" "qmni,qni"))
6490 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6491 (plus:QI (match_dup 1) (match_dup 2)))]
6492 "ix86_match_ccmode (insn, CCGOCmode)
6493 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6495 switch (get_attr_type (insn))
6498 if (operands[2] == const1_rtx)
6499 return "inc{b}\t%0";
6502 gcc_assert (operands[2] == constm1_rtx
6503 || (CONST_INT_P (operands[2])
6504 && INTVAL (operands[2]) == 255));
6505 return "dec{b}\t%0";
6509 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6510 if (CONST_INT_P (operands[2])
6511 && INTVAL (operands[2]) < 0)
6513 operands[2] = GEN_INT (-INTVAL (operands[2]));
6514 return "sub{b}\t{%2, %0|%0, %2}";
6516 return "add{b}\t{%2, %0|%0, %2}";
6520 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6521 (const_string "incdec")
6522 (const_string "alu")))
6523 (set_attr "mode" "QI")])
6525 (define_insn "*addqi_3"
6526 [(set (reg FLAGS_REG)
6527 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6528 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6529 (clobber (match_scratch:QI 0 "=q"))]
6530 "ix86_match_ccmode (insn, CCZmode)
6531 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6533 switch (get_attr_type (insn))
6536 if (operands[2] == const1_rtx)
6537 return "inc{b}\t%0";
6540 gcc_assert (operands[2] == constm1_rtx
6541 || (CONST_INT_P (operands[2])
6542 && INTVAL (operands[2]) == 255));
6543 return "dec{b}\t%0";
6547 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6548 if (CONST_INT_P (operands[2])
6549 && INTVAL (operands[2]) < 0)
6551 operands[2] = GEN_INT (-INTVAL (operands[2]));
6552 return "sub{b}\t{%2, %0|%0, %2}";
6554 return "add{b}\t{%2, %0|%0, %2}";
6558 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6559 (const_string "incdec")
6560 (const_string "alu")))
6561 (set_attr "mode" "QI")])
6563 ; See comments above addsi_4 for details.
6564 (define_insn "*addqi_4"
6565 [(set (reg FLAGS_REG)
6566 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6567 (match_operand:QI 2 "const_int_operand" "n")))
6568 (clobber (match_scratch:QI 0 "=qm"))]
6569 "ix86_match_ccmode (insn, CCGCmode)
6570 && (INTVAL (operands[2]) & 0xff) != 0x80"
6572 switch (get_attr_type (insn))
6575 if (operands[2] == constm1_rtx
6576 || (CONST_INT_P (operands[2])
6577 && INTVAL (operands[2]) == 255))
6578 return "inc{b}\t%0";
6581 gcc_assert (operands[2] == const1_rtx);
6582 return "dec{b}\t%0";
6586 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6587 if (INTVAL (operands[2]) < 0)
6589 operands[2] = GEN_INT (-INTVAL (operands[2]));
6590 return "add{b}\t{%2, %0|%0, %2}";
6592 return "sub{b}\t{%2, %0|%0, %2}";
6596 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6597 (const_string "incdec")
6598 (const_string "alu")))
6599 (set_attr "mode" "QI")])
6602 (define_insn "*addqi_5"
6603 [(set (reg FLAGS_REG)
6605 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6606 (match_operand:QI 2 "general_operand" "qmni"))
6608 (clobber (match_scratch:QI 0 "=q"))]
6609 "ix86_match_ccmode (insn, CCGOCmode)
6610 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6612 switch (get_attr_type (insn))
6615 if (operands[2] == const1_rtx)
6616 return "inc{b}\t%0";
6619 gcc_assert (operands[2] == constm1_rtx
6620 || (CONST_INT_P (operands[2])
6621 && INTVAL (operands[2]) == 255));
6622 return "dec{b}\t%0";
6626 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6627 if (CONST_INT_P (operands[2])
6628 && INTVAL (operands[2]) < 0)
6630 operands[2] = GEN_INT (-INTVAL (operands[2]));
6631 return "sub{b}\t{%2, %0|%0, %2}";
6633 return "add{b}\t{%2, %0|%0, %2}";
6637 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6638 (const_string "incdec")
6639 (const_string "alu")))
6640 (set_attr "mode" "QI")])
6643 (define_insn "addqi_ext_1"
6644 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6649 (match_operand 1 "ext_register_operand" "0")
6652 (match_operand:QI 2 "general_operand" "Qmn")))
6653 (clobber (reg:CC FLAGS_REG))]
6656 switch (get_attr_type (insn))
6659 if (operands[2] == const1_rtx)
6660 return "inc{b}\t%h0";
6663 gcc_assert (operands[2] == constm1_rtx
6664 || (CONST_INT_P (operands[2])
6665 && INTVAL (operands[2]) == 255));
6666 return "dec{b}\t%h0";
6670 return "add{b}\t{%2, %h0|%h0, %2}";
6674 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6675 (const_string "incdec")
6676 (const_string "alu")))
6677 (set_attr "mode" "QI")])
6679 (define_insn "*addqi_ext_1_rex64"
6680 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6685 (match_operand 1 "ext_register_operand" "0")
6688 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6689 (clobber (reg:CC FLAGS_REG))]
6692 switch (get_attr_type (insn))
6695 if (operands[2] == const1_rtx)
6696 return "inc{b}\t%h0";
6699 gcc_assert (operands[2] == constm1_rtx
6700 || (CONST_INT_P (operands[2])
6701 && INTVAL (operands[2]) == 255));
6702 return "dec{b}\t%h0";
6706 return "add{b}\t{%2, %h0|%h0, %2}";
6710 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6711 (const_string "incdec")
6712 (const_string "alu")))
6713 (set_attr "mode" "QI")])
6715 (define_insn "*addqi_ext_2"
6716 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6721 (match_operand 1 "ext_register_operand" "%0")
6725 (match_operand 2 "ext_register_operand" "Q")
6728 (clobber (reg:CC FLAGS_REG))]
6730 "add{b}\t{%h2, %h0|%h0, %h2}"
6731 [(set_attr "type" "alu")
6732 (set_attr "mode" "QI")])
6734 ;; The patterns that match these are at the end of this file.
6736 (define_expand "addxf3"
6737 [(set (match_operand:XF 0 "register_operand" "")
6738 (plus:XF (match_operand:XF 1 "register_operand" "")
6739 (match_operand:XF 2 "register_operand" "")))]
6743 (define_expand "adddf3"
6744 [(set (match_operand:DF 0 "register_operand" "")
6745 (plus:DF (match_operand:DF 1 "register_operand" "")
6746 (match_operand:DF 2 "nonimmediate_operand" "")))]
6747 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6750 (define_expand "addsf3"
6751 [(set (match_operand:SF 0 "register_operand" "")
6752 (plus:SF (match_operand:SF 1 "register_operand" "")
6753 (match_operand:SF 2 "nonimmediate_operand" "")))]
6754 "TARGET_80387 || TARGET_SSE_MATH"
6757 ;; Subtract instructions
6759 ;; %%% splits for subditi3
6761 (define_expand "subti3"
6762 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6763 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6764 (match_operand:TI 2 "x86_64_general_operand" "")))
6765 (clobber (reg:CC FLAGS_REG))])]
6767 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6769 (define_insn "*subti3_1"
6770 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6771 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6772 (match_operand:TI 2 "general_operand" "roiF,riF")))
6773 (clobber (reg:CC FLAGS_REG))]
6774 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6778 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6779 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6780 (match_operand:TI 2 "general_operand" "")))
6781 (clobber (reg:CC FLAGS_REG))]
6782 "TARGET_64BIT && reload_completed"
6783 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6784 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6785 (parallel [(set (match_dup 3)
6786 (minus:DI (match_dup 4)
6787 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6789 (clobber (reg:CC FLAGS_REG))])]
6790 "split_ti (operands+0, 1, operands+0, operands+3);
6791 split_ti (operands+1, 1, operands+1, operands+4);
6792 split_ti (operands+2, 1, operands+2, operands+5);")
6794 ;; %%% splits for subsidi3
6796 (define_expand "subdi3"
6797 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6798 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6799 (match_operand:DI 2 "x86_64_general_operand" "")))
6800 (clobber (reg:CC FLAGS_REG))])]
6802 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6804 (define_insn "*subdi3_1"
6805 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6806 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6807 (match_operand:DI 2 "general_operand" "roiF,riF")))
6808 (clobber (reg:CC FLAGS_REG))]
6809 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6813 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6814 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6815 (match_operand:DI 2 "general_operand" "")))
6816 (clobber (reg:CC FLAGS_REG))]
6817 "!TARGET_64BIT && reload_completed"
6818 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6819 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6820 (parallel [(set (match_dup 3)
6821 (minus:SI (match_dup 4)
6822 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6824 (clobber (reg:CC FLAGS_REG))])]
6825 "split_di (operands+0, 1, operands+0, operands+3);
6826 split_di (operands+1, 1, operands+1, operands+4);
6827 split_di (operands+2, 1, operands+2, operands+5);")
6829 (define_insn "subdi3_carry_rex64"
6830 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6831 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6832 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6833 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6834 (clobber (reg:CC FLAGS_REG))]
6835 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6836 "sbb{q}\t{%2, %0|%0, %2}"
6837 [(set_attr "type" "alu")
6838 (set_attr "pent_pair" "pu")
6839 (set_attr "mode" "DI")])
6841 (define_insn "*subdi_1_rex64"
6842 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6843 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6844 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6845 (clobber (reg:CC FLAGS_REG))]
6846 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6847 "sub{q}\t{%2, %0|%0, %2}"
6848 [(set_attr "type" "alu")
6849 (set_attr "mode" "DI")])
6851 (define_insn "*subdi_2_rex64"
6852 [(set (reg FLAGS_REG)
6854 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6855 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6857 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6858 (minus:DI (match_dup 1) (match_dup 2)))]
6859 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6860 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6861 "sub{q}\t{%2, %0|%0, %2}"
6862 [(set_attr "type" "alu")
6863 (set_attr "mode" "DI")])
6865 (define_insn "*subdi_3_rex63"
6866 [(set (reg FLAGS_REG)
6867 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6868 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6869 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6870 (minus:DI (match_dup 1) (match_dup 2)))]
6871 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6872 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6873 "sub{q}\t{%2, %0|%0, %2}"
6874 [(set_attr "type" "alu")
6875 (set_attr "mode" "DI")])
6877 (define_insn "subqi3_carry"
6878 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6879 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6880 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6881 (match_operand:QI 2 "general_operand" "qi,qm"))))
6882 (clobber (reg:CC FLAGS_REG))]
6883 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6884 "sbb{b}\t{%2, %0|%0, %2}"
6885 [(set_attr "type" "alu")
6886 (set_attr "pent_pair" "pu")
6887 (set_attr "mode" "QI")])
6889 (define_insn "subhi3_carry"
6890 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6891 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6892 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6893 (match_operand:HI 2 "general_operand" "ri,rm"))))
6894 (clobber (reg:CC FLAGS_REG))]
6895 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6896 "sbb{w}\t{%2, %0|%0, %2}"
6897 [(set_attr "type" "alu")
6898 (set_attr "pent_pair" "pu")
6899 (set_attr "mode" "HI")])
6901 (define_insn "subsi3_carry"
6902 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6903 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6904 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6905 (match_operand:SI 2 "general_operand" "ri,rm"))))
6906 (clobber (reg:CC FLAGS_REG))]
6907 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6908 "sbb{l}\t{%2, %0|%0, %2}"
6909 [(set_attr "type" "alu")
6910 (set_attr "pent_pair" "pu")
6911 (set_attr "mode" "SI")])
6913 (define_insn "subsi3_carry_zext"
6914 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6916 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6917 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6918 (match_operand:SI 2 "general_operand" "ri,rm")))))
6919 (clobber (reg:CC FLAGS_REG))]
6920 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6921 "sbb{l}\t{%2, %k0|%k0, %2}"
6922 [(set_attr "type" "alu")
6923 (set_attr "pent_pair" "pu")
6924 (set_attr "mode" "SI")])
6926 (define_expand "subsi3"
6927 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6928 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6929 (match_operand:SI 2 "general_operand" "")))
6930 (clobber (reg:CC FLAGS_REG))])]
6932 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6934 (define_insn "*subsi_1"
6935 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6936 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6937 (match_operand:SI 2 "general_operand" "ri,rm")))
6938 (clobber (reg:CC FLAGS_REG))]
6939 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6940 "sub{l}\t{%2, %0|%0, %2}"
6941 [(set_attr "type" "alu")
6942 (set_attr "mode" "SI")])
6944 (define_insn "*subsi_1_zext"
6945 [(set (match_operand:DI 0 "register_operand" "=r")
6947 (minus:SI (match_operand:SI 1 "register_operand" "0")
6948 (match_operand:SI 2 "general_operand" "rim"))))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6951 "sub{l}\t{%2, %k0|%k0, %2}"
6952 [(set_attr "type" "alu")
6953 (set_attr "mode" "SI")])
6955 (define_insn "*subsi_2"
6956 [(set (reg FLAGS_REG)
6958 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6959 (match_operand:SI 2 "general_operand" "ri,rm"))
6961 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6962 (minus:SI (match_dup 1) (match_dup 2)))]
6963 "ix86_match_ccmode (insn, CCGOCmode)
6964 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6965 "sub{l}\t{%2, %0|%0, %2}"
6966 [(set_attr "type" "alu")
6967 (set_attr "mode" "SI")])
6969 (define_insn "*subsi_2_zext"
6970 [(set (reg FLAGS_REG)
6972 (minus:SI (match_operand:SI 1 "register_operand" "0")
6973 (match_operand:SI 2 "general_operand" "rim"))
6975 (set (match_operand:DI 0 "register_operand" "=r")
6977 (minus:SI (match_dup 1)
6979 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6980 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6981 "sub{l}\t{%2, %k0|%k0, %2}"
6982 [(set_attr "type" "alu")
6983 (set_attr "mode" "SI")])
6985 (define_insn "*subsi_3"
6986 [(set (reg FLAGS_REG)
6987 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6988 (match_operand:SI 2 "general_operand" "ri,rm")))
6989 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6990 (minus:SI (match_dup 1) (match_dup 2)))]
6991 "ix86_match_ccmode (insn, CCmode)
6992 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6993 "sub{l}\t{%2, %0|%0, %2}"
6994 [(set_attr "type" "alu")
6995 (set_attr "mode" "SI")])
6997 (define_insn "*subsi_3_zext"
6998 [(set (reg FLAGS_REG)
6999 (compare (match_operand:SI 1 "register_operand" "0")
7000 (match_operand:SI 2 "general_operand" "rim")))
7001 (set (match_operand:DI 0 "register_operand" "=r")
7003 (minus:SI (match_dup 1)
7005 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7006 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7007 "sub{l}\t{%2, %1|%1, %2}"
7008 [(set_attr "type" "alu")
7009 (set_attr "mode" "DI")])
7011 (define_expand "subhi3"
7012 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7013 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7014 (match_operand:HI 2 "general_operand" "")))
7015 (clobber (reg:CC FLAGS_REG))])]
7016 "TARGET_HIMODE_MATH"
7017 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7019 (define_insn "*subhi_1"
7020 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7021 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7022 (match_operand:HI 2 "general_operand" "ri,rm")))
7023 (clobber (reg:CC FLAGS_REG))]
7024 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7025 "sub{w}\t{%2, %0|%0, %2}"
7026 [(set_attr "type" "alu")
7027 (set_attr "mode" "HI")])
7029 (define_insn "*subhi_2"
7030 [(set (reg FLAGS_REG)
7032 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7033 (match_operand:HI 2 "general_operand" "ri,rm"))
7035 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7036 (minus:HI (match_dup 1) (match_dup 2)))]
7037 "ix86_match_ccmode (insn, CCGOCmode)
7038 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7039 "sub{w}\t{%2, %0|%0, %2}"
7040 [(set_attr "type" "alu")
7041 (set_attr "mode" "HI")])
7043 (define_insn "*subhi_3"
7044 [(set (reg FLAGS_REG)
7045 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7046 (match_operand:HI 2 "general_operand" "ri,rm")))
7047 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7048 (minus:HI (match_dup 1) (match_dup 2)))]
7049 "ix86_match_ccmode (insn, CCmode)
7050 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7051 "sub{w}\t{%2, %0|%0, %2}"
7052 [(set_attr "type" "alu")
7053 (set_attr "mode" "HI")])
7055 (define_expand "subqi3"
7056 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7057 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7058 (match_operand:QI 2 "general_operand" "")))
7059 (clobber (reg:CC FLAGS_REG))])]
7060 "TARGET_QIMODE_MATH"
7061 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7063 (define_insn "*subqi_1"
7064 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7065 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7066 (match_operand:QI 2 "general_operand" "qn,qmn")))
7067 (clobber (reg:CC FLAGS_REG))]
7068 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7069 "sub{b}\t{%2, %0|%0, %2}"
7070 [(set_attr "type" "alu")
7071 (set_attr "mode" "QI")])
7073 (define_insn "*subqi_1_slp"
7074 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7075 (minus:QI (match_dup 0)
7076 (match_operand:QI 1 "general_operand" "qn,qmn")))
7077 (clobber (reg:CC FLAGS_REG))]
7078 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7079 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7080 "sub{b}\t{%1, %0|%0, %1}"
7081 [(set_attr "type" "alu1")
7082 (set_attr "mode" "QI")])
7084 (define_insn "*subqi_2"
7085 [(set (reg FLAGS_REG)
7087 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7088 (match_operand:QI 2 "general_operand" "qi,qm"))
7090 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7091 (minus:HI (match_dup 1) (match_dup 2)))]
7092 "ix86_match_ccmode (insn, CCGOCmode)
7093 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7094 "sub{b}\t{%2, %0|%0, %2}"
7095 [(set_attr "type" "alu")
7096 (set_attr "mode" "QI")])
7098 (define_insn "*subqi_3"
7099 [(set (reg FLAGS_REG)
7100 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7101 (match_operand:QI 2 "general_operand" "qi,qm")))
7102 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7103 (minus:HI (match_dup 1) (match_dup 2)))]
7104 "ix86_match_ccmode (insn, CCmode)
7105 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7106 "sub{b}\t{%2, %0|%0, %2}"
7107 [(set_attr "type" "alu")
7108 (set_attr "mode" "QI")])
7110 ;; The patterns that match these are at the end of this file.
7112 (define_expand "subxf3"
7113 [(set (match_operand:XF 0 "register_operand" "")
7114 (minus:XF (match_operand:XF 1 "register_operand" "")
7115 (match_operand:XF 2 "register_operand" "")))]
7119 (define_expand "subdf3"
7120 [(set (match_operand:DF 0 "register_operand" "")
7121 (minus:DF (match_operand:DF 1 "register_operand" "")
7122 (match_operand:DF 2 "nonimmediate_operand" "")))]
7123 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7126 (define_expand "subsf3"
7127 [(set (match_operand:SF 0 "register_operand" "")
7128 (minus:SF (match_operand:SF 1 "register_operand" "")
7129 (match_operand:SF 2 "nonimmediate_operand" "")))]
7130 "TARGET_80387 || TARGET_SSE_MATH"
7133 ;; Multiply instructions
7135 (define_expand "muldi3"
7136 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7137 (mult:DI (match_operand:DI 1 "register_operand" "")
7138 (match_operand:DI 2 "x86_64_general_operand" "")))
7139 (clobber (reg:CC FLAGS_REG))])]
7144 ;; IMUL reg64, reg64, imm8 Direct
7145 ;; IMUL reg64, mem64, imm8 VectorPath
7146 ;; IMUL reg64, reg64, imm32 Direct
7147 ;; IMUL reg64, mem64, imm32 VectorPath
7148 ;; IMUL reg64, reg64 Direct
7149 ;; IMUL reg64, mem64 Direct
7151 (define_insn "*muldi3_1_rex64"
7152 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7153 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7154 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7155 (clobber (reg:CC FLAGS_REG))]
7157 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7159 imul{q}\t{%2, %1, %0|%0, %1, %2}
7160 imul{q}\t{%2, %1, %0|%0, %1, %2}
7161 imul{q}\t{%2, %0|%0, %2}"
7162 [(set_attr "type" "imul")
7163 (set_attr "prefix_0f" "0,0,1")
7164 (set (attr "athlon_decode")
7165 (cond [(eq_attr "cpu" "athlon")
7166 (const_string "vector")
7167 (eq_attr "alternative" "1")
7168 (const_string "vector")
7169 (and (eq_attr "alternative" "2")
7170 (match_operand 1 "memory_operand" ""))
7171 (const_string "vector")]
7172 (const_string "direct")))
7173 (set (attr "amdfam10_decode")
7174 (cond [(and (eq_attr "alternative" "0,1")
7175 (match_operand 1 "memory_operand" ""))
7176 (const_string "vector")]
7177 (const_string "direct")))
7178 (set_attr "mode" "DI")])
7180 (define_expand "mulsi3"
7181 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7182 (mult:SI (match_operand:SI 1 "register_operand" "")
7183 (match_operand:SI 2 "general_operand" "")))
7184 (clobber (reg:CC FLAGS_REG))])]
7189 ;; IMUL reg32, reg32, imm8 Direct
7190 ;; IMUL reg32, mem32, imm8 VectorPath
7191 ;; IMUL reg32, reg32, imm32 Direct
7192 ;; IMUL reg32, mem32, imm32 VectorPath
7193 ;; IMUL reg32, reg32 Direct
7194 ;; IMUL reg32, mem32 Direct
7196 (define_insn "*mulsi3_1"
7197 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7198 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7199 (match_operand:SI 2 "general_operand" "K,i,mr")))
7200 (clobber (reg:CC FLAGS_REG))]
7201 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7203 imul{l}\t{%2, %1, %0|%0, %1, %2}
7204 imul{l}\t{%2, %1, %0|%0, %1, %2}
7205 imul{l}\t{%2, %0|%0, %2}"
7206 [(set_attr "type" "imul")
7207 (set_attr "prefix_0f" "0,0,1")
7208 (set (attr "athlon_decode")
7209 (cond [(eq_attr "cpu" "athlon")
7210 (const_string "vector")
7211 (eq_attr "alternative" "1")
7212 (const_string "vector")
7213 (and (eq_attr "alternative" "2")
7214 (match_operand 1 "memory_operand" ""))
7215 (const_string "vector")]
7216 (const_string "direct")))
7217 (set (attr "amdfam10_decode")
7218 (cond [(and (eq_attr "alternative" "0,1")
7219 (match_operand 1 "memory_operand" ""))
7220 (const_string "vector")]
7221 (const_string "direct")))
7222 (set_attr "mode" "SI")])
7224 (define_insn "*mulsi3_1_zext"
7225 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7227 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7228 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7229 (clobber (reg:CC FLAGS_REG))]
7231 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7233 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7234 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7235 imul{l}\t{%2, %k0|%k0, %2}"
7236 [(set_attr "type" "imul")
7237 (set_attr "prefix_0f" "0,0,1")
7238 (set (attr "athlon_decode")
7239 (cond [(eq_attr "cpu" "athlon")
7240 (const_string "vector")
7241 (eq_attr "alternative" "1")
7242 (const_string "vector")
7243 (and (eq_attr "alternative" "2")
7244 (match_operand 1 "memory_operand" ""))
7245 (const_string "vector")]
7246 (const_string "direct")))
7247 (set (attr "amdfam10_decode")
7248 (cond [(and (eq_attr "alternative" "0,1")
7249 (match_operand 1 "memory_operand" ""))
7250 (const_string "vector")]
7251 (const_string "direct")))
7252 (set_attr "mode" "SI")])
7254 (define_expand "mulhi3"
7255 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7256 (mult:HI (match_operand:HI 1 "register_operand" "")
7257 (match_operand:HI 2 "general_operand" "")))
7258 (clobber (reg:CC FLAGS_REG))])]
7259 "TARGET_HIMODE_MATH"
7263 ;; IMUL reg16, reg16, imm8 VectorPath
7264 ;; IMUL reg16, mem16, imm8 VectorPath
7265 ;; IMUL reg16, reg16, imm16 VectorPath
7266 ;; IMUL reg16, mem16, imm16 VectorPath
7267 ;; IMUL reg16, reg16 Direct
7268 ;; IMUL reg16, mem16 Direct
7269 (define_insn "*mulhi3_1"
7270 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7271 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7272 (match_operand:HI 2 "general_operand" "K,i,mr")))
7273 (clobber (reg:CC FLAGS_REG))]
7274 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7276 imul{w}\t{%2, %1, %0|%0, %1, %2}
7277 imul{w}\t{%2, %1, %0|%0, %1, %2}
7278 imul{w}\t{%2, %0|%0, %2}"
7279 [(set_attr "type" "imul")
7280 (set_attr "prefix_0f" "0,0,1")
7281 (set (attr "athlon_decode")
7282 (cond [(eq_attr "cpu" "athlon")
7283 (const_string "vector")
7284 (eq_attr "alternative" "1,2")
7285 (const_string "vector")]
7286 (const_string "direct")))
7287 (set (attr "amdfam10_decode")
7288 (cond [(eq_attr "alternative" "0,1")
7289 (const_string "vector")]
7290 (const_string "direct")))
7291 (set_attr "mode" "HI")])
7293 (define_expand "mulqi3"
7294 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7295 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7296 (match_operand:QI 2 "register_operand" "")))
7297 (clobber (reg:CC FLAGS_REG))])]
7298 "TARGET_QIMODE_MATH"
7305 (define_insn "*mulqi3_1"
7306 [(set (match_operand:QI 0 "register_operand" "=a")
7307 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7308 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7309 (clobber (reg:CC FLAGS_REG))]
7311 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7313 [(set_attr "type" "imul")
7314 (set_attr "length_immediate" "0")
7315 (set (attr "athlon_decode")
7316 (if_then_else (eq_attr "cpu" "athlon")
7317 (const_string "vector")
7318 (const_string "direct")))
7319 (set_attr "amdfam10_decode" "direct")
7320 (set_attr "mode" "QI")])
7322 (define_expand "umulqihi3"
7323 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7324 (mult:HI (zero_extend:HI
7325 (match_operand:QI 1 "nonimmediate_operand" ""))
7327 (match_operand:QI 2 "register_operand" ""))))
7328 (clobber (reg:CC FLAGS_REG))])]
7329 "TARGET_QIMODE_MATH"
7332 (define_insn "*umulqihi3_1"
7333 [(set (match_operand:HI 0 "register_operand" "=a")
7334 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7335 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7336 (clobber (reg:CC FLAGS_REG))]
7338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7340 [(set_attr "type" "imul")
7341 (set_attr "length_immediate" "0")
7342 (set (attr "athlon_decode")
7343 (if_then_else (eq_attr "cpu" "athlon")
7344 (const_string "vector")
7345 (const_string "direct")))
7346 (set_attr "amdfam10_decode" "direct")
7347 (set_attr "mode" "QI")])
7349 (define_expand "mulqihi3"
7350 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7351 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7352 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7353 (clobber (reg:CC FLAGS_REG))])]
7354 "TARGET_QIMODE_MATH"
7357 (define_insn "*mulqihi3_insn"
7358 [(set (match_operand:HI 0 "register_operand" "=a")
7359 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7360 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7361 (clobber (reg:CC FLAGS_REG))]
7363 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7365 [(set_attr "type" "imul")
7366 (set_attr "length_immediate" "0")
7367 (set (attr "athlon_decode")
7368 (if_then_else (eq_attr "cpu" "athlon")
7369 (const_string "vector")
7370 (const_string "direct")))
7371 (set_attr "amdfam10_decode" "direct")
7372 (set_attr "mode" "QI")])
7374 (define_expand "umulditi3"
7375 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7376 (mult:TI (zero_extend:TI
7377 (match_operand:DI 1 "nonimmediate_operand" ""))
7379 (match_operand:DI 2 "register_operand" ""))))
7380 (clobber (reg:CC FLAGS_REG))])]
7384 (define_insn "*umulditi3_insn"
7385 [(set (match_operand:TI 0 "register_operand" "=A")
7386 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7387 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7388 (clobber (reg:CC FLAGS_REG))]
7390 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7392 [(set_attr "type" "imul")
7393 (set_attr "length_immediate" "0")
7394 (set (attr "athlon_decode")
7395 (if_then_else (eq_attr "cpu" "athlon")
7396 (const_string "vector")
7397 (const_string "double")))
7398 (set_attr "amdfam10_decode" "double")
7399 (set_attr "mode" "DI")])
7401 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7402 (define_expand "umulsidi3"
7403 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7404 (mult:DI (zero_extend:DI
7405 (match_operand:SI 1 "nonimmediate_operand" ""))
7407 (match_operand:SI 2 "register_operand" ""))))
7408 (clobber (reg:CC FLAGS_REG))])]
7412 (define_insn "*umulsidi3_insn"
7413 [(set (match_operand:DI 0 "register_operand" "=A")
7414 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7415 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7416 (clobber (reg:CC FLAGS_REG))]
7418 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7420 [(set_attr "type" "imul")
7421 (set_attr "length_immediate" "0")
7422 (set (attr "athlon_decode")
7423 (if_then_else (eq_attr "cpu" "athlon")
7424 (const_string "vector")
7425 (const_string "double")))
7426 (set_attr "amdfam10_decode" "double")
7427 (set_attr "mode" "SI")])
7429 (define_expand "mulditi3"
7430 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7431 (mult:TI (sign_extend:TI
7432 (match_operand:DI 1 "nonimmediate_operand" ""))
7434 (match_operand:DI 2 "register_operand" ""))))
7435 (clobber (reg:CC FLAGS_REG))])]
7439 (define_insn "*mulditi3_insn"
7440 [(set (match_operand:TI 0 "register_operand" "=A")
7441 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7442 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7443 (clobber (reg:CC FLAGS_REG))]
7445 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7447 [(set_attr "type" "imul")
7448 (set_attr "length_immediate" "0")
7449 (set (attr "athlon_decode")
7450 (if_then_else (eq_attr "cpu" "athlon")
7451 (const_string "vector")
7452 (const_string "double")))
7453 (set_attr "amdfam10_decode" "double")
7454 (set_attr "mode" "DI")])
7456 (define_expand "mulsidi3"
7457 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7458 (mult:DI (sign_extend:DI
7459 (match_operand:SI 1 "nonimmediate_operand" ""))
7461 (match_operand:SI 2 "register_operand" ""))))
7462 (clobber (reg:CC FLAGS_REG))])]
7466 (define_insn "*mulsidi3_insn"
7467 [(set (match_operand:DI 0 "register_operand" "=A")
7468 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7469 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7470 (clobber (reg:CC FLAGS_REG))]
7472 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7474 [(set_attr "type" "imul")
7475 (set_attr "length_immediate" "0")
7476 (set (attr "athlon_decode")
7477 (if_then_else (eq_attr "cpu" "athlon")
7478 (const_string "vector")
7479 (const_string "double")))
7480 (set_attr "amdfam10_decode" "double")
7481 (set_attr "mode" "SI")])
7483 (define_expand "umuldi3_highpart"
7484 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7487 (mult:TI (zero_extend:TI
7488 (match_operand:DI 1 "nonimmediate_operand" ""))
7490 (match_operand:DI 2 "register_operand" "")))
7492 (clobber (match_scratch:DI 3 ""))
7493 (clobber (reg:CC FLAGS_REG))])]
7497 (define_insn "*umuldi3_highpart_rex64"
7498 [(set (match_operand:DI 0 "register_operand" "=d")
7501 (mult:TI (zero_extend:TI
7502 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7504 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7506 (clobber (match_scratch:DI 3 "=1"))
7507 (clobber (reg:CC FLAGS_REG))]
7509 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7511 [(set_attr "type" "imul")
7512 (set_attr "length_immediate" "0")
7513 (set (attr "athlon_decode")
7514 (if_then_else (eq_attr "cpu" "athlon")
7515 (const_string "vector")
7516 (const_string "double")))
7517 (set_attr "amdfam10_decode" "double")
7518 (set_attr "mode" "DI")])
7520 (define_expand "umulsi3_highpart"
7521 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7524 (mult:DI (zero_extend:DI
7525 (match_operand:SI 1 "nonimmediate_operand" ""))
7527 (match_operand:SI 2 "register_operand" "")))
7529 (clobber (match_scratch:SI 3 ""))
7530 (clobber (reg:CC FLAGS_REG))])]
7534 (define_insn "*umulsi3_highpart_insn"
7535 [(set (match_operand:SI 0 "register_operand" "=d")
7538 (mult:DI (zero_extend:DI
7539 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7541 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7543 (clobber (match_scratch:SI 3 "=1"))
7544 (clobber (reg:CC FLAGS_REG))]
7545 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7547 [(set_attr "type" "imul")
7548 (set_attr "length_immediate" "0")
7549 (set (attr "athlon_decode")
7550 (if_then_else (eq_attr "cpu" "athlon")
7551 (const_string "vector")
7552 (const_string "double")))
7553 (set_attr "amdfam10_decode" "double")
7554 (set_attr "mode" "SI")])
7556 (define_insn "*umulsi3_highpart_zext"
7557 [(set (match_operand:DI 0 "register_operand" "=d")
7558 (zero_extend:DI (truncate:SI
7560 (mult:DI (zero_extend:DI
7561 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7563 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7565 (clobber (match_scratch:SI 3 "=1"))
7566 (clobber (reg:CC FLAGS_REG))]
7568 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7570 [(set_attr "type" "imul")
7571 (set_attr "length_immediate" "0")
7572 (set (attr "athlon_decode")
7573 (if_then_else (eq_attr "cpu" "athlon")
7574 (const_string "vector")
7575 (const_string "double")))
7576 (set_attr "amdfam10_decode" "double")
7577 (set_attr "mode" "SI")])
7579 (define_expand "smuldi3_highpart"
7580 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7583 (mult:TI (sign_extend:TI
7584 (match_operand:DI 1 "nonimmediate_operand" ""))
7586 (match_operand:DI 2 "register_operand" "")))
7588 (clobber (match_scratch:DI 3 ""))
7589 (clobber (reg:CC FLAGS_REG))])]
7593 (define_insn "*smuldi3_highpart_rex64"
7594 [(set (match_operand:DI 0 "register_operand" "=d")
7597 (mult:TI (sign_extend:TI
7598 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7600 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7602 (clobber (match_scratch:DI 3 "=1"))
7603 (clobber (reg:CC FLAGS_REG))]
7605 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7607 [(set_attr "type" "imul")
7608 (set (attr "athlon_decode")
7609 (if_then_else (eq_attr "cpu" "athlon")
7610 (const_string "vector")
7611 (const_string "double")))
7612 (set_attr "amdfam10_decode" "double")
7613 (set_attr "mode" "DI")])
7615 (define_expand "smulsi3_highpart"
7616 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7619 (mult:DI (sign_extend:DI
7620 (match_operand:SI 1 "nonimmediate_operand" ""))
7622 (match_operand:SI 2 "register_operand" "")))
7624 (clobber (match_scratch:SI 3 ""))
7625 (clobber (reg:CC FLAGS_REG))])]
7629 (define_insn "*smulsi3_highpart_insn"
7630 [(set (match_operand:SI 0 "register_operand" "=d")
7633 (mult:DI (sign_extend:DI
7634 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7636 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7638 (clobber (match_scratch:SI 3 "=1"))
7639 (clobber (reg:CC FLAGS_REG))]
7640 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7642 [(set_attr "type" "imul")
7643 (set (attr "athlon_decode")
7644 (if_then_else (eq_attr "cpu" "athlon")
7645 (const_string "vector")
7646 (const_string "double")))
7647 (set_attr "amdfam10_decode" "double")
7648 (set_attr "mode" "SI")])
7650 (define_insn "*smulsi3_highpart_zext"
7651 [(set (match_operand:DI 0 "register_operand" "=d")
7652 (zero_extend:DI (truncate:SI
7654 (mult:DI (sign_extend:DI
7655 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7657 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7659 (clobber (match_scratch:SI 3 "=1"))
7660 (clobber (reg:CC FLAGS_REG))]
7662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7664 [(set_attr "type" "imul")
7665 (set (attr "athlon_decode")
7666 (if_then_else (eq_attr "cpu" "athlon")
7667 (const_string "vector")
7668 (const_string "double")))
7669 (set_attr "amdfam10_decode" "double")
7670 (set_attr "mode" "SI")])
7672 ;; The patterns that match these are at the end of this file.
7674 (define_expand "mulxf3"
7675 [(set (match_operand:XF 0 "register_operand" "")
7676 (mult:XF (match_operand:XF 1 "register_operand" "")
7677 (match_operand:XF 2 "register_operand" "")))]
7681 (define_expand "muldf3"
7682 [(set (match_operand:DF 0 "register_operand" "")
7683 (mult:DF (match_operand:DF 1 "register_operand" "")
7684 (match_operand:DF 2 "nonimmediate_operand" "")))]
7685 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7688 (define_expand "mulsf3"
7689 [(set (match_operand:SF 0 "register_operand" "")
7690 (mult:SF (match_operand:SF 1 "register_operand" "")
7691 (match_operand:SF 2 "nonimmediate_operand" "")))]
7692 "TARGET_80387 || TARGET_SSE_MATH"
7695 ;; Divide instructions
7697 (define_insn "divqi3"
7698 [(set (match_operand:QI 0 "register_operand" "=a")
7699 (div:QI (match_operand:HI 1 "register_operand" "0")
7700 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7701 (clobber (reg:CC FLAGS_REG))]
7702 "TARGET_QIMODE_MATH"
7704 [(set_attr "type" "idiv")
7705 (set_attr "mode" "QI")])
7707 (define_insn "udivqi3"
7708 [(set (match_operand:QI 0 "register_operand" "=a")
7709 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7710 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7711 (clobber (reg:CC FLAGS_REG))]
7712 "TARGET_QIMODE_MATH"
7714 [(set_attr "type" "idiv")
7715 (set_attr "mode" "QI")])
7717 ;; The patterns that match these are at the end of this file.
7719 (define_expand "divxf3"
7720 [(set (match_operand:XF 0 "register_operand" "")
7721 (div:XF (match_operand:XF 1 "register_operand" "")
7722 (match_operand:XF 2 "register_operand" "")))]
7726 (define_expand "divdf3"
7727 [(set (match_operand:DF 0 "register_operand" "")
7728 (div:DF (match_operand:DF 1 "register_operand" "")
7729 (match_operand:DF 2 "nonimmediate_operand" "")))]
7730 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7733 (define_expand "divsf3"
7734 [(set (match_operand:SF 0 "register_operand" "")
7735 (div:SF (match_operand:SF 1 "register_operand" "")
7736 (match_operand:SF 2 "nonimmediate_operand" "")))]
7737 "TARGET_80387 || TARGET_SSE_MATH"
7740 ;; Remainder instructions.
7742 (define_expand "divmoddi4"
7743 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7744 (div:DI (match_operand:DI 1 "register_operand" "")
7745 (match_operand:DI 2 "nonimmediate_operand" "")))
7746 (set (match_operand:DI 3 "register_operand" "")
7747 (mod:DI (match_dup 1) (match_dup 2)))
7748 (clobber (reg:CC FLAGS_REG))])]
7752 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7753 ;; Penalize eax case slightly because it results in worse scheduling
7755 (define_insn "*divmoddi4_nocltd_rex64"
7756 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7757 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7758 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7759 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7760 (mod:DI (match_dup 2) (match_dup 3)))
7761 (clobber (reg:CC FLAGS_REG))]
7762 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7764 [(set_attr "type" "multi")])
7766 (define_insn "*divmoddi4_cltd_rex64"
7767 [(set (match_operand:DI 0 "register_operand" "=a")
7768 (div:DI (match_operand:DI 2 "register_operand" "a")
7769 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7770 (set (match_operand:DI 1 "register_operand" "=&d")
7771 (mod:DI (match_dup 2) (match_dup 3)))
7772 (clobber (reg:CC FLAGS_REG))]
7773 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7775 [(set_attr "type" "multi")])
7777 (define_insn "*divmoddi_noext_rex64"
7778 [(set (match_operand:DI 0 "register_operand" "=a")
7779 (div:DI (match_operand:DI 1 "register_operand" "0")
7780 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7781 (set (match_operand:DI 3 "register_operand" "=d")
7782 (mod:DI (match_dup 1) (match_dup 2)))
7783 (use (match_operand:DI 4 "register_operand" "3"))
7784 (clobber (reg:CC FLAGS_REG))]
7787 [(set_attr "type" "idiv")
7788 (set_attr "mode" "DI")])
7791 [(set (match_operand:DI 0 "register_operand" "")
7792 (div:DI (match_operand:DI 1 "register_operand" "")
7793 (match_operand:DI 2 "nonimmediate_operand" "")))
7794 (set (match_operand:DI 3 "register_operand" "")
7795 (mod:DI (match_dup 1) (match_dup 2)))
7796 (clobber (reg:CC FLAGS_REG))]
7797 "TARGET_64BIT && reload_completed"
7798 [(parallel [(set (match_dup 3)
7799 (ashiftrt:DI (match_dup 4) (const_int 63)))
7800 (clobber (reg:CC FLAGS_REG))])
7801 (parallel [(set (match_dup 0)
7802 (div:DI (reg:DI 0) (match_dup 2)))
7804 (mod:DI (reg:DI 0) (match_dup 2)))
7806 (clobber (reg:CC FLAGS_REG))])]
7808 /* Avoid use of cltd in favor of a mov+shift. */
7809 if (!TARGET_USE_CLTD && !optimize_size)
7811 if (true_regnum (operands[1]))
7812 emit_move_insn (operands[0], operands[1]);
7814 emit_move_insn (operands[3], operands[1]);
7815 operands[4] = operands[3];
7819 gcc_assert (!true_regnum (operands[1]));
7820 operands[4] = operands[1];
7825 (define_expand "divmodsi4"
7826 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7827 (div:SI (match_operand:SI 1 "register_operand" "")
7828 (match_operand:SI 2 "nonimmediate_operand" "")))
7829 (set (match_operand:SI 3 "register_operand" "")
7830 (mod:SI (match_dup 1) (match_dup 2)))
7831 (clobber (reg:CC FLAGS_REG))])]
7835 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7836 ;; Penalize eax case slightly because it results in worse scheduling
7838 (define_insn "*divmodsi4_nocltd"
7839 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7840 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7841 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7842 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7843 (mod:SI (match_dup 2) (match_dup 3)))
7844 (clobber (reg:CC FLAGS_REG))]
7845 "!optimize_size && !TARGET_USE_CLTD"
7847 [(set_attr "type" "multi")])
7849 (define_insn "*divmodsi4_cltd"
7850 [(set (match_operand:SI 0 "register_operand" "=a")
7851 (div:SI (match_operand:SI 2 "register_operand" "a")
7852 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7853 (set (match_operand:SI 1 "register_operand" "=&d")
7854 (mod:SI (match_dup 2) (match_dup 3)))
7855 (clobber (reg:CC FLAGS_REG))]
7856 "optimize_size || TARGET_USE_CLTD"
7858 [(set_attr "type" "multi")])
7860 (define_insn "*divmodsi_noext"
7861 [(set (match_operand:SI 0 "register_operand" "=a")
7862 (div:SI (match_operand:SI 1 "register_operand" "0")
7863 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7864 (set (match_operand:SI 3 "register_operand" "=d")
7865 (mod:SI (match_dup 1) (match_dup 2)))
7866 (use (match_operand:SI 4 "register_operand" "3"))
7867 (clobber (reg:CC FLAGS_REG))]
7870 [(set_attr "type" "idiv")
7871 (set_attr "mode" "SI")])
7874 [(set (match_operand:SI 0 "register_operand" "")
7875 (div:SI (match_operand:SI 1 "register_operand" "")
7876 (match_operand:SI 2 "nonimmediate_operand" "")))
7877 (set (match_operand:SI 3 "register_operand" "")
7878 (mod:SI (match_dup 1) (match_dup 2)))
7879 (clobber (reg:CC FLAGS_REG))]
7881 [(parallel [(set (match_dup 3)
7882 (ashiftrt:SI (match_dup 4) (const_int 31)))
7883 (clobber (reg:CC FLAGS_REG))])
7884 (parallel [(set (match_dup 0)
7885 (div:SI (reg:SI 0) (match_dup 2)))
7887 (mod:SI (reg:SI 0) (match_dup 2)))
7889 (clobber (reg:CC FLAGS_REG))])]
7891 /* Avoid use of cltd in favor of a mov+shift. */
7892 if (!TARGET_USE_CLTD && !optimize_size)
7894 if (true_regnum (operands[1]))
7895 emit_move_insn (operands[0], operands[1]);
7897 emit_move_insn (operands[3], operands[1]);
7898 operands[4] = operands[3];
7902 gcc_assert (!true_regnum (operands[1]));
7903 operands[4] = operands[1];
7907 (define_insn "divmodhi4"
7908 [(set (match_operand:HI 0 "register_operand" "=a")
7909 (div:HI (match_operand:HI 1 "register_operand" "0")
7910 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7911 (set (match_operand:HI 3 "register_operand" "=&d")
7912 (mod:HI (match_dup 1) (match_dup 2)))
7913 (clobber (reg:CC FLAGS_REG))]
7914 "TARGET_HIMODE_MATH"
7916 [(set_attr "type" "multi")
7917 (set_attr "length_immediate" "0")
7918 (set_attr "mode" "SI")])
7920 (define_insn "udivmoddi4"
7921 [(set (match_operand:DI 0 "register_operand" "=a")
7922 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7923 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7924 (set (match_operand:DI 3 "register_operand" "=&d")
7925 (umod:DI (match_dup 1) (match_dup 2)))
7926 (clobber (reg:CC FLAGS_REG))]
7928 "xor{q}\t%3, %3\;div{q}\t%2"
7929 [(set_attr "type" "multi")
7930 (set_attr "length_immediate" "0")
7931 (set_attr "mode" "DI")])
7933 (define_insn "*udivmoddi4_noext"
7934 [(set (match_operand:DI 0 "register_operand" "=a")
7935 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7936 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7937 (set (match_operand:DI 3 "register_operand" "=d")
7938 (umod:DI (match_dup 1) (match_dup 2)))
7940 (clobber (reg:CC FLAGS_REG))]
7943 [(set_attr "type" "idiv")
7944 (set_attr "mode" "DI")])
7947 [(set (match_operand:DI 0 "register_operand" "")
7948 (udiv:DI (match_operand:DI 1 "register_operand" "")
7949 (match_operand:DI 2 "nonimmediate_operand" "")))
7950 (set (match_operand:DI 3 "register_operand" "")
7951 (umod:DI (match_dup 1) (match_dup 2)))
7952 (clobber (reg:CC FLAGS_REG))]
7953 "TARGET_64BIT && reload_completed"
7954 [(set (match_dup 3) (const_int 0))
7955 (parallel [(set (match_dup 0)
7956 (udiv:DI (match_dup 1) (match_dup 2)))
7958 (umod:DI (match_dup 1) (match_dup 2)))
7960 (clobber (reg:CC FLAGS_REG))])]
7963 (define_insn "udivmodsi4"
7964 [(set (match_operand:SI 0 "register_operand" "=a")
7965 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7966 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7967 (set (match_operand:SI 3 "register_operand" "=&d")
7968 (umod:SI (match_dup 1) (match_dup 2)))
7969 (clobber (reg:CC FLAGS_REG))]
7971 "xor{l}\t%3, %3\;div{l}\t%2"
7972 [(set_attr "type" "multi")
7973 (set_attr "length_immediate" "0")
7974 (set_attr "mode" "SI")])
7976 (define_insn "*udivmodsi4_noext"
7977 [(set (match_operand:SI 0 "register_operand" "=a")
7978 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7979 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7980 (set (match_operand:SI 3 "register_operand" "=d")
7981 (umod:SI (match_dup 1) (match_dup 2)))
7983 (clobber (reg:CC FLAGS_REG))]
7986 [(set_attr "type" "idiv")
7987 (set_attr "mode" "SI")])
7990 [(set (match_operand:SI 0 "register_operand" "")
7991 (udiv:SI (match_operand:SI 1 "register_operand" "")
7992 (match_operand:SI 2 "nonimmediate_operand" "")))
7993 (set (match_operand:SI 3 "register_operand" "")
7994 (umod:SI (match_dup 1) (match_dup 2)))
7995 (clobber (reg:CC FLAGS_REG))]
7997 [(set (match_dup 3) (const_int 0))
7998 (parallel [(set (match_dup 0)
7999 (udiv:SI (match_dup 1) (match_dup 2)))
8001 (umod:SI (match_dup 1) (match_dup 2)))
8003 (clobber (reg:CC FLAGS_REG))])]
8006 (define_expand "udivmodhi4"
8007 [(set (match_dup 4) (const_int 0))
8008 (parallel [(set (match_operand:HI 0 "register_operand" "")
8009 (udiv:HI (match_operand:HI 1 "register_operand" "")
8010 (match_operand:HI 2 "nonimmediate_operand" "")))
8011 (set (match_operand:HI 3 "register_operand" "")
8012 (umod:HI (match_dup 1) (match_dup 2)))
8014 (clobber (reg:CC FLAGS_REG))])]
8015 "TARGET_HIMODE_MATH"
8016 "operands[4] = gen_reg_rtx (HImode);")
8018 (define_insn "*udivmodhi_noext"
8019 [(set (match_operand:HI 0 "register_operand" "=a")
8020 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8021 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8022 (set (match_operand:HI 3 "register_operand" "=d")
8023 (umod:HI (match_dup 1) (match_dup 2)))
8024 (use (match_operand:HI 4 "register_operand" "3"))
8025 (clobber (reg:CC FLAGS_REG))]
8028 [(set_attr "type" "idiv")
8029 (set_attr "mode" "HI")])
8031 ;; We cannot use div/idiv for double division, because it causes
8032 ;; "division by zero" on the overflow and that's not what we expect
8033 ;; from truncate. Because true (non truncating) double division is
8034 ;; never generated, we can't create this insn anyway.
8037 ; [(set (match_operand:SI 0 "register_operand" "=a")
8039 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8041 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8042 ; (set (match_operand:SI 3 "register_operand" "=d")
8044 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8045 ; (clobber (reg:CC FLAGS_REG))]
8047 ; "div{l}\t{%2, %0|%0, %2}"
8048 ; [(set_attr "type" "idiv")])
8050 ;;- Logical AND instructions
8052 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8053 ;; Note that this excludes ah.
8055 (define_insn "*testdi_1_rex64"
8056 [(set (reg FLAGS_REG)
8058 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8059 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8061 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8062 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8064 test{l}\t{%k1, %k0|%k0, %k1}
8065 test{l}\t{%k1, %k0|%k0, %k1}
8066 test{q}\t{%1, %0|%0, %1}
8067 test{q}\t{%1, %0|%0, %1}
8068 test{q}\t{%1, %0|%0, %1}"
8069 [(set_attr "type" "test")
8070 (set_attr "modrm" "0,1,0,1,1")
8071 (set_attr "mode" "SI,SI,DI,DI,DI")
8072 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8074 (define_insn "testsi_1"
8075 [(set (reg FLAGS_REG)
8077 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8078 (match_operand:SI 1 "general_operand" "in,in,rin"))
8080 "ix86_match_ccmode (insn, CCNOmode)
8081 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8082 "test{l}\t{%1, %0|%0, %1}"
8083 [(set_attr "type" "test")
8084 (set_attr "modrm" "0,1,1")
8085 (set_attr "mode" "SI")
8086 (set_attr "pent_pair" "uv,np,uv")])
8088 (define_expand "testsi_ccno_1"
8089 [(set (reg:CCNO FLAGS_REG)
8091 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8092 (match_operand:SI 1 "nonmemory_operand" ""))
8097 (define_insn "*testhi_1"
8098 [(set (reg FLAGS_REG)
8099 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8100 (match_operand:HI 1 "general_operand" "n,n,rn"))
8102 "ix86_match_ccmode (insn, CCNOmode)
8103 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8104 "test{w}\t{%1, %0|%0, %1}"
8105 [(set_attr "type" "test")
8106 (set_attr "modrm" "0,1,1")
8107 (set_attr "mode" "HI")
8108 (set_attr "pent_pair" "uv,np,uv")])
8110 (define_expand "testqi_ccz_1"
8111 [(set (reg:CCZ FLAGS_REG)
8112 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8113 (match_operand:QI 1 "nonmemory_operand" ""))
8118 (define_insn "*testqi_1_maybe_si"
8119 [(set (reg FLAGS_REG)
8122 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8123 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8125 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8126 && ix86_match_ccmode (insn,
8127 CONST_INT_P (operands[1])
8128 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8130 if (which_alternative == 3)
8132 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8133 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8134 return "test{l}\t{%1, %k0|%k0, %1}";
8136 return "test{b}\t{%1, %0|%0, %1}";
8138 [(set_attr "type" "test")
8139 (set_attr "modrm" "0,1,1,1")
8140 (set_attr "mode" "QI,QI,QI,SI")
8141 (set_attr "pent_pair" "uv,np,uv,np")])
8143 (define_insn "*testqi_1"
8144 [(set (reg FLAGS_REG)
8147 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8148 (match_operand:QI 1 "general_operand" "n,n,qn"))
8150 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8151 && ix86_match_ccmode (insn, CCNOmode)"
8152 "test{b}\t{%1, %0|%0, %1}"
8153 [(set_attr "type" "test")
8154 (set_attr "modrm" "0,1,1")
8155 (set_attr "mode" "QI")
8156 (set_attr "pent_pair" "uv,np,uv")])
8158 (define_expand "testqi_ext_ccno_0"
8159 [(set (reg:CCNO FLAGS_REG)
8163 (match_operand 0 "ext_register_operand" "")
8166 (match_operand 1 "const_int_operand" ""))
8171 (define_insn "*testqi_ext_0"
8172 [(set (reg FLAGS_REG)
8176 (match_operand 0 "ext_register_operand" "Q")
8179 (match_operand 1 "const_int_operand" "n"))
8181 "ix86_match_ccmode (insn, CCNOmode)"
8182 "test{b}\t{%1, %h0|%h0, %1}"
8183 [(set_attr "type" "test")
8184 (set_attr "mode" "QI")
8185 (set_attr "length_immediate" "1")
8186 (set_attr "pent_pair" "np")])
8188 (define_insn "*testqi_ext_1"
8189 [(set (reg FLAGS_REG)
8193 (match_operand 0 "ext_register_operand" "Q")
8197 (match_operand:QI 1 "general_operand" "Qm")))
8199 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8200 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8201 "test{b}\t{%1, %h0|%h0, %1}"
8202 [(set_attr "type" "test")
8203 (set_attr "mode" "QI")])
8205 (define_insn "*testqi_ext_1_rex64"
8206 [(set (reg FLAGS_REG)
8210 (match_operand 0 "ext_register_operand" "Q")
8214 (match_operand:QI 1 "register_operand" "Q")))
8216 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8217 "test{b}\t{%1, %h0|%h0, %1}"
8218 [(set_attr "type" "test")
8219 (set_attr "mode" "QI")])
8221 (define_insn "*testqi_ext_2"
8222 [(set (reg FLAGS_REG)
8226 (match_operand 0 "ext_register_operand" "Q")
8230 (match_operand 1 "ext_register_operand" "Q")
8234 "ix86_match_ccmode (insn, CCNOmode)"
8235 "test{b}\t{%h1, %h0|%h0, %h1}"
8236 [(set_attr "type" "test")
8237 (set_attr "mode" "QI")])
8239 ;; Combine likes to form bit extractions for some tests. Humor it.
8240 (define_insn "*testqi_ext_3"
8241 [(set (reg FLAGS_REG)
8242 (compare (zero_extract:SI
8243 (match_operand 0 "nonimmediate_operand" "rm")
8244 (match_operand:SI 1 "const_int_operand" "")
8245 (match_operand:SI 2 "const_int_operand" ""))
8247 "ix86_match_ccmode (insn, CCNOmode)
8248 && INTVAL (operands[1]) > 0
8249 && INTVAL (operands[2]) >= 0
8250 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8251 && (GET_MODE (operands[0]) == SImode
8252 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8253 || GET_MODE (operands[0]) == HImode
8254 || GET_MODE (operands[0]) == QImode)"
8257 (define_insn "*testqi_ext_3_rex64"
8258 [(set (reg FLAGS_REG)
8259 (compare (zero_extract:DI
8260 (match_operand 0 "nonimmediate_operand" "rm")
8261 (match_operand:DI 1 "const_int_operand" "")
8262 (match_operand:DI 2 "const_int_operand" ""))
8265 && ix86_match_ccmode (insn, CCNOmode)
8266 && INTVAL (operands[1]) > 0
8267 && INTVAL (operands[2]) >= 0
8268 /* Ensure that resulting mask is zero or sign extended operand. */
8269 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8270 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8271 && INTVAL (operands[1]) > 32))
8272 && (GET_MODE (operands[0]) == SImode
8273 || GET_MODE (operands[0]) == DImode
8274 || GET_MODE (operands[0]) == HImode
8275 || GET_MODE (operands[0]) == QImode)"
8279 [(set (match_operand 0 "flags_reg_operand" "")
8280 (match_operator 1 "compare_operator"
8282 (match_operand 2 "nonimmediate_operand" "")
8283 (match_operand 3 "const_int_operand" "")
8284 (match_operand 4 "const_int_operand" ""))
8286 "ix86_match_ccmode (insn, CCNOmode)"
8287 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8289 rtx val = operands[2];
8290 HOST_WIDE_INT len = INTVAL (operands[3]);
8291 HOST_WIDE_INT pos = INTVAL (operands[4]);
8293 enum machine_mode mode, submode;
8295 mode = GET_MODE (val);
8298 /* ??? Combine likes to put non-volatile mem extractions in QImode
8299 no matter the size of the test. So find a mode that works. */
8300 if (! MEM_VOLATILE_P (val))
8302 mode = smallest_mode_for_size (pos + len, MODE_INT);
8303 val = adjust_address (val, mode, 0);
8306 else if (GET_CODE (val) == SUBREG
8307 && (submode = GET_MODE (SUBREG_REG (val)),
8308 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8309 && pos + len <= GET_MODE_BITSIZE (submode))
8311 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8313 val = SUBREG_REG (val);
8315 else if (mode == HImode && pos + len <= 8)
8317 /* Small HImode tests can be converted to QImode. */
8319 val = gen_lowpart (QImode, val);
8322 if (len == HOST_BITS_PER_WIDE_INT)
8325 mask = ((HOST_WIDE_INT)1 << len) - 1;
8328 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8331 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8332 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8333 ;; this is relatively important trick.
8334 ;; Do the conversion only post-reload to avoid limiting of the register class
8337 [(set (match_operand 0 "flags_reg_operand" "")
8338 (match_operator 1 "compare_operator"
8339 [(and (match_operand 2 "register_operand" "")
8340 (match_operand 3 "const_int_operand" ""))
8343 && QI_REG_P (operands[2])
8344 && GET_MODE (operands[2]) != QImode
8345 && ((ix86_match_ccmode (insn, CCZmode)
8346 && !(INTVAL (operands[3]) & ~(255 << 8)))
8347 || (ix86_match_ccmode (insn, CCNOmode)
8348 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8351 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8354 "operands[2] = gen_lowpart (SImode, operands[2]);
8355 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8358 [(set (match_operand 0 "flags_reg_operand" "")
8359 (match_operator 1 "compare_operator"
8360 [(and (match_operand 2 "nonimmediate_operand" "")
8361 (match_operand 3 "const_int_operand" ""))
8364 && GET_MODE (operands[2]) != QImode
8365 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8366 && ((ix86_match_ccmode (insn, CCZmode)
8367 && !(INTVAL (operands[3]) & ~255))
8368 || (ix86_match_ccmode (insn, CCNOmode)
8369 && !(INTVAL (operands[3]) & ~127)))"
8371 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8373 "operands[2] = gen_lowpart (QImode, operands[2]);
8374 operands[3] = gen_lowpart (QImode, operands[3]);")
8377 ;; %%% This used to optimize known byte-wide and operations to memory,
8378 ;; and sometimes to QImode registers. If this is considered useful,
8379 ;; it should be done with splitters.
8381 (define_expand "anddi3"
8382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8383 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8384 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8385 (clobber (reg:CC FLAGS_REG))]
8387 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8389 (define_insn "*anddi_1_rex64"
8390 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8391 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8392 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8393 (clobber (reg:CC FLAGS_REG))]
8394 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8396 switch (get_attr_type (insn))
8400 enum machine_mode mode;
8402 gcc_assert (CONST_INT_P (operands[2]));
8403 if (INTVAL (operands[2]) == 0xff)
8407 gcc_assert (INTVAL (operands[2]) == 0xffff);
8411 operands[1] = gen_lowpart (mode, operands[1]);
8413 return "movz{bq|x}\t{%1,%0|%0, %1}";
8415 return "movz{wq|x}\t{%1,%0|%0, %1}";
8419 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8420 if (get_attr_mode (insn) == MODE_SI)
8421 return "and{l}\t{%k2, %k0|%k0, %k2}";
8423 return "and{q}\t{%2, %0|%0, %2}";
8426 [(set_attr "type" "alu,alu,alu,imovx")
8427 (set_attr "length_immediate" "*,*,*,0")
8428 (set_attr "mode" "SI,DI,DI,DI")])
8430 (define_insn "*anddi_2"
8431 [(set (reg FLAGS_REG)
8432 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8433 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8435 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8436 (and:DI (match_dup 1) (match_dup 2)))]
8437 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8438 && ix86_binary_operator_ok (AND, DImode, operands)"
8440 and{l}\t{%k2, %k0|%k0, %k2}
8441 and{q}\t{%2, %0|%0, %2}
8442 and{q}\t{%2, %0|%0, %2}"
8443 [(set_attr "type" "alu")
8444 (set_attr "mode" "SI,DI,DI")])
8446 (define_expand "andsi3"
8447 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8448 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8449 (match_operand:SI 2 "general_operand" "")))
8450 (clobber (reg:CC FLAGS_REG))]
8452 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8454 (define_insn "*andsi_1"
8455 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8456 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8457 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8458 (clobber (reg:CC FLAGS_REG))]
8459 "ix86_binary_operator_ok (AND, SImode, operands)"
8461 switch (get_attr_type (insn))
8465 enum machine_mode mode;
8467 gcc_assert (CONST_INT_P (operands[2]));
8468 if (INTVAL (operands[2]) == 0xff)
8472 gcc_assert (INTVAL (operands[2]) == 0xffff);
8476 operands[1] = gen_lowpart (mode, operands[1]);
8478 return "movz{bl|x}\t{%1,%0|%0, %1}";
8480 return "movz{wl|x}\t{%1,%0|%0, %1}";
8484 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8485 return "and{l}\t{%2, %0|%0, %2}";
8488 [(set_attr "type" "alu,alu,imovx")
8489 (set_attr "length_immediate" "*,*,0")
8490 (set_attr "mode" "SI")])
8493 [(set (match_operand 0 "register_operand" "")
8495 (const_int -65536)))
8496 (clobber (reg:CC FLAGS_REG))]
8497 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8498 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8499 "operands[1] = gen_lowpart (HImode, operands[0]);")
8502 [(set (match_operand 0 "ext_register_operand" "")
8505 (clobber (reg:CC FLAGS_REG))]
8506 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8507 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8508 "operands[1] = gen_lowpart (QImode, operands[0]);")
8511 [(set (match_operand 0 "ext_register_operand" "")
8513 (const_int -65281)))
8514 (clobber (reg:CC FLAGS_REG))]
8515 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8516 [(parallel [(set (zero_extract:SI (match_dup 0)
8520 (zero_extract:SI (match_dup 0)
8523 (zero_extract:SI (match_dup 0)
8526 (clobber (reg:CC FLAGS_REG))])]
8527 "operands[0] = gen_lowpart (SImode, operands[0]);")
8529 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8530 (define_insn "*andsi_1_zext"
8531 [(set (match_operand:DI 0 "register_operand" "=r")
8533 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8534 (match_operand:SI 2 "general_operand" "rim"))))
8535 (clobber (reg:CC FLAGS_REG))]
8536 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8537 "and{l}\t{%2, %k0|%k0, %2}"
8538 [(set_attr "type" "alu")
8539 (set_attr "mode" "SI")])
8541 (define_insn "*andsi_2"
8542 [(set (reg FLAGS_REG)
8543 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8544 (match_operand:SI 2 "general_operand" "rim,ri"))
8546 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8547 (and:SI (match_dup 1) (match_dup 2)))]
8548 "ix86_match_ccmode (insn, CCNOmode)
8549 && ix86_binary_operator_ok (AND, SImode, operands)"
8550 "and{l}\t{%2, %0|%0, %2}"
8551 [(set_attr "type" "alu")
8552 (set_attr "mode" "SI")])
8554 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8555 (define_insn "*andsi_2_zext"
8556 [(set (reg FLAGS_REG)
8557 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8558 (match_operand:SI 2 "general_operand" "rim"))
8560 (set (match_operand:DI 0 "register_operand" "=r")
8561 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8562 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8563 && ix86_binary_operator_ok (AND, SImode, operands)"
8564 "and{l}\t{%2, %k0|%k0, %2}"
8565 [(set_attr "type" "alu")
8566 (set_attr "mode" "SI")])
8568 (define_expand "andhi3"
8569 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8570 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8571 (match_operand:HI 2 "general_operand" "")))
8572 (clobber (reg:CC FLAGS_REG))]
8573 "TARGET_HIMODE_MATH"
8574 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8576 (define_insn "*andhi_1"
8577 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8578 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8579 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "ix86_binary_operator_ok (AND, HImode, operands)"
8583 switch (get_attr_type (insn))
8586 gcc_assert (CONST_INT_P (operands[2]));
8587 gcc_assert (INTVAL (operands[2]) == 0xff);
8588 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8593 return "and{w}\t{%2, %0|%0, %2}";
8596 [(set_attr "type" "alu,alu,imovx")
8597 (set_attr "length_immediate" "*,*,0")
8598 (set_attr "mode" "HI,HI,SI")])
8600 (define_insn "*andhi_2"
8601 [(set (reg FLAGS_REG)
8602 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8603 (match_operand:HI 2 "general_operand" "rim,ri"))
8605 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8606 (and:HI (match_dup 1) (match_dup 2)))]
8607 "ix86_match_ccmode (insn, CCNOmode)
8608 && ix86_binary_operator_ok (AND, HImode, operands)"
8609 "and{w}\t{%2, %0|%0, %2}"
8610 [(set_attr "type" "alu")
8611 (set_attr "mode" "HI")])
8613 (define_expand "andqi3"
8614 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8615 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8616 (match_operand:QI 2 "general_operand" "")))
8617 (clobber (reg:CC FLAGS_REG))]
8618 "TARGET_QIMODE_MATH"
8619 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8621 ;; %%% Potential partial reg stall on alternative 2. What to do?
8622 (define_insn "*andqi_1"
8623 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8624 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8625 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8626 (clobber (reg:CC FLAGS_REG))]
8627 "ix86_binary_operator_ok (AND, QImode, operands)"
8629 and{b}\t{%2, %0|%0, %2}
8630 and{b}\t{%2, %0|%0, %2}
8631 and{l}\t{%k2, %k0|%k0, %k2}"
8632 [(set_attr "type" "alu")
8633 (set_attr "mode" "QI,QI,SI")])
8635 (define_insn "*andqi_1_slp"
8636 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8637 (and:QI (match_dup 0)
8638 (match_operand:QI 1 "general_operand" "qi,qmi")))
8639 (clobber (reg:CC FLAGS_REG))]
8640 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8641 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8642 "and{b}\t{%1, %0|%0, %1}"
8643 [(set_attr "type" "alu1")
8644 (set_attr "mode" "QI")])
8646 (define_insn "*andqi_2_maybe_si"
8647 [(set (reg FLAGS_REG)
8649 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8650 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8652 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8653 (and:QI (match_dup 1) (match_dup 2)))]
8654 "ix86_binary_operator_ok (AND, QImode, operands)
8655 && ix86_match_ccmode (insn,
8656 CONST_INT_P (operands[2])
8657 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8659 if (which_alternative == 2)
8661 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8662 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8663 return "and{l}\t{%2, %k0|%k0, %2}";
8665 return "and{b}\t{%2, %0|%0, %2}";
8667 [(set_attr "type" "alu")
8668 (set_attr "mode" "QI,QI,SI")])
8670 (define_insn "*andqi_2"
8671 [(set (reg FLAGS_REG)
8673 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8674 (match_operand:QI 2 "general_operand" "qim,qi"))
8676 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8677 (and:QI (match_dup 1) (match_dup 2)))]
8678 "ix86_match_ccmode (insn, CCNOmode)
8679 && ix86_binary_operator_ok (AND, QImode, operands)"
8680 "and{b}\t{%2, %0|%0, %2}"
8681 [(set_attr "type" "alu")
8682 (set_attr "mode" "QI")])
8684 (define_insn "*andqi_2_slp"
8685 [(set (reg FLAGS_REG)
8687 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8688 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8690 (set (strict_low_part (match_dup 0))
8691 (and:QI (match_dup 0) (match_dup 1)))]
8692 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8693 && ix86_match_ccmode (insn, CCNOmode)
8694 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8695 "and{b}\t{%1, %0|%0, %1}"
8696 [(set_attr "type" "alu1")
8697 (set_attr "mode" "QI")])
8699 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8700 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8701 ;; for a QImode operand, which of course failed.
8703 (define_insn "andqi_ext_0"
8704 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8709 (match_operand 1 "ext_register_operand" "0")
8712 (match_operand 2 "const_int_operand" "n")))
8713 (clobber (reg:CC FLAGS_REG))]
8715 "and{b}\t{%2, %h0|%h0, %2}"
8716 [(set_attr "type" "alu")
8717 (set_attr "length_immediate" "1")
8718 (set_attr "mode" "QI")])
8720 ;; Generated by peephole translating test to and. This shows up
8721 ;; often in fp comparisons.
8723 (define_insn "*andqi_ext_0_cc"
8724 [(set (reg FLAGS_REG)
8728 (match_operand 1 "ext_register_operand" "0")
8731 (match_operand 2 "const_int_operand" "n"))
8733 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8742 "ix86_match_ccmode (insn, CCNOmode)"
8743 "and{b}\t{%2, %h0|%h0, %2}"
8744 [(set_attr "type" "alu")
8745 (set_attr "length_immediate" "1")
8746 (set_attr "mode" "QI")])
8748 (define_insn "*andqi_ext_1"
8749 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8754 (match_operand 1 "ext_register_operand" "0")
8758 (match_operand:QI 2 "general_operand" "Qm"))))
8759 (clobber (reg:CC FLAGS_REG))]
8761 "and{b}\t{%2, %h0|%h0, %2}"
8762 [(set_attr "type" "alu")
8763 (set_attr "length_immediate" "0")
8764 (set_attr "mode" "QI")])
8766 (define_insn "*andqi_ext_1_rex64"
8767 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8772 (match_operand 1 "ext_register_operand" "0")
8776 (match_operand 2 "ext_register_operand" "Q"))))
8777 (clobber (reg:CC FLAGS_REG))]
8779 "and{b}\t{%2, %h0|%h0, %2}"
8780 [(set_attr "type" "alu")
8781 (set_attr "length_immediate" "0")
8782 (set_attr "mode" "QI")])
8784 (define_insn "*andqi_ext_2"
8785 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8790 (match_operand 1 "ext_register_operand" "%0")
8794 (match_operand 2 "ext_register_operand" "Q")
8797 (clobber (reg:CC FLAGS_REG))]
8799 "and{b}\t{%h2, %h0|%h0, %h2}"
8800 [(set_attr "type" "alu")
8801 (set_attr "length_immediate" "0")
8802 (set_attr "mode" "QI")])
8804 ;; Convert wide AND instructions with immediate operand to shorter QImode
8805 ;; equivalents when possible.
8806 ;; Don't do the splitting with memory operands, since it introduces risk
8807 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8808 ;; for size, but that can (should?) be handled by generic code instead.
8810 [(set (match_operand 0 "register_operand" "")
8811 (and (match_operand 1 "register_operand" "")
8812 (match_operand 2 "const_int_operand" "")))
8813 (clobber (reg:CC FLAGS_REG))]
8815 && QI_REG_P (operands[0])
8816 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8817 && !(~INTVAL (operands[2]) & ~(255 << 8))
8818 && GET_MODE (operands[0]) != QImode"
8819 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8820 (and:SI (zero_extract:SI (match_dup 1)
8821 (const_int 8) (const_int 8))
8823 (clobber (reg:CC FLAGS_REG))])]
8824 "operands[0] = gen_lowpart (SImode, operands[0]);
8825 operands[1] = gen_lowpart (SImode, operands[1]);
8826 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8828 ;; Since AND can be encoded with sign extended immediate, this is only
8829 ;; profitable when 7th bit is not set.
8831 [(set (match_operand 0 "register_operand" "")
8832 (and (match_operand 1 "general_operand" "")
8833 (match_operand 2 "const_int_operand" "")))
8834 (clobber (reg:CC FLAGS_REG))]
8836 && ANY_QI_REG_P (operands[0])
8837 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8838 && !(~INTVAL (operands[2]) & ~255)
8839 && !(INTVAL (operands[2]) & 128)
8840 && GET_MODE (operands[0]) != QImode"
8841 [(parallel [(set (strict_low_part (match_dup 0))
8842 (and:QI (match_dup 1)
8844 (clobber (reg:CC FLAGS_REG))])]
8845 "operands[0] = gen_lowpart (QImode, operands[0]);
8846 operands[1] = gen_lowpart (QImode, operands[1]);
8847 operands[2] = gen_lowpart (QImode, operands[2]);")
8849 ;; Logical inclusive OR instructions
8851 ;; %%% This used to optimize known byte-wide and operations to memory.
8852 ;; If this is considered useful, it should be done with splitters.
8854 (define_expand "iordi3"
8855 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8856 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8857 (match_operand:DI 2 "x86_64_general_operand" "")))
8858 (clobber (reg:CC FLAGS_REG))]
8860 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8862 (define_insn "*iordi_1_rex64"
8863 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8864 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8865 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8866 (clobber (reg:CC FLAGS_REG))]
8868 && ix86_binary_operator_ok (IOR, DImode, operands)"
8869 "or{q}\t{%2, %0|%0, %2}"
8870 [(set_attr "type" "alu")
8871 (set_attr "mode" "DI")])
8873 (define_insn "*iordi_2_rex64"
8874 [(set (reg FLAGS_REG)
8875 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8876 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8878 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8879 (ior:DI (match_dup 1) (match_dup 2)))]
8881 && ix86_match_ccmode (insn, CCNOmode)
8882 && ix86_binary_operator_ok (IOR, DImode, operands)"
8883 "or{q}\t{%2, %0|%0, %2}"
8884 [(set_attr "type" "alu")
8885 (set_attr "mode" "DI")])
8887 (define_insn "*iordi_3_rex64"
8888 [(set (reg FLAGS_REG)
8889 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8890 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8892 (clobber (match_scratch:DI 0 "=r"))]
8894 && ix86_match_ccmode (insn, CCNOmode)
8895 && ix86_binary_operator_ok (IOR, DImode, operands)"
8896 "or{q}\t{%2, %0|%0, %2}"
8897 [(set_attr "type" "alu")
8898 (set_attr "mode" "DI")])
8901 (define_expand "iorsi3"
8902 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8903 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8904 (match_operand:SI 2 "general_operand" "")))
8905 (clobber (reg:CC FLAGS_REG))]
8907 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8909 (define_insn "*iorsi_1"
8910 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8911 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8912 (match_operand:SI 2 "general_operand" "ri,rmi")))
8913 (clobber (reg:CC FLAGS_REG))]
8914 "ix86_binary_operator_ok (IOR, SImode, operands)"
8915 "or{l}\t{%2, %0|%0, %2}"
8916 [(set_attr "type" "alu")
8917 (set_attr "mode" "SI")])
8919 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8920 (define_insn "*iorsi_1_zext"
8921 [(set (match_operand:DI 0 "register_operand" "=rm")
8923 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8924 (match_operand:SI 2 "general_operand" "rim"))))
8925 (clobber (reg:CC FLAGS_REG))]
8926 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8927 "or{l}\t{%2, %k0|%k0, %2}"
8928 [(set_attr "type" "alu")
8929 (set_attr "mode" "SI")])
8931 (define_insn "*iorsi_1_zext_imm"
8932 [(set (match_operand:DI 0 "register_operand" "=rm")
8933 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8934 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8935 (clobber (reg:CC FLAGS_REG))]
8937 "or{l}\t{%2, %k0|%k0, %2}"
8938 [(set_attr "type" "alu")
8939 (set_attr "mode" "SI")])
8941 (define_insn "*iorsi_2"
8942 [(set (reg FLAGS_REG)
8943 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8944 (match_operand:SI 2 "general_operand" "rim,ri"))
8946 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8947 (ior:SI (match_dup 1) (match_dup 2)))]
8948 "ix86_match_ccmode (insn, CCNOmode)
8949 && ix86_binary_operator_ok (IOR, SImode, operands)"
8950 "or{l}\t{%2, %0|%0, %2}"
8951 [(set_attr "type" "alu")
8952 (set_attr "mode" "SI")])
8954 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8955 ;; ??? Special case for immediate operand is missing - it is tricky.
8956 (define_insn "*iorsi_2_zext"
8957 [(set (reg FLAGS_REG)
8958 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8959 (match_operand:SI 2 "general_operand" "rim"))
8961 (set (match_operand:DI 0 "register_operand" "=r")
8962 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8963 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8964 && ix86_binary_operator_ok (IOR, SImode, operands)"
8965 "or{l}\t{%2, %k0|%k0, %2}"
8966 [(set_attr "type" "alu")
8967 (set_attr "mode" "SI")])
8969 (define_insn "*iorsi_2_zext_imm"
8970 [(set (reg FLAGS_REG)
8971 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8972 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8974 (set (match_operand:DI 0 "register_operand" "=r")
8975 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8976 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8977 && ix86_binary_operator_ok (IOR, SImode, operands)"
8978 "or{l}\t{%2, %k0|%k0, %2}"
8979 [(set_attr "type" "alu")
8980 (set_attr "mode" "SI")])
8982 (define_insn "*iorsi_3"
8983 [(set (reg FLAGS_REG)
8984 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8985 (match_operand:SI 2 "general_operand" "rim"))
8987 (clobber (match_scratch:SI 0 "=r"))]
8988 "ix86_match_ccmode (insn, CCNOmode)
8989 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8990 "or{l}\t{%2, %0|%0, %2}"
8991 [(set_attr "type" "alu")
8992 (set_attr "mode" "SI")])
8994 (define_expand "iorhi3"
8995 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8996 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8997 (match_operand:HI 2 "general_operand" "")))
8998 (clobber (reg:CC FLAGS_REG))]
8999 "TARGET_HIMODE_MATH"
9000 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9002 (define_insn "*iorhi_1"
9003 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9004 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9005 (match_operand:HI 2 "general_operand" "rmi,ri")))
9006 (clobber (reg:CC FLAGS_REG))]
9007 "ix86_binary_operator_ok (IOR, HImode, operands)"
9008 "or{w}\t{%2, %0|%0, %2}"
9009 [(set_attr "type" "alu")
9010 (set_attr "mode" "HI")])
9012 (define_insn "*iorhi_2"
9013 [(set (reg FLAGS_REG)
9014 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9015 (match_operand:HI 2 "general_operand" "rim,ri"))
9017 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9018 (ior:HI (match_dup 1) (match_dup 2)))]
9019 "ix86_match_ccmode (insn, CCNOmode)
9020 && ix86_binary_operator_ok (IOR, HImode, operands)"
9021 "or{w}\t{%2, %0|%0, %2}"
9022 [(set_attr "type" "alu")
9023 (set_attr "mode" "HI")])
9025 (define_insn "*iorhi_3"
9026 [(set (reg FLAGS_REG)
9027 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9028 (match_operand:HI 2 "general_operand" "rim"))
9030 (clobber (match_scratch:HI 0 "=r"))]
9031 "ix86_match_ccmode (insn, CCNOmode)
9032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9033 "or{w}\t{%2, %0|%0, %2}"
9034 [(set_attr "type" "alu")
9035 (set_attr "mode" "HI")])
9037 (define_expand "iorqi3"
9038 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9039 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9040 (match_operand:QI 2 "general_operand" "")))
9041 (clobber (reg:CC FLAGS_REG))]
9042 "TARGET_QIMODE_MATH"
9043 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9045 ;; %%% Potential partial reg stall on alternative 2. What to do?
9046 (define_insn "*iorqi_1"
9047 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9048 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9049 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9050 (clobber (reg:CC FLAGS_REG))]
9051 "ix86_binary_operator_ok (IOR, QImode, operands)"
9053 or{b}\t{%2, %0|%0, %2}
9054 or{b}\t{%2, %0|%0, %2}
9055 or{l}\t{%k2, %k0|%k0, %k2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "mode" "QI,QI,SI")])
9059 (define_insn "*iorqi_1_slp"
9060 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9061 (ior:QI (match_dup 0)
9062 (match_operand:QI 1 "general_operand" "qmi,qi")))
9063 (clobber (reg:CC FLAGS_REG))]
9064 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9065 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9066 "or{b}\t{%1, %0|%0, %1}"
9067 [(set_attr "type" "alu1")
9068 (set_attr "mode" "QI")])
9070 (define_insn "*iorqi_2"
9071 [(set (reg FLAGS_REG)
9072 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9073 (match_operand:QI 2 "general_operand" "qim,qi"))
9075 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9076 (ior:QI (match_dup 1) (match_dup 2)))]
9077 "ix86_match_ccmode (insn, CCNOmode)
9078 && ix86_binary_operator_ok (IOR, QImode, operands)"
9079 "or{b}\t{%2, %0|%0, %2}"
9080 [(set_attr "type" "alu")
9081 (set_attr "mode" "QI")])
9083 (define_insn "*iorqi_2_slp"
9084 [(set (reg FLAGS_REG)
9085 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9086 (match_operand:QI 1 "general_operand" "qim,qi"))
9088 (set (strict_low_part (match_dup 0))
9089 (ior:QI (match_dup 0) (match_dup 1)))]
9090 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9091 && ix86_match_ccmode (insn, CCNOmode)
9092 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9093 "or{b}\t{%1, %0|%0, %1}"
9094 [(set_attr "type" "alu1")
9095 (set_attr "mode" "QI")])
9097 (define_insn "*iorqi_3"
9098 [(set (reg FLAGS_REG)
9099 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9100 (match_operand:QI 2 "general_operand" "qim"))
9102 (clobber (match_scratch:QI 0 "=q"))]
9103 "ix86_match_ccmode (insn, CCNOmode)
9104 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9105 "or{b}\t{%2, %0|%0, %2}"
9106 [(set_attr "type" "alu")
9107 (set_attr "mode" "QI")])
9109 (define_insn "iorqi_ext_0"
9110 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9115 (match_operand 1 "ext_register_operand" "0")
9118 (match_operand 2 "const_int_operand" "n")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9121 "or{b}\t{%2, %h0|%h0, %2}"
9122 [(set_attr "type" "alu")
9123 (set_attr "length_immediate" "1")
9124 (set_attr "mode" "QI")])
9126 (define_insn "*iorqi_ext_1"
9127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9132 (match_operand 1 "ext_register_operand" "0")
9136 (match_operand:QI 2 "general_operand" "Qm"))))
9137 (clobber (reg:CC FLAGS_REG))]
9139 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9140 "or{b}\t{%2, %h0|%h0, %2}"
9141 [(set_attr "type" "alu")
9142 (set_attr "length_immediate" "0")
9143 (set_attr "mode" "QI")])
9145 (define_insn "*iorqi_ext_1_rex64"
9146 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9151 (match_operand 1 "ext_register_operand" "0")
9155 (match_operand 2 "ext_register_operand" "Q"))))
9156 (clobber (reg:CC FLAGS_REG))]
9158 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9159 "or{b}\t{%2, %h0|%h0, %2}"
9160 [(set_attr "type" "alu")
9161 (set_attr "length_immediate" "0")
9162 (set_attr "mode" "QI")])
9164 (define_insn "*iorqi_ext_2"
9165 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9169 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9172 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9175 (clobber (reg:CC FLAGS_REG))]
9176 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9177 "ior{b}\t{%h2, %h0|%h0, %h2}"
9178 [(set_attr "type" "alu")
9179 (set_attr "length_immediate" "0")
9180 (set_attr "mode" "QI")])
9183 [(set (match_operand 0 "register_operand" "")
9184 (ior (match_operand 1 "register_operand" "")
9185 (match_operand 2 "const_int_operand" "")))
9186 (clobber (reg:CC FLAGS_REG))]
9188 && QI_REG_P (operands[0])
9189 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9190 && !(INTVAL (operands[2]) & ~(255 << 8))
9191 && GET_MODE (operands[0]) != QImode"
9192 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9193 (ior:SI (zero_extract:SI (match_dup 1)
9194 (const_int 8) (const_int 8))
9196 (clobber (reg:CC FLAGS_REG))])]
9197 "operands[0] = gen_lowpart (SImode, operands[0]);
9198 operands[1] = gen_lowpart (SImode, operands[1]);
9199 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9201 ;; Since OR can be encoded with sign extended immediate, this is only
9202 ;; profitable when 7th bit is set.
9204 [(set (match_operand 0 "register_operand" "")
9205 (ior (match_operand 1 "general_operand" "")
9206 (match_operand 2 "const_int_operand" "")))
9207 (clobber (reg:CC FLAGS_REG))]
9209 && ANY_QI_REG_P (operands[0])
9210 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9211 && !(INTVAL (operands[2]) & ~255)
9212 && (INTVAL (operands[2]) & 128)
9213 && GET_MODE (operands[0]) != QImode"
9214 [(parallel [(set (strict_low_part (match_dup 0))
9215 (ior:QI (match_dup 1)
9217 (clobber (reg:CC FLAGS_REG))])]
9218 "operands[0] = gen_lowpart (QImode, operands[0]);
9219 operands[1] = gen_lowpart (QImode, operands[1]);
9220 operands[2] = gen_lowpart (QImode, operands[2]);")
9222 ;; Logical XOR instructions
9224 ;; %%% This used to optimize known byte-wide and operations to memory.
9225 ;; If this is considered useful, it should be done with splitters.
9227 (define_expand "xordi3"
9228 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9229 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9230 (match_operand:DI 2 "x86_64_general_operand" "")))
9231 (clobber (reg:CC FLAGS_REG))]
9233 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9235 (define_insn "*xordi_1_rex64"
9236 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9237 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9238 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9239 (clobber (reg:CC FLAGS_REG))]
9241 && ix86_binary_operator_ok (XOR, DImode, operands)"
9243 xor{q}\t{%2, %0|%0, %2}
9244 xor{q}\t{%2, %0|%0, %2}"
9245 [(set_attr "type" "alu")
9246 (set_attr "mode" "DI,DI")])
9248 (define_insn "*xordi_2_rex64"
9249 [(set (reg FLAGS_REG)
9250 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9251 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9253 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9254 (xor:DI (match_dup 1) (match_dup 2)))]
9256 && ix86_match_ccmode (insn, CCNOmode)
9257 && ix86_binary_operator_ok (XOR, DImode, operands)"
9259 xor{q}\t{%2, %0|%0, %2}
9260 xor{q}\t{%2, %0|%0, %2}"
9261 [(set_attr "type" "alu")
9262 (set_attr "mode" "DI,DI")])
9264 (define_insn "*xordi_3_rex64"
9265 [(set (reg FLAGS_REG)
9266 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9267 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9269 (clobber (match_scratch:DI 0 "=r"))]
9271 && ix86_match_ccmode (insn, CCNOmode)
9272 && ix86_binary_operator_ok (XOR, DImode, operands)"
9273 "xor{q}\t{%2, %0|%0, %2}"
9274 [(set_attr "type" "alu")
9275 (set_attr "mode" "DI")])
9277 (define_expand "xorsi3"
9278 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9279 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9280 (match_operand:SI 2 "general_operand" "")))
9281 (clobber (reg:CC FLAGS_REG))]
9283 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9285 (define_insn "*xorsi_1"
9286 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9287 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9288 (match_operand:SI 2 "general_operand" "ri,rm")))
9289 (clobber (reg:CC FLAGS_REG))]
9290 "ix86_binary_operator_ok (XOR, SImode, operands)"
9291 "xor{l}\t{%2, %0|%0, %2}"
9292 [(set_attr "type" "alu")
9293 (set_attr "mode" "SI")])
9295 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9296 ;; Add speccase for immediates
9297 (define_insn "*xorsi_1_zext"
9298 [(set (match_operand:DI 0 "register_operand" "=r")
9300 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9301 (match_operand:SI 2 "general_operand" "rim"))))
9302 (clobber (reg:CC FLAGS_REG))]
9303 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9304 "xor{l}\t{%2, %k0|%k0, %2}"
9305 [(set_attr "type" "alu")
9306 (set_attr "mode" "SI")])
9308 (define_insn "*xorsi_1_zext_imm"
9309 [(set (match_operand:DI 0 "register_operand" "=r")
9310 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9311 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9312 (clobber (reg:CC FLAGS_REG))]
9313 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9314 "xor{l}\t{%2, %k0|%k0, %2}"
9315 [(set_attr "type" "alu")
9316 (set_attr "mode" "SI")])
9318 (define_insn "*xorsi_2"
9319 [(set (reg FLAGS_REG)
9320 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9321 (match_operand:SI 2 "general_operand" "rim,ri"))
9323 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9324 (xor:SI (match_dup 1) (match_dup 2)))]
9325 "ix86_match_ccmode (insn, CCNOmode)
9326 && ix86_binary_operator_ok (XOR, SImode, operands)"
9327 "xor{l}\t{%2, %0|%0, %2}"
9328 [(set_attr "type" "alu")
9329 (set_attr "mode" "SI")])
9331 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9332 ;; ??? Special case for immediate operand is missing - it is tricky.
9333 (define_insn "*xorsi_2_zext"
9334 [(set (reg FLAGS_REG)
9335 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9336 (match_operand:SI 2 "general_operand" "rim"))
9338 (set (match_operand:DI 0 "register_operand" "=r")
9339 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9340 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9341 && ix86_binary_operator_ok (XOR, SImode, operands)"
9342 "xor{l}\t{%2, %k0|%k0, %2}"
9343 [(set_attr "type" "alu")
9344 (set_attr "mode" "SI")])
9346 (define_insn "*xorsi_2_zext_imm"
9347 [(set (reg FLAGS_REG)
9348 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9349 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9351 (set (match_operand:DI 0 "register_operand" "=r")
9352 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9353 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9354 && ix86_binary_operator_ok (XOR, SImode, operands)"
9355 "xor{l}\t{%2, %k0|%k0, %2}"
9356 [(set_attr "type" "alu")
9357 (set_attr "mode" "SI")])
9359 (define_insn "*xorsi_3"
9360 [(set (reg FLAGS_REG)
9361 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9362 (match_operand:SI 2 "general_operand" "rim"))
9364 (clobber (match_scratch:SI 0 "=r"))]
9365 "ix86_match_ccmode (insn, CCNOmode)
9366 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9367 "xor{l}\t{%2, %0|%0, %2}"
9368 [(set_attr "type" "alu")
9369 (set_attr "mode" "SI")])
9371 (define_expand "xorhi3"
9372 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9373 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9374 (match_operand:HI 2 "general_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))]
9376 "TARGET_HIMODE_MATH"
9377 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9379 (define_insn "*xorhi_1"
9380 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9381 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9382 (match_operand:HI 2 "general_operand" "rmi,ri")))
9383 (clobber (reg:CC FLAGS_REG))]
9384 "ix86_binary_operator_ok (XOR, HImode, operands)"
9385 "xor{w}\t{%2, %0|%0, %2}"
9386 [(set_attr "type" "alu")
9387 (set_attr "mode" "HI")])
9389 (define_insn "*xorhi_2"
9390 [(set (reg FLAGS_REG)
9391 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9392 (match_operand:HI 2 "general_operand" "rim,ri"))
9394 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9395 (xor:HI (match_dup 1) (match_dup 2)))]
9396 "ix86_match_ccmode (insn, CCNOmode)
9397 && ix86_binary_operator_ok (XOR, HImode, operands)"
9398 "xor{w}\t{%2, %0|%0, %2}"
9399 [(set_attr "type" "alu")
9400 (set_attr "mode" "HI")])
9402 (define_insn "*xorhi_3"
9403 [(set (reg FLAGS_REG)
9404 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9405 (match_operand:HI 2 "general_operand" "rim"))
9407 (clobber (match_scratch:HI 0 "=r"))]
9408 "ix86_match_ccmode (insn, CCNOmode)
9409 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9410 "xor{w}\t{%2, %0|%0, %2}"
9411 [(set_attr "type" "alu")
9412 (set_attr "mode" "HI")])
9414 (define_expand "xorqi3"
9415 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9416 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9417 (match_operand:QI 2 "general_operand" "")))
9418 (clobber (reg:CC FLAGS_REG))]
9419 "TARGET_QIMODE_MATH"
9420 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9422 ;; %%% Potential partial reg stall on alternative 2. What to do?
9423 (define_insn "*xorqi_1"
9424 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9425 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9426 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9427 (clobber (reg:CC FLAGS_REG))]
9428 "ix86_binary_operator_ok (XOR, QImode, operands)"
9430 xor{b}\t{%2, %0|%0, %2}
9431 xor{b}\t{%2, %0|%0, %2}
9432 xor{l}\t{%k2, %k0|%k0, %k2}"
9433 [(set_attr "type" "alu")
9434 (set_attr "mode" "QI,QI,SI")])
9436 (define_insn "*xorqi_1_slp"
9437 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9438 (xor:QI (match_dup 0)
9439 (match_operand:QI 1 "general_operand" "qi,qmi")))
9440 (clobber (reg:CC FLAGS_REG))]
9441 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9443 "xor{b}\t{%1, %0|%0, %1}"
9444 [(set_attr "type" "alu1")
9445 (set_attr "mode" "QI")])
9447 (define_insn "xorqi_ext_0"
9448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9453 (match_operand 1 "ext_register_operand" "0")
9456 (match_operand 2 "const_int_operand" "n")))
9457 (clobber (reg:CC FLAGS_REG))]
9458 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9459 "xor{b}\t{%2, %h0|%h0, %2}"
9460 [(set_attr "type" "alu")
9461 (set_attr "length_immediate" "1")
9462 (set_attr "mode" "QI")])
9464 (define_insn "*xorqi_ext_1"
9465 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9470 (match_operand 1 "ext_register_operand" "0")
9474 (match_operand:QI 2 "general_operand" "Qm"))))
9475 (clobber (reg:CC FLAGS_REG))]
9477 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9478 "xor{b}\t{%2, %h0|%h0, %2}"
9479 [(set_attr "type" "alu")
9480 (set_attr "length_immediate" "0")
9481 (set_attr "mode" "QI")])
9483 (define_insn "*xorqi_ext_1_rex64"
9484 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9489 (match_operand 1 "ext_register_operand" "0")
9493 (match_operand 2 "ext_register_operand" "Q"))))
9494 (clobber (reg:CC FLAGS_REG))]
9496 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9497 "xor{b}\t{%2, %h0|%h0, %2}"
9498 [(set_attr "type" "alu")
9499 (set_attr "length_immediate" "0")
9500 (set_attr "mode" "QI")])
9502 (define_insn "*xorqi_ext_2"
9503 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9507 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9510 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9513 (clobber (reg:CC FLAGS_REG))]
9514 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9515 "xor{b}\t{%h2, %h0|%h0, %h2}"
9516 [(set_attr "type" "alu")
9517 (set_attr "length_immediate" "0")
9518 (set_attr "mode" "QI")])
9520 (define_insn "*xorqi_cc_1"
9521 [(set (reg FLAGS_REG)
9523 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9524 (match_operand:QI 2 "general_operand" "qim,qi"))
9526 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9527 (xor:QI (match_dup 1) (match_dup 2)))]
9528 "ix86_match_ccmode (insn, CCNOmode)
9529 && ix86_binary_operator_ok (XOR, QImode, operands)"
9530 "xor{b}\t{%2, %0|%0, %2}"
9531 [(set_attr "type" "alu")
9532 (set_attr "mode" "QI")])
9534 (define_insn "*xorqi_2_slp"
9535 [(set (reg FLAGS_REG)
9536 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9537 (match_operand:QI 1 "general_operand" "qim,qi"))
9539 (set (strict_low_part (match_dup 0))
9540 (xor:QI (match_dup 0) (match_dup 1)))]
9541 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9542 && ix86_match_ccmode (insn, CCNOmode)
9543 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9544 "xor{b}\t{%1, %0|%0, %1}"
9545 [(set_attr "type" "alu1")
9546 (set_attr "mode" "QI")])
9548 (define_insn "*xorqi_cc_2"
9549 [(set (reg FLAGS_REG)
9551 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9552 (match_operand:QI 2 "general_operand" "qim"))
9554 (clobber (match_scratch:QI 0 "=q"))]
9555 "ix86_match_ccmode (insn, CCNOmode)
9556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9557 "xor{b}\t{%2, %0|%0, %2}"
9558 [(set_attr "type" "alu")
9559 (set_attr "mode" "QI")])
9561 (define_insn "*xorqi_cc_ext_1"
9562 [(set (reg FLAGS_REG)
9566 (match_operand 1 "ext_register_operand" "0")
9569 (match_operand:QI 2 "general_operand" "qmn"))
9571 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9575 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9577 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9578 "xor{b}\t{%2, %h0|%h0, %2}"
9579 [(set_attr "type" "alu")
9580 (set_attr "mode" "QI")])
9582 (define_insn "*xorqi_cc_ext_1_rex64"
9583 [(set (reg FLAGS_REG)
9587 (match_operand 1 "ext_register_operand" "0")
9590 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9592 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9596 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9598 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9599 "xor{b}\t{%2, %h0|%h0, %2}"
9600 [(set_attr "type" "alu")
9601 (set_attr "mode" "QI")])
9603 (define_expand "xorqi_cc_ext_1"
9605 (set (reg:CCNO FLAGS_REG)
9609 (match_operand 1 "ext_register_operand" "")
9612 (match_operand:QI 2 "general_operand" ""))
9614 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9618 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9624 [(set (match_operand 0 "register_operand" "")
9625 (xor (match_operand 1 "register_operand" "")
9626 (match_operand 2 "const_int_operand" "")))
9627 (clobber (reg:CC FLAGS_REG))]
9629 && QI_REG_P (operands[0])
9630 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9631 && !(INTVAL (operands[2]) & ~(255 << 8))
9632 && GET_MODE (operands[0]) != QImode"
9633 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9634 (xor:SI (zero_extract:SI (match_dup 1)
9635 (const_int 8) (const_int 8))
9637 (clobber (reg:CC FLAGS_REG))])]
9638 "operands[0] = gen_lowpart (SImode, operands[0]);
9639 operands[1] = gen_lowpart (SImode, operands[1]);
9640 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9642 ;; Since XOR can be encoded with sign extended immediate, this is only
9643 ;; profitable when 7th bit is set.
9645 [(set (match_operand 0 "register_operand" "")
9646 (xor (match_operand 1 "general_operand" "")
9647 (match_operand 2 "const_int_operand" "")))
9648 (clobber (reg:CC FLAGS_REG))]
9650 && ANY_QI_REG_P (operands[0])
9651 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9652 && !(INTVAL (operands[2]) & ~255)
9653 && (INTVAL (operands[2]) & 128)
9654 && GET_MODE (operands[0]) != QImode"
9655 [(parallel [(set (strict_low_part (match_dup 0))
9656 (xor:QI (match_dup 1)
9658 (clobber (reg:CC FLAGS_REG))])]
9659 "operands[0] = gen_lowpart (QImode, operands[0]);
9660 operands[1] = gen_lowpart (QImode, operands[1]);
9661 operands[2] = gen_lowpart (QImode, operands[2]);")
9663 ;; Negation instructions
9665 (define_expand "negti2"
9666 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9667 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9668 (clobber (reg:CC FLAGS_REG))])]
9670 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9672 (define_insn "*negti2_1"
9673 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9674 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9675 (clobber (reg:CC FLAGS_REG))]
9677 && ix86_unary_operator_ok (NEG, TImode, operands)"
9681 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9682 (neg:TI (match_operand:TI 1 "general_operand" "")))
9683 (clobber (reg:CC FLAGS_REG))]
9684 "TARGET_64BIT && reload_completed"
9686 [(set (reg:CCZ FLAGS_REG)
9687 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9688 (set (match_dup 0) (neg:DI (match_dup 2)))])
9691 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9694 (clobber (reg:CC FLAGS_REG))])
9697 (neg:DI (match_dup 1)))
9698 (clobber (reg:CC FLAGS_REG))])]
9699 "split_ti (operands+1, 1, operands+2, operands+3);
9700 split_ti (operands+0, 1, operands+0, operands+1);")
9702 (define_expand "negdi2"
9703 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9704 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9705 (clobber (reg:CC FLAGS_REG))])]
9707 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9709 (define_insn "*negdi2_1"
9710 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9711 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9712 (clobber (reg:CC FLAGS_REG))]
9714 && ix86_unary_operator_ok (NEG, DImode, operands)"
9718 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9719 (neg:DI (match_operand:DI 1 "general_operand" "")))
9720 (clobber (reg:CC FLAGS_REG))]
9721 "!TARGET_64BIT && reload_completed"
9723 [(set (reg:CCZ FLAGS_REG)
9724 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9725 (set (match_dup 0) (neg:SI (match_dup 2)))])
9728 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9731 (clobber (reg:CC FLAGS_REG))])
9734 (neg:SI (match_dup 1)))
9735 (clobber (reg:CC FLAGS_REG))])]
9736 "split_di (operands+1, 1, operands+2, operands+3);
9737 split_di (operands+0, 1, operands+0, operands+1);")
9739 (define_insn "*negdi2_1_rex64"
9740 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9741 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9742 (clobber (reg:CC FLAGS_REG))]
9743 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9745 [(set_attr "type" "negnot")
9746 (set_attr "mode" "DI")])
9748 ;; The problem with neg is that it does not perform (compare x 0),
9749 ;; it really performs (compare 0 x), which leaves us with the zero
9750 ;; flag being the only useful item.
9752 (define_insn "*negdi2_cmpz_rex64"
9753 [(set (reg:CCZ FLAGS_REG)
9754 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9756 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9757 (neg:DI (match_dup 1)))]
9758 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9760 [(set_attr "type" "negnot")
9761 (set_attr "mode" "DI")])
9764 (define_expand "negsi2"
9765 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9766 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9767 (clobber (reg:CC FLAGS_REG))])]
9769 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9771 (define_insn "*negsi2_1"
9772 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9773 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9774 (clobber (reg:CC FLAGS_REG))]
9775 "ix86_unary_operator_ok (NEG, SImode, operands)"
9777 [(set_attr "type" "negnot")
9778 (set_attr "mode" "SI")])
9780 ;; Combine is quite creative about this pattern.
9781 (define_insn "*negsi2_1_zext"
9782 [(set (match_operand:DI 0 "register_operand" "=r")
9783 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9786 (clobber (reg:CC FLAGS_REG))]
9787 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9789 [(set_attr "type" "negnot")
9790 (set_attr "mode" "SI")])
9792 ;; The problem with neg is that it does not perform (compare x 0),
9793 ;; it really performs (compare 0 x), which leaves us with the zero
9794 ;; flag being the only useful item.
9796 (define_insn "*negsi2_cmpz"
9797 [(set (reg:CCZ FLAGS_REG)
9798 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9800 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9801 (neg:SI (match_dup 1)))]
9802 "ix86_unary_operator_ok (NEG, SImode, operands)"
9804 [(set_attr "type" "negnot")
9805 (set_attr "mode" "SI")])
9807 (define_insn "*negsi2_cmpz_zext"
9808 [(set (reg:CCZ FLAGS_REG)
9809 (compare:CCZ (lshiftrt:DI
9811 (match_operand:DI 1 "register_operand" "0")
9815 (set (match_operand:DI 0 "register_operand" "=r")
9816 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9819 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9821 [(set_attr "type" "negnot")
9822 (set_attr "mode" "SI")])
9824 (define_expand "neghi2"
9825 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9826 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9827 (clobber (reg:CC FLAGS_REG))])]
9828 "TARGET_HIMODE_MATH"
9829 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9831 (define_insn "*neghi2_1"
9832 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9833 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "ix86_unary_operator_ok (NEG, HImode, operands)"
9837 [(set_attr "type" "negnot")
9838 (set_attr "mode" "HI")])
9840 (define_insn "*neghi2_cmpz"
9841 [(set (reg:CCZ FLAGS_REG)
9842 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9844 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9845 (neg:HI (match_dup 1)))]
9846 "ix86_unary_operator_ok (NEG, HImode, operands)"
9848 [(set_attr "type" "negnot")
9849 (set_attr "mode" "HI")])
9851 (define_expand "negqi2"
9852 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9853 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9854 (clobber (reg:CC FLAGS_REG))])]
9855 "TARGET_QIMODE_MATH"
9856 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9858 (define_insn "*negqi2_1"
9859 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9860 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "ix86_unary_operator_ok (NEG, QImode, operands)"
9864 [(set_attr "type" "negnot")
9865 (set_attr "mode" "QI")])
9867 (define_insn "*negqi2_cmpz"
9868 [(set (reg:CCZ FLAGS_REG)
9869 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9871 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9872 (neg:QI (match_dup 1)))]
9873 "ix86_unary_operator_ok (NEG, QImode, operands)"
9875 [(set_attr "type" "negnot")
9876 (set_attr "mode" "QI")])
9878 ;; Changing of sign for FP values is doable using integer unit too.
9880 (define_expand "negsf2"
9881 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9882 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9883 "TARGET_80387 || TARGET_SSE_MATH"
9884 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9886 (define_expand "abssf2"
9887 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9888 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9889 "TARGET_80387 || TARGET_SSE_MATH"
9890 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9892 (define_insn "*absnegsf2_mixed"
9893 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9894 (match_operator:SF 3 "absneg_operator"
9895 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9896 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9897 (clobber (reg:CC FLAGS_REG))]
9898 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9899 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9902 (define_insn "*absnegsf2_sse"
9903 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9904 (match_operator:SF 3 "absneg_operator"
9905 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9906 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9907 (clobber (reg:CC FLAGS_REG))]
9909 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9912 (define_insn "*absnegsf2_i387"
9913 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9914 (match_operator:SF 3 "absneg_operator"
9915 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9916 (use (match_operand 2 "" ""))
9917 (clobber (reg:CC FLAGS_REG))]
9918 "TARGET_80387 && !TARGET_SSE_MATH
9919 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9922 (define_expand "copysignsf3"
9923 [(match_operand:SF 0 "register_operand" "")
9924 (match_operand:SF 1 "nonmemory_operand" "")
9925 (match_operand:SF 2 "register_operand" "")]
9928 ix86_expand_copysign (operands);
9932 (define_insn_and_split "copysignsf3_const"
9933 [(set (match_operand:SF 0 "register_operand" "=x")
9935 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9936 (match_operand:SF 2 "register_operand" "0")
9937 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9941 "&& reload_completed"
9944 ix86_split_copysign_const (operands);
9948 (define_insn "copysignsf3_var"
9949 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9951 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9952 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9953 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9954 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9956 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9961 [(set (match_operand:SF 0 "register_operand" "")
9963 [(match_operand:SF 2 "register_operand" "")
9964 (match_operand:SF 3 "register_operand" "")
9965 (match_operand:V4SF 4 "" "")
9966 (match_operand:V4SF 5 "" "")]
9968 (clobber (match_scratch:V4SF 1 ""))]
9969 "TARGET_SSE_MATH && reload_completed"
9972 ix86_split_copysign_var (operands);
9976 (define_expand "negdf2"
9977 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9978 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9979 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9980 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9982 (define_expand "absdf2"
9983 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9984 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9985 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9986 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9988 (define_insn "*absnegdf2_mixed"
9989 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
9990 (match_operator:DF 3 "absneg_operator"
9991 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
9992 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
9993 (clobber (reg:CC FLAGS_REG))]
9994 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9995 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9998 (define_insn "*absnegdf2_sse"
9999 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
10000 (match_operator:DF 3 "absneg_operator"
10001 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10002 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
10003 (clobber (reg:CC FLAGS_REG))]
10004 "TARGET_SSE2 && TARGET_SSE_MATH
10005 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10008 (define_insn "*absnegdf2_i387"
10009 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10010 (match_operator:DF 3 "absneg_operator"
10011 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10012 (use (match_operand 2 "" ""))
10013 (clobber (reg:CC FLAGS_REG))]
10014 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10015 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10018 (define_expand "copysigndf3"
10019 [(match_operand:DF 0 "register_operand" "")
10020 (match_operand:DF 1 "nonmemory_operand" "")
10021 (match_operand:DF 2 "register_operand" "")]
10022 "TARGET_SSE2 && TARGET_SSE_MATH"
10024 ix86_expand_copysign (operands);
10028 (define_insn_and_split "copysigndf3_const"
10029 [(set (match_operand:DF 0 "register_operand" "=x")
10031 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
10032 (match_operand:DF 2 "register_operand" "0")
10033 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10035 "TARGET_SSE2 && TARGET_SSE_MATH"
10037 "&& reload_completed"
10040 ix86_split_copysign_const (operands);
10044 (define_insn "copysigndf3_var"
10045 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
10047 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
10048 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
10049 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10050 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10052 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
10053 "TARGET_SSE2 && TARGET_SSE_MATH"
10057 [(set (match_operand:DF 0 "register_operand" "")
10059 [(match_operand:DF 2 "register_operand" "")
10060 (match_operand:DF 3 "register_operand" "")
10061 (match_operand:V2DF 4 "" "")
10062 (match_operand:V2DF 5 "" "")]
10064 (clobber (match_scratch:V2DF 1 ""))]
10065 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10068 ix86_split_copysign_var (operands);
10072 (define_expand "negxf2"
10073 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10074 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10076 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10078 (define_expand "absxf2"
10079 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10080 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10082 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10084 (define_insn "*absnegxf2_i387"
10085 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10086 (match_operator:XF 3 "absneg_operator"
10087 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10088 (use (match_operand 2 "" ""))
10089 (clobber (reg:CC FLAGS_REG))]
10091 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10094 ;; Splitters for fp abs and neg.
10097 [(set (match_operand 0 "fp_register_operand" "")
10098 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10099 (use (match_operand 2 "" ""))
10100 (clobber (reg:CC FLAGS_REG))]
10102 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10105 [(set (match_operand 0 "register_operand" "")
10106 (match_operator 3 "absneg_operator"
10107 [(match_operand 1 "register_operand" "")]))
10108 (use (match_operand 2 "nonimmediate_operand" ""))
10109 (clobber (reg:CC FLAGS_REG))]
10110 "reload_completed && SSE_REG_P (operands[0])"
10111 [(set (match_dup 0) (match_dup 3))]
10113 enum machine_mode mode = GET_MODE (operands[0]);
10114 enum machine_mode vmode = GET_MODE (operands[2]);
10117 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10118 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10119 if (operands_match_p (operands[0], operands[2]))
10122 operands[1] = operands[2];
10125 if (GET_CODE (operands[3]) == ABS)
10126 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10128 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10133 [(set (match_operand:SF 0 "register_operand" "")
10134 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10135 (use (match_operand:V4SF 2 "" ""))
10136 (clobber (reg:CC FLAGS_REG))]
10138 [(parallel [(set (match_dup 0) (match_dup 1))
10139 (clobber (reg:CC FLAGS_REG))])]
10142 operands[0] = gen_lowpart (SImode, operands[0]);
10143 if (GET_CODE (operands[1]) == ABS)
10145 tmp = gen_int_mode (0x7fffffff, SImode);
10146 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10150 tmp = gen_int_mode (0x80000000, SImode);
10151 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10157 [(set (match_operand:DF 0 "register_operand" "")
10158 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10159 (use (match_operand 2 "" ""))
10160 (clobber (reg:CC FLAGS_REG))]
10162 [(parallel [(set (match_dup 0) (match_dup 1))
10163 (clobber (reg:CC FLAGS_REG))])]
10168 tmp = gen_lowpart (DImode, operands[0]);
10169 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10172 if (GET_CODE (operands[1]) == ABS)
10175 tmp = gen_rtx_NOT (DImode, tmp);
10179 operands[0] = gen_highpart (SImode, operands[0]);
10180 if (GET_CODE (operands[1]) == ABS)
10182 tmp = gen_int_mode (0x7fffffff, SImode);
10183 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10187 tmp = gen_int_mode (0x80000000, SImode);
10188 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10195 [(set (match_operand:XF 0 "register_operand" "")
10196 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10197 (use (match_operand 2 "" ""))
10198 (clobber (reg:CC FLAGS_REG))]
10200 [(parallel [(set (match_dup 0) (match_dup 1))
10201 (clobber (reg:CC FLAGS_REG))])]
10204 operands[0] = gen_rtx_REG (SImode,
10205 true_regnum (operands[0])
10206 + (TARGET_64BIT ? 1 : 2));
10207 if (GET_CODE (operands[1]) == ABS)
10209 tmp = GEN_INT (0x7fff);
10210 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10214 tmp = GEN_INT (0x8000);
10215 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10221 [(set (match_operand 0 "memory_operand" "")
10222 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10223 (use (match_operand 2 "" ""))
10224 (clobber (reg:CC FLAGS_REG))]
10226 [(parallel [(set (match_dup 0) (match_dup 1))
10227 (clobber (reg:CC FLAGS_REG))])]
10229 enum machine_mode mode = GET_MODE (operands[0]);
10230 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10233 operands[0] = adjust_address (operands[0], QImode, size - 1);
10234 if (GET_CODE (operands[1]) == ABS)
10236 tmp = gen_int_mode (0x7f, QImode);
10237 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10241 tmp = gen_int_mode (0x80, QImode);
10242 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10247 ;; Conditionalize these after reload. If they match before reload, we
10248 ;; lose the clobber and ability to use integer instructions.
10250 (define_insn "*negsf2_1"
10251 [(set (match_operand:SF 0 "register_operand" "=f")
10252 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10253 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10255 [(set_attr "type" "fsgn")
10256 (set_attr "mode" "SF")])
10258 (define_insn "*negdf2_1"
10259 [(set (match_operand:DF 0 "register_operand" "=f")
10260 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10261 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10263 [(set_attr "type" "fsgn")
10264 (set_attr "mode" "DF")])
10266 (define_insn "*negxf2_1"
10267 [(set (match_operand:XF 0 "register_operand" "=f")
10268 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10271 [(set_attr "type" "fsgn")
10272 (set_attr "mode" "XF")])
10274 (define_insn "*abssf2_1"
10275 [(set (match_operand:SF 0 "register_operand" "=f")
10276 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10277 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10279 [(set_attr "type" "fsgn")
10280 (set_attr "mode" "SF")])
10282 (define_insn "*absdf2_1"
10283 [(set (match_operand:DF 0 "register_operand" "=f")
10284 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10285 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10287 [(set_attr "type" "fsgn")
10288 (set_attr "mode" "DF")])
10290 (define_insn "*absxf2_1"
10291 [(set (match_operand:XF 0 "register_operand" "=f")
10292 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10295 [(set_attr "type" "fsgn")
10296 (set_attr "mode" "DF")])
10298 (define_insn "*negextendsfdf2"
10299 [(set (match_operand:DF 0 "register_operand" "=f")
10300 (neg:DF (float_extend:DF
10301 (match_operand:SF 1 "register_operand" "0"))))]
10302 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10304 [(set_attr "type" "fsgn")
10305 (set_attr "mode" "DF")])
10307 (define_insn "*negextenddfxf2"
10308 [(set (match_operand:XF 0 "register_operand" "=f")
10309 (neg:XF (float_extend:XF
10310 (match_operand:DF 1 "register_operand" "0"))))]
10313 [(set_attr "type" "fsgn")
10314 (set_attr "mode" "XF")])
10316 (define_insn "*negextendsfxf2"
10317 [(set (match_operand:XF 0 "register_operand" "=f")
10318 (neg:XF (float_extend:XF
10319 (match_operand:SF 1 "register_operand" "0"))))]
10322 [(set_attr "type" "fsgn")
10323 (set_attr "mode" "XF")])
10325 (define_insn "*absextendsfdf2"
10326 [(set (match_operand:DF 0 "register_operand" "=f")
10327 (abs:DF (float_extend:DF
10328 (match_operand:SF 1 "register_operand" "0"))))]
10329 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10331 [(set_attr "type" "fsgn")
10332 (set_attr "mode" "DF")])
10334 (define_insn "*absextenddfxf2"
10335 [(set (match_operand:XF 0 "register_operand" "=f")
10336 (abs:XF (float_extend:XF
10337 (match_operand:DF 1 "register_operand" "0"))))]
10340 [(set_attr "type" "fsgn")
10341 (set_attr "mode" "XF")])
10343 (define_insn "*absextendsfxf2"
10344 [(set (match_operand:XF 0 "register_operand" "=f")
10345 (abs:XF (float_extend:XF
10346 (match_operand:SF 1 "register_operand" "0"))))]
10349 [(set_attr "type" "fsgn")
10350 (set_attr "mode" "XF")])
10352 ;; One complement instructions
10354 (define_expand "one_cmpldi2"
10355 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10356 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10358 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10360 (define_insn "*one_cmpldi2_1_rex64"
10361 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10362 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10363 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10365 [(set_attr "type" "negnot")
10366 (set_attr "mode" "DI")])
10368 (define_insn "*one_cmpldi2_2_rex64"
10369 [(set (reg FLAGS_REG)
10370 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10372 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10373 (not:DI (match_dup 1)))]
10374 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10375 && ix86_unary_operator_ok (NOT, DImode, operands)"
10377 [(set_attr "type" "alu1")
10378 (set_attr "mode" "DI")])
10381 [(set (match_operand 0 "flags_reg_operand" "")
10382 (match_operator 2 "compare_operator"
10383 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10385 (set (match_operand:DI 1 "nonimmediate_operand" "")
10386 (not:DI (match_dup 3)))]
10387 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10388 [(parallel [(set (match_dup 0)
10390 [(xor:DI (match_dup 3) (const_int -1))
10393 (xor:DI (match_dup 3) (const_int -1)))])]
10396 (define_expand "one_cmplsi2"
10397 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10398 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10400 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10402 (define_insn "*one_cmplsi2_1"
10403 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10404 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10405 "ix86_unary_operator_ok (NOT, SImode, operands)"
10407 [(set_attr "type" "negnot")
10408 (set_attr "mode" "SI")])
10410 ;; ??? Currently never generated - xor is used instead.
10411 (define_insn "*one_cmplsi2_1_zext"
10412 [(set (match_operand:DI 0 "register_operand" "=r")
10413 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10414 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10416 [(set_attr "type" "negnot")
10417 (set_attr "mode" "SI")])
10419 (define_insn "*one_cmplsi2_2"
10420 [(set (reg FLAGS_REG)
10421 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10423 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10424 (not:SI (match_dup 1)))]
10425 "ix86_match_ccmode (insn, CCNOmode)
10426 && ix86_unary_operator_ok (NOT, SImode, operands)"
10428 [(set_attr "type" "alu1")
10429 (set_attr "mode" "SI")])
10432 [(set (match_operand 0 "flags_reg_operand" "")
10433 (match_operator 2 "compare_operator"
10434 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10436 (set (match_operand:SI 1 "nonimmediate_operand" "")
10437 (not:SI (match_dup 3)))]
10438 "ix86_match_ccmode (insn, CCNOmode)"
10439 [(parallel [(set (match_dup 0)
10440 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10443 (xor:SI (match_dup 3) (const_int -1)))])]
10446 ;; ??? Currently never generated - xor is used instead.
10447 (define_insn "*one_cmplsi2_2_zext"
10448 [(set (reg FLAGS_REG)
10449 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10451 (set (match_operand:DI 0 "register_operand" "=r")
10452 (zero_extend:DI (not:SI (match_dup 1))))]
10453 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10454 && ix86_unary_operator_ok (NOT, SImode, operands)"
10456 [(set_attr "type" "alu1")
10457 (set_attr "mode" "SI")])
10460 [(set (match_operand 0 "flags_reg_operand" "")
10461 (match_operator 2 "compare_operator"
10462 [(not:SI (match_operand:SI 3 "register_operand" ""))
10464 (set (match_operand:DI 1 "register_operand" "")
10465 (zero_extend:DI (not:SI (match_dup 3))))]
10466 "ix86_match_ccmode (insn, CCNOmode)"
10467 [(parallel [(set (match_dup 0)
10468 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10471 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10474 (define_expand "one_cmplhi2"
10475 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10476 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10477 "TARGET_HIMODE_MATH"
10478 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10480 (define_insn "*one_cmplhi2_1"
10481 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10482 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10483 "ix86_unary_operator_ok (NOT, HImode, operands)"
10485 [(set_attr "type" "negnot")
10486 (set_attr "mode" "HI")])
10488 (define_insn "*one_cmplhi2_2"
10489 [(set (reg FLAGS_REG)
10490 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10492 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10493 (not:HI (match_dup 1)))]
10494 "ix86_match_ccmode (insn, CCNOmode)
10495 && ix86_unary_operator_ok (NEG, HImode, operands)"
10497 [(set_attr "type" "alu1")
10498 (set_attr "mode" "HI")])
10501 [(set (match_operand 0 "flags_reg_operand" "")
10502 (match_operator 2 "compare_operator"
10503 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10505 (set (match_operand:HI 1 "nonimmediate_operand" "")
10506 (not:HI (match_dup 3)))]
10507 "ix86_match_ccmode (insn, CCNOmode)"
10508 [(parallel [(set (match_dup 0)
10509 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10512 (xor:HI (match_dup 3) (const_int -1)))])]
10515 ;; %%% Potential partial reg stall on alternative 1. What to do?
10516 (define_expand "one_cmplqi2"
10517 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10518 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10519 "TARGET_QIMODE_MATH"
10520 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10522 (define_insn "*one_cmplqi2_1"
10523 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10524 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10525 "ix86_unary_operator_ok (NOT, QImode, operands)"
10529 [(set_attr "type" "negnot")
10530 (set_attr "mode" "QI,SI")])
10532 (define_insn "*one_cmplqi2_2"
10533 [(set (reg FLAGS_REG)
10534 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10536 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10537 (not:QI (match_dup 1)))]
10538 "ix86_match_ccmode (insn, CCNOmode)
10539 && ix86_unary_operator_ok (NOT, QImode, operands)"
10541 [(set_attr "type" "alu1")
10542 (set_attr "mode" "QI")])
10545 [(set (match_operand 0 "flags_reg_operand" "")
10546 (match_operator 2 "compare_operator"
10547 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10549 (set (match_operand:QI 1 "nonimmediate_operand" "")
10550 (not:QI (match_dup 3)))]
10551 "ix86_match_ccmode (insn, CCNOmode)"
10552 [(parallel [(set (match_dup 0)
10553 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10556 (xor:QI (match_dup 3) (const_int -1)))])]
10559 ;; Arithmetic shift instructions
10561 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10562 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10563 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10564 ;; from the assembler input.
10566 ;; This instruction shifts the target reg/mem as usual, but instead of
10567 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10568 ;; is a left shift double, bits are taken from the high order bits of
10569 ;; reg, else if the insn is a shift right double, bits are taken from the
10570 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10571 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10573 ;; Since sh[lr]d does not change the `reg' operand, that is done
10574 ;; separately, making all shifts emit pairs of shift double and normal
10575 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10576 ;; support a 63 bit shift, each shift where the count is in a reg expands
10577 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10579 ;; If the shift count is a constant, we need never emit more than one
10580 ;; shift pair, instead using moves and sign extension for counts greater
10583 (define_expand "ashlti3"
10584 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10585 (ashift:TI (match_operand:TI 1 "register_operand" "")
10586 (match_operand:QI 2 "nonmemory_operand" "")))
10587 (clobber (reg:CC FLAGS_REG))])]
10590 if (! immediate_operand (operands[2], QImode))
10592 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10595 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10599 (define_insn "ashlti3_1"
10600 [(set (match_operand:TI 0 "register_operand" "=r")
10601 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10602 (match_operand:QI 2 "register_operand" "c")))
10603 (clobber (match_scratch:DI 3 "=&r"))
10604 (clobber (reg:CC FLAGS_REG))]
10607 [(set_attr "type" "multi")])
10609 (define_insn "*ashlti3_2"
10610 [(set (match_operand:TI 0 "register_operand" "=r")
10611 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10612 (match_operand:QI 2 "immediate_operand" "O")))
10613 (clobber (reg:CC FLAGS_REG))]
10616 [(set_attr "type" "multi")])
10619 [(set (match_operand:TI 0 "register_operand" "")
10620 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10621 (match_operand:QI 2 "register_operand" "")))
10622 (clobber (match_scratch:DI 3 ""))
10623 (clobber (reg:CC FLAGS_REG))]
10624 "TARGET_64BIT && reload_completed"
10626 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10629 [(set (match_operand:TI 0 "register_operand" "")
10630 (ashift:TI (match_operand:TI 1 "register_operand" "")
10631 (match_operand:QI 2 "immediate_operand" "")))
10632 (clobber (reg:CC FLAGS_REG))]
10633 "TARGET_64BIT && reload_completed"
10635 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10637 (define_insn "x86_64_shld"
10638 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10639 (ior:DI (ashift:DI (match_dup 0)
10640 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10641 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10642 (minus:QI (const_int 64) (match_dup 2)))))
10643 (clobber (reg:CC FLAGS_REG))]
10646 shld{q}\t{%2, %1, %0|%0, %1, %2}
10647 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10648 [(set_attr "type" "ishift")
10649 (set_attr "prefix_0f" "1")
10650 (set_attr "mode" "DI")
10651 (set_attr "athlon_decode" "vector")
10652 (set_attr "amdfam10_decode" "vector")])
10654 (define_expand "x86_64_shift_adj"
10655 [(set (reg:CCZ FLAGS_REG)
10656 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10659 (set (match_operand:DI 0 "register_operand" "")
10660 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10661 (match_operand:DI 1 "register_operand" "")
10664 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10665 (match_operand:DI 3 "register_operand" "r")
10670 (define_expand "ashldi3"
10671 [(set (match_operand:DI 0 "shiftdi_operand" "")
10672 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10673 (match_operand:QI 2 "nonmemory_operand" "")))]
10675 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10677 (define_insn "*ashldi3_1_rex64"
10678 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10679 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10680 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10681 (clobber (reg:CC FLAGS_REG))]
10682 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10684 switch (get_attr_type (insn))
10687 gcc_assert (operands[2] == const1_rtx);
10688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10689 return "add{q}\t{%0, %0|%0, %0}";
10692 gcc_assert (CONST_INT_P (operands[2]));
10693 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10694 operands[1] = gen_rtx_MULT (DImode, operands[1],
10695 GEN_INT (1 << INTVAL (operands[2])));
10696 return "lea{q}\t{%a1, %0|%0, %a1}";
10699 if (REG_P (operands[2]))
10700 return "sal{q}\t{%b2, %0|%0, %b2}";
10701 else if (operands[2] == const1_rtx
10702 && (TARGET_SHIFT1 || optimize_size))
10703 return "sal{q}\t%0";
10705 return "sal{q}\t{%2, %0|%0, %2}";
10708 [(set (attr "type")
10709 (cond [(eq_attr "alternative" "1")
10710 (const_string "lea")
10711 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10713 (match_operand 0 "register_operand" ""))
10714 (match_operand 2 "const1_operand" ""))
10715 (const_string "alu")
10717 (const_string "ishift")))
10718 (set_attr "mode" "DI")])
10720 ;; Convert lea to the lea pattern to avoid flags dependency.
10722 [(set (match_operand:DI 0 "register_operand" "")
10723 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10724 (match_operand:QI 2 "immediate_operand" "")))
10725 (clobber (reg:CC FLAGS_REG))]
10726 "TARGET_64BIT && reload_completed
10727 && true_regnum (operands[0]) != true_regnum (operands[1])"
10728 [(set (match_dup 0)
10729 (mult:DI (match_dup 1)
10731 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10733 ;; This pattern can't accept a variable shift count, since shifts by
10734 ;; zero don't affect the flags. We assume that shifts by constant
10735 ;; zero are optimized away.
10736 (define_insn "*ashldi3_cmp_rex64"
10737 [(set (reg FLAGS_REG)
10739 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10740 (match_operand:QI 2 "immediate_operand" "e"))
10742 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10743 (ashift:DI (match_dup 1) (match_dup 2)))]
10744 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10745 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10747 || !TARGET_PARTIAL_FLAG_REG_STALL
10748 || (operands[2] == const1_rtx
10750 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10752 switch (get_attr_type (insn))
10755 gcc_assert (operands[2] == const1_rtx);
10756 return "add{q}\t{%0, %0|%0, %0}";
10759 if (REG_P (operands[2]))
10760 return "sal{q}\t{%b2, %0|%0, %b2}";
10761 else if (operands[2] == const1_rtx
10762 && (TARGET_SHIFT1 || optimize_size))
10763 return "sal{q}\t%0";
10765 return "sal{q}\t{%2, %0|%0, %2}";
10768 [(set (attr "type")
10769 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10771 (match_operand 0 "register_operand" ""))
10772 (match_operand 2 "const1_operand" ""))
10773 (const_string "alu")
10775 (const_string "ishift")))
10776 (set_attr "mode" "DI")])
10778 (define_insn "*ashldi3_cconly_rex64"
10779 [(set (reg FLAGS_REG)
10781 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10782 (match_operand:QI 2 "immediate_operand" "e"))
10784 (clobber (match_scratch:DI 0 "=r"))]
10785 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10786 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10788 || !TARGET_PARTIAL_FLAG_REG_STALL
10789 || (operands[2] == const1_rtx
10791 || TARGET_DOUBLE_WITH_ADD)))"
10793 switch (get_attr_type (insn))
10796 gcc_assert (operands[2] == const1_rtx);
10797 return "add{q}\t{%0, %0|%0, %0}";
10800 if (REG_P (operands[2]))
10801 return "sal{q}\t{%b2, %0|%0, %b2}";
10802 else if (operands[2] == const1_rtx
10803 && (TARGET_SHIFT1 || optimize_size))
10804 return "sal{q}\t%0";
10806 return "sal{q}\t{%2, %0|%0, %2}";
10809 [(set (attr "type")
10810 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10812 (match_operand 0 "register_operand" ""))
10813 (match_operand 2 "const1_operand" ""))
10814 (const_string "alu")
10816 (const_string "ishift")))
10817 (set_attr "mode" "DI")])
10819 (define_insn "*ashldi3_1"
10820 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10821 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10822 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10823 (clobber (reg:CC FLAGS_REG))]
10826 [(set_attr "type" "multi")])
10828 ;; By default we don't ask for a scratch register, because when DImode
10829 ;; values are manipulated, registers are already at a premium. But if
10830 ;; we have one handy, we won't turn it away.
10832 [(match_scratch:SI 3 "r")
10833 (parallel [(set (match_operand:DI 0 "register_operand" "")
10834 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10835 (match_operand:QI 2 "nonmemory_operand" "")))
10836 (clobber (reg:CC FLAGS_REG))])
10838 "!TARGET_64BIT && TARGET_CMOVE"
10840 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10843 [(set (match_operand:DI 0 "register_operand" "")
10844 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10845 (match_operand:QI 2 "nonmemory_operand" "")))
10846 (clobber (reg:CC FLAGS_REG))]
10847 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10848 ? flow2_completed : reload_completed)"
10850 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10852 (define_insn "x86_shld_1"
10853 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10854 (ior:SI (ashift:SI (match_dup 0)
10855 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10856 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10857 (minus:QI (const_int 32) (match_dup 2)))))
10858 (clobber (reg:CC FLAGS_REG))]
10861 shld{l}\t{%2, %1, %0|%0, %1, %2}
10862 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10863 [(set_attr "type" "ishift")
10864 (set_attr "prefix_0f" "1")
10865 (set_attr "mode" "SI")
10866 (set_attr "pent_pair" "np")
10867 (set_attr "athlon_decode" "vector")
10868 (set_attr "amdfam10_decode" "vector")])
10870 (define_expand "x86_shift_adj_1"
10871 [(set (reg:CCZ FLAGS_REG)
10872 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10875 (set (match_operand:SI 0 "register_operand" "")
10876 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10877 (match_operand:SI 1 "register_operand" "")
10880 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10881 (match_operand:SI 3 "register_operand" "r")
10886 (define_expand "x86_shift_adj_2"
10887 [(use (match_operand:SI 0 "register_operand" ""))
10888 (use (match_operand:SI 1 "register_operand" ""))
10889 (use (match_operand:QI 2 "register_operand" ""))]
10892 rtx label = gen_label_rtx ();
10895 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10897 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10898 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10899 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10900 gen_rtx_LABEL_REF (VOIDmode, label),
10902 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10903 JUMP_LABEL (tmp) = label;
10905 emit_move_insn (operands[0], operands[1]);
10906 ix86_expand_clear (operands[1]);
10908 emit_label (label);
10909 LABEL_NUSES (label) = 1;
10914 (define_expand "ashlsi3"
10915 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10916 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10917 (match_operand:QI 2 "nonmemory_operand" "")))
10918 (clobber (reg:CC FLAGS_REG))]
10920 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10922 (define_insn "*ashlsi3_1"
10923 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10924 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10925 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10929 switch (get_attr_type (insn))
10932 gcc_assert (operands[2] == const1_rtx);
10933 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10934 return "add{l}\t{%0, %0|%0, %0}";
10940 if (REG_P (operands[2]))
10941 return "sal{l}\t{%b2, %0|%0, %b2}";
10942 else if (operands[2] == const1_rtx
10943 && (TARGET_SHIFT1 || optimize_size))
10944 return "sal{l}\t%0";
10946 return "sal{l}\t{%2, %0|%0, %2}";
10949 [(set (attr "type")
10950 (cond [(eq_attr "alternative" "1")
10951 (const_string "lea")
10952 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10954 (match_operand 0 "register_operand" ""))
10955 (match_operand 2 "const1_operand" ""))
10956 (const_string "alu")
10958 (const_string "ishift")))
10959 (set_attr "mode" "SI")])
10961 ;; Convert lea to the lea pattern to avoid flags dependency.
10963 [(set (match_operand 0 "register_operand" "")
10964 (ashift (match_operand 1 "index_register_operand" "")
10965 (match_operand:QI 2 "const_int_operand" "")))
10966 (clobber (reg:CC FLAGS_REG))]
10968 && true_regnum (operands[0]) != true_regnum (operands[1])
10969 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10973 enum machine_mode mode = GET_MODE (operands[0]);
10975 if (GET_MODE_SIZE (mode) < 4)
10976 operands[0] = gen_lowpart (SImode, operands[0]);
10978 operands[1] = gen_lowpart (Pmode, operands[1]);
10979 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10981 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10982 if (Pmode != SImode)
10983 pat = gen_rtx_SUBREG (SImode, pat, 0);
10984 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10988 ;; Rare case of shifting RSP is handled by generating move and shift
10990 [(set (match_operand 0 "register_operand" "")
10991 (ashift (match_operand 1 "register_operand" "")
10992 (match_operand:QI 2 "const_int_operand" "")))
10993 (clobber (reg:CC FLAGS_REG))]
10995 && true_regnum (operands[0]) != true_regnum (operands[1])"
10999 emit_move_insn (operands[0], operands[1]);
11000 pat = gen_rtx_SET (VOIDmode, operands[0],
11001 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11002 operands[0], operands[2]));
11003 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11004 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11008 (define_insn "*ashlsi3_1_zext"
11009 [(set (match_operand:DI 0 "register_operand" "=r,r")
11010 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11011 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11012 (clobber (reg:CC FLAGS_REG))]
11013 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11015 switch (get_attr_type (insn))
11018 gcc_assert (operands[2] == const1_rtx);
11019 return "add{l}\t{%k0, %k0|%k0, %k0}";
11025 if (REG_P (operands[2]))
11026 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11027 else if (operands[2] == const1_rtx
11028 && (TARGET_SHIFT1 || optimize_size))
11029 return "sal{l}\t%k0";
11031 return "sal{l}\t{%2, %k0|%k0, %2}";
11034 [(set (attr "type")
11035 (cond [(eq_attr "alternative" "1")
11036 (const_string "lea")
11037 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11039 (match_operand 2 "const1_operand" ""))
11040 (const_string "alu")
11042 (const_string "ishift")))
11043 (set_attr "mode" "SI")])
11045 ;; Convert lea to the lea pattern to avoid flags dependency.
11047 [(set (match_operand:DI 0 "register_operand" "")
11048 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11049 (match_operand:QI 2 "const_int_operand" ""))))
11050 (clobber (reg:CC FLAGS_REG))]
11051 "TARGET_64BIT && reload_completed
11052 && true_regnum (operands[0]) != true_regnum (operands[1])"
11053 [(set (match_dup 0) (zero_extend:DI
11054 (subreg:SI (mult:SI (match_dup 1)
11055 (match_dup 2)) 0)))]
11057 operands[1] = gen_lowpart (Pmode, operands[1]);
11058 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11061 ;; This pattern can't accept a variable shift count, since shifts by
11062 ;; zero don't affect the flags. We assume that shifts by constant
11063 ;; zero are optimized away.
11064 (define_insn "*ashlsi3_cmp"
11065 [(set (reg FLAGS_REG)
11067 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11068 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11070 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11071 (ashift:SI (match_dup 1) (match_dup 2)))]
11072 "ix86_match_ccmode (insn, CCGOCmode)
11073 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11075 || !TARGET_PARTIAL_FLAG_REG_STALL
11076 || (operands[2] == const1_rtx
11078 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11080 switch (get_attr_type (insn))
11083 gcc_assert (operands[2] == const1_rtx);
11084 return "add{l}\t{%0, %0|%0, %0}";
11087 if (REG_P (operands[2]))
11088 return "sal{l}\t{%b2, %0|%0, %b2}";
11089 else if (operands[2] == const1_rtx
11090 && (TARGET_SHIFT1 || optimize_size))
11091 return "sal{l}\t%0";
11093 return "sal{l}\t{%2, %0|%0, %2}";
11096 [(set (attr "type")
11097 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11099 (match_operand 0 "register_operand" ""))
11100 (match_operand 2 "const1_operand" ""))
11101 (const_string "alu")
11103 (const_string "ishift")))
11104 (set_attr "mode" "SI")])
11106 (define_insn "*ashlsi3_cconly"
11107 [(set (reg FLAGS_REG)
11109 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11110 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11112 (clobber (match_scratch:SI 0 "=r"))]
11113 "ix86_match_ccmode (insn, CCGOCmode)
11114 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11116 || !TARGET_PARTIAL_FLAG_REG_STALL
11117 || (operands[2] == const1_rtx
11119 || TARGET_DOUBLE_WITH_ADD)))"
11121 switch (get_attr_type (insn))
11124 gcc_assert (operands[2] == const1_rtx);
11125 return "add{l}\t{%0, %0|%0, %0}";
11128 if (REG_P (operands[2]))
11129 return "sal{l}\t{%b2, %0|%0, %b2}";
11130 else if (operands[2] == const1_rtx
11131 && (TARGET_SHIFT1 || optimize_size))
11132 return "sal{l}\t%0";
11134 return "sal{l}\t{%2, %0|%0, %2}";
11137 [(set (attr "type")
11138 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11140 (match_operand 0 "register_operand" ""))
11141 (match_operand 2 "const1_operand" ""))
11142 (const_string "alu")
11144 (const_string "ishift")))
11145 (set_attr "mode" "SI")])
11147 (define_insn "*ashlsi3_cmp_zext"
11148 [(set (reg FLAGS_REG)
11150 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11151 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11153 (set (match_operand:DI 0 "register_operand" "=r")
11154 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11155 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11156 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11158 || !TARGET_PARTIAL_FLAG_REG_STALL
11159 || (operands[2] == const1_rtx
11161 || TARGET_DOUBLE_WITH_ADD)))"
11163 switch (get_attr_type (insn))
11166 gcc_assert (operands[2] == const1_rtx);
11167 return "add{l}\t{%k0, %k0|%k0, %k0}";
11170 if (REG_P (operands[2]))
11171 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11172 else if (operands[2] == const1_rtx
11173 && (TARGET_SHIFT1 || optimize_size))
11174 return "sal{l}\t%k0";
11176 return "sal{l}\t{%2, %k0|%k0, %2}";
11179 [(set (attr "type")
11180 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11182 (match_operand 2 "const1_operand" ""))
11183 (const_string "alu")
11185 (const_string "ishift")))
11186 (set_attr "mode" "SI")])
11188 (define_expand "ashlhi3"
11189 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11190 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11191 (match_operand:QI 2 "nonmemory_operand" "")))
11192 (clobber (reg:CC FLAGS_REG))]
11193 "TARGET_HIMODE_MATH"
11194 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11196 (define_insn "*ashlhi3_1_lea"
11197 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11198 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11199 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11200 (clobber (reg:CC FLAGS_REG))]
11201 "!TARGET_PARTIAL_REG_STALL
11202 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11204 switch (get_attr_type (insn))
11209 gcc_assert (operands[2] == const1_rtx);
11210 return "add{w}\t{%0, %0|%0, %0}";
11213 if (REG_P (operands[2]))
11214 return "sal{w}\t{%b2, %0|%0, %b2}";
11215 else if (operands[2] == const1_rtx
11216 && (TARGET_SHIFT1 || optimize_size))
11217 return "sal{w}\t%0";
11219 return "sal{w}\t{%2, %0|%0, %2}";
11222 [(set (attr "type")
11223 (cond [(eq_attr "alternative" "1")
11224 (const_string "lea")
11225 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11227 (match_operand 0 "register_operand" ""))
11228 (match_operand 2 "const1_operand" ""))
11229 (const_string "alu")
11231 (const_string "ishift")))
11232 (set_attr "mode" "HI,SI")])
11234 (define_insn "*ashlhi3_1"
11235 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11236 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11237 (match_operand:QI 2 "nonmemory_operand" "cI")))
11238 (clobber (reg:CC FLAGS_REG))]
11239 "TARGET_PARTIAL_REG_STALL
11240 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11242 switch (get_attr_type (insn))
11245 gcc_assert (operands[2] == const1_rtx);
11246 return "add{w}\t{%0, %0|%0, %0}";
11249 if (REG_P (operands[2]))
11250 return "sal{w}\t{%b2, %0|%0, %b2}";
11251 else if (operands[2] == const1_rtx
11252 && (TARGET_SHIFT1 || optimize_size))
11253 return "sal{w}\t%0";
11255 return "sal{w}\t{%2, %0|%0, %2}";
11258 [(set (attr "type")
11259 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11261 (match_operand 0 "register_operand" ""))
11262 (match_operand 2 "const1_operand" ""))
11263 (const_string "alu")
11265 (const_string "ishift")))
11266 (set_attr "mode" "HI")])
11268 ;; This pattern can't accept a variable shift count, since shifts by
11269 ;; zero don't affect the flags. We assume that shifts by constant
11270 ;; zero are optimized away.
11271 (define_insn "*ashlhi3_cmp"
11272 [(set (reg FLAGS_REG)
11274 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11275 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11277 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11278 (ashift:HI (match_dup 1) (match_dup 2)))]
11279 "ix86_match_ccmode (insn, CCGOCmode)
11280 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11282 || !TARGET_PARTIAL_FLAG_REG_STALL
11283 || (operands[2] == const1_rtx
11285 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11287 switch (get_attr_type (insn))
11290 gcc_assert (operands[2] == const1_rtx);
11291 return "add{w}\t{%0, %0|%0, %0}";
11294 if (REG_P (operands[2]))
11295 return "sal{w}\t{%b2, %0|%0, %b2}";
11296 else if (operands[2] == const1_rtx
11297 && (TARGET_SHIFT1 || optimize_size))
11298 return "sal{w}\t%0";
11300 return "sal{w}\t{%2, %0|%0, %2}";
11303 [(set (attr "type")
11304 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11306 (match_operand 0 "register_operand" ""))
11307 (match_operand 2 "const1_operand" ""))
11308 (const_string "alu")
11310 (const_string "ishift")))
11311 (set_attr "mode" "HI")])
11313 (define_insn "*ashlhi3_cconly"
11314 [(set (reg FLAGS_REG)
11316 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11317 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11319 (clobber (match_scratch:HI 0 "=r"))]
11320 "ix86_match_ccmode (insn, CCGOCmode)
11321 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11323 || !TARGET_PARTIAL_FLAG_REG_STALL
11324 || (operands[2] == const1_rtx
11326 || TARGET_DOUBLE_WITH_ADD)))"
11328 switch (get_attr_type (insn))
11331 gcc_assert (operands[2] == const1_rtx);
11332 return "add{w}\t{%0, %0|%0, %0}";
11335 if (REG_P (operands[2]))
11336 return "sal{w}\t{%b2, %0|%0, %b2}";
11337 else if (operands[2] == const1_rtx
11338 && (TARGET_SHIFT1 || optimize_size))
11339 return "sal{w}\t%0";
11341 return "sal{w}\t{%2, %0|%0, %2}";
11344 [(set (attr "type")
11345 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11347 (match_operand 0 "register_operand" ""))
11348 (match_operand 2 "const1_operand" ""))
11349 (const_string "alu")
11351 (const_string "ishift")))
11352 (set_attr "mode" "HI")])
11354 (define_expand "ashlqi3"
11355 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11356 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11357 (match_operand:QI 2 "nonmemory_operand" "")))
11358 (clobber (reg:CC FLAGS_REG))]
11359 "TARGET_QIMODE_MATH"
11360 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11362 ;; %%% Potential partial reg stall on alternative 2. What to do?
11364 (define_insn "*ashlqi3_1_lea"
11365 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11366 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11367 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11368 (clobber (reg:CC FLAGS_REG))]
11369 "!TARGET_PARTIAL_REG_STALL
11370 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11372 switch (get_attr_type (insn))
11377 gcc_assert (operands[2] == const1_rtx);
11378 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11379 return "add{l}\t{%k0, %k0|%k0, %k0}";
11381 return "add{b}\t{%0, %0|%0, %0}";
11384 if (REG_P (operands[2]))
11386 if (get_attr_mode (insn) == MODE_SI)
11387 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11389 return "sal{b}\t{%b2, %0|%0, %b2}";
11391 else if (operands[2] == const1_rtx
11392 && (TARGET_SHIFT1 || optimize_size))
11394 if (get_attr_mode (insn) == MODE_SI)
11395 return "sal{l}\t%0";
11397 return "sal{b}\t%0";
11401 if (get_attr_mode (insn) == MODE_SI)
11402 return "sal{l}\t{%2, %k0|%k0, %2}";
11404 return "sal{b}\t{%2, %0|%0, %2}";
11408 [(set (attr "type")
11409 (cond [(eq_attr "alternative" "2")
11410 (const_string "lea")
11411 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11413 (match_operand 0 "register_operand" ""))
11414 (match_operand 2 "const1_operand" ""))
11415 (const_string "alu")
11417 (const_string "ishift")))
11418 (set_attr "mode" "QI,SI,SI")])
11420 (define_insn "*ashlqi3_1"
11421 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11422 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11423 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11424 (clobber (reg:CC FLAGS_REG))]
11425 "TARGET_PARTIAL_REG_STALL
11426 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11428 switch (get_attr_type (insn))
11431 gcc_assert (operands[2] == const1_rtx);
11432 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11433 return "add{l}\t{%k0, %k0|%k0, %k0}";
11435 return "add{b}\t{%0, %0|%0, %0}";
11438 if (REG_P (operands[2]))
11440 if (get_attr_mode (insn) == MODE_SI)
11441 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11443 return "sal{b}\t{%b2, %0|%0, %b2}";
11445 else if (operands[2] == const1_rtx
11446 && (TARGET_SHIFT1 || optimize_size))
11448 if (get_attr_mode (insn) == MODE_SI)
11449 return "sal{l}\t%0";
11451 return "sal{b}\t%0";
11455 if (get_attr_mode (insn) == MODE_SI)
11456 return "sal{l}\t{%2, %k0|%k0, %2}";
11458 return "sal{b}\t{%2, %0|%0, %2}";
11462 [(set (attr "type")
11463 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11465 (match_operand 0 "register_operand" ""))
11466 (match_operand 2 "const1_operand" ""))
11467 (const_string "alu")
11469 (const_string "ishift")))
11470 (set_attr "mode" "QI,SI")])
11472 ;; This pattern can't accept a variable shift count, since shifts by
11473 ;; zero don't affect the flags. We assume that shifts by constant
11474 ;; zero are optimized away.
11475 (define_insn "*ashlqi3_cmp"
11476 [(set (reg FLAGS_REG)
11478 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11479 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11481 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11482 (ashift:QI (match_dup 1) (match_dup 2)))]
11483 "ix86_match_ccmode (insn, CCGOCmode)
11484 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11486 || !TARGET_PARTIAL_FLAG_REG_STALL
11487 || (operands[2] == const1_rtx
11489 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11491 switch (get_attr_type (insn))
11494 gcc_assert (operands[2] == const1_rtx);
11495 return "add{b}\t{%0, %0|%0, %0}";
11498 if (REG_P (operands[2]))
11499 return "sal{b}\t{%b2, %0|%0, %b2}";
11500 else if (operands[2] == const1_rtx
11501 && (TARGET_SHIFT1 || optimize_size))
11502 return "sal{b}\t%0";
11504 return "sal{b}\t{%2, %0|%0, %2}";
11507 [(set (attr "type")
11508 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11510 (match_operand 0 "register_operand" ""))
11511 (match_operand 2 "const1_operand" ""))
11512 (const_string "alu")
11514 (const_string "ishift")))
11515 (set_attr "mode" "QI")])
11517 (define_insn "*ashlqi3_cconly"
11518 [(set (reg FLAGS_REG)
11520 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11521 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11523 (clobber (match_scratch:QI 0 "=q"))]
11524 "ix86_match_ccmode (insn, CCGOCmode)
11525 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11527 || !TARGET_PARTIAL_FLAG_REG_STALL
11528 || (operands[2] == const1_rtx
11530 || TARGET_DOUBLE_WITH_ADD)))"
11532 switch (get_attr_type (insn))
11535 gcc_assert (operands[2] == const1_rtx);
11536 return "add{b}\t{%0, %0|%0, %0}";
11539 if (REG_P (operands[2]))
11540 return "sal{b}\t{%b2, %0|%0, %b2}";
11541 else if (operands[2] == const1_rtx
11542 && (TARGET_SHIFT1 || optimize_size))
11543 return "sal{b}\t%0";
11545 return "sal{b}\t{%2, %0|%0, %2}";
11548 [(set (attr "type")
11549 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11551 (match_operand 0 "register_operand" ""))
11552 (match_operand 2 "const1_operand" ""))
11553 (const_string "alu")
11555 (const_string "ishift")))
11556 (set_attr "mode" "QI")])
11558 ;; See comment above `ashldi3' about how this works.
11560 (define_expand "ashrti3"
11561 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11562 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11563 (match_operand:QI 2 "nonmemory_operand" "")))
11564 (clobber (reg:CC FLAGS_REG))])]
11567 if (! immediate_operand (operands[2], QImode))
11569 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11572 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11576 (define_insn "ashrti3_1"
11577 [(set (match_operand:TI 0 "register_operand" "=r")
11578 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11579 (match_operand:QI 2 "register_operand" "c")))
11580 (clobber (match_scratch:DI 3 "=&r"))
11581 (clobber (reg:CC FLAGS_REG))]
11584 [(set_attr "type" "multi")])
11586 (define_insn "*ashrti3_2"
11587 [(set (match_operand:TI 0 "register_operand" "=r")
11588 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11589 (match_operand:QI 2 "immediate_operand" "O")))
11590 (clobber (reg:CC FLAGS_REG))]
11593 [(set_attr "type" "multi")])
11596 [(set (match_operand:TI 0 "register_operand" "")
11597 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11598 (match_operand:QI 2 "register_operand" "")))
11599 (clobber (match_scratch:DI 3 ""))
11600 (clobber (reg:CC FLAGS_REG))]
11601 "TARGET_64BIT && reload_completed"
11603 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11606 [(set (match_operand:TI 0 "register_operand" "")
11607 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11608 (match_operand:QI 2 "immediate_operand" "")))
11609 (clobber (reg:CC FLAGS_REG))]
11610 "TARGET_64BIT && reload_completed"
11612 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11614 (define_insn "x86_64_shrd"
11615 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11616 (ior:DI (ashiftrt:DI (match_dup 0)
11617 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11618 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11619 (minus:QI (const_int 64) (match_dup 2)))))
11620 (clobber (reg:CC FLAGS_REG))]
11623 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11624 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11625 [(set_attr "type" "ishift")
11626 (set_attr "prefix_0f" "1")
11627 (set_attr "mode" "DI")
11628 (set_attr "athlon_decode" "vector")
11629 (set_attr "amdfam10_decode" "vector")])
11631 (define_expand "ashrdi3"
11632 [(set (match_operand:DI 0 "shiftdi_operand" "")
11633 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11634 (match_operand:QI 2 "nonmemory_operand" "")))]
11636 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11638 (define_insn "*ashrdi3_63_rex64"
11639 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11640 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11641 (match_operand:DI 2 "const_int_operand" "i,i")))
11642 (clobber (reg:CC FLAGS_REG))]
11643 "TARGET_64BIT && INTVAL (operands[2]) == 63
11644 && (TARGET_USE_CLTD || optimize_size)
11645 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11648 sar{q}\t{%2, %0|%0, %2}"
11649 [(set_attr "type" "imovx,ishift")
11650 (set_attr "prefix_0f" "0,*")
11651 (set_attr "length_immediate" "0,*")
11652 (set_attr "modrm" "0,1")
11653 (set_attr "mode" "DI")])
11655 (define_insn "*ashrdi3_1_one_bit_rex64"
11656 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11657 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11658 (match_operand:QI 2 "const1_operand" "")))
11659 (clobber (reg:CC FLAGS_REG))]
11660 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11661 && (TARGET_SHIFT1 || optimize_size)"
11663 [(set_attr "type" "ishift")
11664 (set (attr "length")
11665 (if_then_else (match_operand:DI 0 "register_operand" "")
11667 (const_string "*")))])
11669 (define_insn "*ashrdi3_1_rex64"
11670 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11671 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11672 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11673 (clobber (reg:CC FLAGS_REG))]
11674 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11676 sar{q}\t{%2, %0|%0, %2}
11677 sar{q}\t{%b2, %0|%0, %b2}"
11678 [(set_attr "type" "ishift")
11679 (set_attr "mode" "DI")])
11681 ;; This pattern can't accept a variable shift count, since shifts by
11682 ;; zero don't affect the flags. We assume that shifts by constant
11683 ;; zero are optimized away.
11684 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11685 [(set (reg FLAGS_REG)
11687 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11688 (match_operand:QI 2 "const1_operand" ""))
11690 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11691 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11692 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11693 && (TARGET_SHIFT1 || optimize_size)
11694 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11696 [(set_attr "type" "ishift")
11697 (set (attr "length")
11698 (if_then_else (match_operand:DI 0 "register_operand" "")
11700 (const_string "*")))])
11702 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11703 [(set (reg FLAGS_REG)
11705 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11706 (match_operand:QI 2 "const1_operand" ""))
11708 (clobber (match_scratch:DI 0 "=r"))]
11709 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11710 && (TARGET_SHIFT1 || optimize_size)
11711 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11713 [(set_attr "type" "ishift")
11714 (set_attr "length" "2")])
11716 ;; This pattern can't accept a variable shift count, since shifts by
11717 ;; zero don't affect the flags. We assume that shifts by constant
11718 ;; zero are optimized away.
11719 (define_insn "*ashrdi3_cmp_rex64"
11720 [(set (reg FLAGS_REG)
11722 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11723 (match_operand:QI 2 "const_int_operand" "n"))
11725 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11726 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11727 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11728 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11730 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11731 "sar{q}\t{%2, %0|%0, %2}"
11732 [(set_attr "type" "ishift")
11733 (set_attr "mode" "DI")])
11735 (define_insn "*ashrdi3_cconly_rex64"
11736 [(set (reg FLAGS_REG)
11738 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11739 (match_operand:QI 2 "const_int_operand" "n"))
11741 (clobber (match_scratch:DI 0 "=r"))]
11742 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11743 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11745 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11746 "sar{q}\t{%2, %0|%0, %2}"
11747 [(set_attr "type" "ishift")
11748 (set_attr "mode" "DI")])
11750 (define_insn "*ashrdi3_1"
11751 [(set (match_operand:DI 0 "register_operand" "=r")
11752 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11753 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11754 (clobber (reg:CC FLAGS_REG))]
11757 [(set_attr "type" "multi")])
11759 ;; By default we don't ask for a scratch register, because when DImode
11760 ;; values are manipulated, registers are already at a premium. But if
11761 ;; we have one handy, we won't turn it away.
11763 [(match_scratch:SI 3 "r")
11764 (parallel [(set (match_operand:DI 0 "register_operand" "")
11765 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11766 (match_operand:QI 2 "nonmemory_operand" "")))
11767 (clobber (reg:CC FLAGS_REG))])
11769 "!TARGET_64BIT && TARGET_CMOVE"
11771 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11774 [(set (match_operand:DI 0 "register_operand" "")
11775 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11776 (match_operand:QI 2 "nonmemory_operand" "")))
11777 (clobber (reg:CC FLAGS_REG))]
11778 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11779 ? flow2_completed : reload_completed)"
11781 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11783 (define_insn "x86_shrd_1"
11784 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11785 (ior:SI (ashiftrt:SI (match_dup 0)
11786 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11787 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11788 (minus:QI (const_int 32) (match_dup 2)))))
11789 (clobber (reg:CC FLAGS_REG))]
11792 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11793 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11794 [(set_attr "type" "ishift")
11795 (set_attr "prefix_0f" "1")
11796 (set_attr "pent_pair" "np")
11797 (set_attr "mode" "SI")])
11799 (define_expand "x86_shift_adj_3"
11800 [(use (match_operand:SI 0 "register_operand" ""))
11801 (use (match_operand:SI 1 "register_operand" ""))
11802 (use (match_operand:QI 2 "register_operand" ""))]
11805 rtx label = gen_label_rtx ();
11808 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11810 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11811 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11812 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11813 gen_rtx_LABEL_REF (VOIDmode, label),
11815 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11816 JUMP_LABEL (tmp) = label;
11818 emit_move_insn (operands[0], operands[1]);
11819 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11821 emit_label (label);
11822 LABEL_NUSES (label) = 1;
11827 (define_insn "ashrsi3_31"
11828 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11829 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11830 (match_operand:SI 2 "const_int_operand" "i,i")))
11831 (clobber (reg:CC FLAGS_REG))]
11832 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11833 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11836 sar{l}\t{%2, %0|%0, %2}"
11837 [(set_attr "type" "imovx,ishift")
11838 (set_attr "prefix_0f" "0,*")
11839 (set_attr "length_immediate" "0,*")
11840 (set_attr "modrm" "0,1")
11841 (set_attr "mode" "SI")])
11843 (define_insn "*ashrsi3_31_zext"
11844 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11845 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11846 (match_operand:SI 2 "const_int_operand" "i,i"))))
11847 (clobber (reg:CC FLAGS_REG))]
11848 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11849 && INTVAL (operands[2]) == 31
11850 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11853 sar{l}\t{%2, %k0|%k0, %2}"
11854 [(set_attr "type" "imovx,ishift")
11855 (set_attr "prefix_0f" "0,*")
11856 (set_attr "length_immediate" "0,*")
11857 (set_attr "modrm" "0,1")
11858 (set_attr "mode" "SI")])
11860 (define_expand "ashrsi3"
11861 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11862 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11863 (match_operand:QI 2 "nonmemory_operand" "")))
11864 (clobber (reg:CC FLAGS_REG))]
11866 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11868 (define_insn "*ashrsi3_1_one_bit"
11869 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11870 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11871 (match_operand:QI 2 "const1_operand" "")))
11872 (clobber (reg:CC FLAGS_REG))]
11873 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11874 && (TARGET_SHIFT1 || optimize_size)"
11876 [(set_attr "type" "ishift")
11877 (set (attr "length")
11878 (if_then_else (match_operand:SI 0 "register_operand" "")
11880 (const_string "*")))])
11882 (define_insn "*ashrsi3_1_one_bit_zext"
11883 [(set (match_operand:DI 0 "register_operand" "=r")
11884 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11885 (match_operand:QI 2 "const1_operand" ""))))
11886 (clobber (reg:CC FLAGS_REG))]
11887 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11888 && (TARGET_SHIFT1 || optimize_size)"
11890 [(set_attr "type" "ishift")
11891 (set_attr "length" "2")])
11893 (define_insn "*ashrsi3_1"
11894 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11895 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11896 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11897 (clobber (reg:CC FLAGS_REG))]
11898 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11900 sar{l}\t{%2, %0|%0, %2}
11901 sar{l}\t{%b2, %0|%0, %b2}"
11902 [(set_attr "type" "ishift")
11903 (set_attr "mode" "SI")])
11905 (define_insn "*ashrsi3_1_zext"
11906 [(set (match_operand:DI 0 "register_operand" "=r,r")
11907 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11908 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11909 (clobber (reg:CC FLAGS_REG))]
11910 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11912 sar{l}\t{%2, %k0|%k0, %2}
11913 sar{l}\t{%b2, %k0|%k0, %b2}"
11914 [(set_attr "type" "ishift")
11915 (set_attr "mode" "SI")])
11917 ;; This pattern can't accept a variable shift count, since shifts by
11918 ;; zero don't affect the flags. We assume that shifts by constant
11919 ;; zero are optimized away.
11920 (define_insn "*ashrsi3_one_bit_cmp"
11921 [(set (reg FLAGS_REG)
11923 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11924 (match_operand:QI 2 "const1_operand" ""))
11926 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11927 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11928 "ix86_match_ccmode (insn, CCGOCmode)
11929 && (TARGET_SHIFT1 || optimize_size)
11930 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11932 [(set_attr "type" "ishift")
11933 (set (attr "length")
11934 (if_then_else (match_operand:SI 0 "register_operand" "")
11936 (const_string "*")))])
11938 (define_insn "*ashrsi3_one_bit_cconly"
11939 [(set (reg FLAGS_REG)
11941 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11942 (match_operand:QI 2 "const1_operand" ""))
11944 (clobber (match_scratch:SI 0 "=r"))]
11945 "ix86_match_ccmode (insn, CCGOCmode)
11946 && (TARGET_SHIFT1 || optimize_size)
11947 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11949 [(set_attr "type" "ishift")
11950 (set_attr "length" "2")])
11952 (define_insn "*ashrsi3_one_bit_cmp_zext"
11953 [(set (reg FLAGS_REG)
11955 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11956 (match_operand:QI 2 "const1_operand" ""))
11958 (set (match_operand:DI 0 "register_operand" "=r")
11959 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11960 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11961 && (TARGET_SHIFT1 || optimize_size)
11962 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11964 [(set_attr "type" "ishift")
11965 (set_attr "length" "2")])
11967 ;; This pattern can't accept a variable shift count, since shifts by
11968 ;; zero don't affect the flags. We assume that shifts by constant
11969 ;; zero are optimized away.
11970 (define_insn "*ashrsi3_cmp"
11971 [(set (reg FLAGS_REG)
11973 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11974 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11976 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11977 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11978 "ix86_match_ccmode (insn, CCGOCmode)
11979 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11981 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11982 "sar{l}\t{%2, %0|%0, %2}"
11983 [(set_attr "type" "ishift")
11984 (set_attr "mode" "SI")])
11986 (define_insn "*ashrsi3_cconly"
11987 [(set (reg FLAGS_REG)
11989 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11990 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11992 (clobber (match_scratch:SI 0 "=r"))]
11993 "ix86_match_ccmode (insn, CCGOCmode)
11994 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11996 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11997 "sar{l}\t{%2, %0|%0, %2}"
11998 [(set_attr "type" "ishift")
11999 (set_attr "mode" "SI")])
12001 (define_insn "*ashrsi3_cmp_zext"
12002 [(set (reg FLAGS_REG)
12004 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12005 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12007 (set (match_operand:DI 0 "register_operand" "=r")
12008 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12009 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12010 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12012 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12013 "sar{l}\t{%2, %k0|%k0, %2}"
12014 [(set_attr "type" "ishift")
12015 (set_attr "mode" "SI")])
12017 (define_expand "ashrhi3"
12018 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12019 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12020 (match_operand:QI 2 "nonmemory_operand" "")))
12021 (clobber (reg:CC FLAGS_REG))]
12022 "TARGET_HIMODE_MATH"
12023 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12025 (define_insn "*ashrhi3_1_one_bit"
12026 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12027 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12028 (match_operand:QI 2 "const1_operand" "")))
12029 (clobber (reg:CC FLAGS_REG))]
12030 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12031 && (TARGET_SHIFT1 || optimize_size)"
12033 [(set_attr "type" "ishift")
12034 (set (attr "length")
12035 (if_then_else (match_operand 0 "register_operand" "")
12037 (const_string "*")))])
12039 (define_insn "*ashrhi3_1"
12040 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12041 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12042 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12043 (clobber (reg:CC FLAGS_REG))]
12044 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12046 sar{w}\t{%2, %0|%0, %2}
12047 sar{w}\t{%b2, %0|%0, %b2}"
12048 [(set_attr "type" "ishift")
12049 (set_attr "mode" "HI")])
12051 ;; This pattern can't accept a variable shift count, since shifts by
12052 ;; zero don't affect the flags. We assume that shifts by constant
12053 ;; zero are optimized away.
12054 (define_insn "*ashrhi3_one_bit_cmp"
12055 [(set (reg FLAGS_REG)
12057 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12058 (match_operand:QI 2 "const1_operand" ""))
12060 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12061 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12062 "ix86_match_ccmode (insn, CCGOCmode)
12063 && (TARGET_SHIFT1 || optimize_size)
12064 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12066 [(set_attr "type" "ishift")
12067 (set (attr "length")
12068 (if_then_else (match_operand 0 "register_operand" "")
12070 (const_string "*")))])
12072 (define_insn "*ashrhi3_one_bit_cconly"
12073 [(set (reg FLAGS_REG)
12075 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12076 (match_operand:QI 2 "const1_operand" ""))
12078 (clobber (match_scratch:HI 0 "=r"))]
12079 "ix86_match_ccmode (insn, CCGOCmode)
12080 && (TARGET_SHIFT1 || optimize_size)
12081 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12083 [(set_attr "type" "ishift")
12084 (set_attr "length" "2")])
12086 ;; This pattern can't accept a variable shift count, since shifts by
12087 ;; zero don't affect the flags. We assume that shifts by constant
12088 ;; zero are optimized away.
12089 (define_insn "*ashrhi3_cmp"
12090 [(set (reg FLAGS_REG)
12092 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12093 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12095 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12096 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12097 "ix86_match_ccmode (insn, CCGOCmode)
12098 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12100 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12101 "sar{w}\t{%2, %0|%0, %2}"
12102 [(set_attr "type" "ishift")
12103 (set_attr "mode" "HI")])
12105 (define_insn "*ashrhi3_cconly"
12106 [(set (reg FLAGS_REG)
12108 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12109 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12111 (clobber (match_scratch:HI 0 "=r"))]
12112 "ix86_match_ccmode (insn, CCGOCmode)
12113 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12115 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12116 "sar{w}\t{%2, %0|%0, %2}"
12117 [(set_attr "type" "ishift")
12118 (set_attr "mode" "HI")])
12120 (define_expand "ashrqi3"
12121 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12122 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12123 (match_operand:QI 2 "nonmemory_operand" "")))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "TARGET_QIMODE_MATH"
12126 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12128 (define_insn "*ashrqi3_1_one_bit"
12129 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12130 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12131 (match_operand:QI 2 "const1_operand" "")))
12132 (clobber (reg:CC FLAGS_REG))]
12133 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12134 && (TARGET_SHIFT1 || optimize_size)"
12136 [(set_attr "type" "ishift")
12137 (set (attr "length")
12138 (if_then_else (match_operand 0 "register_operand" "")
12140 (const_string "*")))])
12142 (define_insn "*ashrqi3_1_one_bit_slp"
12143 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12144 (ashiftrt:QI (match_dup 0)
12145 (match_operand:QI 1 "const1_operand" "")))
12146 (clobber (reg:CC FLAGS_REG))]
12147 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12148 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12149 && (TARGET_SHIFT1 || optimize_size)"
12151 [(set_attr "type" "ishift1")
12152 (set (attr "length")
12153 (if_then_else (match_operand 0 "register_operand" "")
12155 (const_string "*")))])
12157 (define_insn "*ashrqi3_1"
12158 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12159 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12160 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12161 (clobber (reg:CC FLAGS_REG))]
12162 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12164 sar{b}\t{%2, %0|%0, %2}
12165 sar{b}\t{%b2, %0|%0, %b2}"
12166 [(set_attr "type" "ishift")
12167 (set_attr "mode" "QI")])
12169 (define_insn "*ashrqi3_1_slp"
12170 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12171 (ashiftrt:QI (match_dup 0)
12172 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12173 (clobber (reg:CC FLAGS_REG))]
12174 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12175 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12177 sar{b}\t{%1, %0|%0, %1}
12178 sar{b}\t{%b1, %0|%0, %b1}"
12179 [(set_attr "type" "ishift1")
12180 (set_attr "mode" "QI")])
12182 ;; This pattern can't accept a variable shift count, since shifts by
12183 ;; zero don't affect the flags. We assume that shifts by constant
12184 ;; zero are optimized away.
12185 (define_insn "*ashrqi3_one_bit_cmp"
12186 [(set (reg FLAGS_REG)
12188 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12189 (match_operand:QI 2 "const1_operand" "I"))
12191 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12192 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12193 "ix86_match_ccmode (insn, CCGOCmode)
12194 && (TARGET_SHIFT1 || optimize_size)
12195 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12197 [(set_attr "type" "ishift")
12198 (set (attr "length")
12199 (if_then_else (match_operand 0 "register_operand" "")
12201 (const_string "*")))])
12203 (define_insn "*ashrqi3_one_bit_cconly"
12204 [(set (reg FLAGS_REG)
12206 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12207 (match_operand:QI 2 "const1_operand" "I"))
12209 (clobber (match_scratch:QI 0 "=q"))]
12210 "ix86_match_ccmode (insn, CCGOCmode)
12211 && (TARGET_SHIFT1 || optimize_size)
12212 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12214 [(set_attr "type" "ishift")
12215 (set_attr "length" "2")])
12217 ;; This pattern can't accept a variable shift count, since shifts by
12218 ;; zero don't affect the flags. We assume that shifts by constant
12219 ;; zero are optimized away.
12220 (define_insn "*ashrqi3_cmp"
12221 [(set (reg FLAGS_REG)
12223 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12224 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12226 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12227 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12228 "ix86_match_ccmode (insn, CCGOCmode)
12229 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12231 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12232 "sar{b}\t{%2, %0|%0, %2}"
12233 [(set_attr "type" "ishift")
12234 (set_attr "mode" "QI")])
12236 (define_insn "*ashrqi3_cconly"
12237 [(set (reg FLAGS_REG)
12239 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12240 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12242 (clobber (match_scratch:QI 0 "=q"))]
12243 "ix86_match_ccmode (insn, CCGOCmode)
12244 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12246 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12247 "sar{b}\t{%2, %0|%0, %2}"
12248 [(set_attr "type" "ishift")
12249 (set_attr "mode" "QI")])
12252 ;; Logical shift instructions
12254 ;; See comment above `ashldi3' about how this works.
12256 (define_expand "lshrti3"
12257 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12258 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12259 (match_operand:QI 2 "nonmemory_operand" "")))
12260 (clobber (reg:CC FLAGS_REG))])]
12263 if (! immediate_operand (operands[2], QImode))
12265 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12268 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12272 (define_insn "lshrti3_1"
12273 [(set (match_operand:TI 0 "register_operand" "=r")
12274 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12275 (match_operand:QI 2 "register_operand" "c")))
12276 (clobber (match_scratch:DI 3 "=&r"))
12277 (clobber (reg:CC FLAGS_REG))]
12280 [(set_attr "type" "multi")])
12282 (define_insn "*lshrti3_2"
12283 [(set (match_operand:TI 0 "register_operand" "=r")
12284 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12285 (match_operand:QI 2 "immediate_operand" "O")))
12286 (clobber (reg:CC FLAGS_REG))]
12289 [(set_attr "type" "multi")])
12292 [(set (match_operand:TI 0 "register_operand" "")
12293 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12294 (match_operand:QI 2 "register_operand" "")))
12295 (clobber (match_scratch:DI 3 ""))
12296 (clobber (reg:CC FLAGS_REG))]
12297 "TARGET_64BIT && reload_completed"
12299 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12302 [(set (match_operand:TI 0 "register_operand" "")
12303 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12304 (match_operand:QI 2 "immediate_operand" "")))
12305 (clobber (reg:CC FLAGS_REG))]
12306 "TARGET_64BIT && reload_completed"
12308 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12310 (define_expand "lshrdi3"
12311 [(set (match_operand:DI 0 "shiftdi_operand" "")
12312 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12313 (match_operand:QI 2 "nonmemory_operand" "")))]
12315 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12317 (define_insn "*lshrdi3_1_one_bit_rex64"
12318 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12319 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12320 (match_operand:QI 2 "const1_operand" "")))
12321 (clobber (reg:CC FLAGS_REG))]
12322 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12323 && (TARGET_SHIFT1 || optimize_size)"
12325 [(set_attr "type" "ishift")
12326 (set (attr "length")
12327 (if_then_else (match_operand:DI 0 "register_operand" "")
12329 (const_string "*")))])
12331 (define_insn "*lshrdi3_1_rex64"
12332 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12333 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12334 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12335 (clobber (reg:CC FLAGS_REG))]
12336 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12338 shr{q}\t{%2, %0|%0, %2}
12339 shr{q}\t{%b2, %0|%0, %b2}"
12340 [(set_attr "type" "ishift")
12341 (set_attr "mode" "DI")])
12343 ;; This pattern can't accept a variable shift count, since shifts by
12344 ;; zero don't affect the flags. We assume that shifts by constant
12345 ;; zero are optimized away.
12346 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12347 [(set (reg FLAGS_REG)
12349 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12350 (match_operand:QI 2 "const1_operand" ""))
12352 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12353 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12354 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12355 && (TARGET_SHIFT1 || optimize_size)
12356 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12358 [(set_attr "type" "ishift")
12359 (set (attr "length")
12360 (if_then_else (match_operand:DI 0 "register_operand" "")
12362 (const_string "*")))])
12364 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12365 [(set (reg FLAGS_REG)
12367 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const1_operand" ""))
12370 (clobber (match_scratch:DI 0 "=r"))]
12371 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12372 && (TARGET_SHIFT1 || optimize_size)
12373 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12375 [(set_attr "type" "ishift")
12376 (set_attr "length" "2")])
12378 ;; This pattern can't accept a variable shift count, since shifts by
12379 ;; zero don't affect the flags. We assume that shifts by constant
12380 ;; zero are optimized away.
12381 (define_insn "*lshrdi3_cmp_rex64"
12382 [(set (reg FLAGS_REG)
12384 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12385 (match_operand:QI 2 "const_int_operand" "e"))
12387 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12388 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12389 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12390 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12392 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12393 "shr{q}\t{%2, %0|%0, %2}"
12394 [(set_attr "type" "ishift")
12395 (set_attr "mode" "DI")])
12397 (define_insn "*lshrdi3_cconly_rex64"
12398 [(set (reg FLAGS_REG)
12400 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12401 (match_operand:QI 2 "const_int_operand" "e"))
12403 (clobber (match_scratch:DI 0 "=r"))]
12404 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12405 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12407 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12408 "shr{q}\t{%2, %0|%0, %2}"
12409 [(set_attr "type" "ishift")
12410 (set_attr "mode" "DI")])
12412 (define_insn "*lshrdi3_1"
12413 [(set (match_operand:DI 0 "register_operand" "=r")
12414 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12415 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12416 (clobber (reg:CC FLAGS_REG))]
12419 [(set_attr "type" "multi")])
12421 ;; By default we don't ask for a scratch register, because when DImode
12422 ;; values are manipulated, registers are already at a premium. But if
12423 ;; we have one handy, we won't turn it away.
12425 [(match_scratch:SI 3 "r")
12426 (parallel [(set (match_operand:DI 0 "register_operand" "")
12427 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12428 (match_operand:QI 2 "nonmemory_operand" "")))
12429 (clobber (reg:CC FLAGS_REG))])
12431 "!TARGET_64BIT && TARGET_CMOVE"
12433 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12436 [(set (match_operand:DI 0 "register_operand" "")
12437 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12438 (match_operand:QI 2 "nonmemory_operand" "")))
12439 (clobber (reg:CC FLAGS_REG))]
12440 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12441 ? flow2_completed : reload_completed)"
12443 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12445 (define_expand "lshrsi3"
12446 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12447 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12448 (match_operand:QI 2 "nonmemory_operand" "")))
12449 (clobber (reg:CC FLAGS_REG))]
12451 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12453 (define_insn "*lshrsi3_1_one_bit"
12454 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12455 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12456 (match_operand:QI 2 "const1_operand" "")))
12457 (clobber (reg:CC FLAGS_REG))]
12458 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12459 && (TARGET_SHIFT1 || optimize_size)"
12461 [(set_attr "type" "ishift")
12462 (set (attr "length")
12463 (if_then_else (match_operand:SI 0 "register_operand" "")
12465 (const_string "*")))])
12467 (define_insn "*lshrsi3_1_one_bit_zext"
12468 [(set (match_operand:DI 0 "register_operand" "=r")
12469 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12470 (match_operand:QI 2 "const1_operand" "")))
12471 (clobber (reg:CC FLAGS_REG))]
12472 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12473 && (TARGET_SHIFT1 || optimize_size)"
12475 [(set_attr "type" "ishift")
12476 (set_attr "length" "2")])
12478 (define_insn "*lshrsi3_1"
12479 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12480 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12481 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12482 (clobber (reg:CC FLAGS_REG))]
12483 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12485 shr{l}\t{%2, %0|%0, %2}
12486 shr{l}\t{%b2, %0|%0, %b2}"
12487 [(set_attr "type" "ishift")
12488 (set_attr "mode" "SI")])
12490 (define_insn "*lshrsi3_1_zext"
12491 [(set (match_operand:DI 0 "register_operand" "=r,r")
12493 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12494 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12495 (clobber (reg:CC FLAGS_REG))]
12496 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12498 shr{l}\t{%2, %k0|%k0, %2}
12499 shr{l}\t{%b2, %k0|%k0, %b2}"
12500 [(set_attr "type" "ishift")
12501 (set_attr "mode" "SI")])
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags. We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*lshrsi3_one_bit_cmp"
12507 [(set (reg FLAGS_REG)
12509 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510 (match_operand:QI 2 "const1_operand" ""))
12512 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12514 "ix86_match_ccmode (insn, CCGOCmode)
12515 && (TARGET_SHIFT1 || optimize_size)
12516 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12518 [(set_attr "type" "ishift")
12519 (set (attr "length")
12520 (if_then_else (match_operand:SI 0 "register_operand" "")
12522 (const_string "*")))])
12524 (define_insn "*lshrsi3_one_bit_cconly"
12525 [(set (reg FLAGS_REG)
12527 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12528 (match_operand:QI 2 "const1_operand" ""))
12530 (clobber (match_scratch:SI 0 "=r"))]
12531 "ix86_match_ccmode (insn, CCGOCmode)
12532 && (TARGET_SHIFT1 || optimize_size)
12533 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12535 [(set_attr "type" "ishift")
12536 (set_attr "length" "2")])
12538 (define_insn "*lshrsi3_cmp_one_bit_zext"
12539 [(set (reg FLAGS_REG)
12541 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12542 (match_operand:QI 2 "const1_operand" ""))
12544 (set (match_operand:DI 0 "register_operand" "=r")
12545 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12546 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12547 && (TARGET_SHIFT1 || optimize_size)
12548 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12550 [(set_attr "type" "ishift")
12551 (set_attr "length" "2")])
12553 ;; This pattern can't accept a variable shift count, since shifts by
12554 ;; zero don't affect the flags. We assume that shifts by constant
12555 ;; zero are optimized away.
12556 (define_insn "*lshrsi3_cmp"
12557 [(set (reg FLAGS_REG)
12559 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12560 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12562 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12563 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12564 "ix86_match_ccmode (insn, CCGOCmode)
12565 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12567 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12568 "shr{l}\t{%2, %0|%0, %2}"
12569 [(set_attr "type" "ishift")
12570 (set_attr "mode" "SI")])
12572 (define_insn "*lshrsi3_cconly"
12573 [(set (reg FLAGS_REG)
12575 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12576 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12578 (clobber (match_scratch:SI 0 "=r"))]
12579 "ix86_match_ccmode (insn, CCGOCmode)
12580 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12582 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12583 "shr{l}\t{%2, %0|%0, %2}"
12584 [(set_attr "type" "ishift")
12585 (set_attr "mode" "SI")])
12587 (define_insn "*lshrsi3_cmp_zext"
12588 [(set (reg FLAGS_REG)
12590 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12591 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12593 (set (match_operand:DI 0 "register_operand" "=r")
12594 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12595 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12596 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12598 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12599 "shr{l}\t{%2, %k0|%k0, %2}"
12600 [(set_attr "type" "ishift")
12601 (set_attr "mode" "SI")])
12603 (define_expand "lshrhi3"
12604 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12605 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12606 (match_operand:QI 2 "nonmemory_operand" "")))
12607 (clobber (reg:CC FLAGS_REG))]
12608 "TARGET_HIMODE_MATH"
12609 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12611 (define_insn "*lshrhi3_1_one_bit"
12612 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12613 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12614 (match_operand:QI 2 "const1_operand" "")))
12615 (clobber (reg:CC FLAGS_REG))]
12616 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12617 && (TARGET_SHIFT1 || optimize_size)"
12619 [(set_attr "type" "ishift")
12620 (set (attr "length")
12621 (if_then_else (match_operand 0 "register_operand" "")
12623 (const_string "*")))])
12625 (define_insn "*lshrhi3_1"
12626 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12627 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12628 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12629 (clobber (reg:CC FLAGS_REG))]
12630 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12632 shr{w}\t{%2, %0|%0, %2}
12633 shr{w}\t{%b2, %0|%0, %b2}"
12634 [(set_attr "type" "ishift")
12635 (set_attr "mode" "HI")])
12637 ;; This pattern can't accept a variable shift count, since shifts by
12638 ;; zero don't affect the flags. We assume that shifts by constant
12639 ;; zero are optimized away.
12640 (define_insn "*lshrhi3_one_bit_cmp"
12641 [(set (reg FLAGS_REG)
12643 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12644 (match_operand:QI 2 "const1_operand" ""))
12646 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12647 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12648 "ix86_match_ccmode (insn, CCGOCmode)
12649 && (TARGET_SHIFT1 || optimize_size)
12650 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12652 [(set_attr "type" "ishift")
12653 (set (attr "length")
12654 (if_then_else (match_operand:SI 0 "register_operand" "")
12656 (const_string "*")))])
12658 (define_insn "*lshrhi3_one_bit_cconly"
12659 [(set (reg FLAGS_REG)
12661 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12662 (match_operand:QI 2 "const1_operand" ""))
12664 (clobber (match_scratch:HI 0 "=r"))]
12665 "ix86_match_ccmode (insn, CCGOCmode)
12666 && (TARGET_SHIFT1 || optimize_size)
12667 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12669 [(set_attr "type" "ishift")
12670 (set_attr "length" "2")])
12672 ;; This pattern can't accept a variable shift count, since shifts by
12673 ;; zero don't affect the flags. We assume that shifts by constant
12674 ;; zero are optimized away.
12675 (define_insn "*lshrhi3_cmp"
12676 [(set (reg FLAGS_REG)
12678 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12679 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12681 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12682 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12683 "ix86_match_ccmode (insn, CCGOCmode)
12684 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12686 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12687 "shr{w}\t{%2, %0|%0, %2}"
12688 [(set_attr "type" "ishift")
12689 (set_attr "mode" "HI")])
12691 (define_insn "*lshrhi3_cconly"
12692 [(set (reg FLAGS_REG)
12694 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12695 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12697 (clobber (match_scratch:HI 0 "=r"))]
12698 "ix86_match_ccmode (insn, CCGOCmode)
12699 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12701 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12702 "shr{w}\t{%2, %0|%0, %2}"
12703 [(set_attr "type" "ishift")
12704 (set_attr "mode" "HI")])
12706 (define_expand "lshrqi3"
12707 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12708 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12709 (match_operand:QI 2 "nonmemory_operand" "")))
12710 (clobber (reg:CC FLAGS_REG))]
12711 "TARGET_QIMODE_MATH"
12712 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12714 (define_insn "*lshrqi3_1_one_bit"
12715 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12716 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12717 (match_operand:QI 2 "const1_operand" "")))
12718 (clobber (reg:CC FLAGS_REG))]
12719 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12720 && (TARGET_SHIFT1 || optimize_size)"
12722 [(set_attr "type" "ishift")
12723 (set (attr "length")
12724 (if_then_else (match_operand 0 "register_operand" "")
12726 (const_string "*")))])
12728 (define_insn "*lshrqi3_1_one_bit_slp"
12729 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12730 (lshiftrt:QI (match_dup 0)
12731 (match_operand:QI 1 "const1_operand" "")))
12732 (clobber (reg:CC FLAGS_REG))]
12733 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12734 && (TARGET_SHIFT1 || optimize_size)"
12736 [(set_attr "type" "ishift1")
12737 (set (attr "length")
12738 (if_then_else (match_operand 0 "register_operand" "")
12740 (const_string "*")))])
12742 (define_insn "*lshrqi3_1"
12743 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12744 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12745 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12746 (clobber (reg:CC FLAGS_REG))]
12747 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12749 shr{b}\t{%2, %0|%0, %2}
12750 shr{b}\t{%b2, %0|%0, %b2}"
12751 [(set_attr "type" "ishift")
12752 (set_attr "mode" "QI")])
12754 (define_insn "*lshrqi3_1_slp"
12755 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12756 (lshiftrt:QI (match_dup 0)
12757 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12758 (clobber (reg:CC FLAGS_REG))]
12759 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12760 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12762 shr{b}\t{%1, %0|%0, %1}
12763 shr{b}\t{%b1, %0|%0, %b1}"
12764 [(set_attr "type" "ishift1")
12765 (set_attr "mode" "QI")])
12767 ;; This pattern can't accept a variable shift count, since shifts by
12768 ;; zero don't affect the flags. We assume that shifts by constant
12769 ;; zero are optimized away.
12770 (define_insn "*lshrqi2_one_bit_cmp"
12771 [(set (reg FLAGS_REG)
12773 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12774 (match_operand:QI 2 "const1_operand" ""))
12776 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12777 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12778 "ix86_match_ccmode (insn, CCGOCmode)
12779 && (TARGET_SHIFT1 || optimize_size)
12780 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12782 [(set_attr "type" "ishift")
12783 (set (attr "length")
12784 (if_then_else (match_operand:SI 0 "register_operand" "")
12786 (const_string "*")))])
12788 (define_insn "*lshrqi2_one_bit_cconly"
12789 [(set (reg FLAGS_REG)
12791 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12792 (match_operand:QI 2 "const1_operand" ""))
12794 (clobber (match_scratch:QI 0 "=q"))]
12795 "ix86_match_ccmode (insn, CCGOCmode)
12796 && (TARGET_SHIFT1 || optimize_size)
12797 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12799 [(set_attr "type" "ishift")
12800 (set_attr "length" "2")])
12802 ;; This pattern can't accept a variable shift count, since shifts by
12803 ;; zero don't affect the flags. We assume that shifts by constant
12804 ;; zero are optimized away.
12805 (define_insn "*lshrqi2_cmp"
12806 [(set (reg FLAGS_REG)
12808 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12809 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12811 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12812 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12813 "ix86_match_ccmode (insn, CCGOCmode)
12814 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12816 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12817 "shr{b}\t{%2, %0|%0, %2}"
12818 [(set_attr "type" "ishift")
12819 (set_attr "mode" "QI")])
12821 (define_insn "*lshrqi2_cconly"
12822 [(set (reg FLAGS_REG)
12824 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12825 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12827 (clobber (match_scratch:QI 0 "=q"))]
12828 "ix86_match_ccmode (insn, CCGOCmode)
12829 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12831 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12832 "shr{b}\t{%2, %0|%0, %2}"
12833 [(set_attr "type" "ishift")
12834 (set_attr "mode" "QI")])
12836 ;; Rotate instructions
12838 (define_expand "rotldi3"
12839 [(set (match_operand:DI 0 "shiftdi_operand" "")
12840 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12841 (match_operand:QI 2 "nonmemory_operand" "")))
12842 (clobber (reg:CC FLAGS_REG))]
12847 ix86_expand_binary_operator (ROTATE, DImode, operands);
12850 if (!const_1_to_31_operand (operands[2], VOIDmode))
12852 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12856 ;; Implement rotation using two double-precision shift instructions
12857 ;; and a scratch register.
12858 (define_insn_and_split "ix86_rotldi3"
12859 [(set (match_operand:DI 0 "register_operand" "=r")
12860 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12861 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12862 (clobber (reg:CC FLAGS_REG))
12863 (clobber (match_scratch:SI 3 "=&r"))]
12866 "&& reload_completed"
12867 [(set (match_dup 3) (match_dup 4))
12869 [(set (match_dup 4)
12870 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12871 (lshiftrt:SI (match_dup 5)
12872 (minus:QI (const_int 32) (match_dup 2)))))
12873 (clobber (reg:CC FLAGS_REG))])
12875 [(set (match_dup 5)
12876 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12877 (lshiftrt:SI (match_dup 3)
12878 (minus:QI (const_int 32) (match_dup 2)))))
12879 (clobber (reg:CC FLAGS_REG))])]
12880 "split_di (operands, 1, operands + 4, operands + 5);")
12882 (define_insn "*rotlsi3_1_one_bit_rex64"
12883 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12884 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12885 (match_operand:QI 2 "const1_operand" "")))
12886 (clobber (reg:CC FLAGS_REG))]
12887 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12888 && (TARGET_SHIFT1 || optimize_size)"
12890 [(set_attr "type" "rotate")
12891 (set (attr "length")
12892 (if_then_else (match_operand:DI 0 "register_operand" "")
12894 (const_string "*")))])
12896 (define_insn "*rotldi3_1_rex64"
12897 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12898 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12899 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12900 (clobber (reg:CC FLAGS_REG))]
12901 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12903 rol{q}\t{%2, %0|%0, %2}
12904 rol{q}\t{%b2, %0|%0, %b2}"
12905 [(set_attr "type" "rotate")
12906 (set_attr "mode" "DI")])
12908 (define_expand "rotlsi3"
12909 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12910 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12911 (match_operand:QI 2 "nonmemory_operand" "")))
12912 (clobber (reg:CC FLAGS_REG))]
12914 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12916 (define_insn "*rotlsi3_1_one_bit"
12917 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12918 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12919 (match_operand:QI 2 "const1_operand" "")))
12920 (clobber (reg:CC FLAGS_REG))]
12921 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12922 && (TARGET_SHIFT1 || optimize_size)"
12924 [(set_attr "type" "rotate")
12925 (set (attr "length")
12926 (if_then_else (match_operand:SI 0 "register_operand" "")
12928 (const_string "*")))])
12930 (define_insn "*rotlsi3_1_one_bit_zext"
12931 [(set (match_operand:DI 0 "register_operand" "=r")
12933 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12934 (match_operand:QI 2 "const1_operand" ""))))
12935 (clobber (reg:CC FLAGS_REG))]
12936 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12937 && (TARGET_SHIFT1 || optimize_size)"
12939 [(set_attr "type" "rotate")
12940 (set_attr "length" "2")])
12942 (define_insn "*rotlsi3_1"
12943 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12944 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12945 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12946 (clobber (reg:CC FLAGS_REG))]
12947 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12949 rol{l}\t{%2, %0|%0, %2}
12950 rol{l}\t{%b2, %0|%0, %b2}"
12951 [(set_attr "type" "rotate")
12952 (set_attr "mode" "SI")])
12954 (define_insn "*rotlsi3_1_zext"
12955 [(set (match_operand:DI 0 "register_operand" "=r,r")
12957 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12958 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12962 rol{l}\t{%2, %k0|%k0, %2}
12963 rol{l}\t{%b2, %k0|%k0, %b2}"
12964 [(set_attr "type" "rotate")
12965 (set_attr "mode" "SI")])
12967 (define_expand "rotlhi3"
12968 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12969 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12970 (match_operand:QI 2 "nonmemory_operand" "")))
12971 (clobber (reg:CC FLAGS_REG))]
12972 "TARGET_HIMODE_MATH"
12973 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12975 (define_insn "*rotlhi3_1_one_bit"
12976 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12977 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12978 (match_operand:QI 2 "const1_operand" "")))
12979 (clobber (reg:CC FLAGS_REG))]
12980 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12981 && (TARGET_SHIFT1 || optimize_size)"
12983 [(set_attr "type" "rotate")
12984 (set (attr "length")
12985 (if_then_else (match_operand 0 "register_operand" "")
12987 (const_string "*")))])
12989 (define_insn "*rotlhi3_1"
12990 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12991 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12992 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12993 (clobber (reg:CC FLAGS_REG))]
12994 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12996 rol{w}\t{%2, %0|%0, %2}
12997 rol{w}\t{%b2, %0|%0, %b2}"
12998 [(set_attr "type" "rotate")
12999 (set_attr "mode" "HI")])
13001 (define_expand "rotlqi3"
13002 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13003 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13004 (match_operand:QI 2 "nonmemory_operand" "")))
13005 (clobber (reg:CC FLAGS_REG))]
13006 "TARGET_QIMODE_MATH"
13007 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13009 (define_insn "*rotlqi3_1_one_bit_slp"
13010 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13011 (rotate:QI (match_dup 0)
13012 (match_operand:QI 1 "const1_operand" "")))
13013 (clobber (reg:CC FLAGS_REG))]
13014 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13015 && (TARGET_SHIFT1 || optimize_size)"
13017 [(set_attr "type" "rotate1")
13018 (set (attr "length")
13019 (if_then_else (match_operand 0 "register_operand" "")
13021 (const_string "*")))])
13023 (define_insn "*rotlqi3_1_one_bit"
13024 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13025 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13026 (match_operand:QI 2 "const1_operand" "")))
13027 (clobber (reg:CC FLAGS_REG))]
13028 "ix86_binary_operator_ok (ROTATE, QImode, operands)
13029 && (TARGET_SHIFT1 || optimize_size)"
13031 [(set_attr "type" "rotate")
13032 (set (attr "length")
13033 (if_then_else (match_operand 0 "register_operand" "")
13035 (const_string "*")))])
13037 (define_insn "*rotlqi3_1_slp"
13038 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13039 (rotate:QI (match_dup 0)
13040 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13041 (clobber (reg:CC FLAGS_REG))]
13042 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13043 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13045 rol{b}\t{%1, %0|%0, %1}
13046 rol{b}\t{%b1, %0|%0, %b1}"
13047 [(set_attr "type" "rotate1")
13048 (set_attr "mode" "QI")])
13050 (define_insn "*rotlqi3_1"
13051 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13052 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13053 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13054 (clobber (reg:CC FLAGS_REG))]
13055 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13057 rol{b}\t{%2, %0|%0, %2}
13058 rol{b}\t{%b2, %0|%0, %b2}"
13059 [(set_attr "type" "rotate")
13060 (set_attr "mode" "QI")])
13062 (define_expand "rotrdi3"
13063 [(set (match_operand:DI 0 "shiftdi_operand" "")
13064 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13065 (match_operand:QI 2 "nonmemory_operand" "")))
13066 (clobber (reg:CC FLAGS_REG))]
13071 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13074 if (!const_1_to_31_operand (operands[2], VOIDmode))
13076 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13080 ;; Implement rotation using two double-precision shift instructions
13081 ;; and a scratch register.
13082 (define_insn_and_split "ix86_rotrdi3"
13083 [(set (match_operand:DI 0 "register_operand" "=r")
13084 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13085 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13086 (clobber (reg:CC FLAGS_REG))
13087 (clobber (match_scratch:SI 3 "=&r"))]
13090 "&& reload_completed"
13091 [(set (match_dup 3) (match_dup 4))
13093 [(set (match_dup 4)
13094 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13095 (ashift:SI (match_dup 5)
13096 (minus:QI (const_int 32) (match_dup 2)))))
13097 (clobber (reg:CC FLAGS_REG))])
13099 [(set (match_dup 5)
13100 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13101 (ashift:SI (match_dup 3)
13102 (minus:QI (const_int 32) (match_dup 2)))))
13103 (clobber (reg:CC FLAGS_REG))])]
13104 "split_di (operands, 1, operands + 4, operands + 5);")
13106 (define_insn "*rotrdi3_1_one_bit_rex64"
13107 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13108 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13109 (match_operand:QI 2 "const1_operand" "")))
13110 (clobber (reg:CC FLAGS_REG))]
13111 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13112 && (TARGET_SHIFT1 || optimize_size)"
13114 [(set_attr "type" "rotate")
13115 (set (attr "length")
13116 (if_then_else (match_operand:DI 0 "register_operand" "")
13118 (const_string "*")))])
13120 (define_insn "*rotrdi3_1_rex64"
13121 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13122 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13123 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13124 (clobber (reg:CC FLAGS_REG))]
13125 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13127 ror{q}\t{%2, %0|%0, %2}
13128 ror{q}\t{%b2, %0|%0, %b2}"
13129 [(set_attr "type" "rotate")
13130 (set_attr "mode" "DI")])
13132 (define_expand "rotrsi3"
13133 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13134 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13135 (match_operand:QI 2 "nonmemory_operand" "")))
13136 (clobber (reg:CC FLAGS_REG))]
13138 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13140 (define_insn "*rotrsi3_1_one_bit"
13141 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13142 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13143 (match_operand:QI 2 "const1_operand" "")))
13144 (clobber (reg:CC FLAGS_REG))]
13145 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13146 && (TARGET_SHIFT1 || optimize_size)"
13148 [(set_attr "type" "rotate")
13149 (set (attr "length")
13150 (if_then_else (match_operand:SI 0 "register_operand" "")
13152 (const_string "*")))])
13154 (define_insn "*rotrsi3_1_one_bit_zext"
13155 [(set (match_operand:DI 0 "register_operand" "=r")
13157 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13158 (match_operand:QI 2 "const1_operand" ""))))
13159 (clobber (reg:CC FLAGS_REG))]
13160 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13161 && (TARGET_SHIFT1 || optimize_size)"
13163 [(set_attr "type" "rotate")
13164 (set (attr "length")
13165 (if_then_else (match_operand:SI 0 "register_operand" "")
13167 (const_string "*")))])
13169 (define_insn "*rotrsi3_1"
13170 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13171 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13172 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13173 (clobber (reg:CC FLAGS_REG))]
13174 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13176 ror{l}\t{%2, %0|%0, %2}
13177 ror{l}\t{%b2, %0|%0, %b2}"
13178 [(set_attr "type" "rotate")
13179 (set_attr "mode" "SI")])
13181 (define_insn "*rotrsi3_1_zext"
13182 [(set (match_operand:DI 0 "register_operand" "=r,r")
13184 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13185 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13186 (clobber (reg:CC FLAGS_REG))]
13187 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13189 ror{l}\t{%2, %k0|%k0, %2}
13190 ror{l}\t{%b2, %k0|%k0, %b2}"
13191 [(set_attr "type" "rotate")
13192 (set_attr "mode" "SI")])
13194 (define_expand "rotrhi3"
13195 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13196 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13197 (match_operand:QI 2 "nonmemory_operand" "")))
13198 (clobber (reg:CC FLAGS_REG))]
13199 "TARGET_HIMODE_MATH"
13200 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13202 (define_insn "*rotrhi3_one_bit"
13203 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13204 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13205 (match_operand:QI 2 "const1_operand" "")))
13206 (clobber (reg:CC FLAGS_REG))]
13207 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13208 && (TARGET_SHIFT1 || optimize_size)"
13210 [(set_attr "type" "rotate")
13211 (set (attr "length")
13212 (if_then_else (match_operand 0 "register_operand" "")
13214 (const_string "*")))])
13216 (define_insn "*rotrhi3"
13217 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13218 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13219 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13220 (clobber (reg:CC FLAGS_REG))]
13221 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13223 ror{w}\t{%2, %0|%0, %2}
13224 ror{w}\t{%b2, %0|%0, %b2}"
13225 [(set_attr "type" "rotate")
13226 (set_attr "mode" "HI")])
13228 (define_expand "rotrqi3"
13229 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13230 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13231 (match_operand:QI 2 "nonmemory_operand" "")))
13232 (clobber (reg:CC FLAGS_REG))]
13233 "TARGET_QIMODE_MATH"
13234 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13236 (define_insn "*rotrqi3_1_one_bit"
13237 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13238 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13239 (match_operand:QI 2 "const1_operand" "")))
13240 (clobber (reg:CC FLAGS_REG))]
13241 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13242 && (TARGET_SHIFT1 || optimize_size)"
13244 [(set_attr "type" "rotate")
13245 (set (attr "length")
13246 (if_then_else (match_operand 0 "register_operand" "")
13248 (const_string "*")))])
13250 (define_insn "*rotrqi3_1_one_bit_slp"
13251 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13252 (rotatert:QI (match_dup 0)
13253 (match_operand:QI 1 "const1_operand" "")))
13254 (clobber (reg:CC FLAGS_REG))]
13255 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13256 && (TARGET_SHIFT1 || optimize_size)"
13258 [(set_attr "type" "rotate1")
13259 (set (attr "length")
13260 (if_then_else (match_operand 0 "register_operand" "")
13262 (const_string "*")))])
13264 (define_insn "*rotrqi3_1"
13265 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13266 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13267 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13268 (clobber (reg:CC FLAGS_REG))]
13269 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13271 ror{b}\t{%2, %0|%0, %2}
13272 ror{b}\t{%b2, %0|%0, %b2}"
13273 [(set_attr "type" "rotate")
13274 (set_attr "mode" "QI")])
13276 (define_insn "*rotrqi3_1_slp"
13277 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13278 (rotatert:QI (match_dup 0)
13279 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13280 (clobber (reg:CC FLAGS_REG))]
13281 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13282 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13284 ror{b}\t{%1, %0|%0, %1}
13285 ror{b}\t{%b1, %0|%0, %b1}"
13286 [(set_attr "type" "rotate1")
13287 (set_attr "mode" "QI")])
13289 ;; Bit set / bit test instructions
13291 (define_expand "extv"
13292 [(set (match_operand:SI 0 "register_operand" "")
13293 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13294 (match_operand:SI 2 "const8_operand" "")
13295 (match_operand:SI 3 "const8_operand" "")))]
13298 /* Handle extractions from %ah et al. */
13299 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13302 /* From mips.md: extract_bit_field doesn't verify that our source
13303 matches the predicate, so check it again here. */
13304 if (! ext_register_operand (operands[1], VOIDmode))
13308 (define_expand "extzv"
13309 [(set (match_operand:SI 0 "register_operand" "")
13310 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13311 (match_operand:SI 2 "const8_operand" "")
13312 (match_operand:SI 3 "const8_operand" "")))]
13315 /* Handle extractions from %ah et al. */
13316 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13319 /* From mips.md: extract_bit_field doesn't verify that our source
13320 matches the predicate, so check it again here. */
13321 if (! ext_register_operand (operands[1], VOIDmode))
13325 (define_expand "insv"
13326 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13327 (match_operand 1 "const8_operand" "")
13328 (match_operand 2 "const8_operand" ""))
13329 (match_operand 3 "register_operand" ""))]
13332 /* Handle insertions to %ah et al. */
13333 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13336 /* From mips.md: insert_bit_field doesn't verify that our source
13337 matches the predicate, so check it again here. */
13338 if (! ext_register_operand (operands[0], VOIDmode))
13342 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13344 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13349 ;; %%% bts, btr, btc, bt.
13350 ;; In general these instructions are *slow* when applied to memory,
13351 ;; since they enforce atomic operation. When applied to registers,
13352 ;; it depends on the cpu implementation. They're never faster than
13353 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13354 ;; no point. But in 64-bit, we can't hold the relevant immediates
13355 ;; within the instruction itself, so operating on bits in the high
13356 ;; 32-bits of a register becomes easier.
13358 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13359 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13360 ;; negdf respectively, so they can never be disabled entirely.
13362 (define_insn "*btsq"
13363 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13365 (match_operand:DI 1 "const_0_to_63_operand" ""))
13367 (clobber (reg:CC FLAGS_REG))]
13368 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13370 [(set_attr "type" "alu1")])
13372 (define_insn "*btrq"
13373 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13375 (match_operand:DI 1 "const_0_to_63_operand" ""))
13377 (clobber (reg:CC FLAGS_REG))]
13378 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13380 [(set_attr "type" "alu1")])
13382 (define_insn "*btcq"
13383 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13385 (match_operand:DI 1 "const_0_to_63_operand" ""))
13386 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13387 (clobber (reg:CC FLAGS_REG))]
13388 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13390 [(set_attr "type" "alu1")])
13392 ;; Allow Nocona to avoid these instructions if a register is available.
13395 [(match_scratch:DI 2 "r")
13396 (parallel [(set (zero_extract:DI
13397 (match_operand:DI 0 "register_operand" "")
13399 (match_operand:DI 1 "const_0_to_63_operand" ""))
13401 (clobber (reg:CC FLAGS_REG))])]
13402 "TARGET_64BIT && !TARGET_USE_BT"
13405 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13408 if (HOST_BITS_PER_WIDE_INT >= 64)
13409 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13410 else if (i < HOST_BITS_PER_WIDE_INT)
13411 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13413 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13415 op1 = immed_double_const (lo, hi, DImode);
13418 emit_move_insn (operands[2], op1);
13422 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13427 [(match_scratch:DI 2 "r")
13428 (parallel [(set (zero_extract:DI
13429 (match_operand:DI 0 "register_operand" "")
13431 (match_operand:DI 1 "const_0_to_63_operand" ""))
13433 (clobber (reg:CC FLAGS_REG))])]
13434 "TARGET_64BIT && !TARGET_USE_BT"
13437 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13440 if (HOST_BITS_PER_WIDE_INT >= 64)
13441 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13442 else if (i < HOST_BITS_PER_WIDE_INT)
13443 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13445 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13447 op1 = immed_double_const (~lo, ~hi, DImode);
13450 emit_move_insn (operands[2], op1);
13454 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13459 [(match_scratch:DI 2 "r")
13460 (parallel [(set (zero_extract:DI
13461 (match_operand:DI 0 "register_operand" "")
13463 (match_operand:DI 1 "const_0_to_63_operand" ""))
13464 (not:DI (zero_extract:DI
13465 (match_dup 0) (const_int 1) (match_dup 1))))
13466 (clobber (reg:CC FLAGS_REG))])]
13467 "TARGET_64BIT && !TARGET_USE_BT"
13470 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13473 if (HOST_BITS_PER_WIDE_INT >= 64)
13474 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13475 else if (i < HOST_BITS_PER_WIDE_INT)
13476 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13478 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13480 op1 = immed_double_const (lo, hi, DImode);
13483 emit_move_insn (operands[2], op1);
13487 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13491 ;; Store-flag instructions.
13493 ;; For all sCOND expanders, also expand the compare or test insn that
13494 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13496 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13497 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13498 ;; way, which can later delete the movzx if only QImode is needed.
13500 (define_expand "seq"
13501 [(set (match_operand:QI 0 "register_operand" "")
13502 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13504 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13506 (define_expand "sne"
13507 [(set (match_operand:QI 0 "register_operand" "")
13508 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13510 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13512 (define_expand "sgt"
13513 [(set (match_operand:QI 0 "register_operand" "")
13514 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13516 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13518 (define_expand "sgtu"
13519 [(set (match_operand:QI 0 "register_operand" "")
13520 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13522 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13524 (define_expand "slt"
13525 [(set (match_operand:QI 0 "register_operand" "")
13526 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13528 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13530 (define_expand "sltu"
13531 [(set (match_operand:QI 0 "register_operand" "")
13532 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13534 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13536 (define_expand "sge"
13537 [(set (match_operand:QI 0 "register_operand" "")
13538 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13540 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13542 (define_expand "sgeu"
13543 [(set (match_operand:QI 0 "register_operand" "")
13544 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13546 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13548 (define_expand "sle"
13549 [(set (match_operand:QI 0 "register_operand" "")
13550 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13552 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13554 (define_expand "sleu"
13555 [(set (match_operand:QI 0 "register_operand" "")
13556 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13558 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13560 (define_expand "sunordered"
13561 [(set (match_operand:QI 0 "register_operand" "")
13562 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13563 "TARGET_80387 || TARGET_SSE"
13564 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13566 (define_expand "sordered"
13567 [(set (match_operand:QI 0 "register_operand" "")
13568 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13570 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13572 (define_expand "suneq"
13573 [(set (match_operand:QI 0 "register_operand" "")
13574 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13575 "TARGET_80387 || TARGET_SSE"
13576 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13578 (define_expand "sunge"
13579 [(set (match_operand:QI 0 "register_operand" "")
13580 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13581 "TARGET_80387 || TARGET_SSE"
13582 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13584 (define_expand "sungt"
13585 [(set (match_operand:QI 0 "register_operand" "")
13586 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13587 "TARGET_80387 || TARGET_SSE"
13588 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13590 (define_expand "sunle"
13591 [(set (match_operand:QI 0 "register_operand" "")
13592 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13593 "TARGET_80387 || TARGET_SSE"
13594 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13596 (define_expand "sunlt"
13597 [(set (match_operand:QI 0 "register_operand" "")
13598 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13599 "TARGET_80387 || TARGET_SSE"
13600 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13602 (define_expand "sltgt"
13603 [(set (match_operand:QI 0 "register_operand" "")
13604 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13605 "TARGET_80387 || TARGET_SSE"
13606 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13608 (define_insn "*setcc_1"
13609 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13610 (match_operator:QI 1 "ix86_comparison_operator"
13611 [(reg FLAGS_REG) (const_int 0)]))]
13614 [(set_attr "type" "setcc")
13615 (set_attr "mode" "QI")])
13617 (define_insn "*setcc_2"
13618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13619 (match_operator:QI 1 "ix86_comparison_operator"
13620 [(reg FLAGS_REG) (const_int 0)]))]
13623 [(set_attr "type" "setcc")
13624 (set_attr "mode" "QI")])
13626 ;; In general it is not safe to assume too much about CCmode registers,
13627 ;; so simplify-rtx stops when it sees a second one. Under certain
13628 ;; conditions this is safe on x86, so help combine not create
13635 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13636 (ne:QI (match_operator 1 "ix86_comparison_operator"
13637 [(reg FLAGS_REG) (const_int 0)])
13640 [(set (match_dup 0) (match_dup 1))]
13642 PUT_MODE (operands[1], QImode);
13646 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13647 (ne:QI (match_operator 1 "ix86_comparison_operator"
13648 [(reg FLAGS_REG) (const_int 0)])
13651 [(set (match_dup 0) (match_dup 1))]
13653 PUT_MODE (operands[1], QImode);
13657 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13658 (eq:QI (match_operator 1 "ix86_comparison_operator"
13659 [(reg FLAGS_REG) (const_int 0)])
13662 [(set (match_dup 0) (match_dup 1))]
13664 rtx new_op1 = copy_rtx (operands[1]);
13665 operands[1] = new_op1;
13666 PUT_MODE (new_op1, QImode);
13667 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13668 GET_MODE (XEXP (new_op1, 0))));
13670 /* Make sure that (a) the CCmode we have for the flags is strong
13671 enough for the reversed compare or (b) we have a valid FP compare. */
13672 if (! ix86_comparison_operator (new_op1, VOIDmode))
13677 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13678 (eq:QI (match_operator 1 "ix86_comparison_operator"
13679 [(reg FLAGS_REG) (const_int 0)])
13682 [(set (match_dup 0) (match_dup 1))]
13684 rtx new_op1 = copy_rtx (operands[1]);
13685 operands[1] = new_op1;
13686 PUT_MODE (new_op1, QImode);
13687 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13688 GET_MODE (XEXP (new_op1, 0))));
13690 /* Make sure that (a) the CCmode we have for the flags is strong
13691 enough for the reversed compare or (b) we have a valid FP compare. */
13692 if (! ix86_comparison_operator (new_op1, VOIDmode))
13696 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13697 ;; subsequent logical operations are used to imitate conditional moves.
13698 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13701 (define_insn "*sse_setccsf"
13702 [(set (match_operand:SF 0 "register_operand" "=x")
13703 (match_operator:SF 1 "sse_comparison_operator"
13704 [(match_operand:SF 2 "register_operand" "0")
13705 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13707 "cmp%D1ss\t{%3, %0|%0, %3}"
13708 [(set_attr "type" "ssecmp")
13709 (set_attr "mode" "SF")])
13711 (define_insn "*sse_setccdf"
13712 [(set (match_operand:DF 0 "register_operand" "=x")
13713 (match_operator:DF 1 "sse_comparison_operator"
13714 [(match_operand:DF 2 "register_operand" "0")
13715 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13717 "cmp%D1sd\t{%3, %0|%0, %3}"
13718 [(set_attr "type" "ssecmp")
13719 (set_attr "mode" "DF")])
13721 ;; Basic conditional jump instructions.
13722 ;; We ignore the overflow flag for signed branch instructions.
13724 ;; For all bCOND expanders, also expand the compare or test insn that
13725 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13727 (define_expand "beq"
13729 (if_then_else (match_dup 1)
13730 (label_ref (match_operand 0 "" ""))
13733 "ix86_expand_branch (EQ, operands[0]); DONE;")
13735 (define_expand "bne"
13737 (if_then_else (match_dup 1)
13738 (label_ref (match_operand 0 "" ""))
13741 "ix86_expand_branch (NE, operands[0]); DONE;")
13743 (define_expand "bgt"
13745 (if_then_else (match_dup 1)
13746 (label_ref (match_operand 0 "" ""))
13749 "ix86_expand_branch (GT, operands[0]); DONE;")
13751 (define_expand "bgtu"
13753 (if_then_else (match_dup 1)
13754 (label_ref (match_operand 0 "" ""))
13757 "ix86_expand_branch (GTU, operands[0]); DONE;")
13759 (define_expand "blt"
13761 (if_then_else (match_dup 1)
13762 (label_ref (match_operand 0 "" ""))
13765 "ix86_expand_branch (LT, operands[0]); DONE;")
13767 (define_expand "bltu"
13769 (if_then_else (match_dup 1)
13770 (label_ref (match_operand 0 "" ""))
13773 "ix86_expand_branch (LTU, operands[0]); DONE;")
13775 (define_expand "bge"
13777 (if_then_else (match_dup 1)
13778 (label_ref (match_operand 0 "" ""))
13781 "ix86_expand_branch (GE, operands[0]); DONE;")
13783 (define_expand "bgeu"
13785 (if_then_else (match_dup 1)
13786 (label_ref (match_operand 0 "" ""))
13789 "ix86_expand_branch (GEU, operands[0]); DONE;")
13791 (define_expand "ble"
13793 (if_then_else (match_dup 1)
13794 (label_ref (match_operand 0 "" ""))
13797 "ix86_expand_branch (LE, operands[0]); DONE;")
13799 (define_expand "bleu"
13801 (if_then_else (match_dup 1)
13802 (label_ref (match_operand 0 "" ""))
13805 "ix86_expand_branch (LEU, operands[0]); DONE;")
13807 (define_expand "bunordered"
13809 (if_then_else (match_dup 1)
13810 (label_ref (match_operand 0 "" ""))
13812 "TARGET_80387 || TARGET_SSE_MATH"
13813 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13815 (define_expand "bordered"
13817 (if_then_else (match_dup 1)
13818 (label_ref (match_operand 0 "" ""))
13820 "TARGET_80387 || TARGET_SSE_MATH"
13821 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13823 (define_expand "buneq"
13825 (if_then_else (match_dup 1)
13826 (label_ref (match_operand 0 "" ""))
13828 "TARGET_80387 || TARGET_SSE_MATH"
13829 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13831 (define_expand "bunge"
13833 (if_then_else (match_dup 1)
13834 (label_ref (match_operand 0 "" ""))
13836 "TARGET_80387 || TARGET_SSE_MATH"
13837 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13839 (define_expand "bungt"
13841 (if_then_else (match_dup 1)
13842 (label_ref (match_operand 0 "" ""))
13844 "TARGET_80387 || TARGET_SSE_MATH"
13845 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13847 (define_expand "bunle"
13849 (if_then_else (match_dup 1)
13850 (label_ref (match_operand 0 "" ""))
13852 "TARGET_80387 || TARGET_SSE_MATH"
13853 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13855 (define_expand "bunlt"
13857 (if_then_else (match_dup 1)
13858 (label_ref (match_operand 0 "" ""))
13860 "TARGET_80387 || TARGET_SSE_MATH"
13861 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13863 (define_expand "bltgt"
13865 (if_then_else (match_dup 1)
13866 (label_ref (match_operand 0 "" ""))
13868 "TARGET_80387 || TARGET_SSE_MATH"
13869 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13871 (define_insn "*jcc_1"
13873 (if_then_else (match_operator 1 "ix86_comparison_operator"
13874 [(reg FLAGS_REG) (const_int 0)])
13875 (label_ref (match_operand 0 "" ""))
13879 [(set_attr "type" "ibr")
13880 (set_attr "modrm" "0")
13881 (set (attr "length")
13882 (if_then_else (and (ge (minus (match_dup 0) (pc))
13884 (lt (minus (match_dup 0) (pc))
13889 (define_insn "*jcc_2"
13891 (if_then_else (match_operator 1 "ix86_comparison_operator"
13892 [(reg FLAGS_REG) (const_int 0)])
13894 (label_ref (match_operand 0 "" ""))))]
13897 [(set_attr "type" "ibr")
13898 (set_attr "modrm" "0")
13899 (set (attr "length")
13900 (if_then_else (and (ge (minus (match_dup 0) (pc))
13902 (lt (minus (match_dup 0) (pc))
13907 ;; In general it is not safe to assume too much about CCmode registers,
13908 ;; so simplify-rtx stops when it sees a second one. Under certain
13909 ;; conditions this is safe on x86, so help combine not create
13917 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13918 [(reg FLAGS_REG) (const_int 0)])
13920 (label_ref (match_operand 1 "" ""))
13924 (if_then_else (match_dup 0)
13925 (label_ref (match_dup 1))
13928 PUT_MODE (operands[0], VOIDmode);
13933 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13934 [(reg FLAGS_REG) (const_int 0)])
13936 (label_ref (match_operand 1 "" ""))
13940 (if_then_else (match_dup 0)
13941 (label_ref (match_dup 1))
13944 rtx new_op0 = copy_rtx (operands[0]);
13945 operands[0] = new_op0;
13946 PUT_MODE (new_op0, VOIDmode);
13947 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13948 GET_MODE (XEXP (new_op0, 0))));
13950 /* Make sure that (a) the CCmode we have for the flags is strong
13951 enough for the reversed compare or (b) we have a valid FP compare. */
13952 if (! ix86_comparison_operator (new_op0, VOIDmode))
13956 ;; Define combination compare-and-branch fp compare instructions to use
13957 ;; during early optimization. Splitting the operation apart early makes
13958 ;; for bad code when we want to reverse the operation.
13960 (define_insn "*fp_jcc_1_mixed"
13962 (if_then_else (match_operator 0 "comparison_operator"
13963 [(match_operand 1 "register_operand" "f,x")
13964 (match_operand 2 "nonimmediate_operand" "f,xm")])
13965 (label_ref (match_operand 3 "" ""))
13967 (clobber (reg:CCFP FPSR_REG))
13968 (clobber (reg:CCFP FLAGS_REG))]
13969 "TARGET_MIX_SSE_I387
13970 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13971 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13972 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13975 (define_insn "*fp_jcc_1_sse"
13977 (if_then_else (match_operator 0 "comparison_operator"
13978 [(match_operand 1 "register_operand" "x")
13979 (match_operand 2 "nonimmediate_operand" "xm")])
13980 (label_ref (match_operand 3 "" ""))
13982 (clobber (reg:CCFP FPSR_REG))
13983 (clobber (reg:CCFP FLAGS_REG))]
13985 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13986 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13987 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13990 (define_insn "*fp_jcc_1_387"
13992 (if_then_else (match_operator 0 "comparison_operator"
13993 [(match_operand 1 "register_operand" "f")
13994 (match_operand 2 "register_operand" "f")])
13995 (label_ref (match_operand 3 "" ""))
13997 (clobber (reg:CCFP FPSR_REG))
13998 (clobber (reg:CCFP FLAGS_REG))]
13999 "TARGET_CMOVE && TARGET_80387
14000 && FLOAT_MODE_P (GET_MODE (operands[1]))
14001 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14002 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14005 (define_insn "*fp_jcc_2_mixed"
14007 (if_then_else (match_operator 0 "comparison_operator"
14008 [(match_operand 1 "register_operand" "f,x")
14009 (match_operand 2 "nonimmediate_operand" "f,xm")])
14011 (label_ref (match_operand 3 "" ""))))
14012 (clobber (reg:CCFP FPSR_REG))
14013 (clobber (reg:CCFP FLAGS_REG))]
14014 "TARGET_MIX_SSE_I387
14015 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14016 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14017 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14020 (define_insn "*fp_jcc_2_sse"
14022 (if_then_else (match_operator 0 "comparison_operator"
14023 [(match_operand 1 "register_operand" "x")
14024 (match_operand 2 "nonimmediate_operand" "xm")])
14026 (label_ref (match_operand 3 "" ""))))
14027 (clobber (reg:CCFP FPSR_REG))
14028 (clobber (reg:CCFP FLAGS_REG))]
14030 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14031 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14032 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14035 (define_insn "*fp_jcc_2_387"
14037 (if_then_else (match_operator 0 "comparison_operator"
14038 [(match_operand 1 "register_operand" "f")
14039 (match_operand 2 "register_operand" "f")])
14041 (label_ref (match_operand 3 "" ""))))
14042 (clobber (reg:CCFP FPSR_REG))
14043 (clobber (reg:CCFP FLAGS_REG))]
14044 "TARGET_CMOVE && TARGET_80387
14045 && FLOAT_MODE_P (GET_MODE (operands[1]))
14046 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14047 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14050 (define_insn "*fp_jcc_3_387"
14052 (if_then_else (match_operator 0 "comparison_operator"
14053 [(match_operand 1 "register_operand" "f")
14054 (match_operand 2 "nonimmediate_operand" "fm")])
14055 (label_ref (match_operand 3 "" ""))
14057 (clobber (reg:CCFP FPSR_REG))
14058 (clobber (reg:CCFP FLAGS_REG))
14059 (clobber (match_scratch:HI 4 "=a"))]
14061 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14062 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14063 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14064 && SELECT_CC_MODE (GET_CODE (operands[0]),
14065 operands[1], operands[2]) == CCFPmode
14066 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14069 (define_insn "*fp_jcc_4_387"
14071 (if_then_else (match_operator 0 "comparison_operator"
14072 [(match_operand 1 "register_operand" "f")
14073 (match_operand 2 "nonimmediate_operand" "fm")])
14075 (label_ref (match_operand 3 "" ""))))
14076 (clobber (reg:CCFP FPSR_REG))
14077 (clobber (reg:CCFP FLAGS_REG))
14078 (clobber (match_scratch:HI 4 "=a"))]
14080 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14081 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14082 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14083 && SELECT_CC_MODE (GET_CODE (operands[0]),
14084 operands[1], operands[2]) == CCFPmode
14085 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14088 (define_insn "*fp_jcc_5_387"
14090 (if_then_else (match_operator 0 "comparison_operator"
14091 [(match_operand 1 "register_operand" "f")
14092 (match_operand 2 "register_operand" "f")])
14093 (label_ref (match_operand 3 "" ""))
14095 (clobber (reg:CCFP FPSR_REG))
14096 (clobber (reg:CCFP FLAGS_REG))
14097 (clobber (match_scratch:HI 4 "=a"))]
14099 && FLOAT_MODE_P (GET_MODE (operands[1]))
14100 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14101 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14104 (define_insn "*fp_jcc_6_387"
14106 (if_then_else (match_operator 0 "comparison_operator"
14107 [(match_operand 1 "register_operand" "f")
14108 (match_operand 2 "register_operand" "f")])
14110 (label_ref (match_operand 3 "" ""))))
14111 (clobber (reg:CCFP FPSR_REG))
14112 (clobber (reg:CCFP FLAGS_REG))
14113 (clobber (match_scratch:HI 4 "=a"))]
14115 && FLOAT_MODE_P (GET_MODE (operands[1]))
14116 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14117 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14120 (define_insn "*fp_jcc_7_387"
14122 (if_then_else (match_operator 0 "comparison_operator"
14123 [(match_operand 1 "register_operand" "f")
14124 (match_operand 2 "const0_operand" "X")])
14125 (label_ref (match_operand 3 "" ""))
14127 (clobber (reg:CCFP FPSR_REG))
14128 (clobber (reg:CCFP FLAGS_REG))
14129 (clobber (match_scratch:HI 4 "=a"))]
14131 && FLOAT_MODE_P (GET_MODE (operands[1]))
14132 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14133 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14134 && SELECT_CC_MODE (GET_CODE (operands[0]),
14135 operands[1], operands[2]) == CCFPmode
14136 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14139 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14140 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14141 ;; with a precedence over other operators and is always put in the first
14142 ;; place. Swap condition and operands to match ficom instruction.
14144 (define_insn "*fp_jcc_8<mode>_387"
14146 (if_then_else (match_operator 0 "comparison_operator"
14147 [(match_operator 1 "float_operator"
14148 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14149 (match_operand 3 "register_operand" "f,f")])
14150 (label_ref (match_operand 4 "" ""))
14152 (clobber (reg:CCFP FPSR_REG))
14153 (clobber (reg:CCFP FLAGS_REG))
14154 (clobber (match_scratch:HI 5 "=a,a"))]
14155 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14156 && FLOAT_MODE_P (GET_MODE (operands[3]))
14157 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14158 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14159 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14160 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14165 (if_then_else (match_operator 0 "comparison_operator"
14166 [(match_operand 1 "register_operand" "")
14167 (match_operand 2 "nonimmediate_operand" "")])
14168 (match_operand 3 "" "")
14169 (match_operand 4 "" "")))
14170 (clobber (reg:CCFP FPSR_REG))
14171 (clobber (reg:CCFP FLAGS_REG))]
14175 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14176 operands[3], operands[4], NULL_RTX, NULL_RTX);
14182 (if_then_else (match_operator 0 "comparison_operator"
14183 [(match_operand 1 "register_operand" "")
14184 (match_operand 2 "general_operand" "")])
14185 (match_operand 3 "" "")
14186 (match_operand 4 "" "")))
14187 (clobber (reg:CCFP FPSR_REG))
14188 (clobber (reg:CCFP FLAGS_REG))
14189 (clobber (match_scratch:HI 5 "=a"))]
14193 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14194 operands[3], operands[4], operands[5], NULL_RTX);
14200 (if_then_else (match_operator 0 "comparison_operator"
14201 [(match_operator 1 "float_operator"
14202 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14203 (match_operand 3 "register_operand" "")])
14204 (match_operand 4 "" "")
14205 (match_operand 5 "" "")))
14206 (clobber (reg:CCFP FPSR_REG))
14207 (clobber (reg:CCFP FLAGS_REG))
14208 (clobber (match_scratch:HI 6 "=a"))]
14212 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14213 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14214 operands[3], operands[7],
14215 operands[4], operands[5], operands[6], NULL_RTX);
14219 ;; %%% Kill this when reload knows how to do it.
14222 (if_then_else (match_operator 0 "comparison_operator"
14223 [(match_operator 1 "float_operator"
14224 [(match_operand:X87MODEI12 2 "register_operand" "")])
14225 (match_operand 3 "register_operand" "")])
14226 (match_operand 4 "" "")
14227 (match_operand 5 "" "")))
14228 (clobber (reg:CCFP FPSR_REG))
14229 (clobber (reg:CCFP FLAGS_REG))
14230 (clobber (match_scratch:HI 6 "=a"))]
14234 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14235 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14236 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14237 operands[3], operands[7],
14238 operands[4], operands[5], operands[6], operands[2]);
14242 ;; Unconditional and other jump instructions
14244 (define_insn "jump"
14246 (label_ref (match_operand 0 "" "")))]
14249 [(set_attr "type" "ibr")
14250 (set (attr "length")
14251 (if_then_else (and (ge (minus (match_dup 0) (pc))
14253 (lt (minus (match_dup 0) (pc))
14257 (set_attr "modrm" "0")])
14259 (define_expand "indirect_jump"
14260 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14264 (define_insn "*indirect_jump"
14265 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14268 [(set_attr "type" "ibr")
14269 (set_attr "length_immediate" "0")])
14271 (define_insn "*indirect_jump_rtx64"
14272 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14275 [(set_attr "type" "ibr")
14276 (set_attr "length_immediate" "0")])
14278 (define_expand "tablejump"
14279 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14280 (use (label_ref (match_operand 1 "" "")))])]
14283 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14284 relative. Convert the relative address to an absolute address. */
14288 enum rtx_code code;
14294 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14296 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14300 op1 = pic_offset_table_rtx;
14305 op0 = pic_offset_table_rtx;
14309 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14314 (define_insn "*tablejump_1"
14315 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14316 (use (label_ref (match_operand 1 "" "")))]
14319 [(set_attr "type" "ibr")
14320 (set_attr "length_immediate" "0")])
14322 (define_insn "*tablejump_1_rtx64"
14323 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14324 (use (label_ref (match_operand 1 "" "")))]
14327 [(set_attr "type" "ibr")
14328 (set_attr "length_immediate" "0")])
14330 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14333 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14334 (set (match_operand:QI 1 "register_operand" "")
14335 (match_operator:QI 2 "ix86_comparison_operator"
14336 [(reg FLAGS_REG) (const_int 0)]))
14337 (set (match_operand 3 "q_regs_operand" "")
14338 (zero_extend (match_dup 1)))]
14339 "(peep2_reg_dead_p (3, operands[1])
14340 || operands_match_p (operands[1], operands[3]))
14341 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14342 [(set (match_dup 4) (match_dup 0))
14343 (set (strict_low_part (match_dup 5))
14346 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14347 operands[5] = gen_lowpart (QImode, operands[3]);
14348 ix86_expand_clear (operands[3]);
14351 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14354 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14355 (set (match_operand:QI 1 "register_operand" "")
14356 (match_operator:QI 2 "ix86_comparison_operator"
14357 [(reg FLAGS_REG) (const_int 0)]))
14358 (parallel [(set (match_operand 3 "q_regs_operand" "")
14359 (zero_extend (match_dup 1)))
14360 (clobber (reg:CC FLAGS_REG))])]
14361 "(peep2_reg_dead_p (3, operands[1])
14362 || operands_match_p (operands[1], operands[3]))
14363 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14364 [(set (match_dup 4) (match_dup 0))
14365 (set (strict_low_part (match_dup 5))
14368 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14369 operands[5] = gen_lowpart (QImode, operands[3]);
14370 ix86_expand_clear (operands[3]);
14373 ;; Call instructions.
14375 ;; The predicates normally associated with named expanders are not properly
14376 ;; checked for calls. This is a bug in the generic code, but it isn't that
14377 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14379 ;; Call subroutine returning no value.
14381 (define_expand "call_pop"
14382 [(parallel [(call (match_operand:QI 0 "" "")
14383 (match_operand:SI 1 "" ""))
14384 (set (reg:SI SP_REG)
14385 (plus:SI (reg:SI SP_REG)
14386 (match_operand:SI 3 "" "")))])]
14389 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14393 (define_insn "*call_pop_0"
14394 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14395 (match_operand:SI 1 "" ""))
14396 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14397 (match_operand:SI 2 "immediate_operand" "")))]
14400 if (SIBLING_CALL_P (insn))
14403 return "call\t%P0";
14405 [(set_attr "type" "call")])
14407 (define_insn "*call_pop_1"
14408 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14409 (match_operand:SI 1 "" ""))
14410 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14411 (match_operand:SI 2 "immediate_operand" "i")))]
14414 if (constant_call_address_operand (operands[0], Pmode))
14416 if (SIBLING_CALL_P (insn))
14419 return "call\t%P0";
14421 if (SIBLING_CALL_P (insn))
14424 return "call\t%A0";
14426 [(set_attr "type" "call")])
14428 (define_expand "call"
14429 [(call (match_operand:QI 0 "" "")
14430 (match_operand 1 "" ""))
14431 (use (match_operand 2 "" ""))]
14434 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14438 (define_expand "sibcall"
14439 [(call (match_operand:QI 0 "" "")
14440 (match_operand 1 "" ""))
14441 (use (match_operand 2 "" ""))]
14444 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14448 (define_insn "*call_0"
14449 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14450 (match_operand 1 "" ""))]
14453 if (SIBLING_CALL_P (insn))
14456 return "call\t%P0";
14458 [(set_attr "type" "call")])
14460 (define_insn "*call_1"
14461 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14462 (match_operand 1 "" ""))]
14463 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14465 if (constant_call_address_operand (operands[0], Pmode))
14466 return "call\t%P0";
14467 return "call\t%A0";
14469 [(set_attr "type" "call")])
14471 (define_insn "*sibcall_1"
14472 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14473 (match_operand 1 "" ""))]
14474 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14476 if (constant_call_address_operand (operands[0], Pmode))
14480 [(set_attr "type" "call")])
14482 (define_insn "*call_1_rex64"
14483 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14484 (match_operand 1 "" ""))]
14485 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14487 if (constant_call_address_operand (operands[0], Pmode))
14488 return "call\t%P0";
14489 return "call\t%A0";
14491 [(set_attr "type" "call")])
14493 (define_insn "*sibcall_1_rex64"
14494 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14495 (match_operand 1 "" ""))]
14496 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14498 [(set_attr "type" "call")])
14500 (define_insn "*sibcall_1_rex64_v"
14501 [(call (mem:QI (reg:DI R11_REG))
14502 (match_operand 0 "" ""))]
14503 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14505 [(set_attr "type" "call")])
14508 ;; Call subroutine, returning value in operand 0
14510 (define_expand "call_value_pop"
14511 [(parallel [(set (match_operand 0 "" "")
14512 (call (match_operand:QI 1 "" "")
14513 (match_operand:SI 2 "" "")))
14514 (set (reg:SI SP_REG)
14515 (plus:SI (reg:SI SP_REG)
14516 (match_operand:SI 4 "" "")))])]
14519 ix86_expand_call (operands[0], operands[1], operands[2],
14520 operands[3], operands[4], 0);
14524 (define_expand "call_value"
14525 [(set (match_operand 0 "" "")
14526 (call (match_operand:QI 1 "" "")
14527 (match_operand:SI 2 "" "")))
14528 (use (match_operand:SI 3 "" ""))]
14529 ;; Operand 2 not used on the i386.
14532 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14536 (define_expand "sibcall_value"
14537 [(set (match_operand 0 "" "")
14538 (call (match_operand:QI 1 "" "")
14539 (match_operand:SI 2 "" "")))
14540 (use (match_operand:SI 3 "" ""))]
14541 ;; Operand 2 not used on the i386.
14544 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14548 ;; Call subroutine returning any type.
14550 (define_expand "untyped_call"
14551 [(parallel [(call (match_operand 0 "" "")
14553 (match_operand 1 "" "")
14554 (match_operand 2 "" "")])]
14559 /* In order to give reg-stack an easier job in validating two
14560 coprocessor registers as containing a possible return value,
14561 simply pretend the untyped call returns a complex long double
14564 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14565 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14566 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14569 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14571 rtx set = XVECEXP (operands[2], 0, i);
14572 emit_move_insn (SET_DEST (set), SET_SRC (set));
14575 /* The optimizer does not know that the call sets the function value
14576 registers we stored in the result block. We avoid problems by
14577 claiming that all hard registers are used and clobbered at this
14579 emit_insn (gen_blockage (const0_rtx));
14584 ;; Prologue and epilogue instructions
14586 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14587 ;; all of memory. This blocks insns from being moved across this point.
14589 (define_insn "blockage"
14590 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14593 [(set_attr "length" "0")])
14595 ;; Insn emitted into the body of a function to return from a function.
14596 ;; This is only done if the function's epilogue is known to be simple.
14597 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14599 (define_expand "return"
14601 "ix86_can_use_return_insn_p ()"
14603 if (current_function_pops_args)
14605 rtx popc = GEN_INT (current_function_pops_args);
14606 emit_jump_insn (gen_return_pop_internal (popc));
14611 (define_insn "return_internal"
14615 [(set_attr "length" "1")
14616 (set_attr "length_immediate" "0")
14617 (set_attr "modrm" "0")])
14619 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14620 ;; instruction Athlon and K8 have.
14622 (define_insn "return_internal_long"
14624 (unspec [(const_int 0)] UNSPEC_REP)]
14627 [(set_attr "length" "1")
14628 (set_attr "length_immediate" "0")
14629 (set_attr "prefix_rep" "1")
14630 (set_attr "modrm" "0")])
14632 (define_insn "return_pop_internal"
14634 (use (match_operand:SI 0 "const_int_operand" ""))]
14637 [(set_attr "length" "3")
14638 (set_attr "length_immediate" "2")
14639 (set_attr "modrm" "0")])
14641 (define_insn "return_indirect_internal"
14643 (use (match_operand:SI 0 "register_operand" "r"))]
14646 [(set_attr "type" "ibr")
14647 (set_attr "length_immediate" "0")])
14653 [(set_attr "length" "1")
14654 (set_attr "length_immediate" "0")
14655 (set_attr "modrm" "0")])
14657 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14658 ;; branch prediction penalty for the third jump in a 16-byte
14661 (define_insn "align"
14662 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14665 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14666 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14668 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14669 The align insn is used to avoid 3 jump instructions in the row to improve
14670 branch prediction and the benefits hardly outweigh the cost of extra 8
14671 nops on the average inserted by full alignment pseudo operation. */
14675 [(set_attr "length" "16")])
14677 (define_expand "prologue"
14680 "ix86_expand_prologue (); DONE;")
14682 (define_insn "set_got"
14683 [(set (match_operand:SI 0 "register_operand" "=r")
14684 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14685 (clobber (reg:CC FLAGS_REG))]
14687 { return output_set_got (operands[0], NULL_RTX); }
14688 [(set_attr "type" "multi")
14689 (set_attr "length" "12")])
14691 (define_insn "set_got_labelled"
14692 [(set (match_operand:SI 0 "register_operand" "=r")
14693 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14695 (clobber (reg:CC FLAGS_REG))]
14697 { return output_set_got (operands[0], operands[1]); }
14698 [(set_attr "type" "multi")
14699 (set_attr "length" "12")])
14701 (define_insn "set_got_rex64"
14702 [(set (match_operand:DI 0 "register_operand" "=r")
14703 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14705 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14706 [(set_attr "type" "lea")
14707 (set_attr "length" "6")])
14709 (define_expand "epilogue"
14712 "ix86_expand_epilogue (1); DONE;")
14714 (define_expand "sibcall_epilogue"
14717 "ix86_expand_epilogue (0); DONE;")
14719 (define_expand "eh_return"
14720 [(use (match_operand 0 "register_operand" ""))]
14723 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14725 /* Tricky bit: we write the address of the handler to which we will
14726 be returning into someone else's stack frame, one word below the
14727 stack address we wish to restore. */
14728 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14729 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14730 tmp = gen_rtx_MEM (Pmode, tmp);
14731 emit_move_insn (tmp, ra);
14733 if (Pmode == SImode)
14734 emit_jump_insn (gen_eh_return_si (sa));
14736 emit_jump_insn (gen_eh_return_di (sa));
14741 (define_insn_and_split "eh_return_si"
14743 (unspec [(match_operand:SI 0 "register_operand" "c")]
14744 UNSPEC_EH_RETURN))]
14749 "ix86_expand_epilogue (2); DONE;")
14751 (define_insn_and_split "eh_return_di"
14753 (unspec [(match_operand:DI 0 "register_operand" "c")]
14754 UNSPEC_EH_RETURN))]
14759 "ix86_expand_epilogue (2); DONE;")
14761 (define_insn "leave"
14762 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14763 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14764 (clobber (mem:BLK (scratch)))]
14767 [(set_attr "type" "leave")])
14769 (define_insn "leave_rex64"
14770 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14771 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14772 (clobber (mem:BLK (scratch)))]
14775 [(set_attr "type" "leave")])
14777 (define_expand "ffssi2"
14779 [(set (match_operand:SI 0 "register_operand" "")
14780 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14781 (clobber (match_scratch:SI 2 ""))
14782 (clobber (reg:CC FLAGS_REG))])]
14786 (define_insn_and_split "*ffs_cmove"
14787 [(set (match_operand:SI 0 "register_operand" "=r")
14788 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14789 (clobber (match_scratch:SI 2 "=&r"))
14790 (clobber (reg:CC FLAGS_REG))]
14793 "&& reload_completed"
14794 [(set (match_dup 2) (const_int -1))
14795 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14796 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14797 (set (match_dup 0) (if_then_else:SI
14798 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14801 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14802 (clobber (reg:CC FLAGS_REG))])]
14805 (define_insn_and_split "*ffs_no_cmove"
14806 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14807 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14808 (clobber (match_scratch:SI 2 "=&q"))
14809 (clobber (reg:CC FLAGS_REG))]
14813 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14814 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14815 (set (strict_low_part (match_dup 3))
14816 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14817 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14818 (clobber (reg:CC FLAGS_REG))])
14819 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14820 (clobber (reg:CC FLAGS_REG))])
14821 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14822 (clobber (reg:CC FLAGS_REG))])]
14824 operands[3] = gen_lowpart (QImode, operands[2]);
14825 ix86_expand_clear (operands[2]);
14828 (define_insn "*ffssi_1"
14829 [(set (reg:CCZ FLAGS_REG)
14830 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14832 (set (match_operand:SI 0 "register_operand" "=r")
14833 (ctz:SI (match_dup 1)))]
14835 "bsf{l}\t{%1, %0|%0, %1}"
14836 [(set_attr "prefix_0f" "1")])
14838 (define_expand "ffsdi2"
14840 [(set (match_operand:DI 0 "register_operand" "")
14841 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14842 (clobber (match_scratch:DI 2 ""))
14843 (clobber (reg:CC FLAGS_REG))])]
14844 "TARGET_64BIT && TARGET_CMOVE"
14847 (define_insn_and_split "*ffs_rex64"
14848 [(set (match_operand:DI 0 "register_operand" "=r")
14849 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14850 (clobber (match_scratch:DI 2 "=&r"))
14851 (clobber (reg:CC FLAGS_REG))]
14852 "TARGET_64BIT && TARGET_CMOVE"
14854 "&& reload_completed"
14855 [(set (match_dup 2) (const_int -1))
14856 (parallel [(set (reg:CCZ FLAGS_REG)
14857 (compare:CCZ (match_dup 1) (const_int 0)))
14858 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14859 (set (match_dup 0) (if_then_else:DI
14860 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14863 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14864 (clobber (reg:CC FLAGS_REG))])]
14867 (define_insn "*ffsdi_1"
14868 [(set (reg:CCZ FLAGS_REG)
14869 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14871 (set (match_operand:DI 0 "register_operand" "=r")
14872 (ctz:DI (match_dup 1)))]
14874 "bsf{q}\t{%1, %0|%0, %1}"
14875 [(set_attr "prefix_0f" "1")])
14877 (define_insn "ctzsi2"
14878 [(set (match_operand:SI 0 "register_operand" "=r")
14879 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14880 (clobber (reg:CC FLAGS_REG))]
14882 "bsf{l}\t{%1, %0|%0, %1}"
14883 [(set_attr "prefix_0f" "1")])
14885 (define_insn "ctzdi2"
14886 [(set (match_operand:DI 0 "register_operand" "=r")
14887 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14888 (clobber (reg:CC FLAGS_REG))]
14890 "bsf{q}\t{%1, %0|%0, %1}"
14891 [(set_attr "prefix_0f" "1")])
14893 (define_expand "clzsi2"
14895 [(set (match_operand:SI 0 "register_operand" "")
14896 (minus:SI (const_int 31)
14897 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14898 (clobber (reg:CC FLAGS_REG))])
14900 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14901 (clobber (reg:CC FLAGS_REG))])]
14906 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14911 (define_insn "clzsi2_abm"
14912 [(set (match_operand:SI 0 "register_operand" "=r")
14913 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14914 (clobber (reg:CC FLAGS_REG))]
14916 "lzcnt{l}\t{%1, %0|%0, %1}"
14917 [(set_attr "prefix_rep" "1")
14918 (set_attr "type" "bitmanip")
14919 (set_attr "mode" "SI")])
14921 (define_insn "*bsr"
14922 [(set (match_operand:SI 0 "register_operand" "=r")
14923 (minus:SI (const_int 31)
14924 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14925 (clobber (reg:CC FLAGS_REG))]
14927 "bsr{l}\t{%1, %0|%0, %1}"
14928 [(set_attr "prefix_0f" "1")
14929 (set_attr "mode" "SI")])
14931 (define_insn "popcountsi2"
14932 [(set (match_operand:SI 0 "register_operand" "=r")
14933 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14934 (clobber (reg:CC FLAGS_REG))]
14936 "popcnt{l}\t{%1, %0|%0, %1}"
14937 [(set_attr "prefix_rep" "1")
14938 (set_attr "type" "bitmanip")
14939 (set_attr "mode" "SI")])
14941 (define_insn "*popcountsi2_cmp"
14942 [(set (reg FLAGS_REG)
14944 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14946 (set (match_operand:SI 0 "register_operand" "=r")
14947 (popcount:SI (match_dup 1)))]
14948 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14949 "popcnt{l}\t{%1, %0|%0, %1}"
14950 [(set_attr "prefix_rep" "1")
14951 (set_attr "type" "bitmanip")
14952 (set_attr "mode" "SI")])
14954 (define_insn "*popcountsi2_cmp_zext"
14955 [(set (reg FLAGS_REG)
14957 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14959 (set (match_operand:DI 0 "register_operand" "=r")
14960 (zero_extend:DI(popcount:SI (match_dup 1))))]
14961 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14962 "popcnt{l}\t{%1, %0|%0, %1}"
14963 [(set_attr "prefix_rep" "1")
14964 (set_attr "type" "bitmanip")
14965 (set_attr "mode" "SI")])
14967 (define_insn "bswapsi2"
14968 [(set (match_operand:SI 0 "register_operand" "=r")
14969 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14970 (clobber (reg:CC FLAGS_REG))]
14973 [(set_attr "prefix_0f" "1")
14974 (set_attr "length" "2")])
14976 (define_insn "*bswapdi2_rex"
14977 [(set (match_operand:DI 0 "register_operand" "=r")
14978 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14979 (clobber (reg:CC FLAGS_REG))]
14980 "TARGET_64BIT && TARGET_BSWAP"
14982 [(set_attr "prefix_0f" "1")
14983 (set_attr "length" "3")])
14985 (define_expand "bswapdi2"
14986 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14987 (bswap:DI (match_operand:DI 1 "register_operand" "")))
14988 (clobber (reg:CC FLAGS_REG))])]
14994 tmp1 = gen_reg_rtx (SImode);
14995 tmp2 = gen_reg_rtx (SImode);
14996 emit_insn (gen_bswapsi2 (tmp1, gen_lowpart (SImode, operands[1])));
14997 emit_insn (gen_bswapsi2 (tmp2, gen_highpart (SImode, operands[1])));
14998 emit_move_insn (gen_lowpart (SImode, operands[0]), tmp2);
14999 emit_move_insn (gen_highpart (SImode, operands[0]), tmp1);
15004 (define_expand "clzdi2"
15006 [(set (match_operand:DI 0 "register_operand" "")
15007 (minus:DI (const_int 63)
15008 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15009 (clobber (reg:CC FLAGS_REG))])
15011 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15012 (clobber (reg:CC FLAGS_REG))])]
15017 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15022 (define_insn "clzdi2_abm"
15023 [(set (match_operand:DI 0 "register_operand" "=r")
15024 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15025 (clobber (reg:CC FLAGS_REG))]
15026 "TARGET_64BIT && TARGET_ABM"
15027 "lzcnt{q}\t{%1, %0|%0, %1}"
15028 [(set_attr "prefix_rep" "1")
15029 (set_attr "type" "bitmanip")
15030 (set_attr "mode" "DI")])
15032 (define_insn "*bsr_rex64"
15033 [(set (match_operand:DI 0 "register_operand" "=r")
15034 (minus:DI (const_int 63)
15035 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15036 (clobber (reg:CC FLAGS_REG))]
15038 "bsr{q}\t{%1, %0|%0, %1}"
15039 [(set_attr "prefix_0f" "1")
15040 (set_attr "mode" "DI")])
15042 (define_insn "popcountdi2"
15043 [(set (match_operand:DI 0 "register_operand" "=r")
15044 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15045 (clobber (reg:CC FLAGS_REG))]
15046 "TARGET_64BIT && TARGET_POPCNT"
15047 "popcnt{q}\t{%1, %0|%0, %1}"
15048 [(set_attr "prefix_rep" "1")
15049 (set_attr "type" "bitmanip")
15050 (set_attr "mode" "DI")])
15052 (define_insn "*popcountdi2_cmp"
15053 [(set (reg FLAGS_REG)
15055 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15057 (set (match_operand:DI 0 "register_operand" "=r")
15058 (popcount:DI (match_dup 1)))]
15059 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15060 "popcnt{q}\t{%1, %0|%0, %1}"
15061 [(set_attr "prefix_rep" "1")
15062 (set_attr "type" "bitmanip")
15063 (set_attr "mode" "DI")])
15065 (define_expand "clzhi2"
15067 [(set (match_operand:HI 0 "register_operand" "")
15068 (minus:HI (const_int 15)
15069 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15070 (clobber (reg:CC FLAGS_REG))])
15072 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15073 (clobber (reg:CC FLAGS_REG))])]
15078 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15083 (define_insn "clzhi2_abm"
15084 [(set (match_operand:HI 0 "register_operand" "=r")
15085 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15086 (clobber (reg:CC FLAGS_REG))]
15088 "lzcnt{w}\t{%1, %0|%0, %1}"
15089 [(set_attr "prefix_rep" "1")
15090 (set_attr "type" "bitmanip")
15091 (set_attr "mode" "HI")])
15093 (define_insn "*bsrhi"
15094 [(set (match_operand:HI 0 "register_operand" "=r")
15095 (minus:HI (const_int 15)
15096 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15097 (clobber (reg:CC FLAGS_REG))]
15099 "bsr{w}\t{%1, %0|%0, %1}"
15100 [(set_attr "prefix_0f" "1")
15101 (set_attr "mode" "HI")])
15103 (define_insn "popcounthi2"
15104 [(set (match_operand:HI 0 "register_operand" "=r")
15105 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15106 (clobber (reg:CC FLAGS_REG))]
15108 "popcnt{w}\t{%1, %0|%0, %1}"
15109 [(set_attr "prefix_rep" "1")
15110 (set_attr "type" "bitmanip")
15111 (set_attr "mode" "HI")])
15113 (define_insn "*popcounthi2_cmp"
15114 [(set (reg FLAGS_REG)
15116 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15118 (set (match_operand:HI 0 "register_operand" "=r")
15119 (popcount:HI (match_dup 1)))]
15120 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15121 "popcnt{w}\t{%1, %0|%0, %1}"
15122 [(set_attr "prefix_rep" "1")
15123 (set_attr "type" "bitmanip")
15124 (set_attr "mode" "HI")])
15126 ;; Thread-local storage patterns for ELF.
15128 ;; Note that these code sequences must appear exactly as shown
15129 ;; in order to allow linker relaxation.
15131 (define_insn "*tls_global_dynamic_32_gnu"
15132 [(set (match_operand:SI 0 "register_operand" "=a")
15133 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15134 (match_operand:SI 2 "tls_symbolic_operand" "")
15135 (match_operand:SI 3 "call_insn_operand" "")]
15137 (clobber (match_scratch:SI 4 "=d"))
15138 (clobber (match_scratch:SI 5 "=c"))
15139 (clobber (reg:CC FLAGS_REG))]
15140 "!TARGET_64BIT && TARGET_GNU_TLS"
15141 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15142 [(set_attr "type" "multi")
15143 (set_attr "length" "12")])
15145 (define_insn "*tls_global_dynamic_32_sun"
15146 [(set (match_operand:SI 0 "register_operand" "=a")
15147 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15148 (match_operand:SI 2 "tls_symbolic_operand" "")
15149 (match_operand:SI 3 "call_insn_operand" "")]
15151 (clobber (match_scratch:SI 4 "=d"))
15152 (clobber (match_scratch:SI 5 "=c"))
15153 (clobber (reg:CC FLAGS_REG))]
15154 "!TARGET_64BIT && TARGET_SUN_TLS"
15155 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15156 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15157 [(set_attr "type" "multi")
15158 (set_attr "length" "14")])
15160 (define_expand "tls_global_dynamic_32"
15161 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15164 (match_operand:SI 1 "tls_symbolic_operand" "")
15167 (clobber (match_scratch:SI 4 ""))
15168 (clobber (match_scratch:SI 5 ""))
15169 (clobber (reg:CC FLAGS_REG))])]
15173 operands[2] = pic_offset_table_rtx;
15176 operands[2] = gen_reg_rtx (Pmode);
15177 emit_insn (gen_set_got (operands[2]));
15179 if (TARGET_GNU2_TLS)
15181 emit_insn (gen_tls_dynamic_gnu2_32
15182 (operands[0], operands[1], operands[2]));
15185 operands[3] = ix86_tls_get_addr ();
15188 (define_insn "*tls_global_dynamic_64"
15189 [(set (match_operand:DI 0 "register_operand" "=a")
15190 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15191 (match_operand:DI 3 "" "")))
15192 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15195 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15196 [(set_attr "type" "multi")
15197 (set_attr "length" "16")])
15199 (define_expand "tls_global_dynamic_64"
15200 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15201 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15202 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15206 if (TARGET_GNU2_TLS)
15208 emit_insn (gen_tls_dynamic_gnu2_64
15209 (operands[0], operands[1]));
15212 operands[2] = ix86_tls_get_addr ();
15215 (define_insn "*tls_local_dynamic_base_32_gnu"
15216 [(set (match_operand:SI 0 "register_operand" "=a")
15217 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15218 (match_operand:SI 2 "call_insn_operand" "")]
15219 UNSPEC_TLS_LD_BASE))
15220 (clobber (match_scratch:SI 3 "=d"))
15221 (clobber (match_scratch:SI 4 "=c"))
15222 (clobber (reg:CC FLAGS_REG))]
15223 "!TARGET_64BIT && TARGET_GNU_TLS"
15224 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15225 [(set_attr "type" "multi")
15226 (set_attr "length" "11")])
15228 (define_insn "*tls_local_dynamic_base_32_sun"
15229 [(set (match_operand:SI 0 "register_operand" "=a")
15230 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15231 (match_operand:SI 2 "call_insn_operand" "")]
15232 UNSPEC_TLS_LD_BASE))
15233 (clobber (match_scratch:SI 3 "=d"))
15234 (clobber (match_scratch:SI 4 "=c"))
15235 (clobber (reg:CC FLAGS_REG))]
15236 "!TARGET_64BIT && TARGET_SUN_TLS"
15237 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15238 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15239 [(set_attr "type" "multi")
15240 (set_attr "length" "13")])
15242 (define_expand "tls_local_dynamic_base_32"
15243 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15244 (unspec:SI [(match_dup 1) (match_dup 2)]
15245 UNSPEC_TLS_LD_BASE))
15246 (clobber (match_scratch:SI 3 ""))
15247 (clobber (match_scratch:SI 4 ""))
15248 (clobber (reg:CC FLAGS_REG))])]
15252 operands[1] = pic_offset_table_rtx;
15255 operands[1] = gen_reg_rtx (Pmode);
15256 emit_insn (gen_set_got (operands[1]));
15258 if (TARGET_GNU2_TLS)
15260 emit_insn (gen_tls_dynamic_gnu2_32
15261 (operands[0], ix86_tls_module_base (), operands[1]));
15264 operands[2] = ix86_tls_get_addr ();
15267 (define_insn "*tls_local_dynamic_base_64"
15268 [(set (match_operand:DI 0 "register_operand" "=a")
15269 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15270 (match_operand:DI 2 "" "")))
15271 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15273 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15274 [(set_attr "type" "multi")
15275 (set_attr "length" "12")])
15277 (define_expand "tls_local_dynamic_base_64"
15278 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15279 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15280 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15283 if (TARGET_GNU2_TLS)
15285 emit_insn (gen_tls_dynamic_gnu2_64
15286 (operands[0], ix86_tls_module_base ()));
15289 operands[1] = ix86_tls_get_addr ();
15292 ;; Local dynamic of a single variable is a lose. Show combine how
15293 ;; to convert that back to global dynamic.
15295 (define_insn_and_split "*tls_local_dynamic_32_once"
15296 [(set (match_operand:SI 0 "register_operand" "=a")
15297 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15298 (match_operand:SI 2 "call_insn_operand" "")]
15299 UNSPEC_TLS_LD_BASE)
15300 (const:SI (unspec:SI
15301 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15303 (clobber (match_scratch:SI 4 "=d"))
15304 (clobber (match_scratch:SI 5 "=c"))
15305 (clobber (reg:CC FLAGS_REG))]
15309 [(parallel [(set (match_dup 0)
15310 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15312 (clobber (match_dup 4))
15313 (clobber (match_dup 5))
15314 (clobber (reg:CC FLAGS_REG))])]
15317 ;; Load and add the thread base pointer from %gs:0.
15319 (define_insn "*load_tp_si"
15320 [(set (match_operand:SI 0 "register_operand" "=r")
15321 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15323 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15324 [(set_attr "type" "imov")
15325 (set_attr "modrm" "0")
15326 (set_attr "length" "7")
15327 (set_attr "memory" "load")
15328 (set_attr "imm_disp" "false")])
15330 (define_insn "*add_tp_si"
15331 [(set (match_operand:SI 0 "register_operand" "=r")
15332 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15333 (match_operand:SI 1 "register_operand" "0")))
15334 (clobber (reg:CC FLAGS_REG))]
15336 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15337 [(set_attr "type" "alu")
15338 (set_attr "modrm" "0")
15339 (set_attr "length" "7")
15340 (set_attr "memory" "load")
15341 (set_attr "imm_disp" "false")])
15343 (define_insn "*load_tp_di"
15344 [(set (match_operand:DI 0 "register_operand" "=r")
15345 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15347 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15348 [(set_attr "type" "imov")
15349 (set_attr "modrm" "0")
15350 (set_attr "length" "7")
15351 (set_attr "memory" "load")
15352 (set_attr "imm_disp" "false")])
15354 (define_insn "*add_tp_di"
15355 [(set (match_operand:DI 0 "register_operand" "=r")
15356 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15357 (match_operand:DI 1 "register_operand" "0")))
15358 (clobber (reg:CC FLAGS_REG))]
15360 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15361 [(set_attr "type" "alu")
15362 (set_attr "modrm" "0")
15363 (set_attr "length" "7")
15364 (set_attr "memory" "load")
15365 (set_attr "imm_disp" "false")])
15367 ;; GNU2 TLS patterns can be split.
15369 (define_expand "tls_dynamic_gnu2_32"
15370 [(set (match_dup 3)
15371 (plus:SI (match_operand:SI 2 "register_operand" "")
15373 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15376 [(set (match_operand:SI 0 "register_operand" "")
15377 (unspec:SI [(match_dup 1) (match_dup 3)
15378 (match_dup 2) (reg:SI SP_REG)]
15380 (clobber (reg:CC FLAGS_REG))])]
15381 "!TARGET_64BIT && TARGET_GNU2_TLS"
15383 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15384 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15387 (define_insn "*tls_dynamic_lea_32"
15388 [(set (match_operand:SI 0 "register_operand" "=r")
15389 (plus:SI (match_operand:SI 1 "register_operand" "b")
15391 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15392 UNSPEC_TLSDESC))))]
15393 "!TARGET_64BIT && TARGET_GNU2_TLS"
15394 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15395 [(set_attr "type" "lea")
15396 (set_attr "mode" "SI")
15397 (set_attr "length" "6")
15398 (set_attr "length_address" "4")])
15400 (define_insn "*tls_dynamic_call_32"
15401 [(set (match_operand:SI 0 "register_operand" "=a")
15402 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15403 (match_operand:SI 2 "register_operand" "0")
15404 ;; we have to make sure %ebx still points to the GOT
15405 (match_operand:SI 3 "register_operand" "b")
15408 (clobber (reg:CC FLAGS_REG))]
15409 "!TARGET_64BIT && TARGET_GNU2_TLS"
15410 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15411 [(set_attr "type" "call")
15412 (set_attr "length" "2")
15413 (set_attr "length_address" "0")])
15415 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15416 [(set (match_operand:SI 0 "register_operand" "=&a")
15418 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15419 (match_operand:SI 4 "" "")
15420 (match_operand:SI 2 "register_operand" "b")
15423 (const:SI (unspec:SI
15424 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15426 (clobber (reg:CC FLAGS_REG))]
15427 "!TARGET_64BIT && TARGET_GNU2_TLS"
15430 [(set (match_dup 0) (match_dup 5))]
15432 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15433 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15436 (define_expand "tls_dynamic_gnu2_64"
15437 [(set (match_dup 2)
15438 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15441 [(set (match_operand:DI 0 "register_operand" "")
15442 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15444 (clobber (reg:CC FLAGS_REG))])]
15445 "TARGET_64BIT && TARGET_GNU2_TLS"
15447 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15448 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15451 (define_insn "*tls_dynamic_lea_64"
15452 [(set (match_operand:DI 0 "register_operand" "=r")
15453 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15455 "TARGET_64BIT && TARGET_GNU2_TLS"
15456 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15457 [(set_attr "type" "lea")
15458 (set_attr "mode" "DI")
15459 (set_attr "length" "7")
15460 (set_attr "length_address" "4")])
15462 (define_insn "*tls_dynamic_call_64"
15463 [(set (match_operand:DI 0 "register_operand" "=a")
15464 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15465 (match_operand:DI 2 "register_operand" "0")
15468 (clobber (reg:CC FLAGS_REG))]
15469 "TARGET_64BIT && TARGET_GNU2_TLS"
15470 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15471 [(set_attr "type" "call")
15472 (set_attr "length" "2")
15473 (set_attr "length_address" "0")])
15475 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15476 [(set (match_operand:DI 0 "register_operand" "=&a")
15478 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15479 (match_operand:DI 3 "" "")
15482 (const:DI (unspec:DI
15483 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15485 (clobber (reg:CC FLAGS_REG))]
15486 "TARGET_64BIT && TARGET_GNU2_TLS"
15489 [(set (match_dup 0) (match_dup 4))]
15491 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15492 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15497 ;; These patterns match the binary 387 instructions for addM3, subM3,
15498 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15499 ;; SFmode. The first is the normal insn, the second the same insn but
15500 ;; with one operand a conversion, and the third the same insn but with
15501 ;; the other operand a conversion. The conversion may be SFmode or
15502 ;; SImode if the target mode DFmode, but only SImode if the target mode
15505 ;; Gcc is slightly more smart about handling normal two address instructions
15506 ;; so use special patterns for add and mull.
15508 (define_insn "*fop_sf_comm_mixed"
15509 [(set (match_operand:SF 0 "register_operand" "=f,x")
15510 (match_operator:SF 3 "binary_fp_operator"
15511 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15512 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15513 "TARGET_MIX_SSE_I387
15514 && COMMUTATIVE_ARITH_P (operands[3])
15515 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15516 "* return output_387_binary_op (insn, operands);"
15517 [(set (attr "type")
15518 (if_then_else (eq_attr "alternative" "1")
15519 (if_then_else (match_operand:SF 3 "mult_operator" "")
15520 (const_string "ssemul")
15521 (const_string "sseadd"))
15522 (if_then_else (match_operand:SF 3 "mult_operator" "")
15523 (const_string "fmul")
15524 (const_string "fop"))))
15525 (set_attr "mode" "SF")])
15527 (define_insn "*fop_sf_comm_sse"
15528 [(set (match_operand:SF 0 "register_operand" "=x")
15529 (match_operator:SF 3 "binary_fp_operator"
15530 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15531 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15533 && COMMUTATIVE_ARITH_P (operands[3])
15534 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15535 "* return output_387_binary_op (insn, operands);"
15536 [(set (attr "type")
15537 (if_then_else (match_operand:SF 3 "mult_operator" "")
15538 (const_string "ssemul")
15539 (const_string "sseadd")))
15540 (set_attr "mode" "SF")])
15542 (define_insn "*fop_sf_comm_i387"
15543 [(set (match_operand:SF 0 "register_operand" "=f")
15544 (match_operator:SF 3 "binary_fp_operator"
15545 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15546 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15548 && COMMUTATIVE_ARITH_P (operands[3])
15549 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15550 "* return output_387_binary_op (insn, operands);"
15551 [(set (attr "type")
15552 (if_then_else (match_operand:SF 3 "mult_operator" "")
15553 (const_string "fmul")
15554 (const_string "fop")))
15555 (set_attr "mode" "SF")])
15557 (define_insn "*fop_sf_1_mixed"
15558 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15559 (match_operator:SF 3 "binary_fp_operator"
15560 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15561 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15562 "TARGET_MIX_SSE_I387
15563 && !COMMUTATIVE_ARITH_P (operands[3])
15564 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15565 "* return output_387_binary_op (insn, operands);"
15566 [(set (attr "type")
15567 (cond [(and (eq_attr "alternative" "2")
15568 (match_operand:SF 3 "mult_operator" ""))
15569 (const_string "ssemul")
15570 (and (eq_attr "alternative" "2")
15571 (match_operand:SF 3 "div_operator" ""))
15572 (const_string "ssediv")
15573 (eq_attr "alternative" "2")
15574 (const_string "sseadd")
15575 (match_operand:SF 3 "mult_operator" "")
15576 (const_string "fmul")
15577 (match_operand:SF 3 "div_operator" "")
15578 (const_string "fdiv")
15580 (const_string "fop")))
15581 (set_attr "mode" "SF")])
15583 (define_insn "*fop_sf_1_sse"
15584 [(set (match_operand:SF 0 "register_operand" "=x")
15585 (match_operator:SF 3 "binary_fp_operator"
15586 [(match_operand:SF 1 "register_operand" "0")
15587 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15589 && !COMMUTATIVE_ARITH_P (operands[3])"
15590 "* return output_387_binary_op (insn, operands);"
15591 [(set (attr "type")
15592 (cond [(match_operand:SF 3 "mult_operator" "")
15593 (const_string "ssemul")
15594 (match_operand:SF 3 "div_operator" "")
15595 (const_string "ssediv")
15597 (const_string "sseadd")))
15598 (set_attr "mode" "SF")])
15600 ;; This pattern is not fully shadowed by the pattern above.
15601 (define_insn "*fop_sf_1_i387"
15602 [(set (match_operand:SF 0 "register_operand" "=f,f")
15603 (match_operator:SF 3 "binary_fp_operator"
15604 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15605 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15606 "TARGET_80387 && !TARGET_SSE_MATH
15607 && !COMMUTATIVE_ARITH_P (operands[3])
15608 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15609 "* return output_387_binary_op (insn, operands);"
15610 [(set (attr "type")
15611 (cond [(match_operand:SF 3 "mult_operator" "")
15612 (const_string "fmul")
15613 (match_operand:SF 3 "div_operator" "")
15614 (const_string "fdiv")
15616 (const_string "fop")))
15617 (set_attr "mode" "SF")])
15619 ;; ??? Add SSE splitters for these!
15620 (define_insn "*fop_sf_2<mode>_i387"
15621 [(set (match_operand:SF 0 "register_operand" "=f,f")
15622 (match_operator:SF 3 "binary_fp_operator"
15623 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15624 (match_operand:SF 2 "register_operand" "0,0")]))]
15625 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15626 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15627 [(set (attr "type")
15628 (cond [(match_operand:SF 3 "mult_operator" "")
15629 (const_string "fmul")
15630 (match_operand:SF 3 "div_operator" "")
15631 (const_string "fdiv")
15633 (const_string "fop")))
15634 (set_attr "fp_int_src" "true")
15635 (set_attr "mode" "<MODE>")])
15637 (define_insn "*fop_sf_3<mode>_i387"
15638 [(set (match_operand:SF 0 "register_operand" "=f,f")
15639 (match_operator:SF 3 "binary_fp_operator"
15640 [(match_operand:SF 1 "register_operand" "0,0")
15641 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15642 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15643 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15644 [(set (attr "type")
15645 (cond [(match_operand:SF 3 "mult_operator" "")
15646 (const_string "fmul")
15647 (match_operand:SF 3 "div_operator" "")
15648 (const_string "fdiv")
15650 (const_string "fop")))
15651 (set_attr "fp_int_src" "true")
15652 (set_attr "mode" "<MODE>")])
15654 (define_insn "*fop_df_comm_mixed"
15655 [(set (match_operand:DF 0 "register_operand" "=f,x")
15656 (match_operator:DF 3 "binary_fp_operator"
15657 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15658 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15659 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15660 && COMMUTATIVE_ARITH_P (operands[3])
15661 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15662 "* return output_387_binary_op (insn, operands);"
15663 [(set (attr "type")
15664 (if_then_else (eq_attr "alternative" "1")
15665 (if_then_else (match_operand:DF 3 "mult_operator" "")
15666 (const_string "ssemul")
15667 (const_string "sseadd"))
15668 (if_then_else (match_operand:DF 3 "mult_operator" "")
15669 (const_string "fmul")
15670 (const_string "fop"))))
15671 (set_attr "mode" "DF")])
15673 (define_insn "*fop_df_comm_sse"
15674 [(set (match_operand:DF 0 "register_operand" "=x")
15675 (match_operator:DF 3 "binary_fp_operator"
15676 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15677 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15678 "TARGET_SSE2 && TARGET_SSE_MATH
15679 && COMMUTATIVE_ARITH_P (operands[3])
15680 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15681 "* return output_387_binary_op (insn, operands);"
15682 [(set (attr "type")
15683 (if_then_else (match_operand:DF 3 "mult_operator" "")
15684 (const_string "ssemul")
15685 (const_string "sseadd")))
15686 (set_attr "mode" "DF")])
15688 (define_insn "*fop_df_comm_i387"
15689 [(set (match_operand:DF 0 "register_operand" "=f")
15690 (match_operator:DF 3 "binary_fp_operator"
15691 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15692 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15694 && COMMUTATIVE_ARITH_P (operands[3])
15695 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15696 "* return output_387_binary_op (insn, operands);"
15697 [(set (attr "type")
15698 (if_then_else (match_operand:DF 3 "mult_operator" "")
15699 (const_string "fmul")
15700 (const_string "fop")))
15701 (set_attr "mode" "DF")])
15703 (define_insn "*fop_df_1_mixed"
15704 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15705 (match_operator:DF 3 "binary_fp_operator"
15706 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15707 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15708 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15709 && !COMMUTATIVE_ARITH_P (operands[3])
15710 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15711 "* return output_387_binary_op (insn, operands);"
15712 [(set (attr "type")
15713 (cond [(and (eq_attr "alternative" "2")
15714 (match_operand:DF 3 "mult_operator" ""))
15715 (const_string "ssemul")
15716 (and (eq_attr "alternative" "2")
15717 (match_operand:DF 3 "div_operator" ""))
15718 (const_string "ssediv")
15719 (eq_attr "alternative" "2")
15720 (const_string "sseadd")
15721 (match_operand:DF 3 "mult_operator" "")
15722 (const_string "fmul")
15723 (match_operand:DF 3 "div_operator" "")
15724 (const_string "fdiv")
15726 (const_string "fop")))
15727 (set_attr "mode" "DF")])
15729 (define_insn "*fop_df_1_sse"
15730 [(set (match_operand:DF 0 "register_operand" "=x")
15731 (match_operator:DF 3 "binary_fp_operator"
15732 [(match_operand:DF 1 "register_operand" "0")
15733 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15734 "TARGET_SSE2 && TARGET_SSE_MATH
15735 && !COMMUTATIVE_ARITH_P (operands[3])"
15736 "* return output_387_binary_op (insn, operands);"
15737 [(set_attr "mode" "DF")
15739 (cond [(match_operand:DF 3 "mult_operator" "")
15740 (const_string "ssemul")
15741 (match_operand:DF 3 "div_operator" "")
15742 (const_string "ssediv")
15744 (const_string "sseadd")))])
15746 ;; This pattern is not fully shadowed by the pattern above.
15747 (define_insn "*fop_df_1_i387"
15748 [(set (match_operand:DF 0 "register_operand" "=f,f")
15749 (match_operator:DF 3 "binary_fp_operator"
15750 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15751 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15752 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15753 && !COMMUTATIVE_ARITH_P (operands[3])
15754 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15755 "* return output_387_binary_op (insn, operands);"
15756 [(set (attr "type")
15757 (cond [(match_operand:DF 3 "mult_operator" "")
15758 (const_string "fmul")
15759 (match_operand:DF 3 "div_operator" "")
15760 (const_string "fdiv")
15762 (const_string "fop")))
15763 (set_attr "mode" "DF")])
15765 ;; ??? Add SSE splitters for these!
15766 (define_insn "*fop_df_2<mode>_i387"
15767 [(set (match_operand:DF 0 "register_operand" "=f,f")
15768 (match_operator:DF 3 "binary_fp_operator"
15769 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15770 (match_operand:DF 2 "register_operand" "0,0")]))]
15771 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15772 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15773 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15774 [(set (attr "type")
15775 (cond [(match_operand:DF 3 "mult_operator" "")
15776 (const_string "fmul")
15777 (match_operand:DF 3 "div_operator" "")
15778 (const_string "fdiv")
15780 (const_string "fop")))
15781 (set_attr "fp_int_src" "true")
15782 (set_attr "mode" "<MODE>")])
15784 (define_insn "*fop_df_3<mode>_i387"
15785 [(set (match_operand:DF 0 "register_operand" "=f,f")
15786 (match_operator:DF 3 "binary_fp_operator"
15787 [(match_operand:DF 1 "register_operand" "0,0")
15788 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15789 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15790 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15791 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15792 [(set (attr "type")
15793 (cond [(match_operand:DF 3 "mult_operator" "")
15794 (const_string "fmul")
15795 (match_operand:DF 3 "div_operator" "")
15796 (const_string "fdiv")
15798 (const_string "fop")))
15799 (set_attr "fp_int_src" "true")
15800 (set_attr "mode" "<MODE>")])
15802 (define_insn "*fop_df_4_i387"
15803 [(set (match_operand:DF 0 "register_operand" "=f,f")
15804 (match_operator:DF 3 "binary_fp_operator"
15805 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15806 (match_operand:DF 2 "register_operand" "0,f")]))]
15807 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15808 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15809 "* return output_387_binary_op (insn, operands);"
15810 [(set (attr "type")
15811 (cond [(match_operand:DF 3 "mult_operator" "")
15812 (const_string "fmul")
15813 (match_operand:DF 3 "div_operator" "")
15814 (const_string "fdiv")
15816 (const_string "fop")))
15817 (set_attr "mode" "SF")])
15819 (define_insn "*fop_df_5_i387"
15820 [(set (match_operand:DF 0 "register_operand" "=f,f")
15821 (match_operator:DF 3 "binary_fp_operator"
15822 [(match_operand:DF 1 "register_operand" "0,f")
15824 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15825 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15826 "* return output_387_binary_op (insn, operands);"
15827 [(set (attr "type")
15828 (cond [(match_operand:DF 3 "mult_operator" "")
15829 (const_string "fmul")
15830 (match_operand:DF 3 "div_operator" "")
15831 (const_string "fdiv")
15833 (const_string "fop")))
15834 (set_attr "mode" "SF")])
15836 (define_insn "*fop_df_6_i387"
15837 [(set (match_operand:DF 0 "register_operand" "=f,f")
15838 (match_operator:DF 3 "binary_fp_operator"
15840 (match_operand:SF 1 "register_operand" "0,f"))
15842 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15843 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15844 "* return output_387_binary_op (insn, operands);"
15845 [(set (attr "type")
15846 (cond [(match_operand:DF 3 "mult_operator" "")
15847 (const_string "fmul")
15848 (match_operand:DF 3 "div_operator" "")
15849 (const_string "fdiv")
15851 (const_string "fop")))
15852 (set_attr "mode" "SF")])
15854 (define_insn "*fop_xf_comm_i387"
15855 [(set (match_operand:XF 0 "register_operand" "=f")
15856 (match_operator:XF 3 "binary_fp_operator"
15857 [(match_operand:XF 1 "register_operand" "%0")
15858 (match_operand:XF 2 "register_operand" "f")]))]
15860 && COMMUTATIVE_ARITH_P (operands[3])"
15861 "* return output_387_binary_op (insn, operands);"
15862 [(set (attr "type")
15863 (if_then_else (match_operand:XF 3 "mult_operator" "")
15864 (const_string "fmul")
15865 (const_string "fop")))
15866 (set_attr "mode" "XF")])
15868 (define_insn "*fop_xf_1_i387"
15869 [(set (match_operand:XF 0 "register_operand" "=f,f")
15870 (match_operator:XF 3 "binary_fp_operator"
15871 [(match_operand:XF 1 "register_operand" "0,f")
15872 (match_operand:XF 2 "register_operand" "f,0")]))]
15874 && !COMMUTATIVE_ARITH_P (operands[3])"
15875 "* return output_387_binary_op (insn, operands);"
15876 [(set (attr "type")
15877 (cond [(match_operand:XF 3 "mult_operator" "")
15878 (const_string "fmul")
15879 (match_operand:XF 3 "div_operator" "")
15880 (const_string "fdiv")
15882 (const_string "fop")))
15883 (set_attr "mode" "XF")])
15885 (define_insn "*fop_xf_2<mode>_i387"
15886 [(set (match_operand:XF 0 "register_operand" "=f,f")
15887 (match_operator:XF 3 "binary_fp_operator"
15888 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15889 (match_operand:XF 2 "register_operand" "0,0")]))]
15890 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15891 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15892 [(set (attr "type")
15893 (cond [(match_operand:XF 3 "mult_operator" "")
15894 (const_string "fmul")
15895 (match_operand:XF 3 "div_operator" "")
15896 (const_string "fdiv")
15898 (const_string "fop")))
15899 (set_attr "fp_int_src" "true")
15900 (set_attr "mode" "<MODE>")])
15902 (define_insn "*fop_xf_3<mode>_i387"
15903 [(set (match_operand:XF 0 "register_operand" "=f,f")
15904 (match_operator:XF 3 "binary_fp_operator"
15905 [(match_operand:XF 1 "register_operand" "0,0")
15906 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15907 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15908 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15909 [(set (attr "type")
15910 (cond [(match_operand:XF 3 "mult_operator" "")
15911 (const_string "fmul")
15912 (match_operand:XF 3 "div_operator" "")
15913 (const_string "fdiv")
15915 (const_string "fop")))
15916 (set_attr "fp_int_src" "true")
15917 (set_attr "mode" "<MODE>")])
15919 (define_insn "*fop_xf_4_i387"
15920 [(set (match_operand:XF 0 "register_operand" "=f,f")
15921 (match_operator:XF 3 "binary_fp_operator"
15923 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15924 (match_operand:XF 2 "register_operand" "0,f")]))]
15926 "* return output_387_binary_op (insn, operands);"
15927 [(set (attr "type")
15928 (cond [(match_operand:XF 3 "mult_operator" "")
15929 (const_string "fmul")
15930 (match_operand:XF 3 "div_operator" "")
15931 (const_string "fdiv")
15933 (const_string "fop")))
15934 (set_attr "mode" "SF")])
15936 (define_insn "*fop_xf_5_i387"
15937 [(set (match_operand:XF 0 "register_operand" "=f,f")
15938 (match_operator:XF 3 "binary_fp_operator"
15939 [(match_operand:XF 1 "register_operand" "0,f")
15941 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15943 "* return output_387_binary_op (insn, operands);"
15944 [(set (attr "type")
15945 (cond [(match_operand:XF 3 "mult_operator" "")
15946 (const_string "fmul")
15947 (match_operand:XF 3 "div_operator" "")
15948 (const_string "fdiv")
15950 (const_string "fop")))
15951 (set_attr "mode" "SF")])
15953 (define_insn "*fop_xf_6_i387"
15954 [(set (match_operand:XF 0 "register_operand" "=f,f")
15955 (match_operator:XF 3 "binary_fp_operator"
15957 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15959 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15961 "* return output_387_binary_op (insn, operands);"
15962 [(set (attr "type")
15963 (cond [(match_operand:XF 3 "mult_operator" "")
15964 (const_string "fmul")
15965 (match_operand:XF 3 "div_operator" "")
15966 (const_string "fdiv")
15968 (const_string "fop")))
15969 (set_attr "mode" "SF")])
15972 [(set (match_operand 0 "register_operand" "")
15973 (match_operator 3 "binary_fp_operator"
15974 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15975 (match_operand 2 "register_operand" "")]))]
15976 "TARGET_80387 && reload_completed
15977 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15980 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15981 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15982 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15983 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15984 GET_MODE (operands[3]),
15987 ix86_free_from_memory (GET_MODE (operands[1]));
15992 [(set (match_operand 0 "register_operand" "")
15993 (match_operator 3 "binary_fp_operator"
15994 [(match_operand 1 "register_operand" "")
15995 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15996 "TARGET_80387 && reload_completed
15997 && FLOAT_MODE_P (GET_MODE (operands[0]))"
16000 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16001 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16002 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16003 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16004 GET_MODE (operands[3]),
16007 ix86_free_from_memory (GET_MODE (operands[2]));
16011 ;; FPU special functions.
16013 ;; This pattern implements a no-op XFmode truncation for
16014 ;; all fancy i386 XFmode math functions.
16016 (define_insn "truncxf<mode>2_i387_noop_unspec"
16017 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16018 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16019 UNSPEC_TRUNC_NOOP))]
16020 "TARGET_USE_FANCY_MATH_387"
16021 "* return output_387_reg_move (insn, operands);"
16022 [(set_attr "type" "fmov")
16023 (set_attr "mode" "<MODE>")])
16025 (define_insn "sqrtxf2"
16026 [(set (match_operand:XF 0 "register_operand" "=f")
16027 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16028 "TARGET_USE_FANCY_MATH_387"
16030 [(set_attr "type" "fpspc")
16031 (set_attr "mode" "XF")
16032 (set_attr "athlon_decode" "direct")
16033 (set_attr "amdfam10_decode" "direct")])
16035 (define_insn "sqrt_extend<mode>xf2_i387"
16036 [(set (match_operand:XF 0 "register_operand" "=f")
16039 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16040 "TARGET_USE_FANCY_MATH_387"
16042 [(set_attr "type" "fpspc")
16043 (set_attr "mode" "XF")
16044 (set_attr "athlon_decode" "direct")
16045 (set_attr "amdfam10_decode" "direct")])
16047 (define_insn "*sqrt<mode>2_sse"
16048 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16050 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16051 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16052 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16053 [(set_attr "type" "sse")
16054 (set_attr "mode" "<MODE>")
16055 (set_attr "athlon_decode" "*")
16056 (set_attr "amdfam10_decode" "*")])
16058 (define_expand "sqrt<mode>2"
16059 [(set (match_operand:X87MODEF12 0 "register_operand" "")
16061 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16062 "TARGET_USE_FANCY_MATH_387
16063 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16065 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16067 rtx op0 = gen_reg_rtx (XFmode);
16068 rtx op1 = force_reg (<MODE>mode, operands[1]);
16070 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16071 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16076 (define_insn "fpremxf4_i387"
16077 [(set (match_operand:XF 0 "register_operand" "=f")
16078 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16079 (match_operand:XF 3 "register_operand" "1")]
16081 (set (match_operand:XF 1 "register_operand" "=u")
16082 (unspec:XF [(match_dup 2) (match_dup 3)]
16084 (set (reg:CCFP FPSR_REG)
16085 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16086 "TARGET_USE_FANCY_MATH_387"
16088 [(set_attr "type" "fpspc")
16089 (set_attr "mode" "XF")])
16091 (define_expand "fmodxf3"
16092 [(use (match_operand:XF 0 "register_operand" ""))
16093 (use (match_operand:XF 1 "register_operand" ""))
16094 (use (match_operand:XF 2 "register_operand" ""))]
16095 "TARGET_USE_FANCY_MATH_387"
16097 rtx label = gen_label_rtx ();
16099 emit_label (label);
16101 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16102 operands[1], operands[2]));
16103 ix86_emit_fp_unordered_jump (label);
16105 emit_move_insn (operands[0], operands[1]);
16109 (define_expand "fmod<mode>3"
16110 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16111 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16112 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16113 "TARGET_USE_FANCY_MATH_387"
16115 rtx label = gen_label_rtx ();
16117 rtx op1 = gen_reg_rtx (XFmode);
16118 rtx op2 = gen_reg_rtx (XFmode);
16120 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16121 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16123 emit_label (label);
16124 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16125 ix86_emit_fp_unordered_jump (label);
16127 /* Truncate the result properly for strict SSE math. */
16128 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16129 && !TARGET_MIX_SSE_I387)
16130 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16132 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16137 (define_insn "fprem1xf4_i387"
16138 [(set (match_operand:XF 0 "register_operand" "=f")
16139 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16140 (match_operand:XF 3 "register_operand" "1")]
16142 (set (match_operand:XF 1 "register_operand" "=u")
16143 (unspec:XF [(match_dup 2) (match_dup 3)]
16145 (set (reg:CCFP FPSR_REG)
16146 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16147 "TARGET_USE_FANCY_MATH_387"
16149 [(set_attr "type" "fpspc")
16150 (set_attr "mode" "XF")])
16152 (define_expand "remainderxf3"
16153 [(use (match_operand:XF 0 "register_operand" ""))
16154 (use (match_operand:XF 1 "register_operand" ""))
16155 (use (match_operand:XF 2 "register_operand" ""))]
16156 "TARGET_USE_FANCY_MATH_387"
16158 rtx label = gen_label_rtx ();
16160 emit_label (label);
16162 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16163 operands[1], operands[2]));
16164 ix86_emit_fp_unordered_jump (label);
16166 emit_move_insn (operands[0], operands[1]);
16170 (define_expand "remainder<mode>3"
16171 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16172 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16173 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16174 "TARGET_USE_FANCY_MATH_387"
16176 rtx label = gen_label_rtx ();
16178 rtx op1 = gen_reg_rtx (XFmode);
16179 rtx op2 = gen_reg_rtx (XFmode);
16181 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16182 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16184 emit_label (label);
16186 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16187 ix86_emit_fp_unordered_jump (label);
16189 /* Truncate the result properly for strict SSE math. */
16190 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16191 && !TARGET_MIX_SSE_I387)
16192 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16194 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16199 (define_insn "*sinxf2_i387"
16200 [(set (match_operand:XF 0 "register_operand" "=f")
16201 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16202 "TARGET_USE_FANCY_MATH_387
16203 && flag_unsafe_math_optimizations"
16205 [(set_attr "type" "fpspc")
16206 (set_attr "mode" "XF")])
16208 (define_insn "*sin_extend<mode>xf2_i387"
16209 [(set (match_operand:XF 0 "register_operand" "=f")
16210 (unspec:XF [(float_extend:XF
16211 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16213 "TARGET_USE_FANCY_MATH_387
16214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16215 || TARGET_MIX_SSE_I387)
16216 && flag_unsafe_math_optimizations"
16218 [(set_attr "type" "fpspc")
16219 (set_attr "mode" "XF")])
16221 (define_insn "*cosxf2_i387"
16222 [(set (match_operand:XF 0 "register_operand" "=f")
16223 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16224 "TARGET_USE_FANCY_MATH_387
16225 && flag_unsafe_math_optimizations"
16227 [(set_attr "type" "fpspc")
16228 (set_attr "mode" "XF")])
16230 (define_insn "*cos_extend<mode>xf2_i387"
16231 [(set (match_operand:XF 0 "register_operand" "=f")
16232 (unspec:XF [(float_extend:XF
16233 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16235 "TARGET_USE_FANCY_MATH_387
16236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16237 || TARGET_MIX_SSE_I387)
16238 && flag_unsafe_math_optimizations"
16240 [(set_attr "type" "fpspc")
16241 (set_attr "mode" "XF")])
16243 ;; When sincos pattern is defined, sin and cos builtin functions will be
16244 ;; expanded to sincos pattern with one of its outputs left unused.
16245 ;; CSE pass will figure out if two sincos patterns can be combined,
16246 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16247 ;; depending on the unused output.
16249 (define_insn "sincosxf3"
16250 [(set (match_operand:XF 0 "register_operand" "=f")
16251 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16252 UNSPEC_SINCOS_COS))
16253 (set (match_operand:XF 1 "register_operand" "=u")
16254 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16255 "TARGET_USE_FANCY_MATH_387
16256 && flag_unsafe_math_optimizations"
16258 [(set_attr "type" "fpspc")
16259 (set_attr "mode" "XF")])
16262 [(set (match_operand:XF 0 "register_operand" "")
16263 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16264 UNSPEC_SINCOS_COS))
16265 (set (match_operand:XF 1 "register_operand" "")
16266 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16267 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16268 && !reload_completed && !reload_in_progress"
16269 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16273 [(set (match_operand:XF 0 "register_operand" "")
16274 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16275 UNSPEC_SINCOS_COS))
16276 (set (match_operand:XF 1 "register_operand" "")
16277 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16278 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16279 && !reload_completed && !reload_in_progress"
16280 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16283 (define_insn "sincos_extend<mode>xf3_i387"
16284 [(set (match_operand:XF 0 "register_operand" "=f")
16285 (unspec:XF [(float_extend:XF
16286 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16287 UNSPEC_SINCOS_COS))
16288 (set (match_operand:XF 1 "register_operand" "=u")
16289 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16290 "TARGET_USE_FANCY_MATH_387
16291 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16292 || TARGET_MIX_SSE_I387)
16293 && flag_unsafe_math_optimizations"
16295 [(set_attr "type" "fpspc")
16296 (set_attr "mode" "XF")])
16299 [(set (match_operand:XF 0 "register_operand" "")
16300 (unspec:XF [(float_extend:XF
16301 (match_operand:X87MODEF12 2 "register_operand" ""))]
16302 UNSPEC_SINCOS_COS))
16303 (set (match_operand:XF 1 "register_operand" "")
16304 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16305 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16306 && !reload_completed && !reload_in_progress"
16307 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16311 [(set (match_operand:XF 0 "register_operand" "")
16312 (unspec:XF [(float_extend:XF
16313 (match_operand:X87MODEF12 2 "register_operand" ""))]
16314 UNSPEC_SINCOS_COS))
16315 (set (match_operand:XF 1 "register_operand" "")
16316 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16317 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16318 && !reload_completed && !reload_in_progress"
16319 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16322 (define_expand "sincos<mode>3"
16323 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16324 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16325 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16326 "TARGET_USE_FANCY_MATH_387
16327 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16328 || TARGET_MIX_SSE_I387)
16329 && flag_unsafe_math_optimizations"
16331 rtx op0 = gen_reg_rtx (XFmode);
16332 rtx op1 = gen_reg_rtx (XFmode);
16334 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16335 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16336 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16340 (define_insn "fptanxf4_i387"
16341 [(set (match_operand:XF 0 "register_operand" "=f")
16342 (match_operand:XF 3 "const_double_operand" "F"))
16343 (set (match_operand:XF 1 "register_operand" "=u")
16344 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16346 "TARGET_USE_FANCY_MATH_387
16347 && flag_unsafe_math_optimizations
16348 && standard_80387_constant_p (operands[3]) == 2"
16350 [(set_attr "type" "fpspc")
16351 (set_attr "mode" "XF")])
16353 (define_insn "fptan_extend<mode>xf4_i387"
16354 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16355 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16356 (set (match_operand:XF 1 "register_operand" "=u")
16357 (unspec:XF [(float_extend:XF
16358 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16360 "TARGET_USE_FANCY_MATH_387
16361 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16362 || TARGET_MIX_SSE_I387)
16363 && flag_unsafe_math_optimizations
16364 && standard_80387_constant_p (operands[3]) == 2"
16366 [(set_attr "type" "fpspc")
16367 (set_attr "mode" "XF")])
16369 (define_expand "tanxf2"
16370 [(use (match_operand:XF 0 "register_operand" ""))
16371 (use (match_operand:XF 1 "register_operand" ""))]
16372 "TARGET_USE_FANCY_MATH_387
16373 && flag_unsafe_math_optimizations"
16375 rtx one = gen_reg_rtx (XFmode);
16376 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16378 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16382 (define_expand "tan<mode>2"
16383 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16384 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16385 "TARGET_USE_FANCY_MATH_387
16386 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16387 || TARGET_MIX_SSE_I387)
16388 && flag_unsafe_math_optimizations"
16390 rtx op0 = gen_reg_rtx (XFmode);
16392 rtx one = gen_reg_rtx (<MODE>mode);
16393 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16395 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16396 operands[1], op2));
16397 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16401 (define_insn "*fpatanxf3_i387"
16402 [(set (match_operand:XF 0 "register_operand" "=f")
16403 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16404 (match_operand:XF 2 "register_operand" "u")]
16406 (clobber (match_scratch:XF 3 "=2"))]
16407 "TARGET_USE_FANCY_MATH_387
16408 && flag_unsafe_math_optimizations"
16410 [(set_attr "type" "fpspc")
16411 (set_attr "mode" "XF")])
16413 (define_insn "fpatan_extend<mode>xf3_i387"
16414 [(set (match_operand:XF 0 "register_operand" "=f")
16415 (unspec:XF [(float_extend:XF
16416 (match_operand:X87MODEF12 1 "register_operand" "0"))
16418 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16420 (clobber (match_scratch:XF 3 "=2"))]
16421 "TARGET_USE_FANCY_MATH_387
16422 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16423 || TARGET_MIX_SSE_I387)
16424 && flag_unsafe_math_optimizations"
16426 [(set_attr "type" "fpspc")
16427 (set_attr "mode" "XF")])
16429 (define_expand "atan2xf3"
16430 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16431 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16432 (match_operand:XF 1 "register_operand" "")]
16434 (clobber (match_scratch:XF 3 ""))])]
16435 "TARGET_USE_FANCY_MATH_387
16436 && flag_unsafe_math_optimizations"
16439 (define_expand "atan2<mode>3"
16440 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16441 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16442 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16443 "TARGET_USE_FANCY_MATH_387
16444 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16445 || TARGET_MIX_SSE_I387)
16446 && flag_unsafe_math_optimizations"
16448 rtx op0 = gen_reg_rtx (XFmode);
16450 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16451 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16455 (define_expand "atanxf2"
16456 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16457 (unspec:XF [(match_dup 2)
16458 (match_operand:XF 1 "register_operand" "")]
16460 (clobber (match_scratch:XF 3 ""))])]
16461 "TARGET_USE_FANCY_MATH_387
16462 && flag_unsafe_math_optimizations"
16464 operands[2] = gen_reg_rtx (XFmode);
16465 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16468 (define_expand "atan<mode>2"
16469 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16470 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16471 "TARGET_USE_FANCY_MATH_387
16472 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16473 || TARGET_MIX_SSE_I387)
16474 && flag_unsafe_math_optimizations"
16476 rtx op0 = gen_reg_rtx (XFmode);
16478 rtx op2 = gen_reg_rtx (<MODE>mode);
16479 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16481 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16482 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16486 (define_expand "asinxf2"
16487 [(set (match_dup 2)
16488 (mult:XF (match_operand:XF 1 "register_operand" "")
16490 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16491 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16492 (parallel [(set (match_operand:XF 0 "register_operand" "")
16493 (unspec:XF [(match_dup 5) (match_dup 1)]
16495 (clobber (match_scratch:XF 6 ""))])]
16496 "TARGET_USE_FANCY_MATH_387
16497 && flag_unsafe_math_optimizations && !optimize_size"
16501 for (i = 2; i < 6; i++)
16502 operands[i] = gen_reg_rtx (XFmode);
16504 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16507 (define_expand "asin<mode>2"
16508 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16509 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16510 "TARGET_USE_FANCY_MATH_387
16511 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16512 || TARGET_MIX_SSE_I387)
16513 && flag_unsafe_math_optimizations && !optimize_size"
16515 rtx op0 = gen_reg_rtx (XFmode);
16516 rtx op1 = gen_reg_rtx (XFmode);
16518 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16519 emit_insn (gen_asinxf2 (op0, op1));
16520 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16524 (define_expand "acosxf2"
16525 [(set (match_dup 2)
16526 (mult:XF (match_operand:XF 1 "register_operand" "")
16528 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16529 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16530 (parallel [(set (match_operand:XF 0 "register_operand" "")
16531 (unspec:XF [(match_dup 1) (match_dup 5)]
16533 (clobber (match_scratch:XF 6 ""))])]
16534 "TARGET_USE_FANCY_MATH_387
16535 && flag_unsafe_math_optimizations && !optimize_size"
16539 for (i = 2; i < 6; i++)
16540 operands[i] = gen_reg_rtx (XFmode);
16542 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16545 (define_expand "acos<mode>2"
16546 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16547 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16548 "TARGET_USE_FANCY_MATH_387
16549 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16550 || TARGET_MIX_SSE_I387)
16551 && flag_unsafe_math_optimizations && !optimize_size"
16553 rtx op0 = gen_reg_rtx (XFmode);
16554 rtx op1 = gen_reg_rtx (XFmode);
16556 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16557 emit_insn (gen_acosxf2 (op0, op1));
16558 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16562 (define_insn "fyl2xxf3_i387"
16563 [(set (match_operand:XF 0 "register_operand" "=f")
16564 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16565 (match_operand:XF 2 "register_operand" "u")]
16567 (clobber (match_scratch:XF 3 "=2"))]
16568 "TARGET_USE_FANCY_MATH_387
16569 && flag_unsafe_math_optimizations"
16571 [(set_attr "type" "fpspc")
16572 (set_attr "mode" "XF")])
16574 (define_insn "fyl2x_extend<mode>xf3_i387"
16575 [(set (match_operand:XF 0 "register_operand" "=f")
16576 (unspec:XF [(float_extend:XF
16577 (match_operand:X87MODEF12 1 "register_operand" "0"))
16578 (match_operand:XF 2 "register_operand" "u")]
16580 (clobber (match_scratch:XF 3 "=2"))]
16581 "TARGET_USE_FANCY_MATH_387
16582 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16583 || TARGET_MIX_SSE_I387)
16584 && flag_unsafe_math_optimizations"
16586 [(set_attr "type" "fpspc")
16587 (set_attr "mode" "XF")])
16589 (define_expand "logxf2"
16590 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16591 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16592 (match_dup 2)] UNSPEC_FYL2X))
16593 (clobber (match_scratch:XF 3 ""))])]
16594 "TARGET_USE_FANCY_MATH_387
16595 && flag_unsafe_math_optimizations"
16597 operands[2] = gen_reg_rtx (XFmode);
16598 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16601 (define_expand "log<mode>2"
16602 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16603 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16604 "TARGET_USE_FANCY_MATH_387
16605 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16606 || TARGET_MIX_SSE_I387)
16607 && flag_unsafe_math_optimizations"
16609 rtx op0 = gen_reg_rtx (XFmode);
16611 rtx op2 = gen_reg_rtx (XFmode);
16612 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16614 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16615 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16619 (define_expand "log10xf2"
16620 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16621 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16622 (match_dup 2)] UNSPEC_FYL2X))
16623 (clobber (match_scratch:XF 3 ""))])]
16624 "TARGET_USE_FANCY_MATH_387
16625 && flag_unsafe_math_optimizations"
16627 operands[2] = gen_reg_rtx (XFmode);
16628 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16631 (define_expand "log10<mode>2"
16632 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16633 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16634 "TARGET_USE_FANCY_MATH_387
16635 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16636 || TARGET_MIX_SSE_I387)
16637 && flag_unsafe_math_optimizations"
16639 rtx op0 = gen_reg_rtx (XFmode);
16641 rtx op2 = gen_reg_rtx (XFmode);
16642 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16644 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16645 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16649 (define_expand "log2xf2"
16650 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16651 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16652 (match_dup 2)] UNSPEC_FYL2X))
16653 (clobber (match_scratch:XF 3 ""))])]
16654 "TARGET_USE_FANCY_MATH_387
16655 && flag_unsafe_math_optimizations"
16657 operands[2] = gen_reg_rtx (XFmode);
16658 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16661 (define_expand "log2<mode>2"
16662 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16663 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16664 "TARGET_USE_FANCY_MATH_387
16665 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16666 || TARGET_MIX_SSE_I387)
16667 && flag_unsafe_math_optimizations"
16669 rtx op0 = gen_reg_rtx (XFmode);
16671 rtx op2 = gen_reg_rtx (XFmode);
16672 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16674 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16675 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16679 (define_insn "fyl2xp1xf3_i387"
16680 [(set (match_operand:XF 0 "register_operand" "=f")
16681 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16682 (match_operand:XF 2 "register_operand" "u")]
16684 (clobber (match_scratch:XF 3 "=2"))]
16685 "TARGET_USE_FANCY_MATH_387
16686 && flag_unsafe_math_optimizations"
16688 [(set_attr "type" "fpspc")
16689 (set_attr "mode" "XF")])
16691 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16692 [(set (match_operand:XF 0 "register_operand" "=f")
16693 (unspec:XF [(float_extend:XF
16694 (match_operand:X87MODEF12 1 "register_operand" "0"))
16695 (match_operand:XF 2 "register_operand" "u")]
16697 (clobber (match_scratch:XF 3 "=2"))]
16698 "TARGET_USE_FANCY_MATH_387
16699 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16700 || TARGET_MIX_SSE_I387)
16701 && flag_unsafe_math_optimizations"
16703 [(set_attr "type" "fpspc")
16704 (set_attr "mode" "XF")])
16706 (define_expand "log1pxf2"
16707 [(use (match_operand:XF 0 "register_operand" ""))
16708 (use (match_operand:XF 1 "register_operand" ""))]
16709 "TARGET_USE_FANCY_MATH_387
16710 && flag_unsafe_math_optimizations && !optimize_size"
16712 ix86_emit_i387_log1p (operands[0], operands[1]);
16716 (define_expand "log1p<mode>2"
16717 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16718 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16719 "TARGET_USE_FANCY_MATH_387
16720 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16721 || TARGET_MIX_SSE_I387)
16722 && flag_unsafe_math_optimizations && !optimize_size"
16724 rtx op0 = gen_reg_rtx (XFmode);
16726 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16728 ix86_emit_i387_log1p (op0, operands[1]);
16729 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16733 (define_insn "fxtractxf3_i387"
16734 [(set (match_operand:XF 0 "register_operand" "=f")
16735 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16736 UNSPEC_XTRACT_FRACT))
16737 (set (match_operand:XF 1 "register_operand" "=u")
16738 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16739 "TARGET_USE_FANCY_MATH_387
16740 && flag_unsafe_math_optimizations"
16742 [(set_attr "type" "fpspc")
16743 (set_attr "mode" "XF")])
16745 (define_insn "fxtract_extend<mode>xf3_i387"
16746 [(set (match_operand:XF 0 "register_operand" "=f")
16747 (unspec:XF [(float_extend:XF
16748 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16749 UNSPEC_XTRACT_FRACT))
16750 (set (match_operand:XF 1 "register_operand" "=u")
16751 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16752 "TARGET_USE_FANCY_MATH_387
16753 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16754 || TARGET_MIX_SSE_I387)
16755 && flag_unsafe_math_optimizations"
16757 [(set_attr "type" "fpspc")
16758 (set_attr "mode" "XF")])
16760 (define_expand "logbxf2"
16761 [(parallel [(set (match_dup 2)
16762 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16763 UNSPEC_XTRACT_FRACT))
16764 (set (match_operand:XF 0 "register_operand" "")
16765 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16766 "TARGET_USE_FANCY_MATH_387
16767 && flag_unsafe_math_optimizations"
16769 operands[2] = gen_reg_rtx (XFmode);
16772 (define_expand "logb<mode>2"
16773 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16774 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16775 "TARGET_USE_FANCY_MATH_387
16776 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16777 || TARGET_MIX_SSE_I387)
16778 && flag_unsafe_math_optimizations"
16780 rtx op0 = gen_reg_rtx (XFmode);
16781 rtx op1 = gen_reg_rtx (XFmode);
16783 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16784 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16788 (define_expand "ilogbxf2"
16789 [(use (match_operand:SI 0 "register_operand" ""))
16790 (use (match_operand:XF 1 "register_operand" ""))]
16791 "TARGET_USE_FANCY_MATH_387
16792 && flag_unsafe_math_optimizations && !optimize_size"
16794 rtx op0 = gen_reg_rtx (XFmode);
16795 rtx op1 = gen_reg_rtx (XFmode);
16797 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16798 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16802 (define_expand "ilogb<mode>2"
16803 [(use (match_operand:SI 0 "register_operand" ""))
16804 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16805 "TARGET_USE_FANCY_MATH_387
16806 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16807 || TARGET_MIX_SSE_I387)
16808 && flag_unsafe_math_optimizations && !optimize_size"
16810 rtx op0 = gen_reg_rtx (XFmode);
16811 rtx op1 = gen_reg_rtx (XFmode);
16813 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16814 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16818 (define_insn "*f2xm1xf2_i387"
16819 [(set (match_operand:XF 0 "register_operand" "=f")
16820 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16822 "TARGET_USE_FANCY_MATH_387
16823 && flag_unsafe_math_optimizations"
16825 [(set_attr "type" "fpspc")
16826 (set_attr "mode" "XF")])
16828 (define_insn "*fscalexf4_i387"
16829 [(set (match_operand:XF 0 "register_operand" "=f")
16830 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16831 (match_operand:XF 3 "register_operand" "1")]
16832 UNSPEC_FSCALE_FRACT))
16833 (set (match_operand:XF 1 "register_operand" "=u")
16834 (unspec:XF [(match_dup 2) (match_dup 3)]
16835 UNSPEC_FSCALE_EXP))]
16836 "TARGET_USE_FANCY_MATH_387
16837 && flag_unsafe_math_optimizations"
16839 [(set_attr "type" "fpspc")
16840 (set_attr "mode" "XF")])
16842 (define_expand "expNcorexf3"
16843 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16844 (match_operand:XF 2 "register_operand" "")))
16845 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16846 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16847 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16848 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16849 (parallel [(set (match_operand:XF 0 "register_operand" "")
16850 (unspec:XF [(match_dup 8) (match_dup 4)]
16851 UNSPEC_FSCALE_FRACT))
16853 (unspec:XF [(match_dup 8) (match_dup 4)]
16854 UNSPEC_FSCALE_EXP))])]
16855 "TARGET_USE_FANCY_MATH_387
16856 && flag_unsafe_math_optimizations && !optimize_size"
16860 for (i = 3; i < 10; i++)
16861 operands[i] = gen_reg_rtx (XFmode);
16863 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16866 (define_expand "expxf2"
16867 [(use (match_operand:XF 0 "register_operand" ""))
16868 (use (match_operand:XF 1 "register_operand" ""))]
16869 "TARGET_USE_FANCY_MATH_387
16870 && flag_unsafe_math_optimizations && !optimize_size"
16872 rtx op2 = gen_reg_rtx (XFmode);
16873 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16875 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16879 (define_expand "exp<mode>2"
16880 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16881 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16882 "TARGET_USE_FANCY_MATH_387
16883 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16884 || TARGET_MIX_SSE_I387)
16885 && flag_unsafe_math_optimizations && !optimize_size"
16887 rtx op0 = gen_reg_rtx (XFmode);
16888 rtx op1 = gen_reg_rtx (XFmode);
16890 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16891 emit_insn (gen_expxf2 (op0, op1));
16892 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16896 (define_expand "exp10xf2"
16897 [(use (match_operand:XF 0 "register_operand" ""))
16898 (use (match_operand:XF 1 "register_operand" ""))]
16899 "TARGET_USE_FANCY_MATH_387
16900 && flag_unsafe_math_optimizations && !optimize_size"
16902 rtx op2 = gen_reg_rtx (XFmode);
16903 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16905 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16909 (define_expand "exp10<mode>2"
16910 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16911 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16912 "TARGET_USE_FANCY_MATH_387
16913 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16914 || TARGET_MIX_SSE_I387)
16915 && flag_unsafe_math_optimizations && !optimize_size"
16917 rtx op0 = gen_reg_rtx (XFmode);
16918 rtx op1 = gen_reg_rtx (XFmode);
16920 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16921 emit_insn (gen_exp10xf2 (op0, op1));
16922 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16926 (define_expand "exp2xf2"
16927 [(use (match_operand:XF 0 "register_operand" ""))
16928 (use (match_operand:XF 1 "register_operand" ""))]
16929 "TARGET_USE_FANCY_MATH_387
16930 && flag_unsafe_math_optimizations && !optimize_size"
16932 rtx op2 = gen_reg_rtx (XFmode);
16933 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16935 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16939 (define_expand "exp2<mode>2"
16940 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16941 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16942 "TARGET_USE_FANCY_MATH_387
16943 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16944 || TARGET_MIX_SSE_I387)
16945 && flag_unsafe_math_optimizations && !optimize_size"
16947 rtx op0 = gen_reg_rtx (XFmode);
16948 rtx op1 = gen_reg_rtx (XFmode);
16950 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16951 emit_insn (gen_exp2xf2 (op0, op1));
16952 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16956 (define_expand "expm1xf2"
16957 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16959 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16960 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16961 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16962 (parallel [(set (match_dup 7)
16963 (unspec:XF [(match_dup 6) (match_dup 4)]
16964 UNSPEC_FSCALE_FRACT))
16966 (unspec:XF [(match_dup 6) (match_dup 4)]
16967 UNSPEC_FSCALE_EXP))])
16968 (parallel [(set (match_dup 10)
16969 (unspec:XF [(match_dup 9) (match_dup 8)]
16970 UNSPEC_FSCALE_FRACT))
16971 (set (match_dup 11)
16972 (unspec:XF [(match_dup 9) (match_dup 8)]
16973 UNSPEC_FSCALE_EXP))])
16974 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16975 (set (match_operand:XF 0 "register_operand" "")
16976 (plus:XF (match_dup 12) (match_dup 7)))]
16977 "TARGET_USE_FANCY_MATH_387
16978 && flag_unsafe_math_optimizations && !optimize_size"
16982 for (i = 2; i < 13; i++)
16983 operands[i] = gen_reg_rtx (XFmode);
16985 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16986 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16989 (define_expand "expm1<mode>2"
16990 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16991 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16992 "TARGET_USE_FANCY_MATH_387
16993 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16994 || TARGET_MIX_SSE_I387)
16995 && flag_unsafe_math_optimizations && !optimize_size"
16997 rtx op0 = gen_reg_rtx (XFmode);
16998 rtx op1 = gen_reg_rtx (XFmode);
17000 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17001 emit_insn (gen_expm1xf2 (op0, op1));
17002 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17006 (define_expand "ldexpxf3"
17007 [(set (match_dup 3)
17008 (float:XF (match_operand:SI 2 "register_operand" "")))
17009 (parallel [(set (match_operand:XF 0 " register_operand" "")
17010 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17012 UNSPEC_FSCALE_FRACT))
17014 (unspec:XF [(match_dup 1) (match_dup 3)]
17015 UNSPEC_FSCALE_EXP))])]
17016 "TARGET_USE_FANCY_MATH_387
17017 && flag_unsafe_math_optimizations && !optimize_size"
17019 operands[3] = gen_reg_rtx (XFmode);
17020 operands[4] = gen_reg_rtx (XFmode);
17023 (define_expand "ldexp<mode>3"
17024 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17025 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17026 (use (match_operand:SI 2 "register_operand" ""))]
17027 "TARGET_USE_FANCY_MATH_387
17028 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17029 || TARGET_MIX_SSE_I387)
17030 && flag_unsafe_math_optimizations && !optimize_size"
17032 rtx op0 = gen_reg_rtx (XFmode);
17033 rtx op1 = gen_reg_rtx (XFmode);
17035 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17036 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17037 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17042 (define_insn "frndintxf2"
17043 [(set (match_operand:XF 0 "register_operand" "=f")
17044 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17046 "TARGET_USE_FANCY_MATH_387
17047 && flag_unsafe_math_optimizations"
17049 [(set_attr "type" "fpspc")
17050 (set_attr "mode" "XF")])
17052 (define_expand "rintdf2"
17053 [(use (match_operand:DF 0 "register_operand" ""))
17054 (use (match_operand:DF 1 "register_operand" ""))]
17055 "(TARGET_USE_FANCY_MATH_387
17056 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17057 && flag_unsafe_math_optimizations)
17058 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17059 && !flag_trapping_math
17060 && !optimize_size)"
17062 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17063 && !flag_trapping_math
17065 ix86_expand_rint (operand0, operand1);
17068 rtx op0 = gen_reg_rtx (XFmode);
17069 rtx op1 = gen_reg_rtx (XFmode);
17071 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17072 emit_insn (gen_frndintxf2 (op0, op1));
17074 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17079 (define_expand "rintsf2"
17080 [(use (match_operand:SF 0 "register_operand" ""))
17081 (use (match_operand:SF 1 "register_operand" ""))]
17082 "(TARGET_USE_FANCY_MATH_387
17083 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17084 && flag_unsafe_math_optimizations)
17085 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17086 && !flag_trapping_math
17087 && !optimize_size)"
17089 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17090 && !flag_trapping_math
17092 ix86_expand_rint (operand0, operand1);
17095 rtx op0 = gen_reg_rtx (XFmode);
17096 rtx op1 = gen_reg_rtx (XFmode);
17098 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17099 emit_insn (gen_frndintxf2 (op0, op1));
17101 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17106 (define_expand "rintxf2"
17107 [(use (match_operand:XF 0 "register_operand" ""))
17108 (use (match_operand:XF 1 "register_operand" ""))]
17109 "TARGET_USE_FANCY_MATH_387
17110 && flag_unsafe_math_optimizations && !optimize_size"
17112 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17116 (define_expand "roundsf2"
17117 [(match_operand:SF 0 "register_operand" "")
17118 (match_operand:SF 1 "nonimmediate_operand" "")]
17119 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17120 && !flag_trapping_math && !flag_rounding_math
17123 ix86_expand_round (operand0, operand1);
17127 (define_expand "rounddf2"
17128 [(match_operand:DF 0 "register_operand" "")
17129 (match_operand:DF 1 "nonimmediate_operand" "")]
17130 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17131 && !flag_trapping_math && !flag_rounding_math
17135 ix86_expand_round (operand0, operand1);
17137 ix86_expand_rounddf_32 (operand0, operand1);
17141 (define_insn_and_split "*fistdi2_1"
17142 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17143 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17145 "TARGET_USE_FANCY_MATH_387
17146 && !(reload_completed || reload_in_progress)"
17151 if (memory_operand (operands[0], VOIDmode))
17152 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17155 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17156 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17161 [(set_attr "type" "fpspc")
17162 (set_attr "mode" "DI")])
17164 (define_insn "fistdi2"
17165 [(set (match_operand:DI 0 "memory_operand" "=m")
17166 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17168 (clobber (match_scratch:XF 2 "=&1f"))]
17169 "TARGET_USE_FANCY_MATH_387"
17170 "* return output_fix_trunc (insn, operands, 0);"
17171 [(set_attr "type" "fpspc")
17172 (set_attr "mode" "DI")])
17174 (define_insn "fistdi2_with_temp"
17175 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17176 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17178 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17179 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17180 "TARGET_USE_FANCY_MATH_387"
17182 [(set_attr "type" "fpspc")
17183 (set_attr "mode" "DI")])
17186 [(set (match_operand:DI 0 "register_operand" "")
17187 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17189 (clobber (match_operand:DI 2 "memory_operand" ""))
17190 (clobber (match_scratch 3 ""))]
17192 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17193 (clobber (match_dup 3))])
17194 (set (match_dup 0) (match_dup 2))]
17198 [(set (match_operand:DI 0 "memory_operand" "")
17199 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17201 (clobber (match_operand:DI 2 "memory_operand" ""))
17202 (clobber (match_scratch 3 ""))]
17204 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17205 (clobber (match_dup 3))])]
17208 (define_insn_and_split "*fist<mode>2_1"
17209 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17210 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17212 "TARGET_USE_FANCY_MATH_387
17213 && !(reload_completed || reload_in_progress)"
17218 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17219 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17223 [(set_attr "type" "fpspc")
17224 (set_attr "mode" "<MODE>")])
17226 (define_insn "fist<mode>2"
17227 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17228 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17230 "TARGET_USE_FANCY_MATH_387"
17231 "* return output_fix_trunc (insn, operands, 0);"
17232 [(set_attr "type" "fpspc")
17233 (set_attr "mode" "<MODE>")])
17235 (define_insn "fist<mode>2_with_temp"
17236 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17237 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17239 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17240 "TARGET_USE_FANCY_MATH_387"
17242 [(set_attr "type" "fpspc")
17243 (set_attr "mode" "<MODE>")])
17246 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17247 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17249 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17251 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17253 (set (match_dup 0) (match_dup 2))]
17257 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17258 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17260 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17262 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17266 (define_expand "lrintxf<mode>2"
17267 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17268 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17270 "TARGET_USE_FANCY_MATH_387"
17273 (define_expand "lrint<mode>di2"
17274 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17275 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17276 UNSPEC_FIX_NOTRUNC))]
17277 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17280 (define_expand "lrint<mode>si2"
17281 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17282 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17283 UNSPEC_FIX_NOTRUNC))]
17284 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17287 (define_expand "lround<mode>di2"
17288 [(match_operand:DI 0 "nonimmediate_operand" "")
17289 (match_operand:SSEMODEF 1 "register_operand" "")]
17290 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17291 && !flag_trapping_math && !flag_rounding_math
17294 ix86_expand_lround (operand0, operand1);
17298 (define_expand "lround<mode>si2"
17299 [(match_operand:SI 0 "nonimmediate_operand" "")
17300 (match_operand:SSEMODEF 1 "register_operand" "")]
17301 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17302 && !flag_trapping_math && !flag_rounding_math
17305 ix86_expand_lround (operand0, operand1);
17309 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17310 (define_insn_and_split "frndintxf2_floor"
17311 [(set (match_operand:XF 0 "register_operand" "=f")
17312 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17313 UNSPEC_FRNDINT_FLOOR))
17314 (clobber (reg:CC FLAGS_REG))]
17315 "TARGET_USE_FANCY_MATH_387
17316 && flag_unsafe_math_optimizations
17317 && !(reload_completed || reload_in_progress)"
17322 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17324 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17325 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17327 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17328 operands[2], operands[3]));
17331 [(set_attr "type" "frndint")
17332 (set_attr "i387_cw" "floor")
17333 (set_attr "mode" "XF")])
17335 (define_insn "frndintxf2_floor_i387"
17336 [(set (match_operand:XF 0 "register_operand" "=f")
17337 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17338 UNSPEC_FRNDINT_FLOOR))
17339 (use (match_operand:HI 2 "memory_operand" "m"))
17340 (use (match_operand:HI 3 "memory_operand" "m"))]
17341 "TARGET_USE_FANCY_MATH_387
17342 && flag_unsafe_math_optimizations"
17343 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17344 [(set_attr "type" "frndint")
17345 (set_attr "i387_cw" "floor")
17346 (set_attr "mode" "XF")])
17348 (define_expand "floorxf2"
17349 [(use (match_operand:XF 0 "register_operand" ""))
17350 (use (match_operand:XF 1 "register_operand" ""))]
17351 "TARGET_USE_FANCY_MATH_387
17352 && flag_unsafe_math_optimizations && !optimize_size"
17354 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17358 (define_expand "floordf2"
17359 [(use (match_operand:DF 0 "register_operand" ""))
17360 (use (match_operand:DF 1 "register_operand" ""))]
17361 "((TARGET_USE_FANCY_MATH_387
17362 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17363 && flag_unsafe_math_optimizations)
17364 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17365 && !flag_trapping_math))
17368 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17369 && !flag_trapping_math)
17372 ix86_expand_floorceil (operand0, operand1, true);
17374 ix86_expand_floorceildf_32 (operand0, operand1, true);
17378 rtx op0 = gen_reg_rtx (XFmode);
17379 rtx op1 = gen_reg_rtx (XFmode);
17381 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17382 emit_insn (gen_frndintxf2_floor (op0, op1));
17384 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17389 (define_expand "floorsf2"
17390 [(use (match_operand:SF 0 "register_operand" ""))
17391 (use (match_operand:SF 1 "register_operand" ""))]
17392 "((TARGET_USE_FANCY_MATH_387
17393 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17394 && flag_unsafe_math_optimizations)
17395 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17396 && !flag_trapping_math))
17399 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17400 && !flag_trapping_math)
17401 ix86_expand_floorceil (operand0, operand1, true);
17404 rtx op0 = gen_reg_rtx (XFmode);
17405 rtx op1 = gen_reg_rtx (XFmode);
17407 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17408 emit_insn (gen_frndintxf2_floor (op0, op1));
17410 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17415 (define_insn_and_split "*fist<mode>2_floor_1"
17416 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17417 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17418 UNSPEC_FIST_FLOOR))
17419 (clobber (reg:CC FLAGS_REG))]
17420 "TARGET_USE_FANCY_MATH_387
17421 && flag_unsafe_math_optimizations
17422 && !(reload_completed || reload_in_progress)"
17427 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17429 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17430 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17431 if (memory_operand (operands[0], VOIDmode))
17432 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17433 operands[2], operands[3]));
17436 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17437 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17438 operands[2], operands[3],
17443 [(set_attr "type" "fistp")
17444 (set_attr "i387_cw" "floor")
17445 (set_attr "mode" "<MODE>")])
17447 (define_insn "fistdi2_floor"
17448 [(set (match_operand:DI 0 "memory_operand" "=m")
17449 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17450 UNSPEC_FIST_FLOOR))
17451 (use (match_operand:HI 2 "memory_operand" "m"))
17452 (use (match_operand:HI 3 "memory_operand" "m"))
17453 (clobber (match_scratch:XF 4 "=&1f"))]
17454 "TARGET_USE_FANCY_MATH_387
17455 && flag_unsafe_math_optimizations"
17456 "* return output_fix_trunc (insn, operands, 0);"
17457 [(set_attr "type" "fistp")
17458 (set_attr "i387_cw" "floor")
17459 (set_attr "mode" "DI")])
17461 (define_insn "fistdi2_floor_with_temp"
17462 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17463 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17464 UNSPEC_FIST_FLOOR))
17465 (use (match_operand:HI 2 "memory_operand" "m,m"))
17466 (use (match_operand:HI 3 "memory_operand" "m,m"))
17467 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17468 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17469 "TARGET_USE_FANCY_MATH_387
17470 && flag_unsafe_math_optimizations"
17472 [(set_attr "type" "fistp")
17473 (set_attr "i387_cw" "floor")
17474 (set_attr "mode" "DI")])
17477 [(set (match_operand:DI 0 "register_operand" "")
17478 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17479 UNSPEC_FIST_FLOOR))
17480 (use (match_operand:HI 2 "memory_operand" ""))
17481 (use (match_operand:HI 3 "memory_operand" ""))
17482 (clobber (match_operand:DI 4 "memory_operand" ""))
17483 (clobber (match_scratch 5 ""))]
17485 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17486 (use (match_dup 2))
17487 (use (match_dup 3))
17488 (clobber (match_dup 5))])
17489 (set (match_dup 0) (match_dup 4))]
17493 [(set (match_operand:DI 0 "memory_operand" "")
17494 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17495 UNSPEC_FIST_FLOOR))
17496 (use (match_operand:HI 2 "memory_operand" ""))
17497 (use (match_operand:HI 3 "memory_operand" ""))
17498 (clobber (match_operand:DI 4 "memory_operand" ""))
17499 (clobber (match_scratch 5 ""))]
17501 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17502 (use (match_dup 2))
17503 (use (match_dup 3))
17504 (clobber (match_dup 5))])]
17507 (define_insn "fist<mode>2_floor"
17508 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17509 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17510 UNSPEC_FIST_FLOOR))
17511 (use (match_operand:HI 2 "memory_operand" "m"))
17512 (use (match_operand:HI 3 "memory_operand" "m"))]
17513 "TARGET_USE_FANCY_MATH_387
17514 && flag_unsafe_math_optimizations"
17515 "* return output_fix_trunc (insn, operands, 0);"
17516 [(set_attr "type" "fistp")
17517 (set_attr "i387_cw" "floor")
17518 (set_attr "mode" "<MODE>")])
17520 (define_insn "fist<mode>2_floor_with_temp"
17521 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17522 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17523 UNSPEC_FIST_FLOOR))
17524 (use (match_operand:HI 2 "memory_operand" "m,m"))
17525 (use (match_operand:HI 3 "memory_operand" "m,m"))
17526 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17527 "TARGET_USE_FANCY_MATH_387
17528 && flag_unsafe_math_optimizations"
17530 [(set_attr "type" "fistp")
17531 (set_attr "i387_cw" "floor")
17532 (set_attr "mode" "<MODE>")])
17535 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17536 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17537 UNSPEC_FIST_FLOOR))
17538 (use (match_operand:HI 2 "memory_operand" ""))
17539 (use (match_operand:HI 3 "memory_operand" ""))
17540 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17542 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17543 UNSPEC_FIST_FLOOR))
17544 (use (match_dup 2))
17545 (use (match_dup 3))])
17546 (set (match_dup 0) (match_dup 4))]
17550 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17551 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17552 UNSPEC_FIST_FLOOR))
17553 (use (match_operand:HI 2 "memory_operand" ""))
17554 (use (match_operand:HI 3 "memory_operand" ""))
17555 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17557 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17558 UNSPEC_FIST_FLOOR))
17559 (use (match_dup 2))
17560 (use (match_dup 3))])]
17563 (define_expand "lfloorxf<mode>2"
17564 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17565 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17566 UNSPEC_FIST_FLOOR))
17567 (clobber (reg:CC FLAGS_REG))])]
17568 "TARGET_USE_FANCY_MATH_387
17569 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17570 && flag_unsafe_math_optimizations"
17573 (define_expand "lfloor<mode>di2"
17574 [(match_operand:DI 0 "nonimmediate_operand" "")
17575 (match_operand:SSEMODEF 1 "register_operand" "")]
17576 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17577 && !flag_trapping_math
17580 ix86_expand_lfloorceil (operand0, operand1, true);
17584 (define_expand "lfloor<mode>si2"
17585 [(match_operand:SI 0 "nonimmediate_operand" "")
17586 (match_operand:SSEMODEF 1 "register_operand" "")]
17587 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17588 && !flag_trapping_math
17589 && (!optimize_size || !TARGET_64BIT)"
17591 ix86_expand_lfloorceil (operand0, operand1, true);
17595 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17596 (define_insn_and_split "frndintxf2_ceil"
17597 [(set (match_operand:XF 0 "register_operand" "=f")
17598 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17599 UNSPEC_FRNDINT_CEIL))
17600 (clobber (reg:CC FLAGS_REG))]
17601 "TARGET_USE_FANCY_MATH_387
17602 && flag_unsafe_math_optimizations
17603 && !(reload_completed || reload_in_progress)"
17608 ix86_optimize_mode_switching[I387_CEIL] = 1;
17610 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17611 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17613 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17614 operands[2], operands[3]));
17617 [(set_attr "type" "frndint")
17618 (set_attr "i387_cw" "ceil")
17619 (set_attr "mode" "XF")])
17621 (define_insn "frndintxf2_ceil_i387"
17622 [(set (match_operand:XF 0 "register_operand" "=f")
17623 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17624 UNSPEC_FRNDINT_CEIL))
17625 (use (match_operand:HI 2 "memory_operand" "m"))
17626 (use (match_operand:HI 3 "memory_operand" "m"))]
17627 "TARGET_USE_FANCY_MATH_387
17628 && flag_unsafe_math_optimizations"
17629 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17630 [(set_attr "type" "frndint")
17631 (set_attr "i387_cw" "ceil")
17632 (set_attr "mode" "XF")])
17634 (define_expand "ceilxf2"
17635 [(use (match_operand:XF 0 "register_operand" ""))
17636 (use (match_operand:XF 1 "register_operand" ""))]
17637 "TARGET_USE_FANCY_MATH_387
17638 && flag_unsafe_math_optimizations && !optimize_size"
17640 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17644 (define_expand "ceildf2"
17645 [(use (match_operand:DF 0 "register_operand" ""))
17646 (use (match_operand:DF 1 "register_operand" ""))]
17647 "((TARGET_USE_FANCY_MATH_387
17648 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17649 && flag_unsafe_math_optimizations)
17650 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17651 && !flag_trapping_math))
17654 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17655 && !flag_trapping_math)
17658 ix86_expand_floorceil (operand0, operand1, false);
17660 ix86_expand_floorceildf_32 (operand0, operand1, false);
17664 rtx op0 = gen_reg_rtx (XFmode);
17665 rtx op1 = gen_reg_rtx (XFmode);
17667 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17668 emit_insn (gen_frndintxf2_ceil (op0, op1));
17670 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17675 (define_expand "ceilsf2"
17676 [(use (match_operand:SF 0 "register_operand" ""))
17677 (use (match_operand:SF 1 "register_operand" ""))]
17678 "((TARGET_USE_FANCY_MATH_387
17679 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17680 && flag_unsafe_math_optimizations)
17681 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17682 && !flag_trapping_math))
17685 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17686 && !flag_trapping_math)
17687 ix86_expand_floorceil (operand0, operand1, false);
17690 rtx op0 = gen_reg_rtx (XFmode);
17691 rtx op1 = gen_reg_rtx (XFmode);
17693 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17694 emit_insn (gen_frndintxf2_ceil (op0, op1));
17696 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17701 (define_insn_and_split "*fist<mode>2_ceil_1"
17702 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17703 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17705 (clobber (reg:CC FLAGS_REG))]
17706 "TARGET_USE_FANCY_MATH_387
17707 && flag_unsafe_math_optimizations
17708 && !(reload_completed || reload_in_progress)"
17713 ix86_optimize_mode_switching[I387_CEIL] = 1;
17715 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17716 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17717 if (memory_operand (operands[0], VOIDmode))
17718 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17719 operands[2], operands[3]));
17722 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17723 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17724 operands[2], operands[3],
17729 [(set_attr "type" "fistp")
17730 (set_attr "i387_cw" "ceil")
17731 (set_attr "mode" "<MODE>")])
17733 (define_insn "fistdi2_ceil"
17734 [(set (match_operand:DI 0 "memory_operand" "=m")
17735 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17737 (use (match_operand:HI 2 "memory_operand" "m"))
17738 (use (match_operand:HI 3 "memory_operand" "m"))
17739 (clobber (match_scratch:XF 4 "=&1f"))]
17740 "TARGET_USE_FANCY_MATH_387
17741 && flag_unsafe_math_optimizations"
17742 "* return output_fix_trunc (insn, operands, 0);"
17743 [(set_attr "type" "fistp")
17744 (set_attr "i387_cw" "ceil")
17745 (set_attr "mode" "DI")])
17747 (define_insn "fistdi2_ceil_with_temp"
17748 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17749 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17751 (use (match_operand:HI 2 "memory_operand" "m,m"))
17752 (use (match_operand:HI 3 "memory_operand" "m,m"))
17753 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17754 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17755 "TARGET_USE_FANCY_MATH_387
17756 && flag_unsafe_math_optimizations"
17758 [(set_attr "type" "fistp")
17759 (set_attr "i387_cw" "ceil")
17760 (set_attr "mode" "DI")])
17763 [(set (match_operand:DI 0 "register_operand" "")
17764 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17766 (use (match_operand:HI 2 "memory_operand" ""))
17767 (use (match_operand:HI 3 "memory_operand" ""))
17768 (clobber (match_operand:DI 4 "memory_operand" ""))
17769 (clobber (match_scratch 5 ""))]
17771 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17772 (use (match_dup 2))
17773 (use (match_dup 3))
17774 (clobber (match_dup 5))])
17775 (set (match_dup 0) (match_dup 4))]
17779 [(set (match_operand:DI 0 "memory_operand" "")
17780 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17782 (use (match_operand:HI 2 "memory_operand" ""))
17783 (use (match_operand:HI 3 "memory_operand" ""))
17784 (clobber (match_operand:DI 4 "memory_operand" ""))
17785 (clobber (match_scratch 5 ""))]
17787 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17788 (use (match_dup 2))
17789 (use (match_dup 3))
17790 (clobber (match_dup 5))])]
17793 (define_insn "fist<mode>2_ceil"
17794 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17795 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17797 (use (match_operand:HI 2 "memory_operand" "m"))
17798 (use (match_operand:HI 3 "memory_operand" "m"))]
17799 "TARGET_USE_FANCY_MATH_387
17800 && flag_unsafe_math_optimizations"
17801 "* return output_fix_trunc (insn, operands, 0);"
17802 [(set_attr "type" "fistp")
17803 (set_attr "i387_cw" "ceil")
17804 (set_attr "mode" "<MODE>")])
17806 (define_insn "fist<mode>2_ceil_with_temp"
17807 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17808 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17810 (use (match_operand:HI 2 "memory_operand" "m,m"))
17811 (use (match_operand:HI 3 "memory_operand" "m,m"))
17812 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17813 "TARGET_USE_FANCY_MATH_387
17814 && flag_unsafe_math_optimizations"
17816 [(set_attr "type" "fistp")
17817 (set_attr "i387_cw" "ceil")
17818 (set_attr "mode" "<MODE>")])
17821 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17822 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17824 (use (match_operand:HI 2 "memory_operand" ""))
17825 (use (match_operand:HI 3 "memory_operand" ""))
17826 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17828 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17830 (use (match_dup 2))
17831 (use (match_dup 3))])
17832 (set (match_dup 0) (match_dup 4))]
17836 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17837 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17839 (use (match_operand:HI 2 "memory_operand" ""))
17840 (use (match_operand:HI 3 "memory_operand" ""))
17841 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17843 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17845 (use (match_dup 2))
17846 (use (match_dup 3))])]
17849 (define_expand "lceilxf<mode>2"
17850 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17851 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17853 (clobber (reg:CC FLAGS_REG))])]
17854 "TARGET_USE_FANCY_MATH_387
17855 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17856 && flag_unsafe_math_optimizations"
17859 (define_expand "lceil<mode>di2"
17860 [(match_operand:DI 0 "nonimmediate_operand" "")
17861 (match_operand:SSEMODEF 1 "register_operand" "")]
17862 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17863 && !flag_trapping_math"
17865 ix86_expand_lfloorceil (operand0, operand1, false);
17869 (define_expand "lceil<mode>si2"
17870 [(match_operand:SI 0 "nonimmediate_operand" "")
17871 (match_operand:SSEMODEF 1 "register_operand" "")]
17872 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17873 && !flag_trapping_math"
17875 ix86_expand_lfloorceil (operand0, operand1, false);
17879 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17880 (define_insn_and_split "frndintxf2_trunc"
17881 [(set (match_operand:XF 0 "register_operand" "=f")
17882 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17883 UNSPEC_FRNDINT_TRUNC))
17884 (clobber (reg:CC FLAGS_REG))]
17885 "TARGET_USE_FANCY_MATH_387
17886 && flag_unsafe_math_optimizations
17887 && !(reload_completed || reload_in_progress)"
17892 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17894 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17895 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17897 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17898 operands[2], operands[3]));
17901 [(set_attr "type" "frndint")
17902 (set_attr "i387_cw" "trunc")
17903 (set_attr "mode" "XF")])
17905 (define_insn "frndintxf2_trunc_i387"
17906 [(set (match_operand:XF 0 "register_operand" "=f")
17907 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17908 UNSPEC_FRNDINT_TRUNC))
17909 (use (match_operand:HI 2 "memory_operand" "m"))
17910 (use (match_operand:HI 3 "memory_operand" "m"))]
17911 "TARGET_USE_FANCY_MATH_387
17912 && flag_unsafe_math_optimizations"
17913 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17914 [(set_attr "type" "frndint")
17915 (set_attr "i387_cw" "trunc")
17916 (set_attr "mode" "XF")])
17918 (define_expand "btruncxf2"
17919 [(use (match_operand:XF 0 "register_operand" ""))
17920 (use (match_operand:XF 1 "register_operand" ""))]
17921 "TARGET_USE_FANCY_MATH_387
17922 && flag_unsafe_math_optimizations && !optimize_size"
17924 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17928 (define_expand "btruncdf2"
17929 [(use (match_operand:DF 0 "register_operand" ""))
17930 (use (match_operand:DF 1 "register_operand" ""))]
17931 "((TARGET_USE_FANCY_MATH_387
17932 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17933 && flag_unsafe_math_optimizations)
17934 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17935 && !flag_trapping_math))
17938 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17939 && !flag_trapping_math)
17942 ix86_expand_trunc (operand0, operand1);
17944 ix86_expand_truncdf_32 (operand0, operand1);
17948 rtx op0 = gen_reg_rtx (XFmode);
17949 rtx op1 = gen_reg_rtx (XFmode);
17951 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17952 emit_insn (gen_frndintxf2_trunc (op0, op1));
17954 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17959 (define_expand "btruncsf2"
17960 [(use (match_operand:SF 0 "register_operand" ""))
17961 (use (match_operand:SF 1 "register_operand" ""))]
17962 "((TARGET_USE_FANCY_MATH_387
17963 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17964 && flag_unsafe_math_optimizations)
17965 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17966 && !flag_trapping_math))
17969 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17970 && !flag_trapping_math)
17971 ix86_expand_trunc (operand0, operand1);
17974 rtx op0 = gen_reg_rtx (XFmode);
17975 rtx op1 = gen_reg_rtx (XFmode);
17977 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17978 emit_insn (gen_frndintxf2_trunc (op0, op1));
17980 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17985 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17986 (define_insn_and_split "frndintxf2_mask_pm"
17987 [(set (match_operand:XF 0 "register_operand" "=f")
17988 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17989 UNSPEC_FRNDINT_MASK_PM))
17990 (clobber (reg:CC FLAGS_REG))]
17991 "TARGET_USE_FANCY_MATH_387
17992 && flag_unsafe_math_optimizations
17993 && !(reload_completed || reload_in_progress)"
17998 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18000 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18001 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18003 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18004 operands[2], operands[3]));
18007 [(set_attr "type" "frndint")
18008 (set_attr "i387_cw" "mask_pm")
18009 (set_attr "mode" "XF")])
18011 (define_insn "frndintxf2_mask_pm_i387"
18012 [(set (match_operand:XF 0 "register_operand" "=f")
18013 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18014 UNSPEC_FRNDINT_MASK_PM))
18015 (use (match_operand:HI 2 "memory_operand" "m"))
18016 (use (match_operand:HI 3 "memory_operand" "m"))]
18017 "TARGET_USE_FANCY_MATH_387
18018 && flag_unsafe_math_optimizations"
18019 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18020 [(set_attr "type" "frndint")
18021 (set_attr "i387_cw" "mask_pm")
18022 (set_attr "mode" "XF")])
18024 (define_expand "nearbyintxf2"
18025 [(use (match_operand:XF 0 "register_operand" ""))
18026 (use (match_operand:XF 1 "register_operand" ""))]
18027 "TARGET_USE_FANCY_MATH_387
18028 && flag_unsafe_math_optimizations"
18030 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18035 (define_expand "nearbyintdf2"
18036 [(use (match_operand:DF 0 "register_operand" ""))
18037 (use (match_operand:DF 1 "register_operand" ""))]
18038 "TARGET_USE_FANCY_MATH_387
18039 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18040 && flag_unsafe_math_optimizations"
18042 rtx op0 = gen_reg_rtx (XFmode);
18043 rtx op1 = gen_reg_rtx (XFmode);
18045 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18046 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18048 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18052 (define_expand "nearbyintsf2"
18053 [(use (match_operand:SF 0 "register_operand" ""))
18054 (use (match_operand:SF 1 "register_operand" ""))]
18055 "TARGET_USE_FANCY_MATH_387
18056 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18057 && flag_unsafe_math_optimizations"
18059 rtx op0 = gen_reg_rtx (XFmode);
18060 rtx op1 = gen_reg_rtx (XFmode);
18062 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18063 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18065 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18069 (define_insn "fxam<mode>2_i387"
18070 [(set (match_operand:HI 0 "register_operand" "=a")
18072 [(match_operand:X87MODEF 1 "register_operand" "f")]
18074 "TARGET_USE_FANCY_MATH_387"
18075 "fxam\n\tfnstsw\t%0"
18076 [(set_attr "type" "multi")
18077 (set_attr "unit" "i387")
18078 (set_attr "mode" "<MODE>")])
18080 (define_expand "isinf<mode>2"
18081 [(use (match_operand:SI 0 "register_operand" ""))
18082 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18083 "TARGET_USE_FANCY_MATH_387
18084 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18085 || TARGET_MIX_SSE_I387)"
18087 rtx mask = GEN_INT (0x45);
18088 rtx val = GEN_INT (0x05);
18092 rtx scratch = gen_reg_rtx (HImode);
18093 rtx res = gen_reg_rtx (QImode);
18095 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18096 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18097 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18098 cond = gen_rtx_fmt_ee (EQ, QImode,
18099 gen_rtx_REG (CCmode, FLAGS_REG),
18101 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18102 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18107 ;; Block operation instructions
18109 (define_expand "movmemsi"
18110 [(use (match_operand:BLK 0 "memory_operand" ""))
18111 (use (match_operand:BLK 1 "memory_operand" ""))
18112 (use (match_operand:SI 2 "nonmemory_operand" ""))
18113 (use (match_operand:SI 3 "const_int_operand" ""))
18114 (use (match_operand:SI 4 "const_int_operand" ""))
18115 (use (match_operand:SI 5 "const_int_operand" ""))]
18118 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18119 operands[4], operands[5]))
18125 (define_expand "movmemdi"
18126 [(use (match_operand:BLK 0 "memory_operand" ""))
18127 (use (match_operand:BLK 1 "memory_operand" ""))
18128 (use (match_operand:DI 2 "nonmemory_operand" ""))
18129 (use (match_operand:DI 3 "const_int_operand" ""))
18130 (use (match_operand:SI 4 "const_int_operand" ""))
18131 (use (match_operand:SI 5 "const_int_operand" ""))]
18134 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18135 operands[4], operands[5]))
18141 ;; Most CPUs don't like single string operations
18142 ;; Handle this case here to simplify previous expander.
18144 (define_expand "strmov"
18145 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18146 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18147 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18148 (clobber (reg:CC FLAGS_REG))])
18149 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18150 (clobber (reg:CC FLAGS_REG))])]
18153 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18155 /* If .md ever supports :P for Pmode, these can be directly
18156 in the pattern above. */
18157 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18158 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18160 if (TARGET_SINGLE_STRINGOP || optimize_size)
18162 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18163 operands[2], operands[3],
18164 operands[5], operands[6]));
18168 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18171 (define_expand "strmov_singleop"
18172 [(parallel [(set (match_operand 1 "memory_operand" "")
18173 (match_operand 3 "memory_operand" ""))
18174 (set (match_operand 0 "register_operand" "")
18175 (match_operand 4 "" ""))
18176 (set (match_operand 2 "register_operand" "")
18177 (match_operand 5 "" ""))])]
18178 "TARGET_SINGLE_STRINGOP || optimize_size"
18181 (define_insn "*strmovdi_rex_1"
18182 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18183 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18184 (set (match_operand:DI 0 "register_operand" "=D")
18185 (plus:DI (match_dup 2)
18187 (set (match_operand:DI 1 "register_operand" "=S")
18188 (plus:DI (match_dup 3)
18190 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18192 [(set_attr "type" "str")
18193 (set_attr "mode" "DI")
18194 (set_attr "memory" "both")])
18196 (define_insn "*strmovsi_1"
18197 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18198 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18199 (set (match_operand:SI 0 "register_operand" "=D")
18200 (plus:SI (match_dup 2)
18202 (set (match_operand:SI 1 "register_operand" "=S")
18203 (plus:SI (match_dup 3)
18205 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18207 [(set_attr "type" "str")
18208 (set_attr "mode" "SI")
18209 (set_attr "memory" "both")])
18211 (define_insn "*strmovsi_rex_1"
18212 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18213 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18214 (set (match_operand:DI 0 "register_operand" "=D")
18215 (plus:DI (match_dup 2)
18217 (set (match_operand:DI 1 "register_operand" "=S")
18218 (plus:DI (match_dup 3)
18220 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18222 [(set_attr "type" "str")
18223 (set_attr "mode" "SI")
18224 (set_attr "memory" "both")])
18226 (define_insn "*strmovhi_1"
18227 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18228 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18229 (set (match_operand:SI 0 "register_operand" "=D")
18230 (plus:SI (match_dup 2)
18232 (set (match_operand:SI 1 "register_operand" "=S")
18233 (plus:SI (match_dup 3)
18235 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18237 [(set_attr "type" "str")
18238 (set_attr "memory" "both")
18239 (set_attr "mode" "HI")])
18241 (define_insn "*strmovhi_rex_1"
18242 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18243 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18244 (set (match_operand:DI 0 "register_operand" "=D")
18245 (plus:DI (match_dup 2)
18247 (set (match_operand:DI 1 "register_operand" "=S")
18248 (plus:DI (match_dup 3)
18250 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18252 [(set_attr "type" "str")
18253 (set_attr "memory" "both")
18254 (set_attr "mode" "HI")])
18256 (define_insn "*strmovqi_1"
18257 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18258 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18259 (set (match_operand:SI 0 "register_operand" "=D")
18260 (plus:SI (match_dup 2)
18262 (set (match_operand:SI 1 "register_operand" "=S")
18263 (plus:SI (match_dup 3)
18265 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18267 [(set_attr "type" "str")
18268 (set_attr "memory" "both")
18269 (set_attr "mode" "QI")])
18271 (define_insn "*strmovqi_rex_1"
18272 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18273 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18274 (set (match_operand:DI 0 "register_operand" "=D")
18275 (plus:DI (match_dup 2)
18277 (set (match_operand:DI 1 "register_operand" "=S")
18278 (plus:DI (match_dup 3)
18280 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18282 [(set_attr "type" "str")
18283 (set_attr "memory" "both")
18284 (set_attr "mode" "QI")])
18286 (define_expand "rep_mov"
18287 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18288 (set (match_operand 0 "register_operand" "")
18289 (match_operand 5 "" ""))
18290 (set (match_operand 2 "register_operand" "")
18291 (match_operand 6 "" ""))
18292 (set (match_operand 1 "memory_operand" "")
18293 (match_operand 3 "memory_operand" ""))
18294 (use (match_dup 4))])]
18298 (define_insn "*rep_movdi_rex64"
18299 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18300 (set (match_operand:DI 0 "register_operand" "=D")
18301 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18303 (match_operand:DI 3 "register_operand" "0")))
18304 (set (match_operand:DI 1 "register_operand" "=S")
18305 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18306 (match_operand:DI 4 "register_operand" "1")))
18307 (set (mem:BLK (match_dup 3))
18308 (mem:BLK (match_dup 4)))
18309 (use (match_dup 5))]
18311 "{rep\;movsq|rep movsq}"
18312 [(set_attr "type" "str")
18313 (set_attr "prefix_rep" "1")
18314 (set_attr "memory" "both")
18315 (set_attr "mode" "DI")])
18317 (define_insn "*rep_movsi"
18318 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18319 (set (match_operand:SI 0 "register_operand" "=D")
18320 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18322 (match_operand:SI 3 "register_operand" "0")))
18323 (set (match_operand:SI 1 "register_operand" "=S")
18324 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18325 (match_operand:SI 4 "register_operand" "1")))
18326 (set (mem:BLK (match_dup 3))
18327 (mem:BLK (match_dup 4)))
18328 (use (match_dup 5))]
18330 "{rep\;movsl|rep movsd}"
18331 [(set_attr "type" "str")
18332 (set_attr "prefix_rep" "1")
18333 (set_attr "memory" "both")
18334 (set_attr "mode" "SI")])
18336 (define_insn "*rep_movsi_rex64"
18337 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18338 (set (match_operand:DI 0 "register_operand" "=D")
18339 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18341 (match_operand:DI 3 "register_operand" "0")))
18342 (set (match_operand:DI 1 "register_operand" "=S")
18343 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18344 (match_operand:DI 4 "register_operand" "1")))
18345 (set (mem:BLK (match_dup 3))
18346 (mem:BLK (match_dup 4)))
18347 (use (match_dup 5))]
18349 "{rep\;movsl|rep movsd}"
18350 [(set_attr "type" "str")
18351 (set_attr "prefix_rep" "1")
18352 (set_attr "memory" "both")
18353 (set_attr "mode" "SI")])
18355 (define_insn "*rep_movqi"
18356 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18357 (set (match_operand:SI 0 "register_operand" "=D")
18358 (plus:SI (match_operand:SI 3 "register_operand" "0")
18359 (match_operand:SI 5 "register_operand" "2")))
18360 (set (match_operand:SI 1 "register_operand" "=S")
18361 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18362 (set (mem:BLK (match_dup 3))
18363 (mem:BLK (match_dup 4)))
18364 (use (match_dup 5))]
18366 "{rep\;movsb|rep movsb}"
18367 [(set_attr "type" "str")
18368 (set_attr "prefix_rep" "1")
18369 (set_attr "memory" "both")
18370 (set_attr "mode" "SI")])
18372 (define_insn "*rep_movqi_rex64"
18373 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18374 (set (match_operand:DI 0 "register_operand" "=D")
18375 (plus:DI (match_operand:DI 3 "register_operand" "0")
18376 (match_operand:DI 5 "register_operand" "2")))
18377 (set (match_operand:DI 1 "register_operand" "=S")
18378 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18379 (set (mem:BLK (match_dup 3))
18380 (mem:BLK (match_dup 4)))
18381 (use (match_dup 5))]
18383 "{rep\;movsb|rep movsb}"
18384 [(set_attr "type" "str")
18385 (set_attr "prefix_rep" "1")
18386 (set_attr "memory" "both")
18387 (set_attr "mode" "SI")])
18389 (define_expand "setmemsi"
18390 [(use (match_operand:BLK 0 "memory_operand" ""))
18391 (use (match_operand:SI 1 "nonmemory_operand" ""))
18392 (use (match_operand 2 "const_int_operand" ""))
18393 (use (match_operand 3 "const_int_operand" ""))
18394 (use (match_operand:SI 4 "const_int_operand" ""))
18395 (use (match_operand:SI 5 "const_int_operand" ""))]
18398 if (ix86_expand_setmem (operands[0], operands[1],
18399 operands[2], operands[3],
18400 operands[4], operands[5]))
18406 (define_expand "setmemdi"
18407 [(use (match_operand:BLK 0 "memory_operand" ""))
18408 (use (match_operand:DI 1 "nonmemory_operand" ""))
18409 (use (match_operand 2 "const_int_operand" ""))
18410 (use (match_operand 3 "const_int_operand" ""))
18411 (use (match_operand 4 "const_int_operand" ""))
18412 (use (match_operand 5 "const_int_operand" ""))]
18415 if (ix86_expand_setmem (operands[0], operands[1],
18416 operands[2], operands[3],
18417 operands[4], operands[5]))
18423 ;; Most CPUs don't like single string operations
18424 ;; Handle this case here to simplify previous expander.
18426 (define_expand "strset"
18427 [(set (match_operand 1 "memory_operand" "")
18428 (match_operand 2 "register_operand" ""))
18429 (parallel [(set (match_operand 0 "register_operand" "")
18431 (clobber (reg:CC FLAGS_REG))])]
18434 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18435 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18437 /* If .md ever supports :P for Pmode, this can be directly
18438 in the pattern above. */
18439 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18440 GEN_INT (GET_MODE_SIZE (GET_MODE
18442 if (TARGET_SINGLE_STRINGOP || optimize_size)
18444 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18450 (define_expand "strset_singleop"
18451 [(parallel [(set (match_operand 1 "memory_operand" "")
18452 (match_operand 2 "register_operand" ""))
18453 (set (match_operand 0 "register_operand" "")
18454 (match_operand 3 "" ""))])]
18455 "TARGET_SINGLE_STRINGOP || optimize_size"
18458 (define_insn "*strsetdi_rex_1"
18459 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18460 (match_operand:DI 2 "register_operand" "a"))
18461 (set (match_operand:DI 0 "register_operand" "=D")
18462 (plus:DI (match_dup 1)
18464 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18466 [(set_attr "type" "str")
18467 (set_attr "memory" "store")
18468 (set_attr "mode" "DI")])
18470 (define_insn "*strsetsi_1"
18471 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18472 (match_operand:SI 2 "register_operand" "a"))
18473 (set (match_operand:SI 0 "register_operand" "=D")
18474 (plus:SI (match_dup 1)
18476 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18478 [(set_attr "type" "str")
18479 (set_attr "memory" "store")
18480 (set_attr "mode" "SI")])
18482 (define_insn "*strsetsi_rex_1"
18483 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18484 (match_operand:SI 2 "register_operand" "a"))
18485 (set (match_operand:DI 0 "register_operand" "=D")
18486 (plus:DI (match_dup 1)
18488 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18490 [(set_attr "type" "str")
18491 (set_attr "memory" "store")
18492 (set_attr "mode" "SI")])
18494 (define_insn "*strsethi_1"
18495 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18496 (match_operand:HI 2 "register_operand" "a"))
18497 (set (match_operand:SI 0 "register_operand" "=D")
18498 (plus:SI (match_dup 1)
18500 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18502 [(set_attr "type" "str")
18503 (set_attr "memory" "store")
18504 (set_attr "mode" "HI")])
18506 (define_insn "*strsethi_rex_1"
18507 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18508 (match_operand:HI 2 "register_operand" "a"))
18509 (set (match_operand:DI 0 "register_operand" "=D")
18510 (plus:DI (match_dup 1)
18512 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18514 [(set_attr "type" "str")
18515 (set_attr "memory" "store")
18516 (set_attr "mode" "HI")])
18518 (define_insn "*strsetqi_1"
18519 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18520 (match_operand:QI 2 "register_operand" "a"))
18521 (set (match_operand:SI 0 "register_operand" "=D")
18522 (plus:SI (match_dup 1)
18524 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18526 [(set_attr "type" "str")
18527 (set_attr "memory" "store")
18528 (set_attr "mode" "QI")])
18530 (define_insn "*strsetqi_rex_1"
18531 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18532 (match_operand:QI 2 "register_operand" "a"))
18533 (set (match_operand:DI 0 "register_operand" "=D")
18534 (plus:DI (match_dup 1)
18536 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18538 [(set_attr "type" "str")
18539 (set_attr "memory" "store")
18540 (set_attr "mode" "QI")])
18542 (define_expand "rep_stos"
18543 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18544 (set (match_operand 0 "register_operand" "")
18545 (match_operand 4 "" ""))
18546 (set (match_operand 2 "memory_operand" "") (const_int 0))
18547 (use (match_operand 3 "register_operand" ""))
18548 (use (match_dup 1))])]
18552 (define_insn "*rep_stosdi_rex64"
18553 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18554 (set (match_operand:DI 0 "register_operand" "=D")
18555 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18557 (match_operand:DI 3 "register_operand" "0")))
18558 (set (mem:BLK (match_dup 3))
18560 (use (match_operand:DI 2 "register_operand" "a"))
18561 (use (match_dup 4))]
18563 "{rep\;stosq|rep stosq}"
18564 [(set_attr "type" "str")
18565 (set_attr "prefix_rep" "1")
18566 (set_attr "memory" "store")
18567 (set_attr "mode" "DI")])
18569 (define_insn "*rep_stossi"
18570 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18571 (set (match_operand:SI 0 "register_operand" "=D")
18572 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18574 (match_operand:SI 3 "register_operand" "0")))
18575 (set (mem:BLK (match_dup 3))
18577 (use (match_operand:SI 2 "register_operand" "a"))
18578 (use (match_dup 4))]
18580 "{rep\;stosl|rep stosd}"
18581 [(set_attr "type" "str")
18582 (set_attr "prefix_rep" "1")
18583 (set_attr "memory" "store")
18584 (set_attr "mode" "SI")])
18586 (define_insn "*rep_stossi_rex64"
18587 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18588 (set (match_operand:DI 0 "register_operand" "=D")
18589 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18591 (match_operand:DI 3 "register_operand" "0")))
18592 (set (mem:BLK (match_dup 3))
18594 (use (match_operand:SI 2 "register_operand" "a"))
18595 (use (match_dup 4))]
18597 "{rep\;stosl|rep stosd}"
18598 [(set_attr "type" "str")
18599 (set_attr "prefix_rep" "1")
18600 (set_attr "memory" "store")
18601 (set_attr "mode" "SI")])
18603 (define_insn "*rep_stosqi"
18604 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18605 (set (match_operand:SI 0 "register_operand" "=D")
18606 (plus:SI (match_operand:SI 3 "register_operand" "0")
18607 (match_operand:SI 4 "register_operand" "1")))
18608 (set (mem:BLK (match_dup 3))
18610 (use (match_operand:QI 2 "register_operand" "a"))
18611 (use (match_dup 4))]
18613 "{rep\;stosb|rep stosb}"
18614 [(set_attr "type" "str")
18615 (set_attr "prefix_rep" "1")
18616 (set_attr "memory" "store")
18617 (set_attr "mode" "QI")])
18619 (define_insn "*rep_stosqi_rex64"
18620 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18621 (set (match_operand:DI 0 "register_operand" "=D")
18622 (plus:DI (match_operand:DI 3 "register_operand" "0")
18623 (match_operand:DI 4 "register_operand" "1")))
18624 (set (mem:BLK (match_dup 3))
18626 (use (match_operand:QI 2 "register_operand" "a"))
18627 (use (match_dup 4))]
18629 "{rep\;stosb|rep stosb}"
18630 [(set_attr "type" "str")
18631 (set_attr "prefix_rep" "1")
18632 (set_attr "memory" "store")
18633 (set_attr "mode" "QI")])
18635 (define_expand "cmpstrnsi"
18636 [(set (match_operand:SI 0 "register_operand" "")
18637 (compare:SI (match_operand:BLK 1 "general_operand" "")
18638 (match_operand:BLK 2 "general_operand" "")))
18639 (use (match_operand 3 "general_operand" ""))
18640 (use (match_operand 4 "immediate_operand" ""))]
18641 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18643 rtx addr1, addr2, out, outlow, count, countreg, align;
18645 /* Can't use this if the user has appropriated esi or edi. */
18646 if (global_regs[4] || global_regs[5])
18651 out = gen_reg_rtx (SImode);
18653 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18654 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18655 if (addr1 != XEXP (operands[1], 0))
18656 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18657 if (addr2 != XEXP (operands[2], 0))
18658 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18660 count = operands[3];
18661 countreg = ix86_zero_extend_to_Pmode (count);
18663 /* %%% Iff we are testing strict equality, we can use known alignment
18664 to good advantage. This may be possible with combine, particularly
18665 once cc0 is dead. */
18666 align = operands[4];
18668 if (CONST_INT_P (count))
18670 if (INTVAL (count) == 0)
18672 emit_move_insn (operands[0], const0_rtx);
18675 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18676 operands[1], operands[2]));
18681 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18683 emit_insn (gen_cmpsi_1 (countreg, countreg));
18684 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18685 operands[1], operands[2]));
18688 outlow = gen_lowpart (QImode, out);
18689 emit_insn (gen_cmpintqi (outlow));
18690 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18692 if (operands[0] != out)
18693 emit_move_insn (operands[0], out);
18698 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18700 (define_expand "cmpintqi"
18701 [(set (match_dup 1)
18702 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18704 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18705 (parallel [(set (match_operand:QI 0 "register_operand" "")
18706 (minus:QI (match_dup 1)
18708 (clobber (reg:CC FLAGS_REG))])]
18710 "operands[1] = gen_reg_rtx (QImode);
18711 operands[2] = gen_reg_rtx (QImode);")
18713 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18714 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18716 (define_expand "cmpstrnqi_nz_1"
18717 [(parallel [(set (reg:CC FLAGS_REG)
18718 (compare:CC (match_operand 4 "memory_operand" "")
18719 (match_operand 5 "memory_operand" "")))
18720 (use (match_operand 2 "register_operand" ""))
18721 (use (match_operand:SI 3 "immediate_operand" ""))
18722 (clobber (match_operand 0 "register_operand" ""))
18723 (clobber (match_operand 1 "register_operand" ""))
18724 (clobber (match_dup 2))])]
18728 (define_insn "*cmpstrnqi_nz_1"
18729 [(set (reg:CC FLAGS_REG)
18730 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18731 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18732 (use (match_operand:SI 6 "register_operand" "2"))
18733 (use (match_operand:SI 3 "immediate_operand" "i"))
18734 (clobber (match_operand:SI 0 "register_operand" "=S"))
18735 (clobber (match_operand:SI 1 "register_operand" "=D"))
18736 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18739 [(set_attr "type" "str")
18740 (set_attr "mode" "QI")
18741 (set_attr "prefix_rep" "1")])
18743 (define_insn "*cmpstrnqi_nz_rex_1"
18744 [(set (reg:CC FLAGS_REG)
18745 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18746 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18747 (use (match_operand:DI 6 "register_operand" "2"))
18748 (use (match_operand:SI 3 "immediate_operand" "i"))
18749 (clobber (match_operand:DI 0 "register_operand" "=S"))
18750 (clobber (match_operand:DI 1 "register_operand" "=D"))
18751 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18754 [(set_attr "type" "str")
18755 (set_attr "mode" "QI")
18756 (set_attr "prefix_rep" "1")])
18758 ;; The same, but the count is not known to not be zero.
18760 (define_expand "cmpstrnqi_1"
18761 [(parallel [(set (reg:CC FLAGS_REG)
18762 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18764 (compare:CC (match_operand 4 "memory_operand" "")
18765 (match_operand 5 "memory_operand" ""))
18767 (use (match_operand:SI 3 "immediate_operand" ""))
18768 (use (reg:CC FLAGS_REG))
18769 (clobber (match_operand 0 "register_operand" ""))
18770 (clobber (match_operand 1 "register_operand" ""))
18771 (clobber (match_dup 2))])]
18775 (define_insn "*cmpstrnqi_1"
18776 [(set (reg:CC FLAGS_REG)
18777 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18779 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18780 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18782 (use (match_operand:SI 3 "immediate_operand" "i"))
18783 (use (reg:CC FLAGS_REG))
18784 (clobber (match_operand:SI 0 "register_operand" "=S"))
18785 (clobber (match_operand:SI 1 "register_operand" "=D"))
18786 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18789 [(set_attr "type" "str")
18790 (set_attr "mode" "QI")
18791 (set_attr "prefix_rep" "1")])
18793 (define_insn "*cmpstrnqi_rex_1"
18794 [(set (reg:CC FLAGS_REG)
18795 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18797 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18798 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18800 (use (match_operand:SI 3 "immediate_operand" "i"))
18801 (use (reg:CC FLAGS_REG))
18802 (clobber (match_operand:DI 0 "register_operand" "=S"))
18803 (clobber (match_operand:DI 1 "register_operand" "=D"))
18804 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18807 [(set_attr "type" "str")
18808 (set_attr "mode" "QI")
18809 (set_attr "prefix_rep" "1")])
18811 (define_expand "strlensi"
18812 [(set (match_operand:SI 0 "register_operand" "")
18813 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18814 (match_operand:QI 2 "immediate_operand" "")
18815 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18818 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18824 (define_expand "strlendi"
18825 [(set (match_operand:DI 0 "register_operand" "")
18826 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18827 (match_operand:QI 2 "immediate_operand" "")
18828 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18831 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18837 (define_expand "strlenqi_1"
18838 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18839 (clobber (match_operand 1 "register_operand" ""))
18840 (clobber (reg:CC FLAGS_REG))])]
18844 (define_insn "*strlenqi_1"
18845 [(set (match_operand:SI 0 "register_operand" "=&c")
18846 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18847 (match_operand:QI 2 "register_operand" "a")
18848 (match_operand:SI 3 "immediate_operand" "i")
18849 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18850 (clobber (match_operand:SI 1 "register_operand" "=D"))
18851 (clobber (reg:CC FLAGS_REG))]
18854 [(set_attr "type" "str")
18855 (set_attr "mode" "QI")
18856 (set_attr "prefix_rep" "1")])
18858 (define_insn "*strlenqi_rex_1"
18859 [(set (match_operand:DI 0 "register_operand" "=&c")
18860 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18861 (match_operand:QI 2 "register_operand" "a")
18862 (match_operand:DI 3 "immediate_operand" "i")
18863 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18864 (clobber (match_operand:DI 1 "register_operand" "=D"))
18865 (clobber (reg:CC FLAGS_REG))]
18868 [(set_attr "type" "str")
18869 (set_attr "mode" "QI")
18870 (set_attr "prefix_rep" "1")])
18872 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18873 ;; handled in combine, but it is not currently up to the task.
18874 ;; When used for their truth value, the cmpstrn* expanders generate
18883 ;; The intermediate three instructions are unnecessary.
18885 ;; This one handles cmpstrn*_nz_1...
18888 (set (reg:CC FLAGS_REG)
18889 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18890 (mem:BLK (match_operand 5 "register_operand" ""))))
18891 (use (match_operand 6 "register_operand" ""))
18892 (use (match_operand:SI 3 "immediate_operand" ""))
18893 (clobber (match_operand 0 "register_operand" ""))
18894 (clobber (match_operand 1 "register_operand" ""))
18895 (clobber (match_operand 2 "register_operand" ""))])
18896 (set (match_operand:QI 7 "register_operand" "")
18897 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18898 (set (match_operand:QI 8 "register_operand" "")
18899 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18900 (set (reg FLAGS_REG)
18901 (compare (match_dup 7) (match_dup 8)))
18903 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18905 (set (reg:CC FLAGS_REG)
18906 (compare:CC (mem:BLK (match_dup 4))
18907 (mem:BLK (match_dup 5))))
18908 (use (match_dup 6))
18909 (use (match_dup 3))
18910 (clobber (match_dup 0))
18911 (clobber (match_dup 1))
18912 (clobber (match_dup 2))])]
18915 ;; ...and this one handles cmpstrn*_1.
18918 (set (reg:CC FLAGS_REG)
18919 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18921 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18922 (mem:BLK (match_operand 5 "register_operand" "")))
18924 (use (match_operand:SI 3 "immediate_operand" ""))
18925 (use (reg:CC FLAGS_REG))
18926 (clobber (match_operand 0 "register_operand" ""))
18927 (clobber (match_operand 1 "register_operand" ""))
18928 (clobber (match_operand 2 "register_operand" ""))])
18929 (set (match_operand:QI 7 "register_operand" "")
18930 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18931 (set (match_operand:QI 8 "register_operand" "")
18932 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18933 (set (reg FLAGS_REG)
18934 (compare (match_dup 7) (match_dup 8)))
18936 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18938 (set (reg:CC FLAGS_REG)
18939 (if_then_else:CC (ne (match_dup 6)
18941 (compare:CC (mem:BLK (match_dup 4))
18942 (mem:BLK (match_dup 5)))
18944 (use (match_dup 3))
18945 (use (reg:CC FLAGS_REG))
18946 (clobber (match_dup 0))
18947 (clobber (match_dup 1))
18948 (clobber (match_dup 2))])]
18953 ;; Conditional move instructions.
18955 (define_expand "movdicc"
18956 [(set (match_operand:DI 0 "register_operand" "")
18957 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18958 (match_operand:DI 2 "general_operand" "")
18959 (match_operand:DI 3 "general_operand" "")))]
18961 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18963 (define_insn "x86_movdicc_0_m1_rex64"
18964 [(set (match_operand:DI 0 "register_operand" "=r")
18965 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18968 (clobber (reg:CC FLAGS_REG))]
18971 ; Since we don't have the proper number of operands for an alu insn,
18972 ; fill in all the blanks.
18973 [(set_attr "type" "alu")
18974 (set_attr "pent_pair" "pu")
18975 (set_attr "memory" "none")
18976 (set_attr "imm_disp" "false")
18977 (set_attr "mode" "DI")
18978 (set_attr "length_immediate" "0")])
18980 (define_insn "*movdicc_c_rex64"
18981 [(set (match_operand:DI 0 "register_operand" "=r,r")
18982 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18983 [(reg FLAGS_REG) (const_int 0)])
18984 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18985 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18986 "TARGET_64BIT && TARGET_CMOVE
18987 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18989 cmov%O2%C1\t{%2, %0|%0, %2}
18990 cmov%O2%c1\t{%3, %0|%0, %3}"
18991 [(set_attr "type" "icmov")
18992 (set_attr "mode" "DI")])
18994 (define_expand "movsicc"
18995 [(set (match_operand:SI 0 "register_operand" "")
18996 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18997 (match_operand:SI 2 "general_operand" "")
18998 (match_operand:SI 3 "general_operand" "")))]
19000 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19002 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19003 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19004 ;; So just document what we're doing explicitly.
19006 (define_insn "x86_movsicc_0_m1"
19007 [(set (match_operand:SI 0 "register_operand" "=r")
19008 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19011 (clobber (reg:CC FLAGS_REG))]
19014 ; Since we don't have the proper number of operands for an alu insn,
19015 ; fill in all the blanks.
19016 [(set_attr "type" "alu")
19017 (set_attr "pent_pair" "pu")
19018 (set_attr "memory" "none")
19019 (set_attr "imm_disp" "false")
19020 (set_attr "mode" "SI")
19021 (set_attr "length_immediate" "0")])
19023 (define_insn "*movsicc_noc"
19024 [(set (match_operand:SI 0 "register_operand" "=r,r")
19025 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19026 [(reg FLAGS_REG) (const_int 0)])
19027 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19028 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19030 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19032 cmov%O2%C1\t{%2, %0|%0, %2}
19033 cmov%O2%c1\t{%3, %0|%0, %3}"
19034 [(set_attr "type" "icmov")
19035 (set_attr "mode" "SI")])
19037 (define_expand "movhicc"
19038 [(set (match_operand:HI 0 "register_operand" "")
19039 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19040 (match_operand:HI 2 "general_operand" "")
19041 (match_operand:HI 3 "general_operand" "")))]
19042 "TARGET_HIMODE_MATH"
19043 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19045 (define_insn "*movhicc_noc"
19046 [(set (match_operand:HI 0 "register_operand" "=r,r")
19047 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19048 [(reg FLAGS_REG) (const_int 0)])
19049 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19050 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19052 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19054 cmov%O2%C1\t{%2, %0|%0, %2}
19055 cmov%O2%c1\t{%3, %0|%0, %3}"
19056 [(set_attr "type" "icmov")
19057 (set_attr "mode" "HI")])
19059 (define_expand "movqicc"
19060 [(set (match_operand:QI 0 "register_operand" "")
19061 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19062 (match_operand:QI 2 "general_operand" "")
19063 (match_operand:QI 3 "general_operand" "")))]
19064 "TARGET_QIMODE_MATH"
19065 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19067 (define_insn_and_split "*movqicc_noc"
19068 [(set (match_operand:QI 0 "register_operand" "=r,r")
19069 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19070 [(match_operand 4 "flags_reg_operand" "")
19072 (match_operand:QI 2 "register_operand" "r,0")
19073 (match_operand:QI 3 "register_operand" "0,r")))]
19074 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19076 "&& reload_completed"
19077 [(set (match_dup 0)
19078 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19081 "operands[0] = gen_lowpart (SImode, operands[0]);
19082 operands[2] = gen_lowpart (SImode, operands[2]);
19083 operands[3] = gen_lowpart (SImode, operands[3]);"
19084 [(set_attr "type" "icmov")
19085 (set_attr "mode" "SI")])
19087 (define_expand "movsfcc"
19088 [(set (match_operand:SF 0 "register_operand" "")
19089 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19090 (match_operand:SF 2 "register_operand" "")
19091 (match_operand:SF 3 "register_operand" "")))]
19092 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19093 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19095 (define_insn "*movsfcc_1_387"
19096 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19097 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19098 [(reg FLAGS_REG) (const_int 0)])
19099 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19100 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19101 "TARGET_80387 && TARGET_CMOVE
19102 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19104 fcmov%F1\t{%2, %0|%0, %2}
19105 fcmov%f1\t{%3, %0|%0, %3}
19106 cmov%O2%C1\t{%2, %0|%0, %2}
19107 cmov%O2%c1\t{%3, %0|%0, %3}"
19108 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19109 (set_attr "mode" "SF,SF,SI,SI")])
19111 (define_expand "movdfcc"
19112 [(set (match_operand:DF 0 "register_operand" "")
19113 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19114 (match_operand:DF 2 "register_operand" "")
19115 (match_operand:DF 3 "register_operand" "")))]
19116 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19117 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19119 (define_insn "*movdfcc_1"
19120 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19121 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19122 [(reg FLAGS_REG) (const_int 0)])
19123 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19124 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19125 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19126 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19128 fcmov%F1\t{%2, %0|%0, %2}
19129 fcmov%f1\t{%3, %0|%0, %3}
19132 [(set_attr "type" "fcmov,fcmov,multi,multi")
19133 (set_attr "mode" "DF")])
19135 (define_insn "*movdfcc_1_rex64"
19136 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19137 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19138 [(reg FLAGS_REG) (const_int 0)])
19139 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19140 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19141 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19142 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19144 fcmov%F1\t{%2, %0|%0, %2}
19145 fcmov%f1\t{%3, %0|%0, %3}
19146 cmov%O2%C1\t{%2, %0|%0, %2}
19147 cmov%O2%c1\t{%3, %0|%0, %3}"
19148 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19149 (set_attr "mode" "DF")])
19152 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19153 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19154 [(match_operand 4 "flags_reg_operand" "")
19156 (match_operand:DF 2 "nonimmediate_operand" "")
19157 (match_operand:DF 3 "nonimmediate_operand" "")))]
19158 "!TARGET_64BIT && reload_completed"
19159 [(set (match_dup 2)
19160 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19164 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19167 "split_di (operands+2, 1, operands+5, operands+6);
19168 split_di (operands+3, 1, operands+7, operands+8);
19169 split_di (operands, 1, operands+2, operands+3);")
19171 (define_expand "movxfcc"
19172 [(set (match_operand:XF 0 "register_operand" "")
19173 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19174 (match_operand:XF 2 "register_operand" "")
19175 (match_operand:XF 3 "register_operand" "")))]
19176 "TARGET_80387 && TARGET_CMOVE"
19177 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19179 (define_insn "*movxfcc_1"
19180 [(set (match_operand:XF 0 "register_operand" "=f,f")
19181 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19182 [(reg FLAGS_REG) (const_int 0)])
19183 (match_operand:XF 2 "register_operand" "f,0")
19184 (match_operand:XF 3 "register_operand" "0,f")))]
19185 "TARGET_80387 && TARGET_CMOVE"
19187 fcmov%F1\t{%2, %0|%0, %2}
19188 fcmov%f1\t{%3, %0|%0, %3}"
19189 [(set_attr "type" "fcmov")
19190 (set_attr "mode" "XF")])
19192 ;; These versions of the min/max patterns are intentionally ignorant of
19193 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19194 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19195 ;; are undefined in this condition, we're certain this is correct.
19197 (define_insn "sminsf3"
19198 [(set (match_operand:SF 0 "register_operand" "=x")
19199 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19200 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19202 "minss\t{%2, %0|%0, %2}"
19203 [(set_attr "type" "sseadd")
19204 (set_attr "mode" "SF")])
19206 (define_insn "smaxsf3"
19207 [(set (match_operand:SF 0 "register_operand" "=x")
19208 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19209 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19211 "maxss\t{%2, %0|%0, %2}"
19212 [(set_attr "type" "sseadd")
19213 (set_attr "mode" "SF")])
19215 (define_insn "smindf3"
19216 [(set (match_operand:DF 0 "register_operand" "=x")
19217 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19218 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19219 "TARGET_SSE2 && TARGET_SSE_MATH"
19220 "minsd\t{%2, %0|%0, %2}"
19221 [(set_attr "type" "sseadd")
19222 (set_attr "mode" "DF")])
19224 (define_insn "smaxdf3"
19225 [(set (match_operand:DF 0 "register_operand" "=x")
19226 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19227 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19228 "TARGET_SSE2 && TARGET_SSE_MATH"
19229 "maxsd\t{%2, %0|%0, %2}"
19230 [(set_attr "type" "sseadd")
19231 (set_attr "mode" "DF")])
19233 ;; These versions of the min/max patterns implement exactly the operations
19234 ;; min = (op1 < op2 ? op1 : op2)
19235 ;; max = (!(op1 < op2) ? op1 : op2)
19236 ;; Their operands are not commutative, and thus they may be used in the
19237 ;; presence of -0.0 and NaN.
19239 (define_insn "*ieee_sminsf3"
19240 [(set (match_operand:SF 0 "register_operand" "=x")
19241 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19242 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19245 "minss\t{%2, %0|%0, %2}"
19246 [(set_attr "type" "sseadd")
19247 (set_attr "mode" "SF")])
19249 (define_insn "*ieee_smaxsf3"
19250 [(set (match_operand:SF 0 "register_operand" "=x")
19251 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19252 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19255 "maxss\t{%2, %0|%0, %2}"
19256 [(set_attr "type" "sseadd")
19257 (set_attr "mode" "SF")])
19259 (define_insn "*ieee_smindf3"
19260 [(set (match_operand:DF 0 "register_operand" "=x")
19261 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19262 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19264 "TARGET_SSE2 && TARGET_SSE_MATH"
19265 "minsd\t{%2, %0|%0, %2}"
19266 [(set_attr "type" "sseadd")
19267 (set_attr "mode" "DF")])
19269 (define_insn "*ieee_smaxdf3"
19270 [(set (match_operand:DF 0 "register_operand" "=x")
19271 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19272 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19274 "TARGET_SSE2 && TARGET_SSE_MATH"
19275 "maxsd\t{%2, %0|%0, %2}"
19276 [(set_attr "type" "sseadd")
19277 (set_attr "mode" "DF")])
19279 ;; Make two stack loads independent:
19281 ;; fld %st(0) -> fld bb
19282 ;; fmul bb fmul %st(1), %st
19284 ;; Actually we only match the last two instructions for simplicity.
19286 [(set (match_operand 0 "fp_register_operand" "")
19287 (match_operand 1 "fp_register_operand" ""))
19289 (match_operator 2 "binary_fp_operator"
19291 (match_operand 3 "memory_operand" "")]))]
19292 "REGNO (operands[0]) != REGNO (operands[1])"
19293 [(set (match_dup 0) (match_dup 3))
19294 (set (match_dup 0) (match_dup 4))]
19296 ;; The % modifier is not operational anymore in peephole2's, so we have to
19297 ;; swap the operands manually in the case of addition and multiplication.
19298 "if (COMMUTATIVE_ARITH_P (operands[2]))
19299 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19300 operands[0], operands[1]);
19302 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19303 operands[1], operands[0]);")
19305 ;; Conditional addition patterns
19306 (define_expand "addqicc"
19307 [(match_operand:QI 0 "register_operand" "")
19308 (match_operand 1 "comparison_operator" "")
19309 (match_operand:QI 2 "register_operand" "")
19310 (match_operand:QI 3 "const_int_operand" "")]
19312 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19314 (define_expand "addhicc"
19315 [(match_operand:HI 0 "register_operand" "")
19316 (match_operand 1 "comparison_operator" "")
19317 (match_operand:HI 2 "register_operand" "")
19318 (match_operand:HI 3 "const_int_operand" "")]
19320 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19322 (define_expand "addsicc"
19323 [(match_operand:SI 0 "register_operand" "")
19324 (match_operand 1 "comparison_operator" "")
19325 (match_operand:SI 2 "register_operand" "")
19326 (match_operand:SI 3 "const_int_operand" "")]
19328 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19330 (define_expand "adddicc"
19331 [(match_operand:DI 0 "register_operand" "")
19332 (match_operand 1 "comparison_operator" "")
19333 (match_operand:DI 2 "register_operand" "")
19334 (match_operand:DI 3 "const_int_operand" "")]
19336 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19339 ;; Misc patterns (?)
19341 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19342 ;; Otherwise there will be nothing to keep
19344 ;; [(set (reg ebp) (reg esp))]
19345 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19346 ;; (clobber (eflags)]
19347 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19349 ;; in proper program order.
19350 (define_insn "pro_epilogue_adjust_stack_1"
19351 [(set (match_operand:SI 0 "register_operand" "=r,r")
19352 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19353 (match_operand:SI 2 "immediate_operand" "i,i")))
19354 (clobber (reg:CC FLAGS_REG))
19355 (clobber (mem:BLK (scratch)))]
19358 switch (get_attr_type (insn))
19361 return "mov{l}\t{%1, %0|%0, %1}";
19364 if (CONST_INT_P (operands[2])
19365 && (INTVAL (operands[2]) == 128
19366 || (INTVAL (operands[2]) < 0
19367 && INTVAL (operands[2]) != -128)))
19369 operands[2] = GEN_INT (-INTVAL (operands[2]));
19370 return "sub{l}\t{%2, %0|%0, %2}";
19372 return "add{l}\t{%2, %0|%0, %2}";
19375 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19376 return "lea{l}\t{%a2, %0|%0, %a2}";
19379 gcc_unreachable ();
19382 [(set (attr "type")
19383 (cond [(eq_attr "alternative" "0")
19384 (const_string "alu")
19385 (match_operand:SI 2 "const0_operand" "")
19386 (const_string "imov")
19388 (const_string "lea")))
19389 (set_attr "mode" "SI")])
19391 (define_insn "pro_epilogue_adjust_stack_rex64"
19392 [(set (match_operand:DI 0 "register_operand" "=r,r")
19393 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19394 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19395 (clobber (reg:CC FLAGS_REG))
19396 (clobber (mem:BLK (scratch)))]
19399 switch (get_attr_type (insn))
19402 return "mov{q}\t{%1, %0|%0, %1}";
19405 if (CONST_INT_P (operands[2])
19406 /* Avoid overflows. */
19407 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19408 && (INTVAL (operands[2]) == 128
19409 || (INTVAL (operands[2]) < 0
19410 && INTVAL (operands[2]) != -128)))
19412 operands[2] = GEN_INT (-INTVAL (operands[2]));
19413 return "sub{q}\t{%2, %0|%0, %2}";
19415 return "add{q}\t{%2, %0|%0, %2}";
19418 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19419 return "lea{q}\t{%a2, %0|%0, %a2}";
19422 gcc_unreachable ();
19425 [(set (attr "type")
19426 (cond [(eq_attr "alternative" "0")
19427 (const_string "alu")
19428 (match_operand:DI 2 "const0_operand" "")
19429 (const_string "imov")
19431 (const_string "lea")))
19432 (set_attr "mode" "DI")])
19434 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19435 [(set (match_operand:DI 0 "register_operand" "=r,r")
19436 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19437 (match_operand:DI 3 "immediate_operand" "i,i")))
19438 (use (match_operand:DI 2 "register_operand" "r,r"))
19439 (clobber (reg:CC FLAGS_REG))
19440 (clobber (mem:BLK (scratch)))]
19443 switch (get_attr_type (insn))
19446 return "add{q}\t{%2, %0|%0, %2}";
19449 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19450 return "lea{q}\t{%a2, %0|%0, %a2}";
19453 gcc_unreachable ();
19456 [(set_attr "type" "alu,lea")
19457 (set_attr "mode" "DI")])
19459 (define_expand "allocate_stack_worker"
19460 [(match_operand:SI 0 "register_operand" "")]
19461 "TARGET_STACK_PROBE"
19463 if (reload_completed)
19466 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19468 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19473 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19475 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19480 (define_insn "allocate_stack_worker_1"
19481 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19482 UNSPECV_STACK_PROBE)
19483 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19484 (clobber (match_scratch:SI 1 "=0"))
19485 (clobber (reg:CC FLAGS_REG))]
19486 "!TARGET_64BIT && TARGET_STACK_PROBE"
19488 [(set_attr "type" "multi")
19489 (set_attr "length" "5")])
19491 (define_expand "allocate_stack_worker_postreload"
19492 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19493 UNSPECV_STACK_PROBE)
19494 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19495 (clobber (match_dup 0))
19496 (clobber (reg:CC FLAGS_REG))])]
19500 (define_insn "allocate_stack_worker_rex64"
19501 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19502 UNSPECV_STACK_PROBE)
19503 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19504 (clobber (match_scratch:DI 1 "=0"))
19505 (clobber (reg:CC FLAGS_REG))]
19506 "TARGET_64BIT && TARGET_STACK_PROBE"
19508 [(set_attr "type" "multi")
19509 (set_attr "length" "5")])
19511 (define_expand "allocate_stack_worker_rex64_postreload"
19512 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19513 UNSPECV_STACK_PROBE)
19514 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19515 (clobber (match_dup 0))
19516 (clobber (reg:CC FLAGS_REG))])]
19520 (define_expand "allocate_stack"
19521 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19522 (minus:SI (reg:SI SP_REG)
19523 (match_operand:SI 1 "general_operand" "")))
19524 (clobber (reg:CC FLAGS_REG))])
19525 (parallel [(set (reg:SI SP_REG)
19526 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19527 (clobber (reg:CC FLAGS_REG))])]
19528 "TARGET_STACK_PROBE"
19530 #ifdef CHECK_STACK_LIMIT
19531 if (CONST_INT_P (operands[1])
19532 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19533 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19537 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19540 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19544 (define_expand "builtin_setjmp_receiver"
19545 [(label_ref (match_operand 0 "" ""))]
19546 "!TARGET_64BIT && flag_pic"
19551 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19552 rtx label_rtx = gen_label_rtx ();
19553 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19554 xops[0] = xops[1] = picreg;
19555 xops[2] = gen_rtx_CONST (SImode,
19556 gen_rtx_MINUS (SImode,
19557 gen_rtx_LABEL_REF (SImode, label_rtx),
19558 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19559 ix86_expand_binary_operator (MINUS, SImode, xops);
19562 emit_insn (gen_set_got (pic_offset_table_rtx));
19566 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19569 [(set (match_operand 0 "register_operand" "")
19570 (match_operator 3 "promotable_binary_operator"
19571 [(match_operand 1 "register_operand" "")
19572 (match_operand 2 "aligned_operand" "")]))
19573 (clobber (reg:CC FLAGS_REG))]
19574 "! TARGET_PARTIAL_REG_STALL && reload_completed
19575 && ((GET_MODE (operands[0]) == HImode
19576 && ((!optimize_size && !TARGET_FAST_PREFIX)
19577 /* ??? next two lines just !satisfies_constraint_K (...) */
19578 || !CONST_INT_P (operands[2])
19579 || satisfies_constraint_K (operands[2])))
19580 || (GET_MODE (operands[0]) == QImode
19581 && (TARGET_PROMOTE_QImode || optimize_size)))"
19582 [(parallel [(set (match_dup 0)
19583 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19584 (clobber (reg:CC FLAGS_REG))])]
19585 "operands[0] = gen_lowpart (SImode, operands[0]);
19586 operands[1] = gen_lowpart (SImode, operands[1]);
19587 if (GET_CODE (operands[3]) != ASHIFT)
19588 operands[2] = gen_lowpart (SImode, operands[2]);
19589 PUT_MODE (operands[3], SImode);")
19591 ; Promote the QImode tests, as i386 has encoding of the AND
19592 ; instruction with 32-bit sign-extended immediate and thus the
19593 ; instruction size is unchanged, except in the %eax case for
19594 ; which it is increased by one byte, hence the ! optimize_size.
19596 [(set (match_operand 0 "flags_reg_operand" "")
19597 (match_operator 2 "compare_operator"
19598 [(and (match_operand 3 "aligned_operand" "")
19599 (match_operand 4 "const_int_operand" ""))
19601 (set (match_operand 1 "register_operand" "")
19602 (and (match_dup 3) (match_dup 4)))]
19603 "! TARGET_PARTIAL_REG_STALL && reload_completed
19604 /* Ensure that the operand will remain sign-extended immediate. */
19605 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19607 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19608 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19609 [(parallel [(set (match_dup 0)
19610 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19613 (and:SI (match_dup 3) (match_dup 4)))])]
19616 = gen_int_mode (INTVAL (operands[4])
19617 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19618 operands[1] = gen_lowpart (SImode, operands[1]);
19619 operands[3] = gen_lowpart (SImode, operands[3]);
19622 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19623 ; the TEST instruction with 32-bit sign-extended immediate and thus
19624 ; the instruction size would at least double, which is not what we
19625 ; want even with ! optimize_size.
19627 [(set (match_operand 0 "flags_reg_operand" "")
19628 (match_operator 1 "compare_operator"
19629 [(and (match_operand:HI 2 "aligned_operand" "")
19630 (match_operand:HI 3 "const_int_operand" ""))
19632 "! TARGET_PARTIAL_REG_STALL && reload_completed
19633 /* Ensure that the operand will remain sign-extended immediate. */
19634 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19635 && ! TARGET_FAST_PREFIX
19636 && ! optimize_size"
19637 [(set (match_dup 0)
19638 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19642 = gen_int_mode (INTVAL (operands[3])
19643 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19644 operands[2] = gen_lowpart (SImode, operands[2]);
19648 [(set (match_operand 0 "register_operand" "")
19649 (neg (match_operand 1 "register_operand" "")))
19650 (clobber (reg:CC FLAGS_REG))]
19651 "! TARGET_PARTIAL_REG_STALL && reload_completed
19652 && (GET_MODE (operands[0]) == HImode
19653 || (GET_MODE (operands[0]) == QImode
19654 && (TARGET_PROMOTE_QImode || optimize_size)))"
19655 [(parallel [(set (match_dup 0)
19656 (neg:SI (match_dup 1)))
19657 (clobber (reg:CC FLAGS_REG))])]
19658 "operands[0] = gen_lowpart (SImode, operands[0]);
19659 operands[1] = gen_lowpart (SImode, operands[1]);")
19662 [(set (match_operand 0 "register_operand" "")
19663 (not (match_operand 1 "register_operand" "")))]
19664 "! TARGET_PARTIAL_REG_STALL && reload_completed
19665 && (GET_MODE (operands[0]) == HImode
19666 || (GET_MODE (operands[0]) == QImode
19667 && (TARGET_PROMOTE_QImode || optimize_size)))"
19668 [(set (match_dup 0)
19669 (not:SI (match_dup 1)))]
19670 "operands[0] = gen_lowpart (SImode, operands[0]);
19671 operands[1] = gen_lowpart (SImode, operands[1]);")
19674 [(set (match_operand 0 "register_operand" "")
19675 (if_then_else (match_operator 1 "comparison_operator"
19676 [(reg FLAGS_REG) (const_int 0)])
19677 (match_operand 2 "register_operand" "")
19678 (match_operand 3 "register_operand" "")))]
19679 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19680 && (GET_MODE (operands[0]) == HImode
19681 || (GET_MODE (operands[0]) == QImode
19682 && (TARGET_PROMOTE_QImode || optimize_size)))"
19683 [(set (match_dup 0)
19684 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19685 "operands[0] = gen_lowpart (SImode, operands[0]);
19686 operands[2] = gen_lowpart (SImode, operands[2]);
19687 operands[3] = gen_lowpart (SImode, operands[3]);")
19690 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19691 ;; transform a complex memory operation into two memory to register operations.
19693 ;; Don't push memory operands
19695 [(set (match_operand:SI 0 "push_operand" "")
19696 (match_operand:SI 1 "memory_operand" ""))
19697 (match_scratch:SI 2 "r")]
19698 "!optimize_size && !TARGET_PUSH_MEMORY
19699 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19700 [(set (match_dup 2) (match_dup 1))
19701 (set (match_dup 0) (match_dup 2))]
19705 [(set (match_operand:DI 0 "push_operand" "")
19706 (match_operand:DI 1 "memory_operand" ""))
19707 (match_scratch:DI 2 "r")]
19708 "!optimize_size && !TARGET_PUSH_MEMORY
19709 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19710 [(set (match_dup 2) (match_dup 1))
19711 (set (match_dup 0) (match_dup 2))]
19714 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19717 [(set (match_operand:SF 0 "push_operand" "")
19718 (match_operand:SF 1 "memory_operand" ""))
19719 (match_scratch:SF 2 "r")]
19720 "!optimize_size && !TARGET_PUSH_MEMORY
19721 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19722 [(set (match_dup 2) (match_dup 1))
19723 (set (match_dup 0) (match_dup 2))]
19727 [(set (match_operand:HI 0 "push_operand" "")
19728 (match_operand:HI 1 "memory_operand" ""))
19729 (match_scratch:HI 2 "r")]
19730 "!optimize_size && !TARGET_PUSH_MEMORY
19731 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19732 [(set (match_dup 2) (match_dup 1))
19733 (set (match_dup 0) (match_dup 2))]
19737 [(set (match_operand:QI 0 "push_operand" "")
19738 (match_operand:QI 1 "memory_operand" ""))
19739 (match_scratch:QI 2 "q")]
19740 "!optimize_size && !TARGET_PUSH_MEMORY
19741 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19742 [(set (match_dup 2) (match_dup 1))
19743 (set (match_dup 0) (match_dup 2))]
19746 ;; Don't move an immediate directly to memory when the instruction
19749 [(match_scratch:SI 1 "r")
19750 (set (match_operand:SI 0 "memory_operand" "")
19753 && ! TARGET_USE_MOV0
19754 && TARGET_SPLIT_LONG_MOVES
19755 && get_attr_length (insn) >= ix86_cost->large_insn
19756 && peep2_regno_dead_p (0, FLAGS_REG)"
19757 [(parallel [(set (match_dup 1) (const_int 0))
19758 (clobber (reg:CC FLAGS_REG))])
19759 (set (match_dup 0) (match_dup 1))]
19763 [(match_scratch:HI 1 "r")
19764 (set (match_operand:HI 0 "memory_operand" "")
19767 && ! TARGET_USE_MOV0
19768 && TARGET_SPLIT_LONG_MOVES
19769 && get_attr_length (insn) >= ix86_cost->large_insn
19770 && peep2_regno_dead_p (0, FLAGS_REG)"
19771 [(parallel [(set (match_dup 2) (const_int 0))
19772 (clobber (reg:CC FLAGS_REG))])
19773 (set (match_dup 0) (match_dup 1))]
19774 "operands[2] = gen_lowpart (SImode, operands[1]);")
19777 [(match_scratch:QI 1 "q")
19778 (set (match_operand:QI 0 "memory_operand" "")
19781 && ! TARGET_USE_MOV0
19782 && TARGET_SPLIT_LONG_MOVES
19783 && get_attr_length (insn) >= ix86_cost->large_insn
19784 && peep2_regno_dead_p (0, FLAGS_REG)"
19785 [(parallel [(set (match_dup 2) (const_int 0))
19786 (clobber (reg:CC FLAGS_REG))])
19787 (set (match_dup 0) (match_dup 1))]
19788 "operands[2] = gen_lowpart (SImode, operands[1]);")
19791 [(match_scratch:SI 2 "r")
19792 (set (match_operand:SI 0 "memory_operand" "")
19793 (match_operand:SI 1 "immediate_operand" ""))]
19795 && get_attr_length (insn) >= ix86_cost->large_insn
19796 && TARGET_SPLIT_LONG_MOVES"
19797 [(set (match_dup 2) (match_dup 1))
19798 (set (match_dup 0) (match_dup 2))]
19802 [(match_scratch:HI 2 "r")
19803 (set (match_operand:HI 0 "memory_operand" "")
19804 (match_operand:HI 1 "immediate_operand" ""))]
19805 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19806 && TARGET_SPLIT_LONG_MOVES"
19807 [(set (match_dup 2) (match_dup 1))
19808 (set (match_dup 0) (match_dup 2))]
19812 [(match_scratch:QI 2 "q")
19813 (set (match_operand:QI 0 "memory_operand" "")
19814 (match_operand:QI 1 "immediate_operand" ""))]
19815 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19816 && TARGET_SPLIT_LONG_MOVES"
19817 [(set (match_dup 2) (match_dup 1))
19818 (set (match_dup 0) (match_dup 2))]
19821 ;; Don't compare memory with zero, load and use a test instead.
19823 [(set (match_operand 0 "flags_reg_operand" "")
19824 (match_operator 1 "compare_operator"
19825 [(match_operand:SI 2 "memory_operand" "")
19827 (match_scratch:SI 3 "r")]
19828 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19829 [(set (match_dup 3) (match_dup 2))
19830 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19833 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19834 ;; Don't split NOTs with a displacement operand, because resulting XOR
19835 ;; will not be pairable anyway.
19837 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19838 ;; represented using a modRM byte. The XOR replacement is long decoded,
19839 ;; so this split helps here as well.
19841 ;; Note: Can't do this as a regular split because we can't get proper
19842 ;; lifetime information then.
19845 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19846 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19848 && peep2_regno_dead_p (0, FLAGS_REG)
19849 && ((TARGET_PENTIUM
19850 && (!MEM_P (operands[0])
19851 || !memory_displacement_operand (operands[0], SImode)))
19852 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19853 [(parallel [(set (match_dup 0)
19854 (xor:SI (match_dup 1) (const_int -1)))
19855 (clobber (reg:CC FLAGS_REG))])]
19859 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19860 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19862 && peep2_regno_dead_p (0, FLAGS_REG)
19863 && ((TARGET_PENTIUM
19864 && (!MEM_P (operands[0])
19865 || !memory_displacement_operand (operands[0], HImode)))
19866 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19867 [(parallel [(set (match_dup 0)
19868 (xor:HI (match_dup 1) (const_int -1)))
19869 (clobber (reg:CC FLAGS_REG))])]
19873 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19874 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19876 && peep2_regno_dead_p (0, FLAGS_REG)
19877 && ((TARGET_PENTIUM
19878 && (!MEM_P (operands[0])
19879 || !memory_displacement_operand (operands[0], QImode)))
19880 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19881 [(parallel [(set (match_dup 0)
19882 (xor:QI (match_dup 1) (const_int -1)))
19883 (clobber (reg:CC FLAGS_REG))])]
19886 ;; Non pairable "test imm, reg" instructions can be translated to
19887 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19888 ;; byte opcode instead of two, have a short form for byte operands),
19889 ;; so do it for other CPUs as well. Given that the value was dead,
19890 ;; this should not create any new dependencies. Pass on the sub-word
19891 ;; versions if we're concerned about partial register stalls.
19894 [(set (match_operand 0 "flags_reg_operand" "")
19895 (match_operator 1 "compare_operator"
19896 [(and:SI (match_operand:SI 2 "register_operand" "")
19897 (match_operand:SI 3 "immediate_operand" ""))
19899 "ix86_match_ccmode (insn, CCNOmode)
19900 && (true_regnum (operands[2]) != 0
19901 || satisfies_constraint_K (operands[3]))
19902 && peep2_reg_dead_p (1, operands[2])"
19904 [(set (match_dup 0)
19905 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19908 (and:SI (match_dup 2) (match_dup 3)))])]
19911 ;; We don't need to handle HImode case, because it will be promoted to SImode
19912 ;; on ! TARGET_PARTIAL_REG_STALL
19915 [(set (match_operand 0 "flags_reg_operand" "")
19916 (match_operator 1 "compare_operator"
19917 [(and:QI (match_operand:QI 2 "register_operand" "")
19918 (match_operand:QI 3 "immediate_operand" ""))
19920 "! TARGET_PARTIAL_REG_STALL
19921 && ix86_match_ccmode (insn, CCNOmode)
19922 && true_regnum (operands[2]) != 0
19923 && peep2_reg_dead_p (1, operands[2])"
19925 [(set (match_dup 0)
19926 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19929 (and:QI (match_dup 2) (match_dup 3)))])]
19933 [(set (match_operand 0 "flags_reg_operand" "")
19934 (match_operator 1 "compare_operator"
19937 (match_operand 2 "ext_register_operand" "")
19940 (match_operand 3 "const_int_operand" ""))
19942 "! TARGET_PARTIAL_REG_STALL
19943 && ix86_match_ccmode (insn, CCNOmode)
19944 && true_regnum (operands[2]) != 0
19945 && peep2_reg_dead_p (1, operands[2])"
19946 [(parallel [(set (match_dup 0)
19955 (set (zero_extract:SI (match_dup 2)
19966 ;; Don't do logical operations with memory inputs.
19968 [(match_scratch:SI 2 "r")
19969 (parallel [(set (match_operand:SI 0 "register_operand" "")
19970 (match_operator:SI 3 "arith_or_logical_operator"
19972 (match_operand:SI 1 "memory_operand" "")]))
19973 (clobber (reg:CC FLAGS_REG))])]
19974 "! optimize_size && ! TARGET_READ_MODIFY"
19975 [(set (match_dup 2) (match_dup 1))
19976 (parallel [(set (match_dup 0)
19977 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19978 (clobber (reg:CC FLAGS_REG))])]
19982 [(match_scratch:SI 2 "r")
19983 (parallel [(set (match_operand:SI 0 "register_operand" "")
19984 (match_operator:SI 3 "arith_or_logical_operator"
19985 [(match_operand:SI 1 "memory_operand" "")
19987 (clobber (reg:CC FLAGS_REG))])]
19988 "! optimize_size && ! TARGET_READ_MODIFY"
19989 [(set (match_dup 2) (match_dup 1))
19990 (parallel [(set (match_dup 0)
19991 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19992 (clobber (reg:CC FLAGS_REG))])]
19995 ; Don't do logical operations with memory outputs
19997 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19998 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19999 ; the same decoder scheduling characteristics as the original.
20002 [(match_scratch:SI 2 "r")
20003 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20004 (match_operator:SI 3 "arith_or_logical_operator"
20006 (match_operand:SI 1 "nonmemory_operand" "")]))
20007 (clobber (reg:CC FLAGS_REG))])]
20008 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20009 [(set (match_dup 2) (match_dup 0))
20010 (parallel [(set (match_dup 2)
20011 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20012 (clobber (reg:CC FLAGS_REG))])
20013 (set (match_dup 0) (match_dup 2))]
20017 [(match_scratch:SI 2 "r")
20018 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20019 (match_operator:SI 3 "arith_or_logical_operator"
20020 [(match_operand:SI 1 "nonmemory_operand" "")
20022 (clobber (reg:CC FLAGS_REG))])]
20023 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20024 [(set (match_dup 2) (match_dup 0))
20025 (parallel [(set (match_dup 2)
20026 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20027 (clobber (reg:CC FLAGS_REG))])
20028 (set (match_dup 0) (match_dup 2))]
20031 ;; Attempt to always use XOR for zeroing registers.
20033 [(set (match_operand 0 "register_operand" "")
20034 (match_operand 1 "const0_operand" ""))]
20035 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20036 && (! TARGET_USE_MOV0 || optimize_size)
20037 && GENERAL_REG_P (operands[0])
20038 && peep2_regno_dead_p (0, FLAGS_REG)"
20039 [(parallel [(set (match_dup 0) (const_int 0))
20040 (clobber (reg:CC FLAGS_REG))])]
20042 operands[0] = gen_lowpart (word_mode, operands[0]);
20046 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20048 "(GET_MODE (operands[0]) == QImode
20049 || GET_MODE (operands[0]) == HImode)
20050 && (! TARGET_USE_MOV0 || optimize_size)
20051 && peep2_regno_dead_p (0, FLAGS_REG)"
20052 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20053 (clobber (reg:CC FLAGS_REG))])])
20055 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20057 [(set (match_operand 0 "register_operand" "")
20059 "(GET_MODE (operands[0]) == HImode
20060 || GET_MODE (operands[0]) == SImode
20061 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20062 && (optimize_size || TARGET_PENTIUM)
20063 && peep2_regno_dead_p (0, FLAGS_REG)"
20064 [(parallel [(set (match_dup 0) (const_int -1))
20065 (clobber (reg:CC FLAGS_REG))])]
20066 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20069 ;; Attempt to convert simple leas to adds. These can be created by
20072 [(set (match_operand:SI 0 "register_operand" "")
20073 (plus:SI (match_dup 0)
20074 (match_operand:SI 1 "nonmemory_operand" "")))]
20075 "peep2_regno_dead_p (0, FLAGS_REG)"
20076 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20077 (clobber (reg:CC FLAGS_REG))])]
20081 [(set (match_operand:SI 0 "register_operand" "")
20082 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20083 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20084 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20085 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20086 (clobber (reg:CC FLAGS_REG))])]
20087 "operands[2] = gen_lowpart (SImode, operands[2]);")
20090 [(set (match_operand:DI 0 "register_operand" "")
20091 (plus:DI (match_dup 0)
20092 (match_operand:DI 1 "x86_64_general_operand" "")))]
20093 "peep2_regno_dead_p (0, FLAGS_REG)"
20094 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20095 (clobber (reg:CC FLAGS_REG))])]
20099 [(set (match_operand:SI 0 "register_operand" "")
20100 (mult:SI (match_dup 0)
20101 (match_operand:SI 1 "const_int_operand" "")))]
20102 "exact_log2 (INTVAL (operands[1])) >= 0
20103 && peep2_regno_dead_p (0, FLAGS_REG)"
20104 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20105 (clobber (reg:CC FLAGS_REG))])]
20106 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20109 [(set (match_operand:DI 0 "register_operand" "")
20110 (mult:DI (match_dup 0)
20111 (match_operand:DI 1 "const_int_operand" "")))]
20112 "exact_log2 (INTVAL (operands[1])) >= 0
20113 && peep2_regno_dead_p (0, FLAGS_REG)"
20114 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20115 (clobber (reg:CC FLAGS_REG))])]
20116 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20119 [(set (match_operand:SI 0 "register_operand" "")
20120 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20121 (match_operand:DI 2 "const_int_operand" "")) 0))]
20122 "exact_log2 (INTVAL (operands[2])) >= 0
20123 && REGNO (operands[0]) == REGNO (operands[1])
20124 && peep2_regno_dead_p (0, FLAGS_REG)"
20125 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20126 (clobber (reg:CC FLAGS_REG))])]
20127 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20129 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20130 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20131 ;; many CPUs it is also faster, since special hardware to avoid esp
20132 ;; dependencies is present.
20134 ;; While some of these conversions may be done using splitters, we use peepholes
20135 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20137 ;; Convert prologue esp subtractions to push.
20138 ;; We need register to push. In order to keep verify_flow_info happy we have
20140 ;; - use scratch and clobber it in order to avoid dependencies
20141 ;; - use already live register
20142 ;; We can't use the second way right now, since there is no reliable way how to
20143 ;; verify that given register is live. First choice will also most likely in
20144 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20145 ;; call clobbered registers are dead. We may want to use base pointer as an
20146 ;; alternative when no register is available later.
20149 [(match_scratch:SI 0 "r")
20150 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20151 (clobber (reg:CC FLAGS_REG))
20152 (clobber (mem:BLK (scratch)))])]
20153 "optimize_size || !TARGET_SUB_ESP_4"
20154 [(clobber (match_dup 0))
20155 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20156 (clobber (mem:BLK (scratch)))])])
20159 [(match_scratch:SI 0 "r")
20160 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20161 (clobber (reg:CC FLAGS_REG))
20162 (clobber (mem:BLK (scratch)))])]
20163 "optimize_size || !TARGET_SUB_ESP_8"
20164 [(clobber (match_dup 0))
20165 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20166 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20167 (clobber (mem:BLK (scratch)))])])
20169 ;; Convert esp subtractions to push.
20171 [(match_scratch:SI 0 "r")
20172 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20173 (clobber (reg:CC FLAGS_REG))])]
20174 "optimize_size || !TARGET_SUB_ESP_4"
20175 [(clobber (match_dup 0))
20176 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20179 [(match_scratch:SI 0 "r")
20180 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20181 (clobber (reg:CC FLAGS_REG))])]
20182 "optimize_size || !TARGET_SUB_ESP_8"
20183 [(clobber (match_dup 0))
20184 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20185 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20187 ;; Convert epilogue deallocator to pop.
20189 [(match_scratch:SI 0 "r")
20190 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20191 (clobber (reg:CC FLAGS_REG))
20192 (clobber (mem:BLK (scratch)))])]
20193 "optimize_size || !TARGET_ADD_ESP_4"
20194 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20195 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20196 (clobber (mem:BLK (scratch)))])]
20199 ;; Two pops case is tricky, since pop causes dependency on destination register.
20200 ;; We use two registers if available.
20202 [(match_scratch:SI 0 "r")
20203 (match_scratch:SI 1 "r")
20204 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20205 (clobber (reg:CC FLAGS_REG))
20206 (clobber (mem:BLK (scratch)))])]
20207 "optimize_size || !TARGET_ADD_ESP_8"
20208 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20209 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20210 (clobber (mem:BLK (scratch)))])
20211 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20212 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20216 [(match_scratch:SI 0 "r")
20217 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20218 (clobber (reg:CC FLAGS_REG))
20219 (clobber (mem:BLK (scratch)))])]
20221 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20222 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20223 (clobber (mem:BLK (scratch)))])
20224 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20225 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20228 ;; Convert esp additions to pop.
20230 [(match_scratch:SI 0 "r")
20231 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20232 (clobber (reg:CC FLAGS_REG))])]
20234 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20235 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20238 ;; Two pops case is tricky, since pop causes dependency on destination register.
20239 ;; We use two registers if available.
20241 [(match_scratch:SI 0 "r")
20242 (match_scratch:SI 1 "r")
20243 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20244 (clobber (reg:CC FLAGS_REG))])]
20246 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20247 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20248 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20249 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20253 [(match_scratch:SI 0 "r")
20254 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20255 (clobber (reg:CC FLAGS_REG))])]
20257 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20258 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20259 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20260 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20263 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20264 ;; required and register dies. Similarly for 128 to plus -128.
20266 [(set (match_operand 0 "flags_reg_operand" "")
20267 (match_operator 1 "compare_operator"
20268 [(match_operand 2 "register_operand" "")
20269 (match_operand 3 "const_int_operand" "")]))]
20270 "(INTVAL (operands[3]) == -1
20271 || INTVAL (operands[3]) == 1
20272 || INTVAL (operands[3]) == 128)
20273 && ix86_match_ccmode (insn, CCGCmode)
20274 && peep2_reg_dead_p (1, operands[2])"
20275 [(parallel [(set (match_dup 0)
20276 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20277 (clobber (match_dup 2))])]
20281 [(match_scratch:DI 0 "r")
20282 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20283 (clobber (reg:CC FLAGS_REG))
20284 (clobber (mem:BLK (scratch)))])]
20285 "optimize_size || !TARGET_SUB_ESP_4"
20286 [(clobber (match_dup 0))
20287 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20288 (clobber (mem:BLK (scratch)))])])
20291 [(match_scratch:DI 0 "r")
20292 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20293 (clobber (reg:CC FLAGS_REG))
20294 (clobber (mem:BLK (scratch)))])]
20295 "optimize_size || !TARGET_SUB_ESP_8"
20296 [(clobber (match_dup 0))
20297 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20298 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20299 (clobber (mem:BLK (scratch)))])])
20301 ;; Convert esp subtractions to push.
20303 [(match_scratch:DI 0 "r")
20304 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20305 (clobber (reg:CC FLAGS_REG))])]
20306 "optimize_size || !TARGET_SUB_ESP_4"
20307 [(clobber (match_dup 0))
20308 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20311 [(match_scratch:DI 0 "r")
20312 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20313 (clobber (reg:CC FLAGS_REG))])]
20314 "optimize_size || !TARGET_SUB_ESP_8"
20315 [(clobber (match_dup 0))
20316 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20317 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20319 ;; Convert epilogue deallocator to pop.
20321 [(match_scratch:DI 0 "r")
20322 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20323 (clobber (reg:CC FLAGS_REG))
20324 (clobber (mem:BLK (scratch)))])]
20325 "optimize_size || !TARGET_ADD_ESP_4"
20326 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20327 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20328 (clobber (mem:BLK (scratch)))])]
20331 ;; Two pops case is tricky, since pop causes dependency on destination register.
20332 ;; We use two registers if available.
20334 [(match_scratch:DI 0 "r")
20335 (match_scratch:DI 1 "r")
20336 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20337 (clobber (reg:CC FLAGS_REG))
20338 (clobber (mem:BLK (scratch)))])]
20339 "optimize_size || !TARGET_ADD_ESP_8"
20340 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20341 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20342 (clobber (mem:BLK (scratch)))])
20343 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20344 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20348 [(match_scratch:DI 0 "r")
20349 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20350 (clobber (reg:CC FLAGS_REG))
20351 (clobber (mem:BLK (scratch)))])]
20353 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20354 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20355 (clobber (mem:BLK (scratch)))])
20356 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20357 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20360 ;; Convert esp additions to pop.
20362 [(match_scratch:DI 0 "r")
20363 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20364 (clobber (reg:CC FLAGS_REG))])]
20366 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20367 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20370 ;; Two pops case is tricky, since pop causes dependency on destination register.
20371 ;; We use two registers if available.
20373 [(match_scratch:DI 0 "r")
20374 (match_scratch:DI 1 "r")
20375 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20376 (clobber (reg:CC FLAGS_REG))])]
20378 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20379 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20380 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20381 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20385 [(match_scratch:DI 0 "r")
20386 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20387 (clobber (reg:CC FLAGS_REG))])]
20389 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20390 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20391 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20392 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20395 ;; Convert imul by three, five and nine into lea
20398 [(set (match_operand:SI 0 "register_operand" "")
20399 (mult:SI (match_operand:SI 1 "register_operand" "")
20400 (match_operand:SI 2 "const_int_operand" "")))
20401 (clobber (reg:CC FLAGS_REG))])]
20402 "INTVAL (operands[2]) == 3
20403 || INTVAL (operands[2]) == 5
20404 || INTVAL (operands[2]) == 9"
20405 [(set (match_dup 0)
20406 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20408 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20412 [(set (match_operand:SI 0 "register_operand" "")
20413 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20414 (match_operand:SI 2 "const_int_operand" "")))
20415 (clobber (reg:CC FLAGS_REG))])]
20417 && (INTVAL (operands[2]) == 3
20418 || INTVAL (operands[2]) == 5
20419 || INTVAL (operands[2]) == 9)"
20420 [(set (match_dup 0) (match_dup 1))
20422 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20424 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20428 [(set (match_operand:DI 0 "register_operand" "")
20429 (mult:DI (match_operand:DI 1 "register_operand" "")
20430 (match_operand:DI 2 "const_int_operand" "")))
20431 (clobber (reg:CC FLAGS_REG))])]
20433 && (INTVAL (operands[2]) == 3
20434 || INTVAL (operands[2]) == 5
20435 || INTVAL (operands[2]) == 9)"
20436 [(set (match_dup 0)
20437 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20439 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20443 [(set (match_operand:DI 0 "register_operand" "")
20444 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20445 (match_operand:DI 2 "const_int_operand" "")))
20446 (clobber (reg:CC FLAGS_REG))])]
20449 && (INTVAL (operands[2]) == 3
20450 || INTVAL (operands[2]) == 5
20451 || INTVAL (operands[2]) == 9)"
20452 [(set (match_dup 0) (match_dup 1))
20454 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20456 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20458 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20459 ;; imul $32bit_imm, reg, reg is direct decoded.
20461 [(match_scratch:DI 3 "r")
20462 (parallel [(set (match_operand:DI 0 "register_operand" "")
20463 (mult:DI (match_operand:DI 1 "memory_operand" "")
20464 (match_operand:DI 2 "immediate_operand" "")))
20465 (clobber (reg:CC FLAGS_REG))])]
20466 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20467 && !satisfies_constraint_K (operands[2])"
20468 [(set (match_dup 3) (match_dup 1))
20469 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20470 (clobber (reg:CC FLAGS_REG))])]
20474 [(match_scratch:SI 3 "r")
20475 (parallel [(set (match_operand:SI 0 "register_operand" "")
20476 (mult:SI (match_operand:SI 1 "memory_operand" "")
20477 (match_operand:SI 2 "immediate_operand" "")))
20478 (clobber (reg:CC FLAGS_REG))])]
20479 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20480 && !satisfies_constraint_K (operands[2])"
20481 [(set (match_dup 3) (match_dup 1))
20482 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20483 (clobber (reg:CC FLAGS_REG))])]
20487 [(match_scratch:SI 3 "r")
20488 (parallel [(set (match_operand:DI 0 "register_operand" "")
20490 (mult:SI (match_operand:SI 1 "memory_operand" "")
20491 (match_operand:SI 2 "immediate_operand" ""))))
20492 (clobber (reg:CC FLAGS_REG))])]
20493 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20494 && !satisfies_constraint_K (operands[2])"
20495 [(set (match_dup 3) (match_dup 1))
20496 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20497 (clobber (reg:CC FLAGS_REG))])]
20500 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20501 ;; Convert it into imul reg, reg
20502 ;; It would be better to force assembler to encode instruction using long
20503 ;; immediate, but there is apparently no way to do so.
20505 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20506 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20507 (match_operand:DI 2 "const_int_operand" "")))
20508 (clobber (reg:CC FLAGS_REG))])
20509 (match_scratch:DI 3 "r")]
20510 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20511 && satisfies_constraint_K (operands[2])"
20512 [(set (match_dup 3) (match_dup 2))
20513 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20514 (clobber (reg:CC FLAGS_REG))])]
20516 if (!rtx_equal_p (operands[0], operands[1]))
20517 emit_move_insn (operands[0], operands[1]);
20521 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20522 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20523 (match_operand:SI 2 "const_int_operand" "")))
20524 (clobber (reg:CC FLAGS_REG))])
20525 (match_scratch:SI 3 "r")]
20526 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20527 && satisfies_constraint_K (operands[2])"
20528 [(set (match_dup 3) (match_dup 2))
20529 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20530 (clobber (reg:CC FLAGS_REG))])]
20532 if (!rtx_equal_p (operands[0], operands[1]))
20533 emit_move_insn (operands[0], operands[1]);
20537 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20538 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20539 (match_operand:HI 2 "immediate_operand" "")))
20540 (clobber (reg:CC FLAGS_REG))])
20541 (match_scratch:HI 3 "r")]
20542 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20543 [(set (match_dup 3) (match_dup 2))
20544 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20545 (clobber (reg:CC FLAGS_REG))])]
20547 if (!rtx_equal_p (operands[0], operands[1]))
20548 emit_move_insn (operands[0], operands[1]);
20551 ;; After splitting up read-modify operations, array accesses with memory
20552 ;; operands might end up in form:
20554 ;; movl 4(%esp), %edx
20556 ;; instead of pre-splitting:
20558 ;; addl 4(%esp), %eax
20560 ;; movl 4(%esp), %edx
20561 ;; leal (%edx,%eax,4), %eax
20564 [(parallel [(set (match_operand 0 "register_operand" "")
20565 (ashift (match_operand 1 "register_operand" "")
20566 (match_operand 2 "const_int_operand" "")))
20567 (clobber (reg:CC FLAGS_REG))])
20568 (set (match_operand 3 "register_operand")
20569 (match_operand 4 "x86_64_general_operand" ""))
20570 (parallel [(set (match_operand 5 "register_operand" "")
20571 (plus (match_operand 6 "register_operand" "")
20572 (match_operand 7 "register_operand" "")))
20573 (clobber (reg:CC FLAGS_REG))])]
20574 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20575 /* Validate MODE for lea. */
20576 && ((!TARGET_PARTIAL_REG_STALL
20577 && (GET_MODE (operands[0]) == QImode
20578 || GET_MODE (operands[0]) == HImode))
20579 || GET_MODE (operands[0]) == SImode
20580 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20581 /* We reorder load and the shift. */
20582 && !rtx_equal_p (operands[1], operands[3])
20583 && !reg_overlap_mentioned_p (operands[0], operands[4])
20584 /* Last PLUS must consist of operand 0 and 3. */
20585 && !rtx_equal_p (operands[0], operands[3])
20586 && (rtx_equal_p (operands[3], operands[6])
20587 || rtx_equal_p (operands[3], operands[7]))
20588 && (rtx_equal_p (operands[0], operands[6])
20589 || rtx_equal_p (operands[0], operands[7]))
20590 /* The intermediate operand 0 must die or be same as output. */
20591 && (rtx_equal_p (operands[0], operands[5])
20592 || peep2_reg_dead_p (3, operands[0]))"
20593 [(set (match_dup 3) (match_dup 4))
20594 (set (match_dup 0) (match_dup 1))]
20596 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20597 int scale = 1 << INTVAL (operands[2]);
20598 rtx index = gen_lowpart (Pmode, operands[1]);
20599 rtx base = gen_lowpart (Pmode, operands[3]);
20600 rtx dest = gen_lowpart (mode, operands[5]);
20602 operands[1] = gen_rtx_PLUS (Pmode, base,
20603 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20605 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20606 operands[0] = dest;
20609 ;; Call-value patterns last so that the wildcard operand does not
20610 ;; disrupt insn-recog's switch tables.
20612 (define_insn "*call_value_pop_0"
20613 [(set (match_operand 0 "" "")
20614 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20615 (match_operand:SI 2 "" "")))
20616 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20617 (match_operand:SI 3 "immediate_operand" "")))]
20620 if (SIBLING_CALL_P (insn))
20623 return "call\t%P1";
20625 [(set_attr "type" "callv")])
20627 (define_insn "*call_value_pop_1"
20628 [(set (match_operand 0 "" "")
20629 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20630 (match_operand:SI 2 "" "")))
20631 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20632 (match_operand:SI 3 "immediate_operand" "i")))]
20635 if (constant_call_address_operand (operands[1], Pmode))
20637 if (SIBLING_CALL_P (insn))
20640 return "call\t%P1";
20642 if (SIBLING_CALL_P (insn))
20645 return "call\t%A1";
20647 [(set_attr "type" "callv")])
20649 (define_insn "*call_value_0"
20650 [(set (match_operand 0 "" "")
20651 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20652 (match_operand:SI 2 "" "")))]
20655 if (SIBLING_CALL_P (insn))
20658 return "call\t%P1";
20660 [(set_attr "type" "callv")])
20662 (define_insn "*call_value_0_rex64"
20663 [(set (match_operand 0 "" "")
20664 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20665 (match_operand:DI 2 "const_int_operand" "")))]
20668 if (SIBLING_CALL_P (insn))
20671 return "call\t%P1";
20673 [(set_attr "type" "callv")])
20675 (define_insn "*call_value_1"
20676 [(set (match_operand 0 "" "")
20677 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20678 (match_operand:SI 2 "" "")))]
20679 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20681 if (constant_call_address_operand (operands[1], Pmode))
20682 return "call\t%P1";
20683 return "call\t%A1";
20685 [(set_attr "type" "callv")])
20687 (define_insn "*sibcall_value_1"
20688 [(set (match_operand 0 "" "")
20689 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20690 (match_operand:SI 2 "" "")))]
20691 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20693 if (constant_call_address_operand (operands[1], Pmode))
20697 [(set_attr "type" "callv")])
20699 (define_insn "*call_value_1_rex64"
20700 [(set (match_operand 0 "" "")
20701 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20702 (match_operand:DI 2 "" "")))]
20703 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20705 if (constant_call_address_operand (operands[1], Pmode))
20706 return "call\t%P1";
20707 return "call\t%A1";
20709 [(set_attr "type" "callv")])
20711 (define_insn "*sibcall_value_1_rex64"
20712 [(set (match_operand 0 "" "")
20713 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20714 (match_operand:DI 2 "" "")))]
20715 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20717 [(set_attr "type" "callv")])
20719 (define_insn "*sibcall_value_1_rex64_v"
20720 [(set (match_operand 0 "" "")
20721 (call (mem:QI (reg:DI R11_REG))
20722 (match_operand:DI 1 "" "")))]
20723 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20725 [(set_attr "type" "callv")])
20727 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20728 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20729 ;; caught for use by garbage collectors and the like. Using an insn that
20730 ;; maps to SIGILL makes it more likely the program will rightfully die.
20731 ;; Keeping with tradition, "6" is in honor of #UD.
20732 (define_insn "trap"
20733 [(trap_if (const_int 1) (const_int 6))]
20735 { return ASM_SHORT "0x0b0f"; }
20736 [(set_attr "length" "2")])
20738 (define_expand "sse_prologue_save"
20739 [(parallel [(set (match_operand:BLK 0 "" "")
20740 (unspec:BLK [(reg:DI 21)
20747 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20748 (use (match_operand:DI 1 "register_operand" ""))
20749 (use (match_operand:DI 2 "immediate_operand" ""))
20750 (use (label_ref:DI (match_operand 3 "" "")))])]
20754 (define_insn "*sse_prologue_save_insn"
20755 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20756 (match_operand:DI 4 "const_int_operand" "n")))
20757 (unspec:BLK [(reg:DI 21)
20764 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20765 (use (match_operand:DI 1 "register_operand" "r"))
20766 (use (match_operand:DI 2 "const_int_operand" "i"))
20767 (use (label_ref:DI (match_operand 3 "" "X")))]
20769 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20770 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20774 operands[0] = gen_rtx_MEM (Pmode,
20775 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20776 output_asm_insn (\"jmp\\t%A1\", operands);
20777 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20779 operands[4] = adjust_address (operands[0], DImode, i*16);
20780 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20781 PUT_MODE (operands[4], TImode);
20782 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20783 output_asm_insn (\"rex\", operands);
20784 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20786 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20787 CODE_LABEL_NUMBER (operands[3]));
20791 [(set_attr "type" "other")
20792 (set_attr "length_immediate" "0")
20793 (set_attr "length_address" "0")
20794 (set_attr "length" "135")
20795 (set_attr "memory" "store")
20796 (set_attr "modrm" "0")
20797 (set_attr "mode" "DI")])
20799 (define_expand "prefetch"
20800 [(prefetch (match_operand 0 "address_operand" "")
20801 (match_operand:SI 1 "const_int_operand" "")
20802 (match_operand:SI 2 "const_int_operand" ""))]
20803 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20805 int rw = INTVAL (operands[1]);
20806 int locality = INTVAL (operands[2]);
20808 gcc_assert (rw == 0 || rw == 1);
20809 gcc_assert (locality >= 0 && locality <= 3);
20810 gcc_assert (GET_MODE (operands[0]) == Pmode
20811 || GET_MODE (operands[0]) == VOIDmode);
20813 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20814 supported by SSE counterpart or the SSE prefetch is not available
20815 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20817 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20818 operands[2] = GEN_INT (3);
20820 operands[1] = const0_rtx;
20823 (define_insn "*prefetch_sse"
20824 [(prefetch (match_operand:SI 0 "address_operand" "p")
20826 (match_operand:SI 1 "const_int_operand" ""))]
20827 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20829 static const char * const patterns[4] = {
20830 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20833 int locality = INTVAL (operands[1]);
20834 gcc_assert (locality >= 0 && locality <= 3);
20836 return patterns[locality];
20838 [(set_attr "type" "sse")
20839 (set_attr "memory" "none")])
20841 (define_insn "*prefetch_sse_rex"
20842 [(prefetch (match_operand:DI 0 "address_operand" "p")
20844 (match_operand:SI 1 "const_int_operand" ""))]
20845 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20847 static const char * const patterns[4] = {
20848 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20851 int locality = INTVAL (operands[1]);
20852 gcc_assert (locality >= 0 && locality <= 3);
20854 return patterns[locality];
20856 [(set_attr "type" "sse")
20857 (set_attr "memory" "none")])
20859 (define_insn "*prefetch_3dnow"
20860 [(prefetch (match_operand:SI 0 "address_operand" "p")
20861 (match_operand:SI 1 "const_int_operand" "n")
20863 "TARGET_3DNOW && !TARGET_64BIT"
20865 if (INTVAL (operands[1]) == 0)
20866 return "prefetch\t%a0";
20868 return "prefetchw\t%a0";
20870 [(set_attr "type" "mmx")
20871 (set_attr "memory" "none")])
20873 (define_insn "*prefetch_3dnow_rex"
20874 [(prefetch (match_operand:DI 0 "address_operand" "p")
20875 (match_operand:SI 1 "const_int_operand" "n")
20877 "TARGET_3DNOW && TARGET_64BIT"
20879 if (INTVAL (operands[1]) == 0)
20880 return "prefetch\t%a0";
20882 return "prefetchw\t%a0";
20884 [(set_attr "type" "mmx")
20885 (set_attr "memory" "none")])
20887 (define_expand "stack_protect_set"
20888 [(match_operand 0 "memory_operand" "")
20889 (match_operand 1 "memory_operand" "")]
20892 #ifdef TARGET_THREAD_SSP_OFFSET
20894 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20895 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20897 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20898 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20901 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20903 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20908 (define_insn "stack_protect_set_si"
20909 [(set (match_operand:SI 0 "memory_operand" "=m")
20910 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20911 (set (match_scratch:SI 2 "=&r") (const_int 0))
20912 (clobber (reg:CC FLAGS_REG))]
20914 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20915 [(set_attr "type" "multi")])
20917 (define_insn "stack_protect_set_di"
20918 [(set (match_operand:DI 0 "memory_operand" "=m")
20919 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20920 (set (match_scratch:DI 2 "=&r") (const_int 0))
20921 (clobber (reg:CC FLAGS_REG))]
20923 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20924 [(set_attr "type" "multi")])
20926 (define_insn "stack_tls_protect_set_si"
20927 [(set (match_operand:SI 0 "memory_operand" "=m")
20928 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20929 (set (match_scratch:SI 2 "=&r") (const_int 0))
20930 (clobber (reg:CC FLAGS_REG))]
20932 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20933 [(set_attr "type" "multi")])
20935 (define_insn "stack_tls_protect_set_di"
20936 [(set (match_operand:DI 0 "memory_operand" "=m")
20937 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20938 (set (match_scratch:DI 2 "=&r") (const_int 0))
20939 (clobber (reg:CC FLAGS_REG))]
20942 /* The kernel uses a different segment register for performance reasons; a
20943 system call would not have to trash the userspace segment register,
20944 which would be expensive */
20945 if (ix86_cmodel != CM_KERNEL)
20946 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20948 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20950 [(set_attr "type" "multi")])
20952 (define_expand "stack_protect_test"
20953 [(match_operand 0 "memory_operand" "")
20954 (match_operand 1 "memory_operand" "")
20955 (match_operand 2 "" "")]
20958 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20959 ix86_compare_op0 = operands[0];
20960 ix86_compare_op1 = operands[1];
20961 ix86_compare_emitted = flags;
20963 #ifdef TARGET_THREAD_SSP_OFFSET
20965 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20966 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20968 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20969 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20972 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20974 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20976 emit_jump_insn (gen_beq (operands[2]));
20980 (define_insn "stack_protect_test_si"
20981 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20982 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20983 (match_operand:SI 2 "memory_operand" "m")]
20985 (clobber (match_scratch:SI 3 "=&r"))]
20987 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20988 [(set_attr "type" "multi")])
20990 (define_insn "stack_protect_test_di"
20991 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20992 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20993 (match_operand:DI 2 "memory_operand" "m")]
20995 (clobber (match_scratch:DI 3 "=&r"))]
20997 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20998 [(set_attr "type" "multi")])
21000 (define_insn "stack_tls_protect_test_si"
21001 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21002 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21003 (match_operand:SI 2 "const_int_operand" "i")]
21004 UNSPEC_SP_TLS_TEST))
21005 (clobber (match_scratch:SI 3 "=r"))]
21007 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21008 [(set_attr "type" "multi")])
21010 (define_insn "stack_tls_protect_test_di"
21011 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21012 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21013 (match_operand:DI 2 "const_int_operand" "i")]
21014 UNSPEC_SP_TLS_TEST))
21015 (clobber (match_scratch:DI 3 "=r"))]
21018 /* The kernel uses a different segment register for performance reasons; a
21019 system call would not have to trash the userspace segment register,
21020 which would be expensive */
21021 if (ix86_cmodel != CM_KERNEL)
21022 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21024 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21026 [(set_attr "type" "multi")])
21030 (include "sync.md")