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 ,?*Y,*x")
1191 (match_operand:SI 1 "general_operand"
1192 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*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,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1985 (match_operand:DI 1 "general_operand"
1986 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,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,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2026 (match_operand:DI 1 "general_operand"
2027 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2028 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2030 switch (get_attr_type (insn))
2033 if (which_alternative == 13)
2034 return "movq2dq\t{%1, %0|%0, %1}";
2036 return "movdq2q\t{%1, %0|%0, %1}";
2038 if (get_attr_mode (insn) == MODE_TI)
2039 return "movdqa\t{%1, %0|%0, %1}";
2042 /* Moves from and into integer register is done using movd opcode with
2044 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2045 return "movd\t{%1, %0|%0, %1}";
2046 return "movq\t{%1, %0|%0, %1}";
2049 return "pxor\t%0, %0";
2053 return "lea{q}\t{%a1, %0|%0, %a1}";
2055 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2056 if (get_attr_mode (insn) == MODE_SI)
2057 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2058 else if (which_alternative == 2)
2059 return "movabs{q}\t{%1, %0|%0, %1}";
2061 return "mov{q}\t{%1, %0|%0, %1}";
2065 (cond [(eq_attr "alternative" "5")
2066 (const_string "mmxadd")
2067 (eq_attr "alternative" "6,7,8")
2068 (const_string "mmxmov")
2069 (eq_attr "alternative" "9")
2070 (const_string "sselog1")
2071 (eq_attr "alternative" "10,11,12")
2072 (const_string "ssemov")
2073 (eq_attr "alternative" "13,14")
2074 (const_string "ssecvt")
2075 (eq_attr "alternative" "4")
2076 (const_string "multi")
2077 (match_operand:DI 1 "pic_32bit_operand" "")
2078 (const_string "lea")
2080 (const_string "imov")))
2081 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2082 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2083 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2085 ;; Stores and loads of ax to arbitrary constant address.
2086 ;; We fake an second form of instruction to force reload to load address
2087 ;; into register when rax is not available
2088 (define_insn "*movabsdi_1_rex64"
2089 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2090 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2091 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2093 movabs{q}\t{%1, %P0|%P0, %1}
2094 mov{q}\t{%1, %a0|%a0, %1}"
2095 [(set_attr "type" "imov")
2096 (set_attr "modrm" "0,*")
2097 (set_attr "length_address" "8,0")
2098 (set_attr "length_immediate" "0,*")
2099 (set_attr "memory" "store")
2100 (set_attr "mode" "DI")])
2102 (define_insn "*movabsdi_2_rex64"
2103 [(set (match_operand:DI 0 "register_operand" "=a,r")
2104 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2105 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2107 movabs{q}\t{%P1, %0|%0, %P1}
2108 mov{q}\t{%a1, %0|%0, %a1}"
2109 [(set_attr "type" "imov")
2110 (set_attr "modrm" "0,*")
2111 (set_attr "length_address" "8,0")
2112 (set_attr "length_immediate" "0")
2113 (set_attr "memory" "load")
2114 (set_attr "mode" "DI")])
2116 ;; Convert impossible stores of immediate to existing instructions.
2117 ;; First try to get scratch register and go through it. In case this
2118 ;; fails, move by 32bit parts.
2120 [(match_scratch:DI 2 "r")
2121 (set (match_operand:DI 0 "memory_operand" "")
2122 (match_operand:DI 1 "immediate_operand" ""))]
2123 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2124 && !x86_64_immediate_operand (operands[1], DImode)"
2125 [(set (match_dup 2) (match_dup 1))
2126 (set (match_dup 0) (match_dup 2))]
2129 ;; We need to define this as both peepholer and splitter for case
2130 ;; peephole2 pass is not run.
2131 ;; "&& 1" is needed to keep it from matching the previous pattern.
2133 [(set (match_operand:DI 0 "memory_operand" "")
2134 (match_operand:DI 1 "immediate_operand" ""))]
2135 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2136 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2137 [(set (match_dup 2) (match_dup 3))
2138 (set (match_dup 4) (match_dup 5))]
2139 "split_di (operands, 2, operands + 2, operands + 4);")
2142 [(set (match_operand:DI 0 "memory_operand" "")
2143 (match_operand:DI 1 "immediate_operand" ""))]
2144 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2145 ? flow2_completed : reload_completed)
2146 && !symbolic_operand (operands[1], DImode)
2147 && !x86_64_immediate_operand (operands[1], DImode)"
2148 [(set (match_dup 2) (match_dup 3))
2149 (set (match_dup 4) (match_dup 5))]
2150 "split_di (operands, 2, operands + 2, operands + 4);")
2152 (define_insn "*swapdi_rex64"
2153 [(set (match_operand:DI 0 "register_operand" "+r")
2154 (match_operand:DI 1 "register_operand" "+r"))
2159 [(set_attr "type" "imov")
2160 (set_attr "mode" "DI")
2161 (set_attr "pent_pair" "np")
2162 (set_attr "athlon_decode" "vector")
2163 (set_attr "amdfam10_decode" "double")])
2165 (define_expand "movti"
2166 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2167 (match_operand:TI 1 "nonimmediate_operand" ""))]
2168 "TARGET_SSE || TARGET_64BIT"
2171 ix86_expand_move (TImode, operands);
2173 ix86_expand_vector_move (TImode, operands);
2177 (define_insn "*movti_internal"
2178 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2179 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2180 "TARGET_SSE && !TARGET_64BIT
2181 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2183 switch (which_alternative)
2186 if (get_attr_mode (insn) == MODE_V4SF)
2187 return "xorps\t%0, %0";
2189 return "pxor\t%0, %0";
2192 if (get_attr_mode (insn) == MODE_V4SF)
2193 return "movaps\t{%1, %0|%0, %1}";
2195 return "movdqa\t{%1, %0|%0, %1}";
2200 [(set_attr "type" "sselog1,ssemov,ssemov")
2202 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2203 (ne (symbol_ref "optimize_size") (const_int 0)))
2204 (const_string "V4SF")
2205 (and (eq_attr "alternative" "2")
2206 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2208 (const_string "V4SF")]
2209 (const_string "TI")))])
2211 (define_insn "*movti_rex64"
2212 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2213 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2215 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2217 switch (which_alternative)
2223 if (get_attr_mode (insn) == MODE_V4SF)
2224 return "xorps\t%0, %0";
2226 return "pxor\t%0, %0";
2229 if (get_attr_mode (insn) == MODE_V4SF)
2230 return "movaps\t{%1, %0|%0, %1}";
2232 return "movdqa\t{%1, %0|%0, %1}";
2237 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2239 (cond [(eq_attr "alternative" "2,3")
2241 (ne (symbol_ref "optimize_size")
2243 (const_string "V4SF")
2244 (const_string "TI"))
2245 (eq_attr "alternative" "4")
2247 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2249 (ne (symbol_ref "optimize_size")
2251 (const_string "V4SF")
2252 (const_string "TI"))]
2253 (const_string "DI")))])
2256 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2257 (match_operand:TI 1 "general_operand" ""))]
2258 "reload_completed && !SSE_REG_P (operands[0])
2259 && !SSE_REG_P (operands[1])"
2261 "ix86_split_long_move (operands); DONE;")
2263 (define_expand "movsf"
2264 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2265 (match_operand:SF 1 "general_operand" ""))]
2267 "ix86_expand_move (SFmode, operands); DONE;")
2269 (define_insn "*pushsf"
2270 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2271 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2274 /* Anything else should be already split before reg-stack. */
2275 gcc_assert (which_alternative == 1);
2276 return "push{l}\t%1";
2278 [(set_attr "type" "multi,push,multi")
2279 (set_attr "unit" "i387,*,*")
2280 (set_attr "mode" "SF,SI,SF")])
2282 (define_insn "*pushsf_rex64"
2283 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2284 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2287 /* Anything else should be already split before reg-stack. */
2288 gcc_assert (which_alternative == 1);
2289 return "push{q}\t%q1";
2291 [(set_attr "type" "multi,push,multi")
2292 (set_attr "unit" "i387,*,*")
2293 (set_attr "mode" "SF,DI,SF")])
2296 [(set (match_operand:SF 0 "push_operand" "")
2297 (match_operand:SF 1 "memory_operand" ""))]
2299 && MEM_P (operands[1])
2300 && constant_pool_reference_p (operands[1])"
2303 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2306 ;; %%% Kill this when call knows how to work this out.
2308 [(set (match_operand:SF 0 "push_operand" "")
2309 (match_operand:SF 1 "any_fp_register_operand" ""))]
2311 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2312 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2315 [(set (match_operand:SF 0 "push_operand" "")
2316 (match_operand:SF 1 "any_fp_register_operand" ""))]
2318 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2319 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2321 (define_insn "*movsf_1"
2322 [(set (match_operand:SF 0 "nonimmediate_operand"
2323 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2324 (match_operand:SF 1 "general_operand"
2325 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2326 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2327 && (reload_in_progress || reload_completed
2328 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2329 || (!TARGET_SSE_MATH && optimize_size
2330 && standard_80387_constant_p (operands[1]))
2331 || GET_CODE (operands[1]) != CONST_DOUBLE
2332 || memory_operand (operands[0], SFmode))"
2334 switch (which_alternative)
2337 return output_387_reg_move (insn, operands);
2340 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2341 return "fstp%z0\t%y0";
2343 return "fst%z0\t%y0";
2346 return standard_80387_constant_opcode (operands[1]);
2350 return "mov{l}\t{%1, %0|%0, %1}";
2352 if (get_attr_mode (insn) == MODE_TI)
2353 return "pxor\t%0, %0";
2355 return "xorps\t%0, %0";
2357 if (get_attr_mode (insn) == MODE_V4SF)
2358 return "movaps\t{%1, %0|%0, %1}";
2360 return "movss\t{%1, %0|%0, %1}";
2363 return "movss\t{%1, %0|%0, %1}";
2367 return "movd\t{%1, %0|%0, %1}";
2370 return "movq\t{%1, %0|%0, %1}";
2376 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2378 (cond [(eq_attr "alternative" "3,4,9,10")
2380 (eq_attr "alternative" "5")
2382 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2384 (ne (symbol_ref "TARGET_SSE2")
2386 (eq (symbol_ref "optimize_size")
2389 (const_string "V4SF"))
2390 /* For architectures resolving dependencies on
2391 whole SSE registers use APS move to break dependency
2392 chains, otherwise use short move to avoid extra work.
2394 Do the same for architectures resolving dependencies on
2395 the parts. While in DF mode it is better to always handle
2396 just register parts, the SF mode is different due to lack
2397 of instructions to load just part of the register. It is
2398 better to maintain the whole registers in single format
2399 to avoid problems on using packed logical operations. */
2400 (eq_attr "alternative" "6")
2402 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2404 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2406 (const_string "V4SF")
2407 (const_string "SF"))
2408 (eq_attr "alternative" "11")
2409 (const_string "DI")]
2410 (const_string "SF")))])
2412 (define_insn "*swapsf"
2413 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2414 (match_operand:SF 1 "fp_register_operand" "+f"))
2417 "reload_completed || TARGET_80387"
2419 if (STACK_TOP_P (operands[0]))
2424 [(set_attr "type" "fxch")
2425 (set_attr "mode" "SF")])
2427 (define_expand "movdf"
2428 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2429 (match_operand:DF 1 "general_operand" ""))]
2431 "ix86_expand_move (DFmode, operands); DONE;")
2433 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2434 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2435 ;; On the average, pushdf using integers can be still shorter. Allow this
2436 ;; pattern for optimize_size too.
2438 (define_insn "*pushdf_nointeger"
2439 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2440 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2441 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2443 /* This insn should be already split before reg-stack. */
2446 [(set_attr "type" "multi")
2447 (set_attr "unit" "i387,*,*,*")
2448 (set_attr "mode" "DF,SI,SI,DF")])
2450 (define_insn "*pushdf_integer"
2451 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2452 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2453 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2455 /* This insn should be already split before reg-stack. */
2458 [(set_attr "type" "multi")
2459 (set_attr "unit" "i387,*,*")
2460 (set_attr "mode" "DF,SI,DF")])
2462 ;; %%% Kill this when call knows how to work this out.
2464 [(set (match_operand:DF 0 "push_operand" "")
2465 (match_operand:DF 1 "any_fp_register_operand" ""))]
2466 "!TARGET_64BIT && reload_completed"
2467 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2468 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2472 [(set (match_operand:DF 0 "push_operand" "")
2473 (match_operand:DF 1 "any_fp_register_operand" ""))]
2474 "TARGET_64BIT && reload_completed"
2475 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2476 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2480 [(set (match_operand:DF 0 "push_operand" "")
2481 (match_operand:DF 1 "general_operand" ""))]
2484 "ix86_split_long_move (operands); DONE;")
2486 ;; Moving is usually shorter when only FP registers are used. This separate
2487 ;; movdf pattern avoids the use of integer registers for FP operations
2488 ;; when optimizing for size.
2490 (define_insn "*movdf_nointeger"
2491 [(set (match_operand:DF 0 "nonimmediate_operand"
2492 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2493 (match_operand:DF 1 "general_operand"
2494 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2495 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2496 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2497 && (reload_in_progress || reload_completed
2498 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2499 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2500 && standard_80387_constant_p (operands[1]))
2501 || GET_CODE (operands[1]) != CONST_DOUBLE
2502 || memory_operand (operands[0], DFmode))"
2504 switch (which_alternative)
2507 return output_387_reg_move (insn, operands);
2510 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2511 return "fstp%z0\t%y0";
2513 return "fst%z0\t%y0";
2516 return standard_80387_constant_opcode (operands[1]);
2522 switch (get_attr_mode (insn))
2525 return "xorps\t%0, %0";
2527 return "xorpd\t%0, %0";
2529 return "pxor\t%0, %0";
2536 switch (get_attr_mode (insn))
2539 return "movaps\t{%1, %0|%0, %1}";
2541 return "movapd\t{%1, %0|%0, %1}";
2543 return "movdqa\t{%1, %0|%0, %1}";
2545 return "movq\t{%1, %0|%0, %1}";
2547 return "movsd\t{%1, %0|%0, %1}";
2549 return "movlpd\t{%1, %0|%0, %1}";
2551 return "movlps\t{%1, %0|%0, %1}";
2560 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2562 (cond [(eq_attr "alternative" "0,1,2")
2564 (eq_attr "alternative" "3,4")
2567 /* For SSE1, we have many fewer alternatives. */
2568 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2569 (cond [(eq_attr "alternative" "5,6")
2570 (const_string "V4SF")
2572 (const_string "V2SF"))
2574 /* xorps is one byte shorter. */
2575 (eq_attr "alternative" "5")
2576 (cond [(ne (symbol_ref "optimize_size")
2578 (const_string "V4SF")
2579 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2583 (const_string "V2DF"))
2585 /* For architectures resolving dependencies on
2586 whole SSE registers use APD move to break dependency
2587 chains, otherwise use short move to avoid extra work.
2589 movaps encodes one byte shorter. */
2590 (eq_attr "alternative" "6")
2592 [(ne (symbol_ref "optimize_size")
2594 (const_string "V4SF")
2595 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2597 (const_string "V2DF")
2599 (const_string "DF"))
2600 /* For architectures resolving dependencies on register
2601 parts we may avoid extra work to zero out upper part
2603 (eq_attr "alternative" "7")
2605 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2607 (const_string "V1DF")
2608 (const_string "DF"))
2610 (const_string "DF")))])
2612 (define_insn "*movdf_integer"
2613 [(set (match_operand:DF 0 "nonimmediate_operand"
2614 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2615 (match_operand:DF 1 "general_operand"
2616 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2617 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2618 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2619 && (reload_in_progress || reload_completed
2620 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2621 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2622 && standard_80387_constant_p (operands[1]))
2623 || GET_CODE (operands[1]) != CONST_DOUBLE
2624 || memory_operand (operands[0], DFmode))"
2626 switch (which_alternative)
2629 return output_387_reg_move (insn, operands);
2632 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2633 return "fstp%z0\t%y0";
2635 return "fst%z0\t%y0";
2638 return standard_80387_constant_opcode (operands[1]);
2645 switch (get_attr_mode (insn))
2648 return "xorps\t%0, %0";
2650 return "xorpd\t%0, %0";
2652 return "pxor\t%0, %0";
2659 switch (get_attr_mode (insn))
2662 return "movaps\t{%1, %0|%0, %1}";
2664 return "movapd\t{%1, %0|%0, %1}";
2666 return "movdqa\t{%1, %0|%0, %1}";
2668 return "movq\t{%1, %0|%0, %1}";
2670 return "movsd\t{%1, %0|%0, %1}";
2672 return "movlpd\t{%1, %0|%0, %1}";
2674 return "movlps\t{%1, %0|%0, %1}";
2683 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2685 (cond [(eq_attr "alternative" "0,1,2")
2687 (eq_attr "alternative" "3,4")
2690 /* For SSE1, we have many fewer alternatives. */
2691 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2692 (cond [(eq_attr "alternative" "5,6")
2693 (const_string "V4SF")
2695 (const_string "V2SF"))
2697 /* xorps is one byte shorter. */
2698 (eq_attr "alternative" "5")
2699 (cond [(ne (symbol_ref "optimize_size")
2701 (const_string "V4SF")
2702 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2706 (const_string "V2DF"))
2708 /* For architectures resolving dependencies on
2709 whole SSE registers use APD move to break dependency
2710 chains, otherwise use short move to avoid extra work.
2712 movaps encodes one byte shorter. */
2713 (eq_attr "alternative" "6")
2715 [(ne (symbol_ref "optimize_size")
2717 (const_string "V4SF")
2718 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2720 (const_string "V2DF")
2722 (const_string "DF"))
2723 /* For architectures resolving dependencies on register
2724 parts we may avoid extra work to zero out upper part
2726 (eq_attr "alternative" "7")
2728 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2730 (const_string "V1DF")
2731 (const_string "DF"))
2733 (const_string "DF")))])
2736 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2737 (match_operand:DF 1 "general_operand" ""))]
2739 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2740 && ! (ANY_FP_REG_P (operands[0]) ||
2741 (GET_CODE (operands[0]) == SUBREG
2742 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2743 && ! (ANY_FP_REG_P (operands[1]) ||
2744 (GET_CODE (operands[1]) == SUBREG
2745 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2747 "ix86_split_long_move (operands); DONE;")
2749 (define_insn "*swapdf"
2750 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2751 (match_operand:DF 1 "fp_register_operand" "+f"))
2754 "reload_completed || TARGET_80387"
2756 if (STACK_TOP_P (operands[0]))
2761 [(set_attr "type" "fxch")
2762 (set_attr "mode" "DF")])
2764 (define_expand "movxf"
2765 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2766 (match_operand:XF 1 "general_operand" ""))]
2768 "ix86_expand_move (XFmode, operands); DONE;")
2770 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2771 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2772 ;; Pushing using integer instructions is longer except for constants
2773 ;; and direct memory references.
2774 ;; (assuming that any given constant is pushed only once, but this ought to be
2775 ;; handled elsewhere).
2777 (define_insn "*pushxf_nointeger"
2778 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2779 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2782 /* This insn should be already split before reg-stack. */
2785 [(set_attr "type" "multi")
2786 (set_attr "unit" "i387,*,*")
2787 (set_attr "mode" "XF,SI,SI")])
2789 (define_insn "*pushxf_integer"
2790 [(set (match_operand:XF 0 "push_operand" "=<,<")
2791 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2794 /* This insn should be already split before reg-stack. */
2797 [(set_attr "type" "multi")
2798 (set_attr "unit" "i387,*")
2799 (set_attr "mode" "XF,SI")])
2802 [(set (match_operand 0 "push_operand" "")
2803 (match_operand 1 "general_operand" ""))]
2805 && (GET_MODE (operands[0]) == XFmode
2806 || GET_MODE (operands[0]) == DFmode)
2807 && !ANY_FP_REG_P (operands[1])"
2809 "ix86_split_long_move (operands); DONE;")
2812 [(set (match_operand:XF 0 "push_operand" "")
2813 (match_operand:XF 1 "any_fp_register_operand" ""))]
2815 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2816 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2817 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2820 [(set (match_operand:XF 0 "push_operand" "")
2821 (match_operand:XF 1 "any_fp_register_operand" ""))]
2823 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2824 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2825 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2827 ;; Do not use integer registers when optimizing for size
2828 (define_insn "*movxf_nointeger"
2829 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2830 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2832 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2833 && (reload_in_progress || reload_completed
2834 || (optimize_size && standard_80387_constant_p (operands[1]))
2835 || GET_CODE (operands[1]) != CONST_DOUBLE
2836 || memory_operand (operands[0], XFmode))"
2838 switch (which_alternative)
2841 return output_387_reg_move (insn, operands);
2844 /* There is no non-popping store to memory for XFmode. So if
2845 we need one, follow the store with a load. */
2846 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2847 return "fstp%z0\t%y0\;fld%z0\t%y0";
2849 return "fstp%z0\t%y0";
2852 return standard_80387_constant_opcode (operands[1]);
2860 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2861 (set_attr "mode" "XF,XF,XF,SI,SI")])
2863 (define_insn "*movxf_integer"
2864 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2865 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2867 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2868 && (reload_in_progress || reload_completed
2869 || (optimize_size && standard_80387_constant_p (operands[1]))
2870 || GET_CODE (operands[1]) != CONST_DOUBLE
2871 || memory_operand (operands[0], XFmode))"
2873 switch (which_alternative)
2876 return output_387_reg_move (insn, operands);
2879 /* There is no non-popping store to memory for XFmode. So if
2880 we need one, follow the store with a load. */
2881 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2882 return "fstp%z0\t%y0\;fld%z0\t%y0";
2884 return "fstp%z0\t%y0";
2887 return standard_80387_constant_opcode (operands[1]);
2896 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2897 (set_attr "mode" "XF,XF,XF,SI,SI")])
2900 [(set (match_operand 0 "nonimmediate_operand" "")
2901 (match_operand 1 "general_operand" ""))]
2903 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2904 && GET_MODE (operands[0]) == XFmode
2905 && ! (ANY_FP_REG_P (operands[0]) ||
2906 (GET_CODE (operands[0]) == SUBREG
2907 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2908 && ! (ANY_FP_REG_P (operands[1]) ||
2909 (GET_CODE (operands[1]) == SUBREG
2910 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2912 "ix86_split_long_move (operands); DONE;")
2915 [(set (match_operand 0 "register_operand" "")
2916 (match_operand 1 "memory_operand" ""))]
2918 && MEM_P (operands[1])
2919 && (GET_MODE (operands[0]) == XFmode
2920 || GET_MODE (operands[0]) == SFmode
2921 || GET_MODE (operands[0]) == DFmode)
2922 && constant_pool_reference_p (operands[1])"
2923 [(set (match_dup 0) (match_dup 1))]
2925 rtx c = avoid_constant_pool_reference (operands[1]);
2926 rtx r = operands[0];
2928 if (GET_CODE (r) == SUBREG)
2933 if (!standard_sse_constant_p (c))
2936 else if (FP_REG_P (r))
2938 if (!standard_80387_constant_p (c))
2941 else if (MMX_REG_P (r))
2948 [(set (match_operand 0 "register_operand" "")
2949 (float_extend (match_operand 1 "memory_operand" "")))]
2951 && MEM_P (operands[1])
2952 && (GET_MODE (operands[0]) == XFmode
2953 || GET_MODE (operands[0]) == SFmode
2954 || GET_MODE (operands[0]) == DFmode)
2955 && constant_pool_reference_p (operands[1])"
2956 [(set (match_dup 0) (match_dup 1))]
2958 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2959 rtx r = operands[0];
2961 if (GET_CODE (r) == SUBREG)
2966 if (!standard_sse_constant_p (c))
2969 else if (FP_REG_P (r))
2971 if (!standard_80387_constant_p (c))
2974 else if (MMX_REG_P (r))
2980 (define_insn "swapxf"
2981 [(set (match_operand:XF 0 "register_operand" "+f")
2982 (match_operand:XF 1 "register_operand" "+f"))
2987 if (STACK_TOP_P (operands[0]))
2992 [(set_attr "type" "fxch")
2993 (set_attr "mode" "XF")])
2995 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2997 [(set (match_operand:X87MODEF 0 "register_operand" "")
2998 (match_operand:X87MODEF 1 "immediate_operand" ""))]
2999 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3000 && (standard_80387_constant_p (operands[1]) == 8
3001 || standard_80387_constant_p (operands[1]) == 9)"
3002 [(set (match_dup 0)(match_dup 1))
3004 (neg:X87MODEF (match_dup 0)))]
3008 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3009 if (real_isnegzero (&r))
3010 operands[1] = CONST0_RTX (<MODE>mode);
3012 operands[1] = CONST1_RTX (<MODE>mode);
3015 (define_expand "movtf"
3016 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3017 (match_operand:TF 1 "nonimmediate_operand" ""))]
3020 ix86_expand_move (TFmode, operands);
3024 (define_insn "*movtf_internal"
3025 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3026 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3028 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3030 switch (which_alternative)
3036 if (get_attr_mode (insn) == MODE_V4SF)
3037 return "xorps\t%0, %0";
3039 return "pxor\t%0, %0";
3042 if (get_attr_mode (insn) == MODE_V4SF)
3043 return "movaps\t{%1, %0|%0, %1}";
3045 return "movdqa\t{%1, %0|%0, %1}";
3050 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3052 (cond [(eq_attr "alternative" "2,3")
3054 (ne (symbol_ref "optimize_size")
3056 (const_string "V4SF")
3057 (const_string "TI"))
3058 (eq_attr "alternative" "4")
3060 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3062 (ne (symbol_ref "optimize_size")
3064 (const_string "V4SF")
3065 (const_string "TI"))]
3066 (const_string "DI")))])
3069 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3070 (match_operand:TF 1 "general_operand" ""))]
3071 "reload_completed && !SSE_REG_P (operands[0])
3072 && !SSE_REG_P (operands[1])"
3074 "ix86_split_long_move (operands); DONE;")
3076 ;; Zero extension instructions
3078 (define_expand "zero_extendhisi2"
3079 [(set (match_operand:SI 0 "register_operand" "")
3080 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3083 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3085 operands[1] = force_reg (HImode, operands[1]);
3086 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3091 (define_insn "zero_extendhisi2_and"
3092 [(set (match_operand:SI 0 "register_operand" "=r")
3093 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3094 (clobber (reg:CC FLAGS_REG))]
3095 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3097 [(set_attr "type" "alu1")
3098 (set_attr "mode" "SI")])
3101 [(set (match_operand:SI 0 "register_operand" "")
3102 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3103 (clobber (reg:CC FLAGS_REG))]
3104 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3105 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3106 (clobber (reg:CC FLAGS_REG))])]
3109 (define_insn "*zero_extendhisi2_movzwl"
3110 [(set (match_operand:SI 0 "register_operand" "=r")
3111 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3112 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3113 "movz{wl|x}\t{%1, %0|%0, %1}"
3114 [(set_attr "type" "imovx")
3115 (set_attr "mode" "SI")])
3117 (define_expand "zero_extendqihi2"
3119 [(set (match_operand:HI 0 "register_operand" "")
3120 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3121 (clobber (reg:CC FLAGS_REG))])]
3125 (define_insn "*zero_extendqihi2_and"
3126 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3127 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3128 (clobber (reg:CC FLAGS_REG))]
3129 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3131 [(set_attr "type" "alu1")
3132 (set_attr "mode" "HI")])
3134 (define_insn "*zero_extendqihi2_movzbw_and"
3135 [(set (match_operand:HI 0 "register_operand" "=r,r")
3136 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3137 (clobber (reg:CC FLAGS_REG))]
3138 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3140 [(set_attr "type" "imovx,alu1")
3141 (set_attr "mode" "HI")])
3143 ; zero extend to SImode here to avoid partial register stalls
3144 (define_insn "*zero_extendqihi2_movzbl"
3145 [(set (match_operand:HI 0 "register_operand" "=r")
3146 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3147 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3148 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3149 [(set_attr "type" "imovx")
3150 (set_attr "mode" "SI")])
3152 ;; For the movzbw case strip only the clobber
3154 [(set (match_operand:HI 0 "register_operand" "")
3155 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3156 (clobber (reg:CC FLAGS_REG))]
3158 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3159 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3160 [(set (match_operand:HI 0 "register_operand" "")
3161 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3163 ;; When source and destination does not overlap, clear destination
3164 ;; first and then do the movb
3166 [(set (match_operand:HI 0 "register_operand" "")
3167 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3168 (clobber (reg:CC FLAGS_REG))]
3170 && ANY_QI_REG_P (operands[0])
3171 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3172 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3173 [(set (match_dup 0) (const_int 0))
3174 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3175 "operands[2] = gen_lowpart (QImode, operands[0]);")
3177 ;; Rest is handled by single and.
3179 [(set (match_operand:HI 0 "register_operand" "")
3180 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3181 (clobber (reg:CC FLAGS_REG))]
3183 && true_regnum (operands[0]) == true_regnum (operands[1])"
3184 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3185 (clobber (reg:CC FLAGS_REG))])]
3188 (define_expand "zero_extendqisi2"
3190 [(set (match_operand:SI 0 "register_operand" "")
3191 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3192 (clobber (reg:CC FLAGS_REG))])]
3196 (define_insn "*zero_extendqisi2_and"
3197 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3198 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3199 (clobber (reg:CC FLAGS_REG))]
3200 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3202 [(set_attr "type" "alu1")
3203 (set_attr "mode" "SI")])
3205 (define_insn "*zero_extendqisi2_movzbw_and"
3206 [(set (match_operand:SI 0 "register_operand" "=r,r")
3207 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3208 (clobber (reg:CC FLAGS_REG))]
3209 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3211 [(set_attr "type" "imovx,alu1")
3212 (set_attr "mode" "SI")])
3214 (define_insn "*zero_extendqisi2_movzbw"
3215 [(set (match_operand:SI 0 "register_operand" "=r")
3216 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3217 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3218 "movz{bl|x}\t{%1, %0|%0, %1}"
3219 [(set_attr "type" "imovx")
3220 (set_attr "mode" "SI")])
3222 ;; For the movzbl case strip only the clobber
3224 [(set (match_operand:SI 0 "register_operand" "")
3225 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3226 (clobber (reg:CC FLAGS_REG))]
3228 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3229 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3231 (zero_extend:SI (match_dup 1)))])
3233 ;; When source and destination does not overlap, clear destination
3234 ;; first and then do the movb
3236 [(set (match_operand:SI 0 "register_operand" "")
3237 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3238 (clobber (reg:CC FLAGS_REG))]
3240 && ANY_QI_REG_P (operands[0])
3241 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3242 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3243 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3244 [(set (match_dup 0) (const_int 0))
3245 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3246 "operands[2] = gen_lowpart (QImode, operands[0]);")
3248 ;; Rest is handled by single and.
3250 [(set (match_operand:SI 0 "register_operand" "")
3251 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3252 (clobber (reg:CC FLAGS_REG))]
3254 && true_regnum (operands[0]) == true_regnum (operands[1])"
3255 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3256 (clobber (reg:CC FLAGS_REG))])]
3259 ;; %%% Kill me once multi-word ops are sane.
3260 (define_expand "zero_extendsidi2"
3261 [(set (match_operand:DI 0 "register_operand" "=r")
3262 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3266 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3271 (define_insn "zero_extendsidi2_32"
3272 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3273 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3274 (clobber (reg:CC FLAGS_REG))]
3280 movd\t{%1, %0|%0, %1}
3281 movd\t{%1, %0|%0, %1}"
3282 [(set_attr "mode" "SI,SI,SI,DI,TI")
3283 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3285 (define_insn "zero_extendsidi2_rex64"
3286 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3287 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3290 mov\t{%k1, %k0|%k0, %k1}
3292 movd\t{%1, %0|%0, %1}
3293 movd\t{%1, %0|%0, %1}"
3294 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3295 (set_attr "mode" "SI,DI,SI,SI")])
3298 [(set (match_operand:DI 0 "memory_operand" "")
3299 (zero_extend:DI (match_dup 0)))]
3301 [(set (match_dup 4) (const_int 0))]
3302 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3305 [(set (match_operand:DI 0 "register_operand" "")
3306 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3307 (clobber (reg:CC FLAGS_REG))]
3308 "!TARGET_64BIT && reload_completed
3309 && true_regnum (operands[0]) == true_regnum (operands[1])"
3310 [(set (match_dup 4) (const_int 0))]
3311 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3314 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3315 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3316 (clobber (reg:CC FLAGS_REG))]
3317 "!TARGET_64BIT && reload_completed
3318 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3319 [(set (match_dup 3) (match_dup 1))
3320 (set (match_dup 4) (const_int 0))]
3321 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3323 (define_insn "zero_extendhidi2"
3324 [(set (match_operand:DI 0 "register_operand" "=r")
3325 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3327 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3328 [(set_attr "type" "imovx")
3329 (set_attr "mode" "DI")])
3331 (define_insn "zero_extendqidi2"
3332 [(set (match_operand:DI 0 "register_operand" "=r")
3333 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3335 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3336 [(set_attr "type" "imovx")
3337 (set_attr "mode" "DI")])
3339 ;; Sign extension instructions
3341 (define_expand "extendsidi2"
3342 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3343 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3344 (clobber (reg:CC FLAGS_REG))
3345 (clobber (match_scratch:SI 2 ""))])]
3350 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3355 (define_insn "*extendsidi2_1"
3356 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3357 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3358 (clobber (reg:CC FLAGS_REG))
3359 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3363 (define_insn "extendsidi2_rex64"
3364 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3365 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3369 movs{lq|x}\t{%1,%0|%0, %1}"
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "DI")
3372 (set_attr "prefix_0f" "0")
3373 (set_attr "modrm" "0,1")])
3375 (define_insn "extendhidi2"
3376 [(set (match_operand:DI 0 "register_operand" "=r")
3377 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3379 "movs{wq|x}\t{%1,%0|%0, %1}"
3380 [(set_attr "type" "imovx")
3381 (set_attr "mode" "DI")])
3383 (define_insn "extendqidi2"
3384 [(set (match_operand:DI 0 "register_operand" "=r")
3385 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3387 "movs{bq|x}\t{%1,%0|%0, %1}"
3388 [(set_attr "type" "imovx")
3389 (set_attr "mode" "DI")])
3391 ;; Extend to memory case when source register does die.
3393 [(set (match_operand:DI 0 "memory_operand" "")
3394 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3395 (clobber (reg:CC FLAGS_REG))
3396 (clobber (match_operand:SI 2 "register_operand" ""))]
3398 && dead_or_set_p (insn, operands[1])
3399 && !reg_mentioned_p (operands[1], operands[0]))"
3400 [(set (match_dup 3) (match_dup 1))
3401 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3402 (clobber (reg:CC FLAGS_REG))])
3403 (set (match_dup 4) (match_dup 1))]
3404 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3406 ;; Extend to memory case when source register does not die.
3408 [(set (match_operand:DI 0 "memory_operand" "")
3409 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3410 (clobber (reg:CC FLAGS_REG))
3411 (clobber (match_operand:SI 2 "register_operand" ""))]
3415 split_di (&operands[0], 1, &operands[3], &operands[4]);
3417 emit_move_insn (operands[3], operands[1]);
3419 /* Generate a cltd if possible and doing so it profitable. */
3420 if (true_regnum (operands[1]) == 0
3421 && true_regnum (operands[2]) == 1
3422 && (optimize_size || TARGET_USE_CLTD))
3424 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3428 emit_move_insn (operands[2], operands[1]);
3429 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3431 emit_move_insn (operands[4], operands[2]);
3435 ;; Extend to register case. Optimize case where source and destination
3436 ;; registers match and cases where we can use cltd.
3438 [(set (match_operand:DI 0 "register_operand" "")
3439 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3440 (clobber (reg:CC FLAGS_REG))
3441 (clobber (match_scratch:SI 2 ""))]
3445 split_di (&operands[0], 1, &operands[3], &operands[4]);
3447 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3448 emit_move_insn (operands[3], operands[1]);
3450 /* Generate a cltd if possible and doing so it profitable. */
3451 if (true_regnum (operands[3]) == 0
3452 && (optimize_size || TARGET_USE_CLTD))
3454 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3458 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3459 emit_move_insn (operands[4], operands[1]);
3461 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3465 (define_insn "extendhisi2"
3466 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3467 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3470 switch (get_attr_prefix_0f (insn))
3473 return "{cwtl|cwde}";
3475 return "movs{wl|x}\t{%1,%0|%0, %1}";
3478 [(set_attr "type" "imovx")
3479 (set_attr "mode" "SI")
3480 (set (attr "prefix_0f")
3481 ;; movsx is short decodable while cwtl is vector decoded.
3482 (if_then_else (and (eq_attr "cpu" "!k6")
3483 (eq_attr "alternative" "0"))
3485 (const_string "1")))
3487 (if_then_else (eq_attr "prefix_0f" "0")
3489 (const_string "1")))])
3491 (define_insn "*extendhisi2_zext"
3492 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3494 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3497 switch (get_attr_prefix_0f (insn))
3500 return "{cwtl|cwde}";
3502 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3505 [(set_attr "type" "imovx")
3506 (set_attr "mode" "SI")
3507 (set (attr "prefix_0f")
3508 ;; movsx is short decodable while cwtl is vector decoded.
3509 (if_then_else (and (eq_attr "cpu" "!k6")
3510 (eq_attr "alternative" "0"))
3512 (const_string "1")))
3514 (if_then_else (eq_attr "prefix_0f" "0")
3516 (const_string "1")))])
3518 (define_insn "extendqihi2"
3519 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3520 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3523 switch (get_attr_prefix_0f (insn))
3526 return "{cbtw|cbw}";
3528 return "movs{bw|x}\t{%1,%0|%0, %1}";
3531 [(set_attr "type" "imovx")
3532 (set_attr "mode" "HI")
3533 (set (attr "prefix_0f")
3534 ;; movsx is short decodable while cwtl is vector decoded.
3535 (if_then_else (and (eq_attr "cpu" "!k6")
3536 (eq_attr "alternative" "0"))
3538 (const_string "1")))
3540 (if_then_else (eq_attr "prefix_0f" "0")
3542 (const_string "1")))])
3544 (define_insn "extendqisi2"
3545 [(set (match_operand:SI 0 "register_operand" "=r")
3546 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3548 "movs{bl|x}\t{%1,%0|%0, %1}"
3549 [(set_attr "type" "imovx")
3550 (set_attr "mode" "SI")])
3552 (define_insn "*extendqisi2_zext"
3553 [(set (match_operand:DI 0 "register_operand" "=r")
3555 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3557 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3558 [(set_attr "type" "imovx")
3559 (set_attr "mode" "SI")])
3561 ;; Conversions between float and double.
3563 ;; These are all no-ops in the model used for the 80387. So just
3566 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3567 (define_insn "*dummy_extendsfdf2"
3568 [(set (match_operand:DF 0 "push_operand" "=<")
3569 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3574 [(set (match_operand:DF 0 "push_operand" "")
3575 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3577 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3578 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3581 [(set (match_operand:DF 0 "push_operand" "")
3582 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3584 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3585 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3587 (define_insn "*dummy_extendsfxf2"
3588 [(set (match_operand:XF 0 "push_operand" "=<")
3589 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3594 [(set (match_operand:XF 0 "push_operand" "")
3595 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3597 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3598 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3599 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3602 [(set (match_operand:XF 0 "push_operand" "")
3603 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3605 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3606 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3607 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3610 [(set (match_operand:XF 0 "push_operand" "")
3611 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3613 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3614 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3615 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3618 [(set (match_operand:XF 0 "push_operand" "")
3619 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3621 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3622 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3623 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3625 (define_expand "extendsfdf2"
3626 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3627 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3628 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3630 /* ??? Needed for compress_float_constant since all fp constants
3631 are LEGITIMATE_CONSTANT_P. */
3632 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3634 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3635 && standard_80387_constant_p (operands[1]) > 0)
3637 operands[1] = simplify_const_unary_operation
3638 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3639 emit_move_insn_1 (operands[0], operands[1]);
3642 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3646 (define_insn "*extendsfdf2_mixed"
3647 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3648 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3649 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3651 switch (which_alternative)
3654 return output_387_reg_move (insn, operands);
3657 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3658 return "fstp%z0\t%y0";
3660 return "fst%z0\t%y0";
3663 return "cvtss2sd\t{%1, %0|%0, %1}";
3669 [(set_attr "type" "fmov,fmov,ssecvt")
3670 (set_attr "mode" "SF,XF,DF")])
3672 (define_insn "*extendsfdf2_sse"
3673 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3674 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3675 "TARGET_SSE2 && TARGET_SSE_MATH"
3676 "cvtss2sd\t{%1, %0|%0, %1}"
3677 [(set_attr "type" "ssecvt")
3678 (set_attr "mode" "DF")])
3680 (define_insn "*extendsfdf2_i387"
3681 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3682 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3685 switch (which_alternative)
3688 return output_387_reg_move (insn, operands);
3691 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3692 return "fstp%z0\t%y0";
3694 return "fst%z0\t%y0";
3700 [(set_attr "type" "fmov")
3701 (set_attr "mode" "SF,XF")])
3703 (define_expand "extendsfxf2"
3704 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3705 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3708 /* ??? Needed for compress_float_constant since all fp constants
3709 are LEGITIMATE_CONSTANT_P. */
3710 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3712 if (standard_80387_constant_p (operands[1]) > 0)
3714 operands[1] = simplify_const_unary_operation
3715 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3716 emit_move_insn_1 (operands[0], operands[1]);
3719 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3723 (define_insn "*extendsfxf2_i387"
3724 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3725 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3728 switch (which_alternative)
3731 return output_387_reg_move (insn, operands);
3734 /* There is no non-popping store to memory for XFmode. So if
3735 we need one, follow the store with a load. */
3736 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3737 return "fstp%z0\t%y0";
3739 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3745 [(set_attr "type" "fmov")
3746 (set_attr "mode" "SF,XF")])
3748 (define_expand "extenddfxf2"
3749 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3750 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3753 /* ??? Needed for compress_float_constant since all fp constants
3754 are LEGITIMATE_CONSTANT_P. */
3755 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3757 if (standard_80387_constant_p (operands[1]) > 0)
3759 operands[1] = simplify_const_unary_operation
3760 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3761 emit_move_insn_1 (operands[0], operands[1]);
3764 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3768 (define_insn "*extenddfxf2_i387"
3769 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3770 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3773 switch (which_alternative)
3776 return output_387_reg_move (insn, operands);
3779 /* There is no non-popping store to memory for XFmode. So if
3780 we need one, follow the store with a load. */
3781 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3782 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3784 return "fstp%z0\t%y0";
3790 [(set_attr "type" "fmov")
3791 (set_attr "mode" "DF,XF")])
3793 ;; %%% This seems bad bad news.
3794 ;; This cannot output into an f-reg because there is no way to be sure
3795 ;; of truncating in that case. Otherwise this is just like a simple move
3796 ;; insn. So we pretend we can output to a reg in order to get better
3797 ;; register preferencing, but we really use a stack slot.
3799 ;; Conversion from DFmode to SFmode.
3801 (define_expand "truncdfsf2"
3802 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3804 (match_operand:DF 1 "nonimmediate_operand" "")))]
3805 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3807 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3809 else if (flag_unsafe_math_optimizations)
3813 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3814 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3819 (define_expand "truncdfsf2_with_temp"
3820 [(parallel [(set (match_operand:SF 0 "" "")
3821 (float_truncate:SF (match_operand:DF 1 "" "")))
3822 (clobber (match_operand:SF 2 "" ""))])]
3825 (define_insn "*truncdfsf_fast_mixed"
3826 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3828 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3829 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3831 switch (which_alternative)
3834 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3835 return "fstp%z0\t%y0";
3837 return "fst%z0\t%y0";
3839 return output_387_reg_move (insn, operands);
3841 return "cvtsd2ss\t{%1, %0|%0, %1}";
3846 [(set_attr "type" "fmov,fmov,ssecvt")
3847 (set_attr "mode" "SF")])
3849 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3850 ;; because nothing we do here is unsafe.
3851 (define_insn "*truncdfsf_fast_sse"
3852 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3854 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3855 "TARGET_SSE2 && TARGET_SSE_MATH"
3856 "cvtsd2ss\t{%1, %0|%0, %1}"
3857 [(set_attr "type" "ssecvt")
3858 (set_attr "mode" "SF")])
3860 (define_insn "*truncdfsf_fast_i387"
3861 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3863 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3864 "TARGET_80387 && flag_unsafe_math_optimizations"
3865 "* return output_387_reg_move (insn, operands);"
3866 [(set_attr "type" "fmov")
3867 (set_attr "mode" "SF")])
3869 (define_insn "*truncdfsf_mixed"
3870 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3872 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3873 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3874 "TARGET_MIX_SSE_I387"
3876 switch (which_alternative)
3879 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3880 return "fstp%z0\t%y0";
3882 return "fst%z0\t%y0";
3886 return "cvtsd2ss\t{%1, %0|%0, %1}";
3891 [(set_attr "type" "fmov,multi,ssecvt")
3892 (set_attr "unit" "*,i387,*")
3893 (set_attr "mode" "SF")])
3895 (define_insn "*truncdfsf_i387"
3896 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3898 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3899 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3902 switch (which_alternative)
3905 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3906 return "fstp%z0\t%y0";
3908 return "fst%z0\t%y0";
3915 [(set_attr "type" "fmov,multi")
3916 (set_attr "unit" "*,i387")
3917 (set_attr "mode" "SF")])
3919 (define_insn "*truncdfsf2_i387_1"
3920 [(set (match_operand:SF 0 "memory_operand" "=m")
3922 (match_operand:DF 1 "register_operand" "f")))]
3924 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3925 && !TARGET_MIX_SSE_I387"
3927 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3928 return "fstp%z0\t%y0";
3930 return "fst%z0\t%y0";
3932 [(set_attr "type" "fmov")
3933 (set_attr "mode" "SF")])
3936 [(set (match_operand:SF 0 "register_operand" "")
3938 (match_operand:DF 1 "fp_register_operand" "")))
3939 (clobber (match_operand 2 "" ""))]
3941 [(set (match_dup 2) (match_dup 1))
3942 (set (match_dup 0) (match_dup 2))]
3944 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3947 ;; Conversion from XFmode to SFmode.
3949 (define_expand "truncxfsf2"
3950 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3952 (match_operand:XF 1 "register_operand" "")))
3953 (clobber (match_dup 2))])]
3956 if (flag_unsafe_math_optimizations)
3958 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3959 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3960 if (reg != operands[0])
3961 emit_move_insn (operands[0], reg);
3965 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3968 (define_insn "*truncxfsf2_mixed"
3969 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3971 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3972 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3975 gcc_assert (!which_alternative);
3976 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977 return "fstp%z0\t%y0";
3979 return "fst%z0\t%y0";
3981 [(set_attr "type" "fmov,multi,multi,multi")
3982 (set_attr "unit" "*,i387,i387,i387")
3983 (set_attr "mode" "SF")])
3985 (define_insn "truncxfsf2_i387_noop"
3986 [(set (match_operand:SF 0 "register_operand" "=f")
3987 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3988 "TARGET_80387 && flag_unsafe_math_optimizations"
3989 "* return output_387_reg_move (insn, operands);"
3990 [(set_attr "type" "fmov")
3991 (set_attr "mode" "SF")])
3993 (define_insn "*truncxfsf2_i387"
3994 [(set (match_operand:SF 0 "memory_operand" "=m")
3996 (match_operand:XF 1 "register_operand" "f")))]
3999 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4000 return "fstp%z0\t%y0";
4002 return "fst%z0\t%y0";
4004 [(set_attr "type" "fmov")
4005 (set_attr "mode" "SF")])
4008 [(set (match_operand:SF 0 "register_operand" "")
4010 (match_operand:XF 1 "register_operand" "")))
4011 (clobber (match_operand:SF 2 "memory_operand" ""))]
4012 "TARGET_80387 && reload_completed"
4013 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4014 (set (match_dup 0) (match_dup 2))]
4018 [(set (match_operand:SF 0 "memory_operand" "")
4020 (match_operand:XF 1 "register_operand" "")))
4021 (clobber (match_operand:SF 2 "memory_operand" ""))]
4023 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4026 ;; Conversion from XFmode to DFmode.
4028 (define_expand "truncxfdf2"
4029 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4031 (match_operand:XF 1 "register_operand" "")))
4032 (clobber (match_dup 2))])]
4035 if (flag_unsafe_math_optimizations)
4037 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4038 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4039 if (reg != operands[0])
4040 emit_move_insn (operands[0], reg);
4044 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4047 (define_insn "*truncxfdf2_mixed"
4048 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4050 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4051 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4054 gcc_assert (!which_alternative);
4055 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4056 return "fstp%z0\t%y0";
4058 return "fst%z0\t%y0";
4060 [(set_attr "type" "fmov,multi,multi,multi")
4061 (set_attr "unit" "*,i387,i387,i387")
4062 (set_attr "mode" "DF")])
4064 (define_insn "truncxfdf2_i387_noop"
4065 [(set (match_operand:DF 0 "register_operand" "=f")
4066 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4067 "TARGET_80387 && flag_unsafe_math_optimizations"
4068 "* return output_387_reg_move (insn, operands);"
4069 [(set_attr "type" "fmov")
4070 (set_attr "mode" "DF")])
4072 (define_insn "*truncxfdf2_i387"
4073 [(set (match_operand:DF 0 "memory_operand" "=m")
4075 (match_operand:XF 1 "register_operand" "f")))]
4078 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4079 return "fstp%z0\t%y0";
4081 return "fst%z0\t%y0";
4083 [(set_attr "type" "fmov")
4084 (set_attr "mode" "DF")])
4087 [(set (match_operand:DF 0 "register_operand" "")
4089 (match_operand:XF 1 "register_operand" "")))
4090 (clobber (match_operand:DF 2 "memory_operand" ""))]
4091 "TARGET_80387 && reload_completed"
4092 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4093 (set (match_dup 0) (match_dup 2))]
4097 [(set (match_operand:DF 0 "memory_operand" "")
4099 (match_operand:XF 1 "register_operand" "")))
4100 (clobber (match_operand:DF 2 "memory_operand" ""))]
4102 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4105 ;; Signed conversion to DImode.
4107 (define_expand "fix_truncxfdi2"
4108 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4109 (fix:DI (match_operand:XF 1 "register_operand" "")))
4110 (clobber (reg:CC FLAGS_REG))])]
4115 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4120 (define_expand "fix_trunc<mode>di2"
4121 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4122 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4123 (clobber (reg:CC FLAGS_REG))])]
4124 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4127 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4129 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4132 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4134 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4135 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4136 if (out != operands[0])
4137 emit_move_insn (operands[0], out);
4142 ;; Signed conversion to SImode.
4144 (define_expand "fix_truncxfsi2"
4145 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4146 (fix:SI (match_operand:XF 1 "register_operand" "")))
4147 (clobber (reg:CC FLAGS_REG))])]
4152 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4157 (define_expand "fix_trunc<mode>si2"
4158 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4159 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4160 (clobber (reg:CC FLAGS_REG))])]
4161 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4164 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4166 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4169 if (SSE_FLOAT_MODE_P (<MODE>mode))
4171 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4172 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4173 if (out != operands[0])
4174 emit_move_insn (operands[0], out);
4179 ;; Signed conversion to HImode.
4181 (define_expand "fix_trunc<mode>hi2"
4182 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4183 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4184 (clobber (reg:CC FLAGS_REG))])]
4186 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4190 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4195 ;; When SSE is available, it is always faster to use it!
4196 (define_insn "fix_truncsfdi_sse"
4197 [(set (match_operand:DI 0 "register_operand" "=r,r")
4198 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4199 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4200 "cvttss2si{q}\t{%1, %0|%0, %1}"
4201 [(set_attr "type" "sseicvt")
4202 (set_attr "mode" "SF")
4203 (set_attr "athlon_decode" "double,vector")
4204 (set_attr "amdfam10_decode" "double,double")])
4206 (define_insn "fix_truncdfdi_sse"
4207 [(set (match_operand:DI 0 "register_operand" "=r,r")
4208 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4209 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4210 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4211 [(set_attr "type" "sseicvt")
4212 (set_attr "mode" "DF")
4213 (set_attr "athlon_decode" "double,vector")
4214 (set_attr "amdfam10_decode" "double,double")])
4216 (define_insn "fix_truncsfsi_sse"
4217 [(set (match_operand:SI 0 "register_operand" "=r,r")
4218 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4219 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4220 "cvttss2si\t{%1, %0|%0, %1}"
4221 [(set_attr "type" "sseicvt")
4222 (set_attr "mode" "DF")
4223 (set_attr "athlon_decode" "double,vector")
4224 (set_attr "amdfam10_decode" "double,double")])
4226 (define_insn "fix_truncdfsi_sse"
4227 [(set (match_operand:SI 0 "register_operand" "=r,r")
4228 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4229 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4230 "cvttsd2si\t{%1, %0|%0, %1}"
4231 [(set_attr "type" "sseicvt")
4232 (set_attr "mode" "DF")
4233 (set_attr "athlon_decode" "double,vector")
4234 (set_attr "amdfam10_decode" "double,double")])
4236 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4238 [(set (match_operand:DF 0 "register_operand" "")
4239 (match_operand:DF 1 "memory_operand" ""))
4240 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4241 (fix:SSEMODEI24 (match_dup 0)))]
4243 && peep2_reg_dead_p (2, operands[0])"
4244 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4248 [(set (match_operand:SF 0 "register_operand" "")
4249 (match_operand:SF 1 "memory_operand" ""))
4250 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4251 (fix:SSEMODEI24 (match_dup 0)))]
4253 && peep2_reg_dead_p (2, operands[0])"
4254 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4257 ;; Avoid vector decoded forms of the instruction.
4259 [(match_scratch:DF 2 "Y")
4260 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4261 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4262 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4263 [(set (match_dup 2) (match_dup 1))
4264 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4268 [(match_scratch:SF 2 "x")
4269 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4270 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4271 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4272 [(set (match_dup 2) (match_dup 1))
4273 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4276 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4277 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4278 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4280 && FLOAT_MODE_P (GET_MODE (operands[1]))
4281 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4282 && (TARGET_64BIT || <MODE>mode != DImode))
4284 && !(reload_completed || reload_in_progress)"
4289 if (memory_operand (operands[0], VOIDmode))
4290 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4293 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4294 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4300 [(set_attr "type" "fisttp")
4301 (set_attr "mode" "<MODE>")])
4303 (define_insn "fix_trunc<mode>_i387_fisttp"
4304 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4305 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4306 (clobber (match_scratch:XF 2 "=&1f"))]
4308 && FLOAT_MODE_P (GET_MODE (operands[1]))
4309 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4310 && (TARGET_64BIT || <MODE>mode != DImode))
4311 && TARGET_SSE_MATH)"
4312 "* return output_fix_trunc (insn, operands, 1);"
4313 [(set_attr "type" "fisttp")
4314 (set_attr "mode" "<MODE>")])
4316 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4317 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4318 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4319 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4320 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4322 && FLOAT_MODE_P (GET_MODE (operands[1]))
4323 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4324 && (TARGET_64BIT || <MODE>mode != DImode))
4325 && TARGET_SSE_MATH)"
4327 [(set_attr "type" "fisttp")
4328 (set_attr "mode" "<MODE>")])
4331 [(set (match_operand:X87MODEI 0 "register_operand" "")
4332 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4333 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4334 (clobber (match_scratch 3 ""))]
4336 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4337 (clobber (match_dup 3))])
4338 (set (match_dup 0) (match_dup 2))]
4342 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4343 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4344 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4345 (clobber (match_scratch 3 ""))]
4347 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4348 (clobber (match_dup 3))])]
4351 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4352 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4353 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4354 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4355 ;; function in i386.c.
4356 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4357 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4358 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4359 (clobber (reg:CC FLAGS_REG))]
4360 "TARGET_80387 && !TARGET_FISTTP
4361 && FLOAT_MODE_P (GET_MODE (operands[1]))
4362 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4363 && (TARGET_64BIT || <MODE>mode != DImode))
4364 && !(reload_completed || reload_in_progress)"
4369 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4371 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4372 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4373 if (memory_operand (operands[0], VOIDmode))
4374 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4375 operands[2], operands[3]));
4378 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4379 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4380 operands[2], operands[3],
4385 [(set_attr "type" "fistp")
4386 (set_attr "i387_cw" "trunc")
4387 (set_attr "mode" "<MODE>")])
4389 (define_insn "fix_truncdi_i387"
4390 [(set (match_operand:DI 0 "memory_operand" "=m")
4391 (fix:DI (match_operand 1 "register_operand" "f")))
4392 (use (match_operand:HI 2 "memory_operand" "m"))
4393 (use (match_operand:HI 3 "memory_operand" "m"))
4394 (clobber (match_scratch:XF 4 "=&1f"))]
4395 "TARGET_80387 && !TARGET_FISTTP
4396 && FLOAT_MODE_P (GET_MODE (operands[1]))
4397 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4398 "* return output_fix_trunc (insn, operands, 0);"
4399 [(set_attr "type" "fistp")
4400 (set_attr "i387_cw" "trunc")
4401 (set_attr "mode" "DI")])
4403 (define_insn "fix_truncdi_i387_with_temp"
4404 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4405 (fix:DI (match_operand 1 "register_operand" "f,f")))
4406 (use (match_operand:HI 2 "memory_operand" "m,m"))
4407 (use (match_operand:HI 3 "memory_operand" "m,m"))
4408 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4409 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4410 "TARGET_80387 && !TARGET_FISTTP
4411 && FLOAT_MODE_P (GET_MODE (operands[1]))
4412 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4414 [(set_attr "type" "fistp")
4415 (set_attr "i387_cw" "trunc")
4416 (set_attr "mode" "DI")])
4419 [(set (match_operand:DI 0 "register_operand" "")
4420 (fix:DI (match_operand 1 "register_operand" "")))
4421 (use (match_operand:HI 2 "memory_operand" ""))
4422 (use (match_operand:HI 3 "memory_operand" ""))
4423 (clobber (match_operand:DI 4 "memory_operand" ""))
4424 (clobber (match_scratch 5 ""))]
4426 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4429 (clobber (match_dup 5))])
4430 (set (match_dup 0) (match_dup 4))]
4434 [(set (match_operand:DI 0 "memory_operand" "")
4435 (fix:DI (match_operand 1 "register_operand" "")))
4436 (use (match_operand:HI 2 "memory_operand" ""))
4437 (use (match_operand:HI 3 "memory_operand" ""))
4438 (clobber (match_operand:DI 4 "memory_operand" ""))
4439 (clobber (match_scratch 5 ""))]
4441 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4444 (clobber (match_dup 5))])]
4447 (define_insn "fix_trunc<mode>_i387"
4448 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4449 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4450 (use (match_operand:HI 2 "memory_operand" "m"))
4451 (use (match_operand:HI 3 "memory_operand" "m"))]
4452 "TARGET_80387 && !TARGET_FISTTP
4453 && FLOAT_MODE_P (GET_MODE (operands[1]))
4454 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4455 "* return output_fix_trunc (insn, operands, 0);"
4456 [(set_attr "type" "fistp")
4457 (set_attr "i387_cw" "trunc")
4458 (set_attr "mode" "<MODE>")])
4460 (define_insn "fix_trunc<mode>_i387_with_temp"
4461 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4462 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4463 (use (match_operand:HI 2 "memory_operand" "m,m"))
4464 (use (match_operand:HI 3 "memory_operand" "m,m"))
4465 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4466 "TARGET_80387 && !TARGET_FISTTP
4467 && FLOAT_MODE_P (GET_MODE (operands[1]))
4468 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4470 [(set_attr "type" "fistp")
4471 (set_attr "i387_cw" "trunc")
4472 (set_attr "mode" "<MODE>")])
4475 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4476 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4477 (use (match_operand:HI 2 "memory_operand" ""))
4478 (use (match_operand:HI 3 "memory_operand" ""))
4479 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4481 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4483 (use (match_dup 3))])
4484 (set (match_dup 0) (match_dup 4))]
4488 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4489 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4490 (use (match_operand:HI 2 "memory_operand" ""))
4491 (use (match_operand:HI 3 "memory_operand" ""))
4492 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4494 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4496 (use (match_dup 3))])]
4499 (define_insn "x86_fnstcw_1"
4500 [(set (match_operand:HI 0 "memory_operand" "=m")
4501 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4504 [(set_attr "length" "2")
4505 (set_attr "mode" "HI")
4506 (set_attr "unit" "i387")])
4508 (define_insn "x86_fldcw_1"
4509 [(set (reg:HI FPCR_REG)
4510 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4513 [(set_attr "length" "2")
4514 (set_attr "mode" "HI")
4515 (set_attr "unit" "i387")
4516 (set_attr "athlon_decode" "vector")
4517 (set_attr "amdfam10_decode" "vector")])
4519 ;; Conversion between fixed point and floating point.
4521 ;; Even though we only accept memory inputs, the backend _really_
4522 ;; wants to be able to do this between registers.
4524 (define_expand "floathisf2"
4525 [(set (match_operand:SF 0 "register_operand" "")
4526 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4527 "TARGET_80387 || TARGET_SSE_MATH"
4529 if (TARGET_SSE_MATH)
4531 emit_insn (gen_floatsisf2 (operands[0],
4532 convert_to_mode (SImode, operands[1], 0)));
4537 (define_insn "*floathisf2_i387"
4538 [(set (match_operand:SF 0 "register_operand" "=f,f")
4539 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4540 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4544 [(set_attr "type" "fmov,multi")
4545 (set_attr "mode" "SF")
4546 (set_attr "unit" "*,i387")
4547 (set_attr "fp_int_src" "true")])
4549 (define_expand "floatsisf2"
4550 [(set (match_operand:SF 0 "register_operand" "")
4551 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4552 "TARGET_80387 || TARGET_SSE_MATH"
4555 (define_insn "*floatsisf2_mixed"
4556 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4557 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4558 "TARGET_MIX_SSE_I387"
4562 cvtsi2ss\t{%1, %0|%0, %1}
4563 cvtsi2ss\t{%1, %0|%0, %1}"
4564 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4565 (set_attr "mode" "SF")
4566 (set_attr "unit" "*,i387,*,*")
4567 (set_attr "athlon_decode" "*,*,vector,double")
4568 (set_attr "amdfam10_decode" "*,*,vector,double")
4569 (set_attr "fp_int_src" "true")])
4571 (define_insn "*floatsisf2_sse"
4572 [(set (match_operand:SF 0 "register_operand" "=x,x")
4573 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4575 "cvtsi2ss\t{%1, %0|%0, %1}"
4576 [(set_attr "type" "sseicvt")
4577 (set_attr "mode" "SF")
4578 (set_attr "athlon_decode" "vector,double")
4579 (set_attr "amdfam10_decode" "vector,double")
4580 (set_attr "fp_int_src" "true")])
4582 (define_insn "*floatsisf2_i387"
4583 [(set (match_operand:SF 0 "register_operand" "=f,f")
4584 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4589 [(set_attr "type" "fmov,multi")
4590 (set_attr "mode" "SF")
4591 (set_attr "unit" "*,i387")
4592 (set_attr "fp_int_src" "true")])
4594 (define_expand "floatdisf2"
4595 [(set (match_operand:SF 0 "register_operand" "")
4596 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4597 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4600 (define_insn "*floatdisf2_mixed"
4601 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4602 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4603 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4607 cvtsi2ss{q}\t{%1, %0|%0, %1}
4608 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4609 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4610 (set_attr "mode" "SF")
4611 (set_attr "unit" "*,i387,*,*")
4612 (set_attr "athlon_decode" "*,*,vector,double")
4613 (set_attr "amdfam10_decode" "*,*,vector,double")
4614 (set_attr "fp_int_src" "true")])
4616 (define_insn "*floatdisf2_sse"
4617 [(set (match_operand:SF 0 "register_operand" "=x,x")
4618 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4619 "TARGET_64BIT && TARGET_SSE_MATH"
4620 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4621 [(set_attr "type" "sseicvt")
4622 (set_attr "mode" "SF")
4623 (set_attr "athlon_decode" "vector,double")
4624 (set_attr "amdfam10_decode" "vector,double")
4625 (set_attr "fp_int_src" "true")])
4627 (define_insn "*floatdisf2_i387"
4628 [(set (match_operand:SF 0 "register_operand" "=f,f")
4629 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4634 [(set_attr "type" "fmov,multi")
4635 (set_attr "mode" "SF")
4636 (set_attr "unit" "*,i387")
4637 (set_attr "fp_int_src" "true")])
4639 (define_expand "floathidf2"
4640 [(set (match_operand:DF 0 "register_operand" "")
4641 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4642 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4644 if (TARGET_SSE2 && TARGET_SSE_MATH)
4646 emit_insn (gen_floatsidf2 (operands[0],
4647 convert_to_mode (SImode, operands[1], 0)));
4652 (define_insn "*floathidf2_i387"
4653 [(set (match_operand:DF 0 "register_operand" "=f,f")
4654 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4655 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4659 [(set_attr "type" "fmov,multi")
4660 (set_attr "mode" "DF")
4661 (set_attr "unit" "*,i387")
4662 (set_attr "fp_int_src" "true")])
4664 (define_expand "floatsidf2"
4665 [(set (match_operand:DF 0 "register_operand" "")
4666 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4667 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4670 (define_insn "*floatsidf2_mixed"
4671 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4672 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4673 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4677 cvtsi2sd\t{%1, %0|%0, %1}
4678 cvtsi2sd\t{%1, %0|%0, %1}"
4679 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4680 (set_attr "mode" "DF")
4681 (set_attr "unit" "*,i387,*,*")
4682 (set_attr "athlon_decode" "*,*,double,direct")
4683 (set_attr "amdfam10_decode" "*,*,vector,double")
4684 (set_attr "fp_int_src" "true")])
4686 (define_insn "*floatsidf2_sse"
4687 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4688 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4689 "TARGET_SSE2 && TARGET_SSE_MATH"
4690 "cvtsi2sd\t{%1, %0|%0, %1}"
4691 [(set_attr "type" "sseicvt")
4692 (set_attr "mode" "DF")
4693 (set_attr "athlon_decode" "double,direct")
4694 (set_attr "amdfam10_decode" "vector,double")
4695 (set_attr "fp_int_src" "true")])
4697 (define_insn "*floatsidf2_i387"
4698 [(set (match_operand:DF 0 "register_operand" "=f,f")
4699 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4704 [(set_attr "type" "fmov,multi")
4705 (set_attr "mode" "DF")
4706 (set_attr "unit" "*,i387")
4707 (set_attr "fp_int_src" "true")])
4709 (define_expand "floatdidf2"
4710 [(set (match_operand:DF 0 "register_operand" "")
4711 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4712 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4715 (define_insn "*floatdidf2_mixed"
4716 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4717 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4718 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4722 cvtsi2sd{q}\t{%1, %0|%0, %1}
4723 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4724 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4725 (set_attr "mode" "DF")
4726 (set_attr "unit" "*,i387,*,*")
4727 (set_attr "athlon_decode" "*,*,double,direct")
4728 (set_attr "amdfam10_decode" "*,*,vector,double")
4729 (set_attr "fp_int_src" "true")])
4731 (define_insn "*floatdidf2_sse"
4732 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4733 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4734 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4735 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4736 [(set_attr "type" "sseicvt")
4737 (set_attr "mode" "DF")
4738 (set_attr "athlon_decode" "double,direct")
4739 (set_attr "amdfam10_decode" "vector,double")
4740 (set_attr "fp_int_src" "true")])
4742 (define_insn "*floatdidf2_i387"
4743 [(set (match_operand:DF 0 "register_operand" "=f,f")
4744 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4749 [(set_attr "type" "fmov,multi")
4750 (set_attr "mode" "DF")
4751 (set_attr "unit" "*,i387")
4752 (set_attr "fp_int_src" "true")])
4754 (define_insn "floathixf2"
4755 [(set (match_operand:XF 0 "register_operand" "=f,f")
4756 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4761 [(set_attr "type" "fmov,multi")
4762 (set_attr "mode" "XF")
4763 (set_attr "unit" "*,i387")
4764 (set_attr "fp_int_src" "true")])
4766 (define_insn "floatsixf2"
4767 [(set (match_operand:XF 0 "register_operand" "=f,f")
4768 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4773 [(set_attr "type" "fmov,multi")
4774 (set_attr "mode" "XF")
4775 (set_attr "unit" "*,i387")
4776 (set_attr "fp_int_src" "true")])
4778 (define_insn "floatdixf2"
4779 [(set (match_operand:XF 0 "register_operand" "=f,f")
4780 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4785 [(set_attr "type" "fmov,multi")
4786 (set_attr "mode" "XF")
4787 (set_attr "unit" "*,i387")
4788 (set_attr "fp_int_src" "true")])
4790 ;; %%% Kill these when reload knows how to do it.
4792 [(set (match_operand 0 "fp_register_operand" "")
4793 (float (match_operand 1 "register_operand" "")))]
4796 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4799 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4800 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4801 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4802 ix86_free_from_memory (GET_MODE (operands[1]));
4806 (define_expand "floatunssisf2"
4807 [(use (match_operand:SF 0 "register_operand" ""))
4808 (use (match_operand:SI 1 "register_operand" ""))]
4809 "!TARGET_64BIT && TARGET_SSE_MATH"
4810 "x86_emit_floatuns (operands); DONE;")
4812 (define_expand "floatunsdisf2"
4813 [(use (match_operand:SF 0 "register_operand" ""))
4814 (use (match_operand:DI 1 "register_operand" ""))]
4815 "TARGET_64BIT && TARGET_SSE_MATH"
4816 "x86_emit_floatuns (operands); DONE;")
4818 (define_expand "floatunsdidf2"
4819 [(use (match_operand:DF 0 "register_operand" ""))
4820 (use (match_operand:DI 1 "register_operand" ""))]
4821 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4822 "x86_emit_floatuns (operands); DONE;")
4824 ;; SSE extract/set expanders
4829 ;; %%% splits for addditi3
4831 (define_expand "addti3"
4832 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4833 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4834 (match_operand:TI 2 "x86_64_general_operand" "")))
4835 (clobber (reg:CC FLAGS_REG))]
4837 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4839 (define_insn "*addti3_1"
4840 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4841 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4842 (match_operand:TI 2 "general_operand" "roiF,riF")))
4843 (clobber (reg:CC FLAGS_REG))]
4844 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4848 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4849 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4850 (match_operand:TI 2 "general_operand" "")))
4851 (clobber (reg:CC FLAGS_REG))]
4852 "TARGET_64BIT && reload_completed"
4853 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4855 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4856 (parallel [(set (match_dup 3)
4857 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4860 (clobber (reg:CC FLAGS_REG))])]
4861 "split_ti (operands+0, 1, operands+0, operands+3);
4862 split_ti (operands+1, 1, operands+1, operands+4);
4863 split_ti (operands+2, 1, operands+2, operands+5);")
4865 ;; %%% splits for addsidi3
4866 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4867 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4868 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4870 (define_expand "adddi3"
4871 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4872 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4873 (match_operand:DI 2 "x86_64_general_operand" "")))
4874 (clobber (reg:CC FLAGS_REG))]
4876 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4878 (define_insn "*adddi3_1"
4879 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4880 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4881 (match_operand:DI 2 "general_operand" "roiF,riF")))
4882 (clobber (reg:CC FLAGS_REG))]
4883 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4887 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4888 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4889 (match_operand:DI 2 "general_operand" "")))
4890 (clobber (reg:CC FLAGS_REG))]
4891 "!TARGET_64BIT && reload_completed"
4892 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4894 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4895 (parallel [(set (match_dup 3)
4896 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4899 (clobber (reg:CC FLAGS_REG))])]
4900 "split_di (operands+0, 1, operands+0, operands+3);
4901 split_di (operands+1, 1, operands+1, operands+4);
4902 split_di (operands+2, 1, operands+2, operands+5);")
4904 (define_insn "adddi3_carry_rex64"
4905 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4906 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4907 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4908 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4909 (clobber (reg:CC FLAGS_REG))]
4910 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4911 "adc{q}\t{%2, %0|%0, %2}"
4912 [(set_attr "type" "alu")
4913 (set_attr "pent_pair" "pu")
4914 (set_attr "mode" "DI")])
4916 (define_insn "*adddi3_cc_rex64"
4917 [(set (reg:CC FLAGS_REG)
4918 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4919 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4921 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4922 (plus:DI (match_dup 1) (match_dup 2)))]
4923 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4924 "add{q}\t{%2, %0|%0, %2}"
4925 [(set_attr "type" "alu")
4926 (set_attr "mode" "DI")])
4928 (define_insn "addqi3_carry"
4929 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4930 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4931 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4932 (match_operand:QI 2 "general_operand" "qi,qm")))
4933 (clobber (reg:CC FLAGS_REG))]
4934 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4935 "adc{b}\t{%2, %0|%0, %2}"
4936 [(set_attr "type" "alu")
4937 (set_attr "pent_pair" "pu")
4938 (set_attr "mode" "QI")])
4940 (define_insn "addhi3_carry"
4941 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4942 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4943 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4944 (match_operand:HI 2 "general_operand" "ri,rm")))
4945 (clobber (reg:CC FLAGS_REG))]
4946 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4947 "adc{w}\t{%2, %0|%0, %2}"
4948 [(set_attr "type" "alu")
4949 (set_attr "pent_pair" "pu")
4950 (set_attr "mode" "HI")])
4952 (define_insn "addsi3_carry"
4953 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4954 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4955 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4956 (match_operand:SI 2 "general_operand" "ri,rm")))
4957 (clobber (reg:CC FLAGS_REG))]
4958 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4959 "adc{l}\t{%2, %0|%0, %2}"
4960 [(set_attr "type" "alu")
4961 (set_attr "pent_pair" "pu")
4962 (set_attr "mode" "SI")])
4964 (define_insn "*addsi3_carry_zext"
4965 [(set (match_operand:DI 0 "register_operand" "=r")
4967 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4968 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4969 (match_operand:SI 2 "general_operand" "rim"))))
4970 (clobber (reg:CC FLAGS_REG))]
4971 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4972 "adc{l}\t{%2, %k0|%k0, %2}"
4973 [(set_attr "type" "alu")
4974 (set_attr "pent_pair" "pu")
4975 (set_attr "mode" "SI")])
4977 (define_insn "*addsi3_cc"
4978 [(set (reg:CC FLAGS_REG)
4979 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4980 (match_operand:SI 2 "general_operand" "ri,rm")]
4982 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4983 (plus:SI (match_dup 1) (match_dup 2)))]
4984 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4985 "add{l}\t{%2, %0|%0, %2}"
4986 [(set_attr "type" "alu")
4987 (set_attr "mode" "SI")])
4989 (define_insn "addqi3_cc"
4990 [(set (reg:CC FLAGS_REG)
4991 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4992 (match_operand:QI 2 "general_operand" "qi,qm")]
4994 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4995 (plus:QI (match_dup 1) (match_dup 2)))]
4996 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4997 "add{b}\t{%2, %0|%0, %2}"
4998 [(set_attr "type" "alu")
4999 (set_attr "mode" "QI")])
5001 (define_expand "addsi3"
5002 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5003 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5004 (match_operand:SI 2 "general_operand" "")))
5005 (clobber (reg:CC FLAGS_REG))])]
5007 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5009 (define_insn "*lea_1"
5010 [(set (match_operand:SI 0 "register_operand" "=r")
5011 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5013 "lea{l}\t{%a1, %0|%0, %a1}"
5014 [(set_attr "type" "lea")
5015 (set_attr "mode" "SI")])
5017 (define_insn "*lea_1_rex64"
5018 [(set (match_operand:SI 0 "register_operand" "=r")
5019 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5021 "lea{l}\t{%a1, %0|%0, %a1}"
5022 [(set_attr "type" "lea")
5023 (set_attr "mode" "SI")])
5025 (define_insn "*lea_1_zext"
5026 [(set (match_operand:DI 0 "register_operand" "=r")
5028 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5030 "lea{l}\t{%a1, %k0|%k0, %a1}"
5031 [(set_attr "type" "lea")
5032 (set_attr "mode" "SI")])
5034 (define_insn "*lea_2_rex64"
5035 [(set (match_operand:DI 0 "register_operand" "=r")
5036 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5038 "lea{q}\t{%a1, %0|%0, %a1}"
5039 [(set_attr "type" "lea")
5040 (set_attr "mode" "DI")])
5042 ;; The lea patterns for non-Pmodes needs to be matched by several
5043 ;; insns converted to real lea by splitters.
5045 (define_insn_and_split "*lea_general_1"
5046 [(set (match_operand 0 "register_operand" "=r")
5047 (plus (plus (match_operand 1 "index_register_operand" "l")
5048 (match_operand 2 "register_operand" "r"))
5049 (match_operand 3 "immediate_operand" "i")))]
5050 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5051 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5052 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5053 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5054 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5055 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5056 || GET_MODE (operands[3]) == VOIDmode)"
5058 "&& reload_completed"
5062 operands[0] = gen_lowpart (SImode, operands[0]);
5063 operands[1] = gen_lowpart (Pmode, operands[1]);
5064 operands[2] = gen_lowpart (Pmode, operands[2]);
5065 operands[3] = gen_lowpart (Pmode, operands[3]);
5066 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5068 if (Pmode != SImode)
5069 pat = gen_rtx_SUBREG (SImode, pat, 0);
5070 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5073 [(set_attr "type" "lea")
5074 (set_attr "mode" "SI")])
5076 (define_insn_and_split "*lea_general_1_zext"
5077 [(set (match_operand:DI 0 "register_operand" "=r")
5079 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5080 (match_operand:SI 2 "register_operand" "r"))
5081 (match_operand:SI 3 "immediate_operand" "i"))))]
5084 "&& reload_completed"
5086 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5088 (match_dup 3)) 0)))]
5090 operands[1] = gen_lowpart (Pmode, operands[1]);
5091 operands[2] = gen_lowpart (Pmode, operands[2]);
5092 operands[3] = gen_lowpart (Pmode, operands[3]);
5094 [(set_attr "type" "lea")
5095 (set_attr "mode" "SI")])
5097 (define_insn_and_split "*lea_general_2"
5098 [(set (match_operand 0 "register_operand" "=r")
5099 (plus (mult (match_operand 1 "index_register_operand" "l")
5100 (match_operand 2 "const248_operand" "i"))
5101 (match_operand 3 "nonmemory_operand" "ri")))]
5102 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5103 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5104 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5105 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5106 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5107 || GET_MODE (operands[3]) == VOIDmode)"
5109 "&& reload_completed"
5113 operands[0] = gen_lowpart (SImode, operands[0]);
5114 operands[1] = gen_lowpart (Pmode, operands[1]);
5115 operands[3] = gen_lowpart (Pmode, operands[3]);
5116 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5118 if (Pmode != SImode)
5119 pat = gen_rtx_SUBREG (SImode, pat, 0);
5120 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5123 [(set_attr "type" "lea")
5124 (set_attr "mode" "SI")])
5126 (define_insn_and_split "*lea_general_2_zext"
5127 [(set (match_operand:DI 0 "register_operand" "=r")
5129 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5130 (match_operand:SI 2 "const248_operand" "n"))
5131 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5134 "&& reload_completed"
5136 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5138 (match_dup 3)) 0)))]
5140 operands[1] = gen_lowpart (Pmode, operands[1]);
5141 operands[3] = gen_lowpart (Pmode, operands[3]);
5143 [(set_attr "type" "lea")
5144 (set_attr "mode" "SI")])
5146 (define_insn_and_split "*lea_general_3"
5147 [(set (match_operand 0 "register_operand" "=r")
5148 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5149 (match_operand 2 "const248_operand" "i"))
5150 (match_operand 3 "register_operand" "r"))
5151 (match_operand 4 "immediate_operand" "i")))]
5152 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5153 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5154 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5155 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5156 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5158 "&& reload_completed"
5162 operands[0] = gen_lowpart (SImode, operands[0]);
5163 operands[1] = gen_lowpart (Pmode, operands[1]);
5164 operands[3] = gen_lowpart (Pmode, operands[3]);
5165 operands[4] = gen_lowpart (Pmode, operands[4]);
5166 pat = gen_rtx_PLUS (Pmode,
5167 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5171 if (Pmode != SImode)
5172 pat = gen_rtx_SUBREG (SImode, pat, 0);
5173 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5176 [(set_attr "type" "lea")
5177 (set_attr "mode" "SI")])
5179 (define_insn_and_split "*lea_general_3_zext"
5180 [(set (match_operand:DI 0 "register_operand" "=r")
5182 (plus:SI (plus:SI (mult:SI
5183 (match_operand:SI 1 "index_register_operand" "l")
5184 (match_operand:SI 2 "const248_operand" "n"))
5185 (match_operand:SI 3 "register_operand" "r"))
5186 (match_operand:SI 4 "immediate_operand" "i"))))]
5189 "&& reload_completed"
5191 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5194 (match_dup 4)) 0)))]
5196 operands[1] = gen_lowpart (Pmode, operands[1]);
5197 operands[3] = gen_lowpart (Pmode, operands[3]);
5198 operands[4] = gen_lowpart (Pmode, operands[4]);
5200 [(set_attr "type" "lea")
5201 (set_attr "mode" "SI")])
5203 (define_insn "*adddi_1_rex64"
5204 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5205 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5206 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5207 (clobber (reg:CC FLAGS_REG))]
5208 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5210 switch (get_attr_type (insn))
5213 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5214 return "lea{q}\t{%a2, %0|%0, %a2}";
5217 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5218 if (operands[2] == const1_rtx)
5219 return "inc{q}\t%0";
5222 gcc_assert (operands[2] == constm1_rtx);
5223 return "dec{q}\t%0";
5227 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5229 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5230 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5231 if (CONST_INT_P (operands[2])
5232 /* Avoid overflows. */
5233 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5234 && (INTVAL (operands[2]) == 128
5235 || (INTVAL (operands[2]) < 0
5236 && INTVAL (operands[2]) != -128)))
5238 operands[2] = GEN_INT (-INTVAL (operands[2]));
5239 return "sub{q}\t{%2, %0|%0, %2}";
5241 return "add{q}\t{%2, %0|%0, %2}";
5245 (cond [(eq_attr "alternative" "2")
5246 (const_string "lea")
5247 ; Current assemblers are broken and do not allow @GOTOFF in
5248 ; ought but a memory context.
5249 (match_operand:DI 2 "pic_symbolic_operand" "")
5250 (const_string "lea")
5251 (match_operand:DI 2 "incdec_operand" "")
5252 (const_string "incdec")
5254 (const_string "alu")))
5255 (set_attr "mode" "DI")])
5257 ;; Convert lea to the lea pattern to avoid flags dependency.
5259 [(set (match_operand:DI 0 "register_operand" "")
5260 (plus:DI (match_operand:DI 1 "register_operand" "")
5261 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5262 (clobber (reg:CC FLAGS_REG))]
5263 "TARGET_64BIT && reload_completed
5264 && true_regnum (operands[0]) != true_regnum (operands[1])"
5266 (plus:DI (match_dup 1)
5270 (define_insn "*adddi_2_rex64"
5271 [(set (reg FLAGS_REG)
5273 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5274 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5276 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5277 (plus:DI (match_dup 1) (match_dup 2)))]
5278 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5279 && ix86_binary_operator_ok (PLUS, DImode, operands)
5280 /* Current assemblers are broken and do not allow @GOTOFF in
5281 ought but a memory context. */
5282 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5284 switch (get_attr_type (insn))
5287 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5288 if (operands[2] == const1_rtx)
5289 return "inc{q}\t%0";
5292 gcc_assert (operands[2] == constm1_rtx);
5293 return "dec{q}\t%0";
5297 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5298 /* ???? We ought to handle there the 32bit case too
5299 - do we need new constraint? */
5300 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5301 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5302 if (CONST_INT_P (operands[2])
5303 /* Avoid overflows. */
5304 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5305 && (INTVAL (operands[2]) == 128
5306 || (INTVAL (operands[2]) < 0
5307 && INTVAL (operands[2]) != -128)))
5309 operands[2] = GEN_INT (-INTVAL (operands[2]));
5310 return "sub{q}\t{%2, %0|%0, %2}";
5312 return "add{q}\t{%2, %0|%0, %2}";
5316 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5317 (const_string "incdec")
5318 (const_string "alu")))
5319 (set_attr "mode" "DI")])
5321 (define_insn "*adddi_3_rex64"
5322 [(set (reg FLAGS_REG)
5323 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5324 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5325 (clobber (match_scratch:DI 0 "=r"))]
5327 && ix86_match_ccmode (insn, CCZmode)
5328 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5329 /* Current assemblers are broken and do not allow @GOTOFF in
5330 ought but a memory context. */
5331 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5333 switch (get_attr_type (insn))
5336 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5337 if (operands[2] == const1_rtx)
5338 return "inc{q}\t%0";
5341 gcc_assert (operands[2] == constm1_rtx);
5342 return "dec{q}\t%0";
5346 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5347 /* ???? We ought to handle there the 32bit case too
5348 - do we need new constraint? */
5349 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5350 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5351 if (CONST_INT_P (operands[2])
5352 /* Avoid overflows. */
5353 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5354 && (INTVAL (operands[2]) == 128
5355 || (INTVAL (operands[2]) < 0
5356 && INTVAL (operands[2]) != -128)))
5358 operands[2] = GEN_INT (-INTVAL (operands[2]));
5359 return "sub{q}\t{%2, %0|%0, %2}";
5361 return "add{q}\t{%2, %0|%0, %2}";
5365 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5366 (const_string "incdec")
5367 (const_string "alu")))
5368 (set_attr "mode" "DI")])
5370 ; For comparisons against 1, -1 and 128, we may generate better code
5371 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5372 ; is matched then. We can't accept general immediate, because for
5373 ; case of overflows, the result is messed up.
5374 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5376 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5377 ; only for comparisons not depending on it.
5378 (define_insn "*adddi_4_rex64"
5379 [(set (reg FLAGS_REG)
5380 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5381 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5382 (clobber (match_scratch:DI 0 "=rm"))]
5384 && ix86_match_ccmode (insn, CCGCmode)"
5386 switch (get_attr_type (insn))
5389 if (operands[2] == constm1_rtx)
5390 return "inc{q}\t%0";
5393 gcc_assert (operands[2] == const1_rtx);
5394 return "dec{q}\t%0";
5398 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5399 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5400 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5401 if ((INTVAL (operands[2]) == -128
5402 || (INTVAL (operands[2]) > 0
5403 && INTVAL (operands[2]) != 128))
5404 /* Avoid overflows. */
5405 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5406 return "sub{q}\t{%2, %0|%0, %2}";
5407 operands[2] = GEN_INT (-INTVAL (operands[2]));
5408 return "add{q}\t{%2, %0|%0, %2}";
5412 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5413 (const_string "incdec")
5414 (const_string "alu")))
5415 (set_attr "mode" "DI")])
5417 (define_insn "*adddi_5_rex64"
5418 [(set (reg FLAGS_REG)
5420 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5421 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5423 (clobber (match_scratch:DI 0 "=r"))]
5425 && ix86_match_ccmode (insn, CCGOCmode)
5426 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5427 /* Current assemblers are broken and do not allow @GOTOFF in
5428 ought but a memory context. */
5429 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5431 switch (get_attr_type (insn))
5434 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5435 if (operands[2] == const1_rtx)
5436 return "inc{q}\t%0";
5439 gcc_assert (operands[2] == constm1_rtx);
5440 return "dec{q}\t%0";
5444 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5445 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5446 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5447 if (CONST_INT_P (operands[2])
5448 /* Avoid overflows. */
5449 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5450 && (INTVAL (operands[2]) == 128
5451 || (INTVAL (operands[2]) < 0
5452 && INTVAL (operands[2]) != -128)))
5454 operands[2] = GEN_INT (-INTVAL (operands[2]));
5455 return "sub{q}\t{%2, %0|%0, %2}";
5457 return "add{q}\t{%2, %0|%0, %2}";
5461 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5462 (const_string "incdec")
5463 (const_string "alu")))
5464 (set_attr "mode" "DI")])
5467 (define_insn "*addsi_1"
5468 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5469 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5470 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5471 (clobber (reg:CC FLAGS_REG))]
5472 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5474 switch (get_attr_type (insn))
5477 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5478 return "lea{l}\t{%a2, %0|%0, %a2}";
5481 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5482 if (operands[2] == const1_rtx)
5483 return "inc{l}\t%0";
5486 gcc_assert (operands[2] == constm1_rtx);
5487 return "dec{l}\t%0";
5491 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5493 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5494 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5495 if (CONST_INT_P (operands[2])
5496 && (INTVAL (operands[2]) == 128
5497 || (INTVAL (operands[2]) < 0
5498 && INTVAL (operands[2]) != -128)))
5500 operands[2] = GEN_INT (-INTVAL (operands[2]));
5501 return "sub{l}\t{%2, %0|%0, %2}";
5503 return "add{l}\t{%2, %0|%0, %2}";
5507 (cond [(eq_attr "alternative" "2")
5508 (const_string "lea")
5509 ; Current assemblers are broken and do not allow @GOTOFF in
5510 ; ought but a memory context.
5511 (match_operand:SI 2 "pic_symbolic_operand" "")
5512 (const_string "lea")
5513 (match_operand:SI 2 "incdec_operand" "")
5514 (const_string "incdec")
5516 (const_string "alu")))
5517 (set_attr "mode" "SI")])
5519 ;; Convert lea to the lea pattern to avoid flags dependency.
5521 [(set (match_operand 0 "register_operand" "")
5522 (plus (match_operand 1 "register_operand" "")
5523 (match_operand 2 "nonmemory_operand" "")))
5524 (clobber (reg:CC FLAGS_REG))]
5526 && true_regnum (operands[0]) != true_regnum (operands[1])"
5530 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5531 may confuse gen_lowpart. */
5532 if (GET_MODE (operands[0]) != Pmode)
5534 operands[1] = gen_lowpart (Pmode, operands[1]);
5535 operands[2] = gen_lowpart (Pmode, operands[2]);
5537 operands[0] = gen_lowpart (SImode, operands[0]);
5538 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5539 if (Pmode != SImode)
5540 pat = gen_rtx_SUBREG (SImode, pat, 0);
5541 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5545 ;; It may seem that nonimmediate operand is proper one for operand 1.
5546 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5547 ;; we take care in ix86_binary_operator_ok to not allow two memory
5548 ;; operands so proper swapping will be done in reload. This allow
5549 ;; patterns constructed from addsi_1 to match.
5550 (define_insn "addsi_1_zext"
5551 [(set (match_operand:DI 0 "register_operand" "=r,r")
5553 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5554 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5555 (clobber (reg:CC FLAGS_REG))]
5556 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5558 switch (get_attr_type (insn))
5561 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5562 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5565 if (operands[2] == const1_rtx)
5566 return "inc{l}\t%k0";
5569 gcc_assert (operands[2] == constm1_rtx);
5570 return "dec{l}\t%k0";
5574 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5575 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5576 if (CONST_INT_P (operands[2])
5577 && (INTVAL (operands[2]) == 128
5578 || (INTVAL (operands[2]) < 0
5579 && INTVAL (operands[2]) != -128)))
5581 operands[2] = GEN_INT (-INTVAL (operands[2]));
5582 return "sub{l}\t{%2, %k0|%k0, %2}";
5584 return "add{l}\t{%2, %k0|%k0, %2}";
5588 (cond [(eq_attr "alternative" "1")
5589 (const_string "lea")
5590 ; Current assemblers are broken and do not allow @GOTOFF in
5591 ; ought but a memory context.
5592 (match_operand:SI 2 "pic_symbolic_operand" "")
5593 (const_string "lea")
5594 (match_operand:SI 2 "incdec_operand" "")
5595 (const_string "incdec")
5597 (const_string "alu")))
5598 (set_attr "mode" "SI")])
5600 ;; Convert lea to the lea pattern to avoid flags dependency.
5602 [(set (match_operand:DI 0 "register_operand" "")
5604 (plus:SI (match_operand:SI 1 "register_operand" "")
5605 (match_operand:SI 2 "nonmemory_operand" ""))))
5606 (clobber (reg:CC FLAGS_REG))]
5607 "TARGET_64BIT && reload_completed
5608 && true_regnum (operands[0]) != true_regnum (operands[1])"
5610 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5612 operands[1] = gen_lowpart (Pmode, operands[1]);
5613 operands[2] = gen_lowpart (Pmode, operands[2]);
5616 (define_insn "*addsi_2"
5617 [(set (reg FLAGS_REG)
5619 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5620 (match_operand:SI 2 "general_operand" "rmni,rni"))
5622 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5623 (plus:SI (match_dup 1) (match_dup 2)))]
5624 "ix86_match_ccmode (insn, CCGOCmode)
5625 && ix86_binary_operator_ok (PLUS, SImode, operands)
5626 /* Current assemblers are broken and do not allow @GOTOFF in
5627 ought but a memory context. */
5628 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5630 switch (get_attr_type (insn))
5633 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634 if (operands[2] == const1_rtx)
5635 return "inc{l}\t%0";
5638 gcc_assert (operands[2] == constm1_rtx);
5639 return "dec{l}\t%0";
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5645 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5646 if (CONST_INT_P (operands[2])
5647 && (INTVAL (operands[2]) == 128
5648 || (INTVAL (operands[2]) < 0
5649 && INTVAL (operands[2]) != -128)))
5651 operands[2] = GEN_INT (-INTVAL (operands[2]));
5652 return "sub{l}\t{%2, %0|%0, %2}";
5654 return "add{l}\t{%2, %0|%0, %2}";
5658 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5659 (const_string "incdec")
5660 (const_string "alu")))
5661 (set_attr "mode" "SI")])
5663 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5664 (define_insn "*addsi_2_zext"
5665 [(set (reg FLAGS_REG)
5667 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5668 (match_operand:SI 2 "general_operand" "rmni"))
5670 (set (match_operand:DI 0 "register_operand" "=r")
5671 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5672 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5673 && ix86_binary_operator_ok (PLUS, SImode, operands)
5674 /* Current assemblers are broken and do not allow @GOTOFF in
5675 ought but a memory context. */
5676 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5678 switch (get_attr_type (insn))
5681 if (operands[2] == const1_rtx)
5682 return "inc{l}\t%k0";
5685 gcc_assert (operands[2] == constm1_rtx);
5686 return "dec{l}\t%k0";
5690 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5691 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5692 if (CONST_INT_P (operands[2])
5693 && (INTVAL (operands[2]) == 128
5694 || (INTVAL (operands[2]) < 0
5695 && INTVAL (operands[2]) != -128)))
5697 operands[2] = GEN_INT (-INTVAL (operands[2]));
5698 return "sub{l}\t{%2, %k0|%k0, %2}";
5700 return "add{l}\t{%2, %k0|%k0, %2}";
5704 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5705 (const_string "incdec")
5706 (const_string "alu")))
5707 (set_attr "mode" "SI")])
5709 (define_insn "*addsi_3"
5710 [(set (reg FLAGS_REG)
5711 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5712 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5713 (clobber (match_scratch:SI 0 "=r"))]
5714 "ix86_match_ccmode (insn, CCZmode)
5715 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5716 /* Current assemblers are broken and do not allow @GOTOFF in
5717 ought but a memory context. */
5718 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5720 switch (get_attr_type (insn))
5723 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5724 if (operands[2] == const1_rtx)
5725 return "inc{l}\t%0";
5728 gcc_assert (operands[2] == constm1_rtx);
5729 return "dec{l}\t%0";
5733 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5734 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5735 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5736 if (CONST_INT_P (operands[2])
5737 && (INTVAL (operands[2]) == 128
5738 || (INTVAL (operands[2]) < 0
5739 && INTVAL (operands[2]) != -128)))
5741 operands[2] = GEN_INT (-INTVAL (operands[2]));
5742 return "sub{l}\t{%2, %0|%0, %2}";
5744 return "add{l}\t{%2, %0|%0, %2}";
5748 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5749 (const_string "incdec")
5750 (const_string "alu")))
5751 (set_attr "mode" "SI")])
5753 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5754 (define_insn "*addsi_3_zext"
5755 [(set (reg FLAGS_REG)
5756 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5757 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5758 (set (match_operand:DI 0 "register_operand" "=r")
5759 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5760 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5761 && ix86_binary_operator_ok (PLUS, SImode, operands)
5762 /* Current assemblers are broken and do not allow @GOTOFF in
5763 ought but a memory context. */
5764 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5766 switch (get_attr_type (insn))
5769 if (operands[2] == const1_rtx)
5770 return "inc{l}\t%k0";
5773 gcc_assert (operands[2] == constm1_rtx);
5774 return "dec{l}\t%k0";
5778 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5779 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5780 if (CONST_INT_P (operands[2])
5781 && (INTVAL (operands[2]) == 128
5782 || (INTVAL (operands[2]) < 0
5783 && INTVAL (operands[2]) != -128)))
5785 operands[2] = GEN_INT (-INTVAL (operands[2]));
5786 return "sub{l}\t{%2, %k0|%k0, %2}";
5788 return "add{l}\t{%2, %k0|%k0, %2}";
5792 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5793 (const_string "incdec")
5794 (const_string "alu")))
5795 (set_attr "mode" "SI")])
5797 ; For comparisons against 1, -1 and 128, we may generate better code
5798 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5799 ; is matched then. We can't accept general immediate, because for
5800 ; case of overflows, the result is messed up.
5801 ; This pattern also don't hold of 0x80000000, since the value overflows
5803 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5804 ; only for comparisons not depending on it.
5805 (define_insn "*addsi_4"
5806 [(set (reg FLAGS_REG)
5807 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5808 (match_operand:SI 2 "const_int_operand" "n")))
5809 (clobber (match_scratch:SI 0 "=rm"))]
5810 "ix86_match_ccmode (insn, CCGCmode)
5811 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5813 switch (get_attr_type (insn))
5816 if (operands[2] == constm1_rtx)
5817 return "inc{l}\t%0";
5820 gcc_assert (operands[2] == const1_rtx);
5821 return "dec{l}\t%0";
5825 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5826 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5827 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5828 if ((INTVAL (operands[2]) == -128
5829 || (INTVAL (operands[2]) > 0
5830 && INTVAL (operands[2]) != 128)))
5831 return "sub{l}\t{%2, %0|%0, %2}";
5832 operands[2] = GEN_INT (-INTVAL (operands[2]));
5833 return "add{l}\t{%2, %0|%0, %2}";
5837 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5838 (const_string "incdec")
5839 (const_string "alu")))
5840 (set_attr "mode" "SI")])
5842 (define_insn "*addsi_5"
5843 [(set (reg FLAGS_REG)
5845 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5846 (match_operand:SI 2 "general_operand" "rmni"))
5848 (clobber (match_scratch:SI 0 "=r"))]
5849 "ix86_match_ccmode (insn, CCGOCmode)
5850 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5851 /* Current assemblers are broken and do not allow @GOTOFF in
5852 ought but a memory context. */
5853 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5855 switch (get_attr_type (insn))
5858 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5859 if (operands[2] == const1_rtx)
5860 return "inc{l}\t%0";
5863 gcc_assert (operands[2] == constm1_rtx);
5864 return "dec{l}\t%0";
5868 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5869 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5870 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5871 if (CONST_INT_P (operands[2])
5872 && (INTVAL (operands[2]) == 128
5873 || (INTVAL (operands[2]) < 0
5874 && INTVAL (operands[2]) != -128)))
5876 operands[2] = GEN_INT (-INTVAL (operands[2]));
5877 return "sub{l}\t{%2, %0|%0, %2}";
5879 return "add{l}\t{%2, %0|%0, %2}";
5883 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5884 (const_string "incdec")
5885 (const_string "alu")))
5886 (set_attr "mode" "SI")])
5888 (define_expand "addhi3"
5889 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5890 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5891 (match_operand:HI 2 "general_operand" "")))
5892 (clobber (reg:CC FLAGS_REG))])]
5893 "TARGET_HIMODE_MATH"
5894 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5896 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5897 ;; type optimizations enabled by define-splits. This is not important
5898 ;; for PII, and in fact harmful because of partial register stalls.
5900 (define_insn "*addhi_1_lea"
5901 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5902 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5903 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5904 (clobber (reg:CC FLAGS_REG))]
5905 "!TARGET_PARTIAL_REG_STALL
5906 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5908 switch (get_attr_type (insn))
5913 if (operands[2] == const1_rtx)
5914 return "inc{w}\t%0";
5917 gcc_assert (operands[2] == constm1_rtx);
5918 return "dec{w}\t%0";
5922 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5923 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5924 if (CONST_INT_P (operands[2])
5925 && (INTVAL (operands[2]) == 128
5926 || (INTVAL (operands[2]) < 0
5927 && INTVAL (operands[2]) != -128)))
5929 operands[2] = GEN_INT (-INTVAL (operands[2]));
5930 return "sub{w}\t{%2, %0|%0, %2}";
5932 return "add{w}\t{%2, %0|%0, %2}";
5936 (if_then_else (eq_attr "alternative" "2")
5937 (const_string "lea")
5938 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5939 (const_string "incdec")
5940 (const_string "alu"))))
5941 (set_attr "mode" "HI,HI,SI")])
5943 (define_insn "*addhi_1"
5944 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5945 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5946 (match_operand:HI 2 "general_operand" "ri,rm")))
5947 (clobber (reg:CC FLAGS_REG))]
5948 "TARGET_PARTIAL_REG_STALL
5949 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5951 switch (get_attr_type (insn))
5954 if (operands[2] == const1_rtx)
5955 return "inc{w}\t%0";
5958 gcc_assert (operands[2] == constm1_rtx);
5959 return "dec{w}\t%0";
5963 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5964 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5965 if (CONST_INT_P (operands[2])
5966 && (INTVAL (operands[2]) == 128
5967 || (INTVAL (operands[2]) < 0
5968 && INTVAL (operands[2]) != -128)))
5970 operands[2] = GEN_INT (-INTVAL (operands[2]));
5971 return "sub{w}\t{%2, %0|%0, %2}";
5973 return "add{w}\t{%2, %0|%0, %2}";
5977 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5978 (const_string "incdec")
5979 (const_string "alu")))
5980 (set_attr "mode" "HI")])
5982 (define_insn "*addhi_2"
5983 [(set (reg FLAGS_REG)
5985 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5986 (match_operand:HI 2 "general_operand" "rmni,rni"))
5988 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5989 (plus:HI (match_dup 1) (match_dup 2)))]
5990 "ix86_match_ccmode (insn, CCGOCmode)
5991 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5993 switch (get_attr_type (insn))
5996 if (operands[2] == const1_rtx)
5997 return "inc{w}\t%0";
6000 gcc_assert (operands[2] == constm1_rtx);
6001 return "dec{w}\t%0";
6005 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6006 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6007 if (CONST_INT_P (operands[2])
6008 && (INTVAL (operands[2]) == 128
6009 || (INTVAL (operands[2]) < 0
6010 && INTVAL (operands[2]) != -128)))
6012 operands[2] = GEN_INT (-INTVAL (operands[2]));
6013 return "sub{w}\t{%2, %0|%0, %2}";
6015 return "add{w}\t{%2, %0|%0, %2}";
6019 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6020 (const_string "incdec")
6021 (const_string "alu")))
6022 (set_attr "mode" "HI")])
6024 (define_insn "*addhi_3"
6025 [(set (reg FLAGS_REG)
6026 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6027 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6028 (clobber (match_scratch:HI 0 "=r"))]
6029 "ix86_match_ccmode (insn, CCZmode)
6030 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6032 switch (get_attr_type (insn))
6035 if (operands[2] == const1_rtx)
6036 return "inc{w}\t%0";
6039 gcc_assert (operands[2] == constm1_rtx);
6040 return "dec{w}\t%0";
6044 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6045 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6046 if (CONST_INT_P (operands[2])
6047 && (INTVAL (operands[2]) == 128
6048 || (INTVAL (operands[2]) < 0
6049 && INTVAL (operands[2]) != -128)))
6051 operands[2] = GEN_INT (-INTVAL (operands[2]));
6052 return "sub{w}\t{%2, %0|%0, %2}";
6054 return "add{w}\t{%2, %0|%0, %2}";
6058 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6059 (const_string "incdec")
6060 (const_string "alu")))
6061 (set_attr "mode" "HI")])
6063 ; See comments above addsi_4 for details.
6064 (define_insn "*addhi_4"
6065 [(set (reg FLAGS_REG)
6066 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6067 (match_operand:HI 2 "const_int_operand" "n")))
6068 (clobber (match_scratch:HI 0 "=rm"))]
6069 "ix86_match_ccmode (insn, CCGCmode)
6070 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6072 switch (get_attr_type (insn))
6075 if (operands[2] == constm1_rtx)
6076 return "inc{w}\t%0";
6079 gcc_assert (operands[2] == const1_rtx);
6080 return "dec{w}\t%0";
6084 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6085 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6087 if ((INTVAL (operands[2]) == -128
6088 || (INTVAL (operands[2]) > 0
6089 && INTVAL (operands[2]) != 128)))
6090 return "sub{w}\t{%2, %0|%0, %2}";
6091 operands[2] = GEN_INT (-INTVAL (operands[2]));
6092 return "add{w}\t{%2, %0|%0, %2}";
6096 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6097 (const_string "incdec")
6098 (const_string "alu")))
6099 (set_attr "mode" "SI")])
6102 (define_insn "*addhi_5"
6103 [(set (reg FLAGS_REG)
6105 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6106 (match_operand:HI 2 "general_operand" "rmni"))
6108 (clobber (match_scratch:HI 0 "=r"))]
6109 "ix86_match_ccmode (insn, CCGOCmode)
6110 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6112 switch (get_attr_type (insn))
6115 if (operands[2] == const1_rtx)
6116 return "inc{w}\t%0";
6119 gcc_assert (operands[2] == constm1_rtx);
6120 return "dec{w}\t%0";
6124 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6125 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6126 if (CONST_INT_P (operands[2])
6127 && (INTVAL (operands[2]) == 128
6128 || (INTVAL (operands[2]) < 0
6129 && INTVAL (operands[2]) != -128)))
6131 operands[2] = GEN_INT (-INTVAL (operands[2]));
6132 return "sub{w}\t{%2, %0|%0, %2}";
6134 return "add{w}\t{%2, %0|%0, %2}";
6138 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6139 (const_string "incdec")
6140 (const_string "alu")))
6141 (set_attr "mode" "HI")])
6143 (define_expand "addqi3"
6144 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6145 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6146 (match_operand:QI 2 "general_operand" "")))
6147 (clobber (reg:CC FLAGS_REG))])]
6148 "TARGET_QIMODE_MATH"
6149 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6151 ;; %%% Potential partial reg stall on alternative 2. What to do?
6152 (define_insn "*addqi_1_lea"
6153 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6154 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6155 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6156 (clobber (reg:CC FLAGS_REG))]
6157 "!TARGET_PARTIAL_REG_STALL
6158 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6160 int widen = (which_alternative == 2);
6161 switch (get_attr_type (insn))
6166 if (operands[2] == const1_rtx)
6167 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6170 gcc_assert (operands[2] == constm1_rtx);
6171 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6175 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6176 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6177 if (CONST_INT_P (operands[2])
6178 && (INTVAL (operands[2]) == 128
6179 || (INTVAL (operands[2]) < 0
6180 && INTVAL (operands[2]) != -128)))
6182 operands[2] = GEN_INT (-INTVAL (operands[2]));
6184 return "sub{l}\t{%2, %k0|%k0, %2}";
6186 return "sub{b}\t{%2, %0|%0, %2}";
6189 return "add{l}\t{%k2, %k0|%k0, %k2}";
6191 return "add{b}\t{%2, %0|%0, %2}";
6195 (if_then_else (eq_attr "alternative" "3")
6196 (const_string "lea")
6197 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6198 (const_string "incdec")
6199 (const_string "alu"))))
6200 (set_attr "mode" "QI,QI,SI,SI")])
6202 (define_insn "*addqi_1"
6203 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6204 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6205 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6206 (clobber (reg:CC FLAGS_REG))]
6207 "TARGET_PARTIAL_REG_STALL
6208 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6210 int widen = (which_alternative == 2);
6211 switch (get_attr_type (insn))
6214 if (operands[2] == const1_rtx)
6215 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6218 gcc_assert (operands[2] == constm1_rtx);
6219 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6223 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6224 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6225 if (CONST_INT_P (operands[2])
6226 && (INTVAL (operands[2]) == 128
6227 || (INTVAL (operands[2]) < 0
6228 && INTVAL (operands[2]) != -128)))
6230 operands[2] = GEN_INT (-INTVAL (operands[2]));
6232 return "sub{l}\t{%2, %k0|%k0, %2}";
6234 return "sub{b}\t{%2, %0|%0, %2}";
6237 return "add{l}\t{%k2, %k0|%k0, %k2}";
6239 return "add{b}\t{%2, %0|%0, %2}";
6243 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6244 (const_string "incdec")
6245 (const_string "alu")))
6246 (set_attr "mode" "QI,QI,SI")])
6248 (define_insn "*addqi_1_slp"
6249 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6250 (plus:QI (match_dup 0)
6251 (match_operand:QI 1 "general_operand" "qn,qnm")))
6252 (clobber (reg:CC FLAGS_REG))]
6253 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6254 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6256 switch (get_attr_type (insn))
6259 if (operands[1] == const1_rtx)
6260 return "inc{b}\t%0";
6263 gcc_assert (operands[1] == constm1_rtx);
6264 return "dec{b}\t%0";
6268 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6269 if (CONST_INT_P (operands[1])
6270 && INTVAL (operands[1]) < 0)
6272 operands[1] = GEN_INT (-INTVAL (operands[1]));
6273 return "sub{b}\t{%1, %0|%0, %1}";
6275 return "add{b}\t{%1, %0|%0, %1}";
6279 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6280 (const_string "incdec")
6281 (const_string "alu1")))
6282 (set (attr "memory")
6283 (if_then_else (match_operand 1 "memory_operand" "")
6284 (const_string "load")
6285 (const_string "none")))
6286 (set_attr "mode" "QI")])
6288 (define_insn "*addqi_2"
6289 [(set (reg FLAGS_REG)
6291 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6292 (match_operand:QI 2 "general_operand" "qmni,qni"))
6294 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6295 (plus:QI (match_dup 1) (match_dup 2)))]
6296 "ix86_match_ccmode (insn, CCGOCmode)
6297 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6299 switch (get_attr_type (insn))
6302 if (operands[2] == const1_rtx)
6303 return "inc{b}\t%0";
6306 gcc_assert (operands[2] == constm1_rtx
6307 || (CONST_INT_P (operands[2])
6308 && INTVAL (operands[2]) == 255));
6309 return "dec{b}\t%0";
6313 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6314 if (CONST_INT_P (operands[2])
6315 && INTVAL (operands[2]) < 0)
6317 operands[2] = GEN_INT (-INTVAL (operands[2]));
6318 return "sub{b}\t{%2, %0|%0, %2}";
6320 return "add{b}\t{%2, %0|%0, %2}";
6324 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6325 (const_string "incdec")
6326 (const_string "alu")))
6327 (set_attr "mode" "QI")])
6329 (define_insn "*addqi_3"
6330 [(set (reg FLAGS_REG)
6331 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6332 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6333 (clobber (match_scratch:QI 0 "=q"))]
6334 "ix86_match_ccmode (insn, CCZmode)
6335 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6337 switch (get_attr_type (insn))
6340 if (operands[2] == const1_rtx)
6341 return "inc{b}\t%0";
6344 gcc_assert (operands[2] == constm1_rtx
6345 || (CONST_INT_P (operands[2])
6346 && INTVAL (operands[2]) == 255));
6347 return "dec{b}\t%0";
6351 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6352 if (CONST_INT_P (operands[2])
6353 && INTVAL (operands[2]) < 0)
6355 operands[2] = GEN_INT (-INTVAL (operands[2]));
6356 return "sub{b}\t{%2, %0|%0, %2}";
6358 return "add{b}\t{%2, %0|%0, %2}";
6362 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6363 (const_string "incdec")
6364 (const_string "alu")))
6365 (set_attr "mode" "QI")])
6367 ; See comments above addsi_4 for details.
6368 (define_insn "*addqi_4"
6369 [(set (reg FLAGS_REG)
6370 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6371 (match_operand:QI 2 "const_int_operand" "n")))
6372 (clobber (match_scratch:QI 0 "=qm"))]
6373 "ix86_match_ccmode (insn, CCGCmode)
6374 && (INTVAL (operands[2]) & 0xff) != 0x80"
6376 switch (get_attr_type (insn))
6379 if (operands[2] == constm1_rtx
6380 || (CONST_INT_P (operands[2])
6381 && INTVAL (operands[2]) == 255))
6382 return "inc{b}\t%0";
6385 gcc_assert (operands[2] == const1_rtx);
6386 return "dec{b}\t%0";
6390 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6391 if (INTVAL (operands[2]) < 0)
6393 operands[2] = GEN_INT (-INTVAL (operands[2]));
6394 return "add{b}\t{%2, %0|%0, %2}";
6396 return "sub{b}\t{%2, %0|%0, %2}";
6400 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6401 (const_string "incdec")
6402 (const_string "alu")))
6403 (set_attr "mode" "QI")])
6406 (define_insn "*addqi_5"
6407 [(set (reg FLAGS_REG)
6409 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6410 (match_operand:QI 2 "general_operand" "qmni"))
6412 (clobber (match_scratch:QI 0 "=q"))]
6413 "ix86_match_ccmode (insn, CCGOCmode)
6414 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6416 switch (get_attr_type (insn))
6419 if (operands[2] == const1_rtx)
6420 return "inc{b}\t%0";
6423 gcc_assert (operands[2] == constm1_rtx
6424 || (CONST_INT_P (operands[2])
6425 && INTVAL (operands[2]) == 255));
6426 return "dec{b}\t%0";
6430 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6431 if (CONST_INT_P (operands[2])
6432 && INTVAL (operands[2]) < 0)
6434 operands[2] = GEN_INT (-INTVAL (operands[2]));
6435 return "sub{b}\t{%2, %0|%0, %2}";
6437 return "add{b}\t{%2, %0|%0, %2}";
6441 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6442 (const_string "incdec")
6443 (const_string "alu")))
6444 (set_attr "mode" "QI")])
6447 (define_insn "addqi_ext_1"
6448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6453 (match_operand 1 "ext_register_operand" "0")
6456 (match_operand:QI 2 "general_operand" "Qmn")))
6457 (clobber (reg:CC FLAGS_REG))]
6460 switch (get_attr_type (insn))
6463 if (operands[2] == const1_rtx)
6464 return "inc{b}\t%h0";
6467 gcc_assert (operands[2] == constm1_rtx
6468 || (CONST_INT_P (operands[2])
6469 && INTVAL (operands[2]) == 255));
6470 return "dec{b}\t%h0";
6474 return "add{b}\t{%2, %h0|%h0, %2}";
6478 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6479 (const_string "incdec")
6480 (const_string "alu")))
6481 (set_attr "mode" "QI")])
6483 (define_insn "*addqi_ext_1_rex64"
6484 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6489 (match_operand 1 "ext_register_operand" "0")
6492 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6493 (clobber (reg:CC FLAGS_REG))]
6496 switch (get_attr_type (insn))
6499 if (operands[2] == const1_rtx)
6500 return "inc{b}\t%h0";
6503 gcc_assert (operands[2] == constm1_rtx
6504 || (CONST_INT_P (operands[2])
6505 && INTVAL (operands[2]) == 255));
6506 return "dec{b}\t%h0";
6510 return "add{b}\t{%2, %h0|%h0, %2}";
6514 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6515 (const_string "incdec")
6516 (const_string "alu")))
6517 (set_attr "mode" "QI")])
6519 (define_insn "*addqi_ext_2"
6520 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6525 (match_operand 1 "ext_register_operand" "%0")
6529 (match_operand 2 "ext_register_operand" "Q")
6532 (clobber (reg:CC FLAGS_REG))]
6534 "add{b}\t{%h2, %h0|%h0, %h2}"
6535 [(set_attr "type" "alu")
6536 (set_attr "mode" "QI")])
6538 ;; The patterns that match these are at the end of this file.
6540 (define_expand "addxf3"
6541 [(set (match_operand:XF 0 "register_operand" "")
6542 (plus:XF (match_operand:XF 1 "register_operand" "")
6543 (match_operand:XF 2 "register_operand" "")))]
6547 (define_expand "adddf3"
6548 [(set (match_operand:DF 0 "register_operand" "")
6549 (plus:DF (match_operand:DF 1 "register_operand" "")
6550 (match_operand:DF 2 "nonimmediate_operand" "")))]
6551 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6554 (define_expand "addsf3"
6555 [(set (match_operand:SF 0 "register_operand" "")
6556 (plus:SF (match_operand:SF 1 "register_operand" "")
6557 (match_operand:SF 2 "nonimmediate_operand" "")))]
6558 "TARGET_80387 || TARGET_SSE_MATH"
6561 ;; Subtract instructions
6563 ;; %%% splits for subditi3
6565 (define_expand "subti3"
6566 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6567 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6568 (match_operand:TI 2 "x86_64_general_operand" "")))
6569 (clobber (reg:CC FLAGS_REG))])]
6571 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6573 (define_insn "*subti3_1"
6574 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6575 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6576 (match_operand:TI 2 "general_operand" "roiF,riF")))
6577 (clobber (reg:CC FLAGS_REG))]
6578 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6582 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6583 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6584 (match_operand:TI 2 "general_operand" "")))
6585 (clobber (reg:CC FLAGS_REG))]
6586 "TARGET_64BIT && reload_completed"
6587 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6588 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6589 (parallel [(set (match_dup 3)
6590 (minus:DI (match_dup 4)
6591 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6593 (clobber (reg:CC FLAGS_REG))])]
6594 "split_ti (operands+0, 1, operands+0, operands+3);
6595 split_ti (operands+1, 1, operands+1, operands+4);
6596 split_ti (operands+2, 1, operands+2, operands+5);")
6598 ;; %%% splits for subsidi3
6600 (define_expand "subdi3"
6601 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6602 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6603 (match_operand:DI 2 "x86_64_general_operand" "")))
6604 (clobber (reg:CC FLAGS_REG))])]
6606 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6608 (define_insn "*subdi3_1"
6609 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6610 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6611 (match_operand:DI 2 "general_operand" "roiF,riF")))
6612 (clobber (reg:CC FLAGS_REG))]
6613 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6617 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6618 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6619 (match_operand:DI 2 "general_operand" "")))
6620 (clobber (reg:CC FLAGS_REG))]
6621 "!TARGET_64BIT && reload_completed"
6622 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6623 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6624 (parallel [(set (match_dup 3)
6625 (minus:SI (match_dup 4)
6626 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6628 (clobber (reg:CC FLAGS_REG))])]
6629 "split_di (operands+0, 1, operands+0, operands+3);
6630 split_di (operands+1, 1, operands+1, operands+4);
6631 split_di (operands+2, 1, operands+2, operands+5);")
6633 (define_insn "subdi3_carry_rex64"
6634 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6635 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6636 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6637 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6638 (clobber (reg:CC FLAGS_REG))]
6639 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6640 "sbb{q}\t{%2, %0|%0, %2}"
6641 [(set_attr "type" "alu")
6642 (set_attr "pent_pair" "pu")
6643 (set_attr "mode" "DI")])
6645 (define_insn "*subdi_1_rex64"
6646 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6647 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6648 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6649 (clobber (reg:CC FLAGS_REG))]
6650 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6651 "sub{q}\t{%2, %0|%0, %2}"
6652 [(set_attr "type" "alu")
6653 (set_attr "mode" "DI")])
6655 (define_insn "*subdi_2_rex64"
6656 [(set (reg FLAGS_REG)
6658 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6659 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6661 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6662 (minus:DI (match_dup 1) (match_dup 2)))]
6663 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6664 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6665 "sub{q}\t{%2, %0|%0, %2}"
6666 [(set_attr "type" "alu")
6667 (set_attr "mode" "DI")])
6669 (define_insn "*subdi_3_rex63"
6670 [(set (reg FLAGS_REG)
6671 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6672 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6673 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6674 (minus:DI (match_dup 1) (match_dup 2)))]
6675 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6676 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6677 "sub{q}\t{%2, %0|%0, %2}"
6678 [(set_attr "type" "alu")
6679 (set_attr "mode" "DI")])
6681 (define_insn "subqi3_carry"
6682 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6683 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6684 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6685 (match_operand:QI 2 "general_operand" "qi,qm"))))
6686 (clobber (reg:CC FLAGS_REG))]
6687 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6688 "sbb{b}\t{%2, %0|%0, %2}"
6689 [(set_attr "type" "alu")
6690 (set_attr "pent_pair" "pu")
6691 (set_attr "mode" "QI")])
6693 (define_insn "subhi3_carry"
6694 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6695 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6696 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6697 (match_operand:HI 2 "general_operand" "ri,rm"))))
6698 (clobber (reg:CC FLAGS_REG))]
6699 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6700 "sbb{w}\t{%2, %0|%0, %2}"
6701 [(set_attr "type" "alu")
6702 (set_attr "pent_pair" "pu")
6703 (set_attr "mode" "HI")])
6705 (define_insn "subsi3_carry"
6706 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6707 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6708 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6709 (match_operand:SI 2 "general_operand" "ri,rm"))))
6710 (clobber (reg:CC FLAGS_REG))]
6711 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6712 "sbb{l}\t{%2, %0|%0, %2}"
6713 [(set_attr "type" "alu")
6714 (set_attr "pent_pair" "pu")
6715 (set_attr "mode" "SI")])
6717 (define_insn "subsi3_carry_zext"
6718 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6720 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6721 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6722 (match_operand:SI 2 "general_operand" "ri,rm")))))
6723 (clobber (reg:CC FLAGS_REG))]
6724 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6725 "sbb{l}\t{%2, %k0|%k0, %2}"
6726 [(set_attr "type" "alu")
6727 (set_attr "pent_pair" "pu")
6728 (set_attr "mode" "SI")])
6730 (define_expand "subsi3"
6731 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6732 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6733 (match_operand:SI 2 "general_operand" "")))
6734 (clobber (reg:CC FLAGS_REG))])]
6736 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6738 (define_insn "*subsi_1"
6739 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6740 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6741 (match_operand:SI 2 "general_operand" "ri,rm")))
6742 (clobber (reg:CC FLAGS_REG))]
6743 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6744 "sub{l}\t{%2, %0|%0, %2}"
6745 [(set_attr "type" "alu")
6746 (set_attr "mode" "SI")])
6748 (define_insn "*subsi_1_zext"
6749 [(set (match_operand:DI 0 "register_operand" "=r")
6751 (minus:SI (match_operand:SI 1 "register_operand" "0")
6752 (match_operand:SI 2 "general_operand" "rim"))))
6753 (clobber (reg:CC FLAGS_REG))]
6754 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6755 "sub{l}\t{%2, %k0|%k0, %2}"
6756 [(set_attr "type" "alu")
6757 (set_attr "mode" "SI")])
6759 (define_insn "*subsi_2"
6760 [(set (reg FLAGS_REG)
6762 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6763 (match_operand:SI 2 "general_operand" "ri,rm"))
6765 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6766 (minus:SI (match_dup 1) (match_dup 2)))]
6767 "ix86_match_ccmode (insn, CCGOCmode)
6768 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6769 "sub{l}\t{%2, %0|%0, %2}"
6770 [(set_attr "type" "alu")
6771 (set_attr "mode" "SI")])
6773 (define_insn "*subsi_2_zext"
6774 [(set (reg FLAGS_REG)
6776 (minus:SI (match_operand:SI 1 "register_operand" "0")
6777 (match_operand:SI 2 "general_operand" "rim"))
6779 (set (match_operand:DI 0 "register_operand" "=r")
6781 (minus:SI (match_dup 1)
6783 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6784 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6785 "sub{l}\t{%2, %k0|%k0, %2}"
6786 [(set_attr "type" "alu")
6787 (set_attr "mode" "SI")])
6789 (define_insn "*subsi_3"
6790 [(set (reg FLAGS_REG)
6791 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6792 (match_operand:SI 2 "general_operand" "ri,rm")))
6793 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6794 (minus:SI (match_dup 1) (match_dup 2)))]
6795 "ix86_match_ccmode (insn, CCmode)
6796 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6797 "sub{l}\t{%2, %0|%0, %2}"
6798 [(set_attr "type" "alu")
6799 (set_attr "mode" "SI")])
6801 (define_insn "*subsi_3_zext"
6802 [(set (reg FLAGS_REG)
6803 (compare (match_operand:SI 1 "register_operand" "0")
6804 (match_operand:SI 2 "general_operand" "rim")))
6805 (set (match_operand:DI 0 "register_operand" "=r")
6807 (minus:SI (match_dup 1)
6809 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6810 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6811 "sub{l}\t{%2, %1|%1, %2}"
6812 [(set_attr "type" "alu")
6813 (set_attr "mode" "DI")])
6815 (define_expand "subhi3"
6816 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6817 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6818 (match_operand:HI 2 "general_operand" "")))
6819 (clobber (reg:CC FLAGS_REG))])]
6820 "TARGET_HIMODE_MATH"
6821 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6823 (define_insn "*subhi_1"
6824 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6825 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6826 (match_operand:HI 2 "general_operand" "ri,rm")))
6827 (clobber (reg:CC FLAGS_REG))]
6828 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6829 "sub{w}\t{%2, %0|%0, %2}"
6830 [(set_attr "type" "alu")
6831 (set_attr "mode" "HI")])
6833 (define_insn "*subhi_2"
6834 [(set (reg FLAGS_REG)
6836 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6837 (match_operand:HI 2 "general_operand" "ri,rm"))
6839 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6840 (minus:HI (match_dup 1) (match_dup 2)))]
6841 "ix86_match_ccmode (insn, CCGOCmode)
6842 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6843 "sub{w}\t{%2, %0|%0, %2}"
6844 [(set_attr "type" "alu")
6845 (set_attr "mode" "HI")])
6847 (define_insn "*subhi_3"
6848 [(set (reg FLAGS_REG)
6849 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6850 (match_operand:HI 2 "general_operand" "ri,rm")))
6851 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6852 (minus:HI (match_dup 1) (match_dup 2)))]
6853 "ix86_match_ccmode (insn, CCmode)
6854 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6855 "sub{w}\t{%2, %0|%0, %2}"
6856 [(set_attr "type" "alu")
6857 (set_attr "mode" "HI")])
6859 (define_expand "subqi3"
6860 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6861 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6862 (match_operand:QI 2 "general_operand" "")))
6863 (clobber (reg:CC FLAGS_REG))])]
6864 "TARGET_QIMODE_MATH"
6865 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6867 (define_insn "*subqi_1"
6868 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6869 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6870 (match_operand:QI 2 "general_operand" "qn,qmn")))
6871 (clobber (reg:CC FLAGS_REG))]
6872 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6873 "sub{b}\t{%2, %0|%0, %2}"
6874 [(set_attr "type" "alu")
6875 (set_attr "mode" "QI")])
6877 (define_insn "*subqi_1_slp"
6878 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6879 (minus:QI (match_dup 0)
6880 (match_operand:QI 1 "general_operand" "qn,qmn")))
6881 (clobber (reg:CC FLAGS_REG))]
6882 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6883 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6884 "sub{b}\t{%1, %0|%0, %1}"
6885 [(set_attr "type" "alu1")
6886 (set_attr "mode" "QI")])
6888 (define_insn "*subqi_2"
6889 [(set (reg FLAGS_REG)
6891 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6892 (match_operand:QI 2 "general_operand" "qi,qm"))
6894 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6895 (minus:HI (match_dup 1) (match_dup 2)))]
6896 "ix86_match_ccmode (insn, CCGOCmode)
6897 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6898 "sub{b}\t{%2, %0|%0, %2}"
6899 [(set_attr "type" "alu")
6900 (set_attr "mode" "QI")])
6902 (define_insn "*subqi_3"
6903 [(set (reg FLAGS_REG)
6904 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6905 (match_operand:QI 2 "general_operand" "qi,qm")))
6906 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6907 (minus:HI (match_dup 1) (match_dup 2)))]
6908 "ix86_match_ccmode (insn, CCmode)
6909 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6910 "sub{b}\t{%2, %0|%0, %2}"
6911 [(set_attr "type" "alu")
6912 (set_attr "mode" "QI")])
6914 ;; The patterns that match these are at the end of this file.
6916 (define_expand "subxf3"
6917 [(set (match_operand:XF 0 "register_operand" "")
6918 (minus:XF (match_operand:XF 1 "register_operand" "")
6919 (match_operand:XF 2 "register_operand" "")))]
6923 (define_expand "subdf3"
6924 [(set (match_operand:DF 0 "register_operand" "")
6925 (minus:DF (match_operand:DF 1 "register_operand" "")
6926 (match_operand:DF 2 "nonimmediate_operand" "")))]
6927 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6930 (define_expand "subsf3"
6931 [(set (match_operand:SF 0 "register_operand" "")
6932 (minus:SF (match_operand:SF 1 "register_operand" "")
6933 (match_operand:SF 2 "nonimmediate_operand" "")))]
6934 "TARGET_80387 || TARGET_SSE_MATH"
6937 ;; Multiply instructions
6939 (define_expand "muldi3"
6940 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6941 (mult:DI (match_operand:DI 1 "register_operand" "")
6942 (match_operand:DI 2 "x86_64_general_operand" "")))
6943 (clobber (reg:CC FLAGS_REG))])]
6948 ;; IMUL reg64, reg64, imm8 Direct
6949 ;; IMUL reg64, mem64, imm8 VectorPath
6950 ;; IMUL reg64, reg64, imm32 Direct
6951 ;; IMUL reg64, mem64, imm32 VectorPath
6952 ;; IMUL reg64, reg64 Direct
6953 ;; IMUL reg64, mem64 Direct
6955 (define_insn "*muldi3_1_rex64"
6956 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6957 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6958 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6959 (clobber (reg:CC FLAGS_REG))]
6961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6963 imul{q}\t{%2, %1, %0|%0, %1, %2}
6964 imul{q}\t{%2, %1, %0|%0, %1, %2}
6965 imul{q}\t{%2, %0|%0, %2}"
6966 [(set_attr "type" "imul")
6967 (set_attr "prefix_0f" "0,0,1")
6968 (set (attr "athlon_decode")
6969 (cond [(eq_attr "cpu" "athlon")
6970 (const_string "vector")
6971 (eq_attr "alternative" "1")
6972 (const_string "vector")
6973 (and (eq_attr "alternative" "2")
6974 (match_operand 1 "memory_operand" ""))
6975 (const_string "vector")]
6976 (const_string "direct")))
6977 (set (attr "amdfam10_decode")
6978 (cond [(and (eq_attr "alternative" "0,1")
6979 (match_operand 1 "memory_operand" ""))
6980 (const_string "vector")]
6981 (const_string "direct")))
6982 (set_attr "mode" "DI")])
6984 (define_expand "mulsi3"
6985 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6986 (mult:SI (match_operand:SI 1 "register_operand" "")
6987 (match_operand:SI 2 "general_operand" "")))
6988 (clobber (reg:CC FLAGS_REG))])]
6993 ;; IMUL reg32, reg32, imm8 Direct
6994 ;; IMUL reg32, mem32, imm8 VectorPath
6995 ;; IMUL reg32, reg32, imm32 Direct
6996 ;; IMUL reg32, mem32, imm32 VectorPath
6997 ;; IMUL reg32, reg32 Direct
6998 ;; IMUL reg32, mem32 Direct
7000 (define_insn "*mulsi3_1"
7001 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7002 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7003 (match_operand:SI 2 "general_operand" "K,i,mr")))
7004 (clobber (reg:CC FLAGS_REG))]
7005 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7007 imul{l}\t{%2, %1, %0|%0, %1, %2}
7008 imul{l}\t{%2, %1, %0|%0, %1, %2}
7009 imul{l}\t{%2, %0|%0, %2}"
7010 [(set_attr "type" "imul")
7011 (set_attr "prefix_0f" "0,0,1")
7012 (set (attr "athlon_decode")
7013 (cond [(eq_attr "cpu" "athlon")
7014 (const_string "vector")
7015 (eq_attr "alternative" "1")
7016 (const_string "vector")
7017 (and (eq_attr "alternative" "2")
7018 (match_operand 1 "memory_operand" ""))
7019 (const_string "vector")]
7020 (const_string "direct")))
7021 (set (attr "amdfam10_decode")
7022 (cond [(and (eq_attr "alternative" "0,1")
7023 (match_operand 1 "memory_operand" ""))
7024 (const_string "vector")]
7025 (const_string "direct")))
7026 (set_attr "mode" "SI")])
7028 (define_insn "*mulsi3_1_zext"
7029 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7031 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7032 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7033 (clobber (reg:CC FLAGS_REG))]
7035 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7037 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7038 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7039 imul{l}\t{%2, %k0|%k0, %2}"
7040 [(set_attr "type" "imul")
7041 (set_attr "prefix_0f" "0,0,1")
7042 (set (attr "athlon_decode")
7043 (cond [(eq_attr "cpu" "athlon")
7044 (const_string "vector")
7045 (eq_attr "alternative" "1")
7046 (const_string "vector")
7047 (and (eq_attr "alternative" "2")
7048 (match_operand 1 "memory_operand" ""))
7049 (const_string "vector")]
7050 (const_string "direct")))
7051 (set (attr "amdfam10_decode")
7052 (cond [(and (eq_attr "alternative" "0,1")
7053 (match_operand 1 "memory_operand" ""))
7054 (const_string "vector")]
7055 (const_string "direct")))
7056 (set_attr "mode" "SI")])
7058 (define_expand "mulhi3"
7059 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7060 (mult:HI (match_operand:HI 1 "register_operand" "")
7061 (match_operand:HI 2 "general_operand" "")))
7062 (clobber (reg:CC FLAGS_REG))])]
7063 "TARGET_HIMODE_MATH"
7067 ;; IMUL reg16, reg16, imm8 VectorPath
7068 ;; IMUL reg16, mem16, imm8 VectorPath
7069 ;; IMUL reg16, reg16, imm16 VectorPath
7070 ;; IMUL reg16, mem16, imm16 VectorPath
7071 ;; IMUL reg16, reg16 Direct
7072 ;; IMUL reg16, mem16 Direct
7073 (define_insn "*mulhi3_1"
7074 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7075 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7076 (match_operand:HI 2 "general_operand" "K,i,mr")))
7077 (clobber (reg:CC FLAGS_REG))]
7078 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7080 imul{w}\t{%2, %1, %0|%0, %1, %2}
7081 imul{w}\t{%2, %1, %0|%0, %1, %2}
7082 imul{w}\t{%2, %0|%0, %2}"
7083 [(set_attr "type" "imul")
7084 (set_attr "prefix_0f" "0,0,1")
7085 (set (attr "athlon_decode")
7086 (cond [(eq_attr "cpu" "athlon")
7087 (const_string "vector")
7088 (eq_attr "alternative" "1,2")
7089 (const_string "vector")]
7090 (const_string "direct")))
7091 (set (attr "amdfam10_decode")
7092 (cond [(eq_attr "alternative" "0,1")
7093 (const_string "vector")]
7094 (const_string "direct")))
7095 (set_attr "mode" "HI")])
7097 (define_expand "mulqi3"
7098 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7099 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7100 (match_operand:QI 2 "register_operand" "")))
7101 (clobber (reg:CC FLAGS_REG))])]
7102 "TARGET_QIMODE_MATH"
7109 (define_insn "*mulqi3_1"
7110 [(set (match_operand:QI 0 "register_operand" "=a")
7111 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7112 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7113 (clobber (reg:CC FLAGS_REG))]
7115 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7117 [(set_attr "type" "imul")
7118 (set_attr "length_immediate" "0")
7119 (set (attr "athlon_decode")
7120 (if_then_else (eq_attr "cpu" "athlon")
7121 (const_string "vector")
7122 (const_string "direct")))
7123 (set_attr "amdfam10_decode" "direct")
7124 (set_attr "mode" "QI")])
7126 (define_expand "umulqihi3"
7127 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7128 (mult:HI (zero_extend:HI
7129 (match_operand:QI 1 "nonimmediate_operand" ""))
7131 (match_operand:QI 2 "register_operand" ""))))
7132 (clobber (reg:CC FLAGS_REG))])]
7133 "TARGET_QIMODE_MATH"
7136 (define_insn "*umulqihi3_1"
7137 [(set (match_operand:HI 0 "register_operand" "=a")
7138 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7139 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7140 (clobber (reg:CC FLAGS_REG))]
7142 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7144 [(set_attr "type" "imul")
7145 (set_attr "length_immediate" "0")
7146 (set (attr "athlon_decode")
7147 (if_then_else (eq_attr "cpu" "athlon")
7148 (const_string "vector")
7149 (const_string "direct")))
7150 (set_attr "amdfam10_decode" "direct")
7151 (set_attr "mode" "QI")])
7153 (define_expand "mulqihi3"
7154 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7155 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7156 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7157 (clobber (reg:CC FLAGS_REG))])]
7158 "TARGET_QIMODE_MATH"
7161 (define_insn "*mulqihi3_insn"
7162 [(set (match_operand:HI 0 "register_operand" "=a")
7163 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7164 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7165 (clobber (reg:CC FLAGS_REG))]
7167 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7169 [(set_attr "type" "imul")
7170 (set_attr "length_immediate" "0")
7171 (set (attr "athlon_decode")
7172 (if_then_else (eq_attr "cpu" "athlon")
7173 (const_string "vector")
7174 (const_string "direct")))
7175 (set_attr "amdfam10_decode" "direct")
7176 (set_attr "mode" "QI")])
7178 (define_expand "umulditi3"
7179 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7180 (mult:TI (zero_extend:TI
7181 (match_operand:DI 1 "nonimmediate_operand" ""))
7183 (match_operand:DI 2 "register_operand" ""))))
7184 (clobber (reg:CC FLAGS_REG))])]
7188 (define_insn "*umulditi3_insn"
7189 [(set (match_operand:TI 0 "register_operand" "=A")
7190 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7191 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7192 (clobber (reg:CC FLAGS_REG))]
7194 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7196 [(set_attr "type" "imul")
7197 (set_attr "length_immediate" "0")
7198 (set (attr "athlon_decode")
7199 (if_then_else (eq_attr "cpu" "athlon")
7200 (const_string "vector")
7201 (const_string "double")))
7202 (set_attr "amdfam10_decode" "double")
7203 (set_attr "mode" "DI")])
7205 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7206 (define_expand "umulsidi3"
7207 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7208 (mult:DI (zero_extend:DI
7209 (match_operand:SI 1 "nonimmediate_operand" ""))
7211 (match_operand:SI 2 "register_operand" ""))))
7212 (clobber (reg:CC FLAGS_REG))])]
7216 (define_insn "*umulsidi3_insn"
7217 [(set (match_operand:DI 0 "register_operand" "=A")
7218 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7219 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7220 (clobber (reg:CC FLAGS_REG))]
7222 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7224 [(set_attr "type" "imul")
7225 (set_attr "length_immediate" "0")
7226 (set (attr "athlon_decode")
7227 (if_then_else (eq_attr "cpu" "athlon")
7228 (const_string "vector")
7229 (const_string "double")))
7230 (set_attr "amdfam10_decode" "double")
7231 (set_attr "mode" "SI")])
7233 (define_expand "mulditi3"
7234 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7235 (mult:TI (sign_extend:TI
7236 (match_operand:DI 1 "nonimmediate_operand" ""))
7238 (match_operand:DI 2 "register_operand" ""))))
7239 (clobber (reg:CC FLAGS_REG))])]
7243 (define_insn "*mulditi3_insn"
7244 [(set (match_operand:TI 0 "register_operand" "=A")
7245 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7246 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7247 (clobber (reg:CC FLAGS_REG))]
7249 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7251 [(set_attr "type" "imul")
7252 (set_attr "length_immediate" "0")
7253 (set (attr "athlon_decode")
7254 (if_then_else (eq_attr "cpu" "athlon")
7255 (const_string "vector")
7256 (const_string "double")))
7257 (set_attr "amdfam10_decode" "double")
7258 (set_attr "mode" "DI")])
7260 (define_expand "mulsidi3"
7261 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7262 (mult:DI (sign_extend:DI
7263 (match_operand:SI 1 "nonimmediate_operand" ""))
7265 (match_operand:SI 2 "register_operand" ""))))
7266 (clobber (reg:CC FLAGS_REG))])]
7270 (define_insn "*mulsidi3_insn"
7271 [(set (match_operand:DI 0 "register_operand" "=A")
7272 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7273 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7274 (clobber (reg:CC FLAGS_REG))]
7276 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7278 [(set_attr "type" "imul")
7279 (set_attr "length_immediate" "0")
7280 (set (attr "athlon_decode")
7281 (if_then_else (eq_attr "cpu" "athlon")
7282 (const_string "vector")
7283 (const_string "double")))
7284 (set_attr "amdfam10_decode" "double")
7285 (set_attr "mode" "SI")])
7287 (define_expand "umuldi3_highpart"
7288 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7291 (mult:TI (zero_extend:TI
7292 (match_operand:DI 1 "nonimmediate_operand" ""))
7294 (match_operand:DI 2 "register_operand" "")))
7296 (clobber (match_scratch:DI 3 ""))
7297 (clobber (reg:CC FLAGS_REG))])]
7301 (define_insn "*umuldi3_highpart_rex64"
7302 [(set (match_operand:DI 0 "register_operand" "=d")
7305 (mult:TI (zero_extend:TI
7306 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7308 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7310 (clobber (match_scratch:DI 3 "=1"))
7311 (clobber (reg:CC FLAGS_REG))]
7313 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7315 [(set_attr "type" "imul")
7316 (set_attr "length_immediate" "0")
7317 (set (attr "athlon_decode")
7318 (if_then_else (eq_attr "cpu" "athlon")
7319 (const_string "vector")
7320 (const_string "double")))
7321 (set_attr "amdfam10_decode" "double")
7322 (set_attr "mode" "DI")])
7324 (define_expand "umulsi3_highpart"
7325 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7328 (mult:DI (zero_extend:DI
7329 (match_operand:SI 1 "nonimmediate_operand" ""))
7331 (match_operand:SI 2 "register_operand" "")))
7333 (clobber (match_scratch:SI 3 ""))
7334 (clobber (reg:CC FLAGS_REG))])]
7338 (define_insn "*umulsi3_highpart_insn"
7339 [(set (match_operand:SI 0 "register_operand" "=d")
7342 (mult:DI (zero_extend:DI
7343 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7345 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7347 (clobber (match_scratch:SI 3 "=1"))
7348 (clobber (reg:CC FLAGS_REG))]
7349 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7351 [(set_attr "type" "imul")
7352 (set_attr "length_immediate" "0")
7353 (set (attr "athlon_decode")
7354 (if_then_else (eq_attr "cpu" "athlon")
7355 (const_string "vector")
7356 (const_string "double")))
7357 (set_attr "amdfam10_decode" "double")
7358 (set_attr "mode" "SI")])
7360 (define_insn "*umulsi3_highpart_zext"
7361 [(set (match_operand:DI 0 "register_operand" "=d")
7362 (zero_extend:DI (truncate:SI
7364 (mult:DI (zero_extend:DI
7365 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7367 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7369 (clobber (match_scratch:SI 3 "=1"))
7370 (clobber (reg:CC FLAGS_REG))]
7372 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7374 [(set_attr "type" "imul")
7375 (set_attr "length_immediate" "0")
7376 (set (attr "athlon_decode")
7377 (if_then_else (eq_attr "cpu" "athlon")
7378 (const_string "vector")
7379 (const_string "double")))
7380 (set_attr "amdfam10_decode" "double")
7381 (set_attr "mode" "SI")])
7383 (define_expand "smuldi3_highpart"
7384 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7387 (mult:TI (sign_extend:TI
7388 (match_operand:DI 1 "nonimmediate_operand" ""))
7390 (match_operand:DI 2 "register_operand" "")))
7392 (clobber (match_scratch:DI 3 ""))
7393 (clobber (reg:CC FLAGS_REG))])]
7397 (define_insn "*smuldi3_highpart_rex64"
7398 [(set (match_operand:DI 0 "register_operand" "=d")
7401 (mult:TI (sign_extend:TI
7402 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7404 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7406 (clobber (match_scratch:DI 3 "=1"))
7407 (clobber (reg:CC FLAGS_REG))]
7409 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7411 [(set_attr "type" "imul")
7412 (set (attr "athlon_decode")
7413 (if_then_else (eq_attr "cpu" "athlon")
7414 (const_string "vector")
7415 (const_string "double")))
7416 (set_attr "amdfam10_decode" "double")
7417 (set_attr "mode" "DI")])
7419 (define_expand "smulsi3_highpart"
7420 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7423 (mult:DI (sign_extend:DI
7424 (match_operand:SI 1 "nonimmediate_operand" ""))
7426 (match_operand:SI 2 "register_operand" "")))
7428 (clobber (match_scratch:SI 3 ""))
7429 (clobber (reg:CC FLAGS_REG))])]
7433 (define_insn "*smulsi3_highpart_insn"
7434 [(set (match_operand:SI 0 "register_operand" "=d")
7437 (mult:DI (sign_extend:DI
7438 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7440 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7442 (clobber (match_scratch:SI 3 "=1"))
7443 (clobber (reg:CC FLAGS_REG))]
7444 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7446 [(set_attr "type" "imul")
7447 (set (attr "athlon_decode")
7448 (if_then_else (eq_attr "cpu" "athlon")
7449 (const_string "vector")
7450 (const_string "double")))
7451 (set_attr "amdfam10_decode" "double")
7452 (set_attr "mode" "SI")])
7454 (define_insn "*smulsi3_highpart_zext"
7455 [(set (match_operand:DI 0 "register_operand" "=d")
7456 (zero_extend:DI (truncate:SI
7458 (mult:DI (sign_extend:DI
7459 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7461 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7463 (clobber (match_scratch:SI 3 "=1"))
7464 (clobber (reg:CC FLAGS_REG))]
7466 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7468 [(set_attr "type" "imul")
7469 (set (attr "athlon_decode")
7470 (if_then_else (eq_attr "cpu" "athlon")
7471 (const_string "vector")
7472 (const_string "double")))
7473 (set_attr "amdfam10_decode" "double")
7474 (set_attr "mode" "SI")])
7476 ;; The patterns that match these are at the end of this file.
7478 (define_expand "mulxf3"
7479 [(set (match_operand:XF 0 "register_operand" "")
7480 (mult:XF (match_operand:XF 1 "register_operand" "")
7481 (match_operand:XF 2 "register_operand" "")))]
7485 (define_expand "muldf3"
7486 [(set (match_operand:DF 0 "register_operand" "")
7487 (mult:DF (match_operand:DF 1 "register_operand" "")
7488 (match_operand:DF 2 "nonimmediate_operand" "")))]
7489 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7492 (define_expand "mulsf3"
7493 [(set (match_operand:SF 0 "register_operand" "")
7494 (mult:SF (match_operand:SF 1 "register_operand" "")
7495 (match_operand:SF 2 "nonimmediate_operand" "")))]
7496 "TARGET_80387 || TARGET_SSE_MATH"
7499 ;; Divide instructions
7501 (define_insn "divqi3"
7502 [(set (match_operand:QI 0 "register_operand" "=a")
7503 (div:QI (match_operand:HI 1 "register_operand" "0")
7504 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "TARGET_QIMODE_MATH"
7508 [(set_attr "type" "idiv")
7509 (set_attr "mode" "QI")])
7511 (define_insn "udivqi3"
7512 [(set (match_operand:QI 0 "register_operand" "=a")
7513 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7514 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7515 (clobber (reg:CC FLAGS_REG))]
7516 "TARGET_QIMODE_MATH"
7518 [(set_attr "type" "idiv")
7519 (set_attr "mode" "QI")])
7521 ;; The patterns that match these are at the end of this file.
7523 (define_expand "divxf3"
7524 [(set (match_operand:XF 0 "register_operand" "")
7525 (div:XF (match_operand:XF 1 "register_operand" "")
7526 (match_operand:XF 2 "register_operand" "")))]
7530 (define_expand "divdf3"
7531 [(set (match_operand:DF 0 "register_operand" "")
7532 (div:DF (match_operand:DF 1 "register_operand" "")
7533 (match_operand:DF 2 "nonimmediate_operand" "")))]
7534 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7537 (define_expand "divsf3"
7538 [(set (match_operand:SF 0 "register_operand" "")
7539 (div:SF (match_operand:SF 1 "register_operand" "")
7540 (match_operand:SF 2 "nonimmediate_operand" "")))]
7541 "TARGET_80387 || TARGET_SSE_MATH"
7544 ;; Remainder instructions.
7546 (define_expand "divmoddi4"
7547 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7548 (div:DI (match_operand:DI 1 "register_operand" "")
7549 (match_operand:DI 2 "nonimmediate_operand" "")))
7550 (set (match_operand:DI 3 "register_operand" "")
7551 (mod:DI (match_dup 1) (match_dup 2)))
7552 (clobber (reg:CC FLAGS_REG))])]
7556 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7557 ;; Penalize eax case slightly because it results in worse scheduling
7559 (define_insn "*divmoddi4_nocltd_rex64"
7560 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7561 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7562 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7563 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7564 (mod:DI (match_dup 2) (match_dup 3)))
7565 (clobber (reg:CC FLAGS_REG))]
7566 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7568 [(set_attr "type" "multi")])
7570 (define_insn "*divmoddi4_cltd_rex64"
7571 [(set (match_operand:DI 0 "register_operand" "=a")
7572 (div:DI (match_operand:DI 2 "register_operand" "a")
7573 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7574 (set (match_operand:DI 1 "register_operand" "=&d")
7575 (mod:DI (match_dup 2) (match_dup 3)))
7576 (clobber (reg:CC FLAGS_REG))]
7577 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7579 [(set_attr "type" "multi")])
7581 (define_insn "*divmoddi_noext_rex64"
7582 [(set (match_operand:DI 0 "register_operand" "=a")
7583 (div:DI (match_operand:DI 1 "register_operand" "0")
7584 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7585 (set (match_operand:DI 3 "register_operand" "=d")
7586 (mod:DI (match_dup 1) (match_dup 2)))
7587 (use (match_operand:DI 4 "register_operand" "3"))
7588 (clobber (reg:CC FLAGS_REG))]
7591 [(set_attr "type" "idiv")
7592 (set_attr "mode" "DI")])
7595 [(set (match_operand:DI 0 "register_operand" "")
7596 (div:DI (match_operand:DI 1 "register_operand" "")
7597 (match_operand:DI 2 "nonimmediate_operand" "")))
7598 (set (match_operand:DI 3 "register_operand" "")
7599 (mod:DI (match_dup 1) (match_dup 2)))
7600 (clobber (reg:CC FLAGS_REG))]
7601 "TARGET_64BIT && reload_completed"
7602 [(parallel [(set (match_dup 3)
7603 (ashiftrt:DI (match_dup 4) (const_int 63)))
7604 (clobber (reg:CC FLAGS_REG))])
7605 (parallel [(set (match_dup 0)
7606 (div:DI (reg:DI 0) (match_dup 2)))
7608 (mod:DI (reg:DI 0) (match_dup 2)))
7610 (clobber (reg:CC FLAGS_REG))])]
7612 /* Avoid use of cltd in favor of a mov+shift. */
7613 if (!TARGET_USE_CLTD && !optimize_size)
7615 if (true_regnum (operands[1]))
7616 emit_move_insn (operands[0], operands[1]);
7618 emit_move_insn (operands[3], operands[1]);
7619 operands[4] = operands[3];
7623 gcc_assert (!true_regnum (operands[1]));
7624 operands[4] = operands[1];
7629 (define_expand "divmodsi4"
7630 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7631 (div:SI (match_operand:SI 1 "register_operand" "")
7632 (match_operand:SI 2 "nonimmediate_operand" "")))
7633 (set (match_operand:SI 3 "register_operand" "")
7634 (mod:SI (match_dup 1) (match_dup 2)))
7635 (clobber (reg:CC FLAGS_REG))])]
7639 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7640 ;; Penalize eax case slightly because it results in worse scheduling
7642 (define_insn "*divmodsi4_nocltd"
7643 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7644 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7645 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7646 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7647 (mod:SI (match_dup 2) (match_dup 3)))
7648 (clobber (reg:CC FLAGS_REG))]
7649 "!optimize_size && !TARGET_USE_CLTD"
7651 [(set_attr "type" "multi")])
7653 (define_insn "*divmodsi4_cltd"
7654 [(set (match_operand:SI 0 "register_operand" "=a")
7655 (div:SI (match_operand:SI 2 "register_operand" "a")
7656 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7657 (set (match_operand:SI 1 "register_operand" "=&d")
7658 (mod:SI (match_dup 2) (match_dup 3)))
7659 (clobber (reg:CC FLAGS_REG))]
7660 "optimize_size || TARGET_USE_CLTD"
7662 [(set_attr "type" "multi")])
7664 (define_insn "*divmodsi_noext"
7665 [(set (match_operand:SI 0 "register_operand" "=a")
7666 (div:SI (match_operand:SI 1 "register_operand" "0")
7667 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7668 (set (match_operand:SI 3 "register_operand" "=d")
7669 (mod:SI (match_dup 1) (match_dup 2)))
7670 (use (match_operand:SI 4 "register_operand" "3"))
7671 (clobber (reg:CC FLAGS_REG))]
7674 [(set_attr "type" "idiv")
7675 (set_attr "mode" "SI")])
7678 [(set (match_operand:SI 0 "register_operand" "")
7679 (div:SI (match_operand:SI 1 "register_operand" "")
7680 (match_operand:SI 2 "nonimmediate_operand" "")))
7681 (set (match_operand:SI 3 "register_operand" "")
7682 (mod:SI (match_dup 1) (match_dup 2)))
7683 (clobber (reg:CC FLAGS_REG))]
7685 [(parallel [(set (match_dup 3)
7686 (ashiftrt:SI (match_dup 4) (const_int 31)))
7687 (clobber (reg:CC FLAGS_REG))])
7688 (parallel [(set (match_dup 0)
7689 (div:SI (reg:SI 0) (match_dup 2)))
7691 (mod:SI (reg:SI 0) (match_dup 2)))
7693 (clobber (reg:CC FLAGS_REG))])]
7695 /* Avoid use of cltd in favor of a mov+shift. */
7696 if (!TARGET_USE_CLTD && !optimize_size)
7698 if (true_regnum (operands[1]))
7699 emit_move_insn (operands[0], operands[1]);
7701 emit_move_insn (operands[3], operands[1]);
7702 operands[4] = operands[3];
7706 gcc_assert (!true_regnum (operands[1]));
7707 operands[4] = operands[1];
7711 (define_insn "divmodhi4"
7712 [(set (match_operand:HI 0 "register_operand" "=a")
7713 (div:HI (match_operand:HI 1 "register_operand" "0")
7714 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7715 (set (match_operand:HI 3 "register_operand" "=&d")
7716 (mod:HI (match_dup 1) (match_dup 2)))
7717 (clobber (reg:CC FLAGS_REG))]
7718 "TARGET_HIMODE_MATH"
7720 [(set_attr "type" "multi")
7721 (set_attr "length_immediate" "0")
7722 (set_attr "mode" "SI")])
7724 (define_insn "udivmoddi4"
7725 [(set (match_operand:DI 0 "register_operand" "=a")
7726 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7727 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7728 (set (match_operand:DI 3 "register_operand" "=&d")
7729 (umod:DI (match_dup 1) (match_dup 2)))
7730 (clobber (reg:CC FLAGS_REG))]
7732 "xor{q}\t%3, %3\;div{q}\t%2"
7733 [(set_attr "type" "multi")
7734 (set_attr "length_immediate" "0")
7735 (set_attr "mode" "DI")])
7737 (define_insn "*udivmoddi4_noext"
7738 [(set (match_operand:DI 0 "register_operand" "=a")
7739 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7740 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7741 (set (match_operand:DI 3 "register_operand" "=d")
7742 (umod:DI (match_dup 1) (match_dup 2)))
7744 (clobber (reg:CC FLAGS_REG))]
7747 [(set_attr "type" "idiv")
7748 (set_attr "mode" "DI")])
7751 [(set (match_operand:DI 0 "register_operand" "")
7752 (udiv:DI (match_operand:DI 1 "register_operand" "")
7753 (match_operand:DI 2 "nonimmediate_operand" "")))
7754 (set (match_operand:DI 3 "register_operand" "")
7755 (umod:DI (match_dup 1) (match_dup 2)))
7756 (clobber (reg:CC FLAGS_REG))]
7757 "TARGET_64BIT && reload_completed"
7758 [(set (match_dup 3) (const_int 0))
7759 (parallel [(set (match_dup 0)
7760 (udiv:DI (match_dup 1) (match_dup 2)))
7762 (umod:DI (match_dup 1) (match_dup 2)))
7764 (clobber (reg:CC FLAGS_REG))])]
7767 (define_insn "udivmodsi4"
7768 [(set (match_operand:SI 0 "register_operand" "=a")
7769 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7770 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7771 (set (match_operand:SI 3 "register_operand" "=&d")
7772 (umod:SI (match_dup 1) (match_dup 2)))
7773 (clobber (reg:CC FLAGS_REG))]
7775 "xor{l}\t%3, %3\;div{l}\t%2"
7776 [(set_attr "type" "multi")
7777 (set_attr "length_immediate" "0")
7778 (set_attr "mode" "SI")])
7780 (define_insn "*udivmodsi4_noext"
7781 [(set (match_operand:SI 0 "register_operand" "=a")
7782 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7783 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7784 (set (match_operand:SI 3 "register_operand" "=d")
7785 (umod:SI (match_dup 1) (match_dup 2)))
7787 (clobber (reg:CC FLAGS_REG))]
7790 [(set_attr "type" "idiv")
7791 (set_attr "mode" "SI")])
7794 [(set (match_operand:SI 0 "register_operand" "")
7795 (udiv:SI (match_operand:SI 1 "register_operand" "")
7796 (match_operand:SI 2 "nonimmediate_operand" "")))
7797 (set (match_operand:SI 3 "register_operand" "")
7798 (umod:SI (match_dup 1) (match_dup 2)))
7799 (clobber (reg:CC FLAGS_REG))]
7801 [(set (match_dup 3) (const_int 0))
7802 (parallel [(set (match_dup 0)
7803 (udiv:SI (match_dup 1) (match_dup 2)))
7805 (umod:SI (match_dup 1) (match_dup 2)))
7807 (clobber (reg:CC FLAGS_REG))])]
7810 (define_expand "udivmodhi4"
7811 [(set (match_dup 4) (const_int 0))
7812 (parallel [(set (match_operand:HI 0 "register_operand" "")
7813 (udiv:HI (match_operand:HI 1 "register_operand" "")
7814 (match_operand:HI 2 "nonimmediate_operand" "")))
7815 (set (match_operand:HI 3 "register_operand" "")
7816 (umod:HI (match_dup 1) (match_dup 2)))
7818 (clobber (reg:CC FLAGS_REG))])]
7819 "TARGET_HIMODE_MATH"
7820 "operands[4] = gen_reg_rtx (HImode);")
7822 (define_insn "*udivmodhi_noext"
7823 [(set (match_operand:HI 0 "register_operand" "=a")
7824 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7825 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7826 (set (match_operand:HI 3 "register_operand" "=d")
7827 (umod:HI (match_dup 1) (match_dup 2)))
7828 (use (match_operand:HI 4 "register_operand" "3"))
7829 (clobber (reg:CC FLAGS_REG))]
7832 [(set_attr "type" "idiv")
7833 (set_attr "mode" "HI")])
7835 ;; We cannot use div/idiv for double division, because it causes
7836 ;; "division by zero" on the overflow and that's not what we expect
7837 ;; from truncate. Because true (non truncating) double division is
7838 ;; never generated, we can't create this insn anyway.
7841 ; [(set (match_operand:SI 0 "register_operand" "=a")
7843 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7845 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7846 ; (set (match_operand:SI 3 "register_operand" "=d")
7848 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7849 ; (clobber (reg:CC FLAGS_REG))]
7851 ; "div{l}\t{%2, %0|%0, %2}"
7852 ; [(set_attr "type" "idiv")])
7854 ;;- Logical AND instructions
7856 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7857 ;; Note that this excludes ah.
7859 (define_insn "*testdi_1_rex64"
7860 [(set (reg FLAGS_REG)
7862 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7863 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7865 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7866 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7868 test{l}\t{%k1, %k0|%k0, %k1}
7869 test{l}\t{%k1, %k0|%k0, %k1}
7870 test{q}\t{%1, %0|%0, %1}
7871 test{q}\t{%1, %0|%0, %1}
7872 test{q}\t{%1, %0|%0, %1}"
7873 [(set_attr "type" "test")
7874 (set_attr "modrm" "0,1,0,1,1")
7875 (set_attr "mode" "SI,SI,DI,DI,DI")
7876 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7878 (define_insn "testsi_1"
7879 [(set (reg FLAGS_REG)
7881 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7882 (match_operand:SI 1 "general_operand" "in,in,rin"))
7884 "ix86_match_ccmode (insn, CCNOmode)
7885 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7886 "test{l}\t{%1, %0|%0, %1}"
7887 [(set_attr "type" "test")
7888 (set_attr "modrm" "0,1,1")
7889 (set_attr "mode" "SI")
7890 (set_attr "pent_pair" "uv,np,uv")])
7892 (define_expand "testsi_ccno_1"
7893 [(set (reg:CCNO FLAGS_REG)
7895 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7896 (match_operand:SI 1 "nonmemory_operand" ""))
7901 (define_insn "*testhi_1"
7902 [(set (reg FLAGS_REG)
7903 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7904 (match_operand:HI 1 "general_operand" "n,n,rn"))
7906 "ix86_match_ccmode (insn, CCNOmode)
7907 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7908 "test{w}\t{%1, %0|%0, %1}"
7909 [(set_attr "type" "test")
7910 (set_attr "modrm" "0,1,1")
7911 (set_attr "mode" "HI")
7912 (set_attr "pent_pair" "uv,np,uv")])
7914 (define_expand "testqi_ccz_1"
7915 [(set (reg:CCZ FLAGS_REG)
7916 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7917 (match_operand:QI 1 "nonmemory_operand" ""))
7922 (define_insn "*testqi_1_maybe_si"
7923 [(set (reg FLAGS_REG)
7926 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7927 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7929 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7930 && ix86_match_ccmode (insn,
7931 CONST_INT_P (operands[1])
7932 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7934 if (which_alternative == 3)
7936 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7937 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7938 return "test{l}\t{%1, %k0|%k0, %1}";
7940 return "test{b}\t{%1, %0|%0, %1}";
7942 [(set_attr "type" "test")
7943 (set_attr "modrm" "0,1,1,1")
7944 (set_attr "mode" "QI,QI,QI,SI")
7945 (set_attr "pent_pair" "uv,np,uv,np")])
7947 (define_insn "*testqi_1"
7948 [(set (reg FLAGS_REG)
7951 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7952 (match_operand:QI 1 "general_operand" "n,n,qn"))
7954 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7955 && ix86_match_ccmode (insn, CCNOmode)"
7956 "test{b}\t{%1, %0|%0, %1}"
7957 [(set_attr "type" "test")
7958 (set_attr "modrm" "0,1,1")
7959 (set_attr "mode" "QI")
7960 (set_attr "pent_pair" "uv,np,uv")])
7962 (define_expand "testqi_ext_ccno_0"
7963 [(set (reg:CCNO FLAGS_REG)
7967 (match_operand 0 "ext_register_operand" "")
7970 (match_operand 1 "const_int_operand" ""))
7975 (define_insn "*testqi_ext_0"
7976 [(set (reg FLAGS_REG)
7980 (match_operand 0 "ext_register_operand" "Q")
7983 (match_operand 1 "const_int_operand" "n"))
7985 "ix86_match_ccmode (insn, CCNOmode)"
7986 "test{b}\t{%1, %h0|%h0, %1}"
7987 [(set_attr "type" "test")
7988 (set_attr "mode" "QI")
7989 (set_attr "length_immediate" "1")
7990 (set_attr "pent_pair" "np")])
7992 (define_insn "*testqi_ext_1"
7993 [(set (reg FLAGS_REG)
7997 (match_operand 0 "ext_register_operand" "Q")
8001 (match_operand:QI 1 "general_operand" "Qm")))
8003 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8004 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8005 "test{b}\t{%1, %h0|%h0, %1}"
8006 [(set_attr "type" "test")
8007 (set_attr "mode" "QI")])
8009 (define_insn "*testqi_ext_1_rex64"
8010 [(set (reg FLAGS_REG)
8014 (match_operand 0 "ext_register_operand" "Q")
8018 (match_operand:QI 1 "register_operand" "Q")))
8020 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8021 "test{b}\t{%1, %h0|%h0, %1}"
8022 [(set_attr "type" "test")
8023 (set_attr "mode" "QI")])
8025 (define_insn "*testqi_ext_2"
8026 [(set (reg FLAGS_REG)
8030 (match_operand 0 "ext_register_operand" "Q")
8034 (match_operand 1 "ext_register_operand" "Q")
8038 "ix86_match_ccmode (insn, CCNOmode)"
8039 "test{b}\t{%h1, %h0|%h0, %h1}"
8040 [(set_attr "type" "test")
8041 (set_attr "mode" "QI")])
8043 ;; Combine likes to form bit extractions for some tests. Humor it.
8044 (define_insn "*testqi_ext_3"
8045 [(set (reg FLAGS_REG)
8046 (compare (zero_extract:SI
8047 (match_operand 0 "nonimmediate_operand" "rm")
8048 (match_operand:SI 1 "const_int_operand" "")
8049 (match_operand:SI 2 "const_int_operand" ""))
8051 "ix86_match_ccmode (insn, CCNOmode)
8052 && INTVAL (operands[1]) > 0
8053 && INTVAL (operands[2]) >= 0
8054 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8055 && (GET_MODE (operands[0]) == SImode
8056 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8057 || GET_MODE (operands[0]) == HImode
8058 || GET_MODE (operands[0]) == QImode)"
8061 (define_insn "*testqi_ext_3_rex64"
8062 [(set (reg FLAGS_REG)
8063 (compare (zero_extract:DI
8064 (match_operand 0 "nonimmediate_operand" "rm")
8065 (match_operand:DI 1 "const_int_operand" "")
8066 (match_operand:DI 2 "const_int_operand" ""))
8069 && ix86_match_ccmode (insn, CCNOmode)
8070 && INTVAL (operands[1]) > 0
8071 && INTVAL (operands[2]) >= 0
8072 /* Ensure that resulting mask is zero or sign extended operand. */
8073 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8074 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8075 && INTVAL (operands[1]) > 32))
8076 && (GET_MODE (operands[0]) == SImode
8077 || GET_MODE (operands[0]) == DImode
8078 || GET_MODE (operands[0]) == HImode
8079 || GET_MODE (operands[0]) == QImode)"
8083 [(set (match_operand 0 "flags_reg_operand" "")
8084 (match_operator 1 "compare_operator"
8086 (match_operand 2 "nonimmediate_operand" "")
8087 (match_operand 3 "const_int_operand" "")
8088 (match_operand 4 "const_int_operand" ""))
8090 "ix86_match_ccmode (insn, CCNOmode)"
8091 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8093 rtx val = operands[2];
8094 HOST_WIDE_INT len = INTVAL (operands[3]);
8095 HOST_WIDE_INT pos = INTVAL (operands[4]);
8097 enum machine_mode mode, submode;
8099 mode = GET_MODE (val);
8102 /* ??? Combine likes to put non-volatile mem extractions in QImode
8103 no matter the size of the test. So find a mode that works. */
8104 if (! MEM_VOLATILE_P (val))
8106 mode = smallest_mode_for_size (pos + len, MODE_INT);
8107 val = adjust_address (val, mode, 0);
8110 else if (GET_CODE (val) == SUBREG
8111 && (submode = GET_MODE (SUBREG_REG (val)),
8112 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8113 && pos + len <= GET_MODE_BITSIZE (submode))
8115 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8117 val = SUBREG_REG (val);
8119 else if (mode == HImode && pos + len <= 8)
8121 /* Small HImode tests can be converted to QImode. */
8123 val = gen_lowpart (QImode, val);
8126 if (len == HOST_BITS_PER_WIDE_INT)
8129 mask = ((HOST_WIDE_INT)1 << len) - 1;
8132 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8135 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8136 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8137 ;; this is relatively important trick.
8138 ;; Do the conversion only post-reload to avoid limiting of the register class
8141 [(set (match_operand 0 "flags_reg_operand" "")
8142 (match_operator 1 "compare_operator"
8143 [(and (match_operand 2 "register_operand" "")
8144 (match_operand 3 "const_int_operand" ""))
8147 && QI_REG_P (operands[2])
8148 && GET_MODE (operands[2]) != QImode
8149 && ((ix86_match_ccmode (insn, CCZmode)
8150 && !(INTVAL (operands[3]) & ~(255 << 8)))
8151 || (ix86_match_ccmode (insn, CCNOmode)
8152 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8155 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8158 "operands[2] = gen_lowpart (SImode, operands[2]);
8159 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8162 [(set (match_operand 0 "flags_reg_operand" "")
8163 (match_operator 1 "compare_operator"
8164 [(and (match_operand 2 "nonimmediate_operand" "")
8165 (match_operand 3 "const_int_operand" ""))
8168 && GET_MODE (operands[2]) != QImode
8169 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8170 && ((ix86_match_ccmode (insn, CCZmode)
8171 && !(INTVAL (operands[3]) & ~255))
8172 || (ix86_match_ccmode (insn, CCNOmode)
8173 && !(INTVAL (operands[3]) & ~127)))"
8175 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8177 "operands[2] = gen_lowpart (QImode, operands[2]);
8178 operands[3] = gen_lowpart (QImode, operands[3]);")
8181 ;; %%% This used to optimize known byte-wide and operations to memory,
8182 ;; and sometimes to QImode registers. If this is considered useful,
8183 ;; it should be done with splitters.
8185 (define_expand "anddi3"
8186 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8187 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8188 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8189 (clobber (reg:CC FLAGS_REG))]
8191 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8193 (define_insn "*anddi_1_rex64"
8194 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8195 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8196 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8197 (clobber (reg:CC FLAGS_REG))]
8198 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8200 switch (get_attr_type (insn))
8204 enum machine_mode mode;
8206 gcc_assert (CONST_INT_P (operands[2]));
8207 if (INTVAL (operands[2]) == 0xff)
8211 gcc_assert (INTVAL (operands[2]) == 0xffff);
8215 operands[1] = gen_lowpart (mode, operands[1]);
8217 return "movz{bq|x}\t{%1,%0|%0, %1}";
8219 return "movz{wq|x}\t{%1,%0|%0, %1}";
8223 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8224 if (get_attr_mode (insn) == MODE_SI)
8225 return "and{l}\t{%k2, %k0|%k0, %k2}";
8227 return "and{q}\t{%2, %0|%0, %2}";
8230 [(set_attr "type" "alu,alu,alu,imovx")
8231 (set_attr "length_immediate" "*,*,*,0")
8232 (set_attr "mode" "SI,DI,DI,DI")])
8234 (define_insn "*anddi_2"
8235 [(set (reg FLAGS_REG)
8236 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8237 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8239 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8240 (and:DI (match_dup 1) (match_dup 2)))]
8241 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8242 && ix86_binary_operator_ok (AND, DImode, operands)"
8244 and{l}\t{%k2, %k0|%k0, %k2}
8245 and{q}\t{%2, %0|%0, %2}
8246 and{q}\t{%2, %0|%0, %2}"
8247 [(set_attr "type" "alu")
8248 (set_attr "mode" "SI,DI,DI")])
8250 (define_expand "andsi3"
8251 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8252 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8253 (match_operand:SI 2 "general_operand" "")))
8254 (clobber (reg:CC FLAGS_REG))]
8256 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8258 (define_insn "*andsi_1"
8259 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8260 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8261 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8262 (clobber (reg:CC FLAGS_REG))]
8263 "ix86_binary_operator_ok (AND, SImode, operands)"
8265 switch (get_attr_type (insn))
8269 enum machine_mode mode;
8271 gcc_assert (CONST_INT_P (operands[2]));
8272 if (INTVAL (operands[2]) == 0xff)
8276 gcc_assert (INTVAL (operands[2]) == 0xffff);
8280 operands[1] = gen_lowpart (mode, operands[1]);
8282 return "movz{bl|x}\t{%1,%0|%0, %1}";
8284 return "movz{wl|x}\t{%1,%0|%0, %1}";
8288 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8289 return "and{l}\t{%2, %0|%0, %2}";
8292 [(set_attr "type" "alu,alu,imovx")
8293 (set_attr "length_immediate" "*,*,0")
8294 (set_attr "mode" "SI")])
8297 [(set (match_operand 0 "register_operand" "")
8299 (const_int -65536)))
8300 (clobber (reg:CC FLAGS_REG))]
8301 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8302 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8303 "operands[1] = gen_lowpart (HImode, operands[0]);")
8306 [(set (match_operand 0 "ext_register_operand" "")
8309 (clobber (reg:CC FLAGS_REG))]
8310 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8311 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8312 "operands[1] = gen_lowpart (QImode, operands[0]);")
8315 [(set (match_operand 0 "ext_register_operand" "")
8317 (const_int -65281)))
8318 (clobber (reg:CC FLAGS_REG))]
8319 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8320 [(parallel [(set (zero_extract:SI (match_dup 0)
8324 (zero_extract:SI (match_dup 0)
8327 (zero_extract:SI (match_dup 0)
8330 (clobber (reg:CC FLAGS_REG))])]
8331 "operands[0] = gen_lowpart (SImode, operands[0]);")
8333 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8334 (define_insn "*andsi_1_zext"
8335 [(set (match_operand:DI 0 "register_operand" "=r")
8337 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8338 (match_operand:SI 2 "general_operand" "rim"))))
8339 (clobber (reg:CC FLAGS_REG))]
8340 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8341 "and{l}\t{%2, %k0|%k0, %2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "mode" "SI")])
8345 (define_insn "*andsi_2"
8346 [(set (reg FLAGS_REG)
8347 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8348 (match_operand:SI 2 "general_operand" "rim,ri"))
8350 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8351 (and:SI (match_dup 1) (match_dup 2)))]
8352 "ix86_match_ccmode (insn, CCNOmode)
8353 && ix86_binary_operator_ok (AND, SImode, operands)"
8354 "and{l}\t{%2, %0|%0, %2}"
8355 [(set_attr "type" "alu")
8356 (set_attr "mode" "SI")])
8358 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8359 (define_insn "*andsi_2_zext"
8360 [(set (reg FLAGS_REG)
8361 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8362 (match_operand:SI 2 "general_operand" "rim"))
8364 (set (match_operand:DI 0 "register_operand" "=r")
8365 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8366 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8367 && ix86_binary_operator_ok (AND, SImode, operands)"
8368 "and{l}\t{%2, %k0|%k0, %2}"
8369 [(set_attr "type" "alu")
8370 (set_attr "mode" "SI")])
8372 (define_expand "andhi3"
8373 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8374 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8375 (match_operand:HI 2 "general_operand" "")))
8376 (clobber (reg:CC FLAGS_REG))]
8377 "TARGET_HIMODE_MATH"
8378 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8380 (define_insn "*andhi_1"
8381 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8382 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8383 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8384 (clobber (reg:CC FLAGS_REG))]
8385 "ix86_binary_operator_ok (AND, HImode, operands)"
8387 switch (get_attr_type (insn))
8390 gcc_assert (CONST_INT_P (operands[2]));
8391 gcc_assert (INTVAL (operands[2]) == 0xff);
8392 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8395 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8397 return "and{w}\t{%2, %0|%0, %2}";
8400 [(set_attr "type" "alu,alu,imovx")
8401 (set_attr "length_immediate" "*,*,0")
8402 (set_attr "mode" "HI,HI,SI")])
8404 (define_insn "*andhi_2"
8405 [(set (reg FLAGS_REG)
8406 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8407 (match_operand:HI 2 "general_operand" "rim,ri"))
8409 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8410 (and:HI (match_dup 1) (match_dup 2)))]
8411 "ix86_match_ccmode (insn, CCNOmode)
8412 && ix86_binary_operator_ok (AND, HImode, operands)"
8413 "and{w}\t{%2, %0|%0, %2}"
8414 [(set_attr "type" "alu")
8415 (set_attr "mode" "HI")])
8417 (define_expand "andqi3"
8418 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8419 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8420 (match_operand:QI 2 "general_operand" "")))
8421 (clobber (reg:CC FLAGS_REG))]
8422 "TARGET_QIMODE_MATH"
8423 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8425 ;; %%% Potential partial reg stall on alternative 2. What to do?
8426 (define_insn "*andqi_1"
8427 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8428 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8429 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8430 (clobber (reg:CC FLAGS_REG))]
8431 "ix86_binary_operator_ok (AND, QImode, operands)"
8433 and{b}\t{%2, %0|%0, %2}
8434 and{b}\t{%2, %0|%0, %2}
8435 and{l}\t{%k2, %k0|%k0, %k2}"
8436 [(set_attr "type" "alu")
8437 (set_attr "mode" "QI,QI,SI")])
8439 (define_insn "*andqi_1_slp"
8440 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8441 (and:QI (match_dup 0)
8442 (match_operand:QI 1 "general_operand" "qi,qmi")))
8443 (clobber (reg:CC FLAGS_REG))]
8444 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8445 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8446 "and{b}\t{%1, %0|%0, %1}"
8447 [(set_attr "type" "alu1")
8448 (set_attr "mode" "QI")])
8450 (define_insn "*andqi_2_maybe_si"
8451 [(set (reg FLAGS_REG)
8453 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8454 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8456 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8457 (and:QI (match_dup 1) (match_dup 2)))]
8458 "ix86_binary_operator_ok (AND, QImode, operands)
8459 && ix86_match_ccmode (insn,
8460 CONST_INT_P (operands[2])
8461 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8463 if (which_alternative == 2)
8465 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8466 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8467 return "and{l}\t{%2, %k0|%k0, %2}";
8469 return "and{b}\t{%2, %0|%0, %2}";
8471 [(set_attr "type" "alu")
8472 (set_attr "mode" "QI,QI,SI")])
8474 (define_insn "*andqi_2"
8475 [(set (reg FLAGS_REG)
8477 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8478 (match_operand:QI 2 "general_operand" "qim,qi"))
8480 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8481 (and:QI (match_dup 1) (match_dup 2)))]
8482 "ix86_match_ccmode (insn, CCNOmode)
8483 && ix86_binary_operator_ok (AND, QImode, operands)"
8484 "and{b}\t{%2, %0|%0, %2}"
8485 [(set_attr "type" "alu")
8486 (set_attr "mode" "QI")])
8488 (define_insn "*andqi_2_slp"
8489 [(set (reg FLAGS_REG)
8491 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8492 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8494 (set (strict_low_part (match_dup 0))
8495 (and:QI (match_dup 0) (match_dup 1)))]
8496 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8497 && ix86_match_ccmode (insn, CCNOmode)
8498 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8499 "and{b}\t{%1, %0|%0, %1}"
8500 [(set_attr "type" "alu1")
8501 (set_attr "mode" "QI")])
8503 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8504 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8505 ;; for a QImode operand, which of course failed.
8507 (define_insn "andqi_ext_0"
8508 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8513 (match_operand 1 "ext_register_operand" "0")
8516 (match_operand 2 "const_int_operand" "n")))
8517 (clobber (reg:CC FLAGS_REG))]
8519 "and{b}\t{%2, %h0|%h0, %2}"
8520 [(set_attr "type" "alu")
8521 (set_attr "length_immediate" "1")
8522 (set_attr "mode" "QI")])
8524 ;; Generated by peephole translating test to and. This shows up
8525 ;; often in fp comparisons.
8527 (define_insn "*andqi_ext_0_cc"
8528 [(set (reg FLAGS_REG)
8532 (match_operand 1 "ext_register_operand" "0")
8535 (match_operand 2 "const_int_operand" "n"))
8537 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8546 "ix86_match_ccmode (insn, CCNOmode)"
8547 "and{b}\t{%2, %h0|%h0, %2}"
8548 [(set_attr "type" "alu")
8549 (set_attr "length_immediate" "1")
8550 (set_attr "mode" "QI")])
8552 (define_insn "*andqi_ext_1"
8553 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8558 (match_operand 1 "ext_register_operand" "0")
8562 (match_operand:QI 2 "general_operand" "Qm"))))
8563 (clobber (reg:CC FLAGS_REG))]
8565 "and{b}\t{%2, %h0|%h0, %2}"
8566 [(set_attr "type" "alu")
8567 (set_attr "length_immediate" "0")
8568 (set_attr "mode" "QI")])
8570 (define_insn "*andqi_ext_1_rex64"
8571 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8576 (match_operand 1 "ext_register_operand" "0")
8580 (match_operand 2 "ext_register_operand" "Q"))))
8581 (clobber (reg:CC FLAGS_REG))]
8583 "and{b}\t{%2, %h0|%h0, %2}"
8584 [(set_attr "type" "alu")
8585 (set_attr "length_immediate" "0")
8586 (set_attr "mode" "QI")])
8588 (define_insn "*andqi_ext_2"
8589 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8594 (match_operand 1 "ext_register_operand" "%0")
8598 (match_operand 2 "ext_register_operand" "Q")
8601 (clobber (reg:CC FLAGS_REG))]
8603 "and{b}\t{%h2, %h0|%h0, %h2}"
8604 [(set_attr "type" "alu")
8605 (set_attr "length_immediate" "0")
8606 (set_attr "mode" "QI")])
8608 ;; Convert wide AND instructions with immediate operand to shorter QImode
8609 ;; equivalents when possible.
8610 ;; Don't do the splitting with memory operands, since it introduces risk
8611 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8612 ;; for size, but that can (should?) be handled by generic code instead.
8614 [(set (match_operand 0 "register_operand" "")
8615 (and (match_operand 1 "register_operand" "")
8616 (match_operand 2 "const_int_operand" "")))
8617 (clobber (reg:CC FLAGS_REG))]
8619 && QI_REG_P (operands[0])
8620 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8621 && !(~INTVAL (operands[2]) & ~(255 << 8))
8622 && GET_MODE (operands[0]) != QImode"
8623 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8624 (and:SI (zero_extract:SI (match_dup 1)
8625 (const_int 8) (const_int 8))
8627 (clobber (reg:CC FLAGS_REG))])]
8628 "operands[0] = gen_lowpart (SImode, operands[0]);
8629 operands[1] = gen_lowpart (SImode, operands[1]);
8630 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8632 ;; Since AND can be encoded with sign extended immediate, this is only
8633 ;; profitable when 7th bit is not set.
8635 [(set (match_operand 0 "register_operand" "")
8636 (and (match_operand 1 "general_operand" "")
8637 (match_operand 2 "const_int_operand" "")))
8638 (clobber (reg:CC FLAGS_REG))]
8640 && ANY_QI_REG_P (operands[0])
8641 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8642 && !(~INTVAL (operands[2]) & ~255)
8643 && !(INTVAL (operands[2]) & 128)
8644 && GET_MODE (operands[0]) != QImode"
8645 [(parallel [(set (strict_low_part (match_dup 0))
8646 (and:QI (match_dup 1)
8648 (clobber (reg:CC FLAGS_REG))])]
8649 "operands[0] = gen_lowpart (QImode, operands[0]);
8650 operands[1] = gen_lowpart (QImode, operands[1]);
8651 operands[2] = gen_lowpart (QImode, operands[2]);")
8653 ;; Logical inclusive OR instructions
8655 ;; %%% This used to optimize known byte-wide and operations to memory.
8656 ;; If this is considered useful, it should be done with splitters.
8658 (define_expand "iordi3"
8659 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8660 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8661 (match_operand:DI 2 "x86_64_general_operand" "")))
8662 (clobber (reg:CC FLAGS_REG))]
8664 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8666 (define_insn "*iordi_1_rex64"
8667 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8668 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8669 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8670 (clobber (reg:CC FLAGS_REG))]
8672 && ix86_binary_operator_ok (IOR, DImode, operands)"
8673 "or{q}\t{%2, %0|%0, %2}"
8674 [(set_attr "type" "alu")
8675 (set_attr "mode" "DI")])
8677 (define_insn "*iordi_2_rex64"
8678 [(set (reg FLAGS_REG)
8679 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8680 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8682 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8683 (ior:DI (match_dup 1) (match_dup 2)))]
8685 && ix86_match_ccmode (insn, CCNOmode)
8686 && ix86_binary_operator_ok (IOR, DImode, operands)"
8687 "or{q}\t{%2, %0|%0, %2}"
8688 [(set_attr "type" "alu")
8689 (set_attr "mode" "DI")])
8691 (define_insn "*iordi_3_rex64"
8692 [(set (reg FLAGS_REG)
8693 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8694 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8696 (clobber (match_scratch:DI 0 "=r"))]
8698 && ix86_match_ccmode (insn, CCNOmode)
8699 && ix86_binary_operator_ok (IOR, DImode, operands)"
8700 "or{q}\t{%2, %0|%0, %2}"
8701 [(set_attr "type" "alu")
8702 (set_attr "mode" "DI")])
8705 (define_expand "iorsi3"
8706 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8707 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8708 (match_operand:SI 2 "general_operand" "")))
8709 (clobber (reg:CC FLAGS_REG))]
8711 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8713 (define_insn "*iorsi_1"
8714 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8715 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8716 (match_operand:SI 2 "general_operand" "ri,rmi")))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "ix86_binary_operator_ok (IOR, SImode, operands)"
8719 "or{l}\t{%2, %0|%0, %2}"
8720 [(set_attr "type" "alu")
8721 (set_attr "mode" "SI")])
8723 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8724 (define_insn "*iorsi_1_zext"
8725 [(set (match_operand:DI 0 "register_operand" "=rm")
8727 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8728 (match_operand:SI 2 "general_operand" "rim"))))
8729 (clobber (reg:CC FLAGS_REG))]
8730 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8731 "or{l}\t{%2, %k0|%k0, %2}"
8732 [(set_attr "type" "alu")
8733 (set_attr "mode" "SI")])
8735 (define_insn "*iorsi_1_zext_imm"
8736 [(set (match_operand:DI 0 "register_operand" "=rm")
8737 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8738 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8739 (clobber (reg:CC FLAGS_REG))]
8741 "or{l}\t{%2, %k0|%k0, %2}"
8742 [(set_attr "type" "alu")
8743 (set_attr "mode" "SI")])
8745 (define_insn "*iorsi_2"
8746 [(set (reg FLAGS_REG)
8747 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8748 (match_operand:SI 2 "general_operand" "rim,ri"))
8750 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8751 (ior:SI (match_dup 1) (match_dup 2)))]
8752 "ix86_match_ccmode (insn, CCNOmode)
8753 && ix86_binary_operator_ok (IOR, SImode, operands)"
8754 "or{l}\t{%2, %0|%0, %2}"
8755 [(set_attr "type" "alu")
8756 (set_attr "mode" "SI")])
8758 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8759 ;; ??? Special case for immediate operand is missing - it is tricky.
8760 (define_insn "*iorsi_2_zext"
8761 [(set (reg FLAGS_REG)
8762 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8763 (match_operand:SI 2 "general_operand" "rim"))
8765 (set (match_operand:DI 0 "register_operand" "=r")
8766 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8767 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8768 && ix86_binary_operator_ok (IOR, SImode, operands)"
8769 "or{l}\t{%2, %k0|%k0, %2}"
8770 [(set_attr "type" "alu")
8771 (set_attr "mode" "SI")])
8773 (define_insn "*iorsi_2_zext_imm"
8774 [(set (reg FLAGS_REG)
8775 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8776 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8778 (set (match_operand:DI 0 "register_operand" "=r")
8779 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8780 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8781 && ix86_binary_operator_ok (IOR, SImode, operands)"
8782 "or{l}\t{%2, %k0|%k0, %2}"
8783 [(set_attr "type" "alu")
8784 (set_attr "mode" "SI")])
8786 (define_insn "*iorsi_3"
8787 [(set (reg FLAGS_REG)
8788 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8789 (match_operand:SI 2 "general_operand" "rim"))
8791 (clobber (match_scratch:SI 0 "=r"))]
8792 "ix86_match_ccmode (insn, CCNOmode)
8793 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8794 "or{l}\t{%2, %0|%0, %2}"
8795 [(set_attr "type" "alu")
8796 (set_attr "mode" "SI")])
8798 (define_expand "iorhi3"
8799 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8800 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8801 (match_operand:HI 2 "general_operand" "")))
8802 (clobber (reg:CC FLAGS_REG))]
8803 "TARGET_HIMODE_MATH"
8804 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8806 (define_insn "*iorhi_1"
8807 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8808 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8809 (match_operand:HI 2 "general_operand" "rmi,ri")))
8810 (clobber (reg:CC FLAGS_REG))]
8811 "ix86_binary_operator_ok (IOR, HImode, operands)"
8812 "or{w}\t{%2, %0|%0, %2}"
8813 [(set_attr "type" "alu")
8814 (set_attr "mode" "HI")])
8816 (define_insn "*iorhi_2"
8817 [(set (reg FLAGS_REG)
8818 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8819 (match_operand:HI 2 "general_operand" "rim,ri"))
8821 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8822 (ior:HI (match_dup 1) (match_dup 2)))]
8823 "ix86_match_ccmode (insn, CCNOmode)
8824 && ix86_binary_operator_ok (IOR, HImode, operands)"
8825 "or{w}\t{%2, %0|%0, %2}"
8826 [(set_attr "type" "alu")
8827 (set_attr "mode" "HI")])
8829 (define_insn "*iorhi_3"
8830 [(set (reg FLAGS_REG)
8831 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8832 (match_operand:HI 2 "general_operand" "rim"))
8834 (clobber (match_scratch:HI 0 "=r"))]
8835 "ix86_match_ccmode (insn, CCNOmode)
8836 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8837 "or{w}\t{%2, %0|%0, %2}"
8838 [(set_attr "type" "alu")
8839 (set_attr "mode" "HI")])
8841 (define_expand "iorqi3"
8842 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8843 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8844 (match_operand:QI 2 "general_operand" "")))
8845 (clobber (reg:CC FLAGS_REG))]
8846 "TARGET_QIMODE_MATH"
8847 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8849 ;; %%% Potential partial reg stall on alternative 2. What to do?
8850 (define_insn "*iorqi_1"
8851 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8852 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8853 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8854 (clobber (reg:CC FLAGS_REG))]
8855 "ix86_binary_operator_ok (IOR, QImode, operands)"
8857 or{b}\t{%2, %0|%0, %2}
8858 or{b}\t{%2, %0|%0, %2}
8859 or{l}\t{%k2, %k0|%k0, %k2}"
8860 [(set_attr "type" "alu")
8861 (set_attr "mode" "QI,QI,SI")])
8863 (define_insn "*iorqi_1_slp"
8864 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8865 (ior:QI (match_dup 0)
8866 (match_operand:QI 1 "general_operand" "qmi,qi")))
8867 (clobber (reg:CC FLAGS_REG))]
8868 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8869 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8870 "or{b}\t{%1, %0|%0, %1}"
8871 [(set_attr "type" "alu1")
8872 (set_attr "mode" "QI")])
8874 (define_insn "*iorqi_2"
8875 [(set (reg FLAGS_REG)
8876 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8877 (match_operand:QI 2 "general_operand" "qim,qi"))
8879 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8880 (ior:QI (match_dup 1) (match_dup 2)))]
8881 "ix86_match_ccmode (insn, CCNOmode)
8882 && ix86_binary_operator_ok (IOR, QImode, operands)"
8883 "or{b}\t{%2, %0|%0, %2}"
8884 [(set_attr "type" "alu")
8885 (set_attr "mode" "QI")])
8887 (define_insn "*iorqi_2_slp"
8888 [(set (reg FLAGS_REG)
8889 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8890 (match_operand:QI 1 "general_operand" "qim,qi"))
8892 (set (strict_low_part (match_dup 0))
8893 (ior:QI (match_dup 0) (match_dup 1)))]
8894 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8895 && ix86_match_ccmode (insn, CCNOmode)
8896 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8897 "or{b}\t{%1, %0|%0, %1}"
8898 [(set_attr "type" "alu1")
8899 (set_attr "mode" "QI")])
8901 (define_insn "*iorqi_3"
8902 [(set (reg FLAGS_REG)
8903 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8904 (match_operand:QI 2 "general_operand" "qim"))
8906 (clobber (match_scratch:QI 0 "=q"))]
8907 "ix86_match_ccmode (insn, CCNOmode)
8908 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8909 "or{b}\t{%2, %0|%0, %2}"
8910 [(set_attr "type" "alu")
8911 (set_attr "mode" "QI")])
8913 (define_insn "iorqi_ext_0"
8914 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8919 (match_operand 1 "ext_register_operand" "0")
8922 (match_operand 2 "const_int_operand" "n")))
8923 (clobber (reg:CC FLAGS_REG))]
8924 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8925 "or{b}\t{%2, %h0|%h0, %2}"
8926 [(set_attr "type" "alu")
8927 (set_attr "length_immediate" "1")
8928 (set_attr "mode" "QI")])
8930 (define_insn "*iorqi_ext_1"
8931 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8936 (match_operand 1 "ext_register_operand" "0")
8940 (match_operand:QI 2 "general_operand" "Qm"))))
8941 (clobber (reg:CC FLAGS_REG))]
8943 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8944 "or{b}\t{%2, %h0|%h0, %2}"
8945 [(set_attr "type" "alu")
8946 (set_attr "length_immediate" "0")
8947 (set_attr "mode" "QI")])
8949 (define_insn "*iorqi_ext_1_rex64"
8950 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8955 (match_operand 1 "ext_register_operand" "0")
8959 (match_operand 2 "ext_register_operand" "Q"))))
8960 (clobber (reg:CC FLAGS_REG))]
8962 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8963 "or{b}\t{%2, %h0|%h0, %2}"
8964 [(set_attr "type" "alu")
8965 (set_attr "length_immediate" "0")
8966 (set_attr "mode" "QI")])
8968 (define_insn "*iorqi_ext_2"
8969 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8973 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8976 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8979 (clobber (reg:CC FLAGS_REG))]
8980 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8981 "ior{b}\t{%h2, %h0|%h0, %h2}"
8982 [(set_attr "type" "alu")
8983 (set_attr "length_immediate" "0")
8984 (set_attr "mode" "QI")])
8987 [(set (match_operand 0 "register_operand" "")
8988 (ior (match_operand 1 "register_operand" "")
8989 (match_operand 2 "const_int_operand" "")))
8990 (clobber (reg:CC FLAGS_REG))]
8992 && QI_REG_P (operands[0])
8993 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8994 && !(INTVAL (operands[2]) & ~(255 << 8))
8995 && GET_MODE (operands[0]) != QImode"
8996 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8997 (ior:SI (zero_extract:SI (match_dup 1)
8998 (const_int 8) (const_int 8))
9000 (clobber (reg:CC FLAGS_REG))])]
9001 "operands[0] = gen_lowpart (SImode, operands[0]);
9002 operands[1] = gen_lowpart (SImode, operands[1]);
9003 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9005 ;; Since OR can be encoded with sign extended immediate, this is only
9006 ;; profitable when 7th bit is set.
9008 [(set (match_operand 0 "register_operand" "")
9009 (ior (match_operand 1 "general_operand" "")
9010 (match_operand 2 "const_int_operand" "")))
9011 (clobber (reg:CC FLAGS_REG))]
9013 && ANY_QI_REG_P (operands[0])
9014 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9015 && !(INTVAL (operands[2]) & ~255)
9016 && (INTVAL (operands[2]) & 128)
9017 && GET_MODE (operands[0]) != QImode"
9018 [(parallel [(set (strict_low_part (match_dup 0))
9019 (ior:QI (match_dup 1)
9021 (clobber (reg:CC FLAGS_REG))])]
9022 "operands[0] = gen_lowpart (QImode, operands[0]);
9023 operands[1] = gen_lowpart (QImode, operands[1]);
9024 operands[2] = gen_lowpart (QImode, operands[2]);")
9026 ;; Logical XOR instructions
9028 ;; %%% This used to optimize known byte-wide and operations to memory.
9029 ;; If this is considered useful, it should be done with splitters.
9031 (define_expand "xordi3"
9032 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9033 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9034 (match_operand:DI 2 "x86_64_general_operand" "")))
9035 (clobber (reg:CC FLAGS_REG))]
9037 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9039 (define_insn "*xordi_1_rex64"
9040 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9041 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9042 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9043 (clobber (reg:CC FLAGS_REG))]
9045 && ix86_binary_operator_ok (XOR, DImode, operands)"
9047 xor{q}\t{%2, %0|%0, %2}
9048 xor{q}\t{%2, %0|%0, %2}"
9049 [(set_attr "type" "alu")
9050 (set_attr "mode" "DI,DI")])
9052 (define_insn "*xordi_2_rex64"
9053 [(set (reg FLAGS_REG)
9054 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9055 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9057 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9058 (xor:DI (match_dup 1) (match_dup 2)))]
9060 && ix86_match_ccmode (insn, CCNOmode)
9061 && ix86_binary_operator_ok (XOR, DImode, operands)"
9063 xor{q}\t{%2, %0|%0, %2}
9064 xor{q}\t{%2, %0|%0, %2}"
9065 [(set_attr "type" "alu")
9066 (set_attr "mode" "DI,DI")])
9068 (define_insn "*xordi_3_rex64"
9069 [(set (reg FLAGS_REG)
9070 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9071 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9073 (clobber (match_scratch:DI 0 "=r"))]
9075 && ix86_match_ccmode (insn, CCNOmode)
9076 && ix86_binary_operator_ok (XOR, DImode, operands)"
9077 "xor{q}\t{%2, %0|%0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "mode" "DI")])
9081 (define_expand "xorsi3"
9082 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9083 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9084 (match_operand:SI 2 "general_operand" "")))
9085 (clobber (reg:CC FLAGS_REG))]
9087 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9089 (define_insn "*xorsi_1"
9090 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9091 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9092 (match_operand:SI 2 "general_operand" "ri,rm")))
9093 (clobber (reg:CC FLAGS_REG))]
9094 "ix86_binary_operator_ok (XOR, SImode, operands)"
9095 "xor{l}\t{%2, %0|%0, %2}"
9096 [(set_attr "type" "alu")
9097 (set_attr "mode" "SI")])
9099 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9100 ;; Add speccase for immediates
9101 (define_insn "*xorsi_1_zext"
9102 [(set (match_operand:DI 0 "register_operand" "=r")
9104 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9105 (match_operand:SI 2 "general_operand" "rim"))))
9106 (clobber (reg:CC FLAGS_REG))]
9107 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9108 "xor{l}\t{%2, %k0|%k0, %2}"
9109 [(set_attr "type" "alu")
9110 (set_attr "mode" "SI")])
9112 (define_insn "*xorsi_1_zext_imm"
9113 [(set (match_operand:DI 0 "register_operand" "=r")
9114 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9115 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9116 (clobber (reg:CC FLAGS_REG))]
9117 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9118 "xor{l}\t{%2, %k0|%k0, %2}"
9119 [(set_attr "type" "alu")
9120 (set_attr "mode" "SI")])
9122 (define_insn "*xorsi_2"
9123 [(set (reg FLAGS_REG)
9124 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9125 (match_operand:SI 2 "general_operand" "rim,ri"))
9127 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9128 (xor:SI (match_dup 1) (match_dup 2)))]
9129 "ix86_match_ccmode (insn, CCNOmode)
9130 && ix86_binary_operator_ok (XOR, SImode, operands)"
9131 "xor{l}\t{%2, %0|%0, %2}"
9132 [(set_attr "type" "alu")
9133 (set_attr "mode" "SI")])
9135 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9136 ;; ??? Special case for immediate operand is missing - it is tricky.
9137 (define_insn "*xorsi_2_zext"
9138 [(set (reg FLAGS_REG)
9139 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9140 (match_operand:SI 2 "general_operand" "rim"))
9142 (set (match_operand:DI 0 "register_operand" "=r")
9143 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9144 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9145 && ix86_binary_operator_ok (XOR, SImode, operands)"
9146 "xor{l}\t{%2, %k0|%k0, %2}"
9147 [(set_attr "type" "alu")
9148 (set_attr "mode" "SI")])
9150 (define_insn "*xorsi_2_zext_imm"
9151 [(set (reg FLAGS_REG)
9152 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9153 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9155 (set (match_operand:DI 0 "register_operand" "=r")
9156 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9157 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9158 && ix86_binary_operator_ok (XOR, SImode, operands)"
9159 "xor{l}\t{%2, %k0|%k0, %2}"
9160 [(set_attr "type" "alu")
9161 (set_attr "mode" "SI")])
9163 (define_insn "*xorsi_3"
9164 [(set (reg FLAGS_REG)
9165 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9166 (match_operand:SI 2 "general_operand" "rim"))
9168 (clobber (match_scratch:SI 0 "=r"))]
9169 "ix86_match_ccmode (insn, CCNOmode)
9170 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9171 "xor{l}\t{%2, %0|%0, %2}"
9172 [(set_attr "type" "alu")
9173 (set_attr "mode" "SI")])
9175 (define_expand "xorhi3"
9176 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9177 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9178 (match_operand:HI 2 "general_operand" "")))
9179 (clobber (reg:CC FLAGS_REG))]
9180 "TARGET_HIMODE_MATH"
9181 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9183 (define_insn "*xorhi_1"
9184 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9185 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9186 (match_operand:HI 2 "general_operand" "rmi,ri")))
9187 (clobber (reg:CC FLAGS_REG))]
9188 "ix86_binary_operator_ok (XOR, HImode, operands)"
9189 "xor{w}\t{%2, %0|%0, %2}"
9190 [(set_attr "type" "alu")
9191 (set_attr "mode" "HI")])
9193 (define_insn "*xorhi_2"
9194 [(set (reg FLAGS_REG)
9195 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9196 (match_operand:HI 2 "general_operand" "rim,ri"))
9198 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9199 (xor:HI (match_dup 1) (match_dup 2)))]
9200 "ix86_match_ccmode (insn, CCNOmode)
9201 && ix86_binary_operator_ok (XOR, HImode, operands)"
9202 "xor{w}\t{%2, %0|%0, %2}"
9203 [(set_attr "type" "alu")
9204 (set_attr "mode" "HI")])
9206 (define_insn "*xorhi_3"
9207 [(set (reg FLAGS_REG)
9208 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9209 (match_operand:HI 2 "general_operand" "rim"))
9211 (clobber (match_scratch:HI 0 "=r"))]
9212 "ix86_match_ccmode (insn, CCNOmode)
9213 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9214 "xor{w}\t{%2, %0|%0, %2}"
9215 [(set_attr "type" "alu")
9216 (set_attr "mode" "HI")])
9218 (define_expand "xorqi3"
9219 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9220 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9221 (match_operand:QI 2 "general_operand" "")))
9222 (clobber (reg:CC FLAGS_REG))]
9223 "TARGET_QIMODE_MATH"
9224 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9226 ;; %%% Potential partial reg stall on alternative 2. What to do?
9227 (define_insn "*xorqi_1"
9228 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9229 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9230 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9231 (clobber (reg:CC FLAGS_REG))]
9232 "ix86_binary_operator_ok (XOR, QImode, operands)"
9234 xor{b}\t{%2, %0|%0, %2}
9235 xor{b}\t{%2, %0|%0, %2}
9236 xor{l}\t{%k2, %k0|%k0, %k2}"
9237 [(set_attr "type" "alu")
9238 (set_attr "mode" "QI,QI,SI")])
9240 (define_insn "*xorqi_1_slp"
9241 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9242 (xor:QI (match_dup 0)
9243 (match_operand:QI 1 "general_operand" "qi,qmi")))
9244 (clobber (reg:CC FLAGS_REG))]
9245 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9246 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9247 "xor{b}\t{%1, %0|%0, %1}"
9248 [(set_attr "type" "alu1")
9249 (set_attr "mode" "QI")])
9251 (define_insn "xorqi_ext_0"
9252 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9257 (match_operand 1 "ext_register_operand" "0")
9260 (match_operand 2 "const_int_operand" "n")))
9261 (clobber (reg:CC FLAGS_REG))]
9262 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9263 "xor{b}\t{%2, %h0|%h0, %2}"
9264 [(set_attr "type" "alu")
9265 (set_attr "length_immediate" "1")
9266 (set_attr "mode" "QI")])
9268 (define_insn "*xorqi_ext_1"
9269 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9274 (match_operand 1 "ext_register_operand" "0")
9278 (match_operand:QI 2 "general_operand" "Qm"))))
9279 (clobber (reg:CC FLAGS_REG))]
9281 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9282 "xor{b}\t{%2, %h0|%h0, %2}"
9283 [(set_attr "type" "alu")
9284 (set_attr "length_immediate" "0")
9285 (set_attr "mode" "QI")])
9287 (define_insn "*xorqi_ext_1_rex64"
9288 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9293 (match_operand 1 "ext_register_operand" "0")
9297 (match_operand 2 "ext_register_operand" "Q"))))
9298 (clobber (reg:CC FLAGS_REG))]
9300 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9301 "xor{b}\t{%2, %h0|%h0, %2}"
9302 [(set_attr "type" "alu")
9303 (set_attr "length_immediate" "0")
9304 (set_attr "mode" "QI")])
9306 (define_insn "*xorqi_ext_2"
9307 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9311 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9314 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9317 (clobber (reg:CC FLAGS_REG))]
9318 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9319 "xor{b}\t{%h2, %h0|%h0, %h2}"
9320 [(set_attr "type" "alu")
9321 (set_attr "length_immediate" "0")
9322 (set_attr "mode" "QI")])
9324 (define_insn "*xorqi_cc_1"
9325 [(set (reg FLAGS_REG)
9327 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9328 (match_operand:QI 2 "general_operand" "qim,qi"))
9330 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9331 (xor:QI (match_dup 1) (match_dup 2)))]
9332 "ix86_match_ccmode (insn, CCNOmode)
9333 && ix86_binary_operator_ok (XOR, QImode, operands)"
9334 "xor{b}\t{%2, %0|%0, %2}"
9335 [(set_attr "type" "alu")
9336 (set_attr "mode" "QI")])
9338 (define_insn "*xorqi_2_slp"
9339 [(set (reg FLAGS_REG)
9340 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9341 (match_operand:QI 1 "general_operand" "qim,qi"))
9343 (set (strict_low_part (match_dup 0))
9344 (xor:QI (match_dup 0) (match_dup 1)))]
9345 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9346 && ix86_match_ccmode (insn, CCNOmode)
9347 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9348 "xor{b}\t{%1, %0|%0, %1}"
9349 [(set_attr "type" "alu1")
9350 (set_attr "mode" "QI")])
9352 (define_insn "*xorqi_cc_2"
9353 [(set (reg FLAGS_REG)
9355 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9356 (match_operand:QI 2 "general_operand" "qim"))
9358 (clobber (match_scratch:QI 0 "=q"))]
9359 "ix86_match_ccmode (insn, CCNOmode)
9360 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9361 "xor{b}\t{%2, %0|%0, %2}"
9362 [(set_attr "type" "alu")
9363 (set_attr "mode" "QI")])
9365 (define_insn "*xorqi_cc_ext_1"
9366 [(set (reg FLAGS_REG)
9370 (match_operand 1 "ext_register_operand" "0")
9373 (match_operand:QI 2 "general_operand" "qmn"))
9375 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9379 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9381 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9382 "xor{b}\t{%2, %h0|%h0, %2}"
9383 [(set_attr "type" "alu")
9384 (set_attr "mode" "QI")])
9386 (define_insn "*xorqi_cc_ext_1_rex64"
9387 [(set (reg FLAGS_REG)
9391 (match_operand 1 "ext_register_operand" "0")
9394 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9396 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9400 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9402 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9403 "xor{b}\t{%2, %h0|%h0, %2}"
9404 [(set_attr "type" "alu")
9405 (set_attr "mode" "QI")])
9407 (define_expand "xorqi_cc_ext_1"
9409 (set (reg:CCNO FLAGS_REG)
9413 (match_operand 1 "ext_register_operand" "")
9416 (match_operand:QI 2 "general_operand" ""))
9418 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9422 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9428 [(set (match_operand 0 "register_operand" "")
9429 (xor (match_operand 1 "register_operand" "")
9430 (match_operand 2 "const_int_operand" "")))
9431 (clobber (reg:CC FLAGS_REG))]
9433 && QI_REG_P (operands[0])
9434 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9435 && !(INTVAL (operands[2]) & ~(255 << 8))
9436 && GET_MODE (operands[0]) != QImode"
9437 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9438 (xor:SI (zero_extract:SI (match_dup 1)
9439 (const_int 8) (const_int 8))
9441 (clobber (reg:CC FLAGS_REG))])]
9442 "operands[0] = gen_lowpart (SImode, operands[0]);
9443 operands[1] = gen_lowpart (SImode, operands[1]);
9444 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9446 ;; Since XOR can be encoded with sign extended immediate, this is only
9447 ;; profitable when 7th bit is set.
9449 [(set (match_operand 0 "register_operand" "")
9450 (xor (match_operand 1 "general_operand" "")
9451 (match_operand 2 "const_int_operand" "")))
9452 (clobber (reg:CC FLAGS_REG))]
9454 && ANY_QI_REG_P (operands[0])
9455 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9456 && !(INTVAL (operands[2]) & ~255)
9457 && (INTVAL (operands[2]) & 128)
9458 && GET_MODE (operands[0]) != QImode"
9459 [(parallel [(set (strict_low_part (match_dup 0))
9460 (xor:QI (match_dup 1)
9462 (clobber (reg:CC FLAGS_REG))])]
9463 "operands[0] = gen_lowpart (QImode, operands[0]);
9464 operands[1] = gen_lowpart (QImode, operands[1]);
9465 operands[2] = gen_lowpart (QImode, operands[2]);")
9467 ;; Negation instructions
9469 (define_expand "negti2"
9470 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9471 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9472 (clobber (reg:CC FLAGS_REG))])]
9474 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9476 (define_insn "*negti2_1"
9477 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9478 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9479 (clobber (reg:CC FLAGS_REG))]
9481 && ix86_unary_operator_ok (NEG, TImode, operands)"
9485 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9486 (neg:TI (match_operand:TI 1 "general_operand" "")))
9487 (clobber (reg:CC FLAGS_REG))]
9488 "TARGET_64BIT && reload_completed"
9490 [(set (reg:CCZ FLAGS_REG)
9491 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9492 (set (match_dup 0) (neg:DI (match_dup 2)))])
9495 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9498 (clobber (reg:CC FLAGS_REG))])
9501 (neg:DI (match_dup 1)))
9502 (clobber (reg:CC FLAGS_REG))])]
9503 "split_ti (operands+1, 1, operands+2, operands+3);
9504 split_ti (operands+0, 1, operands+0, operands+1);")
9506 (define_expand "negdi2"
9507 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9508 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9509 (clobber (reg:CC FLAGS_REG))])]
9511 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9513 (define_insn "*negdi2_1"
9514 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9515 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9516 (clobber (reg:CC FLAGS_REG))]
9518 && ix86_unary_operator_ok (NEG, DImode, operands)"
9522 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9523 (neg:DI (match_operand:DI 1 "general_operand" "")))
9524 (clobber (reg:CC FLAGS_REG))]
9525 "!TARGET_64BIT && reload_completed"
9527 [(set (reg:CCZ FLAGS_REG)
9528 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9529 (set (match_dup 0) (neg:SI (match_dup 2)))])
9532 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9535 (clobber (reg:CC FLAGS_REG))])
9538 (neg:SI (match_dup 1)))
9539 (clobber (reg:CC FLAGS_REG))])]
9540 "split_di (operands+1, 1, operands+2, operands+3);
9541 split_di (operands+0, 1, operands+0, operands+1);")
9543 (define_insn "*negdi2_1_rex64"
9544 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9545 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9546 (clobber (reg:CC FLAGS_REG))]
9547 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9549 [(set_attr "type" "negnot")
9550 (set_attr "mode" "DI")])
9552 ;; The problem with neg is that it does not perform (compare x 0),
9553 ;; it really performs (compare 0 x), which leaves us with the zero
9554 ;; flag being the only useful item.
9556 (define_insn "*negdi2_cmpz_rex64"
9557 [(set (reg:CCZ FLAGS_REG)
9558 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9560 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9561 (neg:DI (match_dup 1)))]
9562 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9564 [(set_attr "type" "negnot")
9565 (set_attr "mode" "DI")])
9568 (define_expand "negsi2"
9569 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9570 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9571 (clobber (reg:CC FLAGS_REG))])]
9573 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9575 (define_insn "*negsi2_1"
9576 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9577 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9578 (clobber (reg:CC FLAGS_REG))]
9579 "ix86_unary_operator_ok (NEG, SImode, operands)"
9581 [(set_attr "type" "negnot")
9582 (set_attr "mode" "SI")])
9584 ;; Combine is quite creative about this pattern.
9585 (define_insn "*negsi2_1_zext"
9586 [(set (match_operand:DI 0 "register_operand" "=r")
9587 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9590 (clobber (reg:CC FLAGS_REG))]
9591 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9593 [(set_attr "type" "negnot")
9594 (set_attr "mode" "SI")])
9596 ;; The problem with neg is that it does not perform (compare x 0),
9597 ;; it really performs (compare 0 x), which leaves us with the zero
9598 ;; flag being the only useful item.
9600 (define_insn "*negsi2_cmpz"
9601 [(set (reg:CCZ FLAGS_REG)
9602 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9604 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9605 (neg:SI (match_dup 1)))]
9606 "ix86_unary_operator_ok (NEG, SImode, operands)"
9608 [(set_attr "type" "negnot")
9609 (set_attr "mode" "SI")])
9611 (define_insn "*negsi2_cmpz_zext"
9612 [(set (reg:CCZ FLAGS_REG)
9613 (compare:CCZ (lshiftrt:DI
9615 (match_operand:DI 1 "register_operand" "0")
9619 (set (match_operand:DI 0 "register_operand" "=r")
9620 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9623 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9625 [(set_attr "type" "negnot")
9626 (set_attr "mode" "SI")])
9628 (define_expand "neghi2"
9629 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9630 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9631 (clobber (reg:CC FLAGS_REG))])]
9632 "TARGET_HIMODE_MATH"
9633 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9635 (define_insn "*neghi2_1"
9636 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9637 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9638 (clobber (reg:CC FLAGS_REG))]
9639 "ix86_unary_operator_ok (NEG, HImode, operands)"
9641 [(set_attr "type" "negnot")
9642 (set_attr "mode" "HI")])
9644 (define_insn "*neghi2_cmpz"
9645 [(set (reg:CCZ FLAGS_REG)
9646 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9648 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9649 (neg:HI (match_dup 1)))]
9650 "ix86_unary_operator_ok (NEG, HImode, operands)"
9652 [(set_attr "type" "negnot")
9653 (set_attr "mode" "HI")])
9655 (define_expand "negqi2"
9656 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9657 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9658 (clobber (reg:CC FLAGS_REG))])]
9659 "TARGET_QIMODE_MATH"
9660 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9662 (define_insn "*negqi2_1"
9663 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9664 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9665 (clobber (reg:CC FLAGS_REG))]
9666 "ix86_unary_operator_ok (NEG, QImode, operands)"
9668 [(set_attr "type" "negnot")
9669 (set_attr "mode" "QI")])
9671 (define_insn "*negqi2_cmpz"
9672 [(set (reg:CCZ FLAGS_REG)
9673 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9675 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9676 (neg:QI (match_dup 1)))]
9677 "ix86_unary_operator_ok (NEG, QImode, operands)"
9679 [(set_attr "type" "negnot")
9680 (set_attr "mode" "QI")])
9682 ;; Changing of sign for FP values is doable using integer unit too.
9684 (define_expand "negsf2"
9685 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9686 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9687 "TARGET_80387 || TARGET_SSE_MATH"
9688 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9690 (define_expand "abssf2"
9691 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9692 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9693 "TARGET_80387 || TARGET_SSE_MATH"
9694 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9696 (define_insn "*absnegsf2_mixed"
9697 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9698 (match_operator:SF 3 "absneg_operator"
9699 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9700 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9701 (clobber (reg:CC FLAGS_REG))]
9702 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9703 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9706 (define_insn "*absnegsf2_sse"
9707 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9708 (match_operator:SF 3 "absneg_operator"
9709 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9710 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9711 (clobber (reg:CC FLAGS_REG))]
9713 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9716 (define_insn "*absnegsf2_i387"
9717 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9718 (match_operator:SF 3 "absneg_operator"
9719 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9720 (use (match_operand 2 "" ""))
9721 (clobber (reg:CC FLAGS_REG))]
9722 "TARGET_80387 && !TARGET_SSE_MATH
9723 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9726 (define_expand "copysignsf3"
9727 [(match_operand:SF 0 "register_operand" "")
9728 (match_operand:SF 1 "nonmemory_operand" "")
9729 (match_operand:SF 2 "register_operand" "")]
9732 ix86_expand_copysign (operands);
9736 (define_insn_and_split "copysignsf3_const"
9737 [(set (match_operand:SF 0 "register_operand" "=x")
9739 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9740 (match_operand:SF 2 "register_operand" "0")
9741 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9745 "&& reload_completed"
9748 ix86_split_copysign_const (operands);
9752 (define_insn "copysignsf3_var"
9753 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9755 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9756 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9757 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9758 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9760 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9765 [(set (match_operand:SF 0 "register_operand" "")
9767 [(match_operand:SF 2 "register_operand" "")
9768 (match_operand:SF 3 "register_operand" "")
9769 (match_operand:V4SF 4 "" "")
9770 (match_operand:V4SF 5 "" "")]
9772 (clobber (match_scratch:V4SF 1 ""))]
9773 "TARGET_SSE_MATH && reload_completed"
9776 ix86_split_copysign_var (operands);
9780 (define_expand "negdf2"
9781 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9782 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9783 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9784 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9786 (define_expand "absdf2"
9787 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9788 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9789 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9790 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9792 (define_insn "*absnegdf2_mixed"
9793 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9794 (match_operator:DF 3 "absneg_operator"
9795 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9796 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9799 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9802 (define_insn "*absnegdf2_sse"
9803 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9804 (match_operator:DF 3 "absneg_operator"
9805 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9806 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9807 (clobber (reg:CC FLAGS_REG))]
9808 "TARGET_SSE2 && TARGET_SSE_MATH
9809 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9812 (define_insn "*absnegdf2_i387"
9813 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9814 (match_operator:DF 3 "absneg_operator"
9815 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9816 (use (match_operand 2 "" ""))
9817 (clobber (reg:CC FLAGS_REG))]
9818 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9819 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9822 (define_expand "copysigndf3"
9823 [(match_operand:DF 0 "register_operand" "")
9824 (match_operand:DF 1 "nonmemory_operand" "")
9825 (match_operand:DF 2 "register_operand" "")]
9826 "TARGET_SSE2 && TARGET_SSE_MATH"
9828 ix86_expand_copysign (operands);
9832 (define_insn_and_split "copysigndf3_const"
9833 [(set (match_operand:DF 0 "register_operand" "=x")
9835 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9836 (match_operand:DF 2 "register_operand" "0")
9837 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9839 "TARGET_SSE2 && TARGET_SSE_MATH"
9841 "&& reload_completed"
9844 ix86_split_copysign_const (operands);
9848 (define_insn "copysigndf3_var"
9849 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9851 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9852 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9853 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9854 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9856 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9857 "TARGET_SSE2 && TARGET_SSE_MATH"
9861 [(set (match_operand:DF 0 "register_operand" "")
9863 [(match_operand:DF 2 "register_operand" "")
9864 (match_operand:DF 3 "register_operand" "")
9865 (match_operand:V2DF 4 "" "")
9866 (match_operand:V2DF 5 "" "")]
9868 (clobber (match_scratch:V2DF 1 ""))]
9869 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9872 ix86_split_copysign_var (operands);
9876 (define_expand "negxf2"
9877 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9878 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9880 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9882 (define_expand "absxf2"
9883 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9884 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9886 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9888 (define_insn "*absnegxf2_i387"
9889 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9890 (match_operator:XF 3 "absneg_operator"
9891 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9892 (use (match_operand 2 "" ""))
9893 (clobber (reg:CC FLAGS_REG))]
9895 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9898 ;; Splitters for fp abs and neg.
9901 [(set (match_operand 0 "fp_register_operand" "")
9902 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9903 (use (match_operand 2 "" ""))
9904 (clobber (reg:CC FLAGS_REG))]
9906 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9909 [(set (match_operand 0 "register_operand" "")
9910 (match_operator 3 "absneg_operator"
9911 [(match_operand 1 "register_operand" "")]))
9912 (use (match_operand 2 "nonimmediate_operand" ""))
9913 (clobber (reg:CC FLAGS_REG))]
9914 "reload_completed && SSE_REG_P (operands[0])"
9915 [(set (match_dup 0) (match_dup 3))]
9917 enum machine_mode mode = GET_MODE (operands[0]);
9918 enum machine_mode vmode = GET_MODE (operands[2]);
9921 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9922 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9923 if (operands_match_p (operands[0], operands[2]))
9926 operands[1] = operands[2];
9929 if (GET_CODE (operands[3]) == ABS)
9930 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9932 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9937 [(set (match_operand:SF 0 "register_operand" "")
9938 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9939 (use (match_operand:V4SF 2 "" ""))
9940 (clobber (reg:CC FLAGS_REG))]
9942 [(parallel [(set (match_dup 0) (match_dup 1))
9943 (clobber (reg:CC FLAGS_REG))])]
9946 operands[0] = gen_lowpart (SImode, operands[0]);
9947 if (GET_CODE (operands[1]) == ABS)
9949 tmp = gen_int_mode (0x7fffffff, SImode);
9950 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9954 tmp = gen_int_mode (0x80000000, SImode);
9955 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9961 [(set (match_operand:DF 0 "register_operand" "")
9962 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9963 (use (match_operand 2 "" ""))
9964 (clobber (reg:CC FLAGS_REG))]
9966 [(parallel [(set (match_dup 0) (match_dup 1))
9967 (clobber (reg:CC FLAGS_REG))])]
9972 tmp = gen_lowpart (DImode, operands[0]);
9973 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9976 if (GET_CODE (operands[1]) == ABS)
9979 tmp = gen_rtx_NOT (DImode, tmp);
9983 operands[0] = gen_highpart (SImode, operands[0]);
9984 if (GET_CODE (operands[1]) == ABS)
9986 tmp = gen_int_mode (0x7fffffff, SImode);
9987 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9991 tmp = gen_int_mode (0x80000000, SImode);
9992 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9999 [(set (match_operand:XF 0 "register_operand" "")
10000 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10001 (use (match_operand 2 "" ""))
10002 (clobber (reg:CC FLAGS_REG))]
10004 [(parallel [(set (match_dup 0) (match_dup 1))
10005 (clobber (reg:CC FLAGS_REG))])]
10008 operands[0] = gen_rtx_REG (SImode,
10009 true_regnum (operands[0])
10010 + (TARGET_64BIT ? 1 : 2));
10011 if (GET_CODE (operands[1]) == ABS)
10013 tmp = GEN_INT (0x7fff);
10014 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10018 tmp = GEN_INT (0x8000);
10019 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10025 [(set (match_operand 0 "memory_operand" "")
10026 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10027 (use (match_operand 2 "" ""))
10028 (clobber (reg:CC FLAGS_REG))]
10030 [(parallel [(set (match_dup 0) (match_dup 1))
10031 (clobber (reg:CC FLAGS_REG))])]
10033 enum machine_mode mode = GET_MODE (operands[0]);
10034 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10037 operands[0] = adjust_address (operands[0], QImode, size - 1);
10038 if (GET_CODE (operands[1]) == ABS)
10040 tmp = gen_int_mode (0x7f, QImode);
10041 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10045 tmp = gen_int_mode (0x80, QImode);
10046 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10051 ;; Conditionalize these after reload. If they match before reload, we
10052 ;; lose the clobber and ability to use integer instructions.
10054 (define_insn "*negsf2_1"
10055 [(set (match_operand:SF 0 "register_operand" "=f")
10056 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10057 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10059 [(set_attr "type" "fsgn")
10060 (set_attr "mode" "SF")])
10062 (define_insn "*negdf2_1"
10063 [(set (match_operand:DF 0 "register_operand" "=f")
10064 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10065 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10067 [(set_attr "type" "fsgn")
10068 (set_attr "mode" "DF")])
10070 (define_insn "*negxf2_1"
10071 [(set (match_operand:XF 0 "register_operand" "=f")
10072 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10075 [(set_attr "type" "fsgn")
10076 (set_attr "mode" "XF")])
10078 (define_insn "*abssf2_1"
10079 [(set (match_operand:SF 0 "register_operand" "=f")
10080 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10081 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10083 [(set_attr "type" "fsgn")
10084 (set_attr "mode" "SF")])
10086 (define_insn "*absdf2_1"
10087 [(set (match_operand:DF 0 "register_operand" "=f")
10088 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10089 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10091 [(set_attr "type" "fsgn")
10092 (set_attr "mode" "DF")])
10094 (define_insn "*absxf2_1"
10095 [(set (match_operand:XF 0 "register_operand" "=f")
10096 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10099 [(set_attr "type" "fsgn")
10100 (set_attr "mode" "DF")])
10102 (define_insn "*negextendsfdf2"
10103 [(set (match_operand:DF 0 "register_operand" "=f")
10104 (neg:DF (float_extend:DF
10105 (match_operand:SF 1 "register_operand" "0"))))]
10106 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10108 [(set_attr "type" "fsgn")
10109 (set_attr "mode" "DF")])
10111 (define_insn "*negextenddfxf2"
10112 [(set (match_operand:XF 0 "register_operand" "=f")
10113 (neg:XF (float_extend:XF
10114 (match_operand:DF 1 "register_operand" "0"))))]
10117 [(set_attr "type" "fsgn")
10118 (set_attr "mode" "XF")])
10120 (define_insn "*negextendsfxf2"
10121 [(set (match_operand:XF 0 "register_operand" "=f")
10122 (neg:XF (float_extend:XF
10123 (match_operand:SF 1 "register_operand" "0"))))]
10126 [(set_attr "type" "fsgn")
10127 (set_attr "mode" "XF")])
10129 (define_insn "*absextendsfdf2"
10130 [(set (match_operand:DF 0 "register_operand" "=f")
10131 (abs:DF (float_extend:DF
10132 (match_operand:SF 1 "register_operand" "0"))))]
10133 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10135 [(set_attr "type" "fsgn")
10136 (set_attr "mode" "DF")])
10138 (define_insn "*absextenddfxf2"
10139 [(set (match_operand:XF 0 "register_operand" "=f")
10140 (abs:XF (float_extend:XF
10141 (match_operand:DF 1 "register_operand" "0"))))]
10144 [(set_attr "type" "fsgn")
10145 (set_attr "mode" "XF")])
10147 (define_insn "*absextendsfxf2"
10148 [(set (match_operand:XF 0 "register_operand" "=f")
10149 (abs:XF (float_extend:XF
10150 (match_operand:SF 1 "register_operand" "0"))))]
10153 [(set_attr "type" "fsgn")
10154 (set_attr "mode" "XF")])
10156 ;; One complement instructions
10158 (define_expand "one_cmpldi2"
10159 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10160 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10162 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10164 (define_insn "*one_cmpldi2_1_rex64"
10165 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10166 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10167 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10169 [(set_attr "type" "negnot")
10170 (set_attr "mode" "DI")])
10172 (define_insn "*one_cmpldi2_2_rex64"
10173 [(set (reg FLAGS_REG)
10174 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10176 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10177 (not:DI (match_dup 1)))]
10178 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10179 && ix86_unary_operator_ok (NOT, DImode, operands)"
10181 [(set_attr "type" "alu1")
10182 (set_attr "mode" "DI")])
10185 [(set (match_operand 0 "flags_reg_operand" "")
10186 (match_operator 2 "compare_operator"
10187 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10189 (set (match_operand:DI 1 "nonimmediate_operand" "")
10190 (not:DI (match_dup 3)))]
10191 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10192 [(parallel [(set (match_dup 0)
10194 [(xor:DI (match_dup 3) (const_int -1))
10197 (xor:DI (match_dup 3) (const_int -1)))])]
10200 (define_expand "one_cmplsi2"
10201 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10202 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10204 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10206 (define_insn "*one_cmplsi2_1"
10207 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10208 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10209 "ix86_unary_operator_ok (NOT, SImode, operands)"
10211 [(set_attr "type" "negnot")
10212 (set_attr "mode" "SI")])
10214 ;; ??? Currently never generated - xor is used instead.
10215 (define_insn "*one_cmplsi2_1_zext"
10216 [(set (match_operand:DI 0 "register_operand" "=r")
10217 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10218 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10220 [(set_attr "type" "negnot")
10221 (set_attr "mode" "SI")])
10223 (define_insn "*one_cmplsi2_2"
10224 [(set (reg FLAGS_REG)
10225 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10227 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10228 (not:SI (match_dup 1)))]
10229 "ix86_match_ccmode (insn, CCNOmode)
10230 && ix86_unary_operator_ok (NOT, SImode, operands)"
10232 [(set_attr "type" "alu1")
10233 (set_attr "mode" "SI")])
10236 [(set (match_operand 0 "flags_reg_operand" "")
10237 (match_operator 2 "compare_operator"
10238 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10240 (set (match_operand:SI 1 "nonimmediate_operand" "")
10241 (not:SI (match_dup 3)))]
10242 "ix86_match_ccmode (insn, CCNOmode)"
10243 [(parallel [(set (match_dup 0)
10244 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10247 (xor:SI (match_dup 3) (const_int -1)))])]
10250 ;; ??? Currently never generated - xor is used instead.
10251 (define_insn "*one_cmplsi2_2_zext"
10252 [(set (reg FLAGS_REG)
10253 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10255 (set (match_operand:DI 0 "register_operand" "=r")
10256 (zero_extend:DI (not:SI (match_dup 1))))]
10257 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10258 && ix86_unary_operator_ok (NOT, SImode, operands)"
10260 [(set_attr "type" "alu1")
10261 (set_attr "mode" "SI")])
10264 [(set (match_operand 0 "flags_reg_operand" "")
10265 (match_operator 2 "compare_operator"
10266 [(not:SI (match_operand:SI 3 "register_operand" ""))
10268 (set (match_operand:DI 1 "register_operand" "")
10269 (zero_extend:DI (not:SI (match_dup 3))))]
10270 "ix86_match_ccmode (insn, CCNOmode)"
10271 [(parallel [(set (match_dup 0)
10272 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10275 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10278 (define_expand "one_cmplhi2"
10279 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10280 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10281 "TARGET_HIMODE_MATH"
10282 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10284 (define_insn "*one_cmplhi2_1"
10285 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10286 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10287 "ix86_unary_operator_ok (NOT, HImode, operands)"
10289 [(set_attr "type" "negnot")
10290 (set_attr "mode" "HI")])
10292 (define_insn "*one_cmplhi2_2"
10293 [(set (reg FLAGS_REG)
10294 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10296 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10297 (not:HI (match_dup 1)))]
10298 "ix86_match_ccmode (insn, CCNOmode)
10299 && ix86_unary_operator_ok (NEG, HImode, operands)"
10301 [(set_attr "type" "alu1")
10302 (set_attr "mode" "HI")])
10305 [(set (match_operand 0 "flags_reg_operand" "")
10306 (match_operator 2 "compare_operator"
10307 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10309 (set (match_operand:HI 1 "nonimmediate_operand" "")
10310 (not:HI (match_dup 3)))]
10311 "ix86_match_ccmode (insn, CCNOmode)"
10312 [(parallel [(set (match_dup 0)
10313 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10316 (xor:HI (match_dup 3) (const_int -1)))])]
10319 ;; %%% Potential partial reg stall on alternative 1. What to do?
10320 (define_expand "one_cmplqi2"
10321 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10322 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10323 "TARGET_QIMODE_MATH"
10324 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10326 (define_insn "*one_cmplqi2_1"
10327 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10328 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10329 "ix86_unary_operator_ok (NOT, QImode, operands)"
10333 [(set_attr "type" "negnot")
10334 (set_attr "mode" "QI,SI")])
10336 (define_insn "*one_cmplqi2_2"
10337 [(set (reg FLAGS_REG)
10338 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10340 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10341 (not:QI (match_dup 1)))]
10342 "ix86_match_ccmode (insn, CCNOmode)
10343 && ix86_unary_operator_ok (NOT, QImode, operands)"
10345 [(set_attr "type" "alu1")
10346 (set_attr "mode" "QI")])
10349 [(set (match_operand 0 "flags_reg_operand" "")
10350 (match_operator 2 "compare_operator"
10351 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10353 (set (match_operand:QI 1 "nonimmediate_operand" "")
10354 (not:QI (match_dup 3)))]
10355 "ix86_match_ccmode (insn, CCNOmode)"
10356 [(parallel [(set (match_dup 0)
10357 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10360 (xor:QI (match_dup 3) (const_int -1)))])]
10363 ;; Arithmetic shift instructions
10365 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10366 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10367 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10368 ;; from the assembler input.
10370 ;; This instruction shifts the target reg/mem as usual, but instead of
10371 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10372 ;; is a left shift double, bits are taken from the high order bits of
10373 ;; reg, else if the insn is a shift right double, bits are taken from the
10374 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10375 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10377 ;; Since sh[lr]d does not change the `reg' operand, that is done
10378 ;; separately, making all shifts emit pairs of shift double and normal
10379 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10380 ;; support a 63 bit shift, each shift where the count is in a reg expands
10381 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10383 ;; If the shift count is a constant, we need never emit more than one
10384 ;; shift pair, instead using moves and sign extension for counts greater
10387 (define_expand "ashlti3"
10388 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10389 (ashift:TI (match_operand:TI 1 "register_operand" "")
10390 (match_operand:QI 2 "nonmemory_operand" "")))
10391 (clobber (reg:CC FLAGS_REG))])]
10394 if (! immediate_operand (operands[2], QImode))
10396 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10399 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10403 (define_insn "ashlti3_1"
10404 [(set (match_operand:TI 0 "register_operand" "=r")
10405 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10406 (match_operand:QI 2 "register_operand" "c")))
10407 (clobber (match_scratch:DI 3 "=&r"))
10408 (clobber (reg:CC FLAGS_REG))]
10411 [(set_attr "type" "multi")])
10413 (define_insn "*ashlti3_2"
10414 [(set (match_operand:TI 0 "register_operand" "=r")
10415 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10416 (match_operand:QI 2 "immediate_operand" "O")))
10417 (clobber (reg:CC FLAGS_REG))]
10420 [(set_attr "type" "multi")])
10423 [(set (match_operand:TI 0 "register_operand" "")
10424 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10425 (match_operand:QI 2 "register_operand" "")))
10426 (clobber (match_scratch:DI 3 ""))
10427 (clobber (reg:CC FLAGS_REG))]
10428 "TARGET_64BIT && reload_completed"
10430 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10433 [(set (match_operand:TI 0 "register_operand" "")
10434 (ashift:TI (match_operand:TI 1 "register_operand" "")
10435 (match_operand:QI 2 "immediate_operand" "")))
10436 (clobber (reg:CC FLAGS_REG))]
10437 "TARGET_64BIT && reload_completed"
10439 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10441 (define_insn "x86_64_shld"
10442 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10443 (ior:DI (ashift:DI (match_dup 0)
10444 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10445 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10446 (minus:QI (const_int 64) (match_dup 2)))))
10447 (clobber (reg:CC FLAGS_REG))]
10450 shld{q}\t{%2, %1, %0|%0, %1, %2}
10451 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10452 [(set_attr "type" "ishift")
10453 (set_attr "prefix_0f" "1")
10454 (set_attr "mode" "DI")
10455 (set_attr "athlon_decode" "vector")
10456 (set_attr "amdfam10_decode" "vector")])
10458 (define_expand "x86_64_shift_adj"
10459 [(set (reg:CCZ FLAGS_REG)
10460 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10463 (set (match_operand:DI 0 "register_operand" "")
10464 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10465 (match_operand:DI 1 "register_operand" "")
10468 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10469 (match_operand:DI 3 "register_operand" "r")
10474 (define_expand "ashldi3"
10475 [(set (match_operand:DI 0 "shiftdi_operand" "")
10476 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10477 (match_operand:QI 2 "nonmemory_operand" "")))]
10479 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10481 (define_insn "*ashldi3_1_rex64"
10482 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10483 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10484 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10485 (clobber (reg:CC FLAGS_REG))]
10486 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10488 switch (get_attr_type (insn))
10491 gcc_assert (operands[2] == const1_rtx);
10492 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10493 return "add{q}\t{%0, %0|%0, %0}";
10496 gcc_assert (CONST_INT_P (operands[2]));
10497 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10498 operands[1] = gen_rtx_MULT (DImode, operands[1],
10499 GEN_INT (1 << INTVAL (operands[2])));
10500 return "lea{q}\t{%a1, %0|%0, %a1}";
10503 if (REG_P (operands[2]))
10504 return "sal{q}\t{%b2, %0|%0, %b2}";
10505 else if (operands[2] == const1_rtx
10506 && (TARGET_SHIFT1 || optimize_size))
10507 return "sal{q}\t%0";
10509 return "sal{q}\t{%2, %0|%0, %2}";
10512 [(set (attr "type")
10513 (cond [(eq_attr "alternative" "1")
10514 (const_string "lea")
10515 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10517 (match_operand 0 "register_operand" ""))
10518 (match_operand 2 "const1_operand" ""))
10519 (const_string "alu")
10521 (const_string "ishift")))
10522 (set_attr "mode" "DI")])
10524 ;; Convert lea to the lea pattern to avoid flags dependency.
10526 [(set (match_operand:DI 0 "register_operand" "")
10527 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10528 (match_operand:QI 2 "immediate_operand" "")))
10529 (clobber (reg:CC FLAGS_REG))]
10530 "TARGET_64BIT && reload_completed
10531 && true_regnum (operands[0]) != true_regnum (operands[1])"
10532 [(set (match_dup 0)
10533 (mult:DI (match_dup 1)
10535 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10537 ;; This pattern can't accept a variable shift count, since shifts by
10538 ;; zero don't affect the flags. We assume that shifts by constant
10539 ;; zero are optimized away.
10540 (define_insn "*ashldi3_cmp_rex64"
10541 [(set (reg FLAGS_REG)
10543 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10544 (match_operand:QI 2 "immediate_operand" "e"))
10546 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10547 (ashift:DI (match_dup 1) (match_dup 2)))]
10548 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10549 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10551 || !TARGET_PARTIAL_FLAG_REG_STALL
10552 || (operands[2] == const1_rtx
10554 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10556 switch (get_attr_type (insn))
10559 gcc_assert (operands[2] == const1_rtx);
10560 return "add{q}\t{%0, %0|%0, %0}";
10563 if (REG_P (operands[2]))
10564 return "sal{q}\t{%b2, %0|%0, %b2}";
10565 else if (operands[2] == const1_rtx
10566 && (TARGET_SHIFT1 || optimize_size))
10567 return "sal{q}\t%0";
10569 return "sal{q}\t{%2, %0|%0, %2}";
10572 [(set (attr "type")
10573 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10575 (match_operand 0 "register_operand" ""))
10576 (match_operand 2 "const1_operand" ""))
10577 (const_string "alu")
10579 (const_string "ishift")))
10580 (set_attr "mode" "DI")])
10582 (define_insn "*ashldi3_cconly_rex64"
10583 [(set (reg FLAGS_REG)
10585 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10586 (match_operand:QI 2 "immediate_operand" "e"))
10588 (clobber (match_scratch:DI 0 "=r"))]
10589 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10590 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10592 || !TARGET_PARTIAL_FLAG_REG_STALL
10593 || (operands[2] == const1_rtx
10595 || TARGET_DOUBLE_WITH_ADD)))"
10597 switch (get_attr_type (insn))
10600 gcc_assert (operands[2] == const1_rtx);
10601 return "add{q}\t{%0, %0|%0, %0}";
10604 if (REG_P (operands[2]))
10605 return "sal{q}\t{%b2, %0|%0, %b2}";
10606 else if (operands[2] == const1_rtx
10607 && (TARGET_SHIFT1 || optimize_size))
10608 return "sal{q}\t%0";
10610 return "sal{q}\t{%2, %0|%0, %2}";
10613 [(set (attr "type")
10614 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10616 (match_operand 0 "register_operand" ""))
10617 (match_operand 2 "const1_operand" ""))
10618 (const_string "alu")
10620 (const_string "ishift")))
10621 (set_attr "mode" "DI")])
10623 (define_insn "*ashldi3_1"
10624 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10625 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10626 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10627 (clobber (reg:CC FLAGS_REG))]
10630 [(set_attr "type" "multi")])
10632 ;; By default we don't ask for a scratch register, because when DImode
10633 ;; values are manipulated, registers are already at a premium. But if
10634 ;; we have one handy, we won't turn it away.
10636 [(match_scratch:SI 3 "r")
10637 (parallel [(set (match_operand:DI 0 "register_operand" "")
10638 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10639 (match_operand:QI 2 "nonmemory_operand" "")))
10640 (clobber (reg:CC FLAGS_REG))])
10642 "!TARGET_64BIT && TARGET_CMOVE"
10644 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10647 [(set (match_operand:DI 0 "register_operand" "")
10648 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10649 (match_operand:QI 2 "nonmemory_operand" "")))
10650 (clobber (reg:CC FLAGS_REG))]
10651 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10652 ? flow2_completed : reload_completed)"
10654 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10656 (define_insn "x86_shld_1"
10657 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10658 (ior:SI (ashift:SI (match_dup 0)
10659 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10660 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10661 (minus:QI (const_int 32) (match_dup 2)))))
10662 (clobber (reg:CC FLAGS_REG))]
10665 shld{l}\t{%2, %1, %0|%0, %1, %2}
10666 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10667 [(set_attr "type" "ishift")
10668 (set_attr "prefix_0f" "1")
10669 (set_attr "mode" "SI")
10670 (set_attr "pent_pair" "np")
10671 (set_attr "athlon_decode" "vector")
10672 (set_attr "amdfam10_decode" "vector")])
10674 (define_expand "x86_shift_adj_1"
10675 [(set (reg:CCZ FLAGS_REG)
10676 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10679 (set (match_operand:SI 0 "register_operand" "")
10680 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10681 (match_operand:SI 1 "register_operand" "")
10684 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10685 (match_operand:SI 3 "register_operand" "r")
10690 (define_expand "x86_shift_adj_2"
10691 [(use (match_operand:SI 0 "register_operand" ""))
10692 (use (match_operand:SI 1 "register_operand" ""))
10693 (use (match_operand:QI 2 "register_operand" ""))]
10696 rtx label = gen_label_rtx ();
10699 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10701 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10702 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10703 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10704 gen_rtx_LABEL_REF (VOIDmode, label),
10706 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10707 JUMP_LABEL (tmp) = label;
10709 emit_move_insn (operands[0], operands[1]);
10710 ix86_expand_clear (operands[1]);
10712 emit_label (label);
10713 LABEL_NUSES (label) = 1;
10718 (define_expand "ashlsi3"
10719 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10720 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10721 (match_operand:QI 2 "nonmemory_operand" "")))
10722 (clobber (reg:CC FLAGS_REG))]
10724 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10726 (define_insn "*ashlsi3_1"
10727 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10728 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10729 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10730 (clobber (reg:CC FLAGS_REG))]
10731 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10733 switch (get_attr_type (insn))
10736 gcc_assert (operands[2] == const1_rtx);
10737 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10738 return "add{l}\t{%0, %0|%0, %0}";
10744 if (REG_P (operands[2]))
10745 return "sal{l}\t{%b2, %0|%0, %b2}";
10746 else if (operands[2] == const1_rtx
10747 && (TARGET_SHIFT1 || optimize_size))
10748 return "sal{l}\t%0";
10750 return "sal{l}\t{%2, %0|%0, %2}";
10753 [(set (attr "type")
10754 (cond [(eq_attr "alternative" "1")
10755 (const_string "lea")
10756 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10758 (match_operand 0 "register_operand" ""))
10759 (match_operand 2 "const1_operand" ""))
10760 (const_string "alu")
10762 (const_string "ishift")))
10763 (set_attr "mode" "SI")])
10765 ;; Convert lea to the lea pattern to avoid flags dependency.
10767 [(set (match_operand 0 "register_operand" "")
10768 (ashift (match_operand 1 "index_register_operand" "")
10769 (match_operand:QI 2 "const_int_operand" "")))
10770 (clobber (reg:CC FLAGS_REG))]
10772 && true_regnum (operands[0]) != true_regnum (operands[1])
10773 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10777 enum machine_mode mode = GET_MODE (operands[0]);
10779 if (GET_MODE_SIZE (mode) < 4)
10780 operands[0] = gen_lowpart (SImode, operands[0]);
10782 operands[1] = gen_lowpart (Pmode, operands[1]);
10783 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10785 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10786 if (Pmode != SImode)
10787 pat = gen_rtx_SUBREG (SImode, pat, 0);
10788 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10792 ;; Rare case of shifting RSP is handled by generating move and shift
10794 [(set (match_operand 0 "register_operand" "")
10795 (ashift (match_operand 1 "register_operand" "")
10796 (match_operand:QI 2 "const_int_operand" "")))
10797 (clobber (reg:CC FLAGS_REG))]
10799 && true_regnum (operands[0]) != true_regnum (operands[1])"
10803 emit_move_insn (operands[0], operands[1]);
10804 pat = gen_rtx_SET (VOIDmode, operands[0],
10805 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10806 operands[0], operands[2]));
10807 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10808 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10812 (define_insn "*ashlsi3_1_zext"
10813 [(set (match_operand:DI 0 "register_operand" "=r,r")
10814 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10815 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10816 (clobber (reg:CC FLAGS_REG))]
10817 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10819 switch (get_attr_type (insn))
10822 gcc_assert (operands[2] == const1_rtx);
10823 return "add{l}\t{%k0, %k0|%k0, %k0}";
10829 if (REG_P (operands[2]))
10830 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10831 else if (operands[2] == const1_rtx
10832 && (TARGET_SHIFT1 || optimize_size))
10833 return "sal{l}\t%k0";
10835 return "sal{l}\t{%2, %k0|%k0, %2}";
10838 [(set (attr "type")
10839 (cond [(eq_attr "alternative" "1")
10840 (const_string "lea")
10841 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10843 (match_operand 2 "const1_operand" ""))
10844 (const_string "alu")
10846 (const_string "ishift")))
10847 (set_attr "mode" "SI")])
10849 ;; Convert lea to the lea pattern to avoid flags dependency.
10851 [(set (match_operand:DI 0 "register_operand" "")
10852 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10853 (match_operand:QI 2 "const_int_operand" ""))))
10854 (clobber (reg:CC FLAGS_REG))]
10855 "TARGET_64BIT && reload_completed
10856 && true_regnum (operands[0]) != true_regnum (operands[1])"
10857 [(set (match_dup 0) (zero_extend:DI
10858 (subreg:SI (mult:SI (match_dup 1)
10859 (match_dup 2)) 0)))]
10861 operands[1] = gen_lowpart (Pmode, operands[1]);
10862 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10865 ;; This pattern can't accept a variable shift count, since shifts by
10866 ;; zero don't affect the flags. We assume that shifts by constant
10867 ;; zero are optimized away.
10868 (define_insn "*ashlsi3_cmp"
10869 [(set (reg FLAGS_REG)
10871 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10872 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10874 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10875 (ashift:SI (match_dup 1) (match_dup 2)))]
10876 "ix86_match_ccmode (insn, CCGOCmode)
10877 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10879 || !TARGET_PARTIAL_FLAG_REG_STALL
10880 || (operands[2] == const1_rtx
10882 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10884 switch (get_attr_type (insn))
10887 gcc_assert (operands[2] == const1_rtx);
10888 return "add{l}\t{%0, %0|%0, %0}";
10891 if (REG_P (operands[2]))
10892 return "sal{l}\t{%b2, %0|%0, %b2}";
10893 else if (operands[2] == const1_rtx
10894 && (TARGET_SHIFT1 || optimize_size))
10895 return "sal{l}\t%0";
10897 return "sal{l}\t{%2, %0|%0, %2}";
10900 [(set (attr "type")
10901 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10903 (match_operand 0 "register_operand" ""))
10904 (match_operand 2 "const1_operand" ""))
10905 (const_string "alu")
10907 (const_string "ishift")))
10908 (set_attr "mode" "SI")])
10910 (define_insn "*ashlsi3_cconly"
10911 [(set (reg FLAGS_REG)
10913 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10914 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10916 (clobber (match_scratch:SI 0 "=r"))]
10917 "ix86_match_ccmode (insn, CCGOCmode)
10918 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10920 || !TARGET_PARTIAL_FLAG_REG_STALL
10921 || (operands[2] == const1_rtx
10923 || TARGET_DOUBLE_WITH_ADD)))"
10925 switch (get_attr_type (insn))
10928 gcc_assert (operands[2] == const1_rtx);
10929 return "add{l}\t{%0, %0|%0, %0}";
10932 if (REG_P (operands[2]))
10933 return "sal{l}\t{%b2, %0|%0, %b2}";
10934 else if (operands[2] == const1_rtx
10935 && (TARGET_SHIFT1 || optimize_size))
10936 return "sal{l}\t%0";
10938 return "sal{l}\t{%2, %0|%0, %2}";
10941 [(set (attr "type")
10942 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10944 (match_operand 0 "register_operand" ""))
10945 (match_operand 2 "const1_operand" ""))
10946 (const_string "alu")
10948 (const_string "ishift")))
10949 (set_attr "mode" "SI")])
10951 (define_insn "*ashlsi3_cmp_zext"
10952 [(set (reg FLAGS_REG)
10954 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10955 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10957 (set (match_operand:DI 0 "register_operand" "=r")
10958 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10959 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10960 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10962 || !TARGET_PARTIAL_FLAG_REG_STALL
10963 || (operands[2] == const1_rtx
10965 || TARGET_DOUBLE_WITH_ADD)))"
10967 switch (get_attr_type (insn))
10970 gcc_assert (operands[2] == const1_rtx);
10971 return "add{l}\t{%k0, %k0|%k0, %k0}";
10974 if (REG_P (operands[2]))
10975 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10976 else if (operands[2] == const1_rtx
10977 && (TARGET_SHIFT1 || optimize_size))
10978 return "sal{l}\t%k0";
10980 return "sal{l}\t{%2, %k0|%k0, %2}";
10983 [(set (attr "type")
10984 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10986 (match_operand 2 "const1_operand" ""))
10987 (const_string "alu")
10989 (const_string "ishift")))
10990 (set_attr "mode" "SI")])
10992 (define_expand "ashlhi3"
10993 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10994 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10995 (match_operand:QI 2 "nonmemory_operand" "")))
10996 (clobber (reg:CC FLAGS_REG))]
10997 "TARGET_HIMODE_MATH"
10998 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11000 (define_insn "*ashlhi3_1_lea"
11001 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11002 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11003 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11004 (clobber (reg:CC FLAGS_REG))]
11005 "!TARGET_PARTIAL_REG_STALL
11006 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11008 switch (get_attr_type (insn))
11013 gcc_assert (operands[2] == const1_rtx);
11014 return "add{w}\t{%0, %0|%0, %0}";
11017 if (REG_P (operands[2]))
11018 return "sal{w}\t{%b2, %0|%0, %b2}";
11019 else if (operands[2] == const1_rtx
11020 && (TARGET_SHIFT1 || optimize_size))
11021 return "sal{w}\t%0";
11023 return "sal{w}\t{%2, %0|%0, %2}";
11026 [(set (attr "type")
11027 (cond [(eq_attr "alternative" "1")
11028 (const_string "lea")
11029 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11031 (match_operand 0 "register_operand" ""))
11032 (match_operand 2 "const1_operand" ""))
11033 (const_string "alu")
11035 (const_string "ishift")))
11036 (set_attr "mode" "HI,SI")])
11038 (define_insn "*ashlhi3_1"
11039 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11040 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11041 (match_operand:QI 2 "nonmemory_operand" "cI")))
11042 (clobber (reg:CC FLAGS_REG))]
11043 "TARGET_PARTIAL_REG_STALL
11044 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11046 switch (get_attr_type (insn))
11049 gcc_assert (operands[2] == const1_rtx);
11050 return "add{w}\t{%0, %0|%0, %0}";
11053 if (REG_P (operands[2]))
11054 return "sal{w}\t{%b2, %0|%0, %b2}";
11055 else if (operands[2] == const1_rtx
11056 && (TARGET_SHIFT1 || optimize_size))
11057 return "sal{w}\t%0";
11059 return "sal{w}\t{%2, %0|%0, %2}";
11062 [(set (attr "type")
11063 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11065 (match_operand 0 "register_operand" ""))
11066 (match_operand 2 "const1_operand" ""))
11067 (const_string "alu")
11069 (const_string "ishift")))
11070 (set_attr "mode" "HI")])
11072 ;; This pattern can't accept a variable shift count, since shifts by
11073 ;; zero don't affect the flags. We assume that shifts by constant
11074 ;; zero are optimized away.
11075 (define_insn "*ashlhi3_cmp"
11076 [(set (reg FLAGS_REG)
11078 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11079 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11081 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11082 (ashift:HI (match_dup 1) (match_dup 2)))]
11083 "ix86_match_ccmode (insn, CCGOCmode)
11084 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11086 || !TARGET_PARTIAL_FLAG_REG_STALL
11087 || (operands[2] == const1_rtx
11089 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11091 switch (get_attr_type (insn))
11094 gcc_assert (operands[2] == const1_rtx);
11095 return "add{w}\t{%0, %0|%0, %0}";
11098 if (REG_P (operands[2]))
11099 return "sal{w}\t{%b2, %0|%0, %b2}";
11100 else if (operands[2] == const1_rtx
11101 && (TARGET_SHIFT1 || optimize_size))
11102 return "sal{w}\t%0";
11104 return "sal{w}\t{%2, %0|%0, %2}";
11107 [(set (attr "type")
11108 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11110 (match_operand 0 "register_operand" ""))
11111 (match_operand 2 "const1_operand" ""))
11112 (const_string "alu")
11114 (const_string "ishift")))
11115 (set_attr "mode" "HI")])
11117 (define_insn "*ashlhi3_cconly"
11118 [(set (reg FLAGS_REG)
11120 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11121 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11123 (clobber (match_scratch:HI 0 "=r"))]
11124 "ix86_match_ccmode (insn, CCGOCmode)
11125 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11127 || !TARGET_PARTIAL_FLAG_REG_STALL
11128 || (operands[2] == const1_rtx
11130 || TARGET_DOUBLE_WITH_ADD)))"
11132 switch (get_attr_type (insn))
11135 gcc_assert (operands[2] == const1_rtx);
11136 return "add{w}\t{%0, %0|%0, %0}";
11139 if (REG_P (operands[2]))
11140 return "sal{w}\t{%b2, %0|%0, %b2}";
11141 else if (operands[2] == const1_rtx
11142 && (TARGET_SHIFT1 || optimize_size))
11143 return "sal{w}\t%0";
11145 return "sal{w}\t{%2, %0|%0, %2}";
11148 [(set (attr "type")
11149 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11151 (match_operand 0 "register_operand" ""))
11152 (match_operand 2 "const1_operand" ""))
11153 (const_string "alu")
11155 (const_string "ishift")))
11156 (set_attr "mode" "HI")])
11158 (define_expand "ashlqi3"
11159 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11160 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11161 (match_operand:QI 2 "nonmemory_operand" "")))
11162 (clobber (reg:CC FLAGS_REG))]
11163 "TARGET_QIMODE_MATH"
11164 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11166 ;; %%% Potential partial reg stall on alternative 2. What to do?
11168 (define_insn "*ashlqi3_1_lea"
11169 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11170 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11171 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11172 (clobber (reg:CC FLAGS_REG))]
11173 "!TARGET_PARTIAL_REG_STALL
11174 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11176 switch (get_attr_type (insn))
11181 gcc_assert (operands[2] == const1_rtx);
11182 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11183 return "add{l}\t{%k0, %k0|%k0, %k0}";
11185 return "add{b}\t{%0, %0|%0, %0}";
11188 if (REG_P (operands[2]))
11190 if (get_attr_mode (insn) == MODE_SI)
11191 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11193 return "sal{b}\t{%b2, %0|%0, %b2}";
11195 else if (operands[2] == const1_rtx
11196 && (TARGET_SHIFT1 || optimize_size))
11198 if (get_attr_mode (insn) == MODE_SI)
11199 return "sal{l}\t%0";
11201 return "sal{b}\t%0";
11205 if (get_attr_mode (insn) == MODE_SI)
11206 return "sal{l}\t{%2, %k0|%k0, %2}";
11208 return "sal{b}\t{%2, %0|%0, %2}";
11212 [(set (attr "type")
11213 (cond [(eq_attr "alternative" "2")
11214 (const_string "lea")
11215 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11217 (match_operand 0 "register_operand" ""))
11218 (match_operand 2 "const1_operand" ""))
11219 (const_string "alu")
11221 (const_string "ishift")))
11222 (set_attr "mode" "QI,SI,SI")])
11224 (define_insn "*ashlqi3_1"
11225 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11226 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11227 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11228 (clobber (reg:CC FLAGS_REG))]
11229 "TARGET_PARTIAL_REG_STALL
11230 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11232 switch (get_attr_type (insn))
11235 gcc_assert (operands[2] == const1_rtx);
11236 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11237 return "add{l}\t{%k0, %k0|%k0, %k0}";
11239 return "add{b}\t{%0, %0|%0, %0}";
11242 if (REG_P (operands[2]))
11244 if (get_attr_mode (insn) == MODE_SI)
11245 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11247 return "sal{b}\t{%b2, %0|%0, %b2}";
11249 else if (operands[2] == const1_rtx
11250 && (TARGET_SHIFT1 || optimize_size))
11252 if (get_attr_mode (insn) == MODE_SI)
11253 return "sal{l}\t%0";
11255 return "sal{b}\t%0";
11259 if (get_attr_mode (insn) == MODE_SI)
11260 return "sal{l}\t{%2, %k0|%k0, %2}";
11262 return "sal{b}\t{%2, %0|%0, %2}";
11266 [(set (attr "type")
11267 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11269 (match_operand 0 "register_operand" ""))
11270 (match_operand 2 "const1_operand" ""))
11271 (const_string "alu")
11273 (const_string "ishift")))
11274 (set_attr "mode" "QI,SI")])
11276 ;; This pattern can't accept a variable shift count, since shifts by
11277 ;; zero don't affect the flags. We assume that shifts by constant
11278 ;; zero are optimized away.
11279 (define_insn "*ashlqi3_cmp"
11280 [(set (reg FLAGS_REG)
11282 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11283 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11285 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11286 (ashift:QI (match_dup 1) (match_dup 2)))]
11287 "ix86_match_ccmode (insn, CCGOCmode)
11288 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11290 || !TARGET_PARTIAL_FLAG_REG_STALL
11291 || (operands[2] == const1_rtx
11293 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11295 switch (get_attr_type (insn))
11298 gcc_assert (operands[2] == const1_rtx);
11299 return "add{b}\t{%0, %0|%0, %0}";
11302 if (REG_P (operands[2]))
11303 return "sal{b}\t{%b2, %0|%0, %b2}";
11304 else if (operands[2] == const1_rtx
11305 && (TARGET_SHIFT1 || optimize_size))
11306 return "sal{b}\t%0";
11308 return "sal{b}\t{%2, %0|%0, %2}";
11311 [(set (attr "type")
11312 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11314 (match_operand 0 "register_operand" ""))
11315 (match_operand 2 "const1_operand" ""))
11316 (const_string "alu")
11318 (const_string "ishift")))
11319 (set_attr "mode" "QI")])
11321 (define_insn "*ashlqi3_cconly"
11322 [(set (reg FLAGS_REG)
11324 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11325 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11327 (clobber (match_scratch:QI 0 "=q"))]
11328 "ix86_match_ccmode (insn, CCGOCmode)
11329 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11331 || !TARGET_PARTIAL_FLAG_REG_STALL
11332 || (operands[2] == const1_rtx
11334 || TARGET_DOUBLE_WITH_ADD)))"
11336 switch (get_attr_type (insn))
11339 gcc_assert (operands[2] == const1_rtx);
11340 return "add{b}\t{%0, %0|%0, %0}";
11343 if (REG_P (operands[2]))
11344 return "sal{b}\t{%b2, %0|%0, %b2}";
11345 else if (operands[2] == const1_rtx
11346 && (TARGET_SHIFT1 || optimize_size))
11347 return "sal{b}\t%0";
11349 return "sal{b}\t{%2, %0|%0, %2}";
11352 [(set (attr "type")
11353 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11355 (match_operand 0 "register_operand" ""))
11356 (match_operand 2 "const1_operand" ""))
11357 (const_string "alu")
11359 (const_string "ishift")))
11360 (set_attr "mode" "QI")])
11362 ;; See comment above `ashldi3' about how this works.
11364 (define_expand "ashrti3"
11365 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11366 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11367 (match_operand:QI 2 "nonmemory_operand" "")))
11368 (clobber (reg:CC FLAGS_REG))])]
11371 if (! immediate_operand (operands[2], QImode))
11373 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11376 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11380 (define_insn "ashrti3_1"
11381 [(set (match_operand:TI 0 "register_operand" "=r")
11382 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11383 (match_operand:QI 2 "register_operand" "c")))
11384 (clobber (match_scratch:DI 3 "=&r"))
11385 (clobber (reg:CC FLAGS_REG))]
11388 [(set_attr "type" "multi")])
11390 (define_insn "*ashrti3_2"
11391 [(set (match_operand:TI 0 "register_operand" "=r")
11392 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11393 (match_operand:QI 2 "immediate_operand" "O")))
11394 (clobber (reg:CC FLAGS_REG))]
11397 [(set_attr "type" "multi")])
11400 [(set (match_operand:TI 0 "register_operand" "")
11401 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11402 (match_operand:QI 2 "register_operand" "")))
11403 (clobber (match_scratch:DI 3 ""))
11404 (clobber (reg:CC FLAGS_REG))]
11405 "TARGET_64BIT && reload_completed"
11407 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11410 [(set (match_operand:TI 0 "register_operand" "")
11411 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11412 (match_operand:QI 2 "immediate_operand" "")))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "TARGET_64BIT && reload_completed"
11416 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11418 (define_insn "x86_64_shrd"
11419 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11420 (ior:DI (ashiftrt:DI (match_dup 0)
11421 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11422 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11423 (minus:QI (const_int 64) (match_dup 2)))))
11424 (clobber (reg:CC FLAGS_REG))]
11427 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11428 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11429 [(set_attr "type" "ishift")
11430 (set_attr "prefix_0f" "1")
11431 (set_attr "mode" "DI")
11432 (set_attr "athlon_decode" "vector")
11433 (set_attr "amdfam10_decode" "vector")])
11435 (define_expand "ashrdi3"
11436 [(set (match_operand:DI 0 "shiftdi_operand" "")
11437 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11438 (match_operand:QI 2 "nonmemory_operand" "")))]
11440 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11442 (define_insn "*ashrdi3_63_rex64"
11443 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11444 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11445 (match_operand:DI 2 "const_int_operand" "i,i")))
11446 (clobber (reg:CC FLAGS_REG))]
11447 "TARGET_64BIT && INTVAL (operands[2]) == 63
11448 && (TARGET_USE_CLTD || optimize_size)
11449 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11452 sar{q}\t{%2, %0|%0, %2}"
11453 [(set_attr "type" "imovx,ishift")
11454 (set_attr "prefix_0f" "0,*")
11455 (set_attr "length_immediate" "0,*")
11456 (set_attr "modrm" "0,1")
11457 (set_attr "mode" "DI")])
11459 (define_insn "*ashrdi3_1_one_bit_rex64"
11460 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11461 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11462 (match_operand:QI 2 "const1_operand" "")))
11463 (clobber (reg:CC FLAGS_REG))]
11464 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11465 && (TARGET_SHIFT1 || optimize_size)"
11467 [(set_attr "type" "ishift")
11468 (set (attr "length")
11469 (if_then_else (match_operand:DI 0 "register_operand" "")
11471 (const_string "*")))])
11473 (define_insn "*ashrdi3_1_rex64"
11474 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11475 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11476 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11477 (clobber (reg:CC FLAGS_REG))]
11478 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11480 sar{q}\t{%2, %0|%0, %2}
11481 sar{q}\t{%b2, %0|%0, %b2}"
11482 [(set_attr "type" "ishift")
11483 (set_attr "mode" "DI")])
11485 ;; This pattern can't accept a variable shift count, since shifts by
11486 ;; zero don't affect the flags. We assume that shifts by constant
11487 ;; zero are optimized away.
11488 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11489 [(set (reg FLAGS_REG)
11491 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11492 (match_operand:QI 2 "const1_operand" ""))
11494 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11495 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11496 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11497 && (TARGET_SHIFT1 || optimize_size)
11498 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11500 [(set_attr "type" "ishift")
11501 (set (attr "length")
11502 (if_then_else (match_operand:DI 0 "register_operand" "")
11504 (const_string "*")))])
11506 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11507 [(set (reg FLAGS_REG)
11509 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11510 (match_operand:QI 2 "const1_operand" ""))
11512 (clobber (match_scratch:DI 0 "=r"))]
11513 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11514 && (TARGET_SHIFT1 || optimize_size)
11515 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11517 [(set_attr "type" "ishift")
11518 (set_attr "length" "2")])
11520 ;; This pattern can't accept a variable shift count, since shifts by
11521 ;; zero don't affect the flags. We assume that shifts by constant
11522 ;; zero are optimized away.
11523 (define_insn "*ashrdi3_cmp_rex64"
11524 [(set (reg FLAGS_REG)
11526 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11527 (match_operand:QI 2 "const_int_operand" "n"))
11529 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11530 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11531 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11532 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11534 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11535 "sar{q}\t{%2, %0|%0, %2}"
11536 [(set_attr "type" "ishift")
11537 (set_attr "mode" "DI")])
11539 (define_insn "*ashrdi3_cconly_rex64"
11540 [(set (reg FLAGS_REG)
11542 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11543 (match_operand:QI 2 "const_int_operand" "n"))
11545 (clobber (match_scratch:DI 0 "=r"))]
11546 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11547 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11549 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11550 "sar{q}\t{%2, %0|%0, %2}"
11551 [(set_attr "type" "ishift")
11552 (set_attr "mode" "DI")])
11554 (define_insn "*ashrdi3_1"
11555 [(set (match_operand:DI 0 "register_operand" "=r")
11556 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11557 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11558 (clobber (reg:CC FLAGS_REG))]
11561 [(set_attr "type" "multi")])
11563 ;; By default we don't ask for a scratch register, because when DImode
11564 ;; values are manipulated, registers are already at a premium. But if
11565 ;; we have one handy, we won't turn it away.
11567 [(match_scratch:SI 3 "r")
11568 (parallel [(set (match_operand:DI 0 "register_operand" "")
11569 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11570 (match_operand:QI 2 "nonmemory_operand" "")))
11571 (clobber (reg:CC FLAGS_REG))])
11573 "!TARGET_64BIT && TARGET_CMOVE"
11575 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11578 [(set (match_operand:DI 0 "register_operand" "")
11579 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11580 (match_operand:QI 2 "nonmemory_operand" "")))
11581 (clobber (reg:CC FLAGS_REG))]
11582 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11583 ? flow2_completed : reload_completed)"
11585 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11587 (define_insn "x86_shrd_1"
11588 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11589 (ior:SI (ashiftrt:SI (match_dup 0)
11590 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11591 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11592 (minus:QI (const_int 32) (match_dup 2)))))
11593 (clobber (reg:CC FLAGS_REG))]
11596 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11597 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11598 [(set_attr "type" "ishift")
11599 (set_attr "prefix_0f" "1")
11600 (set_attr "pent_pair" "np")
11601 (set_attr "mode" "SI")])
11603 (define_expand "x86_shift_adj_3"
11604 [(use (match_operand:SI 0 "register_operand" ""))
11605 (use (match_operand:SI 1 "register_operand" ""))
11606 (use (match_operand:QI 2 "register_operand" ""))]
11609 rtx label = gen_label_rtx ();
11612 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11614 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11615 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11616 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11617 gen_rtx_LABEL_REF (VOIDmode, label),
11619 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11620 JUMP_LABEL (tmp) = label;
11622 emit_move_insn (operands[0], operands[1]);
11623 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11625 emit_label (label);
11626 LABEL_NUSES (label) = 1;
11631 (define_insn "ashrsi3_31"
11632 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11633 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11634 (match_operand:SI 2 "const_int_operand" "i,i")))
11635 (clobber (reg:CC FLAGS_REG))]
11636 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11637 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11640 sar{l}\t{%2, %0|%0, %2}"
11641 [(set_attr "type" "imovx,ishift")
11642 (set_attr "prefix_0f" "0,*")
11643 (set_attr "length_immediate" "0,*")
11644 (set_attr "modrm" "0,1")
11645 (set_attr "mode" "SI")])
11647 (define_insn "*ashrsi3_31_zext"
11648 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11649 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11650 (match_operand:SI 2 "const_int_operand" "i,i"))))
11651 (clobber (reg:CC FLAGS_REG))]
11652 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11653 && INTVAL (operands[2]) == 31
11654 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11657 sar{l}\t{%2, %k0|%k0, %2}"
11658 [(set_attr "type" "imovx,ishift")
11659 (set_attr "prefix_0f" "0,*")
11660 (set_attr "length_immediate" "0,*")
11661 (set_attr "modrm" "0,1")
11662 (set_attr "mode" "SI")])
11664 (define_expand "ashrsi3"
11665 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11666 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11667 (match_operand:QI 2 "nonmemory_operand" "")))
11668 (clobber (reg:CC FLAGS_REG))]
11670 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11672 (define_insn "*ashrsi3_1_one_bit"
11673 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11674 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11675 (match_operand:QI 2 "const1_operand" "")))
11676 (clobber (reg:CC FLAGS_REG))]
11677 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11678 && (TARGET_SHIFT1 || optimize_size)"
11680 [(set_attr "type" "ishift")
11681 (set (attr "length")
11682 (if_then_else (match_operand:SI 0 "register_operand" "")
11684 (const_string "*")))])
11686 (define_insn "*ashrsi3_1_one_bit_zext"
11687 [(set (match_operand:DI 0 "register_operand" "=r")
11688 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11689 (match_operand:QI 2 "const1_operand" ""))))
11690 (clobber (reg:CC FLAGS_REG))]
11691 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11692 && (TARGET_SHIFT1 || optimize_size)"
11694 [(set_attr "type" "ishift")
11695 (set_attr "length" "2")])
11697 (define_insn "*ashrsi3_1"
11698 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11699 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11700 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11701 (clobber (reg:CC FLAGS_REG))]
11702 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11704 sar{l}\t{%2, %0|%0, %2}
11705 sar{l}\t{%b2, %0|%0, %b2}"
11706 [(set_attr "type" "ishift")
11707 (set_attr "mode" "SI")])
11709 (define_insn "*ashrsi3_1_zext"
11710 [(set (match_operand:DI 0 "register_operand" "=r,r")
11711 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11712 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11713 (clobber (reg:CC FLAGS_REG))]
11714 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11716 sar{l}\t{%2, %k0|%k0, %2}
11717 sar{l}\t{%b2, %k0|%k0, %b2}"
11718 [(set_attr "type" "ishift")
11719 (set_attr "mode" "SI")])
11721 ;; This pattern can't accept a variable shift count, since shifts by
11722 ;; zero don't affect the flags. We assume that shifts by constant
11723 ;; zero are optimized away.
11724 (define_insn "*ashrsi3_one_bit_cmp"
11725 [(set (reg FLAGS_REG)
11727 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11728 (match_operand:QI 2 "const1_operand" ""))
11730 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11731 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11732 "ix86_match_ccmode (insn, CCGOCmode)
11733 && (TARGET_SHIFT1 || optimize_size)
11734 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11736 [(set_attr "type" "ishift")
11737 (set (attr "length")
11738 (if_then_else (match_operand:SI 0 "register_operand" "")
11740 (const_string "*")))])
11742 (define_insn "*ashrsi3_one_bit_cconly"
11743 [(set (reg FLAGS_REG)
11745 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11746 (match_operand:QI 2 "const1_operand" ""))
11748 (clobber (match_scratch:SI 0 "=r"))]
11749 "ix86_match_ccmode (insn, CCGOCmode)
11750 && (TARGET_SHIFT1 || optimize_size)
11751 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11753 [(set_attr "type" "ishift")
11754 (set_attr "length" "2")])
11756 (define_insn "*ashrsi3_one_bit_cmp_zext"
11757 [(set (reg FLAGS_REG)
11759 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11760 (match_operand:QI 2 "const1_operand" ""))
11762 (set (match_operand:DI 0 "register_operand" "=r")
11763 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11764 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11765 && (TARGET_SHIFT1 || optimize_size)
11766 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11768 [(set_attr "type" "ishift")
11769 (set_attr "length" "2")])
11771 ;; This pattern can't accept a variable shift count, since shifts by
11772 ;; zero don't affect the flags. We assume that shifts by constant
11773 ;; zero are optimized away.
11774 (define_insn "*ashrsi3_cmp"
11775 [(set (reg FLAGS_REG)
11777 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11778 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11780 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11781 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11782 "ix86_match_ccmode (insn, CCGOCmode)
11783 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11785 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11786 "sar{l}\t{%2, %0|%0, %2}"
11787 [(set_attr "type" "ishift")
11788 (set_attr "mode" "SI")])
11790 (define_insn "*ashrsi3_cconly"
11791 [(set (reg FLAGS_REG)
11793 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11794 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11796 (clobber (match_scratch:SI 0 "=r"))]
11797 "ix86_match_ccmode (insn, CCGOCmode)
11798 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11800 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11801 "sar{l}\t{%2, %0|%0, %2}"
11802 [(set_attr "type" "ishift")
11803 (set_attr "mode" "SI")])
11805 (define_insn "*ashrsi3_cmp_zext"
11806 [(set (reg FLAGS_REG)
11808 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11809 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11811 (set (match_operand:DI 0 "register_operand" "=r")
11812 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11813 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11814 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11816 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11817 "sar{l}\t{%2, %k0|%k0, %2}"
11818 [(set_attr "type" "ishift")
11819 (set_attr "mode" "SI")])
11821 (define_expand "ashrhi3"
11822 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11823 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11824 (match_operand:QI 2 "nonmemory_operand" "")))
11825 (clobber (reg:CC FLAGS_REG))]
11826 "TARGET_HIMODE_MATH"
11827 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11829 (define_insn "*ashrhi3_1_one_bit"
11830 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11831 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11832 (match_operand:QI 2 "const1_operand" "")))
11833 (clobber (reg:CC FLAGS_REG))]
11834 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11835 && (TARGET_SHIFT1 || optimize_size)"
11837 [(set_attr "type" "ishift")
11838 (set (attr "length")
11839 (if_then_else (match_operand 0 "register_operand" "")
11841 (const_string "*")))])
11843 (define_insn "*ashrhi3_1"
11844 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11845 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11846 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11847 (clobber (reg:CC FLAGS_REG))]
11848 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11850 sar{w}\t{%2, %0|%0, %2}
11851 sar{w}\t{%b2, %0|%0, %b2}"
11852 [(set_attr "type" "ishift")
11853 (set_attr "mode" "HI")])
11855 ;; This pattern can't accept a variable shift count, since shifts by
11856 ;; zero don't affect the flags. We assume that shifts by constant
11857 ;; zero are optimized away.
11858 (define_insn "*ashrhi3_one_bit_cmp"
11859 [(set (reg FLAGS_REG)
11861 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11862 (match_operand:QI 2 "const1_operand" ""))
11864 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11865 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11866 "ix86_match_ccmode (insn, CCGOCmode)
11867 && (TARGET_SHIFT1 || optimize_size)
11868 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11870 [(set_attr "type" "ishift")
11871 (set (attr "length")
11872 (if_then_else (match_operand 0 "register_operand" "")
11874 (const_string "*")))])
11876 (define_insn "*ashrhi3_one_bit_cconly"
11877 [(set (reg FLAGS_REG)
11879 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11880 (match_operand:QI 2 "const1_operand" ""))
11882 (clobber (match_scratch:HI 0 "=r"))]
11883 "ix86_match_ccmode (insn, CCGOCmode)
11884 && (TARGET_SHIFT1 || optimize_size)
11885 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11887 [(set_attr "type" "ishift")
11888 (set_attr "length" "2")])
11890 ;; This pattern can't accept a variable shift count, since shifts by
11891 ;; zero don't affect the flags. We assume that shifts by constant
11892 ;; zero are optimized away.
11893 (define_insn "*ashrhi3_cmp"
11894 [(set (reg FLAGS_REG)
11896 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11897 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11899 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11900 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11901 "ix86_match_ccmode (insn, CCGOCmode)
11902 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11904 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11905 "sar{w}\t{%2, %0|%0, %2}"
11906 [(set_attr "type" "ishift")
11907 (set_attr "mode" "HI")])
11909 (define_insn "*ashrhi3_cconly"
11910 [(set (reg FLAGS_REG)
11912 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11913 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11915 (clobber (match_scratch:HI 0 "=r"))]
11916 "ix86_match_ccmode (insn, CCGOCmode)
11917 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11919 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11920 "sar{w}\t{%2, %0|%0, %2}"
11921 [(set_attr "type" "ishift")
11922 (set_attr "mode" "HI")])
11924 (define_expand "ashrqi3"
11925 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11926 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11927 (match_operand:QI 2 "nonmemory_operand" "")))
11928 (clobber (reg:CC FLAGS_REG))]
11929 "TARGET_QIMODE_MATH"
11930 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11932 (define_insn "*ashrqi3_1_one_bit"
11933 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11934 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11935 (match_operand:QI 2 "const1_operand" "")))
11936 (clobber (reg:CC FLAGS_REG))]
11937 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11938 && (TARGET_SHIFT1 || optimize_size)"
11940 [(set_attr "type" "ishift")
11941 (set (attr "length")
11942 (if_then_else (match_operand 0 "register_operand" "")
11944 (const_string "*")))])
11946 (define_insn "*ashrqi3_1_one_bit_slp"
11947 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11948 (ashiftrt:QI (match_dup 0)
11949 (match_operand:QI 1 "const1_operand" "")))
11950 (clobber (reg:CC FLAGS_REG))]
11951 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11952 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11953 && (TARGET_SHIFT1 || optimize_size)"
11955 [(set_attr "type" "ishift1")
11956 (set (attr "length")
11957 (if_then_else (match_operand 0 "register_operand" "")
11959 (const_string "*")))])
11961 (define_insn "*ashrqi3_1"
11962 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11963 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11964 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11965 (clobber (reg:CC FLAGS_REG))]
11966 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11968 sar{b}\t{%2, %0|%0, %2}
11969 sar{b}\t{%b2, %0|%0, %b2}"
11970 [(set_attr "type" "ishift")
11971 (set_attr "mode" "QI")])
11973 (define_insn "*ashrqi3_1_slp"
11974 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11975 (ashiftrt:QI (match_dup 0)
11976 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11977 (clobber (reg:CC FLAGS_REG))]
11978 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11979 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11981 sar{b}\t{%1, %0|%0, %1}
11982 sar{b}\t{%b1, %0|%0, %b1}"
11983 [(set_attr "type" "ishift1")
11984 (set_attr "mode" "QI")])
11986 ;; This pattern can't accept a variable shift count, since shifts by
11987 ;; zero don't affect the flags. We assume that shifts by constant
11988 ;; zero are optimized away.
11989 (define_insn "*ashrqi3_one_bit_cmp"
11990 [(set (reg FLAGS_REG)
11992 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11993 (match_operand:QI 2 "const1_operand" "I"))
11995 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11996 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11997 "ix86_match_ccmode (insn, CCGOCmode)
11998 && (TARGET_SHIFT1 || optimize_size)
11999 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12001 [(set_attr "type" "ishift")
12002 (set (attr "length")
12003 (if_then_else (match_operand 0 "register_operand" "")
12005 (const_string "*")))])
12007 (define_insn "*ashrqi3_one_bit_cconly"
12008 [(set (reg FLAGS_REG)
12010 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12011 (match_operand:QI 2 "const1_operand" "I"))
12013 (clobber (match_scratch:QI 0 "=q"))]
12014 "ix86_match_ccmode (insn, CCGOCmode)
12015 && (TARGET_SHIFT1 || optimize_size)
12016 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12018 [(set_attr "type" "ishift")
12019 (set_attr "length" "2")])
12021 ;; This pattern can't accept a variable shift count, since shifts by
12022 ;; zero don't affect the flags. We assume that shifts by constant
12023 ;; zero are optimized away.
12024 (define_insn "*ashrqi3_cmp"
12025 [(set (reg FLAGS_REG)
12027 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12028 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12030 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12031 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12032 "ix86_match_ccmode (insn, CCGOCmode)
12033 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12035 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12036 "sar{b}\t{%2, %0|%0, %2}"
12037 [(set_attr "type" "ishift")
12038 (set_attr "mode" "QI")])
12040 (define_insn "*ashrqi3_cconly"
12041 [(set (reg FLAGS_REG)
12043 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12044 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12046 (clobber (match_scratch:QI 0 "=q"))]
12047 "ix86_match_ccmode (insn, CCGOCmode)
12048 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12050 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12051 "sar{b}\t{%2, %0|%0, %2}"
12052 [(set_attr "type" "ishift")
12053 (set_attr "mode" "QI")])
12056 ;; Logical shift instructions
12058 ;; See comment above `ashldi3' about how this works.
12060 (define_expand "lshrti3"
12061 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12062 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12063 (match_operand:QI 2 "nonmemory_operand" "")))
12064 (clobber (reg:CC FLAGS_REG))])]
12067 if (! immediate_operand (operands[2], QImode))
12069 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12072 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12076 (define_insn "lshrti3_1"
12077 [(set (match_operand:TI 0 "register_operand" "=r")
12078 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12079 (match_operand:QI 2 "register_operand" "c")))
12080 (clobber (match_scratch:DI 3 "=&r"))
12081 (clobber (reg:CC FLAGS_REG))]
12084 [(set_attr "type" "multi")])
12086 (define_insn "*lshrti3_2"
12087 [(set (match_operand:TI 0 "register_operand" "=r")
12088 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12089 (match_operand:QI 2 "immediate_operand" "O")))
12090 (clobber (reg:CC FLAGS_REG))]
12093 [(set_attr "type" "multi")])
12096 [(set (match_operand:TI 0 "register_operand" "")
12097 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12098 (match_operand:QI 2 "register_operand" "")))
12099 (clobber (match_scratch:DI 3 ""))
12100 (clobber (reg:CC FLAGS_REG))]
12101 "TARGET_64BIT && reload_completed"
12103 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12106 [(set (match_operand:TI 0 "register_operand" "")
12107 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12108 (match_operand:QI 2 "immediate_operand" "")))
12109 (clobber (reg:CC FLAGS_REG))]
12110 "TARGET_64BIT && reload_completed"
12112 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12114 (define_expand "lshrdi3"
12115 [(set (match_operand:DI 0 "shiftdi_operand" "")
12116 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12117 (match_operand:QI 2 "nonmemory_operand" "")))]
12119 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12121 (define_insn "*lshrdi3_1_one_bit_rex64"
12122 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12123 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12124 (match_operand:QI 2 "const1_operand" "")))
12125 (clobber (reg:CC FLAGS_REG))]
12126 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12127 && (TARGET_SHIFT1 || optimize_size)"
12129 [(set_attr "type" "ishift")
12130 (set (attr "length")
12131 (if_then_else (match_operand:DI 0 "register_operand" "")
12133 (const_string "*")))])
12135 (define_insn "*lshrdi3_1_rex64"
12136 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12137 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12138 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12139 (clobber (reg:CC FLAGS_REG))]
12140 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12142 shr{q}\t{%2, %0|%0, %2}
12143 shr{q}\t{%b2, %0|%0, %b2}"
12144 [(set_attr "type" "ishift")
12145 (set_attr "mode" "DI")])
12147 ;; This pattern can't accept a variable shift count, since shifts by
12148 ;; zero don't affect the flags. We assume that shifts by constant
12149 ;; zero are optimized away.
12150 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12151 [(set (reg FLAGS_REG)
12153 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12154 (match_operand:QI 2 "const1_operand" ""))
12156 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12157 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12158 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12159 && (TARGET_SHIFT1 || optimize_size)
12160 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12162 [(set_attr "type" "ishift")
12163 (set (attr "length")
12164 (if_then_else (match_operand:DI 0 "register_operand" "")
12166 (const_string "*")))])
12168 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12169 [(set (reg FLAGS_REG)
12171 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12172 (match_operand:QI 2 "const1_operand" ""))
12174 (clobber (match_scratch:DI 0 "=r"))]
12175 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12176 && (TARGET_SHIFT1 || optimize_size)
12177 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12179 [(set_attr "type" "ishift")
12180 (set_attr "length" "2")])
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 "*lshrdi3_cmp_rex64"
12186 [(set (reg FLAGS_REG)
12188 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12189 (match_operand:QI 2 "const_int_operand" "e"))
12191 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12192 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12193 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12194 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12196 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12197 "shr{q}\t{%2, %0|%0, %2}"
12198 [(set_attr "type" "ishift")
12199 (set_attr "mode" "DI")])
12201 (define_insn "*lshrdi3_cconly_rex64"
12202 [(set (reg FLAGS_REG)
12204 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12205 (match_operand:QI 2 "const_int_operand" "e"))
12207 (clobber (match_scratch:DI 0 "=r"))]
12208 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12209 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12211 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12212 "shr{q}\t{%2, %0|%0, %2}"
12213 [(set_attr "type" "ishift")
12214 (set_attr "mode" "DI")])
12216 (define_insn "*lshrdi3_1"
12217 [(set (match_operand:DI 0 "register_operand" "=r")
12218 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12219 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12220 (clobber (reg:CC FLAGS_REG))]
12223 [(set_attr "type" "multi")])
12225 ;; By default we don't ask for a scratch register, because when DImode
12226 ;; values are manipulated, registers are already at a premium. But if
12227 ;; we have one handy, we won't turn it away.
12229 [(match_scratch:SI 3 "r")
12230 (parallel [(set (match_operand:DI 0 "register_operand" "")
12231 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12232 (match_operand:QI 2 "nonmemory_operand" "")))
12233 (clobber (reg:CC FLAGS_REG))])
12235 "!TARGET_64BIT && TARGET_CMOVE"
12237 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12240 [(set (match_operand:DI 0 "register_operand" "")
12241 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12242 (match_operand:QI 2 "nonmemory_operand" "")))
12243 (clobber (reg:CC FLAGS_REG))]
12244 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12245 ? flow2_completed : reload_completed)"
12247 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12249 (define_expand "lshrsi3"
12250 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12251 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12252 (match_operand:QI 2 "nonmemory_operand" "")))
12253 (clobber (reg:CC FLAGS_REG))]
12255 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12257 (define_insn "*lshrsi3_1_one_bit"
12258 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12259 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12260 (match_operand:QI 2 "const1_operand" "")))
12261 (clobber (reg:CC FLAGS_REG))]
12262 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12263 && (TARGET_SHIFT1 || optimize_size)"
12265 [(set_attr "type" "ishift")
12266 (set (attr "length")
12267 (if_then_else (match_operand:SI 0 "register_operand" "")
12269 (const_string "*")))])
12271 (define_insn "*lshrsi3_1_one_bit_zext"
12272 [(set (match_operand:DI 0 "register_operand" "=r")
12273 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12274 (match_operand:QI 2 "const1_operand" "")))
12275 (clobber (reg:CC FLAGS_REG))]
12276 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12277 && (TARGET_SHIFT1 || optimize_size)"
12279 [(set_attr "type" "ishift")
12280 (set_attr "length" "2")])
12282 (define_insn "*lshrsi3_1"
12283 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12284 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12285 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12286 (clobber (reg:CC FLAGS_REG))]
12287 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12289 shr{l}\t{%2, %0|%0, %2}
12290 shr{l}\t{%b2, %0|%0, %b2}"
12291 [(set_attr "type" "ishift")
12292 (set_attr "mode" "SI")])
12294 (define_insn "*lshrsi3_1_zext"
12295 [(set (match_operand:DI 0 "register_operand" "=r,r")
12297 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12298 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12299 (clobber (reg:CC FLAGS_REG))]
12300 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12302 shr{l}\t{%2, %k0|%k0, %2}
12303 shr{l}\t{%b2, %k0|%k0, %b2}"
12304 [(set_attr "type" "ishift")
12305 (set_attr "mode" "SI")])
12307 ;; This pattern can't accept a variable shift count, since shifts by
12308 ;; zero don't affect the flags. We assume that shifts by constant
12309 ;; zero are optimized away.
12310 (define_insn "*lshrsi3_one_bit_cmp"
12311 [(set (reg FLAGS_REG)
12313 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12314 (match_operand:QI 2 "const1_operand" ""))
12316 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12317 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12318 "ix86_match_ccmode (insn, CCGOCmode)
12319 && (TARGET_SHIFT1 || optimize_size)
12320 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12322 [(set_attr "type" "ishift")
12323 (set (attr "length")
12324 (if_then_else (match_operand:SI 0 "register_operand" "")
12326 (const_string "*")))])
12328 (define_insn "*lshrsi3_one_bit_cconly"
12329 [(set (reg FLAGS_REG)
12331 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12332 (match_operand:QI 2 "const1_operand" ""))
12334 (clobber (match_scratch:SI 0 "=r"))]
12335 "ix86_match_ccmode (insn, CCGOCmode)
12336 && (TARGET_SHIFT1 || optimize_size)
12337 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12339 [(set_attr "type" "ishift")
12340 (set_attr "length" "2")])
12342 (define_insn "*lshrsi3_cmp_one_bit_zext"
12343 [(set (reg FLAGS_REG)
12345 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12346 (match_operand:QI 2 "const1_operand" ""))
12348 (set (match_operand:DI 0 "register_operand" "=r")
12349 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12350 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12351 && (TARGET_SHIFT1 || optimize_size)
12352 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12354 [(set_attr "type" "ishift")
12355 (set_attr "length" "2")])
12357 ;; This pattern can't accept a variable shift count, since shifts by
12358 ;; zero don't affect the flags. We assume that shifts by constant
12359 ;; zero are optimized away.
12360 (define_insn "*lshrsi3_cmp"
12361 [(set (reg FLAGS_REG)
12363 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12364 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12366 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12367 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12368 "ix86_match_ccmode (insn, CCGOCmode)
12369 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12371 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12372 "shr{l}\t{%2, %0|%0, %2}"
12373 [(set_attr "type" "ishift")
12374 (set_attr "mode" "SI")])
12376 (define_insn "*lshrsi3_cconly"
12377 [(set (reg FLAGS_REG)
12379 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12380 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12382 (clobber (match_scratch:SI 0 "=r"))]
12383 "ix86_match_ccmode (insn, CCGOCmode)
12384 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12386 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12387 "shr{l}\t{%2, %0|%0, %2}"
12388 [(set_attr "type" "ishift")
12389 (set_attr "mode" "SI")])
12391 (define_insn "*lshrsi3_cmp_zext"
12392 [(set (reg FLAGS_REG)
12394 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12395 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12397 (set (match_operand:DI 0 "register_operand" "=r")
12398 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12399 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12400 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12402 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12403 "shr{l}\t{%2, %k0|%k0, %2}"
12404 [(set_attr "type" "ishift")
12405 (set_attr "mode" "SI")])
12407 (define_expand "lshrhi3"
12408 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12409 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12410 (match_operand:QI 2 "nonmemory_operand" "")))
12411 (clobber (reg:CC FLAGS_REG))]
12412 "TARGET_HIMODE_MATH"
12413 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12415 (define_insn "*lshrhi3_1_one_bit"
12416 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12417 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12418 (match_operand:QI 2 "const1_operand" "")))
12419 (clobber (reg:CC FLAGS_REG))]
12420 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12421 && (TARGET_SHIFT1 || optimize_size)"
12423 [(set_attr "type" "ishift")
12424 (set (attr "length")
12425 (if_then_else (match_operand 0 "register_operand" "")
12427 (const_string "*")))])
12429 (define_insn "*lshrhi3_1"
12430 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12431 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12432 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12433 (clobber (reg:CC FLAGS_REG))]
12434 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12436 shr{w}\t{%2, %0|%0, %2}
12437 shr{w}\t{%b2, %0|%0, %b2}"
12438 [(set_attr "type" "ishift")
12439 (set_attr "mode" "HI")])
12441 ;; This pattern can't accept a variable shift count, since shifts by
12442 ;; zero don't affect the flags. We assume that shifts by constant
12443 ;; zero are optimized away.
12444 (define_insn "*lshrhi3_one_bit_cmp"
12445 [(set (reg FLAGS_REG)
12447 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12448 (match_operand:QI 2 "const1_operand" ""))
12450 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12451 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12452 "ix86_match_ccmode (insn, CCGOCmode)
12453 && (TARGET_SHIFT1 || optimize_size)
12454 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12456 [(set_attr "type" "ishift")
12457 (set (attr "length")
12458 (if_then_else (match_operand:SI 0 "register_operand" "")
12460 (const_string "*")))])
12462 (define_insn "*lshrhi3_one_bit_cconly"
12463 [(set (reg FLAGS_REG)
12465 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12466 (match_operand:QI 2 "const1_operand" ""))
12468 (clobber (match_scratch:HI 0 "=r"))]
12469 "ix86_match_ccmode (insn, CCGOCmode)
12470 && (TARGET_SHIFT1 || optimize_size)
12471 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12473 [(set_attr "type" "ishift")
12474 (set_attr "length" "2")])
12476 ;; This pattern can't accept a variable shift count, since shifts by
12477 ;; zero don't affect the flags. We assume that shifts by constant
12478 ;; zero are optimized away.
12479 (define_insn "*lshrhi3_cmp"
12480 [(set (reg FLAGS_REG)
12482 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12483 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12485 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12486 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12487 "ix86_match_ccmode (insn, CCGOCmode)
12488 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12490 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12491 "shr{w}\t{%2, %0|%0, %2}"
12492 [(set_attr "type" "ishift")
12493 (set_attr "mode" "HI")])
12495 (define_insn "*lshrhi3_cconly"
12496 [(set (reg FLAGS_REG)
12498 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12499 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12501 (clobber (match_scratch:HI 0 "=r"))]
12502 "ix86_match_ccmode (insn, CCGOCmode)
12503 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12505 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12506 "shr{w}\t{%2, %0|%0, %2}"
12507 [(set_attr "type" "ishift")
12508 (set_attr "mode" "HI")])
12510 (define_expand "lshrqi3"
12511 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12512 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12513 (match_operand:QI 2 "nonmemory_operand" "")))
12514 (clobber (reg:CC FLAGS_REG))]
12515 "TARGET_QIMODE_MATH"
12516 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12518 (define_insn "*lshrqi3_1_one_bit"
12519 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12520 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12521 (match_operand:QI 2 "const1_operand" "")))
12522 (clobber (reg:CC FLAGS_REG))]
12523 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12524 && (TARGET_SHIFT1 || optimize_size)"
12526 [(set_attr "type" "ishift")
12527 (set (attr "length")
12528 (if_then_else (match_operand 0 "register_operand" "")
12530 (const_string "*")))])
12532 (define_insn "*lshrqi3_1_one_bit_slp"
12533 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12534 (lshiftrt:QI (match_dup 0)
12535 (match_operand:QI 1 "const1_operand" "")))
12536 (clobber (reg:CC FLAGS_REG))]
12537 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12538 && (TARGET_SHIFT1 || optimize_size)"
12540 [(set_attr "type" "ishift1")
12541 (set (attr "length")
12542 (if_then_else (match_operand 0 "register_operand" "")
12544 (const_string "*")))])
12546 (define_insn "*lshrqi3_1"
12547 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12548 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12549 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12550 (clobber (reg:CC FLAGS_REG))]
12551 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12553 shr{b}\t{%2, %0|%0, %2}
12554 shr{b}\t{%b2, %0|%0, %b2}"
12555 [(set_attr "type" "ishift")
12556 (set_attr "mode" "QI")])
12558 (define_insn "*lshrqi3_1_slp"
12559 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12560 (lshiftrt:QI (match_dup 0)
12561 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12562 (clobber (reg:CC FLAGS_REG))]
12563 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12564 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12566 shr{b}\t{%1, %0|%0, %1}
12567 shr{b}\t{%b1, %0|%0, %b1}"
12568 [(set_attr "type" "ishift1")
12569 (set_attr "mode" "QI")])
12571 ;; This pattern can't accept a variable shift count, since shifts by
12572 ;; zero don't affect the flags. We assume that shifts by constant
12573 ;; zero are optimized away.
12574 (define_insn "*lshrqi2_one_bit_cmp"
12575 [(set (reg FLAGS_REG)
12577 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12578 (match_operand:QI 2 "const1_operand" ""))
12580 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12581 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12582 "ix86_match_ccmode (insn, CCGOCmode)
12583 && (TARGET_SHIFT1 || optimize_size)
12584 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12586 [(set_attr "type" "ishift")
12587 (set (attr "length")
12588 (if_then_else (match_operand:SI 0 "register_operand" "")
12590 (const_string "*")))])
12592 (define_insn "*lshrqi2_one_bit_cconly"
12593 [(set (reg FLAGS_REG)
12595 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12596 (match_operand:QI 2 "const1_operand" ""))
12598 (clobber (match_scratch:QI 0 "=q"))]
12599 "ix86_match_ccmode (insn, CCGOCmode)
12600 && (TARGET_SHIFT1 || optimize_size)
12601 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12603 [(set_attr "type" "ishift")
12604 (set_attr "length" "2")])
12606 ;; This pattern can't accept a variable shift count, since shifts by
12607 ;; zero don't affect the flags. We assume that shifts by constant
12608 ;; zero are optimized away.
12609 (define_insn "*lshrqi2_cmp"
12610 [(set (reg FLAGS_REG)
12612 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12613 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12615 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12616 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12617 "ix86_match_ccmode (insn, CCGOCmode)
12618 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12620 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12621 "shr{b}\t{%2, %0|%0, %2}"
12622 [(set_attr "type" "ishift")
12623 (set_attr "mode" "QI")])
12625 (define_insn "*lshrqi2_cconly"
12626 [(set (reg FLAGS_REG)
12628 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12629 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12631 (clobber (match_scratch:QI 0 "=q"))]
12632 "ix86_match_ccmode (insn, CCGOCmode)
12633 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12635 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12636 "shr{b}\t{%2, %0|%0, %2}"
12637 [(set_attr "type" "ishift")
12638 (set_attr "mode" "QI")])
12640 ;; Rotate instructions
12642 (define_expand "rotldi3"
12643 [(set (match_operand:DI 0 "shiftdi_operand" "")
12644 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12645 (match_operand:QI 2 "nonmemory_operand" "")))
12646 (clobber (reg:CC FLAGS_REG))]
12651 ix86_expand_binary_operator (ROTATE, DImode, operands);
12654 if (!const_1_to_31_operand (operands[2], VOIDmode))
12656 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12660 ;; Implement rotation using two double-precision shift instructions
12661 ;; and a scratch register.
12662 (define_insn_and_split "ix86_rotldi3"
12663 [(set (match_operand:DI 0 "register_operand" "=r")
12664 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12665 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12666 (clobber (reg:CC FLAGS_REG))
12667 (clobber (match_scratch:SI 3 "=&r"))]
12670 "&& reload_completed"
12671 [(set (match_dup 3) (match_dup 4))
12673 [(set (match_dup 4)
12674 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12675 (lshiftrt:SI (match_dup 5)
12676 (minus:QI (const_int 32) (match_dup 2)))))
12677 (clobber (reg:CC FLAGS_REG))])
12679 [(set (match_dup 5)
12680 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12681 (lshiftrt:SI (match_dup 3)
12682 (minus:QI (const_int 32) (match_dup 2)))))
12683 (clobber (reg:CC FLAGS_REG))])]
12684 "split_di (operands, 1, operands + 4, operands + 5);")
12686 (define_insn "*rotlsi3_1_one_bit_rex64"
12687 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12688 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12689 (match_operand:QI 2 "const1_operand" "")))
12690 (clobber (reg:CC FLAGS_REG))]
12691 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12692 && (TARGET_SHIFT1 || optimize_size)"
12694 [(set_attr "type" "rotate")
12695 (set (attr "length")
12696 (if_then_else (match_operand:DI 0 "register_operand" "")
12698 (const_string "*")))])
12700 (define_insn "*rotldi3_1_rex64"
12701 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12702 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12703 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12704 (clobber (reg:CC FLAGS_REG))]
12705 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12707 rol{q}\t{%2, %0|%0, %2}
12708 rol{q}\t{%b2, %0|%0, %b2}"
12709 [(set_attr "type" "rotate")
12710 (set_attr "mode" "DI")])
12712 (define_expand "rotlsi3"
12713 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12714 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12715 (match_operand:QI 2 "nonmemory_operand" "")))
12716 (clobber (reg:CC FLAGS_REG))]
12718 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12720 (define_insn "*rotlsi3_1_one_bit"
12721 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12722 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12723 (match_operand:QI 2 "const1_operand" "")))
12724 (clobber (reg:CC FLAGS_REG))]
12725 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12726 && (TARGET_SHIFT1 || optimize_size)"
12728 [(set_attr "type" "rotate")
12729 (set (attr "length")
12730 (if_then_else (match_operand:SI 0 "register_operand" "")
12732 (const_string "*")))])
12734 (define_insn "*rotlsi3_1_one_bit_zext"
12735 [(set (match_operand:DI 0 "register_operand" "=r")
12737 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12738 (match_operand:QI 2 "const1_operand" ""))))
12739 (clobber (reg:CC FLAGS_REG))]
12740 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12741 && (TARGET_SHIFT1 || optimize_size)"
12743 [(set_attr "type" "rotate")
12744 (set_attr "length" "2")])
12746 (define_insn "*rotlsi3_1"
12747 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12748 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12749 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12750 (clobber (reg:CC FLAGS_REG))]
12751 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12753 rol{l}\t{%2, %0|%0, %2}
12754 rol{l}\t{%b2, %0|%0, %b2}"
12755 [(set_attr "type" "rotate")
12756 (set_attr "mode" "SI")])
12758 (define_insn "*rotlsi3_1_zext"
12759 [(set (match_operand:DI 0 "register_operand" "=r,r")
12761 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12762 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12763 (clobber (reg:CC FLAGS_REG))]
12764 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12766 rol{l}\t{%2, %k0|%k0, %2}
12767 rol{l}\t{%b2, %k0|%k0, %b2}"
12768 [(set_attr "type" "rotate")
12769 (set_attr "mode" "SI")])
12771 (define_expand "rotlhi3"
12772 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12773 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12774 (match_operand:QI 2 "nonmemory_operand" "")))
12775 (clobber (reg:CC FLAGS_REG))]
12776 "TARGET_HIMODE_MATH"
12777 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12779 (define_insn "*rotlhi3_1_one_bit"
12780 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12781 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12782 (match_operand:QI 2 "const1_operand" "")))
12783 (clobber (reg:CC FLAGS_REG))]
12784 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12785 && (TARGET_SHIFT1 || optimize_size)"
12787 [(set_attr "type" "rotate")
12788 (set (attr "length")
12789 (if_then_else (match_operand 0 "register_operand" "")
12791 (const_string "*")))])
12793 (define_insn "*rotlhi3_1"
12794 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12795 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12796 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12797 (clobber (reg:CC FLAGS_REG))]
12798 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12800 rol{w}\t{%2, %0|%0, %2}
12801 rol{w}\t{%b2, %0|%0, %b2}"
12802 [(set_attr "type" "rotate")
12803 (set_attr "mode" "HI")])
12805 (define_expand "rotlqi3"
12806 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12807 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12808 (match_operand:QI 2 "nonmemory_operand" "")))
12809 (clobber (reg:CC FLAGS_REG))]
12810 "TARGET_QIMODE_MATH"
12811 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12813 (define_insn "*rotlqi3_1_one_bit_slp"
12814 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12815 (rotate:QI (match_dup 0)
12816 (match_operand:QI 1 "const1_operand" "")))
12817 (clobber (reg:CC FLAGS_REG))]
12818 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12819 && (TARGET_SHIFT1 || optimize_size)"
12821 [(set_attr "type" "rotate1")
12822 (set (attr "length")
12823 (if_then_else (match_operand 0 "register_operand" "")
12825 (const_string "*")))])
12827 (define_insn "*rotlqi3_1_one_bit"
12828 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12829 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12830 (match_operand:QI 2 "const1_operand" "")))
12831 (clobber (reg:CC FLAGS_REG))]
12832 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12833 && (TARGET_SHIFT1 || optimize_size)"
12835 [(set_attr "type" "rotate")
12836 (set (attr "length")
12837 (if_then_else (match_operand 0 "register_operand" "")
12839 (const_string "*")))])
12841 (define_insn "*rotlqi3_1_slp"
12842 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12843 (rotate:QI (match_dup 0)
12844 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12845 (clobber (reg:CC FLAGS_REG))]
12846 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12847 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12849 rol{b}\t{%1, %0|%0, %1}
12850 rol{b}\t{%b1, %0|%0, %b1}"
12851 [(set_attr "type" "rotate1")
12852 (set_attr "mode" "QI")])
12854 (define_insn "*rotlqi3_1"
12855 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12856 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12857 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12858 (clobber (reg:CC FLAGS_REG))]
12859 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12861 rol{b}\t{%2, %0|%0, %2}
12862 rol{b}\t{%b2, %0|%0, %b2}"
12863 [(set_attr "type" "rotate")
12864 (set_attr "mode" "QI")])
12866 (define_expand "rotrdi3"
12867 [(set (match_operand:DI 0 "shiftdi_operand" "")
12868 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12869 (match_operand:QI 2 "nonmemory_operand" "")))
12870 (clobber (reg:CC FLAGS_REG))]
12875 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12878 if (!const_1_to_31_operand (operands[2], VOIDmode))
12880 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12884 ;; Implement rotation using two double-precision shift instructions
12885 ;; and a scratch register.
12886 (define_insn_and_split "ix86_rotrdi3"
12887 [(set (match_operand:DI 0 "register_operand" "=r")
12888 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12889 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12890 (clobber (reg:CC FLAGS_REG))
12891 (clobber (match_scratch:SI 3 "=&r"))]
12894 "&& reload_completed"
12895 [(set (match_dup 3) (match_dup 4))
12897 [(set (match_dup 4)
12898 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12899 (ashift:SI (match_dup 5)
12900 (minus:QI (const_int 32) (match_dup 2)))))
12901 (clobber (reg:CC FLAGS_REG))])
12903 [(set (match_dup 5)
12904 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12905 (ashift:SI (match_dup 3)
12906 (minus:QI (const_int 32) (match_dup 2)))))
12907 (clobber (reg:CC FLAGS_REG))])]
12908 "split_di (operands, 1, operands + 4, operands + 5);")
12910 (define_insn "*rotrdi3_1_one_bit_rex64"
12911 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12912 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12913 (match_operand:QI 2 "const1_operand" "")))
12914 (clobber (reg:CC FLAGS_REG))]
12915 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12916 && (TARGET_SHIFT1 || optimize_size)"
12918 [(set_attr "type" "rotate")
12919 (set (attr "length")
12920 (if_then_else (match_operand:DI 0 "register_operand" "")
12922 (const_string "*")))])
12924 (define_insn "*rotrdi3_1_rex64"
12925 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12926 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12927 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12928 (clobber (reg:CC FLAGS_REG))]
12929 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12931 ror{q}\t{%2, %0|%0, %2}
12932 ror{q}\t{%b2, %0|%0, %b2}"
12933 [(set_attr "type" "rotate")
12934 (set_attr "mode" "DI")])
12936 (define_expand "rotrsi3"
12937 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12938 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12939 (match_operand:QI 2 "nonmemory_operand" "")))
12940 (clobber (reg:CC FLAGS_REG))]
12942 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12944 (define_insn "*rotrsi3_1_one_bit"
12945 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12946 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12947 (match_operand:QI 2 "const1_operand" "")))
12948 (clobber (reg:CC FLAGS_REG))]
12949 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12950 && (TARGET_SHIFT1 || optimize_size)"
12952 [(set_attr "type" "rotate")
12953 (set (attr "length")
12954 (if_then_else (match_operand:SI 0 "register_operand" "")
12956 (const_string "*")))])
12958 (define_insn "*rotrsi3_1_one_bit_zext"
12959 [(set (match_operand:DI 0 "register_operand" "=r")
12961 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12962 (match_operand:QI 2 "const1_operand" ""))))
12963 (clobber (reg:CC FLAGS_REG))]
12964 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12965 && (TARGET_SHIFT1 || optimize_size)"
12967 [(set_attr "type" "rotate")
12968 (set (attr "length")
12969 (if_then_else (match_operand:SI 0 "register_operand" "")
12971 (const_string "*")))])
12973 (define_insn "*rotrsi3_1"
12974 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12975 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12976 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12977 (clobber (reg:CC FLAGS_REG))]
12978 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12980 ror{l}\t{%2, %0|%0, %2}
12981 ror{l}\t{%b2, %0|%0, %b2}"
12982 [(set_attr "type" "rotate")
12983 (set_attr "mode" "SI")])
12985 (define_insn "*rotrsi3_1_zext"
12986 [(set (match_operand:DI 0 "register_operand" "=r,r")
12988 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12989 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12990 (clobber (reg:CC FLAGS_REG))]
12991 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12993 ror{l}\t{%2, %k0|%k0, %2}
12994 ror{l}\t{%b2, %k0|%k0, %b2}"
12995 [(set_attr "type" "rotate")
12996 (set_attr "mode" "SI")])
12998 (define_expand "rotrhi3"
12999 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13000 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13001 (match_operand:QI 2 "nonmemory_operand" "")))
13002 (clobber (reg:CC FLAGS_REG))]
13003 "TARGET_HIMODE_MATH"
13004 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13006 (define_insn "*rotrhi3_one_bit"
13007 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13008 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13009 (match_operand:QI 2 "const1_operand" "")))
13010 (clobber (reg:CC FLAGS_REG))]
13011 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13012 && (TARGET_SHIFT1 || optimize_size)"
13014 [(set_attr "type" "rotate")
13015 (set (attr "length")
13016 (if_then_else (match_operand 0 "register_operand" "")
13018 (const_string "*")))])
13020 (define_insn "*rotrhi3"
13021 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13022 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13023 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13024 (clobber (reg:CC FLAGS_REG))]
13025 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13027 ror{w}\t{%2, %0|%0, %2}
13028 ror{w}\t{%b2, %0|%0, %b2}"
13029 [(set_attr "type" "rotate")
13030 (set_attr "mode" "HI")])
13032 (define_expand "rotrqi3"
13033 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13034 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13035 (match_operand:QI 2 "nonmemory_operand" "")))
13036 (clobber (reg:CC FLAGS_REG))]
13037 "TARGET_QIMODE_MATH"
13038 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13040 (define_insn "*rotrqi3_1_one_bit"
13041 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13042 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13043 (match_operand:QI 2 "const1_operand" "")))
13044 (clobber (reg:CC FLAGS_REG))]
13045 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13046 && (TARGET_SHIFT1 || optimize_size)"
13048 [(set_attr "type" "rotate")
13049 (set (attr "length")
13050 (if_then_else (match_operand 0 "register_operand" "")
13052 (const_string "*")))])
13054 (define_insn "*rotrqi3_1_one_bit_slp"
13055 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13056 (rotatert:QI (match_dup 0)
13057 (match_operand:QI 1 "const1_operand" "")))
13058 (clobber (reg:CC FLAGS_REG))]
13059 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13060 && (TARGET_SHIFT1 || optimize_size)"
13062 [(set_attr "type" "rotate1")
13063 (set (attr "length")
13064 (if_then_else (match_operand 0 "register_operand" "")
13066 (const_string "*")))])
13068 (define_insn "*rotrqi3_1"
13069 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13070 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13071 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13072 (clobber (reg:CC FLAGS_REG))]
13073 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13075 ror{b}\t{%2, %0|%0, %2}
13076 ror{b}\t{%b2, %0|%0, %b2}"
13077 [(set_attr "type" "rotate")
13078 (set_attr "mode" "QI")])
13080 (define_insn "*rotrqi3_1_slp"
13081 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13082 (rotatert:QI (match_dup 0)
13083 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13084 (clobber (reg:CC FLAGS_REG))]
13085 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13086 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13088 ror{b}\t{%1, %0|%0, %1}
13089 ror{b}\t{%b1, %0|%0, %b1}"
13090 [(set_attr "type" "rotate1")
13091 (set_attr "mode" "QI")])
13093 ;; Bit set / bit test instructions
13095 (define_expand "extv"
13096 [(set (match_operand:SI 0 "register_operand" "")
13097 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13098 (match_operand:SI 2 "const8_operand" "")
13099 (match_operand:SI 3 "const8_operand" "")))]
13102 /* Handle extractions from %ah et al. */
13103 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13106 /* From mips.md: extract_bit_field doesn't verify that our source
13107 matches the predicate, so check it again here. */
13108 if (! ext_register_operand (operands[1], VOIDmode))
13112 (define_expand "extzv"
13113 [(set (match_operand:SI 0 "register_operand" "")
13114 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13115 (match_operand:SI 2 "const8_operand" "")
13116 (match_operand:SI 3 "const8_operand" "")))]
13119 /* Handle extractions from %ah et al. */
13120 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13123 /* From mips.md: extract_bit_field doesn't verify that our source
13124 matches the predicate, so check it again here. */
13125 if (! ext_register_operand (operands[1], VOIDmode))
13129 (define_expand "insv"
13130 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13131 (match_operand 1 "const8_operand" "")
13132 (match_operand 2 "const8_operand" ""))
13133 (match_operand 3 "register_operand" ""))]
13136 /* Handle insertions to %ah et al. */
13137 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13140 /* From mips.md: insert_bit_field doesn't verify that our source
13141 matches the predicate, so check it again here. */
13142 if (! ext_register_operand (operands[0], VOIDmode))
13146 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13148 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13153 ;; %%% bts, btr, btc, bt.
13154 ;; In general these instructions are *slow* when applied to memory,
13155 ;; since they enforce atomic operation. When applied to registers,
13156 ;; it depends on the cpu implementation. They're never faster than
13157 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13158 ;; no point. But in 64-bit, we can't hold the relevant immediates
13159 ;; within the instruction itself, so operating on bits in the high
13160 ;; 32-bits of a register becomes easier.
13162 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13163 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13164 ;; negdf respectively, so they can never be disabled entirely.
13166 (define_insn "*btsq"
13167 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13169 (match_operand:DI 1 "const_0_to_63_operand" ""))
13171 (clobber (reg:CC FLAGS_REG))]
13172 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13174 [(set_attr "type" "alu1")])
13176 (define_insn "*btrq"
13177 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13179 (match_operand:DI 1 "const_0_to_63_operand" ""))
13181 (clobber (reg:CC FLAGS_REG))]
13182 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13184 [(set_attr "type" "alu1")])
13186 (define_insn "*btcq"
13187 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13189 (match_operand:DI 1 "const_0_to_63_operand" ""))
13190 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13191 (clobber (reg:CC FLAGS_REG))]
13192 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13194 [(set_attr "type" "alu1")])
13196 ;; Allow Nocona to avoid these instructions if a register is available.
13199 [(match_scratch:DI 2 "r")
13200 (parallel [(set (zero_extract:DI
13201 (match_operand:DI 0 "register_operand" "")
13203 (match_operand:DI 1 "const_0_to_63_operand" ""))
13205 (clobber (reg:CC FLAGS_REG))])]
13206 "TARGET_64BIT && !TARGET_USE_BT"
13209 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13212 if (HOST_BITS_PER_WIDE_INT >= 64)
13213 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13214 else if (i < HOST_BITS_PER_WIDE_INT)
13215 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13217 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13219 op1 = immed_double_const (lo, hi, DImode);
13222 emit_move_insn (operands[2], op1);
13226 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13231 [(match_scratch:DI 2 "r")
13232 (parallel [(set (zero_extract:DI
13233 (match_operand:DI 0 "register_operand" "")
13235 (match_operand:DI 1 "const_0_to_63_operand" ""))
13237 (clobber (reg:CC FLAGS_REG))])]
13238 "TARGET_64BIT && !TARGET_USE_BT"
13241 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13244 if (HOST_BITS_PER_WIDE_INT >= 64)
13245 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13246 else if (i < HOST_BITS_PER_WIDE_INT)
13247 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13249 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13251 op1 = immed_double_const (~lo, ~hi, DImode);
13254 emit_move_insn (operands[2], op1);
13258 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13263 [(match_scratch:DI 2 "r")
13264 (parallel [(set (zero_extract:DI
13265 (match_operand:DI 0 "register_operand" "")
13267 (match_operand:DI 1 "const_0_to_63_operand" ""))
13268 (not:DI (zero_extract:DI
13269 (match_dup 0) (const_int 1) (match_dup 1))))
13270 (clobber (reg:CC FLAGS_REG))])]
13271 "TARGET_64BIT && !TARGET_USE_BT"
13274 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13277 if (HOST_BITS_PER_WIDE_INT >= 64)
13278 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13279 else if (i < HOST_BITS_PER_WIDE_INT)
13280 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13282 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13284 op1 = immed_double_const (lo, hi, DImode);
13287 emit_move_insn (operands[2], op1);
13291 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13295 ;; Store-flag instructions.
13297 ;; For all sCOND expanders, also expand the compare or test insn that
13298 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13300 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13301 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13302 ;; way, which can later delete the movzx if only QImode is needed.
13304 (define_expand "seq"
13305 [(set (match_operand:QI 0 "register_operand" "")
13306 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13308 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13310 (define_expand "sne"
13311 [(set (match_operand:QI 0 "register_operand" "")
13312 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13314 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13316 (define_expand "sgt"
13317 [(set (match_operand:QI 0 "register_operand" "")
13318 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13320 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13322 (define_expand "sgtu"
13323 [(set (match_operand:QI 0 "register_operand" "")
13324 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13326 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13328 (define_expand "slt"
13329 [(set (match_operand:QI 0 "register_operand" "")
13330 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13332 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13334 (define_expand "sltu"
13335 [(set (match_operand:QI 0 "register_operand" "")
13336 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13338 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13340 (define_expand "sge"
13341 [(set (match_operand:QI 0 "register_operand" "")
13342 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13344 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13346 (define_expand "sgeu"
13347 [(set (match_operand:QI 0 "register_operand" "")
13348 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13350 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13352 (define_expand "sle"
13353 [(set (match_operand:QI 0 "register_operand" "")
13354 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13356 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13358 (define_expand "sleu"
13359 [(set (match_operand:QI 0 "register_operand" "")
13360 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13362 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13364 (define_expand "sunordered"
13365 [(set (match_operand:QI 0 "register_operand" "")
13366 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13367 "TARGET_80387 || TARGET_SSE"
13368 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13370 (define_expand "sordered"
13371 [(set (match_operand:QI 0 "register_operand" "")
13372 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13374 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13376 (define_expand "suneq"
13377 [(set (match_operand:QI 0 "register_operand" "")
13378 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13379 "TARGET_80387 || TARGET_SSE"
13380 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13382 (define_expand "sunge"
13383 [(set (match_operand:QI 0 "register_operand" "")
13384 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13385 "TARGET_80387 || TARGET_SSE"
13386 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13388 (define_expand "sungt"
13389 [(set (match_operand:QI 0 "register_operand" "")
13390 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13391 "TARGET_80387 || TARGET_SSE"
13392 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13394 (define_expand "sunle"
13395 [(set (match_operand:QI 0 "register_operand" "")
13396 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13397 "TARGET_80387 || TARGET_SSE"
13398 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13400 (define_expand "sunlt"
13401 [(set (match_operand:QI 0 "register_operand" "")
13402 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13403 "TARGET_80387 || TARGET_SSE"
13404 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13406 (define_expand "sltgt"
13407 [(set (match_operand:QI 0 "register_operand" "")
13408 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13409 "TARGET_80387 || TARGET_SSE"
13410 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13412 (define_insn "*setcc_1"
13413 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13414 (match_operator:QI 1 "ix86_comparison_operator"
13415 [(reg FLAGS_REG) (const_int 0)]))]
13418 [(set_attr "type" "setcc")
13419 (set_attr "mode" "QI")])
13421 (define_insn "*setcc_2"
13422 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13423 (match_operator:QI 1 "ix86_comparison_operator"
13424 [(reg FLAGS_REG) (const_int 0)]))]
13427 [(set_attr "type" "setcc")
13428 (set_attr "mode" "QI")])
13430 ;; In general it is not safe to assume too much about CCmode registers,
13431 ;; so simplify-rtx stops when it sees a second one. Under certain
13432 ;; conditions this is safe on x86, so help combine not create
13439 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13440 (ne:QI (match_operator 1 "ix86_comparison_operator"
13441 [(reg FLAGS_REG) (const_int 0)])
13444 [(set (match_dup 0) (match_dup 1))]
13446 PUT_MODE (operands[1], QImode);
13450 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13451 (ne:QI (match_operator 1 "ix86_comparison_operator"
13452 [(reg FLAGS_REG) (const_int 0)])
13455 [(set (match_dup 0) (match_dup 1))]
13457 PUT_MODE (operands[1], QImode);
13461 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13462 (eq:QI (match_operator 1 "ix86_comparison_operator"
13463 [(reg FLAGS_REG) (const_int 0)])
13466 [(set (match_dup 0) (match_dup 1))]
13468 rtx new_op1 = copy_rtx (operands[1]);
13469 operands[1] = new_op1;
13470 PUT_MODE (new_op1, QImode);
13471 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13472 GET_MODE (XEXP (new_op1, 0))));
13474 /* Make sure that (a) the CCmode we have for the flags is strong
13475 enough for the reversed compare or (b) we have a valid FP compare. */
13476 if (! ix86_comparison_operator (new_op1, VOIDmode))
13481 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13482 (eq:QI (match_operator 1 "ix86_comparison_operator"
13483 [(reg FLAGS_REG) (const_int 0)])
13486 [(set (match_dup 0) (match_dup 1))]
13488 rtx new_op1 = copy_rtx (operands[1]);
13489 operands[1] = new_op1;
13490 PUT_MODE (new_op1, QImode);
13491 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13492 GET_MODE (XEXP (new_op1, 0))));
13494 /* Make sure that (a) the CCmode we have for the flags is strong
13495 enough for the reversed compare or (b) we have a valid FP compare. */
13496 if (! ix86_comparison_operator (new_op1, VOIDmode))
13500 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13501 ;; subsequent logical operations are used to imitate conditional moves.
13502 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13505 (define_insn "*sse_setccsf"
13506 [(set (match_operand:SF 0 "register_operand" "=x")
13507 (match_operator:SF 1 "sse_comparison_operator"
13508 [(match_operand:SF 2 "register_operand" "0")
13509 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13511 "cmp%D1ss\t{%3, %0|%0, %3}"
13512 [(set_attr "type" "ssecmp")
13513 (set_attr "mode" "SF")])
13515 (define_insn "*sse_setccdf"
13516 [(set (match_operand:DF 0 "register_operand" "=Y")
13517 (match_operator:DF 1 "sse_comparison_operator"
13518 [(match_operand:DF 2 "register_operand" "0")
13519 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13521 "cmp%D1sd\t{%3, %0|%0, %3}"
13522 [(set_attr "type" "ssecmp")
13523 (set_attr "mode" "DF")])
13525 ;; Basic conditional jump instructions.
13526 ;; We ignore the overflow flag for signed branch instructions.
13528 ;; For all bCOND expanders, also expand the compare or test insn that
13529 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13531 (define_expand "beq"
13533 (if_then_else (match_dup 1)
13534 (label_ref (match_operand 0 "" ""))
13537 "ix86_expand_branch (EQ, operands[0]); DONE;")
13539 (define_expand "bne"
13541 (if_then_else (match_dup 1)
13542 (label_ref (match_operand 0 "" ""))
13545 "ix86_expand_branch (NE, operands[0]); DONE;")
13547 (define_expand "bgt"
13549 (if_then_else (match_dup 1)
13550 (label_ref (match_operand 0 "" ""))
13553 "ix86_expand_branch (GT, operands[0]); DONE;")
13555 (define_expand "bgtu"
13557 (if_then_else (match_dup 1)
13558 (label_ref (match_operand 0 "" ""))
13561 "ix86_expand_branch (GTU, operands[0]); DONE;")
13563 (define_expand "blt"
13565 (if_then_else (match_dup 1)
13566 (label_ref (match_operand 0 "" ""))
13569 "ix86_expand_branch (LT, operands[0]); DONE;")
13571 (define_expand "bltu"
13573 (if_then_else (match_dup 1)
13574 (label_ref (match_operand 0 "" ""))
13577 "ix86_expand_branch (LTU, operands[0]); DONE;")
13579 (define_expand "bge"
13581 (if_then_else (match_dup 1)
13582 (label_ref (match_operand 0 "" ""))
13585 "ix86_expand_branch (GE, operands[0]); DONE;")
13587 (define_expand "bgeu"
13589 (if_then_else (match_dup 1)
13590 (label_ref (match_operand 0 "" ""))
13593 "ix86_expand_branch (GEU, operands[0]); DONE;")
13595 (define_expand "ble"
13597 (if_then_else (match_dup 1)
13598 (label_ref (match_operand 0 "" ""))
13601 "ix86_expand_branch (LE, operands[0]); DONE;")
13603 (define_expand "bleu"
13605 (if_then_else (match_dup 1)
13606 (label_ref (match_operand 0 "" ""))
13609 "ix86_expand_branch (LEU, operands[0]); DONE;")
13611 (define_expand "bunordered"
13613 (if_then_else (match_dup 1)
13614 (label_ref (match_operand 0 "" ""))
13616 "TARGET_80387 || TARGET_SSE_MATH"
13617 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13619 (define_expand "bordered"
13621 (if_then_else (match_dup 1)
13622 (label_ref (match_operand 0 "" ""))
13624 "TARGET_80387 || TARGET_SSE_MATH"
13625 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13627 (define_expand "buneq"
13629 (if_then_else (match_dup 1)
13630 (label_ref (match_operand 0 "" ""))
13632 "TARGET_80387 || TARGET_SSE_MATH"
13633 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13635 (define_expand "bunge"
13637 (if_then_else (match_dup 1)
13638 (label_ref (match_operand 0 "" ""))
13640 "TARGET_80387 || TARGET_SSE_MATH"
13641 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13643 (define_expand "bungt"
13645 (if_then_else (match_dup 1)
13646 (label_ref (match_operand 0 "" ""))
13648 "TARGET_80387 || TARGET_SSE_MATH"
13649 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13651 (define_expand "bunle"
13653 (if_then_else (match_dup 1)
13654 (label_ref (match_operand 0 "" ""))
13656 "TARGET_80387 || TARGET_SSE_MATH"
13657 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13659 (define_expand "bunlt"
13661 (if_then_else (match_dup 1)
13662 (label_ref (match_operand 0 "" ""))
13664 "TARGET_80387 || TARGET_SSE_MATH"
13665 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13667 (define_expand "bltgt"
13669 (if_then_else (match_dup 1)
13670 (label_ref (match_operand 0 "" ""))
13672 "TARGET_80387 || TARGET_SSE_MATH"
13673 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13675 (define_insn "*jcc_1"
13677 (if_then_else (match_operator 1 "ix86_comparison_operator"
13678 [(reg FLAGS_REG) (const_int 0)])
13679 (label_ref (match_operand 0 "" ""))
13683 [(set_attr "type" "ibr")
13684 (set_attr "modrm" "0")
13685 (set (attr "length")
13686 (if_then_else (and (ge (minus (match_dup 0) (pc))
13688 (lt (minus (match_dup 0) (pc))
13693 (define_insn "*jcc_2"
13695 (if_then_else (match_operator 1 "ix86_comparison_operator"
13696 [(reg FLAGS_REG) (const_int 0)])
13698 (label_ref (match_operand 0 "" ""))))]
13701 [(set_attr "type" "ibr")
13702 (set_attr "modrm" "0")
13703 (set (attr "length")
13704 (if_then_else (and (ge (minus (match_dup 0) (pc))
13706 (lt (minus (match_dup 0) (pc))
13711 ;; In general it is not safe to assume too much about CCmode registers,
13712 ;; so simplify-rtx stops when it sees a second one. Under certain
13713 ;; conditions this is safe on x86, so help combine not create
13721 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13722 [(reg FLAGS_REG) (const_int 0)])
13724 (label_ref (match_operand 1 "" ""))
13728 (if_then_else (match_dup 0)
13729 (label_ref (match_dup 1))
13732 PUT_MODE (operands[0], VOIDmode);
13737 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13738 [(reg FLAGS_REG) (const_int 0)])
13740 (label_ref (match_operand 1 "" ""))
13744 (if_then_else (match_dup 0)
13745 (label_ref (match_dup 1))
13748 rtx new_op0 = copy_rtx (operands[0]);
13749 operands[0] = new_op0;
13750 PUT_MODE (new_op0, VOIDmode);
13751 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13752 GET_MODE (XEXP (new_op0, 0))));
13754 /* Make sure that (a) the CCmode we have for the flags is strong
13755 enough for the reversed compare or (b) we have a valid FP compare. */
13756 if (! ix86_comparison_operator (new_op0, VOIDmode))
13760 ;; Define combination compare-and-branch fp compare instructions to use
13761 ;; during early optimization. Splitting the operation apart early makes
13762 ;; for bad code when we want to reverse the operation.
13764 (define_insn "*fp_jcc_1_mixed"
13766 (if_then_else (match_operator 0 "comparison_operator"
13767 [(match_operand 1 "register_operand" "f,x")
13768 (match_operand 2 "nonimmediate_operand" "f,xm")])
13769 (label_ref (match_operand 3 "" ""))
13771 (clobber (reg:CCFP FPSR_REG))
13772 (clobber (reg:CCFP FLAGS_REG))]
13773 "TARGET_MIX_SSE_I387
13774 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13775 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13776 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13779 (define_insn "*fp_jcc_1_sse"
13781 (if_then_else (match_operator 0 "comparison_operator"
13782 [(match_operand 1 "register_operand" "x")
13783 (match_operand 2 "nonimmediate_operand" "xm")])
13784 (label_ref (match_operand 3 "" ""))
13786 (clobber (reg:CCFP FPSR_REG))
13787 (clobber (reg:CCFP FLAGS_REG))]
13789 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13790 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13791 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13794 (define_insn "*fp_jcc_1_387"
13796 (if_then_else (match_operator 0 "comparison_operator"
13797 [(match_operand 1 "register_operand" "f")
13798 (match_operand 2 "register_operand" "f")])
13799 (label_ref (match_operand 3 "" ""))
13801 (clobber (reg:CCFP FPSR_REG))
13802 (clobber (reg:CCFP FLAGS_REG))]
13803 "TARGET_CMOVE && TARGET_80387
13804 && FLOAT_MODE_P (GET_MODE (operands[1]))
13805 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13806 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13809 (define_insn "*fp_jcc_2_mixed"
13811 (if_then_else (match_operator 0 "comparison_operator"
13812 [(match_operand 1 "register_operand" "f,x")
13813 (match_operand 2 "nonimmediate_operand" "f,xm")])
13815 (label_ref (match_operand 3 "" ""))))
13816 (clobber (reg:CCFP FPSR_REG))
13817 (clobber (reg:CCFP FLAGS_REG))]
13818 "TARGET_MIX_SSE_I387
13819 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13820 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13821 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13824 (define_insn "*fp_jcc_2_sse"
13826 (if_then_else (match_operator 0 "comparison_operator"
13827 [(match_operand 1 "register_operand" "x")
13828 (match_operand 2 "nonimmediate_operand" "xm")])
13830 (label_ref (match_operand 3 "" ""))))
13831 (clobber (reg:CCFP FPSR_REG))
13832 (clobber (reg:CCFP FLAGS_REG))]
13834 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13835 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13836 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13839 (define_insn "*fp_jcc_2_387"
13841 (if_then_else (match_operator 0 "comparison_operator"
13842 [(match_operand 1 "register_operand" "f")
13843 (match_operand 2 "register_operand" "f")])
13845 (label_ref (match_operand 3 "" ""))))
13846 (clobber (reg:CCFP FPSR_REG))
13847 (clobber (reg:CCFP FLAGS_REG))]
13848 "TARGET_CMOVE && TARGET_80387
13849 && FLOAT_MODE_P (GET_MODE (operands[1]))
13850 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13851 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13854 (define_insn "*fp_jcc_3_387"
13856 (if_then_else (match_operator 0 "comparison_operator"
13857 [(match_operand 1 "register_operand" "f")
13858 (match_operand 2 "nonimmediate_operand" "fm")])
13859 (label_ref (match_operand 3 "" ""))
13861 (clobber (reg:CCFP FPSR_REG))
13862 (clobber (reg:CCFP FLAGS_REG))
13863 (clobber (match_scratch:HI 4 "=a"))]
13865 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13866 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13867 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13868 && SELECT_CC_MODE (GET_CODE (operands[0]),
13869 operands[1], operands[2]) == CCFPmode
13870 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13873 (define_insn "*fp_jcc_4_387"
13875 (if_then_else (match_operator 0 "comparison_operator"
13876 [(match_operand 1 "register_operand" "f")
13877 (match_operand 2 "nonimmediate_operand" "fm")])
13879 (label_ref (match_operand 3 "" ""))))
13880 (clobber (reg:CCFP FPSR_REG))
13881 (clobber (reg:CCFP FLAGS_REG))
13882 (clobber (match_scratch:HI 4 "=a"))]
13884 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13885 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13886 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13887 && SELECT_CC_MODE (GET_CODE (operands[0]),
13888 operands[1], operands[2]) == CCFPmode
13889 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13892 (define_insn "*fp_jcc_5_387"
13894 (if_then_else (match_operator 0 "comparison_operator"
13895 [(match_operand 1 "register_operand" "f")
13896 (match_operand 2 "register_operand" "f")])
13897 (label_ref (match_operand 3 "" ""))
13899 (clobber (reg:CCFP FPSR_REG))
13900 (clobber (reg:CCFP FLAGS_REG))
13901 (clobber (match_scratch:HI 4 "=a"))]
13903 && FLOAT_MODE_P (GET_MODE (operands[1]))
13904 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13905 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13908 (define_insn "*fp_jcc_6_387"
13910 (if_then_else (match_operator 0 "comparison_operator"
13911 [(match_operand 1 "register_operand" "f")
13912 (match_operand 2 "register_operand" "f")])
13914 (label_ref (match_operand 3 "" ""))))
13915 (clobber (reg:CCFP FPSR_REG))
13916 (clobber (reg:CCFP FLAGS_REG))
13917 (clobber (match_scratch:HI 4 "=a"))]
13919 && FLOAT_MODE_P (GET_MODE (operands[1]))
13920 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13921 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13924 (define_insn "*fp_jcc_7_387"
13926 (if_then_else (match_operator 0 "comparison_operator"
13927 [(match_operand 1 "register_operand" "f")
13928 (match_operand 2 "const0_operand" "X")])
13929 (label_ref (match_operand 3 "" ""))
13931 (clobber (reg:CCFP FPSR_REG))
13932 (clobber (reg:CCFP FLAGS_REG))
13933 (clobber (match_scratch:HI 4 "=a"))]
13935 && FLOAT_MODE_P (GET_MODE (operands[1]))
13936 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13937 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13938 && SELECT_CC_MODE (GET_CODE (operands[0]),
13939 operands[1], operands[2]) == CCFPmode
13940 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13943 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13944 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13945 ;; with a precedence over other operators and is always put in the first
13946 ;; place. Swap condition and operands to match ficom instruction.
13948 (define_insn "*fp_jcc_8<mode>_387"
13950 (if_then_else (match_operator 0 "comparison_operator"
13951 [(match_operator 1 "float_operator"
13952 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13953 (match_operand 3 "register_operand" "f,f")])
13954 (label_ref (match_operand 4 "" ""))
13956 (clobber (reg:CCFP FPSR_REG))
13957 (clobber (reg:CCFP FLAGS_REG))
13958 (clobber (match_scratch:HI 5 "=a,a"))]
13959 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13960 && FLOAT_MODE_P (GET_MODE (operands[3]))
13961 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13962 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13963 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13964 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13969 (if_then_else (match_operator 0 "comparison_operator"
13970 [(match_operand 1 "register_operand" "")
13971 (match_operand 2 "nonimmediate_operand" "")])
13972 (match_operand 3 "" "")
13973 (match_operand 4 "" "")))
13974 (clobber (reg:CCFP FPSR_REG))
13975 (clobber (reg:CCFP FLAGS_REG))]
13979 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13980 operands[3], operands[4], NULL_RTX, NULL_RTX);
13986 (if_then_else (match_operator 0 "comparison_operator"
13987 [(match_operand 1 "register_operand" "")
13988 (match_operand 2 "general_operand" "")])
13989 (match_operand 3 "" "")
13990 (match_operand 4 "" "")))
13991 (clobber (reg:CCFP FPSR_REG))
13992 (clobber (reg:CCFP FLAGS_REG))
13993 (clobber (match_scratch:HI 5 "=a"))]
13997 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13998 operands[3], operands[4], operands[5], NULL_RTX);
14004 (if_then_else (match_operator 0 "comparison_operator"
14005 [(match_operator 1 "float_operator"
14006 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14007 (match_operand 3 "register_operand" "")])
14008 (match_operand 4 "" "")
14009 (match_operand 5 "" "")))
14010 (clobber (reg:CCFP FPSR_REG))
14011 (clobber (reg:CCFP FLAGS_REG))
14012 (clobber (match_scratch:HI 6 "=a"))]
14016 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14017 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14018 operands[3], operands[7],
14019 operands[4], operands[5], operands[6], NULL_RTX);
14023 ;; %%% Kill this when reload knows how to do it.
14026 (if_then_else (match_operator 0 "comparison_operator"
14027 [(match_operator 1 "float_operator"
14028 [(match_operand:X87MODEI12 2 "register_operand" "")])
14029 (match_operand 3 "register_operand" "")])
14030 (match_operand 4 "" "")
14031 (match_operand 5 "" "")))
14032 (clobber (reg:CCFP FPSR_REG))
14033 (clobber (reg:CCFP FLAGS_REG))
14034 (clobber (match_scratch:HI 6 "=a"))]
14038 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14039 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14040 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14041 operands[3], operands[7],
14042 operands[4], operands[5], operands[6], operands[2]);
14046 ;; Unconditional and other jump instructions
14048 (define_insn "jump"
14050 (label_ref (match_operand 0 "" "")))]
14053 [(set_attr "type" "ibr")
14054 (set (attr "length")
14055 (if_then_else (and (ge (minus (match_dup 0) (pc))
14057 (lt (minus (match_dup 0) (pc))
14061 (set_attr "modrm" "0")])
14063 (define_expand "indirect_jump"
14064 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14068 (define_insn "*indirect_jump"
14069 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14072 [(set_attr "type" "ibr")
14073 (set_attr "length_immediate" "0")])
14075 (define_insn "*indirect_jump_rtx64"
14076 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14079 [(set_attr "type" "ibr")
14080 (set_attr "length_immediate" "0")])
14082 (define_expand "tablejump"
14083 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14084 (use (label_ref (match_operand 1 "" "")))])]
14087 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14088 relative. Convert the relative address to an absolute address. */
14092 enum rtx_code code;
14098 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14100 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14104 op1 = pic_offset_table_rtx;
14109 op0 = pic_offset_table_rtx;
14113 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14118 (define_insn "*tablejump_1"
14119 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14120 (use (label_ref (match_operand 1 "" "")))]
14123 [(set_attr "type" "ibr")
14124 (set_attr "length_immediate" "0")])
14126 (define_insn "*tablejump_1_rtx64"
14127 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14128 (use (label_ref (match_operand 1 "" "")))]
14131 [(set_attr "type" "ibr")
14132 (set_attr "length_immediate" "0")])
14134 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14137 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14138 (set (match_operand:QI 1 "register_operand" "")
14139 (match_operator:QI 2 "ix86_comparison_operator"
14140 [(reg FLAGS_REG) (const_int 0)]))
14141 (set (match_operand 3 "q_regs_operand" "")
14142 (zero_extend (match_dup 1)))]
14143 "(peep2_reg_dead_p (3, operands[1])
14144 || operands_match_p (operands[1], operands[3]))
14145 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14146 [(set (match_dup 4) (match_dup 0))
14147 (set (strict_low_part (match_dup 5))
14150 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14151 operands[5] = gen_lowpart (QImode, operands[3]);
14152 ix86_expand_clear (operands[3]);
14155 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14158 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14159 (set (match_operand:QI 1 "register_operand" "")
14160 (match_operator:QI 2 "ix86_comparison_operator"
14161 [(reg FLAGS_REG) (const_int 0)]))
14162 (parallel [(set (match_operand 3 "q_regs_operand" "")
14163 (zero_extend (match_dup 1)))
14164 (clobber (reg:CC FLAGS_REG))])]
14165 "(peep2_reg_dead_p (3, operands[1])
14166 || operands_match_p (operands[1], operands[3]))
14167 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14168 [(set (match_dup 4) (match_dup 0))
14169 (set (strict_low_part (match_dup 5))
14172 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14173 operands[5] = gen_lowpart (QImode, operands[3]);
14174 ix86_expand_clear (operands[3]);
14177 ;; Call instructions.
14179 ;; The predicates normally associated with named expanders are not properly
14180 ;; checked for calls. This is a bug in the generic code, but it isn't that
14181 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14183 ;; Call subroutine returning no value.
14185 (define_expand "call_pop"
14186 [(parallel [(call (match_operand:QI 0 "" "")
14187 (match_operand:SI 1 "" ""))
14188 (set (reg:SI SP_REG)
14189 (plus:SI (reg:SI SP_REG)
14190 (match_operand:SI 3 "" "")))])]
14193 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14197 (define_insn "*call_pop_0"
14198 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14199 (match_operand:SI 1 "" ""))
14200 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14201 (match_operand:SI 2 "immediate_operand" "")))]
14204 if (SIBLING_CALL_P (insn))
14207 return "call\t%P0";
14209 [(set_attr "type" "call")])
14211 (define_insn "*call_pop_1"
14212 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14213 (match_operand:SI 1 "" ""))
14214 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14215 (match_operand:SI 2 "immediate_operand" "i")))]
14218 if (constant_call_address_operand (operands[0], Pmode))
14220 if (SIBLING_CALL_P (insn))
14223 return "call\t%P0";
14225 if (SIBLING_CALL_P (insn))
14228 return "call\t%A0";
14230 [(set_attr "type" "call")])
14232 (define_expand "call"
14233 [(call (match_operand:QI 0 "" "")
14234 (match_operand 1 "" ""))
14235 (use (match_operand 2 "" ""))]
14238 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14242 (define_expand "sibcall"
14243 [(call (match_operand:QI 0 "" "")
14244 (match_operand 1 "" ""))
14245 (use (match_operand 2 "" ""))]
14248 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14252 (define_insn "*call_0"
14253 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14254 (match_operand 1 "" ""))]
14257 if (SIBLING_CALL_P (insn))
14260 return "call\t%P0";
14262 [(set_attr "type" "call")])
14264 (define_insn "*call_1"
14265 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14266 (match_operand 1 "" ""))]
14267 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14269 if (constant_call_address_operand (operands[0], Pmode))
14270 return "call\t%P0";
14271 return "call\t%A0";
14273 [(set_attr "type" "call")])
14275 (define_insn "*sibcall_1"
14276 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14277 (match_operand 1 "" ""))]
14278 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14280 if (constant_call_address_operand (operands[0], Pmode))
14284 [(set_attr "type" "call")])
14286 (define_insn "*call_1_rex64"
14287 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14288 (match_operand 1 "" ""))]
14289 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14291 if (constant_call_address_operand (operands[0], Pmode))
14292 return "call\t%P0";
14293 return "call\t%A0";
14295 [(set_attr "type" "call")])
14297 (define_insn "*sibcall_1_rex64"
14298 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14299 (match_operand 1 "" ""))]
14300 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14302 [(set_attr "type" "call")])
14304 (define_insn "*sibcall_1_rex64_v"
14305 [(call (mem:QI (reg:DI R11_REG))
14306 (match_operand 0 "" ""))]
14307 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14309 [(set_attr "type" "call")])
14312 ;; Call subroutine, returning value in operand 0
14314 (define_expand "call_value_pop"
14315 [(parallel [(set (match_operand 0 "" "")
14316 (call (match_operand:QI 1 "" "")
14317 (match_operand:SI 2 "" "")))
14318 (set (reg:SI SP_REG)
14319 (plus:SI (reg:SI SP_REG)
14320 (match_operand:SI 4 "" "")))])]
14323 ix86_expand_call (operands[0], operands[1], operands[2],
14324 operands[3], operands[4], 0);
14328 (define_expand "call_value"
14329 [(set (match_operand 0 "" "")
14330 (call (match_operand:QI 1 "" "")
14331 (match_operand:SI 2 "" "")))
14332 (use (match_operand:SI 3 "" ""))]
14333 ;; Operand 2 not used on the i386.
14336 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14340 (define_expand "sibcall_value"
14341 [(set (match_operand 0 "" "")
14342 (call (match_operand:QI 1 "" "")
14343 (match_operand:SI 2 "" "")))
14344 (use (match_operand:SI 3 "" ""))]
14345 ;; Operand 2 not used on the i386.
14348 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14352 ;; Call subroutine returning any type.
14354 (define_expand "untyped_call"
14355 [(parallel [(call (match_operand 0 "" "")
14357 (match_operand 1 "" "")
14358 (match_operand 2 "" "")])]
14363 /* In order to give reg-stack an easier job in validating two
14364 coprocessor registers as containing a possible return value,
14365 simply pretend the untyped call returns a complex long double
14368 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14369 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14370 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14373 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14375 rtx set = XVECEXP (operands[2], 0, i);
14376 emit_move_insn (SET_DEST (set), SET_SRC (set));
14379 /* The optimizer does not know that the call sets the function value
14380 registers we stored in the result block. We avoid problems by
14381 claiming that all hard registers are used and clobbered at this
14383 emit_insn (gen_blockage (const0_rtx));
14388 ;; Prologue and epilogue instructions
14390 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14391 ;; all of memory. This blocks insns from being moved across this point.
14393 (define_insn "blockage"
14394 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14397 [(set_attr "length" "0")])
14399 ;; Insn emitted into the body of a function to return from a function.
14400 ;; This is only done if the function's epilogue is known to be simple.
14401 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14403 (define_expand "return"
14405 "ix86_can_use_return_insn_p ()"
14407 if (current_function_pops_args)
14409 rtx popc = GEN_INT (current_function_pops_args);
14410 emit_jump_insn (gen_return_pop_internal (popc));
14415 (define_insn "return_internal"
14419 [(set_attr "length" "1")
14420 (set_attr "length_immediate" "0")
14421 (set_attr "modrm" "0")])
14423 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14424 ;; instruction Athlon and K8 have.
14426 (define_insn "return_internal_long"
14428 (unspec [(const_int 0)] UNSPEC_REP)]
14431 [(set_attr "length" "1")
14432 (set_attr "length_immediate" "0")
14433 (set_attr "prefix_rep" "1")
14434 (set_attr "modrm" "0")])
14436 (define_insn "return_pop_internal"
14438 (use (match_operand:SI 0 "const_int_operand" ""))]
14441 [(set_attr "length" "3")
14442 (set_attr "length_immediate" "2")
14443 (set_attr "modrm" "0")])
14445 (define_insn "return_indirect_internal"
14447 (use (match_operand:SI 0 "register_operand" "r"))]
14450 [(set_attr "type" "ibr")
14451 (set_attr "length_immediate" "0")])
14457 [(set_attr "length" "1")
14458 (set_attr "length_immediate" "0")
14459 (set_attr "modrm" "0")])
14461 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14462 ;; branch prediction penalty for the third jump in a 16-byte
14465 (define_insn "align"
14466 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14469 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14470 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14472 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14473 The align insn is used to avoid 3 jump instructions in the row to improve
14474 branch prediction and the benefits hardly outweigh the cost of extra 8
14475 nops on the average inserted by full alignment pseudo operation. */
14479 [(set_attr "length" "16")])
14481 (define_expand "prologue"
14484 "ix86_expand_prologue (); DONE;")
14486 (define_insn "set_got"
14487 [(set (match_operand:SI 0 "register_operand" "=r")
14488 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14489 (clobber (reg:CC FLAGS_REG))]
14491 { return output_set_got (operands[0], NULL_RTX); }
14492 [(set_attr "type" "multi")
14493 (set_attr "length" "12")])
14495 (define_insn "set_got_labelled"
14496 [(set (match_operand:SI 0 "register_operand" "=r")
14497 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14499 (clobber (reg:CC FLAGS_REG))]
14501 { return output_set_got (operands[0], operands[1]); }
14502 [(set_attr "type" "multi")
14503 (set_attr "length" "12")])
14505 (define_insn "set_got_rex64"
14506 [(set (match_operand:DI 0 "register_operand" "=r")
14507 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14509 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14510 [(set_attr "type" "lea")
14511 (set_attr "length" "6")])
14513 (define_expand "epilogue"
14516 "ix86_expand_epilogue (1); DONE;")
14518 (define_expand "sibcall_epilogue"
14521 "ix86_expand_epilogue (0); DONE;")
14523 (define_expand "eh_return"
14524 [(use (match_operand 0 "register_operand" ""))]
14527 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14529 /* Tricky bit: we write the address of the handler to which we will
14530 be returning into someone else's stack frame, one word below the
14531 stack address we wish to restore. */
14532 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14533 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14534 tmp = gen_rtx_MEM (Pmode, tmp);
14535 emit_move_insn (tmp, ra);
14537 if (Pmode == SImode)
14538 emit_jump_insn (gen_eh_return_si (sa));
14540 emit_jump_insn (gen_eh_return_di (sa));
14545 (define_insn_and_split "eh_return_si"
14547 (unspec [(match_operand:SI 0 "register_operand" "c")]
14548 UNSPEC_EH_RETURN))]
14553 "ix86_expand_epilogue (2); DONE;")
14555 (define_insn_and_split "eh_return_di"
14557 (unspec [(match_operand:DI 0 "register_operand" "c")]
14558 UNSPEC_EH_RETURN))]
14563 "ix86_expand_epilogue (2); DONE;")
14565 (define_insn "leave"
14566 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14567 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14568 (clobber (mem:BLK (scratch)))]
14571 [(set_attr "type" "leave")])
14573 (define_insn "leave_rex64"
14574 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14575 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14576 (clobber (mem:BLK (scratch)))]
14579 [(set_attr "type" "leave")])
14581 (define_expand "ffssi2"
14583 [(set (match_operand:SI 0 "register_operand" "")
14584 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14585 (clobber (match_scratch:SI 2 ""))
14586 (clobber (reg:CC FLAGS_REG))])]
14590 (define_insn_and_split "*ffs_cmove"
14591 [(set (match_operand:SI 0 "register_operand" "=r")
14592 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14593 (clobber (match_scratch:SI 2 "=&r"))
14594 (clobber (reg:CC FLAGS_REG))]
14597 "&& reload_completed"
14598 [(set (match_dup 2) (const_int -1))
14599 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14600 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14601 (set (match_dup 0) (if_then_else:SI
14602 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14605 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14606 (clobber (reg:CC FLAGS_REG))])]
14609 (define_insn_and_split "*ffs_no_cmove"
14610 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14611 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14612 (clobber (match_scratch:SI 2 "=&q"))
14613 (clobber (reg:CC FLAGS_REG))]
14617 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14618 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14619 (set (strict_low_part (match_dup 3))
14620 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14621 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14622 (clobber (reg:CC FLAGS_REG))])
14623 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14624 (clobber (reg:CC FLAGS_REG))])
14625 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14626 (clobber (reg:CC FLAGS_REG))])]
14628 operands[3] = gen_lowpart (QImode, operands[2]);
14629 ix86_expand_clear (operands[2]);
14632 (define_insn "*ffssi_1"
14633 [(set (reg:CCZ FLAGS_REG)
14634 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14636 (set (match_operand:SI 0 "register_operand" "=r")
14637 (ctz:SI (match_dup 1)))]
14639 "bsf{l}\t{%1, %0|%0, %1}"
14640 [(set_attr "prefix_0f" "1")])
14642 (define_expand "ffsdi2"
14644 [(set (match_operand:DI 0 "register_operand" "")
14645 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14646 (clobber (match_scratch:DI 2 ""))
14647 (clobber (reg:CC FLAGS_REG))])]
14648 "TARGET_64BIT && TARGET_CMOVE"
14651 (define_insn_and_split "*ffs_rex64"
14652 [(set (match_operand:DI 0 "register_operand" "=r")
14653 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14654 (clobber (match_scratch:DI 2 "=&r"))
14655 (clobber (reg:CC FLAGS_REG))]
14656 "TARGET_64BIT && TARGET_CMOVE"
14658 "&& reload_completed"
14659 [(set (match_dup 2) (const_int -1))
14660 (parallel [(set (reg:CCZ FLAGS_REG)
14661 (compare:CCZ (match_dup 1) (const_int 0)))
14662 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14663 (set (match_dup 0) (if_then_else:DI
14664 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14667 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14668 (clobber (reg:CC FLAGS_REG))])]
14671 (define_insn "*ffsdi_1"
14672 [(set (reg:CCZ FLAGS_REG)
14673 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14675 (set (match_operand:DI 0 "register_operand" "=r")
14676 (ctz:DI (match_dup 1)))]
14678 "bsf{q}\t{%1, %0|%0, %1}"
14679 [(set_attr "prefix_0f" "1")])
14681 (define_insn "ctzsi2"
14682 [(set (match_operand:SI 0 "register_operand" "=r")
14683 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14684 (clobber (reg:CC FLAGS_REG))]
14686 "bsf{l}\t{%1, %0|%0, %1}"
14687 [(set_attr "prefix_0f" "1")])
14689 (define_insn "ctzdi2"
14690 [(set (match_operand:DI 0 "register_operand" "=r")
14691 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14692 (clobber (reg:CC FLAGS_REG))]
14694 "bsf{q}\t{%1, %0|%0, %1}"
14695 [(set_attr "prefix_0f" "1")])
14697 (define_expand "clzsi2"
14699 [(set (match_operand:SI 0 "register_operand" "")
14700 (minus:SI (const_int 31)
14701 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14702 (clobber (reg:CC FLAGS_REG))])
14704 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14705 (clobber (reg:CC FLAGS_REG))])]
14710 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14715 (define_insn "clzsi2_abm"
14716 [(set (match_operand:SI 0 "register_operand" "=r")
14717 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14718 (clobber (reg:CC FLAGS_REG))]
14720 "lzcnt{l}\t{%1, %0|%0, %1}"
14721 [(set_attr "prefix_rep" "1")
14722 (set_attr "type" "bitmanip")
14723 (set_attr "mode" "SI")])
14725 (define_insn "*bsr"
14726 [(set (match_operand:SI 0 "register_operand" "=r")
14727 (minus:SI (const_int 31)
14728 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14729 (clobber (reg:CC FLAGS_REG))]
14731 "bsr{l}\t{%1, %0|%0, %1}"
14732 [(set_attr "prefix_0f" "1")
14733 (set_attr "mode" "SI")])
14735 (define_insn "popcountsi2"
14736 [(set (match_operand:SI 0 "register_operand" "=r")
14737 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14738 (clobber (reg:CC FLAGS_REG))]
14740 "popcnt{l}\t{%1, %0|%0, %1}"
14741 [(set_attr "prefix_rep" "1")
14742 (set_attr "type" "bitmanip")
14743 (set_attr "mode" "SI")])
14745 (define_insn "*popcountsi2_cmp"
14746 [(set (reg FLAGS_REG)
14748 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14750 (set (match_operand:SI 0 "register_operand" "=r")
14751 (popcount:SI (match_dup 1)))]
14752 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14753 "popcnt{l}\t{%1, %0|%0, %1}"
14754 [(set_attr "prefix_rep" "1")
14755 (set_attr "type" "bitmanip")
14756 (set_attr "mode" "SI")])
14758 (define_insn "*popcountsi2_cmp_zext"
14759 [(set (reg FLAGS_REG)
14761 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14763 (set (match_operand:DI 0 "register_operand" "=r")
14764 (zero_extend:DI(popcount:SI (match_dup 1))))]
14765 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14766 "popcnt{l}\t{%1, %0|%0, %1}"
14767 [(set_attr "prefix_rep" "1")
14768 (set_attr "type" "bitmanip")
14769 (set_attr "mode" "SI")])
14771 (define_insn "bswapsi2"
14772 [(set (match_operand:SI 0 "register_operand" "=r")
14773 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14774 (clobber (reg:CC FLAGS_REG))]
14777 [(set_attr "prefix_0f" "1")
14778 (set_attr "length" "2")])
14780 (define_insn "bswapdi2"
14781 [(set (match_operand:DI 0 "register_operand" "=r")
14782 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14783 (clobber (reg:CC FLAGS_REG))]
14784 "TARGET_64BIT && TARGET_BSWAP"
14786 [(set_attr "prefix_0f" "1")
14787 (set_attr "length" "3")])
14789 (define_expand "clzdi2"
14791 [(set (match_operand:DI 0 "register_operand" "")
14792 (minus:DI (const_int 63)
14793 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14794 (clobber (reg:CC FLAGS_REG))])
14796 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14797 (clobber (reg:CC FLAGS_REG))])]
14802 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14807 (define_insn "clzdi2_abm"
14808 [(set (match_operand:DI 0 "register_operand" "=r")
14809 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14810 (clobber (reg:CC FLAGS_REG))]
14811 "TARGET_64BIT && TARGET_ABM"
14812 "lzcnt{q}\t{%1, %0|%0, %1}"
14813 [(set_attr "prefix_rep" "1")
14814 (set_attr "type" "bitmanip")
14815 (set_attr "mode" "DI")])
14817 (define_insn "*bsr_rex64"
14818 [(set (match_operand:DI 0 "register_operand" "=r")
14819 (minus:DI (const_int 63)
14820 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14821 (clobber (reg:CC FLAGS_REG))]
14823 "bsr{q}\t{%1, %0|%0, %1}"
14824 [(set_attr "prefix_0f" "1")
14825 (set_attr "mode" "DI")])
14827 (define_insn "popcountdi2"
14828 [(set (match_operand:DI 0 "register_operand" "=r")
14829 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14830 (clobber (reg:CC FLAGS_REG))]
14831 "TARGET_64BIT && TARGET_POPCNT"
14832 "popcnt{q}\t{%1, %0|%0, %1}"
14833 [(set_attr "prefix_rep" "1")
14834 (set_attr "type" "bitmanip")
14835 (set_attr "mode" "DI")])
14837 (define_insn "*popcountdi2_cmp"
14838 [(set (reg FLAGS_REG)
14840 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
14842 (set (match_operand:DI 0 "register_operand" "=r")
14843 (popcount:DI (match_dup 1)))]
14844 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14845 "popcnt{q}\t{%1, %0|%0, %1}"
14846 [(set_attr "prefix_rep" "1")
14847 (set_attr "type" "bitmanip")
14848 (set_attr "mode" "DI")])
14850 (define_expand "clzhi2"
14852 [(set (match_operand:HI 0 "register_operand" "")
14853 (minus:HI (const_int 15)
14854 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14855 (clobber (reg:CC FLAGS_REG))])
14857 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14858 (clobber (reg:CC FLAGS_REG))])]
14863 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14868 (define_insn "clzhi2_abm"
14869 [(set (match_operand:HI 0 "register_operand" "=r")
14870 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14871 (clobber (reg:CC FLAGS_REG))]
14873 "lzcnt{w}\t{%1, %0|%0, %1}"
14874 [(set_attr "prefix_rep" "1")
14875 (set_attr "type" "bitmanip")
14876 (set_attr "mode" "HI")])
14878 (define_insn "*bsrhi"
14879 [(set (match_operand:HI 0 "register_operand" "=r")
14880 (minus:HI (const_int 15)
14881 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14882 (clobber (reg:CC FLAGS_REG))]
14884 "bsr{w}\t{%1, %0|%0, %1}"
14885 [(set_attr "prefix_0f" "1")
14886 (set_attr "mode" "HI")])
14888 (define_insn "popcounthi2"
14889 [(set (match_operand:HI 0 "register_operand" "=r")
14890 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
14891 (clobber (reg:CC FLAGS_REG))]
14893 "popcnt{w}\t{%1, %0|%0, %1}"
14894 [(set_attr "prefix_rep" "1")
14895 (set_attr "type" "bitmanip")
14896 (set_attr "mode" "HI")])
14898 (define_insn "*popcounthi2_cmp"
14899 [(set (reg FLAGS_REG)
14901 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
14903 (set (match_operand:HI 0 "register_operand" "=r")
14904 (popcount:HI (match_dup 1)))]
14905 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14906 "popcnt{w}\t{%1, %0|%0, %1}"
14907 [(set_attr "prefix_rep" "1")
14908 (set_attr "type" "bitmanip")
14909 (set_attr "mode" "HI")])
14911 ;; Thread-local storage patterns for ELF.
14913 ;; Note that these code sequences must appear exactly as shown
14914 ;; in order to allow linker relaxation.
14916 (define_insn "*tls_global_dynamic_32_gnu"
14917 [(set (match_operand:SI 0 "register_operand" "=a")
14918 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14919 (match_operand:SI 2 "tls_symbolic_operand" "")
14920 (match_operand:SI 3 "call_insn_operand" "")]
14922 (clobber (match_scratch:SI 4 "=d"))
14923 (clobber (match_scratch:SI 5 "=c"))
14924 (clobber (reg:CC FLAGS_REG))]
14925 "!TARGET_64BIT && TARGET_GNU_TLS"
14926 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14927 [(set_attr "type" "multi")
14928 (set_attr "length" "12")])
14930 (define_insn "*tls_global_dynamic_32_sun"
14931 [(set (match_operand:SI 0 "register_operand" "=a")
14932 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14933 (match_operand:SI 2 "tls_symbolic_operand" "")
14934 (match_operand:SI 3 "call_insn_operand" "")]
14936 (clobber (match_scratch:SI 4 "=d"))
14937 (clobber (match_scratch:SI 5 "=c"))
14938 (clobber (reg:CC FLAGS_REG))]
14939 "!TARGET_64BIT && TARGET_SUN_TLS"
14940 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14941 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14942 [(set_attr "type" "multi")
14943 (set_attr "length" "14")])
14945 (define_expand "tls_global_dynamic_32"
14946 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14949 (match_operand:SI 1 "tls_symbolic_operand" "")
14952 (clobber (match_scratch:SI 4 ""))
14953 (clobber (match_scratch:SI 5 ""))
14954 (clobber (reg:CC FLAGS_REG))])]
14958 operands[2] = pic_offset_table_rtx;
14961 operands[2] = gen_reg_rtx (Pmode);
14962 emit_insn (gen_set_got (operands[2]));
14964 if (TARGET_GNU2_TLS)
14966 emit_insn (gen_tls_dynamic_gnu2_32
14967 (operands[0], operands[1], operands[2]));
14970 operands[3] = ix86_tls_get_addr ();
14973 (define_insn "*tls_global_dynamic_64"
14974 [(set (match_operand:DI 0 "register_operand" "=a")
14975 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14976 (match_operand:DI 3 "" "")))
14977 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14980 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14981 [(set_attr "type" "multi")
14982 (set_attr "length" "16")])
14984 (define_expand "tls_global_dynamic_64"
14985 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14986 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14987 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14991 if (TARGET_GNU2_TLS)
14993 emit_insn (gen_tls_dynamic_gnu2_64
14994 (operands[0], operands[1]));
14997 operands[2] = ix86_tls_get_addr ();
15000 (define_insn "*tls_local_dynamic_base_32_gnu"
15001 [(set (match_operand:SI 0 "register_operand" "=a")
15002 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15003 (match_operand:SI 2 "call_insn_operand" "")]
15004 UNSPEC_TLS_LD_BASE))
15005 (clobber (match_scratch:SI 3 "=d"))
15006 (clobber (match_scratch:SI 4 "=c"))
15007 (clobber (reg:CC FLAGS_REG))]
15008 "!TARGET_64BIT && TARGET_GNU_TLS"
15009 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15010 [(set_attr "type" "multi")
15011 (set_attr "length" "11")])
15013 (define_insn "*tls_local_dynamic_base_32_sun"
15014 [(set (match_operand:SI 0 "register_operand" "=a")
15015 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15016 (match_operand:SI 2 "call_insn_operand" "")]
15017 UNSPEC_TLS_LD_BASE))
15018 (clobber (match_scratch:SI 3 "=d"))
15019 (clobber (match_scratch:SI 4 "=c"))
15020 (clobber (reg:CC FLAGS_REG))]
15021 "!TARGET_64BIT && TARGET_SUN_TLS"
15022 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15023 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15024 [(set_attr "type" "multi")
15025 (set_attr "length" "13")])
15027 (define_expand "tls_local_dynamic_base_32"
15028 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15029 (unspec:SI [(match_dup 1) (match_dup 2)]
15030 UNSPEC_TLS_LD_BASE))
15031 (clobber (match_scratch:SI 3 ""))
15032 (clobber (match_scratch:SI 4 ""))
15033 (clobber (reg:CC FLAGS_REG))])]
15037 operands[1] = pic_offset_table_rtx;
15040 operands[1] = gen_reg_rtx (Pmode);
15041 emit_insn (gen_set_got (operands[1]));
15043 if (TARGET_GNU2_TLS)
15045 emit_insn (gen_tls_dynamic_gnu2_32
15046 (operands[0], ix86_tls_module_base (), operands[1]));
15049 operands[2] = ix86_tls_get_addr ();
15052 (define_insn "*tls_local_dynamic_base_64"
15053 [(set (match_operand:DI 0 "register_operand" "=a")
15054 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15055 (match_operand:DI 2 "" "")))
15056 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15058 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15059 [(set_attr "type" "multi")
15060 (set_attr "length" "12")])
15062 (define_expand "tls_local_dynamic_base_64"
15063 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15064 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15065 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15068 if (TARGET_GNU2_TLS)
15070 emit_insn (gen_tls_dynamic_gnu2_64
15071 (operands[0], ix86_tls_module_base ()));
15074 operands[1] = ix86_tls_get_addr ();
15077 ;; Local dynamic of a single variable is a lose. Show combine how
15078 ;; to convert that back to global dynamic.
15080 (define_insn_and_split "*tls_local_dynamic_32_once"
15081 [(set (match_operand:SI 0 "register_operand" "=a")
15082 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15083 (match_operand:SI 2 "call_insn_operand" "")]
15084 UNSPEC_TLS_LD_BASE)
15085 (const:SI (unspec:SI
15086 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15088 (clobber (match_scratch:SI 4 "=d"))
15089 (clobber (match_scratch:SI 5 "=c"))
15090 (clobber (reg:CC FLAGS_REG))]
15094 [(parallel [(set (match_dup 0)
15095 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15097 (clobber (match_dup 4))
15098 (clobber (match_dup 5))
15099 (clobber (reg:CC FLAGS_REG))])]
15102 ;; Load and add the thread base pointer from %gs:0.
15104 (define_insn "*load_tp_si"
15105 [(set (match_operand:SI 0 "register_operand" "=r")
15106 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15108 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15109 [(set_attr "type" "imov")
15110 (set_attr "modrm" "0")
15111 (set_attr "length" "7")
15112 (set_attr "memory" "load")
15113 (set_attr "imm_disp" "false")])
15115 (define_insn "*add_tp_si"
15116 [(set (match_operand:SI 0 "register_operand" "=r")
15117 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15118 (match_operand:SI 1 "register_operand" "0")))
15119 (clobber (reg:CC FLAGS_REG))]
15121 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15122 [(set_attr "type" "alu")
15123 (set_attr "modrm" "0")
15124 (set_attr "length" "7")
15125 (set_attr "memory" "load")
15126 (set_attr "imm_disp" "false")])
15128 (define_insn "*load_tp_di"
15129 [(set (match_operand:DI 0 "register_operand" "=r")
15130 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15132 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15133 [(set_attr "type" "imov")
15134 (set_attr "modrm" "0")
15135 (set_attr "length" "7")
15136 (set_attr "memory" "load")
15137 (set_attr "imm_disp" "false")])
15139 (define_insn "*add_tp_di"
15140 [(set (match_operand:DI 0 "register_operand" "=r")
15141 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15142 (match_operand:DI 1 "register_operand" "0")))
15143 (clobber (reg:CC FLAGS_REG))]
15145 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15146 [(set_attr "type" "alu")
15147 (set_attr "modrm" "0")
15148 (set_attr "length" "7")
15149 (set_attr "memory" "load")
15150 (set_attr "imm_disp" "false")])
15152 ;; GNU2 TLS patterns can be split.
15154 (define_expand "tls_dynamic_gnu2_32"
15155 [(set (match_dup 3)
15156 (plus:SI (match_operand:SI 2 "register_operand" "")
15158 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15161 [(set (match_operand:SI 0 "register_operand" "")
15162 (unspec:SI [(match_dup 1) (match_dup 3)
15163 (match_dup 2) (reg:SI SP_REG)]
15165 (clobber (reg:CC FLAGS_REG))])]
15166 "!TARGET_64BIT && TARGET_GNU2_TLS"
15168 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15169 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15172 (define_insn "*tls_dynamic_lea_32"
15173 [(set (match_operand:SI 0 "register_operand" "=r")
15174 (plus:SI (match_operand:SI 1 "register_operand" "b")
15176 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15177 UNSPEC_TLSDESC))))]
15178 "!TARGET_64BIT && TARGET_GNU2_TLS"
15179 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15180 [(set_attr "type" "lea")
15181 (set_attr "mode" "SI")
15182 (set_attr "length" "6")
15183 (set_attr "length_address" "4")])
15185 (define_insn "*tls_dynamic_call_32"
15186 [(set (match_operand:SI 0 "register_operand" "=a")
15187 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15188 (match_operand:SI 2 "register_operand" "0")
15189 ;; we have to make sure %ebx still points to the GOT
15190 (match_operand:SI 3 "register_operand" "b")
15193 (clobber (reg:CC FLAGS_REG))]
15194 "!TARGET_64BIT && TARGET_GNU2_TLS"
15195 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15196 [(set_attr "type" "call")
15197 (set_attr "length" "2")
15198 (set_attr "length_address" "0")])
15200 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15201 [(set (match_operand:SI 0 "register_operand" "=&a")
15203 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15204 (match_operand:SI 4 "" "")
15205 (match_operand:SI 2 "register_operand" "b")
15208 (const:SI (unspec:SI
15209 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15211 (clobber (reg:CC FLAGS_REG))]
15212 "!TARGET_64BIT && TARGET_GNU2_TLS"
15215 [(set (match_dup 0) (match_dup 5))]
15217 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15218 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15221 (define_expand "tls_dynamic_gnu2_64"
15222 [(set (match_dup 2)
15223 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15226 [(set (match_operand:DI 0 "register_operand" "")
15227 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15229 (clobber (reg:CC FLAGS_REG))])]
15230 "TARGET_64BIT && TARGET_GNU2_TLS"
15232 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15233 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15236 (define_insn "*tls_dynamic_lea_64"
15237 [(set (match_operand:DI 0 "register_operand" "=r")
15238 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15240 "TARGET_64BIT && TARGET_GNU2_TLS"
15241 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15242 [(set_attr "type" "lea")
15243 (set_attr "mode" "DI")
15244 (set_attr "length" "7")
15245 (set_attr "length_address" "4")])
15247 (define_insn "*tls_dynamic_call_64"
15248 [(set (match_operand:DI 0 "register_operand" "=a")
15249 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15250 (match_operand:DI 2 "register_operand" "0")
15253 (clobber (reg:CC FLAGS_REG))]
15254 "TARGET_64BIT && TARGET_GNU2_TLS"
15255 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15256 [(set_attr "type" "call")
15257 (set_attr "length" "2")
15258 (set_attr "length_address" "0")])
15260 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15261 [(set (match_operand:DI 0 "register_operand" "=&a")
15263 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15264 (match_operand:DI 3 "" "")
15267 (const:DI (unspec:DI
15268 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15270 (clobber (reg:CC FLAGS_REG))]
15271 "TARGET_64BIT && TARGET_GNU2_TLS"
15274 [(set (match_dup 0) (match_dup 4))]
15276 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15277 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15282 ;; These patterns match the binary 387 instructions for addM3, subM3,
15283 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15284 ;; SFmode. The first is the normal insn, the second the same insn but
15285 ;; with one operand a conversion, and the third the same insn but with
15286 ;; the other operand a conversion. The conversion may be SFmode or
15287 ;; SImode if the target mode DFmode, but only SImode if the target mode
15290 ;; Gcc is slightly more smart about handling normal two address instructions
15291 ;; so use special patterns for add and mull.
15293 (define_insn "*fop_sf_comm_mixed"
15294 [(set (match_operand:SF 0 "register_operand" "=f,x")
15295 (match_operator:SF 3 "binary_fp_operator"
15296 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15297 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15298 "TARGET_MIX_SSE_I387
15299 && COMMUTATIVE_ARITH_P (operands[3])
15300 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15301 "* return output_387_binary_op (insn, operands);"
15302 [(set (attr "type")
15303 (if_then_else (eq_attr "alternative" "1")
15304 (if_then_else (match_operand:SF 3 "mult_operator" "")
15305 (const_string "ssemul")
15306 (const_string "sseadd"))
15307 (if_then_else (match_operand:SF 3 "mult_operator" "")
15308 (const_string "fmul")
15309 (const_string "fop"))))
15310 (set_attr "mode" "SF")])
15312 (define_insn "*fop_sf_comm_sse"
15313 [(set (match_operand:SF 0 "register_operand" "=x")
15314 (match_operator:SF 3 "binary_fp_operator"
15315 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15316 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15318 && COMMUTATIVE_ARITH_P (operands[3])
15319 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15320 "* return output_387_binary_op (insn, operands);"
15321 [(set (attr "type")
15322 (if_then_else (match_operand:SF 3 "mult_operator" "")
15323 (const_string "ssemul")
15324 (const_string "sseadd")))
15325 (set_attr "mode" "SF")])
15327 (define_insn "*fop_sf_comm_i387"
15328 [(set (match_operand:SF 0 "register_operand" "=f")
15329 (match_operator:SF 3 "binary_fp_operator"
15330 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15331 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15333 && COMMUTATIVE_ARITH_P (operands[3])
15334 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15335 "* return output_387_binary_op (insn, operands);"
15336 [(set (attr "type")
15337 (if_then_else (match_operand:SF 3 "mult_operator" "")
15338 (const_string "fmul")
15339 (const_string "fop")))
15340 (set_attr "mode" "SF")])
15342 (define_insn "*fop_sf_1_mixed"
15343 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15344 (match_operator:SF 3 "binary_fp_operator"
15345 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15346 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15347 "TARGET_MIX_SSE_I387
15348 && !COMMUTATIVE_ARITH_P (operands[3])
15349 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15350 "* return output_387_binary_op (insn, operands);"
15351 [(set (attr "type")
15352 (cond [(and (eq_attr "alternative" "2")
15353 (match_operand:SF 3 "mult_operator" ""))
15354 (const_string "ssemul")
15355 (and (eq_attr "alternative" "2")
15356 (match_operand:SF 3 "div_operator" ""))
15357 (const_string "ssediv")
15358 (eq_attr "alternative" "2")
15359 (const_string "sseadd")
15360 (match_operand:SF 3 "mult_operator" "")
15361 (const_string "fmul")
15362 (match_operand:SF 3 "div_operator" "")
15363 (const_string "fdiv")
15365 (const_string "fop")))
15366 (set_attr "mode" "SF")])
15368 (define_insn "*fop_sf_1_sse"
15369 [(set (match_operand:SF 0 "register_operand" "=x")
15370 (match_operator:SF 3 "binary_fp_operator"
15371 [(match_operand:SF 1 "register_operand" "0")
15372 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15374 && !COMMUTATIVE_ARITH_P (operands[3])"
15375 "* return output_387_binary_op (insn, operands);"
15376 [(set (attr "type")
15377 (cond [(match_operand:SF 3 "mult_operator" "")
15378 (const_string "ssemul")
15379 (match_operand:SF 3 "div_operator" "")
15380 (const_string "ssediv")
15382 (const_string "sseadd")))
15383 (set_attr "mode" "SF")])
15385 ;; This pattern is not fully shadowed by the pattern above.
15386 (define_insn "*fop_sf_1_i387"
15387 [(set (match_operand:SF 0 "register_operand" "=f,f")
15388 (match_operator:SF 3 "binary_fp_operator"
15389 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15390 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15391 "TARGET_80387 && !TARGET_SSE_MATH
15392 && !COMMUTATIVE_ARITH_P (operands[3])
15393 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15394 "* return output_387_binary_op (insn, operands);"
15395 [(set (attr "type")
15396 (cond [(match_operand:SF 3 "mult_operator" "")
15397 (const_string "fmul")
15398 (match_operand:SF 3 "div_operator" "")
15399 (const_string "fdiv")
15401 (const_string "fop")))
15402 (set_attr "mode" "SF")])
15404 ;; ??? Add SSE splitters for these!
15405 (define_insn "*fop_sf_2<mode>_i387"
15406 [(set (match_operand:SF 0 "register_operand" "=f,f")
15407 (match_operator:SF 3 "binary_fp_operator"
15408 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15409 (match_operand:SF 2 "register_operand" "0,0")]))]
15410 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15411 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15412 [(set (attr "type")
15413 (cond [(match_operand:SF 3 "mult_operator" "")
15414 (const_string "fmul")
15415 (match_operand:SF 3 "div_operator" "")
15416 (const_string "fdiv")
15418 (const_string "fop")))
15419 (set_attr "fp_int_src" "true")
15420 (set_attr "mode" "<MODE>")])
15422 (define_insn "*fop_sf_3<mode>_i387"
15423 [(set (match_operand:SF 0 "register_operand" "=f,f")
15424 (match_operator:SF 3 "binary_fp_operator"
15425 [(match_operand:SF 1 "register_operand" "0,0")
15426 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15427 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15428 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15429 [(set (attr "type")
15430 (cond [(match_operand:SF 3 "mult_operator" "")
15431 (const_string "fmul")
15432 (match_operand:SF 3 "div_operator" "")
15433 (const_string "fdiv")
15435 (const_string "fop")))
15436 (set_attr "fp_int_src" "true")
15437 (set_attr "mode" "<MODE>")])
15439 (define_insn "*fop_df_comm_mixed"
15440 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15441 (match_operator:DF 3 "binary_fp_operator"
15442 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15443 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15444 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15445 && COMMUTATIVE_ARITH_P (operands[3])
15446 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15447 "* return output_387_binary_op (insn, operands);"
15448 [(set (attr "type")
15449 (if_then_else (eq_attr "alternative" "1")
15450 (if_then_else (match_operand:DF 3 "mult_operator" "")
15451 (const_string "ssemul")
15452 (const_string "sseadd"))
15453 (if_then_else (match_operand:DF 3 "mult_operator" "")
15454 (const_string "fmul")
15455 (const_string "fop"))))
15456 (set_attr "mode" "DF")])
15458 (define_insn "*fop_df_comm_sse"
15459 [(set (match_operand:DF 0 "register_operand" "=Y")
15460 (match_operator:DF 3 "binary_fp_operator"
15461 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15462 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15463 "TARGET_SSE2 && TARGET_SSE_MATH
15464 && COMMUTATIVE_ARITH_P (operands[3])
15465 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15466 "* return output_387_binary_op (insn, operands);"
15467 [(set (attr "type")
15468 (if_then_else (match_operand:DF 3 "mult_operator" "")
15469 (const_string "ssemul")
15470 (const_string "sseadd")))
15471 (set_attr "mode" "DF")])
15473 (define_insn "*fop_df_comm_i387"
15474 [(set (match_operand:DF 0 "register_operand" "=f")
15475 (match_operator:DF 3 "binary_fp_operator"
15476 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15477 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15479 && COMMUTATIVE_ARITH_P (operands[3])
15480 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15481 "* return output_387_binary_op (insn, operands);"
15482 [(set (attr "type")
15483 (if_then_else (match_operand:DF 3 "mult_operator" "")
15484 (const_string "fmul")
15485 (const_string "fop")))
15486 (set_attr "mode" "DF")])
15488 (define_insn "*fop_df_1_mixed"
15489 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15490 (match_operator:DF 3 "binary_fp_operator"
15491 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15492 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15493 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15494 && !COMMUTATIVE_ARITH_P (operands[3])
15495 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15496 "* return output_387_binary_op (insn, operands);"
15497 [(set (attr "type")
15498 (cond [(and (eq_attr "alternative" "2")
15499 (match_operand:DF 3 "mult_operator" ""))
15500 (const_string "ssemul")
15501 (and (eq_attr "alternative" "2")
15502 (match_operand:DF 3 "div_operator" ""))
15503 (const_string "ssediv")
15504 (eq_attr "alternative" "2")
15505 (const_string "sseadd")
15506 (match_operand:DF 3 "mult_operator" "")
15507 (const_string "fmul")
15508 (match_operand:DF 3 "div_operator" "")
15509 (const_string "fdiv")
15511 (const_string "fop")))
15512 (set_attr "mode" "DF")])
15514 (define_insn "*fop_df_1_sse"
15515 [(set (match_operand:DF 0 "register_operand" "=Y")
15516 (match_operator:DF 3 "binary_fp_operator"
15517 [(match_operand:DF 1 "register_operand" "0")
15518 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15519 "TARGET_SSE2 && TARGET_SSE_MATH
15520 && !COMMUTATIVE_ARITH_P (operands[3])"
15521 "* return output_387_binary_op (insn, operands);"
15522 [(set_attr "mode" "DF")
15524 (cond [(match_operand:DF 3 "mult_operator" "")
15525 (const_string "ssemul")
15526 (match_operand:DF 3 "div_operator" "")
15527 (const_string "ssediv")
15529 (const_string "sseadd")))])
15531 ;; This pattern is not fully shadowed by the pattern above.
15532 (define_insn "*fop_df_1_i387"
15533 [(set (match_operand:DF 0 "register_operand" "=f,f")
15534 (match_operator:DF 3 "binary_fp_operator"
15535 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15536 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15537 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15538 && !COMMUTATIVE_ARITH_P (operands[3])
15539 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15540 "* return output_387_binary_op (insn, operands);"
15541 [(set (attr "type")
15542 (cond [(match_operand:DF 3 "mult_operator" "")
15543 (const_string "fmul")
15544 (match_operand:DF 3 "div_operator" "")
15545 (const_string "fdiv")
15547 (const_string "fop")))
15548 (set_attr "mode" "DF")])
15550 ;; ??? Add SSE splitters for these!
15551 (define_insn "*fop_df_2<mode>_i387"
15552 [(set (match_operand:DF 0 "register_operand" "=f,f")
15553 (match_operator:DF 3 "binary_fp_operator"
15554 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15555 (match_operand:DF 2 "register_operand" "0,0")]))]
15556 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15557 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15558 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15559 [(set (attr "type")
15560 (cond [(match_operand:DF 3 "mult_operator" "")
15561 (const_string "fmul")
15562 (match_operand:DF 3 "div_operator" "")
15563 (const_string "fdiv")
15565 (const_string "fop")))
15566 (set_attr "fp_int_src" "true")
15567 (set_attr "mode" "<MODE>")])
15569 (define_insn "*fop_df_3<mode>_i387"
15570 [(set (match_operand:DF 0 "register_operand" "=f,f")
15571 (match_operator:DF 3 "binary_fp_operator"
15572 [(match_operand:DF 1 "register_operand" "0,0")
15573 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15574 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15575 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15576 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15577 [(set (attr "type")
15578 (cond [(match_operand:DF 3 "mult_operator" "")
15579 (const_string "fmul")
15580 (match_operand:DF 3 "div_operator" "")
15581 (const_string "fdiv")
15583 (const_string "fop")))
15584 (set_attr "fp_int_src" "true")
15585 (set_attr "mode" "<MODE>")])
15587 (define_insn "*fop_df_4_i387"
15588 [(set (match_operand:DF 0 "register_operand" "=f,f")
15589 (match_operator:DF 3 "binary_fp_operator"
15590 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15591 (match_operand:DF 2 "register_operand" "0,f")]))]
15592 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15593 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15594 "* return output_387_binary_op (insn, operands);"
15595 [(set (attr "type")
15596 (cond [(match_operand:DF 3 "mult_operator" "")
15597 (const_string "fmul")
15598 (match_operand:DF 3 "div_operator" "")
15599 (const_string "fdiv")
15601 (const_string "fop")))
15602 (set_attr "mode" "SF")])
15604 (define_insn "*fop_df_5_i387"
15605 [(set (match_operand:DF 0 "register_operand" "=f,f")
15606 (match_operator:DF 3 "binary_fp_operator"
15607 [(match_operand:DF 1 "register_operand" "0,f")
15609 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15610 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15611 "* return output_387_binary_op (insn, operands);"
15612 [(set (attr "type")
15613 (cond [(match_operand:DF 3 "mult_operator" "")
15614 (const_string "fmul")
15615 (match_operand:DF 3 "div_operator" "")
15616 (const_string "fdiv")
15618 (const_string "fop")))
15619 (set_attr "mode" "SF")])
15621 (define_insn "*fop_df_6_i387"
15622 [(set (match_operand:DF 0 "register_operand" "=f,f")
15623 (match_operator:DF 3 "binary_fp_operator"
15625 (match_operand:SF 1 "register_operand" "0,f"))
15627 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15628 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15629 "* return output_387_binary_op (insn, operands);"
15630 [(set (attr "type")
15631 (cond [(match_operand:DF 3 "mult_operator" "")
15632 (const_string "fmul")
15633 (match_operand:DF 3 "div_operator" "")
15634 (const_string "fdiv")
15636 (const_string "fop")))
15637 (set_attr "mode" "SF")])
15639 (define_insn "*fop_xf_comm_i387"
15640 [(set (match_operand:XF 0 "register_operand" "=f")
15641 (match_operator:XF 3 "binary_fp_operator"
15642 [(match_operand:XF 1 "register_operand" "%0")
15643 (match_operand:XF 2 "register_operand" "f")]))]
15645 && COMMUTATIVE_ARITH_P (operands[3])"
15646 "* return output_387_binary_op (insn, operands);"
15647 [(set (attr "type")
15648 (if_then_else (match_operand:XF 3 "mult_operator" "")
15649 (const_string "fmul")
15650 (const_string "fop")))
15651 (set_attr "mode" "XF")])
15653 (define_insn "*fop_xf_1_i387"
15654 [(set (match_operand:XF 0 "register_operand" "=f,f")
15655 (match_operator:XF 3 "binary_fp_operator"
15656 [(match_operand:XF 1 "register_operand" "0,f")
15657 (match_operand:XF 2 "register_operand" "f,0")]))]
15659 && !COMMUTATIVE_ARITH_P (operands[3])"
15660 "* return output_387_binary_op (insn, operands);"
15661 [(set (attr "type")
15662 (cond [(match_operand:XF 3 "mult_operator" "")
15663 (const_string "fmul")
15664 (match_operand:XF 3 "div_operator" "")
15665 (const_string "fdiv")
15667 (const_string "fop")))
15668 (set_attr "mode" "XF")])
15670 (define_insn "*fop_xf_2<mode>_i387"
15671 [(set (match_operand:XF 0 "register_operand" "=f,f")
15672 (match_operator:XF 3 "binary_fp_operator"
15673 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15674 (match_operand:XF 2 "register_operand" "0,0")]))]
15675 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15676 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15677 [(set (attr "type")
15678 (cond [(match_operand:XF 3 "mult_operator" "")
15679 (const_string "fmul")
15680 (match_operand:XF 3 "div_operator" "")
15681 (const_string "fdiv")
15683 (const_string "fop")))
15684 (set_attr "fp_int_src" "true")
15685 (set_attr "mode" "<MODE>")])
15687 (define_insn "*fop_xf_3<mode>_i387"
15688 [(set (match_operand:XF 0 "register_operand" "=f,f")
15689 (match_operator:XF 3 "binary_fp_operator"
15690 [(match_operand:XF 1 "register_operand" "0,0")
15691 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15692 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15693 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15694 [(set (attr "type")
15695 (cond [(match_operand:XF 3 "mult_operator" "")
15696 (const_string "fmul")
15697 (match_operand:XF 3 "div_operator" "")
15698 (const_string "fdiv")
15700 (const_string "fop")))
15701 (set_attr "fp_int_src" "true")
15702 (set_attr "mode" "<MODE>")])
15704 (define_insn "*fop_xf_4_i387"
15705 [(set (match_operand:XF 0 "register_operand" "=f,f")
15706 (match_operator:XF 3 "binary_fp_operator"
15708 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15709 (match_operand:XF 2 "register_operand" "0,f")]))]
15711 "* return output_387_binary_op (insn, operands);"
15712 [(set (attr "type")
15713 (cond [(match_operand:XF 3 "mult_operator" "")
15714 (const_string "fmul")
15715 (match_operand:XF 3 "div_operator" "")
15716 (const_string "fdiv")
15718 (const_string "fop")))
15719 (set_attr "mode" "SF")])
15721 (define_insn "*fop_xf_5_i387"
15722 [(set (match_operand:XF 0 "register_operand" "=f,f")
15723 (match_operator:XF 3 "binary_fp_operator"
15724 [(match_operand:XF 1 "register_operand" "0,f")
15726 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15728 "* return output_387_binary_op (insn, operands);"
15729 [(set (attr "type")
15730 (cond [(match_operand:XF 3 "mult_operator" "")
15731 (const_string "fmul")
15732 (match_operand:XF 3 "div_operator" "")
15733 (const_string "fdiv")
15735 (const_string "fop")))
15736 (set_attr "mode" "SF")])
15738 (define_insn "*fop_xf_6_i387"
15739 [(set (match_operand:XF 0 "register_operand" "=f,f")
15740 (match_operator:XF 3 "binary_fp_operator"
15742 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15744 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15746 "* return output_387_binary_op (insn, operands);"
15747 [(set (attr "type")
15748 (cond [(match_operand:XF 3 "mult_operator" "")
15749 (const_string "fmul")
15750 (match_operand:XF 3 "div_operator" "")
15751 (const_string "fdiv")
15753 (const_string "fop")))
15754 (set_attr "mode" "SF")])
15757 [(set (match_operand 0 "register_operand" "")
15758 (match_operator 3 "binary_fp_operator"
15759 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15760 (match_operand 2 "register_operand" "")]))]
15761 "TARGET_80387 && reload_completed
15762 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15765 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15766 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15767 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15768 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15769 GET_MODE (operands[3]),
15772 ix86_free_from_memory (GET_MODE (operands[1]));
15777 [(set (match_operand 0 "register_operand" "")
15778 (match_operator 3 "binary_fp_operator"
15779 [(match_operand 1 "register_operand" "")
15780 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15781 "TARGET_80387 && reload_completed
15782 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15785 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15786 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15787 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15788 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15789 GET_MODE (operands[3]),
15792 ix86_free_from_memory (GET_MODE (operands[2]));
15796 ;; FPU special functions.
15798 ;; This pattern implements a no-op XFmode truncation for
15799 ;; all fancy i386 XFmode math functions.
15801 (define_insn "truncxf<mode>2_i387_noop_unspec"
15802 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15803 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15804 UNSPEC_TRUNC_NOOP))]
15805 "TARGET_USE_FANCY_MATH_387"
15806 "* return output_387_reg_move (insn, operands);"
15807 [(set_attr "type" "fmov")
15808 (set_attr "mode" "<MODE>")])
15810 (define_insn "sqrtxf2"
15811 [(set (match_operand:XF 0 "register_operand" "=f")
15812 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15813 "TARGET_USE_FANCY_MATH_387"
15815 [(set_attr "type" "fpspc")
15816 (set_attr "mode" "XF")
15817 (set_attr "athlon_decode" "direct")
15818 (set_attr "amdfam10_decode" "direct")])
15820 (define_insn "sqrt_extend<mode>xf2_i387"
15821 [(set (match_operand:XF 0 "register_operand" "=f")
15824 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15825 "TARGET_USE_FANCY_MATH_387"
15827 [(set_attr "type" "fpspc")
15828 (set_attr "mode" "XF")
15829 (set_attr "athlon_decode" "direct")
15830 (set_attr "amdfam10_decode" "direct")])
15832 (define_insn "*sqrt<mode>2_sse"
15833 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15835 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15836 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15837 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15838 [(set_attr "type" "sse")
15839 (set_attr "mode" "<MODE>")
15840 (set_attr "athlon_decode" "*")
15841 (set_attr "amdfam10_decode" "*")])
15843 (define_expand "sqrt<mode>2"
15844 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15846 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15847 "TARGET_USE_FANCY_MATH_387
15848 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15850 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15852 rtx op0 = gen_reg_rtx (XFmode);
15853 rtx op1 = force_reg (<MODE>mode, operands[1]);
15855 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15856 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15861 (define_insn "fpremxf4_i387"
15862 [(set (match_operand:XF 0 "register_operand" "=f")
15863 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15864 (match_operand:XF 3 "register_operand" "1")]
15866 (set (match_operand:XF 1 "register_operand" "=u")
15867 (unspec:XF [(match_dup 2) (match_dup 3)]
15869 (set (reg:CCFP FPSR_REG)
15870 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15871 "TARGET_USE_FANCY_MATH_387"
15873 [(set_attr "type" "fpspc")
15874 (set_attr "mode" "XF")])
15876 (define_expand "fmodxf3"
15877 [(use (match_operand:XF 0 "register_operand" ""))
15878 (use (match_operand:XF 1 "register_operand" ""))
15879 (use (match_operand:XF 2 "register_operand" ""))]
15880 "TARGET_USE_FANCY_MATH_387"
15882 rtx label = gen_label_rtx ();
15884 emit_label (label);
15886 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15887 operands[1], operands[2]));
15888 ix86_emit_fp_unordered_jump (label);
15890 emit_move_insn (operands[0], operands[1]);
15894 (define_expand "fmod<mode>3"
15895 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15896 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15897 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15898 "TARGET_USE_FANCY_MATH_387"
15900 rtx label = gen_label_rtx ();
15902 rtx op1 = gen_reg_rtx (XFmode);
15903 rtx op2 = gen_reg_rtx (XFmode);
15905 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15906 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15908 emit_label (label);
15909 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15910 ix86_emit_fp_unordered_jump (label);
15912 /* Truncate the result properly for strict SSE math. */
15913 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15914 && !TARGET_MIX_SSE_I387)
15915 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15917 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15922 (define_insn "fprem1xf4_i387"
15923 [(set (match_operand:XF 0 "register_operand" "=f")
15924 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15925 (match_operand:XF 3 "register_operand" "1")]
15927 (set (match_operand:XF 1 "register_operand" "=u")
15928 (unspec:XF [(match_dup 2) (match_dup 3)]
15930 (set (reg:CCFP FPSR_REG)
15931 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15932 "TARGET_USE_FANCY_MATH_387"
15934 [(set_attr "type" "fpspc")
15935 (set_attr "mode" "XF")])
15937 (define_expand "remainderxf3"
15938 [(use (match_operand:XF 0 "register_operand" ""))
15939 (use (match_operand:XF 1 "register_operand" ""))
15940 (use (match_operand:XF 2 "register_operand" ""))]
15941 "TARGET_USE_FANCY_MATH_387"
15943 rtx label = gen_label_rtx ();
15945 emit_label (label);
15947 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15948 operands[1], operands[2]));
15949 ix86_emit_fp_unordered_jump (label);
15951 emit_move_insn (operands[0], operands[1]);
15955 (define_expand "remainder<mode>3"
15956 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15957 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15958 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15959 "TARGET_USE_FANCY_MATH_387"
15961 rtx label = gen_label_rtx ();
15963 rtx op1 = gen_reg_rtx (XFmode);
15964 rtx op2 = gen_reg_rtx (XFmode);
15966 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15967 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15969 emit_label (label);
15971 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15972 ix86_emit_fp_unordered_jump (label);
15974 /* Truncate the result properly for strict SSE math. */
15975 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15976 && !TARGET_MIX_SSE_I387)
15977 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15979 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15984 (define_insn "*sinxf2_i387"
15985 [(set (match_operand:XF 0 "register_operand" "=f")
15986 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15987 "TARGET_USE_FANCY_MATH_387
15988 && flag_unsafe_math_optimizations"
15990 [(set_attr "type" "fpspc")
15991 (set_attr "mode" "XF")])
15993 (define_insn "*sin_extend<mode>xf2_i387"
15994 [(set (match_operand:XF 0 "register_operand" "=f")
15995 (unspec:XF [(float_extend:XF
15996 (match_operand:X87MODEF12 1 "register_operand" "0"))]
15998 "TARGET_USE_FANCY_MATH_387
15999 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16000 || TARGET_MIX_SSE_I387)
16001 && flag_unsafe_math_optimizations"
16003 [(set_attr "type" "fpspc")
16004 (set_attr "mode" "XF")])
16006 (define_insn "*cosxf2_i387"
16007 [(set (match_operand:XF 0 "register_operand" "=f")
16008 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16009 "TARGET_USE_FANCY_MATH_387
16010 && flag_unsafe_math_optimizations"
16012 [(set_attr "type" "fpspc")
16013 (set_attr "mode" "XF")])
16015 (define_insn "*cos_extend<mode>xf2_i387"
16016 [(set (match_operand:XF 0 "register_operand" "=f")
16017 (unspec:XF [(float_extend:XF
16018 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16020 "TARGET_USE_FANCY_MATH_387
16021 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16022 || TARGET_MIX_SSE_I387)
16023 && flag_unsafe_math_optimizations"
16025 [(set_attr "type" "fpspc")
16026 (set_attr "mode" "XF")])
16028 ;; When sincos pattern is defined, sin and cos builtin functions will be
16029 ;; expanded to sincos pattern with one of its outputs left unused.
16030 ;; CSE pass will figure out if two sincos patterns can be combined,
16031 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16032 ;; depending on the unused output.
16034 (define_insn "sincosxf3"
16035 [(set (match_operand:XF 0 "register_operand" "=f")
16036 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16037 UNSPEC_SINCOS_COS))
16038 (set (match_operand:XF 1 "register_operand" "=u")
16039 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16040 "TARGET_USE_FANCY_MATH_387
16041 && flag_unsafe_math_optimizations"
16043 [(set_attr "type" "fpspc")
16044 (set_attr "mode" "XF")])
16047 [(set (match_operand:XF 0 "register_operand" "")
16048 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16049 UNSPEC_SINCOS_COS))
16050 (set (match_operand:XF 1 "register_operand" "")
16051 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16052 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16053 && !reload_completed && !reload_in_progress"
16054 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16058 [(set (match_operand:XF 0 "register_operand" "")
16059 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16060 UNSPEC_SINCOS_COS))
16061 (set (match_operand:XF 1 "register_operand" "")
16062 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16063 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16064 && !reload_completed && !reload_in_progress"
16065 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16068 (define_insn "sincos_extend<mode>xf3_i387"
16069 [(set (match_operand:XF 0 "register_operand" "=f")
16070 (unspec:XF [(float_extend:XF
16071 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16072 UNSPEC_SINCOS_COS))
16073 (set (match_operand:XF 1 "register_operand" "=u")
16074 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16075 "TARGET_USE_FANCY_MATH_387
16076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16077 || TARGET_MIX_SSE_I387)
16078 && flag_unsafe_math_optimizations"
16080 [(set_attr "type" "fpspc")
16081 (set_attr "mode" "XF")])
16084 [(set (match_operand:XF 0 "register_operand" "")
16085 (unspec:XF [(float_extend:XF
16086 (match_operand:X87MODEF12 2 "register_operand" ""))]
16087 UNSPEC_SINCOS_COS))
16088 (set (match_operand:XF 1 "register_operand" "")
16089 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16090 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16091 && !reload_completed && !reload_in_progress"
16092 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16096 [(set (match_operand:XF 0 "register_operand" "")
16097 (unspec:XF [(float_extend:XF
16098 (match_operand:X87MODEF12 2 "register_operand" ""))]
16099 UNSPEC_SINCOS_COS))
16100 (set (match_operand:XF 1 "register_operand" "")
16101 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16102 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16103 && !reload_completed && !reload_in_progress"
16104 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16107 (define_expand "sincos<mode>3"
16108 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16109 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16110 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16111 "TARGET_USE_FANCY_MATH_387
16112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16113 || TARGET_MIX_SSE_I387)
16114 && flag_unsafe_math_optimizations"
16116 rtx op0 = gen_reg_rtx (XFmode);
16117 rtx op1 = gen_reg_rtx (XFmode);
16119 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16120 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16121 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16125 (define_insn "fptanxf4_i387"
16126 [(set (match_operand:XF 0 "register_operand" "=f")
16127 (match_operand:XF 3 "const_double_operand" "F"))
16128 (set (match_operand:XF 1 "register_operand" "=u")
16129 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16131 "TARGET_USE_FANCY_MATH_387
16132 && flag_unsafe_math_optimizations
16133 && standard_80387_constant_p (operands[3]) == 2"
16135 [(set_attr "type" "fpspc")
16136 (set_attr "mode" "XF")])
16138 (define_insn "fptan_extend<mode>xf4_i387"
16139 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16140 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16141 (set (match_operand:XF 1 "register_operand" "=u")
16142 (unspec:XF [(float_extend:XF
16143 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16145 "TARGET_USE_FANCY_MATH_387
16146 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16147 || TARGET_MIX_SSE_I387)
16148 && flag_unsafe_math_optimizations
16149 && standard_80387_constant_p (operands[3]) == 2"
16151 [(set_attr "type" "fpspc")
16152 (set_attr "mode" "XF")])
16154 (define_expand "tanxf2"
16155 [(use (match_operand:XF 0 "register_operand" ""))
16156 (use (match_operand:XF 1 "register_operand" ""))]
16157 "TARGET_USE_FANCY_MATH_387
16158 && flag_unsafe_math_optimizations"
16160 rtx one = gen_reg_rtx (XFmode);
16161 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16163 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16167 (define_expand "tan<mode>2"
16168 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16169 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16170 "TARGET_USE_FANCY_MATH_387
16171 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16172 || TARGET_MIX_SSE_I387)
16173 && flag_unsafe_math_optimizations"
16175 rtx op0 = gen_reg_rtx (XFmode);
16177 rtx one = gen_reg_rtx (<MODE>mode);
16178 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16180 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16181 operands[1], op2));
16182 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16186 (define_insn "*fpatanxf3_i387"
16187 [(set (match_operand:XF 0 "register_operand" "=f")
16188 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16189 (match_operand:XF 2 "register_operand" "u")]
16191 (clobber (match_scratch:XF 3 "=2"))]
16192 "TARGET_USE_FANCY_MATH_387
16193 && flag_unsafe_math_optimizations"
16195 [(set_attr "type" "fpspc")
16196 (set_attr "mode" "XF")])
16198 (define_insn "fpatan_extend<mode>xf3_i387"
16199 [(set (match_operand:XF 0 "register_operand" "=f")
16200 (unspec:XF [(float_extend:XF
16201 (match_operand:X87MODEF12 1 "register_operand" "0"))
16203 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16205 (clobber (match_scratch:XF 3 "=2"))]
16206 "TARGET_USE_FANCY_MATH_387
16207 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16208 || TARGET_MIX_SSE_I387)
16209 && flag_unsafe_math_optimizations"
16211 [(set_attr "type" "fpspc")
16212 (set_attr "mode" "XF")])
16214 (define_expand "atan2xf3"
16215 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16216 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16217 (match_operand:XF 1 "register_operand" "")]
16219 (clobber (match_scratch:XF 3 ""))])]
16220 "TARGET_USE_FANCY_MATH_387
16221 && flag_unsafe_math_optimizations"
16224 (define_expand "atan2<mode>3"
16225 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16226 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16227 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16228 "TARGET_USE_FANCY_MATH_387
16229 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16230 || TARGET_MIX_SSE_I387)
16231 && flag_unsafe_math_optimizations"
16233 rtx op0 = gen_reg_rtx (XFmode);
16235 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16236 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16240 (define_expand "atanxf2"
16241 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16242 (unspec:XF [(match_dup 2)
16243 (match_operand:XF 1 "register_operand" "")]
16245 (clobber (match_scratch:XF 3 ""))])]
16246 "TARGET_USE_FANCY_MATH_387
16247 && flag_unsafe_math_optimizations"
16249 operands[2] = gen_reg_rtx (XFmode);
16250 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16253 (define_expand "atan<mode>2"
16254 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16255 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16256 "TARGET_USE_FANCY_MATH_387
16257 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16258 || TARGET_MIX_SSE_I387)
16259 && flag_unsafe_math_optimizations"
16261 rtx op0 = gen_reg_rtx (XFmode);
16263 rtx op2 = gen_reg_rtx (<MODE>mode);
16264 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16266 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16267 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16271 (define_expand "asinxf2"
16272 [(set (match_dup 2)
16273 (mult:XF (match_operand:XF 1 "register_operand" "")
16275 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16276 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16277 (parallel [(set (match_operand:XF 0 "register_operand" "")
16278 (unspec:XF [(match_dup 5) (match_dup 1)]
16280 (clobber (match_scratch:XF 6 ""))])]
16281 "TARGET_USE_FANCY_MATH_387
16282 && flag_unsafe_math_optimizations && !optimize_size"
16286 for (i = 2; i < 6; i++)
16287 operands[i] = gen_reg_rtx (XFmode);
16289 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16292 (define_expand "asin<mode>2"
16293 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16294 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16295 "TARGET_USE_FANCY_MATH_387
16296 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16297 || TARGET_MIX_SSE_I387)
16298 && flag_unsafe_math_optimizations && !optimize_size"
16300 rtx op0 = gen_reg_rtx (XFmode);
16301 rtx op1 = gen_reg_rtx (XFmode);
16303 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16304 emit_insn (gen_asinxf2 (op0, op1));
16305 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16309 (define_expand "acosxf2"
16310 [(set (match_dup 2)
16311 (mult:XF (match_operand:XF 1 "register_operand" "")
16313 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16314 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16315 (parallel [(set (match_operand:XF 0 "register_operand" "")
16316 (unspec:XF [(match_dup 1) (match_dup 5)]
16318 (clobber (match_scratch:XF 6 ""))])]
16319 "TARGET_USE_FANCY_MATH_387
16320 && flag_unsafe_math_optimizations && !optimize_size"
16324 for (i = 2; i < 6; i++)
16325 operands[i] = gen_reg_rtx (XFmode);
16327 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16330 (define_expand "acos<mode>2"
16331 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16332 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16333 "TARGET_USE_FANCY_MATH_387
16334 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16335 || TARGET_MIX_SSE_I387)
16336 && flag_unsafe_math_optimizations && !optimize_size"
16338 rtx op0 = gen_reg_rtx (XFmode);
16339 rtx op1 = gen_reg_rtx (XFmode);
16341 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16342 emit_insn (gen_acosxf2 (op0, op1));
16343 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16347 (define_insn "fyl2xxf3_i387"
16348 [(set (match_operand:XF 0 "register_operand" "=f")
16349 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16350 (match_operand:XF 2 "register_operand" "u")]
16352 (clobber (match_scratch:XF 3 "=2"))]
16353 "TARGET_USE_FANCY_MATH_387
16354 && flag_unsafe_math_optimizations"
16356 [(set_attr "type" "fpspc")
16357 (set_attr "mode" "XF")])
16359 (define_insn "fyl2x_extend<mode>xf3_i387"
16360 [(set (match_operand:XF 0 "register_operand" "=f")
16361 (unspec:XF [(float_extend:XF
16362 (match_operand:X87MODEF12 1 "register_operand" "0"))
16363 (match_operand:XF 2 "register_operand" "u")]
16365 (clobber (match_scratch:XF 3 "=2"))]
16366 "TARGET_USE_FANCY_MATH_387
16367 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16368 || TARGET_MIX_SSE_I387)
16369 && flag_unsafe_math_optimizations"
16371 [(set_attr "type" "fpspc")
16372 (set_attr "mode" "XF")])
16374 (define_expand "logxf2"
16375 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16376 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16377 (match_dup 2)] UNSPEC_FYL2X))
16378 (clobber (match_scratch:XF 3 ""))])]
16379 "TARGET_USE_FANCY_MATH_387
16380 && flag_unsafe_math_optimizations"
16382 operands[2] = gen_reg_rtx (XFmode);
16383 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16386 (define_expand "log<mode>2"
16387 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16388 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16389 "TARGET_USE_FANCY_MATH_387
16390 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16391 || TARGET_MIX_SSE_I387)
16392 && flag_unsafe_math_optimizations"
16394 rtx op0 = gen_reg_rtx (XFmode);
16396 rtx op2 = gen_reg_rtx (XFmode);
16397 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16399 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16400 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16404 (define_expand "log10xf2"
16405 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16406 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16407 (match_dup 2)] UNSPEC_FYL2X))
16408 (clobber (match_scratch:XF 3 ""))])]
16409 "TARGET_USE_FANCY_MATH_387
16410 && flag_unsafe_math_optimizations"
16412 operands[2] = gen_reg_rtx (XFmode);
16413 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16416 (define_expand "log10<mode>2"
16417 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16418 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16419 "TARGET_USE_FANCY_MATH_387
16420 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16421 || TARGET_MIX_SSE_I387)
16422 && flag_unsafe_math_optimizations"
16424 rtx op0 = gen_reg_rtx (XFmode);
16426 rtx op2 = gen_reg_rtx (XFmode);
16427 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16429 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16430 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16434 (define_expand "log2xf2"
16435 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16436 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16437 (match_dup 2)] UNSPEC_FYL2X))
16438 (clobber (match_scratch:XF 3 ""))])]
16439 "TARGET_USE_FANCY_MATH_387
16440 && flag_unsafe_math_optimizations"
16442 operands[2] = gen_reg_rtx (XFmode);
16443 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16446 (define_expand "log2<mode>2"
16447 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16448 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16449 "TARGET_USE_FANCY_MATH_387
16450 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16451 || TARGET_MIX_SSE_I387)
16452 && flag_unsafe_math_optimizations"
16454 rtx op0 = gen_reg_rtx (XFmode);
16456 rtx op2 = gen_reg_rtx (XFmode);
16457 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16459 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16460 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16464 (define_insn "fyl2xp1xf3_i387"
16465 [(set (match_operand:XF 0 "register_operand" "=f")
16466 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16467 (match_operand:XF 2 "register_operand" "u")]
16469 (clobber (match_scratch:XF 3 "=2"))]
16470 "TARGET_USE_FANCY_MATH_387
16471 && flag_unsafe_math_optimizations"
16473 [(set_attr "type" "fpspc")
16474 (set_attr "mode" "XF")])
16476 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16477 [(set (match_operand:XF 0 "register_operand" "=f")
16478 (unspec:XF [(float_extend:XF
16479 (match_operand:X87MODEF12 1 "register_operand" "0"))
16480 (match_operand:XF 2 "register_operand" "u")]
16482 (clobber (match_scratch:XF 3 "=2"))]
16483 "TARGET_USE_FANCY_MATH_387
16484 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16485 || TARGET_MIX_SSE_I387)
16486 && flag_unsafe_math_optimizations"
16488 [(set_attr "type" "fpspc")
16489 (set_attr "mode" "XF")])
16491 (define_expand "log1pxf2"
16492 [(use (match_operand:XF 0 "register_operand" ""))
16493 (use (match_operand:XF 1 "register_operand" ""))]
16494 "TARGET_USE_FANCY_MATH_387
16495 && flag_unsafe_math_optimizations && !optimize_size"
16497 ix86_emit_i387_log1p (operands[0], operands[1]);
16501 (define_expand "log1p<mode>2"
16502 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16503 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16504 "TARGET_USE_FANCY_MATH_387
16505 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16506 || TARGET_MIX_SSE_I387)
16507 && flag_unsafe_math_optimizations && !optimize_size"
16509 rtx op0 = gen_reg_rtx (XFmode);
16511 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16513 ix86_emit_i387_log1p (op0, operands[1]);
16514 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16518 (define_insn "fxtractxf3_i387"
16519 [(set (match_operand:XF 0 "register_operand" "=f")
16520 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16521 UNSPEC_XTRACT_FRACT))
16522 (set (match_operand:XF 1 "register_operand" "=u")
16523 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16524 "TARGET_USE_FANCY_MATH_387
16525 && flag_unsafe_math_optimizations"
16527 [(set_attr "type" "fpspc")
16528 (set_attr "mode" "XF")])
16530 (define_insn "fxtract_extend<mode>xf3_i387"
16531 [(set (match_operand:XF 0 "register_operand" "=f")
16532 (unspec:XF [(float_extend:XF
16533 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16534 UNSPEC_XTRACT_FRACT))
16535 (set (match_operand:XF 1 "register_operand" "=u")
16536 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16537 "TARGET_USE_FANCY_MATH_387
16538 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16539 || TARGET_MIX_SSE_I387)
16540 && flag_unsafe_math_optimizations"
16542 [(set_attr "type" "fpspc")
16543 (set_attr "mode" "XF")])
16545 (define_expand "logbxf2"
16546 [(parallel [(set (match_dup 2)
16547 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16548 UNSPEC_XTRACT_FRACT))
16549 (set (match_operand:XF 0 "register_operand" "")
16550 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16551 "TARGET_USE_FANCY_MATH_387
16552 && flag_unsafe_math_optimizations"
16554 operands[2] = gen_reg_rtx (XFmode);
16557 (define_expand "logb<mode>2"
16558 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16559 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16560 "TARGET_USE_FANCY_MATH_387
16561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16562 || TARGET_MIX_SSE_I387)
16563 && flag_unsafe_math_optimizations"
16565 rtx op0 = gen_reg_rtx (XFmode);
16566 rtx op1 = gen_reg_rtx (XFmode);
16568 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16569 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16573 (define_expand "ilogbxf2"
16574 [(use (match_operand:SI 0 "register_operand" ""))
16575 (use (match_operand:XF 1 "register_operand" ""))]
16576 "TARGET_USE_FANCY_MATH_387
16577 && flag_unsafe_math_optimizations && !optimize_size"
16579 rtx op0 = gen_reg_rtx (XFmode);
16580 rtx op1 = gen_reg_rtx (XFmode);
16582 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16583 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16587 (define_expand "ilogb<mode>2"
16588 [(use (match_operand:SI 0 "register_operand" ""))
16589 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16590 "TARGET_USE_FANCY_MATH_387
16591 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16592 || TARGET_MIX_SSE_I387)
16593 && flag_unsafe_math_optimizations && !optimize_size"
16595 rtx op0 = gen_reg_rtx (XFmode);
16596 rtx op1 = gen_reg_rtx (XFmode);
16598 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16599 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16603 (define_insn "*f2xm1xf2_i387"
16604 [(set (match_operand:XF 0 "register_operand" "=f")
16605 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16607 "TARGET_USE_FANCY_MATH_387
16608 && flag_unsafe_math_optimizations"
16610 [(set_attr "type" "fpspc")
16611 (set_attr "mode" "XF")])
16613 (define_insn "*fscalexf4_i387"
16614 [(set (match_operand:XF 0 "register_operand" "=f")
16615 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16616 (match_operand:XF 3 "register_operand" "1")]
16617 UNSPEC_FSCALE_FRACT))
16618 (set (match_operand:XF 1 "register_operand" "=u")
16619 (unspec:XF [(match_dup 2) (match_dup 3)]
16620 UNSPEC_FSCALE_EXP))]
16621 "TARGET_USE_FANCY_MATH_387
16622 && flag_unsafe_math_optimizations"
16624 [(set_attr "type" "fpspc")
16625 (set_attr "mode" "XF")])
16627 (define_expand "expNcorexf3"
16628 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16629 (match_operand:XF 2 "register_operand" "")))
16630 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16631 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16632 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16633 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16634 (parallel [(set (match_operand:XF 0 "register_operand" "")
16635 (unspec:XF [(match_dup 8) (match_dup 4)]
16636 UNSPEC_FSCALE_FRACT))
16638 (unspec:XF [(match_dup 8) (match_dup 4)]
16639 UNSPEC_FSCALE_EXP))])]
16640 "TARGET_USE_FANCY_MATH_387
16641 && flag_unsafe_math_optimizations && !optimize_size"
16645 for (i = 3; i < 10; i++)
16646 operands[i] = gen_reg_rtx (XFmode);
16648 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16651 (define_expand "expxf2"
16652 [(use (match_operand:XF 0 "register_operand" ""))
16653 (use (match_operand:XF 1 "register_operand" ""))]
16654 "TARGET_USE_FANCY_MATH_387
16655 && flag_unsafe_math_optimizations && !optimize_size"
16657 rtx op2 = gen_reg_rtx (XFmode);
16658 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16660 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16664 (define_expand "exp<mode>2"
16665 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16666 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16667 "TARGET_USE_FANCY_MATH_387
16668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16669 || TARGET_MIX_SSE_I387)
16670 && flag_unsafe_math_optimizations && !optimize_size"
16672 rtx op0 = gen_reg_rtx (XFmode);
16673 rtx op1 = gen_reg_rtx (XFmode);
16675 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16676 emit_insn (gen_expxf2 (op0, op1));
16677 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16681 (define_expand "exp10xf2"
16682 [(use (match_operand:XF 0 "register_operand" ""))
16683 (use (match_operand:XF 1 "register_operand" ""))]
16684 "TARGET_USE_FANCY_MATH_387
16685 && flag_unsafe_math_optimizations && !optimize_size"
16687 rtx op2 = gen_reg_rtx (XFmode);
16688 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16690 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16694 (define_expand "exp10<mode>2"
16695 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16696 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16697 "TARGET_USE_FANCY_MATH_387
16698 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16699 || TARGET_MIX_SSE_I387)
16700 && flag_unsafe_math_optimizations && !optimize_size"
16702 rtx op0 = gen_reg_rtx (XFmode);
16703 rtx op1 = gen_reg_rtx (XFmode);
16705 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16706 emit_insn (gen_exp10xf2 (op0, op1));
16707 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16711 (define_expand "exp2xf2"
16712 [(use (match_operand:XF 0 "register_operand" ""))
16713 (use (match_operand:XF 1 "register_operand" ""))]
16714 "TARGET_USE_FANCY_MATH_387
16715 && flag_unsafe_math_optimizations && !optimize_size"
16717 rtx op2 = gen_reg_rtx (XFmode);
16718 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16720 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16724 (define_expand "exp2<mode>2"
16725 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16726 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16727 "TARGET_USE_FANCY_MATH_387
16728 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16729 || TARGET_MIX_SSE_I387)
16730 && flag_unsafe_math_optimizations && !optimize_size"
16732 rtx op0 = gen_reg_rtx (XFmode);
16733 rtx op1 = gen_reg_rtx (XFmode);
16735 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16736 emit_insn (gen_exp2xf2 (op0, op1));
16737 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16741 (define_expand "expm1xf2"
16742 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16744 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16745 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16746 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16747 (parallel [(set (match_dup 7)
16748 (unspec:XF [(match_dup 6) (match_dup 4)]
16749 UNSPEC_FSCALE_FRACT))
16751 (unspec:XF [(match_dup 6) (match_dup 4)]
16752 UNSPEC_FSCALE_EXP))])
16753 (parallel [(set (match_dup 10)
16754 (unspec:XF [(match_dup 9) (match_dup 8)]
16755 UNSPEC_FSCALE_FRACT))
16756 (set (match_dup 11)
16757 (unspec:XF [(match_dup 9) (match_dup 8)]
16758 UNSPEC_FSCALE_EXP))])
16759 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16760 (set (match_operand:XF 0 "register_operand" "")
16761 (plus:XF (match_dup 12) (match_dup 7)))]
16762 "TARGET_USE_FANCY_MATH_387
16763 && flag_unsafe_math_optimizations && !optimize_size"
16767 for (i = 2; i < 13; i++)
16768 operands[i] = gen_reg_rtx (XFmode);
16770 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16771 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16774 (define_expand "expm1<mode>2"
16775 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16776 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16777 "TARGET_USE_FANCY_MATH_387
16778 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16779 || TARGET_MIX_SSE_I387)
16780 && flag_unsafe_math_optimizations && !optimize_size"
16782 rtx op0 = gen_reg_rtx (XFmode);
16783 rtx op1 = gen_reg_rtx (XFmode);
16785 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16786 emit_insn (gen_expm1xf2 (op0, op1));
16787 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16791 (define_expand "ldexpxf3"
16792 [(set (match_dup 3)
16793 (float:XF (match_operand:SI 2 "register_operand" "")))
16794 (parallel [(set (match_operand:XF 0 " register_operand" "")
16795 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16797 UNSPEC_FSCALE_FRACT))
16799 (unspec:XF [(match_dup 1) (match_dup 3)]
16800 UNSPEC_FSCALE_EXP))])]
16801 "TARGET_USE_FANCY_MATH_387
16802 && flag_unsafe_math_optimizations && !optimize_size"
16804 operands[3] = gen_reg_rtx (XFmode);
16805 operands[4] = gen_reg_rtx (XFmode);
16808 (define_expand "ldexp<mode>3"
16809 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16810 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16811 (use (match_operand:SI 2 "register_operand" ""))]
16812 "TARGET_USE_FANCY_MATH_387
16813 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16814 || TARGET_MIX_SSE_I387)
16815 && flag_unsafe_math_optimizations && !optimize_size"
16817 rtx op0 = gen_reg_rtx (XFmode);
16818 rtx op1 = gen_reg_rtx (XFmode);
16820 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16821 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16822 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16827 (define_insn "frndintxf2"
16828 [(set (match_operand:XF 0 "register_operand" "=f")
16829 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16831 "TARGET_USE_FANCY_MATH_387
16832 && flag_unsafe_math_optimizations"
16834 [(set_attr "type" "fpspc")
16835 (set_attr "mode" "XF")])
16837 (define_expand "rintdf2"
16838 [(use (match_operand:DF 0 "register_operand" ""))
16839 (use (match_operand:DF 1 "register_operand" ""))]
16840 "(TARGET_USE_FANCY_MATH_387
16841 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16842 && flag_unsafe_math_optimizations)
16843 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16844 && !flag_trapping_math
16845 && !optimize_size)"
16847 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16848 && !flag_trapping_math
16850 ix86_expand_rint (operand0, operand1);
16853 rtx op0 = gen_reg_rtx (XFmode);
16854 rtx op1 = gen_reg_rtx (XFmode);
16856 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16857 emit_insn (gen_frndintxf2 (op0, op1));
16859 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16864 (define_expand "rintsf2"
16865 [(use (match_operand:SF 0 "register_operand" ""))
16866 (use (match_operand:SF 1 "register_operand" ""))]
16867 "(TARGET_USE_FANCY_MATH_387
16868 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16869 && flag_unsafe_math_optimizations)
16870 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16871 && !flag_trapping_math
16872 && !optimize_size)"
16874 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16875 && !flag_trapping_math
16877 ix86_expand_rint (operand0, operand1);
16880 rtx op0 = gen_reg_rtx (XFmode);
16881 rtx op1 = gen_reg_rtx (XFmode);
16883 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16884 emit_insn (gen_frndintxf2 (op0, op1));
16886 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16891 (define_expand "rintxf2"
16892 [(use (match_operand:XF 0 "register_operand" ""))
16893 (use (match_operand:XF 1 "register_operand" ""))]
16894 "TARGET_USE_FANCY_MATH_387
16895 && flag_unsafe_math_optimizations && !optimize_size"
16897 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16901 (define_expand "roundsf2"
16902 [(match_operand:SF 0 "register_operand" "")
16903 (match_operand:SF 1 "nonimmediate_operand" "")]
16904 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16905 && !flag_trapping_math && !flag_rounding_math
16908 ix86_expand_round (operand0, operand1);
16912 (define_expand "rounddf2"
16913 [(match_operand:DF 0 "register_operand" "")
16914 (match_operand:DF 1 "nonimmediate_operand" "")]
16915 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16916 && !flag_trapping_math && !flag_rounding_math
16920 ix86_expand_round (operand0, operand1);
16922 ix86_expand_rounddf_32 (operand0, operand1);
16926 (define_insn_and_split "*fistdi2_1"
16927 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16928 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16930 "TARGET_USE_FANCY_MATH_387
16931 && !(reload_completed || reload_in_progress)"
16936 if (memory_operand (operands[0], VOIDmode))
16937 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16940 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16941 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16946 [(set_attr "type" "fpspc")
16947 (set_attr "mode" "DI")])
16949 (define_insn "fistdi2"
16950 [(set (match_operand:DI 0 "memory_operand" "=m")
16951 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16953 (clobber (match_scratch:XF 2 "=&1f"))]
16954 "TARGET_USE_FANCY_MATH_387"
16955 "* return output_fix_trunc (insn, operands, 0);"
16956 [(set_attr "type" "fpspc")
16957 (set_attr "mode" "DI")])
16959 (define_insn "fistdi2_with_temp"
16960 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16961 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16963 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16964 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16965 "TARGET_USE_FANCY_MATH_387"
16967 [(set_attr "type" "fpspc")
16968 (set_attr "mode" "DI")])
16971 [(set (match_operand:DI 0 "register_operand" "")
16972 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16974 (clobber (match_operand:DI 2 "memory_operand" ""))
16975 (clobber (match_scratch 3 ""))]
16977 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16978 (clobber (match_dup 3))])
16979 (set (match_dup 0) (match_dup 2))]
16983 [(set (match_operand:DI 0 "memory_operand" "")
16984 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16986 (clobber (match_operand:DI 2 "memory_operand" ""))
16987 (clobber (match_scratch 3 ""))]
16989 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16990 (clobber (match_dup 3))])]
16993 (define_insn_and_split "*fist<mode>2_1"
16994 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16995 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16997 "TARGET_USE_FANCY_MATH_387
16998 && !(reload_completed || reload_in_progress)"
17003 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17004 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17008 [(set_attr "type" "fpspc")
17009 (set_attr "mode" "<MODE>")])
17011 (define_insn "fist<mode>2"
17012 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17013 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17015 "TARGET_USE_FANCY_MATH_387"
17016 "* return output_fix_trunc (insn, operands, 0);"
17017 [(set_attr "type" "fpspc")
17018 (set_attr "mode" "<MODE>")])
17020 (define_insn "fist<mode>2_with_temp"
17021 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17022 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17024 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17025 "TARGET_USE_FANCY_MATH_387"
17027 [(set_attr "type" "fpspc")
17028 (set_attr "mode" "<MODE>")])
17031 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17032 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17034 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17036 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17038 (set (match_dup 0) (match_dup 2))]
17042 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17043 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17045 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17047 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17051 (define_expand "lrintxf<mode>2"
17052 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17053 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17055 "TARGET_USE_FANCY_MATH_387"
17058 (define_expand "lrint<mode>di2"
17059 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17060 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17061 UNSPEC_FIX_NOTRUNC))]
17062 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17065 (define_expand "lrint<mode>si2"
17066 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17067 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17068 UNSPEC_FIX_NOTRUNC))]
17069 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17072 (define_expand "lround<mode>di2"
17073 [(match_operand:DI 0 "nonimmediate_operand" "")
17074 (match_operand:SSEMODEF 1 "register_operand" "")]
17075 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17076 && !flag_trapping_math && !flag_rounding_math
17079 ix86_expand_lround (operand0, operand1);
17083 (define_expand "lround<mode>si2"
17084 [(match_operand:SI 0 "nonimmediate_operand" "")
17085 (match_operand:SSEMODEF 1 "register_operand" "")]
17086 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17087 && !flag_trapping_math && !flag_rounding_math
17090 ix86_expand_lround (operand0, operand1);
17094 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17095 (define_insn_and_split "frndintxf2_floor"
17096 [(set (match_operand:XF 0 "register_operand" "=f")
17097 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17098 UNSPEC_FRNDINT_FLOOR))
17099 (clobber (reg:CC FLAGS_REG))]
17100 "TARGET_USE_FANCY_MATH_387
17101 && flag_unsafe_math_optimizations
17102 && !(reload_completed || reload_in_progress)"
17107 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17109 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17110 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17112 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17113 operands[2], operands[3]));
17116 [(set_attr "type" "frndint")
17117 (set_attr "i387_cw" "floor")
17118 (set_attr "mode" "XF")])
17120 (define_insn "frndintxf2_floor_i387"
17121 [(set (match_operand:XF 0 "register_operand" "=f")
17122 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17123 UNSPEC_FRNDINT_FLOOR))
17124 (use (match_operand:HI 2 "memory_operand" "m"))
17125 (use (match_operand:HI 3 "memory_operand" "m"))]
17126 "TARGET_USE_FANCY_MATH_387
17127 && flag_unsafe_math_optimizations"
17128 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17129 [(set_attr "type" "frndint")
17130 (set_attr "i387_cw" "floor")
17131 (set_attr "mode" "XF")])
17133 (define_expand "floorxf2"
17134 [(use (match_operand:XF 0 "register_operand" ""))
17135 (use (match_operand:XF 1 "register_operand" ""))]
17136 "TARGET_USE_FANCY_MATH_387
17137 && flag_unsafe_math_optimizations && !optimize_size"
17139 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17143 (define_expand "floordf2"
17144 [(use (match_operand:DF 0 "register_operand" ""))
17145 (use (match_operand:DF 1 "register_operand" ""))]
17146 "((TARGET_USE_FANCY_MATH_387
17147 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17148 && flag_unsafe_math_optimizations)
17149 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17150 && !flag_trapping_math))
17153 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17154 && !flag_trapping_math)
17157 ix86_expand_floorceil (operand0, operand1, true);
17159 ix86_expand_floorceildf_32 (operand0, operand1, true);
17163 rtx op0 = gen_reg_rtx (XFmode);
17164 rtx op1 = gen_reg_rtx (XFmode);
17166 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17167 emit_insn (gen_frndintxf2_floor (op0, op1));
17169 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17174 (define_expand "floorsf2"
17175 [(use (match_operand:SF 0 "register_operand" ""))
17176 (use (match_operand:SF 1 "register_operand" ""))]
17177 "((TARGET_USE_FANCY_MATH_387
17178 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17179 && flag_unsafe_math_optimizations)
17180 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17181 && !flag_trapping_math))
17184 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17185 && !flag_trapping_math)
17186 ix86_expand_floorceil (operand0, operand1, true);
17189 rtx op0 = gen_reg_rtx (XFmode);
17190 rtx op1 = gen_reg_rtx (XFmode);
17192 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17193 emit_insn (gen_frndintxf2_floor (op0, op1));
17195 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17200 (define_insn_and_split "*fist<mode>2_floor_1"
17201 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17202 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17203 UNSPEC_FIST_FLOOR))
17204 (clobber (reg:CC FLAGS_REG))]
17205 "TARGET_USE_FANCY_MATH_387
17206 && flag_unsafe_math_optimizations
17207 && !(reload_completed || reload_in_progress)"
17212 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17214 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17215 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17216 if (memory_operand (operands[0], VOIDmode))
17217 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17218 operands[2], operands[3]));
17221 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17222 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17223 operands[2], operands[3],
17228 [(set_attr "type" "fistp")
17229 (set_attr "i387_cw" "floor")
17230 (set_attr "mode" "<MODE>")])
17232 (define_insn "fistdi2_floor"
17233 [(set (match_operand:DI 0 "memory_operand" "=m")
17234 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17235 UNSPEC_FIST_FLOOR))
17236 (use (match_operand:HI 2 "memory_operand" "m"))
17237 (use (match_operand:HI 3 "memory_operand" "m"))
17238 (clobber (match_scratch:XF 4 "=&1f"))]
17239 "TARGET_USE_FANCY_MATH_387
17240 && flag_unsafe_math_optimizations"
17241 "* return output_fix_trunc (insn, operands, 0);"
17242 [(set_attr "type" "fistp")
17243 (set_attr "i387_cw" "floor")
17244 (set_attr "mode" "DI")])
17246 (define_insn "fistdi2_floor_with_temp"
17247 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17248 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17249 UNSPEC_FIST_FLOOR))
17250 (use (match_operand:HI 2 "memory_operand" "m,m"))
17251 (use (match_operand:HI 3 "memory_operand" "m,m"))
17252 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17253 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17254 "TARGET_USE_FANCY_MATH_387
17255 && flag_unsafe_math_optimizations"
17257 [(set_attr "type" "fistp")
17258 (set_attr "i387_cw" "floor")
17259 (set_attr "mode" "DI")])
17262 [(set (match_operand:DI 0 "register_operand" "")
17263 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17264 UNSPEC_FIST_FLOOR))
17265 (use (match_operand:HI 2 "memory_operand" ""))
17266 (use (match_operand:HI 3 "memory_operand" ""))
17267 (clobber (match_operand:DI 4 "memory_operand" ""))
17268 (clobber (match_scratch 5 ""))]
17270 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17271 (use (match_dup 2))
17272 (use (match_dup 3))
17273 (clobber (match_dup 5))])
17274 (set (match_dup 0) (match_dup 4))]
17278 [(set (match_operand:DI 0 "memory_operand" "")
17279 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17280 UNSPEC_FIST_FLOOR))
17281 (use (match_operand:HI 2 "memory_operand" ""))
17282 (use (match_operand:HI 3 "memory_operand" ""))
17283 (clobber (match_operand:DI 4 "memory_operand" ""))
17284 (clobber (match_scratch 5 ""))]
17286 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17287 (use (match_dup 2))
17288 (use (match_dup 3))
17289 (clobber (match_dup 5))])]
17292 (define_insn "fist<mode>2_floor"
17293 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17294 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17295 UNSPEC_FIST_FLOOR))
17296 (use (match_operand:HI 2 "memory_operand" "m"))
17297 (use (match_operand:HI 3 "memory_operand" "m"))]
17298 "TARGET_USE_FANCY_MATH_387
17299 && flag_unsafe_math_optimizations"
17300 "* return output_fix_trunc (insn, operands, 0);"
17301 [(set_attr "type" "fistp")
17302 (set_attr "i387_cw" "floor")
17303 (set_attr "mode" "<MODE>")])
17305 (define_insn "fist<mode>2_floor_with_temp"
17306 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17307 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17308 UNSPEC_FIST_FLOOR))
17309 (use (match_operand:HI 2 "memory_operand" "m,m"))
17310 (use (match_operand:HI 3 "memory_operand" "m,m"))
17311 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17312 "TARGET_USE_FANCY_MATH_387
17313 && flag_unsafe_math_optimizations"
17315 [(set_attr "type" "fistp")
17316 (set_attr "i387_cw" "floor")
17317 (set_attr "mode" "<MODE>")])
17320 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17321 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17322 UNSPEC_FIST_FLOOR))
17323 (use (match_operand:HI 2 "memory_operand" ""))
17324 (use (match_operand:HI 3 "memory_operand" ""))
17325 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17327 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17328 UNSPEC_FIST_FLOOR))
17329 (use (match_dup 2))
17330 (use (match_dup 3))])
17331 (set (match_dup 0) (match_dup 4))]
17335 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17336 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17337 UNSPEC_FIST_FLOOR))
17338 (use (match_operand:HI 2 "memory_operand" ""))
17339 (use (match_operand:HI 3 "memory_operand" ""))
17340 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17342 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17343 UNSPEC_FIST_FLOOR))
17344 (use (match_dup 2))
17345 (use (match_dup 3))])]
17348 (define_expand "lfloorxf<mode>2"
17349 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17350 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17351 UNSPEC_FIST_FLOOR))
17352 (clobber (reg:CC FLAGS_REG))])]
17353 "TARGET_USE_FANCY_MATH_387
17354 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17355 && flag_unsafe_math_optimizations"
17358 (define_expand "lfloor<mode>di2"
17359 [(match_operand:DI 0 "nonimmediate_operand" "")
17360 (match_operand:SSEMODEF 1 "register_operand" "")]
17361 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17362 && !flag_trapping_math
17365 ix86_expand_lfloorceil (operand0, operand1, true);
17369 (define_expand "lfloor<mode>si2"
17370 [(match_operand:SI 0 "nonimmediate_operand" "")
17371 (match_operand:SSEMODEF 1 "register_operand" "")]
17372 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17373 && !flag_trapping_math
17374 && (!optimize_size || !TARGET_64BIT)"
17376 ix86_expand_lfloorceil (operand0, operand1, true);
17380 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17381 (define_insn_and_split "frndintxf2_ceil"
17382 [(set (match_operand:XF 0 "register_operand" "=f")
17383 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17384 UNSPEC_FRNDINT_CEIL))
17385 (clobber (reg:CC FLAGS_REG))]
17386 "TARGET_USE_FANCY_MATH_387
17387 && flag_unsafe_math_optimizations
17388 && !(reload_completed || reload_in_progress)"
17393 ix86_optimize_mode_switching[I387_CEIL] = 1;
17395 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17396 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17398 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17399 operands[2], operands[3]));
17402 [(set_attr "type" "frndint")
17403 (set_attr "i387_cw" "ceil")
17404 (set_attr "mode" "XF")])
17406 (define_insn "frndintxf2_ceil_i387"
17407 [(set (match_operand:XF 0 "register_operand" "=f")
17408 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17409 UNSPEC_FRNDINT_CEIL))
17410 (use (match_operand:HI 2 "memory_operand" "m"))
17411 (use (match_operand:HI 3 "memory_operand" "m"))]
17412 "TARGET_USE_FANCY_MATH_387
17413 && flag_unsafe_math_optimizations"
17414 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17415 [(set_attr "type" "frndint")
17416 (set_attr "i387_cw" "ceil")
17417 (set_attr "mode" "XF")])
17419 (define_expand "ceilxf2"
17420 [(use (match_operand:XF 0 "register_operand" ""))
17421 (use (match_operand:XF 1 "register_operand" ""))]
17422 "TARGET_USE_FANCY_MATH_387
17423 && flag_unsafe_math_optimizations && !optimize_size"
17425 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17429 (define_expand "ceildf2"
17430 [(use (match_operand:DF 0 "register_operand" ""))
17431 (use (match_operand:DF 1 "register_operand" ""))]
17432 "((TARGET_USE_FANCY_MATH_387
17433 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17434 && flag_unsafe_math_optimizations)
17435 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17436 && !flag_trapping_math))
17439 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17440 && !flag_trapping_math)
17443 ix86_expand_floorceil (operand0, operand1, false);
17445 ix86_expand_floorceildf_32 (operand0, operand1, false);
17449 rtx op0 = gen_reg_rtx (XFmode);
17450 rtx op1 = gen_reg_rtx (XFmode);
17452 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17453 emit_insn (gen_frndintxf2_ceil (op0, op1));
17455 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17460 (define_expand "ceilsf2"
17461 [(use (match_operand:SF 0 "register_operand" ""))
17462 (use (match_operand:SF 1 "register_operand" ""))]
17463 "((TARGET_USE_FANCY_MATH_387
17464 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17465 && flag_unsafe_math_optimizations)
17466 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17467 && !flag_trapping_math))
17470 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17471 && !flag_trapping_math)
17472 ix86_expand_floorceil (operand0, operand1, false);
17475 rtx op0 = gen_reg_rtx (XFmode);
17476 rtx op1 = gen_reg_rtx (XFmode);
17478 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17479 emit_insn (gen_frndintxf2_ceil (op0, op1));
17481 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17486 (define_insn_and_split "*fist<mode>2_ceil_1"
17487 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17488 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17490 (clobber (reg:CC FLAGS_REG))]
17491 "TARGET_USE_FANCY_MATH_387
17492 && flag_unsafe_math_optimizations
17493 && !(reload_completed || reload_in_progress)"
17498 ix86_optimize_mode_switching[I387_CEIL] = 1;
17500 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17501 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17502 if (memory_operand (operands[0], VOIDmode))
17503 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17504 operands[2], operands[3]));
17507 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17508 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17509 operands[2], operands[3],
17514 [(set_attr "type" "fistp")
17515 (set_attr "i387_cw" "ceil")
17516 (set_attr "mode" "<MODE>")])
17518 (define_insn "fistdi2_ceil"
17519 [(set (match_operand:DI 0 "memory_operand" "=m")
17520 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17522 (use (match_operand:HI 2 "memory_operand" "m"))
17523 (use (match_operand:HI 3 "memory_operand" "m"))
17524 (clobber (match_scratch:XF 4 "=&1f"))]
17525 "TARGET_USE_FANCY_MATH_387
17526 && flag_unsafe_math_optimizations"
17527 "* return output_fix_trunc (insn, operands, 0);"
17528 [(set_attr "type" "fistp")
17529 (set_attr "i387_cw" "ceil")
17530 (set_attr "mode" "DI")])
17532 (define_insn "fistdi2_ceil_with_temp"
17533 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17534 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17536 (use (match_operand:HI 2 "memory_operand" "m,m"))
17537 (use (match_operand:HI 3 "memory_operand" "m,m"))
17538 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17539 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17540 "TARGET_USE_FANCY_MATH_387
17541 && flag_unsafe_math_optimizations"
17543 [(set_attr "type" "fistp")
17544 (set_attr "i387_cw" "ceil")
17545 (set_attr "mode" "DI")])
17548 [(set (match_operand:DI 0 "register_operand" "")
17549 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17551 (use (match_operand:HI 2 "memory_operand" ""))
17552 (use (match_operand:HI 3 "memory_operand" ""))
17553 (clobber (match_operand:DI 4 "memory_operand" ""))
17554 (clobber (match_scratch 5 ""))]
17556 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17557 (use (match_dup 2))
17558 (use (match_dup 3))
17559 (clobber (match_dup 5))])
17560 (set (match_dup 0) (match_dup 4))]
17564 [(set (match_operand:DI 0 "memory_operand" "")
17565 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17567 (use (match_operand:HI 2 "memory_operand" ""))
17568 (use (match_operand:HI 3 "memory_operand" ""))
17569 (clobber (match_operand:DI 4 "memory_operand" ""))
17570 (clobber (match_scratch 5 ""))]
17572 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17573 (use (match_dup 2))
17574 (use (match_dup 3))
17575 (clobber (match_dup 5))])]
17578 (define_insn "fist<mode>2_ceil"
17579 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17580 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17582 (use (match_operand:HI 2 "memory_operand" "m"))
17583 (use (match_operand:HI 3 "memory_operand" "m"))]
17584 "TARGET_USE_FANCY_MATH_387
17585 && flag_unsafe_math_optimizations"
17586 "* return output_fix_trunc (insn, operands, 0);"
17587 [(set_attr "type" "fistp")
17588 (set_attr "i387_cw" "ceil")
17589 (set_attr "mode" "<MODE>")])
17591 (define_insn "fist<mode>2_ceil_with_temp"
17592 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17593 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17595 (use (match_operand:HI 2 "memory_operand" "m,m"))
17596 (use (match_operand:HI 3 "memory_operand" "m,m"))
17597 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17598 "TARGET_USE_FANCY_MATH_387
17599 && flag_unsafe_math_optimizations"
17601 [(set_attr "type" "fistp")
17602 (set_attr "i387_cw" "ceil")
17603 (set_attr "mode" "<MODE>")])
17606 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17607 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17609 (use (match_operand:HI 2 "memory_operand" ""))
17610 (use (match_operand:HI 3 "memory_operand" ""))
17611 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17613 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17615 (use (match_dup 2))
17616 (use (match_dup 3))])
17617 (set (match_dup 0) (match_dup 4))]
17621 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17622 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17624 (use (match_operand:HI 2 "memory_operand" ""))
17625 (use (match_operand:HI 3 "memory_operand" ""))
17626 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17628 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17630 (use (match_dup 2))
17631 (use (match_dup 3))])]
17634 (define_expand "lceilxf<mode>2"
17635 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17636 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17638 (clobber (reg:CC FLAGS_REG))])]
17639 "TARGET_USE_FANCY_MATH_387
17640 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17641 && flag_unsafe_math_optimizations"
17644 (define_expand "lceil<mode>di2"
17645 [(match_operand:DI 0 "nonimmediate_operand" "")
17646 (match_operand:SSEMODEF 1 "register_operand" "")]
17647 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17648 && !flag_trapping_math"
17650 ix86_expand_lfloorceil (operand0, operand1, false);
17654 (define_expand "lceil<mode>si2"
17655 [(match_operand:SI 0 "nonimmediate_operand" "")
17656 (match_operand:SSEMODEF 1 "register_operand" "")]
17657 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17658 && !flag_trapping_math"
17660 ix86_expand_lfloorceil (operand0, operand1, false);
17664 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17665 (define_insn_and_split "frndintxf2_trunc"
17666 [(set (match_operand:XF 0 "register_operand" "=f")
17667 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17668 UNSPEC_FRNDINT_TRUNC))
17669 (clobber (reg:CC FLAGS_REG))]
17670 "TARGET_USE_FANCY_MATH_387
17671 && flag_unsafe_math_optimizations
17672 && !(reload_completed || reload_in_progress)"
17677 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17679 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17680 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17682 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17683 operands[2], operands[3]));
17686 [(set_attr "type" "frndint")
17687 (set_attr "i387_cw" "trunc")
17688 (set_attr "mode" "XF")])
17690 (define_insn "frndintxf2_trunc_i387"
17691 [(set (match_operand:XF 0 "register_operand" "=f")
17692 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17693 UNSPEC_FRNDINT_TRUNC))
17694 (use (match_operand:HI 2 "memory_operand" "m"))
17695 (use (match_operand:HI 3 "memory_operand" "m"))]
17696 "TARGET_USE_FANCY_MATH_387
17697 && flag_unsafe_math_optimizations"
17698 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17699 [(set_attr "type" "frndint")
17700 (set_attr "i387_cw" "trunc")
17701 (set_attr "mode" "XF")])
17703 (define_expand "btruncxf2"
17704 [(use (match_operand:XF 0 "register_operand" ""))
17705 (use (match_operand:XF 1 "register_operand" ""))]
17706 "TARGET_USE_FANCY_MATH_387
17707 && flag_unsafe_math_optimizations && !optimize_size"
17709 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17713 (define_expand "btruncdf2"
17714 [(use (match_operand:DF 0 "register_operand" ""))
17715 (use (match_operand:DF 1 "register_operand" ""))]
17716 "((TARGET_USE_FANCY_MATH_387
17717 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17718 && flag_unsafe_math_optimizations)
17719 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17720 && !flag_trapping_math))
17723 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17724 && !flag_trapping_math)
17727 ix86_expand_trunc (operand0, operand1);
17729 ix86_expand_truncdf_32 (operand0, operand1);
17733 rtx op0 = gen_reg_rtx (XFmode);
17734 rtx op1 = gen_reg_rtx (XFmode);
17736 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17737 emit_insn (gen_frndintxf2_trunc (op0, op1));
17739 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17744 (define_expand "btruncsf2"
17745 [(use (match_operand:SF 0 "register_operand" ""))
17746 (use (match_operand:SF 1 "register_operand" ""))]
17747 "((TARGET_USE_FANCY_MATH_387
17748 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17749 && flag_unsafe_math_optimizations)
17750 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17751 && !flag_trapping_math))
17754 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17755 && !flag_trapping_math)
17756 ix86_expand_trunc (operand0, operand1);
17759 rtx op0 = gen_reg_rtx (XFmode);
17760 rtx op1 = gen_reg_rtx (XFmode);
17762 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17763 emit_insn (gen_frndintxf2_trunc (op0, op1));
17765 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17770 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17771 (define_insn_and_split "frndintxf2_mask_pm"
17772 [(set (match_operand:XF 0 "register_operand" "=f")
17773 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17774 UNSPEC_FRNDINT_MASK_PM))
17775 (clobber (reg:CC FLAGS_REG))]
17776 "TARGET_USE_FANCY_MATH_387
17777 && flag_unsafe_math_optimizations
17778 && !(reload_completed || reload_in_progress)"
17783 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17785 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17786 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17788 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17789 operands[2], operands[3]));
17792 [(set_attr "type" "frndint")
17793 (set_attr "i387_cw" "mask_pm")
17794 (set_attr "mode" "XF")])
17796 (define_insn "frndintxf2_mask_pm_i387"
17797 [(set (match_operand:XF 0 "register_operand" "=f")
17798 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17799 UNSPEC_FRNDINT_MASK_PM))
17800 (use (match_operand:HI 2 "memory_operand" "m"))
17801 (use (match_operand:HI 3 "memory_operand" "m"))]
17802 "TARGET_USE_FANCY_MATH_387
17803 && flag_unsafe_math_optimizations"
17804 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17805 [(set_attr "type" "frndint")
17806 (set_attr "i387_cw" "mask_pm")
17807 (set_attr "mode" "XF")])
17809 (define_expand "nearbyintxf2"
17810 [(use (match_operand:XF 0 "register_operand" ""))
17811 (use (match_operand:XF 1 "register_operand" ""))]
17812 "TARGET_USE_FANCY_MATH_387
17813 && flag_unsafe_math_optimizations"
17815 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17820 (define_expand "nearbyintdf2"
17821 [(use (match_operand:DF 0 "register_operand" ""))
17822 (use (match_operand:DF 1 "register_operand" ""))]
17823 "TARGET_USE_FANCY_MATH_387
17824 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17825 && flag_unsafe_math_optimizations"
17827 rtx op0 = gen_reg_rtx (XFmode);
17828 rtx op1 = gen_reg_rtx (XFmode);
17830 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17831 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17833 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17837 (define_expand "nearbyintsf2"
17838 [(use (match_operand:SF 0 "register_operand" ""))
17839 (use (match_operand:SF 1 "register_operand" ""))]
17840 "TARGET_USE_FANCY_MATH_387
17841 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17842 && flag_unsafe_math_optimizations"
17844 rtx op0 = gen_reg_rtx (XFmode);
17845 rtx op1 = gen_reg_rtx (XFmode);
17847 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17848 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17850 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17854 (define_insn "fxam<mode>2_i387"
17855 [(set (match_operand:HI 0 "register_operand" "=a")
17857 [(match_operand:X87MODEF 1 "register_operand" "f")]
17859 "TARGET_USE_FANCY_MATH_387"
17860 "fxam\n\tfnstsw\t%0"
17861 [(set_attr "type" "multi")
17862 (set_attr "unit" "i387")
17863 (set_attr "mode" "<MODE>")])
17865 (define_expand "isinf<mode>2"
17866 [(use (match_operand:SI 0 "register_operand" ""))
17867 (use (match_operand:X87MODEF 1 "register_operand" ""))]
17868 "TARGET_USE_FANCY_MATH_387
17869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17870 || TARGET_MIX_SSE_I387)"
17872 rtx mask = GEN_INT (0x45);
17873 rtx val = GEN_INT (0x05);
17877 rtx scratch = gen_reg_rtx (HImode);
17878 rtx res = gen_reg_rtx (QImode);
17880 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17881 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17882 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17883 cond = gen_rtx_fmt_ee (EQ, QImode,
17884 gen_rtx_REG (CCmode, FLAGS_REG),
17886 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17887 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17892 ;; Block operation instructions
17894 (define_expand "movmemsi"
17895 [(use (match_operand:BLK 0 "memory_operand" ""))
17896 (use (match_operand:BLK 1 "memory_operand" ""))
17897 (use (match_operand:SI 2 "nonmemory_operand" ""))
17898 (use (match_operand:SI 3 "const_int_operand" ""))
17899 (use (match_operand:SI 4 "const_int_operand" ""))
17900 (use (match_operand:SI 5 "const_int_operand" ""))]
17903 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17904 operands[4], operands[5]))
17910 (define_expand "movmemdi"
17911 [(use (match_operand:BLK 0 "memory_operand" ""))
17912 (use (match_operand:BLK 1 "memory_operand" ""))
17913 (use (match_operand:DI 2 "nonmemory_operand" ""))
17914 (use (match_operand:DI 3 "const_int_operand" ""))
17915 (use (match_operand:SI 4 "const_int_operand" ""))
17916 (use (match_operand:SI 5 "const_int_operand" ""))]
17919 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17920 operands[4], operands[5]))
17926 ;; Most CPUs don't like single string operations
17927 ;; Handle this case here to simplify previous expander.
17929 (define_expand "strmov"
17930 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17931 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17932 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17933 (clobber (reg:CC FLAGS_REG))])
17934 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17935 (clobber (reg:CC FLAGS_REG))])]
17938 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17940 /* If .md ever supports :P for Pmode, these can be directly
17941 in the pattern above. */
17942 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17943 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17945 if (TARGET_SINGLE_STRINGOP || optimize_size)
17947 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17948 operands[2], operands[3],
17949 operands[5], operands[6]));
17953 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17956 (define_expand "strmov_singleop"
17957 [(parallel [(set (match_operand 1 "memory_operand" "")
17958 (match_operand 3 "memory_operand" ""))
17959 (set (match_operand 0 "register_operand" "")
17960 (match_operand 4 "" ""))
17961 (set (match_operand 2 "register_operand" "")
17962 (match_operand 5 "" ""))])]
17963 "TARGET_SINGLE_STRINGOP || optimize_size"
17966 (define_insn "*strmovdi_rex_1"
17967 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17968 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17969 (set (match_operand:DI 0 "register_operand" "=D")
17970 (plus:DI (match_dup 2)
17972 (set (match_operand:DI 1 "register_operand" "=S")
17973 (plus:DI (match_dup 3)
17975 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17977 [(set_attr "type" "str")
17978 (set_attr "mode" "DI")
17979 (set_attr "memory" "both")])
17981 (define_insn "*strmovsi_1"
17982 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17983 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17984 (set (match_operand:SI 0 "register_operand" "=D")
17985 (plus:SI (match_dup 2)
17987 (set (match_operand:SI 1 "register_operand" "=S")
17988 (plus:SI (match_dup 3)
17990 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17992 [(set_attr "type" "str")
17993 (set_attr "mode" "SI")
17994 (set_attr "memory" "both")])
17996 (define_insn "*strmovsi_rex_1"
17997 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17998 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17999 (set (match_operand:DI 0 "register_operand" "=D")
18000 (plus:DI (match_dup 2)
18002 (set (match_operand:DI 1 "register_operand" "=S")
18003 (plus:DI (match_dup 3)
18005 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18007 [(set_attr "type" "str")
18008 (set_attr "mode" "SI")
18009 (set_attr "memory" "both")])
18011 (define_insn "*strmovhi_1"
18012 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18013 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18014 (set (match_operand:SI 0 "register_operand" "=D")
18015 (plus:SI (match_dup 2)
18017 (set (match_operand:SI 1 "register_operand" "=S")
18018 (plus:SI (match_dup 3)
18020 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18022 [(set_attr "type" "str")
18023 (set_attr "memory" "both")
18024 (set_attr "mode" "HI")])
18026 (define_insn "*strmovhi_rex_1"
18027 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18028 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18029 (set (match_operand:DI 0 "register_operand" "=D")
18030 (plus:DI (match_dup 2)
18032 (set (match_operand:DI 1 "register_operand" "=S")
18033 (plus:DI (match_dup 3)
18035 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18037 [(set_attr "type" "str")
18038 (set_attr "memory" "both")
18039 (set_attr "mode" "HI")])
18041 (define_insn "*strmovqi_1"
18042 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18043 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18044 (set (match_operand:SI 0 "register_operand" "=D")
18045 (plus:SI (match_dup 2)
18047 (set (match_operand:SI 1 "register_operand" "=S")
18048 (plus:SI (match_dup 3)
18050 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18052 [(set_attr "type" "str")
18053 (set_attr "memory" "both")
18054 (set_attr "mode" "QI")])
18056 (define_insn "*strmovqi_rex_1"
18057 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18058 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18059 (set (match_operand:DI 0 "register_operand" "=D")
18060 (plus:DI (match_dup 2)
18062 (set (match_operand:DI 1 "register_operand" "=S")
18063 (plus:DI (match_dup 3)
18065 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18067 [(set_attr "type" "str")
18068 (set_attr "memory" "both")
18069 (set_attr "mode" "QI")])
18071 (define_expand "rep_mov"
18072 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18073 (set (match_operand 0 "register_operand" "")
18074 (match_operand 5 "" ""))
18075 (set (match_operand 2 "register_operand" "")
18076 (match_operand 6 "" ""))
18077 (set (match_operand 1 "memory_operand" "")
18078 (match_operand 3 "memory_operand" ""))
18079 (use (match_dup 4))])]
18083 (define_insn "*rep_movdi_rex64"
18084 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18085 (set (match_operand:DI 0 "register_operand" "=D")
18086 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18088 (match_operand:DI 3 "register_operand" "0")))
18089 (set (match_operand:DI 1 "register_operand" "=S")
18090 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18091 (match_operand:DI 4 "register_operand" "1")))
18092 (set (mem:BLK (match_dup 3))
18093 (mem:BLK (match_dup 4)))
18094 (use (match_dup 5))]
18096 "{rep\;movsq|rep movsq}"
18097 [(set_attr "type" "str")
18098 (set_attr "prefix_rep" "1")
18099 (set_attr "memory" "both")
18100 (set_attr "mode" "DI")])
18102 (define_insn "*rep_movsi"
18103 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18104 (set (match_operand:SI 0 "register_operand" "=D")
18105 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18107 (match_operand:SI 3 "register_operand" "0")))
18108 (set (match_operand:SI 1 "register_operand" "=S")
18109 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18110 (match_operand:SI 4 "register_operand" "1")))
18111 (set (mem:BLK (match_dup 3))
18112 (mem:BLK (match_dup 4)))
18113 (use (match_dup 5))]
18115 "{rep\;movsl|rep movsd}"
18116 [(set_attr "type" "str")
18117 (set_attr "prefix_rep" "1")
18118 (set_attr "memory" "both")
18119 (set_attr "mode" "SI")])
18121 (define_insn "*rep_movsi_rex64"
18122 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18123 (set (match_operand:DI 0 "register_operand" "=D")
18124 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18126 (match_operand:DI 3 "register_operand" "0")))
18127 (set (match_operand:DI 1 "register_operand" "=S")
18128 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18129 (match_operand:DI 4 "register_operand" "1")))
18130 (set (mem:BLK (match_dup 3))
18131 (mem:BLK (match_dup 4)))
18132 (use (match_dup 5))]
18134 "{rep\;movsl|rep movsd}"
18135 [(set_attr "type" "str")
18136 (set_attr "prefix_rep" "1")
18137 (set_attr "memory" "both")
18138 (set_attr "mode" "SI")])
18140 (define_insn "*rep_movqi"
18141 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18142 (set (match_operand:SI 0 "register_operand" "=D")
18143 (plus:SI (match_operand:SI 3 "register_operand" "0")
18144 (match_operand:SI 5 "register_operand" "2")))
18145 (set (match_operand:SI 1 "register_operand" "=S")
18146 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18147 (set (mem:BLK (match_dup 3))
18148 (mem:BLK (match_dup 4)))
18149 (use (match_dup 5))]
18151 "{rep\;movsb|rep movsb}"
18152 [(set_attr "type" "str")
18153 (set_attr "prefix_rep" "1")
18154 (set_attr "memory" "both")
18155 (set_attr "mode" "SI")])
18157 (define_insn "*rep_movqi_rex64"
18158 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18159 (set (match_operand:DI 0 "register_operand" "=D")
18160 (plus:DI (match_operand:DI 3 "register_operand" "0")
18161 (match_operand:DI 5 "register_operand" "2")))
18162 (set (match_operand:DI 1 "register_operand" "=S")
18163 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18164 (set (mem:BLK (match_dup 3))
18165 (mem:BLK (match_dup 4)))
18166 (use (match_dup 5))]
18168 "{rep\;movsb|rep movsb}"
18169 [(set_attr "type" "str")
18170 (set_attr "prefix_rep" "1")
18171 (set_attr "memory" "both")
18172 (set_attr "mode" "SI")])
18174 (define_expand "setmemsi"
18175 [(use (match_operand:BLK 0 "memory_operand" ""))
18176 (use (match_operand:SI 1 "nonmemory_operand" ""))
18177 (use (match_operand 2 "const_int_operand" ""))
18178 (use (match_operand 3 "const_int_operand" ""))
18179 (use (match_operand:SI 4 "const_int_operand" ""))
18180 (use (match_operand:SI 5 "const_int_operand" ""))]
18183 if (ix86_expand_setmem (operands[0], operands[1],
18184 operands[2], operands[3],
18185 operands[4], operands[5]))
18191 (define_expand "setmemdi"
18192 [(use (match_operand:BLK 0 "memory_operand" ""))
18193 (use (match_operand:DI 1 "nonmemory_operand" ""))
18194 (use (match_operand 2 "const_int_operand" ""))
18195 (use (match_operand 3 "const_int_operand" ""))
18196 (use (match_operand 4 "const_int_operand" ""))
18197 (use (match_operand 5 "const_int_operand" ""))]
18200 if (ix86_expand_setmem (operands[0], operands[1],
18201 operands[2], operands[3],
18202 operands[4], operands[5]))
18208 ;; Most CPUs don't like single string operations
18209 ;; Handle this case here to simplify previous expander.
18211 (define_expand "strset"
18212 [(set (match_operand 1 "memory_operand" "")
18213 (match_operand 2 "register_operand" ""))
18214 (parallel [(set (match_operand 0 "register_operand" "")
18216 (clobber (reg:CC FLAGS_REG))])]
18219 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18220 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18222 /* If .md ever supports :P for Pmode, this can be directly
18223 in the pattern above. */
18224 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18225 GEN_INT (GET_MODE_SIZE (GET_MODE
18227 if (TARGET_SINGLE_STRINGOP || optimize_size)
18229 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18235 (define_expand "strset_singleop"
18236 [(parallel [(set (match_operand 1 "memory_operand" "")
18237 (match_operand 2 "register_operand" ""))
18238 (set (match_operand 0 "register_operand" "")
18239 (match_operand 3 "" ""))])]
18240 "TARGET_SINGLE_STRINGOP || optimize_size"
18243 (define_insn "*strsetdi_rex_1"
18244 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18245 (match_operand:DI 2 "register_operand" "a"))
18246 (set (match_operand:DI 0 "register_operand" "=D")
18247 (plus:DI (match_dup 1)
18249 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18251 [(set_attr "type" "str")
18252 (set_attr "memory" "store")
18253 (set_attr "mode" "DI")])
18255 (define_insn "*strsetsi_1"
18256 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18257 (match_operand:SI 2 "register_operand" "a"))
18258 (set (match_operand:SI 0 "register_operand" "=D")
18259 (plus:SI (match_dup 1)
18261 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18263 [(set_attr "type" "str")
18264 (set_attr "memory" "store")
18265 (set_attr "mode" "SI")])
18267 (define_insn "*strsetsi_rex_1"
18268 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18269 (match_operand:SI 2 "register_operand" "a"))
18270 (set (match_operand:DI 0 "register_operand" "=D")
18271 (plus:DI (match_dup 1)
18273 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18275 [(set_attr "type" "str")
18276 (set_attr "memory" "store")
18277 (set_attr "mode" "SI")])
18279 (define_insn "*strsethi_1"
18280 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18281 (match_operand:HI 2 "register_operand" "a"))
18282 (set (match_operand:SI 0 "register_operand" "=D")
18283 (plus:SI (match_dup 1)
18285 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18287 [(set_attr "type" "str")
18288 (set_attr "memory" "store")
18289 (set_attr "mode" "HI")])
18291 (define_insn "*strsethi_rex_1"
18292 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18293 (match_operand:HI 2 "register_operand" "a"))
18294 (set (match_operand:DI 0 "register_operand" "=D")
18295 (plus:DI (match_dup 1)
18297 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18299 [(set_attr "type" "str")
18300 (set_attr "memory" "store")
18301 (set_attr "mode" "HI")])
18303 (define_insn "*strsetqi_1"
18304 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18305 (match_operand:QI 2 "register_operand" "a"))
18306 (set (match_operand:SI 0 "register_operand" "=D")
18307 (plus:SI (match_dup 1)
18309 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18311 [(set_attr "type" "str")
18312 (set_attr "memory" "store")
18313 (set_attr "mode" "QI")])
18315 (define_insn "*strsetqi_rex_1"
18316 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18317 (match_operand:QI 2 "register_operand" "a"))
18318 (set (match_operand:DI 0 "register_operand" "=D")
18319 (plus:DI (match_dup 1)
18321 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18323 [(set_attr "type" "str")
18324 (set_attr "memory" "store")
18325 (set_attr "mode" "QI")])
18327 (define_expand "rep_stos"
18328 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18329 (set (match_operand 0 "register_operand" "")
18330 (match_operand 4 "" ""))
18331 (set (match_operand 2 "memory_operand" "") (const_int 0))
18332 (use (match_operand 3 "register_operand" ""))
18333 (use (match_dup 1))])]
18337 (define_insn "*rep_stosdi_rex64"
18338 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18339 (set (match_operand:DI 0 "register_operand" "=D")
18340 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18342 (match_operand:DI 3 "register_operand" "0")))
18343 (set (mem:BLK (match_dup 3))
18345 (use (match_operand:DI 2 "register_operand" "a"))
18346 (use (match_dup 4))]
18348 "{rep\;stosq|rep stosq}"
18349 [(set_attr "type" "str")
18350 (set_attr "prefix_rep" "1")
18351 (set_attr "memory" "store")
18352 (set_attr "mode" "DI")])
18354 (define_insn "*rep_stossi"
18355 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18356 (set (match_operand:SI 0 "register_operand" "=D")
18357 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18359 (match_operand:SI 3 "register_operand" "0")))
18360 (set (mem:BLK (match_dup 3))
18362 (use (match_operand:SI 2 "register_operand" "a"))
18363 (use (match_dup 4))]
18365 "{rep\;stosl|rep stosd}"
18366 [(set_attr "type" "str")
18367 (set_attr "prefix_rep" "1")
18368 (set_attr "memory" "store")
18369 (set_attr "mode" "SI")])
18371 (define_insn "*rep_stossi_rex64"
18372 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18373 (set (match_operand:DI 0 "register_operand" "=D")
18374 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18376 (match_operand:DI 3 "register_operand" "0")))
18377 (set (mem:BLK (match_dup 3))
18379 (use (match_operand:SI 2 "register_operand" "a"))
18380 (use (match_dup 4))]
18382 "{rep\;stosl|rep stosd}"
18383 [(set_attr "type" "str")
18384 (set_attr "prefix_rep" "1")
18385 (set_attr "memory" "store")
18386 (set_attr "mode" "SI")])
18388 (define_insn "*rep_stosqi"
18389 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18390 (set (match_operand:SI 0 "register_operand" "=D")
18391 (plus:SI (match_operand:SI 3 "register_operand" "0")
18392 (match_operand:SI 4 "register_operand" "1")))
18393 (set (mem:BLK (match_dup 3))
18395 (use (match_operand:QI 2 "register_operand" "a"))
18396 (use (match_dup 4))]
18398 "{rep\;stosb|rep stosb}"
18399 [(set_attr "type" "str")
18400 (set_attr "prefix_rep" "1")
18401 (set_attr "memory" "store")
18402 (set_attr "mode" "QI")])
18404 (define_insn "*rep_stosqi_rex64"
18405 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18406 (set (match_operand:DI 0 "register_operand" "=D")
18407 (plus:DI (match_operand:DI 3 "register_operand" "0")
18408 (match_operand:DI 4 "register_operand" "1")))
18409 (set (mem:BLK (match_dup 3))
18411 (use (match_operand:QI 2 "register_operand" "a"))
18412 (use (match_dup 4))]
18414 "{rep\;stosb|rep stosb}"
18415 [(set_attr "type" "str")
18416 (set_attr "prefix_rep" "1")
18417 (set_attr "memory" "store")
18418 (set_attr "mode" "QI")])
18420 (define_expand "cmpstrnsi"
18421 [(set (match_operand:SI 0 "register_operand" "")
18422 (compare:SI (match_operand:BLK 1 "general_operand" "")
18423 (match_operand:BLK 2 "general_operand" "")))
18424 (use (match_operand 3 "general_operand" ""))
18425 (use (match_operand 4 "immediate_operand" ""))]
18426 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18428 rtx addr1, addr2, out, outlow, count, countreg, align;
18430 /* Can't use this if the user has appropriated esi or edi. */
18431 if (global_regs[4] || global_regs[5])
18436 out = gen_reg_rtx (SImode);
18438 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18439 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18440 if (addr1 != XEXP (operands[1], 0))
18441 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18442 if (addr2 != XEXP (operands[2], 0))
18443 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18445 count = operands[3];
18446 countreg = ix86_zero_extend_to_Pmode (count);
18448 /* %%% Iff we are testing strict equality, we can use known alignment
18449 to good advantage. This may be possible with combine, particularly
18450 once cc0 is dead. */
18451 align = operands[4];
18453 if (CONST_INT_P (count))
18455 if (INTVAL (count) == 0)
18457 emit_move_insn (operands[0], const0_rtx);
18460 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18461 operands[1], operands[2]));
18466 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18468 emit_insn (gen_cmpsi_1 (countreg, countreg));
18469 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18470 operands[1], operands[2]));
18473 outlow = gen_lowpart (QImode, out);
18474 emit_insn (gen_cmpintqi (outlow));
18475 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18477 if (operands[0] != out)
18478 emit_move_insn (operands[0], out);
18483 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18485 (define_expand "cmpintqi"
18486 [(set (match_dup 1)
18487 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18489 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18490 (parallel [(set (match_operand:QI 0 "register_operand" "")
18491 (minus:QI (match_dup 1)
18493 (clobber (reg:CC FLAGS_REG))])]
18495 "operands[1] = gen_reg_rtx (QImode);
18496 operands[2] = gen_reg_rtx (QImode);")
18498 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18499 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18501 (define_expand "cmpstrnqi_nz_1"
18502 [(parallel [(set (reg:CC FLAGS_REG)
18503 (compare:CC (match_operand 4 "memory_operand" "")
18504 (match_operand 5 "memory_operand" "")))
18505 (use (match_operand 2 "register_operand" ""))
18506 (use (match_operand:SI 3 "immediate_operand" ""))
18507 (clobber (match_operand 0 "register_operand" ""))
18508 (clobber (match_operand 1 "register_operand" ""))
18509 (clobber (match_dup 2))])]
18513 (define_insn "*cmpstrnqi_nz_1"
18514 [(set (reg:CC FLAGS_REG)
18515 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18516 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18517 (use (match_operand:SI 6 "register_operand" "2"))
18518 (use (match_operand:SI 3 "immediate_operand" "i"))
18519 (clobber (match_operand:SI 0 "register_operand" "=S"))
18520 (clobber (match_operand:SI 1 "register_operand" "=D"))
18521 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18524 [(set_attr "type" "str")
18525 (set_attr "mode" "QI")
18526 (set_attr "prefix_rep" "1")])
18528 (define_insn "*cmpstrnqi_nz_rex_1"
18529 [(set (reg:CC FLAGS_REG)
18530 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18531 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18532 (use (match_operand:DI 6 "register_operand" "2"))
18533 (use (match_operand:SI 3 "immediate_operand" "i"))
18534 (clobber (match_operand:DI 0 "register_operand" "=S"))
18535 (clobber (match_operand:DI 1 "register_operand" "=D"))
18536 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18539 [(set_attr "type" "str")
18540 (set_attr "mode" "QI")
18541 (set_attr "prefix_rep" "1")])
18543 ;; The same, but the count is not known to not be zero.
18545 (define_expand "cmpstrnqi_1"
18546 [(parallel [(set (reg:CC FLAGS_REG)
18547 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18549 (compare:CC (match_operand 4 "memory_operand" "")
18550 (match_operand 5 "memory_operand" ""))
18552 (use (match_operand:SI 3 "immediate_operand" ""))
18553 (use (reg:CC FLAGS_REG))
18554 (clobber (match_operand 0 "register_operand" ""))
18555 (clobber (match_operand 1 "register_operand" ""))
18556 (clobber (match_dup 2))])]
18560 (define_insn "*cmpstrnqi_1"
18561 [(set (reg:CC FLAGS_REG)
18562 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18564 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18565 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18567 (use (match_operand:SI 3 "immediate_operand" "i"))
18568 (use (reg:CC FLAGS_REG))
18569 (clobber (match_operand:SI 0 "register_operand" "=S"))
18570 (clobber (match_operand:SI 1 "register_operand" "=D"))
18571 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18574 [(set_attr "type" "str")
18575 (set_attr "mode" "QI")
18576 (set_attr "prefix_rep" "1")])
18578 (define_insn "*cmpstrnqi_rex_1"
18579 [(set (reg:CC FLAGS_REG)
18580 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18582 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18583 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18585 (use (match_operand:SI 3 "immediate_operand" "i"))
18586 (use (reg:CC FLAGS_REG))
18587 (clobber (match_operand:DI 0 "register_operand" "=S"))
18588 (clobber (match_operand:DI 1 "register_operand" "=D"))
18589 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18592 [(set_attr "type" "str")
18593 (set_attr "mode" "QI")
18594 (set_attr "prefix_rep" "1")])
18596 (define_expand "strlensi"
18597 [(set (match_operand:SI 0 "register_operand" "")
18598 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18599 (match_operand:QI 2 "immediate_operand" "")
18600 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18603 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18609 (define_expand "strlendi"
18610 [(set (match_operand:DI 0 "register_operand" "")
18611 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18612 (match_operand:QI 2 "immediate_operand" "")
18613 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18616 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18622 (define_expand "strlenqi_1"
18623 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18624 (clobber (match_operand 1 "register_operand" ""))
18625 (clobber (reg:CC FLAGS_REG))])]
18629 (define_insn "*strlenqi_1"
18630 [(set (match_operand:SI 0 "register_operand" "=&c")
18631 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18632 (match_operand:QI 2 "register_operand" "a")
18633 (match_operand:SI 3 "immediate_operand" "i")
18634 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18635 (clobber (match_operand:SI 1 "register_operand" "=D"))
18636 (clobber (reg:CC FLAGS_REG))]
18639 [(set_attr "type" "str")
18640 (set_attr "mode" "QI")
18641 (set_attr "prefix_rep" "1")])
18643 (define_insn "*strlenqi_rex_1"
18644 [(set (match_operand:DI 0 "register_operand" "=&c")
18645 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18646 (match_operand:QI 2 "register_operand" "a")
18647 (match_operand:DI 3 "immediate_operand" "i")
18648 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18649 (clobber (match_operand:DI 1 "register_operand" "=D"))
18650 (clobber (reg:CC FLAGS_REG))]
18653 [(set_attr "type" "str")
18654 (set_attr "mode" "QI")
18655 (set_attr "prefix_rep" "1")])
18657 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18658 ;; handled in combine, but it is not currently up to the task.
18659 ;; When used for their truth value, the cmpstrn* expanders generate
18668 ;; The intermediate three instructions are unnecessary.
18670 ;; This one handles cmpstrn*_nz_1...
18673 (set (reg:CC FLAGS_REG)
18674 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18675 (mem:BLK (match_operand 5 "register_operand" ""))))
18676 (use (match_operand 6 "register_operand" ""))
18677 (use (match_operand:SI 3 "immediate_operand" ""))
18678 (clobber (match_operand 0 "register_operand" ""))
18679 (clobber (match_operand 1 "register_operand" ""))
18680 (clobber (match_operand 2 "register_operand" ""))])
18681 (set (match_operand:QI 7 "register_operand" "")
18682 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18683 (set (match_operand:QI 8 "register_operand" "")
18684 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18685 (set (reg FLAGS_REG)
18686 (compare (match_dup 7) (match_dup 8)))
18688 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18690 (set (reg:CC FLAGS_REG)
18691 (compare:CC (mem:BLK (match_dup 4))
18692 (mem:BLK (match_dup 5))))
18693 (use (match_dup 6))
18694 (use (match_dup 3))
18695 (clobber (match_dup 0))
18696 (clobber (match_dup 1))
18697 (clobber (match_dup 2))])]
18700 ;; ...and this one handles cmpstrn*_1.
18703 (set (reg:CC FLAGS_REG)
18704 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18706 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18707 (mem:BLK (match_operand 5 "register_operand" "")))
18709 (use (match_operand:SI 3 "immediate_operand" ""))
18710 (use (reg:CC FLAGS_REG))
18711 (clobber (match_operand 0 "register_operand" ""))
18712 (clobber (match_operand 1 "register_operand" ""))
18713 (clobber (match_operand 2 "register_operand" ""))])
18714 (set (match_operand:QI 7 "register_operand" "")
18715 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18716 (set (match_operand:QI 8 "register_operand" "")
18717 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18718 (set (reg FLAGS_REG)
18719 (compare (match_dup 7) (match_dup 8)))
18721 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18723 (set (reg:CC FLAGS_REG)
18724 (if_then_else:CC (ne (match_dup 6)
18726 (compare:CC (mem:BLK (match_dup 4))
18727 (mem:BLK (match_dup 5)))
18729 (use (match_dup 3))
18730 (use (reg:CC FLAGS_REG))
18731 (clobber (match_dup 0))
18732 (clobber (match_dup 1))
18733 (clobber (match_dup 2))])]
18738 ;; Conditional move instructions.
18740 (define_expand "movdicc"
18741 [(set (match_operand:DI 0 "register_operand" "")
18742 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18743 (match_operand:DI 2 "general_operand" "")
18744 (match_operand:DI 3 "general_operand" "")))]
18746 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18748 (define_insn "x86_movdicc_0_m1_rex64"
18749 [(set (match_operand:DI 0 "register_operand" "=r")
18750 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18753 (clobber (reg:CC FLAGS_REG))]
18756 ; Since we don't have the proper number of operands for an alu insn,
18757 ; fill in all the blanks.
18758 [(set_attr "type" "alu")
18759 (set_attr "pent_pair" "pu")
18760 (set_attr "memory" "none")
18761 (set_attr "imm_disp" "false")
18762 (set_attr "mode" "DI")
18763 (set_attr "length_immediate" "0")])
18765 (define_insn "*movdicc_c_rex64"
18766 [(set (match_operand:DI 0 "register_operand" "=r,r")
18767 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18768 [(reg FLAGS_REG) (const_int 0)])
18769 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18770 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18771 "TARGET_64BIT && TARGET_CMOVE
18772 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18774 cmov%O2%C1\t{%2, %0|%0, %2}
18775 cmov%O2%c1\t{%3, %0|%0, %3}"
18776 [(set_attr "type" "icmov")
18777 (set_attr "mode" "DI")])
18779 (define_expand "movsicc"
18780 [(set (match_operand:SI 0 "register_operand" "")
18781 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18782 (match_operand:SI 2 "general_operand" "")
18783 (match_operand:SI 3 "general_operand" "")))]
18785 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18787 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18788 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18789 ;; So just document what we're doing explicitly.
18791 (define_insn "x86_movsicc_0_m1"
18792 [(set (match_operand:SI 0 "register_operand" "=r")
18793 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18796 (clobber (reg:CC FLAGS_REG))]
18799 ; Since we don't have the proper number of operands for an alu insn,
18800 ; fill in all the blanks.
18801 [(set_attr "type" "alu")
18802 (set_attr "pent_pair" "pu")
18803 (set_attr "memory" "none")
18804 (set_attr "imm_disp" "false")
18805 (set_attr "mode" "SI")
18806 (set_attr "length_immediate" "0")])
18808 (define_insn "*movsicc_noc"
18809 [(set (match_operand:SI 0 "register_operand" "=r,r")
18810 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18811 [(reg FLAGS_REG) (const_int 0)])
18812 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18813 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18815 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18817 cmov%O2%C1\t{%2, %0|%0, %2}
18818 cmov%O2%c1\t{%3, %0|%0, %3}"
18819 [(set_attr "type" "icmov")
18820 (set_attr "mode" "SI")])
18822 (define_expand "movhicc"
18823 [(set (match_operand:HI 0 "register_operand" "")
18824 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18825 (match_operand:HI 2 "general_operand" "")
18826 (match_operand:HI 3 "general_operand" "")))]
18827 "TARGET_HIMODE_MATH"
18828 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18830 (define_insn "*movhicc_noc"
18831 [(set (match_operand:HI 0 "register_operand" "=r,r")
18832 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18833 [(reg FLAGS_REG) (const_int 0)])
18834 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18835 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18837 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18839 cmov%O2%C1\t{%2, %0|%0, %2}
18840 cmov%O2%c1\t{%3, %0|%0, %3}"
18841 [(set_attr "type" "icmov")
18842 (set_attr "mode" "HI")])
18844 (define_expand "movqicc"
18845 [(set (match_operand:QI 0 "register_operand" "")
18846 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18847 (match_operand:QI 2 "general_operand" "")
18848 (match_operand:QI 3 "general_operand" "")))]
18849 "TARGET_QIMODE_MATH"
18850 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18852 (define_insn_and_split "*movqicc_noc"
18853 [(set (match_operand:QI 0 "register_operand" "=r,r")
18854 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18855 [(match_operand 4 "flags_reg_operand" "")
18857 (match_operand:QI 2 "register_operand" "r,0")
18858 (match_operand:QI 3 "register_operand" "0,r")))]
18859 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18861 "&& reload_completed"
18862 [(set (match_dup 0)
18863 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18866 "operands[0] = gen_lowpart (SImode, operands[0]);
18867 operands[2] = gen_lowpart (SImode, operands[2]);
18868 operands[3] = gen_lowpart (SImode, operands[3]);"
18869 [(set_attr "type" "icmov")
18870 (set_attr "mode" "SI")])
18872 (define_expand "movsfcc"
18873 [(set (match_operand:SF 0 "register_operand" "")
18874 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18875 (match_operand:SF 2 "register_operand" "")
18876 (match_operand:SF 3 "register_operand" "")))]
18877 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18878 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18880 (define_insn "*movsfcc_1_387"
18881 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18882 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18883 [(reg FLAGS_REG) (const_int 0)])
18884 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18885 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18886 "TARGET_80387 && TARGET_CMOVE
18887 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18889 fcmov%F1\t{%2, %0|%0, %2}
18890 fcmov%f1\t{%3, %0|%0, %3}
18891 cmov%O2%C1\t{%2, %0|%0, %2}
18892 cmov%O2%c1\t{%3, %0|%0, %3}"
18893 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18894 (set_attr "mode" "SF,SF,SI,SI")])
18896 (define_expand "movdfcc"
18897 [(set (match_operand:DF 0 "register_operand" "")
18898 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18899 (match_operand:DF 2 "register_operand" "")
18900 (match_operand:DF 3 "register_operand" "")))]
18901 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18902 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18904 (define_insn "*movdfcc_1"
18905 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18906 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18907 [(reg FLAGS_REG) (const_int 0)])
18908 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18909 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18910 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18911 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18913 fcmov%F1\t{%2, %0|%0, %2}
18914 fcmov%f1\t{%3, %0|%0, %3}
18917 [(set_attr "type" "fcmov,fcmov,multi,multi")
18918 (set_attr "mode" "DF")])
18920 (define_insn "*movdfcc_1_rex64"
18921 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18922 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18923 [(reg FLAGS_REG) (const_int 0)])
18924 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18925 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18926 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18927 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18929 fcmov%F1\t{%2, %0|%0, %2}
18930 fcmov%f1\t{%3, %0|%0, %3}
18931 cmov%O2%C1\t{%2, %0|%0, %2}
18932 cmov%O2%c1\t{%3, %0|%0, %3}"
18933 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18934 (set_attr "mode" "DF")])
18937 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18938 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18939 [(match_operand 4 "flags_reg_operand" "")
18941 (match_operand:DF 2 "nonimmediate_operand" "")
18942 (match_operand:DF 3 "nonimmediate_operand" "")))]
18943 "!TARGET_64BIT && reload_completed"
18944 [(set (match_dup 2)
18945 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18949 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18952 "split_di (operands+2, 1, operands+5, operands+6);
18953 split_di (operands+3, 1, operands+7, operands+8);
18954 split_di (operands, 1, operands+2, operands+3);")
18956 (define_expand "movxfcc"
18957 [(set (match_operand:XF 0 "register_operand" "")
18958 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18959 (match_operand:XF 2 "register_operand" "")
18960 (match_operand:XF 3 "register_operand" "")))]
18961 "TARGET_80387 && TARGET_CMOVE"
18962 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18964 (define_insn "*movxfcc_1"
18965 [(set (match_operand:XF 0 "register_operand" "=f,f")
18966 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18967 [(reg FLAGS_REG) (const_int 0)])
18968 (match_operand:XF 2 "register_operand" "f,0")
18969 (match_operand:XF 3 "register_operand" "0,f")))]
18970 "TARGET_80387 && TARGET_CMOVE"
18972 fcmov%F1\t{%2, %0|%0, %2}
18973 fcmov%f1\t{%3, %0|%0, %3}"
18974 [(set_attr "type" "fcmov")
18975 (set_attr "mode" "XF")])
18977 ;; These versions of the min/max patterns are intentionally ignorant of
18978 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18979 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18980 ;; are undefined in this condition, we're certain this is correct.
18982 (define_insn "sminsf3"
18983 [(set (match_operand:SF 0 "register_operand" "=x")
18984 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18985 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18987 "minss\t{%2, %0|%0, %2}"
18988 [(set_attr "type" "sseadd")
18989 (set_attr "mode" "SF")])
18991 (define_insn "smaxsf3"
18992 [(set (match_operand:SF 0 "register_operand" "=x")
18993 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18994 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18996 "maxss\t{%2, %0|%0, %2}"
18997 [(set_attr "type" "sseadd")
18998 (set_attr "mode" "SF")])
19000 (define_insn "smindf3"
19001 [(set (match_operand:DF 0 "register_operand" "=x")
19002 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19003 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19004 "TARGET_SSE2 && TARGET_SSE_MATH"
19005 "minsd\t{%2, %0|%0, %2}"
19006 [(set_attr "type" "sseadd")
19007 (set_attr "mode" "DF")])
19009 (define_insn "smaxdf3"
19010 [(set (match_operand:DF 0 "register_operand" "=x")
19011 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19012 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19013 "TARGET_SSE2 && TARGET_SSE_MATH"
19014 "maxsd\t{%2, %0|%0, %2}"
19015 [(set_attr "type" "sseadd")
19016 (set_attr "mode" "DF")])
19018 ;; These versions of the min/max patterns implement exactly the operations
19019 ;; min = (op1 < op2 ? op1 : op2)
19020 ;; max = (!(op1 < op2) ? op1 : op2)
19021 ;; Their operands are not commutative, and thus they may be used in the
19022 ;; presence of -0.0 and NaN.
19024 (define_insn "*ieee_sminsf3"
19025 [(set (match_operand:SF 0 "register_operand" "=x")
19026 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19027 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19030 "minss\t{%2, %0|%0, %2}"
19031 [(set_attr "type" "sseadd")
19032 (set_attr "mode" "SF")])
19034 (define_insn "*ieee_smaxsf3"
19035 [(set (match_operand:SF 0 "register_operand" "=x")
19036 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19037 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19040 "maxss\t{%2, %0|%0, %2}"
19041 [(set_attr "type" "sseadd")
19042 (set_attr "mode" "SF")])
19044 (define_insn "*ieee_smindf3"
19045 [(set (match_operand:DF 0 "register_operand" "=x")
19046 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19047 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19049 "TARGET_SSE2 && TARGET_SSE_MATH"
19050 "minsd\t{%2, %0|%0, %2}"
19051 [(set_attr "type" "sseadd")
19052 (set_attr "mode" "DF")])
19054 (define_insn "*ieee_smaxdf3"
19055 [(set (match_operand:DF 0 "register_operand" "=x")
19056 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19057 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19059 "TARGET_SSE2 && TARGET_SSE_MATH"
19060 "maxsd\t{%2, %0|%0, %2}"
19061 [(set_attr "type" "sseadd")
19062 (set_attr "mode" "DF")])
19064 ;; Make two stack loads independent:
19066 ;; fld %st(0) -> fld bb
19067 ;; fmul bb fmul %st(1), %st
19069 ;; Actually we only match the last two instructions for simplicity.
19071 [(set (match_operand 0 "fp_register_operand" "")
19072 (match_operand 1 "fp_register_operand" ""))
19074 (match_operator 2 "binary_fp_operator"
19076 (match_operand 3 "memory_operand" "")]))]
19077 "REGNO (operands[0]) != REGNO (operands[1])"
19078 [(set (match_dup 0) (match_dup 3))
19079 (set (match_dup 0) (match_dup 4))]
19081 ;; The % modifier is not operational anymore in peephole2's, so we have to
19082 ;; swap the operands manually in the case of addition and multiplication.
19083 "if (COMMUTATIVE_ARITH_P (operands[2]))
19084 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19085 operands[0], operands[1]);
19087 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19088 operands[1], operands[0]);")
19090 ;; Conditional addition patterns
19091 (define_expand "addqicc"
19092 [(match_operand:QI 0 "register_operand" "")
19093 (match_operand 1 "comparison_operator" "")
19094 (match_operand:QI 2 "register_operand" "")
19095 (match_operand:QI 3 "const_int_operand" "")]
19097 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19099 (define_expand "addhicc"
19100 [(match_operand:HI 0 "register_operand" "")
19101 (match_operand 1 "comparison_operator" "")
19102 (match_operand:HI 2 "register_operand" "")
19103 (match_operand:HI 3 "const_int_operand" "")]
19105 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19107 (define_expand "addsicc"
19108 [(match_operand:SI 0 "register_operand" "")
19109 (match_operand 1 "comparison_operator" "")
19110 (match_operand:SI 2 "register_operand" "")
19111 (match_operand:SI 3 "const_int_operand" "")]
19113 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19115 (define_expand "adddicc"
19116 [(match_operand:DI 0 "register_operand" "")
19117 (match_operand 1 "comparison_operator" "")
19118 (match_operand:DI 2 "register_operand" "")
19119 (match_operand:DI 3 "const_int_operand" "")]
19121 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19124 ;; Misc patterns (?)
19126 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19127 ;; Otherwise there will be nothing to keep
19129 ;; [(set (reg ebp) (reg esp))]
19130 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19131 ;; (clobber (eflags)]
19132 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19134 ;; in proper program order.
19135 (define_insn "pro_epilogue_adjust_stack_1"
19136 [(set (match_operand:SI 0 "register_operand" "=r,r")
19137 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19138 (match_operand:SI 2 "immediate_operand" "i,i")))
19139 (clobber (reg:CC FLAGS_REG))
19140 (clobber (mem:BLK (scratch)))]
19143 switch (get_attr_type (insn))
19146 return "mov{l}\t{%1, %0|%0, %1}";
19149 if (CONST_INT_P (operands[2])
19150 && (INTVAL (operands[2]) == 128
19151 || (INTVAL (operands[2]) < 0
19152 && INTVAL (operands[2]) != -128)))
19154 operands[2] = GEN_INT (-INTVAL (operands[2]));
19155 return "sub{l}\t{%2, %0|%0, %2}";
19157 return "add{l}\t{%2, %0|%0, %2}";
19160 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19161 return "lea{l}\t{%a2, %0|%0, %a2}";
19164 gcc_unreachable ();
19167 [(set (attr "type")
19168 (cond [(eq_attr "alternative" "0")
19169 (const_string "alu")
19170 (match_operand:SI 2 "const0_operand" "")
19171 (const_string "imov")
19173 (const_string "lea")))
19174 (set_attr "mode" "SI")])
19176 (define_insn "pro_epilogue_adjust_stack_rex64"
19177 [(set (match_operand:DI 0 "register_operand" "=r,r")
19178 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19179 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19180 (clobber (reg:CC FLAGS_REG))
19181 (clobber (mem:BLK (scratch)))]
19184 switch (get_attr_type (insn))
19187 return "mov{q}\t{%1, %0|%0, %1}";
19190 if (CONST_INT_P (operands[2])
19191 /* Avoid overflows. */
19192 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19193 && (INTVAL (operands[2]) == 128
19194 || (INTVAL (operands[2]) < 0
19195 && INTVAL (operands[2]) != -128)))
19197 operands[2] = GEN_INT (-INTVAL (operands[2]));
19198 return "sub{q}\t{%2, %0|%0, %2}";
19200 return "add{q}\t{%2, %0|%0, %2}";
19203 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19204 return "lea{q}\t{%a2, %0|%0, %a2}";
19207 gcc_unreachable ();
19210 [(set (attr "type")
19211 (cond [(eq_attr "alternative" "0")
19212 (const_string "alu")
19213 (match_operand:DI 2 "const0_operand" "")
19214 (const_string "imov")
19216 (const_string "lea")))
19217 (set_attr "mode" "DI")])
19219 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19220 [(set (match_operand:DI 0 "register_operand" "=r,r")
19221 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19222 (match_operand:DI 3 "immediate_operand" "i,i")))
19223 (use (match_operand:DI 2 "register_operand" "r,r"))
19224 (clobber (reg:CC FLAGS_REG))
19225 (clobber (mem:BLK (scratch)))]
19228 switch (get_attr_type (insn))
19231 return "add{q}\t{%2, %0|%0, %2}";
19234 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19235 return "lea{q}\t{%a2, %0|%0, %a2}";
19238 gcc_unreachable ();
19241 [(set_attr "type" "alu,lea")
19242 (set_attr "mode" "DI")])
19244 (define_expand "allocate_stack_worker"
19245 [(match_operand:SI 0 "register_operand" "")]
19246 "TARGET_STACK_PROBE"
19248 if (reload_completed)
19251 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19253 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19258 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19260 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19265 (define_insn "allocate_stack_worker_1"
19266 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19267 UNSPECV_STACK_PROBE)
19268 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19269 (clobber (match_scratch:SI 1 "=0"))
19270 (clobber (reg:CC FLAGS_REG))]
19271 "!TARGET_64BIT && TARGET_STACK_PROBE"
19273 [(set_attr "type" "multi")
19274 (set_attr "length" "5")])
19276 (define_expand "allocate_stack_worker_postreload"
19277 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19278 UNSPECV_STACK_PROBE)
19279 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19280 (clobber (match_dup 0))
19281 (clobber (reg:CC FLAGS_REG))])]
19285 (define_insn "allocate_stack_worker_rex64"
19286 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19287 UNSPECV_STACK_PROBE)
19288 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19289 (clobber (match_scratch:DI 1 "=0"))
19290 (clobber (reg:CC FLAGS_REG))]
19291 "TARGET_64BIT && TARGET_STACK_PROBE"
19293 [(set_attr "type" "multi")
19294 (set_attr "length" "5")])
19296 (define_expand "allocate_stack_worker_rex64_postreload"
19297 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19298 UNSPECV_STACK_PROBE)
19299 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19300 (clobber (match_dup 0))
19301 (clobber (reg:CC FLAGS_REG))])]
19305 (define_expand "allocate_stack"
19306 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19307 (minus:SI (reg:SI SP_REG)
19308 (match_operand:SI 1 "general_operand" "")))
19309 (clobber (reg:CC FLAGS_REG))])
19310 (parallel [(set (reg:SI SP_REG)
19311 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19312 (clobber (reg:CC FLAGS_REG))])]
19313 "TARGET_STACK_PROBE"
19315 #ifdef CHECK_STACK_LIMIT
19316 if (CONST_INT_P (operands[1])
19317 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19318 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19322 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19325 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19329 (define_expand "builtin_setjmp_receiver"
19330 [(label_ref (match_operand 0 "" ""))]
19331 "!TARGET_64BIT && flag_pic"
19336 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19337 rtx label_rtx = gen_label_rtx ();
19338 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19339 xops[0] = xops[1] = picreg;
19340 xops[2] = gen_rtx_CONST (SImode,
19341 gen_rtx_MINUS (SImode,
19342 gen_rtx_LABEL_REF (SImode, label_rtx),
19343 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19344 ix86_expand_binary_operator (MINUS, SImode, xops);
19347 emit_insn (gen_set_got (pic_offset_table_rtx));
19351 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19354 [(set (match_operand 0 "register_operand" "")
19355 (match_operator 3 "promotable_binary_operator"
19356 [(match_operand 1 "register_operand" "")
19357 (match_operand 2 "aligned_operand" "")]))
19358 (clobber (reg:CC FLAGS_REG))]
19359 "! TARGET_PARTIAL_REG_STALL && reload_completed
19360 && ((GET_MODE (operands[0]) == HImode
19361 && ((!optimize_size && !TARGET_FAST_PREFIX)
19362 /* ??? next two lines just !satisfies_constraint_K (...) */
19363 || !CONST_INT_P (operands[2])
19364 || satisfies_constraint_K (operands[2])))
19365 || (GET_MODE (operands[0]) == QImode
19366 && (TARGET_PROMOTE_QImode || optimize_size)))"
19367 [(parallel [(set (match_dup 0)
19368 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19369 (clobber (reg:CC FLAGS_REG))])]
19370 "operands[0] = gen_lowpart (SImode, operands[0]);
19371 operands[1] = gen_lowpart (SImode, operands[1]);
19372 if (GET_CODE (operands[3]) != ASHIFT)
19373 operands[2] = gen_lowpart (SImode, operands[2]);
19374 PUT_MODE (operands[3], SImode);")
19376 ; Promote the QImode tests, as i386 has encoding of the AND
19377 ; instruction with 32-bit sign-extended immediate and thus the
19378 ; instruction size is unchanged, except in the %eax case for
19379 ; which it is increased by one byte, hence the ! optimize_size.
19381 [(set (match_operand 0 "flags_reg_operand" "")
19382 (match_operator 2 "compare_operator"
19383 [(and (match_operand 3 "aligned_operand" "")
19384 (match_operand 4 "const_int_operand" ""))
19386 (set (match_operand 1 "register_operand" "")
19387 (and (match_dup 3) (match_dup 4)))]
19388 "! TARGET_PARTIAL_REG_STALL && reload_completed
19389 /* Ensure that the operand will remain sign-extended immediate. */
19390 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19392 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19393 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19394 [(parallel [(set (match_dup 0)
19395 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19398 (and:SI (match_dup 3) (match_dup 4)))])]
19401 = gen_int_mode (INTVAL (operands[4])
19402 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19403 operands[1] = gen_lowpart (SImode, operands[1]);
19404 operands[3] = gen_lowpart (SImode, operands[3]);
19407 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19408 ; the TEST instruction with 32-bit sign-extended immediate and thus
19409 ; the instruction size would at least double, which is not what we
19410 ; want even with ! optimize_size.
19412 [(set (match_operand 0 "flags_reg_operand" "")
19413 (match_operator 1 "compare_operator"
19414 [(and (match_operand:HI 2 "aligned_operand" "")
19415 (match_operand:HI 3 "const_int_operand" ""))
19417 "! TARGET_PARTIAL_REG_STALL && reload_completed
19418 /* Ensure that the operand will remain sign-extended immediate. */
19419 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19420 && ! TARGET_FAST_PREFIX
19421 && ! optimize_size"
19422 [(set (match_dup 0)
19423 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19427 = gen_int_mode (INTVAL (operands[3])
19428 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19429 operands[2] = gen_lowpart (SImode, operands[2]);
19433 [(set (match_operand 0 "register_operand" "")
19434 (neg (match_operand 1 "register_operand" "")))
19435 (clobber (reg:CC FLAGS_REG))]
19436 "! TARGET_PARTIAL_REG_STALL && reload_completed
19437 && (GET_MODE (operands[0]) == HImode
19438 || (GET_MODE (operands[0]) == QImode
19439 && (TARGET_PROMOTE_QImode || optimize_size)))"
19440 [(parallel [(set (match_dup 0)
19441 (neg:SI (match_dup 1)))
19442 (clobber (reg:CC FLAGS_REG))])]
19443 "operands[0] = gen_lowpart (SImode, operands[0]);
19444 operands[1] = gen_lowpart (SImode, operands[1]);")
19447 [(set (match_operand 0 "register_operand" "")
19448 (not (match_operand 1 "register_operand" "")))]
19449 "! TARGET_PARTIAL_REG_STALL && reload_completed
19450 && (GET_MODE (operands[0]) == HImode
19451 || (GET_MODE (operands[0]) == QImode
19452 && (TARGET_PROMOTE_QImode || optimize_size)))"
19453 [(set (match_dup 0)
19454 (not:SI (match_dup 1)))]
19455 "operands[0] = gen_lowpart (SImode, operands[0]);
19456 operands[1] = gen_lowpart (SImode, operands[1]);")
19459 [(set (match_operand 0 "register_operand" "")
19460 (if_then_else (match_operator 1 "comparison_operator"
19461 [(reg FLAGS_REG) (const_int 0)])
19462 (match_operand 2 "register_operand" "")
19463 (match_operand 3 "register_operand" "")))]
19464 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19465 && (GET_MODE (operands[0]) == HImode
19466 || (GET_MODE (operands[0]) == QImode
19467 && (TARGET_PROMOTE_QImode || optimize_size)))"
19468 [(set (match_dup 0)
19469 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19470 "operands[0] = gen_lowpart (SImode, operands[0]);
19471 operands[2] = gen_lowpart (SImode, operands[2]);
19472 operands[3] = gen_lowpart (SImode, operands[3]);")
19475 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19476 ;; transform a complex memory operation into two memory to register operations.
19478 ;; Don't push memory operands
19480 [(set (match_operand:SI 0 "push_operand" "")
19481 (match_operand:SI 1 "memory_operand" ""))
19482 (match_scratch:SI 2 "r")]
19483 "!optimize_size && !TARGET_PUSH_MEMORY
19484 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19485 [(set (match_dup 2) (match_dup 1))
19486 (set (match_dup 0) (match_dup 2))]
19490 [(set (match_operand:DI 0 "push_operand" "")
19491 (match_operand:DI 1 "memory_operand" ""))
19492 (match_scratch:DI 2 "r")]
19493 "!optimize_size && !TARGET_PUSH_MEMORY
19494 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19495 [(set (match_dup 2) (match_dup 1))
19496 (set (match_dup 0) (match_dup 2))]
19499 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19502 [(set (match_operand:SF 0 "push_operand" "")
19503 (match_operand:SF 1 "memory_operand" ""))
19504 (match_scratch:SF 2 "r")]
19505 "!optimize_size && !TARGET_PUSH_MEMORY
19506 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19507 [(set (match_dup 2) (match_dup 1))
19508 (set (match_dup 0) (match_dup 2))]
19512 [(set (match_operand:HI 0 "push_operand" "")
19513 (match_operand:HI 1 "memory_operand" ""))
19514 (match_scratch:HI 2 "r")]
19515 "!optimize_size && !TARGET_PUSH_MEMORY
19516 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19517 [(set (match_dup 2) (match_dup 1))
19518 (set (match_dup 0) (match_dup 2))]
19522 [(set (match_operand:QI 0 "push_operand" "")
19523 (match_operand:QI 1 "memory_operand" ""))
19524 (match_scratch:QI 2 "q")]
19525 "!optimize_size && !TARGET_PUSH_MEMORY
19526 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19527 [(set (match_dup 2) (match_dup 1))
19528 (set (match_dup 0) (match_dup 2))]
19531 ;; Don't move an immediate directly to memory when the instruction
19534 [(match_scratch:SI 1 "r")
19535 (set (match_operand:SI 0 "memory_operand" "")
19538 && ! TARGET_USE_MOV0
19539 && TARGET_SPLIT_LONG_MOVES
19540 && get_attr_length (insn) >= ix86_cost->large_insn
19541 && peep2_regno_dead_p (0, FLAGS_REG)"
19542 [(parallel [(set (match_dup 1) (const_int 0))
19543 (clobber (reg:CC FLAGS_REG))])
19544 (set (match_dup 0) (match_dup 1))]
19548 [(match_scratch:HI 1 "r")
19549 (set (match_operand:HI 0 "memory_operand" "")
19552 && ! TARGET_USE_MOV0
19553 && TARGET_SPLIT_LONG_MOVES
19554 && get_attr_length (insn) >= ix86_cost->large_insn
19555 && peep2_regno_dead_p (0, FLAGS_REG)"
19556 [(parallel [(set (match_dup 2) (const_int 0))
19557 (clobber (reg:CC FLAGS_REG))])
19558 (set (match_dup 0) (match_dup 1))]
19559 "operands[2] = gen_lowpart (SImode, operands[1]);")
19562 [(match_scratch:QI 1 "q")
19563 (set (match_operand:QI 0 "memory_operand" "")
19566 && ! TARGET_USE_MOV0
19567 && TARGET_SPLIT_LONG_MOVES
19568 && get_attr_length (insn) >= ix86_cost->large_insn
19569 && peep2_regno_dead_p (0, FLAGS_REG)"
19570 [(parallel [(set (match_dup 2) (const_int 0))
19571 (clobber (reg:CC FLAGS_REG))])
19572 (set (match_dup 0) (match_dup 1))]
19573 "operands[2] = gen_lowpart (SImode, operands[1]);")
19576 [(match_scratch:SI 2 "r")
19577 (set (match_operand:SI 0 "memory_operand" "")
19578 (match_operand:SI 1 "immediate_operand" ""))]
19580 && get_attr_length (insn) >= ix86_cost->large_insn
19581 && TARGET_SPLIT_LONG_MOVES"
19582 [(set (match_dup 2) (match_dup 1))
19583 (set (match_dup 0) (match_dup 2))]
19587 [(match_scratch:HI 2 "r")
19588 (set (match_operand:HI 0 "memory_operand" "")
19589 (match_operand:HI 1 "immediate_operand" ""))]
19590 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19591 && TARGET_SPLIT_LONG_MOVES"
19592 [(set (match_dup 2) (match_dup 1))
19593 (set (match_dup 0) (match_dup 2))]
19597 [(match_scratch:QI 2 "q")
19598 (set (match_operand:QI 0 "memory_operand" "")
19599 (match_operand:QI 1 "immediate_operand" ""))]
19600 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19601 && TARGET_SPLIT_LONG_MOVES"
19602 [(set (match_dup 2) (match_dup 1))
19603 (set (match_dup 0) (match_dup 2))]
19606 ;; Don't compare memory with zero, load and use a test instead.
19608 [(set (match_operand 0 "flags_reg_operand" "")
19609 (match_operator 1 "compare_operator"
19610 [(match_operand:SI 2 "memory_operand" "")
19612 (match_scratch:SI 3 "r")]
19613 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19614 [(set (match_dup 3) (match_dup 2))
19615 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19618 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19619 ;; Don't split NOTs with a displacement operand, because resulting XOR
19620 ;; will not be pairable anyway.
19622 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19623 ;; represented using a modRM byte. The XOR replacement is long decoded,
19624 ;; so this split helps here as well.
19626 ;; Note: Can't do this as a regular split because we can't get proper
19627 ;; lifetime information then.
19630 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19631 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19633 && peep2_regno_dead_p (0, FLAGS_REG)
19634 && ((TARGET_PENTIUM
19635 && (!MEM_P (operands[0])
19636 || !memory_displacement_operand (operands[0], SImode)))
19637 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19638 [(parallel [(set (match_dup 0)
19639 (xor:SI (match_dup 1) (const_int -1)))
19640 (clobber (reg:CC FLAGS_REG))])]
19644 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19645 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19647 && peep2_regno_dead_p (0, FLAGS_REG)
19648 && ((TARGET_PENTIUM
19649 && (!MEM_P (operands[0])
19650 || !memory_displacement_operand (operands[0], HImode)))
19651 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19652 [(parallel [(set (match_dup 0)
19653 (xor:HI (match_dup 1) (const_int -1)))
19654 (clobber (reg:CC FLAGS_REG))])]
19658 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19659 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19661 && peep2_regno_dead_p (0, FLAGS_REG)
19662 && ((TARGET_PENTIUM
19663 && (!MEM_P (operands[0])
19664 || !memory_displacement_operand (operands[0], QImode)))
19665 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19666 [(parallel [(set (match_dup 0)
19667 (xor:QI (match_dup 1) (const_int -1)))
19668 (clobber (reg:CC FLAGS_REG))])]
19671 ;; Non pairable "test imm, reg" instructions can be translated to
19672 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19673 ;; byte opcode instead of two, have a short form for byte operands),
19674 ;; so do it for other CPUs as well. Given that the value was dead,
19675 ;; this should not create any new dependencies. Pass on the sub-word
19676 ;; versions if we're concerned about partial register stalls.
19679 [(set (match_operand 0 "flags_reg_operand" "")
19680 (match_operator 1 "compare_operator"
19681 [(and:SI (match_operand:SI 2 "register_operand" "")
19682 (match_operand:SI 3 "immediate_operand" ""))
19684 "ix86_match_ccmode (insn, CCNOmode)
19685 && (true_regnum (operands[2]) != 0
19686 || satisfies_constraint_K (operands[3]))
19687 && peep2_reg_dead_p (1, operands[2])"
19689 [(set (match_dup 0)
19690 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19693 (and:SI (match_dup 2) (match_dup 3)))])]
19696 ;; We don't need to handle HImode case, because it will be promoted to SImode
19697 ;; on ! TARGET_PARTIAL_REG_STALL
19700 [(set (match_operand 0 "flags_reg_operand" "")
19701 (match_operator 1 "compare_operator"
19702 [(and:QI (match_operand:QI 2 "register_operand" "")
19703 (match_operand:QI 3 "immediate_operand" ""))
19705 "! TARGET_PARTIAL_REG_STALL
19706 && ix86_match_ccmode (insn, CCNOmode)
19707 && true_regnum (operands[2]) != 0
19708 && peep2_reg_dead_p (1, operands[2])"
19710 [(set (match_dup 0)
19711 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19714 (and:QI (match_dup 2) (match_dup 3)))])]
19718 [(set (match_operand 0 "flags_reg_operand" "")
19719 (match_operator 1 "compare_operator"
19722 (match_operand 2 "ext_register_operand" "")
19725 (match_operand 3 "const_int_operand" ""))
19727 "! TARGET_PARTIAL_REG_STALL
19728 && ix86_match_ccmode (insn, CCNOmode)
19729 && true_regnum (operands[2]) != 0
19730 && peep2_reg_dead_p (1, operands[2])"
19731 [(parallel [(set (match_dup 0)
19740 (set (zero_extract:SI (match_dup 2)
19751 ;; Don't do logical operations with memory inputs.
19753 [(match_scratch:SI 2 "r")
19754 (parallel [(set (match_operand:SI 0 "register_operand" "")
19755 (match_operator:SI 3 "arith_or_logical_operator"
19757 (match_operand:SI 1 "memory_operand" "")]))
19758 (clobber (reg:CC FLAGS_REG))])]
19759 "! optimize_size && ! TARGET_READ_MODIFY"
19760 [(set (match_dup 2) (match_dup 1))
19761 (parallel [(set (match_dup 0)
19762 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19763 (clobber (reg:CC FLAGS_REG))])]
19767 [(match_scratch:SI 2 "r")
19768 (parallel [(set (match_operand:SI 0 "register_operand" "")
19769 (match_operator:SI 3 "arith_or_logical_operator"
19770 [(match_operand:SI 1 "memory_operand" "")
19772 (clobber (reg:CC FLAGS_REG))])]
19773 "! optimize_size && ! TARGET_READ_MODIFY"
19774 [(set (match_dup 2) (match_dup 1))
19775 (parallel [(set (match_dup 0)
19776 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19777 (clobber (reg:CC FLAGS_REG))])]
19780 ; Don't do logical operations with memory outputs
19782 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19783 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19784 ; the same decoder scheduling characteristics as the original.
19787 [(match_scratch:SI 2 "r")
19788 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19789 (match_operator:SI 3 "arith_or_logical_operator"
19791 (match_operand:SI 1 "nonmemory_operand" "")]))
19792 (clobber (reg:CC FLAGS_REG))])]
19793 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19794 [(set (match_dup 2) (match_dup 0))
19795 (parallel [(set (match_dup 2)
19796 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19797 (clobber (reg:CC FLAGS_REG))])
19798 (set (match_dup 0) (match_dup 2))]
19802 [(match_scratch:SI 2 "r")
19803 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19804 (match_operator:SI 3 "arith_or_logical_operator"
19805 [(match_operand:SI 1 "nonmemory_operand" "")
19807 (clobber (reg:CC FLAGS_REG))])]
19808 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19809 [(set (match_dup 2) (match_dup 0))
19810 (parallel [(set (match_dup 2)
19811 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19812 (clobber (reg:CC FLAGS_REG))])
19813 (set (match_dup 0) (match_dup 2))]
19816 ;; Attempt to always use XOR for zeroing registers.
19818 [(set (match_operand 0 "register_operand" "")
19819 (match_operand 1 "const0_operand" ""))]
19820 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19821 && (! TARGET_USE_MOV0 || optimize_size)
19822 && GENERAL_REG_P (operands[0])
19823 && peep2_regno_dead_p (0, FLAGS_REG)"
19824 [(parallel [(set (match_dup 0) (const_int 0))
19825 (clobber (reg:CC FLAGS_REG))])]
19827 operands[0] = gen_lowpart (word_mode, operands[0]);
19831 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19833 "(GET_MODE (operands[0]) == QImode
19834 || GET_MODE (operands[0]) == HImode)
19835 && (! TARGET_USE_MOV0 || optimize_size)
19836 && peep2_regno_dead_p (0, FLAGS_REG)"
19837 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19838 (clobber (reg:CC FLAGS_REG))])])
19840 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19842 [(set (match_operand 0 "register_operand" "")
19844 "(GET_MODE (operands[0]) == HImode
19845 || GET_MODE (operands[0]) == SImode
19846 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19847 && (optimize_size || TARGET_PENTIUM)
19848 && peep2_regno_dead_p (0, FLAGS_REG)"
19849 [(parallel [(set (match_dup 0) (const_int -1))
19850 (clobber (reg:CC FLAGS_REG))])]
19851 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19854 ;; Attempt to convert simple leas to adds. These can be created by
19857 [(set (match_operand:SI 0 "register_operand" "")
19858 (plus:SI (match_dup 0)
19859 (match_operand:SI 1 "nonmemory_operand" "")))]
19860 "peep2_regno_dead_p (0, FLAGS_REG)"
19861 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19862 (clobber (reg:CC FLAGS_REG))])]
19866 [(set (match_operand:SI 0 "register_operand" "")
19867 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19868 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19869 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19870 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19871 (clobber (reg:CC FLAGS_REG))])]
19872 "operands[2] = gen_lowpart (SImode, operands[2]);")
19875 [(set (match_operand:DI 0 "register_operand" "")
19876 (plus:DI (match_dup 0)
19877 (match_operand:DI 1 "x86_64_general_operand" "")))]
19878 "peep2_regno_dead_p (0, FLAGS_REG)"
19879 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19880 (clobber (reg:CC FLAGS_REG))])]
19884 [(set (match_operand:SI 0 "register_operand" "")
19885 (mult:SI (match_dup 0)
19886 (match_operand:SI 1 "const_int_operand" "")))]
19887 "exact_log2 (INTVAL (operands[1])) >= 0
19888 && peep2_regno_dead_p (0, FLAGS_REG)"
19889 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19890 (clobber (reg:CC FLAGS_REG))])]
19891 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19894 [(set (match_operand:DI 0 "register_operand" "")
19895 (mult:DI (match_dup 0)
19896 (match_operand:DI 1 "const_int_operand" "")))]
19897 "exact_log2 (INTVAL (operands[1])) >= 0
19898 && peep2_regno_dead_p (0, FLAGS_REG)"
19899 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19900 (clobber (reg:CC FLAGS_REG))])]
19901 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19904 [(set (match_operand:SI 0 "register_operand" "")
19905 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19906 (match_operand:DI 2 "const_int_operand" "")) 0))]
19907 "exact_log2 (INTVAL (operands[2])) >= 0
19908 && REGNO (operands[0]) == REGNO (operands[1])
19909 && peep2_regno_dead_p (0, FLAGS_REG)"
19910 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19911 (clobber (reg:CC FLAGS_REG))])]
19912 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19914 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19915 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19916 ;; many CPUs it is also faster, since special hardware to avoid esp
19917 ;; dependencies is present.
19919 ;; While some of these conversions may be done using splitters, we use peepholes
19920 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19922 ;; Convert prologue esp subtractions to push.
19923 ;; We need register to push. In order to keep verify_flow_info happy we have
19925 ;; - use scratch and clobber it in order to avoid dependencies
19926 ;; - use already live register
19927 ;; We can't use the second way right now, since there is no reliable way how to
19928 ;; verify that given register is live. First choice will also most likely in
19929 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19930 ;; call clobbered registers are dead. We may want to use base pointer as an
19931 ;; alternative when no register is available later.
19934 [(match_scratch:SI 0 "r")
19935 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19936 (clobber (reg:CC FLAGS_REG))
19937 (clobber (mem:BLK (scratch)))])]
19938 "optimize_size || !TARGET_SUB_ESP_4"
19939 [(clobber (match_dup 0))
19940 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19941 (clobber (mem:BLK (scratch)))])])
19944 [(match_scratch:SI 0 "r")
19945 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19946 (clobber (reg:CC FLAGS_REG))
19947 (clobber (mem:BLK (scratch)))])]
19948 "optimize_size || !TARGET_SUB_ESP_8"
19949 [(clobber (match_dup 0))
19950 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19951 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19952 (clobber (mem:BLK (scratch)))])])
19954 ;; Convert esp subtractions to push.
19956 [(match_scratch:SI 0 "r")
19957 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19958 (clobber (reg:CC FLAGS_REG))])]
19959 "optimize_size || !TARGET_SUB_ESP_4"
19960 [(clobber (match_dup 0))
19961 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19964 [(match_scratch:SI 0 "r")
19965 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19966 (clobber (reg:CC FLAGS_REG))])]
19967 "optimize_size || !TARGET_SUB_ESP_8"
19968 [(clobber (match_dup 0))
19969 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19970 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19972 ;; Convert epilogue deallocator to pop.
19974 [(match_scratch:SI 0 "r")
19975 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19976 (clobber (reg:CC FLAGS_REG))
19977 (clobber (mem:BLK (scratch)))])]
19978 "optimize_size || !TARGET_ADD_ESP_4"
19979 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19980 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19981 (clobber (mem:BLK (scratch)))])]
19984 ;; Two pops case is tricky, since pop causes dependency on destination register.
19985 ;; We use two registers if available.
19987 [(match_scratch:SI 0 "r")
19988 (match_scratch:SI 1 "r")
19989 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19990 (clobber (reg:CC FLAGS_REG))
19991 (clobber (mem:BLK (scratch)))])]
19992 "optimize_size || !TARGET_ADD_ESP_8"
19993 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19994 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19995 (clobber (mem:BLK (scratch)))])
19996 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19997 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20001 [(match_scratch:SI 0 "r")
20002 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20003 (clobber (reg:CC FLAGS_REG))
20004 (clobber (mem:BLK (scratch)))])]
20006 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20007 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20008 (clobber (mem:BLK (scratch)))])
20009 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20010 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20013 ;; Convert esp additions to pop.
20015 [(match_scratch:SI 0 "r")
20016 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20017 (clobber (reg:CC FLAGS_REG))])]
20019 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20020 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20023 ;; Two pops case is tricky, since pop causes dependency on destination register.
20024 ;; We use two registers if available.
20026 [(match_scratch:SI 0 "r")
20027 (match_scratch:SI 1 "r")
20028 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20029 (clobber (reg:CC FLAGS_REG))])]
20031 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20032 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20033 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20034 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20038 [(match_scratch:SI 0 "r")
20039 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20040 (clobber (reg:CC FLAGS_REG))])]
20042 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20043 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20044 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20045 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20048 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20049 ;; required and register dies. Similarly for 128 to plus -128.
20051 [(set (match_operand 0 "flags_reg_operand" "")
20052 (match_operator 1 "compare_operator"
20053 [(match_operand 2 "register_operand" "")
20054 (match_operand 3 "const_int_operand" "")]))]
20055 "(INTVAL (operands[3]) == -1
20056 || INTVAL (operands[3]) == 1
20057 || INTVAL (operands[3]) == 128)
20058 && ix86_match_ccmode (insn, CCGCmode)
20059 && peep2_reg_dead_p (1, operands[2])"
20060 [(parallel [(set (match_dup 0)
20061 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20062 (clobber (match_dup 2))])]
20066 [(match_scratch:DI 0 "r")
20067 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20068 (clobber (reg:CC FLAGS_REG))
20069 (clobber (mem:BLK (scratch)))])]
20070 "optimize_size || !TARGET_SUB_ESP_4"
20071 [(clobber (match_dup 0))
20072 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20073 (clobber (mem:BLK (scratch)))])])
20076 [(match_scratch:DI 0 "r")
20077 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20078 (clobber (reg:CC FLAGS_REG))
20079 (clobber (mem:BLK (scratch)))])]
20080 "optimize_size || !TARGET_SUB_ESP_8"
20081 [(clobber (match_dup 0))
20082 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20083 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20084 (clobber (mem:BLK (scratch)))])])
20086 ;; Convert esp subtractions to push.
20088 [(match_scratch:DI 0 "r")
20089 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20090 (clobber (reg:CC FLAGS_REG))])]
20091 "optimize_size || !TARGET_SUB_ESP_4"
20092 [(clobber (match_dup 0))
20093 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20096 [(match_scratch:DI 0 "r")
20097 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20098 (clobber (reg:CC FLAGS_REG))])]
20099 "optimize_size || !TARGET_SUB_ESP_8"
20100 [(clobber (match_dup 0))
20101 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20102 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20104 ;; Convert epilogue deallocator to pop.
20106 [(match_scratch:DI 0 "r")
20107 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20108 (clobber (reg:CC FLAGS_REG))
20109 (clobber (mem:BLK (scratch)))])]
20110 "optimize_size || !TARGET_ADD_ESP_4"
20111 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20112 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20113 (clobber (mem:BLK (scratch)))])]
20116 ;; Two pops case is tricky, since pop causes dependency on destination register.
20117 ;; We use two registers if available.
20119 [(match_scratch:DI 0 "r")
20120 (match_scratch:DI 1 "r")
20121 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20122 (clobber (reg:CC FLAGS_REG))
20123 (clobber (mem:BLK (scratch)))])]
20124 "optimize_size || !TARGET_ADD_ESP_8"
20125 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20126 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20127 (clobber (mem:BLK (scratch)))])
20128 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20129 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20133 [(match_scratch:DI 0 "r")
20134 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20135 (clobber (reg:CC FLAGS_REG))
20136 (clobber (mem:BLK (scratch)))])]
20138 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20139 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20140 (clobber (mem:BLK (scratch)))])
20141 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20142 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20145 ;; Convert esp additions to pop.
20147 [(match_scratch:DI 0 "r")
20148 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20149 (clobber (reg:CC FLAGS_REG))])]
20151 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20152 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20155 ;; Two pops case is tricky, since pop causes dependency on destination register.
20156 ;; We use two registers if available.
20158 [(match_scratch:DI 0 "r")
20159 (match_scratch:DI 1 "r")
20160 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20161 (clobber (reg:CC FLAGS_REG))])]
20163 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20164 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20165 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20166 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20170 [(match_scratch:DI 0 "r")
20171 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20172 (clobber (reg:CC FLAGS_REG))])]
20174 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20175 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20176 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20177 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20180 ;; Convert imul by three, five and nine into lea
20183 [(set (match_operand:SI 0 "register_operand" "")
20184 (mult:SI (match_operand:SI 1 "register_operand" "")
20185 (match_operand:SI 2 "const_int_operand" "")))
20186 (clobber (reg:CC FLAGS_REG))])]
20187 "INTVAL (operands[2]) == 3
20188 || INTVAL (operands[2]) == 5
20189 || INTVAL (operands[2]) == 9"
20190 [(set (match_dup 0)
20191 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20193 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20197 [(set (match_operand:SI 0 "register_operand" "")
20198 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20199 (match_operand:SI 2 "const_int_operand" "")))
20200 (clobber (reg:CC FLAGS_REG))])]
20202 && (INTVAL (operands[2]) == 3
20203 || INTVAL (operands[2]) == 5
20204 || INTVAL (operands[2]) == 9)"
20205 [(set (match_dup 0) (match_dup 1))
20207 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20209 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20213 [(set (match_operand:DI 0 "register_operand" "")
20214 (mult:DI (match_operand:DI 1 "register_operand" "")
20215 (match_operand:DI 2 "const_int_operand" "")))
20216 (clobber (reg:CC FLAGS_REG))])]
20218 && (INTVAL (operands[2]) == 3
20219 || INTVAL (operands[2]) == 5
20220 || INTVAL (operands[2]) == 9)"
20221 [(set (match_dup 0)
20222 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20224 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20228 [(set (match_operand:DI 0 "register_operand" "")
20229 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20230 (match_operand:DI 2 "const_int_operand" "")))
20231 (clobber (reg:CC FLAGS_REG))])]
20234 && (INTVAL (operands[2]) == 3
20235 || INTVAL (operands[2]) == 5
20236 || INTVAL (operands[2]) == 9)"
20237 [(set (match_dup 0) (match_dup 1))
20239 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20241 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20243 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20244 ;; imul $32bit_imm, reg, reg is direct decoded.
20246 [(match_scratch:DI 3 "r")
20247 (parallel [(set (match_operand:DI 0 "register_operand" "")
20248 (mult:DI (match_operand:DI 1 "memory_operand" "")
20249 (match_operand:DI 2 "immediate_operand" "")))
20250 (clobber (reg:CC FLAGS_REG))])]
20251 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20252 && !satisfies_constraint_K (operands[2])"
20253 [(set (match_dup 3) (match_dup 1))
20254 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20255 (clobber (reg:CC FLAGS_REG))])]
20259 [(match_scratch:SI 3 "r")
20260 (parallel [(set (match_operand:SI 0 "register_operand" "")
20261 (mult:SI (match_operand:SI 1 "memory_operand" "")
20262 (match_operand:SI 2 "immediate_operand" "")))
20263 (clobber (reg:CC FLAGS_REG))])]
20264 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20265 && !satisfies_constraint_K (operands[2])"
20266 [(set (match_dup 3) (match_dup 1))
20267 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20268 (clobber (reg:CC FLAGS_REG))])]
20272 [(match_scratch:SI 3 "r")
20273 (parallel [(set (match_operand:DI 0 "register_operand" "")
20275 (mult:SI (match_operand:SI 1 "memory_operand" "")
20276 (match_operand:SI 2 "immediate_operand" ""))))
20277 (clobber (reg:CC FLAGS_REG))])]
20278 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20279 && !satisfies_constraint_K (operands[2])"
20280 [(set (match_dup 3) (match_dup 1))
20281 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20282 (clobber (reg:CC FLAGS_REG))])]
20285 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20286 ;; Convert it into imul reg, reg
20287 ;; It would be better to force assembler to encode instruction using long
20288 ;; immediate, but there is apparently no way to do so.
20290 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20291 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20292 (match_operand:DI 2 "const_int_operand" "")))
20293 (clobber (reg:CC FLAGS_REG))])
20294 (match_scratch:DI 3 "r")]
20295 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20296 && satisfies_constraint_K (operands[2])"
20297 [(set (match_dup 3) (match_dup 2))
20298 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20299 (clobber (reg:CC FLAGS_REG))])]
20301 if (!rtx_equal_p (operands[0], operands[1]))
20302 emit_move_insn (operands[0], operands[1]);
20306 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20307 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20308 (match_operand:SI 2 "const_int_operand" "")))
20309 (clobber (reg:CC FLAGS_REG))])
20310 (match_scratch:SI 3 "r")]
20311 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20312 && satisfies_constraint_K (operands[2])"
20313 [(set (match_dup 3) (match_dup 2))
20314 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20315 (clobber (reg:CC FLAGS_REG))])]
20317 if (!rtx_equal_p (operands[0], operands[1]))
20318 emit_move_insn (operands[0], operands[1]);
20322 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20323 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20324 (match_operand:HI 2 "immediate_operand" "")))
20325 (clobber (reg:CC FLAGS_REG))])
20326 (match_scratch:HI 3 "r")]
20327 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20328 [(set (match_dup 3) (match_dup 2))
20329 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20330 (clobber (reg:CC FLAGS_REG))])]
20332 if (!rtx_equal_p (operands[0], operands[1]))
20333 emit_move_insn (operands[0], operands[1]);
20336 ;; After splitting up read-modify operations, array accesses with memory
20337 ;; operands might end up in form:
20339 ;; movl 4(%esp), %edx
20341 ;; instead of pre-splitting:
20343 ;; addl 4(%esp), %eax
20345 ;; movl 4(%esp), %edx
20346 ;; leal (%edx,%eax,4), %eax
20349 [(parallel [(set (match_operand 0 "register_operand" "")
20350 (ashift (match_operand 1 "register_operand" "")
20351 (match_operand 2 "const_int_operand" "")))
20352 (clobber (reg:CC FLAGS_REG))])
20353 (set (match_operand 3 "register_operand")
20354 (match_operand 4 "x86_64_general_operand" ""))
20355 (parallel [(set (match_operand 5 "register_operand" "")
20356 (plus (match_operand 6 "register_operand" "")
20357 (match_operand 7 "register_operand" "")))
20358 (clobber (reg:CC FLAGS_REG))])]
20359 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20360 /* Validate MODE for lea. */
20361 && ((!TARGET_PARTIAL_REG_STALL
20362 && (GET_MODE (operands[0]) == QImode
20363 || GET_MODE (operands[0]) == HImode))
20364 || GET_MODE (operands[0]) == SImode
20365 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20366 /* We reorder load and the shift. */
20367 && !rtx_equal_p (operands[1], operands[3])
20368 && !reg_overlap_mentioned_p (operands[0], operands[4])
20369 /* Last PLUS must consist of operand 0 and 3. */
20370 && !rtx_equal_p (operands[0], operands[3])
20371 && (rtx_equal_p (operands[3], operands[6])
20372 || rtx_equal_p (operands[3], operands[7]))
20373 && (rtx_equal_p (operands[0], operands[6])
20374 || rtx_equal_p (operands[0], operands[7]))
20375 /* The intermediate operand 0 must die or be same as output. */
20376 && (rtx_equal_p (operands[0], operands[5])
20377 || peep2_reg_dead_p (3, operands[0]))"
20378 [(set (match_dup 3) (match_dup 4))
20379 (set (match_dup 0) (match_dup 1))]
20381 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20382 int scale = 1 << INTVAL (operands[2]);
20383 rtx index = gen_lowpart (Pmode, operands[1]);
20384 rtx base = gen_lowpart (Pmode, operands[3]);
20385 rtx dest = gen_lowpart (mode, operands[5]);
20387 operands[1] = gen_rtx_PLUS (Pmode, base,
20388 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20390 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20391 operands[0] = dest;
20394 ;; Call-value patterns last so that the wildcard operand does not
20395 ;; disrupt insn-recog's switch tables.
20397 (define_insn "*call_value_pop_0"
20398 [(set (match_operand 0 "" "")
20399 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20400 (match_operand:SI 2 "" "")))
20401 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20402 (match_operand:SI 3 "immediate_operand" "")))]
20405 if (SIBLING_CALL_P (insn))
20408 return "call\t%P1";
20410 [(set_attr "type" "callv")])
20412 (define_insn "*call_value_pop_1"
20413 [(set (match_operand 0 "" "")
20414 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20415 (match_operand:SI 2 "" "")))
20416 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20417 (match_operand:SI 3 "immediate_operand" "i")))]
20420 if (constant_call_address_operand (operands[1], Pmode))
20422 if (SIBLING_CALL_P (insn))
20425 return "call\t%P1";
20427 if (SIBLING_CALL_P (insn))
20430 return "call\t%A1";
20432 [(set_attr "type" "callv")])
20434 (define_insn "*call_value_0"
20435 [(set (match_operand 0 "" "")
20436 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20437 (match_operand:SI 2 "" "")))]
20440 if (SIBLING_CALL_P (insn))
20443 return "call\t%P1";
20445 [(set_attr "type" "callv")])
20447 (define_insn "*call_value_0_rex64"
20448 [(set (match_operand 0 "" "")
20449 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20450 (match_operand:DI 2 "const_int_operand" "")))]
20453 if (SIBLING_CALL_P (insn))
20456 return "call\t%P1";
20458 [(set_attr "type" "callv")])
20460 (define_insn "*call_value_1"
20461 [(set (match_operand 0 "" "")
20462 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20463 (match_operand:SI 2 "" "")))]
20464 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20466 if (constant_call_address_operand (operands[1], Pmode))
20467 return "call\t%P1";
20468 return "call\t%A1";
20470 [(set_attr "type" "callv")])
20472 (define_insn "*sibcall_value_1"
20473 [(set (match_operand 0 "" "")
20474 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20475 (match_operand:SI 2 "" "")))]
20476 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20478 if (constant_call_address_operand (operands[1], Pmode))
20482 [(set_attr "type" "callv")])
20484 (define_insn "*call_value_1_rex64"
20485 [(set (match_operand 0 "" "")
20486 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20487 (match_operand:DI 2 "" "")))]
20488 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20490 if (constant_call_address_operand (operands[1], Pmode))
20491 return "call\t%P1";
20492 return "call\t%A1";
20494 [(set_attr "type" "callv")])
20496 (define_insn "*sibcall_value_1_rex64"
20497 [(set (match_operand 0 "" "")
20498 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20499 (match_operand:DI 2 "" "")))]
20500 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20502 [(set_attr "type" "callv")])
20504 (define_insn "*sibcall_value_1_rex64_v"
20505 [(set (match_operand 0 "" "")
20506 (call (mem:QI (reg:DI R11_REG))
20507 (match_operand:DI 1 "" "")))]
20508 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20510 [(set_attr "type" "callv")])
20512 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20513 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20514 ;; caught for use by garbage collectors and the like. Using an insn that
20515 ;; maps to SIGILL makes it more likely the program will rightfully die.
20516 ;; Keeping with tradition, "6" is in honor of #UD.
20517 (define_insn "trap"
20518 [(trap_if (const_int 1) (const_int 6))]
20520 { return ASM_SHORT "0x0b0f"; }
20521 [(set_attr "length" "2")])
20523 (define_expand "sse_prologue_save"
20524 [(parallel [(set (match_operand:BLK 0 "" "")
20525 (unspec:BLK [(reg:DI 21)
20532 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20533 (use (match_operand:DI 1 "register_operand" ""))
20534 (use (match_operand:DI 2 "immediate_operand" ""))
20535 (use (label_ref:DI (match_operand 3 "" "")))])]
20539 (define_insn "*sse_prologue_save_insn"
20540 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20541 (match_operand:DI 4 "const_int_operand" "n")))
20542 (unspec:BLK [(reg:DI 21)
20549 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20550 (use (match_operand:DI 1 "register_operand" "r"))
20551 (use (match_operand:DI 2 "const_int_operand" "i"))
20552 (use (label_ref:DI (match_operand 3 "" "X")))]
20554 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20555 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20559 operands[0] = gen_rtx_MEM (Pmode,
20560 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20561 output_asm_insn (\"jmp\\t%A1\", operands);
20562 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20564 operands[4] = adjust_address (operands[0], DImode, i*16);
20565 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20566 PUT_MODE (operands[4], TImode);
20567 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20568 output_asm_insn (\"rex\", operands);
20569 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20571 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20572 CODE_LABEL_NUMBER (operands[3]));
20576 [(set_attr "type" "other")
20577 (set_attr "length_immediate" "0")
20578 (set_attr "length_address" "0")
20579 (set_attr "length" "135")
20580 (set_attr "memory" "store")
20581 (set_attr "modrm" "0")
20582 (set_attr "mode" "DI")])
20584 (define_expand "prefetch"
20585 [(prefetch (match_operand 0 "address_operand" "")
20586 (match_operand:SI 1 "const_int_operand" "")
20587 (match_operand:SI 2 "const_int_operand" ""))]
20588 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20590 int rw = INTVAL (operands[1]);
20591 int locality = INTVAL (operands[2]);
20593 gcc_assert (rw == 0 || rw == 1);
20594 gcc_assert (locality >= 0 && locality <= 3);
20595 gcc_assert (GET_MODE (operands[0]) == Pmode
20596 || GET_MODE (operands[0]) == VOIDmode);
20598 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20599 supported by SSE counterpart or the SSE prefetch is not available
20600 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20602 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20603 operands[2] = GEN_INT (3);
20605 operands[1] = const0_rtx;
20608 (define_insn "*prefetch_sse"
20609 [(prefetch (match_operand:SI 0 "address_operand" "p")
20611 (match_operand:SI 1 "const_int_operand" ""))]
20612 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20614 static const char * const patterns[4] = {
20615 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20618 int locality = INTVAL (operands[1]);
20619 gcc_assert (locality >= 0 && locality <= 3);
20621 return patterns[locality];
20623 [(set_attr "type" "sse")
20624 (set_attr "memory" "none")])
20626 (define_insn "*prefetch_sse_rex"
20627 [(prefetch (match_operand:DI 0 "address_operand" "p")
20629 (match_operand:SI 1 "const_int_operand" ""))]
20630 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20632 static const char * const patterns[4] = {
20633 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20636 int locality = INTVAL (operands[1]);
20637 gcc_assert (locality >= 0 && locality <= 3);
20639 return patterns[locality];
20641 [(set_attr "type" "sse")
20642 (set_attr "memory" "none")])
20644 (define_insn "*prefetch_3dnow"
20645 [(prefetch (match_operand:SI 0 "address_operand" "p")
20646 (match_operand:SI 1 "const_int_operand" "n")
20648 "TARGET_3DNOW && !TARGET_64BIT"
20650 if (INTVAL (operands[1]) == 0)
20651 return "prefetch\t%a0";
20653 return "prefetchw\t%a0";
20655 [(set_attr "type" "mmx")
20656 (set_attr "memory" "none")])
20658 (define_insn "*prefetch_3dnow_rex"
20659 [(prefetch (match_operand:DI 0 "address_operand" "p")
20660 (match_operand:SI 1 "const_int_operand" "n")
20662 "TARGET_3DNOW && TARGET_64BIT"
20664 if (INTVAL (operands[1]) == 0)
20665 return "prefetch\t%a0";
20667 return "prefetchw\t%a0";
20669 [(set_attr "type" "mmx")
20670 (set_attr "memory" "none")])
20672 (define_expand "stack_protect_set"
20673 [(match_operand 0 "memory_operand" "")
20674 (match_operand 1 "memory_operand" "")]
20677 #ifdef TARGET_THREAD_SSP_OFFSET
20679 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20680 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20682 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20683 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20686 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20688 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20693 (define_insn "stack_protect_set_si"
20694 [(set (match_operand:SI 0 "memory_operand" "=m")
20695 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20696 (set (match_scratch:SI 2 "=&r") (const_int 0))
20697 (clobber (reg:CC FLAGS_REG))]
20699 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20700 [(set_attr "type" "multi")])
20702 (define_insn "stack_protect_set_di"
20703 [(set (match_operand:DI 0 "memory_operand" "=m")
20704 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20705 (set (match_scratch:DI 2 "=&r") (const_int 0))
20706 (clobber (reg:CC FLAGS_REG))]
20708 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20709 [(set_attr "type" "multi")])
20711 (define_insn "stack_tls_protect_set_si"
20712 [(set (match_operand:SI 0 "memory_operand" "=m")
20713 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20714 (set (match_scratch:SI 2 "=&r") (const_int 0))
20715 (clobber (reg:CC FLAGS_REG))]
20717 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20718 [(set_attr "type" "multi")])
20720 (define_insn "stack_tls_protect_set_di"
20721 [(set (match_operand:DI 0 "memory_operand" "=m")
20722 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20723 (set (match_scratch:DI 2 "=&r") (const_int 0))
20724 (clobber (reg:CC FLAGS_REG))]
20727 /* The kernel uses a different segment register for performance reasons; a
20728 system call would not have to trash the userspace segment register,
20729 which would be expensive */
20730 if (ix86_cmodel != CM_KERNEL)
20731 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20733 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20735 [(set_attr "type" "multi")])
20737 (define_expand "stack_protect_test"
20738 [(match_operand 0 "memory_operand" "")
20739 (match_operand 1 "memory_operand" "")
20740 (match_operand 2 "" "")]
20743 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20744 ix86_compare_op0 = operands[0];
20745 ix86_compare_op1 = operands[1];
20746 ix86_compare_emitted = flags;
20748 #ifdef TARGET_THREAD_SSP_OFFSET
20750 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20751 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20753 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20754 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20757 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20759 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20761 emit_jump_insn (gen_beq (operands[2]));
20765 (define_insn "stack_protect_test_si"
20766 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20767 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20768 (match_operand:SI 2 "memory_operand" "m")]
20770 (clobber (match_scratch:SI 3 "=&r"))]
20772 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20773 [(set_attr "type" "multi")])
20775 (define_insn "stack_protect_test_di"
20776 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20777 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20778 (match_operand:DI 2 "memory_operand" "m")]
20780 (clobber (match_scratch:DI 3 "=&r"))]
20782 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20783 [(set_attr "type" "multi")])
20785 (define_insn "stack_tls_protect_test_si"
20786 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20787 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20788 (match_operand:SI 2 "const_int_operand" "i")]
20789 UNSPEC_SP_TLS_TEST))
20790 (clobber (match_scratch:SI 3 "=r"))]
20792 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20793 [(set_attr "type" "multi")])
20795 (define_insn "stack_tls_protect_test_di"
20796 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20797 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20798 (match_operand:DI 2 "const_int_operand" "i")]
20799 UNSPEC_SP_TLS_TEST))
20800 (clobber (match_scratch:DI 3 "=r"))]
20803 /* The kernel uses a different segment register for performance reasons; a
20804 system call would not have to trash the userspace segment register,
20805 which would be expensive */
20806 if (ix86_cmodel != CM_KERNEL)
20807 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20809 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20811 [(set_attr "type" "multi")])
20815 (include "sync.md")