1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
88 (UNSPEC_TRUNC_NOOP 29)
90 ; For SSE/MMX support:
91 (UNSPEC_FIX_NOTRUNC 30)
99 (UNSPEC_NOP 38) ; prevents combiner cleverness
110 ; Generic math support
112 (UNSPEC_IEEE_MIN 51) ; not commutative
113 (UNSPEC_IEEE_MAX 52) ; not commutative
128 (UNSPEC_FRNDINT_FLOOR 70)
129 (UNSPEC_FRNDINT_CEIL 71)
130 (UNSPEC_FRNDINT_TRUNC 72)
131 (UNSPEC_FRNDINT_MASK_PM 73)
132 (UNSPEC_FIST_FLOOR 74)
133 (UNSPEC_FIST_CEIL 75)
135 ; x87 Double output FP
136 (UNSPEC_SINCOS_COS 80)
137 (UNSPEC_SINCOS_SIN 81)
138 (UNSPEC_XTRACT_FRACT 84)
139 (UNSPEC_XTRACT_EXP 85)
140 (UNSPEC_FSCALE_FRACT 86)
141 (UNSPEC_FSCALE_EXP 87)
150 (UNSPEC_SP_TLS_SET 102)
151 (UNSPEC_SP_TLS_TEST 103)
160 [(UNSPECV_BLOCKAGE 0)
161 (UNSPECV_STACK_PROBE 1)
170 (UNSPECV_CMPXCHG_1 10)
171 (UNSPECV_CMPXCHG_2 11)
176 ;; Registers by name.
187 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
190 ;; In C guard expressions, put expressions which may be compile-time
191 ;; constants first. This allows for better optimization. For
192 ;; example, write "TARGET_64BIT && reload_completed", not
193 ;; "reload_completed && TARGET_64BIT".
196 ;; Processor type. This attribute must exactly match the processor_type
197 ;; enumeration in i386.h.
198 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,nocona,core2,generic32,generic64"
199 (const (symbol_ref "ix86_tune")))
201 ;; A basic instruction type. Refinements due to arguments to be
202 ;; provided in other attributes.
205 alu,alu1,negnot,imov,imovx,lea,
206 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
207 icmp,test,ibr,setcc,icmov,
208 push,pop,call,callv,leave,
210 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
211 sselog,sselog1,sseiadd,sseishft,sseimul,
212 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv,
213 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
214 (const_string "other"))
216 ;; Main data type used by the insn
218 "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
219 (const_string "unknown"))
221 ;; The CPU unit operations uses.
222 (define_attr "unit" "integer,i387,sse,mmx,unknown"
223 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
224 (const_string "i387")
225 (eq_attr "type" "sselog,sselog1,sseiadd,sseishft,sseimul,
226 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,sseicvt,ssediv")
228 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
230 (eq_attr "type" "other")
231 (const_string "unknown")]
232 (const_string "integer")))
234 ;; The (bounding maximum) length of an instruction immediate.
235 (define_attr "length_immediate" ""
236 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave")
238 (eq_attr "unit" "i387,sse,mmx")
240 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
242 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
243 (eq_attr "type" "imov,test")
244 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
245 (eq_attr "type" "call")
246 (if_then_else (match_operand 0 "constant_call_address_operand" "")
249 (eq_attr "type" "callv")
250 (if_then_else (match_operand 1 "constant_call_address_operand" "")
253 ;; We don't know the size before shorten_branches. Expect
254 ;; the instruction to fit for better scheduling.
255 (eq_attr "type" "ibr")
258 (symbol_ref "/* Update immediate_length and other attributes! */
259 gcc_unreachable (),1")))
261 ;; The (bounding maximum) length of an instruction address.
262 (define_attr "length_address" ""
263 (cond [(eq_attr "type" "str,other,multi,fxch")
265 (and (eq_attr "type" "call")
266 (match_operand 0 "constant_call_address_operand" ""))
268 (and (eq_attr "type" "callv")
269 (match_operand 1 "constant_call_address_operand" ""))
272 (symbol_ref "ix86_attr_length_address_default (insn)")))
274 ;; Set when length prefix is used.
275 (define_attr "prefix_data16" ""
276 (if_then_else (ior (eq_attr "mode" "HI")
277 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
281 ;; Set when string REP prefix is used.
282 (define_attr "prefix_rep" ""
283 (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
287 ;; Set when 0f opcode prefix is used.
288 (define_attr "prefix_0f" ""
290 (ior (eq_attr "type" "imovx,setcc,icmov")
291 (eq_attr "unit" "sse,mmx"))
295 ;; Set when REX opcode prefix is used.
296 (define_attr "prefix_rex" ""
297 (cond [(and (eq_attr "mode" "DI")
298 (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
300 (and (eq_attr "mode" "QI")
301 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
304 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
310 ;; Set when modrm byte is used.
311 (define_attr "modrm" ""
312 (cond [(eq_attr "type" "str,leave")
314 (eq_attr "unit" "i387")
316 (and (eq_attr "type" "incdec")
317 (ior (match_operand:SI 1 "register_operand" "")
318 (match_operand:HI 1 "register_operand" "")))
320 (and (eq_attr "type" "push")
321 (not (match_operand 1 "memory_operand" "")))
323 (and (eq_attr "type" "pop")
324 (not (match_operand 0 "memory_operand" "")))
326 (and (eq_attr "type" "imov")
327 (ior (and (match_operand 0 "register_operand" "")
328 (match_operand 1 "immediate_operand" ""))
329 (ior (and (match_operand 0 "ax_reg_operand" "")
330 (match_operand 1 "memory_displacement_only_operand" ""))
331 (and (match_operand 0 "memory_displacement_only_operand" "")
332 (match_operand 1 "ax_reg_operand" "")))))
334 (and (eq_attr "type" "call")
335 (match_operand 0 "constant_call_address_operand" ""))
337 (and (eq_attr "type" "callv")
338 (match_operand 1 "constant_call_address_operand" ""))
343 ;; The (bounding maximum) length of an instruction in bytes.
344 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
345 ;; Later we may want to split them and compute proper length as for
347 (define_attr "length" ""
348 (cond [(eq_attr "type" "other,multi,fistp,frndint")
350 (eq_attr "type" "fcmp")
352 (eq_attr "unit" "i387")
354 (plus (attr "prefix_data16")
355 (attr "length_address")))]
356 (plus (plus (attr "modrm")
357 (plus (attr "prefix_0f")
358 (plus (attr "prefix_rex")
360 (plus (attr "prefix_rep")
361 (plus (attr "prefix_data16")
362 (plus (attr "length_immediate")
363 (attr "length_address")))))))
365 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
366 ;; `store' if there is a simple memory reference therein, or `unknown'
367 ;; if the instruction is complex.
369 (define_attr "memory" "none,load,store,both,unknown"
370 (cond [(eq_attr "type" "other,multi,str")
371 (const_string "unknown")
372 (eq_attr "type" "lea,fcmov,fpspc")
373 (const_string "none")
374 (eq_attr "type" "fistp,leave")
375 (const_string "both")
376 (eq_attr "type" "frndint")
377 (const_string "load")
378 (eq_attr "type" "push")
379 (if_then_else (match_operand 1 "memory_operand" "")
380 (const_string "both")
381 (const_string "store"))
382 (eq_attr "type" "pop")
383 (if_then_else (match_operand 0 "memory_operand" "")
384 (const_string "both")
385 (const_string "load"))
386 (eq_attr "type" "setcc")
387 (if_then_else (match_operand 0 "memory_operand" "")
388 (const_string "store")
389 (const_string "none"))
390 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
391 (if_then_else (ior (match_operand 0 "memory_operand" "")
392 (match_operand 1 "memory_operand" ""))
393 (const_string "load")
394 (const_string "none"))
395 (eq_attr "type" "ibr")
396 (if_then_else (match_operand 0 "memory_operand" "")
397 (const_string "load")
398 (const_string "none"))
399 (eq_attr "type" "call")
400 (if_then_else (match_operand 0 "constant_call_address_operand" "")
401 (const_string "none")
402 (const_string "load"))
403 (eq_attr "type" "callv")
404 (if_then_else (match_operand 1 "constant_call_address_operand" "")
405 (const_string "none")
406 (const_string "load"))
407 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
408 (match_operand 1 "memory_operand" ""))
409 (const_string "both")
410 (and (match_operand 0 "memory_operand" "")
411 (match_operand 1 "memory_operand" ""))
412 (const_string "both")
413 (match_operand 0 "memory_operand" "")
414 (const_string "store")
415 (match_operand 1 "memory_operand" "")
416 (const_string "load")
418 "!alu1,negnot,ishift1,
419 imov,imovx,icmp,test,
421 sse,ssemov,ssecmp,ssecomi,ssecvt,sseicvt,sselog1,
422 mmx,mmxmov,mmxcmp,mmxcvt")
423 (match_operand 2 "memory_operand" ""))
424 (const_string "load")
425 (and (eq_attr "type" "icmov")
426 (match_operand 3 "memory_operand" ""))
427 (const_string "load")
429 (const_string "none")))
431 ;; Indicates if an instruction has both an immediate and a displacement.
433 (define_attr "imm_disp" "false,true,unknown"
434 (cond [(eq_attr "type" "other,multi")
435 (const_string "unknown")
436 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
437 (and (match_operand 0 "memory_displacement_operand" "")
438 (match_operand 1 "immediate_operand" "")))
439 (const_string "true")
440 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
441 (and (match_operand 0 "memory_displacement_operand" "")
442 (match_operand 2 "immediate_operand" "")))
443 (const_string "true")
445 (const_string "false")))
447 ;; Indicates if an FP operation has an integer source.
449 (define_attr "fp_int_src" "false,true"
450 (const_string "false"))
452 ;; Defines rounding mode of an FP operation.
454 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
455 (const_string "any"))
457 ;; Describe a user's asm statement.
458 (define_asm_attributes
459 [(set_attr "length" "128")
460 (set_attr "type" "multi")])
462 ;; All x87 floating point modes
463 (define_mode_macro X87MODEF [SF DF XF])
465 ;; x87 SFmode and DFMode floating point modes
466 (define_mode_macro X87MODEF12 [SF DF])
468 ;; All integer modes handled by x87 fisttp operator.
469 (define_mode_macro X87MODEI [HI SI DI])
471 ;; All integer modes handled by integer x87 operators.
472 (define_mode_macro X87MODEI12 [HI SI])
474 ;; All SSE floating point modes
475 (define_mode_macro SSEMODEF [SF DF])
477 ;; All integer modes handled by SSE cvtts?2si* operators.
478 (define_mode_macro SSEMODEI24 [SI DI])
480 ;; SSE asm suffix for floating point modes
481 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
484 ;; Scheduling descriptions
486 (include "pentium.md")
489 (include "athlon.md")
493 ;; Operand and operator predicates and constraints
495 (include "predicates.md")
496 (include "constraints.md")
499 ;; Compare instructions.
501 ;; All compare insns have expanders that save the operands away without
502 ;; actually generating RTL. The bCOND or sCOND (emitted immediately
503 ;; after the cmp) will actually emit the cmpM.
505 (define_expand "cmpti"
506 [(set (reg:CC FLAGS_REG)
507 (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
508 (match_operand:TI 1 "x86_64_general_operand" "")))]
511 if (MEM_P (operands[0]) && MEM_P (operands[1]))
512 operands[0] = force_reg (TImode, operands[0]);
513 ix86_compare_op0 = operands[0];
514 ix86_compare_op1 = operands[1];
518 (define_expand "cmpdi"
519 [(set (reg:CC FLAGS_REG)
520 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
521 (match_operand:DI 1 "x86_64_general_operand" "")))]
524 if (MEM_P (operands[0]) && MEM_P (operands[1]))
525 operands[0] = force_reg (DImode, operands[0]);
526 ix86_compare_op0 = operands[0];
527 ix86_compare_op1 = operands[1];
531 (define_expand "cmpsi"
532 [(set (reg:CC FLAGS_REG)
533 (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
534 (match_operand:SI 1 "general_operand" "")))]
537 if (MEM_P (operands[0]) && MEM_P (operands[1]))
538 operands[0] = force_reg (SImode, operands[0]);
539 ix86_compare_op0 = operands[0];
540 ix86_compare_op1 = operands[1];
544 (define_expand "cmphi"
545 [(set (reg:CC FLAGS_REG)
546 (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
547 (match_operand:HI 1 "general_operand" "")))]
550 if (MEM_P (operands[0]) && MEM_P (operands[1]))
551 operands[0] = force_reg (HImode, operands[0]);
552 ix86_compare_op0 = operands[0];
553 ix86_compare_op1 = operands[1];
557 (define_expand "cmpqi"
558 [(set (reg:CC FLAGS_REG)
559 (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
560 (match_operand:QI 1 "general_operand" "")))]
563 if (MEM_P (operands[0]) && MEM_P (operands[1]))
564 operands[0] = force_reg (QImode, operands[0]);
565 ix86_compare_op0 = operands[0];
566 ix86_compare_op1 = operands[1];
570 (define_insn "cmpdi_ccno_1_rex64"
571 [(set (reg FLAGS_REG)
572 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
573 (match_operand:DI 1 "const0_operand" "n,n")))]
574 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
576 test{q}\t{%0, %0|%0, %0}
577 cmp{q}\t{%1, %0|%0, %1}"
578 [(set_attr "type" "test,icmp")
579 (set_attr "length_immediate" "0,1")
580 (set_attr "mode" "DI")])
582 (define_insn "*cmpdi_minus_1_rex64"
583 [(set (reg FLAGS_REG)
584 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
585 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
587 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
588 "cmp{q}\t{%1, %0|%0, %1}"
589 [(set_attr "type" "icmp")
590 (set_attr "mode" "DI")])
592 (define_expand "cmpdi_1_rex64"
593 [(set (reg:CC FLAGS_REG)
594 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
595 (match_operand:DI 1 "general_operand" "")))]
599 (define_insn "cmpdi_1_insn_rex64"
600 [(set (reg FLAGS_REG)
601 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
602 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
603 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
604 "cmp{q}\t{%1, %0|%0, %1}"
605 [(set_attr "type" "icmp")
606 (set_attr "mode" "DI")])
609 (define_insn "*cmpsi_ccno_1"
610 [(set (reg FLAGS_REG)
611 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
612 (match_operand:SI 1 "const0_operand" "n,n")))]
613 "ix86_match_ccmode (insn, CCNOmode)"
615 test{l}\t{%0, %0|%0, %0}
616 cmp{l}\t{%1, %0|%0, %1}"
617 [(set_attr "type" "test,icmp")
618 (set_attr "length_immediate" "0,1")
619 (set_attr "mode" "SI")])
621 (define_insn "*cmpsi_minus_1"
622 [(set (reg FLAGS_REG)
623 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
624 (match_operand:SI 1 "general_operand" "ri,mr"))
626 "ix86_match_ccmode (insn, CCGOCmode)"
627 "cmp{l}\t{%1, %0|%0, %1}"
628 [(set_attr "type" "icmp")
629 (set_attr "mode" "SI")])
631 (define_expand "cmpsi_1"
632 [(set (reg:CC FLAGS_REG)
633 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "rm,r")
634 (match_operand:SI 1 "general_operand" "ri,mr")))]
638 (define_insn "*cmpsi_1_insn"
639 [(set (reg FLAGS_REG)
640 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
641 (match_operand:SI 1 "general_operand" "ri,mr")))]
642 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
643 && ix86_match_ccmode (insn, CCmode)"
644 "cmp{l}\t{%1, %0|%0, %1}"
645 [(set_attr "type" "icmp")
646 (set_attr "mode" "SI")])
648 (define_insn "*cmphi_ccno_1"
649 [(set (reg FLAGS_REG)
650 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
651 (match_operand:HI 1 "const0_operand" "n,n")))]
652 "ix86_match_ccmode (insn, CCNOmode)"
654 test{w}\t{%0, %0|%0, %0}
655 cmp{w}\t{%1, %0|%0, %1}"
656 [(set_attr "type" "test,icmp")
657 (set_attr "length_immediate" "0,1")
658 (set_attr "mode" "HI")])
660 (define_insn "*cmphi_minus_1"
661 [(set (reg FLAGS_REG)
662 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
663 (match_operand:HI 1 "general_operand" "ri,mr"))
665 "ix86_match_ccmode (insn, CCGOCmode)"
666 "cmp{w}\t{%1, %0|%0, %1}"
667 [(set_attr "type" "icmp")
668 (set_attr "mode" "HI")])
670 (define_insn "*cmphi_1"
671 [(set (reg FLAGS_REG)
672 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
673 (match_operand:HI 1 "general_operand" "ri,mr")))]
674 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
675 && ix86_match_ccmode (insn, CCmode)"
676 "cmp{w}\t{%1, %0|%0, %1}"
677 [(set_attr "type" "icmp")
678 (set_attr "mode" "HI")])
680 (define_insn "*cmpqi_ccno_1"
681 [(set (reg FLAGS_REG)
682 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
683 (match_operand:QI 1 "const0_operand" "n,n")))]
684 "ix86_match_ccmode (insn, CCNOmode)"
686 test{b}\t{%0, %0|%0, %0}
687 cmp{b}\t{$0, %0|%0, 0}"
688 [(set_attr "type" "test,icmp")
689 (set_attr "length_immediate" "0,1")
690 (set_attr "mode" "QI")])
692 (define_insn "*cmpqi_1"
693 [(set (reg FLAGS_REG)
694 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
695 (match_operand:QI 1 "general_operand" "qi,mq")))]
696 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
697 && ix86_match_ccmode (insn, CCmode)"
698 "cmp{b}\t{%1, %0|%0, %1}"
699 [(set_attr "type" "icmp")
700 (set_attr "mode" "QI")])
702 (define_insn "*cmpqi_minus_1"
703 [(set (reg FLAGS_REG)
704 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
705 (match_operand:QI 1 "general_operand" "qi,mq"))
707 "ix86_match_ccmode (insn, CCGOCmode)"
708 "cmp{b}\t{%1, %0|%0, %1}"
709 [(set_attr "type" "icmp")
710 (set_attr "mode" "QI")])
712 (define_insn "*cmpqi_ext_1"
713 [(set (reg FLAGS_REG)
715 (match_operand:QI 0 "general_operand" "Qm")
718 (match_operand 1 "ext_register_operand" "Q")
721 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
722 "cmp{b}\t{%h1, %0|%0, %h1}"
723 [(set_attr "type" "icmp")
724 (set_attr "mode" "QI")])
726 (define_insn "*cmpqi_ext_1_rex64"
727 [(set (reg FLAGS_REG)
729 (match_operand:QI 0 "register_operand" "Q")
732 (match_operand 1 "ext_register_operand" "Q")
735 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
736 "cmp{b}\t{%h1, %0|%0, %h1}"
737 [(set_attr "type" "icmp")
738 (set_attr "mode" "QI")])
740 (define_insn "*cmpqi_ext_2"
741 [(set (reg FLAGS_REG)
745 (match_operand 0 "ext_register_operand" "Q")
748 (match_operand:QI 1 "const0_operand" "n")))]
749 "ix86_match_ccmode (insn, CCNOmode)"
751 [(set_attr "type" "test")
752 (set_attr "length_immediate" "0")
753 (set_attr "mode" "QI")])
755 (define_expand "cmpqi_ext_3"
756 [(set (reg:CC FLAGS_REG)
760 (match_operand 0 "ext_register_operand" "")
763 (match_operand:QI 1 "general_operand" "")))]
767 (define_insn "cmpqi_ext_3_insn"
768 [(set (reg FLAGS_REG)
772 (match_operand 0 "ext_register_operand" "Q")
775 (match_operand:QI 1 "general_operand" "Qmn")))]
776 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
777 "cmp{b}\t{%1, %h0|%h0, %1}"
778 [(set_attr "type" "icmp")
779 (set_attr "mode" "QI")])
781 (define_insn "cmpqi_ext_3_insn_rex64"
782 [(set (reg FLAGS_REG)
786 (match_operand 0 "ext_register_operand" "Q")
789 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
790 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
791 "cmp{b}\t{%1, %h0|%h0, %1}"
792 [(set_attr "type" "icmp")
793 (set_attr "mode" "QI")])
795 (define_insn "*cmpqi_ext_4"
796 [(set (reg FLAGS_REG)
800 (match_operand 0 "ext_register_operand" "Q")
805 (match_operand 1 "ext_register_operand" "Q")
808 "ix86_match_ccmode (insn, CCmode)"
809 "cmp{b}\t{%h1, %h0|%h0, %h1}"
810 [(set_attr "type" "icmp")
811 (set_attr "mode" "QI")])
813 ;; These implement float point compares.
814 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
815 ;; which would allow mix and match FP modes on the compares. Which is what
816 ;; the old patterns did, but with many more of them.
818 (define_expand "cmpxf"
819 [(set (reg:CC FLAGS_REG)
820 (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
821 (match_operand:XF 1 "nonmemory_operand" "")))]
824 ix86_compare_op0 = operands[0];
825 ix86_compare_op1 = operands[1];
829 (define_expand "cmpdf"
830 [(set (reg:CC FLAGS_REG)
831 (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
832 (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
833 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
835 ix86_compare_op0 = operands[0];
836 ix86_compare_op1 = operands[1];
840 (define_expand "cmpsf"
841 [(set (reg:CC FLAGS_REG)
842 (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
843 (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
844 "TARGET_80387 || TARGET_SSE_MATH"
846 ix86_compare_op0 = operands[0];
847 ix86_compare_op1 = operands[1];
851 ;; FP compares, step 1:
852 ;; Set the FP condition codes.
854 ;; CCFPmode compare with exceptions
855 ;; CCFPUmode compare with no exceptions
857 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
858 ;; used to manage the reg stack popping would not be preserved.
860 (define_insn "*cmpfp_0"
861 [(set (match_operand:HI 0 "register_operand" "=a")
864 (match_operand 1 "register_operand" "f")
865 (match_operand 2 "const0_operand" "X"))]
868 && FLOAT_MODE_P (GET_MODE (operands[1]))
869 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
870 "* return output_fp_compare (insn, operands, 0, 0);"
871 [(set_attr "type" "multi")
872 (set_attr "unit" "i387")
874 (cond [(match_operand:SF 1 "" "")
876 (match_operand:DF 1 "" "")
879 (const_string "XF")))])
881 (define_insn "*cmpfp_sf"
882 [(set (match_operand:HI 0 "register_operand" "=a")
885 (match_operand:SF 1 "register_operand" "f")
886 (match_operand:SF 2 "nonimmediate_operand" "fm"))]
889 "* return output_fp_compare (insn, operands, 0, 0);"
890 [(set_attr "type" "multi")
891 (set_attr "unit" "i387")
892 (set_attr "mode" "SF")])
894 (define_insn "*cmpfp_df"
895 [(set (match_operand:HI 0 "register_operand" "=a")
898 (match_operand:DF 1 "register_operand" "f")
899 (match_operand:DF 2 "nonimmediate_operand" "fm"))]
902 "* return output_fp_compare (insn, operands, 0, 0);"
903 [(set_attr "type" "multi")
904 (set_attr "unit" "i387")
905 (set_attr "mode" "DF")])
907 (define_insn "*cmpfp_xf"
908 [(set (match_operand:HI 0 "register_operand" "=a")
911 (match_operand:XF 1 "register_operand" "f")
912 (match_operand:XF 2 "register_operand" "f"))]
915 "* return output_fp_compare (insn, operands, 0, 0);"
916 [(set_attr "type" "multi")
917 (set_attr "unit" "i387")
918 (set_attr "mode" "XF")])
920 (define_insn "*cmpfp_u"
921 [(set (match_operand:HI 0 "register_operand" "=a")
924 (match_operand 1 "register_operand" "f")
925 (match_operand 2 "register_operand" "f"))]
928 && FLOAT_MODE_P (GET_MODE (operands[1]))
929 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
930 "* return output_fp_compare (insn, operands, 0, 1);"
931 [(set_attr "type" "multi")
932 (set_attr "unit" "i387")
934 (cond [(match_operand:SF 1 "" "")
936 (match_operand:DF 1 "" "")
939 (const_string "XF")))])
941 (define_insn "*cmpfp_<mode>"
942 [(set (match_operand:HI 0 "register_operand" "=a")
945 (match_operand 1 "register_operand" "f")
946 (match_operator 3 "float_operator"
947 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
949 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
950 && FLOAT_MODE_P (GET_MODE (operands[1]))
951 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
952 "* return output_fp_compare (insn, operands, 0, 0);"
953 [(set_attr "type" "multi")
954 (set_attr "unit" "i387")
955 (set_attr "fp_int_src" "true")
956 (set_attr "mode" "<MODE>")])
958 ;; FP compares, step 2
959 ;; Move the fpsw to ax.
961 (define_insn "x86_fnstsw_1"
962 [(set (match_operand:HI 0 "register_operand" "=a")
963 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
966 [(set_attr "length" "2")
967 (set_attr "mode" "SI")
968 (set_attr "unit" "i387")])
970 ;; FP compares, step 3
971 ;; Get ax into flags, general case.
973 (define_insn "x86_sahf_1"
974 [(set (reg:CC FLAGS_REG)
975 (unspec:CC [(match_operand:HI 0 "register_operand" "a")] UNSPEC_SAHF))]
978 [(set_attr "length" "1")
979 (set_attr "athlon_decode" "vector")
980 (set_attr "mode" "SI")])
982 ;; Pentium Pro can do steps 1 through 3 in one go.
984 (define_insn "*cmpfp_i_mixed"
985 [(set (reg:CCFP FLAGS_REG)
986 (compare:CCFP (match_operand 0 "register_operand" "f,x")
987 (match_operand 1 "nonimmediate_operand" "f,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" "fcmp,ssecomi")
994 (if_then_else (match_operand:SF 1 "" "")
996 (const_string "DF")))
997 (set_attr "athlon_decode" "vector")])
999 (define_insn "*cmpfp_i_sse"
1000 [(set (reg:CCFP FLAGS_REG)
1001 (compare:CCFP (match_operand 0 "register_operand" "x")
1002 (match_operand 1 "nonimmediate_operand" "xm")))]
1004 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1005 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1006 "* return output_fp_compare (insn, operands, 1, 0);"
1007 [(set_attr "type" "ssecomi")
1009 (if_then_else (match_operand:SF 1 "" "")
1011 (const_string "DF")))
1012 (set_attr "athlon_decode" "vector")])
1014 (define_insn "*cmpfp_i_i387"
1015 [(set (reg:CCFP FLAGS_REG)
1016 (compare:CCFP (match_operand 0 "register_operand" "f")
1017 (match_operand 1 "register_operand" "f")))]
1018 "TARGET_80387 && TARGET_CMOVE
1019 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1020 && FLOAT_MODE_P (GET_MODE (operands[0]))
1021 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1022 "* return output_fp_compare (insn, operands, 1, 0);"
1023 [(set_attr "type" "fcmp")
1025 (cond [(match_operand:SF 1 "" "")
1027 (match_operand:DF 1 "" "")
1030 (const_string "XF")))
1031 (set_attr "athlon_decode" "vector")])
1033 (define_insn "*cmpfp_iu_mixed"
1034 [(set (reg:CCFPU FLAGS_REG)
1035 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1036 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1037 "TARGET_MIX_SSE_I387
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" "fcmp,ssecomi")
1043 (if_then_else (match_operand:SF 1 "" "")
1045 (const_string "DF")))
1046 (set_attr "athlon_decode" "vector")])
1048 (define_insn "*cmpfp_iu_sse"
1049 [(set (reg:CCFPU FLAGS_REG)
1050 (compare:CCFPU (match_operand 0 "register_operand" "x")
1051 (match_operand 1 "nonimmediate_operand" "xm")))]
1053 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1054 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1055 "* return output_fp_compare (insn, operands, 1, 1);"
1056 [(set_attr "type" "ssecomi")
1058 (if_then_else (match_operand:SF 1 "" "")
1060 (const_string "DF")))
1061 (set_attr "athlon_decode" "vector")])
1063 (define_insn "*cmpfp_iu_387"
1064 [(set (reg:CCFPU FLAGS_REG)
1065 (compare:CCFPU (match_operand 0 "register_operand" "f")
1066 (match_operand 1 "register_operand" "f")))]
1067 "TARGET_80387 && TARGET_CMOVE
1068 && (!TARGET_SSE_MATH || !SSE_FLOAT_MODE_P (GET_MODE (operands[0])))
1069 && FLOAT_MODE_P (GET_MODE (operands[0]))
1070 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1071 "* return output_fp_compare (insn, operands, 1, 1);"
1072 [(set_attr "type" "fcmp")
1074 (cond [(match_operand:SF 1 "" "")
1076 (match_operand:DF 1 "" "")
1079 (const_string "XF")))
1080 (set_attr "athlon_decode" "vector")])
1082 ;; Move instructions.
1084 ;; General case of fullword move.
1086 (define_expand "movsi"
1087 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1088 (match_operand:SI 1 "general_operand" ""))]
1090 "ix86_expand_move (SImode, operands); DONE;")
1092 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1095 ;; %%% We don't use a post-inc memory reference because x86 is not a
1096 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1097 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1098 ;; targets without our curiosities, and it is just as easy to represent
1099 ;; this differently.
1101 (define_insn "*pushsi2"
1102 [(set (match_operand:SI 0 "push_operand" "=<")
1103 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1106 [(set_attr "type" "push")
1107 (set_attr "mode" "SI")])
1109 ;; For 64BIT abi we always round up to 8 bytes.
1110 (define_insn "*pushsi2_rex64"
1111 [(set (match_operand:SI 0 "push_operand" "=X")
1112 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1115 [(set_attr "type" "push")
1116 (set_attr "mode" "SI")])
1118 (define_insn "*pushsi2_prologue"
1119 [(set (match_operand:SI 0 "push_operand" "=<")
1120 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1121 (clobber (mem:BLK (scratch)))]
1124 [(set_attr "type" "push")
1125 (set_attr "mode" "SI")])
1127 (define_insn "*popsi1_epilogue"
1128 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1129 (mem:SI (reg:SI SP_REG)))
1130 (set (reg:SI SP_REG)
1131 (plus:SI (reg:SI SP_REG) (const_int 4)))
1132 (clobber (mem:BLK (scratch)))]
1135 [(set_attr "type" "pop")
1136 (set_attr "mode" "SI")])
1138 (define_insn "popsi1"
1139 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1140 (mem:SI (reg:SI SP_REG)))
1141 (set (reg:SI SP_REG)
1142 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1145 [(set_attr "type" "pop")
1146 (set_attr "mode" "SI")])
1148 (define_insn "*movsi_xor"
1149 [(set (match_operand:SI 0 "register_operand" "=r")
1150 (match_operand:SI 1 "const0_operand" "i"))
1151 (clobber (reg:CC FLAGS_REG))]
1152 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1153 "xor{l}\t{%0, %0|%0, %0}"
1154 [(set_attr "type" "alu1")
1155 (set_attr "mode" "SI")
1156 (set_attr "length_immediate" "0")])
1158 (define_insn "*movsi_or"
1159 [(set (match_operand:SI 0 "register_operand" "=r")
1160 (match_operand:SI 1 "immediate_operand" "i"))
1161 (clobber (reg:CC FLAGS_REG))]
1163 && operands[1] == constm1_rtx
1164 && (TARGET_PENTIUM || optimize_size)"
1166 operands[1] = constm1_rtx;
1167 return "or{l}\t{%1, %0|%0, %1}";
1169 [(set_attr "type" "alu1")
1170 (set_attr "mode" "SI")
1171 (set_attr "length_immediate" "1")])
1173 (define_insn "*movsi_1"
1174 [(set (match_operand:SI 0 "nonimmediate_operand"
1175 "=r ,m ,*y,*y,?rm,?*y,*x,*x,?r,m ,?*Y,*x")
1176 (match_operand:SI 1 "general_operand"
1177 "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Y,*x,r ,m "))]
1178 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1180 switch (get_attr_type (insn))
1183 if (get_attr_mode (insn) == MODE_TI)
1184 return "pxor\t%0, %0";
1185 return "xorps\t%0, %0";
1188 switch (get_attr_mode (insn))
1191 return "movdqa\t{%1, %0|%0, %1}";
1193 return "movaps\t{%1, %0|%0, %1}";
1195 return "movd\t{%1, %0|%0, %1}";
1197 return "movss\t{%1, %0|%0, %1}";
1203 return "pxor\t%0, %0";
1206 if (get_attr_mode (insn) == MODE_DI)
1207 return "movq\t{%1, %0|%0, %1}";
1208 return "movd\t{%1, %0|%0, %1}";
1211 return "lea{l}\t{%1, %0|%0, %1}";
1214 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1215 return "mov{l}\t{%1, %0|%0, %1}";
1219 (cond [(eq_attr "alternative" "2")
1220 (const_string "mmxadd")
1221 (eq_attr "alternative" "3,4,5")
1222 (const_string "mmxmov")
1223 (eq_attr "alternative" "6")
1224 (const_string "sselog1")
1225 (eq_attr "alternative" "7,8,9,10,11")
1226 (const_string "ssemov")
1227 (match_operand:DI 1 "pic_32bit_operand" "")
1228 (const_string "lea")
1230 (const_string "imov")))
1232 (cond [(eq_attr "alternative" "2,3")
1234 (eq_attr "alternative" "6,7")
1236 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1237 (const_string "V4SF")
1238 (const_string "TI"))
1239 (and (eq_attr "alternative" "8,9,10,11")
1240 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1243 (const_string "SI")))])
1245 ;; Stores and loads of ax to arbitrary constant address.
1246 ;; We fake an second form of instruction to force reload to load address
1247 ;; into register when rax is not available
1248 (define_insn "*movabssi_1_rex64"
1249 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1250 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1251 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1253 movabs{l}\t{%1, %P0|%P0, %1}
1254 mov{l}\t{%1, %a0|%a0, %1}"
1255 [(set_attr "type" "imov")
1256 (set_attr "modrm" "0,*")
1257 (set_attr "length_address" "8,0")
1258 (set_attr "length_immediate" "0,*")
1259 (set_attr "memory" "store")
1260 (set_attr "mode" "SI")])
1262 (define_insn "*movabssi_2_rex64"
1263 [(set (match_operand:SI 0 "register_operand" "=a,r")
1264 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1265 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1267 movabs{l}\t{%P1, %0|%0, %P1}
1268 mov{l}\t{%a1, %0|%0, %a1}"
1269 [(set_attr "type" "imov")
1270 (set_attr "modrm" "0,*")
1271 (set_attr "length_address" "8,0")
1272 (set_attr "length_immediate" "0")
1273 (set_attr "memory" "load")
1274 (set_attr "mode" "SI")])
1276 (define_insn "*swapsi"
1277 [(set (match_operand:SI 0 "register_operand" "+r")
1278 (match_operand:SI 1 "register_operand" "+r"))
1283 [(set_attr "type" "imov")
1284 (set_attr "mode" "SI")
1285 (set_attr "pent_pair" "np")
1286 (set_attr "athlon_decode" "vector")])
1288 (define_expand "movhi"
1289 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1290 (match_operand:HI 1 "general_operand" ""))]
1292 "ix86_expand_move (HImode, operands); DONE;")
1294 (define_insn "*pushhi2"
1295 [(set (match_operand:HI 0 "push_operand" "=X")
1296 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1299 [(set_attr "type" "push")
1300 (set_attr "mode" "SI")])
1302 ;; For 64BIT abi we always round up to 8 bytes.
1303 (define_insn "*pushhi2_rex64"
1304 [(set (match_operand:HI 0 "push_operand" "=X")
1305 (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1308 [(set_attr "type" "push")
1309 (set_attr "mode" "DI")])
1311 (define_insn "*movhi_1"
1312 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1313 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1314 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1316 switch (get_attr_type (insn))
1319 /* movzwl is faster than movw on p2 due to partial word stalls,
1320 though not as fast as an aligned movl. */
1321 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1323 if (get_attr_mode (insn) == MODE_SI)
1324 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1326 return "mov{w}\t{%1, %0|%0, %1}";
1330 (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1331 (const_string "imov")
1332 (and (eq_attr "alternative" "0")
1333 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1335 (eq (symbol_ref "TARGET_HIMODE_MATH")
1337 (const_string "imov")
1338 (and (eq_attr "alternative" "1,2")
1339 (match_operand:HI 1 "aligned_operand" ""))
1340 (const_string "imov")
1341 (and (ne (symbol_ref "TARGET_MOVX")
1343 (eq_attr "alternative" "0,2"))
1344 (const_string "imovx")
1346 (const_string "imov")))
1348 (cond [(eq_attr "type" "imovx")
1350 (and (eq_attr "alternative" "1,2")
1351 (match_operand:HI 1 "aligned_operand" ""))
1353 (and (eq_attr "alternative" "0")
1354 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1356 (eq (symbol_ref "TARGET_HIMODE_MATH")
1360 (const_string "HI")))])
1362 ;; Stores and loads of ax to arbitrary constant address.
1363 ;; We fake an second form of instruction to force reload to load address
1364 ;; into register when rax is not available
1365 (define_insn "*movabshi_1_rex64"
1366 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1367 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1368 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1370 movabs{w}\t{%1, %P0|%P0, %1}
1371 mov{w}\t{%1, %a0|%a0, %1}"
1372 [(set_attr "type" "imov")
1373 (set_attr "modrm" "0,*")
1374 (set_attr "length_address" "8,0")
1375 (set_attr "length_immediate" "0,*")
1376 (set_attr "memory" "store")
1377 (set_attr "mode" "HI")])
1379 (define_insn "*movabshi_2_rex64"
1380 [(set (match_operand:HI 0 "register_operand" "=a,r")
1381 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1382 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1384 movabs{w}\t{%P1, %0|%0, %P1}
1385 mov{w}\t{%a1, %0|%0, %a1}"
1386 [(set_attr "type" "imov")
1387 (set_attr "modrm" "0,*")
1388 (set_attr "length_address" "8,0")
1389 (set_attr "length_immediate" "0")
1390 (set_attr "memory" "load")
1391 (set_attr "mode" "HI")])
1393 (define_insn "*swaphi_1"
1394 [(set (match_operand:HI 0 "register_operand" "+r")
1395 (match_operand:HI 1 "register_operand" "+r"))
1398 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1400 [(set_attr "type" "imov")
1401 (set_attr "mode" "SI")
1402 (set_attr "pent_pair" "np")
1403 (set_attr "athlon_decode" "vector")])
1405 (define_insn "*swaphi_2"
1406 [(set (match_operand:HI 0 "register_operand" "+r")
1407 (match_operand:HI 1 "register_operand" "+r"))
1410 "TARGET_PARTIAL_REG_STALL"
1412 [(set_attr "type" "imov")
1413 (set_attr "mode" "HI")
1414 (set_attr "pent_pair" "np")
1415 (set_attr "athlon_decode" "vector")])
1417 (define_expand "movstricthi"
1418 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1419 (match_operand:HI 1 "general_operand" ""))]
1420 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1422 /* Don't generate memory->memory moves, go through a register */
1423 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1424 operands[1] = force_reg (HImode, operands[1]);
1427 (define_insn "*movstricthi_1"
1428 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1429 (match_operand:HI 1 "general_operand" "rn,m"))]
1430 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1431 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1432 "mov{w}\t{%1, %0|%0, %1}"
1433 [(set_attr "type" "imov")
1434 (set_attr "mode" "HI")])
1436 (define_insn "*movstricthi_xor"
1437 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1438 (match_operand:HI 1 "const0_operand" "i"))
1439 (clobber (reg:CC FLAGS_REG))]
1441 && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1442 "xor{w}\t{%0, %0|%0, %0}"
1443 [(set_attr "type" "alu1")
1444 (set_attr "mode" "HI")
1445 (set_attr "length_immediate" "0")])
1447 (define_expand "movqi"
1448 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1449 (match_operand:QI 1 "general_operand" ""))]
1451 "ix86_expand_move (QImode, operands); DONE;")
1453 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1454 ;; "push a byte". But actually we use pushl, which has the effect
1455 ;; of rounding the amount pushed up to a word.
1457 (define_insn "*pushqi2"
1458 [(set (match_operand:QI 0 "push_operand" "=X")
1459 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1462 [(set_attr "type" "push")
1463 (set_attr "mode" "SI")])
1465 ;; For 64BIT abi we always round up to 8 bytes.
1466 (define_insn "*pushqi2_rex64"
1467 [(set (match_operand:QI 0 "push_operand" "=X")
1468 (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1471 [(set_attr "type" "push")
1472 (set_attr "mode" "DI")])
1474 ;; Situation is quite tricky about when to choose full sized (SImode) move
1475 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1476 ;; partial register dependency machines (such as AMD Athlon), where QImode
1477 ;; moves issue extra dependency and for partial register stalls machines
1478 ;; that don't use QImode patterns (and QImode move cause stall on the next
1481 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1482 ;; register stall machines with, where we use QImode instructions, since
1483 ;; partial register stall can be caused there. Then we use movzx.
1484 (define_insn "*movqi_1"
1485 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1486 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1487 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1489 switch (get_attr_type (insn))
1492 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1493 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1495 if (get_attr_mode (insn) == MODE_SI)
1496 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1498 return "mov{b}\t{%1, %0|%0, %1}";
1502 (cond [(and (eq_attr "alternative" "5")
1503 (not (match_operand:QI 1 "aligned_operand" "")))
1504 (const_string "imovx")
1505 (ne (symbol_ref "optimize_size") (const_int 0))
1506 (const_string "imov")
1507 (and (eq_attr "alternative" "3")
1508 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1510 (eq (symbol_ref "TARGET_QIMODE_MATH")
1512 (const_string "imov")
1513 (eq_attr "alternative" "3,5")
1514 (const_string "imovx")
1515 (and (ne (symbol_ref "TARGET_MOVX")
1517 (eq_attr "alternative" "2"))
1518 (const_string "imovx")
1520 (const_string "imov")))
1522 (cond [(eq_attr "alternative" "3,4,5")
1524 (eq_attr "alternative" "6")
1526 (eq_attr "type" "imovx")
1528 (and (eq_attr "type" "imov")
1529 (and (eq_attr "alternative" "0,1")
1530 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1532 (and (eq (symbol_ref "optimize_size")
1534 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1537 ;; Avoid partial register stalls when not using QImode arithmetic
1538 (and (eq_attr "type" "imov")
1539 (and (eq_attr "alternative" "0,1")
1540 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1542 (eq (symbol_ref "TARGET_QIMODE_MATH")
1546 (const_string "QI")))])
1548 (define_expand "reload_outqi"
1549 [(parallel [(match_operand:QI 0 "" "=m")
1550 (match_operand:QI 1 "register_operand" "r")
1551 (match_operand:QI 2 "register_operand" "=&q")])]
1555 op0 = operands[0]; op1 = operands[1]; op2 = operands[2];
1557 gcc_assert (!reg_overlap_mentioned_p (op2, op0));
1558 if (! q_regs_operand (op1, QImode))
1560 emit_insn (gen_movqi (op2, op1));
1563 emit_insn (gen_movqi (op0, op1));
1567 (define_insn "*swapqi_1"
1568 [(set (match_operand:QI 0 "register_operand" "+r")
1569 (match_operand:QI 1 "register_operand" "+r"))
1572 "!TARGET_PARTIAL_REG_STALL || optimize_size"
1574 [(set_attr "type" "imov")
1575 (set_attr "mode" "SI")
1576 (set_attr "pent_pair" "np")
1577 (set_attr "athlon_decode" "vector")])
1579 (define_insn "*swapqi_2"
1580 [(set (match_operand:QI 0 "register_operand" "+q")
1581 (match_operand:QI 1 "register_operand" "+q"))
1584 "TARGET_PARTIAL_REG_STALL"
1586 [(set_attr "type" "imov")
1587 (set_attr "mode" "QI")
1588 (set_attr "pent_pair" "np")
1589 (set_attr "athlon_decode" "vector")])
1591 (define_expand "movstrictqi"
1592 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1593 (match_operand:QI 1 "general_operand" ""))]
1594 "! TARGET_PARTIAL_REG_STALL || optimize_size"
1596 /* Don't generate memory->memory moves, go through a register. */
1597 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1598 operands[1] = force_reg (QImode, operands[1]);
1601 (define_insn "*movstrictqi_1"
1602 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1603 (match_operand:QI 1 "general_operand" "*qn,m"))]
1604 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1605 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1606 "mov{b}\t{%1, %0|%0, %1}"
1607 [(set_attr "type" "imov")
1608 (set_attr "mode" "QI")])
1610 (define_insn "*movstrictqi_xor"
1611 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1612 (match_operand:QI 1 "const0_operand" "i"))
1613 (clobber (reg:CC FLAGS_REG))]
1614 "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1615 "xor{b}\t{%0, %0|%0, %0}"
1616 [(set_attr "type" "alu1")
1617 (set_attr "mode" "QI")
1618 (set_attr "length_immediate" "0")])
1620 (define_insn "*movsi_extv_1"
1621 [(set (match_operand:SI 0 "register_operand" "=R")
1622 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1626 "movs{bl|x}\t{%h1, %0|%0, %h1}"
1627 [(set_attr "type" "imovx")
1628 (set_attr "mode" "SI")])
1630 (define_insn "*movhi_extv_1"
1631 [(set (match_operand:HI 0 "register_operand" "=R")
1632 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1636 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1637 [(set_attr "type" "imovx")
1638 (set_attr "mode" "SI")])
1640 (define_insn "*movqi_extv_1"
1641 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1642 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1647 switch (get_attr_type (insn))
1650 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1652 return "mov{b}\t{%h1, %0|%0, %h1}";
1656 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1657 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1658 (ne (symbol_ref "TARGET_MOVX")
1660 (const_string "imovx")
1661 (const_string "imov")))
1663 (if_then_else (eq_attr "type" "imovx")
1665 (const_string "QI")))])
1667 (define_insn "*movqi_extv_1_rex64"
1668 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1669 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1674 switch (get_attr_type (insn))
1677 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1679 return "mov{b}\t{%h1, %0|%0, %h1}";
1683 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1684 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1685 (ne (symbol_ref "TARGET_MOVX")
1687 (const_string "imovx")
1688 (const_string "imov")))
1690 (if_then_else (eq_attr "type" "imovx")
1692 (const_string "QI")))])
1694 ;; Stores and loads of ax to arbitrary constant address.
1695 ;; We fake an second form of instruction to force reload to load address
1696 ;; into register when rax is not available
1697 (define_insn "*movabsqi_1_rex64"
1698 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1699 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1700 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1702 movabs{b}\t{%1, %P0|%P0, %1}
1703 mov{b}\t{%1, %a0|%a0, %1}"
1704 [(set_attr "type" "imov")
1705 (set_attr "modrm" "0,*")
1706 (set_attr "length_address" "8,0")
1707 (set_attr "length_immediate" "0,*")
1708 (set_attr "memory" "store")
1709 (set_attr "mode" "QI")])
1711 (define_insn "*movabsqi_2_rex64"
1712 [(set (match_operand:QI 0 "register_operand" "=a,r")
1713 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1714 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1716 movabs{b}\t{%P1, %0|%0, %P1}
1717 mov{b}\t{%a1, %0|%0, %a1}"
1718 [(set_attr "type" "imov")
1719 (set_attr "modrm" "0,*")
1720 (set_attr "length_address" "8,0")
1721 (set_attr "length_immediate" "0")
1722 (set_attr "memory" "load")
1723 (set_attr "mode" "QI")])
1725 (define_insn "*movdi_extzv_1"
1726 [(set (match_operand:DI 0 "register_operand" "=R")
1727 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1731 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1732 [(set_attr "type" "imovx")
1733 (set_attr "mode" "DI")])
1735 (define_insn "*movsi_extzv_1"
1736 [(set (match_operand:SI 0 "register_operand" "=R")
1737 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1741 "movz{bl|x}\t{%h1, %0|%0, %h1}"
1742 [(set_attr "type" "imovx")
1743 (set_attr "mode" "SI")])
1745 (define_insn "*movqi_extzv_2"
1746 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1747 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1752 switch (get_attr_type (insn))
1755 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1757 return "mov{b}\t{%h1, %0|%0, %h1}";
1761 (if_then_else (and (match_operand:QI 0 "register_operand" "")
1762 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1763 (ne (symbol_ref "TARGET_MOVX")
1765 (const_string "imovx")
1766 (const_string "imov")))
1768 (if_then_else (eq_attr "type" "imovx")
1770 (const_string "QI")))])
1772 (define_insn "*movqi_extzv_2_rex64"
1773 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1774 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1779 switch (get_attr_type (insn))
1782 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
1784 return "mov{b}\t{%h1, %0|%0, %h1}";
1788 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1789 (ne (symbol_ref "TARGET_MOVX")
1791 (const_string "imovx")
1792 (const_string "imov")))
1794 (if_then_else (eq_attr "type" "imovx")
1796 (const_string "QI")))])
1798 (define_insn "movsi_insv_1"
1799 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1802 (match_operand:SI 1 "general_operand" "Qmn"))]
1804 "mov{b}\t{%b1, %h0|%h0, %b1}"
1805 [(set_attr "type" "imov")
1806 (set_attr "mode" "QI")])
1808 (define_insn "*movsi_insv_1_rex64"
1809 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1812 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
1814 "mov{b}\t{%b1, %h0|%h0, %b1}"
1815 [(set_attr "type" "imov")
1816 (set_attr "mode" "QI")])
1818 (define_insn "movdi_insv_1_rex64"
1819 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1822 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
1824 "mov{b}\t{%b1, %h0|%h0, %b1}"
1825 [(set_attr "type" "imov")
1826 (set_attr "mode" "QI")])
1828 (define_insn "*movqi_insv_2"
1829 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1832 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1835 "mov{b}\t{%h1, %h0|%h0, %h1}"
1836 [(set_attr "type" "imov")
1837 (set_attr "mode" "QI")])
1839 (define_expand "movdi"
1840 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1841 (match_operand:DI 1 "general_operand" ""))]
1843 "ix86_expand_move (DImode, operands); DONE;")
1845 (define_insn "*pushdi"
1846 [(set (match_operand:DI 0 "push_operand" "=<")
1847 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1851 (define_insn "*pushdi2_rex64"
1852 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1853 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1858 [(set_attr "type" "push,multi")
1859 (set_attr "mode" "DI")])
1861 ;; Convert impossible pushes of immediate to existing instructions.
1862 ;; First try to get scratch register and go through it. In case this
1863 ;; fails, push sign extended lower part first and then overwrite
1864 ;; upper part by 32bit move.
1866 [(match_scratch:DI 2 "r")
1867 (set (match_operand:DI 0 "push_operand" "")
1868 (match_operand:DI 1 "immediate_operand" ""))]
1869 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1870 && !x86_64_immediate_operand (operands[1], DImode)"
1871 [(set (match_dup 2) (match_dup 1))
1872 (set (match_dup 0) (match_dup 2))]
1875 ;; We need to define this as both peepholer and splitter for case
1876 ;; peephole2 pass is not run.
1877 ;; "&& 1" is needed to keep it from matching the previous pattern.
1879 [(set (match_operand:DI 0 "push_operand" "")
1880 (match_operand:DI 1 "immediate_operand" ""))]
1881 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1882 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1883 [(set (match_dup 0) (match_dup 1))
1884 (set (match_dup 2) (match_dup 3))]
1885 "split_di (operands + 1, 1, operands + 2, operands + 3);
1886 operands[1] = gen_lowpart (DImode, operands[2]);
1887 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1892 [(set (match_operand:DI 0 "push_operand" "")
1893 (match_operand:DI 1 "immediate_operand" ""))]
1894 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1895 ? flow2_completed : reload_completed)
1896 && !symbolic_operand (operands[1], DImode)
1897 && !x86_64_immediate_operand (operands[1], DImode)"
1898 [(set (match_dup 0) (match_dup 1))
1899 (set (match_dup 2) (match_dup 3))]
1900 "split_di (operands + 1, 1, operands + 2, operands + 3);
1901 operands[1] = gen_lowpart (DImode, operands[2]);
1902 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1906 (define_insn "*pushdi2_prologue_rex64"
1907 [(set (match_operand:DI 0 "push_operand" "=<")
1908 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1909 (clobber (mem:BLK (scratch)))]
1912 [(set_attr "type" "push")
1913 (set_attr "mode" "DI")])
1915 (define_insn "*popdi1_epilogue_rex64"
1916 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1917 (mem:DI (reg:DI SP_REG)))
1918 (set (reg:DI SP_REG)
1919 (plus:DI (reg:DI SP_REG) (const_int 8)))
1920 (clobber (mem:BLK (scratch)))]
1923 [(set_attr "type" "pop")
1924 (set_attr "mode" "DI")])
1926 (define_insn "popdi1"
1927 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1928 (mem:DI (reg:DI SP_REG)))
1929 (set (reg:DI SP_REG)
1930 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1933 [(set_attr "type" "pop")
1934 (set_attr "mode" "DI")])
1936 (define_insn "*movdi_xor_rex64"
1937 [(set (match_operand:DI 0 "register_operand" "=r")
1938 (match_operand:DI 1 "const0_operand" "i"))
1939 (clobber (reg:CC FLAGS_REG))]
1940 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1941 && reload_completed"
1942 "xor{l}\t{%k0, %k0|%k0, %k0}"
1943 [(set_attr "type" "alu1")
1944 (set_attr "mode" "SI")
1945 (set_attr "length_immediate" "0")])
1947 (define_insn "*movdi_or_rex64"
1948 [(set (match_operand:DI 0 "register_operand" "=r")
1949 (match_operand:DI 1 "const_int_operand" "i"))
1950 (clobber (reg:CC FLAGS_REG))]
1951 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1953 && operands[1] == constm1_rtx"
1955 operands[1] = constm1_rtx;
1956 return "or{q}\t{%1, %0|%0, %1}";
1958 [(set_attr "type" "alu1")
1959 (set_attr "mode" "DI")
1960 (set_attr "length_immediate" "1")])
1962 (define_insn "*movdi_2"
1963 [(set (match_operand:DI 0 "nonimmediate_operand"
1964 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1965 (match_operand:DI 1 "general_operand"
1966 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1967 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1972 movq\t{%1, %0|%0, %1}
1973 movq\t{%1, %0|%0, %1}
1975 movq\t{%1, %0|%0, %1}
1976 movdqa\t{%1, %0|%0, %1}
1977 movq\t{%1, %0|%0, %1}
1979 movlps\t{%1, %0|%0, %1}
1980 movaps\t{%1, %0|%0, %1}
1981 movlps\t{%1, %0|%0, %1}"
1982 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1983 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1986 [(set (match_operand:DI 0 "push_operand" "")
1987 (match_operand:DI 1 "general_operand" ""))]
1988 "!TARGET_64BIT && reload_completed
1989 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1991 "ix86_split_long_move (operands); DONE;")
1993 ;; %%% This multiword shite has got to go.
1995 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1996 (match_operand:DI 1 "general_operand" ""))]
1997 "!TARGET_64BIT && reload_completed
1998 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1999 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2001 "ix86_split_long_move (operands); DONE;")
2003 (define_insn "*movdi_1_rex64"
2004 [(set (match_operand:DI 0 "nonimmediate_operand"
2005 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
2006 (match_operand:DI 1 "general_operand"
2007 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
2008 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2010 switch (get_attr_type (insn))
2013 if (which_alternative == 13)
2014 return "movq2dq\t{%1, %0|%0, %1}";
2016 return "movdq2q\t{%1, %0|%0, %1}";
2018 if (get_attr_mode (insn) == MODE_TI)
2019 return "movdqa\t{%1, %0|%0, %1}";
2022 /* Moves from and into integer register is done using movd opcode with
2024 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2025 return "movd\t{%1, %0|%0, %1}";
2026 return "movq\t{%1, %0|%0, %1}";
2029 return "pxor\t%0, %0";
2033 return "lea{q}\t{%a1, %0|%0, %a1}";
2035 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2036 if (get_attr_mode (insn) == MODE_SI)
2037 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2038 else if (which_alternative == 2)
2039 return "movabs{q}\t{%1, %0|%0, %1}";
2041 return "mov{q}\t{%1, %0|%0, %1}";
2045 (cond [(eq_attr "alternative" "5")
2046 (const_string "mmxadd")
2047 (eq_attr "alternative" "6,7,8")
2048 (const_string "mmxmov")
2049 (eq_attr "alternative" "9")
2050 (const_string "sselog1")
2051 (eq_attr "alternative" "10,11,12")
2052 (const_string "ssemov")
2053 (eq_attr "alternative" "13,14")
2054 (const_string "ssecvt")
2055 (eq_attr "alternative" "4")
2056 (const_string "multi")
2057 (match_operand:DI 1 "pic_32bit_operand" "")
2058 (const_string "lea")
2060 (const_string "imov")))
2061 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2062 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2063 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2065 ;; Stores and loads of ax to arbitrary constant address.
2066 ;; We fake an second form of instruction to force reload to load address
2067 ;; into register when rax is not available
2068 (define_insn "*movabsdi_1_rex64"
2069 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2070 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2071 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2073 movabs{q}\t{%1, %P0|%P0, %1}
2074 mov{q}\t{%1, %a0|%a0, %1}"
2075 [(set_attr "type" "imov")
2076 (set_attr "modrm" "0,*")
2077 (set_attr "length_address" "8,0")
2078 (set_attr "length_immediate" "0,*")
2079 (set_attr "memory" "store")
2080 (set_attr "mode" "DI")])
2082 (define_insn "*movabsdi_2_rex64"
2083 [(set (match_operand:DI 0 "register_operand" "=a,r")
2084 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2085 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2087 movabs{q}\t{%P1, %0|%0, %P1}
2088 mov{q}\t{%a1, %0|%0, %a1}"
2089 [(set_attr "type" "imov")
2090 (set_attr "modrm" "0,*")
2091 (set_attr "length_address" "8,0")
2092 (set_attr "length_immediate" "0")
2093 (set_attr "memory" "load")
2094 (set_attr "mode" "DI")])
2096 ;; Convert impossible stores of immediate to existing instructions.
2097 ;; First try to get scratch register and go through it. In case this
2098 ;; fails, move by 32bit parts.
2100 [(match_scratch:DI 2 "r")
2101 (set (match_operand:DI 0 "memory_operand" "")
2102 (match_operand:DI 1 "immediate_operand" ""))]
2103 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2104 && !x86_64_immediate_operand (operands[1], DImode)"
2105 [(set (match_dup 2) (match_dup 1))
2106 (set (match_dup 0) (match_dup 2))]
2109 ;; We need to define this as both peepholer and splitter for case
2110 ;; peephole2 pass is not run.
2111 ;; "&& 1" is needed to keep it from matching the previous pattern.
2113 [(set (match_operand:DI 0 "memory_operand" "")
2114 (match_operand:DI 1 "immediate_operand" ""))]
2115 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2116 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2117 [(set (match_dup 2) (match_dup 3))
2118 (set (match_dup 4) (match_dup 5))]
2119 "split_di (operands, 2, operands + 2, operands + 4);")
2122 [(set (match_operand:DI 0 "memory_operand" "")
2123 (match_operand:DI 1 "immediate_operand" ""))]
2124 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2125 ? flow2_completed : reload_completed)
2126 && !symbolic_operand (operands[1], DImode)
2127 && !x86_64_immediate_operand (operands[1], DImode)"
2128 [(set (match_dup 2) (match_dup 3))
2129 (set (match_dup 4) (match_dup 5))]
2130 "split_di (operands, 2, operands + 2, operands + 4);")
2132 (define_insn "*swapdi_rex64"
2133 [(set (match_operand:DI 0 "register_operand" "+r")
2134 (match_operand:DI 1 "register_operand" "+r"))
2139 [(set_attr "type" "imov")
2140 (set_attr "mode" "DI")
2141 (set_attr "pent_pair" "np")
2142 (set_attr "athlon_decode" "vector")])
2144 (define_expand "movti"
2145 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2146 (match_operand:TI 1 "nonimmediate_operand" ""))]
2147 "TARGET_SSE || TARGET_64BIT"
2150 ix86_expand_move (TImode, operands);
2152 ix86_expand_vector_move (TImode, operands);
2156 (define_insn "*movti_internal"
2157 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2158 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2159 "TARGET_SSE && !TARGET_64BIT
2160 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2162 switch (which_alternative)
2165 if (get_attr_mode (insn) == MODE_V4SF)
2166 return "xorps\t%0, %0";
2168 return "pxor\t%0, %0";
2171 if (get_attr_mode (insn) == MODE_V4SF)
2172 return "movaps\t{%1, %0|%0, %1}";
2174 return "movdqa\t{%1, %0|%0, %1}";
2179 [(set_attr "type" "sselog1,ssemov,ssemov")
2181 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2182 (ne (symbol_ref "optimize_size") (const_int 0)))
2183 (const_string "V4SF")
2184 (and (eq_attr "alternative" "2")
2185 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2187 (const_string "V4SF")]
2188 (const_string "TI")))])
2190 (define_insn "*movti_rex64"
2191 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2192 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2194 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2196 switch (which_alternative)
2202 if (get_attr_mode (insn) == MODE_V4SF)
2203 return "xorps\t%0, %0";
2205 return "pxor\t%0, %0";
2208 if (get_attr_mode (insn) == MODE_V4SF)
2209 return "movaps\t{%1, %0|%0, %1}";
2211 return "movdqa\t{%1, %0|%0, %1}";
2216 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2218 (cond [(eq_attr "alternative" "2,3")
2220 (ne (symbol_ref "optimize_size")
2222 (const_string "V4SF")
2223 (const_string "TI"))
2224 (eq_attr "alternative" "4")
2226 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2228 (ne (symbol_ref "optimize_size")
2230 (const_string "V4SF")
2231 (const_string "TI"))]
2232 (const_string "DI")))])
2235 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2236 (match_operand:TI 1 "general_operand" ""))]
2237 "reload_completed && !SSE_REG_P (operands[0])
2238 && !SSE_REG_P (operands[1])"
2240 "ix86_split_long_move (operands); DONE;")
2242 (define_expand "movsf"
2243 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2244 (match_operand:SF 1 "general_operand" ""))]
2246 "ix86_expand_move (SFmode, operands); DONE;")
2248 (define_insn "*pushsf"
2249 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2250 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2253 /* Anything else should be already split before reg-stack. */
2254 gcc_assert (which_alternative == 1);
2255 return "push{l}\t%1";
2257 [(set_attr "type" "multi,push,multi")
2258 (set_attr "unit" "i387,*,*")
2259 (set_attr "mode" "SF,SI,SF")])
2261 (define_insn "*pushsf_rex64"
2262 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2263 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2266 /* Anything else should be already split before reg-stack. */
2267 gcc_assert (which_alternative == 1);
2268 return "push{q}\t%q1";
2270 [(set_attr "type" "multi,push,multi")
2271 (set_attr "unit" "i387,*,*")
2272 (set_attr "mode" "SF,DI,SF")])
2275 [(set (match_operand:SF 0 "push_operand" "")
2276 (match_operand:SF 1 "memory_operand" ""))]
2278 && MEM_P (operands[1])
2279 && constant_pool_reference_p (operands[1])"
2282 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2285 ;; %%% Kill this when call knows how to work this out.
2287 [(set (match_operand:SF 0 "push_operand" "")
2288 (match_operand:SF 1 "any_fp_register_operand" ""))]
2290 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2291 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2294 [(set (match_operand:SF 0 "push_operand" "")
2295 (match_operand:SF 1 "any_fp_register_operand" ""))]
2297 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2298 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2300 (define_insn "*movsf_1"
2301 [(set (match_operand:SF 0 "nonimmediate_operand"
2302 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2303 (match_operand:SF 1 "general_operand"
2304 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2305 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2306 && (reload_in_progress || reload_completed
2307 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2308 || (!TARGET_SSE_MATH && optimize_size
2309 && standard_80387_constant_p (operands[1]))
2310 || GET_CODE (operands[1]) != CONST_DOUBLE
2311 || memory_operand (operands[0], SFmode))"
2313 switch (which_alternative)
2316 return output_387_reg_move (insn, operands);
2319 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2320 return "fstp%z0\t%y0";
2322 return "fst%z0\t%y0";
2325 return standard_80387_constant_opcode (operands[1]);
2329 return "mov{l}\t{%1, %0|%0, %1}";
2331 if (get_attr_mode (insn) == MODE_TI)
2332 return "pxor\t%0, %0";
2334 return "xorps\t%0, %0";
2336 if (get_attr_mode (insn) == MODE_V4SF)
2337 return "movaps\t{%1, %0|%0, %1}";
2339 return "movss\t{%1, %0|%0, %1}";
2342 return "movss\t{%1, %0|%0, %1}";
2346 return "movd\t{%1, %0|%0, %1}";
2349 return "movq\t{%1, %0|%0, %1}";
2355 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2357 (cond [(eq_attr "alternative" "3,4,9,10")
2359 (eq_attr "alternative" "5")
2361 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2363 (ne (symbol_ref "TARGET_SSE2")
2365 (eq (symbol_ref "optimize_size")
2368 (const_string "V4SF"))
2369 /* For architectures resolving dependencies on
2370 whole SSE registers use APS move to break dependency
2371 chains, otherwise use short move to avoid extra work.
2373 Do the same for architectures resolving dependencies on
2374 the parts. While in DF mode it is better to always handle
2375 just register parts, the SF mode is different due to lack
2376 of instructions to load just part of the register. It is
2377 better to maintain the whole registers in single format
2378 to avoid problems on using packed logical operations. */
2379 (eq_attr "alternative" "6")
2381 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2383 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2385 (const_string "V4SF")
2386 (const_string "SF"))
2387 (eq_attr "alternative" "11")
2388 (const_string "DI")]
2389 (const_string "SF")))])
2391 (define_insn "*swapsf"
2392 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2393 (match_operand:SF 1 "fp_register_operand" "+f"))
2396 "reload_completed || TARGET_80387"
2398 if (STACK_TOP_P (operands[0]))
2403 [(set_attr "type" "fxch")
2404 (set_attr "mode" "SF")])
2406 (define_expand "movdf"
2407 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2408 (match_operand:DF 1 "general_operand" ""))]
2410 "ix86_expand_move (DFmode, operands); DONE;")
2412 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2413 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2414 ;; On the average, pushdf using integers can be still shorter. Allow this
2415 ;; pattern for optimize_size too.
2417 (define_insn "*pushdf_nointeger"
2418 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2419 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2420 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2422 /* This insn should be already split before reg-stack. */
2425 [(set_attr "type" "multi")
2426 (set_attr "unit" "i387,*,*,*")
2427 (set_attr "mode" "DF,SI,SI,DF")])
2429 (define_insn "*pushdf_integer"
2430 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2431 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y"))]
2432 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2434 /* This insn should be already split before reg-stack. */
2437 [(set_attr "type" "multi")
2438 (set_attr "unit" "i387,*,*")
2439 (set_attr "mode" "DF,SI,DF")])
2441 ;; %%% Kill this when call knows how to work this out.
2443 [(set (match_operand:DF 0 "push_operand" "")
2444 (match_operand:DF 1 "any_fp_register_operand" ""))]
2445 "!TARGET_64BIT && reload_completed"
2446 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2447 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2451 [(set (match_operand:DF 0 "push_operand" "")
2452 (match_operand:DF 1 "any_fp_register_operand" ""))]
2453 "TARGET_64BIT && reload_completed"
2454 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2455 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2459 [(set (match_operand:DF 0 "push_operand" "")
2460 (match_operand:DF 1 "general_operand" ""))]
2463 "ix86_split_long_move (operands); DONE;")
2465 ;; Moving is usually shorter when only FP registers are used. This separate
2466 ;; movdf pattern avoids the use of integer registers for FP operations
2467 ;; when optimizing for size.
2469 (define_insn "*movdf_nointeger"
2470 [(set (match_operand:DF 0 "nonimmediate_operand"
2471 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2472 (match_operand:DF 1 "general_operand"
2473 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2474 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2475 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2476 && (reload_in_progress || reload_completed
2477 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2478 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2479 && standard_80387_constant_p (operands[1]))
2480 || GET_CODE (operands[1]) != CONST_DOUBLE
2481 || memory_operand (operands[0], DFmode))"
2483 switch (which_alternative)
2486 return output_387_reg_move (insn, operands);
2489 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2490 return "fstp%z0\t%y0";
2492 return "fst%z0\t%y0";
2495 return standard_80387_constant_opcode (operands[1]);
2501 switch (get_attr_mode (insn))
2504 return "xorps\t%0, %0";
2506 return "xorpd\t%0, %0";
2508 return "pxor\t%0, %0";
2515 switch (get_attr_mode (insn))
2518 return "movaps\t{%1, %0|%0, %1}";
2520 return "movapd\t{%1, %0|%0, %1}";
2522 return "movdqa\t{%1, %0|%0, %1}";
2524 return "movq\t{%1, %0|%0, %1}";
2526 return "movsd\t{%1, %0|%0, %1}";
2528 return "movlpd\t{%1, %0|%0, %1}";
2530 return "movlps\t{%1, %0|%0, %1}";
2539 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2541 (cond [(eq_attr "alternative" "0,1,2")
2543 (eq_attr "alternative" "3,4")
2546 /* For SSE1, we have many fewer alternatives. */
2547 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2548 (cond [(eq_attr "alternative" "5,6")
2549 (const_string "V4SF")
2551 (const_string "V2SF"))
2553 /* xorps is one byte shorter. */
2554 (eq_attr "alternative" "5")
2555 (cond [(ne (symbol_ref "optimize_size")
2557 (const_string "V4SF")
2558 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2562 (const_string "V2DF"))
2564 /* For architectures resolving dependencies on
2565 whole SSE registers use APD move to break dependency
2566 chains, otherwise use short move to avoid extra work.
2568 movaps encodes one byte shorter. */
2569 (eq_attr "alternative" "6")
2571 [(ne (symbol_ref "optimize_size")
2573 (const_string "V4SF")
2574 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2576 (const_string "V2DF")
2578 (const_string "DF"))
2579 /* For architectures resolving dependencies on register
2580 parts we may avoid extra work to zero out upper part
2582 (eq_attr "alternative" "7")
2584 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2586 (const_string "V1DF")
2587 (const_string "DF"))
2589 (const_string "DF")))])
2591 (define_insn "*movdf_integer"
2592 [(set (match_operand:DF 0 "nonimmediate_operand"
2593 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2594 (match_operand:DF 1 "general_operand"
2595 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2596 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2597 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2598 && (reload_in_progress || reload_completed
2599 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2600 || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2601 && standard_80387_constant_p (operands[1]))
2602 || GET_CODE (operands[1]) != CONST_DOUBLE
2603 || memory_operand (operands[0], DFmode))"
2605 switch (which_alternative)
2608 return output_387_reg_move (insn, operands);
2611 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2612 return "fstp%z0\t%y0";
2614 return "fst%z0\t%y0";
2617 return standard_80387_constant_opcode (operands[1]);
2624 switch (get_attr_mode (insn))
2627 return "xorps\t%0, %0";
2629 return "xorpd\t%0, %0";
2631 return "pxor\t%0, %0";
2638 switch (get_attr_mode (insn))
2641 return "movaps\t{%1, %0|%0, %1}";
2643 return "movapd\t{%1, %0|%0, %1}";
2645 return "movdqa\t{%1, %0|%0, %1}";
2647 return "movq\t{%1, %0|%0, %1}";
2649 return "movsd\t{%1, %0|%0, %1}";
2651 return "movlpd\t{%1, %0|%0, %1}";
2653 return "movlps\t{%1, %0|%0, %1}";
2662 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2664 (cond [(eq_attr "alternative" "0,1,2")
2666 (eq_attr "alternative" "3,4")
2669 /* For SSE1, we have many fewer alternatives. */
2670 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2671 (cond [(eq_attr "alternative" "5,6")
2672 (const_string "V4SF")
2674 (const_string "V2SF"))
2676 /* xorps is one byte shorter. */
2677 (eq_attr "alternative" "5")
2678 (cond [(ne (symbol_ref "optimize_size")
2680 (const_string "V4SF")
2681 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2685 (const_string "V2DF"))
2687 /* For architectures resolving dependencies on
2688 whole SSE registers use APD move to break dependency
2689 chains, otherwise use short move to avoid extra work.
2691 movaps encodes one byte shorter. */
2692 (eq_attr "alternative" "6")
2694 [(ne (symbol_ref "optimize_size")
2696 (const_string "V4SF")
2697 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2699 (const_string "V2DF")
2701 (const_string "DF"))
2702 /* For architectures resolving dependencies on register
2703 parts we may avoid extra work to zero out upper part
2705 (eq_attr "alternative" "7")
2707 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2709 (const_string "V1DF")
2710 (const_string "DF"))
2712 (const_string "DF")))])
2715 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2716 (match_operand:DF 1 "general_operand" ""))]
2718 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2719 && ! (ANY_FP_REG_P (operands[0]) ||
2720 (GET_CODE (operands[0]) == SUBREG
2721 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2722 && ! (ANY_FP_REG_P (operands[1]) ||
2723 (GET_CODE (operands[1]) == SUBREG
2724 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2726 "ix86_split_long_move (operands); DONE;")
2728 (define_insn "*swapdf"
2729 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2730 (match_operand:DF 1 "fp_register_operand" "+f"))
2733 "reload_completed || TARGET_80387"
2735 if (STACK_TOP_P (operands[0]))
2740 [(set_attr "type" "fxch")
2741 (set_attr "mode" "DF")])
2743 (define_expand "movxf"
2744 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2745 (match_operand:XF 1 "general_operand" ""))]
2747 "ix86_expand_move (XFmode, operands); DONE;")
2749 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2750 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2751 ;; Pushing using integer instructions is longer except for constants
2752 ;; and direct memory references.
2753 ;; (assuming that any given constant is pushed only once, but this ought to be
2754 ;; handled elsewhere).
2756 (define_insn "*pushxf_nointeger"
2757 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2758 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2761 /* This insn should be already split before reg-stack. */
2764 [(set_attr "type" "multi")
2765 (set_attr "unit" "i387,*,*")
2766 (set_attr "mode" "XF,SI,SI")])
2768 (define_insn "*pushxf_integer"
2769 [(set (match_operand:XF 0 "push_operand" "=<,<")
2770 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2773 /* This insn should be already split before reg-stack. */
2776 [(set_attr "type" "multi")
2777 (set_attr "unit" "i387,*")
2778 (set_attr "mode" "XF,SI")])
2781 [(set (match_operand 0 "push_operand" "")
2782 (match_operand 1 "general_operand" ""))]
2784 && (GET_MODE (operands[0]) == XFmode
2785 || GET_MODE (operands[0]) == DFmode)
2786 && !ANY_FP_REG_P (operands[1])"
2788 "ix86_split_long_move (operands); DONE;")
2791 [(set (match_operand:XF 0 "push_operand" "")
2792 (match_operand:XF 1 "any_fp_register_operand" ""))]
2794 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2795 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2796 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2799 [(set (match_operand:XF 0 "push_operand" "")
2800 (match_operand:XF 1 "any_fp_register_operand" ""))]
2802 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2803 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2804 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2806 ;; Do not use integer registers when optimizing for size
2807 (define_insn "*movxf_nointeger"
2808 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2809 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2811 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2812 && (reload_in_progress || reload_completed
2813 || (optimize_size && standard_80387_constant_p (operands[1]))
2814 || GET_CODE (operands[1]) != CONST_DOUBLE
2815 || memory_operand (operands[0], XFmode))"
2817 switch (which_alternative)
2820 return output_387_reg_move (insn, operands);
2823 /* There is no non-popping store to memory for XFmode. So if
2824 we need one, follow the store with a load. */
2825 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2826 return "fstp%z0\t%y0\;fld%z0\t%y0";
2828 return "fstp%z0\t%y0";
2831 return standard_80387_constant_opcode (operands[1]);
2839 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2840 (set_attr "mode" "XF,XF,XF,SI,SI")])
2842 (define_insn "*movxf_integer"
2843 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2844 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2846 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2847 && (reload_in_progress || reload_completed
2848 || (optimize_size && standard_80387_constant_p (operands[1]))
2849 || GET_CODE (operands[1]) != CONST_DOUBLE
2850 || memory_operand (operands[0], XFmode))"
2852 switch (which_alternative)
2855 return output_387_reg_move (insn, operands);
2858 /* There is no non-popping store to memory for XFmode. So if
2859 we need one, follow the store with a load. */
2860 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2861 return "fstp%z0\t%y0\;fld%z0\t%y0";
2863 return "fstp%z0\t%y0";
2866 return standard_80387_constant_opcode (operands[1]);
2875 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2876 (set_attr "mode" "XF,XF,XF,SI,SI")])
2879 [(set (match_operand 0 "nonimmediate_operand" "")
2880 (match_operand 1 "general_operand" ""))]
2882 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2883 && GET_MODE (operands[0]) == XFmode
2884 && ! (ANY_FP_REG_P (operands[0]) ||
2885 (GET_CODE (operands[0]) == SUBREG
2886 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2887 && ! (ANY_FP_REG_P (operands[1]) ||
2888 (GET_CODE (operands[1]) == SUBREG
2889 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2891 "ix86_split_long_move (operands); DONE;")
2894 [(set (match_operand 0 "register_operand" "")
2895 (match_operand 1 "memory_operand" ""))]
2897 && MEM_P (operands[1])
2898 && (GET_MODE (operands[0]) == XFmode
2899 || GET_MODE (operands[0]) == SFmode
2900 || GET_MODE (operands[0]) == DFmode)
2901 && constant_pool_reference_p (operands[1])"
2902 [(set (match_dup 0) (match_dup 1))]
2904 rtx c = avoid_constant_pool_reference (operands[1]);
2905 rtx r = operands[0];
2907 if (GET_CODE (r) == SUBREG)
2912 if (!standard_sse_constant_p (c))
2915 else if (FP_REG_P (r))
2917 if (!standard_80387_constant_p (c))
2920 else if (MMX_REG_P (r))
2927 [(set (match_operand 0 "register_operand" "")
2928 (float_extend (match_operand 1 "memory_operand" "")))]
2930 && MEM_P (operands[1])
2931 && (GET_MODE (operands[0]) == XFmode
2932 || GET_MODE (operands[0]) == SFmode
2933 || GET_MODE (operands[0]) == DFmode)
2934 && constant_pool_reference_p (operands[1])"
2935 [(set (match_dup 0) (match_dup 1))]
2937 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2938 rtx r = operands[0];
2940 if (GET_CODE (r) == SUBREG)
2945 if (!standard_sse_constant_p (c))
2948 else if (FP_REG_P (r))
2950 if (!standard_80387_constant_p (c))
2953 else if (MMX_REG_P (r))
2959 (define_insn "swapxf"
2960 [(set (match_operand:XF 0 "register_operand" "+f")
2961 (match_operand:XF 1 "register_operand" "+f"))
2966 if (STACK_TOP_P (operands[0]))
2971 [(set_attr "type" "fxch")
2972 (set_attr "mode" "XF")])
2974 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2976 [(set (match_operand:X87MODEF 0 "register_operand" "")
2977 (match_operand:X87MODEF 1 "immediate_operand" ""))]
2978 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2979 && (standard_80387_constant_p (operands[1]) == 8
2980 || standard_80387_constant_p (operands[1]) == 9)"
2981 [(set (match_dup 0)(match_dup 1))
2983 (neg:X87MODEF (match_dup 0)))]
2987 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2988 if (real_isnegzero (&r))
2989 operands[1] = CONST0_RTX (<MODE>mode);
2991 operands[1] = CONST1_RTX (<MODE>mode);
2994 (define_expand "movtf"
2995 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2996 (match_operand:TF 1 "nonimmediate_operand" ""))]
2999 ix86_expand_move (TFmode, operands);
3003 (define_insn "*movtf_internal"
3004 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3005 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3007 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3009 switch (which_alternative)
3015 if (get_attr_mode (insn) == MODE_V4SF)
3016 return "xorps\t%0, %0";
3018 return "pxor\t%0, %0";
3021 if (get_attr_mode (insn) == MODE_V4SF)
3022 return "movaps\t{%1, %0|%0, %1}";
3024 return "movdqa\t{%1, %0|%0, %1}";
3029 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3031 (cond [(eq_attr "alternative" "2,3")
3033 (ne (symbol_ref "optimize_size")
3035 (const_string "V4SF")
3036 (const_string "TI"))
3037 (eq_attr "alternative" "4")
3039 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3041 (ne (symbol_ref "optimize_size")
3043 (const_string "V4SF")
3044 (const_string "TI"))]
3045 (const_string "DI")))])
3048 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3049 (match_operand:TF 1 "general_operand" ""))]
3050 "reload_completed && !SSE_REG_P (operands[0])
3051 && !SSE_REG_P (operands[1])"
3053 "ix86_split_long_move (operands); DONE;")
3055 ;; Zero extension instructions
3057 (define_expand "zero_extendhisi2"
3058 [(set (match_operand:SI 0 "register_operand" "")
3059 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3062 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3064 operands[1] = force_reg (HImode, operands[1]);
3065 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3070 (define_insn "zero_extendhisi2_and"
3071 [(set (match_operand:SI 0 "register_operand" "=r")
3072 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3073 (clobber (reg:CC FLAGS_REG))]
3074 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3076 [(set_attr "type" "alu1")
3077 (set_attr "mode" "SI")])
3080 [(set (match_operand:SI 0 "register_operand" "")
3081 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3082 (clobber (reg:CC FLAGS_REG))]
3083 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3084 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3085 (clobber (reg:CC FLAGS_REG))])]
3088 (define_insn "*zero_extendhisi2_movzwl"
3089 [(set (match_operand:SI 0 "register_operand" "=r")
3090 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3091 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3092 "movz{wl|x}\t{%1, %0|%0, %1}"
3093 [(set_attr "type" "imovx")
3094 (set_attr "mode" "SI")])
3096 (define_expand "zero_extendqihi2"
3098 [(set (match_operand:HI 0 "register_operand" "")
3099 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3100 (clobber (reg:CC FLAGS_REG))])]
3104 (define_insn "*zero_extendqihi2_and"
3105 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3106 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3107 (clobber (reg:CC FLAGS_REG))]
3108 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3110 [(set_attr "type" "alu1")
3111 (set_attr "mode" "HI")])
3113 (define_insn "*zero_extendqihi2_movzbw_and"
3114 [(set (match_operand:HI 0 "register_operand" "=r,r")
3115 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3116 (clobber (reg:CC FLAGS_REG))]
3117 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3119 [(set_attr "type" "imovx,alu1")
3120 (set_attr "mode" "HI")])
3122 ; zero extend to SImode here to avoid partial register stalls
3123 (define_insn "*zero_extendqihi2_movzbl"
3124 [(set (match_operand:HI 0 "register_operand" "=r")
3125 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3126 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3127 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3128 [(set_attr "type" "imovx")
3129 (set_attr "mode" "SI")])
3131 ;; For the movzbw case strip only the clobber
3133 [(set (match_operand:HI 0 "register_operand" "")
3134 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3135 (clobber (reg:CC FLAGS_REG))]
3137 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3138 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3139 [(set (match_operand:HI 0 "register_operand" "")
3140 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3142 ;; When source and destination does not overlap, clear destination
3143 ;; first and then do the movb
3145 [(set (match_operand:HI 0 "register_operand" "")
3146 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3147 (clobber (reg:CC FLAGS_REG))]
3149 && ANY_QI_REG_P (operands[0])
3150 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3151 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3152 [(set (match_dup 0) (const_int 0))
3153 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3154 "operands[2] = gen_lowpart (QImode, operands[0]);")
3156 ;; Rest is handled by single and.
3158 [(set (match_operand:HI 0 "register_operand" "")
3159 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3160 (clobber (reg:CC FLAGS_REG))]
3162 && true_regnum (operands[0]) == true_regnum (operands[1])"
3163 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3164 (clobber (reg:CC FLAGS_REG))])]
3167 (define_expand "zero_extendqisi2"
3169 [(set (match_operand:SI 0 "register_operand" "")
3170 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3171 (clobber (reg:CC FLAGS_REG))])]
3175 (define_insn "*zero_extendqisi2_and"
3176 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3177 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3178 (clobber (reg:CC FLAGS_REG))]
3179 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3181 [(set_attr "type" "alu1")
3182 (set_attr "mode" "SI")])
3184 (define_insn "*zero_extendqisi2_movzbw_and"
3185 [(set (match_operand:SI 0 "register_operand" "=r,r")
3186 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3187 (clobber (reg:CC FLAGS_REG))]
3188 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3190 [(set_attr "type" "imovx,alu1")
3191 (set_attr "mode" "SI")])
3193 (define_insn "*zero_extendqisi2_movzbw"
3194 [(set (match_operand:SI 0 "register_operand" "=r")
3195 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3196 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3197 "movz{bl|x}\t{%1, %0|%0, %1}"
3198 [(set_attr "type" "imovx")
3199 (set_attr "mode" "SI")])
3201 ;; For the movzbl case strip only the clobber
3203 [(set (match_operand:SI 0 "register_operand" "")
3204 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3205 (clobber (reg:CC FLAGS_REG))]
3207 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3208 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3210 (zero_extend:SI (match_dup 1)))])
3212 ;; When source and destination does not overlap, clear destination
3213 ;; first and then do the movb
3215 [(set (match_operand:SI 0 "register_operand" "")
3216 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3217 (clobber (reg:CC FLAGS_REG))]
3219 && ANY_QI_REG_P (operands[0])
3220 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3221 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3222 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3223 [(set (match_dup 0) (const_int 0))
3224 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3225 "operands[2] = gen_lowpart (QImode, operands[0]);")
3227 ;; Rest is handled by single and.
3229 [(set (match_operand:SI 0 "register_operand" "")
3230 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3231 (clobber (reg:CC FLAGS_REG))]
3233 && true_regnum (operands[0]) == true_regnum (operands[1])"
3234 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3235 (clobber (reg:CC FLAGS_REG))])]
3238 ;; %%% Kill me once multi-word ops are sane.
3239 (define_expand "zero_extendsidi2"
3240 [(set (match_operand:DI 0 "register_operand" "=r")
3241 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3245 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3250 (define_insn "zero_extendsidi2_32"
3251 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3252 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3253 (clobber (reg:CC FLAGS_REG))]
3259 movd\t{%1, %0|%0, %1}
3260 movd\t{%1, %0|%0, %1}"
3261 [(set_attr "mode" "SI,SI,SI,DI,TI")
3262 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3264 (define_insn "zero_extendsidi2_rex64"
3265 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3266 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3269 mov\t{%k1, %k0|%k0, %k1}
3271 movd\t{%1, %0|%0, %1}
3272 movd\t{%1, %0|%0, %1}"
3273 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3274 (set_attr "mode" "SI,DI,SI,SI")])
3277 [(set (match_operand:DI 0 "memory_operand" "")
3278 (zero_extend:DI (match_dup 0)))]
3280 [(set (match_dup 4) (const_int 0))]
3281 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3284 [(set (match_operand:DI 0 "register_operand" "")
3285 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3286 (clobber (reg:CC FLAGS_REG))]
3287 "!TARGET_64BIT && reload_completed
3288 && true_regnum (operands[0]) == true_regnum (operands[1])"
3289 [(set (match_dup 4) (const_int 0))]
3290 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3293 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3294 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3295 (clobber (reg:CC FLAGS_REG))]
3296 "!TARGET_64BIT && reload_completed
3297 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3298 [(set (match_dup 3) (match_dup 1))
3299 (set (match_dup 4) (const_int 0))]
3300 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3302 (define_insn "zero_extendhidi2"
3303 [(set (match_operand:DI 0 "register_operand" "=r")
3304 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3306 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3307 [(set_attr "type" "imovx")
3308 (set_attr "mode" "DI")])
3310 (define_insn "zero_extendqidi2"
3311 [(set (match_operand:DI 0 "register_operand" "=r")
3312 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3314 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3315 [(set_attr "type" "imovx")
3316 (set_attr "mode" "DI")])
3318 ;; Sign extension instructions
3320 (define_expand "extendsidi2"
3321 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3322 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3323 (clobber (reg:CC FLAGS_REG))
3324 (clobber (match_scratch:SI 2 ""))])]
3329 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3334 (define_insn "*extendsidi2_1"
3335 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3336 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3337 (clobber (reg:CC FLAGS_REG))
3338 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3342 (define_insn "extendsidi2_rex64"
3343 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3344 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3348 movs{lq|x}\t{%1,%0|%0, %1}"
3349 [(set_attr "type" "imovx")
3350 (set_attr "mode" "DI")
3351 (set_attr "prefix_0f" "0")
3352 (set_attr "modrm" "0,1")])
3354 (define_insn "extendhidi2"
3355 [(set (match_operand:DI 0 "register_operand" "=r")
3356 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3358 "movs{wq|x}\t{%1,%0|%0, %1}"
3359 [(set_attr "type" "imovx")
3360 (set_attr "mode" "DI")])
3362 (define_insn "extendqidi2"
3363 [(set (match_operand:DI 0 "register_operand" "=r")
3364 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3366 "movs{bq|x}\t{%1,%0|%0, %1}"
3367 [(set_attr "type" "imovx")
3368 (set_attr "mode" "DI")])
3370 ;; Extend to memory case when source register does die.
3372 [(set (match_operand:DI 0 "memory_operand" "")
3373 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3374 (clobber (reg:CC FLAGS_REG))
3375 (clobber (match_operand:SI 2 "register_operand" ""))]
3377 && dead_or_set_p (insn, operands[1])
3378 && !reg_mentioned_p (operands[1], operands[0]))"
3379 [(set (match_dup 3) (match_dup 1))
3380 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3381 (clobber (reg:CC FLAGS_REG))])
3382 (set (match_dup 4) (match_dup 1))]
3383 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3385 ;; Extend to memory case when source register does not die.
3387 [(set (match_operand:DI 0 "memory_operand" "")
3388 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3389 (clobber (reg:CC FLAGS_REG))
3390 (clobber (match_operand:SI 2 "register_operand" ""))]
3394 split_di (&operands[0], 1, &operands[3], &operands[4]);
3396 emit_move_insn (operands[3], operands[1]);
3398 /* Generate a cltd if possible and doing so it profitable. */
3399 if (true_regnum (operands[1]) == 0
3400 && true_regnum (operands[2]) == 1
3401 && (optimize_size || TARGET_USE_CLTD))
3403 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3407 emit_move_insn (operands[2], operands[1]);
3408 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3410 emit_move_insn (operands[4], operands[2]);
3414 ;; Extend to register case. Optimize case where source and destination
3415 ;; registers match and cases where we can use cltd.
3417 [(set (match_operand:DI 0 "register_operand" "")
3418 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3419 (clobber (reg:CC FLAGS_REG))
3420 (clobber (match_scratch:SI 2 ""))]
3424 split_di (&operands[0], 1, &operands[3], &operands[4]);
3426 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3427 emit_move_insn (operands[3], operands[1]);
3429 /* Generate a cltd if possible and doing so it profitable. */
3430 if (true_regnum (operands[3]) == 0
3431 && (optimize_size || TARGET_USE_CLTD))
3433 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3437 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3438 emit_move_insn (operands[4], operands[1]);
3440 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3444 (define_insn "extendhisi2"
3445 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3446 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3449 switch (get_attr_prefix_0f (insn))
3452 return "{cwtl|cwde}";
3454 return "movs{wl|x}\t{%1,%0|%0, %1}";
3457 [(set_attr "type" "imovx")
3458 (set_attr "mode" "SI")
3459 (set (attr "prefix_0f")
3460 ;; movsx is short decodable while cwtl is vector decoded.
3461 (if_then_else (and (eq_attr "cpu" "!k6")
3462 (eq_attr "alternative" "0"))
3464 (const_string "1")))
3466 (if_then_else (eq_attr "prefix_0f" "0")
3468 (const_string "1")))])
3470 (define_insn "*extendhisi2_zext"
3471 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3473 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3476 switch (get_attr_prefix_0f (insn))
3479 return "{cwtl|cwde}";
3481 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3484 [(set_attr "type" "imovx")
3485 (set_attr "mode" "SI")
3486 (set (attr "prefix_0f")
3487 ;; movsx is short decodable while cwtl is vector decoded.
3488 (if_then_else (and (eq_attr "cpu" "!k6")
3489 (eq_attr "alternative" "0"))
3491 (const_string "1")))
3493 (if_then_else (eq_attr "prefix_0f" "0")
3495 (const_string "1")))])
3497 (define_insn "extendqihi2"
3498 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3499 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3502 switch (get_attr_prefix_0f (insn))
3505 return "{cbtw|cbw}";
3507 return "movs{bw|x}\t{%1,%0|%0, %1}";
3510 [(set_attr "type" "imovx")
3511 (set_attr "mode" "HI")
3512 (set (attr "prefix_0f")
3513 ;; movsx is short decodable while cwtl is vector decoded.
3514 (if_then_else (and (eq_attr "cpu" "!k6")
3515 (eq_attr "alternative" "0"))
3517 (const_string "1")))
3519 (if_then_else (eq_attr "prefix_0f" "0")
3521 (const_string "1")))])
3523 (define_insn "extendqisi2"
3524 [(set (match_operand:SI 0 "register_operand" "=r")
3525 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3527 "movs{bl|x}\t{%1,%0|%0, %1}"
3528 [(set_attr "type" "imovx")
3529 (set_attr "mode" "SI")])
3531 (define_insn "*extendqisi2_zext"
3532 [(set (match_operand:DI 0 "register_operand" "=r")
3534 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3536 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3537 [(set_attr "type" "imovx")
3538 (set_attr "mode" "SI")])
3540 ;; Conversions between float and double.
3542 ;; These are all no-ops in the model used for the 80387. So just
3545 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3546 (define_insn "*dummy_extendsfdf2"
3547 [(set (match_operand:DF 0 "push_operand" "=<")
3548 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3553 [(set (match_operand:DF 0 "push_operand" "")
3554 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3556 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3557 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3560 [(set (match_operand:DF 0 "push_operand" "")
3561 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3563 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3564 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3566 (define_insn "*dummy_extendsfxf2"
3567 [(set (match_operand:XF 0 "push_operand" "=<")
3568 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3573 [(set (match_operand:XF 0 "push_operand" "")
3574 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3576 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3577 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3578 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3581 [(set (match_operand:XF 0 "push_operand" "")
3582 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3584 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3585 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3586 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3589 [(set (match_operand:XF 0 "push_operand" "")
3590 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3592 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3593 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3594 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3597 [(set (match_operand:XF 0 "push_operand" "")
3598 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3600 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3601 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3602 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3604 (define_expand "extendsfdf2"
3605 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3606 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3607 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3609 /* ??? Needed for compress_float_constant since all fp constants
3610 are LEGITIMATE_CONSTANT_P. */
3611 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3613 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3614 && standard_80387_constant_p (operands[1]) > 0)
3616 operands[1] = simplify_const_unary_operation
3617 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3618 emit_move_insn_1 (operands[0], operands[1]);
3621 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3625 (define_insn "*extendsfdf2_mixed"
3626 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3627 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3628 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3630 switch (which_alternative)
3633 return output_387_reg_move (insn, operands);
3636 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3637 return "fstp%z0\t%y0";
3639 return "fst%z0\t%y0";
3642 return "cvtss2sd\t{%1, %0|%0, %1}";
3648 [(set_attr "type" "fmov,fmov,ssecvt")
3649 (set_attr "mode" "SF,XF,DF")])
3651 (define_insn "*extendsfdf2_sse"
3652 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3653 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3654 "TARGET_SSE2 && TARGET_SSE_MATH"
3655 "cvtss2sd\t{%1, %0|%0, %1}"
3656 [(set_attr "type" "ssecvt")
3657 (set_attr "mode" "DF")])
3659 (define_insn "*extendsfdf2_i387"
3660 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3661 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3664 switch (which_alternative)
3667 return output_387_reg_move (insn, operands);
3670 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3671 return "fstp%z0\t%y0";
3673 return "fst%z0\t%y0";
3679 [(set_attr "type" "fmov")
3680 (set_attr "mode" "SF,XF")])
3682 (define_expand "extendsfxf2"
3683 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3684 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3687 /* ??? Needed for compress_float_constant since all fp constants
3688 are LEGITIMATE_CONSTANT_P. */
3689 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3691 if (standard_80387_constant_p (operands[1]) > 0)
3693 operands[1] = simplify_const_unary_operation
3694 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3695 emit_move_insn_1 (operands[0], operands[1]);
3698 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3702 (define_insn "*extendsfxf2_i387"
3703 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3704 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3707 switch (which_alternative)
3710 return output_387_reg_move (insn, operands);
3713 /* There is no non-popping store to memory for XFmode. So if
3714 we need one, follow the store with a load. */
3715 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3716 return "fstp%z0\t%y0";
3718 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3724 [(set_attr "type" "fmov")
3725 (set_attr "mode" "SF,XF")])
3727 (define_expand "extenddfxf2"
3728 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3729 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3732 /* ??? Needed for compress_float_constant since all fp constants
3733 are LEGITIMATE_CONSTANT_P. */
3734 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3736 if (standard_80387_constant_p (operands[1]) > 0)
3738 operands[1] = simplify_const_unary_operation
3739 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3740 emit_move_insn_1 (operands[0], operands[1]);
3743 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3747 (define_insn "*extenddfxf2_i387"
3748 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3749 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3752 switch (which_alternative)
3755 return output_387_reg_move (insn, operands);
3758 /* There is no non-popping store to memory for XFmode. So if
3759 we need one, follow the store with a load. */
3760 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3761 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3763 return "fstp%z0\t%y0";
3769 [(set_attr "type" "fmov")
3770 (set_attr "mode" "DF,XF")])
3772 ;; %%% This seems bad bad news.
3773 ;; This cannot output into an f-reg because there is no way to be sure
3774 ;; of truncating in that case. Otherwise this is just like a simple move
3775 ;; insn. So we pretend we can output to a reg in order to get better
3776 ;; register preferencing, but we really use a stack slot.
3778 ;; Conversion from DFmode to SFmode.
3780 (define_expand "truncdfsf2"
3781 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3783 (match_operand:DF 1 "nonimmediate_operand" "")))]
3784 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3786 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3788 else if (flag_unsafe_math_optimizations)
3792 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3793 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3798 (define_expand "truncdfsf2_with_temp"
3799 [(parallel [(set (match_operand:SF 0 "" "")
3800 (float_truncate:SF (match_operand:DF 1 "" "")))
3801 (clobber (match_operand:SF 2 "" ""))])]
3804 (define_insn "*truncdfsf_fast_mixed"
3805 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3807 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3808 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3810 switch (which_alternative)
3813 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3814 return "fstp%z0\t%y0";
3816 return "fst%z0\t%y0";
3818 return output_387_reg_move (insn, operands);
3820 return "cvtsd2ss\t{%1, %0|%0, %1}";
3825 [(set_attr "type" "fmov,fmov,ssecvt")
3826 (set_attr "mode" "SF")])
3828 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3829 ;; because nothing we do here is unsafe.
3830 (define_insn "*truncdfsf_fast_sse"
3831 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3833 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3834 "TARGET_SSE2 && TARGET_SSE_MATH"
3835 "cvtsd2ss\t{%1, %0|%0, %1}"
3836 [(set_attr "type" "ssecvt")
3837 (set_attr "mode" "SF")])
3839 (define_insn "*truncdfsf_fast_i387"
3840 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3842 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3843 "TARGET_80387 && flag_unsafe_math_optimizations"
3844 "* return output_387_reg_move (insn, operands);"
3845 [(set_attr "type" "fmov")
3846 (set_attr "mode" "SF")])
3848 (define_insn "*truncdfsf_mixed"
3849 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3851 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3852 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3853 "TARGET_MIX_SSE_I387"
3855 switch (which_alternative)
3858 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3859 return "fstp%z0\t%y0";
3861 return "fst%z0\t%y0";
3865 return "cvtsd2ss\t{%1, %0|%0, %1}";
3870 [(set_attr "type" "fmov,multi,ssecvt")
3871 (set_attr "unit" "*,i387,*")
3872 (set_attr "mode" "SF")])
3874 (define_insn "*truncdfsf_i387"
3875 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3877 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3878 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3881 switch (which_alternative)
3884 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3885 return "fstp%z0\t%y0";
3887 return "fst%z0\t%y0";
3894 [(set_attr "type" "fmov,multi")
3895 (set_attr "unit" "*,i387")
3896 (set_attr "mode" "SF")])
3898 (define_insn "*truncdfsf2_i387_1"
3899 [(set (match_operand:SF 0 "memory_operand" "=m")
3901 (match_operand:DF 1 "register_operand" "f")))]
3903 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3904 && !TARGET_MIX_SSE_I387"
3906 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3907 return "fstp%z0\t%y0";
3909 return "fst%z0\t%y0";
3911 [(set_attr "type" "fmov")
3912 (set_attr "mode" "SF")])
3915 [(set (match_operand:SF 0 "register_operand" "")
3917 (match_operand:DF 1 "fp_register_operand" "")))
3918 (clobber (match_operand 2 "" ""))]
3920 [(set (match_dup 2) (match_dup 1))
3921 (set (match_dup 0) (match_dup 2))]
3923 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3926 ;; Conversion from XFmode to SFmode.
3928 (define_expand "truncxfsf2"
3929 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3931 (match_operand:XF 1 "register_operand" "")))
3932 (clobber (match_dup 2))])]
3935 if (flag_unsafe_math_optimizations)
3937 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3938 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3939 if (reg != operands[0])
3940 emit_move_insn (operands[0], reg);
3944 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3947 (define_insn "*truncxfsf2_mixed"
3948 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3950 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3951 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3954 gcc_assert (!which_alternative);
3955 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3956 return "fstp%z0\t%y0";
3958 return "fst%z0\t%y0";
3960 [(set_attr "type" "fmov,multi,multi,multi")
3961 (set_attr "unit" "*,i387,i387,i387")
3962 (set_attr "mode" "SF")])
3964 (define_insn "truncxfsf2_i387_noop"
3965 [(set (match_operand:SF 0 "register_operand" "=f")
3966 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3967 "TARGET_80387 && flag_unsafe_math_optimizations"
3968 "* return output_387_reg_move (insn, operands);"
3969 [(set_attr "type" "fmov")
3970 (set_attr "mode" "SF")])
3972 (define_insn "*truncxfsf2_i387"
3973 [(set (match_operand:SF 0 "memory_operand" "=m")
3975 (match_operand:XF 1 "register_operand" "f")))]
3978 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3979 return "fstp%z0\t%y0";
3981 return "fst%z0\t%y0";
3983 [(set_attr "type" "fmov")
3984 (set_attr "mode" "SF")])
3987 [(set (match_operand:SF 0 "register_operand" "")
3989 (match_operand:XF 1 "register_operand" "")))
3990 (clobber (match_operand:SF 2 "memory_operand" ""))]
3991 "TARGET_80387 && reload_completed"
3992 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3993 (set (match_dup 0) (match_dup 2))]
3997 [(set (match_operand:SF 0 "memory_operand" "")
3999 (match_operand:XF 1 "register_operand" "")))
4000 (clobber (match_operand:SF 2 "memory_operand" ""))]
4002 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4005 ;; Conversion from XFmode to DFmode.
4007 (define_expand "truncxfdf2"
4008 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4010 (match_operand:XF 1 "register_operand" "")))
4011 (clobber (match_dup 2))])]
4014 if (flag_unsafe_math_optimizations)
4016 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4017 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4018 if (reg != operands[0])
4019 emit_move_insn (operands[0], reg);
4023 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4026 (define_insn "*truncxfdf2_mixed"
4027 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4029 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4030 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4033 gcc_assert (!which_alternative);
4034 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4035 return "fstp%z0\t%y0";
4037 return "fst%z0\t%y0";
4039 [(set_attr "type" "fmov,multi,multi,multi")
4040 (set_attr "unit" "*,i387,i387,i387")
4041 (set_attr "mode" "DF")])
4043 (define_insn "truncxfdf2_i387_noop"
4044 [(set (match_operand:DF 0 "register_operand" "=f")
4045 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4046 "TARGET_80387 && flag_unsafe_math_optimizations"
4047 "* return output_387_reg_move (insn, operands);"
4048 [(set_attr "type" "fmov")
4049 (set_attr "mode" "DF")])
4051 (define_insn "*truncxfdf2_i387"
4052 [(set (match_operand:DF 0 "memory_operand" "=m")
4054 (match_operand:XF 1 "register_operand" "f")))]
4057 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4058 return "fstp%z0\t%y0";
4060 return "fst%z0\t%y0";
4062 [(set_attr "type" "fmov")
4063 (set_attr "mode" "DF")])
4066 [(set (match_operand:DF 0 "register_operand" "")
4068 (match_operand:XF 1 "register_operand" "")))
4069 (clobber (match_operand:DF 2 "memory_operand" ""))]
4070 "TARGET_80387 && reload_completed"
4071 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4072 (set (match_dup 0) (match_dup 2))]
4076 [(set (match_operand:DF 0 "memory_operand" "")
4078 (match_operand:XF 1 "register_operand" "")))
4079 (clobber (match_operand:DF 2 "memory_operand" ""))]
4081 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4084 ;; Signed conversion to DImode.
4086 (define_expand "fix_truncxfdi2"
4087 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4088 (fix:DI (match_operand:XF 1 "register_operand" "")))
4089 (clobber (reg:CC FLAGS_REG))])]
4094 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4099 (define_expand "fix_trunc<mode>di2"
4100 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4101 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4102 (clobber (reg:CC FLAGS_REG))])]
4103 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4106 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4108 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4111 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4113 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4114 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4115 if (out != operands[0])
4116 emit_move_insn (operands[0], out);
4121 ;; Signed conversion to SImode.
4123 (define_expand "fix_truncxfsi2"
4124 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4125 (fix:SI (match_operand:XF 1 "register_operand" "")))
4126 (clobber (reg:CC FLAGS_REG))])]
4131 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4136 (define_expand "fix_trunc<mode>si2"
4137 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4138 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4139 (clobber (reg:CC FLAGS_REG))])]
4140 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4143 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4145 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4148 if (SSE_FLOAT_MODE_P (<MODE>mode))
4150 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4151 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4152 if (out != operands[0])
4153 emit_move_insn (operands[0], out);
4158 ;; Signed conversion to HImode.
4160 (define_expand "fix_trunc<mode>hi2"
4161 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4162 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4163 (clobber (reg:CC FLAGS_REG))])]
4165 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4169 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4174 ;; When SSE is available, it is always faster to use it!
4175 (define_insn "fix_truncsfdi_sse"
4176 [(set (match_operand:DI 0 "register_operand" "=r,r")
4177 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4178 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4179 "cvttss2si{q}\t{%1, %0|%0, %1}"
4180 [(set_attr "type" "sseicvt")
4181 (set_attr "mode" "SF")
4182 (set_attr "athlon_decode" "double,vector")])
4184 (define_insn "fix_truncdfdi_sse"
4185 [(set (match_operand:DI 0 "register_operand" "=r,r")
4186 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4187 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4188 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4189 [(set_attr "type" "sseicvt")
4190 (set_attr "mode" "DF")
4191 (set_attr "athlon_decode" "double,vector")])
4193 (define_insn "fix_truncsfsi_sse"
4194 [(set (match_operand:SI 0 "register_operand" "=r,r")
4195 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4196 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4197 "cvttss2si\t{%1, %0|%0, %1}"
4198 [(set_attr "type" "sseicvt")
4199 (set_attr "mode" "DF")
4200 (set_attr "athlon_decode" "double,vector")])
4202 (define_insn "fix_truncdfsi_sse"
4203 [(set (match_operand:SI 0 "register_operand" "=r,r")
4204 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4205 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4206 "cvttsd2si\t{%1, %0|%0, %1}"
4207 [(set_attr "type" "sseicvt")
4208 (set_attr "mode" "DF")
4209 (set_attr "athlon_decode" "double,vector")])
4211 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4213 [(set (match_operand:DF 0 "register_operand" "")
4214 (match_operand:DF 1 "memory_operand" ""))
4215 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4216 (fix:SSEMODEI24 (match_dup 0)))]
4218 && peep2_reg_dead_p (2, operands[0])"
4219 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4223 [(set (match_operand:SF 0 "register_operand" "")
4224 (match_operand:SF 1 "memory_operand" ""))
4225 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4226 (fix:SSEMODEI24 (match_dup 0)))]
4228 && peep2_reg_dead_p (2, operands[0])"
4229 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4232 ;; Avoid vector decoded forms of the instruction.
4234 [(match_scratch:DF 2 "Y")
4235 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4236 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4237 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4238 [(set (match_dup 2) (match_dup 1))
4239 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4243 [(match_scratch:SF 2 "x")
4244 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4245 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4246 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4247 [(set (match_dup 2) (match_dup 1))
4248 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4251 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4252 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4253 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4255 && FLOAT_MODE_P (GET_MODE (operands[1]))
4256 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4257 && (TARGET_64BIT || <MODE>mode != DImode))
4259 && !(reload_completed || reload_in_progress)"
4264 if (memory_operand (operands[0], VOIDmode))
4265 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4268 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4269 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4275 [(set_attr "type" "fisttp")
4276 (set_attr "mode" "<MODE>")])
4278 (define_insn "fix_trunc<mode>_i387_fisttp"
4279 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4280 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4281 (clobber (match_scratch:XF 2 "=&1f"))]
4283 && FLOAT_MODE_P (GET_MODE (operands[1]))
4284 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4285 && (TARGET_64BIT || <MODE>mode != DImode))
4286 && TARGET_SSE_MATH)"
4287 "* return output_fix_trunc (insn, operands, 1);"
4288 [(set_attr "type" "fisttp")
4289 (set_attr "mode" "<MODE>")])
4291 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4292 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4293 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4294 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4295 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4297 && FLOAT_MODE_P (GET_MODE (operands[1]))
4298 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4299 && (TARGET_64BIT || <MODE>mode != DImode))
4300 && TARGET_SSE_MATH)"
4302 [(set_attr "type" "fisttp")
4303 (set_attr "mode" "<MODE>")])
4306 [(set (match_operand:X87MODEI 0 "register_operand" "")
4307 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4308 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4309 (clobber (match_scratch 3 ""))]
4311 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4312 (clobber (match_dup 3))])
4313 (set (match_dup 0) (match_dup 2))]
4317 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4318 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4319 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4320 (clobber (match_scratch 3 ""))]
4322 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4323 (clobber (match_dup 3))])]
4326 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4327 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4328 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4329 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4330 ;; function in i386.c.
4331 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4332 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4333 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4334 (clobber (reg:CC FLAGS_REG))]
4335 "TARGET_80387 && !TARGET_FISTTP
4336 && FLOAT_MODE_P (GET_MODE (operands[1]))
4337 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4338 && (TARGET_64BIT || <MODE>mode != DImode))
4339 && !(reload_completed || reload_in_progress)"
4344 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4346 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4347 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4348 if (memory_operand (operands[0], VOIDmode))
4349 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4350 operands[2], operands[3]));
4353 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4354 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4355 operands[2], operands[3],
4360 [(set_attr "type" "fistp")
4361 (set_attr "i387_cw" "trunc")
4362 (set_attr "mode" "<MODE>")])
4364 (define_insn "fix_truncdi_i387"
4365 [(set (match_operand:DI 0 "memory_operand" "=m")
4366 (fix:DI (match_operand 1 "register_operand" "f")))
4367 (use (match_operand:HI 2 "memory_operand" "m"))
4368 (use (match_operand:HI 3 "memory_operand" "m"))
4369 (clobber (match_scratch:XF 4 "=&1f"))]
4370 "TARGET_80387 && !TARGET_FISTTP
4371 && FLOAT_MODE_P (GET_MODE (operands[1]))
4372 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4373 "* return output_fix_trunc (insn, operands, 0);"
4374 [(set_attr "type" "fistp")
4375 (set_attr "i387_cw" "trunc")
4376 (set_attr "mode" "DI")])
4378 (define_insn "fix_truncdi_i387_with_temp"
4379 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4380 (fix:DI (match_operand 1 "register_operand" "f,f")))
4381 (use (match_operand:HI 2 "memory_operand" "m,m"))
4382 (use (match_operand:HI 3 "memory_operand" "m,m"))
4383 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4384 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4385 "TARGET_80387 && !TARGET_FISTTP
4386 && FLOAT_MODE_P (GET_MODE (operands[1]))
4387 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4389 [(set_attr "type" "fistp")
4390 (set_attr "i387_cw" "trunc")
4391 (set_attr "mode" "DI")])
4394 [(set (match_operand:DI 0 "register_operand" "")
4395 (fix:DI (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:DI 4 "memory_operand" ""))
4399 (clobber (match_scratch 5 ""))]
4401 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4404 (clobber (match_dup 5))])
4405 (set (match_dup 0) (match_dup 4))]
4409 [(set (match_operand:DI 0 "memory_operand" "")
4410 (fix:DI (match_operand 1 "register_operand" "")))
4411 (use (match_operand:HI 2 "memory_operand" ""))
4412 (use (match_operand:HI 3 "memory_operand" ""))
4413 (clobber (match_operand:DI 4 "memory_operand" ""))
4414 (clobber (match_scratch 5 ""))]
4416 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4419 (clobber (match_dup 5))])]
4422 (define_insn "fix_trunc<mode>_i387"
4423 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4424 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4425 (use (match_operand:HI 2 "memory_operand" "m"))
4426 (use (match_operand:HI 3 "memory_operand" "m"))]
4427 "TARGET_80387 && !TARGET_FISTTP
4428 && FLOAT_MODE_P (GET_MODE (operands[1]))
4429 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4430 "* return output_fix_trunc (insn, operands, 0);"
4431 [(set_attr "type" "fistp")
4432 (set_attr "i387_cw" "trunc")
4433 (set_attr "mode" "<MODE>")])
4435 (define_insn "fix_trunc<mode>_i387_with_temp"
4436 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4437 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4438 (use (match_operand:HI 2 "memory_operand" "m,m"))
4439 (use (match_operand:HI 3 "memory_operand" "m,m"))
4440 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4441 "TARGET_80387 && !TARGET_FISTTP
4442 && FLOAT_MODE_P (GET_MODE (operands[1]))
4443 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4445 [(set_attr "type" "fistp")
4446 (set_attr "i387_cw" "trunc")
4447 (set_attr "mode" "<MODE>")])
4450 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4451 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4452 (use (match_operand:HI 2 "memory_operand" ""))
4453 (use (match_operand:HI 3 "memory_operand" ""))
4454 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4456 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4458 (use (match_dup 3))])
4459 (set (match_dup 0) (match_dup 4))]
4463 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4464 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4465 (use (match_operand:HI 2 "memory_operand" ""))
4466 (use (match_operand:HI 3 "memory_operand" ""))
4467 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4469 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4471 (use (match_dup 3))])]
4474 (define_insn "x86_fnstcw_1"
4475 [(set (match_operand:HI 0 "memory_operand" "=m")
4476 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4479 [(set_attr "length" "2")
4480 (set_attr "mode" "HI")
4481 (set_attr "unit" "i387")])
4483 (define_insn "x86_fldcw_1"
4484 [(set (reg:HI FPCR_REG)
4485 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4488 [(set_attr "length" "2")
4489 (set_attr "mode" "HI")
4490 (set_attr "unit" "i387")
4491 (set_attr "athlon_decode" "vector")])
4493 ;; Conversion between fixed point and floating point.
4495 ;; Even though we only accept memory inputs, the backend _really_
4496 ;; wants to be able to do this between registers.
4498 (define_expand "floathisf2"
4499 [(set (match_operand:SF 0 "register_operand" "")
4500 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4501 "TARGET_80387 || TARGET_SSE_MATH"
4503 if (TARGET_SSE_MATH)
4505 emit_insn (gen_floatsisf2 (operands[0],
4506 convert_to_mode (SImode, operands[1], 0)));
4511 (define_insn "*floathisf2_i387"
4512 [(set (match_operand:SF 0 "register_operand" "=f,f")
4513 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4514 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4518 [(set_attr "type" "fmov,multi")
4519 (set_attr "mode" "SF")
4520 (set_attr "unit" "*,i387")
4521 (set_attr "fp_int_src" "true")])
4523 (define_expand "floatsisf2"
4524 [(set (match_operand:SF 0 "register_operand" "")
4525 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4526 "TARGET_80387 || TARGET_SSE_MATH"
4529 (define_insn "*floatsisf2_mixed"
4530 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4531 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4532 "TARGET_MIX_SSE_I387"
4536 cvtsi2ss\t{%1, %0|%0, %1}
4537 cvtsi2ss\t{%1, %0|%0, %1}"
4538 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4539 (set_attr "mode" "SF")
4540 (set_attr "unit" "*,i387,*,*")
4541 (set_attr "athlon_decode" "*,*,vector,double")
4542 (set_attr "fp_int_src" "true")])
4544 (define_insn "*floatsisf2_sse"
4545 [(set (match_operand:SF 0 "register_operand" "=x,x")
4546 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4548 "cvtsi2ss\t{%1, %0|%0, %1}"
4549 [(set_attr "type" "sseicvt")
4550 (set_attr "mode" "SF")
4551 (set_attr "athlon_decode" "vector,double")
4552 (set_attr "fp_int_src" "true")])
4554 (define_insn "*floatsisf2_i387"
4555 [(set (match_operand:SF 0 "register_operand" "=f,f")
4556 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4561 [(set_attr "type" "fmov,multi")
4562 (set_attr "mode" "SF")
4563 (set_attr "unit" "*,i387")
4564 (set_attr "fp_int_src" "true")])
4566 (define_expand "floatdisf2"
4567 [(set (match_operand:SF 0 "register_operand" "")
4568 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4569 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4572 (define_insn "*floatdisf2_mixed"
4573 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4574 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4575 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4579 cvtsi2ss{q}\t{%1, %0|%0, %1}
4580 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4581 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4582 (set_attr "mode" "SF")
4583 (set_attr "unit" "*,i387,*,*")
4584 (set_attr "athlon_decode" "*,*,vector,double")
4585 (set_attr "fp_int_src" "true")])
4587 (define_insn "*floatdisf2_sse"
4588 [(set (match_operand:SF 0 "register_operand" "=x,x")
4589 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4590 "TARGET_64BIT && TARGET_SSE_MATH"
4591 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4592 [(set_attr "type" "sseicvt")
4593 (set_attr "mode" "SF")
4594 (set_attr "athlon_decode" "vector,double")
4595 (set_attr "fp_int_src" "true")])
4597 (define_insn "*floatdisf2_i387"
4598 [(set (match_operand:SF 0 "register_operand" "=f,f")
4599 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4604 [(set_attr "type" "fmov,multi")
4605 (set_attr "mode" "SF")
4606 (set_attr "unit" "*,i387")
4607 (set_attr "fp_int_src" "true")])
4609 (define_expand "floathidf2"
4610 [(set (match_operand:DF 0 "register_operand" "")
4611 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4612 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4614 if (TARGET_SSE2 && TARGET_SSE_MATH)
4616 emit_insn (gen_floatsidf2 (operands[0],
4617 convert_to_mode (SImode, operands[1], 0)));
4622 (define_insn "*floathidf2_i387"
4623 [(set (match_operand:DF 0 "register_operand" "=f,f")
4624 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4625 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4629 [(set_attr "type" "fmov,multi")
4630 (set_attr "mode" "DF")
4631 (set_attr "unit" "*,i387")
4632 (set_attr "fp_int_src" "true")])
4634 (define_expand "floatsidf2"
4635 [(set (match_operand:DF 0 "register_operand" "")
4636 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4637 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4640 (define_insn "*floatsidf2_mixed"
4641 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4642 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4643 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4647 cvtsi2sd\t{%1, %0|%0, %1}
4648 cvtsi2sd\t{%1, %0|%0, %1}"
4649 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4650 (set_attr "mode" "DF")
4651 (set_attr "unit" "*,i387,*,*")
4652 (set_attr "athlon_decode" "*,*,double,direct")
4653 (set_attr "fp_int_src" "true")])
4655 (define_insn "*floatsidf2_sse"
4656 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4657 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4658 "TARGET_SSE2 && TARGET_SSE_MATH"
4659 "cvtsi2sd\t{%1, %0|%0, %1}"
4660 [(set_attr "type" "sseicvt")
4661 (set_attr "mode" "DF")
4662 (set_attr "athlon_decode" "double,direct")
4663 (set_attr "fp_int_src" "true")])
4665 (define_insn "*floatsidf2_i387"
4666 [(set (match_operand:DF 0 "register_operand" "=f,f")
4667 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4672 [(set_attr "type" "fmov,multi")
4673 (set_attr "mode" "DF")
4674 (set_attr "unit" "*,i387")
4675 (set_attr "fp_int_src" "true")])
4677 (define_expand "floatdidf2"
4678 [(set (match_operand:DF 0 "register_operand" "")
4679 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4680 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4683 (define_insn "*floatdidf2_mixed"
4684 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4685 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4686 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4690 cvtsi2sd{q}\t{%1, %0|%0, %1}
4691 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4692 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4693 (set_attr "mode" "DF")
4694 (set_attr "unit" "*,i387,*,*")
4695 (set_attr "athlon_decode" "*,*,double,direct")
4696 (set_attr "fp_int_src" "true")])
4698 (define_insn "*floatdidf2_sse"
4699 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4700 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4701 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4702 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4703 [(set_attr "type" "sseicvt")
4704 (set_attr "mode" "DF")
4705 (set_attr "athlon_decode" "double,direct")
4706 (set_attr "fp_int_src" "true")])
4708 (define_insn "*floatdidf2_i387"
4709 [(set (match_operand:DF 0 "register_operand" "=f,f")
4710 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4715 [(set_attr "type" "fmov,multi")
4716 (set_attr "mode" "DF")
4717 (set_attr "unit" "*,i387")
4718 (set_attr "fp_int_src" "true")])
4720 (define_insn "floathixf2"
4721 [(set (match_operand:XF 0 "register_operand" "=f,f")
4722 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4727 [(set_attr "type" "fmov,multi")
4728 (set_attr "mode" "XF")
4729 (set_attr "unit" "*,i387")
4730 (set_attr "fp_int_src" "true")])
4732 (define_insn "floatsixf2"
4733 [(set (match_operand:XF 0 "register_operand" "=f,f")
4734 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4739 [(set_attr "type" "fmov,multi")
4740 (set_attr "mode" "XF")
4741 (set_attr "unit" "*,i387")
4742 (set_attr "fp_int_src" "true")])
4744 (define_insn "floatdixf2"
4745 [(set (match_operand:XF 0 "register_operand" "=f,f")
4746 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4751 [(set_attr "type" "fmov,multi")
4752 (set_attr "mode" "XF")
4753 (set_attr "unit" "*,i387")
4754 (set_attr "fp_int_src" "true")])
4756 ;; %%% Kill these when reload knows how to do it.
4758 [(set (match_operand 0 "fp_register_operand" "")
4759 (float (match_operand 1 "register_operand" "")))]
4762 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4765 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4766 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4767 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4768 ix86_free_from_memory (GET_MODE (operands[1]));
4772 (define_expand "floatunssisf2"
4773 [(use (match_operand:SF 0 "register_operand" ""))
4774 (use (match_operand:SI 1 "register_operand" ""))]
4775 "!TARGET_64BIT && TARGET_SSE_MATH"
4776 "x86_emit_floatuns (operands); DONE;")
4778 (define_expand "floatunsdisf2"
4779 [(use (match_operand:SF 0 "register_operand" ""))
4780 (use (match_operand:DI 1 "register_operand" ""))]
4781 "TARGET_64BIT && TARGET_SSE_MATH"
4782 "x86_emit_floatuns (operands); DONE;")
4784 (define_expand "floatunsdidf2"
4785 [(use (match_operand:DF 0 "register_operand" ""))
4786 (use (match_operand:DI 1 "register_operand" ""))]
4787 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4788 "x86_emit_floatuns (operands); DONE;")
4790 ;; SSE extract/set expanders
4795 ;; %%% splits for addditi3
4797 (define_expand "addti3"
4798 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4799 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4800 (match_operand:TI 2 "x86_64_general_operand" "")))
4801 (clobber (reg:CC FLAGS_REG))]
4803 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4805 (define_insn "*addti3_1"
4806 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4807 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4808 (match_operand:TI 2 "general_operand" "roiF,riF")))
4809 (clobber (reg:CC FLAGS_REG))]
4810 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4814 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4815 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4816 (match_operand:TI 2 "general_operand" "")))
4817 (clobber (reg:CC FLAGS_REG))]
4818 "TARGET_64BIT && reload_completed"
4819 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4821 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4822 (parallel [(set (match_dup 3)
4823 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4826 (clobber (reg:CC FLAGS_REG))])]
4827 "split_ti (operands+0, 1, operands+0, operands+3);
4828 split_ti (operands+1, 1, operands+1, operands+4);
4829 split_ti (operands+2, 1, operands+2, operands+5);")
4831 ;; %%% splits for addsidi3
4832 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4833 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4834 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4836 (define_expand "adddi3"
4837 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4838 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4839 (match_operand:DI 2 "x86_64_general_operand" "")))
4840 (clobber (reg:CC FLAGS_REG))]
4842 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4844 (define_insn "*adddi3_1"
4845 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4846 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4847 (match_operand:DI 2 "general_operand" "roiF,riF")))
4848 (clobber (reg:CC FLAGS_REG))]
4849 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4853 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4854 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4855 (match_operand:DI 2 "general_operand" "")))
4856 (clobber (reg:CC FLAGS_REG))]
4857 "!TARGET_64BIT && reload_completed"
4858 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4860 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4861 (parallel [(set (match_dup 3)
4862 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4865 (clobber (reg:CC FLAGS_REG))])]
4866 "split_di (operands+0, 1, operands+0, operands+3);
4867 split_di (operands+1, 1, operands+1, operands+4);
4868 split_di (operands+2, 1, operands+2, operands+5);")
4870 (define_insn "adddi3_carry_rex64"
4871 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4872 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4873 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4874 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4875 (clobber (reg:CC FLAGS_REG))]
4876 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4877 "adc{q}\t{%2, %0|%0, %2}"
4878 [(set_attr "type" "alu")
4879 (set_attr "pent_pair" "pu")
4880 (set_attr "mode" "DI")])
4882 (define_insn "*adddi3_cc_rex64"
4883 [(set (reg:CC FLAGS_REG)
4884 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4885 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4887 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4888 (plus:DI (match_dup 1) (match_dup 2)))]
4889 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4890 "add{q}\t{%2, %0|%0, %2}"
4891 [(set_attr "type" "alu")
4892 (set_attr "mode" "DI")])
4894 (define_insn "addqi3_carry"
4895 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4896 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4897 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4898 (match_operand:QI 2 "general_operand" "qi,qm")))
4899 (clobber (reg:CC FLAGS_REG))]
4900 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4901 "adc{b}\t{%2, %0|%0, %2}"
4902 [(set_attr "type" "alu")
4903 (set_attr "pent_pair" "pu")
4904 (set_attr "mode" "QI")])
4906 (define_insn "addhi3_carry"
4907 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4908 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4909 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4910 (match_operand:HI 2 "general_operand" "ri,rm")))
4911 (clobber (reg:CC FLAGS_REG))]
4912 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4913 "adc{w}\t{%2, %0|%0, %2}"
4914 [(set_attr "type" "alu")
4915 (set_attr "pent_pair" "pu")
4916 (set_attr "mode" "HI")])
4918 (define_insn "addsi3_carry"
4919 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4920 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4921 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4922 (match_operand:SI 2 "general_operand" "ri,rm")))
4923 (clobber (reg:CC FLAGS_REG))]
4924 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4925 "adc{l}\t{%2, %0|%0, %2}"
4926 [(set_attr "type" "alu")
4927 (set_attr "pent_pair" "pu")
4928 (set_attr "mode" "SI")])
4930 (define_insn "*addsi3_carry_zext"
4931 [(set (match_operand:DI 0 "register_operand" "=r")
4933 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4934 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4935 (match_operand:SI 2 "general_operand" "rim"))))
4936 (clobber (reg:CC FLAGS_REG))]
4937 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4938 "adc{l}\t{%2, %k0|%k0, %2}"
4939 [(set_attr "type" "alu")
4940 (set_attr "pent_pair" "pu")
4941 (set_attr "mode" "SI")])
4943 (define_insn "*addsi3_cc"
4944 [(set (reg:CC FLAGS_REG)
4945 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4946 (match_operand:SI 2 "general_operand" "ri,rm")]
4948 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4949 (plus:SI (match_dup 1) (match_dup 2)))]
4950 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4951 "add{l}\t{%2, %0|%0, %2}"
4952 [(set_attr "type" "alu")
4953 (set_attr "mode" "SI")])
4955 (define_insn "addqi3_cc"
4956 [(set (reg:CC FLAGS_REG)
4957 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4958 (match_operand:QI 2 "general_operand" "qi,qm")]
4960 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4961 (plus:QI (match_dup 1) (match_dup 2)))]
4962 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4963 "add{b}\t{%2, %0|%0, %2}"
4964 [(set_attr "type" "alu")
4965 (set_attr "mode" "QI")])
4967 (define_expand "addsi3"
4968 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4969 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4970 (match_operand:SI 2 "general_operand" "")))
4971 (clobber (reg:CC FLAGS_REG))])]
4973 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4975 (define_insn "*lea_1"
4976 [(set (match_operand:SI 0 "register_operand" "=r")
4977 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4979 "lea{l}\t{%a1, %0|%0, %a1}"
4980 [(set_attr "type" "lea")
4981 (set_attr "mode" "SI")])
4983 (define_insn "*lea_1_rex64"
4984 [(set (match_operand:SI 0 "register_operand" "=r")
4985 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4987 "lea{l}\t{%a1, %0|%0, %a1}"
4988 [(set_attr "type" "lea")
4989 (set_attr "mode" "SI")])
4991 (define_insn "*lea_1_zext"
4992 [(set (match_operand:DI 0 "register_operand" "=r")
4994 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4996 "lea{l}\t{%a1, %k0|%k0, %a1}"
4997 [(set_attr "type" "lea")
4998 (set_attr "mode" "SI")])
5000 (define_insn "*lea_2_rex64"
5001 [(set (match_operand:DI 0 "register_operand" "=r")
5002 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5004 "lea{q}\t{%a1, %0|%0, %a1}"
5005 [(set_attr "type" "lea")
5006 (set_attr "mode" "DI")])
5008 ;; The lea patterns for non-Pmodes needs to be matched by several
5009 ;; insns converted to real lea by splitters.
5011 (define_insn_and_split "*lea_general_1"
5012 [(set (match_operand 0 "register_operand" "=r")
5013 (plus (plus (match_operand 1 "index_register_operand" "l")
5014 (match_operand 2 "register_operand" "r"))
5015 (match_operand 3 "immediate_operand" "i")))]
5016 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5017 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5018 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5019 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5020 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5021 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5022 || GET_MODE (operands[3]) == VOIDmode)"
5024 "&& reload_completed"
5028 operands[0] = gen_lowpart (SImode, operands[0]);
5029 operands[1] = gen_lowpart (Pmode, operands[1]);
5030 operands[2] = gen_lowpart (Pmode, operands[2]);
5031 operands[3] = gen_lowpart (Pmode, operands[3]);
5032 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5034 if (Pmode != SImode)
5035 pat = gen_rtx_SUBREG (SImode, pat, 0);
5036 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5039 [(set_attr "type" "lea")
5040 (set_attr "mode" "SI")])
5042 (define_insn_and_split "*lea_general_1_zext"
5043 [(set (match_operand:DI 0 "register_operand" "=r")
5045 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5046 (match_operand:SI 2 "register_operand" "r"))
5047 (match_operand:SI 3 "immediate_operand" "i"))))]
5050 "&& reload_completed"
5052 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5054 (match_dup 3)) 0)))]
5056 operands[1] = gen_lowpart (Pmode, operands[1]);
5057 operands[2] = gen_lowpart (Pmode, operands[2]);
5058 operands[3] = gen_lowpart (Pmode, operands[3]);
5060 [(set_attr "type" "lea")
5061 (set_attr "mode" "SI")])
5063 (define_insn_and_split "*lea_general_2"
5064 [(set (match_operand 0 "register_operand" "=r")
5065 (plus (mult (match_operand 1 "index_register_operand" "l")
5066 (match_operand 2 "const248_operand" "i"))
5067 (match_operand 3 "nonmemory_operand" "ri")))]
5068 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5069 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5070 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5071 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5072 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5073 || GET_MODE (operands[3]) == VOIDmode)"
5075 "&& reload_completed"
5079 operands[0] = gen_lowpart (SImode, operands[0]);
5080 operands[1] = gen_lowpart (Pmode, operands[1]);
5081 operands[3] = gen_lowpart (Pmode, operands[3]);
5082 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5084 if (Pmode != SImode)
5085 pat = gen_rtx_SUBREG (SImode, pat, 0);
5086 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5089 [(set_attr "type" "lea")
5090 (set_attr "mode" "SI")])
5092 (define_insn_and_split "*lea_general_2_zext"
5093 [(set (match_operand:DI 0 "register_operand" "=r")
5095 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5096 (match_operand:SI 2 "const248_operand" "n"))
5097 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5100 "&& reload_completed"
5102 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5104 (match_dup 3)) 0)))]
5106 operands[1] = gen_lowpart (Pmode, operands[1]);
5107 operands[3] = gen_lowpart (Pmode, operands[3]);
5109 [(set_attr "type" "lea")
5110 (set_attr "mode" "SI")])
5112 (define_insn_and_split "*lea_general_3"
5113 [(set (match_operand 0 "register_operand" "=r")
5114 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5115 (match_operand 2 "const248_operand" "i"))
5116 (match_operand 3 "register_operand" "r"))
5117 (match_operand 4 "immediate_operand" "i")))]
5118 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5119 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5120 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5121 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5122 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5124 "&& reload_completed"
5128 operands[0] = gen_lowpart (SImode, operands[0]);
5129 operands[1] = gen_lowpart (Pmode, operands[1]);
5130 operands[3] = gen_lowpart (Pmode, operands[3]);
5131 operands[4] = gen_lowpart (Pmode, operands[4]);
5132 pat = gen_rtx_PLUS (Pmode,
5133 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5137 if (Pmode != SImode)
5138 pat = gen_rtx_SUBREG (SImode, pat, 0);
5139 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5142 [(set_attr "type" "lea")
5143 (set_attr "mode" "SI")])
5145 (define_insn_and_split "*lea_general_3_zext"
5146 [(set (match_operand:DI 0 "register_operand" "=r")
5148 (plus:SI (plus:SI (mult:SI
5149 (match_operand:SI 1 "index_register_operand" "l")
5150 (match_operand:SI 2 "const248_operand" "n"))
5151 (match_operand:SI 3 "register_operand" "r"))
5152 (match_operand:SI 4 "immediate_operand" "i"))))]
5155 "&& reload_completed"
5157 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5160 (match_dup 4)) 0)))]
5162 operands[1] = gen_lowpart (Pmode, operands[1]);
5163 operands[3] = gen_lowpart (Pmode, operands[3]);
5164 operands[4] = gen_lowpart (Pmode, operands[4]);
5166 [(set_attr "type" "lea")
5167 (set_attr "mode" "SI")])
5169 (define_insn "*adddi_1_rex64"
5170 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5171 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5172 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5173 (clobber (reg:CC FLAGS_REG))]
5174 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5176 switch (get_attr_type (insn))
5179 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5180 return "lea{q}\t{%a2, %0|%0, %a2}";
5183 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5184 if (operands[2] == const1_rtx)
5185 return "inc{q}\t%0";
5188 gcc_assert (operands[2] == constm1_rtx);
5189 return "dec{q}\t%0";
5193 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5195 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5196 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5197 if (CONST_INT_P (operands[2])
5198 /* Avoid overflows. */
5199 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5200 && (INTVAL (operands[2]) == 128
5201 || (INTVAL (operands[2]) < 0
5202 && INTVAL (operands[2]) != -128)))
5204 operands[2] = GEN_INT (-INTVAL (operands[2]));
5205 return "sub{q}\t{%2, %0|%0, %2}";
5207 return "add{q}\t{%2, %0|%0, %2}";
5211 (cond [(eq_attr "alternative" "2")
5212 (const_string "lea")
5213 ; Current assemblers are broken and do not allow @GOTOFF in
5214 ; ought but a memory context.
5215 (match_operand:DI 2 "pic_symbolic_operand" "")
5216 (const_string "lea")
5217 (match_operand:DI 2 "incdec_operand" "")
5218 (const_string "incdec")
5220 (const_string "alu")))
5221 (set_attr "mode" "DI")])
5223 ;; Convert lea to the lea pattern to avoid flags dependency.
5225 [(set (match_operand:DI 0 "register_operand" "")
5226 (plus:DI (match_operand:DI 1 "register_operand" "")
5227 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5228 (clobber (reg:CC FLAGS_REG))]
5229 "TARGET_64BIT && reload_completed
5230 && true_regnum (operands[0]) != true_regnum (operands[1])"
5232 (plus:DI (match_dup 1)
5236 (define_insn "*adddi_2_rex64"
5237 [(set (reg FLAGS_REG)
5239 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5240 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5242 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5243 (plus:DI (match_dup 1) (match_dup 2)))]
5244 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5245 && ix86_binary_operator_ok (PLUS, DImode, operands)
5246 /* Current assemblers are broken and do not allow @GOTOFF in
5247 ought but a memory context. */
5248 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5250 switch (get_attr_type (insn))
5253 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5254 if (operands[2] == const1_rtx)
5255 return "inc{q}\t%0";
5258 gcc_assert (operands[2] == constm1_rtx);
5259 return "dec{q}\t%0";
5263 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5264 /* ???? We ought to handle there the 32bit case too
5265 - do we need new constraint? */
5266 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5267 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5268 if (CONST_INT_P (operands[2])
5269 /* Avoid overflows. */
5270 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5271 && (INTVAL (operands[2]) == 128
5272 || (INTVAL (operands[2]) < 0
5273 && INTVAL (operands[2]) != -128)))
5275 operands[2] = GEN_INT (-INTVAL (operands[2]));
5276 return "sub{q}\t{%2, %0|%0, %2}";
5278 return "add{q}\t{%2, %0|%0, %2}";
5282 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5283 (const_string "incdec")
5284 (const_string "alu")))
5285 (set_attr "mode" "DI")])
5287 (define_insn "*adddi_3_rex64"
5288 [(set (reg FLAGS_REG)
5289 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5290 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5291 (clobber (match_scratch:DI 0 "=r"))]
5293 && ix86_match_ccmode (insn, CCZmode)
5294 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5295 /* Current assemblers are broken and do not allow @GOTOFF in
5296 ought but a memory context. */
5297 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5299 switch (get_attr_type (insn))
5302 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5303 if (operands[2] == const1_rtx)
5304 return "inc{q}\t%0";
5307 gcc_assert (operands[2] == constm1_rtx);
5308 return "dec{q}\t%0";
5312 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5313 /* ???? We ought to handle there the 32bit case too
5314 - do we need new constraint? */
5315 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5316 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5317 if (CONST_INT_P (operands[2])
5318 /* Avoid overflows. */
5319 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5320 && (INTVAL (operands[2]) == 128
5321 || (INTVAL (operands[2]) < 0
5322 && INTVAL (operands[2]) != -128)))
5324 operands[2] = GEN_INT (-INTVAL (operands[2]));
5325 return "sub{q}\t{%2, %0|%0, %2}";
5327 return "add{q}\t{%2, %0|%0, %2}";
5331 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5332 (const_string "incdec")
5333 (const_string "alu")))
5334 (set_attr "mode" "DI")])
5336 ; For comparisons against 1, -1 and 128, we may generate better code
5337 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5338 ; is matched then. We can't accept general immediate, because for
5339 ; case of overflows, the result is messed up.
5340 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5342 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5343 ; only for comparisons not depending on it.
5344 (define_insn "*adddi_4_rex64"
5345 [(set (reg FLAGS_REG)
5346 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5347 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5348 (clobber (match_scratch:DI 0 "=rm"))]
5350 && ix86_match_ccmode (insn, CCGCmode)"
5352 switch (get_attr_type (insn))
5355 if (operands[2] == constm1_rtx)
5356 return "inc{q}\t%0";
5359 gcc_assert (operands[2] == const1_rtx);
5360 return "dec{q}\t%0";
5364 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5365 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5366 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5367 if ((INTVAL (operands[2]) == -128
5368 || (INTVAL (operands[2]) > 0
5369 && INTVAL (operands[2]) != 128))
5370 /* Avoid overflows. */
5371 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5372 return "sub{q}\t{%2, %0|%0, %2}";
5373 operands[2] = GEN_INT (-INTVAL (operands[2]));
5374 return "add{q}\t{%2, %0|%0, %2}";
5378 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5379 (const_string "incdec")
5380 (const_string "alu")))
5381 (set_attr "mode" "DI")])
5383 (define_insn "*adddi_5_rex64"
5384 [(set (reg FLAGS_REG)
5386 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5387 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5389 (clobber (match_scratch:DI 0 "=r"))]
5391 && ix86_match_ccmode (insn, CCGOCmode)
5392 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5393 /* Current assemblers are broken and do not allow @GOTOFF in
5394 ought but a memory context. */
5395 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5397 switch (get_attr_type (insn))
5400 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5401 if (operands[2] == const1_rtx)
5402 return "inc{q}\t%0";
5405 gcc_assert (operands[2] == constm1_rtx);
5406 return "dec{q}\t%0";
5410 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5411 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5412 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5413 if (CONST_INT_P (operands[2])
5414 /* Avoid overflows. */
5415 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5416 && (INTVAL (operands[2]) == 128
5417 || (INTVAL (operands[2]) < 0
5418 && INTVAL (operands[2]) != -128)))
5420 operands[2] = GEN_INT (-INTVAL (operands[2]));
5421 return "sub{q}\t{%2, %0|%0, %2}";
5423 return "add{q}\t{%2, %0|%0, %2}";
5427 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5428 (const_string "incdec")
5429 (const_string "alu")))
5430 (set_attr "mode" "DI")])
5433 (define_insn "*addsi_1"
5434 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5435 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5436 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5437 (clobber (reg:CC FLAGS_REG))]
5438 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5440 switch (get_attr_type (insn))
5443 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5444 return "lea{l}\t{%a2, %0|%0, %a2}";
5447 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5448 if (operands[2] == const1_rtx)
5449 return "inc{l}\t%0";
5452 gcc_assert (operands[2] == constm1_rtx);
5453 return "dec{l}\t%0";
5457 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5459 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5460 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5461 if (CONST_INT_P (operands[2])
5462 && (INTVAL (operands[2]) == 128
5463 || (INTVAL (operands[2]) < 0
5464 && INTVAL (operands[2]) != -128)))
5466 operands[2] = GEN_INT (-INTVAL (operands[2]));
5467 return "sub{l}\t{%2, %0|%0, %2}";
5469 return "add{l}\t{%2, %0|%0, %2}";
5473 (cond [(eq_attr "alternative" "2")
5474 (const_string "lea")
5475 ; Current assemblers are broken and do not allow @GOTOFF in
5476 ; ought but a memory context.
5477 (match_operand:SI 2 "pic_symbolic_operand" "")
5478 (const_string "lea")
5479 (match_operand:SI 2 "incdec_operand" "")
5480 (const_string "incdec")
5482 (const_string "alu")))
5483 (set_attr "mode" "SI")])
5485 ;; Convert lea to the lea pattern to avoid flags dependency.
5487 [(set (match_operand 0 "register_operand" "")
5488 (plus (match_operand 1 "register_operand" "")
5489 (match_operand 2 "nonmemory_operand" "")))
5490 (clobber (reg:CC FLAGS_REG))]
5492 && true_regnum (operands[0]) != true_regnum (operands[1])"
5496 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5497 may confuse gen_lowpart. */
5498 if (GET_MODE (operands[0]) != Pmode)
5500 operands[1] = gen_lowpart (Pmode, operands[1]);
5501 operands[2] = gen_lowpart (Pmode, operands[2]);
5503 operands[0] = gen_lowpart (SImode, operands[0]);
5504 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5505 if (Pmode != SImode)
5506 pat = gen_rtx_SUBREG (SImode, pat, 0);
5507 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5511 ;; It may seem that nonimmediate operand is proper one for operand 1.
5512 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5513 ;; we take care in ix86_binary_operator_ok to not allow two memory
5514 ;; operands so proper swapping will be done in reload. This allow
5515 ;; patterns constructed from addsi_1 to match.
5516 (define_insn "addsi_1_zext"
5517 [(set (match_operand:DI 0 "register_operand" "=r,r")
5519 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5520 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5521 (clobber (reg:CC FLAGS_REG))]
5522 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5524 switch (get_attr_type (insn))
5527 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5528 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5531 if (operands[2] == const1_rtx)
5532 return "inc{l}\t%k0";
5535 gcc_assert (operands[2] == constm1_rtx);
5536 return "dec{l}\t%k0";
5540 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5541 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5542 if (CONST_INT_P (operands[2])
5543 && (INTVAL (operands[2]) == 128
5544 || (INTVAL (operands[2]) < 0
5545 && INTVAL (operands[2]) != -128)))
5547 operands[2] = GEN_INT (-INTVAL (operands[2]));
5548 return "sub{l}\t{%2, %k0|%k0, %2}";
5550 return "add{l}\t{%2, %k0|%k0, %2}";
5554 (cond [(eq_attr "alternative" "1")
5555 (const_string "lea")
5556 ; Current assemblers are broken and do not allow @GOTOFF in
5557 ; ought but a memory context.
5558 (match_operand:SI 2 "pic_symbolic_operand" "")
5559 (const_string "lea")
5560 (match_operand:SI 2 "incdec_operand" "")
5561 (const_string "incdec")
5563 (const_string "alu")))
5564 (set_attr "mode" "SI")])
5566 ;; Convert lea to the lea pattern to avoid flags dependency.
5568 [(set (match_operand:DI 0 "register_operand" "")
5570 (plus:SI (match_operand:SI 1 "register_operand" "")
5571 (match_operand:SI 2 "nonmemory_operand" ""))))
5572 (clobber (reg:CC FLAGS_REG))]
5573 "TARGET_64BIT && reload_completed
5574 && true_regnum (operands[0]) != true_regnum (operands[1])"
5576 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5578 operands[1] = gen_lowpart (Pmode, operands[1]);
5579 operands[2] = gen_lowpart (Pmode, operands[2]);
5582 (define_insn "*addsi_2"
5583 [(set (reg FLAGS_REG)
5585 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5586 (match_operand:SI 2 "general_operand" "rmni,rni"))
5588 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5589 (plus:SI (match_dup 1) (match_dup 2)))]
5590 "ix86_match_ccmode (insn, CCGOCmode)
5591 && ix86_binary_operator_ok (PLUS, SImode, operands)
5592 /* Current assemblers are broken and do not allow @GOTOFF in
5593 ought but a memory context. */
5594 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5596 switch (get_attr_type (insn))
5599 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5600 if (operands[2] == const1_rtx)
5601 return "inc{l}\t%0";
5604 gcc_assert (operands[2] == constm1_rtx);
5605 return "dec{l}\t%0";
5609 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5610 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5611 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5612 if (CONST_INT_P (operands[2])
5613 && (INTVAL (operands[2]) == 128
5614 || (INTVAL (operands[2]) < 0
5615 && INTVAL (operands[2]) != -128)))
5617 operands[2] = GEN_INT (-INTVAL (operands[2]));
5618 return "sub{l}\t{%2, %0|%0, %2}";
5620 return "add{l}\t{%2, %0|%0, %2}";
5624 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5625 (const_string "incdec")
5626 (const_string "alu")))
5627 (set_attr "mode" "SI")])
5629 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5630 (define_insn "*addsi_2_zext"
5631 [(set (reg FLAGS_REG)
5633 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5634 (match_operand:SI 2 "general_operand" "rmni"))
5636 (set (match_operand:DI 0 "register_operand" "=r")
5637 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5638 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5639 && ix86_binary_operator_ok (PLUS, SImode, operands)
5640 /* Current assemblers are broken and do not allow @GOTOFF in
5641 ought but a memory context. */
5642 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5644 switch (get_attr_type (insn))
5647 if (operands[2] == const1_rtx)
5648 return "inc{l}\t%k0";
5651 gcc_assert (operands[2] == constm1_rtx);
5652 return "dec{l}\t%k0";
5656 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5657 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5658 if (CONST_INT_P (operands[2])
5659 && (INTVAL (operands[2]) == 128
5660 || (INTVAL (operands[2]) < 0
5661 && INTVAL (operands[2]) != -128)))
5663 operands[2] = GEN_INT (-INTVAL (operands[2]));
5664 return "sub{l}\t{%2, %k0|%k0, %2}";
5666 return "add{l}\t{%2, %k0|%k0, %2}";
5670 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5671 (const_string "incdec")
5672 (const_string "alu")))
5673 (set_attr "mode" "SI")])
5675 (define_insn "*addsi_3"
5676 [(set (reg FLAGS_REG)
5677 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5678 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5679 (clobber (match_scratch:SI 0 "=r"))]
5680 "ix86_match_ccmode (insn, CCZmode)
5681 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5682 /* Current assemblers are broken and do not allow @GOTOFF in
5683 ought but a memory context. */
5684 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5686 switch (get_attr_type (insn))
5689 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5690 if (operands[2] == const1_rtx)
5691 return "inc{l}\t%0";
5694 gcc_assert (operands[2] == constm1_rtx);
5695 return "dec{l}\t%0";
5699 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5700 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5701 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5702 if (CONST_INT_P (operands[2])
5703 && (INTVAL (operands[2]) == 128
5704 || (INTVAL (operands[2]) < 0
5705 && INTVAL (operands[2]) != -128)))
5707 operands[2] = GEN_INT (-INTVAL (operands[2]));
5708 return "sub{l}\t{%2, %0|%0, %2}";
5710 return "add{l}\t{%2, %0|%0, %2}";
5714 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5715 (const_string "incdec")
5716 (const_string "alu")))
5717 (set_attr "mode" "SI")])
5719 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5720 (define_insn "*addsi_3_zext"
5721 [(set (reg FLAGS_REG)
5722 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5723 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5724 (set (match_operand:DI 0 "register_operand" "=r")
5725 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5726 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5727 && ix86_binary_operator_ok (PLUS, SImode, operands)
5728 /* Current assemblers are broken and do not allow @GOTOFF in
5729 ought but a memory context. */
5730 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5732 switch (get_attr_type (insn))
5735 if (operands[2] == const1_rtx)
5736 return "inc{l}\t%k0";
5739 gcc_assert (operands[2] == constm1_rtx);
5740 return "dec{l}\t%k0";
5744 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5745 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5746 if (CONST_INT_P (operands[2])
5747 && (INTVAL (operands[2]) == 128
5748 || (INTVAL (operands[2]) < 0
5749 && INTVAL (operands[2]) != -128)))
5751 operands[2] = GEN_INT (-INTVAL (operands[2]));
5752 return "sub{l}\t{%2, %k0|%k0, %2}";
5754 return "add{l}\t{%2, %k0|%k0, %2}";
5758 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5759 (const_string "incdec")
5760 (const_string "alu")))
5761 (set_attr "mode" "SI")])
5763 ; For comparisons against 1, -1 and 128, we may generate better code
5764 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5765 ; is matched then. We can't accept general immediate, because for
5766 ; case of overflows, the result is messed up.
5767 ; This pattern also don't hold of 0x80000000, since the value overflows
5769 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5770 ; only for comparisons not depending on it.
5771 (define_insn "*addsi_4"
5772 [(set (reg FLAGS_REG)
5773 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5774 (match_operand:SI 2 "const_int_operand" "n")))
5775 (clobber (match_scratch:SI 0 "=rm"))]
5776 "ix86_match_ccmode (insn, CCGCmode)
5777 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5779 switch (get_attr_type (insn))
5782 if (operands[2] == constm1_rtx)
5783 return "inc{l}\t%0";
5786 gcc_assert (operands[2] == const1_rtx);
5787 return "dec{l}\t%0";
5791 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5792 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5793 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5794 if ((INTVAL (operands[2]) == -128
5795 || (INTVAL (operands[2]) > 0
5796 && INTVAL (operands[2]) != 128)))
5797 return "sub{l}\t{%2, %0|%0, %2}";
5798 operands[2] = GEN_INT (-INTVAL (operands[2]));
5799 return "add{l}\t{%2, %0|%0, %2}";
5803 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5804 (const_string "incdec")
5805 (const_string "alu")))
5806 (set_attr "mode" "SI")])
5808 (define_insn "*addsi_5"
5809 [(set (reg FLAGS_REG)
5811 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5812 (match_operand:SI 2 "general_operand" "rmni"))
5814 (clobber (match_scratch:SI 0 "=r"))]
5815 "ix86_match_ccmode (insn, CCGOCmode)
5816 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
5817 /* Current assemblers are broken and do not allow @GOTOFF in
5818 ought but a memory context. */
5819 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5821 switch (get_attr_type (insn))
5824 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5825 if (operands[2] == const1_rtx)
5826 return "inc{l}\t%0";
5829 gcc_assert (operands[2] == constm1_rtx);
5830 return "dec{l}\t%0";
5834 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5835 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5836 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5837 if (CONST_INT_P (operands[2])
5838 && (INTVAL (operands[2]) == 128
5839 || (INTVAL (operands[2]) < 0
5840 && INTVAL (operands[2]) != -128)))
5842 operands[2] = GEN_INT (-INTVAL (operands[2]));
5843 return "sub{l}\t{%2, %0|%0, %2}";
5845 return "add{l}\t{%2, %0|%0, %2}";
5849 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5850 (const_string "incdec")
5851 (const_string "alu")))
5852 (set_attr "mode" "SI")])
5854 (define_expand "addhi3"
5855 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5856 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5857 (match_operand:HI 2 "general_operand" "")))
5858 (clobber (reg:CC FLAGS_REG))])]
5859 "TARGET_HIMODE_MATH"
5860 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5862 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5863 ;; type optimizations enabled by define-splits. This is not important
5864 ;; for PII, and in fact harmful because of partial register stalls.
5866 (define_insn "*addhi_1_lea"
5867 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5868 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5869 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5870 (clobber (reg:CC FLAGS_REG))]
5871 "!TARGET_PARTIAL_REG_STALL
5872 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5874 switch (get_attr_type (insn))
5879 if (operands[2] == const1_rtx)
5880 return "inc{w}\t%0";
5883 gcc_assert (operands[2] == constm1_rtx);
5884 return "dec{w}\t%0";
5888 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5889 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5890 if (CONST_INT_P (operands[2])
5891 && (INTVAL (operands[2]) == 128
5892 || (INTVAL (operands[2]) < 0
5893 && INTVAL (operands[2]) != -128)))
5895 operands[2] = GEN_INT (-INTVAL (operands[2]));
5896 return "sub{w}\t{%2, %0|%0, %2}";
5898 return "add{w}\t{%2, %0|%0, %2}";
5902 (if_then_else (eq_attr "alternative" "2")
5903 (const_string "lea")
5904 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5905 (const_string "incdec")
5906 (const_string "alu"))))
5907 (set_attr "mode" "HI,HI,SI")])
5909 (define_insn "*addhi_1"
5910 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5911 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5912 (match_operand:HI 2 "general_operand" "ri,rm")))
5913 (clobber (reg:CC FLAGS_REG))]
5914 "TARGET_PARTIAL_REG_STALL
5915 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5917 switch (get_attr_type (insn))
5920 if (operands[2] == const1_rtx)
5921 return "inc{w}\t%0";
5924 gcc_assert (operands[2] == constm1_rtx);
5925 return "dec{w}\t%0";
5929 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5930 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5931 if (CONST_INT_P (operands[2])
5932 && (INTVAL (operands[2]) == 128
5933 || (INTVAL (operands[2]) < 0
5934 && INTVAL (operands[2]) != -128)))
5936 operands[2] = GEN_INT (-INTVAL (operands[2]));
5937 return "sub{w}\t{%2, %0|%0, %2}";
5939 return "add{w}\t{%2, %0|%0, %2}";
5943 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5944 (const_string "incdec")
5945 (const_string "alu")))
5946 (set_attr "mode" "HI")])
5948 (define_insn "*addhi_2"
5949 [(set (reg FLAGS_REG)
5951 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5952 (match_operand:HI 2 "general_operand" "rmni,rni"))
5954 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5955 (plus:HI (match_dup 1) (match_dup 2)))]
5956 "ix86_match_ccmode (insn, CCGOCmode)
5957 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5959 switch (get_attr_type (insn))
5962 if (operands[2] == const1_rtx)
5963 return "inc{w}\t%0";
5966 gcc_assert (operands[2] == constm1_rtx);
5967 return "dec{w}\t%0";
5971 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5972 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5973 if (CONST_INT_P (operands[2])
5974 && (INTVAL (operands[2]) == 128
5975 || (INTVAL (operands[2]) < 0
5976 && INTVAL (operands[2]) != -128)))
5978 operands[2] = GEN_INT (-INTVAL (operands[2]));
5979 return "sub{w}\t{%2, %0|%0, %2}";
5981 return "add{w}\t{%2, %0|%0, %2}";
5985 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5986 (const_string "incdec")
5987 (const_string "alu")))
5988 (set_attr "mode" "HI")])
5990 (define_insn "*addhi_3"
5991 [(set (reg FLAGS_REG)
5992 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5993 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5994 (clobber (match_scratch:HI 0 "=r"))]
5995 "ix86_match_ccmode (insn, CCZmode)
5996 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5998 switch (get_attr_type (insn))
6001 if (operands[2] == const1_rtx)
6002 return "inc{w}\t%0";
6005 gcc_assert (operands[2] == constm1_rtx);
6006 return "dec{w}\t%0";
6010 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6011 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6012 if (CONST_INT_P (operands[2])
6013 && (INTVAL (operands[2]) == 128
6014 || (INTVAL (operands[2]) < 0
6015 && INTVAL (operands[2]) != -128)))
6017 operands[2] = GEN_INT (-INTVAL (operands[2]));
6018 return "sub{w}\t{%2, %0|%0, %2}";
6020 return "add{w}\t{%2, %0|%0, %2}";
6024 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6025 (const_string "incdec")
6026 (const_string "alu")))
6027 (set_attr "mode" "HI")])
6029 ; See comments above addsi_4 for details.
6030 (define_insn "*addhi_4"
6031 [(set (reg FLAGS_REG)
6032 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6033 (match_operand:HI 2 "const_int_operand" "n")))
6034 (clobber (match_scratch:HI 0 "=rm"))]
6035 "ix86_match_ccmode (insn, CCGCmode)
6036 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6038 switch (get_attr_type (insn))
6041 if (operands[2] == constm1_rtx)
6042 return "inc{w}\t%0";
6045 gcc_assert (operands[2] == const1_rtx);
6046 return "dec{w}\t%0";
6050 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6051 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6052 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6053 if ((INTVAL (operands[2]) == -128
6054 || (INTVAL (operands[2]) > 0
6055 && INTVAL (operands[2]) != 128)))
6056 return "sub{w}\t{%2, %0|%0, %2}";
6057 operands[2] = GEN_INT (-INTVAL (operands[2]));
6058 return "add{w}\t{%2, %0|%0, %2}";
6062 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6063 (const_string "incdec")
6064 (const_string "alu")))
6065 (set_attr "mode" "SI")])
6068 (define_insn "*addhi_5"
6069 [(set (reg FLAGS_REG)
6071 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6072 (match_operand:HI 2 "general_operand" "rmni"))
6074 (clobber (match_scratch:HI 0 "=r"))]
6075 "ix86_match_ccmode (insn, CCGOCmode)
6076 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6078 switch (get_attr_type (insn))
6081 if (operands[2] == const1_rtx)
6082 return "inc{w}\t%0";
6085 gcc_assert (operands[2] == constm1_rtx);
6086 return "dec{w}\t%0";
6090 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6091 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6092 if (CONST_INT_P (operands[2])
6093 && (INTVAL (operands[2]) == 128
6094 || (INTVAL (operands[2]) < 0
6095 && INTVAL (operands[2]) != -128)))
6097 operands[2] = GEN_INT (-INTVAL (operands[2]));
6098 return "sub{w}\t{%2, %0|%0, %2}";
6100 return "add{w}\t{%2, %0|%0, %2}";
6104 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6105 (const_string "incdec")
6106 (const_string "alu")))
6107 (set_attr "mode" "HI")])
6109 (define_expand "addqi3"
6110 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6111 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6112 (match_operand:QI 2 "general_operand" "")))
6113 (clobber (reg:CC FLAGS_REG))])]
6114 "TARGET_QIMODE_MATH"
6115 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6117 ;; %%% Potential partial reg stall on alternative 2. What to do?
6118 (define_insn "*addqi_1_lea"
6119 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6120 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6121 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6122 (clobber (reg:CC FLAGS_REG))]
6123 "!TARGET_PARTIAL_REG_STALL
6124 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6126 int widen = (which_alternative == 2);
6127 switch (get_attr_type (insn))
6132 if (operands[2] == const1_rtx)
6133 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6136 gcc_assert (operands[2] == constm1_rtx);
6137 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6141 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6142 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6143 if (CONST_INT_P (operands[2])
6144 && (INTVAL (operands[2]) == 128
6145 || (INTVAL (operands[2]) < 0
6146 && INTVAL (operands[2]) != -128)))
6148 operands[2] = GEN_INT (-INTVAL (operands[2]));
6150 return "sub{l}\t{%2, %k0|%k0, %2}";
6152 return "sub{b}\t{%2, %0|%0, %2}";
6155 return "add{l}\t{%k2, %k0|%k0, %k2}";
6157 return "add{b}\t{%2, %0|%0, %2}";
6161 (if_then_else (eq_attr "alternative" "3")
6162 (const_string "lea")
6163 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6164 (const_string "incdec")
6165 (const_string "alu"))))
6166 (set_attr "mode" "QI,QI,SI,SI")])
6168 (define_insn "*addqi_1"
6169 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6170 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6171 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6172 (clobber (reg:CC FLAGS_REG))]
6173 "TARGET_PARTIAL_REG_STALL
6174 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6176 int widen = (which_alternative == 2);
6177 switch (get_attr_type (insn))
6180 if (operands[2] == const1_rtx)
6181 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6184 gcc_assert (operands[2] == constm1_rtx);
6185 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6189 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6190 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6191 if (CONST_INT_P (operands[2])
6192 && (INTVAL (operands[2]) == 128
6193 || (INTVAL (operands[2]) < 0
6194 && INTVAL (operands[2]) != -128)))
6196 operands[2] = GEN_INT (-INTVAL (operands[2]));
6198 return "sub{l}\t{%2, %k0|%k0, %2}";
6200 return "sub{b}\t{%2, %0|%0, %2}";
6203 return "add{l}\t{%k2, %k0|%k0, %k2}";
6205 return "add{b}\t{%2, %0|%0, %2}";
6209 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6210 (const_string "incdec")
6211 (const_string "alu")))
6212 (set_attr "mode" "QI,QI,SI")])
6214 (define_insn "*addqi_1_slp"
6215 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6216 (plus:QI (match_dup 0)
6217 (match_operand:QI 1 "general_operand" "qn,qnm")))
6218 (clobber (reg:CC FLAGS_REG))]
6219 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6220 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6222 switch (get_attr_type (insn))
6225 if (operands[1] == const1_rtx)
6226 return "inc{b}\t%0";
6229 gcc_assert (operands[1] == constm1_rtx);
6230 return "dec{b}\t%0";
6234 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6235 if (CONST_INT_P (operands[1])
6236 && INTVAL (operands[1]) < 0)
6238 operands[1] = GEN_INT (-INTVAL (operands[1]));
6239 return "sub{b}\t{%1, %0|%0, %1}";
6241 return "add{b}\t{%1, %0|%0, %1}";
6245 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6246 (const_string "incdec")
6247 (const_string "alu1")))
6248 (set (attr "memory")
6249 (if_then_else (match_operand 1 "memory_operand" "")
6250 (const_string "load")
6251 (const_string "none")))
6252 (set_attr "mode" "QI")])
6254 (define_insn "*addqi_2"
6255 [(set (reg FLAGS_REG)
6257 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6258 (match_operand:QI 2 "general_operand" "qmni,qni"))
6260 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6261 (plus:QI (match_dup 1) (match_dup 2)))]
6262 "ix86_match_ccmode (insn, CCGOCmode)
6263 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6265 switch (get_attr_type (insn))
6268 if (operands[2] == const1_rtx)
6269 return "inc{b}\t%0";
6272 gcc_assert (operands[2] == constm1_rtx
6273 || (CONST_INT_P (operands[2])
6274 && INTVAL (operands[2]) == 255));
6275 return "dec{b}\t%0";
6279 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6280 if (CONST_INT_P (operands[2])
6281 && INTVAL (operands[2]) < 0)
6283 operands[2] = GEN_INT (-INTVAL (operands[2]));
6284 return "sub{b}\t{%2, %0|%0, %2}";
6286 return "add{b}\t{%2, %0|%0, %2}";
6290 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6291 (const_string "incdec")
6292 (const_string "alu")))
6293 (set_attr "mode" "QI")])
6295 (define_insn "*addqi_3"
6296 [(set (reg FLAGS_REG)
6297 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6298 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6299 (clobber (match_scratch:QI 0 "=q"))]
6300 "ix86_match_ccmode (insn, CCZmode)
6301 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6303 switch (get_attr_type (insn))
6306 if (operands[2] == const1_rtx)
6307 return "inc{b}\t%0";
6310 gcc_assert (operands[2] == constm1_rtx
6311 || (CONST_INT_P (operands[2])
6312 && INTVAL (operands[2]) == 255));
6313 return "dec{b}\t%0";
6317 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6318 if (CONST_INT_P (operands[2])
6319 && INTVAL (operands[2]) < 0)
6321 operands[2] = GEN_INT (-INTVAL (operands[2]));
6322 return "sub{b}\t{%2, %0|%0, %2}";
6324 return "add{b}\t{%2, %0|%0, %2}";
6328 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6329 (const_string "incdec")
6330 (const_string "alu")))
6331 (set_attr "mode" "QI")])
6333 ; See comments above addsi_4 for details.
6334 (define_insn "*addqi_4"
6335 [(set (reg FLAGS_REG)
6336 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6337 (match_operand:QI 2 "const_int_operand" "n")))
6338 (clobber (match_scratch:QI 0 "=qm"))]
6339 "ix86_match_ccmode (insn, CCGCmode)
6340 && (INTVAL (operands[2]) & 0xff) != 0x80"
6342 switch (get_attr_type (insn))
6345 if (operands[2] == constm1_rtx
6346 || (CONST_INT_P (operands[2])
6347 && INTVAL (operands[2]) == 255))
6348 return "inc{b}\t%0";
6351 gcc_assert (operands[2] == const1_rtx);
6352 return "dec{b}\t%0";
6356 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6357 if (INTVAL (operands[2]) < 0)
6359 operands[2] = GEN_INT (-INTVAL (operands[2]));
6360 return "add{b}\t{%2, %0|%0, %2}";
6362 return "sub{b}\t{%2, %0|%0, %2}";
6366 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6367 (const_string "incdec")
6368 (const_string "alu")))
6369 (set_attr "mode" "QI")])
6372 (define_insn "*addqi_5"
6373 [(set (reg FLAGS_REG)
6375 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6376 (match_operand:QI 2 "general_operand" "qmni"))
6378 (clobber (match_scratch:QI 0 "=q"))]
6379 "ix86_match_ccmode (insn, CCGOCmode)
6380 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6382 switch (get_attr_type (insn))
6385 if (operands[2] == const1_rtx)
6386 return "inc{b}\t%0";
6389 gcc_assert (operands[2] == constm1_rtx
6390 || (CONST_INT_P (operands[2])
6391 && INTVAL (operands[2]) == 255));
6392 return "dec{b}\t%0";
6396 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6397 if (CONST_INT_P (operands[2])
6398 && INTVAL (operands[2]) < 0)
6400 operands[2] = GEN_INT (-INTVAL (operands[2]));
6401 return "sub{b}\t{%2, %0|%0, %2}";
6403 return "add{b}\t{%2, %0|%0, %2}";
6407 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6408 (const_string "incdec")
6409 (const_string "alu")))
6410 (set_attr "mode" "QI")])
6413 (define_insn "addqi_ext_1"
6414 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6419 (match_operand 1 "ext_register_operand" "0")
6422 (match_operand:QI 2 "general_operand" "Qmn")))
6423 (clobber (reg:CC FLAGS_REG))]
6426 switch (get_attr_type (insn))
6429 if (operands[2] == const1_rtx)
6430 return "inc{b}\t%h0";
6433 gcc_assert (operands[2] == constm1_rtx
6434 || (CONST_INT_P (operands[2])
6435 && INTVAL (operands[2]) == 255));
6436 return "dec{b}\t%h0";
6440 return "add{b}\t{%2, %h0|%h0, %2}";
6444 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6445 (const_string "incdec")
6446 (const_string "alu")))
6447 (set_attr "mode" "QI")])
6449 (define_insn "*addqi_ext_1_rex64"
6450 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6455 (match_operand 1 "ext_register_operand" "0")
6458 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6459 (clobber (reg:CC FLAGS_REG))]
6462 switch (get_attr_type (insn))
6465 if (operands[2] == const1_rtx)
6466 return "inc{b}\t%h0";
6469 gcc_assert (operands[2] == constm1_rtx
6470 || (CONST_INT_P (operands[2])
6471 && INTVAL (operands[2]) == 255));
6472 return "dec{b}\t%h0";
6476 return "add{b}\t{%2, %h0|%h0, %2}";
6480 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6481 (const_string "incdec")
6482 (const_string "alu")))
6483 (set_attr "mode" "QI")])
6485 (define_insn "*addqi_ext_2"
6486 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6491 (match_operand 1 "ext_register_operand" "%0")
6495 (match_operand 2 "ext_register_operand" "Q")
6498 (clobber (reg:CC FLAGS_REG))]
6500 "add{b}\t{%h2, %h0|%h0, %h2}"
6501 [(set_attr "type" "alu")
6502 (set_attr "mode" "QI")])
6504 ;; The patterns that match these are at the end of this file.
6506 (define_expand "addxf3"
6507 [(set (match_operand:XF 0 "register_operand" "")
6508 (plus:XF (match_operand:XF 1 "register_operand" "")
6509 (match_operand:XF 2 "register_operand" "")))]
6513 (define_expand "adddf3"
6514 [(set (match_operand:DF 0 "register_operand" "")
6515 (plus:DF (match_operand:DF 1 "register_operand" "")
6516 (match_operand:DF 2 "nonimmediate_operand" "")))]
6517 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6520 (define_expand "addsf3"
6521 [(set (match_operand:SF 0 "register_operand" "")
6522 (plus:SF (match_operand:SF 1 "register_operand" "")
6523 (match_operand:SF 2 "nonimmediate_operand" "")))]
6524 "TARGET_80387 || TARGET_SSE_MATH"
6527 ;; Subtract instructions
6529 ;; %%% splits for subditi3
6531 (define_expand "subti3"
6532 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6533 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6534 (match_operand:TI 2 "x86_64_general_operand" "")))
6535 (clobber (reg:CC FLAGS_REG))])]
6537 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6539 (define_insn "*subti3_1"
6540 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6541 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6542 (match_operand:TI 2 "general_operand" "roiF,riF")))
6543 (clobber (reg:CC FLAGS_REG))]
6544 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6548 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6549 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6550 (match_operand:TI 2 "general_operand" "")))
6551 (clobber (reg:CC FLAGS_REG))]
6552 "TARGET_64BIT && reload_completed"
6553 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6554 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6555 (parallel [(set (match_dup 3)
6556 (minus:DI (match_dup 4)
6557 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6559 (clobber (reg:CC FLAGS_REG))])]
6560 "split_ti (operands+0, 1, operands+0, operands+3);
6561 split_ti (operands+1, 1, operands+1, operands+4);
6562 split_ti (operands+2, 1, operands+2, operands+5);")
6564 ;; %%% splits for subsidi3
6566 (define_expand "subdi3"
6567 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6568 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6569 (match_operand:DI 2 "x86_64_general_operand" "")))
6570 (clobber (reg:CC FLAGS_REG))])]
6572 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6574 (define_insn "*subdi3_1"
6575 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6576 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6577 (match_operand:DI 2 "general_operand" "roiF,riF")))
6578 (clobber (reg:CC FLAGS_REG))]
6579 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6583 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6584 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6585 (match_operand:DI 2 "general_operand" "")))
6586 (clobber (reg:CC FLAGS_REG))]
6587 "!TARGET_64BIT && reload_completed"
6588 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6589 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6590 (parallel [(set (match_dup 3)
6591 (minus:SI (match_dup 4)
6592 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6594 (clobber (reg:CC FLAGS_REG))])]
6595 "split_di (operands+0, 1, operands+0, operands+3);
6596 split_di (operands+1, 1, operands+1, operands+4);
6597 split_di (operands+2, 1, operands+2, operands+5);")
6599 (define_insn "subdi3_carry_rex64"
6600 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6601 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6602 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6603 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6604 (clobber (reg:CC FLAGS_REG))]
6605 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6606 "sbb{q}\t{%2, %0|%0, %2}"
6607 [(set_attr "type" "alu")
6608 (set_attr "pent_pair" "pu")
6609 (set_attr "mode" "DI")])
6611 (define_insn "*subdi_1_rex64"
6612 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6613 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6614 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6615 (clobber (reg:CC FLAGS_REG))]
6616 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6617 "sub{q}\t{%2, %0|%0, %2}"
6618 [(set_attr "type" "alu")
6619 (set_attr "mode" "DI")])
6621 (define_insn "*subdi_2_rex64"
6622 [(set (reg FLAGS_REG)
6624 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6625 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6627 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6628 (minus:DI (match_dup 1) (match_dup 2)))]
6629 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6630 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6631 "sub{q}\t{%2, %0|%0, %2}"
6632 [(set_attr "type" "alu")
6633 (set_attr "mode" "DI")])
6635 (define_insn "*subdi_3_rex63"
6636 [(set (reg FLAGS_REG)
6637 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6638 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6639 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6640 (minus:DI (match_dup 1) (match_dup 2)))]
6641 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6642 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6643 "sub{q}\t{%2, %0|%0, %2}"
6644 [(set_attr "type" "alu")
6645 (set_attr "mode" "DI")])
6647 (define_insn "subqi3_carry"
6648 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6649 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6650 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6651 (match_operand:QI 2 "general_operand" "qi,qm"))))
6652 (clobber (reg:CC FLAGS_REG))]
6653 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6654 "sbb{b}\t{%2, %0|%0, %2}"
6655 [(set_attr "type" "alu")
6656 (set_attr "pent_pair" "pu")
6657 (set_attr "mode" "QI")])
6659 (define_insn "subhi3_carry"
6660 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6661 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6662 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6663 (match_operand:HI 2 "general_operand" "ri,rm"))))
6664 (clobber (reg:CC FLAGS_REG))]
6665 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6666 "sbb{w}\t{%2, %0|%0, %2}"
6667 [(set_attr "type" "alu")
6668 (set_attr "pent_pair" "pu")
6669 (set_attr "mode" "HI")])
6671 (define_insn "subsi3_carry"
6672 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6673 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6674 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6675 (match_operand:SI 2 "general_operand" "ri,rm"))))
6676 (clobber (reg:CC FLAGS_REG))]
6677 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6678 "sbb{l}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "pent_pair" "pu")
6681 (set_attr "mode" "SI")])
6683 (define_insn "subsi3_carry_zext"
6684 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6686 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6687 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6688 (match_operand:SI 2 "general_operand" "ri,rm")))))
6689 (clobber (reg:CC FLAGS_REG))]
6690 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6691 "sbb{l}\t{%2, %k0|%k0, %2}"
6692 [(set_attr "type" "alu")
6693 (set_attr "pent_pair" "pu")
6694 (set_attr "mode" "SI")])
6696 (define_expand "subsi3"
6697 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6698 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6699 (match_operand:SI 2 "general_operand" "")))
6700 (clobber (reg:CC FLAGS_REG))])]
6702 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6704 (define_insn "*subsi_1"
6705 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6706 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6707 (match_operand:SI 2 "general_operand" "ri,rm")))
6708 (clobber (reg:CC FLAGS_REG))]
6709 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6710 "sub{l}\t{%2, %0|%0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "SI")])
6714 (define_insn "*subsi_1_zext"
6715 [(set (match_operand:DI 0 "register_operand" "=r")
6717 (minus:SI (match_operand:SI 1 "register_operand" "0")
6718 (match_operand:SI 2 "general_operand" "rim"))))
6719 (clobber (reg:CC FLAGS_REG))]
6720 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6721 "sub{l}\t{%2, %k0|%k0, %2}"
6722 [(set_attr "type" "alu")
6723 (set_attr "mode" "SI")])
6725 (define_insn "*subsi_2"
6726 [(set (reg FLAGS_REG)
6728 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6729 (match_operand:SI 2 "general_operand" "ri,rm"))
6731 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6732 (minus:SI (match_dup 1) (match_dup 2)))]
6733 "ix86_match_ccmode (insn, CCGOCmode)
6734 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735 "sub{l}\t{%2, %0|%0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "mode" "SI")])
6739 (define_insn "*subsi_2_zext"
6740 [(set (reg FLAGS_REG)
6742 (minus:SI (match_operand:SI 1 "register_operand" "0")
6743 (match_operand:SI 2 "general_operand" "rim"))
6745 (set (match_operand:DI 0 "register_operand" "=r")
6747 (minus:SI (match_dup 1)
6749 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6750 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6751 "sub{l}\t{%2, %k0|%k0, %2}"
6752 [(set_attr "type" "alu")
6753 (set_attr "mode" "SI")])
6755 (define_insn "*subsi_3"
6756 [(set (reg FLAGS_REG)
6757 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6758 (match_operand:SI 2 "general_operand" "ri,rm")))
6759 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6760 (minus:SI (match_dup 1) (match_dup 2)))]
6761 "ix86_match_ccmode (insn, CCmode)
6762 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763 "sub{l}\t{%2, %0|%0, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "SI")])
6767 (define_insn "*subsi_3_zext"
6768 [(set (reg FLAGS_REG)
6769 (compare (match_operand:SI 1 "register_operand" "0")
6770 (match_operand:SI 2 "general_operand" "rim")))
6771 (set (match_operand:DI 0 "register_operand" "=r")
6773 (minus:SI (match_dup 1)
6775 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6776 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777 "sub{l}\t{%2, %1|%1, %2}"
6778 [(set_attr "type" "alu")
6779 (set_attr "mode" "DI")])
6781 (define_expand "subhi3"
6782 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6783 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6784 (match_operand:HI 2 "general_operand" "")))
6785 (clobber (reg:CC FLAGS_REG))])]
6786 "TARGET_HIMODE_MATH"
6787 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6789 (define_insn "*subhi_1"
6790 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6791 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6792 (match_operand:HI 2 "general_operand" "ri,rm")))
6793 (clobber (reg:CC FLAGS_REG))]
6794 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6795 "sub{w}\t{%2, %0|%0, %2}"
6796 [(set_attr "type" "alu")
6797 (set_attr "mode" "HI")])
6799 (define_insn "*subhi_2"
6800 [(set (reg FLAGS_REG)
6802 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6803 (match_operand:HI 2 "general_operand" "ri,rm"))
6805 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6806 (minus:HI (match_dup 1) (match_dup 2)))]
6807 "ix86_match_ccmode (insn, CCGOCmode)
6808 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6809 "sub{w}\t{%2, %0|%0, %2}"
6810 [(set_attr "type" "alu")
6811 (set_attr "mode" "HI")])
6813 (define_insn "*subhi_3"
6814 [(set (reg FLAGS_REG)
6815 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6816 (match_operand:HI 2 "general_operand" "ri,rm")))
6817 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6818 (minus:HI (match_dup 1) (match_dup 2)))]
6819 "ix86_match_ccmode (insn, CCmode)
6820 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6821 "sub{w}\t{%2, %0|%0, %2}"
6822 [(set_attr "type" "alu")
6823 (set_attr "mode" "HI")])
6825 (define_expand "subqi3"
6826 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6827 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6828 (match_operand:QI 2 "general_operand" "")))
6829 (clobber (reg:CC FLAGS_REG))])]
6830 "TARGET_QIMODE_MATH"
6831 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6833 (define_insn "*subqi_1"
6834 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6835 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6836 (match_operand:QI 2 "general_operand" "qn,qmn")))
6837 (clobber (reg:CC FLAGS_REG))]
6838 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6839 "sub{b}\t{%2, %0|%0, %2}"
6840 [(set_attr "type" "alu")
6841 (set_attr "mode" "QI")])
6843 (define_insn "*subqi_1_slp"
6844 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6845 (minus:QI (match_dup 0)
6846 (match_operand:QI 1 "general_operand" "qn,qmn")))
6847 (clobber (reg:CC FLAGS_REG))]
6848 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6849 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6850 "sub{b}\t{%1, %0|%0, %1}"
6851 [(set_attr "type" "alu1")
6852 (set_attr "mode" "QI")])
6854 (define_insn "*subqi_2"
6855 [(set (reg FLAGS_REG)
6857 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6858 (match_operand:QI 2 "general_operand" "qi,qm"))
6860 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6861 (minus:HI (match_dup 1) (match_dup 2)))]
6862 "ix86_match_ccmode (insn, CCGOCmode)
6863 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6864 "sub{b}\t{%2, %0|%0, %2}"
6865 [(set_attr "type" "alu")
6866 (set_attr "mode" "QI")])
6868 (define_insn "*subqi_3"
6869 [(set (reg FLAGS_REG)
6870 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6871 (match_operand:QI 2 "general_operand" "qi,qm")))
6872 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6873 (minus:HI (match_dup 1) (match_dup 2)))]
6874 "ix86_match_ccmode (insn, CCmode)
6875 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6876 "sub{b}\t{%2, %0|%0, %2}"
6877 [(set_attr "type" "alu")
6878 (set_attr "mode" "QI")])
6880 ;; The patterns that match these are at the end of this file.
6882 (define_expand "subxf3"
6883 [(set (match_operand:XF 0 "register_operand" "")
6884 (minus:XF (match_operand:XF 1 "register_operand" "")
6885 (match_operand:XF 2 "register_operand" "")))]
6889 (define_expand "subdf3"
6890 [(set (match_operand:DF 0 "register_operand" "")
6891 (minus:DF (match_operand:DF 1 "register_operand" "")
6892 (match_operand:DF 2 "nonimmediate_operand" "")))]
6893 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6896 (define_expand "subsf3"
6897 [(set (match_operand:SF 0 "register_operand" "")
6898 (minus:SF (match_operand:SF 1 "register_operand" "")
6899 (match_operand:SF 2 "nonimmediate_operand" "")))]
6900 "TARGET_80387 || TARGET_SSE_MATH"
6903 ;; Multiply instructions
6905 (define_expand "muldi3"
6906 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6907 (mult:DI (match_operand:DI 1 "register_operand" "")
6908 (match_operand:DI 2 "x86_64_general_operand" "")))
6909 (clobber (reg:CC FLAGS_REG))])]
6913 (define_insn "*muldi3_1_rex64"
6914 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6915 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6916 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6917 (clobber (reg:CC FLAGS_REG))]
6919 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6921 imul{q}\t{%2, %1, %0|%0, %1, %2}
6922 imul{q}\t{%2, %1, %0|%0, %1, %2}
6923 imul{q}\t{%2, %0|%0, %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" "DI")])
6937 (define_expand "mulsi3"
6938 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6939 (mult:SI (match_operand:SI 1 "register_operand" "")
6940 (match_operand:SI 2 "general_operand" "")))
6941 (clobber (reg:CC FLAGS_REG))])]
6945 (define_insn "*mulsi3_1"
6946 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6947 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6948 (match_operand:SI 2 "general_operand" "K,i,mr")))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6952 imul{l}\t{%2, %1, %0|%0, %1, %2}
6953 imul{l}\t{%2, %1, %0|%0, %1, %2}
6954 imul{l}\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")
6961 (const_string "vector")
6962 (and (eq_attr "alternative" "2")
6963 (match_operand 1 "memory_operand" ""))
6964 (const_string "vector")]
6965 (const_string "direct")))
6966 (set_attr "mode" "SI")])
6968 (define_insn "*mulsi3_1_zext"
6969 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6971 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6972 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6973 (clobber (reg:CC FLAGS_REG))]
6975 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6977 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6978 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6979 imul{l}\t{%2, %k0|%k0, %2}"
6980 [(set_attr "type" "imul")
6981 (set_attr "prefix_0f" "0,0,1")
6982 (set (attr "athlon_decode")
6983 (cond [(eq_attr "cpu" "athlon")
6984 (const_string "vector")
6985 (eq_attr "alternative" "1")
6986 (const_string "vector")
6987 (and (eq_attr "alternative" "2")
6988 (match_operand 1 "memory_operand" ""))
6989 (const_string "vector")]
6990 (const_string "direct")))
6991 (set_attr "mode" "SI")])
6993 (define_expand "mulhi3"
6994 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6995 (mult:HI (match_operand:HI 1 "register_operand" "")
6996 (match_operand:HI 2 "general_operand" "")))
6997 (clobber (reg:CC FLAGS_REG))])]
6998 "TARGET_HIMODE_MATH"
7001 (define_insn "*mulhi3_1"
7002 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7003 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7004 (match_operand:HI 2 "general_operand" "K,i,mr")))
7005 (clobber (reg:CC FLAGS_REG))]
7006 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7008 imul{w}\t{%2, %1, %0|%0, %1, %2}
7009 imul{w}\t{%2, %1, %0|%0, %1, %2}
7010 imul{w}\t{%2, %0|%0, %2}"
7011 [(set_attr "type" "imul")
7012 (set_attr "prefix_0f" "0,0,1")
7013 (set (attr "athlon_decode")
7014 (cond [(eq_attr "cpu" "athlon")
7015 (const_string "vector")
7016 (eq_attr "alternative" "1,2")
7017 (const_string "vector")]
7018 (const_string "direct")))
7019 (set_attr "mode" "HI")])
7021 (define_expand "mulqi3"
7022 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7023 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7024 (match_operand:QI 2 "register_operand" "")))
7025 (clobber (reg:CC FLAGS_REG))])]
7026 "TARGET_QIMODE_MATH"
7029 (define_insn "*mulqi3_1"
7030 [(set (match_operand:QI 0 "register_operand" "=a")
7031 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7032 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7033 (clobber (reg:CC FLAGS_REG))]
7035 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7037 [(set_attr "type" "imul")
7038 (set_attr "length_immediate" "0")
7039 (set (attr "athlon_decode")
7040 (if_then_else (eq_attr "cpu" "athlon")
7041 (const_string "vector")
7042 (const_string "direct")))
7043 (set_attr "mode" "QI")])
7045 (define_expand "umulqihi3"
7046 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7047 (mult:HI (zero_extend:HI
7048 (match_operand:QI 1 "nonimmediate_operand" ""))
7050 (match_operand:QI 2 "register_operand" ""))))
7051 (clobber (reg:CC FLAGS_REG))])]
7052 "TARGET_QIMODE_MATH"
7055 (define_insn "*umulqihi3_1"
7056 [(set (match_operand:HI 0 "register_operand" "=a")
7057 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7058 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7059 (clobber (reg:CC FLAGS_REG))]
7061 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7063 [(set_attr "type" "imul")
7064 (set_attr "length_immediate" "0")
7065 (set (attr "athlon_decode")
7066 (if_then_else (eq_attr "cpu" "athlon")
7067 (const_string "vector")
7068 (const_string "direct")))
7069 (set_attr "mode" "QI")])
7071 (define_expand "mulqihi3"
7072 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7073 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7074 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7075 (clobber (reg:CC FLAGS_REG))])]
7076 "TARGET_QIMODE_MATH"
7079 (define_insn "*mulqihi3_insn"
7080 [(set (match_operand:HI 0 "register_operand" "=a")
7081 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7082 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7083 (clobber (reg:CC FLAGS_REG))]
7085 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7087 [(set_attr "type" "imul")
7088 (set_attr "length_immediate" "0")
7089 (set (attr "athlon_decode")
7090 (if_then_else (eq_attr "cpu" "athlon")
7091 (const_string "vector")
7092 (const_string "direct")))
7093 (set_attr "mode" "QI")])
7095 (define_expand "umulditi3"
7096 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7097 (mult:TI (zero_extend:TI
7098 (match_operand:DI 1 "nonimmediate_operand" ""))
7100 (match_operand:DI 2 "register_operand" ""))))
7101 (clobber (reg:CC FLAGS_REG))])]
7105 (define_insn "*umulditi3_insn"
7106 [(set (match_operand:TI 0 "register_operand" "=A")
7107 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7108 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7109 (clobber (reg:CC FLAGS_REG))]
7111 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7113 [(set_attr "type" "imul")
7114 (set_attr "length_immediate" "0")
7115 (set (attr "athlon_decode")
7116 (if_then_else (eq_attr "cpu" "athlon")
7117 (const_string "vector")
7118 (const_string "double")))
7119 (set_attr "mode" "DI")])
7121 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7122 (define_expand "umulsidi3"
7123 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7124 (mult:DI (zero_extend:DI
7125 (match_operand:SI 1 "nonimmediate_operand" ""))
7127 (match_operand:SI 2 "register_operand" ""))))
7128 (clobber (reg:CC FLAGS_REG))])]
7132 (define_insn "*umulsidi3_insn"
7133 [(set (match_operand:DI 0 "register_operand" "=A")
7134 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7135 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7136 (clobber (reg:CC FLAGS_REG))]
7138 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7140 [(set_attr "type" "imul")
7141 (set_attr "length_immediate" "0")
7142 (set (attr "athlon_decode")
7143 (if_then_else (eq_attr "cpu" "athlon")
7144 (const_string "vector")
7145 (const_string "double")))
7146 (set_attr "mode" "SI")])
7148 (define_expand "mulditi3"
7149 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7150 (mult:TI (sign_extend:TI
7151 (match_operand:DI 1 "nonimmediate_operand" ""))
7153 (match_operand:DI 2 "register_operand" ""))))
7154 (clobber (reg:CC FLAGS_REG))])]
7158 (define_insn "*mulditi3_insn"
7159 [(set (match_operand:TI 0 "register_operand" "=A")
7160 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7161 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7162 (clobber (reg:CC FLAGS_REG))]
7164 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7166 [(set_attr "type" "imul")
7167 (set_attr "length_immediate" "0")
7168 (set (attr "athlon_decode")
7169 (if_then_else (eq_attr "cpu" "athlon")
7170 (const_string "vector")
7171 (const_string "double")))
7172 (set_attr "mode" "DI")])
7174 (define_expand "mulsidi3"
7175 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7176 (mult:DI (sign_extend:DI
7177 (match_operand:SI 1 "nonimmediate_operand" ""))
7179 (match_operand:SI 2 "register_operand" ""))))
7180 (clobber (reg:CC FLAGS_REG))])]
7184 (define_insn "*mulsidi3_insn"
7185 [(set (match_operand:DI 0 "register_operand" "=A")
7186 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7187 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7188 (clobber (reg:CC FLAGS_REG))]
7190 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7192 [(set_attr "type" "imul")
7193 (set_attr "length_immediate" "0")
7194 (set (attr "athlon_decode")
7195 (if_then_else (eq_attr "cpu" "athlon")
7196 (const_string "vector")
7197 (const_string "double")))
7198 (set_attr "mode" "SI")])
7200 (define_expand "umuldi3_highpart"
7201 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7204 (mult:TI (zero_extend:TI
7205 (match_operand:DI 1 "nonimmediate_operand" ""))
7207 (match_operand:DI 2 "register_operand" "")))
7209 (clobber (match_scratch:DI 3 ""))
7210 (clobber (reg:CC FLAGS_REG))])]
7214 (define_insn "*umuldi3_highpart_rex64"
7215 [(set (match_operand:DI 0 "register_operand" "=d")
7218 (mult:TI (zero_extend:TI
7219 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7221 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7223 (clobber (match_scratch:DI 3 "=1"))
7224 (clobber (reg:CC FLAGS_REG))]
7226 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7228 [(set_attr "type" "imul")
7229 (set_attr "length_immediate" "0")
7230 (set (attr "athlon_decode")
7231 (if_then_else (eq_attr "cpu" "athlon")
7232 (const_string "vector")
7233 (const_string "double")))
7234 (set_attr "mode" "DI")])
7236 (define_expand "umulsi3_highpart"
7237 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7240 (mult:DI (zero_extend:DI
7241 (match_operand:SI 1 "nonimmediate_operand" ""))
7243 (match_operand:SI 2 "register_operand" "")))
7245 (clobber (match_scratch:SI 3 ""))
7246 (clobber (reg:CC FLAGS_REG))])]
7250 (define_insn "*umulsi3_highpart_insn"
7251 [(set (match_operand:SI 0 "register_operand" "=d")
7254 (mult:DI (zero_extend:DI
7255 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7257 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7259 (clobber (match_scratch:SI 3 "=1"))
7260 (clobber (reg:CC FLAGS_REG))]
7261 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7263 [(set_attr "type" "imul")
7264 (set_attr "length_immediate" "0")
7265 (set (attr "athlon_decode")
7266 (if_then_else (eq_attr "cpu" "athlon")
7267 (const_string "vector")
7268 (const_string "double")))
7269 (set_attr "mode" "SI")])
7271 (define_insn "*umulsi3_highpart_zext"
7272 [(set (match_operand:DI 0 "register_operand" "=d")
7273 (zero_extend:DI (truncate:SI
7275 (mult:DI (zero_extend:DI
7276 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7278 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7280 (clobber (match_scratch:SI 3 "=1"))
7281 (clobber (reg:CC FLAGS_REG))]
7283 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7285 [(set_attr "type" "imul")
7286 (set_attr "length_immediate" "0")
7287 (set (attr "athlon_decode")
7288 (if_then_else (eq_attr "cpu" "athlon")
7289 (const_string "vector")
7290 (const_string "double")))
7291 (set_attr "mode" "SI")])
7293 (define_expand "smuldi3_highpart"
7294 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7297 (mult:TI (sign_extend:TI
7298 (match_operand:DI 1 "nonimmediate_operand" ""))
7300 (match_operand:DI 2 "register_operand" "")))
7302 (clobber (match_scratch:DI 3 ""))
7303 (clobber (reg:CC FLAGS_REG))])]
7307 (define_insn "*smuldi3_highpart_rex64"
7308 [(set (match_operand:DI 0 "register_operand" "=d")
7311 (mult:TI (sign_extend:TI
7312 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7314 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7316 (clobber (match_scratch:DI 3 "=1"))
7317 (clobber (reg:CC FLAGS_REG))]
7319 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7321 [(set_attr "type" "imul")
7322 (set (attr "athlon_decode")
7323 (if_then_else (eq_attr "cpu" "athlon")
7324 (const_string "vector")
7325 (const_string "double")))
7326 (set_attr "mode" "DI")])
7328 (define_expand "smulsi3_highpart"
7329 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7332 (mult:DI (sign_extend:DI
7333 (match_operand:SI 1 "nonimmediate_operand" ""))
7335 (match_operand:SI 2 "register_operand" "")))
7337 (clobber (match_scratch:SI 3 ""))
7338 (clobber (reg:CC FLAGS_REG))])]
7342 (define_insn "*smulsi3_highpart_insn"
7343 [(set (match_operand:SI 0 "register_operand" "=d")
7346 (mult:DI (sign_extend:DI
7347 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7349 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7351 (clobber (match_scratch:SI 3 "=1"))
7352 (clobber (reg:CC FLAGS_REG))]
7353 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7355 [(set_attr "type" "imul")
7356 (set (attr "athlon_decode")
7357 (if_then_else (eq_attr "cpu" "athlon")
7358 (const_string "vector")
7359 (const_string "double")))
7360 (set_attr "mode" "SI")])
7362 (define_insn "*smulsi3_highpart_zext"
7363 [(set (match_operand:DI 0 "register_operand" "=d")
7364 (zero_extend:DI (truncate:SI
7366 (mult:DI (sign_extend:DI
7367 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7369 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7371 (clobber (match_scratch:SI 3 "=1"))
7372 (clobber (reg:CC FLAGS_REG))]
7374 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7376 [(set_attr "type" "imul")
7377 (set (attr "athlon_decode")
7378 (if_then_else (eq_attr "cpu" "athlon")
7379 (const_string "vector")
7380 (const_string "double")))
7381 (set_attr "mode" "SI")])
7383 ;; The patterns that match these are at the end of this file.
7385 (define_expand "mulxf3"
7386 [(set (match_operand:XF 0 "register_operand" "")
7387 (mult:XF (match_operand:XF 1 "register_operand" "")
7388 (match_operand:XF 2 "register_operand" "")))]
7392 (define_expand "muldf3"
7393 [(set (match_operand:DF 0 "register_operand" "")
7394 (mult:DF (match_operand:DF 1 "register_operand" "")
7395 (match_operand:DF 2 "nonimmediate_operand" "")))]
7396 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7399 (define_expand "mulsf3"
7400 [(set (match_operand:SF 0 "register_operand" "")
7401 (mult:SF (match_operand:SF 1 "register_operand" "")
7402 (match_operand:SF 2 "nonimmediate_operand" "")))]
7403 "TARGET_80387 || TARGET_SSE_MATH"
7406 ;; Divide instructions
7408 (define_insn "divqi3"
7409 [(set (match_operand:QI 0 "register_operand" "=a")
7410 (div:QI (match_operand:HI 1 "register_operand" "0")
7411 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7412 (clobber (reg:CC FLAGS_REG))]
7413 "TARGET_QIMODE_MATH"
7415 [(set_attr "type" "idiv")
7416 (set_attr "mode" "QI")])
7418 (define_insn "udivqi3"
7419 [(set (match_operand:QI 0 "register_operand" "=a")
7420 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7421 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7422 (clobber (reg:CC FLAGS_REG))]
7423 "TARGET_QIMODE_MATH"
7425 [(set_attr "type" "idiv")
7426 (set_attr "mode" "QI")])
7428 ;; The patterns that match these are at the end of this file.
7430 (define_expand "divxf3"
7431 [(set (match_operand:XF 0 "register_operand" "")
7432 (div:XF (match_operand:XF 1 "register_operand" "")
7433 (match_operand:XF 2 "register_operand" "")))]
7437 (define_expand "divdf3"
7438 [(set (match_operand:DF 0 "register_operand" "")
7439 (div:DF (match_operand:DF 1 "register_operand" "")
7440 (match_operand:DF 2 "nonimmediate_operand" "")))]
7441 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7444 (define_expand "divsf3"
7445 [(set (match_operand:SF 0 "register_operand" "")
7446 (div:SF (match_operand:SF 1 "register_operand" "")
7447 (match_operand:SF 2 "nonimmediate_operand" "")))]
7448 "TARGET_80387 || TARGET_SSE_MATH"
7451 ;; Remainder instructions.
7453 (define_expand "divmoddi4"
7454 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7455 (div:DI (match_operand:DI 1 "register_operand" "")
7456 (match_operand:DI 2 "nonimmediate_operand" "")))
7457 (set (match_operand:DI 3 "register_operand" "")
7458 (mod:DI (match_dup 1) (match_dup 2)))
7459 (clobber (reg:CC FLAGS_REG))])]
7463 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7464 ;; Penalize eax case slightly because it results in worse scheduling
7466 (define_insn "*divmoddi4_nocltd_rex64"
7467 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7468 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7469 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7470 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7471 (mod:DI (match_dup 2) (match_dup 3)))
7472 (clobber (reg:CC FLAGS_REG))]
7473 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7475 [(set_attr "type" "multi")])
7477 (define_insn "*divmoddi4_cltd_rex64"
7478 [(set (match_operand:DI 0 "register_operand" "=a")
7479 (div:DI (match_operand:DI 2 "register_operand" "a")
7480 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7481 (set (match_operand:DI 1 "register_operand" "=&d")
7482 (mod:DI (match_dup 2) (match_dup 3)))
7483 (clobber (reg:CC FLAGS_REG))]
7484 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7486 [(set_attr "type" "multi")])
7488 (define_insn "*divmoddi_noext_rex64"
7489 [(set (match_operand:DI 0 "register_operand" "=a")
7490 (div:DI (match_operand:DI 1 "register_operand" "0")
7491 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7492 (set (match_operand:DI 3 "register_operand" "=d")
7493 (mod:DI (match_dup 1) (match_dup 2)))
7494 (use (match_operand:DI 4 "register_operand" "3"))
7495 (clobber (reg:CC FLAGS_REG))]
7498 [(set_attr "type" "idiv")
7499 (set_attr "mode" "DI")])
7502 [(set (match_operand:DI 0 "register_operand" "")
7503 (div:DI (match_operand:DI 1 "register_operand" "")
7504 (match_operand:DI 2 "nonimmediate_operand" "")))
7505 (set (match_operand:DI 3 "register_operand" "")
7506 (mod:DI (match_dup 1) (match_dup 2)))
7507 (clobber (reg:CC FLAGS_REG))]
7508 "TARGET_64BIT && reload_completed"
7509 [(parallel [(set (match_dup 3)
7510 (ashiftrt:DI (match_dup 4) (const_int 63)))
7511 (clobber (reg:CC FLAGS_REG))])
7512 (parallel [(set (match_dup 0)
7513 (div:DI (reg:DI 0) (match_dup 2)))
7515 (mod:DI (reg:DI 0) (match_dup 2)))
7517 (clobber (reg:CC FLAGS_REG))])]
7519 /* Avoid use of cltd in favor of a mov+shift. */
7520 if (!TARGET_USE_CLTD && !optimize_size)
7522 if (true_regnum (operands[1]))
7523 emit_move_insn (operands[0], operands[1]);
7525 emit_move_insn (operands[3], operands[1]);
7526 operands[4] = operands[3];
7530 gcc_assert (!true_regnum (operands[1]));
7531 operands[4] = operands[1];
7536 (define_expand "divmodsi4"
7537 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7538 (div:SI (match_operand:SI 1 "register_operand" "")
7539 (match_operand:SI 2 "nonimmediate_operand" "")))
7540 (set (match_operand:SI 3 "register_operand" "")
7541 (mod:SI (match_dup 1) (match_dup 2)))
7542 (clobber (reg:CC FLAGS_REG))])]
7546 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7547 ;; Penalize eax case slightly because it results in worse scheduling
7549 (define_insn "*divmodsi4_nocltd"
7550 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7551 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7552 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7553 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7554 (mod:SI (match_dup 2) (match_dup 3)))
7555 (clobber (reg:CC FLAGS_REG))]
7556 "!optimize_size && !TARGET_USE_CLTD"
7558 [(set_attr "type" "multi")])
7560 (define_insn "*divmodsi4_cltd"
7561 [(set (match_operand:SI 0 "register_operand" "=a")
7562 (div:SI (match_operand:SI 2 "register_operand" "a")
7563 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7564 (set (match_operand:SI 1 "register_operand" "=&d")
7565 (mod:SI (match_dup 2) (match_dup 3)))
7566 (clobber (reg:CC FLAGS_REG))]
7567 "optimize_size || TARGET_USE_CLTD"
7569 [(set_attr "type" "multi")])
7571 (define_insn "*divmodsi_noext"
7572 [(set (match_operand:SI 0 "register_operand" "=a")
7573 (div:SI (match_operand:SI 1 "register_operand" "0")
7574 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7575 (set (match_operand:SI 3 "register_operand" "=d")
7576 (mod:SI (match_dup 1) (match_dup 2)))
7577 (use (match_operand:SI 4 "register_operand" "3"))
7578 (clobber (reg:CC FLAGS_REG))]
7581 [(set_attr "type" "idiv")
7582 (set_attr "mode" "SI")])
7585 [(set (match_operand:SI 0 "register_operand" "")
7586 (div:SI (match_operand:SI 1 "register_operand" "")
7587 (match_operand:SI 2 "nonimmediate_operand" "")))
7588 (set (match_operand:SI 3 "register_operand" "")
7589 (mod:SI (match_dup 1) (match_dup 2)))
7590 (clobber (reg:CC FLAGS_REG))]
7592 [(parallel [(set (match_dup 3)
7593 (ashiftrt:SI (match_dup 4) (const_int 31)))
7594 (clobber (reg:CC FLAGS_REG))])
7595 (parallel [(set (match_dup 0)
7596 (div:SI (reg:SI 0) (match_dup 2)))
7598 (mod:SI (reg:SI 0) (match_dup 2)))
7600 (clobber (reg:CC FLAGS_REG))])]
7602 /* Avoid use of cltd in favor of a mov+shift. */
7603 if (!TARGET_USE_CLTD && !optimize_size)
7605 if (true_regnum (operands[1]))
7606 emit_move_insn (operands[0], operands[1]);
7608 emit_move_insn (operands[3], operands[1]);
7609 operands[4] = operands[3];
7613 gcc_assert (!true_regnum (operands[1]));
7614 operands[4] = operands[1];
7618 (define_insn "divmodhi4"
7619 [(set (match_operand:HI 0 "register_operand" "=a")
7620 (div:HI (match_operand:HI 1 "register_operand" "0")
7621 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7622 (set (match_operand:HI 3 "register_operand" "=&d")
7623 (mod:HI (match_dup 1) (match_dup 2)))
7624 (clobber (reg:CC FLAGS_REG))]
7625 "TARGET_HIMODE_MATH"
7627 [(set_attr "type" "multi")
7628 (set_attr "length_immediate" "0")
7629 (set_attr "mode" "SI")])
7631 (define_insn "udivmoddi4"
7632 [(set (match_operand:DI 0 "register_operand" "=a")
7633 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7634 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7635 (set (match_operand:DI 3 "register_operand" "=&d")
7636 (umod:DI (match_dup 1) (match_dup 2)))
7637 (clobber (reg:CC FLAGS_REG))]
7639 "xor{q}\t%3, %3\;div{q}\t%2"
7640 [(set_attr "type" "multi")
7641 (set_attr "length_immediate" "0")
7642 (set_attr "mode" "DI")])
7644 (define_insn "*udivmoddi4_noext"
7645 [(set (match_operand:DI 0 "register_operand" "=a")
7646 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7647 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7648 (set (match_operand:DI 3 "register_operand" "=d")
7649 (umod:DI (match_dup 1) (match_dup 2)))
7651 (clobber (reg:CC FLAGS_REG))]
7654 [(set_attr "type" "idiv")
7655 (set_attr "mode" "DI")])
7658 [(set (match_operand:DI 0 "register_operand" "")
7659 (udiv:DI (match_operand:DI 1 "register_operand" "")
7660 (match_operand:DI 2 "nonimmediate_operand" "")))
7661 (set (match_operand:DI 3 "register_operand" "")
7662 (umod:DI (match_dup 1) (match_dup 2)))
7663 (clobber (reg:CC FLAGS_REG))]
7664 "TARGET_64BIT && reload_completed"
7665 [(set (match_dup 3) (const_int 0))
7666 (parallel [(set (match_dup 0)
7667 (udiv:DI (match_dup 1) (match_dup 2)))
7669 (umod:DI (match_dup 1) (match_dup 2)))
7671 (clobber (reg:CC FLAGS_REG))])]
7674 (define_insn "udivmodsi4"
7675 [(set (match_operand:SI 0 "register_operand" "=a")
7676 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7677 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7678 (set (match_operand:SI 3 "register_operand" "=&d")
7679 (umod:SI (match_dup 1) (match_dup 2)))
7680 (clobber (reg:CC FLAGS_REG))]
7682 "xor{l}\t%3, %3\;div{l}\t%2"
7683 [(set_attr "type" "multi")
7684 (set_attr "length_immediate" "0")
7685 (set_attr "mode" "SI")])
7687 (define_insn "*udivmodsi4_noext"
7688 [(set (match_operand:SI 0 "register_operand" "=a")
7689 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7690 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7691 (set (match_operand:SI 3 "register_operand" "=d")
7692 (umod:SI (match_dup 1) (match_dup 2)))
7694 (clobber (reg:CC FLAGS_REG))]
7697 [(set_attr "type" "idiv")
7698 (set_attr "mode" "SI")])
7701 [(set (match_operand:SI 0 "register_operand" "")
7702 (udiv:SI (match_operand:SI 1 "register_operand" "")
7703 (match_operand:SI 2 "nonimmediate_operand" "")))
7704 (set (match_operand:SI 3 "register_operand" "")
7705 (umod:SI (match_dup 1) (match_dup 2)))
7706 (clobber (reg:CC FLAGS_REG))]
7708 [(set (match_dup 3) (const_int 0))
7709 (parallel [(set (match_dup 0)
7710 (udiv:SI (match_dup 1) (match_dup 2)))
7712 (umod:SI (match_dup 1) (match_dup 2)))
7714 (clobber (reg:CC FLAGS_REG))])]
7717 (define_expand "udivmodhi4"
7718 [(set (match_dup 4) (const_int 0))
7719 (parallel [(set (match_operand:HI 0 "register_operand" "")
7720 (udiv:HI (match_operand:HI 1 "register_operand" "")
7721 (match_operand:HI 2 "nonimmediate_operand" "")))
7722 (set (match_operand:HI 3 "register_operand" "")
7723 (umod:HI (match_dup 1) (match_dup 2)))
7725 (clobber (reg:CC FLAGS_REG))])]
7726 "TARGET_HIMODE_MATH"
7727 "operands[4] = gen_reg_rtx (HImode);")
7729 (define_insn "*udivmodhi_noext"
7730 [(set (match_operand:HI 0 "register_operand" "=a")
7731 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7732 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7733 (set (match_operand:HI 3 "register_operand" "=d")
7734 (umod:HI (match_dup 1) (match_dup 2)))
7735 (use (match_operand:HI 4 "register_operand" "3"))
7736 (clobber (reg:CC FLAGS_REG))]
7739 [(set_attr "type" "idiv")
7740 (set_attr "mode" "HI")])
7742 ;; We cannot use div/idiv for double division, because it causes
7743 ;; "division by zero" on the overflow and that's not what we expect
7744 ;; from truncate. Because true (non truncating) double division is
7745 ;; never generated, we can't create this insn anyway.
7748 ; [(set (match_operand:SI 0 "register_operand" "=a")
7750 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7752 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7753 ; (set (match_operand:SI 3 "register_operand" "=d")
7755 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7756 ; (clobber (reg:CC FLAGS_REG))]
7758 ; "div{l}\t{%2, %0|%0, %2}"
7759 ; [(set_attr "type" "idiv")])
7761 ;;- Logical AND instructions
7763 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7764 ;; Note that this excludes ah.
7766 (define_insn "*testdi_1_rex64"
7767 [(set (reg FLAGS_REG)
7769 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7770 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7772 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7773 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7775 test{l}\t{%k1, %k0|%k0, %k1}
7776 test{l}\t{%k1, %k0|%k0, %k1}
7777 test{q}\t{%1, %0|%0, %1}
7778 test{q}\t{%1, %0|%0, %1}
7779 test{q}\t{%1, %0|%0, %1}"
7780 [(set_attr "type" "test")
7781 (set_attr "modrm" "0,1,0,1,1")
7782 (set_attr "mode" "SI,SI,DI,DI,DI")
7783 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7785 (define_insn "testsi_1"
7786 [(set (reg FLAGS_REG)
7788 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7789 (match_operand:SI 1 "general_operand" "in,in,rin"))
7791 "ix86_match_ccmode (insn, CCNOmode)
7792 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7793 "test{l}\t{%1, %0|%0, %1}"
7794 [(set_attr "type" "test")
7795 (set_attr "modrm" "0,1,1")
7796 (set_attr "mode" "SI")
7797 (set_attr "pent_pair" "uv,np,uv")])
7799 (define_expand "testsi_ccno_1"
7800 [(set (reg:CCNO FLAGS_REG)
7802 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7803 (match_operand:SI 1 "nonmemory_operand" ""))
7808 (define_insn "*testhi_1"
7809 [(set (reg FLAGS_REG)
7810 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7811 (match_operand:HI 1 "general_operand" "n,n,rn"))
7813 "ix86_match_ccmode (insn, CCNOmode)
7814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7815 "test{w}\t{%1, %0|%0, %1}"
7816 [(set_attr "type" "test")
7817 (set_attr "modrm" "0,1,1")
7818 (set_attr "mode" "HI")
7819 (set_attr "pent_pair" "uv,np,uv")])
7821 (define_expand "testqi_ccz_1"
7822 [(set (reg:CCZ FLAGS_REG)
7823 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7824 (match_operand:QI 1 "nonmemory_operand" ""))
7829 (define_insn "*testqi_1_maybe_si"
7830 [(set (reg FLAGS_REG)
7833 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7834 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7836 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7837 && ix86_match_ccmode (insn,
7838 CONST_INT_P (operands[1])
7839 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7841 if (which_alternative == 3)
7843 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7844 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7845 return "test{l}\t{%1, %k0|%k0, %1}";
7847 return "test{b}\t{%1, %0|%0, %1}";
7849 [(set_attr "type" "test")
7850 (set_attr "modrm" "0,1,1,1")
7851 (set_attr "mode" "QI,QI,QI,SI")
7852 (set_attr "pent_pair" "uv,np,uv,np")])
7854 (define_insn "*testqi_1"
7855 [(set (reg FLAGS_REG)
7858 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7859 (match_operand:QI 1 "general_operand" "n,n,qn"))
7861 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7862 && ix86_match_ccmode (insn, CCNOmode)"
7863 "test{b}\t{%1, %0|%0, %1}"
7864 [(set_attr "type" "test")
7865 (set_attr "modrm" "0,1,1")
7866 (set_attr "mode" "QI")
7867 (set_attr "pent_pair" "uv,np,uv")])
7869 (define_expand "testqi_ext_ccno_0"
7870 [(set (reg:CCNO FLAGS_REG)
7874 (match_operand 0 "ext_register_operand" "")
7877 (match_operand 1 "const_int_operand" ""))
7882 (define_insn "*testqi_ext_0"
7883 [(set (reg FLAGS_REG)
7887 (match_operand 0 "ext_register_operand" "Q")
7890 (match_operand 1 "const_int_operand" "n"))
7892 "ix86_match_ccmode (insn, CCNOmode)"
7893 "test{b}\t{%1, %h0|%h0, %1}"
7894 [(set_attr "type" "test")
7895 (set_attr "mode" "QI")
7896 (set_attr "length_immediate" "1")
7897 (set_attr "pent_pair" "np")])
7899 (define_insn "*testqi_ext_1"
7900 [(set (reg FLAGS_REG)
7904 (match_operand 0 "ext_register_operand" "Q")
7908 (match_operand:QI 1 "general_operand" "Qm")))
7910 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7911 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7912 "test{b}\t{%1, %h0|%h0, %1}"
7913 [(set_attr "type" "test")
7914 (set_attr "mode" "QI")])
7916 (define_insn "*testqi_ext_1_rex64"
7917 [(set (reg FLAGS_REG)
7921 (match_operand 0 "ext_register_operand" "Q")
7925 (match_operand:QI 1 "register_operand" "Q")))
7927 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7928 "test{b}\t{%1, %h0|%h0, %1}"
7929 [(set_attr "type" "test")
7930 (set_attr "mode" "QI")])
7932 (define_insn "*testqi_ext_2"
7933 [(set (reg FLAGS_REG)
7937 (match_operand 0 "ext_register_operand" "Q")
7941 (match_operand 1 "ext_register_operand" "Q")
7945 "ix86_match_ccmode (insn, CCNOmode)"
7946 "test{b}\t{%h1, %h0|%h0, %h1}"
7947 [(set_attr "type" "test")
7948 (set_attr "mode" "QI")])
7950 ;; Combine likes to form bit extractions for some tests. Humor it.
7951 (define_insn "*testqi_ext_3"
7952 [(set (reg FLAGS_REG)
7953 (compare (zero_extract:SI
7954 (match_operand 0 "nonimmediate_operand" "rm")
7955 (match_operand:SI 1 "const_int_operand" "")
7956 (match_operand:SI 2 "const_int_operand" ""))
7958 "ix86_match_ccmode (insn, CCNOmode)
7959 && INTVAL (operands[1]) > 0
7960 && INTVAL (operands[2]) >= 0
7961 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7962 && (GET_MODE (operands[0]) == SImode
7963 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7964 || GET_MODE (operands[0]) == HImode
7965 || GET_MODE (operands[0]) == QImode)"
7968 (define_insn "*testqi_ext_3_rex64"
7969 [(set (reg FLAGS_REG)
7970 (compare (zero_extract:DI
7971 (match_operand 0 "nonimmediate_operand" "rm")
7972 (match_operand:DI 1 "const_int_operand" "")
7973 (match_operand:DI 2 "const_int_operand" ""))
7976 && ix86_match_ccmode (insn, CCNOmode)
7977 && INTVAL (operands[1]) > 0
7978 && INTVAL (operands[2]) >= 0
7979 /* Ensure that resulting mask is zero or sign extended operand. */
7980 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7981 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7982 && INTVAL (operands[1]) > 32))
7983 && (GET_MODE (operands[0]) == SImode
7984 || GET_MODE (operands[0]) == DImode
7985 || GET_MODE (operands[0]) == HImode
7986 || GET_MODE (operands[0]) == QImode)"
7990 [(set (match_operand 0 "flags_reg_operand" "")
7991 (match_operator 1 "compare_operator"
7993 (match_operand 2 "nonimmediate_operand" "")
7994 (match_operand 3 "const_int_operand" "")
7995 (match_operand 4 "const_int_operand" ""))
7997 "ix86_match_ccmode (insn, CCNOmode)"
7998 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8000 rtx val = operands[2];
8001 HOST_WIDE_INT len = INTVAL (operands[3]);
8002 HOST_WIDE_INT pos = INTVAL (operands[4]);
8004 enum machine_mode mode, submode;
8006 mode = GET_MODE (val);
8009 /* ??? Combine likes to put non-volatile mem extractions in QImode
8010 no matter the size of the test. So find a mode that works. */
8011 if (! MEM_VOLATILE_P (val))
8013 mode = smallest_mode_for_size (pos + len, MODE_INT);
8014 val = adjust_address (val, mode, 0);
8017 else if (GET_CODE (val) == SUBREG
8018 && (submode = GET_MODE (SUBREG_REG (val)),
8019 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8020 && pos + len <= GET_MODE_BITSIZE (submode))
8022 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8024 val = SUBREG_REG (val);
8026 else if (mode == HImode && pos + len <= 8)
8028 /* Small HImode tests can be converted to QImode. */
8030 val = gen_lowpart (QImode, val);
8033 if (len == HOST_BITS_PER_WIDE_INT)
8036 mask = ((HOST_WIDE_INT)1 << len) - 1;
8039 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8042 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8043 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8044 ;; this is relatively important trick.
8045 ;; Do the conversion only post-reload to avoid limiting of the register class
8048 [(set (match_operand 0 "flags_reg_operand" "")
8049 (match_operator 1 "compare_operator"
8050 [(and (match_operand 2 "register_operand" "")
8051 (match_operand 3 "const_int_operand" ""))
8054 && QI_REG_P (operands[2])
8055 && GET_MODE (operands[2]) != QImode
8056 && ((ix86_match_ccmode (insn, CCZmode)
8057 && !(INTVAL (operands[3]) & ~(255 << 8)))
8058 || (ix86_match_ccmode (insn, CCNOmode)
8059 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8062 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8065 "operands[2] = gen_lowpart (SImode, operands[2]);
8066 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8069 [(set (match_operand 0 "flags_reg_operand" "")
8070 (match_operator 1 "compare_operator"
8071 [(and (match_operand 2 "nonimmediate_operand" "")
8072 (match_operand 3 "const_int_operand" ""))
8075 && GET_MODE (operands[2]) != QImode
8076 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8077 && ((ix86_match_ccmode (insn, CCZmode)
8078 && !(INTVAL (operands[3]) & ~255))
8079 || (ix86_match_ccmode (insn, CCNOmode)
8080 && !(INTVAL (operands[3]) & ~127)))"
8082 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8084 "operands[2] = gen_lowpart (QImode, operands[2]);
8085 operands[3] = gen_lowpart (QImode, operands[3]);")
8088 ;; %%% This used to optimize known byte-wide and operations to memory,
8089 ;; and sometimes to QImode registers. If this is considered useful,
8090 ;; it should be done with splitters.
8092 (define_expand "anddi3"
8093 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8094 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8095 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8096 (clobber (reg:CC FLAGS_REG))]
8098 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8100 (define_insn "*anddi_1_rex64"
8101 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8102 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8103 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8104 (clobber (reg:CC FLAGS_REG))]
8105 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8107 switch (get_attr_type (insn))
8111 enum machine_mode mode;
8113 gcc_assert (CONST_INT_P (operands[2]));
8114 if (INTVAL (operands[2]) == 0xff)
8118 gcc_assert (INTVAL (operands[2]) == 0xffff);
8122 operands[1] = gen_lowpart (mode, operands[1]);
8124 return "movz{bq|x}\t{%1,%0|%0, %1}";
8126 return "movz{wq|x}\t{%1,%0|%0, %1}";
8130 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8131 if (get_attr_mode (insn) == MODE_SI)
8132 return "and{l}\t{%k2, %k0|%k0, %k2}";
8134 return "and{q}\t{%2, %0|%0, %2}";
8137 [(set_attr "type" "alu,alu,alu,imovx")
8138 (set_attr "length_immediate" "*,*,*,0")
8139 (set_attr "mode" "SI,DI,DI,DI")])
8141 (define_insn "*anddi_2"
8142 [(set (reg FLAGS_REG)
8143 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8144 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8146 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8147 (and:DI (match_dup 1) (match_dup 2)))]
8148 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8149 && ix86_binary_operator_ok (AND, DImode, operands)"
8151 and{l}\t{%k2, %k0|%k0, %k2}
8152 and{q}\t{%2, %0|%0, %2}
8153 and{q}\t{%2, %0|%0, %2}"
8154 [(set_attr "type" "alu")
8155 (set_attr "mode" "SI,DI,DI")])
8157 (define_expand "andsi3"
8158 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8159 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8160 (match_operand:SI 2 "general_operand" "")))
8161 (clobber (reg:CC FLAGS_REG))]
8163 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8165 (define_insn "*andsi_1"
8166 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8167 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8168 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8169 (clobber (reg:CC FLAGS_REG))]
8170 "ix86_binary_operator_ok (AND, SImode, operands)"
8172 switch (get_attr_type (insn))
8176 enum machine_mode mode;
8178 gcc_assert (CONST_INT_P (operands[2]));
8179 if (INTVAL (operands[2]) == 0xff)
8183 gcc_assert (INTVAL (operands[2]) == 0xffff);
8187 operands[1] = gen_lowpart (mode, operands[1]);
8189 return "movz{bl|x}\t{%1,%0|%0, %1}";
8191 return "movz{wl|x}\t{%1,%0|%0, %1}";
8195 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8196 return "and{l}\t{%2, %0|%0, %2}";
8199 [(set_attr "type" "alu,alu,imovx")
8200 (set_attr "length_immediate" "*,*,0")
8201 (set_attr "mode" "SI")])
8204 [(set (match_operand 0 "register_operand" "")
8206 (const_int -65536)))
8207 (clobber (reg:CC FLAGS_REG))]
8208 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8209 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8210 "operands[1] = gen_lowpart (HImode, operands[0]);")
8213 [(set (match_operand 0 "ext_register_operand" "")
8216 (clobber (reg:CC FLAGS_REG))]
8217 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8218 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8219 "operands[1] = gen_lowpart (QImode, operands[0]);")
8222 [(set (match_operand 0 "ext_register_operand" "")
8224 (const_int -65281)))
8225 (clobber (reg:CC FLAGS_REG))]
8226 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8227 [(parallel [(set (zero_extract:SI (match_dup 0)
8231 (zero_extract:SI (match_dup 0)
8234 (zero_extract:SI (match_dup 0)
8237 (clobber (reg:CC FLAGS_REG))])]
8238 "operands[0] = gen_lowpart (SImode, operands[0]);")
8240 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8241 (define_insn "*andsi_1_zext"
8242 [(set (match_operand:DI 0 "register_operand" "=r")
8244 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8245 (match_operand:SI 2 "general_operand" "rim"))))
8246 (clobber (reg:CC FLAGS_REG))]
8247 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8248 "and{l}\t{%2, %k0|%k0, %2}"
8249 [(set_attr "type" "alu")
8250 (set_attr "mode" "SI")])
8252 (define_insn "*andsi_2"
8253 [(set (reg FLAGS_REG)
8254 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8255 (match_operand:SI 2 "general_operand" "rim,ri"))
8257 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8258 (and:SI (match_dup 1) (match_dup 2)))]
8259 "ix86_match_ccmode (insn, CCNOmode)
8260 && ix86_binary_operator_ok (AND, SImode, operands)"
8261 "and{l}\t{%2, %0|%0, %2}"
8262 [(set_attr "type" "alu")
8263 (set_attr "mode" "SI")])
8265 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8266 (define_insn "*andsi_2_zext"
8267 [(set (reg FLAGS_REG)
8268 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8269 (match_operand:SI 2 "general_operand" "rim"))
8271 (set (match_operand:DI 0 "register_operand" "=r")
8272 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8273 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8274 && ix86_binary_operator_ok (AND, SImode, operands)"
8275 "and{l}\t{%2, %k0|%k0, %2}"
8276 [(set_attr "type" "alu")
8277 (set_attr "mode" "SI")])
8279 (define_expand "andhi3"
8280 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8281 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8282 (match_operand:HI 2 "general_operand" "")))
8283 (clobber (reg:CC FLAGS_REG))]
8284 "TARGET_HIMODE_MATH"
8285 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8287 (define_insn "*andhi_1"
8288 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8289 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8290 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8291 (clobber (reg:CC FLAGS_REG))]
8292 "ix86_binary_operator_ok (AND, HImode, operands)"
8294 switch (get_attr_type (insn))
8297 gcc_assert (CONST_INT_P (operands[2]));
8298 gcc_assert (INTVAL (operands[2]) == 0xff);
8299 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8302 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8304 return "and{w}\t{%2, %0|%0, %2}";
8307 [(set_attr "type" "alu,alu,imovx")
8308 (set_attr "length_immediate" "*,*,0")
8309 (set_attr "mode" "HI,HI,SI")])
8311 (define_insn "*andhi_2"
8312 [(set (reg FLAGS_REG)
8313 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8314 (match_operand:HI 2 "general_operand" "rim,ri"))
8316 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8317 (and:HI (match_dup 1) (match_dup 2)))]
8318 "ix86_match_ccmode (insn, CCNOmode)
8319 && ix86_binary_operator_ok (AND, HImode, operands)"
8320 "and{w}\t{%2, %0|%0, %2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "mode" "HI")])
8324 (define_expand "andqi3"
8325 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8326 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8327 (match_operand:QI 2 "general_operand" "")))
8328 (clobber (reg:CC FLAGS_REG))]
8329 "TARGET_QIMODE_MATH"
8330 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8332 ;; %%% Potential partial reg stall on alternative 2. What to do?
8333 (define_insn "*andqi_1"
8334 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8335 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8336 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8337 (clobber (reg:CC FLAGS_REG))]
8338 "ix86_binary_operator_ok (AND, QImode, operands)"
8340 and{b}\t{%2, %0|%0, %2}
8341 and{b}\t{%2, %0|%0, %2}
8342 and{l}\t{%k2, %k0|%k0, %k2}"
8343 [(set_attr "type" "alu")
8344 (set_attr "mode" "QI,QI,SI")])
8346 (define_insn "*andqi_1_slp"
8347 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8348 (and:QI (match_dup 0)
8349 (match_operand:QI 1 "general_operand" "qi,qmi")))
8350 (clobber (reg:CC FLAGS_REG))]
8351 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8352 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8353 "and{b}\t{%1, %0|%0, %1}"
8354 [(set_attr "type" "alu1")
8355 (set_attr "mode" "QI")])
8357 (define_insn "*andqi_2_maybe_si"
8358 [(set (reg FLAGS_REG)
8360 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8361 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8363 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8364 (and:QI (match_dup 1) (match_dup 2)))]
8365 "ix86_binary_operator_ok (AND, QImode, operands)
8366 && ix86_match_ccmode (insn,
8367 CONST_INT_P (operands[2])
8368 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8370 if (which_alternative == 2)
8372 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8373 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8374 return "and{l}\t{%2, %k0|%k0, %2}";
8376 return "and{b}\t{%2, %0|%0, %2}";
8378 [(set_attr "type" "alu")
8379 (set_attr "mode" "QI,QI,SI")])
8381 (define_insn "*andqi_2"
8382 [(set (reg FLAGS_REG)
8384 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8385 (match_operand:QI 2 "general_operand" "qim,qi"))
8387 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8388 (and:QI (match_dup 1) (match_dup 2)))]
8389 "ix86_match_ccmode (insn, CCNOmode)
8390 && ix86_binary_operator_ok (AND, QImode, operands)"
8391 "and{b}\t{%2, %0|%0, %2}"
8392 [(set_attr "type" "alu")
8393 (set_attr "mode" "QI")])
8395 (define_insn "*andqi_2_slp"
8396 [(set (reg FLAGS_REG)
8398 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8399 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8401 (set (strict_low_part (match_dup 0))
8402 (and:QI (match_dup 0) (match_dup 1)))]
8403 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8404 && ix86_match_ccmode (insn, CCNOmode)
8405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8406 "and{b}\t{%1, %0|%0, %1}"
8407 [(set_attr "type" "alu1")
8408 (set_attr "mode" "QI")])
8410 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8411 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8412 ;; for a QImode operand, which of course failed.
8414 (define_insn "andqi_ext_0"
8415 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8420 (match_operand 1 "ext_register_operand" "0")
8423 (match_operand 2 "const_int_operand" "n")))
8424 (clobber (reg:CC FLAGS_REG))]
8426 "and{b}\t{%2, %h0|%h0, %2}"
8427 [(set_attr "type" "alu")
8428 (set_attr "length_immediate" "1")
8429 (set_attr "mode" "QI")])
8431 ;; Generated by peephole translating test to and. This shows up
8432 ;; often in fp comparisons.
8434 (define_insn "*andqi_ext_0_cc"
8435 [(set (reg FLAGS_REG)
8439 (match_operand 1 "ext_register_operand" "0")
8442 (match_operand 2 "const_int_operand" "n"))
8444 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8453 "ix86_match_ccmode (insn, CCNOmode)"
8454 "and{b}\t{%2, %h0|%h0, %2}"
8455 [(set_attr "type" "alu")
8456 (set_attr "length_immediate" "1")
8457 (set_attr "mode" "QI")])
8459 (define_insn "*andqi_ext_1"
8460 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8465 (match_operand 1 "ext_register_operand" "0")
8469 (match_operand:QI 2 "general_operand" "Qm"))))
8470 (clobber (reg:CC FLAGS_REG))]
8472 "and{b}\t{%2, %h0|%h0, %2}"
8473 [(set_attr "type" "alu")
8474 (set_attr "length_immediate" "0")
8475 (set_attr "mode" "QI")])
8477 (define_insn "*andqi_ext_1_rex64"
8478 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8483 (match_operand 1 "ext_register_operand" "0")
8487 (match_operand 2 "ext_register_operand" "Q"))))
8488 (clobber (reg:CC FLAGS_REG))]
8490 "and{b}\t{%2, %h0|%h0, %2}"
8491 [(set_attr "type" "alu")
8492 (set_attr "length_immediate" "0")
8493 (set_attr "mode" "QI")])
8495 (define_insn "*andqi_ext_2"
8496 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8501 (match_operand 1 "ext_register_operand" "%0")
8505 (match_operand 2 "ext_register_operand" "Q")
8508 (clobber (reg:CC FLAGS_REG))]
8510 "and{b}\t{%h2, %h0|%h0, %h2}"
8511 [(set_attr "type" "alu")
8512 (set_attr "length_immediate" "0")
8513 (set_attr "mode" "QI")])
8515 ;; Convert wide AND instructions with immediate operand to shorter QImode
8516 ;; equivalents when possible.
8517 ;; Don't do the splitting with memory operands, since it introduces risk
8518 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8519 ;; for size, but that can (should?) be handled by generic code instead.
8521 [(set (match_operand 0 "register_operand" "")
8522 (and (match_operand 1 "register_operand" "")
8523 (match_operand 2 "const_int_operand" "")))
8524 (clobber (reg:CC FLAGS_REG))]
8526 && QI_REG_P (operands[0])
8527 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8528 && !(~INTVAL (operands[2]) & ~(255 << 8))
8529 && GET_MODE (operands[0]) != QImode"
8530 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8531 (and:SI (zero_extract:SI (match_dup 1)
8532 (const_int 8) (const_int 8))
8534 (clobber (reg:CC FLAGS_REG))])]
8535 "operands[0] = gen_lowpart (SImode, operands[0]);
8536 operands[1] = gen_lowpart (SImode, operands[1]);
8537 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8539 ;; Since AND can be encoded with sign extended immediate, this is only
8540 ;; profitable when 7th bit is not set.
8542 [(set (match_operand 0 "register_operand" "")
8543 (and (match_operand 1 "general_operand" "")
8544 (match_operand 2 "const_int_operand" "")))
8545 (clobber (reg:CC FLAGS_REG))]
8547 && ANY_QI_REG_P (operands[0])
8548 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8549 && !(~INTVAL (operands[2]) & ~255)
8550 && !(INTVAL (operands[2]) & 128)
8551 && GET_MODE (operands[0]) != QImode"
8552 [(parallel [(set (strict_low_part (match_dup 0))
8553 (and:QI (match_dup 1)
8555 (clobber (reg:CC FLAGS_REG))])]
8556 "operands[0] = gen_lowpart (QImode, operands[0]);
8557 operands[1] = gen_lowpart (QImode, operands[1]);
8558 operands[2] = gen_lowpart (QImode, operands[2]);")
8560 ;; Logical inclusive OR instructions
8562 ;; %%% This used to optimize known byte-wide and operations to memory.
8563 ;; If this is considered useful, it should be done with splitters.
8565 (define_expand "iordi3"
8566 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8567 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8568 (match_operand:DI 2 "x86_64_general_operand" "")))
8569 (clobber (reg:CC FLAGS_REG))]
8571 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8573 (define_insn "*iordi_1_rex64"
8574 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8575 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8576 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8577 (clobber (reg:CC FLAGS_REG))]
8579 && ix86_binary_operator_ok (IOR, DImode, operands)"
8580 "or{q}\t{%2, %0|%0, %2}"
8581 [(set_attr "type" "alu")
8582 (set_attr "mode" "DI")])
8584 (define_insn "*iordi_2_rex64"
8585 [(set (reg FLAGS_REG)
8586 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8587 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8589 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8590 (ior:DI (match_dup 1) (match_dup 2)))]
8592 && ix86_match_ccmode (insn, CCNOmode)
8593 && ix86_binary_operator_ok (IOR, DImode, operands)"
8594 "or{q}\t{%2, %0|%0, %2}"
8595 [(set_attr "type" "alu")
8596 (set_attr "mode" "DI")])
8598 (define_insn "*iordi_3_rex64"
8599 [(set (reg FLAGS_REG)
8600 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8601 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8603 (clobber (match_scratch:DI 0 "=r"))]
8605 && ix86_match_ccmode (insn, CCNOmode)
8606 && ix86_binary_operator_ok (IOR, DImode, operands)"
8607 "or{q}\t{%2, %0|%0, %2}"
8608 [(set_attr "type" "alu")
8609 (set_attr "mode" "DI")])
8612 (define_expand "iorsi3"
8613 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8614 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8615 (match_operand:SI 2 "general_operand" "")))
8616 (clobber (reg:CC FLAGS_REG))]
8618 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8620 (define_insn "*iorsi_1"
8621 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8622 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8623 (match_operand:SI 2 "general_operand" "ri,rmi")))
8624 (clobber (reg:CC FLAGS_REG))]
8625 "ix86_binary_operator_ok (IOR, SImode, operands)"
8626 "or{l}\t{%2, %0|%0, %2}"
8627 [(set_attr "type" "alu")
8628 (set_attr "mode" "SI")])
8630 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8631 (define_insn "*iorsi_1_zext"
8632 [(set (match_operand:DI 0 "register_operand" "=rm")
8634 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8635 (match_operand:SI 2 "general_operand" "rim"))))
8636 (clobber (reg:CC FLAGS_REG))]
8637 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8638 "or{l}\t{%2, %k0|%k0, %2}"
8639 [(set_attr "type" "alu")
8640 (set_attr "mode" "SI")])
8642 (define_insn "*iorsi_1_zext_imm"
8643 [(set (match_operand:DI 0 "register_operand" "=rm")
8644 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8645 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8646 (clobber (reg:CC FLAGS_REG))]
8648 "or{l}\t{%2, %k0|%k0, %2}"
8649 [(set_attr "type" "alu")
8650 (set_attr "mode" "SI")])
8652 (define_insn "*iorsi_2"
8653 [(set (reg FLAGS_REG)
8654 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8655 (match_operand:SI 2 "general_operand" "rim,ri"))
8657 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8658 (ior:SI (match_dup 1) (match_dup 2)))]
8659 "ix86_match_ccmode (insn, CCNOmode)
8660 && ix86_binary_operator_ok (IOR, SImode, operands)"
8661 "or{l}\t{%2, %0|%0, %2}"
8662 [(set_attr "type" "alu")
8663 (set_attr "mode" "SI")])
8665 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8666 ;; ??? Special case for immediate operand is missing - it is tricky.
8667 (define_insn "*iorsi_2_zext"
8668 [(set (reg FLAGS_REG)
8669 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8670 (match_operand:SI 2 "general_operand" "rim"))
8672 (set (match_operand:DI 0 "register_operand" "=r")
8673 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8674 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8675 && ix86_binary_operator_ok (IOR, SImode, operands)"
8676 "or{l}\t{%2, %k0|%k0, %2}"
8677 [(set_attr "type" "alu")
8678 (set_attr "mode" "SI")])
8680 (define_insn "*iorsi_2_zext_imm"
8681 [(set (reg FLAGS_REG)
8682 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8683 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8685 (set (match_operand:DI 0 "register_operand" "=r")
8686 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8687 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8688 && ix86_binary_operator_ok (IOR, SImode, operands)"
8689 "or{l}\t{%2, %k0|%k0, %2}"
8690 [(set_attr "type" "alu")
8691 (set_attr "mode" "SI")])
8693 (define_insn "*iorsi_3"
8694 [(set (reg FLAGS_REG)
8695 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8696 (match_operand:SI 2 "general_operand" "rim"))
8698 (clobber (match_scratch:SI 0 "=r"))]
8699 "ix86_match_ccmode (insn, CCNOmode)
8700 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8701 "or{l}\t{%2, %0|%0, %2}"
8702 [(set_attr "type" "alu")
8703 (set_attr "mode" "SI")])
8705 (define_expand "iorhi3"
8706 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8707 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8708 (match_operand:HI 2 "general_operand" "")))
8709 (clobber (reg:CC FLAGS_REG))]
8710 "TARGET_HIMODE_MATH"
8711 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8713 (define_insn "*iorhi_1"
8714 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8715 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8716 (match_operand:HI 2 "general_operand" "rmi,ri")))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "ix86_binary_operator_ok (IOR, HImode, operands)"
8719 "or{w}\t{%2, %0|%0, %2}"
8720 [(set_attr "type" "alu")
8721 (set_attr "mode" "HI")])
8723 (define_insn "*iorhi_2"
8724 [(set (reg FLAGS_REG)
8725 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8726 (match_operand:HI 2 "general_operand" "rim,ri"))
8728 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8729 (ior:HI (match_dup 1) (match_dup 2)))]
8730 "ix86_match_ccmode (insn, CCNOmode)
8731 && ix86_binary_operator_ok (IOR, HImode, operands)"
8732 "or{w}\t{%2, %0|%0, %2}"
8733 [(set_attr "type" "alu")
8734 (set_attr "mode" "HI")])
8736 (define_insn "*iorhi_3"
8737 [(set (reg FLAGS_REG)
8738 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8739 (match_operand:HI 2 "general_operand" "rim"))
8741 (clobber (match_scratch:HI 0 "=r"))]
8742 "ix86_match_ccmode (insn, CCNOmode)
8743 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8744 "or{w}\t{%2, %0|%0, %2}"
8745 [(set_attr "type" "alu")
8746 (set_attr "mode" "HI")])
8748 (define_expand "iorqi3"
8749 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8750 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8751 (match_operand:QI 2 "general_operand" "")))
8752 (clobber (reg:CC FLAGS_REG))]
8753 "TARGET_QIMODE_MATH"
8754 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8756 ;; %%% Potential partial reg stall on alternative 2. What to do?
8757 (define_insn "*iorqi_1"
8758 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8759 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8760 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8761 (clobber (reg:CC FLAGS_REG))]
8762 "ix86_binary_operator_ok (IOR, QImode, operands)"
8764 or{b}\t{%2, %0|%0, %2}
8765 or{b}\t{%2, %0|%0, %2}
8766 or{l}\t{%k2, %k0|%k0, %k2}"
8767 [(set_attr "type" "alu")
8768 (set_attr "mode" "QI,QI,SI")])
8770 (define_insn "*iorqi_1_slp"
8771 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8772 (ior:QI (match_dup 0)
8773 (match_operand:QI 1 "general_operand" "qmi,qi")))
8774 (clobber (reg:CC FLAGS_REG))]
8775 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8776 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8777 "or{b}\t{%1, %0|%0, %1}"
8778 [(set_attr "type" "alu1")
8779 (set_attr "mode" "QI")])
8781 (define_insn "*iorqi_2"
8782 [(set (reg FLAGS_REG)
8783 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8784 (match_operand:QI 2 "general_operand" "qim,qi"))
8786 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8787 (ior:QI (match_dup 1) (match_dup 2)))]
8788 "ix86_match_ccmode (insn, CCNOmode)
8789 && ix86_binary_operator_ok (IOR, QImode, operands)"
8790 "or{b}\t{%2, %0|%0, %2}"
8791 [(set_attr "type" "alu")
8792 (set_attr "mode" "QI")])
8794 (define_insn "*iorqi_2_slp"
8795 [(set (reg FLAGS_REG)
8796 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8797 (match_operand:QI 1 "general_operand" "qim,qi"))
8799 (set (strict_low_part (match_dup 0))
8800 (ior:QI (match_dup 0) (match_dup 1)))]
8801 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8802 && ix86_match_ccmode (insn, CCNOmode)
8803 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8804 "or{b}\t{%1, %0|%0, %1}"
8805 [(set_attr "type" "alu1")
8806 (set_attr "mode" "QI")])
8808 (define_insn "*iorqi_3"
8809 [(set (reg FLAGS_REG)
8810 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8811 (match_operand:QI 2 "general_operand" "qim"))
8813 (clobber (match_scratch:QI 0 "=q"))]
8814 "ix86_match_ccmode (insn, CCNOmode)
8815 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8816 "or{b}\t{%2, %0|%0, %2}"
8817 [(set_attr "type" "alu")
8818 (set_attr "mode" "QI")])
8820 (define_insn "iorqi_ext_0"
8821 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8826 (match_operand 1 "ext_register_operand" "0")
8829 (match_operand 2 "const_int_operand" "n")))
8830 (clobber (reg:CC FLAGS_REG))]
8831 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8832 "or{b}\t{%2, %h0|%h0, %2}"
8833 [(set_attr "type" "alu")
8834 (set_attr "length_immediate" "1")
8835 (set_attr "mode" "QI")])
8837 (define_insn "*iorqi_ext_1"
8838 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8843 (match_operand 1 "ext_register_operand" "0")
8847 (match_operand:QI 2 "general_operand" "Qm"))))
8848 (clobber (reg:CC FLAGS_REG))]
8850 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8851 "or{b}\t{%2, %h0|%h0, %2}"
8852 [(set_attr "type" "alu")
8853 (set_attr "length_immediate" "0")
8854 (set_attr "mode" "QI")])
8856 (define_insn "*iorqi_ext_1_rex64"
8857 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8862 (match_operand 1 "ext_register_operand" "0")
8866 (match_operand 2 "ext_register_operand" "Q"))))
8867 (clobber (reg:CC FLAGS_REG))]
8869 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8870 "or{b}\t{%2, %h0|%h0, %2}"
8871 [(set_attr "type" "alu")
8872 (set_attr "length_immediate" "0")
8873 (set_attr "mode" "QI")])
8875 (define_insn "*iorqi_ext_2"
8876 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8880 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8883 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8886 (clobber (reg:CC FLAGS_REG))]
8887 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8888 "ior{b}\t{%h2, %h0|%h0, %h2}"
8889 [(set_attr "type" "alu")
8890 (set_attr "length_immediate" "0")
8891 (set_attr "mode" "QI")])
8894 [(set (match_operand 0 "register_operand" "")
8895 (ior (match_operand 1 "register_operand" "")
8896 (match_operand 2 "const_int_operand" "")))
8897 (clobber (reg:CC FLAGS_REG))]
8899 && QI_REG_P (operands[0])
8900 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8901 && !(INTVAL (operands[2]) & ~(255 << 8))
8902 && GET_MODE (operands[0]) != QImode"
8903 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8904 (ior:SI (zero_extract:SI (match_dup 1)
8905 (const_int 8) (const_int 8))
8907 (clobber (reg:CC FLAGS_REG))])]
8908 "operands[0] = gen_lowpart (SImode, operands[0]);
8909 operands[1] = gen_lowpart (SImode, operands[1]);
8910 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8912 ;; Since OR can be encoded with sign extended immediate, this is only
8913 ;; profitable when 7th bit is set.
8915 [(set (match_operand 0 "register_operand" "")
8916 (ior (match_operand 1 "general_operand" "")
8917 (match_operand 2 "const_int_operand" "")))
8918 (clobber (reg:CC FLAGS_REG))]
8920 && ANY_QI_REG_P (operands[0])
8921 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8922 && !(INTVAL (operands[2]) & ~255)
8923 && (INTVAL (operands[2]) & 128)
8924 && GET_MODE (operands[0]) != QImode"
8925 [(parallel [(set (strict_low_part (match_dup 0))
8926 (ior:QI (match_dup 1)
8928 (clobber (reg:CC FLAGS_REG))])]
8929 "operands[0] = gen_lowpart (QImode, operands[0]);
8930 operands[1] = gen_lowpart (QImode, operands[1]);
8931 operands[2] = gen_lowpart (QImode, operands[2]);")
8933 ;; Logical XOR instructions
8935 ;; %%% This used to optimize known byte-wide and operations to memory.
8936 ;; If this is considered useful, it should be done with splitters.
8938 (define_expand "xordi3"
8939 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8940 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8941 (match_operand:DI 2 "x86_64_general_operand" "")))
8942 (clobber (reg:CC FLAGS_REG))]
8944 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8946 (define_insn "*xordi_1_rex64"
8947 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8948 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8949 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8950 (clobber (reg:CC FLAGS_REG))]
8952 && ix86_binary_operator_ok (XOR, DImode, operands)"
8954 xor{q}\t{%2, %0|%0, %2}
8955 xor{q}\t{%2, %0|%0, %2}"
8956 [(set_attr "type" "alu")
8957 (set_attr "mode" "DI,DI")])
8959 (define_insn "*xordi_2_rex64"
8960 [(set (reg FLAGS_REG)
8961 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8962 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8964 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8965 (xor:DI (match_dup 1) (match_dup 2)))]
8967 && ix86_match_ccmode (insn, CCNOmode)
8968 && ix86_binary_operator_ok (XOR, DImode, operands)"
8970 xor{q}\t{%2, %0|%0, %2}
8971 xor{q}\t{%2, %0|%0, %2}"
8972 [(set_attr "type" "alu")
8973 (set_attr "mode" "DI,DI")])
8975 (define_insn "*xordi_3_rex64"
8976 [(set (reg FLAGS_REG)
8977 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8978 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8980 (clobber (match_scratch:DI 0 "=r"))]
8982 && ix86_match_ccmode (insn, CCNOmode)
8983 && ix86_binary_operator_ok (XOR, DImode, operands)"
8984 "xor{q}\t{%2, %0|%0, %2}"
8985 [(set_attr "type" "alu")
8986 (set_attr "mode" "DI")])
8988 (define_expand "xorsi3"
8989 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8990 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8991 (match_operand:SI 2 "general_operand" "")))
8992 (clobber (reg:CC FLAGS_REG))]
8994 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8996 (define_insn "*xorsi_1"
8997 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8998 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8999 (match_operand:SI 2 "general_operand" "ri,rm")))
9000 (clobber (reg:CC FLAGS_REG))]
9001 "ix86_binary_operator_ok (XOR, SImode, operands)"
9002 "xor{l}\t{%2, %0|%0, %2}"
9003 [(set_attr "type" "alu")
9004 (set_attr "mode" "SI")])
9006 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9007 ;; Add speccase for immediates
9008 (define_insn "*xorsi_1_zext"
9009 [(set (match_operand:DI 0 "register_operand" "=r")
9011 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9012 (match_operand:SI 2 "general_operand" "rim"))))
9013 (clobber (reg:CC FLAGS_REG))]
9014 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9015 "xor{l}\t{%2, %k0|%k0, %2}"
9016 [(set_attr "type" "alu")
9017 (set_attr "mode" "SI")])
9019 (define_insn "*xorsi_1_zext_imm"
9020 [(set (match_operand:DI 0 "register_operand" "=r")
9021 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9022 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9023 (clobber (reg:CC FLAGS_REG))]
9024 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9025 "xor{l}\t{%2, %k0|%k0, %2}"
9026 [(set_attr "type" "alu")
9027 (set_attr "mode" "SI")])
9029 (define_insn "*xorsi_2"
9030 [(set (reg FLAGS_REG)
9031 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9032 (match_operand:SI 2 "general_operand" "rim,ri"))
9034 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9035 (xor:SI (match_dup 1) (match_dup 2)))]
9036 "ix86_match_ccmode (insn, CCNOmode)
9037 && ix86_binary_operator_ok (XOR, SImode, operands)"
9038 "xor{l}\t{%2, %0|%0, %2}"
9039 [(set_attr "type" "alu")
9040 (set_attr "mode" "SI")])
9042 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9043 ;; ??? Special case for immediate operand is missing - it is tricky.
9044 (define_insn "*xorsi_2_zext"
9045 [(set (reg FLAGS_REG)
9046 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9047 (match_operand:SI 2 "general_operand" "rim"))
9049 (set (match_operand:DI 0 "register_operand" "=r")
9050 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9051 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9052 && ix86_binary_operator_ok (XOR, SImode, operands)"
9053 "xor{l}\t{%2, %k0|%k0, %2}"
9054 [(set_attr "type" "alu")
9055 (set_attr "mode" "SI")])
9057 (define_insn "*xorsi_2_zext_imm"
9058 [(set (reg FLAGS_REG)
9059 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9060 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9062 (set (match_operand:DI 0 "register_operand" "=r")
9063 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9064 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9065 && ix86_binary_operator_ok (XOR, SImode, operands)"
9066 "xor{l}\t{%2, %k0|%k0, %2}"
9067 [(set_attr "type" "alu")
9068 (set_attr "mode" "SI")])
9070 (define_insn "*xorsi_3"
9071 [(set (reg FLAGS_REG)
9072 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9073 (match_operand:SI 2 "general_operand" "rim"))
9075 (clobber (match_scratch:SI 0 "=r"))]
9076 "ix86_match_ccmode (insn, CCNOmode)
9077 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9078 "xor{l}\t{%2, %0|%0, %2}"
9079 [(set_attr "type" "alu")
9080 (set_attr "mode" "SI")])
9082 (define_expand "xorhi3"
9083 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9084 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9085 (match_operand:HI 2 "general_operand" "")))
9086 (clobber (reg:CC FLAGS_REG))]
9087 "TARGET_HIMODE_MATH"
9088 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9090 (define_insn "*xorhi_1"
9091 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9092 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9093 (match_operand:HI 2 "general_operand" "rmi,ri")))
9094 (clobber (reg:CC FLAGS_REG))]
9095 "ix86_binary_operator_ok (XOR, HImode, operands)"
9096 "xor{w}\t{%2, %0|%0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "HI")])
9100 (define_insn "*xorhi_2"
9101 [(set (reg FLAGS_REG)
9102 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9103 (match_operand:HI 2 "general_operand" "rim,ri"))
9105 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9106 (xor:HI (match_dup 1) (match_dup 2)))]
9107 "ix86_match_ccmode (insn, CCNOmode)
9108 && ix86_binary_operator_ok (XOR, HImode, operands)"
9109 "xor{w}\t{%2, %0|%0, %2}"
9110 [(set_attr "type" "alu")
9111 (set_attr "mode" "HI")])
9113 (define_insn "*xorhi_3"
9114 [(set (reg FLAGS_REG)
9115 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9116 (match_operand:HI 2 "general_operand" "rim"))
9118 (clobber (match_scratch:HI 0 "=r"))]
9119 "ix86_match_ccmode (insn, CCNOmode)
9120 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9121 "xor{w}\t{%2, %0|%0, %2}"
9122 [(set_attr "type" "alu")
9123 (set_attr "mode" "HI")])
9125 (define_expand "xorqi3"
9126 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9127 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9128 (match_operand:QI 2 "general_operand" "")))
9129 (clobber (reg:CC FLAGS_REG))]
9130 "TARGET_QIMODE_MATH"
9131 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9133 ;; %%% Potential partial reg stall on alternative 2. What to do?
9134 (define_insn "*xorqi_1"
9135 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9136 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9137 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9138 (clobber (reg:CC FLAGS_REG))]
9139 "ix86_binary_operator_ok (XOR, QImode, operands)"
9141 xor{b}\t{%2, %0|%0, %2}
9142 xor{b}\t{%2, %0|%0, %2}
9143 xor{l}\t{%k2, %k0|%k0, %k2}"
9144 [(set_attr "type" "alu")
9145 (set_attr "mode" "QI,QI,SI")])
9147 (define_insn "*xorqi_1_slp"
9148 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9149 (xor:QI (match_dup 0)
9150 (match_operand:QI 1 "general_operand" "qi,qmi")))
9151 (clobber (reg:CC FLAGS_REG))]
9152 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9153 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9154 "xor{b}\t{%1, %0|%0, %1}"
9155 [(set_attr "type" "alu1")
9156 (set_attr "mode" "QI")])
9158 (define_insn "xorqi_ext_0"
9159 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9164 (match_operand 1 "ext_register_operand" "0")
9167 (match_operand 2 "const_int_operand" "n")))
9168 (clobber (reg:CC FLAGS_REG))]
9169 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9170 "xor{b}\t{%2, %h0|%h0, %2}"
9171 [(set_attr "type" "alu")
9172 (set_attr "length_immediate" "1")
9173 (set_attr "mode" "QI")])
9175 (define_insn "*xorqi_ext_1"
9176 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9181 (match_operand 1 "ext_register_operand" "0")
9185 (match_operand:QI 2 "general_operand" "Qm"))))
9186 (clobber (reg:CC FLAGS_REG))]
9188 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9189 "xor{b}\t{%2, %h0|%h0, %2}"
9190 [(set_attr "type" "alu")
9191 (set_attr "length_immediate" "0")
9192 (set_attr "mode" "QI")])
9194 (define_insn "*xorqi_ext_1_rex64"
9195 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9200 (match_operand 1 "ext_register_operand" "0")
9204 (match_operand 2 "ext_register_operand" "Q"))))
9205 (clobber (reg:CC FLAGS_REG))]
9207 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9208 "xor{b}\t{%2, %h0|%h0, %2}"
9209 [(set_attr "type" "alu")
9210 (set_attr "length_immediate" "0")
9211 (set_attr "mode" "QI")])
9213 (define_insn "*xorqi_ext_2"
9214 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9218 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9221 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9224 (clobber (reg:CC FLAGS_REG))]
9225 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9226 "xor{b}\t{%h2, %h0|%h0, %h2}"
9227 [(set_attr "type" "alu")
9228 (set_attr "length_immediate" "0")
9229 (set_attr "mode" "QI")])
9231 (define_insn "*xorqi_cc_1"
9232 [(set (reg FLAGS_REG)
9234 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9235 (match_operand:QI 2 "general_operand" "qim,qi"))
9237 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9238 (xor:QI (match_dup 1) (match_dup 2)))]
9239 "ix86_match_ccmode (insn, CCNOmode)
9240 && ix86_binary_operator_ok (XOR, QImode, operands)"
9241 "xor{b}\t{%2, %0|%0, %2}"
9242 [(set_attr "type" "alu")
9243 (set_attr "mode" "QI")])
9245 (define_insn "*xorqi_2_slp"
9246 [(set (reg FLAGS_REG)
9247 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9248 (match_operand:QI 1 "general_operand" "qim,qi"))
9250 (set (strict_low_part (match_dup 0))
9251 (xor:QI (match_dup 0) (match_dup 1)))]
9252 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9253 && ix86_match_ccmode (insn, CCNOmode)
9254 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9255 "xor{b}\t{%1, %0|%0, %1}"
9256 [(set_attr "type" "alu1")
9257 (set_attr "mode" "QI")])
9259 (define_insn "*xorqi_cc_2"
9260 [(set (reg FLAGS_REG)
9262 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9263 (match_operand:QI 2 "general_operand" "qim"))
9265 (clobber (match_scratch:QI 0 "=q"))]
9266 "ix86_match_ccmode (insn, CCNOmode)
9267 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9268 "xor{b}\t{%2, %0|%0, %2}"
9269 [(set_attr "type" "alu")
9270 (set_attr "mode" "QI")])
9272 (define_insn "*xorqi_cc_ext_1"
9273 [(set (reg FLAGS_REG)
9277 (match_operand 1 "ext_register_operand" "0")
9280 (match_operand:QI 2 "general_operand" "qmn"))
9282 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9286 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9288 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9289 "xor{b}\t{%2, %h0|%h0, %2}"
9290 [(set_attr "type" "alu")
9291 (set_attr "mode" "QI")])
9293 (define_insn "*xorqi_cc_ext_1_rex64"
9294 [(set (reg FLAGS_REG)
9298 (match_operand 1 "ext_register_operand" "0")
9301 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9303 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9307 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9309 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9310 "xor{b}\t{%2, %h0|%h0, %2}"
9311 [(set_attr "type" "alu")
9312 (set_attr "mode" "QI")])
9314 (define_expand "xorqi_cc_ext_1"
9316 (set (reg:CCNO FLAGS_REG)
9320 (match_operand 1 "ext_register_operand" "")
9323 (match_operand:QI 2 "general_operand" ""))
9325 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9329 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9335 [(set (match_operand 0 "register_operand" "")
9336 (xor (match_operand 1 "register_operand" "")
9337 (match_operand 2 "const_int_operand" "")))
9338 (clobber (reg:CC FLAGS_REG))]
9340 && QI_REG_P (operands[0])
9341 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9342 && !(INTVAL (operands[2]) & ~(255 << 8))
9343 && GET_MODE (operands[0]) != QImode"
9344 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9345 (xor:SI (zero_extract:SI (match_dup 1)
9346 (const_int 8) (const_int 8))
9348 (clobber (reg:CC FLAGS_REG))])]
9349 "operands[0] = gen_lowpart (SImode, operands[0]);
9350 operands[1] = gen_lowpart (SImode, operands[1]);
9351 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9353 ;; Since XOR can be encoded with sign extended immediate, this is only
9354 ;; profitable when 7th bit is set.
9356 [(set (match_operand 0 "register_operand" "")
9357 (xor (match_operand 1 "general_operand" "")
9358 (match_operand 2 "const_int_operand" "")))
9359 (clobber (reg:CC FLAGS_REG))]
9361 && ANY_QI_REG_P (operands[0])
9362 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9363 && !(INTVAL (operands[2]) & ~255)
9364 && (INTVAL (operands[2]) & 128)
9365 && GET_MODE (operands[0]) != QImode"
9366 [(parallel [(set (strict_low_part (match_dup 0))
9367 (xor:QI (match_dup 1)
9369 (clobber (reg:CC FLAGS_REG))])]
9370 "operands[0] = gen_lowpart (QImode, operands[0]);
9371 operands[1] = gen_lowpart (QImode, operands[1]);
9372 operands[2] = gen_lowpart (QImode, operands[2]);")
9374 ;; Negation instructions
9376 (define_expand "negti2"
9377 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9378 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9379 (clobber (reg:CC FLAGS_REG))])]
9381 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9383 (define_insn "*negti2_1"
9384 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9385 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9386 (clobber (reg:CC FLAGS_REG))]
9388 && ix86_unary_operator_ok (NEG, TImode, operands)"
9392 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9393 (neg:TI (match_operand:TI 1 "general_operand" "")))
9394 (clobber (reg:CC FLAGS_REG))]
9395 "TARGET_64BIT && reload_completed"
9397 [(set (reg:CCZ FLAGS_REG)
9398 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9399 (set (match_dup 0) (neg:DI (match_dup 2)))])
9402 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9405 (clobber (reg:CC FLAGS_REG))])
9408 (neg:DI (match_dup 1)))
9409 (clobber (reg:CC FLAGS_REG))])]
9410 "split_ti (operands+1, 1, operands+2, operands+3);
9411 split_ti (operands+0, 1, operands+0, operands+1);")
9413 (define_expand "negdi2"
9414 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9415 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9416 (clobber (reg:CC FLAGS_REG))])]
9418 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9420 (define_insn "*negdi2_1"
9421 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9422 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9423 (clobber (reg:CC FLAGS_REG))]
9425 && ix86_unary_operator_ok (NEG, DImode, operands)"
9429 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9430 (neg:DI (match_operand:DI 1 "general_operand" "")))
9431 (clobber (reg:CC FLAGS_REG))]
9432 "!TARGET_64BIT && reload_completed"
9434 [(set (reg:CCZ FLAGS_REG)
9435 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9436 (set (match_dup 0) (neg:SI (match_dup 2)))])
9439 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9442 (clobber (reg:CC FLAGS_REG))])
9445 (neg:SI (match_dup 1)))
9446 (clobber (reg:CC FLAGS_REG))])]
9447 "split_di (operands+1, 1, operands+2, operands+3);
9448 split_di (operands+0, 1, operands+0, operands+1);")
9450 (define_insn "*negdi2_1_rex64"
9451 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9452 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9453 (clobber (reg:CC FLAGS_REG))]
9454 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9456 [(set_attr "type" "negnot")
9457 (set_attr "mode" "DI")])
9459 ;; The problem with neg is that it does not perform (compare x 0),
9460 ;; it really performs (compare 0 x), which leaves us with the zero
9461 ;; flag being the only useful item.
9463 (define_insn "*negdi2_cmpz_rex64"
9464 [(set (reg:CCZ FLAGS_REG)
9465 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9467 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9468 (neg:DI (match_dup 1)))]
9469 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9471 [(set_attr "type" "negnot")
9472 (set_attr "mode" "DI")])
9475 (define_expand "negsi2"
9476 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9477 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9478 (clobber (reg:CC FLAGS_REG))])]
9480 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9482 (define_insn "*negsi2_1"
9483 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9484 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9485 (clobber (reg:CC FLAGS_REG))]
9486 "ix86_unary_operator_ok (NEG, SImode, operands)"
9488 [(set_attr "type" "negnot")
9489 (set_attr "mode" "SI")])
9491 ;; Combine is quite creative about this pattern.
9492 (define_insn "*negsi2_1_zext"
9493 [(set (match_operand:DI 0 "register_operand" "=r")
9494 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9497 (clobber (reg:CC FLAGS_REG))]
9498 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9500 [(set_attr "type" "negnot")
9501 (set_attr "mode" "SI")])
9503 ;; The problem with neg is that it does not perform (compare x 0),
9504 ;; it really performs (compare 0 x), which leaves us with the zero
9505 ;; flag being the only useful item.
9507 (define_insn "*negsi2_cmpz"
9508 [(set (reg:CCZ FLAGS_REG)
9509 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9511 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9512 (neg:SI (match_dup 1)))]
9513 "ix86_unary_operator_ok (NEG, SImode, operands)"
9515 [(set_attr "type" "negnot")
9516 (set_attr "mode" "SI")])
9518 (define_insn "*negsi2_cmpz_zext"
9519 [(set (reg:CCZ FLAGS_REG)
9520 (compare:CCZ (lshiftrt:DI
9522 (match_operand:DI 1 "register_operand" "0")
9526 (set (match_operand:DI 0 "register_operand" "=r")
9527 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9530 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9532 [(set_attr "type" "negnot")
9533 (set_attr "mode" "SI")])
9535 (define_expand "neghi2"
9536 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9537 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9538 (clobber (reg:CC FLAGS_REG))])]
9539 "TARGET_HIMODE_MATH"
9540 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9542 (define_insn "*neghi2_1"
9543 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9544 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9545 (clobber (reg:CC FLAGS_REG))]
9546 "ix86_unary_operator_ok (NEG, HImode, operands)"
9548 [(set_attr "type" "negnot")
9549 (set_attr "mode" "HI")])
9551 (define_insn "*neghi2_cmpz"
9552 [(set (reg:CCZ FLAGS_REG)
9553 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9555 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9556 (neg:HI (match_dup 1)))]
9557 "ix86_unary_operator_ok (NEG, HImode, operands)"
9559 [(set_attr "type" "negnot")
9560 (set_attr "mode" "HI")])
9562 (define_expand "negqi2"
9563 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9564 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9565 (clobber (reg:CC FLAGS_REG))])]
9566 "TARGET_QIMODE_MATH"
9567 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9569 (define_insn "*negqi2_1"
9570 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9571 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9572 (clobber (reg:CC FLAGS_REG))]
9573 "ix86_unary_operator_ok (NEG, QImode, operands)"
9575 [(set_attr "type" "negnot")
9576 (set_attr "mode" "QI")])
9578 (define_insn "*negqi2_cmpz"
9579 [(set (reg:CCZ FLAGS_REG)
9580 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9582 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9583 (neg:QI (match_dup 1)))]
9584 "ix86_unary_operator_ok (NEG, QImode, operands)"
9586 [(set_attr "type" "negnot")
9587 (set_attr "mode" "QI")])
9589 ;; Changing of sign for FP values is doable using integer unit too.
9591 (define_expand "negsf2"
9592 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9593 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9594 "TARGET_80387 || TARGET_SSE_MATH"
9595 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9597 (define_expand "abssf2"
9598 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9599 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9600 "TARGET_80387 || TARGET_SSE_MATH"
9601 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9603 (define_insn "*absnegsf2_mixed"
9604 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9605 (match_operator:SF 3 "absneg_operator"
9606 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9607 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9608 (clobber (reg:CC FLAGS_REG))]
9609 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9610 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9613 (define_insn "*absnegsf2_sse"
9614 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9615 (match_operator:SF 3 "absneg_operator"
9616 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9617 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9618 (clobber (reg:CC FLAGS_REG))]
9620 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9623 (define_insn "*absnegsf2_i387"
9624 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9625 (match_operator:SF 3 "absneg_operator"
9626 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9627 (use (match_operand 2 "" ""))
9628 (clobber (reg:CC FLAGS_REG))]
9629 "TARGET_80387 && !TARGET_SSE_MATH
9630 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9633 (define_expand "copysignsf3"
9634 [(match_operand:SF 0 "register_operand" "")
9635 (match_operand:SF 1 "nonmemory_operand" "")
9636 (match_operand:SF 2 "register_operand" "")]
9639 ix86_expand_copysign (operands);
9643 (define_insn_and_split "copysignsf3_const"
9644 [(set (match_operand:SF 0 "register_operand" "=x")
9646 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9647 (match_operand:SF 2 "register_operand" "0")
9648 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9652 "&& reload_completed"
9655 ix86_split_copysign_const (operands);
9659 (define_insn "copysignsf3_var"
9660 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9662 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9663 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9664 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9665 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9667 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9672 [(set (match_operand:SF 0 "register_operand" "")
9674 [(match_operand:SF 2 "register_operand" "")
9675 (match_operand:SF 3 "register_operand" "")
9676 (match_operand:V4SF 4 "" "")
9677 (match_operand:V4SF 5 "" "")]
9679 (clobber (match_scratch:V4SF 1 ""))]
9680 "TARGET_SSE_MATH && reload_completed"
9683 ix86_split_copysign_var (operands);
9687 (define_expand "negdf2"
9688 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9689 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9690 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9691 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9693 (define_expand "absdf2"
9694 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9695 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9696 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9697 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9699 (define_insn "*absnegdf2_mixed"
9700 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9701 (match_operator:DF 3 "absneg_operator"
9702 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9703 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9704 (clobber (reg:CC FLAGS_REG))]
9705 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9706 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9709 (define_insn "*absnegdf2_sse"
9710 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9711 (match_operator:DF 3 "absneg_operator"
9712 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9713 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "TARGET_SSE2 && TARGET_SSE_MATH
9716 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9719 (define_insn "*absnegdf2_i387"
9720 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9721 (match_operator:DF 3 "absneg_operator"
9722 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9723 (use (match_operand 2 "" ""))
9724 (clobber (reg:CC FLAGS_REG))]
9725 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9726 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9729 (define_expand "copysigndf3"
9730 [(match_operand:DF 0 "register_operand" "")
9731 (match_operand:DF 1 "nonmemory_operand" "")
9732 (match_operand:DF 2 "register_operand" "")]
9733 "TARGET_SSE2 && TARGET_SSE_MATH"
9735 ix86_expand_copysign (operands);
9739 (define_insn_and_split "copysigndf3_const"
9740 [(set (match_operand:DF 0 "register_operand" "=x")
9742 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9743 (match_operand:DF 2 "register_operand" "0")
9744 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9746 "TARGET_SSE2 && TARGET_SSE_MATH"
9748 "&& reload_completed"
9751 ix86_split_copysign_const (operands);
9755 (define_insn "copysigndf3_var"
9756 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9758 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9759 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9760 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9761 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9763 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9764 "TARGET_SSE2 && TARGET_SSE_MATH"
9768 [(set (match_operand:DF 0 "register_operand" "")
9770 [(match_operand:DF 2 "register_operand" "")
9771 (match_operand:DF 3 "register_operand" "")
9772 (match_operand:V2DF 4 "" "")
9773 (match_operand:V2DF 5 "" "")]
9775 (clobber (match_scratch:V2DF 1 ""))]
9776 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9779 ix86_split_copysign_var (operands);
9783 (define_expand "negxf2"
9784 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9785 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9787 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9789 (define_expand "absxf2"
9790 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9791 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9793 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9795 (define_insn "*absnegxf2_i387"
9796 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9797 (match_operator:XF 3 "absneg_operator"
9798 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9799 (use (match_operand 2 "" ""))
9800 (clobber (reg:CC FLAGS_REG))]
9802 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9805 ;; Splitters for fp abs and neg.
9808 [(set (match_operand 0 "fp_register_operand" "")
9809 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9810 (use (match_operand 2 "" ""))
9811 (clobber (reg:CC FLAGS_REG))]
9813 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9816 [(set (match_operand 0 "register_operand" "")
9817 (match_operator 3 "absneg_operator"
9818 [(match_operand 1 "register_operand" "")]))
9819 (use (match_operand 2 "nonimmediate_operand" ""))
9820 (clobber (reg:CC FLAGS_REG))]
9821 "reload_completed && SSE_REG_P (operands[0])"
9822 [(set (match_dup 0) (match_dup 3))]
9824 enum machine_mode mode = GET_MODE (operands[0]);
9825 enum machine_mode vmode = GET_MODE (operands[2]);
9828 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9829 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9830 if (operands_match_p (operands[0], operands[2]))
9833 operands[1] = operands[2];
9836 if (GET_CODE (operands[3]) == ABS)
9837 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9839 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9844 [(set (match_operand:SF 0 "register_operand" "")
9845 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9846 (use (match_operand:V4SF 2 "" ""))
9847 (clobber (reg:CC FLAGS_REG))]
9849 [(parallel [(set (match_dup 0) (match_dup 1))
9850 (clobber (reg:CC FLAGS_REG))])]
9853 operands[0] = gen_lowpart (SImode, operands[0]);
9854 if (GET_CODE (operands[1]) == ABS)
9856 tmp = gen_int_mode (0x7fffffff, SImode);
9857 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9861 tmp = gen_int_mode (0x80000000, SImode);
9862 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9868 [(set (match_operand:DF 0 "register_operand" "")
9869 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9870 (use (match_operand 2 "" ""))
9871 (clobber (reg:CC FLAGS_REG))]
9873 [(parallel [(set (match_dup 0) (match_dup 1))
9874 (clobber (reg:CC FLAGS_REG))])]
9879 tmp = gen_lowpart (DImode, operands[0]);
9880 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9883 if (GET_CODE (operands[1]) == ABS)
9886 tmp = gen_rtx_NOT (DImode, tmp);
9890 operands[0] = gen_highpart (SImode, operands[0]);
9891 if (GET_CODE (operands[1]) == ABS)
9893 tmp = gen_int_mode (0x7fffffff, SImode);
9894 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9898 tmp = gen_int_mode (0x80000000, SImode);
9899 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9906 [(set (match_operand:XF 0 "register_operand" "")
9907 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9908 (use (match_operand 2 "" ""))
9909 (clobber (reg:CC FLAGS_REG))]
9911 [(parallel [(set (match_dup 0) (match_dup 1))
9912 (clobber (reg:CC FLAGS_REG))])]
9915 operands[0] = gen_rtx_REG (SImode,
9916 true_regnum (operands[0])
9917 + (TARGET_64BIT ? 1 : 2));
9918 if (GET_CODE (operands[1]) == ABS)
9920 tmp = GEN_INT (0x7fff);
9921 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9925 tmp = GEN_INT (0x8000);
9926 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9932 [(set (match_operand 0 "memory_operand" "")
9933 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9934 (use (match_operand 2 "" ""))
9935 (clobber (reg:CC FLAGS_REG))]
9937 [(parallel [(set (match_dup 0) (match_dup 1))
9938 (clobber (reg:CC FLAGS_REG))])]
9940 enum machine_mode mode = GET_MODE (operands[0]);
9941 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9944 operands[0] = adjust_address (operands[0], QImode, size - 1);
9945 if (GET_CODE (operands[1]) == ABS)
9947 tmp = gen_int_mode (0x7f, QImode);
9948 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9952 tmp = gen_int_mode (0x80, QImode);
9953 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9958 ;; Conditionalize these after reload. If they match before reload, we
9959 ;; lose the clobber and ability to use integer instructions.
9961 (define_insn "*negsf2_1"
9962 [(set (match_operand:SF 0 "register_operand" "=f")
9963 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9964 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9966 [(set_attr "type" "fsgn")
9967 (set_attr "mode" "SF")])
9969 (define_insn "*negdf2_1"
9970 [(set (match_operand:DF 0 "register_operand" "=f")
9971 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9972 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9974 [(set_attr "type" "fsgn")
9975 (set_attr "mode" "DF")])
9977 (define_insn "*negxf2_1"
9978 [(set (match_operand:XF 0 "register_operand" "=f")
9979 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9982 [(set_attr "type" "fsgn")
9983 (set_attr "mode" "XF")])
9985 (define_insn "*abssf2_1"
9986 [(set (match_operand:SF 0 "register_operand" "=f")
9987 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9988 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9990 [(set_attr "type" "fsgn")
9991 (set_attr "mode" "SF")])
9993 (define_insn "*absdf2_1"
9994 [(set (match_operand:DF 0 "register_operand" "=f")
9995 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9996 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9998 [(set_attr "type" "fsgn")
9999 (set_attr "mode" "DF")])
10001 (define_insn "*absxf2_1"
10002 [(set (match_operand:XF 0 "register_operand" "=f")
10003 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10006 [(set_attr "type" "fsgn")
10007 (set_attr "mode" "DF")])
10009 (define_insn "*negextendsfdf2"
10010 [(set (match_operand:DF 0 "register_operand" "=f")
10011 (neg:DF (float_extend:DF
10012 (match_operand:SF 1 "register_operand" "0"))))]
10013 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10015 [(set_attr "type" "fsgn")
10016 (set_attr "mode" "DF")])
10018 (define_insn "*negextenddfxf2"
10019 [(set (match_operand:XF 0 "register_operand" "=f")
10020 (neg:XF (float_extend:XF
10021 (match_operand:DF 1 "register_operand" "0"))))]
10024 [(set_attr "type" "fsgn")
10025 (set_attr "mode" "XF")])
10027 (define_insn "*negextendsfxf2"
10028 [(set (match_operand:XF 0 "register_operand" "=f")
10029 (neg:XF (float_extend:XF
10030 (match_operand:SF 1 "register_operand" "0"))))]
10033 [(set_attr "type" "fsgn")
10034 (set_attr "mode" "XF")])
10036 (define_insn "*absextendsfdf2"
10037 [(set (match_operand:DF 0 "register_operand" "=f")
10038 (abs:DF (float_extend:DF
10039 (match_operand:SF 1 "register_operand" "0"))))]
10040 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10042 [(set_attr "type" "fsgn")
10043 (set_attr "mode" "DF")])
10045 (define_insn "*absextenddfxf2"
10046 [(set (match_operand:XF 0 "register_operand" "=f")
10047 (abs:XF (float_extend:XF
10048 (match_operand:DF 1 "register_operand" "0"))))]
10051 [(set_attr "type" "fsgn")
10052 (set_attr "mode" "XF")])
10054 (define_insn "*absextendsfxf2"
10055 [(set (match_operand:XF 0 "register_operand" "=f")
10056 (abs:XF (float_extend:XF
10057 (match_operand:SF 1 "register_operand" "0"))))]
10060 [(set_attr "type" "fsgn")
10061 (set_attr "mode" "XF")])
10063 ;; One complement instructions
10065 (define_expand "one_cmpldi2"
10066 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10067 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10069 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10071 (define_insn "*one_cmpldi2_1_rex64"
10072 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10073 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10074 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10076 [(set_attr "type" "negnot")
10077 (set_attr "mode" "DI")])
10079 (define_insn "*one_cmpldi2_2_rex64"
10080 [(set (reg FLAGS_REG)
10081 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10083 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10084 (not:DI (match_dup 1)))]
10085 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10086 && ix86_unary_operator_ok (NOT, DImode, operands)"
10088 [(set_attr "type" "alu1")
10089 (set_attr "mode" "DI")])
10092 [(set (match_operand 0 "flags_reg_operand" "")
10093 (match_operator 2 "compare_operator"
10094 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10096 (set (match_operand:DI 1 "nonimmediate_operand" "")
10097 (not:DI (match_dup 3)))]
10098 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10099 [(parallel [(set (match_dup 0)
10101 [(xor:DI (match_dup 3) (const_int -1))
10104 (xor:DI (match_dup 3) (const_int -1)))])]
10107 (define_expand "one_cmplsi2"
10108 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10109 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10111 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10113 (define_insn "*one_cmplsi2_1"
10114 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10115 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10116 "ix86_unary_operator_ok (NOT, SImode, operands)"
10118 [(set_attr "type" "negnot")
10119 (set_attr "mode" "SI")])
10121 ;; ??? Currently never generated - xor is used instead.
10122 (define_insn "*one_cmplsi2_1_zext"
10123 [(set (match_operand:DI 0 "register_operand" "=r")
10124 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10125 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10127 [(set_attr "type" "negnot")
10128 (set_attr "mode" "SI")])
10130 (define_insn "*one_cmplsi2_2"
10131 [(set (reg FLAGS_REG)
10132 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10134 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10135 (not:SI (match_dup 1)))]
10136 "ix86_match_ccmode (insn, CCNOmode)
10137 && ix86_unary_operator_ok (NOT, SImode, operands)"
10139 [(set_attr "type" "alu1")
10140 (set_attr "mode" "SI")])
10143 [(set (match_operand 0 "flags_reg_operand" "")
10144 (match_operator 2 "compare_operator"
10145 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10147 (set (match_operand:SI 1 "nonimmediate_operand" "")
10148 (not:SI (match_dup 3)))]
10149 "ix86_match_ccmode (insn, CCNOmode)"
10150 [(parallel [(set (match_dup 0)
10151 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10154 (xor:SI (match_dup 3) (const_int -1)))])]
10157 ;; ??? Currently never generated - xor is used instead.
10158 (define_insn "*one_cmplsi2_2_zext"
10159 [(set (reg FLAGS_REG)
10160 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10162 (set (match_operand:DI 0 "register_operand" "=r")
10163 (zero_extend:DI (not:SI (match_dup 1))))]
10164 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10165 && ix86_unary_operator_ok (NOT, SImode, operands)"
10167 [(set_attr "type" "alu1")
10168 (set_attr "mode" "SI")])
10171 [(set (match_operand 0 "flags_reg_operand" "")
10172 (match_operator 2 "compare_operator"
10173 [(not:SI (match_operand:SI 3 "register_operand" ""))
10175 (set (match_operand:DI 1 "register_operand" "")
10176 (zero_extend:DI (not:SI (match_dup 3))))]
10177 "ix86_match_ccmode (insn, CCNOmode)"
10178 [(parallel [(set (match_dup 0)
10179 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10182 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10185 (define_expand "one_cmplhi2"
10186 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10187 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10188 "TARGET_HIMODE_MATH"
10189 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10191 (define_insn "*one_cmplhi2_1"
10192 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10193 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10194 "ix86_unary_operator_ok (NOT, HImode, operands)"
10196 [(set_attr "type" "negnot")
10197 (set_attr "mode" "HI")])
10199 (define_insn "*one_cmplhi2_2"
10200 [(set (reg FLAGS_REG)
10201 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10203 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10204 (not:HI (match_dup 1)))]
10205 "ix86_match_ccmode (insn, CCNOmode)
10206 && ix86_unary_operator_ok (NEG, HImode, operands)"
10208 [(set_attr "type" "alu1")
10209 (set_attr "mode" "HI")])
10212 [(set (match_operand 0 "flags_reg_operand" "")
10213 (match_operator 2 "compare_operator"
10214 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10216 (set (match_operand:HI 1 "nonimmediate_operand" "")
10217 (not:HI (match_dup 3)))]
10218 "ix86_match_ccmode (insn, CCNOmode)"
10219 [(parallel [(set (match_dup 0)
10220 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10223 (xor:HI (match_dup 3) (const_int -1)))])]
10226 ;; %%% Potential partial reg stall on alternative 1. What to do?
10227 (define_expand "one_cmplqi2"
10228 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10229 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10230 "TARGET_QIMODE_MATH"
10231 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10233 (define_insn "*one_cmplqi2_1"
10234 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10235 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10236 "ix86_unary_operator_ok (NOT, QImode, operands)"
10240 [(set_attr "type" "negnot")
10241 (set_attr "mode" "QI,SI")])
10243 (define_insn "*one_cmplqi2_2"
10244 [(set (reg FLAGS_REG)
10245 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10247 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10248 (not:QI (match_dup 1)))]
10249 "ix86_match_ccmode (insn, CCNOmode)
10250 && ix86_unary_operator_ok (NOT, QImode, operands)"
10252 [(set_attr "type" "alu1")
10253 (set_attr "mode" "QI")])
10256 [(set (match_operand 0 "flags_reg_operand" "")
10257 (match_operator 2 "compare_operator"
10258 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10260 (set (match_operand:QI 1 "nonimmediate_operand" "")
10261 (not:QI (match_dup 3)))]
10262 "ix86_match_ccmode (insn, CCNOmode)"
10263 [(parallel [(set (match_dup 0)
10264 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10267 (xor:QI (match_dup 3) (const_int -1)))])]
10270 ;; Arithmetic shift instructions
10272 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10273 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10274 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10275 ;; from the assembler input.
10277 ;; This instruction shifts the target reg/mem as usual, but instead of
10278 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10279 ;; is a left shift double, bits are taken from the high order bits of
10280 ;; reg, else if the insn is a shift right double, bits are taken from the
10281 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10282 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10284 ;; Since sh[lr]d does not change the `reg' operand, that is done
10285 ;; separately, making all shifts emit pairs of shift double and normal
10286 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10287 ;; support a 63 bit shift, each shift where the count is in a reg expands
10288 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10290 ;; If the shift count is a constant, we need never emit more than one
10291 ;; shift pair, instead using moves and sign extension for counts greater
10294 (define_expand "ashlti3"
10295 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10296 (ashift:TI (match_operand:TI 1 "register_operand" "")
10297 (match_operand:QI 2 "nonmemory_operand" "")))
10298 (clobber (reg:CC FLAGS_REG))])]
10301 if (! immediate_operand (operands[2], QImode))
10303 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10306 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10310 (define_insn "ashlti3_1"
10311 [(set (match_operand:TI 0 "register_operand" "=r")
10312 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10313 (match_operand:QI 2 "register_operand" "c")))
10314 (clobber (match_scratch:DI 3 "=&r"))
10315 (clobber (reg:CC FLAGS_REG))]
10318 [(set_attr "type" "multi")])
10320 (define_insn "*ashlti3_2"
10321 [(set (match_operand:TI 0 "register_operand" "=r")
10322 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10323 (match_operand:QI 2 "immediate_operand" "O")))
10324 (clobber (reg:CC FLAGS_REG))]
10327 [(set_attr "type" "multi")])
10330 [(set (match_operand:TI 0 "register_operand" "")
10331 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10332 (match_operand:QI 2 "register_operand" "")))
10333 (clobber (match_scratch:DI 3 ""))
10334 (clobber (reg:CC FLAGS_REG))]
10335 "TARGET_64BIT && reload_completed"
10337 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10340 [(set (match_operand:TI 0 "register_operand" "")
10341 (ashift:TI (match_operand:TI 1 "register_operand" "")
10342 (match_operand:QI 2 "immediate_operand" "")))
10343 (clobber (reg:CC FLAGS_REG))]
10344 "TARGET_64BIT && reload_completed"
10346 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10348 (define_insn "x86_64_shld"
10349 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10350 (ior:DI (ashift:DI (match_dup 0)
10351 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10352 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10353 (minus:QI (const_int 64) (match_dup 2)))))
10354 (clobber (reg:CC FLAGS_REG))]
10357 shld{q}\t{%2, %1, %0|%0, %1, %2}
10358 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10359 [(set_attr "type" "ishift")
10360 (set_attr "prefix_0f" "1")
10361 (set_attr "mode" "DI")
10362 (set_attr "athlon_decode" "vector")])
10364 (define_expand "x86_64_shift_adj"
10365 [(set (reg:CCZ FLAGS_REG)
10366 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10369 (set (match_operand:DI 0 "register_operand" "")
10370 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10371 (match_operand:DI 1 "register_operand" "")
10374 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10375 (match_operand:DI 3 "register_operand" "r")
10380 (define_expand "ashldi3"
10381 [(set (match_operand:DI 0 "shiftdi_operand" "")
10382 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10383 (match_operand:QI 2 "nonmemory_operand" "")))]
10385 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10387 (define_insn "*ashldi3_1_rex64"
10388 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10389 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10390 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10391 (clobber (reg:CC FLAGS_REG))]
10392 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10394 switch (get_attr_type (insn))
10397 gcc_assert (operands[2] == const1_rtx);
10398 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10399 return "add{q}\t{%0, %0|%0, %0}";
10402 gcc_assert (CONST_INT_P (operands[2]));
10403 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10404 operands[1] = gen_rtx_MULT (DImode, operands[1],
10405 GEN_INT (1 << INTVAL (operands[2])));
10406 return "lea{q}\t{%a1, %0|%0, %a1}";
10409 if (REG_P (operands[2]))
10410 return "sal{q}\t{%b2, %0|%0, %b2}";
10411 else if (operands[2] == const1_rtx
10412 && (TARGET_SHIFT1 || optimize_size))
10413 return "sal{q}\t%0";
10415 return "sal{q}\t{%2, %0|%0, %2}";
10418 [(set (attr "type")
10419 (cond [(eq_attr "alternative" "1")
10420 (const_string "lea")
10421 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10423 (match_operand 0 "register_operand" ""))
10424 (match_operand 2 "const1_operand" ""))
10425 (const_string "alu")
10427 (const_string "ishift")))
10428 (set_attr "mode" "DI")])
10430 ;; Convert lea to the lea pattern to avoid flags dependency.
10432 [(set (match_operand:DI 0 "register_operand" "")
10433 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10434 (match_operand:QI 2 "immediate_operand" "")))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "TARGET_64BIT && reload_completed
10437 && true_regnum (operands[0]) != true_regnum (operands[1])"
10438 [(set (match_dup 0)
10439 (mult:DI (match_dup 1)
10441 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10443 ;; This pattern can't accept a variable shift count, since shifts by
10444 ;; zero don't affect the flags. We assume that shifts by constant
10445 ;; zero are optimized away.
10446 (define_insn "*ashldi3_cmp_rex64"
10447 [(set (reg FLAGS_REG)
10449 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10450 (match_operand:QI 2 "immediate_operand" "e"))
10452 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10453 (ashift:DI (match_dup 1) (match_dup 2)))]
10454 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10455 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10457 || !TARGET_PARTIAL_FLAG_REG_STALL
10458 || (operands[2] == const1_rtx
10460 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10462 switch (get_attr_type (insn))
10465 gcc_assert (operands[2] == const1_rtx);
10466 return "add{q}\t{%0, %0|%0, %0}";
10469 if (REG_P (operands[2]))
10470 return "sal{q}\t{%b2, %0|%0, %b2}";
10471 else if (operands[2] == const1_rtx
10472 && (TARGET_SHIFT1 || optimize_size))
10473 return "sal{q}\t%0";
10475 return "sal{q}\t{%2, %0|%0, %2}";
10478 [(set (attr "type")
10479 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10481 (match_operand 0 "register_operand" ""))
10482 (match_operand 2 "const1_operand" ""))
10483 (const_string "alu")
10485 (const_string "ishift")))
10486 (set_attr "mode" "DI")])
10488 (define_insn "*ashldi3_cconly_rex64"
10489 [(set (reg FLAGS_REG)
10491 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10492 (match_operand:QI 2 "immediate_operand" "e"))
10494 (clobber (match_scratch:DI 0 "=r"))]
10495 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10496 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10498 || !TARGET_PARTIAL_FLAG_REG_STALL
10499 || (operands[2] == const1_rtx
10501 || TARGET_DOUBLE_WITH_ADD)))"
10503 switch (get_attr_type (insn))
10506 gcc_assert (operands[2] == const1_rtx);
10507 return "add{q}\t{%0, %0|%0, %0}";
10510 if (REG_P (operands[2]))
10511 return "sal{q}\t{%b2, %0|%0, %b2}";
10512 else if (operands[2] == const1_rtx
10513 && (TARGET_SHIFT1 || optimize_size))
10514 return "sal{q}\t%0";
10516 return "sal{q}\t{%2, %0|%0, %2}";
10519 [(set (attr "type")
10520 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10522 (match_operand 0 "register_operand" ""))
10523 (match_operand 2 "const1_operand" ""))
10524 (const_string "alu")
10526 (const_string "ishift")))
10527 (set_attr "mode" "DI")])
10529 (define_insn "*ashldi3_1"
10530 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10531 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10532 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10533 (clobber (reg:CC FLAGS_REG))]
10536 [(set_attr "type" "multi")])
10538 ;; By default we don't ask for a scratch register, because when DImode
10539 ;; values are manipulated, registers are already at a premium. But if
10540 ;; we have one handy, we won't turn it away.
10542 [(match_scratch:SI 3 "r")
10543 (parallel [(set (match_operand:DI 0 "register_operand" "")
10544 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10545 (match_operand:QI 2 "nonmemory_operand" "")))
10546 (clobber (reg:CC FLAGS_REG))])
10548 "!TARGET_64BIT && TARGET_CMOVE"
10550 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10553 [(set (match_operand:DI 0 "register_operand" "")
10554 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10555 (match_operand:QI 2 "nonmemory_operand" "")))
10556 (clobber (reg:CC FLAGS_REG))]
10557 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10558 ? flow2_completed : reload_completed)"
10560 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10562 (define_insn "x86_shld_1"
10563 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10564 (ior:SI (ashift:SI (match_dup 0)
10565 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10566 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10567 (minus:QI (const_int 32) (match_dup 2)))))
10568 (clobber (reg:CC FLAGS_REG))]
10571 shld{l}\t{%2, %1, %0|%0, %1, %2}
10572 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10573 [(set_attr "type" "ishift")
10574 (set_attr "prefix_0f" "1")
10575 (set_attr "mode" "SI")
10576 (set_attr "pent_pair" "np")
10577 (set_attr "athlon_decode" "vector")])
10579 (define_expand "x86_shift_adj_1"
10580 [(set (reg:CCZ FLAGS_REG)
10581 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10584 (set (match_operand:SI 0 "register_operand" "")
10585 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10586 (match_operand:SI 1 "register_operand" "")
10589 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10590 (match_operand:SI 3 "register_operand" "r")
10595 (define_expand "x86_shift_adj_2"
10596 [(use (match_operand:SI 0 "register_operand" ""))
10597 (use (match_operand:SI 1 "register_operand" ""))
10598 (use (match_operand:QI 2 "register_operand" ""))]
10601 rtx label = gen_label_rtx ();
10604 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10606 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10607 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10608 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10609 gen_rtx_LABEL_REF (VOIDmode, label),
10611 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10612 JUMP_LABEL (tmp) = label;
10614 emit_move_insn (operands[0], operands[1]);
10615 ix86_expand_clear (operands[1]);
10617 emit_label (label);
10618 LABEL_NUSES (label) = 1;
10623 (define_expand "ashlsi3"
10624 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10625 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10626 (match_operand:QI 2 "nonmemory_operand" "")))
10627 (clobber (reg:CC FLAGS_REG))]
10629 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10631 (define_insn "*ashlsi3_1"
10632 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10633 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10634 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10635 (clobber (reg:CC FLAGS_REG))]
10636 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10638 switch (get_attr_type (insn))
10641 gcc_assert (operands[2] == const1_rtx);
10642 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10643 return "add{l}\t{%0, %0|%0, %0}";
10649 if (REG_P (operands[2]))
10650 return "sal{l}\t{%b2, %0|%0, %b2}";
10651 else if (operands[2] == const1_rtx
10652 && (TARGET_SHIFT1 || optimize_size))
10653 return "sal{l}\t%0";
10655 return "sal{l}\t{%2, %0|%0, %2}";
10658 [(set (attr "type")
10659 (cond [(eq_attr "alternative" "1")
10660 (const_string "lea")
10661 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10663 (match_operand 0 "register_operand" ""))
10664 (match_operand 2 "const1_operand" ""))
10665 (const_string "alu")
10667 (const_string "ishift")))
10668 (set_attr "mode" "SI")])
10670 ;; Convert lea to the lea pattern to avoid flags dependency.
10672 [(set (match_operand 0 "register_operand" "")
10673 (ashift (match_operand 1 "index_register_operand" "")
10674 (match_operand:QI 2 "const_int_operand" "")))
10675 (clobber (reg:CC FLAGS_REG))]
10677 && true_regnum (operands[0]) != true_regnum (operands[1])
10678 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10682 enum machine_mode mode = GET_MODE (operands[0]);
10684 if (GET_MODE_SIZE (mode) < 4)
10685 operands[0] = gen_lowpart (SImode, operands[0]);
10687 operands[1] = gen_lowpart (Pmode, operands[1]);
10688 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10690 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10691 if (Pmode != SImode)
10692 pat = gen_rtx_SUBREG (SImode, pat, 0);
10693 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10697 ;; Rare case of shifting RSP is handled by generating move and shift
10699 [(set (match_operand 0 "register_operand" "")
10700 (ashift (match_operand 1 "register_operand" "")
10701 (match_operand:QI 2 "const_int_operand" "")))
10702 (clobber (reg:CC FLAGS_REG))]
10704 && true_regnum (operands[0]) != true_regnum (operands[1])"
10708 emit_move_insn (operands[0], operands[1]);
10709 pat = gen_rtx_SET (VOIDmode, operands[0],
10710 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10711 operands[0], operands[2]));
10712 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10713 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10717 (define_insn "*ashlsi3_1_zext"
10718 [(set (match_operand:DI 0 "register_operand" "=r,r")
10719 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10720 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10721 (clobber (reg:CC FLAGS_REG))]
10722 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10724 switch (get_attr_type (insn))
10727 gcc_assert (operands[2] == const1_rtx);
10728 return "add{l}\t{%k0, %k0|%k0, %k0}";
10734 if (REG_P (operands[2]))
10735 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10736 else if (operands[2] == const1_rtx
10737 && (TARGET_SHIFT1 || optimize_size))
10738 return "sal{l}\t%k0";
10740 return "sal{l}\t{%2, %k0|%k0, %2}";
10743 [(set (attr "type")
10744 (cond [(eq_attr "alternative" "1")
10745 (const_string "lea")
10746 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10748 (match_operand 2 "const1_operand" ""))
10749 (const_string "alu")
10751 (const_string "ishift")))
10752 (set_attr "mode" "SI")])
10754 ;; Convert lea to the lea pattern to avoid flags dependency.
10756 [(set (match_operand:DI 0 "register_operand" "")
10757 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10758 (match_operand:QI 2 "const_int_operand" ""))))
10759 (clobber (reg:CC FLAGS_REG))]
10760 "TARGET_64BIT && reload_completed
10761 && true_regnum (operands[0]) != true_regnum (operands[1])"
10762 [(set (match_dup 0) (zero_extend:DI
10763 (subreg:SI (mult:SI (match_dup 1)
10764 (match_dup 2)) 0)))]
10766 operands[1] = gen_lowpart (Pmode, operands[1]);
10767 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10770 ;; This pattern can't accept a variable shift count, since shifts by
10771 ;; zero don't affect the flags. We assume that shifts by constant
10772 ;; zero are optimized away.
10773 (define_insn "*ashlsi3_cmp"
10774 [(set (reg FLAGS_REG)
10776 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10777 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10779 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10780 (ashift:SI (match_dup 1) (match_dup 2)))]
10781 "ix86_match_ccmode (insn, CCGOCmode)
10782 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10784 || !TARGET_PARTIAL_FLAG_REG_STALL
10785 || (operands[2] == const1_rtx
10787 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10789 switch (get_attr_type (insn))
10792 gcc_assert (operands[2] == const1_rtx);
10793 return "add{l}\t{%0, %0|%0, %0}";
10796 if (REG_P (operands[2]))
10797 return "sal{l}\t{%b2, %0|%0, %b2}";
10798 else if (operands[2] == const1_rtx
10799 && (TARGET_SHIFT1 || optimize_size))
10800 return "sal{l}\t%0";
10802 return "sal{l}\t{%2, %0|%0, %2}";
10805 [(set (attr "type")
10806 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10808 (match_operand 0 "register_operand" ""))
10809 (match_operand 2 "const1_operand" ""))
10810 (const_string "alu")
10812 (const_string "ishift")))
10813 (set_attr "mode" "SI")])
10815 (define_insn "*ashlsi3_cconly"
10816 [(set (reg FLAGS_REG)
10818 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10819 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10821 (clobber (match_scratch:SI 0 "=r"))]
10822 "ix86_match_ccmode (insn, CCGOCmode)
10823 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10825 || !TARGET_PARTIAL_FLAG_REG_STALL
10826 || (operands[2] == const1_rtx
10828 || TARGET_DOUBLE_WITH_ADD)))"
10830 switch (get_attr_type (insn))
10833 gcc_assert (operands[2] == const1_rtx);
10834 return "add{l}\t{%0, %0|%0, %0}";
10837 if (REG_P (operands[2]))
10838 return "sal{l}\t{%b2, %0|%0, %b2}";
10839 else if (operands[2] == const1_rtx
10840 && (TARGET_SHIFT1 || optimize_size))
10841 return "sal{l}\t%0";
10843 return "sal{l}\t{%2, %0|%0, %2}";
10846 [(set (attr "type")
10847 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10849 (match_operand 0 "register_operand" ""))
10850 (match_operand 2 "const1_operand" ""))
10851 (const_string "alu")
10853 (const_string "ishift")))
10854 (set_attr "mode" "SI")])
10856 (define_insn "*ashlsi3_cmp_zext"
10857 [(set (reg FLAGS_REG)
10859 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10860 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10862 (set (match_operand:DI 0 "register_operand" "=r")
10863 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10864 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10865 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10867 || !TARGET_PARTIAL_FLAG_REG_STALL
10868 || (operands[2] == const1_rtx
10870 || TARGET_DOUBLE_WITH_ADD)))"
10872 switch (get_attr_type (insn))
10875 gcc_assert (operands[2] == const1_rtx);
10876 return "add{l}\t{%k0, %k0|%k0, %k0}";
10879 if (REG_P (operands[2]))
10880 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10881 else if (operands[2] == const1_rtx
10882 && (TARGET_SHIFT1 || optimize_size))
10883 return "sal{l}\t%k0";
10885 return "sal{l}\t{%2, %k0|%k0, %2}";
10888 [(set (attr "type")
10889 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10891 (match_operand 2 "const1_operand" ""))
10892 (const_string "alu")
10894 (const_string "ishift")))
10895 (set_attr "mode" "SI")])
10897 (define_expand "ashlhi3"
10898 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10899 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10900 (match_operand:QI 2 "nonmemory_operand" "")))
10901 (clobber (reg:CC FLAGS_REG))]
10902 "TARGET_HIMODE_MATH"
10903 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10905 (define_insn "*ashlhi3_1_lea"
10906 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10907 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10908 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10909 (clobber (reg:CC FLAGS_REG))]
10910 "!TARGET_PARTIAL_REG_STALL
10911 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10913 switch (get_attr_type (insn))
10918 gcc_assert (operands[2] == const1_rtx);
10919 return "add{w}\t{%0, %0|%0, %0}";
10922 if (REG_P (operands[2]))
10923 return "sal{w}\t{%b2, %0|%0, %b2}";
10924 else if (operands[2] == const1_rtx
10925 && (TARGET_SHIFT1 || optimize_size))
10926 return "sal{w}\t%0";
10928 return "sal{w}\t{%2, %0|%0, %2}";
10931 [(set (attr "type")
10932 (cond [(eq_attr "alternative" "1")
10933 (const_string "lea")
10934 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10936 (match_operand 0 "register_operand" ""))
10937 (match_operand 2 "const1_operand" ""))
10938 (const_string "alu")
10940 (const_string "ishift")))
10941 (set_attr "mode" "HI,SI")])
10943 (define_insn "*ashlhi3_1"
10944 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10945 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10946 (match_operand:QI 2 "nonmemory_operand" "cI")))
10947 (clobber (reg:CC FLAGS_REG))]
10948 "TARGET_PARTIAL_REG_STALL
10949 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10951 switch (get_attr_type (insn))
10954 gcc_assert (operands[2] == const1_rtx);
10955 return "add{w}\t{%0, %0|%0, %0}";
10958 if (REG_P (operands[2]))
10959 return "sal{w}\t{%b2, %0|%0, %b2}";
10960 else if (operands[2] == const1_rtx
10961 && (TARGET_SHIFT1 || optimize_size))
10962 return "sal{w}\t%0";
10964 return "sal{w}\t{%2, %0|%0, %2}";
10967 [(set (attr "type")
10968 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10970 (match_operand 0 "register_operand" ""))
10971 (match_operand 2 "const1_operand" ""))
10972 (const_string "alu")
10974 (const_string "ishift")))
10975 (set_attr "mode" "HI")])
10977 ;; This pattern can't accept a variable shift count, since shifts by
10978 ;; zero don't affect the flags. We assume that shifts by constant
10979 ;; zero are optimized away.
10980 (define_insn "*ashlhi3_cmp"
10981 [(set (reg FLAGS_REG)
10983 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10984 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10986 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10987 (ashift:HI (match_dup 1) (match_dup 2)))]
10988 "ix86_match_ccmode (insn, CCGOCmode)
10989 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10991 || !TARGET_PARTIAL_FLAG_REG_STALL
10992 || (operands[2] == const1_rtx
10994 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10996 switch (get_attr_type (insn))
10999 gcc_assert (operands[2] == const1_rtx);
11000 return "add{w}\t{%0, %0|%0, %0}";
11003 if (REG_P (operands[2]))
11004 return "sal{w}\t{%b2, %0|%0, %b2}";
11005 else if (operands[2] == const1_rtx
11006 && (TARGET_SHIFT1 || optimize_size))
11007 return "sal{w}\t%0";
11009 return "sal{w}\t{%2, %0|%0, %2}";
11012 [(set (attr "type")
11013 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11015 (match_operand 0 "register_operand" ""))
11016 (match_operand 2 "const1_operand" ""))
11017 (const_string "alu")
11019 (const_string "ishift")))
11020 (set_attr "mode" "HI")])
11022 (define_insn "*ashlhi3_cconly"
11023 [(set (reg FLAGS_REG)
11025 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11026 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11028 (clobber (match_scratch:HI 0 "=r"))]
11029 "ix86_match_ccmode (insn, CCGOCmode)
11030 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11032 || !TARGET_PARTIAL_FLAG_REG_STALL
11033 || (operands[2] == const1_rtx
11035 || TARGET_DOUBLE_WITH_ADD)))"
11037 switch (get_attr_type (insn))
11040 gcc_assert (operands[2] == const1_rtx);
11041 return "add{w}\t{%0, %0|%0, %0}";
11044 if (REG_P (operands[2]))
11045 return "sal{w}\t{%b2, %0|%0, %b2}";
11046 else if (operands[2] == const1_rtx
11047 && (TARGET_SHIFT1 || optimize_size))
11048 return "sal{w}\t%0";
11050 return "sal{w}\t{%2, %0|%0, %2}";
11053 [(set (attr "type")
11054 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11056 (match_operand 0 "register_operand" ""))
11057 (match_operand 2 "const1_operand" ""))
11058 (const_string "alu")
11060 (const_string "ishift")))
11061 (set_attr "mode" "HI")])
11063 (define_expand "ashlqi3"
11064 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11065 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11066 (match_operand:QI 2 "nonmemory_operand" "")))
11067 (clobber (reg:CC FLAGS_REG))]
11068 "TARGET_QIMODE_MATH"
11069 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11071 ;; %%% Potential partial reg stall on alternative 2. What to do?
11073 (define_insn "*ashlqi3_1_lea"
11074 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11075 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11076 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
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))
11086 gcc_assert (operands[2] == const1_rtx);
11087 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11088 return "add{l}\t{%k0, %k0|%k0, %k0}";
11090 return "add{b}\t{%0, %0|%0, %0}";
11093 if (REG_P (operands[2]))
11095 if (get_attr_mode (insn) == MODE_SI)
11096 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11098 return "sal{b}\t{%b2, %0|%0, %b2}";
11100 else if (operands[2] == const1_rtx
11101 && (TARGET_SHIFT1 || optimize_size))
11103 if (get_attr_mode (insn) == MODE_SI)
11104 return "sal{l}\t%0";
11106 return "sal{b}\t%0";
11110 if (get_attr_mode (insn) == MODE_SI)
11111 return "sal{l}\t{%2, %k0|%k0, %2}";
11113 return "sal{b}\t{%2, %0|%0, %2}";
11117 [(set (attr "type")
11118 (cond [(eq_attr "alternative" "2")
11119 (const_string "lea")
11120 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11122 (match_operand 0 "register_operand" ""))
11123 (match_operand 2 "const1_operand" ""))
11124 (const_string "alu")
11126 (const_string "ishift")))
11127 (set_attr "mode" "QI,SI,SI")])
11129 (define_insn "*ashlqi3_1"
11130 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11131 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11132 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11133 (clobber (reg:CC FLAGS_REG))]
11134 "TARGET_PARTIAL_REG_STALL
11135 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11137 switch (get_attr_type (insn))
11140 gcc_assert (operands[2] == const1_rtx);
11141 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11142 return "add{l}\t{%k0, %k0|%k0, %k0}";
11144 return "add{b}\t{%0, %0|%0, %0}";
11147 if (REG_P (operands[2]))
11149 if (get_attr_mode (insn) == MODE_SI)
11150 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11152 return "sal{b}\t{%b2, %0|%0, %b2}";
11154 else if (operands[2] == const1_rtx
11155 && (TARGET_SHIFT1 || optimize_size))
11157 if (get_attr_mode (insn) == MODE_SI)
11158 return "sal{l}\t%0";
11160 return "sal{b}\t%0";
11164 if (get_attr_mode (insn) == MODE_SI)
11165 return "sal{l}\t{%2, %k0|%k0, %2}";
11167 return "sal{b}\t{%2, %0|%0, %2}";
11171 [(set (attr "type")
11172 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11174 (match_operand 0 "register_operand" ""))
11175 (match_operand 2 "const1_operand" ""))
11176 (const_string "alu")
11178 (const_string "ishift")))
11179 (set_attr "mode" "QI,SI")])
11181 ;; This pattern can't accept a variable shift count, since shifts by
11182 ;; zero don't affect the flags. We assume that shifts by constant
11183 ;; zero are optimized away.
11184 (define_insn "*ashlqi3_cmp"
11185 [(set (reg FLAGS_REG)
11187 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11188 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11190 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11191 (ashift:QI (match_dup 1) (match_dup 2)))]
11192 "ix86_match_ccmode (insn, CCGOCmode)
11193 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11195 || !TARGET_PARTIAL_FLAG_REG_STALL
11196 || (operands[2] == const1_rtx
11198 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11200 switch (get_attr_type (insn))
11203 gcc_assert (operands[2] == const1_rtx);
11204 return "add{b}\t{%0, %0|%0, %0}";
11207 if (REG_P (operands[2]))
11208 return "sal{b}\t{%b2, %0|%0, %b2}";
11209 else if (operands[2] == const1_rtx
11210 && (TARGET_SHIFT1 || optimize_size))
11211 return "sal{b}\t%0";
11213 return "sal{b}\t{%2, %0|%0, %2}";
11216 [(set (attr "type")
11217 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11219 (match_operand 0 "register_operand" ""))
11220 (match_operand 2 "const1_operand" ""))
11221 (const_string "alu")
11223 (const_string "ishift")))
11224 (set_attr "mode" "QI")])
11226 (define_insn "*ashlqi3_cconly"
11227 [(set (reg FLAGS_REG)
11229 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11230 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11232 (clobber (match_scratch:QI 0 "=q"))]
11233 "ix86_match_ccmode (insn, CCGOCmode)
11234 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11236 || !TARGET_PARTIAL_FLAG_REG_STALL
11237 || (operands[2] == const1_rtx
11239 || TARGET_DOUBLE_WITH_ADD)))"
11241 switch (get_attr_type (insn))
11244 gcc_assert (operands[2] == const1_rtx);
11245 return "add{b}\t{%0, %0|%0, %0}";
11248 if (REG_P (operands[2]))
11249 return "sal{b}\t{%b2, %0|%0, %b2}";
11250 else if (operands[2] == const1_rtx
11251 && (TARGET_SHIFT1 || optimize_size))
11252 return "sal{b}\t%0";
11254 return "sal{b}\t{%2, %0|%0, %2}";
11257 [(set (attr "type")
11258 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11260 (match_operand 0 "register_operand" ""))
11261 (match_operand 2 "const1_operand" ""))
11262 (const_string "alu")
11264 (const_string "ishift")))
11265 (set_attr "mode" "QI")])
11267 ;; See comment above `ashldi3' about how this works.
11269 (define_expand "ashrti3"
11270 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11271 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11272 (match_operand:QI 2 "nonmemory_operand" "")))
11273 (clobber (reg:CC FLAGS_REG))])]
11276 if (! immediate_operand (operands[2], QImode))
11278 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11281 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11285 (define_insn "ashrti3_1"
11286 [(set (match_operand:TI 0 "register_operand" "=r")
11287 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11288 (match_operand:QI 2 "register_operand" "c")))
11289 (clobber (match_scratch:DI 3 "=&r"))
11290 (clobber (reg:CC FLAGS_REG))]
11293 [(set_attr "type" "multi")])
11295 (define_insn "*ashrti3_2"
11296 [(set (match_operand:TI 0 "register_operand" "=r")
11297 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11298 (match_operand:QI 2 "immediate_operand" "O")))
11299 (clobber (reg:CC FLAGS_REG))]
11302 [(set_attr "type" "multi")])
11305 [(set (match_operand:TI 0 "register_operand" "")
11306 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11307 (match_operand:QI 2 "register_operand" "")))
11308 (clobber (match_scratch:DI 3 ""))
11309 (clobber (reg:CC FLAGS_REG))]
11310 "TARGET_64BIT && reload_completed"
11312 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11315 [(set (match_operand:TI 0 "register_operand" "")
11316 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11317 (match_operand:QI 2 "immediate_operand" "")))
11318 (clobber (reg:CC FLAGS_REG))]
11319 "TARGET_64BIT && reload_completed"
11321 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11323 (define_insn "x86_64_shrd"
11324 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11325 (ior:DI (ashiftrt:DI (match_dup 0)
11326 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11327 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11328 (minus:QI (const_int 64) (match_dup 2)))))
11329 (clobber (reg:CC FLAGS_REG))]
11332 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11333 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11334 [(set_attr "type" "ishift")
11335 (set_attr "prefix_0f" "1")
11336 (set_attr "mode" "DI")
11337 (set_attr "athlon_decode" "vector")])
11339 (define_expand "ashrdi3"
11340 [(set (match_operand:DI 0 "shiftdi_operand" "")
11341 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11342 (match_operand:QI 2 "nonmemory_operand" "")))]
11344 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11346 (define_insn "*ashrdi3_63_rex64"
11347 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11348 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11349 (match_operand:DI 2 "const_int_operand" "i,i")))
11350 (clobber (reg:CC FLAGS_REG))]
11351 "TARGET_64BIT && INTVAL (operands[2]) == 63
11352 && (TARGET_USE_CLTD || optimize_size)
11353 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11356 sar{q}\t{%2, %0|%0, %2}"
11357 [(set_attr "type" "imovx,ishift")
11358 (set_attr "prefix_0f" "0,*")
11359 (set_attr "length_immediate" "0,*")
11360 (set_attr "modrm" "0,1")
11361 (set_attr "mode" "DI")])
11363 (define_insn "*ashrdi3_1_one_bit_rex64"
11364 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11365 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11366 (match_operand:QI 2 "const1_operand" "")))
11367 (clobber (reg:CC FLAGS_REG))]
11368 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11369 && (TARGET_SHIFT1 || optimize_size)"
11371 [(set_attr "type" "ishift")
11372 (set (attr "length")
11373 (if_then_else (match_operand:DI 0 "register_operand" "")
11375 (const_string "*")))])
11377 (define_insn "*ashrdi3_1_rex64"
11378 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11379 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11380 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11381 (clobber (reg:CC FLAGS_REG))]
11382 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11384 sar{q}\t{%2, %0|%0, %2}
11385 sar{q}\t{%b2, %0|%0, %b2}"
11386 [(set_attr "type" "ishift")
11387 (set_attr "mode" "DI")])
11389 ;; This pattern can't accept a variable shift count, since shifts by
11390 ;; zero don't affect the flags. We assume that shifts by constant
11391 ;; zero are optimized away.
11392 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11393 [(set (reg FLAGS_REG)
11395 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11396 (match_operand:QI 2 "const1_operand" ""))
11398 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11399 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11400 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11401 && (TARGET_SHIFT1 || optimize_size)
11402 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11404 [(set_attr "type" "ishift")
11405 (set (attr "length")
11406 (if_then_else (match_operand:DI 0 "register_operand" "")
11408 (const_string "*")))])
11410 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11411 [(set (reg FLAGS_REG)
11413 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11414 (match_operand:QI 2 "const1_operand" ""))
11416 (clobber (match_scratch:DI 0 "=r"))]
11417 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11418 && (TARGET_SHIFT1 || optimize_size)
11419 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11421 [(set_attr "type" "ishift")
11422 (set_attr "length" "2")])
11424 ;; This pattern can't accept a variable shift count, since shifts by
11425 ;; zero don't affect the flags. We assume that shifts by constant
11426 ;; zero are optimized away.
11427 (define_insn "*ashrdi3_cmp_rex64"
11428 [(set (reg FLAGS_REG)
11430 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11431 (match_operand:QI 2 "const_int_operand" "n"))
11433 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11434 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11435 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11436 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11438 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11439 "sar{q}\t{%2, %0|%0, %2}"
11440 [(set_attr "type" "ishift")
11441 (set_attr "mode" "DI")])
11443 (define_insn "*ashrdi3_cconly_rex64"
11444 [(set (reg FLAGS_REG)
11446 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11447 (match_operand:QI 2 "const_int_operand" "n"))
11449 (clobber (match_scratch:DI 0 "=r"))]
11450 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11451 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11453 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11454 "sar{q}\t{%2, %0|%0, %2}"
11455 [(set_attr "type" "ishift")
11456 (set_attr "mode" "DI")])
11458 (define_insn "*ashrdi3_1"
11459 [(set (match_operand:DI 0 "register_operand" "=r")
11460 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11461 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11462 (clobber (reg:CC FLAGS_REG))]
11465 [(set_attr "type" "multi")])
11467 ;; By default we don't ask for a scratch register, because when DImode
11468 ;; values are manipulated, registers are already at a premium. But if
11469 ;; we have one handy, we won't turn it away.
11471 [(match_scratch:SI 3 "r")
11472 (parallel [(set (match_operand:DI 0 "register_operand" "")
11473 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11474 (match_operand:QI 2 "nonmemory_operand" "")))
11475 (clobber (reg:CC FLAGS_REG))])
11477 "!TARGET_64BIT && TARGET_CMOVE"
11479 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11482 [(set (match_operand:DI 0 "register_operand" "")
11483 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11484 (match_operand:QI 2 "nonmemory_operand" "")))
11485 (clobber (reg:CC FLAGS_REG))]
11486 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11487 ? flow2_completed : reload_completed)"
11489 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11491 (define_insn "x86_shrd_1"
11492 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11493 (ior:SI (ashiftrt:SI (match_dup 0)
11494 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11495 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11496 (minus:QI (const_int 32) (match_dup 2)))))
11497 (clobber (reg:CC FLAGS_REG))]
11500 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11501 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11502 [(set_attr "type" "ishift")
11503 (set_attr "prefix_0f" "1")
11504 (set_attr "pent_pair" "np")
11505 (set_attr "mode" "SI")])
11507 (define_expand "x86_shift_adj_3"
11508 [(use (match_operand:SI 0 "register_operand" ""))
11509 (use (match_operand:SI 1 "register_operand" ""))
11510 (use (match_operand:QI 2 "register_operand" ""))]
11513 rtx label = gen_label_rtx ();
11516 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11518 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11519 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11520 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11521 gen_rtx_LABEL_REF (VOIDmode, label),
11523 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11524 JUMP_LABEL (tmp) = label;
11526 emit_move_insn (operands[0], operands[1]);
11527 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11529 emit_label (label);
11530 LABEL_NUSES (label) = 1;
11535 (define_insn "ashrsi3_31"
11536 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11537 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11538 (match_operand:SI 2 "const_int_operand" "i,i")))
11539 (clobber (reg:CC FLAGS_REG))]
11540 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11541 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11544 sar{l}\t{%2, %0|%0, %2}"
11545 [(set_attr "type" "imovx,ishift")
11546 (set_attr "prefix_0f" "0,*")
11547 (set_attr "length_immediate" "0,*")
11548 (set_attr "modrm" "0,1")
11549 (set_attr "mode" "SI")])
11551 (define_insn "*ashrsi3_31_zext"
11552 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11553 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11554 (match_operand:SI 2 "const_int_operand" "i,i"))))
11555 (clobber (reg:CC FLAGS_REG))]
11556 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11557 && INTVAL (operands[2]) == 31
11558 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11561 sar{l}\t{%2, %k0|%k0, %2}"
11562 [(set_attr "type" "imovx,ishift")
11563 (set_attr "prefix_0f" "0,*")
11564 (set_attr "length_immediate" "0,*")
11565 (set_attr "modrm" "0,1")
11566 (set_attr "mode" "SI")])
11568 (define_expand "ashrsi3"
11569 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11570 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11571 (match_operand:QI 2 "nonmemory_operand" "")))
11572 (clobber (reg:CC FLAGS_REG))]
11574 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11576 (define_insn "*ashrsi3_1_one_bit"
11577 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11578 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11579 (match_operand:QI 2 "const1_operand" "")))
11580 (clobber (reg:CC FLAGS_REG))]
11581 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11582 && (TARGET_SHIFT1 || optimize_size)"
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_1_one_bit_zext"
11591 [(set (match_operand:DI 0 "register_operand" "=r")
11592 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11593 (match_operand:QI 2 "const1_operand" ""))))
11594 (clobber (reg:CC FLAGS_REG))]
11595 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11596 && (TARGET_SHIFT1 || optimize_size)"
11598 [(set_attr "type" "ishift")
11599 (set_attr "length" "2")])
11601 (define_insn "*ashrsi3_1"
11602 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11603 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11604 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11605 (clobber (reg:CC FLAGS_REG))]
11606 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11608 sar{l}\t{%2, %0|%0, %2}
11609 sar{l}\t{%b2, %0|%0, %b2}"
11610 [(set_attr "type" "ishift")
11611 (set_attr "mode" "SI")])
11613 (define_insn "*ashrsi3_1_zext"
11614 [(set (match_operand:DI 0 "register_operand" "=r,r")
11615 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11616 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11617 (clobber (reg:CC FLAGS_REG))]
11618 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11620 sar{l}\t{%2, %k0|%k0, %2}
11621 sar{l}\t{%b2, %k0|%k0, %b2}"
11622 [(set_attr "type" "ishift")
11623 (set_attr "mode" "SI")])
11625 ;; This pattern can't accept a variable shift count, since shifts by
11626 ;; zero don't affect the flags. We assume that shifts by constant
11627 ;; zero are optimized away.
11628 (define_insn "*ashrsi3_one_bit_cmp"
11629 [(set (reg FLAGS_REG)
11631 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11632 (match_operand:QI 2 "const1_operand" ""))
11634 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11635 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11636 "ix86_match_ccmode (insn, CCGOCmode)
11637 && (TARGET_SHIFT1 || optimize_size)
11638 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11640 [(set_attr "type" "ishift")
11641 (set (attr "length")
11642 (if_then_else (match_operand:SI 0 "register_operand" "")
11644 (const_string "*")))])
11646 (define_insn "*ashrsi3_one_bit_cconly"
11647 [(set (reg FLAGS_REG)
11649 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11650 (match_operand:QI 2 "const1_operand" ""))
11652 (clobber (match_scratch:SI 0 "=r"))]
11653 "ix86_match_ccmode (insn, CCGOCmode)
11654 && (TARGET_SHIFT1 || optimize_size)
11655 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11657 [(set_attr "type" "ishift")
11658 (set_attr "length" "2")])
11660 (define_insn "*ashrsi3_one_bit_cmp_zext"
11661 [(set (reg FLAGS_REG)
11663 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11664 (match_operand:QI 2 "const1_operand" ""))
11666 (set (match_operand:DI 0 "register_operand" "=r")
11667 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11668 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11669 && (TARGET_SHIFT1 || optimize_size)
11670 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11672 [(set_attr "type" "ishift")
11673 (set_attr "length" "2")])
11675 ;; This pattern can't accept a variable shift count, since shifts by
11676 ;; zero don't affect the flags. We assume that shifts by constant
11677 ;; zero are optimized away.
11678 (define_insn "*ashrsi3_cmp"
11679 [(set (reg FLAGS_REG)
11681 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11682 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11684 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11685 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11686 "ix86_match_ccmode (insn, CCGOCmode)
11687 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11689 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11690 "sar{l}\t{%2, %0|%0, %2}"
11691 [(set_attr "type" "ishift")
11692 (set_attr "mode" "SI")])
11694 (define_insn "*ashrsi3_cconly"
11695 [(set (reg FLAGS_REG)
11697 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11698 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11700 (clobber (match_scratch:SI 0 "=r"))]
11701 "ix86_match_ccmode (insn, CCGOCmode)
11702 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11704 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11705 "sar{l}\t{%2, %0|%0, %2}"
11706 [(set_attr "type" "ishift")
11707 (set_attr "mode" "SI")])
11709 (define_insn "*ashrsi3_cmp_zext"
11710 [(set (reg FLAGS_REG)
11712 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11713 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11715 (set (match_operand:DI 0 "register_operand" "=r")
11716 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11717 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11718 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11720 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11721 "sar{l}\t{%2, %k0|%k0, %2}"
11722 [(set_attr "type" "ishift")
11723 (set_attr "mode" "SI")])
11725 (define_expand "ashrhi3"
11726 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11727 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11728 (match_operand:QI 2 "nonmemory_operand" "")))
11729 (clobber (reg:CC FLAGS_REG))]
11730 "TARGET_HIMODE_MATH"
11731 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11733 (define_insn "*ashrhi3_1_one_bit"
11734 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11735 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11736 (match_operand:QI 2 "const1_operand" "")))
11737 (clobber (reg:CC FLAGS_REG))]
11738 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11739 && (TARGET_SHIFT1 || optimize_size)"
11741 [(set_attr "type" "ishift")
11742 (set (attr "length")
11743 (if_then_else (match_operand 0 "register_operand" "")
11745 (const_string "*")))])
11747 (define_insn "*ashrhi3_1"
11748 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11749 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11750 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11751 (clobber (reg:CC FLAGS_REG))]
11752 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11754 sar{w}\t{%2, %0|%0, %2}
11755 sar{w}\t{%b2, %0|%0, %b2}"
11756 [(set_attr "type" "ishift")
11757 (set_attr "mode" "HI")])
11759 ;; This pattern can't accept a variable shift count, since shifts by
11760 ;; zero don't affect the flags. We assume that shifts by constant
11761 ;; zero are optimized away.
11762 (define_insn "*ashrhi3_one_bit_cmp"
11763 [(set (reg FLAGS_REG)
11765 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11766 (match_operand:QI 2 "const1_operand" ""))
11768 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11769 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11770 "ix86_match_ccmode (insn, CCGOCmode)
11771 && (TARGET_SHIFT1 || optimize_size)
11772 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11774 [(set_attr "type" "ishift")
11775 (set (attr "length")
11776 (if_then_else (match_operand 0 "register_operand" "")
11778 (const_string "*")))])
11780 (define_insn "*ashrhi3_one_bit_cconly"
11781 [(set (reg FLAGS_REG)
11783 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11784 (match_operand:QI 2 "const1_operand" ""))
11786 (clobber (match_scratch:HI 0 "=r"))]
11787 "ix86_match_ccmode (insn, CCGOCmode)
11788 && (TARGET_SHIFT1 || optimize_size)
11789 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11791 [(set_attr "type" "ishift")
11792 (set_attr "length" "2")])
11794 ;; This pattern can't accept a variable shift count, since shifts by
11795 ;; zero don't affect the flags. We assume that shifts by constant
11796 ;; zero are optimized away.
11797 (define_insn "*ashrhi3_cmp"
11798 [(set (reg FLAGS_REG)
11800 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11801 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11803 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11804 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11805 "ix86_match_ccmode (insn, CCGOCmode)
11806 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11808 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11809 "sar{w}\t{%2, %0|%0, %2}"
11810 [(set_attr "type" "ishift")
11811 (set_attr "mode" "HI")])
11813 (define_insn "*ashrhi3_cconly"
11814 [(set (reg FLAGS_REG)
11816 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11817 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11819 (clobber (match_scratch:HI 0 "=r"))]
11820 "ix86_match_ccmode (insn, CCGOCmode)
11821 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11823 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11824 "sar{w}\t{%2, %0|%0, %2}"
11825 [(set_attr "type" "ishift")
11826 (set_attr "mode" "HI")])
11828 (define_expand "ashrqi3"
11829 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11830 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11831 (match_operand:QI 2 "nonmemory_operand" "")))
11832 (clobber (reg:CC FLAGS_REG))]
11833 "TARGET_QIMODE_MATH"
11834 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11836 (define_insn "*ashrqi3_1_one_bit"
11837 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11838 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11839 (match_operand:QI 2 "const1_operand" "")))
11840 (clobber (reg:CC FLAGS_REG))]
11841 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11842 && (TARGET_SHIFT1 || optimize_size)"
11844 [(set_attr "type" "ishift")
11845 (set (attr "length")
11846 (if_then_else (match_operand 0 "register_operand" "")
11848 (const_string "*")))])
11850 (define_insn "*ashrqi3_1_one_bit_slp"
11851 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11852 (ashiftrt:QI (match_dup 0)
11853 (match_operand:QI 1 "const1_operand" "")))
11854 (clobber (reg:CC FLAGS_REG))]
11855 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11856 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11857 && (TARGET_SHIFT1 || optimize_size)"
11859 [(set_attr "type" "ishift1")
11860 (set (attr "length")
11861 (if_then_else (match_operand 0 "register_operand" "")
11863 (const_string "*")))])
11865 (define_insn "*ashrqi3_1"
11866 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11867 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11868 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11869 (clobber (reg:CC FLAGS_REG))]
11870 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11872 sar{b}\t{%2, %0|%0, %2}
11873 sar{b}\t{%b2, %0|%0, %b2}"
11874 [(set_attr "type" "ishift")
11875 (set_attr "mode" "QI")])
11877 (define_insn "*ashrqi3_1_slp"
11878 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11879 (ashiftrt:QI (match_dup 0)
11880 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11881 (clobber (reg:CC FLAGS_REG))]
11882 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11883 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11885 sar{b}\t{%1, %0|%0, %1}
11886 sar{b}\t{%b1, %0|%0, %b1}"
11887 [(set_attr "type" "ishift1")
11888 (set_attr "mode" "QI")])
11890 ;; This pattern can't accept a variable shift count, since shifts by
11891 ;; zero don't affect the flags. We assume that shifts by constant
11892 ;; zero are optimized away.
11893 (define_insn "*ashrqi3_one_bit_cmp"
11894 [(set (reg FLAGS_REG)
11896 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11897 (match_operand:QI 2 "const1_operand" "I"))
11899 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11900 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11901 "ix86_match_ccmode (insn, CCGOCmode)
11902 && (TARGET_SHIFT1 || optimize_size)
11903 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11905 [(set_attr "type" "ishift")
11906 (set (attr "length")
11907 (if_then_else (match_operand 0 "register_operand" "")
11909 (const_string "*")))])
11911 (define_insn "*ashrqi3_one_bit_cconly"
11912 [(set (reg FLAGS_REG)
11914 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11915 (match_operand:QI 2 "const1_operand" "I"))
11917 (clobber (match_scratch:QI 0 "=q"))]
11918 "ix86_match_ccmode (insn, CCGOCmode)
11919 && (TARGET_SHIFT1 || optimize_size)
11920 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11922 [(set_attr "type" "ishift")
11923 (set_attr "length" "2")])
11925 ;; This pattern can't accept a variable shift count, since shifts by
11926 ;; zero don't affect the flags. We assume that shifts by constant
11927 ;; zero are optimized away.
11928 (define_insn "*ashrqi3_cmp"
11929 [(set (reg FLAGS_REG)
11931 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11932 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11934 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11935 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11936 "ix86_match_ccmode (insn, CCGOCmode)
11937 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11939 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11940 "sar{b}\t{%2, %0|%0, %2}"
11941 [(set_attr "type" "ishift")
11942 (set_attr "mode" "QI")])
11944 (define_insn "*ashrqi3_cconly"
11945 [(set (reg FLAGS_REG)
11947 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11950 (clobber (match_scratch:QI 0 "=q"))]
11951 "ix86_match_ccmode (insn, CCGOCmode)
11952 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11954 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11955 "sar{b}\t{%2, %0|%0, %2}"
11956 [(set_attr "type" "ishift")
11957 (set_attr "mode" "QI")])
11960 ;; Logical shift instructions
11962 ;; See comment above `ashldi3' about how this works.
11964 (define_expand "lshrti3"
11965 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11966 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11967 (match_operand:QI 2 "nonmemory_operand" "")))
11968 (clobber (reg:CC FLAGS_REG))])]
11971 if (! immediate_operand (operands[2], QImode))
11973 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11976 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11980 (define_insn "lshrti3_1"
11981 [(set (match_operand:TI 0 "register_operand" "=r")
11982 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11983 (match_operand:QI 2 "register_operand" "c")))
11984 (clobber (match_scratch:DI 3 "=&r"))
11985 (clobber (reg:CC FLAGS_REG))]
11988 [(set_attr "type" "multi")])
11990 (define_insn "*lshrti3_2"
11991 [(set (match_operand:TI 0 "register_operand" "=r")
11992 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11993 (match_operand:QI 2 "immediate_operand" "O")))
11994 (clobber (reg:CC FLAGS_REG))]
11997 [(set_attr "type" "multi")])
12000 [(set (match_operand:TI 0 "register_operand" "")
12001 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12002 (match_operand:QI 2 "register_operand" "")))
12003 (clobber (match_scratch:DI 3 ""))
12004 (clobber (reg:CC FLAGS_REG))]
12005 "TARGET_64BIT && reload_completed"
12007 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12010 [(set (match_operand:TI 0 "register_operand" "")
12011 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12012 (match_operand:QI 2 "immediate_operand" "")))
12013 (clobber (reg:CC FLAGS_REG))]
12014 "TARGET_64BIT && reload_completed"
12016 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12018 (define_expand "lshrdi3"
12019 [(set (match_operand:DI 0 "shiftdi_operand" "")
12020 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12021 (match_operand:QI 2 "nonmemory_operand" "")))]
12023 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12025 (define_insn "*lshrdi3_1_one_bit_rex64"
12026 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12027 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12028 (match_operand:QI 2 "const1_operand" "")))
12029 (clobber (reg:CC FLAGS_REG))]
12030 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12031 && (TARGET_SHIFT1 || optimize_size)"
12033 [(set_attr "type" "ishift")
12034 (set (attr "length")
12035 (if_then_else (match_operand:DI 0 "register_operand" "")
12037 (const_string "*")))])
12039 (define_insn "*lshrdi3_1_rex64"
12040 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12041 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12042 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12043 (clobber (reg:CC FLAGS_REG))]
12044 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12046 shr{q}\t{%2, %0|%0, %2}
12047 shr{q}\t{%b2, %0|%0, %b2}"
12048 [(set_attr "type" "ishift")
12049 (set_attr "mode" "DI")])
12051 ;; This pattern can't accept a variable shift count, since shifts by
12052 ;; zero don't affect the flags. We assume that shifts by constant
12053 ;; zero are optimized away.
12054 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12055 [(set (reg FLAGS_REG)
12057 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12058 (match_operand:QI 2 "const1_operand" ""))
12060 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12061 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12062 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12063 && (TARGET_SHIFT1 || optimize_size)
12064 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12066 [(set_attr "type" "ishift")
12067 (set (attr "length")
12068 (if_then_else (match_operand:DI 0 "register_operand" "")
12070 (const_string "*")))])
12072 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12073 [(set (reg FLAGS_REG)
12075 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12076 (match_operand:QI 2 "const1_operand" ""))
12078 (clobber (match_scratch:DI 0 "=r"))]
12079 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12080 && (TARGET_SHIFT1 || optimize_size)
12081 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12083 [(set_attr "type" "ishift")
12084 (set_attr "length" "2")])
12086 ;; This pattern can't accept a variable shift count, since shifts by
12087 ;; zero don't affect the flags. We assume that shifts by constant
12088 ;; zero are optimized away.
12089 (define_insn "*lshrdi3_cmp_rex64"
12090 [(set (reg FLAGS_REG)
12092 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12093 (match_operand:QI 2 "const_int_operand" "e"))
12095 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12096 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12097 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12098 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12100 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12101 "shr{q}\t{%2, %0|%0, %2}"
12102 [(set_attr "type" "ishift")
12103 (set_attr "mode" "DI")])
12105 (define_insn "*lshrdi3_cconly_rex64"
12106 [(set (reg FLAGS_REG)
12108 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12109 (match_operand:QI 2 "const_int_operand" "e"))
12111 (clobber (match_scratch:DI 0 "=r"))]
12112 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12113 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12115 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12116 "shr{q}\t{%2, %0|%0, %2}"
12117 [(set_attr "type" "ishift")
12118 (set_attr "mode" "DI")])
12120 (define_insn "*lshrdi3_1"
12121 [(set (match_operand:DI 0 "register_operand" "=r")
12122 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12123 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12124 (clobber (reg:CC FLAGS_REG))]
12127 [(set_attr "type" "multi")])
12129 ;; By default we don't ask for a scratch register, because when DImode
12130 ;; values are manipulated, registers are already at a premium. But if
12131 ;; we have one handy, we won't turn it away.
12133 [(match_scratch:SI 3 "r")
12134 (parallel [(set (match_operand:DI 0 "register_operand" "")
12135 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12136 (match_operand:QI 2 "nonmemory_operand" "")))
12137 (clobber (reg:CC FLAGS_REG))])
12139 "!TARGET_64BIT && TARGET_CMOVE"
12141 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12144 [(set (match_operand:DI 0 "register_operand" "")
12145 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12146 (match_operand:QI 2 "nonmemory_operand" "")))
12147 (clobber (reg:CC FLAGS_REG))]
12148 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12149 ? flow2_completed : reload_completed)"
12151 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12153 (define_expand "lshrsi3"
12154 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12155 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12156 (match_operand:QI 2 "nonmemory_operand" "")))
12157 (clobber (reg:CC FLAGS_REG))]
12159 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12161 (define_insn "*lshrsi3_1_one_bit"
12162 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12163 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12164 (match_operand:QI 2 "const1_operand" "")))
12165 (clobber (reg:CC FLAGS_REG))]
12166 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12167 && (TARGET_SHIFT1 || optimize_size)"
12169 [(set_attr "type" "ishift")
12170 (set (attr "length")
12171 (if_then_else (match_operand:SI 0 "register_operand" "")
12173 (const_string "*")))])
12175 (define_insn "*lshrsi3_1_one_bit_zext"
12176 [(set (match_operand:DI 0 "register_operand" "=r")
12177 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12178 (match_operand:QI 2 "const1_operand" "")))
12179 (clobber (reg:CC FLAGS_REG))]
12180 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12181 && (TARGET_SHIFT1 || optimize_size)"
12183 [(set_attr "type" "ishift")
12184 (set_attr "length" "2")])
12186 (define_insn "*lshrsi3_1"
12187 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12188 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12189 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12190 (clobber (reg:CC FLAGS_REG))]
12191 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12193 shr{l}\t{%2, %0|%0, %2}
12194 shr{l}\t{%b2, %0|%0, %b2}"
12195 [(set_attr "type" "ishift")
12196 (set_attr "mode" "SI")])
12198 (define_insn "*lshrsi3_1_zext"
12199 [(set (match_operand:DI 0 "register_operand" "=r,r")
12201 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12202 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12203 (clobber (reg:CC FLAGS_REG))]
12204 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12206 shr{l}\t{%2, %k0|%k0, %2}
12207 shr{l}\t{%b2, %k0|%k0, %b2}"
12208 [(set_attr "type" "ishift")
12209 (set_attr "mode" "SI")])
12211 ;; This pattern can't accept a variable shift count, since shifts by
12212 ;; zero don't affect the flags. We assume that shifts by constant
12213 ;; zero are optimized away.
12214 (define_insn "*lshrsi3_one_bit_cmp"
12215 [(set (reg FLAGS_REG)
12217 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12218 (match_operand:QI 2 "const1_operand" ""))
12220 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12221 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12222 "ix86_match_ccmode (insn, CCGOCmode)
12223 && (TARGET_SHIFT1 || optimize_size)
12224 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12226 [(set_attr "type" "ishift")
12227 (set (attr "length")
12228 (if_then_else (match_operand:SI 0 "register_operand" "")
12230 (const_string "*")))])
12232 (define_insn "*lshrsi3_one_bit_cconly"
12233 [(set (reg FLAGS_REG)
12235 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12236 (match_operand:QI 2 "const1_operand" ""))
12238 (clobber (match_scratch:SI 0 "=r"))]
12239 "ix86_match_ccmode (insn, CCGOCmode)
12240 && (TARGET_SHIFT1 || optimize_size)
12241 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12243 [(set_attr "type" "ishift")
12244 (set_attr "length" "2")])
12246 (define_insn "*lshrsi3_cmp_one_bit_zext"
12247 [(set (reg FLAGS_REG)
12249 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12250 (match_operand:QI 2 "const1_operand" ""))
12252 (set (match_operand:DI 0 "register_operand" "=r")
12253 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12254 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12255 && (TARGET_SHIFT1 || optimize_size)
12256 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12258 [(set_attr "type" "ishift")
12259 (set_attr "length" "2")])
12261 ;; This pattern can't accept a variable shift count, since shifts by
12262 ;; zero don't affect the flags. We assume that shifts by constant
12263 ;; zero are optimized away.
12264 (define_insn "*lshrsi3_cmp"
12265 [(set (reg FLAGS_REG)
12267 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12268 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12270 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12271 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12272 "ix86_match_ccmode (insn, CCGOCmode)
12273 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12275 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12276 "shr{l}\t{%2, %0|%0, %2}"
12277 [(set_attr "type" "ishift")
12278 (set_attr "mode" "SI")])
12280 (define_insn "*lshrsi3_cconly"
12281 [(set (reg FLAGS_REG)
12283 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12284 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12286 (clobber (match_scratch:SI 0 "=r"))]
12287 "ix86_match_ccmode (insn, CCGOCmode)
12288 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12290 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12291 "shr{l}\t{%2, %0|%0, %2}"
12292 [(set_attr "type" "ishift")
12293 (set_attr "mode" "SI")])
12295 (define_insn "*lshrsi3_cmp_zext"
12296 [(set (reg FLAGS_REG)
12298 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12299 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12301 (set (match_operand:DI 0 "register_operand" "=r")
12302 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12303 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12304 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12306 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12307 "shr{l}\t{%2, %k0|%k0, %2}"
12308 [(set_attr "type" "ishift")
12309 (set_attr "mode" "SI")])
12311 (define_expand "lshrhi3"
12312 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12313 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12314 (match_operand:QI 2 "nonmemory_operand" "")))
12315 (clobber (reg:CC FLAGS_REG))]
12316 "TARGET_HIMODE_MATH"
12317 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12319 (define_insn "*lshrhi3_1_one_bit"
12320 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12321 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12322 (match_operand:QI 2 "const1_operand" "")))
12323 (clobber (reg:CC FLAGS_REG))]
12324 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12325 && (TARGET_SHIFT1 || optimize_size)"
12327 [(set_attr "type" "ishift")
12328 (set (attr "length")
12329 (if_then_else (match_operand 0 "register_operand" "")
12331 (const_string "*")))])
12333 (define_insn "*lshrhi3_1"
12334 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12335 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12336 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12337 (clobber (reg:CC FLAGS_REG))]
12338 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12340 shr{w}\t{%2, %0|%0, %2}
12341 shr{w}\t{%b2, %0|%0, %b2}"
12342 [(set_attr "type" "ishift")
12343 (set_attr "mode" "HI")])
12345 ;; This pattern can't accept a variable shift count, since shifts by
12346 ;; zero don't affect the flags. We assume that shifts by constant
12347 ;; zero are optimized away.
12348 (define_insn "*lshrhi3_one_bit_cmp"
12349 [(set (reg FLAGS_REG)
12351 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12352 (match_operand:QI 2 "const1_operand" ""))
12354 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12355 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12356 "ix86_match_ccmode (insn, CCGOCmode)
12357 && (TARGET_SHIFT1 || optimize_size)
12358 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12360 [(set_attr "type" "ishift")
12361 (set (attr "length")
12362 (if_then_else (match_operand:SI 0 "register_operand" "")
12364 (const_string "*")))])
12366 (define_insn "*lshrhi3_one_bit_cconly"
12367 [(set (reg FLAGS_REG)
12369 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12370 (match_operand:QI 2 "const1_operand" ""))
12372 (clobber (match_scratch:HI 0 "=r"))]
12373 "ix86_match_ccmode (insn, CCGOCmode)
12374 && (TARGET_SHIFT1 || optimize_size)
12375 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12377 [(set_attr "type" "ishift")
12378 (set_attr "length" "2")])
12380 ;; This pattern can't accept a variable shift count, since shifts by
12381 ;; zero don't affect the flags. We assume that shifts by constant
12382 ;; zero are optimized away.
12383 (define_insn "*lshrhi3_cmp"
12384 [(set (reg FLAGS_REG)
12386 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12387 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12389 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12390 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12391 "ix86_match_ccmode (insn, CCGOCmode)
12392 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12394 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12395 "shr{w}\t{%2, %0|%0, %2}"
12396 [(set_attr "type" "ishift")
12397 (set_attr "mode" "HI")])
12399 (define_insn "*lshrhi3_cconly"
12400 [(set (reg FLAGS_REG)
12402 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12403 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12405 (clobber (match_scratch:HI 0 "=r"))]
12406 "ix86_match_ccmode (insn, CCGOCmode)
12407 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12409 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12410 "shr{w}\t{%2, %0|%0, %2}"
12411 [(set_attr "type" "ishift")
12412 (set_attr "mode" "HI")])
12414 (define_expand "lshrqi3"
12415 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12416 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12417 (match_operand:QI 2 "nonmemory_operand" "")))
12418 (clobber (reg:CC FLAGS_REG))]
12419 "TARGET_QIMODE_MATH"
12420 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12422 (define_insn "*lshrqi3_1_one_bit"
12423 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12424 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12425 (match_operand:QI 2 "const1_operand" "")))
12426 (clobber (reg:CC FLAGS_REG))]
12427 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12428 && (TARGET_SHIFT1 || optimize_size)"
12430 [(set_attr "type" "ishift")
12431 (set (attr "length")
12432 (if_then_else (match_operand 0 "register_operand" "")
12434 (const_string "*")))])
12436 (define_insn "*lshrqi3_1_one_bit_slp"
12437 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12438 (lshiftrt:QI (match_dup 0)
12439 (match_operand:QI 1 "const1_operand" "")))
12440 (clobber (reg:CC FLAGS_REG))]
12441 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12442 && (TARGET_SHIFT1 || optimize_size)"
12444 [(set_attr "type" "ishift1")
12445 (set (attr "length")
12446 (if_then_else (match_operand 0 "register_operand" "")
12448 (const_string "*")))])
12450 (define_insn "*lshrqi3_1"
12451 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12452 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12453 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12454 (clobber (reg:CC FLAGS_REG))]
12455 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12457 shr{b}\t{%2, %0|%0, %2}
12458 shr{b}\t{%b2, %0|%0, %b2}"
12459 [(set_attr "type" "ishift")
12460 (set_attr "mode" "QI")])
12462 (define_insn "*lshrqi3_1_slp"
12463 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12464 (lshiftrt:QI (match_dup 0)
12465 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12466 (clobber (reg:CC FLAGS_REG))]
12467 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12468 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12470 shr{b}\t{%1, %0|%0, %1}
12471 shr{b}\t{%b1, %0|%0, %b1}"
12472 [(set_attr "type" "ishift1")
12473 (set_attr "mode" "QI")])
12475 ;; This pattern can't accept a variable shift count, since shifts by
12476 ;; zero don't affect the flags. We assume that shifts by constant
12477 ;; zero are optimized away.
12478 (define_insn "*lshrqi2_one_bit_cmp"
12479 [(set (reg FLAGS_REG)
12481 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12482 (match_operand:QI 2 "const1_operand" ""))
12484 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12485 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12486 "ix86_match_ccmode (insn, CCGOCmode)
12487 && (TARGET_SHIFT1 || optimize_size)
12488 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12490 [(set_attr "type" "ishift")
12491 (set (attr "length")
12492 (if_then_else (match_operand:SI 0 "register_operand" "")
12494 (const_string "*")))])
12496 (define_insn "*lshrqi2_one_bit_cconly"
12497 [(set (reg FLAGS_REG)
12499 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12500 (match_operand:QI 2 "const1_operand" ""))
12502 (clobber (match_scratch:QI 0 "=q"))]
12503 "ix86_match_ccmode (insn, CCGOCmode)
12504 && (TARGET_SHIFT1 || optimize_size)
12505 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12507 [(set_attr "type" "ishift")
12508 (set_attr "length" "2")])
12510 ;; This pattern can't accept a variable shift count, since shifts by
12511 ;; zero don't affect the flags. We assume that shifts by constant
12512 ;; zero are optimized away.
12513 (define_insn "*lshrqi2_cmp"
12514 [(set (reg FLAGS_REG)
12516 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12517 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12519 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12520 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12521 "ix86_match_ccmode (insn, CCGOCmode)
12522 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12524 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12525 "shr{b}\t{%2, %0|%0, %2}"
12526 [(set_attr "type" "ishift")
12527 (set_attr "mode" "QI")])
12529 (define_insn "*lshrqi2_cconly"
12530 [(set (reg FLAGS_REG)
12532 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12533 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12535 (clobber (match_scratch:QI 0 "=q"))]
12536 "ix86_match_ccmode (insn, CCGOCmode)
12537 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12539 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12540 "shr{b}\t{%2, %0|%0, %2}"
12541 [(set_attr "type" "ishift")
12542 (set_attr "mode" "QI")])
12544 ;; Rotate instructions
12546 (define_expand "rotldi3"
12547 [(set (match_operand:DI 0 "shiftdi_operand" "")
12548 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12549 (match_operand:QI 2 "nonmemory_operand" "")))
12550 (clobber (reg:CC FLAGS_REG))]
12555 ix86_expand_binary_operator (ROTATE, DImode, operands);
12558 if (!const_1_to_31_operand (operands[2], VOIDmode))
12560 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12564 ;; Implement rotation using two double-precision shift instructions
12565 ;; and a scratch register.
12566 (define_insn_and_split "ix86_rotldi3"
12567 [(set (match_operand:DI 0 "register_operand" "=r")
12568 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12569 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12570 (clobber (reg:CC FLAGS_REG))
12571 (clobber (match_scratch:SI 3 "=&r"))]
12574 "&& reload_completed"
12575 [(set (match_dup 3) (match_dup 4))
12577 [(set (match_dup 4)
12578 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12579 (lshiftrt:SI (match_dup 5)
12580 (minus:QI (const_int 32) (match_dup 2)))))
12581 (clobber (reg:CC FLAGS_REG))])
12583 [(set (match_dup 5)
12584 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12585 (lshiftrt:SI (match_dup 3)
12586 (minus:QI (const_int 32) (match_dup 2)))))
12587 (clobber (reg:CC FLAGS_REG))])]
12588 "split_di (operands, 1, operands + 4, operands + 5);")
12590 (define_insn "*rotlsi3_1_one_bit_rex64"
12591 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12592 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12593 (match_operand:QI 2 "const1_operand" "")))
12594 (clobber (reg:CC FLAGS_REG))]
12595 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12596 && (TARGET_SHIFT1 || optimize_size)"
12598 [(set_attr "type" "rotate")
12599 (set (attr "length")
12600 (if_then_else (match_operand:DI 0 "register_operand" "")
12602 (const_string "*")))])
12604 (define_insn "*rotldi3_1_rex64"
12605 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12606 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12607 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12608 (clobber (reg:CC FLAGS_REG))]
12609 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12611 rol{q}\t{%2, %0|%0, %2}
12612 rol{q}\t{%b2, %0|%0, %b2}"
12613 [(set_attr "type" "rotate")
12614 (set_attr "mode" "DI")])
12616 (define_expand "rotlsi3"
12617 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12618 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12619 (match_operand:QI 2 "nonmemory_operand" "")))
12620 (clobber (reg:CC FLAGS_REG))]
12622 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12624 (define_insn "*rotlsi3_1_one_bit"
12625 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12626 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12627 (match_operand:QI 2 "const1_operand" "")))
12628 (clobber (reg:CC FLAGS_REG))]
12629 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12630 && (TARGET_SHIFT1 || optimize_size)"
12632 [(set_attr "type" "rotate")
12633 (set (attr "length")
12634 (if_then_else (match_operand:SI 0 "register_operand" "")
12636 (const_string "*")))])
12638 (define_insn "*rotlsi3_1_one_bit_zext"
12639 [(set (match_operand:DI 0 "register_operand" "=r")
12641 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12642 (match_operand:QI 2 "const1_operand" ""))))
12643 (clobber (reg:CC FLAGS_REG))]
12644 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12645 && (TARGET_SHIFT1 || optimize_size)"
12647 [(set_attr "type" "rotate")
12648 (set_attr "length" "2")])
12650 (define_insn "*rotlsi3_1"
12651 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12652 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12653 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12654 (clobber (reg:CC FLAGS_REG))]
12655 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12657 rol{l}\t{%2, %0|%0, %2}
12658 rol{l}\t{%b2, %0|%0, %b2}"
12659 [(set_attr "type" "rotate")
12660 (set_attr "mode" "SI")])
12662 (define_insn "*rotlsi3_1_zext"
12663 [(set (match_operand:DI 0 "register_operand" "=r,r")
12665 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12666 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12667 (clobber (reg:CC FLAGS_REG))]
12668 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12670 rol{l}\t{%2, %k0|%k0, %2}
12671 rol{l}\t{%b2, %k0|%k0, %b2}"
12672 [(set_attr "type" "rotate")
12673 (set_attr "mode" "SI")])
12675 (define_expand "rotlhi3"
12676 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12677 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12678 (match_operand:QI 2 "nonmemory_operand" "")))
12679 (clobber (reg:CC FLAGS_REG))]
12680 "TARGET_HIMODE_MATH"
12681 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12683 (define_insn "*rotlhi3_1_one_bit"
12684 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12685 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12686 (match_operand:QI 2 "const1_operand" "")))
12687 (clobber (reg:CC FLAGS_REG))]
12688 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12689 && (TARGET_SHIFT1 || optimize_size)"
12691 [(set_attr "type" "rotate")
12692 (set (attr "length")
12693 (if_then_else (match_operand 0 "register_operand" "")
12695 (const_string "*")))])
12697 (define_insn "*rotlhi3_1"
12698 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12699 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12700 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12701 (clobber (reg:CC FLAGS_REG))]
12702 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12704 rol{w}\t{%2, %0|%0, %2}
12705 rol{w}\t{%b2, %0|%0, %b2}"
12706 [(set_attr "type" "rotate")
12707 (set_attr "mode" "HI")])
12709 (define_expand "rotlqi3"
12710 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12711 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12712 (match_operand:QI 2 "nonmemory_operand" "")))
12713 (clobber (reg:CC FLAGS_REG))]
12714 "TARGET_QIMODE_MATH"
12715 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12717 (define_insn "*rotlqi3_1_one_bit_slp"
12718 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12719 (rotate:QI (match_dup 0)
12720 (match_operand:QI 1 "const1_operand" "")))
12721 (clobber (reg:CC FLAGS_REG))]
12722 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12723 && (TARGET_SHIFT1 || optimize_size)"
12725 [(set_attr "type" "rotate1")
12726 (set (attr "length")
12727 (if_then_else (match_operand 0 "register_operand" "")
12729 (const_string "*")))])
12731 (define_insn "*rotlqi3_1_one_bit"
12732 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12733 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12734 (match_operand:QI 2 "const1_operand" "")))
12735 (clobber (reg:CC FLAGS_REG))]
12736 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12737 && (TARGET_SHIFT1 || optimize_size)"
12739 [(set_attr "type" "rotate")
12740 (set (attr "length")
12741 (if_then_else (match_operand 0 "register_operand" "")
12743 (const_string "*")))])
12745 (define_insn "*rotlqi3_1_slp"
12746 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12747 (rotate:QI (match_dup 0)
12748 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12749 (clobber (reg:CC FLAGS_REG))]
12750 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12751 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12753 rol{b}\t{%1, %0|%0, %1}
12754 rol{b}\t{%b1, %0|%0, %b1}"
12755 [(set_attr "type" "rotate1")
12756 (set_attr "mode" "QI")])
12758 (define_insn "*rotlqi3_1"
12759 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12760 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12761 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12762 (clobber (reg:CC FLAGS_REG))]
12763 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12765 rol{b}\t{%2, %0|%0, %2}
12766 rol{b}\t{%b2, %0|%0, %b2}"
12767 [(set_attr "type" "rotate")
12768 (set_attr "mode" "QI")])
12770 (define_expand "rotrdi3"
12771 [(set (match_operand:DI 0 "shiftdi_operand" "")
12772 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12773 (match_operand:QI 2 "nonmemory_operand" "")))
12774 (clobber (reg:CC FLAGS_REG))]
12779 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12782 if (!const_1_to_31_operand (operands[2], VOIDmode))
12784 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12788 ;; Implement rotation using two double-precision shift instructions
12789 ;; and a scratch register.
12790 (define_insn_and_split "ix86_rotrdi3"
12791 [(set (match_operand:DI 0 "register_operand" "=r")
12792 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12793 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12794 (clobber (reg:CC FLAGS_REG))
12795 (clobber (match_scratch:SI 3 "=&r"))]
12798 "&& reload_completed"
12799 [(set (match_dup 3) (match_dup 4))
12801 [(set (match_dup 4)
12802 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12803 (ashift:SI (match_dup 5)
12804 (minus:QI (const_int 32) (match_dup 2)))))
12805 (clobber (reg:CC FLAGS_REG))])
12807 [(set (match_dup 5)
12808 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12809 (ashift:SI (match_dup 3)
12810 (minus:QI (const_int 32) (match_dup 2)))))
12811 (clobber (reg:CC FLAGS_REG))])]
12812 "split_di (operands, 1, operands + 4, operands + 5);")
12814 (define_insn "*rotrdi3_1_one_bit_rex64"
12815 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12816 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12817 (match_operand:QI 2 "const1_operand" "")))
12818 (clobber (reg:CC FLAGS_REG))]
12819 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12820 && (TARGET_SHIFT1 || optimize_size)"
12822 [(set_attr "type" "rotate")
12823 (set (attr "length")
12824 (if_then_else (match_operand:DI 0 "register_operand" "")
12826 (const_string "*")))])
12828 (define_insn "*rotrdi3_1_rex64"
12829 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12830 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12831 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12832 (clobber (reg:CC FLAGS_REG))]
12833 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12835 ror{q}\t{%2, %0|%0, %2}
12836 ror{q}\t{%b2, %0|%0, %b2}"
12837 [(set_attr "type" "rotate")
12838 (set_attr "mode" "DI")])
12840 (define_expand "rotrsi3"
12841 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12842 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12843 (match_operand:QI 2 "nonmemory_operand" "")))
12844 (clobber (reg:CC FLAGS_REG))]
12846 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12848 (define_insn "*rotrsi3_1_one_bit"
12849 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12850 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12851 (match_operand:QI 2 "const1_operand" "")))
12852 (clobber (reg:CC FLAGS_REG))]
12853 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12854 && (TARGET_SHIFT1 || optimize_size)"
12856 [(set_attr "type" "rotate")
12857 (set (attr "length")
12858 (if_then_else (match_operand:SI 0 "register_operand" "")
12860 (const_string "*")))])
12862 (define_insn "*rotrsi3_1_one_bit_zext"
12863 [(set (match_operand:DI 0 "register_operand" "=r")
12865 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12866 (match_operand:QI 2 "const1_operand" ""))))
12867 (clobber (reg:CC FLAGS_REG))]
12868 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12869 && (TARGET_SHIFT1 || optimize_size)"
12871 [(set_attr "type" "rotate")
12872 (set (attr "length")
12873 (if_then_else (match_operand:SI 0 "register_operand" "")
12875 (const_string "*")))])
12877 (define_insn "*rotrsi3_1"
12878 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12879 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12880 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12881 (clobber (reg:CC FLAGS_REG))]
12882 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12884 ror{l}\t{%2, %0|%0, %2}
12885 ror{l}\t{%b2, %0|%0, %b2}"
12886 [(set_attr "type" "rotate")
12887 (set_attr "mode" "SI")])
12889 (define_insn "*rotrsi3_1_zext"
12890 [(set (match_operand:DI 0 "register_operand" "=r,r")
12892 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12893 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12894 (clobber (reg:CC FLAGS_REG))]
12895 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12897 ror{l}\t{%2, %k0|%k0, %2}
12898 ror{l}\t{%b2, %k0|%k0, %b2}"
12899 [(set_attr "type" "rotate")
12900 (set_attr "mode" "SI")])
12902 (define_expand "rotrhi3"
12903 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12904 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12905 (match_operand:QI 2 "nonmemory_operand" "")))
12906 (clobber (reg:CC FLAGS_REG))]
12907 "TARGET_HIMODE_MATH"
12908 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12910 (define_insn "*rotrhi3_one_bit"
12911 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12912 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12913 (match_operand:QI 2 "const1_operand" "")))
12914 (clobber (reg:CC FLAGS_REG))]
12915 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12916 && (TARGET_SHIFT1 || optimize_size)"
12918 [(set_attr "type" "rotate")
12919 (set (attr "length")
12920 (if_then_else (match_operand 0 "register_operand" "")
12922 (const_string "*")))])
12924 (define_insn "*rotrhi3"
12925 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12926 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12927 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12928 (clobber (reg:CC FLAGS_REG))]
12929 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12931 ror{w}\t{%2, %0|%0, %2}
12932 ror{w}\t{%b2, %0|%0, %b2}"
12933 [(set_attr "type" "rotate")
12934 (set_attr "mode" "HI")])
12936 (define_expand "rotrqi3"
12937 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12938 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12939 (match_operand:QI 2 "nonmemory_operand" "")))
12940 (clobber (reg:CC FLAGS_REG))]
12941 "TARGET_QIMODE_MATH"
12942 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12944 (define_insn "*rotrqi3_1_one_bit"
12945 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12946 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12947 (match_operand:QI 2 "const1_operand" "")))
12948 (clobber (reg:CC FLAGS_REG))]
12949 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12950 && (TARGET_SHIFT1 || optimize_size)"
12952 [(set_attr "type" "rotate")
12953 (set (attr "length")
12954 (if_then_else (match_operand 0 "register_operand" "")
12956 (const_string "*")))])
12958 (define_insn "*rotrqi3_1_one_bit_slp"
12959 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12960 (rotatert:QI (match_dup 0)
12961 (match_operand:QI 1 "const1_operand" "")))
12962 (clobber (reg:CC FLAGS_REG))]
12963 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12964 && (TARGET_SHIFT1 || optimize_size)"
12966 [(set_attr "type" "rotate1")
12967 (set (attr "length")
12968 (if_then_else (match_operand 0 "register_operand" "")
12970 (const_string "*")))])
12972 (define_insn "*rotrqi3_1"
12973 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12974 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12975 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12976 (clobber (reg:CC FLAGS_REG))]
12977 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12979 ror{b}\t{%2, %0|%0, %2}
12980 ror{b}\t{%b2, %0|%0, %b2}"
12981 [(set_attr "type" "rotate")
12982 (set_attr "mode" "QI")])
12984 (define_insn "*rotrqi3_1_slp"
12985 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12986 (rotatert:QI (match_dup 0)
12987 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12988 (clobber (reg:CC FLAGS_REG))]
12989 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12990 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12992 ror{b}\t{%1, %0|%0, %1}
12993 ror{b}\t{%b1, %0|%0, %b1}"
12994 [(set_attr "type" "rotate1")
12995 (set_attr "mode" "QI")])
12997 ;; Bit set / bit test instructions
12999 (define_expand "extv"
13000 [(set (match_operand:SI 0 "register_operand" "")
13001 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13002 (match_operand:SI 2 "const8_operand" "")
13003 (match_operand:SI 3 "const8_operand" "")))]
13006 /* Handle extractions from %ah et al. */
13007 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13010 /* From mips.md: extract_bit_field doesn't verify that our source
13011 matches the predicate, so check it again here. */
13012 if (! ext_register_operand (operands[1], VOIDmode))
13016 (define_expand "extzv"
13017 [(set (match_operand:SI 0 "register_operand" "")
13018 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13019 (match_operand:SI 2 "const8_operand" "")
13020 (match_operand:SI 3 "const8_operand" "")))]
13023 /* Handle extractions from %ah et al. */
13024 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13027 /* From mips.md: extract_bit_field doesn't verify that our source
13028 matches the predicate, so check it again here. */
13029 if (! ext_register_operand (operands[1], VOIDmode))
13033 (define_expand "insv"
13034 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13035 (match_operand 1 "const8_operand" "")
13036 (match_operand 2 "const8_operand" ""))
13037 (match_operand 3 "register_operand" ""))]
13040 /* Handle insertions to %ah et al. */
13041 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13044 /* From mips.md: insert_bit_field doesn't verify that our source
13045 matches the predicate, so check it again here. */
13046 if (! ext_register_operand (operands[0], VOIDmode))
13050 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13052 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13057 ;; %%% bts, btr, btc, bt.
13058 ;; In general these instructions are *slow* when applied to memory,
13059 ;; since they enforce atomic operation. When applied to registers,
13060 ;; it depends on the cpu implementation. They're never faster than
13061 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13062 ;; no point. But in 64-bit, we can't hold the relevant immediates
13063 ;; within the instruction itself, so operating on bits in the high
13064 ;; 32-bits of a register becomes easier.
13066 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13067 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13068 ;; negdf respectively, so they can never be disabled entirely.
13070 (define_insn "*btsq"
13071 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13073 (match_operand:DI 1 "const_0_to_63_operand" ""))
13075 (clobber (reg:CC FLAGS_REG))]
13076 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13078 [(set_attr "type" "alu1")])
13080 (define_insn "*btrq"
13081 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13083 (match_operand:DI 1 "const_0_to_63_operand" ""))
13085 (clobber (reg:CC FLAGS_REG))]
13086 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13088 [(set_attr "type" "alu1")])
13090 (define_insn "*btcq"
13091 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13093 (match_operand:DI 1 "const_0_to_63_operand" ""))
13094 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13095 (clobber (reg:CC FLAGS_REG))]
13096 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13098 [(set_attr "type" "alu1")])
13100 ;; Allow Nocona to avoid these instructions if a register is available.
13103 [(match_scratch:DI 2 "r")
13104 (parallel [(set (zero_extract:DI
13105 (match_operand:DI 0 "register_operand" "")
13107 (match_operand:DI 1 "const_0_to_63_operand" ""))
13109 (clobber (reg:CC FLAGS_REG))])]
13110 "TARGET_64BIT && !TARGET_USE_BT"
13113 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13116 if (HOST_BITS_PER_WIDE_INT >= 64)
13117 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13118 else if (i < HOST_BITS_PER_WIDE_INT)
13119 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13121 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13123 op1 = immed_double_const (lo, hi, DImode);
13126 emit_move_insn (operands[2], op1);
13130 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13135 [(match_scratch:DI 2 "r")
13136 (parallel [(set (zero_extract:DI
13137 (match_operand:DI 0 "register_operand" "")
13139 (match_operand:DI 1 "const_0_to_63_operand" ""))
13141 (clobber (reg:CC FLAGS_REG))])]
13142 "TARGET_64BIT && !TARGET_USE_BT"
13145 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13148 if (HOST_BITS_PER_WIDE_INT >= 64)
13149 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13150 else if (i < HOST_BITS_PER_WIDE_INT)
13151 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13153 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13155 op1 = immed_double_const (~lo, ~hi, DImode);
13158 emit_move_insn (operands[2], op1);
13162 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13167 [(match_scratch:DI 2 "r")
13168 (parallel [(set (zero_extract:DI
13169 (match_operand:DI 0 "register_operand" "")
13171 (match_operand:DI 1 "const_0_to_63_operand" ""))
13172 (not:DI (zero_extract:DI
13173 (match_dup 0) (const_int 1) (match_dup 1))))
13174 (clobber (reg:CC FLAGS_REG))])]
13175 "TARGET_64BIT && !TARGET_USE_BT"
13178 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13181 if (HOST_BITS_PER_WIDE_INT >= 64)
13182 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13183 else if (i < HOST_BITS_PER_WIDE_INT)
13184 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13186 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13188 op1 = immed_double_const (lo, hi, DImode);
13191 emit_move_insn (operands[2], op1);
13195 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13199 ;; Store-flag instructions.
13201 ;; For all sCOND expanders, also expand the compare or test insn that
13202 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13204 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13205 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13206 ;; way, which can later delete the movzx if only QImode is needed.
13208 (define_expand "seq"
13209 [(set (match_operand:QI 0 "register_operand" "")
13210 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13212 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13214 (define_expand "sne"
13215 [(set (match_operand:QI 0 "register_operand" "")
13216 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13218 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13220 (define_expand "sgt"
13221 [(set (match_operand:QI 0 "register_operand" "")
13222 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13224 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13226 (define_expand "sgtu"
13227 [(set (match_operand:QI 0 "register_operand" "")
13228 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13230 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13232 (define_expand "slt"
13233 [(set (match_operand:QI 0 "register_operand" "")
13234 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13236 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13238 (define_expand "sltu"
13239 [(set (match_operand:QI 0 "register_operand" "")
13240 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13242 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13244 (define_expand "sge"
13245 [(set (match_operand:QI 0 "register_operand" "")
13246 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13248 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13250 (define_expand "sgeu"
13251 [(set (match_operand:QI 0 "register_operand" "")
13252 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13254 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13256 (define_expand "sle"
13257 [(set (match_operand:QI 0 "register_operand" "")
13258 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13260 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13262 (define_expand "sleu"
13263 [(set (match_operand:QI 0 "register_operand" "")
13264 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13266 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13268 (define_expand "sunordered"
13269 [(set (match_operand:QI 0 "register_operand" "")
13270 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13271 "TARGET_80387 || TARGET_SSE"
13272 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13274 (define_expand "sordered"
13275 [(set (match_operand:QI 0 "register_operand" "")
13276 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13278 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13280 (define_expand "suneq"
13281 [(set (match_operand:QI 0 "register_operand" "")
13282 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13283 "TARGET_80387 || TARGET_SSE"
13284 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13286 (define_expand "sunge"
13287 [(set (match_operand:QI 0 "register_operand" "")
13288 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13289 "TARGET_80387 || TARGET_SSE"
13290 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13292 (define_expand "sungt"
13293 [(set (match_operand:QI 0 "register_operand" "")
13294 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13295 "TARGET_80387 || TARGET_SSE"
13296 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13298 (define_expand "sunle"
13299 [(set (match_operand:QI 0 "register_operand" "")
13300 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13301 "TARGET_80387 || TARGET_SSE"
13302 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13304 (define_expand "sunlt"
13305 [(set (match_operand:QI 0 "register_operand" "")
13306 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13307 "TARGET_80387 || TARGET_SSE"
13308 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13310 (define_expand "sltgt"
13311 [(set (match_operand:QI 0 "register_operand" "")
13312 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13313 "TARGET_80387 || TARGET_SSE"
13314 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13316 (define_insn "*setcc_1"
13317 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13318 (match_operator:QI 1 "ix86_comparison_operator"
13319 [(reg FLAGS_REG) (const_int 0)]))]
13322 [(set_attr "type" "setcc")
13323 (set_attr "mode" "QI")])
13325 (define_insn "*setcc_2"
13326 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13327 (match_operator:QI 1 "ix86_comparison_operator"
13328 [(reg FLAGS_REG) (const_int 0)]))]
13331 [(set_attr "type" "setcc")
13332 (set_attr "mode" "QI")])
13334 ;; In general it is not safe to assume too much about CCmode registers,
13335 ;; so simplify-rtx stops when it sees a second one. Under certain
13336 ;; conditions this is safe on x86, so help combine not create
13343 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13344 (ne:QI (match_operator 1 "ix86_comparison_operator"
13345 [(reg FLAGS_REG) (const_int 0)])
13348 [(set (match_dup 0) (match_dup 1))]
13350 PUT_MODE (operands[1], QImode);
13354 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13355 (ne:QI (match_operator 1 "ix86_comparison_operator"
13356 [(reg FLAGS_REG) (const_int 0)])
13359 [(set (match_dup 0) (match_dup 1))]
13361 PUT_MODE (operands[1], QImode);
13365 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13366 (eq:QI (match_operator 1 "ix86_comparison_operator"
13367 [(reg FLAGS_REG) (const_int 0)])
13370 [(set (match_dup 0) (match_dup 1))]
13372 rtx new_op1 = copy_rtx (operands[1]);
13373 operands[1] = new_op1;
13374 PUT_MODE (new_op1, QImode);
13375 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13376 GET_MODE (XEXP (new_op1, 0))));
13378 /* Make sure that (a) the CCmode we have for the flags is strong
13379 enough for the reversed compare or (b) we have a valid FP compare. */
13380 if (! ix86_comparison_operator (new_op1, VOIDmode))
13385 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13386 (eq:QI (match_operator 1 "ix86_comparison_operator"
13387 [(reg FLAGS_REG) (const_int 0)])
13390 [(set (match_dup 0) (match_dup 1))]
13392 rtx new_op1 = copy_rtx (operands[1]);
13393 operands[1] = new_op1;
13394 PUT_MODE (new_op1, QImode);
13395 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13396 GET_MODE (XEXP (new_op1, 0))));
13398 /* Make sure that (a) the CCmode we have for the flags is strong
13399 enough for the reversed compare or (b) we have a valid FP compare. */
13400 if (! ix86_comparison_operator (new_op1, VOIDmode))
13404 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13405 ;; subsequent logical operations are used to imitate conditional moves.
13406 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13409 (define_insn "*sse_setccsf"
13410 [(set (match_operand:SF 0 "register_operand" "=x")
13411 (match_operator:SF 1 "sse_comparison_operator"
13412 [(match_operand:SF 2 "register_operand" "0")
13413 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13415 "cmp%D1ss\t{%3, %0|%0, %3}"
13416 [(set_attr "type" "ssecmp")
13417 (set_attr "mode" "SF")])
13419 (define_insn "*sse_setccdf"
13420 [(set (match_operand:DF 0 "register_operand" "=Y")
13421 (match_operator:DF 1 "sse_comparison_operator"
13422 [(match_operand:DF 2 "register_operand" "0")
13423 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13425 "cmp%D1sd\t{%3, %0|%0, %3}"
13426 [(set_attr "type" "ssecmp")
13427 (set_attr "mode" "DF")])
13429 ;; Basic conditional jump instructions.
13430 ;; We ignore the overflow flag for signed branch instructions.
13432 ;; For all bCOND expanders, also expand the compare or test insn that
13433 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13435 (define_expand "beq"
13437 (if_then_else (match_dup 1)
13438 (label_ref (match_operand 0 "" ""))
13441 "ix86_expand_branch (EQ, operands[0]); DONE;")
13443 (define_expand "bne"
13445 (if_then_else (match_dup 1)
13446 (label_ref (match_operand 0 "" ""))
13449 "ix86_expand_branch (NE, operands[0]); DONE;")
13451 (define_expand "bgt"
13453 (if_then_else (match_dup 1)
13454 (label_ref (match_operand 0 "" ""))
13457 "ix86_expand_branch (GT, operands[0]); DONE;")
13459 (define_expand "bgtu"
13461 (if_then_else (match_dup 1)
13462 (label_ref (match_operand 0 "" ""))
13465 "ix86_expand_branch (GTU, operands[0]); DONE;")
13467 (define_expand "blt"
13469 (if_then_else (match_dup 1)
13470 (label_ref (match_operand 0 "" ""))
13473 "ix86_expand_branch (LT, operands[0]); DONE;")
13475 (define_expand "bltu"
13477 (if_then_else (match_dup 1)
13478 (label_ref (match_operand 0 "" ""))
13481 "ix86_expand_branch (LTU, operands[0]); DONE;")
13483 (define_expand "bge"
13485 (if_then_else (match_dup 1)
13486 (label_ref (match_operand 0 "" ""))
13489 "ix86_expand_branch (GE, operands[0]); DONE;")
13491 (define_expand "bgeu"
13493 (if_then_else (match_dup 1)
13494 (label_ref (match_operand 0 "" ""))
13497 "ix86_expand_branch (GEU, operands[0]); DONE;")
13499 (define_expand "ble"
13501 (if_then_else (match_dup 1)
13502 (label_ref (match_operand 0 "" ""))
13505 "ix86_expand_branch (LE, operands[0]); DONE;")
13507 (define_expand "bleu"
13509 (if_then_else (match_dup 1)
13510 (label_ref (match_operand 0 "" ""))
13513 "ix86_expand_branch (LEU, operands[0]); DONE;")
13515 (define_expand "bunordered"
13517 (if_then_else (match_dup 1)
13518 (label_ref (match_operand 0 "" ""))
13520 "TARGET_80387 || TARGET_SSE_MATH"
13521 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13523 (define_expand "bordered"
13525 (if_then_else (match_dup 1)
13526 (label_ref (match_operand 0 "" ""))
13528 "TARGET_80387 || TARGET_SSE_MATH"
13529 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13531 (define_expand "buneq"
13533 (if_then_else (match_dup 1)
13534 (label_ref (match_operand 0 "" ""))
13536 "TARGET_80387 || TARGET_SSE_MATH"
13537 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13539 (define_expand "bunge"
13541 (if_then_else (match_dup 1)
13542 (label_ref (match_operand 0 "" ""))
13544 "TARGET_80387 || TARGET_SSE_MATH"
13545 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13547 (define_expand "bungt"
13549 (if_then_else (match_dup 1)
13550 (label_ref (match_operand 0 "" ""))
13552 "TARGET_80387 || TARGET_SSE_MATH"
13553 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13555 (define_expand "bunle"
13557 (if_then_else (match_dup 1)
13558 (label_ref (match_operand 0 "" ""))
13560 "TARGET_80387 || TARGET_SSE_MATH"
13561 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13563 (define_expand "bunlt"
13565 (if_then_else (match_dup 1)
13566 (label_ref (match_operand 0 "" ""))
13568 "TARGET_80387 || TARGET_SSE_MATH"
13569 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13571 (define_expand "bltgt"
13573 (if_then_else (match_dup 1)
13574 (label_ref (match_operand 0 "" ""))
13576 "TARGET_80387 || TARGET_SSE_MATH"
13577 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13579 (define_insn "*jcc_1"
13581 (if_then_else (match_operator 1 "ix86_comparison_operator"
13582 [(reg FLAGS_REG) (const_int 0)])
13583 (label_ref (match_operand 0 "" ""))
13587 [(set_attr "type" "ibr")
13588 (set_attr "modrm" "0")
13589 (set (attr "length")
13590 (if_then_else (and (ge (minus (match_dup 0) (pc))
13592 (lt (minus (match_dup 0) (pc))
13597 (define_insn "*jcc_2"
13599 (if_then_else (match_operator 1 "ix86_comparison_operator"
13600 [(reg FLAGS_REG) (const_int 0)])
13602 (label_ref (match_operand 0 "" ""))))]
13605 [(set_attr "type" "ibr")
13606 (set_attr "modrm" "0")
13607 (set (attr "length")
13608 (if_then_else (and (ge (minus (match_dup 0) (pc))
13610 (lt (minus (match_dup 0) (pc))
13615 ;; In general it is not safe to assume too much about CCmode registers,
13616 ;; so simplify-rtx stops when it sees a second one. Under certain
13617 ;; conditions this is safe on x86, so help combine not create
13625 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13626 [(reg FLAGS_REG) (const_int 0)])
13628 (label_ref (match_operand 1 "" ""))
13632 (if_then_else (match_dup 0)
13633 (label_ref (match_dup 1))
13636 PUT_MODE (operands[0], VOIDmode);
13641 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13642 [(reg FLAGS_REG) (const_int 0)])
13644 (label_ref (match_operand 1 "" ""))
13648 (if_then_else (match_dup 0)
13649 (label_ref (match_dup 1))
13652 rtx new_op0 = copy_rtx (operands[0]);
13653 operands[0] = new_op0;
13654 PUT_MODE (new_op0, VOIDmode);
13655 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13656 GET_MODE (XEXP (new_op0, 0))));
13658 /* Make sure that (a) the CCmode we have for the flags is strong
13659 enough for the reversed compare or (b) we have a valid FP compare. */
13660 if (! ix86_comparison_operator (new_op0, VOIDmode))
13664 ;; Define combination compare-and-branch fp compare instructions to use
13665 ;; during early optimization. Splitting the operation apart early makes
13666 ;; for bad code when we want to reverse the operation.
13668 (define_insn "*fp_jcc_1_mixed"
13670 (if_then_else (match_operator 0 "comparison_operator"
13671 [(match_operand 1 "register_operand" "f,x")
13672 (match_operand 2 "nonimmediate_operand" "f,xm")])
13673 (label_ref (match_operand 3 "" ""))
13675 (clobber (reg:CCFP FPSR_REG))
13676 (clobber (reg:CCFP FLAGS_REG))]
13677 "TARGET_MIX_SSE_I387
13678 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13679 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13680 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13683 (define_insn "*fp_jcc_1_sse"
13685 (if_then_else (match_operator 0 "comparison_operator"
13686 [(match_operand 1 "register_operand" "x")
13687 (match_operand 2 "nonimmediate_operand" "xm")])
13688 (label_ref (match_operand 3 "" ""))
13690 (clobber (reg:CCFP FPSR_REG))
13691 (clobber (reg:CCFP FLAGS_REG))]
13693 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13694 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13695 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13698 (define_insn "*fp_jcc_1_387"
13700 (if_then_else (match_operator 0 "comparison_operator"
13701 [(match_operand 1 "register_operand" "f")
13702 (match_operand 2 "register_operand" "f")])
13703 (label_ref (match_operand 3 "" ""))
13705 (clobber (reg:CCFP FPSR_REG))
13706 (clobber (reg:CCFP FLAGS_REG))]
13707 "TARGET_CMOVE && TARGET_80387
13708 && FLOAT_MODE_P (GET_MODE (operands[1]))
13709 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13710 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13713 (define_insn "*fp_jcc_2_mixed"
13715 (if_then_else (match_operator 0 "comparison_operator"
13716 [(match_operand 1 "register_operand" "f,x")
13717 (match_operand 2 "nonimmediate_operand" "f,xm")])
13719 (label_ref (match_operand 3 "" ""))))
13720 (clobber (reg:CCFP FPSR_REG))
13721 (clobber (reg:CCFP FLAGS_REG))]
13722 "TARGET_MIX_SSE_I387
13723 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13724 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13725 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13728 (define_insn "*fp_jcc_2_sse"
13730 (if_then_else (match_operator 0 "comparison_operator"
13731 [(match_operand 1 "register_operand" "x")
13732 (match_operand 2 "nonimmediate_operand" "xm")])
13734 (label_ref (match_operand 3 "" ""))))
13735 (clobber (reg:CCFP FPSR_REG))
13736 (clobber (reg:CCFP FLAGS_REG))]
13738 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13739 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13740 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13743 (define_insn "*fp_jcc_2_387"
13745 (if_then_else (match_operator 0 "comparison_operator"
13746 [(match_operand 1 "register_operand" "f")
13747 (match_operand 2 "register_operand" "f")])
13749 (label_ref (match_operand 3 "" ""))))
13750 (clobber (reg:CCFP FPSR_REG))
13751 (clobber (reg:CCFP FLAGS_REG))]
13752 "TARGET_CMOVE && TARGET_80387
13753 && FLOAT_MODE_P (GET_MODE (operands[1]))
13754 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13755 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13758 (define_insn "*fp_jcc_3_387"
13760 (if_then_else (match_operator 0 "comparison_operator"
13761 [(match_operand 1 "register_operand" "f")
13762 (match_operand 2 "nonimmediate_operand" "fm")])
13763 (label_ref (match_operand 3 "" ""))
13765 (clobber (reg:CCFP FPSR_REG))
13766 (clobber (reg:CCFP FLAGS_REG))
13767 (clobber (match_scratch:HI 4 "=a"))]
13769 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13770 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13771 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13772 && SELECT_CC_MODE (GET_CODE (operands[0]),
13773 operands[1], operands[2]) == CCFPmode
13774 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13777 (define_insn "*fp_jcc_4_387"
13779 (if_then_else (match_operator 0 "comparison_operator"
13780 [(match_operand 1 "register_operand" "f")
13781 (match_operand 2 "nonimmediate_operand" "fm")])
13783 (label_ref (match_operand 3 "" ""))))
13784 (clobber (reg:CCFP FPSR_REG))
13785 (clobber (reg:CCFP FLAGS_REG))
13786 (clobber (match_scratch:HI 4 "=a"))]
13788 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13789 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13790 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13791 && SELECT_CC_MODE (GET_CODE (operands[0]),
13792 operands[1], operands[2]) == CCFPmode
13793 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13796 (define_insn "*fp_jcc_5_387"
13798 (if_then_else (match_operator 0 "comparison_operator"
13799 [(match_operand 1 "register_operand" "f")
13800 (match_operand 2 "register_operand" "f")])
13801 (label_ref (match_operand 3 "" ""))
13803 (clobber (reg:CCFP FPSR_REG))
13804 (clobber (reg:CCFP FLAGS_REG))
13805 (clobber (match_scratch:HI 4 "=a"))]
13807 && FLOAT_MODE_P (GET_MODE (operands[1]))
13808 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13809 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13812 (define_insn "*fp_jcc_6_387"
13814 (if_then_else (match_operator 0 "comparison_operator"
13815 [(match_operand 1 "register_operand" "f")
13816 (match_operand 2 "register_operand" "f")])
13818 (label_ref (match_operand 3 "" ""))))
13819 (clobber (reg:CCFP FPSR_REG))
13820 (clobber (reg:CCFP FLAGS_REG))
13821 (clobber (match_scratch:HI 4 "=a"))]
13823 && FLOAT_MODE_P (GET_MODE (operands[1]))
13824 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13825 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13828 (define_insn "*fp_jcc_7_387"
13830 (if_then_else (match_operator 0 "comparison_operator"
13831 [(match_operand 1 "register_operand" "f")
13832 (match_operand 2 "const0_operand" "X")])
13833 (label_ref (match_operand 3 "" ""))
13835 (clobber (reg:CCFP FPSR_REG))
13836 (clobber (reg:CCFP FLAGS_REG))
13837 (clobber (match_scratch:HI 4 "=a"))]
13839 && FLOAT_MODE_P (GET_MODE (operands[1]))
13840 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13841 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13842 && SELECT_CC_MODE (GET_CODE (operands[0]),
13843 operands[1], operands[2]) == CCFPmode
13844 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13847 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13848 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13849 ;; with a precedence over other operators and is always put in the first
13850 ;; place. Swap condition and operands to match ficom instruction.
13852 (define_insn "*fp_jcc_8<mode>_387"
13854 (if_then_else (match_operator 0 "comparison_operator"
13855 [(match_operator 1 "float_operator"
13856 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13857 (match_operand 3 "register_operand" "f,f")])
13858 (label_ref (match_operand 4 "" ""))
13860 (clobber (reg:CCFP FPSR_REG))
13861 (clobber (reg:CCFP FLAGS_REG))
13862 (clobber (match_scratch:HI 5 "=a,a"))]
13863 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13864 && FLOAT_MODE_P (GET_MODE (operands[3]))
13865 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13866 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13867 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13868 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13873 (if_then_else (match_operator 0 "comparison_operator"
13874 [(match_operand 1 "register_operand" "")
13875 (match_operand 2 "nonimmediate_operand" "")])
13876 (match_operand 3 "" "")
13877 (match_operand 4 "" "")))
13878 (clobber (reg:CCFP FPSR_REG))
13879 (clobber (reg:CCFP FLAGS_REG))]
13883 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13884 operands[3], operands[4], NULL_RTX, NULL_RTX);
13890 (if_then_else (match_operator 0 "comparison_operator"
13891 [(match_operand 1 "register_operand" "")
13892 (match_operand 2 "general_operand" "")])
13893 (match_operand 3 "" "")
13894 (match_operand 4 "" "")))
13895 (clobber (reg:CCFP FPSR_REG))
13896 (clobber (reg:CCFP FLAGS_REG))
13897 (clobber (match_scratch:HI 5 "=a"))]
13901 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13902 operands[3], operands[4], operands[5], NULL_RTX);
13908 (if_then_else (match_operator 0 "comparison_operator"
13909 [(match_operator 1 "float_operator"
13910 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13911 (match_operand 3 "register_operand" "")])
13912 (match_operand 4 "" "")
13913 (match_operand 5 "" "")))
13914 (clobber (reg:CCFP FPSR_REG))
13915 (clobber (reg:CCFP FLAGS_REG))
13916 (clobber (match_scratch:HI 6 "=a"))]
13920 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13921 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13922 operands[3], operands[7],
13923 operands[4], operands[5], operands[6], NULL_RTX);
13927 ;; %%% Kill this when reload knows how to do it.
13930 (if_then_else (match_operator 0 "comparison_operator"
13931 [(match_operator 1 "float_operator"
13932 [(match_operand:X87MODEI12 2 "register_operand" "")])
13933 (match_operand 3 "register_operand" "")])
13934 (match_operand 4 "" "")
13935 (match_operand 5 "" "")))
13936 (clobber (reg:CCFP FPSR_REG))
13937 (clobber (reg:CCFP FLAGS_REG))
13938 (clobber (match_scratch:HI 6 "=a"))]
13942 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13943 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13944 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13945 operands[3], operands[7],
13946 operands[4], operands[5], operands[6], operands[2]);
13950 ;; Unconditional and other jump instructions
13952 (define_insn "jump"
13954 (label_ref (match_operand 0 "" "")))]
13957 [(set_attr "type" "ibr")
13958 (set (attr "length")
13959 (if_then_else (and (ge (minus (match_dup 0) (pc))
13961 (lt (minus (match_dup 0) (pc))
13965 (set_attr "modrm" "0")])
13967 (define_expand "indirect_jump"
13968 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13972 (define_insn "*indirect_jump"
13973 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13976 [(set_attr "type" "ibr")
13977 (set_attr "length_immediate" "0")])
13979 (define_insn "*indirect_jump_rtx64"
13980 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13983 [(set_attr "type" "ibr")
13984 (set_attr "length_immediate" "0")])
13986 (define_expand "tablejump"
13987 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13988 (use (label_ref (match_operand 1 "" "")))])]
13991 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13992 relative. Convert the relative address to an absolute address. */
13996 enum rtx_code code;
14002 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14004 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14008 op1 = pic_offset_table_rtx;
14013 op0 = pic_offset_table_rtx;
14017 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14022 (define_insn "*tablejump_1"
14023 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14024 (use (label_ref (match_operand 1 "" "")))]
14027 [(set_attr "type" "ibr")
14028 (set_attr "length_immediate" "0")])
14030 (define_insn "*tablejump_1_rtx64"
14031 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14032 (use (label_ref (match_operand 1 "" "")))]
14035 [(set_attr "type" "ibr")
14036 (set_attr "length_immediate" "0")])
14038 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14041 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14042 (set (match_operand:QI 1 "register_operand" "")
14043 (match_operator:QI 2 "ix86_comparison_operator"
14044 [(reg FLAGS_REG) (const_int 0)]))
14045 (set (match_operand 3 "q_regs_operand" "")
14046 (zero_extend (match_dup 1)))]
14047 "(peep2_reg_dead_p (3, operands[1])
14048 || operands_match_p (operands[1], operands[3]))
14049 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14050 [(set (match_dup 4) (match_dup 0))
14051 (set (strict_low_part (match_dup 5))
14054 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14055 operands[5] = gen_lowpart (QImode, operands[3]);
14056 ix86_expand_clear (operands[3]);
14059 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14062 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14063 (set (match_operand:QI 1 "register_operand" "")
14064 (match_operator:QI 2 "ix86_comparison_operator"
14065 [(reg FLAGS_REG) (const_int 0)]))
14066 (parallel [(set (match_operand 3 "q_regs_operand" "")
14067 (zero_extend (match_dup 1)))
14068 (clobber (reg:CC FLAGS_REG))])]
14069 "(peep2_reg_dead_p (3, operands[1])
14070 || operands_match_p (operands[1], operands[3]))
14071 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14072 [(set (match_dup 4) (match_dup 0))
14073 (set (strict_low_part (match_dup 5))
14076 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14077 operands[5] = gen_lowpart (QImode, operands[3]);
14078 ix86_expand_clear (operands[3]);
14081 ;; Call instructions.
14083 ;; The predicates normally associated with named expanders are not properly
14084 ;; checked for calls. This is a bug in the generic code, but it isn't that
14085 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14087 ;; Call subroutine returning no value.
14089 (define_expand "call_pop"
14090 [(parallel [(call (match_operand:QI 0 "" "")
14091 (match_operand:SI 1 "" ""))
14092 (set (reg:SI SP_REG)
14093 (plus:SI (reg:SI SP_REG)
14094 (match_operand:SI 3 "" "")))])]
14097 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14101 (define_insn "*call_pop_0"
14102 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14103 (match_operand:SI 1 "" ""))
14104 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14105 (match_operand:SI 2 "immediate_operand" "")))]
14108 if (SIBLING_CALL_P (insn))
14111 return "call\t%P0";
14113 [(set_attr "type" "call")])
14115 (define_insn "*call_pop_1"
14116 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14117 (match_operand:SI 1 "" ""))
14118 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14119 (match_operand:SI 2 "immediate_operand" "i")))]
14122 if (constant_call_address_operand (operands[0], Pmode))
14124 if (SIBLING_CALL_P (insn))
14127 return "call\t%P0";
14129 if (SIBLING_CALL_P (insn))
14132 return "call\t%A0";
14134 [(set_attr "type" "call")])
14136 (define_expand "call"
14137 [(call (match_operand:QI 0 "" "")
14138 (match_operand 1 "" ""))
14139 (use (match_operand 2 "" ""))]
14142 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14146 (define_expand "sibcall"
14147 [(call (match_operand:QI 0 "" "")
14148 (match_operand 1 "" ""))
14149 (use (match_operand 2 "" ""))]
14152 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14156 (define_insn "*call_0"
14157 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14158 (match_operand 1 "" ""))]
14161 if (SIBLING_CALL_P (insn))
14164 return "call\t%P0";
14166 [(set_attr "type" "call")])
14168 (define_insn "*call_1"
14169 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14170 (match_operand 1 "" ""))]
14171 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14173 if (constant_call_address_operand (operands[0], Pmode))
14174 return "call\t%P0";
14175 return "call\t%A0";
14177 [(set_attr "type" "call")])
14179 (define_insn "*sibcall_1"
14180 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14181 (match_operand 1 "" ""))]
14182 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14184 if (constant_call_address_operand (operands[0], Pmode))
14188 [(set_attr "type" "call")])
14190 (define_insn "*call_1_rex64"
14191 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14192 (match_operand 1 "" ""))]
14193 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14195 if (constant_call_address_operand (operands[0], Pmode))
14196 return "call\t%P0";
14197 return "call\t%A0";
14199 [(set_attr "type" "call")])
14201 (define_insn "*sibcall_1_rex64"
14202 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14203 (match_operand 1 "" ""))]
14204 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14206 [(set_attr "type" "call")])
14208 (define_insn "*sibcall_1_rex64_v"
14209 [(call (mem:QI (reg:DI R11_REG))
14210 (match_operand 0 "" ""))]
14211 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14213 [(set_attr "type" "call")])
14216 ;; Call subroutine, returning value in operand 0
14218 (define_expand "call_value_pop"
14219 [(parallel [(set (match_operand 0 "" "")
14220 (call (match_operand:QI 1 "" "")
14221 (match_operand:SI 2 "" "")))
14222 (set (reg:SI SP_REG)
14223 (plus:SI (reg:SI SP_REG)
14224 (match_operand:SI 4 "" "")))])]
14227 ix86_expand_call (operands[0], operands[1], operands[2],
14228 operands[3], operands[4], 0);
14232 (define_expand "call_value"
14233 [(set (match_operand 0 "" "")
14234 (call (match_operand:QI 1 "" "")
14235 (match_operand:SI 2 "" "")))
14236 (use (match_operand:SI 3 "" ""))]
14237 ;; Operand 2 not used on the i386.
14240 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14244 (define_expand "sibcall_value"
14245 [(set (match_operand 0 "" "")
14246 (call (match_operand:QI 1 "" "")
14247 (match_operand:SI 2 "" "")))
14248 (use (match_operand:SI 3 "" ""))]
14249 ;; Operand 2 not used on the i386.
14252 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14256 ;; Call subroutine returning any type.
14258 (define_expand "untyped_call"
14259 [(parallel [(call (match_operand 0 "" "")
14261 (match_operand 1 "" "")
14262 (match_operand 2 "" "")])]
14267 /* In order to give reg-stack an easier job in validating two
14268 coprocessor registers as containing a possible return value,
14269 simply pretend the untyped call returns a complex long double
14272 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14273 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14274 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14277 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14279 rtx set = XVECEXP (operands[2], 0, i);
14280 emit_move_insn (SET_DEST (set), SET_SRC (set));
14283 /* The optimizer does not know that the call sets the function value
14284 registers we stored in the result block. We avoid problems by
14285 claiming that all hard registers are used and clobbered at this
14287 emit_insn (gen_blockage (const0_rtx));
14292 ;; Prologue and epilogue instructions
14294 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14295 ;; all of memory. This blocks insns from being moved across this point.
14297 (define_insn "blockage"
14298 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14301 [(set_attr "length" "0")])
14303 ;; Insn emitted into the body of a function to return from a function.
14304 ;; This is only done if the function's epilogue is known to be simple.
14305 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14307 (define_expand "return"
14309 "ix86_can_use_return_insn_p ()"
14311 if (current_function_pops_args)
14313 rtx popc = GEN_INT (current_function_pops_args);
14314 emit_jump_insn (gen_return_pop_internal (popc));
14319 (define_insn "return_internal"
14323 [(set_attr "length" "1")
14324 (set_attr "length_immediate" "0")
14325 (set_attr "modrm" "0")])
14327 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14328 ;; instruction Athlon and K8 have.
14330 (define_insn "return_internal_long"
14332 (unspec [(const_int 0)] UNSPEC_REP)]
14335 [(set_attr "length" "1")
14336 (set_attr "length_immediate" "0")
14337 (set_attr "prefix_rep" "1")
14338 (set_attr "modrm" "0")])
14340 (define_insn "return_pop_internal"
14342 (use (match_operand:SI 0 "const_int_operand" ""))]
14345 [(set_attr "length" "3")
14346 (set_attr "length_immediate" "2")
14347 (set_attr "modrm" "0")])
14349 (define_insn "return_indirect_internal"
14351 (use (match_operand:SI 0 "register_operand" "r"))]
14354 [(set_attr "type" "ibr")
14355 (set_attr "length_immediate" "0")])
14361 [(set_attr "length" "1")
14362 (set_attr "length_immediate" "0")
14363 (set_attr "modrm" "0")])
14365 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14366 ;; branch prediction penalty for the third jump in a 16-byte
14369 (define_insn "align"
14370 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14373 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14374 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14376 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14377 The align insn is used to avoid 3 jump instructions in the row to improve
14378 branch prediction and the benefits hardly outweigh the cost of extra 8
14379 nops on the average inserted by full alignment pseudo operation. */
14383 [(set_attr "length" "16")])
14385 (define_expand "prologue"
14388 "ix86_expand_prologue (); DONE;")
14390 (define_insn "set_got"
14391 [(set (match_operand:SI 0 "register_operand" "=r")
14392 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14393 (clobber (reg:CC FLAGS_REG))]
14395 { return output_set_got (operands[0], NULL_RTX); }
14396 [(set_attr "type" "multi")
14397 (set_attr "length" "12")])
14399 (define_insn "set_got_labelled"
14400 [(set (match_operand:SI 0 "register_operand" "=r")
14401 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14403 (clobber (reg:CC FLAGS_REG))]
14405 { return output_set_got (operands[0], operands[1]); }
14406 [(set_attr "type" "multi")
14407 (set_attr "length" "12")])
14409 (define_insn "set_got_rex64"
14410 [(set (match_operand:DI 0 "register_operand" "=r")
14411 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14413 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14414 [(set_attr "type" "lea")
14415 (set_attr "length" "6")])
14417 (define_expand "epilogue"
14420 "ix86_expand_epilogue (1); DONE;")
14422 (define_expand "sibcall_epilogue"
14425 "ix86_expand_epilogue (0); DONE;")
14427 (define_expand "eh_return"
14428 [(use (match_operand 0 "register_operand" ""))]
14431 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14433 /* Tricky bit: we write the address of the handler to which we will
14434 be returning into someone else's stack frame, one word below the
14435 stack address we wish to restore. */
14436 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14437 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14438 tmp = gen_rtx_MEM (Pmode, tmp);
14439 emit_move_insn (tmp, ra);
14441 if (Pmode == SImode)
14442 emit_jump_insn (gen_eh_return_si (sa));
14444 emit_jump_insn (gen_eh_return_di (sa));
14449 (define_insn_and_split "eh_return_si"
14451 (unspec [(match_operand:SI 0 "register_operand" "c")]
14452 UNSPEC_EH_RETURN))]
14457 "ix86_expand_epilogue (2); DONE;")
14459 (define_insn_and_split "eh_return_di"
14461 (unspec [(match_operand:DI 0 "register_operand" "c")]
14462 UNSPEC_EH_RETURN))]
14467 "ix86_expand_epilogue (2); DONE;")
14469 (define_insn "leave"
14470 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14471 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14472 (clobber (mem:BLK (scratch)))]
14475 [(set_attr "type" "leave")])
14477 (define_insn "leave_rex64"
14478 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14479 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14480 (clobber (mem:BLK (scratch)))]
14483 [(set_attr "type" "leave")])
14485 (define_expand "ffssi2"
14487 [(set (match_operand:SI 0 "register_operand" "")
14488 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14489 (clobber (match_scratch:SI 2 ""))
14490 (clobber (reg:CC FLAGS_REG))])]
14494 (define_insn_and_split "*ffs_cmove"
14495 [(set (match_operand:SI 0 "register_operand" "=r")
14496 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14497 (clobber (match_scratch:SI 2 "=&r"))
14498 (clobber (reg:CC FLAGS_REG))]
14501 "&& reload_completed"
14502 [(set (match_dup 2) (const_int -1))
14503 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14504 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14505 (set (match_dup 0) (if_then_else:SI
14506 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14509 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14510 (clobber (reg:CC FLAGS_REG))])]
14513 (define_insn_and_split "*ffs_no_cmove"
14514 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14515 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14516 (clobber (match_scratch:SI 2 "=&q"))
14517 (clobber (reg:CC FLAGS_REG))]
14521 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14522 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14523 (set (strict_low_part (match_dup 3))
14524 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14525 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14526 (clobber (reg:CC FLAGS_REG))])
14527 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14528 (clobber (reg:CC FLAGS_REG))])
14529 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14530 (clobber (reg:CC FLAGS_REG))])]
14532 operands[3] = gen_lowpart (QImode, operands[2]);
14533 ix86_expand_clear (operands[2]);
14536 (define_insn "*ffssi_1"
14537 [(set (reg:CCZ FLAGS_REG)
14538 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14540 (set (match_operand:SI 0 "register_operand" "=r")
14541 (ctz:SI (match_dup 1)))]
14543 "bsf{l}\t{%1, %0|%0, %1}"
14544 [(set_attr "prefix_0f" "1")])
14546 (define_expand "ffsdi2"
14548 [(set (match_operand:DI 0 "register_operand" "")
14549 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14550 (clobber (match_scratch:DI 2 ""))
14551 (clobber (reg:CC FLAGS_REG))])]
14552 "TARGET_64BIT && TARGET_CMOVE"
14555 (define_insn_and_split "*ffs_rex64"
14556 [(set (match_operand:DI 0 "register_operand" "=r")
14557 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14558 (clobber (match_scratch:DI 2 "=&r"))
14559 (clobber (reg:CC FLAGS_REG))]
14560 "TARGET_64BIT && TARGET_CMOVE"
14562 "&& reload_completed"
14563 [(set (match_dup 2) (const_int -1))
14564 (parallel [(set (reg:CCZ FLAGS_REG)
14565 (compare:CCZ (match_dup 1) (const_int 0)))
14566 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14567 (set (match_dup 0) (if_then_else:DI
14568 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14571 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14572 (clobber (reg:CC FLAGS_REG))])]
14575 (define_insn "*ffsdi_1"
14576 [(set (reg:CCZ FLAGS_REG)
14577 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14579 (set (match_operand:DI 0 "register_operand" "=r")
14580 (ctz:DI (match_dup 1)))]
14582 "bsf{q}\t{%1, %0|%0, %1}"
14583 [(set_attr "prefix_0f" "1")])
14585 (define_insn "ctzsi2"
14586 [(set (match_operand:SI 0 "register_operand" "=r")
14587 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14588 (clobber (reg:CC FLAGS_REG))]
14590 "bsf{l}\t{%1, %0|%0, %1}"
14591 [(set_attr "prefix_0f" "1")])
14593 (define_insn "ctzdi2"
14594 [(set (match_operand:DI 0 "register_operand" "=r")
14595 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14596 (clobber (reg:CC FLAGS_REG))]
14598 "bsf{q}\t{%1, %0|%0, %1}"
14599 [(set_attr "prefix_0f" "1")])
14601 (define_expand "clzsi2"
14603 [(set (match_operand:SI 0 "register_operand" "")
14604 (minus:SI (const_int 31)
14605 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14606 (clobber (reg:CC FLAGS_REG))])
14608 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14609 (clobber (reg:CC FLAGS_REG))])]
14613 (define_insn "*bsr"
14614 [(set (match_operand:SI 0 "register_operand" "=r")
14615 (minus:SI (const_int 31)
14616 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14617 (clobber (reg:CC FLAGS_REG))]
14619 "bsr{l}\t{%1, %0|%0, %1}"
14620 [(set_attr "prefix_0f" "1")])
14622 (define_insn "bswapsi2"
14623 [(set (match_operand:SI 0 "register_operand" "=r")
14624 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14625 (clobber (reg:CC FLAGS_REG))]
14628 [(set_attr "prefix_0f" "1")
14629 (set_attr "length" "2")])
14631 (define_insn "bswapdi2"
14632 [(set (match_operand:DI 0 "register_operand" "=r")
14633 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14634 (clobber (reg:CC FLAGS_REG))]
14635 "TARGET_64BIT && TARGET_BSWAP"
14637 [(set_attr "prefix_0f" "1")
14638 (set_attr "length" "3")])
14640 (define_expand "clzdi2"
14642 [(set (match_operand:DI 0 "register_operand" "")
14643 (minus:DI (const_int 63)
14644 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14645 (clobber (reg:CC FLAGS_REG))])
14647 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14648 (clobber (reg:CC FLAGS_REG))])]
14652 (define_insn "*bsr_rex64"
14653 [(set (match_operand:DI 0 "register_operand" "=r")
14654 (minus:DI (const_int 63)
14655 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14656 (clobber (reg:CC FLAGS_REG))]
14658 "bsr{q}\t{%1, %0|%0, %1}"
14659 [(set_attr "prefix_0f" "1")])
14661 ;; Thread-local storage patterns for ELF.
14663 ;; Note that these code sequences must appear exactly as shown
14664 ;; in order to allow linker relaxation.
14666 (define_insn "*tls_global_dynamic_32_gnu"
14667 [(set (match_operand:SI 0 "register_operand" "=a")
14668 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14669 (match_operand:SI 2 "tls_symbolic_operand" "")
14670 (match_operand:SI 3 "call_insn_operand" "")]
14672 (clobber (match_scratch:SI 4 "=d"))
14673 (clobber (match_scratch:SI 5 "=c"))
14674 (clobber (reg:CC FLAGS_REG))]
14675 "!TARGET_64BIT && TARGET_GNU_TLS"
14676 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14677 [(set_attr "type" "multi")
14678 (set_attr "length" "12")])
14680 (define_insn "*tls_global_dynamic_32_sun"
14681 [(set (match_operand:SI 0 "register_operand" "=a")
14682 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14683 (match_operand:SI 2 "tls_symbolic_operand" "")
14684 (match_operand:SI 3 "call_insn_operand" "")]
14686 (clobber (match_scratch:SI 4 "=d"))
14687 (clobber (match_scratch:SI 5 "=c"))
14688 (clobber (reg:CC FLAGS_REG))]
14689 "!TARGET_64BIT && TARGET_SUN_TLS"
14690 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14691 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14692 [(set_attr "type" "multi")
14693 (set_attr "length" "14")])
14695 (define_expand "tls_global_dynamic_32"
14696 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14699 (match_operand:SI 1 "tls_symbolic_operand" "")
14702 (clobber (match_scratch:SI 4 ""))
14703 (clobber (match_scratch:SI 5 ""))
14704 (clobber (reg:CC FLAGS_REG))])]
14708 operands[2] = pic_offset_table_rtx;
14711 operands[2] = gen_reg_rtx (Pmode);
14712 emit_insn (gen_set_got (operands[2]));
14714 if (TARGET_GNU2_TLS)
14716 emit_insn (gen_tls_dynamic_gnu2_32
14717 (operands[0], operands[1], operands[2]));
14720 operands[3] = ix86_tls_get_addr ();
14723 (define_insn "*tls_global_dynamic_64"
14724 [(set (match_operand:DI 0 "register_operand" "=a")
14725 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14726 (match_operand:DI 3 "" "")))
14727 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14730 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14731 [(set_attr "type" "multi")
14732 (set_attr "length" "16")])
14734 (define_expand "tls_global_dynamic_64"
14735 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14736 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14737 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14741 if (TARGET_GNU2_TLS)
14743 emit_insn (gen_tls_dynamic_gnu2_64
14744 (operands[0], operands[1]));
14747 operands[2] = ix86_tls_get_addr ();
14750 (define_insn "*tls_local_dynamic_base_32_gnu"
14751 [(set (match_operand:SI 0 "register_operand" "=a")
14752 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14753 (match_operand:SI 2 "call_insn_operand" "")]
14754 UNSPEC_TLS_LD_BASE))
14755 (clobber (match_scratch:SI 3 "=d"))
14756 (clobber (match_scratch:SI 4 "=c"))
14757 (clobber (reg:CC FLAGS_REG))]
14758 "!TARGET_64BIT && TARGET_GNU_TLS"
14759 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14760 [(set_attr "type" "multi")
14761 (set_attr "length" "11")])
14763 (define_insn "*tls_local_dynamic_base_32_sun"
14764 [(set (match_operand:SI 0 "register_operand" "=a")
14765 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14766 (match_operand:SI 2 "call_insn_operand" "")]
14767 UNSPEC_TLS_LD_BASE))
14768 (clobber (match_scratch:SI 3 "=d"))
14769 (clobber (match_scratch:SI 4 "=c"))
14770 (clobber (reg:CC FLAGS_REG))]
14771 "!TARGET_64BIT && TARGET_SUN_TLS"
14772 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14773 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14774 [(set_attr "type" "multi")
14775 (set_attr "length" "13")])
14777 (define_expand "tls_local_dynamic_base_32"
14778 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14779 (unspec:SI [(match_dup 1) (match_dup 2)]
14780 UNSPEC_TLS_LD_BASE))
14781 (clobber (match_scratch:SI 3 ""))
14782 (clobber (match_scratch:SI 4 ""))
14783 (clobber (reg:CC FLAGS_REG))])]
14787 operands[1] = pic_offset_table_rtx;
14790 operands[1] = gen_reg_rtx (Pmode);
14791 emit_insn (gen_set_got (operands[1]));
14793 if (TARGET_GNU2_TLS)
14795 emit_insn (gen_tls_dynamic_gnu2_32
14796 (operands[0], ix86_tls_module_base (), operands[1]));
14799 operands[2] = ix86_tls_get_addr ();
14802 (define_insn "*tls_local_dynamic_base_64"
14803 [(set (match_operand:DI 0 "register_operand" "=a")
14804 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14805 (match_operand:DI 2 "" "")))
14806 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14808 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14809 [(set_attr "type" "multi")
14810 (set_attr "length" "12")])
14812 (define_expand "tls_local_dynamic_base_64"
14813 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14814 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14815 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14818 if (TARGET_GNU2_TLS)
14820 emit_insn (gen_tls_dynamic_gnu2_64
14821 (operands[0], ix86_tls_module_base ()));
14824 operands[1] = ix86_tls_get_addr ();
14827 ;; Local dynamic of a single variable is a lose. Show combine how
14828 ;; to convert that back to global dynamic.
14830 (define_insn_and_split "*tls_local_dynamic_32_once"
14831 [(set (match_operand:SI 0 "register_operand" "=a")
14832 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14833 (match_operand:SI 2 "call_insn_operand" "")]
14834 UNSPEC_TLS_LD_BASE)
14835 (const:SI (unspec:SI
14836 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14838 (clobber (match_scratch:SI 4 "=d"))
14839 (clobber (match_scratch:SI 5 "=c"))
14840 (clobber (reg:CC FLAGS_REG))]
14844 [(parallel [(set (match_dup 0)
14845 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14847 (clobber (match_dup 4))
14848 (clobber (match_dup 5))
14849 (clobber (reg:CC FLAGS_REG))])]
14852 ;; Load and add the thread base pointer from %gs:0.
14854 (define_insn "*load_tp_si"
14855 [(set (match_operand:SI 0 "register_operand" "=r")
14856 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14858 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14859 [(set_attr "type" "imov")
14860 (set_attr "modrm" "0")
14861 (set_attr "length" "7")
14862 (set_attr "memory" "load")
14863 (set_attr "imm_disp" "false")])
14865 (define_insn "*add_tp_si"
14866 [(set (match_operand:SI 0 "register_operand" "=r")
14867 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14868 (match_operand:SI 1 "register_operand" "0")))
14869 (clobber (reg:CC FLAGS_REG))]
14871 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14872 [(set_attr "type" "alu")
14873 (set_attr "modrm" "0")
14874 (set_attr "length" "7")
14875 (set_attr "memory" "load")
14876 (set_attr "imm_disp" "false")])
14878 (define_insn "*load_tp_di"
14879 [(set (match_operand:DI 0 "register_operand" "=r")
14880 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14882 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14883 [(set_attr "type" "imov")
14884 (set_attr "modrm" "0")
14885 (set_attr "length" "7")
14886 (set_attr "memory" "load")
14887 (set_attr "imm_disp" "false")])
14889 (define_insn "*add_tp_di"
14890 [(set (match_operand:DI 0 "register_operand" "=r")
14891 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14892 (match_operand:DI 1 "register_operand" "0")))
14893 (clobber (reg:CC FLAGS_REG))]
14895 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14896 [(set_attr "type" "alu")
14897 (set_attr "modrm" "0")
14898 (set_attr "length" "7")
14899 (set_attr "memory" "load")
14900 (set_attr "imm_disp" "false")])
14902 ;; GNU2 TLS patterns can be split.
14904 (define_expand "tls_dynamic_gnu2_32"
14905 [(set (match_dup 3)
14906 (plus:SI (match_operand:SI 2 "register_operand" "")
14908 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14911 [(set (match_operand:SI 0 "register_operand" "")
14912 (unspec:SI [(match_dup 1) (match_dup 3)
14913 (match_dup 2) (reg:SI SP_REG)]
14915 (clobber (reg:CC FLAGS_REG))])]
14916 "!TARGET_64BIT && TARGET_GNU2_TLS"
14918 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14919 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14922 (define_insn "*tls_dynamic_lea_32"
14923 [(set (match_operand:SI 0 "register_operand" "=r")
14924 (plus:SI (match_operand:SI 1 "register_operand" "b")
14926 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14927 UNSPEC_TLSDESC))))]
14928 "!TARGET_64BIT && TARGET_GNU2_TLS"
14929 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14930 [(set_attr "type" "lea")
14931 (set_attr "mode" "SI")
14932 (set_attr "length" "6")
14933 (set_attr "length_address" "4")])
14935 (define_insn "*tls_dynamic_call_32"
14936 [(set (match_operand:SI 0 "register_operand" "=a")
14937 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14938 (match_operand:SI 2 "register_operand" "0")
14939 ;; we have to make sure %ebx still points to the GOT
14940 (match_operand:SI 3 "register_operand" "b")
14943 (clobber (reg:CC FLAGS_REG))]
14944 "!TARGET_64BIT && TARGET_GNU2_TLS"
14945 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14946 [(set_attr "type" "call")
14947 (set_attr "length" "2")
14948 (set_attr "length_address" "0")])
14950 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14951 [(set (match_operand:SI 0 "register_operand" "=&a")
14953 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14954 (match_operand:SI 4 "" "")
14955 (match_operand:SI 2 "register_operand" "b")
14958 (const:SI (unspec:SI
14959 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14961 (clobber (reg:CC FLAGS_REG))]
14962 "!TARGET_64BIT && TARGET_GNU2_TLS"
14965 [(set (match_dup 0) (match_dup 5))]
14967 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14968 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14971 (define_expand "tls_dynamic_gnu2_64"
14972 [(set (match_dup 2)
14973 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14976 [(set (match_operand:DI 0 "register_operand" "")
14977 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14979 (clobber (reg:CC FLAGS_REG))])]
14980 "TARGET_64BIT && TARGET_GNU2_TLS"
14982 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14983 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14986 (define_insn "*tls_dynamic_lea_64"
14987 [(set (match_operand:DI 0 "register_operand" "=r")
14988 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14990 "TARGET_64BIT && TARGET_GNU2_TLS"
14991 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14992 [(set_attr "type" "lea")
14993 (set_attr "mode" "DI")
14994 (set_attr "length" "7")
14995 (set_attr "length_address" "4")])
14997 (define_insn "*tls_dynamic_call_64"
14998 [(set (match_operand:DI 0 "register_operand" "=a")
14999 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15000 (match_operand:DI 2 "register_operand" "0")
15003 (clobber (reg:CC FLAGS_REG))]
15004 "TARGET_64BIT && TARGET_GNU2_TLS"
15005 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15006 [(set_attr "type" "call")
15007 (set_attr "length" "2")
15008 (set_attr "length_address" "0")])
15010 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15011 [(set (match_operand:DI 0 "register_operand" "=&a")
15013 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15014 (match_operand:DI 3 "" "")
15017 (const:DI (unspec:DI
15018 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15020 (clobber (reg:CC FLAGS_REG))]
15021 "TARGET_64BIT && TARGET_GNU2_TLS"
15024 [(set (match_dup 0) (match_dup 4))]
15026 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15027 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15032 ;; These patterns match the binary 387 instructions for addM3, subM3,
15033 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15034 ;; SFmode. The first is the normal insn, the second the same insn but
15035 ;; with one operand a conversion, and the third the same insn but with
15036 ;; the other operand a conversion. The conversion may be SFmode or
15037 ;; SImode if the target mode DFmode, but only SImode if the target mode
15040 ;; Gcc is slightly more smart about handling normal two address instructions
15041 ;; so use special patterns for add and mull.
15043 (define_insn "*fop_sf_comm_mixed"
15044 [(set (match_operand:SF 0 "register_operand" "=f,x")
15045 (match_operator:SF 3 "binary_fp_operator"
15046 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15047 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15048 "TARGET_MIX_SSE_I387
15049 && COMMUTATIVE_ARITH_P (operands[3])
15050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15051 "* return output_387_binary_op (insn, operands);"
15052 [(set (attr "type")
15053 (if_then_else (eq_attr "alternative" "1")
15054 (if_then_else (match_operand:SF 3 "mult_operator" "")
15055 (const_string "ssemul")
15056 (const_string "sseadd"))
15057 (if_then_else (match_operand:SF 3 "mult_operator" "")
15058 (const_string "fmul")
15059 (const_string "fop"))))
15060 (set_attr "mode" "SF")])
15062 (define_insn "*fop_sf_comm_sse"
15063 [(set (match_operand:SF 0 "register_operand" "=x")
15064 (match_operator:SF 3 "binary_fp_operator"
15065 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15066 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15068 && COMMUTATIVE_ARITH_P (operands[3])
15069 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15070 "* return output_387_binary_op (insn, operands);"
15071 [(set (attr "type")
15072 (if_then_else (match_operand:SF 3 "mult_operator" "")
15073 (const_string "ssemul")
15074 (const_string "sseadd")))
15075 (set_attr "mode" "SF")])
15077 (define_insn "*fop_sf_comm_i387"
15078 [(set (match_operand:SF 0 "register_operand" "=f")
15079 (match_operator:SF 3 "binary_fp_operator"
15080 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15081 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15083 && COMMUTATIVE_ARITH_P (operands[3])
15084 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15085 "* return output_387_binary_op (insn, operands);"
15086 [(set (attr "type")
15087 (if_then_else (match_operand:SF 3 "mult_operator" "")
15088 (const_string "fmul")
15089 (const_string "fop")))
15090 (set_attr "mode" "SF")])
15092 (define_insn "*fop_sf_1_mixed"
15093 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15094 (match_operator:SF 3 "binary_fp_operator"
15095 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15096 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15097 "TARGET_MIX_SSE_I387
15098 && !COMMUTATIVE_ARITH_P (operands[3])
15099 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15100 "* return output_387_binary_op (insn, operands);"
15101 [(set (attr "type")
15102 (cond [(and (eq_attr "alternative" "2")
15103 (match_operand:SF 3 "mult_operator" ""))
15104 (const_string "ssemul")
15105 (and (eq_attr "alternative" "2")
15106 (match_operand:SF 3 "div_operator" ""))
15107 (const_string "ssediv")
15108 (eq_attr "alternative" "2")
15109 (const_string "sseadd")
15110 (match_operand:SF 3 "mult_operator" "")
15111 (const_string "fmul")
15112 (match_operand:SF 3 "div_operator" "")
15113 (const_string "fdiv")
15115 (const_string "fop")))
15116 (set_attr "mode" "SF")])
15118 (define_insn "*fop_sf_1_sse"
15119 [(set (match_operand:SF 0 "register_operand" "=x")
15120 (match_operator:SF 3 "binary_fp_operator"
15121 [(match_operand:SF 1 "register_operand" "0")
15122 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15124 && !COMMUTATIVE_ARITH_P (operands[3])"
15125 "* return output_387_binary_op (insn, operands);"
15126 [(set (attr "type")
15127 (cond [(match_operand:SF 3 "mult_operator" "")
15128 (const_string "ssemul")
15129 (match_operand:SF 3 "div_operator" "")
15130 (const_string "ssediv")
15132 (const_string "sseadd")))
15133 (set_attr "mode" "SF")])
15135 ;; This pattern is not fully shadowed by the pattern above.
15136 (define_insn "*fop_sf_1_i387"
15137 [(set (match_operand:SF 0 "register_operand" "=f,f")
15138 (match_operator:SF 3 "binary_fp_operator"
15139 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15140 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15141 "TARGET_80387 && !TARGET_SSE_MATH
15142 && !COMMUTATIVE_ARITH_P (operands[3])
15143 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15144 "* return output_387_binary_op (insn, operands);"
15145 [(set (attr "type")
15146 (cond [(match_operand:SF 3 "mult_operator" "")
15147 (const_string "fmul")
15148 (match_operand:SF 3 "div_operator" "")
15149 (const_string "fdiv")
15151 (const_string "fop")))
15152 (set_attr "mode" "SF")])
15154 ;; ??? Add SSE splitters for these!
15155 (define_insn "*fop_sf_2<mode>_i387"
15156 [(set (match_operand:SF 0 "register_operand" "=f,f")
15157 (match_operator:SF 3 "binary_fp_operator"
15158 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15159 (match_operand:SF 2 "register_operand" "0,0")]))]
15160 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15161 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15162 [(set (attr "type")
15163 (cond [(match_operand:SF 3 "mult_operator" "")
15164 (const_string "fmul")
15165 (match_operand:SF 3 "div_operator" "")
15166 (const_string "fdiv")
15168 (const_string "fop")))
15169 (set_attr "fp_int_src" "true")
15170 (set_attr "mode" "<MODE>")])
15172 (define_insn "*fop_sf_3<mode>_i387"
15173 [(set (match_operand:SF 0 "register_operand" "=f,f")
15174 (match_operator:SF 3 "binary_fp_operator"
15175 [(match_operand:SF 1 "register_operand" "0,0")
15176 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15177 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15178 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15179 [(set (attr "type")
15180 (cond [(match_operand:SF 3 "mult_operator" "")
15181 (const_string "fmul")
15182 (match_operand:SF 3 "div_operator" "")
15183 (const_string "fdiv")
15185 (const_string "fop")))
15186 (set_attr "fp_int_src" "true")
15187 (set_attr "mode" "<MODE>")])
15189 (define_insn "*fop_df_comm_mixed"
15190 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15191 (match_operator:DF 3 "binary_fp_operator"
15192 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15193 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15194 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15195 && COMMUTATIVE_ARITH_P (operands[3])
15196 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15197 "* return output_387_binary_op (insn, operands);"
15198 [(set (attr "type")
15199 (if_then_else (eq_attr "alternative" "1")
15200 (if_then_else (match_operand:DF 3 "mult_operator" "")
15201 (const_string "ssemul")
15202 (const_string "sseadd"))
15203 (if_then_else (match_operand:DF 3 "mult_operator" "")
15204 (const_string "fmul")
15205 (const_string "fop"))))
15206 (set_attr "mode" "DF")])
15208 (define_insn "*fop_df_comm_sse"
15209 [(set (match_operand:DF 0 "register_operand" "=Y")
15210 (match_operator:DF 3 "binary_fp_operator"
15211 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15212 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15213 "TARGET_SSE2 && TARGET_SSE_MATH
15214 && COMMUTATIVE_ARITH_P (operands[3])
15215 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15216 "* return output_387_binary_op (insn, operands);"
15217 [(set (attr "type")
15218 (if_then_else (match_operand:DF 3 "mult_operator" "")
15219 (const_string "ssemul")
15220 (const_string "sseadd")))
15221 (set_attr "mode" "DF")])
15223 (define_insn "*fop_df_comm_i387"
15224 [(set (match_operand:DF 0 "register_operand" "=f")
15225 (match_operator:DF 3 "binary_fp_operator"
15226 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15227 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15229 && COMMUTATIVE_ARITH_P (operands[3])
15230 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15231 "* return output_387_binary_op (insn, operands);"
15232 [(set (attr "type")
15233 (if_then_else (match_operand:DF 3 "mult_operator" "")
15234 (const_string "fmul")
15235 (const_string "fop")))
15236 (set_attr "mode" "DF")])
15238 (define_insn "*fop_df_1_mixed"
15239 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15240 (match_operator:DF 3 "binary_fp_operator"
15241 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15242 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15243 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15244 && !COMMUTATIVE_ARITH_P (operands[3])
15245 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15246 "* return output_387_binary_op (insn, operands);"
15247 [(set (attr "type")
15248 (cond [(and (eq_attr "alternative" "2")
15249 (match_operand:DF 3 "mult_operator" ""))
15250 (const_string "ssemul")
15251 (and (eq_attr "alternative" "2")
15252 (match_operand:DF 3 "div_operator" ""))
15253 (const_string "ssediv")
15254 (eq_attr "alternative" "2")
15255 (const_string "sseadd")
15256 (match_operand:DF 3 "mult_operator" "")
15257 (const_string "fmul")
15258 (match_operand:DF 3 "div_operator" "")
15259 (const_string "fdiv")
15261 (const_string "fop")))
15262 (set_attr "mode" "DF")])
15264 (define_insn "*fop_df_1_sse"
15265 [(set (match_operand:DF 0 "register_operand" "=Y")
15266 (match_operator:DF 3 "binary_fp_operator"
15267 [(match_operand:DF 1 "register_operand" "0")
15268 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15269 "TARGET_SSE2 && TARGET_SSE_MATH
15270 && !COMMUTATIVE_ARITH_P (operands[3])"
15271 "* return output_387_binary_op (insn, operands);"
15272 [(set_attr "mode" "DF")
15274 (cond [(match_operand:DF 3 "mult_operator" "")
15275 (const_string "ssemul")
15276 (match_operand:DF 3 "div_operator" "")
15277 (const_string "ssediv")
15279 (const_string "sseadd")))])
15281 ;; This pattern is not fully shadowed by the pattern above.
15282 (define_insn "*fop_df_1_i387"
15283 [(set (match_operand:DF 0 "register_operand" "=f,f")
15284 (match_operator:DF 3 "binary_fp_operator"
15285 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15286 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15287 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15288 && !COMMUTATIVE_ARITH_P (operands[3])
15289 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15290 "* return output_387_binary_op (insn, operands);"
15291 [(set (attr "type")
15292 (cond [(match_operand:DF 3 "mult_operator" "")
15293 (const_string "fmul")
15294 (match_operand:DF 3 "div_operator" "")
15295 (const_string "fdiv")
15297 (const_string "fop")))
15298 (set_attr "mode" "DF")])
15300 ;; ??? Add SSE splitters for these!
15301 (define_insn "*fop_df_2<mode>_i387"
15302 [(set (match_operand:DF 0 "register_operand" "=f,f")
15303 (match_operator:DF 3 "binary_fp_operator"
15304 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15305 (match_operand:DF 2 "register_operand" "0,0")]))]
15306 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15307 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15308 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15309 [(set (attr "type")
15310 (cond [(match_operand:DF 3 "mult_operator" "")
15311 (const_string "fmul")
15312 (match_operand:DF 3 "div_operator" "")
15313 (const_string "fdiv")
15315 (const_string "fop")))
15316 (set_attr "fp_int_src" "true")
15317 (set_attr "mode" "<MODE>")])
15319 (define_insn "*fop_df_3<mode>_i387"
15320 [(set (match_operand:DF 0 "register_operand" "=f,f")
15321 (match_operator:DF 3 "binary_fp_operator"
15322 [(match_operand:DF 1 "register_operand" "0,0")
15323 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15324 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15325 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15326 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15327 [(set (attr "type")
15328 (cond [(match_operand:DF 3 "mult_operator" "")
15329 (const_string "fmul")
15330 (match_operand:DF 3 "div_operator" "")
15331 (const_string "fdiv")
15333 (const_string "fop")))
15334 (set_attr "fp_int_src" "true")
15335 (set_attr "mode" "<MODE>")])
15337 (define_insn "*fop_df_4_i387"
15338 [(set (match_operand:DF 0 "register_operand" "=f,f")
15339 (match_operator:DF 3 "binary_fp_operator"
15340 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15341 (match_operand:DF 2 "register_operand" "0,f")]))]
15342 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15343 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15344 "* return output_387_binary_op (insn, operands);"
15345 [(set (attr "type")
15346 (cond [(match_operand:DF 3 "mult_operator" "")
15347 (const_string "fmul")
15348 (match_operand:DF 3 "div_operator" "")
15349 (const_string "fdiv")
15351 (const_string "fop")))
15352 (set_attr "mode" "SF")])
15354 (define_insn "*fop_df_5_i387"
15355 [(set (match_operand:DF 0 "register_operand" "=f,f")
15356 (match_operator:DF 3 "binary_fp_operator"
15357 [(match_operand:DF 1 "register_operand" "0,f")
15359 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15360 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15361 "* return output_387_binary_op (insn, operands);"
15362 [(set (attr "type")
15363 (cond [(match_operand:DF 3 "mult_operator" "")
15364 (const_string "fmul")
15365 (match_operand:DF 3 "div_operator" "")
15366 (const_string "fdiv")
15368 (const_string "fop")))
15369 (set_attr "mode" "SF")])
15371 (define_insn "*fop_df_6_i387"
15372 [(set (match_operand:DF 0 "register_operand" "=f,f")
15373 (match_operator:DF 3 "binary_fp_operator"
15375 (match_operand:SF 1 "register_operand" "0,f"))
15377 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15378 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15379 "* return output_387_binary_op (insn, operands);"
15380 [(set (attr "type")
15381 (cond [(match_operand:DF 3 "mult_operator" "")
15382 (const_string "fmul")
15383 (match_operand:DF 3 "div_operator" "")
15384 (const_string "fdiv")
15386 (const_string "fop")))
15387 (set_attr "mode" "SF")])
15389 (define_insn "*fop_xf_comm_i387"
15390 [(set (match_operand:XF 0 "register_operand" "=f")
15391 (match_operator:XF 3 "binary_fp_operator"
15392 [(match_operand:XF 1 "register_operand" "%0")
15393 (match_operand:XF 2 "register_operand" "f")]))]
15395 && COMMUTATIVE_ARITH_P (operands[3])"
15396 "* return output_387_binary_op (insn, operands);"
15397 [(set (attr "type")
15398 (if_then_else (match_operand:XF 3 "mult_operator" "")
15399 (const_string "fmul")
15400 (const_string "fop")))
15401 (set_attr "mode" "XF")])
15403 (define_insn "*fop_xf_1_i387"
15404 [(set (match_operand:XF 0 "register_operand" "=f,f")
15405 (match_operator:XF 3 "binary_fp_operator"
15406 [(match_operand:XF 1 "register_operand" "0,f")
15407 (match_operand:XF 2 "register_operand" "f,0")]))]
15409 && !COMMUTATIVE_ARITH_P (operands[3])"
15410 "* return output_387_binary_op (insn, operands);"
15411 [(set (attr "type")
15412 (cond [(match_operand:XF 3 "mult_operator" "")
15413 (const_string "fmul")
15414 (match_operand:XF 3 "div_operator" "")
15415 (const_string "fdiv")
15417 (const_string "fop")))
15418 (set_attr "mode" "XF")])
15420 (define_insn "*fop_xf_2<mode>_i387"
15421 [(set (match_operand:XF 0 "register_operand" "=f,f")
15422 (match_operator:XF 3 "binary_fp_operator"
15423 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15424 (match_operand:XF 2 "register_operand" "0,0")]))]
15425 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15426 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15427 [(set (attr "type")
15428 (cond [(match_operand:XF 3 "mult_operator" "")
15429 (const_string "fmul")
15430 (match_operand:XF 3 "div_operator" "")
15431 (const_string "fdiv")
15433 (const_string "fop")))
15434 (set_attr "fp_int_src" "true")
15435 (set_attr "mode" "<MODE>")])
15437 (define_insn "*fop_xf_3<mode>_i387"
15438 [(set (match_operand:XF 0 "register_operand" "=f,f")
15439 (match_operator:XF 3 "binary_fp_operator"
15440 [(match_operand:XF 1 "register_operand" "0,0")
15441 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15442 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15443 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15444 [(set (attr "type")
15445 (cond [(match_operand:XF 3 "mult_operator" "")
15446 (const_string "fmul")
15447 (match_operand:XF 3 "div_operator" "")
15448 (const_string "fdiv")
15450 (const_string "fop")))
15451 (set_attr "fp_int_src" "true")
15452 (set_attr "mode" "<MODE>")])
15454 (define_insn "*fop_xf_4_i387"
15455 [(set (match_operand:XF 0 "register_operand" "=f,f")
15456 (match_operator:XF 3 "binary_fp_operator"
15458 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15459 (match_operand:XF 2 "register_operand" "0,f")]))]
15461 "* return output_387_binary_op (insn, operands);"
15462 [(set (attr "type")
15463 (cond [(match_operand:XF 3 "mult_operator" "")
15464 (const_string "fmul")
15465 (match_operand:XF 3 "div_operator" "")
15466 (const_string "fdiv")
15468 (const_string "fop")))
15469 (set_attr "mode" "SF")])
15471 (define_insn "*fop_xf_5_i387"
15472 [(set (match_operand:XF 0 "register_operand" "=f,f")
15473 (match_operator:XF 3 "binary_fp_operator"
15474 [(match_operand:XF 1 "register_operand" "0,f")
15476 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15478 "* return output_387_binary_op (insn, operands);"
15479 [(set (attr "type")
15480 (cond [(match_operand:XF 3 "mult_operator" "")
15481 (const_string "fmul")
15482 (match_operand:XF 3 "div_operator" "")
15483 (const_string "fdiv")
15485 (const_string "fop")))
15486 (set_attr "mode" "SF")])
15488 (define_insn "*fop_xf_6_i387"
15489 [(set (match_operand:XF 0 "register_operand" "=f,f")
15490 (match_operator:XF 3 "binary_fp_operator"
15492 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15494 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15496 "* return output_387_binary_op (insn, operands);"
15497 [(set (attr "type")
15498 (cond [(match_operand:XF 3 "mult_operator" "")
15499 (const_string "fmul")
15500 (match_operand:XF 3 "div_operator" "")
15501 (const_string "fdiv")
15503 (const_string "fop")))
15504 (set_attr "mode" "SF")])
15507 [(set (match_operand 0 "register_operand" "")
15508 (match_operator 3 "binary_fp_operator"
15509 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15510 (match_operand 2 "register_operand" "")]))]
15511 "TARGET_80387 && reload_completed
15512 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15515 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15516 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15517 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15518 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15519 GET_MODE (operands[3]),
15522 ix86_free_from_memory (GET_MODE (operands[1]));
15527 [(set (match_operand 0 "register_operand" "")
15528 (match_operator 3 "binary_fp_operator"
15529 [(match_operand 1 "register_operand" "")
15530 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15531 "TARGET_80387 && reload_completed
15532 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15535 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15536 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15537 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15538 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15539 GET_MODE (operands[3]),
15542 ix86_free_from_memory (GET_MODE (operands[2]));
15546 ;; FPU special functions.
15548 ;; This pattern implements a no-op XFmode truncation for
15549 ;; all fancy i386 XFmode math functions.
15551 (define_insn "truncxf<mode>2_i387_noop_unspec"
15552 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15553 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15554 UNSPEC_TRUNC_NOOP))]
15555 "TARGET_USE_FANCY_MATH_387"
15556 "* return output_387_reg_move (insn, operands);"
15557 [(set_attr "type" "fmov")
15558 (set_attr "mode" "<MODE>")])
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 "sqrt_extend<mode>xf2_i387"
15570 [(set (match_operand:XF 0 "register_operand" "=f")
15573 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15574 "TARGET_USE_FANCY_MATH_387"
15576 [(set_attr "type" "fpspc")
15577 (set_attr "mode" "XF")
15578 (set_attr "athlon_decode" "direct")])
15580 (define_insn "*sqrt<mode>2_sse"
15581 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15583 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15584 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15585 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15586 [(set_attr "type" "sse")
15587 (set_attr "mode" "<MODE>")
15588 (set_attr "athlon_decode" "*")])
15590 (define_expand "sqrt<mode>2"
15591 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15593 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15594 "TARGET_USE_FANCY_MATH_387
15595 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15597 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15599 rtx op0 = gen_reg_rtx (XFmode);
15600 rtx op1 = force_reg (<MODE>mode, operands[1]);
15602 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15603 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15608 (define_insn "fpremxf4_i387"
15609 [(set (match_operand:XF 0 "register_operand" "=f")
15610 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15611 (match_operand:XF 3 "register_operand" "1")]
15613 (set (match_operand:XF 1 "register_operand" "=u")
15614 (unspec:XF [(match_dup 2) (match_dup 3)]
15616 (set (reg:CCFP FPSR_REG)
15617 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15618 "TARGET_USE_FANCY_MATH_387"
15620 [(set_attr "type" "fpspc")
15621 (set_attr "mode" "XF")])
15623 (define_expand "fmodxf3"
15624 [(use (match_operand:XF 0 "register_operand" ""))
15625 (use (match_operand:XF 1 "register_operand" ""))
15626 (use (match_operand:XF 2 "register_operand" ""))]
15627 "TARGET_USE_FANCY_MATH_387"
15629 rtx label = gen_label_rtx ();
15631 emit_label (label);
15633 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15634 operands[1], operands[2]));
15635 ix86_emit_fp_unordered_jump (label);
15637 emit_move_insn (operands[0], operands[1]);
15641 (define_expand "fmod<mode>3"
15642 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15643 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15644 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15645 "TARGET_USE_FANCY_MATH_387"
15647 rtx label = gen_label_rtx ();
15649 rtx op1 = gen_reg_rtx (XFmode);
15650 rtx op2 = gen_reg_rtx (XFmode);
15652 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15653 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15655 emit_label (label);
15656 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15657 ix86_emit_fp_unordered_jump (label);
15659 /* Truncate the result properly for strict SSE math. */
15660 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15661 && !TARGET_MIX_SSE_I387)
15662 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15664 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15669 (define_insn "fprem1xf4_i387"
15670 [(set (match_operand:XF 0 "register_operand" "=f")
15671 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15672 (match_operand:XF 3 "register_operand" "1")]
15674 (set (match_operand:XF 1 "register_operand" "=u")
15675 (unspec:XF [(match_dup 2) (match_dup 3)]
15677 (set (reg:CCFP FPSR_REG)
15678 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15679 "TARGET_USE_FANCY_MATH_387"
15681 [(set_attr "type" "fpspc")
15682 (set_attr "mode" "XF")])
15684 (define_expand "remainderxf3"
15685 [(use (match_operand:XF 0 "register_operand" ""))
15686 (use (match_operand:XF 1 "register_operand" ""))
15687 (use (match_operand:XF 2 "register_operand" ""))]
15688 "TARGET_USE_FANCY_MATH_387"
15690 rtx label = gen_label_rtx ();
15692 emit_label (label);
15694 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15695 operands[1], operands[2]));
15696 ix86_emit_fp_unordered_jump (label);
15698 emit_move_insn (operands[0], operands[1]);
15702 (define_expand "remainder<mode>3"
15703 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15704 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15705 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15706 "TARGET_USE_FANCY_MATH_387"
15708 rtx label = gen_label_rtx ();
15710 rtx op1 = gen_reg_rtx (XFmode);
15711 rtx op2 = gen_reg_rtx (XFmode);
15713 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15714 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15716 emit_label (label);
15718 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15719 ix86_emit_fp_unordered_jump (label);
15721 /* Truncate the result properly for strict SSE math. */
15722 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15723 && !TARGET_MIX_SSE_I387)
15724 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15726 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15731 (define_insn "*sinxf2_i387"
15732 [(set (match_operand:XF 0 "register_operand" "=f")
15733 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15734 "TARGET_USE_FANCY_MATH_387
15735 && flag_unsafe_math_optimizations"
15737 [(set_attr "type" "fpspc")
15738 (set_attr "mode" "XF")])
15740 (define_insn "*sin_extend<mode>xf2_i387"
15741 [(set (match_operand:XF 0 "register_operand" "=f")
15742 (unspec:XF [(float_extend:XF
15743 (match_operand:X87MODEF12 1 "register_operand" "0"))]
15745 "TARGET_USE_FANCY_MATH_387
15746 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15747 || TARGET_MIX_SSE_I387)
15748 && flag_unsafe_math_optimizations"
15750 [(set_attr "type" "fpspc")
15751 (set_attr "mode" "XF")])
15753 (define_insn "*cosxf2_i387"
15754 [(set (match_operand:XF 0 "register_operand" "=f")
15755 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15756 "TARGET_USE_FANCY_MATH_387
15757 && flag_unsafe_math_optimizations"
15759 [(set_attr "type" "fpspc")
15760 (set_attr "mode" "XF")])
15762 (define_insn "*cos_extend<mode>xf2_i387"
15763 [(set (match_operand:XF 0 "register_operand" "=f")
15764 (unspec:XF [(float_extend:XF
15765 (match_operand:X87MODEF12 1 "register_operand" "0"))]
15767 "TARGET_USE_FANCY_MATH_387
15768 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15769 || TARGET_MIX_SSE_I387)
15770 && flag_unsafe_math_optimizations"
15772 [(set_attr "type" "fpspc")
15773 (set_attr "mode" "XF")])
15775 ;; When sincos pattern is defined, sin and cos builtin functions will be
15776 ;; expanded to sincos pattern with one of its outputs left unused.
15777 ;; CSE pass will figure out if two sincos patterns can be combined,
15778 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15779 ;; depending on the unused output.
15781 (define_insn "sincosxf3"
15782 [(set (match_operand:XF 0 "register_operand" "=f")
15783 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15784 UNSPEC_SINCOS_COS))
15785 (set (match_operand:XF 1 "register_operand" "=u")
15786 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15787 "TARGET_USE_FANCY_MATH_387
15788 && flag_unsafe_math_optimizations"
15790 [(set_attr "type" "fpspc")
15791 (set_attr "mode" "XF")])
15794 [(set (match_operand:XF 0 "register_operand" "")
15795 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15796 UNSPEC_SINCOS_COS))
15797 (set (match_operand:XF 1 "register_operand" "")
15798 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15799 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15800 && !reload_completed && !reload_in_progress"
15801 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15805 [(set (match_operand:XF 0 "register_operand" "")
15806 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15807 UNSPEC_SINCOS_COS))
15808 (set (match_operand:XF 1 "register_operand" "")
15809 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15810 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15811 && !reload_completed && !reload_in_progress"
15812 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15815 (define_insn "sincos_extend<mode>xf3_i387"
15816 [(set (match_operand:XF 0 "register_operand" "=f")
15817 (unspec:XF [(float_extend:XF
15818 (match_operand:X87MODEF12 2 "register_operand" "0"))]
15819 UNSPEC_SINCOS_COS))
15820 (set (match_operand:XF 1 "register_operand" "=u")
15821 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15822 "TARGET_USE_FANCY_MATH_387
15823 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15824 || TARGET_MIX_SSE_I387)
15825 && flag_unsafe_math_optimizations"
15827 [(set_attr "type" "fpspc")
15828 (set_attr "mode" "XF")])
15831 [(set (match_operand:XF 0 "register_operand" "")
15832 (unspec:XF [(float_extend:XF
15833 (match_operand:X87MODEF12 2 "register_operand" ""))]
15834 UNSPEC_SINCOS_COS))
15835 (set (match_operand:XF 1 "register_operand" "")
15836 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15837 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15838 && !reload_completed && !reload_in_progress"
15839 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15843 [(set (match_operand:XF 0 "register_operand" "")
15844 (unspec:XF [(float_extend:XF
15845 (match_operand:X87MODEF12 2 "register_operand" ""))]
15846 UNSPEC_SINCOS_COS))
15847 (set (match_operand:XF 1 "register_operand" "")
15848 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15849 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15850 && !reload_completed && !reload_in_progress"
15851 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15854 (define_expand "sincos<mode>3"
15855 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15856 (use (match_operand:X87MODEF12 1 "register_operand" ""))
15857 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15858 "TARGET_USE_FANCY_MATH_387
15859 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15860 || TARGET_MIX_SSE_I387)
15861 && flag_unsafe_math_optimizations"
15863 rtx op0 = gen_reg_rtx (XFmode);
15864 rtx op1 = gen_reg_rtx (XFmode);
15866 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15867 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15868 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15872 (define_insn "fptanxf4_i387"
15873 [(set (match_operand:XF 0 "register_operand" "=f")
15874 (match_operand:XF 3 "const_double_operand" "F"))
15875 (set (match_operand:XF 1 "register_operand" "=u")
15876 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15878 "TARGET_USE_FANCY_MATH_387
15879 && flag_unsafe_math_optimizations
15880 && standard_80387_constant_p (operands[3]) == 2"
15882 [(set_attr "type" "fpspc")
15883 (set_attr "mode" "XF")])
15885 (define_insn "fptan_extend<mode>xf4_i387"
15886 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15887 (match_operand:X87MODEF12 3 "const_double_operand" "F"))
15888 (set (match_operand:XF 1 "register_operand" "=u")
15889 (unspec:XF [(float_extend:XF
15890 (match_operand:X87MODEF12 2 "register_operand" "0"))]
15892 "TARGET_USE_FANCY_MATH_387
15893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15894 || TARGET_MIX_SSE_I387)
15895 && flag_unsafe_math_optimizations
15896 && standard_80387_constant_p (operands[3]) == 2"
15898 [(set_attr "type" "fpspc")
15899 (set_attr "mode" "XF")])
15901 (define_expand "tanxf2"
15902 [(use (match_operand:XF 0 "register_operand" ""))
15903 (use (match_operand:XF 1 "register_operand" ""))]
15904 "TARGET_USE_FANCY_MATH_387
15905 && flag_unsafe_math_optimizations"
15907 rtx one = gen_reg_rtx (XFmode);
15908 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15910 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15914 (define_expand "tan<mode>2"
15915 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15916 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
15917 "TARGET_USE_FANCY_MATH_387
15918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15919 || TARGET_MIX_SSE_I387)
15920 && flag_unsafe_math_optimizations"
15922 rtx op0 = gen_reg_rtx (XFmode);
15924 rtx one = gen_reg_rtx (<MODE>mode);
15925 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15927 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15928 operands[1], op2));
15929 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15933 (define_insn "*fpatanxf3_i387"
15934 [(set (match_operand:XF 0 "register_operand" "=f")
15935 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15936 (match_operand:XF 2 "register_operand" "u")]
15938 (clobber (match_scratch:XF 3 "=2"))]
15939 "TARGET_USE_FANCY_MATH_387
15940 && flag_unsafe_math_optimizations"
15942 [(set_attr "type" "fpspc")
15943 (set_attr "mode" "XF")])
15945 (define_insn "fpatan_extend<mode>xf3_i387"
15946 [(set (match_operand:XF 0 "register_operand" "=f")
15947 (unspec:XF [(float_extend:XF
15948 (match_operand:X87MODEF12 1 "register_operand" "0"))
15950 (match_operand:X87MODEF12 2 "register_operand" "u"))]
15952 (clobber (match_scratch:XF 3 "=2"))]
15953 "TARGET_USE_FANCY_MATH_387
15954 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15955 || TARGET_MIX_SSE_I387)
15956 && flag_unsafe_math_optimizations"
15958 [(set_attr "type" "fpspc")
15959 (set_attr "mode" "XF")])
15961 (define_expand "atan2xf3"
15962 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15963 (unspec:XF [(match_operand:XF 2 "register_operand" "")
15964 (match_operand:XF 1 "register_operand" "")]
15966 (clobber (match_scratch:XF 3 ""))])]
15967 "TARGET_USE_FANCY_MATH_387
15968 && flag_unsafe_math_optimizations"
15971 (define_expand "atan2<mode>3"
15972 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15973 (use (match_operand:X87MODEF12 1 "register_operand" ""))
15974 (use (match_operand:X87MODEF12 2 "register_operand" ""))]
15975 "TARGET_USE_FANCY_MATH_387
15976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15977 || TARGET_MIX_SSE_I387)
15978 && flag_unsafe_math_optimizations"
15980 rtx op0 = gen_reg_rtx (XFmode);
15982 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15983 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15987 (define_expand "atanxf2"
15988 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15989 (unspec:XF [(match_dup 2)
15990 (match_operand:XF 1 "register_operand" "")]
15992 (clobber (match_scratch:XF 3 ""))])]
15993 "TARGET_USE_FANCY_MATH_387
15994 && flag_unsafe_math_optimizations"
15996 operands[2] = gen_reg_rtx (XFmode);
15997 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16000 (define_expand "atan<mode>2"
16001 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16002 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16003 "TARGET_USE_FANCY_MATH_387
16004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16005 || TARGET_MIX_SSE_I387)
16006 && flag_unsafe_math_optimizations"
16008 rtx op0 = gen_reg_rtx (XFmode);
16010 rtx op2 = gen_reg_rtx (<MODE>mode);
16011 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16013 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16014 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16018 (define_expand "asinxf2"
16019 [(set (match_dup 2)
16020 (mult:XF (match_operand:XF 1 "register_operand" "")
16022 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16023 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16024 (parallel [(set (match_operand:XF 0 "register_operand" "")
16025 (unspec:XF [(match_dup 5) (match_dup 1)]
16027 (clobber (match_scratch:XF 6 ""))])]
16028 "TARGET_USE_FANCY_MATH_387
16029 && flag_unsafe_math_optimizations && !optimize_size"
16033 for (i = 2; i < 6; i++)
16034 operands[i] = gen_reg_rtx (XFmode);
16036 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16039 (define_expand "asin<mode>2"
16040 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16041 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16042 "TARGET_USE_FANCY_MATH_387
16043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16044 || TARGET_MIX_SSE_I387)
16045 && flag_unsafe_math_optimizations && !optimize_size"
16047 rtx op0 = gen_reg_rtx (XFmode);
16048 rtx op1 = gen_reg_rtx (XFmode);
16050 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16051 emit_insn (gen_asinxf2 (op0, op1));
16052 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16056 (define_expand "acosxf2"
16057 [(set (match_dup 2)
16058 (mult:XF (match_operand:XF 1 "register_operand" "")
16060 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16061 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16062 (parallel [(set (match_operand:XF 0 "register_operand" "")
16063 (unspec:XF [(match_dup 1) (match_dup 5)]
16065 (clobber (match_scratch:XF 6 ""))])]
16066 "TARGET_USE_FANCY_MATH_387
16067 && flag_unsafe_math_optimizations && !optimize_size"
16071 for (i = 2; i < 6; i++)
16072 operands[i] = gen_reg_rtx (XFmode);
16074 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16077 (define_expand "acos<mode>2"
16078 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16079 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16080 "TARGET_USE_FANCY_MATH_387
16081 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16082 || TARGET_MIX_SSE_I387)
16083 && flag_unsafe_math_optimizations && !optimize_size"
16085 rtx op0 = gen_reg_rtx (XFmode);
16086 rtx op1 = gen_reg_rtx (XFmode);
16088 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16089 emit_insn (gen_acosxf2 (op0, op1));
16090 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16094 (define_insn "fyl2xxf3_i387"
16095 [(set (match_operand:XF 0 "register_operand" "=f")
16096 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16097 (match_operand:XF 2 "register_operand" "u")]
16099 (clobber (match_scratch:XF 3 "=2"))]
16100 "TARGET_USE_FANCY_MATH_387
16101 && flag_unsafe_math_optimizations"
16103 [(set_attr "type" "fpspc")
16104 (set_attr "mode" "XF")])
16106 (define_insn "fyl2x_extend<mode>xf3_i387"
16107 [(set (match_operand:XF 0 "register_operand" "=f")
16108 (unspec:XF [(float_extend:XF
16109 (match_operand:X87MODEF12 1 "register_operand" "0"))
16110 (match_operand:XF 2 "register_operand" "u")]
16112 (clobber (match_scratch:XF 3 "=2"))]
16113 "TARGET_USE_FANCY_MATH_387
16114 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16115 || TARGET_MIX_SSE_I387)
16116 && flag_unsafe_math_optimizations"
16118 [(set_attr "type" "fpspc")
16119 (set_attr "mode" "XF")])
16121 (define_expand "logxf2"
16122 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16123 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16124 (match_dup 2)] UNSPEC_FYL2X))
16125 (clobber (match_scratch:XF 3 ""))])]
16126 "TARGET_USE_FANCY_MATH_387
16127 && flag_unsafe_math_optimizations"
16129 operands[2] = gen_reg_rtx (XFmode);
16130 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16133 (define_expand "log<mode>2"
16134 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16135 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16136 "TARGET_USE_FANCY_MATH_387
16137 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16138 || TARGET_MIX_SSE_I387)
16139 && flag_unsafe_math_optimizations"
16141 rtx op0 = gen_reg_rtx (XFmode);
16143 rtx op2 = gen_reg_rtx (XFmode);
16144 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16146 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16147 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16151 (define_expand "log10xf2"
16152 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16153 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16154 (match_dup 2)] UNSPEC_FYL2X))
16155 (clobber (match_scratch:XF 3 ""))])]
16156 "TARGET_USE_FANCY_MATH_387
16157 && flag_unsafe_math_optimizations"
16159 operands[2] = gen_reg_rtx (XFmode);
16160 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16163 (define_expand "log10<mode>2"
16164 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16165 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16166 "TARGET_USE_FANCY_MATH_387
16167 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16168 || TARGET_MIX_SSE_I387)
16169 && flag_unsafe_math_optimizations"
16171 rtx op0 = gen_reg_rtx (XFmode);
16173 rtx op2 = gen_reg_rtx (XFmode);
16174 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16176 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16177 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16181 (define_expand "log2xf2"
16182 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16183 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16184 (match_dup 2)] UNSPEC_FYL2X))
16185 (clobber (match_scratch:XF 3 ""))])]
16186 "TARGET_USE_FANCY_MATH_387
16187 && flag_unsafe_math_optimizations"
16189 operands[2] = gen_reg_rtx (XFmode);
16190 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16193 (define_expand "log2<mode>2"
16194 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16195 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16196 "TARGET_USE_FANCY_MATH_387
16197 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16198 || TARGET_MIX_SSE_I387)
16199 && flag_unsafe_math_optimizations"
16201 rtx op0 = gen_reg_rtx (XFmode);
16203 rtx op2 = gen_reg_rtx (XFmode);
16204 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16206 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16211 (define_insn "fyl2xp1xf3_i387"
16212 [(set (match_operand:XF 0 "register_operand" "=f")
16213 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16214 (match_operand:XF 2 "register_operand" "u")]
16216 (clobber (match_scratch:XF 3 "=2"))]
16217 "TARGET_USE_FANCY_MATH_387
16218 && flag_unsafe_math_optimizations"
16220 [(set_attr "type" "fpspc")
16221 (set_attr "mode" "XF")])
16223 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16224 [(set (match_operand:XF 0 "register_operand" "=f")
16225 (unspec:XF [(float_extend:XF
16226 (match_operand:X87MODEF12 1 "register_operand" "0"))
16227 (match_operand:XF 2 "register_operand" "u")]
16229 (clobber (match_scratch:XF 3 "=2"))]
16230 "TARGET_USE_FANCY_MATH_387
16231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16232 || TARGET_MIX_SSE_I387)
16233 && flag_unsafe_math_optimizations"
16235 [(set_attr "type" "fpspc")
16236 (set_attr "mode" "XF")])
16238 (define_expand "log1pxf2"
16239 [(use (match_operand:XF 0 "register_operand" ""))
16240 (use (match_operand:XF 1 "register_operand" ""))]
16241 "TARGET_USE_FANCY_MATH_387
16242 && flag_unsafe_math_optimizations && !optimize_size"
16244 ix86_emit_i387_log1p (operands[0], operands[1]);
16248 (define_expand "log1p<mode>2"
16249 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16250 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16251 "TARGET_USE_FANCY_MATH_387
16252 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16253 || TARGET_MIX_SSE_I387)
16254 && flag_unsafe_math_optimizations && !optimize_size"
16256 rtx op0 = gen_reg_rtx (XFmode);
16258 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16260 ix86_emit_i387_log1p (op0, operands[1]);
16261 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16265 (define_insn "fxtractxf3_i387"
16266 [(set (match_operand:XF 0 "register_operand" "=f")
16267 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16268 UNSPEC_XTRACT_FRACT))
16269 (set (match_operand:XF 1 "register_operand" "=u")
16270 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16271 "TARGET_USE_FANCY_MATH_387
16272 && flag_unsafe_math_optimizations"
16274 [(set_attr "type" "fpspc")
16275 (set_attr "mode" "XF")])
16277 (define_insn "fxtract_extend<mode>xf3_i387"
16278 [(set (match_operand:XF 0 "register_operand" "=f")
16279 (unspec:XF [(float_extend:XF
16280 (match_operand:X87MODEF12 2 "register_operand" "0"))]
16281 UNSPEC_XTRACT_FRACT))
16282 (set (match_operand:XF 1 "register_operand" "=u")
16283 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16284 "TARGET_USE_FANCY_MATH_387
16285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16286 || TARGET_MIX_SSE_I387)
16287 && flag_unsafe_math_optimizations"
16289 [(set_attr "type" "fpspc")
16290 (set_attr "mode" "XF")])
16292 (define_expand "logbxf2"
16293 [(parallel [(set (match_dup 2)
16294 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16295 UNSPEC_XTRACT_FRACT))
16296 (set (match_operand:XF 0 "register_operand" "")
16297 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16298 "TARGET_USE_FANCY_MATH_387
16299 && flag_unsafe_math_optimizations"
16301 operands[2] = gen_reg_rtx (XFmode);
16304 (define_expand "logb<mode>2"
16305 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16306 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16307 "TARGET_USE_FANCY_MATH_387
16308 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16309 || TARGET_MIX_SSE_I387)
16310 && flag_unsafe_math_optimizations"
16312 rtx op0 = gen_reg_rtx (XFmode);
16313 rtx op1 = gen_reg_rtx (XFmode);
16315 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16316 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16320 (define_expand "ilogbxf2"
16321 [(use (match_operand:SI 0 "register_operand" ""))
16322 (use (match_operand:XF 1 "register_operand" ""))]
16323 "TARGET_USE_FANCY_MATH_387
16324 && flag_unsafe_math_optimizations && !optimize_size"
16326 rtx op0 = gen_reg_rtx (XFmode);
16327 rtx op1 = gen_reg_rtx (XFmode);
16329 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16330 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16334 (define_expand "ilogb<mode>2"
16335 [(use (match_operand:SI 0 "register_operand" ""))
16336 (use (match_operand:X87MODEF12 1 "register_operand" ""))]
16337 "TARGET_USE_FANCY_MATH_387
16338 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16339 || TARGET_MIX_SSE_I387)
16340 && flag_unsafe_math_optimizations && !optimize_size"
16342 rtx op0 = gen_reg_rtx (XFmode);
16343 rtx op1 = gen_reg_rtx (XFmode);
16345 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16346 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16350 (define_insn "*f2xm1xf2_i387"
16351 [(set (match_operand:XF 0 "register_operand" "=f")
16352 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16354 "TARGET_USE_FANCY_MATH_387
16355 && flag_unsafe_math_optimizations"
16357 [(set_attr "type" "fpspc")
16358 (set_attr "mode" "XF")])
16360 (define_insn "*fscalexf4_i387"
16361 [(set (match_operand:XF 0 "register_operand" "=f")
16362 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16363 (match_operand:XF 3 "register_operand" "1")]
16364 UNSPEC_FSCALE_FRACT))
16365 (set (match_operand:XF 1 "register_operand" "=u")
16366 (unspec:XF [(match_dup 2) (match_dup 3)]
16367 UNSPEC_FSCALE_EXP))]
16368 "TARGET_USE_FANCY_MATH_387
16369 && flag_unsafe_math_optimizations"
16371 [(set_attr "type" "fpspc")
16372 (set_attr "mode" "XF")])
16374 (define_expand "expNcorexf3"
16375 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16376 (match_operand:XF 2 "register_operand" "")))
16377 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16378 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16379 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16380 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16381 (parallel [(set (match_operand:XF 0 "register_operand" "")
16382 (unspec:XF [(match_dup 8) (match_dup 4)]
16383 UNSPEC_FSCALE_FRACT))
16385 (unspec:XF [(match_dup 8) (match_dup 4)]
16386 UNSPEC_FSCALE_EXP))])]
16387 "TARGET_USE_FANCY_MATH_387
16388 && flag_unsafe_math_optimizations && !optimize_size"
16392 for (i = 3; i < 10; i++)
16393 operands[i] = gen_reg_rtx (XFmode);
16395 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16398 (define_expand "expxf2"
16399 [(use (match_operand:XF 0 "register_operand" ""))
16400 (use (match_operand:XF 1 "register_operand" ""))]
16401 "TARGET_USE_FANCY_MATH_387
16402 && flag_unsafe_math_optimizations && !optimize_size"
16404 rtx op2 = gen_reg_rtx (XFmode);
16405 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16407 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16411 (define_expand "exp<mode>2"
16412 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16413 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16414 "TARGET_USE_FANCY_MATH_387
16415 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16416 || TARGET_MIX_SSE_I387)
16417 && flag_unsafe_math_optimizations && !optimize_size"
16419 rtx op0 = gen_reg_rtx (XFmode);
16420 rtx op1 = gen_reg_rtx (XFmode);
16422 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16423 emit_insn (gen_expxf2 (op0, op1));
16424 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16428 (define_expand "exp10xf2"
16429 [(use (match_operand:XF 0 "register_operand" ""))
16430 (use (match_operand:XF 1 "register_operand" ""))]
16431 "TARGET_USE_FANCY_MATH_387
16432 && flag_unsafe_math_optimizations && !optimize_size"
16434 rtx op2 = gen_reg_rtx (XFmode);
16435 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16437 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16441 (define_expand "exp10<mode>2"
16442 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16443 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16444 "TARGET_USE_FANCY_MATH_387
16445 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16446 || TARGET_MIX_SSE_I387)
16447 && flag_unsafe_math_optimizations && !optimize_size"
16449 rtx op0 = gen_reg_rtx (XFmode);
16450 rtx op1 = gen_reg_rtx (XFmode);
16452 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16453 emit_insn (gen_exp10xf2 (op0, op1));
16454 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16458 (define_expand "exp2xf2"
16459 [(use (match_operand:XF 0 "register_operand" ""))
16460 (use (match_operand:XF 1 "register_operand" ""))]
16461 "TARGET_USE_FANCY_MATH_387
16462 && flag_unsafe_math_optimizations && !optimize_size"
16464 rtx op2 = gen_reg_rtx (XFmode);
16465 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16467 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16471 (define_expand "exp2<mode>2"
16472 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16473 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16474 "TARGET_USE_FANCY_MATH_387
16475 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16476 || TARGET_MIX_SSE_I387)
16477 && flag_unsafe_math_optimizations && !optimize_size"
16479 rtx op0 = gen_reg_rtx (XFmode);
16480 rtx op1 = gen_reg_rtx (XFmode);
16482 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16483 emit_insn (gen_exp2xf2 (op0, op1));
16484 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16488 (define_expand "expm1xf2"
16489 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16491 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16492 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16493 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16494 (parallel [(set (match_dup 7)
16495 (unspec:XF [(match_dup 6) (match_dup 4)]
16496 UNSPEC_FSCALE_FRACT))
16498 (unspec:XF [(match_dup 6) (match_dup 4)]
16499 UNSPEC_FSCALE_EXP))])
16500 (parallel [(set (match_dup 10)
16501 (unspec:XF [(match_dup 9) (match_dup 8)]
16502 UNSPEC_FSCALE_FRACT))
16503 (set (match_dup 11)
16504 (unspec:XF [(match_dup 9) (match_dup 8)]
16505 UNSPEC_FSCALE_EXP))])
16506 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16507 (set (match_operand:XF 0 "register_operand" "")
16508 (plus:XF (match_dup 12) (match_dup 7)))]
16509 "TARGET_USE_FANCY_MATH_387
16510 && flag_unsafe_math_optimizations && !optimize_size"
16514 for (i = 2; i < 13; i++)
16515 operands[i] = gen_reg_rtx (XFmode);
16517 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16518 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
16521 (define_expand "expm1<mode>2"
16522 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16523 (use (match_operand:X87MODEF12 1 "general_operand" ""))]
16524 "TARGET_USE_FANCY_MATH_387
16525 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16526 || TARGET_MIX_SSE_I387)
16527 && flag_unsafe_math_optimizations && !optimize_size"
16529 rtx op0 = gen_reg_rtx (XFmode);
16530 rtx op1 = gen_reg_rtx (XFmode);
16532 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16533 emit_insn (gen_expm1xf2 (op0, op1));
16534 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16538 (define_expand "ldexpxf3"
16539 [(set (match_dup 3)
16540 (float:XF (match_operand:SI 2 "register_operand" "")))
16541 (parallel [(set (match_operand:XF 0 " register_operand" "")
16542 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16544 UNSPEC_FSCALE_FRACT))
16546 (unspec:XF [(match_dup 1) (match_dup 3)]
16547 UNSPEC_FSCALE_EXP))])]
16548 "TARGET_USE_FANCY_MATH_387
16549 && flag_unsafe_math_optimizations && !optimize_size"
16551 operands[3] = gen_reg_rtx (XFmode);
16552 operands[4] = gen_reg_rtx (XFmode);
16555 (define_expand "ldexp<mode>3"
16556 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
16557 (use (match_operand:X87MODEF12 1 "general_operand" ""))
16558 (use (match_operand:SI 2 "register_operand" ""))]
16559 "TARGET_USE_FANCY_MATH_387
16560 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16561 || TARGET_MIX_SSE_I387)
16562 && flag_unsafe_math_optimizations && !optimize_size"
16564 rtx op0 = gen_reg_rtx (XFmode);
16565 rtx op1 = gen_reg_rtx (XFmode);
16567 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16568 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16569 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16574 (define_insn "frndintxf2"
16575 [(set (match_operand:XF 0 "register_operand" "=f")
16576 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16578 "TARGET_USE_FANCY_MATH_387
16579 && flag_unsafe_math_optimizations"
16581 [(set_attr "type" "fpspc")
16582 (set_attr "mode" "XF")])
16584 (define_expand "rintdf2"
16585 [(use (match_operand:DF 0 "register_operand" ""))
16586 (use (match_operand:DF 1 "register_operand" ""))]
16587 "(TARGET_USE_FANCY_MATH_387
16588 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16589 && flag_unsafe_math_optimizations)
16590 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16591 && !flag_trapping_math
16592 && !optimize_size)"
16594 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16595 && !flag_trapping_math
16597 ix86_expand_rint (operand0, operand1);
16600 rtx op0 = gen_reg_rtx (XFmode);
16601 rtx op1 = gen_reg_rtx (XFmode);
16603 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16604 emit_insn (gen_frndintxf2 (op0, op1));
16606 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16611 (define_expand "rintsf2"
16612 [(use (match_operand:SF 0 "register_operand" ""))
16613 (use (match_operand:SF 1 "register_operand" ""))]
16614 "(TARGET_USE_FANCY_MATH_387
16615 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16616 && flag_unsafe_math_optimizations)
16617 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16618 && !flag_trapping_math
16619 && !optimize_size)"
16621 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16622 && !flag_trapping_math
16624 ix86_expand_rint (operand0, operand1);
16627 rtx op0 = gen_reg_rtx (XFmode);
16628 rtx op1 = gen_reg_rtx (XFmode);
16630 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16631 emit_insn (gen_frndintxf2 (op0, op1));
16633 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16638 (define_expand "rintxf2"
16639 [(use (match_operand:XF 0 "register_operand" ""))
16640 (use (match_operand:XF 1 "register_operand" ""))]
16641 "TARGET_USE_FANCY_MATH_387
16642 && flag_unsafe_math_optimizations && !optimize_size"
16644 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
16648 (define_expand "roundsf2"
16649 [(match_operand:SF 0 "register_operand" "")
16650 (match_operand:SF 1 "nonimmediate_operand" "")]
16651 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16652 && !flag_trapping_math && !flag_rounding_math
16655 ix86_expand_round (operand0, operand1);
16659 (define_expand "rounddf2"
16660 [(match_operand:DF 0 "register_operand" "")
16661 (match_operand:DF 1 "nonimmediate_operand" "")]
16662 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16663 && !flag_trapping_math && !flag_rounding_math
16667 ix86_expand_round (operand0, operand1);
16669 ix86_expand_rounddf_32 (operand0, operand1);
16673 (define_insn_and_split "*fistdi2_1"
16674 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16675 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16677 "TARGET_USE_FANCY_MATH_387
16678 && !(reload_completed || reload_in_progress)"
16683 if (memory_operand (operands[0], VOIDmode))
16684 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16687 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16688 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16693 [(set_attr "type" "fpspc")
16694 (set_attr "mode" "DI")])
16696 (define_insn "fistdi2"
16697 [(set (match_operand:DI 0 "memory_operand" "=m")
16698 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16700 (clobber (match_scratch:XF 2 "=&1f"))]
16701 "TARGET_USE_FANCY_MATH_387"
16702 "* return output_fix_trunc (insn, operands, 0);"
16703 [(set_attr "type" "fpspc")
16704 (set_attr "mode" "DI")])
16706 (define_insn "fistdi2_with_temp"
16707 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16708 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16710 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
16711 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16712 "TARGET_USE_FANCY_MATH_387"
16714 [(set_attr "type" "fpspc")
16715 (set_attr "mode" "DI")])
16718 [(set (match_operand:DI 0 "register_operand" "")
16719 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16721 (clobber (match_operand:DI 2 "memory_operand" ""))
16722 (clobber (match_scratch 3 ""))]
16724 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16725 (clobber (match_dup 3))])
16726 (set (match_dup 0) (match_dup 2))]
16730 [(set (match_operand:DI 0 "memory_operand" "")
16731 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16733 (clobber (match_operand:DI 2 "memory_operand" ""))
16734 (clobber (match_scratch 3 ""))]
16736 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16737 (clobber (match_dup 3))])]
16740 (define_insn_and_split "*fist<mode>2_1"
16741 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16742 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16744 "TARGET_USE_FANCY_MATH_387
16745 && !(reload_completed || reload_in_progress)"
16750 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16751 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16755 [(set_attr "type" "fpspc")
16756 (set_attr "mode" "<MODE>")])
16758 (define_insn "fist<mode>2"
16759 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16760 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16762 "TARGET_USE_FANCY_MATH_387"
16763 "* return output_fix_trunc (insn, operands, 0);"
16764 [(set_attr "type" "fpspc")
16765 (set_attr "mode" "<MODE>")])
16767 (define_insn "fist<mode>2_with_temp"
16768 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16769 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16771 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16772 "TARGET_USE_FANCY_MATH_387"
16774 [(set_attr "type" "fpspc")
16775 (set_attr "mode" "<MODE>")])
16778 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16779 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16781 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16783 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
16785 (set (match_dup 0) (match_dup 2))]
16789 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16790 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16792 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16794 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16798 (define_expand "lrintxf<mode>2"
16799 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16800 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16802 "TARGET_USE_FANCY_MATH_387"
16805 (define_expand "lrint<mode>di2"
16806 [(set (match_operand:DI 0 "nonimmediate_operand" "")
16807 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
16808 UNSPEC_FIX_NOTRUNC))]
16809 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
16812 (define_expand "lrint<mode>si2"
16813 [(set (match_operand:SI 0 "nonimmediate_operand" "")
16814 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
16815 UNSPEC_FIX_NOTRUNC))]
16816 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16819 (define_expand "lround<mode>di2"
16820 [(match_operand:DI 0 "nonimmediate_operand" "")
16821 (match_operand:SSEMODEF 1 "register_operand" "")]
16822 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
16823 && !flag_trapping_math && !flag_rounding_math
16826 ix86_expand_lround (operand0, operand1);
16830 (define_expand "lround<mode>si2"
16831 [(match_operand:SI 0 "nonimmediate_operand" "")
16832 (match_operand:SSEMODEF 1 "register_operand" "")]
16833 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16834 && !flag_trapping_math && !flag_rounding_math
16837 ix86_expand_lround (operand0, operand1);
16841 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16842 (define_insn_and_split "frndintxf2_floor"
16843 [(set (match_operand:XF 0 "register_operand" "=f")
16844 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16845 UNSPEC_FRNDINT_FLOOR))
16846 (clobber (reg:CC FLAGS_REG))]
16847 "TARGET_USE_FANCY_MATH_387
16848 && flag_unsafe_math_optimizations
16849 && !(reload_completed || reload_in_progress)"
16854 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16856 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16857 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16859 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16860 operands[2], operands[3]));
16863 [(set_attr "type" "frndint")
16864 (set_attr "i387_cw" "floor")
16865 (set_attr "mode" "XF")])
16867 (define_insn "frndintxf2_floor_i387"
16868 [(set (match_operand:XF 0 "register_operand" "=f")
16869 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16870 UNSPEC_FRNDINT_FLOOR))
16871 (use (match_operand:HI 2 "memory_operand" "m"))
16872 (use (match_operand:HI 3 "memory_operand" "m"))]
16873 "TARGET_USE_FANCY_MATH_387
16874 && flag_unsafe_math_optimizations"
16875 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16876 [(set_attr "type" "frndint")
16877 (set_attr "i387_cw" "floor")
16878 (set_attr "mode" "XF")])
16880 (define_expand "floorxf2"
16881 [(use (match_operand:XF 0 "register_operand" ""))
16882 (use (match_operand:XF 1 "register_operand" ""))]
16883 "TARGET_USE_FANCY_MATH_387
16884 && flag_unsafe_math_optimizations && !optimize_size"
16886 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16890 (define_expand "floordf2"
16891 [(use (match_operand:DF 0 "register_operand" ""))
16892 (use (match_operand:DF 1 "register_operand" ""))]
16893 "((TARGET_USE_FANCY_MATH_387
16894 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16895 && flag_unsafe_math_optimizations)
16896 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16897 && !flag_trapping_math))
16900 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
16901 && !flag_trapping_math)
16904 ix86_expand_floorceil (operand0, operand1, true);
16906 ix86_expand_floorceildf_32 (operand0, operand1, true);
16910 rtx op0 = gen_reg_rtx (XFmode);
16911 rtx op1 = gen_reg_rtx (XFmode);
16913 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16914 emit_insn (gen_frndintxf2_floor (op0, op1));
16916 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16921 (define_expand "floorsf2"
16922 [(use (match_operand:SF 0 "register_operand" ""))
16923 (use (match_operand:SF 1 "register_operand" ""))]
16924 "((TARGET_USE_FANCY_MATH_387
16925 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16926 && flag_unsafe_math_optimizations)
16927 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16928 && !flag_trapping_math))
16931 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
16932 && !flag_trapping_math)
16933 ix86_expand_floorceil (operand0, operand1, true);
16936 rtx op0 = gen_reg_rtx (XFmode);
16937 rtx op1 = gen_reg_rtx (XFmode);
16939 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16940 emit_insn (gen_frndintxf2_floor (op0, op1));
16942 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16947 (define_insn_and_split "*fist<mode>2_floor_1"
16948 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
16949 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
16950 UNSPEC_FIST_FLOOR))
16951 (clobber (reg:CC FLAGS_REG))]
16952 "TARGET_USE_FANCY_MATH_387
16953 && flag_unsafe_math_optimizations
16954 && !(reload_completed || reload_in_progress)"
16959 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16961 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16962 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16963 if (memory_operand (operands[0], VOIDmode))
16964 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16965 operands[2], operands[3]));
16968 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16969 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16970 operands[2], operands[3],
16975 [(set_attr "type" "fistp")
16976 (set_attr "i387_cw" "floor")
16977 (set_attr "mode" "<MODE>")])
16979 (define_insn "fistdi2_floor"
16980 [(set (match_operand:DI 0 "memory_operand" "=m")
16981 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16982 UNSPEC_FIST_FLOOR))
16983 (use (match_operand:HI 2 "memory_operand" "m"))
16984 (use (match_operand:HI 3 "memory_operand" "m"))
16985 (clobber (match_scratch:XF 4 "=&1f"))]
16986 "TARGET_USE_FANCY_MATH_387
16987 && flag_unsafe_math_optimizations"
16988 "* return output_fix_trunc (insn, operands, 0);"
16989 [(set_attr "type" "fistp")
16990 (set_attr "i387_cw" "floor")
16991 (set_attr "mode" "DI")])
16993 (define_insn "fistdi2_floor_with_temp"
16994 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16995 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16996 UNSPEC_FIST_FLOOR))
16997 (use (match_operand:HI 2 "memory_operand" "m,m"))
16998 (use (match_operand:HI 3 "memory_operand" "m,m"))
16999 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17000 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17001 "TARGET_USE_FANCY_MATH_387
17002 && flag_unsafe_math_optimizations"
17004 [(set_attr "type" "fistp")
17005 (set_attr "i387_cw" "floor")
17006 (set_attr "mode" "DI")])
17009 [(set (match_operand:DI 0 "register_operand" "")
17010 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17011 UNSPEC_FIST_FLOOR))
17012 (use (match_operand:HI 2 "memory_operand" ""))
17013 (use (match_operand:HI 3 "memory_operand" ""))
17014 (clobber (match_operand:DI 4 "memory_operand" ""))
17015 (clobber (match_scratch 5 ""))]
17017 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17018 (use (match_dup 2))
17019 (use (match_dup 3))
17020 (clobber (match_dup 5))])
17021 (set (match_dup 0) (match_dup 4))]
17025 [(set (match_operand:DI 0 "memory_operand" "")
17026 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17027 UNSPEC_FIST_FLOOR))
17028 (use (match_operand:HI 2 "memory_operand" ""))
17029 (use (match_operand:HI 3 "memory_operand" ""))
17030 (clobber (match_operand:DI 4 "memory_operand" ""))
17031 (clobber (match_scratch 5 ""))]
17033 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17034 (use (match_dup 2))
17035 (use (match_dup 3))
17036 (clobber (match_dup 5))])]
17039 (define_insn "fist<mode>2_floor"
17040 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17041 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17042 UNSPEC_FIST_FLOOR))
17043 (use (match_operand:HI 2 "memory_operand" "m"))
17044 (use (match_operand:HI 3 "memory_operand" "m"))]
17045 "TARGET_USE_FANCY_MATH_387
17046 && flag_unsafe_math_optimizations"
17047 "* return output_fix_trunc (insn, operands, 0);"
17048 [(set_attr "type" "fistp")
17049 (set_attr "i387_cw" "floor")
17050 (set_attr "mode" "<MODE>")])
17052 (define_insn "fist<mode>2_floor_with_temp"
17053 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17054 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17055 UNSPEC_FIST_FLOOR))
17056 (use (match_operand:HI 2 "memory_operand" "m,m"))
17057 (use (match_operand:HI 3 "memory_operand" "m,m"))
17058 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17059 "TARGET_USE_FANCY_MATH_387
17060 && flag_unsafe_math_optimizations"
17062 [(set_attr "type" "fistp")
17063 (set_attr "i387_cw" "floor")
17064 (set_attr "mode" "<MODE>")])
17067 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17068 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17069 UNSPEC_FIST_FLOOR))
17070 (use (match_operand:HI 2 "memory_operand" ""))
17071 (use (match_operand:HI 3 "memory_operand" ""))
17072 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17074 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17075 UNSPEC_FIST_FLOOR))
17076 (use (match_dup 2))
17077 (use (match_dup 3))])
17078 (set (match_dup 0) (match_dup 4))]
17082 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17083 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17084 UNSPEC_FIST_FLOOR))
17085 (use (match_operand:HI 2 "memory_operand" ""))
17086 (use (match_operand:HI 3 "memory_operand" ""))
17087 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17089 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17090 UNSPEC_FIST_FLOOR))
17091 (use (match_dup 2))
17092 (use (match_dup 3))])]
17095 (define_expand "lfloorxf<mode>2"
17096 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17097 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17098 UNSPEC_FIST_FLOOR))
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "TARGET_USE_FANCY_MATH_387
17101 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17102 && flag_unsafe_math_optimizations"
17105 (define_expand "lfloor<mode>di2"
17106 [(match_operand:DI 0 "nonimmediate_operand" "")
17107 (match_operand:SSEMODEF 1 "register_operand" "")]
17108 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17109 && !flag_trapping_math
17112 ix86_expand_lfloorceil (operand0, operand1, true);
17116 (define_expand "lfloor<mode>si2"
17117 [(match_operand:SI 0 "nonimmediate_operand" "")
17118 (match_operand:SSEMODEF 1 "register_operand" "")]
17119 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17120 && !flag_trapping_math
17121 && (!optimize_size || !TARGET_64BIT)"
17123 ix86_expand_lfloorceil (operand0, operand1, true);
17127 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17128 (define_insn_and_split "frndintxf2_ceil"
17129 [(set (match_operand:XF 0 "register_operand" "=f")
17130 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17131 UNSPEC_FRNDINT_CEIL))
17132 (clobber (reg:CC FLAGS_REG))]
17133 "TARGET_USE_FANCY_MATH_387
17134 && flag_unsafe_math_optimizations
17135 && !(reload_completed || reload_in_progress)"
17140 ix86_optimize_mode_switching[I387_CEIL] = 1;
17142 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17143 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17145 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17146 operands[2], operands[3]));
17149 [(set_attr "type" "frndint")
17150 (set_attr "i387_cw" "ceil")
17151 (set_attr "mode" "XF")])
17153 (define_insn "frndintxf2_ceil_i387"
17154 [(set (match_operand:XF 0 "register_operand" "=f")
17155 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17156 UNSPEC_FRNDINT_CEIL))
17157 (use (match_operand:HI 2 "memory_operand" "m"))
17158 (use (match_operand:HI 3 "memory_operand" "m"))]
17159 "TARGET_USE_FANCY_MATH_387
17160 && flag_unsafe_math_optimizations"
17161 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17162 [(set_attr "type" "frndint")
17163 (set_attr "i387_cw" "ceil")
17164 (set_attr "mode" "XF")])
17166 (define_expand "ceilxf2"
17167 [(use (match_operand:XF 0 "register_operand" ""))
17168 (use (match_operand:XF 1 "register_operand" ""))]
17169 "TARGET_USE_FANCY_MATH_387
17170 && flag_unsafe_math_optimizations && !optimize_size"
17172 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17176 (define_expand "ceildf2"
17177 [(use (match_operand:DF 0 "register_operand" ""))
17178 (use (match_operand:DF 1 "register_operand" ""))]
17179 "((TARGET_USE_FANCY_MATH_387
17180 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17181 && flag_unsafe_math_optimizations)
17182 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17183 && !flag_trapping_math))
17186 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17187 && !flag_trapping_math)
17190 ix86_expand_floorceil (operand0, operand1, false);
17192 ix86_expand_floorceildf_32 (operand0, operand1, false);
17196 rtx op0 = gen_reg_rtx (XFmode);
17197 rtx op1 = gen_reg_rtx (XFmode);
17199 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17200 emit_insn (gen_frndintxf2_ceil (op0, op1));
17202 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17207 (define_expand "ceilsf2"
17208 [(use (match_operand:SF 0 "register_operand" ""))
17209 (use (match_operand:SF 1 "register_operand" ""))]
17210 "((TARGET_USE_FANCY_MATH_387
17211 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17212 && flag_unsafe_math_optimizations)
17213 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17214 && !flag_trapping_math))
17217 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17218 && !flag_trapping_math)
17219 ix86_expand_floorceil (operand0, operand1, false);
17222 rtx op0 = gen_reg_rtx (XFmode);
17223 rtx op1 = gen_reg_rtx (XFmode);
17225 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17226 emit_insn (gen_frndintxf2_ceil (op0, op1));
17228 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17233 (define_insn_and_split "*fist<mode>2_ceil_1"
17234 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17235 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17237 (clobber (reg:CC FLAGS_REG))]
17238 "TARGET_USE_FANCY_MATH_387
17239 && flag_unsafe_math_optimizations
17240 && !(reload_completed || reload_in_progress)"
17245 ix86_optimize_mode_switching[I387_CEIL] = 1;
17247 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17248 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17249 if (memory_operand (operands[0], VOIDmode))
17250 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17251 operands[2], operands[3]));
17254 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17255 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17256 operands[2], operands[3],
17261 [(set_attr "type" "fistp")
17262 (set_attr "i387_cw" "ceil")
17263 (set_attr "mode" "<MODE>")])
17265 (define_insn "fistdi2_ceil"
17266 [(set (match_operand:DI 0 "memory_operand" "=m")
17267 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17269 (use (match_operand:HI 2 "memory_operand" "m"))
17270 (use (match_operand:HI 3 "memory_operand" "m"))
17271 (clobber (match_scratch:XF 4 "=&1f"))]
17272 "TARGET_USE_FANCY_MATH_387
17273 && flag_unsafe_math_optimizations"
17274 "* return output_fix_trunc (insn, operands, 0);"
17275 [(set_attr "type" "fistp")
17276 (set_attr "i387_cw" "ceil")
17277 (set_attr "mode" "DI")])
17279 (define_insn "fistdi2_ceil_with_temp"
17280 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17281 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17283 (use (match_operand:HI 2 "memory_operand" "m,m"))
17284 (use (match_operand:HI 3 "memory_operand" "m,m"))
17285 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17286 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17287 "TARGET_USE_FANCY_MATH_387
17288 && flag_unsafe_math_optimizations"
17290 [(set_attr "type" "fistp")
17291 (set_attr "i387_cw" "ceil")
17292 (set_attr "mode" "DI")])
17295 [(set (match_operand:DI 0 "register_operand" "")
17296 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17298 (use (match_operand:HI 2 "memory_operand" ""))
17299 (use (match_operand:HI 3 "memory_operand" ""))
17300 (clobber (match_operand:DI 4 "memory_operand" ""))
17301 (clobber (match_scratch 5 ""))]
17303 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17304 (use (match_dup 2))
17305 (use (match_dup 3))
17306 (clobber (match_dup 5))])
17307 (set (match_dup 0) (match_dup 4))]
17311 [(set (match_operand:DI 0 "memory_operand" "")
17312 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17314 (use (match_operand:HI 2 "memory_operand" ""))
17315 (use (match_operand:HI 3 "memory_operand" ""))
17316 (clobber (match_operand:DI 4 "memory_operand" ""))
17317 (clobber (match_scratch 5 ""))]
17319 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17320 (use (match_dup 2))
17321 (use (match_dup 3))
17322 (clobber (match_dup 5))])]
17325 (define_insn "fist<mode>2_ceil"
17326 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17327 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17329 (use (match_operand:HI 2 "memory_operand" "m"))
17330 (use (match_operand:HI 3 "memory_operand" "m"))]
17331 "TARGET_USE_FANCY_MATH_387
17332 && flag_unsafe_math_optimizations"
17333 "* return output_fix_trunc (insn, operands, 0);"
17334 [(set_attr "type" "fistp")
17335 (set_attr "i387_cw" "ceil")
17336 (set_attr "mode" "<MODE>")])
17338 (define_insn "fist<mode>2_ceil_with_temp"
17339 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17340 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17342 (use (match_operand:HI 2 "memory_operand" "m,m"))
17343 (use (match_operand:HI 3 "memory_operand" "m,m"))
17344 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17345 "TARGET_USE_FANCY_MATH_387
17346 && flag_unsafe_math_optimizations"
17348 [(set_attr "type" "fistp")
17349 (set_attr "i387_cw" "ceil")
17350 (set_attr "mode" "<MODE>")])
17353 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17354 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17356 (use (match_operand:HI 2 "memory_operand" ""))
17357 (use (match_operand:HI 3 "memory_operand" ""))
17358 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17360 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17362 (use (match_dup 2))
17363 (use (match_dup 3))])
17364 (set (match_dup 0) (match_dup 4))]
17368 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17369 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17371 (use (match_operand:HI 2 "memory_operand" ""))
17372 (use (match_operand:HI 3 "memory_operand" ""))
17373 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17375 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17377 (use (match_dup 2))
17378 (use (match_dup 3))])]
17381 (define_expand "lceilxf<mode>2"
17382 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17383 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17385 (clobber (reg:CC FLAGS_REG))])]
17386 "TARGET_USE_FANCY_MATH_387
17387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17388 && flag_unsafe_math_optimizations"
17391 (define_expand "lceil<mode>di2"
17392 [(match_operand:DI 0 "nonimmediate_operand" "")
17393 (match_operand:SSEMODEF 1 "register_operand" "")]
17394 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17395 && !flag_trapping_math"
17397 ix86_expand_lfloorceil (operand0, operand1, false);
17401 (define_expand "lceil<mode>si2"
17402 [(match_operand:SI 0 "nonimmediate_operand" "")
17403 (match_operand:SSEMODEF 1 "register_operand" "")]
17404 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17405 && !flag_trapping_math"
17407 ix86_expand_lfloorceil (operand0, operand1, false);
17411 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17412 (define_insn_and_split "frndintxf2_trunc"
17413 [(set (match_operand:XF 0 "register_operand" "=f")
17414 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17415 UNSPEC_FRNDINT_TRUNC))
17416 (clobber (reg:CC FLAGS_REG))]
17417 "TARGET_USE_FANCY_MATH_387
17418 && flag_unsafe_math_optimizations
17419 && !(reload_completed || reload_in_progress)"
17424 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17426 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17427 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17429 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17430 operands[2], operands[3]));
17433 [(set_attr "type" "frndint")
17434 (set_attr "i387_cw" "trunc")
17435 (set_attr "mode" "XF")])
17437 (define_insn "frndintxf2_trunc_i387"
17438 [(set (match_operand:XF 0 "register_operand" "=f")
17439 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17440 UNSPEC_FRNDINT_TRUNC))
17441 (use (match_operand:HI 2 "memory_operand" "m"))
17442 (use (match_operand:HI 3 "memory_operand" "m"))]
17443 "TARGET_USE_FANCY_MATH_387
17444 && flag_unsafe_math_optimizations"
17445 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17446 [(set_attr "type" "frndint")
17447 (set_attr "i387_cw" "trunc")
17448 (set_attr "mode" "XF")])
17450 (define_expand "btruncxf2"
17451 [(use (match_operand:XF 0 "register_operand" ""))
17452 (use (match_operand:XF 1 "register_operand" ""))]
17453 "TARGET_USE_FANCY_MATH_387
17454 && flag_unsafe_math_optimizations && !optimize_size"
17456 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17460 (define_expand "btruncdf2"
17461 [(use (match_operand:DF 0 "register_operand" ""))
17462 (use (match_operand:DF 1 "register_operand" ""))]
17463 "((TARGET_USE_FANCY_MATH_387
17464 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17465 && flag_unsafe_math_optimizations)
17466 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17467 && !flag_trapping_math))
17470 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17471 && !flag_trapping_math)
17474 ix86_expand_trunc (operand0, operand1);
17476 ix86_expand_truncdf_32 (operand0, operand1);
17480 rtx op0 = gen_reg_rtx (XFmode);
17481 rtx op1 = gen_reg_rtx (XFmode);
17483 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17484 emit_insn (gen_frndintxf2_trunc (op0, op1));
17486 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17491 (define_expand "btruncsf2"
17492 [(use (match_operand:SF 0 "register_operand" ""))
17493 (use (match_operand:SF 1 "register_operand" ""))]
17494 "((TARGET_USE_FANCY_MATH_387
17495 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17496 && flag_unsafe_math_optimizations)
17497 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17498 && !flag_trapping_math))
17501 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17502 && !flag_trapping_math)
17503 ix86_expand_trunc (operand0, operand1);
17506 rtx op0 = gen_reg_rtx (XFmode);
17507 rtx op1 = gen_reg_rtx (XFmode);
17509 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17510 emit_insn (gen_frndintxf2_trunc (op0, op1));
17512 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17517 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17518 (define_insn_and_split "frndintxf2_mask_pm"
17519 [(set (match_operand:XF 0 "register_operand" "=f")
17520 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17521 UNSPEC_FRNDINT_MASK_PM))
17522 (clobber (reg:CC FLAGS_REG))]
17523 "TARGET_USE_FANCY_MATH_387
17524 && flag_unsafe_math_optimizations
17525 && !(reload_completed || reload_in_progress)"
17530 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17532 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17533 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17535 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17536 operands[2], operands[3]));
17539 [(set_attr "type" "frndint")
17540 (set_attr "i387_cw" "mask_pm")
17541 (set_attr "mode" "XF")])
17543 (define_insn "frndintxf2_mask_pm_i387"
17544 [(set (match_operand:XF 0 "register_operand" "=f")
17545 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17546 UNSPEC_FRNDINT_MASK_PM))
17547 (use (match_operand:HI 2 "memory_operand" "m"))
17548 (use (match_operand:HI 3 "memory_operand" "m"))]
17549 "TARGET_USE_FANCY_MATH_387
17550 && flag_unsafe_math_optimizations"
17551 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17552 [(set_attr "type" "frndint")
17553 (set_attr "i387_cw" "mask_pm")
17554 (set_attr "mode" "XF")])
17556 (define_expand "nearbyintxf2"
17557 [(use (match_operand:XF 0 "register_operand" ""))
17558 (use (match_operand:XF 1 "register_operand" ""))]
17559 "TARGET_USE_FANCY_MATH_387
17560 && flag_unsafe_math_optimizations"
17562 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17567 (define_expand "nearbyintdf2"
17568 [(use (match_operand:DF 0 "register_operand" ""))
17569 (use (match_operand:DF 1 "register_operand" ""))]
17570 "TARGET_USE_FANCY_MATH_387
17571 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17572 && flag_unsafe_math_optimizations"
17574 rtx op0 = gen_reg_rtx (XFmode);
17575 rtx op1 = gen_reg_rtx (XFmode);
17577 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17578 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17580 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17584 (define_expand "nearbyintsf2"
17585 [(use (match_operand:SF 0 "register_operand" ""))
17586 (use (match_operand:SF 1 "register_operand" ""))]
17587 "TARGET_USE_FANCY_MATH_387
17588 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17589 && flag_unsafe_math_optimizations"
17591 rtx op0 = gen_reg_rtx (XFmode);
17592 rtx op1 = gen_reg_rtx (XFmode);
17594 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17595 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17597 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17601 (define_insn "fxam<mode>2_i387"
17602 [(set (match_operand:HI 0 "register_operand" "=a")
17604 [(match_operand:X87MODEF 1 "register_operand" "f")]
17606 "TARGET_USE_FANCY_MATH_387"
17607 "fxam\n\tfnstsw\t%0"
17608 [(set_attr "type" "multi")
17609 (set_attr "unit" "i387")
17610 (set_attr "mode" "<MODE>")])
17612 (define_expand "isinf<mode>2"
17613 [(use (match_operand:SI 0 "register_operand" ""))
17614 (use (match_operand:X87MODEF 1 "register_operand" ""))]
17615 "TARGET_USE_FANCY_MATH_387
17616 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17617 || TARGET_MIX_SSE_I387)"
17619 rtx mask = GEN_INT (0x45);
17620 rtx val = GEN_INT (0x05);
17624 rtx scratch = gen_reg_rtx (HImode);
17625 rtx res = gen_reg_rtx (QImode);
17627 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17628 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17629 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17630 cond = gen_rtx_fmt_ee (EQ, QImode,
17631 gen_rtx_REG (CCmode, FLAGS_REG),
17633 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17634 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17639 ;; Block operation instructions
17641 (define_expand "movmemsi"
17642 [(use (match_operand:BLK 0 "memory_operand" ""))
17643 (use (match_operand:BLK 1 "memory_operand" ""))
17644 (use (match_operand:SI 2 "nonmemory_operand" ""))
17645 (use (match_operand:SI 3 "const_int_operand" ""))
17646 (use (match_operand:SI 4 "const_int_operand" ""))
17647 (use (match_operand:SI 5 "const_int_operand" ""))]
17650 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17651 operands[4], operands[5]))
17657 (define_expand "movmemdi"
17658 [(use (match_operand:BLK 0 "memory_operand" ""))
17659 (use (match_operand:BLK 1 "memory_operand" ""))
17660 (use (match_operand:DI 2 "nonmemory_operand" ""))
17661 (use (match_operand:DI 3 "const_int_operand" ""))
17662 (use (match_operand:SI 4 "const_int_operand" ""))
17663 (use (match_operand:SI 5 "const_int_operand" ""))]
17666 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17667 operands[4], operands[5]))
17673 ;; Most CPUs don't like single string operations
17674 ;; Handle this case here to simplify previous expander.
17676 (define_expand "strmov"
17677 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17678 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17679 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17680 (clobber (reg:CC FLAGS_REG))])
17681 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17682 (clobber (reg:CC FLAGS_REG))])]
17685 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17687 /* If .md ever supports :P for Pmode, these can be directly
17688 in the pattern above. */
17689 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17690 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17692 if (TARGET_SINGLE_STRINGOP || optimize_size)
17694 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17695 operands[2], operands[3],
17696 operands[5], operands[6]));
17700 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17703 (define_expand "strmov_singleop"
17704 [(parallel [(set (match_operand 1 "memory_operand" "")
17705 (match_operand 3 "memory_operand" ""))
17706 (set (match_operand 0 "register_operand" "")
17707 (match_operand 4 "" ""))
17708 (set (match_operand 2 "register_operand" "")
17709 (match_operand 5 "" ""))])]
17710 "TARGET_SINGLE_STRINGOP || optimize_size"
17713 (define_insn "*strmovdi_rex_1"
17714 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17715 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17716 (set (match_operand:DI 0 "register_operand" "=D")
17717 (plus:DI (match_dup 2)
17719 (set (match_operand:DI 1 "register_operand" "=S")
17720 (plus:DI (match_dup 3)
17722 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17724 [(set_attr "type" "str")
17725 (set_attr "mode" "DI")
17726 (set_attr "memory" "both")])
17728 (define_insn "*strmovsi_1"
17729 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17730 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17731 (set (match_operand:SI 0 "register_operand" "=D")
17732 (plus:SI (match_dup 2)
17734 (set (match_operand:SI 1 "register_operand" "=S")
17735 (plus:SI (match_dup 3)
17737 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17739 [(set_attr "type" "str")
17740 (set_attr "mode" "SI")
17741 (set_attr "memory" "both")])
17743 (define_insn "*strmovsi_rex_1"
17744 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17745 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17746 (set (match_operand:DI 0 "register_operand" "=D")
17747 (plus:DI (match_dup 2)
17749 (set (match_operand:DI 1 "register_operand" "=S")
17750 (plus:DI (match_dup 3)
17752 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17754 [(set_attr "type" "str")
17755 (set_attr "mode" "SI")
17756 (set_attr "memory" "both")])
17758 (define_insn "*strmovhi_1"
17759 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17760 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17761 (set (match_operand:SI 0 "register_operand" "=D")
17762 (plus:SI (match_dup 2)
17764 (set (match_operand:SI 1 "register_operand" "=S")
17765 (plus:SI (match_dup 3)
17767 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17769 [(set_attr "type" "str")
17770 (set_attr "memory" "both")
17771 (set_attr "mode" "HI")])
17773 (define_insn "*strmovhi_rex_1"
17774 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17775 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17776 (set (match_operand:DI 0 "register_operand" "=D")
17777 (plus:DI (match_dup 2)
17779 (set (match_operand:DI 1 "register_operand" "=S")
17780 (plus:DI (match_dup 3)
17782 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17784 [(set_attr "type" "str")
17785 (set_attr "memory" "both")
17786 (set_attr "mode" "HI")])
17788 (define_insn "*strmovqi_1"
17789 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17790 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17791 (set (match_operand:SI 0 "register_operand" "=D")
17792 (plus:SI (match_dup 2)
17794 (set (match_operand:SI 1 "register_operand" "=S")
17795 (plus:SI (match_dup 3)
17797 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17799 [(set_attr "type" "str")
17800 (set_attr "memory" "both")
17801 (set_attr "mode" "QI")])
17803 (define_insn "*strmovqi_rex_1"
17804 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17805 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17806 (set (match_operand:DI 0 "register_operand" "=D")
17807 (plus:DI (match_dup 2)
17809 (set (match_operand:DI 1 "register_operand" "=S")
17810 (plus:DI (match_dup 3)
17812 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17814 [(set_attr "type" "str")
17815 (set_attr "memory" "both")
17816 (set_attr "mode" "QI")])
17818 (define_expand "rep_mov"
17819 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17820 (set (match_operand 0 "register_operand" "")
17821 (match_operand 5 "" ""))
17822 (set (match_operand 2 "register_operand" "")
17823 (match_operand 6 "" ""))
17824 (set (match_operand 1 "memory_operand" "")
17825 (match_operand 3 "memory_operand" ""))
17826 (use (match_dup 4))])]
17830 (define_insn "*rep_movdi_rex64"
17831 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17832 (set (match_operand:DI 0 "register_operand" "=D")
17833 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17835 (match_operand:DI 3 "register_operand" "0")))
17836 (set (match_operand:DI 1 "register_operand" "=S")
17837 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17838 (match_operand:DI 4 "register_operand" "1")))
17839 (set (mem:BLK (match_dup 3))
17840 (mem:BLK (match_dup 4)))
17841 (use (match_dup 5))]
17843 "{rep\;movsq|rep movsq}"
17844 [(set_attr "type" "str")
17845 (set_attr "prefix_rep" "1")
17846 (set_attr "memory" "both")
17847 (set_attr "mode" "DI")])
17849 (define_insn "*rep_movsi"
17850 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17851 (set (match_operand:SI 0 "register_operand" "=D")
17852 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17854 (match_operand:SI 3 "register_operand" "0")))
17855 (set (match_operand:SI 1 "register_operand" "=S")
17856 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17857 (match_operand:SI 4 "register_operand" "1")))
17858 (set (mem:BLK (match_dup 3))
17859 (mem:BLK (match_dup 4)))
17860 (use (match_dup 5))]
17862 "{rep\;movsl|rep movsd}"
17863 [(set_attr "type" "str")
17864 (set_attr "prefix_rep" "1")
17865 (set_attr "memory" "both")
17866 (set_attr "mode" "SI")])
17868 (define_insn "*rep_movsi_rex64"
17869 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17870 (set (match_operand:DI 0 "register_operand" "=D")
17871 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17873 (match_operand:DI 3 "register_operand" "0")))
17874 (set (match_operand:DI 1 "register_operand" "=S")
17875 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17876 (match_operand:DI 4 "register_operand" "1")))
17877 (set (mem:BLK (match_dup 3))
17878 (mem:BLK (match_dup 4)))
17879 (use (match_dup 5))]
17881 "{rep\;movsl|rep movsd}"
17882 [(set_attr "type" "str")
17883 (set_attr "prefix_rep" "1")
17884 (set_attr "memory" "both")
17885 (set_attr "mode" "SI")])
17887 (define_insn "*rep_movqi"
17888 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17889 (set (match_operand:SI 0 "register_operand" "=D")
17890 (plus:SI (match_operand:SI 3 "register_operand" "0")
17891 (match_operand:SI 5 "register_operand" "2")))
17892 (set (match_operand:SI 1 "register_operand" "=S")
17893 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17894 (set (mem:BLK (match_dup 3))
17895 (mem:BLK (match_dup 4)))
17896 (use (match_dup 5))]
17898 "{rep\;movsb|rep movsb}"
17899 [(set_attr "type" "str")
17900 (set_attr "prefix_rep" "1")
17901 (set_attr "memory" "both")
17902 (set_attr "mode" "SI")])
17904 (define_insn "*rep_movqi_rex64"
17905 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17906 (set (match_operand:DI 0 "register_operand" "=D")
17907 (plus:DI (match_operand:DI 3 "register_operand" "0")
17908 (match_operand:DI 5 "register_operand" "2")))
17909 (set (match_operand:DI 1 "register_operand" "=S")
17910 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17911 (set (mem:BLK (match_dup 3))
17912 (mem:BLK (match_dup 4)))
17913 (use (match_dup 5))]
17915 "{rep\;movsb|rep movsb}"
17916 [(set_attr "type" "str")
17917 (set_attr "prefix_rep" "1")
17918 (set_attr "memory" "both")
17919 (set_attr "mode" "SI")])
17921 (define_expand "setmemsi"
17922 [(use (match_operand:BLK 0 "memory_operand" ""))
17923 (use (match_operand:SI 1 "nonmemory_operand" ""))
17924 (use (match_operand 2 "const_int_operand" ""))
17925 (use (match_operand 3 "const_int_operand" ""))
17926 (use (match_operand:SI 4 "const_int_operand" ""))
17927 (use (match_operand:SI 5 "const_int_operand" ""))]
17930 if (ix86_expand_setmem (operands[0], operands[1],
17931 operands[2], operands[3],
17932 operands[4], operands[5]))
17938 (define_expand "setmemdi"
17939 [(use (match_operand:BLK 0 "memory_operand" ""))
17940 (use (match_operand:DI 1 "nonmemory_operand" ""))
17941 (use (match_operand 2 "const_int_operand" ""))
17942 (use (match_operand 3 "const_int_operand" ""))
17943 (use (match_operand 4 "const_int_operand" ""))
17944 (use (match_operand 5 "const_int_operand" ""))]
17947 if (ix86_expand_setmem (operands[0], operands[1],
17948 operands[2], operands[3],
17949 operands[4], operands[5]))
17955 ;; Most CPUs don't like single string operations
17956 ;; Handle this case here to simplify previous expander.
17958 (define_expand "strset"
17959 [(set (match_operand 1 "memory_operand" "")
17960 (match_operand 2 "register_operand" ""))
17961 (parallel [(set (match_operand 0 "register_operand" "")
17963 (clobber (reg:CC FLAGS_REG))])]
17966 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17967 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17969 /* If .md ever supports :P for Pmode, this can be directly
17970 in the pattern above. */
17971 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17972 GEN_INT (GET_MODE_SIZE (GET_MODE
17974 if (TARGET_SINGLE_STRINGOP || optimize_size)
17976 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17982 (define_expand "strset_singleop"
17983 [(parallel [(set (match_operand 1 "memory_operand" "")
17984 (match_operand 2 "register_operand" ""))
17985 (set (match_operand 0 "register_operand" "")
17986 (match_operand 3 "" ""))])]
17987 "TARGET_SINGLE_STRINGOP || optimize_size"
17990 (define_insn "*strsetdi_rex_1"
17991 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17992 (match_operand:DI 2 "register_operand" "a"))
17993 (set (match_operand:DI 0 "register_operand" "=D")
17994 (plus:DI (match_dup 1)
17996 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
17998 [(set_attr "type" "str")
17999 (set_attr "memory" "store")
18000 (set_attr "mode" "DI")])
18002 (define_insn "*strsetsi_1"
18003 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18004 (match_operand:SI 2 "register_operand" "a"))
18005 (set (match_operand:SI 0 "register_operand" "=D")
18006 (plus:SI (match_dup 1)
18008 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18010 [(set_attr "type" "str")
18011 (set_attr "memory" "store")
18012 (set_attr "mode" "SI")])
18014 (define_insn "*strsetsi_rex_1"
18015 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18016 (match_operand:SI 2 "register_operand" "a"))
18017 (set (match_operand:DI 0 "register_operand" "=D")
18018 (plus:DI (match_dup 1)
18020 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18022 [(set_attr "type" "str")
18023 (set_attr "memory" "store")
18024 (set_attr "mode" "SI")])
18026 (define_insn "*strsethi_1"
18027 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18028 (match_operand:HI 2 "register_operand" "a"))
18029 (set (match_operand:SI 0 "register_operand" "=D")
18030 (plus:SI (match_dup 1)
18032 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18034 [(set_attr "type" "str")
18035 (set_attr "memory" "store")
18036 (set_attr "mode" "HI")])
18038 (define_insn "*strsethi_rex_1"
18039 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18040 (match_operand:HI 2 "register_operand" "a"))
18041 (set (match_operand:DI 0 "register_operand" "=D")
18042 (plus:DI (match_dup 1)
18044 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18046 [(set_attr "type" "str")
18047 (set_attr "memory" "store")
18048 (set_attr "mode" "HI")])
18050 (define_insn "*strsetqi_1"
18051 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18052 (match_operand:QI 2 "register_operand" "a"))
18053 (set (match_operand:SI 0 "register_operand" "=D")
18054 (plus:SI (match_dup 1)
18056 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18058 [(set_attr "type" "str")
18059 (set_attr "memory" "store")
18060 (set_attr "mode" "QI")])
18062 (define_insn "*strsetqi_rex_1"
18063 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18064 (match_operand:QI 2 "register_operand" "a"))
18065 (set (match_operand:DI 0 "register_operand" "=D")
18066 (plus:DI (match_dup 1)
18068 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18070 [(set_attr "type" "str")
18071 (set_attr "memory" "store")
18072 (set_attr "mode" "QI")])
18074 (define_expand "rep_stos"
18075 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18076 (set (match_operand 0 "register_operand" "")
18077 (match_operand 4 "" ""))
18078 (set (match_operand 2 "memory_operand" "") (const_int 0))
18079 (use (match_operand 3 "register_operand" ""))
18080 (use (match_dup 1))])]
18084 (define_insn "*rep_stosdi_rex64"
18085 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18086 (set (match_operand:DI 0 "register_operand" "=D")
18087 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18089 (match_operand:DI 3 "register_operand" "0")))
18090 (set (mem:BLK (match_dup 3))
18092 (use (match_operand:DI 2 "register_operand" "a"))
18093 (use (match_dup 4))]
18095 "{rep\;stosq|rep stosq}"
18096 [(set_attr "type" "str")
18097 (set_attr "prefix_rep" "1")
18098 (set_attr "memory" "store")
18099 (set_attr "mode" "DI")])
18101 (define_insn "*rep_stossi"
18102 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18103 (set (match_operand:SI 0 "register_operand" "=D")
18104 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18106 (match_operand:SI 3 "register_operand" "0")))
18107 (set (mem:BLK (match_dup 3))
18109 (use (match_operand:SI 2 "register_operand" "a"))
18110 (use (match_dup 4))]
18112 "{rep\;stosl|rep stosd}"
18113 [(set_attr "type" "str")
18114 (set_attr "prefix_rep" "1")
18115 (set_attr "memory" "store")
18116 (set_attr "mode" "SI")])
18118 (define_insn "*rep_stossi_rex64"
18119 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18120 (set (match_operand:DI 0 "register_operand" "=D")
18121 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18123 (match_operand:DI 3 "register_operand" "0")))
18124 (set (mem:BLK (match_dup 3))
18126 (use (match_operand:SI 2 "register_operand" "a"))
18127 (use (match_dup 4))]
18129 "{rep\;stosl|rep stosd}"
18130 [(set_attr "type" "str")
18131 (set_attr "prefix_rep" "1")
18132 (set_attr "memory" "store")
18133 (set_attr "mode" "SI")])
18135 (define_insn "*rep_stosqi"
18136 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18137 (set (match_operand:SI 0 "register_operand" "=D")
18138 (plus:SI (match_operand:SI 3 "register_operand" "0")
18139 (match_operand:SI 4 "register_operand" "1")))
18140 (set (mem:BLK (match_dup 3))
18142 (use (match_operand:QI 2 "register_operand" "a"))
18143 (use (match_dup 4))]
18145 "{rep\;stosb|rep stosb}"
18146 [(set_attr "type" "str")
18147 (set_attr "prefix_rep" "1")
18148 (set_attr "memory" "store")
18149 (set_attr "mode" "QI")])
18151 (define_insn "*rep_stosqi_rex64"
18152 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18153 (set (match_operand:DI 0 "register_operand" "=D")
18154 (plus:DI (match_operand:DI 3 "register_operand" "0")
18155 (match_operand:DI 4 "register_operand" "1")))
18156 (set (mem:BLK (match_dup 3))
18158 (use (match_operand:QI 2 "register_operand" "a"))
18159 (use (match_dup 4))]
18161 "{rep\;stosb|rep stosb}"
18162 [(set_attr "type" "str")
18163 (set_attr "prefix_rep" "1")
18164 (set_attr "memory" "store")
18165 (set_attr "mode" "QI")])
18167 (define_expand "cmpstrnsi"
18168 [(set (match_operand:SI 0 "register_operand" "")
18169 (compare:SI (match_operand:BLK 1 "general_operand" "")
18170 (match_operand:BLK 2 "general_operand" "")))
18171 (use (match_operand 3 "general_operand" ""))
18172 (use (match_operand 4 "immediate_operand" ""))]
18173 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18175 rtx addr1, addr2, out, outlow, count, countreg, align;
18177 /* Can't use this if the user has appropriated esi or edi. */
18178 if (global_regs[4] || global_regs[5])
18183 out = gen_reg_rtx (SImode);
18185 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18186 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18187 if (addr1 != XEXP (operands[1], 0))
18188 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18189 if (addr2 != XEXP (operands[2], 0))
18190 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18192 count = operands[3];
18193 countreg = ix86_zero_extend_to_Pmode (count);
18195 /* %%% Iff we are testing strict equality, we can use known alignment
18196 to good advantage. This may be possible with combine, particularly
18197 once cc0 is dead. */
18198 align = operands[4];
18200 if (CONST_INT_P (count))
18202 if (INTVAL (count) == 0)
18204 emit_move_insn (operands[0], const0_rtx);
18207 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18208 operands[1], operands[2]));
18213 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18215 emit_insn (gen_cmpsi_1 (countreg, countreg));
18216 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18217 operands[1], operands[2]));
18220 outlow = gen_lowpart (QImode, out);
18221 emit_insn (gen_cmpintqi (outlow));
18222 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18224 if (operands[0] != out)
18225 emit_move_insn (operands[0], out);
18230 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18232 (define_expand "cmpintqi"
18233 [(set (match_dup 1)
18234 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18236 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18237 (parallel [(set (match_operand:QI 0 "register_operand" "")
18238 (minus:QI (match_dup 1)
18240 (clobber (reg:CC FLAGS_REG))])]
18242 "operands[1] = gen_reg_rtx (QImode);
18243 operands[2] = gen_reg_rtx (QImode);")
18245 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18246 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18248 (define_expand "cmpstrnqi_nz_1"
18249 [(parallel [(set (reg:CC FLAGS_REG)
18250 (compare:CC (match_operand 4 "memory_operand" "")
18251 (match_operand 5 "memory_operand" "")))
18252 (use (match_operand 2 "register_operand" ""))
18253 (use (match_operand:SI 3 "immediate_operand" ""))
18254 (clobber (match_operand 0 "register_operand" ""))
18255 (clobber (match_operand 1 "register_operand" ""))
18256 (clobber (match_dup 2))])]
18260 (define_insn "*cmpstrnqi_nz_1"
18261 [(set (reg:CC FLAGS_REG)
18262 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18263 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18264 (use (match_operand:SI 6 "register_operand" "2"))
18265 (use (match_operand:SI 3 "immediate_operand" "i"))
18266 (clobber (match_operand:SI 0 "register_operand" "=S"))
18267 (clobber (match_operand:SI 1 "register_operand" "=D"))
18268 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18271 [(set_attr "type" "str")
18272 (set_attr "mode" "QI")
18273 (set_attr "prefix_rep" "1")])
18275 (define_insn "*cmpstrnqi_nz_rex_1"
18276 [(set (reg:CC FLAGS_REG)
18277 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18278 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18279 (use (match_operand:DI 6 "register_operand" "2"))
18280 (use (match_operand:SI 3 "immediate_operand" "i"))
18281 (clobber (match_operand:DI 0 "register_operand" "=S"))
18282 (clobber (match_operand:DI 1 "register_operand" "=D"))
18283 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18286 [(set_attr "type" "str")
18287 (set_attr "mode" "QI")
18288 (set_attr "prefix_rep" "1")])
18290 ;; The same, but the count is not known to not be zero.
18292 (define_expand "cmpstrnqi_1"
18293 [(parallel [(set (reg:CC FLAGS_REG)
18294 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18296 (compare:CC (match_operand 4 "memory_operand" "")
18297 (match_operand 5 "memory_operand" ""))
18299 (use (match_operand:SI 3 "immediate_operand" ""))
18300 (use (reg:CC FLAGS_REG))
18301 (clobber (match_operand 0 "register_operand" ""))
18302 (clobber (match_operand 1 "register_operand" ""))
18303 (clobber (match_dup 2))])]
18307 (define_insn "*cmpstrnqi_1"
18308 [(set (reg:CC FLAGS_REG)
18309 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18311 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18312 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18314 (use (match_operand:SI 3 "immediate_operand" "i"))
18315 (use (reg:CC FLAGS_REG))
18316 (clobber (match_operand:SI 0 "register_operand" "=S"))
18317 (clobber (match_operand:SI 1 "register_operand" "=D"))
18318 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18321 [(set_attr "type" "str")
18322 (set_attr "mode" "QI")
18323 (set_attr "prefix_rep" "1")])
18325 (define_insn "*cmpstrnqi_rex_1"
18326 [(set (reg:CC FLAGS_REG)
18327 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18329 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18330 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18332 (use (match_operand:SI 3 "immediate_operand" "i"))
18333 (use (reg:CC FLAGS_REG))
18334 (clobber (match_operand:DI 0 "register_operand" "=S"))
18335 (clobber (match_operand:DI 1 "register_operand" "=D"))
18336 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18339 [(set_attr "type" "str")
18340 (set_attr "mode" "QI")
18341 (set_attr "prefix_rep" "1")])
18343 (define_expand "strlensi"
18344 [(set (match_operand:SI 0 "register_operand" "")
18345 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18346 (match_operand:QI 2 "immediate_operand" "")
18347 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18350 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18356 (define_expand "strlendi"
18357 [(set (match_operand:DI 0 "register_operand" "")
18358 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18359 (match_operand:QI 2 "immediate_operand" "")
18360 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18363 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18369 (define_expand "strlenqi_1"
18370 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18371 (clobber (match_operand 1 "register_operand" ""))
18372 (clobber (reg:CC FLAGS_REG))])]
18376 (define_insn "*strlenqi_1"
18377 [(set (match_operand:SI 0 "register_operand" "=&c")
18378 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18379 (match_operand:QI 2 "register_operand" "a")
18380 (match_operand:SI 3 "immediate_operand" "i")
18381 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18382 (clobber (match_operand:SI 1 "register_operand" "=D"))
18383 (clobber (reg:CC FLAGS_REG))]
18386 [(set_attr "type" "str")
18387 (set_attr "mode" "QI")
18388 (set_attr "prefix_rep" "1")])
18390 (define_insn "*strlenqi_rex_1"
18391 [(set (match_operand:DI 0 "register_operand" "=&c")
18392 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18393 (match_operand:QI 2 "register_operand" "a")
18394 (match_operand:DI 3 "immediate_operand" "i")
18395 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18396 (clobber (match_operand:DI 1 "register_operand" "=D"))
18397 (clobber (reg:CC FLAGS_REG))]
18400 [(set_attr "type" "str")
18401 (set_attr "mode" "QI")
18402 (set_attr "prefix_rep" "1")])
18404 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18405 ;; handled in combine, but it is not currently up to the task.
18406 ;; When used for their truth value, the cmpstrn* expanders generate
18415 ;; The intermediate three instructions are unnecessary.
18417 ;; This one handles cmpstrn*_nz_1...
18420 (set (reg:CC FLAGS_REG)
18421 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18422 (mem:BLK (match_operand 5 "register_operand" ""))))
18423 (use (match_operand 6 "register_operand" ""))
18424 (use (match_operand:SI 3 "immediate_operand" ""))
18425 (clobber (match_operand 0 "register_operand" ""))
18426 (clobber (match_operand 1 "register_operand" ""))
18427 (clobber (match_operand 2 "register_operand" ""))])
18428 (set (match_operand:QI 7 "register_operand" "")
18429 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18430 (set (match_operand:QI 8 "register_operand" "")
18431 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18432 (set (reg FLAGS_REG)
18433 (compare (match_dup 7) (match_dup 8)))
18435 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18437 (set (reg:CC FLAGS_REG)
18438 (compare:CC (mem:BLK (match_dup 4))
18439 (mem:BLK (match_dup 5))))
18440 (use (match_dup 6))
18441 (use (match_dup 3))
18442 (clobber (match_dup 0))
18443 (clobber (match_dup 1))
18444 (clobber (match_dup 2))])]
18447 ;; ...and this one handles cmpstrn*_1.
18450 (set (reg:CC FLAGS_REG)
18451 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18453 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18454 (mem:BLK (match_operand 5 "register_operand" "")))
18456 (use (match_operand:SI 3 "immediate_operand" ""))
18457 (use (reg:CC FLAGS_REG))
18458 (clobber (match_operand 0 "register_operand" ""))
18459 (clobber (match_operand 1 "register_operand" ""))
18460 (clobber (match_operand 2 "register_operand" ""))])
18461 (set (match_operand:QI 7 "register_operand" "")
18462 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18463 (set (match_operand:QI 8 "register_operand" "")
18464 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18465 (set (reg FLAGS_REG)
18466 (compare (match_dup 7) (match_dup 8)))
18468 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18470 (set (reg:CC FLAGS_REG)
18471 (if_then_else:CC (ne (match_dup 6)
18473 (compare:CC (mem:BLK (match_dup 4))
18474 (mem:BLK (match_dup 5)))
18476 (use (match_dup 3))
18477 (use (reg:CC FLAGS_REG))
18478 (clobber (match_dup 0))
18479 (clobber (match_dup 1))
18480 (clobber (match_dup 2))])]
18485 ;; Conditional move instructions.
18487 (define_expand "movdicc"
18488 [(set (match_operand:DI 0 "register_operand" "")
18489 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18490 (match_operand:DI 2 "general_operand" "")
18491 (match_operand:DI 3 "general_operand" "")))]
18493 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18495 (define_insn "x86_movdicc_0_m1_rex64"
18496 [(set (match_operand:DI 0 "register_operand" "=r")
18497 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18500 (clobber (reg:CC FLAGS_REG))]
18503 ; Since we don't have the proper number of operands for an alu insn,
18504 ; fill in all the blanks.
18505 [(set_attr "type" "alu")
18506 (set_attr "pent_pair" "pu")
18507 (set_attr "memory" "none")
18508 (set_attr "imm_disp" "false")
18509 (set_attr "mode" "DI")
18510 (set_attr "length_immediate" "0")])
18512 (define_insn "*movdicc_c_rex64"
18513 [(set (match_operand:DI 0 "register_operand" "=r,r")
18514 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18515 [(reg FLAGS_REG) (const_int 0)])
18516 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
18517 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
18518 "TARGET_64BIT && TARGET_CMOVE
18519 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18521 cmov%O2%C1\t{%2, %0|%0, %2}
18522 cmov%O2%c1\t{%3, %0|%0, %3}"
18523 [(set_attr "type" "icmov")
18524 (set_attr "mode" "DI")])
18526 (define_expand "movsicc"
18527 [(set (match_operand:SI 0 "register_operand" "")
18528 (if_then_else:SI (match_operand 1 "comparison_operator" "")
18529 (match_operand:SI 2 "general_operand" "")
18530 (match_operand:SI 3 "general_operand" "")))]
18532 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18534 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18535 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18536 ;; So just document what we're doing explicitly.
18538 (define_insn "x86_movsicc_0_m1"
18539 [(set (match_operand:SI 0 "register_operand" "=r")
18540 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
18543 (clobber (reg:CC FLAGS_REG))]
18546 ; Since we don't have the proper number of operands for an alu insn,
18547 ; fill in all the blanks.
18548 [(set_attr "type" "alu")
18549 (set_attr "pent_pair" "pu")
18550 (set_attr "memory" "none")
18551 (set_attr "imm_disp" "false")
18552 (set_attr "mode" "SI")
18553 (set_attr "length_immediate" "0")])
18555 (define_insn "*movsicc_noc"
18556 [(set (match_operand:SI 0 "register_operand" "=r,r")
18557 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
18558 [(reg FLAGS_REG) (const_int 0)])
18559 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
18560 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
18562 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18564 cmov%O2%C1\t{%2, %0|%0, %2}
18565 cmov%O2%c1\t{%3, %0|%0, %3}"
18566 [(set_attr "type" "icmov")
18567 (set_attr "mode" "SI")])
18569 (define_expand "movhicc"
18570 [(set (match_operand:HI 0 "register_operand" "")
18571 (if_then_else:HI (match_operand 1 "comparison_operator" "")
18572 (match_operand:HI 2 "general_operand" "")
18573 (match_operand:HI 3 "general_operand" "")))]
18574 "TARGET_HIMODE_MATH"
18575 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18577 (define_insn "*movhicc_noc"
18578 [(set (match_operand:HI 0 "register_operand" "=r,r")
18579 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
18580 [(reg FLAGS_REG) (const_int 0)])
18581 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
18582 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
18584 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18586 cmov%O2%C1\t{%2, %0|%0, %2}
18587 cmov%O2%c1\t{%3, %0|%0, %3}"
18588 [(set_attr "type" "icmov")
18589 (set_attr "mode" "HI")])
18591 (define_expand "movqicc"
18592 [(set (match_operand:QI 0 "register_operand" "")
18593 (if_then_else:QI (match_operand 1 "comparison_operator" "")
18594 (match_operand:QI 2 "general_operand" "")
18595 (match_operand:QI 3 "general_operand" "")))]
18596 "TARGET_QIMODE_MATH"
18597 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18599 (define_insn_and_split "*movqicc_noc"
18600 [(set (match_operand:QI 0 "register_operand" "=r,r")
18601 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18602 [(match_operand 4 "flags_reg_operand" "")
18604 (match_operand:QI 2 "register_operand" "r,0")
18605 (match_operand:QI 3 "register_operand" "0,r")))]
18606 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18608 "&& reload_completed"
18609 [(set (match_dup 0)
18610 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18613 "operands[0] = gen_lowpart (SImode, operands[0]);
18614 operands[2] = gen_lowpart (SImode, operands[2]);
18615 operands[3] = gen_lowpart (SImode, operands[3]);"
18616 [(set_attr "type" "icmov")
18617 (set_attr "mode" "SI")])
18619 (define_expand "movsfcc"
18620 [(set (match_operand:SF 0 "register_operand" "")
18621 (if_then_else:SF (match_operand 1 "comparison_operator" "")
18622 (match_operand:SF 2 "register_operand" "")
18623 (match_operand:SF 3 "register_operand" "")))]
18624 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
18625 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18627 (define_insn "*movsfcc_1_387"
18628 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18629 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18630 [(reg FLAGS_REG) (const_int 0)])
18631 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18632 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18633 "TARGET_80387 && TARGET_CMOVE
18634 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18636 fcmov%F1\t{%2, %0|%0, %2}
18637 fcmov%f1\t{%3, %0|%0, %3}
18638 cmov%O2%C1\t{%2, %0|%0, %2}
18639 cmov%O2%c1\t{%3, %0|%0, %3}"
18640 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18641 (set_attr "mode" "SF,SF,SI,SI")])
18643 (define_expand "movdfcc"
18644 [(set (match_operand:DF 0 "register_operand" "")
18645 (if_then_else:DF (match_operand 1 "comparison_operator" "")
18646 (match_operand:DF 2 "register_operand" "")
18647 (match_operand:DF 3 "register_operand" "")))]
18648 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
18649 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18651 (define_insn "*movdfcc_1"
18652 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18653 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18654 [(reg FLAGS_REG) (const_int 0)])
18655 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18656 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18657 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18658 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18660 fcmov%F1\t{%2, %0|%0, %2}
18661 fcmov%f1\t{%3, %0|%0, %3}
18664 [(set_attr "type" "fcmov,fcmov,multi,multi")
18665 (set_attr "mode" "DF")])
18667 (define_insn "*movdfcc_1_rex64"
18668 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18669 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18670 [(reg FLAGS_REG) (const_int 0)])
18671 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18672 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18673 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18674 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18676 fcmov%F1\t{%2, %0|%0, %2}
18677 fcmov%f1\t{%3, %0|%0, %3}
18678 cmov%O2%C1\t{%2, %0|%0, %2}
18679 cmov%O2%c1\t{%3, %0|%0, %3}"
18680 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18681 (set_attr "mode" "DF")])
18684 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18685 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18686 [(match_operand 4 "flags_reg_operand" "")
18688 (match_operand:DF 2 "nonimmediate_operand" "")
18689 (match_operand:DF 3 "nonimmediate_operand" "")))]
18690 "!TARGET_64BIT && reload_completed"
18691 [(set (match_dup 2)
18692 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18696 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18699 "split_di (operands+2, 1, operands+5, operands+6);
18700 split_di (operands+3, 1, operands+7, operands+8);
18701 split_di (operands, 1, operands+2, operands+3);")
18703 (define_expand "movxfcc"
18704 [(set (match_operand:XF 0 "register_operand" "")
18705 (if_then_else:XF (match_operand 1 "comparison_operator" "")
18706 (match_operand:XF 2 "register_operand" "")
18707 (match_operand:XF 3 "register_operand" "")))]
18708 "TARGET_80387 && TARGET_CMOVE"
18709 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
18711 (define_insn "*movxfcc_1"
18712 [(set (match_operand:XF 0 "register_operand" "=f,f")
18713 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18714 [(reg FLAGS_REG) (const_int 0)])
18715 (match_operand:XF 2 "register_operand" "f,0")
18716 (match_operand:XF 3 "register_operand" "0,f")))]
18717 "TARGET_80387 && TARGET_CMOVE"
18719 fcmov%F1\t{%2, %0|%0, %2}
18720 fcmov%f1\t{%3, %0|%0, %3}"
18721 [(set_attr "type" "fcmov")
18722 (set_attr "mode" "XF")])
18724 ;; These versions of the min/max patterns are intentionally ignorant of
18725 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18726 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18727 ;; are undefined in this condition, we're certain this is correct.
18729 (define_insn "sminsf3"
18730 [(set (match_operand:SF 0 "register_operand" "=x")
18731 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18732 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18734 "minss\t{%2, %0|%0, %2}"
18735 [(set_attr "type" "sseadd")
18736 (set_attr "mode" "SF")])
18738 (define_insn "smaxsf3"
18739 [(set (match_operand:SF 0 "register_operand" "=x")
18740 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
18741 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
18743 "maxss\t{%2, %0|%0, %2}"
18744 [(set_attr "type" "sseadd")
18745 (set_attr "mode" "SF")])
18747 (define_insn "smindf3"
18748 [(set (match_operand:DF 0 "register_operand" "=x")
18749 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18750 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18751 "TARGET_SSE2 && TARGET_SSE_MATH"
18752 "minsd\t{%2, %0|%0, %2}"
18753 [(set_attr "type" "sseadd")
18754 (set_attr "mode" "DF")])
18756 (define_insn "smaxdf3"
18757 [(set (match_operand:DF 0 "register_operand" "=x")
18758 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
18759 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
18760 "TARGET_SSE2 && TARGET_SSE_MATH"
18761 "maxsd\t{%2, %0|%0, %2}"
18762 [(set_attr "type" "sseadd")
18763 (set_attr "mode" "DF")])
18765 ;; These versions of the min/max patterns implement exactly the operations
18766 ;; min = (op1 < op2 ? op1 : op2)
18767 ;; max = (!(op1 < op2) ? op1 : op2)
18768 ;; Their operands are not commutative, and thus they may be used in the
18769 ;; presence of -0.0 and NaN.
18771 (define_insn "*ieee_sminsf3"
18772 [(set (match_operand:SF 0 "register_operand" "=x")
18773 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18774 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18777 "minss\t{%2, %0|%0, %2}"
18778 [(set_attr "type" "sseadd")
18779 (set_attr "mode" "SF")])
18781 (define_insn "*ieee_smaxsf3"
18782 [(set (match_operand:SF 0 "register_operand" "=x")
18783 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
18784 (match_operand:SF 2 "nonimmediate_operand" "xm")]
18787 "maxss\t{%2, %0|%0, %2}"
18788 [(set_attr "type" "sseadd")
18789 (set_attr "mode" "SF")])
18791 (define_insn "*ieee_smindf3"
18792 [(set (match_operand:DF 0 "register_operand" "=x")
18793 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18794 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18796 "TARGET_SSE2 && TARGET_SSE_MATH"
18797 "minsd\t{%2, %0|%0, %2}"
18798 [(set_attr "type" "sseadd")
18799 (set_attr "mode" "DF")])
18801 (define_insn "*ieee_smaxdf3"
18802 [(set (match_operand:DF 0 "register_operand" "=x")
18803 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
18804 (match_operand:DF 2 "nonimmediate_operand" "xm")]
18806 "TARGET_SSE2 && TARGET_SSE_MATH"
18807 "maxsd\t{%2, %0|%0, %2}"
18808 [(set_attr "type" "sseadd")
18809 (set_attr "mode" "DF")])
18811 ;; Make two stack loads independent:
18813 ;; fld %st(0) -> fld bb
18814 ;; fmul bb fmul %st(1), %st
18816 ;; Actually we only match the last two instructions for simplicity.
18818 [(set (match_operand 0 "fp_register_operand" "")
18819 (match_operand 1 "fp_register_operand" ""))
18821 (match_operator 2 "binary_fp_operator"
18823 (match_operand 3 "memory_operand" "")]))]
18824 "REGNO (operands[0]) != REGNO (operands[1])"
18825 [(set (match_dup 0) (match_dup 3))
18826 (set (match_dup 0) (match_dup 4))]
18828 ;; The % modifier is not operational anymore in peephole2's, so we have to
18829 ;; swap the operands manually in the case of addition and multiplication.
18830 "if (COMMUTATIVE_ARITH_P (operands[2]))
18831 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18832 operands[0], operands[1]);
18834 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18835 operands[1], operands[0]);")
18837 ;; Conditional addition patterns
18838 (define_expand "addqicc"
18839 [(match_operand:QI 0 "register_operand" "")
18840 (match_operand 1 "comparison_operator" "")
18841 (match_operand:QI 2 "register_operand" "")
18842 (match_operand:QI 3 "const_int_operand" "")]
18844 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18846 (define_expand "addhicc"
18847 [(match_operand:HI 0 "register_operand" "")
18848 (match_operand 1 "comparison_operator" "")
18849 (match_operand:HI 2 "register_operand" "")
18850 (match_operand:HI 3 "const_int_operand" "")]
18852 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18854 (define_expand "addsicc"
18855 [(match_operand:SI 0 "register_operand" "")
18856 (match_operand 1 "comparison_operator" "")
18857 (match_operand:SI 2 "register_operand" "")
18858 (match_operand:SI 3 "const_int_operand" "")]
18860 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18862 (define_expand "adddicc"
18863 [(match_operand:DI 0 "register_operand" "")
18864 (match_operand 1 "comparison_operator" "")
18865 (match_operand:DI 2 "register_operand" "")
18866 (match_operand:DI 3 "const_int_operand" "")]
18868 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
18871 ;; Misc patterns (?)
18873 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18874 ;; Otherwise there will be nothing to keep
18876 ;; [(set (reg ebp) (reg esp))]
18877 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18878 ;; (clobber (eflags)]
18879 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18881 ;; in proper program order.
18882 (define_insn "pro_epilogue_adjust_stack_1"
18883 [(set (match_operand:SI 0 "register_operand" "=r,r")
18884 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18885 (match_operand:SI 2 "immediate_operand" "i,i")))
18886 (clobber (reg:CC FLAGS_REG))
18887 (clobber (mem:BLK (scratch)))]
18890 switch (get_attr_type (insn))
18893 return "mov{l}\t{%1, %0|%0, %1}";
18896 if (CONST_INT_P (operands[2])
18897 && (INTVAL (operands[2]) == 128
18898 || (INTVAL (operands[2]) < 0
18899 && INTVAL (operands[2]) != -128)))
18901 operands[2] = GEN_INT (-INTVAL (operands[2]));
18902 return "sub{l}\t{%2, %0|%0, %2}";
18904 return "add{l}\t{%2, %0|%0, %2}";
18907 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18908 return "lea{l}\t{%a2, %0|%0, %a2}";
18911 gcc_unreachable ();
18914 [(set (attr "type")
18915 (cond [(eq_attr "alternative" "0")
18916 (const_string "alu")
18917 (match_operand:SI 2 "const0_operand" "")
18918 (const_string "imov")
18920 (const_string "lea")))
18921 (set_attr "mode" "SI")])
18923 (define_insn "pro_epilogue_adjust_stack_rex64"
18924 [(set (match_operand:DI 0 "register_operand" "=r,r")
18925 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18926 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18927 (clobber (reg:CC FLAGS_REG))
18928 (clobber (mem:BLK (scratch)))]
18931 switch (get_attr_type (insn))
18934 return "mov{q}\t{%1, %0|%0, %1}";
18937 if (CONST_INT_P (operands[2])
18938 /* Avoid overflows. */
18939 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18940 && (INTVAL (operands[2]) == 128
18941 || (INTVAL (operands[2]) < 0
18942 && INTVAL (operands[2]) != -128)))
18944 operands[2] = GEN_INT (-INTVAL (operands[2]));
18945 return "sub{q}\t{%2, %0|%0, %2}";
18947 return "add{q}\t{%2, %0|%0, %2}";
18950 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18951 return "lea{q}\t{%a2, %0|%0, %a2}";
18954 gcc_unreachable ();
18957 [(set (attr "type")
18958 (cond [(eq_attr "alternative" "0")
18959 (const_string "alu")
18960 (match_operand:DI 2 "const0_operand" "")
18961 (const_string "imov")
18963 (const_string "lea")))
18964 (set_attr "mode" "DI")])
18966 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18967 [(set (match_operand:DI 0 "register_operand" "=r,r")
18968 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18969 (match_operand:DI 3 "immediate_operand" "i,i")))
18970 (use (match_operand:DI 2 "register_operand" "r,r"))
18971 (clobber (reg:CC FLAGS_REG))
18972 (clobber (mem:BLK (scratch)))]
18975 switch (get_attr_type (insn))
18978 return "add{q}\t{%2, %0|%0, %2}";
18981 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18982 return "lea{q}\t{%a2, %0|%0, %a2}";
18985 gcc_unreachable ();
18988 [(set_attr "type" "alu,lea")
18989 (set_attr "mode" "DI")])
18991 (define_expand "allocate_stack_worker"
18992 [(match_operand:SI 0 "register_operand" "")]
18993 "TARGET_STACK_PROBE"
18995 if (reload_completed)
18998 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19000 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19005 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19007 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19012 (define_insn "allocate_stack_worker_1"
19013 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19014 UNSPECV_STACK_PROBE)
19015 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19016 (clobber (match_scratch:SI 1 "=0"))
19017 (clobber (reg:CC FLAGS_REG))]
19018 "!TARGET_64BIT && TARGET_STACK_PROBE"
19020 [(set_attr "type" "multi")
19021 (set_attr "length" "5")])
19023 (define_expand "allocate_stack_worker_postreload"
19024 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19025 UNSPECV_STACK_PROBE)
19026 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19027 (clobber (match_dup 0))
19028 (clobber (reg:CC FLAGS_REG))])]
19032 (define_insn "allocate_stack_worker_rex64"
19033 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19034 UNSPECV_STACK_PROBE)
19035 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19036 (clobber (match_scratch:DI 1 "=0"))
19037 (clobber (reg:CC FLAGS_REG))]
19038 "TARGET_64BIT && TARGET_STACK_PROBE"
19040 [(set_attr "type" "multi")
19041 (set_attr "length" "5")])
19043 (define_expand "allocate_stack_worker_rex64_postreload"
19044 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19045 UNSPECV_STACK_PROBE)
19046 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19047 (clobber (match_dup 0))
19048 (clobber (reg:CC FLAGS_REG))])]
19052 (define_expand "allocate_stack"
19053 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19054 (minus:SI (reg:SI SP_REG)
19055 (match_operand:SI 1 "general_operand" "")))
19056 (clobber (reg:CC FLAGS_REG))])
19057 (parallel [(set (reg:SI SP_REG)
19058 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19059 (clobber (reg:CC FLAGS_REG))])]
19060 "TARGET_STACK_PROBE"
19062 #ifdef CHECK_STACK_LIMIT
19063 if (CONST_INT_P (operands[1])
19064 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19065 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19069 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19072 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19076 (define_expand "builtin_setjmp_receiver"
19077 [(label_ref (match_operand 0 "" ""))]
19078 "!TARGET_64BIT && flag_pic"
19083 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19084 rtx label_rtx = gen_label_rtx ();
19085 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19086 xops[0] = xops[1] = picreg;
19087 xops[2] = gen_rtx_CONST (SImode,
19088 gen_rtx_MINUS (SImode,
19089 gen_rtx_LABEL_REF (SImode, label_rtx),
19090 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19091 ix86_expand_binary_operator (MINUS, SImode, xops);
19094 emit_insn (gen_set_got (pic_offset_table_rtx));
19098 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19101 [(set (match_operand 0 "register_operand" "")
19102 (match_operator 3 "promotable_binary_operator"
19103 [(match_operand 1 "register_operand" "")
19104 (match_operand 2 "aligned_operand" "")]))
19105 (clobber (reg:CC FLAGS_REG))]
19106 "! TARGET_PARTIAL_REG_STALL && reload_completed
19107 && ((GET_MODE (operands[0]) == HImode
19108 && ((!optimize_size && !TARGET_FAST_PREFIX)
19109 /* ??? next two lines just !satisfies_constraint_K (...) */
19110 || !CONST_INT_P (operands[2])
19111 || satisfies_constraint_K (operands[2])))
19112 || (GET_MODE (operands[0]) == QImode
19113 && (TARGET_PROMOTE_QImode || optimize_size)))"
19114 [(parallel [(set (match_dup 0)
19115 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19116 (clobber (reg:CC FLAGS_REG))])]
19117 "operands[0] = gen_lowpart (SImode, operands[0]);
19118 operands[1] = gen_lowpart (SImode, operands[1]);
19119 if (GET_CODE (operands[3]) != ASHIFT)
19120 operands[2] = gen_lowpart (SImode, operands[2]);
19121 PUT_MODE (operands[3], SImode);")
19123 ; Promote the QImode tests, as i386 has encoding of the AND
19124 ; instruction with 32-bit sign-extended immediate and thus the
19125 ; instruction size is unchanged, except in the %eax case for
19126 ; which it is increased by one byte, hence the ! optimize_size.
19128 [(set (match_operand 0 "flags_reg_operand" "")
19129 (match_operator 2 "compare_operator"
19130 [(and (match_operand 3 "aligned_operand" "")
19131 (match_operand 4 "const_int_operand" ""))
19133 (set (match_operand 1 "register_operand" "")
19134 (and (match_dup 3) (match_dup 4)))]
19135 "! TARGET_PARTIAL_REG_STALL && reload_completed
19136 /* Ensure that the operand will remain sign-extended immediate. */
19137 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19139 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19140 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19141 [(parallel [(set (match_dup 0)
19142 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19145 (and:SI (match_dup 3) (match_dup 4)))])]
19148 = gen_int_mode (INTVAL (operands[4])
19149 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19150 operands[1] = gen_lowpart (SImode, operands[1]);
19151 operands[3] = gen_lowpart (SImode, operands[3]);
19154 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19155 ; the TEST instruction with 32-bit sign-extended immediate and thus
19156 ; the instruction size would at least double, which is not what we
19157 ; want even with ! optimize_size.
19159 [(set (match_operand 0 "flags_reg_operand" "")
19160 (match_operator 1 "compare_operator"
19161 [(and (match_operand:HI 2 "aligned_operand" "")
19162 (match_operand:HI 3 "const_int_operand" ""))
19164 "! TARGET_PARTIAL_REG_STALL && reload_completed
19165 /* Ensure that the operand will remain sign-extended immediate. */
19166 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19167 && ! TARGET_FAST_PREFIX
19168 && ! optimize_size"
19169 [(set (match_dup 0)
19170 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19174 = gen_int_mode (INTVAL (operands[3])
19175 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19176 operands[2] = gen_lowpart (SImode, operands[2]);
19180 [(set (match_operand 0 "register_operand" "")
19181 (neg (match_operand 1 "register_operand" "")))
19182 (clobber (reg:CC FLAGS_REG))]
19183 "! TARGET_PARTIAL_REG_STALL && reload_completed
19184 && (GET_MODE (operands[0]) == HImode
19185 || (GET_MODE (operands[0]) == QImode
19186 && (TARGET_PROMOTE_QImode || optimize_size)))"
19187 [(parallel [(set (match_dup 0)
19188 (neg:SI (match_dup 1)))
19189 (clobber (reg:CC FLAGS_REG))])]
19190 "operands[0] = gen_lowpart (SImode, operands[0]);
19191 operands[1] = gen_lowpart (SImode, operands[1]);")
19194 [(set (match_operand 0 "register_operand" "")
19195 (not (match_operand 1 "register_operand" "")))]
19196 "! TARGET_PARTIAL_REG_STALL && reload_completed
19197 && (GET_MODE (operands[0]) == HImode
19198 || (GET_MODE (operands[0]) == QImode
19199 && (TARGET_PROMOTE_QImode || optimize_size)))"
19200 [(set (match_dup 0)
19201 (not:SI (match_dup 1)))]
19202 "operands[0] = gen_lowpart (SImode, operands[0]);
19203 operands[1] = gen_lowpart (SImode, operands[1]);")
19206 [(set (match_operand 0 "register_operand" "")
19207 (if_then_else (match_operator 1 "comparison_operator"
19208 [(reg FLAGS_REG) (const_int 0)])
19209 (match_operand 2 "register_operand" "")
19210 (match_operand 3 "register_operand" "")))]
19211 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19212 && (GET_MODE (operands[0]) == HImode
19213 || (GET_MODE (operands[0]) == QImode
19214 && (TARGET_PROMOTE_QImode || optimize_size)))"
19215 [(set (match_dup 0)
19216 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19217 "operands[0] = gen_lowpart (SImode, operands[0]);
19218 operands[2] = gen_lowpart (SImode, operands[2]);
19219 operands[3] = gen_lowpart (SImode, operands[3]);")
19222 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19223 ;; transform a complex memory operation into two memory to register operations.
19225 ;; Don't push memory operands
19227 [(set (match_operand:SI 0 "push_operand" "")
19228 (match_operand:SI 1 "memory_operand" ""))
19229 (match_scratch:SI 2 "r")]
19230 "!optimize_size && !TARGET_PUSH_MEMORY
19231 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19232 [(set (match_dup 2) (match_dup 1))
19233 (set (match_dup 0) (match_dup 2))]
19237 [(set (match_operand:DI 0 "push_operand" "")
19238 (match_operand:DI 1 "memory_operand" ""))
19239 (match_scratch:DI 2 "r")]
19240 "!optimize_size && !TARGET_PUSH_MEMORY
19241 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19242 [(set (match_dup 2) (match_dup 1))
19243 (set (match_dup 0) (match_dup 2))]
19246 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19249 [(set (match_operand:SF 0 "push_operand" "")
19250 (match_operand:SF 1 "memory_operand" ""))
19251 (match_scratch:SF 2 "r")]
19252 "!optimize_size && !TARGET_PUSH_MEMORY
19253 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19254 [(set (match_dup 2) (match_dup 1))
19255 (set (match_dup 0) (match_dup 2))]
19259 [(set (match_operand:HI 0 "push_operand" "")
19260 (match_operand:HI 1 "memory_operand" ""))
19261 (match_scratch:HI 2 "r")]
19262 "!optimize_size && !TARGET_PUSH_MEMORY
19263 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19264 [(set (match_dup 2) (match_dup 1))
19265 (set (match_dup 0) (match_dup 2))]
19269 [(set (match_operand:QI 0 "push_operand" "")
19270 (match_operand:QI 1 "memory_operand" ""))
19271 (match_scratch:QI 2 "q")]
19272 "!optimize_size && !TARGET_PUSH_MEMORY
19273 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19274 [(set (match_dup 2) (match_dup 1))
19275 (set (match_dup 0) (match_dup 2))]
19278 ;; Don't move an immediate directly to memory when the instruction
19281 [(match_scratch:SI 1 "r")
19282 (set (match_operand:SI 0 "memory_operand" "")
19285 && ! TARGET_USE_MOV0
19286 && TARGET_SPLIT_LONG_MOVES
19287 && get_attr_length (insn) >= ix86_cost->large_insn
19288 && peep2_regno_dead_p (0, FLAGS_REG)"
19289 [(parallel [(set (match_dup 1) (const_int 0))
19290 (clobber (reg:CC FLAGS_REG))])
19291 (set (match_dup 0) (match_dup 1))]
19295 [(match_scratch:HI 1 "r")
19296 (set (match_operand:HI 0 "memory_operand" "")
19299 && ! TARGET_USE_MOV0
19300 && TARGET_SPLIT_LONG_MOVES
19301 && get_attr_length (insn) >= ix86_cost->large_insn
19302 && peep2_regno_dead_p (0, FLAGS_REG)"
19303 [(parallel [(set (match_dup 2) (const_int 0))
19304 (clobber (reg:CC FLAGS_REG))])
19305 (set (match_dup 0) (match_dup 1))]
19306 "operands[2] = gen_lowpart (SImode, operands[1]);")
19309 [(match_scratch:QI 1 "q")
19310 (set (match_operand:QI 0 "memory_operand" "")
19313 && ! TARGET_USE_MOV0
19314 && TARGET_SPLIT_LONG_MOVES
19315 && get_attr_length (insn) >= ix86_cost->large_insn
19316 && peep2_regno_dead_p (0, FLAGS_REG)"
19317 [(parallel [(set (match_dup 2) (const_int 0))
19318 (clobber (reg:CC FLAGS_REG))])
19319 (set (match_dup 0) (match_dup 1))]
19320 "operands[2] = gen_lowpart (SImode, operands[1]);")
19323 [(match_scratch:SI 2 "r")
19324 (set (match_operand:SI 0 "memory_operand" "")
19325 (match_operand:SI 1 "immediate_operand" ""))]
19327 && get_attr_length (insn) >= ix86_cost->large_insn
19328 && TARGET_SPLIT_LONG_MOVES"
19329 [(set (match_dup 2) (match_dup 1))
19330 (set (match_dup 0) (match_dup 2))]
19334 [(match_scratch:HI 2 "r")
19335 (set (match_operand:HI 0 "memory_operand" "")
19336 (match_operand:HI 1 "immediate_operand" ""))]
19337 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19338 && TARGET_SPLIT_LONG_MOVES"
19339 [(set (match_dup 2) (match_dup 1))
19340 (set (match_dup 0) (match_dup 2))]
19344 [(match_scratch:QI 2 "q")
19345 (set (match_operand:QI 0 "memory_operand" "")
19346 (match_operand:QI 1 "immediate_operand" ""))]
19347 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19348 && TARGET_SPLIT_LONG_MOVES"
19349 [(set (match_dup 2) (match_dup 1))
19350 (set (match_dup 0) (match_dup 2))]
19353 ;; Don't compare memory with zero, load and use a test instead.
19355 [(set (match_operand 0 "flags_reg_operand" "")
19356 (match_operator 1 "compare_operator"
19357 [(match_operand:SI 2 "memory_operand" "")
19359 (match_scratch:SI 3 "r")]
19360 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19361 [(set (match_dup 3) (match_dup 2))
19362 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19365 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19366 ;; Don't split NOTs with a displacement operand, because resulting XOR
19367 ;; will not be pairable anyway.
19369 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19370 ;; represented using a modRM byte. The XOR replacement is long decoded,
19371 ;; so this split helps here as well.
19373 ;; Note: Can't do this as a regular split because we can't get proper
19374 ;; lifetime information then.
19377 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19378 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19380 && peep2_regno_dead_p (0, FLAGS_REG)
19381 && ((TARGET_PENTIUM
19382 && (!MEM_P (operands[0])
19383 || !memory_displacement_operand (operands[0], SImode)))
19384 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19385 [(parallel [(set (match_dup 0)
19386 (xor:SI (match_dup 1) (const_int -1)))
19387 (clobber (reg:CC FLAGS_REG))])]
19391 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19392 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19394 && peep2_regno_dead_p (0, FLAGS_REG)
19395 && ((TARGET_PENTIUM
19396 && (!MEM_P (operands[0])
19397 || !memory_displacement_operand (operands[0], HImode)))
19398 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19399 [(parallel [(set (match_dup 0)
19400 (xor:HI (match_dup 1) (const_int -1)))
19401 (clobber (reg:CC FLAGS_REG))])]
19405 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19406 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19408 && peep2_regno_dead_p (0, FLAGS_REG)
19409 && ((TARGET_PENTIUM
19410 && (!MEM_P (operands[0])
19411 || !memory_displacement_operand (operands[0], QImode)))
19412 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19413 [(parallel [(set (match_dup 0)
19414 (xor:QI (match_dup 1) (const_int -1)))
19415 (clobber (reg:CC FLAGS_REG))])]
19418 ;; Non pairable "test imm, reg" instructions can be translated to
19419 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19420 ;; byte opcode instead of two, have a short form for byte operands),
19421 ;; so do it for other CPUs as well. Given that the value was dead,
19422 ;; this should not create any new dependencies. Pass on the sub-word
19423 ;; versions if we're concerned about partial register stalls.
19426 [(set (match_operand 0 "flags_reg_operand" "")
19427 (match_operator 1 "compare_operator"
19428 [(and:SI (match_operand:SI 2 "register_operand" "")
19429 (match_operand:SI 3 "immediate_operand" ""))
19431 "ix86_match_ccmode (insn, CCNOmode)
19432 && (true_regnum (operands[2]) != 0
19433 || satisfies_constraint_K (operands[3]))
19434 && peep2_reg_dead_p (1, operands[2])"
19436 [(set (match_dup 0)
19437 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19440 (and:SI (match_dup 2) (match_dup 3)))])]
19443 ;; We don't need to handle HImode case, because it will be promoted to SImode
19444 ;; on ! TARGET_PARTIAL_REG_STALL
19447 [(set (match_operand 0 "flags_reg_operand" "")
19448 (match_operator 1 "compare_operator"
19449 [(and:QI (match_operand:QI 2 "register_operand" "")
19450 (match_operand:QI 3 "immediate_operand" ""))
19452 "! TARGET_PARTIAL_REG_STALL
19453 && ix86_match_ccmode (insn, CCNOmode)
19454 && true_regnum (operands[2]) != 0
19455 && peep2_reg_dead_p (1, operands[2])"
19457 [(set (match_dup 0)
19458 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19461 (and:QI (match_dup 2) (match_dup 3)))])]
19465 [(set (match_operand 0 "flags_reg_operand" "")
19466 (match_operator 1 "compare_operator"
19469 (match_operand 2 "ext_register_operand" "")
19472 (match_operand 3 "const_int_operand" ""))
19474 "! TARGET_PARTIAL_REG_STALL
19475 && ix86_match_ccmode (insn, CCNOmode)
19476 && true_regnum (operands[2]) != 0
19477 && peep2_reg_dead_p (1, operands[2])"
19478 [(parallel [(set (match_dup 0)
19487 (set (zero_extract:SI (match_dup 2)
19498 ;; Don't do logical operations with memory inputs.
19500 [(match_scratch:SI 2 "r")
19501 (parallel [(set (match_operand:SI 0 "register_operand" "")
19502 (match_operator:SI 3 "arith_or_logical_operator"
19504 (match_operand:SI 1 "memory_operand" "")]))
19505 (clobber (reg:CC FLAGS_REG))])]
19506 "! optimize_size && ! TARGET_READ_MODIFY"
19507 [(set (match_dup 2) (match_dup 1))
19508 (parallel [(set (match_dup 0)
19509 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19510 (clobber (reg:CC FLAGS_REG))])]
19514 [(match_scratch:SI 2 "r")
19515 (parallel [(set (match_operand:SI 0 "register_operand" "")
19516 (match_operator:SI 3 "arith_or_logical_operator"
19517 [(match_operand:SI 1 "memory_operand" "")
19519 (clobber (reg:CC FLAGS_REG))])]
19520 "! optimize_size && ! TARGET_READ_MODIFY"
19521 [(set (match_dup 2) (match_dup 1))
19522 (parallel [(set (match_dup 0)
19523 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19524 (clobber (reg:CC FLAGS_REG))])]
19527 ; Don't do logical operations with memory outputs
19529 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19530 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19531 ; the same decoder scheduling characteristics as the original.
19534 [(match_scratch:SI 2 "r")
19535 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19536 (match_operator:SI 3 "arith_or_logical_operator"
19538 (match_operand:SI 1 "nonmemory_operand" "")]))
19539 (clobber (reg:CC FLAGS_REG))])]
19540 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19541 [(set (match_dup 2) (match_dup 0))
19542 (parallel [(set (match_dup 2)
19543 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19544 (clobber (reg:CC FLAGS_REG))])
19545 (set (match_dup 0) (match_dup 2))]
19549 [(match_scratch:SI 2 "r")
19550 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19551 (match_operator:SI 3 "arith_or_logical_operator"
19552 [(match_operand:SI 1 "nonmemory_operand" "")
19554 (clobber (reg:CC FLAGS_REG))])]
19555 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
19556 [(set (match_dup 2) (match_dup 0))
19557 (parallel [(set (match_dup 2)
19558 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19559 (clobber (reg:CC FLAGS_REG))])
19560 (set (match_dup 0) (match_dup 2))]
19563 ;; Attempt to always use XOR for zeroing registers.
19565 [(set (match_operand 0 "register_operand" "")
19566 (match_operand 1 "const0_operand" ""))]
19567 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19568 && (! TARGET_USE_MOV0 || optimize_size)
19569 && GENERAL_REG_P (operands[0])
19570 && peep2_regno_dead_p (0, FLAGS_REG)"
19571 [(parallel [(set (match_dup 0) (const_int 0))
19572 (clobber (reg:CC FLAGS_REG))])]
19574 operands[0] = gen_lowpart (word_mode, operands[0]);
19578 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19580 "(GET_MODE (operands[0]) == QImode
19581 || GET_MODE (operands[0]) == HImode)
19582 && (! TARGET_USE_MOV0 || optimize_size)
19583 && peep2_regno_dead_p (0, FLAGS_REG)"
19584 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19585 (clobber (reg:CC FLAGS_REG))])])
19587 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19589 [(set (match_operand 0 "register_operand" "")
19591 "(GET_MODE (operands[0]) == HImode
19592 || GET_MODE (operands[0]) == SImode
19593 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19594 && (optimize_size || TARGET_PENTIUM)
19595 && peep2_regno_dead_p (0, FLAGS_REG)"
19596 [(parallel [(set (match_dup 0) (const_int -1))
19597 (clobber (reg:CC FLAGS_REG))])]
19598 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19601 ;; Attempt to convert simple leas to adds. These can be created by
19604 [(set (match_operand:SI 0 "register_operand" "")
19605 (plus:SI (match_dup 0)
19606 (match_operand:SI 1 "nonmemory_operand" "")))]
19607 "peep2_regno_dead_p (0, FLAGS_REG)"
19608 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19609 (clobber (reg:CC FLAGS_REG))])]
19613 [(set (match_operand:SI 0 "register_operand" "")
19614 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19615 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19616 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19617 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19618 (clobber (reg:CC FLAGS_REG))])]
19619 "operands[2] = gen_lowpart (SImode, operands[2]);")
19622 [(set (match_operand:DI 0 "register_operand" "")
19623 (plus:DI (match_dup 0)
19624 (match_operand:DI 1 "x86_64_general_operand" "")))]
19625 "peep2_regno_dead_p (0, FLAGS_REG)"
19626 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19627 (clobber (reg:CC FLAGS_REG))])]
19631 [(set (match_operand:SI 0 "register_operand" "")
19632 (mult:SI (match_dup 0)
19633 (match_operand:SI 1 "const_int_operand" "")))]
19634 "exact_log2 (INTVAL (operands[1])) >= 0
19635 && peep2_regno_dead_p (0, FLAGS_REG)"
19636 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19637 (clobber (reg:CC FLAGS_REG))])]
19638 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19641 [(set (match_operand:DI 0 "register_operand" "")
19642 (mult:DI (match_dup 0)
19643 (match_operand:DI 1 "const_int_operand" "")))]
19644 "exact_log2 (INTVAL (operands[1])) >= 0
19645 && peep2_regno_dead_p (0, FLAGS_REG)"
19646 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19647 (clobber (reg:CC FLAGS_REG))])]
19648 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19651 [(set (match_operand:SI 0 "register_operand" "")
19652 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19653 (match_operand:DI 2 "const_int_operand" "")) 0))]
19654 "exact_log2 (INTVAL (operands[2])) >= 0
19655 && REGNO (operands[0]) == REGNO (operands[1])
19656 && peep2_regno_dead_p (0, FLAGS_REG)"
19657 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19658 (clobber (reg:CC FLAGS_REG))])]
19659 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19661 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19662 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19663 ;; many CPUs it is also faster, since special hardware to avoid esp
19664 ;; dependencies is present.
19666 ;; While some of these conversions may be done using splitters, we use peepholes
19667 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19669 ;; Convert prologue esp subtractions to push.
19670 ;; We need register to push. In order to keep verify_flow_info happy we have
19672 ;; - use scratch and clobber it in order to avoid dependencies
19673 ;; - use already live register
19674 ;; We can't use the second way right now, since there is no reliable way how to
19675 ;; verify that given register is live. First choice will also most likely in
19676 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19677 ;; call clobbered registers are dead. We may want to use base pointer as an
19678 ;; alternative when no register is available later.
19681 [(match_scratch:SI 0 "r")
19682 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19683 (clobber (reg:CC FLAGS_REG))
19684 (clobber (mem:BLK (scratch)))])]
19685 "optimize_size || !TARGET_SUB_ESP_4"
19686 [(clobber (match_dup 0))
19687 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19688 (clobber (mem:BLK (scratch)))])])
19691 [(match_scratch:SI 0 "r")
19692 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19693 (clobber (reg:CC FLAGS_REG))
19694 (clobber (mem:BLK (scratch)))])]
19695 "optimize_size || !TARGET_SUB_ESP_8"
19696 [(clobber (match_dup 0))
19697 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19698 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19699 (clobber (mem:BLK (scratch)))])])
19701 ;; Convert esp subtractions to push.
19703 [(match_scratch:SI 0 "r")
19704 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19705 (clobber (reg:CC FLAGS_REG))])]
19706 "optimize_size || !TARGET_SUB_ESP_4"
19707 [(clobber (match_dup 0))
19708 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19711 [(match_scratch:SI 0 "r")
19712 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19713 (clobber (reg:CC FLAGS_REG))])]
19714 "optimize_size || !TARGET_SUB_ESP_8"
19715 [(clobber (match_dup 0))
19716 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19717 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19719 ;; Convert epilogue deallocator to pop.
19721 [(match_scratch:SI 0 "r")
19722 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19723 (clobber (reg:CC FLAGS_REG))
19724 (clobber (mem:BLK (scratch)))])]
19725 "optimize_size || !TARGET_ADD_ESP_4"
19726 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19727 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19728 (clobber (mem:BLK (scratch)))])]
19731 ;; Two pops case is tricky, since pop causes dependency on destination register.
19732 ;; We use two registers if available.
19734 [(match_scratch:SI 0 "r")
19735 (match_scratch:SI 1 "r")
19736 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19737 (clobber (reg:CC FLAGS_REG))
19738 (clobber (mem:BLK (scratch)))])]
19739 "optimize_size || !TARGET_ADD_ESP_8"
19740 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19741 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19742 (clobber (mem:BLK (scratch)))])
19743 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19744 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19748 [(match_scratch:SI 0 "r")
19749 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19750 (clobber (reg:CC FLAGS_REG))
19751 (clobber (mem:BLK (scratch)))])]
19753 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19754 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19755 (clobber (mem:BLK (scratch)))])
19756 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19757 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19760 ;; Convert esp additions to pop.
19762 [(match_scratch:SI 0 "r")
19763 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19764 (clobber (reg:CC FLAGS_REG))])]
19766 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19767 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19770 ;; Two pops case is tricky, since pop causes dependency on destination register.
19771 ;; We use two registers if available.
19773 [(match_scratch:SI 0 "r")
19774 (match_scratch:SI 1 "r")
19775 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19776 (clobber (reg:CC FLAGS_REG))])]
19778 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19779 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19780 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19781 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19785 [(match_scratch:SI 0 "r")
19786 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19787 (clobber (reg:CC FLAGS_REG))])]
19789 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19790 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19791 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19792 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19795 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19796 ;; required and register dies. Similarly for 128 to plus -128.
19798 [(set (match_operand 0 "flags_reg_operand" "")
19799 (match_operator 1 "compare_operator"
19800 [(match_operand 2 "register_operand" "")
19801 (match_operand 3 "const_int_operand" "")]))]
19802 "(INTVAL (operands[3]) == -1
19803 || INTVAL (operands[3]) == 1
19804 || INTVAL (operands[3]) == 128)
19805 && ix86_match_ccmode (insn, CCGCmode)
19806 && peep2_reg_dead_p (1, operands[2])"
19807 [(parallel [(set (match_dup 0)
19808 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19809 (clobber (match_dup 2))])]
19813 [(match_scratch:DI 0 "r")
19814 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19815 (clobber (reg:CC FLAGS_REG))
19816 (clobber (mem:BLK (scratch)))])]
19817 "optimize_size || !TARGET_SUB_ESP_4"
19818 [(clobber (match_dup 0))
19819 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19820 (clobber (mem:BLK (scratch)))])])
19823 [(match_scratch:DI 0 "r")
19824 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19825 (clobber (reg:CC FLAGS_REG))
19826 (clobber (mem:BLK (scratch)))])]
19827 "optimize_size || !TARGET_SUB_ESP_8"
19828 [(clobber (match_dup 0))
19829 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19830 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19831 (clobber (mem:BLK (scratch)))])])
19833 ;; Convert esp subtractions to push.
19835 [(match_scratch:DI 0 "r")
19836 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19837 (clobber (reg:CC FLAGS_REG))])]
19838 "optimize_size || !TARGET_SUB_ESP_4"
19839 [(clobber (match_dup 0))
19840 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19843 [(match_scratch:DI 0 "r")
19844 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19845 (clobber (reg:CC FLAGS_REG))])]
19846 "optimize_size || !TARGET_SUB_ESP_8"
19847 [(clobber (match_dup 0))
19848 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19849 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19851 ;; Convert epilogue deallocator to pop.
19853 [(match_scratch:DI 0 "r")
19854 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19855 (clobber (reg:CC FLAGS_REG))
19856 (clobber (mem:BLK (scratch)))])]
19857 "optimize_size || !TARGET_ADD_ESP_4"
19858 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19859 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19860 (clobber (mem:BLK (scratch)))])]
19863 ;; Two pops case is tricky, since pop causes dependency on destination register.
19864 ;; We use two registers if available.
19866 [(match_scratch:DI 0 "r")
19867 (match_scratch:DI 1 "r")
19868 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19869 (clobber (reg:CC FLAGS_REG))
19870 (clobber (mem:BLK (scratch)))])]
19871 "optimize_size || !TARGET_ADD_ESP_8"
19872 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19873 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19874 (clobber (mem:BLK (scratch)))])
19875 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19876 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19880 [(match_scratch:DI 0 "r")
19881 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19882 (clobber (reg:CC FLAGS_REG))
19883 (clobber (mem:BLK (scratch)))])]
19885 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19886 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19887 (clobber (mem:BLK (scratch)))])
19888 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19889 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19892 ;; Convert esp additions to pop.
19894 [(match_scratch:DI 0 "r")
19895 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19896 (clobber (reg:CC FLAGS_REG))])]
19898 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19899 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19902 ;; Two pops case is tricky, since pop causes dependency on destination register.
19903 ;; We use two registers if available.
19905 [(match_scratch:DI 0 "r")
19906 (match_scratch:DI 1 "r")
19907 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19908 (clobber (reg:CC FLAGS_REG))])]
19910 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19911 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19912 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19913 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19917 [(match_scratch:DI 0 "r")
19918 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19919 (clobber (reg:CC FLAGS_REG))])]
19921 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19922 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19923 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19924 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19927 ;; Convert imul by three, five and nine into lea
19930 [(set (match_operand:SI 0 "register_operand" "")
19931 (mult:SI (match_operand:SI 1 "register_operand" "")
19932 (match_operand:SI 2 "const_int_operand" "")))
19933 (clobber (reg:CC FLAGS_REG))])]
19934 "INTVAL (operands[2]) == 3
19935 || INTVAL (operands[2]) == 5
19936 || INTVAL (operands[2]) == 9"
19937 [(set (match_dup 0)
19938 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19940 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19944 [(set (match_operand:SI 0 "register_operand" "")
19945 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19946 (match_operand:SI 2 "const_int_operand" "")))
19947 (clobber (reg:CC FLAGS_REG))])]
19949 && (INTVAL (operands[2]) == 3
19950 || INTVAL (operands[2]) == 5
19951 || INTVAL (operands[2]) == 9)"
19952 [(set (match_dup 0) (match_dup 1))
19954 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19956 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19960 [(set (match_operand:DI 0 "register_operand" "")
19961 (mult:DI (match_operand:DI 1 "register_operand" "")
19962 (match_operand:DI 2 "const_int_operand" "")))
19963 (clobber (reg:CC FLAGS_REG))])]
19965 && (INTVAL (operands[2]) == 3
19966 || INTVAL (operands[2]) == 5
19967 || INTVAL (operands[2]) == 9)"
19968 [(set (match_dup 0)
19969 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19971 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19975 [(set (match_operand:DI 0 "register_operand" "")
19976 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19977 (match_operand:DI 2 "const_int_operand" "")))
19978 (clobber (reg:CC FLAGS_REG))])]
19981 && (INTVAL (operands[2]) == 3
19982 || INTVAL (operands[2]) == 5
19983 || INTVAL (operands[2]) == 9)"
19984 [(set (match_dup 0) (match_dup 1))
19986 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19988 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19990 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19991 ;; imul $32bit_imm, reg, reg is direct decoded.
19993 [(match_scratch:DI 3 "r")
19994 (parallel [(set (match_operand:DI 0 "register_operand" "")
19995 (mult:DI (match_operand:DI 1 "memory_operand" "")
19996 (match_operand:DI 2 "immediate_operand" "")))
19997 (clobber (reg:CC FLAGS_REG))])]
19998 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
19999 && !satisfies_constraint_K (operands[2])"
20000 [(set (match_dup 3) (match_dup 1))
20001 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20002 (clobber (reg:CC FLAGS_REG))])]
20006 [(match_scratch:SI 3 "r")
20007 (parallel [(set (match_operand:SI 0 "register_operand" "")
20008 (mult:SI (match_operand:SI 1 "memory_operand" "")
20009 (match_operand:SI 2 "immediate_operand" "")))
20010 (clobber (reg:CC FLAGS_REG))])]
20011 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20012 && !satisfies_constraint_K (operands[2])"
20013 [(set (match_dup 3) (match_dup 1))
20014 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20015 (clobber (reg:CC FLAGS_REG))])]
20019 [(match_scratch:SI 3 "r")
20020 (parallel [(set (match_operand:DI 0 "register_operand" "")
20022 (mult:SI (match_operand:SI 1 "memory_operand" "")
20023 (match_operand:SI 2 "immediate_operand" ""))))
20024 (clobber (reg:CC FLAGS_REG))])]
20025 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20026 && !satisfies_constraint_K (operands[2])"
20027 [(set (match_dup 3) (match_dup 1))
20028 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20029 (clobber (reg:CC FLAGS_REG))])]
20032 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20033 ;; Convert it into imul reg, reg
20034 ;; It would be better to force assembler to encode instruction using long
20035 ;; immediate, but there is apparently no way to do so.
20037 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20038 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20039 (match_operand:DI 2 "const_int_operand" "")))
20040 (clobber (reg:CC FLAGS_REG))])
20041 (match_scratch:DI 3 "r")]
20042 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20043 && satisfies_constraint_K (operands[2])"
20044 [(set (match_dup 3) (match_dup 2))
20045 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20046 (clobber (reg:CC FLAGS_REG))])]
20048 if (!rtx_equal_p (operands[0], operands[1]))
20049 emit_move_insn (operands[0], operands[1]);
20053 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20054 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20055 (match_operand:SI 2 "const_int_operand" "")))
20056 (clobber (reg:CC FLAGS_REG))])
20057 (match_scratch:SI 3 "r")]
20058 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20059 && satisfies_constraint_K (operands[2])"
20060 [(set (match_dup 3) (match_dup 2))
20061 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20062 (clobber (reg:CC FLAGS_REG))])]
20064 if (!rtx_equal_p (operands[0], operands[1]))
20065 emit_move_insn (operands[0], operands[1]);
20069 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20070 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20071 (match_operand:HI 2 "immediate_operand" "")))
20072 (clobber (reg:CC FLAGS_REG))])
20073 (match_scratch:HI 3 "r")]
20074 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20075 [(set (match_dup 3) (match_dup 2))
20076 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20077 (clobber (reg:CC FLAGS_REG))])]
20079 if (!rtx_equal_p (operands[0], operands[1]))
20080 emit_move_insn (operands[0], operands[1]);
20083 ;; After splitting up read-modify operations, array accesses with memory
20084 ;; operands might end up in form:
20086 ;; movl 4(%esp), %edx
20088 ;; instead of pre-splitting:
20090 ;; addl 4(%esp), %eax
20092 ;; movl 4(%esp), %edx
20093 ;; leal (%edx,%eax,4), %eax
20096 [(parallel [(set (match_operand 0 "register_operand" "")
20097 (ashift (match_operand 1 "register_operand" "")
20098 (match_operand 2 "const_int_operand" "")))
20099 (clobber (reg:CC FLAGS_REG))])
20100 (set (match_operand 3 "register_operand")
20101 (match_operand 4 "x86_64_general_operand" ""))
20102 (parallel [(set (match_operand 5 "register_operand" "")
20103 (plus (match_operand 6 "register_operand" "")
20104 (match_operand 7 "register_operand" "")))
20105 (clobber (reg:CC FLAGS_REG))])]
20106 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20107 /* Validate MODE for lea. */
20108 && ((!TARGET_PARTIAL_REG_STALL
20109 && (GET_MODE (operands[0]) == QImode
20110 || GET_MODE (operands[0]) == HImode))
20111 || GET_MODE (operands[0]) == SImode
20112 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20113 /* We reorder load and the shift. */
20114 && !rtx_equal_p (operands[1], operands[3])
20115 && !reg_overlap_mentioned_p (operands[0], operands[4])
20116 /* Last PLUS must consist of operand 0 and 3. */
20117 && !rtx_equal_p (operands[0], operands[3])
20118 && (rtx_equal_p (operands[3], operands[6])
20119 || rtx_equal_p (operands[3], operands[7]))
20120 && (rtx_equal_p (operands[0], operands[6])
20121 || rtx_equal_p (operands[0], operands[7]))
20122 /* The intermediate operand 0 must die or be same as output. */
20123 && (rtx_equal_p (operands[0], operands[5])
20124 || peep2_reg_dead_p (3, operands[0]))"
20125 [(set (match_dup 3) (match_dup 4))
20126 (set (match_dup 0) (match_dup 1))]
20128 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20129 int scale = 1 << INTVAL (operands[2]);
20130 rtx index = gen_lowpart (Pmode, operands[1]);
20131 rtx base = gen_lowpart (Pmode, operands[3]);
20132 rtx dest = gen_lowpart (mode, operands[5]);
20134 operands[1] = gen_rtx_PLUS (Pmode, base,
20135 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20137 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20138 operands[0] = dest;
20141 ;; Call-value patterns last so that the wildcard operand does not
20142 ;; disrupt insn-recog's switch tables.
20144 (define_insn "*call_value_pop_0"
20145 [(set (match_operand 0 "" "")
20146 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20147 (match_operand:SI 2 "" "")))
20148 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20149 (match_operand:SI 3 "immediate_operand" "")))]
20152 if (SIBLING_CALL_P (insn))
20155 return "call\t%P1";
20157 [(set_attr "type" "callv")])
20159 (define_insn "*call_value_pop_1"
20160 [(set (match_operand 0 "" "")
20161 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20162 (match_operand:SI 2 "" "")))
20163 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20164 (match_operand:SI 3 "immediate_operand" "i")))]
20167 if (constant_call_address_operand (operands[1], Pmode))
20169 if (SIBLING_CALL_P (insn))
20172 return "call\t%P1";
20174 if (SIBLING_CALL_P (insn))
20177 return "call\t%A1";
20179 [(set_attr "type" "callv")])
20181 (define_insn "*call_value_0"
20182 [(set (match_operand 0 "" "")
20183 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20184 (match_operand:SI 2 "" "")))]
20187 if (SIBLING_CALL_P (insn))
20190 return "call\t%P1";
20192 [(set_attr "type" "callv")])
20194 (define_insn "*call_value_0_rex64"
20195 [(set (match_operand 0 "" "")
20196 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20197 (match_operand:DI 2 "const_int_operand" "")))]
20200 if (SIBLING_CALL_P (insn))
20203 return "call\t%P1";
20205 [(set_attr "type" "callv")])
20207 (define_insn "*call_value_1"
20208 [(set (match_operand 0 "" "")
20209 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20210 (match_operand:SI 2 "" "")))]
20211 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20213 if (constant_call_address_operand (operands[1], Pmode))
20214 return "call\t%P1";
20215 return "call\t%A1";
20217 [(set_attr "type" "callv")])
20219 (define_insn "*sibcall_value_1"
20220 [(set (match_operand 0 "" "")
20221 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20222 (match_operand:SI 2 "" "")))]
20223 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20225 if (constant_call_address_operand (operands[1], Pmode))
20229 [(set_attr "type" "callv")])
20231 (define_insn "*call_value_1_rex64"
20232 [(set (match_operand 0 "" "")
20233 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20234 (match_operand:DI 2 "" "")))]
20235 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20237 if (constant_call_address_operand (operands[1], Pmode))
20238 return "call\t%P1";
20239 return "call\t%A1";
20241 [(set_attr "type" "callv")])
20243 (define_insn "*sibcall_value_1_rex64"
20244 [(set (match_operand 0 "" "")
20245 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20246 (match_operand:DI 2 "" "")))]
20247 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20249 [(set_attr "type" "callv")])
20251 (define_insn "*sibcall_value_1_rex64_v"
20252 [(set (match_operand 0 "" "")
20253 (call (mem:QI (reg:DI R11_REG))
20254 (match_operand:DI 1 "" "")))]
20255 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20257 [(set_attr "type" "callv")])
20259 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20260 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20261 ;; caught for use by garbage collectors and the like. Using an insn that
20262 ;; maps to SIGILL makes it more likely the program will rightfully die.
20263 ;; Keeping with tradition, "6" is in honor of #UD.
20264 (define_insn "trap"
20265 [(trap_if (const_int 1) (const_int 6))]
20267 { return ASM_SHORT "0x0b0f"; }
20268 [(set_attr "length" "2")])
20270 (define_expand "sse_prologue_save"
20271 [(parallel [(set (match_operand:BLK 0 "" "")
20272 (unspec:BLK [(reg:DI 21)
20279 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20280 (use (match_operand:DI 1 "register_operand" ""))
20281 (use (match_operand:DI 2 "immediate_operand" ""))
20282 (use (label_ref:DI (match_operand 3 "" "")))])]
20286 (define_insn "*sse_prologue_save_insn"
20287 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20288 (match_operand:DI 4 "const_int_operand" "n")))
20289 (unspec:BLK [(reg:DI 21)
20296 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20297 (use (match_operand:DI 1 "register_operand" "r"))
20298 (use (match_operand:DI 2 "const_int_operand" "i"))
20299 (use (label_ref:DI (match_operand 3 "" "X")))]
20301 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20302 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20306 operands[0] = gen_rtx_MEM (Pmode,
20307 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20308 output_asm_insn (\"jmp\\t%A1\", operands);
20309 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20311 operands[4] = adjust_address (operands[0], DImode, i*16);
20312 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20313 PUT_MODE (operands[4], TImode);
20314 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20315 output_asm_insn (\"rex\", operands);
20316 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20318 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20319 CODE_LABEL_NUMBER (operands[3]));
20323 [(set_attr "type" "other")
20324 (set_attr "length_immediate" "0")
20325 (set_attr "length_address" "0")
20326 (set_attr "length" "135")
20327 (set_attr "memory" "store")
20328 (set_attr "modrm" "0")
20329 (set_attr "mode" "DI")])
20331 (define_expand "prefetch"
20332 [(prefetch (match_operand 0 "address_operand" "")
20333 (match_operand:SI 1 "const_int_operand" "")
20334 (match_operand:SI 2 "const_int_operand" ""))]
20335 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20337 int rw = INTVAL (operands[1]);
20338 int locality = INTVAL (operands[2]);
20340 gcc_assert (rw == 0 || rw == 1);
20341 gcc_assert (locality >= 0 && locality <= 3);
20342 gcc_assert (GET_MODE (operands[0]) == Pmode
20343 || GET_MODE (operands[0]) == VOIDmode);
20345 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20346 supported by SSE counterpart or the SSE prefetch is not available
20347 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20349 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20350 operands[2] = GEN_INT (3);
20352 operands[1] = const0_rtx;
20355 (define_insn "*prefetch_sse"
20356 [(prefetch (match_operand:SI 0 "address_operand" "p")
20358 (match_operand:SI 1 "const_int_operand" ""))]
20359 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20361 static const char * const patterns[4] = {
20362 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20365 int locality = INTVAL (operands[1]);
20366 gcc_assert (locality >= 0 && locality <= 3);
20368 return patterns[locality];
20370 [(set_attr "type" "sse")
20371 (set_attr "memory" "none")])
20373 (define_insn "*prefetch_sse_rex"
20374 [(prefetch (match_operand:DI 0 "address_operand" "p")
20376 (match_operand:SI 1 "const_int_operand" ""))]
20377 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20379 static const char * const patterns[4] = {
20380 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20383 int locality = INTVAL (operands[1]);
20384 gcc_assert (locality >= 0 && locality <= 3);
20386 return patterns[locality];
20388 [(set_attr "type" "sse")
20389 (set_attr "memory" "none")])
20391 (define_insn "*prefetch_3dnow"
20392 [(prefetch (match_operand:SI 0 "address_operand" "p")
20393 (match_operand:SI 1 "const_int_operand" "n")
20395 "TARGET_3DNOW && !TARGET_64BIT"
20397 if (INTVAL (operands[1]) == 0)
20398 return "prefetch\t%a0";
20400 return "prefetchw\t%a0";
20402 [(set_attr "type" "mmx")
20403 (set_attr "memory" "none")])
20405 (define_insn "*prefetch_3dnow_rex"
20406 [(prefetch (match_operand:DI 0 "address_operand" "p")
20407 (match_operand:SI 1 "const_int_operand" "n")
20409 "TARGET_3DNOW && TARGET_64BIT"
20411 if (INTVAL (operands[1]) == 0)
20412 return "prefetch\t%a0";
20414 return "prefetchw\t%a0";
20416 [(set_attr "type" "mmx")
20417 (set_attr "memory" "none")])
20419 (define_expand "stack_protect_set"
20420 [(match_operand 0 "memory_operand" "")
20421 (match_operand 1 "memory_operand" "")]
20424 #ifdef TARGET_THREAD_SSP_OFFSET
20426 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20427 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20429 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20430 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20433 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20435 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20440 (define_insn "stack_protect_set_si"
20441 [(set (match_operand:SI 0 "memory_operand" "=m")
20442 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20443 (set (match_scratch:SI 2 "=&r") (const_int 0))
20444 (clobber (reg:CC FLAGS_REG))]
20446 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20447 [(set_attr "type" "multi")])
20449 (define_insn "stack_protect_set_di"
20450 [(set (match_operand:DI 0 "memory_operand" "=m")
20451 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20452 (set (match_scratch:DI 2 "=&r") (const_int 0))
20453 (clobber (reg:CC FLAGS_REG))]
20455 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20456 [(set_attr "type" "multi")])
20458 (define_insn "stack_tls_protect_set_si"
20459 [(set (match_operand:SI 0 "memory_operand" "=m")
20460 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20461 (set (match_scratch:SI 2 "=&r") (const_int 0))
20462 (clobber (reg:CC FLAGS_REG))]
20464 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20465 [(set_attr "type" "multi")])
20467 (define_insn "stack_tls_protect_set_di"
20468 [(set (match_operand:DI 0 "memory_operand" "=m")
20469 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20470 (set (match_scratch:DI 2 "=&r") (const_int 0))
20471 (clobber (reg:CC FLAGS_REG))]
20474 /* The kernel uses a different segment register for performance reasons; a
20475 system call would not have to trash the userspace segment register,
20476 which would be expensive */
20477 if (ix86_cmodel != CM_KERNEL)
20478 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20480 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20482 [(set_attr "type" "multi")])
20484 (define_expand "stack_protect_test"
20485 [(match_operand 0 "memory_operand" "")
20486 (match_operand 1 "memory_operand" "")
20487 (match_operand 2 "" "")]
20490 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20491 ix86_compare_op0 = operands[0];
20492 ix86_compare_op1 = operands[1];
20493 ix86_compare_emitted = flags;
20495 #ifdef TARGET_THREAD_SSP_OFFSET
20497 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20498 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20500 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20501 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20504 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20506 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20508 emit_jump_insn (gen_beq (operands[2]));
20512 (define_insn "stack_protect_test_si"
20513 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20514 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20515 (match_operand:SI 2 "memory_operand" "m")]
20517 (clobber (match_scratch:SI 3 "=&r"))]
20519 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20520 [(set_attr "type" "multi")])
20522 (define_insn "stack_protect_test_di"
20523 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20524 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20525 (match_operand:DI 2 "memory_operand" "m")]
20527 (clobber (match_scratch:DI 3 "=&r"))]
20529 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20530 [(set_attr "type" "multi")])
20532 (define_insn "stack_tls_protect_test_si"
20533 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20534 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20535 (match_operand:SI 2 "const_int_operand" "i")]
20536 UNSPEC_SP_TLS_TEST))
20537 (clobber (match_scratch:SI 3 "=r"))]
20539 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
20540 [(set_attr "type" "multi")])
20542 (define_insn "stack_tls_protect_test_di"
20543 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20544 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20545 (match_operand:DI 2 "const_int_operand" "i")]
20546 UNSPEC_SP_TLS_TEST))
20547 (clobber (match_scratch:DI 3 "=r"))]
20550 /* The kernel uses a different segment register for performance reasons; a
20551 system call would not have to trash the userspace segment register,
20552 which would be expensive */
20553 if (ix86_cmodel != CM_KERNEL)
20554 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
20556 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
20558 [(set_attr "type" "multi")])
20562 (include "sync.md")