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
126 (UNSPEC_FRNDINT_FLOOR 70)
127 (UNSPEC_FRNDINT_CEIL 71)
128 (UNSPEC_FRNDINT_TRUNC 72)
129 (UNSPEC_FRNDINT_MASK_PM 73)
130 (UNSPEC_FIST_FLOOR 74)
131 (UNSPEC_FIST_CEIL 75)
133 ; x87 Double output FP
134 (UNSPEC_SINCOS_COS 80)
135 (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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
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 "GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM"
1489 switch (get_attr_type (insn))
1492 gcc_assert (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM);
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 (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
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 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
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 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
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 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
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 && GET_CODE (operands[1]) == MEM
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 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
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 && GET_CODE (operands[1]) == MEM
2898 && (GET_MODE (operands[0]) == XFmode
2899 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2900 && constant_pool_reference_p (operands[1])"
2901 [(set (match_dup 0) (match_dup 1))]
2903 rtx c = avoid_constant_pool_reference (operands[1]);
2904 rtx r = operands[0];
2906 if (GET_CODE (r) == SUBREG)
2911 if (!standard_sse_constant_p (c))
2914 else if (FP_REG_P (r))
2916 if (!standard_80387_constant_p (c))
2919 else if (MMX_REG_P (r))
2926 [(set (match_operand 0 "register_operand" "")
2927 (float_extend (match_operand 1 "memory_operand" "")))]
2929 && GET_CODE (operands[1]) == MEM
2930 && (GET_MODE (operands[0]) == XFmode
2931 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2932 && constant_pool_reference_p (operands[1])"
2933 [(set (match_dup 0) (match_dup 1))]
2935 rtx c = avoid_constant_pool_reference (SET_SRC (PATTERN (curr_insn)));
2936 rtx r = operands[0];
2938 if (GET_CODE (r) == SUBREG)
2943 if (!standard_sse_constant_p (c))
2946 else if (FP_REG_P (r))
2948 if (!standard_80387_constant_p (c))
2951 else if (MMX_REG_P (r))
2957 (define_insn "swapxf"
2958 [(set (match_operand:XF 0 "register_operand" "+f")
2959 (match_operand:XF 1 "register_operand" "+f"))
2964 if (STACK_TOP_P (operands[0]))
2969 [(set_attr "type" "fxch")
2970 (set_attr "mode" "XF")])
2972 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2974 [(set (match_operand:X87MODEF 0 "register_operand" "")
2975 (match_operand:X87MODEF 1 "immediate_operand" ""))]
2976 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2977 && (standard_80387_constant_p (operands[1]) == 8
2978 || standard_80387_constant_p (operands[1]) == 9)"
2979 [(set (match_dup 0)(match_dup 1))
2981 (neg:X87MODEF (match_dup 0)))]
2985 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2986 if (real_isnegzero (&r))
2987 operands[1] = CONST0_RTX (<MODE>mode);
2989 operands[1] = CONST1_RTX (<MODE>mode);
2992 (define_expand "movtf"
2993 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2994 (match_operand:TF 1 "nonimmediate_operand" ""))]
2997 ix86_expand_move (TFmode, operands);
3001 (define_insn "*movtf_internal"
3002 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
3003 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
3005 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
3007 switch (which_alternative)
3013 if (get_attr_mode (insn) == MODE_V4SF)
3014 return "xorps\t%0, %0";
3016 return "pxor\t%0, %0";
3019 if (get_attr_mode (insn) == MODE_V4SF)
3020 return "movaps\t{%1, %0|%0, %1}";
3022 return "movdqa\t{%1, %0|%0, %1}";
3027 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
3029 (cond [(eq_attr "alternative" "2,3")
3031 (ne (symbol_ref "optimize_size")
3033 (const_string "V4SF")
3034 (const_string "TI"))
3035 (eq_attr "alternative" "4")
3037 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3039 (ne (symbol_ref "optimize_size")
3041 (const_string "V4SF")
3042 (const_string "TI"))]
3043 (const_string "DI")))])
3046 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3047 (match_operand:TF 1 "general_operand" ""))]
3048 "reload_completed && !SSE_REG_P (operands[0])
3049 && !SSE_REG_P (operands[1])"
3051 "ix86_split_long_move (operands); DONE;")
3053 ;; Zero extension instructions
3055 (define_expand "zero_extendhisi2"
3056 [(set (match_operand:SI 0 "register_operand" "")
3057 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3060 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3062 operands[1] = force_reg (HImode, operands[1]);
3063 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3068 (define_insn "zero_extendhisi2_and"
3069 [(set (match_operand:SI 0 "register_operand" "=r")
3070 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3071 (clobber (reg:CC FLAGS_REG))]
3072 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3074 [(set_attr "type" "alu1")
3075 (set_attr "mode" "SI")])
3078 [(set (match_operand:SI 0 "register_operand" "")
3079 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3080 (clobber (reg:CC FLAGS_REG))]
3081 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3082 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3083 (clobber (reg:CC FLAGS_REG))])]
3086 (define_insn "*zero_extendhisi2_movzwl"
3087 [(set (match_operand:SI 0 "register_operand" "=r")
3088 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3089 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3090 "movz{wl|x}\t{%1, %0|%0, %1}"
3091 [(set_attr "type" "imovx")
3092 (set_attr "mode" "SI")])
3094 (define_expand "zero_extendqihi2"
3096 [(set (match_operand:HI 0 "register_operand" "")
3097 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3098 (clobber (reg:CC FLAGS_REG))])]
3102 (define_insn "*zero_extendqihi2_and"
3103 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3104 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3105 (clobber (reg:CC FLAGS_REG))]
3106 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3108 [(set_attr "type" "alu1")
3109 (set_attr "mode" "HI")])
3111 (define_insn "*zero_extendqihi2_movzbw_and"
3112 [(set (match_operand:HI 0 "register_operand" "=r,r")
3113 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3114 (clobber (reg:CC FLAGS_REG))]
3115 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3117 [(set_attr "type" "imovx,alu1")
3118 (set_attr "mode" "HI")])
3120 ; zero extend to SImode here to avoid partial register stalls
3121 (define_insn "*zero_extendqihi2_movzbl"
3122 [(set (match_operand:HI 0 "register_operand" "=r")
3123 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3124 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3125 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3126 [(set_attr "type" "imovx")
3127 (set_attr "mode" "SI")])
3129 ;; For the movzbw case strip only the clobber
3131 [(set (match_operand:HI 0 "register_operand" "")
3132 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3133 (clobber (reg:CC FLAGS_REG))]
3135 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3136 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3137 [(set (match_operand:HI 0 "register_operand" "")
3138 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3140 ;; When source and destination does not overlap, clear destination
3141 ;; first and then do the movb
3143 [(set (match_operand:HI 0 "register_operand" "")
3144 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3145 (clobber (reg:CC FLAGS_REG))]
3147 && ANY_QI_REG_P (operands[0])
3148 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3149 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3150 [(set (match_dup 0) (const_int 0))
3151 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3152 "operands[2] = gen_lowpart (QImode, operands[0]);")
3154 ;; Rest is handled by single and.
3156 [(set (match_operand:HI 0 "register_operand" "")
3157 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3158 (clobber (reg:CC FLAGS_REG))]
3160 && true_regnum (operands[0]) == true_regnum (operands[1])"
3161 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3162 (clobber (reg:CC FLAGS_REG))])]
3165 (define_expand "zero_extendqisi2"
3167 [(set (match_operand:SI 0 "register_operand" "")
3168 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3169 (clobber (reg:CC FLAGS_REG))])]
3173 (define_insn "*zero_extendqisi2_and"
3174 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3175 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3176 (clobber (reg:CC FLAGS_REG))]
3177 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3179 [(set_attr "type" "alu1")
3180 (set_attr "mode" "SI")])
3182 (define_insn "*zero_extendqisi2_movzbw_and"
3183 [(set (match_operand:SI 0 "register_operand" "=r,r")
3184 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3185 (clobber (reg:CC FLAGS_REG))]
3186 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3188 [(set_attr "type" "imovx,alu1")
3189 (set_attr "mode" "SI")])
3191 (define_insn "*zero_extendqisi2_movzbw"
3192 [(set (match_operand:SI 0 "register_operand" "=r")
3193 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3194 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3195 "movz{bl|x}\t{%1, %0|%0, %1}"
3196 [(set_attr "type" "imovx")
3197 (set_attr "mode" "SI")])
3199 ;; For the movzbl case strip only the clobber
3201 [(set (match_operand:SI 0 "register_operand" "")
3202 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3203 (clobber (reg:CC FLAGS_REG))]
3205 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3206 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3208 (zero_extend:SI (match_dup 1)))])
3210 ;; When source and destination does not overlap, clear destination
3211 ;; first and then do the movb
3213 [(set (match_operand:SI 0 "register_operand" "")
3214 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3215 (clobber (reg:CC FLAGS_REG))]
3217 && ANY_QI_REG_P (operands[0])
3218 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3219 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3220 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3221 [(set (match_dup 0) (const_int 0))
3222 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3223 "operands[2] = gen_lowpart (QImode, operands[0]);")
3225 ;; Rest is handled by single and.
3227 [(set (match_operand:SI 0 "register_operand" "")
3228 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3229 (clobber (reg:CC FLAGS_REG))]
3231 && true_regnum (operands[0]) == true_regnum (operands[1])"
3232 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3233 (clobber (reg:CC FLAGS_REG))])]
3236 ;; %%% Kill me once multi-word ops are sane.
3237 (define_expand "zero_extendsidi2"
3238 [(set (match_operand:DI 0 "register_operand" "=r")
3239 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3243 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3248 (define_insn "zero_extendsidi2_32"
3249 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3250 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3251 (clobber (reg:CC FLAGS_REG))]
3257 movd\t{%1, %0|%0, %1}
3258 movd\t{%1, %0|%0, %1}"
3259 [(set_attr "mode" "SI,SI,SI,DI,TI")
3260 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3262 (define_insn "zero_extendsidi2_rex64"
3263 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3264 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3267 mov\t{%k1, %k0|%k0, %k1}
3269 movd\t{%1, %0|%0, %1}
3270 movd\t{%1, %0|%0, %1}"
3271 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3272 (set_attr "mode" "SI,DI,SI,SI")])
3275 [(set (match_operand:DI 0 "memory_operand" "")
3276 (zero_extend:DI (match_dup 0)))]
3278 [(set (match_dup 4) (const_int 0))]
3279 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3282 [(set (match_operand:DI 0 "register_operand" "")
3283 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3284 (clobber (reg:CC FLAGS_REG))]
3285 "!TARGET_64BIT && reload_completed
3286 && true_regnum (operands[0]) == true_regnum (operands[1])"
3287 [(set (match_dup 4) (const_int 0))]
3288 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3291 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3292 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3293 (clobber (reg:CC FLAGS_REG))]
3294 "!TARGET_64BIT && reload_completed
3295 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3296 [(set (match_dup 3) (match_dup 1))
3297 (set (match_dup 4) (const_int 0))]
3298 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3300 (define_insn "zero_extendhidi2"
3301 [(set (match_operand:DI 0 "register_operand" "=r")
3302 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3304 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3305 [(set_attr "type" "imovx")
3306 (set_attr "mode" "DI")])
3308 (define_insn "zero_extendqidi2"
3309 [(set (match_operand:DI 0 "register_operand" "=r")
3310 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3312 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3313 [(set_attr "type" "imovx")
3314 (set_attr "mode" "DI")])
3316 ;; Sign extension instructions
3318 (define_expand "extendsidi2"
3319 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3320 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3321 (clobber (reg:CC FLAGS_REG))
3322 (clobber (match_scratch:SI 2 ""))])]
3327 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3332 (define_insn "*extendsidi2_1"
3333 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3334 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3335 (clobber (reg:CC FLAGS_REG))
3336 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3340 (define_insn "extendsidi2_rex64"
3341 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3342 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3346 movs{lq|x}\t{%1,%0|%0, %1}"
3347 [(set_attr "type" "imovx")
3348 (set_attr "mode" "DI")
3349 (set_attr "prefix_0f" "0")
3350 (set_attr "modrm" "0,1")])
3352 (define_insn "extendhidi2"
3353 [(set (match_operand:DI 0 "register_operand" "=r")
3354 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3356 "movs{wq|x}\t{%1,%0|%0, %1}"
3357 [(set_attr "type" "imovx")
3358 (set_attr "mode" "DI")])
3360 (define_insn "extendqidi2"
3361 [(set (match_operand:DI 0 "register_operand" "=r")
3362 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3364 "movs{bq|x}\t{%1,%0|%0, %1}"
3365 [(set_attr "type" "imovx")
3366 (set_attr "mode" "DI")])
3368 ;; Extend to memory case when source register does die.
3370 [(set (match_operand:DI 0 "memory_operand" "")
3371 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3372 (clobber (reg:CC FLAGS_REG))
3373 (clobber (match_operand:SI 2 "register_operand" ""))]
3375 && dead_or_set_p (insn, operands[1])
3376 && !reg_mentioned_p (operands[1], operands[0]))"
3377 [(set (match_dup 3) (match_dup 1))
3378 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3379 (clobber (reg:CC FLAGS_REG))])
3380 (set (match_dup 4) (match_dup 1))]
3381 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3383 ;; Extend to memory case when source register does not die.
3385 [(set (match_operand:DI 0 "memory_operand" "")
3386 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3387 (clobber (reg:CC FLAGS_REG))
3388 (clobber (match_operand:SI 2 "register_operand" ""))]
3392 split_di (&operands[0], 1, &operands[3], &operands[4]);
3394 emit_move_insn (operands[3], operands[1]);
3396 /* Generate a cltd if possible and doing so it profitable. */
3397 if (true_regnum (operands[1]) == 0
3398 && true_regnum (operands[2]) == 1
3399 && (optimize_size || TARGET_USE_CLTD))
3401 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3405 emit_move_insn (operands[2], operands[1]);
3406 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3408 emit_move_insn (operands[4], operands[2]);
3412 ;; Extend to register case. Optimize case where source and destination
3413 ;; registers match and cases where we can use cltd.
3415 [(set (match_operand:DI 0 "register_operand" "")
3416 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3417 (clobber (reg:CC FLAGS_REG))
3418 (clobber (match_scratch:SI 2 ""))]
3422 split_di (&operands[0], 1, &operands[3], &operands[4]);
3424 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3425 emit_move_insn (operands[3], operands[1]);
3427 /* Generate a cltd if possible and doing so it profitable. */
3428 if (true_regnum (operands[3]) == 0
3429 && (optimize_size || TARGET_USE_CLTD))
3431 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3435 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3436 emit_move_insn (operands[4], operands[1]);
3438 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3442 (define_insn "extendhisi2"
3443 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3444 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3447 switch (get_attr_prefix_0f (insn))
3450 return "{cwtl|cwde}";
3452 return "movs{wl|x}\t{%1,%0|%0, %1}";
3455 [(set_attr "type" "imovx")
3456 (set_attr "mode" "SI")
3457 (set (attr "prefix_0f")
3458 ;; movsx is short decodable while cwtl is vector decoded.
3459 (if_then_else (and (eq_attr "cpu" "!k6")
3460 (eq_attr "alternative" "0"))
3462 (const_string "1")))
3464 (if_then_else (eq_attr "prefix_0f" "0")
3466 (const_string "1")))])
3468 (define_insn "*extendhisi2_zext"
3469 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3471 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3474 switch (get_attr_prefix_0f (insn))
3477 return "{cwtl|cwde}";
3479 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3482 [(set_attr "type" "imovx")
3483 (set_attr "mode" "SI")
3484 (set (attr "prefix_0f")
3485 ;; movsx is short decodable while cwtl is vector decoded.
3486 (if_then_else (and (eq_attr "cpu" "!k6")
3487 (eq_attr "alternative" "0"))
3489 (const_string "1")))
3491 (if_then_else (eq_attr "prefix_0f" "0")
3493 (const_string "1")))])
3495 (define_insn "extendqihi2"
3496 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3497 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3500 switch (get_attr_prefix_0f (insn))
3503 return "{cbtw|cbw}";
3505 return "movs{bw|x}\t{%1,%0|%0, %1}";
3508 [(set_attr "type" "imovx")
3509 (set_attr "mode" "HI")
3510 (set (attr "prefix_0f")
3511 ;; movsx is short decodable while cwtl is vector decoded.
3512 (if_then_else (and (eq_attr "cpu" "!k6")
3513 (eq_attr "alternative" "0"))
3515 (const_string "1")))
3517 (if_then_else (eq_attr "prefix_0f" "0")
3519 (const_string "1")))])
3521 (define_insn "extendqisi2"
3522 [(set (match_operand:SI 0 "register_operand" "=r")
3523 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3525 "movs{bl|x}\t{%1,%0|%0, %1}"
3526 [(set_attr "type" "imovx")
3527 (set_attr "mode" "SI")])
3529 (define_insn "*extendqisi2_zext"
3530 [(set (match_operand:DI 0 "register_operand" "=r")
3532 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3534 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3535 [(set_attr "type" "imovx")
3536 (set_attr "mode" "SI")])
3538 ;; Conversions between float and double.
3540 ;; These are all no-ops in the model used for the 80387. So just
3543 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3544 (define_insn "*dummy_extendsfdf2"
3545 [(set (match_operand:DF 0 "push_operand" "=<")
3546 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3551 [(set (match_operand:DF 0 "push_operand" "")
3552 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3554 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3555 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3558 [(set (match_operand:DF 0 "push_operand" "")
3559 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3561 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3562 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3564 (define_insn "*dummy_extendsfxf2"
3565 [(set (match_operand:XF 0 "push_operand" "=<")
3566 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3571 [(set (match_operand:XF 0 "push_operand" "")
3572 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3574 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3575 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3576 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3579 [(set (match_operand:XF 0 "push_operand" "")
3580 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3582 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3583 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3584 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3587 [(set (match_operand:XF 0 "push_operand" "")
3588 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3590 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3591 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3592 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3595 [(set (match_operand:XF 0 "push_operand" "")
3596 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3598 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3599 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3600 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3602 (define_expand "extendsfdf2"
3603 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3604 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3605 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3607 /* ??? Needed for compress_float_constant since all fp constants
3608 are LEGITIMATE_CONSTANT_P. */
3609 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3611 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3612 && standard_80387_constant_p (operands[1]) > 0)
3614 operands[1] = simplify_const_unary_operation
3615 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3616 emit_move_insn_1 (operands[0], operands[1]);
3619 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3623 (define_insn "*extendsfdf2_mixed"
3624 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3625 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3626 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3628 switch (which_alternative)
3631 return output_387_reg_move (insn, operands);
3634 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3635 return "fstp%z0\t%y0";
3637 return "fst%z0\t%y0";
3640 return "cvtss2sd\t{%1, %0|%0, %1}";
3646 [(set_attr "type" "fmov,fmov,ssecvt")
3647 (set_attr "mode" "SF,XF,DF")])
3649 (define_insn "*extendsfdf2_sse"
3650 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3651 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3652 "TARGET_SSE2 && TARGET_SSE_MATH"
3653 "cvtss2sd\t{%1, %0|%0, %1}"
3654 [(set_attr "type" "ssecvt")
3655 (set_attr "mode" "DF")])
3657 (define_insn "*extendsfdf2_i387"
3658 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3659 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3662 switch (which_alternative)
3665 return output_387_reg_move (insn, operands);
3668 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3669 return "fstp%z0\t%y0";
3671 return "fst%z0\t%y0";
3677 [(set_attr "type" "fmov")
3678 (set_attr "mode" "SF,XF")])
3680 (define_expand "extendsfxf2"
3681 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3682 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3685 /* ??? Needed for compress_float_constant since all fp constants
3686 are LEGITIMATE_CONSTANT_P. */
3687 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3689 if (standard_80387_constant_p (operands[1]) > 0)
3691 operands[1] = simplify_const_unary_operation
3692 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3693 emit_move_insn_1 (operands[0], operands[1]);
3696 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3700 (define_insn "*extendsfxf2_i387"
3701 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3702 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3705 switch (which_alternative)
3708 return output_387_reg_move (insn, operands);
3711 /* There is no non-popping store to memory for XFmode. So if
3712 we need one, follow the store with a load. */
3713 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3714 return "fstp%z0\t%y0";
3716 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3722 [(set_attr "type" "fmov")
3723 (set_attr "mode" "SF,XF")])
3725 (define_expand "extenddfxf2"
3726 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3727 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3730 /* ??? Needed for compress_float_constant since all fp constants
3731 are LEGITIMATE_CONSTANT_P. */
3732 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3734 if (standard_80387_constant_p (operands[1]) > 0)
3736 operands[1] = simplify_const_unary_operation
3737 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3738 emit_move_insn_1 (operands[0], operands[1]);
3741 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3745 (define_insn "*extenddfxf2_i387"
3746 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3747 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3750 switch (which_alternative)
3753 return output_387_reg_move (insn, operands);
3756 /* There is no non-popping store to memory for XFmode. So if
3757 we need one, follow the store with a load. */
3758 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3759 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3761 return "fstp%z0\t%y0";
3767 [(set_attr "type" "fmov")
3768 (set_attr "mode" "DF,XF")])
3770 ;; %%% This seems bad bad news.
3771 ;; This cannot output into an f-reg because there is no way to be sure
3772 ;; of truncating in that case. Otherwise this is just like a simple move
3773 ;; insn. So we pretend we can output to a reg in order to get better
3774 ;; register preferencing, but we really use a stack slot.
3776 ;; Conversion from DFmode to SFmode.
3778 (define_expand "truncdfsf2"
3779 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3781 (match_operand:DF 1 "nonimmediate_operand" "")))]
3782 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3784 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3786 else if (flag_unsafe_math_optimizations)
3790 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3791 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3796 (define_expand "truncdfsf2_with_temp"
3797 [(parallel [(set (match_operand:SF 0 "" "")
3798 (float_truncate:SF (match_operand:DF 1 "" "")))
3799 (clobber (match_operand:SF 2 "" ""))])]
3802 (define_insn "*truncdfsf_fast_mixed"
3803 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3805 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3806 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3808 switch (which_alternative)
3811 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3812 return "fstp%z0\t%y0";
3814 return "fst%z0\t%y0";
3816 return output_387_reg_move (insn, operands);
3818 return "cvtsd2ss\t{%1, %0|%0, %1}";
3823 [(set_attr "type" "fmov,fmov,ssecvt")
3824 (set_attr "mode" "SF")])
3826 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3827 ;; because nothing we do here is unsafe.
3828 (define_insn "*truncdfsf_fast_sse"
3829 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3831 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3832 "TARGET_SSE2 && TARGET_SSE_MATH"
3833 "cvtsd2ss\t{%1, %0|%0, %1}"
3834 [(set_attr "type" "ssecvt")
3835 (set_attr "mode" "SF")])
3837 (define_insn "*truncdfsf_fast_i387"
3838 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3840 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3841 "TARGET_80387 && flag_unsafe_math_optimizations"
3842 "* return output_387_reg_move (insn, operands);"
3843 [(set_attr "type" "fmov")
3844 (set_attr "mode" "SF")])
3846 (define_insn "*truncdfsf_mixed"
3847 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3849 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3850 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3851 "TARGET_MIX_SSE_I387"
3853 switch (which_alternative)
3856 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3857 return "fstp%z0\t%y0";
3859 return "fst%z0\t%y0";
3863 return "cvtsd2ss\t{%1, %0|%0, %1}";
3868 [(set_attr "type" "fmov,multi,ssecvt")
3869 (set_attr "unit" "*,i387,*")
3870 (set_attr "mode" "SF")])
3872 (define_insn "*truncdfsf_i387"
3873 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3875 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3876 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3879 switch (which_alternative)
3882 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3883 return "fstp%z0\t%y0";
3885 return "fst%z0\t%y0";
3892 [(set_attr "type" "fmov,multi")
3893 (set_attr "unit" "*,i387")
3894 (set_attr "mode" "SF")])
3896 (define_insn "*truncdfsf2_i387_1"
3897 [(set (match_operand:SF 0 "memory_operand" "=m")
3899 (match_operand:DF 1 "register_operand" "f")))]
3901 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3902 && !TARGET_MIX_SSE_I387"
3904 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3905 return "fstp%z0\t%y0";
3907 return "fst%z0\t%y0";
3909 [(set_attr "type" "fmov")
3910 (set_attr "mode" "SF")])
3913 [(set (match_operand:SF 0 "register_operand" "")
3915 (match_operand:DF 1 "fp_register_operand" "")))
3916 (clobber (match_operand 2 "" ""))]
3918 [(set (match_dup 2) (match_dup 1))
3919 (set (match_dup 0) (match_dup 2))]
3921 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3924 ;; Conversion from XFmode to SFmode.
3926 (define_expand "truncxfsf2"
3927 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3929 (match_operand:XF 1 "register_operand" "")))
3930 (clobber (match_dup 2))])]
3933 if (flag_unsafe_math_optimizations)
3935 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3936 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3937 if (reg != operands[0])
3938 emit_move_insn (operands[0], reg);
3942 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3945 (define_insn "*truncxfsf2_mixed"
3946 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3948 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3949 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3952 gcc_assert (!which_alternative);
3953 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3954 return "fstp%z0\t%y0";
3956 return "fst%z0\t%y0";
3958 [(set_attr "type" "fmov,multi,multi,multi")
3959 (set_attr "unit" "*,i387,i387,i387")
3960 (set_attr "mode" "SF")])
3962 (define_insn "truncxfsf2_i387_noop"
3963 [(set (match_operand:SF 0 "register_operand" "=f")
3964 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3965 "TARGET_80387 && flag_unsafe_math_optimizations"
3966 "* return output_387_reg_move (insn, operands);"
3967 [(set_attr "type" "fmov")
3968 (set_attr "mode" "SF")])
3970 (define_insn "*truncxfsf2_i387"
3971 [(set (match_operand:SF 0 "memory_operand" "=m")
3973 (match_operand:XF 1 "register_operand" "f")))]
3976 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3977 return "fstp%z0\t%y0";
3979 return "fst%z0\t%y0";
3981 [(set_attr "type" "fmov")
3982 (set_attr "mode" "SF")])
3985 [(set (match_operand:SF 0 "register_operand" "")
3987 (match_operand:XF 1 "register_operand" "")))
3988 (clobber (match_operand:SF 2 "memory_operand" ""))]
3989 "TARGET_80387 && reload_completed"
3990 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3991 (set (match_dup 0) (match_dup 2))]
3995 [(set (match_operand:SF 0 "memory_operand" "")
3997 (match_operand:XF 1 "register_operand" "")))
3998 (clobber (match_operand:SF 2 "memory_operand" ""))]
4000 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
4003 ;; Conversion from XFmode to DFmode.
4005 (define_expand "truncxfdf2"
4006 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
4008 (match_operand:XF 1 "register_operand" "")))
4009 (clobber (match_dup 2))])]
4012 if (flag_unsafe_math_optimizations)
4014 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
4015 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
4016 if (reg != operands[0])
4017 emit_move_insn (operands[0], reg);
4021 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
4024 (define_insn "*truncxfdf2_mixed"
4025 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
4027 (match_operand:XF 1 "register_operand" "f,f,f,f")))
4028 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
4031 gcc_assert (!which_alternative);
4032 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4033 return "fstp%z0\t%y0";
4035 return "fst%z0\t%y0";
4037 [(set_attr "type" "fmov,multi,multi,multi")
4038 (set_attr "unit" "*,i387,i387,i387")
4039 (set_attr "mode" "DF")])
4041 (define_insn "truncxfdf2_i387_noop"
4042 [(set (match_operand:DF 0 "register_operand" "=f")
4043 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4044 "TARGET_80387 && flag_unsafe_math_optimizations"
4045 "* return output_387_reg_move (insn, operands);"
4046 [(set_attr "type" "fmov")
4047 (set_attr "mode" "DF")])
4049 (define_insn "*truncxfdf2_i387"
4050 [(set (match_operand:DF 0 "memory_operand" "=m")
4052 (match_operand:XF 1 "register_operand" "f")))]
4055 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4056 return "fstp%z0\t%y0";
4058 return "fst%z0\t%y0";
4060 [(set_attr "type" "fmov")
4061 (set_attr "mode" "DF")])
4064 [(set (match_operand:DF 0 "register_operand" "")
4066 (match_operand:XF 1 "register_operand" "")))
4067 (clobber (match_operand:DF 2 "memory_operand" ""))]
4068 "TARGET_80387 && reload_completed"
4069 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4070 (set (match_dup 0) (match_dup 2))]
4074 [(set (match_operand:DF 0 "memory_operand" "")
4076 (match_operand:XF 1 "register_operand" "")))
4077 (clobber (match_operand:DF 2 "memory_operand" ""))]
4079 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4082 ;; Signed conversion to DImode.
4084 (define_expand "fix_truncxfdi2"
4085 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4086 (fix:DI (match_operand:XF 1 "register_operand" "")))
4087 (clobber (reg:CC FLAGS_REG))])]
4092 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4097 (define_expand "fix_trunc<mode>di2"
4098 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4099 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4100 (clobber (reg:CC FLAGS_REG))])]
4101 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4104 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4106 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4109 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4111 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4112 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4113 if (out != operands[0])
4114 emit_move_insn (operands[0], out);
4119 ;; Signed conversion to SImode.
4121 (define_expand "fix_truncxfsi2"
4122 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4123 (fix:SI (match_operand:XF 1 "register_operand" "")))
4124 (clobber (reg:CC FLAGS_REG))])]
4129 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4134 (define_expand "fix_trunc<mode>si2"
4135 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4136 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4137 (clobber (reg:CC FLAGS_REG))])]
4138 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4141 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4143 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4146 if (SSE_FLOAT_MODE_P (<MODE>mode))
4148 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4149 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4150 if (out != operands[0])
4151 emit_move_insn (operands[0], out);
4156 ;; Signed conversion to HImode.
4158 (define_expand "fix_trunc<mode>hi2"
4159 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4160 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4161 (clobber (reg:CC FLAGS_REG))])]
4163 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4167 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4172 ;; When SSE is available, it is always faster to use it!
4173 (define_insn "fix_truncsfdi_sse"
4174 [(set (match_operand:DI 0 "register_operand" "=r,r")
4175 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4176 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4177 "cvttss2si{q}\t{%1, %0|%0, %1}"
4178 [(set_attr "type" "sseicvt")
4179 (set_attr "mode" "SF")
4180 (set_attr "athlon_decode" "double,vector")])
4182 (define_insn "fix_truncdfdi_sse"
4183 [(set (match_operand:DI 0 "register_operand" "=r,r")
4184 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4185 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4186 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4187 [(set_attr "type" "sseicvt")
4188 (set_attr "mode" "DF")
4189 (set_attr "athlon_decode" "double,vector")])
4191 (define_insn "fix_truncsfsi_sse"
4192 [(set (match_operand:SI 0 "register_operand" "=r,r")
4193 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4194 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4195 "cvttss2si\t{%1, %0|%0, %1}"
4196 [(set_attr "type" "sseicvt")
4197 (set_attr "mode" "DF")
4198 (set_attr "athlon_decode" "double,vector")])
4200 (define_insn "fix_truncdfsi_sse"
4201 [(set (match_operand:SI 0 "register_operand" "=r,r")
4202 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4203 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4204 "cvttsd2si\t{%1, %0|%0, %1}"
4205 [(set_attr "type" "sseicvt")
4206 (set_attr "mode" "DF")
4207 (set_attr "athlon_decode" "double,vector")])
4209 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4211 [(set (match_operand:DF 0 "register_operand" "")
4212 (match_operand:DF 1 "memory_operand" ""))
4213 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4214 (fix:SSEMODEI24 (match_dup 0)))]
4216 && peep2_reg_dead_p (2, operands[0])"
4217 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4221 [(set (match_operand:SF 0 "register_operand" "")
4222 (match_operand:SF 1 "memory_operand" ""))
4223 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4224 (fix:SSEMODEI24 (match_dup 0)))]
4226 && peep2_reg_dead_p (2, operands[0])"
4227 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4230 ;; Avoid vector decoded forms of the instruction.
4232 [(match_scratch:DF 2 "Y")
4233 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4234 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4235 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4236 [(set (match_dup 2) (match_dup 1))
4237 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4241 [(match_scratch:SF 2 "x")
4242 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4243 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4244 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4245 [(set (match_dup 2) (match_dup 1))
4246 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4249 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4250 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4251 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4253 && FLOAT_MODE_P (GET_MODE (operands[1]))
4254 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4255 && (TARGET_64BIT || <MODE>mode != DImode))
4257 && !(reload_completed || reload_in_progress)"
4262 if (memory_operand (operands[0], VOIDmode))
4263 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4266 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4267 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4273 [(set_attr "type" "fisttp")
4274 (set_attr "mode" "<MODE>")])
4276 (define_insn "fix_trunc<mode>_i387_fisttp"
4277 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4278 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4279 (clobber (match_scratch:XF 2 "=&1f"))]
4281 && FLOAT_MODE_P (GET_MODE (operands[1]))
4282 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4283 && (TARGET_64BIT || <MODE>mode != DImode))
4284 && TARGET_SSE_MATH)"
4285 "* return output_fix_trunc (insn, operands, 1);"
4286 [(set_attr "type" "fisttp")
4287 (set_attr "mode" "<MODE>")])
4289 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4290 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4291 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4292 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4293 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4295 && FLOAT_MODE_P (GET_MODE (operands[1]))
4296 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4297 && (TARGET_64BIT || <MODE>mode != DImode))
4298 && TARGET_SSE_MATH)"
4300 [(set_attr "type" "fisttp")
4301 (set_attr "mode" "<MODE>")])
4304 [(set (match_operand:X87MODEI 0 "register_operand" "")
4305 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4306 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4307 (clobber (match_scratch 3 ""))]
4309 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4310 (clobber (match_dup 3))])
4311 (set (match_dup 0) (match_dup 2))]
4315 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4316 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4317 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4318 (clobber (match_scratch 3 ""))]
4320 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4321 (clobber (match_dup 3))])]
4324 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4325 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4326 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4327 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4328 ;; function in i386.c.
4329 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4330 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4331 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4332 (clobber (reg:CC FLAGS_REG))]
4333 "TARGET_80387 && !TARGET_FISTTP
4334 && FLOAT_MODE_P (GET_MODE (operands[1]))
4335 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4336 && (TARGET_64BIT || <MODE>mode != DImode))
4337 && !(reload_completed || reload_in_progress)"
4342 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4344 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4345 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4346 if (memory_operand (operands[0], VOIDmode))
4347 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4348 operands[2], operands[3]));
4351 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4352 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4353 operands[2], operands[3],
4358 [(set_attr "type" "fistp")
4359 (set_attr "i387_cw" "trunc")
4360 (set_attr "mode" "<MODE>")])
4362 (define_insn "fix_truncdi_i387"
4363 [(set (match_operand:DI 0 "memory_operand" "=m")
4364 (fix:DI (match_operand 1 "register_operand" "f")))
4365 (use (match_operand:HI 2 "memory_operand" "m"))
4366 (use (match_operand:HI 3 "memory_operand" "m"))
4367 (clobber (match_scratch:XF 4 "=&1f"))]
4368 "TARGET_80387 && !TARGET_FISTTP
4369 && FLOAT_MODE_P (GET_MODE (operands[1]))
4370 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4371 "* return output_fix_trunc (insn, operands, 0);"
4372 [(set_attr "type" "fistp")
4373 (set_attr "i387_cw" "trunc")
4374 (set_attr "mode" "DI")])
4376 (define_insn "fix_truncdi_i387_with_temp"
4377 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4378 (fix:DI (match_operand 1 "register_operand" "f,f")))
4379 (use (match_operand:HI 2 "memory_operand" "m,m"))
4380 (use (match_operand:HI 3 "memory_operand" "m,m"))
4381 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4382 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4383 "TARGET_80387 && !TARGET_FISTTP
4384 && FLOAT_MODE_P (GET_MODE (operands[1]))
4385 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4387 [(set_attr "type" "fistp")
4388 (set_attr "i387_cw" "trunc")
4389 (set_attr "mode" "DI")])
4392 [(set (match_operand:DI 0 "register_operand" "")
4393 (fix:DI (match_operand 1 "register_operand" "")))
4394 (use (match_operand:HI 2 "memory_operand" ""))
4395 (use (match_operand:HI 3 "memory_operand" ""))
4396 (clobber (match_operand:DI 4 "memory_operand" ""))
4397 (clobber (match_scratch 5 ""))]
4399 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4402 (clobber (match_dup 5))])
4403 (set (match_dup 0) (match_dup 4))]
4407 [(set (match_operand:DI 0 "memory_operand" "")
4408 (fix:DI (match_operand 1 "register_operand" "")))
4409 (use (match_operand:HI 2 "memory_operand" ""))
4410 (use (match_operand:HI 3 "memory_operand" ""))
4411 (clobber (match_operand:DI 4 "memory_operand" ""))
4412 (clobber (match_scratch 5 ""))]
4414 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4417 (clobber (match_dup 5))])]
4420 (define_insn "fix_trunc<mode>_i387"
4421 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4422 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4423 (use (match_operand:HI 2 "memory_operand" "m"))
4424 (use (match_operand:HI 3 "memory_operand" "m"))]
4425 "TARGET_80387 && !TARGET_FISTTP
4426 && FLOAT_MODE_P (GET_MODE (operands[1]))
4427 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4428 "* return output_fix_trunc (insn, operands, 0);"
4429 [(set_attr "type" "fistp")
4430 (set_attr "i387_cw" "trunc")
4431 (set_attr "mode" "<MODE>")])
4433 (define_insn "fix_trunc<mode>_i387_with_temp"
4434 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4435 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4436 (use (match_operand:HI 2 "memory_operand" "m,m"))
4437 (use (match_operand:HI 3 "memory_operand" "m,m"))
4438 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4439 "TARGET_80387 && !TARGET_FISTTP
4440 && FLOAT_MODE_P (GET_MODE (operands[1]))
4441 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4443 [(set_attr "type" "fistp")
4444 (set_attr "i387_cw" "trunc")
4445 (set_attr "mode" "<MODE>")])
4448 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4449 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4450 (use (match_operand:HI 2 "memory_operand" ""))
4451 (use (match_operand:HI 3 "memory_operand" ""))
4452 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4454 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4456 (use (match_dup 3))])
4457 (set (match_dup 0) (match_dup 4))]
4461 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4462 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4463 (use (match_operand:HI 2 "memory_operand" ""))
4464 (use (match_operand:HI 3 "memory_operand" ""))
4465 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4467 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4469 (use (match_dup 3))])]
4472 (define_insn "x86_fnstcw_1"
4473 [(set (match_operand:HI 0 "memory_operand" "=m")
4474 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4477 [(set_attr "length" "2")
4478 (set_attr "mode" "HI")
4479 (set_attr "unit" "i387")])
4481 (define_insn "x86_fldcw_1"
4482 [(set (reg:HI FPCR_REG)
4483 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4486 [(set_attr "length" "2")
4487 (set_attr "mode" "HI")
4488 (set_attr "unit" "i387")
4489 (set_attr "athlon_decode" "vector")])
4491 ;; Conversion between fixed point and floating point.
4493 ;; Even though we only accept memory inputs, the backend _really_
4494 ;; wants to be able to do this between registers.
4496 (define_expand "floathisf2"
4497 [(set (match_operand:SF 0 "register_operand" "")
4498 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4499 "TARGET_80387 || TARGET_SSE_MATH"
4501 if (TARGET_SSE_MATH)
4503 emit_insn (gen_floatsisf2 (operands[0],
4504 convert_to_mode (SImode, operands[1], 0)));
4509 (define_insn "*floathisf2_i387"
4510 [(set (match_operand:SF 0 "register_operand" "=f,f")
4511 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4512 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4516 [(set_attr "type" "fmov,multi")
4517 (set_attr "mode" "SF")
4518 (set_attr "unit" "*,i387")
4519 (set_attr "fp_int_src" "true")])
4521 (define_expand "floatsisf2"
4522 [(set (match_operand:SF 0 "register_operand" "")
4523 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4524 "TARGET_80387 || TARGET_SSE_MATH"
4527 (define_insn "*floatsisf2_mixed"
4528 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4529 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4530 "TARGET_MIX_SSE_I387"
4534 cvtsi2ss\t{%1, %0|%0, %1}
4535 cvtsi2ss\t{%1, %0|%0, %1}"
4536 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4537 (set_attr "mode" "SF")
4538 (set_attr "unit" "*,i387,*,*")
4539 (set_attr "athlon_decode" "*,*,vector,double")
4540 (set_attr "fp_int_src" "true")])
4542 (define_insn "*floatsisf2_sse"
4543 [(set (match_operand:SF 0 "register_operand" "=x,x")
4544 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4546 "cvtsi2ss\t{%1, %0|%0, %1}"
4547 [(set_attr "type" "sseicvt")
4548 (set_attr "mode" "SF")
4549 (set_attr "athlon_decode" "vector,double")
4550 (set_attr "fp_int_src" "true")])
4552 (define_insn "*floatsisf2_i387"
4553 [(set (match_operand:SF 0 "register_operand" "=f,f")
4554 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4559 [(set_attr "type" "fmov,multi")
4560 (set_attr "mode" "SF")
4561 (set_attr "unit" "*,i387")
4562 (set_attr "fp_int_src" "true")])
4564 (define_expand "floatdisf2"
4565 [(set (match_operand:SF 0 "register_operand" "")
4566 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4567 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4570 (define_insn "*floatdisf2_mixed"
4571 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4572 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4573 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4577 cvtsi2ss{q}\t{%1, %0|%0, %1}
4578 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4579 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4580 (set_attr "mode" "SF")
4581 (set_attr "unit" "*,i387,*,*")
4582 (set_attr "athlon_decode" "*,*,vector,double")
4583 (set_attr "fp_int_src" "true")])
4585 (define_insn "*floatdisf2_sse"
4586 [(set (match_operand:SF 0 "register_operand" "=x,x")
4587 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4588 "TARGET_64BIT && TARGET_SSE_MATH"
4589 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4590 [(set_attr "type" "sseicvt")
4591 (set_attr "mode" "SF")
4592 (set_attr "athlon_decode" "vector,double")
4593 (set_attr "fp_int_src" "true")])
4595 (define_insn "*floatdisf2_i387"
4596 [(set (match_operand:SF 0 "register_operand" "=f,f")
4597 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4602 [(set_attr "type" "fmov,multi")
4603 (set_attr "mode" "SF")
4604 (set_attr "unit" "*,i387")
4605 (set_attr "fp_int_src" "true")])
4607 (define_expand "floathidf2"
4608 [(set (match_operand:DF 0 "register_operand" "")
4609 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4610 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4612 if (TARGET_SSE2 && TARGET_SSE_MATH)
4614 emit_insn (gen_floatsidf2 (operands[0],
4615 convert_to_mode (SImode, operands[1], 0)));
4620 (define_insn "*floathidf2_i387"
4621 [(set (match_operand:DF 0 "register_operand" "=f,f")
4622 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4623 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4627 [(set_attr "type" "fmov,multi")
4628 (set_attr "mode" "DF")
4629 (set_attr "unit" "*,i387")
4630 (set_attr "fp_int_src" "true")])
4632 (define_expand "floatsidf2"
4633 [(set (match_operand:DF 0 "register_operand" "")
4634 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4635 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4638 (define_insn "*floatsidf2_mixed"
4639 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4640 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4641 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4645 cvtsi2sd\t{%1, %0|%0, %1}
4646 cvtsi2sd\t{%1, %0|%0, %1}"
4647 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4648 (set_attr "mode" "DF")
4649 (set_attr "unit" "*,i387,*,*")
4650 (set_attr "athlon_decode" "*,*,double,direct")
4651 (set_attr "fp_int_src" "true")])
4653 (define_insn "*floatsidf2_sse"
4654 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4655 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4656 "TARGET_SSE2 && TARGET_SSE_MATH"
4657 "cvtsi2sd\t{%1, %0|%0, %1}"
4658 [(set_attr "type" "sseicvt")
4659 (set_attr "mode" "DF")
4660 (set_attr "athlon_decode" "double,direct")
4661 (set_attr "fp_int_src" "true")])
4663 (define_insn "*floatsidf2_i387"
4664 [(set (match_operand:DF 0 "register_operand" "=f,f")
4665 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4670 [(set_attr "type" "fmov,multi")
4671 (set_attr "mode" "DF")
4672 (set_attr "unit" "*,i387")
4673 (set_attr "fp_int_src" "true")])
4675 (define_expand "floatdidf2"
4676 [(set (match_operand:DF 0 "register_operand" "")
4677 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4678 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4681 (define_insn "*floatdidf2_mixed"
4682 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4683 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4684 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4688 cvtsi2sd{q}\t{%1, %0|%0, %1}
4689 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4690 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4691 (set_attr "mode" "DF")
4692 (set_attr "unit" "*,i387,*,*")
4693 (set_attr "athlon_decode" "*,*,double,direct")
4694 (set_attr "fp_int_src" "true")])
4696 (define_insn "*floatdidf2_sse"
4697 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4698 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4699 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4700 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4701 [(set_attr "type" "sseicvt")
4702 (set_attr "mode" "DF")
4703 (set_attr "athlon_decode" "double,direct")
4704 (set_attr "fp_int_src" "true")])
4706 (define_insn "*floatdidf2_i387"
4707 [(set (match_operand:DF 0 "register_operand" "=f,f")
4708 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4713 [(set_attr "type" "fmov,multi")
4714 (set_attr "mode" "DF")
4715 (set_attr "unit" "*,i387")
4716 (set_attr "fp_int_src" "true")])
4718 (define_insn "floathixf2"
4719 [(set (match_operand:XF 0 "register_operand" "=f,f")
4720 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4725 [(set_attr "type" "fmov,multi")
4726 (set_attr "mode" "XF")
4727 (set_attr "unit" "*,i387")
4728 (set_attr "fp_int_src" "true")])
4730 (define_insn "floatsixf2"
4731 [(set (match_operand:XF 0 "register_operand" "=f,f")
4732 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4737 [(set_attr "type" "fmov,multi")
4738 (set_attr "mode" "XF")
4739 (set_attr "unit" "*,i387")
4740 (set_attr "fp_int_src" "true")])
4742 (define_insn "floatdixf2"
4743 [(set (match_operand:XF 0 "register_operand" "=f,f")
4744 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4749 [(set_attr "type" "fmov,multi")
4750 (set_attr "mode" "XF")
4751 (set_attr "unit" "*,i387")
4752 (set_attr "fp_int_src" "true")])
4754 ;; %%% Kill these when reload knows how to do it.
4756 [(set (match_operand 0 "fp_register_operand" "")
4757 (float (match_operand 1 "register_operand" "")))]
4760 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4763 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4764 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4765 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4766 ix86_free_from_memory (GET_MODE (operands[1]));
4770 (define_expand "floatunssisf2"
4771 [(use (match_operand:SF 0 "register_operand" ""))
4772 (use (match_operand:SI 1 "register_operand" ""))]
4773 "!TARGET_64BIT && TARGET_SSE_MATH"
4774 "x86_emit_floatuns (operands); DONE;")
4776 (define_expand "floatunsdisf2"
4777 [(use (match_operand:SF 0 "register_operand" ""))
4778 (use (match_operand:DI 1 "register_operand" ""))]
4779 "TARGET_64BIT && TARGET_SSE_MATH"
4780 "x86_emit_floatuns (operands); DONE;")
4782 (define_expand "floatunsdidf2"
4783 [(use (match_operand:DF 0 "register_operand" ""))
4784 (use (match_operand:DI 1 "register_operand" ""))]
4785 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4786 "x86_emit_floatuns (operands); DONE;")
4788 ;; SSE extract/set expanders
4793 ;; %%% splits for addditi3
4795 (define_expand "addti3"
4796 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4797 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4798 (match_operand:TI 2 "x86_64_general_operand" "")))
4799 (clobber (reg:CC FLAGS_REG))]
4801 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4803 (define_insn "*addti3_1"
4804 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4805 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4806 (match_operand:TI 2 "general_operand" "roiF,riF")))
4807 (clobber (reg:CC FLAGS_REG))]
4808 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4812 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4813 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4814 (match_operand:TI 2 "general_operand" "")))
4815 (clobber (reg:CC FLAGS_REG))]
4816 "TARGET_64BIT && reload_completed"
4817 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4819 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4820 (parallel [(set (match_dup 3)
4821 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4824 (clobber (reg:CC FLAGS_REG))])]
4825 "split_ti (operands+0, 1, operands+0, operands+3);
4826 split_ti (operands+1, 1, operands+1, operands+4);
4827 split_ti (operands+2, 1, operands+2, operands+5);")
4829 ;; %%% splits for addsidi3
4830 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4831 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4832 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4834 (define_expand "adddi3"
4835 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4836 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4837 (match_operand:DI 2 "x86_64_general_operand" "")))
4838 (clobber (reg:CC FLAGS_REG))]
4840 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4842 (define_insn "*adddi3_1"
4843 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4844 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4845 (match_operand:DI 2 "general_operand" "roiF,riF")))
4846 (clobber (reg:CC FLAGS_REG))]
4847 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4851 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4852 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4853 (match_operand:DI 2 "general_operand" "")))
4854 (clobber (reg:CC FLAGS_REG))]
4855 "!TARGET_64BIT && reload_completed"
4856 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4858 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4859 (parallel [(set (match_dup 3)
4860 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4863 (clobber (reg:CC FLAGS_REG))])]
4864 "split_di (operands+0, 1, operands+0, operands+3);
4865 split_di (operands+1, 1, operands+1, operands+4);
4866 split_di (operands+2, 1, operands+2, operands+5);")
4868 (define_insn "adddi3_carry_rex64"
4869 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4870 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4871 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4872 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4873 (clobber (reg:CC FLAGS_REG))]
4874 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4875 "adc{q}\t{%2, %0|%0, %2}"
4876 [(set_attr "type" "alu")
4877 (set_attr "pent_pair" "pu")
4878 (set_attr "mode" "DI")])
4880 (define_insn "*adddi3_cc_rex64"
4881 [(set (reg:CC FLAGS_REG)
4882 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4883 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4885 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4886 (plus:DI (match_dup 1) (match_dup 2)))]
4887 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4888 "add{q}\t{%2, %0|%0, %2}"
4889 [(set_attr "type" "alu")
4890 (set_attr "mode" "DI")])
4892 (define_insn "addqi3_carry"
4893 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4894 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4895 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4896 (match_operand:QI 2 "general_operand" "qi,qm")))
4897 (clobber (reg:CC FLAGS_REG))]
4898 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4899 "adc{b}\t{%2, %0|%0, %2}"
4900 [(set_attr "type" "alu")
4901 (set_attr "pent_pair" "pu")
4902 (set_attr "mode" "QI")])
4904 (define_insn "addhi3_carry"
4905 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4906 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4907 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4908 (match_operand:HI 2 "general_operand" "ri,rm")))
4909 (clobber (reg:CC FLAGS_REG))]
4910 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4911 "adc{w}\t{%2, %0|%0, %2}"
4912 [(set_attr "type" "alu")
4913 (set_attr "pent_pair" "pu")
4914 (set_attr "mode" "HI")])
4916 (define_insn "addsi3_carry"
4917 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4918 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4919 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4920 (match_operand:SI 2 "general_operand" "ri,rm")))
4921 (clobber (reg:CC FLAGS_REG))]
4922 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4923 "adc{l}\t{%2, %0|%0, %2}"
4924 [(set_attr "type" "alu")
4925 (set_attr "pent_pair" "pu")
4926 (set_attr "mode" "SI")])
4928 (define_insn "*addsi3_carry_zext"
4929 [(set (match_operand:DI 0 "register_operand" "=r")
4931 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4932 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4933 (match_operand:SI 2 "general_operand" "rim"))))
4934 (clobber (reg:CC FLAGS_REG))]
4935 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4936 "adc{l}\t{%2, %k0|%k0, %2}"
4937 [(set_attr "type" "alu")
4938 (set_attr "pent_pair" "pu")
4939 (set_attr "mode" "SI")])
4941 (define_insn "*addsi3_cc"
4942 [(set (reg:CC FLAGS_REG)
4943 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4944 (match_operand:SI 2 "general_operand" "ri,rm")]
4946 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4947 (plus:SI (match_dup 1) (match_dup 2)))]
4948 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4949 "add{l}\t{%2, %0|%0, %2}"
4950 [(set_attr "type" "alu")
4951 (set_attr "mode" "SI")])
4953 (define_insn "addqi3_cc"
4954 [(set (reg:CC FLAGS_REG)
4955 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4956 (match_operand:QI 2 "general_operand" "qi,qm")]
4958 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4959 (plus:QI (match_dup 1) (match_dup 2)))]
4960 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4961 "add{b}\t{%2, %0|%0, %2}"
4962 [(set_attr "type" "alu")
4963 (set_attr "mode" "QI")])
4965 (define_expand "addsi3"
4966 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4967 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4968 (match_operand:SI 2 "general_operand" "")))
4969 (clobber (reg:CC FLAGS_REG))])]
4971 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4973 (define_insn "*lea_1"
4974 [(set (match_operand:SI 0 "register_operand" "=r")
4975 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4977 "lea{l}\t{%a1, %0|%0, %a1}"
4978 [(set_attr "type" "lea")
4979 (set_attr "mode" "SI")])
4981 (define_insn "*lea_1_rex64"
4982 [(set (match_operand:SI 0 "register_operand" "=r")
4983 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4985 "lea{l}\t{%a1, %0|%0, %a1}"
4986 [(set_attr "type" "lea")
4987 (set_attr "mode" "SI")])
4989 (define_insn "*lea_1_zext"
4990 [(set (match_operand:DI 0 "register_operand" "=r")
4992 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4994 "lea{l}\t{%a1, %k0|%k0, %a1}"
4995 [(set_attr "type" "lea")
4996 (set_attr "mode" "SI")])
4998 (define_insn "*lea_2_rex64"
4999 [(set (match_operand:DI 0 "register_operand" "=r")
5000 (match_operand:DI 1 "no_seg_address_operand" "p"))]
5002 "lea{q}\t{%a1, %0|%0, %a1}"
5003 [(set_attr "type" "lea")
5004 (set_attr "mode" "DI")])
5006 ;; The lea patterns for non-Pmodes needs to be matched by several
5007 ;; insns converted to real lea by splitters.
5009 (define_insn_and_split "*lea_general_1"
5010 [(set (match_operand 0 "register_operand" "=r")
5011 (plus (plus (match_operand 1 "index_register_operand" "l")
5012 (match_operand 2 "register_operand" "r"))
5013 (match_operand 3 "immediate_operand" "i")))]
5014 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5015 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5016 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5017 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5018 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5019 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5020 || GET_MODE (operands[3]) == VOIDmode)"
5022 "&& reload_completed"
5026 operands[0] = gen_lowpart (SImode, operands[0]);
5027 operands[1] = gen_lowpart (Pmode, operands[1]);
5028 operands[2] = gen_lowpart (Pmode, operands[2]);
5029 operands[3] = gen_lowpart (Pmode, operands[3]);
5030 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5032 if (Pmode != SImode)
5033 pat = gen_rtx_SUBREG (SImode, pat, 0);
5034 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5037 [(set_attr "type" "lea")
5038 (set_attr "mode" "SI")])
5040 (define_insn_and_split "*lea_general_1_zext"
5041 [(set (match_operand:DI 0 "register_operand" "=r")
5043 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5044 (match_operand:SI 2 "register_operand" "r"))
5045 (match_operand:SI 3 "immediate_operand" "i"))))]
5048 "&& reload_completed"
5050 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5052 (match_dup 3)) 0)))]
5054 operands[1] = gen_lowpart (Pmode, operands[1]);
5055 operands[2] = gen_lowpart (Pmode, operands[2]);
5056 operands[3] = gen_lowpart (Pmode, operands[3]);
5058 [(set_attr "type" "lea")
5059 (set_attr "mode" "SI")])
5061 (define_insn_and_split "*lea_general_2"
5062 [(set (match_operand 0 "register_operand" "=r")
5063 (plus (mult (match_operand 1 "index_register_operand" "l")
5064 (match_operand 2 "const248_operand" "i"))
5065 (match_operand 3 "nonmemory_operand" "ri")))]
5066 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5067 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5068 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5069 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5070 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5071 || GET_MODE (operands[3]) == VOIDmode)"
5073 "&& reload_completed"
5077 operands[0] = gen_lowpart (SImode, operands[0]);
5078 operands[1] = gen_lowpart (Pmode, operands[1]);
5079 operands[3] = gen_lowpart (Pmode, operands[3]);
5080 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5082 if (Pmode != SImode)
5083 pat = gen_rtx_SUBREG (SImode, pat, 0);
5084 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5087 [(set_attr "type" "lea")
5088 (set_attr "mode" "SI")])
5090 (define_insn_and_split "*lea_general_2_zext"
5091 [(set (match_operand:DI 0 "register_operand" "=r")
5093 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5094 (match_operand:SI 2 "const248_operand" "n"))
5095 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5098 "&& reload_completed"
5100 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5102 (match_dup 3)) 0)))]
5104 operands[1] = gen_lowpart (Pmode, operands[1]);
5105 operands[3] = gen_lowpart (Pmode, operands[3]);
5107 [(set_attr "type" "lea")
5108 (set_attr "mode" "SI")])
5110 (define_insn_and_split "*lea_general_3"
5111 [(set (match_operand 0 "register_operand" "=r")
5112 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5113 (match_operand 2 "const248_operand" "i"))
5114 (match_operand 3 "register_operand" "r"))
5115 (match_operand 4 "immediate_operand" "i")))]
5116 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5117 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5118 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5119 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5120 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5122 "&& reload_completed"
5126 operands[0] = gen_lowpart (SImode, operands[0]);
5127 operands[1] = gen_lowpart (Pmode, operands[1]);
5128 operands[3] = gen_lowpart (Pmode, operands[3]);
5129 operands[4] = gen_lowpart (Pmode, operands[4]);
5130 pat = gen_rtx_PLUS (Pmode,
5131 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5135 if (Pmode != SImode)
5136 pat = gen_rtx_SUBREG (SImode, pat, 0);
5137 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5140 [(set_attr "type" "lea")
5141 (set_attr "mode" "SI")])
5143 (define_insn_and_split "*lea_general_3_zext"
5144 [(set (match_operand:DI 0 "register_operand" "=r")
5146 (plus:SI (plus:SI (mult:SI
5147 (match_operand:SI 1 "index_register_operand" "l")
5148 (match_operand:SI 2 "const248_operand" "n"))
5149 (match_operand:SI 3 "register_operand" "r"))
5150 (match_operand:SI 4 "immediate_operand" "i"))))]
5153 "&& reload_completed"
5155 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5158 (match_dup 4)) 0)))]
5160 operands[1] = gen_lowpart (Pmode, operands[1]);
5161 operands[3] = gen_lowpart (Pmode, operands[3]);
5162 operands[4] = gen_lowpart (Pmode, operands[4]);
5164 [(set_attr "type" "lea")
5165 (set_attr "mode" "SI")])
5167 (define_insn "*adddi_1_rex64"
5168 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5169 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5170 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5171 (clobber (reg:CC FLAGS_REG))]
5172 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5174 switch (get_attr_type (insn))
5177 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5178 return "lea{q}\t{%a2, %0|%0, %a2}";
5181 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5182 if (operands[2] == const1_rtx)
5183 return "inc{q}\t%0";
5186 gcc_assert (operands[2] == constm1_rtx);
5187 return "dec{q}\t%0";
5191 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5193 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5194 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5195 if (GET_CODE (operands[2]) == CONST_INT
5196 /* Avoid overflows. */
5197 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5198 && (INTVAL (operands[2]) == 128
5199 || (INTVAL (operands[2]) < 0
5200 && INTVAL (operands[2]) != -128)))
5202 operands[2] = GEN_INT (-INTVAL (operands[2]));
5203 return "sub{q}\t{%2, %0|%0, %2}";
5205 return "add{q}\t{%2, %0|%0, %2}";
5209 (cond [(eq_attr "alternative" "2")
5210 (const_string "lea")
5211 ; Current assemblers are broken and do not allow @GOTOFF in
5212 ; ought but a memory context.
5213 (match_operand:DI 2 "pic_symbolic_operand" "")
5214 (const_string "lea")
5215 (match_operand:DI 2 "incdec_operand" "")
5216 (const_string "incdec")
5218 (const_string "alu")))
5219 (set_attr "mode" "DI")])
5221 ;; Convert lea to the lea pattern to avoid flags dependency.
5223 [(set (match_operand:DI 0 "register_operand" "")
5224 (plus:DI (match_operand:DI 1 "register_operand" "")
5225 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5226 (clobber (reg:CC FLAGS_REG))]
5227 "TARGET_64BIT && reload_completed
5228 && true_regnum (operands[0]) != true_regnum (operands[1])"
5230 (plus:DI (match_dup 1)
5234 (define_insn "*adddi_2_rex64"
5235 [(set (reg FLAGS_REG)
5237 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5238 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5240 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5241 (plus:DI (match_dup 1) (match_dup 2)))]
5242 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5243 && ix86_binary_operator_ok (PLUS, DImode, operands)
5244 /* Current assemblers are broken and do not allow @GOTOFF in
5245 ought but a memory context. */
5246 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5248 switch (get_attr_type (insn))
5251 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5252 if (operands[2] == const1_rtx)
5253 return "inc{q}\t%0";
5256 gcc_assert (operands[2] == constm1_rtx);
5257 return "dec{q}\t%0";
5261 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5262 /* ???? We ought to handle there the 32bit case too
5263 - do we need new constraint? */
5264 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5265 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5266 if (GET_CODE (operands[2]) == CONST_INT
5267 /* Avoid overflows. */
5268 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5269 && (INTVAL (operands[2]) == 128
5270 || (INTVAL (operands[2]) < 0
5271 && INTVAL (operands[2]) != -128)))
5273 operands[2] = GEN_INT (-INTVAL (operands[2]));
5274 return "sub{q}\t{%2, %0|%0, %2}";
5276 return "add{q}\t{%2, %0|%0, %2}";
5280 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5281 (const_string "incdec")
5282 (const_string "alu")))
5283 (set_attr "mode" "DI")])
5285 (define_insn "*adddi_3_rex64"
5286 [(set (reg FLAGS_REG)
5287 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5288 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5289 (clobber (match_scratch:DI 0 "=r"))]
5291 && ix86_match_ccmode (insn, CCZmode)
5292 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5293 /* Current assemblers are broken and do not allow @GOTOFF in
5294 ought but a memory context. */
5295 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5297 switch (get_attr_type (insn))
5300 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5301 if (operands[2] == const1_rtx)
5302 return "inc{q}\t%0";
5305 gcc_assert (operands[2] == constm1_rtx);
5306 return "dec{q}\t%0";
5310 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5311 /* ???? We ought to handle there the 32bit case too
5312 - do we need new constraint? */
5313 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5314 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5315 if (GET_CODE (operands[2]) == CONST_INT
5316 /* Avoid overflows. */
5317 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5318 && (INTVAL (operands[2]) == 128
5319 || (INTVAL (operands[2]) < 0
5320 && INTVAL (operands[2]) != -128)))
5322 operands[2] = GEN_INT (-INTVAL (operands[2]));
5323 return "sub{q}\t{%2, %0|%0, %2}";
5325 return "add{q}\t{%2, %0|%0, %2}";
5329 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5330 (const_string "incdec")
5331 (const_string "alu")))
5332 (set_attr "mode" "DI")])
5334 ; For comparisons against 1, -1 and 128, we may generate better code
5335 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5336 ; is matched then. We can't accept general immediate, because for
5337 ; case of overflows, the result is messed up.
5338 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5340 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5341 ; only for comparisons not depending on it.
5342 (define_insn "*adddi_4_rex64"
5343 [(set (reg FLAGS_REG)
5344 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5345 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5346 (clobber (match_scratch:DI 0 "=rm"))]
5348 && ix86_match_ccmode (insn, CCGCmode)"
5350 switch (get_attr_type (insn))
5353 if (operands[2] == constm1_rtx)
5354 return "inc{q}\t%0";
5357 gcc_assert (operands[2] == const1_rtx);
5358 return "dec{q}\t%0";
5362 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5363 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5364 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5365 if ((INTVAL (operands[2]) == -128
5366 || (INTVAL (operands[2]) > 0
5367 && INTVAL (operands[2]) != 128))
5368 /* Avoid overflows. */
5369 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5370 return "sub{q}\t{%2, %0|%0, %2}";
5371 operands[2] = GEN_INT (-INTVAL (operands[2]));
5372 return "add{q}\t{%2, %0|%0, %2}";
5376 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5377 (const_string "incdec")
5378 (const_string "alu")))
5379 (set_attr "mode" "DI")])
5381 (define_insn "*adddi_5_rex64"
5382 [(set (reg FLAGS_REG)
5384 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5385 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5387 (clobber (match_scratch:DI 0 "=r"))]
5389 && ix86_match_ccmode (insn, CCGOCmode)
5390 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5391 /* Current assemblers are broken and do not allow @GOTOFF in
5392 ought but a memory context. */
5393 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5395 switch (get_attr_type (insn))
5398 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5399 if (operands[2] == const1_rtx)
5400 return "inc{q}\t%0";
5403 gcc_assert (operands[2] == constm1_rtx);
5404 return "dec{q}\t%0";
5408 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5409 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5410 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5411 if (GET_CODE (operands[2]) == CONST_INT
5412 /* Avoid overflows. */
5413 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5414 && (INTVAL (operands[2]) == 128
5415 || (INTVAL (operands[2]) < 0
5416 && INTVAL (operands[2]) != -128)))
5418 operands[2] = GEN_INT (-INTVAL (operands[2]));
5419 return "sub{q}\t{%2, %0|%0, %2}";
5421 return "add{q}\t{%2, %0|%0, %2}";
5425 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5426 (const_string "incdec")
5427 (const_string "alu")))
5428 (set_attr "mode" "DI")])
5431 (define_insn "*addsi_1"
5432 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5433 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5434 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5435 (clobber (reg:CC FLAGS_REG))]
5436 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5438 switch (get_attr_type (insn))
5441 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5442 return "lea{l}\t{%a2, %0|%0, %a2}";
5445 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5446 if (operands[2] == const1_rtx)
5447 return "inc{l}\t%0";
5450 gcc_assert (operands[2] == constm1_rtx);
5451 return "dec{l}\t%0";
5455 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5457 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5458 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5459 if (GET_CODE (operands[2]) == CONST_INT
5460 && (INTVAL (operands[2]) == 128
5461 || (INTVAL (operands[2]) < 0
5462 && INTVAL (operands[2]) != -128)))
5464 operands[2] = GEN_INT (-INTVAL (operands[2]));
5465 return "sub{l}\t{%2, %0|%0, %2}";
5467 return "add{l}\t{%2, %0|%0, %2}";
5471 (cond [(eq_attr "alternative" "2")
5472 (const_string "lea")
5473 ; Current assemblers are broken and do not allow @GOTOFF in
5474 ; ought but a memory context.
5475 (match_operand:SI 2 "pic_symbolic_operand" "")
5476 (const_string "lea")
5477 (match_operand:SI 2 "incdec_operand" "")
5478 (const_string "incdec")
5480 (const_string "alu")))
5481 (set_attr "mode" "SI")])
5483 ;; Convert lea to the lea pattern to avoid flags dependency.
5485 [(set (match_operand 0 "register_operand" "")
5486 (plus (match_operand 1 "register_operand" "")
5487 (match_operand 2 "nonmemory_operand" "")))
5488 (clobber (reg:CC FLAGS_REG))]
5490 && true_regnum (operands[0]) != true_regnum (operands[1])"
5494 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5495 may confuse gen_lowpart. */
5496 if (GET_MODE (operands[0]) != Pmode)
5498 operands[1] = gen_lowpart (Pmode, operands[1]);
5499 operands[2] = gen_lowpart (Pmode, operands[2]);
5501 operands[0] = gen_lowpart (SImode, operands[0]);
5502 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5503 if (Pmode != SImode)
5504 pat = gen_rtx_SUBREG (SImode, pat, 0);
5505 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5509 ;; It may seem that nonimmediate operand is proper one for operand 1.
5510 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5511 ;; we take care in ix86_binary_operator_ok to not allow two memory
5512 ;; operands so proper swapping will be done in reload. This allow
5513 ;; patterns constructed from addsi_1 to match.
5514 (define_insn "addsi_1_zext"
5515 [(set (match_operand:DI 0 "register_operand" "=r,r")
5517 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5518 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5519 (clobber (reg:CC FLAGS_REG))]
5520 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5522 switch (get_attr_type (insn))
5525 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5526 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5529 if (operands[2] == const1_rtx)
5530 return "inc{l}\t%k0";
5533 gcc_assert (operands[2] == constm1_rtx);
5534 return "dec{l}\t%k0";
5538 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5539 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5540 if (GET_CODE (operands[2]) == CONST_INT
5541 && (INTVAL (operands[2]) == 128
5542 || (INTVAL (operands[2]) < 0
5543 && INTVAL (operands[2]) != -128)))
5545 operands[2] = GEN_INT (-INTVAL (operands[2]));
5546 return "sub{l}\t{%2, %k0|%k0, %2}";
5548 return "add{l}\t{%2, %k0|%k0, %2}";
5552 (cond [(eq_attr "alternative" "1")
5553 (const_string "lea")
5554 ; Current assemblers are broken and do not allow @GOTOFF in
5555 ; ought but a memory context.
5556 (match_operand:SI 2 "pic_symbolic_operand" "")
5557 (const_string "lea")
5558 (match_operand:SI 2 "incdec_operand" "")
5559 (const_string "incdec")
5561 (const_string "alu")))
5562 (set_attr "mode" "SI")])
5564 ;; Convert lea to the lea pattern to avoid flags dependency.
5566 [(set (match_operand:DI 0 "register_operand" "")
5568 (plus:SI (match_operand:SI 1 "register_operand" "")
5569 (match_operand:SI 2 "nonmemory_operand" ""))))
5570 (clobber (reg:CC FLAGS_REG))]
5571 "TARGET_64BIT && reload_completed
5572 && true_regnum (operands[0]) != true_regnum (operands[1])"
5574 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5576 operands[1] = gen_lowpart (Pmode, operands[1]);
5577 operands[2] = gen_lowpart (Pmode, operands[2]);
5580 (define_insn "*addsi_2"
5581 [(set (reg FLAGS_REG)
5583 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5584 (match_operand:SI 2 "general_operand" "rmni,rni"))
5586 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5587 (plus:SI (match_dup 1) (match_dup 2)))]
5588 "ix86_match_ccmode (insn, CCGOCmode)
5589 && ix86_binary_operator_ok (PLUS, SImode, operands)
5590 /* Current assemblers are broken and do not allow @GOTOFF in
5591 ought but a memory context. */
5592 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5594 switch (get_attr_type (insn))
5597 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5598 if (operands[2] == const1_rtx)
5599 return "inc{l}\t%0";
5602 gcc_assert (operands[2] == constm1_rtx);
5603 return "dec{l}\t%0";
5607 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5608 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5609 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5610 if (GET_CODE (operands[2]) == CONST_INT
5611 && (INTVAL (operands[2]) == 128
5612 || (INTVAL (operands[2]) < 0
5613 && INTVAL (operands[2]) != -128)))
5615 operands[2] = GEN_INT (-INTVAL (operands[2]));
5616 return "sub{l}\t{%2, %0|%0, %2}";
5618 return "add{l}\t{%2, %0|%0, %2}";
5622 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5623 (const_string "incdec")
5624 (const_string "alu")))
5625 (set_attr "mode" "SI")])
5627 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5628 (define_insn "*addsi_2_zext"
5629 [(set (reg FLAGS_REG)
5631 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5632 (match_operand:SI 2 "general_operand" "rmni"))
5634 (set (match_operand:DI 0 "register_operand" "=r")
5635 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5636 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5637 && ix86_binary_operator_ok (PLUS, SImode, operands)
5638 /* Current assemblers are broken and do not allow @GOTOFF in
5639 ought but a memory context. */
5640 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5642 switch (get_attr_type (insn))
5645 if (operands[2] == const1_rtx)
5646 return "inc{l}\t%k0";
5649 gcc_assert (operands[2] == constm1_rtx);
5650 return "dec{l}\t%k0";
5654 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5655 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5656 if (GET_CODE (operands[2]) == CONST_INT
5657 && (INTVAL (operands[2]) == 128
5658 || (INTVAL (operands[2]) < 0
5659 && INTVAL (operands[2]) != -128)))
5661 operands[2] = GEN_INT (-INTVAL (operands[2]));
5662 return "sub{l}\t{%2, %k0|%k0, %2}";
5664 return "add{l}\t{%2, %k0|%k0, %2}";
5668 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5669 (const_string "incdec")
5670 (const_string "alu")))
5671 (set_attr "mode" "SI")])
5673 (define_insn "*addsi_3"
5674 [(set (reg FLAGS_REG)
5675 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5676 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5677 (clobber (match_scratch:SI 0 "=r"))]
5678 "ix86_match_ccmode (insn, CCZmode)
5679 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5680 /* Current assemblers are broken and do not allow @GOTOFF in
5681 ought but a memory context. */
5682 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5684 switch (get_attr_type (insn))
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688 if (operands[2] == const1_rtx)
5689 return "inc{l}\t%0";
5692 gcc_assert (operands[2] == constm1_rtx);
5693 return "dec{l}\t%0";
5697 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5698 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5699 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5700 if (GET_CODE (operands[2]) == CONST_INT
5701 && (INTVAL (operands[2]) == 128
5702 || (INTVAL (operands[2]) < 0
5703 && INTVAL (operands[2]) != -128)))
5705 operands[2] = GEN_INT (-INTVAL (operands[2]));
5706 return "sub{l}\t{%2, %0|%0, %2}";
5708 return "add{l}\t{%2, %0|%0, %2}";
5712 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5713 (const_string "incdec")
5714 (const_string "alu")))
5715 (set_attr "mode" "SI")])
5717 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5718 (define_insn "*addsi_3_zext"
5719 [(set (reg FLAGS_REG)
5720 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5721 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5722 (set (match_operand:DI 0 "register_operand" "=r")
5723 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5724 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5725 && ix86_binary_operator_ok (PLUS, SImode, operands)
5726 /* Current assemblers are broken and do not allow @GOTOFF in
5727 ought but a memory context. */
5728 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5730 switch (get_attr_type (insn))
5733 if (operands[2] == const1_rtx)
5734 return "inc{l}\t%k0";
5737 gcc_assert (operands[2] == constm1_rtx);
5738 return "dec{l}\t%k0";
5742 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5743 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5744 if (GET_CODE (operands[2]) == CONST_INT
5745 && (INTVAL (operands[2]) == 128
5746 || (INTVAL (operands[2]) < 0
5747 && INTVAL (operands[2]) != -128)))
5749 operands[2] = GEN_INT (-INTVAL (operands[2]));
5750 return "sub{l}\t{%2, %k0|%k0, %2}";
5752 return "add{l}\t{%2, %k0|%k0, %2}";
5756 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5757 (const_string "incdec")
5758 (const_string "alu")))
5759 (set_attr "mode" "SI")])
5761 ; For comparisons against 1, -1 and 128, we may generate better code
5762 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5763 ; is matched then. We can't accept general immediate, because for
5764 ; case of overflows, the result is messed up.
5765 ; This pattern also don't hold of 0x80000000, since the value overflows
5767 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5768 ; only for comparisons not depending on it.
5769 (define_insn "*addsi_4"
5770 [(set (reg FLAGS_REG)
5771 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5772 (match_operand:SI 2 "const_int_operand" "n")))
5773 (clobber (match_scratch:SI 0 "=rm"))]
5774 "ix86_match_ccmode (insn, CCGCmode)
5775 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5777 switch (get_attr_type (insn))
5780 if (operands[2] == constm1_rtx)
5781 return "inc{l}\t%0";
5784 gcc_assert (operands[2] == const1_rtx);
5785 return "dec{l}\t%0";
5789 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5790 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5791 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5792 if ((INTVAL (operands[2]) == -128
5793 || (INTVAL (operands[2]) > 0
5794 && INTVAL (operands[2]) != 128)))
5795 return "sub{l}\t{%2, %0|%0, %2}";
5796 operands[2] = GEN_INT (-INTVAL (operands[2]));
5797 return "add{l}\t{%2, %0|%0, %2}";
5801 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5802 (const_string "incdec")
5803 (const_string "alu")))
5804 (set_attr "mode" "SI")])
5806 (define_insn "*addsi_5"
5807 [(set (reg FLAGS_REG)
5809 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5810 (match_operand:SI 2 "general_operand" "rmni"))
5812 (clobber (match_scratch:SI 0 "=r"))]
5813 "ix86_match_ccmode (insn, CCGOCmode)
5814 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5815 /* Current assemblers are broken and do not allow @GOTOFF in
5816 ought but a memory context. */
5817 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5819 switch (get_attr_type (insn))
5822 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5823 if (operands[2] == const1_rtx)
5824 return "inc{l}\t%0";
5827 gcc_assert (operands[2] == constm1_rtx);
5828 return "dec{l}\t%0";
5832 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5833 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5834 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5835 if (GET_CODE (operands[2]) == CONST_INT
5836 && (INTVAL (operands[2]) == 128
5837 || (INTVAL (operands[2]) < 0
5838 && INTVAL (operands[2]) != -128)))
5840 operands[2] = GEN_INT (-INTVAL (operands[2]));
5841 return "sub{l}\t{%2, %0|%0, %2}";
5843 return "add{l}\t{%2, %0|%0, %2}";
5847 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5848 (const_string "incdec")
5849 (const_string "alu")))
5850 (set_attr "mode" "SI")])
5852 (define_expand "addhi3"
5853 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5854 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5855 (match_operand:HI 2 "general_operand" "")))
5856 (clobber (reg:CC FLAGS_REG))])]
5857 "TARGET_HIMODE_MATH"
5858 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5860 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5861 ;; type optimizations enabled by define-splits. This is not important
5862 ;; for PII, and in fact harmful because of partial register stalls.
5864 (define_insn "*addhi_1_lea"
5865 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5866 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5867 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5868 (clobber (reg:CC FLAGS_REG))]
5869 "!TARGET_PARTIAL_REG_STALL
5870 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5872 switch (get_attr_type (insn))
5877 if (operands[2] == const1_rtx)
5878 return "inc{w}\t%0";
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{w}\t%0";
5886 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5887 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5888 if (GET_CODE (operands[2]) == CONST_INT
5889 && (INTVAL (operands[2]) == 128
5890 || (INTVAL (operands[2]) < 0
5891 && INTVAL (operands[2]) != -128)))
5893 operands[2] = GEN_INT (-INTVAL (operands[2]));
5894 return "sub{w}\t{%2, %0|%0, %2}";
5896 return "add{w}\t{%2, %0|%0, %2}";
5900 (if_then_else (eq_attr "alternative" "2")
5901 (const_string "lea")
5902 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5903 (const_string "incdec")
5904 (const_string "alu"))))
5905 (set_attr "mode" "HI,HI,SI")])
5907 (define_insn "*addhi_1"
5908 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5909 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5910 (match_operand:HI 2 "general_operand" "ri,rm")))
5911 (clobber (reg:CC FLAGS_REG))]
5912 "TARGET_PARTIAL_REG_STALL
5913 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5915 switch (get_attr_type (insn))
5918 if (operands[2] == const1_rtx)
5919 return "inc{w}\t%0";
5922 gcc_assert (operands[2] == constm1_rtx);
5923 return "dec{w}\t%0";
5927 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5928 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5929 if (GET_CODE (operands[2]) == CONST_INT
5930 && (INTVAL (operands[2]) == 128
5931 || (INTVAL (operands[2]) < 0
5932 && INTVAL (operands[2]) != -128)))
5934 operands[2] = GEN_INT (-INTVAL (operands[2]));
5935 return "sub{w}\t{%2, %0|%0, %2}";
5937 return "add{w}\t{%2, %0|%0, %2}";
5941 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5942 (const_string "incdec")
5943 (const_string "alu")))
5944 (set_attr "mode" "HI")])
5946 (define_insn "*addhi_2"
5947 [(set (reg FLAGS_REG)
5949 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5950 (match_operand:HI 2 "general_operand" "rmni,rni"))
5952 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5953 (plus:HI (match_dup 1) (match_dup 2)))]
5954 "ix86_match_ccmode (insn, CCGOCmode)
5955 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5957 switch (get_attr_type (insn))
5960 if (operands[2] == const1_rtx)
5961 return "inc{w}\t%0";
5964 gcc_assert (operands[2] == constm1_rtx);
5965 return "dec{w}\t%0";
5969 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5970 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5971 if (GET_CODE (operands[2]) == CONST_INT
5972 && (INTVAL (operands[2]) == 128
5973 || (INTVAL (operands[2]) < 0
5974 && INTVAL (operands[2]) != -128)))
5976 operands[2] = GEN_INT (-INTVAL (operands[2]));
5977 return "sub{w}\t{%2, %0|%0, %2}";
5979 return "add{w}\t{%2, %0|%0, %2}";
5983 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5984 (const_string "incdec")
5985 (const_string "alu")))
5986 (set_attr "mode" "HI")])
5988 (define_insn "*addhi_3"
5989 [(set (reg FLAGS_REG)
5990 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5991 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5992 (clobber (match_scratch:HI 0 "=r"))]
5993 "ix86_match_ccmode (insn, CCZmode)
5994 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5996 switch (get_attr_type (insn))
5999 if (operands[2] == const1_rtx)
6000 return "inc{w}\t%0";
6003 gcc_assert (operands[2] == constm1_rtx);
6004 return "dec{w}\t%0";
6008 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6009 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6010 if (GET_CODE (operands[2]) == CONST_INT
6011 && (INTVAL (operands[2]) == 128
6012 || (INTVAL (operands[2]) < 0
6013 && INTVAL (operands[2]) != -128)))
6015 operands[2] = GEN_INT (-INTVAL (operands[2]));
6016 return "sub{w}\t{%2, %0|%0, %2}";
6018 return "add{w}\t{%2, %0|%0, %2}";
6022 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6023 (const_string "incdec")
6024 (const_string "alu")))
6025 (set_attr "mode" "HI")])
6027 ; See comments above addsi_4 for details.
6028 (define_insn "*addhi_4"
6029 [(set (reg FLAGS_REG)
6030 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6031 (match_operand:HI 2 "const_int_operand" "n")))
6032 (clobber (match_scratch:HI 0 "=rm"))]
6033 "ix86_match_ccmode (insn, CCGCmode)
6034 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6036 switch (get_attr_type (insn))
6039 if (operands[2] == constm1_rtx)
6040 return "inc{w}\t%0";
6043 gcc_assert (operands[2] == const1_rtx);
6044 return "dec{w}\t%0";
6048 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6049 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6050 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6051 if ((INTVAL (operands[2]) == -128
6052 || (INTVAL (operands[2]) > 0
6053 && INTVAL (operands[2]) != 128)))
6054 return "sub{w}\t{%2, %0|%0, %2}";
6055 operands[2] = GEN_INT (-INTVAL (operands[2]));
6056 return "add{w}\t{%2, %0|%0, %2}";
6060 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6061 (const_string "incdec")
6062 (const_string "alu")))
6063 (set_attr "mode" "SI")])
6066 (define_insn "*addhi_5"
6067 [(set (reg FLAGS_REG)
6069 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6070 (match_operand:HI 2 "general_operand" "rmni"))
6072 (clobber (match_scratch:HI 0 "=r"))]
6073 "ix86_match_ccmode (insn, CCGOCmode)
6074 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6076 switch (get_attr_type (insn))
6079 if (operands[2] == const1_rtx)
6080 return "inc{w}\t%0";
6083 gcc_assert (operands[2] == constm1_rtx);
6084 return "dec{w}\t%0";
6088 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6089 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6090 if (GET_CODE (operands[2]) == CONST_INT
6091 && (INTVAL (operands[2]) == 128
6092 || (INTVAL (operands[2]) < 0
6093 && INTVAL (operands[2]) != -128)))
6095 operands[2] = GEN_INT (-INTVAL (operands[2]));
6096 return "sub{w}\t{%2, %0|%0, %2}";
6098 return "add{w}\t{%2, %0|%0, %2}";
6102 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6103 (const_string "incdec")
6104 (const_string "alu")))
6105 (set_attr "mode" "HI")])
6107 (define_expand "addqi3"
6108 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6109 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6110 (match_operand:QI 2 "general_operand" "")))
6111 (clobber (reg:CC FLAGS_REG))])]
6112 "TARGET_QIMODE_MATH"
6113 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6115 ;; %%% Potential partial reg stall on alternative 2. What to do?
6116 (define_insn "*addqi_1_lea"
6117 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6118 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6119 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6120 (clobber (reg:CC FLAGS_REG))]
6121 "!TARGET_PARTIAL_REG_STALL
6122 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6124 int widen = (which_alternative == 2);
6125 switch (get_attr_type (insn))
6130 if (operands[2] == const1_rtx)
6131 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6134 gcc_assert (operands[2] == constm1_rtx);
6135 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6139 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6140 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6141 if (GET_CODE (operands[2]) == CONST_INT
6142 && (INTVAL (operands[2]) == 128
6143 || (INTVAL (operands[2]) < 0
6144 && INTVAL (operands[2]) != -128)))
6146 operands[2] = GEN_INT (-INTVAL (operands[2]));
6148 return "sub{l}\t{%2, %k0|%k0, %2}";
6150 return "sub{b}\t{%2, %0|%0, %2}";
6153 return "add{l}\t{%k2, %k0|%k0, %k2}";
6155 return "add{b}\t{%2, %0|%0, %2}";
6159 (if_then_else (eq_attr "alternative" "3")
6160 (const_string "lea")
6161 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6162 (const_string "incdec")
6163 (const_string "alu"))))
6164 (set_attr "mode" "QI,QI,SI,SI")])
6166 (define_insn "*addqi_1"
6167 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6168 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6169 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6170 (clobber (reg:CC FLAGS_REG))]
6171 "TARGET_PARTIAL_REG_STALL
6172 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6174 int widen = (which_alternative == 2);
6175 switch (get_attr_type (insn))
6178 if (operands[2] == const1_rtx)
6179 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6182 gcc_assert (operands[2] == constm1_rtx);
6183 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6187 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6188 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6189 if (GET_CODE (operands[2]) == CONST_INT
6190 && (INTVAL (operands[2]) == 128
6191 || (INTVAL (operands[2]) < 0
6192 && INTVAL (operands[2]) != -128)))
6194 operands[2] = GEN_INT (-INTVAL (operands[2]));
6196 return "sub{l}\t{%2, %k0|%k0, %2}";
6198 return "sub{b}\t{%2, %0|%0, %2}";
6201 return "add{l}\t{%k2, %k0|%k0, %k2}";
6203 return "add{b}\t{%2, %0|%0, %2}";
6207 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6208 (const_string "incdec")
6209 (const_string "alu")))
6210 (set_attr "mode" "QI,QI,SI")])
6212 (define_insn "*addqi_1_slp"
6213 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6214 (plus:QI (match_dup 0)
6215 (match_operand:QI 1 "general_operand" "qn,qnm")))
6216 (clobber (reg:CC FLAGS_REG))]
6217 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6218 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6220 switch (get_attr_type (insn))
6223 if (operands[1] == const1_rtx)
6224 return "inc{b}\t%0";
6227 gcc_assert (operands[1] == constm1_rtx);
6228 return "dec{b}\t%0";
6232 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6233 if (GET_CODE (operands[1]) == CONST_INT
6234 && INTVAL (operands[1]) < 0)
6236 operands[1] = GEN_INT (-INTVAL (operands[1]));
6237 return "sub{b}\t{%1, %0|%0, %1}";
6239 return "add{b}\t{%1, %0|%0, %1}";
6243 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6244 (const_string "incdec")
6245 (const_string "alu1")))
6246 (set (attr "memory")
6247 (if_then_else (match_operand 1 "memory_operand" "")
6248 (const_string "load")
6249 (const_string "none")))
6250 (set_attr "mode" "QI")])
6252 (define_insn "*addqi_2"
6253 [(set (reg FLAGS_REG)
6255 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6256 (match_operand:QI 2 "general_operand" "qmni,qni"))
6258 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6259 (plus:QI (match_dup 1) (match_dup 2)))]
6260 "ix86_match_ccmode (insn, CCGOCmode)
6261 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6263 switch (get_attr_type (insn))
6266 if (operands[2] == const1_rtx)
6267 return "inc{b}\t%0";
6270 gcc_assert (operands[2] == constm1_rtx
6271 || (GET_CODE (operands[2]) == CONST_INT
6272 && INTVAL (operands[2]) == 255));
6273 return "dec{b}\t%0";
6277 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6278 if (GET_CODE (operands[2]) == CONST_INT
6279 && INTVAL (operands[2]) < 0)
6281 operands[2] = GEN_INT (-INTVAL (operands[2]));
6282 return "sub{b}\t{%2, %0|%0, %2}";
6284 return "add{b}\t{%2, %0|%0, %2}";
6288 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6289 (const_string "incdec")
6290 (const_string "alu")))
6291 (set_attr "mode" "QI")])
6293 (define_insn "*addqi_3"
6294 [(set (reg FLAGS_REG)
6295 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6296 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6297 (clobber (match_scratch:QI 0 "=q"))]
6298 "ix86_match_ccmode (insn, CCZmode)
6299 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6301 switch (get_attr_type (insn))
6304 if (operands[2] == const1_rtx)
6305 return "inc{b}\t%0";
6308 gcc_assert (operands[2] == constm1_rtx
6309 || (GET_CODE (operands[2]) == CONST_INT
6310 && INTVAL (operands[2]) == 255));
6311 return "dec{b}\t%0";
6315 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6316 if (GET_CODE (operands[2]) == CONST_INT
6317 && INTVAL (operands[2]) < 0)
6319 operands[2] = GEN_INT (-INTVAL (operands[2]));
6320 return "sub{b}\t{%2, %0|%0, %2}";
6322 return "add{b}\t{%2, %0|%0, %2}";
6326 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6327 (const_string "incdec")
6328 (const_string "alu")))
6329 (set_attr "mode" "QI")])
6331 ; See comments above addsi_4 for details.
6332 (define_insn "*addqi_4"
6333 [(set (reg FLAGS_REG)
6334 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6335 (match_operand:QI 2 "const_int_operand" "n")))
6336 (clobber (match_scratch:QI 0 "=qm"))]
6337 "ix86_match_ccmode (insn, CCGCmode)
6338 && (INTVAL (operands[2]) & 0xff) != 0x80"
6340 switch (get_attr_type (insn))
6343 if (operands[2] == constm1_rtx
6344 || (GET_CODE (operands[2]) == CONST_INT
6345 && INTVAL (operands[2]) == 255))
6346 return "inc{b}\t%0";
6349 gcc_assert (operands[2] == const1_rtx);
6350 return "dec{b}\t%0";
6354 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6355 if (INTVAL (operands[2]) < 0)
6357 operands[2] = GEN_INT (-INTVAL (operands[2]));
6358 return "add{b}\t{%2, %0|%0, %2}";
6360 return "sub{b}\t{%2, %0|%0, %2}";
6364 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6365 (const_string "incdec")
6366 (const_string "alu")))
6367 (set_attr "mode" "QI")])
6370 (define_insn "*addqi_5"
6371 [(set (reg FLAGS_REG)
6373 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6374 (match_operand:QI 2 "general_operand" "qmni"))
6376 (clobber (match_scratch:QI 0 "=q"))]
6377 "ix86_match_ccmode (insn, CCGOCmode)
6378 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6380 switch (get_attr_type (insn))
6383 if (operands[2] == const1_rtx)
6384 return "inc{b}\t%0";
6387 gcc_assert (operands[2] == constm1_rtx
6388 || (GET_CODE (operands[2]) == CONST_INT
6389 && INTVAL (operands[2]) == 255));
6390 return "dec{b}\t%0";
6394 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6395 if (GET_CODE (operands[2]) == CONST_INT
6396 && INTVAL (operands[2]) < 0)
6398 operands[2] = GEN_INT (-INTVAL (operands[2]));
6399 return "sub{b}\t{%2, %0|%0, %2}";
6401 return "add{b}\t{%2, %0|%0, %2}";
6405 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6406 (const_string "incdec")
6407 (const_string "alu")))
6408 (set_attr "mode" "QI")])
6411 (define_insn "addqi_ext_1"
6412 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6417 (match_operand 1 "ext_register_operand" "0")
6420 (match_operand:QI 2 "general_operand" "Qmn")))
6421 (clobber (reg:CC FLAGS_REG))]
6424 switch (get_attr_type (insn))
6427 if (operands[2] == const1_rtx)
6428 return "inc{b}\t%h0";
6431 gcc_assert (operands[2] == constm1_rtx
6432 || (GET_CODE (operands[2]) == CONST_INT
6433 && INTVAL (operands[2]) == 255));
6434 return "dec{b}\t%h0";
6438 return "add{b}\t{%2, %h0|%h0, %2}";
6442 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6443 (const_string "incdec")
6444 (const_string "alu")))
6445 (set_attr "mode" "QI")])
6447 (define_insn "*addqi_ext_1_rex64"
6448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6453 (match_operand 1 "ext_register_operand" "0")
6456 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6457 (clobber (reg:CC FLAGS_REG))]
6460 switch (get_attr_type (insn))
6463 if (operands[2] == const1_rtx)
6464 return "inc{b}\t%h0";
6467 gcc_assert (operands[2] == constm1_rtx
6468 || (GET_CODE (operands[2]) == CONST_INT
6469 && INTVAL (operands[2]) == 255));
6470 return "dec{b}\t%h0";
6474 return "add{b}\t{%2, %h0|%h0, %2}";
6478 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6479 (const_string "incdec")
6480 (const_string "alu")))
6481 (set_attr "mode" "QI")])
6483 (define_insn "*addqi_ext_2"
6484 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6489 (match_operand 1 "ext_register_operand" "%0")
6493 (match_operand 2 "ext_register_operand" "Q")
6496 (clobber (reg:CC FLAGS_REG))]
6498 "add{b}\t{%h2, %h0|%h0, %h2}"
6499 [(set_attr "type" "alu")
6500 (set_attr "mode" "QI")])
6502 ;; The patterns that match these are at the end of this file.
6504 (define_expand "addxf3"
6505 [(set (match_operand:XF 0 "register_operand" "")
6506 (plus:XF (match_operand:XF 1 "register_operand" "")
6507 (match_operand:XF 2 "register_operand" "")))]
6511 (define_expand "adddf3"
6512 [(set (match_operand:DF 0 "register_operand" "")
6513 (plus:DF (match_operand:DF 1 "register_operand" "")
6514 (match_operand:DF 2 "nonimmediate_operand" "")))]
6515 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6518 (define_expand "addsf3"
6519 [(set (match_operand:SF 0 "register_operand" "")
6520 (plus:SF (match_operand:SF 1 "register_operand" "")
6521 (match_operand:SF 2 "nonimmediate_operand" "")))]
6522 "TARGET_80387 || TARGET_SSE_MATH"
6525 ;; Subtract instructions
6527 ;; %%% splits for subditi3
6529 (define_expand "subti3"
6530 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6531 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6532 (match_operand:TI 2 "x86_64_general_operand" "")))
6533 (clobber (reg:CC FLAGS_REG))])]
6535 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6537 (define_insn "*subti3_1"
6538 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6539 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6540 (match_operand:TI 2 "general_operand" "roiF,riF")))
6541 (clobber (reg:CC FLAGS_REG))]
6542 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6546 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6547 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6548 (match_operand:TI 2 "general_operand" "")))
6549 (clobber (reg:CC FLAGS_REG))]
6550 "TARGET_64BIT && reload_completed"
6551 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6552 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6553 (parallel [(set (match_dup 3)
6554 (minus:DI (match_dup 4)
6555 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6557 (clobber (reg:CC FLAGS_REG))])]
6558 "split_ti (operands+0, 1, operands+0, operands+3);
6559 split_ti (operands+1, 1, operands+1, operands+4);
6560 split_ti (operands+2, 1, operands+2, operands+5);")
6562 ;; %%% splits for subsidi3
6564 (define_expand "subdi3"
6565 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6566 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6567 (match_operand:DI 2 "x86_64_general_operand" "")))
6568 (clobber (reg:CC FLAGS_REG))])]
6570 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6572 (define_insn "*subdi3_1"
6573 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6574 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6575 (match_operand:DI 2 "general_operand" "roiF,riF")))
6576 (clobber (reg:CC FLAGS_REG))]
6577 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6581 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6582 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6583 (match_operand:DI 2 "general_operand" "")))
6584 (clobber (reg:CC FLAGS_REG))]
6585 "!TARGET_64BIT && reload_completed"
6586 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6587 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6588 (parallel [(set (match_dup 3)
6589 (minus:SI (match_dup 4)
6590 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6592 (clobber (reg:CC FLAGS_REG))])]
6593 "split_di (operands+0, 1, operands+0, operands+3);
6594 split_di (operands+1, 1, operands+1, operands+4);
6595 split_di (operands+2, 1, operands+2, operands+5);")
6597 (define_insn "subdi3_carry_rex64"
6598 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6599 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6600 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6601 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6602 (clobber (reg:CC FLAGS_REG))]
6603 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6604 "sbb{q}\t{%2, %0|%0, %2}"
6605 [(set_attr "type" "alu")
6606 (set_attr "pent_pair" "pu")
6607 (set_attr "mode" "DI")])
6609 (define_insn "*subdi_1_rex64"
6610 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6611 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6612 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6613 (clobber (reg:CC FLAGS_REG))]
6614 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6615 "sub{q}\t{%2, %0|%0, %2}"
6616 [(set_attr "type" "alu")
6617 (set_attr "mode" "DI")])
6619 (define_insn "*subdi_2_rex64"
6620 [(set (reg FLAGS_REG)
6622 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6623 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6625 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6626 (minus:DI (match_dup 1) (match_dup 2)))]
6627 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6628 && ix86_binary_operator_ok (MINUS, DImode, operands)"
6629 "sub{q}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "mode" "DI")])
6633 (define_insn "*subdi_3_rex63"
6634 [(set (reg FLAGS_REG)
6635 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6636 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6637 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6638 (minus:DI (match_dup 1) (match_dup 2)))]
6639 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6640 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6641 "sub{q}\t{%2, %0|%0, %2}"
6642 [(set_attr "type" "alu")
6643 (set_attr "mode" "DI")])
6645 (define_insn "subqi3_carry"
6646 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6647 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6648 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6649 (match_operand:QI 2 "general_operand" "qi,qm"))))
6650 (clobber (reg:CC FLAGS_REG))]
6651 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6652 "sbb{b}\t{%2, %0|%0, %2}"
6653 [(set_attr "type" "alu")
6654 (set_attr "pent_pair" "pu")
6655 (set_attr "mode" "QI")])
6657 (define_insn "subhi3_carry"
6658 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6659 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6660 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6661 (match_operand:HI 2 "general_operand" "ri,rm"))))
6662 (clobber (reg:CC FLAGS_REG))]
6663 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6664 "sbb{w}\t{%2, %0|%0, %2}"
6665 [(set_attr "type" "alu")
6666 (set_attr "pent_pair" "pu")
6667 (set_attr "mode" "HI")])
6669 (define_insn "subsi3_carry"
6670 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6671 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6672 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6673 (match_operand:SI 2 "general_operand" "ri,rm"))))
6674 (clobber (reg:CC FLAGS_REG))]
6675 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6676 "sbb{l}\t{%2, %0|%0, %2}"
6677 [(set_attr "type" "alu")
6678 (set_attr "pent_pair" "pu")
6679 (set_attr "mode" "SI")])
6681 (define_insn "subsi3_carry_zext"
6682 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6684 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6685 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6686 (match_operand:SI 2 "general_operand" "ri,rm")))))
6687 (clobber (reg:CC FLAGS_REG))]
6688 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6689 "sbb{l}\t{%2, %k0|%k0, %2}"
6690 [(set_attr "type" "alu")
6691 (set_attr "pent_pair" "pu")
6692 (set_attr "mode" "SI")])
6694 (define_expand "subsi3"
6695 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6696 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6697 (match_operand:SI 2 "general_operand" "")))
6698 (clobber (reg:CC FLAGS_REG))])]
6700 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6702 (define_insn "*subsi_1"
6703 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6704 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6705 (match_operand:SI 2 "general_operand" "ri,rm")))
6706 (clobber (reg:CC FLAGS_REG))]
6707 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6708 "sub{l}\t{%2, %0|%0, %2}"
6709 [(set_attr "type" "alu")
6710 (set_attr "mode" "SI")])
6712 (define_insn "*subsi_1_zext"
6713 [(set (match_operand:DI 0 "register_operand" "=r")
6715 (minus:SI (match_operand:SI 1 "register_operand" "0")
6716 (match_operand:SI 2 "general_operand" "rim"))))
6717 (clobber (reg:CC FLAGS_REG))]
6718 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719 "sub{l}\t{%2, %k0|%k0, %2}"
6720 [(set_attr "type" "alu")
6721 (set_attr "mode" "SI")])
6723 (define_insn "*subsi_2"
6724 [(set (reg FLAGS_REG)
6726 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6727 (match_operand:SI 2 "general_operand" "ri,rm"))
6729 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6730 (minus:SI (match_dup 1) (match_dup 2)))]
6731 "ix86_match_ccmode (insn, CCGOCmode)
6732 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6733 "sub{l}\t{%2, %0|%0, %2}"
6734 [(set_attr "type" "alu")
6735 (set_attr "mode" "SI")])
6737 (define_insn "*subsi_2_zext"
6738 [(set (reg FLAGS_REG)
6740 (minus:SI (match_operand:SI 1 "register_operand" "0")
6741 (match_operand:SI 2 "general_operand" "rim"))
6743 (set (match_operand:DI 0 "register_operand" "=r")
6745 (minus:SI (match_dup 1)
6747 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6748 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6749 "sub{l}\t{%2, %k0|%k0, %2}"
6750 [(set_attr "type" "alu")
6751 (set_attr "mode" "SI")])
6753 (define_insn "*subsi_3"
6754 [(set (reg FLAGS_REG)
6755 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6756 (match_operand:SI 2 "general_operand" "ri,rm")))
6757 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6758 (minus:SI (match_dup 1) (match_dup 2)))]
6759 "ix86_match_ccmode (insn, CCmode)
6760 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6761 "sub{l}\t{%2, %0|%0, %2}"
6762 [(set_attr "type" "alu")
6763 (set_attr "mode" "SI")])
6765 (define_insn "*subsi_3_zext"
6766 [(set (reg FLAGS_REG)
6767 (compare (match_operand:SI 1 "register_operand" "0")
6768 (match_operand:SI 2 "general_operand" "rim")))
6769 (set (match_operand:DI 0 "register_operand" "=r")
6771 (minus:SI (match_dup 1)
6773 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6774 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6775 "sub{l}\t{%2, %1|%1, %2}"
6776 [(set_attr "type" "alu")
6777 (set_attr "mode" "DI")])
6779 (define_expand "subhi3"
6780 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6781 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6782 (match_operand:HI 2 "general_operand" "")))
6783 (clobber (reg:CC FLAGS_REG))])]
6784 "TARGET_HIMODE_MATH"
6785 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6787 (define_insn "*subhi_1"
6788 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6789 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6790 (match_operand:HI 2 "general_operand" "ri,rm")))
6791 (clobber (reg:CC FLAGS_REG))]
6792 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6793 "sub{w}\t{%2, %0|%0, %2}"
6794 [(set_attr "type" "alu")
6795 (set_attr "mode" "HI")])
6797 (define_insn "*subhi_2"
6798 [(set (reg FLAGS_REG)
6800 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6801 (match_operand:HI 2 "general_operand" "ri,rm"))
6803 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6804 (minus:HI (match_dup 1) (match_dup 2)))]
6805 "ix86_match_ccmode (insn, CCGOCmode)
6806 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6807 "sub{w}\t{%2, %0|%0, %2}"
6808 [(set_attr "type" "alu")
6809 (set_attr "mode" "HI")])
6811 (define_insn "*subhi_3"
6812 [(set (reg FLAGS_REG)
6813 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6814 (match_operand:HI 2 "general_operand" "ri,rm")))
6815 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6816 (minus:HI (match_dup 1) (match_dup 2)))]
6817 "ix86_match_ccmode (insn, CCmode)
6818 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6819 "sub{w}\t{%2, %0|%0, %2}"
6820 [(set_attr "type" "alu")
6821 (set_attr "mode" "HI")])
6823 (define_expand "subqi3"
6824 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6825 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6826 (match_operand:QI 2 "general_operand" "")))
6827 (clobber (reg:CC FLAGS_REG))])]
6828 "TARGET_QIMODE_MATH"
6829 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6831 (define_insn "*subqi_1"
6832 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6833 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6834 (match_operand:QI 2 "general_operand" "qn,qmn")))
6835 (clobber (reg:CC FLAGS_REG))]
6836 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6837 "sub{b}\t{%2, %0|%0, %2}"
6838 [(set_attr "type" "alu")
6839 (set_attr "mode" "QI")])
6841 (define_insn "*subqi_1_slp"
6842 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6843 (minus:QI (match_dup 0)
6844 (match_operand:QI 1 "general_operand" "qn,qmn")))
6845 (clobber (reg:CC FLAGS_REG))]
6846 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6847 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6848 "sub{b}\t{%1, %0|%0, %1}"
6849 [(set_attr "type" "alu1")
6850 (set_attr "mode" "QI")])
6852 (define_insn "*subqi_2"
6853 [(set (reg FLAGS_REG)
6855 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6856 (match_operand:QI 2 "general_operand" "qi,qm"))
6858 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6859 (minus:HI (match_dup 1) (match_dup 2)))]
6860 "ix86_match_ccmode (insn, CCGOCmode)
6861 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6862 "sub{b}\t{%2, %0|%0, %2}"
6863 [(set_attr "type" "alu")
6864 (set_attr "mode" "QI")])
6866 (define_insn "*subqi_3"
6867 [(set (reg FLAGS_REG)
6868 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6869 (match_operand:QI 2 "general_operand" "qi,qm")))
6870 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6871 (minus:HI (match_dup 1) (match_dup 2)))]
6872 "ix86_match_ccmode (insn, CCmode)
6873 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6874 "sub{b}\t{%2, %0|%0, %2}"
6875 [(set_attr "type" "alu")
6876 (set_attr "mode" "QI")])
6878 ;; The patterns that match these are at the end of this file.
6880 (define_expand "subxf3"
6881 [(set (match_operand:XF 0 "register_operand" "")
6882 (minus:XF (match_operand:XF 1 "register_operand" "")
6883 (match_operand:XF 2 "register_operand" "")))]
6887 (define_expand "subdf3"
6888 [(set (match_operand:DF 0 "register_operand" "")
6889 (minus:DF (match_operand:DF 1 "register_operand" "")
6890 (match_operand:DF 2 "nonimmediate_operand" "")))]
6891 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6894 (define_expand "subsf3"
6895 [(set (match_operand:SF 0 "register_operand" "")
6896 (minus:SF (match_operand:SF 1 "register_operand" "")
6897 (match_operand:SF 2 "nonimmediate_operand" "")))]
6898 "TARGET_80387 || TARGET_SSE_MATH"
6901 ;; Multiply instructions
6903 (define_expand "muldi3"
6904 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6905 (mult:DI (match_operand:DI 1 "register_operand" "")
6906 (match_operand:DI 2 "x86_64_general_operand" "")))
6907 (clobber (reg:CC FLAGS_REG))])]
6911 (define_insn "*muldi3_1_rex64"
6912 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6913 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6914 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6915 (clobber (reg:CC FLAGS_REG))]
6917 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6919 imul{q}\t{%2, %1, %0|%0, %1, %2}
6920 imul{q}\t{%2, %1, %0|%0, %1, %2}
6921 imul{q}\t{%2, %0|%0, %2}"
6922 [(set_attr "type" "imul")
6923 (set_attr "prefix_0f" "0,0,1")
6924 (set (attr "athlon_decode")
6925 (cond [(eq_attr "cpu" "athlon")
6926 (const_string "vector")
6927 (eq_attr "alternative" "1")
6928 (const_string "vector")
6929 (and (eq_attr "alternative" "2")
6930 (match_operand 1 "memory_operand" ""))
6931 (const_string "vector")]
6932 (const_string "direct")))
6933 (set_attr "mode" "DI")])
6935 (define_expand "mulsi3"
6936 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6937 (mult:SI (match_operand:SI 1 "register_operand" "")
6938 (match_operand:SI 2 "general_operand" "")))
6939 (clobber (reg:CC FLAGS_REG))])]
6943 (define_insn "*mulsi3_1"
6944 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6945 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6946 (match_operand:SI 2 "general_operand" "K,i,mr")))
6947 (clobber (reg:CC FLAGS_REG))]
6948 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6950 imul{l}\t{%2, %1, %0|%0, %1, %2}
6951 imul{l}\t{%2, %1, %0|%0, %1, %2}
6952 imul{l}\t{%2, %0|%0, %2}"
6953 [(set_attr "type" "imul")
6954 (set_attr "prefix_0f" "0,0,1")
6955 (set (attr "athlon_decode")
6956 (cond [(eq_attr "cpu" "athlon")
6957 (const_string "vector")
6958 (eq_attr "alternative" "1")
6959 (const_string "vector")
6960 (and (eq_attr "alternative" "2")
6961 (match_operand 1 "memory_operand" ""))
6962 (const_string "vector")]
6963 (const_string "direct")))
6964 (set_attr "mode" "SI")])
6966 (define_insn "*mulsi3_1_zext"
6967 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6969 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6970 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6971 (clobber (reg:CC FLAGS_REG))]
6973 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6975 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6976 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6977 imul{l}\t{%2, %k0|%k0, %2}"
6978 [(set_attr "type" "imul")
6979 (set_attr "prefix_0f" "0,0,1")
6980 (set (attr "athlon_decode")
6981 (cond [(eq_attr "cpu" "athlon")
6982 (const_string "vector")
6983 (eq_attr "alternative" "1")
6984 (const_string "vector")
6985 (and (eq_attr "alternative" "2")
6986 (match_operand 1 "memory_operand" ""))
6987 (const_string "vector")]
6988 (const_string "direct")))
6989 (set_attr "mode" "SI")])
6991 (define_expand "mulhi3"
6992 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6993 (mult:HI (match_operand:HI 1 "register_operand" "")
6994 (match_operand:HI 2 "general_operand" "")))
6995 (clobber (reg:CC FLAGS_REG))])]
6996 "TARGET_HIMODE_MATH"
6999 (define_insn "*mulhi3_1"
7000 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7001 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7002 (match_operand:HI 2 "general_operand" "K,i,mr")))
7003 (clobber (reg:CC FLAGS_REG))]
7004 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7006 imul{w}\t{%2, %1, %0|%0, %1, %2}
7007 imul{w}\t{%2, %1, %0|%0, %1, %2}
7008 imul{w}\t{%2, %0|%0, %2}"
7009 [(set_attr "type" "imul")
7010 (set_attr "prefix_0f" "0,0,1")
7011 (set (attr "athlon_decode")
7012 (cond [(eq_attr "cpu" "athlon")
7013 (const_string "vector")
7014 (eq_attr "alternative" "1,2")
7015 (const_string "vector")]
7016 (const_string "direct")))
7017 (set_attr "mode" "HI")])
7019 (define_expand "mulqi3"
7020 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7021 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7022 (match_operand:QI 2 "register_operand" "")))
7023 (clobber (reg:CC FLAGS_REG))])]
7024 "TARGET_QIMODE_MATH"
7027 (define_insn "*mulqi3_1"
7028 [(set (match_operand:QI 0 "register_operand" "=a")
7029 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7030 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7031 (clobber (reg:CC FLAGS_REG))]
7033 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7035 [(set_attr "type" "imul")
7036 (set_attr "length_immediate" "0")
7037 (set (attr "athlon_decode")
7038 (if_then_else (eq_attr "cpu" "athlon")
7039 (const_string "vector")
7040 (const_string "direct")))
7041 (set_attr "mode" "QI")])
7043 (define_expand "umulqihi3"
7044 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7045 (mult:HI (zero_extend:HI
7046 (match_operand:QI 1 "nonimmediate_operand" ""))
7048 (match_operand:QI 2 "register_operand" ""))))
7049 (clobber (reg:CC FLAGS_REG))])]
7050 "TARGET_QIMODE_MATH"
7053 (define_insn "*umulqihi3_1"
7054 [(set (match_operand:HI 0 "register_operand" "=a")
7055 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7056 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7057 (clobber (reg:CC FLAGS_REG))]
7059 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7061 [(set_attr "type" "imul")
7062 (set_attr "length_immediate" "0")
7063 (set (attr "athlon_decode")
7064 (if_then_else (eq_attr "cpu" "athlon")
7065 (const_string "vector")
7066 (const_string "direct")))
7067 (set_attr "mode" "QI")])
7069 (define_expand "mulqihi3"
7070 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7071 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7072 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7073 (clobber (reg:CC FLAGS_REG))])]
7074 "TARGET_QIMODE_MATH"
7077 (define_insn "*mulqihi3_insn"
7078 [(set (match_operand:HI 0 "register_operand" "=a")
7079 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7080 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7081 (clobber (reg:CC FLAGS_REG))]
7083 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7085 [(set_attr "type" "imul")
7086 (set_attr "length_immediate" "0")
7087 (set (attr "athlon_decode")
7088 (if_then_else (eq_attr "cpu" "athlon")
7089 (const_string "vector")
7090 (const_string "direct")))
7091 (set_attr "mode" "QI")])
7093 (define_expand "umulditi3"
7094 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7095 (mult:TI (zero_extend:TI
7096 (match_operand:DI 1 "nonimmediate_operand" ""))
7098 (match_operand:DI 2 "register_operand" ""))))
7099 (clobber (reg:CC FLAGS_REG))])]
7103 (define_insn "*umulditi3_insn"
7104 [(set (match_operand:TI 0 "register_operand" "=A")
7105 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7106 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7107 (clobber (reg:CC FLAGS_REG))]
7109 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7111 [(set_attr "type" "imul")
7112 (set_attr "length_immediate" "0")
7113 (set (attr "athlon_decode")
7114 (if_then_else (eq_attr "cpu" "athlon")
7115 (const_string "vector")
7116 (const_string "double")))
7117 (set_attr "mode" "DI")])
7119 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7120 (define_expand "umulsidi3"
7121 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7122 (mult:DI (zero_extend:DI
7123 (match_operand:SI 1 "nonimmediate_operand" ""))
7125 (match_operand:SI 2 "register_operand" ""))))
7126 (clobber (reg:CC FLAGS_REG))])]
7130 (define_insn "*umulsidi3_insn"
7131 [(set (match_operand:DI 0 "register_operand" "=A")
7132 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7133 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7134 (clobber (reg:CC FLAGS_REG))]
7136 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7138 [(set_attr "type" "imul")
7139 (set_attr "length_immediate" "0")
7140 (set (attr "athlon_decode")
7141 (if_then_else (eq_attr "cpu" "athlon")
7142 (const_string "vector")
7143 (const_string "double")))
7144 (set_attr "mode" "SI")])
7146 (define_expand "mulditi3"
7147 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7148 (mult:TI (sign_extend:TI
7149 (match_operand:DI 1 "nonimmediate_operand" ""))
7151 (match_operand:DI 2 "register_operand" ""))))
7152 (clobber (reg:CC FLAGS_REG))])]
7156 (define_insn "*mulditi3_insn"
7157 [(set (match_operand:TI 0 "register_operand" "=A")
7158 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7159 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7160 (clobber (reg:CC FLAGS_REG))]
7162 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7164 [(set_attr "type" "imul")
7165 (set_attr "length_immediate" "0")
7166 (set (attr "athlon_decode")
7167 (if_then_else (eq_attr "cpu" "athlon")
7168 (const_string "vector")
7169 (const_string "double")))
7170 (set_attr "mode" "DI")])
7172 (define_expand "mulsidi3"
7173 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7174 (mult:DI (sign_extend:DI
7175 (match_operand:SI 1 "nonimmediate_operand" ""))
7177 (match_operand:SI 2 "register_operand" ""))))
7178 (clobber (reg:CC FLAGS_REG))])]
7182 (define_insn "*mulsidi3_insn"
7183 [(set (match_operand:DI 0 "register_operand" "=A")
7184 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7185 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7186 (clobber (reg:CC FLAGS_REG))]
7188 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7190 [(set_attr "type" "imul")
7191 (set_attr "length_immediate" "0")
7192 (set (attr "athlon_decode")
7193 (if_then_else (eq_attr "cpu" "athlon")
7194 (const_string "vector")
7195 (const_string "double")))
7196 (set_attr "mode" "SI")])
7198 (define_expand "umuldi3_highpart"
7199 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7202 (mult:TI (zero_extend:TI
7203 (match_operand:DI 1 "nonimmediate_operand" ""))
7205 (match_operand:DI 2 "register_operand" "")))
7207 (clobber (match_scratch:DI 3 ""))
7208 (clobber (reg:CC FLAGS_REG))])]
7212 (define_insn "*umuldi3_highpart_rex64"
7213 [(set (match_operand:DI 0 "register_operand" "=d")
7216 (mult:TI (zero_extend:TI
7217 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7219 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7221 (clobber (match_scratch:DI 3 "=1"))
7222 (clobber (reg:CC FLAGS_REG))]
7224 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7226 [(set_attr "type" "imul")
7227 (set_attr "length_immediate" "0")
7228 (set (attr "athlon_decode")
7229 (if_then_else (eq_attr "cpu" "athlon")
7230 (const_string "vector")
7231 (const_string "double")))
7232 (set_attr "mode" "DI")])
7234 (define_expand "umulsi3_highpart"
7235 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7238 (mult:DI (zero_extend:DI
7239 (match_operand:SI 1 "nonimmediate_operand" ""))
7241 (match_operand:SI 2 "register_operand" "")))
7243 (clobber (match_scratch:SI 3 ""))
7244 (clobber (reg:CC FLAGS_REG))])]
7248 (define_insn "*umulsi3_highpart_insn"
7249 [(set (match_operand:SI 0 "register_operand" "=d")
7252 (mult:DI (zero_extend:DI
7253 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7255 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7257 (clobber (match_scratch:SI 3 "=1"))
7258 (clobber (reg:CC FLAGS_REG))]
7259 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7261 [(set_attr "type" "imul")
7262 (set_attr "length_immediate" "0")
7263 (set (attr "athlon_decode")
7264 (if_then_else (eq_attr "cpu" "athlon")
7265 (const_string "vector")
7266 (const_string "double")))
7267 (set_attr "mode" "SI")])
7269 (define_insn "*umulsi3_highpart_zext"
7270 [(set (match_operand:DI 0 "register_operand" "=d")
7271 (zero_extend:DI (truncate:SI
7273 (mult:DI (zero_extend:DI
7274 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7276 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7278 (clobber (match_scratch:SI 3 "=1"))
7279 (clobber (reg:CC FLAGS_REG))]
7281 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7283 [(set_attr "type" "imul")
7284 (set_attr "length_immediate" "0")
7285 (set (attr "athlon_decode")
7286 (if_then_else (eq_attr "cpu" "athlon")
7287 (const_string "vector")
7288 (const_string "double")))
7289 (set_attr "mode" "SI")])
7291 (define_expand "smuldi3_highpart"
7292 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7295 (mult:TI (sign_extend:TI
7296 (match_operand:DI 1 "nonimmediate_operand" ""))
7298 (match_operand:DI 2 "register_operand" "")))
7300 (clobber (match_scratch:DI 3 ""))
7301 (clobber (reg:CC FLAGS_REG))])]
7305 (define_insn "*smuldi3_highpart_rex64"
7306 [(set (match_operand:DI 0 "register_operand" "=d")
7309 (mult:TI (sign_extend:TI
7310 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7312 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7314 (clobber (match_scratch:DI 3 "=1"))
7315 (clobber (reg:CC FLAGS_REG))]
7317 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7319 [(set_attr "type" "imul")
7320 (set (attr "athlon_decode")
7321 (if_then_else (eq_attr "cpu" "athlon")
7322 (const_string "vector")
7323 (const_string "double")))
7324 (set_attr "mode" "DI")])
7326 (define_expand "smulsi3_highpart"
7327 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7330 (mult:DI (sign_extend:DI
7331 (match_operand:SI 1 "nonimmediate_operand" ""))
7333 (match_operand:SI 2 "register_operand" "")))
7335 (clobber (match_scratch:SI 3 ""))
7336 (clobber (reg:CC FLAGS_REG))])]
7340 (define_insn "*smulsi3_highpart_insn"
7341 [(set (match_operand:SI 0 "register_operand" "=d")
7344 (mult:DI (sign_extend:DI
7345 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7347 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7349 (clobber (match_scratch:SI 3 "=1"))
7350 (clobber (reg:CC FLAGS_REG))]
7351 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7353 [(set_attr "type" "imul")
7354 (set (attr "athlon_decode")
7355 (if_then_else (eq_attr "cpu" "athlon")
7356 (const_string "vector")
7357 (const_string "double")))
7358 (set_attr "mode" "SI")])
7360 (define_insn "*smulsi3_highpart_zext"
7361 [(set (match_operand:DI 0 "register_operand" "=d")
7362 (zero_extend:DI (truncate:SI
7364 (mult:DI (sign_extend:DI
7365 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7367 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7369 (clobber (match_scratch:SI 3 "=1"))
7370 (clobber (reg:CC FLAGS_REG))]
7372 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7374 [(set_attr "type" "imul")
7375 (set (attr "athlon_decode")
7376 (if_then_else (eq_attr "cpu" "athlon")
7377 (const_string "vector")
7378 (const_string "double")))
7379 (set_attr "mode" "SI")])
7381 ;; The patterns that match these are at the end of this file.
7383 (define_expand "mulxf3"
7384 [(set (match_operand:XF 0 "register_operand" "")
7385 (mult:XF (match_operand:XF 1 "register_operand" "")
7386 (match_operand:XF 2 "register_operand" "")))]
7390 (define_expand "muldf3"
7391 [(set (match_operand:DF 0 "register_operand" "")
7392 (mult:DF (match_operand:DF 1 "register_operand" "")
7393 (match_operand:DF 2 "nonimmediate_operand" "")))]
7394 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7397 (define_expand "mulsf3"
7398 [(set (match_operand:SF 0 "register_operand" "")
7399 (mult:SF (match_operand:SF 1 "register_operand" "")
7400 (match_operand:SF 2 "nonimmediate_operand" "")))]
7401 "TARGET_80387 || TARGET_SSE_MATH"
7404 ;; Divide instructions
7406 (define_insn "divqi3"
7407 [(set (match_operand:QI 0 "register_operand" "=a")
7408 (div:QI (match_operand:HI 1 "register_operand" "0")
7409 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7410 (clobber (reg:CC FLAGS_REG))]
7411 "TARGET_QIMODE_MATH"
7413 [(set_attr "type" "idiv")
7414 (set_attr "mode" "QI")])
7416 (define_insn "udivqi3"
7417 [(set (match_operand:QI 0 "register_operand" "=a")
7418 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7419 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7420 (clobber (reg:CC FLAGS_REG))]
7421 "TARGET_QIMODE_MATH"
7423 [(set_attr "type" "idiv")
7424 (set_attr "mode" "QI")])
7426 ;; The patterns that match these are at the end of this file.
7428 (define_expand "divxf3"
7429 [(set (match_operand:XF 0 "register_operand" "")
7430 (div:XF (match_operand:XF 1 "register_operand" "")
7431 (match_operand:XF 2 "register_operand" "")))]
7435 (define_expand "divdf3"
7436 [(set (match_operand:DF 0 "register_operand" "")
7437 (div:DF (match_operand:DF 1 "register_operand" "")
7438 (match_operand:DF 2 "nonimmediate_operand" "")))]
7439 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7442 (define_expand "divsf3"
7443 [(set (match_operand:SF 0 "register_operand" "")
7444 (div:SF (match_operand:SF 1 "register_operand" "")
7445 (match_operand:SF 2 "nonimmediate_operand" "")))]
7446 "TARGET_80387 || TARGET_SSE_MATH"
7449 ;; Remainder instructions.
7451 (define_expand "divmoddi4"
7452 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7453 (div:DI (match_operand:DI 1 "register_operand" "")
7454 (match_operand:DI 2 "nonimmediate_operand" "")))
7455 (set (match_operand:DI 3 "register_operand" "")
7456 (mod:DI (match_dup 1) (match_dup 2)))
7457 (clobber (reg:CC FLAGS_REG))])]
7461 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7462 ;; Penalize eax case slightly because it results in worse scheduling
7464 (define_insn "*divmoddi4_nocltd_rex64"
7465 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7466 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7467 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7468 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7469 (mod:DI (match_dup 2) (match_dup 3)))
7470 (clobber (reg:CC FLAGS_REG))]
7471 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7473 [(set_attr "type" "multi")])
7475 (define_insn "*divmoddi4_cltd_rex64"
7476 [(set (match_operand:DI 0 "register_operand" "=a")
7477 (div:DI (match_operand:DI 2 "register_operand" "a")
7478 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7479 (set (match_operand:DI 1 "register_operand" "=&d")
7480 (mod:DI (match_dup 2) (match_dup 3)))
7481 (clobber (reg:CC FLAGS_REG))]
7482 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7484 [(set_attr "type" "multi")])
7486 (define_insn "*divmoddi_noext_rex64"
7487 [(set (match_operand:DI 0 "register_operand" "=a")
7488 (div:DI (match_operand:DI 1 "register_operand" "0")
7489 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7490 (set (match_operand:DI 3 "register_operand" "=d")
7491 (mod:DI (match_dup 1) (match_dup 2)))
7492 (use (match_operand:DI 4 "register_operand" "3"))
7493 (clobber (reg:CC FLAGS_REG))]
7496 [(set_attr "type" "idiv")
7497 (set_attr "mode" "DI")])
7500 [(set (match_operand:DI 0 "register_operand" "")
7501 (div:DI (match_operand:DI 1 "register_operand" "")
7502 (match_operand:DI 2 "nonimmediate_operand" "")))
7503 (set (match_operand:DI 3 "register_operand" "")
7504 (mod:DI (match_dup 1) (match_dup 2)))
7505 (clobber (reg:CC FLAGS_REG))]
7506 "TARGET_64BIT && reload_completed"
7507 [(parallel [(set (match_dup 3)
7508 (ashiftrt:DI (match_dup 4) (const_int 63)))
7509 (clobber (reg:CC FLAGS_REG))])
7510 (parallel [(set (match_dup 0)
7511 (div:DI (reg:DI 0) (match_dup 2)))
7513 (mod:DI (reg:DI 0) (match_dup 2)))
7515 (clobber (reg:CC FLAGS_REG))])]
7517 /* Avoid use of cltd in favor of a mov+shift. */
7518 if (!TARGET_USE_CLTD && !optimize_size)
7520 if (true_regnum (operands[1]))
7521 emit_move_insn (operands[0], operands[1]);
7523 emit_move_insn (operands[3], operands[1]);
7524 operands[4] = operands[3];
7528 gcc_assert (!true_regnum (operands[1]));
7529 operands[4] = operands[1];
7534 (define_expand "divmodsi4"
7535 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7536 (div:SI (match_operand:SI 1 "register_operand" "")
7537 (match_operand:SI 2 "nonimmediate_operand" "")))
7538 (set (match_operand:SI 3 "register_operand" "")
7539 (mod:SI (match_dup 1) (match_dup 2)))
7540 (clobber (reg:CC FLAGS_REG))])]
7544 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7545 ;; Penalize eax case slightly because it results in worse scheduling
7547 (define_insn "*divmodsi4_nocltd"
7548 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7549 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7550 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7551 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7552 (mod:SI (match_dup 2) (match_dup 3)))
7553 (clobber (reg:CC FLAGS_REG))]
7554 "!optimize_size && !TARGET_USE_CLTD"
7556 [(set_attr "type" "multi")])
7558 (define_insn "*divmodsi4_cltd"
7559 [(set (match_operand:SI 0 "register_operand" "=a")
7560 (div:SI (match_operand:SI 2 "register_operand" "a")
7561 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7562 (set (match_operand:SI 1 "register_operand" "=&d")
7563 (mod:SI (match_dup 2) (match_dup 3)))
7564 (clobber (reg:CC FLAGS_REG))]
7565 "optimize_size || TARGET_USE_CLTD"
7567 [(set_attr "type" "multi")])
7569 (define_insn "*divmodsi_noext"
7570 [(set (match_operand:SI 0 "register_operand" "=a")
7571 (div:SI (match_operand:SI 1 "register_operand" "0")
7572 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7573 (set (match_operand:SI 3 "register_operand" "=d")
7574 (mod:SI (match_dup 1) (match_dup 2)))
7575 (use (match_operand:SI 4 "register_operand" "3"))
7576 (clobber (reg:CC FLAGS_REG))]
7579 [(set_attr "type" "idiv")
7580 (set_attr "mode" "SI")])
7583 [(set (match_operand:SI 0 "register_operand" "")
7584 (div:SI (match_operand:SI 1 "register_operand" "")
7585 (match_operand:SI 2 "nonimmediate_operand" "")))
7586 (set (match_operand:SI 3 "register_operand" "")
7587 (mod:SI (match_dup 1) (match_dup 2)))
7588 (clobber (reg:CC FLAGS_REG))]
7590 [(parallel [(set (match_dup 3)
7591 (ashiftrt:SI (match_dup 4) (const_int 31)))
7592 (clobber (reg:CC FLAGS_REG))])
7593 (parallel [(set (match_dup 0)
7594 (div:SI (reg:SI 0) (match_dup 2)))
7596 (mod:SI (reg:SI 0) (match_dup 2)))
7598 (clobber (reg:CC FLAGS_REG))])]
7600 /* Avoid use of cltd in favor of a mov+shift. */
7601 if (!TARGET_USE_CLTD && !optimize_size)
7603 if (true_regnum (operands[1]))
7604 emit_move_insn (operands[0], operands[1]);
7606 emit_move_insn (operands[3], operands[1]);
7607 operands[4] = operands[3];
7611 gcc_assert (!true_regnum (operands[1]));
7612 operands[4] = operands[1];
7616 (define_insn "divmodhi4"
7617 [(set (match_operand:HI 0 "register_operand" "=a")
7618 (div:HI (match_operand:HI 1 "register_operand" "0")
7619 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7620 (set (match_operand:HI 3 "register_operand" "=&d")
7621 (mod:HI (match_dup 1) (match_dup 2)))
7622 (clobber (reg:CC FLAGS_REG))]
7623 "TARGET_HIMODE_MATH"
7625 [(set_attr "type" "multi")
7626 (set_attr "length_immediate" "0")
7627 (set_attr "mode" "SI")])
7629 (define_insn "udivmoddi4"
7630 [(set (match_operand:DI 0 "register_operand" "=a")
7631 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7632 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7633 (set (match_operand:DI 3 "register_operand" "=&d")
7634 (umod:DI (match_dup 1) (match_dup 2)))
7635 (clobber (reg:CC FLAGS_REG))]
7637 "xor{q}\t%3, %3\;div{q}\t%2"
7638 [(set_attr "type" "multi")
7639 (set_attr "length_immediate" "0")
7640 (set_attr "mode" "DI")])
7642 (define_insn "*udivmoddi4_noext"
7643 [(set (match_operand:DI 0 "register_operand" "=a")
7644 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7645 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7646 (set (match_operand:DI 3 "register_operand" "=d")
7647 (umod:DI (match_dup 1) (match_dup 2)))
7649 (clobber (reg:CC FLAGS_REG))]
7652 [(set_attr "type" "idiv")
7653 (set_attr "mode" "DI")])
7656 [(set (match_operand:DI 0 "register_operand" "")
7657 (udiv:DI (match_operand:DI 1 "register_operand" "")
7658 (match_operand:DI 2 "nonimmediate_operand" "")))
7659 (set (match_operand:DI 3 "register_operand" "")
7660 (umod:DI (match_dup 1) (match_dup 2)))
7661 (clobber (reg:CC FLAGS_REG))]
7662 "TARGET_64BIT && reload_completed"
7663 [(set (match_dup 3) (const_int 0))
7664 (parallel [(set (match_dup 0)
7665 (udiv:DI (match_dup 1) (match_dup 2)))
7667 (umod:DI (match_dup 1) (match_dup 2)))
7669 (clobber (reg:CC FLAGS_REG))])]
7672 (define_insn "udivmodsi4"
7673 [(set (match_operand:SI 0 "register_operand" "=a")
7674 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7675 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7676 (set (match_operand:SI 3 "register_operand" "=&d")
7677 (umod:SI (match_dup 1) (match_dup 2)))
7678 (clobber (reg:CC FLAGS_REG))]
7680 "xor{l}\t%3, %3\;div{l}\t%2"
7681 [(set_attr "type" "multi")
7682 (set_attr "length_immediate" "0")
7683 (set_attr "mode" "SI")])
7685 (define_insn "*udivmodsi4_noext"
7686 [(set (match_operand:SI 0 "register_operand" "=a")
7687 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7688 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7689 (set (match_operand:SI 3 "register_operand" "=d")
7690 (umod:SI (match_dup 1) (match_dup 2)))
7692 (clobber (reg:CC FLAGS_REG))]
7695 [(set_attr "type" "idiv")
7696 (set_attr "mode" "SI")])
7699 [(set (match_operand:SI 0 "register_operand" "")
7700 (udiv:SI (match_operand:SI 1 "register_operand" "")
7701 (match_operand:SI 2 "nonimmediate_operand" "")))
7702 (set (match_operand:SI 3 "register_operand" "")
7703 (umod:SI (match_dup 1) (match_dup 2)))
7704 (clobber (reg:CC FLAGS_REG))]
7706 [(set (match_dup 3) (const_int 0))
7707 (parallel [(set (match_dup 0)
7708 (udiv:SI (match_dup 1) (match_dup 2)))
7710 (umod:SI (match_dup 1) (match_dup 2)))
7712 (clobber (reg:CC FLAGS_REG))])]
7715 (define_expand "udivmodhi4"
7716 [(set (match_dup 4) (const_int 0))
7717 (parallel [(set (match_operand:HI 0 "register_operand" "")
7718 (udiv:HI (match_operand:HI 1 "register_operand" "")
7719 (match_operand:HI 2 "nonimmediate_operand" "")))
7720 (set (match_operand:HI 3 "register_operand" "")
7721 (umod:HI (match_dup 1) (match_dup 2)))
7723 (clobber (reg:CC FLAGS_REG))])]
7724 "TARGET_HIMODE_MATH"
7725 "operands[4] = gen_reg_rtx (HImode);")
7727 (define_insn "*udivmodhi_noext"
7728 [(set (match_operand:HI 0 "register_operand" "=a")
7729 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7730 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7731 (set (match_operand:HI 3 "register_operand" "=d")
7732 (umod:HI (match_dup 1) (match_dup 2)))
7733 (use (match_operand:HI 4 "register_operand" "3"))
7734 (clobber (reg:CC FLAGS_REG))]
7737 [(set_attr "type" "idiv")
7738 (set_attr "mode" "HI")])
7740 ;; We cannot use div/idiv for double division, because it causes
7741 ;; "division by zero" on the overflow and that's not what we expect
7742 ;; from truncate. Because true (non truncating) double division is
7743 ;; never generated, we can't create this insn anyway.
7746 ; [(set (match_operand:SI 0 "register_operand" "=a")
7748 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7750 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7751 ; (set (match_operand:SI 3 "register_operand" "=d")
7753 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7754 ; (clobber (reg:CC FLAGS_REG))]
7756 ; "div{l}\t{%2, %0|%0, %2}"
7757 ; [(set_attr "type" "idiv")])
7759 ;;- Logical AND instructions
7761 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7762 ;; Note that this excludes ah.
7764 (define_insn "*testdi_1_rex64"
7765 [(set (reg FLAGS_REG)
7767 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7768 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7770 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7771 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7773 test{l}\t{%k1, %k0|%k0, %k1}
7774 test{l}\t{%k1, %k0|%k0, %k1}
7775 test{q}\t{%1, %0|%0, %1}
7776 test{q}\t{%1, %0|%0, %1}
7777 test{q}\t{%1, %0|%0, %1}"
7778 [(set_attr "type" "test")
7779 (set_attr "modrm" "0,1,0,1,1")
7780 (set_attr "mode" "SI,SI,DI,DI,DI")
7781 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7783 (define_insn "testsi_1"
7784 [(set (reg FLAGS_REG)
7786 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7787 (match_operand:SI 1 "general_operand" "in,in,rin"))
7789 "ix86_match_ccmode (insn, CCNOmode)
7790 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7791 "test{l}\t{%1, %0|%0, %1}"
7792 [(set_attr "type" "test")
7793 (set_attr "modrm" "0,1,1")
7794 (set_attr "mode" "SI")
7795 (set_attr "pent_pair" "uv,np,uv")])
7797 (define_expand "testsi_ccno_1"
7798 [(set (reg:CCNO FLAGS_REG)
7800 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7801 (match_operand:SI 1 "nonmemory_operand" ""))
7806 (define_insn "*testhi_1"
7807 [(set (reg FLAGS_REG)
7808 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7809 (match_operand:HI 1 "general_operand" "n,n,rn"))
7811 "ix86_match_ccmode (insn, CCNOmode)
7812 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7813 "test{w}\t{%1, %0|%0, %1}"
7814 [(set_attr "type" "test")
7815 (set_attr "modrm" "0,1,1")
7816 (set_attr "mode" "HI")
7817 (set_attr "pent_pair" "uv,np,uv")])
7819 (define_expand "testqi_ccz_1"
7820 [(set (reg:CCZ FLAGS_REG)
7821 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7822 (match_operand:QI 1 "nonmemory_operand" ""))
7827 (define_insn "*testqi_1_maybe_si"
7828 [(set (reg FLAGS_REG)
7831 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7832 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7834 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7835 && ix86_match_ccmode (insn,
7836 GET_CODE (operands[1]) == CONST_INT
7837 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7839 if (which_alternative == 3)
7841 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7842 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7843 return "test{l}\t{%1, %k0|%k0, %1}";
7845 return "test{b}\t{%1, %0|%0, %1}";
7847 [(set_attr "type" "test")
7848 (set_attr "modrm" "0,1,1,1")
7849 (set_attr "mode" "QI,QI,QI,SI")
7850 (set_attr "pent_pair" "uv,np,uv,np")])
7852 (define_insn "*testqi_1"
7853 [(set (reg FLAGS_REG)
7856 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7857 (match_operand:QI 1 "general_operand" "n,n,qn"))
7859 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7860 && ix86_match_ccmode (insn, CCNOmode)"
7861 "test{b}\t{%1, %0|%0, %1}"
7862 [(set_attr "type" "test")
7863 (set_attr "modrm" "0,1,1")
7864 (set_attr "mode" "QI")
7865 (set_attr "pent_pair" "uv,np,uv")])
7867 (define_expand "testqi_ext_ccno_0"
7868 [(set (reg:CCNO FLAGS_REG)
7872 (match_operand 0 "ext_register_operand" "")
7875 (match_operand 1 "const_int_operand" ""))
7880 (define_insn "*testqi_ext_0"
7881 [(set (reg FLAGS_REG)
7885 (match_operand 0 "ext_register_operand" "Q")
7888 (match_operand 1 "const_int_operand" "n"))
7890 "ix86_match_ccmode (insn, CCNOmode)"
7891 "test{b}\t{%1, %h0|%h0, %1}"
7892 [(set_attr "type" "test")
7893 (set_attr "mode" "QI")
7894 (set_attr "length_immediate" "1")
7895 (set_attr "pent_pair" "np")])
7897 (define_insn "*testqi_ext_1"
7898 [(set (reg FLAGS_REG)
7902 (match_operand 0 "ext_register_operand" "Q")
7906 (match_operand:QI 1 "general_operand" "Qm")))
7908 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7909 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7910 "test{b}\t{%1, %h0|%h0, %1}"
7911 [(set_attr "type" "test")
7912 (set_attr "mode" "QI")])
7914 (define_insn "*testqi_ext_1_rex64"
7915 [(set (reg FLAGS_REG)
7919 (match_operand 0 "ext_register_operand" "Q")
7923 (match_operand:QI 1 "register_operand" "Q")))
7925 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7926 "test{b}\t{%1, %h0|%h0, %1}"
7927 [(set_attr "type" "test")
7928 (set_attr "mode" "QI")])
7930 (define_insn "*testqi_ext_2"
7931 [(set (reg FLAGS_REG)
7935 (match_operand 0 "ext_register_operand" "Q")
7939 (match_operand 1 "ext_register_operand" "Q")
7943 "ix86_match_ccmode (insn, CCNOmode)"
7944 "test{b}\t{%h1, %h0|%h0, %h1}"
7945 [(set_attr "type" "test")
7946 (set_attr "mode" "QI")])
7948 ;; Combine likes to form bit extractions for some tests. Humor it.
7949 (define_insn "*testqi_ext_3"
7950 [(set (reg FLAGS_REG)
7951 (compare (zero_extract:SI
7952 (match_operand 0 "nonimmediate_operand" "rm")
7953 (match_operand:SI 1 "const_int_operand" "")
7954 (match_operand:SI 2 "const_int_operand" ""))
7956 "ix86_match_ccmode (insn, CCNOmode)
7957 && INTVAL (operands[1]) > 0
7958 && INTVAL (operands[2]) >= 0
7959 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7960 && (GET_MODE (operands[0]) == SImode
7961 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7962 || GET_MODE (operands[0]) == HImode
7963 || GET_MODE (operands[0]) == QImode)"
7966 (define_insn "*testqi_ext_3_rex64"
7967 [(set (reg FLAGS_REG)
7968 (compare (zero_extract:DI
7969 (match_operand 0 "nonimmediate_operand" "rm")
7970 (match_operand:DI 1 "const_int_operand" "")
7971 (match_operand:DI 2 "const_int_operand" ""))
7974 && ix86_match_ccmode (insn, CCNOmode)
7975 && INTVAL (operands[1]) > 0
7976 && INTVAL (operands[2]) >= 0
7977 /* Ensure that resulting mask is zero or sign extended operand. */
7978 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7979 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7980 && INTVAL (operands[1]) > 32))
7981 && (GET_MODE (operands[0]) == SImode
7982 || GET_MODE (operands[0]) == DImode
7983 || GET_MODE (operands[0]) == HImode
7984 || GET_MODE (operands[0]) == QImode)"
7988 [(set (match_operand 0 "flags_reg_operand" "")
7989 (match_operator 1 "compare_operator"
7991 (match_operand 2 "nonimmediate_operand" "")
7992 (match_operand 3 "const_int_operand" "")
7993 (match_operand 4 "const_int_operand" ""))
7995 "ix86_match_ccmode (insn, CCNOmode)"
7996 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7998 rtx val = operands[2];
7999 HOST_WIDE_INT len = INTVAL (operands[3]);
8000 HOST_WIDE_INT pos = INTVAL (operands[4]);
8002 enum machine_mode mode, submode;
8004 mode = GET_MODE (val);
8005 if (GET_CODE (val) == MEM)
8007 /* ??? Combine likes to put non-volatile mem extractions in QImode
8008 no matter the size of the test. So find a mode that works. */
8009 if (! MEM_VOLATILE_P (val))
8011 mode = smallest_mode_for_size (pos + len, MODE_INT);
8012 val = adjust_address (val, mode, 0);
8015 else if (GET_CODE (val) == SUBREG
8016 && (submode = GET_MODE (SUBREG_REG (val)),
8017 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8018 && pos + len <= GET_MODE_BITSIZE (submode))
8020 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8022 val = SUBREG_REG (val);
8024 else if (mode == HImode && pos + len <= 8)
8026 /* Small HImode tests can be converted to QImode. */
8028 val = gen_lowpart (QImode, val);
8031 if (len == HOST_BITS_PER_WIDE_INT)
8034 mask = ((HOST_WIDE_INT)1 << len) - 1;
8037 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8040 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8041 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8042 ;; this is relatively important trick.
8043 ;; Do the conversion only post-reload to avoid limiting of the register class
8046 [(set (match_operand 0 "flags_reg_operand" "")
8047 (match_operator 1 "compare_operator"
8048 [(and (match_operand 2 "register_operand" "")
8049 (match_operand 3 "const_int_operand" ""))
8052 && QI_REG_P (operands[2])
8053 && GET_MODE (operands[2]) != QImode
8054 && ((ix86_match_ccmode (insn, CCZmode)
8055 && !(INTVAL (operands[3]) & ~(255 << 8)))
8056 || (ix86_match_ccmode (insn, CCNOmode)
8057 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8060 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8063 "operands[2] = gen_lowpart (SImode, operands[2]);
8064 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8067 [(set (match_operand 0 "flags_reg_operand" "")
8068 (match_operator 1 "compare_operator"
8069 [(and (match_operand 2 "nonimmediate_operand" "")
8070 (match_operand 3 "const_int_operand" ""))
8073 && GET_MODE (operands[2]) != QImode
8074 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8075 && ((ix86_match_ccmode (insn, CCZmode)
8076 && !(INTVAL (operands[3]) & ~255))
8077 || (ix86_match_ccmode (insn, CCNOmode)
8078 && !(INTVAL (operands[3]) & ~127)))"
8080 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8082 "operands[2] = gen_lowpart (QImode, operands[2]);
8083 operands[3] = gen_lowpart (QImode, operands[3]);")
8086 ;; %%% This used to optimize known byte-wide and operations to memory,
8087 ;; and sometimes to QImode registers. If this is considered useful,
8088 ;; it should be done with splitters.
8090 (define_expand "anddi3"
8091 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8092 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8093 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8094 (clobber (reg:CC FLAGS_REG))]
8096 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8098 (define_insn "*anddi_1_rex64"
8099 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8100 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8101 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8102 (clobber (reg:CC FLAGS_REG))]
8103 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8105 switch (get_attr_type (insn))
8109 enum machine_mode mode;
8111 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8112 if (INTVAL (operands[2]) == 0xff)
8116 gcc_assert (INTVAL (operands[2]) == 0xffff);
8120 operands[1] = gen_lowpart (mode, operands[1]);
8122 return "movz{bq|x}\t{%1,%0|%0, %1}";
8124 return "movz{wq|x}\t{%1,%0|%0, %1}";
8128 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8129 if (get_attr_mode (insn) == MODE_SI)
8130 return "and{l}\t{%k2, %k0|%k0, %k2}";
8132 return "and{q}\t{%2, %0|%0, %2}";
8135 [(set_attr "type" "alu,alu,alu,imovx")
8136 (set_attr "length_immediate" "*,*,*,0")
8137 (set_attr "mode" "SI,DI,DI,DI")])
8139 (define_insn "*anddi_2"
8140 [(set (reg FLAGS_REG)
8141 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8142 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8144 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8145 (and:DI (match_dup 1) (match_dup 2)))]
8146 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8147 && ix86_binary_operator_ok (AND, DImode, operands)"
8149 and{l}\t{%k2, %k0|%k0, %k2}
8150 and{q}\t{%2, %0|%0, %2}
8151 and{q}\t{%2, %0|%0, %2}"
8152 [(set_attr "type" "alu")
8153 (set_attr "mode" "SI,DI,DI")])
8155 (define_expand "andsi3"
8156 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8157 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8158 (match_operand:SI 2 "general_operand" "")))
8159 (clobber (reg:CC FLAGS_REG))]
8161 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8163 (define_insn "*andsi_1"
8164 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8165 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8166 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8167 (clobber (reg:CC FLAGS_REG))]
8168 "ix86_binary_operator_ok (AND, SImode, operands)"
8170 switch (get_attr_type (insn))
8174 enum machine_mode mode;
8176 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8177 if (INTVAL (operands[2]) == 0xff)
8181 gcc_assert (INTVAL (operands[2]) == 0xffff);
8185 operands[1] = gen_lowpart (mode, operands[1]);
8187 return "movz{bl|x}\t{%1,%0|%0, %1}";
8189 return "movz{wl|x}\t{%1,%0|%0, %1}";
8193 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8194 return "and{l}\t{%2, %0|%0, %2}";
8197 [(set_attr "type" "alu,alu,imovx")
8198 (set_attr "length_immediate" "*,*,0")
8199 (set_attr "mode" "SI")])
8202 [(set (match_operand 0 "register_operand" "")
8204 (const_int -65536)))
8205 (clobber (reg:CC FLAGS_REG))]
8206 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8207 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8208 "operands[1] = gen_lowpart (HImode, operands[0]);")
8211 [(set (match_operand 0 "ext_register_operand" "")
8214 (clobber (reg:CC FLAGS_REG))]
8215 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8216 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8217 "operands[1] = gen_lowpart (QImode, operands[0]);")
8220 [(set (match_operand 0 "ext_register_operand" "")
8222 (const_int -65281)))
8223 (clobber (reg:CC FLAGS_REG))]
8224 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8225 [(parallel [(set (zero_extract:SI (match_dup 0)
8229 (zero_extract:SI (match_dup 0)
8232 (zero_extract:SI (match_dup 0)
8235 (clobber (reg:CC FLAGS_REG))])]
8236 "operands[0] = gen_lowpart (SImode, operands[0]);")
8238 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8239 (define_insn "*andsi_1_zext"
8240 [(set (match_operand:DI 0 "register_operand" "=r")
8242 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8243 (match_operand:SI 2 "general_operand" "rim"))))
8244 (clobber (reg:CC FLAGS_REG))]
8245 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8246 "and{l}\t{%2, %k0|%k0, %2}"
8247 [(set_attr "type" "alu")
8248 (set_attr "mode" "SI")])
8250 (define_insn "*andsi_2"
8251 [(set (reg FLAGS_REG)
8252 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8253 (match_operand:SI 2 "general_operand" "rim,ri"))
8255 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8256 (and:SI (match_dup 1) (match_dup 2)))]
8257 "ix86_match_ccmode (insn, CCNOmode)
8258 && ix86_binary_operator_ok (AND, SImode, operands)"
8259 "and{l}\t{%2, %0|%0, %2}"
8260 [(set_attr "type" "alu")
8261 (set_attr "mode" "SI")])
8263 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8264 (define_insn "*andsi_2_zext"
8265 [(set (reg FLAGS_REG)
8266 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8267 (match_operand:SI 2 "general_operand" "rim"))
8269 (set (match_operand:DI 0 "register_operand" "=r")
8270 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8271 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8272 && ix86_binary_operator_ok (AND, SImode, operands)"
8273 "and{l}\t{%2, %k0|%k0, %2}"
8274 [(set_attr "type" "alu")
8275 (set_attr "mode" "SI")])
8277 (define_expand "andhi3"
8278 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8279 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8280 (match_operand:HI 2 "general_operand" "")))
8281 (clobber (reg:CC FLAGS_REG))]
8282 "TARGET_HIMODE_MATH"
8283 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8285 (define_insn "*andhi_1"
8286 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8287 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8288 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8289 (clobber (reg:CC FLAGS_REG))]
8290 "ix86_binary_operator_ok (AND, HImode, operands)"
8292 switch (get_attr_type (insn))
8295 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8296 gcc_assert (INTVAL (operands[2]) == 0xff);
8297 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8300 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8302 return "and{w}\t{%2, %0|%0, %2}";
8305 [(set_attr "type" "alu,alu,imovx")
8306 (set_attr "length_immediate" "*,*,0")
8307 (set_attr "mode" "HI,HI,SI")])
8309 (define_insn "*andhi_2"
8310 [(set (reg FLAGS_REG)
8311 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8312 (match_operand:HI 2 "general_operand" "rim,ri"))
8314 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8315 (and:HI (match_dup 1) (match_dup 2)))]
8316 "ix86_match_ccmode (insn, CCNOmode)
8317 && ix86_binary_operator_ok (AND, HImode, operands)"
8318 "and{w}\t{%2, %0|%0, %2}"
8319 [(set_attr "type" "alu")
8320 (set_attr "mode" "HI")])
8322 (define_expand "andqi3"
8323 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8324 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8325 (match_operand:QI 2 "general_operand" "")))
8326 (clobber (reg:CC FLAGS_REG))]
8327 "TARGET_QIMODE_MATH"
8328 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8330 ;; %%% Potential partial reg stall on alternative 2. What to do?
8331 (define_insn "*andqi_1"
8332 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8333 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8334 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8335 (clobber (reg:CC FLAGS_REG))]
8336 "ix86_binary_operator_ok (AND, QImode, operands)"
8338 and{b}\t{%2, %0|%0, %2}
8339 and{b}\t{%2, %0|%0, %2}
8340 and{l}\t{%k2, %k0|%k0, %k2}"
8341 [(set_attr "type" "alu")
8342 (set_attr "mode" "QI,QI,SI")])
8344 (define_insn "*andqi_1_slp"
8345 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8346 (and:QI (match_dup 0)
8347 (match_operand:QI 1 "general_operand" "qi,qmi")))
8348 (clobber (reg:CC FLAGS_REG))]
8349 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8350 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8351 "and{b}\t{%1, %0|%0, %1}"
8352 [(set_attr "type" "alu1")
8353 (set_attr "mode" "QI")])
8355 (define_insn "*andqi_2_maybe_si"
8356 [(set (reg FLAGS_REG)
8358 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8359 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8361 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8362 (and:QI (match_dup 1) (match_dup 2)))]
8363 "ix86_binary_operator_ok (AND, QImode, operands)
8364 && ix86_match_ccmode (insn,
8365 GET_CODE (operands[2]) == CONST_INT
8366 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8368 if (which_alternative == 2)
8370 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8371 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8372 return "and{l}\t{%2, %k0|%k0, %2}";
8374 return "and{b}\t{%2, %0|%0, %2}";
8376 [(set_attr "type" "alu")
8377 (set_attr "mode" "QI,QI,SI")])
8379 (define_insn "*andqi_2"
8380 [(set (reg FLAGS_REG)
8382 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8383 (match_operand:QI 2 "general_operand" "qim,qi"))
8385 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8386 (and:QI (match_dup 1) (match_dup 2)))]
8387 "ix86_match_ccmode (insn, CCNOmode)
8388 && ix86_binary_operator_ok (AND, QImode, operands)"
8389 "and{b}\t{%2, %0|%0, %2}"
8390 [(set_attr "type" "alu")
8391 (set_attr "mode" "QI")])
8393 (define_insn "*andqi_2_slp"
8394 [(set (reg FLAGS_REG)
8396 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8397 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8399 (set (strict_low_part (match_dup 0))
8400 (and:QI (match_dup 0) (match_dup 1)))]
8401 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8402 && ix86_match_ccmode (insn, CCNOmode)
8403 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8404 "and{b}\t{%1, %0|%0, %1}"
8405 [(set_attr "type" "alu1")
8406 (set_attr "mode" "QI")])
8408 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8409 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8410 ;; for a QImode operand, which of course failed.
8412 (define_insn "andqi_ext_0"
8413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8418 (match_operand 1 "ext_register_operand" "0")
8421 (match_operand 2 "const_int_operand" "n")))
8422 (clobber (reg:CC FLAGS_REG))]
8424 "and{b}\t{%2, %h0|%h0, %2}"
8425 [(set_attr "type" "alu")
8426 (set_attr "length_immediate" "1")
8427 (set_attr "mode" "QI")])
8429 ;; Generated by peephole translating test to and. This shows up
8430 ;; often in fp comparisons.
8432 (define_insn "*andqi_ext_0_cc"
8433 [(set (reg FLAGS_REG)
8437 (match_operand 1 "ext_register_operand" "0")
8440 (match_operand 2 "const_int_operand" "n"))
8442 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8451 "ix86_match_ccmode (insn, CCNOmode)"
8452 "and{b}\t{%2, %h0|%h0, %2}"
8453 [(set_attr "type" "alu")
8454 (set_attr "length_immediate" "1")
8455 (set_attr "mode" "QI")])
8457 (define_insn "*andqi_ext_1"
8458 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8463 (match_operand 1 "ext_register_operand" "0")
8467 (match_operand:QI 2 "general_operand" "Qm"))))
8468 (clobber (reg:CC FLAGS_REG))]
8470 "and{b}\t{%2, %h0|%h0, %2}"
8471 [(set_attr "type" "alu")
8472 (set_attr "length_immediate" "0")
8473 (set_attr "mode" "QI")])
8475 (define_insn "*andqi_ext_1_rex64"
8476 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8481 (match_operand 1 "ext_register_operand" "0")
8485 (match_operand 2 "ext_register_operand" "Q"))))
8486 (clobber (reg:CC FLAGS_REG))]
8488 "and{b}\t{%2, %h0|%h0, %2}"
8489 [(set_attr "type" "alu")
8490 (set_attr "length_immediate" "0")
8491 (set_attr "mode" "QI")])
8493 (define_insn "*andqi_ext_2"
8494 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8499 (match_operand 1 "ext_register_operand" "%0")
8503 (match_operand 2 "ext_register_operand" "Q")
8506 (clobber (reg:CC FLAGS_REG))]
8508 "and{b}\t{%h2, %h0|%h0, %h2}"
8509 [(set_attr "type" "alu")
8510 (set_attr "length_immediate" "0")
8511 (set_attr "mode" "QI")])
8513 ;; Convert wide AND instructions with immediate operand to shorter QImode
8514 ;; equivalents when possible.
8515 ;; Don't do the splitting with memory operands, since it introduces risk
8516 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8517 ;; for size, but that can (should?) be handled by generic code instead.
8519 [(set (match_operand 0 "register_operand" "")
8520 (and (match_operand 1 "register_operand" "")
8521 (match_operand 2 "const_int_operand" "")))
8522 (clobber (reg:CC FLAGS_REG))]
8524 && QI_REG_P (operands[0])
8525 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8526 && !(~INTVAL (operands[2]) & ~(255 << 8))
8527 && GET_MODE (operands[0]) != QImode"
8528 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8529 (and:SI (zero_extract:SI (match_dup 1)
8530 (const_int 8) (const_int 8))
8532 (clobber (reg:CC FLAGS_REG))])]
8533 "operands[0] = gen_lowpart (SImode, operands[0]);
8534 operands[1] = gen_lowpart (SImode, operands[1]);
8535 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8537 ;; Since AND can be encoded with sign extended immediate, this is only
8538 ;; profitable when 7th bit is not set.
8540 [(set (match_operand 0 "register_operand" "")
8541 (and (match_operand 1 "general_operand" "")
8542 (match_operand 2 "const_int_operand" "")))
8543 (clobber (reg:CC FLAGS_REG))]
8545 && ANY_QI_REG_P (operands[0])
8546 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8547 && !(~INTVAL (operands[2]) & ~255)
8548 && !(INTVAL (operands[2]) & 128)
8549 && GET_MODE (operands[0]) != QImode"
8550 [(parallel [(set (strict_low_part (match_dup 0))
8551 (and:QI (match_dup 1)
8553 (clobber (reg:CC FLAGS_REG))])]
8554 "operands[0] = gen_lowpart (QImode, operands[0]);
8555 operands[1] = gen_lowpart (QImode, operands[1]);
8556 operands[2] = gen_lowpart (QImode, operands[2]);")
8558 ;; Logical inclusive OR instructions
8560 ;; %%% This used to optimize known byte-wide and operations to memory.
8561 ;; If this is considered useful, it should be done with splitters.
8563 (define_expand "iordi3"
8564 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8565 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8566 (match_operand:DI 2 "x86_64_general_operand" "")))
8567 (clobber (reg:CC FLAGS_REG))]
8569 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8571 (define_insn "*iordi_1_rex64"
8572 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8573 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8574 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8575 (clobber (reg:CC FLAGS_REG))]
8577 && ix86_binary_operator_ok (IOR, DImode, operands)"
8578 "or{q}\t{%2, %0|%0, %2}"
8579 [(set_attr "type" "alu")
8580 (set_attr "mode" "DI")])
8582 (define_insn "*iordi_2_rex64"
8583 [(set (reg FLAGS_REG)
8584 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8585 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8587 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8588 (ior:DI (match_dup 1) (match_dup 2)))]
8590 && ix86_match_ccmode (insn, CCNOmode)
8591 && ix86_binary_operator_ok (IOR, DImode, operands)"
8592 "or{q}\t{%2, %0|%0, %2}"
8593 [(set_attr "type" "alu")
8594 (set_attr "mode" "DI")])
8596 (define_insn "*iordi_3_rex64"
8597 [(set (reg FLAGS_REG)
8598 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8599 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8601 (clobber (match_scratch:DI 0 "=r"))]
8603 && ix86_match_ccmode (insn, CCNOmode)
8604 && ix86_binary_operator_ok (IOR, DImode, operands)"
8605 "or{q}\t{%2, %0|%0, %2}"
8606 [(set_attr "type" "alu")
8607 (set_attr "mode" "DI")])
8610 (define_expand "iorsi3"
8611 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8612 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8613 (match_operand:SI 2 "general_operand" "")))
8614 (clobber (reg:CC FLAGS_REG))]
8616 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8618 (define_insn "*iorsi_1"
8619 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8620 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8621 (match_operand:SI 2 "general_operand" "ri,rmi")))
8622 (clobber (reg:CC FLAGS_REG))]
8623 "ix86_binary_operator_ok (IOR, SImode, operands)"
8624 "or{l}\t{%2, %0|%0, %2}"
8625 [(set_attr "type" "alu")
8626 (set_attr "mode" "SI")])
8628 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8629 (define_insn "*iorsi_1_zext"
8630 [(set (match_operand:DI 0 "register_operand" "=rm")
8632 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8633 (match_operand:SI 2 "general_operand" "rim"))))
8634 (clobber (reg:CC FLAGS_REG))]
8635 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8636 "or{l}\t{%2, %k0|%k0, %2}"
8637 [(set_attr "type" "alu")
8638 (set_attr "mode" "SI")])
8640 (define_insn "*iorsi_1_zext_imm"
8641 [(set (match_operand:DI 0 "register_operand" "=rm")
8642 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8643 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8644 (clobber (reg:CC FLAGS_REG))]
8646 "or{l}\t{%2, %k0|%k0, %2}"
8647 [(set_attr "type" "alu")
8648 (set_attr "mode" "SI")])
8650 (define_insn "*iorsi_2"
8651 [(set (reg FLAGS_REG)
8652 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8653 (match_operand:SI 2 "general_operand" "rim,ri"))
8655 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8656 (ior:SI (match_dup 1) (match_dup 2)))]
8657 "ix86_match_ccmode (insn, CCNOmode)
8658 && ix86_binary_operator_ok (IOR, SImode, operands)"
8659 "or{l}\t{%2, %0|%0, %2}"
8660 [(set_attr "type" "alu")
8661 (set_attr "mode" "SI")])
8663 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8664 ;; ??? Special case for immediate operand is missing - it is tricky.
8665 (define_insn "*iorsi_2_zext"
8666 [(set (reg FLAGS_REG)
8667 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8668 (match_operand:SI 2 "general_operand" "rim"))
8670 (set (match_operand:DI 0 "register_operand" "=r")
8671 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8672 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8673 && ix86_binary_operator_ok (IOR, SImode, operands)"
8674 "or{l}\t{%2, %k0|%k0, %2}"
8675 [(set_attr "type" "alu")
8676 (set_attr "mode" "SI")])
8678 (define_insn "*iorsi_2_zext_imm"
8679 [(set (reg FLAGS_REG)
8680 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8681 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8683 (set (match_operand:DI 0 "register_operand" "=r")
8684 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8685 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8686 && ix86_binary_operator_ok (IOR, SImode, operands)"
8687 "or{l}\t{%2, %k0|%k0, %2}"
8688 [(set_attr "type" "alu")
8689 (set_attr "mode" "SI")])
8691 (define_insn "*iorsi_3"
8692 [(set (reg FLAGS_REG)
8693 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8694 (match_operand:SI 2 "general_operand" "rim"))
8696 (clobber (match_scratch:SI 0 "=r"))]
8697 "ix86_match_ccmode (insn, CCNOmode)
8698 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8699 "or{l}\t{%2, %0|%0, %2}"
8700 [(set_attr "type" "alu")
8701 (set_attr "mode" "SI")])
8703 (define_expand "iorhi3"
8704 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8705 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8706 (match_operand:HI 2 "general_operand" "")))
8707 (clobber (reg:CC FLAGS_REG))]
8708 "TARGET_HIMODE_MATH"
8709 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8711 (define_insn "*iorhi_1"
8712 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8713 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8714 (match_operand:HI 2 "general_operand" "rmi,ri")))
8715 (clobber (reg:CC FLAGS_REG))]
8716 "ix86_binary_operator_ok (IOR, HImode, operands)"
8717 "or{w}\t{%2, %0|%0, %2}"
8718 [(set_attr "type" "alu")
8719 (set_attr "mode" "HI")])
8721 (define_insn "*iorhi_2"
8722 [(set (reg FLAGS_REG)
8723 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8724 (match_operand:HI 2 "general_operand" "rim,ri"))
8726 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8727 (ior:HI (match_dup 1) (match_dup 2)))]
8728 "ix86_match_ccmode (insn, CCNOmode)
8729 && ix86_binary_operator_ok (IOR, HImode, operands)"
8730 "or{w}\t{%2, %0|%0, %2}"
8731 [(set_attr "type" "alu")
8732 (set_attr "mode" "HI")])
8734 (define_insn "*iorhi_3"
8735 [(set (reg FLAGS_REG)
8736 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8737 (match_operand:HI 2 "general_operand" "rim"))
8739 (clobber (match_scratch:HI 0 "=r"))]
8740 "ix86_match_ccmode (insn, CCNOmode)
8741 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8742 "or{w}\t{%2, %0|%0, %2}"
8743 [(set_attr "type" "alu")
8744 (set_attr "mode" "HI")])
8746 (define_expand "iorqi3"
8747 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8748 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8749 (match_operand:QI 2 "general_operand" "")))
8750 (clobber (reg:CC FLAGS_REG))]
8751 "TARGET_QIMODE_MATH"
8752 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8754 ;; %%% Potential partial reg stall on alternative 2. What to do?
8755 (define_insn "*iorqi_1"
8756 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8757 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8758 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8759 (clobber (reg:CC FLAGS_REG))]
8760 "ix86_binary_operator_ok (IOR, QImode, operands)"
8762 or{b}\t{%2, %0|%0, %2}
8763 or{b}\t{%2, %0|%0, %2}
8764 or{l}\t{%k2, %k0|%k0, %k2}"
8765 [(set_attr "type" "alu")
8766 (set_attr "mode" "QI,QI,SI")])
8768 (define_insn "*iorqi_1_slp"
8769 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8770 (ior:QI (match_dup 0)
8771 (match_operand:QI 1 "general_operand" "qmi,qi")))
8772 (clobber (reg:CC FLAGS_REG))]
8773 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8774 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8775 "or{b}\t{%1, %0|%0, %1}"
8776 [(set_attr "type" "alu1")
8777 (set_attr "mode" "QI")])
8779 (define_insn "*iorqi_2"
8780 [(set (reg FLAGS_REG)
8781 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8782 (match_operand:QI 2 "general_operand" "qim,qi"))
8784 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8785 (ior:QI (match_dup 1) (match_dup 2)))]
8786 "ix86_match_ccmode (insn, CCNOmode)
8787 && ix86_binary_operator_ok (IOR, QImode, operands)"
8788 "or{b}\t{%2, %0|%0, %2}"
8789 [(set_attr "type" "alu")
8790 (set_attr "mode" "QI")])
8792 (define_insn "*iorqi_2_slp"
8793 [(set (reg FLAGS_REG)
8794 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8795 (match_operand:QI 1 "general_operand" "qim,qi"))
8797 (set (strict_low_part (match_dup 0))
8798 (ior:QI (match_dup 0) (match_dup 1)))]
8799 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8800 && ix86_match_ccmode (insn, CCNOmode)
8801 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8802 "or{b}\t{%1, %0|%0, %1}"
8803 [(set_attr "type" "alu1")
8804 (set_attr "mode" "QI")])
8806 (define_insn "*iorqi_3"
8807 [(set (reg FLAGS_REG)
8808 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8809 (match_operand:QI 2 "general_operand" "qim"))
8811 (clobber (match_scratch:QI 0 "=q"))]
8812 "ix86_match_ccmode (insn, CCNOmode)
8813 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8814 "or{b}\t{%2, %0|%0, %2}"
8815 [(set_attr "type" "alu")
8816 (set_attr "mode" "QI")])
8818 (define_insn "iorqi_ext_0"
8819 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8824 (match_operand 1 "ext_register_operand" "0")
8827 (match_operand 2 "const_int_operand" "n")))
8828 (clobber (reg:CC FLAGS_REG))]
8829 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8830 "or{b}\t{%2, %h0|%h0, %2}"
8831 [(set_attr "type" "alu")
8832 (set_attr "length_immediate" "1")
8833 (set_attr "mode" "QI")])
8835 (define_insn "*iorqi_ext_1"
8836 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8841 (match_operand 1 "ext_register_operand" "0")
8845 (match_operand:QI 2 "general_operand" "Qm"))))
8846 (clobber (reg:CC FLAGS_REG))]
8848 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8849 "or{b}\t{%2, %h0|%h0, %2}"
8850 [(set_attr "type" "alu")
8851 (set_attr "length_immediate" "0")
8852 (set_attr "mode" "QI")])
8854 (define_insn "*iorqi_ext_1_rex64"
8855 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8860 (match_operand 1 "ext_register_operand" "0")
8864 (match_operand 2 "ext_register_operand" "Q"))))
8865 (clobber (reg:CC FLAGS_REG))]
8867 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8868 "or{b}\t{%2, %h0|%h0, %2}"
8869 [(set_attr "type" "alu")
8870 (set_attr "length_immediate" "0")
8871 (set_attr "mode" "QI")])
8873 (define_insn "*iorqi_ext_2"
8874 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8878 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8881 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8884 (clobber (reg:CC FLAGS_REG))]
8885 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8886 "ior{b}\t{%h2, %h0|%h0, %h2}"
8887 [(set_attr "type" "alu")
8888 (set_attr "length_immediate" "0")
8889 (set_attr "mode" "QI")])
8892 [(set (match_operand 0 "register_operand" "")
8893 (ior (match_operand 1 "register_operand" "")
8894 (match_operand 2 "const_int_operand" "")))
8895 (clobber (reg:CC FLAGS_REG))]
8897 && QI_REG_P (operands[0])
8898 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8899 && !(INTVAL (operands[2]) & ~(255 << 8))
8900 && GET_MODE (operands[0]) != QImode"
8901 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8902 (ior:SI (zero_extract:SI (match_dup 1)
8903 (const_int 8) (const_int 8))
8905 (clobber (reg:CC FLAGS_REG))])]
8906 "operands[0] = gen_lowpart (SImode, operands[0]);
8907 operands[1] = gen_lowpart (SImode, operands[1]);
8908 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8910 ;; Since OR can be encoded with sign extended immediate, this is only
8911 ;; profitable when 7th bit is set.
8913 [(set (match_operand 0 "register_operand" "")
8914 (ior (match_operand 1 "general_operand" "")
8915 (match_operand 2 "const_int_operand" "")))
8916 (clobber (reg:CC FLAGS_REG))]
8918 && ANY_QI_REG_P (operands[0])
8919 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8920 && !(INTVAL (operands[2]) & ~255)
8921 && (INTVAL (operands[2]) & 128)
8922 && GET_MODE (operands[0]) != QImode"
8923 [(parallel [(set (strict_low_part (match_dup 0))
8924 (ior:QI (match_dup 1)
8926 (clobber (reg:CC FLAGS_REG))])]
8927 "operands[0] = gen_lowpart (QImode, operands[0]);
8928 operands[1] = gen_lowpart (QImode, operands[1]);
8929 operands[2] = gen_lowpart (QImode, operands[2]);")
8931 ;; Logical XOR instructions
8933 ;; %%% This used to optimize known byte-wide and operations to memory.
8934 ;; If this is considered useful, it should be done with splitters.
8936 (define_expand "xordi3"
8937 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8938 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8939 (match_operand:DI 2 "x86_64_general_operand" "")))
8940 (clobber (reg:CC FLAGS_REG))]
8942 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8944 (define_insn "*xordi_1_rex64"
8945 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8946 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8947 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8948 (clobber (reg:CC FLAGS_REG))]
8950 && ix86_binary_operator_ok (XOR, DImode, operands)"
8952 xor{q}\t{%2, %0|%0, %2}
8953 xor{q}\t{%2, %0|%0, %2}"
8954 [(set_attr "type" "alu")
8955 (set_attr "mode" "DI,DI")])
8957 (define_insn "*xordi_2_rex64"
8958 [(set (reg FLAGS_REG)
8959 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8960 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8962 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8963 (xor:DI (match_dup 1) (match_dup 2)))]
8965 && ix86_match_ccmode (insn, CCNOmode)
8966 && ix86_binary_operator_ok (XOR, DImode, operands)"
8968 xor{q}\t{%2, %0|%0, %2}
8969 xor{q}\t{%2, %0|%0, %2}"
8970 [(set_attr "type" "alu")
8971 (set_attr "mode" "DI,DI")])
8973 (define_insn "*xordi_3_rex64"
8974 [(set (reg FLAGS_REG)
8975 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8976 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8978 (clobber (match_scratch:DI 0 "=r"))]
8980 && ix86_match_ccmode (insn, CCNOmode)
8981 && ix86_binary_operator_ok (XOR, DImode, operands)"
8982 "xor{q}\t{%2, %0|%0, %2}"
8983 [(set_attr "type" "alu")
8984 (set_attr "mode" "DI")])
8986 (define_expand "xorsi3"
8987 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8988 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8989 (match_operand:SI 2 "general_operand" "")))
8990 (clobber (reg:CC FLAGS_REG))]
8992 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8994 (define_insn "*xorsi_1"
8995 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8996 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8997 (match_operand:SI 2 "general_operand" "ri,rm")))
8998 (clobber (reg:CC FLAGS_REG))]
8999 "ix86_binary_operator_ok (XOR, SImode, operands)"
9000 "xor{l}\t{%2, %0|%0, %2}"
9001 [(set_attr "type" "alu")
9002 (set_attr "mode" "SI")])
9004 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9005 ;; Add speccase for immediates
9006 (define_insn "*xorsi_1_zext"
9007 [(set (match_operand:DI 0 "register_operand" "=r")
9009 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9010 (match_operand:SI 2 "general_operand" "rim"))))
9011 (clobber (reg:CC FLAGS_REG))]
9012 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9013 "xor{l}\t{%2, %k0|%k0, %2}"
9014 [(set_attr "type" "alu")
9015 (set_attr "mode" "SI")])
9017 (define_insn "*xorsi_1_zext_imm"
9018 [(set (match_operand:DI 0 "register_operand" "=r")
9019 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9020 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9021 (clobber (reg:CC FLAGS_REG))]
9022 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9023 "xor{l}\t{%2, %k0|%k0, %2}"
9024 [(set_attr "type" "alu")
9025 (set_attr "mode" "SI")])
9027 (define_insn "*xorsi_2"
9028 [(set (reg FLAGS_REG)
9029 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9030 (match_operand:SI 2 "general_operand" "rim,ri"))
9032 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9033 (xor:SI (match_dup 1) (match_dup 2)))]
9034 "ix86_match_ccmode (insn, CCNOmode)
9035 && ix86_binary_operator_ok (XOR, SImode, operands)"
9036 "xor{l}\t{%2, %0|%0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "SI")])
9040 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9041 ;; ??? Special case for immediate operand is missing - it is tricky.
9042 (define_insn "*xorsi_2_zext"
9043 [(set (reg FLAGS_REG)
9044 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9045 (match_operand:SI 2 "general_operand" "rim"))
9047 (set (match_operand:DI 0 "register_operand" "=r")
9048 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9049 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9050 && ix86_binary_operator_ok (XOR, SImode, operands)"
9051 "xor{l}\t{%2, %k0|%k0, %2}"
9052 [(set_attr "type" "alu")
9053 (set_attr "mode" "SI")])
9055 (define_insn "*xorsi_2_zext_imm"
9056 [(set (reg FLAGS_REG)
9057 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9058 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9060 (set (match_operand:DI 0 "register_operand" "=r")
9061 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9062 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9063 && ix86_binary_operator_ok (XOR, SImode, operands)"
9064 "xor{l}\t{%2, %k0|%k0, %2}"
9065 [(set_attr "type" "alu")
9066 (set_attr "mode" "SI")])
9068 (define_insn "*xorsi_3"
9069 [(set (reg FLAGS_REG)
9070 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9071 (match_operand:SI 2 "general_operand" "rim"))
9073 (clobber (match_scratch:SI 0 "=r"))]
9074 "ix86_match_ccmode (insn, CCNOmode)
9075 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9076 "xor{l}\t{%2, %0|%0, %2}"
9077 [(set_attr "type" "alu")
9078 (set_attr "mode" "SI")])
9080 (define_expand "xorhi3"
9081 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9082 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9083 (match_operand:HI 2 "general_operand" "")))
9084 (clobber (reg:CC FLAGS_REG))]
9085 "TARGET_HIMODE_MATH"
9086 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9088 (define_insn "*xorhi_1"
9089 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9090 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9091 (match_operand:HI 2 "general_operand" "rmi,ri")))
9092 (clobber (reg:CC FLAGS_REG))]
9093 "ix86_binary_operator_ok (XOR, HImode, operands)"
9094 "xor{w}\t{%2, %0|%0, %2}"
9095 [(set_attr "type" "alu")
9096 (set_attr "mode" "HI")])
9098 (define_insn "*xorhi_2"
9099 [(set (reg FLAGS_REG)
9100 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9101 (match_operand:HI 2 "general_operand" "rim,ri"))
9103 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9104 (xor:HI (match_dup 1) (match_dup 2)))]
9105 "ix86_match_ccmode (insn, CCNOmode)
9106 && ix86_binary_operator_ok (XOR, HImode, operands)"
9107 "xor{w}\t{%2, %0|%0, %2}"
9108 [(set_attr "type" "alu")
9109 (set_attr "mode" "HI")])
9111 (define_insn "*xorhi_3"
9112 [(set (reg FLAGS_REG)
9113 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9114 (match_operand:HI 2 "general_operand" "rim"))
9116 (clobber (match_scratch:HI 0 "=r"))]
9117 "ix86_match_ccmode (insn, CCNOmode)
9118 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9119 "xor{w}\t{%2, %0|%0, %2}"
9120 [(set_attr "type" "alu")
9121 (set_attr "mode" "HI")])
9123 (define_expand "xorqi3"
9124 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9125 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9126 (match_operand:QI 2 "general_operand" "")))
9127 (clobber (reg:CC FLAGS_REG))]
9128 "TARGET_QIMODE_MATH"
9129 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9131 ;; %%% Potential partial reg stall on alternative 2. What to do?
9132 (define_insn "*xorqi_1"
9133 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9134 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9135 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9136 (clobber (reg:CC FLAGS_REG))]
9137 "ix86_binary_operator_ok (XOR, QImode, operands)"
9139 xor{b}\t{%2, %0|%0, %2}
9140 xor{b}\t{%2, %0|%0, %2}
9141 xor{l}\t{%k2, %k0|%k0, %k2}"
9142 [(set_attr "type" "alu")
9143 (set_attr "mode" "QI,QI,SI")])
9145 (define_insn "*xorqi_1_slp"
9146 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9147 (xor:QI (match_dup 0)
9148 (match_operand:QI 1 "general_operand" "qi,qmi")))
9149 (clobber (reg:CC FLAGS_REG))]
9150 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9151 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9152 "xor{b}\t{%1, %0|%0, %1}"
9153 [(set_attr "type" "alu1")
9154 (set_attr "mode" "QI")])
9156 (define_insn "xorqi_ext_0"
9157 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9162 (match_operand 1 "ext_register_operand" "0")
9165 (match_operand 2 "const_int_operand" "n")))
9166 (clobber (reg:CC FLAGS_REG))]
9167 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9168 "xor{b}\t{%2, %h0|%h0, %2}"
9169 [(set_attr "type" "alu")
9170 (set_attr "length_immediate" "1")
9171 (set_attr "mode" "QI")])
9173 (define_insn "*xorqi_ext_1"
9174 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9179 (match_operand 1 "ext_register_operand" "0")
9183 (match_operand:QI 2 "general_operand" "Qm"))))
9184 (clobber (reg:CC FLAGS_REG))]
9186 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9187 "xor{b}\t{%2, %h0|%h0, %2}"
9188 [(set_attr "type" "alu")
9189 (set_attr "length_immediate" "0")
9190 (set_attr "mode" "QI")])
9192 (define_insn "*xorqi_ext_1_rex64"
9193 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9198 (match_operand 1 "ext_register_operand" "0")
9202 (match_operand 2 "ext_register_operand" "Q"))))
9203 (clobber (reg:CC FLAGS_REG))]
9205 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9206 "xor{b}\t{%2, %h0|%h0, %2}"
9207 [(set_attr "type" "alu")
9208 (set_attr "length_immediate" "0")
9209 (set_attr "mode" "QI")])
9211 (define_insn "*xorqi_ext_2"
9212 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9216 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9219 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9222 (clobber (reg:CC FLAGS_REG))]
9223 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9224 "xor{b}\t{%h2, %h0|%h0, %h2}"
9225 [(set_attr "type" "alu")
9226 (set_attr "length_immediate" "0")
9227 (set_attr "mode" "QI")])
9229 (define_insn "*xorqi_cc_1"
9230 [(set (reg FLAGS_REG)
9232 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9233 (match_operand:QI 2 "general_operand" "qim,qi"))
9235 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9236 (xor:QI (match_dup 1) (match_dup 2)))]
9237 "ix86_match_ccmode (insn, CCNOmode)
9238 && ix86_binary_operator_ok (XOR, QImode, operands)"
9239 "xor{b}\t{%2, %0|%0, %2}"
9240 [(set_attr "type" "alu")
9241 (set_attr "mode" "QI")])
9243 (define_insn "*xorqi_2_slp"
9244 [(set (reg FLAGS_REG)
9245 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9246 (match_operand:QI 1 "general_operand" "qim,qi"))
9248 (set (strict_low_part (match_dup 0))
9249 (xor:QI (match_dup 0) (match_dup 1)))]
9250 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9251 && ix86_match_ccmode (insn, CCNOmode)
9252 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9253 "xor{b}\t{%1, %0|%0, %1}"
9254 [(set_attr "type" "alu1")
9255 (set_attr "mode" "QI")])
9257 (define_insn "*xorqi_cc_2"
9258 [(set (reg FLAGS_REG)
9260 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9261 (match_operand:QI 2 "general_operand" "qim"))
9263 (clobber (match_scratch:QI 0 "=q"))]
9264 "ix86_match_ccmode (insn, CCNOmode)
9265 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9266 "xor{b}\t{%2, %0|%0, %2}"
9267 [(set_attr "type" "alu")
9268 (set_attr "mode" "QI")])
9270 (define_insn "*xorqi_cc_ext_1"
9271 [(set (reg FLAGS_REG)
9275 (match_operand 1 "ext_register_operand" "0")
9278 (match_operand:QI 2 "general_operand" "qmn"))
9280 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9284 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9286 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9287 "xor{b}\t{%2, %h0|%h0, %2}"
9288 [(set_attr "type" "alu")
9289 (set_attr "mode" "QI")])
9291 (define_insn "*xorqi_cc_ext_1_rex64"
9292 [(set (reg FLAGS_REG)
9296 (match_operand 1 "ext_register_operand" "0")
9299 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9301 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9305 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9307 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9308 "xor{b}\t{%2, %h0|%h0, %2}"
9309 [(set_attr "type" "alu")
9310 (set_attr "mode" "QI")])
9312 (define_expand "xorqi_cc_ext_1"
9314 (set (reg:CCNO FLAGS_REG)
9318 (match_operand 1 "ext_register_operand" "")
9321 (match_operand:QI 2 "general_operand" ""))
9323 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9327 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9333 [(set (match_operand 0 "register_operand" "")
9334 (xor (match_operand 1 "register_operand" "")
9335 (match_operand 2 "const_int_operand" "")))
9336 (clobber (reg:CC FLAGS_REG))]
9338 && QI_REG_P (operands[0])
9339 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9340 && !(INTVAL (operands[2]) & ~(255 << 8))
9341 && GET_MODE (operands[0]) != QImode"
9342 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9343 (xor:SI (zero_extract:SI (match_dup 1)
9344 (const_int 8) (const_int 8))
9346 (clobber (reg:CC FLAGS_REG))])]
9347 "operands[0] = gen_lowpart (SImode, operands[0]);
9348 operands[1] = gen_lowpart (SImode, operands[1]);
9349 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9351 ;; Since XOR can be encoded with sign extended immediate, this is only
9352 ;; profitable when 7th bit is set.
9354 [(set (match_operand 0 "register_operand" "")
9355 (xor (match_operand 1 "general_operand" "")
9356 (match_operand 2 "const_int_operand" "")))
9357 (clobber (reg:CC FLAGS_REG))]
9359 && ANY_QI_REG_P (operands[0])
9360 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9361 && !(INTVAL (operands[2]) & ~255)
9362 && (INTVAL (operands[2]) & 128)
9363 && GET_MODE (operands[0]) != QImode"
9364 [(parallel [(set (strict_low_part (match_dup 0))
9365 (xor:QI (match_dup 1)
9367 (clobber (reg:CC FLAGS_REG))])]
9368 "operands[0] = gen_lowpart (QImode, operands[0]);
9369 operands[1] = gen_lowpart (QImode, operands[1]);
9370 operands[2] = gen_lowpart (QImode, operands[2]);")
9372 ;; Negation instructions
9374 (define_expand "negti2"
9375 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9376 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9377 (clobber (reg:CC FLAGS_REG))])]
9379 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9381 (define_insn "*negti2_1"
9382 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9383 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9384 (clobber (reg:CC FLAGS_REG))]
9386 && ix86_unary_operator_ok (NEG, TImode, operands)"
9390 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9391 (neg:TI (match_operand:TI 1 "general_operand" "")))
9392 (clobber (reg:CC FLAGS_REG))]
9393 "TARGET_64BIT && reload_completed"
9395 [(set (reg:CCZ FLAGS_REG)
9396 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9397 (set (match_dup 0) (neg:DI (match_dup 2)))])
9400 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9403 (clobber (reg:CC FLAGS_REG))])
9406 (neg:DI (match_dup 1)))
9407 (clobber (reg:CC FLAGS_REG))])]
9408 "split_ti (operands+1, 1, operands+2, operands+3);
9409 split_ti (operands+0, 1, operands+0, operands+1);")
9411 (define_expand "negdi2"
9412 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9413 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9414 (clobber (reg:CC FLAGS_REG))])]
9416 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9418 (define_insn "*negdi2_1"
9419 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9420 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9421 (clobber (reg:CC FLAGS_REG))]
9423 && ix86_unary_operator_ok (NEG, DImode, operands)"
9427 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9428 (neg:DI (match_operand:DI 1 "general_operand" "")))
9429 (clobber (reg:CC FLAGS_REG))]
9430 "!TARGET_64BIT && reload_completed"
9432 [(set (reg:CCZ FLAGS_REG)
9433 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9434 (set (match_dup 0) (neg:SI (match_dup 2)))])
9437 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9440 (clobber (reg:CC FLAGS_REG))])
9443 (neg:SI (match_dup 1)))
9444 (clobber (reg:CC FLAGS_REG))])]
9445 "split_di (operands+1, 1, operands+2, operands+3);
9446 split_di (operands+0, 1, operands+0, operands+1);")
9448 (define_insn "*negdi2_1_rex64"
9449 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9450 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9451 (clobber (reg:CC FLAGS_REG))]
9452 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9454 [(set_attr "type" "negnot")
9455 (set_attr "mode" "DI")])
9457 ;; The problem with neg is that it does not perform (compare x 0),
9458 ;; it really performs (compare 0 x), which leaves us with the zero
9459 ;; flag being the only useful item.
9461 (define_insn "*negdi2_cmpz_rex64"
9462 [(set (reg:CCZ FLAGS_REG)
9463 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9465 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9466 (neg:DI (match_dup 1)))]
9467 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9469 [(set_attr "type" "negnot")
9470 (set_attr "mode" "DI")])
9473 (define_expand "negsi2"
9474 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9475 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9476 (clobber (reg:CC FLAGS_REG))])]
9478 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9480 (define_insn "*negsi2_1"
9481 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9482 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9483 (clobber (reg:CC FLAGS_REG))]
9484 "ix86_unary_operator_ok (NEG, SImode, operands)"
9486 [(set_attr "type" "negnot")
9487 (set_attr "mode" "SI")])
9489 ;; Combine is quite creative about this pattern.
9490 (define_insn "*negsi2_1_zext"
9491 [(set (match_operand:DI 0 "register_operand" "=r")
9492 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9495 (clobber (reg:CC FLAGS_REG))]
9496 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9498 [(set_attr "type" "negnot")
9499 (set_attr "mode" "SI")])
9501 ;; The problem with neg is that it does not perform (compare x 0),
9502 ;; it really performs (compare 0 x), which leaves us with the zero
9503 ;; flag being the only useful item.
9505 (define_insn "*negsi2_cmpz"
9506 [(set (reg:CCZ FLAGS_REG)
9507 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9509 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9510 (neg:SI (match_dup 1)))]
9511 "ix86_unary_operator_ok (NEG, SImode, operands)"
9513 [(set_attr "type" "negnot")
9514 (set_attr "mode" "SI")])
9516 (define_insn "*negsi2_cmpz_zext"
9517 [(set (reg:CCZ FLAGS_REG)
9518 (compare:CCZ (lshiftrt:DI
9520 (match_operand:DI 1 "register_operand" "0")
9524 (set (match_operand:DI 0 "register_operand" "=r")
9525 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9528 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9530 [(set_attr "type" "negnot")
9531 (set_attr "mode" "SI")])
9533 (define_expand "neghi2"
9534 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9535 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9536 (clobber (reg:CC FLAGS_REG))])]
9537 "TARGET_HIMODE_MATH"
9538 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9540 (define_insn "*neghi2_1"
9541 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9542 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "ix86_unary_operator_ok (NEG, HImode, operands)"
9546 [(set_attr "type" "negnot")
9547 (set_attr "mode" "HI")])
9549 (define_insn "*neghi2_cmpz"
9550 [(set (reg:CCZ FLAGS_REG)
9551 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9553 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9554 (neg:HI (match_dup 1)))]
9555 "ix86_unary_operator_ok (NEG, HImode, operands)"
9557 [(set_attr "type" "negnot")
9558 (set_attr "mode" "HI")])
9560 (define_expand "negqi2"
9561 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9562 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9563 (clobber (reg:CC FLAGS_REG))])]
9564 "TARGET_QIMODE_MATH"
9565 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9567 (define_insn "*negqi2_1"
9568 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9569 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9570 (clobber (reg:CC FLAGS_REG))]
9571 "ix86_unary_operator_ok (NEG, QImode, operands)"
9573 [(set_attr "type" "negnot")
9574 (set_attr "mode" "QI")])
9576 (define_insn "*negqi2_cmpz"
9577 [(set (reg:CCZ FLAGS_REG)
9578 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9580 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9581 (neg:QI (match_dup 1)))]
9582 "ix86_unary_operator_ok (NEG, QImode, operands)"
9584 [(set_attr "type" "negnot")
9585 (set_attr "mode" "QI")])
9587 ;; Changing of sign for FP values is doable using integer unit too.
9589 (define_expand "negsf2"
9590 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9591 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9592 "TARGET_80387 || TARGET_SSE_MATH"
9593 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9595 (define_expand "abssf2"
9596 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9597 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9598 "TARGET_80387 || TARGET_SSE_MATH"
9599 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9601 (define_insn "*absnegsf2_mixed"
9602 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9603 (match_operator:SF 3 "absneg_operator"
9604 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9605 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9606 (clobber (reg:CC FLAGS_REG))]
9607 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9608 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9611 (define_insn "*absnegsf2_sse"
9612 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9613 (match_operator:SF 3 "absneg_operator"
9614 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9615 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9616 (clobber (reg:CC FLAGS_REG))]
9618 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9621 (define_insn "*absnegsf2_i387"
9622 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9623 (match_operator:SF 3 "absneg_operator"
9624 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9625 (use (match_operand 2 "" ""))
9626 (clobber (reg:CC FLAGS_REG))]
9627 "TARGET_80387 && !TARGET_SSE_MATH
9628 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9631 (define_expand "copysignsf3"
9632 [(match_operand:SF 0 "register_operand" "")
9633 (match_operand:SF 1 "nonmemory_operand" "")
9634 (match_operand:SF 2 "register_operand" "")]
9637 ix86_expand_copysign (operands);
9641 (define_insn_and_split "copysignsf3_const"
9642 [(set (match_operand:SF 0 "register_operand" "=x")
9644 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9645 (match_operand:SF 2 "register_operand" "0")
9646 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9650 "&& reload_completed"
9653 ix86_split_copysign_const (operands);
9657 (define_insn "copysignsf3_var"
9658 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9660 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9661 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9662 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9663 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9665 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9670 [(set (match_operand:SF 0 "register_operand" "")
9672 [(match_operand:SF 2 "register_operand" "")
9673 (match_operand:SF 3 "register_operand" "")
9674 (match_operand:V4SF 4 "" "")
9675 (match_operand:V4SF 5 "" "")]
9677 (clobber (match_scratch:V4SF 1 ""))]
9678 "TARGET_SSE_MATH && reload_completed"
9681 ix86_split_copysign_var (operands);
9685 (define_expand "negdf2"
9686 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9687 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9688 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9689 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9691 (define_expand "absdf2"
9692 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9693 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9694 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9695 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9697 (define_insn "*absnegdf2_mixed"
9698 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9699 (match_operator:DF 3 "absneg_operator"
9700 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9701 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9702 (clobber (reg:CC FLAGS_REG))]
9703 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9704 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9707 (define_insn "*absnegdf2_sse"
9708 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9709 (match_operator:DF 3 "absneg_operator"
9710 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9711 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9712 (clobber (reg:CC FLAGS_REG))]
9713 "TARGET_SSE2 && TARGET_SSE_MATH
9714 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9717 (define_insn "*absnegdf2_i387"
9718 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9719 (match_operator:DF 3 "absneg_operator"
9720 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9721 (use (match_operand 2 "" ""))
9722 (clobber (reg:CC FLAGS_REG))]
9723 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9724 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9727 (define_expand "copysigndf3"
9728 [(match_operand:DF 0 "register_operand" "")
9729 (match_operand:DF 1 "nonmemory_operand" "")
9730 (match_operand:DF 2 "register_operand" "")]
9731 "TARGET_SSE2 && TARGET_SSE_MATH"
9733 ix86_expand_copysign (operands);
9737 (define_insn_and_split "copysigndf3_const"
9738 [(set (match_operand:DF 0 "register_operand" "=x")
9740 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9741 (match_operand:DF 2 "register_operand" "0")
9742 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9744 "TARGET_SSE2 && TARGET_SSE_MATH"
9746 "&& reload_completed"
9749 ix86_split_copysign_const (operands);
9753 (define_insn "copysigndf3_var"
9754 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9756 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9757 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9758 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9759 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9761 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9762 "TARGET_SSE2 && TARGET_SSE_MATH"
9766 [(set (match_operand:DF 0 "register_operand" "")
9768 [(match_operand:DF 2 "register_operand" "")
9769 (match_operand:DF 3 "register_operand" "")
9770 (match_operand:V2DF 4 "" "")
9771 (match_operand:V2DF 5 "" "")]
9773 (clobber (match_scratch:V2DF 1 ""))]
9774 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9777 ix86_split_copysign_var (operands);
9781 (define_expand "negxf2"
9782 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9783 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9785 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9787 (define_expand "absxf2"
9788 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9789 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9791 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9793 (define_insn "*absnegxf2_i387"
9794 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9795 (match_operator:XF 3 "absneg_operator"
9796 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9797 (use (match_operand 2 "" ""))
9798 (clobber (reg:CC FLAGS_REG))]
9800 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9803 ;; Splitters for fp abs and neg.
9806 [(set (match_operand 0 "fp_register_operand" "")
9807 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9808 (use (match_operand 2 "" ""))
9809 (clobber (reg:CC FLAGS_REG))]
9811 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9814 [(set (match_operand 0 "register_operand" "")
9815 (match_operator 3 "absneg_operator"
9816 [(match_operand 1 "register_operand" "")]))
9817 (use (match_operand 2 "nonimmediate_operand" ""))
9818 (clobber (reg:CC FLAGS_REG))]
9819 "reload_completed && SSE_REG_P (operands[0])"
9820 [(set (match_dup 0) (match_dup 3))]
9822 enum machine_mode mode = GET_MODE (operands[0]);
9823 enum machine_mode vmode = GET_MODE (operands[2]);
9826 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9827 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9828 if (operands_match_p (operands[0], operands[2]))
9831 operands[1] = operands[2];
9834 if (GET_CODE (operands[3]) == ABS)
9835 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9837 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9842 [(set (match_operand:SF 0 "register_operand" "")
9843 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9844 (use (match_operand:V4SF 2 "" ""))
9845 (clobber (reg:CC FLAGS_REG))]
9847 [(parallel [(set (match_dup 0) (match_dup 1))
9848 (clobber (reg:CC FLAGS_REG))])]
9851 operands[0] = gen_lowpart (SImode, operands[0]);
9852 if (GET_CODE (operands[1]) == ABS)
9854 tmp = gen_int_mode (0x7fffffff, SImode);
9855 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9859 tmp = gen_int_mode (0x80000000, SImode);
9860 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9866 [(set (match_operand:DF 0 "register_operand" "")
9867 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9868 (use (match_operand 2 "" ""))
9869 (clobber (reg:CC FLAGS_REG))]
9871 [(parallel [(set (match_dup 0) (match_dup 1))
9872 (clobber (reg:CC FLAGS_REG))])]
9877 tmp = gen_lowpart (DImode, operands[0]);
9878 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9881 if (GET_CODE (operands[1]) == ABS)
9884 tmp = gen_rtx_NOT (DImode, tmp);
9888 operands[0] = gen_highpart (SImode, operands[0]);
9889 if (GET_CODE (operands[1]) == ABS)
9891 tmp = gen_int_mode (0x7fffffff, SImode);
9892 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9896 tmp = gen_int_mode (0x80000000, SImode);
9897 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9904 [(set (match_operand:XF 0 "register_operand" "")
9905 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9906 (use (match_operand 2 "" ""))
9907 (clobber (reg:CC FLAGS_REG))]
9909 [(parallel [(set (match_dup 0) (match_dup 1))
9910 (clobber (reg:CC FLAGS_REG))])]
9913 operands[0] = gen_rtx_REG (SImode,
9914 true_regnum (operands[0])
9915 + (TARGET_64BIT ? 1 : 2));
9916 if (GET_CODE (operands[1]) == ABS)
9918 tmp = GEN_INT (0x7fff);
9919 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9923 tmp = GEN_INT (0x8000);
9924 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9930 [(set (match_operand 0 "memory_operand" "")
9931 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9932 (use (match_operand 2 "" ""))
9933 (clobber (reg:CC FLAGS_REG))]
9935 [(parallel [(set (match_dup 0) (match_dup 1))
9936 (clobber (reg:CC FLAGS_REG))])]
9938 enum machine_mode mode = GET_MODE (operands[0]);
9939 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9942 operands[0] = adjust_address (operands[0], QImode, size - 1);
9943 if (GET_CODE (operands[1]) == ABS)
9945 tmp = gen_int_mode (0x7f, QImode);
9946 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9950 tmp = gen_int_mode (0x80, QImode);
9951 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9956 ;; Conditionalize these after reload. If they match before reload, we
9957 ;; lose the clobber and ability to use integer instructions.
9959 (define_insn "*negsf2_1"
9960 [(set (match_operand:SF 0 "register_operand" "=f")
9961 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9962 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9964 [(set_attr "type" "fsgn")
9965 (set_attr "mode" "SF")])
9967 (define_insn "*negdf2_1"
9968 [(set (match_operand:DF 0 "register_operand" "=f")
9969 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9970 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9972 [(set_attr "type" "fsgn")
9973 (set_attr "mode" "DF")])
9975 (define_insn "*negxf2_1"
9976 [(set (match_operand:XF 0 "register_operand" "=f")
9977 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9980 [(set_attr "type" "fsgn")
9981 (set_attr "mode" "XF")])
9983 (define_insn "*abssf2_1"
9984 [(set (match_operand:SF 0 "register_operand" "=f")
9985 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9986 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9988 [(set_attr "type" "fsgn")
9989 (set_attr "mode" "SF")])
9991 (define_insn "*absdf2_1"
9992 [(set (match_operand:DF 0 "register_operand" "=f")
9993 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9994 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9996 [(set_attr "type" "fsgn")
9997 (set_attr "mode" "DF")])
9999 (define_insn "*absxf2_1"
10000 [(set (match_operand:XF 0 "register_operand" "=f")
10001 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
10004 [(set_attr "type" "fsgn")
10005 (set_attr "mode" "DF")])
10007 (define_insn "*negextendsfdf2"
10008 [(set (match_operand:DF 0 "register_operand" "=f")
10009 (neg:DF (float_extend:DF
10010 (match_operand:SF 1 "register_operand" "0"))))]
10011 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10013 [(set_attr "type" "fsgn")
10014 (set_attr "mode" "DF")])
10016 (define_insn "*negextenddfxf2"
10017 [(set (match_operand:XF 0 "register_operand" "=f")
10018 (neg:XF (float_extend:XF
10019 (match_operand:DF 1 "register_operand" "0"))))]
10022 [(set_attr "type" "fsgn")
10023 (set_attr "mode" "XF")])
10025 (define_insn "*negextendsfxf2"
10026 [(set (match_operand:XF 0 "register_operand" "=f")
10027 (neg:XF (float_extend:XF
10028 (match_operand:SF 1 "register_operand" "0"))))]
10031 [(set_attr "type" "fsgn")
10032 (set_attr "mode" "XF")])
10034 (define_insn "*absextendsfdf2"
10035 [(set (match_operand:DF 0 "register_operand" "=f")
10036 (abs:DF (float_extend:DF
10037 (match_operand:SF 1 "register_operand" "0"))))]
10038 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10040 [(set_attr "type" "fsgn")
10041 (set_attr "mode" "DF")])
10043 (define_insn "*absextenddfxf2"
10044 [(set (match_operand:XF 0 "register_operand" "=f")
10045 (abs:XF (float_extend:XF
10046 (match_operand:DF 1 "register_operand" "0"))))]
10049 [(set_attr "type" "fsgn")
10050 (set_attr "mode" "XF")])
10052 (define_insn "*absextendsfxf2"
10053 [(set (match_operand:XF 0 "register_operand" "=f")
10054 (abs:XF (float_extend:XF
10055 (match_operand:SF 1 "register_operand" "0"))))]
10058 [(set_attr "type" "fsgn")
10059 (set_attr "mode" "XF")])
10061 ;; One complement instructions
10063 (define_expand "one_cmpldi2"
10064 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10065 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10067 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10069 (define_insn "*one_cmpldi2_1_rex64"
10070 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10071 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10072 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10074 [(set_attr "type" "negnot")
10075 (set_attr "mode" "DI")])
10077 (define_insn "*one_cmpldi2_2_rex64"
10078 [(set (reg FLAGS_REG)
10079 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10081 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10082 (not:DI (match_dup 1)))]
10083 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10084 && ix86_unary_operator_ok (NOT, DImode, operands)"
10086 [(set_attr "type" "alu1")
10087 (set_attr "mode" "DI")])
10090 [(set (match_operand 0 "flags_reg_operand" "")
10091 (match_operator 2 "compare_operator"
10092 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10094 (set (match_operand:DI 1 "nonimmediate_operand" "")
10095 (not:DI (match_dup 3)))]
10096 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10097 [(parallel [(set (match_dup 0)
10099 [(xor:DI (match_dup 3) (const_int -1))
10102 (xor:DI (match_dup 3) (const_int -1)))])]
10105 (define_expand "one_cmplsi2"
10106 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10107 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10109 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10111 (define_insn "*one_cmplsi2_1"
10112 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10113 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10114 "ix86_unary_operator_ok (NOT, SImode, operands)"
10116 [(set_attr "type" "negnot")
10117 (set_attr "mode" "SI")])
10119 ;; ??? Currently never generated - xor is used instead.
10120 (define_insn "*one_cmplsi2_1_zext"
10121 [(set (match_operand:DI 0 "register_operand" "=r")
10122 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10123 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10125 [(set_attr "type" "negnot")
10126 (set_attr "mode" "SI")])
10128 (define_insn "*one_cmplsi2_2"
10129 [(set (reg FLAGS_REG)
10130 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10132 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10133 (not:SI (match_dup 1)))]
10134 "ix86_match_ccmode (insn, CCNOmode)
10135 && ix86_unary_operator_ok (NOT, SImode, operands)"
10137 [(set_attr "type" "alu1")
10138 (set_attr "mode" "SI")])
10141 [(set (match_operand 0 "flags_reg_operand" "")
10142 (match_operator 2 "compare_operator"
10143 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10145 (set (match_operand:SI 1 "nonimmediate_operand" "")
10146 (not:SI (match_dup 3)))]
10147 "ix86_match_ccmode (insn, CCNOmode)"
10148 [(parallel [(set (match_dup 0)
10149 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10152 (xor:SI (match_dup 3) (const_int -1)))])]
10155 ;; ??? Currently never generated - xor is used instead.
10156 (define_insn "*one_cmplsi2_2_zext"
10157 [(set (reg FLAGS_REG)
10158 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10160 (set (match_operand:DI 0 "register_operand" "=r")
10161 (zero_extend:DI (not:SI (match_dup 1))))]
10162 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10163 && ix86_unary_operator_ok (NOT, SImode, operands)"
10165 [(set_attr "type" "alu1")
10166 (set_attr "mode" "SI")])
10169 [(set (match_operand 0 "flags_reg_operand" "")
10170 (match_operator 2 "compare_operator"
10171 [(not:SI (match_operand:SI 3 "register_operand" ""))
10173 (set (match_operand:DI 1 "register_operand" "")
10174 (zero_extend:DI (not:SI (match_dup 3))))]
10175 "ix86_match_ccmode (insn, CCNOmode)"
10176 [(parallel [(set (match_dup 0)
10177 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10180 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10183 (define_expand "one_cmplhi2"
10184 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10185 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10186 "TARGET_HIMODE_MATH"
10187 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10189 (define_insn "*one_cmplhi2_1"
10190 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10191 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10192 "ix86_unary_operator_ok (NOT, HImode, operands)"
10194 [(set_attr "type" "negnot")
10195 (set_attr "mode" "HI")])
10197 (define_insn "*one_cmplhi2_2"
10198 [(set (reg FLAGS_REG)
10199 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10201 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10202 (not:HI (match_dup 1)))]
10203 "ix86_match_ccmode (insn, CCNOmode)
10204 && ix86_unary_operator_ok (NEG, HImode, operands)"
10206 [(set_attr "type" "alu1")
10207 (set_attr "mode" "HI")])
10210 [(set (match_operand 0 "flags_reg_operand" "")
10211 (match_operator 2 "compare_operator"
10212 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10214 (set (match_operand:HI 1 "nonimmediate_operand" "")
10215 (not:HI (match_dup 3)))]
10216 "ix86_match_ccmode (insn, CCNOmode)"
10217 [(parallel [(set (match_dup 0)
10218 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10221 (xor:HI (match_dup 3) (const_int -1)))])]
10224 ;; %%% Potential partial reg stall on alternative 1. What to do?
10225 (define_expand "one_cmplqi2"
10226 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10227 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10228 "TARGET_QIMODE_MATH"
10229 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10231 (define_insn "*one_cmplqi2_1"
10232 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10233 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10234 "ix86_unary_operator_ok (NOT, QImode, operands)"
10238 [(set_attr "type" "negnot")
10239 (set_attr "mode" "QI,SI")])
10241 (define_insn "*one_cmplqi2_2"
10242 [(set (reg FLAGS_REG)
10243 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10245 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10246 (not:QI (match_dup 1)))]
10247 "ix86_match_ccmode (insn, CCNOmode)
10248 && ix86_unary_operator_ok (NOT, QImode, operands)"
10250 [(set_attr "type" "alu1")
10251 (set_attr "mode" "QI")])
10254 [(set (match_operand 0 "flags_reg_operand" "")
10255 (match_operator 2 "compare_operator"
10256 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10258 (set (match_operand:QI 1 "nonimmediate_operand" "")
10259 (not:QI (match_dup 3)))]
10260 "ix86_match_ccmode (insn, CCNOmode)"
10261 [(parallel [(set (match_dup 0)
10262 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10265 (xor:QI (match_dup 3) (const_int -1)))])]
10268 ;; Arithmetic shift instructions
10270 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10271 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10272 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10273 ;; from the assembler input.
10275 ;; This instruction shifts the target reg/mem as usual, but instead of
10276 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10277 ;; is a left shift double, bits are taken from the high order bits of
10278 ;; reg, else if the insn is a shift right double, bits are taken from the
10279 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10280 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10282 ;; Since sh[lr]d does not change the `reg' operand, that is done
10283 ;; separately, making all shifts emit pairs of shift double and normal
10284 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10285 ;; support a 63 bit shift, each shift where the count is in a reg expands
10286 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10288 ;; If the shift count is a constant, we need never emit more than one
10289 ;; shift pair, instead using moves and sign extension for counts greater
10292 (define_expand "ashlti3"
10293 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10294 (ashift:TI (match_operand:TI 1 "register_operand" "")
10295 (match_operand:QI 2 "nonmemory_operand" "")))
10296 (clobber (reg:CC FLAGS_REG))])]
10299 if (! immediate_operand (operands[2], QImode))
10301 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10304 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10308 (define_insn "ashlti3_1"
10309 [(set (match_operand:TI 0 "register_operand" "=r")
10310 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10311 (match_operand:QI 2 "register_operand" "c")))
10312 (clobber (match_scratch:DI 3 "=&r"))
10313 (clobber (reg:CC FLAGS_REG))]
10316 [(set_attr "type" "multi")])
10318 (define_insn "*ashlti3_2"
10319 [(set (match_operand:TI 0 "register_operand" "=r")
10320 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10321 (match_operand:QI 2 "immediate_operand" "O")))
10322 (clobber (reg:CC FLAGS_REG))]
10325 [(set_attr "type" "multi")])
10328 [(set (match_operand:TI 0 "register_operand" "")
10329 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10330 (match_operand:QI 2 "register_operand" "")))
10331 (clobber (match_scratch:DI 3 ""))
10332 (clobber (reg:CC FLAGS_REG))]
10333 "TARGET_64BIT && reload_completed"
10335 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10338 [(set (match_operand:TI 0 "register_operand" "")
10339 (ashift:TI (match_operand:TI 1 "register_operand" "")
10340 (match_operand:QI 2 "immediate_operand" "")))
10341 (clobber (reg:CC FLAGS_REG))]
10342 "TARGET_64BIT && reload_completed"
10344 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10346 (define_insn "x86_64_shld"
10347 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10348 (ior:DI (ashift:DI (match_dup 0)
10349 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10350 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10351 (minus:QI (const_int 64) (match_dup 2)))))
10352 (clobber (reg:CC FLAGS_REG))]
10355 shld{q}\t{%2, %1, %0|%0, %1, %2}
10356 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10357 [(set_attr "type" "ishift")
10358 (set_attr "prefix_0f" "1")
10359 (set_attr "mode" "DI")
10360 (set_attr "athlon_decode" "vector")])
10362 (define_expand "x86_64_shift_adj"
10363 [(set (reg:CCZ FLAGS_REG)
10364 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10367 (set (match_operand:DI 0 "register_operand" "")
10368 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10369 (match_operand:DI 1 "register_operand" "")
10372 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10373 (match_operand:DI 3 "register_operand" "r")
10378 (define_expand "ashldi3"
10379 [(set (match_operand:DI 0 "shiftdi_operand" "")
10380 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10381 (match_operand:QI 2 "nonmemory_operand" "")))]
10383 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10385 (define_insn "*ashldi3_1_rex64"
10386 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10387 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10388 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10392 switch (get_attr_type (insn))
10395 gcc_assert (operands[2] == const1_rtx);
10396 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10397 return "add{q}\t{%0, %0|%0, %0}";
10400 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10401 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10402 operands[1] = gen_rtx_MULT (DImode, operands[1],
10403 GEN_INT (1 << INTVAL (operands[2])));
10404 return "lea{q}\t{%a1, %0|%0, %a1}";
10407 if (REG_P (operands[2]))
10408 return "sal{q}\t{%b2, %0|%0, %b2}";
10409 else if (operands[2] == const1_rtx
10410 && (TARGET_SHIFT1 || optimize_size))
10411 return "sal{q}\t%0";
10413 return "sal{q}\t{%2, %0|%0, %2}";
10416 [(set (attr "type")
10417 (cond [(eq_attr "alternative" "1")
10418 (const_string "lea")
10419 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10421 (match_operand 0 "register_operand" ""))
10422 (match_operand 2 "const1_operand" ""))
10423 (const_string "alu")
10425 (const_string "ishift")))
10426 (set_attr "mode" "DI")])
10428 ;; Convert lea to the lea pattern to avoid flags dependency.
10430 [(set (match_operand:DI 0 "register_operand" "")
10431 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10432 (match_operand:QI 2 "immediate_operand" "")))
10433 (clobber (reg:CC FLAGS_REG))]
10434 "TARGET_64BIT && reload_completed
10435 && true_regnum (operands[0]) != true_regnum (operands[1])"
10436 [(set (match_dup 0)
10437 (mult:DI (match_dup 1)
10439 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10441 ;; This pattern can't accept a variable shift count, since shifts by
10442 ;; zero don't affect the flags. We assume that shifts by constant
10443 ;; zero are optimized away.
10444 (define_insn "*ashldi3_cmp_rex64"
10445 [(set (reg FLAGS_REG)
10447 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10448 (match_operand:QI 2 "immediate_operand" "e"))
10450 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10451 (ashift:DI (match_dup 1) (match_dup 2)))]
10452 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10453 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10455 || !TARGET_PARTIAL_FLAG_REG_STALL
10456 || (operands[2] == const1_rtx
10458 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10460 switch (get_attr_type (insn))
10463 gcc_assert (operands[2] == const1_rtx);
10464 return "add{q}\t{%0, %0|%0, %0}";
10467 if (REG_P (operands[2]))
10468 return "sal{q}\t{%b2, %0|%0, %b2}";
10469 else if (operands[2] == const1_rtx
10470 && (TARGET_SHIFT1 || optimize_size))
10471 return "sal{q}\t%0";
10473 return "sal{q}\t{%2, %0|%0, %2}";
10476 [(set (attr "type")
10477 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10479 (match_operand 0 "register_operand" ""))
10480 (match_operand 2 "const1_operand" ""))
10481 (const_string "alu")
10483 (const_string "ishift")))
10484 (set_attr "mode" "DI")])
10486 (define_insn "*ashldi3_cconly_rex64"
10487 [(set (reg FLAGS_REG)
10489 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10490 (match_operand:QI 2 "immediate_operand" "e"))
10492 (clobber (match_scratch:DI 0 "=r"))]
10493 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10494 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10496 || !TARGET_PARTIAL_FLAG_REG_STALL
10497 || (operands[2] == const1_rtx
10499 || TARGET_DOUBLE_WITH_ADD)))"
10501 switch (get_attr_type (insn))
10504 gcc_assert (operands[2] == const1_rtx);
10505 return "add{q}\t{%0, %0|%0, %0}";
10508 if (REG_P (operands[2]))
10509 return "sal{q}\t{%b2, %0|%0, %b2}";
10510 else if (operands[2] == const1_rtx
10511 && (TARGET_SHIFT1 || optimize_size))
10512 return "sal{q}\t%0";
10514 return "sal{q}\t{%2, %0|%0, %2}";
10517 [(set (attr "type")
10518 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10520 (match_operand 0 "register_operand" ""))
10521 (match_operand 2 "const1_operand" ""))
10522 (const_string "alu")
10524 (const_string "ishift")))
10525 (set_attr "mode" "DI")])
10527 (define_insn "*ashldi3_1"
10528 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10529 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10530 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10531 (clobber (reg:CC FLAGS_REG))]
10534 [(set_attr "type" "multi")])
10536 ;; By default we don't ask for a scratch register, because when DImode
10537 ;; values are manipulated, registers are already at a premium. But if
10538 ;; we have one handy, we won't turn it away.
10540 [(match_scratch:SI 3 "r")
10541 (parallel [(set (match_operand:DI 0 "register_operand" "")
10542 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10543 (match_operand:QI 2 "nonmemory_operand" "")))
10544 (clobber (reg:CC FLAGS_REG))])
10546 "!TARGET_64BIT && TARGET_CMOVE"
10548 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10551 [(set (match_operand:DI 0 "register_operand" "")
10552 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10553 (match_operand:QI 2 "nonmemory_operand" "")))
10554 (clobber (reg:CC FLAGS_REG))]
10555 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10556 ? flow2_completed : reload_completed)"
10558 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10560 (define_insn "x86_shld_1"
10561 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10562 (ior:SI (ashift:SI (match_dup 0)
10563 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10564 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10565 (minus:QI (const_int 32) (match_dup 2)))))
10566 (clobber (reg:CC FLAGS_REG))]
10569 shld{l}\t{%2, %1, %0|%0, %1, %2}
10570 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10571 [(set_attr "type" "ishift")
10572 (set_attr "prefix_0f" "1")
10573 (set_attr "mode" "SI")
10574 (set_attr "pent_pair" "np")
10575 (set_attr "athlon_decode" "vector")])
10577 (define_expand "x86_shift_adj_1"
10578 [(set (reg:CCZ FLAGS_REG)
10579 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10582 (set (match_operand:SI 0 "register_operand" "")
10583 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10584 (match_operand:SI 1 "register_operand" "")
10587 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10588 (match_operand:SI 3 "register_operand" "r")
10593 (define_expand "x86_shift_adj_2"
10594 [(use (match_operand:SI 0 "register_operand" ""))
10595 (use (match_operand:SI 1 "register_operand" ""))
10596 (use (match_operand:QI 2 "register_operand" ""))]
10599 rtx label = gen_label_rtx ();
10602 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10604 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10605 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10606 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10607 gen_rtx_LABEL_REF (VOIDmode, label),
10609 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10610 JUMP_LABEL (tmp) = label;
10612 emit_move_insn (operands[0], operands[1]);
10613 ix86_expand_clear (operands[1]);
10615 emit_label (label);
10616 LABEL_NUSES (label) = 1;
10621 (define_expand "ashlsi3"
10622 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10623 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10624 (match_operand:QI 2 "nonmemory_operand" "")))
10625 (clobber (reg:CC FLAGS_REG))]
10627 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10629 (define_insn "*ashlsi3_1"
10630 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10631 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10632 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10633 (clobber (reg:CC FLAGS_REG))]
10634 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10636 switch (get_attr_type (insn))
10639 gcc_assert (operands[2] == const1_rtx);
10640 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10641 return "add{l}\t{%0, %0|%0, %0}";
10647 if (REG_P (operands[2]))
10648 return "sal{l}\t{%b2, %0|%0, %b2}";
10649 else if (operands[2] == const1_rtx
10650 && (TARGET_SHIFT1 || optimize_size))
10651 return "sal{l}\t%0";
10653 return "sal{l}\t{%2, %0|%0, %2}";
10656 [(set (attr "type")
10657 (cond [(eq_attr "alternative" "1")
10658 (const_string "lea")
10659 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10661 (match_operand 0 "register_operand" ""))
10662 (match_operand 2 "const1_operand" ""))
10663 (const_string "alu")
10665 (const_string "ishift")))
10666 (set_attr "mode" "SI")])
10668 ;; Convert lea to the lea pattern to avoid flags dependency.
10670 [(set (match_operand 0 "register_operand" "")
10671 (ashift (match_operand 1 "index_register_operand" "")
10672 (match_operand:QI 2 "const_int_operand" "")))
10673 (clobber (reg:CC FLAGS_REG))]
10675 && true_regnum (operands[0]) != true_regnum (operands[1])
10676 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10680 enum machine_mode mode = GET_MODE (operands[0]);
10682 if (GET_MODE_SIZE (mode) < 4)
10683 operands[0] = gen_lowpart (SImode, operands[0]);
10685 operands[1] = gen_lowpart (Pmode, operands[1]);
10686 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10688 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10689 if (Pmode != SImode)
10690 pat = gen_rtx_SUBREG (SImode, pat, 0);
10691 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10695 ;; Rare case of shifting RSP is handled by generating move and shift
10697 [(set (match_operand 0 "register_operand" "")
10698 (ashift (match_operand 1 "register_operand" "")
10699 (match_operand:QI 2 "const_int_operand" "")))
10700 (clobber (reg:CC FLAGS_REG))]
10702 && true_regnum (operands[0]) != true_regnum (operands[1])"
10706 emit_move_insn (operands[0], operands[1]);
10707 pat = gen_rtx_SET (VOIDmode, operands[0],
10708 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10709 operands[0], operands[2]));
10710 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10711 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10715 (define_insn "*ashlsi3_1_zext"
10716 [(set (match_operand:DI 0 "register_operand" "=r,r")
10717 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10718 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10719 (clobber (reg:CC FLAGS_REG))]
10720 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10722 switch (get_attr_type (insn))
10725 gcc_assert (operands[2] == const1_rtx);
10726 return "add{l}\t{%k0, %k0|%k0, %k0}";
10732 if (REG_P (operands[2]))
10733 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10734 else if (operands[2] == const1_rtx
10735 && (TARGET_SHIFT1 || optimize_size))
10736 return "sal{l}\t%k0";
10738 return "sal{l}\t{%2, %k0|%k0, %2}";
10741 [(set (attr "type")
10742 (cond [(eq_attr "alternative" "1")
10743 (const_string "lea")
10744 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10746 (match_operand 2 "const1_operand" ""))
10747 (const_string "alu")
10749 (const_string "ishift")))
10750 (set_attr "mode" "SI")])
10752 ;; Convert lea to the lea pattern to avoid flags dependency.
10754 [(set (match_operand:DI 0 "register_operand" "")
10755 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10756 (match_operand:QI 2 "const_int_operand" ""))))
10757 (clobber (reg:CC FLAGS_REG))]
10758 "TARGET_64BIT && reload_completed
10759 && true_regnum (operands[0]) != true_regnum (operands[1])"
10760 [(set (match_dup 0) (zero_extend:DI
10761 (subreg:SI (mult:SI (match_dup 1)
10762 (match_dup 2)) 0)))]
10764 operands[1] = gen_lowpart (Pmode, operands[1]);
10765 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10768 ;; This pattern can't accept a variable shift count, since shifts by
10769 ;; zero don't affect the flags. We assume that shifts by constant
10770 ;; zero are optimized away.
10771 (define_insn "*ashlsi3_cmp"
10772 [(set (reg FLAGS_REG)
10774 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10775 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10777 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10778 (ashift:SI (match_dup 1) (match_dup 2)))]
10779 "ix86_match_ccmode (insn, CCGOCmode)
10780 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10782 || !TARGET_PARTIAL_FLAG_REG_STALL
10783 || (operands[2] == const1_rtx
10785 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10787 switch (get_attr_type (insn))
10790 gcc_assert (operands[2] == const1_rtx);
10791 return "add{l}\t{%0, %0|%0, %0}";
10794 if (REG_P (operands[2]))
10795 return "sal{l}\t{%b2, %0|%0, %b2}";
10796 else if (operands[2] == const1_rtx
10797 && (TARGET_SHIFT1 || optimize_size))
10798 return "sal{l}\t%0";
10800 return "sal{l}\t{%2, %0|%0, %2}";
10803 [(set (attr "type")
10804 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10806 (match_operand 0 "register_operand" ""))
10807 (match_operand 2 "const1_operand" ""))
10808 (const_string "alu")
10810 (const_string "ishift")))
10811 (set_attr "mode" "SI")])
10813 (define_insn "*ashlsi3_cconly"
10814 [(set (reg FLAGS_REG)
10816 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10817 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10819 (clobber (match_scratch:SI 0 "=r"))]
10820 "ix86_match_ccmode (insn, CCGOCmode)
10821 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10823 || !TARGET_PARTIAL_FLAG_REG_STALL
10824 || (operands[2] == const1_rtx
10826 || TARGET_DOUBLE_WITH_ADD)))"
10828 switch (get_attr_type (insn))
10831 gcc_assert (operands[2] == const1_rtx);
10832 return "add{l}\t{%0, %0|%0, %0}";
10835 if (REG_P (operands[2]))
10836 return "sal{l}\t{%b2, %0|%0, %b2}";
10837 else if (operands[2] == const1_rtx
10838 && (TARGET_SHIFT1 || optimize_size))
10839 return "sal{l}\t%0";
10841 return "sal{l}\t{%2, %0|%0, %2}";
10844 [(set (attr "type")
10845 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10847 (match_operand 0 "register_operand" ""))
10848 (match_operand 2 "const1_operand" ""))
10849 (const_string "alu")
10851 (const_string "ishift")))
10852 (set_attr "mode" "SI")])
10854 (define_insn "*ashlsi3_cmp_zext"
10855 [(set (reg FLAGS_REG)
10857 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10858 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10860 (set (match_operand:DI 0 "register_operand" "=r")
10861 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10862 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10863 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10865 || !TARGET_PARTIAL_FLAG_REG_STALL
10866 || (operands[2] == const1_rtx
10868 || TARGET_DOUBLE_WITH_ADD)))"
10870 switch (get_attr_type (insn))
10873 gcc_assert (operands[2] == const1_rtx);
10874 return "add{l}\t{%k0, %k0|%k0, %k0}";
10877 if (REG_P (operands[2]))
10878 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10879 else if (operands[2] == const1_rtx
10880 && (TARGET_SHIFT1 || optimize_size))
10881 return "sal{l}\t%k0";
10883 return "sal{l}\t{%2, %k0|%k0, %2}";
10886 [(set (attr "type")
10887 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10889 (match_operand 2 "const1_operand" ""))
10890 (const_string "alu")
10892 (const_string "ishift")))
10893 (set_attr "mode" "SI")])
10895 (define_expand "ashlhi3"
10896 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10897 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10898 (match_operand:QI 2 "nonmemory_operand" "")))
10899 (clobber (reg:CC FLAGS_REG))]
10900 "TARGET_HIMODE_MATH"
10901 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10903 (define_insn "*ashlhi3_1_lea"
10904 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10905 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10906 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10907 (clobber (reg:CC FLAGS_REG))]
10908 "!TARGET_PARTIAL_REG_STALL
10909 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10911 switch (get_attr_type (insn))
10916 gcc_assert (operands[2] == const1_rtx);
10917 return "add{w}\t{%0, %0|%0, %0}";
10920 if (REG_P (operands[2]))
10921 return "sal{w}\t{%b2, %0|%0, %b2}";
10922 else if (operands[2] == const1_rtx
10923 && (TARGET_SHIFT1 || optimize_size))
10924 return "sal{w}\t%0";
10926 return "sal{w}\t{%2, %0|%0, %2}";
10929 [(set (attr "type")
10930 (cond [(eq_attr "alternative" "1")
10931 (const_string "lea")
10932 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10934 (match_operand 0 "register_operand" ""))
10935 (match_operand 2 "const1_operand" ""))
10936 (const_string "alu")
10938 (const_string "ishift")))
10939 (set_attr "mode" "HI,SI")])
10941 (define_insn "*ashlhi3_1"
10942 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10943 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10944 (match_operand:QI 2 "nonmemory_operand" "cI")))
10945 (clobber (reg:CC FLAGS_REG))]
10946 "TARGET_PARTIAL_REG_STALL
10947 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10949 switch (get_attr_type (insn))
10952 gcc_assert (operands[2] == const1_rtx);
10953 return "add{w}\t{%0, %0|%0, %0}";
10956 if (REG_P (operands[2]))
10957 return "sal{w}\t{%b2, %0|%0, %b2}";
10958 else if (operands[2] == const1_rtx
10959 && (TARGET_SHIFT1 || optimize_size))
10960 return "sal{w}\t%0";
10962 return "sal{w}\t{%2, %0|%0, %2}";
10965 [(set (attr "type")
10966 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10968 (match_operand 0 "register_operand" ""))
10969 (match_operand 2 "const1_operand" ""))
10970 (const_string "alu")
10972 (const_string "ishift")))
10973 (set_attr "mode" "HI")])
10975 ;; This pattern can't accept a variable shift count, since shifts by
10976 ;; zero don't affect the flags. We assume that shifts by constant
10977 ;; zero are optimized away.
10978 (define_insn "*ashlhi3_cmp"
10979 [(set (reg FLAGS_REG)
10981 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10982 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10984 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10985 (ashift:HI (match_dup 1) (match_dup 2)))]
10986 "ix86_match_ccmode (insn, CCGOCmode)
10987 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10989 || !TARGET_PARTIAL_FLAG_REG_STALL
10990 || (operands[2] == const1_rtx
10992 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10994 switch (get_attr_type (insn))
10997 gcc_assert (operands[2] == const1_rtx);
10998 return "add{w}\t{%0, %0|%0, %0}";
11001 if (REG_P (operands[2]))
11002 return "sal{w}\t{%b2, %0|%0, %b2}";
11003 else if (operands[2] == const1_rtx
11004 && (TARGET_SHIFT1 || optimize_size))
11005 return "sal{w}\t%0";
11007 return "sal{w}\t{%2, %0|%0, %2}";
11010 [(set (attr "type")
11011 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11013 (match_operand 0 "register_operand" ""))
11014 (match_operand 2 "const1_operand" ""))
11015 (const_string "alu")
11017 (const_string "ishift")))
11018 (set_attr "mode" "HI")])
11020 (define_insn "*ashlhi3_cconly"
11021 [(set (reg FLAGS_REG)
11023 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11024 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11026 (clobber (match_scratch:HI 0 "=r"))]
11027 "ix86_match_ccmode (insn, CCGOCmode)
11028 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11030 || !TARGET_PARTIAL_FLAG_REG_STALL
11031 || (operands[2] == const1_rtx
11033 || TARGET_DOUBLE_WITH_ADD)))"
11035 switch (get_attr_type (insn))
11038 gcc_assert (operands[2] == const1_rtx);
11039 return "add{w}\t{%0, %0|%0, %0}";
11042 if (REG_P (operands[2]))
11043 return "sal{w}\t{%b2, %0|%0, %b2}";
11044 else if (operands[2] == const1_rtx
11045 && (TARGET_SHIFT1 || optimize_size))
11046 return "sal{w}\t%0";
11048 return "sal{w}\t{%2, %0|%0, %2}";
11051 [(set (attr "type")
11052 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11054 (match_operand 0 "register_operand" ""))
11055 (match_operand 2 "const1_operand" ""))
11056 (const_string "alu")
11058 (const_string "ishift")))
11059 (set_attr "mode" "HI")])
11061 (define_expand "ashlqi3"
11062 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11063 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11064 (match_operand:QI 2 "nonmemory_operand" "")))
11065 (clobber (reg:CC FLAGS_REG))]
11066 "TARGET_QIMODE_MATH"
11067 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11069 ;; %%% Potential partial reg stall on alternative 2. What to do?
11071 (define_insn "*ashlqi3_1_lea"
11072 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11073 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11074 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11075 (clobber (reg:CC FLAGS_REG))]
11076 "!TARGET_PARTIAL_REG_STALL
11077 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11079 switch (get_attr_type (insn))
11084 gcc_assert (operands[2] == const1_rtx);
11085 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11086 return "add{l}\t{%k0, %k0|%k0, %k0}";
11088 return "add{b}\t{%0, %0|%0, %0}";
11091 if (REG_P (operands[2]))
11093 if (get_attr_mode (insn) == MODE_SI)
11094 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11096 return "sal{b}\t{%b2, %0|%0, %b2}";
11098 else if (operands[2] == const1_rtx
11099 && (TARGET_SHIFT1 || optimize_size))
11101 if (get_attr_mode (insn) == MODE_SI)
11102 return "sal{l}\t%0";
11104 return "sal{b}\t%0";
11108 if (get_attr_mode (insn) == MODE_SI)
11109 return "sal{l}\t{%2, %k0|%k0, %2}";
11111 return "sal{b}\t{%2, %0|%0, %2}";
11115 [(set (attr "type")
11116 (cond [(eq_attr "alternative" "2")
11117 (const_string "lea")
11118 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11120 (match_operand 0 "register_operand" ""))
11121 (match_operand 2 "const1_operand" ""))
11122 (const_string "alu")
11124 (const_string "ishift")))
11125 (set_attr "mode" "QI,SI,SI")])
11127 (define_insn "*ashlqi3_1"
11128 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11129 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11130 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11131 (clobber (reg:CC FLAGS_REG))]
11132 "TARGET_PARTIAL_REG_STALL
11133 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11135 switch (get_attr_type (insn))
11138 gcc_assert (operands[2] == const1_rtx);
11139 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11140 return "add{l}\t{%k0, %k0|%k0, %k0}";
11142 return "add{b}\t{%0, %0|%0, %0}";
11145 if (REG_P (operands[2]))
11147 if (get_attr_mode (insn) == MODE_SI)
11148 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11150 return "sal{b}\t{%b2, %0|%0, %b2}";
11152 else if (operands[2] == const1_rtx
11153 && (TARGET_SHIFT1 || optimize_size))
11155 if (get_attr_mode (insn) == MODE_SI)
11156 return "sal{l}\t%0";
11158 return "sal{b}\t%0";
11162 if (get_attr_mode (insn) == MODE_SI)
11163 return "sal{l}\t{%2, %k0|%k0, %2}";
11165 return "sal{b}\t{%2, %0|%0, %2}";
11169 [(set (attr "type")
11170 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11172 (match_operand 0 "register_operand" ""))
11173 (match_operand 2 "const1_operand" ""))
11174 (const_string "alu")
11176 (const_string "ishift")))
11177 (set_attr "mode" "QI,SI")])
11179 ;; This pattern can't accept a variable shift count, since shifts by
11180 ;; zero don't affect the flags. We assume that shifts by constant
11181 ;; zero are optimized away.
11182 (define_insn "*ashlqi3_cmp"
11183 [(set (reg FLAGS_REG)
11185 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11186 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11188 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11189 (ashift:QI (match_dup 1) (match_dup 2)))]
11190 "ix86_match_ccmode (insn, CCGOCmode)
11191 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11193 || !TARGET_PARTIAL_FLAG_REG_STALL
11194 || (operands[2] == const1_rtx
11196 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11198 switch (get_attr_type (insn))
11201 gcc_assert (operands[2] == const1_rtx);
11202 return "add{b}\t{%0, %0|%0, %0}";
11205 if (REG_P (operands[2]))
11206 return "sal{b}\t{%b2, %0|%0, %b2}";
11207 else if (operands[2] == const1_rtx
11208 && (TARGET_SHIFT1 || optimize_size))
11209 return "sal{b}\t%0";
11211 return "sal{b}\t{%2, %0|%0, %2}";
11214 [(set (attr "type")
11215 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11217 (match_operand 0 "register_operand" ""))
11218 (match_operand 2 "const1_operand" ""))
11219 (const_string "alu")
11221 (const_string "ishift")))
11222 (set_attr "mode" "QI")])
11224 (define_insn "*ashlqi3_cconly"
11225 [(set (reg FLAGS_REG)
11227 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11228 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11230 (clobber (match_scratch:QI 0 "=q"))]
11231 "ix86_match_ccmode (insn, CCGOCmode)
11232 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11234 || !TARGET_PARTIAL_FLAG_REG_STALL
11235 || (operands[2] == const1_rtx
11237 || TARGET_DOUBLE_WITH_ADD)))"
11239 switch (get_attr_type (insn))
11242 gcc_assert (operands[2] == const1_rtx);
11243 return "add{b}\t{%0, %0|%0, %0}";
11246 if (REG_P (operands[2]))
11247 return "sal{b}\t{%b2, %0|%0, %b2}";
11248 else if (operands[2] == const1_rtx
11249 && (TARGET_SHIFT1 || optimize_size))
11250 return "sal{b}\t%0";
11252 return "sal{b}\t{%2, %0|%0, %2}";
11255 [(set (attr "type")
11256 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11258 (match_operand 0 "register_operand" ""))
11259 (match_operand 2 "const1_operand" ""))
11260 (const_string "alu")
11262 (const_string "ishift")))
11263 (set_attr "mode" "QI")])
11265 ;; See comment above `ashldi3' about how this works.
11267 (define_expand "ashrti3"
11268 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11269 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11270 (match_operand:QI 2 "nonmemory_operand" "")))
11271 (clobber (reg:CC FLAGS_REG))])]
11274 if (! immediate_operand (operands[2], QImode))
11276 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11279 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11283 (define_insn "ashrti3_1"
11284 [(set (match_operand:TI 0 "register_operand" "=r")
11285 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11286 (match_operand:QI 2 "register_operand" "c")))
11287 (clobber (match_scratch:DI 3 "=&r"))
11288 (clobber (reg:CC FLAGS_REG))]
11291 [(set_attr "type" "multi")])
11293 (define_insn "*ashrti3_2"
11294 [(set (match_operand:TI 0 "register_operand" "=r")
11295 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11296 (match_operand:QI 2 "immediate_operand" "O")))
11297 (clobber (reg:CC FLAGS_REG))]
11300 [(set_attr "type" "multi")])
11303 [(set (match_operand:TI 0 "register_operand" "")
11304 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11305 (match_operand:QI 2 "register_operand" "")))
11306 (clobber (match_scratch:DI 3 ""))
11307 (clobber (reg:CC FLAGS_REG))]
11308 "TARGET_64BIT && reload_completed"
11310 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11313 [(set (match_operand:TI 0 "register_operand" "")
11314 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11315 (match_operand:QI 2 "immediate_operand" "")))
11316 (clobber (reg:CC FLAGS_REG))]
11317 "TARGET_64BIT && reload_completed"
11319 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11321 (define_insn "x86_64_shrd"
11322 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11323 (ior:DI (ashiftrt:DI (match_dup 0)
11324 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11325 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11326 (minus:QI (const_int 64) (match_dup 2)))))
11327 (clobber (reg:CC FLAGS_REG))]
11330 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11331 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11332 [(set_attr "type" "ishift")
11333 (set_attr "prefix_0f" "1")
11334 (set_attr "mode" "DI")
11335 (set_attr "athlon_decode" "vector")])
11337 (define_expand "ashrdi3"
11338 [(set (match_operand:DI 0 "shiftdi_operand" "")
11339 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11340 (match_operand:QI 2 "nonmemory_operand" "")))]
11342 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11344 (define_insn "*ashrdi3_63_rex64"
11345 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11346 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11347 (match_operand:DI 2 "const_int_operand" "i,i")))
11348 (clobber (reg:CC FLAGS_REG))]
11349 "TARGET_64BIT && INTVAL (operands[2]) == 63
11350 && (TARGET_USE_CLTD || optimize_size)
11351 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11354 sar{q}\t{%2, %0|%0, %2}"
11355 [(set_attr "type" "imovx,ishift")
11356 (set_attr "prefix_0f" "0,*")
11357 (set_attr "length_immediate" "0,*")
11358 (set_attr "modrm" "0,1")
11359 (set_attr "mode" "DI")])
11361 (define_insn "*ashrdi3_1_one_bit_rex64"
11362 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11363 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11364 (match_operand:QI 2 "const1_operand" "")))
11365 (clobber (reg:CC FLAGS_REG))]
11366 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11367 && (TARGET_SHIFT1 || optimize_size)"
11369 [(set_attr "type" "ishift")
11370 (set (attr "length")
11371 (if_then_else (match_operand:DI 0 "register_operand" "")
11373 (const_string "*")))])
11375 (define_insn "*ashrdi3_1_rex64"
11376 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11377 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11378 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11379 (clobber (reg:CC FLAGS_REG))]
11380 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11382 sar{q}\t{%2, %0|%0, %2}
11383 sar{q}\t{%b2, %0|%0, %b2}"
11384 [(set_attr "type" "ishift")
11385 (set_attr "mode" "DI")])
11387 ;; This pattern can't accept a variable shift count, since shifts by
11388 ;; zero don't affect the flags. We assume that shifts by constant
11389 ;; zero are optimized away.
11390 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11391 [(set (reg FLAGS_REG)
11393 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11394 (match_operand:QI 2 "const1_operand" ""))
11396 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11397 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11398 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11399 && (TARGET_SHIFT1 || optimize_size)
11400 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11402 [(set_attr "type" "ishift")
11403 (set (attr "length")
11404 (if_then_else (match_operand:DI 0 "register_operand" "")
11406 (const_string "*")))])
11408 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11409 [(set (reg FLAGS_REG)
11411 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11412 (match_operand:QI 2 "const1_operand" ""))
11414 (clobber (match_scratch:DI 0 "=r"))]
11415 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11416 && (TARGET_SHIFT1 || optimize_size)
11417 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11419 [(set_attr "type" "ishift")
11420 (set_attr "length" "2")])
11422 ;; This pattern can't accept a variable shift count, since shifts by
11423 ;; zero don't affect the flags. We assume that shifts by constant
11424 ;; zero are optimized away.
11425 (define_insn "*ashrdi3_cmp_rex64"
11426 [(set (reg FLAGS_REG)
11428 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11429 (match_operand:QI 2 "const_int_operand" "n"))
11431 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11432 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11433 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11434 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11436 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11437 "sar{q}\t{%2, %0|%0, %2}"
11438 [(set_attr "type" "ishift")
11439 (set_attr "mode" "DI")])
11441 (define_insn "*ashrdi3_cconly_rex64"
11442 [(set (reg FLAGS_REG)
11444 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11445 (match_operand:QI 2 "const_int_operand" "n"))
11447 (clobber (match_scratch:DI 0 "=r"))]
11448 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11449 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11451 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11452 "sar{q}\t{%2, %0|%0, %2}"
11453 [(set_attr "type" "ishift")
11454 (set_attr "mode" "DI")])
11456 (define_insn "*ashrdi3_1"
11457 [(set (match_operand:DI 0 "register_operand" "=r")
11458 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11459 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11460 (clobber (reg:CC FLAGS_REG))]
11463 [(set_attr "type" "multi")])
11465 ;; By default we don't ask for a scratch register, because when DImode
11466 ;; values are manipulated, registers are already at a premium. But if
11467 ;; we have one handy, we won't turn it away.
11469 [(match_scratch:SI 3 "r")
11470 (parallel [(set (match_operand:DI 0 "register_operand" "")
11471 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11472 (match_operand:QI 2 "nonmemory_operand" "")))
11473 (clobber (reg:CC FLAGS_REG))])
11475 "!TARGET_64BIT && TARGET_CMOVE"
11477 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11480 [(set (match_operand:DI 0 "register_operand" "")
11481 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11482 (match_operand:QI 2 "nonmemory_operand" "")))
11483 (clobber (reg:CC FLAGS_REG))]
11484 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11485 ? flow2_completed : reload_completed)"
11487 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11489 (define_insn "x86_shrd_1"
11490 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11491 (ior:SI (ashiftrt:SI (match_dup 0)
11492 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11493 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11494 (minus:QI (const_int 32) (match_dup 2)))))
11495 (clobber (reg:CC FLAGS_REG))]
11498 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11499 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11500 [(set_attr "type" "ishift")
11501 (set_attr "prefix_0f" "1")
11502 (set_attr "pent_pair" "np")
11503 (set_attr "mode" "SI")])
11505 (define_expand "x86_shift_adj_3"
11506 [(use (match_operand:SI 0 "register_operand" ""))
11507 (use (match_operand:SI 1 "register_operand" ""))
11508 (use (match_operand:QI 2 "register_operand" ""))]
11511 rtx label = gen_label_rtx ();
11514 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11516 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11517 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11518 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11519 gen_rtx_LABEL_REF (VOIDmode, label),
11521 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11522 JUMP_LABEL (tmp) = label;
11524 emit_move_insn (operands[0], operands[1]);
11525 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11527 emit_label (label);
11528 LABEL_NUSES (label) = 1;
11533 (define_insn "ashrsi3_31"
11534 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11535 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11536 (match_operand:SI 2 "const_int_operand" "i,i")))
11537 (clobber (reg:CC FLAGS_REG))]
11538 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11539 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11542 sar{l}\t{%2, %0|%0, %2}"
11543 [(set_attr "type" "imovx,ishift")
11544 (set_attr "prefix_0f" "0,*")
11545 (set_attr "length_immediate" "0,*")
11546 (set_attr "modrm" "0,1")
11547 (set_attr "mode" "SI")])
11549 (define_insn "*ashrsi3_31_zext"
11550 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11551 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11552 (match_operand:SI 2 "const_int_operand" "i,i"))))
11553 (clobber (reg:CC FLAGS_REG))]
11554 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11555 && INTVAL (operands[2]) == 31
11556 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11559 sar{l}\t{%2, %k0|%k0, %2}"
11560 [(set_attr "type" "imovx,ishift")
11561 (set_attr "prefix_0f" "0,*")
11562 (set_attr "length_immediate" "0,*")
11563 (set_attr "modrm" "0,1")
11564 (set_attr "mode" "SI")])
11566 (define_expand "ashrsi3"
11567 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11568 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11569 (match_operand:QI 2 "nonmemory_operand" "")))
11570 (clobber (reg:CC FLAGS_REG))]
11572 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11574 (define_insn "*ashrsi3_1_one_bit"
11575 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11576 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11577 (match_operand:QI 2 "const1_operand" "")))
11578 (clobber (reg:CC FLAGS_REG))]
11579 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11580 && (TARGET_SHIFT1 || optimize_size)"
11582 [(set_attr "type" "ishift")
11583 (set (attr "length")
11584 (if_then_else (match_operand:SI 0 "register_operand" "")
11586 (const_string "*")))])
11588 (define_insn "*ashrsi3_1_one_bit_zext"
11589 [(set (match_operand:DI 0 "register_operand" "=r")
11590 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11591 (match_operand:QI 2 "const1_operand" ""))))
11592 (clobber (reg:CC FLAGS_REG))]
11593 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11594 && (TARGET_SHIFT1 || optimize_size)"
11596 [(set_attr "type" "ishift")
11597 (set_attr "length" "2")])
11599 (define_insn "*ashrsi3_1"
11600 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11601 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11602 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11603 (clobber (reg:CC FLAGS_REG))]
11604 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11606 sar{l}\t{%2, %0|%0, %2}
11607 sar{l}\t{%b2, %0|%0, %b2}"
11608 [(set_attr "type" "ishift")
11609 (set_attr "mode" "SI")])
11611 (define_insn "*ashrsi3_1_zext"
11612 [(set (match_operand:DI 0 "register_operand" "=r,r")
11613 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11614 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11615 (clobber (reg:CC FLAGS_REG))]
11616 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11618 sar{l}\t{%2, %k0|%k0, %2}
11619 sar{l}\t{%b2, %k0|%k0, %b2}"
11620 [(set_attr "type" "ishift")
11621 (set_attr "mode" "SI")])
11623 ;; This pattern can't accept a variable shift count, since shifts by
11624 ;; zero don't affect the flags. We assume that shifts by constant
11625 ;; zero are optimized away.
11626 (define_insn "*ashrsi3_one_bit_cmp"
11627 [(set (reg FLAGS_REG)
11629 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11630 (match_operand:QI 2 "const1_operand" ""))
11632 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11633 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11634 "ix86_match_ccmode (insn, CCGOCmode)
11635 && (TARGET_SHIFT1 || optimize_size)
11636 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11638 [(set_attr "type" "ishift")
11639 (set (attr "length")
11640 (if_then_else (match_operand:SI 0 "register_operand" "")
11642 (const_string "*")))])
11644 (define_insn "*ashrsi3_one_bit_cconly"
11645 [(set (reg FLAGS_REG)
11647 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11648 (match_operand:QI 2 "const1_operand" ""))
11650 (clobber (match_scratch:SI 0 "=r"))]
11651 "ix86_match_ccmode (insn, CCGOCmode)
11652 && (TARGET_SHIFT1 || optimize_size)
11653 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11655 [(set_attr "type" "ishift")
11656 (set_attr "length" "2")])
11658 (define_insn "*ashrsi3_one_bit_cmp_zext"
11659 [(set (reg FLAGS_REG)
11661 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11662 (match_operand:QI 2 "const1_operand" ""))
11664 (set (match_operand:DI 0 "register_operand" "=r")
11665 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11666 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11667 && (TARGET_SHIFT1 || optimize_size)
11668 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11670 [(set_attr "type" "ishift")
11671 (set_attr "length" "2")])
11673 ;; This pattern can't accept a variable shift count, since shifts by
11674 ;; zero don't affect the flags. We assume that shifts by constant
11675 ;; zero are optimized away.
11676 (define_insn "*ashrsi3_cmp"
11677 [(set (reg FLAGS_REG)
11679 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11680 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11682 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11683 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11684 "ix86_match_ccmode (insn, CCGOCmode)
11685 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11687 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11688 "sar{l}\t{%2, %0|%0, %2}"
11689 [(set_attr "type" "ishift")
11690 (set_attr "mode" "SI")])
11692 (define_insn "*ashrsi3_cconly"
11693 [(set (reg FLAGS_REG)
11695 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11696 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11698 (clobber (match_scratch:SI 0 "=r"))]
11699 "ix86_match_ccmode (insn, CCGOCmode)
11700 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11702 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11703 "sar{l}\t{%2, %0|%0, %2}"
11704 [(set_attr "type" "ishift")
11705 (set_attr "mode" "SI")])
11707 (define_insn "*ashrsi3_cmp_zext"
11708 [(set (reg FLAGS_REG)
11710 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11711 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11713 (set (match_operand:DI 0 "register_operand" "=r")
11714 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11715 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11716 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11718 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11719 "sar{l}\t{%2, %k0|%k0, %2}"
11720 [(set_attr "type" "ishift")
11721 (set_attr "mode" "SI")])
11723 (define_expand "ashrhi3"
11724 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11725 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11726 (match_operand:QI 2 "nonmemory_operand" "")))
11727 (clobber (reg:CC FLAGS_REG))]
11728 "TARGET_HIMODE_MATH"
11729 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11731 (define_insn "*ashrhi3_1_one_bit"
11732 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11733 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11734 (match_operand:QI 2 "const1_operand" "")))
11735 (clobber (reg:CC FLAGS_REG))]
11736 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11737 && (TARGET_SHIFT1 || optimize_size)"
11739 [(set_attr "type" "ishift")
11740 (set (attr "length")
11741 (if_then_else (match_operand 0 "register_operand" "")
11743 (const_string "*")))])
11745 (define_insn "*ashrhi3_1"
11746 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11747 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11748 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11749 (clobber (reg:CC FLAGS_REG))]
11750 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11752 sar{w}\t{%2, %0|%0, %2}
11753 sar{w}\t{%b2, %0|%0, %b2}"
11754 [(set_attr "type" "ishift")
11755 (set_attr "mode" "HI")])
11757 ;; This pattern can't accept a variable shift count, since shifts by
11758 ;; zero don't affect the flags. We assume that shifts by constant
11759 ;; zero are optimized away.
11760 (define_insn "*ashrhi3_one_bit_cmp"
11761 [(set (reg FLAGS_REG)
11763 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11764 (match_operand:QI 2 "const1_operand" ""))
11766 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11767 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11768 "ix86_match_ccmode (insn, CCGOCmode)
11769 && (TARGET_SHIFT1 || optimize_size)
11770 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11772 [(set_attr "type" "ishift")
11773 (set (attr "length")
11774 (if_then_else (match_operand 0 "register_operand" "")
11776 (const_string "*")))])
11778 (define_insn "*ashrhi3_one_bit_cconly"
11779 [(set (reg FLAGS_REG)
11781 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11782 (match_operand:QI 2 "const1_operand" ""))
11784 (clobber (match_scratch:HI 0 "=r"))]
11785 "ix86_match_ccmode (insn, CCGOCmode)
11786 && (TARGET_SHIFT1 || optimize_size)
11787 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11789 [(set_attr "type" "ishift")
11790 (set_attr "length" "2")])
11792 ;; This pattern can't accept a variable shift count, since shifts by
11793 ;; zero don't affect the flags. We assume that shifts by constant
11794 ;; zero are optimized away.
11795 (define_insn "*ashrhi3_cmp"
11796 [(set (reg FLAGS_REG)
11798 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11799 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11801 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11802 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11803 "ix86_match_ccmode (insn, CCGOCmode)
11804 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11806 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11807 "sar{w}\t{%2, %0|%0, %2}"
11808 [(set_attr "type" "ishift")
11809 (set_attr "mode" "HI")])
11811 (define_insn "*ashrhi3_cconly"
11812 [(set (reg FLAGS_REG)
11814 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11815 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11817 (clobber (match_scratch:HI 0 "=r"))]
11818 "ix86_match_ccmode (insn, CCGOCmode)
11819 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11821 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11822 "sar{w}\t{%2, %0|%0, %2}"
11823 [(set_attr "type" "ishift")
11824 (set_attr "mode" "HI")])
11826 (define_expand "ashrqi3"
11827 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11828 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11829 (match_operand:QI 2 "nonmemory_operand" "")))
11830 (clobber (reg:CC FLAGS_REG))]
11831 "TARGET_QIMODE_MATH"
11832 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11834 (define_insn "*ashrqi3_1_one_bit"
11835 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11836 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11837 (match_operand:QI 2 "const1_operand" "")))
11838 (clobber (reg:CC FLAGS_REG))]
11839 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11840 && (TARGET_SHIFT1 || optimize_size)"
11842 [(set_attr "type" "ishift")
11843 (set (attr "length")
11844 (if_then_else (match_operand 0 "register_operand" "")
11846 (const_string "*")))])
11848 (define_insn "*ashrqi3_1_one_bit_slp"
11849 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11850 (ashiftrt:QI (match_dup 0)
11851 (match_operand:QI 1 "const1_operand" "")))
11852 (clobber (reg:CC FLAGS_REG))]
11853 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11854 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11855 && (TARGET_SHIFT1 || optimize_size)"
11857 [(set_attr "type" "ishift1")
11858 (set (attr "length")
11859 (if_then_else (match_operand 0 "register_operand" "")
11861 (const_string "*")))])
11863 (define_insn "*ashrqi3_1"
11864 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11865 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11866 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11867 (clobber (reg:CC FLAGS_REG))]
11868 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11870 sar{b}\t{%2, %0|%0, %2}
11871 sar{b}\t{%b2, %0|%0, %b2}"
11872 [(set_attr "type" "ishift")
11873 (set_attr "mode" "QI")])
11875 (define_insn "*ashrqi3_1_slp"
11876 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11877 (ashiftrt:QI (match_dup 0)
11878 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11879 (clobber (reg:CC FLAGS_REG))]
11880 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11881 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11883 sar{b}\t{%1, %0|%0, %1}
11884 sar{b}\t{%b1, %0|%0, %b1}"
11885 [(set_attr "type" "ishift1")
11886 (set_attr "mode" "QI")])
11888 ;; This pattern can't accept a variable shift count, since shifts by
11889 ;; zero don't affect the flags. We assume that shifts by constant
11890 ;; zero are optimized away.
11891 (define_insn "*ashrqi3_one_bit_cmp"
11892 [(set (reg FLAGS_REG)
11894 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11895 (match_operand:QI 2 "const1_operand" "I"))
11897 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11898 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11899 "ix86_match_ccmode (insn, CCGOCmode)
11900 && (TARGET_SHIFT1 || optimize_size)
11901 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11903 [(set_attr "type" "ishift")
11904 (set (attr "length")
11905 (if_then_else (match_operand 0 "register_operand" "")
11907 (const_string "*")))])
11909 (define_insn "*ashrqi3_one_bit_cconly"
11910 [(set (reg FLAGS_REG)
11912 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11913 (match_operand:QI 2 "const1_operand" "I"))
11915 (clobber (match_scratch:QI 0 "=q"))]
11916 "ix86_match_ccmode (insn, CCGOCmode)
11917 && (TARGET_SHIFT1 || optimize_size)
11918 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11920 [(set_attr "type" "ishift")
11921 (set_attr "length" "2")])
11923 ;; This pattern can't accept a variable shift count, since shifts by
11924 ;; zero don't affect the flags. We assume that shifts by constant
11925 ;; zero are optimized away.
11926 (define_insn "*ashrqi3_cmp"
11927 [(set (reg FLAGS_REG)
11929 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11930 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11932 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11933 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11934 "ix86_match_ccmode (insn, CCGOCmode)
11935 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11937 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11938 "sar{b}\t{%2, %0|%0, %2}"
11939 [(set_attr "type" "ishift")
11940 (set_attr "mode" "QI")])
11942 (define_insn "*ashrqi3_cconly"
11943 [(set (reg FLAGS_REG)
11945 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11946 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11948 (clobber (match_scratch:QI 0 "=q"))]
11949 "ix86_match_ccmode (insn, CCGOCmode)
11950 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11952 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11953 "sar{b}\t{%2, %0|%0, %2}"
11954 [(set_attr "type" "ishift")
11955 (set_attr "mode" "QI")])
11958 ;; Logical shift instructions
11960 ;; See comment above `ashldi3' about how this works.
11962 (define_expand "lshrti3"
11963 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11964 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11965 (match_operand:QI 2 "nonmemory_operand" "")))
11966 (clobber (reg:CC FLAGS_REG))])]
11969 if (! immediate_operand (operands[2], QImode))
11971 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11974 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11978 (define_insn "lshrti3_1"
11979 [(set (match_operand:TI 0 "register_operand" "=r")
11980 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11981 (match_operand:QI 2 "register_operand" "c")))
11982 (clobber (match_scratch:DI 3 "=&r"))
11983 (clobber (reg:CC FLAGS_REG))]
11986 [(set_attr "type" "multi")])
11988 (define_insn "*lshrti3_2"
11989 [(set (match_operand:TI 0 "register_operand" "=r")
11990 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11991 (match_operand:QI 2 "immediate_operand" "O")))
11992 (clobber (reg:CC FLAGS_REG))]
11995 [(set_attr "type" "multi")])
11998 [(set (match_operand:TI 0 "register_operand" "")
11999 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12000 (match_operand:QI 2 "register_operand" "")))
12001 (clobber (match_scratch:DI 3 ""))
12002 (clobber (reg:CC FLAGS_REG))]
12003 "TARGET_64BIT && reload_completed"
12005 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12008 [(set (match_operand:TI 0 "register_operand" "")
12009 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12010 (match_operand:QI 2 "immediate_operand" "")))
12011 (clobber (reg:CC FLAGS_REG))]
12012 "TARGET_64BIT && reload_completed"
12014 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12016 (define_expand "lshrdi3"
12017 [(set (match_operand:DI 0 "shiftdi_operand" "")
12018 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12019 (match_operand:QI 2 "nonmemory_operand" "")))]
12021 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12023 (define_insn "*lshrdi3_1_one_bit_rex64"
12024 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12025 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12026 (match_operand:QI 2 "const1_operand" "")))
12027 (clobber (reg:CC FLAGS_REG))]
12028 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12029 && (TARGET_SHIFT1 || optimize_size)"
12031 [(set_attr "type" "ishift")
12032 (set (attr "length")
12033 (if_then_else (match_operand:DI 0 "register_operand" "")
12035 (const_string "*")))])
12037 (define_insn "*lshrdi3_1_rex64"
12038 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12039 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12040 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12041 (clobber (reg:CC FLAGS_REG))]
12042 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12044 shr{q}\t{%2, %0|%0, %2}
12045 shr{q}\t{%b2, %0|%0, %b2}"
12046 [(set_attr "type" "ishift")
12047 (set_attr "mode" "DI")])
12049 ;; This pattern can't accept a variable shift count, since shifts by
12050 ;; zero don't affect the flags. We assume that shifts by constant
12051 ;; zero are optimized away.
12052 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12053 [(set (reg FLAGS_REG)
12055 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12056 (match_operand:QI 2 "const1_operand" ""))
12058 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12059 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12060 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12061 && (TARGET_SHIFT1 || optimize_size)
12062 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12064 [(set_attr "type" "ishift")
12065 (set (attr "length")
12066 (if_then_else (match_operand:DI 0 "register_operand" "")
12068 (const_string "*")))])
12070 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12071 [(set (reg FLAGS_REG)
12073 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12074 (match_operand:QI 2 "const1_operand" ""))
12076 (clobber (match_scratch:DI 0 "=r"))]
12077 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12078 && (TARGET_SHIFT1 || optimize_size)
12079 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12081 [(set_attr "type" "ishift")
12082 (set_attr "length" "2")])
12084 ;; This pattern can't accept a variable shift count, since shifts by
12085 ;; zero don't affect the flags. We assume that shifts by constant
12086 ;; zero are optimized away.
12087 (define_insn "*lshrdi3_cmp_rex64"
12088 [(set (reg FLAGS_REG)
12090 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12091 (match_operand:QI 2 "const_int_operand" "e"))
12093 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12094 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12095 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12096 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12098 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12099 "shr{q}\t{%2, %0|%0, %2}"
12100 [(set_attr "type" "ishift")
12101 (set_attr "mode" "DI")])
12103 (define_insn "*lshrdi3_cconly_rex64"
12104 [(set (reg FLAGS_REG)
12106 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12107 (match_operand:QI 2 "const_int_operand" "e"))
12109 (clobber (match_scratch:DI 0 "=r"))]
12110 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12111 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12113 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12114 "shr{q}\t{%2, %0|%0, %2}"
12115 [(set_attr "type" "ishift")
12116 (set_attr "mode" "DI")])
12118 (define_insn "*lshrdi3_1"
12119 [(set (match_operand:DI 0 "register_operand" "=r")
12120 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12121 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12122 (clobber (reg:CC FLAGS_REG))]
12125 [(set_attr "type" "multi")])
12127 ;; By default we don't ask for a scratch register, because when DImode
12128 ;; values are manipulated, registers are already at a premium. But if
12129 ;; we have one handy, we won't turn it away.
12131 [(match_scratch:SI 3 "r")
12132 (parallel [(set (match_operand:DI 0 "register_operand" "")
12133 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12134 (match_operand:QI 2 "nonmemory_operand" "")))
12135 (clobber (reg:CC FLAGS_REG))])
12137 "!TARGET_64BIT && TARGET_CMOVE"
12139 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12142 [(set (match_operand:DI 0 "register_operand" "")
12143 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12144 (match_operand:QI 2 "nonmemory_operand" "")))
12145 (clobber (reg:CC FLAGS_REG))]
12146 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12147 ? flow2_completed : reload_completed)"
12149 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12151 (define_expand "lshrsi3"
12152 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12153 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12154 (match_operand:QI 2 "nonmemory_operand" "")))
12155 (clobber (reg:CC FLAGS_REG))]
12157 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12159 (define_insn "*lshrsi3_1_one_bit"
12160 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12161 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12162 (match_operand:QI 2 "const1_operand" "")))
12163 (clobber (reg:CC FLAGS_REG))]
12164 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12165 && (TARGET_SHIFT1 || optimize_size)"
12167 [(set_attr "type" "ishift")
12168 (set (attr "length")
12169 (if_then_else (match_operand:SI 0 "register_operand" "")
12171 (const_string "*")))])
12173 (define_insn "*lshrsi3_1_one_bit_zext"
12174 [(set (match_operand:DI 0 "register_operand" "=r")
12175 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12176 (match_operand:QI 2 "const1_operand" "")))
12177 (clobber (reg:CC FLAGS_REG))]
12178 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12179 && (TARGET_SHIFT1 || optimize_size)"
12181 [(set_attr "type" "ishift")
12182 (set_attr "length" "2")])
12184 (define_insn "*lshrsi3_1"
12185 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12186 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12187 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12188 (clobber (reg:CC FLAGS_REG))]
12189 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12191 shr{l}\t{%2, %0|%0, %2}
12192 shr{l}\t{%b2, %0|%0, %b2}"
12193 [(set_attr "type" "ishift")
12194 (set_attr "mode" "SI")])
12196 (define_insn "*lshrsi3_1_zext"
12197 [(set (match_operand:DI 0 "register_operand" "=r,r")
12199 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12200 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12201 (clobber (reg:CC FLAGS_REG))]
12202 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12204 shr{l}\t{%2, %k0|%k0, %2}
12205 shr{l}\t{%b2, %k0|%k0, %b2}"
12206 [(set_attr "type" "ishift")
12207 (set_attr "mode" "SI")])
12209 ;; This pattern can't accept a variable shift count, since shifts by
12210 ;; zero don't affect the flags. We assume that shifts by constant
12211 ;; zero are optimized away.
12212 (define_insn "*lshrsi3_one_bit_cmp"
12213 [(set (reg FLAGS_REG)
12215 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12216 (match_operand:QI 2 "const1_operand" ""))
12218 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12219 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12220 "ix86_match_ccmode (insn, CCGOCmode)
12221 && (TARGET_SHIFT1 || optimize_size)
12222 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12224 [(set_attr "type" "ishift")
12225 (set (attr "length")
12226 (if_then_else (match_operand:SI 0 "register_operand" "")
12228 (const_string "*")))])
12230 (define_insn "*lshrsi3_one_bit_cconly"
12231 [(set (reg FLAGS_REG)
12233 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12234 (match_operand:QI 2 "const1_operand" ""))
12236 (clobber (match_scratch:SI 0 "=r"))]
12237 "ix86_match_ccmode (insn, CCGOCmode)
12238 && (TARGET_SHIFT1 || optimize_size)
12239 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12241 [(set_attr "type" "ishift")
12242 (set_attr "length" "2")])
12244 (define_insn "*lshrsi3_cmp_one_bit_zext"
12245 [(set (reg FLAGS_REG)
12247 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12248 (match_operand:QI 2 "const1_operand" ""))
12250 (set (match_operand:DI 0 "register_operand" "=r")
12251 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12252 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12253 && (TARGET_SHIFT1 || optimize_size)
12254 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12256 [(set_attr "type" "ishift")
12257 (set_attr "length" "2")])
12259 ;; This pattern can't accept a variable shift count, since shifts by
12260 ;; zero don't affect the flags. We assume that shifts by constant
12261 ;; zero are optimized away.
12262 (define_insn "*lshrsi3_cmp"
12263 [(set (reg FLAGS_REG)
12265 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12266 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12268 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12269 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12270 "ix86_match_ccmode (insn, CCGOCmode)
12271 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12273 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12274 "shr{l}\t{%2, %0|%0, %2}"
12275 [(set_attr "type" "ishift")
12276 (set_attr "mode" "SI")])
12278 (define_insn "*lshrsi3_cconly"
12279 [(set (reg FLAGS_REG)
12281 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12282 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12284 (clobber (match_scratch:SI 0 "=r"))]
12285 "ix86_match_ccmode (insn, CCGOCmode)
12286 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12288 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12289 "shr{l}\t{%2, %0|%0, %2}"
12290 [(set_attr "type" "ishift")
12291 (set_attr "mode" "SI")])
12293 (define_insn "*lshrsi3_cmp_zext"
12294 [(set (reg FLAGS_REG)
12296 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12297 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12299 (set (match_operand:DI 0 "register_operand" "=r")
12300 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12301 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12302 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12304 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12305 "shr{l}\t{%2, %k0|%k0, %2}"
12306 [(set_attr "type" "ishift")
12307 (set_attr "mode" "SI")])
12309 (define_expand "lshrhi3"
12310 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12311 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12312 (match_operand:QI 2 "nonmemory_operand" "")))
12313 (clobber (reg:CC FLAGS_REG))]
12314 "TARGET_HIMODE_MATH"
12315 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12317 (define_insn "*lshrhi3_1_one_bit"
12318 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12319 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12320 (match_operand:QI 2 "const1_operand" "")))
12321 (clobber (reg:CC FLAGS_REG))]
12322 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12323 && (TARGET_SHIFT1 || optimize_size)"
12325 [(set_attr "type" "ishift")
12326 (set (attr "length")
12327 (if_then_else (match_operand 0 "register_operand" "")
12329 (const_string "*")))])
12331 (define_insn "*lshrhi3_1"
12332 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12333 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12334 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12335 (clobber (reg:CC FLAGS_REG))]
12336 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12338 shr{w}\t{%2, %0|%0, %2}
12339 shr{w}\t{%b2, %0|%0, %b2}"
12340 [(set_attr "type" "ishift")
12341 (set_attr "mode" "HI")])
12343 ;; This pattern can't accept a variable shift count, since shifts by
12344 ;; zero don't affect the flags. We assume that shifts by constant
12345 ;; zero are optimized away.
12346 (define_insn "*lshrhi3_one_bit_cmp"
12347 [(set (reg FLAGS_REG)
12349 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12350 (match_operand:QI 2 "const1_operand" ""))
12352 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12353 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12354 "ix86_match_ccmode (insn, CCGOCmode)
12355 && (TARGET_SHIFT1 || optimize_size)
12356 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12358 [(set_attr "type" "ishift")
12359 (set (attr "length")
12360 (if_then_else (match_operand:SI 0 "register_operand" "")
12362 (const_string "*")))])
12364 (define_insn "*lshrhi3_one_bit_cconly"
12365 [(set (reg FLAGS_REG)
12367 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368 (match_operand:QI 2 "const1_operand" ""))
12370 (clobber (match_scratch:HI 0 "=r"))]
12371 "ix86_match_ccmode (insn, CCGOCmode)
12372 && (TARGET_SHIFT1 || optimize_size)
12373 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12375 [(set_attr "type" "ishift")
12376 (set_attr "length" "2")])
12378 ;; This pattern can't accept a variable shift count, since shifts by
12379 ;; zero don't affect the flags. We assume that shifts by constant
12380 ;; zero are optimized away.
12381 (define_insn "*lshrhi3_cmp"
12382 [(set (reg FLAGS_REG)
12384 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12385 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12387 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12388 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12389 "ix86_match_ccmode (insn, CCGOCmode)
12390 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12392 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12393 "shr{w}\t{%2, %0|%0, %2}"
12394 [(set_attr "type" "ishift")
12395 (set_attr "mode" "HI")])
12397 (define_insn "*lshrhi3_cconly"
12398 [(set (reg FLAGS_REG)
12400 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12401 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12403 (clobber (match_scratch:HI 0 "=r"))]
12404 "ix86_match_ccmode (insn, CCGOCmode)
12405 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12407 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12408 "shr{w}\t{%2, %0|%0, %2}"
12409 [(set_attr "type" "ishift")
12410 (set_attr "mode" "HI")])
12412 (define_expand "lshrqi3"
12413 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12414 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12415 (match_operand:QI 2 "nonmemory_operand" "")))
12416 (clobber (reg:CC FLAGS_REG))]
12417 "TARGET_QIMODE_MATH"
12418 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12420 (define_insn "*lshrqi3_1_one_bit"
12421 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12422 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12423 (match_operand:QI 2 "const1_operand" "")))
12424 (clobber (reg:CC FLAGS_REG))]
12425 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12426 && (TARGET_SHIFT1 || optimize_size)"
12428 [(set_attr "type" "ishift")
12429 (set (attr "length")
12430 (if_then_else (match_operand 0 "register_operand" "")
12432 (const_string "*")))])
12434 (define_insn "*lshrqi3_1_one_bit_slp"
12435 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12436 (lshiftrt:QI (match_dup 0)
12437 (match_operand:QI 1 "const1_operand" "")))
12438 (clobber (reg:CC FLAGS_REG))]
12439 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12440 && (TARGET_SHIFT1 || optimize_size)"
12442 [(set_attr "type" "ishift1")
12443 (set (attr "length")
12444 (if_then_else (match_operand 0 "register_operand" "")
12446 (const_string "*")))])
12448 (define_insn "*lshrqi3_1"
12449 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12450 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12451 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12452 (clobber (reg:CC FLAGS_REG))]
12453 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12455 shr{b}\t{%2, %0|%0, %2}
12456 shr{b}\t{%b2, %0|%0, %b2}"
12457 [(set_attr "type" "ishift")
12458 (set_attr "mode" "QI")])
12460 (define_insn "*lshrqi3_1_slp"
12461 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12462 (lshiftrt:QI (match_dup 0)
12463 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12464 (clobber (reg:CC FLAGS_REG))]
12465 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12466 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12468 shr{b}\t{%1, %0|%0, %1}
12469 shr{b}\t{%b1, %0|%0, %b1}"
12470 [(set_attr "type" "ishift1")
12471 (set_attr "mode" "QI")])
12473 ;; This pattern can't accept a variable shift count, since shifts by
12474 ;; zero don't affect the flags. We assume that shifts by constant
12475 ;; zero are optimized away.
12476 (define_insn "*lshrqi2_one_bit_cmp"
12477 [(set (reg FLAGS_REG)
12479 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12480 (match_operand:QI 2 "const1_operand" ""))
12482 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12483 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12484 "ix86_match_ccmode (insn, CCGOCmode)
12485 && (TARGET_SHIFT1 || optimize_size)
12486 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12488 [(set_attr "type" "ishift")
12489 (set (attr "length")
12490 (if_then_else (match_operand:SI 0 "register_operand" "")
12492 (const_string "*")))])
12494 (define_insn "*lshrqi2_one_bit_cconly"
12495 [(set (reg FLAGS_REG)
12497 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12498 (match_operand:QI 2 "const1_operand" ""))
12500 (clobber (match_scratch:QI 0 "=q"))]
12501 "ix86_match_ccmode (insn, CCGOCmode)
12502 && (TARGET_SHIFT1 || optimize_size)
12503 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12505 [(set_attr "type" "ishift")
12506 (set_attr "length" "2")])
12508 ;; This pattern can't accept a variable shift count, since shifts by
12509 ;; zero don't affect the flags. We assume that shifts by constant
12510 ;; zero are optimized away.
12511 (define_insn "*lshrqi2_cmp"
12512 [(set (reg FLAGS_REG)
12514 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12515 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12517 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12518 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12519 "ix86_match_ccmode (insn, CCGOCmode)
12520 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12522 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12523 "shr{b}\t{%2, %0|%0, %2}"
12524 [(set_attr "type" "ishift")
12525 (set_attr "mode" "QI")])
12527 (define_insn "*lshrqi2_cconly"
12528 [(set (reg FLAGS_REG)
12530 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12531 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12533 (clobber (match_scratch:QI 0 "=q"))]
12534 "ix86_match_ccmode (insn, CCGOCmode)
12535 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12537 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12538 "shr{b}\t{%2, %0|%0, %2}"
12539 [(set_attr "type" "ishift")
12540 (set_attr "mode" "QI")])
12542 ;; Rotate instructions
12544 (define_expand "rotldi3"
12545 [(set (match_operand:DI 0 "shiftdi_operand" "")
12546 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12547 (match_operand:QI 2 "nonmemory_operand" "")))
12548 (clobber (reg:CC FLAGS_REG))]
12553 ix86_expand_binary_operator (ROTATE, DImode, operands);
12556 if (!const_1_to_31_operand (operands[2], VOIDmode))
12558 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12562 ;; Implement rotation using two double-precision shift instructions
12563 ;; and a scratch register.
12564 (define_insn_and_split "ix86_rotldi3"
12565 [(set (match_operand:DI 0 "register_operand" "=r")
12566 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12567 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12568 (clobber (reg:CC FLAGS_REG))
12569 (clobber (match_scratch:SI 3 "=&r"))]
12572 "&& reload_completed"
12573 [(set (match_dup 3) (match_dup 4))
12575 [(set (match_dup 4)
12576 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12577 (lshiftrt:SI (match_dup 5)
12578 (minus:QI (const_int 32) (match_dup 2)))))
12579 (clobber (reg:CC FLAGS_REG))])
12581 [(set (match_dup 5)
12582 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12583 (lshiftrt:SI (match_dup 3)
12584 (minus:QI (const_int 32) (match_dup 2)))))
12585 (clobber (reg:CC FLAGS_REG))])]
12586 "split_di (operands, 1, operands + 4, operands + 5);")
12588 (define_insn "*rotlsi3_1_one_bit_rex64"
12589 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12590 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12591 (match_operand:QI 2 "const1_operand" "")))
12592 (clobber (reg:CC FLAGS_REG))]
12593 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12594 && (TARGET_SHIFT1 || optimize_size)"
12596 [(set_attr "type" "rotate")
12597 (set (attr "length")
12598 (if_then_else (match_operand:DI 0 "register_operand" "")
12600 (const_string "*")))])
12602 (define_insn "*rotldi3_1_rex64"
12603 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12604 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12605 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12606 (clobber (reg:CC FLAGS_REG))]
12607 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12609 rol{q}\t{%2, %0|%0, %2}
12610 rol{q}\t{%b2, %0|%0, %b2}"
12611 [(set_attr "type" "rotate")
12612 (set_attr "mode" "DI")])
12614 (define_expand "rotlsi3"
12615 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12616 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12617 (match_operand:QI 2 "nonmemory_operand" "")))
12618 (clobber (reg:CC FLAGS_REG))]
12620 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12622 (define_insn "*rotlsi3_1_one_bit"
12623 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12624 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12625 (match_operand:QI 2 "const1_operand" "")))
12626 (clobber (reg:CC FLAGS_REG))]
12627 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12628 && (TARGET_SHIFT1 || optimize_size)"
12630 [(set_attr "type" "rotate")
12631 (set (attr "length")
12632 (if_then_else (match_operand:SI 0 "register_operand" "")
12634 (const_string "*")))])
12636 (define_insn "*rotlsi3_1_one_bit_zext"
12637 [(set (match_operand:DI 0 "register_operand" "=r")
12639 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12640 (match_operand:QI 2 "const1_operand" ""))))
12641 (clobber (reg:CC FLAGS_REG))]
12642 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12643 && (TARGET_SHIFT1 || optimize_size)"
12645 [(set_attr "type" "rotate")
12646 (set_attr "length" "2")])
12648 (define_insn "*rotlsi3_1"
12649 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12650 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12651 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12652 (clobber (reg:CC FLAGS_REG))]
12653 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12655 rol{l}\t{%2, %0|%0, %2}
12656 rol{l}\t{%b2, %0|%0, %b2}"
12657 [(set_attr "type" "rotate")
12658 (set_attr "mode" "SI")])
12660 (define_insn "*rotlsi3_1_zext"
12661 [(set (match_operand:DI 0 "register_operand" "=r,r")
12663 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12664 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12665 (clobber (reg:CC FLAGS_REG))]
12666 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12668 rol{l}\t{%2, %k0|%k0, %2}
12669 rol{l}\t{%b2, %k0|%k0, %b2}"
12670 [(set_attr "type" "rotate")
12671 (set_attr "mode" "SI")])
12673 (define_expand "rotlhi3"
12674 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12675 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12676 (match_operand:QI 2 "nonmemory_operand" "")))
12677 (clobber (reg:CC FLAGS_REG))]
12678 "TARGET_HIMODE_MATH"
12679 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12681 (define_insn "*rotlhi3_1_one_bit"
12682 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12683 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12684 (match_operand:QI 2 "const1_operand" "")))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12687 && (TARGET_SHIFT1 || optimize_size)"
12689 [(set_attr "type" "rotate")
12690 (set (attr "length")
12691 (if_then_else (match_operand 0 "register_operand" "")
12693 (const_string "*")))])
12695 (define_insn "*rotlhi3_1"
12696 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12697 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12698 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12699 (clobber (reg:CC FLAGS_REG))]
12700 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12702 rol{w}\t{%2, %0|%0, %2}
12703 rol{w}\t{%b2, %0|%0, %b2}"
12704 [(set_attr "type" "rotate")
12705 (set_attr "mode" "HI")])
12707 (define_expand "rotlqi3"
12708 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12709 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12710 (match_operand:QI 2 "nonmemory_operand" "")))
12711 (clobber (reg:CC FLAGS_REG))]
12712 "TARGET_QIMODE_MATH"
12713 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12715 (define_insn "*rotlqi3_1_one_bit_slp"
12716 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12717 (rotate:QI (match_dup 0)
12718 (match_operand:QI 1 "const1_operand" "")))
12719 (clobber (reg:CC FLAGS_REG))]
12720 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12721 && (TARGET_SHIFT1 || optimize_size)"
12723 [(set_attr "type" "rotate1")
12724 (set (attr "length")
12725 (if_then_else (match_operand 0 "register_operand" "")
12727 (const_string "*")))])
12729 (define_insn "*rotlqi3_1_one_bit"
12730 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12731 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12732 (match_operand:QI 2 "const1_operand" "")))
12733 (clobber (reg:CC FLAGS_REG))]
12734 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12735 && (TARGET_SHIFT1 || optimize_size)"
12737 [(set_attr "type" "rotate")
12738 (set (attr "length")
12739 (if_then_else (match_operand 0 "register_operand" "")
12741 (const_string "*")))])
12743 (define_insn "*rotlqi3_1_slp"
12744 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12745 (rotate:QI (match_dup 0)
12746 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12747 (clobber (reg:CC FLAGS_REG))]
12748 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12749 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12751 rol{b}\t{%1, %0|%0, %1}
12752 rol{b}\t{%b1, %0|%0, %b1}"
12753 [(set_attr "type" "rotate1")
12754 (set_attr "mode" "QI")])
12756 (define_insn "*rotlqi3_1"
12757 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12758 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12759 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12760 (clobber (reg:CC FLAGS_REG))]
12761 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12763 rol{b}\t{%2, %0|%0, %2}
12764 rol{b}\t{%b2, %0|%0, %b2}"
12765 [(set_attr "type" "rotate")
12766 (set_attr "mode" "QI")])
12768 (define_expand "rotrdi3"
12769 [(set (match_operand:DI 0 "shiftdi_operand" "")
12770 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12771 (match_operand:QI 2 "nonmemory_operand" "")))
12772 (clobber (reg:CC FLAGS_REG))]
12777 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12780 if (!const_1_to_31_operand (operands[2], VOIDmode))
12782 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12786 ;; Implement rotation using two double-precision shift instructions
12787 ;; and a scratch register.
12788 (define_insn_and_split "ix86_rotrdi3"
12789 [(set (match_operand:DI 0 "register_operand" "=r")
12790 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12791 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12792 (clobber (reg:CC FLAGS_REG))
12793 (clobber (match_scratch:SI 3 "=&r"))]
12796 "&& reload_completed"
12797 [(set (match_dup 3) (match_dup 4))
12799 [(set (match_dup 4)
12800 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12801 (ashift:SI (match_dup 5)
12802 (minus:QI (const_int 32) (match_dup 2)))))
12803 (clobber (reg:CC FLAGS_REG))])
12805 [(set (match_dup 5)
12806 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12807 (ashift:SI (match_dup 3)
12808 (minus:QI (const_int 32) (match_dup 2)))))
12809 (clobber (reg:CC FLAGS_REG))])]
12810 "split_di (operands, 1, operands + 4, operands + 5);")
12812 (define_insn "*rotrdi3_1_one_bit_rex64"
12813 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12814 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12815 (match_operand:QI 2 "const1_operand" "")))
12816 (clobber (reg:CC FLAGS_REG))]
12817 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12818 && (TARGET_SHIFT1 || optimize_size)"
12820 [(set_attr "type" "rotate")
12821 (set (attr "length")
12822 (if_then_else (match_operand:DI 0 "register_operand" "")
12824 (const_string "*")))])
12826 (define_insn "*rotrdi3_1_rex64"
12827 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12828 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12829 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12830 (clobber (reg:CC FLAGS_REG))]
12831 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12833 ror{q}\t{%2, %0|%0, %2}
12834 ror{q}\t{%b2, %0|%0, %b2}"
12835 [(set_attr "type" "rotate")
12836 (set_attr "mode" "DI")])
12838 (define_expand "rotrsi3"
12839 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12840 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12841 (match_operand:QI 2 "nonmemory_operand" "")))
12842 (clobber (reg:CC FLAGS_REG))]
12844 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12846 (define_insn "*rotrsi3_1_one_bit"
12847 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12848 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12849 (match_operand:QI 2 "const1_operand" "")))
12850 (clobber (reg:CC FLAGS_REG))]
12851 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12852 && (TARGET_SHIFT1 || optimize_size)"
12854 [(set_attr "type" "rotate")
12855 (set (attr "length")
12856 (if_then_else (match_operand:SI 0 "register_operand" "")
12858 (const_string "*")))])
12860 (define_insn "*rotrsi3_1_one_bit_zext"
12861 [(set (match_operand:DI 0 "register_operand" "=r")
12863 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12864 (match_operand:QI 2 "const1_operand" ""))))
12865 (clobber (reg:CC FLAGS_REG))]
12866 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12867 && (TARGET_SHIFT1 || optimize_size)"
12869 [(set_attr "type" "rotate")
12870 (set (attr "length")
12871 (if_then_else (match_operand:SI 0 "register_operand" "")
12873 (const_string "*")))])
12875 (define_insn "*rotrsi3_1"
12876 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12877 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12878 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12879 (clobber (reg:CC FLAGS_REG))]
12880 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12882 ror{l}\t{%2, %0|%0, %2}
12883 ror{l}\t{%b2, %0|%0, %b2}"
12884 [(set_attr "type" "rotate")
12885 (set_attr "mode" "SI")])
12887 (define_insn "*rotrsi3_1_zext"
12888 [(set (match_operand:DI 0 "register_operand" "=r,r")
12890 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12891 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12892 (clobber (reg:CC FLAGS_REG))]
12893 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12895 ror{l}\t{%2, %k0|%k0, %2}
12896 ror{l}\t{%b2, %k0|%k0, %b2}"
12897 [(set_attr "type" "rotate")
12898 (set_attr "mode" "SI")])
12900 (define_expand "rotrhi3"
12901 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12902 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12903 (match_operand:QI 2 "nonmemory_operand" "")))
12904 (clobber (reg:CC FLAGS_REG))]
12905 "TARGET_HIMODE_MATH"
12906 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12908 (define_insn "*rotrhi3_one_bit"
12909 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12910 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12911 (match_operand:QI 2 "const1_operand" "")))
12912 (clobber (reg:CC FLAGS_REG))]
12913 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12914 && (TARGET_SHIFT1 || optimize_size)"
12916 [(set_attr "type" "rotate")
12917 (set (attr "length")
12918 (if_then_else (match_operand 0 "register_operand" "")
12920 (const_string "*")))])
12922 (define_insn "*rotrhi3"
12923 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12924 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12925 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12926 (clobber (reg:CC FLAGS_REG))]
12927 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12929 ror{w}\t{%2, %0|%0, %2}
12930 ror{w}\t{%b2, %0|%0, %b2}"
12931 [(set_attr "type" "rotate")
12932 (set_attr "mode" "HI")])
12934 (define_expand "rotrqi3"
12935 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12936 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12937 (match_operand:QI 2 "nonmemory_operand" "")))
12938 (clobber (reg:CC FLAGS_REG))]
12939 "TARGET_QIMODE_MATH"
12940 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12942 (define_insn "*rotrqi3_1_one_bit"
12943 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12944 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12945 (match_operand:QI 2 "const1_operand" "")))
12946 (clobber (reg:CC FLAGS_REG))]
12947 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12948 && (TARGET_SHIFT1 || optimize_size)"
12950 [(set_attr "type" "rotate")
12951 (set (attr "length")
12952 (if_then_else (match_operand 0 "register_operand" "")
12954 (const_string "*")))])
12956 (define_insn "*rotrqi3_1_one_bit_slp"
12957 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12958 (rotatert:QI (match_dup 0)
12959 (match_operand:QI 1 "const1_operand" "")))
12960 (clobber (reg:CC FLAGS_REG))]
12961 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12962 && (TARGET_SHIFT1 || optimize_size)"
12964 [(set_attr "type" "rotate1")
12965 (set (attr "length")
12966 (if_then_else (match_operand 0 "register_operand" "")
12968 (const_string "*")))])
12970 (define_insn "*rotrqi3_1"
12971 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12972 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12973 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12974 (clobber (reg:CC FLAGS_REG))]
12975 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12977 ror{b}\t{%2, %0|%0, %2}
12978 ror{b}\t{%b2, %0|%0, %b2}"
12979 [(set_attr "type" "rotate")
12980 (set_attr "mode" "QI")])
12982 (define_insn "*rotrqi3_1_slp"
12983 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12984 (rotatert:QI (match_dup 0)
12985 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12986 (clobber (reg:CC FLAGS_REG))]
12987 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12988 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12990 ror{b}\t{%1, %0|%0, %1}
12991 ror{b}\t{%b1, %0|%0, %b1}"
12992 [(set_attr "type" "rotate1")
12993 (set_attr "mode" "QI")])
12995 ;; Bit set / bit test instructions
12997 (define_expand "extv"
12998 [(set (match_operand:SI 0 "register_operand" "")
12999 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13000 (match_operand:SI 2 "const8_operand" "")
13001 (match_operand:SI 3 "const8_operand" "")))]
13004 /* Handle extractions from %ah et al. */
13005 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13008 /* From mips.md: extract_bit_field doesn't verify that our source
13009 matches the predicate, so check it again here. */
13010 if (! ext_register_operand (operands[1], VOIDmode))
13014 (define_expand "extzv"
13015 [(set (match_operand:SI 0 "register_operand" "")
13016 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13017 (match_operand:SI 2 "const8_operand" "")
13018 (match_operand:SI 3 "const8_operand" "")))]
13021 /* Handle extractions from %ah et al. */
13022 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13025 /* From mips.md: extract_bit_field doesn't verify that our source
13026 matches the predicate, so check it again here. */
13027 if (! ext_register_operand (operands[1], VOIDmode))
13031 (define_expand "insv"
13032 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13033 (match_operand 1 "const8_operand" "")
13034 (match_operand 2 "const8_operand" ""))
13035 (match_operand 3 "register_operand" ""))]
13038 /* Handle insertions to %ah et al. */
13039 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13042 /* From mips.md: insert_bit_field doesn't verify that our source
13043 matches the predicate, so check it again here. */
13044 if (! ext_register_operand (operands[0], VOIDmode))
13048 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13050 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13055 ;; %%% bts, btr, btc, bt.
13056 ;; In general these instructions are *slow* when applied to memory,
13057 ;; since they enforce atomic operation. When applied to registers,
13058 ;; it depends on the cpu implementation. They're never faster than
13059 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13060 ;; no point. But in 64-bit, we can't hold the relevant immediates
13061 ;; within the instruction itself, so operating on bits in the high
13062 ;; 32-bits of a register becomes easier.
13064 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13065 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13066 ;; negdf respectively, so they can never be disabled entirely.
13068 (define_insn "*btsq"
13069 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13071 (match_operand:DI 1 "const_0_to_63_operand" ""))
13073 (clobber (reg:CC FLAGS_REG))]
13074 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13076 [(set_attr "type" "alu1")])
13078 (define_insn "*btrq"
13079 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13081 (match_operand:DI 1 "const_0_to_63_operand" ""))
13083 (clobber (reg:CC FLAGS_REG))]
13084 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13086 [(set_attr "type" "alu1")])
13088 (define_insn "*btcq"
13089 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13091 (match_operand:DI 1 "const_0_to_63_operand" ""))
13092 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13093 (clobber (reg:CC FLAGS_REG))]
13094 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13096 [(set_attr "type" "alu1")])
13098 ;; Allow Nocona to avoid these instructions if a register is available.
13101 [(match_scratch:DI 2 "r")
13102 (parallel [(set (zero_extract:DI
13103 (match_operand:DI 0 "register_operand" "")
13105 (match_operand:DI 1 "const_0_to_63_operand" ""))
13107 (clobber (reg:CC FLAGS_REG))])]
13108 "TARGET_64BIT && !TARGET_USE_BT"
13111 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13114 if (HOST_BITS_PER_WIDE_INT >= 64)
13115 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13116 else if (i < HOST_BITS_PER_WIDE_INT)
13117 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13119 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13121 op1 = immed_double_const (lo, hi, DImode);
13124 emit_move_insn (operands[2], op1);
13128 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13133 [(match_scratch:DI 2 "r")
13134 (parallel [(set (zero_extract:DI
13135 (match_operand:DI 0 "register_operand" "")
13137 (match_operand:DI 1 "const_0_to_63_operand" ""))
13139 (clobber (reg:CC FLAGS_REG))])]
13140 "TARGET_64BIT && !TARGET_USE_BT"
13143 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13146 if (HOST_BITS_PER_WIDE_INT >= 64)
13147 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13148 else if (i < HOST_BITS_PER_WIDE_INT)
13149 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13151 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13153 op1 = immed_double_const (~lo, ~hi, DImode);
13156 emit_move_insn (operands[2], op1);
13160 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13165 [(match_scratch:DI 2 "r")
13166 (parallel [(set (zero_extract:DI
13167 (match_operand:DI 0 "register_operand" "")
13169 (match_operand:DI 1 "const_0_to_63_operand" ""))
13170 (not:DI (zero_extract:DI
13171 (match_dup 0) (const_int 1) (match_dup 1))))
13172 (clobber (reg:CC FLAGS_REG))])]
13173 "TARGET_64BIT && !TARGET_USE_BT"
13176 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13179 if (HOST_BITS_PER_WIDE_INT >= 64)
13180 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13181 else if (i < HOST_BITS_PER_WIDE_INT)
13182 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13184 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13186 op1 = immed_double_const (lo, hi, DImode);
13189 emit_move_insn (operands[2], op1);
13193 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13197 ;; Store-flag instructions.
13199 ;; For all sCOND expanders, also expand the compare or test insn that
13200 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13202 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13203 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13204 ;; way, which can later delete the movzx if only QImode is needed.
13206 (define_expand "seq"
13207 [(set (match_operand:QI 0 "register_operand" "")
13208 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13210 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13212 (define_expand "sne"
13213 [(set (match_operand:QI 0 "register_operand" "")
13214 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13216 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13218 (define_expand "sgt"
13219 [(set (match_operand:QI 0 "register_operand" "")
13220 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13222 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13224 (define_expand "sgtu"
13225 [(set (match_operand:QI 0 "register_operand" "")
13226 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13228 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13230 (define_expand "slt"
13231 [(set (match_operand:QI 0 "register_operand" "")
13232 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13234 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13236 (define_expand "sltu"
13237 [(set (match_operand:QI 0 "register_operand" "")
13238 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13240 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13242 (define_expand "sge"
13243 [(set (match_operand:QI 0 "register_operand" "")
13244 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13246 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13248 (define_expand "sgeu"
13249 [(set (match_operand:QI 0 "register_operand" "")
13250 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13252 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13254 (define_expand "sle"
13255 [(set (match_operand:QI 0 "register_operand" "")
13256 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13258 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13260 (define_expand "sleu"
13261 [(set (match_operand:QI 0 "register_operand" "")
13262 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13264 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13266 (define_expand "sunordered"
13267 [(set (match_operand:QI 0 "register_operand" "")
13268 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13269 "TARGET_80387 || TARGET_SSE"
13270 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13272 (define_expand "sordered"
13273 [(set (match_operand:QI 0 "register_operand" "")
13274 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13276 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13278 (define_expand "suneq"
13279 [(set (match_operand:QI 0 "register_operand" "")
13280 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13281 "TARGET_80387 || TARGET_SSE"
13282 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13284 (define_expand "sunge"
13285 [(set (match_operand:QI 0 "register_operand" "")
13286 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13287 "TARGET_80387 || TARGET_SSE"
13288 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13290 (define_expand "sungt"
13291 [(set (match_operand:QI 0 "register_operand" "")
13292 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13293 "TARGET_80387 || TARGET_SSE"
13294 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13296 (define_expand "sunle"
13297 [(set (match_operand:QI 0 "register_operand" "")
13298 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13299 "TARGET_80387 || TARGET_SSE"
13300 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13302 (define_expand "sunlt"
13303 [(set (match_operand:QI 0 "register_operand" "")
13304 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13305 "TARGET_80387 || TARGET_SSE"
13306 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13308 (define_expand "sltgt"
13309 [(set (match_operand:QI 0 "register_operand" "")
13310 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13311 "TARGET_80387 || TARGET_SSE"
13312 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13314 (define_insn "*setcc_1"
13315 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13316 (match_operator:QI 1 "ix86_comparison_operator"
13317 [(reg FLAGS_REG) (const_int 0)]))]
13320 [(set_attr "type" "setcc")
13321 (set_attr "mode" "QI")])
13323 (define_insn "*setcc_2"
13324 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13325 (match_operator:QI 1 "ix86_comparison_operator"
13326 [(reg FLAGS_REG) (const_int 0)]))]
13329 [(set_attr "type" "setcc")
13330 (set_attr "mode" "QI")])
13332 ;; In general it is not safe to assume too much about CCmode registers,
13333 ;; so simplify-rtx stops when it sees a second one. Under certain
13334 ;; conditions this is safe on x86, so help combine not create
13341 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13342 (ne:QI (match_operator 1 "ix86_comparison_operator"
13343 [(reg FLAGS_REG) (const_int 0)])
13346 [(set (match_dup 0) (match_dup 1))]
13348 PUT_MODE (operands[1], QImode);
13352 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13353 (ne:QI (match_operator 1 "ix86_comparison_operator"
13354 [(reg FLAGS_REG) (const_int 0)])
13357 [(set (match_dup 0) (match_dup 1))]
13359 PUT_MODE (operands[1], QImode);
13363 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13364 (eq:QI (match_operator 1 "ix86_comparison_operator"
13365 [(reg FLAGS_REG) (const_int 0)])
13368 [(set (match_dup 0) (match_dup 1))]
13370 rtx new_op1 = copy_rtx (operands[1]);
13371 operands[1] = new_op1;
13372 PUT_MODE (new_op1, QImode);
13373 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13374 GET_MODE (XEXP (new_op1, 0))));
13376 /* Make sure that (a) the CCmode we have for the flags is strong
13377 enough for the reversed compare or (b) we have a valid FP compare. */
13378 if (! ix86_comparison_operator (new_op1, VOIDmode))
13383 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13384 (eq:QI (match_operator 1 "ix86_comparison_operator"
13385 [(reg FLAGS_REG) (const_int 0)])
13388 [(set (match_dup 0) (match_dup 1))]
13390 rtx new_op1 = copy_rtx (operands[1]);
13391 operands[1] = new_op1;
13392 PUT_MODE (new_op1, QImode);
13393 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13394 GET_MODE (XEXP (new_op1, 0))));
13396 /* Make sure that (a) the CCmode we have for the flags is strong
13397 enough for the reversed compare or (b) we have a valid FP compare. */
13398 if (! ix86_comparison_operator (new_op1, VOIDmode))
13402 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13403 ;; subsequent logical operations are used to imitate conditional moves.
13404 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13407 (define_insn "*sse_setccsf"
13408 [(set (match_operand:SF 0 "register_operand" "=x")
13409 (match_operator:SF 1 "sse_comparison_operator"
13410 [(match_operand:SF 2 "register_operand" "0")
13411 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13413 "cmp%D1ss\t{%3, %0|%0, %3}"
13414 [(set_attr "type" "ssecmp")
13415 (set_attr "mode" "SF")])
13417 (define_insn "*sse_setccdf"
13418 [(set (match_operand:DF 0 "register_operand" "=Y")
13419 (match_operator:DF 1 "sse_comparison_operator"
13420 [(match_operand:DF 2 "register_operand" "0")
13421 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13423 "cmp%D1sd\t{%3, %0|%0, %3}"
13424 [(set_attr "type" "ssecmp")
13425 (set_attr "mode" "DF")])
13427 ;; Basic conditional jump instructions.
13428 ;; We ignore the overflow flag for signed branch instructions.
13430 ;; For all bCOND expanders, also expand the compare or test insn that
13431 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13433 (define_expand "beq"
13435 (if_then_else (match_dup 1)
13436 (label_ref (match_operand 0 "" ""))
13439 "ix86_expand_branch (EQ, operands[0]); DONE;")
13441 (define_expand "bne"
13443 (if_then_else (match_dup 1)
13444 (label_ref (match_operand 0 "" ""))
13447 "ix86_expand_branch (NE, operands[0]); DONE;")
13449 (define_expand "bgt"
13451 (if_then_else (match_dup 1)
13452 (label_ref (match_operand 0 "" ""))
13455 "ix86_expand_branch (GT, operands[0]); DONE;")
13457 (define_expand "bgtu"
13459 (if_then_else (match_dup 1)
13460 (label_ref (match_operand 0 "" ""))
13463 "ix86_expand_branch (GTU, operands[0]); DONE;")
13465 (define_expand "blt"
13467 (if_then_else (match_dup 1)
13468 (label_ref (match_operand 0 "" ""))
13471 "ix86_expand_branch (LT, operands[0]); DONE;")
13473 (define_expand "bltu"
13475 (if_then_else (match_dup 1)
13476 (label_ref (match_operand 0 "" ""))
13479 "ix86_expand_branch (LTU, operands[0]); DONE;")
13481 (define_expand "bge"
13483 (if_then_else (match_dup 1)
13484 (label_ref (match_operand 0 "" ""))
13487 "ix86_expand_branch (GE, operands[0]); DONE;")
13489 (define_expand "bgeu"
13491 (if_then_else (match_dup 1)
13492 (label_ref (match_operand 0 "" ""))
13495 "ix86_expand_branch (GEU, operands[0]); DONE;")
13497 (define_expand "ble"
13499 (if_then_else (match_dup 1)
13500 (label_ref (match_operand 0 "" ""))
13503 "ix86_expand_branch (LE, operands[0]); DONE;")
13505 (define_expand "bleu"
13507 (if_then_else (match_dup 1)
13508 (label_ref (match_operand 0 "" ""))
13511 "ix86_expand_branch (LEU, operands[0]); DONE;")
13513 (define_expand "bunordered"
13515 (if_then_else (match_dup 1)
13516 (label_ref (match_operand 0 "" ""))
13518 "TARGET_80387 || TARGET_SSE_MATH"
13519 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13521 (define_expand "bordered"
13523 (if_then_else (match_dup 1)
13524 (label_ref (match_operand 0 "" ""))
13526 "TARGET_80387 || TARGET_SSE_MATH"
13527 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13529 (define_expand "buneq"
13531 (if_then_else (match_dup 1)
13532 (label_ref (match_operand 0 "" ""))
13534 "TARGET_80387 || TARGET_SSE_MATH"
13535 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13537 (define_expand "bunge"
13539 (if_then_else (match_dup 1)
13540 (label_ref (match_operand 0 "" ""))
13542 "TARGET_80387 || TARGET_SSE_MATH"
13543 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13545 (define_expand "bungt"
13547 (if_then_else (match_dup 1)
13548 (label_ref (match_operand 0 "" ""))
13550 "TARGET_80387 || TARGET_SSE_MATH"
13551 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13553 (define_expand "bunle"
13555 (if_then_else (match_dup 1)
13556 (label_ref (match_operand 0 "" ""))
13558 "TARGET_80387 || TARGET_SSE_MATH"
13559 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13561 (define_expand "bunlt"
13563 (if_then_else (match_dup 1)
13564 (label_ref (match_operand 0 "" ""))
13566 "TARGET_80387 || TARGET_SSE_MATH"
13567 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13569 (define_expand "bltgt"
13571 (if_then_else (match_dup 1)
13572 (label_ref (match_operand 0 "" ""))
13574 "TARGET_80387 || TARGET_SSE_MATH"
13575 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13577 (define_insn "*jcc_1"
13579 (if_then_else (match_operator 1 "ix86_comparison_operator"
13580 [(reg FLAGS_REG) (const_int 0)])
13581 (label_ref (match_operand 0 "" ""))
13585 [(set_attr "type" "ibr")
13586 (set_attr "modrm" "0")
13587 (set (attr "length")
13588 (if_then_else (and (ge (minus (match_dup 0) (pc))
13590 (lt (minus (match_dup 0) (pc))
13595 (define_insn "*jcc_2"
13597 (if_then_else (match_operator 1 "ix86_comparison_operator"
13598 [(reg FLAGS_REG) (const_int 0)])
13600 (label_ref (match_operand 0 "" ""))))]
13603 [(set_attr "type" "ibr")
13604 (set_attr "modrm" "0")
13605 (set (attr "length")
13606 (if_then_else (and (ge (minus (match_dup 0) (pc))
13608 (lt (minus (match_dup 0) (pc))
13613 ;; In general it is not safe to assume too much about CCmode registers,
13614 ;; so simplify-rtx stops when it sees a second one. Under certain
13615 ;; conditions this is safe on x86, so help combine not create
13623 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13624 [(reg FLAGS_REG) (const_int 0)])
13626 (label_ref (match_operand 1 "" ""))
13630 (if_then_else (match_dup 0)
13631 (label_ref (match_dup 1))
13634 PUT_MODE (operands[0], VOIDmode);
13639 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13640 [(reg FLAGS_REG) (const_int 0)])
13642 (label_ref (match_operand 1 "" ""))
13646 (if_then_else (match_dup 0)
13647 (label_ref (match_dup 1))
13650 rtx new_op0 = copy_rtx (operands[0]);
13651 operands[0] = new_op0;
13652 PUT_MODE (new_op0, VOIDmode);
13653 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13654 GET_MODE (XEXP (new_op0, 0))));
13656 /* Make sure that (a) the CCmode we have for the flags is strong
13657 enough for the reversed compare or (b) we have a valid FP compare. */
13658 if (! ix86_comparison_operator (new_op0, VOIDmode))
13662 ;; Define combination compare-and-branch fp compare instructions to use
13663 ;; during early optimization. Splitting the operation apart early makes
13664 ;; for bad code when we want to reverse the operation.
13666 (define_insn "*fp_jcc_1_mixed"
13668 (if_then_else (match_operator 0 "comparison_operator"
13669 [(match_operand 1 "register_operand" "f,x")
13670 (match_operand 2 "nonimmediate_operand" "f,xm")])
13671 (label_ref (match_operand 3 "" ""))
13673 (clobber (reg:CCFP FPSR_REG))
13674 (clobber (reg:CCFP FLAGS_REG))]
13675 "TARGET_MIX_SSE_I387
13676 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13677 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13678 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13681 (define_insn "*fp_jcc_1_sse"
13683 (if_then_else (match_operator 0 "comparison_operator"
13684 [(match_operand 1 "register_operand" "x")
13685 (match_operand 2 "nonimmediate_operand" "xm")])
13686 (label_ref (match_operand 3 "" ""))
13688 (clobber (reg:CCFP FPSR_REG))
13689 (clobber (reg:CCFP FLAGS_REG))]
13691 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13692 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13693 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13696 (define_insn "*fp_jcc_1_387"
13698 (if_then_else (match_operator 0 "comparison_operator"
13699 [(match_operand 1 "register_operand" "f")
13700 (match_operand 2 "register_operand" "f")])
13701 (label_ref (match_operand 3 "" ""))
13703 (clobber (reg:CCFP FPSR_REG))
13704 (clobber (reg:CCFP FLAGS_REG))]
13705 "TARGET_CMOVE && TARGET_80387
13706 && FLOAT_MODE_P (GET_MODE (operands[1]))
13707 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13708 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13711 (define_insn "*fp_jcc_2_mixed"
13713 (if_then_else (match_operator 0 "comparison_operator"
13714 [(match_operand 1 "register_operand" "f,x")
13715 (match_operand 2 "nonimmediate_operand" "f,xm")])
13717 (label_ref (match_operand 3 "" ""))))
13718 (clobber (reg:CCFP FPSR_REG))
13719 (clobber (reg:CCFP FLAGS_REG))]
13720 "TARGET_MIX_SSE_I387
13721 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13722 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13723 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13726 (define_insn "*fp_jcc_2_sse"
13728 (if_then_else (match_operator 0 "comparison_operator"
13729 [(match_operand 1 "register_operand" "x")
13730 (match_operand 2 "nonimmediate_operand" "xm")])
13732 (label_ref (match_operand 3 "" ""))))
13733 (clobber (reg:CCFP FPSR_REG))
13734 (clobber (reg:CCFP FLAGS_REG))]
13736 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13737 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13738 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13741 (define_insn "*fp_jcc_2_387"
13743 (if_then_else (match_operator 0 "comparison_operator"
13744 [(match_operand 1 "register_operand" "f")
13745 (match_operand 2 "register_operand" "f")])
13747 (label_ref (match_operand 3 "" ""))))
13748 (clobber (reg:CCFP FPSR_REG))
13749 (clobber (reg:CCFP FLAGS_REG))]
13750 "TARGET_CMOVE && TARGET_80387
13751 && FLOAT_MODE_P (GET_MODE (operands[1]))
13752 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13753 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13756 (define_insn "*fp_jcc_3_387"
13758 (if_then_else (match_operator 0 "comparison_operator"
13759 [(match_operand 1 "register_operand" "f")
13760 (match_operand 2 "nonimmediate_operand" "fm")])
13761 (label_ref (match_operand 3 "" ""))
13763 (clobber (reg:CCFP FPSR_REG))
13764 (clobber (reg:CCFP FLAGS_REG))
13765 (clobber (match_scratch:HI 4 "=a"))]
13767 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13768 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13769 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13770 && SELECT_CC_MODE (GET_CODE (operands[0]),
13771 operands[1], operands[2]) == CCFPmode
13772 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13775 (define_insn "*fp_jcc_4_387"
13777 (if_then_else (match_operator 0 "comparison_operator"
13778 [(match_operand 1 "register_operand" "f")
13779 (match_operand 2 "nonimmediate_operand" "fm")])
13781 (label_ref (match_operand 3 "" ""))))
13782 (clobber (reg:CCFP FPSR_REG))
13783 (clobber (reg:CCFP FLAGS_REG))
13784 (clobber (match_scratch:HI 4 "=a"))]
13786 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13787 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13788 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13789 && SELECT_CC_MODE (GET_CODE (operands[0]),
13790 operands[1], operands[2]) == CCFPmode
13791 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13794 (define_insn "*fp_jcc_5_387"
13796 (if_then_else (match_operator 0 "comparison_operator"
13797 [(match_operand 1 "register_operand" "f")
13798 (match_operand 2 "register_operand" "f")])
13799 (label_ref (match_operand 3 "" ""))
13801 (clobber (reg:CCFP FPSR_REG))
13802 (clobber (reg:CCFP FLAGS_REG))
13803 (clobber (match_scratch:HI 4 "=a"))]
13805 && FLOAT_MODE_P (GET_MODE (operands[1]))
13806 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13807 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13810 (define_insn "*fp_jcc_6_387"
13812 (if_then_else (match_operator 0 "comparison_operator"
13813 [(match_operand 1 "register_operand" "f")
13814 (match_operand 2 "register_operand" "f")])
13816 (label_ref (match_operand 3 "" ""))))
13817 (clobber (reg:CCFP FPSR_REG))
13818 (clobber (reg:CCFP FLAGS_REG))
13819 (clobber (match_scratch:HI 4 "=a"))]
13821 && FLOAT_MODE_P (GET_MODE (operands[1]))
13822 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13823 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13826 (define_insn "*fp_jcc_7_387"
13828 (if_then_else (match_operator 0 "comparison_operator"
13829 [(match_operand 1 "register_operand" "f")
13830 (match_operand 2 "const0_operand" "X")])
13831 (label_ref (match_operand 3 "" ""))
13833 (clobber (reg:CCFP FPSR_REG))
13834 (clobber (reg:CCFP FLAGS_REG))
13835 (clobber (match_scratch:HI 4 "=a"))]
13837 && FLOAT_MODE_P (GET_MODE (operands[1]))
13838 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13839 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13840 && SELECT_CC_MODE (GET_CODE (operands[0]),
13841 operands[1], operands[2]) == CCFPmode
13842 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13845 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13846 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13847 ;; with a precedence over other operators and is always put in the first
13848 ;; place. Swap condition and operands to match ficom instruction.
13850 (define_insn "*fp_jcc_8<mode>_387"
13852 (if_then_else (match_operator 0 "comparison_operator"
13853 [(match_operator 1 "float_operator"
13854 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13855 (match_operand 3 "register_operand" "f,f")])
13856 (label_ref (match_operand 4 "" ""))
13858 (clobber (reg:CCFP FPSR_REG))
13859 (clobber (reg:CCFP FLAGS_REG))
13860 (clobber (match_scratch:HI 5 "=a,a"))]
13861 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13862 && FLOAT_MODE_P (GET_MODE (operands[3]))
13863 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13864 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13865 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13866 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13871 (if_then_else (match_operator 0 "comparison_operator"
13872 [(match_operand 1 "register_operand" "")
13873 (match_operand 2 "nonimmediate_operand" "")])
13874 (match_operand 3 "" "")
13875 (match_operand 4 "" "")))
13876 (clobber (reg:CCFP FPSR_REG))
13877 (clobber (reg:CCFP FLAGS_REG))]
13881 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13882 operands[3], operands[4], NULL_RTX, NULL_RTX);
13888 (if_then_else (match_operator 0 "comparison_operator"
13889 [(match_operand 1 "register_operand" "")
13890 (match_operand 2 "general_operand" "")])
13891 (match_operand 3 "" "")
13892 (match_operand 4 "" "")))
13893 (clobber (reg:CCFP FPSR_REG))
13894 (clobber (reg:CCFP FLAGS_REG))
13895 (clobber (match_scratch:HI 5 "=a"))]
13899 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13900 operands[3], operands[4], operands[5], NULL_RTX);
13906 (if_then_else (match_operator 0 "comparison_operator"
13907 [(match_operator 1 "float_operator"
13908 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13909 (match_operand 3 "register_operand" "")])
13910 (match_operand 4 "" "")
13911 (match_operand 5 "" "")))
13912 (clobber (reg:CCFP FPSR_REG))
13913 (clobber (reg:CCFP FLAGS_REG))
13914 (clobber (match_scratch:HI 6 "=a"))]
13918 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13919 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13920 operands[3], operands[7],
13921 operands[4], operands[5], operands[6], NULL_RTX);
13925 ;; %%% Kill this when reload knows how to do it.
13928 (if_then_else (match_operator 0 "comparison_operator"
13929 [(match_operator 1 "float_operator"
13930 [(match_operand:X87MODEI12 2 "register_operand" "")])
13931 (match_operand 3 "register_operand" "")])
13932 (match_operand 4 "" "")
13933 (match_operand 5 "" "")))
13934 (clobber (reg:CCFP FPSR_REG))
13935 (clobber (reg:CCFP FLAGS_REG))
13936 (clobber (match_scratch:HI 6 "=a"))]
13940 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13941 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13942 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13943 operands[3], operands[7],
13944 operands[4], operands[5], operands[6], operands[2]);
13948 ;; Unconditional and other jump instructions
13950 (define_insn "jump"
13952 (label_ref (match_operand 0 "" "")))]
13955 [(set_attr "type" "ibr")
13956 (set (attr "length")
13957 (if_then_else (and (ge (minus (match_dup 0) (pc))
13959 (lt (minus (match_dup 0) (pc))
13963 (set_attr "modrm" "0")])
13965 (define_expand "indirect_jump"
13966 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13970 (define_insn "*indirect_jump"
13971 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13974 [(set_attr "type" "ibr")
13975 (set_attr "length_immediate" "0")])
13977 (define_insn "*indirect_jump_rtx64"
13978 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13981 [(set_attr "type" "ibr")
13982 (set_attr "length_immediate" "0")])
13984 (define_expand "tablejump"
13985 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13986 (use (label_ref (match_operand 1 "" "")))])]
13989 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13990 relative. Convert the relative address to an absolute address. */
13994 enum rtx_code code;
14000 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14002 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14006 op1 = pic_offset_table_rtx;
14011 op0 = pic_offset_table_rtx;
14015 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14020 (define_insn "*tablejump_1"
14021 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14022 (use (label_ref (match_operand 1 "" "")))]
14025 [(set_attr "type" "ibr")
14026 (set_attr "length_immediate" "0")])
14028 (define_insn "*tablejump_1_rtx64"
14029 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14030 (use (label_ref (match_operand 1 "" "")))]
14033 [(set_attr "type" "ibr")
14034 (set_attr "length_immediate" "0")])
14036 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14039 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14040 (set (match_operand:QI 1 "register_operand" "")
14041 (match_operator:QI 2 "ix86_comparison_operator"
14042 [(reg FLAGS_REG) (const_int 0)]))
14043 (set (match_operand 3 "q_regs_operand" "")
14044 (zero_extend (match_dup 1)))]
14045 "(peep2_reg_dead_p (3, operands[1])
14046 || operands_match_p (operands[1], operands[3]))
14047 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14048 [(set (match_dup 4) (match_dup 0))
14049 (set (strict_low_part (match_dup 5))
14052 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14053 operands[5] = gen_lowpart (QImode, operands[3]);
14054 ix86_expand_clear (operands[3]);
14057 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14060 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14061 (set (match_operand:QI 1 "register_operand" "")
14062 (match_operator:QI 2 "ix86_comparison_operator"
14063 [(reg FLAGS_REG) (const_int 0)]))
14064 (parallel [(set (match_operand 3 "q_regs_operand" "")
14065 (zero_extend (match_dup 1)))
14066 (clobber (reg:CC FLAGS_REG))])]
14067 "(peep2_reg_dead_p (3, operands[1])
14068 || operands_match_p (operands[1], operands[3]))
14069 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14070 [(set (match_dup 4) (match_dup 0))
14071 (set (strict_low_part (match_dup 5))
14074 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14075 operands[5] = gen_lowpart (QImode, operands[3]);
14076 ix86_expand_clear (operands[3]);
14079 ;; Call instructions.
14081 ;; The predicates normally associated with named expanders are not properly
14082 ;; checked for calls. This is a bug in the generic code, but it isn't that
14083 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14085 ;; Call subroutine returning no value.
14087 (define_expand "call_pop"
14088 [(parallel [(call (match_operand:QI 0 "" "")
14089 (match_operand:SI 1 "" ""))
14090 (set (reg:SI SP_REG)
14091 (plus:SI (reg:SI SP_REG)
14092 (match_operand:SI 3 "" "")))])]
14095 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14099 (define_insn "*call_pop_0"
14100 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14101 (match_operand:SI 1 "" ""))
14102 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14103 (match_operand:SI 2 "immediate_operand" "")))]
14106 if (SIBLING_CALL_P (insn))
14109 return "call\t%P0";
14111 [(set_attr "type" "call")])
14113 (define_insn "*call_pop_1"
14114 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14115 (match_operand:SI 1 "" ""))
14116 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14117 (match_operand:SI 2 "immediate_operand" "i")))]
14120 if (constant_call_address_operand (operands[0], Pmode))
14122 if (SIBLING_CALL_P (insn))
14125 return "call\t%P0";
14127 if (SIBLING_CALL_P (insn))
14130 return "call\t%A0";
14132 [(set_attr "type" "call")])
14134 (define_expand "call"
14135 [(call (match_operand:QI 0 "" "")
14136 (match_operand 1 "" ""))
14137 (use (match_operand 2 "" ""))]
14140 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14144 (define_expand "sibcall"
14145 [(call (match_operand:QI 0 "" "")
14146 (match_operand 1 "" ""))
14147 (use (match_operand 2 "" ""))]
14150 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14154 (define_insn "*call_0"
14155 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14156 (match_operand 1 "" ""))]
14159 if (SIBLING_CALL_P (insn))
14162 return "call\t%P0";
14164 [(set_attr "type" "call")])
14166 (define_insn "*call_1"
14167 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14168 (match_operand 1 "" ""))]
14169 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14171 if (constant_call_address_operand (operands[0], Pmode))
14172 return "call\t%P0";
14173 return "call\t%A0";
14175 [(set_attr "type" "call")])
14177 (define_insn "*sibcall_1"
14178 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14179 (match_operand 1 "" ""))]
14180 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14182 if (constant_call_address_operand (operands[0], Pmode))
14186 [(set_attr "type" "call")])
14188 (define_insn "*call_1_rex64"
14189 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14190 (match_operand 1 "" ""))]
14191 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14193 if (constant_call_address_operand (operands[0], Pmode))
14194 return "call\t%P0";
14195 return "call\t%A0";
14197 [(set_attr "type" "call")])
14199 (define_insn "*sibcall_1_rex64"
14200 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14201 (match_operand 1 "" ""))]
14202 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14204 [(set_attr "type" "call")])
14206 (define_insn "*sibcall_1_rex64_v"
14207 [(call (mem:QI (reg:DI R11_REG))
14208 (match_operand 0 "" ""))]
14209 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14211 [(set_attr "type" "call")])
14214 ;; Call subroutine, returning value in operand 0
14216 (define_expand "call_value_pop"
14217 [(parallel [(set (match_operand 0 "" "")
14218 (call (match_operand:QI 1 "" "")
14219 (match_operand:SI 2 "" "")))
14220 (set (reg:SI SP_REG)
14221 (plus:SI (reg:SI SP_REG)
14222 (match_operand:SI 4 "" "")))])]
14225 ix86_expand_call (operands[0], operands[1], operands[2],
14226 operands[3], operands[4], 0);
14230 (define_expand "call_value"
14231 [(set (match_operand 0 "" "")
14232 (call (match_operand:QI 1 "" "")
14233 (match_operand:SI 2 "" "")))
14234 (use (match_operand:SI 3 "" ""))]
14235 ;; Operand 2 not used on the i386.
14238 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14242 (define_expand "sibcall_value"
14243 [(set (match_operand 0 "" "")
14244 (call (match_operand:QI 1 "" "")
14245 (match_operand:SI 2 "" "")))
14246 (use (match_operand:SI 3 "" ""))]
14247 ;; Operand 2 not used on the i386.
14250 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14254 ;; Call subroutine returning any type.
14256 (define_expand "untyped_call"
14257 [(parallel [(call (match_operand 0 "" "")
14259 (match_operand 1 "" "")
14260 (match_operand 2 "" "")])]
14265 /* In order to give reg-stack an easier job in validating two
14266 coprocessor registers as containing a possible return value,
14267 simply pretend the untyped call returns a complex long double
14270 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14271 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14272 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14275 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14277 rtx set = XVECEXP (operands[2], 0, i);
14278 emit_move_insn (SET_DEST (set), SET_SRC (set));
14281 /* The optimizer does not know that the call sets the function value
14282 registers we stored in the result block. We avoid problems by
14283 claiming that all hard registers are used and clobbered at this
14285 emit_insn (gen_blockage (const0_rtx));
14290 ;; Prologue and epilogue instructions
14292 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14293 ;; all of memory. This blocks insns from being moved across this point.
14295 (define_insn "blockage"
14296 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14299 [(set_attr "length" "0")])
14301 ;; Insn emitted into the body of a function to return from a function.
14302 ;; This is only done if the function's epilogue is known to be simple.
14303 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14305 (define_expand "return"
14307 "ix86_can_use_return_insn_p ()"
14309 if (current_function_pops_args)
14311 rtx popc = GEN_INT (current_function_pops_args);
14312 emit_jump_insn (gen_return_pop_internal (popc));
14317 (define_insn "return_internal"
14321 [(set_attr "length" "1")
14322 (set_attr "length_immediate" "0")
14323 (set_attr "modrm" "0")])
14325 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14326 ;; instruction Athlon and K8 have.
14328 (define_insn "return_internal_long"
14330 (unspec [(const_int 0)] UNSPEC_REP)]
14333 [(set_attr "length" "1")
14334 (set_attr "length_immediate" "0")
14335 (set_attr "prefix_rep" "1")
14336 (set_attr "modrm" "0")])
14338 (define_insn "return_pop_internal"
14340 (use (match_operand:SI 0 "const_int_operand" ""))]
14343 [(set_attr "length" "3")
14344 (set_attr "length_immediate" "2")
14345 (set_attr "modrm" "0")])
14347 (define_insn "return_indirect_internal"
14349 (use (match_operand:SI 0 "register_operand" "r"))]
14352 [(set_attr "type" "ibr")
14353 (set_attr "length_immediate" "0")])
14359 [(set_attr "length" "1")
14360 (set_attr "length_immediate" "0")
14361 (set_attr "modrm" "0")])
14363 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14364 ;; branch prediction penalty for the third jump in a 16-byte
14367 (define_insn "align"
14368 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14371 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14372 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14374 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14375 The align insn is used to avoid 3 jump instructions in the row to improve
14376 branch prediction and the benefits hardly outweigh the cost of extra 8
14377 nops on the average inserted by full alignment pseudo operation. */
14381 [(set_attr "length" "16")])
14383 (define_expand "prologue"
14386 "ix86_expand_prologue (); DONE;")
14388 (define_insn "set_got"
14389 [(set (match_operand:SI 0 "register_operand" "=r")
14390 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14391 (clobber (reg:CC FLAGS_REG))]
14393 { return output_set_got (operands[0], NULL_RTX); }
14394 [(set_attr "type" "multi")
14395 (set_attr "length" "12")])
14397 (define_insn "set_got_labelled"
14398 [(set (match_operand:SI 0 "register_operand" "=r")
14399 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14401 (clobber (reg:CC FLAGS_REG))]
14403 { return output_set_got (operands[0], operands[1]); }
14404 [(set_attr "type" "multi")
14405 (set_attr "length" "12")])
14407 (define_insn "set_got_rex64"
14408 [(set (match_operand:DI 0 "register_operand" "=r")
14409 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14411 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14412 [(set_attr "type" "lea")
14413 (set_attr "length" "6")])
14415 (define_expand "epilogue"
14418 "ix86_expand_epilogue (1); DONE;")
14420 (define_expand "sibcall_epilogue"
14423 "ix86_expand_epilogue (0); DONE;")
14425 (define_expand "eh_return"
14426 [(use (match_operand 0 "register_operand" ""))]
14429 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14431 /* Tricky bit: we write the address of the handler to which we will
14432 be returning into someone else's stack frame, one word below the
14433 stack address we wish to restore. */
14434 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14435 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14436 tmp = gen_rtx_MEM (Pmode, tmp);
14437 emit_move_insn (tmp, ra);
14439 if (Pmode == SImode)
14440 emit_jump_insn (gen_eh_return_si (sa));
14442 emit_jump_insn (gen_eh_return_di (sa));
14447 (define_insn_and_split "eh_return_si"
14449 (unspec [(match_operand:SI 0 "register_operand" "c")]
14450 UNSPEC_EH_RETURN))]
14455 "ix86_expand_epilogue (2); DONE;")
14457 (define_insn_and_split "eh_return_di"
14459 (unspec [(match_operand:DI 0 "register_operand" "c")]
14460 UNSPEC_EH_RETURN))]
14465 "ix86_expand_epilogue (2); DONE;")
14467 (define_insn "leave"
14468 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14469 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14470 (clobber (mem:BLK (scratch)))]
14473 [(set_attr "type" "leave")])
14475 (define_insn "leave_rex64"
14476 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14477 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14478 (clobber (mem:BLK (scratch)))]
14481 [(set_attr "type" "leave")])
14483 (define_expand "ffssi2"
14485 [(set (match_operand:SI 0 "register_operand" "")
14486 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14487 (clobber (match_scratch:SI 2 ""))
14488 (clobber (reg:CC FLAGS_REG))])]
14492 (define_insn_and_split "*ffs_cmove"
14493 [(set (match_operand:SI 0 "register_operand" "=r")
14494 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14495 (clobber (match_scratch:SI 2 "=&r"))
14496 (clobber (reg:CC FLAGS_REG))]
14499 "&& reload_completed"
14500 [(set (match_dup 2) (const_int -1))
14501 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14502 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14503 (set (match_dup 0) (if_then_else:SI
14504 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14507 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14508 (clobber (reg:CC FLAGS_REG))])]
14511 (define_insn_and_split "*ffs_no_cmove"
14512 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14513 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14514 (clobber (match_scratch:SI 2 "=&q"))
14515 (clobber (reg:CC FLAGS_REG))]
14519 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14520 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14521 (set (strict_low_part (match_dup 3))
14522 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14523 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14524 (clobber (reg:CC FLAGS_REG))])
14525 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14526 (clobber (reg:CC FLAGS_REG))])
14527 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14528 (clobber (reg:CC FLAGS_REG))])]
14530 operands[3] = gen_lowpart (QImode, operands[2]);
14531 ix86_expand_clear (operands[2]);
14534 (define_insn "*ffssi_1"
14535 [(set (reg:CCZ FLAGS_REG)
14536 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14538 (set (match_operand:SI 0 "register_operand" "=r")
14539 (ctz:SI (match_dup 1)))]
14541 "bsf{l}\t{%1, %0|%0, %1}"
14542 [(set_attr "prefix_0f" "1")])
14544 (define_expand "ffsdi2"
14546 [(set (match_operand:DI 0 "register_operand" "")
14547 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14548 (clobber (match_scratch:DI 2 ""))
14549 (clobber (reg:CC FLAGS_REG))])]
14550 "TARGET_64BIT && TARGET_CMOVE"
14553 (define_insn_and_split "*ffs_rex64"
14554 [(set (match_operand:DI 0 "register_operand" "=r")
14555 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14556 (clobber (match_scratch:DI 2 "=&r"))
14557 (clobber (reg:CC FLAGS_REG))]
14558 "TARGET_64BIT && TARGET_CMOVE"
14560 "&& reload_completed"
14561 [(set (match_dup 2) (const_int -1))
14562 (parallel [(set (reg:CCZ FLAGS_REG)
14563 (compare:CCZ (match_dup 1) (const_int 0)))
14564 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14565 (set (match_dup 0) (if_then_else:DI
14566 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14569 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14570 (clobber (reg:CC FLAGS_REG))])]
14573 (define_insn "*ffsdi_1"
14574 [(set (reg:CCZ FLAGS_REG)
14575 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14577 (set (match_operand:DI 0 "register_operand" "=r")
14578 (ctz:DI (match_dup 1)))]
14580 "bsf{q}\t{%1, %0|%0, %1}"
14581 [(set_attr "prefix_0f" "1")])
14583 (define_insn "ctzsi2"
14584 [(set (match_operand:SI 0 "register_operand" "=r")
14585 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14586 (clobber (reg:CC FLAGS_REG))]
14588 "bsf{l}\t{%1, %0|%0, %1}"
14589 [(set_attr "prefix_0f" "1")])
14591 (define_insn "ctzdi2"
14592 [(set (match_operand:DI 0 "register_operand" "=r")
14593 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14594 (clobber (reg:CC FLAGS_REG))]
14596 "bsf{q}\t{%1, %0|%0, %1}"
14597 [(set_attr "prefix_0f" "1")])
14599 (define_expand "clzsi2"
14601 [(set (match_operand:SI 0 "register_operand" "")
14602 (minus:SI (const_int 31)
14603 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14604 (clobber (reg:CC FLAGS_REG))])
14606 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14607 (clobber (reg:CC FLAGS_REG))])]
14611 (define_insn "*bsr"
14612 [(set (match_operand:SI 0 "register_operand" "=r")
14613 (minus:SI (const_int 31)
14614 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14615 (clobber (reg:CC FLAGS_REG))]
14617 "bsr{l}\t{%1, %0|%0, %1}"
14618 [(set_attr "prefix_0f" "1")])
14620 (define_insn "bswapsi2"
14621 [(set (match_operand:SI 0 "register_operand" "=r")
14622 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14623 (clobber (reg:CC FLAGS_REG))]
14626 [(set_attr "prefix_0f" "1")
14627 (set_attr "length" "2")])
14629 (define_insn "bswapdi2"
14630 [(set (match_operand:DI 0 "register_operand" "=r")
14631 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14632 (clobber (reg:CC FLAGS_REG))]
14633 "TARGET_64BIT && TARGET_BSWAP"
14635 [(set_attr "prefix_0f" "1")
14636 (set_attr "length" "3")])
14638 (define_expand "clzdi2"
14640 [(set (match_operand:DI 0 "register_operand" "")
14641 (minus:DI (const_int 63)
14642 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14643 (clobber (reg:CC FLAGS_REG))])
14645 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14646 (clobber (reg:CC FLAGS_REG))])]
14650 (define_insn "*bsr_rex64"
14651 [(set (match_operand:DI 0 "register_operand" "=r")
14652 (minus:DI (const_int 63)
14653 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14654 (clobber (reg:CC FLAGS_REG))]
14656 "bsr{q}\t{%1, %0|%0, %1}"
14657 [(set_attr "prefix_0f" "1")])
14659 ;; Thread-local storage patterns for ELF.
14661 ;; Note that these code sequences must appear exactly as shown
14662 ;; in order to allow linker relaxation.
14664 (define_insn "*tls_global_dynamic_32_gnu"
14665 [(set (match_operand:SI 0 "register_operand" "=a")
14666 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14667 (match_operand:SI 2 "tls_symbolic_operand" "")
14668 (match_operand:SI 3 "call_insn_operand" "")]
14670 (clobber (match_scratch:SI 4 "=d"))
14671 (clobber (match_scratch:SI 5 "=c"))
14672 (clobber (reg:CC FLAGS_REG))]
14673 "!TARGET_64BIT && TARGET_GNU_TLS"
14674 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14675 [(set_attr "type" "multi")
14676 (set_attr "length" "12")])
14678 (define_insn "*tls_global_dynamic_32_sun"
14679 [(set (match_operand:SI 0 "register_operand" "=a")
14680 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14681 (match_operand:SI 2 "tls_symbolic_operand" "")
14682 (match_operand:SI 3 "call_insn_operand" "")]
14684 (clobber (match_scratch:SI 4 "=d"))
14685 (clobber (match_scratch:SI 5 "=c"))
14686 (clobber (reg:CC FLAGS_REG))]
14687 "!TARGET_64BIT && TARGET_SUN_TLS"
14688 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14689 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14690 [(set_attr "type" "multi")
14691 (set_attr "length" "14")])
14693 (define_expand "tls_global_dynamic_32"
14694 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14697 (match_operand:SI 1 "tls_symbolic_operand" "")
14700 (clobber (match_scratch:SI 4 ""))
14701 (clobber (match_scratch:SI 5 ""))
14702 (clobber (reg:CC FLAGS_REG))])]
14706 operands[2] = pic_offset_table_rtx;
14709 operands[2] = gen_reg_rtx (Pmode);
14710 emit_insn (gen_set_got (operands[2]));
14712 if (TARGET_GNU2_TLS)
14714 emit_insn (gen_tls_dynamic_gnu2_32
14715 (operands[0], operands[1], operands[2]));
14718 operands[3] = ix86_tls_get_addr ();
14721 (define_insn "*tls_global_dynamic_64"
14722 [(set (match_operand:DI 0 "register_operand" "=a")
14723 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14724 (match_operand:DI 3 "" "")))
14725 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14728 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14729 [(set_attr "type" "multi")
14730 (set_attr "length" "16")])
14732 (define_expand "tls_global_dynamic_64"
14733 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14734 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14735 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14739 if (TARGET_GNU2_TLS)
14741 emit_insn (gen_tls_dynamic_gnu2_64
14742 (operands[0], operands[1]));
14745 operands[2] = ix86_tls_get_addr ();
14748 (define_insn "*tls_local_dynamic_base_32_gnu"
14749 [(set (match_operand:SI 0 "register_operand" "=a")
14750 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14751 (match_operand:SI 2 "call_insn_operand" "")]
14752 UNSPEC_TLS_LD_BASE))
14753 (clobber (match_scratch:SI 3 "=d"))
14754 (clobber (match_scratch:SI 4 "=c"))
14755 (clobber (reg:CC FLAGS_REG))]
14756 "!TARGET_64BIT && TARGET_GNU_TLS"
14757 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14758 [(set_attr "type" "multi")
14759 (set_attr "length" "11")])
14761 (define_insn "*tls_local_dynamic_base_32_sun"
14762 [(set (match_operand:SI 0 "register_operand" "=a")
14763 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14764 (match_operand:SI 2 "call_insn_operand" "")]
14765 UNSPEC_TLS_LD_BASE))
14766 (clobber (match_scratch:SI 3 "=d"))
14767 (clobber (match_scratch:SI 4 "=c"))
14768 (clobber (reg:CC FLAGS_REG))]
14769 "!TARGET_64BIT && TARGET_SUN_TLS"
14770 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14771 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14772 [(set_attr "type" "multi")
14773 (set_attr "length" "13")])
14775 (define_expand "tls_local_dynamic_base_32"
14776 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14777 (unspec:SI [(match_dup 1) (match_dup 2)]
14778 UNSPEC_TLS_LD_BASE))
14779 (clobber (match_scratch:SI 3 ""))
14780 (clobber (match_scratch:SI 4 ""))
14781 (clobber (reg:CC FLAGS_REG))])]
14785 operands[1] = pic_offset_table_rtx;
14788 operands[1] = gen_reg_rtx (Pmode);
14789 emit_insn (gen_set_got (operands[1]));
14791 if (TARGET_GNU2_TLS)
14793 emit_insn (gen_tls_dynamic_gnu2_32
14794 (operands[0], ix86_tls_module_base (), operands[1]));
14797 operands[2] = ix86_tls_get_addr ();
14800 (define_insn "*tls_local_dynamic_base_64"
14801 [(set (match_operand:DI 0 "register_operand" "=a")
14802 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14803 (match_operand:DI 2 "" "")))
14804 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14806 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14807 [(set_attr "type" "multi")
14808 (set_attr "length" "12")])
14810 (define_expand "tls_local_dynamic_base_64"
14811 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14812 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14813 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14816 if (TARGET_GNU2_TLS)
14818 emit_insn (gen_tls_dynamic_gnu2_64
14819 (operands[0], ix86_tls_module_base ()));
14822 operands[1] = ix86_tls_get_addr ();
14825 ;; Local dynamic of a single variable is a lose. Show combine how
14826 ;; to convert that back to global dynamic.
14828 (define_insn_and_split "*tls_local_dynamic_32_once"
14829 [(set (match_operand:SI 0 "register_operand" "=a")
14830 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14831 (match_operand:SI 2 "call_insn_operand" "")]
14832 UNSPEC_TLS_LD_BASE)
14833 (const:SI (unspec:SI
14834 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14836 (clobber (match_scratch:SI 4 "=d"))
14837 (clobber (match_scratch:SI 5 "=c"))
14838 (clobber (reg:CC FLAGS_REG))]
14842 [(parallel [(set (match_dup 0)
14843 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14845 (clobber (match_dup 4))
14846 (clobber (match_dup 5))
14847 (clobber (reg:CC FLAGS_REG))])]
14850 ;; Load and add the thread base pointer from %gs:0.
14852 (define_insn "*load_tp_si"
14853 [(set (match_operand:SI 0 "register_operand" "=r")
14854 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14856 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14857 [(set_attr "type" "imov")
14858 (set_attr "modrm" "0")
14859 (set_attr "length" "7")
14860 (set_attr "memory" "load")
14861 (set_attr "imm_disp" "false")])
14863 (define_insn "*add_tp_si"
14864 [(set (match_operand:SI 0 "register_operand" "=r")
14865 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14866 (match_operand:SI 1 "register_operand" "0")))
14867 (clobber (reg:CC FLAGS_REG))]
14869 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14870 [(set_attr "type" "alu")
14871 (set_attr "modrm" "0")
14872 (set_attr "length" "7")
14873 (set_attr "memory" "load")
14874 (set_attr "imm_disp" "false")])
14876 (define_insn "*load_tp_di"
14877 [(set (match_operand:DI 0 "register_operand" "=r")
14878 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14880 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14881 [(set_attr "type" "imov")
14882 (set_attr "modrm" "0")
14883 (set_attr "length" "7")
14884 (set_attr "memory" "load")
14885 (set_attr "imm_disp" "false")])
14887 (define_insn "*add_tp_di"
14888 [(set (match_operand:DI 0 "register_operand" "=r")
14889 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14890 (match_operand:DI 1 "register_operand" "0")))
14891 (clobber (reg:CC FLAGS_REG))]
14893 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14894 [(set_attr "type" "alu")
14895 (set_attr "modrm" "0")
14896 (set_attr "length" "7")
14897 (set_attr "memory" "load")
14898 (set_attr "imm_disp" "false")])
14900 ;; GNU2 TLS patterns can be split.
14902 (define_expand "tls_dynamic_gnu2_32"
14903 [(set (match_dup 3)
14904 (plus:SI (match_operand:SI 2 "register_operand" "")
14906 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14909 [(set (match_operand:SI 0 "register_operand" "")
14910 (unspec:SI [(match_dup 1) (match_dup 3)
14911 (match_dup 2) (reg:SI SP_REG)]
14913 (clobber (reg:CC FLAGS_REG))])]
14914 "!TARGET_64BIT && TARGET_GNU2_TLS"
14916 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14917 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14920 (define_insn "*tls_dynamic_lea_32"
14921 [(set (match_operand:SI 0 "register_operand" "=r")
14922 (plus:SI (match_operand:SI 1 "register_operand" "b")
14924 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14925 UNSPEC_TLSDESC))))]
14926 "!TARGET_64BIT && TARGET_GNU2_TLS"
14927 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14928 [(set_attr "type" "lea")
14929 (set_attr "mode" "SI")
14930 (set_attr "length" "6")
14931 (set_attr "length_address" "4")])
14933 (define_insn "*tls_dynamic_call_32"
14934 [(set (match_operand:SI 0 "register_operand" "=a")
14935 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14936 (match_operand:SI 2 "register_operand" "0")
14937 ;; we have to make sure %ebx still points to the GOT
14938 (match_operand:SI 3 "register_operand" "b")
14941 (clobber (reg:CC FLAGS_REG))]
14942 "!TARGET_64BIT && TARGET_GNU2_TLS"
14943 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14944 [(set_attr "type" "call")
14945 (set_attr "length" "2")
14946 (set_attr "length_address" "0")])
14948 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14949 [(set (match_operand:SI 0 "register_operand" "=&a")
14951 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14952 (match_operand:SI 4 "" "")
14953 (match_operand:SI 2 "register_operand" "b")
14956 (const:SI (unspec:SI
14957 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14959 (clobber (reg:CC FLAGS_REG))]
14960 "!TARGET_64BIT && TARGET_GNU2_TLS"
14963 [(set (match_dup 0) (match_dup 5))]
14965 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14966 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14969 (define_expand "tls_dynamic_gnu2_64"
14970 [(set (match_dup 2)
14971 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14974 [(set (match_operand:DI 0 "register_operand" "")
14975 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14977 (clobber (reg:CC FLAGS_REG))])]
14978 "TARGET_64BIT && TARGET_GNU2_TLS"
14980 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14981 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14984 (define_insn "*tls_dynamic_lea_64"
14985 [(set (match_operand:DI 0 "register_operand" "=r")
14986 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14988 "TARGET_64BIT && TARGET_GNU2_TLS"
14989 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14990 [(set_attr "type" "lea")
14991 (set_attr "mode" "DI")
14992 (set_attr "length" "7")
14993 (set_attr "length_address" "4")])
14995 (define_insn "*tls_dynamic_call_64"
14996 [(set (match_operand:DI 0 "register_operand" "=a")
14997 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14998 (match_operand:DI 2 "register_operand" "0")
15001 (clobber (reg:CC FLAGS_REG))]
15002 "TARGET_64BIT && TARGET_GNU2_TLS"
15003 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15004 [(set_attr "type" "call")
15005 (set_attr "length" "2")
15006 (set_attr "length_address" "0")])
15008 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15009 [(set (match_operand:DI 0 "register_operand" "=&a")
15011 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15012 (match_operand:DI 3 "" "")
15015 (const:DI (unspec:DI
15016 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15018 (clobber (reg:CC FLAGS_REG))]
15019 "TARGET_64BIT && TARGET_GNU2_TLS"
15022 [(set (match_dup 0) (match_dup 4))]
15024 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15025 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15030 ;; These patterns match the binary 387 instructions for addM3, subM3,
15031 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15032 ;; SFmode. The first is the normal insn, the second the same insn but
15033 ;; with one operand a conversion, and the third the same insn but with
15034 ;; the other operand a conversion. The conversion may be SFmode or
15035 ;; SImode if the target mode DFmode, but only SImode if the target mode
15038 ;; Gcc is slightly more smart about handling normal two address instructions
15039 ;; so use special patterns for add and mull.
15041 (define_insn "*fop_sf_comm_mixed"
15042 [(set (match_operand:SF 0 "register_operand" "=f,x")
15043 (match_operator:SF 3 "binary_fp_operator"
15044 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15045 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15046 "TARGET_MIX_SSE_I387
15047 && COMMUTATIVE_ARITH_P (operands[3])
15048 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15049 "* return output_387_binary_op (insn, operands);"
15050 [(set (attr "type")
15051 (if_then_else (eq_attr "alternative" "1")
15052 (if_then_else (match_operand:SF 3 "mult_operator" "")
15053 (const_string "ssemul")
15054 (const_string "sseadd"))
15055 (if_then_else (match_operand:SF 3 "mult_operator" "")
15056 (const_string "fmul")
15057 (const_string "fop"))))
15058 (set_attr "mode" "SF")])
15060 (define_insn "*fop_sf_comm_sse"
15061 [(set (match_operand:SF 0 "register_operand" "=x")
15062 (match_operator:SF 3 "binary_fp_operator"
15063 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15064 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15066 && COMMUTATIVE_ARITH_P (operands[3])
15067 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15068 "* return output_387_binary_op (insn, operands);"
15069 [(set (attr "type")
15070 (if_then_else (match_operand:SF 3 "mult_operator" "")
15071 (const_string "ssemul")
15072 (const_string "sseadd")))
15073 (set_attr "mode" "SF")])
15075 (define_insn "*fop_sf_comm_i387"
15076 [(set (match_operand:SF 0 "register_operand" "=f")
15077 (match_operator:SF 3 "binary_fp_operator"
15078 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15079 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15081 && COMMUTATIVE_ARITH_P (operands[3])
15082 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15083 "* return output_387_binary_op (insn, operands);"
15084 [(set (attr "type")
15085 (if_then_else (match_operand:SF 3 "mult_operator" "")
15086 (const_string "fmul")
15087 (const_string "fop")))
15088 (set_attr "mode" "SF")])
15090 (define_insn "*fop_sf_1_mixed"
15091 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15092 (match_operator:SF 3 "binary_fp_operator"
15093 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15094 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15095 "TARGET_MIX_SSE_I387
15096 && !COMMUTATIVE_ARITH_P (operands[3])
15097 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15098 "* return output_387_binary_op (insn, operands);"
15099 [(set (attr "type")
15100 (cond [(and (eq_attr "alternative" "2")
15101 (match_operand:SF 3 "mult_operator" ""))
15102 (const_string "ssemul")
15103 (and (eq_attr "alternative" "2")
15104 (match_operand:SF 3 "div_operator" ""))
15105 (const_string "ssediv")
15106 (eq_attr "alternative" "2")
15107 (const_string "sseadd")
15108 (match_operand:SF 3 "mult_operator" "")
15109 (const_string "fmul")
15110 (match_operand:SF 3 "div_operator" "")
15111 (const_string "fdiv")
15113 (const_string "fop")))
15114 (set_attr "mode" "SF")])
15116 (define_insn "*fop_sf_1_sse"
15117 [(set (match_operand:SF 0 "register_operand" "=x")
15118 (match_operator:SF 3 "binary_fp_operator"
15119 [(match_operand:SF 1 "register_operand" "0")
15120 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15122 && !COMMUTATIVE_ARITH_P (operands[3])"
15123 "* return output_387_binary_op (insn, operands);"
15124 [(set (attr "type")
15125 (cond [(match_operand:SF 3 "mult_operator" "")
15126 (const_string "ssemul")
15127 (match_operand:SF 3 "div_operator" "")
15128 (const_string "ssediv")
15130 (const_string "sseadd")))
15131 (set_attr "mode" "SF")])
15133 ;; This pattern is not fully shadowed by the pattern above.
15134 (define_insn "*fop_sf_1_i387"
15135 [(set (match_operand:SF 0 "register_operand" "=f,f")
15136 (match_operator:SF 3 "binary_fp_operator"
15137 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15138 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15139 "TARGET_80387 && !TARGET_SSE_MATH
15140 && !COMMUTATIVE_ARITH_P (operands[3])
15141 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15142 "* return output_387_binary_op (insn, operands);"
15143 [(set (attr "type")
15144 (cond [(match_operand:SF 3 "mult_operator" "")
15145 (const_string "fmul")
15146 (match_operand:SF 3 "div_operator" "")
15147 (const_string "fdiv")
15149 (const_string "fop")))
15150 (set_attr "mode" "SF")])
15152 ;; ??? Add SSE splitters for these!
15153 (define_insn "*fop_sf_2<mode>_i387"
15154 [(set (match_operand:SF 0 "register_operand" "=f,f")
15155 (match_operator:SF 3 "binary_fp_operator"
15156 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15157 (match_operand:SF 2 "register_operand" "0,0")]))]
15158 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15159 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15160 [(set (attr "type")
15161 (cond [(match_operand:SF 3 "mult_operator" "")
15162 (const_string "fmul")
15163 (match_operand:SF 3 "div_operator" "")
15164 (const_string "fdiv")
15166 (const_string "fop")))
15167 (set_attr "fp_int_src" "true")
15168 (set_attr "mode" "<MODE>")])
15170 (define_insn "*fop_sf_3<mode>_i387"
15171 [(set (match_operand:SF 0 "register_operand" "=f,f")
15172 (match_operator:SF 3 "binary_fp_operator"
15173 [(match_operand:SF 1 "register_operand" "0,0")
15174 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15175 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15176 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15177 [(set (attr "type")
15178 (cond [(match_operand:SF 3 "mult_operator" "")
15179 (const_string "fmul")
15180 (match_operand:SF 3 "div_operator" "")
15181 (const_string "fdiv")
15183 (const_string "fop")))
15184 (set_attr "fp_int_src" "true")
15185 (set_attr "mode" "<MODE>")])
15187 (define_insn "*fop_df_comm_mixed"
15188 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15189 (match_operator:DF 3 "binary_fp_operator"
15190 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15191 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15192 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15193 && COMMUTATIVE_ARITH_P (operands[3])
15194 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15195 "* return output_387_binary_op (insn, operands);"
15196 [(set (attr "type")
15197 (if_then_else (eq_attr "alternative" "1")
15198 (if_then_else (match_operand:DF 3 "mult_operator" "")
15199 (const_string "ssemul")
15200 (const_string "sseadd"))
15201 (if_then_else (match_operand:DF 3 "mult_operator" "")
15202 (const_string "fmul")
15203 (const_string "fop"))))
15204 (set_attr "mode" "DF")])
15206 (define_insn "*fop_df_comm_sse"
15207 [(set (match_operand:DF 0 "register_operand" "=Y")
15208 (match_operator:DF 3 "binary_fp_operator"
15209 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15210 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15211 "TARGET_SSE2 && TARGET_SSE_MATH
15212 && COMMUTATIVE_ARITH_P (operands[3])
15213 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15214 "* return output_387_binary_op (insn, operands);"
15215 [(set (attr "type")
15216 (if_then_else (match_operand:DF 3 "mult_operator" "")
15217 (const_string "ssemul")
15218 (const_string "sseadd")))
15219 (set_attr "mode" "DF")])
15221 (define_insn "*fop_df_comm_i387"
15222 [(set (match_operand:DF 0 "register_operand" "=f")
15223 (match_operator:DF 3 "binary_fp_operator"
15224 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15225 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15227 && COMMUTATIVE_ARITH_P (operands[3])
15228 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15229 "* return output_387_binary_op (insn, operands);"
15230 [(set (attr "type")
15231 (if_then_else (match_operand:DF 3 "mult_operator" "")
15232 (const_string "fmul")
15233 (const_string "fop")))
15234 (set_attr "mode" "DF")])
15236 (define_insn "*fop_df_1_mixed"
15237 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15238 (match_operator:DF 3 "binary_fp_operator"
15239 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15240 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15241 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15242 && !COMMUTATIVE_ARITH_P (operands[3])
15243 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15244 "* return output_387_binary_op (insn, operands);"
15245 [(set (attr "type")
15246 (cond [(and (eq_attr "alternative" "2")
15247 (match_operand:DF 3 "mult_operator" ""))
15248 (const_string "ssemul")
15249 (and (eq_attr "alternative" "2")
15250 (match_operand:DF 3 "div_operator" ""))
15251 (const_string "ssediv")
15252 (eq_attr "alternative" "2")
15253 (const_string "sseadd")
15254 (match_operand:DF 3 "mult_operator" "")
15255 (const_string "fmul")
15256 (match_operand:DF 3 "div_operator" "")
15257 (const_string "fdiv")
15259 (const_string "fop")))
15260 (set_attr "mode" "DF")])
15262 (define_insn "*fop_df_1_sse"
15263 [(set (match_operand:DF 0 "register_operand" "=Y")
15264 (match_operator:DF 3 "binary_fp_operator"
15265 [(match_operand:DF 1 "register_operand" "0")
15266 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15267 "TARGET_SSE2 && TARGET_SSE_MATH
15268 && !COMMUTATIVE_ARITH_P (operands[3])"
15269 "* return output_387_binary_op (insn, operands);"
15270 [(set_attr "mode" "DF")
15272 (cond [(match_operand:DF 3 "mult_operator" "")
15273 (const_string "ssemul")
15274 (match_operand:DF 3 "div_operator" "")
15275 (const_string "ssediv")
15277 (const_string "sseadd")))])
15279 ;; This pattern is not fully shadowed by the pattern above.
15280 (define_insn "*fop_df_1_i387"
15281 [(set (match_operand:DF 0 "register_operand" "=f,f")
15282 (match_operator:DF 3 "binary_fp_operator"
15283 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15284 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15285 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15286 && !COMMUTATIVE_ARITH_P (operands[3])
15287 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15288 "* return output_387_binary_op (insn, operands);"
15289 [(set (attr "type")
15290 (cond [(match_operand:DF 3 "mult_operator" "")
15291 (const_string "fmul")
15292 (match_operand:DF 3 "div_operator" "")
15293 (const_string "fdiv")
15295 (const_string "fop")))
15296 (set_attr "mode" "DF")])
15298 ;; ??? Add SSE splitters for these!
15299 (define_insn "*fop_df_2<mode>_i387"
15300 [(set (match_operand:DF 0 "register_operand" "=f,f")
15301 (match_operator:DF 3 "binary_fp_operator"
15302 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15303 (match_operand:DF 2 "register_operand" "0,0")]))]
15304 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15305 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15306 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15307 [(set (attr "type")
15308 (cond [(match_operand:DF 3 "mult_operator" "")
15309 (const_string "fmul")
15310 (match_operand:DF 3 "div_operator" "")
15311 (const_string "fdiv")
15313 (const_string "fop")))
15314 (set_attr "fp_int_src" "true")
15315 (set_attr "mode" "<MODE>")])
15317 (define_insn "*fop_df_3<mode>_i387"
15318 [(set (match_operand:DF 0 "register_operand" "=f,f")
15319 (match_operator:DF 3 "binary_fp_operator"
15320 [(match_operand:DF 1 "register_operand" "0,0")
15321 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15322 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15323 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15324 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15325 [(set (attr "type")
15326 (cond [(match_operand:DF 3 "mult_operator" "")
15327 (const_string "fmul")
15328 (match_operand:DF 3 "div_operator" "")
15329 (const_string "fdiv")
15331 (const_string "fop")))
15332 (set_attr "fp_int_src" "true")
15333 (set_attr "mode" "<MODE>")])
15335 (define_insn "*fop_df_4_i387"
15336 [(set (match_operand:DF 0 "register_operand" "=f,f")
15337 (match_operator:DF 3 "binary_fp_operator"
15338 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15339 (match_operand:DF 2 "register_operand" "0,f")]))]
15340 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15341 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15342 "* return output_387_binary_op (insn, operands);"
15343 [(set (attr "type")
15344 (cond [(match_operand:DF 3 "mult_operator" "")
15345 (const_string "fmul")
15346 (match_operand:DF 3 "div_operator" "")
15347 (const_string "fdiv")
15349 (const_string "fop")))
15350 (set_attr "mode" "SF")])
15352 (define_insn "*fop_df_5_i387"
15353 [(set (match_operand:DF 0 "register_operand" "=f,f")
15354 (match_operator:DF 3 "binary_fp_operator"
15355 [(match_operand:DF 1 "register_operand" "0,f")
15357 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15358 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15359 "* return output_387_binary_op (insn, operands);"
15360 [(set (attr "type")
15361 (cond [(match_operand:DF 3 "mult_operator" "")
15362 (const_string "fmul")
15363 (match_operand:DF 3 "div_operator" "")
15364 (const_string "fdiv")
15366 (const_string "fop")))
15367 (set_attr "mode" "SF")])
15369 (define_insn "*fop_df_6_i387"
15370 [(set (match_operand:DF 0 "register_operand" "=f,f")
15371 (match_operator:DF 3 "binary_fp_operator"
15373 (match_operand:SF 1 "register_operand" "0,f"))
15375 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15376 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15377 "* return output_387_binary_op (insn, operands);"
15378 [(set (attr "type")
15379 (cond [(match_operand:DF 3 "mult_operator" "")
15380 (const_string "fmul")
15381 (match_operand:DF 3 "div_operator" "")
15382 (const_string "fdiv")
15384 (const_string "fop")))
15385 (set_attr "mode" "SF")])
15387 (define_insn "*fop_xf_comm_i387"
15388 [(set (match_operand:XF 0 "register_operand" "=f")
15389 (match_operator:XF 3 "binary_fp_operator"
15390 [(match_operand:XF 1 "register_operand" "%0")
15391 (match_operand:XF 2 "register_operand" "f")]))]
15393 && COMMUTATIVE_ARITH_P (operands[3])"
15394 "* return output_387_binary_op (insn, operands);"
15395 [(set (attr "type")
15396 (if_then_else (match_operand:XF 3 "mult_operator" "")
15397 (const_string "fmul")
15398 (const_string "fop")))
15399 (set_attr "mode" "XF")])
15401 (define_insn "*fop_xf_1_i387"
15402 [(set (match_operand:XF 0 "register_operand" "=f,f")
15403 (match_operator:XF 3 "binary_fp_operator"
15404 [(match_operand:XF 1 "register_operand" "0,f")
15405 (match_operand:XF 2 "register_operand" "f,0")]))]
15407 && !COMMUTATIVE_ARITH_P (operands[3])"
15408 "* return output_387_binary_op (insn, operands);"
15409 [(set (attr "type")
15410 (cond [(match_operand:XF 3 "mult_operator" "")
15411 (const_string "fmul")
15412 (match_operand:XF 3 "div_operator" "")
15413 (const_string "fdiv")
15415 (const_string "fop")))
15416 (set_attr "mode" "XF")])
15418 (define_insn "*fop_xf_2<mode>_i387"
15419 [(set (match_operand:XF 0 "register_operand" "=f,f")
15420 (match_operator:XF 3 "binary_fp_operator"
15421 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15422 (match_operand:XF 2 "register_operand" "0,0")]))]
15423 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15424 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15425 [(set (attr "type")
15426 (cond [(match_operand:XF 3 "mult_operator" "")
15427 (const_string "fmul")
15428 (match_operand:XF 3 "div_operator" "")
15429 (const_string "fdiv")
15431 (const_string "fop")))
15432 (set_attr "fp_int_src" "true")
15433 (set_attr "mode" "<MODE>")])
15435 (define_insn "*fop_xf_3<mode>_i387"
15436 [(set (match_operand:XF 0 "register_operand" "=f,f")
15437 (match_operator:XF 3 "binary_fp_operator"
15438 [(match_operand:XF 1 "register_operand" "0,0")
15439 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15440 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15441 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15442 [(set (attr "type")
15443 (cond [(match_operand:XF 3 "mult_operator" "")
15444 (const_string "fmul")
15445 (match_operand:XF 3 "div_operator" "")
15446 (const_string "fdiv")
15448 (const_string "fop")))
15449 (set_attr "fp_int_src" "true")
15450 (set_attr "mode" "<MODE>")])
15452 (define_insn "*fop_xf_4_i387"
15453 [(set (match_operand:XF 0 "register_operand" "=f,f")
15454 (match_operator:XF 3 "binary_fp_operator"
15456 (match_operand:X87MODEF12 1 "nonimmediate_operand" "fm,0"))
15457 (match_operand:XF 2 "register_operand" "0,f")]))]
15459 "* return output_387_binary_op (insn, operands);"
15460 [(set (attr "type")
15461 (cond [(match_operand:XF 3 "mult_operator" "")
15462 (const_string "fmul")
15463 (match_operand:XF 3 "div_operator" "")
15464 (const_string "fdiv")
15466 (const_string "fop")))
15467 (set_attr "mode" "SF")])
15469 (define_insn "*fop_xf_5_i387"
15470 [(set (match_operand:XF 0 "register_operand" "=f,f")
15471 (match_operator:XF 3 "binary_fp_operator"
15472 [(match_operand:XF 1 "register_operand" "0,f")
15474 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15476 "* return output_387_binary_op (insn, operands);"
15477 [(set (attr "type")
15478 (cond [(match_operand:XF 3 "mult_operator" "")
15479 (const_string "fmul")
15480 (match_operand:XF 3 "div_operator" "")
15481 (const_string "fdiv")
15483 (const_string "fop")))
15484 (set_attr "mode" "SF")])
15486 (define_insn "*fop_xf_6_i387"
15487 [(set (match_operand:XF 0 "register_operand" "=f,f")
15488 (match_operator:XF 3 "binary_fp_operator"
15490 (match_operand:X87MODEF12 1 "register_operand" "0,f"))
15492 (match_operand:X87MODEF12 2 "nonimmediate_operand" "fm,0"))]))]
15494 "* return output_387_binary_op (insn, operands);"
15495 [(set (attr "type")
15496 (cond [(match_operand:XF 3 "mult_operator" "")
15497 (const_string "fmul")
15498 (match_operand:XF 3 "div_operator" "")
15499 (const_string "fdiv")
15501 (const_string "fop")))
15502 (set_attr "mode" "SF")])
15505 [(set (match_operand 0 "register_operand" "")
15506 (match_operator 3 "binary_fp_operator"
15507 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15508 (match_operand 2 "register_operand" "")]))]
15509 "TARGET_80387 && reload_completed
15510 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15513 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15514 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15515 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15516 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15517 GET_MODE (operands[3]),
15520 ix86_free_from_memory (GET_MODE (operands[1]));
15525 [(set (match_operand 0 "register_operand" "")
15526 (match_operator 3 "binary_fp_operator"
15527 [(match_operand 1 "register_operand" "")
15528 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15529 "TARGET_80387 && reload_completed
15530 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15533 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15534 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15535 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15536 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15537 GET_MODE (operands[3]),
15540 ix86_free_from_memory (GET_MODE (operands[2]));
15544 ;; FPU special functions.
15546 ;; This pattern implements a no-op XFmode truncation for
15547 ;; all fancy i386 XFmode math functions.
15549 (define_insn "truncxf<mode>2_i387_noop_unspec"
15550 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15551 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15552 UNSPEC_TRUNC_NOOP))]
15553 "TARGET_USE_FANCY_MATH_387"
15554 "* return output_387_reg_move (insn, operands);"
15555 [(set_attr "type" "fmov")
15556 (set_attr "mode" "<MODE>")])
15558 (define_insn "sqrtxf2"
15559 [(set (match_operand:XF 0 "register_operand" "=f")
15560 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15561 "TARGET_USE_FANCY_MATH_387"
15563 [(set_attr "type" "fpspc")
15564 (set_attr "mode" "XF")
15565 (set_attr "athlon_decode" "direct")])
15567 (define_insn "sqrt_extend<mode>xf2_i387"
15568 [(set (match_operand:XF 0 "register_operand" "=f")
15571 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15572 "TARGET_USE_FANCY_MATH_387"
15574 [(set_attr "type" "fpspc")
15575 (set_attr "mode" "XF")
15576 (set_attr "athlon_decode" "direct")])
15578 (define_insn "*sqrt<mode>2_sse"
15579 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15581 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15582 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15583 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15584 [(set_attr "type" "sse")
15585 (set_attr "mode" "<MODE>")
15586 (set_attr "athlon_decode" "*")])
15588 (define_expand "sqrt<mode>2"
15589 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15591 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15592 "TARGET_USE_FANCY_MATH_387
15593 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15595 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15597 rtx op0 = gen_reg_rtx (XFmode);
15598 rtx op1 = force_reg (<MODE>mode, operands[1]);
15600 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15601 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15606 (define_insn "fpremxf4_i387"
15607 [(set (match_operand:XF 0 "register_operand" "=f")
15608 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15609 (match_operand:XF 3 "register_operand" "1")]
15611 (set (match_operand:XF 1 "register_operand" "=u")
15612 (unspec:XF [(match_dup 2) (match_dup 3)]
15614 (set (reg:CCFP FPSR_REG)
15615 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15616 "TARGET_USE_FANCY_MATH_387"
15618 [(set_attr "type" "fpspc")
15619 (set_attr "mode" "XF")])
15621 (define_expand "fmodxf3"
15622 [(use (match_operand:XF 0 "register_operand" ""))
15623 (use (match_operand:XF 1 "register_operand" ""))
15624 (use (match_operand:XF 2 "register_operand" ""))]
15625 "TARGET_USE_FANCY_MATH_387"
15627 rtx label = gen_label_rtx ();
15629 emit_label (label);
15631 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15632 operands[1], operands[2]));
15633 ix86_emit_fp_unordered_jump (label);
15635 emit_move_insn (operands[0], operands[1]);
15639 (define_expand "fmod<mode>3"
15640 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15641 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15642 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15643 "TARGET_USE_FANCY_MATH_387"
15645 rtx label = gen_label_rtx ();
15647 rtx op1 = gen_reg_rtx (XFmode);
15648 rtx op2 = gen_reg_rtx (XFmode);
15650 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15651 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15653 emit_label (label);
15654 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15655 ix86_emit_fp_unordered_jump (label);
15657 /* Truncate the result properly for strict SSE math. */
15658 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15659 && !TARGET_MIX_SSE_I387)
15660 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15662 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15667 (define_insn "fprem1xf4_i387"
15668 [(set (match_operand:XF 0 "register_operand" "=f")
15669 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15670 (match_operand:XF 3 "register_operand" "1")]
15672 (set (match_operand:XF 1 "register_operand" "=u")
15673 (unspec:XF [(match_dup 2) (match_dup 3)]
15675 (set (reg:CCFP FPSR_REG)
15676 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15677 "TARGET_USE_FANCY_MATH_387"
15679 [(set_attr "type" "fpspc")
15680 (set_attr "mode" "XF")])
15682 (define_expand "remainderxf3"
15683 [(use (match_operand:XF 0 "register_operand" ""))
15684 (use (match_operand:XF 1 "register_operand" ""))
15685 (use (match_operand:XF 2 "register_operand" ""))]
15686 "TARGET_USE_FANCY_MATH_387"
15688 rtx label = gen_label_rtx ();
15690 emit_label (label);
15692 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15693 operands[1], operands[2]));
15694 ix86_emit_fp_unordered_jump (label);
15696 emit_move_insn (operands[0], operands[1]);
15700 (define_expand "remainder<mode>3"
15701 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15702 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15703 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15704 "TARGET_USE_FANCY_MATH_387"
15706 rtx label = gen_label_rtx ();
15708 rtx op1 = gen_reg_rtx (XFmode);
15709 rtx op2 = gen_reg_rtx (XFmode);
15711 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15712 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15714 emit_label (label);
15716 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15717 ix86_emit_fp_unordered_jump (label);
15719 /* Truncate the result properly for strict SSE math. */
15720 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15721 && !TARGET_MIX_SSE_I387)
15722 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15724 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15729 (define_insn "*sindf2"
15730 [(set (match_operand:DF 0 "register_operand" "=f")
15731 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15732 "TARGET_USE_FANCY_MATH_387
15733 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15734 && flag_unsafe_math_optimizations"
15736 [(set_attr "type" "fpspc")
15737 (set_attr "mode" "DF")])
15739 (define_insn "*sinsf2"
15740 [(set (match_operand:SF 0 "register_operand" "=f")
15741 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15742 "TARGET_USE_FANCY_MATH_387
15743 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15744 && flag_unsafe_math_optimizations"
15746 [(set_attr "type" "fpspc")
15747 (set_attr "mode" "SF")])
15749 (define_insn "*sinextendsfdf2"
15750 [(set (match_operand:DF 0 "register_operand" "=f")
15751 (unspec:DF [(float_extend:DF
15752 (match_operand:SF 1 "register_operand" "0"))]
15754 "TARGET_USE_FANCY_MATH_387
15755 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15756 && flag_unsafe_math_optimizations"
15758 [(set_attr "type" "fpspc")
15759 (set_attr "mode" "DF")])
15761 (define_insn "*sinxf2"
15762 [(set (match_operand:XF 0 "register_operand" "=f")
15763 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15764 "TARGET_USE_FANCY_MATH_387
15765 && flag_unsafe_math_optimizations"
15767 [(set_attr "type" "fpspc")
15768 (set_attr "mode" "XF")])
15770 (define_insn "*cosdf2"
15771 [(set (match_operand:DF 0 "register_operand" "=f")
15772 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15773 "TARGET_USE_FANCY_MATH_387
15774 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15775 && flag_unsafe_math_optimizations"
15777 [(set_attr "type" "fpspc")
15778 (set_attr "mode" "DF")])
15780 (define_insn "*cossf2"
15781 [(set (match_operand:SF 0 "register_operand" "=f")
15782 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15783 "TARGET_USE_FANCY_MATH_387
15784 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15785 && flag_unsafe_math_optimizations"
15787 [(set_attr "type" "fpspc")
15788 (set_attr "mode" "SF")])
15790 (define_insn "*cosextendsfdf2"
15791 [(set (match_operand:DF 0 "register_operand" "=f")
15792 (unspec:DF [(float_extend:DF
15793 (match_operand:SF 1 "register_operand" "0"))]
15795 "TARGET_USE_FANCY_MATH_387
15796 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15797 && flag_unsafe_math_optimizations"
15799 [(set_attr "type" "fpspc")
15800 (set_attr "mode" "DF")])
15802 (define_insn "*cosxf2"
15803 [(set (match_operand:XF 0 "register_operand" "=f")
15804 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15805 "TARGET_USE_FANCY_MATH_387
15806 && flag_unsafe_math_optimizations"
15808 [(set_attr "type" "fpspc")
15809 (set_attr "mode" "XF")])
15811 ;; With sincos pattern defined, sin and cos builtin function will be
15812 ;; expanded to sincos pattern with one of its outputs left unused.
15813 ;; Cse pass will detected, if two sincos patterns can be combined,
15814 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15815 ;; depending on the unused output.
15817 (define_insn "sincosdf3"
15818 [(set (match_operand:DF 0 "register_operand" "=f")
15819 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15820 UNSPEC_SINCOS_COS))
15821 (set (match_operand:DF 1 "register_operand" "=u")
15822 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15823 "TARGET_USE_FANCY_MATH_387
15824 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15825 && flag_unsafe_math_optimizations"
15827 [(set_attr "type" "fpspc")
15828 (set_attr "mode" "DF")])
15831 [(set (match_operand:DF 0 "register_operand" "")
15832 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15833 UNSPEC_SINCOS_COS))
15834 (set (match_operand:DF 1 "register_operand" "")
15835 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15836 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15837 && !reload_completed && !reload_in_progress"
15838 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15842 [(set (match_operand:DF 0 "register_operand" "")
15843 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15844 UNSPEC_SINCOS_COS))
15845 (set (match_operand:DF 1 "register_operand" "")
15846 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15847 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15848 && !reload_completed && !reload_in_progress"
15849 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15852 (define_insn "sincossf3"
15853 [(set (match_operand:SF 0 "register_operand" "=f")
15854 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15855 UNSPEC_SINCOS_COS))
15856 (set (match_operand:SF 1 "register_operand" "=u")
15857 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15858 "TARGET_USE_FANCY_MATH_387
15859 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15860 && flag_unsafe_math_optimizations"
15862 [(set_attr "type" "fpspc")
15863 (set_attr "mode" "SF")])
15866 [(set (match_operand:SF 0 "register_operand" "")
15867 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15868 UNSPEC_SINCOS_COS))
15869 (set (match_operand:SF 1 "register_operand" "")
15870 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15871 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15872 && !reload_completed && !reload_in_progress"
15873 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15877 [(set (match_operand:SF 0 "register_operand" "")
15878 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15879 UNSPEC_SINCOS_COS))
15880 (set (match_operand:SF 1 "register_operand" "")
15881 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15882 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15883 && !reload_completed && !reload_in_progress"
15884 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15887 (define_insn "*sincosextendsfdf3"
15888 [(set (match_operand:DF 0 "register_operand" "=f")
15889 (unspec:DF [(float_extend:DF
15890 (match_operand:SF 2 "register_operand" "0"))]
15891 UNSPEC_SINCOS_COS))
15892 (set (match_operand:DF 1 "register_operand" "=u")
15893 (unspec:DF [(float_extend:DF
15894 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15895 "TARGET_USE_FANCY_MATH_387
15896 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15897 && flag_unsafe_math_optimizations"
15899 [(set_attr "type" "fpspc")
15900 (set_attr "mode" "DF")])
15903 [(set (match_operand:DF 0 "register_operand" "")
15904 (unspec:DF [(float_extend:DF
15905 (match_operand:SF 2 "register_operand" ""))]
15906 UNSPEC_SINCOS_COS))
15907 (set (match_operand:DF 1 "register_operand" "")
15908 (unspec:DF [(float_extend:DF
15909 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15910 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15911 && !reload_completed && !reload_in_progress"
15912 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15913 (match_dup 2))] UNSPEC_SIN))]
15917 [(set (match_operand:DF 0 "register_operand" "")
15918 (unspec:DF [(float_extend:DF
15919 (match_operand:SF 2 "register_operand" ""))]
15920 UNSPEC_SINCOS_COS))
15921 (set (match_operand:DF 1 "register_operand" "")
15922 (unspec:DF [(float_extend:DF
15923 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15924 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15925 && !reload_completed && !reload_in_progress"
15926 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15927 (match_dup 2))] UNSPEC_COS))]
15930 (define_insn "sincosxf3"
15931 [(set (match_operand:XF 0 "register_operand" "=f")
15932 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15933 UNSPEC_SINCOS_COS))
15934 (set (match_operand:XF 1 "register_operand" "=u")
15935 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15936 "TARGET_USE_FANCY_MATH_387
15937 && flag_unsafe_math_optimizations"
15939 [(set_attr "type" "fpspc")
15940 (set_attr "mode" "XF")])
15943 [(set (match_operand:XF 0 "register_operand" "")
15944 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15945 UNSPEC_SINCOS_COS))
15946 (set (match_operand:XF 1 "register_operand" "")
15947 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15948 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15949 && !reload_completed && !reload_in_progress"
15950 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15954 [(set (match_operand:XF 0 "register_operand" "")
15955 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15956 UNSPEC_SINCOS_COS))
15957 (set (match_operand:XF 1 "register_operand" "")
15958 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15959 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15960 && !reload_completed && !reload_in_progress"
15961 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15964 (define_insn "*tandf3_1"
15965 [(set (match_operand:DF 0 "register_operand" "=f")
15966 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15968 (set (match_operand:DF 1 "register_operand" "=u")
15969 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15970 "TARGET_USE_FANCY_MATH_387
15971 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15972 && flag_unsafe_math_optimizations"
15974 [(set_attr "type" "fpspc")
15975 (set_attr "mode" "DF")])
15977 ;; optimize sequence: fptan
15980 ;; into fptan insn.
15983 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15984 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15986 (set (match_operand:DF 1 "register_operand" "")
15987 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15989 (match_operand:DF 3 "immediate_operand" ""))]
15990 "standard_80387_constant_p (operands[3]) == 2"
15991 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15992 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15995 (define_expand "tandf2"
15996 [(parallel [(set (match_dup 2)
15997 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15999 (set (match_operand:DF 0 "register_operand" "")
16000 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16001 "TARGET_USE_FANCY_MATH_387
16002 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16003 && flag_unsafe_math_optimizations"
16005 operands[2] = gen_reg_rtx (DFmode);
16008 (define_insn "*tansf3_1"
16009 [(set (match_operand:SF 0 "register_operand" "=f")
16010 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
16012 (set (match_operand:SF 1 "register_operand" "=u")
16013 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
16014 "TARGET_USE_FANCY_MATH_387
16015 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16016 && flag_unsafe_math_optimizations"
16018 [(set_attr "type" "fpspc")
16019 (set_attr "mode" "SF")])
16021 ;; optimize sequence: fptan
16024 ;; into fptan insn.
16027 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16028 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16030 (set (match_operand:SF 1 "register_operand" "")
16031 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16033 (match_operand:SF 3 "immediate_operand" ""))]
16034 "standard_80387_constant_p (operands[3]) == 2"
16035 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16036 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16039 (define_expand "tansf2"
16040 [(parallel [(set (match_dup 2)
16041 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16043 (set (match_operand:SF 0 "register_operand" "")
16044 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16045 "TARGET_USE_FANCY_MATH_387
16046 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16047 && flag_unsafe_math_optimizations"
16049 operands[2] = gen_reg_rtx (SFmode);
16052 (define_insn "*tanxf3_1"
16053 [(set (match_operand:XF 0 "register_operand" "=f")
16054 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16056 (set (match_operand:XF 1 "register_operand" "=u")
16057 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16058 "TARGET_USE_FANCY_MATH_387
16059 && flag_unsafe_math_optimizations"
16061 [(set_attr "type" "fpspc")
16062 (set_attr "mode" "XF")])
16064 ;; optimize sequence: fptan
16067 ;; into fptan insn.
16070 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16071 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16073 (set (match_operand:XF 1 "register_operand" "")
16074 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16076 (match_operand:XF 3 "immediate_operand" ""))]
16077 "standard_80387_constant_p (operands[3]) == 2"
16078 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16079 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16082 (define_expand "tanxf2"
16083 [(parallel [(set (match_dup 2)
16084 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16086 (set (match_operand:XF 0 "register_operand" "")
16087 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16088 "TARGET_USE_FANCY_MATH_387
16089 && flag_unsafe_math_optimizations"
16091 operands[2] = gen_reg_rtx (XFmode);
16094 (define_insn "atan2df3_1"
16095 [(set (match_operand:DF 0 "register_operand" "=f")
16096 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16097 (match_operand:DF 1 "register_operand" "u")]
16099 (clobber (match_scratch:DF 3 "=1"))]
16100 "TARGET_USE_FANCY_MATH_387
16101 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16102 && flag_unsafe_math_optimizations"
16104 [(set_attr "type" "fpspc")
16105 (set_attr "mode" "DF")])
16107 (define_expand "atan2df3"
16108 [(use (match_operand:DF 0 "register_operand" ""))
16109 (use (match_operand:DF 2 "register_operand" ""))
16110 (use (match_operand:DF 1 "register_operand" ""))]
16111 "TARGET_USE_FANCY_MATH_387
16112 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16113 && flag_unsafe_math_optimizations"
16115 rtx copy = gen_reg_rtx (DFmode);
16116 emit_move_insn (copy, operands[1]);
16117 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16121 (define_expand "atandf2"
16122 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16123 (unspec:DF [(match_dup 2)
16124 (match_operand:DF 1 "register_operand" "")]
16126 (clobber (match_scratch:DF 3 ""))])]
16127 "TARGET_USE_FANCY_MATH_387
16128 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16129 && flag_unsafe_math_optimizations"
16131 operands[2] = gen_reg_rtx (DFmode);
16132 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16135 (define_insn "atan2sf3_1"
16136 [(set (match_operand:SF 0 "register_operand" "=f")
16137 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16138 (match_operand:SF 1 "register_operand" "u")]
16140 (clobber (match_scratch:SF 3 "=1"))]
16141 "TARGET_USE_FANCY_MATH_387
16142 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16143 && flag_unsafe_math_optimizations"
16145 [(set_attr "type" "fpspc")
16146 (set_attr "mode" "SF")])
16148 (define_expand "atan2sf3"
16149 [(use (match_operand:SF 0 "register_operand" ""))
16150 (use (match_operand:SF 2 "register_operand" ""))
16151 (use (match_operand:SF 1 "register_operand" ""))]
16152 "TARGET_USE_FANCY_MATH_387
16153 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16154 && flag_unsafe_math_optimizations"
16156 rtx copy = gen_reg_rtx (SFmode);
16157 emit_move_insn (copy, operands[1]);
16158 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16162 (define_expand "atansf2"
16163 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16164 (unspec:SF [(match_dup 2)
16165 (match_operand:SF 1 "register_operand" "")]
16167 (clobber (match_scratch:SF 3 ""))])]
16168 "TARGET_USE_FANCY_MATH_387
16169 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16170 && flag_unsafe_math_optimizations"
16172 operands[2] = gen_reg_rtx (SFmode);
16173 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16176 (define_insn "atan2xf3_1"
16177 [(set (match_operand:XF 0 "register_operand" "=f")
16178 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16179 (match_operand:XF 1 "register_operand" "u")]
16181 (clobber (match_scratch:XF 3 "=1"))]
16182 "TARGET_USE_FANCY_MATH_387
16183 && flag_unsafe_math_optimizations"
16185 [(set_attr "type" "fpspc")
16186 (set_attr "mode" "XF")])
16188 (define_expand "atan2xf3"
16189 [(use (match_operand:XF 0 "register_operand" ""))
16190 (use (match_operand:XF 2 "register_operand" ""))
16191 (use (match_operand:XF 1 "register_operand" ""))]
16192 "TARGET_USE_FANCY_MATH_387
16193 && flag_unsafe_math_optimizations"
16195 rtx copy = gen_reg_rtx (XFmode);
16196 emit_move_insn (copy, operands[1]);
16197 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16201 (define_expand "atanxf2"
16202 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16203 (unspec:XF [(match_dup 2)
16204 (match_operand:XF 1 "register_operand" "")]
16206 (clobber (match_scratch:XF 3 ""))])]
16207 "TARGET_USE_FANCY_MATH_387
16208 && flag_unsafe_math_optimizations"
16210 operands[2] = gen_reg_rtx (XFmode);
16211 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16214 (define_expand "asindf2"
16215 [(set (match_dup 2)
16216 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16217 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16218 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16219 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16220 (parallel [(set (match_dup 7)
16221 (unspec:XF [(match_dup 6) (match_dup 2)]
16223 (clobber (match_scratch:XF 8 ""))])
16224 (set (match_operand:DF 0 "register_operand" "")
16225 (float_truncate:DF (match_dup 7)))]
16226 "TARGET_USE_FANCY_MATH_387
16227 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16228 && flag_unsafe_math_optimizations && !optimize_size"
16232 for (i=2; i<8; i++)
16233 operands[i] = gen_reg_rtx (XFmode);
16235 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16238 (define_expand "asinsf2"
16239 [(set (match_dup 2)
16240 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16241 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16242 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16243 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16244 (parallel [(set (match_dup 7)
16245 (unspec:XF [(match_dup 6) (match_dup 2)]
16247 (clobber (match_scratch:XF 8 ""))])
16248 (set (match_operand:SF 0 "register_operand" "")
16249 (float_truncate:SF (match_dup 7)))]
16250 "TARGET_USE_FANCY_MATH_387
16251 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16252 && flag_unsafe_math_optimizations && !optimize_size"
16256 for (i=2; i<8; i++)
16257 operands[i] = gen_reg_rtx (XFmode);
16259 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16262 (define_expand "asinxf2"
16263 [(set (match_dup 2)
16264 (mult:XF (match_operand:XF 1 "register_operand" "")
16266 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16267 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16268 (parallel [(set (match_operand:XF 0 "register_operand" "")
16269 (unspec:XF [(match_dup 5) (match_dup 1)]
16271 (clobber (match_scratch:XF 6 ""))])]
16272 "TARGET_USE_FANCY_MATH_387
16273 && flag_unsafe_math_optimizations && !optimize_size"
16277 for (i=2; i<6; i++)
16278 operands[i] = gen_reg_rtx (XFmode);
16280 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16283 (define_expand "acosdf2"
16284 [(set (match_dup 2)
16285 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16286 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16287 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16288 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16289 (parallel [(set (match_dup 7)
16290 (unspec:XF [(match_dup 2) (match_dup 6)]
16292 (clobber (match_scratch:XF 8 ""))])
16293 (set (match_operand:DF 0 "register_operand" "")
16294 (float_truncate:DF (match_dup 7)))]
16295 "TARGET_USE_FANCY_MATH_387
16296 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16297 && flag_unsafe_math_optimizations && !optimize_size"
16301 for (i=2; i<8; i++)
16302 operands[i] = gen_reg_rtx (XFmode);
16304 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16307 (define_expand "acossf2"
16308 [(set (match_dup 2)
16309 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16310 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16311 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16312 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16313 (parallel [(set (match_dup 7)
16314 (unspec:XF [(match_dup 2) (match_dup 6)]
16316 (clobber (match_scratch:XF 8 ""))])
16317 (set (match_operand:SF 0 "register_operand" "")
16318 (float_truncate:SF (match_dup 7)))]
16319 "TARGET_USE_FANCY_MATH_387
16320 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16321 && flag_unsafe_math_optimizations && !optimize_size"
16325 for (i=2; i<8; i++)
16326 operands[i] = gen_reg_rtx (XFmode);
16328 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16331 (define_expand "acosxf2"
16332 [(set (match_dup 2)
16333 (mult:XF (match_operand:XF 1 "register_operand" "")
16335 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16336 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16337 (parallel [(set (match_operand:XF 0 "register_operand" "")
16338 (unspec:XF [(match_dup 1) (match_dup 5)]
16340 (clobber (match_scratch:XF 6 ""))])]
16341 "TARGET_USE_FANCY_MATH_387
16342 && flag_unsafe_math_optimizations && !optimize_size"
16346 for (i=2; i<6; i++)
16347 operands[i] = gen_reg_rtx (XFmode);
16349 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16352 (define_insn "fyl2x_xf3"
16353 [(set (match_operand:XF 0 "register_operand" "=f")
16354 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16355 (match_operand:XF 1 "register_operand" "u")]
16357 (clobber (match_scratch:XF 3 "=1"))]
16358 "TARGET_USE_FANCY_MATH_387
16359 && flag_unsafe_math_optimizations"
16361 [(set_attr "type" "fpspc")
16362 (set_attr "mode" "XF")])
16364 (define_expand "logsf2"
16365 [(set (match_dup 2)
16366 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16367 (parallel [(set (match_dup 4)
16368 (unspec:XF [(match_dup 2)
16369 (match_dup 3)] UNSPEC_FYL2X))
16370 (clobber (match_scratch:XF 5 ""))])
16371 (set (match_operand:SF 0 "register_operand" "")
16372 (float_truncate:SF (match_dup 4)))]
16373 "TARGET_USE_FANCY_MATH_387
16374 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16375 && flag_unsafe_math_optimizations"
16379 operands[2] = gen_reg_rtx (XFmode);
16380 operands[3] = gen_reg_rtx (XFmode);
16381 operands[4] = gen_reg_rtx (XFmode);
16383 temp = standard_80387_constant_rtx (4); /* fldln2 */
16384 emit_move_insn (operands[3], temp);
16387 (define_expand "logdf2"
16388 [(set (match_dup 2)
16389 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16390 (parallel [(set (match_dup 4)
16391 (unspec:XF [(match_dup 2)
16392 (match_dup 3)] UNSPEC_FYL2X))
16393 (clobber (match_scratch:XF 5 ""))])
16394 (set (match_operand:DF 0 "register_operand" "")
16395 (float_truncate:DF (match_dup 4)))]
16396 "TARGET_USE_FANCY_MATH_387
16397 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16398 && flag_unsafe_math_optimizations"
16402 operands[2] = gen_reg_rtx (XFmode);
16403 operands[3] = gen_reg_rtx (XFmode);
16404 operands[4] = gen_reg_rtx (XFmode);
16406 temp = standard_80387_constant_rtx (4); /* fldln2 */
16407 emit_move_insn (operands[3], temp);
16410 (define_expand "logxf2"
16411 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16412 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16413 (match_dup 2)] UNSPEC_FYL2X))
16414 (clobber (match_scratch:XF 3 ""))])]
16415 "TARGET_USE_FANCY_MATH_387
16416 && flag_unsafe_math_optimizations"
16420 operands[2] = gen_reg_rtx (XFmode);
16421 temp = standard_80387_constant_rtx (4); /* fldln2 */
16422 emit_move_insn (operands[2], temp);
16425 (define_expand "log10sf2"
16426 [(set (match_dup 2)
16427 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16428 (parallel [(set (match_dup 4)
16429 (unspec:XF [(match_dup 2)
16430 (match_dup 3)] UNSPEC_FYL2X))
16431 (clobber (match_scratch:XF 5 ""))])
16432 (set (match_operand:SF 0 "register_operand" "")
16433 (float_truncate:SF (match_dup 4)))]
16434 "TARGET_USE_FANCY_MATH_387
16435 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16436 && flag_unsafe_math_optimizations"
16440 operands[2] = gen_reg_rtx (XFmode);
16441 operands[3] = gen_reg_rtx (XFmode);
16442 operands[4] = gen_reg_rtx (XFmode);
16444 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16445 emit_move_insn (operands[3], temp);
16448 (define_expand "log10df2"
16449 [(set (match_dup 2)
16450 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16451 (parallel [(set (match_dup 4)
16452 (unspec:XF [(match_dup 2)
16453 (match_dup 3)] UNSPEC_FYL2X))
16454 (clobber (match_scratch:XF 5 ""))])
16455 (set (match_operand:DF 0 "register_operand" "")
16456 (float_truncate:DF (match_dup 4)))]
16457 "TARGET_USE_FANCY_MATH_387
16458 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16459 && flag_unsafe_math_optimizations"
16463 operands[2] = gen_reg_rtx (XFmode);
16464 operands[3] = gen_reg_rtx (XFmode);
16465 operands[4] = gen_reg_rtx (XFmode);
16467 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16468 emit_move_insn (operands[3], temp);
16471 (define_expand "log10xf2"
16472 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16473 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16474 (match_dup 2)] UNSPEC_FYL2X))
16475 (clobber (match_scratch:XF 3 ""))])]
16476 "TARGET_USE_FANCY_MATH_387
16477 && flag_unsafe_math_optimizations"
16481 operands[2] = gen_reg_rtx (XFmode);
16482 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16483 emit_move_insn (operands[2], temp);
16486 (define_expand "log2sf2"
16487 [(set (match_dup 2)
16488 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16489 (parallel [(set (match_dup 4)
16490 (unspec:XF [(match_dup 2)
16491 (match_dup 3)] UNSPEC_FYL2X))
16492 (clobber (match_scratch:XF 5 ""))])
16493 (set (match_operand:SF 0 "register_operand" "")
16494 (float_truncate:SF (match_dup 4)))]
16495 "TARGET_USE_FANCY_MATH_387
16496 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16497 && flag_unsafe_math_optimizations"
16499 operands[2] = gen_reg_rtx (XFmode);
16500 operands[3] = gen_reg_rtx (XFmode);
16501 operands[4] = gen_reg_rtx (XFmode);
16503 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16506 (define_expand "log2df2"
16507 [(set (match_dup 2)
16508 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16509 (parallel [(set (match_dup 4)
16510 (unspec:XF [(match_dup 2)
16511 (match_dup 3)] UNSPEC_FYL2X))
16512 (clobber (match_scratch:XF 5 ""))])
16513 (set (match_operand:DF 0 "register_operand" "")
16514 (float_truncate:DF (match_dup 4)))]
16515 "TARGET_USE_FANCY_MATH_387
16516 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16517 && flag_unsafe_math_optimizations"
16519 operands[2] = gen_reg_rtx (XFmode);
16520 operands[3] = gen_reg_rtx (XFmode);
16521 operands[4] = gen_reg_rtx (XFmode);
16523 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16526 (define_expand "log2xf2"
16527 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16528 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16529 (match_dup 2)] UNSPEC_FYL2X))
16530 (clobber (match_scratch:XF 3 ""))])]
16531 "TARGET_USE_FANCY_MATH_387
16532 && flag_unsafe_math_optimizations"
16534 operands[2] = gen_reg_rtx (XFmode);
16535 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16538 (define_insn "fyl2xp1_xf3"
16539 [(set (match_operand:XF 0 "register_operand" "=f")
16540 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16541 (match_operand:XF 1 "register_operand" "u")]
16543 (clobber (match_scratch:XF 3 "=1"))]
16544 "TARGET_USE_FANCY_MATH_387
16545 && flag_unsafe_math_optimizations"
16547 [(set_attr "type" "fpspc")
16548 (set_attr "mode" "XF")])
16550 (define_expand "log1psf2"
16551 [(use (match_operand:SF 0 "register_operand" ""))
16552 (use (match_operand:SF 1 "register_operand" ""))]
16553 "TARGET_USE_FANCY_MATH_387
16554 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16555 && flag_unsafe_math_optimizations && !optimize_size"
16557 rtx op0 = gen_reg_rtx (XFmode);
16558 rtx op1 = gen_reg_rtx (XFmode);
16560 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16561 ix86_emit_i387_log1p (op0, op1);
16562 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16566 (define_expand "log1pdf2"
16567 [(use (match_operand:DF 0 "register_operand" ""))
16568 (use (match_operand:DF 1 "register_operand" ""))]
16569 "TARGET_USE_FANCY_MATH_387
16570 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16571 && flag_unsafe_math_optimizations && !optimize_size"
16573 rtx op0 = gen_reg_rtx (XFmode);
16574 rtx op1 = gen_reg_rtx (XFmode);
16576 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16577 ix86_emit_i387_log1p (op0, op1);
16578 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16582 (define_expand "log1pxf2"
16583 [(use (match_operand:XF 0 "register_operand" ""))
16584 (use (match_operand:XF 1 "register_operand" ""))]
16585 "TARGET_USE_FANCY_MATH_387
16586 && flag_unsafe_math_optimizations && !optimize_size"
16588 ix86_emit_i387_log1p (operands[0], operands[1]);
16592 (define_insn "*fxtractxf3"
16593 [(set (match_operand:XF 0 "register_operand" "=f")
16594 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16595 UNSPEC_XTRACT_FRACT))
16596 (set (match_operand:XF 1 "register_operand" "=u")
16597 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16598 "TARGET_USE_FANCY_MATH_387
16599 && flag_unsafe_math_optimizations"
16601 [(set_attr "type" "fpspc")
16602 (set_attr "mode" "XF")])
16604 (define_expand "logbsf2"
16605 [(set (match_dup 2)
16606 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16607 (parallel [(set (match_dup 3)
16608 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16610 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16611 (set (match_operand:SF 0 "register_operand" "")
16612 (float_truncate:SF (match_dup 4)))]
16613 "TARGET_USE_FANCY_MATH_387
16614 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16615 && flag_unsafe_math_optimizations"
16617 operands[2] = gen_reg_rtx (XFmode);
16618 operands[3] = gen_reg_rtx (XFmode);
16619 operands[4] = gen_reg_rtx (XFmode);
16622 (define_expand "logbdf2"
16623 [(set (match_dup 2)
16624 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16625 (parallel [(set (match_dup 3)
16626 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16628 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16629 (set (match_operand:DF 0 "register_operand" "")
16630 (float_truncate:DF (match_dup 4)))]
16631 "TARGET_USE_FANCY_MATH_387
16632 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16633 && flag_unsafe_math_optimizations"
16635 operands[2] = gen_reg_rtx (XFmode);
16636 operands[3] = gen_reg_rtx (XFmode);
16637 operands[4] = gen_reg_rtx (XFmode);
16640 (define_expand "logbxf2"
16641 [(parallel [(set (match_dup 2)
16642 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16643 UNSPEC_XTRACT_FRACT))
16644 (set (match_operand:XF 0 "register_operand" "")
16645 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16646 "TARGET_USE_FANCY_MATH_387
16647 && flag_unsafe_math_optimizations"
16649 operands[2] = gen_reg_rtx (XFmode);
16652 (define_expand "ilogbsi2"
16653 [(parallel [(set (match_dup 2)
16654 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16655 UNSPEC_XTRACT_FRACT))
16656 (set (match_operand:XF 3 "register_operand" "")
16657 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16658 (parallel [(set (match_operand:SI 0 "register_operand" "")
16659 (fix:SI (match_dup 3)))
16660 (clobber (reg:CC FLAGS_REG))])]
16661 "TARGET_USE_FANCY_MATH_387
16662 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16663 && flag_unsafe_math_optimizations && !optimize_size"
16665 operands[2] = gen_reg_rtx (XFmode);
16666 operands[3] = gen_reg_rtx (XFmode);
16669 (define_insn "*f2xm1xf2"
16670 [(set (match_operand:XF 0 "register_operand" "=f")
16671 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16673 "TARGET_USE_FANCY_MATH_387
16674 && flag_unsafe_math_optimizations"
16676 [(set_attr "type" "fpspc")
16677 (set_attr "mode" "XF")])
16679 (define_insn "*fscalexf4"
16680 [(set (match_operand:XF 0 "register_operand" "=f")
16681 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16682 (match_operand:XF 3 "register_operand" "1")]
16683 UNSPEC_FSCALE_FRACT))
16684 (set (match_operand:XF 1 "register_operand" "=u")
16685 (unspec:XF [(match_dup 2) (match_dup 3)]
16686 UNSPEC_FSCALE_EXP))]
16687 "TARGET_USE_FANCY_MATH_387
16688 && flag_unsafe_math_optimizations"
16690 [(set_attr "type" "fpspc")
16691 (set_attr "mode" "XF")])
16693 (define_expand "expsf2"
16694 [(set (match_dup 2)
16695 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16696 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16697 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16698 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16699 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16700 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16701 (parallel [(set (match_dup 10)
16702 (unspec:XF [(match_dup 9) (match_dup 5)]
16703 UNSPEC_FSCALE_FRACT))
16704 (set (match_dup 11)
16705 (unspec:XF [(match_dup 9) (match_dup 5)]
16706 UNSPEC_FSCALE_EXP))])
16707 (set (match_operand:SF 0 "register_operand" "")
16708 (float_truncate:SF (match_dup 10)))]
16709 "TARGET_USE_FANCY_MATH_387
16710 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16711 && flag_unsafe_math_optimizations && !optimize_size"
16716 for (i=2; i<12; i++)
16717 operands[i] = gen_reg_rtx (XFmode);
16718 temp = standard_80387_constant_rtx (5); /* fldl2e */
16719 emit_move_insn (operands[3], temp);
16720 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16723 (define_expand "expdf2"
16724 [(set (match_dup 2)
16725 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16726 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16727 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16728 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16729 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16730 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16731 (parallel [(set (match_dup 10)
16732 (unspec:XF [(match_dup 9) (match_dup 5)]
16733 UNSPEC_FSCALE_FRACT))
16734 (set (match_dup 11)
16735 (unspec:XF [(match_dup 9) (match_dup 5)]
16736 UNSPEC_FSCALE_EXP))])
16737 (set (match_operand:DF 0 "register_operand" "")
16738 (float_truncate:DF (match_dup 10)))]
16739 "TARGET_USE_FANCY_MATH_387
16740 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16741 && flag_unsafe_math_optimizations && !optimize_size"
16746 for (i=2; i<12; i++)
16747 operands[i] = gen_reg_rtx (XFmode);
16748 temp = standard_80387_constant_rtx (5); /* fldl2e */
16749 emit_move_insn (operands[3], temp);
16750 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16753 (define_expand "expxf2"
16754 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16756 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16757 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16758 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16759 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16760 (parallel [(set (match_operand:XF 0 "register_operand" "")
16761 (unspec:XF [(match_dup 8) (match_dup 4)]
16762 UNSPEC_FSCALE_FRACT))
16764 (unspec:XF [(match_dup 8) (match_dup 4)]
16765 UNSPEC_FSCALE_EXP))])]
16766 "TARGET_USE_FANCY_MATH_387
16767 && flag_unsafe_math_optimizations && !optimize_size"
16772 for (i=2; i<10; i++)
16773 operands[i] = gen_reg_rtx (XFmode);
16774 temp = standard_80387_constant_rtx (5); /* fldl2e */
16775 emit_move_insn (operands[2], temp);
16776 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16779 (define_expand "exp10sf2"
16780 [(set (match_dup 2)
16781 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16782 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16783 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16784 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16785 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16786 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16787 (parallel [(set (match_dup 10)
16788 (unspec:XF [(match_dup 9) (match_dup 5)]
16789 UNSPEC_FSCALE_FRACT))
16790 (set (match_dup 11)
16791 (unspec:XF [(match_dup 9) (match_dup 5)]
16792 UNSPEC_FSCALE_EXP))])
16793 (set (match_operand:SF 0 "register_operand" "")
16794 (float_truncate:SF (match_dup 10)))]
16795 "TARGET_USE_FANCY_MATH_387
16796 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16797 && flag_unsafe_math_optimizations && !optimize_size"
16802 for (i=2; i<12; i++)
16803 operands[i] = gen_reg_rtx (XFmode);
16804 temp = standard_80387_constant_rtx (6); /* fldl2t */
16805 emit_move_insn (operands[3], temp);
16806 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16809 (define_expand "exp10df2"
16810 [(set (match_dup 2)
16811 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16812 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16813 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16814 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16815 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16816 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16817 (parallel [(set (match_dup 10)
16818 (unspec:XF [(match_dup 9) (match_dup 5)]
16819 UNSPEC_FSCALE_FRACT))
16820 (set (match_dup 11)
16821 (unspec:XF [(match_dup 9) (match_dup 5)]
16822 UNSPEC_FSCALE_EXP))])
16823 (set (match_operand:DF 0 "register_operand" "")
16824 (float_truncate:DF (match_dup 10)))]
16825 "TARGET_USE_FANCY_MATH_387
16826 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16827 && flag_unsafe_math_optimizations && !optimize_size"
16832 for (i=2; i<12; i++)
16833 operands[i] = gen_reg_rtx (XFmode);
16834 temp = standard_80387_constant_rtx (6); /* fldl2t */
16835 emit_move_insn (operands[3], temp);
16836 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16839 (define_expand "exp10xf2"
16840 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16842 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16843 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16844 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16845 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16846 (parallel [(set (match_operand:XF 0 "register_operand" "")
16847 (unspec:XF [(match_dup 8) (match_dup 4)]
16848 UNSPEC_FSCALE_FRACT))
16850 (unspec:XF [(match_dup 8) (match_dup 4)]
16851 UNSPEC_FSCALE_EXP))])]
16852 "TARGET_USE_FANCY_MATH_387
16853 && flag_unsafe_math_optimizations && !optimize_size"
16858 for (i=2; i<10; i++)
16859 operands[i] = gen_reg_rtx (XFmode);
16860 temp = standard_80387_constant_rtx (6); /* fldl2t */
16861 emit_move_insn (operands[2], temp);
16862 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16865 (define_expand "exp2sf2"
16866 [(set (match_dup 2)
16867 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16868 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16869 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16870 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16871 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16872 (parallel [(set (match_dup 8)
16873 (unspec:XF [(match_dup 7) (match_dup 3)]
16874 UNSPEC_FSCALE_FRACT))
16876 (unspec:XF [(match_dup 7) (match_dup 3)]
16877 UNSPEC_FSCALE_EXP))])
16878 (set (match_operand:SF 0 "register_operand" "")
16879 (float_truncate:SF (match_dup 8)))]
16880 "TARGET_USE_FANCY_MATH_387
16881 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16882 && flag_unsafe_math_optimizations && !optimize_size"
16886 for (i=2; i<10; i++)
16887 operands[i] = gen_reg_rtx (XFmode);
16888 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16891 (define_expand "exp2df2"
16892 [(set (match_dup 2)
16893 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16894 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16895 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16896 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16897 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16898 (parallel [(set (match_dup 8)
16899 (unspec:XF [(match_dup 7) (match_dup 3)]
16900 UNSPEC_FSCALE_FRACT))
16902 (unspec:XF [(match_dup 7) (match_dup 3)]
16903 UNSPEC_FSCALE_EXP))])
16904 (set (match_operand:DF 0 "register_operand" "")
16905 (float_truncate:DF (match_dup 8)))]
16906 "TARGET_USE_FANCY_MATH_387
16907 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16908 && flag_unsafe_math_optimizations && !optimize_size"
16912 for (i=2; i<10; i++)
16913 operands[i] = gen_reg_rtx (XFmode);
16914 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16917 (define_expand "exp2xf2"
16918 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16919 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16920 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16921 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16922 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16923 (parallel [(set (match_operand:XF 0 "register_operand" "")
16924 (unspec:XF [(match_dup 7) (match_dup 3)]
16925 UNSPEC_FSCALE_FRACT))
16927 (unspec:XF [(match_dup 7) (match_dup 3)]
16928 UNSPEC_FSCALE_EXP))])]
16929 "TARGET_USE_FANCY_MATH_387
16930 && flag_unsafe_math_optimizations && !optimize_size"
16934 for (i=2; i<9; i++)
16935 operands[i] = gen_reg_rtx (XFmode);
16936 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16939 (define_expand "expm1df2"
16940 [(set (match_dup 2)
16941 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16942 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16943 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16944 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16945 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16946 (parallel [(set (match_dup 8)
16947 (unspec:XF [(match_dup 7) (match_dup 5)]
16948 UNSPEC_FSCALE_FRACT))
16950 (unspec:XF [(match_dup 7) (match_dup 5)]
16951 UNSPEC_FSCALE_EXP))])
16952 (parallel [(set (match_dup 11)
16953 (unspec:XF [(match_dup 10) (match_dup 9)]
16954 UNSPEC_FSCALE_FRACT))
16955 (set (match_dup 12)
16956 (unspec:XF [(match_dup 10) (match_dup 9)]
16957 UNSPEC_FSCALE_EXP))])
16958 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16959 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16960 (set (match_operand:DF 0 "register_operand" "")
16961 (float_truncate:DF (match_dup 14)))]
16962 "TARGET_USE_FANCY_MATH_387
16963 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16964 && flag_unsafe_math_optimizations && !optimize_size"
16969 for (i=2; i<15; i++)
16970 operands[i] = gen_reg_rtx (XFmode);
16971 temp = standard_80387_constant_rtx (5); /* fldl2e */
16972 emit_move_insn (operands[3], temp);
16973 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16976 (define_expand "expm1sf2"
16977 [(set (match_dup 2)
16978 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16979 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16980 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16981 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16982 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16983 (parallel [(set (match_dup 8)
16984 (unspec:XF [(match_dup 7) (match_dup 5)]
16985 UNSPEC_FSCALE_FRACT))
16987 (unspec:XF [(match_dup 7) (match_dup 5)]
16988 UNSPEC_FSCALE_EXP))])
16989 (parallel [(set (match_dup 11)
16990 (unspec:XF [(match_dup 10) (match_dup 9)]
16991 UNSPEC_FSCALE_FRACT))
16992 (set (match_dup 12)
16993 (unspec:XF [(match_dup 10) (match_dup 9)]
16994 UNSPEC_FSCALE_EXP))])
16995 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16996 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16997 (set (match_operand:SF 0 "register_operand" "")
16998 (float_truncate:SF (match_dup 14)))]
16999 "TARGET_USE_FANCY_MATH_387
17000 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17001 && flag_unsafe_math_optimizations && !optimize_size"
17006 for (i=2; i<15; i++)
17007 operands[i] = gen_reg_rtx (XFmode);
17008 temp = standard_80387_constant_rtx (5); /* fldl2e */
17009 emit_move_insn (operands[3], temp);
17010 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
17013 (define_expand "expm1xf2"
17014 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17016 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17017 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17018 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17019 (parallel [(set (match_dup 7)
17020 (unspec:XF [(match_dup 6) (match_dup 4)]
17021 UNSPEC_FSCALE_FRACT))
17023 (unspec:XF [(match_dup 6) (match_dup 4)]
17024 UNSPEC_FSCALE_EXP))])
17025 (parallel [(set (match_dup 10)
17026 (unspec:XF [(match_dup 9) (match_dup 8)]
17027 UNSPEC_FSCALE_FRACT))
17028 (set (match_dup 11)
17029 (unspec:XF [(match_dup 9) (match_dup 8)]
17030 UNSPEC_FSCALE_EXP))])
17031 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17032 (set (match_operand:XF 0 "register_operand" "")
17033 (plus:XF (match_dup 12) (match_dup 7)))]
17034 "TARGET_USE_FANCY_MATH_387
17035 && flag_unsafe_math_optimizations && !optimize_size"
17040 for (i=2; i<13; i++)
17041 operands[i] = gen_reg_rtx (XFmode);
17042 temp = standard_80387_constant_rtx (5); /* fldl2e */
17043 emit_move_insn (operands[2], temp);
17044 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17047 (define_expand "ldexpdf3"
17048 [(set (match_dup 3)
17049 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17051 (float:XF (match_operand:SI 2 "register_operand" "")))
17052 (parallel [(set (match_dup 5)
17053 (unspec:XF [(match_dup 3) (match_dup 4)]
17054 UNSPEC_FSCALE_FRACT))
17056 (unspec:XF [(match_dup 3) (match_dup 4)]
17057 UNSPEC_FSCALE_EXP))])
17058 (set (match_operand:DF 0 "register_operand" "")
17059 (float_truncate:DF (match_dup 5)))]
17060 "TARGET_USE_FANCY_MATH_387
17061 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17062 && flag_unsafe_math_optimizations && !optimize_size"
17066 for (i=3; i<7; i++)
17067 operands[i] = gen_reg_rtx (XFmode);
17070 (define_expand "ldexpsf3"
17071 [(set (match_dup 3)
17072 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
17074 (float:XF (match_operand:SI 2 "register_operand" "")))
17075 (parallel [(set (match_dup 5)
17076 (unspec:XF [(match_dup 3) (match_dup 4)]
17077 UNSPEC_FSCALE_FRACT))
17079 (unspec:XF [(match_dup 3) (match_dup 4)]
17080 UNSPEC_FSCALE_EXP))])
17081 (set (match_operand:SF 0 "register_operand" "")
17082 (float_truncate:SF (match_dup 5)))]
17083 "TARGET_USE_FANCY_MATH_387
17084 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17085 && flag_unsafe_math_optimizations && !optimize_size"
17089 for (i=3; i<7; i++)
17090 operands[i] = gen_reg_rtx (XFmode);
17093 (define_expand "ldexpxf3"
17094 [(set (match_dup 3)
17095 (float:XF (match_operand:SI 2 "register_operand" "")))
17096 (parallel [(set (match_operand:XF 0 " register_operand" "")
17097 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17099 UNSPEC_FSCALE_FRACT))
17101 (unspec:XF [(match_dup 1) (match_dup 3)]
17102 UNSPEC_FSCALE_EXP))])]
17103 "TARGET_USE_FANCY_MATH_387
17104 && flag_unsafe_math_optimizations && !optimize_size"
17108 for (i=3; i<5; i++)
17109 operands[i] = gen_reg_rtx (XFmode);
17113 (define_insn "frndintxf2"
17114 [(set (match_operand:XF 0 "register_operand" "=f")
17115 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17117 "TARGET_USE_FANCY_MATH_387
17118 && flag_unsafe_math_optimizations"
17120 [(set_attr "type" "fpspc")
17121 (set_attr "mode" "XF")])
17123 (define_expand "rintdf2"
17124 [(use (match_operand:DF 0 "register_operand" ""))
17125 (use (match_operand:DF 1 "register_operand" ""))]
17126 "(TARGET_USE_FANCY_MATH_387
17127 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17128 && flag_unsafe_math_optimizations)
17129 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17130 && !flag_trapping_math
17131 && !optimize_size)"
17133 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17134 && !flag_trapping_math
17136 ix86_expand_rint (operand0, operand1);
17139 rtx op0 = gen_reg_rtx (XFmode);
17140 rtx op1 = gen_reg_rtx (XFmode);
17142 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17143 emit_insn (gen_frndintxf2 (op0, op1));
17145 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17150 (define_expand "rintsf2"
17151 [(use (match_operand:SF 0 "register_operand" ""))
17152 (use (match_operand:SF 1 "register_operand" ""))]
17153 "(TARGET_USE_FANCY_MATH_387
17154 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17155 && flag_unsafe_math_optimizations)
17156 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17157 && !flag_trapping_math
17158 && !optimize_size)"
17160 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17161 && !flag_trapping_math
17163 ix86_expand_rint (operand0, operand1);
17166 rtx op0 = gen_reg_rtx (XFmode);
17167 rtx op1 = gen_reg_rtx (XFmode);
17169 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17170 emit_insn (gen_frndintxf2 (op0, op1));
17172 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17177 (define_expand "rintxf2"
17178 [(use (match_operand:XF 0 "register_operand" ""))
17179 (use (match_operand:XF 1 "register_operand" ""))]
17180 "TARGET_USE_FANCY_MATH_387
17181 && flag_unsafe_math_optimizations && !optimize_size"
17183 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17187 (define_expand "roundsf2"
17188 [(match_operand:SF 0 "register_operand" "")
17189 (match_operand:SF 1 "nonimmediate_operand" "")]
17190 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17191 && !flag_trapping_math && !flag_rounding_math
17194 ix86_expand_round (operand0, operand1);
17198 (define_expand "rounddf2"
17199 [(match_operand:DF 0 "register_operand" "")
17200 (match_operand:DF 1 "nonimmediate_operand" "")]
17201 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17202 && !flag_trapping_math && !flag_rounding_math
17206 ix86_expand_round (operand0, operand1);
17208 ix86_expand_rounddf_32 (operand0, operand1);
17212 (define_insn_and_split "*fistdi2_1"
17213 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17214 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17216 "TARGET_USE_FANCY_MATH_387
17217 && !(reload_completed || reload_in_progress)"
17222 if (memory_operand (operands[0], VOIDmode))
17223 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17226 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17227 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17232 [(set_attr "type" "fpspc")
17233 (set_attr "mode" "DI")])
17235 (define_insn "fistdi2"
17236 [(set (match_operand:DI 0 "memory_operand" "=m")
17237 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17239 (clobber (match_scratch:XF 2 "=&1f"))]
17240 "TARGET_USE_FANCY_MATH_387"
17241 "* return output_fix_trunc (insn, operands, 0);"
17242 [(set_attr "type" "fpspc")
17243 (set_attr "mode" "DI")])
17245 (define_insn "fistdi2_with_temp"
17246 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17247 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17249 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17250 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17251 "TARGET_USE_FANCY_MATH_387"
17253 [(set_attr "type" "fpspc")
17254 (set_attr "mode" "DI")])
17257 [(set (match_operand:DI 0 "register_operand" "")
17258 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17260 (clobber (match_operand:DI 2 "memory_operand" ""))
17261 (clobber (match_scratch 3 ""))]
17263 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17264 (clobber (match_dup 3))])
17265 (set (match_dup 0) (match_dup 2))]
17269 [(set (match_operand:DI 0 "memory_operand" "")
17270 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17272 (clobber (match_operand:DI 2 "memory_operand" ""))
17273 (clobber (match_scratch 3 ""))]
17275 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17276 (clobber (match_dup 3))])]
17279 (define_insn_and_split "*fist<mode>2_1"
17280 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17281 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17283 "TARGET_USE_FANCY_MATH_387
17284 && !(reload_completed || reload_in_progress)"
17289 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17290 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17294 [(set_attr "type" "fpspc")
17295 (set_attr "mode" "<MODE>")])
17297 (define_insn "fist<mode>2"
17298 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17299 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17301 "TARGET_USE_FANCY_MATH_387"
17302 "* return output_fix_trunc (insn, operands, 0);"
17303 [(set_attr "type" "fpspc")
17304 (set_attr "mode" "<MODE>")])
17306 (define_insn "fist<mode>2_with_temp"
17307 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17308 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17310 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17311 "TARGET_USE_FANCY_MATH_387"
17313 [(set_attr "type" "fpspc")
17314 (set_attr "mode" "<MODE>")])
17317 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17318 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17320 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17322 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17324 (set (match_dup 0) (match_dup 2))]
17328 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17329 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17331 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17333 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17337 (define_expand "lrintxf<mode>2"
17338 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17339 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17341 "TARGET_USE_FANCY_MATH_387"
17344 (define_expand "lrint<mode>di2"
17345 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17346 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17347 UNSPEC_FIX_NOTRUNC))]
17348 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17351 (define_expand "lrint<mode>si2"
17352 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17353 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17354 UNSPEC_FIX_NOTRUNC))]
17355 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17358 (define_expand "lround<mode>di2"
17359 [(match_operand:DI 0 "nonimmediate_operand" "")
17360 (match_operand:SSEMODEF 1 "register_operand" "")]
17361 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17362 && !flag_trapping_math && !flag_rounding_math
17365 ix86_expand_lround (operand0, operand1);
17369 (define_expand "lround<mode>si2"
17370 [(match_operand:SI 0 "nonimmediate_operand" "")
17371 (match_operand:SSEMODEF 1 "register_operand" "")]
17372 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17373 && !flag_trapping_math && !flag_rounding_math
17376 ix86_expand_lround (operand0, operand1);
17380 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17381 (define_insn_and_split "frndintxf2_floor"
17382 [(set (match_operand:XF 0 "register_operand" "=f")
17383 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17384 UNSPEC_FRNDINT_FLOOR))
17385 (clobber (reg:CC FLAGS_REG))]
17386 "TARGET_USE_FANCY_MATH_387
17387 && flag_unsafe_math_optimizations
17388 && !(reload_completed || reload_in_progress)"
17393 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17395 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17396 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17398 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17399 operands[2], operands[3]));
17402 [(set_attr "type" "frndint")
17403 (set_attr "i387_cw" "floor")
17404 (set_attr "mode" "XF")])
17406 (define_insn "frndintxf2_floor_i387"
17407 [(set (match_operand:XF 0 "register_operand" "=f")
17408 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17409 UNSPEC_FRNDINT_FLOOR))
17410 (use (match_operand:HI 2 "memory_operand" "m"))
17411 (use (match_operand:HI 3 "memory_operand" "m"))]
17412 "TARGET_USE_FANCY_MATH_387
17413 && flag_unsafe_math_optimizations"
17414 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17415 [(set_attr "type" "frndint")
17416 (set_attr "i387_cw" "floor")
17417 (set_attr "mode" "XF")])
17419 (define_expand "floorxf2"
17420 [(use (match_operand:XF 0 "register_operand" ""))
17421 (use (match_operand:XF 1 "register_operand" ""))]
17422 "TARGET_USE_FANCY_MATH_387
17423 && flag_unsafe_math_optimizations && !optimize_size"
17425 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17429 (define_expand "floordf2"
17430 [(use (match_operand:DF 0 "register_operand" ""))
17431 (use (match_operand:DF 1 "register_operand" ""))]
17432 "((TARGET_USE_FANCY_MATH_387
17433 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17434 && flag_unsafe_math_optimizations)
17435 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17436 && !flag_trapping_math))
17439 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17440 && !flag_trapping_math)
17443 ix86_expand_floorceil (operand0, operand1, true);
17445 ix86_expand_floorceildf_32 (operand0, operand1, true);
17449 rtx op0 = gen_reg_rtx (XFmode);
17450 rtx op1 = gen_reg_rtx (XFmode);
17452 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17453 emit_insn (gen_frndintxf2_floor (op0, op1));
17455 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17460 (define_expand "floorsf2"
17461 [(use (match_operand:SF 0 "register_operand" ""))
17462 (use (match_operand:SF 1 "register_operand" ""))]
17463 "((TARGET_USE_FANCY_MATH_387
17464 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17465 && flag_unsafe_math_optimizations)
17466 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17467 && !flag_trapping_math))
17470 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17471 && !flag_trapping_math)
17472 ix86_expand_floorceil (operand0, operand1, true);
17475 rtx op0 = gen_reg_rtx (XFmode);
17476 rtx op1 = gen_reg_rtx (XFmode);
17478 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17479 emit_insn (gen_frndintxf2_floor (op0, op1));
17481 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17486 (define_insn_and_split "*fist<mode>2_floor_1"
17487 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17488 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17489 UNSPEC_FIST_FLOOR))
17490 (clobber (reg:CC FLAGS_REG))]
17491 "TARGET_USE_FANCY_MATH_387
17492 && flag_unsafe_math_optimizations
17493 && !(reload_completed || reload_in_progress)"
17498 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17500 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17501 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17502 if (memory_operand (operands[0], VOIDmode))
17503 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17504 operands[2], operands[3]));
17507 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17508 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17509 operands[2], operands[3],
17514 [(set_attr "type" "fistp")
17515 (set_attr "i387_cw" "floor")
17516 (set_attr "mode" "<MODE>")])
17518 (define_insn "fistdi2_floor"
17519 [(set (match_operand:DI 0 "memory_operand" "=m")
17520 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17521 UNSPEC_FIST_FLOOR))
17522 (use (match_operand:HI 2 "memory_operand" "m"))
17523 (use (match_operand:HI 3 "memory_operand" "m"))
17524 (clobber (match_scratch:XF 4 "=&1f"))]
17525 "TARGET_USE_FANCY_MATH_387
17526 && flag_unsafe_math_optimizations"
17527 "* return output_fix_trunc (insn, operands, 0);"
17528 [(set_attr "type" "fistp")
17529 (set_attr "i387_cw" "floor")
17530 (set_attr "mode" "DI")])
17532 (define_insn "fistdi2_floor_with_temp"
17533 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17534 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17535 UNSPEC_FIST_FLOOR))
17536 (use (match_operand:HI 2 "memory_operand" "m,m"))
17537 (use (match_operand:HI 3 "memory_operand" "m,m"))
17538 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17539 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17540 "TARGET_USE_FANCY_MATH_387
17541 && flag_unsafe_math_optimizations"
17543 [(set_attr "type" "fistp")
17544 (set_attr "i387_cw" "floor")
17545 (set_attr "mode" "DI")])
17548 [(set (match_operand:DI 0 "register_operand" "")
17549 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17550 UNSPEC_FIST_FLOOR))
17551 (use (match_operand:HI 2 "memory_operand" ""))
17552 (use (match_operand:HI 3 "memory_operand" ""))
17553 (clobber (match_operand:DI 4 "memory_operand" ""))
17554 (clobber (match_scratch 5 ""))]
17556 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17557 (use (match_dup 2))
17558 (use (match_dup 3))
17559 (clobber (match_dup 5))])
17560 (set (match_dup 0) (match_dup 4))]
17564 [(set (match_operand:DI 0 "memory_operand" "")
17565 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17566 UNSPEC_FIST_FLOOR))
17567 (use (match_operand:HI 2 "memory_operand" ""))
17568 (use (match_operand:HI 3 "memory_operand" ""))
17569 (clobber (match_operand:DI 4 "memory_operand" ""))
17570 (clobber (match_scratch 5 ""))]
17572 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17573 (use (match_dup 2))
17574 (use (match_dup 3))
17575 (clobber (match_dup 5))])]
17578 (define_insn "fist<mode>2_floor"
17579 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17580 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17581 UNSPEC_FIST_FLOOR))
17582 (use (match_operand:HI 2 "memory_operand" "m"))
17583 (use (match_operand:HI 3 "memory_operand" "m"))]
17584 "TARGET_USE_FANCY_MATH_387
17585 && flag_unsafe_math_optimizations"
17586 "* return output_fix_trunc (insn, operands, 0);"
17587 [(set_attr "type" "fistp")
17588 (set_attr "i387_cw" "floor")
17589 (set_attr "mode" "<MODE>")])
17591 (define_insn "fist<mode>2_floor_with_temp"
17592 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17593 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17594 UNSPEC_FIST_FLOOR))
17595 (use (match_operand:HI 2 "memory_operand" "m,m"))
17596 (use (match_operand:HI 3 "memory_operand" "m,m"))
17597 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17598 "TARGET_USE_FANCY_MATH_387
17599 && flag_unsafe_math_optimizations"
17601 [(set_attr "type" "fistp")
17602 (set_attr "i387_cw" "floor")
17603 (set_attr "mode" "<MODE>")])
17606 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17607 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17608 UNSPEC_FIST_FLOOR))
17609 (use (match_operand:HI 2 "memory_operand" ""))
17610 (use (match_operand:HI 3 "memory_operand" ""))
17611 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17613 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17614 UNSPEC_FIST_FLOOR))
17615 (use (match_dup 2))
17616 (use (match_dup 3))])
17617 (set (match_dup 0) (match_dup 4))]
17621 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17622 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17623 UNSPEC_FIST_FLOOR))
17624 (use (match_operand:HI 2 "memory_operand" ""))
17625 (use (match_operand:HI 3 "memory_operand" ""))
17626 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17628 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17629 UNSPEC_FIST_FLOOR))
17630 (use (match_dup 2))
17631 (use (match_dup 3))])]
17634 (define_expand "lfloorxf<mode>2"
17635 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17636 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17637 UNSPEC_FIST_FLOOR))
17638 (clobber (reg:CC FLAGS_REG))])]
17639 "TARGET_USE_FANCY_MATH_387
17640 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17641 && flag_unsafe_math_optimizations"
17644 (define_expand "lfloor<mode>di2"
17645 [(match_operand:DI 0 "nonimmediate_operand" "")
17646 (match_operand:SSEMODEF 1 "register_operand" "")]
17647 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17648 && !flag_trapping_math
17651 ix86_expand_lfloorceil (operand0, operand1, true);
17655 (define_expand "lfloor<mode>si2"
17656 [(match_operand:SI 0 "nonimmediate_operand" "")
17657 (match_operand:SSEMODEF 1 "register_operand" "")]
17658 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17659 && !flag_trapping_math
17660 && (!optimize_size || !TARGET_64BIT)"
17662 ix86_expand_lfloorceil (operand0, operand1, true);
17666 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17667 (define_insn_and_split "frndintxf2_ceil"
17668 [(set (match_operand:XF 0 "register_operand" "=f")
17669 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17670 UNSPEC_FRNDINT_CEIL))
17671 (clobber (reg:CC FLAGS_REG))]
17672 "TARGET_USE_FANCY_MATH_387
17673 && flag_unsafe_math_optimizations
17674 && !(reload_completed || reload_in_progress)"
17679 ix86_optimize_mode_switching[I387_CEIL] = 1;
17681 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17682 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17684 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17685 operands[2], operands[3]));
17688 [(set_attr "type" "frndint")
17689 (set_attr "i387_cw" "ceil")
17690 (set_attr "mode" "XF")])
17692 (define_insn "frndintxf2_ceil_i387"
17693 [(set (match_operand:XF 0 "register_operand" "=f")
17694 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17695 UNSPEC_FRNDINT_CEIL))
17696 (use (match_operand:HI 2 "memory_operand" "m"))
17697 (use (match_operand:HI 3 "memory_operand" "m"))]
17698 "TARGET_USE_FANCY_MATH_387
17699 && flag_unsafe_math_optimizations"
17700 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17701 [(set_attr "type" "frndint")
17702 (set_attr "i387_cw" "ceil")
17703 (set_attr "mode" "XF")])
17705 (define_expand "ceilxf2"
17706 [(use (match_operand:XF 0 "register_operand" ""))
17707 (use (match_operand:XF 1 "register_operand" ""))]
17708 "TARGET_USE_FANCY_MATH_387
17709 && flag_unsafe_math_optimizations && !optimize_size"
17711 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17715 (define_expand "ceildf2"
17716 [(use (match_operand:DF 0 "register_operand" ""))
17717 (use (match_operand:DF 1 "register_operand" ""))]
17718 "((TARGET_USE_FANCY_MATH_387
17719 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17720 && flag_unsafe_math_optimizations)
17721 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17722 && !flag_trapping_math))
17725 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17726 && !flag_trapping_math)
17729 ix86_expand_floorceil (operand0, operand1, false);
17731 ix86_expand_floorceildf_32 (operand0, operand1, false);
17735 rtx op0 = gen_reg_rtx (XFmode);
17736 rtx op1 = gen_reg_rtx (XFmode);
17738 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17739 emit_insn (gen_frndintxf2_ceil (op0, op1));
17741 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17746 (define_expand "ceilsf2"
17747 [(use (match_operand:SF 0 "register_operand" ""))
17748 (use (match_operand:SF 1 "register_operand" ""))]
17749 "((TARGET_USE_FANCY_MATH_387
17750 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17751 && flag_unsafe_math_optimizations)
17752 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17753 && !flag_trapping_math))
17756 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17757 && !flag_trapping_math)
17758 ix86_expand_floorceil (operand0, operand1, false);
17761 rtx op0 = gen_reg_rtx (XFmode);
17762 rtx op1 = gen_reg_rtx (XFmode);
17764 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17765 emit_insn (gen_frndintxf2_ceil (op0, op1));
17767 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17772 (define_insn_and_split "*fist<mode>2_ceil_1"
17773 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17774 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17776 (clobber (reg:CC FLAGS_REG))]
17777 "TARGET_USE_FANCY_MATH_387
17778 && flag_unsafe_math_optimizations
17779 && !(reload_completed || reload_in_progress)"
17784 ix86_optimize_mode_switching[I387_CEIL] = 1;
17786 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17787 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17788 if (memory_operand (operands[0], VOIDmode))
17789 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17790 operands[2], operands[3]));
17793 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17794 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17795 operands[2], operands[3],
17800 [(set_attr "type" "fistp")
17801 (set_attr "i387_cw" "ceil")
17802 (set_attr "mode" "<MODE>")])
17804 (define_insn "fistdi2_ceil"
17805 [(set (match_operand:DI 0 "memory_operand" "=m")
17806 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17808 (use (match_operand:HI 2 "memory_operand" "m"))
17809 (use (match_operand:HI 3 "memory_operand" "m"))
17810 (clobber (match_scratch:XF 4 "=&1f"))]
17811 "TARGET_USE_FANCY_MATH_387
17812 && flag_unsafe_math_optimizations"
17813 "* return output_fix_trunc (insn, operands, 0);"
17814 [(set_attr "type" "fistp")
17815 (set_attr "i387_cw" "ceil")
17816 (set_attr "mode" "DI")])
17818 (define_insn "fistdi2_ceil_with_temp"
17819 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17820 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17822 (use (match_operand:HI 2 "memory_operand" "m,m"))
17823 (use (match_operand:HI 3 "memory_operand" "m,m"))
17824 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17825 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17826 "TARGET_USE_FANCY_MATH_387
17827 && flag_unsafe_math_optimizations"
17829 [(set_attr "type" "fistp")
17830 (set_attr "i387_cw" "ceil")
17831 (set_attr "mode" "DI")])
17834 [(set (match_operand:DI 0 "register_operand" "")
17835 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17837 (use (match_operand:HI 2 "memory_operand" ""))
17838 (use (match_operand:HI 3 "memory_operand" ""))
17839 (clobber (match_operand:DI 4 "memory_operand" ""))
17840 (clobber (match_scratch 5 ""))]
17842 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17843 (use (match_dup 2))
17844 (use (match_dup 3))
17845 (clobber (match_dup 5))])
17846 (set (match_dup 0) (match_dup 4))]
17850 [(set (match_operand:DI 0 "memory_operand" "")
17851 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17853 (use (match_operand:HI 2 "memory_operand" ""))
17854 (use (match_operand:HI 3 "memory_operand" ""))
17855 (clobber (match_operand:DI 4 "memory_operand" ""))
17856 (clobber (match_scratch 5 ""))]
17858 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17859 (use (match_dup 2))
17860 (use (match_dup 3))
17861 (clobber (match_dup 5))])]
17864 (define_insn "fist<mode>2_ceil"
17865 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17866 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17868 (use (match_operand:HI 2 "memory_operand" "m"))
17869 (use (match_operand:HI 3 "memory_operand" "m"))]
17870 "TARGET_USE_FANCY_MATH_387
17871 && flag_unsafe_math_optimizations"
17872 "* return output_fix_trunc (insn, operands, 0);"
17873 [(set_attr "type" "fistp")
17874 (set_attr "i387_cw" "ceil")
17875 (set_attr "mode" "<MODE>")])
17877 (define_insn "fist<mode>2_ceil_with_temp"
17878 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17879 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17881 (use (match_operand:HI 2 "memory_operand" "m,m"))
17882 (use (match_operand:HI 3 "memory_operand" "m,m"))
17883 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17884 "TARGET_USE_FANCY_MATH_387
17885 && flag_unsafe_math_optimizations"
17887 [(set_attr "type" "fistp")
17888 (set_attr "i387_cw" "ceil")
17889 (set_attr "mode" "<MODE>")])
17892 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17893 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17895 (use (match_operand:HI 2 "memory_operand" ""))
17896 (use (match_operand:HI 3 "memory_operand" ""))
17897 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17899 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17901 (use (match_dup 2))
17902 (use (match_dup 3))])
17903 (set (match_dup 0) (match_dup 4))]
17907 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17908 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17910 (use (match_operand:HI 2 "memory_operand" ""))
17911 (use (match_operand:HI 3 "memory_operand" ""))
17912 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17914 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17916 (use (match_dup 2))
17917 (use (match_dup 3))])]
17920 (define_expand "lceilxf<mode>2"
17921 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17922 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17924 (clobber (reg:CC FLAGS_REG))])]
17925 "TARGET_USE_FANCY_MATH_387
17926 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17927 && flag_unsafe_math_optimizations"
17930 (define_expand "lceil<mode>di2"
17931 [(match_operand:DI 0 "nonimmediate_operand" "")
17932 (match_operand:SSEMODEF 1 "register_operand" "")]
17933 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17934 && !flag_trapping_math"
17936 ix86_expand_lfloorceil (operand0, operand1, false);
17940 (define_expand "lceil<mode>si2"
17941 [(match_operand:SI 0 "nonimmediate_operand" "")
17942 (match_operand:SSEMODEF 1 "register_operand" "")]
17943 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17944 && !flag_trapping_math"
17946 ix86_expand_lfloorceil (operand0, operand1, false);
17950 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17951 (define_insn_and_split "frndintxf2_trunc"
17952 [(set (match_operand:XF 0 "register_operand" "=f")
17953 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17954 UNSPEC_FRNDINT_TRUNC))
17955 (clobber (reg:CC FLAGS_REG))]
17956 "TARGET_USE_FANCY_MATH_387
17957 && flag_unsafe_math_optimizations
17958 && !(reload_completed || reload_in_progress)"
17963 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17965 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17966 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17968 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17969 operands[2], operands[3]));
17972 [(set_attr "type" "frndint")
17973 (set_attr "i387_cw" "trunc")
17974 (set_attr "mode" "XF")])
17976 (define_insn "frndintxf2_trunc_i387"
17977 [(set (match_operand:XF 0 "register_operand" "=f")
17978 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17979 UNSPEC_FRNDINT_TRUNC))
17980 (use (match_operand:HI 2 "memory_operand" "m"))
17981 (use (match_operand:HI 3 "memory_operand" "m"))]
17982 "TARGET_USE_FANCY_MATH_387
17983 && flag_unsafe_math_optimizations"
17984 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17985 [(set_attr "type" "frndint")
17986 (set_attr "i387_cw" "trunc")
17987 (set_attr "mode" "XF")])
17989 (define_expand "btruncxf2"
17990 [(use (match_operand:XF 0 "register_operand" ""))
17991 (use (match_operand:XF 1 "register_operand" ""))]
17992 "TARGET_USE_FANCY_MATH_387
17993 && flag_unsafe_math_optimizations && !optimize_size"
17995 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17999 (define_expand "btruncdf2"
18000 [(use (match_operand:DF 0 "register_operand" ""))
18001 (use (match_operand:DF 1 "register_operand" ""))]
18002 "((TARGET_USE_FANCY_MATH_387
18003 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18004 && flag_unsafe_math_optimizations)
18005 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18006 && !flag_trapping_math))
18009 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
18010 && !flag_trapping_math)
18013 ix86_expand_trunc (operand0, operand1);
18015 ix86_expand_truncdf_32 (operand0, operand1);
18019 rtx op0 = gen_reg_rtx (XFmode);
18020 rtx op1 = gen_reg_rtx (XFmode);
18022 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18023 emit_insn (gen_frndintxf2_trunc (op0, op1));
18025 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18030 (define_expand "btruncsf2"
18031 [(use (match_operand:SF 0 "register_operand" ""))
18032 (use (match_operand:SF 1 "register_operand" ""))]
18033 "((TARGET_USE_FANCY_MATH_387
18034 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18035 && flag_unsafe_math_optimizations)
18036 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18037 && !flag_trapping_math))
18040 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18041 && !flag_trapping_math)
18042 ix86_expand_trunc (operand0, operand1);
18045 rtx op0 = gen_reg_rtx (XFmode);
18046 rtx op1 = gen_reg_rtx (XFmode);
18048 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18049 emit_insn (gen_frndintxf2_trunc (op0, op1));
18051 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18056 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18057 (define_insn_and_split "frndintxf2_mask_pm"
18058 [(set (match_operand:XF 0 "register_operand" "=f")
18059 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18060 UNSPEC_FRNDINT_MASK_PM))
18061 (clobber (reg:CC FLAGS_REG))]
18062 "TARGET_USE_FANCY_MATH_387
18063 && flag_unsafe_math_optimizations
18064 && !(reload_completed || reload_in_progress)"
18069 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18071 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18072 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18074 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18075 operands[2], operands[3]));
18078 [(set_attr "type" "frndint")
18079 (set_attr "i387_cw" "mask_pm")
18080 (set_attr "mode" "XF")])
18082 (define_insn "frndintxf2_mask_pm_i387"
18083 [(set (match_operand:XF 0 "register_operand" "=f")
18084 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18085 UNSPEC_FRNDINT_MASK_PM))
18086 (use (match_operand:HI 2 "memory_operand" "m"))
18087 (use (match_operand:HI 3 "memory_operand" "m"))]
18088 "TARGET_USE_FANCY_MATH_387
18089 && flag_unsafe_math_optimizations"
18090 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18091 [(set_attr "type" "frndint")
18092 (set_attr "i387_cw" "mask_pm")
18093 (set_attr "mode" "XF")])
18095 (define_expand "nearbyintxf2"
18096 [(use (match_operand:XF 0 "register_operand" ""))
18097 (use (match_operand:XF 1 "register_operand" ""))]
18098 "TARGET_USE_FANCY_MATH_387
18099 && flag_unsafe_math_optimizations"
18101 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18106 (define_expand "nearbyintdf2"
18107 [(use (match_operand:DF 0 "register_operand" ""))
18108 (use (match_operand:DF 1 "register_operand" ""))]
18109 "TARGET_USE_FANCY_MATH_387
18110 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18111 && flag_unsafe_math_optimizations"
18113 rtx op0 = gen_reg_rtx (XFmode);
18114 rtx op1 = gen_reg_rtx (XFmode);
18116 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18117 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18119 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18123 (define_expand "nearbyintsf2"
18124 [(use (match_operand:SF 0 "register_operand" ""))
18125 (use (match_operand:SF 1 "register_operand" ""))]
18126 "TARGET_USE_FANCY_MATH_387
18127 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18128 && flag_unsafe_math_optimizations"
18130 rtx op0 = gen_reg_rtx (XFmode);
18131 rtx op1 = gen_reg_rtx (XFmode);
18133 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18134 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18136 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18141 ;; Block operation instructions
18143 (define_expand "movmemsi"
18144 [(use (match_operand:BLK 0 "memory_operand" ""))
18145 (use (match_operand:BLK 1 "memory_operand" ""))
18146 (use (match_operand:SI 2 "nonmemory_operand" ""))
18147 (use (match_operand:SI 3 "const_int_operand" ""))]
18150 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18151 operands[3], constm1_rtx))
18157 (define_expand "movmemdi"
18158 [(use (match_operand:BLK 0 "memory_operand" ""))
18159 (use (match_operand:BLK 1 "memory_operand" ""))
18160 (use (match_operand:DI 2 "nonmemory_operand" ""))
18161 (use (match_operand:DI 3 "const_int_operand" ""))]
18164 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18165 operands[3], constm1_rtx))
18171 ;; Most CPUs don't like single string operations
18172 ;; Handle this case here to simplify previous expander.
18174 (define_expand "strmov"
18175 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18176 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18177 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18178 (clobber (reg:CC FLAGS_REG))])
18179 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18180 (clobber (reg:CC FLAGS_REG))])]
18183 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18185 /* If .md ever supports :P for Pmode, these can be directly
18186 in the pattern above. */
18187 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18188 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18190 if (TARGET_SINGLE_STRINGOP || optimize_size)
18192 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18193 operands[2], operands[3],
18194 operands[5], operands[6]));
18198 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18201 (define_expand "strmov_singleop"
18202 [(parallel [(set (match_operand 1 "memory_operand" "")
18203 (match_operand 3 "memory_operand" ""))
18204 (set (match_operand 0 "register_operand" "")
18205 (match_operand 4 "" ""))
18206 (set (match_operand 2 "register_operand" "")
18207 (match_operand 5 "" ""))])]
18208 "TARGET_SINGLE_STRINGOP || optimize_size"
18211 (define_insn "*strmovdi_rex_1"
18212 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18213 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18214 (set (match_operand:DI 0 "register_operand" "=D")
18215 (plus:DI (match_dup 2)
18217 (set (match_operand:DI 1 "register_operand" "=S")
18218 (plus:DI (match_dup 3)
18220 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18222 [(set_attr "type" "str")
18223 (set_attr "mode" "DI")
18224 (set_attr "memory" "both")])
18226 (define_insn "*strmovsi_1"
18227 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18228 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18229 (set (match_operand:SI 0 "register_operand" "=D")
18230 (plus:SI (match_dup 2)
18232 (set (match_operand:SI 1 "register_operand" "=S")
18233 (plus:SI (match_dup 3)
18235 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18237 [(set_attr "type" "str")
18238 (set_attr "mode" "SI")
18239 (set_attr "memory" "both")])
18241 (define_insn "*strmovsi_rex_1"
18242 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18243 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18244 (set (match_operand:DI 0 "register_operand" "=D")
18245 (plus:DI (match_dup 2)
18247 (set (match_operand:DI 1 "register_operand" "=S")
18248 (plus:DI (match_dup 3)
18250 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18252 [(set_attr "type" "str")
18253 (set_attr "mode" "SI")
18254 (set_attr "memory" "both")])
18256 (define_insn "*strmovhi_1"
18257 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18258 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18259 (set (match_operand:SI 0 "register_operand" "=D")
18260 (plus:SI (match_dup 2)
18262 (set (match_operand:SI 1 "register_operand" "=S")
18263 (plus:SI (match_dup 3)
18265 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18267 [(set_attr "type" "str")
18268 (set_attr "memory" "both")
18269 (set_attr "mode" "HI")])
18271 (define_insn "*strmovhi_rex_1"
18272 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18273 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18274 (set (match_operand:DI 0 "register_operand" "=D")
18275 (plus:DI (match_dup 2)
18277 (set (match_operand:DI 1 "register_operand" "=S")
18278 (plus:DI (match_dup 3)
18280 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18282 [(set_attr "type" "str")
18283 (set_attr "memory" "both")
18284 (set_attr "mode" "HI")])
18286 (define_insn "*strmovqi_1"
18287 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18288 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18289 (set (match_operand:SI 0 "register_operand" "=D")
18290 (plus:SI (match_dup 2)
18292 (set (match_operand:SI 1 "register_operand" "=S")
18293 (plus:SI (match_dup 3)
18295 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18297 [(set_attr "type" "str")
18298 (set_attr "memory" "both")
18299 (set_attr "mode" "QI")])
18301 (define_insn "*strmovqi_rex_1"
18302 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18303 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18304 (set (match_operand:DI 0 "register_operand" "=D")
18305 (plus:DI (match_dup 2)
18307 (set (match_operand:DI 1 "register_operand" "=S")
18308 (plus:DI (match_dup 3)
18310 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18312 [(set_attr "type" "str")
18313 (set_attr "memory" "both")
18314 (set_attr "mode" "QI")])
18316 (define_expand "rep_mov"
18317 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18318 (set (match_operand 0 "register_operand" "")
18319 (match_operand 5 "" ""))
18320 (set (match_operand 2 "register_operand" "")
18321 (match_operand 6 "" ""))
18322 (set (match_operand 1 "memory_operand" "")
18323 (match_operand 3 "memory_operand" ""))
18324 (use (match_dup 4))])]
18328 (define_insn "*rep_movdi_rex64"
18329 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18330 (set (match_operand:DI 0 "register_operand" "=D")
18331 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18333 (match_operand:DI 3 "register_operand" "0")))
18334 (set (match_operand:DI 1 "register_operand" "=S")
18335 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18336 (match_operand:DI 4 "register_operand" "1")))
18337 (set (mem:BLK (match_dup 3))
18338 (mem:BLK (match_dup 4)))
18339 (use (match_dup 5))]
18341 "{rep\;movsq|rep movsq}"
18342 [(set_attr "type" "str")
18343 (set_attr "prefix_rep" "1")
18344 (set_attr "memory" "both")
18345 (set_attr "mode" "DI")])
18347 (define_insn "*rep_movsi"
18348 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18349 (set (match_operand:SI 0 "register_operand" "=D")
18350 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18352 (match_operand:SI 3 "register_operand" "0")))
18353 (set (match_operand:SI 1 "register_operand" "=S")
18354 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18355 (match_operand:SI 4 "register_operand" "1")))
18356 (set (mem:BLK (match_dup 3))
18357 (mem:BLK (match_dup 4)))
18358 (use (match_dup 5))]
18360 "{rep\;movsl|rep movsd}"
18361 [(set_attr "type" "str")
18362 (set_attr "prefix_rep" "1")
18363 (set_attr "memory" "both")
18364 (set_attr "mode" "SI")])
18366 (define_insn "*rep_movsi_rex64"
18367 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18368 (set (match_operand:DI 0 "register_operand" "=D")
18369 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18371 (match_operand:DI 3 "register_operand" "0")))
18372 (set (match_operand:DI 1 "register_operand" "=S")
18373 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18374 (match_operand:DI 4 "register_operand" "1")))
18375 (set (mem:BLK (match_dup 3))
18376 (mem:BLK (match_dup 4)))
18377 (use (match_dup 5))]
18379 "{rep\;movsl|rep movsd}"
18380 [(set_attr "type" "str")
18381 (set_attr "prefix_rep" "1")
18382 (set_attr "memory" "both")
18383 (set_attr "mode" "SI")])
18385 (define_insn "*rep_movqi"
18386 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18387 (set (match_operand:SI 0 "register_operand" "=D")
18388 (plus:SI (match_operand:SI 3 "register_operand" "0")
18389 (match_operand:SI 5 "register_operand" "2")))
18390 (set (match_operand:SI 1 "register_operand" "=S")
18391 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18392 (set (mem:BLK (match_dup 3))
18393 (mem:BLK (match_dup 4)))
18394 (use (match_dup 5))]
18396 "{rep\;movsb|rep movsb}"
18397 [(set_attr "type" "str")
18398 (set_attr "prefix_rep" "1")
18399 (set_attr "memory" "both")
18400 (set_attr "mode" "SI")])
18402 (define_insn "*rep_movqi_rex64"
18403 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18404 (set (match_operand:DI 0 "register_operand" "=D")
18405 (plus:DI (match_operand:DI 3 "register_operand" "0")
18406 (match_operand:DI 5 "register_operand" "2")))
18407 (set (match_operand:DI 1 "register_operand" "=S")
18408 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18409 (set (mem:BLK (match_dup 3))
18410 (mem:BLK (match_dup 4)))
18411 (use (match_dup 5))]
18413 "{rep\;movsb|rep movsb}"
18414 [(set_attr "type" "str")
18415 (set_attr "prefix_rep" "1")
18416 (set_attr "memory" "both")
18417 (set_attr "mode" "SI")])
18419 (define_expand "setmemsi"
18420 [(use (match_operand:BLK 0 "memory_operand" ""))
18421 (use (match_operand:SI 1 "nonmemory_operand" ""))
18422 (use (match_operand 2 "const_int_operand" ""))
18423 (use (match_operand 3 "const_int_operand" ""))]
18426 if (ix86_expand_setmem (operands[0], operands[1],
18427 operands[2], operands[3],
18428 operands[3], constm1_rtx))
18434 (define_expand "setmemdi"
18435 [(use (match_operand:BLK 0 "memory_operand" ""))
18436 (use (match_operand:DI 1 "nonmemory_operand" ""))
18437 (use (match_operand 2 "const_int_operand" ""))
18438 (use (match_operand 3 "const_int_operand" ""))
18439 (use (match_operand 4 "const_int_operand" ""))
18440 (use (match_operand 5 "const_int_operand" ""))]
18443 if (ix86_expand_setmem (operands[0], operands[1],
18444 operands[2], operands[3],
18445 operands[3], constm1_rtx))
18451 ;; Most CPUs don't like single string operations
18452 ;; Handle this case here to simplify previous expander.
18454 (define_expand "strset"
18455 [(set (match_operand 1 "memory_operand" "")
18456 (match_operand 2 "register_operand" ""))
18457 (parallel [(set (match_operand 0 "register_operand" "")
18459 (clobber (reg:CC FLAGS_REG))])]
18462 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18463 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18465 /* If .md ever supports :P for Pmode, this can be directly
18466 in the pattern above. */
18467 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18468 GEN_INT (GET_MODE_SIZE (GET_MODE
18470 if (TARGET_SINGLE_STRINGOP || optimize_size)
18472 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18478 (define_expand "strset_singleop"
18479 [(parallel [(set (match_operand 1 "memory_operand" "")
18480 (match_operand 2 "register_operand" ""))
18481 (set (match_operand 0 "register_operand" "")
18482 (match_operand 3 "" ""))])]
18483 "TARGET_SINGLE_STRINGOP || optimize_size"
18486 (define_insn "*strsetdi_rex_1"
18487 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18488 (match_operand:DI 2 "register_operand" "a"))
18489 (set (match_operand:DI 0 "register_operand" "=D")
18490 (plus:DI (match_dup 1)
18492 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18494 [(set_attr "type" "str")
18495 (set_attr "memory" "store")
18496 (set_attr "mode" "DI")])
18498 (define_insn "*strsetsi_1"
18499 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18500 (match_operand:SI 2 "register_operand" "a"))
18501 (set (match_operand:SI 0 "register_operand" "=D")
18502 (plus:SI (match_dup 1)
18504 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18506 [(set_attr "type" "str")
18507 (set_attr "memory" "store")
18508 (set_attr "mode" "SI")])
18510 (define_insn "*strsetsi_rex_1"
18511 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18512 (match_operand:SI 2 "register_operand" "a"))
18513 (set (match_operand:DI 0 "register_operand" "=D")
18514 (plus:DI (match_dup 1)
18516 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18518 [(set_attr "type" "str")
18519 (set_attr "memory" "store")
18520 (set_attr "mode" "SI")])
18522 (define_insn "*strsethi_1"
18523 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18524 (match_operand:HI 2 "register_operand" "a"))
18525 (set (match_operand:SI 0 "register_operand" "=D")
18526 (plus:SI (match_dup 1)
18528 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18530 [(set_attr "type" "str")
18531 (set_attr "memory" "store")
18532 (set_attr "mode" "HI")])
18534 (define_insn "*strsethi_rex_1"
18535 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18536 (match_operand:HI 2 "register_operand" "a"))
18537 (set (match_operand:DI 0 "register_operand" "=D")
18538 (plus:DI (match_dup 1)
18540 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18542 [(set_attr "type" "str")
18543 (set_attr "memory" "store")
18544 (set_attr "mode" "HI")])
18546 (define_insn "*strsetqi_1"
18547 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18548 (match_operand:QI 2 "register_operand" "a"))
18549 (set (match_operand:SI 0 "register_operand" "=D")
18550 (plus:SI (match_dup 1)
18552 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18554 [(set_attr "type" "str")
18555 (set_attr "memory" "store")
18556 (set_attr "mode" "QI")])
18558 (define_insn "*strsetqi_rex_1"
18559 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18560 (match_operand:QI 2 "register_operand" "a"))
18561 (set (match_operand:DI 0 "register_operand" "=D")
18562 (plus:DI (match_dup 1)
18564 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18566 [(set_attr "type" "str")
18567 (set_attr "memory" "store")
18568 (set_attr "mode" "QI")])
18570 (define_expand "rep_stos"
18571 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18572 (set (match_operand 0 "register_operand" "")
18573 (match_operand 4 "" ""))
18574 (set (match_operand 2 "memory_operand" "") (const_int 0))
18575 (use (match_operand 3 "register_operand" ""))
18576 (use (match_dup 1))])]
18580 (define_insn "*rep_stosdi_rex64"
18581 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18582 (set (match_operand:DI 0 "register_operand" "=D")
18583 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18585 (match_operand:DI 3 "register_operand" "0")))
18586 (set (mem:BLK (match_dup 3))
18588 (use (match_operand:DI 2 "register_operand" "a"))
18589 (use (match_dup 4))]
18591 "{rep\;stosq|rep stosq}"
18592 [(set_attr "type" "str")
18593 (set_attr "prefix_rep" "1")
18594 (set_attr "memory" "store")
18595 (set_attr "mode" "DI")])
18597 (define_insn "*rep_stossi"
18598 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18599 (set (match_operand:SI 0 "register_operand" "=D")
18600 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18602 (match_operand:SI 3 "register_operand" "0")))
18603 (set (mem:BLK (match_dup 3))
18605 (use (match_operand:SI 2 "register_operand" "a"))
18606 (use (match_dup 4))]
18608 "{rep\;stosl|rep stosd}"
18609 [(set_attr "type" "str")
18610 (set_attr "prefix_rep" "1")
18611 (set_attr "memory" "store")
18612 (set_attr "mode" "SI")])
18614 (define_insn "*rep_stossi_rex64"
18615 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18616 (set (match_operand:DI 0 "register_operand" "=D")
18617 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18619 (match_operand:DI 3 "register_operand" "0")))
18620 (set (mem:BLK (match_dup 3))
18622 (use (match_operand:SI 2 "register_operand" "a"))
18623 (use (match_dup 4))]
18625 "{rep\;stosl|rep stosd}"
18626 [(set_attr "type" "str")
18627 (set_attr "prefix_rep" "1")
18628 (set_attr "memory" "store")
18629 (set_attr "mode" "SI")])
18631 (define_insn "*rep_stosqi"
18632 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18633 (set (match_operand:SI 0 "register_operand" "=D")
18634 (plus:SI (match_operand:SI 3 "register_operand" "0")
18635 (match_operand:SI 4 "register_operand" "1")))
18636 (set (mem:BLK (match_dup 3))
18638 (use (match_operand:QI 2 "register_operand" "a"))
18639 (use (match_dup 4))]
18641 "{rep\;stosb|rep stosb}"
18642 [(set_attr "type" "str")
18643 (set_attr "prefix_rep" "1")
18644 (set_attr "memory" "store")
18645 (set_attr "mode" "QI")])
18647 (define_insn "*rep_stosqi_rex64"
18648 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18649 (set (match_operand:DI 0 "register_operand" "=D")
18650 (plus:DI (match_operand:DI 3 "register_operand" "0")
18651 (match_operand:DI 4 "register_operand" "1")))
18652 (set (mem:BLK (match_dup 3))
18654 (use (match_operand:QI 2 "register_operand" "a"))
18655 (use (match_dup 4))]
18657 "{rep\;stosb|rep stosb}"
18658 [(set_attr "type" "str")
18659 (set_attr "prefix_rep" "1")
18660 (set_attr "memory" "store")
18661 (set_attr "mode" "QI")])
18663 (define_expand "cmpstrnsi"
18664 [(set (match_operand:SI 0 "register_operand" "")
18665 (compare:SI (match_operand:BLK 1 "general_operand" "")
18666 (match_operand:BLK 2 "general_operand" "")))
18667 (use (match_operand 3 "general_operand" ""))
18668 (use (match_operand 4 "immediate_operand" ""))]
18669 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18671 rtx addr1, addr2, out, outlow, count, countreg, align;
18673 /* Can't use this if the user has appropriated esi or edi. */
18674 if (global_regs[4] || global_regs[5])
18678 if (GET_CODE (out) != REG)
18679 out = gen_reg_rtx (SImode);
18681 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18682 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18683 if (addr1 != XEXP (operands[1], 0))
18684 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18685 if (addr2 != XEXP (operands[2], 0))
18686 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18688 count = operands[3];
18689 countreg = ix86_zero_extend_to_Pmode (count);
18691 /* %%% Iff we are testing strict equality, we can use known alignment
18692 to good advantage. This may be possible with combine, particularly
18693 once cc0 is dead. */
18694 align = operands[4];
18696 if (GET_CODE (count) == CONST_INT)
18698 if (INTVAL (count) == 0)
18700 emit_move_insn (operands[0], const0_rtx);
18703 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18704 operands[1], operands[2]));
18709 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18711 emit_insn (gen_cmpsi_1 (countreg, countreg));
18712 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18713 operands[1], operands[2]));
18716 outlow = gen_lowpart (QImode, out);
18717 emit_insn (gen_cmpintqi (outlow));
18718 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18720 if (operands[0] != out)
18721 emit_move_insn (operands[0], out);
18726 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18728 (define_expand "cmpintqi"
18729 [(set (match_dup 1)
18730 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18732 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18733 (parallel [(set (match_operand:QI 0 "register_operand" "")
18734 (minus:QI (match_dup 1)
18736 (clobber (reg:CC FLAGS_REG))])]
18738 "operands[1] = gen_reg_rtx (QImode);
18739 operands[2] = gen_reg_rtx (QImode);")
18741 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18742 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18744 (define_expand "cmpstrnqi_nz_1"
18745 [(parallel [(set (reg:CC FLAGS_REG)
18746 (compare:CC (match_operand 4 "memory_operand" "")
18747 (match_operand 5 "memory_operand" "")))
18748 (use (match_operand 2 "register_operand" ""))
18749 (use (match_operand:SI 3 "immediate_operand" ""))
18750 (clobber (match_operand 0 "register_operand" ""))
18751 (clobber (match_operand 1 "register_operand" ""))
18752 (clobber (match_dup 2))])]
18756 (define_insn "*cmpstrnqi_nz_1"
18757 [(set (reg:CC FLAGS_REG)
18758 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18759 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18760 (use (match_operand:SI 6 "register_operand" "2"))
18761 (use (match_operand:SI 3 "immediate_operand" "i"))
18762 (clobber (match_operand:SI 0 "register_operand" "=S"))
18763 (clobber (match_operand:SI 1 "register_operand" "=D"))
18764 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18767 [(set_attr "type" "str")
18768 (set_attr "mode" "QI")
18769 (set_attr "prefix_rep" "1")])
18771 (define_insn "*cmpstrnqi_nz_rex_1"
18772 [(set (reg:CC FLAGS_REG)
18773 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18774 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18775 (use (match_operand:DI 6 "register_operand" "2"))
18776 (use (match_operand:SI 3 "immediate_operand" "i"))
18777 (clobber (match_operand:DI 0 "register_operand" "=S"))
18778 (clobber (match_operand:DI 1 "register_operand" "=D"))
18779 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18782 [(set_attr "type" "str")
18783 (set_attr "mode" "QI")
18784 (set_attr "prefix_rep" "1")])
18786 ;; The same, but the count is not known to not be zero.
18788 (define_expand "cmpstrnqi_1"
18789 [(parallel [(set (reg:CC FLAGS_REG)
18790 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18792 (compare:CC (match_operand 4 "memory_operand" "")
18793 (match_operand 5 "memory_operand" ""))
18795 (use (match_operand:SI 3 "immediate_operand" ""))
18796 (use (reg:CC FLAGS_REG))
18797 (clobber (match_operand 0 "register_operand" ""))
18798 (clobber (match_operand 1 "register_operand" ""))
18799 (clobber (match_dup 2))])]
18803 (define_insn "*cmpstrnqi_1"
18804 [(set (reg:CC FLAGS_REG)
18805 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18807 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18808 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18810 (use (match_operand:SI 3 "immediate_operand" "i"))
18811 (use (reg:CC FLAGS_REG))
18812 (clobber (match_operand:SI 0 "register_operand" "=S"))
18813 (clobber (match_operand:SI 1 "register_operand" "=D"))
18814 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18817 [(set_attr "type" "str")
18818 (set_attr "mode" "QI")
18819 (set_attr "prefix_rep" "1")])
18821 (define_insn "*cmpstrnqi_rex_1"
18822 [(set (reg:CC FLAGS_REG)
18823 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18825 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18826 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18828 (use (match_operand:SI 3 "immediate_operand" "i"))
18829 (use (reg:CC FLAGS_REG))
18830 (clobber (match_operand:DI 0 "register_operand" "=S"))
18831 (clobber (match_operand:DI 1 "register_operand" "=D"))
18832 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18835 [(set_attr "type" "str")
18836 (set_attr "mode" "QI")
18837 (set_attr "prefix_rep" "1")])
18839 (define_expand "strlensi"
18840 [(set (match_operand:SI 0 "register_operand" "")
18841 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18842 (match_operand:QI 2 "immediate_operand" "")
18843 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18846 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18852 (define_expand "strlendi"
18853 [(set (match_operand:DI 0 "register_operand" "")
18854 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18855 (match_operand:QI 2 "immediate_operand" "")
18856 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18859 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18865 (define_expand "strlenqi_1"
18866 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18867 (clobber (match_operand 1 "register_operand" ""))
18868 (clobber (reg:CC FLAGS_REG))])]
18872 (define_insn "*strlenqi_1"
18873 [(set (match_operand:SI 0 "register_operand" "=&c")
18874 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18875 (match_operand:QI 2 "register_operand" "a")
18876 (match_operand:SI 3 "immediate_operand" "i")
18877 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18878 (clobber (match_operand:SI 1 "register_operand" "=D"))
18879 (clobber (reg:CC FLAGS_REG))]
18882 [(set_attr "type" "str")
18883 (set_attr "mode" "QI")
18884 (set_attr "prefix_rep" "1")])
18886 (define_insn "*strlenqi_rex_1"
18887 [(set (match_operand:DI 0 "register_operand" "=&c")
18888 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18889 (match_operand:QI 2 "register_operand" "a")
18890 (match_operand:DI 3 "immediate_operand" "i")
18891 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18892 (clobber (match_operand:DI 1 "register_operand" "=D"))
18893 (clobber (reg:CC FLAGS_REG))]
18896 [(set_attr "type" "str")
18897 (set_attr "mode" "QI")
18898 (set_attr "prefix_rep" "1")])
18900 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18901 ;; handled in combine, but it is not currently up to the task.
18902 ;; When used for their truth value, the cmpstrn* expanders generate
18911 ;; The intermediate three instructions are unnecessary.
18913 ;; This one handles cmpstrn*_nz_1...
18916 (set (reg:CC FLAGS_REG)
18917 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18918 (mem:BLK (match_operand 5 "register_operand" ""))))
18919 (use (match_operand 6 "register_operand" ""))
18920 (use (match_operand:SI 3 "immediate_operand" ""))
18921 (clobber (match_operand 0 "register_operand" ""))
18922 (clobber (match_operand 1 "register_operand" ""))
18923 (clobber (match_operand 2 "register_operand" ""))])
18924 (set (match_operand:QI 7 "register_operand" "")
18925 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18926 (set (match_operand:QI 8 "register_operand" "")
18927 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18928 (set (reg FLAGS_REG)
18929 (compare (match_dup 7) (match_dup 8)))
18931 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18933 (set (reg:CC FLAGS_REG)
18934 (compare:CC (mem:BLK (match_dup 4))
18935 (mem:BLK (match_dup 5))))
18936 (use (match_dup 6))
18937 (use (match_dup 3))
18938 (clobber (match_dup 0))
18939 (clobber (match_dup 1))
18940 (clobber (match_dup 2))])]
18943 ;; ...and this one handles cmpstrn*_1.
18946 (set (reg:CC FLAGS_REG)
18947 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18949 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18950 (mem:BLK (match_operand 5 "register_operand" "")))
18952 (use (match_operand:SI 3 "immediate_operand" ""))
18953 (use (reg:CC FLAGS_REG))
18954 (clobber (match_operand 0 "register_operand" ""))
18955 (clobber (match_operand 1 "register_operand" ""))
18956 (clobber (match_operand 2 "register_operand" ""))])
18957 (set (match_operand:QI 7 "register_operand" "")
18958 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18959 (set (match_operand:QI 8 "register_operand" "")
18960 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18961 (set (reg FLAGS_REG)
18962 (compare (match_dup 7) (match_dup 8)))
18964 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18966 (set (reg:CC FLAGS_REG)
18967 (if_then_else:CC (ne (match_dup 6)
18969 (compare:CC (mem:BLK (match_dup 4))
18970 (mem:BLK (match_dup 5)))
18972 (use (match_dup 3))
18973 (use (reg:CC FLAGS_REG))
18974 (clobber (match_dup 0))
18975 (clobber (match_dup 1))
18976 (clobber (match_dup 2))])]
18981 ;; Conditional move instructions.
18983 (define_expand "movdicc"
18984 [(set (match_operand:DI 0 "register_operand" "")
18985 (if_then_else:DI (match_operand 1 "comparison_operator" "")
18986 (match_operand:DI 2 "general_operand" "")
18987 (match_operand:DI 3 "general_operand" "")))]
18989 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
18991 (define_insn "x86_movdicc_0_m1_rex64"
18992 [(set (match_operand:DI 0 "register_operand" "=r")
18993 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
18996 (clobber (reg:CC FLAGS_REG))]
18999 ; Since we don't have the proper number of operands for an alu insn,
19000 ; fill in all the blanks.
19001 [(set_attr "type" "alu")
19002 (set_attr "pent_pair" "pu")
19003 (set_attr "memory" "none")
19004 (set_attr "imm_disp" "false")
19005 (set_attr "mode" "DI")
19006 (set_attr "length_immediate" "0")])
19008 (define_insn "*movdicc_c_rex64"
19009 [(set (match_operand:DI 0 "register_operand" "=r,r")
19010 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19011 [(reg FLAGS_REG) (const_int 0)])
19012 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19013 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19014 "TARGET_64BIT && TARGET_CMOVE
19015 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19017 cmov%O2%C1\t{%2, %0|%0, %2}
19018 cmov%O2%c1\t{%3, %0|%0, %3}"
19019 [(set_attr "type" "icmov")
19020 (set_attr "mode" "DI")])
19022 (define_expand "movsicc"
19023 [(set (match_operand:SI 0 "register_operand" "")
19024 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19025 (match_operand:SI 2 "general_operand" "")
19026 (match_operand:SI 3 "general_operand" "")))]
19028 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19030 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19031 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19032 ;; So just document what we're doing explicitly.
19034 (define_insn "x86_movsicc_0_m1"
19035 [(set (match_operand:SI 0 "register_operand" "=r")
19036 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19039 (clobber (reg:CC FLAGS_REG))]
19042 ; Since we don't have the proper number of operands for an alu insn,
19043 ; fill in all the blanks.
19044 [(set_attr "type" "alu")
19045 (set_attr "pent_pair" "pu")
19046 (set_attr "memory" "none")
19047 (set_attr "imm_disp" "false")
19048 (set_attr "mode" "SI")
19049 (set_attr "length_immediate" "0")])
19051 (define_insn "*movsicc_noc"
19052 [(set (match_operand:SI 0 "register_operand" "=r,r")
19053 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19054 [(reg FLAGS_REG) (const_int 0)])
19055 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19056 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19058 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19060 cmov%O2%C1\t{%2, %0|%0, %2}
19061 cmov%O2%c1\t{%3, %0|%0, %3}"
19062 [(set_attr "type" "icmov")
19063 (set_attr "mode" "SI")])
19065 (define_expand "movhicc"
19066 [(set (match_operand:HI 0 "register_operand" "")
19067 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19068 (match_operand:HI 2 "general_operand" "")
19069 (match_operand:HI 3 "general_operand" "")))]
19070 "TARGET_HIMODE_MATH"
19071 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19073 (define_insn "*movhicc_noc"
19074 [(set (match_operand:HI 0 "register_operand" "=r,r")
19075 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19076 [(reg FLAGS_REG) (const_int 0)])
19077 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19078 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19080 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19082 cmov%O2%C1\t{%2, %0|%0, %2}
19083 cmov%O2%c1\t{%3, %0|%0, %3}"
19084 [(set_attr "type" "icmov")
19085 (set_attr "mode" "HI")])
19087 (define_expand "movqicc"
19088 [(set (match_operand:QI 0 "register_operand" "")
19089 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19090 (match_operand:QI 2 "general_operand" "")
19091 (match_operand:QI 3 "general_operand" "")))]
19092 "TARGET_QIMODE_MATH"
19093 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19095 (define_insn_and_split "*movqicc_noc"
19096 [(set (match_operand:QI 0 "register_operand" "=r,r")
19097 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19098 [(match_operand 4 "flags_reg_operand" "")
19100 (match_operand:QI 2 "register_operand" "r,0")
19101 (match_operand:QI 3 "register_operand" "0,r")))]
19102 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19104 "&& reload_completed"
19105 [(set (match_dup 0)
19106 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19109 "operands[0] = gen_lowpart (SImode, operands[0]);
19110 operands[2] = gen_lowpart (SImode, operands[2]);
19111 operands[3] = gen_lowpart (SImode, operands[3]);"
19112 [(set_attr "type" "icmov")
19113 (set_attr "mode" "SI")])
19115 (define_expand "movsfcc"
19116 [(set (match_operand:SF 0 "register_operand" "")
19117 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19118 (match_operand:SF 2 "register_operand" "")
19119 (match_operand:SF 3 "register_operand" "")))]
19120 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19121 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19123 (define_insn "*movsfcc_1_387"
19124 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19125 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19126 [(reg FLAGS_REG) (const_int 0)])
19127 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19128 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19129 "TARGET_80387 && TARGET_CMOVE
19130 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19132 fcmov%F1\t{%2, %0|%0, %2}
19133 fcmov%f1\t{%3, %0|%0, %3}
19134 cmov%O2%C1\t{%2, %0|%0, %2}
19135 cmov%O2%c1\t{%3, %0|%0, %3}"
19136 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19137 (set_attr "mode" "SF,SF,SI,SI")])
19139 (define_expand "movdfcc"
19140 [(set (match_operand:DF 0 "register_operand" "")
19141 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19142 (match_operand:DF 2 "register_operand" "")
19143 (match_operand:DF 3 "register_operand" "")))]
19144 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19145 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19147 (define_insn "*movdfcc_1"
19148 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19149 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19150 [(reg FLAGS_REG) (const_int 0)])
19151 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19152 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19153 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19154 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19156 fcmov%F1\t{%2, %0|%0, %2}
19157 fcmov%f1\t{%3, %0|%0, %3}
19160 [(set_attr "type" "fcmov,fcmov,multi,multi")
19161 (set_attr "mode" "DF")])
19163 (define_insn "*movdfcc_1_rex64"
19164 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19165 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19166 [(reg FLAGS_REG) (const_int 0)])
19167 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19168 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19169 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19170 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19172 fcmov%F1\t{%2, %0|%0, %2}
19173 fcmov%f1\t{%3, %0|%0, %3}
19174 cmov%O2%C1\t{%2, %0|%0, %2}
19175 cmov%O2%c1\t{%3, %0|%0, %3}"
19176 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19177 (set_attr "mode" "DF")])
19180 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19181 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19182 [(match_operand 4 "flags_reg_operand" "")
19184 (match_operand:DF 2 "nonimmediate_operand" "")
19185 (match_operand:DF 3 "nonimmediate_operand" "")))]
19186 "!TARGET_64BIT && reload_completed"
19187 [(set (match_dup 2)
19188 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19192 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19195 "split_di (operands+2, 1, operands+5, operands+6);
19196 split_di (operands+3, 1, operands+7, operands+8);
19197 split_di (operands, 1, operands+2, operands+3);")
19199 (define_expand "movxfcc"
19200 [(set (match_operand:XF 0 "register_operand" "")
19201 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19202 (match_operand:XF 2 "register_operand" "")
19203 (match_operand:XF 3 "register_operand" "")))]
19204 "TARGET_80387 && TARGET_CMOVE"
19205 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19207 (define_insn "*movxfcc_1"
19208 [(set (match_operand:XF 0 "register_operand" "=f,f")
19209 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19210 [(reg FLAGS_REG) (const_int 0)])
19211 (match_operand:XF 2 "register_operand" "f,0")
19212 (match_operand:XF 3 "register_operand" "0,f")))]
19213 "TARGET_80387 && TARGET_CMOVE"
19215 fcmov%F1\t{%2, %0|%0, %2}
19216 fcmov%f1\t{%3, %0|%0, %3}"
19217 [(set_attr "type" "fcmov")
19218 (set_attr "mode" "XF")])
19220 ;; These versions of the min/max patterns are intentionally ignorant of
19221 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19222 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19223 ;; are undefined in this condition, we're certain this is correct.
19225 (define_insn "sminsf3"
19226 [(set (match_operand:SF 0 "register_operand" "=x")
19227 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19228 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19230 "minss\t{%2, %0|%0, %2}"
19231 [(set_attr "type" "sseadd")
19232 (set_attr "mode" "SF")])
19234 (define_insn "smaxsf3"
19235 [(set (match_operand:SF 0 "register_operand" "=x")
19236 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19237 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19239 "maxss\t{%2, %0|%0, %2}"
19240 [(set_attr "type" "sseadd")
19241 (set_attr "mode" "SF")])
19243 (define_insn "smindf3"
19244 [(set (match_operand:DF 0 "register_operand" "=x")
19245 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19246 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19247 "TARGET_SSE2 && TARGET_SSE_MATH"
19248 "minsd\t{%2, %0|%0, %2}"
19249 [(set_attr "type" "sseadd")
19250 (set_attr "mode" "DF")])
19252 (define_insn "smaxdf3"
19253 [(set (match_operand:DF 0 "register_operand" "=x")
19254 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19255 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19256 "TARGET_SSE2 && TARGET_SSE_MATH"
19257 "maxsd\t{%2, %0|%0, %2}"
19258 [(set_attr "type" "sseadd")
19259 (set_attr "mode" "DF")])
19261 ;; These versions of the min/max patterns implement exactly the operations
19262 ;; min = (op1 < op2 ? op1 : op2)
19263 ;; max = (!(op1 < op2) ? op1 : op2)
19264 ;; Their operands are not commutative, and thus they may be used in the
19265 ;; presence of -0.0 and NaN.
19267 (define_insn "*ieee_sminsf3"
19268 [(set (match_operand:SF 0 "register_operand" "=x")
19269 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19270 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19273 "minss\t{%2, %0|%0, %2}"
19274 [(set_attr "type" "sseadd")
19275 (set_attr "mode" "SF")])
19277 (define_insn "*ieee_smaxsf3"
19278 [(set (match_operand:SF 0 "register_operand" "=x")
19279 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19280 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19283 "maxss\t{%2, %0|%0, %2}"
19284 [(set_attr "type" "sseadd")
19285 (set_attr "mode" "SF")])
19287 (define_insn "*ieee_smindf3"
19288 [(set (match_operand:DF 0 "register_operand" "=x")
19289 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19290 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19292 "TARGET_SSE2 && TARGET_SSE_MATH"
19293 "minsd\t{%2, %0|%0, %2}"
19294 [(set_attr "type" "sseadd")
19295 (set_attr "mode" "DF")])
19297 (define_insn "*ieee_smaxdf3"
19298 [(set (match_operand:DF 0 "register_operand" "=x")
19299 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19300 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19302 "TARGET_SSE2 && TARGET_SSE_MATH"
19303 "maxsd\t{%2, %0|%0, %2}"
19304 [(set_attr "type" "sseadd")
19305 (set_attr "mode" "DF")])
19307 ;; Make two stack loads independent:
19309 ;; fld %st(0) -> fld bb
19310 ;; fmul bb fmul %st(1), %st
19312 ;; Actually we only match the last two instructions for simplicity.
19314 [(set (match_operand 0 "fp_register_operand" "")
19315 (match_operand 1 "fp_register_operand" ""))
19317 (match_operator 2 "binary_fp_operator"
19319 (match_operand 3 "memory_operand" "")]))]
19320 "REGNO (operands[0]) != REGNO (operands[1])"
19321 [(set (match_dup 0) (match_dup 3))
19322 (set (match_dup 0) (match_dup 4))]
19324 ;; The % modifier is not operational anymore in peephole2's, so we have to
19325 ;; swap the operands manually in the case of addition and multiplication.
19326 "if (COMMUTATIVE_ARITH_P (operands[2]))
19327 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19328 operands[0], operands[1]);
19330 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19331 operands[1], operands[0]);")
19333 ;; Conditional addition patterns
19334 (define_expand "addqicc"
19335 [(match_operand:QI 0 "register_operand" "")
19336 (match_operand 1 "comparison_operator" "")
19337 (match_operand:QI 2 "register_operand" "")
19338 (match_operand:QI 3 "const_int_operand" "")]
19340 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19342 (define_expand "addhicc"
19343 [(match_operand:HI 0 "register_operand" "")
19344 (match_operand 1 "comparison_operator" "")
19345 (match_operand:HI 2 "register_operand" "")
19346 (match_operand:HI 3 "const_int_operand" "")]
19348 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19350 (define_expand "addsicc"
19351 [(match_operand:SI 0 "register_operand" "")
19352 (match_operand 1 "comparison_operator" "")
19353 (match_operand:SI 2 "register_operand" "")
19354 (match_operand:SI 3 "const_int_operand" "")]
19356 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19358 (define_expand "adddicc"
19359 [(match_operand:DI 0 "register_operand" "")
19360 (match_operand 1 "comparison_operator" "")
19361 (match_operand:DI 2 "register_operand" "")
19362 (match_operand:DI 3 "const_int_operand" "")]
19364 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19367 ;; Misc patterns (?)
19369 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19370 ;; Otherwise there will be nothing to keep
19372 ;; [(set (reg ebp) (reg esp))]
19373 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19374 ;; (clobber (eflags)]
19375 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19377 ;; in proper program order.
19378 (define_insn "pro_epilogue_adjust_stack_1"
19379 [(set (match_operand:SI 0 "register_operand" "=r,r")
19380 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19381 (match_operand:SI 2 "immediate_operand" "i,i")))
19382 (clobber (reg:CC FLAGS_REG))
19383 (clobber (mem:BLK (scratch)))]
19386 switch (get_attr_type (insn))
19389 return "mov{l}\t{%1, %0|%0, %1}";
19392 if (GET_CODE (operands[2]) == CONST_INT
19393 && (INTVAL (operands[2]) == 128
19394 || (INTVAL (operands[2]) < 0
19395 && INTVAL (operands[2]) != -128)))
19397 operands[2] = GEN_INT (-INTVAL (operands[2]));
19398 return "sub{l}\t{%2, %0|%0, %2}";
19400 return "add{l}\t{%2, %0|%0, %2}";
19403 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19404 return "lea{l}\t{%a2, %0|%0, %a2}";
19407 gcc_unreachable ();
19410 [(set (attr "type")
19411 (cond [(eq_attr "alternative" "0")
19412 (const_string "alu")
19413 (match_operand:SI 2 "const0_operand" "")
19414 (const_string "imov")
19416 (const_string "lea")))
19417 (set_attr "mode" "SI")])
19419 (define_insn "pro_epilogue_adjust_stack_rex64"
19420 [(set (match_operand:DI 0 "register_operand" "=r,r")
19421 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19422 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19423 (clobber (reg:CC FLAGS_REG))
19424 (clobber (mem:BLK (scratch)))]
19427 switch (get_attr_type (insn))
19430 return "mov{q}\t{%1, %0|%0, %1}";
19433 if (GET_CODE (operands[2]) == CONST_INT
19434 /* Avoid overflows. */
19435 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19436 && (INTVAL (operands[2]) == 128
19437 || (INTVAL (operands[2]) < 0
19438 && INTVAL (operands[2]) != -128)))
19440 operands[2] = GEN_INT (-INTVAL (operands[2]));
19441 return "sub{q}\t{%2, %0|%0, %2}";
19443 return "add{q}\t{%2, %0|%0, %2}";
19446 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19447 return "lea{q}\t{%a2, %0|%0, %a2}";
19450 gcc_unreachable ();
19453 [(set (attr "type")
19454 (cond [(eq_attr "alternative" "0")
19455 (const_string "alu")
19456 (match_operand:DI 2 "const0_operand" "")
19457 (const_string "imov")
19459 (const_string "lea")))
19460 (set_attr "mode" "DI")])
19462 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19463 [(set (match_operand:DI 0 "register_operand" "=r,r")
19464 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19465 (match_operand:DI 3 "immediate_operand" "i,i")))
19466 (use (match_operand:DI 2 "register_operand" "r,r"))
19467 (clobber (reg:CC FLAGS_REG))
19468 (clobber (mem:BLK (scratch)))]
19471 switch (get_attr_type (insn))
19474 return "add{q}\t{%2, %0|%0, %2}";
19477 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19478 return "lea{q}\t{%a2, %0|%0, %a2}";
19481 gcc_unreachable ();
19484 [(set_attr "type" "alu,lea")
19485 (set_attr "mode" "DI")])
19487 (define_expand "allocate_stack_worker"
19488 [(match_operand:SI 0 "register_operand" "")]
19489 "TARGET_STACK_PROBE"
19491 if (reload_completed)
19494 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19496 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19501 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19503 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19508 (define_insn "allocate_stack_worker_1"
19509 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19510 UNSPECV_STACK_PROBE)
19511 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19512 (clobber (match_scratch:SI 1 "=0"))
19513 (clobber (reg:CC FLAGS_REG))]
19514 "!TARGET_64BIT && TARGET_STACK_PROBE"
19516 [(set_attr "type" "multi")
19517 (set_attr "length" "5")])
19519 (define_expand "allocate_stack_worker_postreload"
19520 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19521 UNSPECV_STACK_PROBE)
19522 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19523 (clobber (match_dup 0))
19524 (clobber (reg:CC FLAGS_REG))])]
19528 (define_insn "allocate_stack_worker_rex64"
19529 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19530 UNSPECV_STACK_PROBE)
19531 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19532 (clobber (match_scratch:DI 1 "=0"))
19533 (clobber (reg:CC FLAGS_REG))]
19534 "TARGET_64BIT && TARGET_STACK_PROBE"
19536 [(set_attr "type" "multi")
19537 (set_attr "length" "5")])
19539 (define_expand "allocate_stack_worker_rex64_postreload"
19540 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19541 UNSPECV_STACK_PROBE)
19542 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19543 (clobber (match_dup 0))
19544 (clobber (reg:CC FLAGS_REG))])]
19548 (define_expand "allocate_stack"
19549 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19550 (minus:SI (reg:SI SP_REG)
19551 (match_operand:SI 1 "general_operand" "")))
19552 (clobber (reg:CC FLAGS_REG))])
19553 (parallel [(set (reg:SI SP_REG)
19554 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19555 (clobber (reg:CC FLAGS_REG))])]
19556 "TARGET_STACK_PROBE"
19558 #ifdef CHECK_STACK_LIMIT
19559 if (GET_CODE (operands[1]) == CONST_INT
19560 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19561 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19565 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19568 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19572 (define_expand "builtin_setjmp_receiver"
19573 [(label_ref (match_operand 0 "" ""))]
19574 "!TARGET_64BIT && flag_pic"
19579 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19580 rtx label_rtx = gen_label_rtx ();
19581 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19582 xops[0] = xops[1] = picreg;
19583 xops[2] = gen_rtx_CONST (SImode,
19584 gen_rtx_MINUS (SImode,
19585 gen_rtx_LABEL_REF (SImode, label_rtx),
19586 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19587 ix86_expand_binary_operator (MINUS, SImode, xops);
19590 emit_insn (gen_set_got (pic_offset_table_rtx));
19594 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19597 [(set (match_operand 0 "register_operand" "")
19598 (match_operator 3 "promotable_binary_operator"
19599 [(match_operand 1 "register_operand" "")
19600 (match_operand 2 "aligned_operand" "")]))
19601 (clobber (reg:CC FLAGS_REG))]
19602 "! TARGET_PARTIAL_REG_STALL && reload_completed
19603 && ((GET_MODE (operands[0]) == HImode
19604 && ((!optimize_size && !TARGET_FAST_PREFIX)
19605 /* ??? next two lines just !satisfies_constraint_K (...) */
19606 || GET_CODE (operands[2]) != CONST_INT
19607 || satisfies_constraint_K (operands[2])))
19608 || (GET_MODE (operands[0]) == QImode
19609 && (TARGET_PROMOTE_QImode || optimize_size)))"
19610 [(parallel [(set (match_dup 0)
19611 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19612 (clobber (reg:CC FLAGS_REG))])]
19613 "operands[0] = gen_lowpart (SImode, operands[0]);
19614 operands[1] = gen_lowpart (SImode, operands[1]);
19615 if (GET_CODE (operands[3]) != ASHIFT)
19616 operands[2] = gen_lowpart (SImode, operands[2]);
19617 PUT_MODE (operands[3], SImode);")
19619 ; Promote the QImode tests, as i386 has encoding of the AND
19620 ; instruction with 32-bit sign-extended immediate and thus the
19621 ; instruction size is unchanged, except in the %eax case for
19622 ; which it is increased by one byte, hence the ! optimize_size.
19624 [(set (match_operand 0 "flags_reg_operand" "")
19625 (match_operator 2 "compare_operator"
19626 [(and (match_operand 3 "aligned_operand" "")
19627 (match_operand 4 "const_int_operand" ""))
19629 (set (match_operand 1 "register_operand" "")
19630 (and (match_dup 3) (match_dup 4)))]
19631 "! TARGET_PARTIAL_REG_STALL && reload_completed
19632 /* Ensure that the operand will remain sign-extended immediate. */
19633 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19635 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19636 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19637 [(parallel [(set (match_dup 0)
19638 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19641 (and:SI (match_dup 3) (match_dup 4)))])]
19644 = gen_int_mode (INTVAL (operands[4])
19645 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19646 operands[1] = gen_lowpart (SImode, operands[1]);
19647 operands[3] = gen_lowpart (SImode, operands[3]);
19650 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19651 ; the TEST instruction with 32-bit sign-extended immediate and thus
19652 ; the instruction size would at least double, which is not what we
19653 ; want even with ! optimize_size.
19655 [(set (match_operand 0 "flags_reg_operand" "")
19656 (match_operator 1 "compare_operator"
19657 [(and (match_operand:HI 2 "aligned_operand" "")
19658 (match_operand:HI 3 "const_int_operand" ""))
19660 "! TARGET_PARTIAL_REG_STALL && reload_completed
19661 /* Ensure that the operand will remain sign-extended immediate. */
19662 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19663 && ! TARGET_FAST_PREFIX
19664 && ! optimize_size"
19665 [(set (match_dup 0)
19666 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19670 = gen_int_mode (INTVAL (operands[3])
19671 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19672 operands[2] = gen_lowpart (SImode, operands[2]);
19676 [(set (match_operand 0 "register_operand" "")
19677 (neg (match_operand 1 "register_operand" "")))
19678 (clobber (reg:CC FLAGS_REG))]
19679 "! TARGET_PARTIAL_REG_STALL && reload_completed
19680 && (GET_MODE (operands[0]) == HImode
19681 || (GET_MODE (operands[0]) == QImode
19682 && (TARGET_PROMOTE_QImode || optimize_size)))"
19683 [(parallel [(set (match_dup 0)
19684 (neg:SI (match_dup 1)))
19685 (clobber (reg:CC FLAGS_REG))])]
19686 "operands[0] = gen_lowpart (SImode, operands[0]);
19687 operands[1] = gen_lowpart (SImode, operands[1]);")
19690 [(set (match_operand 0 "register_operand" "")
19691 (not (match_operand 1 "register_operand" "")))]
19692 "! TARGET_PARTIAL_REG_STALL && reload_completed
19693 && (GET_MODE (operands[0]) == HImode
19694 || (GET_MODE (operands[0]) == QImode
19695 && (TARGET_PROMOTE_QImode || optimize_size)))"
19696 [(set (match_dup 0)
19697 (not:SI (match_dup 1)))]
19698 "operands[0] = gen_lowpart (SImode, operands[0]);
19699 operands[1] = gen_lowpart (SImode, operands[1]);")
19702 [(set (match_operand 0 "register_operand" "")
19703 (if_then_else (match_operator 1 "comparison_operator"
19704 [(reg FLAGS_REG) (const_int 0)])
19705 (match_operand 2 "register_operand" "")
19706 (match_operand 3 "register_operand" "")))]
19707 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19708 && (GET_MODE (operands[0]) == HImode
19709 || (GET_MODE (operands[0]) == QImode
19710 && (TARGET_PROMOTE_QImode || optimize_size)))"
19711 [(set (match_dup 0)
19712 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19713 "operands[0] = gen_lowpart (SImode, operands[0]);
19714 operands[2] = gen_lowpart (SImode, operands[2]);
19715 operands[3] = gen_lowpart (SImode, operands[3]);")
19718 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19719 ;; transform a complex memory operation into two memory to register operations.
19721 ;; Don't push memory operands
19723 [(set (match_operand:SI 0 "push_operand" "")
19724 (match_operand:SI 1 "memory_operand" ""))
19725 (match_scratch:SI 2 "r")]
19726 "!optimize_size && !TARGET_PUSH_MEMORY
19727 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19728 [(set (match_dup 2) (match_dup 1))
19729 (set (match_dup 0) (match_dup 2))]
19733 [(set (match_operand:DI 0 "push_operand" "")
19734 (match_operand:DI 1 "memory_operand" ""))
19735 (match_scratch:DI 2 "r")]
19736 "!optimize_size && !TARGET_PUSH_MEMORY
19737 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19738 [(set (match_dup 2) (match_dup 1))
19739 (set (match_dup 0) (match_dup 2))]
19742 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19745 [(set (match_operand:SF 0 "push_operand" "")
19746 (match_operand:SF 1 "memory_operand" ""))
19747 (match_scratch:SF 2 "r")]
19748 "!optimize_size && !TARGET_PUSH_MEMORY
19749 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19750 [(set (match_dup 2) (match_dup 1))
19751 (set (match_dup 0) (match_dup 2))]
19755 [(set (match_operand:HI 0 "push_operand" "")
19756 (match_operand:HI 1 "memory_operand" ""))
19757 (match_scratch:HI 2 "r")]
19758 "!optimize_size && !TARGET_PUSH_MEMORY
19759 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19760 [(set (match_dup 2) (match_dup 1))
19761 (set (match_dup 0) (match_dup 2))]
19765 [(set (match_operand:QI 0 "push_operand" "")
19766 (match_operand:QI 1 "memory_operand" ""))
19767 (match_scratch:QI 2 "q")]
19768 "!optimize_size && !TARGET_PUSH_MEMORY
19769 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19770 [(set (match_dup 2) (match_dup 1))
19771 (set (match_dup 0) (match_dup 2))]
19774 ;; Don't move an immediate directly to memory when the instruction
19777 [(match_scratch:SI 1 "r")
19778 (set (match_operand:SI 0 "memory_operand" "")
19781 && ! TARGET_USE_MOV0
19782 && TARGET_SPLIT_LONG_MOVES
19783 && get_attr_length (insn) >= ix86_cost->large_insn
19784 && peep2_regno_dead_p (0, FLAGS_REG)"
19785 [(parallel [(set (match_dup 1) (const_int 0))
19786 (clobber (reg:CC FLAGS_REG))])
19787 (set (match_dup 0) (match_dup 1))]
19791 [(match_scratch:HI 1 "r")
19792 (set (match_operand:HI 0 "memory_operand" "")
19795 && ! TARGET_USE_MOV0
19796 && TARGET_SPLIT_LONG_MOVES
19797 && get_attr_length (insn) >= ix86_cost->large_insn
19798 && peep2_regno_dead_p (0, FLAGS_REG)"
19799 [(parallel [(set (match_dup 2) (const_int 0))
19800 (clobber (reg:CC FLAGS_REG))])
19801 (set (match_dup 0) (match_dup 1))]
19802 "operands[2] = gen_lowpart (SImode, operands[1]);")
19805 [(match_scratch:QI 1 "q")
19806 (set (match_operand:QI 0 "memory_operand" "")
19809 && ! TARGET_USE_MOV0
19810 && TARGET_SPLIT_LONG_MOVES
19811 && get_attr_length (insn) >= ix86_cost->large_insn
19812 && peep2_regno_dead_p (0, FLAGS_REG)"
19813 [(parallel [(set (match_dup 2) (const_int 0))
19814 (clobber (reg:CC FLAGS_REG))])
19815 (set (match_dup 0) (match_dup 1))]
19816 "operands[2] = gen_lowpart (SImode, operands[1]);")
19819 [(match_scratch:SI 2 "r")
19820 (set (match_operand:SI 0 "memory_operand" "")
19821 (match_operand:SI 1 "immediate_operand" ""))]
19823 && get_attr_length (insn) >= ix86_cost->large_insn
19824 && TARGET_SPLIT_LONG_MOVES"
19825 [(set (match_dup 2) (match_dup 1))
19826 (set (match_dup 0) (match_dup 2))]
19830 [(match_scratch:HI 2 "r")
19831 (set (match_operand:HI 0 "memory_operand" "")
19832 (match_operand:HI 1 "immediate_operand" ""))]
19833 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19834 && TARGET_SPLIT_LONG_MOVES"
19835 [(set (match_dup 2) (match_dup 1))
19836 (set (match_dup 0) (match_dup 2))]
19840 [(match_scratch:QI 2 "q")
19841 (set (match_operand:QI 0 "memory_operand" "")
19842 (match_operand:QI 1 "immediate_operand" ""))]
19843 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19844 && TARGET_SPLIT_LONG_MOVES"
19845 [(set (match_dup 2) (match_dup 1))
19846 (set (match_dup 0) (match_dup 2))]
19849 ;; Don't compare memory with zero, load and use a test instead.
19851 [(set (match_operand 0 "flags_reg_operand" "")
19852 (match_operator 1 "compare_operator"
19853 [(match_operand:SI 2 "memory_operand" "")
19855 (match_scratch:SI 3 "r")]
19856 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19857 [(set (match_dup 3) (match_dup 2))
19858 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19861 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19862 ;; Don't split NOTs with a displacement operand, because resulting XOR
19863 ;; will not be pairable anyway.
19865 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19866 ;; represented using a modRM byte. The XOR replacement is long decoded,
19867 ;; so this split helps here as well.
19869 ;; Note: Can't do this as a regular split because we can't get proper
19870 ;; lifetime information then.
19873 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19874 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19876 && peep2_regno_dead_p (0, FLAGS_REG)
19877 && ((TARGET_PENTIUM
19878 && (GET_CODE (operands[0]) != MEM
19879 || !memory_displacement_operand (operands[0], SImode)))
19880 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19881 [(parallel [(set (match_dup 0)
19882 (xor:SI (match_dup 1) (const_int -1)))
19883 (clobber (reg:CC FLAGS_REG))])]
19887 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19888 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19890 && peep2_regno_dead_p (0, FLAGS_REG)
19891 && ((TARGET_PENTIUM
19892 && (GET_CODE (operands[0]) != MEM
19893 || !memory_displacement_operand (operands[0], HImode)))
19894 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19895 [(parallel [(set (match_dup 0)
19896 (xor:HI (match_dup 1) (const_int -1)))
19897 (clobber (reg:CC FLAGS_REG))])]
19901 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19902 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19904 && peep2_regno_dead_p (0, FLAGS_REG)
19905 && ((TARGET_PENTIUM
19906 && (GET_CODE (operands[0]) != MEM
19907 || !memory_displacement_operand (operands[0], QImode)))
19908 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19909 [(parallel [(set (match_dup 0)
19910 (xor:QI (match_dup 1) (const_int -1)))
19911 (clobber (reg:CC FLAGS_REG))])]
19914 ;; Non pairable "test imm, reg" instructions can be translated to
19915 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19916 ;; byte opcode instead of two, have a short form for byte operands),
19917 ;; so do it for other CPUs as well. Given that the value was dead,
19918 ;; this should not create any new dependencies. Pass on the sub-word
19919 ;; versions if we're concerned about partial register stalls.
19922 [(set (match_operand 0 "flags_reg_operand" "")
19923 (match_operator 1 "compare_operator"
19924 [(and:SI (match_operand:SI 2 "register_operand" "")
19925 (match_operand:SI 3 "immediate_operand" ""))
19927 "ix86_match_ccmode (insn, CCNOmode)
19928 && (true_regnum (operands[2]) != 0
19929 || satisfies_constraint_K (operands[3]))
19930 && peep2_reg_dead_p (1, operands[2])"
19932 [(set (match_dup 0)
19933 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19936 (and:SI (match_dup 2) (match_dup 3)))])]
19939 ;; We don't need to handle HImode case, because it will be promoted to SImode
19940 ;; on ! TARGET_PARTIAL_REG_STALL
19943 [(set (match_operand 0 "flags_reg_operand" "")
19944 (match_operator 1 "compare_operator"
19945 [(and:QI (match_operand:QI 2 "register_operand" "")
19946 (match_operand:QI 3 "immediate_operand" ""))
19948 "! TARGET_PARTIAL_REG_STALL
19949 && ix86_match_ccmode (insn, CCNOmode)
19950 && true_regnum (operands[2]) != 0
19951 && peep2_reg_dead_p (1, operands[2])"
19953 [(set (match_dup 0)
19954 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19957 (and:QI (match_dup 2) (match_dup 3)))])]
19961 [(set (match_operand 0 "flags_reg_operand" "")
19962 (match_operator 1 "compare_operator"
19965 (match_operand 2 "ext_register_operand" "")
19968 (match_operand 3 "const_int_operand" ""))
19970 "! TARGET_PARTIAL_REG_STALL
19971 && ix86_match_ccmode (insn, CCNOmode)
19972 && true_regnum (operands[2]) != 0
19973 && peep2_reg_dead_p (1, operands[2])"
19974 [(parallel [(set (match_dup 0)
19983 (set (zero_extract:SI (match_dup 2)
19994 ;; Don't do logical operations with memory inputs.
19996 [(match_scratch:SI 2 "r")
19997 (parallel [(set (match_operand:SI 0 "register_operand" "")
19998 (match_operator:SI 3 "arith_or_logical_operator"
20000 (match_operand:SI 1 "memory_operand" "")]))
20001 (clobber (reg:CC FLAGS_REG))])]
20002 "! optimize_size && ! TARGET_READ_MODIFY"
20003 [(set (match_dup 2) (match_dup 1))
20004 (parallel [(set (match_dup 0)
20005 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20006 (clobber (reg:CC FLAGS_REG))])]
20010 [(match_scratch:SI 2 "r")
20011 (parallel [(set (match_operand:SI 0 "register_operand" "")
20012 (match_operator:SI 3 "arith_or_logical_operator"
20013 [(match_operand:SI 1 "memory_operand" "")
20015 (clobber (reg:CC FLAGS_REG))])]
20016 "! optimize_size && ! TARGET_READ_MODIFY"
20017 [(set (match_dup 2) (match_dup 1))
20018 (parallel [(set (match_dup 0)
20019 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20020 (clobber (reg:CC FLAGS_REG))])]
20023 ; Don't do logical operations with memory outputs
20025 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20026 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20027 ; the same decoder scheduling characteristics as the original.
20030 [(match_scratch:SI 2 "r")
20031 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20032 (match_operator:SI 3 "arith_or_logical_operator"
20034 (match_operand:SI 1 "nonmemory_operand" "")]))
20035 (clobber (reg:CC FLAGS_REG))])]
20036 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20037 [(set (match_dup 2) (match_dup 0))
20038 (parallel [(set (match_dup 2)
20039 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20040 (clobber (reg:CC FLAGS_REG))])
20041 (set (match_dup 0) (match_dup 2))]
20045 [(match_scratch:SI 2 "r")
20046 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20047 (match_operator:SI 3 "arith_or_logical_operator"
20048 [(match_operand:SI 1 "nonmemory_operand" "")
20050 (clobber (reg:CC FLAGS_REG))])]
20051 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20052 [(set (match_dup 2) (match_dup 0))
20053 (parallel [(set (match_dup 2)
20054 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20055 (clobber (reg:CC FLAGS_REG))])
20056 (set (match_dup 0) (match_dup 2))]
20059 ;; Attempt to always use XOR for zeroing registers.
20061 [(set (match_operand 0 "register_operand" "")
20062 (match_operand 1 "const0_operand" ""))]
20063 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20064 && (! TARGET_USE_MOV0 || optimize_size)
20065 && GENERAL_REG_P (operands[0])
20066 && peep2_regno_dead_p (0, FLAGS_REG)"
20067 [(parallel [(set (match_dup 0) (const_int 0))
20068 (clobber (reg:CC FLAGS_REG))])]
20070 operands[0] = gen_lowpart (word_mode, operands[0]);
20074 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20076 "(GET_MODE (operands[0]) == QImode
20077 || GET_MODE (operands[0]) == HImode)
20078 && (! TARGET_USE_MOV0 || optimize_size)
20079 && peep2_regno_dead_p (0, FLAGS_REG)"
20080 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20081 (clobber (reg:CC FLAGS_REG))])])
20083 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20085 [(set (match_operand 0 "register_operand" "")
20087 "(GET_MODE (operands[0]) == HImode
20088 || GET_MODE (operands[0]) == SImode
20089 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20090 && (optimize_size || TARGET_PENTIUM)
20091 && peep2_regno_dead_p (0, FLAGS_REG)"
20092 [(parallel [(set (match_dup 0) (const_int -1))
20093 (clobber (reg:CC FLAGS_REG))])]
20094 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20097 ;; Attempt to convert simple leas to adds. These can be created by
20100 [(set (match_operand:SI 0 "register_operand" "")
20101 (plus:SI (match_dup 0)
20102 (match_operand:SI 1 "nonmemory_operand" "")))]
20103 "peep2_regno_dead_p (0, FLAGS_REG)"
20104 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20105 (clobber (reg:CC FLAGS_REG))])]
20109 [(set (match_operand:SI 0 "register_operand" "")
20110 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20111 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20112 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20113 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20114 (clobber (reg:CC FLAGS_REG))])]
20115 "operands[2] = gen_lowpart (SImode, operands[2]);")
20118 [(set (match_operand:DI 0 "register_operand" "")
20119 (plus:DI (match_dup 0)
20120 (match_operand:DI 1 "x86_64_general_operand" "")))]
20121 "peep2_regno_dead_p (0, FLAGS_REG)"
20122 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20123 (clobber (reg:CC FLAGS_REG))])]
20127 [(set (match_operand:SI 0 "register_operand" "")
20128 (mult:SI (match_dup 0)
20129 (match_operand:SI 1 "const_int_operand" "")))]
20130 "exact_log2 (INTVAL (operands[1])) >= 0
20131 && peep2_regno_dead_p (0, FLAGS_REG)"
20132 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20133 (clobber (reg:CC FLAGS_REG))])]
20134 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20137 [(set (match_operand:DI 0 "register_operand" "")
20138 (mult:DI (match_dup 0)
20139 (match_operand:DI 1 "const_int_operand" "")))]
20140 "exact_log2 (INTVAL (operands[1])) >= 0
20141 && peep2_regno_dead_p (0, FLAGS_REG)"
20142 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20143 (clobber (reg:CC FLAGS_REG))])]
20144 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20147 [(set (match_operand:SI 0 "register_operand" "")
20148 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20149 (match_operand:DI 2 "const_int_operand" "")) 0))]
20150 "exact_log2 (INTVAL (operands[2])) >= 0
20151 && REGNO (operands[0]) == REGNO (operands[1])
20152 && peep2_regno_dead_p (0, FLAGS_REG)"
20153 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20154 (clobber (reg:CC FLAGS_REG))])]
20155 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20157 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20158 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20159 ;; many CPUs it is also faster, since special hardware to avoid esp
20160 ;; dependencies is present.
20162 ;; While some of these conversions may be done using splitters, we use peepholes
20163 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20165 ;; Convert prologue esp subtractions to push.
20166 ;; We need register to push. In order to keep verify_flow_info happy we have
20168 ;; - use scratch and clobber it in order to avoid dependencies
20169 ;; - use already live register
20170 ;; We can't use the second way right now, since there is no reliable way how to
20171 ;; verify that given register is live. First choice will also most likely in
20172 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20173 ;; call clobbered registers are dead. We may want to use base pointer as an
20174 ;; alternative when no register is available later.
20177 [(match_scratch:SI 0 "r")
20178 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20179 (clobber (reg:CC FLAGS_REG))
20180 (clobber (mem:BLK (scratch)))])]
20181 "optimize_size || !TARGET_SUB_ESP_4"
20182 [(clobber (match_dup 0))
20183 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20184 (clobber (mem:BLK (scratch)))])])
20187 [(match_scratch:SI 0 "r")
20188 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20189 (clobber (reg:CC FLAGS_REG))
20190 (clobber (mem:BLK (scratch)))])]
20191 "optimize_size || !TARGET_SUB_ESP_8"
20192 [(clobber (match_dup 0))
20193 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20194 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20195 (clobber (mem:BLK (scratch)))])])
20197 ;; Convert esp subtractions to push.
20199 [(match_scratch:SI 0 "r")
20200 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20201 (clobber (reg:CC FLAGS_REG))])]
20202 "optimize_size || !TARGET_SUB_ESP_4"
20203 [(clobber (match_dup 0))
20204 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20207 [(match_scratch:SI 0 "r")
20208 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20209 (clobber (reg:CC FLAGS_REG))])]
20210 "optimize_size || !TARGET_SUB_ESP_8"
20211 [(clobber (match_dup 0))
20212 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20213 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20215 ;; Convert epilogue deallocator to pop.
20217 [(match_scratch:SI 0 "r")
20218 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20219 (clobber (reg:CC FLAGS_REG))
20220 (clobber (mem:BLK (scratch)))])]
20221 "optimize_size || !TARGET_ADD_ESP_4"
20222 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20223 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20224 (clobber (mem:BLK (scratch)))])]
20227 ;; Two pops case is tricky, since pop causes dependency on destination register.
20228 ;; We use two registers if available.
20230 [(match_scratch:SI 0 "r")
20231 (match_scratch:SI 1 "r")
20232 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20233 (clobber (reg:CC FLAGS_REG))
20234 (clobber (mem:BLK (scratch)))])]
20235 "optimize_size || !TARGET_ADD_ESP_8"
20236 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20237 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20238 (clobber (mem:BLK (scratch)))])
20239 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20240 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20244 [(match_scratch:SI 0 "r")
20245 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20246 (clobber (reg:CC FLAGS_REG))
20247 (clobber (mem:BLK (scratch)))])]
20249 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20250 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20251 (clobber (mem:BLK (scratch)))])
20252 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20253 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20256 ;; Convert esp additions to pop.
20258 [(match_scratch:SI 0 "r")
20259 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20260 (clobber (reg:CC FLAGS_REG))])]
20262 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20263 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20266 ;; Two pops case is tricky, since pop causes dependency on destination register.
20267 ;; We use two registers if available.
20269 [(match_scratch:SI 0 "r")
20270 (match_scratch:SI 1 "r")
20271 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20272 (clobber (reg:CC FLAGS_REG))])]
20274 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20275 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20276 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20277 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20281 [(match_scratch:SI 0 "r")
20282 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20283 (clobber (reg:CC FLAGS_REG))])]
20285 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20286 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20287 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20288 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20291 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20292 ;; required and register dies. Similarly for 128 to plus -128.
20294 [(set (match_operand 0 "flags_reg_operand" "")
20295 (match_operator 1 "compare_operator"
20296 [(match_operand 2 "register_operand" "")
20297 (match_operand 3 "const_int_operand" "")]))]
20298 "(INTVAL (operands[3]) == -1
20299 || INTVAL (operands[3]) == 1
20300 || INTVAL (operands[3]) == 128)
20301 && ix86_match_ccmode (insn, CCGCmode)
20302 && peep2_reg_dead_p (1, operands[2])"
20303 [(parallel [(set (match_dup 0)
20304 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20305 (clobber (match_dup 2))])]
20309 [(match_scratch:DI 0 "r")
20310 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20311 (clobber (reg:CC FLAGS_REG))
20312 (clobber (mem:BLK (scratch)))])]
20313 "optimize_size || !TARGET_SUB_ESP_4"
20314 [(clobber (match_dup 0))
20315 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20316 (clobber (mem:BLK (scratch)))])])
20319 [(match_scratch:DI 0 "r")
20320 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20321 (clobber (reg:CC FLAGS_REG))
20322 (clobber (mem:BLK (scratch)))])]
20323 "optimize_size || !TARGET_SUB_ESP_8"
20324 [(clobber (match_dup 0))
20325 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20326 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20327 (clobber (mem:BLK (scratch)))])])
20329 ;; Convert esp subtractions to push.
20331 [(match_scratch:DI 0 "r")
20332 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20333 (clobber (reg:CC FLAGS_REG))])]
20334 "optimize_size || !TARGET_SUB_ESP_4"
20335 [(clobber (match_dup 0))
20336 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20339 [(match_scratch:DI 0 "r")
20340 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20341 (clobber (reg:CC FLAGS_REG))])]
20342 "optimize_size || !TARGET_SUB_ESP_8"
20343 [(clobber (match_dup 0))
20344 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20345 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20347 ;; Convert epilogue deallocator to pop.
20349 [(match_scratch:DI 0 "r")
20350 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20351 (clobber (reg:CC FLAGS_REG))
20352 (clobber (mem:BLK (scratch)))])]
20353 "optimize_size || !TARGET_ADD_ESP_4"
20354 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20355 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20356 (clobber (mem:BLK (scratch)))])]
20359 ;; Two pops case is tricky, since pop causes dependency on destination register.
20360 ;; We use two registers if available.
20362 [(match_scratch:DI 0 "r")
20363 (match_scratch:DI 1 "r")
20364 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20365 (clobber (reg:CC FLAGS_REG))
20366 (clobber (mem:BLK (scratch)))])]
20367 "optimize_size || !TARGET_ADD_ESP_8"
20368 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20369 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20370 (clobber (mem:BLK (scratch)))])
20371 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20372 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20376 [(match_scratch:DI 0 "r")
20377 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20378 (clobber (reg:CC FLAGS_REG))
20379 (clobber (mem:BLK (scratch)))])]
20381 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20382 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20383 (clobber (mem:BLK (scratch)))])
20384 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20385 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20388 ;; Convert esp additions to pop.
20390 [(match_scratch:DI 0 "r")
20391 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20392 (clobber (reg:CC FLAGS_REG))])]
20394 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20395 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20398 ;; Two pops case is tricky, since pop causes dependency on destination register.
20399 ;; We use two registers if available.
20401 [(match_scratch:DI 0 "r")
20402 (match_scratch:DI 1 "r")
20403 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20404 (clobber (reg:CC FLAGS_REG))])]
20406 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20407 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20408 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20409 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20413 [(match_scratch:DI 0 "r")
20414 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20415 (clobber (reg:CC FLAGS_REG))])]
20417 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20418 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20419 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20420 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20423 ;; Convert imul by three, five and nine into lea
20426 [(set (match_operand:SI 0 "register_operand" "")
20427 (mult:SI (match_operand:SI 1 "register_operand" "")
20428 (match_operand:SI 2 "const_int_operand" "")))
20429 (clobber (reg:CC FLAGS_REG))])]
20430 "INTVAL (operands[2]) == 3
20431 || INTVAL (operands[2]) == 5
20432 || INTVAL (operands[2]) == 9"
20433 [(set (match_dup 0)
20434 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20436 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20440 [(set (match_operand:SI 0 "register_operand" "")
20441 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20442 (match_operand:SI 2 "const_int_operand" "")))
20443 (clobber (reg:CC FLAGS_REG))])]
20445 && (INTVAL (operands[2]) == 3
20446 || INTVAL (operands[2]) == 5
20447 || INTVAL (operands[2]) == 9)"
20448 [(set (match_dup 0) (match_dup 1))
20450 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20452 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20456 [(set (match_operand:DI 0 "register_operand" "")
20457 (mult:DI (match_operand:DI 1 "register_operand" "")
20458 (match_operand:DI 2 "const_int_operand" "")))
20459 (clobber (reg:CC FLAGS_REG))])]
20461 && (INTVAL (operands[2]) == 3
20462 || INTVAL (operands[2]) == 5
20463 || INTVAL (operands[2]) == 9)"
20464 [(set (match_dup 0)
20465 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20467 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20471 [(set (match_operand:DI 0 "register_operand" "")
20472 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20473 (match_operand:DI 2 "const_int_operand" "")))
20474 (clobber (reg:CC FLAGS_REG))])]
20477 && (INTVAL (operands[2]) == 3
20478 || INTVAL (operands[2]) == 5
20479 || INTVAL (operands[2]) == 9)"
20480 [(set (match_dup 0) (match_dup 1))
20482 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20484 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20486 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20487 ;; imul $32bit_imm, reg, reg is direct decoded.
20489 [(match_scratch:DI 3 "r")
20490 (parallel [(set (match_operand:DI 0 "register_operand" "")
20491 (mult:DI (match_operand:DI 1 "memory_operand" "")
20492 (match_operand:DI 2 "immediate_operand" "")))
20493 (clobber (reg:CC FLAGS_REG))])]
20494 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20495 && !satisfies_constraint_K (operands[2])"
20496 [(set (match_dup 3) (match_dup 1))
20497 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20498 (clobber (reg:CC FLAGS_REG))])]
20502 [(match_scratch:SI 3 "r")
20503 (parallel [(set (match_operand:SI 0 "register_operand" "")
20504 (mult:SI (match_operand:SI 1 "memory_operand" "")
20505 (match_operand:SI 2 "immediate_operand" "")))
20506 (clobber (reg:CC FLAGS_REG))])]
20507 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20508 && !satisfies_constraint_K (operands[2])"
20509 [(set (match_dup 3) (match_dup 1))
20510 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20511 (clobber (reg:CC FLAGS_REG))])]
20515 [(match_scratch:SI 3 "r")
20516 (parallel [(set (match_operand:DI 0 "register_operand" "")
20518 (mult:SI (match_operand:SI 1 "memory_operand" "")
20519 (match_operand:SI 2 "immediate_operand" ""))))
20520 (clobber (reg:CC FLAGS_REG))])]
20521 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20522 && !satisfies_constraint_K (operands[2])"
20523 [(set (match_dup 3) (match_dup 1))
20524 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20525 (clobber (reg:CC FLAGS_REG))])]
20528 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20529 ;; Convert it into imul reg, reg
20530 ;; It would be better to force assembler to encode instruction using long
20531 ;; immediate, but there is apparently no way to do so.
20533 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20534 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20535 (match_operand:DI 2 "const_int_operand" "")))
20536 (clobber (reg:CC FLAGS_REG))])
20537 (match_scratch:DI 3 "r")]
20538 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20539 && satisfies_constraint_K (operands[2])"
20540 [(set (match_dup 3) (match_dup 2))
20541 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20542 (clobber (reg:CC FLAGS_REG))])]
20544 if (!rtx_equal_p (operands[0], operands[1]))
20545 emit_move_insn (operands[0], operands[1]);
20549 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20550 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20551 (match_operand:SI 2 "const_int_operand" "")))
20552 (clobber (reg:CC FLAGS_REG))])
20553 (match_scratch:SI 3 "r")]
20554 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20555 && satisfies_constraint_K (operands[2])"
20556 [(set (match_dup 3) (match_dup 2))
20557 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20558 (clobber (reg:CC FLAGS_REG))])]
20560 if (!rtx_equal_p (operands[0], operands[1]))
20561 emit_move_insn (operands[0], operands[1]);
20565 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20566 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20567 (match_operand:HI 2 "immediate_operand" "")))
20568 (clobber (reg:CC FLAGS_REG))])
20569 (match_scratch:HI 3 "r")]
20570 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20571 [(set (match_dup 3) (match_dup 2))
20572 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20573 (clobber (reg:CC FLAGS_REG))])]
20575 if (!rtx_equal_p (operands[0], operands[1]))
20576 emit_move_insn (operands[0], operands[1]);
20579 ;; After splitting up read-modify operations, array accesses with memory
20580 ;; operands might end up in form:
20582 ;; movl 4(%esp), %edx
20584 ;; instead of pre-splitting:
20586 ;; addl 4(%esp), %eax
20588 ;; movl 4(%esp), %edx
20589 ;; leal (%edx,%eax,4), %eax
20592 [(parallel [(set (match_operand 0 "register_operand" "")
20593 (ashift (match_operand 1 "register_operand" "")
20594 (match_operand 2 "const_int_operand" "")))
20595 (clobber (reg:CC FLAGS_REG))])
20596 (set (match_operand 3 "register_operand")
20597 (match_operand 4 "x86_64_general_operand" ""))
20598 (parallel [(set (match_operand 5 "register_operand" "")
20599 (plus (match_operand 6 "register_operand" "")
20600 (match_operand 7 "register_operand" "")))
20601 (clobber (reg:CC FLAGS_REG))])]
20602 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20603 /* Validate MODE for lea. */
20604 && ((!TARGET_PARTIAL_REG_STALL
20605 && (GET_MODE (operands[0]) == QImode
20606 || GET_MODE (operands[0]) == HImode))
20607 || GET_MODE (operands[0]) == SImode
20608 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20609 /* We reorder load and the shift. */
20610 && !rtx_equal_p (operands[1], operands[3])
20611 && !reg_overlap_mentioned_p (operands[0], operands[4])
20612 /* Last PLUS must consist of operand 0 and 3. */
20613 && !rtx_equal_p (operands[0], operands[3])
20614 && (rtx_equal_p (operands[3], operands[6])
20615 || rtx_equal_p (operands[3], operands[7]))
20616 && (rtx_equal_p (operands[0], operands[6])
20617 || rtx_equal_p (operands[0], operands[7]))
20618 /* The intermediate operand 0 must die or be same as output. */
20619 && (rtx_equal_p (operands[0], operands[5])
20620 || peep2_reg_dead_p (3, operands[0]))"
20621 [(set (match_dup 3) (match_dup 4))
20622 (set (match_dup 0) (match_dup 1))]
20624 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20625 int scale = 1 << INTVAL (operands[2]);
20626 rtx index = gen_lowpart (Pmode, operands[1]);
20627 rtx base = gen_lowpart (Pmode, operands[3]);
20628 rtx dest = gen_lowpart (mode, operands[5]);
20630 operands[1] = gen_rtx_PLUS (Pmode, base,
20631 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20633 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20634 operands[0] = dest;
20637 ;; Call-value patterns last so that the wildcard operand does not
20638 ;; disrupt insn-recog's switch tables.
20640 (define_insn "*call_value_pop_0"
20641 [(set (match_operand 0 "" "")
20642 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20643 (match_operand:SI 2 "" "")))
20644 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20645 (match_operand:SI 3 "immediate_operand" "")))]
20648 if (SIBLING_CALL_P (insn))
20651 return "call\t%P1";
20653 [(set_attr "type" "callv")])
20655 (define_insn "*call_value_pop_1"
20656 [(set (match_operand 0 "" "")
20657 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20658 (match_operand:SI 2 "" "")))
20659 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20660 (match_operand:SI 3 "immediate_operand" "i")))]
20663 if (constant_call_address_operand (operands[1], Pmode))
20665 if (SIBLING_CALL_P (insn))
20668 return "call\t%P1";
20670 if (SIBLING_CALL_P (insn))
20673 return "call\t%A1";
20675 [(set_attr "type" "callv")])
20677 (define_insn "*call_value_0"
20678 [(set (match_operand 0 "" "")
20679 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20680 (match_operand:SI 2 "" "")))]
20683 if (SIBLING_CALL_P (insn))
20686 return "call\t%P1";
20688 [(set_attr "type" "callv")])
20690 (define_insn "*call_value_0_rex64"
20691 [(set (match_operand 0 "" "")
20692 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20693 (match_operand:DI 2 "const_int_operand" "")))]
20696 if (SIBLING_CALL_P (insn))
20699 return "call\t%P1";
20701 [(set_attr "type" "callv")])
20703 (define_insn "*call_value_1"
20704 [(set (match_operand 0 "" "")
20705 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20706 (match_operand:SI 2 "" "")))]
20707 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20709 if (constant_call_address_operand (operands[1], Pmode))
20710 return "call\t%P1";
20711 return "call\t%A1";
20713 [(set_attr "type" "callv")])
20715 (define_insn "*sibcall_value_1"
20716 [(set (match_operand 0 "" "")
20717 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20718 (match_operand:SI 2 "" "")))]
20719 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20721 if (constant_call_address_operand (operands[1], Pmode))
20725 [(set_attr "type" "callv")])
20727 (define_insn "*call_value_1_rex64"
20728 [(set (match_operand 0 "" "")
20729 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20730 (match_operand:DI 2 "" "")))]
20731 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20733 if (constant_call_address_operand (operands[1], Pmode))
20734 return "call\t%P1";
20735 return "call\t%A1";
20737 [(set_attr "type" "callv")])
20739 (define_insn "*sibcall_value_1_rex64"
20740 [(set (match_operand 0 "" "")
20741 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20742 (match_operand:DI 2 "" "")))]
20743 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20745 [(set_attr "type" "callv")])
20747 (define_insn "*sibcall_value_1_rex64_v"
20748 [(set (match_operand 0 "" "")
20749 (call (mem:QI (reg:DI R11_REG))
20750 (match_operand:DI 1 "" "")))]
20751 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20753 [(set_attr "type" "callv")])
20755 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20756 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20757 ;; caught for use by garbage collectors and the like. Using an insn that
20758 ;; maps to SIGILL makes it more likely the program will rightfully die.
20759 ;; Keeping with tradition, "6" is in honor of #UD.
20760 (define_insn "trap"
20761 [(trap_if (const_int 1) (const_int 6))]
20763 { return ASM_SHORT "0x0b0f"; }
20764 [(set_attr "length" "2")])
20766 (define_expand "sse_prologue_save"
20767 [(parallel [(set (match_operand:BLK 0 "" "")
20768 (unspec:BLK [(reg:DI 21)
20775 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20776 (use (match_operand:DI 1 "register_operand" ""))
20777 (use (match_operand:DI 2 "immediate_operand" ""))
20778 (use (label_ref:DI (match_operand 3 "" "")))])]
20782 (define_insn "*sse_prologue_save_insn"
20783 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20784 (match_operand:DI 4 "const_int_operand" "n")))
20785 (unspec:BLK [(reg:DI 21)
20792 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20793 (use (match_operand:DI 1 "register_operand" "r"))
20794 (use (match_operand:DI 2 "const_int_operand" "i"))
20795 (use (label_ref:DI (match_operand 3 "" "X")))]
20797 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20798 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20802 operands[0] = gen_rtx_MEM (Pmode,
20803 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20804 output_asm_insn (\"jmp\\t%A1\", operands);
20805 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20807 operands[4] = adjust_address (operands[0], DImode, i*16);
20808 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20809 PUT_MODE (operands[4], TImode);
20810 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20811 output_asm_insn (\"rex\", operands);
20812 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20814 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20815 CODE_LABEL_NUMBER (operands[3]));
20819 [(set_attr "type" "other")
20820 (set_attr "length_immediate" "0")
20821 (set_attr "length_address" "0")
20822 (set_attr "length" "135")
20823 (set_attr "memory" "store")
20824 (set_attr "modrm" "0")
20825 (set_attr "mode" "DI")])
20827 (define_expand "prefetch"
20828 [(prefetch (match_operand 0 "address_operand" "")
20829 (match_operand:SI 1 "const_int_operand" "")
20830 (match_operand:SI 2 "const_int_operand" ""))]
20831 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20833 int rw = INTVAL (operands[1]);
20834 int locality = INTVAL (operands[2]);
20836 gcc_assert (rw == 0 || rw == 1);
20837 gcc_assert (locality >= 0 && locality <= 3);
20838 gcc_assert (GET_MODE (operands[0]) == Pmode
20839 || GET_MODE (operands[0]) == VOIDmode);
20841 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20842 supported by SSE counterpart or the SSE prefetch is not available
20843 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20845 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20846 operands[2] = GEN_INT (3);
20848 operands[1] = const0_rtx;
20851 (define_insn "*prefetch_sse"
20852 [(prefetch (match_operand:SI 0 "address_operand" "p")
20854 (match_operand:SI 1 "const_int_operand" ""))]
20855 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20857 static const char * const patterns[4] = {
20858 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20861 int locality = INTVAL (operands[1]);
20862 gcc_assert (locality >= 0 && locality <= 3);
20864 return patterns[locality];
20866 [(set_attr "type" "sse")
20867 (set_attr "memory" "none")])
20869 (define_insn "*prefetch_sse_rex"
20870 [(prefetch (match_operand:DI 0 "address_operand" "p")
20872 (match_operand:SI 1 "const_int_operand" ""))]
20873 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20875 static const char * const patterns[4] = {
20876 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20879 int locality = INTVAL (operands[1]);
20880 gcc_assert (locality >= 0 && locality <= 3);
20882 return patterns[locality];
20884 [(set_attr "type" "sse")
20885 (set_attr "memory" "none")])
20887 (define_insn "*prefetch_3dnow"
20888 [(prefetch (match_operand:SI 0 "address_operand" "p")
20889 (match_operand:SI 1 "const_int_operand" "n")
20891 "TARGET_3DNOW && !TARGET_64BIT"
20893 if (INTVAL (operands[1]) == 0)
20894 return "prefetch\t%a0";
20896 return "prefetchw\t%a0";
20898 [(set_attr "type" "mmx")
20899 (set_attr "memory" "none")])
20901 (define_insn "*prefetch_3dnow_rex"
20902 [(prefetch (match_operand:DI 0 "address_operand" "p")
20903 (match_operand:SI 1 "const_int_operand" "n")
20905 "TARGET_3DNOW && TARGET_64BIT"
20907 if (INTVAL (operands[1]) == 0)
20908 return "prefetch\t%a0";
20910 return "prefetchw\t%a0";
20912 [(set_attr "type" "mmx")
20913 (set_attr "memory" "none")])
20915 (define_expand "stack_protect_set"
20916 [(match_operand 0 "memory_operand" "")
20917 (match_operand 1 "memory_operand" "")]
20920 #ifdef TARGET_THREAD_SSP_OFFSET
20922 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20923 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20925 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20926 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20929 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20931 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20936 (define_insn "stack_protect_set_si"
20937 [(set (match_operand:SI 0 "memory_operand" "=m")
20938 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20939 (set (match_scratch:SI 2 "=&r") (const_int 0))
20940 (clobber (reg:CC FLAGS_REG))]
20942 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20943 [(set_attr "type" "multi")])
20945 (define_insn "stack_protect_set_di"
20946 [(set (match_operand:DI 0 "memory_operand" "=m")
20947 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20948 (set (match_scratch:DI 2 "=&r") (const_int 0))
20949 (clobber (reg:CC FLAGS_REG))]
20951 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20952 [(set_attr "type" "multi")])
20954 (define_insn "stack_tls_protect_set_si"
20955 [(set (match_operand:SI 0 "memory_operand" "=m")
20956 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20957 (set (match_scratch:SI 2 "=&r") (const_int 0))
20958 (clobber (reg:CC FLAGS_REG))]
20960 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20961 [(set_attr "type" "multi")])
20963 (define_insn "stack_tls_protect_set_di"
20964 [(set (match_operand:DI 0 "memory_operand" "=m")
20965 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20966 (set (match_scratch:DI 2 "=&r") (const_int 0))
20967 (clobber (reg:CC FLAGS_REG))]
20970 /* The kernel uses a different segment register for performance reasons; a
20971 system call would not have to trash the userspace segment register,
20972 which would be expensive */
20973 if (ix86_cmodel != CM_KERNEL)
20974 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20976 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20978 [(set_attr "type" "multi")])
20980 (define_expand "stack_protect_test"
20981 [(match_operand 0 "memory_operand" "")
20982 (match_operand 1 "memory_operand" "")
20983 (match_operand 2 "" "")]
20986 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20987 ix86_compare_op0 = operands[0];
20988 ix86_compare_op1 = operands[1];
20989 ix86_compare_emitted = flags;
20991 #ifdef TARGET_THREAD_SSP_OFFSET
20993 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20994 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20996 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20997 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21000 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21002 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21004 emit_jump_insn (gen_beq (operands[2]));
21008 (define_insn "stack_protect_test_si"
21009 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21010 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21011 (match_operand:SI 2 "memory_operand" "m")]
21013 (clobber (match_scratch:SI 3 "=&r"))]
21015 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21016 [(set_attr "type" "multi")])
21018 (define_insn "stack_protect_test_di"
21019 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21020 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21021 (match_operand:DI 2 "memory_operand" "m")]
21023 (clobber (match_scratch:DI 3 "=&r"))]
21025 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21026 [(set_attr "type" "multi")])
21028 (define_insn "stack_tls_protect_test_si"
21029 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21030 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21031 (match_operand:SI 2 "const_int_operand" "i")]
21032 UNSPEC_SP_TLS_TEST))
21033 (clobber (match_scratch:SI 3 "=r"))]
21035 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21036 [(set_attr "type" "multi")])
21038 (define_insn "stack_tls_protect_test_di"
21039 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21040 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21041 (match_operand:DI 2 "const_int_operand" "i")]
21042 UNSPEC_SP_TLS_TEST))
21043 (clobber (match_scratch:DI 3 "=r"))]
21046 /* The kernel uses a different segment register for performance reasons; a
21047 system call would not have to trash the userspace segment register,
21048 which would be expensive */
21049 if (ix86_cmodel != CM_KERNEL)
21050 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21052 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21054 [(set_attr "type" "multi")])
21058 (include "sync.md")