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 ;; The special asm out single letter directives following a '%' are:
31 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
33 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
34 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
35 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
36 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
37 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
38 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
39 ;; 'J' Print the appropriate jump operand.
41 ;; 'b' Print the QImode name of the register for the indicated operand.
42 ;; %b0 would print %al if operands[0] is reg 0.
43 ;; 'w' Likewise, print the HImode name of the register.
44 ;; 'k' Likewise, print the SImode name of the register.
45 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
46 ;; 'y' Print "st(0)" instead of "st" as a register.
51 [; Relocation specifiers
63 (UNSPEC_STACK_ALLOC 11)
65 (UNSPEC_SSE_PROLOGUE_SAVE 13)
72 (UNSPEC_TLS_LD_BASE 18)
75 ; Other random patterns
84 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
85 (UNSPEC_TRUNC_NOOP 29)
87 ; For SSE/MMX support:
88 (UNSPEC_FIX_NOTRUNC 30)
96 (UNSPEC_NOP 38) ; prevents combiner cleverness
107 ; Generic math support
109 (UNSPEC_IEEE_MIN 51) ; not commutative
110 (UNSPEC_IEEE_MAX 52) ; not commutative
125 (UNSPEC_FRNDINT_FLOOR 70)
126 (UNSPEC_FRNDINT_CEIL 71)
127 (UNSPEC_FRNDINT_TRUNC 72)
128 (UNSPEC_FRNDINT_MASK_PM 73)
129 (UNSPEC_FIST_FLOOR 74)
130 (UNSPEC_FIST_CEIL 75)
132 ; x87 Double output FP
133 (UNSPEC_SINCOS_COS 80)
134 (UNSPEC_SINCOS_SIN 81)
135 (UNSPEC_XTRACT_FRACT 84)
136 (UNSPEC_XTRACT_EXP 85)
137 (UNSPEC_FSCALE_FRACT 86)
138 (UNSPEC_FSCALE_EXP 87)
147 (UNSPEC_SP_TLS_SET 102)
148 (UNSPEC_SP_TLS_TEST 103)
158 (UNSPEC_INSERTQI 132)
163 [(UNSPECV_BLOCKAGE 0)
164 (UNSPECV_STACK_PROBE 1)
173 (UNSPECV_CMPXCHG_1 10)
174 (UNSPECV_CMPXCHG_2 11)
179 ;; Registers by name.
190 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
193 ;; In C guard expressions, put expressions which may be compile-time
194 ;; constants first. This allows for better optimization. For
195 ;; example, write "TARGET_64BIT && reload_completed", not
196 ;; "reload_completed && TARGET_64BIT".
199 ;; Processor type. This attribute must exactly match the processor_type
200 ;; enumeration in i386.h.
201 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
202 nocona,core2,generic32,generic64,amdfam10"
203 (const (symbol_ref "ix86_tune")))
205 ;; A basic instruction type. Refinements due to arguments to be
206 ;; provided in other attributes.
209 alu,alu1,negnot,imov,imovx,lea,
210 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
211 icmp,test,ibr,setcc,icmov,
212 push,pop,call,callv,leave,
214 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
215 sselog,sselog1,sseiadd,sseishft,sseimul,
216 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins,
217 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
218 (const_string "other"))
220 ;; Main data type used by the insn
222 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
223 (const_string "unknown"))
225 ;; The CPU unit operations uses.
226 (define_attr "unit" "integer,i387,sse,mmx,unknown"
227 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
228 (const_string "i387")
229 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
230 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,sseins")
232 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
234 (eq_attr "type" "other")
235 (const_string "unknown")]
236 (const_string "integer")))
238 ;; The (bounding maximum) length of an instruction immediate.
239 (define_attr "length_immediate" ""
240 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
243 (eq_attr "unit" "i387,sse,mmx")
245 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
247 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
248 (eq_attr "type" "imov,test")
249 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
250 (eq_attr "type" "call")
251 (if_then_else (match_operand 0 "constant_call_address_operand" "")
254 (eq_attr "type" "callv")
255 (if_then_else (match_operand 1 "constant_call_address_operand" "")
258 ;; We don't know the size before shorten_branches. Expect
259 ;; the instruction to fit for better scheduling.
260 (eq_attr "type" "ibr")
263 (symbol_ref "/* Update immediate_length and other attributes! */
264 gcc_unreachable (),1")))
266 ;; The (bounding maximum) length of an instruction address.
267 (define_attr "length_address" ""
268 (cond [(eq_attr "type" "str,other,multi,fxch")
270 (and (eq_attr "type" "call")
271 (match_operand 0 "constant_call_address_operand" ""))
273 (and (eq_attr "type" "callv")
274 (match_operand 1 "constant_call_address_operand" ""))
277 (symbol_ref "ix86_attr_length_address_default (insn)")))
279 ;; Set when length prefix is used.
280 (define_attr "prefix_data16" ""
281 (if_then_else (ior (eq_attr "mode" "HI")
282 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
286 ;; Set when string REP prefix is used.
287 (define_attr "prefix_rep" ""
288 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
292 ;; Set when 0f opcode prefix is used.
293 (define_attr "prefix_0f" ""
295 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
296 (eq_attr "unit" "sse,mmx"))
300 ;; Set when REX opcode prefix is used.
301 (define_attr "prefix_rex" ""
302 (cond [(and (eq_attr "mode" "DI")
303 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
305 (and (eq_attr "mode" "QI")
306 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
309 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
315 ;; Set when modrm byte is used.
316 (define_attr "modrm" ""
317 (cond [(eq_attr "type" "str,leave")
319 (eq_attr "unit" "i387")
321 (and (eq_attr "type" "incdec")
322 (ior (match_operand:SI 1 "register_operand" "")
323 (match_operand:HI 1 "register_operand" "")))
325 (and (eq_attr "type" "push")
326 (not (match_operand 1 "memory_operand" "")))
328 (and (eq_attr "type" "pop")
329 (not (match_operand 0 "memory_operand" "")))
331 (and (eq_attr "type" "imov")
332 (ior (and (match_operand 0 "register_operand" "")
333 (match_operand 1 "immediate_operand" ""))
334 (ior (and (match_operand 0 "ax_reg_operand" "")
335 (match_operand 1 "memory_displacement_only_operand" ""))
336 (and (match_operand 0 "memory_displacement_only_operand" "")
337 (match_operand 1 "ax_reg_operand" "")))))
339 (and (eq_attr "type" "call")
340 (match_operand 0 "constant_call_address_operand" ""))
342 (and (eq_attr "type" "callv")
343 (match_operand 1 "constant_call_address_operand" ""))
348 ;; The (bounding maximum) length of an instruction in bytes.
349 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
350 ;; Later we may want to split them and compute proper length as for
352 (define_attr "length" ""
353 (cond [(eq_attr "type" "other,multi,fistp,frndint")
355 (eq_attr "type" "fcmp")
357 (eq_attr "unit" "i387")
359 (plus (attr "prefix_data16")
360 (attr "length_address")))]
361 (plus (plus (attr "modrm")
362 (plus (attr "prefix_0f")
363 (plus (attr "prefix_rex")
365 (plus (attr "prefix_rep")
366 (plus (attr "prefix_data16")
367 (plus (attr "length_immediate")
368 (attr "length_address")))))))
370 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
371 ;; `store' if there is a simple memory reference therein, or `unknown'
372 ;; if the instruction is complex.
374 (define_attr "memory" "none,load,store,both,unknown"
375 (cond [(eq_attr "type" "other,multi,str")
376 (const_string "unknown")
377 (eq_attr "type" "lea,fcmov,fpspc")
378 (const_string "none")
379 (eq_attr "type" "fistp,leave")
380 (const_string "both")
381 (eq_attr "type" "frndint")
382 (const_string "load")
383 (eq_attr "type" "push")
384 (if_then_else (match_operand 1 "memory_operand" "")
385 (const_string "both")
386 (const_string "store"))
387 (eq_attr "type" "pop")
388 (if_then_else (match_operand 0 "memory_operand" "")
389 (const_string "both")
390 (const_string "load"))
391 (eq_attr "type" "setcc")
392 (if_then_else (match_operand 0 "memory_operand" "")
393 (const_string "store")
394 (const_string "none"))
395 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
396 (if_then_else (ior (match_operand 0 "memory_operand" "")
397 (match_operand 1 "memory_operand" ""))
398 (const_string "load")
399 (const_string "none"))
400 (eq_attr "type" "ibr")
401 (if_then_else (match_operand 0 "memory_operand" "")
402 (const_string "load")
403 (const_string "none"))
404 (eq_attr "type" "call")
405 (if_then_else (match_operand 0 "constant_call_address_operand" "")
406 (const_string "none")
407 (const_string "load"))
408 (eq_attr "type" "callv")
409 (if_then_else (match_operand 1 "constant_call_address_operand" "")
410 (const_string "none")
411 (const_string "load"))
412 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
413 (match_operand 1 "memory_operand" ""))
414 (const_string "both")
415 (and (match_operand 0 "memory_operand" "")
416 (match_operand 1 "memory_operand" ""))
417 (const_string "both")
418 (match_operand 0 "memory_operand" "")
419 (const_string "store")
420 (match_operand 1 "memory_operand" "")
421 (const_string "load")
423 "!alu1,negnot,ishift1,
424 imov,imovx,icmp,test,bitmanip,
426 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
427 mmx,mmxmov,mmxcmp,mmxcvt")
428 (match_operand 2 "memory_operand" ""))
429 (const_string "load")
430 (and (eq_attr "type" "icmov")
431 (match_operand 3 "memory_operand" ""))
432 (const_string "load")
434 (const_string "none")))
436 ;; Indicates if an instruction has both an immediate and a displacement.
438 (define_attr "imm_disp" "false,true,unknown"
439 (cond [(eq_attr "type" "other,multi")
440 (const_string "unknown")
441 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
442 (and (match_operand 0 "memory_displacement_operand" "")
443 (match_operand 1 "immediate_operand" "")))
444 (const_string "true")
445 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
446 (and (match_operand 0 "memory_displacement_operand" "")
447 (match_operand 2 "immediate_operand" "")))
448 (const_string "true")
450 (const_string "false")))
452 ;; Indicates if an FP operation has an integer source.
454 (define_attr "fp_int_src" "false,true"
455 (const_string "false"))
457 ;; Defines rounding mode of an FP operation.
459 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
460 (const_string "any"))
462 ;; Describe a user's asm statement.
463 (define_asm_attributes
464 [(set_attr "length" "128")
465 (set_attr "type" "multi")])
467 ;; All x87 floating point modes
468 (define_mode_macro X87MODEF [SF DF XF])
470 ;; x87 SFmode and DFMode floating point modes
471 (define_mode_macro X87MODEF12 [SF DF])
473 ;; All integer modes handled by x87 fisttp operator.
474 (define_mode_macro X87MODEI [HI SI DI])
476 ;; All integer modes handled by integer x87 operators.
477 (define_mode_macro X87MODEI12 [HI SI])
479 ;; All SSE floating point modes
480 (define_mode_macro SSEMODEF [SF DF])
482 ;; All integer modes handled by SSE cvtts?2si* operators.
483 (define_mode_macro SSEMODEI24 [SI DI])
485 ;; SSE asm suffix for floating point modes
486 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
488 ;; SSE vector mode corresponding to a scalar mode
489 (define_mode_attr ssevecmode
490 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
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)"
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)"
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)"
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)"
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)"
1169 [(set_attr "type" "alu1")
1170 (set_attr "mode" "SI")
1171 (set_attr "length_immediate" "0")])
1173 (define_insn "*movsi_or"
1174 [(set (match_operand:SI 0 "register_operand" "=r")
1175 (match_operand:SI 1 "immediate_operand" "i"))
1176 (clobber (reg:CC FLAGS_REG))]
1178 && operands[1] == constm1_rtx
1179 && (TARGET_PENTIUM || optimize_size)"
1181 operands[1] = constm1_rtx;
1182 return "or{l}\t{%1, %0|%0, %1}";
1184 [(set_attr "type" "alu1")
1185 (set_attr "mode" "SI")
1186 (set_attr "length_immediate" "1")])
1188 (define_insn "*movsi_1"
1189 [(set (match_operand:SI 0 "nonimmediate_operand"
1190 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1191 (match_operand:SI 1 "general_operand"
1192 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1193 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1195 switch (get_attr_type (insn))
1198 if (get_attr_mode (insn) == MODE_TI)
1199 return "pxor\t%0, %0";
1200 return "xorps\t%0, %0";
1203 switch (get_attr_mode (insn))
1206 return "movdqa\t{%1, %0|%0, %1}";
1208 return "movaps\t{%1, %0|%0, %1}";
1210 return "movd\t{%1, %0|%0, %1}";
1212 return "movss\t{%1, %0|%0, %1}";
1218 return "pxor\t%0, %0";
1221 if (get_attr_mode (insn) == MODE_DI)
1222 return "movq\t{%1, %0|%0, %1}";
1223 return "movd\t{%1, %0|%0, %1}";
1226 return "lea{l}\t{%1, %0|%0, %1}";
1229 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1230 return "mov{l}\t{%1, %0|%0, %1}";
1234 (cond [(eq_attr "alternative" "2")
1235 (const_string "mmxadd")
1236 (eq_attr "alternative" "3,4,5")
1237 (const_string "mmxmov")
1238 (eq_attr "alternative" "6")
1239 (const_string "sselog1")
1240 (eq_attr "alternative" "7,8,9,10,11")
1241 (const_string "ssemov")
1242 (match_operand:DI 1 "pic_32bit_operand" "")
1243 (const_string "lea")
1245 (const_string "imov")))
1247 (cond [(eq_attr "alternative" "2,3")
1249 (eq_attr "alternative" "6,7")
1251 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1252 (const_string "V4SF")
1253 (const_string "TI"))
1254 (and (eq_attr "alternative" "8,9,10,11")
1255 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1258 (const_string "SI")))])
1260 ;; Stores and loads of ax to arbitrary constant address.
1261 ;; We fake an second form of instruction to force reload to load address
1262 ;; into register when rax is not available
1263 (define_insn "*movabssi_1_rex64"
1264 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1265 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1266 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1268 movabs{l}\t{%1, %P0|%P0, %1}
1269 mov{l}\t{%1, %a0|%a0, %1}"
1270 [(set_attr "type" "imov")
1271 (set_attr "modrm" "0,*")
1272 (set_attr "length_address" "8,0")
1273 (set_attr "length_immediate" "0,*")
1274 (set_attr "memory" "store")
1275 (set_attr "mode" "SI")])
1277 (define_insn "*movabssi_2_rex64"
1278 [(set (match_operand:SI 0 "register_operand" "=a,r")
1279 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1280 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1282 movabs{l}\t{%P1, %0|%0, %P1}
1283 mov{l}\t{%a1, %0|%0, %a1}"
1284 [(set_attr "type" "imov")
1285 (set_attr "modrm" "0,*")
1286 (set_attr "length_address" "8,0")
1287 (set_attr "length_immediate" "0")
1288 (set_attr "memory" "load")
1289 (set_attr "mode" "SI")])
1291 (define_insn "*swapsi"
1292 [(set (match_operand:SI 0 "register_operand" "+r")
1293 (match_operand:SI 1 "register_operand" "+r"))
1298 [(set_attr "type" "imov")
1299 (set_attr "mode" "SI")
1300 (set_attr "pent_pair" "np")
1301 (set_attr "athlon_decode" "vector")
1302 (set_attr "amdfam10_decode" "double")])
1304 (define_expand "movhi"
1305 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1306 (match_operand:HI 1 "general_operand" ""))]
1308 "ix86_expand_move (HImode, operands); DONE;")
1310 (define_insn "*pushhi2"
1311 [(set (match_operand:HI 0 "push_operand" "=X")
1312 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1315 [(set_attr "type" "push")
1316 (set_attr "mode" "SI")])
1318 ;; For 64BIT abi we always round up to 8 bytes.
1319 (define_insn "*pushhi2_rex64"
1320 [(set (match_operand:HI 0 "push_operand" "=X")
1321 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1324 [(set_attr "type" "push")
1325 (set_attr "mode" "DI")])
1327 (define_insn "*movhi_1"
1328 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1329 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1332 switch (get_attr_type (insn))
1335 /* movzwl is faster than movw on p2 due to partial word stalls,
1336 though not as fast as an aligned movl. */
1337 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1339 if (get_attr_mode (insn) == MODE_SI)
1340 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1342 return "mov{w}\t{%1, %0|%0, %1}";
1346 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1347 (const_string "imov")
1348 (and (eq_attr "alternative" "0")
1349 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1351 (eq (symbol_ref "TARGET_HIMODE_MATH")
1353 (const_string "imov")
1354 (and (eq_attr "alternative" "1,2")
1355 (match_operand:HI 1 "aligned_operand" ""))
1356 (const_string "imov")
1357 (and (ne (symbol_ref "TARGET_MOVX")
1359 (eq_attr "alternative" "0,2"))
1360 (const_string "imovx")
1362 (const_string "imov")))
1364 (cond [(eq_attr "type" "imovx")
1366 (and (eq_attr "alternative" "1,2")
1367 (match_operand:HI 1 "aligned_operand" ""))
1369 (and (eq_attr "alternative" "0")
1370 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1372 (eq (symbol_ref "TARGET_HIMODE_MATH")
1376 (const_string "HI")))])
1378 ;; Stores and loads of ax to arbitrary constant address.
1379 ;; We fake an second form of instruction to force reload to load address
1380 ;; into register when rax is not available
1381 (define_insn "*movabshi_1_rex64"
1382 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1383 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1384 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1386 movabs{w}\t{%1, %P0|%P0, %1}
1387 mov{w}\t{%1, %a0|%a0, %1}"
1388 [(set_attr "type" "imov")
1389 (set_attr "modrm" "0,*")
1390 (set_attr "length_address" "8,0")
1391 (set_attr "length_immediate" "0,*")
1392 (set_attr "memory" "store")
1393 (set_attr "mode" "HI")])
1395 (define_insn "*movabshi_2_rex64"
1396 [(set (match_operand:HI 0 "register_operand" "=a,r")
1397 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1398 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1400 movabs{w}\t{%P1, %0|%0, %P1}
1401 mov{w}\t{%a1, %0|%0, %a1}"
1402 [(set_attr "type" "imov")
1403 (set_attr "modrm" "0,*")
1404 (set_attr "length_address" "8,0")
1405 (set_attr "length_immediate" "0")
1406 (set_attr "memory" "load")
1407 (set_attr "mode" "HI")])
1409 (define_insn "*swaphi_1"
1410 [(set (match_operand:HI 0 "register_operand" "+r")
1411 (match_operand:HI 1 "register_operand" "+r"))
1414 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1416 [(set_attr "type" "imov")
1417 (set_attr "mode" "SI")
1418 (set_attr "pent_pair" "np")
1419 (set_attr "athlon_decode" "vector")
1420 (set_attr "amdfam10_decode" "double")])
1422 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1423 (define_insn "*swaphi_2"
1424 [(set (match_operand:HI 0 "register_operand" "+r")
1425 (match_operand:HI 1 "register_operand" "+r"))
1428 "TARGET_PARTIAL_REG_STALL"
1430 [(set_attr "type" "imov")
1431 (set_attr "mode" "HI")
1432 (set_attr "pent_pair" "np")
1433 (set_attr "athlon_decode" "vector")])
1435 (define_expand "movstricthi"
1436 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1437 (match_operand:HI 1 "general_operand" ""))]
1438 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1440 /* Don't generate memory->memory moves, go through a register */
1441 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1442 operands[1] = force_reg (HImode, operands[1]);
1445 (define_insn "*movstricthi_1"
1446 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1447 (match_operand:HI 1 "general_operand" "rn,m"))]
1448 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1449 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1450 "mov{w}\t{%1, %0|%0, %1}"
1451 [(set_attr "type" "imov")
1452 (set_attr "mode" "HI")])
1454 (define_insn "*movstricthi_xor"
1455 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1456 (match_operand:HI 1 "const0_operand" "i"))
1457 (clobber (reg:CC FLAGS_REG))]
1459 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
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)"
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"
1963 [(set_attr "type" "alu1")
1964 (set_attr "mode" "SI")
1965 (set_attr "length_immediate" "0")])
1967 (define_insn "*movdi_or_rex64"
1968 [(set (match_operand:DI 0 "register_operand" "=r")
1969 (match_operand:DI 1 "const_int_operand" "i"))
1970 (clobber (reg:CC FLAGS_REG))]
1971 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1973 && operands[1] == constm1_rtx"
1975 operands[1] = constm1_rtx;
1976 return "or{q}\t{%1, %0|%0, %1}";
1978 [(set_attr "type" "alu1")
1979 (set_attr "mode" "DI")
1980 (set_attr "length_immediate" "1")])
1982 (define_insn "*movdi_2"
1983 [(set (match_operand:DI 0 "nonimmediate_operand"
1984 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
1985 (match_operand:DI 1 "general_operand"
1986 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
1987 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1992 movq\t{%1, %0|%0, %1}
1993 movq\t{%1, %0|%0, %1}
1995 movq\t{%1, %0|%0, %1}
1996 movdqa\t{%1, %0|%0, %1}
1997 movq\t{%1, %0|%0, %1}
1999 movlps\t{%1, %0|%0, %1}
2000 movaps\t{%1, %0|%0, %1}
2001 movlps\t{%1, %0|%0, %1}"
2002 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2003 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2006 [(set (match_operand:DI 0 "push_operand" "")
2007 (match_operand:DI 1 "general_operand" ""))]
2008 "!TARGET_64BIT && reload_completed
2009 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2011 "ix86_split_long_move (operands); DONE;")
2013 ;; %%% This multiword shite has got to go.
2015 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2016 (match_operand:DI 1 "general_operand" ""))]
2017 "!TARGET_64BIT && reload_completed
2018 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2019 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2021 "ix86_split_long_move (operands); DONE;")
2023 (define_insn "*movdi_1_rex64"
2024 [(set (match_operand:DI 0 "nonimmediate_operand"
2025 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2026 (match_operand:DI 1 "general_operand"
2027 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2028 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2030 switch (get_attr_type (insn))
2033 if (SSE_REG_P (operands[0]))
2034 return "movq2dq\t{%1, %0|%0, %1}";
2036 return "movdq2q\t{%1, %0|%0, %1}";
2039 if (get_attr_mode (insn) == MODE_TI)
2040 return "movdqa\t{%1, %0|%0, %1}";
2044 /* Moves from and into integer register is done using movd
2045 opcode with REX prefix. */
2046 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2047 return "movd\t{%1, %0|%0, %1}";
2048 return "movq\t{%1, %0|%0, %1}";
2052 return "pxor\t%0, %0";
2058 return "lea{q}\t{%a1, %0|%0, %a1}";
2061 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2062 if (get_attr_mode (insn) == MODE_SI)
2063 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2064 else if (which_alternative == 2)
2065 return "movabs{q}\t{%1, %0|%0, %1}";
2067 return "mov{q}\t{%1, %0|%0, %1}";
2071 (cond [(eq_attr "alternative" "5")
2072 (const_string "mmxadd")
2073 (eq_attr "alternative" "6,7,8,9,10")
2074 (const_string "mmxmov")
2075 (eq_attr "alternative" "11")
2076 (const_string "sselog1")
2077 (eq_attr "alternative" "12,13,14,15,16")
2078 (const_string "ssemov")
2079 (eq_attr "alternative" "17,18")
2080 (const_string "ssecvt")
2081 (eq_attr "alternative" "4")
2082 (const_string "multi")
2083 (match_operand:DI 1 "pic_32bit_operand" "")
2084 (const_string "lea")
2086 (const_string "imov")))
2087 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2088 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2089 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2091 ;; Stores and loads of ax to arbitrary constant address.
2092 ;; We fake an second form of instruction to force reload to load address
2093 ;; into register when rax is not available
2094 (define_insn "*movabsdi_1_rex64"
2095 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2096 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2097 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2099 movabs{q}\t{%1, %P0|%P0, %1}
2100 mov{q}\t{%1, %a0|%a0, %1}"
2101 [(set_attr "type" "imov")
2102 (set_attr "modrm" "0,*")
2103 (set_attr "length_address" "8,0")
2104 (set_attr "length_immediate" "0,*")
2105 (set_attr "memory" "store")
2106 (set_attr "mode" "DI")])
2108 (define_insn "*movabsdi_2_rex64"
2109 [(set (match_operand:DI 0 "register_operand" "=a,r")
2110 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2111 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2113 movabs{q}\t{%P1, %0|%0, %P1}
2114 mov{q}\t{%a1, %0|%0, %a1}"
2115 [(set_attr "type" "imov")
2116 (set_attr "modrm" "0,*")
2117 (set_attr "length_address" "8,0")
2118 (set_attr "length_immediate" "0")
2119 (set_attr "memory" "load")
2120 (set_attr "mode" "DI")])
2122 ;; Convert impossible stores of immediate to existing instructions.
2123 ;; First try to get scratch register and go through it. In case this
2124 ;; fails, move by 32bit parts.
2126 [(match_scratch:DI 2 "r")
2127 (set (match_operand:DI 0 "memory_operand" "")
2128 (match_operand:DI 1 "immediate_operand" ""))]
2129 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2130 && !x86_64_immediate_operand (operands[1], DImode)"
2131 [(set (match_dup 2) (match_dup 1))
2132 (set (match_dup 0) (match_dup 2))]
2135 ;; We need to define this as both peepholer and splitter for case
2136 ;; peephole2 pass is not run.
2137 ;; "&& 1" is needed to keep it from matching the previous pattern.
2139 [(set (match_operand:DI 0 "memory_operand" "")
2140 (match_operand:DI 1 "immediate_operand" ""))]
2141 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2142 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2143 [(set (match_dup 2) (match_dup 3))
2144 (set (match_dup 4) (match_dup 5))]
2145 "split_di (operands, 2, operands + 2, operands + 4);")
2148 [(set (match_operand:DI 0 "memory_operand" "")
2149 (match_operand:DI 1 "immediate_operand" ""))]
2150 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2151 ? flow2_completed : reload_completed)
2152 && !symbolic_operand (operands[1], DImode)
2153 && !x86_64_immediate_operand (operands[1], DImode)"
2154 [(set (match_dup 2) (match_dup 3))
2155 (set (match_dup 4) (match_dup 5))]
2156 "split_di (operands, 2, operands + 2, operands + 4);")
2158 (define_insn "*swapdi_rex64"
2159 [(set (match_operand:DI 0 "register_operand" "+r")
2160 (match_operand:DI 1 "register_operand" "+r"))
2165 [(set_attr "type" "imov")
2166 (set_attr "mode" "DI")
2167 (set_attr "pent_pair" "np")
2168 (set_attr "athlon_decode" "vector")
2169 (set_attr "amdfam10_decode" "double")])
2171 (define_expand "movti"
2172 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2173 (match_operand:TI 1 "nonimmediate_operand" ""))]
2174 "TARGET_SSE || TARGET_64BIT"
2177 ix86_expand_move (TImode, operands);
2179 ix86_expand_vector_move (TImode, operands);
2183 (define_insn "*movti_internal"
2184 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2185 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2186 "TARGET_SSE && !TARGET_64BIT
2187 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189 switch (which_alternative)
2192 if (get_attr_mode (insn) == MODE_V4SF)
2193 return "xorps\t%0, %0";
2195 return "pxor\t%0, %0";
2198 if (get_attr_mode (insn) == MODE_V4SF)
2199 return "movaps\t{%1, %0|%0, %1}";
2201 return "movdqa\t{%1, %0|%0, %1}";
2206 [(set_attr "type" "sselog1,ssemov,ssemov")
2208 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2209 (ne (symbol_ref "optimize_size") (const_int 0)))
2210 (const_string "V4SF")
2211 (and (eq_attr "alternative" "2")
2212 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2214 (const_string "V4SF")]
2215 (const_string "TI")))])
2217 (define_insn "*movti_rex64"
2218 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2219 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2221 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2223 switch (which_alternative)
2229 if (get_attr_mode (insn) == MODE_V4SF)
2230 return "xorps\t%0, %0";
2232 return "pxor\t%0, %0";
2235 if (get_attr_mode (insn) == MODE_V4SF)
2236 return "movaps\t{%1, %0|%0, %1}";
2238 return "movdqa\t{%1, %0|%0, %1}";
2243 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2245 (cond [(eq_attr "alternative" "2,3")
2247 (ne (symbol_ref "optimize_size")
2249 (const_string "V4SF")
2250 (const_string "TI"))
2251 (eq_attr "alternative" "4")
2253 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2255 (ne (symbol_ref "optimize_size")
2257 (const_string "V4SF")
2258 (const_string "TI"))]
2259 (const_string "DI")))])
2262 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2263 (match_operand:TI 1 "general_operand" ""))]
2264 "reload_completed && !SSE_REG_P (operands[0])
2265 && !SSE_REG_P (operands[1])"
2267 "ix86_split_long_move (operands); DONE;")
2269 (define_expand "movsf"
2270 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2271 (match_operand:SF 1 "general_operand" ""))]
2273 "ix86_expand_move (SFmode, operands); DONE;")
2275 (define_insn "*pushsf"
2276 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2277 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2280 /* Anything else should be already split before reg-stack. */
2281 gcc_assert (which_alternative == 1);
2282 return "push{l}\t%1";
2284 [(set_attr "type" "multi,push,multi")
2285 (set_attr "unit" "i387,*,*")
2286 (set_attr "mode" "SF,SI,SF")])
2288 (define_insn "*pushsf_rex64"
2289 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2290 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2293 /* Anything else should be already split before reg-stack. */
2294 gcc_assert (which_alternative == 1);
2295 return "push{q}\t%q1";
2297 [(set_attr "type" "multi,push,multi")
2298 (set_attr "unit" "i387,*,*")
2299 (set_attr "mode" "SF,DI,SF")])
2302 [(set (match_operand:SF 0 "push_operand" "")
2303 (match_operand:SF 1 "memory_operand" ""))]
2305 && MEM_P (operands[1])
2306 && constant_pool_reference_p (operands[1])"
2309 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2312 ;; %%% Kill this when call knows how to work this out.
2314 [(set (match_operand:SF 0 "push_operand" "")
2315 (match_operand:SF 1 "any_fp_register_operand" ""))]
2317 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2318 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2321 [(set (match_operand:SF 0 "push_operand" "")
2322 (match_operand:SF 1 "any_fp_register_operand" ""))]
2324 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2325 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2327 (define_insn "*movsf_1"
2328 [(set (match_operand:SF 0 "nonimmediate_operand"
2329 "=f,m,f,r ,m ,x,x,x ,m,*y,m ,*y,Yi,r ,*Ym,r ")
2330 (match_operand:SF 1 "general_operand"
2331 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y,r ,Yi,r ,*Ym"))]
2332 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2333 && (reload_in_progress || reload_completed
2334 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2335 || (!TARGET_SSE_MATH && optimize_size
2336 && standard_80387_constant_p (operands[1]))
2337 || GET_CODE (operands[1]) != CONST_DOUBLE
2338 || memory_operand (operands[0], SFmode))"
2340 switch (which_alternative)
2343 return output_387_reg_move (insn, operands);
2346 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2347 return "fstp%z0\t%y0";
2349 return "fst%z0\t%y0";
2352 return standard_80387_constant_opcode (operands[1]);
2356 return "mov{l}\t{%1, %0|%0, %1}";
2358 if (get_attr_mode (insn) == MODE_TI)
2359 return "pxor\t%0, %0";
2361 return "xorps\t%0, %0";
2363 if (get_attr_mode (insn) == MODE_V4SF)
2364 return "movaps\t{%1, %0|%0, %1}";
2366 return "movss\t{%1, %0|%0, %1}";
2368 return "movss\t{%1, %0|%0, %1}";
2371 case 12: case 13: case 14: case 15:
2372 return "movd\t{%1, %0|%0, %1}";
2375 return "movq\t{%1, %0|%0, %1}";
2381 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2383 (cond [(eq_attr "alternative" "3,4,9,10")
2385 (eq_attr "alternative" "5")
2387 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2389 (ne (symbol_ref "TARGET_SSE2")
2391 (eq (symbol_ref "optimize_size")
2394 (const_string "V4SF"))
2395 /* For architectures resolving dependencies on
2396 whole SSE registers use APS move to break dependency
2397 chains, otherwise use short move to avoid extra work.
2399 Do the same for architectures resolving dependencies on
2400 the parts. While in DF mode it is better to always handle
2401 just register parts, the SF mode is different due to lack
2402 of instructions to load just part of the register. It is
2403 better to maintain the whole registers in single format
2404 to avoid problems on using packed logical operations. */
2405 (eq_attr "alternative" "6")
2407 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2409 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2411 (const_string "V4SF")
2412 (const_string "SF"))
2413 (eq_attr "alternative" "11")
2414 (const_string "DI")]
2415 (const_string "SF")))])
2417 (define_insn "*swapsf"
2418 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2419 (match_operand:SF 1 "fp_register_operand" "+f"))
2422 "reload_completed || TARGET_80387"
2424 if (STACK_TOP_P (operands[0]))
2429 [(set_attr "type" "fxch")
2430 (set_attr "mode" "SF")])
2432 (define_expand "movdf"
2433 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2434 (match_operand:DF 1 "general_operand" ""))]
2436 "ix86_expand_move (DFmode, operands); DONE;")
2438 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2439 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2440 ;; On the average, pushdf using integers can be still shorter. Allow this
2441 ;; pattern for optimize_size too.
2443 (define_insn "*pushdf_nointeger"
2444 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2445 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2446 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2448 /* This insn should be already split before reg-stack. */
2451 [(set_attr "type" "multi")
2452 (set_attr "unit" "i387,*,*,*")
2453 (set_attr "mode" "DF,SI,SI,DF")])
2455 (define_insn "*pushdf_integer"
2456 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2457 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2458 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2460 /* This insn should be already split before reg-stack. */
2463 [(set_attr "type" "multi")
2464 (set_attr "unit" "i387,*,*")
2465 (set_attr "mode" "DF,SI,DF")])
2467 ;; %%% Kill this when call knows how to work this out.
2469 [(set (match_operand:DF 0 "push_operand" "")
2470 (match_operand:DF 1 "any_fp_register_operand" ""))]
2471 "!TARGET_64BIT && reload_completed"
2472 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2473 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2477 [(set (match_operand:DF 0 "push_operand" "")
2478 (match_operand:DF 1 "any_fp_register_operand" ""))]
2479 "TARGET_64BIT && reload_completed"
2480 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2481 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2485 [(set (match_operand:DF 0 "push_operand" "")
2486 (match_operand:DF 1 "general_operand" ""))]
2489 "ix86_split_long_move (operands); DONE;")
2491 ;; Moving is usually shorter when only FP registers are used. This separate
2492 ;; movdf pattern avoids the use of integer registers for FP operations
2493 ;; when optimizing for size.
2495 (define_insn "*movdf_nointeger"
2496 [(set (match_operand:DF 0 "nonimmediate_operand"
2497 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
2498 (match_operand:DF 1 "general_operand"
2499 "fm,f,G,*roF,F*r,C ,Y2*x,mY2*x,Y2*x"))]
2500 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2501 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2502 && (reload_in_progress || reload_completed
2503 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2504 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2505 && standard_80387_constant_p (operands[1]))
2506 || GET_CODE (operands[1]) != CONST_DOUBLE
2507 || memory_operand (operands[0], DFmode))"
2509 switch (which_alternative)
2512 return output_387_reg_move (insn, operands);
2515 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2516 return "fstp%z0\t%y0";
2518 return "fst%z0\t%y0";
2521 return standard_80387_constant_opcode (operands[1]);
2527 switch (get_attr_mode (insn))
2530 return "xorps\t%0, %0";
2532 return "xorpd\t%0, %0";
2534 return "pxor\t%0, %0";
2541 switch (get_attr_mode (insn))
2544 return "movaps\t{%1, %0|%0, %1}";
2546 return "movapd\t{%1, %0|%0, %1}";
2548 return "movdqa\t{%1, %0|%0, %1}";
2550 return "movq\t{%1, %0|%0, %1}";
2552 return "movsd\t{%1, %0|%0, %1}";
2554 return "movlpd\t{%1, %0|%0, %1}";
2556 return "movlps\t{%1, %0|%0, %1}";
2565 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2567 (cond [(eq_attr "alternative" "0,1,2")
2569 (eq_attr "alternative" "3,4")
2572 /* For SSE1, we have many fewer alternatives. */
2573 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2574 (cond [(eq_attr "alternative" "5,6")
2575 (const_string "V4SF")
2577 (const_string "V2SF"))
2579 /* xorps is one byte shorter. */
2580 (eq_attr "alternative" "5")
2581 (cond [(ne (symbol_ref "optimize_size")
2583 (const_string "V4SF")
2584 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2588 (const_string "V2DF"))
2590 /* For architectures resolving dependencies on
2591 whole SSE registers use APD move to break dependency
2592 chains, otherwise use short move to avoid extra work.
2594 movaps encodes one byte shorter. */
2595 (eq_attr "alternative" "6")
2597 [(ne (symbol_ref "optimize_size")
2599 (const_string "V4SF")
2600 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2602 (const_string "V2DF")
2604 (const_string "DF"))
2605 /* For architectures resolving dependencies on register
2606 parts we may avoid extra work to zero out upper part
2608 (eq_attr "alternative" "7")
2610 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2612 (const_string "V1DF")
2613 (const_string "DF"))
2615 (const_string "DF")))])
2617 (define_insn "*movdf_integer_rex64"
2618 [(set (match_operand:DF 0 "nonimmediate_operand"
2619 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2620 (match_operand:DF 1 "general_operand"
2621 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2622 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2623 && (reload_in_progress || reload_completed
2624 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2625 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2626 && standard_80387_constant_p (operands[1]))
2627 || GET_CODE (operands[1]) != CONST_DOUBLE
2628 || memory_operand (operands[0], DFmode))"
2630 switch (which_alternative)
2633 return output_387_reg_move (insn, operands);
2636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2637 return "fstp%z0\t%y0";
2639 return "fst%z0\t%y0";
2642 return standard_80387_constant_opcode (operands[1]);
2649 switch (get_attr_mode (insn))
2652 return "xorps\t%0, %0";
2654 return "xorpd\t%0, %0";
2656 return "pxor\t%0, %0";
2663 switch (get_attr_mode (insn))
2666 return "movaps\t{%1, %0|%0, %1}";
2668 return "movapd\t{%1, %0|%0, %1}";
2670 return "movdqa\t{%1, %0|%0, %1}";
2672 return "movq\t{%1, %0|%0, %1}";
2674 return "movsd\t{%1, %0|%0, %1}";
2676 return "movlpd\t{%1, %0|%0, %1}";
2678 return "movlps\t{%1, %0|%0, %1}";
2685 return "movd\t{%1, %0|%0, %1}";
2691 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2693 (cond [(eq_attr "alternative" "0,1,2")
2695 (eq_attr "alternative" "3,4,9,10")
2698 /* For SSE1, we have many fewer alternatives. */
2699 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700 (cond [(eq_attr "alternative" "5,6")
2701 (const_string "V4SF")
2703 (const_string "V2SF"))
2705 /* xorps is one byte shorter. */
2706 (eq_attr "alternative" "5")
2707 (cond [(ne (symbol_ref "optimize_size")
2709 (const_string "V4SF")
2710 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2714 (const_string "V2DF"))
2716 /* For architectures resolving dependencies on
2717 whole SSE registers use APD move to break dependency
2718 chains, otherwise use short move to avoid extra work.
2720 movaps encodes one byte shorter. */
2721 (eq_attr "alternative" "6")
2723 [(ne (symbol_ref "optimize_size")
2725 (const_string "V4SF")
2726 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2728 (const_string "V2DF")
2730 (const_string "DF"))
2731 /* For architectures resolving dependencies on register
2732 parts we may avoid extra work to zero out upper part
2734 (eq_attr "alternative" "7")
2736 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2738 (const_string "V1DF")
2739 (const_string "DF"))
2741 (const_string "DF")))])
2743 (define_insn "*movdf_integer"
2744 [(set (match_operand:DF 0 "nonimmediate_operand"
2745 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
2746 (match_operand:DF 1 "general_operand"
2747 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
2748 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2749 && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
2750 && (reload_in_progress || reload_completed
2751 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2752 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2753 && standard_80387_constant_p (operands[1]))
2754 || GET_CODE (operands[1]) != CONST_DOUBLE
2755 || memory_operand (operands[0], DFmode))"
2757 switch (which_alternative)
2760 return output_387_reg_move (insn, operands);
2763 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2764 return "fstp%z0\t%y0";
2766 return "fst%z0\t%y0";
2769 return standard_80387_constant_opcode (operands[1]);
2776 switch (get_attr_mode (insn))
2779 return "xorps\t%0, %0";
2781 return "xorpd\t%0, %0";
2783 return "pxor\t%0, %0";
2790 switch (get_attr_mode (insn))
2793 return "movaps\t{%1, %0|%0, %1}";
2795 return "movapd\t{%1, %0|%0, %1}";
2797 return "movdqa\t{%1, %0|%0, %1}";
2799 return "movq\t{%1, %0|%0, %1}";
2801 return "movsd\t{%1, %0|%0, %1}";
2803 return "movlpd\t{%1, %0|%0, %1}";
2805 return "movlps\t{%1, %0|%0, %1}";
2814 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2816 (cond [(eq_attr "alternative" "0,1,2")
2818 (eq_attr "alternative" "3,4")
2821 /* For SSE1, we have many fewer alternatives. */
2822 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2823 (cond [(eq_attr "alternative" "5,6")
2824 (const_string "V4SF")
2826 (const_string "V2SF"))
2828 /* xorps is one byte shorter. */
2829 (eq_attr "alternative" "5")
2830 (cond [(ne (symbol_ref "optimize_size")
2832 (const_string "V4SF")
2833 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2837 (const_string "V2DF"))
2839 /* For architectures resolving dependencies on
2840 whole SSE registers use APD move to break dependency
2841 chains, otherwise use short move to avoid extra work.
2843 movaps encodes one byte shorter. */
2844 (eq_attr "alternative" "6")
2846 [(ne (symbol_ref "optimize_size")
2848 (const_string "V4SF")
2849 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2851 (const_string "V2DF")
2853 (const_string "DF"))
2854 /* For architectures resolving dependencies on register
2855 parts we may avoid extra work to zero out upper part
2857 (eq_attr "alternative" "7")
2859 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2861 (const_string "V1DF")
2862 (const_string "DF"))
2864 (const_string "DF")))])
2867 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2868 (match_operand:DF 1 "general_operand" ""))]
2870 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871 && ! (ANY_FP_REG_P (operands[0]) ||
2872 (GET_CODE (operands[0]) == SUBREG
2873 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874 && ! (ANY_FP_REG_P (operands[1]) ||
2875 (GET_CODE (operands[1]) == SUBREG
2876 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2878 "ix86_split_long_move (operands); DONE;")
2880 (define_insn "*swapdf"
2881 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2882 (match_operand:DF 1 "fp_register_operand" "+f"))
2885 "reload_completed || TARGET_80387"
2887 if (STACK_TOP_P (operands[0]))
2892 [(set_attr "type" "fxch")
2893 (set_attr "mode" "DF")])
2895 (define_expand "movxf"
2896 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2897 (match_operand:XF 1 "general_operand" ""))]
2899 "ix86_expand_move (XFmode, operands); DONE;")
2901 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2902 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2903 ;; Pushing using integer instructions is longer except for constants
2904 ;; and direct memory references.
2905 ;; (assuming that any given constant is pushed only once, but this ought to be
2906 ;; handled elsewhere).
2908 (define_insn "*pushxf_nointeger"
2909 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2910 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2913 /* This insn should be already split before reg-stack. */
2916 [(set_attr "type" "multi")
2917 (set_attr "unit" "i387,*,*")
2918 (set_attr "mode" "XF,SI,SI")])
2920 (define_insn "*pushxf_integer"
2921 [(set (match_operand:XF 0 "push_operand" "=<,<")
2922 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2925 /* This insn should be already split before reg-stack. */
2928 [(set_attr "type" "multi")
2929 (set_attr "unit" "i387,*")
2930 (set_attr "mode" "XF,SI")])
2933 [(set (match_operand 0 "push_operand" "")
2934 (match_operand 1 "general_operand" ""))]
2936 && (GET_MODE (operands[0]) == XFmode
2937 || GET_MODE (operands[0]) == DFmode)
2938 && !ANY_FP_REG_P (operands[1])"
2940 "ix86_split_long_move (operands); DONE;")
2943 [(set (match_operand:XF 0 "push_operand" "")
2944 (match_operand:XF 1 "any_fp_register_operand" ""))]
2946 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2947 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2948 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2951 [(set (match_operand:XF 0 "push_operand" "")
2952 (match_operand:XF 1 "any_fp_register_operand" ""))]
2954 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2955 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2956 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2958 ;; Do not use integer registers when optimizing for size
2959 (define_insn "*movxf_nointeger"
2960 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2961 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2963 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2964 && (reload_in_progress || reload_completed
2965 || (optimize_size && standard_80387_constant_p (operands[1]))
2966 || GET_CODE (operands[1]) != CONST_DOUBLE
2967 || memory_operand (operands[0], XFmode))"
2969 switch (which_alternative)
2972 return output_387_reg_move (insn, operands);
2975 /* There is no non-popping store to memory for XFmode. So if
2976 we need one, follow the store with a load. */
2977 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2978 return "fstp%z0\t%y0\;fld%z0\t%y0";
2980 return "fstp%z0\t%y0";
2983 return standard_80387_constant_opcode (operands[1]);
2991 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2992 (set_attr "mode" "XF,XF,XF,SI,SI")])
2994 (define_insn "*movxf_integer"
2995 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2996 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2998 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2999 && (reload_in_progress || reload_completed
3000 || (optimize_size && standard_80387_constant_p (operands[1]))
3001 || GET_CODE (operands[1]) != CONST_DOUBLE
3002 || memory_operand (operands[0], XFmode))"
3004 switch (which_alternative)
3007 return output_387_reg_move (insn, operands);
3010 /* There is no non-popping store to memory for XFmode. So if
3011 we need one, follow the store with a load. */
3012 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3013 return "fstp%z0\t%y0\;fld%z0\t%y0";
3015 return "fstp%z0\t%y0";
3018 return standard_80387_constant_opcode (operands[1]);
3027 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3028 (set_attr "mode" "XF,XF,XF,SI,SI")])
3031 [(set (match_operand 0 "nonimmediate_operand" "")
3032 (match_operand 1 "general_operand" ""))]
3034 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3035 && GET_MODE (operands[0]) == XFmode
3036 && ! (ANY_FP_REG_P (operands[0]) ||
3037 (GET_CODE (operands[0]) == SUBREG
3038 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3039 && ! (ANY_FP_REG_P (operands[1]) ||
3040 (GET_CODE (operands[1]) == SUBREG
3041 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3043 "ix86_split_long_move (operands); DONE;")
3046 [(set (match_operand 0 "register_operand" "")
3047 (match_operand 1 "memory_operand" ""))]
3049 && MEM_P (operands[1])
3050 && (GET_MODE (operands[0]) == XFmode
3051 || GET_MODE (operands[0]) == SFmode
3052 || GET_MODE (operands[0]) == DFmode)
3053 && constant_pool_reference_p (operands[1])"
3054 [(set (match_dup 0) (match_dup 1))]
3056 rtx c = avoid_constant_pool_reference (operands[1]);
3057 rtx r = operands[0];
3059 if (GET_CODE (r) == SUBREG)
3064 if (!standard_sse_constant_p (c))
3067 else if (FP_REG_P (r))
3069 if (!standard_80387_constant_p (c))
3072 else if (MMX_REG_P (r))
3079 [(set (match_operand 0 "register_operand" "")
3080 (float_extend (match_operand 1 "memory_operand" "")))]
3082 && MEM_P (operands[1])
3083 && (GET_MODE (operands[0]) == XFmode
3084 || GET_MODE (operands[0]) == SFmode
3085 || GET_MODE (operands[0]) == DFmode)
3086 && constant_pool_reference_p (operands[1])"
3087 [(set (match_dup 0) (match_dup 1))]
3089 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
3090 rtx r = operands[0];
3092 if (GET_CODE (r) == SUBREG)
3097 if (!standard_sse_constant_p (c))
3100 else if (FP_REG_P (r))
3102 if (!standard_80387_constant_p (c))
3105 else if (MMX_REG_P (r))
3111 (define_insn "swapxf"
3112 [(set (match_operand:XF 0 "register_operand" "+f")
3113 (match_operand:XF 1 "register_operand" "+f"))
3118 if (STACK_TOP_P (operands[0]))
3123 [(set_attr "type" "fxch")
3124 (set_attr "mode" "XF")])
3126 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3128 [(set (match_operand:X87MODEF 0 "register_operand" "")
3129 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3130 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3131 && (standard_80387_constant_p (operands[1]) == 8
3132 || standard_80387_constant_p (operands[1]) == 9)"
3133 [(set (match_dup 0)(match_dup 1))
3135 (neg:X87MODEF (match_dup 0)))]
3139 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3140 if (real_isnegzero (&r))
3141 operands[1] = CONST0_RTX (<MODE>mode);
3143 operands[1] = CONST1_RTX (<MODE>mode);
3146 (define_expand "movtf"
3147 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3148 (match_operand:TF 1 "nonimmediate_operand" ""))]
3151 ix86_expand_move (TFmode, operands);
3155 (define_insn "*movtf_internal"
3156 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3157 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3159 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3161 switch (which_alternative)
3167 if (get_attr_mode (insn) == MODE_V4SF)
3168 return "xorps\t%0, %0";
3170 return "pxor\t%0, %0";
3173 if (get_attr_mode (insn) == MODE_V4SF)
3174 return "movaps\t{%1, %0|%0, %1}";
3176 return "movdqa\t{%1, %0|%0, %1}";
3181 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3183 (cond [(eq_attr "alternative" "2,3")
3185 (ne (symbol_ref "optimize_size")
3187 (const_string "V4SF")
3188 (const_string "TI"))
3189 (eq_attr "alternative" "4")
3191 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3193 (ne (symbol_ref "optimize_size")
3195 (const_string "V4SF")
3196 (const_string "TI"))]
3197 (const_string "DI")))])
3200 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3201 (match_operand:TF 1 "general_operand" ""))]
3202 "reload_completed && !SSE_REG_P (operands[0])
3203 && !SSE_REG_P (operands[1])"
3205 "ix86_split_long_move (operands); DONE;")
3207 ;; Zero extension instructions
3209 (define_expand "zero_extendhisi2"
3210 [(set (match_operand:SI 0 "register_operand" "")
3211 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3214 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3216 operands[1] = force_reg (HImode, operands[1]);
3217 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3222 (define_insn "zero_extendhisi2_and"
3223 [(set (match_operand:SI 0 "register_operand" "=r")
3224 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3225 (clobber (reg:CC FLAGS_REG))]
3226 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3228 [(set_attr "type" "alu1")
3229 (set_attr "mode" "SI")])
3232 [(set (match_operand:SI 0 "register_operand" "")
3233 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3234 (clobber (reg:CC FLAGS_REG))]
3235 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3236 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3237 (clobber (reg:CC FLAGS_REG))])]
3240 (define_insn "*zero_extendhisi2_movzwl"
3241 [(set (match_operand:SI 0 "register_operand" "=r")
3242 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3243 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3244 "movz{wl|x}\t{%1, %0|%0, %1}"
3245 [(set_attr "type" "imovx")
3246 (set_attr "mode" "SI")])
3248 (define_expand "zero_extendqihi2"
3250 [(set (match_operand:HI 0 "register_operand" "")
3251 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3252 (clobber (reg:CC FLAGS_REG))])]
3256 (define_insn "*zero_extendqihi2_and"
3257 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3258 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3259 (clobber (reg:CC FLAGS_REG))]
3260 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3262 [(set_attr "type" "alu1")
3263 (set_attr "mode" "HI")])
3265 (define_insn "*zero_extendqihi2_movzbw_and"
3266 [(set (match_operand:HI 0 "register_operand" "=r,r")
3267 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3268 (clobber (reg:CC FLAGS_REG))]
3269 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3271 [(set_attr "type" "imovx,alu1")
3272 (set_attr "mode" "HI")])
3274 ; zero extend to SImode here to avoid partial register stalls
3275 (define_insn "*zero_extendqihi2_movzbl"
3276 [(set (match_operand:HI 0 "register_operand" "=r")
3277 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3278 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3279 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3280 [(set_attr "type" "imovx")
3281 (set_attr "mode" "SI")])
3283 ;; For the movzbw case strip only the clobber
3285 [(set (match_operand:HI 0 "register_operand" "")
3286 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3287 (clobber (reg:CC FLAGS_REG))]
3289 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3290 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3291 [(set (match_operand:HI 0 "register_operand" "")
3292 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3294 ;; When source and destination does not overlap, clear destination
3295 ;; first and then do the movb
3297 [(set (match_operand:HI 0 "register_operand" "")
3298 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3299 (clobber (reg:CC FLAGS_REG))]
3301 && ANY_QI_REG_P (operands[0])
3302 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3303 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3304 [(set (match_dup 0) (const_int 0))
3305 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3306 "operands[2] = gen_lowpart (QImode, operands[0]);")
3308 ;; Rest is handled by single and.
3310 [(set (match_operand:HI 0 "register_operand" "")
3311 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3312 (clobber (reg:CC FLAGS_REG))]
3314 && true_regnum (operands[0]) == true_regnum (operands[1])"
3315 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3316 (clobber (reg:CC FLAGS_REG))])]
3319 (define_expand "zero_extendqisi2"
3321 [(set (match_operand:SI 0 "register_operand" "")
3322 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3323 (clobber (reg:CC FLAGS_REG))])]
3327 (define_insn "*zero_extendqisi2_and"
3328 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3329 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3330 (clobber (reg:CC FLAGS_REG))]
3331 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3333 [(set_attr "type" "alu1")
3334 (set_attr "mode" "SI")])
3336 (define_insn "*zero_extendqisi2_movzbw_and"
3337 [(set (match_operand:SI 0 "register_operand" "=r,r")
3338 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3339 (clobber (reg:CC FLAGS_REG))]
3340 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3342 [(set_attr "type" "imovx,alu1")
3343 (set_attr "mode" "SI")])
3345 (define_insn "*zero_extendqisi2_movzbw"
3346 [(set (match_operand:SI 0 "register_operand" "=r")
3347 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3348 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3349 "movz{bl|x}\t{%1, %0|%0, %1}"
3350 [(set_attr "type" "imovx")
3351 (set_attr "mode" "SI")])
3353 ;; For the movzbl case strip only the clobber
3355 [(set (match_operand:SI 0 "register_operand" "")
3356 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3357 (clobber (reg:CC FLAGS_REG))]
3359 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3360 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3362 (zero_extend:SI (match_dup 1)))])
3364 ;; When source and destination does not overlap, clear destination
3365 ;; first and then do the movb
3367 [(set (match_operand:SI 0 "register_operand" "")
3368 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3369 (clobber (reg:CC FLAGS_REG))]
3371 && ANY_QI_REG_P (operands[0])
3372 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3373 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3374 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3375 [(set (match_dup 0) (const_int 0))
3376 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3377 "operands[2] = gen_lowpart (QImode, operands[0]);")
3379 ;; Rest is handled by single and.
3381 [(set (match_operand:SI 0 "register_operand" "")
3382 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3383 (clobber (reg:CC FLAGS_REG))]
3385 && true_regnum (operands[0]) == true_regnum (operands[1])"
3386 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3387 (clobber (reg:CC FLAGS_REG))])]
3390 ;; %%% Kill me once multi-word ops are sane.
3391 (define_expand "zero_extendsidi2"
3392 [(set (match_operand:DI 0 "register_operand" "=r")
3393 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3398 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3403 (define_insn "zero_extendsidi2_32"
3404 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,*y,?*Yi,*Y2")
3406 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3407 (clobber (reg:CC FLAGS_REG))]
3413 movd\t{%1, %0|%0, %1}
3414 movd\t{%1, %0|%0, %1}
3415 movd\t{%1, %0|%0, %1}
3416 movd\t{%1, %0|%0, %1}"
3417 [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3418 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3420 (define_insn "zero_extendsidi2_rex64"
3421 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,*y,?*Yi,*Y2")
3423 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3426 mov\t{%k1, %k0|%k0, %k1}
3428 movd\t{%1, %0|%0, %1}
3429 movd\t{%1, %0|%0, %1}
3430 movd\t{%1, %0|%0, %1}
3431 movd\t{%1, %0|%0, %1}"
3432 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3433 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3436 [(set (match_operand:DI 0 "memory_operand" "")
3437 (zero_extend:DI (match_dup 0)))]
3439 [(set (match_dup 4) (const_int 0))]
3440 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3443 [(set (match_operand:DI 0 "register_operand" "")
3444 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3445 (clobber (reg:CC FLAGS_REG))]
3446 "!TARGET_64BIT && reload_completed
3447 && true_regnum (operands[0]) == true_regnum (operands[1])"
3448 [(set (match_dup 4) (const_int 0))]
3449 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3452 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3453 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3454 (clobber (reg:CC FLAGS_REG))]
3455 "!TARGET_64BIT && reload_completed
3456 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3457 [(set (match_dup 3) (match_dup 1))
3458 (set (match_dup 4) (const_int 0))]
3459 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3461 (define_insn "zero_extendhidi2"
3462 [(set (match_operand:DI 0 "register_operand" "=r")
3463 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3465 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3466 [(set_attr "type" "imovx")
3467 (set_attr "mode" "DI")])
3469 (define_insn "zero_extendqidi2"
3470 [(set (match_operand:DI 0 "register_operand" "=r")
3471 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3473 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3474 [(set_attr "type" "imovx")
3475 (set_attr "mode" "DI")])
3477 ;; Sign extension instructions
3479 (define_expand "extendsidi2"
3480 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3481 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3482 (clobber (reg:CC FLAGS_REG))
3483 (clobber (match_scratch:SI 2 ""))])]
3488 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3493 (define_insn "*extendsidi2_1"
3494 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3495 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3496 (clobber (reg:CC FLAGS_REG))
3497 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3501 (define_insn "extendsidi2_rex64"
3502 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3503 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3507 movs{lq|x}\t{%1,%0|%0, %1}"
3508 [(set_attr "type" "imovx")
3509 (set_attr "mode" "DI")
3510 (set_attr "prefix_0f" "0")
3511 (set_attr "modrm" "0,1")])
3513 (define_insn "extendhidi2"
3514 [(set (match_operand:DI 0 "register_operand" "=r")
3515 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3517 "movs{wq|x}\t{%1,%0|%0, %1}"
3518 [(set_attr "type" "imovx")
3519 (set_attr "mode" "DI")])
3521 (define_insn "extendqidi2"
3522 [(set (match_operand:DI 0 "register_operand" "=r")
3523 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3525 "movs{bq|x}\t{%1,%0|%0, %1}"
3526 [(set_attr "type" "imovx")
3527 (set_attr "mode" "DI")])
3529 ;; Extend to memory case when source register does die.
3531 [(set (match_operand:DI 0 "memory_operand" "")
3532 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3533 (clobber (reg:CC FLAGS_REG))
3534 (clobber (match_operand:SI 2 "register_operand" ""))]
3536 && dead_or_set_p (insn, operands[1])
3537 && !reg_mentioned_p (operands[1], operands[0]))"
3538 [(set (match_dup 3) (match_dup 1))
3539 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3540 (clobber (reg:CC FLAGS_REG))])
3541 (set (match_dup 4) (match_dup 1))]
3542 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3544 ;; Extend to memory case when source register does not die.
3546 [(set (match_operand:DI 0 "memory_operand" "")
3547 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3548 (clobber (reg:CC FLAGS_REG))
3549 (clobber (match_operand:SI 2 "register_operand" ""))]
3553 split_di (&operands[0], 1, &operands[3], &operands[4]);
3555 emit_move_insn (operands[3], operands[1]);
3557 /* Generate a cltd if possible and doing so it profitable. */
3558 if (true_regnum (operands[1]) == 0
3559 && true_regnum (operands[2]) == 1
3560 && (optimize_size || TARGET_USE_CLTD))
3562 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3566 emit_move_insn (operands[2], operands[1]);
3567 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3569 emit_move_insn (operands[4], operands[2]);
3573 ;; Extend to register case. Optimize case where source and destination
3574 ;; registers match and cases where we can use cltd.
3576 [(set (match_operand:DI 0 "register_operand" "")
3577 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3578 (clobber (reg:CC FLAGS_REG))
3579 (clobber (match_scratch:SI 2 ""))]
3583 split_di (&operands[0], 1, &operands[3], &operands[4]);
3585 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3586 emit_move_insn (operands[3], operands[1]);
3588 /* Generate a cltd if possible and doing so it profitable. */
3589 if (true_regnum (operands[3]) == 0
3590 && (optimize_size || TARGET_USE_CLTD))
3592 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3596 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3597 emit_move_insn (operands[4], operands[1]);
3599 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3603 (define_insn "extendhisi2"
3604 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3605 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3608 switch (get_attr_prefix_0f (insn))
3611 return "{cwtl|cwde}";
3613 return "movs{wl|x}\t{%1,%0|%0, %1}";
3616 [(set_attr "type" "imovx")
3617 (set_attr "mode" "SI")
3618 (set (attr "prefix_0f")
3619 ;; movsx is short decodable while cwtl is vector decoded.
3620 (if_then_else (and (eq_attr "cpu" "!k6")
3621 (eq_attr "alternative" "0"))
3623 (const_string "1")))
3625 (if_then_else (eq_attr "prefix_0f" "0")
3627 (const_string "1")))])
3629 (define_insn "*extendhisi2_zext"
3630 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3632 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3635 switch (get_attr_prefix_0f (insn))
3638 return "{cwtl|cwde}";
3640 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3643 [(set_attr "type" "imovx")
3644 (set_attr "mode" "SI")
3645 (set (attr "prefix_0f")
3646 ;; movsx is short decodable while cwtl is vector decoded.
3647 (if_then_else (and (eq_attr "cpu" "!k6")
3648 (eq_attr "alternative" "0"))
3650 (const_string "1")))
3652 (if_then_else (eq_attr "prefix_0f" "0")
3654 (const_string "1")))])
3656 (define_insn "extendqihi2"
3657 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3658 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3661 switch (get_attr_prefix_0f (insn))
3664 return "{cbtw|cbw}";
3666 return "movs{bw|x}\t{%1,%0|%0, %1}";
3669 [(set_attr "type" "imovx")
3670 (set_attr "mode" "HI")
3671 (set (attr "prefix_0f")
3672 ;; movsx is short decodable while cwtl is vector decoded.
3673 (if_then_else (and (eq_attr "cpu" "!k6")
3674 (eq_attr "alternative" "0"))
3676 (const_string "1")))
3678 (if_then_else (eq_attr "prefix_0f" "0")
3680 (const_string "1")))])
3682 (define_insn "extendqisi2"
3683 [(set (match_operand:SI 0 "register_operand" "=r")
3684 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3686 "movs{bl|x}\t{%1,%0|%0, %1}"
3687 [(set_attr "type" "imovx")
3688 (set_attr "mode" "SI")])
3690 (define_insn "*extendqisi2_zext"
3691 [(set (match_operand:DI 0 "register_operand" "=r")
3693 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3695 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3696 [(set_attr "type" "imovx")
3697 (set_attr "mode" "SI")])
3699 ;; Conversions between float and double.
3701 ;; These are all no-ops in the model used for the 80387. So just
3704 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3705 (define_insn "*dummy_extendsfdf2"
3706 [(set (match_operand:DF 0 "push_operand" "=<")
3707 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3712 [(set (match_operand:DF 0 "push_operand" "")
3713 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3715 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3716 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3719 [(set (match_operand:DF 0 "push_operand" "")
3720 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3722 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3723 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3725 (define_insn "*dummy_extendsfxf2"
3726 [(set (match_operand:XF 0 "push_operand" "=<")
3727 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3732 [(set (match_operand:XF 0 "push_operand" "")
3733 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3735 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3736 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3737 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3740 [(set (match_operand:XF 0 "push_operand" "")
3741 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3743 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3744 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3745 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3748 [(set (match_operand:XF 0 "push_operand" "")
3749 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3751 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3752 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3753 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3756 [(set (match_operand:XF 0 "push_operand" "")
3757 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3759 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3760 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3761 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3763 (define_expand "extendsfdf2"
3764 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3765 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3766 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3768 /* ??? Needed for compress_float_constant since all fp constants
3769 are LEGITIMATE_CONSTANT_P. */
3770 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3772 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3773 && standard_80387_constant_p (operands[1]) > 0)
3775 operands[1] = simplify_const_unary_operation
3776 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3777 emit_move_insn_1 (operands[0], operands[1]);
3780 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3784 (define_insn "*extendsfdf2_mixed"
3785 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3787 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3788 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3790 switch (which_alternative)
3793 return output_387_reg_move (insn, operands);
3796 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3797 return "fstp%z0\t%y0";
3799 return "fst%z0\t%y0";
3802 return "cvtss2sd\t{%1, %0|%0, %1}";
3808 [(set_attr "type" "fmov,fmov,ssecvt")
3809 (set_attr "mode" "SF,XF,DF")])
3811 (define_insn "*extendsfdf2_sse"
3812 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3813 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3814 "TARGET_SSE2 && TARGET_SSE_MATH"
3815 "cvtss2sd\t{%1, %0|%0, %1}"
3816 [(set_attr "type" "ssecvt")
3817 (set_attr "mode" "DF")])
3819 (define_insn "*extendsfdf2_i387"
3820 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3821 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3824 switch (which_alternative)
3827 return output_387_reg_move (insn, operands);
3830 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3831 return "fstp%z0\t%y0";
3833 return "fst%z0\t%y0";
3839 [(set_attr "type" "fmov")
3840 (set_attr "mode" "SF,XF")])
3842 (define_expand "extendsfxf2"
3843 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3844 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3847 /* ??? Needed for compress_float_constant since all fp constants
3848 are LEGITIMATE_CONSTANT_P. */
3849 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3851 if (standard_80387_constant_p (operands[1]) > 0)
3853 operands[1] = simplify_const_unary_operation
3854 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3855 emit_move_insn_1 (operands[0], operands[1]);
3858 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3862 (define_insn "*extendsfxf2_i387"
3863 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3864 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3867 switch (which_alternative)
3870 return output_387_reg_move (insn, operands);
3873 /* There is no non-popping store to memory for XFmode. So if
3874 we need one, follow the store with a load. */
3875 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3876 return "fstp%z0\t%y0";
3878 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3884 [(set_attr "type" "fmov")
3885 (set_attr "mode" "SF,XF")])
3887 (define_expand "extenddfxf2"
3888 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3889 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3892 /* ??? Needed for compress_float_constant since all fp constants
3893 are LEGITIMATE_CONSTANT_P. */
3894 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3896 if (standard_80387_constant_p (operands[1]) > 0)
3898 operands[1] = simplify_const_unary_operation
3899 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3900 emit_move_insn_1 (operands[0], operands[1]);
3903 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3907 (define_insn "*extenddfxf2_i387"
3908 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3909 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3912 switch (which_alternative)
3915 return output_387_reg_move (insn, operands);
3918 /* There is no non-popping store to memory for XFmode. So if
3919 we need one, follow the store with a load. */
3920 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3921 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3923 return "fstp%z0\t%y0";
3929 [(set_attr "type" "fmov")
3930 (set_attr "mode" "DF,XF")])
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case. Otherwise this is just like a simple move
3935 ;; insn. So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3938 ;; Conversion from DFmode to SFmode.
3940 (define_expand "truncdfsf2"
3941 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3943 (match_operand:DF 1 "nonimmediate_operand" "")))]
3944 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3946 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3948 else if (flag_unsafe_math_optimizations)
3952 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3953 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3958 (define_expand "truncdfsf2_with_temp"
3959 [(parallel [(set (match_operand:SF 0 "" "")
3960 (float_truncate:SF (match_operand:DF 1 "" "")))
3961 (clobber (match_operand:SF 2 "" ""))])]
3964 (define_insn "*truncdfsf_fast_mixed"
3965 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,x")
3967 (match_operand:DF 1 "nonimmediate_operand" "f ,f,xm")))]
3968 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3970 switch (which_alternative)
3973 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3974 return "fstp%z0\t%y0";
3976 return "fst%z0\t%y0";
3978 return output_387_reg_move (insn, operands);
3980 return "cvtsd2ss\t{%1, %0|%0, %1}";
3985 [(set_attr "type" "fmov,fmov,ssecvt")
3986 (set_attr "mode" "SF")])
3988 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3989 ;; because nothing we do here is unsafe.
3990 (define_insn "*truncdfsf_fast_sse"
3991 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3993 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3994 "TARGET_SSE2 && TARGET_SSE_MATH"
3995 "cvtsd2ss\t{%1, %0|%0, %1}"
3996 [(set_attr "type" "ssecvt")
3997 (set_attr "mode" "SF")])
3999 (define_insn "*truncdfsf_fast_i387"
4000 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4002 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4003 "TARGET_80387 && flag_unsafe_math_optimizations"
4004 "* return output_387_reg_move (insn, operands);"
4005 [(set_attr "type" "fmov")
4006 (set_attr "mode" "SF")])
4008 (define_insn "*truncdfsf_mixed"
4009 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y2")
4011 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Y2m")))
4012 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
4013 "TARGET_MIX_SSE_I387"
4015 switch (which_alternative)
4018 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4019 return "fstp%z0\t%y0";
4021 return "fst%z0\t%y0";
4025 return "cvtsd2ss\t{%1, %0|%0, %1}";
4030 [(set_attr "type" "fmov,multi,ssecvt")
4031 (set_attr "unit" "*,i387,*")
4032 (set_attr "mode" "SF")])
4034 (define_insn "*truncdfsf_i387"
4035 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4037 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4038 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4041 switch (which_alternative)
4044 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4045 return "fstp%z0\t%y0";
4047 return "fst%z0\t%y0";
4054 [(set_attr "type" "fmov,multi")
4055 (set_attr "unit" "*,i387")
4056 (set_attr "mode" "SF")])
4058 (define_insn "*truncdfsf2_i387_1"
4059 [(set (match_operand:SF 0 "memory_operand" "=m")
4061 (match_operand:DF 1 "register_operand" "f")))]
4063 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4064 && !TARGET_MIX_SSE_I387"
4066 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4067 return "fstp%z0\t%y0";
4069 return "fst%z0\t%y0";
4071 [(set_attr "type" "fmov")
4072 (set_attr "mode" "SF")])
4075 [(set (match_operand:SF 0 "register_operand" "")
4077 (match_operand:DF 1 "fp_register_operand" "")))
4078 (clobber (match_operand 2 "" ""))]
4080 [(set (match_dup 2) (match_dup 1))
4081 (set (match_dup 0) (match_dup 2))]
4083 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4086 ;; Conversion from XFmode to SFmode.
4088 (define_expand "truncxfsf2"
4089 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
4091 (match_operand:XF 1 "register_operand" "")))
4092 (clobber (match_dup 2))])]
4095 if (flag_unsafe_math_optimizations)
4097 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
4098 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
4099 if (reg != operands[0])
4100 emit_move_insn (operands[0], reg);
4104 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
4107 (define_insn "*truncxfsf2_mixed"
4108 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
4110 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4111 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
4114 gcc_assert (!which_alternative);
4115 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4116 return "fstp%z0\t%y0";
4118 return "fst%z0\t%y0";
4120 [(set_attr "type" "fmov,multi,multi,multi")
4121 (set_attr "unit" "*,i387,i387,i387")
4122 (set_attr "mode" "SF")])
4124 (define_insn "truncxfsf2_i387_noop"
4125 [(set (match_operand:SF 0 "register_operand" "=f")
4126 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
4127 "TARGET_80387 && flag_unsafe_math_optimizations"
4128 "* return output_387_reg_move (insn, operands);"
4129 [(set_attr "type" "fmov")
4130 (set_attr "mode" "SF")])
4132 (define_insn "*truncxfsf2_i387"
4133 [(set (match_operand:SF 0 "memory_operand" "=m")
4135 (match_operand:XF 1 "register_operand" "f")))]
4138 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4139 return "fstp%z0\t%y0";
4141 return "fst%z0\t%y0";
4143 [(set_attr "type" "fmov")
4144 (set_attr "mode" "SF")])
4147 [(set (match_operand:SF 0 "register_operand" "")
4149 (match_operand:XF 1 "register_operand" "")))
4150 (clobber (match_operand:SF 2 "memory_operand" ""))]
4151 "TARGET_80387 && reload_completed"
4152 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
4153 (set (match_dup 0) (match_dup 2))]
4157 [(set (match_operand:SF 0 "memory_operand" "")
4159 (match_operand:XF 1 "register_operand" "")))
4160 (clobber (match_operand:SF 2 "memory_operand" ""))]
4162 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4165 ;; Conversion from XFmode to DFmode.
4167 (define_expand "truncxfdf2"
4168 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4170 (match_operand:XF 1 "register_operand" "")))
4171 (clobber (match_dup 2))])]
4174 if (flag_unsafe_math_optimizations)
4176 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4177 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4178 if (reg != operands[0])
4179 emit_move_insn (operands[0], reg);
4183 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4186 (define_insn "*truncxfdf2_mixed"
4187 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y2*x")
4189 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4190 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4193 gcc_assert (!which_alternative);
4194 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4195 return "fstp%z0\t%y0";
4197 return "fst%z0\t%y0";
4199 [(set_attr "type" "fmov,multi,multi,multi")
4200 (set_attr "unit" "*,i387,i387,i387")
4201 (set_attr "mode" "DF")])
4203 (define_insn "truncxfdf2_i387_noop"
4204 [(set (match_operand:DF 0 "register_operand" "=f")
4205 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4206 "TARGET_80387 && flag_unsafe_math_optimizations"
4207 "* return output_387_reg_move (insn, operands);"
4208 [(set_attr "type" "fmov")
4209 (set_attr "mode" "DF")])
4211 (define_insn "*truncxfdf2_i387"
4212 [(set (match_operand:DF 0 "memory_operand" "=m")
4214 (match_operand:XF 1 "register_operand" "f")))]
4217 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4218 return "fstp%z0\t%y0";
4220 return "fst%z0\t%y0";
4222 [(set_attr "type" "fmov")
4223 (set_attr "mode" "DF")])
4226 [(set (match_operand:DF 0 "register_operand" "")
4228 (match_operand:XF 1 "register_operand" "")))
4229 (clobber (match_operand:DF 2 "memory_operand" ""))]
4230 "TARGET_80387 && reload_completed"
4231 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4232 (set (match_dup 0) (match_dup 2))]
4236 [(set (match_operand:DF 0 "memory_operand" "")
4238 (match_operand:XF 1 "register_operand" "")))
4239 (clobber (match_operand:DF 2 "memory_operand" ""))]
4241 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4244 ;; Signed conversion to DImode.
4246 (define_expand "fix_truncxfdi2"
4247 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4248 (fix:DI (match_operand:XF 1 "register_operand" "")))
4249 (clobber (reg:CC FLAGS_REG))])]
4254 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4259 (define_expand "fix_trunc<mode>di2"
4260 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4261 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4262 (clobber (reg:CC FLAGS_REG))])]
4263 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4266 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4268 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4271 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4273 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4274 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4275 if (out != operands[0])
4276 emit_move_insn (operands[0], out);
4281 ;; Signed conversion to SImode.
4283 (define_expand "fix_truncxfsi2"
4284 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4285 (fix:SI (match_operand:XF 1 "register_operand" "")))
4286 (clobber (reg:CC FLAGS_REG))])]
4291 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4296 (define_expand "fix_trunc<mode>si2"
4297 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4298 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4299 (clobber (reg:CC FLAGS_REG))])]
4300 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4303 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4305 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4308 if (SSE_FLOAT_MODE_P (<MODE>mode))
4310 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4311 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4312 if (out != operands[0])
4313 emit_move_insn (operands[0], out);
4318 ;; Signed conversion to HImode.
4320 (define_expand "fix_trunc<mode>hi2"
4321 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4322 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4323 (clobber (reg:CC FLAGS_REG))])]
4325 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4329 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4334 ;; Unsigned conversion to SImode.
4336 (define_expand "fixuns_trunc<mode>si2"
4338 [(set (match_operand:SI 0 "register_operand" "")
4340 (match_operand:SSEMODEF 1 "nonimmediate_operand" "")))
4342 (clobber (match_scratch:<ssevecmode> 3 ""))
4343 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4344 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4346 enum machine_mode mode = <MODE>mode;
4347 enum machine_mode vecmode = <ssevecmode>mode;
4348 REAL_VALUE_TYPE TWO31r;
4351 real_ldexp (&TWO31r, &dconst1, 31);
4352 two31 = const_double_from_real_value (TWO31r, mode);
4353 two31 = ix86_build_const_vector (mode, true, two31);
4354 operands[2] = force_reg (vecmode, two31);
4357 (define_insn_and_split "*fixuns_trunc<mode>_1"
4358 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4360 (match_operand:SSEMODEF 3 "nonimmediate_operand" "xm,xm")))
4361 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4362 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4363 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4364 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4366 "&& reload_completed"
4369 ix86_split_convert_uns_si_sse (operands);
4373 ;; Unsigned conversion to HImode.
4374 ;; Without these patterns, we'll try the unsigned SI conversion which
4375 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4377 (define_expand "fixuns_truncsfhi2"
4379 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))
4380 (set (match_operand:HI 0 "nonimmediate_operand" "")
4381 (subreg:HI (match_dup 2) 0))]
4383 "operands[2] = gen_reg_rtx (SImode);")
4385 (define_expand "fixuns_truncdfhi2"
4387 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))
4388 (set (match_operand:HI 0 "nonimmediate_operand" "")
4389 (subreg:HI (match_dup 2) 0))]
4390 "TARGET_SSE_MATH && TARGET_SSE2"
4391 "operands[2] = gen_reg_rtx (SImode);")
4393 ;; When SSE is available, it is always faster to use it!
4394 (define_insn "fix_truncsfdi_sse"
4395 [(set (match_operand:DI 0 "register_operand" "=r,r")
4396 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4397 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4398 "cvttss2si{q}\t{%1, %0|%0, %1}"
4399 [(set_attr "type" "sseicvt")
4400 (set_attr "mode" "SF")
4401 (set_attr "athlon_decode" "double,vector")
4402 (set_attr "amdfam10_decode" "double,double")])
4404 (define_insn "fix_truncdfdi_sse"
4405 [(set (match_operand:DI 0 "register_operand" "=r,r")
4406 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4407 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4408 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4409 [(set_attr "type" "sseicvt")
4410 (set_attr "mode" "DF")
4411 (set_attr "athlon_decode" "double,vector")
4412 (set_attr "amdfam10_decode" "double,double")])
4414 (define_insn "fix_truncsfsi_sse"
4415 [(set (match_operand:SI 0 "register_operand" "=r,r")
4416 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4417 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4418 "cvttss2si\t{%1, %0|%0, %1}"
4419 [(set_attr "type" "sseicvt")
4420 (set_attr "mode" "DF")
4421 (set_attr "athlon_decode" "double,vector")
4422 (set_attr "amdfam10_decode" "double,double")])
4424 (define_insn "fix_truncdfsi_sse"
4425 [(set (match_operand:SI 0 "register_operand" "=r,r")
4426 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "x,xm")))]
4427 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4428 "cvttsd2si\t{%1, %0|%0, %1}"
4429 [(set_attr "type" "sseicvt")
4430 (set_attr "mode" "DF")
4431 (set_attr "athlon_decode" "double,vector")
4432 (set_attr "amdfam10_decode" "double,double")])
4434 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4436 [(set (match_operand:DF 0 "register_operand" "")
4437 (match_operand:DF 1 "memory_operand" ""))
4438 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4439 (fix:SSEMODEI24 (match_dup 0)))]
4441 && peep2_reg_dead_p (2, operands[0])"
4442 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4446 [(set (match_operand:SF 0 "register_operand" "")
4447 (match_operand:SF 1 "memory_operand" ""))
4448 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4449 (fix:SSEMODEI24 (match_dup 0)))]
4451 && peep2_reg_dead_p (2, operands[0])"
4452 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4455 ;; Avoid vector decoded forms of the instruction.
4457 [(match_scratch:DF 2 "Y")
4458 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4459 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4460 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4461 [(set (match_dup 2) (match_dup 1))
4462 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4466 [(match_scratch:SF 2 "x")
4467 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4468 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4469 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4470 [(set (match_dup 2) (match_dup 1))
4471 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4474 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4475 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4476 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4478 && FLOAT_MODE_P (GET_MODE (operands[1]))
4479 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4480 && (TARGET_64BIT || <MODE>mode != DImode))
4482 && !(reload_completed || reload_in_progress)"
4487 if (memory_operand (operands[0], VOIDmode))
4488 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4491 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4492 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4498 [(set_attr "type" "fisttp")
4499 (set_attr "mode" "<MODE>")])
4501 (define_insn "fix_trunc<mode>_i387_fisttp"
4502 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4503 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4504 (clobber (match_scratch:XF 2 "=&1f"))]
4506 && FLOAT_MODE_P (GET_MODE (operands[1]))
4507 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4508 && (TARGET_64BIT || <MODE>mode != DImode))
4509 && TARGET_SSE_MATH)"
4510 "* return output_fix_trunc (insn, operands, 1);"
4511 [(set_attr "type" "fisttp")
4512 (set_attr "mode" "<MODE>")])
4514 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4515 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4516 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4517 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4518 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4520 && FLOAT_MODE_P (GET_MODE (operands[1]))
4521 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4522 && (TARGET_64BIT || <MODE>mode != DImode))
4523 && TARGET_SSE_MATH)"
4525 [(set_attr "type" "fisttp")
4526 (set_attr "mode" "<MODE>")])
4529 [(set (match_operand:X87MODEI 0 "register_operand" "")
4530 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4531 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4532 (clobber (match_scratch 3 ""))]
4534 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4535 (clobber (match_dup 3))])
4536 (set (match_dup 0) (match_dup 2))]
4540 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4541 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4542 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4543 (clobber (match_scratch 3 ""))]
4545 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4546 (clobber (match_dup 3))])]
4549 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4550 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4551 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4552 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4553 ;; function in i386.c.
4554 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4555 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4556 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4557 (clobber (reg:CC FLAGS_REG))]
4558 "TARGET_80387 && !TARGET_FISTTP
4559 && FLOAT_MODE_P (GET_MODE (operands[1]))
4560 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4561 && (TARGET_64BIT || <MODE>mode != DImode))
4562 && !(reload_completed || reload_in_progress)"
4567 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4569 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4570 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4571 if (memory_operand (operands[0], VOIDmode))
4572 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4573 operands[2], operands[3]));
4576 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4577 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4578 operands[2], operands[3],
4583 [(set_attr "type" "fistp")
4584 (set_attr "i387_cw" "trunc")
4585 (set_attr "mode" "<MODE>")])
4587 (define_insn "fix_truncdi_i387"
4588 [(set (match_operand:DI 0 "memory_operand" "=m")
4589 (fix:DI (match_operand 1 "register_operand" "f")))
4590 (use (match_operand:HI 2 "memory_operand" "m"))
4591 (use (match_operand:HI 3 "memory_operand" "m"))
4592 (clobber (match_scratch:XF 4 "=&1f"))]
4593 "TARGET_80387 && !TARGET_FISTTP
4594 && FLOAT_MODE_P (GET_MODE (operands[1]))
4595 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4596 "* return output_fix_trunc (insn, operands, 0);"
4597 [(set_attr "type" "fistp")
4598 (set_attr "i387_cw" "trunc")
4599 (set_attr "mode" "DI")])
4601 (define_insn "fix_truncdi_i387_with_temp"
4602 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4603 (fix:DI (match_operand 1 "register_operand" "f,f")))
4604 (use (match_operand:HI 2 "memory_operand" "m,m"))
4605 (use (match_operand:HI 3 "memory_operand" "m,m"))
4606 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4607 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4608 "TARGET_80387 && !TARGET_FISTTP
4609 && FLOAT_MODE_P (GET_MODE (operands[1]))
4610 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4612 [(set_attr "type" "fistp")
4613 (set_attr "i387_cw" "trunc")
4614 (set_attr "mode" "DI")])
4617 [(set (match_operand:DI 0 "register_operand" "")
4618 (fix:DI (match_operand 1 "register_operand" "")))
4619 (use (match_operand:HI 2 "memory_operand" ""))
4620 (use (match_operand:HI 3 "memory_operand" ""))
4621 (clobber (match_operand:DI 4 "memory_operand" ""))
4622 (clobber (match_scratch 5 ""))]
4624 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4627 (clobber (match_dup 5))])
4628 (set (match_dup 0) (match_dup 4))]
4632 [(set (match_operand:DI 0 "memory_operand" "")
4633 (fix:DI (match_operand 1 "register_operand" "")))
4634 (use (match_operand:HI 2 "memory_operand" ""))
4635 (use (match_operand:HI 3 "memory_operand" ""))
4636 (clobber (match_operand:DI 4 "memory_operand" ""))
4637 (clobber (match_scratch 5 ""))]
4639 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4642 (clobber (match_dup 5))])]
4645 (define_insn "fix_trunc<mode>_i387"
4646 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4647 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4648 (use (match_operand:HI 2 "memory_operand" "m"))
4649 (use (match_operand:HI 3 "memory_operand" "m"))]
4650 "TARGET_80387 && !TARGET_FISTTP
4651 && FLOAT_MODE_P (GET_MODE (operands[1]))
4652 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4653 "* return output_fix_trunc (insn, operands, 0);"
4654 [(set_attr "type" "fistp")
4655 (set_attr "i387_cw" "trunc")
4656 (set_attr "mode" "<MODE>")])
4658 (define_insn "fix_trunc<mode>_i387_with_temp"
4659 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4660 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4661 (use (match_operand:HI 2 "memory_operand" "m,m"))
4662 (use (match_operand:HI 3 "memory_operand" "m,m"))
4663 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4664 "TARGET_80387 && !TARGET_FISTTP
4665 && FLOAT_MODE_P (GET_MODE (operands[1]))
4666 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4668 [(set_attr "type" "fistp")
4669 (set_attr "i387_cw" "trunc")
4670 (set_attr "mode" "<MODE>")])
4673 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4674 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4675 (use (match_operand:HI 2 "memory_operand" ""))
4676 (use (match_operand:HI 3 "memory_operand" ""))
4677 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4679 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4681 (use (match_dup 3))])
4682 (set (match_dup 0) (match_dup 4))]
4686 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4687 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4688 (use (match_operand:HI 2 "memory_operand" ""))
4689 (use (match_operand:HI 3 "memory_operand" ""))
4690 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4692 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4694 (use (match_dup 3))])]
4697 (define_insn "x86_fnstcw_1"
4698 [(set (match_operand:HI 0 "memory_operand" "=m")
4699 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4702 [(set_attr "length" "2")
4703 (set_attr "mode" "HI")
4704 (set_attr "unit" "i387")])
4706 (define_insn "x86_fldcw_1"
4707 [(set (reg:HI FPCR_REG)
4708 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4711 [(set_attr "length" "2")
4712 (set_attr "mode" "HI")
4713 (set_attr "unit" "i387")
4714 (set_attr "athlon_decode" "vector")
4715 (set_attr "amdfam10_decode" "vector")])
4717 ;; Conversion between fixed point and floating point.
4719 ;; Even though we only accept memory inputs, the backend _really_
4720 ;; wants to be able to do this between registers.
4722 (define_expand "floathisf2"
4723 [(set (match_operand:SF 0 "register_operand" "")
4724 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4725 "TARGET_80387 || TARGET_SSE_MATH"
4727 if (TARGET_SSE_MATH)
4729 emit_insn (gen_floatsisf2 (operands[0],
4730 convert_to_mode (SImode, operands[1], 0)));
4735 (define_insn "*floathisf2_i387"
4736 [(set (match_operand:SF 0 "register_operand" "=f,f")
4737 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4738 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4742 [(set_attr "type" "fmov,multi")
4743 (set_attr "mode" "SF")
4744 (set_attr "unit" "*,i387")
4745 (set_attr "fp_int_src" "true")])
4747 (define_expand "floatsisf2"
4748 [(set (match_operand:SF 0 "register_operand" "")
4749 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4750 "TARGET_80387 || TARGET_SSE_MATH"
4753 (define_insn "*floatsisf2_mixed"
4754 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4755 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4756 "TARGET_MIX_SSE_I387"
4760 cvtsi2ss\t{%1, %0|%0, %1}
4761 cvtsi2ss\t{%1, %0|%0, %1}"
4762 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4763 (set_attr "mode" "SF")
4764 (set_attr "unit" "*,i387,*,*")
4765 (set_attr "athlon_decode" "*,*,vector,double")
4766 (set_attr "amdfam10_decode" "*,*,vector,double")
4767 (set_attr "fp_int_src" "true")])
4769 (define_insn "*floatsisf2_sse"
4770 [(set (match_operand:SF 0 "register_operand" "=x,x")
4771 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4773 "cvtsi2ss\t{%1, %0|%0, %1}"
4774 [(set_attr "type" "sseicvt")
4775 (set_attr "mode" "SF")
4776 (set_attr "athlon_decode" "vector,double")
4777 (set_attr "amdfam10_decode" "vector,double")
4778 (set_attr "fp_int_src" "true")])
4780 (define_insn "*floatsisf2_i387"
4781 [(set (match_operand:SF 0 "register_operand" "=f,f")
4782 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4787 [(set_attr "type" "fmov,multi")
4788 (set_attr "mode" "SF")
4789 (set_attr "unit" "*,i387")
4790 (set_attr "fp_int_src" "true")])
4792 (define_expand "floatdisf2"
4793 [(set (match_operand:SF 0 "register_operand" "")
4794 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4795 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4798 (define_insn "*floatdisf2_mixed"
4799 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4800 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4801 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4805 cvtsi2ss{q}\t{%1, %0|%0, %1}
4806 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4807 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4808 (set_attr "mode" "SF")
4809 (set_attr "unit" "*,i387,*,*")
4810 (set_attr "athlon_decode" "*,*,vector,double")
4811 (set_attr "amdfam10_decode" "*,*,vector,double")
4812 (set_attr "fp_int_src" "true")])
4814 (define_insn "*floatdisf2_sse"
4815 [(set (match_operand:SF 0 "register_operand" "=x,x")
4816 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4817 "TARGET_64BIT && TARGET_SSE_MATH"
4818 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4819 [(set_attr "type" "sseicvt")
4820 (set_attr "mode" "SF")
4821 (set_attr "athlon_decode" "vector,double")
4822 (set_attr "amdfam10_decode" "vector,double")
4823 (set_attr "fp_int_src" "true")])
4825 (define_insn "*floatdisf2_i387"
4826 [(set (match_operand:SF 0 "register_operand" "=f,f")
4827 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4832 [(set_attr "type" "fmov,multi")
4833 (set_attr "mode" "SF")
4834 (set_attr "unit" "*,i387")
4835 (set_attr "fp_int_src" "true")])
4837 (define_expand "floathidf2"
4838 [(set (match_operand:DF 0 "register_operand" "")
4839 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4840 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4842 if (TARGET_SSE2 && TARGET_SSE_MATH)
4844 emit_insn (gen_floatsidf2 (operands[0],
4845 convert_to_mode (SImode, operands[1], 0)));
4850 (define_insn "*floathidf2_i387"
4851 [(set (match_operand:DF 0 "register_operand" "=f,f")
4852 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4853 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4857 [(set_attr "type" "fmov,multi")
4858 (set_attr "mode" "DF")
4859 (set_attr "unit" "*,i387")
4860 (set_attr "fp_int_src" "true")])
4862 (define_expand "floatsidf2"
4863 [(set (match_operand:DF 0 "register_operand" "")
4864 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4865 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4868 (define_insn "*floatsidf2_mixed"
4869 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4870 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4871 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4875 cvtsi2sd\t{%1, %0|%0, %1}
4876 cvtsi2sd\t{%1, %0|%0, %1}"
4877 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4878 (set_attr "mode" "DF")
4879 (set_attr "unit" "*,i387,*,*")
4880 (set_attr "athlon_decode" "*,*,double,direct")
4881 (set_attr "amdfam10_decode" "*,*,vector,double")
4882 (set_attr "fp_int_src" "true")])
4884 (define_insn "*floatsidf2_sse"
4885 [(set (match_operand:DF 0 "register_operand" "=x,x")
4886 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4887 "TARGET_SSE2 && TARGET_SSE_MATH"
4888 "cvtsi2sd\t{%1, %0|%0, %1}"
4889 [(set_attr "type" "sseicvt")
4890 (set_attr "mode" "DF")
4891 (set_attr "athlon_decode" "double,direct")
4892 (set_attr "amdfam10_decode" "vector,double")
4893 (set_attr "fp_int_src" "true")])
4895 (define_insn "*floatsidf2_i387"
4896 [(set (match_operand:DF 0 "register_operand" "=f,f")
4897 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4902 [(set_attr "type" "fmov,multi")
4903 (set_attr "mode" "DF")
4904 (set_attr "unit" "*,i387")
4905 (set_attr "fp_int_src" "true")])
4907 (define_expand "floatdidf2"
4908 [(set (match_operand:DF 0 "register_operand" "")
4909 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4910 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4912 if (!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)
4914 ix86_expand_convert_sign_didf_sse (operands[0], operands[1]);
4919 (define_insn "*floatdidf2_mixed"
4920 [(set (match_operand:DF 0 "register_operand" "=f,?f,x,x")
4921 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4922 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4926 cvtsi2sd{q}\t{%1, %0|%0, %1}
4927 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4928 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4929 (set_attr "mode" "DF")
4930 (set_attr "unit" "*,i387,*,*")
4931 (set_attr "athlon_decode" "*,*,double,direct")
4932 (set_attr "amdfam10_decode" "*,*,vector,double")
4933 (set_attr "fp_int_src" "true")])
4935 (define_insn "*floatdidf2_sse"
4936 [(set (match_operand:DF 0 "register_operand" "=x,x")
4937 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4938 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4939 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4940 [(set_attr "type" "sseicvt")
4941 (set_attr "mode" "DF")
4942 (set_attr "athlon_decode" "double,direct")
4943 (set_attr "amdfam10_decode" "vector,double")
4944 (set_attr "fp_int_src" "true")])
4946 (define_insn "*floatdidf2_i387"
4947 [(set (match_operand:DF 0 "register_operand" "=f,f")
4948 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4953 [(set_attr "type" "fmov,multi")
4954 (set_attr "mode" "DF")
4955 (set_attr "unit" "*,i387")
4956 (set_attr "fp_int_src" "true")])
4958 (define_insn "floathixf2"
4959 [(set (match_operand:XF 0 "register_operand" "=f,f")
4960 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4965 [(set_attr "type" "fmov,multi")
4966 (set_attr "mode" "XF")
4967 (set_attr "unit" "*,i387")
4968 (set_attr "fp_int_src" "true")])
4970 (define_insn "floatsixf2"
4971 [(set (match_operand:XF 0 "register_operand" "=f,f")
4972 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4977 [(set_attr "type" "fmov,multi")
4978 (set_attr "mode" "XF")
4979 (set_attr "unit" "*,i387")
4980 (set_attr "fp_int_src" "true")])
4982 (define_insn "floatdixf2"
4983 [(set (match_operand:XF 0 "register_operand" "=f,f")
4984 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4989 [(set_attr "type" "fmov,multi")
4990 (set_attr "mode" "XF")
4991 (set_attr "unit" "*,i387")
4992 (set_attr "fp_int_src" "true")])
4994 ;; %%% Kill these when reload knows how to do it.
4996 [(set (match_operand 0 "fp_register_operand" "")
4997 (float (match_operand 1 "register_operand" "")))]
5000 && FLOAT_MODE_P (GET_MODE (operands[0]))"
5003 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
5004 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
5005 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
5006 ix86_free_from_memory (GET_MODE (operands[1]));
5010 (define_expand "floatunssisf2"
5011 [(use (match_operand:SF 0 "register_operand" ""))
5012 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5015 if (TARGET_SSE_MATH && TARGET_SSE2)
5016 ix86_expand_convert_uns_sisf_sse (operands[0], operands[1]);
5018 x86_emit_floatuns (operands);
5022 (define_expand "floatunssidf2"
5023 [(use (match_operand:DF 0 "register_operand" ""))
5024 (use (match_operand:SI 1 "nonimmediate_operand" ""))]
5025 "!TARGET_64BIT && TARGET_SSE_MATH && TARGET_SSE2"
5026 "ix86_expand_convert_uns_sidf_sse (operands[0], operands[1]); DONE;")
5028 (define_expand "floatunsdisf2"
5029 [(use (match_operand:SF 0 "register_operand" ""))
5030 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5031 "TARGET_64BIT && TARGET_SSE_MATH"
5032 "x86_emit_floatuns (operands); DONE;")
5034 (define_expand "floatunsdidf2"
5035 [(use (match_operand:DF 0 "register_operand" ""))
5036 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5037 "TARGET_SSE_MATH && TARGET_SSE2
5038 && (TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)"
5041 x86_emit_floatuns (operands);
5043 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5047 ;; SSE extract/set expanders
5052 ;; %%% splits for addditi3
5054 (define_expand "addti3"
5055 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5056 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5057 (match_operand:TI 2 "x86_64_general_operand" "")))
5058 (clobber (reg:CC FLAGS_REG))]
5060 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5062 (define_insn "*addti3_1"
5063 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5064 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5065 (match_operand:TI 2 "general_operand" "roiF,riF")))
5066 (clobber (reg:CC FLAGS_REG))]
5067 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5071 [(set (match_operand:TI 0 "nonimmediate_operand" "")
5072 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5073 (match_operand:TI 2 "general_operand" "")))
5074 (clobber (reg:CC FLAGS_REG))]
5075 "TARGET_64BIT && reload_completed"
5076 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5078 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5079 (parallel [(set (match_dup 3)
5080 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5083 (clobber (reg:CC FLAGS_REG))])]
5084 "split_ti (operands+0, 1, operands+0, operands+3);
5085 split_ti (operands+1, 1, operands+1, operands+4);
5086 split_ti (operands+2, 1, operands+2, operands+5);")
5088 ;; %%% splits for addsidi3
5089 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
5090 ; (plus:DI (match_operand:DI 1 "general_operand" "")
5091 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5093 (define_expand "adddi3"
5094 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5095 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5096 (match_operand:DI 2 "x86_64_general_operand" "")))
5097 (clobber (reg:CC FLAGS_REG))]
5099 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5101 (define_insn "*adddi3_1"
5102 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5103 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5104 (match_operand:DI 2 "general_operand" "roiF,riF")))
5105 (clobber (reg:CC FLAGS_REG))]
5106 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5110 [(set (match_operand:DI 0 "nonimmediate_operand" "")
5111 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5112 (match_operand:DI 2 "general_operand" "")))
5113 (clobber (reg:CC FLAGS_REG))]
5114 "!TARGET_64BIT && reload_completed"
5115 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5117 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5118 (parallel [(set (match_dup 3)
5119 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5122 (clobber (reg:CC FLAGS_REG))])]
5123 "split_di (operands+0, 1, operands+0, operands+3);
5124 split_di (operands+1, 1, operands+1, operands+4);
5125 split_di (operands+2, 1, operands+2, operands+5);")
5127 (define_insn "adddi3_carry_rex64"
5128 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5129 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5130 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5131 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5132 (clobber (reg:CC FLAGS_REG))]
5133 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5134 "adc{q}\t{%2, %0|%0, %2}"
5135 [(set_attr "type" "alu")
5136 (set_attr "pent_pair" "pu")
5137 (set_attr "mode" "DI")])
5139 (define_insn "*adddi3_cc_rex64"
5140 [(set (reg:CC FLAGS_REG)
5141 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5142 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5144 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5145 (plus:DI (match_dup 1) (match_dup 2)))]
5146 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5147 "add{q}\t{%2, %0|%0, %2}"
5148 [(set_attr "type" "alu")
5149 (set_attr "mode" "DI")])
5151 (define_insn "addqi3_carry"
5152 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5153 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5154 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5155 (match_operand:QI 2 "general_operand" "qi,qm")))
5156 (clobber (reg:CC FLAGS_REG))]
5157 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5158 "adc{b}\t{%2, %0|%0, %2}"
5159 [(set_attr "type" "alu")
5160 (set_attr "pent_pair" "pu")
5161 (set_attr "mode" "QI")])
5163 (define_insn "addhi3_carry"
5164 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5165 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5166 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5167 (match_operand:HI 2 "general_operand" "ri,rm")))
5168 (clobber (reg:CC FLAGS_REG))]
5169 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5170 "adc{w}\t{%2, %0|%0, %2}"
5171 [(set_attr "type" "alu")
5172 (set_attr "pent_pair" "pu")
5173 (set_attr "mode" "HI")])
5175 (define_insn "addsi3_carry"
5176 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5177 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5178 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5179 (match_operand:SI 2 "general_operand" "ri,rm")))
5180 (clobber (reg:CC FLAGS_REG))]
5181 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5182 "adc{l}\t{%2, %0|%0, %2}"
5183 [(set_attr "type" "alu")
5184 (set_attr "pent_pair" "pu")
5185 (set_attr "mode" "SI")])
5187 (define_insn "*addsi3_carry_zext"
5188 [(set (match_operand:DI 0 "register_operand" "=r")
5190 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5191 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5192 (match_operand:SI 2 "general_operand" "rim"))))
5193 (clobber (reg:CC FLAGS_REG))]
5194 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5195 "adc{l}\t{%2, %k0|%k0, %2}"
5196 [(set_attr "type" "alu")
5197 (set_attr "pent_pair" "pu")
5198 (set_attr "mode" "SI")])
5200 (define_insn "*addsi3_cc"
5201 [(set (reg:CC FLAGS_REG)
5202 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5203 (match_operand:SI 2 "general_operand" "ri,rm")]
5205 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5206 (plus:SI (match_dup 1) (match_dup 2)))]
5207 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5208 "add{l}\t{%2, %0|%0, %2}"
5209 [(set_attr "type" "alu")
5210 (set_attr "mode" "SI")])
5212 (define_insn "addqi3_cc"
5213 [(set (reg:CC FLAGS_REG)
5214 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5215 (match_operand:QI 2 "general_operand" "qi,qm")]
5217 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5218 (plus:QI (match_dup 1) (match_dup 2)))]
5219 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5220 "add{b}\t{%2, %0|%0, %2}"
5221 [(set_attr "type" "alu")
5222 (set_attr "mode" "QI")])
5224 (define_expand "addsi3"
5225 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5226 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5227 (match_operand:SI 2 "general_operand" "")))
5228 (clobber (reg:CC FLAGS_REG))])]
5230 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5232 (define_insn "*lea_1"
5233 [(set (match_operand:SI 0 "register_operand" "=r")
5234 (match_operand:SI 1 "no_seg_address_operand" "p"))]
5236 "lea{l}\t{%a1, %0|%0, %a1}"
5237 [(set_attr "type" "lea")
5238 (set_attr "mode" "SI")])
5240 (define_insn "*lea_1_rex64"
5241 [(set (match_operand:SI 0 "register_operand" "=r")
5242 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5244 "lea{l}\t{%a1, %0|%0, %a1}"
5245 [(set_attr "type" "lea")
5246 (set_attr "mode" "SI")])
5248 (define_insn "*lea_1_zext"
5249 [(set (match_operand:DI 0 "register_operand" "=r")
5251 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5253 "lea{l}\t{%a1, %k0|%k0, %a1}"
5254 [(set_attr "type" "lea")
5255 (set_attr "mode" "SI")])
5257 (define_insn "*lea_2_rex64"
5258 [(set (match_operand:DI 0 "register_operand" "=r")
5259 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5261 "lea{q}\t{%a1, %0|%0, %a1}"
5262 [(set_attr "type" "lea")
5263 (set_attr "mode" "DI")])
5265 ;; The lea patterns for non-Pmodes needs to be matched by several
5266 ;; insns converted to real lea by splitters.
5268 (define_insn_and_split "*lea_general_1"
5269 [(set (match_operand 0 "register_operand" "=r")
5270 (plus (plus (match_operand 1 "index_register_operand" "l")
5271 (match_operand 2 "register_operand" "r"))
5272 (match_operand 3 "immediate_operand" "i")))]
5273 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5274 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5275 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5276 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5277 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5278 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5279 || GET_MODE (operands[3]) == VOIDmode)"
5281 "&& reload_completed"
5285 operands[0] = gen_lowpart (SImode, operands[0]);
5286 operands[1] = gen_lowpart (Pmode, operands[1]);
5287 operands[2] = gen_lowpart (Pmode, operands[2]);
5288 operands[3] = gen_lowpart (Pmode, operands[3]);
5289 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5291 if (Pmode != SImode)
5292 pat = gen_rtx_SUBREG (SImode, pat, 0);
5293 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5296 [(set_attr "type" "lea")
5297 (set_attr "mode" "SI")])
5299 (define_insn_and_split "*lea_general_1_zext"
5300 [(set (match_operand:DI 0 "register_operand" "=r")
5302 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5303 (match_operand:SI 2 "register_operand" "r"))
5304 (match_operand:SI 3 "immediate_operand" "i"))))]
5307 "&& reload_completed"
5309 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5311 (match_dup 3)) 0)))]
5313 operands[1] = gen_lowpart (Pmode, operands[1]);
5314 operands[2] = gen_lowpart (Pmode, operands[2]);
5315 operands[3] = gen_lowpart (Pmode, operands[3]);
5317 [(set_attr "type" "lea")
5318 (set_attr "mode" "SI")])
5320 (define_insn_and_split "*lea_general_2"
5321 [(set (match_operand 0 "register_operand" "=r")
5322 (plus (mult (match_operand 1 "index_register_operand" "l")
5323 (match_operand 2 "const248_operand" "i"))
5324 (match_operand 3 "nonmemory_operand" "ri")))]
5325 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5326 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5327 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5328 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5329 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5330 || GET_MODE (operands[3]) == VOIDmode)"
5332 "&& reload_completed"
5336 operands[0] = gen_lowpart (SImode, operands[0]);
5337 operands[1] = gen_lowpart (Pmode, operands[1]);
5338 operands[3] = gen_lowpart (Pmode, operands[3]);
5339 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5341 if (Pmode != SImode)
5342 pat = gen_rtx_SUBREG (SImode, pat, 0);
5343 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5346 [(set_attr "type" "lea")
5347 (set_attr "mode" "SI")])
5349 (define_insn_and_split "*lea_general_2_zext"
5350 [(set (match_operand:DI 0 "register_operand" "=r")
5352 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5353 (match_operand:SI 2 "const248_operand" "n"))
5354 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5357 "&& reload_completed"
5359 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5361 (match_dup 3)) 0)))]
5363 operands[1] = gen_lowpart (Pmode, operands[1]);
5364 operands[3] = gen_lowpart (Pmode, operands[3]);
5366 [(set_attr "type" "lea")
5367 (set_attr "mode" "SI")])
5369 (define_insn_and_split "*lea_general_3"
5370 [(set (match_operand 0 "register_operand" "=r")
5371 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5372 (match_operand 2 "const248_operand" "i"))
5373 (match_operand 3 "register_operand" "r"))
5374 (match_operand 4 "immediate_operand" "i")))]
5375 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5376 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5377 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5378 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5379 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5381 "&& reload_completed"
5385 operands[0] = gen_lowpart (SImode, operands[0]);
5386 operands[1] = gen_lowpart (Pmode, operands[1]);
5387 operands[3] = gen_lowpart (Pmode, operands[3]);
5388 operands[4] = gen_lowpart (Pmode, operands[4]);
5389 pat = gen_rtx_PLUS (Pmode,
5390 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5394 if (Pmode != SImode)
5395 pat = gen_rtx_SUBREG (SImode, pat, 0);
5396 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5399 [(set_attr "type" "lea")
5400 (set_attr "mode" "SI")])
5402 (define_insn_and_split "*lea_general_3_zext"
5403 [(set (match_operand:DI 0 "register_operand" "=r")
5405 (plus:SI (plus:SI (mult:SI
5406 (match_operand:SI 1 "index_register_operand" "l")
5407 (match_operand:SI 2 "const248_operand" "n"))
5408 (match_operand:SI 3 "register_operand" "r"))
5409 (match_operand:SI 4 "immediate_operand" "i"))))]
5412 "&& reload_completed"
5414 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5417 (match_dup 4)) 0)))]
5419 operands[1] = gen_lowpart (Pmode, operands[1]);
5420 operands[3] = gen_lowpart (Pmode, operands[3]);
5421 operands[4] = gen_lowpart (Pmode, operands[4]);
5423 [(set_attr "type" "lea")
5424 (set_attr "mode" "SI")])
5426 (define_insn "*adddi_1_rex64"
5427 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5428 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5429 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5430 (clobber (reg:CC FLAGS_REG))]
5431 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5433 switch (get_attr_type (insn))
5436 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5437 return "lea{q}\t{%a2, %0|%0, %a2}";
5440 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5441 if (operands[2] == const1_rtx)
5442 return "inc{q}\t%0";
5445 gcc_assert (operands[2] == constm1_rtx);
5446 return "dec{q}\t%0";
5450 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5452 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5453 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5454 if (CONST_INT_P (operands[2])
5455 /* Avoid overflows. */
5456 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5457 && (INTVAL (operands[2]) == 128
5458 || (INTVAL (operands[2]) < 0
5459 && INTVAL (operands[2]) != -128)))
5461 operands[2] = GEN_INT (-INTVAL (operands[2]));
5462 return "sub{q}\t{%2, %0|%0, %2}";
5464 return "add{q}\t{%2, %0|%0, %2}";
5468 (cond [(eq_attr "alternative" "2")
5469 (const_string "lea")
5470 ; Current assemblers are broken and do not allow @GOTOFF in
5471 ; ought but a memory context.
5472 (match_operand:DI 2 "pic_symbolic_operand" "")
5473 (const_string "lea")
5474 (match_operand:DI 2 "incdec_operand" "")
5475 (const_string "incdec")
5477 (const_string "alu")))
5478 (set_attr "mode" "DI")])
5480 ;; Convert lea to the lea pattern to avoid flags dependency.
5482 [(set (match_operand:DI 0 "register_operand" "")
5483 (plus:DI (match_operand:DI 1 "register_operand" "")
5484 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5485 (clobber (reg:CC FLAGS_REG))]
5486 "TARGET_64BIT && reload_completed
5487 && true_regnum (operands[0]) != true_regnum (operands[1])"
5489 (plus:DI (match_dup 1)
5493 (define_insn "*adddi_2_rex64"
5494 [(set (reg FLAGS_REG)
5496 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5497 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5499 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5500 (plus:DI (match_dup 1) (match_dup 2)))]
5501 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5502 && ix86_binary_operator_ok (PLUS, DImode, operands)
5503 /* Current assemblers are broken and do not allow @GOTOFF in
5504 ought but a memory context. */
5505 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5507 switch (get_attr_type (insn))
5510 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5511 if (operands[2] == const1_rtx)
5512 return "inc{q}\t%0";
5515 gcc_assert (operands[2] == constm1_rtx);
5516 return "dec{q}\t%0";
5520 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5521 /* ???? We ought to handle there the 32bit case too
5522 - do we need new constraint? */
5523 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5524 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5525 if (CONST_INT_P (operands[2])
5526 /* Avoid overflows. */
5527 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5528 && (INTVAL (operands[2]) == 128
5529 || (INTVAL (operands[2]) < 0
5530 && INTVAL (operands[2]) != -128)))
5532 operands[2] = GEN_INT (-INTVAL (operands[2]));
5533 return "sub{q}\t{%2, %0|%0, %2}";
5535 return "add{q}\t{%2, %0|%0, %2}";
5539 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5540 (const_string "incdec")
5541 (const_string "alu")))
5542 (set_attr "mode" "DI")])
5544 (define_insn "*adddi_3_rex64"
5545 [(set (reg FLAGS_REG)
5546 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5547 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5548 (clobber (match_scratch:DI 0 "=r"))]
5550 && ix86_match_ccmode (insn, CCZmode)
5551 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5552 /* Current assemblers are broken and do not allow @GOTOFF in
5553 ought but a memory context. */
5554 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5556 switch (get_attr_type (insn))
5559 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5560 if (operands[2] == const1_rtx)
5561 return "inc{q}\t%0";
5564 gcc_assert (operands[2] == constm1_rtx);
5565 return "dec{q}\t%0";
5569 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5570 /* ???? We ought to handle there the 32bit case too
5571 - do we need new constraint? */
5572 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5573 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5574 if (CONST_INT_P (operands[2])
5575 /* Avoid overflows. */
5576 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
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{q}\t{%2, %0|%0, %2}";
5584 return "add{q}\t{%2, %0|%0, %2}";
5588 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5589 (const_string "incdec")
5590 (const_string "alu")))
5591 (set_attr "mode" "DI")])
5593 ; For comparisons against 1, -1 and 128, we may generate better code
5594 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5595 ; is matched then. We can't accept general immediate, because for
5596 ; case of overflows, the result is messed up.
5597 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5599 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5600 ; only for comparisons not depending on it.
5601 (define_insn "*adddi_4_rex64"
5602 [(set (reg FLAGS_REG)
5603 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5604 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5605 (clobber (match_scratch:DI 0 "=rm"))]
5607 && ix86_match_ccmode (insn, CCGCmode)"
5609 switch (get_attr_type (insn))
5612 if (operands[2] == constm1_rtx)
5613 return "inc{q}\t%0";
5616 gcc_assert (operands[2] == const1_rtx);
5617 return "dec{q}\t%0";
5621 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5622 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5623 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5624 if ((INTVAL (operands[2]) == -128
5625 || (INTVAL (operands[2]) > 0
5626 && INTVAL (operands[2]) != 128))
5627 /* Avoid overflows. */
5628 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5629 return "sub{q}\t{%2, %0|%0, %2}";
5630 operands[2] = GEN_INT (-INTVAL (operands[2]));
5631 return "add{q}\t{%2, %0|%0, %2}";
5635 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5636 (const_string "incdec")
5637 (const_string "alu")))
5638 (set_attr "mode" "DI")])
5640 (define_insn "*adddi_5_rex64"
5641 [(set (reg FLAGS_REG)
5643 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5644 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5646 (clobber (match_scratch:DI 0 "=r"))]
5648 && ix86_match_ccmode (insn, CCGOCmode)
5649 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5650 /* Current assemblers are broken and do not allow @GOTOFF in
5651 ought but a memory context. */
5652 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5654 switch (get_attr_type (insn))
5657 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658 if (operands[2] == const1_rtx)
5659 return "inc{q}\t%0";
5662 gcc_assert (operands[2] == constm1_rtx);
5663 return "dec{q}\t%0";
5667 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5668 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5669 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5670 if (CONST_INT_P (operands[2])
5671 /* Avoid overflows. */
5672 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5673 && (INTVAL (operands[2]) == 128
5674 || (INTVAL (operands[2]) < 0
5675 && INTVAL (operands[2]) != -128)))
5677 operands[2] = GEN_INT (-INTVAL (operands[2]));
5678 return "sub{q}\t{%2, %0|%0, %2}";
5680 return "add{q}\t{%2, %0|%0, %2}";
5684 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5685 (const_string "incdec")
5686 (const_string "alu")))
5687 (set_attr "mode" "DI")])
5690 (define_insn "*addsi_1"
5691 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5692 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5693 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5694 (clobber (reg:CC FLAGS_REG))]
5695 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5697 switch (get_attr_type (insn))
5700 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5701 return "lea{l}\t{%a2, %0|%0, %a2}";
5704 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5705 if (operands[2] == const1_rtx)
5706 return "inc{l}\t%0";
5709 gcc_assert (operands[2] == constm1_rtx);
5710 return "dec{l}\t%0";
5714 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5716 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5717 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5718 if (CONST_INT_P (operands[2])
5719 && (INTVAL (operands[2]) == 128
5720 || (INTVAL (operands[2]) < 0
5721 && INTVAL (operands[2]) != -128)))
5723 operands[2] = GEN_INT (-INTVAL (operands[2]));
5724 return "sub{l}\t{%2, %0|%0, %2}";
5726 return "add{l}\t{%2, %0|%0, %2}";
5730 (cond [(eq_attr "alternative" "2")
5731 (const_string "lea")
5732 ; Current assemblers are broken and do not allow @GOTOFF in
5733 ; ought but a memory context.
5734 (match_operand:SI 2 "pic_symbolic_operand" "")
5735 (const_string "lea")
5736 (match_operand:SI 2 "incdec_operand" "")
5737 (const_string "incdec")
5739 (const_string "alu")))
5740 (set_attr "mode" "SI")])
5742 ;; Convert lea to the lea pattern to avoid flags dependency.
5744 [(set (match_operand 0 "register_operand" "")
5745 (plus (match_operand 1 "register_operand" "")
5746 (match_operand 2 "nonmemory_operand" "")))
5747 (clobber (reg:CC FLAGS_REG))]
5749 && true_regnum (operands[0]) != true_regnum (operands[1])"
5753 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5754 may confuse gen_lowpart. */
5755 if (GET_MODE (operands[0]) != Pmode)
5757 operands[1] = gen_lowpart (Pmode, operands[1]);
5758 operands[2] = gen_lowpart (Pmode, operands[2]);
5760 operands[0] = gen_lowpart (SImode, operands[0]);
5761 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5762 if (Pmode != SImode)
5763 pat = gen_rtx_SUBREG (SImode, pat, 0);
5764 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5768 ;; It may seem that nonimmediate operand is proper one for operand 1.
5769 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5770 ;; we take care in ix86_binary_operator_ok to not allow two memory
5771 ;; operands so proper swapping will be done in reload. This allow
5772 ;; patterns constructed from addsi_1 to match.
5773 (define_insn "addsi_1_zext"
5774 [(set (match_operand:DI 0 "register_operand" "=r,r")
5776 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5777 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5778 (clobber (reg:CC FLAGS_REG))]
5779 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5781 switch (get_attr_type (insn))
5784 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5785 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5788 if (operands[2] == const1_rtx)
5789 return "inc{l}\t%k0";
5792 gcc_assert (operands[2] == constm1_rtx);
5793 return "dec{l}\t%k0";
5797 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5798 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5799 if (CONST_INT_P (operands[2])
5800 && (INTVAL (operands[2]) == 128
5801 || (INTVAL (operands[2]) < 0
5802 && INTVAL (operands[2]) != -128)))
5804 operands[2] = GEN_INT (-INTVAL (operands[2]));
5805 return "sub{l}\t{%2, %k0|%k0, %2}";
5807 return "add{l}\t{%2, %k0|%k0, %2}";
5811 (cond [(eq_attr "alternative" "1")
5812 (const_string "lea")
5813 ; Current assemblers are broken and do not allow @GOTOFF in
5814 ; ought but a memory context.
5815 (match_operand:SI 2 "pic_symbolic_operand" "")
5816 (const_string "lea")
5817 (match_operand:SI 2 "incdec_operand" "")
5818 (const_string "incdec")
5820 (const_string "alu")))
5821 (set_attr "mode" "SI")])
5823 ;; Convert lea to the lea pattern to avoid flags dependency.
5825 [(set (match_operand:DI 0 "register_operand" "")
5827 (plus:SI (match_operand:SI 1 "register_operand" "")
5828 (match_operand:SI 2 "nonmemory_operand" ""))))
5829 (clobber (reg:CC FLAGS_REG))]
5830 "TARGET_64BIT && reload_completed
5831 && true_regnum (operands[0]) != true_regnum (operands[1])"
5833 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5835 operands[1] = gen_lowpart (Pmode, operands[1]);
5836 operands[2] = gen_lowpart (Pmode, operands[2]);
5839 (define_insn "*addsi_2"
5840 [(set (reg FLAGS_REG)
5842 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5843 (match_operand:SI 2 "general_operand" "rmni,rni"))
5845 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5846 (plus:SI (match_dup 1) (match_dup 2)))]
5847 "ix86_match_ccmode (insn, CCGOCmode)
5848 && ix86_binary_operator_ok (PLUS, SImode, operands)
5849 /* Current assemblers are broken and do not allow @GOTOFF in
5850 ought but a memory context. */
5851 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5853 switch (get_attr_type (insn))
5856 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5857 if (operands[2] == const1_rtx)
5858 return "inc{l}\t%0";
5861 gcc_assert (operands[2] == constm1_rtx);
5862 return "dec{l}\t%0";
5866 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5867 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5868 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5869 if (CONST_INT_P (operands[2])
5870 && (INTVAL (operands[2]) == 128
5871 || (INTVAL (operands[2]) < 0
5872 && INTVAL (operands[2]) != -128)))
5874 operands[2] = GEN_INT (-INTVAL (operands[2]));
5875 return "sub{l}\t{%2, %0|%0, %2}";
5877 return "add{l}\t{%2, %0|%0, %2}";
5881 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5882 (const_string "incdec")
5883 (const_string "alu")))
5884 (set_attr "mode" "SI")])
5886 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5887 (define_insn "*addsi_2_zext"
5888 [(set (reg FLAGS_REG)
5890 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5891 (match_operand:SI 2 "general_operand" "rmni"))
5893 (set (match_operand:DI 0 "register_operand" "=r")
5894 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5895 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5896 && ix86_binary_operator_ok (PLUS, SImode, operands)
5897 /* Current assemblers are broken and do not allow @GOTOFF in
5898 ought but a memory context. */
5899 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5901 switch (get_attr_type (insn))
5904 if (operands[2] == const1_rtx)
5905 return "inc{l}\t%k0";
5908 gcc_assert (operands[2] == constm1_rtx);
5909 return "dec{l}\t%k0";
5913 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5914 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5915 if (CONST_INT_P (operands[2])
5916 && (INTVAL (operands[2]) == 128
5917 || (INTVAL (operands[2]) < 0
5918 && INTVAL (operands[2]) != -128)))
5920 operands[2] = GEN_INT (-INTVAL (operands[2]));
5921 return "sub{l}\t{%2, %k0|%k0, %2}";
5923 return "add{l}\t{%2, %k0|%k0, %2}";
5927 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5928 (const_string "incdec")
5929 (const_string "alu")))
5930 (set_attr "mode" "SI")])
5932 (define_insn "*addsi_3"
5933 [(set (reg FLAGS_REG)
5934 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5935 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5936 (clobber (match_scratch:SI 0 "=r"))]
5937 "ix86_match_ccmode (insn, CCZmode)
5938 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5939 /* Current assemblers are broken and do not allow @GOTOFF in
5940 ought but a memory context. */
5941 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5943 switch (get_attr_type (insn))
5946 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5947 if (operands[2] == const1_rtx)
5948 return "inc{l}\t%0";
5951 gcc_assert (operands[2] == constm1_rtx);
5952 return "dec{l}\t%0";
5956 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5957 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5958 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5959 if (CONST_INT_P (operands[2])
5960 && (INTVAL (operands[2]) == 128
5961 || (INTVAL (operands[2]) < 0
5962 && INTVAL (operands[2]) != -128)))
5964 operands[2] = GEN_INT (-INTVAL (operands[2]));
5965 return "sub{l}\t{%2, %0|%0, %2}";
5967 return "add{l}\t{%2, %0|%0, %2}";
5971 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5972 (const_string "incdec")
5973 (const_string "alu")))
5974 (set_attr "mode" "SI")])
5976 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5977 (define_insn "*addsi_3_zext"
5978 [(set (reg FLAGS_REG)
5979 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5980 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5981 (set (match_operand:DI 0 "register_operand" "=r")
5982 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5983 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5984 && ix86_binary_operator_ok (PLUS, SImode, operands)
5985 /* Current assemblers are broken and do not allow @GOTOFF in
5986 ought but a memory context. */
5987 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5989 switch (get_attr_type (insn))
5992 if (operands[2] == const1_rtx)
5993 return "inc{l}\t%k0";
5996 gcc_assert (operands[2] == constm1_rtx);
5997 return "dec{l}\t%k0";
6001 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6002 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6003 if (CONST_INT_P (operands[2])
6004 && (INTVAL (operands[2]) == 128
6005 || (INTVAL (operands[2]) < 0
6006 && INTVAL (operands[2]) != -128)))
6008 operands[2] = GEN_INT (-INTVAL (operands[2]));
6009 return "sub{l}\t{%2, %k0|%k0, %2}";
6011 return "add{l}\t{%2, %k0|%k0, %2}";
6015 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6016 (const_string "incdec")
6017 (const_string "alu")))
6018 (set_attr "mode" "SI")])
6020 ; For comparisons against 1, -1 and 128, we may generate better code
6021 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6022 ; is matched then. We can't accept general immediate, because for
6023 ; case of overflows, the result is messed up.
6024 ; This pattern also don't hold of 0x80000000, since the value overflows
6026 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6027 ; only for comparisons not depending on it.
6028 (define_insn "*addsi_4"
6029 [(set (reg FLAGS_REG)
6030 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6031 (match_operand:SI 2 "const_int_operand" "n")))
6032 (clobber (match_scratch:SI 0 "=rm"))]
6033 "ix86_match_ccmode (insn, CCGCmode)
6034 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6036 switch (get_attr_type (insn))
6039 if (operands[2] == constm1_rtx)
6040 return "inc{l}\t%0";
6043 gcc_assert (operands[2] == const1_rtx);
6044 return "dec{l}\t%0";
6048 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6049 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6050 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6051 if ((INTVAL (operands[2]) == -128
6052 || (INTVAL (operands[2]) > 0
6053 && INTVAL (operands[2]) != 128)))
6054 return "sub{l}\t{%2, %0|%0, %2}";
6055 operands[2] = GEN_INT (-INTVAL (operands[2]));
6056 return "add{l}\t{%2, %0|%0, %2}";
6060 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6061 (const_string "incdec")
6062 (const_string "alu")))
6063 (set_attr "mode" "SI")])
6065 (define_insn "*addsi_5"
6066 [(set (reg FLAGS_REG)
6068 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6069 (match_operand:SI 2 "general_operand" "rmni"))
6071 (clobber (match_scratch:SI 0 "=r"))]
6072 "ix86_match_ccmode (insn, CCGOCmode)
6073 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6074 /* Current assemblers are broken and do not allow @GOTOFF in
6075 ought but a memory context. */
6076 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6078 switch (get_attr_type (insn))
6081 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6082 if (operands[2] == const1_rtx)
6083 return "inc{l}\t%0";
6086 gcc_assert (operands[2] == constm1_rtx);
6087 return "dec{l}\t%0";
6091 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6092 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6093 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6094 if (CONST_INT_P (operands[2])
6095 && (INTVAL (operands[2]) == 128
6096 || (INTVAL (operands[2]) < 0
6097 && INTVAL (operands[2]) != -128)))
6099 operands[2] = GEN_INT (-INTVAL (operands[2]));
6100 return "sub{l}\t{%2, %0|%0, %2}";
6102 return "add{l}\t{%2, %0|%0, %2}";
6106 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6107 (const_string "incdec")
6108 (const_string "alu")))
6109 (set_attr "mode" "SI")])
6111 (define_expand "addhi3"
6112 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6113 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6114 (match_operand:HI 2 "general_operand" "")))
6115 (clobber (reg:CC FLAGS_REG))])]
6116 "TARGET_HIMODE_MATH"
6117 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6119 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6120 ;; type optimizations enabled by define-splits. This is not important
6121 ;; for PII, and in fact harmful because of partial register stalls.
6123 (define_insn "*addhi_1_lea"
6124 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6125 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6126 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6127 (clobber (reg:CC FLAGS_REG))]
6128 "!TARGET_PARTIAL_REG_STALL
6129 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6131 switch (get_attr_type (insn))
6136 if (operands[2] == const1_rtx)
6137 return "inc{w}\t%0";
6140 gcc_assert (operands[2] == constm1_rtx);
6141 return "dec{w}\t%0";
6145 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6146 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6147 if (CONST_INT_P (operands[2])
6148 && (INTVAL (operands[2]) == 128
6149 || (INTVAL (operands[2]) < 0
6150 && INTVAL (operands[2]) != -128)))
6152 operands[2] = GEN_INT (-INTVAL (operands[2]));
6153 return "sub{w}\t{%2, %0|%0, %2}";
6155 return "add{w}\t{%2, %0|%0, %2}";
6159 (if_then_else (eq_attr "alternative" "2")
6160 (const_string "lea")
6161 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6162 (const_string "incdec")
6163 (const_string "alu"))))
6164 (set_attr "mode" "HI,HI,SI")])
6166 (define_insn "*addhi_1"
6167 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6168 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6169 (match_operand:HI 2 "general_operand" "ri,rm")))
6170 (clobber (reg:CC FLAGS_REG))]
6171 "TARGET_PARTIAL_REG_STALL
6172 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6174 switch (get_attr_type (insn))
6177 if (operands[2] == const1_rtx)
6178 return "inc{w}\t%0";
6181 gcc_assert (operands[2] == constm1_rtx);
6182 return "dec{w}\t%0";
6186 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6187 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6188 if (CONST_INT_P (operands[2])
6189 && (INTVAL (operands[2]) == 128
6190 || (INTVAL (operands[2]) < 0
6191 && INTVAL (operands[2]) != -128)))
6193 operands[2] = GEN_INT (-INTVAL (operands[2]));
6194 return "sub{w}\t{%2, %0|%0, %2}";
6196 return "add{w}\t{%2, %0|%0, %2}";
6200 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6201 (const_string "incdec")
6202 (const_string "alu")))
6203 (set_attr "mode" "HI")])
6205 (define_insn "*addhi_2"
6206 [(set (reg FLAGS_REG)
6208 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6209 (match_operand:HI 2 "general_operand" "rmni,rni"))
6211 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6212 (plus:HI (match_dup 1) (match_dup 2)))]
6213 "ix86_match_ccmode (insn, CCGOCmode)
6214 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6216 switch (get_attr_type (insn))
6219 if (operands[2] == const1_rtx)
6220 return "inc{w}\t%0";
6223 gcc_assert (operands[2] == constm1_rtx);
6224 return "dec{w}\t%0";
6228 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6229 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6230 if (CONST_INT_P (operands[2])
6231 && (INTVAL (operands[2]) == 128
6232 || (INTVAL (operands[2]) < 0
6233 && INTVAL (operands[2]) != -128)))
6235 operands[2] = GEN_INT (-INTVAL (operands[2]));
6236 return "sub{w}\t{%2, %0|%0, %2}";
6238 return "add{w}\t{%2, %0|%0, %2}";
6242 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6243 (const_string "incdec")
6244 (const_string "alu")))
6245 (set_attr "mode" "HI")])
6247 (define_insn "*addhi_3"
6248 [(set (reg FLAGS_REG)
6249 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6250 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6251 (clobber (match_scratch:HI 0 "=r"))]
6252 "ix86_match_ccmode (insn, CCZmode)
6253 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6255 switch (get_attr_type (insn))
6258 if (operands[2] == const1_rtx)
6259 return "inc{w}\t%0";
6262 gcc_assert (operands[2] == constm1_rtx);
6263 return "dec{w}\t%0";
6267 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6268 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6269 if (CONST_INT_P (operands[2])
6270 && (INTVAL (operands[2]) == 128
6271 || (INTVAL (operands[2]) < 0
6272 && INTVAL (operands[2]) != -128)))
6274 operands[2] = GEN_INT (-INTVAL (operands[2]));
6275 return "sub{w}\t{%2, %0|%0, %2}";
6277 return "add{w}\t{%2, %0|%0, %2}";
6281 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6282 (const_string "incdec")
6283 (const_string "alu")))
6284 (set_attr "mode" "HI")])
6286 ; See comments above addsi_4 for details.
6287 (define_insn "*addhi_4"
6288 [(set (reg FLAGS_REG)
6289 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6290 (match_operand:HI 2 "const_int_operand" "n")))
6291 (clobber (match_scratch:HI 0 "=rm"))]
6292 "ix86_match_ccmode (insn, CCGCmode)
6293 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6295 switch (get_attr_type (insn))
6298 if (operands[2] == constm1_rtx)
6299 return "inc{w}\t%0";
6302 gcc_assert (operands[2] == const1_rtx);
6303 return "dec{w}\t%0";
6307 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6308 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6309 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6310 if ((INTVAL (operands[2]) == -128
6311 || (INTVAL (operands[2]) > 0
6312 && INTVAL (operands[2]) != 128)))
6313 return "sub{w}\t{%2, %0|%0, %2}";
6314 operands[2] = GEN_INT (-INTVAL (operands[2]));
6315 return "add{w}\t{%2, %0|%0, %2}";
6319 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6320 (const_string "incdec")
6321 (const_string "alu")))
6322 (set_attr "mode" "SI")])
6325 (define_insn "*addhi_5"
6326 [(set (reg FLAGS_REG)
6328 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6329 (match_operand:HI 2 "general_operand" "rmni"))
6331 (clobber (match_scratch:HI 0 "=r"))]
6332 "ix86_match_ccmode (insn, CCGOCmode)
6333 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6335 switch (get_attr_type (insn))
6338 if (operands[2] == const1_rtx)
6339 return "inc{w}\t%0";
6342 gcc_assert (operands[2] == constm1_rtx);
6343 return "dec{w}\t%0";
6347 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6348 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6349 if (CONST_INT_P (operands[2])
6350 && (INTVAL (operands[2]) == 128
6351 || (INTVAL (operands[2]) < 0
6352 && INTVAL (operands[2]) != -128)))
6354 operands[2] = GEN_INT (-INTVAL (operands[2]));
6355 return "sub{w}\t{%2, %0|%0, %2}";
6357 return "add{w}\t{%2, %0|%0, %2}";
6361 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6362 (const_string "incdec")
6363 (const_string "alu")))
6364 (set_attr "mode" "HI")])
6366 (define_expand "addqi3"
6367 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6368 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6369 (match_operand:QI 2 "general_operand" "")))
6370 (clobber (reg:CC FLAGS_REG))])]
6371 "TARGET_QIMODE_MATH"
6372 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6374 ;; %%% Potential partial reg stall on alternative 2. What to do?
6375 (define_insn "*addqi_1_lea"
6376 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6377 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6378 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6379 (clobber (reg:CC FLAGS_REG))]
6380 "!TARGET_PARTIAL_REG_STALL
6381 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6383 int widen = (which_alternative == 2);
6384 switch (get_attr_type (insn))
6389 if (operands[2] == const1_rtx)
6390 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6393 gcc_assert (operands[2] == constm1_rtx);
6394 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6398 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6399 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6400 if (CONST_INT_P (operands[2])
6401 && (INTVAL (operands[2]) == 128
6402 || (INTVAL (operands[2]) < 0
6403 && INTVAL (operands[2]) != -128)))
6405 operands[2] = GEN_INT (-INTVAL (operands[2]));
6407 return "sub{l}\t{%2, %k0|%k0, %2}";
6409 return "sub{b}\t{%2, %0|%0, %2}";
6412 return "add{l}\t{%k2, %k0|%k0, %k2}";
6414 return "add{b}\t{%2, %0|%0, %2}";
6418 (if_then_else (eq_attr "alternative" "3")
6419 (const_string "lea")
6420 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6421 (const_string "incdec")
6422 (const_string "alu"))))
6423 (set_attr "mode" "QI,QI,SI,SI")])
6425 (define_insn "*addqi_1"
6426 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6427 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6428 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6429 (clobber (reg:CC FLAGS_REG))]
6430 "TARGET_PARTIAL_REG_STALL
6431 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6433 int widen = (which_alternative == 2);
6434 switch (get_attr_type (insn))
6437 if (operands[2] == const1_rtx)
6438 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6441 gcc_assert (operands[2] == constm1_rtx);
6442 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6446 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6447 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6448 if (CONST_INT_P (operands[2])
6449 && (INTVAL (operands[2]) == 128
6450 || (INTVAL (operands[2]) < 0
6451 && INTVAL (operands[2]) != -128)))
6453 operands[2] = GEN_INT (-INTVAL (operands[2]));
6455 return "sub{l}\t{%2, %k0|%k0, %2}";
6457 return "sub{b}\t{%2, %0|%0, %2}";
6460 return "add{l}\t{%k2, %k0|%k0, %k2}";
6462 return "add{b}\t{%2, %0|%0, %2}";
6466 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6467 (const_string "incdec")
6468 (const_string "alu")))
6469 (set_attr "mode" "QI,QI,SI")])
6471 (define_insn "*addqi_1_slp"
6472 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6473 (plus:QI (match_dup 0)
6474 (match_operand:QI 1 "general_operand" "qn,qnm")))
6475 (clobber (reg:CC FLAGS_REG))]
6476 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6477 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6479 switch (get_attr_type (insn))
6482 if (operands[1] == const1_rtx)
6483 return "inc{b}\t%0";
6486 gcc_assert (operands[1] == constm1_rtx);
6487 return "dec{b}\t%0";
6491 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6492 if (CONST_INT_P (operands[1])
6493 && INTVAL (operands[1]) < 0)
6495 operands[1] = GEN_INT (-INTVAL (operands[1]));
6496 return "sub{b}\t{%1, %0|%0, %1}";
6498 return "add{b}\t{%1, %0|%0, %1}";
6502 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6503 (const_string "incdec")
6504 (const_string "alu1")))
6505 (set (attr "memory")
6506 (if_then_else (match_operand 1 "memory_operand" "")
6507 (const_string "load")
6508 (const_string "none")))
6509 (set_attr "mode" "QI")])
6511 (define_insn "*addqi_2"
6512 [(set (reg FLAGS_REG)
6514 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6515 (match_operand:QI 2 "general_operand" "qmni,qni"))
6517 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6518 (plus:QI (match_dup 1) (match_dup 2)))]
6519 "ix86_match_ccmode (insn, CCGOCmode)
6520 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6522 switch (get_attr_type (insn))
6525 if (operands[2] == const1_rtx)
6526 return "inc{b}\t%0";
6529 gcc_assert (operands[2] == constm1_rtx
6530 || (CONST_INT_P (operands[2])
6531 && INTVAL (operands[2]) == 255));
6532 return "dec{b}\t%0";
6536 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6537 if (CONST_INT_P (operands[2])
6538 && INTVAL (operands[2]) < 0)
6540 operands[2] = GEN_INT (-INTVAL (operands[2]));
6541 return "sub{b}\t{%2, %0|%0, %2}";
6543 return "add{b}\t{%2, %0|%0, %2}";
6547 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6548 (const_string "incdec")
6549 (const_string "alu")))
6550 (set_attr "mode" "QI")])
6552 (define_insn "*addqi_3"
6553 [(set (reg FLAGS_REG)
6554 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6555 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6556 (clobber (match_scratch:QI 0 "=q"))]
6557 "ix86_match_ccmode (insn, CCZmode)
6558 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6560 switch (get_attr_type (insn))
6563 if (operands[2] == const1_rtx)
6564 return "inc{b}\t%0";
6567 gcc_assert (operands[2] == constm1_rtx
6568 || (CONST_INT_P (operands[2])
6569 && INTVAL (operands[2]) == 255));
6570 return "dec{b}\t%0";
6574 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6575 if (CONST_INT_P (operands[2])
6576 && INTVAL (operands[2]) < 0)
6578 operands[2] = GEN_INT (-INTVAL (operands[2]));
6579 return "sub{b}\t{%2, %0|%0, %2}";
6581 return "add{b}\t{%2, %0|%0, %2}";
6585 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6586 (const_string "incdec")
6587 (const_string "alu")))
6588 (set_attr "mode" "QI")])
6590 ; See comments above addsi_4 for details.
6591 (define_insn "*addqi_4"
6592 [(set (reg FLAGS_REG)
6593 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6594 (match_operand:QI 2 "const_int_operand" "n")))
6595 (clobber (match_scratch:QI 0 "=qm"))]
6596 "ix86_match_ccmode (insn, CCGCmode)
6597 && (INTVAL (operands[2]) & 0xff) != 0x80"
6599 switch (get_attr_type (insn))
6602 if (operands[2] == constm1_rtx
6603 || (CONST_INT_P (operands[2])
6604 && INTVAL (operands[2]) == 255))
6605 return "inc{b}\t%0";
6608 gcc_assert (operands[2] == const1_rtx);
6609 return "dec{b}\t%0";
6613 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6614 if (INTVAL (operands[2]) < 0)
6616 operands[2] = GEN_INT (-INTVAL (operands[2]));
6617 return "add{b}\t{%2, %0|%0, %2}";
6619 return "sub{b}\t{%2, %0|%0, %2}";
6623 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6624 (const_string "incdec")
6625 (const_string "alu")))
6626 (set_attr "mode" "QI")])
6629 (define_insn "*addqi_5"
6630 [(set (reg FLAGS_REG)
6632 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6633 (match_operand:QI 2 "general_operand" "qmni"))
6635 (clobber (match_scratch:QI 0 "=q"))]
6636 "ix86_match_ccmode (insn, CCGOCmode)
6637 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6639 switch (get_attr_type (insn))
6642 if (operands[2] == const1_rtx)
6643 return "inc{b}\t%0";
6646 gcc_assert (operands[2] == constm1_rtx
6647 || (CONST_INT_P (operands[2])
6648 && INTVAL (operands[2]) == 255));
6649 return "dec{b}\t%0";
6653 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6654 if (CONST_INT_P (operands[2])
6655 && INTVAL (operands[2]) < 0)
6657 operands[2] = GEN_INT (-INTVAL (operands[2]));
6658 return "sub{b}\t{%2, %0|%0, %2}";
6660 return "add{b}\t{%2, %0|%0, %2}";
6664 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6665 (const_string "incdec")
6666 (const_string "alu")))
6667 (set_attr "mode" "QI")])
6670 (define_insn "addqi_ext_1"
6671 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6676 (match_operand 1 "ext_register_operand" "0")
6679 (match_operand:QI 2 "general_operand" "Qmn")))
6680 (clobber (reg:CC FLAGS_REG))]
6683 switch (get_attr_type (insn))
6686 if (operands[2] == const1_rtx)
6687 return "inc{b}\t%h0";
6690 gcc_assert (operands[2] == constm1_rtx
6691 || (CONST_INT_P (operands[2])
6692 && INTVAL (operands[2]) == 255));
6693 return "dec{b}\t%h0";
6697 return "add{b}\t{%2, %h0|%h0, %2}";
6701 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6702 (const_string "incdec")
6703 (const_string "alu")))
6704 (set_attr "mode" "QI")])
6706 (define_insn "*addqi_ext_1_rex64"
6707 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6712 (match_operand 1 "ext_register_operand" "0")
6715 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6716 (clobber (reg:CC FLAGS_REG))]
6719 switch (get_attr_type (insn))
6722 if (operands[2] == const1_rtx)
6723 return "inc{b}\t%h0";
6726 gcc_assert (operands[2] == constm1_rtx
6727 || (CONST_INT_P (operands[2])
6728 && INTVAL (operands[2]) == 255));
6729 return "dec{b}\t%h0";
6733 return "add{b}\t{%2, %h0|%h0, %2}";
6737 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6738 (const_string "incdec")
6739 (const_string "alu")))
6740 (set_attr "mode" "QI")])
6742 (define_insn "*addqi_ext_2"
6743 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6748 (match_operand 1 "ext_register_operand" "%0")
6752 (match_operand 2 "ext_register_operand" "Q")
6755 (clobber (reg:CC FLAGS_REG))]
6757 "add{b}\t{%h2, %h0|%h0, %h2}"
6758 [(set_attr "type" "alu")
6759 (set_attr "mode" "QI")])
6761 ;; The patterns that match these are at the end of this file.
6763 (define_expand "addxf3"
6764 [(set (match_operand:XF 0 "register_operand" "")
6765 (plus:XF (match_operand:XF 1 "register_operand" "")
6766 (match_operand:XF 2 "register_operand" "")))]
6770 (define_expand "adddf3"
6771 [(set (match_operand:DF 0 "register_operand" "")
6772 (plus:DF (match_operand:DF 1 "register_operand" "")
6773 (match_operand:DF 2 "nonimmediate_operand" "")))]
6774 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6777 (define_expand "addsf3"
6778 [(set (match_operand:SF 0 "register_operand" "")
6779 (plus:SF (match_operand:SF 1 "register_operand" "")
6780 (match_operand:SF 2 "nonimmediate_operand" "")))]
6781 "TARGET_80387 || TARGET_SSE_MATH"
6784 ;; Subtract instructions
6786 ;; %%% splits for subditi3
6788 (define_expand "subti3"
6789 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6790 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6791 (match_operand:TI 2 "x86_64_general_operand" "")))
6792 (clobber (reg:CC FLAGS_REG))])]
6794 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6796 (define_insn "*subti3_1"
6797 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6798 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6799 (match_operand:TI 2 "general_operand" "roiF,riF")))
6800 (clobber (reg:CC FLAGS_REG))]
6801 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6805 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6806 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6807 (match_operand:TI 2 "general_operand" "")))
6808 (clobber (reg:CC FLAGS_REG))]
6809 "TARGET_64BIT && reload_completed"
6810 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6811 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6812 (parallel [(set (match_dup 3)
6813 (minus:DI (match_dup 4)
6814 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6816 (clobber (reg:CC FLAGS_REG))])]
6817 "split_ti (operands+0, 1, operands+0, operands+3);
6818 split_ti (operands+1, 1, operands+1, operands+4);
6819 split_ti (operands+2, 1, operands+2, operands+5);")
6821 ;; %%% splits for subsidi3
6823 (define_expand "subdi3"
6824 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6825 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6826 (match_operand:DI 2 "x86_64_general_operand" "")))
6827 (clobber (reg:CC FLAGS_REG))])]
6829 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6831 (define_insn "*subdi3_1"
6832 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6833 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6834 (match_operand:DI 2 "general_operand" "roiF,riF")))
6835 (clobber (reg:CC FLAGS_REG))]
6836 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6840 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6841 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6842 (match_operand:DI 2 "general_operand" "")))
6843 (clobber (reg:CC FLAGS_REG))]
6844 "!TARGET_64BIT && reload_completed"
6845 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6846 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6847 (parallel [(set (match_dup 3)
6848 (minus:SI (match_dup 4)
6849 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6851 (clobber (reg:CC FLAGS_REG))])]
6852 "split_di (operands+0, 1, operands+0, operands+3);
6853 split_di (operands+1, 1, operands+1, operands+4);
6854 split_di (operands+2, 1, operands+2, operands+5);")
6856 (define_insn "subdi3_carry_rex64"
6857 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6858 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6859 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6860 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6861 (clobber (reg:CC FLAGS_REG))]
6862 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6863 "sbb{q}\t{%2, %0|%0, %2}"
6864 [(set_attr "type" "alu")
6865 (set_attr "pent_pair" "pu")
6866 (set_attr "mode" "DI")])
6868 (define_insn "*subdi_1_rex64"
6869 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6870 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6871 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6872 (clobber (reg:CC FLAGS_REG))]
6873 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6874 "sub{q}\t{%2, %0|%0, %2}"
6875 [(set_attr "type" "alu")
6876 (set_attr "mode" "DI")])
6878 (define_insn "*subdi_2_rex64"
6879 [(set (reg FLAGS_REG)
6881 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6882 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6884 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6885 (minus:DI (match_dup 1) (match_dup 2)))]
6886 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6887 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6888 "sub{q}\t{%2, %0|%0, %2}"
6889 [(set_attr "type" "alu")
6890 (set_attr "mode" "DI")])
6892 (define_insn "*subdi_3_rex63"
6893 [(set (reg FLAGS_REG)
6894 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6895 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6896 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6897 (minus:DI (match_dup 1) (match_dup 2)))]
6898 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6899 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6900 "sub{q}\t{%2, %0|%0, %2}"
6901 [(set_attr "type" "alu")
6902 (set_attr "mode" "DI")])
6904 (define_insn "subqi3_carry"
6905 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6906 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6907 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6908 (match_operand:QI 2 "general_operand" "qi,qm"))))
6909 (clobber (reg:CC FLAGS_REG))]
6910 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6911 "sbb{b}\t{%2, %0|%0, %2}"
6912 [(set_attr "type" "alu")
6913 (set_attr "pent_pair" "pu")
6914 (set_attr "mode" "QI")])
6916 (define_insn "subhi3_carry"
6917 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6918 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6919 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6920 (match_operand:HI 2 "general_operand" "ri,rm"))))
6921 (clobber (reg:CC FLAGS_REG))]
6922 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6923 "sbb{w}\t{%2, %0|%0, %2}"
6924 [(set_attr "type" "alu")
6925 (set_attr "pent_pair" "pu")
6926 (set_attr "mode" "HI")])
6928 (define_insn "subsi3_carry"
6929 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6930 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6931 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6932 (match_operand:SI 2 "general_operand" "ri,rm"))))
6933 (clobber (reg:CC FLAGS_REG))]
6934 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6935 "sbb{l}\t{%2, %0|%0, %2}"
6936 [(set_attr "type" "alu")
6937 (set_attr "pent_pair" "pu")
6938 (set_attr "mode" "SI")])
6940 (define_insn "subsi3_carry_zext"
6941 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6943 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6944 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6945 (match_operand:SI 2 "general_operand" "ri,rm")))))
6946 (clobber (reg:CC FLAGS_REG))]
6947 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6948 "sbb{l}\t{%2, %k0|%k0, %2}"
6949 [(set_attr "type" "alu")
6950 (set_attr "pent_pair" "pu")
6951 (set_attr "mode" "SI")])
6953 (define_expand "subsi3"
6954 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6955 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6956 (match_operand:SI 2 "general_operand" "")))
6957 (clobber (reg:CC FLAGS_REG))])]
6959 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6961 (define_insn "*subsi_1"
6962 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6963 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6964 (match_operand:SI 2 "general_operand" "ri,rm")))
6965 (clobber (reg:CC FLAGS_REG))]
6966 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6967 "sub{l}\t{%2, %0|%0, %2}"
6968 [(set_attr "type" "alu")
6969 (set_attr "mode" "SI")])
6971 (define_insn "*subsi_1_zext"
6972 [(set (match_operand:DI 0 "register_operand" "=r")
6974 (minus:SI (match_operand:SI 1 "register_operand" "0")
6975 (match_operand:SI 2 "general_operand" "rim"))))
6976 (clobber (reg:CC FLAGS_REG))]
6977 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6978 "sub{l}\t{%2, %k0|%k0, %2}"
6979 [(set_attr "type" "alu")
6980 (set_attr "mode" "SI")])
6982 (define_insn "*subsi_2"
6983 [(set (reg FLAGS_REG)
6985 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6986 (match_operand:SI 2 "general_operand" "ri,rm"))
6988 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6989 (minus:SI (match_dup 1) (match_dup 2)))]
6990 "ix86_match_ccmode (insn, CCGOCmode)
6991 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6992 "sub{l}\t{%2, %0|%0, %2}"
6993 [(set_attr "type" "alu")
6994 (set_attr "mode" "SI")])
6996 (define_insn "*subsi_2_zext"
6997 [(set (reg FLAGS_REG)
6999 (minus:SI (match_operand:SI 1 "register_operand" "0")
7000 (match_operand:SI 2 "general_operand" "rim"))
7002 (set (match_operand:DI 0 "register_operand" "=r")
7004 (minus:SI (match_dup 1)
7006 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7007 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7008 "sub{l}\t{%2, %k0|%k0, %2}"
7009 [(set_attr "type" "alu")
7010 (set_attr "mode" "SI")])
7012 (define_insn "*subsi_3"
7013 [(set (reg FLAGS_REG)
7014 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7015 (match_operand:SI 2 "general_operand" "ri,rm")))
7016 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7017 (minus:SI (match_dup 1) (match_dup 2)))]
7018 "ix86_match_ccmode (insn, CCmode)
7019 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7020 "sub{l}\t{%2, %0|%0, %2}"
7021 [(set_attr "type" "alu")
7022 (set_attr "mode" "SI")])
7024 (define_insn "*subsi_3_zext"
7025 [(set (reg FLAGS_REG)
7026 (compare (match_operand:SI 1 "register_operand" "0")
7027 (match_operand:SI 2 "general_operand" "rim")))
7028 (set (match_operand:DI 0 "register_operand" "=r")
7030 (minus:SI (match_dup 1)
7032 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7033 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7034 "sub{l}\t{%2, %1|%1, %2}"
7035 [(set_attr "type" "alu")
7036 (set_attr "mode" "DI")])
7038 (define_expand "subhi3"
7039 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7040 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7041 (match_operand:HI 2 "general_operand" "")))
7042 (clobber (reg:CC FLAGS_REG))])]
7043 "TARGET_HIMODE_MATH"
7044 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7046 (define_insn "*subhi_1"
7047 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7048 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7049 (match_operand:HI 2 "general_operand" "ri,rm")))
7050 (clobber (reg:CC FLAGS_REG))]
7051 "ix86_binary_operator_ok (MINUS, HImode, operands)"
7052 "sub{w}\t{%2, %0|%0, %2}"
7053 [(set_attr "type" "alu")
7054 (set_attr "mode" "HI")])
7056 (define_insn "*subhi_2"
7057 [(set (reg FLAGS_REG)
7059 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7060 (match_operand:HI 2 "general_operand" "ri,rm"))
7062 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7063 (minus:HI (match_dup 1) (match_dup 2)))]
7064 "ix86_match_ccmode (insn, CCGOCmode)
7065 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7066 "sub{w}\t{%2, %0|%0, %2}"
7067 [(set_attr "type" "alu")
7068 (set_attr "mode" "HI")])
7070 (define_insn "*subhi_3"
7071 [(set (reg FLAGS_REG)
7072 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7073 (match_operand:HI 2 "general_operand" "ri,rm")))
7074 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7075 (minus:HI (match_dup 1) (match_dup 2)))]
7076 "ix86_match_ccmode (insn, CCmode)
7077 && ix86_binary_operator_ok (MINUS, HImode, operands)"
7078 "sub{w}\t{%2, %0|%0, %2}"
7079 [(set_attr "type" "alu")
7080 (set_attr "mode" "HI")])
7082 (define_expand "subqi3"
7083 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7084 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7085 (match_operand:QI 2 "general_operand" "")))
7086 (clobber (reg:CC FLAGS_REG))])]
7087 "TARGET_QIMODE_MATH"
7088 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7090 (define_insn "*subqi_1"
7091 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7092 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7093 (match_operand:QI 2 "general_operand" "qn,qmn")))
7094 (clobber (reg:CC FLAGS_REG))]
7095 "ix86_binary_operator_ok (MINUS, QImode, operands)"
7096 "sub{b}\t{%2, %0|%0, %2}"
7097 [(set_attr "type" "alu")
7098 (set_attr "mode" "QI")])
7100 (define_insn "*subqi_1_slp"
7101 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7102 (minus:QI (match_dup 0)
7103 (match_operand:QI 1 "general_operand" "qn,qmn")))
7104 (clobber (reg:CC FLAGS_REG))]
7105 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7106 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7107 "sub{b}\t{%1, %0|%0, %1}"
7108 [(set_attr "type" "alu1")
7109 (set_attr "mode" "QI")])
7111 (define_insn "*subqi_2"
7112 [(set (reg FLAGS_REG)
7114 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7115 (match_operand:QI 2 "general_operand" "qi,qm"))
7117 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7118 (minus:HI (match_dup 1) (match_dup 2)))]
7119 "ix86_match_ccmode (insn, CCGOCmode)
7120 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7121 "sub{b}\t{%2, %0|%0, %2}"
7122 [(set_attr "type" "alu")
7123 (set_attr "mode" "QI")])
7125 (define_insn "*subqi_3"
7126 [(set (reg FLAGS_REG)
7127 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7128 (match_operand:QI 2 "general_operand" "qi,qm")))
7129 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7130 (minus:HI (match_dup 1) (match_dup 2)))]
7131 "ix86_match_ccmode (insn, CCmode)
7132 && ix86_binary_operator_ok (MINUS, QImode, operands)"
7133 "sub{b}\t{%2, %0|%0, %2}"
7134 [(set_attr "type" "alu")
7135 (set_attr "mode" "QI")])
7137 ;; The patterns that match these are at the end of this file.
7139 (define_expand "subxf3"
7140 [(set (match_operand:XF 0 "register_operand" "")
7141 (minus:XF (match_operand:XF 1 "register_operand" "")
7142 (match_operand:XF 2 "register_operand" "")))]
7146 (define_expand "subdf3"
7147 [(set (match_operand:DF 0 "register_operand" "")
7148 (minus:DF (match_operand:DF 1 "register_operand" "")
7149 (match_operand:DF 2 "nonimmediate_operand" "")))]
7150 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7153 (define_expand "subsf3"
7154 [(set (match_operand:SF 0 "register_operand" "")
7155 (minus:SF (match_operand:SF 1 "register_operand" "")
7156 (match_operand:SF 2 "nonimmediate_operand" "")))]
7157 "TARGET_80387 || TARGET_SSE_MATH"
7160 ;; Multiply instructions
7162 (define_expand "muldi3"
7163 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7164 (mult:DI (match_operand:DI 1 "register_operand" "")
7165 (match_operand:DI 2 "x86_64_general_operand" "")))
7166 (clobber (reg:CC FLAGS_REG))])]
7171 ;; IMUL reg64, reg64, imm8 Direct
7172 ;; IMUL reg64, mem64, imm8 VectorPath
7173 ;; IMUL reg64, reg64, imm32 Direct
7174 ;; IMUL reg64, mem64, imm32 VectorPath
7175 ;; IMUL reg64, reg64 Direct
7176 ;; IMUL reg64, mem64 Direct
7178 (define_insn "*muldi3_1_rex64"
7179 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7180 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7181 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7182 (clobber (reg:CC FLAGS_REG))]
7184 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7186 imul{q}\t{%2, %1, %0|%0, %1, %2}
7187 imul{q}\t{%2, %1, %0|%0, %1, %2}
7188 imul{q}\t{%2, %0|%0, %2}"
7189 [(set_attr "type" "imul")
7190 (set_attr "prefix_0f" "0,0,1")
7191 (set (attr "athlon_decode")
7192 (cond [(eq_attr "cpu" "athlon")
7193 (const_string "vector")
7194 (eq_attr "alternative" "1")
7195 (const_string "vector")
7196 (and (eq_attr "alternative" "2")
7197 (match_operand 1 "memory_operand" ""))
7198 (const_string "vector")]
7199 (const_string "direct")))
7200 (set (attr "amdfam10_decode")
7201 (cond [(and (eq_attr "alternative" "0,1")
7202 (match_operand 1 "memory_operand" ""))
7203 (const_string "vector")]
7204 (const_string "direct")))
7205 (set_attr "mode" "DI")])
7207 (define_expand "mulsi3"
7208 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7209 (mult:SI (match_operand:SI 1 "register_operand" "")
7210 (match_operand:SI 2 "general_operand" "")))
7211 (clobber (reg:CC FLAGS_REG))])]
7216 ;; IMUL reg32, reg32, imm8 Direct
7217 ;; IMUL reg32, mem32, imm8 VectorPath
7218 ;; IMUL reg32, reg32, imm32 Direct
7219 ;; IMUL reg32, mem32, imm32 VectorPath
7220 ;; IMUL reg32, reg32 Direct
7221 ;; IMUL reg32, mem32 Direct
7223 (define_insn "*mulsi3_1"
7224 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7225 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7226 (match_operand:SI 2 "general_operand" "K,i,mr")))
7227 (clobber (reg:CC FLAGS_REG))]
7228 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7230 imul{l}\t{%2, %1, %0|%0, %1, %2}
7231 imul{l}\t{%2, %1, %0|%0, %1, %2}
7232 imul{l}\t{%2, %0|%0, %2}"
7233 [(set_attr "type" "imul")
7234 (set_attr "prefix_0f" "0,0,1")
7235 (set (attr "athlon_decode")
7236 (cond [(eq_attr "cpu" "athlon")
7237 (const_string "vector")
7238 (eq_attr "alternative" "1")
7239 (const_string "vector")
7240 (and (eq_attr "alternative" "2")
7241 (match_operand 1 "memory_operand" ""))
7242 (const_string "vector")]
7243 (const_string "direct")))
7244 (set (attr "amdfam10_decode")
7245 (cond [(and (eq_attr "alternative" "0,1")
7246 (match_operand 1 "memory_operand" ""))
7247 (const_string "vector")]
7248 (const_string "direct")))
7249 (set_attr "mode" "SI")])
7251 (define_insn "*mulsi3_1_zext"
7252 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7254 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7255 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7256 (clobber (reg:CC FLAGS_REG))]
7258 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7260 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7261 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7262 imul{l}\t{%2, %k0|%k0, %2}"
7263 [(set_attr "type" "imul")
7264 (set_attr "prefix_0f" "0,0,1")
7265 (set (attr "athlon_decode")
7266 (cond [(eq_attr "cpu" "athlon")
7267 (const_string "vector")
7268 (eq_attr "alternative" "1")
7269 (const_string "vector")
7270 (and (eq_attr "alternative" "2")
7271 (match_operand 1 "memory_operand" ""))
7272 (const_string "vector")]
7273 (const_string "direct")))
7274 (set (attr "amdfam10_decode")
7275 (cond [(and (eq_attr "alternative" "0,1")
7276 (match_operand 1 "memory_operand" ""))
7277 (const_string "vector")]
7278 (const_string "direct")))
7279 (set_attr "mode" "SI")])
7281 (define_expand "mulhi3"
7282 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7283 (mult:HI (match_operand:HI 1 "register_operand" "")
7284 (match_operand:HI 2 "general_operand" "")))
7285 (clobber (reg:CC FLAGS_REG))])]
7286 "TARGET_HIMODE_MATH"
7290 ;; IMUL reg16, reg16, imm8 VectorPath
7291 ;; IMUL reg16, mem16, imm8 VectorPath
7292 ;; IMUL reg16, reg16, imm16 VectorPath
7293 ;; IMUL reg16, mem16, imm16 VectorPath
7294 ;; IMUL reg16, reg16 Direct
7295 ;; IMUL reg16, mem16 Direct
7296 (define_insn "*mulhi3_1"
7297 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7298 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7299 (match_operand:HI 2 "general_operand" "K,i,mr")))
7300 (clobber (reg:CC FLAGS_REG))]
7301 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7303 imul{w}\t{%2, %1, %0|%0, %1, %2}
7304 imul{w}\t{%2, %1, %0|%0, %1, %2}
7305 imul{w}\t{%2, %0|%0, %2}"
7306 [(set_attr "type" "imul")
7307 (set_attr "prefix_0f" "0,0,1")
7308 (set (attr "athlon_decode")
7309 (cond [(eq_attr "cpu" "athlon")
7310 (const_string "vector")
7311 (eq_attr "alternative" "1,2")
7312 (const_string "vector")]
7313 (const_string "direct")))
7314 (set (attr "amdfam10_decode")
7315 (cond [(eq_attr "alternative" "0,1")
7316 (const_string "vector")]
7317 (const_string "direct")))
7318 (set_attr "mode" "HI")])
7320 (define_expand "mulqi3"
7321 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7322 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7323 (match_operand:QI 2 "register_operand" "")))
7324 (clobber (reg:CC FLAGS_REG))])]
7325 "TARGET_QIMODE_MATH"
7332 (define_insn "*mulqi3_1"
7333 [(set (match_operand:QI 0 "register_operand" "=a")
7334 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7335 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7336 (clobber (reg:CC FLAGS_REG))]
7338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7340 [(set_attr "type" "imul")
7341 (set_attr "length_immediate" "0")
7342 (set (attr "athlon_decode")
7343 (if_then_else (eq_attr "cpu" "athlon")
7344 (const_string "vector")
7345 (const_string "direct")))
7346 (set_attr "amdfam10_decode" "direct")
7347 (set_attr "mode" "QI")])
7349 (define_expand "umulqihi3"
7350 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7351 (mult:HI (zero_extend:HI
7352 (match_operand:QI 1 "nonimmediate_operand" ""))
7354 (match_operand:QI 2 "register_operand" ""))))
7355 (clobber (reg:CC FLAGS_REG))])]
7356 "TARGET_QIMODE_MATH"
7359 (define_insn "*umulqihi3_1"
7360 [(set (match_operand:HI 0 "register_operand" "=a")
7361 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7362 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7363 (clobber (reg:CC FLAGS_REG))]
7365 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7367 [(set_attr "type" "imul")
7368 (set_attr "length_immediate" "0")
7369 (set (attr "athlon_decode")
7370 (if_then_else (eq_attr "cpu" "athlon")
7371 (const_string "vector")
7372 (const_string "direct")))
7373 (set_attr "amdfam10_decode" "direct")
7374 (set_attr "mode" "QI")])
7376 (define_expand "mulqihi3"
7377 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7378 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7379 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7380 (clobber (reg:CC FLAGS_REG))])]
7381 "TARGET_QIMODE_MATH"
7384 (define_insn "*mulqihi3_insn"
7385 [(set (match_operand:HI 0 "register_operand" "=a")
7386 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7387 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7388 (clobber (reg:CC FLAGS_REG))]
7390 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7392 [(set_attr "type" "imul")
7393 (set_attr "length_immediate" "0")
7394 (set (attr "athlon_decode")
7395 (if_then_else (eq_attr "cpu" "athlon")
7396 (const_string "vector")
7397 (const_string "direct")))
7398 (set_attr "amdfam10_decode" "direct")
7399 (set_attr "mode" "QI")])
7401 (define_expand "umulditi3"
7402 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7403 (mult:TI (zero_extend:TI
7404 (match_operand:DI 1 "nonimmediate_operand" ""))
7406 (match_operand:DI 2 "register_operand" ""))))
7407 (clobber (reg:CC FLAGS_REG))])]
7411 (define_insn "*umulditi3_insn"
7412 [(set (match_operand:TI 0 "register_operand" "=A")
7413 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7414 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7415 (clobber (reg:CC FLAGS_REG))]
7417 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7419 [(set_attr "type" "imul")
7420 (set_attr "length_immediate" "0")
7421 (set (attr "athlon_decode")
7422 (if_then_else (eq_attr "cpu" "athlon")
7423 (const_string "vector")
7424 (const_string "double")))
7425 (set_attr "amdfam10_decode" "double")
7426 (set_attr "mode" "DI")])
7428 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7429 (define_expand "umulsidi3"
7430 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7431 (mult:DI (zero_extend:DI
7432 (match_operand:SI 1 "nonimmediate_operand" ""))
7434 (match_operand:SI 2 "register_operand" ""))))
7435 (clobber (reg:CC FLAGS_REG))])]
7439 (define_insn "*umulsidi3_insn"
7440 [(set (match_operand:DI 0 "register_operand" "=A")
7441 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7442 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7443 (clobber (reg:CC FLAGS_REG))]
7445 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7447 [(set_attr "type" "imul")
7448 (set_attr "length_immediate" "0")
7449 (set (attr "athlon_decode")
7450 (if_then_else (eq_attr "cpu" "athlon")
7451 (const_string "vector")
7452 (const_string "double")))
7453 (set_attr "amdfam10_decode" "double")
7454 (set_attr "mode" "SI")])
7456 (define_expand "mulditi3"
7457 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7458 (mult:TI (sign_extend:TI
7459 (match_operand:DI 1 "nonimmediate_operand" ""))
7461 (match_operand:DI 2 "register_operand" ""))))
7462 (clobber (reg:CC FLAGS_REG))])]
7466 (define_insn "*mulditi3_insn"
7467 [(set (match_operand:TI 0 "register_operand" "=A")
7468 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7469 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7470 (clobber (reg:CC FLAGS_REG))]
7472 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7474 [(set_attr "type" "imul")
7475 (set_attr "length_immediate" "0")
7476 (set (attr "athlon_decode")
7477 (if_then_else (eq_attr "cpu" "athlon")
7478 (const_string "vector")
7479 (const_string "double")))
7480 (set_attr "amdfam10_decode" "double")
7481 (set_attr "mode" "DI")])
7483 (define_expand "mulsidi3"
7484 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7485 (mult:DI (sign_extend:DI
7486 (match_operand:SI 1 "nonimmediate_operand" ""))
7488 (match_operand:SI 2 "register_operand" ""))))
7489 (clobber (reg:CC FLAGS_REG))])]
7493 (define_insn "*mulsidi3_insn"
7494 [(set (match_operand:DI 0 "register_operand" "=A")
7495 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7496 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7497 (clobber (reg:CC FLAGS_REG))]
7499 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7501 [(set_attr "type" "imul")
7502 (set_attr "length_immediate" "0")
7503 (set (attr "athlon_decode")
7504 (if_then_else (eq_attr "cpu" "athlon")
7505 (const_string "vector")
7506 (const_string "double")))
7507 (set_attr "amdfam10_decode" "double")
7508 (set_attr "mode" "SI")])
7510 (define_expand "umuldi3_highpart"
7511 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7514 (mult:TI (zero_extend:TI
7515 (match_operand:DI 1 "nonimmediate_operand" ""))
7517 (match_operand:DI 2 "register_operand" "")))
7519 (clobber (match_scratch:DI 3 ""))
7520 (clobber (reg:CC FLAGS_REG))])]
7524 (define_insn "*umuldi3_highpart_rex64"
7525 [(set (match_operand:DI 0 "register_operand" "=d")
7528 (mult:TI (zero_extend:TI
7529 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7531 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7533 (clobber (match_scratch:DI 3 "=1"))
7534 (clobber (reg:CC FLAGS_REG))]
7536 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7538 [(set_attr "type" "imul")
7539 (set_attr "length_immediate" "0")
7540 (set (attr "athlon_decode")
7541 (if_then_else (eq_attr "cpu" "athlon")
7542 (const_string "vector")
7543 (const_string "double")))
7544 (set_attr "amdfam10_decode" "double")
7545 (set_attr "mode" "DI")])
7547 (define_expand "umulsi3_highpart"
7548 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7551 (mult:DI (zero_extend:DI
7552 (match_operand:SI 1 "nonimmediate_operand" ""))
7554 (match_operand:SI 2 "register_operand" "")))
7556 (clobber (match_scratch:SI 3 ""))
7557 (clobber (reg:CC FLAGS_REG))])]
7561 (define_insn "*umulsi3_highpart_insn"
7562 [(set (match_operand:SI 0 "register_operand" "=d")
7565 (mult:DI (zero_extend:DI
7566 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7568 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7570 (clobber (match_scratch:SI 3 "=1"))
7571 (clobber (reg:CC FLAGS_REG))]
7572 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7574 [(set_attr "type" "imul")
7575 (set_attr "length_immediate" "0")
7576 (set (attr "athlon_decode")
7577 (if_then_else (eq_attr "cpu" "athlon")
7578 (const_string "vector")
7579 (const_string "double")))
7580 (set_attr "amdfam10_decode" "double")
7581 (set_attr "mode" "SI")])
7583 (define_insn "*umulsi3_highpart_zext"
7584 [(set (match_operand:DI 0 "register_operand" "=d")
7585 (zero_extend:DI (truncate:SI
7587 (mult:DI (zero_extend:DI
7588 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7590 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7592 (clobber (match_scratch:SI 3 "=1"))
7593 (clobber (reg:CC FLAGS_REG))]
7595 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7597 [(set_attr "type" "imul")
7598 (set_attr "length_immediate" "0")
7599 (set (attr "athlon_decode")
7600 (if_then_else (eq_attr "cpu" "athlon")
7601 (const_string "vector")
7602 (const_string "double")))
7603 (set_attr "amdfam10_decode" "double")
7604 (set_attr "mode" "SI")])
7606 (define_expand "smuldi3_highpart"
7607 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7610 (mult:TI (sign_extend:TI
7611 (match_operand:DI 1 "nonimmediate_operand" ""))
7613 (match_operand:DI 2 "register_operand" "")))
7615 (clobber (match_scratch:DI 3 ""))
7616 (clobber (reg:CC FLAGS_REG))])]
7620 (define_insn "*smuldi3_highpart_rex64"
7621 [(set (match_operand:DI 0 "register_operand" "=d")
7624 (mult:TI (sign_extend:TI
7625 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7627 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7629 (clobber (match_scratch:DI 3 "=1"))
7630 (clobber (reg:CC FLAGS_REG))]
7632 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7634 [(set_attr "type" "imul")
7635 (set (attr "athlon_decode")
7636 (if_then_else (eq_attr "cpu" "athlon")
7637 (const_string "vector")
7638 (const_string "double")))
7639 (set_attr "amdfam10_decode" "double")
7640 (set_attr "mode" "DI")])
7642 (define_expand "smulsi3_highpart"
7643 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7646 (mult:DI (sign_extend:DI
7647 (match_operand:SI 1 "nonimmediate_operand" ""))
7649 (match_operand:SI 2 "register_operand" "")))
7651 (clobber (match_scratch:SI 3 ""))
7652 (clobber (reg:CC FLAGS_REG))])]
7656 (define_insn "*smulsi3_highpart_insn"
7657 [(set (match_operand:SI 0 "register_operand" "=d")
7660 (mult:DI (sign_extend:DI
7661 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7663 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7665 (clobber (match_scratch:SI 3 "=1"))
7666 (clobber (reg:CC FLAGS_REG))]
7667 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7669 [(set_attr "type" "imul")
7670 (set (attr "athlon_decode")
7671 (if_then_else (eq_attr "cpu" "athlon")
7672 (const_string "vector")
7673 (const_string "double")))
7674 (set_attr "amdfam10_decode" "double")
7675 (set_attr "mode" "SI")])
7677 (define_insn "*smulsi3_highpart_zext"
7678 [(set (match_operand:DI 0 "register_operand" "=d")
7679 (zero_extend:DI (truncate:SI
7681 (mult:DI (sign_extend:DI
7682 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7684 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7686 (clobber (match_scratch:SI 3 "=1"))
7687 (clobber (reg:CC FLAGS_REG))]
7689 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7691 [(set_attr "type" "imul")
7692 (set (attr "athlon_decode")
7693 (if_then_else (eq_attr "cpu" "athlon")
7694 (const_string "vector")
7695 (const_string "double")))
7696 (set_attr "amdfam10_decode" "double")
7697 (set_attr "mode" "SI")])
7699 ;; The patterns that match these are at the end of this file.
7701 (define_expand "mulxf3"
7702 [(set (match_operand:XF 0 "register_operand" "")
7703 (mult:XF (match_operand:XF 1 "register_operand" "")
7704 (match_operand:XF 2 "register_operand" "")))]
7708 (define_expand "muldf3"
7709 [(set (match_operand:DF 0 "register_operand" "")
7710 (mult:DF (match_operand:DF 1 "register_operand" "")
7711 (match_operand:DF 2 "nonimmediate_operand" "")))]
7712 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7715 (define_expand "mulsf3"
7716 [(set (match_operand:SF 0 "register_operand" "")
7717 (mult:SF (match_operand:SF 1 "register_operand" "")
7718 (match_operand:SF 2 "nonimmediate_operand" "")))]
7719 "TARGET_80387 || TARGET_SSE_MATH"
7722 ;; Divide instructions
7724 (define_insn "divqi3"
7725 [(set (match_operand:QI 0 "register_operand" "=a")
7726 (div:QI (match_operand:HI 1 "register_operand" "0")
7727 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7728 (clobber (reg:CC FLAGS_REG))]
7729 "TARGET_QIMODE_MATH"
7731 [(set_attr "type" "idiv")
7732 (set_attr "mode" "QI")])
7734 (define_insn "udivqi3"
7735 [(set (match_operand:QI 0 "register_operand" "=a")
7736 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7737 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7738 (clobber (reg:CC FLAGS_REG))]
7739 "TARGET_QIMODE_MATH"
7741 [(set_attr "type" "idiv")
7742 (set_attr "mode" "QI")])
7744 ;; The patterns that match these are at the end of this file.
7746 (define_expand "divxf3"
7747 [(set (match_operand:XF 0 "register_operand" "")
7748 (div:XF (match_operand:XF 1 "register_operand" "")
7749 (match_operand:XF 2 "register_operand" "")))]
7753 (define_expand "divdf3"
7754 [(set (match_operand:DF 0 "register_operand" "")
7755 (div:DF (match_operand:DF 1 "register_operand" "")
7756 (match_operand:DF 2 "nonimmediate_operand" "")))]
7757 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7760 (define_expand "divsf3"
7761 [(set (match_operand:SF 0 "register_operand" "")
7762 (div:SF (match_operand:SF 1 "register_operand" "")
7763 (match_operand:SF 2 "nonimmediate_operand" "")))]
7764 "TARGET_80387 || TARGET_SSE_MATH"
7767 ;; Remainder instructions.
7769 (define_expand "divmoddi4"
7770 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7771 (div:DI (match_operand:DI 1 "register_operand" "")
7772 (match_operand:DI 2 "nonimmediate_operand" "")))
7773 (set (match_operand:DI 3 "register_operand" "")
7774 (mod:DI (match_dup 1) (match_dup 2)))
7775 (clobber (reg:CC FLAGS_REG))])]
7779 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7780 ;; Penalize eax case slightly because it results in worse scheduling
7782 (define_insn "*divmoddi4_nocltd_rex64"
7783 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7784 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7785 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7786 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7787 (mod:DI (match_dup 2) (match_dup 3)))
7788 (clobber (reg:CC FLAGS_REG))]
7789 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7791 [(set_attr "type" "multi")])
7793 (define_insn "*divmoddi4_cltd_rex64"
7794 [(set (match_operand:DI 0 "register_operand" "=a")
7795 (div:DI (match_operand:DI 2 "register_operand" "a")
7796 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7797 (set (match_operand:DI 1 "register_operand" "=&d")
7798 (mod:DI (match_dup 2) (match_dup 3)))
7799 (clobber (reg:CC FLAGS_REG))]
7800 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7802 [(set_attr "type" "multi")])
7804 (define_insn "*divmoddi_noext_rex64"
7805 [(set (match_operand:DI 0 "register_operand" "=a")
7806 (div:DI (match_operand:DI 1 "register_operand" "0")
7807 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7808 (set (match_operand:DI 3 "register_operand" "=d")
7809 (mod:DI (match_dup 1) (match_dup 2)))
7810 (use (match_operand:DI 4 "register_operand" "3"))
7811 (clobber (reg:CC FLAGS_REG))]
7814 [(set_attr "type" "idiv")
7815 (set_attr "mode" "DI")])
7818 [(set (match_operand:DI 0 "register_operand" "")
7819 (div:DI (match_operand:DI 1 "register_operand" "")
7820 (match_operand:DI 2 "nonimmediate_operand" "")))
7821 (set (match_operand:DI 3 "register_operand" "")
7822 (mod:DI (match_dup 1) (match_dup 2)))
7823 (clobber (reg:CC FLAGS_REG))]
7824 "TARGET_64BIT && reload_completed"
7825 [(parallel [(set (match_dup 3)
7826 (ashiftrt:DI (match_dup 4) (const_int 63)))
7827 (clobber (reg:CC FLAGS_REG))])
7828 (parallel [(set (match_dup 0)
7829 (div:DI (reg:DI 0) (match_dup 2)))
7831 (mod:DI (reg:DI 0) (match_dup 2)))
7833 (clobber (reg:CC FLAGS_REG))])]
7835 /* Avoid use of cltd in favor of a mov+shift. */
7836 if (!TARGET_USE_CLTD && !optimize_size)
7838 if (true_regnum (operands[1]))
7839 emit_move_insn (operands[0], operands[1]);
7841 emit_move_insn (operands[3], operands[1]);
7842 operands[4] = operands[3];
7846 gcc_assert (!true_regnum (operands[1]));
7847 operands[4] = operands[1];
7852 (define_expand "divmodsi4"
7853 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7854 (div:SI (match_operand:SI 1 "register_operand" "")
7855 (match_operand:SI 2 "nonimmediate_operand" "")))
7856 (set (match_operand:SI 3 "register_operand" "")
7857 (mod:SI (match_dup 1) (match_dup 2)))
7858 (clobber (reg:CC FLAGS_REG))])]
7862 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7863 ;; Penalize eax case slightly because it results in worse scheduling
7865 (define_insn "*divmodsi4_nocltd"
7866 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7867 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7868 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7869 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7870 (mod:SI (match_dup 2) (match_dup 3)))
7871 (clobber (reg:CC FLAGS_REG))]
7872 "!optimize_size && !TARGET_USE_CLTD"
7874 [(set_attr "type" "multi")])
7876 (define_insn "*divmodsi4_cltd"
7877 [(set (match_operand:SI 0 "register_operand" "=a")
7878 (div:SI (match_operand:SI 2 "register_operand" "a")
7879 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7880 (set (match_operand:SI 1 "register_operand" "=&d")
7881 (mod:SI (match_dup 2) (match_dup 3)))
7882 (clobber (reg:CC FLAGS_REG))]
7883 "optimize_size || TARGET_USE_CLTD"
7885 [(set_attr "type" "multi")])
7887 (define_insn "*divmodsi_noext"
7888 [(set (match_operand:SI 0 "register_operand" "=a")
7889 (div:SI (match_operand:SI 1 "register_operand" "0")
7890 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7891 (set (match_operand:SI 3 "register_operand" "=d")
7892 (mod:SI (match_dup 1) (match_dup 2)))
7893 (use (match_operand:SI 4 "register_operand" "3"))
7894 (clobber (reg:CC FLAGS_REG))]
7897 [(set_attr "type" "idiv")
7898 (set_attr "mode" "SI")])
7901 [(set (match_operand:SI 0 "register_operand" "")
7902 (div:SI (match_operand:SI 1 "register_operand" "")
7903 (match_operand:SI 2 "nonimmediate_operand" "")))
7904 (set (match_operand:SI 3 "register_operand" "")
7905 (mod:SI (match_dup 1) (match_dup 2)))
7906 (clobber (reg:CC FLAGS_REG))]
7908 [(parallel [(set (match_dup 3)
7909 (ashiftrt:SI (match_dup 4) (const_int 31)))
7910 (clobber (reg:CC FLAGS_REG))])
7911 (parallel [(set (match_dup 0)
7912 (div:SI (reg:SI 0) (match_dup 2)))
7914 (mod:SI (reg:SI 0) (match_dup 2)))
7916 (clobber (reg:CC FLAGS_REG))])]
7918 /* Avoid use of cltd in favor of a mov+shift. */
7919 if (!TARGET_USE_CLTD && !optimize_size)
7921 if (true_regnum (operands[1]))
7922 emit_move_insn (operands[0], operands[1]);
7924 emit_move_insn (operands[3], operands[1]);
7925 operands[4] = operands[3];
7929 gcc_assert (!true_regnum (operands[1]));
7930 operands[4] = operands[1];
7934 (define_insn "divmodhi4"
7935 [(set (match_operand:HI 0 "register_operand" "=a")
7936 (div:HI (match_operand:HI 1 "register_operand" "0")
7937 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7938 (set (match_operand:HI 3 "register_operand" "=&d")
7939 (mod:HI (match_dup 1) (match_dup 2)))
7940 (clobber (reg:CC FLAGS_REG))]
7941 "TARGET_HIMODE_MATH"
7943 [(set_attr "type" "multi")
7944 (set_attr "length_immediate" "0")
7945 (set_attr "mode" "SI")])
7947 (define_insn "udivmoddi4"
7948 [(set (match_operand:DI 0 "register_operand" "=a")
7949 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7950 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7951 (set (match_operand:DI 3 "register_operand" "=&d")
7952 (umod:DI (match_dup 1) (match_dup 2)))
7953 (clobber (reg:CC FLAGS_REG))]
7955 "xor{q}\t%3, %3\;div{q}\t%2"
7956 [(set_attr "type" "multi")
7957 (set_attr "length_immediate" "0")
7958 (set_attr "mode" "DI")])
7960 (define_insn "*udivmoddi4_noext"
7961 [(set (match_operand:DI 0 "register_operand" "=a")
7962 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7963 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7964 (set (match_operand:DI 3 "register_operand" "=d")
7965 (umod:DI (match_dup 1) (match_dup 2)))
7967 (clobber (reg:CC FLAGS_REG))]
7970 [(set_attr "type" "idiv")
7971 (set_attr "mode" "DI")])
7974 [(set (match_operand:DI 0 "register_operand" "")
7975 (udiv:DI (match_operand:DI 1 "register_operand" "")
7976 (match_operand:DI 2 "nonimmediate_operand" "")))
7977 (set (match_operand:DI 3 "register_operand" "")
7978 (umod:DI (match_dup 1) (match_dup 2)))
7979 (clobber (reg:CC FLAGS_REG))]
7980 "TARGET_64BIT && reload_completed"
7981 [(set (match_dup 3) (const_int 0))
7982 (parallel [(set (match_dup 0)
7983 (udiv:DI (match_dup 1) (match_dup 2)))
7985 (umod:DI (match_dup 1) (match_dup 2)))
7987 (clobber (reg:CC FLAGS_REG))])]
7990 (define_insn "udivmodsi4"
7991 [(set (match_operand:SI 0 "register_operand" "=a")
7992 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7993 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7994 (set (match_operand:SI 3 "register_operand" "=&d")
7995 (umod:SI (match_dup 1) (match_dup 2)))
7996 (clobber (reg:CC FLAGS_REG))]
7998 "xor{l}\t%3, %3\;div{l}\t%2"
7999 [(set_attr "type" "multi")
8000 (set_attr "length_immediate" "0")
8001 (set_attr "mode" "SI")])
8003 (define_insn "*udivmodsi4_noext"
8004 [(set (match_operand:SI 0 "register_operand" "=a")
8005 (udiv:SI (match_operand:SI 1 "register_operand" "0")
8006 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8007 (set (match_operand:SI 3 "register_operand" "=d")
8008 (umod:SI (match_dup 1) (match_dup 2)))
8010 (clobber (reg:CC FLAGS_REG))]
8013 [(set_attr "type" "idiv")
8014 (set_attr "mode" "SI")])
8017 [(set (match_operand:SI 0 "register_operand" "")
8018 (udiv:SI (match_operand:SI 1 "register_operand" "")
8019 (match_operand:SI 2 "nonimmediate_operand" "")))
8020 (set (match_operand:SI 3 "register_operand" "")
8021 (umod:SI (match_dup 1) (match_dup 2)))
8022 (clobber (reg:CC FLAGS_REG))]
8024 [(set (match_dup 3) (const_int 0))
8025 (parallel [(set (match_dup 0)
8026 (udiv:SI (match_dup 1) (match_dup 2)))
8028 (umod:SI (match_dup 1) (match_dup 2)))
8030 (clobber (reg:CC FLAGS_REG))])]
8033 (define_expand "udivmodhi4"
8034 [(set (match_dup 4) (const_int 0))
8035 (parallel [(set (match_operand:HI 0 "register_operand" "")
8036 (udiv:HI (match_operand:HI 1 "register_operand" "")
8037 (match_operand:HI 2 "nonimmediate_operand" "")))
8038 (set (match_operand:HI 3 "register_operand" "")
8039 (umod:HI (match_dup 1) (match_dup 2)))
8041 (clobber (reg:CC FLAGS_REG))])]
8042 "TARGET_HIMODE_MATH"
8043 "operands[4] = gen_reg_rtx (HImode);")
8045 (define_insn "*udivmodhi_noext"
8046 [(set (match_operand:HI 0 "register_operand" "=a")
8047 (udiv:HI (match_operand:HI 1 "register_operand" "0")
8048 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8049 (set (match_operand:HI 3 "register_operand" "=d")
8050 (umod:HI (match_dup 1) (match_dup 2)))
8051 (use (match_operand:HI 4 "register_operand" "3"))
8052 (clobber (reg:CC FLAGS_REG))]
8055 [(set_attr "type" "idiv")
8056 (set_attr "mode" "HI")])
8058 ;; We cannot use div/idiv for double division, because it causes
8059 ;; "division by zero" on the overflow and that's not what we expect
8060 ;; from truncate. Because true (non truncating) double division is
8061 ;; never generated, we can't create this insn anyway.
8064 ; [(set (match_operand:SI 0 "register_operand" "=a")
8066 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8068 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8069 ; (set (match_operand:SI 3 "register_operand" "=d")
8071 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8072 ; (clobber (reg:CC FLAGS_REG))]
8074 ; "div{l}\t{%2, %0|%0, %2}"
8075 ; [(set_attr "type" "idiv")])
8077 ;;- Logical AND instructions
8079 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8080 ;; Note that this excludes ah.
8082 (define_insn "*testdi_1_rex64"
8083 [(set (reg FLAGS_REG)
8085 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8086 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8088 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8089 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8091 test{l}\t{%k1, %k0|%k0, %k1}
8092 test{l}\t{%k1, %k0|%k0, %k1}
8093 test{q}\t{%1, %0|%0, %1}
8094 test{q}\t{%1, %0|%0, %1}
8095 test{q}\t{%1, %0|%0, %1}"
8096 [(set_attr "type" "test")
8097 (set_attr "modrm" "0,1,0,1,1")
8098 (set_attr "mode" "SI,SI,DI,DI,DI")
8099 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8101 (define_insn "testsi_1"
8102 [(set (reg FLAGS_REG)
8104 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8105 (match_operand:SI 1 "general_operand" "in,in,rin"))
8107 "ix86_match_ccmode (insn, CCNOmode)
8108 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8109 "test{l}\t{%1, %0|%0, %1}"
8110 [(set_attr "type" "test")
8111 (set_attr "modrm" "0,1,1")
8112 (set_attr "mode" "SI")
8113 (set_attr "pent_pair" "uv,np,uv")])
8115 (define_expand "testsi_ccno_1"
8116 [(set (reg:CCNO FLAGS_REG)
8118 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8119 (match_operand:SI 1 "nonmemory_operand" ""))
8124 (define_insn "*testhi_1"
8125 [(set (reg FLAGS_REG)
8126 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8127 (match_operand:HI 1 "general_operand" "n,n,rn"))
8129 "ix86_match_ccmode (insn, CCNOmode)
8130 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8131 "test{w}\t{%1, %0|%0, %1}"
8132 [(set_attr "type" "test")
8133 (set_attr "modrm" "0,1,1")
8134 (set_attr "mode" "HI")
8135 (set_attr "pent_pair" "uv,np,uv")])
8137 (define_expand "testqi_ccz_1"
8138 [(set (reg:CCZ FLAGS_REG)
8139 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8140 (match_operand:QI 1 "nonmemory_operand" ""))
8145 (define_insn "*testqi_1_maybe_si"
8146 [(set (reg FLAGS_REG)
8149 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8150 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8152 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8153 && ix86_match_ccmode (insn,
8154 CONST_INT_P (operands[1])
8155 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8157 if (which_alternative == 3)
8159 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8160 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8161 return "test{l}\t{%1, %k0|%k0, %1}";
8163 return "test{b}\t{%1, %0|%0, %1}";
8165 [(set_attr "type" "test")
8166 (set_attr "modrm" "0,1,1,1")
8167 (set_attr "mode" "QI,QI,QI,SI")
8168 (set_attr "pent_pair" "uv,np,uv,np")])
8170 (define_insn "*testqi_1"
8171 [(set (reg FLAGS_REG)
8174 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8175 (match_operand:QI 1 "general_operand" "n,n,qn"))
8177 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8178 && ix86_match_ccmode (insn, CCNOmode)"
8179 "test{b}\t{%1, %0|%0, %1}"
8180 [(set_attr "type" "test")
8181 (set_attr "modrm" "0,1,1")
8182 (set_attr "mode" "QI")
8183 (set_attr "pent_pair" "uv,np,uv")])
8185 (define_expand "testqi_ext_ccno_0"
8186 [(set (reg:CCNO FLAGS_REG)
8190 (match_operand 0 "ext_register_operand" "")
8193 (match_operand 1 "const_int_operand" ""))
8198 (define_insn "*testqi_ext_0"
8199 [(set (reg FLAGS_REG)
8203 (match_operand 0 "ext_register_operand" "Q")
8206 (match_operand 1 "const_int_operand" "n"))
8208 "ix86_match_ccmode (insn, CCNOmode)"
8209 "test{b}\t{%1, %h0|%h0, %1}"
8210 [(set_attr "type" "test")
8211 (set_attr "mode" "QI")
8212 (set_attr "length_immediate" "1")
8213 (set_attr "pent_pair" "np")])
8215 (define_insn "*testqi_ext_1"
8216 [(set (reg FLAGS_REG)
8220 (match_operand 0 "ext_register_operand" "Q")
8224 (match_operand:QI 1 "general_operand" "Qm")))
8226 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8227 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8228 "test{b}\t{%1, %h0|%h0, %1}"
8229 [(set_attr "type" "test")
8230 (set_attr "mode" "QI")])
8232 (define_insn "*testqi_ext_1_rex64"
8233 [(set (reg FLAGS_REG)
8237 (match_operand 0 "ext_register_operand" "Q")
8241 (match_operand:QI 1 "register_operand" "Q")))
8243 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8244 "test{b}\t{%1, %h0|%h0, %1}"
8245 [(set_attr "type" "test")
8246 (set_attr "mode" "QI")])
8248 (define_insn "*testqi_ext_2"
8249 [(set (reg FLAGS_REG)
8253 (match_operand 0 "ext_register_operand" "Q")
8257 (match_operand 1 "ext_register_operand" "Q")
8261 "ix86_match_ccmode (insn, CCNOmode)"
8262 "test{b}\t{%h1, %h0|%h0, %h1}"
8263 [(set_attr "type" "test")
8264 (set_attr "mode" "QI")])
8266 ;; Combine likes to form bit extractions for some tests. Humor it.
8267 (define_insn "*testqi_ext_3"
8268 [(set (reg FLAGS_REG)
8269 (compare (zero_extract:SI
8270 (match_operand 0 "nonimmediate_operand" "rm")
8271 (match_operand:SI 1 "const_int_operand" "")
8272 (match_operand:SI 2 "const_int_operand" ""))
8274 "ix86_match_ccmode (insn, CCNOmode)
8275 && INTVAL (operands[1]) > 0
8276 && INTVAL (operands[2]) >= 0
8277 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8278 && (GET_MODE (operands[0]) == SImode
8279 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8280 || GET_MODE (operands[0]) == HImode
8281 || GET_MODE (operands[0]) == QImode)"
8284 (define_insn "*testqi_ext_3_rex64"
8285 [(set (reg FLAGS_REG)
8286 (compare (zero_extract:DI
8287 (match_operand 0 "nonimmediate_operand" "rm")
8288 (match_operand:DI 1 "const_int_operand" "")
8289 (match_operand:DI 2 "const_int_operand" ""))
8292 && ix86_match_ccmode (insn, CCNOmode)
8293 && INTVAL (operands[1]) > 0
8294 && INTVAL (operands[2]) >= 0
8295 /* Ensure that resulting mask is zero or sign extended operand. */
8296 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8297 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8298 && INTVAL (operands[1]) > 32))
8299 && (GET_MODE (operands[0]) == SImode
8300 || GET_MODE (operands[0]) == DImode
8301 || GET_MODE (operands[0]) == HImode
8302 || GET_MODE (operands[0]) == QImode)"
8306 [(set (match_operand 0 "flags_reg_operand" "")
8307 (match_operator 1 "compare_operator"
8309 (match_operand 2 "nonimmediate_operand" "")
8310 (match_operand 3 "const_int_operand" "")
8311 (match_operand 4 "const_int_operand" ""))
8313 "ix86_match_ccmode (insn, CCNOmode)"
8314 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8316 rtx val = operands[2];
8317 HOST_WIDE_INT len = INTVAL (operands[3]);
8318 HOST_WIDE_INT pos = INTVAL (operands[4]);
8320 enum machine_mode mode, submode;
8322 mode = GET_MODE (val);
8325 /* ??? Combine likes to put non-volatile mem extractions in QImode
8326 no matter the size of the test. So find a mode that works. */
8327 if (! MEM_VOLATILE_P (val))
8329 mode = smallest_mode_for_size (pos + len, MODE_INT);
8330 val = adjust_address (val, mode, 0);
8333 else if (GET_CODE (val) == SUBREG
8334 && (submode = GET_MODE (SUBREG_REG (val)),
8335 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8336 && pos + len <= GET_MODE_BITSIZE (submode))
8338 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8340 val = SUBREG_REG (val);
8342 else if (mode == HImode && pos + len <= 8)
8344 /* Small HImode tests can be converted to QImode. */
8346 val = gen_lowpart (QImode, val);
8349 if (len == HOST_BITS_PER_WIDE_INT)
8352 mask = ((HOST_WIDE_INT)1 << len) - 1;
8355 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8358 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8359 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8360 ;; this is relatively important trick.
8361 ;; Do the conversion only post-reload to avoid limiting of the register class
8364 [(set (match_operand 0 "flags_reg_operand" "")
8365 (match_operator 1 "compare_operator"
8366 [(and (match_operand 2 "register_operand" "")
8367 (match_operand 3 "const_int_operand" ""))
8370 && QI_REG_P (operands[2])
8371 && GET_MODE (operands[2]) != QImode
8372 && ((ix86_match_ccmode (insn, CCZmode)
8373 && !(INTVAL (operands[3]) & ~(255 << 8)))
8374 || (ix86_match_ccmode (insn, CCNOmode)
8375 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8378 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8381 "operands[2] = gen_lowpart (SImode, operands[2]);
8382 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8385 [(set (match_operand 0 "flags_reg_operand" "")
8386 (match_operator 1 "compare_operator"
8387 [(and (match_operand 2 "nonimmediate_operand" "")
8388 (match_operand 3 "const_int_operand" ""))
8391 && GET_MODE (operands[2]) != QImode
8392 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8393 && ((ix86_match_ccmode (insn, CCZmode)
8394 && !(INTVAL (operands[3]) & ~255))
8395 || (ix86_match_ccmode (insn, CCNOmode)
8396 && !(INTVAL (operands[3]) & ~127)))"
8398 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8400 "operands[2] = gen_lowpart (QImode, operands[2]);
8401 operands[3] = gen_lowpart (QImode, operands[3]);")
8404 ;; %%% This used to optimize known byte-wide and operations to memory,
8405 ;; and sometimes to QImode registers. If this is considered useful,
8406 ;; it should be done with splitters.
8408 (define_expand "anddi3"
8409 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8410 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8411 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8412 (clobber (reg:CC FLAGS_REG))]
8414 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8416 (define_insn "*anddi_1_rex64"
8417 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8418 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8419 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8420 (clobber (reg:CC FLAGS_REG))]
8421 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8423 switch (get_attr_type (insn))
8427 enum machine_mode mode;
8429 gcc_assert (CONST_INT_P (operands[2]));
8430 if (INTVAL (operands[2]) == 0xff)
8434 gcc_assert (INTVAL (operands[2]) == 0xffff);
8438 operands[1] = gen_lowpart (mode, operands[1]);
8440 return "movz{bq|x}\t{%1,%0|%0, %1}";
8442 return "movz{wq|x}\t{%1,%0|%0, %1}";
8446 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8447 if (get_attr_mode (insn) == MODE_SI)
8448 return "and{l}\t{%k2, %k0|%k0, %k2}";
8450 return "and{q}\t{%2, %0|%0, %2}";
8453 [(set_attr "type" "alu,alu,alu,imovx")
8454 (set_attr "length_immediate" "*,*,*,0")
8455 (set_attr "mode" "SI,DI,DI,DI")])
8457 (define_insn "*anddi_2"
8458 [(set (reg FLAGS_REG)
8459 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8460 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8462 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8463 (and:DI (match_dup 1) (match_dup 2)))]
8464 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8465 && ix86_binary_operator_ok (AND, DImode, operands)"
8467 and{l}\t{%k2, %k0|%k0, %k2}
8468 and{q}\t{%2, %0|%0, %2}
8469 and{q}\t{%2, %0|%0, %2}"
8470 [(set_attr "type" "alu")
8471 (set_attr "mode" "SI,DI,DI")])
8473 (define_expand "andsi3"
8474 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8475 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8476 (match_operand:SI 2 "general_operand" "")))
8477 (clobber (reg:CC FLAGS_REG))]
8479 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8481 (define_insn "*andsi_1"
8482 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8483 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8484 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8485 (clobber (reg:CC FLAGS_REG))]
8486 "ix86_binary_operator_ok (AND, SImode, operands)"
8488 switch (get_attr_type (insn))
8492 enum machine_mode mode;
8494 gcc_assert (CONST_INT_P (operands[2]));
8495 if (INTVAL (operands[2]) == 0xff)
8499 gcc_assert (INTVAL (operands[2]) == 0xffff);
8503 operands[1] = gen_lowpart (mode, operands[1]);
8505 return "movz{bl|x}\t{%1,%0|%0, %1}";
8507 return "movz{wl|x}\t{%1,%0|%0, %1}";
8511 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8512 return "and{l}\t{%2, %0|%0, %2}";
8515 [(set_attr "type" "alu,alu,imovx")
8516 (set_attr "length_immediate" "*,*,0")
8517 (set_attr "mode" "SI")])
8520 [(set (match_operand 0 "register_operand" "")
8522 (const_int -65536)))
8523 (clobber (reg:CC FLAGS_REG))]
8524 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8525 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8526 "operands[1] = gen_lowpart (HImode, operands[0]);")
8529 [(set (match_operand 0 "ext_register_operand" "")
8532 (clobber (reg:CC FLAGS_REG))]
8533 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8534 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8535 "operands[1] = gen_lowpart (QImode, operands[0]);")
8538 [(set (match_operand 0 "ext_register_operand" "")
8540 (const_int -65281)))
8541 (clobber (reg:CC FLAGS_REG))]
8542 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8543 [(parallel [(set (zero_extract:SI (match_dup 0)
8547 (zero_extract:SI (match_dup 0)
8550 (zero_extract:SI (match_dup 0)
8553 (clobber (reg:CC FLAGS_REG))])]
8554 "operands[0] = gen_lowpart (SImode, operands[0]);")
8556 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8557 (define_insn "*andsi_1_zext"
8558 [(set (match_operand:DI 0 "register_operand" "=r")
8560 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8561 (match_operand:SI 2 "general_operand" "rim"))))
8562 (clobber (reg:CC FLAGS_REG))]
8563 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8564 "and{l}\t{%2, %k0|%k0, %2}"
8565 [(set_attr "type" "alu")
8566 (set_attr "mode" "SI")])
8568 (define_insn "*andsi_2"
8569 [(set (reg FLAGS_REG)
8570 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8571 (match_operand:SI 2 "general_operand" "rim,ri"))
8573 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8574 (and:SI (match_dup 1) (match_dup 2)))]
8575 "ix86_match_ccmode (insn, CCNOmode)
8576 && ix86_binary_operator_ok (AND, SImode, operands)"
8577 "and{l}\t{%2, %0|%0, %2}"
8578 [(set_attr "type" "alu")
8579 (set_attr "mode" "SI")])
8581 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8582 (define_insn "*andsi_2_zext"
8583 [(set (reg FLAGS_REG)
8584 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8585 (match_operand:SI 2 "general_operand" "rim"))
8587 (set (match_operand:DI 0 "register_operand" "=r")
8588 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8589 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8590 && ix86_binary_operator_ok (AND, SImode, operands)"
8591 "and{l}\t{%2, %k0|%k0, %2}"
8592 [(set_attr "type" "alu")
8593 (set_attr "mode" "SI")])
8595 (define_expand "andhi3"
8596 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8597 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8598 (match_operand:HI 2 "general_operand" "")))
8599 (clobber (reg:CC FLAGS_REG))]
8600 "TARGET_HIMODE_MATH"
8601 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8603 (define_insn "*andhi_1"
8604 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8605 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8606 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8607 (clobber (reg:CC FLAGS_REG))]
8608 "ix86_binary_operator_ok (AND, HImode, operands)"
8610 switch (get_attr_type (insn))
8613 gcc_assert (CONST_INT_P (operands[2]));
8614 gcc_assert (INTVAL (operands[2]) == 0xff);
8615 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8618 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8620 return "and{w}\t{%2, %0|%0, %2}";
8623 [(set_attr "type" "alu,alu,imovx")
8624 (set_attr "length_immediate" "*,*,0")
8625 (set_attr "mode" "HI,HI,SI")])
8627 (define_insn "*andhi_2"
8628 [(set (reg FLAGS_REG)
8629 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8630 (match_operand:HI 2 "general_operand" "rim,ri"))
8632 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8633 (and:HI (match_dup 1) (match_dup 2)))]
8634 "ix86_match_ccmode (insn, CCNOmode)
8635 && ix86_binary_operator_ok (AND, HImode, operands)"
8636 "and{w}\t{%2, %0|%0, %2}"
8637 [(set_attr "type" "alu")
8638 (set_attr "mode" "HI")])
8640 (define_expand "andqi3"
8641 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8642 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8643 (match_operand:QI 2 "general_operand" "")))
8644 (clobber (reg:CC FLAGS_REG))]
8645 "TARGET_QIMODE_MATH"
8646 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8648 ;; %%% Potential partial reg stall on alternative 2. What to do?
8649 (define_insn "*andqi_1"
8650 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8651 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8652 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8653 (clobber (reg:CC FLAGS_REG))]
8654 "ix86_binary_operator_ok (AND, QImode, operands)"
8656 and{b}\t{%2, %0|%0, %2}
8657 and{b}\t{%2, %0|%0, %2}
8658 and{l}\t{%k2, %k0|%k0, %k2}"
8659 [(set_attr "type" "alu")
8660 (set_attr "mode" "QI,QI,SI")])
8662 (define_insn "*andqi_1_slp"
8663 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8664 (and:QI (match_dup 0)
8665 (match_operand:QI 1 "general_operand" "qi,qmi")))
8666 (clobber (reg:CC FLAGS_REG))]
8667 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8668 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8669 "and{b}\t{%1, %0|%0, %1}"
8670 [(set_attr "type" "alu1")
8671 (set_attr "mode" "QI")])
8673 (define_insn "*andqi_2_maybe_si"
8674 [(set (reg FLAGS_REG)
8676 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8677 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8679 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8680 (and:QI (match_dup 1) (match_dup 2)))]
8681 "ix86_binary_operator_ok (AND, QImode, operands)
8682 && ix86_match_ccmode (insn,
8683 CONST_INT_P (operands[2])
8684 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8686 if (which_alternative == 2)
8688 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8689 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8690 return "and{l}\t{%2, %k0|%k0, %2}";
8692 return "and{b}\t{%2, %0|%0, %2}";
8694 [(set_attr "type" "alu")
8695 (set_attr "mode" "QI,QI,SI")])
8697 (define_insn "*andqi_2"
8698 [(set (reg FLAGS_REG)
8700 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8701 (match_operand:QI 2 "general_operand" "qim,qi"))
8703 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8704 (and:QI (match_dup 1) (match_dup 2)))]
8705 "ix86_match_ccmode (insn, CCNOmode)
8706 && ix86_binary_operator_ok (AND, QImode, operands)"
8707 "and{b}\t{%2, %0|%0, %2}"
8708 [(set_attr "type" "alu")
8709 (set_attr "mode" "QI")])
8711 (define_insn "*andqi_2_slp"
8712 [(set (reg FLAGS_REG)
8714 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8715 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8717 (set (strict_low_part (match_dup 0))
8718 (and:QI (match_dup 0) (match_dup 1)))]
8719 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8720 && ix86_match_ccmode (insn, CCNOmode)
8721 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8722 "and{b}\t{%1, %0|%0, %1}"
8723 [(set_attr "type" "alu1")
8724 (set_attr "mode" "QI")])
8726 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8727 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8728 ;; for a QImode operand, which of course failed.
8730 (define_insn "andqi_ext_0"
8731 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8736 (match_operand 1 "ext_register_operand" "0")
8739 (match_operand 2 "const_int_operand" "n")))
8740 (clobber (reg:CC FLAGS_REG))]
8742 "and{b}\t{%2, %h0|%h0, %2}"
8743 [(set_attr "type" "alu")
8744 (set_attr "length_immediate" "1")
8745 (set_attr "mode" "QI")])
8747 ;; Generated by peephole translating test to and. This shows up
8748 ;; often in fp comparisons.
8750 (define_insn "*andqi_ext_0_cc"
8751 [(set (reg FLAGS_REG)
8755 (match_operand 1 "ext_register_operand" "0")
8758 (match_operand 2 "const_int_operand" "n"))
8760 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8769 "ix86_match_ccmode (insn, CCNOmode)"
8770 "and{b}\t{%2, %h0|%h0, %2}"
8771 [(set_attr "type" "alu")
8772 (set_attr "length_immediate" "1")
8773 (set_attr "mode" "QI")])
8775 (define_insn "*andqi_ext_1"
8776 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8781 (match_operand 1 "ext_register_operand" "0")
8785 (match_operand:QI 2 "general_operand" "Qm"))))
8786 (clobber (reg:CC FLAGS_REG))]
8788 "and{b}\t{%2, %h0|%h0, %2}"
8789 [(set_attr "type" "alu")
8790 (set_attr "length_immediate" "0")
8791 (set_attr "mode" "QI")])
8793 (define_insn "*andqi_ext_1_rex64"
8794 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8799 (match_operand 1 "ext_register_operand" "0")
8803 (match_operand 2 "ext_register_operand" "Q"))))
8804 (clobber (reg:CC FLAGS_REG))]
8806 "and{b}\t{%2, %h0|%h0, %2}"
8807 [(set_attr "type" "alu")
8808 (set_attr "length_immediate" "0")
8809 (set_attr "mode" "QI")])
8811 (define_insn "*andqi_ext_2"
8812 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8817 (match_operand 1 "ext_register_operand" "%0")
8821 (match_operand 2 "ext_register_operand" "Q")
8824 (clobber (reg:CC FLAGS_REG))]
8826 "and{b}\t{%h2, %h0|%h0, %h2}"
8827 [(set_attr "type" "alu")
8828 (set_attr "length_immediate" "0")
8829 (set_attr "mode" "QI")])
8831 ;; Convert wide AND instructions with immediate operand to shorter QImode
8832 ;; equivalents when possible.
8833 ;; Don't do the splitting with memory operands, since it introduces risk
8834 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8835 ;; for size, but that can (should?) be handled by generic code instead.
8837 [(set (match_operand 0 "register_operand" "")
8838 (and (match_operand 1 "register_operand" "")
8839 (match_operand 2 "const_int_operand" "")))
8840 (clobber (reg:CC FLAGS_REG))]
8842 && QI_REG_P (operands[0])
8843 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8844 && !(~INTVAL (operands[2]) & ~(255 << 8))
8845 && GET_MODE (operands[0]) != QImode"
8846 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8847 (and:SI (zero_extract:SI (match_dup 1)
8848 (const_int 8) (const_int 8))
8850 (clobber (reg:CC FLAGS_REG))])]
8851 "operands[0] = gen_lowpart (SImode, operands[0]);
8852 operands[1] = gen_lowpart (SImode, operands[1]);
8853 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8855 ;; Since AND can be encoded with sign extended immediate, this is only
8856 ;; profitable when 7th bit is not set.
8858 [(set (match_operand 0 "register_operand" "")
8859 (and (match_operand 1 "general_operand" "")
8860 (match_operand 2 "const_int_operand" "")))
8861 (clobber (reg:CC FLAGS_REG))]
8863 && ANY_QI_REG_P (operands[0])
8864 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8865 && !(~INTVAL (operands[2]) & ~255)
8866 && !(INTVAL (operands[2]) & 128)
8867 && GET_MODE (operands[0]) != QImode"
8868 [(parallel [(set (strict_low_part (match_dup 0))
8869 (and:QI (match_dup 1)
8871 (clobber (reg:CC FLAGS_REG))])]
8872 "operands[0] = gen_lowpart (QImode, operands[0]);
8873 operands[1] = gen_lowpart (QImode, operands[1]);
8874 operands[2] = gen_lowpart (QImode, operands[2]);")
8876 ;; Logical inclusive OR instructions
8878 ;; %%% This used to optimize known byte-wide and operations to memory.
8879 ;; If this is considered useful, it should be done with splitters.
8881 (define_expand "iordi3"
8882 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8883 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8884 (match_operand:DI 2 "x86_64_general_operand" "")))
8885 (clobber (reg:CC FLAGS_REG))]
8887 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8889 (define_insn "*iordi_1_rex64"
8890 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8891 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8892 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8893 (clobber (reg:CC FLAGS_REG))]
8895 && ix86_binary_operator_ok (IOR, DImode, operands)"
8896 "or{q}\t{%2, %0|%0, %2}"
8897 [(set_attr "type" "alu")
8898 (set_attr "mode" "DI")])
8900 (define_insn "*iordi_2_rex64"
8901 [(set (reg FLAGS_REG)
8902 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8903 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8905 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8906 (ior:DI (match_dup 1) (match_dup 2)))]
8908 && ix86_match_ccmode (insn, CCNOmode)
8909 && ix86_binary_operator_ok (IOR, DImode, operands)"
8910 "or{q}\t{%2, %0|%0, %2}"
8911 [(set_attr "type" "alu")
8912 (set_attr "mode" "DI")])
8914 (define_insn "*iordi_3_rex64"
8915 [(set (reg FLAGS_REG)
8916 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8917 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8919 (clobber (match_scratch:DI 0 "=r"))]
8921 && ix86_match_ccmode (insn, CCNOmode)
8922 && ix86_binary_operator_ok (IOR, DImode, operands)"
8923 "or{q}\t{%2, %0|%0, %2}"
8924 [(set_attr "type" "alu")
8925 (set_attr "mode" "DI")])
8928 (define_expand "iorsi3"
8929 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8930 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8931 (match_operand:SI 2 "general_operand" "")))
8932 (clobber (reg:CC FLAGS_REG))]
8934 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8936 (define_insn "*iorsi_1"
8937 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8938 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8939 (match_operand:SI 2 "general_operand" "ri,rmi")))
8940 (clobber (reg:CC FLAGS_REG))]
8941 "ix86_binary_operator_ok (IOR, SImode, operands)"
8942 "or{l}\t{%2, %0|%0, %2}"
8943 [(set_attr "type" "alu")
8944 (set_attr "mode" "SI")])
8946 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8947 (define_insn "*iorsi_1_zext"
8948 [(set (match_operand:DI 0 "register_operand" "=rm")
8950 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8951 (match_operand:SI 2 "general_operand" "rim"))))
8952 (clobber (reg:CC FLAGS_REG))]
8953 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8954 "or{l}\t{%2, %k0|%k0, %2}"
8955 [(set_attr "type" "alu")
8956 (set_attr "mode" "SI")])
8958 (define_insn "*iorsi_1_zext_imm"
8959 [(set (match_operand:DI 0 "register_operand" "=rm")
8960 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8961 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8962 (clobber (reg:CC FLAGS_REG))]
8964 "or{l}\t{%2, %k0|%k0, %2}"
8965 [(set_attr "type" "alu")
8966 (set_attr "mode" "SI")])
8968 (define_insn "*iorsi_2"
8969 [(set (reg FLAGS_REG)
8970 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8971 (match_operand:SI 2 "general_operand" "rim,ri"))
8973 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8974 (ior:SI (match_dup 1) (match_dup 2)))]
8975 "ix86_match_ccmode (insn, CCNOmode)
8976 && ix86_binary_operator_ok (IOR, SImode, operands)"
8977 "or{l}\t{%2, %0|%0, %2}"
8978 [(set_attr "type" "alu")
8979 (set_attr "mode" "SI")])
8981 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8982 ;; ??? Special case for immediate operand is missing - it is tricky.
8983 (define_insn "*iorsi_2_zext"
8984 [(set (reg FLAGS_REG)
8985 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8986 (match_operand:SI 2 "general_operand" "rim"))
8988 (set (match_operand:DI 0 "register_operand" "=r")
8989 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8990 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8991 && ix86_binary_operator_ok (IOR, SImode, operands)"
8992 "or{l}\t{%2, %k0|%k0, %2}"
8993 [(set_attr "type" "alu")
8994 (set_attr "mode" "SI")])
8996 (define_insn "*iorsi_2_zext_imm"
8997 [(set (reg FLAGS_REG)
8998 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8999 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9001 (set (match_operand:DI 0 "register_operand" "=r")
9002 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9003 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9004 && ix86_binary_operator_ok (IOR, SImode, operands)"
9005 "or{l}\t{%2, %k0|%k0, %2}"
9006 [(set_attr "type" "alu")
9007 (set_attr "mode" "SI")])
9009 (define_insn "*iorsi_3"
9010 [(set (reg FLAGS_REG)
9011 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9012 (match_operand:SI 2 "general_operand" "rim"))
9014 (clobber (match_scratch:SI 0 "=r"))]
9015 "ix86_match_ccmode (insn, CCNOmode)
9016 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9017 "or{l}\t{%2, %0|%0, %2}"
9018 [(set_attr "type" "alu")
9019 (set_attr "mode" "SI")])
9021 (define_expand "iorhi3"
9022 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9023 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9024 (match_operand:HI 2 "general_operand" "")))
9025 (clobber (reg:CC FLAGS_REG))]
9026 "TARGET_HIMODE_MATH"
9027 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9029 (define_insn "*iorhi_1"
9030 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9031 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9032 (match_operand:HI 2 "general_operand" "rmi,ri")))
9033 (clobber (reg:CC FLAGS_REG))]
9034 "ix86_binary_operator_ok (IOR, HImode, operands)"
9035 "or{w}\t{%2, %0|%0, %2}"
9036 [(set_attr "type" "alu")
9037 (set_attr "mode" "HI")])
9039 (define_insn "*iorhi_2"
9040 [(set (reg FLAGS_REG)
9041 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9042 (match_operand:HI 2 "general_operand" "rim,ri"))
9044 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9045 (ior:HI (match_dup 1) (match_dup 2)))]
9046 "ix86_match_ccmode (insn, CCNOmode)
9047 && ix86_binary_operator_ok (IOR, HImode, operands)"
9048 "or{w}\t{%2, %0|%0, %2}"
9049 [(set_attr "type" "alu")
9050 (set_attr "mode" "HI")])
9052 (define_insn "*iorhi_3"
9053 [(set (reg FLAGS_REG)
9054 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9055 (match_operand:HI 2 "general_operand" "rim"))
9057 (clobber (match_scratch:HI 0 "=r"))]
9058 "ix86_match_ccmode (insn, CCNOmode)
9059 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9060 "or{w}\t{%2, %0|%0, %2}"
9061 [(set_attr "type" "alu")
9062 (set_attr "mode" "HI")])
9064 (define_expand "iorqi3"
9065 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9066 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9067 (match_operand:QI 2 "general_operand" "")))
9068 (clobber (reg:CC FLAGS_REG))]
9069 "TARGET_QIMODE_MATH"
9070 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9072 ;; %%% Potential partial reg stall on alternative 2. What to do?
9073 (define_insn "*iorqi_1"
9074 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9075 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9076 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9077 (clobber (reg:CC FLAGS_REG))]
9078 "ix86_binary_operator_ok (IOR, QImode, operands)"
9080 or{b}\t{%2, %0|%0, %2}
9081 or{b}\t{%2, %0|%0, %2}
9082 or{l}\t{%k2, %k0|%k0, %k2}"
9083 [(set_attr "type" "alu")
9084 (set_attr "mode" "QI,QI,SI")])
9086 (define_insn "*iorqi_1_slp"
9087 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9088 (ior:QI (match_dup 0)
9089 (match_operand:QI 1 "general_operand" "qmi,qi")))
9090 (clobber (reg:CC FLAGS_REG))]
9091 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9092 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9093 "or{b}\t{%1, %0|%0, %1}"
9094 [(set_attr "type" "alu1")
9095 (set_attr "mode" "QI")])
9097 (define_insn "*iorqi_2"
9098 [(set (reg FLAGS_REG)
9099 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9100 (match_operand:QI 2 "general_operand" "qim,qi"))
9102 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9103 (ior:QI (match_dup 1) (match_dup 2)))]
9104 "ix86_match_ccmode (insn, CCNOmode)
9105 && ix86_binary_operator_ok (IOR, QImode, operands)"
9106 "or{b}\t{%2, %0|%0, %2}"
9107 [(set_attr "type" "alu")
9108 (set_attr "mode" "QI")])
9110 (define_insn "*iorqi_2_slp"
9111 [(set (reg FLAGS_REG)
9112 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9113 (match_operand:QI 1 "general_operand" "qim,qi"))
9115 (set (strict_low_part (match_dup 0))
9116 (ior:QI (match_dup 0) (match_dup 1)))]
9117 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9118 && ix86_match_ccmode (insn, CCNOmode)
9119 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9120 "or{b}\t{%1, %0|%0, %1}"
9121 [(set_attr "type" "alu1")
9122 (set_attr "mode" "QI")])
9124 (define_insn "*iorqi_3"
9125 [(set (reg FLAGS_REG)
9126 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9127 (match_operand:QI 2 "general_operand" "qim"))
9129 (clobber (match_scratch:QI 0 "=q"))]
9130 "ix86_match_ccmode (insn, CCNOmode)
9131 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9132 "or{b}\t{%2, %0|%0, %2}"
9133 [(set_attr "type" "alu")
9134 (set_attr "mode" "QI")])
9136 (define_insn "iorqi_ext_0"
9137 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9142 (match_operand 1 "ext_register_operand" "0")
9145 (match_operand 2 "const_int_operand" "n")))
9146 (clobber (reg:CC FLAGS_REG))]
9147 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9148 "or{b}\t{%2, %h0|%h0, %2}"
9149 [(set_attr "type" "alu")
9150 (set_attr "length_immediate" "1")
9151 (set_attr "mode" "QI")])
9153 (define_insn "*iorqi_ext_1"
9154 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159 (match_operand 1 "ext_register_operand" "0")
9163 (match_operand:QI 2 "general_operand" "Qm"))))
9164 (clobber (reg:CC FLAGS_REG))]
9166 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9167 "or{b}\t{%2, %h0|%h0, %2}"
9168 [(set_attr "type" "alu")
9169 (set_attr "length_immediate" "0")
9170 (set_attr "mode" "QI")])
9172 (define_insn "*iorqi_ext_1_rex64"
9173 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9178 (match_operand 1 "ext_register_operand" "0")
9182 (match_operand 2 "ext_register_operand" "Q"))))
9183 (clobber (reg:CC FLAGS_REG))]
9185 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9186 "or{b}\t{%2, %h0|%h0, %2}"
9187 [(set_attr "type" "alu")
9188 (set_attr "length_immediate" "0")
9189 (set_attr "mode" "QI")])
9191 (define_insn "*iorqi_ext_2"
9192 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9196 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9199 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9202 (clobber (reg:CC FLAGS_REG))]
9203 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9204 "ior{b}\t{%h2, %h0|%h0, %h2}"
9205 [(set_attr "type" "alu")
9206 (set_attr "length_immediate" "0")
9207 (set_attr "mode" "QI")])
9210 [(set (match_operand 0 "register_operand" "")
9211 (ior (match_operand 1 "register_operand" "")
9212 (match_operand 2 "const_int_operand" "")))
9213 (clobber (reg:CC FLAGS_REG))]
9215 && QI_REG_P (operands[0])
9216 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9217 && !(INTVAL (operands[2]) & ~(255 << 8))
9218 && GET_MODE (operands[0]) != QImode"
9219 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9220 (ior:SI (zero_extract:SI (match_dup 1)
9221 (const_int 8) (const_int 8))
9223 (clobber (reg:CC FLAGS_REG))])]
9224 "operands[0] = gen_lowpart (SImode, operands[0]);
9225 operands[1] = gen_lowpart (SImode, operands[1]);
9226 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9228 ;; Since OR can be encoded with sign extended immediate, this is only
9229 ;; profitable when 7th bit is set.
9231 [(set (match_operand 0 "register_operand" "")
9232 (ior (match_operand 1 "general_operand" "")
9233 (match_operand 2 "const_int_operand" "")))
9234 (clobber (reg:CC FLAGS_REG))]
9236 && ANY_QI_REG_P (operands[0])
9237 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9238 && !(INTVAL (operands[2]) & ~255)
9239 && (INTVAL (operands[2]) & 128)
9240 && GET_MODE (operands[0]) != QImode"
9241 [(parallel [(set (strict_low_part (match_dup 0))
9242 (ior:QI (match_dup 1)
9244 (clobber (reg:CC FLAGS_REG))])]
9245 "operands[0] = gen_lowpart (QImode, operands[0]);
9246 operands[1] = gen_lowpart (QImode, operands[1]);
9247 operands[2] = gen_lowpart (QImode, operands[2]);")
9249 ;; Logical XOR instructions
9251 ;; %%% This used to optimize known byte-wide and operations to memory.
9252 ;; If this is considered useful, it should be done with splitters.
9254 (define_expand "xordi3"
9255 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9256 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9257 (match_operand:DI 2 "x86_64_general_operand" "")))
9258 (clobber (reg:CC FLAGS_REG))]
9260 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9262 (define_insn "*xordi_1_rex64"
9263 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9264 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9265 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9266 (clobber (reg:CC FLAGS_REG))]
9268 && ix86_binary_operator_ok (XOR, DImode, operands)"
9270 xor{q}\t{%2, %0|%0, %2}
9271 xor{q}\t{%2, %0|%0, %2}"
9272 [(set_attr "type" "alu")
9273 (set_attr "mode" "DI,DI")])
9275 (define_insn "*xordi_2_rex64"
9276 [(set (reg FLAGS_REG)
9277 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9278 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9280 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9281 (xor:DI (match_dup 1) (match_dup 2)))]
9283 && ix86_match_ccmode (insn, CCNOmode)
9284 && ix86_binary_operator_ok (XOR, DImode, operands)"
9286 xor{q}\t{%2, %0|%0, %2}
9287 xor{q}\t{%2, %0|%0, %2}"
9288 [(set_attr "type" "alu")
9289 (set_attr "mode" "DI,DI")])
9291 (define_insn "*xordi_3_rex64"
9292 [(set (reg FLAGS_REG)
9293 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9294 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9296 (clobber (match_scratch:DI 0 "=r"))]
9298 && ix86_match_ccmode (insn, CCNOmode)
9299 && ix86_binary_operator_ok (XOR, DImode, operands)"
9300 "xor{q}\t{%2, %0|%0, %2}"
9301 [(set_attr "type" "alu")
9302 (set_attr "mode" "DI")])
9304 (define_expand "xorsi3"
9305 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9306 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9307 (match_operand:SI 2 "general_operand" "")))
9308 (clobber (reg:CC FLAGS_REG))]
9310 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9312 (define_insn "*xorsi_1"
9313 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9314 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9315 (match_operand:SI 2 "general_operand" "ri,rm")))
9316 (clobber (reg:CC FLAGS_REG))]
9317 "ix86_binary_operator_ok (XOR, SImode, operands)"
9318 "xor{l}\t{%2, %0|%0, %2}"
9319 [(set_attr "type" "alu")
9320 (set_attr "mode" "SI")])
9322 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9323 ;; Add speccase for immediates
9324 (define_insn "*xorsi_1_zext"
9325 [(set (match_operand:DI 0 "register_operand" "=r")
9327 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9328 (match_operand:SI 2 "general_operand" "rim"))))
9329 (clobber (reg:CC FLAGS_REG))]
9330 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9331 "xor{l}\t{%2, %k0|%k0, %2}"
9332 [(set_attr "type" "alu")
9333 (set_attr "mode" "SI")])
9335 (define_insn "*xorsi_1_zext_imm"
9336 [(set (match_operand:DI 0 "register_operand" "=r")
9337 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9338 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9339 (clobber (reg:CC FLAGS_REG))]
9340 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9341 "xor{l}\t{%2, %k0|%k0, %2}"
9342 [(set_attr "type" "alu")
9343 (set_attr "mode" "SI")])
9345 (define_insn "*xorsi_2"
9346 [(set (reg FLAGS_REG)
9347 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9348 (match_operand:SI 2 "general_operand" "rim,ri"))
9350 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9351 (xor:SI (match_dup 1) (match_dup 2)))]
9352 "ix86_match_ccmode (insn, CCNOmode)
9353 && ix86_binary_operator_ok (XOR, SImode, operands)"
9354 "xor{l}\t{%2, %0|%0, %2}"
9355 [(set_attr "type" "alu")
9356 (set_attr "mode" "SI")])
9358 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9359 ;; ??? Special case for immediate operand is missing - it is tricky.
9360 (define_insn "*xorsi_2_zext"
9361 [(set (reg FLAGS_REG)
9362 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9363 (match_operand:SI 2 "general_operand" "rim"))
9365 (set (match_operand:DI 0 "register_operand" "=r")
9366 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9367 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9368 && ix86_binary_operator_ok (XOR, SImode, operands)"
9369 "xor{l}\t{%2, %k0|%k0, %2}"
9370 [(set_attr "type" "alu")
9371 (set_attr "mode" "SI")])
9373 (define_insn "*xorsi_2_zext_imm"
9374 [(set (reg FLAGS_REG)
9375 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9376 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9378 (set (match_operand:DI 0 "register_operand" "=r")
9379 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9380 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9381 && ix86_binary_operator_ok (XOR, SImode, operands)"
9382 "xor{l}\t{%2, %k0|%k0, %2}"
9383 [(set_attr "type" "alu")
9384 (set_attr "mode" "SI")])
9386 (define_insn "*xorsi_3"
9387 [(set (reg FLAGS_REG)
9388 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9389 (match_operand:SI 2 "general_operand" "rim"))
9391 (clobber (match_scratch:SI 0 "=r"))]
9392 "ix86_match_ccmode (insn, CCNOmode)
9393 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9394 "xor{l}\t{%2, %0|%0, %2}"
9395 [(set_attr "type" "alu")
9396 (set_attr "mode" "SI")])
9398 (define_expand "xorhi3"
9399 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9400 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9401 (match_operand:HI 2 "general_operand" "")))
9402 (clobber (reg:CC FLAGS_REG))]
9403 "TARGET_HIMODE_MATH"
9404 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9406 (define_insn "*xorhi_1"
9407 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9408 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9409 (match_operand:HI 2 "general_operand" "rmi,ri")))
9410 (clobber (reg:CC FLAGS_REG))]
9411 "ix86_binary_operator_ok (XOR, HImode, operands)"
9412 "xor{w}\t{%2, %0|%0, %2}"
9413 [(set_attr "type" "alu")
9414 (set_attr "mode" "HI")])
9416 (define_insn "*xorhi_2"
9417 [(set (reg FLAGS_REG)
9418 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9419 (match_operand:HI 2 "general_operand" "rim,ri"))
9421 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9422 (xor:HI (match_dup 1) (match_dup 2)))]
9423 "ix86_match_ccmode (insn, CCNOmode)
9424 && ix86_binary_operator_ok (XOR, HImode, operands)"
9425 "xor{w}\t{%2, %0|%0, %2}"
9426 [(set_attr "type" "alu")
9427 (set_attr "mode" "HI")])
9429 (define_insn "*xorhi_3"
9430 [(set (reg FLAGS_REG)
9431 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9432 (match_operand:HI 2 "general_operand" "rim"))
9434 (clobber (match_scratch:HI 0 "=r"))]
9435 "ix86_match_ccmode (insn, CCNOmode)
9436 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9437 "xor{w}\t{%2, %0|%0, %2}"
9438 [(set_attr "type" "alu")
9439 (set_attr "mode" "HI")])
9441 (define_expand "xorqi3"
9442 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9443 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9444 (match_operand:QI 2 "general_operand" "")))
9445 (clobber (reg:CC FLAGS_REG))]
9446 "TARGET_QIMODE_MATH"
9447 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9449 ;; %%% Potential partial reg stall on alternative 2. What to do?
9450 (define_insn "*xorqi_1"
9451 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9452 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9453 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9454 (clobber (reg:CC FLAGS_REG))]
9455 "ix86_binary_operator_ok (XOR, QImode, operands)"
9457 xor{b}\t{%2, %0|%0, %2}
9458 xor{b}\t{%2, %0|%0, %2}
9459 xor{l}\t{%k2, %k0|%k0, %k2}"
9460 [(set_attr "type" "alu")
9461 (set_attr "mode" "QI,QI,SI")])
9463 (define_insn "*xorqi_1_slp"
9464 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9465 (xor:QI (match_dup 0)
9466 (match_operand:QI 1 "general_operand" "qi,qmi")))
9467 (clobber (reg:CC FLAGS_REG))]
9468 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9469 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9470 "xor{b}\t{%1, %0|%0, %1}"
9471 [(set_attr "type" "alu1")
9472 (set_attr "mode" "QI")])
9474 (define_insn "xorqi_ext_0"
9475 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9480 (match_operand 1 "ext_register_operand" "0")
9483 (match_operand 2 "const_int_operand" "n")))
9484 (clobber (reg:CC FLAGS_REG))]
9485 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9486 "xor{b}\t{%2, %h0|%h0, %2}"
9487 [(set_attr "type" "alu")
9488 (set_attr "length_immediate" "1")
9489 (set_attr "mode" "QI")])
9491 (define_insn "*xorqi_ext_1"
9492 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9497 (match_operand 1 "ext_register_operand" "0")
9501 (match_operand:QI 2 "general_operand" "Qm"))))
9502 (clobber (reg:CC FLAGS_REG))]
9504 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9505 "xor{b}\t{%2, %h0|%h0, %2}"
9506 [(set_attr "type" "alu")
9507 (set_attr "length_immediate" "0")
9508 (set_attr "mode" "QI")])
9510 (define_insn "*xorqi_ext_1_rex64"
9511 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9516 (match_operand 1 "ext_register_operand" "0")
9520 (match_operand 2 "ext_register_operand" "Q"))))
9521 (clobber (reg:CC FLAGS_REG))]
9523 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9524 "xor{b}\t{%2, %h0|%h0, %2}"
9525 [(set_attr "type" "alu")
9526 (set_attr "length_immediate" "0")
9527 (set_attr "mode" "QI")])
9529 (define_insn "*xorqi_ext_2"
9530 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9534 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9537 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9540 (clobber (reg:CC FLAGS_REG))]
9541 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9542 "xor{b}\t{%h2, %h0|%h0, %h2}"
9543 [(set_attr "type" "alu")
9544 (set_attr "length_immediate" "0")
9545 (set_attr "mode" "QI")])
9547 (define_insn "*xorqi_cc_1"
9548 [(set (reg FLAGS_REG)
9550 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9551 (match_operand:QI 2 "general_operand" "qim,qi"))
9553 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9554 (xor:QI (match_dup 1) (match_dup 2)))]
9555 "ix86_match_ccmode (insn, CCNOmode)
9556 && ix86_binary_operator_ok (XOR, QImode, operands)"
9557 "xor{b}\t{%2, %0|%0, %2}"
9558 [(set_attr "type" "alu")
9559 (set_attr "mode" "QI")])
9561 (define_insn "*xorqi_2_slp"
9562 [(set (reg FLAGS_REG)
9563 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9564 (match_operand:QI 1 "general_operand" "qim,qi"))
9566 (set (strict_low_part (match_dup 0))
9567 (xor:QI (match_dup 0) (match_dup 1)))]
9568 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9569 && ix86_match_ccmode (insn, CCNOmode)
9570 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9571 "xor{b}\t{%1, %0|%0, %1}"
9572 [(set_attr "type" "alu1")
9573 (set_attr "mode" "QI")])
9575 (define_insn "*xorqi_cc_2"
9576 [(set (reg FLAGS_REG)
9578 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9579 (match_operand:QI 2 "general_operand" "qim"))
9581 (clobber (match_scratch:QI 0 "=q"))]
9582 "ix86_match_ccmode (insn, CCNOmode)
9583 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9584 "xor{b}\t{%2, %0|%0, %2}"
9585 [(set_attr "type" "alu")
9586 (set_attr "mode" "QI")])
9588 (define_insn "*xorqi_cc_ext_1"
9589 [(set (reg FLAGS_REG)
9593 (match_operand 1 "ext_register_operand" "0")
9596 (match_operand:QI 2 "general_operand" "qmn"))
9598 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9602 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9604 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9605 "xor{b}\t{%2, %h0|%h0, %2}"
9606 [(set_attr "type" "alu")
9607 (set_attr "mode" "QI")])
9609 (define_insn "*xorqi_cc_ext_1_rex64"
9610 [(set (reg FLAGS_REG)
9614 (match_operand 1 "ext_register_operand" "0")
9617 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9619 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9623 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9625 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9626 "xor{b}\t{%2, %h0|%h0, %2}"
9627 [(set_attr "type" "alu")
9628 (set_attr "mode" "QI")])
9630 (define_expand "xorqi_cc_ext_1"
9632 (set (reg:CCNO FLAGS_REG)
9636 (match_operand 1 "ext_register_operand" "")
9639 (match_operand:QI 2 "general_operand" ""))
9641 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9645 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9651 [(set (match_operand 0 "register_operand" "")
9652 (xor (match_operand 1 "register_operand" "")
9653 (match_operand 2 "const_int_operand" "")))
9654 (clobber (reg:CC FLAGS_REG))]
9656 && QI_REG_P (operands[0])
9657 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9658 && !(INTVAL (operands[2]) & ~(255 << 8))
9659 && GET_MODE (operands[0]) != QImode"
9660 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9661 (xor:SI (zero_extract:SI (match_dup 1)
9662 (const_int 8) (const_int 8))
9664 (clobber (reg:CC FLAGS_REG))])]
9665 "operands[0] = gen_lowpart (SImode, operands[0]);
9666 operands[1] = gen_lowpart (SImode, operands[1]);
9667 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9669 ;; Since XOR can be encoded with sign extended immediate, this is only
9670 ;; profitable when 7th bit is set.
9672 [(set (match_operand 0 "register_operand" "")
9673 (xor (match_operand 1 "general_operand" "")
9674 (match_operand 2 "const_int_operand" "")))
9675 (clobber (reg:CC FLAGS_REG))]
9677 && ANY_QI_REG_P (operands[0])
9678 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9679 && !(INTVAL (operands[2]) & ~255)
9680 && (INTVAL (operands[2]) & 128)
9681 && GET_MODE (operands[0]) != QImode"
9682 [(parallel [(set (strict_low_part (match_dup 0))
9683 (xor:QI (match_dup 1)
9685 (clobber (reg:CC FLAGS_REG))])]
9686 "operands[0] = gen_lowpart (QImode, operands[0]);
9687 operands[1] = gen_lowpart (QImode, operands[1]);
9688 operands[2] = gen_lowpart (QImode, operands[2]);")
9690 ;; Negation instructions
9692 (define_expand "negti2"
9693 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9694 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9695 (clobber (reg:CC FLAGS_REG))])]
9697 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9699 (define_insn "*negti2_1"
9700 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9701 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9702 (clobber (reg:CC FLAGS_REG))]
9704 && ix86_unary_operator_ok (NEG, TImode, operands)"
9708 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9709 (neg:TI (match_operand:TI 1 "general_operand" "")))
9710 (clobber (reg:CC FLAGS_REG))]
9711 "TARGET_64BIT && reload_completed"
9713 [(set (reg:CCZ FLAGS_REG)
9714 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9715 (set (match_dup 0) (neg:DI (match_dup 2)))])
9718 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9721 (clobber (reg:CC FLAGS_REG))])
9724 (neg:DI (match_dup 1)))
9725 (clobber (reg:CC FLAGS_REG))])]
9726 "split_ti (operands+1, 1, operands+2, operands+3);
9727 split_ti (operands+0, 1, operands+0, operands+1);")
9729 (define_expand "negdi2"
9730 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9731 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9732 (clobber (reg:CC FLAGS_REG))])]
9734 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9736 (define_insn "*negdi2_1"
9737 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9738 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9739 (clobber (reg:CC FLAGS_REG))]
9741 && ix86_unary_operator_ok (NEG, DImode, operands)"
9745 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9746 (neg:DI (match_operand:DI 1 "general_operand" "")))
9747 (clobber (reg:CC FLAGS_REG))]
9748 "!TARGET_64BIT && reload_completed"
9750 [(set (reg:CCZ FLAGS_REG)
9751 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9752 (set (match_dup 0) (neg:SI (match_dup 2)))])
9755 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9758 (clobber (reg:CC FLAGS_REG))])
9761 (neg:SI (match_dup 1)))
9762 (clobber (reg:CC FLAGS_REG))])]
9763 "split_di (operands+1, 1, operands+2, operands+3);
9764 split_di (operands+0, 1, operands+0, operands+1);")
9766 (define_insn "*negdi2_1_rex64"
9767 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9768 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9769 (clobber (reg:CC FLAGS_REG))]
9770 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9772 [(set_attr "type" "negnot")
9773 (set_attr "mode" "DI")])
9775 ;; The problem with neg is that it does not perform (compare x 0),
9776 ;; it really performs (compare 0 x), which leaves us with the zero
9777 ;; flag being the only useful item.
9779 (define_insn "*negdi2_cmpz_rex64"
9780 [(set (reg:CCZ FLAGS_REG)
9781 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9783 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9784 (neg:DI (match_dup 1)))]
9785 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9787 [(set_attr "type" "negnot")
9788 (set_attr "mode" "DI")])
9791 (define_expand "negsi2"
9792 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9793 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9794 (clobber (reg:CC FLAGS_REG))])]
9796 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9798 (define_insn "*negsi2_1"
9799 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9800 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9801 (clobber (reg:CC FLAGS_REG))]
9802 "ix86_unary_operator_ok (NEG, SImode, operands)"
9804 [(set_attr "type" "negnot")
9805 (set_attr "mode" "SI")])
9807 ;; Combine is quite creative about this pattern.
9808 (define_insn "*negsi2_1_zext"
9809 [(set (match_operand:DI 0 "register_operand" "=r")
9810 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9813 (clobber (reg:CC FLAGS_REG))]
9814 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9816 [(set_attr "type" "negnot")
9817 (set_attr "mode" "SI")])
9819 ;; The problem with neg is that it does not perform (compare x 0),
9820 ;; it really performs (compare 0 x), which leaves us with the zero
9821 ;; flag being the only useful item.
9823 (define_insn "*negsi2_cmpz"
9824 [(set (reg:CCZ FLAGS_REG)
9825 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9827 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9828 (neg:SI (match_dup 1)))]
9829 "ix86_unary_operator_ok (NEG, SImode, operands)"
9831 [(set_attr "type" "negnot")
9832 (set_attr "mode" "SI")])
9834 (define_insn "*negsi2_cmpz_zext"
9835 [(set (reg:CCZ FLAGS_REG)
9836 (compare:CCZ (lshiftrt:DI
9838 (match_operand:DI 1 "register_operand" "0")
9842 (set (match_operand:DI 0 "register_operand" "=r")
9843 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9846 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9848 [(set_attr "type" "negnot")
9849 (set_attr "mode" "SI")])
9851 (define_expand "neghi2"
9852 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9853 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9854 (clobber (reg:CC FLAGS_REG))])]
9855 "TARGET_HIMODE_MATH"
9856 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9858 (define_insn "*neghi2_1"
9859 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9860 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "ix86_unary_operator_ok (NEG, HImode, operands)"
9864 [(set_attr "type" "negnot")
9865 (set_attr "mode" "HI")])
9867 (define_insn "*neghi2_cmpz"
9868 [(set (reg:CCZ FLAGS_REG)
9869 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9871 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9872 (neg:HI (match_dup 1)))]
9873 "ix86_unary_operator_ok (NEG, HImode, operands)"
9875 [(set_attr "type" "negnot")
9876 (set_attr "mode" "HI")])
9878 (define_expand "negqi2"
9879 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9880 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9881 (clobber (reg:CC FLAGS_REG))])]
9882 "TARGET_QIMODE_MATH"
9883 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9885 (define_insn "*negqi2_1"
9886 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9887 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9888 (clobber (reg:CC FLAGS_REG))]
9889 "ix86_unary_operator_ok (NEG, QImode, operands)"
9891 [(set_attr "type" "negnot")
9892 (set_attr "mode" "QI")])
9894 (define_insn "*negqi2_cmpz"
9895 [(set (reg:CCZ FLAGS_REG)
9896 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9898 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9899 (neg:QI (match_dup 1)))]
9900 "ix86_unary_operator_ok (NEG, QImode, operands)"
9902 [(set_attr "type" "negnot")
9903 (set_attr "mode" "QI")])
9905 ;; Changing of sign for FP values is doable using integer unit too.
9907 (define_expand "negsf2"
9908 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9909 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9910 "TARGET_80387 || TARGET_SSE_MATH"
9911 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9913 (define_expand "abssf2"
9914 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9915 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9916 "TARGET_80387 || TARGET_SSE_MATH"
9917 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9919 (define_insn "*absnegsf2_mixed"
9920 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9921 (match_operator:SF 3 "absneg_operator"
9922 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9923 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9924 (clobber (reg:CC FLAGS_REG))]
9925 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9926 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9929 (define_insn "*absnegsf2_sse"
9930 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9931 (match_operator:SF 3 "absneg_operator"
9932 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9933 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9934 (clobber (reg:CC FLAGS_REG))]
9936 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9939 (define_insn "*absnegsf2_i387"
9940 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9941 (match_operator:SF 3 "absneg_operator"
9942 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9943 (use (match_operand 2 "" ""))
9944 (clobber (reg:CC FLAGS_REG))]
9945 "TARGET_80387 && !TARGET_SSE_MATH
9946 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9949 (define_expand "copysignsf3"
9950 [(match_operand:SF 0 "register_operand" "")
9951 (match_operand:SF 1 "nonmemory_operand" "")
9952 (match_operand:SF 2 "register_operand" "")]
9955 ix86_expand_copysign (operands);
9959 (define_insn_and_split "copysignsf3_const"
9960 [(set (match_operand:SF 0 "register_operand" "=x")
9962 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9963 (match_operand:SF 2 "register_operand" "0")
9964 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9968 "&& reload_completed"
9971 ix86_split_copysign_const (operands);
9975 (define_insn "copysignsf3_var"
9976 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9978 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9979 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9980 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9981 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9983 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9988 [(set (match_operand:SF 0 "register_operand" "")
9990 [(match_operand:SF 2 "register_operand" "")
9991 (match_operand:SF 3 "register_operand" "")
9992 (match_operand:V4SF 4 "" "")
9993 (match_operand:V4SF 5 "" "")]
9995 (clobber (match_scratch:V4SF 1 ""))]
9996 "TARGET_SSE_MATH && reload_completed"
9999 ix86_split_copysign_var (operands);
10003 (define_expand "negdf2"
10004 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10005 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10006 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10007 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
10009 (define_expand "absdf2"
10010 [(set (match_operand:DF 0 "nonimmediate_operand" "")
10011 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
10012 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
10013 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
10015 (define_insn "*absnegdf2_mixed"
10016 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,f,rm")
10017 (match_operator:DF 3 "absneg_operator"
10018 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0,0")]))
10019 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X,X"))
10020 (clobber (reg:CC FLAGS_REG))]
10021 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
10022 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10025 (define_insn "*absnegdf2_sse"
10026 [(set (match_operand:DF 0 "nonimmediate_operand" "=x,x,rm")
10027 (match_operator:DF 3 "absneg_operator"
10028 [(match_operand:DF 1 "nonimmediate_operand" "0 ,x,0 ")]))
10029 (use (match_operand:V2DF 2 "nonimmediate_operand" "xm,0,X "))
10030 (clobber (reg:CC FLAGS_REG))]
10031 "TARGET_SSE2 && TARGET_SSE_MATH
10032 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10035 (define_insn "*absnegdf2_i387"
10036 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
10037 (match_operator:DF 3 "absneg_operator"
10038 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
10039 (use (match_operand 2 "" ""))
10040 (clobber (reg:CC FLAGS_REG))]
10041 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
10042 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
10045 (define_expand "copysigndf3"
10046 [(match_operand:DF 0 "register_operand" "")
10047 (match_operand:DF 1 "nonmemory_operand" "")
10048 (match_operand:DF 2 "register_operand" "")]
10049 "TARGET_SSE2 && TARGET_SSE_MATH"
10051 ix86_expand_copysign (operands);
10055 (define_insn_and_split "copysigndf3_const"
10056 [(set (match_operand:DF 0 "register_operand" "=x")
10058 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
10059 (match_operand:DF 2 "register_operand" "0")
10060 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
10062 "TARGET_SSE2 && TARGET_SSE_MATH"
10064 "&& reload_completed"
10067 ix86_split_copysign_const (operands);
10071 (define_insn "copysigndf3_var"
10072 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
10074 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
10075 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
10076 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
10077 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
10079 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
10080 "TARGET_SSE2 && TARGET_SSE_MATH"
10084 [(set (match_operand:DF 0 "register_operand" "")
10086 [(match_operand:DF 2 "register_operand" "")
10087 (match_operand:DF 3 "register_operand" "")
10088 (match_operand:V2DF 4 "" "")
10089 (match_operand:V2DF 5 "" "")]
10091 (clobber (match_scratch:V2DF 1 ""))]
10092 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
10095 ix86_split_copysign_var (operands);
10099 (define_expand "negxf2"
10100 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10101 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10103 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
10105 (define_expand "absxf2"
10106 [(set (match_operand:XF 0 "nonimmediate_operand" "")
10107 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
10109 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
10111 (define_insn "*absnegxf2_i387"
10112 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
10113 (match_operator:XF 3 "absneg_operator"
10114 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
10115 (use (match_operand 2 "" ""))
10116 (clobber (reg:CC FLAGS_REG))]
10118 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
10121 ;; Splitters for fp abs and neg.
10124 [(set (match_operand 0 "fp_register_operand" "")
10125 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10126 (use (match_operand 2 "" ""))
10127 (clobber (reg:CC FLAGS_REG))]
10129 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10132 [(set (match_operand 0 "register_operand" "")
10133 (match_operator 3 "absneg_operator"
10134 [(match_operand 1 "register_operand" "")]))
10135 (use (match_operand 2 "nonimmediate_operand" ""))
10136 (clobber (reg:CC FLAGS_REG))]
10137 "reload_completed && SSE_REG_P (operands[0])"
10138 [(set (match_dup 0) (match_dup 3))]
10140 enum machine_mode mode = GET_MODE (operands[0]);
10141 enum machine_mode vmode = GET_MODE (operands[2]);
10144 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10145 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10146 if (operands_match_p (operands[0], operands[2]))
10149 operands[1] = operands[2];
10152 if (GET_CODE (operands[3]) == ABS)
10153 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10155 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10160 [(set (match_operand:SF 0 "register_operand" "")
10161 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10162 (use (match_operand:V4SF 2 "" ""))
10163 (clobber (reg:CC FLAGS_REG))]
10165 [(parallel [(set (match_dup 0) (match_dup 1))
10166 (clobber (reg:CC FLAGS_REG))])]
10169 operands[0] = gen_lowpart (SImode, operands[0]);
10170 if (GET_CODE (operands[1]) == ABS)
10172 tmp = gen_int_mode (0x7fffffff, SImode);
10173 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10177 tmp = gen_int_mode (0x80000000, SImode);
10178 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10184 [(set (match_operand:DF 0 "register_operand" "")
10185 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10186 (use (match_operand 2 "" ""))
10187 (clobber (reg:CC FLAGS_REG))]
10189 [(parallel [(set (match_dup 0) (match_dup 1))
10190 (clobber (reg:CC FLAGS_REG))])]
10195 tmp = gen_lowpart (DImode, operands[0]);
10196 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10199 if (GET_CODE (operands[1]) == ABS)
10202 tmp = gen_rtx_NOT (DImode, tmp);
10206 operands[0] = gen_highpart (SImode, operands[0]);
10207 if (GET_CODE (operands[1]) == ABS)
10209 tmp = gen_int_mode (0x7fffffff, SImode);
10210 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10214 tmp = gen_int_mode (0x80000000, SImode);
10215 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10222 [(set (match_operand:XF 0 "register_operand" "")
10223 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10224 (use (match_operand 2 "" ""))
10225 (clobber (reg:CC FLAGS_REG))]
10227 [(parallel [(set (match_dup 0) (match_dup 1))
10228 (clobber (reg:CC FLAGS_REG))])]
10231 operands[0] = gen_rtx_REG (SImode,
10232 true_regnum (operands[0])
10233 + (TARGET_64BIT ? 1 : 2));
10234 if (GET_CODE (operands[1]) == ABS)
10236 tmp = GEN_INT (0x7fff);
10237 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10241 tmp = GEN_INT (0x8000);
10242 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10248 [(set (match_operand 0 "memory_operand" "")
10249 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10250 (use (match_operand 2 "" ""))
10251 (clobber (reg:CC FLAGS_REG))]
10253 [(parallel [(set (match_dup 0) (match_dup 1))
10254 (clobber (reg:CC FLAGS_REG))])]
10256 enum machine_mode mode = GET_MODE (operands[0]);
10257 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
10260 operands[0] = adjust_address (operands[0], QImode, size - 1);
10261 if (GET_CODE (operands[1]) == ABS)
10263 tmp = gen_int_mode (0x7f, QImode);
10264 tmp = gen_rtx_AND (QImode, operands[0], tmp);
10268 tmp = gen_int_mode (0x80, QImode);
10269 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
10274 ;; Conditionalize these after reload. If they match before reload, we
10275 ;; lose the clobber and ability to use integer instructions.
10277 (define_insn "*negsf2_1"
10278 [(set (match_operand:SF 0 "register_operand" "=f")
10279 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
10280 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10282 [(set_attr "type" "fsgn")
10283 (set_attr "mode" "SF")])
10285 (define_insn "*negdf2_1"
10286 [(set (match_operand:DF 0 "register_operand" "=f")
10287 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
10288 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10290 [(set_attr "type" "fsgn")
10291 (set_attr "mode" "DF")])
10293 (define_insn "*negxf2_1"
10294 [(set (match_operand:XF 0 "register_operand" "=f")
10295 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
10298 [(set_attr "type" "fsgn")
10299 (set_attr "mode" "XF")])
10301 (define_insn "*abssf2_1"
10302 [(set (match_operand:SF 0 "register_operand" "=f")
10303 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
10304 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
10306 [(set_attr "type" "fsgn")
10307 (set_attr "mode" "SF")])
10309 (define_insn "*absdf2_1"
10310 [(set (match_operand:DF 0 "register_operand" "=f")
10311 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
10312 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
10314 [(set_attr "type" "fsgn")
10315 (set_attr "mode" "DF")])
10317 (define_insn "*absxf2_1"
10318 [(set (match_operand:XF 0 "register_operand" "=f")
10319 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10322 [(set_attr "type" "fsgn")
10323 (set_attr "mode" "DF")])
10325 (define_insn "*negextendsfdf2"
10326 [(set (match_operand:DF 0 "register_operand" "=f")
10327 (neg:DF (float_extend:DF
10328 (match_operand:SF 1 "register_operand" "0"))))]
10329 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10331 [(set_attr "type" "fsgn")
10332 (set_attr "mode" "DF")])
10334 (define_insn "*negextenddfxf2"
10335 [(set (match_operand:XF 0 "register_operand" "=f")
10336 (neg:XF (float_extend:XF
10337 (match_operand:DF 1 "register_operand" "0"))))]
10340 [(set_attr "type" "fsgn")
10341 (set_attr "mode" "XF")])
10343 (define_insn "*negextendsfxf2"
10344 [(set (match_operand:XF 0 "register_operand" "=f")
10345 (neg:XF (float_extend:XF
10346 (match_operand:SF 1 "register_operand" "0"))))]
10349 [(set_attr "type" "fsgn")
10350 (set_attr "mode" "XF")])
10352 (define_insn "*absextendsfdf2"
10353 [(set (match_operand:DF 0 "register_operand" "=f")
10354 (abs:DF (float_extend:DF
10355 (match_operand:SF 1 "register_operand" "0"))))]
10356 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10358 [(set_attr "type" "fsgn")
10359 (set_attr "mode" "DF")])
10361 (define_insn "*absextenddfxf2"
10362 [(set (match_operand:XF 0 "register_operand" "=f")
10363 (abs:XF (float_extend:XF
10364 (match_operand:DF 1 "register_operand" "0"))))]
10367 [(set_attr "type" "fsgn")
10368 (set_attr "mode" "XF")])
10370 (define_insn "*absextendsfxf2"
10371 [(set (match_operand:XF 0 "register_operand" "=f")
10372 (abs:XF (float_extend:XF
10373 (match_operand:SF 1 "register_operand" "0"))))]
10376 [(set_attr "type" "fsgn")
10377 (set_attr "mode" "XF")])
10379 ;; One complement instructions
10381 (define_expand "one_cmpldi2"
10382 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10383 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10385 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10387 (define_insn "*one_cmpldi2_1_rex64"
10388 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10389 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10390 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10392 [(set_attr "type" "negnot")
10393 (set_attr "mode" "DI")])
10395 (define_insn "*one_cmpldi2_2_rex64"
10396 [(set (reg FLAGS_REG)
10397 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10399 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10400 (not:DI (match_dup 1)))]
10401 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10402 && ix86_unary_operator_ok (NOT, DImode, operands)"
10404 [(set_attr "type" "alu1")
10405 (set_attr "mode" "DI")])
10408 [(set (match_operand 0 "flags_reg_operand" "")
10409 (match_operator 2 "compare_operator"
10410 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10412 (set (match_operand:DI 1 "nonimmediate_operand" "")
10413 (not:DI (match_dup 3)))]
10414 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10415 [(parallel [(set (match_dup 0)
10417 [(xor:DI (match_dup 3) (const_int -1))
10420 (xor:DI (match_dup 3) (const_int -1)))])]
10423 (define_expand "one_cmplsi2"
10424 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10425 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10427 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10429 (define_insn "*one_cmplsi2_1"
10430 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10431 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10432 "ix86_unary_operator_ok (NOT, SImode, operands)"
10434 [(set_attr "type" "negnot")
10435 (set_attr "mode" "SI")])
10437 ;; ??? Currently never generated - xor is used instead.
10438 (define_insn "*one_cmplsi2_1_zext"
10439 [(set (match_operand:DI 0 "register_operand" "=r")
10440 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10441 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10443 [(set_attr "type" "negnot")
10444 (set_attr "mode" "SI")])
10446 (define_insn "*one_cmplsi2_2"
10447 [(set (reg FLAGS_REG)
10448 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10450 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10451 (not:SI (match_dup 1)))]
10452 "ix86_match_ccmode (insn, CCNOmode)
10453 && ix86_unary_operator_ok (NOT, SImode, operands)"
10455 [(set_attr "type" "alu1")
10456 (set_attr "mode" "SI")])
10459 [(set (match_operand 0 "flags_reg_operand" "")
10460 (match_operator 2 "compare_operator"
10461 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10463 (set (match_operand:SI 1 "nonimmediate_operand" "")
10464 (not:SI (match_dup 3)))]
10465 "ix86_match_ccmode (insn, CCNOmode)"
10466 [(parallel [(set (match_dup 0)
10467 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10470 (xor:SI (match_dup 3) (const_int -1)))])]
10473 ;; ??? Currently never generated - xor is used instead.
10474 (define_insn "*one_cmplsi2_2_zext"
10475 [(set (reg FLAGS_REG)
10476 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10478 (set (match_operand:DI 0 "register_operand" "=r")
10479 (zero_extend:DI (not:SI (match_dup 1))))]
10480 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10481 && ix86_unary_operator_ok (NOT, SImode, operands)"
10483 [(set_attr "type" "alu1")
10484 (set_attr "mode" "SI")])
10487 [(set (match_operand 0 "flags_reg_operand" "")
10488 (match_operator 2 "compare_operator"
10489 [(not:SI (match_operand:SI 3 "register_operand" ""))
10491 (set (match_operand:DI 1 "register_operand" "")
10492 (zero_extend:DI (not:SI (match_dup 3))))]
10493 "ix86_match_ccmode (insn, CCNOmode)"
10494 [(parallel [(set (match_dup 0)
10495 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10498 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10501 (define_expand "one_cmplhi2"
10502 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10503 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10504 "TARGET_HIMODE_MATH"
10505 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10507 (define_insn "*one_cmplhi2_1"
10508 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10509 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10510 "ix86_unary_operator_ok (NOT, HImode, operands)"
10512 [(set_attr "type" "negnot")
10513 (set_attr "mode" "HI")])
10515 (define_insn "*one_cmplhi2_2"
10516 [(set (reg FLAGS_REG)
10517 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10519 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10520 (not:HI (match_dup 1)))]
10521 "ix86_match_ccmode (insn, CCNOmode)
10522 && ix86_unary_operator_ok (NEG, HImode, operands)"
10524 [(set_attr "type" "alu1")
10525 (set_attr "mode" "HI")])
10528 [(set (match_operand 0 "flags_reg_operand" "")
10529 (match_operator 2 "compare_operator"
10530 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10532 (set (match_operand:HI 1 "nonimmediate_operand" "")
10533 (not:HI (match_dup 3)))]
10534 "ix86_match_ccmode (insn, CCNOmode)"
10535 [(parallel [(set (match_dup 0)
10536 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10539 (xor:HI (match_dup 3) (const_int -1)))])]
10542 ;; %%% Potential partial reg stall on alternative 1. What to do?
10543 (define_expand "one_cmplqi2"
10544 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10545 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10546 "TARGET_QIMODE_MATH"
10547 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10549 (define_insn "*one_cmplqi2_1"
10550 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10551 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10552 "ix86_unary_operator_ok (NOT, QImode, operands)"
10556 [(set_attr "type" "negnot")
10557 (set_attr "mode" "QI,SI")])
10559 (define_insn "*one_cmplqi2_2"
10560 [(set (reg FLAGS_REG)
10561 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10563 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10564 (not:QI (match_dup 1)))]
10565 "ix86_match_ccmode (insn, CCNOmode)
10566 && ix86_unary_operator_ok (NOT, QImode, operands)"
10568 [(set_attr "type" "alu1")
10569 (set_attr "mode" "QI")])
10572 [(set (match_operand 0 "flags_reg_operand" "")
10573 (match_operator 2 "compare_operator"
10574 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10576 (set (match_operand:QI 1 "nonimmediate_operand" "")
10577 (not:QI (match_dup 3)))]
10578 "ix86_match_ccmode (insn, CCNOmode)"
10579 [(parallel [(set (match_dup 0)
10580 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10583 (xor:QI (match_dup 3) (const_int -1)))])]
10586 ;; Arithmetic shift instructions
10588 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10589 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10590 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10591 ;; from the assembler input.
10593 ;; This instruction shifts the target reg/mem as usual, but instead of
10594 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10595 ;; is a left shift double, bits are taken from the high order bits of
10596 ;; reg, else if the insn is a shift right double, bits are taken from the
10597 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10598 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10600 ;; Since sh[lr]d does not change the `reg' operand, that is done
10601 ;; separately, making all shifts emit pairs of shift double and normal
10602 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10603 ;; support a 63 bit shift, each shift where the count is in a reg expands
10604 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10606 ;; If the shift count is a constant, we need never emit more than one
10607 ;; shift pair, instead using moves and sign extension for counts greater
10610 (define_expand "ashlti3"
10611 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10612 (ashift:TI (match_operand:TI 1 "register_operand" "")
10613 (match_operand:QI 2 "nonmemory_operand" "")))
10614 (clobber (reg:CC FLAGS_REG))])]
10617 if (! immediate_operand (operands[2], QImode))
10619 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10622 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10626 (define_insn "ashlti3_1"
10627 [(set (match_operand:TI 0 "register_operand" "=r")
10628 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10629 (match_operand:QI 2 "register_operand" "c")))
10630 (clobber (match_scratch:DI 3 "=&r"))
10631 (clobber (reg:CC FLAGS_REG))]
10634 [(set_attr "type" "multi")])
10636 (define_insn "*ashlti3_2"
10637 [(set (match_operand:TI 0 "register_operand" "=r")
10638 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10639 (match_operand:QI 2 "immediate_operand" "O")))
10640 (clobber (reg:CC FLAGS_REG))]
10643 [(set_attr "type" "multi")])
10646 [(set (match_operand:TI 0 "register_operand" "")
10647 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10648 (match_operand:QI 2 "register_operand" "")))
10649 (clobber (match_scratch:DI 3 ""))
10650 (clobber (reg:CC FLAGS_REG))]
10651 "TARGET_64BIT && reload_completed"
10653 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10656 [(set (match_operand:TI 0 "register_operand" "")
10657 (ashift:TI (match_operand:TI 1 "register_operand" "")
10658 (match_operand:QI 2 "immediate_operand" "")))
10659 (clobber (reg:CC FLAGS_REG))]
10660 "TARGET_64BIT && reload_completed"
10662 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10664 (define_insn "x86_64_shld"
10665 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10666 (ior:DI (ashift:DI (match_dup 0)
10667 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10668 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10669 (minus:QI (const_int 64) (match_dup 2)))))
10670 (clobber (reg:CC FLAGS_REG))]
10673 shld{q}\t{%2, %1, %0|%0, %1, %2}
10674 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10675 [(set_attr "type" "ishift")
10676 (set_attr "prefix_0f" "1")
10677 (set_attr "mode" "DI")
10678 (set_attr "athlon_decode" "vector")
10679 (set_attr "amdfam10_decode" "vector")])
10681 (define_expand "x86_64_shift_adj"
10682 [(set (reg:CCZ FLAGS_REG)
10683 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10686 (set (match_operand:DI 0 "register_operand" "")
10687 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10688 (match_operand:DI 1 "register_operand" "")
10691 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10692 (match_operand:DI 3 "register_operand" "r")
10697 (define_expand "ashldi3"
10698 [(set (match_operand:DI 0 "shiftdi_operand" "")
10699 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10700 (match_operand:QI 2 "nonmemory_operand" "")))]
10702 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10704 (define_insn "*ashldi3_1_rex64"
10705 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10706 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10707 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10708 (clobber (reg:CC FLAGS_REG))]
10709 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10711 switch (get_attr_type (insn))
10714 gcc_assert (operands[2] == const1_rtx);
10715 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10716 return "add{q}\t%0, %0";
10719 gcc_assert (CONST_INT_P (operands[2]));
10720 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10721 operands[1] = gen_rtx_MULT (DImode, operands[1],
10722 GEN_INT (1 << INTVAL (operands[2])));
10723 return "lea{q}\t{%a1, %0|%0, %a1}";
10726 if (REG_P (operands[2]))
10727 return "sal{q}\t{%b2, %0|%0, %b2}";
10728 else if (operands[2] == const1_rtx
10729 && (TARGET_SHIFT1 || optimize_size))
10730 return "sal{q}\t%0";
10732 return "sal{q}\t{%2, %0|%0, %2}";
10735 [(set (attr "type")
10736 (cond [(eq_attr "alternative" "1")
10737 (const_string "lea")
10738 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10740 (match_operand 0 "register_operand" ""))
10741 (match_operand 2 "const1_operand" ""))
10742 (const_string "alu")
10744 (const_string "ishift")))
10745 (set_attr "mode" "DI")])
10747 ;; Convert lea to the lea pattern to avoid flags dependency.
10749 [(set (match_operand:DI 0 "register_operand" "")
10750 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10751 (match_operand:QI 2 "immediate_operand" "")))
10752 (clobber (reg:CC FLAGS_REG))]
10753 "TARGET_64BIT && reload_completed
10754 && true_regnum (operands[0]) != true_regnum (operands[1])"
10755 [(set (match_dup 0)
10756 (mult:DI (match_dup 1)
10758 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10760 ;; This pattern can't accept a variable shift count, since shifts by
10761 ;; zero don't affect the flags. We assume that shifts by constant
10762 ;; zero are optimized away.
10763 (define_insn "*ashldi3_cmp_rex64"
10764 [(set (reg FLAGS_REG)
10766 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10767 (match_operand:QI 2 "immediate_operand" "e"))
10769 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10770 (ashift:DI (match_dup 1) (match_dup 2)))]
10771 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10772 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10774 || !TARGET_PARTIAL_FLAG_REG_STALL
10775 || (operands[2] == const1_rtx
10777 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10779 switch (get_attr_type (insn))
10782 gcc_assert (operands[2] == const1_rtx);
10783 return "add{q}\t%0, %0";
10786 if (REG_P (operands[2]))
10787 return "sal{q}\t{%b2, %0|%0, %b2}";
10788 else if (operands[2] == const1_rtx
10789 && (TARGET_SHIFT1 || optimize_size))
10790 return "sal{q}\t%0";
10792 return "sal{q}\t{%2, %0|%0, %2}";
10795 [(set (attr "type")
10796 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10798 (match_operand 0 "register_operand" ""))
10799 (match_operand 2 "const1_operand" ""))
10800 (const_string "alu")
10802 (const_string "ishift")))
10803 (set_attr "mode" "DI")])
10805 (define_insn "*ashldi3_cconly_rex64"
10806 [(set (reg FLAGS_REG)
10808 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10809 (match_operand:QI 2 "immediate_operand" "e"))
10811 (clobber (match_scratch:DI 0 "=r"))]
10812 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10813 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10815 || !TARGET_PARTIAL_FLAG_REG_STALL
10816 || (operands[2] == const1_rtx
10818 || TARGET_DOUBLE_WITH_ADD)))"
10820 switch (get_attr_type (insn))
10823 gcc_assert (operands[2] == const1_rtx);
10824 return "add{q}\t%0, %0";
10827 if (REG_P (operands[2]))
10828 return "sal{q}\t{%b2, %0|%0, %b2}";
10829 else if (operands[2] == const1_rtx
10830 && (TARGET_SHIFT1 || optimize_size))
10831 return "sal{q}\t%0";
10833 return "sal{q}\t{%2, %0|%0, %2}";
10836 [(set (attr "type")
10837 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10839 (match_operand 0 "register_operand" ""))
10840 (match_operand 2 "const1_operand" ""))
10841 (const_string "alu")
10843 (const_string "ishift")))
10844 (set_attr "mode" "DI")])
10846 (define_insn "*ashldi3_1"
10847 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10848 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10849 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10850 (clobber (reg:CC FLAGS_REG))]
10853 [(set_attr "type" "multi")])
10855 ;; By default we don't ask for a scratch register, because when DImode
10856 ;; values are manipulated, registers are already at a premium. But if
10857 ;; we have one handy, we won't turn it away.
10859 [(match_scratch:SI 3 "r")
10860 (parallel [(set (match_operand:DI 0 "register_operand" "")
10861 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10862 (match_operand:QI 2 "nonmemory_operand" "")))
10863 (clobber (reg:CC FLAGS_REG))])
10865 "!TARGET_64BIT && TARGET_CMOVE"
10867 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10870 [(set (match_operand:DI 0 "register_operand" "")
10871 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10872 (match_operand:QI 2 "nonmemory_operand" "")))
10873 (clobber (reg:CC FLAGS_REG))]
10874 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10875 ? flow2_completed : reload_completed)"
10877 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10879 (define_insn "x86_shld_1"
10880 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10881 (ior:SI (ashift:SI (match_dup 0)
10882 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10883 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10884 (minus:QI (const_int 32) (match_dup 2)))))
10885 (clobber (reg:CC FLAGS_REG))]
10888 shld{l}\t{%2, %1, %0|%0, %1, %2}
10889 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10890 [(set_attr "type" "ishift")
10891 (set_attr "prefix_0f" "1")
10892 (set_attr "mode" "SI")
10893 (set_attr "pent_pair" "np")
10894 (set_attr "athlon_decode" "vector")
10895 (set_attr "amdfam10_decode" "vector")])
10897 (define_expand "x86_shift_adj_1"
10898 [(set (reg:CCZ FLAGS_REG)
10899 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10902 (set (match_operand:SI 0 "register_operand" "")
10903 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10904 (match_operand:SI 1 "register_operand" "")
10907 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10908 (match_operand:SI 3 "register_operand" "r")
10913 (define_expand "x86_shift_adj_2"
10914 [(use (match_operand:SI 0 "register_operand" ""))
10915 (use (match_operand:SI 1 "register_operand" ""))
10916 (use (match_operand:QI 2 "register_operand" ""))]
10919 rtx label = gen_label_rtx ();
10922 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10924 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10925 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10926 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10927 gen_rtx_LABEL_REF (VOIDmode, label),
10929 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10930 JUMP_LABEL (tmp) = label;
10932 emit_move_insn (operands[0], operands[1]);
10933 ix86_expand_clear (operands[1]);
10935 emit_label (label);
10936 LABEL_NUSES (label) = 1;
10941 (define_expand "ashlsi3"
10942 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10943 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10944 (match_operand:QI 2 "nonmemory_operand" "")))
10945 (clobber (reg:CC FLAGS_REG))]
10947 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10949 (define_insn "*ashlsi3_1"
10950 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10951 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10952 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10953 (clobber (reg:CC FLAGS_REG))]
10954 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10956 switch (get_attr_type (insn))
10959 gcc_assert (operands[2] == const1_rtx);
10960 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10961 return "add{l}\t%0, %0";
10967 if (REG_P (operands[2]))
10968 return "sal{l}\t{%b2, %0|%0, %b2}";
10969 else if (operands[2] == const1_rtx
10970 && (TARGET_SHIFT1 || optimize_size))
10971 return "sal{l}\t%0";
10973 return "sal{l}\t{%2, %0|%0, %2}";
10976 [(set (attr "type")
10977 (cond [(eq_attr "alternative" "1")
10978 (const_string "lea")
10979 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10981 (match_operand 0 "register_operand" ""))
10982 (match_operand 2 "const1_operand" ""))
10983 (const_string "alu")
10985 (const_string "ishift")))
10986 (set_attr "mode" "SI")])
10988 ;; Convert lea to the lea pattern to avoid flags dependency.
10990 [(set (match_operand 0 "register_operand" "")
10991 (ashift (match_operand 1 "index_register_operand" "")
10992 (match_operand:QI 2 "const_int_operand" "")))
10993 (clobber (reg:CC FLAGS_REG))]
10995 && true_regnum (operands[0]) != true_regnum (operands[1])
10996 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11000 enum machine_mode mode = GET_MODE (operands[0]);
11002 if (GET_MODE_SIZE (mode) < 4)
11003 operands[0] = gen_lowpart (SImode, operands[0]);
11005 operands[1] = gen_lowpart (Pmode, operands[1]);
11006 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11008 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11009 if (Pmode != SImode)
11010 pat = gen_rtx_SUBREG (SImode, pat, 0);
11011 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11015 ;; Rare case of shifting RSP is handled by generating move and shift
11017 [(set (match_operand 0 "register_operand" "")
11018 (ashift (match_operand 1 "register_operand" "")
11019 (match_operand:QI 2 "const_int_operand" "")))
11020 (clobber (reg:CC FLAGS_REG))]
11022 && true_regnum (operands[0]) != true_regnum (operands[1])"
11026 emit_move_insn (operands[0], operands[1]);
11027 pat = gen_rtx_SET (VOIDmode, operands[0],
11028 gen_rtx_ASHIFT (GET_MODE (operands[0]),
11029 operands[0], operands[2]));
11030 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11031 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11035 (define_insn "*ashlsi3_1_zext"
11036 [(set (match_operand:DI 0 "register_operand" "=r,r")
11037 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11038 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11039 (clobber (reg:CC FLAGS_REG))]
11040 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11042 switch (get_attr_type (insn))
11045 gcc_assert (operands[2] == const1_rtx);
11046 return "add{l}\t%k0, %k0";
11052 if (REG_P (operands[2]))
11053 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11054 else if (operands[2] == const1_rtx
11055 && (TARGET_SHIFT1 || optimize_size))
11056 return "sal{l}\t%k0";
11058 return "sal{l}\t{%2, %k0|%k0, %2}";
11061 [(set (attr "type")
11062 (cond [(eq_attr "alternative" "1")
11063 (const_string "lea")
11064 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11066 (match_operand 2 "const1_operand" ""))
11067 (const_string "alu")
11069 (const_string "ishift")))
11070 (set_attr "mode" "SI")])
11072 ;; Convert lea to the lea pattern to avoid flags dependency.
11074 [(set (match_operand:DI 0 "register_operand" "")
11075 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11076 (match_operand:QI 2 "const_int_operand" ""))))
11077 (clobber (reg:CC FLAGS_REG))]
11078 "TARGET_64BIT && reload_completed
11079 && true_regnum (operands[0]) != true_regnum (operands[1])"
11080 [(set (match_dup 0) (zero_extend:DI
11081 (subreg:SI (mult:SI (match_dup 1)
11082 (match_dup 2)) 0)))]
11084 operands[1] = gen_lowpart (Pmode, operands[1]);
11085 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11088 ;; This pattern can't accept a variable shift count, since shifts by
11089 ;; zero don't affect the flags. We assume that shifts by constant
11090 ;; zero are optimized away.
11091 (define_insn "*ashlsi3_cmp"
11092 [(set (reg FLAGS_REG)
11094 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11095 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11097 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11098 (ashift:SI (match_dup 1) (match_dup 2)))]
11099 "ix86_match_ccmode (insn, CCGOCmode)
11100 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11102 || !TARGET_PARTIAL_FLAG_REG_STALL
11103 || (operands[2] == const1_rtx
11105 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11107 switch (get_attr_type (insn))
11110 gcc_assert (operands[2] == const1_rtx);
11111 return "add{l}\t%0, %0";
11114 if (REG_P (operands[2]))
11115 return "sal{l}\t{%b2, %0|%0, %b2}";
11116 else if (operands[2] == const1_rtx
11117 && (TARGET_SHIFT1 || optimize_size))
11118 return "sal{l}\t%0";
11120 return "sal{l}\t{%2, %0|%0, %2}";
11123 [(set (attr "type")
11124 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11126 (match_operand 0 "register_operand" ""))
11127 (match_operand 2 "const1_operand" ""))
11128 (const_string "alu")
11130 (const_string "ishift")))
11131 (set_attr "mode" "SI")])
11133 (define_insn "*ashlsi3_cconly"
11134 [(set (reg FLAGS_REG)
11136 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11137 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11139 (clobber (match_scratch:SI 0 "=r"))]
11140 "ix86_match_ccmode (insn, CCGOCmode)
11141 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11143 || !TARGET_PARTIAL_FLAG_REG_STALL
11144 || (operands[2] == const1_rtx
11146 || TARGET_DOUBLE_WITH_ADD)))"
11148 switch (get_attr_type (insn))
11151 gcc_assert (operands[2] == const1_rtx);
11152 return "add{l}\t%0, %0";
11155 if (REG_P (operands[2]))
11156 return "sal{l}\t{%b2, %0|%0, %b2}";
11157 else if (operands[2] == const1_rtx
11158 && (TARGET_SHIFT1 || optimize_size))
11159 return "sal{l}\t%0";
11161 return "sal{l}\t{%2, %0|%0, %2}";
11164 [(set (attr "type")
11165 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11167 (match_operand 0 "register_operand" ""))
11168 (match_operand 2 "const1_operand" ""))
11169 (const_string "alu")
11171 (const_string "ishift")))
11172 (set_attr "mode" "SI")])
11174 (define_insn "*ashlsi3_cmp_zext"
11175 [(set (reg FLAGS_REG)
11177 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11178 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11180 (set (match_operand:DI 0 "register_operand" "=r")
11181 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11182 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11183 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
11185 || !TARGET_PARTIAL_FLAG_REG_STALL
11186 || (operands[2] == const1_rtx
11188 || TARGET_DOUBLE_WITH_ADD)))"
11190 switch (get_attr_type (insn))
11193 gcc_assert (operands[2] == const1_rtx);
11194 return "add{l}\t%k0, %k0";
11197 if (REG_P (operands[2]))
11198 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11199 else if (operands[2] == const1_rtx
11200 && (TARGET_SHIFT1 || optimize_size))
11201 return "sal{l}\t%k0";
11203 return "sal{l}\t{%2, %k0|%k0, %2}";
11206 [(set (attr "type")
11207 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11209 (match_operand 2 "const1_operand" ""))
11210 (const_string "alu")
11212 (const_string "ishift")))
11213 (set_attr "mode" "SI")])
11215 (define_expand "ashlhi3"
11216 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11217 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11218 (match_operand:QI 2 "nonmemory_operand" "")))
11219 (clobber (reg:CC FLAGS_REG))]
11220 "TARGET_HIMODE_MATH"
11221 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11223 (define_insn "*ashlhi3_1_lea"
11224 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11225 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11226 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11227 (clobber (reg:CC FLAGS_REG))]
11228 "!TARGET_PARTIAL_REG_STALL
11229 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11231 switch (get_attr_type (insn))
11236 gcc_assert (operands[2] == const1_rtx);
11237 return "add{w}\t%0, %0";
11240 if (REG_P (operands[2]))
11241 return "sal{w}\t{%b2, %0|%0, %b2}";
11242 else if (operands[2] == const1_rtx
11243 && (TARGET_SHIFT1 || optimize_size))
11244 return "sal{w}\t%0";
11246 return "sal{w}\t{%2, %0|%0, %2}";
11249 [(set (attr "type")
11250 (cond [(eq_attr "alternative" "1")
11251 (const_string "lea")
11252 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11254 (match_operand 0 "register_operand" ""))
11255 (match_operand 2 "const1_operand" ""))
11256 (const_string "alu")
11258 (const_string "ishift")))
11259 (set_attr "mode" "HI,SI")])
11261 (define_insn "*ashlhi3_1"
11262 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11263 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11264 (match_operand:QI 2 "nonmemory_operand" "cI")))
11265 (clobber (reg:CC FLAGS_REG))]
11266 "TARGET_PARTIAL_REG_STALL
11267 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11269 switch (get_attr_type (insn))
11272 gcc_assert (operands[2] == const1_rtx);
11273 return "add{w}\t%0, %0";
11276 if (REG_P (operands[2]))
11277 return "sal{w}\t{%b2, %0|%0, %b2}";
11278 else if (operands[2] == const1_rtx
11279 && (TARGET_SHIFT1 || optimize_size))
11280 return "sal{w}\t%0";
11282 return "sal{w}\t{%2, %0|%0, %2}";
11285 [(set (attr "type")
11286 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11288 (match_operand 0 "register_operand" ""))
11289 (match_operand 2 "const1_operand" ""))
11290 (const_string "alu")
11292 (const_string "ishift")))
11293 (set_attr "mode" "HI")])
11295 ;; This pattern can't accept a variable shift count, since shifts by
11296 ;; zero don't affect the flags. We assume that shifts by constant
11297 ;; zero are optimized away.
11298 (define_insn "*ashlhi3_cmp"
11299 [(set (reg FLAGS_REG)
11301 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11302 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11304 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11305 (ashift:HI (match_dup 1) (match_dup 2)))]
11306 "ix86_match_ccmode (insn, CCGOCmode)
11307 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11309 || !TARGET_PARTIAL_FLAG_REG_STALL
11310 || (operands[2] == const1_rtx
11312 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11314 switch (get_attr_type (insn))
11317 gcc_assert (operands[2] == const1_rtx);
11318 return "add{w}\t%0, %0";
11321 if (REG_P (operands[2]))
11322 return "sal{w}\t{%b2, %0|%0, %b2}";
11323 else if (operands[2] == const1_rtx
11324 && (TARGET_SHIFT1 || optimize_size))
11325 return "sal{w}\t%0";
11327 return "sal{w}\t{%2, %0|%0, %2}";
11330 [(set (attr "type")
11331 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11333 (match_operand 0 "register_operand" ""))
11334 (match_operand 2 "const1_operand" ""))
11335 (const_string "alu")
11337 (const_string "ishift")))
11338 (set_attr "mode" "HI")])
11340 (define_insn "*ashlhi3_cconly"
11341 [(set (reg FLAGS_REG)
11343 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11344 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11346 (clobber (match_scratch:HI 0 "=r"))]
11347 "ix86_match_ccmode (insn, CCGOCmode)
11348 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11350 || !TARGET_PARTIAL_FLAG_REG_STALL
11351 || (operands[2] == const1_rtx
11353 || TARGET_DOUBLE_WITH_ADD)))"
11355 switch (get_attr_type (insn))
11358 gcc_assert (operands[2] == const1_rtx);
11359 return "add{w}\t%0, %0";
11362 if (REG_P (operands[2]))
11363 return "sal{w}\t{%b2, %0|%0, %b2}";
11364 else if (operands[2] == const1_rtx
11365 && (TARGET_SHIFT1 || optimize_size))
11366 return "sal{w}\t%0";
11368 return "sal{w}\t{%2, %0|%0, %2}";
11371 [(set (attr "type")
11372 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11374 (match_operand 0 "register_operand" ""))
11375 (match_operand 2 "const1_operand" ""))
11376 (const_string "alu")
11378 (const_string "ishift")))
11379 (set_attr "mode" "HI")])
11381 (define_expand "ashlqi3"
11382 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11383 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11384 (match_operand:QI 2 "nonmemory_operand" "")))
11385 (clobber (reg:CC FLAGS_REG))]
11386 "TARGET_QIMODE_MATH"
11387 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11389 ;; %%% Potential partial reg stall on alternative 2. What to do?
11391 (define_insn "*ashlqi3_1_lea"
11392 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11393 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11394 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11395 (clobber (reg:CC FLAGS_REG))]
11396 "!TARGET_PARTIAL_REG_STALL
11397 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11399 switch (get_attr_type (insn))
11404 gcc_assert (operands[2] == const1_rtx);
11405 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11406 return "add{l}\t%k0, %k0";
11408 return "add{b}\t%0, %0";
11411 if (REG_P (operands[2]))
11413 if (get_attr_mode (insn) == MODE_SI)
11414 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11416 return "sal{b}\t{%b2, %0|%0, %b2}";
11418 else if (operands[2] == const1_rtx
11419 && (TARGET_SHIFT1 || optimize_size))
11421 if (get_attr_mode (insn) == MODE_SI)
11422 return "sal{l}\t%0";
11424 return "sal{b}\t%0";
11428 if (get_attr_mode (insn) == MODE_SI)
11429 return "sal{l}\t{%2, %k0|%k0, %2}";
11431 return "sal{b}\t{%2, %0|%0, %2}";
11435 [(set (attr "type")
11436 (cond [(eq_attr "alternative" "2")
11437 (const_string "lea")
11438 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11440 (match_operand 0 "register_operand" ""))
11441 (match_operand 2 "const1_operand" ""))
11442 (const_string "alu")
11444 (const_string "ishift")))
11445 (set_attr "mode" "QI,SI,SI")])
11447 (define_insn "*ashlqi3_1"
11448 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11449 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11450 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11451 (clobber (reg:CC FLAGS_REG))]
11452 "TARGET_PARTIAL_REG_STALL
11453 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11455 switch (get_attr_type (insn))
11458 gcc_assert (operands[2] == const1_rtx);
11459 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11460 return "add{l}\t%k0, %k0";
11462 return "add{b}\t%0, %0";
11465 if (REG_P (operands[2]))
11467 if (get_attr_mode (insn) == MODE_SI)
11468 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11470 return "sal{b}\t{%b2, %0|%0, %b2}";
11472 else if (operands[2] == const1_rtx
11473 && (TARGET_SHIFT1 || optimize_size))
11475 if (get_attr_mode (insn) == MODE_SI)
11476 return "sal{l}\t%0";
11478 return "sal{b}\t%0";
11482 if (get_attr_mode (insn) == MODE_SI)
11483 return "sal{l}\t{%2, %k0|%k0, %2}";
11485 return "sal{b}\t{%2, %0|%0, %2}";
11489 [(set (attr "type")
11490 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11492 (match_operand 0 "register_operand" ""))
11493 (match_operand 2 "const1_operand" ""))
11494 (const_string "alu")
11496 (const_string "ishift")))
11497 (set_attr "mode" "QI,SI")])
11499 ;; This pattern can't accept a variable shift count, since shifts by
11500 ;; zero don't affect the flags. We assume that shifts by constant
11501 ;; zero are optimized away.
11502 (define_insn "*ashlqi3_cmp"
11503 [(set (reg FLAGS_REG)
11505 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11506 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11508 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11509 (ashift:QI (match_dup 1) (match_dup 2)))]
11510 "ix86_match_ccmode (insn, CCGOCmode)
11511 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11513 || !TARGET_PARTIAL_FLAG_REG_STALL
11514 || (operands[2] == const1_rtx
11516 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11518 switch (get_attr_type (insn))
11521 gcc_assert (operands[2] == const1_rtx);
11522 return "add{b}\t%0, %0";
11525 if (REG_P (operands[2]))
11526 return "sal{b}\t{%b2, %0|%0, %b2}";
11527 else if (operands[2] == const1_rtx
11528 && (TARGET_SHIFT1 || optimize_size))
11529 return "sal{b}\t%0";
11531 return "sal{b}\t{%2, %0|%0, %2}";
11534 [(set (attr "type")
11535 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11537 (match_operand 0 "register_operand" ""))
11538 (match_operand 2 "const1_operand" ""))
11539 (const_string "alu")
11541 (const_string "ishift")))
11542 (set_attr "mode" "QI")])
11544 (define_insn "*ashlqi3_cconly"
11545 [(set (reg FLAGS_REG)
11547 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11548 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11550 (clobber (match_scratch:QI 0 "=q"))]
11551 "ix86_match_ccmode (insn, CCGOCmode)
11552 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11554 || !TARGET_PARTIAL_FLAG_REG_STALL
11555 || (operands[2] == const1_rtx
11557 || TARGET_DOUBLE_WITH_ADD)))"
11559 switch (get_attr_type (insn))
11562 gcc_assert (operands[2] == const1_rtx);
11563 return "add{b}\t%0, %0";
11566 if (REG_P (operands[2]))
11567 return "sal{b}\t{%b2, %0|%0, %b2}";
11568 else if (operands[2] == const1_rtx
11569 && (TARGET_SHIFT1 || optimize_size))
11570 return "sal{b}\t%0";
11572 return "sal{b}\t{%2, %0|%0, %2}";
11575 [(set (attr "type")
11576 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11578 (match_operand 0 "register_operand" ""))
11579 (match_operand 2 "const1_operand" ""))
11580 (const_string "alu")
11582 (const_string "ishift")))
11583 (set_attr "mode" "QI")])
11585 ;; See comment above `ashldi3' about how this works.
11587 (define_expand "ashrti3"
11588 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11589 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11590 (match_operand:QI 2 "nonmemory_operand" "")))
11591 (clobber (reg:CC FLAGS_REG))])]
11594 if (! immediate_operand (operands[2], QImode))
11596 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11599 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11603 (define_insn "ashrti3_1"
11604 [(set (match_operand:TI 0 "register_operand" "=r")
11605 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11606 (match_operand:QI 2 "register_operand" "c")))
11607 (clobber (match_scratch:DI 3 "=&r"))
11608 (clobber (reg:CC FLAGS_REG))]
11611 [(set_attr "type" "multi")])
11613 (define_insn "*ashrti3_2"
11614 [(set (match_operand:TI 0 "register_operand" "=r")
11615 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11616 (match_operand:QI 2 "immediate_operand" "O")))
11617 (clobber (reg:CC FLAGS_REG))]
11620 [(set_attr "type" "multi")])
11623 [(set (match_operand:TI 0 "register_operand" "")
11624 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11625 (match_operand:QI 2 "register_operand" "")))
11626 (clobber (match_scratch:DI 3 ""))
11627 (clobber (reg:CC FLAGS_REG))]
11628 "TARGET_64BIT && reload_completed"
11630 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11633 [(set (match_operand:TI 0 "register_operand" "")
11634 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11635 (match_operand:QI 2 "immediate_operand" "")))
11636 (clobber (reg:CC FLAGS_REG))]
11637 "TARGET_64BIT && reload_completed"
11639 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11641 (define_insn "x86_64_shrd"
11642 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11643 (ior:DI (ashiftrt:DI (match_dup 0)
11644 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11645 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11646 (minus:QI (const_int 64) (match_dup 2)))))
11647 (clobber (reg:CC FLAGS_REG))]
11650 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11651 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11652 [(set_attr "type" "ishift")
11653 (set_attr "prefix_0f" "1")
11654 (set_attr "mode" "DI")
11655 (set_attr "athlon_decode" "vector")
11656 (set_attr "amdfam10_decode" "vector")])
11658 (define_expand "ashrdi3"
11659 [(set (match_operand:DI 0 "shiftdi_operand" "")
11660 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11661 (match_operand:QI 2 "nonmemory_operand" "")))]
11663 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11665 (define_insn "*ashrdi3_63_rex64"
11666 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11667 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11668 (match_operand:DI 2 "const_int_operand" "i,i")))
11669 (clobber (reg:CC FLAGS_REG))]
11670 "TARGET_64BIT && INTVAL (operands[2]) == 63
11671 && (TARGET_USE_CLTD || optimize_size)
11672 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11675 sar{q}\t{%2, %0|%0, %2}"
11676 [(set_attr "type" "imovx,ishift")
11677 (set_attr "prefix_0f" "0,*")
11678 (set_attr "length_immediate" "0,*")
11679 (set_attr "modrm" "0,1")
11680 (set_attr "mode" "DI")])
11682 (define_insn "*ashrdi3_1_one_bit_rex64"
11683 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11684 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11685 (match_operand:QI 2 "const1_operand" "")))
11686 (clobber (reg:CC FLAGS_REG))]
11687 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11688 && (TARGET_SHIFT1 || optimize_size)"
11690 [(set_attr "type" "ishift")
11691 (set (attr "length")
11692 (if_then_else (match_operand:DI 0 "register_operand" "")
11694 (const_string "*")))])
11696 (define_insn "*ashrdi3_1_rex64"
11697 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11698 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11699 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11700 (clobber (reg:CC FLAGS_REG))]
11701 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11703 sar{q}\t{%2, %0|%0, %2}
11704 sar{q}\t{%b2, %0|%0, %b2}"
11705 [(set_attr "type" "ishift")
11706 (set_attr "mode" "DI")])
11708 ;; This pattern can't accept a variable shift count, since shifts by
11709 ;; zero don't affect the flags. We assume that shifts by constant
11710 ;; zero are optimized away.
11711 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11712 [(set (reg FLAGS_REG)
11714 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11715 (match_operand:QI 2 "const1_operand" ""))
11717 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11718 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11719 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11720 && (TARGET_SHIFT1 || optimize_size)
11721 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11723 [(set_attr "type" "ishift")
11724 (set (attr "length")
11725 (if_then_else (match_operand:DI 0 "register_operand" "")
11727 (const_string "*")))])
11729 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11730 [(set (reg FLAGS_REG)
11732 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11733 (match_operand:QI 2 "const1_operand" ""))
11735 (clobber (match_scratch:DI 0 "=r"))]
11736 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11737 && (TARGET_SHIFT1 || optimize_size)
11738 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11740 [(set_attr "type" "ishift")
11741 (set_attr "length" "2")])
11743 ;; This pattern can't accept a variable shift count, since shifts by
11744 ;; zero don't affect the flags. We assume that shifts by constant
11745 ;; zero are optimized away.
11746 (define_insn "*ashrdi3_cmp_rex64"
11747 [(set (reg FLAGS_REG)
11749 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11750 (match_operand:QI 2 "const_int_operand" "n"))
11752 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11753 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11754 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11755 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11757 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11758 "sar{q}\t{%2, %0|%0, %2}"
11759 [(set_attr "type" "ishift")
11760 (set_attr "mode" "DI")])
11762 (define_insn "*ashrdi3_cconly_rex64"
11763 [(set (reg FLAGS_REG)
11765 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11766 (match_operand:QI 2 "const_int_operand" "n"))
11768 (clobber (match_scratch:DI 0 "=r"))]
11769 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11770 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11772 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11773 "sar{q}\t{%2, %0|%0, %2}"
11774 [(set_attr "type" "ishift")
11775 (set_attr "mode" "DI")])
11777 (define_insn "*ashrdi3_1"
11778 [(set (match_operand:DI 0 "register_operand" "=r")
11779 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11780 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11781 (clobber (reg:CC FLAGS_REG))]
11784 [(set_attr "type" "multi")])
11786 ;; By default we don't ask for a scratch register, because when DImode
11787 ;; values are manipulated, registers are already at a premium. But if
11788 ;; we have one handy, we won't turn it away.
11790 [(match_scratch:SI 3 "r")
11791 (parallel [(set (match_operand:DI 0 "register_operand" "")
11792 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11793 (match_operand:QI 2 "nonmemory_operand" "")))
11794 (clobber (reg:CC FLAGS_REG))])
11796 "!TARGET_64BIT && TARGET_CMOVE"
11798 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11801 [(set (match_operand:DI 0 "register_operand" "")
11802 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11803 (match_operand:QI 2 "nonmemory_operand" "")))
11804 (clobber (reg:CC FLAGS_REG))]
11805 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11806 ? flow2_completed : reload_completed)"
11808 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11810 (define_insn "x86_shrd_1"
11811 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11812 (ior:SI (ashiftrt:SI (match_dup 0)
11813 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11814 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11815 (minus:QI (const_int 32) (match_dup 2)))))
11816 (clobber (reg:CC FLAGS_REG))]
11819 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11820 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11821 [(set_attr "type" "ishift")
11822 (set_attr "prefix_0f" "1")
11823 (set_attr "pent_pair" "np")
11824 (set_attr "mode" "SI")])
11826 (define_expand "x86_shift_adj_3"
11827 [(use (match_operand:SI 0 "register_operand" ""))
11828 (use (match_operand:SI 1 "register_operand" ""))
11829 (use (match_operand:QI 2 "register_operand" ""))]
11832 rtx label = gen_label_rtx ();
11835 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11837 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11838 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11839 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11840 gen_rtx_LABEL_REF (VOIDmode, label),
11842 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11843 JUMP_LABEL (tmp) = label;
11845 emit_move_insn (operands[0], operands[1]);
11846 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11848 emit_label (label);
11849 LABEL_NUSES (label) = 1;
11854 (define_insn "ashrsi3_31"
11855 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11856 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11857 (match_operand:SI 2 "const_int_operand" "i,i")))
11858 (clobber (reg:CC FLAGS_REG))]
11859 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11860 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11863 sar{l}\t{%2, %0|%0, %2}"
11864 [(set_attr "type" "imovx,ishift")
11865 (set_attr "prefix_0f" "0,*")
11866 (set_attr "length_immediate" "0,*")
11867 (set_attr "modrm" "0,1")
11868 (set_attr "mode" "SI")])
11870 (define_insn "*ashrsi3_31_zext"
11871 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11872 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11873 (match_operand:SI 2 "const_int_operand" "i,i"))))
11874 (clobber (reg:CC FLAGS_REG))]
11875 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11876 && INTVAL (operands[2]) == 31
11877 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11880 sar{l}\t{%2, %k0|%k0, %2}"
11881 [(set_attr "type" "imovx,ishift")
11882 (set_attr "prefix_0f" "0,*")
11883 (set_attr "length_immediate" "0,*")
11884 (set_attr "modrm" "0,1")
11885 (set_attr "mode" "SI")])
11887 (define_expand "ashrsi3"
11888 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11889 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11890 (match_operand:QI 2 "nonmemory_operand" "")))
11891 (clobber (reg:CC FLAGS_REG))]
11893 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11895 (define_insn "*ashrsi3_1_one_bit"
11896 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11897 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11898 (match_operand:QI 2 "const1_operand" "")))
11899 (clobber (reg:CC FLAGS_REG))]
11900 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11901 && (TARGET_SHIFT1 || optimize_size)"
11903 [(set_attr "type" "ishift")
11904 (set (attr "length")
11905 (if_then_else (match_operand:SI 0 "register_operand" "")
11907 (const_string "*")))])
11909 (define_insn "*ashrsi3_1_one_bit_zext"
11910 [(set (match_operand:DI 0 "register_operand" "=r")
11911 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11912 (match_operand:QI 2 "const1_operand" ""))))
11913 (clobber (reg:CC FLAGS_REG))]
11914 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11915 && (TARGET_SHIFT1 || optimize_size)"
11917 [(set_attr "type" "ishift")
11918 (set_attr "length" "2")])
11920 (define_insn "*ashrsi3_1"
11921 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11922 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11923 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11924 (clobber (reg:CC FLAGS_REG))]
11925 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11927 sar{l}\t{%2, %0|%0, %2}
11928 sar{l}\t{%b2, %0|%0, %b2}"
11929 [(set_attr "type" "ishift")
11930 (set_attr "mode" "SI")])
11932 (define_insn "*ashrsi3_1_zext"
11933 [(set (match_operand:DI 0 "register_operand" "=r,r")
11934 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11935 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11936 (clobber (reg:CC FLAGS_REG))]
11937 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11939 sar{l}\t{%2, %k0|%k0, %2}
11940 sar{l}\t{%b2, %k0|%k0, %b2}"
11941 [(set_attr "type" "ishift")
11942 (set_attr "mode" "SI")])
11944 ;; This pattern can't accept a variable shift count, since shifts by
11945 ;; zero don't affect the flags. We assume that shifts by constant
11946 ;; zero are optimized away.
11947 (define_insn "*ashrsi3_one_bit_cmp"
11948 [(set (reg FLAGS_REG)
11950 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11951 (match_operand:QI 2 "const1_operand" ""))
11953 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11954 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11955 "ix86_match_ccmode (insn, CCGOCmode)
11956 && (TARGET_SHIFT1 || optimize_size)
11957 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11959 [(set_attr "type" "ishift")
11960 (set (attr "length")
11961 (if_then_else (match_operand:SI 0 "register_operand" "")
11963 (const_string "*")))])
11965 (define_insn "*ashrsi3_one_bit_cconly"
11966 [(set (reg FLAGS_REG)
11968 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11969 (match_operand:QI 2 "const1_operand" ""))
11971 (clobber (match_scratch:SI 0 "=r"))]
11972 "ix86_match_ccmode (insn, CCGOCmode)
11973 && (TARGET_SHIFT1 || optimize_size)
11974 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11976 [(set_attr "type" "ishift")
11977 (set_attr "length" "2")])
11979 (define_insn "*ashrsi3_one_bit_cmp_zext"
11980 [(set (reg FLAGS_REG)
11982 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11983 (match_operand:QI 2 "const1_operand" ""))
11985 (set (match_operand:DI 0 "register_operand" "=r")
11986 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11987 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11988 && (TARGET_SHIFT1 || optimize_size)
11989 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11991 [(set_attr "type" "ishift")
11992 (set_attr "length" "2")])
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags. We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*ashrsi3_cmp"
11998 [(set (reg FLAGS_REG)
12000 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12001 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12003 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12004 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12005 "ix86_match_ccmode (insn, CCGOCmode)
12006 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12008 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12009 "sar{l}\t{%2, %0|%0, %2}"
12010 [(set_attr "type" "ishift")
12011 (set_attr "mode" "SI")])
12013 (define_insn "*ashrsi3_cconly"
12014 [(set (reg FLAGS_REG)
12016 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12017 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12019 (clobber (match_scratch:SI 0 "=r"))]
12020 "ix86_match_ccmode (insn, CCGOCmode)
12021 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12023 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12024 "sar{l}\t{%2, %0|%0, %2}"
12025 [(set_attr "type" "ishift")
12026 (set_attr "mode" "SI")])
12028 (define_insn "*ashrsi3_cmp_zext"
12029 [(set (reg FLAGS_REG)
12031 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12032 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12034 (set (match_operand:DI 0 "register_operand" "=r")
12035 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12036 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12037 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
12039 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12040 "sar{l}\t{%2, %k0|%k0, %2}"
12041 [(set_attr "type" "ishift")
12042 (set_attr "mode" "SI")])
12044 (define_expand "ashrhi3"
12045 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12046 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12047 (match_operand:QI 2 "nonmemory_operand" "")))
12048 (clobber (reg:CC FLAGS_REG))]
12049 "TARGET_HIMODE_MATH"
12050 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12052 (define_insn "*ashrhi3_1_one_bit"
12053 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12054 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12055 (match_operand:QI 2 "const1_operand" "")))
12056 (clobber (reg:CC FLAGS_REG))]
12057 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12058 && (TARGET_SHIFT1 || optimize_size)"
12060 [(set_attr "type" "ishift")
12061 (set (attr "length")
12062 (if_then_else (match_operand 0 "register_operand" "")
12064 (const_string "*")))])
12066 (define_insn "*ashrhi3_1"
12067 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12068 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12069 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12070 (clobber (reg:CC FLAGS_REG))]
12071 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12073 sar{w}\t{%2, %0|%0, %2}
12074 sar{w}\t{%b2, %0|%0, %b2}"
12075 [(set_attr "type" "ishift")
12076 (set_attr "mode" "HI")])
12078 ;; This pattern can't accept a variable shift count, since shifts by
12079 ;; zero don't affect the flags. We assume that shifts by constant
12080 ;; zero are optimized away.
12081 (define_insn "*ashrhi3_one_bit_cmp"
12082 [(set (reg FLAGS_REG)
12084 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12085 (match_operand:QI 2 "const1_operand" ""))
12087 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12088 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12089 "ix86_match_ccmode (insn, CCGOCmode)
12090 && (TARGET_SHIFT1 || optimize_size)
12091 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12093 [(set_attr "type" "ishift")
12094 (set (attr "length")
12095 (if_then_else (match_operand 0 "register_operand" "")
12097 (const_string "*")))])
12099 (define_insn "*ashrhi3_one_bit_cconly"
12100 [(set (reg FLAGS_REG)
12102 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12103 (match_operand:QI 2 "const1_operand" ""))
12105 (clobber (match_scratch:HI 0 "=r"))]
12106 "ix86_match_ccmode (insn, CCGOCmode)
12107 && (TARGET_SHIFT1 || optimize_size)
12108 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12110 [(set_attr "type" "ishift")
12111 (set_attr "length" "2")])
12113 ;; This pattern can't accept a variable shift count, since shifts by
12114 ;; zero don't affect the flags. We assume that shifts by constant
12115 ;; zero are optimized away.
12116 (define_insn "*ashrhi3_cmp"
12117 [(set (reg FLAGS_REG)
12119 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12120 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12122 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12123 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12124 "ix86_match_ccmode (insn, CCGOCmode)
12125 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12127 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12128 "sar{w}\t{%2, %0|%0, %2}"
12129 [(set_attr "type" "ishift")
12130 (set_attr "mode" "HI")])
12132 (define_insn "*ashrhi3_cconly"
12133 [(set (reg FLAGS_REG)
12135 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12136 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12138 (clobber (match_scratch:HI 0 "=r"))]
12139 "ix86_match_ccmode (insn, CCGOCmode)
12140 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
12142 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12143 "sar{w}\t{%2, %0|%0, %2}"
12144 [(set_attr "type" "ishift")
12145 (set_attr "mode" "HI")])
12147 (define_expand "ashrqi3"
12148 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12149 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12150 (match_operand:QI 2 "nonmemory_operand" "")))
12151 (clobber (reg:CC FLAGS_REG))]
12152 "TARGET_QIMODE_MATH"
12153 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12155 (define_insn "*ashrqi3_1_one_bit"
12156 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12157 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12158 (match_operand:QI 2 "const1_operand" "")))
12159 (clobber (reg:CC FLAGS_REG))]
12160 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12161 && (TARGET_SHIFT1 || optimize_size)"
12163 [(set_attr "type" "ishift")
12164 (set (attr "length")
12165 (if_then_else (match_operand 0 "register_operand" "")
12167 (const_string "*")))])
12169 (define_insn "*ashrqi3_1_one_bit_slp"
12170 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12171 (ashiftrt:QI (match_dup 0)
12172 (match_operand:QI 1 "const1_operand" "")))
12173 (clobber (reg:CC FLAGS_REG))]
12174 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12175 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
12176 && (TARGET_SHIFT1 || optimize_size)"
12178 [(set_attr "type" "ishift1")
12179 (set (attr "length")
12180 (if_then_else (match_operand 0 "register_operand" "")
12182 (const_string "*")))])
12184 (define_insn "*ashrqi3_1"
12185 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12186 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12187 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12188 (clobber (reg:CC FLAGS_REG))]
12189 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12191 sar{b}\t{%2, %0|%0, %2}
12192 sar{b}\t{%b2, %0|%0, %b2}"
12193 [(set_attr "type" "ishift")
12194 (set_attr "mode" "QI")])
12196 (define_insn "*ashrqi3_1_slp"
12197 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12198 (ashiftrt:QI (match_dup 0)
12199 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12200 (clobber (reg:CC FLAGS_REG))]
12201 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12202 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12204 sar{b}\t{%1, %0|%0, %1}
12205 sar{b}\t{%b1, %0|%0, %b1}"
12206 [(set_attr "type" "ishift1")
12207 (set_attr "mode" "QI")])
12209 ;; This pattern can't accept a variable shift count, since shifts by
12210 ;; zero don't affect the flags. We assume that shifts by constant
12211 ;; zero are optimized away.
12212 (define_insn "*ashrqi3_one_bit_cmp"
12213 [(set (reg FLAGS_REG)
12215 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12216 (match_operand:QI 2 "const1_operand" "I"))
12218 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12219 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12220 "ix86_match_ccmode (insn, CCGOCmode)
12221 && (TARGET_SHIFT1 || optimize_size)
12222 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12224 [(set_attr "type" "ishift")
12225 (set (attr "length")
12226 (if_then_else (match_operand 0 "register_operand" "")
12228 (const_string "*")))])
12230 (define_insn "*ashrqi3_one_bit_cconly"
12231 [(set (reg FLAGS_REG)
12233 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12234 (match_operand:QI 2 "const1_operand" "I"))
12236 (clobber (match_scratch:QI 0 "=q"))]
12237 "ix86_match_ccmode (insn, CCGOCmode)
12238 && (TARGET_SHIFT1 || optimize_size)
12239 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12241 [(set_attr "type" "ishift")
12242 (set_attr "length" "2")])
12244 ;; This pattern can't accept a variable shift count, since shifts by
12245 ;; zero don't affect the flags. We assume that shifts by constant
12246 ;; zero are optimized away.
12247 (define_insn "*ashrqi3_cmp"
12248 [(set (reg FLAGS_REG)
12250 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12251 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12253 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12254 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12255 "ix86_match_ccmode (insn, CCGOCmode)
12256 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12258 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12259 "sar{b}\t{%2, %0|%0, %2}"
12260 [(set_attr "type" "ishift")
12261 (set_attr "mode" "QI")])
12263 (define_insn "*ashrqi3_cconly"
12264 [(set (reg FLAGS_REG)
12266 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12267 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12269 (clobber (match_scratch:QI 0 "=q"))]
12270 "ix86_match_ccmode (insn, CCGOCmode)
12271 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
12273 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12274 "sar{b}\t{%2, %0|%0, %2}"
12275 [(set_attr "type" "ishift")
12276 (set_attr "mode" "QI")])
12279 ;; Logical shift instructions
12281 ;; See comment above `ashldi3' about how this works.
12283 (define_expand "lshrti3"
12284 [(parallel [(set (match_operand:TI 0 "register_operand" "")
12285 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12286 (match_operand:QI 2 "nonmemory_operand" "")))
12287 (clobber (reg:CC FLAGS_REG))])]
12290 if (! immediate_operand (operands[2], QImode))
12292 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12295 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12299 (define_insn "lshrti3_1"
12300 [(set (match_operand:TI 0 "register_operand" "=r")
12301 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12302 (match_operand:QI 2 "register_operand" "c")))
12303 (clobber (match_scratch:DI 3 "=&r"))
12304 (clobber (reg:CC FLAGS_REG))]
12307 [(set_attr "type" "multi")])
12309 (define_insn "*lshrti3_2"
12310 [(set (match_operand:TI 0 "register_operand" "=r")
12311 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12312 (match_operand:QI 2 "immediate_operand" "O")))
12313 (clobber (reg:CC FLAGS_REG))]
12316 [(set_attr "type" "multi")])
12319 [(set (match_operand:TI 0 "register_operand" "")
12320 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12321 (match_operand:QI 2 "register_operand" "")))
12322 (clobber (match_scratch:DI 3 ""))
12323 (clobber (reg:CC FLAGS_REG))]
12324 "TARGET_64BIT && reload_completed"
12326 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12329 [(set (match_operand:TI 0 "register_operand" "")
12330 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12331 (match_operand:QI 2 "immediate_operand" "")))
12332 (clobber (reg:CC FLAGS_REG))]
12333 "TARGET_64BIT && reload_completed"
12335 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12337 (define_expand "lshrdi3"
12338 [(set (match_operand:DI 0 "shiftdi_operand" "")
12339 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12340 (match_operand:QI 2 "nonmemory_operand" "")))]
12342 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12344 (define_insn "*lshrdi3_1_one_bit_rex64"
12345 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12346 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12347 (match_operand:QI 2 "const1_operand" "")))
12348 (clobber (reg:CC FLAGS_REG))]
12349 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12350 && (TARGET_SHIFT1 || optimize_size)"
12352 [(set_attr "type" "ishift")
12353 (set (attr "length")
12354 (if_then_else (match_operand:DI 0 "register_operand" "")
12356 (const_string "*")))])
12358 (define_insn "*lshrdi3_1_rex64"
12359 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12360 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12361 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12362 (clobber (reg:CC FLAGS_REG))]
12363 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12365 shr{q}\t{%2, %0|%0, %2}
12366 shr{q}\t{%b2, %0|%0, %b2}"
12367 [(set_attr "type" "ishift")
12368 (set_attr "mode" "DI")])
12370 ;; This pattern can't accept a variable shift count, since shifts by
12371 ;; zero don't affect the flags. We assume that shifts by constant
12372 ;; zero are optimized away.
12373 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12374 [(set (reg FLAGS_REG)
12376 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12377 (match_operand:QI 2 "const1_operand" ""))
12379 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12380 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12381 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12382 && (TARGET_SHIFT1 || optimize_size)
12383 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12385 [(set_attr "type" "ishift")
12386 (set (attr "length")
12387 (if_then_else (match_operand:DI 0 "register_operand" "")
12389 (const_string "*")))])
12391 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12392 [(set (reg FLAGS_REG)
12394 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12395 (match_operand:QI 2 "const1_operand" ""))
12397 (clobber (match_scratch:DI 0 "=r"))]
12398 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12399 && (TARGET_SHIFT1 || optimize_size)
12400 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12402 [(set_attr "type" "ishift")
12403 (set_attr "length" "2")])
12405 ;; This pattern can't accept a variable shift count, since shifts by
12406 ;; zero don't affect the flags. We assume that shifts by constant
12407 ;; zero are optimized away.
12408 (define_insn "*lshrdi3_cmp_rex64"
12409 [(set (reg FLAGS_REG)
12411 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12412 (match_operand:QI 2 "const_int_operand" "e"))
12414 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12415 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12416 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12417 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12419 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12420 "shr{q}\t{%2, %0|%0, %2}"
12421 [(set_attr "type" "ishift")
12422 (set_attr "mode" "DI")])
12424 (define_insn "*lshrdi3_cconly_rex64"
12425 [(set (reg FLAGS_REG)
12427 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12428 (match_operand:QI 2 "const_int_operand" "e"))
12430 (clobber (match_scratch:DI 0 "=r"))]
12431 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12432 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12434 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12435 "shr{q}\t{%2, %0|%0, %2}"
12436 [(set_attr "type" "ishift")
12437 (set_attr "mode" "DI")])
12439 (define_insn "*lshrdi3_1"
12440 [(set (match_operand:DI 0 "register_operand" "=r")
12441 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12442 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12443 (clobber (reg:CC FLAGS_REG))]
12446 [(set_attr "type" "multi")])
12448 ;; By default we don't ask for a scratch register, because when DImode
12449 ;; values are manipulated, registers are already at a premium. But if
12450 ;; we have one handy, we won't turn it away.
12452 [(match_scratch:SI 3 "r")
12453 (parallel [(set (match_operand:DI 0 "register_operand" "")
12454 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12455 (match_operand:QI 2 "nonmemory_operand" "")))
12456 (clobber (reg:CC FLAGS_REG))])
12458 "!TARGET_64BIT && TARGET_CMOVE"
12460 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12463 [(set (match_operand:DI 0 "register_operand" "")
12464 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12465 (match_operand:QI 2 "nonmemory_operand" "")))
12466 (clobber (reg:CC FLAGS_REG))]
12467 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12468 ? flow2_completed : reload_completed)"
12470 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12472 (define_expand "lshrsi3"
12473 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12474 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12475 (match_operand:QI 2 "nonmemory_operand" "")))
12476 (clobber (reg:CC FLAGS_REG))]
12478 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12480 (define_insn "*lshrsi3_1_one_bit"
12481 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12482 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12483 (match_operand:QI 2 "const1_operand" "")))
12484 (clobber (reg:CC FLAGS_REG))]
12485 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12486 && (TARGET_SHIFT1 || optimize_size)"
12488 [(set_attr "type" "ishift")
12489 (set (attr "length")
12490 (if_then_else (match_operand:SI 0 "register_operand" "")
12492 (const_string "*")))])
12494 (define_insn "*lshrsi3_1_one_bit_zext"
12495 [(set (match_operand:DI 0 "register_operand" "=r")
12496 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12497 (match_operand:QI 2 "const1_operand" "")))
12498 (clobber (reg:CC FLAGS_REG))]
12499 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12500 && (TARGET_SHIFT1 || optimize_size)"
12502 [(set_attr "type" "ishift")
12503 (set_attr "length" "2")])
12505 (define_insn "*lshrsi3_1"
12506 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12507 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12508 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12509 (clobber (reg:CC FLAGS_REG))]
12510 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12512 shr{l}\t{%2, %0|%0, %2}
12513 shr{l}\t{%b2, %0|%0, %b2}"
12514 [(set_attr "type" "ishift")
12515 (set_attr "mode" "SI")])
12517 (define_insn "*lshrsi3_1_zext"
12518 [(set (match_operand:DI 0 "register_operand" "=r,r")
12520 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12521 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12522 (clobber (reg:CC FLAGS_REG))]
12523 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12525 shr{l}\t{%2, %k0|%k0, %2}
12526 shr{l}\t{%b2, %k0|%k0, %b2}"
12527 [(set_attr "type" "ishift")
12528 (set_attr "mode" "SI")])
12530 ;; This pattern can't accept a variable shift count, since shifts by
12531 ;; zero don't affect the flags. We assume that shifts by constant
12532 ;; zero are optimized away.
12533 (define_insn "*lshrsi3_one_bit_cmp"
12534 [(set (reg FLAGS_REG)
12536 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12537 (match_operand:QI 2 "const1_operand" ""))
12539 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12540 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12541 "ix86_match_ccmode (insn, CCGOCmode)
12542 && (TARGET_SHIFT1 || optimize_size)
12543 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12545 [(set_attr "type" "ishift")
12546 (set (attr "length")
12547 (if_then_else (match_operand:SI 0 "register_operand" "")
12549 (const_string "*")))])
12551 (define_insn "*lshrsi3_one_bit_cconly"
12552 [(set (reg FLAGS_REG)
12554 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12555 (match_operand:QI 2 "const1_operand" ""))
12557 (clobber (match_scratch:SI 0 "=r"))]
12558 "ix86_match_ccmode (insn, CCGOCmode)
12559 && (TARGET_SHIFT1 || optimize_size)
12560 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12562 [(set_attr "type" "ishift")
12563 (set_attr "length" "2")])
12565 (define_insn "*lshrsi3_cmp_one_bit_zext"
12566 [(set (reg FLAGS_REG)
12568 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12569 (match_operand:QI 2 "const1_operand" ""))
12571 (set (match_operand:DI 0 "register_operand" "=r")
12572 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12573 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12574 && (TARGET_SHIFT1 || optimize_size)
12575 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12577 [(set_attr "type" "ishift")
12578 (set_attr "length" "2")])
12580 ;; This pattern can't accept a variable shift count, since shifts by
12581 ;; zero don't affect the flags. We assume that shifts by constant
12582 ;; zero are optimized away.
12583 (define_insn "*lshrsi3_cmp"
12584 [(set (reg FLAGS_REG)
12586 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12587 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12589 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12590 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12591 "ix86_match_ccmode (insn, CCGOCmode)
12592 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12594 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12595 "shr{l}\t{%2, %0|%0, %2}"
12596 [(set_attr "type" "ishift")
12597 (set_attr "mode" "SI")])
12599 (define_insn "*lshrsi3_cconly"
12600 [(set (reg FLAGS_REG)
12602 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12603 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12605 (clobber (match_scratch:SI 0 "=r"))]
12606 "ix86_match_ccmode (insn, CCGOCmode)
12607 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12609 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12610 "shr{l}\t{%2, %0|%0, %2}"
12611 [(set_attr "type" "ishift")
12612 (set_attr "mode" "SI")])
12614 (define_insn "*lshrsi3_cmp_zext"
12615 [(set (reg FLAGS_REG)
12617 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12618 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12620 (set (match_operand:DI 0 "register_operand" "=r")
12621 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12622 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12623 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12625 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12626 "shr{l}\t{%2, %k0|%k0, %2}"
12627 [(set_attr "type" "ishift")
12628 (set_attr "mode" "SI")])
12630 (define_expand "lshrhi3"
12631 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12632 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12633 (match_operand:QI 2 "nonmemory_operand" "")))
12634 (clobber (reg:CC FLAGS_REG))]
12635 "TARGET_HIMODE_MATH"
12636 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12638 (define_insn "*lshrhi3_1_one_bit"
12639 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12640 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12641 (match_operand:QI 2 "const1_operand" "")))
12642 (clobber (reg:CC FLAGS_REG))]
12643 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12644 && (TARGET_SHIFT1 || optimize_size)"
12646 [(set_attr "type" "ishift")
12647 (set (attr "length")
12648 (if_then_else (match_operand 0 "register_operand" "")
12650 (const_string "*")))])
12652 (define_insn "*lshrhi3_1"
12653 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12654 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12655 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12656 (clobber (reg:CC FLAGS_REG))]
12657 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12659 shr{w}\t{%2, %0|%0, %2}
12660 shr{w}\t{%b2, %0|%0, %b2}"
12661 [(set_attr "type" "ishift")
12662 (set_attr "mode" "HI")])
12664 ;; This pattern can't accept a variable shift count, since shifts by
12665 ;; zero don't affect the flags. We assume that shifts by constant
12666 ;; zero are optimized away.
12667 (define_insn "*lshrhi3_one_bit_cmp"
12668 [(set (reg FLAGS_REG)
12670 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12671 (match_operand:QI 2 "const1_operand" ""))
12673 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12674 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12675 "ix86_match_ccmode (insn, CCGOCmode)
12676 && (TARGET_SHIFT1 || optimize_size)
12677 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12679 [(set_attr "type" "ishift")
12680 (set (attr "length")
12681 (if_then_else (match_operand:SI 0 "register_operand" "")
12683 (const_string "*")))])
12685 (define_insn "*lshrhi3_one_bit_cconly"
12686 [(set (reg FLAGS_REG)
12688 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12689 (match_operand:QI 2 "const1_operand" ""))
12691 (clobber (match_scratch:HI 0 "=r"))]
12692 "ix86_match_ccmode (insn, CCGOCmode)
12693 && (TARGET_SHIFT1 || optimize_size)
12694 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12696 [(set_attr "type" "ishift")
12697 (set_attr "length" "2")])
12699 ;; This pattern can't accept a variable shift count, since shifts by
12700 ;; zero don't affect the flags. We assume that shifts by constant
12701 ;; zero are optimized away.
12702 (define_insn "*lshrhi3_cmp"
12703 [(set (reg FLAGS_REG)
12705 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12706 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12708 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12709 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12710 "ix86_match_ccmode (insn, CCGOCmode)
12711 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12713 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12714 "shr{w}\t{%2, %0|%0, %2}"
12715 [(set_attr "type" "ishift")
12716 (set_attr "mode" "HI")])
12718 (define_insn "*lshrhi3_cconly"
12719 [(set (reg FLAGS_REG)
12721 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12722 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12724 (clobber (match_scratch:HI 0 "=r"))]
12725 "ix86_match_ccmode (insn, CCGOCmode)
12726 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12728 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12729 "shr{w}\t{%2, %0|%0, %2}"
12730 [(set_attr "type" "ishift")
12731 (set_attr "mode" "HI")])
12733 (define_expand "lshrqi3"
12734 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12735 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12736 (match_operand:QI 2 "nonmemory_operand" "")))
12737 (clobber (reg:CC FLAGS_REG))]
12738 "TARGET_QIMODE_MATH"
12739 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12741 (define_insn "*lshrqi3_1_one_bit"
12742 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12743 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12744 (match_operand:QI 2 "const1_operand" "")))
12745 (clobber (reg:CC FLAGS_REG))]
12746 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12747 && (TARGET_SHIFT1 || optimize_size)"
12749 [(set_attr "type" "ishift")
12750 (set (attr "length")
12751 (if_then_else (match_operand 0 "register_operand" "")
12753 (const_string "*")))])
12755 (define_insn "*lshrqi3_1_one_bit_slp"
12756 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12757 (lshiftrt:QI (match_dup 0)
12758 (match_operand:QI 1 "const1_operand" "")))
12759 (clobber (reg:CC FLAGS_REG))]
12760 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12761 && (TARGET_SHIFT1 || optimize_size)"
12763 [(set_attr "type" "ishift1")
12764 (set (attr "length")
12765 (if_then_else (match_operand 0 "register_operand" "")
12767 (const_string "*")))])
12769 (define_insn "*lshrqi3_1"
12770 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12771 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12772 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12773 (clobber (reg:CC FLAGS_REG))]
12774 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12776 shr{b}\t{%2, %0|%0, %2}
12777 shr{b}\t{%b2, %0|%0, %b2}"
12778 [(set_attr "type" "ishift")
12779 (set_attr "mode" "QI")])
12781 (define_insn "*lshrqi3_1_slp"
12782 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12783 (lshiftrt:QI (match_dup 0)
12784 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12785 (clobber (reg:CC FLAGS_REG))]
12786 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12787 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12789 shr{b}\t{%1, %0|%0, %1}
12790 shr{b}\t{%b1, %0|%0, %b1}"
12791 [(set_attr "type" "ishift1")
12792 (set_attr "mode" "QI")])
12794 ;; This pattern can't accept a variable shift count, since shifts by
12795 ;; zero don't affect the flags. We assume that shifts by constant
12796 ;; zero are optimized away.
12797 (define_insn "*lshrqi2_one_bit_cmp"
12798 [(set (reg FLAGS_REG)
12800 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12801 (match_operand:QI 2 "const1_operand" ""))
12803 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12804 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12805 "ix86_match_ccmode (insn, CCGOCmode)
12806 && (TARGET_SHIFT1 || optimize_size)
12807 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12809 [(set_attr "type" "ishift")
12810 (set (attr "length")
12811 (if_then_else (match_operand:SI 0 "register_operand" "")
12813 (const_string "*")))])
12815 (define_insn "*lshrqi2_one_bit_cconly"
12816 [(set (reg FLAGS_REG)
12818 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12819 (match_operand:QI 2 "const1_operand" ""))
12821 (clobber (match_scratch:QI 0 "=q"))]
12822 "ix86_match_ccmode (insn, CCGOCmode)
12823 && (TARGET_SHIFT1 || optimize_size)
12824 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12826 [(set_attr "type" "ishift")
12827 (set_attr "length" "2")])
12829 ;; This pattern can't accept a variable shift count, since shifts by
12830 ;; zero don't affect the flags. We assume that shifts by constant
12831 ;; zero are optimized away.
12832 (define_insn "*lshrqi2_cmp"
12833 [(set (reg FLAGS_REG)
12835 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12836 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12838 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12839 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12840 "ix86_match_ccmode (insn, CCGOCmode)
12841 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12843 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12844 "shr{b}\t{%2, %0|%0, %2}"
12845 [(set_attr "type" "ishift")
12846 (set_attr "mode" "QI")])
12848 (define_insn "*lshrqi2_cconly"
12849 [(set (reg FLAGS_REG)
12851 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12852 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12854 (clobber (match_scratch:QI 0 "=q"))]
12855 "ix86_match_ccmode (insn, CCGOCmode)
12856 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12858 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12859 "shr{b}\t{%2, %0|%0, %2}"
12860 [(set_attr "type" "ishift")
12861 (set_attr "mode" "QI")])
12863 ;; Rotate instructions
12865 (define_expand "rotldi3"
12866 [(set (match_operand:DI 0 "shiftdi_operand" "")
12867 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12868 (match_operand:QI 2 "nonmemory_operand" "")))
12869 (clobber (reg:CC FLAGS_REG))]
12874 ix86_expand_binary_operator (ROTATE, DImode, operands);
12877 if (!const_1_to_31_operand (operands[2], VOIDmode))
12879 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12883 ;; Implement rotation using two double-precision shift instructions
12884 ;; and a scratch register.
12885 (define_insn_and_split "ix86_rotldi3"
12886 [(set (match_operand:DI 0 "register_operand" "=r")
12887 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12888 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12889 (clobber (reg:CC FLAGS_REG))
12890 (clobber (match_scratch:SI 3 "=&r"))]
12893 "&& reload_completed"
12894 [(set (match_dup 3) (match_dup 4))
12896 [(set (match_dup 4)
12897 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12898 (lshiftrt:SI (match_dup 5)
12899 (minus:QI (const_int 32) (match_dup 2)))))
12900 (clobber (reg:CC FLAGS_REG))])
12902 [(set (match_dup 5)
12903 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12904 (lshiftrt:SI (match_dup 3)
12905 (minus:QI (const_int 32) (match_dup 2)))))
12906 (clobber (reg:CC FLAGS_REG))])]
12907 "split_di (operands, 1, operands + 4, operands + 5);")
12909 (define_insn "*rotlsi3_1_one_bit_rex64"
12910 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12911 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12912 (match_operand:QI 2 "const1_operand" "")))
12913 (clobber (reg:CC FLAGS_REG))]
12914 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12915 && (TARGET_SHIFT1 || optimize_size)"
12917 [(set_attr "type" "rotate")
12918 (set (attr "length")
12919 (if_then_else (match_operand:DI 0 "register_operand" "")
12921 (const_string "*")))])
12923 (define_insn "*rotldi3_1_rex64"
12924 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12925 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12926 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12927 (clobber (reg:CC FLAGS_REG))]
12928 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12930 rol{q}\t{%2, %0|%0, %2}
12931 rol{q}\t{%b2, %0|%0, %b2}"
12932 [(set_attr "type" "rotate")
12933 (set_attr "mode" "DI")])
12935 (define_expand "rotlsi3"
12936 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12937 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12938 (match_operand:QI 2 "nonmemory_operand" "")))
12939 (clobber (reg:CC FLAGS_REG))]
12941 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12943 (define_insn "*rotlsi3_1_one_bit"
12944 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12945 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12946 (match_operand:QI 2 "const1_operand" "")))
12947 (clobber (reg:CC FLAGS_REG))]
12948 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12949 && (TARGET_SHIFT1 || optimize_size)"
12951 [(set_attr "type" "rotate")
12952 (set (attr "length")
12953 (if_then_else (match_operand:SI 0 "register_operand" "")
12955 (const_string "*")))])
12957 (define_insn "*rotlsi3_1_one_bit_zext"
12958 [(set (match_operand:DI 0 "register_operand" "=r")
12960 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12961 (match_operand:QI 2 "const1_operand" ""))))
12962 (clobber (reg:CC FLAGS_REG))]
12963 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12964 && (TARGET_SHIFT1 || optimize_size)"
12966 [(set_attr "type" "rotate")
12967 (set_attr "length" "2")])
12969 (define_insn "*rotlsi3_1"
12970 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12971 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12972 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12973 (clobber (reg:CC FLAGS_REG))]
12974 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12976 rol{l}\t{%2, %0|%0, %2}
12977 rol{l}\t{%b2, %0|%0, %b2}"
12978 [(set_attr "type" "rotate")
12979 (set_attr "mode" "SI")])
12981 (define_insn "*rotlsi3_1_zext"
12982 [(set (match_operand:DI 0 "register_operand" "=r,r")
12984 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12985 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12986 (clobber (reg:CC FLAGS_REG))]
12987 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12989 rol{l}\t{%2, %k0|%k0, %2}
12990 rol{l}\t{%b2, %k0|%k0, %b2}"
12991 [(set_attr "type" "rotate")
12992 (set_attr "mode" "SI")])
12994 (define_expand "rotlhi3"
12995 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12996 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12997 (match_operand:QI 2 "nonmemory_operand" "")))
12998 (clobber (reg:CC FLAGS_REG))]
12999 "TARGET_HIMODE_MATH"
13000 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13002 (define_insn "*rotlhi3_1_one_bit"
13003 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13004 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13005 (match_operand:QI 2 "const1_operand" "")))
13006 (clobber (reg:CC FLAGS_REG))]
13007 "ix86_binary_operator_ok (ROTATE, HImode, operands)
13008 && (TARGET_SHIFT1 || optimize_size)"
13010 [(set_attr "type" "rotate")
13011 (set (attr "length")
13012 (if_then_else (match_operand 0 "register_operand" "")
13014 (const_string "*")))])
13016 (define_insn "*rotlhi3_1"
13017 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13018 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13019 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13020 (clobber (reg:CC FLAGS_REG))]
13021 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13023 rol{w}\t{%2, %0|%0, %2}
13024 rol{w}\t{%b2, %0|%0, %b2}"
13025 [(set_attr "type" "rotate")
13026 (set_attr "mode" "HI")])
13029 [(set (match_operand:HI 0 "register_operand" "")
13030 (rotate:HI (match_dup 0) (const_int 8)))
13031 (clobber (reg:CC FLAGS_REG))]
13033 [(parallel [(set (strict_low_part (match_dup 0))
13034 (bswap:HI (match_dup 0)))
13035 (clobber (reg:CC FLAGS_REG))])]
13038 (define_expand "rotlqi3"
13039 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13040 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13041 (match_operand:QI 2 "nonmemory_operand" "")))
13042 (clobber (reg:CC FLAGS_REG))]
13043 "TARGET_QIMODE_MATH"
13044 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13046 (define_insn "*rotlqi3_1_one_bit_slp"
13047 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13048 (rotate:QI (match_dup 0)
13049 (match_operand:QI 1 "const1_operand" "")))
13050 (clobber (reg:CC FLAGS_REG))]
13051 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13052 && (TARGET_SHIFT1 || optimize_size)"
13054 [(set_attr "type" "rotate1")
13055 (set (attr "length")
13056 (if_then_else (match_operand 0 "register_operand" "")
13058 (const_string "*")))])
13060 (define_insn "*rotlqi3_1_one_bit"
13061 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13062 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13063 (match_operand:QI 2 "const1_operand" "")))
13064 (clobber (reg:CC FLAGS_REG))]
13065 "ix86_binary_operator_ok (ROTATE, QImode, operands)
13066 && (TARGET_SHIFT1 || optimize_size)"
13068 [(set_attr "type" "rotate")
13069 (set (attr "length")
13070 (if_then_else (match_operand 0 "register_operand" "")
13072 (const_string "*")))])
13074 (define_insn "*rotlqi3_1_slp"
13075 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13076 (rotate:QI (match_dup 0)
13077 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13078 (clobber (reg:CC FLAGS_REG))]
13079 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13080 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13082 rol{b}\t{%1, %0|%0, %1}
13083 rol{b}\t{%b1, %0|%0, %b1}"
13084 [(set_attr "type" "rotate1")
13085 (set_attr "mode" "QI")])
13087 (define_insn "*rotlqi3_1"
13088 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13089 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13090 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13091 (clobber (reg:CC FLAGS_REG))]
13092 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13094 rol{b}\t{%2, %0|%0, %2}
13095 rol{b}\t{%b2, %0|%0, %b2}"
13096 [(set_attr "type" "rotate")
13097 (set_attr "mode" "QI")])
13099 (define_expand "rotrdi3"
13100 [(set (match_operand:DI 0 "shiftdi_operand" "")
13101 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13102 (match_operand:QI 2 "nonmemory_operand" "")))
13103 (clobber (reg:CC FLAGS_REG))]
13108 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13111 if (!const_1_to_31_operand (operands[2], VOIDmode))
13113 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13117 ;; Implement rotation using two double-precision shift instructions
13118 ;; and a scratch register.
13119 (define_insn_and_split "ix86_rotrdi3"
13120 [(set (match_operand:DI 0 "register_operand" "=r")
13121 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13122 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13123 (clobber (reg:CC FLAGS_REG))
13124 (clobber (match_scratch:SI 3 "=&r"))]
13127 "&& reload_completed"
13128 [(set (match_dup 3) (match_dup 4))
13130 [(set (match_dup 4)
13131 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13132 (ashift:SI (match_dup 5)
13133 (minus:QI (const_int 32) (match_dup 2)))))
13134 (clobber (reg:CC FLAGS_REG))])
13136 [(set (match_dup 5)
13137 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13138 (ashift:SI (match_dup 3)
13139 (minus:QI (const_int 32) (match_dup 2)))))
13140 (clobber (reg:CC FLAGS_REG))])]
13141 "split_di (operands, 1, operands + 4, operands + 5);")
13143 (define_insn "*rotrdi3_1_one_bit_rex64"
13144 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13145 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13146 (match_operand:QI 2 "const1_operand" "")))
13147 (clobber (reg:CC FLAGS_REG))]
13148 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
13149 && (TARGET_SHIFT1 || optimize_size)"
13151 [(set_attr "type" "rotate")
13152 (set (attr "length")
13153 (if_then_else (match_operand:DI 0 "register_operand" "")
13155 (const_string "*")))])
13157 (define_insn "*rotrdi3_1_rex64"
13158 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13159 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13160 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13161 (clobber (reg:CC FLAGS_REG))]
13162 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13164 ror{q}\t{%2, %0|%0, %2}
13165 ror{q}\t{%b2, %0|%0, %b2}"
13166 [(set_attr "type" "rotate")
13167 (set_attr "mode" "DI")])
13169 (define_expand "rotrsi3"
13170 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13171 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13172 (match_operand:QI 2 "nonmemory_operand" "")))
13173 (clobber (reg:CC FLAGS_REG))]
13175 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13177 (define_insn "*rotrsi3_1_one_bit"
13178 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13179 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13180 (match_operand:QI 2 "const1_operand" "")))
13181 (clobber (reg:CC FLAGS_REG))]
13182 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
13183 && (TARGET_SHIFT1 || optimize_size)"
13185 [(set_attr "type" "rotate")
13186 (set (attr "length")
13187 (if_then_else (match_operand:SI 0 "register_operand" "")
13189 (const_string "*")))])
13191 (define_insn "*rotrsi3_1_one_bit_zext"
13192 [(set (match_operand:DI 0 "register_operand" "=r")
13194 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13195 (match_operand:QI 2 "const1_operand" ""))))
13196 (clobber (reg:CC FLAGS_REG))]
13197 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
13198 && (TARGET_SHIFT1 || optimize_size)"
13200 [(set_attr "type" "rotate")
13201 (set (attr "length")
13202 (if_then_else (match_operand:SI 0 "register_operand" "")
13204 (const_string "*")))])
13206 (define_insn "*rotrsi3_1"
13207 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13208 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13209 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13210 (clobber (reg:CC FLAGS_REG))]
13211 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13213 ror{l}\t{%2, %0|%0, %2}
13214 ror{l}\t{%b2, %0|%0, %b2}"
13215 [(set_attr "type" "rotate")
13216 (set_attr "mode" "SI")])
13218 (define_insn "*rotrsi3_1_zext"
13219 [(set (match_operand:DI 0 "register_operand" "=r,r")
13221 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13222 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13223 (clobber (reg:CC FLAGS_REG))]
13224 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13226 ror{l}\t{%2, %k0|%k0, %2}
13227 ror{l}\t{%b2, %k0|%k0, %b2}"
13228 [(set_attr "type" "rotate")
13229 (set_attr "mode" "SI")])
13231 (define_expand "rotrhi3"
13232 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13233 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13234 (match_operand:QI 2 "nonmemory_operand" "")))
13235 (clobber (reg:CC FLAGS_REG))]
13236 "TARGET_HIMODE_MATH"
13237 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13239 (define_insn "*rotrhi3_one_bit"
13240 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13241 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13242 (match_operand:QI 2 "const1_operand" "")))
13243 (clobber (reg:CC FLAGS_REG))]
13244 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
13245 && (TARGET_SHIFT1 || optimize_size)"
13247 [(set_attr "type" "rotate")
13248 (set (attr "length")
13249 (if_then_else (match_operand 0 "register_operand" "")
13251 (const_string "*")))])
13253 (define_insn "*rotrhi3_1"
13254 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13255 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13256 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13257 (clobber (reg:CC FLAGS_REG))]
13258 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13260 ror{w}\t{%2, %0|%0, %2}
13261 ror{w}\t{%b2, %0|%0, %b2}"
13262 [(set_attr "type" "rotate")
13263 (set_attr "mode" "HI")])
13266 [(set (match_operand:HI 0 "register_operand" "")
13267 (rotatert:HI (match_dup 0) (const_int 8)))
13268 (clobber (reg:CC FLAGS_REG))]
13270 [(parallel [(set (strict_low_part (match_dup 0))
13271 (bswap:HI (match_dup 0)))
13272 (clobber (reg:CC FLAGS_REG))])]
13275 (define_expand "rotrqi3"
13276 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13277 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13278 (match_operand:QI 2 "nonmemory_operand" "")))
13279 (clobber (reg:CC FLAGS_REG))]
13280 "TARGET_QIMODE_MATH"
13281 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13283 (define_insn "*rotrqi3_1_one_bit"
13284 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13285 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13286 (match_operand:QI 2 "const1_operand" "")))
13287 (clobber (reg:CC FLAGS_REG))]
13288 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
13289 && (TARGET_SHIFT1 || optimize_size)"
13291 [(set_attr "type" "rotate")
13292 (set (attr "length")
13293 (if_then_else (match_operand 0 "register_operand" "")
13295 (const_string "*")))])
13297 (define_insn "*rotrqi3_1_one_bit_slp"
13298 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13299 (rotatert:QI (match_dup 0)
13300 (match_operand:QI 1 "const1_operand" "")))
13301 (clobber (reg:CC FLAGS_REG))]
13302 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13303 && (TARGET_SHIFT1 || optimize_size)"
13305 [(set_attr "type" "rotate1")
13306 (set (attr "length")
13307 (if_then_else (match_operand 0 "register_operand" "")
13309 (const_string "*")))])
13311 (define_insn "*rotrqi3_1"
13312 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13313 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13314 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13315 (clobber (reg:CC FLAGS_REG))]
13316 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13318 ror{b}\t{%2, %0|%0, %2}
13319 ror{b}\t{%b2, %0|%0, %b2}"
13320 [(set_attr "type" "rotate")
13321 (set_attr "mode" "QI")])
13323 (define_insn "*rotrqi3_1_slp"
13324 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13325 (rotatert:QI (match_dup 0)
13326 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13327 (clobber (reg:CC FLAGS_REG))]
13328 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13329 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13331 ror{b}\t{%1, %0|%0, %1}
13332 ror{b}\t{%b1, %0|%0, %b1}"
13333 [(set_attr "type" "rotate1")
13334 (set_attr "mode" "QI")])
13336 ;; Bit set / bit test instructions
13338 (define_expand "extv"
13339 [(set (match_operand:SI 0 "register_operand" "")
13340 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13341 (match_operand:SI 2 "const8_operand" "")
13342 (match_operand:SI 3 "const8_operand" "")))]
13345 /* Handle extractions from %ah et al. */
13346 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13349 /* From mips.md: extract_bit_field doesn't verify that our source
13350 matches the predicate, so check it again here. */
13351 if (! ext_register_operand (operands[1], VOIDmode))
13355 (define_expand "extzv"
13356 [(set (match_operand:SI 0 "register_operand" "")
13357 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13358 (match_operand:SI 2 "const8_operand" "")
13359 (match_operand:SI 3 "const8_operand" "")))]
13362 /* Handle extractions from %ah et al. */
13363 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13366 /* From mips.md: extract_bit_field doesn't verify that our source
13367 matches the predicate, so check it again here. */
13368 if (! ext_register_operand (operands[1], VOIDmode))
13372 (define_expand "insv"
13373 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13374 (match_operand 1 "const8_operand" "")
13375 (match_operand 2 "const8_operand" ""))
13376 (match_operand 3 "register_operand" ""))]
13379 /* Handle insertions to %ah et al. */
13380 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13383 /* From mips.md: insert_bit_field doesn't verify that our source
13384 matches the predicate, so check it again here. */
13385 if (! ext_register_operand (operands[0], VOIDmode))
13389 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13391 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13396 ;; %%% bts, btr, btc, bt.
13397 ;; In general these instructions are *slow* when applied to memory,
13398 ;; since they enforce atomic operation. When applied to registers,
13399 ;; it depends on the cpu implementation. They're never faster than
13400 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13401 ;; no point. But in 64-bit, we can't hold the relevant immediates
13402 ;; within the instruction itself, so operating on bits in the high
13403 ;; 32-bits of a register becomes easier.
13405 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13406 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13407 ;; negdf respectively, so they can never be disabled entirely.
13409 (define_insn "*btsq"
13410 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13412 (match_operand:DI 1 "const_0_to_63_operand" ""))
13414 (clobber (reg:CC FLAGS_REG))]
13415 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13417 [(set_attr "type" "alu1")])
13419 (define_insn "*btrq"
13420 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13422 (match_operand:DI 1 "const_0_to_63_operand" ""))
13424 (clobber (reg:CC FLAGS_REG))]
13425 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13427 [(set_attr "type" "alu1")])
13429 (define_insn "*btcq"
13430 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13432 (match_operand:DI 1 "const_0_to_63_operand" ""))
13433 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13434 (clobber (reg:CC FLAGS_REG))]
13435 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13437 [(set_attr "type" "alu1")])
13439 ;; Allow Nocona to avoid these instructions if a register is available.
13442 [(match_scratch:DI 2 "r")
13443 (parallel [(set (zero_extract:DI
13444 (match_operand:DI 0 "register_operand" "")
13446 (match_operand:DI 1 "const_0_to_63_operand" ""))
13448 (clobber (reg:CC FLAGS_REG))])]
13449 "TARGET_64BIT && !TARGET_USE_BT"
13452 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13455 if (HOST_BITS_PER_WIDE_INT >= 64)
13456 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13457 else if (i < HOST_BITS_PER_WIDE_INT)
13458 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13460 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13462 op1 = immed_double_const (lo, hi, DImode);
13465 emit_move_insn (operands[2], op1);
13469 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13474 [(match_scratch:DI 2 "r")
13475 (parallel [(set (zero_extract:DI
13476 (match_operand:DI 0 "register_operand" "")
13478 (match_operand:DI 1 "const_0_to_63_operand" ""))
13480 (clobber (reg:CC FLAGS_REG))])]
13481 "TARGET_64BIT && !TARGET_USE_BT"
13484 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13487 if (HOST_BITS_PER_WIDE_INT >= 64)
13488 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13489 else if (i < HOST_BITS_PER_WIDE_INT)
13490 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13492 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13494 op1 = immed_double_const (~lo, ~hi, DImode);
13497 emit_move_insn (operands[2], op1);
13501 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13506 [(match_scratch:DI 2 "r")
13507 (parallel [(set (zero_extract:DI
13508 (match_operand:DI 0 "register_operand" "")
13510 (match_operand:DI 1 "const_0_to_63_operand" ""))
13511 (not:DI (zero_extract:DI
13512 (match_dup 0) (const_int 1) (match_dup 1))))
13513 (clobber (reg:CC FLAGS_REG))])]
13514 "TARGET_64BIT && !TARGET_USE_BT"
13517 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13520 if (HOST_BITS_PER_WIDE_INT >= 64)
13521 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13522 else if (i < HOST_BITS_PER_WIDE_INT)
13523 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13525 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13527 op1 = immed_double_const (lo, hi, DImode);
13530 emit_move_insn (operands[2], op1);
13534 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13538 ;; Store-flag instructions.
13540 ;; For all sCOND expanders, also expand the compare or test insn that
13541 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13543 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13544 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13545 ;; way, which can later delete the movzx if only QImode is needed.
13547 (define_expand "seq"
13548 [(set (match_operand:QI 0 "register_operand" "")
13549 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13551 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13553 (define_expand "sne"
13554 [(set (match_operand:QI 0 "register_operand" "")
13555 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13557 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13559 (define_expand "sgt"
13560 [(set (match_operand:QI 0 "register_operand" "")
13561 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13563 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13565 (define_expand "sgtu"
13566 [(set (match_operand:QI 0 "register_operand" "")
13567 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13569 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13571 (define_expand "slt"
13572 [(set (match_operand:QI 0 "register_operand" "")
13573 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13575 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13577 (define_expand "sltu"
13578 [(set (match_operand:QI 0 "register_operand" "")
13579 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13581 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13583 (define_expand "sge"
13584 [(set (match_operand:QI 0 "register_operand" "")
13585 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13587 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13589 (define_expand "sgeu"
13590 [(set (match_operand:QI 0 "register_operand" "")
13591 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13593 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13595 (define_expand "sle"
13596 [(set (match_operand:QI 0 "register_operand" "")
13597 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13599 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13601 (define_expand "sleu"
13602 [(set (match_operand:QI 0 "register_operand" "")
13603 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13605 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13607 (define_expand "sunordered"
13608 [(set (match_operand:QI 0 "register_operand" "")
13609 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13610 "TARGET_80387 || TARGET_SSE"
13611 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13613 (define_expand "sordered"
13614 [(set (match_operand:QI 0 "register_operand" "")
13615 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13617 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13619 (define_expand "suneq"
13620 [(set (match_operand:QI 0 "register_operand" "")
13621 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13622 "TARGET_80387 || TARGET_SSE"
13623 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13625 (define_expand "sunge"
13626 [(set (match_operand:QI 0 "register_operand" "")
13627 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13628 "TARGET_80387 || TARGET_SSE"
13629 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13631 (define_expand "sungt"
13632 [(set (match_operand:QI 0 "register_operand" "")
13633 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13634 "TARGET_80387 || TARGET_SSE"
13635 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13637 (define_expand "sunle"
13638 [(set (match_operand:QI 0 "register_operand" "")
13639 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13640 "TARGET_80387 || TARGET_SSE"
13641 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13643 (define_expand "sunlt"
13644 [(set (match_operand:QI 0 "register_operand" "")
13645 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13646 "TARGET_80387 || TARGET_SSE"
13647 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13649 (define_expand "sltgt"
13650 [(set (match_operand:QI 0 "register_operand" "")
13651 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13652 "TARGET_80387 || TARGET_SSE"
13653 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13655 (define_insn "*setcc_1"
13656 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13657 (match_operator:QI 1 "ix86_comparison_operator"
13658 [(reg FLAGS_REG) (const_int 0)]))]
13661 [(set_attr "type" "setcc")
13662 (set_attr "mode" "QI")])
13664 (define_insn "*setcc_2"
13665 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13666 (match_operator:QI 1 "ix86_comparison_operator"
13667 [(reg FLAGS_REG) (const_int 0)]))]
13670 [(set_attr "type" "setcc")
13671 (set_attr "mode" "QI")])
13673 ;; In general it is not safe to assume too much about CCmode registers,
13674 ;; so simplify-rtx stops when it sees a second one. Under certain
13675 ;; conditions this is safe on x86, so help combine not create
13682 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13683 (ne:QI (match_operator 1 "ix86_comparison_operator"
13684 [(reg FLAGS_REG) (const_int 0)])
13687 [(set (match_dup 0) (match_dup 1))]
13689 PUT_MODE (operands[1], QImode);
13693 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13694 (ne:QI (match_operator 1 "ix86_comparison_operator"
13695 [(reg FLAGS_REG) (const_int 0)])
13698 [(set (match_dup 0) (match_dup 1))]
13700 PUT_MODE (operands[1], QImode);
13704 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13705 (eq:QI (match_operator 1 "ix86_comparison_operator"
13706 [(reg FLAGS_REG) (const_int 0)])
13709 [(set (match_dup 0) (match_dup 1))]
13711 rtx new_op1 = copy_rtx (operands[1]);
13712 operands[1] = new_op1;
13713 PUT_MODE (new_op1, QImode);
13714 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13715 GET_MODE (XEXP (new_op1, 0))));
13717 /* Make sure that (a) the CCmode we have for the flags is strong
13718 enough for the reversed compare or (b) we have a valid FP compare. */
13719 if (! ix86_comparison_operator (new_op1, VOIDmode))
13724 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13725 (eq:QI (match_operator 1 "ix86_comparison_operator"
13726 [(reg FLAGS_REG) (const_int 0)])
13729 [(set (match_dup 0) (match_dup 1))]
13731 rtx new_op1 = copy_rtx (operands[1]);
13732 operands[1] = new_op1;
13733 PUT_MODE (new_op1, QImode);
13734 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13735 GET_MODE (XEXP (new_op1, 0))));
13737 /* Make sure that (a) the CCmode we have for the flags is strong
13738 enough for the reversed compare or (b) we have a valid FP compare. */
13739 if (! ix86_comparison_operator (new_op1, VOIDmode))
13743 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13744 ;; subsequent logical operations are used to imitate conditional moves.
13745 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13748 (define_insn "*sse_setccsf"
13749 [(set (match_operand:SF 0 "register_operand" "=x")
13750 (match_operator:SF 1 "sse_comparison_operator"
13751 [(match_operand:SF 2 "register_operand" "0")
13752 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13754 "cmp%D1ss\t{%3, %0|%0, %3}"
13755 [(set_attr "type" "ssecmp")
13756 (set_attr "mode" "SF")])
13758 (define_insn "*sse_setccdf"
13759 [(set (match_operand:DF 0 "register_operand" "=x")
13760 (match_operator:DF 1 "sse_comparison_operator"
13761 [(match_operand:DF 2 "register_operand" "0")
13762 (match_operand:DF 3 "nonimmediate_operand" "xm")]))]
13764 "cmp%D1sd\t{%3, %0|%0, %3}"
13765 [(set_attr "type" "ssecmp")
13766 (set_attr "mode" "DF")])
13768 ;; Basic conditional jump instructions.
13769 ;; We ignore the overflow flag for signed branch instructions.
13771 ;; For all bCOND expanders, also expand the compare or test insn that
13772 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13774 (define_expand "beq"
13776 (if_then_else (match_dup 1)
13777 (label_ref (match_operand 0 "" ""))
13780 "ix86_expand_branch (EQ, operands[0]); DONE;")
13782 (define_expand "bne"
13784 (if_then_else (match_dup 1)
13785 (label_ref (match_operand 0 "" ""))
13788 "ix86_expand_branch (NE, operands[0]); DONE;")
13790 (define_expand "bgt"
13792 (if_then_else (match_dup 1)
13793 (label_ref (match_operand 0 "" ""))
13796 "ix86_expand_branch (GT, operands[0]); DONE;")
13798 (define_expand "bgtu"
13800 (if_then_else (match_dup 1)
13801 (label_ref (match_operand 0 "" ""))
13804 "ix86_expand_branch (GTU, operands[0]); DONE;")
13806 (define_expand "blt"
13808 (if_then_else (match_dup 1)
13809 (label_ref (match_operand 0 "" ""))
13812 "ix86_expand_branch (LT, operands[0]); DONE;")
13814 (define_expand "bltu"
13816 (if_then_else (match_dup 1)
13817 (label_ref (match_operand 0 "" ""))
13820 "ix86_expand_branch (LTU, operands[0]); DONE;")
13822 (define_expand "bge"
13824 (if_then_else (match_dup 1)
13825 (label_ref (match_operand 0 "" ""))
13828 "ix86_expand_branch (GE, operands[0]); DONE;")
13830 (define_expand "bgeu"
13832 (if_then_else (match_dup 1)
13833 (label_ref (match_operand 0 "" ""))
13836 "ix86_expand_branch (GEU, operands[0]); DONE;")
13838 (define_expand "ble"
13840 (if_then_else (match_dup 1)
13841 (label_ref (match_operand 0 "" ""))
13844 "ix86_expand_branch (LE, operands[0]); DONE;")
13846 (define_expand "bleu"
13848 (if_then_else (match_dup 1)
13849 (label_ref (match_operand 0 "" ""))
13852 "ix86_expand_branch (LEU, operands[0]); DONE;")
13854 (define_expand "bunordered"
13856 (if_then_else (match_dup 1)
13857 (label_ref (match_operand 0 "" ""))
13859 "TARGET_80387 || TARGET_SSE_MATH"
13860 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13862 (define_expand "bordered"
13864 (if_then_else (match_dup 1)
13865 (label_ref (match_operand 0 "" ""))
13867 "TARGET_80387 || TARGET_SSE_MATH"
13868 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13870 (define_expand "buneq"
13872 (if_then_else (match_dup 1)
13873 (label_ref (match_operand 0 "" ""))
13875 "TARGET_80387 || TARGET_SSE_MATH"
13876 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13878 (define_expand "bunge"
13880 (if_then_else (match_dup 1)
13881 (label_ref (match_operand 0 "" ""))
13883 "TARGET_80387 || TARGET_SSE_MATH"
13884 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13886 (define_expand "bungt"
13888 (if_then_else (match_dup 1)
13889 (label_ref (match_operand 0 "" ""))
13891 "TARGET_80387 || TARGET_SSE_MATH"
13892 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13894 (define_expand "bunle"
13896 (if_then_else (match_dup 1)
13897 (label_ref (match_operand 0 "" ""))
13899 "TARGET_80387 || TARGET_SSE_MATH"
13900 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13902 (define_expand "bunlt"
13904 (if_then_else (match_dup 1)
13905 (label_ref (match_operand 0 "" ""))
13907 "TARGET_80387 || TARGET_SSE_MATH"
13908 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13910 (define_expand "bltgt"
13912 (if_then_else (match_dup 1)
13913 (label_ref (match_operand 0 "" ""))
13915 "TARGET_80387 || TARGET_SSE_MATH"
13916 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13918 (define_insn "*jcc_1"
13920 (if_then_else (match_operator 1 "ix86_comparison_operator"
13921 [(reg FLAGS_REG) (const_int 0)])
13922 (label_ref (match_operand 0 "" ""))
13926 [(set_attr "type" "ibr")
13927 (set_attr "modrm" "0")
13928 (set (attr "length")
13929 (if_then_else (and (ge (minus (match_dup 0) (pc))
13931 (lt (minus (match_dup 0) (pc))
13936 (define_insn "*jcc_2"
13938 (if_then_else (match_operator 1 "ix86_comparison_operator"
13939 [(reg FLAGS_REG) (const_int 0)])
13941 (label_ref (match_operand 0 "" ""))))]
13944 [(set_attr "type" "ibr")
13945 (set_attr "modrm" "0")
13946 (set (attr "length")
13947 (if_then_else (and (ge (minus (match_dup 0) (pc))
13949 (lt (minus (match_dup 0) (pc))
13954 ;; In general it is not safe to assume too much about CCmode registers,
13955 ;; so simplify-rtx stops when it sees a second one. Under certain
13956 ;; conditions this is safe on x86, so help combine not create
13964 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13965 [(reg FLAGS_REG) (const_int 0)])
13967 (label_ref (match_operand 1 "" ""))
13971 (if_then_else (match_dup 0)
13972 (label_ref (match_dup 1))
13975 PUT_MODE (operands[0], VOIDmode);
13980 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13981 [(reg FLAGS_REG) (const_int 0)])
13983 (label_ref (match_operand 1 "" ""))
13987 (if_then_else (match_dup 0)
13988 (label_ref (match_dup 1))
13991 rtx new_op0 = copy_rtx (operands[0]);
13992 operands[0] = new_op0;
13993 PUT_MODE (new_op0, VOIDmode);
13994 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13995 GET_MODE (XEXP (new_op0, 0))));
13997 /* Make sure that (a) the CCmode we have for the flags is strong
13998 enough for the reversed compare or (b) we have a valid FP compare. */
13999 if (! ix86_comparison_operator (new_op0, VOIDmode))
14003 ;; Define combination compare-and-branch fp compare instructions to use
14004 ;; during early optimization. Splitting the operation apart early makes
14005 ;; for bad code when we want to reverse the operation.
14007 (define_insn "*fp_jcc_1_mixed"
14009 (if_then_else (match_operator 0 "comparison_operator"
14010 [(match_operand 1 "register_operand" "f,x")
14011 (match_operand 2 "nonimmediate_operand" "f,xm")])
14012 (label_ref (match_operand 3 "" ""))
14014 (clobber (reg:CCFP FPSR_REG))
14015 (clobber (reg:CCFP FLAGS_REG))]
14016 "TARGET_MIX_SSE_I387
14017 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14018 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14019 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14022 (define_insn "*fp_jcc_1_sse"
14024 (if_then_else (match_operator 0 "comparison_operator"
14025 [(match_operand 1 "register_operand" "x")
14026 (match_operand 2 "nonimmediate_operand" "xm")])
14027 (label_ref (match_operand 3 "" ""))
14029 (clobber (reg:CCFP FPSR_REG))
14030 (clobber (reg:CCFP FLAGS_REG))]
14032 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14033 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14034 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14037 (define_insn "*fp_jcc_1_387"
14039 (if_then_else (match_operator 0 "comparison_operator"
14040 [(match_operand 1 "register_operand" "f")
14041 (match_operand 2 "register_operand" "f")])
14042 (label_ref (match_operand 3 "" ""))
14044 (clobber (reg:CCFP FPSR_REG))
14045 (clobber (reg:CCFP FLAGS_REG))]
14046 "TARGET_CMOVE && TARGET_80387
14047 && FLOAT_MODE_P (GET_MODE (operands[1]))
14048 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14049 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14052 (define_insn "*fp_jcc_2_mixed"
14054 (if_then_else (match_operator 0 "comparison_operator"
14055 [(match_operand 1 "register_operand" "f,x")
14056 (match_operand 2 "nonimmediate_operand" "f,xm")])
14058 (label_ref (match_operand 3 "" ""))))
14059 (clobber (reg:CCFP FPSR_REG))
14060 (clobber (reg:CCFP FLAGS_REG))]
14061 "TARGET_MIX_SSE_I387
14062 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14063 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14064 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14067 (define_insn "*fp_jcc_2_sse"
14069 (if_then_else (match_operator 0 "comparison_operator"
14070 [(match_operand 1 "register_operand" "x")
14071 (match_operand 2 "nonimmediate_operand" "xm")])
14073 (label_ref (match_operand 3 "" ""))))
14074 (clobber (reg:CCFP FPSR_REG))
14075 (clobber (reg:CCFP FLAGS_REG))]
14077 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14078 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14079 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14082 (define_insn "*fp_jcc_2_387"
14084 (if_then_else (match_operator 0 "comparison_operator"
14085 [(match_operand 1 "register_operand" "f")
14086 (match_operand 2 "register_operand" "f")])
14088 (label_ref (match_operand 3 "" ""))))
14089 (clobber (reg:CCFP FPSR_REG))
14090 (clobber (reg:CCFP FLAGS_REG))]
14091 "TARGET_CMOVE && TARGET_80387
14092 && FLOAT_MODE_P (GET_MODE (operands[1]))
14093 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14094 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14097 (define_insn "*fp_jcc_3_387"
14099 (if_then_else (match_operator 0 "comparison_operator"
14100 [(match_operand 1 "register_operand" "f")
14101 (match_operand 2 "nonimmediate_operand" "fm")])
14102 (label_ref (match_operand 3 "" ""))
14104 (clobber (reg:CCFP FPSR_REG))
14105 (clobber (reg:CCFP FLAGS_REG))
14106 (clobber (match_scratch:HI 4 "=a"))]
14108 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14109 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14110 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14111 && SELECT_CC_MODE (GET_CODE (operands[0]),
14112 operands[1], operands[2]) == CCFPmode
14113 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14116 (define_insn "*fp_jcc_4_387"
14118 (if_then_else (match_operator 0 "comparison_operator"
14119 [(match_operand 1 "register_operand" "f")
14120 (match_operand 2 "nonimmediate_operand" "fm")])
14122 (label_ref (match_operand 3 "" ""))))
14123 (clobber (reg:CCFP FPSR_REG))
14124 (clobber (reg:CCFP FLAGS_REG))
14125 (clobber (match_scratch:HI 4 "=a"))]
14127 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14128 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14129 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14130 && SELECT_CC_MODE (GET_CODE (operands[0]),
14131 operands[1], operands[2]) == CCFPmode
14132 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14135 (define_insn "*fp_jcc_5_387"
14137 (if_then_else (match_operator 0 "comparison_operator"
14138 [(match_operand 1 "register_operand" "f")
14139 (match_operand 2 "register_operand" "f")])
14140 (label_ref (match_operand 3 "" ""))
14142 (clobber (reg:CCFP FPSR_REG))
14143 (clobber (reg:CCFP FLAGS_REG))
14144 (clobber (match_scratch:HI 4 "=a"))]
14146 && FLOAT_MODE_P (GET_MODE (operands[1]))
14147 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14148 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14151 (define_insn "*fp_jcc_6_387"
14153 (if_then_else (match_operator 0 "comparison_operator"
14154 [(match_operand 1 "register_operand" "f")
14155 (match_operand 2 "register_operand" "f")])
14157 (label_ref (match_operand 3 "" ""))))
14158 (clobber (reg:CCFP FPSR_REG))
14159 (clobber (reg:CCFP FLAGS_REG))
14160 (clobber (match_scratch:HI 4 "=a"))]
14162 && FLOAT_MODE_P (GET_MODE (operands[1]))
14163 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14164 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14167 (define_insn "*fp_jcc_7_387"
14169 (if_then_else (match_operator 0 "comparison_operator"
14170 [(match_operand 1 "register_operand" "f")
14171 (match_operand 2 "const0_operand" "X")])
14172 (label_ref (match_operand 3 "" ""))
14174 (clobber (reg:CCFP FPSR_REG))
14175 (clobber (reg:CCFP FLAGS_REG))
14176 (clobber (match_scratch:HI 4 "=a"))]
14178 && FLOAT_MODE_P (GET_MODE (operands[1]))
14179 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14180 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14181 && SELECT_CC_MODE (GET_CODE (operands[0]),
14182 operands[1], operands[2]) == CCFPmode
14183 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14186 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14187 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14188 ;; with a precedence over other operators and is always put in the first
14189 ;; place. Swap condition and operands to match ficom instruction.
14191 (define_insn "*fp_jcc_8<mode>_387"
14193 (if_then_else (match_operator 0 "comparison_operator"
14194 [(match_operator 1 "float_operator"
14195 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14196 (match_operand 3 "register_operand" "f,f")])
14197 (label_ref (match_operand 4 "" ""))
14199 (clobber (reg:CCFP FPSR_REG))
14200 (clobber (reg:CCFP FLAGS_REG))
14201 (clobber (match_scratch:HI 5 "=a,a"))]
14202 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
14203 && FLOAT_MODE_P (GET_MODE (operands[3]))
14204 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14205 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14206 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14207 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14212 (if_then_else (match_operator 0 "comparison_operator"
14213 [(match_operand 1 "register_operand" "")
14214 (match_operand 2 "nonimmediate_operand" "")])
14215 (match_operand 3 "" "")
14216 (match_operand 4 "" "")))
14217 (clobber (reg:CCFP FPSR_REG))
14218 (clobber (reg:CCFP FLAGS_REG))]
14222 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14223 operands[3], operands[4], NULL_RTX, NULL_RTX);
14229 (if_then_else (match_operator 0 "comparison_operator"
14230 [(match_operand 1 "register_operand" "")
14231 (match_operand 2 "general_operand" "")])
14232 (match_operand 3 "" "")
14233 (match_operand 4 "" "")))
14234 (clobber (reg:CCFP FPSR_REG))
14235 (clobber (reg:CCFP FLAGS_REG))
14236 (clobber (match_scratch:HI 5 "=a"))]
14240 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14241 operands[3], operands[4], operands[5], NULL_RTX);
14247 (if_then_else (match_operator 0 "comparison_operator"
14248 [(match_operator 1 "float_operator"
14249 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14250 (match_operand 3 "register_operand" "")])
14251 (match_operand 4 "" "")
14252 (match_operand 5 "" "")))
14253 (clobber (reg:CCFP FPSR_REG))
14254 (clobber (reg:CCFP FLAGS_REG))
14255 (clobber (match_scratch:HI 6 "=a"))]
14259 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14260 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14261 operands[3], operands[7],
14262 operands[4], operands[5], operands[6], NULL_RTX);
14266 ;; %%% Kill this when reload knows how to do it.
14269 (if_then_else (match_operator 0 "comparison_operator"
14270 [(match_operator 1 "float_operator"
14271 [(match_operand:X87MODEI12 2 "register_operand" "")])
14272 (match_operand 3 "register_operand" "")])
14273 (match_operand 4 "" "")
14274 (match_operand 5 "" "")))
14275 (clobber (reg:CCFP FPSR_REG))
14276 (clobber (reg:CCFP FLAGS_REG))
14277 (clobber (match_scratch:HI 6 "=a"))]
14281 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14282 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14283 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14284 operands[3], operands[7],
14285 operands[4], operands[5], operands[6], operands[2]);
14289 ;; Unconditional and other jump instructions
14291 (define_insn "jump"
14293 (label_ref (match_operand 0 "" "")))]
14296 [(set_attr "type" "ibr")
14297 (set (attr "length")
14298 (if_then_else (and (ge (minus (match_dup 0) (pc))
14300 (lt (minus (match_dup 0) (pc))
14304 (set_attr "modrm" "0")])
14306 (define_expand "indirect_jump"
14307 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
14311 (define_insn "*indirect_jump"
14312 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14315 [(set_attr "type" "ibr")
14316 (set_attr "length_immediate" "0")])
14318 (define_insn "*indirect_jump_rtx64"
14319 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14322 [(set_attr "type" "ibr")
14323 (set_attr "length_immediate" "0")])
14325 (define_expand "tablejump"
14326 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
14327 (use (label_ref (match_operand 1 "" "")))])]
14330 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14331 relative. Convert the relative address to an absolute address. */
14335 enum rtx_code code;
14341 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14343 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14347 op1 = pic_offset_table_rtx;
14352 op0 = pic_offset_table_rtx;
14356 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14361 (define_insn "*tablejump_1"
14362 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14363 (use (label_ref (match_operand 1 "" "")))]
14366 [(set_attr "type" "ibr")
14367 (set_attr "length_immediate" "0")])
14369 (define_insn "*tablejump_1_rtx64"
14370 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14371 (use (label_ref (match_operand 1 "" "")))]
14374 [(set_attr "type" "ibr")
14375 (set_attr "length_immediate" "0")])
14377 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14380 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14381 (set (match_operand:QI 1 "register_operand" "")
14382 (match_operator:QI 2 "ix86_comparison_operator"
14383 [(reg FLAGS_REG) (const_int 0)]))
14384 (set (match_operand 3 "q_regs_operand" "")
14385 (zero_extend (match_dup 1)))]
14386 "(peep2_reg_dead_p (3, operands[1])
14387 || operands_match_p (operands[1], operands[3]))
14388 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14389 [(set (match_dup 4) (match_dup 0))
14390 (set (strict_low_part (match_dup 5))
14393 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14394 operands[5] = gen_lowpart (QImode, operands[3]);
14395 ix86_expand_clear (operands[3]);
14398 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14401 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14402 (set (match_operand:QI 1 "register_operand" "")
14403 (match_operator:QI 2 "ix86_comparison_operator"
14404 [(reg FLAGS_REG) (const_int 0)]))
14405 (parallel [(set (match_operand 3 "q_regs_operand" "")
14406 (zero_extend (match_dup 1)))
14407 (clobber (reg:CC FLAGS_REG))])]
14408 "(peep2_reg_dead_p (3, operands[1])
14409 || operands_match_p (operands[1], operands[3]))
14410 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14411 [(set (match_dup 4) (match_dup 0))
14412 (set (strict_low_part (match_dup 5))
14415 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14416 operands[5] = gen_lowpart (QImode, operands[3]);
14417 ix86_expand_clear (operands[3]);
14420 ;; Call instructions.
14422 ;; The predicates normally associated with named expanders are not properly
14423 ;; checked for calls. This is a bug in the generic code, but it isn't that
14424 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14426 ;; Call subroutine returning no value.
14428 (define_expand "call_pop"
14429 [(parallel [(call (match_operand:QI 0 "" "")
14430 (match_operand:SI 1 "" ""))
14431 (set (reg:SI SP_REG)
14432 (plus:SI (reg:SI SP_REG)
14433 (match_operand:SI 3 "" "")))])]
14436 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14440 (define_insn "*call_pop_0"
14441 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14442 (match_operand:SI 1 "" ""))
14443 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14444 (match_operand:SI 2 "immediate_operand" "")))]
14447 if (SIBLING_CALL_P (insn))
14450 return "call\t%P0";
14452 [(set_attr "type" "call")])
14454 (define_insn "*call_pop_1"
14455 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14456 (match_operand:SI 1 "" ""))
14457 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14458 (match_operand:SI 2 "immediate_operand" "i")))]
14461 if (constant_call_address_operand (operands[0], Pmode))
14463 if (SIBLING_CALL_P (insn))
14466 return "call\t%P0";
14468 if (SIBLING_CALL_P (insn))
14471 return "call\t%A0";
14473 [(set_attr "type" "call")])
14475 (define_expand "call"
14476 [(call (match_operand:QI 0 "" "")
14477 (match_operand 1 "" ""))
14478 (use (match_operand 2 "" ""))]
14481 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14485 (define_expand "sibcall"
14486 [(call (match_operand:QI 0 "" "")
14487 (match_operand 1 "" ""))
14488 (use (match_operand 2 "" ""))]
14491 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14495 (define_insn "*call_0"
14496 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14497 (match_operand 1 "" ""))]
14500 if (SIBLING_CALL_P (insn))
14503 return "call\t%P0";
14505 [(set_attr "type" "call")])
14507 (define_insn "*call_1"
14508 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14509 (match_operand 1 "" ""))]
14510 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14512 if (constant_call_address_operand (operands[0], Pmode))
14513 return "call\t%P0";
14514 return "call\t%A0";
14516 [(set_attr "type" "call")])
14518 (define_insn "*sibcall_1"
14519 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14520 (match_operand 1 "" ""))]
14521 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14523 if (constant_call_address_operand (operands[0], Pmode))
14527 [(set_attr "type" "call")])
14529 (define_insn "*call_1_rex64"
14530 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14531 (match_operand 1 "" ""))]
14532 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14534 if (constant_call_address_operand (operands[0], Pmode))
14535 return "call\t%P0";
14536 return "call\t%A0";
14538 [(set_attr "type" "call")])
14540 (define_insn "*sibcall_1_rex64"
14541 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14542 (match_operand 1 "" ""))]
14543 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14545 [(set_attr "type" "call")])
14547 (define_insn "*sibcall_1_rex64_v"
14548 [(call (mem:QI (reg:DI R11_REG))
14549 (match_operand 0 "" ""))]
14550 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14552 [(set_attr "type" "call")])
14555 ;; Call subroutine, returning value in operand 0
14557 (define_expand "call_value_pop"
14558 [(parallel [(set (match_operand 0 "" "")
14559 (call (match_operand:QI 1 "" "")
14560 (match_operand:SI 2 "" "")))
14561 (set (reg:SI SP_REG)
14562 (plus:SI (reg:SI SP_REG)
14563 (match_operand:SI 4 "" "")))])]
14566 ix86_expand_call (operands[0], operands[1], operands[2],
14567 operands[3], operands[4], 0);
14571 (define_expand "call_value"
14572 [(set (match_operand 0 "" "")
14573 (call (match_operand:QI 1 "" "")
14574 (match_operand:SI 2 "" "")))
14575 (use (match_operand:SI 3 "" ""))]
14576 ;; Operand 2 not used on the i386.
14579 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14583 (define_expand "sibcall_value"
14584 [(set (match_operand 0 "" "")
14585 (call (match_operand:QI 1 "" "")
14586 (match_operand:SI 2 "" "")))
14587 (use (match_operand:SI 3 "" ""))]
14588 ;; Operand 2 not used on the i386.
14591 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14595 ;; Call subroutine returning any type.
14597 (define_expand "untyped_call"
14598 [(parallel [(call (match_operand 0 "" "")
14600 (match_operand 1 "" "")
14601 (match_operand 2 "" "")])]
14606 /* In order to give reg-stack an easier job in validating two
14607 coprocessor registers as containing a possible return value,
14608 simply pretend the untyped call returns a complex long double
14611 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14612 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14613 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14616 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14618 rtx set = XVECEXP (operands[2], 0, i);
14619 emit_move_insn (SET_DEST (set), SET_SRC (set));
14622 /* The optimizer does not know that the call sets the function value
14623 registers we stored in the result block. We avoid problems by
14624 claiming that all hard registers are used and clobbered at this
14626 emit_insn (gen_blockage (const0_rtx));
14631 ;; Prologue and epilogue instructions
14633 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14634 ;; all of memory. This blocks insns from being moved across this point.
14636 (define_insn "blockage"
14637 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14640 [(set_attr "length" "0")])
14642 ;; Insn emitted into the body of a function to return from a function.
14643 ;; This is only done if the function's epilogue is known to be simple.
14644 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14646 (define_expand "return"
14648 "ix86_can_use_return_insn_p ()"
14650 if (current_function_pops_args)
14652 rtx popc = GEN_INT (current_function_pops_args);
14653 emit_jump_insn (gen_return_pop_internal (popc));
14658 (define_insn "return_internal"
14662 [(set_attr "length" "1")
14663 (set_attr "length_immediate" "0")
14664 (set_attr "modrm" "0")])
14666 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14667 ;; instruction Athlon and K8 have.
14669 (define_insn "return_internal_long"
14671 (unspec [(const_int 0)] UNSPEC_REP)]
14674 [(set_attr "length" "1")
14675 (set_attr "length_immediate" "0")
14676 (set_attr "prefix_rep" "1")
14677 (set_attr "modrm" "0")])
14679 (define_insn "return_pop_internal"
14681 (use (match_operand:SI 0 "const_int_operand" ""))]
14684 [(set_attr "length" "3")
14685 (set_attr "length_immediate" "2")
14686 (set_attr "modrm" "0")])
14688 (define_insn "return_indirect_internal"
14690 (use (match_operand:SI 0 "register_operand" "r"))]
14693 [(set_attr "type" "ibr")
14694 (set_attr "length_immediate" "0")])
14700 [(set_attr "length" "1")
14701 (set_attr "length_immediate" "0")
14702 (set_attr "modrm" "0")])
14704 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14705 ;; branch prediction penalty for the third jump in a 16-byte
14708 (define_insn "align"
14709 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14712 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14713 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14715 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14716 The align insn is used to avoid 3 jump instructions in the row to improve
14717 branch prediction and the benefits hardly outweigh the cost of extra 8
14718 nops on the average inserted by full alignment pseudo operation. */
14722 [(set_attr "length" "16")])
14724 (define_expand "prologue"
14727 "ix86_expand_prologue (); DONE;")
14729 (define_insn "set_got"
14730 [(set (match_operand:SI 0 "register_operand" "=r")
14731 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14732 (clobber (reg:CC FLAGS_REG))]
14734 { return output_set_got (operands[0], NULL_RTX); }
14735 [(set_attr "type" "multi")
14736 (set_attr "length" "12")])
14738 (define_insn "set_got_labelled"
14739 [(set (match_operand:SI 0 "register_operand" "=r")
14740 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14742 (clobber (reg:CC FLAGS_REG))]
14744 { return output_set_got (operands[0], operands[1]); }
14745 [(set_attr "type" "multi")
14746 (set_attr "length" "12")])
14748 (define_insn "set_got_rex64"
14749 [(set (match_operand:DI 0 "register_operand" "=r")
14750 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14752 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14753 [(set_attr "type" "lea")
14754 (set_attr "length" "6")])
14756 (define_expand "epilogue"
14759 "ix86_expand_epilogue (1); DONE;")
14761 (define_expand "sibcall_epilogue"
14764 "ix86_expand_epilogue (0); DONE;")
14766 (define_expand "eh_return"
14767 [(use (match_operand 0 "register_operand" ""))]
14770 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14772 /* Tricky bit: we write the address of the handler to which we will
14773 be returning into someone else's stack frame, one word below the
14774 stack address we wish to restore. */
14775 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14776 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14777 tmp = gen_rtx_MEM (Pmode, tmp);
14778 emit_move_insn (tmp, ra);
14780 if (Pmode == SImode)
14781 emit_jump_insn (gen_eh_return_si (sa));
14783 emit_jump_insn (gen_eh_return_di (sa));
14788 (define_insn_and_split "eh_return_si"
14790 (unspec [(match_operand:SI 0 "register_operand" "c")]
14791 UNSPEC_EH_RETURN))]
14796 "ix86_expand_epilogue (2); DONE;")
14798 (define_insn_and_split "eh_return_di"
14800 (unspec [(match_operand:DI 0 "register_operand" "c")]
14801 UNSPEC_EH_RETURN))]
14806 "ix86_expand_epilogue (2); DONE;")
14808 (define_insn "leave"
14809 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14810 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14811 (clobber (mem:BLK (scratch)))]
14814 [(set_attr "type" "leave")])
14816 (define_insn "leave_rex64"
14817 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14818 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14819 (clobber (mem:BLK (scratch)))]
14822 [(set_attr "type" "leave")])
14824 (define_expand "ffssi2"
14826 [(set (match_operand:SI 0 "register_operand" "")
14827 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14828 (clobber (match_scratch:SI 2 ""))
14829 (clobber (reg:CC FLAGS_REG))])]
14833 (define_insn_and_split "*ffs_cmove"
14834 [(set (match_operand:SI 0 "register_operand" "=r")
14835 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14836 (clobber (match_scratch:SI 2 "=&r"))
14837 (clobber (reg:CC FLAGS_REG))]
14840 "&& reload_completed"
14841 [(set (match_dup 2) (const_int -1))
14842 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14843 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14844 (set (match_dup 0) (if_then_else:SI
14845 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14848 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14849 (clobber (reg:CC FLAGS_REG))])]
14852 (define_insn_and_split "*ffs_no_cmove"
14853 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14854 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14855 (clobber (match_scratch:SI 2 "=&q"))
14856 (clobber (reg:CC FLAGS_REG))]
14860 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14861 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14862 (set (strict_low_part (match_dup 3))
14863 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14864 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14865 (clobber (reg:CC FLAGS_REG))])
14866 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14867 (clobber (reg:CC FLAGS_REG))])
14868 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14869 (clobber (reg:CC FLAGS_REG))])]
14871 operands[3] = gen_lowpart (QImode, operands[2]);
14872 ix86_expand_clear (operands[2]);
14875 (define_insn "*ffssi_1"
14876 [(set (reg:CCZ FLAGS_REG)
14877 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14879 (set (match_operand:SI 0 "register_operand" "=r")
14880 (ctz:SI (match_dup 1)))]
14882 "bsf{l}\t{%1, %0|%0, %1}"
14883 [(set_attr "prefix_0f" "1")])
14885 (define_expand "ffsdi2"
14887 [(set (match_operand:DI 0 "register_operand" "")
14888 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14889 (clobber (match_scratch:DI 2 ""))
14890 (clobber (reg:CC FLAGS_REG))])]
14891 "TARGET_64BIT && TARGET_CMOVE"
14894 (define_insn_and_split "*ffs_rex64"
14895 [(set (match_operand:DI 0 "register_operand" "=r")
14896 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14897 (clobber (match_scratch:DI 2 "=&r"))
14898 (clobber (reg:CC FLAGS_REG))]
14899 "TARGET_64BIT && TARGET_CMOVE"
14901 "&& reload_completed"
14902 [(set (match_dup 2) (const_int -1))
14903 (parallel [(set (reg:CCZ FLAGS_REG)
14904 (compare:CCZ (match_dup 1) (const_int 0)))
14905 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14906 (set (match_dup 0) (if_then_else:DI
14907 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14910 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14911 (clobber (reg:CC FLAGS_REG))])]
14914 (define_insn "*ffsdi_1"
14915 [(set (reg:CCZ FLAGS_REG)
14916 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14918 (set (match_operand:DI 0 "register_operand" "=r")
14919 (ctz:DI (match_dup 1)))]
14921 "bsf{q}\t{%1, %0|%0, %1}"
14922 [(set_attr "prefix_0f" "1")])
14924 (define_insn "ctzsi2"
14925 [(set (match_operand:SI 0 "register_operand" "=r")
14926 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14927 (clobber (reg:CC FLAGS_REG))]
14929 "bsf{l}\t{%1, %0|%0, %1}"
14930 [(set_attr "prefix_0f" "1")])
14932 (define_insn "ctzdi2"
14933 [(set (match_operand:DI 0 "register_operand" "=r")
14934 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14935 (clobber (reg:CC FLAGS_REG))]
14937 "bsf{q}\t{%1, %0|%0, %1}"
14938 [(set_attr "prefix_0f" "1")])
14940 (define_expand "clzsi2"
14942 [(set (match_operand:SI 0 "register_operand" "")
14943 (minus:SI (const_int 31)
14944 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14945 (clobber (reg:CC FLAGS_REG))])
14947 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14948 (clobber (reg:CC FLAGS_REG))])]
14953 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14958 (define_insn "clzsi2_abm"
14959 [(set (match_operand:SI 0 "register_operand" "=r")
14960 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14961 (clobber (reg:CC FLAGS_REG))]
14963 "lzcnt{l}\t{%1, %0|%0, %1}"
14964 [(set_attr "prefix_rep" "1")
14965 (set_attr "type" "bitmanip")
14966 (set_attr "mode" "SI")])
14968 (define_insn "*bsr"
14969 [(set (match_operand:SI 0 "register_operand" "=r")
14970 (minus:SI (const_int 31)
14971 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14972 (clobber (reg:CC FLAGS_REG))]
14974 "bsr{l}\t{%1, %0|%0, %1}"
14975 [(set_attr "prefix_0f" "1")
14976 (set_attr "mode" "SI")])
14978 (define_insn "popcountsi2"
14979 [(set (match_operand:SI 0 "register_operand" "=r")
14980 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14981 (clobber (reg:CC FLAGS_REG))]
14983 "popcnt{l}\t{%1, %0|%0, %1}"
14984 [(set_attr "prefix_rep" "1")
14985 (set_attr "type" "bitmanip")
14986 (set_attr "mode" "SI")])
14988 (define_insn "*popcountsi2_cmp"
14989 [(set (reg FLAGS_REG)
14991 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14993 (set (match_operand:SI 0 "register_operand" "=r")
14994 (popcount:SI (match_dup 1)))]
14995 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14996 "popcnt{l}\t{%1, %0|%0, %1}"
14997 [(set_attr "prefix_rep" "1")
14998 (set_attr "type" "bitmanip")
14999 (set_attr "mode" "SI")])
15001 (define_insn "*popcountsi2_cmp_zext"
15002 [(set (reg FLAGS_REG)
15004 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15006 (set (match_operand:DI 0 "register_operand" "=r")
15007 (zero_extend:DI(popcount:SI (match_dup 1))))]
15008 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15009 "popcnt{l}\t{%1, %0|%0, %1}"
15010 [(set_attr "prefix_rep" "1")
15011 (set_attr "type" "bitmanip")
15012 (set_attr "mode" "SI")])
15014 (define_expand "bswapsi2"
15015 [(set (match_operand:SI 0 "register_operand" "")
15016 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15021 rtx x = operands[0];
15023 emit_move_insn (x, operands[1]);
15024 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15025 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15026 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15031 (define_insn "*bswapsi_1"
15032 [(set (match_operand:SI 0 "register_operand" "=r")
15033 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15036 [(set_attr "prefix_0f" "1")
15037 (set_attr "length" "2")])
15039 (define_insn "*bswaphi_lowpart_1"
15040 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15041 (bswap:HI (match_dup 0)))
15042 (clobber (reg:CC FLAGS_REG))]
15043 "TARGET_USE_XCHGB || optimize_size"
15045 xchg{b}\t{%h0, %b0|%b0, %h0}
15046 rol{w}\t{$8, %0|%0, 8}"
15047 [(set_attr "length" "2,4")
15048 (set_attr "mode" "QI,HI")])
15050 (define_insn "bswaphi_lowpart"
15051 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15052 (bswap:HI (match_dup 0)))
15053 (clobber (reg:CC FLAGS_REG))]
15055 "rol{w}\t{$8, %0|%0, 8}"
15056 [(set_attr "length" "4")
15057 (set_attr "mode" "HI")])
15059 (define_insn "bswapdi2"
15060 [(set (match_operand:DI 0 "register_operand" "=r")
15061 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15064 [(set_attr "prefix_0f" "1")
15065 (set_attr "length" "3")])
15067 (define_expand "clzdi2"
15069 [(set (match_operand:DI 0 "register_operand" "")
15070 (minus:DI (const_int 63)
15071 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15072 (clobber (reg:CC FLAGS_REG))])
15074 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15075 (clobber (reg:CC FLAGS_REG))])]
15080 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15085 (define_insn "clzdi2_abm"
15086 [(set (match_operand:DI 0 "register_operand" "=r")
15087 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15088 (clobber (reg:CC FLAGS_REG))]
15089 "TARGET_64BIT && TARGET_ABM"
15090 "lzcnt{q}\t{%1, %0|%0, %1}"
15091 [(set_attr "prefix_rep" "1")
15092 (set_attr "type" "bitmanip")
15093 (set_attr "mode" "DI")])
15095 (define_insn "*bsr_rex64"
15096 [(set (match_operand:DI 0 "register_operand" "=r")
15097 (minus:DI (const_int 63)
15098 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15099 (clobber (reg:CC FLAGS_REG))]
15101 "bsr{q}\t{%1, %0|%0, %1}"
15102 [(set_attr "prefix_0f" "1")
15103 (set_attr "mode" "DI")])
15105 (define_insn "popcountdi2"
15106 [(set (match_operand:DI 0 "register_operand" "=r")
15107 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15108 (clobber (reg:CC FLAGS_REG))]
15109 "TARGET_64BIT && TARGET_POPCNT"
15110 "popcnt{q}\t{%1, %0|%0, %1}"
15111 [(set_attr "prefix_rep" "1")
15112 (set_attr "type" "bitmanip")
15113 (set_attr "mode" "DI")])
15115 (define_insn "*popcountdi2_cmp"
15116 [(set (reg FLAGS_REG)
15118 (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15120 (set (match_operand:DI 0 "register_operand" "=r")
15121 (popcount:DI (match_dup 1)))]
15122 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15123 "popcnt{q}\t{%1, %0|%0, %1}"
15124 [(set_attr "prefix_rep" "1")
15125 (set_attr "type" "bitmanip")
15126 (set_attr "mode" "DI")])
15128 (define_expand "clzhi2"
15130 [(set (match_operand:HI 0 "register_operand" "")
15131 (minus:HI (const_int 15)
15132 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15133 (clobber (reg:CC FLAGS_REG))])
15135 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15136 (clobber (reg:CC FLAGS_REG))])]
15141 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15146 (define_insn "clzhi2_abm"
15147 [(set (match_operand:HI 0 "register_operand" "=r")
15148 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15149 (clobber (reg:CC FLAGS_REG))]
15151 "lzcnt{w}\t{%1, %0|%0, %1}"
15152 [(set_attr "prefix_rep" "1")
15153 (set_attr "type" "bitmanip")
15154 (set_attr "mode" "HI")])
15156 (define_insn "*bsrhi"
15157 [(set (match_operand:HI 0 "register_operand" "=r")
15158 (minus:HI (const_int 15)
15159 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15160 (clobber (reg:CC FLAGS_REG))]
15162 "bsr{w}\t{%1, %0|%0, %1}"
15163 [(set_attr "prefix_0f" "1")
15164 (set_attr "mode" "HI")])
15166 (define_insn "popcounthi2"
15167 [(set (match_operand:HI 0 "register_operand" "=r")
15168 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15169 (clobber (reg:CC FLAGS_REG))]
15171 "popcnt{w}\t{%1, %0|%0, %1}"
15172 [(set_attr "prefix_rep" "1")
15173 (set_attr "type" "bitmanip")
15174 (set_attr "mode" "HI")])
15176 (define_insn "*popcounthi2_cmp"
15177 [(set (reg FLAGS_REG)
15179 (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15181 (set (match_operand:HI 0 "register_operand" "=r")
15182 (popcount:HI (match_dup 1)))]
15183 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15184 "popcnt{w}\t{%1, %0|%0, %1}"
15185 [(set_attr "prefix_rep" "1")
15186 (set_attr "type" "bitmanip")
15187 (set_attr "mode" "HI")])
15189 (define_expand "paritydi2"
15190 [(set (match_operand:DI 0 "register_operand" "")
15191 (parity:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
15194 rtx scratch = gen_reg_rtx (QImode);
15197 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15198 NULL_RTX, operands[1]));
15200 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15201 gen_rtx_REG (CCmode, FLAGS_REG),
15203 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15206 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15209 rtx tmp = gen_reg_rtx (SImode);
15211 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15212 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15217 (define_insn_and_split "paritydi2_cmp"
15218 [(set (reg:CC FLAGS_REG)
15219 (parity:CC (match_operand:DI 3 "nonimmediate_operand" "0,m")))
15220 (clobber (match_scratch:DI 0 "=r,X"))
15221 (clobber (match_scratch:SI 1 "=r,r"))
15222 (clobber (match_scratch:HI 2 "=Q,Q"))]
15225 "&& reload_completed"
15227 [(set (match_dup 1)
15228 (xor:SI (match_dup 1) (match_dup 4)))
15229 (clobber (reg:CC FLAGS_REG))])
15231 [(set (reg:CC FLAGS_REG)
15232 (parity:CC (match_dup 1)))
15233 (clobber (match_dup 1))
15234 (clobber (match_dup 2))])]
15236 operands[4] = gen_lowpart (SImode, operands[3]);
15238 if (MEM_P (operands[3]))
15239 emit_move_insn (operands[1], gen_highpart (SImode, operands[3]));
15240 else if (! TARGET_64BIT)
15241 operands[1] = gen_highpart (SImode, operands[3]);
15244 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15245 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15249 (define_expand "paritysi2"
15250 [(set (match_operand:SI 0 "register_operand" "")
15251 (parity:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
15254 rtx scratch = gen_reg_rtx (QImode);
15257 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15259 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15260 gen_rtx_REG (CCmode, FLAGS_REG),
15262 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15264 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15268 (define_insn_and_split "paritysi2_cmp"
15269 [(set (reg:CC FLAGS_REG)
15270 (parity:CC (match_operand:SI 2 "nonimmediate_operand" "0,m")))
15271 (clobber (match_scratch:SI 0 "=r,X"))
15272 (clobber (match_scratch:HI 1 "=Q,Q"))]
15275 "&& reload_completed"
15277 [(set (match_dup 1)
15278 (xor:HI (match_dup 1) (match_dup 3)))
15279 (clobber (reg:CC FLAGS_REG))])
15281 [(set (reg:CC FLAGS_REG)
15282 (parity:CC (match_dup 1)))
15283 (clobber (match_dup 1))])]
15285 operands[3] = gen_lowpart (HImode, operands[2]);
15287 if (MEM_P (operands[2]))
15288 emit_move_insn (operands[1], gen_highpart (HImode, operands[2]));
15291 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15292 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15296 (define_insn "*parityhi2_cmp"
15297 [(set (reg:CC FLAGS_REG)
15298 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15299 (clobber (match_scratch:HI 0 "=Q"))]
15301 "xor{b}\t{%h0, %b0|%b0, %h0}"
15302 [(set_attr "length" "2")
15303 (set_attr "mode" "HI")])
15305 (define_insn "*parityqi2_cmp"
15306 [(set (reg:CC FLAGS_REG)
15307 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15310 [(set_attr "length" "2")
15311 (set_attr "mode" "QI")])
15313 ;; Thread-local storage patterns for ELF.
15315 ;; Note that these code sequences must appear exactly as shown
15316 ;; in order to allow linker relaxation.
15318 (define_insn "*tls_global_dynamic_32_gnu"
15319 [(set (match_operand:SI 0 "register_operand" "=a")
15320 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15321 (match_operand:SI 2 "tls_symbolic_operand" "")
15322 (match_operand:SI 3 "call_insn_operand" "")]
15324 (clobber (match_scratch:SI 4 "=d"))
15325 (clobber (match_scratch:SI 5 "=c"))
15326 (clobber (reg:CC FLAGS_REG))]
15327 "!TARGET_64BIT && TARGET_GNU_TLS"
15328 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15329 [(set_attr "type" "multi")
15330 (set_attr "length" "12")])
15332 (define_insn "*tls_global_dynamic_32_sun"
15333 [(set (match_operand:SI 0 "register_operand" "=a")
15334 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15335 (match_operand:SI 2 "tls_symbolic_operand" "")
15336 (match_operand:SI 3 "call_insn_operand" "")]
15338 (clobber (match_scratch:SI 4 "=d"))
15339 (clobber (match_scratch:SI 5 "=c"))
15340 (clobber (reg:CC FLAGS_REG))]
15341 "!TARGET_64BIT && TARGET_SUN_TLS"
15342 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15343 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15344 [(set_attr "type" "multi")
15345 (set_attr "length" "14")])
15347 (define_expand "tls_global_dynamic_32"
15348 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15351 (match_operand:SI 1 "tls_symbolic_operand" "")
15354 (clobber (match_scratch:SI 4 ""))
15355 (clobber (match_scratch:SI 5 ""))
15356 (clobber (reg:CC FLAGS_REG))])]
15360 operands[2] = pic_offset_table_rtx;
15363 operands[2] = gen_reg_rtx (Pmode);
15364 emit_insn (gen_set_got (operands[2]));
15366 if (TARGET_GNU2_TLS)
15368 emit_insn (gen_tls_dynamic_gnu2_32
15369 (operands[0], operands[1], operands[2]));
15372 operands[3] = ix86_tls_get_addr ();
15375 (define_insn "*tls_global_dynamic_64"
15376 [(set (match_operand:DI 0 "register_operand" "=a")
15377 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15378 (match_operand:DI 3 "" "")))
15379 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15382 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15383 [(set_attr "type" "multi")
15384 (set_attr "length" "16")])
15386 (define_expand "tls_global_dynamic_64"
15387 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15388 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15389 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15393 if (TARGET_GNU2_TLS)
15395 emit_insn (gen_tls_dynamic_gnu2_64
15396 (operands[0], operands[1]));
15399 operands[2] = ix86_tls_get_addr ();
15402 (define_insn "*tls_local_dynamic_base_32_gnu"
15403 [(set (match_operand:SI 0 "register_operand" "=a")
15404 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15405 (match_operand:SI 2 "call_insn_operand" "")]
15406 UNSPEC_TLS_LD_BASE))
15407 (clobber (match_scratch:SI 3 "=d"))
15408 (clobber (match_scratch:SI 4 "=c"))
15409 (clobber (reg:CC FLAGS_REG))]
15410 "!TARGET_64BIT && TARGET_GNU_TLS"
15411 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15412 [(set_attr "type" "multi")
15413 (set_attr "length" "11")])
15415 (define_insn "*tls_local_dynamic_base_32_sun"
15416 [(set (match_operand:SI 0 "register_operand" "=a")
15417 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15418 (match_operand:SI 2 "call_insn_operand" "")]
15419 UNSPEC_TLS_LD_BASE))
15420 (clobber (match_scratch:SI 3 "=d"))
15421 (clobber (match_scratch:SI 4 "=c"))
15422 (clobber (reg:CC FLAGS_REG))]
15423 "!TARGET_64BIT && TARGET_SUN_TLS"
15424 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15425 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15426 [(set_attr "type" "multi")
15427 (set_attr "length" "13")])
15429 (define_expand "tls_local_dynamic_base_32"
15430 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15431 (unspec:SI [(match_dup 1) (match_dup 2)]
15432 UNSPEC_TLS_LD_BASE))
15433 (clobber (match_scratch:SI 3 ""))
15434 (clobber (match_scratch:SI 4 ""))
15435 (clobber (reg:CC FLAGS_REG))])]
15439 operands[1] = pic_offset_table_rtx;
15442 operands[1] = gen_reg_rtx (Pmode);
15443 emit_insn (gen_set_got (operands[1]));
15445 if (TARGET_GNU2_TLS)
15447 emit_insn (gen_tls_dynamic_gnu2_32
15448 (operands[0], ix86_tls_module_base (), operands[1]));
15451 operands[2] = ix86_tls_get_addr ();
15454 (define_insn "*tls_local_dynamic_base_64"
15455 [(set (match_operand:DI 0 "register_operand" "=a")
15456 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15457 (match_operand:DI 2 "" "")))
15458 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15460 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
15461 [(set_attr "type" "multi")
15462 (set_attr "length" "12")])
15464 (define_expand "tls_local_dynamic_base_64"
15465 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15466 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15467 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15470 if (TARGET_GNU2_TLS)
15472 emit_insn (gen_tls_dynamic_gnu2_64
15473 (operands[0], ix86_tls_module_base ()));
15476 operands[1] = ix86_tls_get_addr ();
15479 ;; Local dynamic of a single variable is a lose. Show combine how
15480 ;; to convert that back to global dynamic.
15482 (define_insn_and_split "*tls_local_dynamic_32_once"
15483 [(set (match_operand:SI 0 "register_operand" "=a")
15484 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15485 (match_operand:SI 2 "call_insn_operand" "")]
15486 UNSPEC_TLS_LD_BASE)
15487 (const:SI (unspec:SI
15488 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15490 (clobber (match_scratch:SI 4 "=d"))
15491 (clobber (match_scratch:SI 5 "=c"))
15492 (clobber (reg:CC FLAGS_REG))]
15496 [(parallel [(set (match_dup 0)
15497 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15499 (clobber (match_dup 4))
15500 (clobber (match_dup 5))
15501 (clobber (reg:CC FLAGS_REG))])]
15504 ;; Load and add the thread base pointer from %gs:0.
15506 (define_insn "*load_tp_si"
15507 [(set (match_operand:SI 0 "register_operand" "=r")
15508 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15510 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15511 [(set_attr "type" "imov")
15512 (set_attr "modrm" "0")
15513 (set_attr "length" "7")
15514 (set_attr "memory" "load")
15515 (set_attr "imm_disp" "false")])
15517 (define_insn "*add_tp_si"
15518 [(set (match_operand:SI 0 "register_operand" "=r")
15519 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15520 (match_operand:SI 1 "register_operand" "0")))
15521 (clobber (reg:CC FLAGS_REG))]
15523 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
15524 [(set_attr "type" "alu")
15525 (set_attr "modrm" "0")
15526 (set_attr "length" "7")
15527 (set_attr "memory" "load")
15528 (set_attr "imm_disp" "false")])
15530 (define_insn "*load_tp_di"
15531 [(set (match_operand:DI 0 "register_operand" "=r")
15532 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15534 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15535 [(set_attr "type" "imov")
15536 (set_attr "modrm" "0")
15537 (set_attr "length" "7")
15538 (set_attr "memory" "load")
15539 (set_attr "imm_disp" "false")])
15541 (define_insn "*add_tp_di"
15542 [(set (match_operand:DI 0 "register_operand" "=r")
15543 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15544 (match_operand:DI 1 "register_operand" "0")))
15545 (clobber (reg:CC FLAGS_REG))]
15547 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
15548 [(set_attr "type" "alu")
15549 (set_attr "modrm" "0")
15550 (set_attr "length" "7")
15551 (set_attr "memory" "load")
15552 (set_attr "imm_disp" "false")])
15554 ;; GNU2 TLS patterns can be split.
15556 (define_expand "tls_dynamic_gnu2_32"
15557 [(set (match_dup 3)
15558 (plus:SI (match_operand:SI 2 "register_operand" "")
15560 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15563 [(set (match_operand:SI 0 "register_operand" "")
15564 (unspec:SI [(match_dup 1) (match_dup 3)
15565 (match_dup 2) (reg:SI SP_REG)]
15567 (clobber (reg:CC FLAGS_REG))])]
15568 "!TARGET_64BIT && TARGET_GNU2_TLS"
15570 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15571 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15574 (define_insn "*tls_dynamic_lea_32"
15575 [(set (match_operand:SI 0 "register_operand" "=r")
15576 (plus:SI (match_operand:SI 1 "register_operand" "b")
15578 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15579 UNSPEC_TLSDESC))))]
15580 "!TARGET_64BIT && TARGET_GNU2_TLS"
15581 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15582 [(set_attr "type" "lea")
15583 (set_attr "mode" "SI")
15584 (set_attr "length" "6")
15585 (set_attr "length_address" "4")])
15587 (define_insn "*tls_dynamic_call_32"
15588 [(set (match_operand:SI 0 "register_operand" "=a")
15589 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15590 (match_operand:SI 2 "register_operand" "0")
15591 ;; we have to make sure %ebx still points to the GOT
15592 (match_operand:SI 3 "register_operand" "b")
15595 (clobber (reg:CC FLAGS_REG))]
15596 "!TARGET_64BIT && TARGET_GNU2_TLS"
15597 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15598 [(set_attr "type" "call")
15599 (set_attr "length" "2")
15600 (set_attr "length_address" "0")])
15602 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15603 [(set (match_operand:SI 0 "register_operand" "=&a")
15605 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15606 (match_operand:SI 4 "" "")
15607 (match_operand:SI 2 "register_operand" "b")
15610 (const:SI (unspec:SI
15611 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15613 (clobber (reg:CC FLAGS_REG))]
15614 "!TARGET_64BIT && TARGET_GNU2_TLS"
15617 [(set (match_dup 0) (match_dup 5))]
15619 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15620 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15623 (define_expand "tls_dynamic_gnu2_64"
15624 [(set (match_dup 2)
15625 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15628 [(set (match_operand:DI 0 "register_operand" "")
15629 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15631 (clobber (reg:CC FLAGS_REG))])]
15632 "TARGET_64BIT && TARGET_GNU2_TLS"
15634 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15635 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15638 (define_insn "*tls_dynamic_lea_64"
15639 [(set (match_operand:DI 0 "register_operand" "=r")
15640 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15642 "TARGET_64BIT && TARGET_GNU2_TLS"
15643 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
15644 [(set_attr "type" "lea")
15645 (set_attr "mode" "DI")
15646 (set_attr "length" "7")
15647 (set_attr "length_address" "4")])
15649 (define_insn "*tls_dynamic_call_64"
15650 [(set (match_operand:DI 0 "register_operand" "=a")
15651 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15652 (match_operand:DI 2 "register_operand" "0")
15655 (clobber (reg:CC FLAGS_REG))]
15656 "TARGET_64BIT && TARGET_GNU2_TLS"
15657 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15658 [(set_attr "type" "call")
15659 (set_attr "length" "2")
15660 (set_attr "length_address" "0")])
15662 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15663 [(set (match_operand:DI 0 "register_operand" "=&a")
15665 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15666 (match_operand:DI 3 "" "")
15669 (const:DI (unspec:DI
15670 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15672 (clobber (reg:CC FLAGS_REG))]
15673 "TARGET_64BIT && TARGET_GNU2_TLS"
15676 [(set (match_dup 0) (match_dup 4))]
15678 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15679 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15684 ;; These patterns match the binary 387 instructions for addM3, subM3,
15685 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15686 ;; SFmode. The first is the normal insn, the second the same insn but
15687 ;; with one operand a conversion, and the third the same insn but with
15688 ;; the other operand a conversion. The conversion may be SFmode or
15689 ;; SImode if the target mode DFmode, but only SImode if the target mode
15692 ;; Gcc is slightly more smart about handling normal two address instructions
15693 ;; so use special patterns for add and mull.
15695 (define_insn "*fop_sf_comm_mixed"
15696 [(set (match_operand:SF 0 "register_operand" "=f,x")
15697 (match_operator:SF 3 "binary_fp_operator"
15698 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15699 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15700 "TARGET_MIX_SSE_I387
15701 && COMMUTATIVE_ARITH_P (operands[3])
15702 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15703 "* return output_387_binary_op (insn, operands);"
15704 [(set (attr "type")
15705 (if_then_else (eq_attr "alternative" "1")
15706 (if_then_else (match_operand:SF 3 "mult_operator" "")
15707 (const_string "ssemul")
15708 (const_string "sseadd"))
15709 (if_then_else (match_operand:SF 3 "mult_operator" "")
15710 (const_string "fmul")
15711 (const_string "fop"))))
15712 (set_attr "mode" "SF")])
15714 (define_insn "*fop_sf_comm_sse"
15715 [(set (match_operand:SF 0 "register_operand" "=x")
15716 (match_operator:SF 3 "binary_fp_operator"
15717 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15718 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15720 && COMMUTATIVE_ARITH_P (operands[3])
15721 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15722 "* return output_387_binary_op (insn, operands);"
15723 [(set (attr "type")
15724 (if_then_else (match_operand:SF 3 "mult_operator" "")
15725 (const_string "ssemul")
15726 (const_string "sseadd")))
15727 (set_attr "mode" "SF")])
15729 (define_insn "*fop_sf_comm_i387"
15730 [(set (match_operand:SF 0 "register_operand" "=f")
15731 (match_operator:SF 3 "binary_fp_operator"
15732 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15733 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15735 && COMMUTATIVE_ARITH_P (operands[3])
15736 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15737 "* return output_387_binary_op (insn, operands);"
15738 [(set (attr "type")
15739 (if_then_else (match_operand:SF 3 "mult_operator" "")
15740 (const_string "fmul")
15741 (const_string "fop")))
15742 (set_attr "mode" "SF")])
15744 (define_insn "*fop_sf_1_mixed"
15745 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15746 (match_operator:SF 3 "binary_fp_operator"
15747 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15748 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15749 "TARGET_MIX_SSE_I387
15750 && !COMMUTATIVE_ARITH_P (operands[3])
15751 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15752 "* return output_387_binary_op (insn, operands);"
15753 [(set (attr "type")
15754 (cond [(and (eq_attr "alternative" "2")
15755 (match_operand:SF 3 "mult_operator" ""))
15756 (const_string "ssemul")
15757 (and (eq_attr "alternative" "2")
15758 (match_operand:SF 3 "div_operator" ""))
15759 (const_string "ssediv")
15760 (eq_attr "alternative" "2")
15761 (const_string "sseadd")
15762 (match_operand:SF 3 "mult_operator" "")
15763 (const_string "fmul")
15764 (match_operand:SF 3 "div_operator" "")
15765 (const_string "fdiv")
15767 (const_string "fop")))
15768 (set_attr "mode" "SF")])
15770 (define_insn "*fop_sf_1_sse"
15771 [(set (match_operand:SF 0 "register_operand" "=x")
15772 (match_operator:SF 3 "binary_fp_operator"
15773 [(match_operand:SF 1 "register_operand" "0")
15774 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15776 && !COMMUTATIVE_ARITH_P (operands[3])"
15777 "* return output_387_binary_op (insn, operands);"
15778 [(set (attr "type")
15779 (cond [(match_operand:SF 3 "mult_operator" "")
15780 (const_string "ssemul")
15781 (match_operand:SF 3 "div_operator" "")
15782 (const_string "ssediv")
15784 (const_string "sseadd")))
15785 (set_attr "mode" "SF")])
15787 ;; This pattern is not fully shadowed by the pattern above.
15788 (define_insn "*fop_sf_1_i387"
15789 [(set (match_operand:SF 0 "register_operand" "=f,f")
15790 (match_operator:SF 3 "binary_fp_operator"
15791 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15792 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15793 "TARGET_80387 && !TARGET_SSE_MATH
15794 && !COMMUTATIVE_ARITH_P (operands[3])
15795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15796 "* return output_387_binary_op (insn, operands);"
15797 [(set (attr "type")
15798 (cond [(match_operand:SF 3 "mult_operator" "")
15799 (const_string "fmul")
15800 (match_operand:SF 3 "div_operator" "")
15801 (const_string "fdiv")
15803 (const_string "fop")))
15804 (set_attr "mode" "SF")])
15806 ;; ??? Add SSE splitters for these!
15807 (define_insn "*fop_sf_2<mode>_i387"
15808 [(set (match_operand:SF 0 "register_operand" "=f,f")
15809 (match_operator:SF 3 "binary_fp_operator"
15810 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15811 (match_operand:SF 2 "register_operand" "0,0")]))]
15812 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15813 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15814 [(set (attr "type")
15815 (cond [(match_operand:SF 3 "mult_operator" "")
15816 (const_string "fmul")
15817 (match_operand:SF 3 "div_operator" "")
15818 (const_string "fdiv")
15820 (const_string "fop")))
15821 (set_attr "fp_int_src" "true")
15822 (set_attr "mode" "<MODE>")])
15824 (define_insn "*fop_sf_3<mode>_i387"
15825 [(set (match_operand:SF 0 "register_operand" "=f,f")
15826 (match_operator:SF 3 "binary_fp_operator"
15827 [(match_operand:SF 1 "register_operand" "0,0")
15828 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15829 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15830 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15831 [(set (attr "type")
15832 (cond [(match_operand:SF 3 "mult_operator" "")
15833 (const_string "fmul")
15834 (match_operand:SF 3 "div_operator" "")
15835 (const_string "fdiv")
15837 (const_string "fop")))
15838 (set_attr "fp_int_src" "true")
15839 (set_attr "mode" "<MODE>")])
15841 (define_insn "*fop_df_comm_mixed"
15842 [(set (match_operand:DF 0 "register_operand" "=f,x")
15843 (match_operator:DF 3 "binary_fp_operator"
15844 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15845 (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15846 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15847 && COMMUTATIVE_ARITH_P (operands[3])
15848 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15849 "* return output_387_binary_op (insn, operands);"
15850 [(set (attr "type")
15851 (if_then_else (eq_attr "alternative" "1")
15852 (if_then_else (match_operand:DF 3 "mult_operator" "")
15853 (const_string "ssemul")
15854 (const_string "sseadd"))
15855 (if_then_else (match_operand:DF 3 "mult_operator" "")
15856 (const_string "fmul")
15857 (const_string "fop"))))
15858 (set_attr "mode" "DF")])
15860 (define_insn "*fop_df_comm_sse"
15861 [(set (match_operand:DF 0 "register_operand" "=x")
15862 (match_operator:DF 3 "binary_fp_operator"
15863 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15864 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15865 "TARGET_SSE2 && TARGET_SSE_MATH
15866 && COMMUTATIVE_ARITH_P (operands[3])
15867 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15868 "* return output_387_binary_op (insn, operands);"
15869 [(set (attr "type")
15870 (if_then_else (match_operand:DF 3 "mult_operator" "")
15871 (const_string "ssemul")
15872 (const_string "sseadd")))
15873 (set_attr "mode" "DF")])
15875 (define_insn "*fop_df_comm_i387"
15876 [(set (match_operand:DF 0 "register_operand" "=f")
15877 (match_operator:DF 3 "binary_fp_operator"
15878 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15879 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15881 && COMMUTATIVE_ARITH_P (operands[3])
15882 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15883 "* return output_387_binary_op (insn, operands);"
15884 [(set (attr "type")
15885 (if_then_else (match_operand:DF 3 "mult_operator" "")
15886 (const_string "fmul")
15887 (const_string "fop")))
15888 (set_attr "mode" "DF")])
15890 (define_insn "*fop_df_1_mixed"
15891 [(set (match_operand:DF 0 "register_operand" "=f,f,x")
15892 (match_operator:DF 3 "binary_fp_operator"
15893 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15894 (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
15895 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15896 && !COMMUTATIVE_ARITH_P (operands[3])
15897 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15898 "* return output_387_binary_op (insn, operands);"
15899 [(set (attr "type")
15900 (cond [(and (eq_attr "alternative" "2")
15901 (match_operand:DF 3 "mult_operator" ""))
15902 (const_string "ssemul")
15903 (and (eq_attr "alternative" "2")
15904 (match_operand:DF 3 "div_operator" ""))
15905 (const_string "ssediv")
15906 (eq_attr "alternative" "2")
15907 (const_string "sseadd")
15908 (match_operand:DF 3 "mult_operator" "")
15909 (const_string "fmul")
15910 (match_operand:DF 3 "div_operator" "")
15911 (const_string "fdiv")
15913 (const_string "fop")))
15914 (set_attr "mode" "DF")])
15916 (define_insn "*fop_df_1_sse"
15917 [(set (match_operand:DF 0 "register_operand" "=x")
15918 (match_operator:DF 3 "binary_fp_operator"
15919 [(match_operand:DF 1 "register_operand" "0")
15920 (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15921 "TARGET_SSE2 && TARGET_SSE_MATH
15922 && !COMMUTATIVE_ARITH_P (operands[3])"
15923 "* return output_387_binary_op (insn, operands);"
15924 [(set_attr "mode" "DF")
15926 (cond [(match_operand:DF 3 "mult_operator" "")
15927 (const_string "ssemul")
15928 (match_operand:DF 3 "div_operator" "")
15929 (const_string "ssediv")
15931 (const_string "sseadd")))])
15933 ;; This pattern is not fully shadowed by the pattern above.
15934 (define_insn "*fop_df_1_i387"
15935 [(set (match_operand:DF 0 "register_operand" "=f,f")
15936 (match_operator:DF 3 "binary_fp_operator"
15937 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15938 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15939 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15940 && !COMMUTATIVE_ARITH_P (operands[3])
15941 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15942 "* return output_387_binary_op (insn, operands);"
15943 [(set (attr "type")
15944 (cond [(match_operand:DF 3 "mult_operator" "")
15945 (const_string "fmul")
15946 (match_operand:DF 3 "div_operator" "")
15947 (const_string "fdiv")
15949 (const_string "fop")))
15950 (set_attr "mode" "DF")])
15952 ;; ??? Add SSE splitters for these!
15953 (define_insn "*fop_df_2<mode>_i387"
15954 [(set (match_operand:DF 0 "register_operand" "=f,f")
15955 (match_operator:DF 3 "binary_fp_operator"
15956 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15957 (match_operand:DF 2 "register_operand" "0,0")]))]
15958 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15959 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15960 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15961 [(set (attr "type")
15962 (cond [(match_operand:DF 3 "mult_operator" "")
15963 (const_string "fmul")
15964 (match_operand:DF 3 "div_operator" "")
15965 (const_string "fdiv")
15967 (const_string "fop")))
15968 (set_attr "fp_int_src" "true")
15969 (set_attr "mode" "<MODE>")])
15971 (define_insn "*fop_df_3<mode>_i387"
15972 [(set (match_operand:DF 0 "register_operand" "=f,f")
15973 (match_operator:DF 3 "binary_fp_operator"
15974 [(match_operand:DF 1 "register_operand" "0,0")
15975 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15976 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15977 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15978 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15979 [(set (attr "type")
15980 (cond [(match_operand:DF 3 "mult_operator" "")
15981 (const_string "fmul")
15982 (match_operand:DF 3 "div_operator" "")
15983 (const_string "fdiv")
15985 (const_string "fop")))
15986 (set_attr "fp_int_src" "true")
15987 (set_attr "mode" "<MODE>")])
15989 (define_insn "*fop_df_4_i387"
15990 [(set (match_operand:DF 0 "register_operand" "=f,f")
15991 (match_operator:DF 3 "binary_fp_operator"
15992 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15993 (match_operand:DF 2 "register_operand" "0,f")]))]
15994 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15995 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15996 "* return output_387_binary_op (insn, operands);"
15997 [(set (attr "type")
15998 (cond [(match_operand:DF 3 "mult_operator" "")
15999 (const_string "fmul")
16000 (match_operand:DF 3 "div_operator" "")
16001 (const_string "fdiv")
16003 (const_string "fop")))
16004 (set_attr "mode" "SF")])
16006 (define_insn "*fop_df_5_i387"
16007 [(set (match_operand:DF 0 "register_operand" "=f,f")
16008 (match_operator:DF 3 "binary_fp_operator"
16009 [(match_operand:DF 1 "register_operand" "0,f")
16011 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16012 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16013 "* return output_387_binary_op (insn, operands);"
16014 [(set (attr "type")
16015 (cond [(match_operand:DF 3 "mult_operator" "")
16016 (const_string "fmul")
16017 (match_operand:DF 3 "div_operator" "")
16018 (const_string "fdiv")
16020 (const_string "fop")))
16021 (set_attr "mode" "SF")])
16023 (define_insn "*fop_df_6_i387"
16024 [(set (match_operand:DF 0 "register_operand" "=f,f")
16025 (match_operator:DF 3 "binary_fp_operator"
16027 (match_operand:SF 1 "register_operand" "0,f"))
16029 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16030 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16031 "* return output_387_binary_op (insn, operands);"
16032 [(set (attr "type")
16033 (cond [(match_operand:DF 3 "mult_operator" "")
16034 (const_string "fmul")
16035 (match_operand:DF 3 "div_operator" "")
16036 (const_string "fdiv")
16038 (const_string "fop")))
16039 (set_attr "mode" "SF")])
16041 (define_insn "*fop_xf_comm_i387"
16042 [(set (match_operand:XF 0 "register_operand" "=f")
16043 (match_operator:XF 3 "binary_fp_operator"
16044 [(match_operand:XF 1 "register_operand" "%0")
16045 (match_operand:XF 2 "register_operand" "f")]))]
16047 && COMMUTATIVE_ARITH_P (operands[3])"
16048 "* return output_387_binary_op (insn, operands);"
16049 [(set (attr "type")
16050 (if_then_else (match_operand:XF 3 "mult_operator" "")
16051 (const_string "fmul")
16052 (const_string "fop")))
16053 (set_attr "mode" "XF")])
16055 (define_insn "*fop_xf_1_i387"
16056 [(set (match_operand:XF 0 "register_operand" "=f,f")
16057 (match_operator:XF 3 "binary_fp_operator"
16058 [(match_operand:XF 1 "register_operand" "0,f")
16059 (match_operand:XF 2 "register_operand" "f,0")]))]
16061 && !COMMUTATIVE_ARITH_P (operands[3])"
16062 "* return output_387_binary_op (insn, operands);"
16063 [(set (attr "type")
16064 (cond [(match_operand:XF 3 "mult_operator" "")
16065 (const_string "fmul")
16066 (match_operand:XF 3 "div_operator" "")
16067 (const_string "fdiv")
16069 (const_string "fop")))
16070 (set_attr "mode" "XF")])
16072 (define_insn "*fop_xf_2<mode>_i387"
16073 [(set (match_operand:XF 0 "register_operand" "=f,f")
16074 (match_operator:XF 3 "binary_fp_operator"
16075 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16076 (match_operand:XF 2 "register_operand" "0,0")]))]
16077 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16078 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16079 [(set (attr "type")
16080 (cond [(match_operand:XF 3 "mult_operator" "")
16081 (const_string "fmul")
16082 (match_operand:XF 3 "div_operator" "")
16083 (const_string "fdiv")
16085 (const_string "fop")))
16086 (set_attr "fp_int_src" "true")
16087 (set_attr "mode" "<MODE>")])
16089 (define_insn "*fop_xf_3<mode>_i387"
16090 [(set (match_operand:XF 0 "register_operand" "=f,f")
16091 (match_operator:XF 3 "binary_fp_operator"
16092 [(match_operand:XF 1 "register_operand" "0,0")
16093 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16094 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16095 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16096 [(set (attr "type")
16097 (cond [(match_operand:XF 3 "mult_operator" "")
16098 (const_string "fmul")
16099 (match_operand:XF 3 "div_operator" "")
16100 (const_string "fdiv")
16102 (const_string "fop")))
16103 (set_attr "fp_int_src" "true")
16104 (set_attr "mode" "<MODE>")])
16106 (define_insn "*fop_xf_4_i387"
16107 [(set (match_operand:XF 0 "register_operand" "=f,f")
16108 (match_operator:XF 3 "binary_fp_operator"
16110 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
16111 (match_operand:XF 2 "register_operand" "0,f")]))]
16113 "* return output_387_binary_op (insn, operands);"
16114 [(set (attr "type")
16115 (cond [(match_operand:XF 3 "mult_operator" "")
16116 (const_string "fmul")
16117 (match_operand:XF 3 "div_operator" "")
16118 (const_string "fdiv")
16120 (const_string "fop")))
16121 (set_attr "mode" "SF")])
16123 (define_insn "*fop_xf_5_i387"
16124 [(set (match_operand:XF 0 "register_operand" "=f,f")
16125 (match_operator:XF 3 "binary_fp_operator"
16126 [(match_operand:XF 1 "register_operand" "0,f")
16128 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16130 "* return output_387_binary_op (insn, operands);"
16131 [(set (attr "type")
16132 (cond [(match_operand:XF 3 "mult_operator" "")
16133 (const_string "fmul")
16134 (match_operand:XF 3 "div_operator" "")
16135 (const_string "fdiv")
16137 (const_string "fop")))
16138 (set_attr "mode" "SF")])
16140 (define_insn "*fop_xf_6_i387"
16141 [(set (match_operand:XF 0 "register_operand" "=f,f")
16142 (match_operator:XF 3 "binary_fp_operator"
16144 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
16146 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
16148 "* return output_387_binary_op (insn, operands);"
16149 [(set (attr "type")
16150 (cond [(match_operand:XF 3 "mult_operator" "")
16151 (const_string "fmul")
16152 (match_operand:XF 3 "div_operator" "")
16153 (const_string "fdiv")
16155 (const_string "fop")))
16156 (set_attr "mode" "SF")])
16159 [(set (match_operand 0 "register_operand" "")
16160 (match_operator 3 "binary_fp_operator"
16161 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16162 (match_operand 2 "register_operand" "")]))]
16163 "TARGET_80387 && reload_completed
16164 && FLOAT_MODE_P (GET_MODE (operands[0]))"
16167 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16168 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16169 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16170 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16171 GET_MODE (operands[3]),
16174 ix86_free_from_memory (GET_MODE (operands[1]));
16179 [(set (match_operand 0 "register_operand" "")
16180 (match_operator 3 "binary_fp_operator"
16181 [(match_operand 1 "register_operand" "")
16182 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16183 "TARGET_80387 && reload_completed
16184 && FLOAT_MODE_P (GET_MODE (operands[0]))"
16187 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16188 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16189 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16190 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16191 GET_MODE (operands[3]),
16194 ix86_free_from_memory (GET_MODE (operands[2]));
16198 ;; FPU special functions.
16200 ;; This pattern implements a no-op XFmode truncation for
16201 ;; all fancy i386 XFmode math functions.
16203 (define_insn "truncxf<mode>2_i387_noop_unspec"
16204 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16205 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
16206 UNSPEC_TRUNC_NOOP))]
16207 "TARGET_USE_FANCY_MATH_387"
16208 "* return output_387_reg_move (insn, operands);"
16209 [(set_attr "type" "fmov")
16210 (set_attr "mode" "<MODE>")])
16212 (define_insn "sqrtxf2"
16213 [(set (match_operand:XF 0 "register_operand" "=f")
16214 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16215 "TARGET_USE_FANCY_MATH_387"
16217 [(set_attr "type" "fpspc")
16218 (set_attr "mode" "XF")
16219 (set_attr "athlon_decode" "direct")
16220 (set_attr "amdfam10_decode" "direct")])
16222 (define_insn "sqrt_extend<mode>xf2_i387"
16223 [(set (match_operand:XF 0 "register_operand" "=f")
16226 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
16227 "TARGET_USE_FANCY_MATH_387"
16229 [(set_attr "type" "fpspc")
16230 (set_attr "mode" "XF")
16231 (set_attr "athlon_decode" "direct")
16232 (set_attr "amdfam10_decode" "direct")])
16234 (define_insn "*sqrt<mode>2_sse"
16235 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
16237 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
16238 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16239 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16240 [(set_attr "type" "sse")
16241 (set_attr "mode" "<MODE>")
16242 (set_attr "athlon_decode" "*")
16243 (set_attr "amdfam10_decode" "*")])
16245 (define_expand "sqrt<mode>2"
16246 [(set (match_operand:X87MODEF12 0 "register_operand" "")
16248 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
16249 "TARGET_USE_FANCY_MATH_387
16250 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16252 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16254 rtx op0 = gen_reg_rtx (XFmode);
16255 rtx op1 = force_reg (<MODE>mode, operands[1]);
16257 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16258 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16263 (define_insn "fpremxf4_i387"
16264 [(set (match_operand:XF 0 "register_operand" "=f")
16265 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16266 (match_operand:XF 3 "register_operand" "1")]
16268 (set (match_operand:XF 1 "register_operand" "=u")
16269 (unspec:XF [(match_dup 2) (match_dup 3)]
16271 (set (reg:CCFP FPSR_REG)
16272 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16273 "TARGET_USE_FANCY_MATH_387"
16275 [(set_attr "type" "fpspc")
16276 (set_attr "mode" "XF")])
16278 (define_expand "fmodxf3"
16279 [(use (match_operand:XF 0 "register_operand" ""))
16280 (use (match_operand:XF 1 "register_operand" ""))
16281 (use (match_operand:XF 2 "register_operand" ""))]
16282 "TARGET_USE_FANCY_MATH_387"
16284 rtx label = gen_label_rtx ();
16286 emit_label (label);
16288 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
16289 operands[1], operands[2]));
16290 ix86_emit_fp_unordered_jump (label);
16292 emit_move_insn (operands[0], operands[1]);
16296 (define_expand "fmod<mode>3"
16297 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16298 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16299 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16300 "TARGET_USE_FANCY_MATH_387"
16302 rtx label = gen_label_rtx ();
16304 rtx op1 = gen_reg_rtx (XFmode);
16305 rtx op2 = gen_reg_rtx (XFmode);
16307 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16308 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16310 emit_label (label);
16311 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16312 ix86_emit_fp_unordered_jump (label);
16314 /* Truncate the result properly for strict SSE math. */
16315 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16316 && !TARGET_MIX_SSE_I387)
16317 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16319 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16324 (define_insn "fprem1xf4_i387"
16325 [(set (match_operand:XF 0 "register_operand" "=f")
16326 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16327 (match_operand:XF 3 "register_operand" "1")]
16329 (set (match_operand:XF 1 "register_operand" "=u")
16330 (unspec:XF [(match_dup 2) (match_dup 3)]
16332 (set (reg:CCFP FPSR_REG)
16333 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
16334 "TARGET_USE_FANCY_MATH_387"
16336 [(set_attr "type" "fpspc")
16337 (set_attr "mode" "XF")])
16339 (define_expand "remainderxf3"
16340 [(use (match_operand:XF 0 "register_operand" ""))
16341 (use (match_operand:XF 1 "register_operand" ""))
16342 (use (match_operand:XF 2 "register_operand" ""))]
16343 "TARGET_USE_FANCY_MATH_387"
16345 rtx label = gen_label_rtx ();
16347 emit_label (label);
16349 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
16350 operands[1], operands[2]));
16351 ix86_emit_fp_unordered_jump (label);
16353 emit_move_insn (operands[0], operands[1]);
16357 (define_expand "remainder<mode>3"
16358 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16359 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16360 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
16361 "TARGET_USE_FANCY_MATH_387"
16363 rtx label = gen_label_rtx ();
16365 rtx op1 = gen_reg_rtx (XFmode);
16366 rtx op2 = gen_reg_rtx (XFmode);
16368 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16369 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16371 emit_label (label);
16373 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16374 ix86_emit_fp_unordered_jump (label);
16376 /* Truncate the result properly for strict SSE math. */
16377 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16378 && !TARGET_MIX_SSE_I387)
16379 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16381 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16386 (define_insn "*sinxf2_i387"
16387 [(set (match_operand:XF 0 "register_operand" "=f")
16388 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16389 "TARGET_USE_FANCY_MATH_387
16390 && flag_unsafe_math_optimizations"
16392 [(set_attr "type" "fpspc")
16393 (set_attr "mode" "XF")])
16395 (define_insn "*sin_extend<mode>xf2_i387"
16396 [(set (match_operand:XF 0 "register_operand" "=f")
16397 (unspec:XF [(float_extend:XF
16398 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16400 "TARGET_USE_FANCY_MATH_387
16401 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16402 || TARGET_MIX_SSE_I387)
16403 && flag_unsafe_math_optimizations"
16405 [(set_attr "type" "fpspc")
16406 (set_attr "mode" "XF")])
16408 (define_insn "*cosxf2_i387"
16409 [(set (match_operand:XF 0 "register_operand" "=f")
16410 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16411 "TARGET_USE_FANCY_MATH_387
16412 && flag_unsafe_math_optimizations"
16414 [(set_attr "type" "fpspc")
16415 (set_attr "mode" "XF")])
16417 (define_insn "*cos_extend<mode>xf2_i387"
16418 [(set (match_operand:XF 0 "register_operand" "=f")
16419 (unspec:XF [(float_extend:XF
16420 (match_operand:X87MODEF12 1 "register_operand" "0"))]
16422 "TARGET_USE_FANCY_MATH_387
16423 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16424 || TARGET_MIX_SSE_I387)
16425 && flag_unsafe_math_optimizations"
16427 [(set_attr "type" "fpspc")
16428 (set_attr "mode" "XF")])
16430 ;; When sincos pattern is defined, sin and cos builtin functions will be
16431 ;; expanded to sincos pattern with one of its outputs left unused.
16432 ;; CSE pass will figure out if two sincos patterns can be combined,
16433 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16434 ;; depending on the unused output.
16436 (define_insn "sincosxf3"
16437 [(set (match_operand:XF 0 "register_operand" "=f")
16438 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16439 UNSPEC_SINCOS_COS))
16440 (set (match_operand:XF 1 "register_operand" "=u")
16441 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16442 "TARGET_USE_FANCY_MATH_387
16443 && flag_unsafe_math_optimizations"
16445 [(set_attr "type" "fpspc")
16446 (set_attr "mode" "XF")])
16449 [(set (match_operand:XF 0 "register_operand" "")
16450 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16451 UNSPEC_SINCOS_COS))
16452 (set (match_operand:XF 1 "register_operand" "")
16453 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16454 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16455 && !reload_completed && !reload_in_progress"
16456 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16460 [(set (match_operand:XF 0 "register_operand" "")
16461 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16462 UNSPEC_SINCOS_COS))
16463 (set (match_operand:XF 1 "register_operand" "")
16464 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16465 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16466 && !reload_completed && !reload_in_progress"
16467 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16470 (define_insn "sincos_extend<mode>xf3_i387"
16471 [(set (match_operand:XF 0 "register_operand" "=f")
16472 (unspec:XF [(float_extend:XF
16473 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16474 UNSPEC_SINCOS_COS))
16475 (set (match_operand:XF 1 "register_operand" "=u")
16476 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16477 "TARGET_USE_FANCY_MATH_387
16478 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16479 || TARGET_MIX_SSE_I387)
16480 && flag_unsafe_math_optimizations"
16482 [(set_attr "type" "fpspc")
16483 (set_attr "mode" "XF")])
16486 [(set (match_operand:XF 0 "register_operand" "")
16487 (unspec:XF [(float_extend:XF
16488 (match_operand:X87MODEF12 2 "register_operand" ""))]
16489 UNSPEC_SINCOS_COS))
16490 (set (match_operand:XF 1 "register_operand" "")
16491 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16492 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16493 && !reload_completed && !reload_in_progress"
16494 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16498 [(set (match_operand:XF 0 "register_operand" "")
16499 (unspec:XF [(float_extend:XF
16500 (match_operand:X87MODEF12 2 "register_operand" ""))]
16501 UNSPEC_SINCOS_COS))
16502 (set (match_operand:XF 1 "register_operand" "")
16503 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16504 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16505 && !reload_completed && !reload_in_progress"
16506 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16509 (define_expand "sincos<mode>3"
16510 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16511 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16512 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16513 "TARGET_USE_FANCY_MATH_387
16514 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16515 || TARGET_MIX_SSE_I387)
16516 && flag_unsafe_math_optimizations"
16518 rtx op0 = gen_reg_rtx (XFmode);
16519 rtx op1 = gen_reg_rtx (XFmode);
16521 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16522 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16527 (define_insn "fptanxf4_i387"
16528 [(set (match_operand:XF 0 "register_operand" "=f")
16529 (match_operand:XF 3 "const_double_operand" "F"))
16530 (set (match_operand:XF 1 "register_operand" "=u")
16531 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16533 "TARGET_USE_FANCY_MATH_387
16534 && flag_unsafe_math_optimizations
16535 && standard_80387_constant_p (operands[3]) == 2"
16537 [(set_attr "type" "fpspc")
16538 (set_attr "mode" "XF")])
16540 (define_insn "fptan_extend<mode>xf4_i387"
16541 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
16542 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
16543 (set (match_operand:XF 1 "register_operand" "=u")
16544 (unspec:XF [(float_extend:XF
16545 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16547 "TARGET_USE_FANCY_MATH_387
16548 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16549 || TARGET_MIX_SSE_I387)
16550 && flag_unsafe_math_optimizations
16551 && standard_80387_constant_p (operands[3]) == 2"
16553 [(set_attr "type" "fpspc")
16554 (set_attr "mode" "XF")])
16556 (define_expand "tanxf2"
16557 [(use (match_operand:XF 0 "register_operand" ""))
16558 (use (match_operand:XF 1 "register_operand" ""))]
16559 "TARGET_USE_FANCY_MATH_387
16560 && flag_unsafe_math_optimizations"
16562 rtx one = gen_reg_rtx (XFmode);
16563 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16565 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16569 (define_expand "tan<mode>2"
16570 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16571 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16572 "TARGET_USE_FANCY_MATH_387
16573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16574 || TARGET_MIX_SSE_I387)
16575 && flag_unsafe_math_optimizations"
16577 rtx op0 = gen_reg_rtx (XFmode);
16579 rtx one = gen_reg_rtx (<MODE>mode);
16580 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16582 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16583 operands[1], op2));
16584 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16588 (define_insn "*fpatanxf3_i387"
16589 [(set (match_operand:XF 0 "register_operand" "=f")
16590 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16591 (match_operand:XF 2 "register_operand" "u")]
16593 (clobber (match_scratch:XF 3 "=2"))]
16594 "TARGET_USE_FANCY_MATH_387
16595 && flag_unsafe_math_optimizations"
16597 [(set_attr "type" "fpspc")
16598 (set_attr "mode" "XF")])
16600 (define_insn "fpatan_extend<mode>xf3_i387"
16601 [(set (match_operand:XF 0 "register_operand" "=f")
16602 (unspec:XF [(float_extend:XF
16603 (match_operand:X87MODEF12 1 "register_operand" "0"))
16605 (match_operand:X87MODEF12 2 "register_operand" "u"))]
16607 (clobber (match_scratch:XF 3 "=2"))]
16608 "TARGET_USE_FANCY_MATH_387
16609 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16610 || TARGET_MIX_SSE_I387)
16611 && flag_unsafe_math_optimizations"
16613 [(set_attr "type" "fpspc")
16614 (set_attr "mode" "XF")])
16616 (define_expand "atan2xf3"
16617 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16618 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16619 (match_operand:XF 1 "register_operand" "")]
16621 (clobber (match_scratch:XF 3 ""))])]
16622 "TARGET_USE_FANCY_MATH_387
16623 && flag_unsafe_math_optimizations"
16626 (define_expand "atan2<mode>3"
16627 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16628 (use (match_operand:X87MODEF12 1 "register_operand" ""))
16629 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
16630 "TARGET_USE_FANCY_MATH_387
16631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16632 || TARGET_MIX_SSE_I387)
16633 && flag_unsafe_math_optimizations"
16635 rtx op0 = gen_reg_rtx (XFmode);
16637 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16638 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16642 (define_expand "atanxf2"
16643 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16644 (unspec:XF [(match_dup 2)
16645 (match_operand:XF 1 "register_operand" "")]
16647 (clobber (match_scratch:XF 3 ""))])]
16648 "TARGET_USE_FANCY_MATH_387
16649 && flag_unsafe_math_optimizations"
16651 operands[2] = gen_reg_rtx (XFmode);
16652 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16655 (define_expand "atan<mode>2"
16656 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16657 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16658 "TARGET_USE_FANCY_MATH_387
16659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16660 || TARGET_MIX_SSE_I387)
16661 && flag_unsafe_math_optimizations"
16663 rtx op0 = gen_reg_rtx (XFmode);
16665 rtx op2 = gen_reg_rtx (<MODE>mode);
16666 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16668 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16669 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16673 (define_expand "asinxf2"
16674 [(set (match_dup 2)
16675 (mult:XF (match_operand:XF 1 "register_operand" "")
16677 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16678 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16679 (parallel [(set (match_operand:XF 0 "register_operand" "")
16680 (unspec:XF [(match_dup 5) (match_dup 1)]
16682 (clobber (match_scratch:XF 6 ""))])]
16683 "TARGET_USE_FANCY_MATH_387
16684 && flag_unsafe_math_optimizations && !optimize_size"
16688 for (i = 2; i < 6; i++)
16689 operands[i] = gen_reg_rtx (XFmode);
16691 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16694 (define_expand "asin<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_asinxf2 (op0, op1));
16707 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16711 (define_expand "acosxf2"
16712 [(set (match_dup 2)
16713 (mult:XF (match_operand:XF 1 "register_operand" "")
16715 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16716 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16717 (parallel [(set (match_operand:XF 0 "register_operand" "")
16718 (unspec:XF [(match_dup 1) (match_dup 5)]
16720 (clobber (match_scratch:XF 6 ""))])]
16721 "TARGET_USE_FANCY_MATH_387
16722 && flag_unsafe_math_optimizations && !optimize_size"
16726 for (i = 2; i < 6; i++)
16727 operands[i] = gen_reg_rtx (XFmode);
16729 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16732 (define_expand "acos<mode>2"
16733 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16734 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16735 "TARGET_USE_FANCY_MATH_387
16736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16737 || TARGET_MIX_SSE_I387)
16738 && flag_unsafe_math_optimizations && !optimize_size"
16740 rtx op0 = gen_reg_rtx (XFmode);
16741 rtx op1 = gen_reg_rtx (XFmode);
16743 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16744 emit_insn (gen_acosxf2 (op0, op1));
16745 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16749 (define_insn "fyl2xxf3_i387"
16750 [(set (match_operand:XF 0 "register_operand" "=f")
16751 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16752 (match_operand:XF 2 "register_operand" "u")]
16754 (clobber (match_scratch:XF 3 "=2"))]
16755 "TARGET_USE_FANCY_MATH_387
16756 && flag_unsafe_math_optimizations"
16758 [(set_attr "type" "fpspc")
16759 (set_attr "mode" "XF")])
16761 (define_insn "fyl2x_extend<mode>xf3_i387"
16762 [(set (match_operand:XF 0 "register_operand" "=f")
16763 (unspec:XF [(float_extend:XF
16764 (match_operand:X87MODEF12 1 "register_operand" "0"))
16765 (match_operand:XF 2 "register_operand" "u")]
16767 (clobber (match_scratch:XF 3 "=2"))]
16768 "TARGET_USE_FANCY_MATH_387
16769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16770 || TARGET_MIX_SSE_I387)
16771 && flag_unsafe_math_optimizations"
16773 [(set_attr "type" "fpspc")
16774 (set_attr "mode" "XF")])
16776 (define_expand "logxf2"
16777 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16778 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16779 (match_dup 2)] UNSPEC_FYL2X))
16780 (clobber (match_scratch:XF 3 ""))])]
16781 "TARGET_USE_FANCY_MATH_387
16782 && flag_unsafe_math_optimizations"
16784 operands[2] = gen_reg_rtx (XFmode);
16785 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16788 (define_expand "log<mode>2"
16789 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16790 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16791 "TARGET_USE_FANCY_MATH_387
16792 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16793 || TARGET_MIX_SSE_I387)
16794 && flag_unsafe_math_optimizations"
16796 rtx op0 = gen_reg_rtx (XFmode);
16798 rtx op2 = gen_reg_rtx (XFmode);
16799 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16801 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16802 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16806 (define_expand "log10xf2"
16807 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16808 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16809 (match_dup 2)] UNSPEC_FYL2X))
16810 (clobber (match_scratch:XF 3 ""))])]
16811 "TARGET_USE_FANCY_MATH_387
16812 && flag_unsafe_math_optimizations"
16814 operands[2] = gen_reg_rtx (XFmode);
16815 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16818 (define_expand "log10<mode>2"
16819 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16820 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16821 "TARGET_USE_FANCY_MATH_387
16822 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16823 || TARGET_MIX_SSE_I387)
16824 && flag_unsafe_math_optimizations"
16826 rtx op0 = gen_reg_rtx (XFmode);
16828 rtx op2 = gen_reg_rtx (XFmode);
16829 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16831 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16832 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16836 (define_expand "log2xf2"
16837 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16838 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16839 (match_dup 2)] UNSPEC_FYL2X))
16840 (clobber (match_scratch:XF 3 ""))])]
16841 "TARGET_USE_FANCY_MATH_387
16842 && flag_unsafe_math_optimizations"
16844 operands[2] = gen_reg_rtx (XFmode);
16845 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16848 (define_expand "log2<mode>2"
16849 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16850 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16851 "TARGET_USE_FANCY_MATH_387
16852 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16853 || TARGET_MIX_SSE_I387)
16854 && flag_unsafe_math_optimizations"
16856 rtx op0 = gen_reg_rtx (XFmode);
16858 rtx op2 = gen_reg_rtx (XFmode);
16859 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16861 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16862 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16866 (define_insn "fyl2xp1xf3_i387"
16867 [(set (match_operand:XF 0 "register_operand" "=f")
16868 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16869 (match_operand:XF 2 "register_operand" "u")]
16871 (clobber (match_scratch:XF 3 "=2"))]
16872 "TARGET_USE_FANCY_MATH_387
16873 && flag_unsafe_math_optimizations"
16875 [(set_attr "type" "fpspc")
16876 (set_attr "mode" "XF")])
16878 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16879 [(set (match_operand:XF 0 "register_operand" "=f")
16880 (unspec:XF [(float_extend:XF
16881 (match_operand:X87MODEF12 1 "register_operand" "0"))
16882 (match_operand:XF 2 "register_operand" "u")]
16884 (clobber (match_scratch:XF 3 "=2"))]
16885 "TARGET_USE_FANCY_MATH_387
16886 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16887 || TARGET_MIX_SSE_I387)
16888 && flag_unsafe_math_optimizations"
16890 [(set_attr "type" "fpspc")
16891 (set_attr "mode" "XF")])
16893 (define_expand "log1pxf2"
16894 [(use (match_operand:XF 0 "register_operand" ""))
16895 (use (match_operand:XF 1 "register_operand" ""))]
16896 "TARGET_USE_FANCY_MATH_387
16897 && flag_unsafe_math_optimizations && !optimize_size"
16899 ix86_emit_i387_log1p (operands[0], operands[1]);
16903 (define_expand "log1p<mode>2"
16904 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16905 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16906 "TARGET_USE_FANCY_MATH_387
16907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16908 || TARGET_MIX_SSE_I387)
16909 && flag_unsafe_math_optimizations && !optimize_size"
16911 rtx op0 = gen_reg_rtx (XFmode);
16913 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16915 ix86_emit_i387_log1p (op0, operands[1]);
16916 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16920 (define_insn "fxtractxf3_i387"
16921 [(set (match_operand:XF 0 "register_operand" "=f")
16922 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16923 UNSPEC_XTRACT_FRACT))
16924 (set (match_operand:XF 1 "register_operand" "=u")
16925 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16926 "TARGET_USE_FANCY_MATH_387
16927 && flag_unsafe_math_optimizations"
16929 [(set_attr "type" "fpspc")
16930 (set_attr "mode" "XF")])
16932 (define_insn "fxtract_extend<mode>xf3_i387"
16933 [(set (match_operand:XF 0 "register_operand" "=f")
16934 (unspec:XF [(float_extend:XF
16935 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16936 UNSPEC_XTRACT_FRACT))
16937 (set (match_operand:XF 1 "register_operand" "=u")
16938 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16939 "TARGET_USE_FANCY_MATH_387
16940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16941 || TARGET_MIX_SSE_I387)
16942 && flag_unsafe_math_optimizations"
16944 [(set_attr "type" "fpspc")
16945 (set_attr "mode" "XF")])
16947 (define_expand "logbxf2"
16948 [(parallel [(set (match_dup 2)
16949 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16950 UNSPEC_XTRACT_FRACT))
16951 (set (match_operand:XF 0 "register_operand" "")
16952 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16953 "TARGET_USE_FANCY_MATH_387
16954 && flag_unsafe_math_optimizations"
16956 operands[2] = gen_reg_rtx (XFmode);
16959 (define_expand "logb<mode>2"
16960 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16961 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16962 "TARGET_USE_FANCY_MATH_387
16963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16964 || TARGET_MIX_SSE_I387)
16965 && flag_unsafe_math_optimizations"
16967 rtx op0 = gen_reg_rtx (XFmode);
16968 rtx op1 = gen_reg_rtx (XFmode);
16970 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16971 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16975 (define_expand "ilogbxf2"
16976 [(use (match_operand:SI 0 "register_operand" ""))
16977 (use (match_operand:XF 1 "register_operand" ""))]
16978 "TARGET_USE_FANCY_MATH_387
16979 && flag_unsafe_math_optimizations && !optimize_size"
16981 rtx op0 = gen_reg_rtx (XFmode);
16982 rtx op1 = gen_reg_rtx (XFmode);
16984 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16985 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16989 (define_expand "ilogb<mode>2"
16990 [(use (match_operand:SI 0 "register_operand" ""))
16991 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16992 "TARGET_USE_FANCY_MATH_387
16993 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16994 || TARGET_MIX_SSE_I387)
16995 && flag_unsafe_math_optimizations && !optimize_size"
16997 rtx op0 = gen_reg_rtx (XFmode);
16998 rtx op1 = gen_reg_rtx (XFmode);
17000 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17001 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17005 (define_insn "*f2xm1xf2_i387"
17006 [(set (match_operand:XF 0 "register_operand" "=f")
17007 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17009 "TARGET_USE_FANCY_MATH_387
17010 && flag_unsafe_math_optimizations"
17012 [(set_attr "type" "fpspc")
17013 (set_attr "mode" "XF")])
17015 (define_insn "*fscalexf4_i387"
17016 [(set (match_operand:XF 0 "register_operand" "=f")
17017 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17018 (match_operand:XF 3 "register_operand" "1")]
17019 UNSPEC_FSCALE_FRACT))
17020 (set (match_operand:XF 1 "register_operand" "=u")
17021 (unspec:XF [(match_dup 2) (match_dup 3)]
17022 UNSPEC_FSCALE_EXP))]
17023 "TARGET_USE_FANCY_MATH_387
17024 && flag_unsafe_math_optimizations"
17026 [(set_attr "type" "fpspc")
17027 (set_attr "mode" "XF")])
17029 (define_expand "expNcorexf3"
17030 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17031 (match_operand:XF 2 "register_operand" "")))
17032 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17033 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17034 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17035 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17036 (parallel [(set (match_operand:XF 0 "register_operand" "")
17037 (unspec:XF [(match_dup 8) (match_dup 4)]
17038 UNSPEC_FSCALE_FRACT))
17040 (unspec:XF [(match_dup 8) (match_dup 4)]
17041 UNSPEC_FSCALE_EXP))])]
17042 "TARGET_USE_FANCY_MATH_387
17043 && flag_unsafe_math_optimizations && !optimize_size"
17047 for (i = 3; i < 10; i++)
17048 operands[i] = gen_reg_rtx (XFmode);
17050 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17053 (define_expand "expxf2"
17054 [(use (match_operand:XF 0 "register_operand" ""))
17055 (use (match_operand:XF 1 "register_operand" ""))]
17056 "TARGET_USE_FANCY_MATH_387
17057 && flag_unsafe_math_optimizations && !optimize_size"
17059 rtx op2 = gen_reg_rtx (XFmode);
17060 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17062 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17066 (define_expand "exp<mode>2"
17067 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17068 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17069 "TARGET_USE_FANCY_MATH_387
17070 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17071 || TARGET_MIX_SSE_I387)
17072 && flag_unsafe_math_optimizations && !optimize_size"
17074 rtx op0 = gen_reg_rtx (XFmode);
17075 rtx op1 = gen_reg_rtx (XFmode);
17077 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17078 emit_insn (gen_expxf2 (op0, op1));
17079 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17083 (define_expand "exp10xf2"
17084 [(use (match_operand:XF 0 "register_operand" ""))
17085 (use (match_operand:XF 1 "register_operand" ""))]
17086 "TARGET_USE_FANCY_MATH_387
17087 && flag_unsafe_math_optimizations && !optimize_size"
17089 rtx op2 = gen_reg_rtx (XFmode);
17090 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17092 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17096 (define_expand "exp10<mode>2"
17097 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17098 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17099 "TARGET_USE_FANCY_MATH_387
17100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17101 || TARGET_MIX_SSE_I387)
17102 && flag_unsafe_math_optimizations && !optimize_size"
17104 rtx op0 = gen_reg_rtx (XFmode);
17105 rtx op1 = gen_reg_rtx (XFmode);
17107 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17108 emit_insn (gen_exp10xf2 (op0, op1));
17109 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17113 (define_expand "exp2xf2"
17114 [(use (match_operand:XF 0 "register_operand" ""))
17115 (use (match_operand:XF 1 "register_operand" ""))]
17116 "TARGET_USE_FANCY_MATH_387
17117 && flag_unsafe_math_optimizations && !optimize_size"
17119 rtx op2 = gen_reg_rtx (XFmode);
17120 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17122 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17126 (define_expand "exp2<mode>2"
17127 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17128 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17129 "TARGET_USE_FANCY_MATH_387
17130 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17131 || TARGET_MIX_SSE_I387)
17132 && flag_unsafe_math_optimizations && !optimize_size"
17134 rtx op0 = gen_reg_rtx (XFmode);
17135 rtx op1 = gen_reg_rtx (XFmode);
17137 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17138 emit_insn (gen_exp2xf2 (op0, op1));
17139 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17143 (define_expand "expm1xf2"
17144 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17146 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17147 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17148 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17149 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17150 (parallel [(set (match_dup 7)
17151 (unspec:XF [(match_dup 6) (match_dup 4)]
17152 UNSPEC_FSCALE_FRACT))
17154 (unspec:XF [(match_dup 6) (match_dup 4)]
17155 UNSPEC_FSCALE_EXP))])
17156 (parallel [(set (match_dup 10)
17157 (unspec:XF [(match_dup 9) (match_dup 8)]
17158 UNSPEC_FSCALE_FRACT))
17159 (set (match_dup 11)
17160 (unspec:XF [(match_dup 9) (match_dup 8)]
17161 UNSPEC_FSCALE_EXP))])
17162 (set (match_dup 12) (minus:XF (match_dup 10)
17163 (float_extend:XF (match_dup 13))))
17164 (set (match_operand:XF 0 "register_operand" "")
17165 (plus:XF (match_dup 12) (match_dup 7)))]
17166 "TARGET_USE_FANCY_MATH_387
17167 && flag_unsafe_math_optimizations && !optimize_size"
17171 for (i = 2; i < 13; i++)
17172 operands[i] = gen_reg_rtx (XFmode);
17175 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17177 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17180 (define_expand "expm1<mode>2"
17181 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17182 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
17183 "TARGET_USE_FANCY_MATH_387
17184 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17185 || TARGET_MIX_SSE_I387)
17186 && flag_unsafe_math_optimizations && !optimize_size"
17188 rtx op0 = gen_reg_rtx (XFmode);
17189 rtx op1 = gen_reg_rtx (XFmode);
17191 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17192 emit_insn (gen_expm1xf2 (op0, op1));
17193 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17197 (define_expand "ldexpxf3"
17198 [(set (match_dup 3)
17199 (float:XF (match_operand:SI 2 "register_operand" "")))
17200 (parallel [(set (match_operand:XF 0 " register_operand" "")
17201 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17203 UNSPEC_FSCALE_FRACT))
17205 (unspec:XF [(match_dup 1) (match_dup 3)]
17206 UNSPEC_FSCALE_EXP))])]
17207 "TARGET_USE_FANCY_MATH_387
17208 && flag_unsafe_math_optimizations && !optimize_size"
17210 operands[3] = gen_reg_rtx (XFmode);
17211 operands[4] = gen_reg_rtx (XFmode);
17214 (define_expand "ldexp<mode>3"
17215 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17216 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17217 (use (match_operand:SI 2 "register_operand" ""))]
17218 "TARGET_USE_FANCY_MATH_387
17219 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17220 || TARGET_MIX_SSE_I387)
17221 && flag_unsafe_math_optimizations && !optimize_size"
17223 rtx op0 = gen_reg_rtx (XFmode);
17224 rtx op1 = gen_reg_rtx (XFmode);
17226 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17227 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17228 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17232 (define_expand "scalbxf3"
17233 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17234 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17235 (match_operand:XF 2 "register_operand" "")]
17236 UNSPEC_FSCALE_FRACT))
17238 (unspec:XF [(match_dup 1) (match_dup 2)]
17239 UNSPEC_FSCALE_EXP))])]
17240 "TARGET_USE_FANCY_MATH_387
17241 && flag_unsafe_math_optimizations && !optimize_size"
17243 operands[3] = gen_reg_rtx (XFmode);
17246 (define_expand "scalb<mode>3"
17247 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
17248 (use (match_operand:X87MODEF12 1 "general_operand" ""))
17249 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
17250 "TARGET_USE_FANCY_MATH_387
17251 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17252 || TARGET_MIX_SSE_I387)
17253 && flag_unsafe_math_optimizations && !optimize_size"
17255 rtx op0 = gen_reg_rtx (XFmode);
17256 rtx op1 = gen_reg_rtx (XFmode);
17257 rtx op2 = gen_reg_rtx (XFmode);
17259 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17260 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17261 emit_insn (gen_scalbxf3 (op0, op1, op2));
17262 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17267 (define_insn "frndintxf2"
17268 [(set (match_operand:XF 0 "register_operand" "=f")
17269 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17271 "TARGET_USE_FANCY_MATH_387
17272 && flag_unsafe_math_optimizations"
17274 [(set_attr "type" "fpspc")
17275 (set_attr "mode" "XF")])
17277 (define_expand "rintdf2"
17278 [(use (match_operand:DF 0 "register_operand" ""))
17279 (use (match_operand:DF 1 "register_operand" ""))]
17280 "(TARGET_USE_FANCY_MATH_387
17281 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17282 && flag_unsafe_math_optimizations)
17283 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17284 && !flag_trapping_math
17285 && !optimize_size)"
17287 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17288 && !flag_trapping_math
17290 ix86_expand_rint (operand0, operand1);
17293 rtx op0 = gen_reg_rtx (XFmode);
17294 rtx op1 = gen_reg_rtx (XFmode);
17296 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17297 emit_insn (gen_frndintxf2 (op0, op1));
17299 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17304 (define_expand "rintsf2"
17305 [(use (match_operand:SF 0 "register_operand" ""))
17306 (use (match_operand:SF 1 "register_operand" ""))]
17307 "(TARGET_USE_FANCY_MATH_387
17308 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17309 && flag_unsafe_math_optimizations)
17310 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17311 && !flag_trapping_math
17312 && !optimize_size)"
17314 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17315 && !flag_trapping_math
17317 ix86_expand_rint (operand0, operand1);
17320 rtx op0 = gen_reg_rtx (XFmode);
17321 rtx op1 = gen_reg_rtx (XFmode);
17323 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17324 emit_insn (gen_frndintxf2 (op0, op1));
17326 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17331 (define_expand "rintxf2"
17332 [(use (match_operand:XF 0 "register_operand" ""))
17333 (use (match_operand:XF 1 "register_operand" ""))]
17334 "TARGET_USE_FANCY_MATH_387
17335 && flag_unsafe_math_optimizations && !optimize_size"
17337 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17341 (define_expand "roundsf2"
17342 [(match_operand:SF 0 "register_operand" "")
17343 (match_operand:SF 1 "nonimmediate_operand" "")]
17344 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17345 && !flag_trapping_math && !flag_rounding_math
17348 ix86_expand_round (operand0, operand1);
17352 (define_expand "rounddf2"
17353 [(match_operand:DF 0 "register_operand" "")
17354 (match_operand:DF 1 "nonimmediate_operand" "")]
17355 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17356 && !flag_trapping_math && !flag_rounding_math
17360 ix86_expand_round (operand0, operand1);
17362 ix86_expand_rounddf_32 (operand0, operand1);
17366 (define_insn_and_split "*fistdi2_1"
17367 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17368 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17370 "TARGET_USE_FANCY_MATH_387
17371 && !(reload_completed || reload_in_progress)"
17376 if (memory_operand (operands[0], VOIDmode))
17377 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17380 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17381 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17386 [(set_attr "type" "fpspc")
17387 (set_attr "mode" "DI")])
17389 (define_insn "fistdi2"
17390 [(set (match_operand:DI 0 "memory_operand" "=m")
17391 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17393 (clobber (match_scratch:XF 2 "=&1f"))]
17394 "TARGET_USE_FANCY_MATH_387"
17395 "* return output_fix_trunc (insn, operands, 0);"
17396 [(set_attr "type" "fpspc")
17397 (set_attr "mode" "DI")])
17399 (define_insn "fistdi2_with_temp"
17400 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17401 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17403 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17404 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17405 "TARGET_USE_FANCY_MATH_387"
17407 [(set_attr "type" "fpspc")
17408 (set_attr "mode" "DI")])
17411 [(set (match_operand:DI 0 "register_operand" "")
17412 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17414 (clobber (match_operand:DI 2 "memory_operand" ""))
17415 (clobber (match_scratch 3 ""))]
17417 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17418 (clobber (match_dup 3))])
17419 (set (match_dup 0) (match_dup 2))]
17423 [(set (match_operand:DI 0 "memory_operand" "")
17424 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17426 (clobber (match_operand:DI 2 "memory_operand" ""))
17427 (clobber (match_scratch 3 ""))]
17429 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17430 (clobber (match_dup 3))])]
17433 (define_insn_and_split "*fist<mode>2_1"
17434 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17435 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17437 "TARGET_USE_FANCY_MATH_387
17438 && !(reload_completed || reload_in_progress)"
17443 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17444 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17448 [(set_attr "type" "fpspc")
17449 (set_attr "mode" "<MODE>")])
17451 (define_insn "fist<mode>2"
17452 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17453 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17455 "TARGET_USE_FANCY_MATH_387"
17456 "* return output_fix_trunc (insn, operands, 0);"
17457 [(set_attr "type" "fpspc")
17458 (set_attr "mode" "<MODE>")])
17460 (define_insn "fist<mode>2_with_temp"
17461 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17462 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17464 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17465 "TARGET_USE_FANCY_MATH_387"
17467 [(set_attr "type" "fpspc")
17468 (set_attr "mode" "<MODE>")])
17471 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17472 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17474 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17476 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17478 (set (match_dup 0) (match_dup 2))]
17482 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17483 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17485 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17487 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17491 (define_expand "lrintxf<mode>2"
17492 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17493 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17495 "TARGET_USE_FANCY_MATH_387"
17498 (define_expand "lrint<mode>di2"
17499 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17500 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17501 UNSPEC_FIX_NOTRUNC))]
17502 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17505 (define_expand "lrint<mode>si2"
17506 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17507 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17508 UNSPEC_FIX_NOTRUNC))]
17509 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17512 (define_expand "lround<mode>di2"
17513 [(match_operand:DI 0 "nonimmediate_operand" "")
17514 (match_operand:SSEMODEF 1 "register_operand" "")]
17515 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17516 && !flag_trapping_math && !flag_rounding_math
17519 ix86_expand_lround (operand0, operand1);
17523 (define_expand "lround<mode>si2"
17524 [(match_operand:SI 0 "nonimmediate_operand" "")
17525 (match_operand:SSEMODEF 1 "register_operand" "")]
17526 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17527 && !flag_trapping_math && !flag_rounding_math
17530 ix86_expand_lround (operand0, operand1);
17534 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17535 (define_insn_and_split "frndintxf2_floor"
17536 [(set (match_operand:XF 0 "register_operand" "=f")
17537 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17538 UNSPEC_FRNDINT_FLOOR))
17539 (clobber (reg:CC FLAGS_REG))]
17540 "TARGET_USE_FANCY_MATH_387
17541 && flag_unsafe_math_optimizations
17542 && !(reload_completed || reload_in_progress)"
17547 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17549 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17550 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17552 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17553 operands[2], operands[3]));
17556 [(set_attr "type" "frndint")
17557 (set_attr "i387_cw" "floor")
17558 (set_attr "mode" "XF")])
17560 (define_insn "frndintxf2_floor_i387"
17561 [(set (match_operand:XF 0 "register_operand" "=f")
17562 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17563 UNSPEC_FRNDINT_FLOOR))
17564 (use (match_operand:HI 2 "memory_operand" "m"))
17565 (use (match_operand:HI 3 "memory_operand" "m"))]
17566 "TARGET_USE_FANCY_MATH_387
17567 && flag_unsafe_math_optimizations"
17568 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17569 [(set_attr "type" "frndint")
17570 (set_attr "i387_cw" "floor")
17571 (set_attr "mode" "XF")])
17573 (define_expand "floorxf2"
17574 [(use (match_operand:XF 0 "register_operand" ""))
17575 (use (match_operand:XF 1 "register_operand" ""))]
17576 "TARGET_USE_FANCY_MATH_387
17577 && flag_unsafe_math_optimizations && !optimize_size"
17579 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17583 (define_expand "floordf2"
17584 [(use (match_operand:DF 0 "register_operand" ""))
17585 (use (match_operand:DF 1 "register_operand" ""))]
17586 "((TARGET_USE_FANCY_MATH_387
17587 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17588 && flag_unsafe_math_optimizations)
17589 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17590 && !flag_trapping_math))
17593 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17594 && !flag_trapping_math)
17597 ix86_expand_floorceil (operand0, operand1, true);
17599 ix86_expand_floorceildf_32 (operand0, operand1, true);
17603 rtx op0 = gen_reg_rtx (XFmode);
17604 rtx op1 = gen_reg_rtx (XFmode);
17606 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17607 emit_insn (gen_frndintxf2_floor (op0, op1));
17609 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17614 (define_expand "floorsf2"
17615 [(use (match_operand:SF 0 "register_operand" ""))
17616 (use (match_operand:SF 1 "register_operand" ""))]
17617 "((TARGET_USE_FANCY_MATH_387
17618 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17619 && flag_unsafe_math_optimizations)
17620 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17621 && !flag_trapping_math))
17624 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17625 && !flag_trapping_math)
17626 ix86_expand_floorceil (operand0, operand1, true);
17629 rtx op0 = gen_reg_rtx (XFmode);
17630 rtx op1 = gen_reg_rtx (XFmode);
17632 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17633 emit_insn (gen_frndintxf2_floor (op0, op1));
17635 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17640 (define_insn_and_split "*fist<mode>2_floor_1"
17641 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17642 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17643 UNSPEC_FIST_FLOOR))
17644 (clobber (reg:CC FLAGS_REG))]
17645 "TARGET_USE_FANCY_MATH_387
17646 && flag_unsafe_math_optimizations
17647 && !(reload_completed || reload_in_progress)"
17652 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17654 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17655 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17656 if (memory_operand (operands[0], VOIDmode))
17657 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17658 operands[2], operands[3]));
17661 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17662 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17663 operands[2], operands[3],
17668 [(set_attr "type" "fistp")
17669 (set_attr "i387_cw" "floor")
17670 (set_attr "mode" "<MODE>")])
17672 (define_insn "fistdi2_floor"
17673 [(set (match_operand:DI 0 "memory_operand" "=m")
17674 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17675 UNSPEC_FIST_FLOOR))
17676 (use (match_operand:HI 2 "memory_operand" "m"))
17677 (use (match_operand:HI 3 "memory_operand" "m"))
17678 (clobber (match_scratch:XF 4 "=&1f"))]
17679 "TARGET_USE_FANCY_MATH_387
17680 && flag_unsafe_math_optimizations"
17681 "* return output_fix_trunc (insn, operands, 0);"
17682 [(set_attr "type" "fistp")
17683 (set_attr "i387_cw" "floor")
17684 (set_attr "mode" "DI")])
17686 (define_insn "fistdi2_floor_with_temp"
17687 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17688 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17689 UNSPEC_FIST_FLOOR))
17690 (use (match_operand:HI 2 "memory_operand" "m,m"))
17691 (use (match_operand:HI 3 "memory_operand" "m,m"))
17692 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17693 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17694 "TARGET_USE_FANCY_MATH_387
17695 && flag_unsafe_math_optimizations"
17697 [(set_attr "type" "fistp")
17698 (set_attr "i387_cw" "floor")
17699 (set_attr "mode" "DI")])
17702 [(set (match_operand:DI 0 "register_operand" "")
17703 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17704 UNSPEC_FIST_FLOOR))
17705 (use (match_operand:HI 2 "memory_operand" ""))
17706 (use (match_operand:HI 3 "memory_operand" ""))
17707 (clobber (match_operand:DI 4 "memory_operand" ""))
17708 (clobber (match_scratch 5 ""))]
17710 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17711 (use (match_dup 2))
17712 (use (match_dup 3))
17713 (clobber (match_dup 5))])
17714 (set (match_dup 0) (match_dup 4))]
17718 [(set (match_operand:DI 0 "memory_operand" "")
17719 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17720 UNSPEC_FIST_FLOOR))
17721 (use (match_operand:HI 2 "memory_operand" ""))
17722 (use (match_operand:HI 3 "memory_operand" ""))
17723 (clobber (match_operand:DI 4 "memory_operand" ""))
17724 (clobber (match_scratch 5 ""))]
17726 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17727 (use (match_dup 2))
17728 (use (match_dup 3))
17729 (clobber (match_dup 5))])]
17732 (define_insn "fist<mode>2_floor"
17733 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17734 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17735 UNSPEC_FIST_FLOOR))
17736 (use (match_operand:HI 2 "memory_operand" "m"))
17737 (use (match_operand:HI 3 "memory_operand" "m"))]
17738 "TARGET_USE_FANCY_MATH_387
17739 && flag_unsafe_math_optimizations"
17740 "* return output_fix_trunc (insn, operands, 0);"
17741 [(set_attr "type" "fistp")
17742 (set_attr "i387_cw" "floor")
17743 (set_attr "mode" "<MODE>")])
17745 (define_insn "fist<mode>2_floor_with_temp"
17746 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17747 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17748 UNSPEC_FIST_FLOOR))
17749 (use (match_operand:HI 2 "memory_operand" "m,m"))
17750 (use (match_operand:HI 3 "memory_operand" "m,m"))
17751 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17752 "TARGET_USE_FANCY_MATH_387
17753 && flag_unsafe_math_optimizations"
17755 [(set_attr "type" "fistp")
17756 (set_attr "i387_cw" "floor")
17757 (set_attr "mode" "<MODE>")])
17760 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17761 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17762 UNSPEC_FIST_FLOOR))
17763 (use (match_operand:HI 2 "memory_operand" ""))
17764 (use (match_operand:HI 3 "memory_operand" ""))
17765 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17767 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17768 UNSPEC_FIST_FLOOR))
17769 (use (match_dup 2))
17770 (use (match_dup 3))])
17771 (set (match_dup 0) (match_dup 4))]
17775 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17776 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17777 UNSPEC_FIST_FLOOR))
17778 (use (match_operand:HI 2 "memory_operand" ""))
17779 (use (match_operand:HI 3 "memory_operand" ""))
17780 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17782 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17783 UNSPEC_FIST_FLOOR))
17784 (use (match_dup 2))
17785 (use (match_dup 3))])]
17788 (define_expand "lfloorxf<mode>2"
17789 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17790 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17791 UNSPEC_FIST_FLOOR))
17792 (clobber (reg:CC FLAGS_REG))])]
17793 "TARGET_USE_FANCY_MATH_387
17794 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17795 && flag_unsafe_math_optimizations"
17798 (define_expand "lfloor<mode>di2"
17799 [(match_operand:DI 0 "nonimmediate_operand" "")
17800 (match_operand:SSEMODEF 1 "register_operand" "")]
17801 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17802 && !flag_trapping_math
17805 ix86_expand_lfloorceil (operand0, operand1, true);
17809 (define_expand "lfloor<mode>si2"
17810 [(match_operand:SI 0 "nonimmediate_operand" "")
17811 (match_operand:SSEMODEF 1 "register_operand" "")]
17812 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17813 && !flag_trapping_math
17814 && (!optimize_size || !TARGET_64BIT)"
17816 ix86_expand_lfloorceil (operand0, operand1, true);
17820 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17821 (define_insn_and_split "frndintxf2_ceil"
17822 [(set (match_operand:XF 0 "register_operand" "=f")
17823 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17824 UNSPEC_FRNDINT_CEIL))
17825 (clobber (reg:CC FLAGS_REG))]
17826 "TARGET_USE_FANCY_MATH_387
17827 && flag_unsafe_math_optimizations
17828 && !(reload_completed || reload_in_progress)"
17833 ix86_optimize_mode_switching[I387_CEIL] = 1;
17835 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17836 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17838 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17839 operands[2], operands[3]));
17842 [(set_attr "type" "frndint")
17843 (set_attr "i387_cw" "ceil")
17844 (set_attr "mode" "XF")])
17846 (define_insn "frndintxf2_ceil_i387"
17847 [(set (match_operand:XF 0 "register_operand" "=f")
17848 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17849 UNSPEC_FRNDINT_CEIL))
17850 (use (match_operand:HI 2 "memory_operand" "m"))
17851 (use (match_operand:HI 3 "memory_operand" "m"))]
17852 "TARGET_USE_FANCY_MATH_387
17853 && flag_unsafe_math_optimizations"
17854 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17855 [(set_attr "type" "frndint")
17856 (set_attr "i387_cw" "ceil")
17857 (set_attr "mode" "XF")])
17859 (define_expand "ceilxf2"
17860 [(use (match_operand:XF 0 "register_operand" ""))
17861 (use (match_operand:XF 1 "register_operand" ""))]
17862 "TARGET_USE_FANCY_MATH_387
17863 && flag_unsafe_math_optimizations && !optimize_size"
17865 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17869 (define_expand "ceildf2"
17870 [(use (match_operand:DF 0 "register_operand" ""))
17871 (use (match_operand:DF 1 "register_operand" ""))]
17872 "((TARGET_USE_FANCY_MATH_387
17873 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17874 && flag_unsafe_math_optimizations)
17875 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17876 && !flag_trapping_math))
17879 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17880 && !flag_trapping_math)
17883 ix86_expand_floorceil (operand0, operand1, false);
17885 ix86_expand_floorceildf_32 (operand0, operand1, false);
17889 rtx op0 = gen_reg_rtx (XFmode);
17890 rtx op1 = gen_reg_rtx (XFmode);
17892 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17893 emit_insn (gen_frndintxf2_ceil (op0, op1));
17895 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17900 (define_expand "ceilsf2"
17901 [(use (match_operand:SF 0 "register_operand" ""))
17902 (use (match_operand:SF 1 "register_operand" ""))]
17903 "((TARGET_USE_FANCY_MATH_387
17904 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17905 && flag_unsafe_math_optimizations)
17906 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17907 && !flag_trapping_math))
17910 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17911 && !flag_trapping_math)
17912 ix86_expand_floorceil (operand0, operand1, false);
17915 rtx op0 = gen_reg_rtx (XFmode);
17916 rtx op1 = gen_reg_rtx (XFmode);
17918 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17919 emit_insn (gen_frndintxf2_ceil (op0, op1));
17921 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17926 (define_insn_and_split "*fist<mode>2_ceil_1"
17927 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17928 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17930 (clobber (reg:CC FLAGS_REG))]
17931 "TARGET_USE_FANCY_MATH_387
17932 && flag_unsafe_math_optimizations
17933 && !(reload_completed || reload_in_progress)"
17938 ix86_optimize_mode_switching[I387_CEIL] = 1;
17940 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17941 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17942 if (memory_operand (operands[0], VOIDmode))
17943 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17944 operands[2], operands[3]));
17947 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17948 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17949 operands[2], operands[3],
17954 [(set_attr "type" "fistp")
17955 (set_attr "i387_cw" "ceil")
17956 (set_attr "mode" "<MODE>")])
17958 (define_insn "fistdi2_ceil"
17959 [(set (match_operand:DI 0 "memory_operand" "=m")
17960 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17962 (use (match_operand:HI 2 "memory_operand" "m"))
17963 (use (match_operand:HI 3 "memory_operand" "m"))
17964 (clobber (match_scratch:XF 4 "=&1f"))]
17965 "TARGET_USE_FANCY_MATH_387
17966 && flag_unsafe_math_optimizations"
17967 "* return output_fix_trunc (insn, operands, 0);"
17968 [(set_attr "type" "fistp")
17969 (set_attr "i387_cw" "ceil")
17970 (set_attr "mode" "DI")])
17972 (define_insn "fistdi2_ceil_with_temp"
17973 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17974 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17976 (use (match_operand:HI 2 "memory_operand" "m,m"))
17977 (use (match_operand:HI 3 "memory_operand" "m,m"))
17978 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17979 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17980 "TARGET_USE_FANCY_MATH_387
17981 && flag_unsafe_math_optimizations"
17983 [(set_attr "type" "fistp")
17984 (set_attr "i387_cw" "ceil")
17985 (set_attr "mode" "DI")])
17988 [(set (match_operand:DI 0 "register_operand" "")
17989 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17991 (use (match_operand:HI 2 "memory_operand" ""))
17992 (use (match_operand:HI 3 "memory_operand" ""))
17993 (clobber (match_operand:DI 4 "memory_operand" ""))
17994 (clobber (match_scratch 5 ""))]
17996 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17997 (use (match_dup 2))
17998 (use (match_dup 3))
17999 (clobber (match_dup 5))])
18000 (set (match_dup 0) (match_dup 4))]
18004 [(set (match_operand:DI 0 "memory_operand" "")
18005 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18007 (use (match_operand:HI 2 "memory_operand" ""))
18008 (use (match_operand:HI 3 "memory_operand" ""))
18009 (clobber (match_operand:DI 4 "memory_operand" ""))
18010 (clobber (match_scratch 5 ""))]
18012 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18013 (use (match_dup 2))
18014 (use (match_dup 3))
18015 (clobber (match_dup 5))])]
18018 (define_insn "fist<mode>2_ceil"
18019 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18020 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18022 (use (match_operand:HI 2 "memory_operand" "m"))
18023 (use (match_operand:HI 3 "memory_operand" "m"))]
18024 "TARGET_USE_FANCY_MATH_387
18025 && flag_unsafe_math_optimizations"
18026 "* return output_fix_trunc (insn, operands, 0);"
18027 [(set_attr "type" "fistp")
18028 (set_attr "i387_cw" "ceil")
18029 (set_attr "mode" "<MODE>")])
18031 (define_insn "fist<mode>2_ceil_with_temp"
18032 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18033 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18035 (use (match_operand:HI 2 "memory_operand" "m,m"))
18036 (use (match_operand:HI 3 "memory_operand" "m,m"))
18037 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
18038 "TARGET_USE_FANCY_MATH_387
18039 && flag_unsafe_math_optimizations"
18041 [(set_attr "type" "fistp")
18042 (set_attr "i387_cw" "ceil")
18043 (set_attr "mode" "<MODE>")])
18046 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18047 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18049 (use (match_operand:HI 2 "memory_operand" ""))
18050 (use (match_operand:HI 3 "memory_operand" ""))
18051 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18053 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18055 (use (match_dup 2))
18056 (use (match_dup 3))])
18057 (set (match_dup 0) (match_dup 4))]
18061 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18062 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18064 (use (match_operand:HI 2 "memory_operand" ""))
18065 (use (match_operand:HI 3 "memory_operand" ""))
18066 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18068 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18070 (use (match_dup 2))
18071 (use (match_dup 3))])]
18074 (define_expand "lceilxf<mode>2"
18075 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18076 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18078 (clobber (reg:CC FLAGS_REG))])]
18079 "TARGET_USE_FANCY_MATH_387
18080 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18081 && flag_unsafe_math_optimizations"
18084 (define_expand "lceil<mode>di2"
18085 [(match_operand:DI 0 "nonimmediate_operand" "")
18086 (match_operand:SSEMODEF 1 "register_operand" "")]
18087 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18088 && !flag_trapping_math"
18090 ix86_expand_lfloorceil (operand0, operand1, false);
18094 (define_expand "lceil<mode>si2"
18095 [(match_operand:SI 0 "nonimmediate_operand" "")
18096 (match_operand:SSEMODEF 1 "register_operand" "")]
18097 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18098 && !flag_trapping_math"
18100 ix86_expand_lfloorceil (operand0, operand1, false);
18104 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18105 (define_insn_and_split "frndintxf2_trunc"
18106 [(set (match_operand:XF 0 "register_operand" "=f")
18107 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18108 UNSPEC_FRNDINT_TRUNC))
18109 (clobber (reg:CC FLAGS_REG))]
18110 "TARGET_USE_FANCY_MATH_387
18111 && flag_unsafe_math_optimizations
18112 && !(reload_completed || reload_in_progress)"
18117 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18119 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18120 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18122 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18123 operands[2], operands[3]));
18126 [(set_attr "type" "frndint")
18127 (set_attr "i387_cw" "trunc")
18128 (set_attr "mode" "XF")])
18130 (define_insn "frndintxf2_trunc_i387"
18131 [(set (match_operand:XF 0 "register_operand" "=f")
18132 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18133 UNSPEC_FRNDINT_TRUNC))
18134 (use (match_operand:HI 2 "memory_operand" "m"))
18135 (use (match_operand:HI 3 "memory_operand" "m"))]
18136 "TARGET_USE_FANCY_MATH_387
18137 && flag_unsafe_math_optimizations"
18138 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18139 [(set_attr "type" "frndint")
18140 (set_attr "i387_cw" "trunc")
18141 (set_attr "mode" "XF")])
18143 (define_expand "btruncxf2"
18144 [(use (match_operand:XF 0 "register_operand" ""))
18145 (use (match_operand:XF 1 "register_operand" ""))]
18146 "TARGET_USE_FANCY_MATH_387
18147 && flag_unsafe_math_optimizations && !optimize_size"
18149 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18153 (define_expand "btruncdf2"
18154 [(use (match_operand:DF 0 "register_operand" ""))
18155 (use (match_operand:DF 1 "register_operand" ""))]
18156 "((TARGET_USE_FANCY_MATH_387
18157 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18158 && flag_unsafe_math_optimizations)
18159 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18160 && !flag_trapping_math))
18163 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18164 && !flag_trapping_math)
18167 ix86_expand_trunc (operand0, operand1);
18169 ix86_expand_truncdf_32 (operand0, operand1);
18173 rtx op0 = gen_reg_rtx (XFmode);
18174 rtx op1 = gen_reg_rtx (XFmode);
18176 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18177 emit_insn (gen_frndintxf2_trunc (op0, op1));
18179 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18184 (define_expand "btruncsf2"
18185 [(use (match_operand:SF 0 "register_operand" ""))
18186 (use (match_operand:SF 1 "register_operand" ""))]
18187 "((TARGET_USE_FANCY_MATH_387
18188 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18189 && flag_unsafe_math_optimizations)
18190 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18191 && !flag_trapping_math))
18194 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18195 && !flag_trapping_math)
18196 ix86_expand_trunc (operand0, operand1);
18199 rtx op0 = gen_reg_rtx (XFmode);
18200 rtx op1 = gen_reg_rtx (XFmode);
18202 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18203 emit_insn (gen_frndintxf2_trunc (op0, op1));
18205 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18210 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18211 (define_insn_and_split "frndintxf2_mask_pm"
18212 [(set (match_operand:XF 0 "register_operand" "=f")
18213 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18214 UNSPEC_FRNDINT_MASK_PM))
18215 (clobber (reg:CC FLAGS_REG))]
18216 "TARGET_USE_FANCY_MATH_387
18217 && flag_unsafe_math_optimizations
18218 && !(reload_completed || reload_in_progress)"
18223 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18225 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18226 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18228 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18229 operands[2], operands[3]));
18232 [(set_attr "type" "frndint")
18233 (set_attr "i387_cw" "mask_pm")
18234 (set_attr "mode" "XF")])
18236 (define_insn "frndintxf2_mask_pm_i387"
18237 [(set (match_operand:XF 0 "register_operand" "=f")
18238 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18239 UNSPEC_FRNDINT_MASK_PM))
18240 (use (match_operand:HI 2 "memory_operand" "m"))
18241 (use (match_operand:HI 3 "memory_operand" "m"))]
18242 "TARGET_USE_FANCY_MATH_387
18243 && flag_unsafe_math_optimizations"
18244 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18245 [(set_attr "type" "frndint")
18246 (set_attr "i387_cw" "mask_pm")
18247 (set_attr "mode" "XF")])
18249 (define_expand "nearbyintxf2"
18250 [(use (match_operand:XF 0 "register_operand" ""))
18251 (use (match_operand:XF 1 "register_operand" ""))]
18252 "TARGET_USE_FANCY_MATH_387
18253 && flag_unsafe_math_optimizations"
18255 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18260 (define_expand "nearbyintdf2"
18261 [(use (match_operand:DF 0 "register_operand" ""))
18262 (use (match_operand:DF 1 "register_operand" ""))]
18263 "TARGET_USE_FANCY_MATH_387
18264 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18265 && flag_unsafe_math_optimizations"
18267 rtx op0 = gen_reg_rtx (XFmode);
18268 rtx op1 = gen_reg_rtx (XFmode);
18270 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18271 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18273 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18277 (define_expand "nearbyintsf2"
18278 [(use (match_operand:SF 0 "register_operand" ""))
18279 (use (match_operand:SF 1 "register_operand" ""))]
18280 "TARGET_USE_FANCY_MATH_387
18281 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18282 && flag_unsafe_math_optimizations"
18284 rtx op0 = gen_reg_rtx (XFmode);
18285 rtx op1 = gen_reg_rtx (XFmode);
18287 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18288 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18290 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18294 (define_insn "fxam<mode>2_i387"
18295 [(set (match_operand:HI 0 "register_operand" "=a")
18297 [(match_operand:X87MODEF 1 "register_operand" "f")]
18299 "TARGET_USE_FANCY_MATH_387"
18300 "fxam\n\tfnstsw\t%0"
18301 [(set_attr "type" "multi")
18302 (set_attr "unit" "i387")
18303 (set_attr "mode" "<MODE>")])
18305 (define_expand "isinf<mode>2"
18306 [(use (match_operand:SI 0 "register_operand" ""))
18307 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18308 "TARGET_USE_FANCY_MATH_387
18309 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18310 || TARGET_MIX_SSE_I387)"
18312 rtx mask = GEN_INT (0x45);
18313 rtx val = GEN_INT (0x05);
18317 rtx scratch = gen_reg_rtx (HImode);
18318 rtx res = gen_reg_rtx (QImode);
18320 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18321 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18322 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18323 cond = gen_rtx_fmt_ee (EQ, QImode,
18324 gen_rtx_REG (CCmode, FLAGS_REG),
18326 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18327 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18332 ;; Block operation instructions
18334 (define_expand "movmemsi"
18335 [(use (match_operand:BLK 0 "memory_operand" ""))
18336 (use (match_operand:BLK 1 "memory_operand" ""))
18337 (use (match_operand:SI 2 "nonmemory_operand" ""))
18338 (use (match_operand:SI 3 "const_int_operand" ""))
18339 (use (match_operand:SI 4 "const_int_operand" ""))
18340 (use (match_operand:SI 5 "const_int_operand" ""))]
18343 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18344 operands[4], operands[5]))
18350 (define_expand "movmemdi"
18351 [(use (match_operand:BLK 0 "memory_operand" ""))
18352 (use (match_operand:BLK 1 "memory_operand" ""))
18353 (use (match_operand:DI 2 "nonmemory_operand" ""))
18354 (use (match_operand:DI 3 "const_int_operand" ""))
18355 (use (match_operand:SI 4 "const_int_operand" ""))
18356 (use (match_operand:SI 5 "const_int_operand" ""))]
18359 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18360 operands[4], operands[5]))
18366 ;; Most CPUs don't like single string operations
18367 ;; Handle this case here to simplify previous expander.
18369 (define_expand "strmov"
18370 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18371 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18372 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18373 (clobber (reg:CC FLAGS_REG))])
18374 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18375 (clobber (reg:CC FLAGS_REG))])]
18378 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18380 /* If .md ever supports :P for Pmode, these can be directly
18381 in the pattern above. */
18382 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18383 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18385 if (TARGET_SINGLE_STRINGOP || optimize_size)
18387 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18388 operands[2], operands[3],
18389 operands[5], operands[6]));
18393 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18396 (define_expand "strmov_singleop"
18397 [(parallel [(set (match_operand 1 "memory_operand" "")
18398 (match_operand 3 "memory_operand" ""))
18399 (set (match_operand 0 "register_operand" "")
18400 (match_operand 4 "" ""))
18401 (set (match_operand 2 "register_operand" "")
18402 (match_operand 5 "" ""))])]
18403 "TARGET_SINGLE_STRINGOP || optimize_size"
18406 (define_insn "*strmovdi_rex_1"
18407 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18408 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18409 (set (match_operand:DI 0 "register_operand" "=D")
18410 (plus:DI (match_dup 2)
18412 (set (match_operand:DI 1 "register_operand" "=S")
18413 (plus:DI (match_dup 3)
18415 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18417 [(set_attr "type" "str")
18418 (set_attr "mode" "DI")
18419 (set_attr "memory" "both")])
18421 (define_insn "*strmovsi_1"
18422 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18423 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18424 (set (match_operand:SI 0 "register_operand" "=D")
18425 (plus:SI (match_dup 2)
18427 (set (match_operand:SI 1 "register_operand" "=S")
18428 (plus:SI (match_dup 3)
18430 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18432 [(set_attr "type" "str")
18433 (set_attr "mode" "SI")
18434 (set_attr "memory" "both")])
18436 (define_insn "*strmovsi_rex_1"
18437 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18438 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18439 (set (match_operand:DI 0 "register_operand" "=D")
18440 (plus:DI (match_dup 2)
18442 (set (match_operand:DI 1 "register_operand" "=S")
18443 (plus:DI (match_dup 3)
18445 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18447 [(set_attr "type" "str")
18448 (set_attr "mode" "SI")
18449 (set_attr "memory" "both")])
18451 (define_insn "*strmovhi_1"
18452 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18453 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18454 (set (match_operand:SI 0 "register_operand" "=D")
18455 (plus:SI (match_dup 2)
18457 (set (match_operand:SI 1 "register_operand" "=S")
18458 (plus:SI (match_dup 3)
18460 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18462 [(set_attr "type" "str")
18463 (set_attr "memory" "both")
18464 (set_attr "mode" "HI")])
18466 (define_insn "*strmovhi_rex_1"
18467 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18468 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18469 (set (match_operand:DI 0 "register_operand" "=D")
18470 (plus:DI (match_dup 2)
18472 (set (match_operand:DI 1 "register_operand" "=S")
18473 (plus:DI (match_dup 3)
18475 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18477 [(set_attr "type" "str")
18478 (set_attr "memory" "both")
18479 (set_attr "mode" "HI")])
18481 (define_insn "*strmovqi_1"
18482 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18483 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18484 (set (match_operand:SI 0 "register_operand" "=D")
18485 (plus:SI (match_dup 2)
18487 (set (match_operand:SI 1 "register_operand" "=S")
18488 (plus:SI (match_dup 3)
18490 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18492 [(set_attr "type" "str")
18493 (set_attr "memory" "both")
18494 (set_attr "mode" "QI")])
18496 (define_insn "*strmovqi_rex_1"
18497 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18498 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18499 (set (match_operand:DI 0 "register_operand" "=D")
18500 (plus:DI (match_dup 2)
18502 (set (match_operand:DI 1 "register_operand" "=S")
18503 (plus:DI (match_dup 3)
18505 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18507 [(set_attr "type" "str")
18508 (set_attr "memory" "both")
18509 (set_attr "mode" "QI")])
18511 (define_expand "rep_mov"
18512 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18513 (set (match_operand 0 "register_operand" "")
18514 (match_operand 5 "" ""))
18515 (set (match_operand 2 "register_operand" "")
18516 (match_operand 6 "" ""))
18517 (set (match_operand 1 "memory_operand" "")
18518 (match_operand 3 "memory_operand" ""))
18519 (use (match_dup 4))])]
18523 (define_insn "*rep_movdi_rex64"
18524 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18525 (set (match_operand:DI 0 "register_operand" "=D")
18526 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18528 (match_operand:DI 3 "register_operand" "0")))
18529 (set (match_operand:DI 1 "register_operand" "=S")
18530 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18531 (match_operand:DI 4 "register_operand" "1")))
18532 (set (mem:BLK (match_dup 3))
18533 (mem:BLK (match_dup 4)))
18534 (use (match_dup 5))]
18536 "{rep\;movsq|rep movsq}"
18537 [(set_attr "type" "str")
18538 (set_attr "prefix_rep" "1")
18539 (set_attr "memory" "both")
18540 (set_attr "mode" "DI")])
18542 (define_insn "*rep_movsi"
18543 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18544 (set (match_operand:SI 0 "register_operand" "=D")
18545 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18547 (match_operand:SI 3 "register_operand" "0")))
18548 (set (match_operand:SI 1 "register_operand" "=S")
18549 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18550 (match_operand:SI 4 "register_operand" "1")))
18551 (set (mem:BLK (match_dup 3))
18552 (mem:BLK (match_dup 4)))
18553 (use (match_dup 5))]
18555 "{rep\;movsl|rep movsd}"
18556 [(set_attr "type" "str")
18557 (set_attr "prefix_rep" "1")
18558 (set_attr "memory" "both")
18559 (set_attr "mode" "SI")])
18561 (define_insn "*rep_movsi_rex64"
18562 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18563 (set (match_operand:DI 0 "register_operand" "=D")
18564 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18566 (match_operand:DI 3 "register_operand" "0")))
18567 (set (match_operand:DI 1 "register_operand" "=S")
18568 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18569 (match_operand:DI 4 "register_operand" "1")))
18570 (set (mem:BLK (match_dup 3))
18571 (mem:BLK (match_dup 4)))
18572 (use (match_dup 5))]
18574 "{rep\;movsl|rep movsd}"
18575 [(set_attr "type" "str")
18576 (set_attr "prefix_rep" "1")
18577 (set_attr "memory" "both")
18578 (set_attr "mode" "SI")])
18580 (define_insn "*rep_movqi"
18581 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18582 (set (match_operand:SI 0 "register_operand" "=D")
18583 (plus:SI (match_operand:SI 3 "register_operand" "0")
18584 (match_operand:SI 5 "register_operand" "2")))
18585 (set (match_operand:SI 1 "register_operand" "=S")
18586 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18587 (set (mem:BLK (match_dup 3))
18588 (mem:BLK (match_dup 4)))
18589 (use (match_dup 5))]
18591 "{rep\;movsb|rep movsb}"
18592 [(set_attr "type" "str")
18593 (set_attr "prefix_rep" "1")
18594 (set_attr "memory" "both")
18595 (set_attr "mode" "SI")])
18597 (define_insn "*rep_movqi_rex64"
18598 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18599 (set (match_operand:DI 0 "register_operand" "=D")
18600 (plus:DI (match_operand:DI 3 "register_operand" "0")
18601 (match_operand:DI 5 "register_operand" "2")))
18602 (set (match_operand:DI 1 "register_operand" "=S")
18603 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18604 (set (mem:BLK (match_dup 3))
18605 (mem:BLK (match_dup 4)))
18606 (use (match_dup 5))]
18608 "{rep\;movsb|rep movsb}"
18609 [(set_attr "type" "str")
18610 (set_attr "prefix_rep" "1")
18611 (set_attr "memory" "both")
18612 (set_attr "mode" "SI")])
18614 (define_expand "setmemsi"
18615 [(use (match_operand:BLK 0 "memory_operand" ""))
18616 (use (match_operand:SI 1 "nonmemory_operand" ""))
18617 (use (match_operand 2 "const_int_operand" ""))
18618 (use (match_operand 3 "const_int_operand" ""))
18619 (use (match_operand:SI 4 "const_int_operand" ""))
18620 (use (match_operand:SI 5 "const_int_operand" ""))]
18623 if (ix86_expand_setmem (operands[0], operands[1],
18624 operands[2], operands[3],
18625 operands[4], operands[5]))
18631 (define_expand "setmemdi"
18632 [(use (match_operand:BLK 0 "memory_operand" ""))
18633 (use (match_operand:DI 1 "nonmemory_operand" ""))
18634 (use (match_operand 2 "const_int_operand" ""))
18635 (use (match_operand 3 "const_int_operand" ""))
18636 (use (match_operand 4 "const_int_operand" ""))
18637 (use (match_operand 5 "const_int_operand" ""))]
18640 if (ix86_expand_setmem (operands[0], operands[1],
18641 operands[2], operands[3],
18642 operands[4], operands[5]))
18648 ;; Most CPUs don't like single string operations
18649 ;; Handle this case here to simplify previous expander.
18651 (define_expand "strset"
18652 [(set (match_operand 1 "memory_operand" "")
18653 (match_operand 2 "register_operand" ""))
18654 (parallel [(set (match_operand 0 "register_operand" "")
18656 (clobber (reg:CC FLAGS_REG))])]
18659 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18660 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18662 /* If .md ever supports :P for Pmode, this can be directly
18663 in the pattern above. */
18664 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18665 GEN_INT (GET_MODE_SIZE (GET_MODE
18667 if (TARGET_SINGLE_STRINGOP || optimize_size)
18669 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18675 (define_expand "strset_singleop"
18676 [(parallel [(set (match_operand 1 "memory_operand" "")
18677 (match_operand 2 "register_operand" ""))
18678 (set (match_operand 0 "register_operand" "")
18679 (match_operand 3 "" ""))])]
18680 "TARGET_SINGLE_STRINGOP || optimize_size"
18683 (define_insn "*strsetdi_rex_1"
18684 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18685 (match_operand:DI 2 "register_operand" "a"))
18686 (set (match_operand:DI 0 "register_operand" "=D")
18687 (plus:DI (match_dup 1)
18689 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18691 [(set_attr "type" "str")
18692 (set_attr "memory" "store")
18693 (set_attr "mode" "DI")])
18695 (define_insn "*strsetsi_1"
18696 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18697 (match_operand:SI 2 "register_operand" "a"))
18698 (set (match_operand:SI 0 "register_operand" "=D")
18699 (plus:SI (match_dup 1)
18701 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18703 [(set_attr "type" "str")
18704 (set_attr "memory" "store")
18705 (set_attr "mode" "SI")])
18707 (define_insn "*strsetsi_rex_1"
18708 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18709 (match_operand:SI 2 "register_operand" "a"))
18710 (set (match_operand:DI 0 "register_operand" "=D")
18711 (plus:DI (match_dup 1)
18713 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18715 [(set_attr "type" "str")
18716 (set_attr "memory" "store")
18717 (set_attr "mode" "SI")])
18719 (define_insn "*strsethi_1"
18720 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18721 (match_operand:HI 2 "register_operand" "a"))
18722 (set (match_operand:SI 0 "register_operand" "=D")
18723 (plus:SI (match_dup 1)
18725 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18727 [(set_attr "type" "str")
18728 (set_attr "memory" "store")
18729 (set_attr "mode" "HI")])
18731 (define_insn "*strsethi_rex_1"
18732 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18733 (match_operand:HI 2 "register_operand" "a"))
18734 (set (match_operand:DI 0 "register_operand" "=D")
18735 (plus:DI (match_dup 1)
18737 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18739 [(set_attr "type" "str")
18740 (set_attr "memory" "store")
18741 (set_attr "mode" "HI")])
18743 (define_insn "*strsetqi_1"
18744 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18745 (match_operand:QI 2 "register_operand" "a"))
18746 (set (match_operand:SI 0 "register_operand" "=D")
18747 (plus:SI (match_dup 1)
18749 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18751 [(set_attr "type" "str")
18752 (set_attr "memory" "store")
18753 (set_attr "mode" "QI")])
18755 (define_insn "*strsetqi_rex_1"
18756 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18757 (match_operand:QI 2 "register_operand" "a"))
18758 (set (match_operand:DI 0 "register_operand" "=D")
18759 (plus:DI (match_dup 1)
18761 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18763 [(set_attr "type" "str")
18764 (set_attr "memory" "store")
18765 (set_attr "mode" "QI")])
18767 (define_expand "rep_stos"
18768 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18769 (set (match_operand 0 "register_operand" "")
18770 (match_operand 4 "" ""))
18771 (set (match_operand 2 "memory_operand" "") (const_int 0))
18772 (use (match_operand 3 "register_operand" ""))
18773 (use (match_dup 1))])]
18777 (define_insn "*rep_stosdi_rex64"
18778 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18779 (set (match_operand:DI 0 "register_operand" "=D")
18780 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18782 (match_operand:DI 3 "register_operand" "0")))
18783 (set (mem:BLK (match_dup 3))
18785 (use (match_operand:DI 2 "register_operand" "a"))
18786 (use (match_dup 4))]
18788 "{rep\;stosq|rep stosq}"
18789 [(set_attr "type" "str")
18790 (set_attr "prefix_rep" "1")
18791 (set_attr "memory" "store")
18792 (set_attr "mode" "DI")])
18794 (define_insn "*rep_stossi"
18795 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18796 (set (match_operand:SI 0 "register_operand" "=D")
18797 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18799 (match_operand:SI 3 "register_operand" "0")))
18800 (set (mem:BLK (match_dup 3))
18802 (use (match_operand:SI 2 "register_operand" "a"))
18803 (use (match_dup 4))]
18805 "{rep\;stosl|rep stosd}"
18806 [(set_attr "type" "str")
18807 (set_attr "prefix_rep" "1")
18808 (set_attr "memory" "store")
18809 (set_attr "mode" "SI")])
18811 (define_insn "*rep_stossi_rex64"
18812 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18813 (set (match_operand:DI 0 "register_operand" "=D")
18814 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18816 (match_operand:DI 3 "register_operand" "0")))
18817 (set (mem:BLK (match_dup 3))
18819 (use (match_operand:SI 2 "register_operand" "a"))
18820 (use (match_dup 4))]
18822 "{rep\;stosl|rep stosd}"
18823 [(set_attr "type" "str")
18824 (set_attr "prefix_rep" "1")
18825 (set_attr "memory" "store")
18826 (set_attr "mode" "SI")])
18828 (define_insn "*rep_stosqi"
18829 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18830 (set (match_operand:SI 0 "register_operand" "=D")
18831 (plus:SI (match_operand:SI 3 "register_operand" "0")
18832 (match_operand:SI 4 "register_operand" "1")))
18833 (set (mem:BLK (match_dup 3))
18835 (use (match_operand:QI 2 "register_operand" "a"))
18836 (use (match_dup 4))]
18838 "{rep\;stosb|rep stosb}"
18839 [(set_attr "type" "str")
18840 (set_attr "prefix_rep" "1")
18841 (set_attr "memory" "store")
18842 (set_attr "mode" "QI")])
18844 (define_insn "*rep_stosqi_rex64"
18845 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18846 (set (match_operand:DI 0 "register_operand" "=D")
18847 (plus:DI (match_operand:DI 3 "register_operand" "0")
18848 (match_operand:DI 4 "register_operand" "1")))
18849 (set (mem:BLK (match_dup 3))
18851 (use (match_operand:QI 2 "register_operand" "a"))
18852 (use (match_dup 4))]
18854 "{rep\;stosb|rep stosb}"
18855 [(set_attr "type" "str")
18856 (set_attr "prefix_rep" "1")
18857 (set_attr "memory" "store")
18858 (set_attr "mode" "QI")])
18860 (define_expand "cmpstrnsi"
18861 [(set (match_operand:SI 0 "register_operand" "")
18862 (compare:SI (match_operand:BLK 1 "general_operand" "")
18863 (match_operand:BLK 2 "general_operand" "")))
18864 (use (match_operand 3 "general_operand" ""))
18865 (use (match_operand 4 "immediate_operand" ""))]
18866 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18868 rtx addr1, addr2, out, outlow, count, countreg, align;
18870 /* Can't use this if the user has appropriated esi or edi. */
18871 if (global_regs[4] || global_regs[5])
18876 out = gen_reg_rtx (SImode);
18878 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18879 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18880 if (addr1 != XEXP (operands[1], 0))
18881 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18882 if (addr2 != XEXP (operands[2], 0))
18883 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18885 count = operands[3];
18886 countreg = ix86_zero_extend_to_Pmode (count);
18888 /* %%% Iff we are testing strict equality, we can use known alignment
18889 to good advantage. This may be possible with combine, particularly
18890 once cc0 is dead. */
18891 align = operands[4];
18893 if (CONST_INT_P (count))
18895 if (INTVAL (count) == 0)
18897 emit_move_insn (operands[0], const0_rtx);
18900 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18901 operands[1], operands[2]));
18906 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18908 emit_insn (gen_cmpsi_1 (countreg, countreg));
18909 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18910 operands[1], operands[2]));
18913 outlow = gen_lowpart (QImode, out);
18914 emit_insn (gen_cmpintqi (outlow));
18915 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18917 if (operands[0] != out)
18918 emit_move_insn (operands[0], out);
18923 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18925 (define_expand "cmpintqi"
18926 [(set (match_dup 1)
18927 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18929 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18930 (parallel [(set (match_operand:QI 0 "register_operand" "")
18931 (minus:QI (match_dup 1)
18933 (clobber (reg:CC FLAGS_REG))])]
18935 "operands[1] = gen_reg_rtx (QImode);
18936 operands[2] = gen_reg_rtx (QImode);")
18938 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18939 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18941 (define_expand "cmpstrnqi_nz_1"
18942 [(parallel [(set (reg:CC FLAGS_REG)
18943 (compare:CC (match_operand 4 "memory_operand" "")
18944 (match_operand 5 "memory_operand" "")))
18945 (use (match_operand 2 "register_operand" ""))
18946 (use (match_operand:SI 3 "immediate_operand" ""))
18947 (clobber (match_operand 0 "register_operand" ""))
18948 (clobber (match_operand 1 "register_operand" ""))
18949 (clobber (match_dup 2))])]
18953 (define_insn "*cmpstrnqi_nz_1"
18954 [(set (reg:CC FLAGS_REG)
18955 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18956 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18957 (use (match_operand:SI 6 "register_operand" "2"))
18958 (use (match_operand:SI 3 "immediate_operand" "i"))
18959 (clobber (match_operand:SI 0 "register_operand" "=S"))
18960 (clobber (match_operand:SI 1 "register_operand" "=D"))
18961 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18964 [(set_attr "type" "str")
18965 (set_attr "mode" "QI")
18966 (set_attr "prefix_rep" "1")])
18968 (define_insn "*cmpstrnqi_nz_rex_1"
18969 [(set (reg:CC FLAGS_REG)
18970 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18971 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18972 (use (match_operand:DI 6 "register_operand" "2"))
18973 (use (match_operand:SI 3 "immediate_operand" "i"))
18974 (clobber (match_operand:DI 0 "register_operand" "=S"))
18975 (clobber (match_operand:DI 1 "register_operand" "=D"))
18976 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18979 [(set_attr "type" "str")
18980 (set_attr "mode" "QI")
18981 (set_attr "prefix_rep" "1")])
18983 ;; The same, but the count is not known to not be zero.
18985 (define_expand "cmpstrnqi_1"
18986 [(parallel [(set (reg:CC FLAGS_REG)
18987 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18989 (compare:CC (match_operand 4 "memory_operand" "")
18990 (match_operand 5 "memory_operand" ""))
18992 (use (match_operand:SI 3 "immediate_operand" ""))
18993 (use (reg:CC FLAGS_REG))
18994 (clobber (match_operand 0 "register_operand" ""))
18995 (clobber (match_operand 1 "register_operand" ""))
18996 (clobber (match_dup 2))])]
19000 (define_insn "*cmpstrnqi_1"
19001 [(set (reg:CC FLAGS_REG)
19002 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19004 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19005 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19007 (use (match_operand:SI 3 "immediate_operand" "i"))
19008 (use (reg:CC FLAGS_REG))
19009 (clobber (match_operand:SI 0 "register_operand" "=S"))
19010 (clobber (match_operand:SI 1 "register_operand" "=D"))
19011 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19014 [(set_attr "type" "str")
19015 (set_attr "mode" "QI")
19016 (set_attr "prefix_rep" "1")])
19018 (define_insn "*cmpstrnqi_rex_1"
19019 [(set (reg:CC FLAGS_REG)
19020 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19022 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19023 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19025 (use (match_operand:SI 3 "immediate_operand" "i"))
19026 (use (reg:CC FLAGS_REG))
19027 (clobber (match_operand:DI 0 "register_operand" "=S"))
19028 (clobber (match_operand:DI 1 "register_operand" "=D"))
19029 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19032 [(set_attr "type" "str")
19033 (set_attr "mode" "QI")
19034 (set_attr "prefix_rep" "1")])
19036 (define_expand "strlensi"
19037 [(set (match_operand:SI 0 "register_operand" "")
19038 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19039 (match_operand:QI 2 "immediate_operand" "")
19040 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19043 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19049 (define_expand "strlendi"
19050 [(set (match_operand:DI 0 "register_operand" "")
19051 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19052 (match_operand:QI 2 "immediate_operand" "")
19053 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19056 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19062 (define_expand "strlenqi_1"
19063 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19064 (clobber (match_operand 1 "register_operand" ""))
19065 (clobber (reg:CC FLAGS_REG))])]
19069 (define_insn "*strlenqi_1"
19070 [(set (match_operand:SI 0 "register_operand" "=&c")
19071 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19072 (match_operand:QI 2 "register_operand" "a")
19073 (match_operand:SI 3 "immediate_operand" "i")
19074 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19075 (clobber (match_operand:SI 1 "register_operand" "=D"))
19076 (clobber (reg:CC FLAGS_REG))]
19079 [(set_attr "type" "str")
19080 (set_attr "mode" "QI")
19081 (set_attr "prefix_rep" "1")])
19083 (define_insn "*strlenqi_rex_1"
19084 [(set (match_operand:DI 0 "register_operand" "=&c")
19085 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19086 (match_operand:QI 2 "register_operand" "a")
19087 (match_operand:DI 3 "immediate_operand" "i")
19088 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19089 (clobber (match_operand:DI 1 "register_operand" "=D"))
19090 (clobber (reg:CC FLAGS_REG))]
19093 [(set_attr "type" "str")
19094 (set_attr "mode" "QI")
19095 (set_attr "prefix_rep" "1")])
19097 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19098 ;; handled in combine, but it is not currently up to the task.
19099 ;; When used for their truth value, the cmpstrn* expanders generate
19108 ;; The intermediate three instructions are unnecessary.
19110 ;; This one handles cmpstrn*_nz_1...
19113 (set (reg:CC FLAGS_REG)
19114 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19115 (mem:BLK (match_operand 5 "register_operand" ""))))
19116 (use (match_operand 6 "register_operand" ""))
19117 (use (match_operand:SI 3 "immediate_operand" ""))
19118 (clobber (match_operand 0 "register_operand" ""))
19119 (clobber (match_operand 1 "register_operand" ""))
19120 (clobber (match_operand 2 "register_operand" ""))])
19121 (set (match_operand:QI 7 "register_operand" "")
19122 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19123 (set (match_operand:QI 8 "register_operand" "")
19124 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19125 (set (reg FLAGS_REG)
19126 (compare (match_dup 7) (match_dup 8)))
19128 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19130 (set (reg:CC FLAGS_REG)
19131 (compare:CC (mem:BLK (match_dup 4))
19132 (mem:BLK (match_dup 5))))
19133 (use (match_dup 6))
19134 (use (match_dup 3))
19135 (clobber (match_dup 0))
19136 (clobber (match_dup 1))
19137 (clobber (match_dup 2))])]
19140 ;; ...and this one handles cmpstrn*_1.
19143 (set (reg:CC FLAGS_REG)
19144 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19146 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19147 (mem:BLK (match_operand 5 "register_operand" "")))
19149 (use (match_operand:SI 3 "immediate_operand" ""))
19150 (use (reg:CC FLAGS_REG))
19151 (clobber (match_operand 0 "register_operand" ""))
19152 (clobber (match_operand 1 "register_operand" ""))
19153 (clobber (match_operand 2 "register_operand" ""))])
19154 (set (match_operand:QI 7 "register_operand" "")
19155 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19156 (set (match_operand:QI 8 "register_operand" "")
19157 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19158 (set (reg FLAGS_REG)
19159 (compare (match_dup 7) (match_dup 8)))
19161 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19163 (set (reg:CC FLAGS_REG)
19164 (if_then_else:CC (ne (match_dup 6)
19166 (compare:CC (mem:BLK (match_dup 4))
19167 (mem:BLK (match_dup 5)))
19169 (use (match_dup 3))
19170 (use (reg:CC FLAGS_REG))
19171 (clobber (match_dup 0))
19172 (clobber (match_dup 1))
19173 (clobber (match_dup 2))])]
19178 ;; Conditional move instructions.
19180 (define_expand "movdicc"
19181 [(set (match_operand:DI 0 "register_operand" "")
19182 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19183 (match_operand:DI 2 "general_operand" "")
19184 (match_operand:DI 3 "general_operand" "")))]
19186 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19188 (define_insn "x86_movdicc_0_m1_rex64"
19189 [(set (match_operand:DI 0 "register_operand" "=r")
19190 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19193 (clobber (reg:CC FLAGS_REG))]
19196 ; Since we don't have the proper number of operands for an alu insn,
19197 ; fill in all the blanks.
19198 [(set_attr "type" "alu")
19199 (set_attr "pent_pair" "pu")
19200 (set_attr "memory" "none")
19201 (set_attr "imm_disp" "false")
19202 (set_attr "mode" "DI")
19203 (set_attr "length_immediate" "0")])
19205 (define_insn "*movdicc_c_rex64"
19206 [(set (match_operand:DI 0 "register_operand" "=r,r")
19207 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19208 [(reg FLAGS_REG) (const_int 0)])
19209 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19210 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19211 "TARGET_64BIT && TARGET_CMOVE
19212 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19214 cmov%O2%C1\t{%2, %0|%0, %2}
19215 cmov%O2%c1\t{%3, %0|%0, %3}"
19216 [(set_attr "type" "icmov")
19217 (set_attr "mode" "DI")])
19219 (define_expand "movsicc"
19220 [(set (match_operand:SI 0 "register_operand" "")
19221 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19222 (match_operand:SI 2 "general_operand" "")
19223 (match_operand:SI 3 "general_operand" "")))]
19225 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19227 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19228 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19229 ;; So just document what we're doing explicitly.
19231 (define_insn "x86_movsicc_0_m1"
19232 [(set (match_operand:SI 0 "register_operand" "=r")
19233 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19236 (clobber (reg:CC FLAGS_REG))]
19239 ; Since we don't have the proper number of operands for an alu insn,
19240 ; fill in all the blanks.
19241 [(set_attr "type" "alu")
19242 (set_attr "pent_pair" "pu")
19243 (set_attr "memory" "none")
19244 (set_attr "imm_disp" "false")
19245 (set_attr "mode" "SI")
19246 (set_attr "length_immediate" "0")])
19248 (define_insn "*movsicc_noc"
19249 [(set (match_operand:SI 0 "register_operand" "=r,r")
19250 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19251 [(reg FLAGS_REG) (const_int 0)])
19252 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19253 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19255 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19257 cmov%O2%C1\t{%2, %0|%0, %2}
19258 cmov%O2%c1\t{%3, %0|%0, %3}"
19259 [(set_attr "type" "icmov")
19260 (set_attr "mode" "SI")])
19262 (define_expand "movhicc"
19263 [(set (match_operand:HI 0 "register_operand" "")
19264 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19265 (match_operand:HI 2 "general_operand" "")
19266 (match_operand:HI 3 "general_operand" "")))]
19267 "TARGET_HIMODE_MATH"
19268 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19270 (define_insn "*movhicc_noc"
19271 [(set (match_operand:HI 0 "register_operand" "=r,r")
19272 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19273 [(reg FLAGS_REG) (const_int 0)])
19274 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19275 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19277 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19279 cmov%O2%C1\t{%2, %0|%0, %2}
19280 cmov%O2%c1\t{%3, %0|%0, %3}"
19281 [(set_attr "type" "icmov")
19282 (set_attr "mode" "HI")])
19284 (define_expand "movqicc"
19285 [(set (match_operand:QI 0 "register_operand" "")
19286 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19287 (match_operand:QI 2 "general_operand" "")
19288 (match_operand:QI 3 "general_operand" "")))]
19289 "TARGET_QIMODE_MATH"
19290 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19292 (define_insn_and_split "*movqicc_noc"
19293 [(set (match_operand:QI 0 "register_operand" "=r,r")
19294 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19295 [(match_operand 4 "flags_reg_operand" "")
19297 (match_operand:QI 2 "register_operand" "r,0")
19298 (match_operand:QI 3 "register_operand" "0,r")))]
19299 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19301 "&& reload_completed"
19302 [(set (match_dup 0)
19303 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19306 "operands[0] = gen_lowpart (SImode, operands[0]);
19307 operands[2] = gen_lowpart (SImode, operands[2]);
19308 operands[3] = gen_lowpart (SImode, operands[3]);"
19309 [(set_attr "type" "icmov")
19310 (set_attr "mode" "SI")])
19312 (define_expand "movsfcc"
19313 [(set (match_operand:SF 0 "register_operand" "")
19314 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19315 (match_operand:SF 2 "register_operand" "")
19316 (match_operand:SF 3 "register_operand" "")))]
19317 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19318 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19320 (define_insn "*movsfcc_1_387"
19321 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19322 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19323 [(reg FLAGS_REG) (const_int 0)])
19324 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19325 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19326 "TARGET_80387 && TARGET_CMOVE
19327 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19329 fcmov%F1\t{%2, %0|%0, %2}
19330 fcmov%f1\t{%3, %0|%0, %3}
19331 cmov%O2%C1\t{%2, %0|%0, %2}
19332 cmov%O2%c1\t{%3, %0|%0, %3}"
19333 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19334 (set_attr "mode" "SF,SF,SI,SI")])
19336 (define_expand "movdfcc"
19337 [(set (match_operand:DF 0 "register_operand" "")
19338 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19339 (match_operand:DF 2 "register_operand" "")
19340 (match_operand:DF 3 "register_operand" "")))]
19341 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19342 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19344 (define_insn "*movdfcc_1"
19345 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19346 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19347 [(reg FLAGS_REG) (const_int 0)])
19348 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19349 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19350 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19351 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19353 fcmov%F1\t{%2, %0|%0, %2}
19354 fcmov%f1\t{%3, %0|%0, %3}
19357 [(set_attr "type" "fcmov,fcmov,multi,multi")
19358 (set_attr "mode" "DF")])
19360 (define_insn "*movdfcc_1_rex64"
19361 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19362 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19363 [(reg FLAGS_REG) (const_int 0)])
19364 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19365 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19366 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19367 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19369 fcmov%F1\t{%2, %0|%0, %2}
19370 fcmov%f1\t{%3, %0|%0, %3}
19371 cmov%O2%C1\t{%2, %0|%0, %2}
19372 cmov%O2%c1\t{%3, %0|%0, %3}"
19373 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19374 (set_attr "mode" "DF")])
19377 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19378 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19379 [(match_operand 4 "flags_reg_operand" "")
19381 (match_operand:DF 2 "nonimmediate_operand" "")
19382 (match_operand:DF 3 "nonimmediate_operand" "")))]
19383 "!TARGET_64BIT && reload_completed"
19384 [(set (match_dup 2)
19385 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19389 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19392 "split_di (operands+2, 1, operands+5, operands+6);
19393 split_di (operands+3, 1, operands+7, operands+8);
19394 split_di (operands, 1, operands+2, operands+3);")
19396 (define_expand "movxfcc"
19397 [(set (match_operand:XF 0 "register_operand" "")
19398 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19399 (match_operand:XF 2 "register_operand" "")
19400 (match_operand:XF 3 "register_operand" "")))]
19401 "TARGET_80387 && TARGET_CMOVE"
19402 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19404 (define_insn "*movxfcc_1"
19405 [(set (match_operand:XF 0 "register_operand" "=f,f")
19406 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19407 [(reg FLAGS_REG) (const_int 0)])
19408 (match_operand:XF 2 "register_operand" "f,0")
19409 (match_operand:XF 3 "register_operand" "0,f")))]
19410 "TARGET_80387 && TARGET_CMOVE"
19412 fcmov%F1\t{%2, %0|%0, %2}
19413 fcmov%f1\t{%3, %0|%0, %3}"
19414 [(set_attr "type" "fcmov")
19415 (set_attr "mode" "XF")])
19417 ;; These versions of the min/max patterns are intentionally ignorant of
19418 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19419 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19420 ;; are undefined in this condition, we're certain this is correct.
19422 (define_insn "sminsf3"
19423 [(set (match_operand:SF 0 "register_operand" "=x")
19424 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19425 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19427 "minss\t{%2, %0|%0, %2}"
19428 [(set_attr "type" "sseadd")
19429 (set_attr "mode" "SF")])
19431 (define_insn "smaxsf3"
19432 [(set (match_operand:SF 0 "register_operand" "=x")
19433 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19434 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19436 "maxss\t{%2, %0|%0, %2}"
19437 [(set_attr "type" "sseadd")
19438 (set_attr "mode" "SF")])
19440 (define_insn "smindf3"
19441 [(set (match_operand:DF 0 "register_operand" "=x")
19442 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19443 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19444 "TARGET_SSE2 && TARGET_SSE_MATH"
19445 "minsd\t{%2, %0|%0, %2}"
19446 [(set_attr "type" "sseadd")
19447 (set_attr "mode" "DF")])
19449 (define_insn "smaxdf3"
19450 [(set (match_operand:DF 0 "register_operand" "=x")
19451 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19452 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19453 "TARGET_SSE2 && TARGET_SSE_MATH"
19454 "maxsd\t{%2, %0|%0, %2}"
19455 [(set_attr "type" "sseadd")
19456 (set_attr "mode" "DF")])
19458 ;; These versions of the min/max patterns implement exactly the operations
19459 ;; min = (op1 < op2 ? op1 : op2)
19460 ;; max = (!(op1 < op2) ? op1 : op2)
19461 ;; Their operands are not commutative, and thus they may be used in the
19462 ;; presence of -0.0 and NaN.
19464 (define_insn "*ieee_sminsf3"
19465 [(set (match_operand:SF 0 "register_operand" "=x")
19466 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19467 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19470 "minss\t{%2, %0|%0, %2}"
19471 [(set_attr "type" "sseadd")
19472 (set_attr "mode" "SF")])
19474 (define_insn "*ieee_smaxsf3"
19475 [(set (match_operand:SF 0 "register_operand" "=x")
19476 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19477 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19480 "maxss\t{%2, %0|%0, %2}"
19481 [(set_attr "type" "sseadd")
19482 (set_attr "mode" "SF")])
19484 (define_insn "*ieee_smindf3"
19485 [(set (match_operand:DF 0 "register_operand" "=x")
19486 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19487 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19489 "TARGET_SSE2 && TARGET_SSE_MATH"
19490 "minsd\t{%2, %0|%0, %2}"
19491 [(set_attr "type" "sseadd")
19492 (set_attr "mode" "DF")])
19494 (define_insn "*ieee_smaxdf3"
19495 [(set (match_operand:DF 0 "register_operand" "=x")
19496 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19497 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19499 "TARGET_SSE2 && TARGET_SSE_MATH"
19500 "maxsd\t{%2, %0|%0, %2}"
19501 [(set_attr "type" "sseadd")
19502 (set_attr "mode" "DF")])
19504 ;; Make two stack loads independent:
19506 ;; fld %st(0) -> fld bb
19507 ;; fmul bb fmul %st(1), %st
19509 ;; Actually we only match the last two instructions for simplicity.
19511 [(set (match_operand 0 "fp_register_operand" "")
19512 (match_operand 1 "fp_register_operand" ""))
19514 (match_operator 2 "binary_fp_operator"
19516 (match_operand 3 "memory_operand" "")]))]
19517 "REGNO (operands[0]) != REGNO (operands[1])"
19518 [(set (match_dup 0) (match_dup 3))
19519 (set (match_dup 0) (match_dup 4))]
19521 ;; The % modifier is not operational anymore in peephole2's, so we have to
19522 ;; swap the operands manually in the case of addition and multiplication.
19523 "if (COMMUTATIVE_ARITH_P (operands[2]))
19524 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19525 operands[0], operands[1]);
19527 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19528 operands[1], operands[0]);")
19530 ;; Conditional addition patterns
19531 (define_expand "addqicc"
19532 [(match_operand:QI 0 "register_operand" "")
19533 (match_operand 1 "comparison_operator" "")
19534 (match_operand:QI 2 "register_operand" "")
19535 (match_operand:QI 3 "const_int_operand" "")]
19537 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19539 (define_expand "addhicc"
19540 [(match_operand:HI 0 "register_operand" "")
19541 (match_operand 1 "comparison_operator" "")
19542 (match_operand:HI 2 "register_operand" "")
19543 (match_operand:HI 3 "const_int_operand" "")]
19545 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19547 (define_expand "addsicc"
19548 [(match_operand:SI 0 "register_operand" "")
19549 (match_operand 1 "comparison_operator" "")
19550 (match_operand:SI 2 "register_operand" "")
19551 (match_operand:SI 3 "const_int_operand" "")]
19553 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19555 (define_expand "adddicc"
19556 [(match_operand:DI 0 "register_operand" "")
19557 (match_operand 1 "comparison_operator" "")
19558 (match_operand:DI 2 "register_operand" "")
19559 (match_operand:DI 3 "const_int_operand" "")]
19561 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19564 ;; Misc patterns (?)
19566 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19567 ;; Otherwise there will be nothing to keep
19569 ;; [(set (reg ebp) (reg esp))]
19570 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19571 ;; (clobber (eflags)]
19572 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19574 ;; in proper program order.
19575 (define_insn "pro_epilogue_adjust_stack_1"
19576 [(set (match_operand:SI 0 "register_operand" "=r,r")
19577 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19578 (match_operand:SI 2 "immediate_operand" "i,i")))
19579 (clobber (reg:CC FLAGS_REG))
19580 (clobber (mem:BLK (scratch)))]
19583 switch (get_attr_type (insn))
19586 return "mov{l}\t{%1, %0|%0, %1}";
19589 if (CONST_INT_P (operands[2])
19590 && (INTVAL (operands[2]) == 128
19591 || (INTVAL (operands[2]) < 0
19592 && INTVAL (operands[2]) != -128)))
19594 operands[2] = GEN_INT (-INTVAL (operands[2]));
19595 return "sub{l}\t{%2, %0|%0, %2}";
19597 return "add{l}\t{%2, %0|%0, %2}";
19600 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19601 return "lea{l}\t{%a2, %0|%0, %a2}";
19604 gcc_unreachable ();
19607 [(set (attr "type")
19608 (cond [(eq_attr "alternative" "0")
19609 (const_string "alu")
19610 (match_operand:SI 2 "const0_operand" "")
19611 (const_string "imov")
19613 (const_string "lea")))
19614 (set_attr "mode" "SI")])
19616 (define_insn "pro_epilogue_adjust_stack_rex64"
19617 [(set (match_operand:DI 0 "register_operand" "=r,r")
19618 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19619 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19620 (clobber (reg:CC FLAGS_REG))
19621 (clobber (mem:BLK (scratch)))]
19624 switch (get_attr_type (insn))
19627 return "mov{q}\t{%1, %0|%0, %1}";
19630 if (CONST_INT_P (operands[2])
19631 /* Avoid overflows. */
19632 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19633 && (INTVAL (operands[2]) == 128
19634 || (INTVAL (operands[2]) < 0
19635 && INTVAL (operands[2]) != -128)))
19637 operands[2] = GEN_INT (-INTVAL (operands[2]));
19638 return "sub{q}\t{%2, %0|%0, %2}";
19640 return "add{q}\t{%2, %0|%0, %2}";
19643 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19644 return "lea{q}\t{%a2, %0|%0, %a2}";
19647 gcc_unreachable ();
19650 [(set (attr "type")
19651 (cond [(eq_attr "alternative" "0")
19652 (const_string "alu")
19653 (match_operand:DI 2 "const0_operand" "")
19654 (const_string "imov")
19656 (const_string "lea")))
19657 (set_attr "mode" "DI")])
19659 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19660 [(set (match_operand:DI 0 "register_operand" "=r,r")
19661 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19662 (match_operand:DI 3 "immediate_operand" "i,i")))
19663 (use (match_operand:DI 2 "register_operand" "r,r"))
19664 (clobber (reg:CC FLAGS_REG))
19665 (clobber (mem:BLK (scratch)))]
19668 switch (get_attr_type (insn))
19671 return "add{q}\t{%2, %0|%0, %2}";
19674 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19675 return "lea{q}\t{%a2, %0|%0, %a2}";
19678 gcc_unreachable ();
19681 [(set_attr "type" "alu,lea")
19682 (set_attr "mode" "DI")])
19684 (define_expand "allocate_stack_worker"
19685 [(match_operand:SI 0 "register_operand" "")]
19686 "TARGET_STACK_PROBE"
19688 if (reload_completed)
19691 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19693 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19698 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19700 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19705 (define_insn "allocate_stack_worker_1"
19706 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19707 UNSPECV_STACK_PROBE)
19708 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19709 (clobber (match_scratch:SI 1 "=0"))
19710 (clobber (reg:CC FLAGS_REG))]
19711 "!TARGET_64BIT && TARGET_STACK_PROBE"
19713 [(set_attr "type" "multi")
19714 (set_attr "length" "5")])
19716 (define_expand "allocate_stack_worker_postreload"
19717 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19718 UNSPECV_STACK_PROBE)
19719 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19720 (clobber (match_dup 0))
19721 (clobber (reg:CC FLAGS_REG))])]
19725 (define_insn "allocate_stack_worker_rex64"
19726 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19727 UNSPECV_STACK_PROBE)
19728 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19729 (clobber (match_scratch:DI 1 "=0"))
19730 (clobber (reg:CC FLAGS_REG))]
19731 "TARGET_64BIT && TARGET_STACK_PROBE"
19733 [(set_attr "type" "multi")
19734 (set_attr "length" "5")])
19736 (define_expand "allocate_stack_worker_rex64_postreload"
19737 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19738 UNSPECV_STACK_PROBE)
19739 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19740 (clobber (match_dup 0))
19741 (clobber (reg:CC FLAGS_REG))])]
19745 (define_expand "allocate_stack"
19746 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19747 (minus:SI (reg:SI SP_REG)
19748 (match_operand:SI 1 "general_operand" "")))
19749 (clobber (reg:CC FLAGS_REG))])
19750 (parallel [(set (reg:SI SP_REG)
19751 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19752 (clobber (reg:CC FLAGS_REG))])]
19753 "TARGET_STACK_PROBE"
19755 #ifdef CHECK_STACK_LIMIT
19756 if (CONST_INT_P (operands[1])
19757 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19758 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19762 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19765 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19769 (define_expand "builtin_setjmp_receiver"
19770 [(label_ref (match_operand 0 "" ""))]
19771 "!TARGET_64BIT && flag_pic"
19776 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19777 rtx label_rtx = gen_label_rtx ();
19778 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19779 xops[0] = xops[1] = picreg;
19780 xops[2] = gen_rtx_CONST (SImode,
19781 gen_rtx_MINUS (SImode,
19782 gen_rtx_LABEL_REF (SImode, label_rtx),
19783 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19784 ix86_expand_binary_operator (MINUS, SImode, xops);
19787 emit_insn (gen_set_got (pic_offset_table_rtx));
19791 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19794 [(set (match_operand 0 "register_operand" "")
19795 (match_operator 3 "promotable_binary_operator"
19796 [(match_operand 1 "register_operand" "")
19797 (match_operand 2 "aligned_operand" "")]))
19798 (clobber (reg:CC FLAGS_REG))]
19799 "! TARGET_PARTIAL_REG_STALL && reload_completed
19800 && ((GET_MODE (operands[0]) == HImode
19801 && ((!optimize_size && !TARGET_FAST_PREFIX)
19802 /* ??? next two lines just !satisfies_constraint_K (...) */
19803 || !CONST_INT_P (operands[2])
19804 || satisfies_constraint_K (operands[2])))
19805 || (GET_MODE (operands[0]) == QImode
19806 && (TARGET_PROMOTE_QImode || optimize_size)))"
19807 [(parallel [(set (match_dup 0)
19808 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19809 (clobber (reg:CC FLAGS_REG))])]
19810 "operands[0] = gen_lowpart (SImode, operands[0]);
19811 operands[1] = gen_lowpart (SImode, operands[1]);
19812 if (GET_CODE (operands[3]) != ASHIFT)
19813 operands[2] = gen_lowpart (SImode, operands[2]);
19814 PUT_MODE (operands[3], SImode);")
19816 ; Promote the QImode tests, as i386 has encoding of the AND
19817 ; instruction with 32-bit sign-extended immediate and thus the
19818 ; instruction size is unchanged, except in the %eax case for
19819 ; which it is increased by one byte, hence the ! optimize_size.
19821 [(set (match_operand 0 "flags_reg_operand" "")
19822 (match_operator 2 "compare_operator"
19823 [(and (match_operand 3 "aligned_operand" "")
19824 (match_operand 4 "const_int_operand" ""))
19826 (set (match_operand 1 "register_operand" "")
19827 (and (match_dup 3) (match_dup 4)))]
19828 "! TARGET_PARTIAL_REG_STALL && reload_completed
19829 /* Ensure that the operand will remain sign-extended immediate. */
19830 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19832 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19833 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19834 [(parallel [(set (match_dup 0)
19835 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19838 (and:SI (match_dup 3) (match_dup 4)))])]
19841 = gen_int_mode (INTVAL (operands[4])
19842 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19843 operands[1] = gen_lowpart (SImode, operands[1]);
19844 operands[3] = gen_lowpart (SImode, operands[3]);
19847 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19848 ; the TEST instruction with 32-bit sign-extended immediate and thus
19849 ; the instruction size would at least double, which is not what we
19850 ; want even with ! optimize_size.
19852 [(set (match_operand 0 "flags_reg_operand" "")
19853 (match_operator 1 "compare_operator"
19854 [(and (match_operand:HI 2 "aligned_operand" "")
19855 (match_operand:HI 3 "const_int_operand" ""))
19857 "! TARGET_PARTIAL_REG_STALL && reload_completed
19858 /* Ensure that the operand will remain sign-extended immediate. */
19859 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19860 && ! TARGET_FAST_PREFIX
19861 && ! optimize_size"
19862 [(set (match_dup 0)
19863 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19867 = gen_int_mode (INTVAL (operands[3])
19868 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19869 operands[2] = gen_lowpart (SImode, operands[2]);
19873 [(set (match_operand 0 "register_operand" "")
19874 (neg (match_operand 1 "register_operand" "")))
19875 (clobber (reg:CC FLAGS_REG))]
19876 "! TARGET_PARTIAL_REG_STALL && reload_completed
19877 && (GET_MODE (operands[0]) == HImode
19878 || (GET_MODE (operands[0]) == QImode
19879 && (TARGET_PROMOTE_QImode || optimize_size)))"
19880 [(parallel [(set (match_dup 0)
19881 (neg:SI (match_dup 1)))
19882 (clobber (reg:CC FLAGS_REG))])]
19883 "operands[0] = gen_lowpart (SImode, operands[0]);
19884 operands[1] = gen_lowpart (SImode, operands[1]);")
19887 [(set (match_operand 0 "register_operand" "")
19888 (not (match_operand 1 "register_operand" "")))]
19889 "! TARGET_PARTIAL_REG_STALL && reload_completed
19890 && (GET_MODE (operands[0]) == HImode
19891 || (GET_MODE (operands[0]) == QImode
19892 && (TARGET_PROMOTE_QImode || optimize_size)))"
19893 [(set (match_dup 0)
19894 (not:SI (match_dup 1)))]
19895 "operands[0] = gen_lowpart (SImode, operands[0]);
19896 operands[1] = gen_lowpart (SImode, operands[1]);")
19899 [(set (match_operand 0 "register_operand" "")
19900 (if_then_else (match_operator 1 "comparison_operator"
19901 [(reg FLAGS_REG) (const_int 0)])
19902 (match_operand 2 "register_operand" "")
19903 (match_operand 3 "register_operand" "")))]
19904 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19905 && (GET_MODE (operands[0]) == HImode
19906 || (GET_MODE (operands[0]) == QImode
19907 && (TARGET_PROMOTE_QImode || optimize_size)))"
19908 [(set (match_dup 0)
19909 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19910 "operands[0] = gen_lowpart (SImode, operands[0]);
19911 operands[2] = gen_lowpart (SImode, operands[2]);
19912 operands[3] = gen_lowpart (SImode, operands[3]);")
19915 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19916 ;; transform a complex memory operation into two memory to register operations.
19918 ;; Don't push memory operands
19920 [(set (match_operand:SI 0 "push_operand" "")
19921 (match_operand:SI 1 "memory_operand" ""))
19922 (match_scratch:SI 2 "r")]
19923 "!optimize_size && !TARGET_PUSH_MEMORY
19924 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19925 [(set (match_dup 2) (match_dup 1))
19926 (set (match_dup 0) (match_dup 2))]
19930 [(set (match_operand:DI 0 "push_operand" "")
19931 (match_operand:DI 1 "memory_operand" ""))
19932 (match_scratch:DI 2 "r")]
19933 "!optimize_size && !TARGET_PUSH_MEMORY
19934 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19935 [(set (match_dup 2) (match_dup 1))
19936 (set (match_dup 0) (match_dup 2))]
19939 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19942 [(set (match_operand:SF 0 "push_operand" "")
19943 (match_operand:SF 1 "memory_operand" ""))
19944 (match_scratch:SF 2 "r")]
19945 "!optimize_size && !TARGET_PUSH_MEMORY
19946 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19947 [(set (match_dup 2) (match_dup 1))
19948 (set (match_dup 0) (match_dup 2))]
19952 [(set (match_operand:HI 0 "push_operand" "")
19953 (match_operand:HI 1 "memory_operand" ""))
19954 (match_scratch:HI 2 "r")]
19955 "!optimize_size && !TARGET_PUSH_MEMORY
19956 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19957 [(set (match_dup 2) (match_dup 1))
19958 (set (match_dup 0) (match_dup 2))]
19962 [(set (match_operand:QI 0 "push_operand" "")
19963 (match_operand:QI 1 "memory_operand" ""))
19964 (match_scratch:QI 2 "q")]
19965 "!optimize_size && !TARGET_PUSH_MEMORY
19966 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19967 [(set (match_dup 2) (match_dup 1))
19968 (set (match_dup 0) (match_dup 2))]
19971 ;; Don't move an immediate directly to memory when the instruction
19974 [(match_scratch:SI 1 "r")
19975 (set (match_operand:SI 0 "memory_operand" "")
19978 && ! TARGET_USE_MOV0
19979 && TARGET_SPLIT_LONG_MOVES
19980 && get_attr_length (insn) >= ix86_cost->large_insn
19981 && peep2_regno_dead_p (0, FLAGS_REG)"
19982 [(parallel [(set (match_dup 1) (const_int 0))
19983 (clobber (reg:CC FLAGS_REG))])
19984 (set (match_dup 0) (match_dup 1))]
19988 [(match_scratch:HI 1 "r")
19989 (set (match_operand:HI 0 "memory_operand" "")
19992 && ! TARGET_USE_MOV0
19993 && TARGET_SPLIT_LONG_MOVES
19994 && get_attr_length (insn) >= ix86_cost->large_insn
19995 && peep2_regno_dead_p (0, FLAGS_REG)"
19996 [(parallel [(set (match_dup 2) (const_int 0))
19997 (clobber (reg:CC FLAGS_REG))])
19998 (set (match_dup 0) (match_dup 1))]
19999 "operands[2] = gen_lowpart (SImode, operands[1]);")
20002 [(match_scratch:QI 1 "q")
20003 (set (match_operand:QI 0 "memory_operand" "")
20006 && ! TARGET_USE_MOV0
20007 && TARGET_SPLIT_LONG_MOVES
20008 && get_attr_length (insn) >= ix86_cost->large_insn
20009 && peep2_regno_dead_p (0, FLAGS_REG)"
20010 [(parallel [(set (match_dup 2) (const_int 0))
20011 (clobber (reg:CC FLAGS_REG))])
20012 (set (match_dup 0) (match_dup 1))]
20013 "operands[2] = gen_lowpart (SImode, operands[1]);")
20016 [(match_scratch:SI 2 "r")
20017 (set (match_operand:SI 0 "memory_operand" "")
20018 (match_operand:SI 1 "immediate_operand" ""))]
20020 && get_attr_length (insn) >= ix86_cost->large_insn
20021 && TARGET_SPLIT_LONG_MOVES"
20022 [(set (match_dup 2) (match_dup 1))
20023 (set (match_dup 0) (match_dup 2))]
20027 [(match_scratch:HI 2 "r")
20028 (set (match_operand:HI 0 "memory_operand" "")
20029 (match_operand:HI 1 "immediate_operand" ""))]
20030 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20031 && TARGET_SPLIT_LONG_MOVES"
20032 [(set (match_dup 2) (match_dup 1))
20033 (set (match_dup 0) (match_dup 2))]
20037 [(match_scratch:QI 2 "q")
20038 (set (match_operand:QI 0 "memory_operand" "")
20039 (match_operand:QI 1 "immediate_operand" ""))]
20040 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
20041 && TARGET_SPLIT_LONG_MOVES"
20042 [(set (match_dup 2) (match_dup 1))
20043 (set (match_dup 0) (match_dup 2))]
20046 ;; Don't compare memory with zero, load and use a test instead.
20048 [(set (match_operand 0 "flags_reg_operand" "")
20049 (match_operator 1 "compare_operator"
20050 [(match_operand:SI 2 "memory_operand" "")
20052 (match_scratch:SI 3 "r")]
20053 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
20054 [(set (match_dup 3) (match_dup 2))
20055 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20058 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20059 ;; Don't split NOTs with a displacement operand, because resulting XOR
20060 ;; will not be pairable anyway.
20062 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20063 ;; represented using a modRM byte. The XOR replacement is long decoded,
20064 ;; so this split helps here as well.
20066 ;; Note: Can't do this as a regular split because we can't get proper
20067 ;; lifetime information then.
20070 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20071 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20073 && peep2_regno_dead_p (0, FLAGS_REG)
20074 && ((TARGET_PENTIUM
20075 && (!MEM_P (operands[0])
20076 || !memory_displacement_operand (operands[0], SImode)))
20077 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
20078 [(parallel [(set (match_dup 0)
20079 (xor:SI (match_dup 1) (const_int -1)))
20080 (clobber (reg:CC FLAGS_REG))])]
20084 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20085 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20087 && peep2_regno_dead_p (0, FLAGS_REG)
20088 && ((TARGET_PENTIUM
20089 && (!MEM_P (operands[0])
20090 || !memory_displacement_operand (operands[0], HImode)))
20091 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
20092 [(parallel [(set (match_dup 0)
20093 (xor:HI (match_dup 1) (const_int -1)))
20094 (clobber (reg:CC FLAGS_REG))])]
20098 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20099 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20101 && peep2_regno_dead_p (0, FLAGS_REG)
20102 && ((TARGET_PENTIUM
20103 && (!MEM_P (operands[0])
20104 || !memory_displacement_operand (operands[0], QImode)))
20105 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
20106 [(parallel [(set (match_dup 0)
20107 (xor:QI (match_dup 1) (const_int -1)))
20108 (clobber (reg:CC FLAGS_REG))])]
20111 ;; Non pairable "test imm, reg" instructions can be translated to
20112 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20113 ;; byte opcode instead of two, have a short form for byte operands),
20114 ;; so do it for other CPUs as well. Given that the value was dead,
20115 ;; this should not create any new dependencies. Pass on the sub-word
20116 ;; versions if we're concerned about partial register stalls.
20119 [(set (match_operand 0 "flags_reg_operand" "")
20120 (match_operator 1 "compare_operator"
20121 [(and:SI (match_operand:SI 2 "register_operand" "")
20122 (match_operand:SI 3 "immediate_operand" ""))
20124 "ix86_match_ccmode (insn, CCNOmode)
20125 && (true_regnum (operands[2]) != 0
20126 || satisfies_constraint_K (operands[3]))
20127 && peep2_reg_dead_p (1, operands[2])"
20129 [(set (match_dup 0)
20130 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20133 (and:SI (match_dup 2) (match_dup 3)))])]
20136 ;; We don't need to handle HImode case, because it will be promoted to SImode
20137 ;; on ! TARGET_PARTIAL_REG_STALL
20140 [(set (match_operand 0 "flags_reg_operand" "")
20141 (match_operator 1 "compare_operator"
20142 [(and:QI (match_operand:QI 2 "register_operand" "")
20143 (match_operand:QI 3 "immediate_operand" ""))
20145 "! TARGET_PARTIAL_REG_STALL
20146 && ix86_match_ccmode (insn, CCNOmode)
20147 && true_regnum (operands[2]) != 0
20148 && peep2_reg_dead_p (1, operands[2])"
20150 [(set (match_dup 0)
20151 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20154 (and:QI (match_dup 2) (match_dup 3)))])]
20158 [(set (match_operand 0 "flags_reg_operand" "")
20159 (match_operator 1 "compare_operator"
20162 (match_operand 2 "ext_register_operand" "")
20165 (match_operand 3 "const_int_operand" ""))
20167 "! TARGET_PARTIAL_REG_STALL
20168 && ix86_match_ccmode (insn, CCNOmode)
20169 && true_regnum (operands[2]) != 0
20170 && peep2_reg_dead_p (1, operands[2])"
20171 [(parallel [(set (match_dup 0)
20180 (set (zero_extract:SI (match_dup 2)
20191 ;; Don't do logical operations with memory inputs.
20193 [(match_scratch:SI 2 "r")
20194 (parallel [(set (match_operand:SI 0 "register_operand" "")
20195 (match_operator:SI 3 "arith_or_logical_operator"
20197 (match_operand:SI 1 "memory_operand" "")]))
20198 (clobber (reg:CC FLAGS_REG))])]
20199 "! optimize_size && ! TARGET_READ_MODIFY"
20200 [(set (match_dup 2) (match_dup 1))
20201 (parallel [(set (match_dup 0)
20202 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20203 (clobber (reg:CC FLAGS_REG))])]
20207 [(match_scratch:SI 2 "r")
20208 (parallel [(set (match_operand:SI 0 "register_operand" "")
20209 (match_operator:SI 3 "arith_or_logical_operator"
20210 [(match_operand:SI 1 "memory_operand" "")
20212 (clobber (reg:CC FLAGS_REG))])]
20213 "! optimize_size && ! TARGET_READ_MODIFY"
20214 [(set (match_dup 2) (match_dup 1))
20215 (parallel [(set (match_dup 0)
20216 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20217 (clobber (reg:CC FLAGS_REG))])]
20220 ; Don't do logical operations with memory outputs
20222 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20223 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20224 ; the same decoder scheduling characteristics as the original.
20227 [(match_scratch:SI 2 "r")
20228 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20229 (match_operator:SI 3 "arith_or_logical_operator"
20231 (match_operand:SI 1 "nonmemory_operand" "")]))
20232 (clobber (reg:CC FLAGS_REG))])]
20233 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20234 [(set (match_dup 2) (match_dup 0))
20235 (parallel [(set (match_dup 2)
20236 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20237 (clobber (reg:CC FLAGS_REG))])
20238 (set (match_dup 0) (match_dup 2))]
20242 [(match_scratch:SI 2 "r")
20243 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20244 (match_operator:SI 3 "arith_or_logical_operator"
20245 [(match_operand:SI 1 "nonmemory_operand" "")
20247 (clobber (reg:CC FLAGS_REG))])]
20248 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20249 [(set (match_dup 2) (match_dup 0))
20250 (parallel [(set (match_dup 2)
20251 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20252 (clobber (reg:CC FLAGS_REG))])
20253 (set (match_dup 0) (match_dup 2))]
20256 ;; Attempt to always use XOR for zeroing registers.
20258 [(set (match_operand 0 "register_operand" "")
20259 (match_operand 1 "const0_operand" ""))]
20260 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20261 && (! TARGET_USE_MOV0 || optimize_size)
20262 && GENERAL_REG_P (operands[0])
20263 && peep2_regno_dead_p (0, FLAGS_REG)"
20264 [(parallel [(set (match_dup 0) (const_int 0))
20265 (clobber (reg:CC FLAGS_REG))])]
20267 operands[0] = gen_lowpart (word_mode, operands[0]);
20271 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20273 "(GET_MODE (operands[0]) == QImode
20274 || GET_MODE (operands[0]) == HImode)
20275 && (! TARGET_USE_MOV0 || optimize_size)
20276 && peep2_regno_dead_p (0, FLAGS_REG)"
20277 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20278 (clobber (reg:CC FLAGS_REG))])])
20280 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20282 [(set (match_operand 0 "register_operand" "")
20284 "(GET_MODE (operands[0]) == HImode
20285 || GET_MODE (operands[0]) == SImode
20286 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20287 && (optimize_size || TARGET_PENTIUM)
20288 && peep2_regno_dead_p (0, FLAGS_REG)"
20289 [(parallel [(set (match_dup 0) (const_int -1))
20290 (clobber (reg:CC FLAGS_REG))])]
20291 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20294 ;; Attempt to convert simple leas to adds. These can be created by
20297 [(set (match_operand:SI 0 "register_operand" "")
20298 (plus:SI (match_dup 0)
20299 (match_operand:SI 1 "nonmemory_operand" "")))]
20300 "peep2_regno_dead_p (0, FLAGS_REG)"
20301 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20302 (clobber (reg:CC FLAGS_REG))])]
20306 [(set (match_operand:SI 0 "register_operand" "")
20307 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20308 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20309 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20310 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20311 (clobber (reg:CC FLAGS_REG))])]
20312 "operands[2] = gen_lowpart (SImode, operands[2]);")
20315 [(set (match_operand:DI 0 "register_operand" "")
20316 (plus:DI (match_dup 0)
20317 (match_operand:DI 1 "x86_64_general_operand" "")))]
20318 "peep2_regno_dead_p (0, FLAGS_REG)"
20319 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20320 (clobber (reg:CC FLAGS_REG))])]
20324 [(set (match_operand:SI 0 "register_operand" "")
20325 (mult:SI (match_dup 0)
20326 (match_operand:SI 1 "const_int_operand" "")))]
20327 "exact_log2 (INTVAL (operands[1])) >= 0
20328 && peep2_regno_dead_p (0, FLAGS_REG)"
20329 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20330 (clobber (reg:CC FLAGS_REG))])]
20331 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20334 [(set (match_operand:DI 0 "register_operand" "")
20335 (mult:DI (match_dup 0)
20336 (match_operand:DI 1 "const_int_operand" "")))]
20337 "exact_log2 (INTVAL (operands[1])) >= 0
20338 && peep2_regno_dead_p (0, FLAGS_REG)"
20339 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20340 (clobber (reg:CC FLAGS_REG))])]
20341 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20344 [(set (match_operand:SI 0 "register_operand" "")
20345 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20346 (match_operand:DI 2 "const_int_operand" "")) 0))]
20347 "exact_log2 (INTVAL (operands[2])) >= 0
20348 && REGNO (operands[0]) == REGNO (operands[1])
20349 && peep2_regno_dead_p (0, FLAGS_REG)"
20350 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20351 (clobber (reg:CC FLAGS_REG))])]
20352 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20354 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20355 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20356 ;; many CPUs it is also faster, since special hardware to avoid esp
20357 ;; dependencies is present.
20359 ;; While some of these conversions may be done using splitters, we use peepholes
20360 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20362 ;; Convert prologue esp subtractions to push.
20363 ;; We need register to push. In order to keep verify_flow_info happy we have
20365 ;; - use scratch and clobber it in order to avoid dependencies
20366 ;; - use already live register
20367 ;; We can't use the second way right now, since there is no reliable way how to
20368 ;; verify that given register is live. First choice will also most likely in
20369 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20370 ;; call clobbered registers are dead. We may want to use base pointer as an
20371 ;; alternative when no register is available later.
20374 [(match_scratch:SI 0 "r")
20375 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20376 (clobber (reg:CC FLAGS_REG))
20377 (clobber (mem:BLK (scratch)))])]
20378 "optimize_size || !TARGET_SUB_ESP_4"
20379 [(clobber (match_dup 0))
20380 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20381 (clobber (mem:BLK (scratch)))])])
20384 [(match_scratch:SI 0 "r")
20385 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20386 (clobber (reg:CC FLAGS_REG))
20387 (clobber (mem:BLK (scratch)))])]
20388 "optimize_size || !TARGET_SUB_ESP_8"
20389 [(clobber (match_dup 0))
20390 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20391 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20392 (clobber (mem:BLK (scratch)))])])
20394 ;; Convert esp subtractions to push.
20396 [(match_scratch:SI 0 "r")
20397 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20398 (clobber (reg:CC FLAGS_REG))])]
20399 "optimize_size || !TARGET_SUB_ESP_4"
20400 [(clobber (match_dup 0))
20401 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20404 [(match_scratch:SI 0 "r")
20405 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20406 (clobber (reg:CC FLAGS_REG))])]
20407 "optimize_size || !TARGET_SUB_ESP_8"
20408 [(clobber (match_dup 0))
20409 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20410 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20412 ;; Convert epilogue deallocator to pop.
20414 [(match_scratch:SI 0 "r")
20415 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20416 (clobber (reg:CC FLAGS_REG))
20417 (clobber (mem:BLK (scratch)))])]
20418 "optimize_size || !TARGET_ADD_ESP_4"
20419 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20420 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20421 (clobber (mem:BLK (scratch)))])]
20424 ;; Two pops case is tricky, since pop causes dependency on destination register.
20425 ;; We use two registers if available.
20427 [(match_scratch:SI 0 "r")
20428 (match_scratch:SI 1 "r")
20429 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20430 (clobber (reg:CC FLAGS_REG))
20431 (clobber (mem:BLK (scratch)))])]
20432 "optimize_size || !TARGET_ADD_ESP_8"
20433 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20434 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20435 (clobber (mem:BLK (scratch)))])
20436 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20437 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20441 [(match_scratch:SI 0 "r")
20442 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20443 (clobber (reg:CC FLAGS_REG))
20444 (clobber (mem:BLK (scratch)))])]
20446 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20447 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20448 (clobber (mem:BLK (scratch)))])
20449 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20450 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20453 ;; Convert esp additions to pop.
20455 [(match_scratch:SI 0 "r")
20456 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20457 (clobber (reg:CC FLAGS_REG))])]
20459 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20460 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20463 ;; Two pops case is tricky, since pop causes dependency on destination register.
20464 ;; We use two registers if available.
20466 [(match_scratch:SI 0 "r")
20467 (match_scratch:SI 1 "r")
20468 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20469 (clobber (reg:CC FLAGS_REG))])]
20471 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20472 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20473 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20474 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20478 [(match_scratch:SI 0 "r")
20479 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20480 (clobber (reg:CC FLAGS_REG))])]
20482 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20483 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20484 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20485 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20488 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20489 ;; required and register dies. Similarly for 128 to plus -128.
20491 [(set (match_operand 0 "flags_reg_operand" "")
20492 (match_operator 1 "compare_operator"
20493 [(match_operand 2 "register_operand" "")
20494 (match_operand 3 "const_int_operand" "")]))]
20495 "(INTVAL (operands[3]) == -1
20496 || INTVAL (operands[3]) == 1
20497 || INTVAL (operands[3]) == 128)
20498 && ix86_match_ccmode (insn, CCGCmode)
20499 && peep2_reg_dead_p (1, operands[2])"
20500 [(parallel [(set (match_dup 0)
20501 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20502 (clobber (match_dup 2))])]
20506 [(match_scratch:DI 0 "r")
20507 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20508 (clobber (reg:CC FLAGS_REG))
20509 (clobber (mem:BLK (scratch)))])]
20510 "optimize_size || !TARGET_SUB_ESP_4"
20511 [(clobber (match_dup 0))
20512 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20513 (clobber (mem:BLK (scratch)))])])
20516 [(match_scratch:DI 0 "r")
20517 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20518 (clobber (reg:CC FLAGS_REG))
20519 (clobber (mem:BLK (scratch)))])]
20520 "optimize_size || !TARGET_SUB_ESP_8"
20521 [(clobber (match_dup 0))
20522 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20523 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20524 (clobber (mem:BLK (scratch)))])])
20526 ;; Convert esp subtractions to push.
20528 [(match_scratch:DI 0 "r")
20529 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20530 (clobber (reg:CC FLAGS_REG))])]
20531 "optimize_size || !TARGET_SUB_ESP_4"
20532 [(clobber (match_dup 0))
20533 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20536 [(match_scratch:DI 0 "r")
20537 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20538 (clobber (reg:CC FLAGS_REG))])]
20539 "optimize_size || !TARGET_SUB_ESP_8"
20540 [(clobber (match_dup 0))
20541 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20542 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20544 ;; Convert epilogue deallocator to pop.
20546 [(match_scratch:DI 0 "r")
20547 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20548 (clobber (reg:CC FLAGS_REG))
20549 (clobber (mem:BLK (scratch)))])]
20550 "optimize_size || !TARGET_ADD_ESP_4"
20551 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20552 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20553 (clobber (mem:BLK (scratch)))])]
20556 ;; Two pops case is tricky, since pop causes dependency on destination register.
20557 ;; We use two registers if available.
20559 [(match_scratch:DI 0 "r")
20560 (match_scratch:DI 1 "r")
20561 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20562 (clobber (reg:CC FLAGS_REG))
20563 (clobber (mem:BLK (scratch)))])]
20564 "optimize_size || !TARGET_ADD_ESP_8"
20565 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20566 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20567 (clobber (mem:BLK (scratch)))])
20568 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20569 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20573 [(match_scratch:DI 0 "r")
20574 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20575 (clobber (reg:CC FLAGS_REG))
20576 (clobber (mem:BLK (scratch)))])]
20578 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20579 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20580 (clobber (mem:BLK (scratch)))])
20581 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20582 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20585 ;; Convert esp additions to pop.
20587 [(match_scratch:DI 0 "r")
20588 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20589 (clobber (reg:CC FLAGS_REG))])]
20591 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20592 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20595 ;; Two pops case is tricky, since pop causes dependency on destination register.
20596 ;; We use two registers if available.
20598 [(match_scratch:DI 0 "r")
20599 (match_scratch:DI 1 "r")
20600 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20601 (clobber (reg:CC FLAGS_REG))])]
20603 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20604 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20605 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20606 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20610 [(match_scratch:DI 0 "r")
20611 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20612 (clobber (reg:CC FLAGS_REG))])]
20614 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20615 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20616 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20617 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20620 ;; Convert imul by three, five and nine into lea
20623 [(set (match_operand:SI 0 "register_operand" "")
20624 (mult:SI (match_operand:SI 1 "register_operand" "")
20625 (match_operand:SI 2 "const_int_operand" "")))
20626 (clobber (reg:CC FLAGS_REG))])]
20627 "INTVAL (operands[2]) == 3
20628 || INTVAL (operands[2]) == 5
20629 || INTVAL (operands[2]) == 9"
20630 [(set (match_dup 0)
20631 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20633 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20637 [(set (match_operand:SI 0 "register_operand" "")
20638 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20639 (match_operand:SI 2 "const_int_operand" "")))
20640 (clobber (reg:CC FLAGS_REG))])]
20642 && (INTVAL (operands[2]) == 3
20643 || INTVAL (operands[2]) == 5
20644 || INTVAL (operands[2]) == 9)"
20645 [(set (match_dup 0) (match_dup 1))
20647 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20649 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20653 [(set (match_operand:DI 0 "register_operand" "")
20654 (mult:DI (match_operand:DI 1 "register_operand" "")
20655 (match_operand:DI 2 "const_int_operand" "")))
20656 (clobber (reg:CC FLAGS_REG))])]
20658 && (INTVAL (operands[2]) == 3
20659 || INTVAL (operands[2]) == 5
20660 || INTVAL (operands[2]) == 9)"
20661 [(set (match_dup 0)
20662 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20664 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20668 [(set (match_operand:DI 0 "register_operand" "")
20669 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20670 (match_operand:DI 2 "const_int_operand" "")))
20671 (clobber (reg:CC FLAGS_REG))])]
20674 && (INTVAL (operands[2]) == 3
20675 || INTVAL (operands[2]) == 5
20676 || INTVAL (operands[2]) == 9)"
20677 [(set (match_dup 0) (match_dup 1))
20679 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20681 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20683 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20684 ;; imul $32bit_imm, reg, reg is direct decoded.
20686 [(match_scratch:DI 3 "r")
20687 (parallel [(set (match_operand:DI 0 "register_operand" "")
20688 (mult:DI (match_operand:DI 1 "memory_operand" "")
20689 (match_operand:DI 2 "immediate_operand" "")))
20690 (clobber (reg:CC FLAGS_REG))])]
20691 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20692 && !satisfies_constraint_K (operands[2])"
20693 [(set (match_dup 3) (match_dup 1))
20694 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20695 (clobber (reg:CC FLAGS_REG))])]
20699 [(match_scratch:SI 3 "r")
20700 (parallel [(set (match_operand:SI 0 "register_operand" "")
20701 (mult:SI (match_operand:SI 1 "memory_operand" "")
20702 (match_operand:SI 2 "immediate_operand" "")))
20703 (clobber (reg:CC FLAGS_REG))])]
20704 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20705 && !satisfies_constraint_K (operands[2])"
20706 [(set (match_dup 3) (match_dup 1))
20707 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20708 (clobber (reg:CC FLAGS_REG))])]
20712 [(match_scratch:SI 3 "r")
20713 (parallel [(set (match_operand:DI 0 "register_operand" "")
20715 (mult:SI (match_operand:SI 1 "memory_operand" "")
20716 (match_operand:SI 2 "immediate_operand" ""))))
20717 (clobber (reg:CC FLAGS_REG))])]
20718 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20719 && !satisfies_constraint_K (operands[2])"
20720 [(set (match_dup 3) (match_dup 1))
20721 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20722 (clobber (reg:CC FLAGS_REG))])]
20725 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20726 ;; Convert it into imul reg, reg
20727 ;; It would be better to force assembler to encode instruction using long
20728 ;; immediate, but there is apparently no way to do so.
20730 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20731 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20732 (match_operand:DI 2 "const_int_operand" "")))
20733 (clobber (reg:CC FLAGS_REG))])
20734 (match_scratch:DI 3 "r")]
20735 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20736 && satisfies_constraint_K (operands[2])"
20737 [(set (match_dup 3) (match_dup 2))
20738 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20739 (clobber (reg:CC FLAGS_REG))])]
20741 if (!rtx_equal_p (operands[0], operands[1]))
20742 emit_move_insn (operands[0], operands[1]);
20746 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20747 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20748 (match_operand:SI 2 "const_int_operand" "")))
20749 (clobber (reg:CC FLAGS_REG))])
20750 (match_scratch:SI 3 "r")]
20751 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size
20752 && satisfies_constraint_K (operands[2])"
20753 [(set (match_dup 3) (match_dup 2))
20754 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20755 (clobber (reg:CC FLAGS_REG))])]
20757 if (!rtx_equal_p (operands[0], operands[1]))
20758 emit_move_insn (operands[0], operands[1]);
20762 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20763 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20764 (match_operand:HI 2 "immediate_operand" "")))
20765 (clobber (reg:CC FLAGS_REG))])
20766 (match_scratch:HI 3 "r")]
20767 "(TARGET_K8 || TARGET_GENERIC64 || TARGET_AMDFAM10) && !optimize_size"
20768 [(set (match_dup 3) (match_dup 2))
20769 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20770 (clobber (reg:CC FLAGS_REG))])]
20772 if (!rtx_equal_p (operands[0], operands[1]))
20773 emit_move_insn (operands[0], operands[1]);
20776 ;; After splitting up read-modify operations, array accesses with memory
20777 ;; operands might end up in form:
20779 ;; movl 4(%esp), %edx
20781 ;; instead of pre-splitting:
20783 ;; addl 4(%esp), %eax
20785 ;; movl 4(%esp), %edx
20786 ;; leal (%edx,%eax,4), %eax
20789 [(parallel [(set (match_operand 0 "register_operand" "")
20790 (ashift (match_operand 1 "register_operand" "")
20791 (match_operand 2 "const_int_operand" "")))
20792 (clobber (reg:CC FLAGS_REG))])
20793 (set (match_operand 3 "register_operand")
20794 (match_operand 4 "x86_64_general_operand" ""))
20795 (parallel [(set (match_operand 5 "register_operand" "")
20796 (plus (match_operand 6 "register_operand" "")
20797 (match_operand 7 "register_operand" "")))
20798 (clobber (reg:CC FLAGS_REG))])]
20799 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20800 /* Validate MODE for lea. */
20801 && ((!TARGET_PARTIAL_REG_STALL
20802 && (GET_MODE (operands[0]) == QImode
20803 || GET_MODE (operands[0]) == HImode))
20804 || GET_MODE (operands[0]) == SImode
20805 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20806 /* We reorder load and the shift. */
20807 && !rtx_equal_p (operands[1], operands[3])
20808 && !reg_overlap_mentioned_p (operands[0], operands[4])
20809 /* Last PLUS must consist of operand 0 and 3. */
20810 && !rtx_equal_p (operands[0], operands[3])
20811 && (rtx_equal_p (operands[3], operands[6])
20812 || rtx_equal_p (operands[3], operands[7]))
20813 && (rtx_equal_p (operands[0], operands[6])
20814 || rtx_equal_p (operands[0], operands[7]))
20815 /* The intermediate operand 0 must die or be same as output. */
20816 && (rtx_equal_p (operands[0], operands[5])
20817 || peep2_reg_dead_p (3, operands[0]))"
20818 [(set (match_dup 3) (match_dup 4))
20819 (set (match_dup 0) (match_dup 1))]
20821 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20822 int scale = 1 << INTVAL (operands[2]);
20823 rtx index = gen_lowpart (Pmode, operands[1]);
20824 rtx base = gen_lowpart (Pmode, operands[3]);
20825 rtx dest = gen_lowpart (mode, operands[5]);
20827 operands[1] = gen_rtx_PLUS (Pmode, base,
20828 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20830 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20831 operands[0] = dest;
20834 ;; Call-value patterns last so that the wildcard operand does not
20835 ;; disrupt insn-recog's switch tables.
20837 (define_insn "*call_value_pop_0"
20838 [(set (match_operand 0 "" "")
20839 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20840 (match_operand:SI 2 "" "")))
20841 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20842 (match_operand:SI 3 "immediate_operand" "")))]
20845 if (SIBLING_CALL_P (insn))
20848 return "call\t%P1";
20850 [(set_attr "type" "callv")])
20852 (define_insn "*call_value_pop_1"
20853 [(set (match_operand 0 "" "")
20854 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20855 (match_operand:SI 2 "" "")))
20856 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20857 (match_operand:SI 3 "immediate_operand" "i")))]
20860 if (constant_call_address_operand (operands[1], Pmode))
20862 if (SIBLING_CALL_P (insn))
20865 return "call\t%P1";
20867 if (SIBLING_CALL_P (insn))
20870 return "call\t%A1";
20872 [(set_attr "type" "callv")])
20874 (define_insn "*call_value_0"
20875 [(set (match_operand 0 "" "")
20876 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20877 (match_operand:SI 2 "" "")))]
20880 if (SIBLING_CALL_P (insn))
20883 return "call\t%P1";
20885 [(set_attr "type" "callv")])
20887 (define_insn "*call_value_0_rex64"
20888 [(set (match_operand 0 "" "")
20889 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20890 (match_operand:DI 2 "const_int_operand" "")))]
20893 if (SIBLING_CALL_P (insn))
20896 return "call\t%P1";
20898 [(set_attr "type" "callv")])
20900 (define_insn "*call_value_1"
20901 [(set (match_operand 0 "" "")
20902 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20903 (match_operand:SI 2 "" "")))]
20904 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20906 if (constant_call_address_operand (operands[1], Pmode))
20907 return "call\t%P1";
20908 return "call\t%A1";
20910 [(set_attr "type" "callv")])
20912 (define_insn "*sibcall_value_1"
20913 [(set (match_operand 0 "" "")
20914 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20915 (match_operand:SI 2 "" "")))]
20916 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20918 if (constant_call_address_operand (operands[1], Pmode))
20922 [(set_attr "type" "callv")])
20924 (define_insn "*call_value_1_rex64"
20925 [(set (match_operand 0 "" "")
20926 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20927 (match_operand:DI 2 "" "")))]
20928 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20930 if (constant_call_address_operand (operands[1], Pmode))
20931 return "call\t%P1";
20932 return "call\t%A1";
20934 [(set_attr "type" "callv")])
20936 (define_insn "*sibcall_value_1_rex64"
20937 [(set (match_operand 0 "" "")
20938 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20939 (match_operand:DI 2 "" "")))]
20940 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20942 [(set_attr "type" "callv")])
20944 (define_insn "*sibcall_value_1_rex64_v"
20945 [(set (match_operand 0 "" "")
20946 (call (mem:QI (reg:DI R11_REG))
20947 (match_operand:DI 1 "" "")))]
20948 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20950 [(set_attr "type" "callv")])
20952 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20953 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20954 ;; caught for use by garbage collectors and the like. Using an insn that
20955 ;; maps to SIGILL makes it more likely the program will rightfully die.
20956 ;; Keeping with tradition, "6" is in honor of #UD.
20957 (define_insn "trap"
20958 [(trap_if (const_int 1) (const_int 6))]
20960 { return ASM_SHORT "0x0b0f"; }
20961 [(set_attr "length" "2")])
20963 (define_expand "sse_prologue_save"
20964 [(parallel [(set (match_operand:BLK 0 "" "")
20965 (unspec:BLK [(reg:DI 21)
20972 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20973 (use (match_operand:DI 1 "register_operand" ""))
20974 (use (match_operand:DI 2 "immediate_operand" ""))
20975 (use (label_ref:DI (match_operand 3 "" "")))])]
20979 (define_insn "*sse_prologue_save_insn"
20980 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20981 (match_operand:DI 4 "const_int_operand" "n")))
20982 (unspec:BLK [(reg:DI 21)
20989 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20990 (use (match_operand:DI 1 "register_operand" "r"))
20991 (use (match_operand:DI 2 "const_int_operand" "i"))
20992 (use (label_ref:DI (match_operand 3 "" "X")))]
20994 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20995 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20999 operands[0] = gen_rtx_MEM (Pmode,
21000 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21001 output_asm_insn (\"jmp\\t%A1\", operands);
21002 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21004 operands[4] = adjust_address (operands[0], DImode, i*16);
21005 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21006 PUT_MODE (operands[4], TImode);
21007 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21008 output_asm_insn (\"rex\", operands);
21009 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
21011 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
21012 CODE_LABEL_NUMBER (operands[3]));
21016 [(set_attr "type" "other")
21017 (set_attr "length_immediate" "0")
21018 (set_attr "length_address" "0")
21019 (set_attr "length" "135")
21020 (set_attr "memory" "store")
21021 (set_attr "modrm" "0")
21022 (set_attr "mode" "DI")])
21024 (define_expand "prefetch"
21025 [(prefetch (match_operand 0 "address_operand" "")
21026 (match_operand:SI 1 "const_int_operand" "")
21027 (match_operand:SI 2 "const_int_operand" ""))]
21028 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21030 int rw = INTVAL (operands[1]);
21031 int locality = INTVAL (operands[2]);
21033 gcc_assert (rw == 0 || rw == 1);
21034 gcc_assert (locality >= 0 && locality <= 3);
21035 gcc_assert (GET_MODE (operands[0]) == Pmode
21036 || GET_MODE (operands[0]) == VOIDmode);
21038 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21039 supported by SSE counterpart or the SSE prefetch is not available
21040 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21042 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21043 operands[2] = GEN_INT (3);
21045 operands[1] = const0_rtx;
21048 (define_insn "*prefetch_sse"
21049 [(prefetch (match_operand:SI 0 "address_operand" "p")
21051 (match_operand:SI 1 "const_int_operand" ""))]
21052 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21054 static const char * const patterns[4] = {
21055 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21058 int locality = INTVAL (operands[1]);
21059 gcc_assert (locality >= 0 && locality <= 3);
21061 return patterns[locality];
21063 [(set_attr "type" "sse")
21064 (set_attr "memory" "none")])
21066 (define_insn "*prefetch_sse_rex"
21067 [(prefetch (match_operand:DI 0 "address_operand" "p")
21069 (match_operand:SI 1 "const_int_operand" ""))]
21070 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21072 static const char * const patterns[4] = {
21073 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21076 int locality = INTVAL (operands[1]);
21077 gcc_assert (locality >= 0 && locality <= 3);
21079 return patterns[locality];
21081 [(set_attr "type" "sse")
21082 (set_attr "memory" "none")])
21084 (define_insn "*prefetch_3dnow"
21085 [(prefetch (match_operand:SI 0 "address_operand" "p")
21086 (match_operand:SI 1 "const_int_operand" "n")
21088 "TARGET_3DNOW && !TARGET_64BIT"
21090 if (INTVAL (operands[1]) == 0)
21091 return "prefetch\t%a0";
21093 return "prefetchw\t%a0";
21095 [(set_attr "type" "mmx")
21096 (set_attr "memory" "none")])
21098 (define_insn "*prefetch_3dnow_rex"
21099 [(prefetch (match_operand:DI 0 "address_operand" "p")
21100 (match_operand:SI 1 "const_int_operand" "n")
21102 "TARGET_3DNOW && TARGET_64BIT"
21104 if (INTVAL (operands[1]) == 0)
21105 return "prefetch\t%a0";
21107 return "prefetchw\t%a0";
21109 [(set_attr "type" "mmx")
21110 (set_attr "memory" "none")])
21112 (define_expand "stack_protect_set"
21113 [(match_operand 0 "memory_operand" "")
21114 (match_operand 1 "memory_operand" "")]
21117 #ifdef TARGET_THREAD_SSP_OFFSET
21119 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21120 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21122 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21123 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21126 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21128 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21133 (define_insn "stack_protect_set_si"
21134 [(set (match_operand:SI 0 "memory_operand" "=m")
21135 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21136 (set (match_scratch:SI 2 "=&r") (const_int 0))
21137 (clobber (reg:CC FLAGS_REG))]
21139 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21140 [(set_attr "type" "multi")])
21142 (define_insn "stack_protect_set_di"
21143 [(set (match_operand:DI 0 "memory_operand" "=m")
21144 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21145 (set (match_scratch:DI 2 "=&r") (const_int 0))
21146 (clobber (reg:CC FLAGS_REG))]
21148 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21149 [(set_attr "type" "multi")])
21151 (define_insn "stack_tls_protect_set_si"
21152 [(set (match_operand:SI 0 "memory_operand" "=m")
21153 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21154 (set (match_scratch:SI 2 "=&r") (const_int 0))
21155 (clobber (reg:CC FLAGS_REG))]
21157 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21158 [(set_attr "type" "multi")])
21160 (define_insn "stack_tls_protect_set_di"
21161 [(set (match_operand:DI 0 "memory_operand" "=m")
21162 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21163 (set (match_scratch:DI 2 "=&r") (const_int 0))
21164 (clobber (reg:CC FLAGS_REG))]
21167 /* The kernel uses a different segment register for performance reasons; a
21168 system call would not have to trash the userspace segment register,
21169 which would be expensive */
21170 if (ix86_cmodel != CM_KERNEL)
21171 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21173 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21175 [(set_attr "type" "multi")])
21177 (define_expand "stack_protect_test"
21178 [(match_operand 0 "memory_operand" "")
21179 (match_operand 1 "memory_operand" "")
21180 (match_operand 2 "" "")]
21183 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21184 ix86_compare_op0 = operands[0];
21185 ix86_compare_op1 = operands[1];
21186 ix86_compare_emitted = flags;
21188 #ifdef TARGET_THREAD_SSP_OFFSET
21190 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21191 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21193 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21194 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21197 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21199 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21201 emit_jump_insn (gen_beq (operands[2]));
21205 (define_insn "stack_protect_test_si"
21206 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21207 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21208 (match_operand:SI 2 "memory_operand" "m")]
21210 (clobber (match_scratch:SI 3 "=&r"))]
21212 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21213 [(set_attr "type" "multi")])
21215 (define_insn "stack_protect_test_di"
21216 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21217 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21218 (match_operand:DI 2 "memory_operand" "m")]
21220 (clobber (match_scratch:DI 3 "=&r"))]
21222 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21223 [(set_attr "type" "multi")])
21225 (define_insn "stack_tls_protect_test_si"
21226 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21227 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21228 (match_operand:SI 2 "const_int_operand" "i")]
21229 UNSPEC_SP_TLS_TEST))
21230 (clobber (match_scratch:SI 3 "=r"))]
21232 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21233 [(set_attr "type" "multi")])
21235 (define_insn "stack_tls_protect_test_di"
21236 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21237 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21238 (match_operand:DI 2 "const_int_operand" "i")]
21239 UNSPEC_SP_TLS_TEST))
21240 (clobber (match_scratch:DI 3 "=r"))]
21243 /* The kernel uses a different segment register for performance reasons; a
21244 system call would not have to trash the userspace segment register,
21245 which would be expensive */
21246 if (ix86_cmodel != CM_KERNEL)
21247 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21249 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21251 [(set_attr "type" "multi")])
21255 (include "sync.md")