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
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
89 ; For SSE/MMX support:
90 (UNSPEC_FIX_NOTRUNC 30)
98 (UNSPEC_NOP 38) ; prevents combiner cleverness
109 ; Generic math support
111 (UNSPEC_IEEE_MIN 51) ; not commutative
112 (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)
137 (UNSPEC_XTRACT_FRACT 84)
138 (UNSPEC_XTRACT_EXP 85)
139 (UNSPEC_FSCALE_FRACT 86)
140 (UNSPEC_FSCALE_EXP 87)
149 (UNSPEC_SP_TLS_SET 102)
150 (UNSPEC_SP_TLS_TEST 103)
154 [(UNSPECV_BLOCKAGE 0)
155 (UNSPECV_STACK_PROBE 1)
164 (UNSPECV_CMPXCHG_1 10)
165 (UNSPECV_CMPXCHG_2 11)
170 ;; Registers by name.
179 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
182 ;; In C guard expressions, put expressions which may be compile-time
183 ;; constants first. This allows for better optimization. For
184 ;; example, write "TARGET_64BIT && reload_completed", not
185 ;; "reload_completed && TARGET_64BIT".
188 ;; Processor type. This attribute must exactly match the processor_type
189 ;; enumeration in i386.h.
190 (define_attr "cpu" "i386,i486,pentium,pentiumpro,k6,athlon,pentium4,k8,nocona,generic32,generic64"
191 (const (symbol_ref "ix86_tune")))
193 ;; A basic instruction type. Refinements due to arguments to be
194 ;; provided in other attributes.
197 alu,alu1,negnot,imov,imovx,lea,
198 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
199 icmp,test,ibr,setcc,icmov,
200 push,pop,call,callv,leave,
202 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
203 sselog,sselog1,sseiadd,sseishft,sseimul,
204 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
205 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
206 (const_string "other"))
208 ;; Main data type used by the insn
210 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
211 (const_string "unknown"))
213 ;; The CPU unit operations uses.
214 (define_attr "unit" "integer,i387,sse,mmx,unknown"
215 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
216 (const_string "i387")
217 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
218 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
220 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
222 (eq_attr "type" "other")
223 (const_string "unknown")]
224 (const_string "integer")))
226 ;; The (bounding maximum) length of an instruction immediate.
227 (define_attr "length_immediate" ""
228 (cond [(eq_attr "type" "incdec,setcc,icmov,str,cld,lea,other,multi,idiv,leave")
230 (eq_attr "unit" "i387,sse,mmx")
232 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
234 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
235 (eq_attr "type" "imov,test")
236 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
237 (eq_attr "type" "call")
238 (if_then_else (match_operand 0 "constant_call_address_operand" "")
241 (eq_attr "type" "callv")
242 (if_then_else (match_operand 1 "constant_call_address_operand" "")
245 ;; We don't know the size before shorten_branches. Expect
246 ;; the instruction to fit for better scheduling.
247 (eq_attr "type" "ibr")
250 (symbol_ref "/* Update immediate_length and other attributes! */
251 gcc_unreachable (),1")))
253 ;; The (bounding maximum) length of an instruction address.
254 (define_attr "length_address" ""
255 (cond [(eq_attr "type" "str,cld,other,multi,fxch")
257 (and (eq_attr "type" "call")
258 (match_operand 0 "constant_call_address_operand" ""))
260 (and (eq_attr "type" "callv")
261 (match_operand 1 "constant_call_address_operand" ""))
264 (symbol_ref "ix86_attr_length_address_default (insn)")))
266 ;; Set when length prefix is used.
267 (define_attr "prefix_data16" ""
268 (if_then_else (ior (eq_attr "mode" "HI")
269 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
273 ;; Set when string REP prefix is used.
274 (define_attr "prefix_rep" ""
275 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
279 ;; Set when 0f opcode prefix is used.
280 (define_attr "prefix_0f" ""
282 (ior (eq_attr "type" "imovx,setcc,icmov")
283 (eq_attr "unit" "sse,mmx"))
287 ;; Set when REX opcode prefix is used.
288 (define_attr "prefix_rex" ""
289 (cond [(and (eq_attr "mode" "DI")
290 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
292 (and (eq_attr "mode" "QI")
293 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
296 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
302 ;; Set when modrm byte is used.
303 (define_attr "modrm" ""
304 (cond [(eq_attr "type" "str,cld,leave")
306 (eq_attr "unit" "i387")
308 (and (eq_attr "type" "incdec")
309 (ior (match_operand:SI 1 "register_operand" "")
310 (match_operand:HI 1 "register_operand" "")))
312 (and (eq_attr "type" "push")
313 (not (match_operand 1 "memory_operand" "")))
315 (and (eq_attr "type" "pop")
316 (not (match_operand 0 "memory_operand" "")))
318 (and (eq_attr "type" "imov")
319 (ior (and (match_operand 0 "register_operand" "")
320 (match_operand 1 "immediate_operand" ""))
321 (ior (and (match_operand 0 "ax_reg_operand" "")
322 (match_operand 1 "memory_displacement_only_operand" ""))
323 (and (match_operand 0 "memory_displacement_only_operand" "")
324 (match_operand 1 "ax_reg_operand" "")))))
326 (and (eq_attr "type" "call")
327 (match_operand 0 "constant_call_address_operand" ""))
329 (and (eq_attr "type" "callv")
330 (match_operand 1 "constant_call_address_operand" ""))
335 ;; The (bounding maximum) length of an instruction in bytes.
336 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
337 ;; Later we may want to split them and compute proper length as for
339 (define_attr "length" ""
340 (cond [(eq_attr "type" "other,multi,fistp,frndint")
342 (eq_attr "type" "fcmp")
344 (eq_attr "unit" "i387")
346 (plus (attr "prefix_data16")
347 (attr "length_address")))]
348 (plus (plus (attr "modrm")
349 (plus (attr "prefix_0f")
350 (plus (attr "prefix_rex")
352 (plus (attr "prefix_rep")
353 (plus (attr "prefix_data16")
354 (plus (attr "length_immediate")
355 (attr "length_address")))))))
357 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
358 ;; `store' if there is a simple memory reference therein, or `unknown'
359 ;; if the instruction is complex.
361 (define_attr "memory" "none,load,store,both,unknown"
362 (cond [(eq_attr "type" "other,multi,str")
363 (const_string "unknown")
364 (eq_attr "type" "lea,fcmov,fpspc,cld")
365 (const_string "none")
366 (eq_attr "type" "fistp,leave")
367 (const_string "both")
368 (eq_attr "type" "frndint")
369 (const_string "load")
370 (eq_attr "type" "push")
371 (if_then_else (match_operand 1 "memory_operand" "")
372 (const_string "both")
373 (const_string "store"))
374 (eq_attr "type" "pop")
375 (if_then_else (match_operand 0 "memory_operand" "")
376 (const_string "both")
377 (const_string "load"))
378 (eq_attr "type" "setcc")
379 (if_then_else (match_operand 0 "memory_operand" "")
380 (const_string "store")
381 (const_string "none"))
382 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
383 (if_then_else (ior (match_operand 0 "memory_operand" "")
384 (match_operand 1 "memory_operand" ""))
385 (const_string "load")
386 (const_string "none"))
387 (eq_attr "type" "ibr")
388 (if_then_else (match_operand 0 "memory_operand" "")
389 (const_string "load")
390 (const_string "none"))
391 (eq_attr "type" "call")
392 (if_then_else (match_operand 0 "constant_call_address_operand" "")
393 (const_string "none")
394 (const_string "load"))
395 (eq_attr "type" "callv")
396 (if_then_else (match_operand 1 "constant_call_address_operand" "")
397 (const_string "none")
398 (const_string "load"))
399 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
400 (match_operand 1 "memory_operand" ""))
401 (const_string "both")
402 (and (match_operand 0 "memory_operand" "")
403 (match_operand 1 "memory_operand" ""))
404 (const_string "both")
405 (match_operand 0 "memory_operand" "")
406 (const_string "store")
407 (match_operand 1 "memory_operand" "")
408 (const_string "load")
410 "!alu1,negnot,ishift1,
411 imov,imovx,icmp,test,
413 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
414 mmx,mmxmov,mmxcmp,mmxcvt")
415 (match_operand 2 "memory_operand" ""))
416 (const_string "load")
417 (and (eq_attr "type" "icmov")
418 (match_operand 3 "memory_operand" ""))
419 (const_string "load")
421 (const_string "none")))
423 ;; Indicates if an instruction has both an immediate and a displacement.
425 (define_attr "imm_disp" "false,true,unknown"
426 (cond [(eq_attr "type" "other,multi")
427 (const_string "unknown")
428 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
429 (and (match_operand 0 "memory_displacement_operand" "")
430 (match_operand 1 "immediate_operand" "")))
431 (const_string "true")
432 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
433 (and (match_operand 0 "memory_displacement_operand" "")
434 (match_operand 2 "immediate_operand" "")))
435 (const_string "true")
437 (const_string "false")))
439 ;; Indicates if an FP operation has an integer source.
441 (define_attr "fp_int_src" "false,true"
442 (const_string "false"))
444 ;; Defines rounding mode of an FP operation.
446 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
447 (const_string "any"))
449 ;; Describe a user's asm statement.
450 (define_asm_attributes
451 [(set_attr "length" "128")
452 (set_attr "type" "multi")])
454 ;; All x87 floating point modes
455 (define_mode_macro X87MODEF [SF DF XF])
457 ;; All integer modes handled by x87 fisttp operator.
458 (define_mode_macro X87MODEI [HI SI DI])
460 ;; All integer modes handled by integer x87 operators.
461 (define_mode_macro X87MODEI12 [HI SI])
463 ;; All SSE floating point modes
464 (define_mode_macro SSEMODEF [SF DF])
466 ;; All integer modes handled by SSE cvtts?2si* operators.
467 (define_mode_macro SSEMODEI24 [SI DI])
470 ;; Scheduling descriptions
472 (include "pentium.md")
475 (include "athlon.md")
478 ;; Operand and operator predicates and constraints
480 (include "predicates.md")
481 (include "constraints.md")
484 ;; Compare instructions.
486 ;; All compare insns have expanders that save the operands away without
487 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
488 ;; after the cmp) will actually emit the cmpM.
490 (define_expand "cmpti"
491 [(set (reg:CC FLAGS_REG)
492 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
493 (match_operand:TI 1 "x86_64_general_operand" "")))]
496 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
497 operands[0] = force_reg (TImode, operands[0]);
498 ix86_compare_op0 = operands[0];
499 ix86_compare_op1 = operands[1];
503 (define_expand "cmpdi"
504 [(set (reg:CC FLAGS_REG)
505 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
506 (match_operand:DI 1 "x86_64_general_operand" "")))]
509 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
510 operands[0] = force_reg (DImode, operands[0]);
511 ix86_compare_op0 = operands[0];
512 ix86_compare_op1 = operands[1];
516 (define_expand "cmpsi"
517 [(set (reg:CC FLAGS_REG)
518 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
519 (match_operand:SI 1 "general_operand" "")))]
522 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
523 operands[0] = force_reg (SImode, operands[0]);
524 ix86_compare_op0 = operands[0];
525 ix86_compare_op1 = operands[1];
529 (define_expand "cmphi"
530 [(set (reg:CC FLAGS_REG)
531 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
532 (match_operand:HI 1 "general_operand" "")))]
535 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
536 operands[0] = force_reg (HImode, operands[0]);
537 ix86_compare_op0 = operands[0];
538 ix86_compare_op1 = operands[1];
542 (define_expand "cmpqi"
543 [(set (reg:CC FLAGS_REG)
544 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
545 (match_operand:QI 1 "general_operand" "")))]
548 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
549 operands[0] = force_reg (QImode, operands[0]);
550 ix86_compare_op0 = operands[0];
551 ix86_compare_op1 = operands[1];
555 (define_insn "cmpdi_ccno_1_rex64"
556 [(set (reg FLAGS_REG)
557 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
558 (match_operand:DI 1 "const0_operand" "n,n")))]
559 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
561 test{q}\t{%0, %0|%0, %0}
562 cmp{q}\t{%1, %0|%0, %1}"
563 [(set_attr "type" "test,icmp")
564 (set_attr "length_immediate" "0,1")
565 (set_attr "mode" "DI")])
567 (define_insn "*cmpdi_minus_1_rex64"
568 [(set (reg FLAGS_REG)
569 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
570 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
572 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
573 "cmp{q}\t{%1, %0|%0, %1}"
574 [(set_attr "type" "icmp")
575 (set_attr "mode" "DI")])
577 (define_expand "cmpdi_1_rex64"
578 [(set (reg:CC FLAGS_REG)
579 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
580 (match_operand:DI 1 "general_operand" "")))]
584 (define_insn "cmpdi_1_insn_rex64"
585 [(set (reg FLAGS_REG)
586 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
587 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
588 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
589 "cmp{q}\t{%1, %0|%0, %1}"
590 [(set_attr "type" "icmp")
591 (set_attr "mode" "DI")])
594 (define_insn "*cmpsi_ccno_1"
595 [(set (reg FLAGS_REG)
596 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
597 (match_operand:SI 1 "const0_operand" "n,n")))]
598 "ix86_match_ccmode (insn, CCNOmode)"
600 test{l}\t{%0, %0|%0, %0}
601 cmp{l}\t{%1, %0|%0, %1}"
602 [(set_attr "type" "test,icmp")
603 (set_attr "length_immediate" "0,1")
604 (set_attr "mode" "SI")])
606 (define_insn "*cmpsi_minus_1"
607 [(set (reg FLAGS_REG)
608 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
609 (match_operand:SI 1 "general_operand" "ri,mr"))
611 "ix86_match_ccmode (insn, CCGOCmode)"
612 "cmp{l}\t{%1, %0|%0, %1}"
613 [(set_attr "type" "icmp")
614 (set_attr "mode" "SI")])
616 (define_expand "cmpsi_1"
617 [(set (reg:CC FLAGS_REG)
618 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
619 (match_operand:SI 1 "general_operand" "ri,mr")))]
623 (define_insn "*cmpsi_1_insn"
624 [(set (reg FLAGS_REG)
625 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
626 (match_operand:SI 1 "general_operand" "ri,mr")))]
627 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
628 && ix86_match_ccmode (insn, CCmode)"
629 "cmp{l}\t{%1, %0|%0, %1}"
630 [(set_attr "type" "icmp")
631 (set_attr "mode" "SI")])
633 (define_insn "*cmphi_ccno_1"
634 [(set (reg FLAGS_REG)
635 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
636 (match_operand:HI 1 "const0_operand" "n,n")))]
637 "ix86_match_ccmode (insn, CCNOmode)"
639 test{w}\t{%0, %0|%0, %0}
640 cmp{w}\t{%1, %0|%0, %1}"
641 [(set_attr "type" "test,icmp")
642 (set_attr "length_immediate" "0,1")
643 (set_attr "mode" "HI")])
645 (define_insn "*cmphi_minus_1"
646 [(set (reg FLAGS_REG)
647 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
648 (match_operand:HI 1 "general_operand" "ri,mr"))
650 "ix86_match_ccmode (insn, CCGOCmode)"
651 "cmp{w}\t{%1, %0|%0, %1}"
652 [(set_attr "type" "icmp")
653 (set_attr "mode" "HI")])
655 (define_insn "*cmphi_1"
656 [(set (reg FLAGS_REG)
657 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
658 (match_operand:HI 1 "general_operand" "ri,mr")))]
659 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
660 && ix86_match_ccmode (insn, CCmode)"
661 "cmp{w}\t{%1, %0|%0, %1}"
662 [(set_attr "type" "icmp")
663 (set_attr "mode" "HI")])
665 (define_insn "*cmpqi_ccno_1"
666 [(set (reg FLAGS_REG)
667 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
668 (match_operand:QI 1 "const0_operand" "n,n")))]
669 "ix86_match_ccmode (insn, CCNOmode)"
671 test{b}\t{%0, %0|%0, %0}
672 cmp{b}\t{$0, %0|%0, 0}"
673 [(set_attr "type" "test,icmp")
674 (set_attr "length_immediate" "0,1")
675 (set_attr "mode" "QI")])
677 (define_insn "*cmpqi_1"
678 [(set (reg FLAGS_REG)
679 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
680 (match_operand:QI 1 "general_operand" "qi,mq")))]
681 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
682 && ix86_match_ccmode (insn, CCmode)"
683 "cmp{b}\t{%1, %0|%0, %1}"
684 [(set_attr "type" "icmp")
685 (set_attr "mode" "QI")])
687 (define_insn "*cmpqi_minus_1"
688 [(set (reg FLAGS_REG)
689 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
690 (match_operand:QI 1 "general_operand" "qi,mq"))
692 "ix86_match_ccmode (insn, CCGOCmode)"
693 "cmp{b}\t{%1, %0|%0, %1}"
694 [(set_attr "type" "icmp")
695 (set_attr "mode" "QI")])
697 (define_insn "*cmpqi_ext_1"
698 [(set (reg FLAGS_REG)
700 (match_operand:QI 0 "general_operand" "Qm")
703 (match_operand 1 "ext_register_operand" "Q")
706 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
707 "cmp{b}\t{%h1, %0|%0, %h1}"
708 [(set_attr "type" "icmp")
709 (set_attr "mode" "QI")])
711 (define_insn "*cmpqi_ext_1_rex64"
712 [(set (reg FLAGS_REG)
714 (match_operand:QI 0 "register_operand" "Q")
717 (match_operand 1 "ext_register_operand" "Q")
720 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
721 "cmp{b}\t{%h1, %0|%0, %h1}"
722 [(set_attr "type" "icmp")
723 (set_attr "mode" "QI")])
725 (define_insn "*cmpqi_ext_2"
726 [(set (reg FLAGS_REG)
730 (match_operand 0 "ext_register_operand" "Q")
733 (match_operand:QI 1 "const0_operand" "n")))]
734 "ix86_match_ccmode (insn, CCNOmode)"
736 [(set_attr "type" "test")
737 (set_attr "length_immediate" "0")
738 (set_attr "mode" "QI")])
740 (define_expand "cmpqi_ext_3"
741 [(set (reg:CC FLAGS_REG)
745 (match_operand 0 "ext_register_operand" "")
748 (match_operand:QI 1 "general_operand" "")))]
752 (define_insn "cmpqi_ext_3_insn"
753 [(set (reg FLAGS_REG)
757 (match_operand 0 "ext_register_operand" "Q")
760 (match_operand:QI 1 "general_operand" "Qmn")))]
761 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
762 "cmp{b}\t{%1, %h0|%h0, %1}"
763 [(set_attr "type" "icmp")
764 (set_attr "mode" "QI")])
766 (define_insn "cmpqi_ext_3_insn_rex64"
767 [(set (reg FLAGS_REG)
771 (match_operand 0 "ext_register_operand" "Q")
774 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
775 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
776 "cmp{b}\t{%1, %h0|%h0, %1}"
777 [(set_attr "type" "icmp")
778 (set_attr "mode" "QI")])
780 (define_insn "*cmpqi_ext_4"
781 [(set (reg FLAGS_REG)
785 (match_operand 0 "ext_register_operand" "Q")
790 (match_operand 1 "ext_register_operand" "Q")
793 "ix86_match_ccmode (insn, CCmode)"
794 "cmp{b}\t{%h1, %h0|%h0, %h1}"
795 [(set_attr "type" "icmp")
796 (set_attr "mode" "QI")])
798 ;; These implement float point compares.
799 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
800 ;; which would allow mix and match FP modes on the compares. Which is what
801 ;; the old patterns did, but with many more of them.
803 (define_expand "cmpxf"
804 [(set (reg:CC FLAGS_REG)
805 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
806 (match_operand:XF 1 "nonmemory_operand" "")))]
809 ix86_compare_op0 = operands[0];
810 ix86_compare_op1 = operands[1];
814 (define_expand "cmpdf"
815 [(set (reg:CC FLAGS_REG)
816 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
817 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
818 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
820 ix86_compare_op0 = operands[0];
821 ix86_compare_op1 = operands[1];
825 (define_expand "cmpsf"
826 [(set (reg:CC FLAGS_REG)
827 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
828 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
829 "TARGET_80387 || TARGET_SSE_MATH"
831 ix86_compare_op0 = operands[0];
832 ix86_compare_op1 = operands[1];
836 ;; FP compares, step 1:
837 ;; Set the FP condition codes.
839 ;; CCFPmode compare with exceptions
840 ;; CCFPUmode compare with no exceptions
842 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
843 ;; used to manage the reg stack popping would not be preserved.
845 (define_insn "*cmpfp_0"
846 [(set (match_operand:HI 0 "register_operand" "=a")
849 (match_operand 1 "register_operand" "f")
850 (match_operand 2 "const0_operand" "X"))]
853 && FLOAT_MODE_P (GET_MODE (operands[1]))
854 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
855 "* return output_fp_compare (insn, operands, 0, 0);"
856 [(set_attr "type" "multi")
857 (set_attr "unit" "i387")
859 (cond [(match_operand:SF 1 "" "")
861 (match_operand:DF 1 "" "")
864 (const_string "XF")))])
866 (define_insn "*cmpfp_sf"
867 [(set (match_operand:HI 0 "register_operand" "=a")
870 (match_operand:SF 1 "register_operand" "f")
871 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
874 "* return output_fp_compare (insn, operands, 0, 0);"
875 [(set_attr "type" "multi")
876 (set_attr "unit" "i387")
877 (set_attr "mode" "SF")])
879 (define_insn "*cmpfp_df"
880 [(set (match_operand:HI 0 "register_operand" "=a")
883 (match_operand:DF 1 "register_operand" "f")
884 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
887 "* return output_fp_compare (insn, operands, 0, 0);"
888 [(set_attr "type" "multi")
889 (set_attr "unit" "i387")
890 (set_attr "mode" "DF")])
892 (define_insn "*cmpfp_xf"
893 [(set (match_operand:HI 0 "register_operand" "=a")
896 (match_operand:XF 1 "register_operand" "f")
897 (match_operand:XF 2 "register_operand" "f"))]
900 "* return output_fp_compare (insn, operands, 0, 0);"
901 [(set_attr "type" "multi")
902 (set_attr "unit" "i387")
903 (set_attr "mode" "XF")])
905 (define_insn "*cmpfp_u"
906 [(set (match_operand:HI 0 "register_operand" "=a")
909 (match_operand 1 "register_operand" "f")
910 (match_operand 2 "register_operand" "f"))]
913 && FLOAT_MODE_P (GET_MODE (operands[1]))
914 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
915 "* return output_fp_compare (insn, operands, 0, 1);"
916 [(set_attr "type" "multi")
917 (set_attr "unit" "i387")
919 (cond [(match_operand:SF 1 "" "")
921 (match_operand:DF 1 "" "")
924 (const_string "XF")))])
926 (define_insn "*cmpfp_<mode>"
927 [(set (match_operand:HI 0 "register_operand" "=a")
930 (match_operand 1 "register_operand" "f")
931 (match_operator 3 "float_operator"
932 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
934 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
935 && FLOAT_MODE_P (GET_MODE (operands[1]))
936 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
937 "* return output_fp_compare (insn, operands, 0, 0);"
938 [(set_attr "type" "multi")
939 (set_attr "unit" "i387")
940 (set_attr "fp_int_src" "true")
941 (set_attr "mode" "<MODE>")])
943 ;; FP compares, step 2
944 ;; Move the fpsw to ax.
946 (define_insn "x86_fnstsw_1"
947 [(set (match_operand:HI 0 "register_operand" "=a")
948 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
951 [(set_attr "length" "2")
952 (set_attr "mode" "SI")
953 (set_attr "unit" "i387")])
955 ;; FP compares, step 3
956 ;; Get ax into flags, general case.
958 (define_insn "x86_sahf_1"
959 [(set (reg:CC FLAGS_REG)
960 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
963 [(set_attr "length" "1")
964 (set_attr "athlon_decode" "vector")
965 (set_attr "mode" "SI")])
967 ;; Pentium Pro can do steps 1 through 3 in one go.
969 (define_insn "*cmpfp_i_mixed"
970 [(set (reg:CCFP FLAGS_REG)
971 (compare:CCFP (match_operand 0 "register_operand" "f,x")
972 (match_operand 1 "nonimmediate_operand" "f,xm")))]
974 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
975 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
976 "* return output_fp_compare (insn, operands, 1, 0);"
977 [(set_attr "type" "fcmp,ssecomi")
979 (if_then_else (match_operand:SF 1 "" "")
981 (const_string "DF")))
982 (set_attr "athlon_decode" "vector")])
984 (define_insn "*cmpfp_i_sse"
985 [(set (reg:CCFP FLAGS_REG)
986 (compare:CCFP (match_operand 0 "register_operand" "x")
987 (match_operand 1 "nonimmediate_operand" "xm")))]
989 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
990 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
991 "* return output_fp_compare (insn, operands, 1, 0);"
992 [(set_attr "type" "ssecomi")
994 (if_then_else (match_operand:SF 1 "" "")
996 (const_string "DF")))
997 (set_attr "athlon_decode" "vector")])
999 (define_insn "*cmpfp_i_i387"
1000 [(set (reg:CCFP FLAGS_REG)
1001 (compare:CCFP (match_operand 0 "register_operand" "f")
1002 (match_operand 1 "register_operand" "f")))]
1003 "TARGET_80387 && TARGET_CMOVE
1004 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1005 && FLOAT_MODE_P (GET_MODE (operands[0]))
1006 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1007 "* return output_fp_compare (insn, operands, 1, 0);"
1008 [(set_attr "type" "fcmp")
1010 (cond [(match_operand:SF 1 "" "")
1012 (match_operand:DF 1 "" "")
1015 (const_string "XF")))
1016 (set_attr "athlon_decode" "vector")])
1018 (define_insn "*cmpfp_iu_mixed"
1019 [(set (reg:CCFPU FLAGS_REG)
1020 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1021 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1022 "TARGET_MIX_SSE_I387
1023 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1024 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1025 "* return output_fp_compare (insn, operands, 1, 1);"
1026 [(set_attr "type" "fcmp,ssecomi")
1028 (if_then_else (match_operand:SF 1 "" "")
1030 (const_string "DF")))
1031 (set_attr "athlon_decode" "vector")])
1033 (define_insn "*cmpfp_iu_sse"
1034 [(set (reg:CCFPU FLAGS_REG)
1035 (compare:CCFPU (match_operand 0 "register_operand" "x")
1036 (match_operand 1 "nonimmediate_operand" "xm")))]
1038 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1039 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1040 "* return output_fp_compare (insn, operands, 1, 1);"
1041 [(set_attr "type" "ssecomi")
1043 (if_then_else (match_operand:SF 1 "" "")
1045 (const_string "DF")))
1046 (set_attr "athlon_decode" "vector")])
1048 (define_insn "*cmpfp_iu_387"
1049 [(set (reg:CCFPU FLAGS_REG)
1050 (compare:CCFPU (match_operand 0 "register_operand" "f")
1051 (match_operand 1 "register_operand" "f")))]
1052 "TARGET_80387 && TARGET_CMOVE
1053 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1054 && FLOAT_MODE_P (GET_MODE (operands[0]))
1055 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1056 "* return output_fp_compare (insn, operands, 1, 1);"
1057 [(set_attr "type" "fcmp")
1059 (cond [(match_operand:SF 1 "" "")
1061 (match_operand:DF 1 "" "")
1064 (const_string "XF")))
1065 (set_attr "athlon_decode" "vector")])
1067 ;; Move instructions.
1069 ;; General case of fullword move.
1071 (define_expand "movsi"
1072 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1073 (match_operand:SI 1 "general_operand" ""))]
1075 "ix86_expand_move (SImode, operands); DONE;")
1077 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1080 ;; %%% We don't use a post-inc memory reference because x86 is not a
1081 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1082 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1083 ;; targets without our curiosities, and it is just as easy to represent
1084 ;; this differently.
1086 (define_insn "*pushsi2"
1087 [(set (match_operand:SI 0 "push_operand" "=<")
1088 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1091 [(set_attr "type" "push")
1092 (set_attr "mode" "SI")])
1094 ;; For 64BIT abi we always round up to 8 bytes.
1095 (define_insn "*pushsi2_rex64"
1096 [(set (match_operand:SI 0 "push_operand" "=X")
1097 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1100 [(set_attr "type" "push")
1101 (set_attr "mode" "SI")])
1103 (define_insn "*pushsi2_prologue"
1104 [(set (match_operand:SI 0 "push_operand" "=<")
1105 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1106 (clobber (mem:BLK (scratch)))]
1109 [(set_attr "type" "push")
1110 (set_attr "mode" "SI")])
1112 (define_insn "*popsi1_epilogue"
1113 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1114 (mem:SI (reg:SI SP_REG)))
1115 (set (reg:SI SP_REG)
1116 (plus:SI (reg:SI SP_REG) (const_int 4)))
1117 (clobber (mem:BLK (scratch)))]
1120 [(set_attr "type" "pop")
1121 (set_attr "mode" "SI")])
1123 (define_insn "popsi1"
1124 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1125 (mem:SI (reg:SI SP_REG)))
1126 (set (reg:SI SP_REG)
1127 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1130 [(set_attr "type" "pop")
1131 (set_attr "mode" "SI")])
1133 (define_insn "*movsi_xor"
1134 [(set (match_operand:SI 0 "register_operand" "=r")
1135 (match_operand:SI 1 "const0_operand" "i"))
1136 (clobber (reg:CC FLAGS_REG))]
1137 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1138 "xor{l}\t{%0, %0|%0, %0}"
1139 [(set_attr "type" "alu1")
1140 (set_attr "mode" "SI")
1141 (set_attr "length_immediate" "0")])
1143 (define_insn "*movsi_or"
1144 [(set (match_operand:SI 0 "register_operand" "=r")
1145 (match_operand:SI 1 "immediate_operand" "i"))
1146 (clobber (reg:CC FLAGS_REG))]
1148 && operands[1] == constm1_rtx
1149 && (TARGET_PENTIUM || optimize_size)"
1151 operands[1] = constm1_rtx;
1152 return "or{l}\t{%1, %0|%0, %1}";
1154 [(set_attr "type" "alu1")
1155 (set_attr "mode" "SI")
1156 (set_attr "length_immediate" "1")])
1158 (define_insn "*movsi_1"
1159 [(set (match_operand:SI 0 "nonimmediate_operand"
1160 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1161 (match_operand:SI 1 "general_operand"
1162 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1163 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1165 switch (get_attr_type (insn))
1168 if (get_attr_mode (insn) == MODE_TI)
1169 return "pxor\t%0, %0";
1170 return "xorps\t%0, %0";
1173 switch (get_attr_mode (insn))
1176 return "movdqa\t{%1, %0|%0, %1}";
1178 return "movaps\t{%1, %0|%0, %1}";
1180 return "movd\t{%1, %0|%0, %1}";
1182 return "movss\t{%1, %0|%0, %1}";
1188 return "pxor\t%0, %0";
1191 if (get_attr_mode (insn) == MODE_DI)
1192 return "movq\t{%1, %0|%0, %1}";
1193 return "movd\t{%1, %0|%0, %1}";
1196 return "lea{l}\t{%1, %0|%0, %1}";
1199 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1200 return "mov{l}\t{%1, %0|%0, %1}";
1204 (cond [(eq_attr "alternative" "2")
1205 (const_string "mmxadd")
1206 (eq_attr "alternative" "3,4,5")
1207 (const_string "mmxmov")
1208 (eq_attr "alternative" "6")
1209 (const_string "sselog1")
1210 (eq_attr "alternative" "7,8,9,10,11")
1211 (const_string "ssemov")
1212 (match_operand:DI 1 "pic_32bit_operand" "")
1213 (const_string "lea")
1215 (const_string "imov")))
1217 (cond [(eq_attr "alternative" "2,3")
1219 (eq_attr "alternative" "6,7")
1221 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1222 (const_string "V4SF")
1223 (const_string "TI"))
1224 (and (eq_attr "alternative" "8,9,10,11")
1225 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1228 (const_string "SI")))])
1230 ;; Stores and loads of ax to arbitrary constant address.
1231 ;; We fake an second form of instruction to force reload to load address
1232 ;; into register when rax is not available
1233 (define_insn "*movabssi_1_rex64"
1234 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1235 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1236 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1238 movabs{l}\t{%1, %P0|%P0, %1}
1239 mov{l}\t{%1, %a0|%a0, %1}"
1240 [(set_attr "type" "imov")
1241 (set_attr "modrm" "0,*")
1242 (set_attr "length_address" "8,0")
1243 (set_attr "length_immediate" "0,*")
1244 (set_attr "memory" "store")
1245 (set_attr "mode" "SI")])
1247 (define_insn "*movabssi_2_rex64"
1248 [(set (match_operand:SI 0 "register_operand" "=a,r")
1249 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1250 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1252 movabs{l}\t{%P1, %0|%0, %P1}
1253 mov{l}\t{%a1, %0|%0, %a1}"
1254 [(set_attr "type" "imov")
1255 (set_attr "modrm" "0,*")
1256 (set_attr "length_address" "8,0")
1257 (set_attr "length_immediate" "0")
1258 (set_attr "memory" "load")
1259 (set_attr "mode" "SI")])
1261 (define_insn "*swapsi"
1262 [(set (match_operand:SI 0 "register_operand" "+r")
1263 (match_operand:SI 1 "register_operand" "+r"))
1268 [(set_attr "type" "imov")
1269 (set_attr "mode" "SI")
1270 (set_attr "pent_pair" "np")
1271 (set_attr "athlon_decode" "vector")])
1273 (define_expand "movhi"
1274 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1275 (match_operand:HI 1 "general_operand" ""))]
1277 "ix86_expand_move (HImode, operands); DONE;")
1279 (define_insn "*pushhi2"
1280 [(set (match_operand:HI 0 "push_operand" "=X")
1281 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1284 [(set_attr "type" "push")
1285 (set_attr "mode" "SI")])
1287 ;; For 64BIT abi we always round up to 8 bytes.
1288 (define_insn "*pushhi2_rex64"
1289 [(set (match_operand:HI 0 "push_operand" "=X")
1290 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1293 [(set_attr "type" "push")
1294 (set_attr "mode" "DI")])
1296 (define_insn "*movhi_1"
1297 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1298 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1299 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1301 switch (get_attr_type (insn))
1304 /* movzwl is faster than movw on p2 due to partial word stalls,
1305 though not as fast as an aligned movl. */
1306 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1308 if (get_attr_mode (insn) == MODE_SI)
1309 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1311 return "mov{w}\t{%1, %0|%0, %1}";
1315 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1316 (const_string "imov")
1317 (and (eq_attr "alternative" "0")
1318 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1320 (eq (symbol_ref "TARGET_HIMODE_MATH")
1322 (const_string "imov")
1323 (and (eq_attr "alternative" "1,2")
1324 (match_operand:HI 1 "aligned_operand" ""))
1325 (const_string "imov")
1326 (and (ne (symbol_ref "TARGET_MOVX")
1328 (eq_attr "alternative" "0,2"))
1329 (const_string "imovx")
1331 (const_string "imov")))
1333 (cond [(eq_attr "type" "imovx")
1335 (and (eq_attr "alternative" "1,2")
1336 (match_operand:HI 1 "aligned_operand" ""))
1338 (and (eq_attr "alternative" "0")
1339 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1341 (eq (symbol_ref "TARGET_HIMODE_MATH")
1345 (const_string "HI")))])
1347 ;; Stores and loads of ax to arbitrary constant address.
1348 ;; We fake an second form of instruction to force reload to load address
1349 ;; into register when rax is not available
1350 (define_insn "*movabshi_1_rex64"
1351 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1352 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1353 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1355 movabs{w}\t{%1, %P0|%P0, %1}
1356 mov{w}\t{%1, %a0|%a0, %1}"
1357 [(set_attr "type" "imov")
1358 (set_attr "modrm" "0,*")
1359 (set_attr "length_address" "8,0")
1360 (set_attr "length_immediate" "0,*")
1361 (set_attr "memory" "store")
1362 (set_attr "mode" "HI")])
1364 (define_insn "*movabshi_2_rex64"
1365 [(set (match_operand:HI 0 "register_operand" "=a,r")
1366 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1367 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1369 movabs{w}\t{%P1, %0|%0, %P1}
1370 mov{w}\t{%a1, %0|%0, %a1}"
1371 [(set_attr "type" "imov")
1372 (set_attr "modrm" "0,*")
1373 (set_attr "length_address" "8,0")
1374 (set_attr "length_immediate" "0")
1375 (set_attr "memory" "load")
1376 (set_attr "mode" "HI")])
1378 (define_insn "*swaphi_1"
1379 [(set (match_operand:HI 0 "register_operand" "+r")
1380 (match_operand:HI 1 "register_operand" "+r"))
1383 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1385 [(set_attr "type" "imov")
1386 (set_attr "mode" "SI")
1387 (set_attr "pent_pair" "np")
1388 (set_attr "athlon_decode" "vector")])
1390 (define_insn "*swaphi_2"
1391 [(set (match_operand:HI 0 "register_operand" "+r")
1392 (match_operand:HI 1 "register_operand" "+r"))
1395 "TARGET_PARTIAL_REG_STALL"
1397 [(set_attr "type" "imov")
1398 (set_attr "mode" "HI")
1399 (set_attr "pent_pair" "np")
1400 (set_attr "athlon_decode" "vector")])
1402 (define_expand "movstricthi"
1403 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1404 (match_operand:HI 1 "general_operand" ""))]
1405 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1407 /* Don't generate memory->memory moves, go through a register */
1408 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1409 operands[1] = force_reg (HImode, operands[1]);
1412 (define_insn "*movstricthi_1"
1413 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1414 (match_operand:HI 1 "general_operand" "rn,m"))]
1415 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1416 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1417 "mov{w}\t{%1, %0|%0, %1}"
1418 [(set_attr "type" "imov")
1419 (set_attr "mode" "HI")])
1421 (define_insn "*movstricthi_xor"
1422 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1423 (match_operand:HI 1 "const0_operand" "i"))
1424 (clobber (reg:CC FLAGS_REG))]
1426 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1427 "xor{w}\t{%0, %0|%0, %0}"
1428 [(set_attr "type" "alu1")
1429 (set_attr "mode" "HI")
1430 (set_attr "length_immediate" "0")])
1432 (define_expand "movqi"
1433 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1434 (match_operand:QI 1 "general_operand" ""))]
1436 "ix86_expand_move (QImode, operands); DONE;")
1438 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1439 ;; "push a byte". But actually we use pushl, which has the effect
1440 ;; of rounding the amount pushed up to a word.
1442 (define_insn "*pushqi2"
1443 [(set (match_operand:QI 0 "push_operand" "=X")
1444 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1447 [(set_attr "type" "push")
1448 (set_attr "mode" "SI")])
1450 ;; For 64BIT abi we always round up to 8 bytes.
1451 (define_insn "*pushqi2_rex64"
1452 [(set (match_operand:QI 0 "push_operand" "=X")
1453 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1456 [(set_attr "type" "push")
1457 (set_attr "mode" "DI")])
1459 ;; Situation is quite tricky about when to choose full sized (SImode) move
1460 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1461 ;; partial register dependency machines (such as AMD Athlon), where QImode
1462 ;; moves issue extra dependency and for partial register stalls machines
1463 ;; that don't use QImode patterns (and QImode move cause stall on the next
1466 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1467 ;; register stall machines with, where we use QImode instructions, since
1468 ;; partial register stall can be caused there. Then we use movzx.
1469 (define_insn "*movqi_1"
1470 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1471 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1472 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1474 switch (get_attr_type (insn))
1477 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
1478 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1480 if (get_attr_mode (insn) == MODE_SI)
1481 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1483 return "mov{b}\t{%1, %0|%0, %1}";
1487 (cond [(and (eq_attr "alternative" "5")
1488 (not (match_operand:QI 1 "aligned_operand" "")))
1489 (const_string "imovx")
1490 (ne (symbol_ref "optimize_size") (const_int 0))
1491 (const_string "imov")
1492 (and (eq_attr "alternative" "3")
1493 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1495 (eq (symbol_ref "TARGET_QIMODE_MATH")
1497 (const_string "imov")
1498 (eq_attr "alternative" "3,5")
1499 (const_string "imovx")
1500 (and (ne (symbol_ref "TARGET_MOVX")
1502 (eq_attr "alternative" "2"))
1503 (const_string "imovx")
1505 (const_string "imov")))
1507 (cond [(eq_attr "alternative" "3,4,5")
1509 (eq_attr "alternative" "6")
1511 (eq_attr "type" "imovx")
1513 (and (eq_attr "type" "imov")
1514 (and (eq_attr "alternative" "0,1")
1515 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1517 (and (eq (symbol_ref "optimize_size")
1519 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1522 ;; Avoid partial register stalls when not using QImode arithmetic
1523 (and (eq_attr "type" "imov")
1524 (and (eq_attr "alternative" "0,1")
1525 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1527 (eq (symbol_ref "TARGET_QIMODE_MATH")
1531 (const_string "QI")))])
1533 (define_expand "reload_outqi"
1534 [(parallel [(match_operand:QI 0 "" "=m")
1535 (match_operand:QI 1 "register_operand" "r")
1536 (match_operand:QI 2 "register_operand" "=&q")])]
1540 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1542 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1543 if (! q_regs_operand (op1, QImode))
1545 emit_insn (gen_movqi (op2, op1));
1548 emit_insn (gen_movqi (op0, op1));
1552 (define_insn "*swapqi_1"
1553 [(set (match_operand:QI 0 "register_operand" "+r")
1554 (match_operand:QI 1 "register_operand" "+r"))
1557 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1559 [(set_attr "type" "imov")
1560 (set_attr "mode" "SI")
1561 (set_attr "pent_pair" "np")
1562 (set_attr "athlon_decode" "vector")])
1564 (define_insn "*swapqi_2"
1565 [(set (match_operand:QI 0 "register_operand" "+q")
1566 (match_operand:QI 1 "register_operand" "+q"))
1569 "TARGET_PARTIAL_REG_STALL"
1571 [(set_attr "type" "imov")
1572 (set_attr "mode" "QI")
1573 (set_attr "pent_pair" "np")
1574 (set_attr "athlon_decode" "vector")])
1576 (define_expand "movstrictqi"
1577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1578 (match_operand:QI 1 "general_operand" ""))]
1579 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1581 /* Don't generate memory->memory moves, go through a register. */
1582 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
1583 operands[1] = force_reg (QImode, operands[1]);
1586 (define_insn "*movstrictqi_1"
1587 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1588 (match_operand:QI 1 "general_operand" "*qn,m"))]
1589 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1590 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
1591 "mov{b}\t{%1, %0|%0, %1}"
1592 [(set_attr "type" "imov")
1593 (set_attr "mode" "QI")])
1595 (define_insn "*movstrictqi_xor"
1596 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1597 (match_operand:QI 1 "const0_operand" "i"))
1598 (clobber (reg:CC FLAGS_REG))]
1599 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1600 "xor{b}\t{%0, %0|%0, %0}"
1601 [(set_attr "type" "alu1")
1602 (set_attr "mode" "QI")
1603 (set_attr "length_immediate" "0")])
1605 (define_insn "*movsi_extv_1"
1606 [(set (match_operand:SI 0 "register_operand" "=R")
1607 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1611 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1612 [(set_attr "type" "imovx")
1613 (set_attr "mode" "SI")])
1615 (define_insn "*movhi_extv_1"
1616 [(set (match_operand:HI 0 "register_operand" "=R")
1617 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1621 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1622 [(set_attr "type" "imovx")
1623 (set_attr "mode" "SI")])
1625 (define_insn "*movqi_extv_1"
1626 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1627 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1632 switch (get_attr_type (insn))
1635 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1637 return "mov{b}\t{%h1, %0|%0, %h1}";
1641 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1642 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1643 (ne (symbol_ref "TARGET_MOVX")
1645 (const_string "imovx")
1646 (const_string "imov")))
1648 (if_then_else (eq_attr "type" "imovx")
1650 (const_string "QI")))])
1652 (define_insn "*movqi_extv_1_rex64"
1653 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1654 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1659 switch (get_attr_type (insn))
1662 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1664 return "mov{b}\t{%h1, %0|%0, %h1}";
1668 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1669 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1670 (ne (symbol_ref "TARGET_MOVX")
1672 (const_string "imovx")
1673 (const_string "imov")))
1675 (if_then_else (eq_attr "type" "imovx")
1677 (const_string "QI")))])
1679 ;; Stores and loads of ax to arbitrary constant address.
1680 ;; We fake an second form of instruction to force reload to load address
1681 ;; into register when rax is not available
1682 (define_insn "*movabsqi_1_rex64"
1683 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1684 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1685 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1687 movabs{b}\t{%1, %P0|%P0, %1}
1688 mov{b}\t{%1, %a0|%a0, %1}"
1689 [(set_attr "type" "imov")
1690 (set_attr "modrm" "0,*")
1691 (set_attr "length_address" "8,0")
1692 (set_attr "length_immediate" "0,*")
1693 (set_attr "memory" "store")
1694 (set_attr "mode" "QI")])
1696 (define_insn "*movabsqi_2_rex64"
1697 [(set (match_operand:QI 0 "register_operand" "=a,r")
1698 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1699 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1701 movabs{b}\t{%P1, %0|%0, %P1}
1702 mov{b}\t{%a1, %0|%0, %a1}"
1703 [(set_attr "type" "imov")
1704 (set_attr "modrm" "0,*")
1705 (set_attr "length_address" "8,0")
1706 (set_attr "length_immediate" "0")
1707 (set_attr "memory" "load")
1708 (set_attr "mode" "QI")])
1710 (define_insn "*movdi_extzv_1"
1711 [(set (match_operand:DI 0 "register_operand" "=R")
1712 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1716 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1717 [(set_attr "type" "imovx")
1718 (set_attr "mode" "DI")])
1720 (define_insn "*movsi_extzv_1"
1721 [(set (match_operand:SI 0 "register_operand" "=R")
1722 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1726 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1727 [(set_attr "type" "imovx")
1728 (set_attr "mode" "SI")])
1730 (define_insn "*movqi_extzv_2"
1731 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1732 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1737 switch (get_attr_type (insn))
1740 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1742 return "mov{b}\t{%h1, %0|%0, %h1}";
1746 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1747 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1748 (ne (symbol_ref "TARGET_MOVX")
1750 (const_string "imovx")
1751 (const_string "imov")))
1753 (if_then_else (eq_attr "type" "imovx")
1755 (const_string "QI")))])
1757 (define_insn "*movqi_extzv_2_rex64"
1758 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1759 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1764 switch (get_attr_type (insn))
1767 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1769 return "mov{b}\t{%h1, %0|%0, %h1}";
1773 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1774 (ne (symbol_ref "TARGET_MOVX")
1776 (const_string "imovx")
1777 (const_string "imov")))
1779 (if_then_else (eq_attr "type" "imovx")
1781 (const_string "QI")))])
1783 (define_insn "movsi_insv_1"
1784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1787 (match_operand:SI 1 "general_operand" "Qmn"))]
1789 "mov{b}\t{%b1, %h0|%h0, %b1}"
1790 [(set_attr "type" "imov")
1791 (set_attr "mode" "QI")])
1793 (define_insn "movdi_insv_1_rex64"
1794 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1797 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1799 "mov{b}\t{%b1, %h0|%h0, %b1}"
1800 [(set_attr "type" "imov")
1801 (set_attr "mode" "QI")])
1803 (define_insn "*movqi_insv_2"
1804 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1807 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1810 "mov{b}\t{%h1, %h0|%h0, %h1}"
1811 [(set_attr "type" "imov")
1812 (set_attr "mode" "QI")])
1814 (define_expand "movdi"
1815 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1816 (match_operand:DI 1 "general_operand" ""))]
1818 "ix86_expand_move (DImode, operands); DONE;")
1820 (define_insn "*pushdi"
1821 [(set (match_operand:DI 0 "push_operand" "=<")
1822 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1826 (define_insn "*pushdi2_rex64"
1827 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1828 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1833 [(set_attr "type" "push,multi")
1834 (set_attr "mode" "DI")])
1836 ;; Convert impossible pushes of immediate to existing instructions.
1837 ;; First try to get scratch register and go through it. In case this
1838 ;; fails, push sign extended lower part first and then overwrite
1839 ;; upper part by 32bit move.
1841 [(match_scratch:DI 2 "r")
1842 (set (match_operand:DI 0 "push_operand" "")
1843 (match_operand:DI 1 "immediate_operand" ""))]
1844 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1845 && !x86_64_immediate_operand (operands[1], DImode)"
1846 [(set (match_dup 2) (match_dup 1))
1847 (set (match_dup 0) (match_dup 2))]
1850 ;; We need to define this as both peepholer and splitter for case
1851 ;; peephole2 pass is not run.
1852 ;; "&& 1" is needed to keep it from matching the previous pattern.
1854 [(set (match_operand:DI 0 "push_operand" "")
1855 (match_operand:DI 1 "immediate_operand" ""))]
1856 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1857 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1858 [(set (match_dup 0) (match_dup 1))
1859 (set (match_dup 2) (match_dup 3))]
1860 "split_di (operands + 1, 1, operands + 2, operands + 3);
1861 operands[1] = gen_lowpart (DImode, operands[2]);
1862 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1867 [(set (match_operand:DI 0 "push_operand" "")
1868 (match_operand:DI 1 "immediate_operand" ""))]
1869 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1870 ? flow2_completed : reload_completed)
1871 && !symbolic_operand (operands[1], DImode)
1872 && !x86_64_immediate_operand (operands[1], DImode)"
1873 [(set (match_dup 0) (match_dup 1))
1874 (set (match_dup 2) (match_dup 3))]
1875 "split_di (operands + 1, 1, operands + 2, operands + 3);
1876 operands[1] = gen_lowpart (DImode, operands[2]);
1877 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1881 (define_insn "*pushdi2_prologue_rex64"
1882 [(set (match_operand:DI 0 "push_operand" "=<")
1883 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1884 (clobber (mem:BLK (scratch)))]
1887 [(set_attr "type" "push")
1888 (set_attr "mode" "DI")])
1890 (define_insn "*popdi1_epilogue_rex64"
1891 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1892 (mem:DI (reg:DI SP_REG)))
1893 (set (reg:DI SP_REG)
1894 (plus:DI (reg:DI SP_REG) (const_int 8)))
1895 (clobber (mem:BLK (scratch)))]
1898 [(set_attr "type" "pop")
1899 (set_attr "mode" "DI")])
1901 (define_insn "popdi1"
1902 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1903 (mem:DI (reg:DI SP_REG)))
1904 (set (reg:DI SP_REG)
1905 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1908 [(set_attr "type" "pop")
1909 (set_attr "mode" "DI")])
1911 (define_insn "*movdi_xor_rex64"
1912 [(set (match_operand:DI 0 "register_operand" "=r")
1913 (match_operand:DI 1 "const0_operand" "i"))
1914 (clobber (reg:CC FLAGS_REG))]
1915 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1916 && reload_completed"
1917 "xor{l}\t{%k0, %k0|%k0, %k0}"
1918 [(set_attr "type" "alu1")
1919 (set_attr "mode" "SI")
1920 (set_attr "length_immediate" "0")])
1922 (define_insn "*movdi_or_rex64"
1923 [(set (match_operand:DI 0 "register_operand" "=r")
1924 (match_operand:DI 1 "const_int_operand" "i"))
1925 (clobber (reg:CC FLAGS_REG))]
1926 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1928 && operands[1] == constm1_rtx"
1930 operands[1] = constm1_rtx;
1931 return "or{q}\t{%1, %0|%0, %1}";
1933 [(set_attr "type" "alu1")
1934 (set_attr "mode" "DI")
1935 (set_attr "length_immediate" "1")])
1937 (define_insn "*movdi_2"
1938 [(set (match_operand:DI 0 "nonimmediate_operand"
1939 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1940 (match_operand:DI 1 "general_operand"
1941 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1942 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1947 movq\t{%1, %0|%0, %1}
1948 movq\t{%1, %0|%0, %1}
1950 movq\t{%1, %0|%0, %1}
1951 movdqa\t{%1, %0|%0, %1}
1952 movq\t{%1, %0|%0, %1}
1954 movlps\t{%1, %0|%0, %1}
1955 movaps\t{%1, %0|%0, %1}
1956 movlps\t{%1, %0|%0, %1}"
1957 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1958 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1961 [(set (match_operand:DI 0 "push_operand" "")
1962 (match_operand:DI 1 "general_operand" ""))]
1963 "!TARGET_64BIT && reload_completed
1964 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1966 "ix86_split_long_move (operands); DONE;")
1968 ;; %%% This multiword shite has got to go.
1970 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1971 (match_operand:DI 1 "general_operand" ""))]
1972 "!TARGET_64BIT && reload_completed
1973 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1974 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1976 "ix86_split_long_move (operands); DONE;")
1978 (define_insn "*movdi_1_rex64"
1979 [(set (match_operand:DI 0 "nonimmediate_operand"
1980 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1981 (match_operand:DI 1 "general_operand"
1982 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1983 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1985 switch (get_attr_type (insn))
1988 if (which_alternative == 13)
1989 return "movq2dq\t{%1, %0|%0, %1}";
1991 return "movdq2q\t{%1, %0|%0, %1}";
1993 if (get_attr_mode (insn) == MODE_TI)
1994 return "movdqa\t{%1, %0|%0, %1}";
1997 /* Moves from and into integer register is done using movd opcode with
1999 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2000 return "movd\t{%1, %0|%0, %1}";
2001 return "movq\t{%1, %0|%0, %1}";
2004 return "pxor\t%0, %0";
2008 return "lea{q}\t{%a1, %0|%0, %a1}";
2010 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2011 if (get_attr_mode (insn) == MODE_SI)
2012 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2013 else if (which_alternative == 2)
2014 return "movabs{q}\t{%1, %0|%0, %1}";
2016 return "mov{q}\t{%1, %0|%0, %1}";
2020 (cond [(eq_attr "alternative" "5")
2021 (const_string "mmxadd")
2022 (eq_attr "alternative" "6,7,8")
2023 (const_string "mmxmov")
2024 (eq_attr "alternative" "9")
2025 (const_string "sselog1")
2026 (eq_attr "alternative" "10,11,12")
2027 (const_string "ssemov")
2028 (eq_attr "alternative" "13,14")
2029 (const_string "ssecvt")
2030 (eq_attr "alternative" "4")
2031 (const_string "multi")
2032 (match_operand:DI 1 "pic_32bit_operand" "")
2033 (const_string "lea")
2035 (const_string "imov")))
2036 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2037 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2038 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2040 ;; Stores and loads of ax to arbitrary constant address.
2041 ;; We fake an second form of instruction to force reload to load address
2042 ;; into register when rax is not available
2043 (define_insn "*movabsdi_1_rex64"
2044 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2045 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2046 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2048 movabs{q}\t{%1, %P0|%P0, %1}
2049 mov{q}\t{%1, %a0|%a0, %1}"
2050 [(set_attr "type" "imov")
2051 (set_attr "modrm" "0,*")
2052 (set_attr "length_address" "8,0")
2053 (set_attr "length_immediate" "0,*")
2054 (set_attr "memory" "store")
2055 (set_attr "mode" "DI")])
2057 (define_insn "*movabsdi_2_rex64"
2058 [(set (match_operand:DI 0 "register_operand" "=a,r")
2059 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2060 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2062 movabs{q}\t{%P1, %0|%0, %P1}
2063 mov{q}\t{%a1, %0|%0, %a1}"
2064 [(set_attr "type" "imov")
2065 (set_attr "modrm" "0,*")
2066 (set_attr "length_address" "8,0")
2067 (set_attr "length_immediate" "0")
2068 (set_attr "memory" "load")
2069 (set_attr "mode" "DI")])
2071 ;; Convert impossible stores of immediate to existing instructions.
2072 ;; First try to get scratch register and go through it. In case this
2073 ;; fails, move by 32bit parts.
2075 [(match_scratch:DI 2 "r")
2076 (set (match_operand:DI 0 "memory_operand" "")
2077 (match_operand:DI 1 "immediate_operand" ""))]
2078 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079 && !x86_64_immediate_operand (operands[1], DImode)"
2080 [(set (match_dup 2) (match_dup 1))
2081 (set (match_dup 0) (match_dup 2))]
2084 ;; We need to define this as both peepholer and splitter for case
2085 ;; peephole2 pass is not run.
2086 ;; "&& 1" is needed to keep it from matching the previous pattern.
2088 [(set (match_operand:DI 0 "memory_operand" "")
2089 (match_operand:DI 1 "immediate_operand" ""))]
2090 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2091 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2092 [(set (match_dup 2) (match_dup 3))
2093 (set (match_dup 4) (match_dup 5))]
2094 "split_di (operands, 2, operands + 2, operands + 4);")
2097 [(set (match_operand:DI 0 "memory_operand" "")
2098 (match_operand:DI 1 "immediate_operand" ""))]
2099 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2100 ? flow2_completed : reload_completed)
2101 && !symbolic_operand (operands[1], DImode)
2102 && !x86_64_immediate_operand (operands[1], DImode)"
2103 [(set (match_dup 2) (match_dup 3))
2104 (set (match_dup 4) (match_dup 5))]
2105 "split_di (operands, 2, operands + 2, operands + 4);")
2107 (define_insn "*swapdi_rex64"
2108 [(set (match_operand:DI 0 "register_operand" "+r")
2109 (match_operand:DI 1 "register_operand" "+r"))
2114 [(set_attr "type" "imov")
2115 (set_attr "mode" "DI")
2116 (set_attr "pent_pair" "np")
2117 (set_attr "athlon_decode" "vector")])
2119 (define_expand "movti"
2120 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2121 (match_operand:TI 1 "nonimmediate_operand" ""))]
2122 "TARGET_SSE || TARGET_64BIT"
2125 ix86_expand_move (TImode, operands);
2127 ix86_expand_vector_move (TImode, operands);
2131 (define_insn "*movti_internal"
2132 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2133 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2134 "TARGET_SSE && !TARGET_64BIT
2135 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2137 switch (which_alternative)
2140 if (get_attr_mode (insn) == MODE_V4SF)
2141 return "xorps\t%0, %0";
2143 return "pxor\t%0, %0";
2146 if (get_attr_mode (insn) == MODE_V4SF)
2147 return "movaps\t{%1, %0|%0, %1}";
2149 return "movdqa\t{%1, %0|%0, %1}";
2154 [(set_attr "type" "sselog1,ssemov,ssemov")
2156 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2157 (ne (symbol_ref "optimize_size") (const_int 0)))
2158 (const_string "V4SF")
2159 (and (eq_attr "alternative" "2")
2160 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2162 (const_string "V4SF")]
2163 (const_string "TI")))])
2165 (define_insn "*movti_rex64"
2166 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2167 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2169 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2171 switch (which_alternative)
2177 if (get_attr_mode (insn) == MODE_V4SF)
2178 return "xorps\t%0, %0";
2180 return "pxor\t%0, %0";
2183 if (get_attr_mode (insn) == MODE_V4SF)
2184 return "movaps\t{%1, %0|%0, %1}";
2186 return "movdqa\t{%1, %0|%0, %1}";
2191 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2193 (cond [(eq_attr "alternative" "2,3")
2195 (ne (symbol_ref "optimize_size")
2197 (const_string "V4SF")
2198 (const_string "TI"))
2199 (eq_attr "alternative" "4")
2201 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2203 (ne (symbol_ref "optimize_size")
2205 (const_string "V4SF")
2206 (const_string "TI"))]
2207 (const_string "DI")))])
2210 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2211 (match_operand:TI 1 "general_operand" ""))]
2212 "reload_completed && !SSE_REG_P (operands[0])
2213 && !SSE_REG_P (operands[1])"
2215 "ix86_split_long_move (operands); DONE;")
2217 (define_expand "movsf"
2218 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2219 (match_operand:SF 1 "general_operand" ""))]
2221 "ix86_expand_move (SFmode, operands); DONE;")
2223 (define_insn "*pushsf"
2224 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2225 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2228 /* Anything else should be already split before reg-stack. */
2229 gcc_assert (which_alternative == 1);
2230 return "push{l}\t%1";
2232 [(set_attr "type" "multi,push,multi")
2233 (set_attr "unit" "i387,*,*")
2234 (set_attr "mode" "SF,SI,SF")])
2236 (define_insn "*pushsf_rex64"
2237 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2238 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2241 /* Anything else should be already split before reg-stack. */
2242 gcc_assert (which_alternative == 1);
2243 return "push{q}\t%q1";
2245 [(set_attr "type" "multi,push,multi")
2246 (set_attr "unit" "i387,*,*")
2247 (set_attr "mode" "SF,DI,SF")])
2250 [(set (match_operand:SF 0 "push_operand" "")
2251 (match_operand:SF 1 "memory_operand" ""))]
2253 && GET_CODE (operands[1]) == MEM
2254 && constant_pool_reference_p (operands[1])"
2257 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2260 ;; %%% Kill this when call knows how to work this out.
2262 [(set (match_operand:SF 0 "push_operand" "")
2263 (match_operand:SF 1 "any_fp_register_operand" ""))]
2265 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2266 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2269 [(set (match_operand:SF 0 "push_operand" "")
2270 (match_operand:SF 1 "any_fp_register_operand" ""))]
2272 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2273 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2275 (define_insn "*movsf_1"
2276 [(set (match_operand:SF 0 "nonimmediate_operand"
2277 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2278 (match_operand:SF 1 "general_operand"
2279 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2280 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2281 && (reload_in_progress || reload_completed
2282 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2283 || GET_CODE (operands[1]) != CONST_DOUBLE
2284 || memory_operand (operands[0], SFmode))"
2286 switch (which_alternative)
2289 return output_387_reg_move (insn, operands);
2292 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2293 return "fstp%z0\t%y0";
2295 return "fst%z0\t%y0";
2298 return standard_80387_constant_opcode (operands[1]);
2302 return "mov{l}\t{%1, %0|%0, %1}";
2304 if (get_attr_mode (insn) == MODE_TI)
2305 return "pxor\t%0, %0";
2307 return "xorps\t%0, %0";
2309 if (get_attr_mode (insn) == MODE_V4SF)
2310 return "movaps\t{%1, %0|%0, %1}";
2312 return "movss\t{%1, %0|%0, %1}";
2315 return "movss\t{%1, %0|%0, %1}";
2319 return "movd\t{%1, %0|%0, %1}";
2322 return "movq\t{%1, %0|%0, %1}";
2328 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2330 (cond [(eq_attr "alternative" "3,4,9,10")
2332 (eq_attr "alternative" "5")
2334 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2336 (ne (symbol_ref "TARGET_SSE2")
2338 (eq (symbol_ref "optimize_size")
2341 (const_string "V4SF"))
2342 /* For architectures resolving dependencies on
2343 whole SSE registers use APS move to break dependency
2344 chains, otherwise use short move to avoid extra work.
2346 Do the same for architectures resolving dependencies on
2347 the parts. While in DF mode it is better to always handle
2348 just register parts, the SF mode is different due to lack
2349 of instructions to load just part of the register. It is
2350 better to maintain the whole registers in single format
2351 to avoid problems on using packed logical operations. */
2352 (eq_attr "alternative" "6")
2354 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2356 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2358 (const_string "V4SF")
2359 (const_string "SF"))
2360 (eq_attr "alternative" "11")
2361 (const_string "DI")]
2362 (const_string "SF")))])
2364 (define_insn "*swapsf"
2365 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2366 (match_operand:SF 1 "fp_register_operand" "+f"))
2369 "reload_completed || TARGET_80387"
2371 if (STACK_TOP_P (operands[0]))
2376 [(set_attr "type" "fxch")
2377 (set_attr "mode" "SF")])
2379 (define_expand "movdf"
2380 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2381 (match_operand:DF 1 "general_operand" ""))]
2383 "ix86_expand_move (DFmode, operands); DONE;")
2385 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2386 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2387 ;; On the average, pushdf using integers can be still shorter. Allow this
2388 ;; pattern for optimize_size too.
2390 (define_insn "*pushdf_nointeger"
2391 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2392 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2393 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2395 /* This insn should be already split before reg-stack. */
2398 [(set_attr "type" "multi")
2399 (set_attr "unit" "i387,*,*,*")
2400 (set_attr "mode" "DF,SI,SI,DF")])
2402 (define_insn "*pushdf_integer"
2403 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2404 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2405 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2407 /* This insn should be already split before reg-stack. */
2410 [(set_attr "type" "multi")
2411 (set_attr "unit" "i387,*,*")
2412 (set_attr "mode" "DF,SI,DF")])
2414 ;; %%% Kill this when call knows how to work this out.
2416 [(set (match_operand:DF 0 "push_operand" "")
2417 (match_operand:DF 1 "any_fp_register_operand" ""))]
2418 "!TARGET_64BIT && reload_completed"
2419 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2420 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2424 [(set (match_operand:DF 0 "push_operand" "")
2425 (match_operand:DF 1 "any_fp_register_operand" ""))]
2426 "TARGET_64BIT && reload_completed"
2427 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2428 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2432 [(set (match_operand:DF 0 "push_operand" "")
2433 (match_operand:DF 1 "general_operand" ""))]
2436 "ix86_split_long_move (operands); DONE;")
2438 ;; Moving is usually shorter when only FP registers are used. This separate
2439 ;; movdf pattern avoids the use of integer registers for FP operations
2440 ;; when optimizing for size.
2442 (define_insn "*movdf_nointeger"
2443 [(set (match_operand:DF 0 "nonimmediate_operand"
2444 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2445 (match_operand:DF 1 "general_operand"
2446 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2447 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2448 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2449 && (reload_in_progress || reload_completed
2450 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2451 || GET_CODE (operands[1]) != CONST_DOUBLE
2452 || memory_operand (operands[0], DFmode))"
2454 switch (which_alternative)
2457 return output_387_reg_move (insn, operands);
2460 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2461 return "fstp%z0\t%y0";
2463 return "fst%z0\t%y0";
2466 return standard_80387_constant_opcode (operands[1]);
2472 switch (get_attr_mode (insn))
2475 return "xorps\t%0, %0";
2477 return "xorpd\t%0, %0";
2479 return "pxor\t%0, %0";
2486 switch (get_attr_mode (insn))
2489 return "movaps\t{%1, %0|%0, %1}";
2491 return "movapd\t{%1, %0|%0, %1}";
2493 return "movdqa\t{%1, %0|%0, %1}";
2495 return "movq\t{%1, %0|%0, %1}";
2497 return "movsd\t{%1, %0|%0, %1}";
2499 return "movlpd\t{%1, %0|%0, %1}";
2501 return "movlps\t{%1, %0|%0, %1}";
2510 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2512 (cond [(eq_attr "alternative" "0,1,2")
2514 (eq_attr "alternative" "3,4")
2517 /* For SSE1, we have many fewer alternatives. */
2518 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2519 (cond [(eq_attr "alternative" "5,6")
2520 (const_string "V4SF")
2522 (const_string "V2SF"))
2524 /* xorps is one byte shorter. */
2525 (eq_attr "alternative" "5")
2526 (cond [(ne (symbol_ref "optimize_size")
2528 (const_string "V4SF")
2529 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2533 (const_string "V2DF"))
2535 /* For architectures resolving dependencies on
2536 whole SSE registers use APD move to break dependency
2537 chains, otherwise use short move to avoid extra work.
2539 movaps encodes one byte shorter. */
2540 (eq_attr "alternative" "6")
2542 [(ne (symbol_ref "optimize_size")
2544 (const_string "V4SF")
2545 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2547 (const_string "V2DF")
2549 (const_string "DF"))
2550 /* For architectures resolving dependencies on register
2551 parts we may avoid extra work to zero out upper part
2553 (eq_attr "alternative" "7")
2555 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2557 (const_string "V1DF")
2558 (const_string "DF"))
2560 (const_string "DF")))])
2562 (define_insn "*movdf_integer"
2563 [(set (match_operand:DF 0 "nonimmediate_operand"
2564 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2565 (match_operand:DF 1 "general_operand"
2566 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2567 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2568 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2569 && (reload_in_progress || reload_completed
2570 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2571 || GET_CODE (operands[1]) != CONST_DOUBLE
2572 || memory_operand (operands[0], DFmode))"
2574 switch (which_alternative)
2577 return output_387_reg_move (insn, operands);
2580 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2581 return "fstp%z0\t%y0";
2583 return "fst%z0\t%y0";
2586 return standard_80387_constant_opcode (operands[1]);
2593 switch (get_attr_mode (insn))
2596 return "xorps\t%0, %0";
2598 return "xorpd\t%0, %0";
2600 return "pxor\t%0, %0";
2607 switch (get_attr_mode (insn))
2610 return "movaps\t{%1, %0|%0, %1}";
2612 return "movapd\t{%1, %0|%0, %1}";
2614 return "movdqa\t{%1, %0|%0, %1}";
2616 return "movq\t{%1, %0|%0, %1}";
2618 return "movsd\t{%1, %0|%0, %1}";
2620 return "movlpd\t{%1, %0|%0, %1}";
2622 return "movlps\t{%1, %0|%0, %1}";
2631 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2633 (cond [(eq_attr "alternative" "0,1,2")
2635 (eq_attr "alternative" "3,4")
2638 /* For SSE1, we have many fewer alternatives. */
2639 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2640 (cond [(eq_attr "alternative" "5,6")
2641 (const_string "V4SF")
2643 (const_string "V2SF"))
2645 /* xorps is one byte shorter. */
2646 (eq_attr "alternative" "5")
2647 (cond [(ne (symbol_ref "optimize_size")
2649 (const_string "V4SF")
2650 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2654 (const_string "V2DF"))
2656 /* For architectures resolving dependencies on
2657 whole SSE registers use APD move to break dependency
2658 chains, otherwise use short move to avoid extra work.
2660 movaps encodes one byte shorter. */
2661 (eq_attr "alternative" "6")
2663 [(ne (symbol_ref "optimize_size")
2665 (const_string "V4SF")
2666 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2668 (const_string "V2DF")
2670 (const_string "DF"))
2671 /* For architectures resolving dependencies on register
2672 parts we may avoid extra work to zero out upper part
2674 (eq_attr "alternative" "7")
2676 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2678 (const_string "V1DF")
2679 (const_string "DF"))
2681 (const_string "DF")))])
2684 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2685 (match_operand:DF 1 "general_operand" ""))]
2687 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2688 && ! (ANY_FP_REG_P (operands[0]) ||
2689 (GET_CODE (operands[0]) == SUBREG
2690 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2691 && ! (ANY_FP_REG_P (operands[1]) ||
2692 (GET_CODE (operands[1]) == SUBREG
2693 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2695 "ix86_split_long_move (operands); DONE;")
2697 (define_insn "*swapdf"
2698 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2699 (match_operand:DF 1 "fp_register_operand" "+f"))
2702 "reload_completed || TARGET_80387"
2704 if (STACK_TOP_P (operands[0]))
2709 [(set_attr "type" "fxch")
2710 (set_attr "mode" "DF")])
2712 (define_expand "movxf"
2713 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2714 (match_operand:XF 1 "general_operand" ""))]
2716 "ix86_expand_move (XFmode, operands); DONE;")
2718 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2719 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2720 ;; Pushing using integer instructions is longer except for constants
2721 ;; and direct memory references.
2722 ;; (assuming that any given constant is pushed only once, but this ought to be
2723 ;; handled elsewhere).
2725 (define_insn "*pushxf_nointeger"
2726 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2727 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2730 /* This insn should be already split before reg-stack. */
2733 [(set_attr "type" "multi")
2734 (set_attr "unit" "i387,*,*")
2735 (set_attr "mode" "XF,SI,SI")])
2737 (define_insn "*pushxf_integer"
2738 [(set (match_operand:XF 0 "push_operand" "=<,<")
2739 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2742 /* This insn should be already split before reg-stack. */
2745 [(set_attr "type" "multi")
2746 (set_attr "unit" "i387,*")
2747 (set_attr "mode" "XF,SI")])
2750 [(set (match_operand 0 "push_operand" "")
2751 (match_operand 1 "general_operand" ""))]
2753 && (GET_MODE (operands[0]) == XFmode
2754 || GET_MODE (operands[0]) == DFmode)
2755 && !ANY_FP_REG_P (operands[1])"
2757 "ix86_split_long_move (operands); DONE;")
2760 [(set (match_operand:XF 0 "push_operand" "")
2761 (match_operand:XF 1 "any_fp_register_operand" ""))]
2763 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2764 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2765 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2768 [(set (match_operand:XF 0 "push_operand" "")
2769 (match_operand:XF 1 "any_fp_register_operand" ""))]
2771 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2772 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2773 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2775 ;; Do not use integer registers when optimizing for size
2776 (define_insn "*movxf_nointeger"
2777 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2778 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2780 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2781 && (reload_in_progress || reload_completed
2782 || GET_CODE (operands[1]) != CONST_DOUBLE
2783 || memory_operand (operands[0], XFmode))"
2785 switch (which_alternative)
2788 return output_387_reg_move (insn, operands);
2791 /* There is no non-popping store to memory for XFmode. So if
2792 we need one, follow the store with a load. */
2793 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2794 return "fstp%z0\t%y0\;fld%z0\t%y0";
2796 return "fstp%z0\t%y0";
2799 return standard_80387_constant_opcode (operands[1]);
2807 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2808 (set_attr "mode" "XF,XF,XF,SI,SI")])
2810 (define_insn "*movxf_integer"
2811 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2812 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2814 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2815 && (reload_in_progress || reload_completed
2816 || GET_CODE (operands[1]) != CONST_DOUBLE
2817 || memory_operand (operands[0], XFmode))"
2819 switch (which_alternative)
2822 return output_387_reg_move (insn, operands);
2825 /* There is no non-popping store to memory for XFmode. So if
2826 we need one, follow the store with a load. */
2827 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2828 return "fstp%z0\t%y0\;fld%z0\t%y0";
2830 return "fstp%z0\t%y0";
2833 return standard_80387_constant_opcode (operands[1]);
2842 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2843 (set_attr "mode" "XF,XF,XF,SI,SI")])
2846 [(set (match_operand 0 "nonimmediate_operand" "")
2847 (match_operand 1 "general_operand" ""))]
2849 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2850 && GET_MODE (operands[0]) == XFmode
2851 && ! (ANY_FP_REG_P (operands[0]) ||
2852 (GET_CODE (operands[0]) == SUBREG
2853 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2854 && ! (ANY_FP_REG_P (operands[1]) ||
2855 (GET_CODE (operands[1]) == SUBREG
2856 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2858 "ix86_split_long_move (operands); DONE;")
2861 [(set (match_operand 0 "register_operand" "")
2862 (match_operand 1 "memory_operand" ""))]
2864 && GET_CODE (operands[1]) == MEM
2865 && (GET_MODE (operands[0]) == XFmode
2866 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2867 && constant_pool_reference_p (operands[1])"
2868 [(set (match_dup 0) (match_dup 1))]
2870 rtx c = avoid_constant_pool_reference (operands[1]);
2871 rtx r = operands[0];
2873 if (GET_CODE (r) == SUBREG)
2878 if (!standard_sse_constant_p (c))
2881 else if (FP_REG_P (r))
2883 if (!standard_80387_constant_p (c))
2886 else if (MMX_REG_P (r))
2892 (define_insn "swapxf"
2893 [(set (match_operand:XF 0 "register_operand" "+f")
2894 (match_operand:XF 1 "register_operand" "+f"))
2899 if (STACK_TOP_P (operands[0]))
2904 [(set_attr "type" "fxch")
2905 (set_attr "mode" "XF")])
2907 (define_expand "movtf"
2908 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2909 (match_operand:TF 1 "nonimmediate_operand" ""))]
2912 ix86_expand_move (TFmode, operands);
2916 (define_insn "*movtf_internal"
2917 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2918 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2920 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2922 switch (which_alternative)
2928 if (get_attr_mode (insn) == MODE_V4SF)
2929 return "xorps\t%0, %0";
2931 return "pxor\t%0, %0";
2934 if (get_attr_mode (insn) == MODE_V4SF)
2935 return "movaps\t{%1, %0|%0, %1}";
2937 return "movdqa\t{%1, %0|%0, %1}";
2942 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2944 (cond [(eq_attr "alternative" "2,3")
2946 (ne (symbol_ref "optimize_size")
2948 (const_string "V4SF")
2949 (const_string "TI"))
2950 (eq_attr "alternative" "4")
2952 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2954 (ne (symbol_ref "optimize_size")
2956 (const_string "V4SF")
2957 (const_string "TI"))]
2958 (const_string "DI")))])
2961 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2962 (match_operand:TF 1 "general_operand" ""))]
2963 "reload_completed && !SSE_REG_P (operands[0])
2964 && !SSE_REG_P (operands[1])"
2966 "ix86_split_long_move (operands); DONE;")
2968 ;; Zero extension instructions
2970 (define_expand "zero_extendhisi2"
2971 [(set (match_operand:SI 0 "register_operand" "")
2972 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
2975 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
2977 operands[1] = force_reg (HImode, operands[1]);
2978 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
2983 (define_insn "zero_extendhisi2_and"
2984 [(set (match_operand:SI 0 "register_operand" "=r")
2985 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
2986 (clobber (reg:CC FLAGS_REG))]
2987 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2989 [(set_attr "type" "alu1")
2990 (set_attr "mode" "SI")])
2993 [(set (match_operand:SI 0 "register_operand" "")
2994 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
2995 (clobber (reg:CC FLAGS_REG))]
2996 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
2997 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
2998 (clobber (reg:CC FLAGS_REG))])]
3001 (define_insn "*zero_extendhisi2_movzwl"
3002 [(set (match_operand:SI 0 "register_operand" "=r")
3003 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3004 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3005 "movz{wl|x}\t{%1, %0|%0, %1}"
3006 [(set_attr "type" "imovx")
3007 (set_attr "mode" "SI")])
3009 (define_expand "zero_extendqihi2"
3011 [(set (match_operand:HI 0 "register_operand" "")
3012 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3013 (clobber (reg:CC FLAGS_REG))])]
3017 (define_insn "*zero_extendqihi2_and"
3018 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3019 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3020 (clobber (reg:CC FLAGS_REG))]
3021 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3023 [(set_attr "type" "alu1")
3024 (set_attr "mode" "HI")])
3026 (define_insn "*zero_extendqihi2_movzbw_and"
3027 [(set (match_operand:HI 0 "register_operand" "=r,r")
3028 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3029 (clobber (reg:CC FLAGS_REG))]
3030 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3032 [(set_attr "type" "imovx,alu1")
3033 (set_attr "mode" "HI")])
3035 ; zero extend to SImode here to avoid partial register stalls
3036 (define_insn "*zero_extendqihi2_movzbl"
3037 [(set (match_operand:HI 0 "register_operand" "=r")
3038 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3039 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3040 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3041 [(set_attr "type" "imovx")
3042 (set_attr "mode" "SI")])
3044 ;; For the movzbw case strip only the clobber
3046 [(set (match_operand:HI 0 "register_operand" "")
3047 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3048 (clobber (reg:CC FLAGS_REG))]
3050 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3051 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3052 [(set (match_operand:HI 0 "register_operand" "")
3053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3055 ;; When source and destination does not overlap, clear destination
3056 ;; first and then do the movb
3058 [(set (match_operand:HI 0 "register_operand" "")
3059 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3060 (clobber (reg:CC FLAGS_REG))]
3062 && ANY_QI_REG_P (operands[0])
3063 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3064 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3065 [(set (match_dup 0) (const_int 0))
3066 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3067 "operands[2] = gen_lowpart (QImode, operands[0]);")
3069 ;; Rest is handled by single and.
3071 [(set (match_operand:HI 0 "register_operand" "")
3072 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3073 (clobber (reg:CC FLAGS_REG))]
3075 && true_regnum (operands[0]) == true_regnum (operands[1])"
3076 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3077 (clobber (reg:CC FLAGS_REG))])]
3080 (define_expand "zero_extendqisi2"
3082 [(set (match_operand:SI 0 "register_operand" "")
3083 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3084 (clobber (reg:CC FLAGS_REG))])]
3088 (define_insn "*zero_extendqisi2_and"
3089 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3090 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3091 (clobber (reg:CC FLAGS_REG))]
3092 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3094 [(set_attr "type" "alu1")
3095 (set_attr "mode" "SI")])
3097 (define_insn "*zero_extendqisi2_movzbw_and"
3098 [(set (match_operand:SI 0 "register_operand" "=r,r")
3099 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3100 (clobber (reg:CC FLAGS_REG))]
3101 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3103 [(set_attr "type" "imovx,alu1")
3104 (set_attr "mode" "SI")])
3106 (define_insn "*zero_extendqisi2_movzbw"
3107 [(set (match_operand:SI 0 "register_operand" "=r")
3108 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3109 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3110 "movz{bl|x}\t{%1, %0|%0, %1}"
3111 [(set_attr "type" "imovx")
3112 (set_attr "mode" "SI")])
3114 ;; For the movzbl case strip only the clobber
3116 [(set (match_operand:SI 0 "register_operand" "")
3117 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3118 (clobber (reg:CC FLAGS_REG))]
3120 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3121 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3123 (zero_extend:SI (match_dup 1)))])
3125 ;; When source and destination does not overlap, clear destination
3126 ;; first and then do the movb
3128 [(set (match_operand:SI 0 "register_operand" "")
3129 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3130 (clobber (reg:CC FLAGS_REG))]
3132 && ANY_QI_REG_P (operands[0])
3133 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3134 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3135 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3136 [(set (match_dup 0) (const_int 0))
3137 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3138 "operands[2] = gen_lowpart (QImode, operands[0]);")
3140 ;; Rest is handled by single and.
3142 [(set (match_operand:SI 0 "register_operand" "")
3143 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3144 (clobber (reg:CC FLAGS_REG))]
3146 && true_regnum (operands[0]) == true_regnum (operands[1])"
3147 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3148 (clobber (reg:CC FLAGS_REG))])]
3151 ;; %%% Kill me once multi-word ops are sane.
3152 (define_expand "zero_extendsidi2"
3153 [(set (match_operand:DI 0 "register_operand" "=r")
3154 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3158 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3163 (define_insn "zero_extendsidi2_32"
3164 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3165 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3166 (clobber (reg:CC FLAGS_REG))]
3172 movd\t{%1, %0|%0, %1}
3173 movd\t{%1, %0|%0, %1}"
3174 [(set_attr "mode" "SI,SI,SI,DI,TI")
3175 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3177 (define_insn "zero_extendsidi2_rex64"
3178 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3179 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3182 mov\t{%k1, %k0|%k0, %k1}
3184 movd\t{%1, %0|%0, %1}
3185 movd\t{%1, %0|%0, %1}"
3186 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3187 (set_attr "mode" "SI,DI,SI,SI")])
3190 [(set (match_operand:DI 0 "memory_operand" "")
3191 (zero_extend:DI (match_dup 0)))]
3193 [(set (match_dup 4) (const_int 0))]
3194 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3197 [(set (match_operand:DI 0 "register_operand" "")
3198 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3199 (clobber (reg:CC FLAGS_REG))]
3200 "!TARGET_64BIT && reload_completed
3201 && true_regnum (operands[0]) == true_regnum (operands[1])"
3202 [(set (match_dup 4) (const_int 0))]
3203 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3206 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3207 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3208 (clobber (reg:CC FLAGS_REG))]
3209 "!TARGET_64BIT && reload_completed
3210 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3211 [(set (match_dup 3) (match_dup 1))
3212 (set (match_dup 4) (const_int 0))]
3213 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3215 (define_insn "zero_extendhidi2"
3216 [(set (match_operand:DI 0 "register_operand" "=r")
3217 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3219 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3220 [(set_attr "type" "imovx")
3221 (set_attr "mode" "DI")])
3223 (define_insn "zero_extendqidi2"
3224 [(set (match_operand:DI 0 "register_operand" "=r")
3225 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3227 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3228 [(set_attr "type" "imovx")
3229 (set_attr "mode" "DI")])
3231 ;; Sign extension instructions
3233 (define_expand "extendsidi2"
3234 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3235 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3236 (clobber (reg:CC FLAGS_REG))
3237 (clobber (match_scratch:SI 2 ""))])]
3242 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3247 (define_insn "*extendsidi2_1"
3248 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3249 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3250 (clobber (reg:CC FLAGS_REG))
3251 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3255 (define_insn "extendsidi2_rex64"
3256 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3257 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3261 movs{lq|x}\t{%1,%0|%0, %1}"
3262 [(set_attr "type" "imovx")
3263 (set_attr "mode" "DI")
3264 (set_attr "prefix_0f" "0")
3265 (set_attr "modrm" "0,1")])
3267 (define_insn "extendhidi2"
3268 [(set (match_operand:DI 0 "register_operand" "=r")
3269 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3271 "movs{wq|x}\t{%1,%0|%0, %1}"
3272 [(set_attr "type" "imovx")
3273 (set_attr "mode" "DI")])
3275 (define_insn "extendqidi2"
3276 [(set (match_operand:DI 0 "register_operand" "=r")
3277 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3279 "movs{bq|x}\t{%1,%0|%0, %1}"
3280 [(set_attr "type" "imovx")
3281 (set_attr "mode" "DI")])
3283 ;; Extend to memory case when source register does die.
3285 [(set (match_operand:DI 0 "memory_operand" "")
3286 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3287 (clobber (reg:CC FLAGS_REG))
3288 (clobber (match_operand:SI 2 "register_operand" ""))]
3290 && dead_or_set_p (insn, operands[1])
3291 && !reg_mentioned_p (operands[1], operands[0]))"
3292 [(set (match_dup 3) (match_dup 1))
3293 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3294 (clobber (reg:CC FLAGS_REG))])
3295 (set (match_dup 4) (match_dup 1))]
3296 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3298 ;; Extend to memory case when source register does not die.
3300 [(set (match_operand:DI 0 "memory_operand" "")
3301 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3302 (clobber (reg:CC FLAGS_REG))
3303 (clobber (match_operand:SI 2 "register_operand" ""))]
3307 split_di (&operands[0], 1, &operands[3], &operands[4]);
3309 emit_move_insn (operands[3], operands[1]);
3311 /* Generate a cltd if possible and doing so it profitable. */
3312 if (true_regnum (operands[1]) == 0
3313 && true_regnum (operands[2]) == 1
3314 && (optimize_size || TARGET_USE_CLTD))
3316 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3320 emit_move_insn (operands[2], operands[1]);
3321 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3323 emit_move_insn (operands[4], operands[2]);
3327 ;; Extend to register case. Optimize case where source and destination
3328 ;; registers match and cases where we can use cltd.
3330 [(set (match_operand:DI 0 "register_operand" "")
3331 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3332 (clobber (reg:CC FLAGS_REG))
3333 (clobber (match_scratch:SI 2 ""))]
3337 split_di (&operands[0], 1, &operands[3], &operands[4]);
3339 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3340 emit_move_insn (operands[3], operands[1]);
3342 /* Generate a cltd if possible and doing so it profitable. */
3343 if (true_regnum (operands[3]) == 0
3344 && (optimize_size || TARGET_USE_CLTD))
3346 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3350 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3351 emit_move_insn (operands[4], operands[1]);
3353 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3357 (define_insn "extendhisi2"
3358 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3359 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3362 switch (get_attr_prefix_0f (insn))
3365 return "{cwtl|cwde}";
3367 return "movs{wl|x}\t{%1,%0|%0, %1}";
3370 [(set_attr "type" "imovx")
3371 (set_attr "mode" "SI")
3372 (set (attr "prefix_0f")
3373 ;; movsx is short decodable while cwtl is vector decoded.
3374 (if_then_else (and (eq_attr "cpu" "!k6")
3375 (eq_attr "alternative" "0"))
3377 (const_string "1")))
3379 (if_then_else (eq_attr "prefix_0f" "0")
3381 (const_string "1")))])
3383 (define_insn "*extendhisi2_zext"
3384 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3386 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3389 switch (get_attr_prefix_0f (insn))
3392 return "{cwtl|cwde}";
3394 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3397 [(set_attr "type" "imovx")
3398 (set_attr "mode" "SI")
3399 (set (attr "prefix_0f")
3400 ;; movsx is short decodable while cwtl is vector decoded.
3401 (if_then_else (and (eq_attr "cpu" "!k6")
3402 (eq_attr "alternative" "0"))
3404 (const_string "1")))
3406 (if_then_else (eq_attr "prefix_0f" "0")
3408 (const_string "1")))])
3410 (define_insn "extendqihi2"
3411 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3412 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3415 switch (get_attr_prefix_0f (insn))
3418 return "{cbtw|cbw}";
3420 return "movs{bw|x}\t{%1,%0|%0, %1}";
3423 [(set_attr "type" "imovx")
3424 (set_attr "mode" "HI")
3425 (set (attr "prefix_0f")
3426 ;; movsx is short decodable while cwtl is vector decoded.
3427 (if_then_else (and (eq_attr "cpu" "!k6")
3428 (eq_attr "alternative" "0"))
3430 (const_string "1")))
3432 (if_then_else (eq_attr "prefix_0f" "0")
3434 (const_string "1")))])
3436 (define_insn "extendqisi2"
3437 [(set (match_operand:SI 0 "register_operand" "=r")
3438 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3440 "movs{bl|x}\t{%1,%0|%0, %1}"
3441 [(set_attr "type" "imovx")
3442 (set_attr "mode" "SI")])
3444 (define_insn "*extendqisi2_zext"
3445 [(set (match_operand:DI 0 "register_operand" "=r")
3447 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3449 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3450 [(set_attr "type" "imovx")
3451 (set_attr "mode" "SI")])
3453 ;; Conversions between float and double.
3455 ;; These are all no-ops in the model used for the 80387. So just
3458 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3459 (define_insn "*dummy_extendsfdf2"
3460 [(set (match_operand:DF 0 "push_operand" "=<")
3461 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3466 [(set (match_operand:DF 0 "push_operand" "")
3467 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3469 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3470 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3473 [(set (match_operand:DF 0 "push_operand" "")
3474 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3476 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3477 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3479 (define_insn "*dummy_extendsfxf2"
3480 [(set (match_operand:XF 0 "push_operand" "=<")
3481 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3486 [(set (match_operand:XF 0 "push_operand" "")
3487 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3489 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3490 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3491 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3494 [(set (match_operand:XF 0 "push_operand" "")
3495 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3497 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3498 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3499 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3502 [(set (match_operand:XF 0 "push_operand" "")
3503 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3505 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3506 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3507 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3510 [(set (match_operand:XF 0 "push_operand" "")
3511 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3513 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3514 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3515 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3517 (define_expand "extendsfdf2"
3518 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3519 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3520 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3522 /* ??? Needed for compress_float_constant since all fp constants
3523 are LEGITIMATE_CONSTANT_P. */
3524 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3526 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3527 && standard_80387_constant_p (operands[1]) > 0)
3529 operands[1] = simplify_const_unary_operation
3530 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3531 emit_move_insn_1 (operands[0], operands[1]);
3534 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3536 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3537 operands[1] = force_reg (SFmode, operands[1]);
3540 (define_insn "*extendsfdf2_mixed"
3541 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3542 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3543 "TARGET_SSE2 && TARGET_MIX_SSE_I387
3544 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3546 switch (which_alternative)
3549 return output_387_reg_move (insn, operands);
3552 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3553 return "fstp%z0\t%y0";
3555 return "fst%z0\t%y0";
3558 return "cvtss2sd\t{%1, %0|%0, %1}";
3564 [(set_attr "type" "fmov,fmov,ssecvt")
3565 (set_attr "mode" "SF,XF,DF")])
3567 (define_insn "*extendsfdf2_sse"
3568 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3569 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3570 "TARGET_SSE2 && TARGET_SSE_MATH
3571 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3572 "cvtss2sd\t{%1, %0|%0, %1}"
3573 [(set_attr "type" "ssecvt")
3574 (set_attr "mode" "DF")])
3576 (define_insn "*extendsfdf2_i387"
3577 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3578 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3580 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3582 switch (which_alternative)
3585 return output_387_reg_move (insn, operands);
3588 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3589 return "fstp%z0\t%y0";
3591 return "fst%z0\t%y0";
3597 [(set_attr "type" "fmov")
3598 (set_attr "mode" "SF,XF")])
3600 (define_expand "extendsfxf2"
3601 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3602 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3605 /* ??? Needed for compress_float_constant since all fp constants
3606 are LEGITIMATE_CONSTANT_P. */
3607 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3609 if (standard_80387_constant_p (operands[1]) > 0)
3611 operands[1] = simplify_const_unary_operation
3612 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3613 emit_move_insn_1 (operands[0], operands[1]);
3616 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3618 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3619 operands[1] = force_reg (SFmode, operands[1]);
3622 (define_insn "*extendsfxf2_i387"
3623 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3624 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3626 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3628 switch (which_alternative)
3631 return output_387_reg_move (insn, operands);
3634 /* There is no non-popping store to memory for XFmode. So if
3635 we need one, follow the store with a load. */
3636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637 return "fstp%z0\t%y0";
3639 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3645 [(set_attr "type" "fmov")
3646 (set_attr "mode" "SF,XF")])
3648 (define_expand "extenddfxf2"
3649 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3650 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3653 /* ??? Needed for compress_float_constant since all fp constants
3654 are LEGITIMATE_CONSTANT_P. */
3655 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3657 if (standard_80387_constant_p (operands[1]) > 0)
3659 operands[1] = simplify_const_unary_operation
3660 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3661 emit_move_insn_1 (operands[0], operands[1]);
3664 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3666 if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
3667 operands[1] = force_reg (DFmode, operands[1]);
3670 (define_insn "*extenddfxf2_i387"
3671 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3672 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3674 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3676 switch (which_alternative)
3679 return output_387_reg_move (insn, operands);
3682 /* There is no non-popping store to memory for XFmode. So if
3683 we need one, follow the store with a load. */
3684 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3685 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3687 return "fstp%z0\t%y0";
3693 [(set_attr "type" "fmov")
3694 (set_attr "mode" "DF,XF")])
3696 ;; %%% This seems bad bad news.
3697 ;; This cannot output into an f-reg because there is no way to be sure
3698 ;; of truncating in that case. Otherwise this is just like a simple move
3699 ;; insn. So we pretend we can output to a reg in order to get better
3700 ;; register preferencing, but we really use a stack slot.
3702 ;; Conversion from DFmode to SFmode.
3704 (define_expand "truncdfsf2"
3705 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3707 (match_operand:DF 1 "nonimmediate_operand" "")))]
3708 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3710 if (MEM_P (operands[0]) && MEM_P (operands[1]))
3711 operands[1] = force_reg (DFmode, operands[1]);
3713 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3715 else if (flag_unsafe_math_optimizations)
3719 rtx temp = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3720 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3725 (define_expand "truncdfsf2_with_temp"
3726 [(parallel [(set (match_operand:SF 0 "" "")
3727 (float_truncate:SF (match_operand:DF 1 "" "")))
3728 (clobber (match_operand:SF 2 "" ""))])]
3731 (define_insn "*truncdfsf_fast_mixed"
3732 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3734 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3735 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3737 switch (which_alternative)
3740 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3741 return "fstp%z0\t%y0";
3743 return "fst%z0\t%y0";
3745 return output_387_reg_move (insn, operands);
3747 return "cvtsd2ss\t{%1, %0|%0, %1}";
3752 [(set_attr "type" "fmov,fmov,ssecvt")
3753 (set_attr "mode" "SF")])
3755 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3756 ;; because nothing we do here is unsafe.
3757 (define_insn "*truncdfsf_fast_sse"
3758 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3760 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3761 "TARGET_SSE2 && TARGET_SSE_MATH"
3762 "cvtsd2ss\t{%1, %0|%0, %1}"
3763 [(set_attr "type" "ssecvt")
3764 (set_attr "mode" "SF")])
3766 (define_insn "*truncdfsf_fast_i387"
3767 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3769 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3770 "TARGET_80387 && flag_unsafe_math_optimizations"
3771 "* return output_387_reg_move (insn, operands);"
3772 [(set_attr "type" "fmov")
3773 (set_attr "mode" "SF")])
3775 (define_insn "*truncdfsf_mixed"
3776 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3778 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3779 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3780 "TARGET_MIX_SSE_I387"
3782 switch (which_alternative)
3785 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3786 return "fstp%z0\t%y0";
3788 return "fst%z0\t%y0";
3792 return "cvtsd2ss\t{%1, %0|%0, %1}";
3797 [(set_attr "type" "fmov,multi,ssecvt")
3798 (set_attr "unit" "*,i387,*")
3799 (set_attr "mode" "SF")])
3801 (define_insn "*truncdfsf_i387"
3802 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3804 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3805 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3808 switch (which_alternative)
3811 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3812 return "fstp%z0\t%y0";
3814 return "fst%z0\t%y0";
3821 [(set_attr "type" "fmov,multi")
3822 (set_attr "unit" "*,i387")
3823 (set_attr "mode" "SF")])
3825 (define_insn "*truncdfsf2_i387_1"
3826 [(set (match_operand:SF 0 "memory_operand" "=m")
3828 (match_operand:DF 1 "register_operand" "f")))]
3830 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3831 && !TARGET_MIX_SSE_I387"
3833 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3834 return "fstp%z0\t%y0";
3836 return "fst%z0\t%y0";
3838 [(set_attr "type" "fmov")
3839 (set_attr "mode" "SF")])
3842 [(set (match_operand:SF 0 "register_operand" "")
3844 (match_operand:DF 1 "fp_register_operand" "")))
3845 (clobber (match_operand 2 "" ""))]
3847 [(set (match_dup 2) (match_dup 1))
3848 (set (match_dup 0) (match_dup 2))]
3850 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3853 ;; Conversion from XFmode to SFmode.
3855 (define_expand "truncxfsf2"
3856 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3858 (match_operand:XF 1 "register_operand" "")))
3859 (clobber (match_dup 2))])]
3862 if (flag_unsafe_math_optimizations)
3864 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3865 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3866 if (reg != operands[0])
3867 emit_move_insn (operands[0], reg);
3871 operands[2] = assign_386_stack_local (SFmode, SLOT_VIRTUAL);
3874 (define_insn "*truncxfsf2_mixed"
3875 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3877 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3878 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3879 "TARGET_MIX_SSE_I387"
3881 gcc_assert (!which_alternative);
3882 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883 return "fstp%z0\t%y0";
3885 return "fst%z0\t%y0";
3887 [(set_attr "type" "fmov,multi,multi,multi")
3888 (set_attr "unit" "*,i387,i387,i387")
3889 (set_attr "mode" "SF")])
3891 (define_insn "truncxfsf2_i387_noop"
3892 [(set (match_operand:SF 0 "register_operand" "=f")
3893 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3894 "TARGET_80387 && flag_unsafe_math_optimizations"
3896 return output_387_reg_move (insn, operands);
3898 [(set_attr "type" "fmov")
3899 (set_attr "mode" "SF")])
3901 (define_insn "*truncxfsf2_i387"
3902 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3904 (match_operand:XF 1 "register_operand" "f,f,f")))
3905 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3908 gcc_assert (!which_alternative);
3909 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3910 return "fstp%z0\t%y0";
3912 return "fst%z0\t%y0";
3914 [(set_attr "type" "fmov,multi,multi")
3915 (set_attr "unit" "*,i387,i387")
3916 (set_attr "mode" "SF")])
3918 (define_insn "*truncxfsf2_i387_1"
3919 [(set (match_operand:SF 0 "memory_operand" "=m")
3921 (match_operand:XF 1 "register_operand" "f")))]
3924 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3925 return "fstp%z0\t%y0";
3927 return "fst%z0\t%y0";
3929 [(set_attr "type" "fmov")
3930 (set_attr "mode" "SF")])
3933 [(set (match_operand:SF 0 "register_operand" "")
3935 (match_operand:XF 1 "register_operand" "")))
3936 (clobber (match_operand:SF 2 "memory_operand" ""))]
3937 "TARGET_80387 && reload_completed"
3938 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3939 (set (match_dup 0) (match_dup 2))]
3943 [(set (match_operand:SF 0 "memory_operand" "")
3945 (match_operand:XF 1 "register_operand" "")))
3946 (clobber (match_operand:SF 2 "memory_operand" ""))]
3948 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3951 ;; Conversion from XFmode to DFmode.
3953 (define_expand "truncxfdf2"
3954 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3956 (match_operand:XF 1 "register_operand" "")))
3957 (clobber (match_dup 2))])]
3960 if (flag_unsafe_math_optimizations)
3962 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3963 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3964 if (reg != operands[0])
3965 emit_move_insn (operands[0], reg);
3969 operands[2] = assign_386_stack_local (DFmode, SLOT_VIRTUAL);
3972 (define_insn "*truncxfdf2_mixed"
3973 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3975 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3976 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3977 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3979 gcc_assert (!which_alternative);
3980 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3981 return "fstp%z0\t%y0";
3983 return "fst%z0\t%y0";
3985 [(set_attr "type" "fmov,multi,multi,multi")
3986 (set_attr "unit" "*,i387,i387,i387")
3987 (set_attr "mode" "DF")])
3989 (define_insn "truncxfdf2_i387_noop"
3990 [(set (match_operand:DF 0 "register_operand" "=f")
3991 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
3992 "TARGET_80387 && flag_unsafe_math_optimizations"
3994 return output_387_reg_move (insn, operands);
3996 [(set_attr "type" "fmov")
3997 (set_attr "mode" "DF")])
3999 (define_insn "*truncxfdf2_i387"
4000 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4002 (match_operand:XF 1 "register_operand" "f,f,f")))
4003 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4006 gcc_assert (!which_alternative);
4007 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4008 return "fstp%z0\t%y0";
4010 return "fst%z0\t%y0";
4012 [(set_attr "type" "fmov,multi,multi")
4013 (set_attr "unit" "*,i387,i387")
4014 (set_attr "mode" "DF")])
4016 (define_insn "*truncxfdf2_i387_1"
4017 [(set (match_operand:DF 0 "memory_operand" "=m")
4019 (match_operand:XF 1 "register_operand" "f")))]
4022 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4023 return "fstp%z0\t%y0";
4025 return "fst%z0\t%y0";
4027 [(set_attr "type" "fmov")
4028 (set_attr "mode" "DF")])
4031 [(set (match_operand:DF 0 "register_operand" "")
4033 (match_operand:XF 1 "register_operand" "")))
4034 (clobber (match_operand:DF 2 "memory_operand" ""))]
4035 "TARGET_80387 && reload_completed"
4036 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4037 (set (match_dup 0) (match_dup 2))]
4041 [(set (match_operand:DF 0 "memory_operand" "")
4043 (match_operand:XF 1 "register_operand" "")))
4044 (clobber (match_operand:DF 2 "memory_operand" ""))]
4046 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4049 ;; Signed conversion to DImode.
4051 (define_expand "fix_truncxfdi2"
4052 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4053 (fix:DI (match_operand:XF 1 "register_operand" "")))
4054 (clobber (reg:CC FLAGS_REG))])]
4059 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4064 (define_expand "fix_trunc<mode>di2"
4065 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4066 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4067 (clobber (reg:CC FLAGS_REG))])]
4068 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4071 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4073 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4076 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4078 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4079 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4080 if (out != operands[0])
4081 emit_move_insn (operands[0], out);
4086 ;; Signed conversion to SImode.
4088 (define_expand "fix_truncxfsi2"
4089 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4090 (fix:SI (match_operand:XF 1 "register_operand" "")))
4091 (clobber (reg:CC FLAGS_REG))])]
4096 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4101 (define_expand "fix_trunc<mode>si2"
4102 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4103 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4104 (clobber (reg:CC FLAGS_REG))])]
4105 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4108 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4110 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4113 if (SSE_FLOAT_MODE_P (<MODE>mode))
4115 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4116 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4117 if (out != operands[0])
4118 emit_move_insn (operands[0], out);
4123 ;; Signed conversion to HImode.
4125 (define_expand "fix_trunc<mode>hi2"
4126 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4127 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4128 (clobber (reg:CC FLAGS_REG))])]
4130 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4134 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4139 ;; When SSE is available, it is always faster to use it!
4140 (define_insn "fix_truncsfdi_sse"
4141 [(set (match_operand:DI 0 "register_operand" "=r,r")
4142 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4143 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4144 "cvttss2si{q}\t{%1, %0|%0, %1}"
4145 [(set_attr "type" "sseicvt")
4146 (set_attr "mode" "SF")
4147 (set_attr "athlon_decode" "double,vector")])
4149 (define_insn "fix_truncdfdi_sse"
4150 [(set (match_operand:DI 0 "register_operand" "=r,r")
4151 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4152 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4153 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4154 [(set_attr "type" "sseicvt")
4155 (set_attr "mode" "DF")
4156 (set_attr "athlon_decode" "double,vector")])
4158 (define_insn "fix_truncsfsi_sse"
4159 [(set (match_operand:SI 0 "register_operand" "=r,r")
4160 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4161 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4162 "cvttss2si\t{%1, %0|%0, %1}"
4163 [(set_attr "type" "sseicvt")
4164 (set_attr "mode" "DF")
4165 (set_attr "athlon_decode" "double,vector")])
4167 (define_insn "fix_truncdfsi_sse"
4168 [(set (match_operand:SI 0 "register_operand" "=r,r")
4169 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4170 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4171 "cvttsd2si\t{%1, %0|%0, %1}"
4172 [(set_attr "type" "sseicvt")
4173 (set_attr "mode" "DF")
4174 (set_attr "athlon_decode" "double,vector")])
4176 ;; Avoid vector decoded forms of the instruction.
4178 [(match_scratch:DF 2 "Y")
4179 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4180 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4181 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4182 [(set (match_dup 2) (match_dup 1))
4183 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4187 [(match_scratch:SF 2 "x")
4188 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4189 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4190 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4191 [(set (match_dup 2) (match_dup 1))
4192 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4195 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4196 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4197 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4199 && FLOAT_MODE_P (GET_MODE (operands[1]))
4200 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4201 && (TARGET_64BIT || <MODE>mode != DImode))
4203 && !(reload_completed || reload_in_progress)"
4208 if (memory_operand (operands[0], VOIDmode))
4209 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4212 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4213 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4219 [(set_attr "type" "fisttp")
4220 (set_attr "mode" "<MODE>")])
4222 (define_insn "fix_trunc<mode>_i387_fisttp"
4223 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4224 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4225 (clobber (match_scratch:XF 2 "=&1f"))]
4227 && FLOAT_MODE_P (GET_MODE (operands[1]))
4228 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4229 && (TARGET_64BIT || <MODE>mode != DImode))
4230 && TARGET_SSE_MATH)"
4231 "* return output_fix_trunc (insn, operands, 1);"
4232 [(set_attr "type" "fisttp")
4233 (set_attr "mode" "<MODE>")])
4235 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4236 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4237 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4238 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4239 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4241 && FLOAT_MODE_P (GET_MODE (operands[1]))
4242 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4243 && (TARGET_64BIT || <MODE>mode != DImode))
4244 && TARGET_SSE_MATH)"
4246 [(set_attr "type" "fisttp")
4247 (set_attr "mode" "<MODE>")])
4250 [(set (match_operand:X87MODEI 0 "register_operand" "")
4251 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4252 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4253 (clobber (match_scratch 3 ""))]
4255 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4256 (clobber (match_dup 3))])
4257 (set (match_dup 0) (match_dup 2))]
4261 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4262 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4263 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4264 (clobber (match_scratch 3 ""))]
4266 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4267 (clobber (match_dup 3))])]
4270 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4271 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4272 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4273 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4274 ;; function in i386.c.
4275 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4276 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4277 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4278 (clobber (reg:CC FLAGS_REG))]
4279 "TARGET_80387 && !TARGET_FISTTP
4280 && FLOAT_MODE_P (GET_MODE (operands[1]))
4281 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4282 && (TARGET_64BIT || <MODE>mode != DImode))
4283 && !(reload_completed || reload_in_progress)"
4288 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4290 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4291 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4292 if (memory_operand (operands[0], VOIDmode))
4293 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4294 operands[2], operands[3]));
4297 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4298 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4299 operands[2], operands[3],
4304 [(set_attr "type" "fistp")
4305 (set_attr "i387_cw" "trunc")
4306 (set_attr "mode" "<MODE>")])
4308 (define_insn "fix_truncdi_i387"
4309 [(set (match_operand:DI 0 "memory_operand" "=m")
4310 (fix:DI (match_operand 1 "register_operand" "f")))
4311 (use (match_operand:HI 2 "memory_operand" "m"))
4312 (use (match_operand:HI 3 "memory_operand" "m"))
4313 (clobber (match_scratch:XF 4 "=&1f"))]
4314 "TARGET_80387 && !TARGET_FISTTP
4315 && FLOAT_MODE_P (GET_MODE (operands[1]))
4316 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4317 "* return output_fix_trunc (insn, operands, 0);"
4318 [(set_attr "type" "fistp")
4319 (set_attr "i387_cw" "trunc")
4320 (set_attr "mode" "DI")])
4322 (define_insn "fix_truncdi_i387_with_temp"
4323 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4324 (fix:DI (match_operand 1 "register_operand" "f,f")))
4325 (use (match_operand:HI 2 "memory_operand" "m,m"))
4326 (use (match_operand:HI 3 "memory_operand" "m,m"))
4327 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4328 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4329 "TARGET_80387 && !TARGET_FISTTP
4330 && FLOAT_MODE_P (GET_MODE (operands[1]))
4331 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4333 [(set_attr "type" "fistp")
4334 (set_attr "i387_cw" "trunc")
4335 (set_attr "mode" "DI")])
4338 [(set (match_operand:DI 0 "register_operand" "")
4339 (fix:DI (match_operand 1 "register_operand" "")))
4340 (use (match_operand:HI 2 "memory_operand" ""))
4341 (use (match_operand:HI 3 "memory_operand" ""))
4342 (clobber (match_operand:DI 4 "memory_operand" ""))
4343 (clobber (match_scratch 5 ""))]
4345 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4348 (clobber (match_dup 5))])
4349 (set (match_dup 0) (match_dup 4))]
4353 [(set (match_operand:DI 0 "memory_operand" "")
4354 (fix:DI (match_operand 1 "register_operand" "")))
4355 (use (match_operand:HI 2 "memory_operand" ""))
4356 (use (match_operand:HI 3 "memory_operand" ""))
4357 (clobber (match_operand:DI 4 "memory_operand" ""))
4358 (clobber (match_scratch 5 ""))]
4360 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4363 (clobber (match_dup 5))])]
4366 (define_insn "fix_trunc<mode>_i387"
4367 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4368 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4369 (use (match_operand:HI 2 "memory_operand" "m"))
4370 (use (match_operand:HI 3 "memory_operand" "m"))]
4371 "TARGET_80387 && !TARGET_FISTTP
4372 && FLOAT_MODE_P (GET_MODE (operands[1]))
4373 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4374 "* return output_fix_trunc (insn, operands, 0);"
4375 [(set_attr "type" "fistp")
4376 (set_attr "i387_cw" "trunc")
4377 (set_attr "mode" "<MODE>")])
4379 (define_insn "fix_trunc<mode>_i387_with_temp"
4380 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4381 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4382 (use (match_operand:HI 2 "memory_operand" "m,m"))
4383 (use (match_operand:HI 3 "memory_operand" "m,m"))
4384 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4385 "TARGET_80387 && !TARGET_FISTTP
4386 && FLOAT_MODE_P (GET_MODE (operands[1]))
4387 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4389 [(set_attr "type" "fistp")
4390 (set_attr "i387_cw" "trunc")
4391 (set_attr "mode" "<MODE>")])
4394 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4395 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4396 (use (match_operand:HI 2 "memory_operand" ""))
4397 (use (match_operand:HI 3 "memory_operand" ""))
4398 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4400 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4402 (use (match_dup 3))])
4403 (set (match_dup 0) (match_dup 4))]
4407 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4408 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4409 (use (match_operand:HI 2 "memory_operand" ""))
4410 (use (match_operand:HI 3 "memory_operand" ""))
4411 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4413 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4415 (use (match_dup 3))])]
4418 (define_insn "x86_fnstcw_1"
4419 [(set (match_operand:HI 0 "memory_operand" "=m")
4420 (unspec:HI [(reg:HI FPSR_REG)] UNSPEC_FSTCW))]
4423 [(set_attr "length" "2")
4424 (set_attr "mode" "HI")
4425 (set_attr "unit" "i387")])
4427 (define_insn "x86_fldcw_1"
4428 [(set (reg:HI FPSR_REG)
4429 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4432 [(set_attr "length" "2")
4433 (set_attr "mode" "HI")
4434 (set_attr "unit" "i387")
4435 (set_attr "athlon_decode" "vector")])
4437 ;; Conversion between fixed point and floating point.
4439 ;; Even though we only accept memory inputs, the backend _really_
4440 ;; wants to be able to do this between registers.
4442 (define_expand "floathisf2"
4443 [(set (match_operand:SF 0 "register_operand" "")
4444 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4445 "TARGET_80387 || TARGET_SSE_MATH"
4447 if (TARGET_SSE_MATH)
4449 emit_insn (gen_floatsisf2 (operands[0],
4450 convert_to_mode (SImode, operands[1], 0)));
4455 (define_insn "*floathisf2_i387"
4456 [(set (match_operand:SF 0 "register_operand" "=f,f")
4457 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4458 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4462 [(set_attr "type" "fmov,multi")
4463 (set_attr "mode" "SF")
4464 (set_attr "unit" "*,i387")
4465 (set_attr "fp_int_src" "true")])
4467 (define_expand "floatsisf2"
4468 [(set (match_operand:SF 0 "register_operand" "")
4469 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4470 "TARGET_80387 || TARGET_SSE_MATH"
4473 (define_insn "*floatsisf2_mixed"
4474 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4475 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4476 "TARGET_MIX_SSE_I387"
4480 cvtsi2ss\t{%1, %0|%0, %1}
4481 cvtsi2ss\t{%1, %0|%0, %1}"
4482 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4483 (set_attr "mode" "SF")
4484 (set_attr "unit" "*,i387,*,*")
4485 (set_attr "athlon_decode" "*,*,vector,double")
4486 (set_attr "fp_int_src" "true")])
4488 (define_insn "*floatsisf2_sse"
4489 [(set (match_operand:SF 0 "register_operand" "=x,x")
4490 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4492 "cvtsi2ss\t{%1, %0|%0, %1}"
4493 [(set_attr "type" "sseicvt")
4494 (set_attr "mode" "SF")
4495 (set_attr "athlon_decode" "vector,double")
4496 (set_attr "fp_int_src" "true")])
4498 (define_insn "*floatsisf2_i387"
4499 [(set (match_operand:SF 0 "register_operand" "=f,f")
4500 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4505 [(set_attr "type" "fmov,multi")
4506 (set_attr "mode" "SF")
4507 (set_attr "unit" "*,i387")
4508 (set_attr "fp_int_src" "true")])
4510 (define_expand "floatdisf2"
4511 [(set (match_operand:SF 0 "register_operand" "")
4512 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4513 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4516 (define_insn "*floatdisf2_mixed"
4517 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4518 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4519 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4523 cvtsi2ss{q}\t{%1, %0|%0, %1}
4524 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4525 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4526 (set_attr "mode" "SF")
4527 (set_attr "unit" "*,i387,*,*")
4528 (set_attr "athlon_decode" "*,*,vector,double")
4529 (set_attr "fp_int_src" "true")])
4531 (define_insn "*floatdisf2_sse"
4532 [(set (match_operand:SF 0 "register_operand" "=x,x")
4533 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4534 "TARGET_64BIT && TARGET_SSE_MATH"
4535 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4536 [(set_attr "type" "sseicvt")
4537 (set_attr "mode" "SF")
4538 (set_attr "athlon_decode" "vector,double")
4539 (set_attr "fp_int_src" "true")])
4541 (define_insn "*floatdisf2_i387"
4542 [(set (match_operand:SF 0 "register_operand" "=f,f")
4543 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4548 [(set_attr "type" "fmov,multi")
4549 (set_attr "mode" "SF")
4550 (set_attr "unit" "*,i387")
4551 (set_attr "fp_int_src" "true")])
4553 (define_expand "floathidf2"
4554 [(set (match_operand:DF 0 "register_operand" "")
4555 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4556 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4558 if (TARGET_SSE2 && TARGET_SSE_MATH)
4560 emit_insn (gen_floatsidf2 (operands[0],
4561 convert_to_mode (SImode, operands[1], 0)));
4566 (define_insn "*floathidf2_i387"
4567 [(set (match_operand:DF 0 "register_operand" "=f,f")
4568 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4569 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4573 [(set_attr "type" "fmov,multi")
4574 (set_attr "mode" "DF")
4575 (set_attr "unit" "*,i387")
4576 (set_attr "fp_int_src" "true")])
4578 (define_expand "floatsidf2"
4579 [(set (match_operand:DF 0 "register_operand" "")
4580 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4581 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4584 (define_insn "*floatsidf2_mixed"
4585 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4586 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4587 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4591 cvtsi2sd\t{%1, %0|%0, %1}
4592 cvtsi2sd\t{%1, %0|%0, %1}"
4593 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4594 (set_attr "mode" "DF")
4595 (set_attr "unit" "*,i387,*,*")
4596 (set_attr "athlon_decode" "*,*,double,direct")
4597 (set_attr "fp_int_src" "true")])
4599 (define_insn "*floatsidf2_sse"
4600 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4601 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4602 "TARGET_SSE2 && TARGET_SSE_MATH"
4603 "cvtsi2sd\t{%1, %0|%0, %1}"
4604 [(set_attr "type" "sseicvt")
4605 (set_attr "mode" "DF")
4606 (set_attr "athlon_decode" "double,direct")
4607 (set_attr "fp_int_src" "true")])
4609 (define_insn "*floatsidf2_i387"
4610 [(set (match_operand:DF 0 "register_operand" "=f,f")
4611 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4616 [(set_attr "type" "fmov,multi")
4617 (set_attr "mode" "DF")
4618 (set_attr "unit" "*,i387")
4619 (set_attr "fp_int_src" "true")])
4621 (define_expand "floatdidf2"
4622 [(set (match_operand:DF 0 "register_operand" "")
4623 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4624 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4627 (define_insn "*floatdidf2_mixed"
4628 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4629 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4630 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4634 cvtsi2sd{q}\t{%1, %0|%0, %1}
4635 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4636 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4637 (set_attr "mode" "DF")
4638 (set_attr "unit" "*,i387,*,*")
4639 (set_attr "athlon_decode" "*,*,double,direct")
4640 (set_attr "fp_int_src" "true")])
4642 (define_insn "*floatdidf2_sse"
4643 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4644 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4645 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4646 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4647 [(set_attr "type" "sseicvt")
4648 (set_attr "mode" "DF")
4649 (set_attr "athlon_decode" "double,direct")
4650 (set_attr "fp_int_src" "true")])
4652 (define_insn "*floatdidf2_i387"
4653 [(set (match_operand:DF 0 "register_operand" "=f,f")
4654 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4659 [(set_attr "type" "fmov,multi")
4660 (set_attr "mode" "DF")
4661 (set_attr "unit" "*,i387")
4662 (set_attr "fp_int_src" "true")])
4664 (define_insn "floathixf2"
4665 [(set (match_operand:XF 0 "register_operand" "=f,f")
4666 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4671 [(set_attr "type" "fmov,multi")
4672 (set_attr "mode" "XF")
4673 (set_attr "unit" "*,i387")
4674 (set_attr "fp_int_src" "true")])
4676 (define_insn "floatsixf2"
4677 [(set (match_operand:XF 0 "register_operand" "=f,f")
4678 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4683 [(set_attr "type" "fmov,multi")
4684 (set_attr "mode" "XF")
4685 (set_attr "unit" "*,i387")
4686 (set_attr "fp_int_src" "true")])
4688 (define_insn "floatdixf2"
4689 [(set (match_operand:XF 0 "register_operand" "=f,f")
4690 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4695 [(set_attr "type" "fmov,multi")
4696 (set_attr "mode" "XF")
4697 (set_attr "unit" "*,i387")
4698 (set_attr "fp_int_src" "true")])
4700 ;; %%% Kill these when reload knows how to do it.
4702 [(set (match_operand 0 "fp_register_operand" "")
4703 (float (match_operand 1 "register_operand" "")))]
4706 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4709 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4710 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4711 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4712 ix86_free_from_memory (GET_MODE (operands[1]));
4716 (define_expand "floatunssisf2"
4717 [(use (match_operand:SF 0 "register_operand" ""))
4718 (use (match_operand:SI 1 "register_operand" ""))]
4719 "!TARGET_64BIT && TARGET_SSE_MATH"
4720 "x86_emit_floatuns (operands); DONE;")
4722 (define_expand "floatunsdisf2"
4723 [(use (match_operand:SF 0 "register_operand" ""))
4724 (use (match_operand:DI 1 "register_operand" ""))]
4725 "TARGET_64BIT && TARGET_SSE_MATH"
4726 "x86_emit_floatuns (operands); DONE;")
4728 (define_expand "floatunsdidf2"
4729 [(use (match_operand:DF 0 "register_operand" ""))
4730 (use (match_operand:DI 1 "register_operand" ""))]
4731 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4732 "x86_emit_floatuns (operands); DONE;")
4734 ;; SSE extract/set expanders
4739 ;; %%% splits for addditi3
4741 (define_expand "addti3"
4742 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4743 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4744 (match_operand:TI 2 "x86_64_general_operand" "")))
4745 (clobber (reg:CC FLAGS_REG))]
4747 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4749 (define_insn "*addti3_1"
4750 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4751 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4752 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
4753 (clobber (reg:CC FLAGS_REG))]
4754 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4758 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4759 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4760 (match_operand:TI 2 "x86_64_general_operand" "")))
4761 (clobber (reg:CC FLAGS_REG))]
4762 "TARGET_64BIT && reload_completed"
4763 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4765 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4766 (parallel [(set (match_dup 3)
4767 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4770 (clobber (reg:CC FLAGS_REG))])]
4771 "split_ti (operands+0, 1, operands+0, operands+3);
4772 split_ti (operands+1, 1, operands+1, operands+4);
4773 split_ti (operands+2, 1, operands+2, operands+5);")
4775 ;; %%% splits for addsidi3
4776 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4777 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4778 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4780 (define_expand "adddi3"
4781 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4782 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4783 (match_operand:DI 2 "x86_64_general_operand" "")))
4784 (clobber (reg:CC FLAGS_REG))]
4786 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4788 (define_insn "*adddi3_1"
4789 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4790 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4791 (match_operand:DI 2 "general_operand" "roiF,riF")))
4792 (clobber (reg:CC FLAGS_REG))]
4793 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4797 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4798 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4799 (match_operand:DI 2 "general_operand" "")))
4800 (clobber (reg:CC FLAGS_REG))]
4801 "!TARGET_64BIT && reload_completed"
4802 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4804 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4805 (parallel [(set (match_dup 3)
4806 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4809 (clobber (reg:CC FLAGS_REG))])]
4810 "split_di (operands+0, 1, operands+0, operands+3);
4811 split_di (operands+1, 1, operands+1, operands+4);
4812 split_di (operands+2, 1, operands+2, operands+5);")
4814 (define_insn "adddi3_carry_rex64"
4815 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4816 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4817 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4818 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4819 (clobber (reg:CC FLAGS_REG))]
4820 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4821 "adc{q}\t{%2, %0|%0, %2}"
4822 [(set_attr "type" "alu")
4823 (set_attr "pent_pair" "pu")
4824 (set_attr "mode" "DI")])
4826 (define_insn "*adddi3_cc_rex64"
4827 [(set (reg:CC FLAGS_REG)
4828 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4829 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4831 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4832 (plus:DI (match_dup 1) (match_dup 2)))]
4833 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4834 "add{q}\t{%2, %0|%0, %2}"
4835 [(set_attr "type" "alu")
4836 (set_attr "mode" "DI")])
4838 (define_insn "addqi3_carry"
4839 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4840 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4841 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4842 (match_operand:QI 2 "general_operand" "qi,qm")))
4843 (clobber (reg:CC FLAGS_REG))]
4844 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4845 "adc{b}\t{%2, %0|%0, %2}"
4846 [(set_attr "type" "alu")
4847 (set_attr "pent_pair" "pu")
4848 (set_attr "mode" "QI")])
4850 (define_insn "addhi3_carry"
4851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4852 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4853 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4854 (match_operand:HI 2 "general_operand" "ri,rm")))
4855 (clobber (reg:CC FLAGS_REG))]
4856 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4857 "adc{w}\t{%2, %0|%0, %2}"
4858 [(set_attr "type" "alu")
4859 (set_attr "pent_pair" "pu")
4860 (set_attr "mode" "HI")])
4862 (define_insn "addsi3_carry"
4863 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4864 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4865 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4866 (match_operand:SI 2 "general_operand" "ri,rm")))
4867 (clobber (reg:CC FLAGS_REG))]
4868 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4869 "adc{l}\t{%2, %0|%0, %2}"
4870 [(set_attr "type" "alu")
4871 (set_attr "pent_pair" "pu")
4872 (set_attr "mode" "SI")])
4874 (define_insn "*addsi3_carry_zext"
4875 [(set (match_operand:DI 0 "register_operand" "=r")
4877 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4878 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4879 (match_operand:SI 2 "general_operand" "rim"))))
4880 (clobber (reg:CC FLAGS_REG))]
4881 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4882 "adc{l}\t{%2, %k0|%k0, %2}"
4883 [(set_attr "type" "alu")
4884 (set_attr "pent_pair" "pu")
4885 (set_attr "mode" "SI")])
4887 (define_insn "*addsi3_cc"
4888 [(set (reg:CC FLAGS_REG)
4889 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4890 (match_operand:SI 2 "general_operand" "ri,rm")]
4892 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4893 (plus:SI (match_dup 1) (match_dup 2)))]
4894 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4895 "add{l}\t{%2, %0|%0, %2}"
4896 [(set_attr "type" "alu")
4897 (set_attr "mode" "SI")])
4899 (define_insn "addqi3_cc"
4900 [(set (reg:CC FLAGS_REG)
4901 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4902 (match_operand:QI 2 "general_operand" "qi,qm")]
4904 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4905 (plus:QI (match_dup 1) (match_dup 2)))]
4906 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4907 "add{b}\t{%2, %0|%0, %2}"
4908 [(set_attr "type" "alu")
4909 (set_attr "mode" "QI")])
4911 (define_expand "addsi3"
4912 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4913 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4914 (match_operand:SI 2 "general_operand" "")))
4915 (clobber (reg:CC FLAGS_REG))])]
4917 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4919 (define_insn "*lea_1"
4920 [(set (match_operand:SI 0 "register_operand" "=r")
4921 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4923 "lea{l}\t{%a1, %0|%0, %a1}"
4924 [(set_attr "type" "lea")
4925 (set_attr "mode" "SI")])
4927 (define_insn "*lea_1_rex64"
4928 [(set (match_operand:SI 0 "register_operand" "=r")
4929 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4931 "lea{l}\t{%a1, %0|%0, %a1}"
4932 [(set_attr "type" "lea")
4933 (set_attr "mode" "SI")])
4935 (define_insn "*lea_1_zext"
4936 [(set (match_operand:DI 0 "register_operand" "=r")
4938 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4940 "lea{l}\t{%a1, %k0|%k0, %a1}"
4941 [(set_attr "type" "lea")
4942 (set_attr "mode" "SI")])
4944 (define_insn "*lea_2_rex64"
4945 [(set (match_operand:DI 0 "register_operand" "=r")
4946 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4948 "lea{q}\t{%a1, %0|%0, %a1}"
4949 [(set_attr "type" "lea")
4950 (set_attr "mode" "DI")])
4952 ;; The lea patterns for non-Pmodes needs to be matched by several
4953 ;; insns converted to real lea by splitters.
4955 (define_insn_and_split "*lea_general_1"
4956 [(set (match_operand 0 "register_operand" "=r")
4957 (plus (plus (match_operand 1 "index_register_operand" "l")
4958 (match_operand 2 "register_operand" "r"))
4959 (match_operand 3 "immediate_operand" "i")))]
4960 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
4961 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
4962 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
4963 && GET_MODE (operands[0]) == GET_MODE (operands[1])
4964 && GET_MODE (operands[0]) == GET_MODE (operands[2])
4965 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
4966 || GET_MODE (operands[3]) == VOIDmode)"
4968 "&& reload_completed"
4972 operands[0] = gen_lowpart (SImode, operands[0]);
4973 operands[1] = gen_lowpart (Pmode, operands[1]);
4974 operands[2] = gen_lowpart (Pmode, operands[2]);
4975 operands[3] = gen_lowpart (Pmode, operands[3]);
4976 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
4978 if (Pmode != SImode)
4979 pat = gen_rtx_SUBREG (SImode, pat, 0);
4980 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
4983 [(set_attr "type" "lea")
4984 (set_attr "mode" "SI")])
4986 (define_insn_and_split "*lea_general_1_zext"
4987 [(set (match_operand:DI 0 "register_operand" "=r")
4989 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
4990 (match_operand:SI 2 "register_operand" "r"))
4991 (match_operand:SI 3 "immediate_operand" "i"))))]
4994 "&& reload_completed"
4996 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
4998 (match_dup 3)) 0)))]
5000 operands[1] = gen_lowpart (Pmode, operands[1]);
5001 operands[2] = gen_lowpart (Pmode, operands[2]);
5002 operands[3] = gen_lowpart (Pmode, operands[3]);
5004 [(set_attr "type" "lea")
5005 (set_attr "mode" "SI")])
5007 (define_insn_and_split "*lea_general_2"
5008 [(set (match_operand 0 "register_operand" "=r")
5009 (plus (mult (match_operand 1 "index_register_operand" "l")
5010 (match_operand 2 "const248_operand" "i"))
5011 (match_operand 3 "nonmemory_operand" "ri")))]
5012 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5013 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5014 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5015 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5016 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5017 || GET_MODE (operands[3]) == VOIDmode)"
5019 "&& reload_completed"
5023 operands[0] = gen_lowpart (SImode, operands[0]);
5024 operands[1] = gen_lowpart (Pmode, operands[1]);
5025 operands[3] = gen_lowpart (Pmode, operands[3]);
5026 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5028 if (Pmode != SImode)
5029 pat = gen_rtx_SUBREG (SImode, pat, 0);
5030 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5033 [(set_attr "type" "lea")
5034 (set_attr "mode" "SI")])
5036 (define_insn_and_split "*lea_general_2_zext"
5037 [(set (match_operand:DI 0 "register_operand" "=r")
5039 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5040 (match_operand:SI 2 "const248_operand" "n"))
5041 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5044 "&& reload_completed"
5046 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5048 (match_dup 3)) 0)))]
5050 operands[1] = gen_lowpart (Pmode, operands[1]);
5051 operands[3] = gen_lowpart (Pmode, operands[3]);
5053 [(set_attr "type" "lea")
5054 (set_attr "mode" "SI")])
5056 (define_insn_and_split "*lea_general_3"
5057 [(set (match_operand 0 "register_operand" "=r")
5058 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5059 (match_operand 2 "const248_operand" "i"))
5060 (match_operand 3 "register_operand" "r"))
5061 (match_operand 4 "immediate_operand" "i")))]
5062 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5063 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5064 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5065 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5066 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5068 "&& reload_completed"
5072 operands[0] = gen_lowpart (SImode, operands[0]);
5073 operands[1] = gen_lowpart (Pmode, operands[1]);
5074 operands[3] = gen_lowpart (Pmode, operands[3]);
5075 operands[4] = gen_lowpart (Pmode, operands[4]);
5076 pat = gen_rtx_PLUS (Pmode,
5077 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5081 if (Pmode != SImode)
5082 pat = gen_rtx_SUBREG (SImode, pat, 0);
5083 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5086 [(set_attr "type" "lea")
5087 (set_attr "mode" "SI")])
5089 (define_insn_and_split "*lea_general_3_zext"
5090 [(set (match_operand:DI 0 "register_operand" "=r")
5092 (plus:SI (plus:SI (mult:SI
5093 (match_operand:SI 1 "index_register_operand" "l")
5094 (match_operand:SI 2 "const248_operand" "n"))
5095 (match_operand:SI 3 "register_operand" "r"))
5096 (match_operand:SI 4 "immediate_operand" "i"))))]
5099 "&& reload_completed"
5101 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5104 (match_dup 4)) 0)))]
5106 operands[1] = gen_lowpart (Pmode, operands[1]);
5107 operands[3] = gen_lowpart (Pmode, operands[3]);
5108 operands[4] = gen_lowpart (Pmode, operands[4]);
5110 [(set_attr "type" "lea")
5111 (set_attr "mode" "SI")])
5113 (define_insn "*adddi_1_rex64"
5114 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5115 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5116 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5117 (clobber (reg:CC FLAGS_REG))]
5118 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5120 switch (get_attr_type (insn))
5123 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5124 return "lea{q}\t{%a2, %0|%0, %a2}";
5127 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5128 if (operands[2] == const1_rtx)
5129 return "inc{q}\t%0";
5132 gcc_assert (operands[2] == constm1_rtx);
5133 return "dec{q}\t%0";
5137 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5139 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5140 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5141 if (GET_CODE (operands[2]) == CONST_INT
5142 /* Avoid overflows. */
5143 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5144 && (INTVAL (operands[2]) == 128
5145 || (INTVAL (operands[2]) < 0
5146 && INTVAL (operands[2]) != -128)))
5148 operands[2] = GEN_INT (-INTVAL (operands[2]));
5149 return "sub{q}\t{%2, %0|%0, %2}";
5151 return "add{q}\t{%2, %0|%0, %2}";
5155 (cond [(eq_attr "alternative" "2")
5156 (const_string "lea")
5157 ; Current assemblers are broken and do not allow @GOTOFF in
5158 ; ought but a memory context.
5159 (match_operand:DI 2 "pic_symbolic_operand" "")
5160 (const_string "lea")
5161 (match_operand:DI 2 "incdec_operand" "")
5162 (const_string "incdec")
5164 (const_string "alu")))
5165 (set_attr "mode" "DI")])
5167 ;; Convert lea to the lea pattern to avoid flags dependency.
5169 [(set (match_operand:DI 0 "register_operand" "")
5170 (plus:DI (match_operand:DI 1 "register_operand" "")
5171 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5172 (clobber (reg:CC FLAGS_REG))]
5173 "TARGET_64BIT && reload_completed
5174 && true_regnum (operands[0]) != true_regnum (operands[1])"
5176 (plus:DI (match_dup 1)
5180 (define_insn "*adddi_2_rex64"
5181 [(set (reg FLAGS_REG)
5183 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5184 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5186 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5187 (plus:DI (match_dup 1) (match_dup 2)))]
5188 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5189 && ix86_binary_operator_ok (PLUS, DImode, operands)
5190 /* Current assemblers are broken and do not allow @GOTOFF in
5191 ought but a memory context. */
5192 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5194 switch (get_attr_type (insn))
5197 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5198 if (operands[2] == const1_rtx)
5199 return "inc{q}\t%0";
5202 gcc_assert (operands[2] == constm1_rtx);
5203 return "dec{q}\t%0";
5207 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5208 /* ???? We ought to handle there the 32bit case too
5209 - do we need new constraint? */
5210 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5211 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5212 if (GET_CODE (operands[2]) == CONST_INT
5213 /* Avoid overflows. */
5214 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5215 && (INTVAL (operands[2]) == 128
5216 || (INTVAL (operands[2]) < 0
5217 && INTVAL (operands[2]) != -128)))
5219 operands[2] = GEN_INT (-INTVAL (operands[2]));
5220 return "sub{q}\t{%2, %0|%0, %2}";
5222 return "add{q}\t{%2, %0|%0, %2}";
5226 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5227 (const_string "incdec")
5228 (const_string "alu")))
5229 (set_attr "mode" "DI")])
5231 (define_insn "*adddi_3_rex64"
5232 [(set (reg FLAGS_REG)
5233 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5234 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5235 (clobber (match_scratch:DI 0 "=r"))]
5237 && ix86_match_ccmode (insn, CCZmode)
5238 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5239 /* Current assemblers are broken and do not allow @GOTOFF in
5240 ought but a memory context. */
5241 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5243 switch (get_attr_type (insn))
5246 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5247 if (operands[2] == const1_rtx)
5248 return "inc{q}\t%0";
5251 gcc_assert (operands[2] == constm1_rtx);
5252 return "dec{q}\t%0";
5256 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5257 /* ???? We ought to handle there the 32bit case too
5258 - do we need new constraint? */
5259 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5260 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5261 if (GET_CODE (operands[2]) == CONST_INT
5262 /* Avoid overflows. */
5263 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5264 && (INTVAL (operands[2]) == 128
5265 || (INTVAL (operands[2]) < 0
5266 && INTVAL (operands[2]) != -128)))
5268 operands[2] = GEN_INT (-INTVAL (operands[2]));
5269 return "sub{q}\t{%2, %0|%0, %2}";
5271 return "add{q}\t{%2, %0|%0, %2}";
5275 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5276 (const_string "incdec")
5277 (const_string "alu")))
5278 (set_attr "mode" "DI")])
5280 ; For comparisons against 1, -1 and 128, we may generate better code
5281 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5282 ; is matched then. We can't accept general immediate, because for
5283 ; case of overflows, the result is messed up.
5284 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5286 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5287 ; only for comparisons not depending on it.
5288 (define_insn "*adddi_4_rex64"
5289 [(set (reg FLAGS_REG)
5290 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5291 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5292 (clobber (match_scratch:DI 0 "=rm"))]
5294 && ix86_match_ccmode (insn, CCGCmode)"
5296 switch (get_attr_type (insn))
5299 if (operands[2] == constm1_rtx)
5300 return "inc{q}\t%0";
5303 gcc_assert (operands[2] == const1_rtx);
5304 return "dec{q}\t%0";
5308 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5309 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5310 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5311 if ((INTVAL (operands[2]) == -128
5312 || (INTVAL (operands[2]) > 0
5313 && INTVAL (operands[2]) != 128))
5314 /* Avoid overflows. */
5315 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5316 return "sub{q}\t{%2, %0|%0, %2}";
5317 operands[2] = GEN_INT (-INTVAL (operands[2]));
5318 return "add{q}\t{%2, %0|%0, %2}";
5322 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5323 (const_string "incdec")
5324 (const_string "alu")))
5325 (set_attr "mode" "DI")])
5327 (define_insn "*adddi_5_rex64"
5328 [(set (reg FLAGS_REG)
5330 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5331 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5333 (clobber (match_scratch:DI 0 "=r"))]
5335 && ix86_match_ccmode (insn, CCGOCmode)
5336 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5337 /* Current assemblers are broken and do not allow @GOTOFF in
5338 ought but a memory context. */
5339 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5341 switch (get_attr_type (insn))
5344 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5345 if (operands[2] == const1_rtx)
5346 return "inc{q}\t%0";
5349 gcc_assert (operands[2] == constm1_rtx);
5350 return "dec{q}\t%0";
5354 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5355 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5356 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5357 if (GET_CODE (operands[2]) == CONST_INT
5358 /* Avoid overflows. */
5359 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5360 && (INTVAL (operands[2]) == 128
5361 || (INTVAL (operands[2]) < 0
5362 && INTVAL (operands[2]) != -128)))
5364 operands[2] = GEN_INT (-INTVAL (operands[2]));
5365 return "sub{q}\t{%2, %0|%0, %2}";
5367 return "add{q}\t{%2, %0|%0, %2}";
5371 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5372 (const_string "incdec")
5373 (const_string "alu")))
5374 (set_attr "mode" "DI")])
5377 (define_insn "*addsi_1"
5378 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5379 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5380 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5381 (clobber (reg:CC FLAGS_REG))]
5382 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5384 switch (get_attr_type (insn))
5387 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5388 return "lea{l}\t{%a2, %0|%0, %a2}";
5391 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5392 if (operands[2] == const1_rtx)
5393 return "inc{l}\t%0";
5396 gcc_assert (operands[2] == constm1_rtx);
5397 return "dec{l}\t%0";
5401 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5403 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5404 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5405 if (GET_CODE (operands[2]) == CONST_INT
5406 && (INTVAL (operands[2]) == 128
5407 || (INTVAL (operands[2]) < 0
5408 && INTVAL (operands[2]) != -128)))
5410 operands[2] = GEN_INT (-INTVAL (operands[2]));
5411 return "sub{l}\t{%2, %0|%0, %2}";
5413 return "add{l}\t{%2, %0|%0, %2}";
5417 (cond [(eq_attr "alternative" "2")
5418 (const_string "lea")
5419 ; Current assemblers are broken and do not allow @GOTOFF in
5420 ; ought but a memory context.
5421 (match_operand:SI 2 "pic_symbolic_operand" "")
5422 (const_string "lea")
5423 (match_operand:SI 2 "incdec_operand" "")
5424 (const_string "incdec")
5426 (const_string "alu")))
5427 (set_attr "mode" "SI")])
5429 ;; Convert lea to the lea pattern to avoid flags dependency.
5431 [(set (match_operand 0 "register_operand" "")
5432 (plus (match_operand 1 "register_operand" "")
5433 (match_operand 2 "nonmemory_operand" "")))
5434 (clobber (reg:CC FLAGS_REG))]
5436 && true_regnum (operands[0]) != true_regnum (operands[1])"
5440 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5441 may confuse gen_lowpart. */
5442 if (GET_MODE (operands[0]) != Pmode)
5444 operands[1] = gen_lowpart (Pmode, operands[1]);
5445 operands[2] = gen_lowpart (Pmode, operands[2]);
5447 operands[0] = gen_lowpart (SImode, operands[0]);
5448 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5449 if (Pmode != SImode)
5450 pat = gen_rtx_SUBREG (SImode, pat, 0);
5451 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5455 ;; It may seem that nonimmediate operand is proper one for operand 1.
5456 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5457 ;; we take care in ix86_binary_operator_ok to not allow two memory
5458 ;; operands so proper swapping will be done in reload. This allow
5459 ;; patterns constructed from addsi_1 to match.
5460 (define_insn "addsi_1_zext"
5461 [(set (match_operand:DI 0 "register_operand" "=r,r")
5463 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5464 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5465 (clobber (reg:CC FLAGS_REG))]
5466 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5468 switch (get_attr_type (insn))
5471 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5472 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5475 if (operands[2] == const1_rtx)
5476 return "inc{l}\t%k0";
5479 gcc_assert (operands[2] == constm1_rtx);
5480 return "dec{l}\t%k0";
5484 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5485 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5486 if (GET_CODE (operands[2]) == CONST_INT
5487 && (INTVAL (operands[2]) == 128
5488 || (INTVAL (operands[2]) < 0
5489 && INTVAL (operands[2]) != -128)))
5491 operands[2] = GEN_INT (-INTVAL (operands[2]));
5492 return "sub{l}\t{%2, %k0|%k0, %2}";
5494 return "add{l}\t{%2, %k0|%k0, %2}";
5498 (cond [(eq_attr "alternative" "1")
5499 (const_string "lea")
5500 ; Current assemblers are broken and do not allow @GOTOFF in
5501 ; ought but a memory context.
5502 (match_operand:SI 2 "pic_symbolic_operand" "")
5503 (const_string "lea")
5504 (match_operand:SI 2 "incdec_operand" "")
5505 (const_string "incdec")
5507 (const_string "alu")))
5508 (set_attr "mode" "SI")])
5510 ;; Convert lea to the lea pattern to avoid flags dependency.
5512 [(set (match_operand:DI 0 "register_operand" "")
5514 (plus:SI (match_operand:SI 1 "register_operand" "")
5515 (match_operand:SI 2 "nonmemory_operand" ""))))
5516 (clobber (reg:CC FLAGS_REG))]
5517 "TARGET_64BIT && reload_completed
5518 && true_regnum (operands[0]) != true_regnum (operands[1])"
5520 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5522 operands[1] = gen_lowpart (Pmode, operands[1]);
5523 operands[2] = gen_lowpart (Pmode, operands[2]);
5526 (define_insn "*addsi_2"
5527 [(set (reg FLAGS_REG)
5529 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5530 (match_operand:SI 2 "general_operand" "rmni,rni"))
5532 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5533 (plus:SI (match_dup 1) (match_dup 2)))]
5534 "ix86_match_ccmode (insn, CCGOCmode)
5535 && ix86_binary_operator_ok (PLUS, SImode, operands)
5536 /* Current assemblers are broken and do not allow @GOTOFF in
5537 ought but a memory context. */
5538 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5540 switch (get_attr_type (insn))
5543 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5544 if (operands[2] == const1_rtx)
5545 return "inc{l}\t%0";
5548 gcc_assert (operands[2] == constm1_rtx);
5549 return "dec{l}\t%0";
5553 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5554 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5555 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5556 if (GET_CODE (operands[2]) == CONST_INT
5557 && (INTVAL (operands[2]) == 128
5558 || (INTVAL (operands[2]) < 0
5559 && INTVAL (operands[2]) != -128)))
5561 operands[2] = GEN_INT (-INTVAL (operands[2]));
5562 return "sub{l}\t{%2, %0|%0, %2}";
5564 return "add{l}\t{%2, %0|%0, %2}";
5568 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5569 (const_string "incdec")
5570 (const_string "alu")))
5571 (set_attr "mode" "SI")])
5573 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5574 (define_insn "*addsi_2_zext"
5575 [(set (reg FLAGS_REG)
5577 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5578 (match_operand:SI 2 "general_operand" "rmni"))
5580 (set (match_operand:DI 0 "register_operand" "=r")
5581 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5582 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5583 && ix86_binary_operator_ok (PLUS, SImode, operands)
5584 /* Current assemblers are broken and do not allow @GOTOFF in
5585 ought but a memory context. */
5586 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5588 switch (get_attr_type (insn))
5591 if (operands[2] == const1_rtx)
5592 return "inc{l}\t%k0";
5595 gcc_assert (operands[2] == constm1_rtx);
5596 return "dec{l}\t%k0";
5600 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5601 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5602 if (GET_CODE (operands[2]) == CONST_INT
5603 && (INTVAL (operands[2]) == 128
5604 || (INTVAL (operands[2]) < 0
5605 && INTVAL (operands[2]) != -128)))
5607 operands[2] = GEN_INT (-INTVAL (operands[2]));
5608 return "sub{l}\t{%2, %k0|%k0, %2}";
5610 return "add{l}\t{%2, %k0|%k0, %2}";
5614 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5615 (const_string "incdec")
5616 (const_string "alu")))
5617 (set_attr "mode" "SI")])
5619 (define_insn "*addsi_3"
5620 [(set (reg FLAGS_REG)
5621 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5622 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5623 (clobber (match_scratch:SI 0 "=r"))]
5624 "ix86_match_ccmode (insn, CCZmode)
5625 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5626 /* Current assemblers are broken and do not allow @GOTOFF in
5627 ought but a memory context. */
5628 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5630 switch (get_attr_type (insn))
5633 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634 if (operands[2] == const1_rtx)
5635 return "inc{l}\t%0";
5638 gcc_assert (operands[2] == constm1_rtx);
5639 return "dec{l}\t%0";
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5645 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5646 if (GET_CODE (operands[2]) == CONST_INT
5647 && (INTVAL (operands[2]) == 128
5648 || (INTVAL (operands[2]) < 0
5649 && INTVAL (operands[2]) != -128)))
5651 operands[2] = GEN_INT (-INTVAL (operands[2]));
5652 return "sub{l}\t{%2, %0|%0, %2}";
5654 return "add{l}\t{%2, %0|%0, %2}";
5658 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5659 (const_string "incdec")
5660 (const_string "alu")))
5661 (set_attr "mode" "SI")])
5663 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5664 (define_insn "*addsi_3_zext"
5665 [(set (reg FLAGS_REG)
5666 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5667 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5668 (set (match_operand:DI 0 "register_operand" "=r")
5669 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5670 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5671 && ix86_binary_operator_ok (PLUS, SImode, operands)
5672 /* Current assemblers are broken and do not allow @GOTOFF in
5673 ought but a memory context. */
5674 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5676 switch (get_attr_type (insn))
5679 if (operands[2] == const1_rtx)
5680 return "inc{l}\t%k0";
5683 gcc_assert (operands[2] == constm1_rtx);
5684 return "dec{l}\t%k0";
5688 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5689 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5690 if (GET_CODE (operands[2]) == CONST_INT
5691 && (INTVAL (operands[2]) == 128
5692 || (INTVAL (operands[2]) < 0
5693 && INTVAL (operands[2]) != -128)))
5695 operands[2] = GEN_INT (-INTVAL (operands[2]));
5696 return "sub{l}\t{%2, %k0|%k0, %2}";
5698 return "add{l}\t{%2, %k0|%k0, %2}";
5702 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5703 (const_string "incdec")
5704 (const_string "alu")))
5705 (set_attr "mode" "SI")])
5707 ; For comparisons against 1, -1 and 128, we may generate better code
5708 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5709 ; is matched then. We can't accept general immediate, because for
5710 ; case of overflows, the result is messed up.
5711 ; This pattern also don't hold of 0x80000000, since the value overflows
5713 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5714 ; only for comparisons not depending on it.
5715 (define_insn "*addsi_4"
5716 [(set (reg FLAGS_REG)
5717 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5718 (match_operand:SI 2 "const_int_operand" "n")))
5719 (clobber (match_scratch:SI 0 "=rm"))]
5720 "ix86_match_ccmode (insn, CCGCmode)
5721 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5723 switch (get_attr_type (insn))
5726 if (operands[2] == constm1_rtx)
5727 return "inc{l}\t%0";
5730 gcc_assert (operands[2] == const1_rtx);
5731 return "dec{l}\t%0";
5735 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5737 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5738 if ((INTVAL (operands[2]) == -128
5739 || (INTVAL (operands[2]) > 0
5740 && INTVAL (operands[2]) != 128)))
5741 return "sub{l}\t{%2, %0|%0, %2}";
5742 operands[2] = GEN_INT (-INTVAL (operands[2]));
5743 return "add{l}\t{%2, %0|%0, %2}";
5747 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5748 (const_string "incdec")
5749 (const_string "alu")))
5750 (set_attr "mode" "SI")])
5752 (define_insn "*addsi_5"
5753 [(set (reg FLAGS_REG)
5755 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5756 (match_operand:SI 2 "general_operand" "rmni"))
5758 (clobber (match_scratch:SI 0 "=r"))]
5759 "ix86_match_ccmode (insn, CCGOCmode)
5760 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5761 /* Current assemblers are broken and do not allow @GOTOFF in
5762 ought but a memory context. */
5763 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5765 switch (get_attr_type (insn))
5768 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5769 if (operands[2] == const1_rtx)
5770 return "inc{l}\t%0";
5773 gcc_assert (operands[2] == constm1_rtx);
5774 return "dec{l}\t%0";
5778 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5779 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5780 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5781 if (GET_CODE (operands[2]) == CONST_INT
5782 && (INTVAL (operands[2]) == 128
5783 || (INTVAL (operands[2]) < 0
5784 && INTVAL (operands[2]) != -128)))
5786 operands[2] = GEN_INT (-INTVAL (operands[2]));
5787 return "sub{l}\t{%2, %0|%0, %2}";
5789 return "add{l}\t{%2, %0|%0, %2}";
5793 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5794 (const_string "incdec")
5795 (const_string "alu")))
5796 (set_attr "mode" "SI")])
5798 (define_expand "addhi3"
5799 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5800 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5801 (match_operand:HI 2 "general_operand" "")))
5802 (clobber (reg:CC FLAGS_REG))])]
5803 "TARGET_HIMODE_MATH"
5804 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5806 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5807 ;; type optimizations enabled by define-splits. This is not important
5808 ;; for PII, and in fact harmful because of partial register stalls.
5810 (define_insn "*addhi_1_lea"
5811 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5812 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5813 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5814 (clobber (reg:CC FLAGS_REG))]
5815 "!TARGET_PARTIAL_REG_STALL
5816 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5818 switch (get_attr_type (insn))
5823 if (operands[2] == const1_rtx)
5824 return "inc{w}\t%0";
5827 gcc_assert (operands[2] == constm1_rtx);
5828 return "dec{w}\t%0";
5832 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5833 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5834 if (GET_CODE (operands[2]) == CONST_INT
5835 && (INTVAL (operands[2]) == 128
5836 || (INTVAL (operands[2]) < 0
5837 && INTVAL (operands[2]) != -128)))
5839 operands[2] = GEN_INT (-INTVAL (operands[2]));
5840 return "sub{w}\t{%2, %0|%0, %2}";
5842 return "add{w}\t{%2, %0|%0, %2}";
5846 (if_then_else (eq_attr "alternative" "2")
5847 (const_string "lea")
5848 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5849 (const_string "incdec")
5850 (const_string "alu"))))
5851 (set_attr "mode" "HI,HI,SI")])
5853 (define_insn "*addhi_1"
5854 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5855 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5856 (match_operand:HI 2 "general_operand" "ri,rm")))
5857 (clobber (reg:CC FLAGS_REG))]
5858 "TARGET_PARTIAL_REG_STALL
5859 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5861 switch (get_attr_type (insn))
5864 if (operands[2] == const1_rtx)
5865 return "inc{w}\t%0";
5868 gcc_assert (operands[2] == constm1_rtx);
5869 return "dec{w}\t%0";
5873 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5874 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5875 if (GET_CODE (operands[2]) == CONST_INT
5876 && (INTVAL (operands[2]) == 128
5877 || (INTVAL (operands[2]) < 0
5878 && INTVAL (operands[2]) != -128)))
5880 operands[2] = GEN_INT (-INTVAL (operands[2]));
5881 return "sub{w}\t{%2, %0|%0, %2}";
5883 return "add{w}\t{%2, %0|%0, %2}";
5887 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5888 (const_string "incdec")
5889 (const_string "alu")))
5890 (set_attr "mode" "HI")])
5892 (define_insn "*addhi_2"
5893 [(set (reg FLAGS_REG)
5895 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896 (match_operand:HI 2 "general_operand" "rmni,rni"))
5898 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5899 (plus:HI (match_dup 1) (match_dup 2)))]
5900 "ix86_match_ccmode (insn, CCGOCmode)
5901 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5903 switch (get_attr_type (insn))
5906 if (operands[2] == const1_rtx)
5907 return "inc{w}\t%0";
5910 gcc_assert (operands[2] == constm1_rtx);
5911 return "dec{w}\t%0";
5915 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5916 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5917 if (GET_CODE (operands[2]) == CONST_INT
5918 && (INTVAL (operands[2]) == 128
5919 || (INTVAL (operands[2]) < 0
5920 && INTVAL (operands[2]) != -128)))
5922 operands[2] = GEN_INT (-INTVAL (operands[2]));
5923 return "sub{w}\t{%2, %0|%0, %2}";
5925 return "add{w}\t{%2, %0|%0, %2}";
5929 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5930 (const_string "incdec")
5931 (const_string "alu")))
5932 (set_attr "mode" "HI")])
5934 (define_insn "*addhi_3"
5935 [(set (reg FLAGS_REG)
5936 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5937 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5938 (clobber (match_scratch:HI 0 "=r"))]
5939 "ix86_match_ccmode (insn, CCZmode)
5940 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5942 switch (get_attr_type (insn))
5945 if (operands[2] == const1_rtx)
5946 return "inc{w}\t%0";
5949 gcc_assert (operands[2] == constm1_rtx);
5950 return "dec{w}\t%0";
5954 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5955 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5956 if (GET_CODE (operands[2]) == CONST_INT
5957 && (INTVAL (operands[2]) == 128
5958 || (INTVAL (operands[2]) < 0
5959 && INTVAL (operands[2]) != -128)))
5961 operands[2] = GEN_INT (-INTVAL (operands[2]));
5962 return "sub{w}\t{%2, %0|%0, %2}";
5964 return "add{w}\t{%2, %0|%0, %2}";
5968 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5969 (const_string "incdec")
5970 (const_string "alu")))
5971 (set_attr "mode" "HI")])
5973 ; See comments above addsi_4 for details.
5974 (define_insn "*addhi_4"
5975 [(set (reg FLAGS_REG)
5976 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
5977 (match_operand:HI 2 "const_int_operand" "n")))
5978 (clobber (match_scratch:HI 0 "=rm"))]
5979 "ix86_match_ccmode (insn, CCGCmode)
5980 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
5982 switch (get_attr_type (insn))
5985 if (operands[2] == constm1_rtx)
5986 return "inc{w}\t%0";
5989 gcc_assert (operands[2] == const1_rtx);
5990 return "dec{w}\t%0";
5994 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5995 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5996 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5997 if ((INTVAL (operands[2]) == -128
5998 || (INTVAL (operands[2]) > 0
5999 && INTVAL (operands[2]) != 128)))
6000 return "sub{w}\t{%2, %0|%0, %2}";
6001 operands[2] = GEN_INT (-INTVAL (operands[2]));
6002 return "add{w}\t{%2, %0|%0, %2}";
6006 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6007 (const_string "incdec")
6008 (const_string "alu")))
6009 (set_attr "mode" "SI")])
6012 (define_insn "*addhi_5"
6013 [(set (reg FLAGS_REG)
6015 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6016 (match_operand:HI 2 "general_operand" "rmni"))
6018 (clobber (match_scratch:HI 0 "=r"))]
6019 "ix86_match_ccmode (insn, CCGOCmode)
6020 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6022 switch (get_attr_type (insn))
6025 if (operands[2] == const1_rtx)
6026 return "inc{w}\t%0";
6029 gcc_assert (operands[2] == constm1_rtx);
6030 return "dec{w}\t%0";
6034 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6035 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6036 if (GET_CODE (operands[2]) == CONST_INT
6037 && (INTVAL (operands[2]) == 128
6038 || (INTVAL (operands[2]) < 0
6039 && INTVAL (operands[2]) != -128)))
6041 operands[2] = GEN_INT (-INTVAL (operands[2]));
6042 return "sub{w}\t{%2, %0|%0, %2}";
6044 return "add{w}\t{%2, %0|%0, %2}";
6048 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6049 (const_string "incdec")
6050 (const_string "alu")))
6051 (set_attr "mode" "HI")])
6053 (define_expand "addqi3"
6054 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6055 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6056 (match_operand:QI 2 "general_operand" "")))
6057 (clobber (reg:CC FLAGS_REG))])]
6058 "TARGET_QIMODE_MATH"
6059 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6061 ;; %%% Potential partial reg stall on alternative 2. What to do?
6062 (define_insn "*addqi_1_lea"
6063 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6064 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6065 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6066 (clobber (reg:CC FLAGS_REG))]
6067 "!TARGET_PARTIAL_REG_STALL
6068 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6070 int widen = (which_alternative == 2);
6071 switch (get_attr_type (insn))
6076 if (operands[2] == const1_rtx)
6077 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6080 gcc_assert (operands[2] == constm1_rtx);
6081 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6085 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6086 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6087 if (GET_CODE (operands[2]) == CONST_INT
6088 && (INTVAL (operands[2]) == 128
6089 || (INTVAL (operands[2]) < 0
6090 && INTVAL (operands[2]) != -128)))
6092 operands[2] = GEN_INT (-INTVAL (operands[2]));
6094 return "sub{l}\t{%2, %k0|%k0, %2}";
6096 return "sub{b}\t{%2, %0|%0, %2}";
6099 return "add{l}\t{%k2, %k0|%k0, %k2}";
6101 return "add{b}\t{%2, %0|%0, %2}";
6105 (if_then_else (eq_attr "alternative" "3")
6106 (const_string "lea")
6107 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6108 (const_string "incdec")
6109 (const_string "alu"))))
6110 (set_attr "mode" "QI,QI,SI,SI")])
6112 (define_insn "*addqi_1"
6113 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6114 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6115 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6116 (clobber (reg:CC FLAGS_REG))]
6117 "TARGET_PARTIAL_REG_STALL
6118 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6120 int widen = (which_alternative == 2);
6121 switch (get_attr_type (insn))
6124 if (operands[2] == const1_rtx)
6125 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6128 gcc_assert (operands[2] == constm1_rtx);
6129 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6133 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6134 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6135 if (GET_CODE (operands[2]) == CONST_INT
6136 && (INTVAL (operands[2]) == 128
6137 || (INTVAL (operands[2]) < 0
6138 && INTVAL (operands[2]) != -128)))
6140 operands[2] = GEN_INT (-INTVAL (operands[2]));
6142 return "sub{l}\t{%2, %k0|%k0, %2}";
6144 return "sub{b}\t{%2, %0|%0, %2}";
6147 return "add{l}\t{%k2, %k0|%k0, %k2}";
6149 return "add{b}\t{%2, %0|%0, %2}";
6153 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6154 (const_string "incdec")
6155 (const_string "alu")))
6156 (set_attr "mode" "QI,QI,SI")])
6158 (define_insn "*addqi_1_slp"
6159 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6160 (plus:QI (match_dup 0)
6161 (match_operand:QI 1 "general_operand" "qn,qnm")))
6162 (clobber (reg:CC FLAGS_REG))]
6163 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6164 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6166 switch (get_attr_type (insn))
6169 if (operands[1] == const1_rtx)
6170 return "inc{b}\t%0";
6173 gcc_assert (operands[1] == constm1_rtx);
6174 return "dec{b}\t%0";
6178 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6179 if (GET_CODE (operands[1]) == CONST_INT
6180 && INTVAL (operands[1]) < 0)
6182 operands[1] = GEN_INT (-INTVAL (operands[1]));
6183 return "sub{b}\t{%1, %0|%0, %1}";
6185 return "add{b}\t{%1, %0|%0, %1}";
6189 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6190 (const_string "incdec")
6191 (const_string "alu1")))
6192 (set (attr "memory")
6193 (if_then_else (match_operand 1 "memory_operand" "")
6194 (const_string "load")
6195 (const_string "none")))
6196 (set_attr "mode" "QI")])
6198 (define_insn "*addqi_2"
6199 [(set (reg FLAGS_REG)
6201 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6202 (match_operand:QI 2 "general_operand" "qmni,qni"))
6204 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6205 (plus:QI (match_dup 1) (match_dup 2)))]
6206 "ix86_match_ccmode (insn, CCGOCmode)
6207 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6209 switch (get_attr_type (insn))
6212 if (operands[2] == const1_rtx)
6213 return "inc{b}\t%0";
6216 gcc_assert (operands[2] == constm1_rtx
6217 || (GET_CODE (operands[2]) == CONST_INT
6218 && INTVAL (operands[2]) == 255));
6219 return "dec{b}\t%0";
6223 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6224 if (GET_CODE (operands[2]) == CONST_INT
6225 && INTVAL (operands[2]) < 0)
6227 operands[2] = GEN_INT (-INTVAL (operands[2]));
6228 return "sub{b}\t{%2, %0|%0, %2}";
6230 return "add{b}\t{%2, %0|%0, %2}";
6234 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6235 (const_string "incdec")
6236 (const_string "alu")))
6237 (set_attr "mode" "QI")])
6239 (define_insn "*addqi_3"
6240 [(set (reg FLAGS_REG)
6241 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6242 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6243 (clobber (match_scratch:QI 0 "=q"))]
6244 "ix86_match_ccmode (insn, CCZmode)
6245 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6247 switch (get_attr_type (insn))
6250 if (operands[2] == const1_rtx)
6251 return "inc{b}\t%0";
6254 gcc_assert (operands[2] == constm1_rtx
6255 || (GET_CODE (operands[2]) == CONST_INT
6256 && INTVAL (operands[2]) == 255));
6257 return "dec{b}\t%0";
6261 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6262 if (GET_CODE (operands[2]) == CONST_INT
6263 && INTVAL (operands[2]) < 0)
6265 operands[2] = GEN_INT (-INTVAL (operands[2]));
6266 return "sub{b}\t{%2, %0|%0, %2}";
6268 return "add{b}\t{%2, %0|%0, %2}";
6272 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6273 (const_string "incdec")
6274 (const_string "alu")))
6275 (set_attr "mode" "QI")])
6277 ; See comments above addsi_4 for details.
6278 (define_insn "*addqi_4"
6279 [(set (reg FLAGS_REG)
6280 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6281 (match_operand:QI 2 "const_int_operand" "n")))
6282 (clobber (match_scratch:QI 0 "=qm"))]
6283 "ix86_match_ccmode (insn, CCGCmode)
6284 && (INTVAL (operands[2]) & 0xff) != 0x80"
6286 switch (get_attr_type (insn))
6289 if (operands[2] == constm1_rtx
6290 || (GET_CODE (operands[2]) == CONST_INT
6291 && INTVAL (operands[2]) == 255))
6292 return "inc{b}\t%0";
6295 gcc_assert (operands[2] == const1_rtx);
6296 return "dec{b}\t%0";
6300 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6301 if (INTVAL (operands[2]) < 0)
6303 operands[2] = GEN_INT (-INTVAL (operands[2]));
6304 return "add{b}\t{%2, %0|%0, %2}";
6306 return "sub{b}\t{%2, %0|%0, %2}";
6310 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6311 (const_string "incdec")
6312 (const_string "alu")))
6313 (set_attr "mode" "QI")])
6316 (define_insn "*addqi_5"
6317 [(set (reg FLAGS_REG)
6319 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6320 (match_operand:QI 2 "general_operand" "qmni"))
6322 (clobber (match_scratch:QI 0 "=q"))]
6323 "ix86_match_ccmode (insn, CCGOCmode)
6324 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6326 switch (get_attr_type (insn))
6329 if (operands[2] == const1_rtx)
6330 return "inc{b}\t%0";
6333 gcc_assert (operands[2] == constm1_rtx
6334 || (GET_CODE (operands[2]) == CONST_INT
6335 && INTVAL (operands[2]) == 255));
6336 return "dec{b}\t%0";
6340 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6341 if (GET_CODE (operands[2]) == CONST_INT
6342 && INTVAL (operands[2]) < 0)
6344 operands[2] = GEN_INT (-INTVAL (operands[2]));
6345 return "sub{b}\t{%2, %0|%0, %2}";
6347 return "add{b}\t{%2, %0|%0, %2}";
6351 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6352 (const_string "incdec")
6353 (const_string "alu")))
6354 (set_attr "mode" "QI")])
6357 (define_insn "addqi_ext_1"
6358 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6363 (match_operand 1 "ext_register_operand" "0")
6366 (match_operand:QI 2 "general_operand" "Qmn")))
6367 (clobber (reg:CC FLAGS_REG))]
6370 switch (get_attr_type (insn))
6373 if (operands[2] == const1_rtx)
6374 return "inc{b}\t%h0";
6377 gcc_assert (operands[2] == constm1_rtx
6378 || (GET_CODE (operands[2]) == CONST_INT
6379 && INTVAL (operands[2]) == 255));
6380 return "dec{b}\t%h0";
6384 return "add{b}\t{%2, %h0|%h0, %2}";
6388 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6389 (const_string "incdec")
6390 (const_string "alu")))
6391 (set_attr "mode" "QI")])
6393 (define_insn "*addqi_ext_1_rex64"
6394 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6399 (match_operand 1 "ext_register_operand" "0")
6402 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6403 (clobber (reg:CC FLAGS_REG))]
6406 switch (get_attr_type (insn))
6409 if (operands[2] == const1_rtx)
6410 return "inc{b}\t%h0";
6413 gcc_assert (operands[2] == constm1_rtx
6414 || (GET_CODE (operands[2]) == CONST_INT
6415 && INTVAL (operands[2]) == 255));
6416 return "dec{b}\t%h0";
6420 return "add{b}\t{%2, %h0|%h0, %2}";
6424 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6425 (const_string "incdec")
6426 (const_string "alu")))
6427 (set_attr "mode" "QI")])
6429 (define_insn "*addqi_ext_2"
6430 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6435 (match_operand 1 "ext_register_operand" "%0")
6439 (match_operand 2 "ext_register_operand" "Q")
6442 (clobber (reg:CC FLAGS_REG))]
6444 "add{b}\t{%h2, %h0|%h0, %h2}"
6445 [(set_attr "type" "alu")
6446 (set_attr "mode" "QI")])
6448 ;; The patterns that match these are at the end of this file.
6450 (define_expand "addxf3"
6451 [(set (match_operand:XF 0 "register_operand" "")
6452 (plus:XF (match_operand:XF 1 "register_operand" "")
6453 (match_operand:XF 2 "register_operand" "")))]
6457 (define_expand "adddf3"
6458 [(set (match_operand:DF 0 "register_operand" "")
6459 (plus:DF (match_operand:DF 1 "register_operand" "")
6460 (match_operand:DF 2 "nonimmediate_operand" "")))]
6461 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6464 (define_expand "addsf3"
6465 [(set (match_operand:SF 0 "register_operand" "")
6466 (plus:SF (match_operand:SF 1 "register_operand" "")
6467 (match_operand:SF 2 "nonimmediate_operand" "")))]
6468 "TARGET_80387 || TARGET_SSE_MATH"
6471 ;; Subtract instructions
6473 ;; %%% splits for subditi3
6475 (define_expand "subti3"
6476 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6477 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6478 (match_operand:TI 2 "x86_64_general_operand" "")))
6479 (clobber (reg:CC FLAGS_REG))])]
6481 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6483 (define_insn "*subti3_1"
6484 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6485 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6486 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6492 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6493 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6494 (match_operand:TI 2 "x86_64_general_operand" "")))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "TARGET_64BIT && reload_completed"
6497 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6498 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6499 (parallel [(set (match_dup 3)
6500 (minus:DI (match_dup 4)
6501 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6503 (clobber (reg:CC FLAGS_REG))])]
6504 "split_ti (operands+0, 1, operands+0, operands+3);
6505 split_ti (operands+1, 1, operands+1, operands+4);
6506 split_ti (operands+2, 1, operands+2, operands+5);")
6508 ;; %%% splits for subsidi3
6510 (define_expand "subdi3"
6511 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6512 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6513 (match_operand:DI 2 "x86_64_general_operand" "")))
6514 (clobber (reg:CC FLAGS_REG))])]
6516 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6518 (define_insn "*subdi3_1"
6519 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6520 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6521 (match_operand:DI 2 "general_operand" "roiF,riF")))
6522 (clobber (reg:CC FLAGS_REG))]
6523 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6527 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6528 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6529 (match_operand:DI 2 "general_operand" "")))
6530 (clobber (reg:CC FLAGS_REG))]
6531 "!TARGET_64BIT && reload_completed"
6532 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6533 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6534 (parallel [(set (match_dup 3)
6535 (minus:SI (match_dup 4)
6536 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6538 (clobber (reg:CC FLAGS_REG))])]
6539 "split_di (operands+0, 1, operands+0, operands+3);
6540 split_di (operands+1, 1, operands+1, operands+4);
6541 split_di (operands+2, 1, operands+2, operands+5);")
6543 (define_insn "subdi3_carry_rex64"
6544 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6545 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6546 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6547 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6548 (clobber (reg:CC FLAGS_REG))]
6549 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6550 "sbb{q}\t{%2, %0|%0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "pent_pair" "pu")
6553 (set_attr "mode" "DI")])
6555 (define_insn "*subdi_1_rex64"
6556 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6557 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6558 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6559 (clobber (reg:CC FLAGS_REG))]
6560 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6561 "sub{q}\t{%2, %0|%0, %2}"
6562 [(set_attr "type" "alu")
6563 (set_attr "mode" "DI")])
6565 (define_insn "*subdi_2_rex64"
6566 [(set (reg FLAGS_REG)
6568 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6569 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6571 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6572 (minus:DI (match_dup 1) (match_dup 2)))]
6573 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6574 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6575 "sub{q}\t{%2, %0|%0, %2}"
6576 [(set_attr "type" "alu")
6577 (set_attr "mode" "DI")])
6579 (define_insn "*subdi_3_rex63"
6580 [(set (reg FLAGS_REG)
6581 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6582 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6583 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6584 (minus:DI (match_dup 1) (match_dup 2)))]
6585 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6586 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6587 "sub{q}\t{%2, %0|%0, %2}"
6588 [(set_attr "type" "alu")
6589 (set_attr "mode" "DI")])
6591 (define_insn "subqi3_carry"
6592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6593 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6594 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6595 (match_operand:QI 2 "general_operand" "qi,qm"))))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6598 "sbb{b}\t{%2, %0|%0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "pent_pair" "pu")
6601 (set_attr "mode" "QI")])
6603 (define_insn "subhi3_carry"
6604 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6605 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6606 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6607 (match_operand:HI 2 "general_operand" "ri,rm"))))
6608 (clobber (reg:CC FLAGS_REG))]
6609 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6610 "sbb{w}\t{%2, %0|%0, %2}"
6611 [(set_attr "type" "alu")
6612 (set_attr "pent_pair" "pu")
6613 (set_attr "mode" "HI")])
6615 (define_insn "subsi3_carry"
6616 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6617 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6618 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6619 (match_operand:SI 2 "general_operand" "ri,rm"))))
6620 (clobber (reg:CC FLAGS_REG))]
6621 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6622 "sbb{l}\t{%2, %0|%0, %2}"
6623 [(set_attr "type" "alu")
6624 (set_attr "pent_pair" "pu")
6625 (set_attr "mode" "SI")])
6627 (define_insn "subsi3_carry_zext"
6628 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6630 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6631 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6632 (match_operand:SI 2 "general_operand" "ri,rm")))))
6633 (clobber (reg:CC FLAGS_REG))]
6634 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6635 "sbb{l}\t{%2, %k0|%k0, %2}"
6636 [(set_attr "type" "alu")
6637 (set_attr "pent_pair" "pu")
6638 (set_attr "mode" "SI")])
6640 (define_expand "subsi3"
6641 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6642 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6643 (match_operand:SI 2 "general_operand" "")))
6644 (clobber (reg:CC FLAGS_REG))])]
6646 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6648 (define_insn "*subsi_1"
6649 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6650 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6651 (match_operand:SI 2 "general_operand" "ri,rm")))
6652 (clobber (reg:CC FLAGS_REG))]
6653 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6654 "sub{l}\t{%2, %0|%0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "mode" "SI")])
6658 (define_insn "*subsi_1_zext"
6659 [(set (match_operand:DI 0 "register_operand" "=r")
6661 (minus:SI (match_operand:SI 1 "register_operand" "0")
6662 (match_operand:SI 2 "general_operand" "rim"))))
6663 (clobber (reg:CC FLAGS_REG))]
6664 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6665 "sub{l}\t{%2, %k0|%k0, %2}"
6666 [(set_attr "type" "alu")
6667 (set_attr "mode" "SI")])
6669 (define_insn "*subsi_2"
6670 [(set (reg FLAGS_REG)
6672 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6673 (match_operand:SI 2 "general_operand" "ri,rm"))
6675 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6676 (minus:SI (match_dup 1) (match_dup 2)))]
6677 "ix86_match_ccmode (insn, CCGOCmode)
6678 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6679 "sub{l}\t{%2, %0|%0, %2}"
6680 [(set_attr "type" "alu")
6681 (set_attr "mode" "SI")])
6683 (define_insn "*subsi_2_zext"
6684 [(set (reg FLAGS_REG)
6686 (minus:SI (match_operand:SI 1 "register_operand" "0")
6687 (match_operand:SI 2 "general_operand" "rim"))
6689 (set (match_operand:DI 0 "register_operand" "=r")
6691 (minus:SI (match_dup 1)
6693 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6694 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6695 "sub{l}\t{%2, %k0|%k0, %2}"
6696 [(set_attr "type" "alu")
6697 (set_attr "mode" "SI")])
6699 (define_insn "*subsi_3"
6700 [(set (reg FLAGS_REG)
6701 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6702 (match_operand:SI 2 "general_operand" "ri,rm")))
6703 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6704 (minus:SI (match_dup 1) (match_dup 2)))]
6705 "ix86_match_ccmode (insn, CCmode)
6706 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6707 "sub{l}\t{%2, %0|%0, %2}"
6708 [(set_attr "type" "alu")
6709 (set_attr "mode" "SI")])
6711 (define_insn "*subsi_3_zext"
6712 [(set (reg FLAGS_REG)
6713 (compare (match_operand:SI 1 "register_operand" "0")
6714 (match_operand:SI 2 "general_operand" "rim")))
6715 (set (match_operand:DI 0 "register_operand" "=r")
6717 (minus:SI (match_dup 1)
6719 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6720 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721 "sub{l}\t{%2, %1|%1, %2}"
6722 [(set_attr "type" "alu")
6723 (set_attr "mode" "DI")])
6725 (define_expand "subhi3"
6726 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6727 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6728 (match_operand:HI 2 "general_operand" "")))
6729 (clobber (reg:CC FLAGS_REG))])]
6730 "TARGET_HIMODE_MATH"
6731 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6733 (define_insn "*subhi_1"
6734 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6735 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6736 (match_operand:HI 2 "general_operand" "ri,rm")))
6737 (clobber (reg:CC FLAGS_REG))]
6738 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6739 "sub{w}\t{%2, %0|%0, %2}"
6740 [(set_attr "type" "alu")
6741 (set_attr "mode" "HI")])
6743 (define_insn "*subhi_2"
6744 [(set (reg FLAGS_REG)
6746 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6747 (match_operand:HI 2 "general_operand" "ri,rm"))
6749 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6750 (minus:HI (match_dup 1) (match_dup 2)))]
6751 "ix86_match_ccmode (insn, CCGOCmode)
6752 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6753 "sub{w}\t{%2, %0|%0, %2}"
6754 [(set_attr "type" "alu")
6755 (set_attr "mode" "HI")])
6757 (define_insn "*subhi_3"
6758 [(set (reg FLAGS_REG)
6759 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6760 (match_operand:HI 2 "general_operand" "ri,rm")))
6761 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6762 (minus:HI (match_dup 1) (match_dup 2)))]
6763 "ix86_match_ccmode (insn, CCmode)
6764 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6765 "sub{w}\t{%2, %0|%0, %2}"
6766 [(set_attr "type" "alu")
6767 (set_attr "mode" "HI")])
6769 (define_expand "subqi3"
6770 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6771 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6772 (match_operand:QI 2 "general_operand" "")))
6773 (clobber (reg:CC FLAGS_REG))])]
6774 "TARGET_QIMODE_MATH"
6775 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6777 (define_insn "*subqi_1"
6778 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6779 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6780 (match_operand:QI 2 "general_operand" "qn,qmn")))
6781 (clobber (reg:CC FLAGS_REG))]
6782 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6783 "sub{b}\t{%2, %0|%0, %2}"
6784 [(set_attr "type" "alu")
6785 (set_attr "mode" "QI")])
6787 (define_insn "*subqi_1_slp"
6788 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6789 (minus:QI (match_dup 0)
6790 (match_operand:QI 1 "general_operand" "qn,qmn")))
6791 (clobber (reg:CC FLAGS_REG))]
6792 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6793 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6794 "sub{b}\t{%1, %0|%0, %1}"
6795 [(set_attr "type" "alu1")
6796 (set_attr "mode" "QI")])
6798 (define_insn "*subqi_2"
6799 [(set (reg FLAGS_REG)
6801 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6802 (match_operand:QI 2 "general_operand" "qi,qm"))
6804 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6805 (minus:HI (match_dup 1) (match_dup 2)))]
6806 "ix86_match_ccmode (insn, CCGOCmode)
6807 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6808 "sub{b}\t{%2, %0|%0, %2}"
6809 [(set_attr "type" "alu")
6810 (set_attr "mode" "QI")])
6812 (define_insn "*subqi_3"
6813 [(set (reg FLAGS_REG)
6814 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6815 (match_operand:QI 2 "general_operand" "qi,qm")))
6816 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6817 (minus:HI (match_dup 1) (match_dup 2)))]
6818 "ix86_match_ccmode (insn, CCmode)
6819 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6820 "sub{b}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "mode" "QI")])
6824 ;; The patterns that match these are at the end of this file.
6826 (define_expand "subxf3"
6827 [(set (match_operand:XF 0 "register_operand" "")
6828 (minus:XF (match_operand:XF 1 "register_operand" "")
6829 (match_operand:XF 2 "register_operand" "")))]
6833 (define_expand "subdf3"
6834 [(set (match_operand:DF 0 "register_operand" "")
6835 (minus:DF (match_operand:DF 1 "register_operand" "")
6836 (match_operand:DF 2 "nonimmediate_operand" "")))]
6837 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6840 (define_expand "subsf3"
6841 [(set (match_operand:SF 0 "register_operand" "")
6842 (minus:SF (match_operand:SF 1 "register_operand" "")
6843 (match_operand:SF 2 "nonimmediate_operand" "")))]
6844 "TARGET_80387 || TARGET_SSE_MATH"
6847 ;; Multiply instructions
6849 (define_expand "muldi3"
6850 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6851 (mult:DI (match_operand:DI 1 "register_operand" "")
6852 (match_operand:DI 2 "x86_64_general_operand" "")))
6853 (clobber (reg:CC FLAGS_REG))])]
6857 (define_insn "*muldi3_1_rex64"
6858 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6859 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6860 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6861 (clobber (reg:CC FLAGS_REG))]
6863 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6865 imul{q}\t{%2, %1, %0|%0, %1, %2}
6866 imul{q}\t{%2, %1, %0|%0, %1, %2}
6867 imul{q}\t{%2, %0|%0, %2}"
6868 [(set_attr "type" "imul")
6869 (set_attr "prefix_0f" "0,0,1")
6870 (set (attr "athlon_decode")
6871 (cond [(eq_attr "cpu" "athlon")
6872 (const_string "vector")
6873 (eq_attr "alternative" "1")
6874 (const_string "vector")
6875 (and (eq_attr "alternative" "2")
6876 (match_operand 1 "memory_operand" ""))
6877 (const_string "vector")]
6878 (const_string "direct")))
6879 (set_attr "mode" "DI")])
6881 (define_expand "mulsi3"
6882 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6883 (mult:SI (match_operand:SI 1 "register_operand" "")
6884 (match_operand:SI 2 "general_operand" "")))
6885 (clobber (reg:CC FLAGS_REG))])]
6889 (define_insn "*mulsi3_1"
6890 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6891 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6892 (match_operand:SI 2 "general_operand" "K,i,mr")))
6893 (clobber (reg:CC FLAGS_REG))]
6894 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6896 imul{l}\t{%2, %1, %0|%0, %1, %2}
6897 imul{l}\t{%2, %1, %0|%0, %1, %2}
6898 imul{l}\t{%2, %0|%0, %2}"
6899 [(set_attr "type" "imul")
6900 (set_attr "prefix_0f" "0,0,1")
6901 (set (attr "athlon_decode")
6902 (cond [(eq_attr "cpu" "athlon")
6903 (const_string "vector")
6904 (eq_attr "alternative" "1")
6905 (const_string "vector")
6906 (and (eq_attr "alternative" "2")
6907 (match_operand 1 "memory_operand" ""))
6908 (const_string "vector")]
6909 (const_string "direct")))
6910 (set_attr "mode" "SI")])
6912 (define_insn "*mulsi3_1_zext"
6913 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6915 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6916 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6917 (clobber (reg:CC FLAGS_REG))]
6919 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6921 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6923 imul{l}\t{%2, %k0|%k0, %2}"
6924 [(set_attr "type" "imul")
6925 (set_attr "prefix_0f" "0,0,1")
6926 (set (attr "athlon_decode")
6927 (cond [(eq_attr "cpu" "athlon")
6928 (const_string "vector")
6929 (eq_attr "alternative" "1")
6930 (const_string "vector")
6931 (and (eq_attr "alternative" "2")
6932 (match_operand 1 "memory_operand" ""))
6933 (const_string "vector")]
6934 (const_string "direct")))
6935 (set_attr "mode" "SI")])
6937 (define_expand "mulhi3"
6938 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6939 (mult:HI (match_operand:HI 1 "register_operand" "")
6940 (match_operand:HI 2 "general_operand" "")))
6941 (clobber (reg:CC FLAGS_REG))])]
6942 "TARGET_HIMODE_MATH"
6945 (define_insn "*mulhi3_1"
6946 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6947 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6948 (match_operand:HI 2 "general_operand" "K,i,mr")))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6952 imul{w}\t{%2, %1, %0|%0, %1, %2}
6953 imul{w}\t{%2, %1, %0|%0, %1, %2}
6954 imul{w}\t{%2, %0|%0, %2}"
6955 [(set_attr "type" "imul")
6956 (set_attr "prefix_0f" "0,0,1")
6957 (set (attr "athlon_decode")
6958 (cond [(eq_attr "cpu" "athlon")
6959 (const_string "vector")
6960 (eq_attr "alternative" "1,2")
6961 (const_string "vector")]
6962 (const_string "direct")))
6963 (set_attr "mode" "HI")])
6965 (define_expand "mulqi3"
6966 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6967 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
6968 (match_operand:QI 2 "register_operand" "")))
6969 (clobber (reg:CC FLAGS_REG))])]
6970 "TARGET_QIMODE_MATH"
6973 (define_insn "*mulqi3_1"
6974 [(set (match_operand:QI 0 "register_operand" "=a")
6975 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6976 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6977 (clobber (reg:CC FLAGS_REG))]
6979 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6981 [(set_attr "type" "imul")
6982 (set_attr "length_immediate" "0")
6983 (set (attr "athlon_decode")
6984 (if_then_else (eq_attr "cpu" "athlon")
6985 (const_string "vector")
6986 (const_string "direct")))
6987 (set_attr "mode" "QI")])
6989 (define_expand "umulqihi3"
6990 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6991 (mult:HI (zero_extend:HI
6992 (match_operand:QI 1 "nonimmediate_operand" ""))
6994 (match_operand:QI 2 "register_operand" ""))))
6995 (clobber (reg:CC FLAGS_REG))])]
6996 "TARGET_QIMODE_MATH"
6999 (define_insn "*umulqihi3_1"
7000 [(set (match_operand:HI 0 "register_operand" "=a")
7001 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7002 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7003 (clobber (reg:CC FLAGS_REG))]
7005 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7007 [(set_attr "type" "imul")
7008 (set_attr "length_immediate" "0")
7009 (set (attr "athlon_decode")
7010 (if_then_else (eq_attr "cpu" "athlon")
7011 (const_string "vector")
7012 (const_string "direct")))
7013 (set_attr "mode" "QI")])
7015 (define_expand "mulqihi3"
7016 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7017 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7018 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7019 (clobber (reg:CC FLAGS_REG))])]
7020 "TARGET_QIMODE_MATH"
7023 (define_insn "*mulqihi3_insn"
7024 [(set (match_operand:HI 0 "register_operand" "=a")
7025 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7026 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7027 (clobber (reg:CC FLAGS_REG))]
7029 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7031 [(set_attr "type" "imul")
7032 (set_attr "length_immediate" "0")
7033 (set (attr "athlon_decode")
7034 (if_then_else (eq_attr "cpu" "athlon")
7035 (const_string "vector")
7036 (const_string "direct")))
7037 (set_attr "mode" "QI")])
7039 (define_expand "umulditi3"
7040 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7041 (mult:TI (zero_extend:TI
7042 (match_operand:DI 1 "nonimmediate_operand" ""))
7044 (match_operand:DI 2 "register_operand" ""))))
7045 (clobber (reg:CC FLAGS_REG))])]
7049 (define_insn "*umulditi3_insn"
7050 [(set (match_operand:TI 0 "register_operand" "=A")
7051 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7052 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7053 (clobber (reg:CC FLAGS_REG))]
7055 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7057 [(set_attr "type" "imul")
7058 (set_attr "length_immediate" "0")
7059 (set (attr "athlon_decode")
7060 (if_then_else (eq_attr "cpu" "athlon")
7061 (const_string "vector")
7062 (const_string "double")))
7063 (set_attr "mode" "DI")])
7065 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7066 (define_expand "umulsidi3"
7067 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7068 (mult:DI (zero_extend:DI
7069 (match_operand:SI 1 "nonimmediate_operand" ""))
7071 (match_operand:SI 2 "register_operand" ""))))
7072 (clobber (reg:CC FLAGS_REG))])]
7076 (define_insn "*umulsidi3_insn"
7077 [(set (match_operand:DI 0 "register_operand" "=A")
7078 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7079 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7080 (clobber (reg:CC FLAGS_REG))]
7082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7084 [(set_attr "type" "imul")
7085 (set_attr "length_immediate" "0")
7086 (set (attr "athlon_decode")
7087 (if_then_else (eq_attr "cpu" "athlon")
7088 (const_string "vector")
7089 (const_string "double")))
7090 (set_attr "mode" "SI")])
7092 (define_expand "mulditi3"
7093 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7094 (mult:TI (sign_extend:TI
7095 (match_operand:DI 1 "nonimmediate_operand" ""))
7097 (match_operand:DI 2 "register_operand" ""))))
7098 (clobber (reg:CC FLAGS_REG))])]
7102 (define_insn "*mulditi3_insn"
7103 [(set (match_operand:TI 0 "register_operand" "=A")
7104 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7105 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7106 (clobber (reg:CC FLAGS_REG))]
7108 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7110 [(set_attr "type" "imul")
7111 (set_attr "length_immediate" "0")
7112 (set (attr "athlon_decode")
7113 (if_then_else (eq_attr "cpu" "athlon")
7114 (const_string "vector")
7115 (const_string "double")))
7116 (set_attr "mode" "DI")])
7118 (define_expand "mulsidi3"
7119 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7120 (mult:DI (sign_extend:DI
7121 (match_operand:SI 1 "nonimmediate_operand" ""))
7123 (match_operand:SI 2 "register_operand" ""))))
7124 (clobber (reg:CC FLAGS_REG))])]
7128 (define_insn "*mulsidi3_insn"
7129 [(set (match_operand:DI 0 "register_operand" "=A")
7130 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7131 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7132 (clobber (reg:CC FLAGS_REG))]
7134 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7136 [(set_attr "type" "imul")
7137 (set_attr "length_immediate" "0")
7138 (set (attr "athlon_decode")
7139 (if_then_else (eq_attr "cpu" "athlon")
7140 (const_string "vector")
7141 (const_string "double")))
7142 (set_attr "mode" "SI")])
7144 (define_expand "umuldi3_highpart"
7145 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7148 (mult:TI (zero_extend:TI
7149 (match_operand:DI 1 "nonimmediate_operand" ""))
7151 (match_operand:DI 2 "register_operand" "")))
7153 (clobber (match_scratch:DI 3 ""))
7154 (clobber (reg:CC FLAGS_REG))])]
7158 (define_insn "*umuldi3_highpart_rex64"
7159 [(set (match_operand:DI 0 "register_operand" "=d")
7162 (mult:TI (zero_extend:TI
7163 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7165 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7167 (clobber (match_scratch:DI 3 "=1"))
7168 (clobber (reg:CC FLAGS_REG))]
7170 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7172 [(set_attr "type" "imul")
7173 (set_attr "length_immediate" "0")
7174 (set (attr "athlon_decode")
7175 (if_then_else (eq_attr "cpu" "athlon")
7176 (const_string "vector")
7177 (const_string "double")))
7178 (set_attr "mode" "DI")])
7180 (define_expand "umulsi3_highpart"
7181 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7184 (mult:DI (zero_extend:DI
7185 (match_operand:SI 1 "nonimmediate_operand" ""))
7187 (match_operand:SI 2 "register_operand" "")))
7189 (clobber (match_scratch:SI 3 ""))
7190 (clobber (reg:CC FLAGS_REG))])]
7194 (define_insn "*umulsi3_highpart_insn"
7195 [(set (match_operand:SI 0 "register_operand" "=d")
7198 (mult:DI (zero_extend:DI
7199 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7201 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7203 (clobber (match_scratch:SI 3 "=1"))
7204 (clobber (reg:CC FLAGS_REG))]
7205 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7207 [(set_attr "type" "imul")
7208 (set_attr "length_immediate" "0")
7209 (set (attr "athlon_decode")
7210 (if_then_else (eq_attr "cpu" "athlon")
7211 (const_string "vector")
7212 (const_string "double")))
7213 (set_attr "mode" "SI")])
7215 (define_insn "*umulsi3_highpart_zext"
7216 [(set (match_operand:DI 0 "register_operand" "=d")
7217 (zero_extend:DI (truncate:SI
7219 (mult:DI (zero_extend:DI
7220 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7222 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7224 (clobber (match_scratch:SI 3 "=1"))
7225 (clobber (reg:CC FLAGS_REG))]
7227 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7229 [(set_attr "type" "imul")
7230 (set_attr "length_immediate" "0")
7231 (set (attr "athlon_decode")
7232 (if_then_else (eq_attr "cpu" "athlon")
7233 (const_string "vector")
7234 (const_string "double")))
7235 (set_attr "mode" "SI")])
7237 (define_expand "smuldi3_highpart"
7238 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7241 (mult:TI (sign_extend:TI
7242 (match_operand:DI 1 "nonimmediate_operand" ""))
7244 (match_operand:DI 2 "register_operand" "")))
7246 (clobber (match_scratch:DI 3 ""))
7247 (clobber (reg:CC FLAGS_REG))])]
7251 (define_insn "*smuldi3_highpart_rex64"
7252 [(set (match_operand:DI 0 "register_operand" "=d")
7255 (mult:TI (sign_extend:TI
7256 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7258 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7260 (clobber (match_scratch:DI 3 "=1"))
7261 (clobber (reg:CC FLAGS_REG))]
7263 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7265 [(set_attr "type" "imul")
7266 (set (attr "athlon_decode")
7267 (if_then_else (eq_attr "cpu" "athlon")
7268 (const_string "vector")
7269 (const_string "double")))
7270 (set_attr "mode" "DI")])
7272 (define_expand "smulsi3_highpart"
7273 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7276 (mult:DI (sign_extend:DI
7277 (match_operand:SI 1 "nonimmediate_operand" ""))
7279 (match_operand:SI 2 "register_operand" "")))
7281 (clobber (match_scratch:SI 3 ""))
7282 (clobber (reg:CC FLAGS_REG))])]
7286 (define_insn "*smulsi3_highpart_insn"
7287 [(set (match_operand:SI 0 "register_operand" "=d")
7290 (mult:DI (sign_extend:DI
7291 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7293 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7295 (clobber (match_scratch:SI 3 "=1"))
7296 (clobber (reg:CC FLAGS_REG))]
7297 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7299 [(set_attr "type" "imul")
7300 (set (attr "athlon_decode")
7301 (if_then_else (eq_attr "cpu" "athlon")
7302 (const_string "vector")
7303 (const_string "double")))
7304 (set_attr "mode" "SI")])
7306 (define_insn "*smulsi3_highpart_zext"
7307 [(set (match_operand:DI 0 "register_operand" "=d")
7308 (zero_extend:DI (truncate:SI
7310 (mult:DI (sign_extend:DI
7311 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7313 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7315 (clobber (match_scratch:SI 3 "=1"))
7316 (clobber (reg:CC FLAGS_REG))]
7318 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7320 [(set_attr "type" "imul")
7321 (set (attr "athlon_decode")
7322 (if_then_else (eq_attr "cpu" "athlon")
7323 (const_string "vector")
7324 (const_string "double")))
7325 (set_attr "mode" "SI")])
7327 ;; The patterns that match these are at the end of this file.
7329 (define_expand "mulxf3"
7330 [(set (match_operand:XF 0 "register_operand" "")
7331 (mult:XF (match_operand:XF 1 "register_operand" "")
7332 (match_operand:XF 2 "register_operand" "")))]
7336 (define_expand "muldf3"
7337 [(set (match_operand:DF 0 "register_operand" "")
7338 (mult:DF (match_operand:DF 1 "register_operand" "")
7339 (match_operand:DF 2 "nonimmediate_operand" "")))]
7340 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7343 (define_expand "mulsf3"
7344 [(set (match_operand:SF 0 "register_operand" "")
7345 (mult:SF (match_operand:SF 1 "register_operand" "")
7346 (match_operand:SF 2 "nonimmediate_operand" "")))]
7347 "TARGET_80387 || TARGET_SSE_MATH"
7350 ;; Divide instructions
7352 (define_insn "divqi3"
7353 [(set (match_operand:QI 0 "register_operand" "=a")
7354 (div:QI (match_operand:HI 1 "register_operand" "0")
7355 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7356 (clobber (reg:CC FLAGS_REG))]
7357 "TARGET_QIMODE_MATH"
7359 [(set_attr "type" "idiv")
7360 (set_attr "mode" "QI")])
7362 (define_insn "udivqi3"
7363 [(set (match_operand:QI 0 "register_operand" "=a")
7364 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7365 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7366 (clobber (reg:CC FLAGS_REG))]
7367 "TARGET_QIMODE_MATH"
7369 [(set_attr "type" "idiv")
7370 (set_attr "mode" "QI")])
7372 ;; The patterns that match these are at the end of this file.
7374 (define_expand "divxf3"
7375 [(set (match_operand:XF 0 "register_operand" "")
7376 (div:XF (match_operand:XF 1 "register_operand" "")
7377 (match_operand:XF 2 "register_operand" "")))]
7381 (define_expand "divdf3"
7382 [(set (match_operand:DF 0 "register_operand" "")
7383 (div:DF (match_operand:DF 1 "register_operand" "")
7384 (match_operand:DF 2 "nonimmediate_operand" "")))]
7385 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7388 (define_expand "divsf3"
7389 [(set (match_operand:SF 0 "register_operand" "")
7390 (div:SF (match_operand:SF 1 "register_operand" "")
7391 (match_operand:SF 2 "nonimmediate_operand" "")))]
7392 "TARGET_80387 || TARGET_SSE_MATH"
7395 ;; Remainder instructions.
7397 (define_expand "divmoddi4"
7398 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7399 (div:DI (match_operand:DI 1 "register_operand" "")
7400 (match_operand:DI 2 "nonimmediate_operand" "")))
7401 (set (match_operand:DI 3 "register_operand" "")
7402 (mod:DI (match_dup 1) (match_dup 2)))
7403 (clobber (reg:CC FLAGS_REG))])]
7407 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7408 ;; Penalize eax case slightly because it results in worse scheduling
7410 (define_insn "*divmoddi4_nocltd_rex64"
7411 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7412 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7413 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7414 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7415 (mod:DI (match_dup 2) (match_dup 3)))
7416 (clobber (reg:CC FLAGS_REG))]
7417 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7419 [(set_attr "type" "multi")])
7421 (define_insn "*divmoddi4_cltd_rex64"
7422 [(set (match_operand:DI 0 "register_operand" "=a")
7423 (div:DI (match_operand:DI 2 "register_operand" "a")
7424 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7425 (set (match_operand:DI 1 "register_operand" "=&d")
7426 (mod:DI (match_dup 2) (match_dup 3)))
7427 (clobber (reg:CC FLAGS_REG))]
7428 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7430 [(set_attr "type" "multi")])
7432 (define_insn "*divmoddi_noext_rex64"
7433 [(set (match_operand:DI 0 "register_operand" "=a")
7434 (div:DI (match_operand:DI 1 "register_operand" "0")
7435 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7436 (set (match_operand:DI 3 "register_operand" "=d")
7437 (mod:DI (match_dup 1) (match_dup 2)))
7438 (use (match_operand:DI 4 "register_operand" "3"))
7439 (clobber (reg:CC FLAGS_REG))]
7442 [(set_attr "type" "idiv")
7443 (set_attr "mode" "DI")])
7446 [(set (match_operand:DI 0 "register_operand" "")
7447 (div:DI (match_operand:DI 1 "register_operand" "")
7448 (match_operand:DI 2 "nonimmediate_operand" "")))
7449 (set (match_operand:DI 3 "register_operand" "")
7450 (mod:DI (match_dup 1) (match_dup 2)))
7451 (clobber (reg:CC FLAGS_REG))]
7452 "TARGET_64BIT && reload_completed"
7453 [(parallel [(set (match_dup 3)
7454 (ashiftrt:DI (match_dup 4) (const_int 63)))
7455 (clobber (reg:CC FLAGS_REG))])
7456 (parallel [(set (match_dup 0)
7457 (div:DI (reg:DI 0) (match_dup 2)))
7459 (mod:DI (reg:DI 0) (match_dup 2)))
7461 (clobber (reg:CC FLAGS_REG))])]
7463 /* Avoid use of cltd in favor of a mov+shift. */
7464 if (!TARGET_USE_CLTD && !optimize_size)
7466 if (true_regnum (operands[1]))
7467 emit_move_insn (operands[0], operands[1]);
7469 emit_move_insn (operands[3], operands[1]);
7470 operands[4] = operands[3];
7474 gcc_assert (!true_regnum (operands[1]));
7475 operands[4] = operands[1];
7480 (define_expand "divmodsi4"
7481 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7482 (div:SI (match_operand:SI 1 "register_operand" "")
7483 (match_operand:SI 2 "nonimmediate_operand" "")))
7484 (set (match_operand:SI 3 "register_operand" "")
7485 (mod:SI (match_dup 1) (match_dup 2)))
7486 (clobber (reg:CC FLAGS_REG))])]
7490 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7491 ;; Penalize eax case slightly because it results in worse scheduling
7493 (define_insn "*divmodsi4_nocltd"
7494 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7495 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7496 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7497 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7498 (mod:SI (match_dup 2) (match_dup 3)))
7499 (clobber (reg:CC FLAGS_REG))]
7500 "!optimize_size && !TARGET_USE_CLTD"
7502 [(set_attr "type" "multi")])
7504 (define_insn "*divmodsi4_cltd"
7505 [(set (match_operand:SI 0 "register_operand" "=a")
7506 (div:SI (match_operand:SI 2 "register_operand" "a")
7507 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7508 (set (match_operand:SI 1 "register_operand" "=&d")
7509 (mod:SI (match_dup 2) (match_dup 3)))
7510 (clobber (reg:CC FLAGS_REG))]
7511 "optimize_size || TARGET_USE_CLTD"
7513 [(set_attr "type" "multi")])
7515 (define_insn "*divmodsi_noext"
7516 [(set (match_operand:SI 0 "register_operand" "=a")
7517 (div:SI (match_operand:SI 1 "register_operand" "0")
7518 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7519 (set (match_operand:SI 3 "register_operand" "=d")
7520 (mod:SI (match_dup 1) (match_dup 2)))
7521 (use (match_operand:SI 4 "register_operand" "3"))
7522 (clobber (reg:CC FLAGS_REG))]
7525 [(set_attr "type" "idiv")
7526 (set_attr "mode" "SI")])
7529 [(set (match_operand:SI 0 "register_operand" "")
7530 (div:SI (match_operand:SI 1 "register_operand" "")
7531 (match_operand:SI 2 "nonimmediate_operand" "")))
7532 (set (match_operand:SI 3 "register_operand" "")
7533 (mod:SI (match_dup 1) (match_dup 2)))
7534 (clobber (reg:CC FLAGS_REG))]
7536 [(parallel [(set (match_dup 3)
7537 (ashiftrt:SI (match_dup 4) (const_int 31)))
7538 (clobber (reg:CC FLAGS_REG))])
7539 (parallel [(set (match_dup 0)
7540 (div:SI (reg:SI 0) (match_dup 2)))
7542 (mod:SI (reg:SI 0) (match_dup 2)))
7544 (clobber (reg:CC FLAGS_REG))])]
7546 /* Avoid use of cltd in favor of a mov+shift. */
7547 if (!TARGET_USE_CLTD && !optimize_size)
7549 if (true_regnum (operands[1]))
7550 emit_move_insn (operands[0], operands[1]);
7552 emit_move_insn (operands[3], operands[1]);
7553 operands[4] = operands[3];
7557 gcc_assert (!true_regnum (operands[1]));
7558 operands[4] = operands[1];
7562 (define_insn "divmodhi4"
7563 [(set (match_operand:HI 0 "register_operand" "=a")
7564 (div:HI (match_operand:HI 1 "register_operand" "0")
7565 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7566 (set (match_operand:HI 3 "register_operand" "=&d")
7567 (mod:HI (match_dup 1) (match_dup 2)))
7568 (clobber (reg:CC FLAGS_REG))]
7569 "TARGET_HIMODE_MATH"
7571 [(set_attr "type" "multi")
7572 (set_attr "length_immediate" "0")
7573 (set_attr "mode" "SI")])
7575 (define_insn "udivmoddi4"
7576 [(set (match_operand:DI 0 "register_operand" "=a")
7577 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7578 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7579 (set (match_operand:DI 3 "register_operand" "=&d")
7580 (umod:DI (match_dup 1) (match_dup 2)))
7581 (clobber (reg:CC FLAGS_REG))]
7583 "xor{q}\t%3, %3\;div{q}\t%2"
7584 [(set_attr "type" "multi")
7585 (set_attr "length_immediate" "0")
7586 (set_attr "mode" "DI")])
7588 (define_insn "*udivmoddi4_noext"
7589 [(set (match_operand:DI 0 "register_operand" "=a")
7590 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7591 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7592 (set (match_operand:DI 3 "register_operand" "=d")
7593 (umod:DI (match_dup 1) (match_dup 2)))
7595 (clobber (reg:CC FLAGS_REG))]
7598 [(set_attr "type" "idiv")
7599 (set_attr "mode" "DI")])
7602 [(set (match_operand:DI 0 "register_operand" "")
7603 (udiv:DI (match_operand:DI 1 "register_operand" "")
7604 (match_operand:DI 2 "nonimmediate_operand" "")))
7605 (set (match_operand:DI 3 "register_operand" "")
7606 (umod:DI (match_dup 1) (match_dup 2)))
7607 (clobber (reg:CC FLAGS_REG))]
7608 "TARGET_64BIT && reload_completed"
7609 [(set (match_dup 3) (const_int 0))
7610 (parallel [(set (match_dup 0)
7611 (udiv:DI (match_dup 1) (match_dup 2)))
7613 (umod:DI (match_dup 1) (match_dup 2)))
7615 (clobber (reg:CC FLAGS_REG))])]
7618 (define_insn "udivmodsi4"
7619 [(set (match_operand:SI 0 "register_operand" "=a")
7620 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7621 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7622 (set (match_operand:SI 3 "register_operand" "=&d")
7623 (umod:SI (match_dup 1) (match_dup 2)))
7624 (clobber (reg:CC FLAGS_REG))]
7626 "xor{l}\t%3, %3\;div{l}\t%2"
7627 [(set_attr "type" "multi")
7628 (set_attr "length_immediate" "0")
7629 (set_attr "mode" "SI")])
7631 (define_insn "*udivmodsi4_noext"
7632 [(set (match_operand:SI 0 "register_operand" "=a")
7633 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7634 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7635 (set (match_operand:SI 3 "register_operand" "=d")
7636 (umod:SI (match_dup 1) (match_dup 2)))
7638 (clobber (reg:CC FLAGS_REG))]
7641 [(set_attr "type" "idiv")
7642 (set_attr "mode" "SI")])
7645 [(set (match_operand:SI 0 "register_operand" "")
7646 (udiv:SI (match_operand:SI 1 "register_operand" "")
7647 (match_operand:SI 2 "nonimmediate_operand" "")))
7648 (set (match_operand:SI 3 "register_operand" "")
7649 (umod:SI (match_dup 1) (match_dup 2)))
7650 (clobber (reg:CC FLAGS_REG))]
7652 [(set (match_dup 3) (const_int 0))
7653 (parallel [(set (match_dup 0)
7654 (udiv:SI (match_dup 1) (match_dup 2)))
7656 (umod:SI (match_dup 1) (match_dup 2)))
7658 (clobber (reg:CC FLAGS_REG))])]
7661 (define_expand "udivmodhi4"
7662 [(set (match_dup 4) (const_int 0))
7663 (parallel [(set (match_operand:HI 0 "register_operand" "")
7664 (udiv:HI (match_operand:HI 1 "register_operand" "")
7665 (match_operand:HI 2 "nonimmediate_operand" "")))
7666 (set (match_operand:HI 3 "register_operand" "")
7667 (umod:HI (match_dup 1) (match_dup 2)))
7669 (clobber (reg:CC FLAGS_REG))])]
7670 "TARGET_HIMODE_MATH"
7671 "operands[4] = gen_reg_rtx (HImode);")
7673 (define_insn "*udivmodhi_noext"
7674 [(set (match_operand:HI 0 "register_operand" "=a")
7675 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7676 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7677 (set (match_operand:HI 3 "register_operand" "=d")
7678 (umod:HI (match_dup 1) (match_dup 2)))
7679 (use (match_operand:HI 4 "register_operand" "3"))
7680 (clobber (reg:CC FLAGS_REG))]
7683 [(set_attr "type" "idiv")
7684 (set_attr "mode" "HI")])
7686 ;; We cannot use div/idiv for double division, because it causes
7687 ;; "division by zero" on the overflow and that's not what we expect
7688 ;; from truncate. Because true (non truncating) double division is
7689 ;; never generated, we can't create this insn anyway.
7692 ; [(set (match_operand:SI 0 "register_operand" "=a")
7694 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7696 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7697 ; (set (match_operand:SI 3 "register_operand" "=d")
7699 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7700 ; (clobber (reg:CC FLAGS_REG))]
7702 ; "div{l}\t{%2, %0|%0, %2}"
7703 ; [(set_attr "type" "idiv")])
7705 ;;- Logical AND instructions
7707 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7708 ;; Note that this excludes ah.
7710 (define_insn "*testdi_1_rex64"
7711 [(set (reg FLAGS_REG)
7713 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7714 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7716 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7717 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7719 test{l}\t{%k1, %k0|%k0, %k1}
7720 test{l}\t{%k1, %k0|%k0, %k1}
7721 test{q}\t{%1, %0|%0, %1}
7722 test{q}\t{%1, %0|%0, %1}
7723 test{q}\t{%1, %0|%0, %1}"
7724 [(set_attr "type" "test")
7725 (set_attr "modrm" "0,1,0,1,1")
7726 (set_attr "mode" "SI,SI,DI,DI,DI")
7727 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7729 (define_insn "testsi_1"
7730 [(set (reg FLAGS_REG)
7732 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7733 (match_operand:SI 1 "general_operand" "in,in,rin"))
7735 "ix86_match_ccmode (insn, CCNOmode)
7736 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7737 "test{l}\t{%1, %0|%0, %1}"
7738 [(set_attr "type" "test")
7739 (set_attr "modrm" "0,1,1")
7740 (set_attr "mode" "SI")
7741 (set_attr "pent_pair" "uv,np,uv")])
7743 (define_expand "testsi_ccno_1"
7744 [(set (reg:CCNO FLAGS_REG)
7746 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7747 (match_operand:SI 1 "nonmemory_operand" ""))
7752 (define_insn "*testhi_1"
7753 [(set (reg FLAGS_REG)
7754 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7755 (match_operand:HI 1 "general_operand" "n,n,rn"))
7757 "ix86_match_ccmode (insn, CCNOmode)
7758 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7759 "test{w}\t{%1, %0|%0, %1}"
7760 [(set_attr "type" "test")
7761 (set_attr "modrm" "0,1,1")
7762 (set_attr "mode" "HI")
7763 (set_attr "pent_pair" "uv,np,uv")])
7765 (define_expand "testqi_ccz_1"
7766 [(set (reg:CCZ FLAGS_REG)
7767 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7768 (match_operand:QI 1 "nonmemory_operand" ""))
7773 (define_insn "*testqi_1_maybe_si"
7774 [(set (reg FLAGS_REG)
7777 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7778 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7780 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7781 && ix86_match_ccmode (insn,
7782 GET_CODE (operands[1]) == CONST_INT
7783 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7785 if (which_alternative == 3)
7787 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7788 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7789 return "test{l}\t{%1, %k0|%k0, %1}";
7791 return "test{b}\t{%1, %0|%0, %1}";
7793 [(set_attr "type" "test")
7794 (set_attr "modrm" "0,1,1,1")
7795 (set_attr "mode" "QI,QI,QI,SI")
7796 (set_attr "pent_pair" "uv,np,uv,np")])
7798 (define_insn "*testqi_1"
7799 [(set (reg FLAGS_REG)
7802 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7803 (match_operand:QI 1 "general_operand" "n,n,qn"))
7805 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7806 && ix86_match_ccmode (insn, CCNOmode)"
7807 "test{b}\t{%1, %0|%0, %1}"
7808 [(set_attr "type" "test")
7809 (set_attr "modrm" "0,1,1")
7810 (set_attr "mode" "QI")
7811 (set_attr "pent_pair" "uv,np,uv")])
7813 (define_expand "testqi_ext_ccno_0"
7814 [(set (reg:CCNO FLAGS_REG)
7818 (match_operand 0 "ext_register_operand" "")
7821 (match_operand 1 "const_int_operand" ""))
7826 (define_insn "*testqi_ext_0"
7827 [(set (reg FLAGS_REG)
7831 (match_operand 0 "ext_register_operand" "Q")
7834 (match_operand 1 "const_int_operand" "n"))
7836 "ix86_match_ccmode (insn, CCNOmode)"
7837 "test{b}\t{%1, %h0|%h0, %1}"
7838 [(set_attr "type" "test")
7839 (set_attr "mode" "QI")
7840 (set_attr "length_immediate" "1")
7841 (set_attr "pent_pair" "np")])
7843 (define_insn "*testqi_ext_1"
7844 [(set (reg FLAGS_REG)
7848 (match_operand 0 "ext_register_operand" "Q")
7852 (match_operand:QI 1 "general_operand" "Qm")))
7854 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7855 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7856 "test{b}\t{%1, %h0|%h0, %1}"
7857 [(set_attr "type" "test")
7858 (set_attr "mode" "QI")])
7860 (define_insn "*testqi_ext_1_rex64"
7861 [(set (reg FLAGS_REG)
7865 (match_operand 0 "ext_register_operand" "Q")
7869 (match_operand:QI 1 "register_operand" "Q")))
7871 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7872 "test{b}\t{%1, %h0|%h0, %1}"
7873 [(set_attr "type" "test")
7874 (set_attr "mode" "QI")])
7876 (define_insn "*testqi_ext_2"
7877 [(set (reg FLAGS_REG)
7881 (match_operand 0 "ext_register_operand" "Q")
7885 (match_operand 1 "ext_register_operand" "Q")
7889 "ix86_match_ccmode (insn, CCNOmode)"
7890 "test{b}\t{%h1, %h0|%h0, %h1}"
7891 [(set_attr "type" "test")
7892 (set_attr "mode" "QI")])
7894 ;; Combine likes to form bit extractions for some tests. Humor it.
7895 (define_insn "*testqi_ext_3"
7896 [(set (reg FLAGS_REG)
7897 (compare (zero_extract:SI
7898 (match_operand 0 "nonimmediate_operand" "rm")
7899 (match_operand:SI 1 "const_int_operand" "")
7900 (match_operand:SI 2 "const_int_operand" ""))
7902 "ix86_match_ccmode (insn, CCNOmode)
7903 && INTVAL (operands[1]) > 0
7904 && INTVAL (operands[2]) >= 0
7905 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7906 && (GET_MODE (operands[0]) == SImode
7907 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7908 || GET_MODE (operands[0]) == HImode
7909 || GET_MODE (operands[0]) == QImode)"
7912 (define_insn "*testqi_ext_3_rex64"
7913 [(set (reg FLAGS_REG)
7914 (compare (zero_extract:DI
7915 (match_operand 0 "nonimmediate_operand" "rm")
7916 (match_operand:DI 1 "const_int_operand" "")
7917 (match_operand:DI 2 "const_int_operand" ""))
7920 && ix86_match_ccmode (insn, CCNOmode)
7921 && INTVAL (operands[1]) > 0
7922 && INTVAL (operands[2]) >= 0
7923 /* Ensure that resulting mask is zero or sign extended operand. */
7924 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7925 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7926 && INTVAL (operands[1]) > 32))
7927 && (GET_MODE (operands[0]) == SImode
7928 || GET_MODE (operands[0]) == DImode
7929 || GET_MODE (operands[0]) == HImode
7930 || GET_MODE (operands[0]) == QImode)"
7934 [(set (match_operand 0 "flags_reg_operand" "")
7935 (match_operator 1 "compare_operator"
7937 (match_operand 2 "nonimmediate_operand" "")
7938 (match_operand 3 "const_int_operand" "")
7939 (match_operand 4 "const_int_operand" ""))
7941 "ix86_match_ccmode (insn, CCNOmode)"
7942 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7944 rtx val = operands[2];
7945 HOST_WIDE_INT len = INTVAL (operands[3]);
7946 HOST_WIDE_INT pos = INTVAL (operands[4]);
7948 enum machine_mode mode, submode;
7950 mode = GET_MODE (val);
7951 if (GET_CODE (val) == MEM)
7953 /* ??? Combine likes to put non-volatile mem extractions in QImode
7954 no matter the size of the test. So find a mode that works. */
7955 if (! MEM_VOLATILE_P (val))
7957 mode = smallest_mode_for_size (pos + len, MODE_INT);
7958 val = adjust_address (val, mode, 0);
7961 else if (GET_CODE (val) == SUBREG
7962 && (submode = GET_MODE (SUBREG_REG (val)),
7963 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7964 && pos + len <= GET_MODE_BITSIZE (submode))
7966 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7968 val = SUBREG_REG (val);
7970 else if (mode == HImode && pos + len <= 8)
7972 /* Small HImode tests can be converted to QImode. */
7974 val = gen_lowpart (QImode, val);
7977 if (len == HOST_BITS_PER_WIDE_INT)
7980 mask = ((HOST_WIDE_INT)1 << len) - 1;
7983 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7986 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7987 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7988 ;; this is relatively important trick.
7989 ;; Do the conversion only post-reload to avoid limiting of the register class
7992 [(set (match_operand 0 "flags_reg_operand" "")
7993 (match_operator 1 "compare_operator"
7994 [(and (match_operand 2 "register_operand" "")
7995 (match_operand 3 "const_int_operand" ""))
7998 && QI_REG_P (operands[2])
7999 && GET_MODE (operands[2]) != QImode
8000 && ((ix86_match_ccmode (insn, CCZmode)
8001 && !(INTVAL (operands[3]) & ~(255 << 8)))
8002 || (ix86_match_ccmode (insn, CCNOmode)
8003 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8006 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8009 "operands[2] = gen_lowpart (SImode, operands[2]);
8010 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8013 [(set (match_operand 0 "flags_reg_operand" "")
8014 (match_operator 1 "compare_operator"
8015 [(and (match_operand 2 "nonimmediate_operand" "")
8016 (match_operand 3 "const_int_operand" ""))
8019 && GET_MODE (operands[2]) != QImode
8020 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8021 && ((ix86_match_ccmode (insn, CCZmode)
8022 && !(INTVAL (operands[3]) & ~255))
8023 || (ix86_match_ccmode (insn, CCNOmode)
8024 && !(INTVAL (operands[3]) & ~127)))"
8026 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8028 "operands[2] = gen_lowpart (QImode, operands[2]);
8029 operands[3] = gen_lowpart (QImode, operands[3]);")
8032 ;; %%% This used to optimize known byte-wide and operations to memory,
8033 ;; and sometimes to QImode registers. If this is considered useful,
8034 ;; it should be done with splitters.
8036 (define_expand "anddi3"
8037 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8038 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8039 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8040 (clobber (reg:CC FLAGS_REG))]
8042 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8044 (define_insn "*anddi_1_rex64"
8045 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8046 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8047 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8048 (clobber (reg:CC FLAGS_REG))]
8049 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8051 switch (get_attr_type (insn))
8055 enum machine_mode mode;
8057 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8058 if (INTVAL (operands[2]) == 0xff)
8062 gcc_assert (INTVAL (operands[2]) == 0xffff);
8066 operands[1] = gen_lowpart (mode, operands[1]);
8068 return "movz{bq|x}\t{%1,%0|%0, %1}";
8070 return "movz{wq|x}\t{%1,%0|%0, %1}";
8074 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8075 if (get_attr_mode (insn) == MODE_SI)
8076 return "and{l}\t{%k2, %k0|%k0, %k2}";
8078 return "and{q}\t{%2, %0|%0, %2}";
8081 [(set_attr "type" "alu,alu,alu,imovx")
8082 (set_attr "length_immediate" "*,*,*,0")
8083 (set_attr "mode" "SI,DI,DI,DI")])
8085 (define_insn "*anddi_2"
8086 [(set (reg FLAGS_REG)
8087 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8088 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8090 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8091 (and:DI (match_dup 1) (match_dup 2)))]
8092 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8093 && ix86_binary_operator_ok (AND, DImode, operands)"
8095 and{l}\t{%k2, %k0|%k0, %k2}
8096 and{q}\t{%2, %0|%0, %2}
8097 and{q}\t{%2, %0|%0, %2}"
8098 [(set_attr "type" "alu")
8099 (set_attr "mode" "SI,DI,DI")])
8101 (define_expand "andsi3"
8102 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8103 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8104 (match_operand:SI 2 "general_operand" "")))
8105 (clobber (reg:CC FLAGS_REG))]
8107 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8109 (define_insn "*andsi_1"
8110 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8111 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8112 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8113 (clobber (reg:CC FLAGS_REG))]
8114 "ix86_binary_operator_ok (AND, SImode, operands)"
8116 switch (get_attr_type (insn))
8120 enum machine_mode mode;
8122 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8123 if (INTVAL (operands[2]) == 0xff)
8127 gcc_assert (INTVAL (operands[2]) == 0xffff);
8131 operands[1] = gen_lowpart (mode, operands[1]);
8133 return "movz{bl|x}\t{%1,%0|%0, %1}";
8135 return "movz{wl|x}\t{%1,%0|%0, %1}";
8139 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8140 return "and{l}\t{%2, %0|%0, %2}";
8143 [(set_attr "type" "alu,alu,imovx")
8144 (set_attr "length_immediate" "*,*,0")
8145 (set_attr "mode" "SI")])
8148 [(set (match_operand 0 "register_operand" "")
8150 (const_int -65536)))
8151 (clobber (reg:CC FLAGS_REG))]
8152 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8153 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8154 "operands[1] = gen_lowpart (HImode, operands[0]);")
8157 [(set (match_operand 0 "ext_register_operand" "")
8160 (clobber (reg:CC FLAGS_REG))]
8161 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8162 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8163 "operands[1] = gen_lowpart (QImode, operands[0]);")
8166 [(set (match_operand 0 "ext_register_operand" "")
8168 (const_int -65281)))
8169 (clobber (reg:CC FLAGS_REG))]
8170 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8171 [(parallel [(set (zero_extract:SI (match_dup 0)
8175 (zero_extract:SI (match_dup 0)
8178 (zero_extract:SI (match_dup 0)
8181 (clobber (reg:CC FLAGS_REG))])]
8182 "operands[0] = gen_lowpart (SImode, operands[0]);")
8184 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8185 (define_insn "*andsi_1_zext"
8186 [(set (match_operand:DI 0 "register_operand" "=r")
8188 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8189 (match_operand:SI 2 "general_operand" "rim"))))
8190 (clobber (reg:CC FLAGS_REG))]
8191 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8192 "and{l}\t{%2, %k0|%k0, %2}"
8193 [(set_attr "type" "alu")
8194 (set_attr "mode" "SI")])
8196 (define_insn "*andsi_2"
8197 [(set (reg FLAGS_REG)
8198 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8199 (match_operand:SI 2 "general_operand" "rim,ri"))
8201 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8202 (and:SI (match_dup 1) (match_dup 2)))]
8203 "ix86_match_ccmode (insn, CCNOmode)
8204 && ix86_binary_operator_ok (AND, SImode, operands)"
8205 "and{l}\t{%2, %0|%0, %2}"
8206 [(set_attr "type" "alu")
8207 (set_attr "mode" "SI")])
8209 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8210 (define_insn "*andsi_2_zext"
8211 [(set (reg FLAGS_REG)
8212 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8213 (match_operand:SI 2 "general_operand" "rim"))
8215 (set (match_operand:DI 0 "register_operand" "=r")
8216 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8217 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8218 && ix86_binary_operator_ok (AND, SImode, operands)"
8219 "and{l}\t{%2, %k0|%k0, %2}"
8220 [(set_attr "type" "alu")
8221 (set_attr "mode" "SI")])
8223 (define_expand "andhi3"
8224 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8225 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8226 (match_operand:HI 2 "general_operand" "")))
8227 (clobber (reg:CC FLAGS_REG))]
8228 "TARGET_HIMODE_MATH"
8229 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8231 (define_insn "*andhi_1"
8232 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8233 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8234 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8235 (clobber (reg:CC FLAGS_REG))]
8236 "ix86_binary_operator_ok (AND, HImode, operands)"
8238 switch (get_attr_type (insn))
8241 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8242 gcc_assert (INTVAL (operands[2]) == 0xff);
8243 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8246 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8248 return "and{w}\t{%2, %0|%0, %2}";
8251 [(set_attr "type" "alu,alu,imovx")
8252 (set_attr "length_immediate" "*,*,0")
8253 (set_attr "mode" "HI,HI,SI")])
8255 (define_insn "*andhi_2"
8256 [(set (reg FLAGS_REG)
8257 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8258 (match_operand:HI 2 "general_operand" "rim,ri"))
8260 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8261 (and:HI (match_dup 1) (match_dup 2)))]
8262 "ix86_match_ccmode (insn, CCNOmode)
8263 && ix86_binary_operator_ok (AND, HImode, operands)"
8264 "and{w}\t{%2, %0|%0, %2}"
8265 [(set_attr "type" "alu")
8266 (set_attr "mode" "HI")])
8268 (define_expand "andqi3"
8269 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8270 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8271 (match_operand:QI 2 "general_operand" "")))
8272 (clobber (reg:CC FLAGS_REG))]
8273 "TARGET_QIMODE_MATH"
8274 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8276 ;; %%% Potential partial reg stall on alternative 2. What to do?
8277 (define_insn "*andqi_1"
8278 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8279 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8280 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8281 (clobber (reg:CC FLAGS_REG))]
8282 "ix86_binary_operator_ok (AND, QImode, operands)"
8284 and{b}\t{%2, %0|%0, %2}
8285 and{b}\t{%2, %0|%0, %2}
8286 and{l}\t{%k2, %k0|%k0, %k2}"
8287 [(set_attr "type" "alu")
8288 (set_attr "mode" "QI,QI,SI")])
8290 (define_insn "*andqi_1_slp"
8291 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8292 (and:QI (match_dup 0)
8293 (match_operand:QI 1 "general_operand" "qi,qmi")))
8294 (clobber (reg:CC FLAGS_REG))]
8295 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8296 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8297 "and{b}\t{%1, %0|%0, %1}"
8298 [(set_attr "type" "alu1")
8299 (set_attr "mode" "QI")])
8301 (define_insn "*andqi_2_maybe_si"
8302 [(set (reg FLAGS_REG)
8304 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8305 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8307 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8308 (and:QI (match_dup 1) (match_dup 2)))]
8309 "ix86_binary_operator_ok (AND, QImode, operands)
8310 && ix86_match_ccmode (insn,
8311 GET_CODE (operands[2]) == CONST_INT
8312 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8314 if (which_alternative == 2)
8316 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8317 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8318 return "and{l}\t{%2, %k0|%k0, %2}";
8320 return "and{b}\t{%2, %0|%0, %2}";
8322 [(set_attr "type" "alu")
8323 (set_attr "mode" "QI,QI,SI")])
8325 (define_insn "*andqi_2"
8326 [(set (reg FLAGS_REG)
8328 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8329 (match_operand:QI 2 "general_operand" "qim,qi"))
8331 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8332 (and:QI (match_dup 1) (match_dup 2)))]
8333 "ix86_match_ccmode (insn, CCNOmode)
8334 && ix86_binary_operator_ok (AND, QImode, operands)"
8335 "and{b}\t{%2, %0|%0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "mode" "QI")])
8339 (define_insn "*andqi_2_slp"
8340 [(set (reg FLAGS_REG)
8342 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8343 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8345 (set (strict_low_part (match_dup 0))
8346 (and:QI (match_dup 0) (match_dup 1)))]
8347 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8348 && ix86_match_ccmode (insn, CCNOmode)
8349 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8350 "and{b}\t{%1, %0|%0, %1}"
8351 [(set_attr "type" "alu1")
8352 (set_attr "mode" "QI")])
8354 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8355 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8356 ;; for a QImode operand, which of course failed.
8358 (define_insn "andqi_ext_0"
8359 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8364 (match_operand 1 "ext_register_operand" "0")
8367 (match_operand 2 "const_int_operand" "n")))
8368 (clobber (reg:CC FLAGS_REG))]
8370 "and{b}\t{%2, %h0|%h0, %2}"
8371 [(set_attr "type" "alu")
8372 (set_attr "length_immediate" "1")
8373 (set_attr "mode" "QI")])
8375 ;; Generated by peephole translating test to and. This shows up
8376 ;; often in fp comparisons.
8378 (define_insn "*andqi_ext_0_cc"
8379 [(set (reg FLAGS_REG)
8383 (match_operand 1 "ext_register_operand" "0")
8386 (match_operand 2 "const_int_operand" "n"))
8388 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8397 "ix86_match_ccmode (insn, CCNOmode)"
8398 "and{b}\t{%2, %h0|%h0, %2}"
8399 [(set_attr "type" "alu")
8400 (set_attr "length_immediate" "1")
8401 (set_attr "mode" "QI")])
8403 (define_insn "*andqi_ext_1"
8404 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8409 (match_operand 1 "ext_register_operand" "0")
8413 (match_operand:QI 2 "general_operand" "Qm"))))
8414 (clobber (reg:CC FLAGS_REG))]
8416 "and{b}\t{%2, %h0|%h0, %2}"
8417 [(set_attr "type" "alu")
8418 (set_attr "length_immediate" "0")
8419 (set_attr "mode" "QI")])
8421 (define_insn "*andqi_ext_1_rex64"
8422 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8427 (match_operand 1 "ext_register_operand" "0")
8431 (match_operand 2 "ext_register_operand" "Q"))))
8432 (clobber (reg:CC FLAGS_REG))]
8434 "and{b}\t{%2, %h0|%h0, %2}"
8435 [(set_attr "type" "alu")
8436 (set_attr "length_immediate" "0")
8437 (set_attr "mode" "QI")])
8439 (define_insn "*andqi_ext_2"
8440 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8445 (match_operand 1 "ext_register_operand" "%0")
8449 (match_operand 2 "ext_register_operand" "Q")
8452 (clobber (reg:CC FLAGS_REG))]
8454 "and{b}\t{%h2, %h0|%h0, %h2}"
8455 [(set_attr "type" "alu")
8456 (set_attr "length_immediate" "0")
8457 (set_attr "mode" "QI")])
8459 ;; Convert wide AND instructions with immediate operand to shorter QImode
8460 ;; equivalents when possible.
8461 ;; Don't do the splitting with memory operands, since it introduces risk
8462 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8463 ;; for size, but that can (should?) be handled by generic code instead.
8465 [(set (match_operand 0 "register_operand" "")
8466 (and (match_operand 1 "register_operand" "")
8467 (match_operand 2 "const_int_operand" "")))
8468 (clobber (reg:CC FLAGS_REG))]
8470 && QI_REG_P (operands[0])
8471 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8472 && !(~INTVAL (operands[2]) & ~(255 << 8))
8473 && GET_MODE (operands[0]) != QImode"
8474 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8475 (and:SI (zero_extract:SI (match_dup 1)
8476 (const_int 8) (const_int 8))
8478 (clobber (reg:CC FLAGS_REG))])]
8479 "operands[0] = gen_lowpart (SImode, operands[0]);
8480 operands[1] = gen_lowpart (SImode, operands[1]);
8481 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8483 ;; Since AND can be encoded with sign extended immediate, this is only
8484 ;; profitable when 7th bit is not set.
8486 [(set (match_operand 0 "register_operand" "")
8487 (and (match_operand 1 "general_operand" "")
8488 (match_operand 2 "const_int_operand" "")))
8489 (clobber (reg:CC FLAGS_REG))]
8491 && ANY_QI_REG_P (operands[0])
8492 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8493 && !(~INTVAL (operands[2]) & ~255)
8494 && !(INTVAL (operands[2]) & 128)
8495 && GET_MODE (operands[0]) != QImode"
8496 [(parallel [(set (strict_low_part (match_dup 0))
8497 (and:QI (match_dup 1)
8499 (clobber (reg:CC FLAGS_REG))])]
8500 "operands[0] = gen_lowpart (QImode, operands[0]);
8501 operands[1] = gen_lowpart (QImode, operands[1]);
8502 operands[2] = gen_lowpart (QImode, operands[2]);")
8504 ;; Logical inclusive OR instructions
8506 ;; %%% This used to optimize known byte-wide and operations to memory.
8507 ;; If this is considered useful, it should be done with splitters.
8509 (define_expand "iordi3"
8510 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8511 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8512 (match_operand:DI 2 "x86_64_general_operand" "")))
8513 (clobber (reg:CC FLAGS_REG))]
8515 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8517 (define_insn "*iordi_1_rex64"
8518 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8519 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8520 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8521 (clobber (reg:CC FLAGS_REG))]
8523 && ix86_binary_operator_ok (IOR, DImode, operands)"
8524 "or{q}\t{%2, %0|%0, %2}"
8525 [(set_attr "type" "alu")
8526 (set_attr "mode" "DI")])
8528 (define_insn "*iordi_2_rex64"
8529 [(set (reg FLAGS_REG)
8530 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8531 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8533 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8534 (ior:DI (match_dup 1) (match_dup 2)))]
8536 && ix86_match_ccmode (insn, CCNOmode)
8537 && ix86_binary_operator_ok (IOR, DImode, operands)"
8538 "or{q}\t{%2, %0|%0, %2}"
8539 [(set_attr "type" "alu")
8540 (set_attr "mode" "DI")])
8542 (define_insn "*iordi_3_rex64"
8543 [(set (reg FLAGS_REG)
8544 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8545 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8547 (clobber (match_scratch:DI 0 "=r"))]
8549 && ix86_match_ccmode (insn, CCNOmode)
8550 && ix86_binary_operator_ok (IOR, DImode, operands)"
8551 "or{q}\t{%2, %0|%0, %2}"
8552 [(set_attr "type" "alu")
8553 (set_attr "mode" "DI")])
8556 (define_expand "iorsi3"
8557 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8558 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8559 (match_operand:SI 2 "general_operand" "")))
8560 (clobber (reg:CC FLAGS_REG))]
8562 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8564 (define_insn "*iorsi_1"
8565 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8566 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8567 (match_operand:SI 2 "general_operand" "ri,rmi")))
8568 (clobber (reg:CC FLAGS_REG))]
8569 "ix86_binary_operator_ok (IOR, SImode, operands)"
8570 "or{l}\t{%2, %0|%0, %2}"
8571 [(set_attr "type" "alu")
8572 (set_attr "mode" "SI")])
8574 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8575 (define_insn "*iorsi_1_zext"
8576 [(set (match_operand:DI 0 "register_operand" "=rm")
8578 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8579 (match_operand:SI 2 "general_operand" "rim"))))
8580 (clobber (reg:CC FLAGS_REG))]
8581 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8582 "or{l}\t{%2, %k0|%k0, %2}"
8583 [(set_attr "type" "alu")
8584 (set_attr "mode" "SI")])
8586 (define_insn "*iorsi_1_zext_imm"
8587 [(set (match_operand:DI 0 "register_operand" "=rm")
8588 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8589 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8590 (clobber (reg:CC FLAGS_REG))]
8592 "or{l}\t{%2, %k0|%k0, %2}"
8593 [(set_attr "type" "alu")
8594 (set_attr "mode" "SI")])
8596 (define_insn "*iorsi_2"
8597 [(set (reg FLAGS_REG)
8598 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8599 (match_operand:SI 2 "general_operand" "rim,ri"))
8601 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8602 (ior:SI (match_dup 1) (match_dup 2)))]
8603 "ix86_match_ccmode (insn, CCNOmode)
8604 && ix86_binary_operator_ok (IOR, SImode, operands)"
8605 "or{l}\t{%2, %0|%0, %2}"
8606 [(set_attr "type" "alu")
8607 (set_attr "mode" "SI")])
8609 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8610 ;; ??? Special case for immediate operand is missing - it is tricky.
8611 (define_insn "*iorsi_2_zext"
8612 [(set (reg FLAGS_REG)
8613 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8614 (match_operand:SI 2 "general_operand" "rim"))
8616 (set (match_operand:DI 0 "register_operand" "=r")
8617 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8618 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8619 && ix86_binary_operator_ok (IOR, SImode, operands)"
8620 "or{l}\t{%2, %k0|%k0, %2}"
8621 [(set_attr "type" "alu")
8622 (set_attr "mode" "SI")])
8624 (define_insn "*iorsi_2_zext_imm"
8625 [(set (reg FLAGS_REG)
8626 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8627 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8629 (set (match_operand:DI 0 "register_operand" "=r")
8630 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8631 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8632 && ix86_binary_operator_ok (IOR, SImode, operands)"
8633 "or{l}\t{%2, %k0|%k0, %2}"
8634 [(set_attr "type" "alu")
8635 (set_attr "mode" "SI")])
8637 (define_insn "*iorsi_3"
8638 [(set (reg FLAGS_REG)
8639 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8640 (match_operand:SI 2 "general_operand" "rim"))
8642 (clobber (match_scratch:SI 0 "=r"))]
8643 "ix86_match_ccmode (insn, CCNOmode)
8644 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8645 "or{l}\t{%2, %0|%0, %2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "mode" "SI")])
8649 (define_expand "iorhi3"
8650 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8651 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8652 (match_operand:HI 2 "general_operand" "")))
8653 (clobber (reg:CC FLAGS_REG))]
8654 "TARGET_HIMODE_MATH"
8655 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8657 (define_insn "*iorhi_1"
8658 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8659 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8660 (match_operand:HI 2 "general_operand" "rmi,ri")))
8661 (clobber (reg:CC FLAGS_REG))]
8662 "ix86_binary_operator_ok (IOR, HImode, operands)"
8663 "or{w}\t{%2, %0|%0, %2}"
8664 [(set_attr "type" "alu")
8665 (set_attr "mode" "HI")])
8667 (define_insn "*iorhi_2"
8668 [(set (reg FLAGS_REG)
8669 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8670 (match_operand:HI 2 "general_operand" "rim,ri"))
8672 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8673 (ior:HI (match_dup 1) (match_dup 2)))]
8674 "ix86_match_ccmode (insn, CCNOmode)
8675 && ix86_binary_operator_ok (IOR, HImode, operands)"
8676 "or{w}\t{%2, %0|%0, %2}"
8677 [(set_attr "type" "alu")
8678 (set_attr "mode" "HI")])
8680 (define_insn "*iorhi_3"
8681 [(set (reg FLAGS_REG)
8682 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8683 (match_operand:HI 2 "general_operand" "rim"))
8685 (clobber (match_scratch:HI 0 "=r"))]
8686 "ix86_match_ccmode (insn, CCNOmode)
8687 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8688 "or{w}\t{%2, %0|%0, %2}"
8689 [(set_attr "type" "alu")
8690 (set_attr "mode" "HI")])
8692 (define_expand "iorqi3"
8693 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8694 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8695 (match_operand:QI 2 "general_operand" "")))
8696 (clobber (reg:CC FLAGS_REG))]
8697 "TARGET_QIMODE_MATH"
8698 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8700 ;; %%% Potential partial reg stall on alternative 2. What to do?
8701 (define_insn "*iorqi_1"
8702 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8703 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8704 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8705 (clobber (reg:CC FLAGS_REG))]
8706 "ix86_binary_operator_ok (IOR, QImode, operands)"
8708 or{b}\t{%2, %0|%0, %2}
8709 or{b}\t{%2, %0|%0, %2}
8710 or{l}\t{%k2, %k0|%k0, %k2}"
8711 [(set_attr "type" "alu")
8712 (set_attr "mode" "QI,QI,SI")])
8714 (define_insn "*iorqi_1_slp"
8715 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8716 (ior:QI (match_dup 0)
8717 (match_operand:QI 1 "general_operand" "qmi,qi")))
8718 (clobber (reg:CC FLAGS_REG))]
8719 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8720 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8721 "or{b}\t{%1, %0|%0, %1}"
8722 [(set_attr "type" "alu1")
8723 (set_attr "mode" "QI")])
8725 (define_insn "*iorqi_2"
8726 [(set (reg FLAGS_REG)
8727 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8728 (match_operand:QI 2 "general_operand" "qim,qi"))
8730 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8731 (ior:QI (match_dup 1) (match_dup 2)))]
8732 "ix86_match_ccmode (insn, CCNOmode)
8733 && ix86_binary_operator_ok (IOR, QImode, operands)"
8734 "or{b}\t{%2, %0|%0, %2}"
8735 [(set_attr "type" "alu")
8736 (set_attr "mode" "QI")])
8738 (define_insn "*iorqi_2_slp"
8739 [(set (reg FLAGS_REG)
8740 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8741 (match_operand:QI 1 "general_operand" "qim,qi"))
8743 (set (strict_low_part (match_dup 0))
8744 (ior:QI (match_dup 0) (match_dup 1)))]
8745 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8746 && ix86_match_ccmode (insn, CCNOmode)
8747 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8748 "or{b}\t{%1, %0|%0, %1}"
8749 [(set_attr "type" "alu1")
8750 (set_attr "mode" "QI")])
8752 (define_insn "*iorqi_3"
8753 [(set (reg FLAGS_REG)
8754 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8755 (match_operand:QI 2 "general_operand" "qim"))
8757 (clobber (match_scratch:QI 0 "=q"))]
8758 "ix86_match_ccmode (insn, CCNOmode)
8759 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8760 "or{b}\t{%2, %0|%0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "mode" "QI")])
8764 (define_insn "iorqi_ext_0"
8765 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8770 (match_operand 1 "ext_register_operand" "0")
8773 (match_operand 2 "const_int_operand" "n")))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8776 "or{b}\t{%2, %h0|%h0, %2}"
8777 [(set_attr "type" "alu")
8778 (set_attr "length_immediate" "1")
8779 (set_attr "mode" "QI")])
8781 (define_insn "*iorqi_ext_1"
8782 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8787 (match_operand 1 "ext_register_operand" "0")
8791 (match_operand:QI 2 "general_operand" "Qm"))))
8792 (clobber (reg:CC FLAGS_REG))]
8794 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8795 "or{b}\t{%2, %h0|%h0, %2}"
8796 [(set_attr "type" "alu")
8797 (set_attr "length_immediate" "0")
8798 (set_attr "mode" "QI")])
8800 (define_insn "*iorqi_ext_1_rex64"
8801 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8806 (match_operand 1 "ext_register_operand" "0")
8810 (match_operand 2 "ext_register_operand" "Q"))))
8811 (clobber (reg:CC FLAGS_REG))]
8813 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8814 "or{b}\t{%2, %h0|%h0, %2}"
8815 [(set_attr "type" "alu")
8816 (set_attr "length_immediate" "0")
8817 (set_attr "mode" "QI")])
8819 (define_insn "*iorqi_ext_2"
8820 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8824 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8827 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8830 (clobber (reg:CC FLAGS_REG))]
8831 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8832 "ior{b}\t{%h2, %h0|%h0, %h2}"
8833 [(set_attr "type" "alu")
8834 (set_attr "length_immediate" "0")
8835 (set_attr "mode" "QI")])
8838 [(set (match_operand 0 "register_operand" "")
8839 (ior (match_operand 1 "register_operand" "")
8840 (match_operand 2 "const_int_operand" "")))
8841 (clobber (reg:CC FLAGS_REG))]
8843 && QI_REG_P (operands[0])
8844 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8845 && !(INTVAL (operands[2]) & ~(255 << 8))
8846 && GET_MODE (operands[0]) != QImode"
8847 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8848 (ior:SI (zero_extract:SI (match_dup 1)
8849 (const_int 8) (const_int 8))
8851 (clobber (reg:CC FLAGS_REG))])]
8852 "operands[0] = gen_lowpart (SImode, operands[0]);
8853 operands[1] = gen_lowpart (SImode, operands[1]);
8854 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8856 ;; Since OR can be encoded with sign extended immediate, this is only
8857 ;; profitable when 7th bit is set.
8859 [(set (match_operand 0 "register_operand" "")
8860 (ior (match_operand 1 "general_operand" "")
8861 (match_operand 2 "const_int_operand" "")))
8862 (clobber (reg:CC FLAGS_REG))]
8864 && ANY_QI_REG_P (operands[0])
8865 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8866 && !(INTVAL (operands[2]) & ~255)
8867 && (INTVAL (operands[2]) & 128)
8868 && GET_MODE (operands[0]) != QImode"
8869 [(parallel [(set (strict_low_part (match_dup 0))
8870 (ior:QI (match_dup 1)
8872 (clobber (reg:CC FLAGS_REG))])]
8873 "operands[0] = gen_lowpart (QImode, operands[0]);
8874 operands[1] = gen_lowpart (QImode, operands[1]);
8875 operands[2] = gen_lowpart (QImode, operands[2]);")
8877 ;; Logical XOR instructions
8879 ;; %%% This used to optimize known byte-wide and operations to memory.
8880 ;; If this is considered useful, it should be done with splitters.
8882 (define_expand "xordi3"
8883 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8884 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8885 (match_operand:DI 2 "x86_64_general_operand" "")))
8886 (clobber (reg:CC FLAGS_REG))]
8888 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8890 (define_insn "*xordi_1_rex64"
8891 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8892 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8893 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8894 (clobber (reg:CC FLAGS_REG))]
8896 && ix86_binary_operator_ok (XOR, DImode, operands)"
8898 xor{q}\t{%2, %0|%0, %2}
8899 xor{q}\t{%2, %0|%0, %2}"
8900 [(set_attr "type" "alu")
8901 (set_attr "mode" "DI,DI")])
8903 (define_insn "*xordi_2_rex64"
8904 [(set (reg FLAGS_REG)
8905 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8906 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8908 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8909 (xor:DI (match_dup 1) (match_dup 2)))]
8911 && ix86_match_ccmode (insn, CCNOmode)
8912 && ix86_binary_operator_ok (XOR, DImode, operands)"
8914 xor{q}\t{%2, %0|%0, %2}
8915 xor{q}\t{%2, %0|%0, %2}"
8916 [(set_attr "type" "alu")
8917 (set_attr "mode" "DI,DI")])
8919 (define_insn "*xordi_3_rex64"
8920 [(set (reg FLAGS_REG)
8921 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8922 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8924 (clobber (match_scratch:DI 0 "=r"))]
8926 && ix86_match_ccmode (insn, CCNOmode)
8927 && ix86_binary_operator_ok (XOR, DImode, operands)"
8928 "xor{q}\t{%2, %0|%0, %2}"
8929 [(set_attr "type" "alu")
8930 (set_attr "mode" "DI")])
8932 (define_expand "xorsi3"
8933 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8934 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8935 (match_operand:SI 2 "general_operand" "")))
8936 (clobber (reg:CC FLAGS_REG))]
8938 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8940 (define_insn "*xorsi_1"
8941 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8942 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8943 (match_operand:SI 2 "general_operand" "ri,rm")))
8944 (clobber (reg:CC FLAGS_REG))]
8945 "ix86_binary_operator_ok (XOR, SImode, operands)"
8946 "xor{l}\t{%2, %0|%0, %2}"
8947 [(set_attr "type" "alu")
8948 (set_attr "mode" "SI")])
8950 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8951 ;; Add speccase for immediates
8952 (define_insn "*xorsi_1_zext"
8953 [(set (match_operand:DI 0 "register_operand" "=r")
8955 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8956 (match_operand:SI 2 "general_operand" "rim"))))
8957 (clobber (reg:CC FLAGS_REG))]
8958 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8959 "xor{l}\t{%2, %k0|%k0, %2}"
8960 [(set_attr "type" "alu")
8961 (set_attr "mode" "SI")])
8963 (define_insn "*xorsi_1_zext_imm"
8964 [(set (match_operand:DI 0 "register_operand" "=r")
8965 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8966 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8967 (clobber (reg:CC FLAGS_REG))]
8968 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8969 "xor{l}\t{%2, %k0|%k0, %2}"
8970 [(set_attr "type" "alu")
8971 (set_attr "mode" "SI")])
8973 (define_insn "*xorsi_2"
8974 [(set (reg FLAGS_REG)
8975 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8976 (match_operand:SI 2 "general_operand" "rim,ri"))
8978 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8979 (xor:SI (match_dup 1) (match_dup 2)))]
8980 "ix86_match_ccmode (insn, CCNOmode)
8981 && ix86_binary_operator_ok (XOR, SImode, operands)"
8982 "xor{l}\t{%2, %0|%0, %2}"
8983 [(set_attr "type" "alu")
8984 (set_attr "mode" "SI")])
8986 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8987 ;; ??? Special case for immediate operand is missing - it is tricky.
8988 (define_insn "*xorsi_2_zext"
8989 [(set (reg FLAGS_REG)
8990 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8991 (match_operand:SI 2 "general_operand" "rim"))
8993 (set (match_operand:DI 0 "register_operand" "=r")
8994 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
8995 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8996 && ix86_binary_operator_ok (XOR, SImode, operands)"
8997 "xor{l}\t{%2, %k0|%k0, %2}"
8998 [(set_attr "type" "alu")
8999 (set_attr "mode" "SI")])
9001 (define_insn "*xorsi_2_zext_imm"
9002 [(set (reg FLAGS_REG)
9003 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9004 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9006 (set (match_operand:DI 0 "register_operand" "=r")
9007 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9008 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9009 && ix86_binary_operator_ok (XOR, SImode, operands)"
9010 "xor{l}\t{%2, %k0|%k0, %2}"
9011 [(set_attr "type" "alu")
9012 (set_attr "mode" "SI")])
9014 (define_insn "*xorsi_3"
9015 [(set (reg FLAGS_REG)
9016 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9017 (match_operand:SI 2 "general_operand" "rim"))
9019 (clobber (match_scratch:SI 0 "=r"))]
9020 "ix86_match_ccmode (insn, CCNOmode)
9021 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9022 "xor{l}\t{%2, %0|%0, %2}"
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "SI")])
9026 (define_expand "xorhi3"
9027 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9028 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9029 (match_operand:HI 2 "general_operand" "")))
9030 (clobber (reg:CC FLAGS_REG))]
9031 "TARGET_HIMODE_MATH"
9032 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9034 (define_insn "*xorhi_1"
9035 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9036 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9037 (match_operand:HI 2 "general_operand" "rmi,ri")))
9038 (clobber (reg:CC FLAGS_REG))]
9039 "ix86_binary_operator_ok (XOR, HImode, operands)"
9040 "xor{w}\t{%2, %0|%0, %2}"
9041 [(set_attr "type" "alu")
9042 (set_attr "mode" "HI")])
9044 (define_insn "*xorhi_2"
9045 [(set (reg FLAGS_REG)
9046 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9047 (match_operand:HI 2 "general_operand" "rim,ri"))
9049 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9050 (xor:HI (match_dup 1) (match_dup 2)))]
9051 "ix86_match_ccmode (insn, CCNOmode)
9052 && ix86_binary_operator_ok (XOR, HImode, operands)"
9053 "xor{w}\t{%2, %0|%0, %2}"
9054 [(set_attr "type" "alu")
9055 (set_attr "mode" "HI")])
9057 (define_insn "*xorhi_3"
9058 [(set (reg FLAGS_REG)
9059 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9060 (match_operand:HI 2 "general_operand" "rim"))
9062 (clobber (match_scratch:HI 0 "=r"))]
9063 "ix86_match_ccmode (insn, CCNOmode)
9064 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9065 "xor{w}\t{%2, %0|%0, %2}"
9066 [(set_attr "type" "alu")
9067 (set_attr "mode" "HI")])
9069 (define_expand "xorqi3"
9070 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9071 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9072 (match_operand:QI 2 "general_operand" "")))
9073 (clobber (reg:CC FLAGS_REG))]
9074 "TARGET_QIMODE_MATH"
9075 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9077 ;; %%% Potential partial reg stall on alternative 2. What to do?
9078 (define_insn "*xorqi_1"
9079 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9080 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9081 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9082 (clobber (reg:CC FLAGS_REG))]
9083 "ix86_binary_operator_ok (XOR, QImode, operands)"
9085 xor{b}\t{%2, %0|%0, %2}
9086 xor{b}\t{%2, %0|%0, %2}
9087 xor{l}\t{%k2, %k0|%k0, %k2}"
9088 [(set_attr "type" "alu")
9089 (set_attr "mode" "QI,QI,SI")])
9091 (define_insn "*xorqi_1_slp"
9092 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9093 (xor:QI (match_dup 0)
9094 (match_operand:QI 1 "general_operand" "qi,qmi")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9097 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9098 "xor{b}\t{%1, %0|%0, %1}"
9099 [(set_attr "type" "alu1")
9100 (set_attr "mode" "QI")])
9102 (define_insn "xorqi_ext_0"
9103 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9108 (match_operand 1 "ext_register_operand" "0")
9111 (match_operand 2 "const_int_operand" "n")))
9112 (clobber (reg:CC FLAGS_REG))]
9113 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9114 "xor{b}\t{%2, %h0|%h0, %2}"
9115 [(set_attr "type" "alu")
9116 (set_attr "length_immediate" "1")
9117 (set_attr "mode" "QI")])
9119 (define_insn "*xorqi_ext_1"
9120 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9125 (match_operand 1 "ext_register_operand" "0")
9129 (match_operand:QI 2 "general_operand" "Qm"))))
9130 (clobber (reg:CC FLAGS_REG))]
9132 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9133 "xor{b}\t{%2, %h0|%h0, %2}"
9134 [(set_attr "type" "alu")
9135 (set_attr "length_immediate" "0")
9136 (set_attr "mode" "QI")])
9138 (define_insn "*xorqi_ext_1_rex64"
9139 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9144 (match_operand 1 "ext_register_operand" "0")
9148 (match_operand 2 "ext_register_operand" "Q"))))
9149 (clobber (reg:CC FLAGS_REG))]
9151 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9152 "xor{b}\t{%2, %h0|%h0, %2}"
9153 [(set_attr "type" "alu")
9154 (set_attr "length_immediate" "0")
9155 (set_attr "mode" "QI")])
9157 (define_insn "*xorqi_ext_2"
9158 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9162 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9165 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9168 (clobber (reg:CC FLAGS_REG))]
9169 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170 "xor{b}\t{%h2, %h0|%h0, %h2}"
9171 [(set_attr "type" "alu")
9172 (set_attr "length_immediate" "0")
9173 (set_attr "mode" "QI")])
9175 (define_insn "*xorqi_cc_1"
9176 [(set (reg FLAGS_REG)
9178 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9179 (match_operand:QI 2 "general_operand" "qim,qi"))
9181 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9182 (xor:QI (match_dup 1) (match_dup 2)))]
9183 "ix86_match_ccmode (insn, CCNOmode)
9184 && ix86_binary_operator_ok (XOR, QImode, operands)"
9185 "xor{b}\t{%2, %0|%0, %2}"
9186 [(set_attr "type" "alu")
9187 (set_attr "mode" "QI")])
9189 (define_insn "*xorqi_2_slp"
9190 [(set (reg FLAGS_REG)
9191 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9192 (match_operand:QI 1 "general_operand" "qim,qi"))
9194 (set (strict_low_part (match_dup 0))
9195 (xor:QI (match_dup 0) (match_dup 1)))]
9196 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9197 && ix86_match_ccmode (insn, CCNOmode)
9198 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9199 "xor{b}\t{%1, %0|%0, %1}"
9200 [(set_attr "type" "alu1")
9201 (set_attr "mode" "QI")])
9203 (define_insn "*xorqi_cc_2"
9204 [(set (reg FLAGS_REG)
9206 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9207 (match_operand:QI 2 "general_operand" "qim"))
9209 (clobber (match_scratch:QI 0 "=q"))]
9210 "ix86_match_ccmode (insn, CCNOmode)
9211 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9212 "xor{b}\t{%2, %0|%0, %2}"
9213 [(set_attr "type" "alu")
9214 (set_attr "mode" "QI")])
9216 (define_insn "*xorqi_cc_ext_1"
9217 [(set (reg FLAGS_REG)
9221 (match_operand 1 "ext_register_operand" "0")
9224 (match_operand:QI 2 "general_operand" "qmn"))
9226 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9230 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9232 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9233 "xor{b}\t{%2, %h0|%h0, %2}"
9234 [(set_attr "type" "alu")
9235 (set_attr "mode" "QI")])
9237 (define_insn "*xorqi_cc_ext_1_rex64"
9238 [(set (reg FLAGS_REG)
9242 (match_operand 1 "ext_register_operand" "0")
9245 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9247 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9251 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9253 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9254 "xor{b}\t{%2, %h0|%h0, %2}"
9255 [(set_attr "type" "alu")
9256 (set_attr "mode" "QI")])
9258 (define_expand "xorqi_cc_ext_1"
9260 (set (reg:CCNO FLAGS_REG)
9264 (match_operand 1 "ext_register_operand" "")
9267 (match_operand:QI 2 "general_operand" ""))
9269 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9273 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9279 [(set (match_operand 0 "register_operand" "")
9280 (xor (match_operand 1 "register_operand" "")
9281 (match_operand 2 "const_int_operand" "")))
9282 (clobber (reg:CC FLAGS_REG))]
9284 && QI_REG_P (operands[0])
9285 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9286 && !(INTVAL (operands[2]) & ~(255 << 8))
9287 && GET_MODE (operands[0]) != QImode"
9288 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9289 (xor:SI (zero_extract:SI (match_dup 1)
9290 (const_int 8) (const_int 8))
9292 (clobber (reg:CC FLAGS_REG))])]
9293 "operands[0] = gen_lowpart (SImode, operands[0]);
9294 operands[1] = gen_lowpart (SImode, operands[1]);
9295 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9297 ;; Since XOR can be encoded with sign extended immediate, this is only
9298 ;; profitable when 7th bit is set.
9300 [(set (match_operand 0 "register_operand" "")
9301 (xor (match_operand 1 "general_operand" "")
9302 (match_operand 2 "const_int_operand" "")))
9303 (clobber (reg:CC FLAGS_REG))]
9305 && ANY_QI_REG_P (operands[0])
9306 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9307 && !(INTVAL (operands[2]) & ~255)
9308 && (INTVAL (operands[2]) & 128)
9309 && GET_MODE (operands[0]) != QImode"
9310 [(parallel [(set (strict_low_part (match_dup 0))
9311 (xor:QI (match_dup 1)
9313 (clobber (reg:CC FLAGS_REG))])]
9314 "operands[0] = gen_lowpart (QImode, operands[0]);
9315 operands[1] = gen_lowpart (QImode, operands[1]);
9316 operands[2] = gen_lowpart (QImode, operands[2]);")
9318 ;; Negation instructions
9320 (define_expand "negti2"
9321 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9322 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9323 (clobber (reg:CC FLAGS_REG))])]
9325 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9327 (define_insn "*negti2_1"
9328 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9329 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9330 (clobber (reg:CC FLAGS_REG))]
9332 && ix86_unary_operator_ok (NEG, TImode, operands)"
9336 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9337 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9338 (clobber (reg:CC FLAGS_REG))]
9339 "TARGET_64BIT && reload_completed"
9341 [(set (reg:CCZ FLAGS_REG)
9342 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9343 (set (match_dup 0) (neg:DI (match_dup 2)))])
9346 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9349 (clobber (reg:CC FLAGS_REG))])
9352 (neg:DI (match_dup 1)))
9353 (clobber (reg:CC FLAGS_REG))])]
9354 "split_ti (operands+1, 1, operands+2, operands+3);
9355 split_ti (operands+0, 1, operands+0, operands+1);")
9357 (define_expand "negdi2"
9358 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9359 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))])]
9362 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9364 (define_insn "*negdi2_1"
9365 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9366 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9367 (clobber (reg:CC FLAGS_REG))]
9369 && ix86_unary_operator_ok (NEG, DImode, operands)"
9373 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9374 (neg:DI (match_operand:DI 1 "general_operand" "")))
9375 (clobber (reg:CC FLAGS_REG))]
9376 "!TARGET_64BIT && reload_completed"
9378 [(set (reg:CCZ FLAGS_REG)
9379 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9380 (set (match_dup 0) (neg:SI (match_dup 2)))])
9383 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9386 (clobber (reg:CC FLAGS_REG))])
9389 (neg:SI (match_dup 1)))
9390 (clobber (reg:CC FLAGS_REG))])]
9391 "split_di (operands+1, 1, operands+2, operands+3);
9392 split_di (operands+0, 1, operands+0, operands+1);")
9394 (define_insn "*negdi2_1_rex64"
9395 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9396 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9397 (clobber (reg:CC FLAGS_REG))]
9398 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9400 [(set_attr "type" "negnot")
9401 (set_attr "mode" "DI")])
9403 ;; The problem with neg is that it does not perform (compare x 0),
9404 ;; it really performs (compare 0 x), which leaves us with the zero
9405 ;; flag being the only useful item.
9407 (define_insn "*negdi2_cmpz_rex64"
9408 [(set (reg:CCZ FLAGS_REG)
9409 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9411 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9412 (neg:DI (match_dup 1)))]
9413 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9415 [(set_attr "type" "negnot")
9416 (set_attr "mode" "DI")])
9419 (define_expand "negsi2"
9420 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9421 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9422 (clobber (reg:CC FLAGS_REG))])]
9424 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9426 (define_insn "*negsi2_1"
9427 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9428 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9429 (clobber (reg:CC FLAGS_REG))]
9430 "ix86_unary_operator_ok (NEG, SImode, operands)"
9432 [(set_attr "type" "negnot")
9433 (set_attr "mode" "SI")])
9435 ;; Combine is quite creative about this pattern.
9436 (define_insn "*negsi2_1_zext"
9437 [(set (match_operand:DI 0 "register_operand" "=r")
9438 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9441 (clobber (reg:CC FLAGS_REG))]
9442 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9444 [(set_attr "type" "negnot")
9445 (set_attr "mode" "SI")])
9447 ;; The problem with neg is that it does not perform (compare x 0),
9448 ;; it really performs (compare 0 x), which leaves us with the zero
9449 ;; flag being the only useful item.
9451 (define_insn "*negsi2_cmpz"
9452 [(set (reg:CCZ FLAGS_REG)
9453 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9455 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9456 (neg:SI (match_dup 1)))]
9457 "ix86_unary_operator_ok (NEG, SImode, operands)"
9459 [(set_attr "type" "negnot")
9460 (set_attr "mode" "SI")])
9462 (define_insn "*negsi2_cmpz_zext"
9463 [(set (reg:CCZ FLAGS_REG)
9464 (compare:CCZ (lshiftrt:DI
9466 (match_operand:DI 1 "register_operand" "0")
9470 (set (match_operand:DI 0 "register_operand" "=r")
9471 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9474 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9476 [(set_attr "type" "negnot")
9477 (set_attr "mode" "SI")])
9479 (define_expand "neghi2"
9480 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9481 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9482 (clobber (reg:CC FLAGS_REG))])]
9483 "TARGET_HIMODE_MATH"
9484 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9486 (define_insn "*neghi2_1"
9487 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9488 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9489 (clobber (reg:CC FLAGS_REG))]
9490 "ix86_unary_operator_ok (NEG, HImode, operands)"
9492 [(set_attr "type" "negnot")
9493 (set_attr "mode" "HI")])
9495 (define_insn "*neghi2_cmpz"
9496 [(set (reg:CCZ FLAGS_REG)
9497 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9499 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9500 (neg:HI (match_dup 1)))]
9501 "ix86_unary_operator_ok (NEG, HImode, operands)"
9503 [(set_attr "type" "negnot")
9504 (set_attr "mode" "HI")])
9506 (define_expand "negqi2"
9507 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9508 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9509 (clobber (reg:CC FLAGS_REG))])]
9510 "TARGET_QIMODE_MATH"
9511 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9513 (define_insn "*negqi2_1"
9514 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9515 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9516 (clobber (reg:CC FLAGS_REG))]
9517 "ix86_unary_operator_ok (NEG, QImode, operands)"
9519 [(set_attr "type" "negnot")
9520 (set_attr "mode" "QI")])
9522 (define_insn "*negqi2_cmpz"
9523 [(set (reg:CCZ FLAGS_REG)
9524 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9526 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9527 (neg:QI (match_dup 1)))]
9528 "ix86_unary_operator_ok (NEG, QImode, operands)"
9530 [(set_attr "type" "negnot")
9531 (set_attr "mode" "QI")])
9533 ;; Changing of sign for FP values is doable using integer unit too.
9535 (define_expand "negsf2"
9536 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9537 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9538 "TARGET_80387 || TARGET_SSE_MATH"
9539 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9541 (define_expand "abssf2"
9542 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9543 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9544 "TARGET_80387 || TARGET_SSE_MATH"
9545 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9547 (define_insn "*absnegsf2_mixed"
9548 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9549 (match_operator:SF 3 "absneg_operator"
9550 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9551 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9552 (clobber (reg:CC FLAGS_REG))]
9553 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9554 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9557 (define_insn "*absnegsf2_sse"
9558 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9559 (match_operator:SF 3 "absneg_operator"
9560 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9561 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9562 (clobber (reg:CC FLAGS_REG))]
9564 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9567 (define_insn "*absnegsf2_i387"
9568 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9569 (match_operator:SF 3 "absneg_operator"
9570 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9571 (use (match_operand 2 "" ""))
9572 (clobber (reg:CC FLAGS_REG))]
9573 "TARGET_80387 && !TARGET_SSE_MATH
9574 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9577 (define_expand "copysignsf3"
9578 [(match_operand:SF 0 "register_operand" "")
9579 (match_operand:SF 1 "nonmemory_operand" "")
9580 (match_operand:SF 2 "register_operand" "")]
9583 ix86_expand_copysign (operands);
9587 (define_insn_and_split "copysignsf3_const"
9588 [(set (match_operand:SF 0 "register_operand" "=x")
9590 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9591 (match_operand:SF 2 "register_operand" "0")
9592 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9596 "&& reload_completed"
9599 ix86_split_copysign_const (operands);
9603 (define_insn "copysignsf3_var"
9604 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9606 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9607 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9608 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9609 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9611 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9616 [(set (match_operand:SF 0 "register_operand" "")
9618 [(match_operand:SF 2 "register_operand" "")
9619 (match_operand:SF 3 "register_operand" "")
9620 (match_operand:V4SF 4 "" "")
9621 (match_operand:V4SF 5 "" "")]
9623 (clobber (match_scratch:V4SF 1 ""))]
9624 "TARGET_SSE_MATH && reload_completed"
9627 ix86_split_copysign_var (operands);
9631 (define_expand "negdf2"
9632 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9633 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9634 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9635 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9637 (define_expand "absdf2"
9638 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9639 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9640 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9641 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9643 (define_insn "*absnegdf2_mixed"
9644 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9645 (match_operator:DF 3 "absneg_operator"
9646 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9647 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9648 (clobber (reg:CC FLAGS_REG))]
9649 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9650 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9653 (define_insn "*absnegdf2_sse"
9654 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9655 (match_operator:DF 3 "absneg_operator"
9656 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9657 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9658 (clobber (reg:CC FLAGS_REG))]
9659 "TARGET_SSE2 && TARGET_SSE_MATH
9660 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9663 (define_insn "*absnegdf2_i387"
9664 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9665 (match_operator:DF 3 "absneg_operator"
9666 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9667 (use (match_operand 2 "" ""))
9668 (clobber (reg:CC FLAGS_REG))]
9669 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9670 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9673 (define_expand "copysigndf3"
9674 [(match_operand:DF 0 "register_operand" "")
9675 (match_operand:DF 1 "nonmemory_operand" "")
9676 (match_operand:DF 2 "register_operand" "")]
9677 "TARGET_SSE2 && TARGET_SSE_MATH"
9679 ix86_expand_copysign (operands);
9683 (define_insn_and_split "copysigndf3_const"
9684 [(set (match_operand:DF 0 "register_operand" "=x")
9686 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9687 (match_operand:DF 2 "register_operand" "0")
9688 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9690 "TARGET_SSE2 && TARGET_SSE_MATH"
9692 "&& reload_completed"
9695 ix86_split_copysign_const (operands);
9699 (define_insn "copysigndf3_var"
9700 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9702 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9703 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9704 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9705 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9707 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9708 "TARGET_SSE2 && TARGET_SSE_MATH"
9712 [(set (match_operand:DF 0 "register_operand" "")
9714 [(match_operand:DF 2 "register_operand" "")
9715 (match_operand:DF 3 "register_operand" "")
9716 (match_operand:V2DF 4 "" "")
9717 (match_operand:V2DF 5 "" "")]
9719 (clobber (match_scratch:V2DF 1 ""))]
9720 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9723 ix86_split_copysign_var (operands);
9727 (define_expand "negxf2"
9728 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9729 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9731 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9733 (define_expand "absxf2"
9734 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9735 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9737 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9739 (define_insn "*absnegxf2_i387"
9740 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9741 (match_operator:XF 3 "absneg_operator"
9742 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9743 (use (match_operand 2 "" ""))
9744 (clobber (reg:CC FLAGS_REG))]
9746 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9749 ;; Splitters for fp abs and neg.
9752 [(set (match_operand 0 "fp_register_operand" "")
9753 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9754 (use (match_operand 2 "" ""))
9755 (clobber (reg:CC FLAGS_REG))]
9757 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9760 [(set (match_operand 0 "register_operand" "")
9761 (match_operator 3 "absneg_operator"
9762 [(match_operand 1 "register_operand" "")]))
9763 (use (match_operand 2 "nonimmediate_operand" ""))
9764 (clobber (reg:CC FLAGS_REG))]
9765 "reload_completed && SSE_REG_P (operands[0])"
9766 [(set (match_dup 0) (match_dup 3))]
9768 enum machine_mode mode = GET_MODE (operands[0]);
9769 enum machine_mode vmode = GET_MODE (operands[2]);
9772 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9773 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9774 if (operands_match_p (operands[0], operands[2]))
9777 operands[1] = operands[2];
9780 if (GET_CODE (operands[3]) == ABS)
9781 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9783 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9788 [(set (match_operand:SF 0 "register_operand" "")
9789 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9790 (use (match_operand:V4SF 2 "" ""))
9791 (clobber (reg:CC FLAGS_REG))]
9793 [(parallel [(set (match_dup 0) (match_dup 1))
9794 (clobber (reg:CC FLAGS_REG))])]
9797 operands[0] = gen_lowpart (SImode, operands[0]);
9798 if (GET_CODE (operands[1]) == ABS)
9800 tmp = gen_int_mode (0x7fffffff, SImode);
9801 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9805 tmp = gen_int_mode (0x80000000, SImode);
9806 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9812 [(set (match_operand:DF 0 "register_operand" "")
9813 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9814 (use (match_operand 2 "" ""))
9815 (clobber (reg:CC FLAGS_REG))]
9817 [(parallel [(set (match_dup 0) (match_dup 1))
9818 (clobber (reg:CC FLAGS_REG))])]
9823 tmp = gen_lowpart (DImode, operands[0]);
9824 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9827 if (GET_CODE (operands[1]) == ABS)
9830 tmp = gen_rtx_NOT (DImode, tmp);
9834 operands[0] = gen_highpart (SImode, operands[0]);
9835 if (GET_CODE (operands[1]) == ABS)
9837 tmp = gen_int_mode (0x7fffffff, SImode);
9838 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9842 tmp = gen_int_mode (0x80000000, SImode);
9843 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9850 [(set (match_operand:XF 0 "register_operand" "")
9851 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9852 (use (match_operand 2 "" ""))
9853 (clobber (reg:CC FLAGS_REG))]
9855 [(parallel [(set (match_dup 0) (match_dup 1))
9856 (clobber (reg:CC FLAGS_REG))])]
9859 operands[0] = gen_rtx_REG (SImode,
9860 true_regnum (operands[0])
9861 + (TARGET_64BIT ? 1 : 2));
9862 if (GET_CODE (operands[1]) == ABS)
9864 tmp = GEN_INT (0x7fff);
9865 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9869 tmp = GEN_INT (0x8000);
9870 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9876 [(set (match_operand 0 "memory_operand" "")
9877 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9878 (use (match_operand 2 "" ""))
9879 (clobber (reg:CC FLAGS_REG))]
9881 [(parallel [(set (match_dup 0) (match_dup 1))
9882 (clobber (reg:CC FLAGS_REG))])]
9884 enum machine_mode mode = GET_MODE (operands[0]);
9885 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9888 operands[0] = adjust_address (operands[0], QImode, size - 1);
9889 if (GET_CODE (operands[1]) == ABS)
9891 tmp = gen_int_mode (0x7f, QImode);
9892 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9896 tmp = gen_int_mode (0x80, QImode);
9897 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9902 ;; Conditionalize these after reload. If they match before reload, we
9903 ;; lose the clobber and ability to use integer instructions.
9905 (define_insn "*negsf2_1"
9906 [(set (match_operand:SF 0 "register_operand" "=f")
9907 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9908 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9910 [(set_attr "type" "fsgn")
9911 (set_attr "mode" "SF")])
9913 (define_insn "*negdf2_1"
9914 [(set (match_operand:DF 0 "register_operand" "=f")
9915 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9916 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9918 [(set_attr "type" "fsgn")
9919 (set_attr "mode" "DF")])
9921 (define_insn "*negxf2_1"
9922 [(set (match_operand:XF 0 "register_operand" "=f")
9923 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9926 [(set_attr "type" "fsgn")
9927 (set_attr "mode" "XF")])
9929 (define_insn "*abssf2_1"
9930 [(set (match_operand:SF 0 "register_operand" "=f")
9931 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9932 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9934 [(set_attr "type" "fsgn")
9935 (set_attr "mode" "SF")])
9937 (define_insn "*absdf2_1"
9938 [(set (match_operand:DF 0 "register_operand" "=f")
9939 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9940 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9942 [(set_attr "type" "fsgn")
9943 (set_attr "mode" "DF")])
9945 (define_insn "*absxf2_1"
9946 [(set (match_operand:XF 0 "register_operand" "=f")
9947 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9950 [(set_attr "type" "fsgn")
9951 (set_attr "mode" "DF")])
9953 (define_insn "*negextendsfdf2"
9954 [(set (match_operand:DF 0 "register_operand" "=f")
9955 (neg:DF (float_extend:DF
9956 (match_operand:SF 1 "register_operand" "0"))))]
9957 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9959 [(set_attr "type" "fsgn")
9960 (set_attr "mode" "DF")])
9962 (define_insn "*negextenddfxf2"
9963 [(set (match_operand:XF 0 "register_operand" "=f")
9964 (neg:XF (float_extend:XF
9965 (match_operand:DF 1 "register_operand" "0"))))]
9968 [(set_attr "type" "fsgn")
9969 (set_attr "mode" "XF")])
9971 (define_insn "*negextendsfxf2"
9972 [(set (match_operand:XF 0 "register_operand" "=f")
9973 (neg:XF (float_extend:XF
9974 (match_operand:SF 1 "register_operand" "0"))))]
9977 [(set_attr "type" "fsgn")
9978 (set_attr "mode" "XF")])
9980 (define_insn "*absextendsfdf2"
9981 [(set (match_operand:DF 0 "register_operand" "=f")
9982 (abs:DF (float_extend:DF
9983 (match_operand:SF 1 "register_operand" "0"))))]
9984 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9986 [(set_attr "type" "fsgn")
9987 (set_attr "mode" "DF")])
9989 (define_insn "*absextenddfxf2"
9990 [(set (match_operand:XF 0 "register_operand" "=f")
9991 (abs:XF (float_extend:XF
9992 (match_operand:DF 1 "register_operand" "0"))))]
9995 [(set_attr "type" "fsgn")
9996 (set_attr "mode" "XF")])
9998 (define_insn "*absextendsfxf2"
9999 [(set (match_operand:XF 0 "register_operand" "=f")
10000 (abs:XF (float_extend:XF
10001 (match_operand:SF 1 "register_operand" "0"))))]
10004 [(set_attr "type" "fsgn")
10005 (set_attr "mode" "XF")])
10007 ;; One complement instructions
10009 (define_expand "one_cmpldi2"
10010 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10011 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10013 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10015 (define_insn "*one_cmpldi2_1_rex64"
10016 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10017 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10018 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10020 [(set_attr "type" "negnot")
10021 (set_attr "mode" "DI")])
10023 (define_insn "*one_cmpldi2_2_rex64"
10024 [(set (reg FLAGS_REG)
10025 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10027 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10028 (not:DI (match_dup 1)))]
10029 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10030 && ix86_unary_operator_ok (NOT, DImode, operands)"
10032 [(set_attr "type" "alu1")
10033 (set_attr "mode" "DI")])
10036 [(set (match_operand 0 "flags_reg_operand" "")
10037 (match_operator 2 "compare_operator"
10038 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10040 (set (match_operand:DI 1 "nonimmediate_operand" "")
10041 (not:DI (match_dup 3)))]
10042 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10043 [(parallel [(set (match_dup 0)
10045 [(xor:DI (match_dup 3) (const_int -1))
10048 (xor:DI (match_dup 3) (const_int -1)))])]
10051 (define_expand "one_cmplsi2"
10052 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10053 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10055 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10057 (define_insn "*one_cmplsi2_1"
10058 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10059 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10060 "ix86_unary_operator_ok (NOT, SImode, operands)"
10062 [(set_attr "type" "negnot")
10063 (set_attr "mode" "SI")])
10065 ;; ??? Currently never generated - xor is used instead.
10066 (define_insn "*one_cmplsi2_1_zext"
10067 [(set (match_operand:DI 0 "register_operand" "=r")
10068 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10069 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10071 [(set_attr "type" "negnot")
10072 (set_attr "mode" "SI")])
10074 (define_insn "*one_cmplsi2_2"
10075 [(set (reg FLAGS_REG)
10076 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10078 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10079 (not:SI (match_dup 1)))]
10080 "ix86_match_ccmode (insn, CCNOmode)
10081 && ix86_unary_operator_ok (NOT, SImode, operands)"
10083 [(set_attr "type" "alu1")
10084 (set_attr "mode" "SI")])
10087 [(set (match_operand 0 "flags_reg_operand" "")
10088 (match_operator 2 "compare_operator"
10089 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10091 (set (match_operand:SI 1 "nonimmediate_operand" "")
10092 (not:SI (match_dup 3)))]
10093 "ix86_match_ccmode (insn, CCNOmode)"
10094 [(parallel [(set (match_dup 0)
10095 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10098 (xor:SI (match_dup 3) (const_int -1)))])]
10101 ;; ??? Currently never generated - xor is used instead.
10102 (define_insn "*one_cmplsi2_2_zext"
10103 [(set (reg FLAGS_REG)
10104 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10106 (set (match_operand:DI 0 "register_operand" "=r")
10107 (zero_extend:DI (not:SI (match_dup 1))))]
10108 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10109 && ix86_unary_operator_ok (NOT, SImode, operands)"
10111 [(set_attr "type" "alu1")
10112 (set_attr "mode" "SI")])
10115 [(set (match_operand 0 "flags_reg_operand" "")
10116 (match_operator 2 "compare_operator"
10117 [(not:SI (match_operand:SI 3 "register_operand" ""))
10119 (set (match_operand:DI 1 "register_operand" "")
10120 (zero_extend:DI (not:SI (match_dup 3))))]
10121 "ix86_match_ccmode (insn, CCNOmode)"
10122 [(parallel [(set (match_dup 0)
10123 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10126 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10129 (define_expand "one_cmplhi2"
10130 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10131 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10132 "TARGET_HIMODE_MATH"
10133 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10135 (define_insn "*one_cmplhi2_1"
10136 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10137 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10138 "ix86_unary_operator_ok (NOT, HImode, operands)"
10140 [(set_attr "type" "negnot")
10141 (set_attr "mode" "HI")])
10143 (define_insn "*one_cmplhi2_2"
10144 [(set (reg FLAGS_REG)
10145 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10147 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10148 (not:HI (match_dup 1)))]
10149 "ix86_match_ccmode (insn, CCNOmode)
10150 && ix86_unary_operator_ok (NEG, HImode, operands)"
10152 [(set_attr "type" "alu1")
10153 (set_attr "mode" "HI")])
10156 [(set (match_operand 0 "flags_reg_operand" "")
10157 (match_operator 2 "compare_operator"
10158 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10160 (set (match_operand:HI 1 "nonimmediate_operand" "")
10161 (not:HI (match_dup 3)))]
10162 "ix86_match_ccmode (insn, CCNOmode)"
10163 [(parallel [(set (match_dup 0)
10164 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10167 (xor:HI (match_dup 3) (const_int -1)))])]
10170 ;; %%% Potential partial reg stall on alternative 1. What to do?
10171 (define_expand "one_cmplqi2"
10172 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10173 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10174 "TARGET_QIMODE_MATH"
10175 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10177 (define_insn "*one_cmplqi2_1"
10178 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10179 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10180 "ix86_unary_operator_ok (NOT, QImode, operands)"
10184 [(set_attr "type" "negnot")
10185 (set_attr "mode" "QI,SI")])
10187 (define_insn "*one_cmplqi2_2"
10188 [(set (reg FLAGS_REG)
10189 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10191 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10192 (not:QI (match_dup 1)))]
10193 "ix86_match_ccmode (insn, CCNOmode)
10194 && ix86_unary_operator_ok (NOT, QImode, operands)"
10196 [(set_attr "type" "alu1")
10197 (set_attr "mode" "QI")])
10200 [(set (match_operand 0 "flags_reg_operand" "")
10201 (match_operator 2 "compare_operator"
10202 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10204 (set (match_operand:QI 1 "nonimmediate_operand" "")
10205 (not:QI (match_dup 3)))]
10206 "ix86_match_ccmode (insn, CCNOmode)"
10207 [(parallel [(set (match_dup 0)
10208 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10211 (xor:QI (match_dup 3) (const_int -1)))])]
10214 ;; Arithmetic shift instructions
10216 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10217 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10218 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10219 ;; from the assembler input.
10221 ;; This instruction shifts the target reg/mem as usual, but instead of
10222 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10223 ;; is a left shift double, bits are taken from the high order bits of
10224 ;; reg, else if the insn is a shift right double, bits are taken from the
10225 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10226 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10228 ;; Since sh[lr]d does not change the `reg' operand, that is done
10229 ;; separately, making all shifts emit pairs of shift double and normal
10230 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10231 ;; support a 63 bit shift, each shift where the count is in a reg expands
10232 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10234 ;; If the shift count is a constant, we need never emit more than one
10235 ;; shift pair, instead using moves and sign extension for counts greater
10238 (define_expand "ashlti3"
10239 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10240 (ashift:TI (match_operand:TI 1 "register_operand" "")
10241 (match_operand:QI 2 "nonmemory_operand" "")))
10242 (clobber (reg:CC FLAGS_REG))])]
10245 if (! immediate_operand (operands[2], QImode))
10247 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10250 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10254 (define_insn "ashlti3_1"
10255 [(set (match_operand:TI 0 "register_operand" "=r")
10256 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10257 (match_operand:QI 2 "register_operand" "c")))
10258 (clobber (match_scratch:DI 3 "=&r"))
10259 (clobber (reg:CC FLAGS_REG))]
10262 [(set_attr "type" "multi")])
10264 (define_insn "*ashlti3_2"
10265 [(set (match_operand:TI 0 "register_operand" "=r")
10266 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10267 (match_operand:QI 2 "immediate_operand" "O")))
10268 (clobber (reg:CC FLAGS_REG))]
10271 [(set_attr "type" "multi")])
10274 [(set (match_operand:TI 0 "register_operand" "")
10275 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10276 (match_operand:QI 2 "register_operand" "")))
10277 (clobber (match_scratch:DI 3 ""))
10278 (clobber (reg:CC FLAGS_REG))]
10279 "TARGET_64BIT && reload_completed"
10281 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10284 [(set (match_operand:TI 0 "register_operand" "")
10285 (ashift:TI (match_operand:TI 1 "register_operand" "")
10286 (match_operand:QI 2 "immediate_operand" "")))
10287 (clobber (reg:CC FLAGS_REG))]
10288 "TARGET_64BIT && reload_completed"
10290 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10292 (define_insn "x86_64_shld"
10293 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10294 (ior:DI (ashift:DI (match_dup 0)
10295 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10296 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10297 (minus:QI (const_int 64) (match_dup 2)))))
10298 (clobber (reg:CC FLAGS_REG))]
10301 shld{q}\t{%2, %1, %0|%0, %1, %2}
10302 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10303 [(set_attr "type" "ishift")
10304 (set_attr "prefix_0f" "1")
10305 (set_attr "mode" "DI")
10306 (set_attr "athlon_decode" "vector")])
10308 (define_expand "x86_64_shift_adj"
10309 [(set (reg:CCZ FLAGS_REG)
10310 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10313 (set (match_operand:DI 0 "register_operand" "")
10314 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10315 (match_operand:DI 1 "register_operand" "")
10318 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10319 (match_operand:DI 3 "register_operand" "r")
10324 (define_expand "ashldi3"
10325 [(set (match_operand:DI 0 "shiftdi_operand" "")
10326 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10327 (match_operand:QI 2 "nonmemory_operand" "")))]
10329 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10331 (define_insn "*ashldi3_1_rex64"
10332 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10333 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10334 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10335 (clobber (reg:CC FLAGS_REG))]
10336 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10338 switch (get_attr_type (insn))
10341 gcc_assert (operands[2] == const1_rtx);
10342 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10343 return "add{q}\t{%0, %0|%0, %0}";
10346 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10347 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10348 operands[1] = gen_rtx_MULT (DImode, operands[1],
10349 GEN_INT (1 << INTVAL (operands[2])));
10350 return "lea{q}\t{%a1, %0|%0, %a1}";
10353 if (REG_P (operands[2]))
10354 return "sal{q}\t{%b2, %0|%0, %b2}";
10355 else if (operands[2] == const1_rtx
10356 && (TARGET_SHIFT1 || optimize_size))
10357 return "sal{q}\t%0";
10359 return "sal{q}\t{%2, %0|%0, %2}";
10362 [(set (attr "type")
10363 (cond [(eq_attr "alternative" "1")
10364 (const_string "lea")
10365 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10367 (match_operand 0 "register_operand" ""))
10368 (match_operand 2 "const1_operand" ""))
10369 (const_string "alu")
10371 (const_string "ishift")))
10372 (set_attr "mode" "DI")])
10374 ;; Convert lea to the lea pattern to avoid flags dependency.
10376 [(set (match_operand:DI 0 "register_operand" "")
10377 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10378 (match_operand:QI 2 "immediate_operand" "")))
10379 (clobber (reg:CC FLAGS_REG))]
10380 "TARGET_64BIT && reload_completed
10381 && true_regnum (operands[0]) != true_regnum (operands[1])"
10382 [(set (match_dup 0)
10383 (mult:DI (match_dup 1)
10385 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10387 ;; This pattern can't accept a variable shift count, since shifts by
10388 ;; zero don't affect the flags. We assume that shifts by constant
10389 ;; zero are optimized away.
10390 (define_insn "*ashldi3_cmp_rex64"
10391 [(set (reg FLAGS_REG)
10393 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10394 (match_operand:QI 2 "immediate_operand" "e"))
10396 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10397 (ashift:DI (match_dup 1) (match_dup 2)))]
10398 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10399 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10401 || !TARGET_PARTIAL_FLAG_REG_STALL
10402 || (operands[2] == const1_rtx
10404 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10406 switch (get_attr_type (insn))
10409 gcc_assert (operands[2] == const1_rtx);
10410 return "add{q}\t{%0, %0|%0, %0}";
10413 if (REG_P (operands[2]))
10414 return "sal{q}\t{%b2, %0|%0, %b2}";
10415 else if (operands[2] == const1_rtx
10416 && (TARGET_SHIFT1 || optimize_size))
10417 return "sal{q}\t%0";
10419 return "sal{q}\t{%2, %0|%0, %2}";
10422 [(set (attr "type")
10423 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10425 (match_operand 0 "register_operand" ""))
10426 (match_operand 2 "const1_operand" ""))
10427 (const_string "alu")
10429 (const_string "ishift")))
10430 (set_attr "mode" "DI")])
10432 (define_insn "*ashldi3_cconly_rex64"
10433 [(set (reg FLAGS_REG)
10435 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10436 (match_operand:QI 2 "immediate_operand" "e"))
10438 (clobber (match_scratch:DI 0 "=r"))]
10439 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10440 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10442 || !TARGET_PARTIAL_FLAG_REG_STALL
10443 || (operands[2] == const1_rtx
10445 || TARGET_DOUBLE_WITH_ADD)))"
10447 switch (get_attr_type (insn))
10450 gcc_assert (operands[2] == const1_rtx);
10451 return "add{q}\t{%0, %0|%0, %0}";
10454 if (REG_P (operands[2]))
10455 return "sal{q}\t{%b2, %0|%0, %b2}";
10456 else if (operands[2] == const1_rtx
10457 && (TARGET_SHIFT1 || optimize_size))
10458 return "sal{q}\t%0";
10460 return "sal{q}\t{%2, %0|%0, %2}";
10463 [(set (attr "type")
10464 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10466 (match_operand 0 "register_operand" ""))
10467 (match_operand 2 "const1_operand" ""))
10468 (const_string "alu")
10470 (const_string "ishift")))
10471 (set_attr "mode" "DI")])
10473 (define_insn "*ashldi3_1"
10474 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10475 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10476 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10477 (clobber (reg:CC FLAGS_REG))]
10480 [(set_attr "type" "multi")])
10482 ;; By default we don't ask for a scratch register, because when DImode
10483 ;; values are manipulated, registers are already at a premium. But if
10484 ;; we have one handy, we won't turn it away.
10486 [(match_scratch:SI 3 "r")
10487 (parallel [(set (match_operand:DI 0 "register_operand" "")
10488 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10489 (match_operand:QI 2 "nonmemory_operand" "")))
10490 (clobber (reg:CC FLAGS_REG))])
10492 "!TARGET_64BIT && TARGET_CMOVE"
10494 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10497 [(set (match_operand:DI 0 "register_operand" "")
10498 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10499 (match_operand:QI 2 "nonmemory_operand" "")))
10500 (clobber (reg:CC FLAGS_REG))]
10501 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10502 ? flow2_completed : reload_completed)"
10504 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10506 (define_insn "x86_shld_1"
10507 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10508 (ior:SI (ashift:SI (match_dup 0)
10509 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10510 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10511 (minus:QI (const_int 32) (match_dup 2)))))
10512 (clobber (reg:CC FLAGS_REG))]
10515 shld{l}\t{%2, %1, %0|%0, %1, %2}
10516 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10517 [(set_attr "type" "ishift")
10518 (set_attr "prefix_0f" "1")
10519 (set_attr "mode" "SI")
10520 (set_attr "pent_pair" "np")
10521 (set_attr "athlon_decode" "vector")])
10523 (define_expand "x86_shift_adj_1"
10524 [(set (reg:CCZ FLAGS_REG)
10525 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10528 (set (match_operand:SI 0 "register_operand" "")
10529 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10530 (match_operand:SI 1 "register_operand" "")
10533 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10534 (match_operand:SI 3 "register_operand" "r")
10539 (define_expand "x86_shift_adj_2"
10540 [(use (match_operand:SI 0 "register_operand" ""))
10541 (use (match_operand:SI 1 "register_operand" ""))
10542 (use (match_operand:QI 2 "register_operand" ""))]
10545 rtx label = gen_label_rtx ();
10548 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10550 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10551 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10552 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10553 gen_rtx_LABEL_REF (VOIDmode, label),
10555 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10556 JUMP_LABEL (tmp) = label;
10558 emit_move_insn (operands[0], operands[1]);
10559 ix86_expand_clear (operands[1]);
10561 emit_label (label);
10562 LABEL_NUSES (label) = 1;
10567 (define_expand "ashlsi3"
10568 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10569 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10570 (match_operand:QI 2 "nonmemory_operand" "")))
10571 (clobber (reg:CC FLAGS_REG))]
10573 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10575 (define_insn "*ashlsi3_1"
10576 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10577 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10578 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10579 (clobber (reg:CC FLAGS_REG))]
10580 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10582 switch (get_attr_type (insn))
10585 gcc_assert (operands[2] == const1_rtx);
10586 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10587 return "add{l}\t{%0, %0|%0, %0}";
10593 if (REG_P (operands[2]))
10594 return "sal{l}\t{%b2, %0|%0, %b2}";
10595 else if (operands[2] == const1_rtx
10596 && (TARGET_SHIFT1 || optimize_size))
10597 return "sal{l}\t%0";
10599 return "sal{l}\t{%2, %0|%0, %2}";
10602 [(set (attr "type")
10603 (cond [(eq_attr "alternative" "1")
10604 (const_string "lea")
10605 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10607 (match_operand 0 "register_operand" ""))
10608 (match_operand 2 "const1_operand" ""))
10609 (const_string "alu")
10611 (const_string "ishift")))
10612 (set_attr "mode" "SI")])
10614 ;; Convert lea to the lea pattern to avoid flags dependency.
10616 [(set (match_operand 0 "register_operand" "")
10617 (ashift (match_operand 1 "index_register_operand" "")
10618 (match_operand:QI 2 "const_int_operand" "")))
10619 (clobber (reg:CC FLAGS_REG))]
10621 && true_regnum (operands[0]) != true_regnum (operands[1])
10622 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10626 enum machine_mode mode = GET_MODE (operands[0]);
10628 if (GET_MODE_SIZE (mode) < 4)
10629 operands[0] = gen_lowpart (SImode, operands[0]);
10631 operands[1] = gen_lowpart (Pmode, operands[1]);
10632 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10634 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10635 if (Pmode != SImode)
10636 pat = gen_rtx_SUBREG (SImode, pat, 0);
10637 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10641 ;; Rare case of shifting RSP is handled by generating move and shift
10643 [(set (match_operand 0 "register_operand" "")
10644 (ashift (match_operand 1 "register_operand" "")
10645 (match_operand:QI 2 "const_int_operand" "")))
10646 (clobber (reg:CC FLAGS_REG))]
10648 && true_regnum (operands[0]) != true_regnum (operands[1])"
10652 emit_move_insn (operands[0], operands[1]);
10653 pat = gen_rtx_SET (VOIDmode, operands[0],
10654 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10655 operands[0], operands[2]));
10656 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10657 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10661 (define_insn "*ashlsi3_1_zext"
10662 [(set (match_operand:DI 0 "register_operand" "=r,r")
10663 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10664 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10665 (clobber (reg:CC FLAGS_REG))]
10666 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10668 switch (get_attr_type (insn))
10671 gcc_assert (operands[2] == const1_rtx);
10672 return "add{l}\t{%k0, %k0|%k0, %k0}";
10678 if (REG_P (operands[2]))
10679 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10680 else if (operands[2] == const1_rtx
10681 && (TARGET_SHIFT1 || optimize_size))
10682 return "sal{l}\t%k0";
10684 return "sal{l}\t{%2, %k0|%k0, %2}";
10687 [(set (attr "type")
10688 (cond [(eq_attr "alternative" "1")
10689 (const_string "lea")
10690 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10692 (match_operand 2 "const1_operand" ""))
10693 (const_string "alu")
10695 (const_string "ishift")))
10696 (set_attr "mode" "SI")])
10698 ;; Convert lea to the lea pattern to avoid flags dependency.
10700 [(set (match_operand:DI 0 "register_operand" "")
10701 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10702 (match_operand:QI 2 "const_int_operand" ""))))
10703 (clobber (reg:CC FLAGS_REG))]
10704 "TARGET_64BIT && reload_completed
10705 && true_regnum (operands[0]) != true_regnum (operands[1])"
10706 [(set (match_dup 0) (zero_extend:DI
10707 (subreg:SI (mult:SI (match_dup 1)
10708 (match_dup 2)) 0)))]
10710 operands[1] = gen_lowpart (Pmode, operands[1]);
10711 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10714 ;; This pattern can't accept a variable shift count, since shifts by
10715 ;; zero don't affect the flags. We assume that shifts by constant
10716 ;; zero are optimized away.
10717 (define_insn "*ashlsi3_cmp"
10718 [(set (reg FLAGS_REG)
10720 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10721 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10723 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10724 (ashift:SI (match_dup 1) (match_dup 2)))]
10725 "ix86_match_ccmode (insn, CCGOCmode)
10726 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10728 || !TARGET_PARTIAL_FLAG_REG_STALL
10729 || (operands[2] == const1_rtx
10731 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10733 switch (get_attr_type (insn))
10736 gcc_assert (operands[2] == const1_rtx);
10737 return "add{l}\t{%0, %0|%0, %0}";
10740 if (REG_P (operands[2]))
10741 return "sal{l}\t{%b2, %0|%0, %b2}";
10742 else if (operands[2] == const1_rtx
10743 && (TARGET_SHIFT1 || optimize_size))
10744 return "sal{l}\t%0";
10746 return "sal{l}\t{%2, %0|%0, %2}";
10749 [(set (attr "type")
10750 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10752 (match_operand 0 "register_operand" ""))
10753 (match_operand 2 "const1_operand" ""))
10754 (const_string "alu")
10756 (const_string "ishift")))
10757 (set_attr "mode" "SI")])
10759 (define_insn "*ashlsi3_cconly"
10760 [(set (reg FLAGS_REG)
10762 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10763 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10765 (clobber (match_scratch:SI 0 "=r"))]
10766 "ix86_match_ccmode (insn, CCGOCmode)
10767 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10769 || !TARGET_PARTIAL_FLAG_REG_STALL
10770 || (operands[2] == const1_rtx
10772 || TARGET_DOUBLE_WITH_ADD)))"
10774 switch (get_attr_type (insn))
10777 gcc_assert (operands[2] == const1_rtx);
10778 return "add{l}\t{%0, %0|%0, %0}";
10781 if (REG_P (operands[2]))
10782 return "sal{l}\t{%b2, %0|%0, %b2}";
10783 else if (operands[2] == const1_rtx
10784 && (TARGET_SHIFT1 || optimize_size))
10785 return "sal{l}\t%0";
10787 return "sal{l}\t{%2, %0|%0, %2}";
10790 [(set (attr "type")
10791 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10793 (match_operand 0 "register_operand" ""))
10794 (match_operand 2 "const1_operand" ""))
10795 (const_string "alu")
10797 (const_string "ishift")))
10798 (set_attr "mode" "SI")])
10800 (define_insn "*ashlsi3_cmp_zext"
10801 [(set (reg FLAGS_REG)
10803 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10804 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10806 (set (match_operand:DI 0 "register_operand" "=r")
10807 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10808 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10809 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10811 || !TARGET_PARTIAL_FLAG_REG_STALL
10812 || (operands[2] == const1_rtx
10814 || TARGET_DOUBLE_WITH_ADD)))"
10816 switch (get_attr_type (insn))
10819 gcc_assert (operands[2] == const1_rtx);
10820 return "add{l}\t{%k0, %k0|%k0, %k0}";
10823 if (REG_P (operands[2]))
10824 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10825 else if (operands[2] == const1_rtx
10826 && (TARGET_SHIFT1 || optimize_size))
10827 return "sal{l}\t%k0";
10829 return "sal{l}\t{%2, %k0|%k0, %2}";
10832 [(set (attr "type")
10833 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10835 (match_operand 2 "const1_operand" ""))
10836 (const_string "alu")
10838 (const_string "ishift")))
10839 (set_attr "mode" "SI")])
10841 (define_expand "ashlhi3"
10842 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10843 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10844 (match_operand:QI 2 "nonmemory_operand" "")))
10845 (clobber (reg:CC FLAGS_REG))]
10846 "TARGET_HIMODE_MATH"
10847 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10849 (define_insn "*ashlhi3_1_lea"
10850 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10851 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10852 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10853 (clobber (reg:CC FLAGS_REG))]
10854 "!TARGET_PARTIAL_REG_STALL
10855 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10857 switch (get_attr_type (insn))
10862 gcc_assert (operands[2] == const1_rtx);
10863 return "add{w}\t{%0, %0|%0, %0}";
10866 if (REG_P (operands[2]))
10867 return "sal{w}\t{%b2, %0|%0, %b2}";
10868 else if (operands[2] == const1_rtx
10869 && (TARGET_SHIFT1 || optimize_size))
10870 return "sal{w}\t%0";
10872 return "sal{w}\t{%2, %0|%0, %2}";
10875 [(set (attr "type")
10876 (cond [(eq_attr "alternative" "1")
10877 (const_string "lea")
10878 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10880 (match_operand 0 "register_operand" ""))
10881 (match_operand 2 "const1_operand" ""))
10882 (const_string "alu")
10884 (const_string "ishift")))
10885 (set_attr "mode" "HI,SI")])
10887 (define_insn "*ashlhi3_1"
10888 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10889 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10890 (match_operand:QI 2 "nonmemory_operand" "cI")))
10891 (clobber (reg:CC FLAGS_REG))]
10892 "TARGET_PARTIAL_REG_STALL
10893 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10895 switch (get_attr_type (insn))
10898 gcc_assert (operands[2] == const1_rtx);
10899 return "add{w}\t{%0, %0|%0, %0}";
10902 if (REG_P (operands[2]))
10903 return "sal{w}\t{%b2, %0|%0, %b2}";
10904 else if (operands[2] == const1_rtx
10905 && (TARGET_SHIFT1 || optimize_size))
10906 return "sal{w}\t%0";
10908 return "sal{w}\t{%2, %0|%0, %2}";
10911 [(set (attr "type")
10912 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10914 (match_operand 0 "register_operand" ""))
10915 (match_operand 2 "const1_operand" ""))
10916 (const_string "alu")
10918 (const_string "ishift")))
10919 (set_attr "mode" "HI")])
10921 ;; This pattern can't accept a variable shift count, since shifts by
10922 ;; zero don't affect the flags. We assume that shifts by constant
10923 ;; zero are optimized away.
10924 (define_insn "*ashlhi3_cmp"
10925 [(set (reg FLAGS_REG)
10927 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10928 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10930 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10931 (ashift:HI (match_dup 1) (match_dup 2)))]
10932 "ix86_match_ccmode (insn, CCGOCmode)
10933 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10935 || !TARGET_PARTIAL_FLAG_REG_STALL
10936 || (operands[2] == const1_rtx
10938 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10940 switch (get_attr_type (insn))
10943 gcc_assert (operands[2] == const1_rtx);
10944 return "add{w}\t{%0, %0|%0, %0}";
10947 if (REG_P (operands[2]))
10948 return "sal{w}\t{%b2, %0|%0, %b2}";
10949 else if (operands[2] == const1_rtx
10950 && (TARGET_SHIFT1 || optimize_size))
10951 return "sal{w}\t%0";
10953 return "sal{w}\t{%2, %0|%0, %2}";
10956 [(set (attr "type")
10957 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10959 (match_operand 0 "register_operand" ""))
10960 (match_operand 2 "const1_operand" ""))
10961 (const_string "alu")
10963 (const_string "ishift")))
10964 (set_attr "mode" "HI")])
10966 (define_insn "*ashlhi3_cconly"
10967 [(set (reg FLAGS_REG)
10969 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10970 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10972 (clobber (match_scratch:HI 0 "=r"))]
10973 "ix86_match_ccmode (insn, CCGOCmode)
10974 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10976 || !TARGET_PARTIAL_FLAG_REG_STALL
10977 || (operands[2] == const1_rtx
10979 || TARGET_DOUBLE_WITH_ADD)))"
10981 switch (get_attr_type (insn))
10984 gcc_assert (operands[2] == const1_rtx);
10985 return "add{w}\t{%0, %0|%0, %0}";
10988 if (REG_P (operands[2]))
10989 return "sal{w}\t{%b2, %0|%0, %b2}";
10990 else if (operands[2] == const1_rtx
10991 && (TARGET_SHIFT1 || optimize_size))
10992 return "sal{w}\t%0";
10994 return "sal{w}\t{%2, %0|%0, %2}";
10997 [(set (attr "type")
10998 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11000 (match_operand 0 "register_operand" ""))
11001 (match_operand 2 "const1_operand" ""))
11002 (const_string "alu")
11004 (const_string "ishift")))
11005 (set_attr "mode" "HI")])
11007 (define_expand "ashlqi3"
11008 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11009 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11010 (match_operand:QI 2 "nonmemory_operand" "")))
11011 (clobber (reg:CC FLAGS_REG))]
11012 "TARGET_QIMODE_MATH"
11013 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11015 ;; %%% Potential partial reg stall on alternative 2. What to do?
11017 (define_insn "*ashlqi3_1_lea"
11018 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11019 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11020 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11021 (clobber (reg:CC FLAGS_REG))]
11022 "!TARGET_PARTIAL_REG_STALL
11023 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11025 switch (get_attr_type (insn))
11030 gcc_assert (operands[2] == const1_rtx);
11031 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11032 return "add{l}\t{%k0, %k0|%k0, %k0}";
11034 return "add{b}\t{%0, %0|%0, %0}";
11037 if (REG_P (operands[2]))
11039 if (get_attr_mode (insn) == MODE_SI)
11040 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11042 return "sal{b}\t{%b2, %0|%0, %b2}";
11044 else if (operands[2] == const1_rtx
11045 && (TARGET_SHIFT1 || optimize_size))
11047 if (get_attr_mode (insn) == MODE_SI)
11048 return "sal{l}\t%0";
11050 return "sal{b}\t%0";
11054 if (get_attr_mode (insn) == MODE_SI)
11055 return "sal{l}\t{%2, %k0|%k0, %2}";
11057 return "sal{b}\t{%2, %0|%0, %2}";
11061 [(set (attr "type")
11062 (cond [(eq_attr "alternative" "2")
11063 (const_string "lea")
11064 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11066 (match_operand 0 "register_operand" ""))
11067 (match_operand 2 "const1_operand" ""))
11068 (const_string "alu")
11070 (const_string "ishift")))
11071 (set_attr "mode" "QI,SI,SI")])
11073 (define_insn "*ashlqi3_1"
11074 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11075 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11076 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11077 (clobber (reg:CC FLAGS_REG))]
11078 "TARGET_PARTIAL_REG_STALL
11079 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11081 switch (get_attr_type (insn))
11084 gcc_assert (operands[2] == const1_rtx);
11085 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11086 return "add{l}\t{%k0, %k0|%k0, %k0}";
11088 return "add{b}\t{%0, %0|%0, %0}";
11091 if (REG_P (operands[2]))
11093 if (get_attr_mode (insn) == MODE_SI)
11094 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11096 return "sal{b}\t{%b2, %0|%0, %b2}";
11098 else if (operands[2] == const1_rtx
11099 && (TARGET_SHIFT1 || optimize_size))
11101 if (get_attr_mode (insn) == MODE_SI)
11102 return "sal{l}\t%0";
11104 return "sal{b}\t%0";
11108 if (get_attr_mode (insn) == MODE_SI)
11109 return "sal{l}\t{%2, %k0|%k0, %2}";
11111 return "sal{b}\t{%2, %0|%0, %2}";
11115 [(set (attr "type")
11116 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11118 (match_operand 0 "register_operand" ""))
11119 (match_operand 2 "const1_operand" ""))
11120 (const_string "alu")
11122 (const_string "ishift")))
11123 (set_attr "mode" "QI,SI")])
11125 ;; This pattern can't accept a variable shift count, since shifts by
11126 ;; zero don't affect the flags. We assume that shifts by constant
11127 ;; zero are optimized away.
11128 (define_insn "*ashlqi3_cmp"
11129 [(set (reg FLAGS_REG)
11131 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11132 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11134 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11135 (ashift:QI (match_dup 1) (match_dup 2)))]
11136 "ix86_match_ccmode (insn, CCGOCmode)
11137 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11139 || !TARGET_PARTIAL_FLAG_REG_STALL
11140 || (operands[2] == const1_rtx
11142 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11144 switch (get_attr_type (insn))
11147 gcc_assert (operands[2] == const1_rtx);
11148 return "add{b}\t{%0, %0|%0, %0}";
11151 if (REG_P (operands[2]))
11152 return "sal{b}\t{%b2, %0|%0, %b2}";
11153 else if (operands[2] == const1_rtx
11154 && (TARGET_SHIFT1 || optimize_size))
11155 return "sal{b}\t%0";
11157 return "sal{b}\t{%2, %0|%0, %2}";
11160 [(set (attr "type")
11161 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11163 (match_operand 0 "register_operand" ""))
11164 (match_operand 2 "const1_operand" ""))
11165 (const_string "alu")
11167 (const_string "ishift")))
11168 (set_attr "mode" "QI")])
11170 (define_insn "*ashlqi3_cconly"
11171 [(set (reg FLAGS_REG)
11173 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11174 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11176 (clobber (match_scratch:QI 0 "=q"))]
11177 "ix86_match_ccmode (insn, CCGOCmode)
11178 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11180 || !TARGET_PARTIAL_FLAG_REG_STALL
11181 || (operands[2] == const1_rtx
11183 || TARGET_DOUBLE_WITH_ADD)))"
11185 switch (get_attr_type (insn))
11188 gcc_assert (operands[2] == const1_rtx);
11189 return "add{b}\t{%0, %0|%0, %0}";
11192 if (REG_P (operands[2]))
11193 return "sal{b}\t{%b2, %0|%0, %b2}";
11194 else if (operands[2] == const1_rtx
11195 && (TARGET_SHIFT1 || optimize_size))
11196 return "sal{b}\t%0";
11198 return "sal{b}\t{%2, %0|%0, %2}";
11201 [(set (attr "type")
11202 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11204 (match_operand 0 "register_operand" ""))
11205 (match_operand 2 "const1_operand" ""))
11206 (const_string "alu")
11208 (const_string "ishift")))
11209 (set_attr "mode" "QI")])
11211 ;; See comment above `ashldi3' about how this works.
11213 (define_expand "ashrti3"
11214 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11215 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11216 (match_operand:QI 2 "nonmemory_operand" "")))
11217 (clobber (reg:CC FLAGS_REG))])]
11220 if (! immediate_operand (operands[2], QImode))
11222 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11225 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11229 (define_insn "ashrti3_1"
11230 [(set (match_operand:TI 0 "register_operand" "=r")
11231 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11232 (match_operand:QI 2 "register_operand" "c")))
11233 (clobber (match_scratch:DI 3 "=&r"))
11234 (clobber (reg:CC FLAGS_REG))]
11237 [(set_attr "type" "multi")])
11239 (define_insn "*ashrti3_2"
11240 [(set (match_operand:TI 0 "register_operand" "=r")
11241 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11242 (match_operand:QI 2 "immediate_operand" "O")))
11243 (clobber (reg:CC FLAGS_REG))]
11246 [(set_attr "type" "multi")])
11249 [(set (match_operand:TI 0 "register_operand" "")
11250 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11251 (match_operand:QI 2 "register_operand" "")))
11252 (clobber (match_scratch:DI 3 ""))
11253 (clobber (reg:CC FLAGS_REG))]
11254 "TARGET_64BIT && reload_completed"
11256 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11259 [(set (match_operand:TI 0 "register_operand" "")
11260 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11261 (match_operand:QI 2 "immediate_operand" "")))
11262 (clobber (reg:CC FLAGS_REG))]
11263 "TARGET_64BIT && reload_completed"
11265 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11267 (define_insn "x86_64_shrd"
11268 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11269 (ior:DI (ashiftrt:DI (match_dup 0)
11270 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11271 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11272 (minus:QI (const_int 64) (match_dup 2)))))
11273 (clobber (reg:CC FLAGS_REG))]
11276 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11277 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11278 [(set_attr "type" "ishift")
11279 (set_attr "prefix_0f" "1")
11280 (set_attr "mode" "DI")
11281 (set_attr "athlon_decode" "vector")])
11283 (define_expand "ashrdi3"
11284 [(set (match_operand:DI 0 "shiftdi_operand" "")
11285 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11286 (match_operand:QI 2 "nonmemory_operand" "")))]
11288 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11290 (define_insn "*ashrdi3_63_rex64"
11291 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11292 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11293 (match_operand:DI 2 "const_int_operand" "i,i")))
11294 (clobber (reg:CC FLAGS_REG))]
11295 "TARGET_64BIT && INTVAL (operands[2]) == 63
11296 && (TARGET_USE_CLTD || optimize_size)
11297 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11300 sar{q}\t{%2, %0|%0, %2}"
11301 [(set_attr "type" "imovx,ishift")
11302 (set_attr "prefix_0f" "0,*")
11303 (set_attr "length_immediate" "0,*")
11304 (set_attr "modrm" "0,1")
11305 (set_attr "mode" "DI")])
11307 (define_insn "*ashrdi3_1_one_bit_rex64"
11308 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11309 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11310 (match_operand:QI 2 "const1_operand" "")))
11311 (clobber (reg:CC FLAGS_REG))]
11312 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11313 && (TARGET_SHIFT1 || optimize_size)"
11315 [(set_attr "type" "ishift")
11316 (set (attr "length")
11317 (if_then_else (match_operand:DI 0 "register_operand" "")
11319 (const_string "*")))])
11321 (define_insn "*ashrdi3_1_rex64"
11322 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11323 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11324 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11325 (clobber (reg:CC FLAGS_REG))]
11326 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11328 sar{q}\t{%2, %0|%0, %2}
11329 sar{q}\t{%b2, %0|%0, %b2}"
11330 [(set_attr "type" "ishift")
11331 (set_attr "mode" "DI")])
11333 ;; This pattern can't accept a variable shift count, since shifts by
11334 ;; zero don't affect the flags. We assume that shifts by constant
11335 ;; zero are optimized away.
11336 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11337 [(set (reg FLAGS_REG)
11339 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11340 (match_operand:QI 2 "const1_operand" ""))
11342 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11343 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11344 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11345 && (TARGET_SHIFT1 || optimize_size)
11346 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11348 [(set_attr "type" "ishift")
11349 (set (attr "length")
11350 (if_then_else (match_operand:DI 0 "register_operand" "")
11352 (const_string "*")))])
11354 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11355 [(set (reg FLAGS_REG)
11357 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11358 (match_operand:QI 2 "const1_operand" ""))
11360 (clobber (match_scratch:DI 0 "=r"))]
11361 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11362 && (TARGET_SHIFT1 || optimize_size)
11363 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11365 [(set_attr "type" "ishift")
11366 (set_attr "length" "2")])
11368 ;; This pattern can't accept a variable shift count, since shifts by
11369 ;; zero don't affect the flags. We assume that shifts by constant
11370 ;; zero are optimized away.
11371 (define_insn "*ashrdi3_cmp_rex64"
11372 [(set (reg FLAGS_REG)
11374 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11375 (match_operand:QI 2 "const_int_operand" "n"))
11377 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11378 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11379 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11380 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11382 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11383 "sar{q}\t{%2, %0|%0, %2}"
11384 [(set_attr "type" "ishift")
11385 (set_attr "mode" "DI")])
11387 (define_insn "*ashrdi3_cconly_rex64"
11388 [(set (reg FLAGS_REG)
11390 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11391 (match_operand:QI 2 "const_int_operand" "n"))
11393 (clobber (match_scratch:DI 0 "=r"))]
11394 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11395 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11397 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11398 "sar{q}\t{%2, %0|%0, %2}"
11399 [(set_attr "type" "ishift")
11400 (set_attr "mode" "DI")])
11402 (define_insn "*ashrdi3_1"
11403 [(set (match_operand:DI 0 "register_operand" "=r")
11404 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11405 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11406 (clobber (reg:CC FLAGS_REG))]
11409 [(set_attr "type" "multi")])
11411 ;; By default we don't ask for a scratch register, because when DImode
11412 ;; values are manipulated, registers are already at a premium. But if
11413 ;; we have one handy, we won't turn it away.
11415 [(match_scratch:SI 3 "r")
11416 (parallel [(set (match_operand:DI 0 "register_operand" "")
11417 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11418 (match_operand:QI 2 "nonmemory_operand" "")))
11419 (clobber (reg:CC FLAGS_REG))])
11421 "!TARGET_64BIT && TARGET_CMOVE"
11423 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11426 [(set (match_operand:DI 0 "register_operand" "")
11427 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11428 (match_operand:QI 2 "nonmemory_operand" "")))
11429 (clobber (reg:CC FLAGS_REG))]
11430 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11431 ? flow2_completed : reload_completed)"
11433 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11435 (define_insn "x86_shrd_1"
11436 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11437 (ior:SI (ashiftrt:SI (match_dup 0)
11438 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11439 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11440 (minus:QI (const_int 32) (match_dup 2)))))
11441 (clobber (reg:CC FLAGS_REG))]
11444 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11445 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11446 [(set_attr "type" "ishift")
11447 (set_attr "prefix_0f" "1")
11448 (set_attr "pent_pair" "np")
11449 (set_attr "mode" "SI")])
11451 (define_expand "x86_shift_adj_3"
11452 [(use (match_operand:SI 0 "register_operand" ""))
11453 (use (match_operand:SI 1 "register_operand" ""))
11454 (use (match_operand:QI 2 "register_operand" ""))]
11457 rtx label = gen_label_rtx ();
11460 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11462 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11463 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11464 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11465 gen_rtx_LABEL_REF (VOIDmode, label),
11467 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11468 JUMP_LABEL (tmp) = label;
11470 emit_move_insn (operands[0], operands[1]);
11471 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11473 emit_label (label);
11474 LABEL_NUSES (label) = 1;
11479 (define_insn "ashrsi3_31"
11480 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11481 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11482 (match_operand:SI 2 "const_int_operand" "i,i")))
11483 (clobber (reg:CC FLAGS_REG))]
11484 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11485 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11488 sar{l}\t{%2, %0|%0, %2}"
11489 [(set_attr "type" "imovx,ishift")
11490 (set_attr "prefix_0f" "0,*")
11491 (set_attr "length_immediate" "0,*")
11492 (set_attr "modrm" "0,1")
11493 (set_attr "mode" "SI")])
11495 (define_insn "*ashrsi3_31_zext"
11496 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11497 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11498 (match_operand:SI 2 "const_int_operand" "i,i"))))
11499 (clobber (reg:CC FLAGS_REG))]
11500 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11501 && INTVAL (operands[2]) == 31
11502 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11505 sar{l}\t{%2, %k0|%k0, %2}"
11506 [(set_attr "type" "imovx,ishift")
11507 (set_attr "prefix_0f" "0,*")
11508 (set_attr "length_immediate" "0,*")
11509 (set_attr "modrm" "0,1")
11510 (set_attr "mode" "SI")])
11512 (define_expand "ashrsi3"
11513 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11514 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11515 (match_operand:QI 2 "nonmemory_operand" "")))
11516 (clobber (reg:CC FLAGS_REG))]
11518 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11520 (define_insn "*ashrsi3_1_one_bit"
11521 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11522 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11523 (match_operand:QI 2 "const1_operand" "")))
11524 (clobber (reg:CC FLAGS_REG))]
11525 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11526 && (TARGET_SHIFT1 || optimize_size)"
11528 [(set_attr "type" "ishift")
11529 (set (attr "length")
11530 (if_then_else (match_operand:SI 0 "register_operand" "")
11532 (const_string "*")))])
11534 (define_insn "*ashrsi3_1_one_bit_zext"
11535 [(set (match_operand:DI 0 "register_operand" "=r")
11536 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11537 (match_operand:QI 2 "const1_operand" ""))))
11538 (clobber (reg:CC FLAGS_REG))]
11539 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11540 && (TARGET_SHIFT1 || optimize_size)"
11542 [(set_attr "type" "ishift")
11543 (set_attr "length" "2")])
11545 (define_insn "*ashrsi3_1"
11546 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11547 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11548 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11549 (clobber (reg:CC FLAGS_REG))]
11550 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11552 sar{l}\t{%2, %0|%0, %2}
11553 sar{l}\t{%b2, %0|%0, %b2}"
11554 [(set_attr "type" "ishift")
11555 (set_attr "mode" "SI")])
11557 (define_insn "*ashrsi3_1_zext"
11558 [(set (match_operand:DI 0 "register_operand" "=r,r")
11559 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11560 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11561 (clobber (reg:CC FLAGS_REG))]
11562 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11564 sar{l}\t{%2, %k0|%k0, %2}
11565 sar{l}\t{%b2, %k0|%k0, %b2}"
11566 [(set_attr "type" "ishift")
11567 (set_attr "mode" "SI")])
11569 ;; This pattern can't accept a variable shift count, since shifts by
11570 ;; zero don't affect the flags. We assume that shifts by constant
11571 ;; zero are optimized away.
11572 (define_insn "*ashrsi3_one_bit_cmp"
11573 [(set (reg FLAGS_REG)
11575 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11576 (match_operand:QI 2 "const1_operand" ""))
11578 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11579 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11580 "ix86_match_ccmode (insn, CCGOCmode)
11581 && (TARGET_SHIFT1 || optimize_size)
11582 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11584 [(set_attr "type" "ishift")
11585 (set (attr "length")
11586 (if_then_else (match_operand:SI 0 "register_operand" "")
11588 (const_string "*")))])
11590 (define_insn "*ashrsi3_one_bit_cconly"
11591 [(set (reg FLAGS_REG)
11593 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11594 (match_operand:QI 2 "const1_operand" ""))
11596 (clobber (match_scratch:SI 0 "=r"))]
11597 "ix86_match_ccmode (insn, CCGOCmode)
11598 && (TARGET_SHIFT1 || optimize_size)
11599 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11601 [(set_attr "type" "ishift")
11602 (set_attr "length" "2")])
11604 (define_insn "*ashrsi3_one_bit_cmp_zext"
11605 [(set (reg FLAGS_REG)
11607 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11608 (match_operand:QI 2 "const1_operand" ""))
11610 (set (match_operand:DI 0 "register_operand" "=r")
11611 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11612 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11613 && (TARGET_SHIFT1 || optimize_size)
11614 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11616 [(set_attr "type" "ishift")
11617 (set_attr "length" "2")])
11619 ;; This pattern can't accept a variable shift count, since shifts by
11620 ;; zero don't affect the flags. We assume that shifts by constant
11621 ;; zero are optimized away.
11622 (define_insn "*ashrsi3_cmp"
11623 [(set (reg FLAGS_REG)
11625 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11626 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11628 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11629 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11630 "ix86_match_ccmode (insn, CCGOCmode)
11631 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11633 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11634 "sar{l}\t{%2, %0|%0, %2}"
11635 [(set_attr "type" "ishift")
11636 (set_attr "mode" "SI")])
11638 (define_insn "*ashrsi3_cconly"
11639 [(set (reg FLAGS_REG)
11641 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11642 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11644 (clobber (match_scratch:SI 0 "=r"))]
11645 "ix86_match_ccmode (insn, CCGOCmode)
11646 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11648 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11649 "sar{l}\t{%2, %0|%0, %2}"
11650 [(set_attr "type" "ishift")
11651 (set_attr "mode" "SI")])
11653 (define_insn "*ashrsi3_cmp_zext"
11654 [(set (reg FLAGS_REG)
11656 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11657 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11659 (set (match_operand:DI 0 "register_operand" "=r")
11660 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11661 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11662 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11664 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11665 "sar{l}\t{%2, %k0|%k0, %2}"
11666 [(set_attr "type" "ishift")
11667 (set_attr "mode" "SI")])
11669 (define_expand "ashrhi3"
11670 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11671 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11672 (match_operand:QI 2 "nonmemory_operand" "")))
11673 (clobber (reg:CC FLAGS_REG))]
11674 "TARGET_HIMODE_MATH"
11675 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11677 (define_insn "*ashrhi3_1_one_bit"
11678 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11679 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11680 (match_operand:QI 2 "const1_operand" "")))
11681 (clobber (reg:CC FLAGS_REG))]
11682 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11683 && (TARGET_SHIFT1 || optimize_size)"
11685 [(set_attr "type" "ishift")
11686 (set (attr "length")
11687 (if_then_else (match_operand 0 "register_operand" "")
11689 (const_string "*")))])
11691 (define_insn "*ashrhi3_1"
11692 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11693 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11694 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11695 (clobber (reg:CC FLAGS_REG))]
11696 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11698 sar{w}\t{%2, %0|%0, %2}
11699 sar{w}\t{%b2, %0|%0, %b2}"
11700 [(set_attr "type" "ishift")
11701 (set_attr "mode" "HI")])
11703 ;; This pattern can't accept a variable shift count, since shifts by
11704 ;; zero don't affect the flags. We assume that shifts by constant
11705 ;; zero are optimized away.
11706 (define_insn "*ashrhi3_one_bit_cmp"
11707 [(set (reg FLAGS_REG)
11709 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11710 (match_operand:QI 2 "const1_operand" ""))
11712 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11713 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11714 "ix86_match_ccmode (insn, CCGOCmode)
11715 && (TARGET_SHIFT1 || optimize_size)
11716 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11718 [(set_attr "type" "ishift")
11719 (set (attr "length")
11720 (if_then_else (match_operand 0 "register_operand" "")
11722 (const_string "*")))])
11724 (define_insn "*ashrhi3_one_bit_cconly"
11725 [(set (reg FLAGS_REG)
11727 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11728 (match_operand:QI 2 "const1_operand" ""))
11730 (clobber (match_scratch:HI 0 "=r"))]
11731 "ix86_match_ccmode (insn, CCGOCmode)
11732 && (TARGET_SHIFT1 || optimize_size)
11733 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11735 [(set_attr "type" "ishift")
11736 (set_attr "length" "2")])
11738 ;; This pattern can't accept a variable shift count, since shifts by
11739 ;; zero don't affect the flags. We assume that shifts by constant
11740 ;; zero are optimized away.
11741 (define_insn "*ashrhi3_cmp"
11742 [(set (reg FLAGS_REG)
11744 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11745 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11747 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11748 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11749 "ix86_match_ccmode (insn, CCGOCmode)
11750 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11752 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11753 "sar{w}\t{%2, %0|%0, %2}"
11754 [(set_attr "type" "ishift")
11755 (set_attr "mode" "HI")])
11757 (define_insn "*ashrhi3_cconly"
11758 [(set (reg FLAGS_REG)
11760 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11761 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11763 (clobber (match_scratch:HI 0 "=r"))]
11764 "ix86_match_ccmode (insn, CCGOCmode)
11765 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11767 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11768 "sar{w}\t{%2, %0|%0, %2}"
11769 [(set_attr "type" "ishift")
11770 (set_attr "mode" "HI")])
11772 (define_expand "ashrqi3"
11773 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11774 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11775 (match_operand:QI 2 "nonmemory_operand" "")))
11776 (clobber (reg:CC FLAGS_REG))]
11777 "TARGET_QIMODE_MATH"
11778 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11780 (define_insn "*ashrqi3_1_one_bit"
11781 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11782 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11783 (match_operand:QI 2 "const1_operand" "")))
11784 (clobber (reg:CC FLAGS_REG))]
11785 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11786 && (TARGET_SHIFT1 || optimize_size)"
11788 [(set_attr "type" "ishift")
11789 (set (attr "length")
11790 (if_then_else (match_operand 0 "register_operand" "")
11792 (const_string "*")))])
11794 (define_insn "*ashrqi3_1_one_bit_slp"
11795 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11796 (ashiftrt:QI (match_dup 0)
11797 (match_operand:QI 1 "const1_operand" "")))
11798 (clobber (reg:CC FLAGS_REG))]
11799 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11800 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11801 && (TARGET_SHIFT1 || optimize_size)"
11803 [(set_attr "type" "ishift1")
11804 (set (attr "length")
11805 (if_then_else (match_operand 0 "register_operand" "")
11807 (const_string "*")))])
11809 (define_insn "*ashrqi3_1"
11810 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11811 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11812 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11813 (clobber (reg:CC FLAGS_REG))]
11814 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11816 sar{b}\t{%2, %0|%0, %2}
11817 sar{b}\t{%b2, %0|%0, %b2}"
11818 [(set_attr "type" "ishift")
11819 (set_attr "mode" "QI")])
11821 (define_insn "*ashrqi3_1_slp"
11822 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11823 (ashiftrt:QI (match_dup 0)
11824 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11825 (clobber (reg:CC FLAGS_REG))]
11826 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11827 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11829 sar{b}\t{%1, %0|%0, %1}
11830 sar{b}\t{%b1, %0|%0, %b1}"
11831 [(set_attr "type" "ishift1")
11832 (set_attr "mode" "QI")])
11834 ;; This pattern can't accept a variable shift count, since shifts by
11835 ;; zero don't affect the flags. We assume that shifts by constant
11836 ;; zero are optimized away.
11837 (define_insn "*ashrqi3_one_bit_cmp"
11838 [(set (reg FLAGS_REG)
11840 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11841 (match_operand:QI 2 "const1_operand" "I"))
11843 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11844 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11845 "ix86_match_ccmode (insn, CCGOCmode)
11846 && (TARGET_SHIFT1 || optimize_size)
11847 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11849 [(set_attr "type" "ishift")
11850 (set (attr "length")
11851 (if_then_else (match_operand 0 "register_operand" "")
11853 (const_string "*")))])
11855 (define_insn "*ashrqi3_one_bit_cconly"
11856 [(set (reg FLAGS_REG)
11858 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11859 (match_operand:QI 2 "const1_operand" "I"))
11861 (clobber (match_scratch:QI 0 "=q"))]
11862 "ix86_match_ccmode (insn, CCGOCmode)
11863 && (TARGET_SHIFT1 || optimize_size)
11864 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11866 [(set_attr "type" "ishift")
11867 (set_attr "length" "2")])
11869 ;; This pattern can't accept a variable shift count, since shifts by
11870 ;; zero don't affect the flags. We assume that shifts by constant
11871 ;; zero are optimized away.
11872 (define_insn "*ashrqi3_cmp"
11873 [(set (reg FLAGS_REG)
11875 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11876 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11878 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11879 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11880 "ix86_match_ccmode (insn, CCGOCmode)
11881 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11883 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11884 "sar{b}\t{%2, %0|%0, %2}"
11885 [(set_attr "type" "ishift")
11886 (set_attr "mode" "QI")])
11888 (define_insn "*ashrqi3_cconly"
11889 [(set (reg FLAGS_REG)
11891 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11892 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11894 (clobber (match_scratch:QI 0 "=q"))]
11895 "ix86_match_ccmode (insn, CCGOCmode)
11896 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11898 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11899 "sar{b}\t{%2, %0|%0, %2}"
11900 [(set_attr "type" "ishift")
11901 (set_attr "mode" "QI")])
11904 ;; Logical shift instructions
11906 ;; See comment above `ashldi3' about how this works.
11908 (define_expand "lshrti3"
11909 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11910 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11911 (match_operand:QI 2 "nonmemory_operand" "")))
11912 (clobber (reg:CC FLAGS_REG))])]
11915 if (! immediate_operand (operands[2], QImode))
11917 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11920 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11924 (define_insn "lshrti3_1"
11925 [(set (match_operand:TI 0 "register_operand" "=r")
11926 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11927 (match_operand:QI 2 "register_operand" "c")))
11928 (clobber (match_scratch:DI 3 "=&r"))
11929 (clobber (reg:CC FLAGS_REG))]
11932 [(set_attr "type" "multi")])
11934 (define_insn "*lshrti3_2"
11935 [(set (match_operand:TI 0 "register_operand" "=r")
11936 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11937 (match_operand:QI 2 "immediate_operand" "O")))
11938 (clobber (reg:CC FLAGS_REG))]
11941 [(set_attr "type" "multi")])
11944 [(set (match_operand:TI 0 "register_operand" "")
11945 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11946 (match_operand:QI 2 "register_operand" "")))
11947 (clobber (match_scratch:DI 3 ""))
11948 (clobber (reg:CC FLAGS_REG))]
11949 "TARGET_64BIT && reload_completed"
11951 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11954 [(set (match_operand:TI 0 "register_operand" "")
11955 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11956 (match_operand:QI 2 "immediate_operand" "")))
11957 (clobber (reg:CC FLAGS_REG))]
11958 "TARGET_64BIT && reload_completed"
11960 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11962 (define_expand "lshrdi3"
11963 [(set (match_operand:DI 0 "shiftdi_operand" "")
11964 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11965 (match_operand:QI 2 "nonmemory_operand" "")))]
11967 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11969 (define_insn "*lshrdi3_1_one_bit_rex64"
11970 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11971 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11972 (match_operand:QI 2 "const1_operand" "")))
11973 (clobber (reg:CC FLAGS_REG))]
11974 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
11975 && (TARGET_SHIFT1 || optimize_size)"
11977 [(set_attr "type" "ishift")
11978 (set (attr "length")
11979 (if_then_else (match_operand:DI 0 "register_operand" "")
11981 (const_string "*")))])
11983 (define_insn "*lshrdi3_1_rex64"
11984 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11985 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11986 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11987 (clobber (reg:CC FLAGS_REG))]
11988 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11990 shr{q}\t{%2, %0|%0, %2}
11991 shr{q}\t{%b2, %0|%0, %b2}"
11992 [(set_attr "type" "ishift")
11993 (set_attr "mode" "DI")])
11995 ;; This pattern can't accept a variable shift count, since shifts by
11996 ;; zero don't affect the flags. We assume that shifts by constant
11997 ;; zero are optimized away.
11998 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11999 [(set (reg FLAGS_REG)
12001 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12002 (match_operand:QI 2 "const1_operand" ""))
12004 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12005 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12006 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12007 && (TARGET_SHIFT1 || optimize_size)
12008 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12010 [(set_attr "type" "ishift")
12011 (set (attr "length")
12012 (if_then_else (match_operand:DI 0 "register_operand" "")
12014 (const_string "*")))])
12016 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12017 [(set (reg FLAGS_REG)
12019 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12020 (match_operand:QI 2 "const1_operand" ""))
12022 (clobber (match_scratch:DI 0 "=r"))]
12023 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12024 && (TARGET_SHIFT1 || optimize_size)
12025 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12027 [(set_attr "type" "ishift")
12028 (set_attr "length" "2")])
12030 ;; This pattern can't accept a variable shift count, since shifts by
12031 ;; zero don't affect the flags. We assume that shifts by constant
12032 ;; zero are optimized away.
12033 (define_insn "*lshrdi3_cmp_rex64"
12034 [(set (reg FLAGS_REG)
12036 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12037 (match_operand:QI 2 "const_int_operand" "e"))
12039 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12040 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12041 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12042 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12044 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12045 "shr{q}\t{%2, %0|%0, %2}"
12046 [(set_attr "type" "ishift")
12047 (set_attr "mode" "DI")])
12049 (define_insn "*lshrdi3_cconly_rex64"
12050 [(set (reg FLAGS_REG)
12052 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12053 (match_operand:QI 2 "const_int_operand" "e"))
12055 (clobber (match_scratch:DI 0 "=r"))]
12056 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12057 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12059 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12060 "shr{q}\t{%2, %0|%0, %2}"
12061 [(set_attr "type" "ishift")
12062 (set_attr "mode" "DI")])
12064 (define_insn "*lshrdi3_1"
12065 [(set (match_operand:DI 0 "register_operand" "=r")
12066 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12067 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12068 (clobber (reg:CC FLAGS_REG))]
12071 [(set_attr "type" "multi")])
12073 ;; By default we don't ask for a scratch register, because when DImode
12074 ;; values are manipulated, registers are already at a premium. But if
12075 ;; we have one handy, we won't turn it away.
12077 [(match_scratch:SI 3 "r")
12078 (parallel [(set (match_operand:DI 0 "register_operand" "")
12079 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12080 (match_operand:QI 2 "nonmemory_operand" "")))
12081 (clobber (reg:CC FLAGS_REG))])
12083 "!TARGET_64BIT && TARGET_CMOVE"
12085 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12088 [(set (match_operand:DI 0 "register_operand" "")
12089 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12090 (match_operand:QI 2 "nonmemory_operand" "")))
12091 (clobber (reg:CC FLAGS_REG))]
12092 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12093 ? flow2_completed : reload_completed)"
12095 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12097 (define_expand "lshrsi3"
12098 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12099 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12100 (match_operand:QI 2 "nonmemory_operand" "")))
12101 (clobber (reg:CC FLAGS_REG))]
12103 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12105 (define_insn "*lshrsi3_1_one_bit"
12106 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12107 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12108 (match_operand:QI 2 "const1_operand" "")))
12109 (clobber (reg:CC FLAGS_REG))]
12110 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12111 && (TARGET_SHIFT1 || optimize_size)"
12113 [(set_attr "type" "ishift")
12114 (set (attr "length")
12115 (if_then_else (match_operand:SI 0 "register_operand" "")
12117 (const_string "*")))])
12119 (define_insn "*lshrsi3_1_one_bit_zext"
12120 [(set (match_operand:DI 0 "register_operand" "=r")
12121 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12122 (match_operand:QI 2 "const1_operand" "")))
12123 (clobber (reg:CC FLAGS_REG))]
12124 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12125 && (TARGET_SHIFT1 || optimize_size)"
12127 [(set_attr "type" "ishift")
12128 (set_attr "length" "2")])
12130 (define_insn "*lshrsi3_1"
12131 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12132 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12133 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12134 (clobber (reg:CC FLAGS_REG))]
12135 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12137 shr{l}\t{%2, %0|%0, %2}
12138 shr{l}\t{%b2, %0|%0, %b2}"
12139 [(set_attr "type" "ishift")
12140 (set_attr "mode" "SI")])
12142 (define_insn "*lshrsi3_1_zext"
12143 [(set (match_operand:DI 0 "register_operand" "=r,r")
12145 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12146 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12147 (clobber (reg:CC FLAGS_REG))]
12148 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12150 shr{l}\t{%2, %k0|%k0, %2}
12151 shr{l}\t{%b2, %k0|%k0, %b2}"
12152 [(set_attr "type" "ishift")
12153 (set_attr "mode" "SI")])
12155 ;; This pattern can't accept a variable shift count, since shifts by
12156 ;; zero don't affect the flags. We assume that shifts by constant
12157 ;; zero are optimized away.
12158 (define_insn "*lshrsi3_one_bit_cmp"
12159 [(set (reg FLAGS_REG)
12161 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12162 (match_operand:QI 2 "const1_operand" ""))
12164 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12165 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12166 "ix86_match_ccmode (insn, CCGOCmode)
12167 && (TARGET_SHIFT1 || optimize_size)
12168 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12170 [(set_attr "type" "ishift")
12171 (set (attr "length")
12172 (if_then_else (match_operand:SI 0 "register_operand" "")
12174 (const_string "*")))])
12176 (define_insn "*lshrsi3_one_bit_cconly"
12177 [(set (reg FLAGS_REG)
12179 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12180 (match_operand:QI 2 "const1_operand" ""))
12182 (clobber (match_scratch:SI 0 "=r"))]
12183 "ix86_match_ccmode (insn, CCGOCmode)
12184 && (TARGET_SHIFT1 || optimize_size)
12185 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12187 [(set_attr "type" "ishift")
12188 (set_attr "length" "2")])
12190 (define_insn "*lshrsi3_cmp_one_bit_zext"
12191 [(set (reg FLAGS_REG)
12193 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12194 (match_operand:QI 2 "const1_operand" ""))
12196 (set (match_operand:DI 0 "register_operand" "=r")
12197 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12198 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12199 && (TARGET_SHIFT1 || optimize_size)
12200 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12202 [(set_attr "type" "ishift")
12203 (set_attr "length" "2")])
12205 ;; This pattern can't accept a variable shift count, since shifts by
12206 ;; zero don't affect the flags. We assume that shifts by constant
12207 ;; zero are optimized away.
12208 (define_insn "*lshrsi3_cmp"
12209 [(set (reg FLAGS_REG)
12211 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12212 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12214 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12215 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12216 "ix86_match_ccmode (insn, CCGOCmode)
12217 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12219 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12220 "shr{l}\t{%2, %0|%0, %2}"
12221 [(set_attr "type" "ishift")
12222 (set_attr "mode" "SI")])
12224 (define_insn "*lshrsi3_cconly"
12225 [(set (reg FLAGS_REG)
12227 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12228 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12230 (clobber (match_scratch:SI 0 "=r"))]
12231 "ix86_match_ccmode (insn, CCGOCmode)
12232 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12234 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12235 "shr{l}\t{%2, %0|%0, %2}"
12236 [(set_attr "type" "ishift")
12237 (set_attr "mode" "SI")])
12239 (define_insn "*lshrsi3_cmp_zext"
12240 [(set (reg FLAGS_REG)
12242 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12243 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12245 (set (match_operand:DI 0 "register_operand" "=r")
12246 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12247 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12248 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12250 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12251 "shr{l}\t{%2, %k0|%k0, %2}"
12252 [(set_attr "type" "ishift")
12253 (set_attr "mode" "SI")])
12255 (define_expand "lshrhi3"
12256 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12257 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12258 (match_operand:QI 2 "nonmemory_operand" "")))
12259 (clobber (reg:CC FLAGS_REG))]
12260 "TARGET_HIMODE_MATH"
12261 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12263 (define_insn "*lshrhi3_1_one_bit"
12264 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12265 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12266 (match_operand:QI 2 "const1_operand" "")))
12267 (clobber (reg:CC FLAGS_REG))]
12268 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12269 && (TARGET_SHIFT1 || optimize_size)"
12271 [(set_attr "type" "ishift")
12272 (set (attr "length")
12273 (if_then_else (match_operand 0 "register_operand" "")
12275 (const_string "*")))])
12277 (define_insn "*lshrhi3_1"
12278 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12279 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12280 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12281 (clobber (reg:CC FLAGS_REG))]
12282 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12284 shr{w}\t{%2, %0|%0, %2}
12285 shr{w}\t{%b2, %0|%0, %b2}"
12286 [(set_attr "type" "ishift")
12287 (set_attr "mode" "HI")])
12289 ;; This pattern can't accept a variable shift count, since shifts by
12290 ;; zero don't affect the flags. We assume that shifts by constant
12291 ;; zero are optimized away.
12292 (define_insn "*lshrhi3_one_bit_cmp"
12293 [(set (reg FLAGS_REG)
12295 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12296 (match_operand:QI 2 "const1_operand" ""))
12298 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12299 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12300 "ix86_match_ccmode (insn, CCGOCmode)
12301 && (TARGET_SHIFT1 || optimize_size)
12302 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12304 [(set_attr "type" "ishift")
12305 (set (attr "length")
12306 (if_then_else (match_operand:SI 0 "register_operand" "")
12308 (const_string "*")))])
12310 (define_insn "*lshrhi3_one_bit_cconly"
12311 [(set (reg FLAGS_REG)
12313 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12314 (match_operand:QI 2 "const1_operand" ""))
12316 (clobber (match_scratch:HI 0 "=r"))]
12317 "ix86_match_ccmode (insn, CCGOCmode)
12318 && (TARGET_SHIFT1 || optimize_size)
12319 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12321 [(set_attr "type" "ishift")
12322 (set_attr "length" "2")])
12324 ;; This pattern can't accept a variable shift count, since shifts by
12325 ;; zero don't affect the flags. We assume that shifts by constant
12326 ;; zero are optimized away.
12327 (define_insn "*lshrhi3_cmp"
12328 [(set (reg FLAGS_REG)
12330 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12331 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12333 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12334 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12335 "ix86_match_ccmode (insn, CCGOCmode)
12336 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12338 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12339 "shr{w}\t{%2, %0|%0, %2}"
12340 [(set_attr "type" "ishift")
12341 (set_attr "mode" "HI")])
12343 (define_insn "*lshrhi3_cconly"
12344 [(set (reg FLAGS_REG)
12346 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12347 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12349 (clobber (match_scratch:HI 0 "=r"))]
12350 "ix86_match_ccmode (insn, CCGOCmode)
12351 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12353 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12354 "shr{w}\t{%2, %0|%0, %2}"
12355 [(set_attr "type" "ishift")
12356 (set_attr "mode" "HI")])
12358 (define_expand "lshrqi3"
12359 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12360 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12361 (match_operand:QI 2 "nonmemory_operand" "")))
12362 (clobber (reg:CC FLAGS_REG))]
12363 "TARGET_QIMODE_MATH"
12364 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12366 (define_insn "*lshrqi3_1_one_bit"
12367 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12368 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12369 (match_operand:QI 2 "const1_operand" "")))
12370 (clobber (reg:CC FLAGS_REG))]
12371 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12372 && (TARGET_SHIFT1 || optimize_size)"
12374 [(set_attr "type" "ishift")
12375 (set (attr "length")
12376 (if_then_else (match_operand 0 "register_operand" "")
12378 (const_string "*")))])
12380 (define_insn "*lshrqi3_1_one_bit_slp"
12381 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12382 (lshiftrt:QI (match_dup 0)
12383 (match_operand:QI 1 "const1_operand" "")))
12384 (clobber (reg:CC FLAGS_REG))]
12385 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12386 && (TARGET_SHIFT1 || optimize_size)"
12388 [(set_attr "type" "ishift1")
12389 (set (attr "length")
12390 (if_then_else (match_operand 0 "register_operand" "")
12392 (const_string "*")))])
12394 (define_insn "*lshrqi3_1"
12395 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12396 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12397 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12398 (clobber (reg:CC FLAGS_REG))]
12399 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12401 shr{b}\t{%2, %0|%0, %2}
12402 shr{b}\t{%b2, %0|%0, %b2}"
12403 [(set_attr "type" "ishift")
12404 (set_attr "mode" "QI")])
12406 (define_insn "*lshrqi3_1_slp"
12407 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12408 (lshiftrt:QI (match_dup 0)
12409 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12410 (clobber (reg:CC FLAGS_REG))]
12411 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12412 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12414 shr{b}\t{%1, %0|%0, %1}
12415 shr{b}\t{%b1, %0|%0, %b1}"
12416 [(set_attr "type" "ishift1")
12417 (set_attr "mode" "QI")])
12419 ;; This pattern can't accept a variable shift count, since shifts by
12420 ;; zero don't affect the flags. We assume that shifts by constant
12421 ;; zero are optimized away.
12422 (define_insn "*lshrqi2_one_bit_cmp"
12423 [(set (reg FLAGS_REG)
12425 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12426 (match_operand:QI 2 "const1_operand" ""))
12428 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12429 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12430 "ix86_match_ccmode (insn, CCGOCmode)
12431 && (TARGET_SHIFT1 || optimize_size)
12432 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12434 [(set_attr "type" "ishift")
12435 (set (attr "length")
12436 (if_then_else (match_operand:SI 0 "register_operand" "")
12438 (const_string "*")))])
12440 (define_insn "*lshrqi2_one_bit_cconly"
12441 [(set (reg FLAGS_REG)
12443 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12444 (match_operand:QI 2 "const1_operand" ""))
12446 (clobber (match_scratch:QI 0 "=q"))]
12447 "ix86_match_ccmode (insn, CCGOCmode)
12448 && (TARGET_SHIFT1 || optimize_size)
12449 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12451 [(set_attr "type" "ishift")
12452 (set_attr "length" "2")])
12454 ;; This pattern can't accept a variable shift count, since shifts by
12455 ;; zero don't affect the flags. We assume that shifts by constant
12456 ;; zero are optimized away.
12457 (define_insn "*lshrqi2_cmp"
12458 [(set (reg FLAGS_REG)
12460 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12461 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12463 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12464 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12465 "ix86_match_ccmode (insn, CCGOCmode)
12466 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12468 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12469 "shr{b}\t{%2, %0|%0, %2}"
12470 [(set_attr "type" "ishift")
12471 (set_attr "mode" "QI")])
12473 (define_insn "*lshrqi2_cconly"
12474 [(set (reg FLAGS_REG)
12476 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12477 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12479 (clobber (match_scratch:QI 0 "=q"))]
12480 "ix86_match_ccmode (insn, CCGOCmode)
12481 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12483 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12484 "shr{b}\t{%2, %0|%0, %2}"
12485 [(set_attr "type" "ishift")
12486 (set_attr "mode" "QI")])
12488 ;; Rotate instructions
12490 (define_expand "rotldi3"
12491 [(set (match_operand:DI 0 "shiftdi_operand" "")
12492 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12493 (match_operand:QI 2 "nonmemory_operand" "")))
12494 (clobber (reg:CC FLAGS_REG))]
12499 ix86_expand_binary_operator (ROTATE, DImode, operands);
12502 if (!const_1_to_31_operand (operands[2], VOIDmode))
12504 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12508 ;; Implement rotation using two double-precision shift instructions
12509 ;; and a scratch register.
12510 (define_insn_and_split "ix86_rotldi3"
12511 [(set (match_operand:DI 0 "register_operand" "=r")
12512 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12513 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12514 (clobber (reg:CC FLAGS_REG))
12515 (clobber (match_scratch:SI 3 "=&r"))]
12518 "&& reload_completed"
12519 [(set (match_dup 3) (match_dup 4))
12521 [(set (match_dup 4)
12522 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12523 (lshiftrt:SI (match_dup 5)
12524 (minus:QI (const_int 32) (match_dup 2)))))
12525 (clobber (reg:CC FLAGS_REG))])
12527 [(set (match_dup 5)
12528 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12529 (lshiftrt:SI (match_dup 3)
12530 (minus:QI (const_int 32) (match_dup 2)))))
12531 (clobber (reg:CC FLAGS_REG))])]
12532 "split_di (operands, 1, operands + 4, operands + 5);")
12534 (define_insn "*rotlsi3_1_one_bit_rex64"
12535 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12536 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12537 (match_operand:QI 2 "const1_operand" "")))
12538 (clobber (reg:CC FLAGS_REG))]
12539 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12540 && (TARGET_SHIFT1 || optimize_size)"
12542 [(set_attr "type" "rotate")
12543 (set (attr "length")
12544 (if_then_else (match_operand:DI 0 "register_operand" "")
12546 (const_string "*")))])
12548 (define_insn "*rotldi3_1_rex64"
12549 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12550 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12551 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12552 (clobber (reg:CC FLAGS_REG))]
12553 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12555 rol{q}\t{%2, %0|%0, %2}
12556 rol{q}\t{%b2, %0|%0, %b2}"
12557 [(set_attr "type" "rotate")
12558 (set_attr "mode" "DI")])
12560 (define_expand "rotlsi3"
12561 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12562 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12563 (match_operand:QI 2 "nonmemory_operand" "")))
12564 (clobber (reg:CC FLAGS_REG))]
12566 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12568 (define_insn "*rotlsi3_1_one_bit"
12569 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12570 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12571 (match_operand:QI 2 "const1_operand" "")))
12572 (clobber (reg:CC FLAGS_REG))]
12573 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12574 && (TARGET_SHIFT1 || optimize_size)"
12576 [(set_attr "type" "rotate")
12577 (set (attr "length")
12578 (if_then_else (match_operand:SI 0 "register_operand" "")
12580 (const_string "*")))])
12582 (define_insn "*rotlsi3_1_one_bit_zext"
12583 [(set (match_operand:DI 0 "register_operand" "=r")
12585 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12586 (match_operand:QI 2 "const1_operand" ""))))
12587 (clobber (reg:CC FLAGS_REG))]
12588 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12589 && (TARGET_SHIFT1 || optimize_size)"
12591 [(set_attr "type" "rotate")
12592 (set_attr "length" "2")])
12594 (define_insn "*rotlsi3_1"
12595 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12596 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12597 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12598 (clobber (reg:CC FLAGS_REG))]
12599 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12601 rol{l}\t{%2, %0|%0, %2}
12602 rol{l}\t{%b2, %0|%0, %b2}"
12603 [(set_attr "type" "rotate")
12604 (set_attr "mode" "SI")])
12606 (define_insn "*rotlsi3_1_zext"
12607 [(set (match_operand:DI 0 "register_operand" "=r,r")
12609 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12610 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12611 (clobber (reg:CC FLAGS_REG))]
12612 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12614 rol{l}\t{%2, %k0|%k0, %2}
12615 rol{l}\t{%b2, %k0|%k0, %b2}"
12616 [(set_attr "type" "rotate")
12617 (set_attr "mode" "SI")])
12619 (define_expand "rotlhi3"
12620 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12621 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12622 (match_operand:QI 2 "nonmemory_operand" "")))
12623 (clobber (reg:CC FLAGS_REG))]
12624 "TARGET_HIMODE_MATH"
12625 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12627 (define_insn "*rotlhi3_1_one_bit"
12628 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12629 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12630 (match_operand:QI 2 "const1_operand" "")))
12631 (clobber (reg:CC FLAGS_REG))]
12632 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12633 && (TARGET_SHIFT1 || optimize_size)"
12635 [(set_attr "type" "rotate")
12636 (set (attr "length")
12637 (if_then_else (match_operand 0 "register_operand" "")
12639 (const_string "*")))])
12641 (define_insn "*rotlhi3_1"
12642 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12643 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12644 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12645 (clobber (reg:CC FLAGS_REG))]
12646 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12648 rol{w}\t{%2, %0|%0, %2}
12649 rol{w}\t{%b2, %0|%0, %b2}"
12650 [(set_attr "type" "rotate")
12651 (set_attr "mode" "HI")])
12653 (define_expand "rotlqi3"
12654 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12655 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12656 (match_operand:QI 2 "nonmemory_operand" "")))
12657 (clobber (reg:CC FLAGS_REG))]
12658 "TARGET_QIMODE_MATH"
12659 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12661 (define_insn "*rotlqi3_1_one_bit_slp"
12662 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12663 (rotate:QI (match_dup 0)
12664 (match_operand:QI 1 "const1_operand" "")))
12665 (clobber (reg:CC FLAGS_REG))]
12666 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12667 && (TARGET_SHIFT1 || optimize_size)"
12669 [(set_attr "type" "rotate1")
12670 (set (attr "length")
12671 (if_then_else (match_operand 0 "register_operand" "")
12673 (const_string "*")))])
12675 (define_insn "*rotlqi3_1_one_bit"
12676 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12677 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12678 (match_operand:QI 2 "const1_operand" "")))
12679 (clobber (reg:CC FLAGS_REG))]
12680 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12681 && (TARGET_SHIFT1 || optimize_size)"
12683 [(set_attr "type" "rotate")
12684 (set (attr "length")
12685 (if_then_else (match_operand 0 "register_operand" "")
12687 (const_string "*")))])
12689 (define_insn "*rotlqi3_1_slp"
12690 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12691 (rotate:QI (match_dup 0)
12692 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12693 (clobber (reg:CC FLAGS_REG))]
12694 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12695 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12697 rol{b}\t{%1, %0|%0, %1}
12698 rol{b}\t{%b1, %0|%0, %b1}"
12699 [(set_attr "type" "rotate1")
12700 (set_attr "mode" "QI")])
12702 (define_insn "*rotlqi3_1"
12703 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12704 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12705 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12706 (clobber (reg:CC FLAGS_REG))]
12707 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12709 rol{b}\t{%2, %0|%0, %2}
12710 rol{b}\t{%b2, %0|%0, %b2}"
12711 [(set_attr "type" "rotate")
12712 (set_attr "mode" "QI")])
12714 (define_expand "rotrdi3"
12715 [(set (match_operand:DI 0 "shiftdi_operand" "")
12716 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12717 (match_operand:QI 2 "nonmemory_operand" "")))
12718 (clobber (reg:CC FLAGS_REG))]
12723 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12726 if (!const_1_to_31_operand (operands[2], VOIDmode))
12728 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12732 ;; Implement rotation using two double-precision shift instructions
12733 ;; and a scratch register.
12734 (define_insn_and_split "ix86_rotrdi3"
12735 [(set (match_operand:DI 0 "register_operand" "=r")
12736 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12737 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12738 (clobber (reg:CC FLAGS_REG))
12739 (clobber (match_scratch:SI 3 "=&r"))]
12742 "&& reload_completed"
12743 [(set (match_dup 3) (match_dup 4))
12745 [(set (match_dup 4)
12746 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12747 (ashift:SI (match_dup 5)
12748 (minus:QI (const_int 32) (match_dup 2)))))
12749 (clobber (reg:CC FLAGS_REG))])
12751 [(set (match_dup 5)
12752 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12753 (ashift:SI (match_dup 3)
12754 (minus:QI (const_int 32) (match_dup 2)))))
12755 (clobber (reg:CC FLAGS_REG))])]
12756 "split_di (operands, 1, operands + 4, operands + 5);")
12758 (define_insn "*rotrdi3_1_one_bit_rex64"
12759 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12760 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12761 (match_operand:QI 2 "const1_operand" "")))
12762 (clobber (reg:CC FLAGS_REG))]
12763 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12764 && (TARGET_SHIFT1 || optimize_size)"
12766 [(set_attr "type" "rotate")
12767 (set (attr "length")
12768 (if_then_else (match_operand:DI 0 "register_operand" "")
12770 (const_string "*")))])
12772 (define_insn "*rotrdi3_1_rex64"
12773 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12774 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12775 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12776 (clobber (reg:CC FLAGS_REG))]
12777 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12779 ror{q}\t{%2, %0|%0, %2}
12780 ror{q}\t{%b2, %0|%0, %b2}"
12781 [(set_attr "type" "rotate")
12782 (set_attr "mode" "DI")])
12784 (define_expand "rotrsi3"
12785 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12786 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12787 (match_operand:QI 2 "nonmemory_operand" "")))
12788 (clobber (reg:CC FLAGS_REG))]
12790 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12792 (define_insn "*rotrsi3_1_one_bit"
12793 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12794 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12795 (match_operand:QI 2 "const1_operand" "")))
12796 (clobber (reg:CC FLAGS_REG))]
12797 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12798 && (TARGET_SHIFT1 || optimize_size)"
12800 [(set_attr "type" "rotate")
12801 (set (attr "length")
12802 (if_then_else (match_operand:SI 0 "register_operand" "")
12804 (const_string "*")))])
12806 (define_insn "*rotrsi3_1_one_bit_zext"
12807 [(set (match_operand:DI 0 "register_operand" "=r")
12809 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12810 (match_operand:QI 2 "const1_operand" ""))))
12811 (clobber (reg:CC FLAGS_REG))]
12812 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12813 && (TARGET_SHIFT1 || optimize_size)"
12815 [(set_attr "type" "rotate")
12816 (set (attr "length")
12817 (if_then_else (match_operand:SI 0 "register_operand" "")
12819 (const_string "*")))])
12821 (define_insn "*rotrsi3_1"
12822 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12823 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12824 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12825 (clobber (reg:CC FLAGS_REG))]
12826 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12828 ror{l}\t{%2, %0|%0, %2}
12829 ror{l}\t{%b2, %0|%0, %b2}"
12830 [(set_attr "type" "rotate")
12831 (set_attr "mode" "SI")])
12833 (define_insn "*rotrsi3_1_zext"
12834 [(set (match_operand:DI 0 "register_operand" "=r,r")
12836 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12837 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12838 (clobber (reg:CC FLAGS_REG))]
12839 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12841 ror{l}\t{%2, %k0|%k0, %2}
12842 ror{l}\t{%b2, %k0|%k0, %b2}"
12843 [(set_attr "type" "rotate")
12844 (set_attr "mode" "SI")])
12846 (define_expand "rotrhi3"
12847 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12848 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12849 (match_operand:QI 2 "nonmemory_operand" "")))
12850 (clobber (reg:CC FLAGS_REG))]
12851 "TARGET_HIMODE_MATH"
12852 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12854 (define_insn "*rotrhi3_one_bit"
12855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12856 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12857 (match_operand:QI 2 "const1_operand" "")))
12858 (clobber (reg:CC FLAGS_REG))]
12859 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12860 && (TARGET_SHIFT1 || optimize_size)"
12862 [(set_attr "type" "rotate")
12863 (set (attr "length")
12864 (if_then_else (match_operand 0 "register_operand" "")
12866 (const_string "*")))])
12868 (define_insn "*rotrhi3"
12869 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12870 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12871 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12872 (clobber (reg:CC FLAGS_REG))]
12873 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12875 ror{w}\t{%2, %0|%0, %2}
12876 ror{w}\t{%b2, %0|%0, %b2}"
12877 [(set_attr "type" "rotate")
12878 (set_attr "mode" "HI")])
12880 (define_expand "rotrqi3"
12881 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12882 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12883 (match_operand:QI 2 "nonmemory_operand" "")))
12884 (clobber (reg:CC FLAGS_REG))]
12885 "TARGET_QIMODE_MATH"
12886 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12888 (define_insn "*rotrqi3_1_one_bit"
12889 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12890 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12891 (match_operand:QI 2 "const1_operand" "")))
12892 (clobber (reg:CC FLAGS_REG))]
12893 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12894 && (TARGET_SHIFT1 || optimize_size)"
12896 [(set_attr "type" "rotate")
12897 (set (attr "length")
12898 (if_then_else (match_operand 0 "register_operand" "")
12900 (const_string "*")))])
12902 (define_insn "*rotrqi3_1_one_bit_slp"
12903 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12904 (rotatert:QI (match_dup 0)
12905 (match_operand:QI 1 "const1_operand" "")))
12906 (clobber (reg:CC FLAGS_REG))]
12907 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12908 && (TARGET_SHIFT1 || optimize_size)"
12910 [(set_attr "type" "rotate1")
12911 (set (attr "length")
12912 (if_then_else (match_operand 0 "register_operand" "")
12914 (const_string "*")))])
12916 (define_insn "*rotrqi3_1"
12917 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12918 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12919 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12920 (clobber (reg:CC FLAGS_REG))]
12921 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12923 ror{b}\t{%2, %0|%0, %2}
12924 ror{b}\t{%b2, %0|%0, %b2}"
12925 [(set_attr "type" "rotate")
12926 (set_attr "mode" "QI")])
12928 (define_insn "*rotrqi3_1_slp"
12929 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12930 (rotatert:QI (match_dup 0)
12931 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12932 (clobber (reg:CC FLAGS_REG))]
12933 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12934 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12936 ror{b}\t{%1, %0|%0, %1}
12937 ror{b}\t{%b1, %0|%0, %b1}"
12938 [(set_attr "type" "rotate1")
12939 (set_attr "mode" "QI")])
12941 ;; Bit set / bit test instructions
12943 (define_expand "extv"
12944 [(set (match_operand:SI 0 "register_operand" "")
12945 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12946 (match_operand:SI 2 "const8_operand" "")
12947 (match_operand:SI 3 "const8_operand" "")))]
12950 /* Handle extractions from %ah et al. */
12951 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12954 /* From mips.md: extract_bit_field doesn't verify that our source
12955 matches the predicate, so check it again here. */
12956 if (! ext_register_operand (operands[1], VOIDmode))
12960 (define_expand "extzv"
12961 [(set (match_operand:SI 0 "register_operand" "")
12962 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12963 (match_operand:SI 2 "const8_operand" "")
12964 (match_operand:SI 3 "const8_operand" "")))]
12967 /* Handle extractions from %ah et al. */
12968 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12971 /* From mips.md: extract_bit_field doesn't verify that our source
12972 matches the predicate, so check it again here. */
12973 if (! ext_register_operand (operands[1], VOIDmode))
12977 (define_expand "insv"
12978 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12979 (match_operand 1 "const8_operand" "")
12980 (match_operand 2 "const8_operand" ""))
12981 (match_operand 3 "register_operand" ""))]
12984 /* Handle insertions to %ah et al. */
12985 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12988 /* From mips.md: insert_bit_field doesn't verify that our source
12989 matches the predicate, so check it again here. */
12990 if (! ext_register_operand (operands[0], VOIDmode))
12994 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12996 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13001 ;; %%% bts, btr, btc, bt.
13002 ;; In general these instructions are *slow* when applied to memory,
13003 ;; since they enforce atomic operation. When applied to registers,
13004 ;; it depends on the cpu implementation. They're never faster than
13005 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13006 ;; no point. But in 64-bit, we can't hold the relevant immediates
13007 ;; within the instruction itself, so operating on bits in the high
13008 ;; 32-bits of a register becomes easier.
13010 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13011 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13012 ;; negdf respectively, so they can never be disabled entirely.
13014 (define_insn "*btsq"
13015 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13017 (match_operand:DI 1 "const_0_to_63_operand" ""))
13019 (clobber (reg:CC FLAGS_REG))]
13020 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13022 [(set_attr "type" "alu1")])
13024 (define_insn "*btrq"
13025 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13027 (match_operand:DI 1 "const_0_to_63_operand" ""))
13029 (clobber (reg:CC FLAGS_REG))]
13030 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13032 [(set_attr "type" "alu1")])
13034 (define_insn "*btcq"
13035 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13037 (match_operand:DI 1 "const_0_to_63_operand" ""))
13038 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13039 (clobber (reg:CC FLAGS_REG))]
13040 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13042 [(set_attr "type" "alu1")])
13044 ;; Allow Nocona to avoid these instructions if a register is available.
13047 [(match_scratch:DI 2 "r")
13048 (parallel [(set (zero_extract:DI
13049 (match_operand:DI 0 "register_operand" "")
13051 (match_operand:DI 1 "const_0_to_63_operand" ""))
13053 (clobber (reg:CC FLAGS_REG))])]
13054 "TARGET_64BIT && !TARGET_USE_BT"
13057 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13060 if (HOST_BITS_PER_WIDE_INT >= 64)
13061 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13062 else if (i < HOST_BITS_PER_WIDE_INT)
13063 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13065 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13067 op1 = immed_double_const (lo, hi, DImode);
13070 emit_move_insn (operands[2], op1);
13074 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13079 [(match_scratch:DI 2 "r")
13080 (parallel [(set (zero_extract:DI
13081 (match_operand:DI 0 "register_operand" "")
13083 (match_operand:DI 1 "const_0_to_63_operand" ""))
13085 (clobber (reg:CC FLAGS_REG))])]
13086 "TARGET_64BIT && !TARGET_USE_BT"
13089 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13092 if (HOST_BITS_PER_WIDE_INT >= 64)
13093 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13094 else if (i < HOST_BITS_PER_WIDE_INT)
13095 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13097 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13099 op1 = immed_double_const (~lo, ~hi, DImode);
13102 emit_move_insn (operands[2], op1);
13106 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13111 [(match_scratch:DI 2 "r")
13112 (parallel [(set (zero_extract:DI
13113 (match_operand:DI 0 "register_operand" "")
13115 (match_operand:DI 1 "const_0_to_63_operand" ""))
13116 (not:DI (zero_extract:DI
13117 (match_dup 0) (const_int 1) (match_dup 1))))
13118 (clobber (reg:CC FLAGS_REG))])]
13119 "TARGET_64BIT && !TARGET_USE_BT"
13122 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13125 if (HOST_BITS_PER_WIDE_INT >= 64)
13126 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13127 else if (i < HOST_BITS_PER_WIDE_INT)
13128 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13130 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13132 op1 = immed_double_const (lo, hi, DImode);
13135 emit_move_insn (operands[2], op1);
13139 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13143 ;; Store-flag instructions.
13145 ;; For all sCOND expanders, also expand the compare or test insn that
13146 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13148 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13149 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13150 ;; way, which can later delete the movzx if only QImode is needed.
13152 (define_expand "seq"
13153 [(set (match_operand:QI 0 "register_operand" "")
13154 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13156 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13158 (define_expand "sne"
13159 [(set (match_operand:QI 0 "register_operand" "")
13160 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13162 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13164 (define_expand "sgt"
13165 [(set (match_operand:QI 0 "register_operand" "")
13166 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13168 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13170 (define_expand "sgtu"
13171 [(set (match_operand:QI 0 "register_operand" "")
13172 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13174 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13176 (define_expand "slt"
13177 [(set (match_operand:QI 0 "register_operand" "")
13178 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13180 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13182 (define_expand "sltu"
13183 [(set (match_operand:QI 0 "register_operand" "")
13184 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13186 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13188 (define_expand "sge"
13189 [(set (match_operand:QI 0 "register_operand" "")
13190 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13192 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13194 (define_expand "sgeu"
13195 [(set (match_operand:QI 0 "register_operand" "")
13196 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13198 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13200 (define_expand "sle"
13201 [(set (match_operand:QI 0 "register_operand" "")
13202 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13204 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13206 (define_expand "sleu"
13207 [(set (match_operand:QI 0 "register_operand" "")
13208 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13212 (define_expand "sunordered"
13213 [(set (match_operand:QI 0 "register_operand" "")
13214 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13215 "TARGET_80387 || TARGET_SSE"
13216 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13218 (define_expand "sordered"
13219 [(set (match_operand:QI 0 "register_operand" "")
13220 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13222 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13224 (define_expand "suneq"
13225 [(set (match_operand:QI 0 "register_operand" "")
13226 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13227 "TARGET_80387 || TARGET_SSE"
13228 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13230 (define_expand "sunge"
13231 [(set (match_operand:QI 0 "register_operand" "")
13232 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13233 "TARGET_80387 || TARGET_SSE"
13234 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13236 (define_expand "sungt"
13237 [(set (match_operand:QI 0 "register_operand" "")
13238 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13239 "TARGET_80387 || TARGET_SSE"
13240 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13242 (define_expand "sunle"
13243 [(set (match_operand:QI 0 "register_operand" "")
13244 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13245 "TARGET_80387 || TARGET_SSE"
13246 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13248 (define_expand "sunlt"
13249 [(set (match_operand:QI 0 "register_operand" "")
13250 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13251 "TARGET_80387 || TARGET_SSE"
13252 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13254 (define_expand "sltgt"
13255 [(set (match_operand:QI 0 "register_operand" "")
13256 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13257 "TARGET_80387 || TARGET_SSE"
13258 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13260 (define_insn "*setcc_1"
13261 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13262 (match_operator:QI 1 "ix86_comparison_operator"
13263 [(reg FLAGS_REG) (const_int 0)]))]
13266 [(set_attr "type" "setcc")
13267 (set_attr "mode" "QI")])
13269 (define_insn "*setcc_2"
13270 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13271 (match_operator:QI 1 "ix86_comparison_operator"
13272 [(reg FLAGS_REG) (const_int 0)]))]
13275 [(set_attr "type" "setcc")
13276 (set_attr "mode" "QI")])
13278 ;; In general it is not safe to assume too much about CCmode registers,
13279 ;; so simplify-rtx stops when it sees a second one. Under certain
13280 ;; conditions this is safe on x86, so help combine not create
13287 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13288 (ne:QI (match_operator 1 "ix86_comparison_operator"
13289 [(reg FLAGS_REG) (const_int 0)])
13292 [(set (match_dup 0) (match_dup 1))]
13294 PUT_MODE (operands[1], QImode);
13298 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13299 (ne:QI (match_operator 1 "ix86_comparison_operator"
13300 [(reg FLAGS_REG) (const_int 0)])
13303 [(set (match_dup 0) (match_dup 1))]
13305 PUT_MODE (operands[1], QImode);
13309 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13310 (eq:QI (match_operator 1 "ix86_comparison_operator"
13311 [(reg FLAGS_REG) (const_int 0)])
13314 [(set (match_dup 0) (match_dup 1))]
13316 rtx new_op1 = copy_rtx (operands[1]);
13317 operands[1] = new_op1;
13318 PUT_MODE (new_op1, QImode);
13319 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13320 GET_MODE (XEXP (new_op1, 0))));
13322 /* Make sure that (a) the CCmode we have for the flags is strong
13323 enough for the reversed compare or (b) we have a valid FP compare. */
13324 if (! ix86_comparison_operator (new_op1, VOIDmode))
13329 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13330 (eq:QI (match_operator 1 "ix86_comparison_operator"
13331 [(reg FLAGS_REG) (const_int 0)])
13334 [(set (match_dup 0) (match_dup 1))]
13336 rtx new_op1 = copy_rtx (operands[1]);
13337 operands[1] = new_op1;
13338 PUT_MODE (new_op1, QImode);
13339 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13340 GET_MODE (XEXP (new_op1, 0))));
13342 /* Make sure that (a) the CCmode we have for the flags is strong
13343 enough for the reversed compare or (b) we have a valid FP compare. */
13344 if (! ix86_comparison_operator (new_op1, VOIDmode))
13348 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13349 ;; subsequent logical operations are used to imitate conditional moves.
13350 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13353 (define_insn "*sse_setccsf"
13354 [(set (match_operand:SF 0 "register_operand" "=x")
13355 (match_operator:SF 1 "sse_comparison_operator"
13356 [(match_operand:SF 2 "register_operand" "0")
13357 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13359 "cmp%D1ss\t{%3, %0|%0, %3}"
13360 [(set_attr "type" "ssecmp")
13361 (set_attr "mode" "SF")])
13363 (define_insn "*sse_setccdf"
13364 [(set (match_operand:DF 0 "register_operand" "=Y")
13365 (match_operator:DF 1 "sse_comparison_operator"
13366 [(match_operand:DF 2 "register_operand" "0")
13367 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13369 "cmp%D1sd\t{%3, %0|%0, %3}"
13370 [(set_attr "type" "ssecmp")
13371 (set_attr "mode" "DF")])
13373 ;; Basic conditional jump instructions.
13374 ;; We ignore the overflow flag for signed branch instructions.
13376 ;; For all bCOND expanders, also expand the compare or test insn that
13377 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13379 (define_expand "beq"
13381 (if_then_else (match_dup 1)
13382 (label_ref (match_operand 0 "" ""))
13385 "ix86_expand_branch (EQ, operands[0]); DONE;")
13387 (define_expand "bne"
13389 (if_then_else (match_dup 1)
13390 (label_ref (match_operand 0 "" ""))
13393 "ix86_expand_branch (NE, operands[0]); DONE;")
13395 (define_expand "bgt"
13397 (if_then_else (match_dup 1)
13398 (label_ref (match_operand 0 "" ""))
13401 "ix86_expand_branch (GT, operands[0]); DONE;")
13403 (define_expand "bgtu"
13405 (if_then_else (match_dup 1)
13406 (label_ref (match_operand 0 "" ""))
13409 "ix86_expand_branch (GTU, operands[0]); DONE;")
13411 (define_expand "blt"
13413 (if_then_else (match_dup 1)
13414 (label_ref (match_operand 0 "" ""))
13417 "ix86_expand_branch (LT, operands[0]); DONE;")
13419 (define_expand "bltu"
13421 (if_then_else (match_dup 1)
13422 (label_ref (match_operand 0 "" ""))
13425 "ix86_expand_branch (LTU, operands[0]); DONE;")
13427 (define_expand "bge"
13429 (if_then_else (match_dup 1)
13430 (label_ref (match_operand 0 "" ""))
13433 "ix86_expand_branch (GE, operands[0]); DONE;")
13435 (define_expand "bgeu"
13437 (if_then_else (match_dup 1)
13438 (label_ref (match_operand 0 "" ""))
13441 "ix86_expand_branch (GEU, operands[0]); DONE;")
13443 (define_expand "ble"
13445 (if_then_else (match_dup 1)
13446 (label_ref (match_operand 0 "" ""))
13449 "ix86_expand_branch (LE, operands[0]); DONE;")
13451 (define_expand "bleu"
13453 (if_then_else (match_dup 1)
13454 (label_ref (match_operand 0 "" ""))
13457 "ix86_expand_branch (LEU, operands[0]); DONE;")
13459 (define_expand "bunordered"
13461 (if_then_else (match_dup 1)
13462 (label_ref (match_operand 0 "" ""))
13464 "TARGET_80387 || TARGET_SSE_MATH"
13465 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13467 (define_expand "bordered"
13469 (if_then_else (match_dup 1)
13470 (label_ref (match_operand 0 "" ""))
13472 "TARGET_80387 || TARGET_SSE_MATH"
13473 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13475 (define_expand "buneq"
13477 (if_then_else (match_dup 1)
13478 (label_ref (match_operand 0 "" ""))
13480 "TARGET_80387 || TARGET_SSE_MATH"
13481 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13483 (define_expand "bunge"
13485 (if_then_else (match_dup 1)
13486 (label_ref (match_operand 0 "" ""))
13488 "TARGET_80387 || TARGET_SSE_MATH"
13489 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13491 (define_expand "bungt"
13493 (if_then_else (match_dup 1)
13494 (label_ref (match_operand 0 "" ""))
13496 "TARGET_80387 || TARGET_SSE_MATH"
13497 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13499 (define_expand "bunle"
13501 (if_then_else (match_dup 1)
13502 (label_ref (match_operand 0 "" ""))
13504 "TARGET_80387 || TARGET_SSE_MATH"
13505 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13507 (define_expand "bunlt"
13509 (if_then_else (match_dup 1)
13510 (label_ref (match_operand 0 "" ""))
13512 "TARGET_80387 || TARGET_SSE_MATH"
13513 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13515 (define_expand "bltgt"
13517 (if_then_else (match_dup 1)
13518 (label_ref (match_operand 0 "" ""))
13520 "TARGET_80387 || TARGET_SSE_MATH"
13521 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13523 (define_insn "*jcc_1"
13525 (if_then_else (match_operator 1 "ix86_comparison_operator"
13526 [(reg FLAGS_REG) (const_int 0)])
13527 (label_ref (match_operand 0 "" ""))
13531 [(set_attr "type" "ibr")
13532 (set_attr "modrm" "0")
13533 (set (attr "length")
13534 (if_then_else (and (ge (minus (match_dup 0) (pc))
13536 (lt (minus (match_dup 0) (pc))
13541 (define_insn "*jcc_2"
13543 (if_then_else (match_operator 1 "ix86_comparison_operator"
13544 [(reg FLAGS_REG) (const_int 0)])
13546 (label_ref (match_operand 0 "" ""))))]
13549 [(set_attr "type" "ibr")
13550 (set_attr "modrm" "0")
13551 (set (attr "length")
13552 (if_then_else (and (ge (minus (match_dup 0) (pc))
13554 (lt (minus (match_dup 0) (pc))
13559 ;; In general it is not safe to assume too much about CCmode registers,
13560 ;; so simplify-rtx stops when it sees a second one. Under certain
13561 ;; conditions this is safe on x86, so help combine not create
13569 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13570 [(reg FLAGS_REG) (const_int 0)])
13572 (label_ref (match_operand 1 "" ""))
13576 (if_then_else (match_dup 0)
13577 (label_ref (match_dup 1))
13580 PUT_MODE (operands[0], VOIDmode);
13585 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13586 [(reg FLAGS_REG) (const_int 0)])
13588 (label_ref (match_operand 1 "" ""))
13592 (if_then_else (match_dup 0)
13593 (label_ref (match_dup 1))
13596 rtx new_op0 = copy_rtx (operands[0]);
13597 operands[0] = new_op0;
13598 PUT_MODE (new_op0, VOIDmode);
13599 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13600 GET_MODE (XEXP (new_op0, 0))));
13602 /* Make sure that (a) the CCmode we have for the flags is strong
13603 enough for the reversed compare or (b) we have a valid FP compare. */
13604 if (! ix86_comparison_operator (new_op0, VOIDmode))
13608 ;; Define combination compare-and-branch fp compare instructions to use
13609 ;; during early optimization. Splitting the operation apart early makes
13610 ;; for bad code when we want to reverse the operation.
13612 (define_insn "*fp_jcc_1_mixed"
13614 (if_then_else (match_operator 0 "comparison_operator"
13615 [(match_operand 1 "register_operand" "f,x")
13616 (match_operand 2 "nonimmediate_operand" "f,xm")])
13617 (label_ref (match_operand 3 "" ""))
13619 (clobber (reg:CCFP FPSR_REG))
13620 (clobber (reg:CCFP FLAGS_REG))]
13621 "TARGET_MIX_SSE_I387
13622 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13623 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13624 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13627 (define_insn "*fp_jcc_1_sse"
13629 (if_then_else (match_operator 0 "comparison_operator"
13630 [(match_operand 1 "register_operand" "x")
13631 (match_operand 2 "nonimmediate_operand" "xm")])
13632 (label_ref (match_operand 3 "" ""))
13634 (clobber (reg:CCFP FPSR_REG))
13635 (clobber (reg:CCFP FLAGS_REG))]
13637 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13638 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13639 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13642 (define_insn "*fp_jcc_1_387"
13644 (if_then_else (match_operator 0 "comparison_operator"
13645 [(match_operand 1 "register_operand" "f")
13646 (match_operand 2 "register_operand" "f")])
13647 (label_ref (match_operand 3 "" ""))
13649 (clobber (reg:CCFP FPSR_REG))
13650 (clobber (reg:CCFP FLAGS_REG))]
13651 "TARGET_CMOVE && TARGET_80387
13652 && FLOAT_MODE_P (GET_MODE (operands[1]))
13653 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13654 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13657 (define_insn "*fp_jcc_2_mixed"
13659 (if_then_else (match_operator 0 "comparison_operator"
13660 [(match_operand 1 "register_operand" "f,x")
13661 (match_operand 2 "nonimmediate_operand" "f,xm")])
13663 (label_ref (match_operand 3 "" ""))))
13664 (clobber (reg:CCFP FPSR_REG))
13665 (clobber (reg:CCFP FLAGS_REG))]
13666 "TARGET_MIX_SSE_I387
13667 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13668 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13669 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13672 (define_insn "*fp_jcc_2_sse"
13674 (if_then_else (match_operator 0 "comparison_operator"
13675 [(match_operand 1 "register_operand" "x")
13676 (match_operand 2 "nonimmediate_operand" "xm")])
13678 (label_ref (match_operand 3 "" ""))))
13679 (clobber (reg:CCFP FPSR_REG))
13680 (clobber (reg:CCFP FLAGS_REG))]
13682 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13683 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13684 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13687 (define_insn "*fp_jcc_2_387"
13689 (if_then_else (match_operator 0 "comparison_operator"
13690 [(match_operand 1 "register_operand" "f")
13691 (match_operand 2 "register_operand" "f")])
13693 (label_ref (match_operand 3 "" ""))))
13694 (clobber (reg:CCFP FPSR_REG))
13695 (clobber (reg:CCFP FLAGS_REG))]
13696 "TARGET_CMOVE && TARGET_80387
13697 && FLOAT_MODE_P (GET_MODE (operands[1]))
13698 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13699 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13702 (define_insn "*fp_jcc_3_387"
13704 (if_then_else (match_operator 0 "comparison_operator"
13705 [(match_operand 1 "register_operand" "f")
13706 (match_operand 2 "nonimmediate_operand" "fm")])
13707 (label_ref (match_operand 3 "" ""))
13709 (clobber (reg:CCFP FPSR_REG))
13710 (clobber (reg:CCFP FLAGS_REG))
13711 (clobber (match_scratch:HI 4 "=a"))]
13713 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13714 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13715 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13716 && SELECT_CC_MODE (GET_CODE (operands[0]),
13717 operands[1], operands[2]) == CCFPmode
13718 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13721 (define_insn "*fp_jcc_4_387"
13723 (if_then_else (match_operator 0 "comparison_operator"
13724 [(match_operand 1 "register_operand" "f")
13725 (match_operand 2 "nonimmediate_operand" "fm")])
13727 (label_ref (match_operand 3 "" ""))))
13728 (clobber (reg:CCFP FPSR_REG))
13729 (clobber (reg:CCFP FLAGS_REG))
13730 (clobber (match_scratch:HI 4 "=a"))]
13732 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13733 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13734 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13735 && SELECT_CC_MODE (GET_CODE (operands[0]),
13736 operands[1], operands[2]) == CCFPmode
13737 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13740 (define_insn "*fp_jcc_5_387"
13742 (if_then_else (match_operator 0 "comparison_operator"
13743 [(match_operand 1 "register_operand" "f")
13744 (match_operand 2 "register_operand" "f")])
13745 (label_ref (match_operand 3 "" ""))
13747 (clobber (reg:CCFP FPSR_REG))
13748 (clobber (reg:CCFP FLAGS_REG))
13749 (clobber (match_scratch:HI 4 "=a"))]
13751 && FLOAT_MODE_P (GET_MODE (operands[1]))
13752 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13753 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13756 (define_insn "*fp_jcc_6_387"
13758 (if_then_else (match_operator 0 "comparison_operator"
13759 [(match_operand 1 "register_operand" "f")
13760 (match_operand 2 "register_operand" "f")])
13762 (label_ref (match_operand 3 "" ""))))
13763 (clobber (reg:CCFP FPSR_REG))
13764 (clobber (reg:CCFP FLAGS_REG))
13765 (clobber (match_scratch:HI 4 "=a"))]
13767 && FLOAT_MODE_P (GET_MODE (operands[1]))
13768 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13769 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13772 (define_insn "*fp_jcc_7_387"
13774 (if_then_else (match_operator 0 "comparison_operator"
13775 [(match_operand 1 "register_operand" "f")
13776 (match_operand 2 "const0_operand" "X")])
13777 (label_ref (match_operand 3 "" ""))
13779 (clobber (reg:CCFP FPSR_REG))
13780 (clobber (reg:CCFP FLAGS_REG))
13781 (clobber (match_scratch:HI 4 "=a"))]
13783 && FLOAT_MODE_P (GET_MODE (operands[1]))
13784 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13785 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13786 && SELECT_CC_MODE (GET_CODE (operands[0]),
13787 operands[1], operands[2]) == CCFPmode
13788 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13791 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13792 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13793 ;; with a precedence over other operators and is always put in the first
13794 ;; place. Swap condition and operands to match ficom instruction.
13796 (define_insn "*fp_jcc_8<mode>_387"
13798 (if_then_else (match_operator 0 "comparison_operator"
13799 [(match_operator 1 "float_operator"
13800 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13801 (match_operand 3 "register_operand" "f,f")])
13802 (label_ref (match_operand 4 "" ""))
13804 (clobber (reg:CCFP FPSR_REG))
13805 (clobber (reg:CCFP FLAGS_REG))
13806 (clobber (match_scratch:HI 5 "=a,a"))]
13807 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13808 && FLOAT_MODE_P (GET_MODE (operands[3]))
13809 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13810 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13811 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13812 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13817 (if_then_else (match_operator 0 "comparison_operator"
13818 [(match_operand 1 "register_operand" "")
13819 (match_operand 2 "nonimmediate_operand" "")])
13820 (match_operand 3 "" "")
13821 (match_operand 4 "" "")))
13822 (clobber (reg:CCFP FPSR_REG))
13823 (clobber (reg:CCFP FLAGS_REG))]
13827 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13828 operands[3], operands[4], NULL_RTX, NULL_RTX);
13834 (if_then_else (match_operator 0 "comparison_operator"
13835 [(match_operand 1 "register_operand" "")
13836 (match_operand 2 "general_operand" "")])
13837 (match_operand 3 "" "")
13838 (match_operand 4 "" "")))
13839 (clobber (reg:CCFP FPSR_REG))
13840 (clobber (reg:CCFP FLAGS_REG))
13841 (clobber (match_scratch:HI 5 "=a"))]
13845 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13846 operands[3], operands[4], operands[5], NULL_RTX);
13852 (if_then_else (match_operator 0 "comparison_operator"
13853 [(match_operator 1 "float_operator"
13854 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13855 (match_operand 3 "register_operand" "")])
13856 (match_operand 4 "" "")
13857 (match_operand 5 "" "")))
13858 (clobber (reg:CCFP FPSR_REG))
13859 (clobber (reg:CCFP FLAGS_REG))
13860 (clobber (match_scratch:HI 6 "=a"))]
13864 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13865 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13866 operands[3], operands[7],
13867 operands[4], operands[5], operands[6], NULL_RTX);
13871 ;; %%% Kill this when reload knows how to do it.
13874 (if_then_else (match_operator 0 "comparison_operator"
13875 [(match_operator 1 "float_operator"
13876 [(match_operand:X87MODEI12 2 "register_operand" "")])
13877 (match_operand 3 "register_operand" "")])
13878 (match_operand 4 "" "")
13879 (match_operand 5 "" "")))
13880 (clobber (reg:CCFP FPSR_REG))
13881 (clobber (reg:CCFP FLAGS_REG))
13882 (clobber (match_scratch:HI 6 "=a"))]
13886 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13887 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13888 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13889 operands[3], operands[7],
13890 operands[4], operands[5], operands[6], operands[2]);
13894 ;; Unconditional and other jump instructions
13896 (define_insn "jump"
13898 (label_ref (match_operand 0 "" "")))]
13901 [(set_attr "type" "ibr")
13902 (set (attr "length")
13903 (if_then_else (and (ge (minus (match_dup 0) (pc))
13905 (lt (minus (match_dup 0) (pc))
13909 (set_attr "modrm" "0")])
13911 (define_expand "indirect_jump"
13912 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13916 (define_insn "*indirect_jump"
13917 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13920 [(set_attr "type" "ibr")
13921 (set_attr "length_immediate" "0")])
13923 (define_insn "*indirect_jump_rtx64"
13924 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13927 [(set_attr "type" "ibr")
13928 (set_attr "length_immediate" "0")])
13930 (define_expand "tablejump"
13931 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13932 (use (label_ref (match_operand 1 "" "")))])]
13935 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13936 relative. Convert the relative address to an absolute address. */
13940 enum rtx_code code;
13946 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13948 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13952 op1 = pic_offset_table_rtx;
13957 op0 = pic_offset_table_rtx;
13961 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13966 (define_insn "*tablejump_1"
13967 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
13968 (use (label_ref (match_operand 1 "" "")))]
13971 [(set_attr "type" "ibr")
13972 (set_attr "length_immediate" "0")])
13974 (define_insn "*tablejump_1_rtx64"
13975 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
13976 (use (label_ref (match_operand 1 "" "")))]
13979 [(set_attr "type" "ibr")
13980 (set_attr "length_immediate" "0")])
13982 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13985 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13986 (set (match_operand:QI 1 "register_operand" "")
13987 (match_operator:QI 2 "ix86_comparison_operator"
13988 [(reg FLAGS_REG) (const_int 0)]))
13989 (set (match_operand 3 "q_regs_operand" "")
13990 (zero_extend (match_dup 1)))]
13991 "(peep2_reg_dead_p (3, operands[1])
13992 || operands_match_p (operands[1], operands[3]))
13993 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13994 [(set (match_dup 4) (match_dup 0))
13995 (set (strict_low_part (match_dup 5))
13998 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13999 operands[5] = gen_lowpart (QImode, operands[3]);
14000 ix86_expand_clear (operands[3]);
14003 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14006 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14007 (set (match_operand:QI 1 "register_operand" "")
14008 (match_operator:QI 2 "ix86_comparison_operator"
14009 [(reg FLAGS_REG) (const_int 0)]))
14010 (parallel [(set (match_operand 3 "q_regs_operand" "")
14011 (zero_extend (match_dup 1)))
14012 (clobber (reg:CC FLAGS_REG))])]
14013 "(peep2_reg_dead_p (3, operands[1])
14014 || operands_match_p (operands[1], operands[3]))
14015 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14016 [(set (match_dup 4) (match_dup 0))
14017 (set (strict_low_part (match_dup 5))
14020 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14021 operands[5] = gen_lowpart (QImode, operands[3]);
14022 ix86_expand_clear (operands[3]);
14025 ;; Call instructions.
14027 ;; The predicates normally associated with named expanders are not properly
14028 ;; checked for calls. This is a bug in the generic code, but it isn't that
14029 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14031 ;; Call subroutine returning no value.
14033 (define_expand "call_pop"
14034 [(parallel [(call (match_operand:QI 0 "" "")
14035 (match_operand:SI 1 "" ""))
14036 (set (reg:SI SP_REG)
14037 (plus:SI (reg:SI SP_REG)
14038 (match_operand:SI 3 "" "")))])]
14041 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14045 (define_insn "*call_pop_0"
14046 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14047 (match_operand:SI 1 "" ""))
14048 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14049 (match_operand:SI 2 "immediate_operand" "")))]
14052 if (SIBLING_CALL_P (insn))
14055 return "call\t%P0";
14057 [(set_attr "type" "call")])
14059 (define_insn "*call_pop_1"
14060 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14061 (match_operand:SI 1 "" ""))
14062 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14063 (match_operand:SI 2 "immediate_operand" "i")))]
14066 if (constant_call_address_operand (operands[0], Pmode))
14068 if (SIBLING_CALL_P (insn))
14071 return "call\t%P0";
14073 if (SIBLING_CALL_P (insn))
14076 return "call\t%A0";
14078 [(set_attr "type" "call")])
14080 (define_expand "call"
14081 [(call (match_operand:QI 0 "" "")
14082 (match_operand 1 "" ""))
14083 (use (match_operand 2 "" ""))]
14086 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14090 (define_expand "sibcall"
14091 [(call (match_operand:QI 0 "" "")
14092 (match_operand 1 "" ""))
14093 (use (match_operand 2 "" ""))]
14096 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14100 (define_insn "*call_0"
14101 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14102 (match_operand 1 "" ""))]
14105 if (SIBLING_CALL_P (insn))
14108 return "call\t%P0";
14110 [(set_attr "type" "call")])
14112 (define_insn "*call_1"
14113 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14114 (match_operand 1 "" ""))]
14115 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14117 if (constant_call_address_operand (operands[0], Pmode))
14118 return "call\t%P0";
14119 return "call\t%A0";
14121 [(set_attr "type" "call")])
14123 (define_insn "*sibcall_1"
14124 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14125 (match_operand 1 "" ""))]
14126 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14128 if (constant_call_address_operand (operands[0], Pmode))
14132 [(set_attr "type" "call")])
14134 (define_insn "*call_1_rex64"
14135 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14136 (match_operand 1 "" ""))]
14137 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14139 if (constant_call_address_operand (operands[0], Pmode))
14140 return "call\t%P0";
14141 return "call\t%A0";
14143 [(set_attr "type" "call")])
14145 (define_insn "*sibcall_1_rex64"
14146 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14147 (match_operand 1 "" ""))]
14148 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14150 [(set_attr "type" "call")])
14152 (define_insn "*sibcall_1_rex64_v"
14153 [(call (mem:QI (reg:DI 40))
14154 (match_operand 0 "" ""))]
14155 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14157 [(set_attr "type" "call")])
14160 ;; Call subroutine, returning value in operand 0
14162 (define_expand "call_value_pop"
14163 [(parallel [(set (match_operand 0 "" "")
14164 (call (match_operand:QI 1 "" "")
14165 (match_operand:SI 2 "" "")))
14166 (set (reg:SI SP_REG)
14167 (plus:SI (reg:SI SP_REG)
14168 (match_operand:SI 4 "" "")))])]
14171 ix86_expand_call (operands[0], operands[1], operands[2],
14172 operands[3], operands[4], 0);
14176 (define_expand "call_value"
14177 [(set (match_operand 0 "" "")
14178 (call (match_operand:QI 1 "" "")
14179 (match_operand:SI 2 "" "")))
14180 (use (match_operand:SI 3 "" ""))]
14181 ;; Operand 2 not used on the i386.
14184 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14188 (define_expand "sibcall_value"
14189 [(set (match_operand 0 "" "")
14190 (call (match_operand:QI 1 "" "")
14191 (match_operand:SI 2 "" "")))
14192 (use (match_operand:SI 3 "" ""))]
14193 ;; Operand 2 not used on the i386.
14196 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14200 ;; Call subroutine returning any type.
14202 (define_expand "untyped_call"
14203 [(parallel [(call (match_operand 0 "" "")
14205 (match_operand 1 "" "")
14206 (match_operand 2 "" "")])]
14211 /* In order to give reg-stack an easier job in validating two
14212 coprocessor registers as containing a possible return value,
14213 simply pretend the untyped call returns a complex long double
14216 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14217 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14218 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14221 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14223 rtx set = XVECEXP (operands[2], 0, i);
14224 emit_move_insn (SET_DEST (set), SET_SRC (set));
14227 /* The optimizer does not know that the call sets the function value
14228 registers we stored in the result block. We avoid problems by
14229 claiming that all hard registers are used and clobbered at this
14231 emit_insn (gen_blockage (const0_rtx));
14236 ;; Prologue and epilogue instructions
14238 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14239 ;; all of memory. This blocks insns from being moved across this point.
14241 (define_insn "blockage"
14242 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14245 [(set_attr "length" "0")])
14247 ;; Insn emitted into the body of a function to return from a function.
14248 ;; This is only done if the function's epilogue is known to be simple.
14249 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14251 (define_expand "return"
14253 "ix86_can_use_return_insn_p ()"
14255 if (current_function_pops_args)
14257 rtx popc = GEN_INT (current_function_pops_args);
14258 emit_jump_insn (gen_return_pop_internal (popc));
14263 (define_insn "return_internal"
14267 [(set_attr "length" "1")
14268 (set_attr "length_immediate" "0")
14269 (set_attr "modrm" "0")])
14271 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14272 ;; instruction Athlon and K8 have.
14274 (define_insn "return_internal_long"
14276 (unspec [(const_int 0)] UNSPEC_REP)]
14279 [(set_attr "length" "1")
14280 (set_attr "length_immediate" "0")
14281 (set_attr "prefix_rep" "1")
14282 (set_attr "modrm" "0")])
14284 (define_insn "return_pop_internal"
14286 (use (match_operand:SI 0 "const_int_operand" ""))]
14289 [(set_attr "length" "3")
14290 (set_attr "length_immediate" "2")
14291 (set_attr "modrm" "0")])
14293 (define_insn "return_indirect_internal"
14295 (use (match_operand:SI 0 "register_operand" "r"))]
14298 [(set_attr "type" "ibr")
14299 (set_attr "length_immediate" "0")])
14305 [(set_attr "length" "1")
14306 (set_attr "length_immediate" "0")
14307 (set_attr "modrm" "0")])
14309 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14310 ;; branch prediction penalty for the third jump in a 16-byte
14313 (define_insn "align"
14314 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14317 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14318 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14320 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14321 The align insn is used to avoid 3 jump instructions in the row to improve
14322 branch prediction and the benefits hardly outweigh the cost of extra 8
14323 nops on the average inserted by full alignment pseudo operation. */
14327 [(set_attr "length" "16")])
14329 (define_expand "prologue"
14332 "ix86_expand_prologue (); DONE;")
14334 (define_insn "set_got"
14335 [(set (match_operand:SI 0 "register_operand" "=r")
14336 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14337 (clobber (reg:CC FLAGS_REG))]
14339 { return output_set_got (operands[0], NULL_RTX); }
14340 [(set_attr "type" "multi")
14341 (set_attr "length" "12")])
14343 (define_insn "set_got_labelled"
14344 [(set (match_operand:SI 0 "register_operand" "=r")
14345 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14347 (clobber (reg:CC FLAGS_REG))]
14349 { return output_set_got (operands[0], operands[1]); }
14350 [(set_attr "type" "multi")
14351 (set_attr "length" "12")])
14353 (define_insn "set_got_rex64"
14354 [(set (match_operand:DI 0 "register_operand" "=r")
14355 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14357 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14358 [(set_attr "type" "lea")
14359 (set_attr "length" "6")])
14361 (define_expand "epilogue"
14364 "ix86_expand_epilogue (1); DONE;")
14366 (define_expand "sibcall_epilogue"
14369 "ix86_expand_epilogue (0); DONE;")
14371 (define_expand "eh_return"
14372 [(use (match_operand 0 "register_operand" ""))]
14375 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14377 /* Tricky bit: we write the address of the handler to which we will
14378 be returning into someone else's stack frame, one word below the
14379 stack address we wish to restore. */
14380 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14381 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14382 tmp = gen_rtx_MEM (Pmode, tmp);
14383 emit_move_insn (tmp, ra);
14385 if (Pmode == SImode)
14386 emit_jump_insn (gen_eh_return_si (sa));
14388 emit_jump_insn (gen_eh_return_di (sa));
14393 (define_insn_and_split "eh_return_si"
14395 (unspec [(match_operand:SI 0 "register_operand" "c")]
14396 UNSPEC_EH_RETURN))]
14401 "ix86_expand_epilogue (2); DONE;")
14403 (define_insn_and_split "eh_return_di"
14405 (unspec [(match_operand:DI 0 "register_operand" "c")]
14406 UNSPEC_EH_RETURN))]
14411 "ix86_expand_epilogue (2); DONE;")
14413 (define_insn "leave"
14414 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14415 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14416 (clobber (mem:BLK (scratch)))]
14419 [(set_attr "type" "leave")])
14421 (define_insn "leave_rex64"
14422 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14423 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14424 (clobber (mem:BLK (scratch)))]
14427 [(set_attr "type" "leave")])
14429 (define_expand "ffssi2"
14431 [(set (match_operand:SI 0 "register_operand" "")
14432 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14433 (clobber (match_scratch:SI 2 ""))
14434 (clobber (reg:CC FLAGS_REG))])]
14438 (define_insn_and_split "*ffs_cmove"
14439 [(set (match_operand:SI 0 "register_operand" "=r")
14440 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14441 (clobber (match_scratch:SI 2 "=&r"))
14442 (clobber (reg:CC FLAGS_REG))]
14445 "&& reload_completed"
14446 [(set (match_dup 2) (const_int -1))
14447 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14448 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14449 (set (match_dup 0) (if_then_else:SI
14450 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14453 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14454 (clobber (reg:CC FLAGS_REG))])]
14457 (define_insn_and_split "*ffs_no_cmove"
14458 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14459 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14460 (clobber (match_scratch:SI 2 "=&q"))
14461 (clobber (reg:CC FLAGS_REG))]
14465 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14466 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14467 (set (strict_low_part (match_dup 3))
14468 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14469 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14470 (clobber (reg:CC FLAGS_REG))])
14471 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14472 (clobber (reg:CC FLAGS_REG))])
14473 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14474 (clobber (reg:CC FLAGS_REG))])]
14476 operands[3] = gen_lowpart (QImode, operands[2]);
14477 ix86_expand_clear (operands[2]);
14480 (define_insn "*ffssi_1"
14481 [(set (reg:CCZ FLAGS_REG)
14482 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14484 (set (match_operand:SI 0 "register_operand" "=r")
14485 (ctz:SI (match_dup 1)))]
14487 "bsf{l}\t{%1, %0|%0, %1}"
14488 [(set_attr "prefix_0f" "1")])
14490 (define_expand "ffsdi2"
14492 [(set (match_operand:DI 0 "register_operand" "")
14493 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14494 (clobber (match_scratch:DI 2 ""))
14495 (clobber (reg:CC FLAGS_REG))])]
14496 "TARGET_64BIT && TARGET_CMOVE"
14499 (define_insn_and_split "*ffs_rex64"
14500 [(set (match_operand:DI 0 "register_operand" "=r")
14501 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14502 (clobber (match_scratch:DI 2 "=&r"))
14503 (clobber (reg:CC FLAGS_REG))]
14504 "TARGET_64BIT && TARGET_CMOVE"
14506 "&& reload_completed"
14507 [(set (match_dup 2) (const_int -1))
14508 (parallel [(set (reg:CCZ FLAGS_REG)
14509 (compare:CCZ (match_dup 1) (const_int 0)))
14510 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14511 (set (match_dup 0) (if_then_else:DI
14512 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14515 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14516 (clobber (reg:CC FLAGS_REG))])]
14519 (define_insn "*ffsdi_1"
14520 [(set (reg:CCZ FLAGS_REG)
14521 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14523 (set (match_operand:DI 0 "register_operand" "=r")
14524 (ctz:DI (match_dup 1)))]
14526 "bsf{q}\t{%1, %0|%0, %1}"
14527 [(set_attr "prefix_0f" "1")])
14529 (define_insn "ctzsi2"
14530 [(set (match_operand:SI 0 "register_operand" "=r")
14531 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14532 (clobber (reg:CC FLAGS_REG))]
14534 "bsf{l}\t{%1, %0|%0, %1}"
14535 [(set_attr "prefix_0f" "1")])
14537 (define_insn "ctzdi2"
14538 [(set (match_operand:DI 0 "register_operand" "=r")
14539 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14540 (clobber (reg:CC FLAGS_REG))]
14542 "bsf{q}\t{%1, %0|%0, %1}"
14543 [(set_attr "prefix_0f" "1")])
14545 (define_expand "clzsi2"
14547 [(set (match_operand:SI 0 "register_operand" "")
14548 (minus:SI (const_int 31)
14549 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14550 (clobber (reg:CC FLAGS_REG))])
14552 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14553 (clobber (reg:CC FLAGS_REG))])]
14557 (define_insn "*bsr"
14558 [(set (match_operand:SI 0 "register_operand" "=r")
14559 (minus:SI (const_int 31)
14560 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14561 (clobber (reg:CC FLAGS_REG))]
14563 "bsr{l}\t{%1, %0|%0, %1}"
14564 [(set_attr "prefix_0f" "1")])
14566 (define_expand "clzdi2"
14568 [(set (match_operand:DI 0 "register_operand" "")
14569 (minus:DI (const_int 63)
14570 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14571 (clobber (reg:CC FLAGS_REG))])
14573 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14574 (clobber (reg:CC FLAGS_REG))])]
14578 (define_insn "*bsr_rex64"
14579 [(set (match_operand:DI 0 "register_operand" "=r")
14580 (minus:DI (const_int 63)
14581 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14582 (clobber (reg:CC FLAGS_REG))]
14584 "bsr{q}\t{%1, %0|%0, %1}"
14585 [(set_attr "prefix_0f" "1")])
14587 ;; Thread-local storage patterns for ELF.
14589 ;; Note that these code sequences must appear exactly as shown
14590 ;; in order to allow linker relaxation.
14592 (define_insn "*tls_global_dynamic_32_gnu"
14593 [(set (match_operand:SI 0 "register_operand" "=a")
14594 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14595 (match_operand:SI 2 "tls_symbolic_operand" "")
14596 (match_operand:SI 3 "call_insn_operand" "")]
14598 (clobber (match_scratch:SI 4 "=d"))
14599 (clobber (match_scratch:SI 5 "=c"))
14600 (clobber (reg:CC FLAGS_REG))]
14601 "!TARGET_64BIT && TARGET_GNU_TLS"
14602 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14603 [(set_attr "type" "multi")
14604 (set_attr "length" "12")])
14606 (define_insn "*tls_global_dynamic_32_sun"
14607 [(set (match_operand:SI 0 "register_operand" "=a")
14608 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14609 (match_operand:SI 2 "tls_symbolic_operand" "")
14610 (match_operand:SI 3 "call_insn_operand" "")]
14612 (clobber (match_scratch:SI 4 "=d"))
14613 (clobber (match_scratch:SI 5 "=c"))
14614 (clobber (reg:CC FLAGS_REG))]
14615 "!TARGET_64BIT && TARGET_SUN_TLS"
14616 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14617 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14618 [(set_attr "type" "multi")
14619 (set_attr "length" "14")])
14621 (define_expand "tls_global_dynamic_32"
14622 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14625 (match_operand:SI 1 "tls_symbolic_operand" "")
14628 (clobber (match_scratch:SI 4 ""))
14629 (clobber (match_scratch:SI 5 ""))
14630 (clobber (reg:CC FLAGS_REG))])]
14634 operands[2] = pic_offset_table_rtx;
14637 operands[2] = gen_reg_rtx (Pmode);
14638 emit_insn (gen_set_got (operands[2]));
14640 if (TARGET_GNU2_TLS)
14642 emit_insn (gen_tls_dynamic_gnu2_32
14643 (operands[0], operands[1], operands[2]));
14646 operands[3] = ix86_tls_get_addr ();
14649 (define_insn "*tls_global_dynamic_64"
14650 [(set (match_operand:DI 0 "register_operand" "=a")
14651 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14652 (match_operand:DI 3 "" "")))
14653 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14656 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14657 [(set_attr "type" "multi")
14658 (set_attr "length" "16")])
14660 (define_expand "tls_global_dynamic_64"
14661 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14662 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14663 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14667 if (TARGET_GNU2_TLS)
14669 emit_insn (gen_tls_dynamic_gnu2_64
14670 (operands[0], operands[1]));
14673 operands[2] = ix86_tls_get_addr ();
14676 (define_insn "*tls_local_dynamic_base_32_gnu"
14677 [(set (match_operand:SI 0 "register_operand" "=a")
14678 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14679 (match_operand:SI 2 "call_insn_operand" "")]
14680 UNSPEC_TLS_LD_BASE))
14681 (clobber (match_scratch:SI 3 "=d"))
14682 (clobber (match_scratch:SI 4 "=c"))
14683 (clobber (reg:CC FLAGS_REG))]
14684 "!TARGET_64BIT && TARGET_GNU_TLS"
14685 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14686 [(set_attr "type" "multi")
14687 (set_attr "length" "11")])
14689 (define_insn "*tls_local_dynamic_base_32_sun"
14690 [(set (match_operand:SI 0 "register_operand" "=a")
14691 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14692 (match_operand:SI 2 "call_insn_operand" "")]
14693 UNSPEC_TLS_LD_BASE))
14694 (clobber (match_scratch:SI 3 "=d"))
14695 (clobber (match_scratch:SI 4 "=c"))
14696 (clobber (reg:CC FLAGS_REG))]
14697 "!TARGET_64BIT && TARGET_SUN_TLS"
14698 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14699 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14700 [(set_attr "type" "multi")
14701 (set_attr "length" "13")])
14703 (define_expand "tls_local_dynamic_base_32"
14704 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14705 (unspec:SI [(match_dup 1) (match_dup 2)]
14706 UNSPEC_TLS_LD_BASE))
14707 (clobber (match_scratch:SI 3 ""))
14708 (clobber (match_scratch:SI 4 ""))
14709 (clobber (reg:CC FLAGS_REG))])]
14713 operands[1] = pic_offset_table_rtx;
14716 operands[1] = gen_reg_rtx (Pmode);
14717 emit_insn (gen_set_got (operands[1]));
14719 if (TARGET_GNU2_TLS)
14721 emit_insn (gen_tls_dynamic_gnu2_32
14722 (operands[0], ix86_tls_module_base (), operands[1]));
14725 operands[2] = ix86_tls_get_addr ();
14728 (define_insn "*tls_local_dynamic_base_64"
14729 [(set (match_operand:DI 0 "register_operand" "=a")
14730 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14731 (match_operand:DI 2 "" "")))
14732 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14734 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14735 [(set_attr "type" "multi")
14736 (set_attr "length" "12")])
14738 (define_expand "tls_local_dynamic_base_64"
14739 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14740 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14741 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14744 if (TARGET_GNU2_TLS)
14746 emit_insn (gen_tls_dynamic_gnu2_64
14747 (operands[0], ix86_tls_module_base ()));
14750 operands[1] = ix86_tls_get_addr ();
14753 ;; Local dynamic of a single variable is a lose. Show combine how
14754 ;; to convert that back to global dynamic.
14756 (define_insn_and_split "*tls_local_dynamic_32_once"
14757 [(set (match_operand:SI 0 "register_operand" "=a")
14758 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14759 (match_operand:SI 2 "call_insn_operand" "")]
14760 UNSPEC_TLS_LD_BASE)
14761 (const:SI (unspec:SI
14762 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14764 (clobber (match_scratch:SI 4 "=d"))
14765 (clobber (match_scratch:SI 5 "=c"))
14766 (clobber (reg:CC FLAGS_REG))]
14770 [(parallel [(set (match_dup 0)
14771 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14773 (clobber (match_dup 4))
14774 (clobber (match_dup 5))
14775 (clobber (reg:CC FLAGS_REG))])]
14778 ;; Load and add the thread base pointer from %gs:0.
14780 (define_insn "*load_tp_si"
14781 [(set (match_operand:SI 0 "register_operand" "=r")
14782 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14784 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14785 [(set_attr "type" "imov")
14786 (set_attr "modrm" "0")
14787 (set_attr "length" "7")
14788 (set_attr "memory" "load")
14789 (set_attr "imm_disp" "false")])
14791 (define_insn "*add_tp_si"
14792 [(set (match_operand:SI 0 "register_operand" "=r")
14793 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14794 (match_operand:SI 1 "register_operand" "0")))
14795 (clobber (reg:CC FLAGS_REG))]
14797 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14798 [(set_attr "type" "alu")
14799 (set_attr "modrm" "0")
14800 (set_attr "length" "7")
14801 (set_attr "memory" "load")
14802 (set_attr "imm_disp" "false")])
14804 (define_insn "*load_tp_di"
14805 [(set (match_operand:DI 0 "register_operand" "=r")
14806 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14808 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14809 [(set_attr "type" "imov")
14810 (set_attr "modrm" "0")
14811 (set_attr "length" "7")
14812 (set_attr "memory" "load")
14813 (set_attr "imm_disp" "false")])
14815 (define_insn "*add_tp_di"
14816 [(set (match_operand:DI 0 "register_operand" "=r")
14817 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14818 (match_operand:DI 1 "register_operand" "0")))
14819 (clobber (reg:CC FLAGS_REG))]
14821 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14822 [(set_attr "type" "alu")
14823 (set_attr "modrm" "0")
14824 (set_attr "length" "7")
14825 (set_attr "memory" "load")
14826 (set_attr "imm_disp" "false")])
14828 ;; GNU2 TLS patterns can be split.
14830 (define_expand "tls_dynamic_gnu2_32"
14831 [(set (match_dup 3)
14832 (plus:SI (match_operand:SI 2 "register_operand" "")
14834 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14837 [(set (match_operand:SI 0 "register_operand" "")
14838 (unspec:SI [(match_dup 1) (match_dup 3)
14839 (match_dup 2) (reg:SI SP_REG)]
14841 (clobber (reg:CC FLAGS_REG))])]
14842 "!TARGET_64BIT && TARGET_GNU2_TLS"
14844 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14845 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14848 (define_insn "*tls_dynamic_lea_32"
14849 [(set (match_operand:SI 0 "register_operand" "=r")
14850 (plus:SI (match_operand:SI 1 "register_operand" "b")
14852 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14853 UNSPEC_TLSDESC))))]
14854 "!TARGET_64BIT && TARGET_GNU2_TLS"
14855 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14856 [(set_attr "type" "lea")
14857 (set_attr "mode" "SI")
14858 (set_attr "length" "6")
14859 (set_attr "length_address" "4")])
14861 (define_insn "*tls_dynamic_call_32"
14862 [(set (match_operand:SI 0 "register_operand" "=a")
14863 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14864 (match_operand:SI 2 "register_operand" "0")
14865 ;; we have to make sure %ebx still points to the GOT
14866 (match_operand:SI 3 "register_operand" "b")
14869 (clobber (reg:CC FLAGS_REG))]
14870 "!TARGET_64BIT && TARGET_GNU2_TLS"
14871 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14872 [(set_attr "type" "call")
14873 (set_attr "length" "2")
14874 (set_attr "length_address" "0")])
14876 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14877 [(set (match_operand:SI 0 "register_operand" "=&a")
14879 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14880 (match_operand:SI 4 "" "")
14881 (match_operand:SI 2 "register_operand" "b")
14884 (const:SI (unspec:SI
14885 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14887 (clobber (reg:CC FLAGS_REG))]
14888 "!TARGET_64BIT && TARGET_GNU2_TLS"
14891 [(set (match_dup 0) (match_dup 5))]
14893 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14894 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14897 (define_expand "tls_dynamic_gnu2_64"
14898 [(set (match_dup 2)
14899 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14902 [(set (match_operand:DI 0 "register_operand" "")
14903 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14905 (clobber (reg:CC FLAGS_REG))])]
14906 "TARGET_64BIT && TARGET_GNU2_TLS"
14908 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14909 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14912 (define_insn "*tls_dynamic_lea_64"
14913 [(set (match_operand:DI 0 "register_operand" "=r")
14914 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14916 "TARGET_64BIT && TARGET_GNU2_TLS"
14917 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14918 [(set_attr "type" "lea")
14919 (set_attr "mode" "DI")
14920 (set_attr "length" "7")
14921 (set_attr "length_address" "4")])
14923 (define_insn "*tls_dynamic_call_64"
14924 [(set (match_operand:DI 0 "register_operand" "=a")
14925 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14926 (match_operand:DI 2 "register_operand" "0")
14929 (clobber (reg:CC FLAGS_REG))]
14930 "TARGET_64BIT && TARGET_GNU2_TLS"
14931 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14932 [(set_attr "type" "call")
14933 (set_attr "length" "2")
14934 (set_attr "length_address" "0")])
14936 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14937 [(set (match_operand:DI 0 "register_operand" "=&a")
14939 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14940 (match_operand:DI 3 "" "")
14943 (const:DI (unspec:DI
14944 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14946 (clobber (reg:CC FLAGS_REG))]
14947 "TARGET_64BIT && TARGET_GNU2_TLS"
14950 [(set (match_dup 0) (match_dup 4))]
14952 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14953 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14958 ;; These patterns match the binary 387 instructions for addM3, subM3,
14959 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14960 ;; SFmode. The first is the normal insn, the second the same insn but
14961 ;; with one operand a conversion, and the third the same insn but with
14962 ;; the other operand a conversion. The conversion may be SFmode or
14963 ;; SImode if the target mode DFmode, but only SImode if the target mode
14966 ;; Gcc is slightly more smart about handling normal two address instructions
14967 ;; so use special patterns for add and mull.
14969 (define_insn "*fop_sf_comm_mixed"
14970 [(set (match_operand:SF 0 "register_operand" "=f,x")
14971 (match_operator:SF 3 "binary_fp_operator"
14972 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
14973 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
14974 "TARGET_MIX_SSE_I387
14975 && COMMUTATIVE_ARITH_P (operands[3])
14976 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14977 "* return output_387_binary_op (insn, operands);"
14978 [(set (attr "type")
14979 (if_then_else (eq_attr "alternative" "1")
14980 (if_then_else (match_operand:SF 3 "mult_operator" "")
14981 (const_string "ssemul")
14982 (const_string "sseadd"))
14983 (if_then_else (match_operand:SF 3 "mult_operator" "")
14984 (const_string "fmul")
14985 (const_string "fop"))))
14986 (set_attr "mode" "SF")])
14988 (define_insn "*fop_sf_comm_sse"
14989 [(set (match_operand:SF 0 "register_operand" "=x")
14990 (match_operator:SF 3 "binary_fp_operator"
14991 [(match_operand:SF 1 "nonimmediate_operand" "%0")
14992 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
14994 && COMMUTATIVE_ARITH_P (operands[3])
14995 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
14996 "* return output_387_binary_op (insn, operands);"
14997 [(set (attr "type")
14998 (if_then_else (match_operand:SF 3 "mult_operator" "")
14999 (const_string "ssemul")
15000 (const_string "sseadd")))
15001 (set_attr "mode" "SF")])
15003 (define_insn "*fop_sf_comm_i387"
15004 [(set (match_operand:SF 0 "register_operand" "=f")
15005 (match_operator:SF 3 "binary_fp_operator"
15006 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15007 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15009 && COMMUTATIVE_ARITH_P (operands[3])
15010 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15011 "* return output_387_binary_op (insn, operands);"
15012 [(set (attr "type")
15013 (if_then_else (match_operand:SF 3 "mult_operator" "")
15014 (const_string "fmul")
15015 (const_string "fop")))
15016 (set_attr "mode" "SF")])
15018 (define_insn "*fop_sf_1_mixed"
15019 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15020 (match_operator:SF 3 "binary_fp_operator"
15021 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15022 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15023 "TARGET_MIX_SSE_I387
15024 && !COMMUTATIVE_ARITH_P (operands[3])
15025 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15026 "* return output_387_binary_op (insn, operands);"
15027 [(set (attr "type")
15028 (cond [(and (eq_attr "alternative" "2")
15029 (match_operand:SF 3 "mult_operator" ""))
15030 (const_string "ssemul")
15031 (and (eq_attr "alternative" "2")
15032 (match_operand:SF 3 "div_operator" ""))
15033 (const_string "ssediv")
15034 (eq_attr "alternative" "2")
15035 (const_string "sseadd")
15036 (match_operand:SF 3 "mult_operator" "")
15037 (const_string "fmul")
15038 (match_operand:SF 3 "div_operator" "")
15039 (const_string "fdiv")
15041 (const_string "fop")))
15042 (set_attr "mode" "SF")])
15044 (define_insn "*fop_sf_1_sse"
15045 [(set (match_operand:SF 0 "register_operand" "=x")
15046 (match_operator:SF 3 "binary_fp_operator"
15047 [(match_operand:SF 1 "register_operand" "0")
15048 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15050 && !COMMUTATIVE_ARITH_P (operands[3])"
15051 "* return output_387_binary_op (insn, operands);"
15052 [(set (attr "type")
15053 (cond [(match_operand:SF 3 "mult_operator" "")
15054 (const_string "ssemul")
15055 (match_operand:SF 3 "div_operator" "")
15056 (const_string "ssediv")
15058 (const_string "sseadd")))
15059 (set_attr "mode" "SF")])
15061 ;; This pattern is not fully shadowed by the pattern above.
15062 (define_insn "*fop_sf_1_i387"
15063 [(set (match_operand:SF 0 "register_operand" "=f,f")
15064 (match_operator:SF 3 "binary_fp_operator"
15065 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15066 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15067 "TARGET_80387 && !TARGET_SSE_MATH
15068 && !COMMUTATIVE_ARITH_P (operands[3])
15069 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15070 "* return output_387_binary_op (insn, operands);"
15071 [(set (attr "type")
15072 (cond [(match_operand:SF 3 "mult_operator" "")
15073 (const_string "fmul")
15074 (match_operand:SF 3 "div_operator" "")
15075 (const_string "fdiv")
15077 (const_string "fop")))
15078 (set_attr "mode" "SF")])
15080 ;; ??? Add SSE splitters for these!
15081 (define_insn "*fop_sf_2<mode>_i387"
15082 [(set (match_operand:SF 0 "register_operand" "=f,f")
15083 (match_operator:SF 3 "binary_fp_operator"
15084 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15085 (match_operand:SF 2 "register_operand" "0,0")]))]
15086 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15087 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15088 [(set (attr "type")
15089 (cond [(match_operand:SF 3 "mult_operator" "")
15090 (const_string "fmul")
15091 (match_operand:SF 3 "div_operator" "")
15092 (const_string "fdiv")
15094 (const_string "fop")))
15095 (set_attr "fp_int_src" "true")
15096 (set_attr "mode" "<MODE>")])
15098 (define_insn "*fop_sf_3<mode>_i387"
15099 [(set (match_operand:SF 0 "register_operand" "=f,f")
15100 (match_operator:SF 3 "binary_fp_operator"
15101 [(match_operand:SF 1 "register_operand" "0,0")
15102 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15103 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15104 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15105 [(set (attr "type")
15106 (cond [(match_operand:SF 3 "mult_operator" "")
15107 (const_string "fmul")
15108 (match_operand:SF 3 "div_operator" "")
15109 (const_string "fdiv")
15111 (const_string "fop")))
15112 (set_attr "fp_int_src" "true")
15113 (set_attr "mode" "<MODE>")])
15115 (define_insn "*fop_df_comm_mixed"
15116 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15117 (match_operator:DF 3 "binary_fp_operator"
15118 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15119 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15120 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15121 && COMMUTATIVE_ARITH_P (operands[3])
15122 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15123 "* return output_387_binary_op (insn, operands);"
15124 [(set (attr "type")
15125 (if_then_else (eq_attr "alternative" "1")
15126 (if_then_else (match_operand:DF 3 "mult_operator" "")
15127 (const_string "ssemul")
15128 (const_string "sseadd"))
15129 (if_then_else (match_operand:DF 3 "mult_operator" "")
15130 (const_string "fmul")
15131 (const_string "fop"))))
15132 (set_attr "mode" "DF")])
15134 (define_insn "*fop_df_comm_sse"
15135 [(set (match_operand:DF 0 "register_operand" "=Y")
15136 (match_operator:DF 3 "binary_fp_operator"
15137 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15138 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15139 "TARGET_SSE2 && TARGET_SSE_MATH
15140 && COMMUTATIVE_ARITH_P (operands[3])
15141 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15142 "* return output_387_binary_op (insn, operands);"
15143 [(set (attr "type")
15144 (if_then_else (match_operand:DF 3 "mult_operator" "")
15145 (const_string "ssemul")
15146 (const_string "sseadd")))
15147 (set_attr "mode" "DF")])
15149 (define_insn "*fop_df_comm_i387"
15150 [(set (match_operand:DF 0 "register_operand" "=f")
15151 (match_operator:DF 3 "binary_fp_operator"
15152 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15153 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15155 && COMMUTATIVE_ARITH_P (operands[3])
15156 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15157 "* return output_387_binary_op (insn, operands);"
15158 [(set (attr "type")
15159 (if_then_else (match_operand:DF 3 "mult_operator" "")
15160 (const_string "fmul")
15161 (const_string "fop")))
15162 (set_attr "mode" "DF")])
15164 (define_insn "*fop_df_1_mixed"
15165 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15166 (match_operator:DF 3 "binary_fp_operator"
15167 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15168 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15169 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15170 && !COMMUTATIVE_ARITH_P (operands[3])
15171 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15172 "* return output_387_binary_op (insn, operands);"
15173 [(set (attr "type")
15174 (cond [(and (eq_attr "alternative" "2")
15175 (match_operand:DF 3 "mult_operator" ""))
15176 (const_string "ssemul")
15177 (and (eq_attr "alternative" "2")
15178 (match_operand:DF 3 "div_operator" ""))
15179 (const_string "ssediv")
15180 (eq_attr "alternative" "2")
15181 (const_string "sseadd")
15182 (match_operand:DF 3 "mult_operator" "")
15183 (const_string "fmul")
15184 (match_operand:DF 3 "div_operator" "")
15185 (const_string "fdiv")
15187 (const_string "fop")))
15188 (set_attr "mode" "DF")])
15190 (define_insn "*fop_df_1_sse"
15191 [(set (match_operand:DF 0 "register_operand" "=Y")
15192 (match_operator:DF 3 "binary_fp_operator"
15193 [(match_operand:DF 1 "register_operand" "0")
15194 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15195 "TARGET_SSE2 && TARGET_SSE_MATH
15196 && !COMMUTATIVE_ARITH_P (operands[3])"
15197 "* return output_387_binary_op (insn, operands);"
15198 [(set_attr "mode" "DF")
15200 (cond [(match_operand:DF 3 "mult_operator" "")
15201 (const_string "ssemul")
15202 (match_operand:DF 3 "div_operator" "")
15203 (const_string "ssediv")
15205 (const_string "sseadd")))])
15207 ;; This pattern is not fully shadowed by the pattern above.
15208 (define_insn "*fop_df_1_i387"
15209 [(set (match_operand:DF 0 "register_operand" "=f,f")
15210 (match_operator:DF 3 "binary_fp_operator"
15211 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15212 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15213 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15214 && !COMMUTATIVE_ARITH_P (operands[3])
15215 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15216 "* return output_387_binary_op (insn, operands);"
15217 [(set (attr "type")
15218 (cond [(match_operand:DF 3 "mult_operator" "")
15219 (const_string "fmul")
15220 (match_operand:DF 3 "div_operator" "")
15221 (const_string "fdiv")
15223 (const_string "fop")))
15224 (set_attr "mode" "DF")])
15226 ;; ??? Add SSE splitters for these!
15227 (define_insn "*fop_df_2<mode>_i387"
15228 [(set (match_operand:DF 0 "register_operand" "=f,f")
15229 (match_operator:DF 3 "binary_fp_operator"
15230 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15231 (match_operand:DF 2 "register_operand" "0,0")]))]
15232 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15233 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15234 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15235 [(set (attr "type")
15236 (cond [(match_operand:DF 3 "mult_operator" "")
15237 (const_string "fmul")
15238 (match_operand:DF 3 "div_operator" "")
15239 (const_string "fdiv")
15241 (const_string "fop")))
15242 (set_attr "fp_int_src" "true")
15243 (set_attr "mode" "<MODE>")])
15245 (define_insn "*fop_df_3<mode>_i387"
15246 [(set (match_operand:DF 0 "register_operand" "=f,f")
15247 (match_operator:DF 3 "binary_fp_operator"
15248 [(match_operand:DF 1 "register_operand" "0,0")
15249 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15250 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15251 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15252 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15253 [(set (attr "type")
15254 (cond [(match_operand:DF 3 "mult_operator" "")
15255 (const_string "fmul")
15256 (match_operand:DF 3 "div_operator" "")
15257 (const_string "fdiv")
15259 (const_string "fop")))
15260 (set_attr "fp_int_src" "true")
15261 (set_attr "mode" "<MODE>")])
15263 (define_insn "*fop_df_4_i387"
15264 [(set (match_operand:DF 0 "register_operand" "=f,f")
15265 (match_operator:DF 3 "binary_fp_operator"
15266 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15267 (match_operand:DF 2 "register_operand" "0,f")]))]
15268 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15269 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15270 "* return output_387_binary_op (insn, operands);"
15271 [(set (attr "type")
15272 (cond [(match_operand:DF 3 "mult_operator" "")
15273 (const_string "fmul")
15274 (match_operand:DF 3 "div_operator" "")
15275 (const_string "fdiv")
15277 (const_string "fop")))
15278 (set_attr "mode" "SF")])
15280 (define_insn "*fop_df_5_i387"
15281 [(set (match_operand:DF 0 "register_operand" "=f,f")
15282 (match_operator:DF 3 "binary_fp_operator"
15283 [(match_operand:DF 1 "register_operand" "0,f")
15285 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15286 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15287 "* return output_387_binary_op (insn, operands);"
15288 [(set (attr "type")
15289 (cond [(match_operand:DF 3 "mult_operator" "")
15290 (const_string "fmul")
15291 (match_operand:DF 3 "div_operator" "")
15292 (const_string "fdiv")
15294 (const_string "fop")))
15295 (set_attr "mode" "SF")])
15297 (define_insn "*fop_df_6_i387"
15298 [(set (match_operand:DF 0 "register_operand" "=f,f")
15299 (match_operator:DF 3 "binary_fp_operator"
15301 (match_operand:SF 1 "register_operand" "0,f"))
15303 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15304 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15305 "* return output_387_binary_op (insn, operands);"
15306 [(set (attr "type")
15307 (cond [(match_operand:DF 3 "mult_operator" "")
15308 (const_string "fmul")
15309 (match_operand:DF 3 "div_operator" "")
15310 (const_string "fdiv")
15312 (const_string "fop")))
15313 (set_attr "mode" "SF")])
15315 (define_insn "*fop_xf_comm_i387"
15316 [(set (match_operand:XF 0 "register_operand" "=f")
15317 (match_operator:XF 3 "binary_fp_operator"
15318 [(match_operand:XF 1 "register_operand" "%0")
15319 (match_operand:XF 2 "register_operand" "f")]))]
15321 && COMMUTATIVE_ARITH_P (operands[3])"
15322 "* return output_387_binary_op (insn, operands);"
15323 [(set (attr "type")
15324 (if_then_else (match_operand:XF 3 "mult_operator" "")
15325 (const_string "fmul")
15326 (const_string "fop")))
15327 (set_attr "mode" "XF")])
15329 (define_insn "*fop_xf_1_i387"
15330 [(set (match_operand:XF 0 "register_operand" "=f,f")
15331 (match_operator:XF 3 "binary_fp_operator"
15332 [(match_operand:XF 1 "register_operand" "0,f")
15333 (match_operand:XF 2 "register_operand" "f,0")]))]
15335 && !COMMUTATIVE_ARITH_P (operands[3])"
15336 "* return output_387_binary_op (insn, operands);"
15337 [(set (attr "type")
15338 (cond [(match_operand:XF 3 "mult_operator" "")
15339 (const_string "fmul")
15340 (match_operand:XF 3 "div_operator" "")
15341 (const_string "fdiv")
15343 (const_string "fop")))
15344 (set_attr "mode" "XF")])
15346 (define_insn "*fop_xf_2<mode>_i387"
15347 [(set (match_operand:XF 0 "register_operand" "=f,f")
15348 (match_operator:XF 3 "binary_fp_operator"
15349 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15350 (match_operand:XF 2 "register_operand" "0,0")]))]
15351 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15352 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15353 [(set (attr "type")
15354 (cond [(match_operand:XF 3 "mult_operator" "")
15355 (const_string "fmul")
15356 (match_operand:XF 3 "div_operator" "")
15357 (const_string "fdiv")
15359 (const_string "fop")))
15360 (set_attr "fp_int_src" "true")
15361 (set_attr "mode" "<MODE>")])
15363 (define_insn "*fop_xf_3<mode>_i387"
15364 [(set (match_operand:XF 0 "register_operand" "=f,f")
15365 (match_operator:XF 3 "binary_fp_operator"
15366 [(match_operand:XF 1 "register_operand" "0,0")
15367 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15368 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15369 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15370 [(set (attr "type")
15371 (cond [(match_operand:XF 3 "mult_operator" "")
15372 (const_string "fmul")
15373 (match_operand:XF 3 "div_operator" "")
15374 (const_string "fdiv")
15376 (const_string "fop")))
15377 (set_attr "fp_int_src" "true")
15378 (set_attr "mode" "<MODE>")])
15380 (define_insn "*fop_xf_4_i387"
15381 [(set (match_operand:XF 0 "register_operand" "=f,f")
15382 (match_operator:XF 3 "binary_fp_operator"
15383 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15384 (match_operand:XF 2 "register_operand" "0,f")]))]
15386 "* return output_387_binary_op (insn, operands);"
15387 [(set (attr "type")
15388 (cond [(match_operand:XF 3 "mult_operator" "")
15389 (const_string "fmul")
15390 (match_operand:XF 3 "div_operator" "")
15391 (const_string "fdiv")
15393 (const_string "fop")))
15394 (set_attr "mode" "SF")])
15396 (define_insn "*fop_xf_5_i387"
15397 [(set (match_operand:XF 0 "register_operand" "=f,f")
15398 (match_operator:XF 3 "binary_fp_operator"
15399 [(match_operand:XF 1 "register_operand" "0,f")
15401 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15403 "* return output_387_binary_op (insn, operands);"
15404 [(set (attr "type")
15405 (cond [(match_operand:XF 3 "mult_operator" "")
15406 (const_string "fmul")
15407 (match_operand:XF 3 "div_operator" "")
15408 (const_string "fdiv")
15410 (const_string "fop")))
15411 (set_attr "mode" "SF")])
15413 (define_insn "*fop_xf_6_i387"
15414 [(set (match_operand:XF 0 "register_operand" "=f,f")
15415 (match_operator:XF 3 "binary_fp_operator"
15417 (match_operand 1 "register_operand" "0,f"))
15419 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15421 "* return output_387_binary_op (insn, operands);"
15422 [(set (attr "type")
15423 (cond [(match_operand:XF 3 "mult_operator" "")
15424 (const_string "fmul")
15425 (match_operand:XF 3 "div_operator" "")
15426 (const_string "fdiv")
15428 (const_string "fop")))
15429 (set_attr "mode" "SF")])
15432 [(set (match_operand 0 "register_operand" "")
15433 (match_operator 3 "binary_fp_operator"
15434 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15435 (match_operand 2 "register_operand" "")]))]
15436 "TARGET_80387 && reload_completed
15437 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15440 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15441 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15442 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15443 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15444 GET_MODE (operands[3]),
15447 ix86_free_from_memory (GET_MODE (operands[1]));
15452 [(set (match_operand 0 "register_operand" "")
15453 (match_operator 3 "binary_fp_operator"
15454 [(match_operand 1 "register_operand" "")
15455 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15456 "TARGET_80387 && reload_completed
15457 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15460 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15461 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15462 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15463 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15464 GET_MODE (operands[3]),
15467 ix86_free_from_memory (GET_MODE (operands[2]));
15471 ;; FPU special functions.
15473 (define_expand "sqrtsf2"
15474 [(set (match_operand:SF 0 "register_operand" "")
15475 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
15476 "TARGET_USE_FANCY_MATH_387 || TARGET_SSE_MATH"
15478 if (!TARGET_SSE_MATH)
15479 operands[1] = force_reg (SFmode, operands[1]);
15482 (define_insn "*sqrtsf2_mixed"
15483 [(set (match_operand:SF 0 "register_operand" "=f,x")
15484 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "0,xm")))]
15485 "TARGET_USE_FANCY_MATH_387 && TARGET_MIX_SSE_I387"
15488 sqrtss\t{%1, %0|%0, %1}"
15489 [(set_attr "type" "fpspc,sse")
15490 (set_attr "mode" "SF,SF")
15491 (set_attr "athlon_decode" "direct,*")])
15493 (define_insn "*sqrtsf2_sse"
15494 [(set (match_operand:SF 0 "register_operand" "=x")
15495 (sqrt:SF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
15497 "sqrtss\t{%1, %0|%0, %1}"
15498 [(set_attr "type" "sse")
15499 (set_attr "mode" "SF")
15500 (set_attr "athlon_decode" "*")])
15502 (define_insn "*sqrtsf2_i387"
15503 [(set (match_operand:SF 0 "register_operand" "=f")
15504 (sqrt:SF (match_operand:SF 1 "register_operand" "0")))]
15505 "TARGET_USE_FANCY_MATH_387"
15507 [(set_attr "type" "fpspc")
15508 (set_attr "mode" "SF")
15509 (set_attr "athlon_decode" "direct")])
15511 (define_expand "sqrtdf2"
15512 [(set (match_operand:DF 0 "register_operand" "")
15513 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
15514 "TARGET_USE_FANCY_MATH_387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
15516 if (!(TARGET_SSE2 && TARGET_SSE_MATH))
15517 operands[1] = force_reg (DFmode, operands[1]);
15520 (define_insn "*sqrtdf2_mixed"
15521 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15522 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "0,Ym")))]
15523 "TARGET_USE_FANCY_MATH_387 && TARGET_SSE2 && TARGET_MIX_SSE_I387"
15526 sqrtsd\t{%1, %0|%0, %1}"
15527 [(set_attr "type" "fpspc,sse")
15528 (set_attr "mode" "DF,DF")
15529 (set_attr "athlon_decode" "direct,*")])
15531 (define_insn "*sqrtdf2_sse"
15532 [(set (match_operand:DF 0 "register_operand" "=Y")
15533 (sqrt:DF (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
15534 "TARGET_SSE2 && TARGET_SSE_MATH"
15535 "sqrtsd\t{%1, %0|%0, %1}"
15536 [(set_attr "type" "sse")
15537 (set_attr "mode" "DF")
15538 (set_attr "athlon_decode" "*")])
15540 (define_insn "*sqrtdf2_i387"
15541 [(set (match_operand:DF 0 "register_operand" "=f")
15542 (sqrt:DF (match_operand:DF 1 "register_operand" "0")))]
15543 "TARGET_USE_FANCY_MATH_387"
15545 [(set_attr "type" "fpspc")
15546 (set_attr "mode" "DF")
15547 (set_attr "athlon_decode" "direct")])
15549 (define_insn "*sqrtextendsfdf2_i387"
15550 [(set (match_operand:DF 0 "register_operand" "=f")
15551 (sqrt:DF (float_extend:DF
15552 (match_operand:SF 1 "register_operand" "0"))))]
15553 "TARGET_USE_FANCY_MATH_387
15554 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
15556 [(set_attr "type" "fpspc")
15557 (set_attr "mode" "DF")
15558 (set_attr "athlon_decode" "direct")])
15560 (define_insn "sqrtxf2"
15561 [(set (match_operand:XF 0 "register_operand" "=f")
15562 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15563 "TARGET_USE_FANCY_MATH_387"
15565 [(set_attr "type" "fpspc")
15566 (set_attr "mode" "XF")
15567 (set_attr "athlon_decode" "direct")])
15569 (define_insn "*sqrtextendsfxf2_i387"
15570 [(set (match_operand:XF 0 "register_operand" "=f")
15571 (sqrt:XF (float_extend:XF
15572 (match_operand:SF 1 "register_operand" "0"))))]
15573 "TARGET_USE_FANCY_MATH_387"
15575 [(set_attr "type" "fpspc")
15576 (set_attr "mode" "XF")
15577 (set_attr "athlon_decode" "direct")])
15579 (define_insn "*sqrtextenddfxf2_i387"
15580 [(set (match_operand:XF 0 "register_operand" "=f")
15581 (sqrt:XF (float_extend:XF
15582 (match_operand:DF 1 "register_operand" "0"))))]
15583 "TARGET_USE_FANCY_MATH_387"
15585 [(set_attr "type" "fpspc")
15586 (set_attr "mode" "XF")
15587 (set_attr "athlon_decode" "direct")])
15589 (define_insn "fpremxf4"
15590 [(set (match_operand:XF 0 "register_operand" "=f")
15591 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15592 (match_operand:XF 3 "register_operand" "1")]
15594 (set (match_operand:XF 1 "register_operand" "=u")
15595 (unspec:XF [(match_dup 2) (match_dup 3)]
15597 (set (reg:CCFP FPSR_REG)
15598 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15599 "TARGET_USE_FANCY_MATH_387
15600 && flag_unsafe_math_optimizations"
15602 [(set_attr "type" "fpspc")
15603 (set_attr "mode" "XF")])
15605 (define_expand "fmodsf3"
15606 [(use (match_operand:SF 0 "register_operand" ""))
15607 (use (match_operand:SF 1 "register_operand" ""))
15608 (use (match_operand:SF 2 "register_operand" ""))]
15609 "TARGET_USE_FANCY_MATH_387
15610 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15611 && flag_unsafe_math_optimizations"
15613 rtx label = gen_label_rtx ();
15615 rtx op1 = gen_reg_rtx (XFmode);
15616 rtx op2 = gen_reg_rtx (XFmode);
15618 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15619 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15621 emit_label (label);
15623 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15624 ix86_emit_fp_unordered_jump (label);
15626 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15630 (define_expand "fmoddf3"
15631 [(use (match_operand:DF 0 "register_operand" ""))
15632 (use (match_operand:DF 1 "register_operand" ""))
15633 (use (match_operand:DF 2 "register_operand" ""))]
15634 "TARGET_USE_FANCY_MATH_387
15635 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15636 && flag_unsafe_math_optimizations"
15638 rtx label = gen_label_rtx ();
15640 rtx op1 = gen_reg_rtx (XFmode);
15641 rtx op2 = gen_reg_rtx (XFmode);
15643 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15644 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15646 emit_label (label);
15648 emit_insn (gen_fpremxf4 (op1, op2, op1, op2));
15649 ix86_emit_fp_unordered_jump (label);
15651 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15655 (define_expand "fmodxf3"
15656 [(use (match_operand:XF 0 "register_operand" ""))
15657 (use (match_operand:XF 1 "register_operand" ""))
15658 (use (match_operand:XF 2 "register_operand" ""))]
15659 "TARGET_USE_FANCY_MATH_387
15660 && flag_unsafe_math_optimizations"
15662 rtx label = gen_label_rtx ();
15664 emit_label (label);
15666 emit_insn (gen_fpremxf4 (operands[1], operands[2],
15667 operands[1], operands[2]));
15668 ix86_emit_fp_unordered_jump (label);
15670 emit_move_insn (operands[0], operands[1]);
15674 (define_insn "fprem1xf4"
15675 [(set (match_operand:XF 0 "register_operand" "=f")
15676 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15677 (match_operand:XF 3 "register_operand" "1")]
15679 (set (match_operand:XF 1 "register_operand" "=u")
15680 (unspec:XF [(match_dup 2) (match_dup 3)]
15682 (set (reg:CCFP FPSR_REG)
15683 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15684 "TARGET_USE_FANCY_MATH_387
15685 && flag_unsafe_math_optimizations"
15687 [(set_attr "type" "fpspc")
15688 (set_attr "mode" "XF")])
15690 (define_expand "dremsf3"
15691 [(use (match_operand:SF 0 "register_operand" ""))
15692 (use (match_operand:SF 1 "register_operand" ""))
15693 (use (match_operand:SF 2 "register_operand" ""))]
15694 "TARGET_USE_FANCY_MATH_387
15695 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15696 && flag_unsafe_math_optimizations"
15698 rtx label = gen_label_rtx ();
15700 rtx op1 = gen_reg_rtx (XFmode);
15701 rtx op2 = gen_reg_rtx (XFmode);
15703 emit_insn(gen_extendsfxf2 (op1, operands[1]));
15704 emit_insn(gen_extendsfxf2 (op2, operands[2]));
15706 emit_label (label);
15708 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15709 ix86_emit_fp_unordered_jump (label);
15711 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op1));
15715 (define_expand "dremdf3"
15716 [(use (match_operand:DF 0 "register_operand" ""))
15717 (use (match_operand:DF 1 "register_operand" ""))
15718 (use (match_operand:DF 2 "register_operand" ""))]
15719 "TARGET_USE_FANCY_MATH_387
15720 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15721 && flag_unsafe_math_optimizations"
15723 rtx label = gen_label_rtx ();
15725 rtx op1 = gen_reg_rtx (XFmode);
15726 rtx op2 = gen_reg_rtx (XFmode);
15728 emit_insn (gen_extenddfxf2 (op1, operands[1]));
15729 emit_insn (gen_extenddfxf2 (op2, operands[2]));
15731 emit_label (label);
15733 emit_insn (gen_fprem1xf4 (op1, op2, op1, op2));
15734 ix86_emit_fp_unordered_jump (label);
15736 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op1));
15740 (define_expand "dremxf3"
15741 [(use (match_operand:XF 0 "register_operand" ""))
15742 (use (match_operand:XF 1 "register_operand" ""))
15743 (use (match_operand:XF 2 "register_operand" ""))]
15744 "TARGET_USE_FANCY_MATH_387
15745 && flag_unsafe_math_optimizations"
15747 rtx label = gen_label_rtx ();
15749 emit_label (label);
15751 emit_insn (gen_fprem1xf4 (operands[1], operands[2],
15752 operands[1], operands[2]));
15753 ix86_emit_fp_unordered_jump (label);
15755 emit_move_insn (operands[0], operands[1]);
15759 (define_insn "*sindf2"
15760 [(set (match_operand:DF 0 "register_operand" "=f")
15761 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15762 "TARGET_USE_FANCY_MATH_387
15763 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15764 && flag_unsafe_math_optimizations"
15766 [(set_attr "type" "fpspc")
15767 (set_attr "mode" "DF")])
15769 (define_insn "*sinsf2"
15770 [(set (match_operand:SF 0 "register_operand" "=f")
15771 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15772 "TARGET_USE_FANCY_MATH_387
15773 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15774 && flag_unsafe_math_optimizations"
15776 [(set_attr "type" "fpspc")
15777 (set_attr "mode" "SF")])
15779 (define_insn "*sinextendsfdf2"
15780 [(set (match_operand:DF 0 "register_operand" "=f")
15781 (unspec:DF [(float_extend:DF
15782 (match_operand:SF 1 "register_operand" "0"))]
15784 "TARGET_USE_FANCY_MATH_387
15785 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15786 && flag_unsafe_math_optimizations"
15788 [(set_attr "type" "fpspc")
15789 (set_attr "mode" "DF")])
15791 (define_insn "*sinxf2"
15792 [(set (match_operand:XF 0 "register_operand" "=f")
15793 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15794 "TARGET_USE_FANCY_MATH_387
15795 && flag_unsafe_math_optimizations"
15797 [(set_attr "type" "fpspc")
15798 (set_attr "mode" "XF")])
15800 (define_insn "*cosdf2"
15801 [(set (match_operand:DF 0 "register_operand" "=f")
15802 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15803 "TARGET_USE_FANCY_MATH_387
15804 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15805 && flag_unsafe_math_optimizations"
15807 [(set_attr "type" "fpspc")
15808 (set_attr "mode" "DF")])
15810 (define_insn "*cossf2"
15811 [(set (match_operand:SF 0 "register_operand" "=f")
15812 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15813 "TARGET_USE_FANCY_MATH_387
15814 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15815 && flag_unsafe_math_optimizations"
15817 [(set_attr "type" "fpspc")
15818 (set_attr "mode" "SF")])
15820 (define_insn "*cosextendsfdf2"
15821 [(set (match_operand:DF 0 "register_operand" "=f")
15822 (unspec:DF [(float_extend:DF
15823 (match_operand:SF 1 "register_operand" "0"))]
15825 "TARGET_USE_FANCY_MATH_387
15826 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15827 && flag_unsafe_math_optimizations"
15829 [(set_attr "type" "fpspc")
15830 (set_attr "mode" "DF")])
15832 (define_insn "*cosxf2"
15833 [(set (match_operand:XF 0 "register_operand" "=f")
15834 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15835 "TARGET_USE_FANCY_MATH_387
15836 && flag_unsafe_math_optimizations"
15838 [(set_attr "type" "fpspc")
15839 (set_attr "mode" "XF")])
15841 ;; With sincos pattern defined, sin and cos builtin function will be
15842 ;; expanded to sincos pattern with one of its outputs left unused.
15843 ;; Cse pass will detected, if two sincos patterns can be combined,
15844 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15845 ;; depending on the unused output.
15847 (define_insn "sincosdf3"
15848 [(set (match_operand:DF 0 "register_operand" "=f")
15849 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15850 UNSPEC_SINCOS_COS))
15851 (set (match_operand:DF 1 "register_operand" "=u")
15852 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15853 "TARGET_USE_FANCY_MATH_387
15854 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15855 && flag_unsafe_math_optimizations"
15857 [(set_attr "type" "fpspc")
15858 (set_attr "mode" "DF")])
15861 [(set (match_operand:DF 0 "register_operand" "")
15862 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15863 UNSPEC_SINCOS_COS))
15864 (set (match_operand:DF 1 "register_operand" "")
15865 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15866 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15867 && !reload_completed && !reload_in_progress"
15868 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15872 [(set (match_operand:DF 0 "register_operand" "")
15873 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15874 UNSPEC_SINCOS_COS))
15875 (set (match_operand:DF 1 "register_operand" "")
15876 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15877 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15878 && !reload_completed && !reload_in_progress"
15879 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15882 (define_insn "sincossf3"
15883 [(set (match_operand:SF 0 "register_operand" "=f")
15884 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15885 UNSPEC_SINCOS_COS))
15886 (set (match_operand:SF 1 "register_operand" "=u")
15887 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15888 "TARGET_USE_FANCY_MATH_387
15889 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15890 && flag_unsafe_math_optimizations"
15892 [(set_attr "type" "fpspc")
15893 (set_attr "mode" "SF")])
15896 [(set (match_operand:SF 0 "register_operand" "")
15897 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15898 UNSPEC_SINCOS_COS))
15899 (set (match_operand:SF 1 "register_operand" "")
15900 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15901 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15902 && !reload_completed && !reload_in_progress"
15903 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15907 [(set (match_operand:SF 0 "register_operand" "")
15908 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15909 UNSPEC_SINCOS_COS))
15910 (set (match_operand:SF 1 "register_operand" "")
15911 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15912 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15913 && !reload_completed && !reload_in_progress"
15914 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15917 (define_insn "*sincosextendsfdf3"
15918 [(set (match_operand:DF 0 "register_operand" "=f")
15919 (unspec:DF [(float_extend:DF
15920 (match_operand:SF 2 "register_operand" "0"))]
15921 UNSPEC_SINCOS_COS))
15922 (set (match_operand:DF 1 "register_operand" "=u")
15923 (unspec:DF [(float_extend:DF
15924 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15925 "TARGET_USE_FANCY_MATH_387
15926 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15927 && flag_unsafe_math_optimizations"
15929 [(set_attr "type" "fpspc")
15930 (set_attr "mode" "DF")])
15933 [(set (match_operand:DF 0 "register_operand" "")
15934 (unspec:DF [(float_extend:DF
15935 (match_operand:SF 2 "register_operand" ""))]
15936 UNSPEC_SINCOS_COS))
15937 (set (match_operand:DF 1 "register_operand" "")
15938 (unspec:DF [(float_extend:DF
15939 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15940 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15941 && !reload_completed && !reload_in_progress"
15942 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15943 (match_dup 2))] UNSPEC_SIN))]
15947 [(set (match_operand:DF 0 "register_operand" "")
15948 (unspec:DF [(float_extend:DF
15949 (match_operand:SF 2 "register_operand" ""))]
15950 UNSPEC_SINCOS_COS))
15951 (set (match_operand:DF 1 "register_operand" "")
15952 (unspec:DF [(float_extend:DF
15953 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15954 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15955 && !reload_completed && !reload_in_progress"
15956 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15957 (match_dup 2))] UNSPEC_COS))]
15960 (define_insn "sincosxf3"
15961 [(set (match_operand:XF 0 "register_operand" "=f")
15962 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15963 UNSPEC_SINCOS_COS))
15964 (set (match_operand:XF 1 "register_operand" "=u")
15965 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15966 "TARGET_USE_FANCY_MATH_387
15967 && flag_unsafe_math_optimizations"
15969 [(set_attr "type" "fpspc")
15970 (set_attr "mode" "XF")])
15973 [(set (match_operand:XF 0 "register_operand" "")
15974 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15975 UNSPEC_SINCOS_COS))
15976 (set (match_operand:XF 1 "register_operand" "")
15977 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15978 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15979 && !reload_completed && !reload_in_progress"
15980 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15984 [(set (match_operand:XF 0 "register_operand" "")
15985 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15986 UNSPEC_SINCOS_COS))
15987 (set (match_operand:XF 1 "register_operand" "")
15988 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15989 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15990 && !reload_completed && !reload_in_progress"
15991 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15994 (define_insn "*tandf3_1"
15995 [(set (match_operand:DF 0 "register_operand" "=f")
15996 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15998 (set (match_operand:DF 1 "register_operand" "=u")
15999 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
16000 "TARGET_USE_FANCY_MATH_387
16001 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16002 && flag_unsafe_math_optimizations"
16004 [(set_attr "type" "fpspc")
16005 (set_attr "mode" "DF")])
16007 ;; optimize sequence: fptan
16010 ;; into fptan insn.
16013 [(parallel[(set (match_operand:DF 0 "register_operand" "")
16014 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
16016 (set (match_operand:DF 1 "register_operand" "")
16017 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
16019 (match_operand:DF 3 "immediate_operand" ""))]
16020 "standard_80387_constant_p (operands[3]) == 2"
16021 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
16022 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16025 (define_expand "tandf2"
16026 [(parallel [(set (match_dup 2)
16027 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
16029 (set (match_operand:DF 0 "register_operand" "")
16030 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16031 "TARGET_USE_FANCY_MATH_387
16032 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16033 && flag_unsafe_math_optimizations"
16035 operands[2] = gen_reg_rtx (DFmode);
16038 (define_insn "*tansf3_1"
16039 [(set (match_operand:SF 0 "register_operand" "=f")
16040 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16042 (set (match_operand:SF 1 "register_operand" "=u")
16043 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16044 "TARGET_USE_FANCY_MATH_387
16045 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16046 && flag_unsafe_math_optimizations"
16048 [(set_attr "type" "fpspc")
16049 (set_attr "mode" "SF")])
16051 ;; optimize sequence: fptan
16054 ;; into fptan insn.
16057 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16058 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16060 (set (match_operand:SF 1 "register_operand" "")
16061 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16063 (match_operand:SF 3 "immediate_operand" ""))]
16064 "standard_80387_constant_p (operands[3]) == 2"
16065 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16066 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16069 (define_expand "tansf2"
16070 [(parallel [(set (match_dup 2)
16071 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16073 (set (match_operand:SF 0 "register_operand" "")
16074 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16075 "TARGET_USE_FANCY_MATH_387
16076 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16077 && flag_unsafe_math_optimizations"
16079 operands[2] = gen_reg_rtx (SFmode);
16082 (define_insn "*tanxf3_1"
16083 [(set (match_operand:XF 0 "register_operand" "=f")
16084 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16086 (set (match_operand:XF 1 "register_operand" "=u")
16087 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16088 "TARGET_USE_FANCY_MATH_387
16089 && flag_unsafe_math_optimizations"
16091 [(set_attr "type" "fpspc")
16092 (set_attr "mode" "XF")])
16094 ;; optimize sequence: fptan
16097 ;; into fptan insn.
16100 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16101 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16103 (set (match_operand:XF 1 "register_operand" "")
16104 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16106 (match_operand:XF 3 "immediate_operand" ""))]
16107 "standard_80387_constant_p (operands[3]) == 2"
16108 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16109 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16112 (define_expand "tanxf2"
16113 [(parallel [(set (match_dup 2)
16114 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16116 (set (match_operand:XF 0 "register_operand" "")
16117 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16118 "TARGET_USE_FANCY_MATH_387
16119 && flag_unsafe_math_optimizations"
16121 operands[2] = gen_reg_rtx (XFmode);
16124 (define_insn "atan2df3_1"
16125 [(set (match_operand:DF 0 "register_operand" "=f")
16126 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16127 (match_operand:DF 1 "register_operand" "u")]
16129 (clobber (match_scratch:DF 3 "=1"))]
16130 "TARGET_USE_FANCY_MATH_387
16131 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16132 && flag_unsafe_math_optimizations"
16134 [(set_attr "type" "fpspc")
16135 (set_attr "mode" "DF")])
16137 (define_expand "atan2df3"
16138 [(use (match_operand:DF 0 "register_operand" ""))
16139 (use (match_operand:DF 2 "register_operand" ""))
16140 (use (match_operand:DF 1 "register_operand" ""))]
16141 "TARGET_USE_FANCY_MATH_387
16142 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16143 && flag_unsafe_math_optimizations"
16145 rtx copy = gen_reg_rtx (DFmode);
16146 emit_move_insn (copy, operands[1]);
16147 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16151 (define_expand "atandf2"
16152 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16153 (unspec:DF [(match_dup 2)
16154 (match_operand:DF 1 "register_operand" "")]
16156 (clobber (match_scratch:DF 3 ""))])]
16157 "TARGET_USE_FANCY_MATH_387
16158 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16159 && flag_unsafe_math_optimizations"
16161 operands[2] = gen_reg_rtx (DFmode);
16162 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16165 (define_insn "atan2sf3_1"
16166 [(set (match_operand:SF 0 "register_operand" "=f")
16167 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16168 (match_operand:SF 1 "register_operand" "u")]
16170 (clobber (match_scratch:SF 3 "=1"))]
16171 "TARGET_USE_FANCY_MATH_387
16172 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16173 && flag_unsafe_math_optimizations"
16175 [(set_attr "type" "fpspc")
16176 (set_attr "mode" "SF")])
16178 (define_expand "atan2sf3"
16179 [(use (match_operand:SF 0 "register_operand" ""))
16180 (use (match_operand:SF 2 "register_operand" ""))
16181 (use (match_operand:SF 1 "register_operand" ""))]
16182 "TARGET_USE_FANCY_MATH_387
16183 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16184 && flag_unsafe_math_optimizations"
16186 rtx copy = gen_reg_rtx (SFmode);
16187 emit_move_insn (copy, operands[1]);
16188 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16192 (define_expand "atansf2"
16193 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16194 (unspec:SF [(match_dup 2)
16195 (match_operand:SF 1 "register_operand" "")]
16197 (clobber (match_scratch:SF 3 ""))])]
16198 "TARGET_USE_FANCY_MATH_387
16199 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16200 && flag_unsafe_math_optimizations"
16202 operands[2] = gen_reg_rtx (SFmode);
16203 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16206 (define_insn "atan2xf3_1"
16207 [(set (match_operand:XF 0 "register_operand" "=f")
16208 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16209 (match_operand:XF 1 "register_operand" "u")]
16211 (clobber (match_scratch:XF 3 "=1"))]
16212 "TARGET_USE_FANCY_MATH_387
16213 && flag_unsafe_math_optimizations"
16215 [(set_attr "type" "fpspc")
16216 (set_attr "mode" "XF")])
16218 (define_expand "atan2xf3"
16219 [(use (match_operand:XF 0 "register_operand" ""))
16220 (use (match_operand:XF 2 "register_operand" ""))
16221 (use (match_operand:XF 1 "register_operand" ""))]
16222 "TARGET_USE_FANCY_MATH_387
16223 && flag_unsafe_math_optimizations"
16225 rtx copy = gen_reg_rtx (XFmode);
16226 emit_move_insn (copy, operands[1]);
16227 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16231 (define_expand "atanxf2"
16232 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16233 (unspec:XF [(match_dup 2)
16234 (match_operand:XF 1 "register_operand" "")]
16236 (clobber (match_scratch:XF 3 ""))])]
16237 "TARGET_USE_FANCY_MATH_387
16238 && flag_unsafe_math_optimizations"
16240 operands[2] = gen_reg_rtx (XFmode);
16241 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16244 (define_expand "asindf2"
16245 [(set (match_dup 2)
16246 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16247 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16248 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16249 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16250 (parallel [(set (match_dup 7)
16251 (unspec:XF [(match_dup 6) (match_dup 2)]
16253 (clobber (match_scratch:XF 8 ""))])
16254 (set (match_operand:DF 0 "register_operand" "")
16255 (float_truncate:DF (match_dup 7)))]
16256 "TARGET_USE_FANCY_MATH_387
16257 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16258 && flag_unsafe_math_optimizations"
16262 for (i=2; i<8; i++)
16263 operands[i] = gen_reg_rtx (XFmode);
16265 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16268 (define_expand "asinsf2"
16269 [(set (match_dup 2)
16270 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16271 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16272 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16273 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16274 (parallel [(set (match_dup 7)
16275 (unspec:XF [(match_dup 6) (match_dup 2)]
16277 (clobber (match_scratch:XF 8 ""))])
16278 (set (match_operand:SF 0 "register_operand" "")
16279 (float_truncate:SF (match_dup 7)))]
16280 "TARGET_USE_FANCY_MATH_387
16281 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16282 && flag_unsafe_math_optimizations"
16286 for (i=2; i<8; i++)
16287 operands[i] = gen_reg_rtx (XFmode);
16289 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16292 (define_expand "asinxf2"
16293 [(set (match_dup 2)
16294 (mult:XF (match_operand:XF 1 "register_operand" "")
16296 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16297 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16298 (parallel [(set (match_operand:XF 0 "register_operand" "")
16299 (unspec:XF [(match_dup 5) (match_dup 1)]
16301 (clobber (match_scratch:XF 6 ""))])]
16302 "TARGET_USE_FANCY_MATH_387
16303 && flag_unsafe_math_optimizations"
16307 for (i=2; i<6; i++)
16308 operands[i] = gen_reg_rtx (XFmode);
16310 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16313 (define_expand "acosdf2"
16314 [(set (match_dup 2)
16315 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16316 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16317 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16318 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16319 (parallel [(set (match_dup 7)
16320 (unspec:XF [(match_dup 2) (match_dup 6)]
16322 (clobber (match_scratch:XF 8 ""))])
16323 (set (match_operand:DF 0 "register_operand" "")
16324 (float_truncate:DF (match_dup 7)))]
16325 "TARGET_USE_FANCY_MATH_387
16326 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16327 && flag_unsafe_math_optimizations"
16331 for (i=2; i<8; i++)
16332 operands[i] = gen_reg_rtx (XFmode);
16334 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16337 (define_expand "acossf2"
16338 [(set (match_dup 2)
16339 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16340 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16341 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16342 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16343 (parallel [(set (match_dup 7)
16344 (unspec:XF [(match_dup 2) (match_dup 6)]
16346 (clobber (match_scratch:XF 8 ""))])
16347 (set (match_operand:SF 0 "register_operand" "")
16348 (float_truncate:SF (match_dup 7)))]
16349 "TARGET_USE_FANCY_MATH_387
16350 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16351 && flag_unsafe_math_optimizations"
16355 for (i=2; i<8; i++)
16356 operands[i] = gen_reg_rtx (XFmode);
16358 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16361 (define_expand "acosxf2"
16362 [(set (match_dup 2)
16363 (mult:XF (match_operand:XF 1 "register_operand" "")
16365 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16366 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16367 (parallel [(set (match_operand:XF 0 "register_operand" "")
16368 (unspec:XF [(match_dup 1) (match_dup 5)]
16370 (clobber (match_scratch:XF 6 ""))])]
16371 "TARGET_USE_FANCY_MATH_387
16372 && flag_unsafe_math_optimizations"
16376 for (i=2; i<6; i++)
16377 operands[i] = gen_reg_rtx (XFmode);
16379 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16382 (define_insn "fyl2x_xf3"
16383 [(set (match_operand:XF 0 "register_operand" "=f")
16384 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16385 (match_operand:XF 1 "register_operand" "u")]
16387 (clobber (match_scratch:XF 3 "=1"))]
16388 "TARGET_USE_FANCY_MATH_387
16389 && flag_unsafe_math_optimizations"
16391 [(set_attr "type" "fpspc")
16392 (set_attr "mode" "XF")])
16394 (define_expand "logsf2"
16395 [(set (match_dup 2)
16396 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16397 (parallel [(set (match_dup 4)
16398 (unspec:XF [(match_dup 2)
16399 (match_dup 3)] UNSPEC_FYL2X))
16400 (clobber (match_scratch:XF 5 ""))])
16401 (set (match_operand:SF 0 "register_operand" "")
16402 (float_truncate:SF (match_dup 4)))]
16403 "TARGET_USE_FANCY_MATH_387
16404 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16405 && flag_unsafe_math_optimizations"
16409 operands[2] = gen_reg_rtx (XFmode);
16410 operands[3] = gen_reg_rtx (XFmode);
16411 operands[4] = gen_reg_rtx (XFmode);
16413 temp = standard_80387_constant_rtx (4); /* fldln2 */
16414 emit_move_insn (operands[3], temp);
16417 (define_expand "logdf2"
16418 [(set (match_dup 2)
16419 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16420 (parallel [(set (match_dup 4)
16421 (unspec:XF [(match_dup 2)
16422 (match_dup 3)] UNSPEC_FYL2X))
16423 (clobber (match_scratch:XF 5 ""))])
16424 (set (match_operand:DF 0 "register_operand" "")
16425 (float_truncate:DF (match_dup 4)))]
16426 "TARGET_USE_FANCY_MATH_387
16427 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16428 && flag_unsafe_math_optimizations"
16432 operands[2] = gen_reg_rtx (XFmode);
16433 operands[3] = gen_reg_rtx (XFmode);
16434 operands[4] = gen_reg_rtx (XFmode);
16436 temp = standard_80387_constant_rtx (4); /* fldln2 */
16437 emit_move_insn (operands[3], temp);
16440 (define_expand "logxf2"
16441 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16442 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16443 (match_dup 2)] UNSPEC_FYL2X))
16444 (clobber (match_scratch:XF 3 ""))])]
16445 "TARGET_USE_FANCY_MATH_387
16446 && flag_unsafe_math_optimizations"
16450 operands[2] = gen_reg_rtx (XFmode);
16451 temp = standard_80387_constant_rtx (4); /* fldln2 */
16452 emit_move_insn (operands[2], temp);
16455 (define_expand "log10sf2"
16456 [(set (match_dup 2)
16457 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16458 (parallel [(set (match_dup 4)
16459 (unspec:XF [(match_dup 2)
16460 (match_dup 3)] UNSPEC_FYL2X))
16461 (clobber (match_scratch:XF 5 ""))])
16462 (set (match_operand:SF 0 "register_operand" "")
16463 (float_truncate:SF (match_dup 4)))]
16464 "TARGET_USE_FANCY_MATH_387
16465 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16466 && flag_unsafe_math_optimizations"
16470 operands[2] = gen_reg_rtx (XFmode);
16471 operands[3] = gen_reg_rtx (XFmode);
16472 operands[4] = gen_reg_rtx (XFmode);
16474 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16475 emit_move_insn (operands[3], temp);
16478 (define_expand "log10df2"
16479 [(set (match_dup 2)
16480 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16481 (parallel [(set (match_dup 4)
16482 (unspec:XF [(match_dup 2)
16483 (match_dup 3)] UNSPEC_FYL2X))
16484 (clobber (match_scratch:XF 5 ""))])
16485 (set (match_operand:DF 0 "register_operand" "")
16486 (float_truncate:DF (match_dup 4)))]
16487 "TARGET_USE_FANCY_MATH_387
16488 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16489 && flag_unsafe_math_optimizations"
16493 operands[2] = gen_reg_rtx (XFmode);
16494 operands[3] = gen_reg_rtx (XFmode);
16495 operands[4] = gen_reg_rtx (XFmode);
16497 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16498 emit_move_insn (operands[3], temp);
16501 (define_expand "log10xf2"
16502 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16503 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16504 (match_dup 2)] UNSPEC_FYL2X))
16505 (clobber (match_scratch:XF 3 ""))])]
16506 "TARGET_USE_FANCY_MATH_387
16507 && flag_unsafe_math_optimizations"
16511 operands[2] = gen_reg_rtx (XFmode);
16512 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16513 emit_move_insn (operands[2], temp);
16516 (define_expand "log2sf2"
16517 [(set (match_dup 2)
16518 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16519 (parallel [(set (match_dup 4)
16520 (unspec:XF [(match_dup 2)
16521 (match_dup 3)] UNSPEC_FYL2X))
16522 (clobber (match_scratch:XF 5 ""))])
16523 (set (match_operand:SF 0 "register_operand" "")
16524 (float_truncate:SF (match_dup 4)))]
16525 "TARGET_USE_FANCY_MATH_387
16526 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16527 && flag_unsafe_math_optimizations"
16529 operands[2] = gen_reg_rtx (XFmode);
16530 operands[3] = gen_reg_rtx (XFmode);
16531 operands[4] = gen_reg_rtx (XFmode);
16533 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16536 (define_expand "log2df2"
16537 [(set (match_dup 2)
16538 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16539 (parallel [(set (match_dup 4)
16540 (unspec:XF [(match_dup 2)
16541 (match_dup 3)] UNSPEC_FYL2X))
16542 (clobber (match_scratch:XF 5 ""))])
16543 (set (match_operand:DF 0 "register_operand" "")
16544 (float_truncate:DF (match_dup 4)))]
16545 "TARGET_USE_FANCY_MATH_387
16546 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16547 && flag_unsafe_math_optimizations"
16549 operands[2] = gen_reg_rtx (XFmode);
16550 operands[3] = gen_reg_rtx (XFmode);
16551 operands[4] = gen_reg_rtx (XFmode);
16553 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16556 (define_expand "log2xf2"
16557 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16558 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16559 (match_dup 2)] UNSPEC_FYL2X))
16560 (clobber (match_scratch:XF 3 ""))])]
16561 "TARGET_USE_FANCY_MATH_387
16562 && flag_unsafe_math_optimizations"
16564 operands[2] = gen_reg_rtx (XFmode);
16565 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16568 (define_insn "fyl2xp1_xf3"
16569 [(set (match_operand:XF 0 "register_operand" "=f")
16570 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16571 (match_operand:XF 1 "register_operand" "u")]
16573 (clobber (match_scratch:XF 3 "=1"))]
16574 "TARGET_USE_FANCY_MATH_387
16575 && flag_unsafe_math_optimizations"
16577 [(set_attr "type" "fpspc")
16578 (set_attr "mode" "XF")])
16580 (define_expand "log1psf2"
16581 [(use (match_operand:SF 0 "register_operand" ""))
16582 (use (match_operand:SF 1 "register_operand" ""))]
16583 "TARGET_USE_FANCY_MATH_387
16584 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16585 && flag_unsafe_math_optimizations"
16587 rtx op0 = gen_reg_rtx (XFmode);
16588 rtx op1 = gen_reg_rtx (XFmode);
16590 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16591 ix86_emit_i387_log1p (op0, op1);
16592 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16596 (define_expand "log1pdf2"
16597 [(use (match_operand:DF 0 "register_operand" ""))
16598 (use (match_operand:DF 1 "register_operand" ""))]
16599 "TARGET_USE_FANCY_MATH_387
16600 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16601 && flag_unsafe_math_optimizations"
16603 rtx op0 = gen_reg_rtx (XFmode);
16604 rtx op1 = gen_reg_rtx (XFmode);
16606 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16607 ix86_emit_i387_log1p (op0, op1);
16608 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16612 (define_expand "log1pxf2"
16613 [(use (match_operand:XF 0 "register_operand" ""))
16614 (use (match_operand:XF 1 "register_operand" ""))]
16615 "TARGET_USE_FANCY_MATH_387
16616 && flag_unsafe_math_optimizations"
16618 ix86_emit_i387_log1p (operands[0], operands[1]);
16622 (define_insn "*fxtractxf3"
16623 [(set (match_operand:XF 0 "register_operand" "=f")
16624 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16625 UNSPEC_XTRACT_FRACT))
16626 (set (match_operand:XF 1 "register_operand" "=u")
16627 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16628 "TARGET_USE_FANCY_MATH_387
16629 && flag_unsafe_math_optimizations"
16631 [(set_attr "type" "fpspc")
16632 (set_attr "mode" "XF")])
16634 (define_expand "logbsf2"
16635 [(set (match_dup 2)
16636 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16637 (parallel [(set (match_dup 3)
16638 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16640 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16641 (set (match_operand:SF 0 "register_operand" "")
16642 (float_truncate:SF (match_dup 4)))]
16643 "TARGET_USE_FANCY_MATH_387
16644 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16645 && flag_unsafe_math_optimizations"
16647 operands[2] = gen_reg_rtx (XFmode);
16648 operands[3] = gen_reg_rtx (XFmode);
16649 operands[4] = gen_reg_rtx (XFmode);
16652 (define_expand "logbdf2"
16653 [(set (match_dup 2)
16654 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16655 (parallel [(set (match_dup 3)
16656 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16658 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16659 (set (match_operand:DF 0 "register_operand" "")
16660 (float_truncate:DF (match_dup 4)))]
16661 "TARGET_USE_FANCY_MATH_387
16662 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16663 && flag_unsafe_math_optimizations"
16665 operands[2] = gen_reg_rtx (XFmode);
16666 operands[3] = gen_reg_rtx (XFmode);
16667 operands[4] = gen_reg_rtx (XFmode);
16670 (define_expand "logbxf2"
16671 [(parallel [(set (match_dup 2)
16672 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16673 UNSPEC_XTRACT_FRACT))
16674 (set (match_operand:XF 0 "register_operand" "")
16675 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16676 "TARGET_USE_FANCY_MATH_387
16677 && flag_unsafe_math_optimizations"
16679 operands[2] = gen_reg_rtx (XFmode);
16682 (define_expand "ilogbsi2"
16683 [(parallel [(set (match_dup 2)
16684 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16685 UNSPEC_XTRACT_FRACT))
16686 (set (match_operand:XF 3 "register_operand" "")
16687 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16688 (parallel [(set (match_operand:SI 0 "register_operand" "")
16689 (fix:SI (match_dup 3)))
16690 (clobber (reg:CC FLAGS_REG))])]
16691 "TARGET_USE_FANCY_MATH_387
16692 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16693 && flag_unsafe_math_optimizations"
16695 operands[2] = gen_reg_rtx (XFmode);
16696 operands[3] = gen_reg_rtx (XFmode);
16699 (define_insn "*f2xm1xf2"
16700 [(set (match_operand:XF 0 "register_operand" "=f")
16701 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16703 "TARGET_USE_FANCY_MATH_387
16704 && flag_unsafe_math_optimizations"
16706 [(set_attr "type" "fpspc")
16707 (set_attr "mode" "XF")])
16709 (define_insn "*fscalexf4"
16710 [(set (match_operand:XF 0 "register_operand" "=f")
16711 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16712 (match_operand:XF 3 "register_operand" "1")]
16713 UNSPEC_FSCALE_FRACT))
16714 (set (match_operand:XF 1 "register_operand" "=u")
16715 (unspec:XF [(match_dup 2) (match_dup 3)]
16716 UNSPEC_FSCALE_EXP))]
16717 "TARGET_USE_FANCY_MATH_387
16718 && flag_unsafe_math_optimizations"
16720 [(set_attr "type" "fpspc")
16721 (set_attr "mode" "XF")])
16723 (define_expand "expsf2"
16724 [(set (match_dup 2)
16725 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16726 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16727 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16728 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16729 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16730 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16731 (parallel [(set (match_dup 10)
16732 (unspec:XF [(match_dup 9) (match_dup 5)]
16733 UNSPEC_FSCALE_FRACT))
16734 (set (match_dup 11)
16735 (unspec:XF [(match_dup 9) (match_dup 5)]
16736 UNSPEC_FSCALE_EXP))])
16737 (set (match_operand:SF 0 "register_operand" "")
16738 (float_truncate:SF (match_dup 10)))]
16739 "TARGET_USE_FANCY_MATH_387
16740 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16741 && flag_unsafe_math_optimizations"
16746 for (i=2; i<12; i++)
16747 operands[i] = gen_reg_rtx (XFmode);
16748 temp = standard_80387_constant_rtx (5); /* fldl2e */
16749 emit_move_insn (operands[3], temp);
16750 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16753 (define_expand "expdf2"
16754 [(set (match_dup 2)
16755 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16756 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16757 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16758 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16759 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16760 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16761 (parallel [(set (match_dup 10)
16762 (unspec:XF [(match_dup 9) (match_dup 5)]
16763 UNSPEC_FSCALE_FRACT))
16764 (set (match_dup 11)
16765 (unspec:XF [(match_dup 9) (match_dup 5)]
16766 UNSPEC_FSCALE_EXP))])
16767 (set (match_operand:DF 0 "register_operand" "")
16768 (float_truncate:DF (match_dup 10)))]
16769 "TARGET_USE_FANCY_MATH_387
16770 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16771 && flag_unsafe_math_optimizations"
16776 for (i=2; i<12; i++)
16777 operands[i] = gen_reg_rtx (XFmode);
16778 temp = standard_80387_constant_rtx (5); /* fldl2e */
16779 emit_move_insn (operands[3], temp);
16780 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16783 (define_expand "expxf2"
16784 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16786 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16787 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16788 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16789 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16790 (parallel [(set (match_operand:XF 0 "register_operand" "")
16791 (unspec:XF [(match_dup 8) (match_dup 4)]
16792 UNSPEC_FSCALE_FRACT))
16794 (unspec:XF [(match_dup 8) (match_dup 4)]
16795 UNSPEC_FSCALE_EXP))])]
16796 "TARGET_USE_FANCY_MATH_387
16797 && flag_unsafe_math_optimizations"
16802 for (i=2; i<10; i++)
16803 operands[i] = gen_reg_rtx (XFmode);
16804 temp = standard_80387_constant_rtx (5); /* fldl2e */
16805 emit_move_insn (operands[2], temp);
16806 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16809 (define_expand "exp10sf2"
16810 [(set (match_dup 2)
16811 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16812 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16813 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16814 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16815 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16816 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16817 (parallel [(set (match_dup 10)
16818 (unspec:XF [(match_dup 9) (match_dup 5)]
16819 UNSPEC_FSCALE_FRACT))
16820 (set (match_dup 11)
16821 (unspec:XF [(match_dup 9) (match_dup 5)]
16822 UNSPEC_FSCALE_EXP))])
16823 (set (match_operand:SF 0 "register_operand" "")
16824 (float_truncate:SF (match_dup 10)))]
16825 "TARGET_USE_FANCY_MATH_387
16826 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16827 && flag_unsafe_math_optimizations"
16832 for (i=2; i<12; i++)
16833 operands[i] = gen_reg_rtx (XFmode);
16834 temp = standard_80387_constant_rtx (6); /* fldl2t */
16835 emit_move_insn (operands[3], temp);
16836 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16839 (define_expand "exp10df2"
16840 [(set (match_dup 2)
16841 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16842 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16843 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16844 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16845 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16846 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16847 (parallel [(set (match_dup 10)
16848 (unspec:XF [(match_dup 9) (match_dup 5)]
16849 UNSPEC_FSCALE_FRACT))
16850 (set (match_dup 11)
16851 (unspec:XF [(match_dup 9) (match_dup 5)]
16852 UNSPEC_FSCALE_EXP))])
16853 (set (match_operand:DF 0 "register_operand" "")
16854 (float_truncate:DF (match_dup 10)))]
16855 "TARGET_USE_FANCY_MATH_387
16856 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16857 && flag_unsafe_math_optimizations"
16862 for (i=2; i<12; i++)
16863 operands[i] = gen_reg_rtx (XFmode);
16864 temp = standard_80387_constant_rtx (6); /* fldl2t */
16865 emit_move_insn (operands[3], temp);
16866 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16869 (define_expand "exp10xf2"
16870 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16872 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16873 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16874 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16875 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16876 (parallel [(set (match_operand:XF 0 "register_operand" "")
16877 (unspec:XF [(match_dup 8) (match_dup 4)]
16878 UNSPEC_FSCALE_FRACT))
16880 (unspec:XF [(match_dup 8) (match_dup 4)]
16881 UNSPEC_FSCALE_EXP))])]
16882 "TARGET_USE_FANCY_MATH_387
16883 && flag_unsafe_math_optimizations"
16888 for (i=2; i<10; i++)
16889 operands[i] = gen_reg_rtx (XFmode);
16890 temp = standard_80387_constant_rtx (6); /* fldl2t */
16891 emit_move_insn (operands[2], temp);
16892 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16895 (define_expand "exp2sf2"
16896 [(set (match_dup 2)
16897 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16898 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16899 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16900 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16901 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16902 (parallel [(set (match_dup 8)
16903 (unspec:XF [(match_dup 7) (match_dup 3)]
16904 UNSPEC_FSCALE_FRACT))
16906 (unspec:XF [(match_dup 7) (match_dup 3)]
16907 UNSPEC_FSCALE_EXP))])
16908 (set (match_operand:SF 0 "register_operand" "")
16909 (float_truncate:SF (match_dup 8)))]
16910 "TARGET_USE_FANCY_MATH_387
16911 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16912 && flag_unsafe_math_optimizations"
16916 for (i=2; i<10; i++)
16917 operands[i] = gen_reg_rtx (XFmode);
16918 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16921 (define_expand "exp2df2"
16922 [(set (match_dup 2)
16923 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16924 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16925 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16926 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16927 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16928 (parallel [(set (match_dup 8)
16929 (unspec:XF [(match_dup 7) (match_dup 3)]
16930 UNSPEC_FSCALE_FRACT))
16932 (unspec:XF [(match_dup 7) (match_dup 3)]
16933 UNSPEC_FSCALE_EXP))])
16934 (set (match_operand:DF 0 "register_operand" "")
16935 (float_truncate:DF (match_dup 8)))]
16936 "TARGET_USE_FANCY_MATH_387
16937 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16938 && flag_unsafe_math_optimizations"
16942 for (i=2; i<10; i++)
16943 operands[i] = gen_reg_rtx (XFmode);
16944 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16947 (define_expand "exp2xf2"
16948 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16949 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16950 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16951 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16952 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16953 (parallel [(set (match_operand:XF 0 "register_operand" "")
16954 (unspec:XF [(match_dup 7) (match_dup 3)]
16955 UNSPEC_FSCALE_FRACT))
16957 (unspec:XF [(match_dup 7) (match_dup 3)]
16958 UNSPEC_FSCALE_EXP))])]
16959 "TARGET_USE_FANCY_MATH_387
16960 && flag_unsafe_math_optimizations"
16964 for (i=2; i<9; i++)
16965 operands[i] = gen_reg_rtx (XFmode);
16966 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16969 (define_expand "expm1df2"
16970 [(set (match_dup 2)
16971 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16972 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16973 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16974 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16975 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16976 (parallel [(set (match_dup 8)
16977 (unspec:XF [(match_dup 7) (match_dup 5)]
16978 UNSPEC_FSCALE_FRACT))
16980 (unspec:XF [(match_dup 7) (match_dup 5)]
16981 UNSPEC_FSCALE_EXP))])
16982 (parallel [(set (match_dup 11)
16983 (unspec:XF [(match_dup 10) (match_dup 9)]
16984 UNSPEC_FSCALE_FRACT))
16985 (set (match_dup 12)
16986 (unspec:XF [(match_dup 10) (match_dup 9)]
16987 UNSPEC_FSCALE_EXP))])
16988 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16989 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16990 (set (match_operand:DF 0 "register_operand" "")
16991 (float_truncate:DF (match_dup 14)))]
16992 "TARGET_USE_FANCY_MATH_387
16993 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16994 && flag_unsafe_math_optimizations"
16999 for (i=2; i<15; i++)
17000 operands[i] = gen_reg_rtx (XFmode);
17001 temp = standard_80387_constant_rtx (5); /* fldl2e */
17002 emit_move_insn (operands[3], temp);
17003 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17006 (define_expand "expm1sf2"
17007 [(set (match_dup 2)
17008 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17009 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
17010 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
17011 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
17012 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
17013 (parallel [(set (match_dup 8)
17014 (unspec:XF [(match_dup 7) (match_dup 5)]
17015 UNSPEC_FSCALE_FRACT))
17017 (unspec:XF [(match_dup 7) (match_dup 5)]
17018 UNSPEC_FSCALE_EXP))])
17019 (parallel [(set (match_dup 11)
17020 (unspec:XF [(match_dup 10) (match_dup 9)]
17021 UNSPEC_FSCALE_FRACT))
17022 (set (match_dup 12)
17023 (unspec:XF [(match_dup 10) (match_dup 9)]
17024 UNSPEC_FSCALE_EXP))])
17025 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
17026 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
17027 (set (match_operand:SF 0 "register_operand" "")
17028 (float_truncate:SF (match_dup 14)))]
17029 "TARGET_USE_FANCY_MATH_387
17030 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17031 && flag_unsafe_math_optimizations"
17036 for (i=2; i<15; i++)
17037 operands[i] = gen_reg_rtx (XFmode);
17038 temp = standard_80387_constant_rtx (5); /* fldl2e */
17039 emit_move_insn (operands[3], temp);
17040 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17043 (define_expand "expm1xf2"
17044 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17046 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17047 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17048 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17049 (parallel [(set (match_dup 7)
17050 (unspec:XF [(match_dup 6) (match_dup 4)]
17051 UNSPEC_FSCALE_FRACT))
17053 (unspec:XF [(match_dup 6) (match_dup 4)]
17054 UNSPEC_FSCALE_EXP))])
17055 (parallel [(set (match_dup 10)
17056 (unspec:XF [(match_dup 9) (match_dup 8)]
17057 UNSPEC_FSCALE_FRACT))
17058 (set (match_dup 11)
17059 (unspec:XF [(match_dup 9) (match_dup 8)]
17060 UNSPEC_FSCALE_EXP))])
17061 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17062 (set (match_operand:XF 0 "register_operand" "")
17063 (plus:XF (match_dup 12) (match_dup 7)))]
17064 "TARGET_USE_FANCY_MATH_387
17065 && flag_unsafe_math_optimizations"
17070 for (i=2; i<13; i++)
17071 operands[i] = gen_reg_rtx (XFmode);
17072 temp = standard_80387_constant_rtx (5); /* fldl2e */
17073 emit_move_insn (operands[2], temp);
17074 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17077 (define_expand "ldexpdf3"
17078 [(set (match_dup 3)
17079 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17081 (float:XF (match_operand:SI 2 "register_operand" "")))
17082 (parallel [(set (match_dup 5)
17083 (unspec:XF [(match_dup 3) (match_dup 4)]
17084 UNSPEC_FSCALE_FRACT))
17086 (unspec:XF [(match_dup 3) (match_dup 4)]
17087 UNSPEC_FSCALE_EXP))])
17088 (set (match_operand:DF 0 "register_operand" "")
17089 (float_truncate:DF (match_dup 5)))]
17090 "TARGET_USE_FANCY_MATH_387
17091 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17092 && flag_unsafe_math_optimizations"
17096 for (i=3; i<7; i++)
17097 operands[i] = gen_reg_rtx (XFmode);
17100 (define_expand "ldexpsf3"
17101 [(set (match_dup 3)
17102 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17104 (float:XF (match_operand:SI 2 "register_operand" "")))
17105 (parallel [(set (match_dup 5)
17106 (unspec:XF [(match_dup 3) (match_dup 4)]
17107 UNSPEC_FSCALE_FRACT))
17109 (unspec:XF [(match_dup 3) (match_dup 4)]
17110 UNSPEC_FSCALE_EXP))])
17111 (set (match_operand:SF 0 "register_operand" "")
17112 (float_truncate:SF (match_dup 5)))]
17113 "TARGET_USE_FANCY_MATH_387
17114 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17115 && flag_unsafe_math_optimizations"
17119 for (i=3; i<7; i++)
17120 operands[i] = gen_reg_rtx (XFmode);
17123 (define_expand "ldexpxf3"
17124 [(set (match_dup 3)
17125 (float:XF (match_operand:SI 2 "register_operand" "")))
17126 (parallel [(set (match_operand:XF 0 " register_operand" "")
17127 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17129 UNSPEC_FSCALE_FRACT))
17131 (unspec:XF [(match_dup 1) (match_dup 3)]
17132 UNSPEC_FSCALE_EXP))])]
17133 "TARGET_USE_FANCY_MATH_387
17134 && flag_unsafe_math_optimizations"
17138 for (i=3; i<5; i++)
17139 operands[i] = gen_reg_rtx (XFmode);
17143 (define_insn "frndintxf2"
17144 [(set (match_operand:XF 0 "register_operand" "=f")
17145 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17147 "TARGET_USE_FANCY_MATH_387
17148 && flag_unsafe_math_optimizations"
17150 [(set_attr "type" "fpspc")
17151 (set_attr "mode" "XF")])
17153 (define_expand "rintdf2"
17154 [(use (match_operand:DF 0 "register_operand" ""))
17155 (use (match_operand:DF 1 "register_operand" ""))]
17156 "TARGET_USE_FANCY_MATH_387
17157 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17158 && flag_unsafe_math_optimizations"
17160 rtx op0 = gen_reg_rtx (XFmode);
17161 rtx op1 = gen_reg_rtx (XFmode);
17163 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17164 emit_insn (gen_frndintxf2 (op0, op1));
17166 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17170 (define_expand "rintsf2"
17171 [(use (match_operand:SF 0 "register_operand" ""))
17172 (use (match_operand:SF 1 "register_operand" ""))]
17173 "TARGET_USE_FANCY_MATH_387
17174 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17175 && flag_unsafe_math_optimizations"
17177 rtx op0 = gen_reg_rtx (XFmode);
17178 rtx op1 = gen_reg_rtx (XFmode);
17180 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17181 emit_insn (gen_frndintxf2 (op0, op1));
17183 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17187 (define_expand "rintxf2"
17188 [(use (match_operand:XF 0 "register_operand" ""))
17189 (use (match_operand:XF 1 "register_operand" ""))]
17190 "TARGET_USE_FANCY_MATH_387
17191 && flag_unsafe_math_optimizations"
17193 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17197 (define_insn_and_split "*fistdi2_1"
17198 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17199 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17201 "TARGET_USE_FANCY_MATH_387
17202 && flag_unsafe_math_optimizations
17203 && !(reload_completed || reload_in_progress)"
17208 if (memory_operand (operands[0], VOIDmode))
17209 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17212 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17213 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17218 [(set_attr "type" "fpspc")
17219 (set_attr "mode" "DI")])
17221 (define_insn "fistdi2"
17222 [(set (match_operand:DI 0 "memory_operand" "=m")
17223 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17225 (clobber (match_scratch:XF 2 "=&1f"))]
17226 "TARGET_USE_FANCY_MATH_387
17227 && flag_unsafe_math_optimizations"
17228 "* return output_fix_trunc (insn, operands, 0);"
17229 [(set_attr "type" "fpspc")
17230 (set_attr "mode" "DI")])
17232 (define_insn "fistdi2_with_temp"
17233 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17234 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17236 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17237 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17238 "TARGET_USE_FANCY_MATH_387
17239 && flag_unsafe_math_optimizations"
17241 [(set_attr "type" "fpspc")
17242 (set_attr "mode" "DI")])
17245 [(set (match_operand:DI 0 "register_operand" "")
17246 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17248 (clobber (match_operand:DI 2 "memory_operand" ""))
17249 (clobber (match_scratch 3 ""))]
17251 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17252 (clobber (match_dup 3))])
17253 (set (match_dup 0) (match_dup 2))]
17257 [(set (match_operand:DI 0 "memory_operand" "")
17258 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17260 (clobber (match_operand:DI 2 "memory_operand" ""))
17261 (clobber (match_scratch 3 ""))]
17263 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17264 (clobber (match_dup 3))])]
17267 (define_insn_and_split "*fist<mode>2_1"
17268 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17269 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17271 "TARGET_USE_FANCY_MATH_387
17272 && flag_unsafe_math_optimizations
17273 && !(reload_completed || reload_in_progress)"
17278 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17279 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17283 [(set_attr "type" "fpspc")
17284 (set_attr "mode" "<MODE>")])
17286 (define_insn "fist<mode>2"
17287 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17288 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17290 "TARGET_USE_FANCY_MATH_387
17291 && flag_unsafe_math_optimizations"
17292 "* return output_fix_trunc (insn, operands, 0);"
17293 [(set_attr "type" "fpspc")
17294 (set_attr "mode" "<MODE>")])
17296 (define_insn "fist<mode>2_with_temp"
17297 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17298 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17300 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17301 "TARGET_USE_FANCY_MATH_387
17302 && flag_unsafe_math_optimizations"
17304 [(set_attr "type" "fpspc")
17305 (set_attr "mode" "<MODE>")])
17308 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17309 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17311 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17313 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17315 (set (match_dup 0) (match_dup 2))]
17319 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17320 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17322 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17324 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17328 (define_expand "lrint<mode>2"
17329 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17330 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17332 "TARGET_USE_FANCY_MATH_387
17333 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17334 && flag_unsafe_math_optimizations"
17337 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17338 (define_insn_and_split "frndintxf2_floor"
17339 [(set (match_operand:XF 0 "register_operand" "=f")
17340 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17341 UNSPEC_FRNDINT_FLOOR))
17342 (clobber (reg:CC FLAGS_REG))]
17343 "TARGET_USE_FANCY_MATH_387
17344 && flag_unsafe_math_optimizations
17345 && !(reload_completed || reload_in_progress)"
17350 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17352 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17353 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17355 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17356 operands[2], operands[3]));
17359 [(set_attr "type" "frndint")
17360 (set_attr "i387_cw" "floor")
17361 (set_attr "mode" "XF")])
17363 (define_insn "frndintxf2_floor_i387"
17364 [(set (match_operand:XF 0 "register_operand" "=f")
17365 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17366 UNSPEC_FRNDINT_FLOOR))
17367 (use (match_operand:HI 2 "memory_operand" "m"))
17368 (use (match_operand:HI 3 "memory_operand" "m"))]
17369 "TARGET_USE_FANCY_MATH_387
17370 && flag_unsafe_math_optimizations"
17371 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17372 [(set_attr "type" "frndint")
17373 (set_attr "i387_cw" "floor")
17374 (set_attr "mode" "XF")])
17376 (define_expand "floorxf2"
17377 [(use (match_operand:XF 0 "register_operand" ""))
17378 (use (match_operand:XF 1 "register_operand" ""))]
17379 "TARGET_USE_FANCY_MATH_387
17380 && flag_unsafe_math_optimizations"
17382 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17386 (define_expand "floordf2"
17387 [(use (match_operand:DF 0 "register_operand" ""))
17388 (use (match_operand:DF 1 "register_operand" ""))]
17389 "TARGET_USE_FANCY_MATH_387
17390 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17391 && flag_unsafe_math_optimizations"
17393 rtx op0 = gen_reg_rtx (XFmode);
17394 rtx op1 = gen_reg_rtx (XFmode);
17396 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17397 emit_insn (gen_frndintxf2_floor (op0, op1));
17399 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17403 (define_expand "floorsf2"
17404 [(use (match_operand:SF 0 "register_operand" ""))
17405 (use (match_operand:SF 1 "register_operand" ""))]
17406 "TARGET_USE_FANCY_MATH_387
17407 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17408 && flag_unsafe_math_optimizations"
17410 rtx op0 = gen_reg_rtx (XFmode);
17411 rtx op1 = gen_reg_rtx (XFmode);
17413 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17414 emit_insn (gen_frndintxf2_floor (op0, op1));
17416 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17420 (define_insn_and_split "*fist<mode>2_floor_1"
17421 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17422 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17423 UNSPEC_FIST_FLOOR))
17424 (clobber (reg:CC FLAGS_REG))]
17425 "TARGET_USE_FANCY_MATH_387
17426 && flag_unsafe_math_optimizations
17427 && !(reload_completed || reload_in_progress)"
17432 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17434 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17435 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17436 if (memory_operand (operands[0], VOIDmode))
17437 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17438 operands[2], operands[3]));
17441 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17442 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17443 operands[2], operands[3],
17448 [(set_attr "type" "fistp")
17449 (set_attr "i387_cw" "floor")
17450 (set_attr "mode" "<MODE>")])
17452 (define_insn "fistdi2_floor"
17453 [(set (match_operand:DI 0 "memory_operand" "=m")
17454 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17455 UNSPEC_FIST_FLOOR))
17456 (use (match_operand:HI 2 "memory_operand" "m"))
17457 (use (match_operand:HI 3 "memory_operand" "m"))
17458 (clobber (match_scratch:XF 4 "=&1f"))]
17459 "TARGET_USE_FANCY_MATH_387
17460 && flag_unsafe_math_optimizations"
17461 "* return output_fix_trunc (insn, operands, 0);"
17462 [(set_attr "type" "fistp")
17463 (set_attr "i387_cw" "floor")
17464 (set_attr "mode" "DI")])
17466 (define_insn "fistdi2_floor_with_temp"
17467 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17468 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17469 UNSPEC_FIST_FLOOR))
17470 (use (match_operand:HI 2 "memory_operand" "m,m"))
17471 (use (match_operand:HI 3 "memory_operand" "m,m"))
17472 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17473 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17474 "TARGET_USE_FANCY_MATH_387
17475 && flag_unsafe_math_optimizations"
17477 [(set_attr "type" "fistp")
17478 (set_attr "i387_cw" "floor")
17479 (set_attr "mode" "DI")])
17482 [(set (match_operand:DI 0 "register_operand" "")
17483 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17484 UNSPEC_FIST_FLOOR))
17485 (use (match_operand:HI 2 "memory_operand" ""))
17486 (use (match_operand:HI 3 "memory_operand" ""))
17487 (clobber (match_operand:DI 4 "memory_operand" ""))
17488 (clobber (match_scratch 5 ""))]
17490 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17491 (use (match_dup 2))
17492 (use (match_dup 3))
17493 (clobber (match_dup 5))])
17494 (set (match_dup 0) (match_dup 4))]
17498 [(set (match_operand:DI 0 "memory_operand" "")
17499 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17500 UNSPEC_FIST_FLOOR))
17501 (use (match_operand:HI 2 "memory_operand" ""))
17502 (use (match_operand:HI 3 "memory_operand" ""))
17503 (clobber (match_operand:DI 4 "memory_operand" ""))
17504 (clobber (match_scratch 5 ""))]
17506 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17507 (use (match_dup 2))
17508 (use (match_dup 3))
17509 (clobber (match_dup 5))])]
17512 (define_insn "fist<mode>2_floor"
17513 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17514 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17515 UNSPEC_FIST_FLOOR))
17516 (use (match_operand:HI 2 "memory_operand" "m"))
17517 (use (match_operand:HI 3 "memory_operand" "m"))]
17518 "TARGET_USE_FANCY_MATH_387
17519 && flag_unsafe_math_optimizations"
17520 "* return output_fix_trunc (insn, operands, 0);"
17521 [(set_attr "type" "fistp")
17522 (set_attr "i387_cw" "floor")
17523 (set_attr "mode" "<MODE>")])
17525 (define_insn "fist<mode>2_floor_with_temp"
17526 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17527 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17528 UNSPEC_FIST_FLOOR))
17529 (use (match_operand:HI 2 "memory_operand" "m,m"))
17530 (use (match_operand:HI 3 "memory_operand" "m,m"))
17531 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17532 "TARGET_USE_FANCY_MATH_387
17533 && flag_unsafe_math_optimizations"
17535 [(set_attr "type" "fistp")
17536 (set_attr "i387_cw" "floor")
17537 (set_attr "mode" "<MODE>")])
17540 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17541 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17542 UNSPEC_FIST_FLOOR))
17543 (use (match_operand:HI 2 "memory_operand" ""))
17544 (use (match_operand:HI 3 "memory_operand" ""))
17545 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17547 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17548 UNSPEC_FIST_FLOOR))
17549 (use (match_dup 2))
17550 (use (match_dup 3))])
17551 (set (match_dup 0) (match_dup 4))]
17555 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17556 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17557 UNSPEC_FIST_FLOOR))
17558 (use (match_operand:HI 2 "memory_operand" ""))
17559 (use (match_operand:HI 3 "memory_operand" ""))
17560 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17562 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17563 UNSPEC_FIST_FLOOR))
17564 (use (match_dup 2))
17565 (use (match_dup 3))])]
17568 (define_expand "lfloor<mode>2"
17569 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17570 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17571 UNSPEC_FIST_FLOOR))
17572 (clobber (reg:CC FLAGS_REG))])]
17573 "TARGET_USE_FANCY_MATH_387
17574 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17575 && flag_unsafe_math_optimizations"
17578 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17579 (define_insn_and_split "frndintxf2_ceil"
17580 [(set (match_operand:XF 0 "register_operand" "=f")
17581 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17582 UNSPEC_FRNDINT_CEIL))
17583 (clobber (reg:CC FLAGS_REG))]
17584 "TARGET_USE_FANCY_MATH_387
17585 && flag_unsafe_math_optimizations
17586 && !(reload_completed || reload_in_progress)"
17591 ix86_optimize_mode_switching[I387_CEIL] = 1;
17593 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17594 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17596 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17597 operands[2], operands[3]));
17600 [(set_attr "type" "frndint")
17601 (set_attr "i387_cw" "ceil")
17602 (set_attr "mode" "XF")])
17604 (define_insn "frndintxf2_ceil_i387"
17605 [(set (match_operand:XF 0 "register_operand" "=f")
17606 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17607 UNSPEC_FRNDINT_CEIL))
17608 (use (match_operand:HI 2 "memory_operand" "m"))
17609 (use (match_operand:HI 3 "memory_operand" "m"))]
17610 "TARGET_USE_FANCY_MATH_387
17611 && flag_unsafe_math_optimizations"
17612 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17613 [(set_attr "type" "frndint")
17614 (set_attr "i387_cw" "ceil")
17615 (set_attr "mode" "XF")])
17617 (define_expand "ceilxf2"
17618 [(use (match_operand:XF 0 "register_operand" ""))
17619 (use (match_operand:XF 1 "register_operand" ""))]
17620 "TARGET_USE_FANCY_MATH_387
17621 && flag_unsafe_math_optimizations"
17623 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17627 (define_expand "ceildf2"
17628 [(use (match_operand:DF 0 "register_operand" ""))
17629 (use (match_operand:DF 1 "register_operand" ""))]
17630 "TARGET_USE_FANCY_MATH_387
17631 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17632 && flag_unsafe_math_optimizations"
17634 rtx op0 = gen_reg_rtx (XFmode);
17635 rtx op1 = gen_reg_rtx (XFmode);
17637 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17638 emit_insn (gen_frndintxf2_ceil (op0, op1));
17640 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17644 (define_expand "ceilsf2"
17645 [(use (match_operand:SF 0 "register_operand" ""))
17646 (use (match_operand:SF 1 "register_operand" ""))]
17647 "TARGET_USE_FANCY_MATH_387
17648 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17649 && flag_unsafe_math_optimizations"
17651 rtx op0 = gen_reg_rtx (XFmode);
17652 rtx op1 = gen_reg_rtx (XFmode);
17654 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17655 emit_insn (gen_frndintxf2_ceil (op0, op1));
17657 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17661 (define_insn_and_split "*fist<mode>2_ceil_1"
17662 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17663 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17665 (clobber (reg:CC FLAGS_REG))]
17666 "TARGET_USE_FANCY_MATH_387
17667 && flag_unsafe_math_optimizations
17668 && !(reload_completed || reload_in_progress)"
17673 ix86_optimize_mode_switching[I387_CEIL] = 1;
17675 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17676 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17677 if (memory_operand (operands[0], VOIDmode))
17678 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17679 operands[2], operands[3]));
17682 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17683 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17684 operands[2], operands[3],
17689 [(set_attr "type" "fistp")
17690 (set_attr "i387_cw" "ceil")
17691 (set_attr "mode" "<MODE>")])
17693 (define_insn "fistdi2_ceil"
17694 [(set (match_operand:DI 0 "memory_operand" "=m")
17695 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17697 (use (match_operand:HI 2 "memory_operand" "m"))
17698 (use (match_operand:HI 3 "memory_operand" "m"))
17699 (clobber (match_scratch:XF 4 "=&1f"))]
17700 "TARGET_USE_FANCY_MATH_387
17701 && flag_unsafe_math_optimizations"
17702 "* return output_fix_trunc (insn, operands, 0);"
17703 [(set_attr "type" "fistp")
17704 (set_attr "i387_cw" "ceil")
17705 (set_attr "mode" "DI")])
17707 (define_insn "fistdi2_ceil_with_temp"
17708 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17709 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17711 (use (match_operand:HI 2 "memory_operand" "m,m"))
17712 (use (match_operand:HI 3 "memory_operand" "m,m"))
17713 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17714 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17715 "TARGET_USE_FANCY_MATH_387
17716 && flag_unsafe_math_optimizations"
17718 [(set_attr "type" "fistp")
17719 (set_attr "i387_cw" "ceil")
17720 (set_attr "mode" "DI")])
17723 [(set (match_operand:DI 0 "register_operand" "")
17724 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17726 (use (match_operand:HI 2 "memory_operand" ""))
17727 (use (match_operand:HI 3 "memory_operand" ""))
17728 (clobber (match_operand:DI 4 "memory_operand" ""))
17729 (clobber (match_scratch 5 ""))]
17731 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17732 (use (match_dup 2))
17733 (use (match_dup 3))
17734 (clobber (match_dup 5))])
17735 (set (match_dup 0) (match_dup 4))]
17739 [(set (match_operand:DI 0 "memory_operand" "")
17740 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17742 (use (match_operand:HI 2 "memory_operand" ""))
17743 (use (match_operand:HI 3 "memory_operand" ""))
17744 (clobber (match_operand:DI 4 "memory_operand" ""))
17745 (clobber (match_scratch 5 ""))]
17747 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17748 (use (match_dup 2))
17749 (use (match_dup 3))
17750 (clobber (match_dup 5))])]
17753 (define_insn "fist<mode>2_ceil"
17754 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17755 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17757 (use (match_operand:HI 2 "memory_operand" "m"))
17758 (use (match_operand:HI 3 "memory_operand" "m"))]
17759 "TARGET_USE_FANCY_MATH_387
17760 && flag_unsafe_math_optimizations"
17761 "* return output_fix_trunc (insn, operands, 0);"
17762 [(set_attr "type" "fistp")
17763 (set_attr "i387_cw" "ceil")
17764 (set_attr "mode" "<MODE>")])
17766 (define_insn "fist<mode>2_ceil_with_temp"
17767 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17768 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17770 (use (match_operand:HI 2 "memory_operand" "m,m"))
17771 (use (match_operand:HI 3 "memory_operand" "m,m"))
17772 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17773 "TARGET_USE_FANCY_MATH_387
17774 && flag_unsafe_math_optimizations"
17776 [(set_attr "type" "fistp")
17777 (set_attr "i387_cw" "ceil")
17778 (set_attr "mode" "<MODE>")])
17781 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17782 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17784 (use (match_operand:HI 2 "memory_operand" ""))
17785 (use (match_operand:HI 3 "memory_operand" ""))
17786 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17788 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17790 (use (match_dup 2))
17791 (use (match_dup 3))])
17792 (set (match_dup 0) (match_dup 4))]
17796 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17797 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17799 (use (match_operand:HI 2 "memory_operand" ""))
17800 (use (match_operand:HI 3 "memory_operand" ""))
17801 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17803 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17805 (use (match_dup 2))
17806 (use (match_dup 3))])]
17809 (define_expand "lceil<mode>2"
17810 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17811 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17813 (clobber (reg:CC FLAGS_REG))])]
17814 "TARGET_USE_FANCY_MATH_387
17815 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17816 && flag_unsafe_math_optimizations"
17819 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17820 (define_insn_and_split "frndintxf2_trunc"
17821 [(set (match_operand:XF 0 "register_operand" "=f")
17822 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17823 UNSPEC_FRNDINT_TRUNC))
17824 (clobber (reg:CC FLAGS_REG))]
17825 "TARGET_USE_FANCY_MATH_387
17826 && flag_unsafe_math_optimizations
17827 && !(reload_completed || reload_in_progress)"
17832 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17834 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17835 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17837 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17838 operands[2], operands[3]));
17841 [(set_attr "type" "frndint")
17842 (set_attr "i387_cw" "trunc")
17843 (set_attr "mode" "XF")])
17845 (define_insn "frndintxf2_trunc_i387"
17846 [(set (match_operand:XF 0 "register_operand" "=f")
17847 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17848 UNSPEC_FRNDINT_TRUNC))
17849 (use (match_operand:HI 2 "memory_operand" "m"))
17850 (use (match_operand:HI 3 "memory_operand" "m"))]
17851 "TARGET_USE_FANCY_MATH_387
17852 && flag_unsafe_math_optimizations"
17853 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17854 [(set_attr "type" "frndint")
17855 (set_attr "i387_cw" "trunc")
17856 (set_attr "mode" "XF")])
17858 (define_expand "btruncxf2"
17859 [(use (match_operand:XF 0 "register_operand" ""))
17860 (use (match_operand:XF 1 "register_operand" ""))]
17861 "TARGET_USE_FANCY_MATH_387
17862 && flag_unsafe_math_optimizations"
17864 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17868 (define_expand "btruncdf2"
17869 [(use (match_operand:DF 0 "register_operand" ""))
17870 (use (match_operand:DF 1 "register_operand" ""))]
17871 "TARGET_USE_FANCY_MATH_387
17872 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17873 && flag_unsafe_math_optimizations"
17875 rtx op0 = gen_reg_rtx (XFmode);
17876 rtx op1 = gen_reg_rtx (XFmode);
17878 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17879 emit_insn (gen_frndintxf2_trunc (op0, op1));
17881 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17885 (define_expand "btruncsf2"
17886 [(use (match_operand:SF 0 "register_operand" ""))
17887 (use (match_operand:SF 1 "register_operand" ""))]
17888 "TARGET_USE_FANCY_MATH_387
17889 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17890 && flag_unsafe_math_optimizations"
17892 rtx op0 = gen_reg_rtx (XFmode);
17893 rtx op1 = gen_reg_rtx (XFmode);
17895 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17896 emit_insn (gen_frndintxf2_trunc (op0, op1));
17898 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17902 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17903 (define_insn_and_split "frndintxf2_mask_pm"
17904 [(set (match_operand:XF 0 "register_operand" "=f")
17905 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17906 UNSPEC_FRNDINT_MASK_PM))
17907 (clobber (reg:CC FLAGS_REG))]
17908 "TARGET_USE_FANCY_MATH_387
17909 && flag_unsafe_math_optimizations
17910 && !(reload_completed || reload_in_progress)"
17915 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17917 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17918 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17920 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17921 operands[2], operands[3]));
17924 [(set_attr "type" "frndint")
17925 (set_attr "i387_cw" "mask_pm")
17926 (set_attr "mode" "XF")])
17928 (define_insn "frndintxf2_mask_pm_i387"
17929 [(set (match_operand:XF 0 "register_operand" "=f")
17930 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17931 UNSPEC_FRNDINT_MASK_PM))
17932 (use (match_operand:HI 2 "memory_operand" "m"))
17933 (use (match_operand:HI 3 "memory_operand" "m"))]
17934 "TARGET_USE_FANCY_MATH_387
17935 && flag_unsafe_math_optimizations"
17936 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17937 [(set_attr "type" "frndint")
17938 (set_attr "i387_cw" "mask_pm")
17939 (set_attr "mode" "XF")])
17941 (define_expand "nearbyintxf2"
17942 [(use (match_operand:XF 0 "register_operand" ""))
17943 (use (match_operand:XF 1 "register_operand" ""))]
17944 "TARGET_USE_FANCY_MATH_387
17945 && flag_unsafe_math_optimizations"
17947 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17952 (define_expand "nearbyintdf2"
17953 [(use (match_operand:DF 0 "register_operand" ""))
17954 (use (match_operand:DF 1 "register_operand" ""))]
17955 "TARGET_USE_FANCY_MATH_387
17956 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17957 && flag_unsafe_math_optimizations"
17959 rtx op0 = gen_reg_rtx (XFmode);
17960 rtx op1 = gen_reg_rtx (XFmode);
17962 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17963 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17965 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17969 (define_expand "nearbyintsf2"
17970 [(use (match_operand:SF 0 "register_operand" ""))
17971 (use (match_operand:SF 1 "register_operand" ""))]
17972 "TARGET_USE_FANCY_MATH_387
17973 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17974 && flag_unsafe_math_optimizations"
17976 rtx op0 = gen_reg_rtx (XFmode);
17977 rtx op1 = gen_reg_rtx (XFmode);
17979 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17980 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17982 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17987 ;; Block operation instructions
17990 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
17993 [(set_attr "type" "cld")])
17995 (define_expand "movmemsi"
17996 [(use (match_operand:BLK 0 "memory_operand" ""))
17997 (use (match_operand:BLK 1 "memory_operand" ""))
17998 (use (match_operand:SI 2 "nonmemory_operand" ""))
17999 (use (match_operand:SI 3 "const_int_operand" ""))]
18000 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18002 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18008 (define_expand "movmemdi"
18009 [(use (match_operand:BLK 0 "memory_operand" ""))
18010 (use (match_operand:BLK 1 "memory_operand" ""))
18011 (use (match_operand:DI 2 "nonmemory_operand" ""))
18012 (use (match_operand:DI 3 "const_int_operand" ""))]
18015 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18021 ;; Most CPUs don't like single string operations
18022 ;; Handle this case here to simplify previous expander.
18024 (define_expand "strmov"
18025 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18026 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18027 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18028 (clobber (reg:CC FLAGS_REG))])
18029 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18030 (clobber (reg:CC FLAGS_REG))])]
18033 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18035 /* If .md ever supports :P for Pmode, these can be directly
18036 in the pattern above. */
18037 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18038 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18040 if (TARGET_SINGLE_STRINGOP || optimize_size)
18042 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18043 operands[2], operands[3],
18044 operands[5], operands[6]));
18048 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18051 (define_expand "strmov_singleop"
18052 [(parallel [(set (match_operand 1 "memory_operand" "")
18053 (match_operand 3 "memory_operand" ""))
18054 (set (match_operand 0 "register_operand" "")
18055 (match_operand 4 "" ""))
18056 (set (match_operand 2 "register_operand" "")
18057 (match_operand 5 "" ""))
18058 (use (reg:SI DIRFLAG_REG))])]
18059 "TARGET_SINGLE_STRINGOP || optimize_size"
18062 (define_insn "*strmovdi_rex_1"
18063 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18064 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18065 (set (match_operand:DI 0 "register_operand" "=D")
18066 (plus:DI (match_dup 2)
18068 (set (match_operand:DI 1 "register_operand" "=S")
18069 (plus:DI (match_dup 3)
18071 (use (reg:SI DIRFLAG_REG))]
18072 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18074 [(set_attr "type" "str")
18075 (set_attr "mode" "DI")
18076 (set_attr "memory" "both")])
18078 (define_insn "*strmovsi_1"
18079 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18080 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18081 (set (match_operand:SI 0 "register_operand" "=D")
18082 (plus:SI (match_dup 2)
18084 (set (match_operand:SI 1 "register_operand" "=S")
18085 (plus:SI (match_dup 3)
18087 (use (reg:SI DIRFLAG_REG))]
18088 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18090 [(set_attr "type" "str")
18091 (set_attr "mode" "SI")
18092 (set_attr "memory" "both")])
18094 (define_insn "*strmovsi_rex_1"
18095 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18096 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18097 (set (match_operand:DI 0 "register_operand" "=D")
18098 (plus:DI (match_dup 2)
18100 (set (match_operand:DI 1 "register_operand" "=S")
18101 (plus:DI (match_dup 3)
18103 (use (reg:SI DIRFLAG_REG))]
18104 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18106 [(set_attr "type" "str")
18107 (set_attr "mode" "SI")
18108 (set_attr "memory" "both")])
18110 (define_insn "*strmovhi_1"
18111 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18112 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18113 (set (match_operand:SI 0 "register_operand" "=D")
18114 (plus:SI (match_dup 2)
18116 (set (match_operand:SI 1 "register_operand" "=S")
18117 (plus:SI (match_dup 3)
18119 (use (reg:SI DIRFLAG_REG))]
18120 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18122 [(set_attr "type" "str")
18123 (set_attr "memory" "both")
18124 (set_attr "mode" "HI")])
18126 (define_insn "*strmovhi_rex_1"
18127 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18128 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18129 (set (match_operand:DI 0 "register_operand" "=D")
18130 (plus:DI (match_dup 2)
18132 (set (match_operand:DI 1 "register_operand" "=S")
18133 (plus:DI (match_dup 3)
18135 (use (reg:SI DIRFLAG_REG))]
18136 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18138 [(set_attr "type" "str")
18139 (set_attr "memory" "both")
18140 (set_attr "mode" "HI")])
18142 (define_insn "*strmovqi_1"
18143 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18144 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18145 (set (match_operand:SI 0 "register_operand" "=D")
18146 (plus:SI (match_dup 2)
18148 (set (match_operand:SI 1 "register_operand" "=S")
18149 (plus:SI (match_dup 3)
18151 (use (reg:SI DIRFLAG_REG))]
18152 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18154 [(set_attr "type" "str")
18155 (set_attr "memory" "both")
18156 (set_attr "mode" "QI")])
18158 (define_insn "*strmovqi_rex_1"
18159 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18160 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18161 (set (match_operand:DI 0 "register_operand" "=D")
18162 (plus:DI (match_dup 2)
18164 (set (match_operand:DI 1 "register_operand" "=S")
18165 (plus:DI (match_dup 3)
18167 (use (reg:SI DIRFLAG_REG))]
18168 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18170 [(set_attr "type" "str")
18171 (set_attr "memory" "both")
18172 (set_attr "mode" "QI")])
18174 (define_expand "rep_mov"
18175 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18176 (set (match_operand 0 "register_operand" "")
18177 (match_operand 5 "" ""))
18178 (set (match_operand 2 "register_operand" "")
18179 (match_operand 6 "" ""))
18180 (set (match_operand 1 "memory_operand" "")
18181 (match_operand 3 "memory_operand" ""))
18182 (use (match_dup 4))
18183 (use (reg:SI DIRFLAG_REG))])]
18187 (define_insn "*rep_movdi_rex64"
18188 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18189 (set (match_operand:DI 0 "register_operand" "=D")
18190 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18192 (match_operand:DI 3 "register_operand" "0")))
18193 (set (match_operand:DI 1 "register_operand" "=S")
18194 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18195 (match_operand:DI 4 "register_operand" "1")))
18196 (set (mem:BLK (match_dup 3))
18197 (mem:BLK (match_dup 4)))
18198 (use (match_dup 5))
18199 (use (reg:SI DIRFLAG_REG))]
18201 "{rep\;movsq|rep movsq}"
18202 [(set_attr "type" "str")
18203 (set_attr "prefix_rep" "1")
18204 (set_attr "memory" "both")
18205 (set_attr "mode" "DI")])
18207 (define_insn "*rep_movsi"
18208 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18209 (set (match_operand:SI 0 "register_operand" "=D")
18210 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18212 (match_operand:SI 3 "register_operand" "0")))
18213 (set (match_operand:SI 1 "register_operand" "=S")
18214 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18215 (match_operand:SI 4 "register_operand" "1")))
18216 (set (mem:BLK (match_dup 3))
18217 (mem:BLK (match_dup 4)))
18218 (use (match_dup 5))
18219 (use (reg:SI DIRFLAG_REG))]
18221 "{rep\;movsl|rep movsd}"
18222 [(set_attr "type" "str")
18223 (set_attr "prefix_rep" "1")
18224 (set_attr "memory" "both")
18225 (set_attr "mode" "SI")])
18227 (define_insn "*rep_movsi_rex64"
18228 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18229 (set (match_operand:DI 0 "register_operand" "=D")
18230 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18232 (match_operand:DI 3 "register_operand" "0")))
18233 (set (match_operand:DI 1 "register_operand" "=S")
18234 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18235 (match_operand:DI 4 "register_operand" "1")))
18236 (set (mem:BLK (match_dup 3))
18237 (mem:BLK (match_dup 4)))
18238 (use (match_dup 5))
18239 (use (reg:SI DIRFLAG_REG))]
18241 "{rep\;movsl|rep movsd}"
18242 [(set_attr "type" "str")
18243 (set_attr "prefix_rep" "1")
18244 (set_attr "memory" "both")
18245 (set_attr "mode" "SI")])
18247 (define_insn "*rep_movqi"
18248 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18249 (set (match_operand:SI 0 "register_operand" "=D")
18250 (plus:SI (match_operand:SI 3 "register_operand" "0")
18251 (match_operand:SI 5 "register_operand" "2")))
18252 (set (match_operand:SI 1 "register_operand" "=S")
18253 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18254 (set (mem:BLK (match_dup 3))
18255 (mem:BLK (match_dup 4)))
18256 (use (match_dup 5))
18257 (use (reg:SI DIRFLAG_REG))]
18259 "{rep\;movsb|rep movsb}"
18260 [(set_attr "type" "str")
18261 (set_attr "prefix_rep" "1")
18262 (set_attr "memory" "both")
18263 (set_attr "mode" "SI")])
18265 (define_insn "*rep_movqi_rex64"
18266 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18267 (set (match_operand:DI 0 "register_operand" "=D")
18268 (plus:DI (match_operand:DI 3 "register_operand" "0")
18269 (match_operand:DI 5 "register_operand" "2")))
18270 (set (match_operand:DI 1 "register_operand" "=S")
18271 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18272 (set (mem:BLK (match_dup 3))
18273 (mem:BLK (match_dup 4)))
18274 (use (match_dup 5))
18275 (use (reg:SI DIRFLAG_REG))]
18277 "{rep\;movsb|rep movsb}"
18278 [(set_attr "type" "str")
18279 (set_attr "prefix_rep" "1")
18280 (set_attr "memory" "both")
18281 (set_attr "mode" "SI")])
18283 (define_expand "setmemsi"
18284 [(use (match_operand:BLK 0 "memory_operand" ""))
18285 (use (match_operand:SI 1 "nonmemory_operand" ""))
18286 (use (match_operand 2 "const_int_operand" ""))
18287 (use (match_operand 3 "const_int_operand" ""))]
18290 /* If value to set is not zero, use the library routine. */
18291 if (operands[2] != const0_rtx)
18294 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18300 (define_expand "setmemdi"
18301 [(use (match_operand:BLK 0 "memory_operand" ""))
18302 (use (match_operand:DI 1 "nonmemory_operand" ""))
18303 (use (match_operand 2 "const_int_operand" ""))
18304 (use (match_operand 3 "const_int_operand" ""))]
18307 /* If value to set is not zero, use the library routine. */
18308 if (operands[2] != const0_rtx)
18311 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18317 ;; Most CPUs don't like single string operations
18318 ;; Handle this case here to simplify previous expander.
18320 (define_expand "strset"
18321 [(set (match_operand 1 "memory_operand" "")
18322 (match_operand 2 "register_operand" ""))
18323 (parallel [(set (match_operand 0 "register_operand" "")
18325 (clobber (reg:CC FLAGS_REG))])]
18328 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18329 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18331 /* If .md ever supports :P for Pmode, this can be directly
18332 in the pattern above. */
18333 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18334 GEN_INT (GET_MODE_SIZE (GET_MODE
18336 if (TARGET_SINGLE_STRINGOP || optimize_size)
18338 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18344 (define_expand "strset_singleop"
18345 [(parallel [(set (match_operand 1 "memory_operand" "")
18346 (match_operand 2 "register_operand" ""))
18347 (set (match_operand 0 "register_operand" "")
18348 (match_operand 3 "" ""))
18349 (use (reg:SI DIRFLAG_REG))])]
18350 "TARGET_SINGLE_STRINGOP || optimize_size"
18353 (define_insn "*strsetdi_rex_1"
18354 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18355 (match_operand:DI 2 "register_operand" "a"))
18356 (set (match_operand:DI 0 "register_operand" "=D")
18357 (plus:DI (match_dup 1)
18359 (use (reg:SI DIRFLAG_REG))]
18360 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18362 [(set_attr "type" "str")
18363 (set_attr "memory" "store")
18364 (set_attr "mode" "DI")])
18366 (define_insn "*strsetsi_1"
18367 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18368 (match_operand:SI 2 "register_operand" "a"))
18369 (set (match_operand:SI 0 "register_operand" "=D")
18370 (plus:SI (match_dup 1)
18372 (use (reg:SI DIRFLAG_REG))]
18373 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18375 [(set_attr "type" "str")
18376 (set_attr "memory" "store")
18377 (set_attr "mode" "SI")])
18379 (define_insn "*strsetsi_rex_1"
18380 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18381 (match_operand:SI 2 "register_operand" "a"))
18382 (set (match_operand:DI 0 "register_operand" "=D")
18383 (plus:DI (match_dup 1)
18385 (use (reg:SI DIRFLAG_REG))]
18386 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18388 [(set_attr "type" "str")
18389 (set_attr "memory" "store")
18390 (set_attr "mode" "SI")])
18392 (define_insn "*strsethi_1"
18393 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18394 (match_operand:HI 2 "register_operand" "a"))
18395 (set (match_operand:SI 0 "register_operand" "=D")
18396 (plus:SI (match_dup 1)
18398 (use (reg:SI DIRFLAG_REG))]
18399 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18401 [(set_attr "type" "str")
18402 (set_attr "memory" "store")
18403 (set_attr "mode" "HI")])
18405 (define_insn "*strsethi_rex_1"
18406 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18407 (match_operand:HI 2 "register_operand" "a"))
18408 (set (match_operand:DI 0 "register_operand" "=D")
18409 (plus:DI (match_dup 1)
18411 (use (reg:SI DIRFLAG_REG))]
18412 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18414 [(set_attr "type" "str")
18415 (set_attr "memory" "store")
18416 (set_attr "mode" "HI")])
18418 (define_insn "*strsetqi_1"
18419 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18420 (match_operand:QI 2 "register_operand" "a"))
18421 (set (match_operand:SI 0 "register_operand" "=D")
18422 (plus:SI (match_dup 1)
18424 (use (reg:SI DIRFLAG_REG))]
18425 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18427 [(set_attr "type" "str")
18428 (set_attr "memory" "store")
18429 (set_attr "mode" "QI")])
18431 (define_insn "*strsetqi_rex_1"
18432 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18433 (match_operand:QI 2 "register_operand" "a"))
18434 (set (match_operand:DI 0 "register_operand" "=D")
18435 (plus:DI (match_dup 1)
18437 (use (reg:SI DIRFLAG_REG))]
18438 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18440 [(set_attr "type" "str")
18441 (set_attr "memory" "store")
18442 (set_attr "mode" "QI")])
18444 (define_expand "rep_stos"
18445 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18446 (set (match_operand 0 "register_operand" "")
18447 (match_operand 4 "" ""))
18448 (set (match_operand 2 "memory_operand" "") (const_int 0))
18449 (use (match_operand 3 "register_operand" ""))
18450 (use (match_dup 1))
18451 (use (reg:SI DIRFLAG_REG))])]
18455 (define_insn "*rep_stosdi_rex64"
18456 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18457 (set (match_operand:DI 0 "register_operand" "=D")
18458 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18460 (match_operand:DI 3 "register_operand" "0")))
18461 (set (mem:BLK (match_dup 3))
18463 (use (match_operand:DI 2 "register_operand" "a"))
18464 (use (match_dup 4))
18465 (use (reg:SI DIRFLAG_REG))]
18467 "{rep\;stosq|rep stosq}"
18468 [(set_attr "type" "str")
18469 (set_attr "prefix_rep" "1")
18470 (set_attr "memory" "store")
18471 (set_attr "mode" "DI")])
18473 (define_insn "*rep_stossi"
18474 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18475 (set (match_operand:SI 0 "register_operand" "=D")
18476 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18478 (match_operand:SI 3 "register_operand" "0")))
18479 (set (mem:BLK (match_dup 3))
18481 (use (match_operand:SI 2 "register_operand" "a"))
18482 (use (match_dup 4))
18483 (use (reg:SI DIRFLAG_REG))]
18485 "{rep\;stosl|rep stosd}"
18486 [(set_attr "type" "str")
18487 (set_attr "prefix_rep" "1")
18488 (set_attr "memory" "store")
18489 (set_attr "mode" "SI")])
18491 (define_insn "*rep_stossi_rex64"
18492 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18493 (set (match_operand:DI 0 "register_operand" "=D")
18494 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18496 (match_operand:DI 3 "register_operand" "0")))
18497 (set (mem:BLK (match_dup 3))
18499 (use (match_operand:SI 2 "register_operand" "a"))
18500 (use (match_dup 4))
18501 (use (reg:SI DIRFLAG_REG))]
18503 "{rep\;stosl|rep stosd}"
18504 [(set_attr "type" "str")
18505 (set_attr "prefix_rep" "1")
18506 (set_attr "memory" "store")
18507 (set_attr "mode" "SI")])
18509 (define_insn "*rep_stosqi"
18510 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18511 (set (match_operand:SI 0 "register_operand" "=D")
18512 (plus:SI (match_operand:SI 3 "register_operand" "0")
18513 (match_operand:SI 4 "register_operand" "1")))
18514 (set (mem:BLK (match_dup 3))
18516 (use (match_operand:QI 2 "register_operand" "a"))
18517 (use (match_dup 4))
18518 (use (reg:SI DIRFLAG_REG))]
18520 "{rep\;stosb|rep stosb}"
18521 [(set_attr "type" "str")
18522 (set_attr "prefix_rep" "1")
18523 (set_attr "memory" "store")
18524 (set_attr "mode" "QI")])
18526 (define_insn "*rep_stosqi_rex64"
18527 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18528 (set (match_operand:DI 0 "register_operand" "=D")
18529 (plus:DI (match_operand:DI 3 "register_operand" "0")
18530 (match_operand:DI 4 "register_operand" "1")))
18531 (set (mem:BLK (match_dup 3))
18533 (use (match_operand:QI 2 "register_operand" "a"))
18534 (use (match_dup 4))
18535 (use (reg:SI DIRFLAG_REG))]
18537 "{rep\;stosb|rep stosb}"
18538 [(set_attr "type" "str")
18539 (set_attr "prefix_rep" "1")
18540 (set_attr "memory" "store")
18541 (set_attr "mode" "QI")])
18543 (define_expand "cmpstrnsi"
18544 [(set (match_operand:SI 0 "register_operand" "")
18545 (compare:SI (match_operand:BLK 1 "general_operand" "")
18546 (match_operand:BLK 2 "general_operand" "")))
18547 (use (match_operand 3 "general_operand" ""))
18548 (use (match_operand 4 "immediate_operand" ""))]
18549 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18551 rtx addr1, addr2, out, outlow, count, countreg, align;
18553 /* Can't use this if the user has appropriated esi or edi. */
18554 if (global_regs[4] || global_regs[5])
18558 if (GET_CODE (out) != REG)
18559 out = gen_reg_rtx (SImode);
18561 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18562 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18563 if (addr1 != XEXP (operands[1], 0))
18564 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18565 if (addr2 != XEXP (operands[2], 0))
18566 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18568 count = operands[3];
18569 countreg = ix86_zero_extend_to_Pmode (count);
18571 /* %%% Iff we are testing strict equality, we can use known alignment
18572 to good advantage. This may be possible with combine, particularly
18573 once cc0 is dead. */
18574 align = operands[4];
18576 emit_insn (gen_cld ());
18577 if (GET_CODE (count) == CONST_INT)
18579 if (INTVAL (count) == 0)
18581 emit_move_insn (operands[0], const0_rtx);
18584 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18585 operands[1], operands[2]));
18590 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18592 emit_insn (gen_cmpsi_1 (countreg, countreg));
18593 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18594 operands[1], operands[2]));
18597 outlow = gen_lowpart (QImode, out);
18598 emit_insn (gen_cmpintqi (outlow));
18599 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18601 if (operands[0] != out)
18602 emit_move_insn (operands[0], out);
18607 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18609 (define_expand "cmpintqi"
18610 [(set (match_dup 1)
18611 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18613 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18614 (parallel [(set (match_operand:QI 0 "register_operand" "")
18615 (minus:QI (match_dup 1)
18617 (clobber (reg:CC FLAGS_REG))])]
18619 "operands[1] = gen_reg_rtx (QImode);
18620 operands[2] = gen_reg_rtx (QImode);")
18622 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18623 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18625 (define_expand "cmpstrnqi_nz_1"
18626 [(parallel [(set (reg:CC FLAGS_REG)
18627 (compare:CC (match_operand 4 "memory_operand" "")
18628 (match_operand 5 "memory_operand" "")))
18629 (use (match_operand 2 "register_operand" ""))
18630 (use (match_operand:SI 3 "immediate_operand" ""))
18631 (use (reg:SI DIRFLAG_REG))
18632 (clobber (match_operand 0 "register_operand" ""))
18633 (clobber (match_operand 1 "register_operand" ""))
18634 (clobber (match_dup 2))])]
18638 (define_insn "*cmpstrnqi_nz_1"
18639 [(set (reg:CC FLAGS_REG)
18640 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18641 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18642 (use (match_operand:SI 6 "register_operand" "2"))
18643 (use (match_operand:SI 3 "immediate_operand" "i"))
18644 (use (reg:SI DIRFLAG_REG))
18645 (clobber (match_operand:SI 0 "register_operand" "=S"))
18646 (clobber (match_operand:SI 1 "register_operand" "=D"))
18647 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18650 [(set_attr "type" "str")
18651 (set_attr "mode" "QI")
18652 (set_attr "prefix_rep" "1")])
18654 (define_insn "*cmpstrnqi_nz_rex_1"
18655 [(set (reg:CC FLAGS_REG)
18656 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18657 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18658 (use (match_operand:DI 6 "register_operand" "2"))
18659 (use (match_operand:SI 3 "immediate_operand" "i"))
18660 (use (reg:SI DIRFLAG_REG))
18661 (clobber (match_operand:DI 0 "register_operand" "=S"))
18662 (clobber (match_operand:DI 1 "register_operand" "=D"))
18663 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18666 [(set_attr "type" "str")
18667 (set_attr "mode" "QI")
18668 (set_attr "prefix_rep" "1")])
18670 ;; The same, but the count is not known to not be zero.
18672 (define_expand "cmpstrnqi_1"
18673 [(parallel [(set (reg:CC FLAGS_REG)
18674 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18676 (compare:CC (match_operand 4 "memory_operand" "")
18677 (match_operand 5 "memory_operand" ""))
18679 (use (match_operand:SI 3 "immediate_operand" ""))
18680 (use (reg:CC FLAGS_REG))
18681 (use (reg:SI DIRFLAG_REG))
18682 (clobber (match_operand 0 "register_operand" ""))
18683 (clobber (match_operand 1 "register_operand" ""))
18684 (clobber (match_dup 2))])]
18688 (define_insn "*cmpstrnqi_1"
18689 [(set (reg:CC FLAGS_REG)
18690 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18692 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18693 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18695 (use (match_operand:SI 3 "immediate_operand" "i"))
18696 (use (reg:CC FLAGS_REG))
18697 (use (reg:SI DIRFLAG_REG))
18698 (clobber (match_operand:SI 0 "register_operand" "=S"))
18699 (clobber (match_operand:SI 1 "register_operand" "=D"))
18700 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18703 [(set_attr "type" "str")
18704 (set_attr "mode" "QI")
18705 (set_attr "prefix_rep" "1")])
18707 (define_insn "*cmpstrnqi_rex_1"
18708 [(set (reg:CC FLAGS_REG)
18709 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18711 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18712 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18714 (use (match_operand:SI 3 "immediate_operand" "i"))
18715 (use (reg:CC FLAGS_REG))
18716 (use (reg:SI DIRFLAG_REG))
18717 (clobber (match_operand:DI 0 "register_operand" "=S"))
18718 (clobber (match_operand:DI 1 "register_operand" "=D"))
18719 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18722 [(set_attr "type" "str")
18723 (set_attr "mode" "QI")
18724 (set_attr "prefix_rep" "1")])
18726 (define_expand "strlensi"
18727 [(set (match_operand:SI 0 "register_operand" "")
18728 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18729 (match_operand:QI 2 "immediate_operand" "")
18730 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18733 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18739 (define_expand "strlendi"
18740 [(set (match_operand:DI 0 "register_operand" "")
18741 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18742 (match_operand:QI 2 "immediate_operand" "")
18743 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18746 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18752 (define_expand "strlenqi_1"
18753 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18754 (use (reg:SI DIRFLAG_REG))
18755 (clobber (match_operand 1 "register_operand" ""))
18756 (clobber (reg:CC FLAGS_REG))])]
18760 (define_insn "*strlenqi_1"
18761 [(set (match_operand:SI 0 "register_operand" "=&c")
18762 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18763 (match_operand:QI 2 "register_operand" "a")
18764 (match_operand:SI 3 "immediate_operand" "i")
18765 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18766 (use (reg:SI DIRFLAG_REG))
18767 (clobber (match_operand:SI 1 "register_operand" "=D"))
18768 (clobber (reg:CC FLAGS_REG))]
18771 [(set_attr "type" "str")
18772 (set_attr "mode" "QI")
18773 (set_attr "prefix_rep" "1")])
18775 (define_insn "*strlenqi_rex_1"
18776 [(set (match_operand:DI 0 "register_operand" "=&c")
18777 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18778 (match_operand:QI 2 "register_operand" "a")
18779 (match_operand:DI 3 "immediate_operand" "i")
18780 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18781 (use (reg:SI DIRFLAG_REG))
18782 (clobber (match_operand:DI 1 "register_operand" "=D"))
18783 (clobber (reg:CC FLAGS_REG))]
18786 [(set_attr "type" "str")
18787 (set_attr "mode" "QI")
18788 (set_attr "prefix_rep" "1")])
18790 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18791 ;; handled in combine, but it is not currently up to the task.
18792 ;; When used for their truth value, the cmpstrn* expanders generate
18801 ;; The intermediate three instructions are unnecessary.
18803 ;; This one handles cmpstrn*_nz_1...
18806 (set (reg:CC FLAGS_REG)
18807 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18808 (mem:BLK (match_operand 5 "register_operand" ""))))
18809 (use (match_operand 6 "register_operand" ""))
18810 (use (match_operand:SI 3 "immediate_operand" ""))
18811 (use (reg:SI DIRFLAG_REG))
18812 (clobber (match_operand 0 "register_operand" ""))
18813 (clobber (match_operand 1 "register_operand" ""))
18814 (clobber (match_operand 2 "register_operand" ""))])
18815 (set (match_operand:QI 7 "register_operand" "")
18816 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18817 (set (match_operand:QI 8 "register_operand" "")
18818 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18819 (set (reg FLAGS_REG)
18820 (compare (match_dup 7) (match_dup 8)))
18822 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18824 (set (reg:CC FLAGS_REG)
18825 (compare:CC (mem:BLK (match_dup 4))
18826 (mem:BLK (match_dup 5))))
18827 (use (match_dup 6))
18828 (use (match_dup 3))
18829 (use (reg:SI DIRFLAG_REG))
18830 (clobber (match_dup 0))
18831 (clobber (match_dup 1))
18832 (clobber (match_dup 2))])]
18835 ;; ...and this one handles cmpstrn*_1.
18838 (set (reg:CC FLAGS_REG)
18839 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18841 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18842 (mem:BLK (match_operand 5 "register_operand" "")))
18844 (use (match_operand:SI 3 "immediate_operand" ""))
18845 (use (reg:CC FLAGS_REG))
18846 (use (reg:SI DIRFLAG_REG))
18847 (clobber (match_operand 0 "register_operand" ""))
18848 (clobber (match_operand 1 "register_operand" ""))
18849 (clobber (match_operand 2 "register_operand" ""))])
18850 (set (match_operand:QI 7 "register_operand" "")
18851 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18852 (set (match_operand:QI 8 "register_operand" "")
18853 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18854 (set (reg FLAGS_REG)
18855 (compare (match_dup 7) (match_dup 8)))
18857 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18859 (set (reg:CC FLAGS_REG)
18860 (if_then_else:CC (ne (match_dup 6)
18862 (compare:CC (mem:BLK (match_dup 4))
18863 (mem:BLK (match_dup 5)))
18865 (use (match_dup 3))
18866 (use (reg:CC FLAGS_REG))
18867 (use (reg:SI DIRFLAG_REG))
18868 (clobber (match_dup 0))
18869 (clobber (match_dup 1))
18870 (clobber (match_dup 2))])]
18875 ;; Conditional move instructions.
18877 (define_expand "movdicc"
18878 [(set (match_operand:DI 0 "register_operand" "")
18879 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18880 (match_operand:DI 2 "general_operand" "")
18881 (match_operand:DI 3 "general_operand" "")))]
18883 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18885 (define_insn "x86_movdicc_0_m1_rex64"
18886 [(set (match_operand:DI 0 "register_operand" "=r")
18887 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18890 (clobber (reg:CC FLAGS_REG))]
18893 ; Since we don't have the proper number of operands for an alu insn,
18894 ; fill in all the blanks.
18895 [(set_attr "type" "alu")
18896 (set_attr "pent_pair" "pu")
18897 (set_attr "memory" "none")
18898 (set_attr "imm_disp" "false")
18899 (set_attr "mode" "DI")
18900 (set_attr "length_immediate" "0")])
18902 (define_insn "*movdicc_c_rex64"
18903 [(set (match_operand:DI 0 "register_operand" "=r,r")
18904 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18905 [(reg FLAGS_REG) (const_int 0)])
18906 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18907 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18908 "TARGET_64BIT && TARGET_CMOVE
18909 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18911 cmov%O2%C1\t{%2, %0|%0, %2}
18912 cmov%O2%c1\t{%3, %0|%0, %3}"
18913 [(set_attr "type" "icmov")
18914 (set_attr "mode" "DI")])
18916 (define_expand "movsicc"
18917 [(set (match_operand:SI 0 "register_operand" "")
18918 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18919 (match_operand:SI 2 "general_operand" "")
18920 (match_operand:SI 3 "general_operand" "")))]
18922 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18924 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18925 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18926 ;; So just document what we're doing explicitly.
18928 (define_insn "x86_movsicc_0_m1"
18929 [(set (match_operand:SI 0 "register_operand" "=r")
18930 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18933 (clobber (reg:CC FLAGS_REG))]
18936 ; Since we don't have the proper number of operands for an alu insn,
18937 ; fill in all the blanks.
18938 [(set_attr "type" "alu")
18939 (set_attr "pent_pair" "pu")
18940 (set_attr "memory" "none")
18941 (set_attr "imm_disp" "false")
18942 (set_attr "mode" "SI")
18943 (set_attr "length_immediate" "0")])
18945 (define_insn "*movsicc_noc"
18946 [(set (match_operand:SI 0 "register_operand" "=r,r")
18947 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18948 [(reg FLAGS_REG) (const_int 0)])
18949 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18950 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18952 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18954 cmov%O2%C1\t{%2, %0|%0, %2}
18955 cmov%O2%c1\t{%3, %0|%0, %3}"
18956 [(set_attr "type" "icmov")
18957 (set_attr "mode" "SI")])
18959 (define_expand "movhicc"
18960 [(set (match_operand:HI 0 "register_operand" "")
18961 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18962 (match_operand:HI 2 "general_operand" "")
18963 (match_operand:HI 3 "general_operand" "")))]
18964 "TARGET_HIMODE_MATH"
18965 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18967 (define_insn "*movhicc_noc"
18968 [(set (match_operand:HI 0 "register_operand" "=r,r")
18969 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18970 [(reg FLAGS_REG) (const_int 0)])
18971 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18972 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18974 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
18976 cmov%O2%C1\t{%2, %0|%0, %2}
18977 cmov%O2%c1\t{%3, %0|%0, %3}"
18978 [(set_attr "type" "icmov")
18979 (set_attr "mode" "HI")])
18981 (define_expand "movqicc"
18982 [(set (match_operand:QI 0 "register_operand" "")
18983 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18984 (match_operand:QI 2 "general_operand" "")
18985 (match_operand:QI 3 "general_operand" "")))]
18986 "TARGET_QIMODE_MATH"
18987 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18989 (define_insn_and_split "*movqicc_noc"
18990 [(set (match_operand:QI 0 "register_operand" "=r,r")
18991 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18992 [(match_operand 4 "flags_reg_operand" "")
18994 (match_operand:QI 2 "register_operand" "r,0")
18995 (match_operand:QI 3 "register_operand" "0,r")))]
18996 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18998 "&& reload_completed"
18999 [(set (match_dup 0)
19000 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19003 "operands[0] = gen_lowpart (SImode, operands[0]);
19004 operands[2] = gen_lowpart (SImode, operands[2]);
19005 operands[3] = gen_lowpart (SImode, operands[3]);"
19006 [(set_attr "type" "icmov")
19007 (set_attr "mode" "SI")])
19009 (define_expand "movsfcc"
19010 [(set (match_operand:SF 0 "register_operand" "")
19011 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19012 (match_operand:SF 2 "register_operand" "")
19013 (match_operand:SF 3 "register_operand" "")))]
19014 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19015 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19017 (define_insn "*movsfcc_1_387"
19018 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19019 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19020 [(reg FLAGS_REG) (const_int 0)])
19021 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19022 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19023 "TARGET_80387 && TARGET_CMOVE
19024 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19026 fcmov%F1\t{%2, %0|%0, %2}
19027 fcmov%f1\t{%3, %0|%0, %3}
19028 cmov%O2%C1\t{%2, %0|%0, %2}
19029 cmov%O2%c1\t{%3, %0|%0, %3}"
19030 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19031 (set_attr "mode" "SF,SF,SI,SI")])
19033 (define_expand "movdfcc"
19034 [(set (match_operand:DF 0 "register_operand" "")
19035 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19036 (match_operand:DF 2 "register_operand" "")
19037 (match_operand:DF 3 "register_operand" "")))]
19038 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19039 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19041 (define_insn "*movdfcc_1"
19042 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19043 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19044 [(reg FLAGS_REG) (const_int 0)])
19045 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19046 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19047 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19048 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19050 fcmov%F1\t{%2, %0|%0, %2}
19051 fcmov%f1\t{%3, %0|%0, %3}
19054 [(set_attr "type" "fcmov,fcmov,multi,multi")
19055 (set_attr "mode" "DF")])
19057 (define_insn "*movdfcc_1_rex64"
19058 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19059 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19060 [(reg FLAGS_REG) (const_int 0)])
19061 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19062 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19063 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19064 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19066 fcmov%F1\t{%2, %0|%0, %2}
19067 fcmov%f1\t{%3, %0|%0, %3}
19068 cmov%O2%C1\t{%2, %0|%0, %2}
19069 cmov%O2%c1\t{%3, %0|%0, %3}"
19070 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19071 (set_attr "mode" "DF")])
19074 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19075 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19076 [(match_operand 4 "flags_reg_operand" "")
19078 (match_operand:DF 2 "nonimmediate_operand" "")
19079 (match_operand:DF 3 "nonimmediate_operand" "")))]
19080 "!TARGET_64BIT && reload_completed"
19081 [(set (match_dup 2)
19082 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19086 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19089 "split_di (operands+2, 1, operands+5, operands+6);
19090 split_di (operands+3, 1, operands+7, operands+8);
19091 split_di (operands, 1, operands+2, operands+3);")
19093 (define_expand "movxfcc"
19094 [(set (match_operand:XF 0 "register_operand" "")
19095 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19096 (match_operand:XF 2 "register_operand" "")
19097 (match_operand:XF 3 "register_operand" "")))]
19098 "TARGET_80387 && TARGET_CMOVE"
19099 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19101 (define_insn "*movxfcc_1"
19102 [(set (match_operand:XF 0 "register_operand" "=f,f")
19103 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19104 [(reg FLAGS_REG) (const_int 0)])
19105 (match_operand:XF 2 "register_operand" "f,0")
19106 (match_operand:XF 3 "register_operand" "0,f")))]
19107 "TARGET_80387 && TARGET_CMOVE"
19109 fcmov%F1\t{%2, %0|%0, %2}
19110 fcmov%f1\t{%3, %0|%0, %3}"
19111 [(set_attr "type" "fcmov")
19112 (set_attr "mode" "XF")])
19114 ;; These versions of the min/max patterns are intentionally ignorant of
19115 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19116 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19117 ;; are undefined in this condition, we're certain this is correct.
19119 (define_insn "sminsf3"
19120 [(set (match_operand:SF 0 "register_operand" "=x")
19121 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19122 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19124 "minss\t{%2, %0|%0, %2}"
19125 [(set_attr "type" "sseadd")
19126 (set_attr "mode" "SF")])
19128 (define_insn "smaxsf3"
19129 [(set (match_operand:SF 0 "register_operand" "=x")
19130 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19131 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19133 "maxss\t{%2, %0|%0, %2}"
19134 [(set_attr "type" "sseadd")
19135 (set_attr "mode" "SF")])
19137 (define_insn "smindf3"
19138 [(set (match_operand:DF 0 "register_operand" "=x")
19139 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19140 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19141 "TARGET_SSE2 && TARGET_SSE_MATH"
19142 "minsd\t{%2, %0|%0, %2}"
19143 [(set_attr "type" "sseadd")
19144 (set_attr "mode" "DF")])
19146 (define_insn "smaxdf3"
19147 [(set (match_operand:DF 0 "register_operand" "=x")
19148 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19149 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19150 "TARGET_SSE2 && TARGET_SSE_MATH"
19151 "maxsd\t{%2, %0|%0, %2}"
19152 [(set_attr "type" "sseadd")
19153 (set_attr "mode" "DF")])
19155 ;; These versions of the min/max patterns implement exactly the operations
19156 ;; min = (op1 < op2 ? op1 : op2)
19157 ;; max = (!(op1 < op2) ? op1 : op2)
19158 ;; Their operands are not commutative, and thus they may be used in the
19159 ;; presence of -0.0 and NaN.
19161 (define_insn "*ieee_sminsf3"
19162 [(set (match_operand:SF 0 "register_operand" "=x")
19163 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19164 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19167 "minss\t{%2, %0|%0, %2}"
19168 [(set_attr "type" "sseadd")
19169 (set_attr "mode" "SF")])
19171 (define_insn "*ieee_smaxsf3"
19172 [(set (match_operand:SF 0 "register_operand" "=x")
19173 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19174 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19177 "maxss\t{%2, %0|%0, %2}"
19178 [(set_attr "type" "sseadd")
19179 (set_attr "mode" "SF")])
19181 (define_insn "*ieee_smindf3"
19182 [(set (match_operand:DF 0 "register_operand" "=x")
19183 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19184 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19186 "TARGET_SSE2 && TARGET_SSE_MATH"
19187 "minsd\t{%2, %0|%0, %2}"
19188 [(set_attr "type" "sseadd")
19189 (set_attr "mode" "DF")])
19191 (define_insn "*ieee_smaxdf3"
19192 [(set (match_operand:DF 0 "register_operand" "=x")
19193 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19194 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19196 "TARGET_SSE2 && TARGET_SSE_MATH"
19197 "maxsd\t{%2, %0|%0, %2}"
19198 [(set_attr "type" "sseadd")
19199 (set_attr "mode" "DF")])
19201 ;; Make two stack loads independent:
19203 ;; fld %st(0) -> fld bb
19204 ;; fmul bb fmul %st(1), %st
19206 ;; Actually we only match the last two instructions for simplicity.
19208 [(set (match_operand 0 "fp_register_operand" "")
19209 (match_operand 1 "fp_register_operand" ""))
19211 (match_operator 2 "binary_fp_operator"
19213 (match_operand 3 "memory_operand" "")]))]
19214 "REGNO (operands[0]) != REGNO (operands[1])"
19215 [(set (match_dup 0) (match_dup 3))
19216 (set (match_dup 0) (match_dup 4))]
19218 ;; The % modifier is not operational anymore in peephole2's, so we have to
19219 ;; swap the operands manually in the case of addition and multiplication.
19220 "if (COMMUTATIVE_ARITH_P (operands[2]))
19221 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19222 operands[0], operands[1]);
19224 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19225 operands[1], operands[0]);")
19227 ;; Conditional addition patterns
19228 (define_expand "addqicc"
19229 [(match_operand:QI 0 "register_operand" "")
19230 (match_operand 1 "comparison_operator" "")
19231 (match_operand:QI 2 "register_operand" "")
19232 (match_operand:QI 3 "const_int_operand" "")]
19234 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19236 (define_expand "addhicc"
19237 [(match_operand:HI 0 "register_operand" "")
19238 (match_operand 1 "comparison_operator" "")
19239 (match_operand:HI 2 "register_operand" "")
19240 (match_operand:HI 3 "const_int_operand" "")]
19242 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19244 (define_expand "addsicc"
19245 [(match_operand:SI 0 "register_operand" "")
19246 (match_operand 1 "comparison_operator" "")
19247 (match_operand:SI 2 "register_operand" "")
19248 (match_operand:SI 3 "const_int_operand" "")]
19250 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19252 (define_expand "adddicc"
19253 [(match_operand:DI 0 "register_operand" "")
19254 (match_operand 1 "comparison_operator" "")
19255 (match_operand:DI 2 "register_operand" "")
19256 (match_operand:DI 3 "const_int_operand" "")]
19258 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19261 ;; Misc patterns (?)
19263 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19264 ;; Otherwise there will be nothing to keep
19266 ;; [(set (reg ebp) (reg esp))]
19267 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19268 ;; (clobber (eflags)]
19269 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19271 ;; in proper program order.
19272 (define_insn "pro_epilogue_adjust_stack_1"
19273 [(set (match_operand:SI 0 "register_operand" "=r,r")
19274 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19275 (match_operand:SI 2 "immediate_operand" "i,i")))
19276 (clobber (reg:CC FLAGS_REG))
19277 (clobber (mem:BLK (scratch)))]
19280 switch (get_attr_type (insn))
19283 return "mov{l}\t{%1, %0|%0, %1}";
19286 if (GET_CODE (operands[2]) == CONST_INT
19287 && (INTVAL (operands[2]) == 128
19288 || (INTVAL (operands[2]) < 0
19289 && INTVAL (operands[2]) != -128)))
19291 operands[2] = GEN_INT (-INTVAL (operands[2]));
19292 return "sub{l}\t{%2, %0|%0, %2}";
19294 return "add{l}\t{%2, %0|%0, %2}";
19297 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19298 return "lea{l}\t{%a2, %0|%0, %a2}";
19301 gcc_unreachable ();
19304 [(set (attr "type")
19305 (cond [(eq_attr "alternative" "0")
19306 (const_string "alu")
19307 (match_operand:SI 2 "const0_operand" "")
19308 (const_string "imov")
19310 (const_string "lea")))
19311 (set_attr "mode" "SI")])
19313 (define_insn "pro_epilogue_adjust_stack_rex64"
19314 [(set (match_operand:DI 0 "register_operand" "=r,r")
19315 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19316 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19317 (clobber (reg:CC FLAGS_REG))
19318 (clobber (mem:BLK (scratch)))]
19321 switch (get_attr_type (insn))
19324 return "mov{q}\t{%1, %0|%0, %1}";
19327 if (GET_CODE (operands[2]) == CONST_INT
19328 /* Avoid overflows. */
19329 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19330 && (INTVAL (operands[2]) == 128
19331 || (INTVAL (operands[2]) < 0
19332 && INTVAL (operands[2]) != -128)))
19334 operands[2] = GEN_INT (-INTVAL (operands[2]));
19335 return "sub{q}\t{%2, %0|%0, %2}";
19337 return "add{q}\t{%2, %0|%0, %2}";
19340 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19341 return "lea{q}\t{%a2, %0|%0, %a2}";
19344 gcc_unreachable ();
19347 [(set (attr "type")
19348 (cond [(eq_attr "alternative" "0")
19349 (const_string "alu")
19350 (match_operand:DI 2 "const0_operand" "")
19351 (const_string "imov")
19353 (const_string "lea")))
19354 (set_attr "mode" "DI")])
19356 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19357 [(set (match_operand:DI 0 "register_operand" "=r,r")
19358 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19359 (match_operand:DI 3 "immediate_operand" "i,i")))
19360 (use (match_operand:DI 2 "register_operand" "r,r"))
19361 (clobber (reg:CC FLAGS_REG))
19362 (clobber (mem:BLK (scratch)))]
19365 switch (get_attr_type (insn))
19368 return "add{q}\t{%2, %0|%0, %2}";
19371 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19372 return "lea{q}\t{%a2, %0|%0, %a2}";
19375 gcc_unreachable ();
19378 [(set_attr "type" "alu,lea")
19379 (set_attr "mode" "DI")])
19381 (define_expand "allocate_stack_worker"
19382 [(match_operand:SI 0 "register_operand" "")]
19383 "TARGET_STACK_PROBE"
19385 if (reload_completed)
19388 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19390 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19395 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19397 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19402 (define_insn "allocate_stack_worker_1"
19403 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19404 UNSPECV_STACK_PROBE)
19405 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19406 (clobber (match_scratch:SI 1 "=0"))
19407 (clobber (reg:CC FLAGS_REG))]
19408 "!TARGET_64BIT && TARGET_STACK_PROBE"
19410 [(set_attr "type" "multi")
19411 (set_attr "length" "5")])
19413 (define_expand "allocate_stack_worker_postreload"
19414 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19415 UNSPECV_STACK_PROBE)
19416 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19417 (clobber (match_dup 0))
19418 (clobber (reg:CC FLAGS_REG))])]
19422 (define_insn "allocate_stack_worker_rex64"
19423 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19424 UNSPECV_STACK_PROBE)
19425 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19426 (clobber (match_scratch:DI 1 "=0"))
19427 (clobber (reg:CC FLAGS_REG))]
19428 "TARGET_64BIT && TARGET_STACK_PROBE"
19430 [(set_attr "type" "multi")
19431 (set_attr "length" "5")])
19433 (define_expand "allocate_stack_worker_rex64_postreload"
19434 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19435 UNSPECV_STACK_PROBE)
19436 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19437 (clobber (match_dup 0))
19438 (clobber (reg:CC FLAGS_REG))])]
19442 (define_expand "allocate_stack"
19443 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19444 (minus:SI (reg:SI SP_REG)
19445 (match_operand:SI 1 "general_operand" "")))
19446 (clobber (reg:CC FLAGS_REG))])
19447 (parallel [(set (reg:SI SP_REG)
19448 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19449 (clobber (reg:CC FLAGS_REG))])]
19450 "TARGET_STACK_PROBE"
19452 #ifdef CHECK_STACK_LIMIT
19453 if (GET_CODE (operands[1]) == CONST_INT
19454 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19455 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19459 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19462 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19466 (define_expand "builtin_setjmp_receiver"
19467 [(label_ref (match_operand 0 "" ""))]
19468 "!TARGET_64BIT && flag_pic"
19473 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19474 rtx label_rtx = gen_label_rtx ();
19475 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19476 xops[0] = xops[1] = picreg;
19477 xops[2] = gen_rtx_CONST (SImode,
19478 gen_rtx_MINUS (SImode,
19479 gen_rtx_LABEL_REF (SImode, label_rtx),
19480 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19481 ix86_expand_binary_operator (MINUS, SImode, xops);
19484 emit_insn (gen_set_got (pic_offset_table_rtx));
19488 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19491 [(set (match_operand 0 "register_operand" "")
19492 (match_operator 3 "promotable_binary_operator"
19493 [(match_operand 1 "register_operand" "")
19494 (match_operand 2 "aligned_operand" "")]))
19495 (clobber (reg:CC FLAGS_REG))]
19496 "! TARGET_PARTIAL_REG_STALL && reload_completed
19497 && ((GET_MODE (operands[0]) == HImode
19498 && ((!optimize_size && !TARGET_FAST_PREFIX)
19499 /* ??? next two lines just !satisfies_constraint_K (...) */
19500 || GET_CODE (operands[2]) != CONST_INT
19501 || satisfies_constraint_K (operands[2])))
19502 || (GET_MODE (operands[0]) == QImode
19503 && (TARGET_PROMOTE_QImode || optimize_size)))"
19504 [(parallel [(set (match_dup 0)
19505 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19506 (clobber (reg:CC FLAGS_REG))])]
19507 "operands[0] = gen_lowpart (SImode, operands[0]);
19508 operands[1] = gen_lowpart (SImode, operands[1]);
19509 if (GET_CODE (operands[3]) != ASHIFT)
19510 operands[2] = gen_lowpart (SImode, operands[2]);
19511 PUT_MODE (operands[3], SImode);")
19513 ; Promote the QImode tests, as i386 has encoding of the AND
19514 ; instruction with 32-bit sign-extended immediate and thus the
19515 ; instruction size is unchanged, except in the %eax case for
19516 ; which it is increased by one byte, hence the ! optimize_size.
19518 [(set (match_operand 0 "flags_reg_operand" "")
19519 (match_operator 2 "compare_operator"
19520 [(and (match_operand 3 "aligned_operand" "")
19521 (match_operand 4 "const_int_operand" ""))
19523 (set (match_operand 1 "register_operand" "")
19524 (and (match_dup 3) (match_dup 4)))]
19525 "! TARGET_PARTIAL_REG_STALL && reload_completed
19526 /* Ensure that the operand will remain sign-extended immediate. */
19527 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19529 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19530 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19531 [(parallel [(set (match_dup 0)
19532 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19535 (and:SI (match_dup 3) (match_dup 4)))])]
19538 = gen_int_mode (INTVAL (operands[4])
19539 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19540 operands[1] = gen_lowpart (SImode, operands[1]);
19541 operands[3] = gen_lowpart (SImode, operands[3]);
19544 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19545 ; the TEST instruction with 32-bit sign-extended immediate and thus
19546 ; the instruction size would at least double, which is not what we
19547 ; want even with ! optimize_size.
19549 [(set (match_operand 0 "flags_reg_operand" "")
19550 (match_operator 1 "compare_operator"
19551 [(and (match_operand:HI 2 "aligned_operand" "")
19552 (match_operand:HI 3 "const_int_operand" ""))
19554 "! TARGET_PARTIAL_REG_STALL && reload_completed
19555 /* Ensure that the operand will remain sign-extended immediate. */
19556 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19557 && ! TARGET_FAST_PREFIX
19558 && ! optimize_size"
19559 [(set (match_dup 0)
19560 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19564 = gen_int_mode (INTVAL (operands[3])
19565 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19566 operands[2] = gen_lowpart (SImode, operands[2]);
19570 [(set (match_operand 0 "register_operand" "")
19571 (neg (match_operand 1 "register_operand" "")))
19572 (clobber (reg:CC FLAGS_REG))]
19573 "! TARGET_PARTIAL_REG_STALL && reload_completed
19574 && (GET_MODE (operands[0]) == HImode
19575 || (GET_MODE (operands[0]) == QImode
19576 && (TARGET_PROMOTE_QImode || optimize_size)))"
19577 [(parallel [(set (match_dup 0)
19578 (neg:SI (match_dup 1)))
19579 (clobber (reg:CC FLAGS_REG))])]
19580 "operands[0] = gen_lowpart (SImode, operands[0]);
19581 operands[1] = gen_lowpart (SImode, operands[1]);")
19584 [(set (match_operand 0 "register_operand" "")
19585 (not (match_operand 1 "register_operand" "")))]
19586 "! TARGET_PARTIAL_REG_STALL && reload_completed
19587 && (GET_MODE (operands[0]) == HImode
19588 || (GET_MODE (operands[0]) == QImode
19589 && (TARGET_PROMOTE_QImode || optimize_size)))"
19590 [(set (match_dup 0)
19591 (not:SI (match_dup 1)))]
19592 "operands[0] = gen_lowpart (SImode, operands[0]);
19593 operands[1] = gen_lowpart (SImode, operands[1]);")
19596 [(set (match_operand 0 "register_operand" "")
19597 (if_then_else (match_operator 1 "comparison_operator"
19598 [(reg FLAGS_REG) (const_int 0)])
19599 (match_operand 2 "register_operand" "")
19600 (match_operand 3 "register_operand" "")))]
19601 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19602 && (GET_MODE (operands[0]) == HImode
19603 || (GET_MODE (operands[0]) == QImode
19604 && (TARGET_PROMOTE_QImode || optimize_size)))"
19605 [(set (match_dup 0)
19606 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19607 "operands[0] = gen_lowpart (SImode, operands[0]);
19608 operands[2] = gen_lowpart (SImode, operands[2]);
19609 operands[3] = gen_lowpart (SImode, operands[3]);")
19612 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19613 ;; transform a complex memory operation into two memory to register operations.
19615 ;; Don't push memory operands
19617 [(set (match_operand:SI 0 "push_operand" "")
19618 (match_operand:SI 1 "memory_operand" ""))
19619 (match_scratch:SI 2 "r")]
19620 "!optimize_size && !TARGET_PUSH_MEMORY
19621 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19622 [(set (match_dup 2) (match_dup 1))
19623 (set (match_dup 0) (match_dup 2))]
19627 [(set (match_operand:DI 0 "push_operand" "")
19628 (match_operand:DI 1 "memory_operand" ""))
19629 (match_scratch:DI 2 "r")]
19630 "!optimize_size && !TARGET_PUSH_MEMORY
19631 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19632 [(set (match_dup 2) (match_dup 1))
19633 (set (match_dup 0) (match_dup 2))]
19636 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19639 [(set (match_operand:SF 0 "push_operand" "")
19640 (match_operand:SF 1 "memory_operand" ""))
19641 (match_scratch:SF 2 "r")]
19642 "!optimize_size && !TARGET_PUSH_MEMORY
19643 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19644 [(set (match_dup 2) (match_dup 1))
19645 (set (match_dup 0) (match_dup 2))]
19649 [(set (match_operand:HI 0 "push_operand" "")
19650 (match_operand:HI 1 "memory_operand" ""))
19651 (match_scratch:HI 2 "r")]
19652 "!optimize_size && !TARGET_PUSH_MEMORY
19653 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19654 [(set (match_dup 2) (match_dup 1))
19655 (set (match_dup 0) (match_dup 2))]
19659 [(set (match_operand:QI 0 "push_operand" "")
19660 (match_operand:QI 1 "memory_operand" ""))
19661 (match_scratch:QI 2 "q")]
19662 "!optimize_size && !TARGET_PUSH_MEMORY
19663 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19664 [(set (match_dup 2) (match_dup 1))
19665 (set (match_dup 0) (match_dup 2))]
19668 ;; Don't move an immediate directly to memory when the instruction
19671 [(match_scratch:SI 1 "r")
19672 (set (match_operand:SI 0 "memory_operand" "")
19675 && ! TARGET_USE_MOV0
19676 && TARGET_SPLIT_LONG_MOVES
19677 && get_attr_length (insn) >= ix86_cost->large_insn
19678 && peep2_regno_dead_p (0, FLAGS_REG)"
19679 [(parallel [(set (match_dup 1) (const_int 0))
19680 (clobber (reg:CC FLAGS_REG))])
19681 (set (match_dup 0) (match_dup 1))]
19685 [(match_scratch:HI 1 "r")
19686 (set (match_operand:HI 0 "memory_operand" "")
19689 && ! TARGET_USE_MOV0
19690 && TARGET_SPLIT_LONG_MOVES
19691 && get_attr_length (insn) >= ix86_cost->large_insn
19692 && peep2_regno_dead_p (0, FLAGS_REG)"
19693 [(parallel [(set (match_dup 2) (const_int 0))
19694 (clobber (reg:CC FLAGS_REG))])
19695 (set (match_dup 0) (match_dup 1))]
19696 "operands[2] = gen_lowpart (SImode, operands[1]);")
19699 [(match_scratch:QI 1 "q")
19700 (set (match_operand:QI 0 "memory_operand" "")
19703 && ! TARGET_USE_MOV0
19704 && TARGET_SPLIT_LONG_MOVES
19705 && get_attr_length (insn) >= ix86_cost->large_insn
19706 && peep2_regno_dead_p (0, FLAGS_REG)"
19707 [(parallel [(set (match_dup 2) (const_int 0))
19708 (clobber (reg:CC FLAGS_REG))])
19709 (set (match_dup 0) (match_dup 1))]
19710 "operands[2] = gen_lowpart (SImode, operands[1]);")
19713 [(match_scratch:SI 2 "r")
19714 (set (match_operand:SI 0 "memory_operand" "")
19715 (match_operand:SI 1 "immediate_operand" ""))]
19717 && get_attr_length (insn) >= ix86_cost->large_insn
19718 && TARGET_SPLIT_LONG_MOVES"
19719 [(set (match_dup 2) (match_dup 1))
19720 (set (match_dup 0) (match_dup 2))]
19724 [(match_scratch:HI 2 "r")
19725 (set (match_operand:HI 0 "memory_operand" "")
19726 (match_operand:HI 1 "immediate_operand" ""))]
19727 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19728 && TARGET_SPLIT_LONG_MOVES"
19729 [(set (match_dup 2) (match_dup 1))
19730 (set (match_dup 0) (match_dup 2))]
19734 [(match_scratch:QI 2 "q")
19735 (set (match_operand:QI 0 "memory_operand" "")
19736 (match_operand:QI 1 "immediate_operand" ""))]
19737 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19738 && TARGET_SPLIT_LONG_MOVES"
19739 [(set (match_dup 2) (match_dup 1))
19740 (set (match_dup 0) (match_dup 2))]
19743 ;; Don't compare memory with zero, load and use a test instead.
19745 [(set (match_operand 0 "flags_reg_operand" "")
19746 (match_operator 1 "compare_operator"
19747 [(match_operand:SI 2 "memory_operand" "")
19749 (match_scratch:SI 3 "r")]
19750 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19751 [(set (match_dup 3) (match_dup 2))
19752 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19755 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19756 ;; Don't split NOTs with a displacement operand, because resulting XOR
19757 ;; will not be pairable anyway.
19759 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19760 ;; represented using a modRM byte. The XOR replacement is long decoded,
19761 ;; so this split helps here as well.
19763 ;; Note: Can't do this as a regular split because we can't get proper
19764 ;; lifetime information then.
19767 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19768 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19770 && peep2_regno_dead_p (0, FLAGS_REG)
19771 && ((TARGET_PENTIUM
19772 && (GET_CODE (operands[0]) != MEM
19773 || !memory_displacement_operand (operands[0], SImode)))
19774 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19775 [(parallel [(set (match_dup 0)
19776 (xor:SI (match_dup 1) (const_int -1)))
19777 (clobber (reg:CC FLAGS_REG))])]
19781 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19782 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19784 && peep2_regno_dead_p (0, FLAGS_REG)
19785 && ((TARGET_PENTIUM
19786 && (GET_CODE (operands[0]) != MEM
19787 || !memory_displacement_operand (operands[0], HImode)))
19788 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19789 [(parallel [(set (match_dup 0)
19790 (xor:HI (match_dup 1) (const_int -1)))
19791 (clobber (reg:CC FLAGS_REG))])]
19795 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19796 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19798 && peep2_regno_dead_p (0, FLAGS_REG)
19799 && ((TARGET_PENTIUM
19800 && (GET_CODE (operands[0]) != MEM
19801 || !memory_displacement_operand (operands[0], QImode)))
19802 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19803 [(parallel [(set (match_dup 0)
19804 (xor:QI (match_dup 1) (const_int -1)))
19805 (clobber (reg:CC FLAGS_REG))])]
19808 ;; Non pairable "test imm, reg" instructions can be translated to
19809 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19810 ;; byte opcode instead of two, have a short form for byte operands),
19811 ;; so do it for other CPUs as well. Given that the value was dead,
19812 ;; this should not create any new dependencies. Pass on the sub-word
19813 ;; versions if we're concerned about partial register stalls.
19816 [(set (match_operand 0 "flags_reg_operand" "")
19817 (match_operator 1 "compare_operator"
19818 [(and:SI (match_operand:SI 2 "register_operand" "")
19819 (match_operand:SI 3 "immediate_operand" ""))
19821 "ix86_match_ccmode (insn, CCNOmode)
19822 && (true_regnum (operands[2]) != 0
19823 || satisfies_constraint_K (operands[3]))
19824 && peep2_reg_dead_p (1, operands[2])"
19826 [(set (match_dup 0)
19827 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19830 (and:SI (match_dup 2) (match_dup 3)))])]
19833 ;; We don't need to handle HImode case, because it will be promoted to SImode
19834 ;; on ! TARGET_PARTIAL_REG_STALL
19837 [(set (match_operand 0 "flags_reg_operand" "")
19838 (match_operator 1 "compare_operator"
19839 [(and:QI (match_operand:QI 2 "register_operand" "")
19840 (match_operand:QI 3 "immediate_operand" ""))
19842 "! TARGET_PARTIAL_REG_STALL
19843 && ix86_match_ccmode (insn, CCNOmode)
19844 && true_regnum (operands[2]) != 0
19845 && peep2_reg_dead_p (1, operands[2])"
19847 [(set (match_dup 0)
19848 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19851 (and:QI (match_dup 2) (match_dup 3)))])]
19855 [(set (match_operand 0 "flags_reg_operand" "")
19856 (match_operator 1 "compare_operator"
19859 (match_operand 2 "ext_register_operand" "")
19862 (match_operand 3 "const_int_operand" ""))
19864 "! TARGET_PARTIAL_REG_STALL
19865 && ix86_match_ccmode (insn, CCNOmode)
19866 && true_regnum (operands[2]) != 0
19867 && peep2_reg_dead_p (1, operands[2])"
19868 [(parallel [(set (match_dup 0)
19877 (set (zero_extract:SI (match_dup 2)
19888 ;; Don't do logical operations with memory inputs.
19890 [(match_scratch:SI 2 "r")
19891 (parallel [(set (match_operand:SI 0 "register_operand" "")
19892 (match_operator:SI 3 "arith_or_logical_operator"
19894 (match_operand:SI 1 "memory_operand" "")]))
19895 (clobber (reg:CC FLAGS_REG))])]
19896 "! optimize_size && ! TARGET_READ_MODIFY"
19897 [(set (match_dup 2) (match_dup 1))
19898 (parallel [(set (match_dup 0)
19899 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19900 (clobber (reg:CC FLAGS_REG))])]
19904 [(match_scratch:SI 2 "r")
19905 (parallel [(set (match_operand:SI 0 "register_operand" "")
19906 (match_operator:SI 3 "arith_or_logical_operator"
19907 [(match_operand:SI 1 "memory_operand" "")
19909 (clobber (reg:CC FLAGS_REG))])]
19910 "! optimize_size && ! TARGET_READ_MODIFY"
19911 [(set (match_dup 2) (match_dup 1))
19912 (parallel [(set (match_dup 0)
19913 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19914 (clobber (reg:CC FLAGS_REG))])]
19917 ; Don't do logical operations with memory outputs
19919 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19920 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19921 ; the same decoder scheduling characteristics as the original.
19924 [(match_scratch:SI 2 "r")
19925 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19926 (match_operator:SI 3 "arith_or_logical_operator"
19928 (match_operand:SI 1 "nonmemory_operand" "")]))
19929 (clobber (reg:CC FLAGS_REG))])]
19930 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19931 [(set (match_dup 2) (match_dup 0))
19932 (parallel [(set (match_dup 2)
19933 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19934 (clobber (reg:CC FLAGS_REG))])
19935 (set (match_dup 0) (match_dup 2))]
19939 [(match_scratch:SI 2 "r")
19940 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19941 (match_operator:SI 3 "arith_or_logical_operator"
19942 [(match_operand:SI 1 "nonmemory_operand" "")
19944 (clobber (reg:CC FLAGS_REG))])]
19945 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19946 [(set (match_dup 2) (match_dup 0))
19947 (parallel [(set (match_dup 2)
19948 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19949 (clobber (reg:CC FLAGS_REG))])
19950 (set (match_dup 0) (match_dup 2))]
19953 ;; Attempt to always use XOR for zeroing registers.
19955 [(set (match_operand 0 "register_operand" "")
19956 (match_operand 1 "const0_operand" ""))]
19957 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19958 && (! TARGET_USE_MOV0 || optimize_size)
19959 && GENERAL_REG_P (operands[0])
19960 && peep2_regno_dead_p (0, FLAGS_REG)"
19961 [(parallel [(set (match_dup 0) (const_int 0))
19962 (clobber (reg:CC FLAGS_REG))])]
19964 operands[0] = gen_lowpart (word_mode, operands[0]);
19968 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19970 "(GET_MODE (operands[0]) == QImode
19971 || GET_MODE (operands[0]) == HImode)
19972 && (! TARGET_USE_MOV0 || optimize_size)
19973 && peep2_regno_dead_p (0, FLAGS_REG)"
19974 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19975 (clobber (reg:CC FLAGS_REG))])])
19977 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19979 [(set (match_operand 0 "register_operand" "")
19981 "(GET_MODE (operands[0]) == HImode
19982 || GET_MODE (operands[0]) == SImode
19983 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19984 && (optimize_size || TARGET_PENTIUM)
19985 && peep2_regno_dead_p (0, FLAGS_REG)"
19986 [(parallel [(set (match_dup 0) (const_int -1))
19987 (clobber (reg:CC FLAGS_REG))])]
19988 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19991 ;; Attempt to convert simple leas to adds. These can be created by
19994 [(set (match_operand:SI 0 "register_operand" "")
19995 (plus:SI (match_dup 0)
19996 (match_operand:SI 1 "nonmemory_operand" "")))]
19997 "peep2_regno_dead_p (0, FLAGS_REG)"
19998 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19999 (clobber (reg:CC FLAGS_REG))])]
20003 [(set (match_operand:SI 0 "register_operand" "")
20004 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20005 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20006 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20007 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20008 (clobber (reg:CC FLAGS_REG))])]
20009 "operands[2] = gen_lowpart (SImode, operands[2]);")
20012 [(set (match_operand:DI 0 "register_operand" "")
20013 (plus:DI (match_dup 0)
20014 (match_operand:DI 1 "x86_64_general_operand" "")))]
20015 "peep2_regno_dead_p (0, FLAGS_REG)"
20016 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20017 (clobber (reg:CC FLAGS_REG))])]
20021 [(set (match_operand:SI 0 "register_operand" "")
20022 (mult:SI (match_dup 0)
20023 (match_operand:SI 1 "const_int_operand" "")))]
20024 "exact_log2 (INTVAL (operands[1])) >= 0
20025 && peep2_regno_dead_p (0, FLAGS_REG)"
20026 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20027 (clobber (reg:CC FLAGS_REG))])]
20028 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20031 [(set (match_operand:DI 0 "register_operand" "")
20032 (mult:DI (match_dup 0)
20033 (match_operand:DI 1 "const_int_operand" "")))]
20034 "exact_log2 (INTVAL (operands[1])) >= 0
20035 && peep2_regno_dead_p (0, FLAGS_REG)"
20036 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20037 (clobber (reg:CC FLAGS_REG))])]
20038 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20041 [(set (match_operand:SI 0 "register_operand" "")
20042 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20043 (match_operand:DI 2 "const_int_operand" "")) 0))]
20044 "exact_log2 (INTVAL (operands[2])) >= 0
20045 && REGNO (operands[0]) == REGNO (operands[1])
20046 && peep2_regno_dead_p (0, FLAGS_REG)"
20047 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20048 (clobber (reg:CC FLAGS_REG))])]
20049 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20051 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20052 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20053 ;; many CPUs it is also faster, since special hardware to avoid esp
20054 ;; dependencies is present.
20056 ;; While some of these conversions may be done using splitters, we use peepholes
20057 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20059 ;; Convert prologue esp subtractions to push.
20060 ;; We need register to push. In order to keep verify_flow_info happy we have
20062 ;; - use scratch and clobber it in order to avoid dependencies
20063 ;; - use already live register
20064 ;; We can't use the second way right now, since there is no reliable way how to
20065 ;; verify that given register is live. First choice will also most likely in
20066 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20067 ;; call clobbered registers are dead. We may want to use base pointer as an
20068 ;; alternative when no register is available later.
20071 [(match_scratch:SI 0 "r")
20072 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20073 (clobber (reg:CC FLAGS_REG))
20074 (clobber (mem:BLK (scratch)))])]
20075 "optimize_size || !TARGET_SUB_ESP_4"
20076 [(clobber (match_dup 0))
20077 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20078 (clobber (mem:BLK (scratch)))])])
20081 [(match_scratch:SI 0 "r")
20082 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20083 (clobber (reg:CC FLAGS_REG))
20084 (clobber (mem:BLK (scratch)))])]
20085 "optimize_size || !TARGET_SUB_ESP_8"
20086 [(clobber (match_dup 0))
20087 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20088 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20089 (clobber (mem:BLK (scratch)))])])
20091 ;; Convert esp subtractions to push.
20093 [(match_scratch:SI 0 "r")
20094 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20095 (clobber (reg:CC FLAGS_REG))])]
20096 "optimize_size || !TARGET_SUB_ESP_4"
20097 [(clobber (match_dup 0))
20098 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20101 [(match_scratch:SI 0 "r")
20102 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20103 (clobber (reg:CC FLAGS_REG))])]
20104 "optimize_size || !TARGET_SUB_ESP_8"
20105 [(clobber (match_dup 0))
20106 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20107 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20109 ;; Convert epilogue deallocator to pop.
20111 [(match_scratch:SI 0 "r")
20112 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20113 (clobber (reg:CC FLAGS_REG))
20114 (clobber (mem:BLK (scratch)))])]
20115 "optimize_size || !TARGET_ADD_ESP_4"
20116 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20117 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20118 (clobber (mem:BLK (scratch)))])]
20121 ;; Two pops case is tricky, since pop causes dependency on destination register.
20122 ;; We use two registers if available.
20124 [(match_scratch:SI 0 "r")
20125 (match_scratch:SI 1 "r")
20126 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20127 (clobber (reg:CC FLAGS_REG))
20128 (clobber (mem:BLK (scratch)))])]
20129 "optimize_size || !TARGET_ADD_ESP_8"
20130 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20131 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20132 (clobber (mem:BLK (scratch)))])
20133 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20134 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20138 [(match_scratch:SI 0 "r")
20139 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20140 (clobber (reg:CC FLAGS_REG))
20141 (clobber (mem:BLK (scratch)))])]
20143 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20144 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20145 (clobber (mem:BLK (scratch)))])
20146 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20147 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20150 ;; Convert esp additions to pop.
20152 [(match_scratch:SI 0 "r")
20153 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20154 (clobber (reg:CC FLAGS_REG))])]
20156 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20157 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20160 ;; Two pops case is tricky, since pop causes dependency on destination register.
20161 ;; We use two registers if available.
20163 [(match_scratch:SI 0 "r")
20164 (match_scratch:SI 1 "r")
20165 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20166 (clobber (reg:CC FLAGS_REG))])]
20168 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20169 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20170 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20171 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20175 [(match_scratch:SI 0 "r")
20176 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20177 (clobber (reg:CC FLAGS_REG))])]
20179 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20180 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20181 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20182 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20185 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20186 ;; required and register dies. Similarly for 128 to plus -128.
20188 [(set (match_operand 0 "flags_reg_operand" "")
20189 (match_operator 1 "compare_operator"
20190 [(match_operand 2 "register_operand" "")
20191 (match_operand 3 "const_int_operand" "")]))]
20192 "(INTVAL (operands[3]) == -1
20193 || INTVAL (operands[3]) == 1
20194 || INTVAL (operands[3]) == 128)
20195 && ix86_match_ccmode (insn, CCGCmode)
20196 && peep2_reg_dead_p (1, operands[2])"
20197 [(parallel [(set (match_dup 0)
20198 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20199 (clobber (match_dup 2))])]
20203 [(match_scratch:DI 0 "r")
20204 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20205 (clobber (reg:CC FLAGS_REG))
20206 (clobber (mem:BLK (scratch)))])]
20207 "optimize_size || !TARGET_SUB_ESP_4"
20208 [(clobber (match_dup 0))
20209 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20210 (clobber (mem:BLK (scratch)))])])
20213 [(match_scratch:DI 0 "r")
20214 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20215 (clobber (reg:CC FLAGS_REG))
20216 (clobber (mem:BLK (scratch)))])]
20217 "optimize_size || !TARGET_SUB_ESP_8"
20218 [(clobber (match_dup 0))
20219 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20220 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20221 (clobber (mem:BLK (scratch)))])])
20223 ;; Convert esp subtractions to push.
20225 [(match_scratch:DI 0 "r")
20226 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20227 (clobber (reg:CC FLAGS_REG))])]
20228 "optimize_size || !TARGET_SUB_ESP_4"
20229 [(clobber (match_dup 0))
20230 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20233 [(match_scratch:DI 0 "r")
20234 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20235 (clobber (reg:CC FLAGS_REG))])]
20236 "optimize_size || !TARGET_SUB_ESP_8"
20237 [(clobber (match_dup 0))
20238 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20239 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20241 ;; Convert epilogue deallocator to pop.
20243 [(match_scratch:DI 0 "r")
20244 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20245 (clobber (reg:CC FLAGS_REG))
20246 (clobber (mem:BLK (scratch)))])]
20247 "optimize_size || !TARGET_ADD_ESP_4"
20248 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20249 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20250 (clobber (mem:BLK (scratch)))])]
20253 ;; Two pops case is tricky, since pop causes dependency on destination register.
20254 ;; We use two registers if available.
20256 [(match_scratch:DI 0 "r")
20257 (match_scratch:DI 1 "r")
20258 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20259 (clobber (reg:CC FLAGS_REG))
20260 (clobber (mem:BLK (scratch)))])]
20261 "optimize_size || !TARGET_ADD_ESP_8"
20262 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20263 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20264 (clobber (mem:BLK (scratch)))])
20265 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20266 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20270 [(match_scratch:DI 0 "r")
20271 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20272 (clobber (reg:CC FLAGS_REG))
20273 (clobber (mem:BLK (scratch)))])]
20275 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20276 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20277 (clobber (mem:BLK (scratch)))])
20278 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20279 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20282 ;; Convert esp additions to pop.
20284 [(match_scratch:DI 0 "r")
20285 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20286 (clobber (reg:CC FLAGS_REG))])]
20288 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20289 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20292 ;; Two pops case is tricky, since pop causes dependency on destination register.
20293 ;; We use two registers if available.
20295 [(match_scratch:DI 0 "r")
20296 (match_scratch:DI 1 "r")
20297 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20298 (clobber (reg:CC FLAGS_REG))])]
20300 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20301 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20302 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20303 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20307 [(match_scratch:DI 0 "r")
20308 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20309 (clobber (reg:CC FLAGS_REG))])]
20311 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20312 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20313 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20314 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20317 ;; Convert imul by three, five and nine into lea
20320 [(set (match_operand:SI 0 "register_operand" "")
20321 (mult:SI (match_operand:SI 1 "register_operand" "")
20322 (match_operand:SI 2 "const_int_operand" "")))
20323 (clobber (reg:CC FLAGS_REG))])]
20324 "INTVAL (operands[2]) == 3
20325 || INTVAL (operands[2]) == 5
20326 || INTVAL (operands[2]) == 9"
20327 [(set (match_dup 0)
20328 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20330 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20334 [(set (match_operand:SI 0 "register_operand" "")
20335 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20336 (match_operand:SI 2 "const_int_operand" "")))
20337 (clobber (reg:CC FLAGS_REG))])]
20339 && (INTVAL (operands[2]) == 3
20340 || INTVAL (operands[2]) == 5
20341 || INTVAL (operands[2]) == 9)"
20342 [(set (match_dup 0) (match_dup 1))
20344 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20346 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20350 [(set (match_operand:DI 0 "register_operand" "")
20351 (mult:DI (match_operand:DI 1 "register_operand" "")
20352 (match_operand:DI 2 "const_int_operand" "")))
20353 (clobber (reg:CC FLAGS_REG))])]
20355 && (INTVAL (operands[2]) == 3
20356 || INTVAL (operands[2]) == 5
20357 || INTVAL (operands[2]) == 9)"
20358 [(set (match_dup 0)
20359 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20361 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20365 [(set (match_operand:DI 0 "register_operand" "")
20366 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20367 (match_operand:DI 2 "const_int_operand" "")))
20368 (clobber (reg:CC FLAGS_REG))])]
20371 && (INTVAL (operands[2]) == 3
20372 || INTVAL (operands[2]) == 5
20373 || INTVAL (operands[2]) == 9)"
20374 [(set (match_dup 0) (match_dup 1))
20376 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20378 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20380 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20381 ;; imul $32bit_imm, reg, reg is direct decoded.
20383 [(match_scratch:DI 3 "r")
20384 (parallel [(set (match_operand:DI 0 "register_operand" "")
20385 (mult:DI (match_operand:DI 1 "memory_operand" "")
20386 (match_operand:DI 2 "immediate_operand" "")))
20387 (clobber (reg:CC FLAGS_REG))])]
20388 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20389 && !satisfies_constraint_K (operands[2])"
20390 [(set (match_dup 3) (match_dup 1))
20391 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20392 (clobber (reg:CC FLAGS_REG))])]
20396 [(match_scratch:SI 3 "r")
20397 (parallel [(set (match_operand:SI 0 "register_operand" "")
20398 (mult:SI (match_operand:SI 1 "memory_operand" "")
20399 (match_operand:SI 2 "immediate_operand" "")))
20400 (clobber (reg:CC FLAGS_REG))])]
20401 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20402 && !satisfies_constraint_K (operands[2])"
20403 [(set (match_dup 3) (match_dup 1))
20404 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20405 (clobber (reg:CC FLAGS_REG))])]
20409 [(match_scratch:SI 3 "r")
20410 (parallel [(set (match_operand:DI 0 "register_operand" "")
20412 (mult:SI (match_operand:SI 1 "memory_operand" "")
20413 (match_operand:SI 2 "immediate_operand" ""))))
20414 (clobber (reg:CC FLAGS_REG))])]
20415 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20416 && !satisfies_constraint_K (operands[2])"
20417 [(set (match_dup 3) (match_dup 1))
20418 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20419 (clobber (reg:CC FLAGS_REG))])]
20422 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20423 ;; Convert it into imul reg, reg
20424 ;; It would be better to force assembler to encode instruction using long
20425 ;; immediate, but there is apparently no way to do so.
20427 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20428 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20429 (match_operand:DI 2 "const_int_operand" "")))
20430 (clobber (reg:CC FLAGS_REG))])
20431 (match_scratch:DI 3 "r")]
20432 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20433 && satisfies_constraint_K (operands[2])"
20434 [(set (match_dup 3) (match_dup 2))
20435 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20436 (clobber (reg:CC FLAGS_REG))])]
20438 if (!rtx_equal_p (operands[0], operands[1]))
20439 emit_move_insn (operands[0], operands[1]);
20443 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20444 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20445 (match_operand:SI 2 "const_int_operand" "")))
20446 (clobber (reg:CC FLAGS_REG))])
20447 (match_scratch:SI 3 "r")]
20448 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20449 && satisfies_constraint_K (operands[2])"
20450 [(set (match_dup 3) (match_dup 2))
20451 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20452 (clobber (reg:CC FLAGS_REG))])]
20454 if (!rtx_equal_p (operands[0], operands[1]))
20455 emit_move_insn (operands[0], operands[1]);
20459 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20460 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20461 (match_operand:HI 2 "immediate_operand" "")))
20462 (clobber (reg:CC FLAGS_REG))])
20463 (match_scratch:HI 3 "r")]
20464 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20465 [(set (match_dup 3) (match_dup 2))
20466 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20467 (clobber (reg:CC FLAGS_REG))])]
20469 if (!rtx_equal_p (operands[0], operands[1]))
20470 emit_move_insn (operands[0], operands[1]);
20473 ;; After splitting up read-modify operations, array accesses with memory
20474 ;; operands might end up in form:
20476 ;; movl 4(%esp), %edx
20478 ;; instead of pre-splitting:
20480 ;; addl 4(%esp), %eax
20482 ;; movl 4(%esp), %edx
20483 ;; leal (%edx,%eax,4), %eax
20486 [(parallel [(set (match_operand 0 "register_operand" "")
20487 (ashift (match_operand 1 "register_operand" "")
20488 (match_operand 2 "const_int_operand" "")))
20489 (clobber (reg:CC FLAGS_REG))])
20490 (set (match_operand 3 "register_operand")
20491 (match_operand 4 "x86_64_general_operand" ""))
20492 (parallel [(set (match_operand 5 "register_operand" "")
20493 (plus (match_operand 6 "register_operand" "")
20494 (match_operand 7 "register_operand" "")))
20495 (clobber (reg:CC FLAGS_REG))])]
20496 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20497 /* Validate MODE for lea. */
20498 && ((!TARGET_PARTIAL_REG_STALL
20499 && (GET_MODE (operands[0]) == QImode
20500 || GET_MODE (operands[0]) == HImode))
20501 || GET_MODE (operands[0]) == SImode
20502 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20503 /* We reorder load and the shift. */
20504 && !rtx_equal_p (operands[1], operands[3])
20505 && !reg_overlap_mentioned_p (operands[0], operands[4])
20506 /* Last PLUS must consist of operand 0 and 3. */
20507 && !rtx_equal_p (operands[0], operands[3])
20508 && (rtx_equal_p (operands[3], operands[6])
20509 || rtx_equal_p (operands[3], operands[7]))
20510 && (rtx_equal_p (operands[0], operands[6])
20511 || rtx_equal_p (operands[0], operands[7]))
20512 /* The intermediate operand 0 must die or be same as output. */
20513 && (rtx_equal_p (operands[0], operands[5])
20514 || peep2_reg_dead_p (3, operands[0]))"
20515 [(set (match_dup 3) (match_dup 4))
20516 (set (match_dup 0) (match_dup 1))]
20518 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20519 int scale = 1 << INTVAL (operands[2]);
20520 rtx index = gen_lowpart (Pmode, operands[1]);
20521 rtx base = gen_lowpart (Pmode, operands[3]);
20522 rtx dest = gen_lowpart (mode, operands[5]);
20524 operands[1] = gen_rtx_PLUS (Pmode, base,
20525 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20527 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20528 operands[0] = dest;
20531 ;; Call-value patterns last so that the wildcard operand does not
20532 ;; disrupt insn-recog's switch tables.
20534 (define_insn "*call_value_pop_0"
20535 [(set (match_operand 0 "" "")
20536 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20537 (match_operand:SI 2 "" "")))
20538 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20539 (match_operand:SI 3 "immediate_operand" "")))]
20542 if (SIBLING_CALL_P (insn))
20545 return "call\t%P1";
20547 [(set_attr "type" "callv")])
20549 (define_insn "*call_value_pop_1"
20550 [(set (match_operand 0 "" "")
20551 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20552 (match_operand:SI 2 "" "")))
20553 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20554 (match_operand:SI 3 "immediate_operand" "i")))]
20557 if (constant_call_address_operand (operands[1], Pmode))
20559 if (SIBLING_CALL_P (insn))
20562 return "call\t%P1";
20564 if (SIBLING_CALL_P (insn))
20567 return "call\t%A1";
20569 [(set_attr "type" "callv")])
20571 (define_insn "*call_value_0"
20572 [(set (match_operand 0 "" "")
20573 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20574 (match_operand:SI 2 "" "")))]
20577 if (SIBLING_CALL_P (insn))
20580 return "call\t%P1";
20582 [(set_attr "type" "callv")])
20584 (define_insn "*call_value_0_rex64"
20585 [(set (match_operand 0 "" "")
20586 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20587 (match_operand:DI 2 "const_int_operand" "")))]
20590 if (SIBLING_CALL_P (insn))
20593 return "call\t%P1";
20595 [(set_attr "type" "callv")])
20597 (define_insn "*call_value_1"
20598 [(set (match_operand 0 "" "")
20599 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20600 (match_operand:SI 2 "" "")))]
20601 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20603 if (constant_call_address_operand (operands[1], Pmode))
20604 return "call\t%P1";
20605 return "call\t%A1";
20607 [(set_attr "type" "callv")])
20609 (define_insn "*sibcall_value_1"
20610 [(set (match_operand 0 "" "")
20611 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20612 (match_operand:SI 2 "" "")))]
20613 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20615 if (constant_call_address_operand (operands[1], Pmode))
20619 [(set_attr "type" "callv")])
20621 (define_insn "*call_value_1_rex64"
20622 [(set (match_operand 0 "" "")
20623 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20624 (match_operand:DI 2 "" "")))]
20625 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20627 if (constant_call_address_operand (operands[1], Pmode))
20628 return "call\t%P1";
20629 return "call\t%A1";
20631 [(set_attr "type" "callv")])
20633 (define_insn "*sibcall_value_1_rex64"
20634 [(set (match_operand 0 "" "")
20635 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20636 (match_operand:DI 2 "" "")))]
20637 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20639 [(set_attr "type" "callv")])
20641 (define_insn "*sibcall_value_1_rex64_v"
20642 [(set (match_operand 0 "" "")
20643 (call (mem:QI (reg:DI 40))
20644 (match_operand:DI 1 "" "")))]
20645 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20647 [(set_attr "type" "callv")])
20649 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20650 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20651 ;; caught for use by garbage collectors and the like. Using an insn that
20652 ;; maps to SIGILL makes it more likely the program will rightfully die.
20653 ;; Keeping with tradition, "6" is in honor of #UD.
20654 (define_insn "trap"
20655 [(trap_if (const_int 1) (const_int 6))]
20657 { return ASM_SHORT "0x0b0f"; }
20658 [(set_attr "length" "2")])
20660 (define_expand "sse_prologue_save"
20661 [(parallel [(set (match_operand:BLK 0 "" "")
20662 (unspec:BLK [(reg:DI 21)
20669 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20670 (use (match_operand:DI 1 "register_operand" ""))
20671 (use (match_operand:DI 2 "immediate_operand" ""))
20672 (use (label_ref:DI (match_operand 3 "" "")))])]
20676 (define_insn "*sse_prologue_save_insn"
20677 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20678 (match_operand:DI 4 "const_int_operand" "n")))
20679 (unspec:BLK [(reg:DI 21)
20686 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20687 (use (match_operand:DI 1 "register_operand" "r"))
20688 (use (match_operand:DI 2 "const_int_operand" "i"))
20689 (use (label_ref:DI (match_operand 3 "" "X")))]
20691 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20692 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20696 operands[0] = gen_rtx_MEM (Pmode,
20697 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20698 output_asm_insn (\"jmp\\t%A1\", operands);
20699 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20701 operands[4] = adjust_address (operands[0], DImode, i*16);
20702 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20703 PUT_MODE (operands[4], TImode);
20704 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20705 output_asm_insn (\"rex\", operands);
20706 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20708 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20709 CODE_LABEL_NUMBER (operands[3]));
20713 [(set_attr "type" "other")
20714 (set_attr "length_immediate" "0")
20715 (set_attr "length_address" "0")
20716 (set_attr "length" "135")
20717 (set_attr "memory" "store")
20718 (set_attr "modrm" "0")
20719 (set_attr "mode" "DI")])
20721 (define_expand "prefetch"
20722 [(prefetch (match_operand 0 "address_operand" "")
20723 (match_operand:SI 1 "const_int_operand" "")
20724 (match_operand:SI 2 "const_int_operand" ""))]
20725 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20727 int rw = INTVAL (operands[1]);
20728 int locality = INTVAL (operands[2]);
20730 gcc_assert (rw == 0 || rw == 1);
20731 gcc_assert (locality >= 0 && locality <= 3);
20732 gcc_assert (GET_MODE (operands[0]) == Pmode
20733 || GET_MODE (operands[0]) == VOIDmode);
20735 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20736 supported by SSE counterpart or the SSE prefetch is not available
20737 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20739 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20740 operands[2] = GEN_INT (3);
20742 operands[1] = const0_rtx;
20745 (define_insn "*prefetch_sse"
20746 [(prefetch (match_operand:SI 0 "address_operand" "p")
20748 (match_operand:SI 1 "const_int_operand" ""))]
20749 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20751 static const char * const patterns[4] = {
20752 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20755 int locality = INTVAL (operands[1]);
20756 gcc_assert (locality >= 0 && locality <= 3);
20758 return patterns[locality];
20760 [(set_attr "type" "sse")
20761 (set_attr "memory" "none")])
20763 (define_insn "*prefetch_sse_rex"
20764 [(prefetch (match_operand:DI 0 "address_operand" "p")
20766 (match_operand:SI 1 "const_int_operand" ""))]
20767 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20769 static const char * const patterns[4] = {
20770 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20773 int locality = INTVAL (operands[1]);
20774 gcc_assert (locality >= 0 && locality <= 3);
20776 return patterns[locality];
20778 [(set_attr "type" "sse")
20779 (set_attr "memory" "none")])
20781 (define_insn "*prefetch_3dnow"
20782 [(prefetch (match_operand:SI 0 "address_operand" "p")
20783 (match_operand:SI 1 "const_int_operand" "n")
20785 "TARGET_3DNOW && !TARGET_64BIT"
20787 if (INTVAL (operands[1]) == 0)
20788 return "prefetch\t%a0";
20790 return "prefetchw\t%a0";
20792 [(set_attr "type" "mmx")
20793 (set_attr "memory" "none")])
20795 (define_insn "*prefetch_3dnow_rex"
20796 [(prefetch (match_operand:DI 0 "address_operand" "p")
20797 (match_operand:SI 1 "const_int_operand" "n")
20799 "TARGET_3DNOW && TARGET_64BIT"
20801 if (INTVAL (operands[1]) == 0)
20802 return "prefetch\t%a0";
20804 return "prefetchw\t%a0";
20806 [(set_attr "type" "mmx")
20807 (set_attr "memory" "none")])
20809 (define_expand "stack_protect_set"
20810 [(match_operand 0 "memory_operand" "")
20811 (match_operand 1 "memory_operand" "")]
20814 #ifdef TARGET_THREAD_SSP_OFFSET
20816 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20817 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20819 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20820 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20823 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20825 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20830 (define_insn "stack_protect_set_si"
20831 [(set (match_operand:SI 0 "memory_operand" "=m")
20832 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20833 (set (match_scratch:SI 2 "=&r") (const_int 0))
20834 (clobber (reg:CC FLAGS_REG))]
20836 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20837 [(set_attr "type" "multi")])
20839 (define_insn "stack_protect_set_di"
20840 [(set (match_operand:DI 0 "memory_operand" "=m")
20841 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20842 (set (match_scratch:DI 2 "=&r") (const_int 0))
20843 (clobber (reg:CC FLAGS_REG))]
20845 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20846 [(set_attr "type" "multi")])
20848 (define_insn "stack_tls_protect_set_si"
20849 [(set (match_operand:SI 0 "memory_operand" "=m")
20850 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20851 (set (match_scratch:SI 2 "=&r") (const_int 0))
20852 (clobber (reg:CC FLAGS_REG))]
20854 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20855 [(set_attr "type" "multi")])
20857 (define_insn "stack_tls_protect_set_di"
20858 [(set (match_operand:DI 0 "memory_operand" "=m")
20859 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20860 (set (match_scratch:DI 2 "=&r") (const_int 0))
20861 (clobber (reg:CC FLAGS_REG))]
20864 /* The kernel uses a different segment register for performance reasons; a
20865 system call would not have to trash the userspace segment register,
20866 which would be expensive */
20867 if (ix86_cmodel != CM_KERNEL)
20868 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20870 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20872 [(set_attr "type" "multi")])
20874 (define_expand "stack_protect_test"
20875 [(match_operand 0 "memory_operand" "")
20876 (match_operand 1 "memory_operand" "")
20877 (match_operand 2 "" "")]
20880 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20881 ix86_compare_op0 = operands[0];
20882 ix86_compare_op1 = operands[1];
20883 ix86_compare_emitted = flags;
20885 #ifdef TARGET_THREAD_SSP_OFFSET
20887 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20888 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20890 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20891 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20894 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20896 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20898 emit_jump_insn (gen_beq (operands[2]));
20902 (define_insn "stack_protect_test_si"
20903 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20904 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20905 (match_operand:SI 2 "memory_operand" "m")]
20907 (clobber (match_scratch:SI 3 "=&r"))]
20909 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20910 [(set_attr "type" "multi")])
20912 (define_insn "stack_protect_test_di"
20913 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20914 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20915 (match_operand:DI 2 "memory_operand" "m")]
20917 (clobber (match_scratch:DI 3 "=&r"))]
20919 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20920 [(set_attr "type" "multi")])
20922 (define_insn "stack_tls_protect_test_si"
20923 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20924 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20925 (match_operand:SI 2 "const_int_operand" "i")]
20926 UNSPEC_SP_TLS_TEST))
20927 (clobber (match_scratch:SI 3 "=r"))]
20929 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20930 [(set_attr "type" "multi")])
20932 (define_insn "stack_tls_protect_test_di"
20933 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20934 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20935 (match_operand:DI 2 "const_int_operand" "i")]
20936 UNSPEC_SP_TLS_TEST))
20937 (clobber (match_scratch:DI 3 "=r"))]
20940 /* The kernel uses a different segment register for performance reasons; a
20941 system call would not have to trash the userspace segment register,
20942 which would be expensive */
20943 if (ix86_cmodel != CM_KERNEL)
20944 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20946 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20948 [(set_attr "type" "multi")])
20952 (include "sync.md")