1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING. If not, write to
22 ;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA. */
25 ;; The original PO technology requires these to be ordered by speed,
26 ;; so that assigner will pick the fastest.
28 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
30 ;; Macro REG_CLASS_FROM_LETTER in file i386.h defines the register
31 ;; constraint letters.
33 ;; The special asm out single letter directives following a '%' are:
34 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
36 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
37 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
38 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
39 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
40 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
41 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
42 ;; 'J' Print the appropriate jump operand.
44 ;; 'b' Print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; 'w' Likewise, print the HImode name of the register.
47 ;; 'k' Likewise, print the SImode name of the register.
48 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
49 ;; 'y' Print "st(0)" instead of "st" as a register.
54 [; Relocation specifiers
66 (UNSPEC_STACK_ALLOC 11)
68 (UNSPEC_SSE_PROLOGUE_SAVE 13)
75 (UNSPEC_TLS_LD_BASE 18)
78 ; Other random patterns
87 (UNSPEC_LD_MPIC 28) ; load_macho_picbase
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,cld,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,cld,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,cld,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,cld")
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 "movdi_insv_1_rex64"
1809 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
1812 (match_operand:DI 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 "*movqi_insv_2"
1819 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
1822 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
1825 "mov{b}\t{%h1, %h0|%h0, %h1}"
1826 [(set_attr "type" "imov")
1827 (set_attr "mode" "QI")])
1829 (define_expand "movdi"
1830 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1831 (match_operand:DI 1 "general_operand" ""))]
1833 "ix86_expand_move (DImode, operands); DONE;")
1835 (define_insn "*pushdi"
1836 [(set (match_operand:DI 0 "push_operand" "=<")
1837 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1841 (define_insn "*pushdi2_rex64"
1842 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1843 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1848 [(set_attr "type" "push,multi")
1849 (set_attr "mode" "DI")])
1851 ;; Convert impossible pushes of immediate to existing instructions.
1852 ;; First try to get scratch register and go through it. In case this
1853 ;; fails, push sign extended lower part first and then overwrite
1854 ;; upper part by 32bit move.
1856 [(match_scratch:DI 2 "r")
1857 (set (match_operand:DI 0 "push_operand" "")
1858 (match_operand:DI 1 "immediate_operand" ""))]
1859 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1860 && !x86_64_immediate_operand (operands[1], DImode)"
1861 [(set (match_dup 2) (match_dup 1))
1862 (set (match_dup 0) (match_dup 2))]
1865 ;; We need to define this as both peepholer and splitter for case
1866 ;; peephole2 pass is not run.
1867 ;; "&& 1" is needed to keep it from matching the previous pattern.
1869 [(set (match_operand:DI 0 "push_operand" "")
1870 (match_operand:DI 1 "immediate_operand" ""))]
1871 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1872 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1873 [(set (match_dup 0) (match_dup 1))
1874 (set (match_dup 2) (match_dup 3))]
1875 "split_di (operands + 1, 1, operands + 2, operands + 3);
1876 operands[1] = gen_lowpart (DImode, operands[2]);
1877 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1882 [(set (match_operand:DI 0 "push_operand" "")
1883 (match_operand:DI 1 "immediate_operand" ""))]
1884 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1885 ? flow2_completed : reload_completed)
1886 && !symbolic_operand (operands[1], DImode)
1887 && !x86_64_immediate_operand (operands[1], DImode)"
1888 [(set (match_dup 0) (match_dup 1))
1889 (set (match_dup 2) (match_dup 3))]
1890 "split_di (operands + 1, 1, operands + 2, operands + 3);
1891 operands[1] = gen_lowpart (DImode, operands[2]);
1892 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1896 (define_insn "*pushdi2_prologue_rex64"
1897 [(set (match_operand:DI 0 "push_operand" "=<")
1898 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
1899 (clobber (mem:BLK (scratch)))]
1902 [(set_attr "type" "push")
1903 (set_attr "mode" "DI")])
1905 (define_insn "*popdi1_epilogue_rex64"
1906 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1907 (mem:DI (reg:DI SP_REG)))
1908 (set (reg:DI SP_REG)
1909 (plus:DI (reg:DI SP_REG) (const_int 8)))
1910 (clobber (mem:BLK (scratch)))]
1913 [(set_attr "type" "pop")
1914 (set_attr "mode" "DI")])
1916 (define_insn "popdi1"
1917 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
1918 (mem:DI (reg:DI SP_REG)))
1919 (set (reg:DI SP_REG)
1920 (plus:DI (reg:DI SP_REG) (const_int 8)))]
1923 [(set_attr "type" "pop")
1924 (set_attr "mode" "DI")])
1926 (define_insn "*movdi_xor_rex64"
1927 [(set (match_operand:DI 0 "register_operand" "=r")
1928 (match_operand:DI 1 "const0_operand" "i"))
1929 (clobber (reg:CC FLAGS_REG))]
1930 "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
1931 && reload_completed"
1932 "xor{l}\t{%k0, %k0|%k0, %k0}"
1933 [(set_attr "type" "alu1")
1934 (set_attr "mode" "SI")
1935 (set_attr "length_immediate" "0")])
1937 (define_insn "*movdi_or_rex64"
1938 [(set (match_operand:DI 0 "register_operand" "=r")
1939 (match_operand:DI 1 "const_int_operand" "i"))
1940 (clobber (reg:CC FLAGS_REG))]
1941 "TARGET_64BIT && (TARGET_PENTIUM || optimize_size)
1943 && operands[1] == constm1_rtx"
1945 operands[1] = constm1_rtx;
1946 return "or{q}\t{%1, %0|%0, %1}";
1948 [(set_attr "type" "alu1")
1949 (set_attr "mode" "DI")
1950 (set_attr "length_immediate" "1")])
1952 (define_insn "*movdi_2"
1953 [(set (match_operand:DI 0 "nonimmediate_operand"
1954 "=r ,o ,*y,m*y,*y,*Y,m ,*Y,*Y,*x,m ,*x,*x")
1955 (match_operand:DI 1 "general_operand"
1956 "riFo,riF,C ,*y ,m ,C ,*Y,*Y,m ,C ,*x,*x,m "))]
1957 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1962 movq\t{%1, %0|%0, %1}
1963 movq\t{%1, %0|%0, %1}
1965 movq\t{%1, %0|%0, %1}
1966 movdqa\t{%1, %0|%0, %1}
1967 movq\t{%1, %0|%0, %1}
1969 movlps\t{%1, %0|%0, %1}
1970 movaps\t{%1, %0|%0, %1}
1971 movlps\t{%1, %0|%0, %1}"
1972 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
1973 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
1976 [(set (match_operand:DI 0 "push_operand" "")
1977 (match_operand:DI 1 "general_operand" ""))]
1978 "!TARGET_64BIT && reload_completed
1979 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1981 "ix86_split_long_move (operands); DONE;")
1983 ;; %%% This multiword shite has got to go.
1985 [(set (match_operand:DI 0 "nonimmediate_operand" "")
1986 (match_operand:DI 1 "general_operand" ""))]
1987 "!TARGET_64BIT && reload_completed
1988 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
1989 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
1991 "ix86_split_long_move (operands); DONE;")
1993 (define_insn "*movdi_1_rex64"
1994 [(set (match_operand:DI 0 "nonimmediate_operand"
1995 "=r,r ,r,m ,!m,*y,*y,?rm,?*y,*x,*x,?rm,?*x,?*x,?*y")
1996 (match_operand:DI 1 "general_operand"
1997 "Z ,rem,i,re,n ,C ,*y,*y ,rm ,C ,*x,*x ,rm ,*y ,*x"))]
1998 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2000 switch (get_attr_type (insn))
2003 if (which_alternative == 13)
2004 return "movq2dq\t{%1, %0|%0, %1}";
2006 return "movdq2q\t{%1, %0|%0, %1}";
2008 if (get_attr_mode (insn) == MODE_TI)
2009 return "movdqa\t{%1, %0|%0, %1}";
2012 /* Moves from and into integer register is done using movd opcode with
2014 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2015 return "movd\t{%1, %0|%0, %1}";
2016 return "movq\t{%1, %0|%0, %1}";
2019 return "pxor\t%0, %0";
2023 return "lea{q}\t{%a1, %0|%0, %a1}";
2025 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2026 if (get_attr_mode (insn) == MODE_SI)
2027 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2028 else if (which_alternative == 2)
2029 return "movabs{q}\t{%1, %0|%0, %1}";
2031 return "mov{q}\t{%1, %0|%0, %1}";
2035 (cond [(eq_attr "alternative" "5")
2036 (const_string "mmxadd")
2037 (eq_attr "alternative" "6,7,8")
2038 (const_string "mmxmov")
2039 (eq_attr "alternative" "9")
2040 (const_string "sselog1")
2041 (eq_attr "alternative" "10,11,12")
2042 (const_string "ssemov")
2043 (eq_attr "alternative" "13,14")
2044 (const_string "ssecvt")
2045 (eq_attr "alternative" "4")
2046 (const_string "multi")
2047 (match_operand:DI 1 "pic_32bit_operand" "")
2048 (const_string "lea")
2050 (const_string "imov")))
2051 (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*")
2052 (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*")
2053 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI")])
2055 ;; Stores and loads of ax to arbitrary constant address.
2056 ;; We fake an second form of instruction to force reload to load address
2057 ;; into register when rax is not available
2058 (define_insn "*movabsdi_1_rex64"
2059 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2060 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2061 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2063 movabs{q}\t{%1, %P0|%P0, %1}
2064 mov{q}\t{%1, %a0|%a0, %1}"
2065 [(set_attr "type" "imov")
2066 (set_attr "modrm" "0,*")
2067 (set_attr "length_address" "8,0")
2068 (set_attr "length_immediate" "0,*")
2069 (set_attr "memory" "store")
2070 (set_attr "mode" "DI")])
2072 (define_insn "*movabsdi_2_rex64"
2073 [(set (match_operand:DI 0 "register_operand" "=a,r")
2074 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2075 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2077 movabs{q}\t{%P1, %0|%0, %P1}
2078 mov{q}\t{%a1, %0|%0, %a1}"
2079 [(set_attr "type" "imov")
2080 (set_attr "modrm" "0,*")
2081 (set_attr "length_address" "8,0")
2082 (set_attr "length_immediate" "0")
2083 (set_attr "memory" "load")
2084 (set_attr "mode" "DI")])
2086 ;; Convert impossible stores of immediate to existing instructions.
2087 ;; First try to get scratch register and go through it. In case this
2088 ;; fails, move by 32bit parts.
2090 [(match_scratch:DI 2 "r")
2091 (set (match_operand:DI 0 "memory_operand" "")
2092 (match_operand:DI 1 "immediate_operand" ""))]
2093 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2094 && !x86_64_immediate_operand (operands[1], DImode)"
2095 [(set (match_dup 2) (match_dup 1))
2096 (set (match_dup 0) (match_dup 2))]
2099 ;; We need to define this as both peepholer and splitter for case
2100 ;; peephole2 pass is not run.
2101 ;; "&& 1" is needed to keep it from matching the previous pattern.
2103 [(set (match_operand:DI 0 "memory_operand" "")
2104 (match_operand:DI 1 "immediate_operand" ""))]
2105 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2106 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2107 [(set (match_dup 2) (match_dup 3))
2108 (set (match_dup 4) (match_dup 5))]
2109 "split_di (operands, 2, operands + 2, operands + 4);")
2112 [(set (match_operand:DI 0 "memory_operand" "")
2113 (match_operand:DI 1 "immediate_operand" ""))]
2114 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2115 ? flow2_completed : reload_completed)
2116 && !symbolic_operand (operands[1], DImode)
2117 && !x86_64_immediate_operand (operands[1], DImode)"
2118 [(set (match_dup 2) (match_dup 3))
2119 (set (match_dup 4) (match_dup 5))]
2120 "split_di (operands, 2, operands + 2, operands + 4);")
2122 (define_insn "*swapdi_rex64"
2123 [(set (match_operand:DI 0 "register_operand" "+r")
2124 (match_operand:DI 1 "register_operand" "+r"))
2129 [(set_attr "type" "imov")
2130 (set_attr "mode" "DI")
2131 (set_attr "pent_pair" "np")
2132 (set_attr "athlon_decode" "vector")])
2134 (define_expand "movti"
2135 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2136 (match_operand:TI 1 "nonimmediate_operand" ""))]
2137 "TARGET_SSE || TARGET_64BIT"
2140 ix86_expand_move (TImode, operands);
2142 ix86_expand_vector_move (TImode, operands);
2146 (define_insn "*movti_internal"
2147 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2148 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2149 "TARGET_SSE && !TARGET_64BIT
2150 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2152 switch (which_alternative)
2155 if (get_attr_mode (insn) == MODE_V4SF)
2156 return "xorps\t%0, %0";
2158 return "pxor\t%0, %0";
2161 if (get_attr_mode (insn) == MODE_V4SF)
2162 return "movaps\t{%1, %0|%0, %1}";
2164 return "movdqa\t{%1, %0|%0, %1}";
2169 [(set_attr "type" "sselog1,ssemov,ssemov")
2171 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2172 (ne (symbol_ref "optimize_size") (const_int 0)))
2173 (const_string "V4SF")
2174 (and (eq_attr "alternative" "2")
2175 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2177 (const_string "V4SF")]
2178 (const_string "TI")))])
2180 (define_insn "*movti_rex64"
2181 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2182 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2184 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2186 switch (which_alternative)
2192 if (get_attr_mode (insn) == MODE_V4SF)
2193 return "xorps\t%0, %0";
2195 return "pxor\t%0, %0";
2198 if (get_attr_mode (insn) == MODE_V4SF)
2199 return "movaps\t{%1, %0|%0, %1}";
2201 return "movdqa\t{%1, %0|%0, %1}";
2206 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2208 (cond [(eq_attr "alternative" "2,3")
2210 (ne (symbol_ref "optimize_size")
2212 (const_string "V4SF")
2213 (const_string "TI"))
2214 (eq_attr "alternative" "4")
2216 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2218 (ne (symbol_ref "optimize_size")
2220 (const_string "V4SF")
2221 (const_string "TI"))]
2222 (const_string "DI")))])
2225 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2226 (match_operand:TI 1 "general_operand" ""))]
2227 "reload_completed && !SSE_REG_P (operands[0])
2228 && !SSE_REG_P (operands[1])"
2230 "ix86_split_long_move (operands); DONE;")
2232 (define_expand "movsf"
2233 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2234 (match_operand:SF 1 "general_operand" ""))]
2236 "ix86_expand_move (SFmode, operands); DONE;")
2238 (define_insn "*pushsf"
2239 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2240 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2243 /* Anything else should be already split before reg-stack. */
2244 gcc_assert (which_alternative == 1);
2245 return "push{l}\t%1";
2247 [(set_attr "type" "multi,push,multi")
2248 (set_attr "unit" "i387,*,*")
2249 (set_attr "mode" "SF,SI,SF")])
2251 (define_insn "*pushsf_rex64"
2252 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2253 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2256 /* Anything else should be already split before reg-stack. */
2257 gcc_assert (which_alternative == 1);
2258 return "push{q}\t%q1";
2260 [(set_attr "type" "multi,push,multi")
2261 (set_attr "unit" "i387,*,*")
2262 (set_attr "mode" "SF,DI,SF")])
2265 [(set (match_operand:SF 0 "push_operand" "")
2266 (match_operand:SF 1 "memory_operand" ""))]
2268 && GET_CODE (operands[1]) == MEM
2269 && constant_pool_reference_p (operands[1])"
2272 "operands[1] = avoid_constant_pool_reference (operands[1]);")
2275 ;; %%% Kill this when call knows how to work this out.
2277 [(set (match_operand:SF 0 "push_operand" "")
2278 (match_operand:SF 1 "any_fp_register_operand" ""))]
2280 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2281 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2284 [(set (match_operand:SF 0 "push_operand" "")
2285 (match_operand:SF 1 "any_fp_register_operand" ""))]
2287 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2288 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2290 (define_insn "*movsf_1"
2291 [(set (match_operand:SF 0 "nonimmediate_operand"
2292 "=f,m ,f,r ,m ,x,x,x ,m ,!*y,!rm,!*y")
2293 (match_operand:SF 1 "general_operand"
2294 "fm,f,G ,rmF,Fr,C ,x ,xm,x,rm ,*y ,*y"))]
2295 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2296 && (reload_in_progress || reload_completed
2297 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2298 || GET_CODE (operands[1]) != CONST_DOUBLE
2299 || memory_operand (operands[0], SFmode))"
2301 switch (which_alternative)
2304 return output_387_reg_move (insn, operands);
2307 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2308 return "fstp%z0\t%y0";
2310 return "fst%z0\t%y0";
2313 return standard_80387_constant_opcode (operands[1]);
2317 return "mov{l}\t{%1, %0|%0, %1}";
2319 if (get_attr_mode (insn) == MODE_TI)
2320 return "pxor\t%0, %0";
2322 return "xorps\t%0, %0";
2324 if (get_attr_mode (insn) == MODE_V4SF)
2325 return "movaps\t{%1, %0|%0, %1}";
2327 return "movss\t{%1, %0|%0, %1}";
2330 return "movss\t{%1, %0|%0, %1}";
2334 return "movd\t{%1, %0|%0, %1}";
2337 return "movq\t{%1, %0|%0, %1}";
2343 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov")
2345 (cond [(eq_attr "alternative" "3,4,9,10")
2347 (eq_attr "alternative" "5")
2349 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2351 (ne (symbol_ref "TARGET_SSE2")
2353 (eq (symbol_ref "optimize_size")
2356 (const_string "V4SF"))
2357 /* For architectures resolving dependencies on
2358 whole SSE registers use APS move to break dependency
2359 chains, otherwise use short move to avoid extra work.
2361 Do the same for architectures resolving dependencies on
2362 the parts. While in DF mode it is better to always handle
2363 just register parts, the SF mode is different due to lack
2364 of instructions to load just part of the register. It is
2365 better to maintain the whole registers in single format
2366 to avoid problems on using packed logical operations. */
2367 (eq_attr "alternative" "6")
2369 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2371 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2373 (const_string "V4SF")
2374 (const_string "SF"))
2375 (eq_attr "alternative" "11")
2376 (const_string "DI")]
2377 (const_string "SF")))])
2379 (define_insn "*swapsf"
2380 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2381 (match_operand:SF 1 "fp_register_operand" "+f"))
2384 "reload_completed || TARGET_80387"
2386 if (STACK_TOP_P (operands[0]))
2391 [(set_attr "type" "fxch")
2392 (set_attr "mode" "SF")])
2394 (define_expand "movdf"
2395 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2396 (match_operand:DF 1 "general_operand" ""))]
2398 "ix86_expand_move (DFmode, operands); DONE;")
2400 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2401 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2402 ;; On the average, pushdf using integers can be still shorter. Allow this
2403 ;; pattern for optimize_size too.
2405 (define_insn "*pushdf_nointeger"
2406 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2407 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y"))]
2408 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2410 /* This insn should be already split before reg-stack. */
2413 [(set_attr "type" "multi")
2414 (set_attr "unit" "i387,*,*,*")
2415 (set_attr "mode" "DF,SI,SI,DF")])
2417 (define_insn "*pushdf_integer"
2418 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2419 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,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,DF")])
2429 ;; %%% Kill this when call knows how to work this out.
2431 [(set (match_operand:DF 0 "push_operand" "")
2432 (match_operand:DF 1 "any_fp_register_operand" ""))]
2433 "!TARGET_64BIT && reload_completed"
2434 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2435 (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2439 [(set (match_operand:DF 0 "push_operand" "")
2440 (match_operand:DF 1 "any_fp_register_operand" ""))]
2441 "TARGET_64BIT && reload_completed"
2442 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2443 (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2447 [(set (match_operand:DF 0 "push_operand" "")
2448 (match_operand:DF 1 "general_operand" ""))]
2451 "ix86_split_long_move (operands); DONE;")
2453 ;; Moving is usually shorter when only FP registers are used. This separate
2454 ;; movdf pattern avoids the use of integer registers for FP operations
2455 ;; when optimizing for size.
2457 (define_insn "*movdf_nointeger"
2458 [(set (match_operand:DF 0 "nonimmediate_operand"
2459 "=f,m,f,*r ,o ,Y*x,Y*x,Y*x ,m ")
2460 (match_operand:DF 1 "general_operand"
2461 "fm,f,G,*roF,F*r,C ,Y*x,mY*x,Y*x"))]
2462 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2463 && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2464 && (reload_in_progress || reload_completed
2465 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2466 || GET_CODE (operands[1]) != CONST_DOUBLE
2467 || memory_operand (operands[0], DFmode))"
2469 switch (which_alternative)
2472 return output_387_reg_move (insn, operands);
2475 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2476 return "fstp%z0\t%y0";
2478 return "fst%z0\t%y0";
2481 return standard_80387_constant_opcode (operands[1]);
2487 switch (get_attr_mode (insn))
2490 return "xorps\t%0, %0";
2492 return "xorpd\t%0, %0";
2494 return "pxor\t%0, %0";
2501 switch (get_attr_mode (insn))
2504 return "movaps\t{%1, %0|%0, %1}";
2506 return "movapd\t{%1, %0|%0, %1}";
2508 return "movdqa\t{%1, %0|%0, %1}";
2510 return "movq\t{%1, %0|%0, %1}";
2512 return "movsd\t{%1, %0|%0, %1}";
2514 return "movlpd\t{%1, %0|%0, %1}";
2516 return "movlps\t{%1, %0|%0, %1}";
2525 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2527 (cond [(eq_attr "alternative" "0,1,2")
2529 (eq_attr "alternative" "3,4")
2532 /* For SSE1, we have many fewer alternatives. */
2533 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2534 (cond [(eq_attr "alternative" "5,6")
2535 (const_string "V4SF")
2537 (const_string "V2SF"))
2539 /* xorps is one byte shorter. */
2540 (eq_attr "alternative" "5")
2541 (cond [(ne (symbol_ref "optimize_size")
2543 (const_string "V4SF")
2544 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2548 (const_string "V2DF"))
2550 /* For architectures resolving dependencies on
2551 whole SSE registers use APD move to break dependency
2552 chains, otherwise use short move to avoid extra work.
2554 movaps encodes one byte shorter. */
2555 (eq_attr "alternative" "6")
2557 [(ne (symbol_ref "optimize_size")
2559 (const_string "V4SF")
2560 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2562 (const_string "V2DF")
2564 (const_string "DF"))
2565 /* For architectures resolving dependencies on register
2566 parts we may avoid extra work to zero out upper part
2568 (eq_attr "alternative" "7")
2570 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2572 (const_string "V1DF")
2573 (const_string "DF"))
2575 (const_string "DF")))])
2577 (define_insn "*movdf_integer"
2578 [(set (match_operand:DF 0 "nonimmediate_operand"
2579 "=f,m,f,r ,o ,Y*x,Y*x,Y*x,m ")
2580 (match_operand:DF 1 "general_operand"
2581 "fm,f,G,roF,Fr,C ,Y*x,m ,Y*x"))]
2582 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2583 && ((!optimize_size && TARGET_INTEGER_DFMODE_MOVES) || TARGET_64BIT)
2584 && (reload_in_progress || reload_completed
2585 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2586 || GET_CODE (operands[1]) != CONST_DOUBLE
2587 || memory_operand (operands[0], DFmode))"
2589 switch (which_alternative)
2592 return output_387_reg_move (insn, operands);
2595 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2596 return "fstp%z0\t%y0";
2598 return "fst%z0\t%y0";
2601 return standard_80387_constant_opcode (operands[1]);
2608 switch (get_attr_mode (insn))
2611 return "xorps\t%0, %0";
2613 return "xorpd\t%0, %0";
2615 return "pxor\t%0, %0";
2622 switch (get_attr_mode (insn))
2625 return "movaps\t{%1, %0|%0, %1}";
2627 return "movapd\t{%1, %0|%0, %1}";
2629 return "movdqa\t{%1, %0|%0, %1}";
2631 return "movq\t{%1, %0|%0, %1}";
2633 return "movsd\t{%1, %0|%0, %1}";
2635 return "movlpd\t{%1, %0|%0, %1}";
2637 return "movlps\t{%1, %0|%0, %1}";
2646 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2648 (cond [(eq_attr "alternative" "0,1,2")
2650 (eq_attr "alternative" "3,4")
2653 /* For SSE1, we have many fewer alternatives. */
2654 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2655 (cond [(eq_attr "alternative" "5,6")
2656 (const_string "V4SF")
2658 (const_string "V2SF"))
2660 /* xorps is one byte shorter. */
2661 (eq_attr "alternative" "5")
2662 (cond [(ne (symbol_ref "optimize_size")
2664 (const_string "V4SF")
2665 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2669 (const_string "V2DF"))
2671 /* For architectures resolving dependencies on
2672 whole SSE registers use APD move to break dependency
2673 chains, otherwise use short move to avoid extra work.
2675 movaps encodes one byte shorter. */
2676 (eq_attr "alternative" "6")
2678 [(ne (symbol_ref "optimize_size")
2680 (const_string "V4SF")
2681 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2683 (const_string "V2DF")
2685 (const_string "DF"))
2686 /* For architectures resolving dependencies on register
2687 parts we may avoid extra work to zero out upper part
2689 (eq_attr "alternative" "7")
2691 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2693 (const_string "V1DF")
2694 (const_string "DF"))
2696 (const_string "DF")))])
2699 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2700 (match_operand:DF 1 "general_operand" ""))]
2702 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2703 && ! (ANY_FP_REG_P (operands[0]) ||
2704 (GET_CODE (operands[0]) == SUBREG
2705 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2706 && ! (ANY_FP_REG_P (operands[1]) ||
2707 (GET_CODE (operands[1]) == SUBREG
2708 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2710 "ix86_split_long_move (operands); DONE;")
2712 (define_insn "*swapdf"
2713 [(set (match_operand:DF 0 "fp_register_operand" "+f")
2714 (match_operand:DF 1 "fp_register_operand" "+f"))
2717 "reload_completed || TARGET_80387"
2719 if (STACK_TOP_P (operands[0]))
2724 [(set_attr "type" "fxch")
2725 (set_attr "mode" "DF")])
2727 (define_expand "movxf"
2728 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2729 (match_operand:XF 1 "general_operand" ""))]
2731 "ix86_expand_move (XFmode, operands); DONE;")
2733 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2734 ;; Size of pushdf using integer instructions is 3+3*memory operand size
2735 ;; Pushing using integer instructions is longer except for constants
2736 ;; and direct memory references.
2737 ;; (assuming that any given constant is pushed only once, but this ought to be
2738 ;; handled elsewhere).
2740 (define_insn "*pushxf_nointeger"
2741 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2742 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2745 /* This insn should be already split before reg-stack. */
2748 [(set_attr "type" "multi")
2749 (set_attr "unit" "i387,*,*")
2750 (set_attr "mode" "XF,SI,SI")])
2752 (define_insn "*pushxf_integer"
2753 [(set (match_operand:XF 0 "push_operand" "=<,<")
2754 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2757 /* This insn should be already split before reg-stack. */
2760 [(set_attr "type" "multi")
2761 (set_attr "unit" "i387,*")
2762 (set_attr "mode" "XF,SI")])
2765 [(set (match_operand 0 "push_operand" "")
2766 (match_operand 1 "general_operand" ""))]
2768 && (GET_MODE (operands[0]) == XFmode
2769 || GET_MODE (operands[0]) == DFmode)
2770 && !ANY_FP_REG_P (operands[1])"
2772 "ix86_split_long_move (operands); DONE;")
2775 [(set (match_operand:XF 0 "push_operand" "")
2776 (match_operand:XF 1 "any_fp_register_operand" ""))]
2778 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
2779 (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
2780 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2783 [(set (match_operand:XF 0 "push_operand" "")
2784 (match_operand:XF 1 "any_fp_register_operand" ""))]
2786 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
2787 (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
2788 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
2790 ;; Do not use integer registers when optimizing for size
2791 (define_insn "*movxf_nointeger"
2792 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2793 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2795 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2796 && (reload_in_progress || reload_completed
2797 || standard_80387_constant_p (operands[1])
2798 || GET_CODE (operands[1]) != CONST_DOUBLE
2799 || memory_operand (operands[0], XFmode))"
2801 switch (which_alternative)
2804 return output_387_reg_move (insn, operands);
2807 /* There is no non-popping store to memory for XFmode. So if
2808 we need one, follow the store with a load. */
2809 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2810 return "fstp%z0\t%y0\;fld%z0\t%y0";
2812 return "fstp%z0\t%y0";
2815 return standard_80387_constant_opcode (operands[1]);
2823 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2824 (set_attr "mode" "XF,XF,XF,SI,SI")])
2826 (define_insn "*movxf_integer"
2827 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2828 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2830 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2831 && (reload_in_progress || reload_completed
2832 || standard_80387_constant_p (operands[1])
2833 || GET_CODE (operands[1]) != CONST_DOUBLE
2834 || memory_operand (operands[0], XFmode))"
2836 switch (which_alternative)
2839 return output_387_reg_move (insn, operands);
2842 /* There is no non-popping store to memory for XFmode. So if
2843 we need one, follow the store with a load. */
2844 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
2845 return "fstp%z0\t%y0\;fld%z0\t%y0";
2847 return "fstp%z0\t%y0";
2850 return standard_80387_constant_opcode (operands[1]);
2859 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2860 (set_attr "mode" "XF,XF,XF,SI,SI")])
2863 [(set (match_operand 0 "nonimmediate_operand" "")
2864 (match_operand 1 "general_operand" ""))]
2866 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
2867 && GET_MODE (operands[0]) == XFmode
2868 && ! (ANY_FP_REG_P (operands[0]) ||
2869 (GET_CODE (operands[0]) == SUBREG
2870 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2871 && ! (ANY_FP_REG_P (operands[1]) ||
2872 (GET_CODE (operands[1]) == SUBREG
2873 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2875 "ix86_split_long_move (operands); DONE;")
2878 [(set (match_operand 0 "register_operand" "")
2879 (match_operand 1 "memory_operand" ""))]
2881 && GET_CODE (operands[1]) == MEM
2882 && (GET_MODE (operands[0]) == XFmode
2883 || GET_MODE (operands[0]) == SFmode || GET_MODE (operands[0]) == DFmode)
2884 && constant_pool_reference_p (operands[1])"
2885 [(set (match_dup 0) (match_dup 1))]
2887 rtx c = avoid_constant_pool_reference (operands[1]);
2888 rtx r = operands[0];
2890 if (GET_CODE (r) == SUBREG)
2895 if (!standard_sse_constant_p (c))
2898 else if (FP_REG_P (r))
2900 if (!standard_80387_constant_p (c))
2903 else if (MMX_REG_P (r))
2909 (define_insn "swapxf"
2910 [(set (match_operand:XF 0 "register_operand" "+f")
2911 (match_operand:XF 1 "register_operand" "+f"))
2916 if (STACK_TOP_P (operands[0]))
2921 [(set_attr "type" "fxch")
2922 (set_attr "mode" "XF")])
2924 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
2926 [(set (match_operand:X87MODEF 0 "register_operand" "")
2927 (match_operand:X87MODEF 1 "immediate_operand" ""))]
2928 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
2929 && (standard_80387_constant_p (operands[1]) == 8
2930 || standard_80387_constant_p (operands[1]) == 9)"
2931 [(set (match_dup 0)(match_dup 1))
2933 (neg:X87MODEF (match_dup 0)))]
2937 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
2938 if (real_isnegzero (&r))
2939 operands[1] = CONST0_RTX (<MODE>mode);
2941 operands[1] = CONST1_RTX (<MODE>mode);
2944 (define_expand "movtf"
2945 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2946 (match_operand:TF 1 "nonimmediate_operand" ""))]
2949 ix86_expand_move (TFmode, operands);
2953 (define_insn "*movtf_internal"
2954 [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,x,x,xm")
2955 (match_operand:TF 1 "general_operand" "riFo,riF,C,xm,x"))]
2957 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
2959 switch (which_alternative)
2965 if (get_attr_mode (insn) == MODE_V4SF)
2966 return "xorps\t%0, %0";
2968 return "pxor\t%0, %0";
2971 if (get_attr_mode (insn) == MODE_V4SF)
2972 return "movaps\t{%1, %0|%0, %1}";
2974 return "movdqa\t{%1, %0|%0, %1}";
2979 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2981 (cond [(eq_attr "alternative" "2,3")
2983 (ne (symbol_ref "optimize_size")
2985 (const_string "V4SF")
2986 (const_string "TI"))
2987 (eq_attr "alternative" "4")
2989 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2991 (ne (symbol_ref "optimize_size")
2993 (const_string "V4SF")
2994 (const_string "TI"))]
2995 (const_string "DI")))])
2998 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2999 (match_operand:TF 1 "general_operand" ""))]
3000 "reload_completed && !SSE_REG_P (operands[0])
3001 && !SSE_REG_P (operands[1])"
3003 "ix86_split_long_move (operands); DONE;")
3005 ;; Zero extension instructions
3007 (define_expand "zero_extendhisi2"
3008 [(set (match_operand:SI 0 "register_operand" "")
3009 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3012 if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3014 operands[1] = force_reg (HImode, operands[1]);
3015 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3020 (define_insn "zero_extendhisi2_and"
3021 [(set (match_operand:SI 0 "register_operand" "=r")
3022 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3023 (clobber (reg:CC FLAGS_REG))]
3024 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3026 [(set_attr "type" "alu1")
3027 (set_attr "mode" "SI")])
3030 [(set (match_operand:SI 0 "register_operand" "")
3031 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3032 (clobber (reg:CC FLAGS_REG))]
3033 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3034 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3035 (clobber (reg:CC FLAGS_REG))])]
3038 (define_insn "*zero_extendhisi2_movzwl"
3039 [(set (match_operand:SI 0 "register_operand" "=r")
3040 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3041 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3042 "movz{wl|x}\t{%1, %0|%0, %1}"
3043 [(set_attr "type" "imovx")
3044 (set_attr "mode" "SI")])
3046 (define_expand "zero_extendqihi2"
3048 [(set (match_operand:HI 0 "register_operand" "")
3049 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3050 (clobber (reg:CC FLAGS_REG))])]
3054 (define_insn "*zero_extendqihi2_and"
3055 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3056 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3057 (clobber (reg:CC FLAGS_REG))]
3058 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3060 [(set_attr "type" "alu1")
3061 (set_attr "mode" "HI")])
3063 (define_insn "*zero_extendqihi2_movzbw_and"
3064 [(set (match_operand:HI 0 "register_operand" "=r,r")
3065 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3066 (clobber (reg:CC FLAGS_REG))]
3067 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3069 [(set_attr "type" "imovx,alu1")
3070 (set_attr "mode" "HI")])
3072 ; zero extend to SImode here to avoid partial register stalls
3073 (define_insn "*zero_extendqihi2_movzbl"
3074 [(set (match_operand:HI 0 "register_operand" "=r")
3075 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3076 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3077 "movz{bl|x}\t{%1, %k0|%k0, %k1}"
3078 [(set_attr "type" "imovx")
3079 (set_attr "mode" "SI")])
3081 ;; For the movzbw case strip only the clobber
3083 [(set (match_operand:HI 0 "register_operand" "")
3084 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3085 (clobber (reg:CC FLAGS_REG))]
3087 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3088 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3089 [(set (match_operand:HI 0 "register_operand" "")
3090 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3092 ;; When source and destination does not overlap, clear destination
3093 ;; first and then do the movb
3095 [(set (match_operand:HI 0 "register_operand" "")
3096 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3097 (clobber (reg:CC FLAGS_REG))]
3099 && ANY_QI_REG_P (operands[0])
3100 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3101 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3102 [(set (match_dup 0) (const_int 0))
3103 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3104 "operands[2] = gen_lowpart (QImode, operands[0]);")
3106 ;; Rest is handled by single and.
3108 [(set (match_operand:HI 0 "register_operand" "")
3109 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3110 (clobber (reg:CC FLAGS_REG))]
3112 && true_regnum (operands[0]) == true_regnum (operands[1])"
3113 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3114 (clobber (reg:CC FLAGS_REG))])]
3117 (define_expand "zero_extendqisi2"
3119 [(set (match_operand:SI 0 "register_operand" "")
3120 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3121 (clobber (reg:CC FLAGS_REG))])]
3125 (define_insn "*zero_extendqisi2_and"
3126 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3127 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3128 (clobber (reg:CC FLAGS_REG))]
3129 "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3131 [(set_attr "type" "alu1")
3132 (set_attr "mode" "SI")])
3134 (define_insn "*zero_extendqisi2_movzbw_and"
3135 [(set (match_operand:SI 0 "register_operand" "=r,r")
3136 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3137 (clobber (reg:CC FLAGS_REG))]
3138 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3140 [(set_attr "type" "imovx,alu1")
3141 (set_attr "mode" "SI")])
3143 (define_insn "*zero_extendqisi2_movzbw"
3144 [(set (match_operand:SI 0 "register_operand" "=r")
3145 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3146 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3147 "movz{bl|x}\t{%1, %0|%0, %1}"
3148 [(set_attr "type" "imovx")
3149 (set_attr "mode" "SI")])
3151 ;; For the movzbl case strip only the clobber
3153 [(set (match_operand:SI 0 "register_operand" "")
3154 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3155 (clobber (reg:CC FLAGS_REG))]
3157 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3158 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3160 (zero_extend:SI (match_dup 1)))])
3162 ;; When source and destination does not overlap, clear destination
3163 ;; first and then do the movb
3165 [(set (match_operand:SI 0 "register_operand" "")
3166 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3167 (clobber (reg:CC FLAGS_REG))]
3169 && ANY_QI_REG_P (operands[0])
3170 && (ANY_QI_REG_P (operands[1]) || GET_CODE (operands[1]) == MEM)
3171 && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3172 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3173 [(set (match_dup 0) (const_int 0))
3174 (set (strict_low_part (match_dup 2)) (match_dup 1))]
3175 "operands[2] = gen_lowpart (QImode, operands[0]);")
3177 ;; Rest is handled by single and.
3179 [(set (match_operand:SI 0 "register_operand" "")
3180 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3181 (clobber (reg:CC FLAGS_REG))]
3183 && true_regnum (operands[0]) == true_regnum (operands[1])"
3184 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3185 (clobber (reg:CC FLAGS_REG))])]
3188 ;; %%% Kill me once multi-word ops are sane.
3189 (define_expand "zero_extendsidi2"
3190 [(set (match_operand:DI 0 "register_operand" "=r")
3191 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
3195 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3200 (define_insn "zero_extendsidi2_32"
3201 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?*o,?*y,?*Y")
3202 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "0,rm,r,rm,rm")))
3203 (clobber (reg:CC FLAGS_REG))]
3209 movd\t{%1, %0|%0, %1}
3210 movd\t{%1, %0|%0, %1}"
3211 [(set_attr "mode" "SI,SI,SI,DI,TI")
3212 (set_attr "type" "multi,multi,multi,mmxmov,ssemov")])
3214 (define_insn "zero_extendsidi2_rex64"
3215 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*y,?*Y")
3216 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm,0,rm,rm")))]
3219 mov\t{%k1, %k0|%k0, %k1}
3221 movd\t{%1, %0|%0, %1}
3222 movd\t{%1, %0|%0, %1}"
3223 [(set_attr "type" "imovx,imov,mmxmov,ssemov")
3224 (set_attr "mode" "SI,DI,SI,SI")])
3227 [(set (match_operand:DI 0 "memory_operand" "")
3228 (zero_extend:DI (match_dup 0)))]
3230 [(set (match_dup 4) (const_int 0))]
3231 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3234 [(set (match_operand:DI 0 "register_operand" "")
3235 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3236 (clobber (reg:CC FLAGS_REG))]
3237 "!TARGET_64BIT && reload_completed
3238 && true_regnum (operands[0]) == true_regnum (operands[1])"
3239 [(set (match_dup 4) (const_int 0))]
3240 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3243 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3244 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3245 (clobber (reg:CC FLAGS_REG))]
3246 "!TARGET_64BIT && reload_completed
3247 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3248 [(set (match_dup 3) (match_dup 1))
3249 (set (match_dup 4) (const_int 0))]
3250 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3252 (define_insn "zero_extendhidi2"
3253 [(set (match_operand:DI 0 "register_operand" "=r")
3254 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3256 "movz{wl|x}\t{%1, %k0|%k0, %1}"
3257 [(set_attr "type" "imovx")
3258 (set_attr "mode" "DI")])
3260 (define_insn "zero_extendqidi2"
3261 [(set (match_operand:DI 0 "register_operand" "=r")
3262 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3264 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3265 [(set_attr "type" "imovx")
3266 (set_attr "mode" "DI")])
3268 ;; Sign extension instructions
3270 (define_expand "extendsidi2"
3271 [(parallel [(set (match_operand:DI 0 "register_operand" "")
3272 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3273 (clobber (reg:CC FLAGS_REG))
3274 (clobber (match_scratch:SI 2 ""))])]
3279 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3284 (define_insn "*extendsidi2_1"
3285 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3286 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3287 (clobber (reg:CC FLAGS_REG))
3288 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3292 (define_insn "extendsidi2_rex64"
3293 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3294 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3298 movs{lq|x}\t{%1,%0|%0, %1}"
3299 [(set_attr "type" "imovx")
3300 (set_attr "mode" "DI")
3301 (set_attr "prefix_0f" "0")
3302 (set_attr "modrm" "0,1")])
3304 (define_insn "extendhidi2"
3305 [(set (match_operand:DI 0 "register_operand" "=r")
3306 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3308 "movs{wq|x}\t{%1,%0|%0, %1}"
3309 [(set_attr "type" "imovx")
3310 (set_attr "mode" "DI")])
3312 (define_insn "extendqidi2"
3313 [(set (match_operand:DI 0 "register_operand" "=r")
3314 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3316 "movs{bq|x}\t{%1,%0|%0, %1}"
3317 [(set_attr "type" "imovx")
3318 (set_attr "mode" "DI")])
3320 ;; Extend to memory case when source register does die.
3322 [(set (match_operand:DI 0 "memory_operand" "")
3323 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3324 (clobber (reg:CC FLAGS_REG))
3325 (clobber (match_operand:SI 2 "register_operand" ""))]
3327 && dead_or_set_p (insn, operands[1])
3328 && !reg_mentioned_p (operands[1], operands[0]))"
3329 [(set (match_dup 3) (match_dup 1))
3330 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3331 (clobber (reg:CC FLAGS_REG))])
3332 (set (match_dup 4) (match_dup 1))]
3333 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3335 ;; Extend to memory case when source register does not die.
3337 [(set (match_operand:DI 0 "memory_operand" "")
3338 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3339 (clobber (reg:CC FLAGS_REG))
3340 (clobber (match_operand:SI 2 "register_operand" ""))]
3344 split_di (&operands[0], 1, &operands[3], &operands[4]);
3346 emit_move_insn (operands[3], operands[1]);
3348 /* Generate a cltd if possible and doing so it profitable. */
3349 if (true_regnum (operands[1]) == 0
3350 && true_regnum (operands[2]) == 1
3351 && (optimize_size || TARGET_USE_CLTD))
3353 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3357 emit_move_insn (operands[2], operands[1]);
3358 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3360 emit_move_insn (operands[4], operands[2]);
3364 ;; Extend to register case. Optimize case where source and destination
3365 ;; registers match and cases where we can use cltd.
3367 [(set (match_operand:DI 0 "register_operand" "")
3368 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3369 (clobber (reg:CC FLAGS_REG))
3370 (clobber (match_scratch:SI 2 ""))]
3374 split_di (&operands[0], 1, &operands[3], &operands[4]);
3376 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3377 emit_move_insn (operands[3], operands[1]);
3379 /* Generate a cltd if possible and doing so it profitable. */
3380 if (true_regnum (operands[3]) == 0
3381 && (optimize_size || TARGET_USE_CLTD))
3383 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3387 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3388 emit_move_insn (operands[4], operands[1]);
3390 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3394 (define_insn "extendhisi2"
3395 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3396 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3399 switch (get_attr_prefix_0f (insn))
3402 return "{cwtl|cwde}";
3404 return "movs{wl|x}\t{%1,%0|%0, %1}";
3407 [(set_attr "type" "imovx")
3408 (set_attr "mode" "SI")
3409 (set (attr "prefix_0f")
3410 ;; movsx is short decodable while cwtl is vector decoded.
3411 (if_then_else (and (eq_attr "cpu" "!k6")
3412 (eq_attr "alternative" "0"))
3414 (const_string "1")))
3416 (if_then_else (eq_attr "prefix_0f" "0")
3418 (const_string "1")))])
3420 (define_insn "*extendhisi2_zext"
3421 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3423 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3426 switch (get_attr_prefix_0f (insn))
3429 return "{cwtl|cwde}";
3431 return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3434 [(set_attr "type" "imovx")
3435 (set_attr "mode" "SI")
3436 (set (attr "prefix_0f")
3437 ;; movsx is short decodable while cwtl is vector decoded.
3438 (if_then_else (and (eq_attr "cpu" "!k6")
3439 (eq_attr "alternative" "0"))
3441 (const_string "1")))
3443 (if_then_else (eq_attr "prefix_0f" "0")
3445 (const_string "1")))])
3447 (define_insn "extendqihi2"
3448 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3449 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3452 switch (get_attr_prefix_0f (insn))
3455 return "{cbtw|cbw}";
3457 return "movs{bw|x}\t{%1,%0|%0, %1}";
3460 [(set_attr "type" "imovx")
3461 (set_attr "mode" "HI")
3462 (set (attr "prefix_0f")
3463 ;; movsx is short decodable while cwtl is vector decoded.
3464 (if_then_else (and (eq_attr "cpu" "!k6")
3465 (eq_attr "alternative" "0"))
3467 (const_string "1")))
3469 (if_then_else (eq_attr "prefix_0f" "0")
3471 (const_string "1")))])
3473 (define_insn "extendqisi2"
3474 [(set (match_operand:SI 0 "register_operand" "=r")
3475 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3477 "movs{bl|x}\t{%1,%0|%0, %1}"
3478 [(set_attr "type" "imovx")
3479 (set_attr "mode" "SI")])
3481 (define_insn "*extendqisi2_zext"
3482 [(set (match_operand:DI 0 "register_operand" "=r")
3484 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3486 "movs{bl|x}\t{%1,%k0|%k0, %1}"
3487 [(set_attr "type" "imovx")
3488 (set_attr "mode" "SI")])
3490 ;; Conversions between float and double.
3492 ;; These are all no-ops in the model used for the 80387. So just
3495 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3496 (define_insn "*dummy_extendsfdf2"
3497 [(set (match_operand:DF 0 "push_operand" "=<")
3498 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
3503 [(set (match_operand:DF 0 "push_operand" "")
3504 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3506 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3507 (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3510 [(set (match_operand:DF 0 "push_operand" "")
3511 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3513 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3514 (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3516 (define_insn "*dummy_extendsfxf2"
3517 [(set (match_operand:XF 0 "push_operand" "=<")
3518 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3523 [(set (match_operand:XF 0 "push_operand" "")
3524 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3526 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3527 (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3528 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3531 [(set (match_operand:XF 0 "push_operand" "")
3532 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3534 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3535 (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3536 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3539 [(set (match_operand:XF 0 "push_operand" "")
3540 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3542 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3543 (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3544 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3547 [(set (match_operand:XF 0 "push_operand" "")
3548 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3550 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3551 (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3552 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3554 (define_expand "extendsfdf2"
3555 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3556 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3557 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3559 /* ??? Needed for compress_float_constant since all fp constants
3560 are LEGITIMATE_CONSTANT_P. */
3561 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3563 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3564 && standard_80387_constant_p (operands[1]) > 0)
3566 operands[1] = simplify_const_unary_operation
3567 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3568 emit_move_insn_1 (operands[0], operands[1]);
3571 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3575 (define_insn "*extendsfdf2_mixed"
3576 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,Y")
3577 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f,mY")))]
3578 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3580 switch (which_alternative)
3583 return output_387_reg_move (insn, operands);
3586 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3587 return "fstp%z0\t%y0";
3589 return "fst%z0\t%y0";
3592 return "cvtss2sd\t{%1, %0|%0, %1}";
3598 [(set_attr "type" "fmov,fmov,ssecvt")
3599 (set_attr "mode" "SF,XF,DF")])
3601 (define_insn "*extendsfdf2_sse"
3602 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y")
3603 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))]
3604 "TARGET_SSE2 && TARGET_SSE_MATH"
3605 "cvtss2sd\t{%1, %0|%0, %1}"
3606 [(set_attr "type" "ssecvt")
3607 (set_attr "mode" "DF")])
3609 (define_insn "*extendsfdf2_i387"
3610 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3611 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3614 switch (which_alternative)
3617 return output_387_reg_move (insn, operands);
3620 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3621 return "fstp%z0\t%y0";
3623 return "fst%z0\t%y0";
3629 [(set_attr "type" "fmov")
3630 (set_attr "mode" "SF,XF")])
3632 (define_expand "extendsfxf2"
3633 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3634 (float_extend:XF (match_operand:SF 1 "general_operand" "")))]
3637 /* ??? Needed for compress_float_constant since all fp constants
3638 are LEGITIMATE_CONSTANT_P. */
3639 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3641 if (standard_80387_constant_p (operands[1]) > 0)
3643 operands[1] = simplify_const_unary_operation
3644 (FLOAT_EXTEND, XFmode, operands[1], SFmode);
3645 emit_move_insn_1 (operands[0], operands[1]);
3648 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3652 (define_insn "*extendsfxf2_i387"
3653 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3654 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3657 switch (which_alternative)
3660 return output_387_reg_move (insn, operands);
3663 /* There is no non-popping store to memory for XFmode. So if
3664 we need one, follow the store with a load. */
3665 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3666 return "fstp%z0\t%y0";
3668 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3674 [(set_attr "type" "fmov")
3675 (set_attr "mode" "SF,XF")])
3677 (define_expand "extenddfxf2"
3678 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3679 (float_extend:XF (match_operand:DF 1 "general_operand" "")))]
3682 /* ??? Needed for compress_float_constant since all fp constants
3683 are LEGITIMATE_CONSTANT_P. */
3684 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3686 if (standard_80387_constant_p (operands[1]) > 0)
3688 operands[1] = simplify_const_unary_operation
3689 (FLOAT_EXTEND, XFmode, operands[1], DFmode);
3690 emit_move_insn_1 (operands[0], operands[1]);
3693 operands[1] = validize_mem (force_const_mem (DFmode, operands[1]));
3697 (define_insn "*extenddfxf2_i387"
3698 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3699 (float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
3702 switch (which_alternative)
3705 return output_387_reg_move (insn, operands);
3708 /* There is no non-popping store to memory for XFmode. So if
3709 we need one, follow the store with a load. */
3710 if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3711 return "fstp%z0\t%y0\n\tfld%z0\t%y0";
3713 return "fstp%z0\t%y0";
3719 [(set_attr "type" "fmov")
3720 (set_attr "mode" "DF,XF")])
3722 ;; %%% This seems bad bad news.
3723 ;; This cannot output into an f-reg because there is no way to be sure
3724 ;; of truncating in that case. Otherwise this is just like a simple move
3725 ;; insn. So we pretend we can output to a reg in order to get better
3726 ;; register preferencing, but we really use a stack slot.
3728 ;; Conversion from DFmode to SFmode.
3730 (define_expand "truncdfsf2"
3731 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3733 (match_operand:DF 1 "nonimmediate_operand" "")))]
3734 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3736 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3738 else if (flag_unsafe_math_optimizations)
3742 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3743 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3748 (define_expand "truncdfsf2_with_temp"
3749 [(parallel [(set (match_operand:SF 0 "" "")
3750 (float_truncate:SF (match_operand:DF 1 "" "")))
3751 (clobber (match_operand:SF 2 "" ""))])]
3754 (define_insn "*truncdfsf_fast_mixed"
3755 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f,Y")
3757 (match_operand:DF 1 "nonimmediate_operand" "f ,f,Ym")))]
3758 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3760 switch (which_alternative)
3763 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3764 return "fstp%z0\t%y0";
3766 return "fst%z0\t%y0";
3768 return output_387_reg_move (insn, operands);
3770 return "cvtsd2ss\t{%1, %0|%0, %1}";
3775 [(set_attr "type" "fmov,fmov,ssecvt")
3776 (set_attr "mode" "SF")])
3778 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3779 ;; because nothing we do here is unsafe.
3780 (define_insn "*truncdfsf_fast_sse"
3781 [(set (match_operand:SF 0 "nonimmediate_operand" "=Y")
3783 (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
3784 "TARGET_SSE2 && TARGET_SSE_MATH"
3785 "cvtsd2ss\t{%1, %0|%0, %1}"
3786 [(set_attr "type" "ssecvt")
3787 (set_attr "mode" "SF")])
3789 (define_insn "*truncdfsf_fast_i387"
3790 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3792 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3793 "TARGET_80387 && flag_unsafe_math_optimizations"
3794 "* return output_387_reg_move (insn, operands);"
3795 [(set_attr "type" "fmov")
3796 (set_attr "mode" "SF")])
3798 (define_insn "*truncdfsf_mixed"
3799 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r,Y")
3801 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,Ym")))
3802 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,X"))]
3803 "TARGET_MIX_SSE_I387"
3805 switch (which_alternative)
3808 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3809 return "fstp%z0\t%y0";
3811 return "fst%z0\t%y0";
3815 return "cvtsd2ss\t{%1, %0|%0, %1}";
3820 [(set_attr "type" "fmov,multi,ssecvt")
3821 (set_attr "unit" "*,i387,*")
3822 (set_attr "mode" "SF")])
3824 (define_insn "*truncdfsf_i387"
3825 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
3827 (match_operand:DF 1 "nonimmediate_operand" "f,f")))
3828 (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
3831 switch (which_alternative)
3834 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3835 return "fstp%z0\t%y0";
3837 return "fst%z0\t%y0";
3844 [(set_attr "type" "fmov,multi")
3845 (set_attr "unit" "*,i387")
3846 (set_attr "mode" "SF")])
3848 (define_insn "*truncdfsf2_i387_1"
3849 [(set (match_operand:SF 0 "memory_operand" "=m")
3851 (match_operand:DF 1 "register_operand" "f")))]
3853 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3854 && !TARGET_MIX_SSE_I387"
3856 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3857 return "fstp%z0\t%y0";
3859 return "fst%z0\t%y0";
3861 [(set_attr "type" "fmov")
3862 (set_attr "mode" "SF")])
3865 [(set (match_operand:SF 0 "register_operand" "")
3867 (match_operand:DF 1 "fp_register_operand" "")))
3868 (clobber (match_operand 2 "" ""))]
3870 [(set (match_dup 2) (match_dup 1))
3871 (set (match_dup 0) (match_dup 2))]
3873 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
3876 ;; Conversion from XFmode to SFmode.
3878 (define_expand "truncxfsf2"
3879 [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
3881 (match_operand:XF 1 "register_operand" "")))
3882 (clobber (match_dup 2))])]
3885 if (flag_unsafe_math_optimizations)
3887 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SFmode);
3888 emit_insn (gen_truncxfsf2_i387_noop (reg, operands[1]));
3889 if (reg != operands[0])
3890 emit_move_insn (operands[0], reg);
3894 operands[2] = assign_386_stack_local (SFmode, SLOT_TEMP);
3897 (define_insn "*truncxfsf2_mixed"
3898 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r,?x")
3900 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3901 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
3902 "TARGET_MIX_SSE_I387"
3904 gcc_assert (!which_alternative);
3905 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3906 return "fstp%z0\t%y0";
3908 return "fst%z0\t%y0";
3910 [(set_attr "type" "fmov,multi,multi,multi")
3911 (set_attr "unit" "*,i387,i387,i387")
3912 (set_attr "mode" "SF")])
3914 (define_insn "truncxfsf2_i387_noop"
3915 [(set (match_operand:SF 0 "register_operand" "=f")
3916 (float_truncate:SF (match_operand:XF 1 "register_operand" "f")))]
3917 "TARGET_80387 && flag_unsafe_math_optimizations"
3918 "* return output_387_reg_move (insn, operands);"
3919 [(set_attr "type" "fmov")
3920 (set_attr "mode" "SF")])
3922 (define_insn "*truncxfsf2_i387"
3923 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?r")
3925 (match_operand:XF 1 "register_operand" "f,f,f")))
3926 (clobber (match_operand:SF 2 "memory_operand" "=X,m,m"))]
3929 gcc_assert (!which_alternative);
3930 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3931 return "fstp%z0\t%y0";
3933 return "fst%z0\t%y0";
3935 [(set_attr "type" "fmov,multi,multi")
3936 (set_attr "unit" "*,i387,i387")
3937 (set_attr "mode" "SF")])
3939 (define_insn "*truncxfsf2_i387_1"
3940 [(set (match_operand:SF 0 "memory_operand" "=m")
3942 (match_operand:XF 1 "register_operand" "f")))]
3945 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
3946 return "fstp%z0\t%y0";
3948 return "fst%z0\t%y0";
3950 [(set_attr "type" "fmov")
3951 (set_attr "mode" "SF")])
3954 [(set (match_operand:SF 0 "register_operand" "")
3956 (match_operand:XF 1 "register_operand" "")))
3957 (clobber (match_operand:SF 2 "memory_operand" ""))]
3958 "TARGET_80387 && reload_completed"
3959 [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
3960 (set (match_dup 0) (match_dup 2))]
3964 [(set (match_operand:SF 0 "memory_operand" "")
3966 (match_operand:XF 1 "register_operand" "")))
3967 (clobber (match_operand:SF 2 "memory_operand" ""))]
3969 [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
3972 ;; Conversion from XFmode to DFmode.
3974 (define_expand "truncxfdf2"
3975 [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
3977 (match_operand:XF 1 "register_operand" "")))
3978 (clobber (match_dup 2))])]
3981 if (flag_unsafe_math_optimizations)
3983 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DFmode);
3984 emit_insn (gen_truncxfdf2_i387_noop (reg, operands[1]));
3985 if (reg != operands[0])
3986 emit_move_insn (operands[0], reg);
3990 operands[2] = assign_386_stack_local (DFmode, SLOT_TEMP);
3993 (define_insn "*truncxfdf2_mixed"
3994 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r,?Y")
3996 (match_operand:XF 1 "register_operand" "f,f,f,f")))
3997 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
3998 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4000 gcc_assert (!which_alternative);
4001 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4002 return "fstp%z0\t%y0";
4004 return "fst%z0\t%y0";
4006 [(set_attr "type" "fmov,multi,multi,multi")
4007 (set_attr "unit" "*,i387,i387,i387")
4008 (set_attr "mode" "DF")])
4010 (define_insn "truncxfdf2_i387_noop"
4011 [(set (match_operand:DF 0 "register_operand" "=f")
4012 (float_truncate:DF (match_operand:XF 1 "register_operand" "f")))]
4013 "TARGET_80387 && flag_unsafe_math_optimizations"
4014 "* return output_387_reg_move (insn, operands);"
4015 [(set_attr "type" "fmov")
4016 (set_attr "mode" "DF")])
4018 (define_insn "*truncxfdf2_i387"
4019 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?r")
4021 (match_operand:XF 1 "register_operand" "f,f,f")))
4022 (clobber (match_operand:DF 2 "memory_operand" "=X,m,m"))]
4025 gcc_assert (!which_alternative);
4026 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4027 return "fstp%z0\t%y0";
4029 return "fst%z0\t%y0";
4031 [(set_attr "type" "fmov,multi,multi")
4032 (set_attr "unit" "*,i387,i387")
4033 (set_attr "mode" "DF")])
4035 (define_insn "*truncxfdf2_i387_1"
4036 [(set (match_operand:DF 0 "memory_operand" "=m")
4038 (match_operand:XF 1 "register_operand" "f")))]
4041 if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
4042 return "fstp%z0\t%y0";
4044 return "fst%z0\t%y0";
4046 [(set_attr "type" "fmov")
4047 (set_attr "mode" "DF")])
4050 [(set (match_operand:DF 0 "register_operand" "")
4052 (match_operand:XF 1 "register_operand" "")))
4053 (clobber (match_operand:DF 2 "memory_operand" ""))]
4054 "TARGET_80387 && reload_completed"
4055 [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
4056 (set (match_dup 0) (match_dup 2))]
4060 [(set (match_operand:DF 0 "memory_operand" "")
4062 (match_operand:XF 1 "register_operand" "")))
4063 (clobber (match_operand:DF 2 "memory_operand" ""))]
4065 [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
4068 ;; Signed conversion to DImode.
4070 (define_expand "fix_truncxfdi2"
4071 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4072 (fix:DI (match_operand:XF 1 "register_operand" "")))
4073 (clobber (reg:CC FLAGS_REG))])]
4078 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4083 (define_expand "fix_trunc<mode>di2"
4084 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4085 (fix:DI (match_operand:SSEMODEF 1 "register_operand" "")))
4086 (clobber (reg:CC FLAGS_REG))])]
4087 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4090 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4092 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4095 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4097 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4098 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4099 if (out != operands[0])
4100 emit_move_insn (operands[0], out);
4105 ;; Signed conversion to SImode.
4107 (define_expand "fix_truncxfsi2"
4108 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4109 (fix:SI (match_operand:XF 1 "register_operand" "")))
4110 (clobber (reg:CC FLAGS_REG))])]
4115 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4120 (define_expand "fix_trunc<mode>si2"
4121 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4122 (fix:SI (match_operand:SSEMODEF 1 "register_operand" "")))
4123 (clobber (reg:CC FLAGS_REG))])]
4124 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4127 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4129 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4132 if (SSE_FLOAT_MODE_P (<MODE>mode))
4134 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4135 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4136 if (out != operands[0])
4137 emit_move_insn (operands[0], out);
4142 ;; Signed conversion to HImode.
4144 (define_expand "fix_trunc<mode>hi2"
4145 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4146 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4147 (clobber (reg:CC FLAGS_REG))])]
4149 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4153 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4158 ;; When SSE is available, it is always faster to use it!
4159 (define_insn "fix_truncsfdi_sse"
4160 [(set (match_operand:DI 0 "register_operand" "=r,r")
4161 (fix:DI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4162 "TARGET_64BIT && TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4163 "cvttss2si{q}\t{%1, %0|%0, %1}"
4164 [(set_attr "type" "sseicvt")
4165 (set_attr "mode" "SF")
4166 (set_attr "athlon_decode" "double,vector")])
4168 (define_insn "fix_truncdfdi_sse"
4169 [(set (match_operand:DI 0 "register_operand" "=r,r")
4170 (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4171 "TARGET_64BIT && TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4172 "cvttsd2si{q}\t{%1, %0|%0, %1}"
4173 [(set_attr "type" "sseicvt")
4174 (set_attr "mode" "DF")
4175 (set_attr "athlon_decode" "double,vector")])
4177 (define_insn "fix_truncsfsi_sse"
4178 [(set (match_operand:SI 0 "register_operand" "=r,r")
4179 (fix:SI (match_operand:SF 1 "nonimmediate_operand" "x,xm")))]
4180 "TARGET_SSE && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4181 "cvttss2si\t{%1, %0|%0, %1}"
4182 [(set_attr "type" "sseicvt")
4183 (set_attr "mode" "DF")
4184 (set_attr "athlon_decode" "double,vector")])
4186 (define_insn "fix_truncdfsi_sse"
4187 [(set (match_operand:SI 0 "register_operand" "=r,r")
4188 (fix:SI (match_operand:DF 1 "nonimmediate_operand" "Y,Ym")))]
4189 "TARGET_SSE2 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4190 "cvttsd2si\t{%1, %0|%0, %1}"
4191 [(set_attr "type" "sseicvt")
4192 (set_attr "mode" "DF")
4193 (set_attr "athlon_decode" "double,vector")])
4195 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4197 [(set (match_operand:DF 0 "register_operand" "")
4198 (match_operand:DF 1 "memory_operand" ""))
4199 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4200 (fix:SSEMODEI24 (match_dup 0)))]
4202 && peep2_reg_dead_p (2, operands[0])"
4203 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4207 [(set (match_operand:SF 0 "register_operand" "")
4208 (match_operand:SF 1 "memory_operand" ""))
4209 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4210 (fix:SSEMODEI24 (match_dup 0)))]
4212 && peep2_reg_dead_p (2, operands[0])"
4213 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4216 ;; Avoid vector decoded forms of the instruction.
4218 [(match_scratch:DF 2 "Y")
4219 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4220 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4221 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4222 [(set (match_dup 2) (match_dup 1))
4223 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4227 [(match_scratch:SF 2 "x")
4228 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4229 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4230 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
4231 [(set (match_dup 2) (match_dup 1))
4232 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4235 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4236 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4237 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))]
4239 && FLOAT_MODE_P (GET_MODE (operands[1]))
4240 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4241 && (TARGET_64BIT || <MODE>mode != DImode))
4243 && !(reload_completed || reload_in_progress)"
4248 if (memory_operand (operands[0], VOIDmode))
4249 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4252 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4253 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4259 [(set_attr "type" "fisttp")
4260 (set_attr "mode" "<MODE>")])
4262 (define_insn "fix_trunc<mode>_i387_fisttp"
4263 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4264 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4265 (clobber (match_scratch:XF 2 "=&1f"))]
4267 && FLOAT_MODE_P (GET_MODE (operands[1]))
4268 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4269 && (TARGET_64BIT || <MODE>mode != DImode))
4270 && TARGET_SSE_MATH)"
4271 "* return output_fix_trunc (insn, operands, 1);"
4272 [(set_attr "type" "fisttp")
4273 (set_attr "mode" "<MODE>")])
4275 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4276 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4277 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4278 (clobber (match_operand:X87MODEI 2 "memory_operand" "=m,m"))
4279 (clobber (match_scratch:XF 3 "=&1f,&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)"
4286 [(set_attr "type" "fisttp")
4287 (set_attr "mode" "<MODE>")])
4290 [(set (match_operand:X87MODEI 0 "register_operand" "")
4291 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4292 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4293 (clobber (match_scratch 3 ""))]
4295 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4296 (clobber (match_dup 3))])
4297 (set (match_dup 0) (match_dup 2))]
4301 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4302 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4303 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4304 (clobber (match_scratch 3 ""))]
4306 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4307 (clobber (match_dup 3))])]
4310 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4311 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4312 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4313 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4314 ;; function in i386.c.
4315 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4316 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4317 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4318 (clobber (reg:CC FLAGS_REG))]
4319 "TARGET_80387 && !TARGET_FISTTP
4320 && FLOAT_MODE_P (GET_MODE (operands[1]))
4321 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4322 && (TARGET_64BIT || <MODE>mode != DImode))
4323 && !(reload_completed || reload_in_progress)"
4328 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4330 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4331 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4332 if (memory_operand (operands[0], VOIDmode))
4333 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4334 operands[2], operands[3]));
4337 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4338 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4339 operands[2], operands[3],
4344 [(set_attr "type" "fistp")
4345 (set_attr "i387_cw" "trunc")
4346 (set_attr "mode" "<MODE>")])
4348 (define_insn "fix_truncdi_i387"
4349 [(set (match_operand:DI 0 "memory_operand" "=m")
4350 (fix:DI (match_operand 1 "register_operand" "f")))
4351 (use (match_operand:HI 2 "memory_operand" "m"))
4352 (use (match_operand:HI 3 "memory_operand" "m"))
4353 (clobber (match_scratch:XF 4 "=&1f"))]
4354 "TARGET_80387 && !TARGET_FISTTP
4355 && FLOAT_MODE_P (GET_MODE (operands[1]))
4356 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4357 "* return output_fix_trunc (insn, operands, 0);"
4358 [(set_attr "type" "fistp")
4359 (set_attr "i387_cw" "trunc")
4360 (set_attr "mode" "DI")])
4362 (define_insn "fix_truncdi_i387_with_temp"
4363 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4364 (fix:DI (match_operand 1 "register_operand" "f,f")))
4365 (use (match_operand:HI 2 "memory_operand" "m,m"))
4366 (use (match_operand:HI 3 "memory_operand" "m,m"))
4367 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
4368 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4369 "TARGET_80387 && !TARGET_FISTTP
4370 && FLOAT_MODE_P (GET_MODE (operands[1]))
4371 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4373 [(set_attr "type" "fistp")
4374 (set_attr "i387_cw" "trunc")
4375 (set_attr "mode" "DI")])
4378 [(set (match_operand:DI 0 "register_operand" "")
4379 (fix:DI (match_operand 1 "register_operand" "")))
4380 (use (match_operand:HI 2 "memory_operand" ""))
4381 (use (match_operand:HI 3 "memory_operand" ""))
4382 (clobber (match_operand:DI 4 "memory_operand" ""))
4383 (clobber (match_scratch 5 ""))]
4385 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4388 (clobber (match_dup 5))])
4389 (set (match_dup 0) (match_dup 4))]
4393 [(set (match_operand:DI 0 "memory_operand" "")
4394 (fix:DI (match_operand 1 "register_operand" "")))
4395 (use (match_operand:HI 2 "memory_operand" ""))
4396 (use (match_operand:HI 3 "memory_operand" ""))
4397 (clobber (match_operand:DI 4 "memory_operand" ""))
4398 (clobber (match_scratch 5 ""))]
4400 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4403 (clobber (match_dup 5))])]
4406 (define_insn "fix_trunc<mode>_i387"
4407 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4408 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4409 (use (match_operand:HI 2 "memory_operand" "m"))
4410 (use (match_operand:HI 3 "memory_operand" "m"))]
4411 "TARGET_80387 && !TARGET_FISTTP
4412 && FLOAT_MODE_P (GET_MODE (operands[1]))
4413 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4414 "* return output_fix_trunc (insn, operands, 0);"
4415 [(set_attr "type" "fistp")
4416 (set_attr "i387_cw" "trunc")
4417 (set_attr "mode" "<MODE>")])
4419 (define_insn "fix_trunc<mode>_i387_with_temp"
4420 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4421 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4422 (use (match_operand:HI 2 "memory_operand" "m,m"))
4423 (use (match_operand:HI 3 "memory_operand" "m,m"))
4424 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
4425 "TARGET_80387 && !TARGET_FISTTP
4426 && FLOAT_MODE_P (GET_MODE (operands[1]))
4427 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4429 [(set_attr "type" "fistp")
4430 (set_attr "i387_cw" "trunc")
4431 (set_attr "mode" "<MODE>")])
4434 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4435 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4436 (use (match_operand:HI 2 "memory_operand" ""))
4437 (use (match_operand:HI 3 "memory_operand" ""))
4438 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4440 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4442 (use (match_dup 3))])
4443 (set (match_dup 0) (match_dup 4))]
4447 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4448 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4449 (use (match_operand:HI 2 "memory_operand" ""))
4450 (use (match_operand:HI 3 "memory_operand" ""))
4451 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4453 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4455 (use (match_dup 3))])]
4458 (define_insn "x86_fnstcw_1"
4459 [(set (match_operand:HI 0 "memory_operand" "=m")
4460 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4463 [(set_attr "length" "2")
4464 (set_attr "mode" "HI")
4465 (set_attr "unit" "i387")])
4467 (define_insn "x86_fldcw_1"
4468 [(set (reg:HI FPCR_REG)
4469 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4472 [(set_attr "length" "2")
4473 (set_attr "mode" "HI")
4474 (set_attr "unit" "i387")
4475 (set_attr "athlon_decode" "vector")])
4477 ;; Conversion between fixed point and floating point.
4479 ;; Even though we only accept memory inputs, the backend _really_
4480 ;; wants to be able to do this between registers.
4482 (define_expand "floathisf2"
4483 [(set (match_operand:SF 0 "register_operand" "")
4484 (float:SF (match_operand:HI 1 "nonimmediate_operand" "")))]
4485 "TARGET_80387 || TARGET_SSE_MATH"
4487 if (TARGET_SSE_MATH)
4489 emit_insn (gen_floatsisf2 (operands[0],
4490 convert_to_mode (SImode, operands[1], 0)));
4495 (define_insn "*floathisf2_i387"
4496 [(set (match_operand:SF 0 "register_operand" "=f,f")
4497 (float:SF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4498 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
4502 [(set_attr "type" "fmov,multi")
4503 (set_attr "mode" "SF")
4504 (set_attr "unit" "*,i387")
4505 (set_attr "fp_int_src" "true")])
4507 (define_expand "floatsisf2"
4508 [(set (match_operand:SF 0 "register_operand" "")
4509 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
4510 "TARGET_80387 || TARGET_SSE_MATH"
4513 (define_insn "*floatsisf2_mixed"
4514 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4515 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4516 "TARGET_MIX_SSE_I387"
4520 cvtsi2ss\t{%1, %0|%0, %1}
4521 cvtsi2ss\t{%1, %0|%0, %1}"
4522 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4523 (set_attr "mode" "SF")
4524 (set_attr "unit" "*,i387,*,*")
4525 (set_attr "athlon_decode" "*,*,vector,double")
4526 (set_attr "fp_int_src" "true")])
4528 (define_insn "*floatsisf2_sse"
4529 [(set (match_operand:SF 0 "register_operand" "=x,x")
4530 (float:SF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4532 "cvtsi2ss\t{%1, %0|%0, %1}"
4533 [(set_attr "type" "sseicvt")
4534 (set_attr "mode" "SF")
4535 (set_attr "athlon_decode" "vector,double")
4536 (set_attr "fp_int_src" "true")])
4538 (define_insn "*floatsisf2_i387"
4539 [(set (match_operand:SF 0 "register_operand" "=f,f")
4540 (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4545 [(set_attr "type" "fmov,multi")
4546 (set_attr "mode" "SF")
4547 (set_attr "unit" "*,i387")
4548 (set_attr "fp_int_src" "true")])
4550 (define_expand "floatdisf2"
4551 [(set (match_operand:SF 0 "register_operand" "")
4552 (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
4553 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE_MATH)"
4556 (define_insn "*floatdisf2_mixed"
4557 [(set (match_operand:SF 0 "register_operand" "=f,?f,x,x")
4558 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4559 "TARGET_64BIT && TARGET_MIX_SSE_I387"
4563 cvtsi2ss{q}\t{%1, %0|%0, %1}
4564 cvtsi2ss{q}\t{%1, %0|%0, %1}"
4565 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4566 (set_attr "mode" "SF")
4567 (set_attr "unit" "*,i387,*,*")
4568 (set_attr "athlon_decode" "*,*,vector,double")
4569 (set_attr "fp_int_src" "true")])
4571 (define_insn "*floatdisf2_sse"
4572 [(set (match_operand:SF 0 "register_operand" "=x,x")
4573 (float:SF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4574 "TARGET_64BIT && TARGET_SSE_MATH"
4575 "cvtsi2ss{q}\t{%1, %0|%0, %1}"
4576 [(set_attr "type" "sseicvt")
4577 (set_attr "mode" "SF")
4578 (set_attr "athlon_decode" "vector,double")
4579 (set_attr "fp_int_src" "true")])
4581 (define_insn "*floatdisf2_i387"
4582 [(set (match_operand:SF 0 "register_operand" "=f,f")
4583 (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4588 [(set_attr "type" "fmov,multi")
4589 (set_attr "mode" "SF")
4590 (set_attr "unit" "*,i387")
4591 (set_attr "fp_int_src" "true")])
4593 (define_expand "floathidf2"
4594 [(set (match_operand:DF 0 "register_operand" "")
4595 (float:DF (match_operand:HI 1 "nonimmediate_operand" "")))]
4596 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4598 if (TARGET_SSE2 && TARGET_SSE_MATH)
4600 emit_insn (gen_floatsidf2 (operands[0],
4601 convert_to_mode (SImode, operands[1], 0)));
4606 (define_insn "*floathidf2_i387"
4607 [(set (match_operand:DF 0 "register_operand" "=f,f")
4608 (float:DF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4609 "TARGET_80387 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)"
4613 [(set_attr "type" "fmov,multi")
4614 (set_attr "mode" "DF")
4615 (set_attr "unit" "*,i387")
4616 (set_attr "fp_int_src" "true")])
4618 (define_expand "floatsidf2"
4619 [(set (match_operand:DF 0 "register_operand" "")
4620 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))]
4621 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4624 (define_insn "*floatsidf2_mixed"
4625 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4626 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,r,mr")))]
4627 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4631 cvtsi2sd\t{%1, %0|%0, %1}
4632 cvtsi2sd\t{%1, %0|%0, %1}"
4633 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4634 (set_attr "mode" "DF")
4635 (set_attr "unit" "*,i387,*,*")
4636 (set_attr "athlon_decode" "*,*,double,direct")
4637 (set_attr "fp_int_src" "true")])
4639 (define_insn "*floatsidf2_sse"
4640 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4641 (float:DF (match_operand:SI 1 "nonimmediate_operand" "r,mr")))]
4642 "TARGET_SSE2 && TARGET_SSE_MATH"
4643 "cvtsi2sd\t{%1, %0|%0, %1}"
4644 [(set_attr "type" "sseicvt")
4645 (set_attr "mode" "DF")
4646 (set_attr "athlon_decode" "double,direct")
4647 (set_attr "fp_int_src" "true")])
4649 (define_insn "*floatsidf2_i387"
4650 [(set (match_operand:DF 0 "register_operand" "=f,f")
4651 (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4656 [(set_attr "type" "fmov,multi")
4657 (set_attr "mode" "DF")
4658 (set_attr "unit" "*,i387")
4659 (set_attr "fp_int_src" "true")])
4661 (define_expand "floatdidf2"
4662 [(set (match_operand:DF 0 "register_operand" "")
4663 (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
4664 "TARGET_80387 || (TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH)"
4667 (define_insn "*floatdidf2_mixed"
4668 [(set (match_operand:DF 0 "register_operand" "=f,?f,Y,Y")
4669 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,r,mr")))]
4670 "TARGET_64BIT && TARGET_SSE2 && TARGET_MIX_SSE_I387"
4674 cvtsi2sd{q}\t{%1, %0|%0, %1}
4675 cvtsi2sd{q}\t{%1, %0|%0, %1}"
4676 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4677 (set_attr "mode" "DF")
4678 (set_attr "unit" "*,i387,*,*")
4679 (set_attr "athlon_decode" "*,*,double,direct")
4680 (set_attr "fp_int_src" "true")])
4682 (define_insn "*floatdidf2_sse"
4683 [(set (match_operand:DF 0 "register_operand" "=Y,Y")
4684 (float:DF (match_operand:DI 1 "nonimmediate_operand" "r,mr")))]
4685 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4686 "cvtsi2sd{q}\t{%1, %0|%0, %1}"
4687 [(set_attr "type" "sseicvt")
4688 (set_attr "mode" "DF")
4689 (set_attr "athlon_decode" "double,direct")
4690 (set_attr "fp_int_src" "true")])
4692 (define_insn "*floatdidf2_i387"
4693 [(set (match_operand:DF 0 "register_operand" "=f,f")
4694 (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4699 [(set_attr "type" "fmov,multi")
4700 (set_attr "mode" "DF")
4701 (set_attr "unit" "*,i387")
4702 (set_attr "fp_int_src" "true")])
4704 (define_insn "floathixf2"
4705 [(set (match_operand:XF 0 "register_operand" "=f,f")
4706 (float:XF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))]
4711 [(set_attr "type" "fmov,multi")
4712 (set_attr "mode" "XF")
4713 (set_attr "unit" "*,i387")
4714 (set_attr "fp_int_src" "true")])
4716 (define_insn "floatsixf2"
4717 [(set (match_operand:XF 0 "register_operand" "=f,f")
4718 (float:XF (match_operand:SI 1 "nonimmediate_operand" "m,?r")))]
4723 [(set_attr "type" "fmov,multi")
4724 (set_attr "mode" "XF")
4725 (set_attr "unit" "*,i387")
4726 (set_attr "fp_int_src" "true")])
4728 (define_insn "floatdixf2"
4729 [(set (match_operand:XF 0 "register_operand" "=f,f")
4730 (float:XF (match_operand:DI 1 "nonimmediate_operand" "m,?r")))]
4735 [(set_attr "type" "fmov,multi")
4736 (set_attr "mode" "XF")
4737 (set_attr "unit" "*,i387")
4738 (set_attr "fp_int_src" "true")])
4740 ;; %%% Kill these when reload knows how to do it.
4742 [(set (match_operand 0 "fp_register_operand" "")
4743 (float (match_operand 1 "register_operand" "")))]
4746 && FLOAT_MODE_P (GET_MODE (operands[0]))"
4749 operands[2] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
4750 operands[2] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[2]);
4751 emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[2]));
4752 ix86_free_from_memory (GET_MODE (operands[1]));
4756 (define_expand "floatunssisf2"
4757 [(use (match_operand:SF 0 "register_operand" ""))
4758 (use (match_operand:SI 1 "register_operand" ""))]
4759 "!TARGET_64BIT && TARGET_SSE_MATH"
4760 "x86_emit_floatuns (operands); DONE;")
4762 (define_expand "floatunsdisf2"
4763 [(use (match_operand:SF 0 "register_operand" ""))
4764 (use (match_operand:DI 1 "register_operand" ""))]
4765 "TARGET_64BIT && TARGET_SSE_MATH"
4766 "x86_emit_floatuns (operands); DONE;")
4768 (define_expand "floatunsdidf2"
4769 [(use (match_operand:DF 0 "register_operand" ""))
4770 (use (match_operand:DI 1 "register_operand" ""))]
4771 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4772 "x86_emit_floatuns (operands); DONE;")
4774 ;; SSE extract/set expanders
4779 ;; %%% splits for addditi3
4781 (define_expand "addti3"
4782 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4783 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4784 (match_operand:TI 2 "x86_64_general_operand" "")))
4785 (clobber (reg:CC FLAGS_REG))]
4787 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
4789 (define_insn "*addti3_1"
4790 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4791 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
4792 (match_operand:TI 2 "general_operand" "roiF,riF")))
4793 (clobber (reg:CC FLAGS_REG))]
4794 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
4798 [(set (match_operand:TI 0 "nonimmediate_operand" "")
4799 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
4800 (match_operand:TI 2 "general_operand" "")))
4801 (clobber (reg:CC FLAGS_REG))]
4802 "TARGET_64BIT && reload_completed"
4803 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4805 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
4806 (parallel [(set (match_dup 3)
4807 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
4810 (clobber (reg:CC FLAGS_REG))])]
4811 "split_ti (operands+0, 1, operands+0, operands+3);
4812 split_ti (operands+1, 1, operands+1, operands+4);
4813 split_ti (operands+2, 1, operands+2, operands+5);")
4815 ;; %%% splits for addsidi3
4816 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
4817 ; (plus:DI (match_operand:DI 1 "general_operand" "")
4818 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
4820 (define_expand "adddi3"
4821 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4822 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4823 (match_operand:DI 2 "x86_64_general_operand" "")))
4824 (clobber (reg:CC FLAGS_REG))]
4826 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
4828 (define_insn "*adddi3_1"
4829 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
4830 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
4831 (match_operand:DI 2 "general_operand" "roiF,riF")))
4832 (clobber (reg:CC FLAGS_REG))]
4833 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4837 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4838 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
4839 (match_operand:DI 2 "general_operand" "")))
4840 (clobber (reg:CC FLAGS_REG))]
4841 "!TARGET_64BIT && reload_completed"
4842 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
4844 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
4845 (parallel [(set (match_dup 3)
4846 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
4849 (clobber (reg:CC FLAGS_REG))])]
4850 "split_di (operands+0, 1, operands+0, operands+3);
4851 split_di (operands+1, 1, operands+1, operands+4);
4852 split_di (operands+2, 1, operands+2, operands+5);")
4854 (define_insn "adddi3_carry_rex64"
4855 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4856 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
4857 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
4858 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
4859 (clobber (reg:CC FLAGS_REG))]
4860 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4861 "adc{q}\t{%2, %0|%0, %2}"
4862 [(set_attr "type" "alu")
4863 (set_attr "pent_pair" "pu")
4864 (set_attr "mode" "DI")])
4866 (define_insn "*adddi3_cc_rex64"
4867 [(set (reg:CC FLAGS_REG)
4868 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
4869 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
4871 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
4872 (plus:DI (match_dup 1) (match_dup 2)))]
4873 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
4874 "add{q}\t{%2, %0|%0, %2}"
4875 [(set_attr "type" "alu")
4876 (set_attr "mode" "DI")])
4878 (define_insn "addqi3_carry"
4879 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4880 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
4881 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
4882 (match_operand:QI 2 "general_operand" "qi,qm")))
4883 (clobber (reg:CC FLAGS_REG))]
4884 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4885 "adc{b}\t{%2, %0|%0, %2}"
4886 [(set_attr "type" "alu")
4887 (set_attr "pent_pair" "pu")
4888 (set_attr "mode" "QI")])
4890 (define_insn "addhi3_carry"
4891 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
4892 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
4893 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
4894 (match_operand:HI 2 "general_operand" "ri,rm")))
4895 (clobber (reg:CC FLAGS_REG))]
4896 "ix86_binary_operator_ok (PLUS, HImode, operands)"
4897 "adc{w}\t{%2, %0|%0, %2}"
4898 [(set_attr "type" "alu")
4899 (set_attr "pent_pair" "pu")
4900 (set_attr "mode" "HI")])
4902 (define_insn "addsi3_carry"
4903 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4904 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4905 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
4906 (match_operand:SI 2 "general_operand" "ri,rm")))
4907 (clobber (reg:CC FLAGS_REG))]
4908 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4909 "adc{l}\t{%2, %0|%0, %2}"
4910 [(set_attr "type" "alu")
4911 (set_attr "pent_pair" "pu")
4912 (set_attr "mode" "SI")])
4914 (define_insn "*addsi3_carry_zext"
4915 [(set (match_operand:DI 0 "register_operand" "=r")
4917 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
4918 (match_operand:SI 1 "nonimmediate_operand" "%0"))
4919 (match_operand:SI 2 "general_operand" "rim"))))
4920 (clobber (reg:CC FLAGS_REG))]
4921 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
4922 "adc{l}\t{%2, %k0|%k0, %2}"
4923 [(set_attr "type" "alu")
4924 (set_attr "pent_pair" "pu")
4925 (set_attr "mode" "SI")])
4927 (define_insn "*addsi3_cc"
4928 [(set (reg:CC FLAGS_REG)
4929 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
4930 (match_operand:SI 2 "general_operand" "ri,rm")]
4932 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
4933 (plus:SI (match_dup 1) (match_dup 2)))]
4934 "ix86_binary_operator_ok (PLUS, SImode, operands)"
4935 "add{l}\t{%2, %0|%0, %2}"
4936 [(set_attr "type" "alu")
4937 (set_attr "mode" "SI")])
4939 (define_insn "addqi3_cc"
4940 [(set (reg:CC FLAGS_REG)
4941 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
4942 (match_operand:QI 2 "general_operand" "qi,qm")]
4944 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
4945 (plus:QI (match_dup 1) (match_dup 2)))]
4946 "ix86_binary_operator_ok (PLUS, QImode, operands)"
4947 "add{b}\t{%2, %0|%0, %2}"
4948 [(set_attr "type" "alu")
4949 (set_attr "mode" "QI")])
4951 (define_expand "addsi3"
4952 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4953 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
4954 (match_operand:SI 2 "general_operand" "")))
4955 (clobber (reg:CC FLAGS_REG))])]
4957 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
4959 (define_insn "*lea_1"
4960 [(set (match_operand:SI 0 "register_operand" "=r")
4961 (match_operand:SI 1 "no_seg_address_operand" "p"))]
4963 "lea{l}\t{%a1, %0|%0, %a1}"
4964 [(set_attr "type" "lea")
4965 (set_attr "mode" "SI")])
4967 (define_insn "*lea_1_rex64"
4968 [(set (match_operand:SI 0 "register_operand" "=r")
4969 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
4971 "lea{l}\t{%a1, %0|%0, %a1}"
4972 [(set_attr "type" "lea")
4973 (set_attr "mode" "SI")])
4975 (define_insn "*lea_1_zext"
4976 [(set (match_operand:DI 0 "register_operand" "=r")
4978 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
4980 "lea{l}\t{%a1, %k0|%k0, %a1}"
4981 [(set_attr "type" "lea")
4982 (set_attr "mode" "SI")])
4984 (define_insn "*lea_2_rex64"
4985 [(set (match_operand:DI 0 "register_operand" "=r")
4986 (match_operand:DI 1 "no_seg_address_operand" "p"))]
4988 "lea{q}\t{%a1, %0|%0, %a1}"
4989 [(set_attr "type" "lea")
4990 (set_attr "mode" "DI")])
4992 ;; The lea patterns for non-Pmodes needs to be matched by several
4993 ;; insns converted to real lea by splitters.
4995 (define_insn_and_split "*lea_general_1"
4996 [(set (match_operand 0 "register_operand" "=r")
4997 (plus (plus (match_operand 1 "index_register_operand" "l")
4998 (match_operand 2 "register_operand" "r"))
4999 (match_operand 3 "immediate_operand" "i")))]
5000 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5001 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5002 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5003 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5004 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5005 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5006 || GET_MODE (operands[3]) == VOIDmode)"
5008 "&& reload_completed"
5012 operands[0] = gen_lowpart (SImode, operands[0]);
5013 operands[1] = gen_lowpart (Pmode, operands[1]);
5014 operands[2] = gen_lowpart (Pmode, operands[2]);
5015 operands[3] = gen_lowpart (Pmode, operands[3]);
5016 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5018 if (Pmode != SImode)
5019 pat = gen_rtx_SUBREG (SImode, pat, 0);
5020 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5023 [(set_attr "type" "lea")
5024 (set_attr "mode" "SI")])
5026 (define_insn_and_split "*lea_general_1_zext"
5027 [(set (match_operand:DI 0 "register_operand" "=r")
5029 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5030 (match_operand:SI 2 "register_operand" "r"))
5031 (match_operand:SI 3 "immediate_operand" "i"))))]
5034 "&& reload_completed"
5036 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5038 (match_dup 3)) 0)))]
5040 operands[1] = gen_lowpart (Pmode, operands[1]);
5041 operands[2] = gen_lowpart (Pmode, operands[2]);
5042 operands[3] = gen_lowpart (Pmode, operands[3]);
5044 [(set_attr "type" "lea")
5045 (set_attr "mode" "SI")])
5047 (define_insn_and_split "*lea_general_2"
5048 [(set (match_operand 0 "register_operand" "=r")
5049 (plus (mult (match_operand 1 "index_register_operand" "l")
5050 (match_operand 2 "const248_operand" "i"))
5051 (match_operand 3 "nonmemory_operand" "ri")))]
5052 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5053 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5054 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5055 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5056 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5057 || GET_MODE (operands[3]) == VOIDmode)"
5059 "&& reload_completed"
5063 operands[0] = gen_lowpart (SImode, operands[0]);
5064 operands[1] = gen_lowpart (Pmode, operands[1]);
5065 operands[3] = gen_lowpart (Pmode, operands[3]);
5066 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5068 if (Pmode != SImode)
5069 pat = gen_rtx_SUBREG (SImode, pat, 0);
5070 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5073 [(set_attr "type" "lea")
5074 (set_attr "mode" "SI")])
5076 (define_insn_and_split "*lea_general_2_zext"
5077 [(set (match_operand:DI 0 "register_operand" "=r")
5079 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5080 (match_operand:SI 2 "const248_operand" "n"))
5081 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5084 "&& reload_completed"
5086 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5088 (match_dup 3)) 0)))]
5090 operands[1] = gen_lowpart (Pmode, operands[1]);
5091 operands[3] = gen_lowpart (Pmode, operands[3]);
5093 [(set_attr "type" "lea")
5094 (set_attr "mode" "SI")])
5096 (define_insn_and_split "*lea_general_3"
5097 [(set (match_operand 0 "register_operand" "=r")
5098 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5099 (match_operand 2 "const248_operand" "i"))
5100 (match_operand 3 "register_operand" "r"))
5101 (match_operand 4 "immediate_operand" "i")))]
5102 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5103 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5104 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5105 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5106 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5108 "&& reload_completed"
5112 operands[0] = gen_lowpart (SImode, operands[0]);
5113 operands[1] = gen_lowpart (Pmode, operands[1]);
5114 operands[3] = gen_lowpart (Pmode, operands[3]);
5115 operands[4] = gen_lowpart (Pmode, operands[4]);
5116 pat = gen_rtx_PLUS (Pmode,
5117 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5121 if (Pmode != SImode)
5122 pat = gen_rtx_SUBREG (SImode, pat, 0);
5123 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5126 [(set_attr "type" "lea")
5127 (set_attr "mode" "SI")])
5129 (define_insn_and_split "*lea_general_3_zext"
5130 [(set (match_operand:DI 0 "register_operand" "=r")
5132 (plus:SI (plus:SI (mult:SI
5133 (match_operand:SI 1 "index_register_operand" "l")
5134 (match_operand:SI 2 "const248_operand" "n"))
5135 (match_operand:SI 3 "register_operand" "r"))
5136 (match_operand:SI 4 "immediate_operand" "i"))))]
5139 "&& reload_completed"
5141 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5144 (match_dup 4)) 0)))]
5146 operands[1] = gen_lowpart (Pmode, operands[1]);
5147 operands[3] = gen_lowpart (Pmode, operands[3]);
5148 operands[4] = gen_lowpart (Pmode, operands[4]);
5150 [(set_attr "type" "lea")
5151 (set_attr "mode" "SI")])
5153 (define_insn "*adddi_1_rex64"
5154 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5155 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5156 (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5157 (clobber (reg:CC FLAGS_REG))]
5158 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5160 switch (get_attr_type (insn))
5163 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5164 return "lea{q}\t{%a2, %0|%0, %a2}";
5167 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5168 if (operands[2] == const1_rtx)
5169 return "inc{q}\t%0";
5172 gcc_assert (operands[2] == constm1_rtx);
5173 return "dec{q}\t%0";
5177 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5179 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5180 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5181 if (GET_CODE (operands[2]) == CONST_INT
5182 /* Avoid overflows. */
5183 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5184 && (INTVAL (operands[2]) == 128
5185 || (INTVAL (operands[2]) < 0
5186 && INTVAL (operands[2]) != -128)))
5188 operands[2] = GEN_INT (-INTVAL (operands[2]));
5189 return "sub{q}\t{%2, %0|%0, %2}";
5191 return "add{q}\t{%2, %0|%0, %2}";
5195 (cond [(eq_attr "alternative" "2")
5196 (const_string "lea")
5197 ; Current assemblers are broken and do not allow @GOTOFF in
5198 ; ought but a memory context.
5199 (match_operand:DI 2 "pic_symbolic_operand" "")
5200 (const_string "lea")
5201 (match_operand:DI 2 "incdec_operand" "")
5202 (const_string "incdec")
5204 (const_string "alu")))
5205 (set_attr "mode" "DI")])
5207 ;; Convert lea to the lea pattern to avoid flags dependency.
5209 [(set (match_operand:DI 0 "register_operand" "")
5210 (plus:DI (match_operand:DI 1 "register_operand" "")
5211 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5212 (clobber (reg:CC FLAGS_REG))]
5213 "TARGET_64BIT && reload_completed
5214 && true_regnum (operands[0]) != true_regnum (operands[1])"
5216 (plus:DI (match_dup 1)
5220 (define_insn "*adddi_2_rex64"
5221 [(set (reg FLAGS_REG)
5223 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5224 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5226 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5227 (plus:DI (match_dup 1) (match_dup 2)))]
5228 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5229 && ix86_binary_operator_ok (PLUS, DImode, operands)
5230 /* Current assemblers are broken and do not allow @GOTOFF in
5231 ought but a memory context. */
5232 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5234 switch (get_attr_type (insn))
5237 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5238 if (operands[2] == const1_rtx)
5239 return "inc{q}\t%0";
5242 gcc_assert (operands[2] == constm1_rtx);
5243 return "dec{q}\t%0";
5247 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5248 /* ???? We ought to handle there the 32bit case too
5249 - do we need new constraint? */
5250 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5251 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5252 if (GET_CODE (operands[2]) == CONST_INT
5253 /* Avoid overflows. */
5254 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5255 && (INTVAL (operands[2]) == 128
5256 || (INTVAL (operands[2]) < 0
5257 && INTVAL (operands[2]) != -128)))
5259 operands[2] = GEN_INT (-INTVAL (operands[2]));
5260 return "sub{q}\t{%2, %0|%0, %2}";
5262 return "add{q}\t{%2, %0|%0, %2}";
5266 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5267 (const_string "incdec")
5268 (const_string "alu")))
5269 (set_attr "mode" "DI")])
5271 (define_insn "*adddi_3_rex64"
5272 [(set (reg FLAGS_REG)
5273 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5274 (match_operand:DI 1 "x86_64_general_operand" "%0")))
5275 (clobber (match_scratch:DI 0 "=r"))]
5277 && ix86_match_ccmode (insn, CCZmode)
5278 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5279 /* Current assemblers are broken and do not allow @GOTOFF in
5280 ought but a memory context. */
5281 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5283 switch (get_attr_type (insn))
5286 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5287 if (operands[2] == const1_rtx)
5288 return "inc{q}\t%0";
5291 gcc_assert (operands[2] == constm1_rtx);
5292 return "dec{q}\t%0";
5296 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5297 /* ???? We ought to handle there the 32bit case too
5298 - do we need new constraint? */
5299 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5300 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5301 if (GET_CODE (operands[2]) == CONST_INT
5302 /* Avoid overflows. */
5303 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5304 && (INTVAL (operands[2]) == 128
5305 || (INTVAL (operands[2]) < 0
5306 && INTVAL (operands[2]) != -128)))
5308 operands[2] = GEN_INT (-INTVAL (operands[2]));
5309 return "sub{q}\t{%2, %0|%0, %2}";
5311 return "add{q}\t{%2, %0|%0, %2}";
5315 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5316 (const_string "incdec")
5317 (const_string "alu")))
5318 (set_attr "mode" "DI")])
5320 ; For comparisons against 1, -1 and 128, we may generate better code
5321 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5322 ; is matched then. We can't accept general immediate, because for
5323 ; case of overflows, the result is messed up.
5324 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
5326 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5327 ; only for comparisons not depending on it.
5328 (define_insn "*adddi_4_rex64"
5329 [(set (reg FLAGS_REG)
5330 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
5331 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5332 (clobber (match_scratch:DI 0 "=rm"))]
5334 && ix86_match_ccmode (insn, CCGCmode)"
5336 switch (get_attr_type (insn))
5339 if (operands[2] == constm1_rtx)
5340 return "inc{q}\t%0";
5343 gcc_assert (operands[2] == const1_rtx);
5344 return "dec{q}\t%0";
5348 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5349 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5350 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5351 if ((INTVAL (operands[2]) == -128
5352 || (INTVAL (operands[2]) > 0
5353 && INTVAL (operands[2]) != 128))
5354 /* Avoid overflows. */
5355 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
5356 return "sub{q}\t{%2, %0|%0, %2}";
5357 operands[2] = GEN_INT (-INTVAL (operands[2]));
5358 return "add{q}\t{%2, %0|%0, %2}";
5362 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5363 (const_string "incdec")
5364 (const_string "alu")))
5365 (set_attr "mode" "DI")])
5367 (define_insn "*adddi_5_rex64"
5368 [(set (reg FLAGS_REG)
5370 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
5371 (match_operand:DI 2 "x86_64_general_operand" "rme"))
5373 (clobber (match_scratch:DI 0 "=r"))]
5375 && ix86_match_ccmode (insn, CCGOCmode)
5376 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5377 /* Current assemblers are broken and do not allow @GOTOFF in
5378 ought but a memory context. */
5379 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5381 switch (get_attr_type (insn))
5384 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5385 if (operands[2] == const1_rtx)
5386 return "inc{q}\t%0";
5389 gcc_assert (operands[2] == constm1_rtx);
5390 return "dec{q}\t%0";
5394 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5395 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5396 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5397 if (GET_CODE (operands[2]) == CONST_INT
5398 /* Avoid overflows. */
5399 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5400 && (INTVAL (operands[2]) == 128
5401 || (INTVAL (operands[2]) < 0
5402 && INTVAL (operands[2]) != -128)))
5404 operands[2] = GEN_INT (-INTVAL (operands[2]));
5405 return "sub{q}\t{%2, %0|%0, %2}";
5407 return "add{q}\t{%2, %0|%0, %2}";
5411 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5412 (const_string "incdec")
5413 (const_string "alu")))
5414 (set_attr "mode" "DI")])
5417 (define_insn "*addsi_1"
5418 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
5419 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
5420 (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
5421 (clobber (reg:CC FLAGS_REG))]
5422 "ix86_binary_operator_ok (PLUS, SImode, operands)"
5424 switch (get_attr_type (insn))
5427 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5428 return "lea{l}\t{%a2, %0|%0, %a2}";
5431 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5432 if (operands[2] == const1_rtx)
5433 return "inc{l}\t%0";
5436 gcc_assert (operands[2] == constm1_rtx);
5437 return "dec{l}\t%0";
5441 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5443 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5444 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5445 if (GET_CODE (operands[2]) == CONST_INT
5446 && (INTVAL (operands[2]) == 128
5447 || (INTVAL (operands[2]) < 0
5448 && INTVAL (operands[2]) != -128)))
5450 operands[2] = GEN_INT (-INTVAL (operands[2]));
5451 return "sub{l}\t{%2, %0|%0, %2}";
5453 return "add{l}\t{%2, %0|%0, %2}";
5457 (cond [(eq_attr "alternative" "2")
5458 (const_string "lea")
5459 ; Current assemblers are broken and do not allow @GOTOFF in
5460 ; ought but a memory context.
5461 (match_operand:SI 2 "pic_symbolic_operand" "")
5462 (const_string "lea")
5463 (match_operand:SI 2 "incdec_operand" "")
5464 (const_string "incdec")
5466 (const_string "alu")))
5467 (set_attr "mode" "SI")])
5469 ;; Convert lea to the lea pattern to avoid flags dependency.
5471 [(set (match_operand 0 "register_operand" "")
5472 (plus (match_operand 1 "register_operand" "")
5473 (match_operand 2 "nonmemory_operand" "")))
5474 (clobber (reg:CC FLAGS_REG))]
5476 && true_regnum (operands[0]) != true_regnum (operands[1])"
5480 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5481 may confuse gen_lowpart. */
5482 if (GET_MODE (operands[0]) != Pmode)
5484 operands[1] = gen_lowpart (Pmode, operands[1]);
5485 operands[2] = gen_lowpart (Pmode, operands[2]);
5487 operands[0] = gen_lowpart (SImode, operands[0]);
5488 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5489 if (Pmode != SImode)
5490 pat = gen_rtx_SUBREG (SImode, pat, 0);
5491 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5495 ;; It may seem that nonimmediate operand is proper one for operand 1.
5496 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5497 ;; we take care in ix86_binary_operator_ok to not allow two memory
5498 ;; operands so proper swapping will be done in reload. This allow
5499 ;; patterns constructed from addsi_1 to match.
5500 (define_insn "addsi_1_zext"
5501 [(set (match_operand:DI 0 "register_operand" "=r,r")
5503 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5504 (match_operand:SI 2 "general_operand" "rmni,lni"))))
5505 (clobber (reg:CC FLAGS_REG))]
5506 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5508 switch (get_attr_type (insn))
5511 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5512 return "lea{l}\t{%a2, %k0|%k0, %a2}";
5515 if (operands[2] == const1_rtx)
5516 return "inc{l}\t%k0";
5519 gcc_assert (operands[2] == constm1_rtx);
5520 return "dec{l}\t%k0";
5524 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5525 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5526 if (GET_CODE (operands[2]) == CONST_INT
5527 && (INTVAL (operands[2]) == 128
5528 || (INTVAL (operands[2]) < 0
5529 && INTVAL (operands[2]) != -128)))
5531 operands[2] = GEN_INT (-INTVAL (operands[2]));
5532 return "sub{l}\t{%2, %k0|%k0, %2}";
5534 return "add{l}\t{%2, %k0|%k0, %2}";
5538 (cond [(eq_attr "alternative" "1")
5539 (const_string "lea")
5540 ; Current assemblers are broken and do not allow @GOTOFF in
5541 ; ought but a memory context.
5542 (match_operand:SI 2 "pic_symbolic_operand" "")
5543 (const_string "lea")
5544 (match_operand:SI 2 "incdec_operand" "")
5545 (const_string "incdec")
5547 (const_string "alu")))
5548 (set_attr "mode" "SI")])
5550 ;; Convert lea to the lea pattern to avoid flags dependency.
5552 [(set (match_operand:DI 0 "register_operand" "")
5554 (plus:SI (match_operand:SI 1 "register_operand" "")
5555 (match_operand:SI 2 "nonmemory_operand" ""))))
5556 (clobber (reg:CC FLAGS_REG))]
5557 "TARGET_64BIT && reload_completed
5558 && true_regnum (operands[0]) != true_regnum (operands[1])"
5560 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
5562 operands[1] = gen_lowpart (Pmode, operands[1]);
5563 operands[2] = gen_lowpart (Pmode, operands[2]);
5566 (define_insn "*addsi_2"
5567 [(set (reg FLAGS_REG)
5569 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
5570 (match_operand:SI 2 "general_operand" "rmni,rni"))
5572 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
5573 (plus:SI (match_dup 1) (match_dup 2)))]
5574 "ix86_match_ccmode (insn, CCGOCmode)
5575 && ix86_binary_operator_ok (PLUS, SImode, operands)
5576 /* Current assemblers are broken and do not allow @GOTOFF in
5577 ought but a memory context. */
5578 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5580 switch (get_attr_type (insn))
5583 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5584 if (operands[2] == const1_rtx)
5585 return "inc{l}\t%0";
5588 gcc_assert (operands[2] == constm1_rtx);
5589 return "dec{l}\t%0";
5593 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5594 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5595 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5596 if (GET_CODE (operands[2]) == CONST_INT
5597 && (INTVAL (operands[2]) == 128
5598 || (INTVAL (operands[2]) < 0
5599 && INTVAL (operands[2]) != -128)))
5601 operands[2] = GEN_INT (-INTVAL (operands[2]));
5602 return "sub{l}\t{%2, %0|%0, %2}";
5604 return "add{l}\t{%2, %0|%0, %2}";
5608 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5609 (const_string "incdec")
5610 (const_string "alu")))
5611 (set_attr "mode" "SI")])
5613 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5614 (define_insn "*addsi_2_zext"
5615 [(set (reg FLAGS_REG)
5617 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5618 (match_operand:SI 2 "general_operand" "rmni"))
5620 (set (match_operand:DI 0 "register_operand" "=r")
5621 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5622 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5623 && ix86_binary_operator_ok (PLUS, SImode, operands)
5624 /* Current assemblers are broken and do not allow @GOTOFF in
5625 ought but a memory context. */
5626 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5628 switch (get_attr_type (insn))
5631 if (operands[2] == const1_rtx)
5632 return "inc{l}\t%k0";
5635 gcc_assert (operands[2] == constm1_rtx);
5636 return "dec{l}\t%k0";
5640 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5641 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5642 if (GET_CODE (operands[2]) == CONST_INT
5643 && (INTVAL (operands[2]) == 128
5644 || (INTVAL (operands[2]) < 0
5645 && INTVAL (operands[2]) != -128)))
5647 operands[2] = GEN_INT (-INTVAL (operands[2]));
5648 return "sub{l}\t{%2, %k0|%k0, %2}";
5650 return "add{l}\t{%2, %k0|%k0, %2}";
5654 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5655 (const_string "incdec")
5656 (const_string "alu")))
5657 (set_attr "mode" "SI")])
5659 (define_insn "*addsi_3"
5660 [(set (reg FLAGS_REG)
5661 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5662 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5663 (clobber (match_scratch:SI 0 "=r"))]
5664 "ix86_match_ccmode (insn, CCZmode)
5665 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5666 /* Current assemblers are broken and do not allow @GOTOFF in
5667 ought but a memory context. */
5668 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5670 switch (get_attr_type (insn))
5673 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5674 if (operands[2] == const1_rtx)
5675 return "inc{l}\t%0";
5678 gcc_assert (operands[2] == constm1_rtx);
5679 return "dec{l}\t%0";
5683 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5684 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5685 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5686 if (GET_CODE (operands[2]) == CONST_INT
5687 && (INTVAL (operands[2]) == 128
5688 || (INTVAL (operands[2]) < 0
5689 && INTVAL (operands[2]) != -128)))
5691 operands[2] = GEN_INT (-INTVAL (operands[2]));
5692 return "sub{l}\t{%2, %0|%0, %2}";
5694 return "add{l}\t{%2, %0|%0, %2}";
5698 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5699 (const_string "incdec")
5700 (const_string "alu")))
5701 (set_attr "mode" "SI")])
5703 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5704 (define_insn "*addsi_3_zext"
5705 [(set (reg FLAGS_REG)
5706 (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
5707 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5708 (set (match_operand:DI 0 "register_operand" "=r")
5709 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5710 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5711 && ix86_binary_operator_ok (PLUS, SImode, operands)
5712 /* Current assemblers are broken and do not allow @GOTOFF in
5713 ought but a memory context. */
5714 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5716 switch (get_attr_type (insn))
5719 if (operands[2] == const1_rtx)
5720 return "inc{l}\t%k0";
5723 gcc_assert (operands[2] == constm1_rtx);
5724 return "dec{l}\t%k0";
5728 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5729 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5730 if (GET_CODE (operands[2]) == CONST_INT
5731 && (INTVAL (operands[2]) == 128
5732 || (INTVAL (operands[2]) < 0
5733 && INTVAL (operands[2]) != -128)))
5735 operands[2] = GEN_INT (-INTVAL (operands[2]));
5736 return "sub{l}\t{%2, %k0|%k0, %2}";
5738 return "add{l}\t{%2, %k0|%k0, %2}";
5742 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5743 (const_string "incdec")
5744 (const_string "alu")))
5745 (set_attr "mode" "SI")])
5747 ; For comparisons against 1, -1 and 128, we may generate better code
5748 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5749 ; is matched then. We can't accept general immediate, because for
5750 ; case of overflows, the result is messed up.
5751 ; This pattern also don't hold of 0x80000000, since the value overflows
5753 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5754 ; only for comparisons not depending on it.
5755 (define_insn "*addsi_4"
5756 [(set (reg FLAGS_REG)
5757 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
5758 (match_operand:SI 2 "const_int_operand" "n")))
5759 (clobber (match_scratch:SI 0 "=rm"))]
5760 "ix86_match_ccmode (insn, CCGCmode)
5761 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
5763 switch (get_attr_type (insn))
5766 if (operands[2] == constm1_rtx)
5767 return "inc{l}\t%0";
5770 gcc_assert (operands[2] == const1_rtx);
5771 return "dec{l}\t%0";
5775 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5776 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5777 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5778 if ((INTVAL (operands[2]) == -128
5779 || (INTVAL (operands[2]) > 0
5780 && INTVAL (operands[2]) != 128)))
5781 return "sub{l}\t{%2, %0|%0, %2}";
5782 operands[2] = GEN_INT (-INTVAL (operands[2]));
5783 return "add{l}\t{%2, %0|%0, %2}";
5787 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5788 (const_string "incdec")
5789 (const_string "alu")))
5790 (set_attr "mode" "SI")])
5792 (define_insn "*addsi_5"
5793 [(set (reg FLAGS_REG)
5795 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5796 (match_operand:SI 2 "general_operand" "rmni"))
5798 (clobber (match_scratch:SI 0 "=r"))]
5799 "ix86_match_ccmode (insn, CCGOCmode)
5800 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)
5801 /* Current assemblers are broken and do not allow @GOTOFF in
5802 ought but a memory context. */
5803 && ! pic_symbolic_operand (operands[2], VOIDmode)"
5805 switch (get_attr_type (insn))
5808 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809 if (operands[2] == const1_rtx)
5810 return "inc{l}\t%0";
5813 gcc_assert (operands[2] == constm1_rtx);
5814 return "dec{l}\t%0";
5818 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5819 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5820 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5821 if (GET_CODE (operands[2]) == CONST_INT
5822 && (INTVAL (operands[2]) == 128
5823 || (INTVAL (operands[2]) < 0
5824 && INTVAL (operands[2]) != -128)))
5826 operands[2] = GEN_INT (-INTVAL (operands[2]));
5827 return "sub{l}\t{%2, %0|%0, %2}";
5829 return "add{l}\t{%2, %0|%0, %2}";
5833 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5834 (const_string "incdec")
5835 (const_string "alu")))
5836 (set_attr "mode" "SI")])
5838 (define_expand "addhi3"
5839 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
5840 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
5841 (match_operand:HI 2 "general_operand" "")))
5842 (clobber (reg:CC FLAGS_REG))])]
5843 "TARGET_HIMODE_MATH"
5844 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
5846 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
5847 ;; type optimizations enabled by define-splits. This is not important
5848 ;; for PII, and in fact harmful because of partial register stalls.
5850 (define_insn "*addhi_1_lea"
5851 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
5852 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
5853 (match_operand:HI 2 "general_operand" "ri,rm,lni")))
5854 (clobber (reg:CC FLAGS_REG))]
5855 "!TARGET_PARTIAL_REG_STALL
5856 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5858 switch (get_attr_type (insn))
5863 if (operands[2] == const1_rtx)
5864 return "inc{w}\t%0";
5867 gcc_assert (operands[2] == constm1_rtx);
5868 return "dec{w}\t%0";
5872 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5873 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5874 if (GET_CODE (operands[2]) == CONST_INT
5875 && (INTVAL (operands[2]) == 128
5876 || (INTVAL (operands[2]) < 0
5877 && INTVAL (operands[2]) != -128)))
5879 operands[2] = GEN_INT (-INTVAL (operands[2]));
5880 return "sub{w}\t{%2, %0|%0, %2}";
5882 return "add{w}\t{%2, %0|%0, %2}";
5886 (if_then_else (eq_attr "alternative" "2")
5887 (const_string "lea")
5888 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5889 (const_string "incdec")
5890 (const_string "alu"))))
5891 (set_attr "mode" "HI,HI,SI")])
5893 (define_insn "*addhi_1"
5894 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5895 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5896 (match_operand:HI 2 "general_operand" "ri,rm")))
5897 (clobber (reg:CC FLAGS_REG))]
5898 "TARGET_PARTIAL_REG_STALL
5899 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5901 switch (get_attr_type (insn))
5904 if (operands[2] == const1_rtx)
5905 return "inc{w}\t%0";
5908 gcc_assert (operands[2] == constm1_rtx);
5909 return "dec{w}\t%0";
5913 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5914 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5915 if (GET_CODE (operands[2]) == CONST_INT
5916 && (INTVAL (operands[2]) == 128
5917 || (INTVAL (operands[2]) < 0
5918 && INTVAL (operands[2]) != -128)))
5920 operands[2] = GEN_INT (-INTVAL (operands[2]));
5921 return "sub{w}\t{%2, %0|%0, %2}";
5923 return "add{w}\t{%2, %0|%0, %2}";
5927 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5928 (const_string "incdec")
5929 (const_string "alu")))
5930 (set_attr "mode" "HI")])
5932 (define_insn "*addhi_2"
5933 [(set (reg FLAGS_REG)
5935 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5936 (match_operand:HI 2 "general_operand" "rmni,rni"))
5938 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
5939 (plus:HI (match_dup 1) (match_dup 2)))]
5940 "ix86_match_ccmode (insn, CCGOCmode)
5941 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5943 switch (get_attr_type (insn))
5946 if (operands[2] == const1_rtx)
5947 return "inc{w}\t%0";
5950 gcc_assert (operands[2] == constm1_rtx);
5951 return "dec{w}\t%0";
5955 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5956 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5957 if (GET_CODE (operands[2]) == CONST_INT
5958 && (INTVAL (operands[2]) == 128
5959 || (INTVAL (operands[2]) < 0
5960 && INTVAL (operands[2]) != -128)))
5962 operands[2] = GEN_INT (-INTVAL (operands[2]));
5963 return "sub{w}\t{%2, %0|%0, %2}";
5965 return "add{w}\t{%2, %0|%0, %2}";
5969 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5970 (const_string "incdec")
5971 (const_string "alu")))
5972 (set_attr "mode" "HI")])
5974 (define_insn "*addhi_3"
5975 [(set (reg FLAGS_REG)
5976 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
5977 (match_operand:HI 1 "nonimmediate_operand" "%0")))
5978 (clobber (match_scratch:HI 0 "=r"))]
5979 "ix86_match_ccmode (insn, CCZmode)
5980 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
5982 switch (get_attr_type (insn))
5985 if (operands[2] == const1_rtx)
5986 return "inc{w}\t%0";
5989 gcc_assert (operands[2] == constm1_rtx);
5990 return "dec{w}\t%0";
5994 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5995 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
5996 if (GET_CODE (operands[2]) == CONST_INT
5997 && (INTVAL (operands[2]) == 128
5998 || (INTVAL (operands[2]) < 0
5999 && INTVAL (operands[2]) != -128)))
6001 operands[2] = GEN_INT (-INTVAL (operands[2]));
6002 return "sub{w}\t{%2, %0|%0, %2}";
6004 return "add{w}\t{%2, %0|%0, %2}";
6008 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6009 (const_string "incdec")
6010 (const_string "alu")))
6011 (set_attr "mode" "HI")])
6013 ; See comments above addsi_4 for details.
6014 (define_insn "*addhi_4"
6015 [(set (reg FLAGS_REG)
6016 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6017 (match_operand:HI 2 "const_int_operand" "n")))
6018 (clobber (match_scratch:HI 0 "=rm"))]
6019 "ix86_match_ccmode (insn, CCGCmode)
6020 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6022 switch (get_attr_type (insn))
6025 if (operands[2] == constm1_rtx)
6026 return "inc{w}\t%0";
6029 gcc_assert (operands[2] == const1_rtx);
6030 return "dec{w}\t%0";
6034 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6035 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6036 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6037 if ((INTVAL (operands[2]) == -128
6038 || (INTVAL (operands[2]) > 0
6039 && INTVAL (operands[2]) != 128)))
6040 return "sub{w}\t{%2, %0|%0, %2}";
6041 operands[2] = GEN_INT (-INTVAL (operands[2]));
6042 return "add{w}\t{%2, %0|%0, %2}";
6046 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6047 (const_string "incdec")
6048 (const_string "alu")))
6049 (set_attr "mode" "SI")])
6052 (define_insn "*addhi_5"
6053 [(set (reg FLAGS_REG)
6055 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6056 (match_operand:HI 2 "general_operand" "rmni"))
6058 (clobber (match_scratch:HI 0 "=r"))]
6059 "ix86_match_ccmode (insn, CCGOCmode)
6060 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6062 switch (get_attr_type (insn))
6065 if (operands[2] == const1_rtx)
6066 return "inc{w}\t%0";
6069 gcc_assert (operands[2] == constm1_rtx);
6070 return "dec{w}\t%0";
6074 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6075 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6076 if (GET_CODE (operands[2]) == CONST_INT
6077 && (INTVAL (operands[2]) == 128
6078 || (INTVAL (operands[2]) < 0
6079 && INTVAL (operands[2]) != -128)))
6081 operands[2] = GEN_INT (-INTVAL (operands[2]));
6082 return "sub{w}\t{%2, %0|%0, %2}";
6084 return "add{w}\t{%2, %0|%0, %2}";
6088 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6089 (const_string "incdec")
6090 (const_string "alu")))
6091 (set_attr "mode" "HI")])
6093 (define_expand "addqi3"
6094 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6095 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6096 (match_operand:QI 2 "general_operand" "")))
6097 (clobber (reg:CC FLAGS_REG))])]
6098 "TARGET_QIMODE_MATH"
6099 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6101 ;; %%% Potential partial reg stall on alternative 2. What to do?
6102 (define_insn "*addqi_1_lea"
6103 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6104 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6105 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6106 (clobber (reg:CC FLAGS_REG))]
6107 "!TARGET_PARTIAL_REG_STALL
6108 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6110 int widen = (which_alternative == 2);
6111 switch (get_attr_type (insn))
6116 if (operands[2] == const1_rtx)
6117 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6120 gcc_assert (operands[2] == constm1_rtx);
6121 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6125 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6126 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6127 if (GET_CODE (operands[2]) == CONST_INT
6128 && (INTVAL (operands[2]) == 128
6129 || (INTVAL (operands[2]) < 0
6130 && INTVAL (operands[2]) != -128)))
6132 operands[2] = GEN_INT (-INTVAL (operands[2]));
6134 return "sub{l}\t{%2, %k0|%k0, %2}";
6136 return "sub{b}\t{%2, %0|%0, %2}";
6139 return "add{l}\t{%k2, %k0|%k0, %k2}";
6141 return "add{b}\t{%2, %0|%0, %2}";
6145 (if_then_else (eq_attr "alternative" "3")
6146 (const_string "lea")
6147 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6148 (const_string "incdec")
6149 (const_string "alu"))))
6150 (set_attr "mode" "QI,QI,SI,SI")])
6152 (define_insn "*addqi_1"
6153 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6154 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6155 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6156 (clobber (reg:CC FLAGS_REG))]
6157 "TARGET_PARTIAL_REG_STALL
6158 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6160 int widen = (which_alternative == 2);
6161 switch (get_attr_type (insn))
6164 if (operands[2] == const1_rtx)
6165 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6168 gcc_assert (operands[2] == constm1_rtx);
6169 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6173 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6174 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6175 if (GET_CODE (operands[2]) == CONST_INT
6176 && (INTVAL (operands[2]) == 128
6177 || (INTVAL (operands[2]) < 0
6178 && INTVAL (operands[2]) != -128)))
6180 operands[2] = GEN_INT (-INTVAL (operands[2]));
6182 return "sub{l}\t{%2, %k0|%k0, %2}";
6184 return "sub{b}\t{%2, %0|%0, %2}";
6187 return "add{l}\t{%k2, %k0|%k0, %k2}";
6189 return "add{b}\t{%2, %0|%0, %2}";
6193 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6194 (const_string "incdec")
6195 (const_string "alu")))
6196 (set_attr "mode" "QI,QI,SI")])
6198 (define_insn "*addqi_1_slp"
6199 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6200 (plus:QI (match_dup 0)
6201 (match_operand:QI 1 "general_operand" "qn,qnm")))
6202 (clobber (reg:CC FLAGS_REG))]
6203 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6204 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6206 switch (get_attr_type (insn))
6209 if (operands[1] == const1_rtx)
6210 return "inc{b}\t%0";
6213 gcc_assert (operands[1] == constm1_rtx);
6214 return "dec{b}\t%0";
6218 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
6219 if (GET_CODE (operands[1]) == CONST_INT
6220 && INTVAL (operands[1]) < 0)
6222 operands[1] = GEN_INT (-INTVAL (operands[1]));
6223 return "sub{b}\t{%1, %0|%0, %1}";
6225 return "add{b}\t{%1, %0|%0, %1}";
6229 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6230 (const_string "incdec")
6231 (const_string "alu1")))
6232 (set (attr "memory")
6233 (if_then_else (match_operand 1 "memory_operand" "")
6234 (const_string "load")
6235 (const_string "none")))
6236 (set_attr "mode" "QI")])
6238 (define_insn "*addqi_2"
6239 [(set (reg FLAGS_REG)
6241 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6242 (match_operand:QI 2 "general_operand" "qmni,qni"))
6244 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6245 (plus:QI (match_dup 1) (match_dup 2)))]
6246 "ix86_match_ccmode (insn, CCGOCmode)
6247 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6249 switch (get_attr_type (insn))
6252 if (operands[2] == const1_rtx)
6253 return "inc{b}\t%0";
6256 gcc_assert (operands[2] == constm1_rtx
6257 || (GET_CODE (operands[2]) == CONST_INT
6258 && INTVAL (operands[2]) == 255));
6259 return "dec{b}\t%0";
6263 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6264 if (GET_CODE (operands[2]) == CONST_INT
6265 && INTVAL (operands[2]) < 0)
6267 operands[2] = GEN_INT (-INTVAL (operands[2]));
6268 return "sub{b}\t{%2, %0|%0, %2}";
6270 return "add{b}\t{%2, %0|%0, %2}";
6274 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6275 (const_string "incdec")
6276 (const_string "alu")))
6277 (set_attr "mode" "QI")])
6279 (define_insn "*addqi_3"
6280 [(set (reg FLAGS_REG)
6281 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
6282 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6283 (clobber (match_scratch:QI 0 "=q"))]
6284 "ix86_match_ccmode (insn, CCZmode)
6285 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6287 switch (get_attr_type (insn))
6290 if (operands[2] == const1_rtx)
6291 return "inc{b}\t%0";
6294 gcc_assert (operands[2] == constm1_rtx
6295 || (GET_CODE (operands[2]) == CONST_INT
6296 && INTVAL (operands[2]) == 255));
6297 return "dec{b}\t%0";
6301 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6302 if (GET_CODE (operands[2]) == CONST_INT
6303 && INTVAL (operands[2]) < 0)
6305 operands[2] = GEN_INT (-INTVAL (operands[2]));
6306 return "sub{b}\t{%2, %0|%0, %2}";
6308 return "add{b}\t{%2, %0|%0, %2}";
6312 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6313 (const_string "incdec")
6314 (const_string "alu")))
6315 (set_attr "mode" "QI")])
6317 ; See comments above addsi_4 for details.
6318 (define_insn "*addqi_4"
6319 [(set (reg FLAGS_REG)
6320 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
6321 (match_operand:QI 2 "const_int_operand" "n")))
6322 (clobber (match_scratch:QI 0 "=qm"))]
6323 "ix86_match_ccmode (insn, CCGCmode)
6324 && (INTVAL (operands[2]) & 0xff) != 0x80"
6326 switch (get_attr_type (insn))
6329 if (operands[2] == constm1_rtx
6330 || (GET_CODE (operands[2]) == CONST_INT
6331 && INTVAL (operands[2]) == 255))
6332 return "inc{b}\t%0";
6335 gcc_assert (operands[2] == const1_rtx);
6336 return "dec{b}\t%0";
6340 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6341 if (INTVAL (operands[2]) < 0)
6343 operands[2] = GEN_INT (-INTVAL (operands[2]));
6344 return "add{b}\t{%2, %0|%0, %2}";
6346 return "sub{b}\t{%2, %0|%0, %2}";
6350 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6351 (const_string "incdec")
6352 (const_string "alu")))
6353 (set_attr "mode" "QI")])
6356 (define_insn "*addqi_5"
6357 [(set (reg FLAGS_REG)
6359 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6360 (match_operand:QI 2 "general_operand" "qmni"))
6362 (clobber (match_scratch:QI 0 "=q"))]
6363 "ix86_match_ccmode (insn, CCGOCmode)
6364 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6366 switch (get_attr_type (insn))
6369 if (operands[2] == const1_rtx)
6370 return "inc{b}\t%0";
6373 gcc_assert (operands[2] == constm1_rtx
6374 || (GET_CODE (operands[2]) == CONST_INT
6375 && INTVAL (operands[2]) == 255));
6376 return "dec{b}\t%0";
6380 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
6381 if (GET_CODE (operands[2]) == CONST_INT
6382 && INTVAL (operands[2]) < 0)
6384 operands[2] = GEN_INT (-INTVAL (operands[2]));
6385 return "sub{b}\t{%2, %0|%0, %2}";
6387 return "add{b}\t{%2, %0|%0, %2}";
6391 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6392 (const_string "incdec")
6393 (const_string "alu")))
6394 (set_attr "mode" "QI")])
6397 (define_insn "addqi_ext_1"
6398 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6403 (match_operand 1 "ext_register_operand" "0")
6406 (match_operand:QI 2 "general_operand" "Qmn")))
6407 (clobber (reg:CC FLAGS_REG))]
6410 switch (get_attr_type (insn))
6413 if (operands[2] == const1_rtx)
6414 return "inc{b}\t%h0";
6417 gcc_assert (operands[2] == constm1_rtx
6418 || (GET_CODE (operands[2]) == CONST_INT
6419 && INTVAL (operands[2]) == 255));
6420 return "dec{b}\t%h0";
6424 return "add{b}\t{%2, %h0|%h0, %2}";
6428 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6429 (const_string "incdec")
6430 (const_string "alu")))
6431 (set_attr "mode" "QI")])
6433 (define_insn "*addqi_ext_1_rex64"
6434 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6439 (match_operand 1 "ext_register_operand" "0")
6442 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6443 (clobber (reg:CC FLAGS_REG))]
6446 switch (get_attr_type (insn))
6449 if (operands[2] == const1_rtx)
6450 return "inc{b}\t%h0";
6453 gcc_assert (operands[2] == constm1_rtx
6454 || (GET_CODE (operands[2]) == CONST_INT
6455 && INTVAL (operands[2]) == 255));
6456 return "dec{b}\t%h0";
6460 return "add{b}\t{%2, %h0|%h0, %2}";
6464 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6465 (const_string "incdec")
6466 (const_string "alu")))
6467 (set_attr "mode" "QI")])
6469 (define_insn "*addqi_ext_2"
6470 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6475 (match_operand 1 "ext_register_operand" "%0")
6479 (match_operand 2 "ext_register_operand" "Q")
6482 (clobber (reg:CC FLAGS_REG))]
6484 "add{b}\t{%h2, %h0|%h0, %h2}"
6485 [(set_attr "type" "alu")
6486 (set_attr "mode" "QI")])
6488 ;; The patterns that match these are at the end of this file.
6490 (define_expand "addxf3"
6491 [(set (match_operand:XF 0 "register_operand" "")
6492 (plus:XF (match_operand:XF 1 "register_operand" "")
6493 (match_operand:XF 2 "register_operand" "")))]
6497 (define_expand "adddf3"
6498 [(set (match_operand:DF 0 "register_operand" "")
6499 (plus:DF (match_operand:DF 1 "register_operand" "")
6500 (match_operand:DF 2 "nonimmediate_operand" "")))]
6501 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6504 (define_expand "addsf3"
6505 [(set (match_operand:SF 0 "register_operand" "")
6506 (plus:SF (match_operand:SF 1 "register_operand" "")
6507 (match_operand:SF 2 "nonimmediate_operand" "")))]
6508 "TARGET_80387 || TARGET_SSE_MATH"
6511 ;; Subtract instructions
6513 ;; %%% splits for subditi3
6515 (define_expand "subti3"
6516 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
6517 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6518 (match_operand:TI 2 "x86_64_general_operand" "")))
6519 (clobber (reg:CC FLAGS_REG))])]
6521 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
6523 (define_insn "*subti3_1"
6524 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6525 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
6526 (match_operand:TI 2 "general_operand" "roiF,riF")))
6527 (clobber (reg:CC FLAGS_REG))]
6528 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
6532 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6533 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6534 (match_operand:TI 2 "general_operand" "")))
6535 (clobber (reg:CC FLAGS_REG))]
6536 "TARGET_64BIT && reload_completed"
6537 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6538 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
6539 (parallel [(set (match_dup 3)
6540 (minus:DI (match_dup 4)
6541 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6543 (clobber (reg:CC FLAGS_REG))])]
6544 "split_ti (operands+0, 1, operands+0, operands+3);
6545 split_ti (operands+1, 1, operands+1, operands+4);
6546 split_ti (operands+2, 1, operands+2, operands+5);")
6548 ;; %%% splits for subsidi3
6550 (define_expand "subdi3"
6551 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
6552 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6553 (match_operand:DI 2 "x86_64_general_operand" "")))
6554 (clobber (reg:CC FLAGS_REG))])]
6556 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
6558 (define_insn "*subdi3_1"
6559 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6560 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6561 (match_operand:DI 2 "general_operand" "roiF,riF")))
6562 (clobber (reg:CC FLAGS_REG))]
6563 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6567 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6568 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6569 (match_operand:DI 2 "general_operand" "")))
6570 (clobber (reg:CC FLAGS_REG))]
6571 "!TARGET_64BIT && reload_completed"
6572 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
6573 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
6574 (parallel [(set (match_dup 3)
6575 (minus:SI (match_dup 4)
6576 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6578 (clobber (reg:CC FLAGS_REG))])]
6579 "split_di (operands+0, 1, operands+0, operands+3);
6580 split_di (operands+1, 1, operands+1, operands+4);
6581 split_di (operands+2, 1, operands+2, operands+5);")
6583 (define_insn "subdi3_carry_rex64"
6584 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6585 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6586 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6587 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
6588 (clobber (reg:CC FLAGS_REG))]
6589 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6590 "sbb{q}\t{%2, %0|%0, %2}"
6591 [(set_attr "type" "alu")
6592 (set_attr "pent_pair" "pu")
6593 (set_attr "mode" "DI")])
6595 (define_insn "*subdi_1_rex64"
6596 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6597 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6598 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6599 (clobber (reg:CC FLAGS_REG))]
6600 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
6601 "sub{q}\t{%2, %0|%0, %2}"
6602 [(set_attr "type" "alu")
6603 (set_attr "mode" "DI")])
6605 (define_insn "*subdi_2_rex64"
6606 [(set (reg FLAGS_REG)
6608 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
6609 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
6611 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6612 (minus:DI (match_dup 1) (match_dup 2)))]
6613 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6614 && 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_3_rex63"
6620 [(set (reg FLAGS_REG)
6621 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
6622 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6623 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6624 (minus:DI (match_dup 1) (match_dup 2)))]
6625 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6626 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6627 "sub{q}\t{%2, %0|%0, %2}"
6628 [(set_attr "type" "alu")
6629 (set_attr "mode" "DI")])
6631 (define_insn "subqi3_carry"
6632 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6633 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6634 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6635 (match_operand:QI 2 "general_operand" "qi,qm"))))
6636 (clobber (reg:CC FLAGS_REG))]
6637 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6638 "sbb{b}\t{%2, %0|%0, %2}"
6639 [(set_attr "type" "alu")
6640 (set_attr "pent_pair" "pu")
6641 (set_attr "mode" "QI")])
6643 (define_insn "subhi3_carry"
6644 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6645 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6646 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6647 (match_operand:HI 2 "general_operand" "ri,rm"))))
6648 (clobber (reg:CC FLAGS_REG))]
6649 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6650 "sbb{w}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "pent_pair" "pu")
6653 (set_attr "mode" "HI")])
6655 (define_insn "subsi3_carry"
6656 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6657 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6658 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6659 (match_operand:SI 2 "general_operand" "ri,rm"))))
6660 (clobber (reg:CC FLAGS_REG))]
6661 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6662 "sbb{l}\t{%2, %0|%0, %2}"
6663 [(set_attr "type" "alu")
6664 (set_attr "pent_pair" "pu")
6665 (set_attr "mode" "SI")])
6667 (define_insn "subsi3_carry_zext"
6668 [(set (match_operand:DI 0 "register_operand" "=rm,r")
6670 (minus:SI (match_operand:SI 1 "register_operand" "0,0")
6671 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6672 (match_operand:SI 2 "general_operand" "ri,rm")))))
6673 (clobber (reg:CC FLAGS_REG))]
6674 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6675 "sbb{l}\t{%2, %k0|%k0, %2}"
6676 [(set_attr "type" "alu")
6677 (set_attr "pent_pair" "pu")
6678 (set_attr "mode" "SI")])
6680 (define_expand "subsi3"
6681 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
6682 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6683 (match_operand:SI 2 "general_operand" "")))
6684 (clobber (reg:CC FLAGS_REG))])]
6686 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
6688 (define_insn "*subsi_1"
6689 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6690 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6691 (match_operand:SI 2 "general_operand" "ri,rm")))
6692 (clobber (reg:CC FLAGS_REG))]
6693 "ix86_binary_operator_ok (MINUS, SImode, operands)"
6694 "sub{l}\t{%2, %0|%0, %2}"
6695 [(set_attr "type" "alu")
6696 (set_attr "mode" "SI")])
6698 (define_insn "*subsi_1_zext"
6699 [(set (match_operand:DI 0 "register_operand" "=r")
6701 (minus:SI (match_operand:SI 1 "register_operand" "0")
6702 (match_operand:SI 2 "general_operand" "rim"))))
6703 (clobber (reg:CC FLAGS_REG))]
6704 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6705 "sub{l}\t{%2, %k0|%k0, %2}"
6706 [(set_attr "type" "alu")
6707 (set_attr "mode" "SI")])
6709 (define_insn "*subsi_2"
6710 [(set (reg FLAGS_REG)
6712 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
6713 (match_operand:SI 2 "general_operand" "ri,rm"))
6715 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6716 (minus:SI (match_dup 1) (match_dup 2)))]
6717 "ix86_match_ccmode (insn, CCGOCmode)
6718 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719 "sub{l}\t{%2, %0|%0, %2}"
6720 [(set_attr "type" "alu")
6721 (set_attr "mode" "SI")])
6723 (define_insn "*subsi_2_zext"
6724 [(set (reg FLAGS_REG)
6726 (minus:SI (match_operand:SI 1 "register_operand" "0")
6727 (match_operand:SI 2 "general_operand" "rim"))
6729 (set (match_operand:DI 0 "register_operand" "=r")
6731 (minus:SI (match_dup 1)
6733 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6734 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735 "sub{l}\t{%2, %k0|%k0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "mode" "SI")])
6739 (define_insn "*subsi_3"
6740 [(set (reg FLAGS_REG)
6741 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
6742 (match_operand:SI 2 "general_operand" "ri,rm")))
6743 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6744 (minus:SI (match_dup 1) (match_dup 2)))]
6745 "ix86_match_ccmode (insn, CCmode)
6746 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6747 "sub{l}\t{%2, %0|%0, %2}"
6748 [(set_attr "type" "alu")
6749 (set_attr "mode" "SI")])
6751 (define_insn "*subsi_3_zext"
6752 [(set (reg FLAGS_REG)
6753 (compare (match_operand:SI 1 "register_operand" "0")
6754 (match_operand:SI 2 "general_operand" "rim")))
6755 (set (match_operand:DI 0 "register_operand" "=r")
6757 (minus:SI (match_dup 1)
6759 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6760 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6761 "sub{l}\t{%2, %1|%1, %2}"
6762 [(set_attr "type" "alu")
6763 (set_attr "mode" "DI")])
6765 (define_expand "subhi3"
6766 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6767 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6768 (match_operand:HI 2 "general_operand" "")))
6769 (clobber (reg:CC FLAGS_REG))])]
6770 "TARGET_HIMODE_MATH"
6771 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
6773 (define_insn "*subhi_1"
6774 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6775 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6776 (match_operand:HI 2 "general_operand" "ri,rm")))
6777 (clobber (reg:CC FLAGS_REG))]
6778 "ix86_binary_operator_ok (MINUS, HImode, operands)"
6779 "sub{w}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "HI")])
6783 (define_insn "*subhi_2"
6784 [(set (reg FLAGS_REG)
6786 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
6787 (match_operand:HI 2 "general_operand" "ri,rm"))
6789 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6790 (minus:HI (match_dup 1) (match_dup 2)))]
6791 "ix86_match_ccmode (insn, CCGOCmode)
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_3"
6798 [(set (reg FLAGS_REG)
6799 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
6800 (match_operand:HI 2 "general_operand" "ri,rm")))
6801 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6802 (minus:HI (match_dup 1) (match_dup 2)))]
6803 "ix86_match_ccmode (insn, CCmode)
6804 && ix86_binary_operator_ok (MINUS, HImode, operands)"
6805 "sub{w}\t{%2, %0|%0, %2}"
6806 [(set_attr "type" "alu")
6807 (set_attr "mode" "HI")])
6809 (define_expand "subqi3"
6810 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6811 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6812 (match_operand:QI 2 "general_operand" "")))
6813 (clobber (reg:CC FLAGS_REG))])]
6814 "TARGET_QIMODE_MATH"
6815 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
6817 (define_insn "*subqi_1"
6818 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6819 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6820 (match_operand:QI 2 "general_operand" "qn,qmn")))
6821 (clobber (reg:CC FLAGS_REG))]
6822 "ix86_binary_operator_ok (MINUS, QImode, operands)"
6823 "sub{b}\t{%2, %0|%0, %2}"
6824 [(set_attr "type" "alu")
6825 (set_attr "mode" "QI")])
6827 (define_insn "*subqi_1_slp"
6828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6829 (minus:QI (match_dup 0)
6830 (match_operand:QI 1 "general_operand" "qn,qmn")))
6831 (clobber (reg:CC FLAGS_REG))]
6832 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6833 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
6834 "sub{b}\t{%1, %0|%0, %1}"
6835 [(set_attr "type" "alu1")
6836 (set_attr "mode" "QI")])
6838 (define_insn "*subqi_2"
6839 [(set (reg FLAGS_REG)
6841 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
6842 (match_operand:QI 2 "general_operand" "qi,qm"))
6844 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6845 (minus:HI (match_dup 1) (match_dup 2)))]
6846 "ix86_match_ccmode (insn, CCGOCmode)
6847 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6848 "sub{b}\t{%2, %0|%0, %2}"
6849 [(set_attr "type" "alu")
6850 (set_attr "mode" "QI")])
6852 (define_insn "*subqi_3"
6853 [(set (reg FLAGS_REG)
6854 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
6855 (match_operand:QI 2 "general_operand" "qi,qm")))
6856 (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
6857 (minus:HI (match_dup 1) (match_dup 2)))]
6858 "ix86_match_ccmode (insn, CCmode)
6859 && ix86_binary_operator_ok (MINUS, QImode, operands)"
6860 "sub{b}\t{%2, %0|%0, %2}"
6861 [(set_attr "type" "alu")
6862 (set_attr "mode" "QI")])
6864 ;; The patterns that match these are at the end of this file.
6866 (define_expand "subxf3"
6867 [(set (match_operand:XF 0 "register_operand" "")
6868 (minus:XF (match_operand:XF 1 "register_operand" "")
6869 (match_operand:XF 2 "register_operand" "")))]
6873 (define_expand "subdf3"
6874 [(set (match_operand:DF 0 "register_operand" "")
6875 (minus:DF (match_operand:DF 1 "register_operand" "")
6876 (match_operand:DF 2 "nonimmediate_operand" "")))]
6877 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
6880 (define_expand "subsf3"
6881 [(set (match_operand:SF 0 "register_operand" "")
6882 (minus:SF (match_operand:SF 1 "register_operand" "")
6883 (match_operand:SF 2 "nonimmediate_operand" "")))]
6884 "TARGET_80387 || TARGET_SSE_MATH"
6887 ;; Multiply instructions
6889 (define_expand "muldi3"
6890 [(parallel [(set (match_operand:DI 0 "register_operand" "")
6891 (mult:DI (match_operand:DI 1 "register_operand" "")
6892 (match_operand:DI 2 "x86_64_general_operand" "")))
6893 (clobber (reg:CC FLAGS_REG))])]
6897 (define_insn "*muldi3_1_rex64"
6898 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6899 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
6900 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
6901 (clobber (reg:CC FLAGS_REG))]
6903 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6905 imul{q}\t{%2, %1, %0|%0, %1, %2}
6906 imul{q}\t{%2, %1, %0|%0, %1, %2}
6907 imul{q}\t{%2, %0|%0, %2}"
6908 [(set_attr "type" "imul")
6909 (set_attr "prefix_0f" "0,0,1")
6910 (set (attr "athlon_decode")
6911 (cond [(eq_attr "cpu" "athlon")
6912 (const_string "vector")
6913 (eq_attr "alternative" "1")
6914 (const_string "vector")
6915 (and (eq_attr "alternative" "2")
6916 (match_operand 1 "memory_operand" ""))
6917 (const_string "vector")]
6918 (const_string "direct")))
6919 (set_attr "mode" "DI")])
6921 (define_expand "mulsi3"
6922 [(parallel [(set (match_operand:SI 0 "register_operand" "")
6923 (mult:SI (match_operand:SI 1 "register_operand" "")
6924 (match_operand:SI 2 "general_operand" "")))
6925 (clobber (reg:CC FLAGS_REG))])]
6929 (define_insn "*mulsi3_1"
6930 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
6931 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6932 (match_operand:SI 2 "general_operand" "K,i,mr")))
6933 (clobber (reg:CC FLAGS_REG))]
6934 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6936 imul{l}\t{%2, %1, %0|%0, %1, %2}
6937 imul{l}\t{%2, %1, %0|%0, %1, %2}
6938 imul{l}\t{%2, %0|%0, %2}"
6939 [(set_attr "type" "imul")
6940 (set_attr "prefix_0f" "0,0,1")
6941 (set (attr "athlon_decode")
6942 (cond [(eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (eq_attr "alternative" "1")
6945 (const_string "vector")
6946 (and (eq_attr "alternative" "2")
6947 (match_operand 1 "memory_operand" ""))
6948 (const_string "vector")]
6949 (const_string "direct")))
6950 (set_attr "mode" "SI")])
6952 (define_insn "*mulsi3_1_zext"
6953 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6955 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6956 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6957 (clobber (reg:CC FLAGS_REG))]
6959 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
6961 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6962 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6963 imul{l}\t{%2, %k0|%k0, %2}"
6964 [(set_attr "type" "imul")
6965 (set_attr "prefix_0f" "0,0,1")
6966 (set (attr "athlon_decode")
6967 (cond [(eq_attr "cpu" "athlon")
6968 (const_string "vector")
6969 (eq_attr "alternative" "1")
6970 (const_string "vector")
6971 (and (eq_attr "alternative" "2")
6972 (match_operand 1 "memory_operand" ""))
6973 (const_string "vector")]
6974 (const_string "direct")))
6975 (set_attr "mode" "SI")])
6977 (define_expand "mulhi3"
6978 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6979 (mult:HI (match_operand:HI 1 "register_operand" "")
6980 (match_operand:HI 2 "general_operand" "")))
6981 (clobber (reg:CC FLAGS_REG))])]
6982 "TARGET_HIMODE_MATH"
6985 (define_insn "*mulhi3_1"
6986 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6987 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6988 (match_operand:HI 2 "general_operand" "K,i,mr")))
6989 (clobber (reg:CC FLAGS_REG))]
6990 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
6992 imul{w}\t{%2, %1, %0|%0, %1, %2}
6993 imul{w}\t{%2, %1, %0|%0, %1, %2}
6994 imul{w}\t{%2, %0|%0, %2}"
6995 [(set_attr "type" "imul")
6996 (set_attr "prefix_0f" "0,0,1")
6997 (set (attr "athlon_decode")
6998 (cond [(eq_attr "cpu" "athlon")
6999 (const_string "vector")
7000 (eq_attr "alternative" "1,2")
7001 (const_string "vector")]
7002 (const_string "direct")))
7003 (set_attr "mode" "HI")])
7005 (define_expand "mulqi3"
7006 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7007 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7008 (match_operand:QI 2 "register_operand" "")))
7009 (clobber (reg:CC FLAGS_REG))])]
7010 "TARGET_QIMODE_MATH"
7013 (define_insn "*mulqi3_1"
7014 [(set (match_operand:QI 0 "register_operand" "=a")
7015 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7016 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7017 (clobber (reg:CC FLAGS_REG))]
7019 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7021 [(set_attr "type" "imul")
7022 (set_attr "length_immediate" "0")
7023 (set (attr "athlon_decode")
7024 (if_then_else (eq_attr "cpu" "athlon")
7025 (const_string "vector")
7026 (const_string "direct")))
7027 (set_attr "mode" "QI")])
7029 (define_expand "umulqihi3"
7030 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7031 (mult:HI (zero_extend:HI
7032 (match_operand:QI 1 "nonimmediate_operand" ""))
7034 (match_operand:QI 2 "register_operand" ""))))
7035 (clobber (reg:CC FLAGS_REG))])]
7036 "TARGET_QIMODE_MATH"
7039 (define_insn "*umulqihi3_1"
7040 [(set (match_operand:HI 0 "register_operand" "=a")
7041 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7042 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7043 (clobber (reg:CC FLAGS_REG))]
7045 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7047 [(set_attr "type" "imul")
7048 (set_attr "length_immediate" "0")
7049 (set (attr "athlon_decode")
7050 (if_then_else (eq_attr "cpu" "athlon")
7051 (const_string "vector")
7052 (const_string "direct")))
7053 (set_attr "mode" "QI")])
7055 (define_expand "mulqihi3"
7056 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7057 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7058 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7059 (clobber (reg:CC FLAGS_REG))])]
7060 "TARGET_QIMODE_MATH"
7063 (define_insn "*mulqihi3_insn"
7064 [(set (match_operand:HI 0 "register_operand" "=a")
7065 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7066 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7067 (clobber (reg:CC FLAGS_REG))]
7069 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7071 [(set_attr "type" "imul")
7072 (set_attr "length_immediate" "0")
7073 (set (attr "athlon_decode")
7074 (if_then_else (eq_attr "cpu" "athlon")
7075 (const_string "vector")
7076 (const_string "direct")))
7077 (set_attr "mode" "QI")])
7079 (define_expand "umulditi3"
7080 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7081 (mult:TI (zero_extend:TI
7082 (match_operand:DI 1 "nonimmediate_operand" ""))
7084 (match_operand:DI 2 "register_operand" ""))))
7085 (clobber (reg:CC FLAGS_REG))])]
7089 (define_insn "*umulditi3_insn"
7090 [(set (match_operand:TI 0 "register_operand" "=A")
7091 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7092 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7093 (clobber (reg:CC FLAGS_REG))]
7095 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7097 [(set_attr "type" "imul")
7098 (set_attr "length_immediate" "0")
7099 (set (attr "athlon_decode")
7100 (if_then_else (eq_attr "cpu" "athlon")
7101 (const_string "vector")
7102 (const_string "double")))
7103 (set_attr "mode" "DI")])
7105 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7106 (define_expand "umulsidi3"
7107 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7108 (mult:DI (zero_extend:DI
7109 (match_operand:SI 1 "nonimmediate_operand" ""))
7111 (match_operand:SI 2 "register_operand" ""))))
7112 (clobber (reg:CC FLAGS_REG))])]
7116 (define_insn "*umulsidi3_insn"
7117 [(set (match_operand:DI 0 "register_operand" "=A")
7118 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7119 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7120 (clobber (reg:CC FLAGS_REG))]
7122 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7124 [(set_attr "type" "imul")
7125 (set_attr "length_immediate" "0")
7126 (set (attr "athlon_decode")
7127 (if_then_else (eq_attr "cpu" "athlon")
7128 (const_string "vector")
7129 (const_string "double")))
7130 (set_attr "mode" "SI")])
7132 (define_expand "mulditi3"
7133 [(parallel [(set (match_operand:TI 0 "register_operand" "")
7134 (mult:TI (sign_extend:TI
7135 (match_operand:DI 1 "nonimmediate_operand" ""))
7137 (match_operand:DI 2 "register_operand" ""))))
7138 (clobber (reg:CC FLAGS_REG))])]
7142 (define_insn "*mulditi3_insn"
7143 [(set (match_operand:TI 0 "register_operand" "=A")
7144 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7145 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7146 (clobber (reg:CC FLAGS_REG))]
7148 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7150 [(set_attr "type" "imul")
7151 (set_attr "length_immediate" "0")
7152 (set (attr "athlon_decode")
7153 (if_then_else (eq_attr "cpu" "athlon")
7154 (const_string "vector")
7155 (const_string "double")))
7156 (set_attr "mode" "DI")])
7158 (define_expand "mulsidi3"
7159 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7160 (mult:DI (sign_extend:DI
7161 (match_operand:SI 1 "nonimmediate_operand" ""))
7163 (match_operand:SI 2 "register_operand" ""))))
7164 (clobber (reg:CC FLAGS_REG))])]
7168 (define_insn "*mulsidi3_insn"
7169 [(set (match_operand:DI 0 "register_operand" "=A")
7170 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7171 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7172 (clobber (reg:CC FLAGS_REG))]
7174 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7176 [(set_attr "type" "imul")
7177 (set_attr "length_immediate" "0")
7178 (set (attr "athlon_decode")
7179 (if_then_else (eq_attr "cpu" "athlon")
7180 (const_string "vector")
7181 (const_string "double")))
7182 (set_attr "mode" "SI")])
7184 (define_expand "umuldi3_highpart"
7185 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7188 (mult:TI (zero_extend:TI
7189 (match_operand:DI 1 "nonimmediate_operand" ""))
7191 (match_operand:DI 2 "register_operand" "")))
7193 (clobber (match_scratch:DI 3 ""))
7194 (clobber (reg:CC FLAGS_REG))])]
7198 (define_insn "*umuldi3_highpart_rex64"
7199 [(set (match_operand:DI 0 "register_operand" "=d")
7202 (mult:TI (zero_extend:TI
7203 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7205 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7207 (clobber (match_scratch:DI 3 "=1"))
7208 (clobber (reg:CC FLAGS_REG))]
7210 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7212 [(set_attr "type" "imul")
7213 (set_attr "length_immediate" "0")
7214 (set (attr "athlon_decode")
7215 (if_then_else (eq_attr "cpu" "athlon")
7216 (const_string "vector")
7217 (const_string "double")))
7218 (set_attr "mode" "DI")])
7220 (define_expand "umulsi3_highpart"
7221 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7224 (mult:DI (zero_extend:DI
7225 (match_operand:SI 1 "nonimmediate_operand" ""))
7227 (match_operand:SI 2 "register_operand" "")))
7229 (clobber (match_scratch:SI 3 ""))
7230 (clobber (reg:CC FLAGS_REG))])]
7234 (define_insn "*umulsi3_highpart_insn"
7235 [(set (match_operand:SI 0 "register_operand" "=d")
7238 (mult:DI (zero_extend:DI
7239 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7241 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7243 (clobber (match_scratch:SI 3 "=1"))
7244 (clobber (reg:CC FLAGS_REG))]
7245 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7247 [(set_attr "type" "imul")
7248 (set_attr "length_immediate" "0")
7249 (set (attr "athlon_decode")
7250 (if_then_else (eq_attr "cpu" "athlon")
7251 (const_string "vector")
7252 (const_string "double")))
7253 (set_attr "mode" "SI")])
7255 (define_insn "*umulsi3_highpart_zext"
7256 [(set (match_operand:DI 0 "register_operand" "=d")
7257 (zero_extend:DI (truncate:SI
7259 (mult:DI (zero_extend:DI
7260 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7262 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7264 (clobber (match_scratch:SI 3 "=1"))
7265 (clobber (reg:CC FLAGS_REG))]
7267 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7269 [(set_attr "type" "imul")
7270 (set_attr "length_immediate" "0")
7271 (set (attr "athlon_decode")
7272 (if_then_else (eq_attr "cpu" "athlon")
7273 (const_string "vector")
7274 (const_string "double")))
7275 (set_attr "mode" "SI")])
7277 (define_expand "smuldi3_highpart"
7278 [(parallel [(set (match_operand:DI 0 "register_operand" "=d")
7281 (mult:TI (sign_extend:TI
7282 (match_operand:DI 1 "nonimmediate_operand" ""))
7284 (match_operand:DI 2 "register_operand" "")))
7286 (clobber (match_scratch:DI 3 ""))
7287 (clobber (reg:CC FLAGS_REG))])]
7291 (define_insn "*smuldi3_highpart_rex64"
7292 [(set (match_operand:DI 0 "register_operand" "=d")
7295 (mult:TI (sign_extend:TI
7296 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7298 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7300 (clobber (match_scratch:DI 3 "=1"))
7301 (clobber (reg:CC FLAGS_REG))]
7303 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7305 [(set_attr "type" "imul")
7306 (set (attr "athlon_decode")
7307 (if_then_else (eq_attr "cpu" "athlon")
7308 (const_string "vector")
7309 (const_string "double")))
7310 (set_attr "mode" "DI")])
7312 (define_expand "smulsi3_highpart"
7313 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7316 (mult:DI (sign_extend:DI
7317 (match_operand:SI 1 "nonimmediate_operand" ""))
7319 (match_operand:SI 2 "register_operand" "")))
7321 (clobber (match_scratch:SI 3 ""))
7322 (clobber (reg:CC FLAGS_REG))])]
7326 (define_insn "*smulsi3_highpart_insn"
7327 [(set (match_operand:SI 0 "register_operand" "=d")
7330 (mult:DI (sign_extend:DI
7331 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7333 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7335 (clobber (match_scratch:SI 3 "=1"))
7336 (clobber (reg:CC FLAGS_REG))]
7337 "GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM"
7339 [(set_attr "type" "imul")
7340 (set (attr "athlon_decode")
7341 (if_then_else (eq_attr "cpu" "athlon")
7342 (const_string "vector")
7343 (const_string "double")))
7344 (set_attr "mode" "SI")])
7346 (define_insn "*smulsi3_highpart_zext"
7347 [(set (match_operand:DI 0 "register_operand" "=d")
7348 (zero_extend:DI (truncate:SI
7350 (mult:DI (sign_extend:DI
7351 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7353 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7355 (clobber (match_scratch:SI 3 "=1"))
7356 (clobber (reg:CC FLAGS_REG))]
7358 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
7360 [(set_attr "type" "imul")
7361 (set (attr "athlon_decode")
7362 (if_then_else (eq_attr "cpu" "athlon")
7363 (const_string "vector")
7364 (const_string "double")))
7365 (set_attr "mode" "SI")])
7367 ;; The patterns that match these are at the end of this file.
7369 (define_expand "mulxf3"
7370 [(set (match_operand:XF 0 "register_operand" "")
7371 (mult:XF (match_operand:XF 1 "register_operand" "")
7372 (match_operand:XF 2 "register_operand" "")))]
7376 (define_expand "muldf3"
7377 [(set (match_operand:DF 0 "register_operand" "")
7378 (mult:DF (match_operand:DF 1 "register_operand" "")
7379 (match_operand:DF 2 "nonimmediate_operand" "")))]
7380 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7383 (define_expand "mulsf3"
7384 [(set (match_operand:SF 0 "register_operand" "")
7385 (mult:SF (match_operand:SF 1 "register_operand" "")
7386 (match_operand:SF 2 "nonimmediate_operand" "")))]
7387 "TARGET_80387 || TARGET_SSE_MATH"
7390 ;; Divide instructions
7392 (define_insn "divqi3"
7393 [(set (match_operand:QI 0 "register_operand" "=a")
7394 (div:QI (match_operand:HI 1 "register_operand" "0")
7395 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7396 (clobber (reg:CC FLAGS_REG))]
7397 "TARGET_QIMODE_MATH"
7399 [(set_attr "type" "idiv")
7400 (set_attr "mode" "QI")])
7402 (define_insn "udivqi3"
7403 [(set (match_operand:QI 0 "register_operand" "=a")
7404 (udiv:QI (match_operand:HI 1 "register_operand" "0")
7405 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7406 (clobber (reg:CC FLAGS_REG))]
7407 "TARGET_QIMODE_MATH"
7409 [(set_attr "type" "idiv")
7410 (set_attr "mode" "QI")])
7412 ;; The patterns that match these are at the end of this file.
7414 (define_expand "divxf3"
7415 [(set (match_operand:XF 0 "register_operand" "")
7416 (div:XF (match_operand:XF 1 "register_operand" "")
7417 (match_operand:XF 2 "register_operand" "")))]
7421 (define_expand "divdf3"
7422 [(set (match_operand:DF 0 "register_operand" "")
7423 (div:DF (match_operand:DF 1 "register_operand" "")
7424 (match_operand:DF 2 "nonimmediate_operand" "")))]
7425 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7428 (define_expand "divsf3"
7429 [(set (match_operand:SF 0 "register_operand" "")
7430 (div:SF (match_operand:SF 1 "register_operand" "")
7431 (match_operand:SF 2 "nonimmediate_operand" "")))]
7432 "TARGET_80387 || TARGET_SSE_MATH"
7435 ;; Remainder instructions.
7437 (define_expand "divmoddi4"
7438 [(parallel [(set (match_operand:DI 0 "register_operand" "")
7439 (div:DI (match_operand:DI 1 "register_operand" "")
7440 (match_operand:DI 2 "nonimmediate_operand" "")))
7441 (set (match_operand:DI 3 "register_operand" "")
7442 (mod:DI (match_dup 1) (match_dup 2)))
7443 (clobber (reg:CC FLAGS_REG))])]
7447 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7448 ;; Penalize eax case slightly because it results in worse scheduling
7450 (define_insn "*divmoddi4_nocltd_rex64"
7451 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
7452 (div:DI (match_operand:DI 2 "register_operand" "1,0")
7453 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
7454 (set (match_operand:DI 1 "register_operand" "=&d,&d")
7455 (mod:DI (match_dup 2) (match_dup 3)))
7456 (clobber (reg:CC FLAGS_REG))]
7457 "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
7459 [(set_attr "type" "multi")])
7461 (define_insn "*divmoddi4_cltd_rex64"
7462 [(set (match_operand:DI 0 "register_operand" "=a")
7463 (div:DI (match_operand:DI 2 "register_operand" "a")
7464 (match_operand:DI 3 "nonimmediate_operand" "rm")))
7465 (set (match_operand:DI 1 "register_operand" "=&d")
7466 (mod:DI (match_dup 2) (match_dup 3)))
7467 (clobber (reg:CC FLAGS_REG))]
7468 "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
7470 [(set_attr "type" "multi")])
7472 (define_insn "*divmoddi_noext_rex64"
7473 [(set (match_operand:DI 0 "register_operand" "=a")
7474 (div:DI (match_operand:DI 1 "register_operand" "0")
7475 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7476 (set (match_operand:DI 3 "register_operand" "=d")
7477 (mod:DI (match_dup 1) (match_dup 2)))
7478 (use (match_operand:DI 4 "register_operand" "3"))
7479 (clobber (reg:CC FLAGS_REG))]
7482 [(set_attr "type" "idiv")
7483 (set_attr "mode" "DI")])
7486 [(set (match_operand:DI 0 "register_operand" "")
7487 (div:DI (match_operand:DI 1 "register_operand" "")
7488 (match_operand:DI 2 "nonimmediate_operand" "")))
7489 (set (match_operand:DI 3 "register_operand" "")
7490 (mod:DI (match_dup 1) (match_dup 2)))
7491 (clobber (reg:CC FLAGS_REG))]
7492 "TARGET_64BIT && reload_completed"
7493 [(parallel [(set (match_dup 3)
7494 (ashiftrt:DI (match_dup 4) (const_int 63)))
7495 (clobber (reg:CC FLAGS_REG))])
7496 (parallel [(set (match_dup 0)
7497 (div:DI (reg:DI 0) (match_dup 2)))
7499 (mod:DI (reg:DI 0) (match_dup 2)))
7501 (clobber (reg:CC FLAGS_REG))])]
7503 /* Avoid use of cltd in favor of a mov+shift. */
7504 if (!TARGET_USE_CLTD && !optimize_size)
7506 if (true_regnum (operands[1]))
7507 emit_move_insn (operands[0], operands[1]);
7509 emit_move_insn (operands[3], operands[1]);
7510 operands[4] = operands[3];
7514 gcc_assert (!true_regnum (operands[1]));
7515 operands[4] = operands[1];
7520 (define_expand "divmodsi4"
7521 [(parallel [(set (match_operand:SI 0 "register_operand" "")
7522 (div:SI (match_operand:SI 1 "register_operand" "")
7523 (match_operand:SI 2 "nonimmediate_operand" "")))
7524 (set (match_operand:SI 3 "register_operand" "")
7525 (mod:SI (match_dup 1) (match_dup 2)))
7526 (clobber (reg:CC FLAGS_REG))])]
7530 ;; Allow to come the parameter in eax or edx to avoid extra moves.
7531 ;; Penalize eax case slightly because it results in worse scheduling
7533 (define_insn "*divmodsi4_nocltd"
7534 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
7535 (div:SI (match_operand:SI 2 "register_operand" "1,0")
7536 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
7537 (set (match_operand:SI 1 "register_operand" "=&d,&d")
7538 (mod:SI (match_dup 2) (match_dup 3)))
7539 (clobber (reg:CC FLAGS_REG))]
7540 "!optimize_size && !TARGET_USE_CLTD"
7542 [(set_attr "type" "multi")])
7544 (define_insn "*divmodsi4_cltd"
7545 [(set (match_operand:SI 0 "register_operand" "=a")
7546 (div:SI (match_operand:SI 2 "register_operand" "a")
7547 (match_operand:SI 3 "nonimmediate_operand" "rm")))
7548 (set (match_operand:SI 1 "register_operand" "=&d")
7549 (mod:SI (match_dup 2) (match_dup 3)))
7550 (clobber (reg:CC FLAGS_REG))]
7551 "optimize_size || TARGET_USE_CLTD"
7553 [(set_attr "type" "multi")])
7555 (define_insn "*divmodsi_noext"
7556 [(set (match_operand:SI 0 "register_operand" "=a")
7557 (div:SI (match_operand:SI 1 "register_operand" "0")
7558 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7559 (set (match_operand:SI 3 "register_operand" "=d")
7560 (mod:SI (match_dup 1) (match_dup 2)))
7561 (use (match_operand:SI 4 "register_operand" "3"))
7562 (clobber (reg:CC FLAGS_REG))]
7565 [(set_attr "type" "idiv")
7566 (set_attr "mode" "SI")])
7569 [(set (match_operand:SI 0 "register_operand" "")
7570 (div:SI (match_operand:SI 1 "register_operand" "")
7571 (match_operand:SI 2 "nonimmediate_operand" "")))
7572 (set (match_operand:SI 3 "register_operand" "")
7573 (mod:SI (match_dup 1) (match_dup 2)))
7574 (clobber (reg:CC FLAGS_REG))]
7576 [(parallel [(set (match_dup 3)
7577 (ashiftrt:SI (match_dup 4) (const_int 31)))
7578 (clobber (reg:CC FLAGS_REG))])
7579 (parallel [(set (match_dup 0)
7580 (div:SI (reg:SI 0) (match_dup 2)))
7582 (mod:SI (reg:SI 0) (match_dup 2)))
7584 (clobber (reg:CC FLAGS_REG))])]
7586 /* Avoid use of cltd in favor of a mov+shift. */
7587 if (!TARGET_USE_CLTD && !optimize_size)
7589 if (true_regnum (operands[1]))
7590 emit_move_insn (operands[0], operands[1]);
7592 emit_move_insn (operands[3], operands[1]);
7593 operands[4] = operands[3];
7597 gcc_assert (!true_regnum (operands[1]));
7598 operands[4] = operands[1];
7602 (define_insn "divmodhi4"
7603 [(set (match_operand:HI 0 "register_operand" "=a")
7604 (div:HI (match_operand:HI 1 "register_operand" "0")
7605 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7606 (set (match_operand:HI 3 "register_operand" "=&d")
7607 (mod:HI (match_dup 1) (match_dup 2)))
7608 (clobber (reg:CC FLAGS_REG))]
7609 "TARGET_HIMODE_MATH"
7611 [(set_attr "type" "multi")
7612 (set_attr "length_immediate" "0")
7613 (set_attr "mode" "SI")])
7615 (define_insn "udivmoddi4"
7616 [(set (match_operand:DI 0 "register_operand" "=a")
7617 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7618 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7619 (set (match_operand:DI 3 "register_operand" "=&d")
7620 (umod:DI (match_dup 1) (match_dup 2)))
7621 (clobber (reg:CC FLAGS_REG))]
7623 "xor{q}\t%3, %3\;div{q}\t%2"
7624 [(set_attr "type" "multi")
7625 (set_attr "length_immediate" "0")
7626 (set_attr "mode" "DI")])
7628 (define_insn "*udivmoddi4_noext"
7629 [(set (match_operand:DI 0 "register_operand" "=a")
7630 (udiv:DI (match_operand:DI 1 "register_operand" "0")
7631 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7632 (set (match_operand:DI 3 "register_operand" "=d")
7633 (umod:DI (match_dup 1) (match_dup 2)))
7635 (clobber (reg:CC FLAGS_REG))]
7638 [(set_attr "type" "idiv")
7639 (set_attr "mode" "DI")])
7642 [(set (match_operand:DI 0 "register_operand" "")
7643 (udiv:DI (match_operand:DI 1 "register_operand" "")
7644 (match_operand:DI 2 "nonimmediate_operand" "")))
7645 (set (match_operand:DI 3 "register_operand" "")
7646 (umod:DI (match_dup 1) (match_dup 2)))
7647 (clobber (reg:CC FLAGS_REG))]
7648 "TARGET_64BIT && reload_completed"
7649 [(set (match_dup 3) (const_int 0))
7650 (parallel [(set (match_dup 0)
7651 (udiv:DI (match_dup 1) (match_dup 2)))
7653 (umod:DI (match_dup 1) (match_dup 2)))
7655 (clobber (reg:CC FLAGS_REG))])]
7658 (define_insn "udivmodsi4"
7659 [(set (match_operand:SI 0 "register_operand" "=a")
7660 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7661 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7662 (set (match_operand:SI 3 "register_operand" "=&d")
7663 (umod:SI (match_dup 1) (match_dup 2)))
7664 (clobber (reg:CC FLAGS_REG))]
7666 "xor{l}\t%3, %3\;div{l}\t%2"
7667 [(set_attr "type" "multi")
7668 (set_attr "length_immediate" "0")
7669 (set_attr "mode" "SI")])
7671 (define_insn "*udivmodsi4_noext"
7672 [(set (match_operand:SI 0 "register_operand" "=a")
7673 (udiv:SI (match_operand:SI 1 "register_operand" "0")
7674 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7675 (set (match_operand:SI 3 "register_operand" "=d")
7676 (umod:SI (match_dup 1) (match_dup 2)))
7678 (clobber (reg:CC FLAGS_REG))]
7681 [(set_attr "type" "idiv")
7682 (set_attr "mode" "SI")])
7685 [(set (match_operand:SI 0 "register_operand" "")
7686 (udiv:SI (match_operand:SI 1 "register_operand" "")
7687 (match_operand:SI 2 "nonimmediate_operand" "")))
7688 (set (match_operand:SI 3 "register_operand" "")
7689 (umod:SI (match_dup 1) (match_dup 2)))
7690 (clobber (reg:CC FLAGS_REG))]
7692 [(set (match_dup 3) (const_int 0))
7693 (parallel [(set (match_dup 0)
7694 (udiv:SI (match_dup 1) (match_dup 2)))
7696 (umod:SI (match_dup 1) (match_dup 2)))
7698 (clobber (reg:CC FLAGS_REG))])]
7701 (define_expand "udivmodhi4"
7702 [(set (match_dup 4) (const_int 0))
7703 (parallel [(set (match_operand:HI 0 "register_operand" "")
7704 (udiv:HI (match_operand:HI 1 "register_operand" "")
7705 (match_operand:HI 2 "nonimmediate_operand" "")))
7706 (set (match_operand:HI 3 "register_operand" "")
7707 (umod:HI (match_dup 1) (match_dup 2)))
7709 (clobber (reg:CC FLAGS_REG))])]
7710 "TARGET_HIMODE_MATH"
7711 "operands[4] = gen_reg_rtx (HImode);")
7713 (define_insn "*udivmodhi_noext"
7714 [(set (match_operand:HI 0 "register_operand" "=a")
7715 (udiv:HI (match_operand:HI 1 "register_operand" "0")
7716 (match_operand:HI 2 "nonimmediate_operand" "rm")))
7717 (set (match_operand:HI 3 "register_operand" "=d")
7718 (umod:HI (match_dup 1) (match_dup 2)))
7719 (use (match_operand:HI 4 "register_operand" "3"))
7720 (clobber (reg:CC FLAGS_REG))]
7723 [(set_attr "type" "idiv")
7724 (set_attr "mode" "HI")])
7726 ;; We cannot use div/idiv for double division, because it causes
7727 ;; "division by zero" on the overflow and that's not what we expect
7728 ;; from truncate. Because true (non truncating) double division is
7729 ;; never generated, we can't create this insn anyway.
7732 ; [(set (match_operand:SI 0 "register_operand" "=a")
7734 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7736 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7737 ; (set (match_operand:SI 3 "register_operand" "=d")
7739 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7740 ; (clobber (reg:CC FLAGS_REG))]
7742 ; "div{l}\t{%2, %0|%0, %2}"
7743 ; [(set_attr "type" "idiv")])
7745 ;;- Logical AND instructions
7747 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7748 ;; Note that this excludes ah.
7750 (define_insn "*testdi_1_rex64"
7751 [(set (reg FLAGS_REG)
7753 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7754 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7756 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7757 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7759 test{l}\t{%k1, %k0|%k0, %k1}
7760 test{l}\t{%k1, %k0|%k0, %k1}
7761 test{q}\t{%1, %0|%0, %1}
7762 test{q}\t{%1, %0|%0, %1}
7763 test{q}\t{%1, %0|%0, %1}"
7764 [(set_attr "type" "test")
7765 (set_attr "modrm" "0,1,0,1,1")
7766 (set_attr "mode" "SI,SI,DI,DI,DI")
7767 (set_attr "pent_pair" "uv,np,uv,np,uv")])
7769 (define_insn "testsi_1"
7770 [(set (reg FLAGS_REG)
7772 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
7773 (match_operand:SI 1 "general_operand" "in,in,rin"))
7775 "ix86_match_ccmode (insn, CCNOmode)
7776 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7777 "test{l}\t{%1, %0|%0, %1}"
7778 [(set_attr "type" "test")
7779 (set_attr "modrm" "0,1,1")
7780 (set_attr "mode" "SI")
7781 (set_attr "pent_pair" "uv,np,uv")])
7783 (define_expand "testsi_ccno_1"
7784 [(set (reg:CCNO FLAGS_REG)
7786 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7787 (match_operand:SI 1 "nonmemory_operand" ""))
7792 (define_insn "*testhi_1"
7793 [(set (reg FLAGS_REG)
7794 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
7795 (match_operand:HI 1 "general_operand" "n,n,rn"))
7797 "ix86_match_ccmode (insn, CCNOmode)
7798 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7799 "test{w}\t{%1, %0|%0, %1}"
7800 [(set_attr "type" "test")
7801 (set_attr "modrm" "0,1,1")
7802 (set_attr "mode" "HI")
7803 (set_attr "pent_pair" "uv,np,uv")])
7805 (define_expand "testqi_ccz_1"
7806 [(set (reg:CCZ FLAGS_REG)
7807 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7808 (match_operand:QI 1 "nonmemory_operand" ""))
7813 (define_insn "*testqi_1_maybe_si"
7814 [(set (reg FLAGS_REG)
7817 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7818 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7820 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7821 && ix86_match_ccmode (insn,
7822 GET_CODE (operands[1]) == CONST_INT
7823 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7825 if (which_alternative == 3)
7827 if (GET_CODE (operands[1]) == CONST_INT && INTVAL (operands[1]) < 0)
7828 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7829 return "test{l}\t{%1, %k0|%k0, %1}";
7831 return "test{b}\t{%1, %0|%0, %1}";
7833 [(set_attr "type" "test")
7834 (set_attr "modrm" "0,1,1,1")
7835 (set_attr "mode" "QI,QI,QI,SI")
7836 (set_attr "pent_pair" "uv,np,uv,np")])
7838 (define_insn "*testqi_1"
7839 [(set (reg FLAGS_REG)
7842 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
7843 (match_operand:QI 1 "general_operand" "n,n,qn"))
7845 "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
7846 && ix86_match_ccmode (insn, CCNOmode)"
7847 "test{b}\t{%1, %0|%0, %1}"
7848 [(set_attr "type" "test")
7849 (set_attr "modrm" "0,1,1")
7850 (set_attr "mode" "QI")
7851 (set_attr "pent_pair" "uv,np,uv")])
7853 (define_expand "testqi_ext_ccno_0"
7854 [(set (reg:CCNO FLAGS_REG)
7858 (match_operand 0 "ext_register_operand" "")
7861 (match_operand 1 "const_int_operand" ""))
7866 (define_insn "*testqi_ext_0"
7867 [(set (reg FLAGS_REG)
7871 (match_operand 0 "ext_register_operand" "Q")
7874 (match_operand 1 "const_int_operand" "n"))
7876 "ix86_match_ccmode (insn, CCNOmode)"
7877 "test{b}\t{%1, %h0|%h0, %1}"
7878 [(set_attr "type" "test")
7879 (set_attr "mode" "QI")
7880 (set_attr "length_immediate" "1")
7881 (set_attr "pent_pair" "np")])
7883 (define_insn "*testqi_ext_1"
7884 [(set (reg FLAGS_REG)
7888 (match_operand 0 "ext_register_operand" "Q")
7892 (match_operand:QI 1 "general_operand" "Qm")))
7894 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7895 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
7896 "test{b}\t{%1, %h0|%h0, %1}"
7897 [(set_attr "type" "test")
7898 (set_attr "mode" "QI")])
7900 (define_insn "*testqi_ext_1_rex64"
7901 [(set (reg FLAGS_REG)
7905 (match_operand 0 "ext_register_operand" "Q")
7909 (match_operand:QI 1 "register_operand" "Q")))
7911 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7912 "test{b}\t{%1, %h0|%h0, %1}"
7913 [(set_attr "type" "test")
7914 (set_attr "mode" "QI")])
7916 (define_insn "*testqi_ext_2"
7917 [(set (reg FLAGS_REG)
7921 (match_operand 0 "ext_register_operand" "Q")
7925 (match_operand 1 "ext_register_operand" "Q")
7929 "ix86_match_ccmode (insn, CCNOmode)"
7930 "test{b}\t{%h1, %h0|%h0, %h1}"
7931 [(set_attr "type" "test")
7932 (set_attr "mode" "QI")])
7934 ;; Combine likes to form bit extractions for some tests. Humor it.
7935 (define_insn "*testqi_ext_3"
7936 [(set (reg FLAGS_REG)
7937 (compare (zero_extract:SI
7938 (match_operand 0 "nonimmediate_operand" "rm")
7939 (match_operand:SI 1 "const_int_operand" "")
7940 (match_operand:SI 2 "const_int_operand" ""))
7942 "ix86_match_ccmode (insn, CCNOmode)
7943 && INTVAL (operands[1]) > 0
7944 && INTVAL (operands[2]) >= 0
7945 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7946 && (GET_MODE (operands[0]) == SImode
7947 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7948 || GET_MODE (operands[0]) == HImode
7949 || GET_MODE (operands[0]) == QImode)"
7952 (define_insn "*testqi_ext_3_rex64"
7953 [(set (reg FLAGS_REG)
7954 (compare (zero_extract:DI
7955 (match_operand 0 "nonimmediate_operand" "rm")
7956 (match_operand:DI 1 "const_int_operand" "")
7957 (match_operand:DI 2 "const_int_operand" ""))
7960 && ix86_match_ccmode (insn, CCNOmode)
7961 && INTVAL (operands[1]) > 0
7962 && INTVAL (operands[2]) >= 0
7963 /* Ensure that resulting mask is zero or sign extended operand. */
7964 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7965 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7966 && INTVAL (operands[1]) > 32))
7967 && (GET_MODE (operands[0]) == SImode
7968 || GET_MODE (operands[0]) == DImode
7969 || GET_MODE (operands[0]) == HImode
7970 || GET_MODE (operands[0]) == QImode)"
7974 [(set (match_operand 0 "flags_reg_operand" "")
7975 (match_operator 1 "compare_operator"
7977 (match_operand 2 "nonimmediate_operand" "")
7978 (match_operand 3 "const_int_operand" "")
7979 (match_operand 4 "const_int_operand" ""))
7981 "ix86_match_ccmode (insn, CCNOmode)"
7982 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7984 rtx val = operands[2];
7985 HOST_WIDE_INT len = INTVAL (operands[3]);
7986 HOST_WIDE_INT pos = INTVAL (operands[4]);
7988 enum machine_mode mode, submode;
7990 mode = GET_MODE (val);
7991 if (GET_CODE (val) == MEM)
7993 /* ??? Combine likes to put non-volatile mem extractions in QImode
7994 no matter the size of the test. So find a mode that works. */
7995 if (! MEM_VOLATILE_P (val))
7997 mode = smallest_mode_for_size (pos + len, MODE_INT);
7998 val = adjust_address (val, mode, 0);
8001 else if (GET_CODE (val) == SUBREG
8002 && (submode = GET_MODE (SUBREG_REG (val)),
8003 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8004 && pos + len <= GET_MODE_BITSIZE (submode))
8006 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8008 val = SUBREG_REG (val);
8010 else if (mode == HImode && pos + len <= 8)
8012 /* Small HImode tests can be converted to QImode. */
8014 val = gen_lowpart (QImode, val);
8017 if (len == HOST_BITS_PER_WIDE_INT)
8020 mask = ((HOST_WIDE_INT)1 << len) - 1;
8023 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8026 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8027 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8028 ;; this is relatively important trick.
8029 ;; Do the conversion only post-reload to avoid limiting of the register class
8032 [(set (match_operand 0 "flags_reg_operand" "")
8033 (match_operator 1 "compare_operator"
8034 [(and (match_operand 2 "register_operand" "")
8035 (match_operand 3 "const_int_operand" ""))
8038 && QI_REG_P (operands[2])
8039 && GET_MODE (operands[2]) != QImode
8040 && ((ix86_match_ccmode (insn, CCZmode)
8041 && !(INTVAL (operands[3]) & ~(255 << 8)))
8042 || (ix86_match_ccmode (insn, CCNOmode)
8043 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8046 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8049 "operands[2] = gen_lowpart (SImode, operands[2]);
8050 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8053 [(set (match_operand 0 "flags_reg_operand" "")
8054 (match_operator 1 "compare_operator"
8055 [(and (match_operand 2 "nonimmediate_operand" "")
8056 (match_operand 3 "const_int_operand" ""))
8059 && GET_MODE (operands[2]) != QImode
8060 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8061 && ((ix86_match_ccmode (insn, CCZmode)
8062 && !(INTVAL (operands[3]) & ~255))
8063 || (ix86_match_ccmode (insn, CCNOmode)
8064 && !(INTVAL (operands[3]) & ~127)))"
8066 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8068 "operands[2] = gen_lowpart (QImode, operands[2]);
8069 operands[3] = gen_lowpart (QImode, operands[3]);")
8072 ;; %%% This used to optimize known byte-wide and operations to memory,
8073 ;; and sometimes to QImode registers. If this is considered useful,
8074 ;; it should be done with splitters.
8076 (define_expand "anddi3"
8077 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8078 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8079 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8080 (clobber (reg:CC FLAGS_REG))]
8082 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8084 (define_insn "*anddi_1_rex64"
8085 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8086 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8087 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8088 (clobber (reg:CC FLAGS_REG))]
8089 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8091 switch (get_attr_type (insn))
8095 enum machine_mode mode;
8097 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8098 if (INTVAL (operands[2]) == 0xff)
8102 gcc_assert (INTVAL (operands[2]) == 0xffff);
8106 operands[1] = gen_lowpart (mode, operands[1]);
8108 return "movz{bq|x}\t{%1,%0|%0, %1}";
8110 return "movz{wq|x}\t{%1,%0|%0, %1}";
8114 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8115 if (get_attr_mode (insn) == MODE_SI)
8116 return "and{l}\t{%k2, %k0|%k0, %k2}";
8118 return "and{q}\t{%2, %0|%0, %2}";
8121 [(set_attr "type" "alu,alu,alu,imovx")
8122 (set_attr "length_immediate" "*,*,*,0")
8123 (set_attr "mode" "SI,DI,DI,DI")])
8125 (define_insn "*anddi_2"
8126 [(set (reg FLAGS_REG)
8127 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8128 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8130 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8131 (and:DI (match_dup 1) (match_dup 2)))]
8132 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8133 && ix86_binary_operator_ok (AND, DImode, operands)"
8135 and{l}\t{%k2, %k0|%k0, %k2}
8136 and{q}\t{%2, %0|%0, %2}
8137 and{q}\t{%2, %0|%0, %2}"
8138 [(set_attr "type" "alu")
8139 (set_attr "mode" "SI,DI,DI")])
8141 (define_expand "andsi3"
8142 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8143 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8144 (match_operand:SI 2 "general_operand" "")))
8145 (clobber (reg:CC FLAGS_REG))]
8147 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8149 (define_insn "*andsi_1"
8150 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8151 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8152 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8153 (clobber (reg:CC FLAGS_REG))]
8154 "ix86_binary_operator_ok (AND, SImode, operands)"
8156 switch (get_attr_type (insn))
8160 enum machine_mode mode;
8162 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8163 if (INTVAL (operands[2]) == 0xff)
8167 gcc_assert (INTVAL (operands[2]) == 0xffff);
8171 operands[1] = gen_lowpart (mode, operands[1]);
8173 return "movz{bl|x}\t{%1,%0|%0, %1}";
8175 return "movz{wl|x}\t{%1,%0|%0, %1}";
8179 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8180 return "and{l}\t{%2, %0|%0, %2}";
8183 [(set_attr "type" "alu,alu,imovx")
8184 (set_attr "length_immediate" "*,*,0")
8185 (set_attr "mode" "SI")])
8188 [(set (match_operand 0 "register_operand" "")
8190 (const_int -65536)))
8191 (clobber (reg:CC FLAGS_REG))]
8192 "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8193 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8194 "operands[1] = gen_lowpart (HImode, operands[0]);")
8197 [(set (match_operand 0 "ext_register_operand" "")
8200 (clobber (reg:CC FLAGS_REG))]
8201 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8202 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8203 "operands[1] = gen_lowpart (QImode, operands[0]);")
8206 [(set (match_operand 0 "ext_register_operand" "")
8208 (const_int -65281)))
8209 (clobber (reg:CC FLAGS_REG))]
8210 "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8211 [(parallel [(set (zero_extract:SI (match_dup 0)
8215 (zero_extract:SI (match_dup 0)
8218 (zero_extract:SI (match_dup 0)
8221 (clobber (reg:CC FLAGS_REG))])]
8222 "operands[0] = gen_lowpart (SImode, operands[0]);")
8224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8225 (define_insn "*andsi_1_zext"
8226 [(set (match_operand:DI 0 "register_operand" "=r")
8228 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8229 (match_operand:SI 2 "general_operand" "rim"))))
8230 (clobber (reg:CC FLAGS_REG))]
8231 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8232 "and{l}\t{%2, %k0|%k0, %2}"
8233 [(set_attr "type" "alu")
8234 (set_attr "mode" "SI")])
8236 (define_insn "*andsi_2"
8237 [(set (reg FLAGS_REG)
8238 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8239 (match_operand:SI 2 "general_operand" "rim,ri"))
8241 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8242 (and:SI (match_dup 1) (match_dup 2)))]
8243 "ix86_match_ccmode (insn, CCNOmode)
8244 && ix86_binary_operator_ok (AND, SImode, operands)"
8245 "and{l}\t{%2, %0|%0, %2}"
8246 [(set_attr "type" "alu")
8247 (set_attr "mode" "SI")])
8249 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8250 (define_insn "*andsi_2_zext"
8251 [(set (reg FLAGS_REG)
8252 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8253 (match_operand:SI 2 "general_operand" "rim"))
8255 (set (match_operand:DI 0 "register_operand" "=r")
8256 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8257 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8258 && ix86_binary_operator_ok (AND, SImode, operands)"
8259 "and{l}\t{%2, %k0|%k0, %2}"
8260 [(set_attr "type" "alu")
8261 (set_attr "mode" "SI")])
8263 (define_expand "andhi3"
8264 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8265 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8266 (match_operand:HI 2 "general_operand" "")))
8267 (clobber (reg:CC FLAGS_REG))]
8268 "TARGET_HIMODE_MATH"
8269 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8271 (define_insn "*andhi_1"
8272 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8273 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8274 (match_operand:HI 2 "general_operand" "ri,rm,L")))
8275 (clobber (reg:CC FLAGS_REG))]
8276 "ix86_binary_operator_ok (AND, HImode, operands)"
8278 switch (get_attr_type (insn))
8281 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
8282 gcc_assert (INTVAL (operands[2]) == 0xff);
8283 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8286 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8288 return "and{w}\t{%2, %0|%0, %2}";
8291 [(set_attr "type" "alu,alu,imovx")
8292 (set_attr "length_immediate" "*,*,0")
8293 (set_attr "mode" "HI,HI,SI")])
8295 (define_insn "*andhi_2"
8296 [(set (reg FLAGS_REG)
8297 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8298 (match_operand:HI 2 "general_operand" "rim,ri"))
8300 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8301 (and:HI (match_dup 1) (match_dup 2)))]
8302 "ix86_match_ccmode (insn, CCNOmode)
8303 && ix86_binary_operator_ok (AND, HImode, operands)"
8304 "and{w}\t{%2, %0|%0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "HI")])
8308 (define_expand "andqi3"
8309 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8310 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8311 (match_operand:QI 2 "general_operand" "")))
8312 (clobber (reg:CC FLAGS_REG))]
8313 "TARGET_QIMODE_MATH"
8314 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8316 ;; %%% Potential partial reg stall on alternative 2. What to do?
8317 (define_insn "*andqi_1"
8318 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8319 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8320 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
8321 (clobber (reg:CC FLAGS_REG))]
8322 "ix86_binary_operator_ok (AND, QImode, operands)"
8324 and{b}\t{%2, %0|%0, %2}
8325 and{b}\t{%2, %0|%0, %2}
8326 and{l}\t{%k2, %k0|%k0, %k2}"
8327 [(set_attr "type" "alu")
8328 (set_attr "mode" "QI,QI,SI")])
8330 (define_insn "*andqi_1_slp"
8331 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8332 (and:QI (match_dup 0)
8333 (match_operand:QI 1 "general_operand" "qi,qmi")))
8334 (clobber (reg:CC FLAGS_REG))]
8335 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8336 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8337 "and{b}\t{%1, %0|%0, %1}"
8338 [(set_attr "type" "alu1")
8339 (set_attr "mode" "QI")])
8341 (define_insn "*andqi_2_maybe_si"
8342 [(set (reg FLAGS_REG)
8344 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8345 (match_operand:QI 2 "general_operand" "qim,qi,i"))
8347 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8348 (and:QI (match_dup 1) (match_dup 2)))]
8349 "ix86_binary_operator_ok (AND, QImode, operands)
8350 && ix86_match_ccmode (insn,
8351 GET_CODE (operands[2]) == CONST_INT
8352 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8354 if (which_alternative == 2)
8356 if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
8357 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8358 return "and{l}\t{%2, %k0|%k0, %2}";
8360 return "and{b}\t{%2, %0|%0, %2}";
8362 [(set_attr "type" "alu")
8363 (set_attr "mode" "QI,QI,SI")])
8365 (define_insn "*andqi_2"
8366 [(set (reg FLAGS_REG)
8368 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8369 (match_operand:QI 2 "general_operand" "qim,qi"))
8371 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8372 (and:QI (match_dup 1) (match_dup 2)))]
8373 "ix86_match_ccmode (insn, CCNOmode)
8374 && ix86_binary_operator_ok (AND, QImode, operands)"
8375 "and{b}\t{%2, %0|%0, %2}"
8376 [(set_attr "type" "alu")
8377 (set_attr "mode" "QI")])
8379 (define_insn "*andqi_2_slp"
8380 [(set (reg FLAGS_REG)
8382 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8383 (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
8385 (set (strict_low_part (match_dup 0))
8386 (and:QI (match_dup 0) (match_dup 1)))]
8387 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8388 && ix86_match_ccmode (insn, CCNOmode)
8389 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8390 "and{b}\t{%1, %0|%0, %1}"
8391 [(set_attr "type" "alu1")
8392 (set_attr "mode" "QI")])
8394 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8395 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8396 ;; for a QImode operand, which of course failed.
8398 (define_insn "andqi_ext_0"
8399 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8404 (match_operand 1 "ext_register_operand" "0")
8407 (match_operand 2 "const_int_operand" "n")))
8408 (clobber (reg:CC FLAGS_REG))]
8410 "and{b}\t{%2, %h0|%h0, %2}"
8411 [(set_attr "type" "alu")
8412 (set_attr "length_immediate" "1")
8413 (set_attr "mode" "QI")])
8415 ;; Generated by peephole translating test to and. This shows up
8416 ;; often in fp comparisons.
8418 (define_insn "*andqi_ext_0_cc"
8419 [(set (reg FLAGS_REG)
8423 (match_operand 1 "ext_register_operand" "0")
8426 (match_operand 2 "const_int_operand" "n"))
8428 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8437 "ix86_match_ccmode (insn, CCNOmode)"
8438 "and{b}\t{%2, %h0|%h0, %2}"
8439 [(set_attr "type" "alu")
8440 (set_attr "length_immediate" "1")
8441 (set_attr "mode" "QI")])
8443 (define_insn "*andqi_ext_1"
8444 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8449 (match_operand 1 "ext_register_operand" "0")
8453 (match_operand:QI 2 "general_operand" "Qm"))))
8454 (clobber (reg:CC FLAGS_REG))]
8456 "and{b}\t{%2, %h0|%h0, %2}"
8457 [(set_attr "type" "alu")
8458 (set_attr "length_immediate" "0")
8459 (set_attr "mode" "QI")])
8461 (define_insn "*andqi_ext_1_rex64"
8462 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8467 (match_operand 1 "ext_register_operand" "0")
8471 (match_operand 2 "ext_register_operand" "Q"))))
8472 (clobber (reg:CC FLAGS_REG))]
8474 "and{b}\t{%2, %h0|%h0, %2}"
8475 [(set_attr "type" "alu")
8476 (set_attr "length_immediate" "0")
8477 (set_attr "mode" "QI")])
8479 (define_insn "*andqi_ext_2"
8480 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8485 (match_operand 1 "ext_register_operand" "%0")
8489 (match_operand 2 "ext_register_operand" "Q")
8492 (clobber (reg:CC FLAGS_REG))]
8494 "and{b}\t{%h2, %h0|%h0, %h2}"
8495 [(set_attr "type" "alu")
8496 (set_attr "length_immediate" "0")
8497 (set_attr "mode" "QI")])
8499 ;; Convert wide AND instructions with immediate operand to shorter QImode
8500 ;; equivalents when possible.
8501 ;; Don't do the splitting with memory operands, since it introduces risk
8502 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8503 ;; for size, but that can (should?) be handled by generic code instead.
8505 [(set (match_operand 0 "register_operand" "")
8506 (and (match_operand 1 "register_operand" "")
8507 (match_operand 2 "const_int_operand" "")))
8508 (clobber (reg:CC FLAGS_REG))]
8510 && QI_REG_P (operands[0])
8511 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8512 && !(~INTVAL (operands[2]) & ~(255 << 8))
8513 && GET_MODE (operands[0]) != QImode"
8514 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8515 (and:SI (zero_extract:SI (match_dup 1)
8516 (const_int 8) (const_int 8))
8518 (clobber (reg:CC FLAGS_REG))])]
8519 "operands[0] = gen_lowpart (SImode, operands[0]);
8520 operands[1] = gen_lowpart (SImode, operands[1]);
8521 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8523 ;; Since AND can be encoded with sign extended immediate, this is only
8524 ;; profitable when 7th bit is not set.
8526 [(set (match_operand 0 "register_operand" "")
8527 (and (match_operand 1 "general_operand" "")
8528 (match_operand 2 "const_int_operand" "")))
8529 (clobber (reg:CC FLAGS_REG))]
8531 && ANY_QI_REG_P (operands[0])
8532 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8533 && !(~INTVAL (operands[2]) & ~255)
8534 && !(INTVAL (operands[2]) & 128)
8535 && GET_MODE (operands[0]) != QImode"
8536 [(parallel [(set (strict_low_part (match_dup 0))
8537 (and:QI (match_dup 1)
8539 (clobber (reg:CC FLAGS_REG))])]
8540 "operands[0] = gen_lowpart (QImode, operands[0]);
8541 operands[1] = gen_lowpart (QImode, operands[1]);
8542 operands[2] = gen_lowpart (QImode, operands[2]);")
8544 ;; Logical inclusive OR instructions
8546 ;; %%% This used to optimize known byte-wide and operations to memory.
8547 ;; If this is considered useful, it should be done with splitters.
8549 (define_expand "iordi3"
8550 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8551 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8552 (match_operand:DI 2 "x86_64_general_operand" "")))
8553 (clobber (reg:CC FLAGS_REG))]
8555 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8557 (define_insn "*iordi_1_rex64"
8558 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8559 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8560 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8561 (clobber (reg:CC FLAGS_REG))]
8563 && ix86_binary_operator_ok (IOR, DImode, operands)"
8564 "or{q}\t{%2, %0|%0, %2}"
8565 [(set_attr "type" "alu")
8566 (set_attr "mode" "DI")])
8568 (define_insn "*iordi_2_rex64"
8569 [(set (reg FLAGS_REG)
8570 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8571 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8573 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8574 (ior:DI (match_dup 1) (match_dup 2)))]
8576 && ix86_match_ccmode (insn, CCNOmode)
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_3_rex64"
8583 [(set (reg FLAGS_REG)
8584 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8585 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8587 (clobber (match_scratch:DI 0 "=r"))]
8589 && ix86_match_ccmode (insn, CCNOmode)
8590 && ix86_binary_operator_ok (IOR, DImode, operands)"
8591 "or{q}\t{%2, %0|%0, %2}"
8592 [(set_attr "type" "alu")
8593 (set_attr "mode" "DI")])
8596 (define_expand "iorsi3"
8597 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8598 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8599 (match_operand:SI 2 "general_operand" "")))
8600 (clobber (reg:CC FLAGS_REG))]
8602 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8604 (define_insn "*iorsi_1"
8605 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8606 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8607 (match_operand:SI 2 "general_operand" "ri,rmi")))
8608 (clobber (reg:CC FLAGS_REG))]
8609 "ix86_binary_operator_ok (IOR, SImode, operands)"
8610 "or{l}\t{%2, %0|%0, %2}"
8611 [(set_attr "type" "alu")
8612 (set_attr "mode" "SI")])
8614 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8615 (define_insn "*iorsi_1_zext"
8616 [(set (match_operand:DI 0 "register_operand" "=rm")
8618 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8619 (match_operand:SI 2 "general_operand" "rim"))))
8620 (clobber (reg:CC FLAGS_REG))]
8621 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8622 "or{l}\t{%2, %k0|%k0, %2}"
8623 [(set_attr "type" "alu")
8624 (set_attr "mode" "SI")])
8626 (define_insn "*iorsi_1_zext_imm"
8627 [(set (match_operand:DI 0 "register_operand" "=rm")
8628 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8629 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8630 (clobber (reg:CC FLAGS_REG))]
8632 "or{l}\t{%2, %k0|%k0, %2}"
8633 [(set_attr "type" "alu")
8634 (set_attr "mode" "SI")])
8636 (define_insn "*iorsi_2"
8637 [(set (reg FLAGS_REG)
8638 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8639 (match_operand:SI 2 "general_operand" "rim,ri"))
8641 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8642 (ior:SI (match_dup 1) (match_dup 2)))]
8643 "ix86_match_ccmode (insn, CCNOmode)
8644 && ix86_binary_operator_ok (IOR, SImode, operands)"
8645 "or{l}\t{%2, %0|%0, %2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "mode" "SI")])
8649 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8650 ;; ??? Special case for immediate operand is missing - it is tricky.
8651 (define_insn "*iorsi_2_zext"
8652 [(set (reg FLAGS_REG)
8653 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8654 (match_operand:SI 2 "general_operand" "rim"))
8656 (set (match_operand:DI 0 "register_operand" "=r")
8657 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8658 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8659 && ix86_binary_operator_ok (IOR, SImode, operands)"
8660 "or{l}\t{%2, %k0|%k0, %2}"
8661 [(set_attr "type" "alu")
8662 (set_attr "mode" "SI")])
8664 (define_insn "*iorsi_2_zext_imm"
8665 [(set (reg FLAGS_REG)
8666 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8667 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
8669 (set (match_operand:DI 0 "register_operand" "=r")
8670 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8671 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8672 && ix86_binary_operator_ok (IOR, SImode, operands)"
8673 "or{l}\t{%2, %k0|%k0, %2}"
8674 [(set_attr "type" "alu")
8675 (set_attr "mode" "SI")])
8677 (define_insn "*iorsi_3"
8678 [(set (reg FLAGS_REG)
8679 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8680 (match_operand:SI 2 "general_operand" "rim"))
8682 (clobber (match_scratch:SI 0 "=r"))]
8683 "ix86_match_ccmode (insn, CCNOmode)
8684 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8685 "or{l}\t{%2, %0|%0, %2}"
8686 [(set_attr "type" "alu")
8687 (set_attr "mode" "SI")])
8689 (define_expand "iorhi3"
8690 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8691 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
8692 (match_operand:HI 2 "general_operand" "")))
8693 (clobber (reg:CC FLAGS_REG))]
8694 "TARGET_HIMODE_MATH"
8695 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
8697 (define_insn "*iorhi_1"
8698 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
8699 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8700 (match_operand:HI 2 "general_operand" "rmi,ri")))
8701 (clobber (reg:CC FLAGS_REG))]
8702 "ix86_binary_operator_ok (IOR, HImode, operands)"
8703 "or{w}\t{%2, %0|%0, %2}"
8704 [(set_attr "type" "alu")
8705 (set_attr "mode" "HI")])
8707 (define_insn "*iorhi_2"
8708 [(set (reg FLAGS_REG)
8709 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8710 (match_operand:HI 2 "general_operand" "rim,ri"))
8712 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8713 (ior:HI (match_dup 1) (match_dup 2)))]
8714 "ix86_match_ccmode (insn, CCNOmode)
8715 && ix86_binary_operator_ok (IOR, HImode, operands)"
8716 "or{w}\t{%2, %0|%0, %2}"
8717 [(set_attr "type" "alu")
8718 (set_attr "mode" "HI")])
8720 (define_insn "*iorhi_3"
8721 [(set (reg FLAGS_REG)
8722 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
8723 (match_operand:HI 2 "general_operand" "rim"))
8725 (clobber (match_scratch:HI 0 "=r"))]
8726 "ix86_match_ccmode (insn, CCNOmode)
8727 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8728 "or{w}\t{%2, %0|%0, %2}"
8729 [(set_attr "type" "alu")
8730 (set_attr "mode" "HI")])
8732 (define_expand "iorqi3"
8733 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8734 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
8735 (match_operand:QI 2 "general_operand" "")))
8736 (clobber (reg:CC FLAGS_REG))]
8737 "TARGET_QIMODE_MATH"
8738 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
8740 ;; %%% Potential partial reg stall on alternative 2. What to do?
8741 (define_insn "*iorqi_1"
8742 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8743 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8744 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
8745 (clobber (reg:CC FLAGS_REG))]
8746 "ix86_binary_operator_ok (IOR, QImode, operands)"
8748 or{b}\t{%2, %0|%0, %2}
8749 or{b}\t{%2, %0|%0, %2}
8750 or{l}\t{%k2, %k0|%k0, %k2}"
8751 [(set_attr "type" "alu")
8752 (set_attr "mode" "QI,QI,SI")])
8754 (define_insn "*iorqi_1_slp"
8755 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8756 (ior:QI (match_dup 0)
8757 (match_operand:QI 1 "general_operand" "qmi,qi")))
8758 (clobber (reg:CC FLAGS_REG))]
8759 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8760 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8761 "or{b}\t{%1, %0|%0, %1}"
8762 [(set_attr "type" "alu1")
8763 (set_attr "mode" "QI")])
8765 (define_insn "*iorqi_2"
8766 [(set (reg FLAGS_REG)
8767 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8768 (match_operand:QI 2 "general_operand" "qim,qi"))
8770 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8771 (ior:QI (match_dup 1) (match_dup 2)))]
8772 "ix86_match_ccmode (insn, CCNOmode)
8773 && ix86_binary_operator_ok (IOR, QImode, operands)"
8774 "or{b}\t{%2, %0|%0, %2}"
8775 [(set_attr "type" "alu")
8776 (set_attr "mode" "QI")])
8778 (define_insn "*iorqi_2_slp"
8779 [(set (reg FLAGS_REG)
8780 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8781 (match_operand:QI 1 "general_operand" "qim,qi"))
8783 (set (strict_low_part (match_dup 0))
8784 (ior:QI (match_dup 0) (match_dup 1)))]
8785 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
8786 && ix86_match_ccmode (insn, CCNOmode)
8787 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
8788 "or{b}\t{%1, %0|%0, %1}"
8789 [(set_attr "type" "alu1")
8790 (set_attr "mode" "QI")])
8792 (define_insn "*iorqi_3"
8793 [(set (reg FLAGS_REG)
8794 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8795 (match_operand:QI 2 "general_operand" "qim"))
8797 (clobber (match_scratch:QI 0 "=q"))]
8798 "ix86_match_ccmode (insn, CCNOmode)
8799 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
8800 "or{b}\t{%2, %0|%0, %2}"
8801 [(set_attr "type" "alu")
8802 (set_attr "mode" "QI")])
8804 (define_insn "iorqi_ext_0"
8805 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8810 (match_operand 1 "ext_register_operand" "0")
8813 (match_operand 2 "const_int_operand" "n")))
8814 (clobber (reg:CC FLAGS_REG))]
8815 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8816 "or{b}\t{%2, %h0|%h0, %2}"
8817 [(set_attr "type" "alu")
8818 (set_attr "length_immediate" "1")
8819 (set_attr "mode" "QI")])
8821 (define_insn "*iorqi_ext_1"
8822 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8827 (match_operand 1 "ext_register_operand" "0")
8831 (match_operand:QI 2 "general_operand" "Qm"))))
8832 (clobber (reg:CC FLAGS_REG))]
8834 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8835 "or{b}\t{%2, %h0|%h0, %2}"
8836 [(set_attr "type" "alu")
8837 (set_attr "length_immediate" "0")
8838 (set_attr "mode" "QI")])
8840 (define_insn "*iorqi_ext_1_rex64"
8841 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8846 (match_operand 1 "ext_register_operand" "0")
8850 (match_operand 2 "ext_register_operand" "Q"))))
8851 (clobber (reg:CC FLAGS_REG))]
8853 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
8854 "or{b}\t{%2, %h0|%h0, %2}"
8855 [(set_attr "type" "alu")
8856 (set_attr "length_immediate" "0")
8857 (set_attr "mode" "QI")])
8859 (define_insn "*iorqi_ext_2"
8860 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8864 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8867 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8870 (clobber (reg:CC FLAGS_REG))]
8871 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
8872 "ior{b}\t{%h2, %h0|%h0, %h2}"
8873 [(set_attr "type" "alu")
8874 (set_attr "length_immediate" "0")
8875 (set_attr "mode" "QI")])
8878 [(set (match_operand 0 "register_operand" "")
8879 (ior (match_operand 1 "register_operand" "")
8880 (match_operand 2 "const_int_operand" "")))
8881 (clobber (reg:CC FLAGS_REG))]
8883 && QI_REG_P (operands[0])
8884 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8885 && !(INTVAL (operands[2]) & ~(255 << 8))
8886 && GET_MODE (operands[0]) != QImode"
8887 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8888 (ior:SI (zero_extract:SI (match_dup 1)
8889 (const_int 8) (const_int 8))
8891 (clobber (reg:CC FLAGS_REG))])]
8892 "operands[0] = gen_lowpart (SImode, operands[0]);
8893 operands[1] = gen_lowpart (SImode, operands[1]);
8894 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8896 ;; Since OR can be encoded with sign extended immediate, this is only
8897 ;; profitable when 7th bit is set.
8899 [(set (match_operand 0 "register_operand" "")
8900 (ior (match_operand 1 "general_operand" "")
8901 (match_operand 2 "const_int_operand" "")))
8902 (clobber (reg:CC FLAGS_REG))]
8904 && ANY_QI_REG_P (operands[0])
8905 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
8906 && !(INTVAL (operands[2]) & ~255)
8907 && (INTVAL (operands[2]) & 128)
8908 && GET_MODE (operands[0]) != QImode"
8909 [(parallel [(set (strict_low_part (match_dup 0))
8910 (ior:QI (match_dup 1)
8912 (clobber (reg:CC FLAGS_REG))])]
8913 "operands[0] = gen_lowpart (QImode, operands[0]);
8914 operands[1] = gen_lowpart (QImode, operands[1]);
8915 operands[2] = gen_lowpart (QImode, operands[2]);")
8917 ;; Logical XOR instructions
8919 ;; %%% This used to optimize known byte-wide and operations to memory.
8920 ;; If this is considered useful, it should be done with splitters.
8922 (define_expand "xordi3"
8923 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8924 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8925 (match_operand:DI 2 "x86_64_general_operand" "")))
8926 (clobber (reg:CC FLAGS_REG))]
8928 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
8930 (define_insn "*xordi_1_rex64"
8931 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8932 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8933 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8934 (clobber (reg:CC FLAGS_REG))]
8936 && ix86_binary_operator_ok (XOR, DImode, operands)"
8938 xor{q}\t{%2, %0|%0, %2}
8939 xor{q}\t{%2, %0|%0, %2}"
8940 [(set_attr "type" "alu")
8941 (set_attr "mode" "DI,DI")])
8943 (define_insn "*xordi_2_rex64"
8944 [(set (reg FLAGS_REG)
8945 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8946 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8948 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8949 (xor:DI (match_dup 1) (match_dup 2)))]
8951 && ix86_match_ccmode (insn, CCNOmode)
8952 && ix86_binary_operator_ok (XOR, DImode, operands)"
8954 xor{q}\t{%2, %0|%0, %2}
8955 xor{q}\t{%2, %0|%0, %2}"
8956 [(set_attr "type" "alu")
8957 (set_attr "mode" "DI,DI")])
8959 (define_insn "*xordi_3_rex64"
8960 [(set (reg FLAGS_REG)
8961 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8962 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8964 (clobber (match_scratch:DI 0 "=r"))]
8966 && ix86_match_ccmode (insn, CCNOmode)
8967 && ix86_binary_operator_ok (XOR, DImode, operands)"
8968 "xor{q}\t{%2, %0|%0, %2}"
8969 [(set_attr "type" "alu")
8970 (set_attr "mode" "DI")])
8972 (define_expand "xorsi3"
8973 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8974 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
8975 (match_operand:SI 2 "general_operand" "")))
8976 (clobber (reg:CC FLAGS_REG))]
8978 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
8980 (define_insn "*xorsi_1"
8981 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8982 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8983 (match_operand:SI 2 "general_operand" "ri,rm")))
8984 (clobber (reg:CC FLAGS_REG))]
8985 "ix86_binary_operator_ok (XOR, SImode, operands)"
8986 "xor{l}\t{%2, %0|%0, %2}"
8987 [(set_attr "type" "alu")
8988 (set_attr "mode" "SI")])
8990 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8991 ;; Add speccase for immediates
8992 (define_insn "*xorsi_1_zext"
8993 [(set (match_operand:DI 0 "register_operand" "=r")
8995 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8996 (match_operand:SI 2 "general_operand" "rim"))))
8997 (clobber (reg:CC FLAGS_REG))]
8998 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
8999 "xor{l}\t{%2, %k0|%k0, %2}"
9000 [(set_attr "type" "alu")
9001 (set_attr "mode" "SI")])
9003 (define_insn "*xorsi_1_zext_imm"
9004 [(set (match_operand:DI 0 "register_operand" "=r")
9005 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9006 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9007 (clobber (reg:CC FLAGS_REG))]
9008 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9009 "xor{l}\t{%2, %k0|%k0, %2}"
9010 [(set_attr "type" "alu")
9011 (set_attr "mode" "SI")])
9013 (define_insn "*xorsi_2"
9014 [(set (reg FLAGS_REG)
9015 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9016 (match_operand:SI 2 "general_operand" "rim,ri"))
9018 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9019 (xor:SI (match_dup 1) (match_dup 2)))]
9020 "ix86_match_ccmode (insn, CCNOmode)
9021 && ix86_binary_operator_ok (XOR, SImode, operands)"
9022 "xor{l}\t{%2, %0|%0, %2}"
9023 [(set_attr "type" "alu")
9024 (set_attr "mode" "SI")])
9026 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9027 ;; ??? Special case for immediate operand is missing - it is tricky.
9028 (define_insn "*xorsi_2_zext"
9029 [(set (reg FLAGS_REG)
9030 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9031 (match_operand:SI 2 "general_operand" "rim"))
9033 (set (match_operand:DI 0 "register_operand" "=r")
9034 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9035 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9036 && ix86_binary_operator_ok (XOR, SImode, operands)"
9037 "xor{l}\t{%2, %k0|%k0, %2}"
9038 [(set_attr "type" "alu")
9039 (set_attr "mode" "SI")])
9041 (define_insn "*xorsi_2_zext_imm"
9042 [(set (reg FLAGS_REG)
9043 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9044 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9046 (set (match_operand:DI 0 "register_operand" "=r")
9047 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9048 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9049 && ix86_binary_operator_ok (XOR, SImode, operands)"
9050 "xor{l}\t{%2, %k0|%k0, %2}"
9051 [(set_attr "type" "alu")
9052 (set_attr "mode" "SI")])
9054 (define_insn "*xorsi_3"
9055 [(set (reg FLAGS_REG)
9056 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9057 (match_operand:SI 2 "general_operand" "rim"))
9059 (clobber (match_scratch:SI 0 "=r"))]
9060 "ix86_match_ccmode (insn, CCNOmode)
9061 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9062 "xor{l}\t{%2, %0|%0, %2}"
9063 [(set_attr "type" "alu")
9064 (set_attr "mode" "SI")])
9066 (define_expand "xorhi3"
9067 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9068 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9069 (match_operand:HI 2 "general_operand" "")))
9070 (clobber (reg:CC FLAGS_REG))]
9071 "TARGET_HIMODE_MATH"
9072 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9074 (define_insn "*xorhi_1"
9075 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9076 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9077 (match_operand:HI 2 "general_operand" "rmi,ri")))
9078 (clobber (reg:CC FLAGS_REG))]
9079 "ix86_binary_operator_ok (XOR, HImode, operands)"
9080 "xor{w}\t{%2, %0|%0, %2}"
9081 [(set_attr "type" "alu")
9082 (set_attr "mode" "HI")])
9084 (define_insn "*xorhi_2"
9085 [(set (reg FLAGS_REG)
9086 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9087 (match_operand:HI 2 "general_operand" "rim,ri"))
9089 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9090 (xor:HI (match_dup 1) (match_dup 2)))]
9091 "ix86_match_ccmode (insn, CCNOmode)
9092 && ix86_binary_operator_ok (XOR, HImode, operands)"
9093 "xor{w}\t{%2, %0|%0, %2}"
9094 [(set_attr "type" "alu")
9095 (set_attr "mode" "HI")])
9097 (define_insn "*xorhi_3"
9098 [(set (reg FLAGS_REG)
9099 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9100 (match_operand:HI 2 "general_operand" "rim"))
9102 (clobber (match_scratch:HI 0 "=r"))]
9103 "ix86_match_ccmode (insn, CCNOmode)
9104 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9105 "xor{w}\t{%2, %0|%0, %2}"
9106 [(set_attr "type" "alu")
9107 (set_attr "mode" "HI")])
9109 (define_expand "xorqi3"
9110 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9111 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9112 (match_operand:QI 2 "general_operand" "")))
9113 (clobber (reg:CC FLAGS_REG))]
9114 "TARGET_QIMODE_MATH"
9115 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9117 ;; %%% Potential partial reg stall on alternative 2. What to do?
9118 (define_insn "*xorqi_1"
9119 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9120 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9121 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9122 (clobber (reg:CC FLAGS_REG))]
9123 "ix86_binary_operator_ok (XOR, QImode, operands)"
9125 xor{b}\t{%2, %0|%0, %2}
9126 xor{b}\t{%2, %0|%0, %2}
9127 xor{l}\t{%k2, %k0|%k0, %k2}"
9128 [(set_attr "type" "alu")
9129 (set_attr "mode" "QI,QI,SI")])
9131 (define_insn "*xorqi_1_slp"
9132 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9133 (xor:QI (match_dup 0)
9134 (match_operand:QI 1 "general_operand" "qi,qmi")))
9135 (clobber (reg:CC FLAGS_REG))]
9136 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9137 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9138 "xor{b}\t{%1, %0|%0, %1}"
9139 [(set_attr "type" "alu1")
9140 (set_attr "mode" "QI")])
9142 (define_insn "xorqi_ext_0"
9143 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9148 (match_operand 1 "ext_register_operand" "0")
9151 (match_operand 2 "const_int_operand" "n")))
9152 (clobber (reg:CC FLAGS_REG))]
9153 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9154 "xor{b}\t{%2, %h0|%h0, %2}"
9155 [(set_attr "type" "alu")
9156 (set_attr "length_immediate" "1")
9157 (set_attr "mode" "QI")])
9159 (define_insn "*xorqi_ext_1"
9160 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9165 (match_operand 1 "ext_register_operand" "0")
9169 (match_operand:QI 2 "general_operand" "Qm"))))
9170 (clobber (reg:CC FLAGS_REG))]
9172 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9173 "xor{b}\t{%2, %h0|%h0, %2}"
9174 [(set_attr "type" "alu")
9175 (set_attr "length_immediate" "0")
9176 (set_attr "mode" "QI")])
9178 (define_insn "*xorqi_ext_1_rex64"
9179 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9184 (match_operand 1 "ext_register_operand" "0")
9188 (match_operand 2 "ext_register_operand" "Q"))))
9189 (clobber (reg:CC FLAGS_REG))]
9191 && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9192 "xor{b}\t{%2, %h0|%h0, %2}"
9193 [(set_attr "type" "alu")
9194 (set_attr "length_immediate" "0")
9195 (set_attr "mode" "QI")])
9197 (define_insn "*xorqi_ext_2"
9198 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9202 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9205 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9208 (clobber (reg:CC FLAGS_REG))]
9209 "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9210 "xor{b}\t{%h2, %h0|%h0, %h2}"
9211 [(set_attr "type" "alu")
9212 (set_attr "length_immediate" "0")
9213 (set_attr "mode" "QI")])
9215 (define_insn "*xorqi_cc_1"
9216 [(set (reg FLAGS_REG)
9218 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9219 (match_operand:QI 2 "general_operand" "qim,qi"))
9221 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9222 (xor:QI (match_dup 1) (match_dup 2)))]
9223 "ix86_match_ccmode (insn, CCNOmode)
9224 && ix86_binary_operator_ok (XOR, QImode, operands)"
9225 "xor{b}\t{%2, %0|%0, %2}"
9226 [(set_attr "type" "alu")
9227 (set_attr "mode" "QI")])
9229 (define_insn "*xorqi_2_slp"
9230 [(set (reg FLAGS_REG)
9231 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9232 (match_operand:QI 1 "general_operand" "qim,qi"))
9234 (set (strict_low_part (match_dup 0))
9235 (xor:QI (match_dup 0) (match_dup 1)))]
9236 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9237 && ix86_match_ccmode (insn, CCNOmode)
9238 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
9239 "xor{b}\t{%1, %0|%0, %1}"
9240 [(set_attr "type" "alu1")
9241 (set_attr "mode" "QI")])
9243 (define_insn "*xorqi_cc_2"
9244 [(set (reg FLAGS_REG)
9246 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9247 (match_operand:QI 2 "general_operand" "qim"))
9249 (clobber (match_scratch:QI 0 "=q"))]
9250 "ix86_match_ccmode (insn, CCNOmode)
9251 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
9252 "xor{b}\t{%2, %0|%0, %2}"
9253 [(set_attr "type" "alu")
9254 (set_attr "mode" "QI")])
9256 (define_insn "*xorqi_cc_ext_1"
9257 [(set (reg FLAGS_REG)
9261 (match_operand 1 "ext_register_operand" "0")
9264 (match_operand:QI 2 "general_operand" "qmn"))
9266 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9270 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9272 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9273 "xor{b}\t{%2, %h0|%h0, %2}"
9274 [(set_attr "type" "alu")
9275 (set_attr "mode" "QI")])
9277 (define_insn "*xorqi_cc_ext_1_rex64"
9278 [(set (reg FLAGS_REG)
9282 (match_operand 1 "ext_register_operand" "0")
9285 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9287 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9291 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9293 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9294 "xor{b}\t{%2, %h0|%h0, %2}"
9295 [(set_attr "type" "alu")
9296 (set_attr "mode" "QI")])
9298 (define_expand "xorqi_cc_ext_1"
9300 (set (reg:CCNO FLAGS_REG)
9304 (match_operand 1 "ext_register_operand" "")
9307 (match_operand:QI 2 "general_operand" ""))
9309 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9313 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9319 [(set (match_operand 0 "register_operand" "")
9320 (xor (match_operand 1 "register_operand" "")
9321 (match_operand 2 "const_int_operand" "")))
9322 (clobber (reg:CC FLAGS_REG))]
9324 && QI_REG_P (operands[0])
9325 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9326 && !(INTVAL (operands[2]) & ~(255 << 8))
9327 && GET_MODE (operands[0]) != QImode"
9328 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9329 (xor:SI (zero_extract:SI (match_dup 1)
9330 (const_int 8) (const_int 8))
9332 (clobber (reg:CC FLAGS_REG))])]
9333 "operands[0] = gen_lowpart (SImode, operands[0]);
9334 operands[1] = gen_lowpart (SImode, operands[1]);
9335 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9337 ;; Since XOR can be encoded with sign extended immediate, this is only
9338 ;; profitable when 7th bit is set.
9340 [(set (match_operand 0 "register_operand" "")
9341 (xor (match_operand 1 "general_operand" "")
9342 (match_operand 2 "const_int_operand" "")))
9343 (clobber (reg:CC FLAGS_REG))]
9345 && ANY_QI_REG_P (operands[0])
9346 && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9347 && !(INTVAL (operands[2]) & ~255)
9348 && (INTVAL (operands[2]) & 128)
9349 && GET_MODE (operands[0]) != QImode"
9350 [(parallel [(set (strict_low_part (match_dup 0))
9351 (xor:QI (match_dup 1)
9353 (clobber (reg:CC FLAGS_REG))])]
9354 "operands[0] = gen_lowpart (QImode, operands[0]);
9355 operands[1] = gen_lowpart (QImode, operands[1]);
9356 operands[2] = gen_lowpart (QImode, operands[2]);")
9358 ;; Negation instructions
9360 (define_expand "negti2"
9361 [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
9362 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9363 (clobber (reg:CC FLAGS_REG))])]
9365 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9367 (define_insn "*negti2_1"
9368 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9369 (neg:TI (match_operand:TI 1 "general_operand" "0")))
9370 (clobber (reg:CC FLAGS_REG))]
9372 && ix86_unary_operator_ok (NEG, TImode, operands)"
9376 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9377 (neg:TI (match_operand:TI 1 "general_operand" "")))
9378 (clobber (reg:CC FLAGS_REG))]
9379 "TARGET_64BIT && reload_completed"
9381 [(set (reg:CCZ FLAGS_REG)
9382 (compare:CCZ (neg:DI (match_dup 2)) (const_int 0)))
9383 (set (match_dup 0) (neg:DI (match_dup 2)))])
9386 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9389 (clobber (reg:CC FLAGS_REG))])
9392 (neg:DI (match_dup 1)))
9393 (clobber (reg:CC FLAGS_REG))])]
9394 "split_ti (operands+1, 1, operands+2, operands+3);
9395 split_ti (operands+0, 1, operands+0, operands+1);")
9397 (define_expand "negdi2"
9398 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
9399 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
9400 (clobber (reg:CC FLAGS_REG))])]
9402 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9404 (define_insn "*negdi2_1"
9405 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9406 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9407 (clobber (reg:CC FLAGS_REG))]
9409 && ix86_unary_operator_ok (NEG, DImode, operands)"
9413 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9414 (neg:DI (match_operand:DI 1 "general_operand" "")))
9415 (clobber (reg:CC FLAGS_REG))]
9416 "!TARGET_64BIT && reload_completed"
9418 [(set (reg:CCZ FLAGS_REG)
9419 (compare:CCZ (neg:SI (match_dup 2)) (const_int 0)))
9420 (set (match_dup 0) (neg:SI (match_dup 2)))])
9423 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9426 (clobber (reg:CC FLAGS_REG))])
9429 (neg:SI (match_dup 1)))
9430 (clobber (reg:CC FLAGS_REG))])]
9431 "split_di (operands+1, 1, operands+2, operands+3);
9432 split_di (operands+0, 1, operands+0, operands+1);")
9434 (define_insn "*negdi2_1_rex64"
9435 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9436 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9437 (clobber (reg:CC FLAGS_REG))]
9438 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9440 [(set_attr "type" "negnot")
9441 (set_attr "mode" "DI")])
9443 ;; The problem with neg is that it does not perform (compare x 0),
9444 ;; it really performs (compare 0 x), which leaves us with the zero
9445 ;; flag being the only useful item.
9447 (define_insn "*negdi2_cmpz_rex64"
9448 [(set (reg:CCZ FLAGS_REG)
9449 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9451 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9452 (neg:DI (match_dup 1)))]
9453 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9455 [(set_attr "type" "negnot")
9456 (set_attr "mode" "DI")])
9459 (define_expand "negsi2"
9460 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
9461 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
9462 (clobber (reg:CC FLAGS_REG))])]
9464 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9466 (define_insn "*negsi2_1"
9467 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9468 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9469 (clobber (reg:CC FLAGS_REG))]
9470 "ix86_unary_operator_ok (NEG, SImode, operands)"
9472 [(set_attr "type" "negnot")
9473 (set_attr "mode" "SI")])
9475 ;; Combine is quite creative about this pattern.
9476 (define_insn "*negsi2_1_zext"
9477 [(set (match_operand:DI 0 "register_operand" "=r")
9478 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9481 (clobber (reg:CC FLAGS_REG))]
9482 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9484 [(set_attr "type" "negnot")
9485 (set_attr "mode" "SI")])
9487 ;; The problem with neg is that it does not perform (compare x 0),
9488 ;; it really performs (compare 0 x), which leaves us with the zero
9489 ;; flag being the only useful item.
9491 (define_insn "*negsi2_cmpz"
9492 [(set (reg:CCZ FLAGS_REG)
9493 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9495 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9496 (neg:SI (match_dup 1)))]
9497 "ix86_unary_operator_ok (NEG, SImode, operands)"
9499 [(set_attr "type" "negnot")
9500 (set_attr "mode" "SI")])
9502 (define_insn "*negsi2_cmpz_zext"
9503 [(set (reg:CCZ FLAGS_REG)
9504 (compare:CCZ (lshiftrt:DI
9506 (match_operand:DI 1 "register_operand" "0")
9510 (set (match_operand:DI 0 "register_operand" "=r")
9511 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9514 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9516 [(set_attr "type" "negnot")
9517 (set_attr "mode" "SI")])
9519 (define_expand "neghi2"
9520 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
9521 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
9522 (clobber (reg:CC FLAGS_REG))])]
9523 "TARGET_HIMODE_MATH"
9524 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9526 (define_insn "*neghi2_1"
9527 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9528 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9529 (clobber (reg:CC FLAGS_REG))]
9530 "ix86_unary_operator_ok (NEG, HImode, operands)"
9532 [(set_attr "type" "negnot")
9533 (set_attr "mode" "HI")])
9535 (define_insn "*neghi2_cmpz"
9536 [(set (reg:CCZ FLAGS_REG)
9537 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9539 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9540 (neg:HI (match_dup 1)))]
9541 "ix86_unary_operator_ok (NEG, HImode, operands)"
9543 [(set_attr "type" "negnot")
9544 (set_attr "mode" "HI")])
9546 (define_expand "negqi2"
9547 [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
9548 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
9549 (clobber (reg:CC FLAGS_REG))])]
9550 "TARGET_QIMODE_MATH"
9551 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9553 (define_insn "*negqi2_1"
9554 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9555 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9556 (clobber (reg:CC FLAGS_REG))]
9557 "ix86_unary_operator_ok (NEG, QImode, operands)"
9559 [(set_attr "type" "negnot")
9560 (set_attr "mode" "QI")])
9562 (define_insn "*negqi2_cmpz"
9563 [(set (reg:CCZ FLAGS_REG)
9564 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9566 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9567 (neg:QI (match_dup 1)))]
9568 "ix86_unary_operator_ok (NEG, QImode, operands)"
9570 [(set_attr "type" "negnot")
9571 (set_attr "mode" "QI")])
9573 ;; Changing of sign for FP values is doable using integer unit too.
9575 (define_expand "negsf2"
9576 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9577 (neg:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9578 "TARGET_80387 || TARGET_SSE_MATH"
9579 "ix86_expand_fp_absneg_operator (NEG, SFmode, operands); DONE;")
9581 (define_expand "abssf2"
9582 [(set (match_operand:SF 0 "nonimmediate_operand" "")
9583 (abs:SF (match_operand:SF 1 "nonimmediate_operand" "")))]
9584 "TARGET_80387 || TARGET_SSE_MATH"
9585 "ix86_expand_fp_absneg_operator (ABS, SFmode, operands); DONE;")
9587 (define_insn "*absnegsf2_mixed"
9588 [(set (match_operand:SF 0 "nonimmediate_operand" "=x ,x,f,rm")
9589 (match_operator:SF 3 "absneg_operator"
9590 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0,0 ")]))
9591 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm ,0,X,X "))
9592 (clobber (reg:CC FLAGS_REG))]
9593 "TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9594 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9597 (define_insn "*absnegsf2_sse"
9598 [(set (match_operand:SF 0 "nonimmediate_operand" "=x,x,rm")
9599 (match_operator:SF 3 "absneg_operator"
9600 [(match_operand:SF 1 "nonimmediate_operand" "0 ,x,0")]))
9601 (use (match_operand:V4SF 2 "nonimmediate_operand" "xm,0,X"))
9602 (clobber (reg:CC FLAGS_REG))]
9604 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9607 (define_insn "*absnegsf2_i387"
9608 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,rm")
9609 (match_operator:SF 3 "absneg_operator"
9610 [(match_operand:SF 1 "nonimmediate_operand" "0,0")]))
9611 (use (match_operand 2 "" ""))
9612 (clobber (reg:CC FLAGS_REG))]
9613 "TARGET_80387 && !TARGET_SSE_MATH
9614 && ix86_unary_operator_ok (GET_CODE (operands[3]), SFmode, operands)"
9617 (define_expand "copysignsf3"
9618 [(match_operand:SF 0 "register_operand" "")
9619 (match_operand:SF 1 "nonmemory_operand" "")
9620 (match_operand:SF 2 "register_operand" "")]
9623 ix86_expand_copysign (operands);
9627 (define_insn_and_split "copysignsf3_const"
9628 [(set (match_operand:SF 0 "register_operand" "=x")
9630 [(match_operand:V4SF 1 "vector_move_operand" "xmC")
9631 (match_operand:SF 2 "register_operand" "0")
9632 (match_operand:V4SF 3 "nonimmediate_operand" "xm")]
9636 "&& reload_completed"
9639 ix86_split_copysign_const (operands);
9643 (define_insn "copysignsf3_var"
9644 [(set (match_operand:SF 0 "register_operand" "=x, x, x, x,x")
9646 [(match_operand:SF 2 "register_operand" " x, 0, 0, x,x")
9647 (match_operand:SF 3 "register_operand" " 1, 1, x, 1,x")
9648 (match_operand:V4SF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9649 (match_operand:V4SF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9651 (clobber (match_scratch:V4SF 1 "=x, x, x, x,x"))]
9656 [(set (match_operand:SF 0 "register_operand" "")
9658 [(match_operand:SF 2 "register_operand" "")
9659 (match_operand:SF 3 "register_operand" "")
9660 (match_operand:V4SF 4 "" "")
9661 (match_operand:V4SF 5 "" "")]
9663 (clobber (match_scratch:V4SF 1 ""))]
9664 "TARGET_SSE_MATH && reload_completed"
9667 ix86_split_copysign_var (operands);
9671 (define_expand "negdf2"
9672 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9673 (neg:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9674 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9675 "ix86_expand_fp_absneg_operator (NEG, DFmode, operands); DONE;")
9677 (define_expand "absdf2"
9678 [(set (match_operand:DF 0 "nonimmediate_operand" "")
9679 (abs:DF (match_operand:DF 1 "nonimmediate_operand" "")))]
9680 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
9681 "ix86_expand_fp_absneg_operator (ABS, DFmode, operands); DONE;")
9683 (define_insn "*absnegdf2_mixed"
9684 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,f,rm")
9685 (match_operator:DF 3 "absneg_operator"
9686 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0,0")]))
9687 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X,X"))
9688 (clobber (reg:CC FLAGS_REG))]
9689 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
9690 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9693 (define_insn "*absnegdf2_sse"
9694 [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Y,rm")
9695 (match_operator:DF 3 "absneg_operator"
9696 [(match_operand:DF 1 "nonimmediate_operand" "0 ,Y,0 ")]))
9697 (use (match_operand:V2DF 2 "nonimmediate_operand" "Ym,0,X "))
9698 (clobber (reg:CC FLAGS_REG))]
9699 "TARGET_SSE2 && TARGET_SSE_MATH
9700 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9703 (define_insn "*absnegdf2_i387"
9704 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,rm")
9705 (match_operator:DF 3 "absneg_operator"
9706 [(match_operand:DF 1 "nonimmediate_operand" "0,0")]))
9707 (use (match_operand 2 "" ""))
9708 (clobber (reg:CC FLAGS_REG))]
9709 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
9710 && ix86_unary_operator_ok (GET_CODE (operands[3]), DFmode, operands)"
9713 (define_expand "copysigndf3"
9714 [(match_operand:DF 0 "register_operand" "")
9715 (match_operand:DF 1 "nonmemory_operand" "")
9716 (match_operand:DF 2 "register_operand" "")]
9717 "TARGET_SSE2 && TARGET_SSE_MATH"
9719 ix86_expand_copysign (operands);
9723 (define_insn_and_split "copysigndf3_const"
9724 [(set (match_operand:DF 0 "register_operand" "=x")
9726 [(match_operand:V2DF 1 "vector_move_operand" "xmC")
9727 (match_operand:DF 2 "register_operand" "0")
9728 (match_operand:V2DF 3 "nonimmediate_operand" "xm")]
9730 "TARGET_SSE2 && TARGET_SSE_MATH"
9732 "&& reload_completed"
9735 ix86_split_copysign_const (operands);
9739 (define_insn "copysigndf3_var"
9740 [(set (match_operand:DF 0 "register_operand" "=x, x, x, x,x")
9742 [(match_operand:DF 2 "register_operand" " x, 0, 0, x,x")
9743 (match_operand:DF 3 "register_operand" " 1, 1, x, 1,x")
9744 (match_operand:V2DF 4 "nonimmediate_operand" " X,xm,xm, 0,0")
9745 (match_operand:V2DF 5 "nonimmediate_operand" " 0,xm, 1,xm,1")]
9747 (clobber (match_scratch:V2DF 1 "=x, x, x, x,x"))]
9748 "TARGET_SSE2 && TARGET_SSE_MATH"
9752 [(set (match_operand:DF 0 "register_operand" "")
9754 [(match_operand:DF 2 "register_operand" "")
9755 (match_operand:DF 3 "register_operand" "")
9756 (match_operand:V2DF 4 "" "")
9757 (match_operand:V2DF 5 "" "")]
9759 (clobber (match_scratch:V2DF 1 ""))]
9760 "TARGET_SSE2 && TARGET_SSE_MATH && reload_completed"
9763 ix86_split_copysign_var (operands);
9767 (define_expand "negxf2"
9768 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9769 (neg:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9771 "ix86_expand_fp_absneg_operator (NEG, XFmode, operands); DONE;")
9773 (define_expand "absxf2"
9774 [(set (match_operand:XF 0 "nonimmediate_operand" "")
9775 (abs:XF (match_operand:XF 1 "nonimmediate_operand" "")))]
9777 "ix86_expand_fp_absneg_operator (ABS, XFmode, operands); DONE;")
9779 (define_insn "*absnegxf2_i387"
9780 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,?rm")
9781 (match_operator:XF 3 "absneg_operator"
9782 [(match_operand:XF 1 "nonimmediate_operand" "0,0")]))
9783 (use (match_operand 2 "" ""))
9784 (clobber (reg:CC FLAGS_REG))]
9786 && ix86_unary_operator_ok (GET_CODE (operands[3]), XFmode, operands)"
9789 ;; Splitters for fp abs and neg.
9792 [(set (match_operand 0 "fp_register_operand" "")
9793 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9794 (use (match_operand 2 "" ""))
9795 (clobber (reg:CC FLAGS_REG))]
9797 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9800 [(set (match_operand 0 "register_operand" "")
9801 (match_operator 3 "absneg_operator"
9802 [(match_operand 1 "register_operand" "")]))
9803 (use (match_operand 2 "nonimmediate_operand" ""))
9804 (clobber (reg:CC FLAGS_REG))]
9805 "reload_completed && SSE_REG_P (operands[0])"
9806 [(set (match_dup 0) (match_dup 3))]
9808 enum machine_mode mode = GET_MODE (operands[0]);
9809 enum machine_mode vmode = GET_MODE (operands[2]);
9812 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9813 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9814 if (operands_match_p (operands[0], operands[2]))
9817 operands[1] = operands[2];
9820 if (GET_CODE (operands[3]) == ABS)
9821 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9823 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9828 [(set (match_operand:SF 0 "register_operand" "")
9829 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9830 (use (match_operand:V4SF 2 "" ""))
9831 (clobber (reg:CC FLAGS_REG))]
9833 [(parallel [(set (match_dup 0) (match_dup 1))
9834 (clobber (reg:CC FLAGS_REG))])]
9837 operands[0] = gen_lowpart (SImode, operands[0]);
9838 if (GET_CODE (operands[1]) == ABS)
9840 tmp = gen_int_mode (0x7fffffff, SImode);
9841 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9845 tmp = gen_int_mode (0x80000000, SImode);
9846 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9852 [(set (match_operand:DF 0 "register_operand" "")
9853 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9854 (use (match_operand 2 "" ""))
9855 (clobber (reg:CC FLAGS_REG))]
9857 [(parallel [(set (match_dup 0) (match_dup 1))
9858 (clobber (reg:CC FLAGS_REG))])]
9863 tmp = gen_lowpart (DImode, operands[0]);
9864 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9867 if (GET_CODE (operands[1]) == ABS)
9870 tmp = gen_rtx_NOT (DImode, tmp);
9874 operands[0] = gen_highpart (SImode, operands[0]);
9875 if (GET_CODE (operands[1]) == ABS)
9877 tmp = gen_int_mode (0x7fffffff, SImode);
9878 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9882 tmp = gen_int_mode (0x80000000, SImode);
9883 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9890 [(set (match_operand:XF 0 "register_operand" "")
9891 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9892 (use (match_operand 2 "" ""))
9893 (clobber (reg:CC FLAGS_REG))]
9895 [(parallel [(set (match_dup 0) (match_dup 1))
9896 (clobber (reg:CC FLAGS_REG))])]
9899 operands[0] = gen_rtx_REG (SImode,
9900 true_regnum (operands[0])
9901 + (TARGET_64BIT ? 1 : 2));
9902 if (GET_CODE (operands[1]) == ABS)
9904 tmp = GEN_INT (0x7fff);
9905 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9909 tmp = GEN_INT (0x8000);
9910 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9916 [(set (match_operand 0 "memory_operand" "")
9917 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9918 (use (match_operand 2 "" ""))
9919 (clobber (reg:CC FLAGS_REG))]
9921 [(parallel [(set (match_dup 0) (match_dup 1))
9922 (clobber (reg:CC FLAGS_REG))])]
9924 enum machine_mode mode = GET_MODE (operands[0]);
9925 int size = mode == XFmode ? 10 : GET_MODE_SIZE (mode);
9928 operands[0] = adjust_address (operands[0], QImode, size - 1);
9929 if (GET_CODE (operands[1]) == ABS)
9931 tmp = gen_int_mode (0x7f, QImode);
9932 tmp = gen_rtx_AND (QImode, operands[0], tmp);
9936 tmp = gen_int_mode (0x80, QImode);
9937 tmp = gen_rtx_XOR (QImode, operands[0], tmp);
9942 ;; Conditionalize these after reload. If they match before reload, we
9943 ;; lose the clobber and ability to use integer instructions.
9945 (define_insn "*negsf2_1"
9946 [(set (match_operand:SF 0 "register_operand" "=f")
9947 (neg:SF (match_operand:SF 1 "register_operand" "0")))]
9948 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9950 [(set_attr "type" "fsgn")
9951 (set_attr "mode" "SF")])
9953 (define_insn "*negdf2_1"
9954 [(set (match_operand:DF 0 "register_operand" "=f")
9955 (neg:DF (match_operand:DF 1 "register_operand" "0")))]
9956 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9958 [(set_attr "type" "fsgn")
9959 (set_attr "mode" "DF")])
9961 (define_insn "*negxf2_1"
9962 [(set (match_operand:XF 0 "register_operand" "=f")
9963 (neg:XF (match_operand:XF 1 "register_operand" "0")))]
9966 [(set_attr "type" "fsgn")
9967 (set_attr "mode" "XF")])
9969 (define_insn "*abssf2_1"
9970 [(set (match_operand:SF 0 "register_operand" "=f")
9971 (abs:SF (match_operand:SF 1 "register_operand" "0")))]
9972 "TARGET_80387 && (reload_completed || !TARGET_SSE_MATH)"
9974 [(set_attr "type" "fsgn")
9975 (set_attr "mode" "SF")])
9977 (define_insn "*absdf2_1"
9978 [(set (match_operand:DF 0 "register_operand" "=f")
9979 (abs:DF (match_operand:DF 1 "register_operand" "0")))]
9980 "TARGET_80387 && (reload_completed || !(TARGET_SSE2 && TARGET_SSE_MATH))"
9982 [(set_attr "type" "fsgn")
9983 (set_attr "mode" "DF")])
9985 (define_insn "*absxf2_1"
9986 [(set (match_operand:XF 0 "register_operand" "=f")
9987 (abs:XF (match_operand:XF 1 "register_operand" "0")))]
9990 [(set_attr "type" "fsgn")
9991 (set_attr "mode" "DF")])
9993 (define_insn "*negextendsfdf2"
9994 [(set (match_operand:DF 0 "register_operand" "=f")
9995 (neg:DF (float_extend:DF
9996 (match_operand:SF 1 "register_operand" "0"))))]
9997 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9999 [(set_attr "type" "fsgn")
10000 (set_attr "mode" "DF")])
10002 (define_insn "*negextenddfxf2"
10003 [(set (match_operand:XF 0 "register_operand" "=f")
10004 (neg:XF (float_extend:XF
10005 (match_operand:DF 1 "register_operand" "0"))))]
10008 [(set_attr "type" "fsgn")
10009 (set_attr "mode" "XF")])
10011 (define_insn "*negextendsfxf2"
10012 [(set (match_operand:XF 0 "register_operand" "=f")
10013 (neg:XF (float_extend:XF
10014 (match_operand:SF 1 "register_operand" "0"))))]
10017 [(set_attr "type" "fsgn")
10018 (set_attr "mode" "XF")])
10020 (define_insn "*absextendsfdf2"
10021 [(set (match_operand:DF 0 "register_operand" "=f")
10022 (abs:DF (float_extend:DF
10023 (match_operand:SF 1 "register_operand" "0"))))]
10024 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10026 [(set_attr "type" "fsgn")
10027 (set_attr "mode" "DF")])
10029 (define_insn "*absextenddfxf2"
10030 [(set (match_operand:XF 0 "register_operand" "=f")
10031 (abs:XF (float_extend:XF
10032 (match_operand:DF 1 "register_operand" "0"))))]
10035 [(set_attr "type" "fsgn")
10036 (set_attr "mode" "XF")])
10038 (define_insn "*absextendsfxf2"
10039 [(set (match_operand:XF 0 "register_operand" "=f")
10040 (abs:XF (float_extend:XF
10041 (match_operand:SF 1 "register_operand" "0"))))]
10044 [(set_attr "type" "fsgn")
10045 (set_attr "mode" "XF")])
10047 ;; One complement instructions
10049 (define_expand "one_cmpldi2"
10050 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10051 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10053 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10055 (define_insn "*one_cmpldi2_1_rex64"
10056 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10057 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10058 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10060 [(set_attr "type" "negnot")
10061 (set_attr "mode" "DI")])
10063 (define_insn "*one_cmpldi2_2_rex64"
10064 [(set (reg FLAGS_REG)
10065 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10067 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10068 (not:DI (match_dup 1)))]
10069 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10070 && ix86_unary_operator_ok (NOT, DImode, operands)"
10072 [(set_attr "type" "alu1")
10073 (set_attr "mode" "DI")])
10076 [(set (match_operand 0 "flags_reg_operand" "")
10077 (match_operator 2 "compare_operator"
10078 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10080 (set (match_operand:DI 1 "nonimmediate_operand" "")
10081 (not:DI (match_dup 3)))]
10082 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10083 [(parallel [(set (match_dup 0)
10085 [(xor:DI (match_dup 3) (const_int -1))
10088 (xor:DI (match_dup 3) (const_int -1)))])]
10091 (define_expand "one_cmplsi2"
10092 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10093 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10095 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10097 (define_insn "*one_cmplsi2_1"
10098 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10099 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10100 "ix86_unary_operator_ok (NOT, SImode, operands)"
10102 [(set_attr "type" "negnot")
10103 (set_attr "mode" "SI")])
10105 ;; ??? Currently never generated - xor is used instead.
10106 (define_insn "*one_cmplsi2_1_zext"
10107 [(set (match_operand:DI 0 "register_operand" "=r")
10108 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10109 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10111 [(set_attr "type" "negnot")
10112 (set_attr "mode" "SI")])
10114 (define_insn "*one_cmplsi2_2"
10115 [(set (reg FLAGS_REG)
10116 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10118 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10119 (not:SI (match_dup 1)))]
10120 "ix86_match_ccmode (insn, CCNOmode)
10121 && ix86_unary_operator_ok (NOT, SImode, operands)"
10123 [(set_attr "type" "alu1")
10124 (set_attr "mode" "SI")])
10127 [(set (match_operand 0 "flags_reg_operand" "")
10128 (match_operator 2 "compare_operator"
10129 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10131 (set (match_operand:SI 1 "nonimmediate_operand" "")
10132 (not:SI (match_dup 3)))]
10133 "ix86_match_ccmode (insn, CCNOmode)"
10134 [(parallel [(set (match_dup 0)
10135 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10138 (xor:SI (match_dup 3) (const_int -1)))])]
10141 ;; ??? Currently never generated - xor is used instead.
10142 (define_insn "*one_cmplsi2_2_zext"
10143 [(set (reg FLAGS_REG)
10144 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10146 (set (match_operand:DI 0 "register_operand" "=r")
10147 (zero_extend:DI (not:SI (match_dup 1))))]
10148 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10149 && ix86_unary_operator_ok (NOT, SImode, operands)"
10151 [(set_attr "type" "alu1")
10152 (set_attr "mode" "SI")])
10155 [(set (match_operand 0 "flags_reg_operand" "")
10156 (match_operator 2 "compare_operator"
10157 [(not:SI (match_operand:SI 3 "register_operand" ""))
10159 (set (match_operand:DI 1 "register_operand" "")
10160 (zero_extend:DI (not:SI (match_dup 3))))]
10161 "ix86_match_ccmode (insn, CCNOmode)"
10162 [(parallel [(set (match_dup 0)
10163 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10166 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10169 (define_expand "one_cmplhi2"
10170 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10171 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10172 "TARGET_HIMODE_MATH"
10173 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10175 (define_insn "*one_cmplhi2_1"
10176 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10177 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10178 "ix86_unary_operator_ok (NOT, HImode, operands)"
10180 [(set_attr "type" "negnot")
10181 (set_attr "mode" "HI")])
10183 (define_insn "*one_cmplhi2_2"
10184 [(set (reg FLAGS_REG)
10185 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10187 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10188 (not:HI (match_dup 1)))]
10189 "ix86_match_ccmode (insn, CCNOmode)
10190 && ix86_unary_operator_ok (NEG, HImode, operands)"
10192 [(set_attr "type" "alu1")
10193 (set_attr "mode" "HI")])
10196 [(set (match_operand 0 "flags_reg_operand" "")
10197 (match_operator 2 "compare_operator"
10198 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10200 (set (match_operand:HI 1 "nonimmediate_operand" "")
10201 (not:HI (match_dup 3)))]
10202 "ix86_match_ccmode (insn, CCNOmode)"
10203 [(parallel [(set (match_dup 0)
10204 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10207 (xor:HI (match_dup 3) (const_int -1)))])]
10210 ;; %%% Potential partial reg stall on alternative 1. What to do?
10211 (define_expand "one_cmplqi2"
10212 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10213 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10214 "TARGET_QIMODE_MATH"
10215 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10217 (define_insn "*one_cmplqi2_1"
10218 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10219 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10220 "ix86_unary_operator_ok (NOT, QImode, operands)"
10224 [(set_attr "type" "negnot")
10225 (set_attr "mode" "QI,SI")])
10227 (define_insn "*one_cmplqi2_2"
10228 [(set (reg FLAGS_REG)
10229 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10231 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10232 (not:QI (match_dup 1)))]
10233 "ix86_match_ccmode (insn, CCNOmode)
10234 && ix86_unary_operator_ok (NOT, QImode, operands)"
10236 [(set_attr "type" "alu1")
10237 (set_attr "mode" "QI")])
10240 [(set (match_operand 0 "flags_reg_operand" "")
10241 (match_operator 2 "compare_operator"
10242 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10244 (set (match_operand:QI 1 "nonimmediate_operand" "")
10245 (not:QI (match_dup 3)))]
10246 "ix86_match_ccmode (insn, CCNOmode)"
10247 [(parallel [(set (match_dup 0)
10248 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10251 (xor:QI (match_dup 3) (const_int -1)))])]
10254 ;; Arithmetic shift instructions
10256 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10257 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10258 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10259 ;; from the assembler input.
10261 ;; This instruction shifts the target reg/mem as usual, but instead of
10262 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10263 ;; is a left shift double, bits are taken from the high order bits of
10264 ;; reg, else if the insn is a shift right double, bits are taken from the
10265 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10266 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10268 ;; Since sh[lr]d does not change the `reg' operand, that is done
10269 ;; separately, making all shifts emit pairs of shift double and normal
10270 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10271 ;; support a 63 bit shift, each shift where the count is in a reg expands
10272 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10274 ;; If the shift count is a constant, we need never emit more than one
10275 ;; shift pair, instead using moves and sign extension for counts greater
10278 (define_expand "ashlti3"
10279 [(parallel [(set (match_operand:TI 0 "register_operand" "")
10280 (ashift:TI (match_operand:TI 1 "register_operand" "")
10281 (match_operand:QI 2 "nonmemory_operand" "")))
10282 (clobber (reg:CC FLAGS_REG))])]
10285 if (! immediate_operand (operands[2], QImode))
10287 emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10290 ix86_expand_binary_operator (ASHIFT, TImode, operands);
10294 (define_insn "ashlti3_1"
10295 [(set (match_operand:TI 0 "register_operand" "=r")
10296 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10297 (match_operand:QI 2 "register_operand" "c")))
10298 (clobber (match_scratch:DI 3 "=&r"))
10299 (clobber (reg:CC FLAGS_REG))]
10302 [(set_attr "type" "multi")])
10304 (define_insn "*ashlti3_2"
10305 [(set (match_operand:TI 0 "register_operand" "=r")
10306 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10307 (match_operand:QI 2 "immediate_operand" "O")))
10308 (clobber (reg:CC FLAGS_REG))]
10311 [(set_attr "type" "multi")])
10314 [(set (match_operand:TI 0 "register_operand" "")
10315 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10316 (match_operand:QI 2 "register_operand" "")))
10317 (clobber (match_scratch:DI 3 ""))
10318 (clobber (reg:CC FLAGS_REG))]
10319 "TARGET_64BIT && reload_completed"
10321 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10324 [(set (match_operand:TI 0 "register_operand" "")
10325 (ashift:TI (match_operand:TI 1 "register_operand" "")
10326 (match_operand:QI 2 "immediate_operand" "")))
10327 (clobber (reg:CC FLAGS_REG))]
10328 "TARGET_64BIT && reload_completed"
10330 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10332 (define_insn "x86_64_shld"
10333 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10334 (ior:DI (ashift:DI (match_dup 0)
10335 (match_operand:QI 2 "nonmemory_operand" "J,c"))
10336 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10337 (minus:QI (const_int 64) (match_dup 2)))))
10338 (clobber (reg:CC FLAGS_REG))]
10341 shld{q}\t{%2, %1, %0|%0, %1, %2}
10342 shld{q}\t{%s2%1, %0|%0, %1, %2}"
10343 [(set_attr "type" "ishift")
10344 (set_attr "prefix_0f" "1")
10345 (set_attr "mode" "DI")
10346 (set_attr "athlon_decode" "vector")])
10348 (define_expand "x86_64_shift_adj"
10349 [(set (reg:CCZ FLAGS_REG)
10350 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10353 (set (match_operand:DI 0 "register_operand" "")
10354 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10355 (match_operand:DI 1 "register_operand" "")
10358 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10359 (match_operand:DI 3 "register_operand" "r")
10364 (define_expand "ashldi3"
10365 [(set (match_operand:DI 0 "shiftdi_operand" "")
10366 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10367 (match_operand:QI 2 "nonmemory_operand" "")))]
10369 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10371 (define_insn "*ashldi3_1_rex64"
10372 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10373 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10374 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10375 (clobber (reg:CC FLAGS_REG))]
10376 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10378 switch (get_attr_type (insn))
10381 gcc_assert (operands[2] == const1_rtx);
10382 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10383 return "add{q}\t{%0, %0|%0, %0}";
10386 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10387 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10388 operands[1] = gen_rtx_MULT (DImode, operands[1],
10389 GEN_INT (1 << INTVAL (operands[2])));
10390 return "lea{q}\t{%a1, %0|%0, %a1}";
10393 if (REG_P (operands[2]))
10394 return "sal{q}\t{%b2, %0|%0, %b2}";
10395 else if (operands[2] == const1_rtx
10396 && (TARGET_SHIFT1 || optimize_size))
10397 return "sal{q}\t%0";
10399 return "sal{q}\t{%2, %0|%0, %2}";
10402 [(set (attr "type")
10403 (cond [(eq_attr "alternative" "1")
10404 (const_string "lea")
10405 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10407 (match_operand 0 "register_operand" ""))
10408 (match_operand 2 "const1_operand" ""))
10409 (const_string "alu")
10411 (const_string "ishift")))
10412 (set_attr "mode" "DI")])
10414 ;; Convert lea to the lea pattern to avoid flags dependency.
10416 [(set (match_operand:DI 0 "register_operand" "")
10417 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10418 (match_operand:QI 2 "immediate_operand" "")))
10419 (clobber (reg:CC FLAGS_REG))]
10420 "TARGET_64BIT && reload_completed
10421 && true_regnum (operands[0]) != true_regnum (operands[1])"
10422 [(set (match_dup 0)
10423 (mult:DI (match_dup 1)
10425 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10427 ;; This pattern can't accept a variable shift count, since shifts by
10428 ;; zero don't affect the flags. We assume that shifts by constant
10429 ;; zero are optimized away.
10430 (define_insn "*ashldi3_cmp_rex64"
10431 [(set (reg FLAGS_REG)
10433 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10434 (match_operand:QI 2 "immediate_operand" "e"))
10436 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10437 (ashift:DI (match_dup 1) (match_dup 2)))]
10438 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10439 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10441 || !TARGET_PARTIAL_FLAG_REG_STALL
10442 || (operands[2] == const1_rtx
10444 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10446 switch (get_attr_type (insn))
10449 gcc_assert (operands[2] == const1_rtx);
10450 return "add{q}\t{%0, %0|%0, %0}";
10453 if (REG_P (operands[2]))
10454 return "sal{q}\t{%b2, %0|%0, %b2}";
10455 else if (operands[2] == const1_rtx
10456 && (TARGET_SHIFT1 || optimize_size))
10457 return "sal{q}\t%0";
10459 return "sal{q}\t{%2, %0|%0, %2}";
10462 [(set (attr "type")
10463 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10465 (match_operand 0 "register_operand" ""))
10466 (match_operand 2 "const1_operand" ""))
10467 (const_string "alu")
10469 (const_string "ishift")))
10470 (set_attr "mode" "DI")])
10472 (define_insn "*ashldi3_cconly_rex64"
10473 [(set (reg FLAGS_REG)
10475 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10476 (match_operand:QI 2 "immediate_operand" "e"))
10478 (clobber (match_scratch:DI 0 "=r"))]
10479 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10480 && ix86_binary_operator_ok (ASHIFT, DImode, operands)
10482 || !TARGET_PARTIAL_FLAG_REG_STALL
10483 || (operands[2] == const1_rtx
10485 || TARGET_DOUBLE_WITH_ADD)))"
10487 switch (get_attr_type (insn))
10490 gcc_assert (operands[2] == const1_rtx);
10491 return "add{q}\t{%0, %0|%0, %0}";
10494 if (REG_P (operands[2]))
10495 return "sal{q}\t{%b2, %0|%0, %b2}";
10496 else if (operands[2] == const1_rtx
10497 && (TARGET_SHIFT1 || optimize_size))
10498 return "sal{q}\t%0";
10500 return "sal{q}\t{%2, %0|%0, %2}";
10503 [(set (attr "type")
10504 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10506 (match_operand 0 "register_operand" ""))
10507 (match_operand 2 "const1_operand" ""))
10508 (const_string "alu")
10510 (const_string "ishift")))
10511 (set_attr "mode" "DI")])
10513 (define_insn "*ashldi3_1"
10514 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10515 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10516 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10517 (clobber (reg:CC FLAGS_REG))]
10520 [(set_attr "type" "multi")])
10522 ;; By default we don't ask for a scratch register, because when DImode
10523 ;; values are manipulated, registers are already at a premium. But if
10524 ;; we have one handy, we won't turn it away.
10526 [(match_scratch:SI 3 "r")
10527 (parallel [(set (match_operand:DI 0 "register_operand" "")
10528 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10529 (match_operand:QI 2 "nonmemory_operand" "")))
10530 (clobber (reg:CC FLAGS_REG))])
10532 "!TARGET_64BIT && TARGET_CMOVE"
10534 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10537 [(set (match_operand:DI 0 "register_operand" "")
10538 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10539 (match_operand:QI 2 "nonmemory_operand" "")))
10540 (clobber (reg:CC FLAGS_REG))]
10541 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10542 ? flow2_completed : reload_completed)"
10544 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10546 (define_insn "x86_shld_1"
10547 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
10548 (ior:SI (ashift:SI (match_dup 0)
10549 (match_operand:QI 2 "nonmemory_operand" "I,c"))
10550 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
10551 (minus:QI (const_int 32) (match_dup 2)))))
10552 (clobber (reg:CC FLAGS_REG))]
10555 shld{l}\t{%2, %1, %0|%0, %1, %2}
10556 shld{l}\t{%s2%1, %0|%0, %1, %2}"
10557 [(set_attr "type" "ishift")
10558 (set_attr "prefix_0f" "1")
10559 (set_attr "mode" "SI")
10560 (set_attr "pent_pair" "np")
10561 (set_attr "athlon_decode" "vector")])
10563 (define_expand "x86_shift_adj_1"
10564 [(set (reg:CCZ FLAGS_REG)
10565 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10568 (set (match_operand:SI 0 "register_operand" "")
10569 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10570 (match_operand:SI 1 "register_operand" "")
10573 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10574 (match_operand:SI 3 "register_operand" "r")
10579 (define_expand "x86_shift_adj_2"
10580 [(use (match_operand:SI 0 "register_operand" ""))
10581 (use (match_operand:SI 1 "register_operand" ""))
10582 (use (match_operand:QI 2 "register_operand" ""))]
10585 rtx label = gen_label_rtx ();
10588 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10590 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10591 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10592 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10593 gen_rtx_LABEL_REF (VOIDmode, label),
10595 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10596 JUMP_LABEL (tmp) = label;
10598 emit_move_insn (operands[0], operands[1]);
10599 ix86_expand_clear (operands[1]);
10601 emit_label (label);
10602 LABEL_NUSES (label) = 1;
10607 (define_expand "ashlsi3"
10608 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10609 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10610 (match_operand:QI 2 "nonmemory_operand" "")))
10611 (clobber (reg:CC FLAGS_REG))]
10613 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10615 (define_insn "*ashlsi3_1"
10616 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10617 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10618 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10619 (clobber (reg:CC FLAGS_REG))]
10620 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10622 switch (get_attr_type (insn))
10625 gcc_assert (operands[2] == const1_rtx);
10626 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10627 return "add{l}\t{%0, %0|%0, %0}";
10633 if (REG_P (operands[2]))
10634 return "sal{l}\t{%b2, %0|%0, %b2}";
10635 else if (operands[2] == const1_rtx
10636 && (TARGET_SHIFT1 || optimize_size))
10637 return "sal{l}\t%0";
10639 return "sal{l}\t{%2, %0|%0, %2}";
10642 [(set (attr "type")
10643 (cond [(eq_attr "alternative" "1")
10644 (const_string "lea")
10645 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10647 (match_operand 0 "register_operand" ""))
10648 (match_operand 2 "const1_operand" ""))
10649 (const_string "alu")
10651 (const_string "ishift")))
10652 (set_attr "mode" "SI")])
10654 ;; Convert lea to the lea pattern to avoid flags dependency.
10656 [(set (match_operand 0 "register_operand" "")
10657 (ashift (match_operand 1 "index_register_operand" "")
10658 (match_operand:QI 2 "const_int_operand" "")))
10659 (clobber (reg:CC FLAGS_REG))]
10661 && true_regnum (operands[0]) != true_regnum (operands[1])
10662 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10666 enum machine_mode mode = GET_MODE (operands[0]);
10668 if (GET_MODE_SIZE (mode) < 4)
10669 operands[0] = gen_lowpart (SImode, operands[0]);
10671 operands[1] = gen_lowpart (Pmode, operands[1]);
10672 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10674 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10675 if (Pmode != SImode)
10676 pat = gen_rtx_SUBREG (SImode, pat, 0);
10677 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10681 ;; Rare case of shifting RSP is handled by generating move and shift
10683 [(set (match_operand 0 "register_operand" "")
10684 (ashift (match_operand 1 "register_operand" "")
10685 (match_operand:QI 2 "const_int_operand" "")))
10686 (clobber (reg:CC FLAGS_REG))]
10688 && true_regnum (operands[0]) != true_regnum (operands[1])"
10692 emit_move_insn (operands[0], operands[1]);
10693 pat = gen_rtx_SET (VOIDmode, operands[0],
10694 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10695 operands[0], operands[2]));
10696 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10697 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10701 (define_insn "*ashlsi3_1_zext"
10702 [(set (match_operand:DI 0 "register_operand" "=r,r")
10703 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10704 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10705 (clobber (reg:CC FLAGS_REG))]
10706 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10708 switch (get_attr_type (insn))
10711 gcc_assert (operands[2] == const1_rtx);
10712 return "add{l}\t{%k0, %k0|%k0, %k0}";
10718 if (REG_P (operands[2]))
10719 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10720 else if (operands[2] == const1_rtx
10721 && (TARGET_SHIFT1 || optimize_size))
10722 return "sal{l}\t%k0";
10724 return "sal{l}\t{%2, %k0|%k0, %2}";
10727 [(set (attr "type")
10728 (cond [(eq_attr "alternative" "1")
10729 (const_string "lea")
10730 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10732 (match_operand 2 "const1_operand" ""))
10733 (const_string "alu")
10735 (const_string "ishift")))
10736 (set_attr "mode" "SI")])
10738 ;; Convert lea to the lea pattern to avoid flags dependency.
10740 [(set (match_operand:DI 0 "register_operand" "")
10741 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10742 (match_operand:QI 2 "const_int_operand" ""))))
10743 (clobber (reg:CC FLAGS_REG))]
10744 "TARGET_64BIT && reload_completed
10745 && true_regnum (operands[0]) != true_regnum (operands[1])"
10746 [(set (match_dup 0) (zero_extend:DI
10747 (subreg:SI (mult:SI (match_dup 1)
10748 (match_dup 2)) 0)))]
10750 operands[1] = gen_lowpart (Pmode, operands[1]);
10751 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10754 ;; This pattern can't accept a variable shift count, since shifts by
10755 ;; zero don't affect the flags. We assume that shifts by constant
10756 ;; zero are optimized away.
10757 (define_insn "*ashlsi3_cmp"
10758 [(set (reg FLAGS_REG)
10760 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10761 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10763 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10764 (ashift:SI (match_dup 1) (match_dup 2)))]
10765 "ix86_match_ccmode (insn, CCGOCmode)
10766 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10768 || !TARGET_PARTIAL_FLAG_REG_STALL
10769 || (operands[2] == const1_rtx
10771 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10773 switch (get_attr_type (insn))
10776 gcc_assert (operands[2] == const1_rtx);
10777 return "add{l}\t{%0, %0|%0, %0}";
10780 if (REG_P (operands[2]))
10781 return "sal{l}\t{%b2, %0|%0, %b2}";
10782 else if (operands[2] == const1_rtx
10783 && (TARGET_SHIFT1 || optimize_size))
10784 return "sal{l}\t%0";
10786 return "sal{l}\t{%2, %0|%0, %2}";
10789 [(set (attr "type")
10790 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10792 (match_operand 0 "register_operand" ""))
10793 (match_operand 2 "const1_operand" ""))
10794 (const_string "alu")
10796 (const_string "ishift")))
10797 (set_attr "mode" "SI")])
10799 (define_insn "*ashlsi3_cconly"
10800 [(set (reg FLAGS_REG)
10802 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10803 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10805 (clobber (match_scratch:SI 0 "=r"))]
10806 "ix86_match_ccmode (insn, CCGOCmode)
10807 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10809 || !TARGET_PARTIAL_FLAG_REG_STALL
10810 || (operands[2] == const1_rtx
10812 || TARGET_DOUBLE_WITH_ADD)))"
10814 switch (get_attr_type (insn))
10817 gcc_assert (operands[2] == const1_rtx);
10818 return "add{l}\t{%0, %0|%0, %0}";
10821 if (REG_P (operands[2]))
10822 return "sal{l}\t{%b2, %0|%0, %b2}";
10823 else if (operands[2] == const1_rtx
10824 && (TARGET_SHIFT1 || optimize_size))
10825 return "sal{l}\t%0";
10827 return "sal{l}\t{%2, %0|%0, %2}";
10830 [(set (attr "type")
10831 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10833 (match_operand 0 "register_operand" ""))
10834 (match_operand 2 "const1_operand" ""))
10835 (const_string "alu")
10837 (const_string "ishift")))
10838 (set_attr "mode" "SI")])
10840 (define_insn "*ashlsi3_cmp_zext"
10841 [(set (reg FLAGS_REG)
10843 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10844 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10846 (set (match_operand:DI 0 "register_operand" "=r")
10847 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10848 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10849 && ix86_binary_operator_ok (ASHIFT, SImode, operands)
10851 || !TARGET_PARTIAL_FLAG_REG_STALL
10852 || (operands[2] == const1_rtx
10854 || TARGET_DOUBLE_WITH_ADD)))"
10856 switch (get_attr_type (insn))
10859 gcc_assert (operands[2] == const1_rtx);
10860 return "add{l}\t{%k0, %k0|%k0, %k0}";
10863 if (REG_P (operands[2]))
10864 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10865 else if (operands[2] == const1_rtx
10866 && (TARGET_SHIFT1 || optimize_size))
10867 return "sal{l}\t%k0";
10869 return "sal{l}\t{%2, %k0|%k0, %2}";
10872 [(set (attr "type")
10873 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10875 (match_operand 2 "const1_operand" ""))
10876 (const_string "alu")
10878 (const_string "ishift")))
10879 (set_attr "mode" "SI")])
10881 (define_expand "ashlhi3"
10882 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10883 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10884 (match_operand:QI 2 "nonmemory_operand" "")))
10885 (clobber (reg:CC FLAGS_REG))]
10886 "TARGET_HIMODE_MATH"
10887 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10889 (define_insn "*ashlhi3_1_lea"
10890 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10891 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10892 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10893 (clobber (reg:CC FLAGS_REG))]
10894 "!TARGET_PARTIAL_REG_STALL
10895 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10897 switch (get_attr_type (insn))
10902 gcc_assert (operands[2] == const1_rtx);
10903 return "add{w}\t{%0, %0|%0, %0}";
10906 if (REG_P (operands[2]))
10907 return "sal{w}\t{%b2, %0|%0, %b2}";
10908 else if (operands[2] == const1_rtx
10909 && (TARGET_SHIFT1 || optimize_size))
10910 return "sal{w}\t%0";
10912 return "sal{w}\t{%2, %0|%0, %2}";
10915 [(set (attr "type")
10916 (cond [(eq_attr "alternative" "1")
10917 (const_string "lea")
10918 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10920 (match_operand 0 "register_operand" ""))
10921 (match_operand 2 "const1_operand" ""))
10922 (const_string "alu")
10924 (const_string "ishift")))
10925 (set_attr "mode" "HI,SI")])
10927 (define_insn "*ashlhi3_1"
10928 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10929 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10930 (match_operand:QI 2 "nonmemory_operand" "cI")))
10931 (clobber (reg:CC FLAGS_REG))]
10932 "TARGET_PARTIAL_REG_STALL
10933 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10935 switch (get_attr_type (insn))
10938 gcc_assert (operands[2] == const1_rtx);
10939 return "add{w}\t{%0, %0|%0, %0}";
10942 if (REG_P (operands[2]))
10943 return "sal{w}\t{%b2, %0|%0, %b2}";
10944 else if (operands[2] == const1_rtx
10945 && (TARGET_SHIFT1 || optimize_size))
10946 return "sal{w}\t%0";
10948 return "sal{w}\t{%2, %0|%0, %2}";
10951 [(set (attr "type")
10952 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10954 (match_operand 0 "register_operand" ""))
10955 (match_operand 2 "const1_operand" ""))
10956 (const_string "alu")
10958 (const_string "ishift")))
10959 (set_attr "mode" "HI")])
10961 ;; This pattern can't accept a variable shift count, since shifts by
10962 ;; zero don't affect the flags. We assume that shifts by constant
10963 ;; zero are optimized away.
10964 (define_insn "*ashlhi3_cmp"
10965 [(set (reg FLAGS_REG)
10967 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10968 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10970 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10971 (ashift:HI (match_dup 1) (match_dup 2)))]
10972 "ix86_match_ccmode (insn, CCGOCmode)
10973 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
10975 || !TARGET_PARTIAL_FLAG_REG_STALL
10976 || (operands[2] == const1_rtx
10978 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10980 switch (get_attr_type (insn))
10983 gcc_assert (operands[2] == const1_rtx);
10984 return "add{w}\t{%0, %0|%0, %0}";
10987 if (REG_P (operands[2]))
10988 return "sal{w}\t{%b2, %0|%0, %b2}";
10989 else if (operands[2] == const1_rtx
10990 && (TARGET_SHIFT1 || optimize_size))
10991 return "sal{w}\t%0";
10993 return "sal{w}\t{%2, %0|%0, %2}";
10996 [(set (attr "type")
10997 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10999 (match_operand 0 "register_operand" ""))
11000 (match_operand 2 "const1_operand" ""))
11001 (const_string "alu")
11003 (const_string "ishift")))
11004 (set_attr "mode" "HI")])
11006 (define_insn "*ashlhi3_cconly"
11007 [(set (reg FLAGS_REG)
11009 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11010 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11012 (clobber (match_scratch:HI 0 "=r"))]
11013 "ix86_match_ccmode (insn, CCGOCmode)
11014 && ix86_binary_operator_ok (ASHIFT, HImode, operands)
11016 || !TARGET_PARTIAL_FLAG_REG_STALL
11017 || (operands[2] == const1_rtx
11019 || TARGET_DOUBLE_WITH_ADD)))"
11021 switch (get_attr_type (insn))
11024 gcc_assert (operands[2] == const1_rtx);
11025 return "add{w}\t{%0, %0|%0, %0}";
11028 if (REG_P (operands[2]))
11029 return "sal{w}\t{%b2, %0|%0, %b2}";
11030 else if (operands[2] == const1_rtx
11031 && (TARGET_SHIFT1 || optimize_size))
11032 return "sal{w}\t%0";
11034 return "sal{w}\t{%2, %0|%0, %2}";
11037 [(set (attr "type")
11038 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11040 (match_operand 0 "register_operand" ""))
11041 (match_operand 2 "const1_operand" ""))
11042 (const_string "alu")
11044 (const_string "ishift")))
11045 (set_attr "mode" "HI")])
11047 (define_expand "ashlqi3"
11048 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11049 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11050 (match_operand:QI 2 "nonmemory_operand" "")))
11051 (clobber (reg:CC FLAGS_REG))]
11052 "TARGET_QIMODE_MATH"
11053 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11055 ;; %%% Potential partial reg stall on alternative 2. What to do?
11057 (define_insn "*ashlqi3_1_lea"
11058 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11059 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11060 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11061 (clobber (reg:CC FLAGS_REG))]
11062 "!TARGET_PARTIAL_REG_STALL
11063 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11065 switch (get_attr_type (insn))
11070 gcc_assert (operands[2] == const1_rtx);
11071 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11072 return "add{l}\t{%k0, %k0|%k0, %k0}";
11074 return "add{b}\t{%0, %0|%0, %0}";
11077 if (REG_P (operands[2]))
11079 if (get_attr_mode (insn) == MODE_SI)
11080 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11082 return "sal{b}\t{%b2, %0|%0, %b2}";
11084 else if (operands[2] == const1_rtx
11085 && (TARGET_SHIFT1 || optimize_size))
11087 if (get_attr_mode (insn) == MODE_SI)
11088 return "sal{l}\t%0";
11090 return "sal{b}\t%0";
11094 if (get_attr_mode (insn) == MODE_SI)
11095 return "sal{l}\t{%2, %k0|%k0, %2}";
11097 return "sal{b}\t{%2, %0|%0, %2}";
11101 [(set (attr "type")
11102 (cond [(eq_attr "alternative" "2")
11103 (const_string "lea")
11104 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11106 (match_operand 0 "register_operand" ""))
11107 (match_operand 2 "const1_operand" ""))
11108 (const_string "alu")
11110 (const_string "ishift")))
11111 (set_attr "mode" "QI,SI,SI")])
11113 (define_insn "*ashlqi3_1"
11114 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11115 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11116 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11117 (clobber (reg:CC FLAGS_REG))]
11118 "TARGET_PARTIAL_REG_STALL
11119 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11121 switch (get_attr_type (insn))
11124 gcc_assert (operands[2] == const1_rtx);
11125 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11126 return "add{l}\t{%k0, %k0|%k0, %k0}";
11128 return "add{b}\t{%0, %0|%0, %0}";
11131 if (REG_P (operands[2]))
11133 if (get_attr_mode (insn) == MODE_SI)
11134 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11136 return "sal{b}\t{%b2, %0|%0, %b2}";
11138 else if (operands[2] == const1_rtx
11139 && (TARGET_SHIFT1 || optimize_size))
11141 if (get_attr_mode (insn) == MODE_SI)
11142 return "sal{l}\t%0";
11144 return "sal{b}\t%0";
11148 if (get_attr_mode (insn) == MODE_SI)
11149 return "sal{l}\t{%2, %k0|%k0, %2}";
11151 return "sal{b}\t{%2, %0|%0, %2}";
11155 [(set (attr "type")
11156 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11158 (match_operand 0 "register_operand" ""))
11159 (match_operand 2 "const1_operand" ""))
11160 (const_string "alu")
11162 (const_string "ishift")))
11163 (set_attr "mode" "QI,SI")])
11165 ;; This pattern can't accept a variable shift count, since shifts by
11166 ;; zero don't affect the flags. We assume that shifts by constant
11167 ;; zero are optimized away.
11168 (define_insn "*ashlqi3_cmp"
11169 [(set (reg FLAGS_REG)
11171 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11172 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11174 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11175 (ashift:QI (match_dup 1) (match_dup 2)))]
11176 "ix86_match_ccmode (insn, CCGOCmode)
11177 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11179 || !TARGET_PARTIAL_FLAG_REG_STALL
11180 || (operands[2] == const1_rtx
11182 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
11184 switch (get_attr_type (insn))
11187 gcc_assert (operands[2] == const1_rtx);
11188 return "add{b}\t{%0, %0|%0, %0}";
11191 if (REG_P (operands[2]))
11192 return "sal{b}\t{%b2, %0|%0, %b2}";
11193 else if (operands[2] == const1_rtx
11194 && (TARGET_SHIFT1 || optimize_size))
11195 return "sal{b}\t%0";
11197 return "sal{b}\t{%2, %0|%0, %2}";
11200 [(set (attr "type")
11201 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11203 (match_operand 0 "register_operand" ""))
11204 (match_operand 2 "const1_operand" ""))
11205 (const_string "alu")
11207 (const_string "ishift")))
11208 (set_attr "mode" "QI")])
11210 (define_insn "*ashlqi3_cconly"
11211 [(set (reg FLAGS_REG)
11213 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11214 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11216 (clobber (match_scratch:QI 0 "=q"))]
11217 "ix86_match_ccmode (insn, CCGOCmode)
11218 && ix86_binary_operator_ok (ASHIFT, QImode, operands)
11220 || !TARGET_PARTIAL_FLAG_REG_STALL
11221 || (operands[2] == const1_rtx
11223 || TARGET_DOUBLE_WITH_ADD)))"
11225 switch (get_attr_type (insn))
11228 gcc_assert (operands[2] == const1_rtx);
11229 return "add{b}\t{%0, %0|%0, %0}";
11232 if (REG_P (operands[2]))
11233 return "sal{b}\t{%b2, %0|%0, %b2}";
11234 else if (operands[2] == const1_rtx
11235 && (TARGET_SHIFT1 || optimize_size))
11236 return "sal{b}\t%0";
11238 return "sal{b}\t{%2, %0|%0, %2}";
11241 [(set (attr "type")
11242 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11244 (match_operand 0 "register_operand" ""))
11245 (match_operand 2 "const1_operand" ""))
11246 (const_string "alu")
11248 (const_string "ishift")))
11249 (set_attr "mode" "QI")])
11251 ;; See comment above `ashldi3' about how this works.
11253 (define_expand "ashrti3"
11254 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11255 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11256 (match_operand:QI 2 "nonmemory_operand" "")))
11257 (clobber (reg:CC FLAGS_REG))])]
11260 if (! immediate_operand (operands[2], QImode))
11262 emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11265 ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11269 (define_insn "ashrti3_1"
11270 [(set (match_operand:TI 0 "register_operand" "=r")
11271 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11272 (match_operand:QI 2 "register_operand" "c")))
11273 (clobber (match_scratch:DI 3 "=&r"))
11274 (clobber (reg:CC FLAGS_REG))]
11277 [(set_attr "type" "multi")])
11279 (define_insn "*ashrti3_2"
11280 [(set (match_operand:TI 0 "register_operand" "=r")
11281 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11282 (match_operand:QI 2 "immediate_operand" "O")))
11283 (clobber (reg:CC FLAGS_REG))]
11286 [(set_attr "type" "multi")])
11289 [(set (match_operand:TI 0 "register_operand" "")
11290 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11291 (match_operand:QI 2 "register_operand" "")))
11292 (clobber (match_scratch:DI 3 ""))
11293 (clobber (reg:CC FLAGS_REG))]
11294 "TARGET_64BIT && reload_completed"
11296 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11299 [(set (match_operand:TI 0 "register_operand" "")
11300 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11301 (match_operand:QI 2 "immediate_operand" "")))
11302 (clobber (reg:CC FLAGS_REG))]
11303 "TARGET_64BIT && reload_completed"
11305 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11307 (define_insn "x86_64_shrd"
11308 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11309 (ior:DI (ashiftrt:DI (match_dup 0)
11310 (match_operand:QI 2 "nonmemory_operand" "J,c"))
11311 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11312 (minus:QI (const_int 64) (match_dup 2)))))
11313 (clobber (reg:CC FLAGS_REG))]
11316 shrd{q}\t{%2, %1, %0|%0, %1, %2}
11317 shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11318 [(set_attr "type" "ishift")
11319 (set_attr "prefix_0f" "1")
11320 (set_attr "mode" "DI")
11321 (set_attr "athlon_decode" "vector")])
11323 (define_expand "ashrdi3"
11324 [(set (match_operand:DI 0 "shiftdi_operand" "")
11325 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11326 (match_operand:QI 2 "nonmemory_operand" "")))]
11328 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11330 (define_insn "*ashrdi3_63_rex64"
11331 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11332 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11333 (match_operand:DI 2 "const_int_operand" "i,i")))
11334 (clobber (reg:CC FLAGS_REG))]
11335 "TARGET_64BIT && INTVAL (operands[2]) == 63
11336 && (TARGET_USE_CLTD || optimize_size)
11337 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11340 sar{q}\t{%2, %0|%0, %2}"
11341 [(set_attr "type" "imovx,ishift")
11342 (set_attr "prefix_0f" "0,*")
11343 (set_attr "length_immediate" "0,*")
11344 (set_attr "modrm" "0,1")
11345 (set_attr "mode" "DI")])
11347 (define_insn "*ashrdi3_1_one_bit_rex64"
11348 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11349 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11350 (match_operand:QI 2 "const1_operand" "")))
11351 (clobber (reg:CC FLAGS_REG))]
11352 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11353 && (TARGET_SHIFT1 || optimize_size)"
11355 [(set_attr "type" "ishift")
11356 (set (attr "length")
11357 (if_then_else (match_operand:DI 0 "register_operand" "")
11359 (const_string "*")))])
11361 (define_insn "*ashrdi3_1_rex64"
11362 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11363 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11364 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11365 (clobber (reg:CC FLAGS_REG))]
11366 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11368 sar{q}\t{%2, %0|%0, %2}
11369 sar{q}\t{%b2, %0|%0, %b2}"
11370 [(set_attr "type" "ishift")
11371 (set_attr "mode" "DI")])
11373 ;; This pattern can't accept a variable shift count, since shifts by
11374 ;; zero don't affect the flags. We assume that shifts by constant
11375 ;; zero are optimized away.
11376 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11377 [(set (reg FLAGS_REG)
11379 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11380 (match_operand:QI 2 "const1_operand" ""))
11382 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11383 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11384 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11385 && (TARGET_SHIFT1 || optimize_size)
11386 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11388 [(set_attr "type" "ishift")
11389 (set (attr "length")
11390 (if_then_else (match_operand:DI 0 "register_operand" "")
11392 (const_string "*")))])
11394 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11395 [(set (reg FLAGS_REG)
11397 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11398 (match_operand:QI 2 "const1_operand" ""))
11400 (clobber (match_scratch:DI 0 "=r"))]
11401 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11402 && (TARGET_SHIFT1 || optimize_size)
11403 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11405 [(set_attr "type" "ishift")
11406 (set_attr "length" "2")])
11408 ;; This pattern can't accept a variable shift count, since shifts by
11409 ;; zero don't affect the flags. We assume that shifts by constant
11410 ;; zero are optimized away.
11411 (define_insn "*ashrdi3_cmp_rex64"
11412 [(set (reg FLAGS_REG)
11414 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11415 (match_operand:QI 2 "const_int_operand" "n"))
11417 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11418 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11419 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11420 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11422 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11423 "sar{q}\t{%2, %0|%0, %2}"
11424 [(set_attr "type" "ishift")
11425 (set_attr "mode" "DI")])
11427 (define_insn "*ashrdi3_cconly_rex64"
11428 [(set (reg FLAGS_REG)
11430 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11431 (match_operand:QI 2 "const_int_operand" "n"))
11433 (clobber (match_scratch:DI 0 "=r"))]
11434 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11435 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)
11437 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11438 "sar{q}\t{%2, %0|%0, %2}"
11439 [(set_attr "type" "ishift")
11440 (set_attr "mode" "DI")])
11442 (define_insn "*ashrdi3_1"
11443 [(set (match_operand:DI 0 "register_operand" "=r")
11444 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11445 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11446 (clobber (reg:CC FLAGS_REG))]
11449 [(set_attr "type" "multi")])
11451 ;; By default we don't ask for a scratch register, because when DImode
11452 ;; values are manipulated, registers are already at a premium. But if
11453 ;; we have one handy, we won't turn it away.
11455 [(match_scratch:SI 3 "r")
11456 (parallel [(set (match_operand:DI 0 "register_operand" "")
11457 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11458 (match_operand:QI 2 "nonmemory_operand" "")))
11459 (clobber (reg:CC FLAGS_REG))])
11461 "!TARGET_64BIT && TARGET_CMOVE"
11463 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11466 [(set (match_operand:DI 0 "register_operand" "")
11467 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11468 (match_operand:QI 2 "nonmemory_operand" "")))
11469 (clobber (reg:CC FLAGS_REG))]
11470 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11471 ? flow2_completed : reload_completed)"
11473 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11475 (define_insn "x86_shrd_1"
11476 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11477 (ior:SI (ashiftrt:SI (match_dup 0)
11478 (match_operand:QI 2 "nonmemory_operand" "I,c"))
11479 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
11480 (minus:QI (const_int 32) (match_dup 2)))))
11481 (clobber (reg:CC FLAGS_REG))]
11484 shrd{l}\t{%2, %1, %0|%0, %1, %2}
11485 shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11486 [(set_attr "type" "ishift")
11487 (set_attr "prefix_0f" "1")
11488 (set_attr "pent_pair" "np")
11489 (set_attr "mode" "SI")])
11491 (define_expand "x86_shift_adj_3"
11492 [(use (match_operand:SI 0 "register_operand" ""))
11493 (use (match_operand:SI 1 "register_operand" ""))
11494 (use (match_operand:QI 2 "register_operand" ""))]
11497 rtx label = gen_label_rtx ();
11500 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11502 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11503 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11504 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11505 gen_rtx_LABEL_REF (VOIDmode, label),
11507 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11508 JUMP_LABEL (tmp) = label;
11510 emit_move_insn (operands[0], operands[1]);
11511 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11513 emit_label (label);
11514 LABEL_NUSES (label) = 1;
11519 (define_insn "ashrsi3_31"
11520 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11521 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11522 (match_operand:SI 2 "const_int_operand" "i,i")))
11523 (clobber (reg:CC FLAGS_REG))]
11524 "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
11525 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11528 sar{l}\t{%2, %0|%0, %2}"
11529 [(set_attr "type" "imovx,ishift")
11530 (set_attr "prefix_0f" "0,*")
11531 (set_attr "length_immediate" "0,*")
11532 (set_attr "modrm" "0,1")
11533 (set_attr "mode" "SI")])
11535 (define_insn "*ashrsi3_31_zext"
11536 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11537 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11538 (match_operand:SI 2 "const_int_operand" "i,i"))))
11539 (clobber (reg:CC FLAGS_REG))]
11540 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
11541 && INTVAL (operands[2]) == 31
11542 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11545 sar{l}\t{%2, %k0|%k0, %2}"
11546 [(set_attr "type" "imovx,ishift")
11547 (set_attr "prefix_0f" "0,*")
11548 (set_attr "length_immediate" "0,*")
11549 (set_attr "modrm" "0,1")
11550 (set_attr "mode" "SI")])
11552 (define_expand "ashrsi3"
11553 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11554 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11555 (match_operand:QI 2 "nonmemory_operand" "")))
11556 (clobber (reg:CC FLAGS_REG))]
11558 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11560 (define_insn "*ashrsi3_1_one_bit"
11561 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11562 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11563 (match_operand:QI 2 "const1_operand" "")))
11564 (clobber (reg:CC FLAGS_REG))]
11565 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11566 && (TARGET_SHIFT1 || optimize_size)"
11568 [(set_attr "type" "ishift")
11569 (set (attr "length")
11570 (if_then_else (match_operand:SI 0 "register_operand" "")
11572 (const_string "*")))])
11574 (define_insn "*ashrsi3_1_one_bit_zext"
11575 [(set (match_operand:DI 0 "register_operand" "=r")
11576 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11577 (match_operand:QI 2 "const1_operand" ""))))
11578 (clobber (reg:CC FLAGS_REG))]
11579 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11580 && (TARGET_SHIFT1 || optimize_size)"
11582 [(set_attr "type" "ishift")
11583 (set_attr "length" "2")])
11585 (define_insn "*ashrsi3_1"
11586 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11587 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11588 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11589 (clobber (reg:CC FLAGS_REG))]
11590 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11592 sar{l}\t{%2, %0|%0, %2}
11593 sar{l}\t{%b2, %0|%0, %b2}"
11594 [(set_attr "type" "ishift")
11595 (set_attr "mode" "SI")])
11597 (define_insn "*ashrsi3_1_zext"
11598 [(set (match_operand:DI 0 "register_operand" "=r,r")
11599 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11600 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11601 (clobber (reg:CC FLAGS_REG))]
11602 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11604 sar{l}\t{%2, %k0|%k0, %2}
11605 sar{l}\t{%b2, %k0|%k0, %b2}"
11606 [(set_attr "type" "ishift")
11607 (set_attr "mode" "SI")])
11609 ;; This pattern can't accept a variable shift count, since shifts by
11610 ;; zero don't affect the flags. We assume that shifts by constant
11611 ;; zero are optimized away.
11612 (define_insn "*ashrsi3_one_bit_cmp"
11613 [(set (reg FLAGS_REG)
11615 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11616 (match_operand:QI 2 "const1_operand" ""))
11618 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11619 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11620 "ix86_match_ccmode (insn, CCGOCmode)
11621 && (TARGET_SHIFT1 || optimize_size)
11622 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11624 [(set_attr "type" "ishift")
11625 (set (attr "length")
11626 (if_then_else (match_operand:SI 0 "register_operand" "")
11628 (const_string "*")))])
11630 (define_insn "*ashrsi3_one_bit_cconly"
11631 [(set (reg FLAGS_REG)
11633 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11634 (match_operand:QI 2 "const1_operand" ""))
11636 (clobber (match_scratch:SI 0 "=r"))]
11637 "ix86_match_ccmode (insn, CCGOCmode)
11638 && (TARGET_SHIFT1 || optimize_size)
11639 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11641 [(set_attr "type" "ishift")
11642 (set_attr "length" "2")])
11644 (define_insn "*ashrsi3_one_bit_cmp_zext"
11645 [(set (reg FLAGS_REG)
11647 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11648 (match_operand:QI 2 "const1_operand" ""))
11650 (set (match_operand:DI 0 "register_operand" "=r")
11651 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11652 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
11653 && (TARGET_SHIFT1 || optimize_size)
11654 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11656 [(set_attr "type" "ishift")
11657 (set_attr "length" "2")])
11659 ;; This pattern can't accept a variable shift count, since shifts by
11660 ;; zero don't affect the flags. We assume that shifts by constant
11661 ;; zero are optimized away.
11662 (define_insn "*ashrsi3_cmp"
11663 [(set (reg FLAGS_REG)
11665 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11666 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11668 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11669 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11670 "ix86_match_ccmode (insn, CCGOCmode)
11671 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11673 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11674 "sar{l}\t{%2, %0|%0, %2}"
11675 [(set_attr "type" "ishift")
11676 (set_attr "mode" "SI")])
11678 (define_insn "*ashrsi3_cconly"
11679 [(set (reg FLAGS_REG)
11681 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11682 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11684 (clobber (match_scratch:SI 0 "=r"))]
11685 "ix86_match_ccmode (insn, CCGOCmode)
11686 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11688 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11689 "sar{l}\t{%2, %0|%0, %2}"
11690 [(set_attr "type" "ishift")
11691 (set_attr "mode" "SI")])
11693 (define_insn "*ashrsi3_cmp_zext"
11694 [(set (reg FLAGS_REG)
11696 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11697 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11699 (set (match_operand:DI 0 "register_operand" "=r")
11700 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11701 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
11702 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)
11704 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11705 "sar{l}\t{%2, %k0|%k0, %2}"
11706 [(set_attr "type" "ishift")
11707 (set_attr "mode" "SI")])
11709 (define_expand "ashrhi3"
11710 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11711 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11712 (match_operand:QI 2 "nonmemory_operand" "")))
11713 (clobber (reg:CC FLAGS_REG))]
11714 "TARGET_HIMODE_MATH"
11715 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11717 (define_insn "*ashrhi3_1_one_bit"
11718 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11719 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11720 (match_operand:QI 2 "const1_operand" "")))
11721 (clobber (reg:CC FLAGS_REG))]
11722 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11723 && (TARGET_SHIFT1 || optimize_size)"
11725 [(set_attr "type" "ishift")
11726 (set (attr "length")
11727 (if_then_else (match_operand 0 "register_operand" "")
11729 (const_string "*")))])
11731 (define_insn "*ashrhi3_1"
11732 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11733 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11734 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11735 (clobber (reg:CC FLAGS_REG))]
11736 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11738 sar{w}\t{%2, %0|%0, %2}
11739 sar{w}\t{%b2, %0|%0, %b2}"
11740 [(set_attr "type" "ishift")
11741 (set_attr "mode" "HI")])
11743 ;; This pattern can't accept a variable shift count, since shifts by
11744 ;; zero don't affect the flags. We assume that shifts by constant
11745 ;; zero are optimized away.
11746 (define_insn "*ashrhi3_one_bit_cmp"
11747 [(set (reg FLAGS_REG)
11749 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11750 (match_operand:QI 2 "const1_operand" ""))
11752 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11753 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11754 "ix86_match_ccmode (insn, CCGOCmode)
11755 && (TARGET_SHIFT1 || optimize_size)
11756 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11758 [(set_attr "type" "ishift")
11759 (set (attr "length")
11760 (if_then_else (match_operand 0 "register_operand" "")
11762 (const_string "*")))])
11764 (define_insn "*ashrhi3_one_bit_cconly"
11765 [(set (reg FLAGS_REG)
11767 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11768 (match_operand:QI 2 "const1_operand" ""))
11770 (clobber (match_scratch:HI 0 "=r"))]
11771 "ix86_match_ccmode (insn, CCGOCmode)
11772 && (TARGET_SHIFT1 || optimize_size)
11773 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11775 [(set_attr "type" "ishift")
11776 (set_attr "length" "2")])
11778 ;; This pattern can't accept a variable shift count, since shifts by
11779 ;; zero don't affect the flags. We assume that shifts by constant
11780 ;; zero are optimized away.
11781 (define_insn "*ashrhi3_cmp"
11782 [(set (reg FLAGS_REG)
11784 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11785 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11787 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11788 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11789 "ix86_match_ccmode (insn, CCGOCmode)
11790 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11792 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11793 "sar{w}\t{%2, %0|%0, %2}"
11794 [(set_attr "type" "ishift")
11795 (set_attr "mode" "HI")])
11797 (define_insn "*ashrhi3_cconly"
11798 [(set (reg FLAGS_REG)
11800 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11801 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11803 (clobber (match_scratch:HI 0 "=r"))]
11804 "ix86_match_ccmode (insn, CCGOCmode)
11805 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)
11807 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11808 "sar{w}\t{%2, %0|%0, %2}"
11809 [(set_attr "type" "ishift")
11810 (set_attr "mode" "HI")])
11812 (define_expand "ashrqi3"
11813 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11814 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11815 (match_operand:QI 2 "nonmemory_operand" "")))
11816 (clobber (reg:CC FLAGS_REG))]
11817 "TARGET_QIMODE_MATH"
11818 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11820 (define_insn "*ashrqi3_1_one_bit"
11821 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11822 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11823 (match_operand:QI 2 "const1_operand" "")))
11824 (clobber (reg:CC FLAGS_REG))]
11825 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11826 && (TARGET_SHIFT1 || optimize_size)"
11828 [(set_attr "type" "ishift")
11829 (set (attr "length")
11830 (if_then_else (match_operand 0 "register_operand" "")
11832 (const_string "*")))])
11834 (define_insn "*ashrqi3_1_one_bit_slp"
11835 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11836 (ashiftrt:QI (match_dup 0)
11837 (match_operand:QI 1 "const1_operand" "")))
11838 (clobber (reg:CC FLAGS_REG))]
11839 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11840 && (! TARGET_PARTIAL_REG_STALL || optimize_size)
11841 && (TARGET_SHIFT1 || optimize_size)"
11843 [(set_attr "type" "ishift1")
11844 (set (attr "length")
11845 (if_then_else (match_operand 0 "register_operand" "")
11847 (const_string "*")))])
11849 (define_insn "*ashrqi3_1"
11850 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11851 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11852 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11853 (clobber (reg:CC FLAGS_REG))]
11854 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11856 sar{b}\t{%2, %0|%0, %2}
11857 sar{b}\t{%b2, %0|%0, %b2}"
11858 [(set_attr "type" "ishift")
11859 (set_attr "mode" "QI")])
11861 (define_insn "*ashrqi3_1_slp"
11862 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11863 (ashiftrt:QI (match_dup 0)
11864 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11865 (clobber (reg:CC FLAGS_REG))]
11866 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
11867 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
11869 sar{b}\t{%1, %0|%0, %1}
11870 sar{b}\t{%b1, %0|%0, %b1}"
11871 [(set_attr "type" "ishift1")
11872 (set_attr "mode" "QI")])
11874 ;; This pattern can't accept a variable shift count, since shifts by
11875 ;; zero don't affect the flags. We assume that shifts by constant
11876 ;; zero are optimized away.
11877 (define_insn "*ashrqi3_one_bit_cmp"
11878 [(set (reg FLAGS_REG)
11880 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11881 (match_operand:QI 2 "const1_operand" "I"))
11883 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11884 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11885 "ix86_match_ccmode (insn, CCGOCmode)
11886 && (TARGET_SHIFT1 || optimize_size)
11887 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11889 [(set_attr "type" "ishift")
11890 (set (attr "length")
11891 (if_then_else (match_operand 0 "register_operand" "")
11893 (const_string "*")))])
11895 (define_insn "*ashrqi3_one_bit_cconly"
11896 [(set (reg FLAGS_REG)
11898 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11899 (match_operand:QI 2 "const1_operand" "I"))
11901 (clobber (match_scratch:QI 0 "=q"))]
11902 "ix86_match_ccmode (insn, CCGOCmode)
11903 && (TARGET_SHIFT1 || optimize_size)
11904 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11906 [(set_attr "type" "ishift")
11907 (set_attr "length" "2")])
11909 ;; This pattern can't accept a variable shift count, since shifts by
11910 ;; zero don't affect the flags. We assume that shifts by constant
11911 ;; zero are optimized away.
11912 (define_insn "*ashrqi3_cmp"
11913 [(set (reg FLAGS_REG)
11915 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11916 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11918 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11919 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11920 "ix86_match_ccmode (insn, CCGOCmode)
11921 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11923 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11924 "sar{b}\t{%2, %0|%0, %2}"
11925 [(set_attr "type" "ishift")
11926 (set_attr "mode" "QI")])
11928 (define_insn "*ashrqi3_cconly"
11929 [(set (reg FLAGS_REG)
11931 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11932 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11934 (clobber (match_scratch:QI 0 "=q"))]
11935 "ix86_match_ccmode (insn, CCGOCmode)
11936 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)
11938 || !TARGET_PARTIAL_FLAG_REG_STALL)"
11939 "sar{b}\t{%2, %0|%0, %2}"
11940 [(set_attr "type" "ishift")
11941 (set_attr "mode" "QI")])
11944 ;; Logical shift instructions
11946 ;; See comment above `ashldi3' about how this works.
11948 (define_expand "lshrti3"
11949 [(parallel [(set (match_operand:TI 0 "register_operand" "")
11950 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11951 (match_operand:QI 2 "nonmemory_operand" "")))
11952 (clobber (reg:CC FLAGS_REG))])]
11955 if (! immediate_operand (operands[2], QImode))
11957 emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
11960 ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
11964 (define_insn "lshrti3_1"
11965 [(set (match_operand:TI 0 "register_operand" "=r")
11966 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11967 (match_operand:QI 2 "register_operand" "c")))
11968 (clobber (match_scratch:DI 3 "=&r"))
11969 (clobber (reg:CC FLAGS_REG))]
11972 [(set_attr "type" "multi")])
11974 (define_insn "*lshrti3_2"
11975 [(set (match_operand:TI 0 "register_operand" "=r")
11976 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11977 (match_operand:QI 2 "immediate_operand" "O")))
11978 (clobber (reg:CC FLAGS_REG))]
11981 [(set_attr "type" "multi")])
11984 [(set (match_operand:TI 0 "register_operand" "")
11985 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11986 (match_operand:QI 2 "register_operand" "")))
11987 (clobber (match_scratch:DI 3 ""))
11988 (clobber (reg:CC FLAGS_REG))]
11989 "TARGET_64BIT && reload_completed"
11991 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11994 [(set (match_operand:TI 0 "register_operand" "")
11995 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11996 (match_operand:QI 2 "immediate_operand" "")))
11997 (clobber (reg:CC FLAGS_REG))]
11998 "TARGET_64BIT && reload_completed"
12000 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12002 (define_expand "lshrdi3"
12003 [(set (match_operand:DI 0 "shiftdi_operand" "")
12004 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12005 (match_operand:QI 2 "nonmemory_operand" "")))]
12007 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12009 (define_insn "*lshrdi3_1_one_bit_rex64"
12010 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12011 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12012 (match_operand:QI 2 "const1_operand" "")))
12013 (clobber (reg:CC FLAGS_REG))]
12014 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12015 && (TARGET_SHIFT1 || optimize_size)"
12017 [(set_attr "type" "ishift")
12018 (set (attr "length")
12019 (if_then_else (match_operand:DI 0 "register_operand" "")
12021 (const_string "*")))])
12023 (define_insn "*lshrdi3_1_rex64"
12024 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12025 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12026 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12027 (clobber (reg:CC FLAGS_REG))]
12028 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12030 shr{q}\t{%2, %0|%0, %2}
12031 shr{q}\t{%b2, %0|%0, %b2}"
12032 [(set_attr "type" "ishift")
12033 (set_attr "mode" "DI")])
12035 ;; This pattern can't accept a variable shift count, since shifts by
12036 ;; zero don't affect the flags. We assume that shifts by constant
12037 ;; zero are optimized away.
12038 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12039 [(set (reg FLAGS_REG)
12041 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12042 (match_operand:QI 2 "const1_operand" ""))
12044 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12045 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12046 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12047 && (TARGET_SHIFT1 || optimize_size)
12048 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12050 [(set_attr "type" "ishift")
12051 (set (attr "length")
12052 (if_then_else (match_operand:DI 0 "register_operand" "")
12054 (const_string "*")))])
12056 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12057 [(set (reg FLAGS_REG)
12059 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12060 (match_operand:QI 2 "const1_operand" ""))
12062 (clobber (match_scratch:DI 0 "=r"))]
12063 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12064 && (TARGET_SHIFT1 || optimize_size)
12065 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12067 [(set_attr "type" "ishift")
12068 (set_attr "length" "2")])
12070 ;; This pattern can't accept a variable shift count, since shifts by
12071 ;; zero don't affect the flags. We assume that shifts by constant
12072 ;; zero are optimized away.
12073 (define_insn "*lshrdi3_cmp_rex64"
12074 [(set (reg FLAGS_REG)
12076 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12077 (match_operand:QI 2 "const_int_operand" "e"))
12079 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12080 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12081 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12082 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12084 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12085 "shr{q}\t{%2, %0|%0, %2}"
12086 [(set_attr "type" "ishift")
12087 (set_attr "mode" "DI")])
12089 (define_insn "*lshrdi3_cconly_rex64"
12090 [(set (reg FLAGS_REG)
12092 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12093 (match_operand:QI 2 "const_int_operand" "e"))
12095 (clobber (match_scratch:DI 0 "=r"))]
12096 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12097 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12099 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12100 "shr{q}\t{%2, %0|%0, %2}"
12101 [(set_attr "type" "ishift")
12102 (set_attr "mode" "DI")])
12104 (define_insn "*lshrdi3_1"
12105 [(set (match_operand:DI 0 "register_operand" "=r")
12106 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12107 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12108 (clobber (reg:CC FLAGS_REG))]
12111 [(set_attr "type" "multi")])
12113 ;; By default we don't ask for a scratch register, because when DImode
12114 ;; values are manipulated, registers are already at a premium. But if
12115 ;; we have one handy, we won't turn it away.
12117 [(match_scratch:SI 3 "r")
12118 (parallel [(set (match_operand:DI 0 "register_operand" "")
12119 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12120 (match_operand:QI 2 "nonmemory_operand" "")))
12121 (clobber (reg:CC FLAGS_REG))])
12123 "!TARGET_64BIT && TARGET_CMOVE"
12125 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12128 [(set (match_operand:DI 0 "register_operand" "")
12129 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12130 (match_operand:QI 2 "nonmemory_operand" "")))
12131 (clobber (reg:CC FLAGS_REG))]
12132 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12133 ? flow2_completed : reload_completed)"
12135 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12137 (define_expand "lshrsi3"
12138 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12139 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12140 (match_operand:QI 2 "nonmemory_operand" "")))
12141 (clobber (reg:CC FLAGS_REG))]
12143 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12145 (define_insn "*lshrsi3_1_one_bit"
12146 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12147 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12148 (match_operand:QI 2 "const1_operand" "")))
12149 (clobber (reg:CC FLAGS_REG))]
12150 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12151 && (TARGET_SHIFT1 || optimize_size)"
12153 [(set_attr "type" "ishift")
12154 (set (attr "length")
12155 (if_then_else (match_operand:SI 0 "register_operand" "")
12157 (const_string "*")))])
12159 (define_insn "*lshrsi3_1_one_bit_zext"
12160 [(set (match_operand:DI 0 "register_operand" "=r")
12161 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12162 (match_operand:QI 2 "const1_operand" "")))
12163 (clobber (reg:CC FLAGS_REG))]
12164 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12165 && (TARGET_SHIFT1 || optimize_size)"
12167 [(set_attr "type" "ishift")
12168 (set_attr "length" "2")])
12170 (define_insn "*lshrsi3_1"
12171 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12172 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12173 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12174 (clobber (reg:CC FLAGS_REG))]
12175 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12177 shr{l}\t{%2, %0|%0, %2}
12178 shr{l}\t{%b2, %0|%0, %b2}"
12179 [(set_attr "type" "ishift")
12180 (set_attr "mode" "SI")])
12182 (define_insn "*lshrsi3_1_zext"
12183 [(set (match_operand:DI 0 "register_operand" "=r,r")
12185 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12186 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12187 (clobber (reg:CC FLAGS_REG))]
12188 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12190 shr{l}\t{%2, %k0|%k0, %2}
12191 shr{l}\t{%b2, %k0|%k0, %b2}"
12192 [(set_attr "type" "ishift")
12193 (set_attr "mode" "SI")])
12195 ;; This pattern can't accept a variable shift count, since shifts by
12196 ;; zero don't affect the flags. We assume that shifts by constant
12197 ;; zero are optimized away.
12198 (define_insn "*lshrsi3_one_bit_cmp"
12199 [(set (reg FLAGS_REG)
12201 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12202 (match_operand:QI 2 "const1_operand" ""))
12204 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12205 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12206 "ix86_match_ccmode (insn, CCGOCmode)
12207 && (TARGET_SHIFT1 || optimize_size)
12208 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12210 [(set_attr "type" "ishift")
12211 (set (attr "length")
12212 (if_then_else (match_operand:SI 0 "register_operand" "")
12214 (const_string "*")))])
12216 (define_insn "*lshrsi3_one_bit_cconly"
12217 [(set (reg FLAGS_REG)
12219 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12220 (match_operand:QI 2 "const1_operand" ""))
12222 (clobber (match_scratch:SI 0 "=r"))]
12223 "ix86_match_ccmode (insn, CCGOCmode)
12224 && (TARGET_SHIFT1 || optimize_size)
12225 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12227 [(set_attr "type" "ishift")
12228 (set_attr "length" "2")])
12230 (define_insn "*lshrsi3_cmp_one_bit_zext"
12231 [(set (reg FLAGS_REG)
12233 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12234 (match_operand:QI 2 "const1_operand" ""))
12236 (set (match_operand:DI 0 "register_operand" "=r")
12237 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12238 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12239 && (TARGET_SHIFT1 || optimize_size)
12240 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12242 [(set_attr "type" "ishift")
12243 (set_attr "length" "2")])
12245 ;; This pattern can't accept a variable shift count, since shifts by
12246 ;; zero don't affect the flags. We assume that shifts by constant
12247 ;; zero are optimized away.
12248 (define_insn "*lshrsi3_cmp"
12249 [(set (reg FLAGS_REG)
12251 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12252 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12254 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12255 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12256 "ix86_match_ccmode (insn, CCGOCmode)
12257 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12259 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12260 "shr{l}\t{%2, %0|%0, %2}"
12261 [(set_attr "type" "ishift")
12262 (set_attr "mode" "SI")])
12264 (define_insn "*lshrsi3_cconly"
12265 [(set (reg FLAGS_REG)
12267 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12268 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12270 (clobber (match_scratch:SI 0 "=r"))]
12271 "ix86_match_ccmode (insn, CCGOCmode)
12272 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12274 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12275 "shr{l}\t{%2, %0|%0, %2}"
12276 [(set_attr "type" "ishift")
12277 (set_attr "mode" "SI")])
12279 (define_insn "*lshrsi3_cmp_zext"
12280 [(set (reg FLAGS_REG)
12282 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12283 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12285 (set (match_operand:DI 0 "register_operand" "=r")
12286 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12287 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12288 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12290 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12291 "shr{l}\t{%2, %k0|%k0, %2}"
12292 [(set_attr "type" "ishift")
12293 (set_attr "mode" "SI")])
12295 (define_expand "lshrhi3"
12296 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12297 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12298 (match_operand:QI 2 "nonmemory_operand" "")))
12299 (clobber (reg:CC FLAGS_REG))]
12300 "TARGET_HIMODE_MATH"
12301 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12303 (define_insn "*lshrhi3_1_one_bit"
12304 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12305 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12306 (match_operand:QI 2 "const1_operand" "")))
12307 (clobber (reg:CC FLAGS_REG))]
12308 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12309 && (TARGET_SHIFT1 || optimize_size)"
12311 [(set_attr "type" "ishift")
12312 (set (attr "length")
12313 (if_then_else (match_operand 0 "register_operand" "")
12315 (const_string "*")))])
12317 (define_insn "*lshrhi3_1"
12318 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12319 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12320 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12321 (clobber (reg:CC FLAGS_REG))]
12322 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12324 shr{w}\t{%2, %0|%0, %2}
12325 shr{w}\t{%b2, %0|%0, %b2}"
12326 [(set_attr "type" "ishift")
12327 (set_attr "mode" "HI")])
12329 ;; This pattern can't accept a variable shift count, since shifts by
12330 ;; zero don't affect the flags. We assume that shifts by constant
12331 ;; zero are optimized away.
12332 (define_insn "*lshrhi3_one_bit_cmp"
12333 [(set (reg FLAGS_REG)
12335 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12336 (match_operand:QI 2 "const1_operand" ""))
12338 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12339 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12340 "ix86_match_ccmode (insn, CCGOCmode)
12341 && (TARGET_SHIFT1 || optimize_size)
12342 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12344 [(set_attr "type" "ishift")
12345 (set (attr "length")
12346 (if_then_else (match_operand:SI 0 "register_operand" "")
12348 (const_string "*")))])
12350 (define_insn "*lshrhi3_one_bit_cconly"
12351 [(set (reg FLAGS_REG)
12353 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12354 (match_operand:QI 2 "const1_operand" ""))
12356 (clobber (match_scratch:HI 0 "=r"))]
12357 "ix86_match_ccmode (insn, CCGOCmode)
12358 && (TARGET_SHIFT1 || optimize_size)
12359 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12361 [(set_attr "type" "ishift")
12362 (set_attr "length" "2")])
12364 ;; This pattern can't accept a variable shift count, since shifts by
12365 ;; zero don't affect the flags. We assume that shifts by constant
12366 ;; zero are optimized away.
12367 (define_insn "*lshrhi3_cmp"
12368 [(set (reg FLAGS_REG)
12370 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12371 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12373 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12374 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12375 "ix86_match_ccmode (insn, CCGOCmode)
12376 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12378 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12379 "shr{w}\t{%2, %0|%0, %2}"
12380 [(set_attr "type" "ishift")
12381 (set_attr "mode" "HI")])
12383 (define_insn "*lshrhi3_cconly"
12384 [(set (reg FLAGS_REG)
12386 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12387 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12389 (clobber (match_scratch:HI 0 "=r"))]
12390 "ix86_match_ccmode (insn, CCGOCmode)
12391 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)
12393 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12394 "shr{w}\t{%2, %0|%0, %2}"
12395 [(set_attr "type" "ishift")
12396 (set_attr "mode" "HI")])
12398 (define_expand "lshrqi3"
12399 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12400 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12401 (match_operand:QI 2 "nonmemory_operand" "")))
12402 (clobber (reg:CC FLAGS_REG))]
12403 "TARGET_QIMODE_MATH"
12404 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12406 (define_insn "*lshrqi3_1_one_bit"
12407 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12408 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12409 (match_operand:QI 2 "const1_operand" "")))
12410 (clobber (reg:CC FLAGS_REG))]
12411 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12412 && (TARGET_SHIFT1 || optimize_size)"
12414 [(set_attr "type" "ishift")
12415 (set (attr "length")
12416 (if_then_else (match_operand 0 "register_operand" "")
12418 (const_string "*")))])
12420 (define_insn "*lshrqi3_1_one_bit_slp"
12421 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12422 (lshiftrt:QI (match_dup 0)
12423 (match_operand:QI 1 "const1_operand" "")))
12424 (clobber (reg:CC FLAGS_REG))]
12425 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12426 && (TARGET_SHIFT1 || optimize_size)"
12428 [(set_attr "type" "ishift1")
12429 (set (attr "length")
12430 (if_then_else (match_operand 0 "register_operand" "")
12432 (const_string "*")))])
12434 (define_insn "*lshrqi3_1"
12435 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12436 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12437 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12438 (clobber (reg:CC FLAGS_REG))]
12439 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12441 shr{b}\t{%2, %0|%0, %2}
12442 shr{b}\t{%b2, %0|%0, %b2}"
12443 [(set_attr "type" "ishift")
12444 (set_attr "mode" "QI")])
12446 (define_insn "*lshrqi3_1_slp"
12447 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12448 (lshiftrt:QI (match_dup 0)
12449 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12450 (clobber (reg:CC FLAGS_REG))]
12451 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12452 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12454 shr{b}\t{%1, %0|%0, %1}
12455 shr{b}\t{%b1, %0|%0, %b1}"
12456 [(set_attr "type" "ishift1")
12457 (set_attr "mode" "QI")])
12459 ;; This pattern can't accept a variable shift count, since shifts by
12460 ;; zero don't affect the flags. We assume that shifts by constant
12461 ;; zero are optimized away.
12462 (define_insn "*lshrqi2_one_bit_cmp"
12463 [(set (reg FLAGS_REG)
12465 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12466 (match_operand:QI 2 "const1_operand" ""))
12468 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12469 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12470 "ix86_match_ccmode (insn, CCGOCmode)
12471 && (TARGET_SHIFT1 || optimize_size)
12472 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12474 [(set_attr "type" "ishift")
12475 (set (attr "length")
12476 (if_then_else (match_operand:SI 0 "register_operand" "")
12478 (const_string "*")))])
12480 (define_insn "*lshrqi2_one_bit_cconly"
12481 [(set (reg FLAGS_REG)
12483 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12484 (match_operand:QI 2 "const1_operand" ""))
12486 (clobber (match_scratch:QI 0 "=q"))]
12487 "ix86_match_ccmode (insn, CCGOCmode)
12488 && (TARGET_SHIFT1 || optimize_size)
12489 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12491 [(set_attr "type" "ishift")
12492 (set_attr "length" "2")])
12494 ;; This pattern can't accept a variable shift count, since shifts by
12495 ;; zero don't affect the flags. We assume that shifts by constant
12496 ;; zero are optimized away.
12497 (define_insn "*lshrqi2_cmp"
12498 [(set (reg FLAGS_REG)
12500 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12501 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12503 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12504 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12505 "ix86_match_ccmode (insn, CCGOCmode)
12506 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12508 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12509 "shr{b}\t{%2, %0|%0, %2}"
12510 [(set_attr "type" "ishift")
12511 (set_attr "mode" "QI")])
12513 (define_insn "*lshrqi2_cconly"
12514 [(set (reg FLAGS_REG)
12516 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12517 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12519 (clobber (match_scratch:QI 0 "=q"))]
12520 "ix86_match_ccmode (insn, CCGOCmode)
12521 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)
12523 || !TARGET_PARTIAL_FLAG_REG_STALL)"
12524 "shr{b}\t{%2, %0|%0, %2}"
12525 [(set_attr "type" "ishift")
12526 (set_attr "mode" "QI")])
12528 ;; Rotate instructions
12530 (define_expand "rotldi3"
12531 [(set (match_operand:DI 0 "shiftdi_operand" "")
12532 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12533 (match_operand:QI 2 "nonmemory_operand" "")))
12534 (clobber (reg:CC FLAGS_REG))]
12539 ix86_expand_binary_operator (ROTATE, DImode, operands);
12542 if (!const_1_to_31_operand (operands[2], VOIDmode))
12544 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12548 ;; Implement rotation using two double-precision shift instructions
12549 ;; and a scratch register.
12550 (define_insn_and_split "ix86_rotldi3"
12551 [(set (match_operand:DI 0 "register_operand" "=r")
12552 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12553 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12554 (clobber (reg:CC FLAGS_REG))
12555 (clobber (match_scratch:SI 3 "=&r"))]
12558 "&& reload_completed"
12559 [(set (match_dup 3) (match_dup 4))
12561 [(set (match_dup 4)
12562 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12563 (lshiftrt:SI (match_dup 5)
12564 (minus:QI (const_int 32) (match_dup 2)))))
12565 (clobber (reg:CC FLAGS_REG))])
12567 [(set (match_dup 5)
12568 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12569 (lshiftrt:SI (match_dup 3)
12570 (minus:QI (const_int 32) (match_dup 2)))))
12571 (clobber (reg:CC FLAGS_REG))])]
12572 "split_di (operands, 1, operands + 4, operands + 5);")
12574 (define_insn "*rotlsi3_1_one_bit_rex64"
12575 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12576 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12577 (match_operand:QI 2 "const1_operand" "")))
12578 (clobber (reg:CC FLAGS_REG))]
12579 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)
12580 && (TARGET_SHIFT1 || optimize_size)"
12582 [(set_attr "type" "rotate")
12583 (set (attr "length")
12584 (if_then_else (match_operand:DI 0 "register_operand" "")
12586 (const_string "*")))])
12588 (define_insn "*rotldi3_1_rex64"
12589 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12590 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12591 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12592 (clobber (reg:CC FLAGS_REG))]
12593 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12595 rol{q}\t{%2, %0|%0, %2}
12596 rol{q}\t{%b2, %0|%0, %b2}"
12597 [(set_attr "type" "rotate")
12598 (set_attr "mode" "DI")])
12600 (define_expand "rotlsi3"
12601 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12602 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12603 (match_operand:QI 2 "nonmemory_operand" "")))
12604 (clobber (reg:CC FLAGS_REG))]
12606 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12608 (define_insn "*rotlsi3_1_one_bit"
12609 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12610 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12611 (match_operand:QI 2 "const1_operand" "")))
12612 (clobber (reg:CC FLAGS_REG))]
12613 "ix86_binary_operator_ok (ROTATE, SImode, operands)
12614 && (TARGET_SHIFT1 || optimize_size)"
12616 [(set_attr "type" "rotate")
12617 (set (attr "length")
12618 (if_then_else (match_operand:SI 0 "register_operand" "")
12620 (const_string "*")))])
12622 (define_insn "*rotlsi3_1_one_bit_zext"
12623 [(set (match_operand:DI 0 "register_operand" "=r")
12625 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12626 (match_operand:QI 2 "const1_operand" ""))))
12627 (clobber (reg:CC FLAGS_REG))]
12628 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)
12629 && (TARGET_SHIFT1 || optimize_size)"
12631 [(set_attr "type" "rotate")
12632 (set_attr "length" "2")])
12634 (define_insn "*rotlsi3_1"
12635 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12636 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12637 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12638 (clobber (reg:CC FLAGS_REG))]
12639 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12641 rol{l}\t{%2, %0|%0, %2}
12642 rol{l}\t{%b2, %0|%0, %b2}"
12643 [(set_attr "type" "rotate")
12644 (set_attr "mode" "SI")])
12646 (define_insn "*rotlsi3_1_zext"
12647 [(set (match_operand:DI 0 "register_operand" "=r,r")
12649 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12650 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12651 (clobber (reg:CC FLAGS_REG))]
12652 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12654 rol{l}\t{%2, %k0|%k0, %2}
12655 rol{l}\t{%b2, %k0|%k0, %b2}"
12656 [(set_attr "type" "rotate")
12657 (set_attr "mode" "SI")])
12659 (define_expand "rotlhi3"
12660 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12661 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12662 (match_operand:QI 2 "nonmemory_operand" "")))
12663 (clobber (reg:CC FLAGS_REG))]
12664 "TARGET_HIMODE_MATH"
12665 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12667 (define_insn "*rotlhi3_1_one_bit"
12668 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12669 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12670 (match_operand:QI 2 "const1_operand" "")))
12671 (clobber (reg:CC FLAGS_REG))]
12672 "ix86_binary_operator_ok (ROTATE, HImode, operands)
12673 && (TARGET_SHIFT1 || optimize_size)"
12675 [(set_attr "type" "rotate")
12676 (set (attr "length")
12677 (if_then_else (match_operand 0 "register_operand" "")
12679 (const_string "*")))])
12681 (define_insn "*rotlhi3_1"
12682 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12683 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12684 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12685 (clobber (reg:CC FLAGS_REG))]
12686 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12688 rol{w}\t{%2, %0|%0, %2}
12689 rol{w}\t{%b2, %0|%0, %b2}"
12690 [(set_attr "type" "rotate")
12691 (set_attr "mode" "HI")])
12693 (define_expand "rotlqi3"
12694 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12695 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12696 (match_operand:QI 2 "nonmemory_operand" "")))
12697 (clobber (reg:CC FLAGS_REG))]
12698 "TARGET_QIMODE_MATH"
12699 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12701 (define_insn "*rotlqi3_1_one_bit_slp"
12702 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12703 (rotate:QI (match_dup 0)
12704 (match_operand:QI 1 "const1_operand" "")))
12705 (clobber (reg:CC FLAGS_REG))]
12706 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12707 && (TARGET_SHIFT1 || optimize_size)"
12709 [(set_attr "type" "rotate1")
12710 (set (attr "length")
12711 (if_then_else (match_operand 0 "register_operand" "")
12713 (const_string "*")))])
12715 (define_insn "*rotlqi3_1_one_bit"
12716 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12717 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12718 (match_operand:QI 2 "const1_operand" "")))
12719 (clobber (reg:CC FLAGS_REG))]
12720 "ix86_binary_operator_ok (ROTATE, QImode, operands)
12721 && (TARGET_SHIFT1 || optimize_size)"
12723 [(set_attr "type" "rotate")
12724 (set (attr "length")
12725 (if_then_else (match_operand 0 "register_operand" "")
12727 (const_string "*")))])
12729 (define_insn "*rotlqi3_1_slp"
12730 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12731 (rotate:QI (match_dup 0)
12732 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12733 (clobber (reg:CC FLAGS_REG))]
12734 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12735 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12737 rol{b}\t{%1, %0|%0, %1}
12738 rol{b}\t{%b1, %0|%0, %b1}"
12739 [(set_attr "type" "rotate1")
12740 (set_attr "mode" "QI")])
12742 (define_insn "*rotlqi3_1"
12743 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12744 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12745 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12746 (clobber (reg:CC FLAGS_REG))]
12747 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12749 rol{b}\t{%2, %0|%0, %2}
12750 rol{b}\t{%b2, %0|%0, %b2}"
12751 [(set_attr "type" "rotate")
12752 (set_attr "mode" "QI")])
12754 (define_expand "rotrdi3"
12755 [(set (match_operand:DI 0 "shiftdi_operand" "")
12756 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12757 (match_operand:QI 2 "nonmemory_operand" "")))
12758 (clobber (reg:CC FLAGS_REG))]
12763 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12766 if (!const_1_to_31_operand (operands[2], VOIDmode))
12768 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12772 ;; Implement rotation using two double-precision shift instructions
12773 ;; and a scratch register.
12774 (define_insn_and_split "ix86_rotrdi3"
12775 [(set (match_operand:DI 0 "register_operand" "=r")
12776 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12777 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12778 (clobber (reg:CC FLAGS_REG))
12779 (clobber (match_scratch:SI 3 "=&r"))]
12782 "&& reload_completed"
12783 [(set (match_dup 3) (match_dup 4))
12785 [(set (match_dup 4)
12786 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12787 (ashift:SI (match_dup 5)
12788 (minus:QI (const_int 32) (match_dup 2)))))
12789 (clobber (reg:CC FLAGS_REG))])
12791 [(set (match_dup 5)
12792 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12793 (ashift:SI (match_dup 3)
12794 (minus:QI (const_int 32) (match_dup 2)))))
12795 (clobber (reg:CC FLAGS_REG))])]
12796 "split_di (operands, 1, operands + 4, operands + 5);")
12798 (define_insn "*rotrdi3_1_one_bit_rex64"
12799 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12800 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12801 (match_operand:QI 2 "const1_operand" "")))
12802 (clobber (reg:CC FLAGS_REG))]
12803 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)
12804 && (TARGET_SHIFT1 || optimize_size)"
12806 [(set_attr "type" "rotate")
12807 (set (attr "length")
12808 (if_then_else (match_operand:DI 0 "register_operand" "")
12810 (const_string "*")))])
12812 (define_insn "*rotrdi3_1_rex64"
12813 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12814 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12815 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12816 (clobber (reg:CC FLAGS_REG))]
12817 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12819 ror{q}\t{%2, %0|%0, %2}
12820 ror{q}\t{%b2, %0|%0, %b2}"
12821 [(set_attr "type" "rotate")
12822 (set_attr "mode" "DI")])
12824 (define_expand "rotrsi3"
12825 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12826 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12827 (match_operand:QI 2 "nonmemory_operand" "")))
12828 (clobber (reg:CC FLAGS_REG))]
12830 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12832 (define_insn "*rotrsi3_1_one_bit"
12833 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12834 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12835 (match_operand:QI 2 "const1_operand" "")))
12836 (clobber (reg:CC FLAGS_REG))]
12837 "ix86_binary_operator_ok (ROTATERT, SImode, operands)
12838 && (TARGET_SHIFT1 || optimize_size)"
12840 [(set_attr "type" "rotate")
12841 (set (attr "length")
12842 (if_then_else (match_operand:SI 0 "register_operand" "")
12844 (const_string "*")))])
12846 (define_insn "*rotrsi3_1_one_bit_zext"
12847 [(set (match_operand:DI 0 "register_operand" "=r")
12849 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12850 (match_operand:QI 2 "const1_operand" ""))))
12851 (clobber (reg:CC FLAGS_REG))]
12852 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)
12853 && (TARGET_SHIFT1 || optimize_size)"
12855 [(set_attr "type" "rotate")
12856 (set (attr "length")
12857 (if_then_else (match_operand:SI 0 "register_operand" "")
12859 (const_string "*")))])
12861 (define_insn "*rotrsi3_1"
12862 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12863 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12864 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12865 (clobber (reg:CC FLAGS_REG))]
12866 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12868 ror{l}\t{%2, %0|%0, %2}
12869 ror{l}\t{%b2, %0|%0, %b2}"
12870 [(set_attr "type" "rotate")
12871 (set_attr "mode" "SI")])
12873 (define_insn "*rotrsi3_1_zext"
12874 [(set (match_operand:DI 0 "register_operand" "=r,r")
12876 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12877 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12878 (clobber (reg:CC FLAGS_REG))]
12879 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12881 ror{l}\t{%2, %k0|%k0, %2}
12882 ror{l}\t{%b2, %k0|%k0, %b2}"
12883 [(set_attr "type" "rotate")
12884 (set_attr "mode" "SI")])
12886 (define_expand "rotrhi3"
12887 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12888 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12889 (match_operand:QI 2 "nonmemory_operand" "")))
12890 (clobber (reg:CC FLAGS_REG))]
12891 "TARGET_HIMODE_MATH"
12892 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12894 (define_insn "*rotrhi3_one_bit"
12895 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12896 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12897 (match_operand:QI 2 "const1_operand" "")))
12898 (clobber (reg:CC FLAGS_REG))]
12899 "ix86_binary_operator_ok (ROTATERT, HImode, operands)
12900 && (TARGET_SHIFT1 || optimize_size)"
12902 [(set_attr "type" "rotate")
12903 (set (attr "length")
12904 (if_then_else (match_operand 0 "register_operand" "")
12906 (const_string "*")))])
12908 (define_insn "*rotrhi3"
12909 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12910 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12911 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12912 (clobber (reg:CC FLAGS_REG))]
12913 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12915 ror{w}\t{%2, %0|%0, %2}
12916 ror{w}\t{%b2, %0|%0, %b2}"
12917 [(set_attr "type" "rotate")
12918 (set_attr "mode" "HI")])
12920 (define_expand "rotrqi3"
12921 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12922 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12923 (match_operand:QI 2 "nonmemory_operand" "")))
12924 (clobber (reg:CC FLAGS_REG))]
12925 "TARGET_QIMODE_MATH"
12926 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12928 (define_insn "*rotrqi3_1_one_bit"
12929 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12930 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12931 (match_operand:QI 2 "const1_operand" "")))
12932 (clobber (reg:CC FLAGS_REG))]
12933 "ix86_binary_operator_ok (ROTATERT, QImode, operands)
12934 && (TARGET_SHIFT1 || optimize_size)"
12936 [(set_attr "type" "rotate")
12937 (set (attr "length")
12938 (if_then_else (match_operand 0 "register_operand" "")
12940 (const_string "*")))])
12942 (define_insn "*rotrqi3_1_one_bit_slp"
12943 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12944 (rotatert:QI (match_dup 0)
12945 (match_operand:QI 1 "const1_operand" "")))
12946 (clobber (reg:CC FLAGS_REG))]
12947 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12948 && (TARGET_SHIFT1 || optimize_size)"
12950 [(set_attr "type" "rotate1")
12951 (set (attr "length")
12952 (if_then_else (match_operand 0 "register_operand" "")
12954 (const_string "*")))])
12956 (define_insn "*rotrqi3_1"
12957 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12958 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12959 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12960 (clobber (reg:CC FLAGS_REG))]
12961 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12963 ror{b}\t{%2, %0|%0, %2}
12964 ror{b}\t{%b2, %0|%0, %b2}"
12965 [(set_attr "type" "rotate")
12966 (set_attr "mode" "QI")])
12968 (define_insn "*rotrqi3_1_slp"
12969 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12970 (rotatert:QI (match_dup 0)
12971 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12972 (clobber (reg:CC FLAGS_REG))]
12973 "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12974 && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
12976 ror{b}\t{%1, %0|%0, %1}
12977 ror{b}\t{%b1, %0|%0, %b1}"
12978 [(set_attr "type" "rotate1")
12979 (set_attr "mode" "QI")])
12981 ;; Bit set / bit test instructions
12983 (define_expand "extv"
12984 [(set (match_operand:SI 0 "register_operand" "")
12985 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12986 (match_operand:SI 2 "const8_operand" "")
12987 (match_operand:SI 3 "const8_operand" "")))]
12990 /* Handle extractions from %ah et al. */
12991 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12994 /* From mips.md: extract_bit_field doesn't verify that our source
12995 matches the predicate, so check it again here. */
12996 if (! ext_register_operand (operands[1], VOIDmode))
13000 (define_expand "extzv"
13001 [(set (match_operand:SI 0 "register_operand" "")
13002 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13003 (match_operand:SI 2 "const8_operand" "")
13004 (match_operand:SI 3 "const8_operand" "")))]
13007 /* Handle extractions from %ah et al. */
13008 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13011 /* From mips.md: extract_bit_field doesn't verify that our source
13012 matches the predicate, so check it again here. */
13013 if (! ext_register_operand (operands[1], VOIDmode))
13017 (define_expand "insv"
13018 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13019 (match_operand 1 "const8_operand" "")
13020 (match_operand 2 "const8_operand" ""))
13021 (match_operand 3 "register_operand" ""))]
13024 /* Handle insertions to %ah et al. */
13025 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13028 /* From mips.md: insert_bit_field doesn't verify that our source
13029 matches the predicate, so check it again here. */
13030 if (! ext_register_operand (operands[0], VOIDmode))
13034 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13036 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13041 ;; %%% bts, btr, btc, bt.
13042 ;; In general these instructions are *slow* when applied to memory,
13043 ;; since they enforce atomic operation. When applied to registers,
13044 ;; it depends on the cpu implementation. They're never faster than
13045 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13046 ;; no point. But in 64-bit, we can't hold the relevant immediates
13047 ;; within the instruction itself, so operating on bits in the high
13048 ;; 32-bits of a register becomes easier.
13050 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13051 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13052 ;; negdf respectively, so they can never be disabled entirely.
13054 (define_insn "*btsq"
13055 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13057 (match_operand:DI 1 "const_0_to_63_operand" ""))
13059 (clobber (reg:CC FLAGS_REG))]
13060 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13062 [(set_attr "type" "alu1")])
13064 (define_insn "*btrq"
13065 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13067 (match_operand:DI 1 "const_0_to_63_operand" ""))
13069 (clobber (reg:CC FLAGS_REG))]
13070 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13072 [(set_attr "type" "alu1")])
13074 (define_insn "*btcq"
13075 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13077 (match_operand:DI 1 "const_0_to_63_operand" ""))
13078 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13079 (clobber (reg:CC FLAGS_REG))]
13080 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13082 [(set_attr "type" "alu1")])
13084 ;; Allow Nocona to avoid these instructions if a register is available.
13087 [(match_scratch:DI 2 "r")
13088 (parallel [(set (zero_extract:DI
13089 (match_operand:DI 0 "register_operand" "")
13091 (match_operand:DI 1 "const_0_to_63_operand" ""))
13093 (clobber (reg:CC FLAGS_REG))])]
13094 "TARGET_64BIT && !TARGET_USE_BT"
13097 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13100 if (HOST_BITS_PER_WIDE_INT >= 64)
13101 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13102 else if (i < HOST_BITS_PER_WIDE_INT)
13103 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13105 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13107 op1 = immed_double_const (lo, hi, DImode);
13110 emit_move_insn (operands[2], op1);
13114 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13119 [(match_scratch:DI 2 "r")
13120 (parallel [(set (zero_extract:DI
13121 (match_operand:DI 0 "register_operand" "")
13123 (match_operand:DI 1 "const_0_to_63_operand" ""))
13125 (clobber (reg:CC FLAGS_REG))])]
13126 "TARGET_64BIT && !TARGET_USE_BT"
13129 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13132 if (HOST_BITS_PER_WIDE_INT >= 64)
13133 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13134 else if (i < HOST_BITS_PER_WIDE_INT)
13135 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13137 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13139 op1 = immed_double_const (~lo, ~hi, DImode);
13142 emit_move_insn (operands[2], op1);
13146 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13151 [(match_scratch:DI 2 "r")
13152 (parallel [(set (zero_extract:DI
13153 (match_operand:DI 0 "register_operand" "")
13155 (match_operand:DI 1 "const_0_to_63_operand" ""))
13156 (not:DI (zero_extract:DI
13157 (match_dup 0) (const_int 1) (match_dup 1))))
13158 (clobber (reg:CC FLAGS_REG))])]
13159 "TARGET_64BIT && !TARGET_USE_BT"
13162 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13165 if (HOST_BITS_PER_WIDE_INT >= 64)
13166 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13167 else if (i < HOST_BITS_PER_WIDE_INT)
13168 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13170 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13172 op1 = immed_double_const (lo, hi, DImode);
13175 emit_move_insn (operands[2], op1);
13179 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13183 ;; Store-flag instructions.
13185 ;; For all sCOND expanders, also expand the compare or test insn that
13186 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13188 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
13189 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
13190 ;; way, which can later delete the movzx if only QImode is needed.
13192 (define_expand "seq"
13193 [(set (match_operand:QI 0 "register_operand" "")
13194 (eq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13196 "if (ix86_expand_setcc (EQ, operands[0])) DONE; else FAIL;")
13198 (define_expand "sne"
13199 [(set (match_operand:QI 0 "register_operand" "")
13200 (ne:QI (reg:CC FLAGS_REG) (const_int 0)))]
13202 "if (ix86_expand_setcc (NE, operands[0])) DONE; else FAIL;")
13204 (define_expand "sgt"
13205 [(set (match_operand:QI 0 "register_operand" "")
13206 (gt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13208 "if (ix86_expand_setcc (GT, operands[0])) DONE; else FAIL;")
13210 (define_expand "sgtu"
13211 [(set (match_operand:QI 0 "register_operand" "")
13212 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13214 "if (ix86_expand_setcc (GTU, operands[0])) DONE; else FAIL;")
13216 (define_expand "slt"
13217 [(set (match_operand:QI 0 "register_operand" "")
13218 (lt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13220 "if (ix86_expand_setcc (LT, operands[0])) DONE; else FAIL;")
13222 (define_expand "sltu"
13223 [(set (match_operand:QI 0 "register_operand" "")
13224 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13226 "if (ix86_expand_setcc (LTU, operands[0])) DONE; else FAIL;")
13228 (define_expand "sge"
13229 [(set (match_operand:QI 0 "register_operand" "")
13230 (ge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13232 "if (ix86_expand_setcc (GE, operands[0])) DONE; else FAIL;")
13234 (define_expand "sgeu"
13235 [(set (match_operand:QI 0 "register_operand" "")
13236 (geu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13238 "if (ix86_expand_setcc (GEU, operands[0])) DONE; else FAIL;")
13240 (define_expand "sle"
13241 [(set (match_operand:QI 0 "register_operand" "")
13242 (le:QI (reg:CC FLAGS_REG) (const_int 0)))]
13244 "if (ix86_expand_setcc (LE, operands[0])) DONE; else FAIL;")
13246 (define_expand "sleu"
13247 [(set (match_operand:QI 0 "register_operand" "")
13248 (leu:QI (reg:CC FLAGS_REG) (const_int 0)))]
13250 "if (ix86_expand_setcc (LEU, operands[0])) DONE; else FAIL;")
13252 (define_expand "sunordered"
13253 [(set (match_operand:QI 0 "register_operand" "")
13254 (unordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13255 "TARGET_80387 || TARGET_SSE"
13256 "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
13258 (define_expand "sordered"
13259 [(set (match_operand:QI 0 "register_operand" "")
13260 (ordered:QI (reg:CC FLAGS_REG) (const_int 0)))]
13262 "if (ix86_expand_setcc (ORDERED, operands[0])) DONE; else FAIL;")
13264 (define_expand "suneq"
13265 [(set (match_operand:QI 0 "register_operand" "")
13266 (uneq:QI (reg:CC FLAGS_REG) (const_int 0)))]
13267 "TARGET_80387 || TARGET_SSE"
13268 "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
13270 (define_expand "sunge"
13271 [(set (match_operand:QI 0 "register_operand" "")
13272 (unge:QI (reg:CC FLAGS_REG) (const_int 0)))]
13273 "TARGET_80387 || TARGET_SSE"
13274 "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
13276 (define_expand "sungt"
13277 [(set (match_operand:QI 0 "register_operand" "")
13278 (ungt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13279 "TARGET_80387 || TARGET_SSE"
13280 "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
13282 (define_expand "sunle"
13283 [(set (match_operand:QI 0 "register_operand" "")
13284 (unle:QI (reg:CC FLAGS_REG) (const_int 0)))]
13285 "TARGET_80387 || TARGET_SSE"
13286 "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
13288 (define_expand "sunlt"
13289 [(set (match_operand:QI 0 "register_operand" "")
13290 (unlt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13291 "TARGET_80387 || TARGET_SSE"
13292 "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
13294 (define_expand "sltgt"
13295 [(set (match_operand:QI 0 "register_operand" "")
13296 (ltgt:QI (reg:CC FLAGS_REG) (const_int 0)))]
13297 "TARGET_80387 || TARGET_SSE"
13298 "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
13300 (define_insn "*setcc_1"
13301 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13302 (match_operator:QI 1 "ix86_comparison_operator"
13303 [(reg FLAGS_REG) (const_int 0)]))]
13306 [(set_attr "type" "setcc")
13307 (set_attr "mode" "QI")])
13309 (define_insn "*setcc_2"
13310 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13311 (match_operator:QI 1 "ix86_comparison_operator"
13312 [(reg FLAGS_REG) (const_int 0)]))]
13315 [(set_attr "type" "setcc")
13316 (set_attr "mode" "QI")])
13318 ;; In general it is not safe to assume too much about CCmode registers,
13319 ;; so simplify-rtx stops when it sees a second one. Under certain
13320 ;; conditions this is safe on x86, so help combine not create
13327 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13328 (ne:QI (match_operator 1 "ix86_comparison_operator"
13329 [(reg FLAGS_REG) (const_int 0)])
13332 [(set (match_dup 0) (match_dup 1))]
13334 PUT_MODE (operands[1], QImode);
13338 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13339 (ne:QI (match_operator 1 "ix86_comparison_operator"
13340 [(reg FLAGS_REG) (const_int 0)])
13343 [(set (match_dup 0) (match_dup 1))]
13345 PUT_MODE (operands[1], QImode);
13349 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13350 (eq:QI (match_operator 1 "ix86_comparison_operator"
13351 [(reg FLAGS_REG) (const_int 0)])
13354 [(set (match_dup 0) (match_dup 1))]
13356 rtx new_op1 = copy_rtx (operands[1]);
13357 operands[1] = new_op1;
13358 PUT_MODE (new_op1, QImode);
13359 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13360 GET_MODE (XEXP (new_op1, 0))));
13362 /* Make sure that (a) the CCmode we have for the flags is strong
13363 enough for the reversed compare or (b) we have a valid FP compare. */
13364 if (! ix86_comparison_operator (new_op1, VOIDmode))
13369 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13370 (eq:QI (match_operator 1 "ix86_comparison_operator"
13371 [(reg FLAGS_REG) (const_int 0)])
13374 [(set (match_dup 0) (match_dup 1))]
13376 rtx new_op1 = copy_rtx (operands[1]);
13377 operands[1] = new_op1;
13378 PUT_MODE (new_op1, QImode);
13379 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13380 GET_MODE (XEXP (new_op1, 0))));
13382 /* Make sure that (a) the CCmode we have for the flags is strong
13383 enough for the reversed compare or (b) we have a valid FP compare. */
13384 if (! ix86_comparison_operator (new_op1, VOIDmode))
13388 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13389 ;; subsequent logical operations are used to imitate conditional moves.
13390 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13393 (define_insn "*sse_setccsf"
13394 [(set (match_operand:SF 0 "register_operand" "=x")
13395 (match_operator:SF 1 "sse_comparison_operator"
13396 [(match_operand:SF 2 "register_operand" "0")
13397 (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
13399 "cmp%D1ss\t{%3, %0|%0, %3}"
13400 [(set_attr "type" "ssecmp")
13401 (set_attr "mode" "SF")])
13403 (define_insn "*sse_setccdf"
13404 [(set (match_operand:DF 0 "register_operand" "=Y")
13405 (match_operator:DF 1 "sse_comparison_operator"
13406 [(match_operand:DF 2 "register_operand" "0")
13407 (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
13409 "cmp%D1sd\t{%3, %0|%0, %3}"
13410 [(set_attr "type" "ssecmp")
13411 (set_attr "mode" "DF")])
13413 ;; Basic conditional jump instructions.
13414 ;; We ignore the overflow flag for signed branch instructions.
13416 ;; For all bCOND expanders, also expand the compare or test insn that
13417 ;; generates reg FLAGS_REG. Generate an equality comparison if `beq' or `bne'.
13419 (define_expand "beq"
13421 (if_then_else (match_dup 1)
13422 (label_ref (match_operand 0 "" ""))
13425 "ix86_expand_branch (EQ, operands[0]); DONE;")
13427 (define_expand "bne"
13429 (if_then_else (match_dup 1)
13430 (label_ref (match_operand 0 "" ""))
13433 "ix86_expand_branch (NE, operands[0]); DONE;")
13435 (define_expand "bgt"
13437 (if_then_else (match_dup 1)
13438 (label_ref (match_operand 0 "" ""))
13441 "ix86_expand_branch (GT, operands[0]); DONE;")
13443 (define_expand "bgtu"
13445 (if_then_else (match_dup 1)
13446 (label_ref (match_operand 0 "" ""))
13449 "ix86_expand_branch (GTU, operands[0]); DONE;")
13451 (define_expand "blt"
13453 (if_then_else (match_dup 1)
13454 (label_ref (match_operand 0 "" ""))
13457 "ix86_expand_branch (LT, operands[0]); DONE;")
13459 (define_expand "bltu"
13461 (if_then_else (match_dup 1)
13462 (label_ref (match_operand 0 "" ""))
13465 "ix86_expand_branch (LTU, operands[0]); DONE;")
13467 (define_expand "bge"
13469 (if_then_else (match_dup 1)
13470 (label_ref (match_operand 0 "" ""))
13473 "ix86_expand_branch (GE, operands[0]); DONE;")
13475 (define_expand "bgeu"
13477 (if_then_else (match_dup 1)
13478 (label_ref (match_operand 0 "" ""))
13481 "ix86_expand_branch (GEU, operands[0]); DONE;")
13483 (define_expand "ble"
13485 (if_then_else (match_dup 1)
13486 (label_ref (match_operand 0 "" ""))
13489 "ix86_expand_branch (LE, operands[0]); DONE;")
13491 (define_expand "bleu"
13493 (if_then_else (match_dup 1)
13494 (label_ref (match_operand 0 "" ""))
13497 "ix86_expand_branch (LEU, operands[0]); DONE;")
13499 (define_expand "bunordered"
13501 (if_then_else (match_dup 1)
13502 (label_ref (match_operand 0 "" ""))
13504 "TARGET_80387 || TARGET_SSE_MATH"
13505 "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
13507 (define_expand "bordered"
13509 (if_then_else (match_dup 1)
13510 (label_ref (match_operand 0 "" ""))
13512 "TARGET_80387 || TARGET_SSE_MATH"
13513 "ix86_expand_branch (ORDERED, operands[0]); DONE;")
13515 (define_expand "buneq"
13517 (if_then_else (match_dup 1)
13518 (label_ref (match_operand 0 "" ""))
13520 "TARGET_80387 || TARGET_SSE_MATH"
13521 "ix86_expand_branch (UNEQ, operands[0]); DONE;")
13523 (define_expand "bunge"
13525 (if_then_else (match_dup 1)
13526 (label_ref (match_operand 0 "" ""))
13528 "TARGET_80387 || TARGET_SSE_MATH"
13529 "ix86_expand_branch (UNGE, operands[0]); DONE;")
13531 (define_expand "bungt"
13533 (if_then_else (match_dup 1)
13534 (label_ref (match_operand 0 "" ""))
13536 "TARGET_80387 || TARGET_SSE_MATH"
13537 "ix86_expand_branch (UNGT, operands[0]); DONE;")
13539 (define_expand "bunle"
13541 (if_then_else (match_dup 1)
13542 (label_ref (match_operand 0 "" ""))
13544 "TARGET_80387 || TARGET_SSE_MATH"
13545 "ix86_expand_branch (UNLE, operands[0]); DONE;")
13547 (define_expand "bunlt"
13549 (if_then_else (match_dup 1)
13550 (label_ref (match_operand 0 "" ""))
13552 "TARGET_80387 || TARGET_SSE_MATH"
13553 "ix86_expand_branch (UNLT, operands[0]); DONE;")
13555 (define_expand "bltgt"
13557 (if_then_else (match_dup 1)
13558 (label_ref (match_operand 0 "" ""))
13560 "TARGET_80387 || TARGET_SSE_MATH"
13561 "ix86_expand_branch (LTGT, operands[0]); DONE;")
13563 (define_insn "*jcc_1"
13565 (if_then_else (match_operator 1 "ix86_comparison_operator"
13566 [(reg FLAGS_REG) (const_int 0)])
13567 (label_ref (match_operand 0 "" ""))
13571 [(set_attr "type" "ibr")
13572 (set_attr "modrm" "0")
13573 (set (attr "length")
13574 (if_then_else (and (ge (minus (match_dup 0) (pc))
13576 (lt (minus (match_dup 0) (pc))
13581 (define_insn "*jcc_2"
13583 (if_then_else (match_operator 1 "ix86_comparison_operator"
13584 [(reg FLAGS_REG) (const_int 0)])
13586 (label_ref (match_operand 0 "" ""))))]
13589 [(set_attr "type" "ibr")
13590 (set_attr "modrm" "0")
13591 (set (attr "length")
13592 (if_then_else (and (ge (minus (match_dup 0) (pc))
13594 (lt (minus (match_dup 0) (pc))
13599 ;; In general it is not safe to assume too much about CCmode registers,
13600 ;; so simplify-rtx stops when it sees a second one. Under certain
13601 ;; conditions this is safe on x86, so help combine not create
13609 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13610 [(reg FLAGS_REG) (const_int 0)])
13612 (label_ref (match_operand 1 "" ""))
13616 (if_then_else (match_dup 0)
13617 (label_ref (match_dup 1))
13620 PUT_MODE (operands[0], VOIDmode);
13625 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13626 [(reg FLAGS_REG) (const_int 0)])
13628 (label_ref (match_operand 1 "" ""))
13632 (if_then_else (match_dup 0)
13633 (label_ref (match_dup 1))
13636 rtx new_op0 = copy_rtx (operands[0]);
13637 operands[0] = new_op0;
13638 PUT_MODE (new_op0, VOIDmode);
13639 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13640 GET_MODE (XEXP (new_op0, 0))));
13642 /* Make sure that (a) the CCmode we have for the flags is strong
13643 enough for the reversed compare or (b) we have a valid FP compare. */
13644 if (! ix86_comparison_operator (new_op0, VOIDmode))
13648 ;; Define combination compare-and-branch fp compare instructions to use
13649 ;; during early optimization. Splitting the operation apart early makes
13650 ;; for bad code when we want to reverse the operation.
13652 (define_insn "*fp_jcc_1_mixed"
13654 (if_then_else (match_operator 0 "comparison_operator"
13655 [(match_operand 1 "register_operand" "f,x")
13656 (match_operand 2 "nonimmediate_operand" "f,xm")])
13657 (label_ref (match_operand 3 "" ""))
13659 (clobber (reg:CCFP FPSR_REG))
13660 (clobber (reg:CCFP FLAGS_REG))]
13661 "TARGET_MIX_SSE_I387
13662 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13663 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13664 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13667 (define_insn "*fp_jcc_1_sse"
13669 (if_then_else (match_operator 0 "comparison_operator"
13670 [(match_operand 1 "register_operand" "x")
13671 (match_operand 2 "nonimmediate_operand" "xm")])
13672 (label_ref (match_operand 3 "" ""))
13674 (clobber (reg:CCFP FPSR_REG))
13675 (clobber (reg:CCFP FLAGS_REG))]
13677 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13678 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13679 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13682 (define_insn "*fp_jcc_1_387"
13684 (if_then_else (match_operator 0 "comparison_operator"
13685 [(match_operand 1 "register_operand" "f")
13686 (match_operand 2 "register_operand" "f")])
13687 (label_ref (match_operand 3 "" ""))
13689 (clobber (reg:CCFP FPSR_REG))
13690 (clobber (reg:CCFP FLAGS_REG))]
13691 "TARGET_CMOVE && TARGET_80387
13692 && FLOAT_MODE_P (GET_MODE (operands[1]))
13693 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13694 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13697 (define_insn "*fp_jcc_2_mixed"
13699 (if_then_else (match_operator 0 "comparison_operator"
13700 [(match_operand 1 "register_operand" "f,x")
13701 (match_operand 2 "nonimmediate_operand" "f,xm")])
13703 (label_ref (match_operand 3 "" ""))))
13704 (clobber (reg:CCFP FPSR_REG))
13705 (clobber (reg:CCFP FLAGS_REG))]
13706 "TARGET_MIX_SSE_I387
13707 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13708 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13709 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13712 (define_insn "*fp_jcc_2_sse"
13714 (if_then_else (match_operator 0 "comparison_operator"
13715 [(match_operand 1 "register_operand" "x")
13716 (match_operand 2 "nonimmediate_operand" "xm")])
13718 (label_ref (match_operand 3 "" ""))))
13719 (clobber (reg:CCFP FPSR_REG))
13720 (clobber (reg:CCFP FLAGS_REG))]
13722 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
13723 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13724 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13727 (define_insn "*fp_jcc_2_387"
13729 (if_then_else (match_operator 0 "comparison_operator"
13730 [(match_operand 1 "register_operand" "f")
13731 (match_operand 2 "register_operand" "f")])
13733 (label_ref (match_operand 3 "" ""))))
13734 (clobber (reg:CCFP FPSR_REG))
13735 (clobber (reg:CCFP FLAGS_REG))]
13736 "TARGET_CMOVE && TARGET_80387
13737 && FLOAT_MODE_P (GET_MODE (operands[1]))
13738 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13739 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13742 (define_insn "*fp_jcc_3_387"
13744 (if_then_else (match_operator 0 "comparison_operator"
13745 [(match_operand 1 "register_operand" "f")
13746 (match_operand 2 "nonimmediate_operand" "fm")])
13747 (label_ref (match_operand 3 "" ""))
13749 (clobber (reg:CCFP FPSR_REG))
13750 (clobber (reg:CCFP FLAGS_REG))
13751 (clobber (match_scratch:HI 4 "=a"))]
13753 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13754 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13755 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13756 && SELECT_CC_MODE (GET_CODE (operands[0]),
13757 operands[1], operands[2]) == CCFPmode
13758 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13761 (define_insn "*fp_jcc_4_387"
13763 (if_then_else (match_operator 0 "comparison_operator"
13764 [(match_operand 1 "register_operand" "f")
13765 (match_operand 2 "nonimmediate_operand" "fm")])
13767 (label_ref (match_operand 3 "" ""))))
13768 (clobber (reg:CCFP FPSR_REG))
13769 (clobber (reg:CCFP FLAGS_REG))
13770 (clobber (match_scratch:HI 4 "=a"))]
13772 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13773 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13774 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13775 && SELECT_CC_MODE (GET_CODE (operands[0]),
13776 operands[1], operands[2]) == CCFPmode
13777 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13780 (define_insn "*fp_jcc_5_387"
13782 (if_then_else (match_operator 0 "comparison_operator"
13783 [(match_operand 1 "register_operand" "f")
13784 (match_operand 2 "register_operand" "f")])
13785 (label_ref (match_operand 3 "" ""))
13787 (clobber (reg:CCFP FPSR_REG))
13788 (clobber (reg:CCFP FLAGS_REG))
13789 (clobber (match_scratch:HI 4 "=a"))]
13791 && FLOAT_MODE_P (GET_MODE (operands[1]))
13792 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13793 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13796 (define_insn "*fp_jcc_6_387"
13798 (if_then_else (match_operator 0 "comparison_operator"
13799 [(match_operand 1 "register_operand" "f")
13800 (match_operand 2 "register_operand" "f")])
13802 (label_ref (match_operand 3 "" ""))))
13803 (clobber (reg:CCFP FPSR_REG))
13804 (clobber (reg:CCFP FLAGS_REG))
13805 (clobber (match_scratch:HI 4 "=a"))]
13807 && FLOAT_MODE_P (GET_MODE (operands[1]))
13808 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13809 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13812 (define_insn "*fp_jcc_7_387"
13814 (if_then_else (match_operator 0 "comparison_operator"
13815 [(match_operand 1 "register_operand" "f")
13816 (match_operand 2 "const0_operand" "X")])
13817 (label_ref (match_operand 3 "" ""))
13819 (clobber (reg:CCFP FPSR_REG))
13820 (clobber (reg:CCFP FLAGS_REG))
13821 (clobber (match_scratch:HI 4 "=a"))]
13823 && FLOAT_MODE_P (GET_MODE (operands[1]))
13824 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13825 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
13826 && SELECT_CC_MODE (GET_CODE (operands[0]),
13827 operands[1], operands[2]) == CCFPmode
13828 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
13831 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13832 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13833 ;; with a precedence over other operators and is always put in the first
13834 ;; place. Swap condition and operands to match ficom instruction.
13836 (define_insn "*fp_jcc_8<mode>_387"
13838 (if_then_else (match_operator 0 "comparison_operator"
13839 [(match_operator 1 "float_operator"
13840 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13841 (match_operand 3 "register_operand" "f,f")])
13842 (label_ref (match_operand 4 "" ""))
13844 (clobber (reg:CCFP FPSR_REG))
13845 (clobber (reg:CCFP FLAGS_REG))
13846 (clobber (match_scratch:HI 5 "=a,a"))]
13847 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
13848 && FLOAT_MODE_P (GET_MODE (operands[3]))
13849 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13850 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
13851 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13852 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
13857 (if_then_else (match_operator 0 "comparison_operator"
13858 [(match_operand 1 "register_operand" "")
13859 (match_operand 2 "nonimmediate_operand" "")])
13860 (match_operand 3 "" "")
13861 (match_operand 4 "" "")))
13862 (clobber (reg:CCFP FPSR_REG))
13863 (clobber (reg:CCFP FLAGS_REG))]
13867 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13868 operands[3], operands[4], NULL_RTX, NULL_RTX);
13874 (if_then_else (match_operator 0 "comparison_operator"
13875 [(match_operand 1 "register_operand" "")
13876 (match_operand 2 "general_operand" "")])
13877 (match_operand 3 "" "")
13878 (match_operand 4 "" "")))
13879 (clobber (reg:CCFP FPSR_REG))
13880 (clobber (reg:CCFP FLAGS_REG))
13881 (clobber (match_scratch:HI 5 "=a"))]
13885 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13886 operands[3], operands[4], operands[5], NULL_RTX);
13892 (if_then_else (match_operator 0 "comparison_operator"
13893 [(match_operator 1 "float_operator"
13894 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13895 (match_operand 3 "register_operand" "")])
13896 (match_operand 4 "" "")
13897 (match_operand 5 "" "")))
13898 (clobber (reg:CCFP FPSR_REG))
13899 (clobber (reg:CCFP FLAGS_REG))
13900 (clobber (match_scratch:HI 6 "=a"))]
13904 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13905 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13906 operands[3], operands[7],
13907 operands[4], operands[5], operands[6], NULL_RTX);
13911 ;; %%% Kill this when reload knows how to do it.
13914 (if_then_else (match_operator 0 "comparison_operator"
13915 [(match_operator 1 "float_operator"
13916 [(match_operand:X87MODEI12 2 "register_operand" "")])
13917 (match_operand 3 "register_operand" "")])
13918 (match_operand 4 "" "")
13919 (match_operand 5 "" "")))
13920 (clobber (reg:CCFP FPSR_REG))
13921 (clobber (reg:CCFP FLAGS_REG))
13922 (clobber (match_scratch:HI 6 "=a"))]
13926 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13927 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13928 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13929 operands[3], operands[7],
13930 operands[4], operands[5], operands[6], operands[2]);
13934 ;; Unconditional and other jump instructions
13936 (define_insn "jump"
13938 (label_ref (match_operand 0 "" "")))]
13941 [(set_attr "type" "ibr")
13942 (set (attr "length")
13943 (if_then_else (and (ge (minus (match_dup 0) (pc))
13945 (lt (minus (match_dup 0) (pc))
13949 (set_attr "modrm" "0")])
13951 (define_expand "indirect_jump"
13952 [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))]
13956 (define_insn "*indirect_jump"
13957 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
13960 [(set_attr "type" "ibr")
13961 (set_attr "length_immediate" "0")])
13963 (define_insn "*indirect_jump_rtx64"
13964 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
13967 [(set_attr "type" "ibr")
13968 (set_attr "length_immediate" "0")])
13970 (define_expand "tablejump"
13971 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" "rm"))
13972 (use (label_ref (match_operand 1 "" "")))])]
13975 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13976 relative. Convert the relative address to an absolute address. */
13980 enum rtx_code code;
13986 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13988 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13992 op1 = pic_offset_table_rtx;
13997 op0 = pic_offset_table_rtx;
14001 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14006 (define_insn "*tablejump_1"
14007 [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14008 (use (label_ref (match_operand 1 "" "")))]
14011 [(set_attr "type" "ibr")
14012 (set_attr "length_immediate" "0")])
14014 (define_insn "*tablejump_1_rtx64"
14015 [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14016 (use (label_ref (match_operand 1 "" "")))]
14019 [(set_attr "type" "ibr")
14020 (set_attr "length_immediate" "0")])
14022 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14025 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14026 (set (match_operand:QI 1 "register_operand" "")
14027 (match_operator:QI 2 "ix86_comparison_operator"
14028 [(reg FLAGS_REG) (const_int 0)]))
14029 (set (match_operand 3 "q_regs_operand" "")
14030 (zero_extend (match_dup 1)))]
14031 "(peep2_reg_dead_p (3, operands[1])
14032 || operands_match_p (operands[1], operands[3]))
14033 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14034 [(set (match_dup 4) (match_dup 0))
14035 (set (strict_low_part (match_dup 5))
14038 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14039 operands[5] = gen_lowpart (QImode, operands[3]);
14040 ix86_expand_clear (operands[3]);
14043 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14046 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14047 (set (match_operand:QI 1 "register_operand" "")
14048 (match_operator:QI 2 "ix86_comparison_operator"
14049 [(reg FLAGS_REG) (const_int 0)]))
14050 (parallel [(set (match_operand 3 "q_regs_operand" "")
14051 (zero_extend (match_dup 1)))
14052 (clobber (reg:CC FLAGS_REG))])]
14053 "(peep2_reg_dead_p (3, operands[1])
14054 || operands_match_p (operands[1], operands[3]))
14055 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14056 [(set (match_dup 4) (match_dup 0))
14057 (set (strict_low_part (match_dup 5))
14060 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14061 operands[5] = gen_lowpart (QImode, operands[3]);
14062 ix86_expand_clear (operands[3]);
14065 ;; Call instructions.
14067 ;; The predicates normally associated with named expanders are not properly
14068 ;; checked for calls. This is a bug in the generic code, but it isn't that
14069 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14071 ;; Call subroutine returning no value.
14073 (define_expand "call_pop"
14074 [(parallel [(call (match_operand:QI 0 "" "")
14075 (match_operand:SI 1 "" ""))
14076 (set (reg:SI SP_REG)
14077 (plus:SI (reg:SI SP_REG)
14078 (match_operand:SI 3 "" "")))])]
14081 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14085 (define_insn "*call_pop_0"
14086 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14087 (match_operand:SI 1 "" ""))
14088 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14089 (match_operand:SI 2 "immediate_operand" "")))]
14092 if (SIBLING_CALL_P (insn))
14095 return "call\t%P0";
14097 [(set_attr "type" "call")])
14099 (define_insn "*call_pop_1"
14100 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14101 (match_operand:SI 1 "" ""))
14102 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14103 (match_operand:SI 2 "immediate_operand" "i")))]
14106 if (constant_call_address_operand (operands[0], Pmode))
14108 if (SIBLING_CALL_P (insn))
14111 return "call\t%P0";
14113 if (SIBLING_CALL_P (insn))
14116 return "call\t%A0";
14118 [(set_attr "type" "call")])
14120 (define_expand "call"
14121 [(call (match_operand:QI 0 "" "")
14122 (match_operand 1 "" ""))
14123 (use (match_operand 2 "" ""))]
14126 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14130 (define_expand "sibcall"
14131 [(call (match_operand:QI 0 "" "")
14132 (match_operand 1 "" ""))
14133 (use (match_operand 2 "" ""))]
14136 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14140 (define_insn "*call_0"
14141 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14142 (match_operand 1 "" ""))]
14145 if (SIBLING_CALL_P (insn))
14148 return "call\t%P0";
14150 [(set_attr "type" "call")])
14152 (define_insn "*call_1"
14153 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14154 (match_operand 1 "" ""))]
14155 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14157 if (constant_call_address_operand (operands[0], Pmode))
14158 return "call\t%P0";
14159 return "call\t%A0";
14161 [(set_attr "type" "call")])
14163 (define_insn "*sibcall_1"
14164 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14165 (match_operand 1 "" ""))]
14166 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14168 if (constant_call_address_operand (operands[0], Pmode))
14172 [(set_attr "type" "call")])
14174 (define_insn "*call_1_rex64"
14175 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14176 (match_operand 1 "" ""))]
14177 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14179 if (constant_call_address_operand (operands[0], Pmode))
14180 return "call\t%P0";
14181 return "call\t%A0";
14183 [(set_attr "type" "call")])
14185 (define_insn "*sibcall_1_rex64"
14186 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14187 (match_operand 1 "" ""))]
14188 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14190 [(set_attr "type" "call")])
14192 (define_insn "*sibcall_1_rex64_v"
14193 [(call (mem:QI (reg:DI R11_REG))
14194 (match_operand 0 "" ""))]
14195 "SIBLING_CALL_P (insn) && TARGET_64BIT"
14197 [(set_attr "type" "call")])
14200 ;; Call subroutine, returning value in operand 0
14202 (define_expand "call_value_pop"
14203 [(parallel [(set (match_operand 0 "" "")
14204 (call (match_operand:QI 1 "" "")
14205 (match_operand:SI 2 "" "")))
14206 (set (reg:SI SP_REG)
14207 (plus:SI (reg:SI SP_REG)
14208 (match_operand:SI 4 "" "")))])]
14211 ix86_expand_call (operands[0], operands[1], operands[2],
14212 operands[3], operands[4], 0);
14216 (define_expand "call_value"
14217 [(set (match_operand 0 "" "")
14218 (call (match_operand:QI 1 "" "")
14219 (match_operand:SI 2 "" "")))
14220 (use (match_operand:SI 3 "" ""))]
14221 ;; Operand 2 not used on the i386.
14224 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14228 (define_expand "sibcall_value"
14229 [(set (match_operand 0 "" "")
14230 (call (match_operand:QI 1 "" "")
14231 (match_operand:SI 2 "" "")))
14232 (use (match_operand:SI 3 "" ""))]
14233 ;; Operand 2 not used on the i386.
14236 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14240 ;; Call subroutine returning any type.
14242 (define_expand "untyped_call"
14243 [(parallel [(call (match_operand 0 "" "")
14245 (match_operand 1 "" "")
14246 (match_operand 2 "" "")])]
14251 /* In order to give reg-stack an easier job in validating two
14252 coprocessor registers as containing a possible return value,
14253 simply pretend the untyped call returns a complex long double
14256 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14257 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14258 operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14261 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14263 rtx set = XVECEXP (operands[2], 0, i);
14264 emit_move_insn (SET_DEST (set), SET_SRC (set));
14267 /* The optimizer does not know that the call sets the function value
14268 registers we stored in the result block. We avoid problems by
14269 claiming that all hard registers are used and clobbered at this
14271 emit_insn (gen_blockage (const0_rtx));
14276 ;; Prologue and epilogue instructions
14278 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14279 ;; all of memory. This blocks insns from being moved across this point.
14281 (define_insn "blockage"
14282 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_BLOCKAGE)]
14285 [(set_attr "length" "0")])
14287 ;; Insn emitted into the body of a function to return from a function.
14288 ;; This is only done if the function's epilogue is known to be simple.
14289 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14291 (define_expand "return"
14293 "ix86_can_use_return_insn_p ()"
14295 if (current_function_pops_args)
14297 rtx popc = GEN_INT (current_function_pops_args);
14298 emit_jump_insn (gen_return_pop_internal (popc));
14303 (define_insn "return_internal"
14307 [(set_attr "length" "1")
14308 (set_attr "length_immediate" "0")
14309 (set_attr "modrm" "0")])
14311 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14312 ;; instruction Athlon and K8 have.
14314 (define_insn "return_internal_long"
14316 (unspec [(const_int 0)] UNSPEC_REP)]
14319 [(set_attr "length" "1")
14320 (set_attr "length_immediate" "0")
14321 (set_attr "prefix_rep" "1")
14322 (set_attr "modrm" "0")])
14324 (define_insn "return_pop_internal"
14326 (use (match_operand:SI 0 "const_int_operand" ""))]
14329 [(set_attr "length" "3")
14330 (set_attr "length_immediate" "2")
14331 (set_attr "modrm" "0")])
14333 (define_insn "return_indirect_internal"
14335 (use (match_operand:SI 0 "register_operand" "r"))]
14338 [(set_attr "type" "ibr")
14339 (set_attr "length_immediate" "0")])
14345 [(set_attr "length" "1")
14346 (set_attr "length_immediate" "0")
14347 (set_attr "modrm" "0")])
14349 ;; Align to 16-byte boundary, max skip in op0. Used to avoid
14350 ;; branch prediction penalty for the third jump in a 16-byte
14353 (define_insn "align"
14354 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14357 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14358 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14360 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14361 The align insn is used to avoid 3 jump instructions in the row to improve
14362 branch prediction and the benefits hardly outweigh the cost of extra 8
14363 nops on the average inserted by full alignment pseudo operation. */
14367 [(set_attr "length" "16")])
14369 (define_expand "prologue"
14372 "ix86_expand_prologue (); DONE;")
14374 (define_insn "set_got"
14375 [(set (match_operand:SI 0 "register_operand" "=r")
14376 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14377 (clobber (reg:CC FLAGS_REG))]
14379 { return output_set_got (operands[0], NULL_RTX); }
14380 [(set_attr "type" "multi")
14381 (set_attr "length" "12")])
14383 (define_insn "set_got_labelled"
14384 [(set (match_operand:SI 0 "register_operand" "=r")
14385 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14387 (clobber (reg:CC FLAGS_REG))]
14389 { return output_set_got (operands[0], operands[1]); }
14390 [(set_attr "type" "multi")
14391 (set_attr "length" "12")])
14393 (define_insn "set_got_rex64"
14394 [(set (match_operand:DI 0 "register_operand" "=r")
14395 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14397 "lea{q}\t_GLOBAL_OFFSET_TABLE_(%%rip), %0"
14398 [(set_attr "type" "lea")
14399 (set_attr "length" "6")])
14401 (define_expand "epilogue"
14404 "ix86_expand_epilogue (1); DONE;")
14406 (define_expand "sibcall_epilogue"
14409 "ix86_expand_epilogue (0); DONE;")
14411 (define_expand "eh_return"
14412 [(use (match_operand 0 "register_operand" ""))]
14415 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14417 /* Tricky bit: we write the address of the handler to which we will
14418 be returning into someone else's stack frame, one word below the
14419 stack address we wish to restore. */
14420 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14421 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14422 tmp = gen_rtx_MEM (Pmode, tmp);
14423 emit_move_insn (tmp, ra);
14425 if (Pmode == SImode)
14426 emit_jump_insn (gen_eh_return_si (sa));
14428 emit_jump_insn (gen_eh_return_di (sa));
14433 (define_insn_and_split "eh_return_si"
14435 (unspec [(match_operand:SI 0 "register_operand" "c")]
14436 UNSPEC_EH_RETURN))]
14441 "ix86_expand_epilogue (2); DONE;")
14443 (define_insn_and_split "eh_return_di"
14445 (unspec [(match_operand:DI 0 "register_operand" "c")]
14446 UNSPEC_EH_RETURN))]
14451 "ix86_expand_epilogue (2); DONE;")
14453 (define_insn "leave"
14454 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14455 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14456 (clobber (mem:BLK (scratch)))]
14459 [(set_attr "type" "leave")])
14461 (define_insn "leave_rex64"
14462 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14463 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14464 (clobber (mem:BLK (scratch)))]
14467 [(set_attr "type" "leave")])
14469 (define_expand "ffssi2"
14471 [(set (match_operand:SI 0 "register_operand" "")
14472 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14473 (clobber (match_scratch:SI 2 ""))
14474 (clobber (reg:CC FLAGS_REG))])]
14478 (define_insn_and_split "*ffs_cmove"
14479 [(set (match_operand:SI 0 "register_operand" "=r")
14480 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14481 (clobber (match_scratch:SI 2 "=&r"))
14482 (clobber (reg:CC FLAGS_REG))]
14485 "&& reload_completed"
14486 [(set (match_dup 2) (const_int -1))
14487 (parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14488 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14489 (set (match_dup 0) (if_then_else:SI
14490 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14493 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14494 (clobber (reg:CC FLAGS_REG))])]
14497 (define_insn_and_split "*ffs_no_cmove"
14498 [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14499 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14500 (clobber (match_scratch:SI 2 "=&q"))
14501 (clobber (reg:CC FLAGS_REG))]
14505 [(parallel [(set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))
14506 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14507 (set (strict_low_part (match_dup 3))
14508 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14509 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14510 (clobber (reg:CC FLAGS_REG))])
14511 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14512 (clobber (reg:CC FLAGS_REG))])
14513 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14514 (clobber (reg:CC FLAGS_REG))])]
14516 operands[3] = gen_lowpart (QImode, operands[2]);
14517 ix86_expand_clear (operands[2]);
14520 (define_insn "*ffssi_1"
14521 [(set (reg:CCZ FLAGS_REG)
14522 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14524 (set (match_operand:SI 0 "register_operand" "=r")
14525 (ctz:SI (match_dup 1)))]
14527 "bsf{l}\t{%1, %0|%0, %1}"
14528 [(set_attr "prefix_0f" "1")])
14530 (define_expand "ffsdi2"
14532 [(set (match_operand:DI 0 "register_operand" "")
14533 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "")))
14534 (clobber (match_scratch:DI 2 ""))
14535 (clobber (reg:CC FLAGS_REG))])]
14536 "TARGET_64BIT && TARGET_CMOVE"
14539 (define_insn_and_split "*ffs_rex64"
14540 [(set (match_operand:DI 0 "register_operand" "=r")
14541 (ffs:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14542 (clobber (match_scratch:DI 2 "=&r"))
14543 (clobber (reg:CC FLAGS_REG))]
14544 "TARGET_64BIT && TARGET_CMOVE"
14546 "&& reload_completed"
14547 [(set (match_dup 2) (const_int -1))
14548 (parallel [(set (reg:CCZ FLAGS_REG)
14549 (compare:CCZ (match_dup 1) (const_int 0)))
14550 (set (match_dup 0) (ctz:DI (match_dup 1)))])
14551 (set (match_dup 0) (if_then_else:DI
14552 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14555 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14556 (clobber (reg:CC FLAGS_REG))])]
14559 (define_insn "*ffsdi_1"
14560 [(set (reg:CCZ FLAGS_REG)
14561 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14563 (set (match_operand:DI 0 "register_operand" "=r")
14564 (ctz:DI (match_dup 1)))]
14566 "bsf{q}\t{%1, %0|%0, %1}"
14567 [(set_attr "prefix_0f" "1")])
14569 (define_insn "ctzsi2"
14570 [(set (match_operand:SI 0 "register_operand" "=r")
14571 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14572 (clobber (reg:CC FLAGS_REG))]
14574 "bsf{l}\t{%1, %0|%0, %1}"
14575 [(set_attr "prefix_0f" "1")])
14577 (define_insn "ctzdi2"
14578 [(set (match_operand:DI 0 "register_operand" "=r")
14579 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14580 (clobber (reg:CC FLAGS_REG))]
14582 "bsf{q}\t{%1, %0|%0, %1}"
14583 [(set_attr "prefix_0f" "1")])
14585 (define_expand "clzsi2"
14587 [(set (match_operand:SI 0 "register_operand" "")
14588 (minus:SI (const_int 31)
14589 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14590 (clobber (reg:CC FLAGS_REG))])
14592 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14593 (clobber (reg:CC FLAGS_REG))])]
14597 (define_insn "*bsr"
14598 [(set (match_operand:SI 0 "register_operand" "=r")
14599 (minus:SI (const_int 31)
14600 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14601 (clobber (reg:CC FLAGS_REG))]
14603 "bsr{l}\t{%1, %0|%0, %1}"
14604 [(set_attr "prefix_0f" "1")])
14606 (define_insn "bswapsi2"
14607 [(set (match_operand:SI 0 "register_operand" "=r")
14608 (bswap:SI (match_operand:SI 1 "register_operand" "0")))
14609 (clobber (reg:CC FLAGS_REG))]
14612 [(set_attr "prefix_0f" "1")
14613 (set_attr "length" "2")])
14615 (define_insn "bswapdi2"
14616 [(set (match_operand:DI 0 "register_operand" "=r")
14617 (bswap:DI (match_operand:DI 1 "register_operand" "0")))
14618 (clobber (reg:CC FLAGS_REG))]
14619 "TARGET_64BIT && TARGET_BSWAP"
14621 [(set_attr "prefix_0f" "1")
14622 (set_attr "length" "3")])
14624 (define_expand "clzdi2"
14626 [(set (match_operand:DI 0 "register_operand" "")
14627 (minus:DI (const_int 63)
14628 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14629 (clobber (reg:CC FLAGS_REG))])
14631 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14632 (clobber (reg:CC FLAGS_REG))])]
14636 (define_insn "*bsr_rex64"
14637 [(set (match_operand:DI 0 "register_operand" "=r")
14638 (minus:DI (const_int 63)
14639 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14640 (clobber (reg:CC FLAGS_REG))]
14642 "bsr{q}\t{%1, %0|%0, %1}"
14643 [(set_attr "prefix_0f" "1")])
14645 ;; Thread-local storage patterns for ELF.
14647 ;; Note that these code sequences must appear exactly as shown
14648 ;; in order to allow linker relaxation.
14650 (define_insn "*tls_global_dynamic_32_gnu"
14651 [(set (match_operand:SI 0 "register_operand" "=a")
14652 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14653 (match_operand:SI 2 "tls_symbolic_operand" "")
14654 (match_operand:SI 3 "call_insn_operand" "")]
14656 (clobber (match_scratch:SI 4 "=d"))
14657 (clobber (match_scratch:SI 5 "=c"))
14658 (clobber (reg:CC FLAGS_REG))]
14659 "!TARGET_64BIT && TARGET_GNU_TLS"
14660 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14661 [(set_attr "type" "multi")
14662 (set_attr "length" "12")])
14664 (define_insn "*tls_global_dynamic_32_sun"
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_SUN_TLS"
14674 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14675 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14676 [(set_attr "type" "multi")
14677 (set_attr "length" "14")])
14679 (define_expand "tls_global_dynamic_32"
14680 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14683 (match_operand:SI 1 "tls_symbolic_operand" "")
14686 (clobber (match_scratch:SI 4 ""))
14687 (clobber (match_scratch:SI 5 ""))
14688 (clobber (reg:CC FLAGS_REG))])]
14692 operands[2] = pic_offset_table_rtx;
14695 operands[2] = gen_reg_rtx (Pmode);
14696 emit_insn (gen_set_got (operands[2]));
14698 if (TARGET_GNU2_TLS)
14700 emit_insn (gen_tls_dynamic_gnu2_32
14701 (operands[0], operands[1], operands[2]));
14704 operands[3] = ix86_tls_get_addr ();
14707 (define_insn "*tls_global_dynamic_64"
14708 [(set (match_operand:DI 0 "register_operand" "=a")
14709 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14710 (match_operand:DI 3 "" "")))
14711 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14714 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|%%rdi, %a1@TLSGD[%%rip]}\;.word\t0x6666\;rex64\;call\t%P2"
14715 [(set_attr "type" "multi")
14716 (set_attr "length" "16")])
14718 (define_expand "tls_global_dynamic_64"
14719 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14720 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14721 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14725 if (TARGET_GNU2_TLS)
14727 emit_insn (gen_tls_dynamic_gnu2_64
14728 (operands[0], operands[1]));
14731 operands[2] = ix86_tls_get_addr ();
14734 (define_insn "*tls_local_dynamic_base_32_gnu"
14735 [(set (match_operand:SI 0 "register_operand" "=a")
14736 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14737 (match_operand:SI 2 "call_insn_operand" "")]
14738 UNSPEC_TLS_LD_BASE))
14739 (clobber (match_scratch:SI 3 "=d"))
14740 (clobber (match_scratch:SI 4 "=c"))
14741 (clobber (reg:CC FLAGS_REG))]
14742 "!TARGET_64BIT && TARGET_GNU_TLS"
14743 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14744 [(set_attr "type" "multi")
14745 (set_attr "length" "11")])
14747 (define_insn "*tls_local_dynamic_base_32_sun"
14748 [(set (match_operand:SI 0 "register_operand" "=a")
14749 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14750 (match_operand:SI 2 "call_insn_operand" "")]
14751 UNSPEC_TLS_LD_BASE))
14752 (clobber (match_scratch:SI 3 "=d"))
14753 (clobber (match_scratch:SI 4 "=c"))
14754 (clobber (reg:CC FLAGS_REG))]
14755 "!TARGET_64BIT && TARGET_SUN_TLS"
14756 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14757 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14758 [(set_attr "type" "multi")
14759 (set_attr "length" "13")])
14761 (define_expand "tls_local_dynamic_base_32"
14762 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14763 (unspec:SI [(match_dup 1) (match_dup 2)]
14764 UNSPEC_TLS_LD_BASE))
14765 (clobber (match_scratch:SI 3 ""))
14766 (clobber (match_scratch:SI 4 ""))
14767 (clobber (reg:CC FLAGS_REG))])]
14771 operands[1] = pic_offset_table_rtx;
14774 operands[1] = gen_reg_rtx (Pmode);
14775 emit_insn (gen_set_got (operands[1]));
14777 if (TARGET_GNU2_TLS)
14779 emit_insn (gen_tls_dynamic_gnu2_32
14780 (operands[0], ix86_tls_module_base (), operands[1]));
14783 operands[2] = ix86_tls_get_addr ();
14786 (define_insn "*tls_local_dynamic_base_64"
14787 [(set (match_operand:DI 0 "register_operand" "=a")
14788 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14789 (match_operand:DI 2 "" "")))
14790 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14792 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|%%rdi, %&@TLSLD[%%rip]}\;call\t%P1"
14793 [(set_attr "type" "multi")
14794 (set_attr "length" "12")])
14796 (define_expand "tls_local_dynamic_base_64"
14797 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14798 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14799 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14802 if (TARGET_GNU2_TLS)
14804 emit_insn (gen_tls_dynamic_gnu2_64
14805 (operands[0], ix86_tls_module_base ()));
14808 operands[1] = ix86_tls_get_addr ();
14811 ;; Local dynamic of a single variable is a lose. Show combine how
14812 ;; to convert that back to global dynamic.
14814 (define_insn_and_split "*tls_local_dynamic_32_once"
14815 [(set (match_operand:SI 0 "register_operand" "=a")
14816 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14817 (match_operand:SI 2 "call_insn_operand" "")]
14818 UNSPEC_TLS_LD_BASE)
14819 (const:SI (unspec:SI
14820 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14822 (clobber (match_scratch:SI 4 "=d"))
14823 (clobber (match_scratch:SI 5 "=c"))
14824 (clobber (reg:CC FLAGS_REG))]
14828 [(parallel [(set (match_dup 0)
14829 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14831 (clobber (match_dup 4))
14832 (clobber (match_dup 5))
14833 (clobber (reg:CC FLAGS_REG))])]
14836 ;; Load and add the thread base pointer from %gs:0.
14838 (define_insn "*load_tp_si"
14839 [(set (match_operand:SI 0 "register_operand" "=r")
14840 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14842 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14843 [(set_attr "type" "imov")
14844 (set_attr "modrm" "0")
14845 (set_attr "length" "7")
14846 (set_attr "memory" "load")
14847 (set_attr "imm_disp" "false")])
14849 (define_insn "*add_tp_si"
14850 [(set (match_operand:SI 0 "register_operand" "=r")
14851 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14852 (match_operand:SI 1 "register_operand" "0")))
14853 (clobber (reg:CC FLAGS_REG))]
14855 "add{l}\t{%%gs:0, %0|%0, DWORD PTR %%gs:0}"
14856 [(set_attr "type" "alu")
14857 (set_attr "modrm" "0")
14858 (set_attr "length" "7")
14859 (set_attr "memory" "load")
14860 (set_attr "imm_disp" "false")])
14862 (define_insn "*load_tp_di"
14863 [(set (match_operand:DI 0 "register_operand" "=r")
14864 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14866 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14867 [(set_attr "type" "imov")
14868 (set_attr "modrm" "0")
14869 (set_attr "length" "7")
14870 (set_attr "memory" "load")
14871 (set_attr "imm_disp" "false")])
14873 (define_insn "*add_tp_di"
14874 [(set (match_operand:DI 0 "register_operand" "=r")
14875 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14876 (match_operand:DI 1 "register_operand" "0")))
14877 (clobber (reg:CC FLAGS_REG))]
14879 "add{q}\t{%%fs:0, %0|%0, QWORD PTR %%fs:0}"
14880 [(set_attr "type" "alu")
14881 (set_attr "modrm" "0")
14882 (set_attr "length" "7")
14883 (set_attr "memory" "load")
14884 (set_attr "imm_disp" "false")])
14886 ;; GNU2 TLS patterns can be split.
14888 (define_expand "tls_dynamic_gnu2_32"
14889 [(set (match_dup 3)
14890 (plus:SI (match_operand:SI 2 "register_operand" "")
14892 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14895 [(set (match_operand:SI 0 "register_operand" "")
14896 (unspec:SI [(match_dup 1) (match_dup 3)
14897 (match_dup 2) (reg:SI SP_REG)]
14899 (clobber (reg:CC FLAGS_REG))])]
14900 "!TARGET_64BIT && TARGET_GNU2_TLS"
14902 operands[3] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14903 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14906 (define_insn "*tls_dynamic_lea_32"
14907 [(set (match_operand:SI 0 "register_operand" "=r")
14908 (plus:SI (match_operand:SI 1 "register_operand" "b")
14910 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14911 UNSPEC_TLSDESC))))]
14912 "!TARGET_64BIT && TARGET_GNU2_TLS"
14913 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14914 [(set_attr "type" "lea")
14915 (set_attr "mode" "SI")
14916 (set_attr "length" "6")
14917 (set_attr "length_address" "4")])
14919 (define_insn "*tls_dynamic_call_32"
14920 [(set (match_operand:SI 0 "register_operand" "=a")
14921 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14922 (match_operand:SI 2 "register_operand" "0")
14923 ;; we have to make sure %ebx still points to the GOT
14924 (match_operand:SI 3 "register_operand" "b")
14927 (clobber (reg:CC FLAGS_REG))]
14928 "!TARGET_64BIT && TARGET_GNU2_TLS"
14929 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14930 [(set_attr "type" "call")
14931 (set_attr "length" "2")
14932 (set_attr "length_address" "0")])
14934 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14935 [(set (match_operand:SI 0 "register_operand" "=&a")
14937 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14938 (match_operand:SI 4 "" "")
14939 (match_operand:SI 2 "register_operand" "b")
14942 (const:SI (unspec:SI
14943 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14945 (clobber (reg:CC FLAGS_REG))]
14946 "!TARGET_64BIT && TARGET_GNU2_TLS"
14949 [(set (match_dup 0) (match_dup 5))]
14951 operands[5] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14952 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14955 (define_expand "tls_dynamic_gnu2_64"
14956 [(set (match_dup 2)
14957 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14960 [(set (match_operand:DI 0 "register_operand" "")
14961 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14963 (clobber (reg:CC FLAGS_REG))])]
14964 "TARGET_64BIT && TARGET_GNU2_TLS"
14966 operands[2] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
14967 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14970 (define_insn "*tls_dynamic_lea_64"
14971 [(set (match_operand:DI 0 "register_operand" "=r")
14972 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14974 "TARGET_64BIT && TARGET_GNU2_TLS"
14975 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[%%rip]}"
14976 [(set_attr "type" "lea")
14977 (set_attr "mode" "DI")
14978 (set_attr "length" "7")
14979 (set_attr "length_address" "4")])
14981 (define_insn "*tls_dynamic_call_64"
14982 [(set (match_operand:DI 0 "register_operand" "=a")
14983 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14984 (match_operand:DI 2 "register_operand" "0")
14987 (clobber (reg:CC FLAGS_REG))]
14988 "TARGET_64BIT && TARGET_GNU2_TLS"
14989 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14990 [(set_attr "type" "call")
14991 (set_attr "length" "2")
14992 (set_attr "length_address" "0")])
14994 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14995 [(set (match_operand:DI 0 "register_operand" "=&a")
14997 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14998 (match_operand:DI 3 "" "")
15001 (const:DI (unspec:DI
15002 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15004 (clobber (reg:CC FLAGS_REG))]
15005 "TARGET_64BIT && TARGET_GNU2_TLS"
15008 [(set (match_dup 0) (match_dup 4))]
15010 operands[4] = no_new_pseudos ? operands[0] : gen_reg_rtx (Pmode);
15011 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15016 ;; These patterns match the binary 387 instructions for addM3, subM3,
15017 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15018 ;; SFmode. The first is the normal insn, the second the same insn but
15019 ;; with one operand a conversion, and the third the same insn but with
15020 ;; the other operand a conversion. The conversion may be SFmode or
15021 ;; SImode if the target mode DFmode, but only SImode if the target mode
15024 ;; Gcc is slightly more smart about handling normal two address instructions
15025 ;; so use special patterns for add and mull.
15027 (define_insn "*fop_sf_comm_mixed"
15028 [(set (match_operand:SF 0 "register_operand" "=f,x")
15029 (match_operator:SF 3 "binary_fp_operator"
15030 [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15031 (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15032 "TARGET_MIX_SSE_I387
15033 && COMMUTATIVE_ARITH_P (operands[3])
15034 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15035 "* return output_387_binary_op (insn, operands);"
15036 [(set (attr "type")
15037 (if_then_else (eq_attr "alternative" "1")
15038 (if_then_else (match_operand:SF 3 "mult_operator" "")
15039 (const_string "ssemul")
15040 (const_string "sseadd"))
15041 (if_then_else (match_operand:SF 3 "mult_operator" "")
15042 (const_string "fmul")
15043 (const_string "fop"))))
15044 (set_attr "mode" "SF")])
15046 (define_insn "*fop_sf_comm_sse"
15047 [(set (match_operand:SF 0 "register_operand" "=x")
15048 (match_operator:SF 3 "binary_fp_operator"
15049 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15050 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15052 && COMMUTATIVE_ARITH_P (operands[3])
15053 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15054 "* return output_387_binary_op (insn, operands);"
15055 [(set (attr "type")
15056 (if_then_else (match_operand:SF 3 "mult_operator" "")
15057 (const_string "ssemul")
15058 (const_string "sseadd")))
15059 (set_attr "mode" "SF")])
15061 (define_insn "*fop_sf_comm_i387"
15062 [(set (match_operand:SF 0 "register_operand" "=f")
15063 (match_operator:SF 3 "binary_fp_operator"
15064 [(match_operand:SF 1 "nonimmediate_operand" "%0")
15065 (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15067 && COMMUTATIVE_ARITH_P (operands[3])
15068 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15069 "* return output_387_binary_op (insn, operands);"
15070 [(set (attr "type")
15071 (if_then_else (match_operand:SF 3 "mult_operator" "")
15072 (const_string "fmul")
15073 (const_string "fop")))
15074 (set_attr "mode" "SF")])
15076 (define_insn "*fop_sf_1_mixed"
15077 [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15078 (match_operator:SF 3 "binary_fp_operator"
15079 [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15080 (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15081 "TARGET_MIX_SSE_I387
15082 && !COMMUTATIVE_ARITH_P (operands[3])
15083 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15084 "* return output_387_binary_op (insn, operands);"
15085 [(set (attr "type")
15086 (cond [(and (eq_attr "alternative" "2")
15087 (match_operand:SF 3 "mult_operator" ""))
15088 (const_string "ssemul")
15089 (and (eq_attr "alternative" "2")
15090 (match_operand:SF 3 "div_operator" ""))
15091 (const_string "ssediv")
15092 (eq_attr "alternative" "2")
15093 (const_string "sseadd")
15094 (match_operand:SF 3 "mult_operator" "")
15095 (const_string "fmul")
15096 (match_operand:SF 3 "div_operator" "")
15097 (const_string "fdiv")
15099 (const_string "fop")))
15100 (set_attr "mode" "SF")])
15102 (define_insn "*fop_sf_1_sse"
15103 [(set (match_operand:SF 0 "register_operand" "=x")
15104 (match_operator:SF 3 "binary_fp_operator"
15105 [(match_operand:SF 1 "register_operand" "0")
15106 (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15108 && !COMMUTATIVE_ARITH_P (operands[3])"
15109 "* return output_387_binary_op (insn, operands);"
15110 [(set (attr "type")
15111 (cond [(match_operand:SF 3 "mult_operator" "")
15112 (const_string "ssemul")
15113 (match_operand:SF 3 "div_operator" "")
15114 (const_string "ssediv")
15116 (const_string "sseadd")))
15117 (set_attr "mode" "SF")])
15119 ;; This pattern is not fully shadowed by the pattern above.
15120 (define_insn "*fop_sf_1_i387"
15121 [(set (match_operand:SF 0 "register_operand" "=f,f")
15122 (match_operator:SF 3 "binary_fp_operator"
15123 [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15124 (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15125 "TARGET_80387 && !TARGET_SSE_MATH
15126 && !COMMUTATIVE_ARITH_P (operands[3])
15127 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15128 "* return output_387_binary_op (insn, operands);"
15129 [(set (attr "type")
15130 (cond [(match_operand:SF 3 "mult_operator" "")
15131 (const_string "fmul")
15132 (match_operand:SF 3 "div_operator" "")
15133 (const_string "fdiv")
15135 (const_string "fop")))
15136 (set_attr "mode" "SF")])
15138 ;; ??? Add SSE splitters for these!
15139 (define_insn "*fop_sf_2<mode>_i387"
15140 [(set (match_operand:SF 0 "register_operand" "=f,f")
15141 (match_operator:SF 3 "binary_fp_operator"
15142 [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15143 (match_operand:SF 2 "register_operand" "0,0")]))]
15144 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15145 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15146 [(set (attr "type")
15147 (cond [(match_operand:SF 3 "mult_operator" "")
15148 (const_string "fmul")
15149 (match_operand:SF 3 "div_operator" "")
15150 (const_string "fdiv")
15152 (const_string "fop")))
15153 (set_attr "fp_int_src" "true")
15154 (set_attr "mode" "<MODE>")])
15156 (define_insn "*fop_sf_3<mode>_i387"
15157 [(set (match_operand:SF 0 "register_operand" "=f,f")
15158 (match_operator:SF 3 "binary_fp_operator"
15159 [(match_operand:SF 1 "register_operand" "0,0")
15160 (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15161 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15162 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15163 [(set (attr "type")
15164 (cond [(match_operand:SF 3 "mult_operator" "")
15165 (const_string "fmul")
15166 (match_operand:SF 3 "div_operator" "")
15167 (const_string "fdiv")
15169 (const_string "fop")))
15170 (set_attr "fp_int_src" "true")
15171 (set_attr "mode" "<MODE>")])
15173 (define_insn "*fop_df_comm_mixed"
15174 [(set (match_operand:DF 0 "register_operand" "=f,Y")
15175 (match_operator:DF 3 "binary_fp_operator"
15176 [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15177 (match_operand:DF 2 "nonimmediate_operand" "fm,Ym")]))]
15178 "TARGET_SSE2 && TARGET_MIX_SSE_I387
15179 && COMMUTATIVE_ARITH_P (operands[3])
15180 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15181 "* return output_387_binary_op (insn, operands);"
15182 [(set (attr "type")
15183 (if_then_else (eq_attr "alternative" "1")
15184 (if_then_else (match_operand:DF 3 "mult_operator" "")
15185 (const_string "ssemul")
15186 (const_string "sseadd"))
15187 (if_then_else (match_operand:DF 3 "mult_operator" "")
15188 (const_string "fmul")
15189 (const_string "fop"))))
15190 (set_attr "mode" "DF")])
15192 (define_insn "*fop_df_comm_sse"
15193 [(set (match_operand:DF 0 "register_operand" "=Y")
15194 (match_operator:DF 3 "binary_fp_operator"
15195 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15196 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15197 "TARGET_SSE2 && TARGET_SSE_MATH
15198 && COMMUTATIVE_ARITH_P (operands[3])
15199 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15200 "* return output_387_binary_op (insn, operands);"
15201 [(set (attr "type")
15202 (if_then_else (match_operand:DF 3 "mult_operator" "")
15203 (const_string "ssemul")
15204 (const_string "sseadd")))
15205 (set_attr "mode" "DF")])
15207 (define_insn "*fop_df_comm_i387"
15208 [(set (match_operand:DF 0 "register_operand" "=f")
15209 (match_operator:DF 3 "binary_fp_operator"
15210 [(match_operand:DF 1 "nonimmediate_operand" "%0")
15211 (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15213 && COMMUTATIVE_ARITH_P (operands[3])
15214 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15215 "* return output_387_binary_op (insn, operands);"
15216 [(set (attr "type")
15217 (if_then_else (match_operand:DF 3 "mult_operator" "")
15218 (const_string "fmul")
15219 (const_string "fop")))
15220 (set_attr "mode" "DF")])
15222 (define_insn "*fop_df_1_mixed"
15223 [(set (match_operand:DF 0 "register_operand" "=f,f,Y")
15224 (match_operator:DF 3 "binary_fp_operator"
15225 [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
15226 (match_operand:DF 2 "nonimmediate_operand" "fm,0,Ym")]))]
15227 "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
15228 && !COMMUTATIVE_ARITH_P (operands[3])
15229 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15230 "* return output_387_binary_op (insn, operands);"
15231 [(set (attr "type")
15232 (cond [(and (eq_attr "alternative" "2")
15233 (match_operand:DF 3 "mult_operator" ""))
15234 (const_string "ssemul")
15235 (and (eq_attr "alternative" "2")
15236 (match_operand:DF 3 "div_operator" ""))
15237 (const_string "ssediv")
15238 (eq_attr "alternative" "2")
15239 (const_string "sseadd")
15240 (match_operand:DF 3 "mult_operator" "")
15241 (const_string "fmul")
15242 (match_operand:DF 3 "div_operator" "")
15243 (const_string "fdiv")
15245 (const_string "fop")))
15246 (set_attr "mode" "DF")])
15248 (define_insn "*fop_df_1_sse"
15249 [(set (match_operand:DF 0 "register_operand" "=Y")
15250 (match_operator:DF 3 "binary_fp_operator"
15251 [(match_operand:DF 1 "register_operand" "0")
15252 (match_operand:DF 2 "nonimmediate_operand" "Ym")]))]
15253 "TARGET_SSE2 && TARGET_SSE_MATH
15254 && !COMMUTATIVE_ARITH_P (operands[3])"
15255 "* return output_387_binary_op (insn, operands);"
15256 [(set_attr "mode" "DF")
15258 (cond [(match_operand:DF 3 "mult_operator" "")
15259 (const_string "ssemul")
15260 (match_operand:DF 3 "div_operator" "")
15261 (const_string "ssediv")
15263 (const_string "sseadd")))])
15265 ;; This pattern is not fully shadowed by the pattern above.
15266 (define_insn "*fop_df_1_i387"
15267 [(set (match_operand:DF 0 "register_operand" "=f,f")
15268 (match_operator:DF 3 "binary_fp_operator"
15269 [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
15270 (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
15271 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15272 && !COMMUTATIVE_ARITH_P (operands[3])
15273 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15274 "* return output_387_binary_op (insn, operands);"
15275 [(set (attr "type")
15276 (cond [(match_operand:DF 3 "mult_operator" "")
15277 (const_string "fmul")
15278 (match_operand:DF 3 "div_operator" "")
15279 (const_string "fdiv")
15281 (const_string "fop")))
15282 (set_attr "mode" "DF")])
15284 ;; ??? Add SSE splitters for these!
15285 (define_insn "*fop_df_2<mode>_i387"
15286 [(set (match_operand:DF 0 "register_operand" "=f,f")
15287 (match_operator:DF 3 "binary_fp_operator"
15288 [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15289 (match_operand:DF 2 "register_operand" "0,0")]))]
15290 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15291 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15292 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15293 [(set (attr "type")
15294 (cond [(match_operand:DF 3 "mult_operator" "")
15295 (const_string "fmul")
15296 (match_operand:DF 3 "div_operator" "")
15297 (const_string "fdiv")
15299 (const_string "fop")))
15300 (set_attr "fp_int_src" "true")
15301 (set_attr "mode" "<MODE>")])
15303 (define_insn "*fop_df_3<mode>_i387"
15304 [(set (match_operand:DF 0 "register_operand" "=f,f")
15305 (match_operator:DF 3 "binary_fp_operator"
15306 [(match_operand:DF 1 "register_operand" "0,0")
15307 (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15308 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
15309 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15310 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15311 [(set (attr "type")
15312 (cond [(match_operand:DF 3 "mult_operator" "")
15313 (const_string "fmul")
15314 (match_operand:DF 3 "div_operator" "")
15315 (const_string "fdiv")
15317 (const_string "fop")))
15318 (set_attr "fp_int_src" "true")
15319 (set_attr "mode" "<MODE>")])
15321 (define_insn "*fop_df_4_i387"
15322 [(set (match_operand:DF 0 "register_operand" "=f,f")
15323 (match_operator:DF 3 "binary_fp_operator"
15324 [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15325 (match_operand:DF 2 "register_operand" "0,f")]))]
15326 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15327 && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
15328 "* return output_387_binary_op (insn, operands);"
15329 [(set (attr "type")
15330 (cond [(match_operand:DF 3 "mult_operator" "")
15331 (const_string "fmul")
15332 (match_operand:DF 3 "div_operator" "")
15333 (const_string "fdiv")
15335 (const_string "fop")))
15336 (set_attr "mode" "SF")])
15338 (define_insn "*fop_df_5_i387"
15339 [(set (match_operand:DF 0 "register_operand" "=f,f")
15340 (match_operator:DF 3 "binary_fp_operator"
15341 [(match_operand:DF 1 "register_operand" "0,f")
15343 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15344 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15345 "* return output_387_binary_op (insn, operands);"
15346 [(set (attr "type")
15347 (cond [(match_operand:DF 3 "mult_operator" "")
15348 (const_string "fmul")
15349 (match_operand:DF 3 "div_operator" "")
15350 (const_string "fdiv")
15352 (const_string "fop")))
15353 (set_attr "mode" "SF")])
15355 (define_insn "*fop_df_6_i387"
15356 [(set (match_operand:DF 0 "register_operand" "=f,f")
15357 (match_operator:DF 3 "binary_fp_operator"
15359 (match_operand:SF 1 "register_operand" "0,f"))
15361 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15362 "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15363 "* return output_387_binary_op (insn, operands);"
15364 [(set (attr "type")
15365 (cond [(match_operand:DF 3 "mult_operator" "")
15366 (const_string "fmul")
15367 (match_operand:DF 3 "div_operator" "")
15368 (const_string "fdiv")
15370 (const_string "fop")))
15371 (set_attr "mode" "SF")])
15373 (define_insn "*fop_xf_comm_i387"
15374 [(set (match_operand:XF 0 "register_operand" "=f")
15375 (match_operator:XF 3 "binary_fp_operator"
15376 [(match_operand:XF 1 "register_operand" "%0")
15377 (match_operand:XF 2 "register_operand" "f")]))]
15379 && COMMUTATIVE_ARITH_P (operands[3])"
15380 "* return output_387_binary_op (insn, operands);"
15381 [(set (attr "type")
15382 (if_then_else (match_operand:XF 3 "mult_operator" "")
15383 (const_string "fmul")
15384 (const_string "fop")))
15385 (set_attr "mode" "XF")])
15387 (define_insn "*fop_xf_1_i387"
15388 [(set (match_operand:XF 0 "register_operand" "=f,f")
15389 (match_operator:XF 3 "binary_fp_operator"
15390 [(match_operand:XF 1 "register_operand" "0,f")
15391 (match_operand:XF 2 "register_operand" "f,0")]))]
15393 && !COMMUTATIVE_ARITH_P (operands[3])"
15394 "* return output_387_binary_op (insn, operands);"
15395 [(set (attr "type")
15396 (cond [(match_operand:XF 3 "mult_operator" "")
15397 (const_string "fmul")
15398 (match_operand:XF 3 "div_operator" "")
15399 (const_string "fdiv")
15401 (const_string "fop")))
15402 (set_attr "mode" "XF")])
15404 (define_insn "*fop_xf_2<mode>_i387"
15405 [(set (match_operand:XF 0 "register_operand" "=f,f")
15406 (match_operator:XF 3 "binary_fp_operator"
15407 [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15408 (match_operand:XF 2 "register_operand" "0,0")]))]
15409 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15410 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15411 [(set (attr "type")
15412 (cond [(match_operand:XF 3 "mult_operator" "")
15413 (const_string "fmul")
15414 (match_operand:XF 3 "div_operator" "")
15415 (const_string "fdiv")
15417 (const_string "fop")))
15418 (set_attr "fp_int_src" "true")
15419 (set_attr "mode" "<MODE>")])
15421 (define_insn "*fop_xf_3<mode>_i387"
15422 [(set (match_operand:XF 0 "register_operand" "=f,f")
15423 (match_operator:XF 3 "binary_fp_operator"
15424 [(match_operand:XF 1 "register_operand" "0,0")
15425 (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15426 "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
15427 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15428 [(set (attr "type")
15429 (cond [(match_operand:XF 3 "mult_operator" "")
15430 (const_string "fmul")
15431 (match_operand:XF 3 "div_operator" "")
15432 (const_string "fdiv")
15434 (const_string "fop")))
15435 (set_attr "fp_int_src" "true")
15436 (set_attr "mode" "<MODE>")])
15438 (define_insn "*fop_xf_4_i387"
15439 [(set (match_operand:XF 0 "register_operand" "=f,f")
15440 (match_operator:XF 3 "binary_fp_operator"
15441 [(float_extend:XF (match_operand 1 "nonimmediate_operand" "fm,0"))
15442 (match_operand:XF 2 "register_operand" "0,f")]))]
15444 "* return output_387_binary_op (insn, operands);"
15445 [(set (attr "type")
15446 (cond [(match_operand:XF 3 "mult_operator" "")
15447 (const_string "fmul")
15448 (match_operand:XF 3 "div_operator" "")
15449 (const_string "fdiv")
15451 (const_string "fop")))
15452 (set_attr "mode" "SF")])
15454 (define_insn "*fop_xf_5_i387"
15455 [(set (match_operand:XF 0 "register_operand" "=f,f")
15456 (match_operator:XF 3 "binary_fp_operator"
15457 [(match_operand:XF 1 "register_operand" "0,f")
15459 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15461 "* return output_387_binary_op (insn, operands);"
15462 [(set (attr "type")
15463 (cond [(match_operand:XF 3 "mult_operator" "")
15464 (const_string "fmul")
15465 (match_operand:XF 3 "div_operator" "")
15466 (const_string "fdiv")
15468 (const_string "fop")))
15469 (set_attr "mode" "SF")])
15471 (define_insn "*fop_xf_6_i387"
15472 [(set (match_operand:XF 0 "register_operand" "=f,f")
15473 (match_operator:XF 3 "binary_fp_operator"
15475 (match_operand 1 "register_operand" "0,f"))
15477 (match_operand 2 "nonimmediate_operand" "fm,0"))]))]
15479 "* return output_387_binary_op (insn, operands);"
15480 [(set (attr "type")
15481 (cond [(match_operand:XF 3 "mult_operator" "")
15482 (const_string "fmul")
15483 (match_operand:XF 3 "div_operator" "")
15484 (const_string "fdiv")
15486 (const_string "fop")))
15487 (set_attr "mode" "SF")])
15490 [(set (match_operand 0 "register_operand" "")
15491 (match_operator 3 "binary_fp_operator"
15492 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15493 (match_operand 2 "register_operand" "")]))]
15494 "TARGET_80387 && reload_completed
15495 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15498 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15499 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15500 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15501 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15502 GET_MODE (operands[3]),
15505 ix86_free_from_memory (GET_MODE (operands[1]));
15510 [(set (match_operand 0 "register_operand" "")
15511 (match_operator 3 "binary_fp_operator"
15512 [(match_operand 1 "register_operand" "")
15513 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15514 "TARGET_80387 && reload_completed
15515 && FLOAT_MODE_P (GET_MODE (operands[0]))"
15518 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15519 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15520 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15521 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15522 GET_MODE (operands[3]),
15525 ix86_free_from_memory (GET_MODE (operands[2]));
15529 ;; FPU special functions.
15531 ;; This pattern implements a no-op XFmode truncation for
15532 ;; all fancy i386 XFmode math functions.
15534 (define_insn "truncxf<mode>2_i387_noop_unspec"
15535 [(set (match_operand:X87MODEF12 0 "register_operand" "=f")
15536 (unspec:X87MODEF12 [(match_operand:XF 1 "register_operand" "f")]
15537 UNSPEC_TRUNC_NOOP))]
15538 "TARGET_USE_FANCY_MATH_387"
15539 "* return output_387_reg_move (insn, operands);"
15540 [(set_attr "type" "fmov")
15541 (set_attr "mode" "<MODE>")])
15543 (define_insn "sqrtxf2"
15544 [(set (match_operand:XF 0 "register_operand" "=f")
15545 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15546 "TARGET_USE_FANCY_MATH_387"
15548 [(set_attr "type" "fpspc")
15549 (set_attr "mode" "XF")
15550 (set_attr "athlon_decode" "direct")])
15552 (define_insn "sqrt_extend<mode>xf2_i387"
15553 [(set (match_operand:XF 0 "register_operand" "=f")
15556 (match_operand:X87MODEF12 1 "register_operand" "0"))))]
15557 "TARGET_USE_FANCY_MATH_387"
15559 [(set_attr "type" "fpspc")
15560 (set_attr "mode" "XF")
15561 (set_attr "athlon_decode" "direct")])
15563 (define_insn "*sqrt<mode>2_sse"
15564 [(set (match_operand:SSEMODEF 0 "register_operand" "=x")
15566 (match_operand:SSEMODEF 1 "nonimmediate_operand" "xm")))]
15567 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15568 "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
15569 [(set_attr "type" "sse")
15570 (set_attr "mode" "<MODE>")
15571 (set_attr "athlon_decode" "*")])
15573 (define_expand "sqrt<mode>2"
15574 [(set (match_operand:X87MODEF12 0 "register_operand" "")
15576 (match_operand:X87MODEF12 1 "nonimmediate_operand" "")))]
15577 "TARGET_USE_FANCY_MATH_387
15578 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15580 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15582 rtx op0 = gen_reg_rtx (XFmode);
15583 rtx op1 = force_reg (<MODE>mode, operands[1]);
15585 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15586 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15591 (define_insn "fpremxf4_i387"
15592 [(set (match_operand:XF 0 "register_operand" "=f")
15593 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15594 (match_operand:XF 3 "register_operand" "1")]
15596 (set (match_operand:XF 1 "register_operand" "=u")
15597 (unspec:XF [(match_dup 2) (match_dup 3)]
15599 (set (reg:CCFP FPSR_REG)
15600 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15601 "TARGET_USE_FANCY_MATH_387"
15603 [(set_attr "type" "fpspc")
15604 (set_attr "mode" "XF")])
15606 (define_expand "fmodxf3"
15607 [(use (match_operand:XF 0 "register_operand" ""))
15608 (use (match_operand:XF 1 "register_operand" ""))
15609 (use (match_operand:XF 2 "register_operand" ""))]
15610 "TARGET_USE_FANCY_MATH_387"
15612 rtx label = gen_label_rtx ();
15614 emit_label (label);
15616 emit_insn (gen_fpremxf4_i387 (operands[1], operands[2],
15617 operands[1], operands[2]));
15618 ix86_emit_fp_unordered_jump (label);
15620 emit_move_insn (operands[0], operands[1]);
15624 (define_expand "fmod<mode>3"
15625 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15626 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15627 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15628 "TARGET_USE_FANCY_MATH_387
15629 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15630 || TARGET_MIX_SSE_I387)"
15632 rtx label = gen_label_rtx ();
15634 rtx op1 = gen_reg_rtx (XFmode);
15635 rtx op2 = gen_reg_rtx (XFmode);
15637 emit_insn(gen_extend<mode>xf2 (op1, operands[1]));
15638 emit_insn(gen_extend<mode>xf2 (op2, operands[2]));
15640 emit_label (label);
15641 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15642 ix86_emit_fp_unordered_jump (label);
15644 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15648 (define_insn "fprem1xf4_i387"
15649 [(set (match_operand:XF 0 "register_operand" "=f")
15650 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15651 (match_operand:XF 3 "register_operand" "1")]
15653 (set (match_operand:XF 1 "register_operand" "=u")
15654 (unspec:XF [(match_dup 2) (match_dup 3)]
15656 (set (reg:CCFP FPSR_REG)
15657 (unspec:CCFP [(const_int 0)] UNSPEC_NOP))]
15658 "TARGET_USE_FANCY_MATH_387"
15660 [(set_attr "type" "fpspc")
15661 (set_attr "mode" "XF")])
15663 (define_expand "remainderxf3"
15664 [(use (match_operand:XF 0 "register_operand" ""))
15665 (use (match_operand:XF 1 "register_operand" ""))
15666 (use (match_operand:XF 2 "register_operand" ""))]
15667 "TARGET_USE_FANCY_MATH_387"
15669 rtx label = gen_label_rtx ();
15671 emit_label (label);
15673 emit_insn (gen_fprem1xf4_i387 (operands[1], operands[2],
15674 operands[1], operands[2]));
15675 ix86_emit_fp_unordered_jump (label);
15677 emit_move_insn (operands[0], operands[1]);
15681 (define_expand "remainder<mode>3"
15682 [(use (match_operand:X87MODEF12 0 "register_operand" ""))
15683 (use (match_operand:X87MODEF12 1 "general_operand" ""))
15684 (use (match_operand:X87MODEF12 2 "general_operand" ""))]
15685 "TARGET_USE_FANCY_MATH_387
15686 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15687 || TARGET_MIX_SSE_I387)"
15689 rtx label = gen_label_rtx ();
15691 rtx op1 = gen_reg_rtx (XFmode);
15692 rtx op2 = gen_reg_rtx (XFmode);
15694 emit_insn(gen_extend<mode>xf2 (op1, operands[1]));
15695 emit_insn(gen_extend<mode>xf2 (op2, operands[2]));
15697 emit_label (label);
15699 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15700 ix86_emit_fp_unordered_jump (label);
15702 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15706 (define_insn "*sindf2"
15707 [(set (match_operand:DF 0 "register_operand" "=f")
15708 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_SIN))]
15709 "TARGET_USE_FANCY_MATH_387
15710 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15711 && flag_unsafe_math_optimizations"
15713 [(set_attr "type" "fpspc")
15714 (set_attr "mode" "DF")])
15716 (define_insn "*sinsf2"
15717 [(set (match_operand:SF 0 "register_operand" "=f")
15718 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_SIN))]
15719 "TARGET_USE_FANCY_MATH_387
15720 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15721 && flag_unsafe_math_optimizations"
15723 [(set_attr "type" "fpspc")
15724 (set_attr "mode" "SF")])
15726 (define_insn "*sinextendsfdf2"
15727 [(set (match_operand:DF 0 "register_operand" "=f")
15728 (unspec:DF [(float_extend:DF
15729 (match_operand:SF 1 "register_operand" "0"))]
15731 "TARGET_USE_FANCY_MATH_387
15732 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15733 && flag_unsafe_math_optimizations"
15735 [(set_attr "type" "fpspc")
15736 (set_attr "mode" "DF")])
15738 (define_insn "*sinxf2"
15739 [(set (match_operand:XF 0 "register_operand" "=f")
15740 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15741 "TARGET_USE_FANCY_MATH_387
15742 && flag_unsafe_math_optimizations"
15744 [(set_attr "type" "fpspc")
15745 (set_attr "mode" "XF")])
15747 (define_insn "*cosdf2"
15748 [(set (match_operand:DF 0 "register_operand" "=f")
15749 (unspec:DF [(match_operand:DF 1 "register_operand" "0")] UNSPEC_COS))]
15750 "TARGET_USE_FANCY_MATH_387
15751 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15752 && flag_unsafe_math_optimizations"
15754 [(set_attr "type" "fpspc")
15755 (set_attr "mode" "DF")])
15757 (define_insn "*cossf2"
15758 [(set (match_operand:SF 0 "register_operand" "=f")
15759 (unspec:SF [(match_operand:SF 1 "register_operand" "0")] UNSPEC_COS))]
15760 "TARGET_USE_FANCY_MATH_387
15761 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15762 && flag_unsafe_math_optimizations"
15764 [(set_attr "type" "fpspc")
15765 (set_attr "mode" "SF")])
15767 (define_insn "*cosextendsfdf2"
15768 [(set (match_operand:DF 0 "register_operand" "=f")
15769 (unspec:DF [(float_extend:DF
15770 (match_operand:SF 1 "register_operand" "0"))]
15772 "TARGET_USE_FANCY_MATH_387
15773 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15774 && flag_unsafe_math_optimizations"
15776 [(set_attr "type" "fpspc")
15777 (set_attr "mode" "DF")])
15779 (define_insn "*cosxf2"
15780 [(set (match_operand:XF 0 "register_operand" "=f")
15781 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15782 "TARGET_USE_FANCY_MATH_387
15783 && flag_unsafe_math_optimizations"
15785 [(set_attr "type" "fpspc")
15786 (set_attr "mode" "XF")])
15788 ;; With sincos pattern defined, sin and cos builtin function will be
15789 ;; expanded to sincos pattern with one of its outputs left unused.
15790 ;; Cse pass will detected, if two sincos patterns can be combined,
15791 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15792 ;; depending on the unused output.
15794 (define_insn "sincosdf3"
15795 [(set (match_operand:DF 0 "register_operand" "=f")
15796 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15797 UNSPEC_SINCOS_COS))
15798 (set (match_operand:DF 1 "register_operand" "=u")
15799 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15800 "TARGET_USE_FANCY_MATH_387
15801 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15802 && flag_unsafe_math_optimizations"
15804 [(set_attr "type" "fpspc")
15805 (set_attr "mode" "DF")])
15808 [(set (match_operand:DF 0 "register_operand" "")
15809 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15810 UNSPEC_SINCOS_COS))
15811 (set (match_operand:DF 1 "register_operand" "")
15812 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15813 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15814 && !reload_completed && !reload_in_progress"
15815 [(set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_SIN))]
15819 [(set (match_operand:DF 0 "register_operand" "")
15820 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15821 UNSPEC_SINCOS_COS))
15822 (set (match_operand:DF 1 "register_operand" "")
15823 (unspec:DF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15824 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15825 && !reload_completed && !reload_in_progress"
15826 [(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_COS))]
15829 (define_insn "sincossf3"
15830 [(set (match_operand:SF 0 "register_operand" "=f")
15831 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15832 UNSPEC_SINCOS_COS))
15833 (set (match_operand:SF 1 "register_operand" "=u")
15834 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15835 "TARGET_USE_FANCY_MATH_387
15836 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15837 && flag_unsafe_math_optimizations"
15839 [(set_attr "type" "fpspc")
15840 (set_attr "mode" "SF")])
15843 [(set (match_operand:SF 0 "register_operand" "")
15844 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15845 UNSPEC_SINCOS_COS))
15846 (set (match_operand:SF 1 "register_operand" "")
15847 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15848 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15849 && !reload_completed && !reload_in_progress"
15850 [(set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
15854 [(set (match_operand:SF 0 "register_operand" "")
15855 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
15856 UNSPEC_SINCOS_COS))
15857 (set (match_operand:SF 1 "register_operand" "")
15858 (unspec:SF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15859 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15860 && !reload_completed && !reload_in_progress"
15861 [(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_COS))]
15864 (define_insn "*sincosextendsfdf3"
15865 [(set (match_operand:DF 0 "register_operand" "=f")
15866 (unspec:DF [(float_extend:DF
15867 (match_operand:SF 2 "register_operand" "0"))]
15868 UNSPEC_SINCOS_COS))
15869 (set (match_operand:DF 1 "register_operand" "=u")
15870 (unspec:DF [(float_extend:DF
15871 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15872 "TARGET_USE_FANCY_MATH_387
15873 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15874 && flag_unsafe_math_optimizations"
15876 [(set_attr "type" "fpspc")
15877 (set_attr "mode" "DF")])
15880 [(set (match_operand:DF 0 "register_operand" "")
15881 (unspec:DF [(float_extend:DF
15882 (match_operand:SF 2 "register_operand" ""))]
15883 UNSPEC_SINCOS_COS))
15884 (set (match_operand:DF 1 "register_operand" "")
15885 (unspec:DF [(float_extend:DF
15886 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15887 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15888 && !reload_completed && !reload_in_progress"
15889 [(set (match_dup 1) (unspec:DF [(float_extend:DF
15890 (match_dup 2))] UNSPEC_SIN))]
15894 [(set (match_operand:DF 0 "register_operand" "")
15895 (unspec:DF [(float_extend:DF
15896 (match_operand:SF 2 "register_operand" ""))]
15897 UNSPEC_SINCOS_COS))
15898 (set (match_operand:DF 1 "register_operand" "")
15899 (unspec:DF [(float_extend:DF
15900 (match_dup 2))] UNSPEC_SINCOS_SIN))]
15901 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15902 && !reload_completed && !reload_in_progress"
15903 [(set (match_dup 0) (unspec:DF [(float_extend:DF
15904 (match_dup 2))] UNSPEC_COS))]
15907 (define_insn "sincosxf3"
15908 [(set (match_operand:XF 0 "register_operand" "=f")
15909 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15910 UNSPEC_SINCOS_COS))
15911 (set (match_operand:XF 1 "register_operand" "=u")
15912 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15913 "TARGET_USE_FANCY_MATH_387
15914 && flag_unsafe_math_optimizations"
15916 [(set_attr "type" "fpspc")
15917 (set_attr "mode" "XF")])
15920 [(set (match_operand:XF 0 "register_operand" "")
15921 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15922 UNSPEC_SINCOS_COS))
15923 (set (match_operand:XF 1 "register_operand" "")
15924 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15925 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15926 && !reload_completed && !reload_in_progress"
15927 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15931 [(set (match_operand:XF 0 "register_operand" "")
15932 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15933 UNSPEC_SINCOS_COS))
15934 (set (match_operand:XF 1 "register_operand" "")
15935 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15936 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15937 && !reload_completed && !reload_in_progress"
15938 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15941 (define_insn "*tandf3_1"
15942 [(set (match_operand:DF 0 "register_operand" "=f")
15943 (unspec:DF [(match_operand:DF 2 "register_operand" "0")]
15945 (set (match_operand:DF 1 "register_operand" "=u")
15946 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))]
15947 "TARGET_USE_FANCY_MATH_387
15948 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15949 && flag_unsafe_math_optimizations"
15951 [(set_attr "type" "fpspc")
15952 (set_attr "mode" "DF")])
15954 ;; optimize sequence: fptan
15957 ;; into fptan insn.
15960 [(parallel[(set (match_operand:DF 0 "register_operand" "")
15961 (unspec:DF [(match_operand:DF 2 "register_operand" "")]
15963 (set (match_operand:DF 1 "register_operand" "")
15964 (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])
15966 (match_operand:DF 3 "immediate_operand" ""))]
15967 "standard_80387_constant_p (operands[3]) == 2"
15968 [(parallel[(set (match_dup 0) (unspec:DF [(match_dup 2)] UNSPEC_TAN_ONE))
15969 (set (match_dup 1) (unspec:DF [(match_dup 2)] UNSPEC_TAN_TAN))])]
15972 (define_expand "tandf2"
15973 [(parallel [(set (match_dup 2)
15974 (unspec:DF [(match_operand:DF 1 "register_operand" "")]
15976 (set (match_operand:DF 0 "register_operand" "")
15977 (unspec:DF [(match_dup 1)] UNSPEC_TAN_TAN))])]
15978 "TARGET_USE_FANCY_MATH_387
15979 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
15980 && flag_unsafe_math_optimizations"
15982 operands[2] = gen_reg_rtx (DFmode);
15985 (define_insn "*tansf3_1"
15986 [(set (match_operand:SF 0 "register_operand" "=f")
15987 (unspec:SF [(match_operand:SF 2 "register_operand" "0")]
15989 (set (match_operand:SF 1 "register_operand" "=u")
15990 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))]
15991 "TARGET_USE_FANCY_MATH_387
15992 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15993 && flag_unsafe_math_optimizations"
15995 [(set_attr "type" "fpspc")
15996 (set_attr "mode" "SF")])
15998 ;; optimize sequence: fptan
16001 ;; into fptan insn.
16004 [(parallel[(set (match_operand:SF 0 "register_operand" "")
16005 (unspec:SF [(match_operand:SF 2 "register_operand" "")]
16007 (set (match_operand:SF 1 "register_operand" "")
16008 (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])
16010 (match_operand:SF 3 "immediate_operand" ""))]
16011 "standard_80387_constant_p (operands[3]) == 2"
16012 [(parallel[(set (match_dup 0) (unspec:SF [(match_dup 2)] UNSPEC_TAN_ONE))
16013 (set (match_dup 1) (unspec:SF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16016 (define_expand "tansf2"
16017 [(parallel [(set (match_dup 2)
16018 (unspec:SF [(match_operand:SF 1 "register_operand" "")]
16020 (set (match_operand:SF 0 "register_operand" "")
16021 (unspec:SF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16022 "TARGET_USE_FANCY_MATH_387
16023 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16024 && flag_unsafe_math_optimizations"
16026 operands[2] = gen_reg_rtx (SFmode);
16029 (define_insn "*tanxf3_1"
16030 [(set (match_operand:XF 0 "register_operand" "=f")
16031 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16033 (set (match_operand:XF 1 "register_operand" "=u")
16034 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))]
16035 "TARGET_USE_FANCY_MATH_387
16036 && flag_unsafe_math_optimizations"
16038 [(set_attr "type" "fpspc")
16039 (set_attr "mode" "XF")])
16041 ;; optimize sequence: fptan
16044 ;; into fptan insn.
16047 [(parallel[(set (match_operand:XF 0 "register_operand" "")
16048 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16050 (set (match_operand:XF 1 "register_operand" "")
16051 (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])
16053 (match_operand:XF 3 "immediate_operand" ""))]
16054 "standard_80387_constant_p (operands[3]) == 2"
16055 [(parallel[(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_TAN_ONE))
16056 (set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_TAN_TAN))])]
16059 (define_expand "tanxf2"
16060 [(parallel [(set (match_dup 2)
16061 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16063 (set (match_operand:XF 0 "register_operand" "")
16064 (unspec:XF [(match_dup 1)] UNSPEC_TAN_TAN))])]
16065 "TARGET_USE_FANCY_MATH_387
16066 && flag_unsafe_math_optimizations"
16068 operands[2] = gen_reg_rtx (XFmode);
16071 (define_insn "atan2df3_1"
16072 [(set (match_operand:DF 0 "register_operand" "=f")
16073 (unspec:DF [(match_operand:DF 2 "register_operand" "0")
16074 (match_operand:DF 1 "register_operand" "u")]
16076 (clobber (match_scratch:DF 3 "=1"))]
16077 "TARGET_USE_FANCY_MATH_387
16078 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16079 && flag_unsafe_math_optimizations"
16081 [(set_attr "type" "fpspc")
16082 (set_attr "mode" "DF")])
16084 (define_expand "atan2df3"
16085 [(use (match_operand:DF 0 "register_operand" ""))
16086 (use (match_operand:DF 2 "register_operand" ""))
16087 (use (match_operand:DF 1 "register_operand" ""))]
16088 "TARGET_USE_FANCY_MATH_387
16089 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16090 && flag_unsafe_math_optimizations"
16092 rtx copy = gen_reg_rtx (DFmode);
16093 emit_move_insn (copy, operands[1]);
16094 emit_insn (gen_atan2df3_1 (operands[0], copy, operands[2]));
16098 (define_expand "atandf2"
16099 [(parallel [(set (match_operand:DF 0 "register_operand" "")
16100 (unspec:DF [(match_dup 2)
16101 (match_operand:DF 1 "register_operand" "")]
16103 (clobber (match_scratch:DF 3 ""))])]
16104 "TARGET_USE_FANCY_MATH_387
16105 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16106 && flag_unsafe_math_optimizations"
16108 operands[2] = gen_reg_rtx (DFmode);
16109 emit_move_insn (operands[2], CONST1_RTX (DFmode)); /* fld1 */
16112 (define_insn "atan2sf3_1"
16113 [(set (match_operand:SF 0 "register_operand" "=f")
16114 (unspec:SF [(match_operand:SF 2 "register_operand" "0")
16115 (match_operand:SF 1 "register_operand" "u")]
16117 (clobber (match_scratch:SF 3 "=1"))]
16118 "TARGET_USE_FANCY_MATH_387
16119 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16120 && flag_unsafe_math_optimizations"
16122 [(set_attr "type" "fpspc")
16123 (set_attr "mode" "SF")])
16125 (define_expand "atan2sf3"
16126 [(use (match_operand:SF 0 "register_operand" ""))
16127 (use (match_operand:SF 2 "register_operand" ""))
16128 (use (match_operand:SF 1 "register_operand" ""))]
16129 "TARGET_USE_FANCY_MATH_387
16130 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16131 && flag_unsafe_math_optimizations"
16133 rtx copy = gen_reg_rtx (SFmode);
16134 emit_move_insn (copy, operands[1]);
16135 emit_insn (gen_atan2sf3_1 (operands[0], copy, operands[2]));
16139 (define_expand "atansf2"
16140 [(parallel [(set (match_operand:SF 0 "register_operand" "")
16141 (unspec:SF [(match_dup 2)
16142 (match_operand:SF 1 "register_operand" "")]
16144 (clobber (match_scratch:SF 3 ""))])]
16145 "TARGET_USE_FANCY_MATH_387
16146 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16147 && flag_unsafe_math_optimizations"
16149 operands[2] = gen_reg_rtx (SFmode);
16150 emit_move_insn (operands[2], CONST1_RTX (SFmode)); /* fld1 */
16153 (define_insn "atan2xf3_1"
16154 [(set (match_operand:XF 0 "register_operand" "=f")
16155 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16156 (match_operand:XF 1 "register_operand" "u")]
16158 (clobber (match_scratch:XF 3 "=1"))]
16159 "TARGET_USE_FANCY_MATH_387
16160 && flag_unsafe_math_optimizations"
16162 [(set_attr "type" "fpspc")
16163 (set_attr "mode" "XF")])
16165 (define_expand "atan2xf3"
16166 [(use (match_operand:XF 0 "register_operand" ""))
16167 (use (match_operand:XF 2 "register_operand" ""))
16168 (use (match_operand:XF 1 "register_operand" ""))]
16169 "TARGET_USE_FANCY_MATH_387
16170 && flag_unsafe_math_optimizations"
16172 rtx copy = gen_reg_rtx (XFmode);
16173 emit_move_insn (copy, operands[1]);
16174 emit_insn (gen_atan2xf3_1 (operands[0], copy, operands[2]));
16178 (define_expand "atanxf2"
16179 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16180 (unspec:XF [(match_dup 2)
16181 (match_operand:XF 1 "register_operand" "")]
16183 (clobber (match_scratch:XF 3 ""))])]
16184 "TARGET_USE_FANCY_MATH_387
16185 && flag_unsafe_math_optimizations"
16187 operands[2] = gen_reg_rtx (XFmode);
16188 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16191 (define_expand "asindf2"
16192 [(set (match_dup 2)
16193 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16194 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16195 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16196 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16197 (parallel [(set (match_dup 7)
16198 (unspec:XF [(match_dup 6) (match_dup 2)]
16200 (clobber (match_scratch:XF 8 ""))])
16201 (set (match_operand:DF 0 "register_operand" "")
16202 (float_truncate:DF (match_dup 7)))]
16203 "TARGET_USE_FANCY_MATH_387
16204 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16205 && flag_unsafe_math_optimizations && !optimize_size"
16209 for (i=2; i<8; i++)
16210 operands[i] = gen_reg_rtx (XFmode);
16212 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16215 (define_expand "asinsf2"
16216 [(set (match_dup 2)
16217 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16218 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16219 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16220 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16221 (parallel [(set (match_dup 7)
16222 (unspec:XF [(match_dup 6) (match_dup 2)]
16224 (clobber (match_scratch:XF 8 ""))])
16225 (set (match_operand:SF 0 "register_operand" "")
16226 (float_truncate:SF (match_dup 7)))]
16227 "TARGET_USE_FANCY_MATH_387
16228 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16229 && flag_unsafe_math_optimizations && !optimize_size"
16233 for (i=2; i<8; i++)
16234 operands[i] = gen_reg_rtx (XFmode);
16236 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16239 (define_expand "asinxf2"
16240 [(set (match_dup 2)
16241 (mult:XF (match_operand:XF 1 "register_operand" "")
16243 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16244 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16245 (parallel [(set (match_operand:XF 0 "register_operand" "")
16246 (unspec:XF [(match_dup 5) (match_dup 1)]
16248 (clobber (match_scratch:XF 6 ""))])]
16249 "TARGET_USE_FANCY_MATH_387
16250 && flag_unsafe_math_optimizations && !optimize_size"
16254 for (i=2; i<6; i++)
16255 operands[i] = gen_reg_rtx (XFmode);
16257 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16260 (define_expand "acosdf2"
16261 [(set (match_dup 2)
16262 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16263 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16264 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16265 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16266 (parallel [(set (match_dup 7)
16267 (unspec:XF [(match_dup 2) (match_dup 6)]
16269 (clobber (match_scratch:XF 8 ""))])
16270 (set (match_operand:DF 0 "register_operand" "")
16271 (float_truncate:DF (match_dup 7)))]
16272 "TARGET_USE_FANCY_MATH_387
16273 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16274 && flag_unsafe_math_optimizations && !optimize_size"
16278 for (i=2; i<8; i++)
16279 operands[i] = gen_reg_rtx (XFmode);
16281 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16284 (define_expand "acossf2"
16285 [(set (match_dup 2)
16286 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16287 (set (match_dup 3) (mult:XF (match_dup 2) (match_dup 2)))
16288 (set (match_dup 5) (minus:XF (match_dup 4) (match_dup 3)))
16289 (set (match_dup 6) (sqrt:XF (match_dup 5)))
16290 (parallel [(set (match_dup 7)
16291 (unspec:XF [(match_dup 2) (match_dup 6)]
16293 (clobber (match_scratch:XF 8 ""))])
16294 (set (match_operand:SF 0 "register_operand" "")
16295 (float_truncate:SF (match_dup 7)))]
16296 "TARGET_USE_FANCY_MATH_387
16297 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16298 && flag_unsafe_math_optimizations && !optimize_size"
16302 for (i=2; i<8; i++)
16303 operands[i] = gen_reg_rtx (XFmode);
16305 emit_move_insn (operands[4], CONST1_RTX (XFmode)); /* fld1 */
16308 (define_expand "acosxf2"
16309 [(set (match_dup 2)
16310 (mult:XF (match_operand:XF 1 "register_operand" "")
16312 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16313 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16314 (parallel [(set (match_operand:XF 0 "register_operand" "")
16315 (unspec:XF [(match_dup 1) (match_dup 5)]
16317 (clobber (match_scratch:XF 6 ""))])]
16318 "TARGET_USE_FANCY_MATH_387
16319 && flag_unsafe_math_optimizations && !optimize_size"
16323 for (i=2; i<6; i++)
16324 operands[i] = gen_reg_rtx (XFmode);
16326 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16329 (define_insn "fyl2x_xf3"
16330 [(set (match_operand:XF 0 "register_operand" "=f")
16331 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16332 (match_operand:XF 1 "register_operand" "u")]
16334 (clobber (match_scratch:XF 3 "=1"))]
16335 "TARGET_USE_FANCY_MATH_387
16336 && flag_unsafe_math_optimizations"
16338 [(set_attr "type" "fpspc")
16339 (set_attr "mode" "XF")])
16341 (define_expand "logsf2"
16342 [(set (match_dup 2)
16343 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16344 (parallel [(set (match_dup 4)
16345 (unspec:XF [(match_dup 2)
16346 (match_dup 3)] UNSPEC_FYL2X))
16347 (clobber (match_scratch:XF 5 ""))])
16348 (set (match_operand:SF 0 "register_operand" "")
16349 (float_truncate:SF (match_dup 4)))]
16350 "TARGET_USE_FANCY_MATH_387
16351 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16352 && flag_unsafe_math_optimizations"
16356 operands[2] = gen_reg_rtx (XFmode);
16357 operands[3] = gen_reg_rtx (XFmode);
16358 operands[4] = gen_reg_rtx (XFmode);
16360 temp = standard_80387_constant_rtx (4); /* fldln2 */
16361 emit_move_insn (operands[3], temp);
16364 (define_expand "logdf2"
16365 [(set (match_dup 2)
16366 (float_extend:XF (match_operand:DF 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:DF 0 "register_operand" "")
16372 (float_truncate:DF (match_dup 4)))]
16373 "TARGET_USE_FANCY_MATH_387
16374 && (!(TARGET_SSE2 && 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 "logxf2"
16388 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16389 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16390 (match_dup 2)] UNSPEC_FYL2X))
16391 (clobber (match_scratch:XF 3 ""))])]
16392 "TARGET_USE_FANCY_MATH_387
16393 && flag_unsafe_math_optimizations"
16397 operands[2] = gen_reg_rtx (XFmode);
16398 temp = standard_80387_constant_rtx (4); /* fldln2 */
16399 emit_move_insn (operands[2], temp);
16402 (define_expand "log10sf2"
16403 [(set (match_dup 2)
16404 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16405 (parallel [(set (match_dup 4)
16406 (unspec:XF [(match_dup 2)
16407 (match_dup 3)] UNSPEC_FYL2X))
16408 (clobber (match_scratch:XF 5 ""))])
16409 (set (match_operand:SF 0 "register_operand" "")
16410 (float_truncate:SF (match_dup 4)))]
16411 "TARGET_USE_FANCY_MATH_387
16412 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16413 && flag_unsafe_math_optimizations"
16417 operands[2] = gen_reg_rtx (XFmode);
16418 operands[3] = gen_reg_rtx (XFmode);
16419 operands[4] = gen_reg_rtx (XFmode);
16421 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16422 emit_move_insn (operands[3], temp);
16425 (define_expand "log10df2"
16426 [(set (match_dup 2)
16427 (float_extend:XF (match_operand:DF 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:DF 0 "register_operand" "")
16433 (float_truncate:DF (match_dup 4)))]
16434 "TARGET_USE_FANCY_MATH_387
16435 && (!(TARGET_SSE2 && 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 "log10xf2"
16449 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16450 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16451 (match_dup 2)] UNSPEC_FYL2X))
16452 (clobber (match_scratch:XF 3 ""))])]
16453 "TARGET_USE_FANCY_MATH_387
16454 && flag_unsafe_math_optimizations"
16458 operands[2] = gen_reg_rtx (XFmode);
16459 temp = standard_80387_constant_rtx (3); /* fldlg2 */
16460 emit_move_insn (operands[2], temp);
16463 (define_expand "log2sf2"
16464 [(set (match_dup 2)
16465 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16466 (parallel [(set (match_dup 4)
16467 (unspec:XF [(match_dup 2)
16468 (match_dup 3)] UNSPEC_FYL2X))
16469 (clobber (match_scratch:XF 5 ""))])
16470 (set (match_operand:SF 0 "register_operand" "")
16471 (float_truncate:SF (match_dup 4)))]
16472 "TARGET_USE_FANCY_MATH_387
16473 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16474 && flag_unsafe_math_optimizations"
16476 operands[2] = gen_reg_rtx (XFmode);
16477 operands[3] = gen_reg_rtx (XFmode);
16478 operands[4] = gen_reg_rtx (XFmode);
16480 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16483 (define_expand "log2df2"
16484 [(set (match_dup 2)
16485 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16486 (parallel [(set (match_dup 4)
16487 (unspec:XF [(match_dup 2)
16488 (match_dup 3)] UNSPEC_FYL2X))
16489 (clobber (match_scratch:XF 5 ""))])
16490 (set (match_operand:DF 0 "register_operand" "")
16491 (float_truncate:DF (match_dup 4)))]
16492 "TARGET_USE_FANCY_MATH_387
16493 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16494 && flag_unsafe_math_optimizations"
16496 operands[2] = gen_reg_rtx (XFmode);
16497 operands[3] = gen_reg_rtx (XFmode);
16498 operands[4] = gen_reg_rtx (XFmode);
16500 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16503 (define_expand "log2xf2"
16504 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16505 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16506 (match_dup 2)] UNSPEC_FYL2X))
16507 (clobber (match_scratch:XF 3 ""))])]
16508 "TARGET_USE_FANCY_MATH_387
16509 && flag_unsafe_math_optimizations"
16511 operands[2] = gen_reg_rtx (XFmode);
16512 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16515 (define_insn "fyl2xp1_xf3"
16516 [(set (match_operand:XF 0 "register_operand" "=f")
16517 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16518 (match_operand:XF 1 "register_operand" "u")]
16520 (clobber (match_scratch:XF 3 "=1"))]
16521 "TARGET_USE_FANCY_MATH_387
16522 && flag_unsafe_math_optimizations"
16524 [(set_attr "type" "fpspc")
16525 (set_attr "mode" "XF")])
16527 (define_expand "log1psf2"
16528 [(use (match_operand:SF 0 "register_operand" ""))
16529 (use (match_operand:SF 1 "register_operand" ""))]
16530 "TARGET_USE_FANCY_MATH_387
16531 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16532 && flag_unsafe_math_optimizations && !optimize_size"
16534 rtx op0 = gen_reg_rtx (XFmode);
16535 rtx op1 = gen_reg_rtx (XFmode);
16537 emit_insn (gen_extendsfxf2 (op1, operands[1]));
16538 ix86_emit_i387_log1p (op0, op1);
16539 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
16543 (define_expand "log1pdf2"
16544 [(use (match_operand:DF 0 "register_operand" ""))
16545 (use (match_operand:DF 1 "register_operand" ""))]
16546 "TARGET_USE_FANCY_MATH_387
16547 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16548 && flag_unsafe_math_optimizations && !optimize_size"
16550 rtx op0 = gen_reg_rtx (XFmode);
16551 rtx op1 = gen_reg_rtx (XFmode);
16553 emit_insn (gen_extenddfxf2 (op1, operands[1]));
16554 ix86_emit_i387_log1p (op0, op1);
16555 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
16559 (define_expand "log1pxf2"
16560 [(use (match_operand:XF 0 "register_operand" ""))
16561 (use (match_operand:XF 1 "register_operand" ""))]
16562 "TARGET_USE_FANCY_MATH_387
16563 && flag_unsafe_math_optimizations && !optimize_size"
16565 ix86_emit_i387_log1p (operands[0], operands[1]);
16569 (define_insn "*fxtractxf3"
16570 [(set (match_operand:XF 0 "register_operand" "=f")
16571 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16572 UNSPEC_XTRACT_FRACT))
16573 (set (match_operand:XF 1 "register_operand" "=u")
16574 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16575 "TARGET_USE_FANCY_MATH_387
16576 && flag_unsafe_math_optimizations"
16578 [(set_attr "type" "fpspc")
16579 (set_attr "mode" "XF")])
16581 (define_expand "logbsf2"
16582 [(set (match_dup 2)
16583 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16584 (parallel [(set (match_dup 3)
16585 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16587 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16588 (set (match_operand:SF 0 "register_operand" "")
16589 (float_truncate:SF (match_dup 4)))]
16590 "TARGET_USE_FANCY_MATH_387
16591 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16592 && flag_unsafe_math_optimizations"
16594 operands[2] = gen_reg_rtx (XFmode);
16595 operands[3] = gen_reg_rtx (XFmode);
16596 operands[4] = gen_reg_rtx (XFmode);
16599 (define_expand "logbdf2"
16600 [(set (match_dup 2)
16601 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16602 (parallel [(set (match_dup 3)
16603 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_FRACT))
16605 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))])
16606 (set (match_operand:DF 0 "register_operand" "")
16607 (float_truncate:DF (match_dup 4)))]
16608 "TARGET_USE_FANCY_MATH_387
16609 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16610 && flag_unsafe_math_optimizations"
16612 operands[2] = gen_reg_rtx (XFmode);
16613 operands[3] = gen_reg_rtx (XFmode);
16614 operands[4] = gen_reg_rtx (XFmode);
16617 (define_expand "logbxf2"
16618 [(parallel [(set (match_dup 2)
16619 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16620 UNSPEC_XTRACT_FRACT))
16621 (set (match_operand:XF 0 "register_operand" "")
16622 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16623 "TARGET_USE_FANCY_MATH_387
16624 && flag_unsafe_math_optimizations"
16626 operands[2] = gen_reg_rtx (XFmode);
16629 (define_expand "ilogbsi2"
16630 [(parallel [(set (match_dup 2)
16631 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16632 UNSPEC_XTRACT_FRACT))
16633 (set (match_operand:XF 3 "register_operand" "")
16634 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])
16635 (parallel [(set (match_operand:SI 0 "register_operand" "")
16636 (fix:SI (match_dup 3)))
16637 (clobber (reg:CC FLAGS_REG))])]
16638 "TARGET_USE_FANCY_MATH_387
16639 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16640 && flag_unsafe_math_optimizations && !optimize_size"
16642 operands[2] = gen_reg_rtx (XFmode);
16643 operands[3] = gen_reg_rtx (XFmode);
16646 (define_insn "*f2xm1xf2"
16647 [(set (match_operand:XF 0 "register_operand" "=f")
16648 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16650 "TARGET_USE_FANCY_MATH_387
16651 && flag_unsafe_math_optimizations"
16653 [(set_attr "type" "fpspc")
16654 (set_attr "mode" "XF")])
16656 (define_insn "*fscalexf4"
16657 [(set (match_operand:XF 0 "register_operand" "=f")
16658 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16659 (match_operand:XF 3 "register_operand" "1")]
16660 UNSPEC_FSCALE_FRACT))
16661 (set (match_operand:XF 1 "register_operand" "=u")
16662 (unspec:XF [(match_dup 2) (match_dup 3)]
16663 UNSPEC_FSCALE_EXP))]
16664 "TARGET_USE_FANCY_MATH_387
16665 && flag_unsafe_math_optimizations"
16667 [(set_attr "type" "fpspc")
16668 (set_attr "mode" "XF")])
16670 (define_expand "expsf2"
16671 [(set (match_dup 2)
16672 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16673 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16674 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16675 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16676 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16677 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16678 (parallel [(set (match_dup 10)
16679 (unspec:XF [(match_dup 9) (match_dup 5)]
16680 UNSPEC_FSCALE_FRACT))
16681 (set (match_dup 11)
16682 (unspec:XF [(match_dup 9) (match_dup 5)]
16683 UNSPEC_FSCALE_EXP))])
16684 (set (match_operand:SF 0 "register_operand" "")
16685 (float_truncate:SF (match_dup 10)))]
16686 "TARGET_USE_FANCY_MATH_387
16687 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16688 && flag_unsafe_math_optimizations && !optimize_size"
16693 for (i=2; i<12; i++)
16694 operands[i] = gen_reg_rtx (XFmode);
16695 temp = standard_80387_constant_rtx (5); /* fldl2e */
16696 emit_move_insn (operands[3], temp);
16697 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16700 (define_expand "expdf2"
16701 [(set (match_dup 2)
16702 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16703 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16704 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16705 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16706 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16707 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16708 (parallel [(set (match_dup 10)
16709 (unspec:XF [(match_dup 9) (match_dup 5)]
16710 UNSPEC_FSCALE_FRACT))
16711 (set (match_dup 11)
16712 (unspec:XF [(match_dup 9) (match_dup 5)]
16713 UNSPEC_FSCALE_EXP))])
16714 (set (match_operand:DF 0 "register_operand" "")
16715 (float_truncate:DF (match_dup 10)))]
16716 "TARGET_USE_FANCY_MATH_387
16717 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16718 && flag_unsafe_math_optimizations && !optimize_size"
16723 for (i=2; i<12; i++)
16724 operands[i] = gen_reg_rtx (XFmode);
16725 temp = standard_80387_constant_rtx (5); /* fldl2e */
16726 emit_move_insn (operands[3], temp);
16727 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16730 (define_expand "expxf2"
16731 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16733 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16734 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16735 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16736 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16737 (parallel [(set (match_operand:XF 0 "register_operand" "")
16738 (unspec:XF [(match_dup 8) (match_dup 4)]
16739 UNSPEC_FSCALE_FRACT))
16741 (unspec:XF [(match_dup 8) (match_dup 4)]
16742 UNSPEC_FSCALE_EXP))])]
16743 "TARGET_USE_FANCY_MATH_387
16744 && flag_unsafe_math_optimizations && !optimize_size"
16749 for (i=2; i<10; i++)
16750 operands[i] = gen_reg_rtx (XFmode);
16751 temp = standard_80387_constant_rtx (5); /* fldl2e */
16752 emit_move_insn (operands[2], temp);
16753 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16756 (define_expand "exp10sf2"
16757 [(set (match_dup 2)
16758 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16759 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16760 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16761 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16762 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16763 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16764 (parallel [(set (match_dup 10)
16765 (unspec:XF [(match_dup 9) (match_dup 5)]
16766 UNSPEC_FSCALE_FRACT))
16767 (set (match_dup 11)
16768 (unspec:XF [(match_dup 9) (match_dup 5)]
16769 UNSPEC_FSCALE_EXP))])
16770 (set (match_operand:SF 0 "register_operand" "")
16771 (float_truncate:SF (match_dup 10)))]
16772 "TARGET_USE_FANCY_MATH_387
16773 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16774 && flag_unsafe_math_optimizations && !optimize_size"
16779 for (i=2; i<12; i++)
16780 operands[i] = gen_reg_rtx (XFmode);
16781 temp = standard_80387_constant_rtx (6); /* fldl2t */
16782 emit_move_insn (operands[3], temp);
16783 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16786 (define_expand "exp10df2"
16787 [(set (match_dup 2)
16788 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16789 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16790 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16791 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16792 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16793 (set (match_dup 9) (plus:XF (match_dup 7) (match_dup 8)))
16794 (parallel [(set (match_dup 10)
16795 (unspec:XF [(match_dup 9) (match_dup 5)]
16796 UNSPEC_FSCALE_FRACT))
16797 (set (match_dup 11)
16798 (unspec:XF [(match_dup 9) (match_dup 5)]
16799 UNSPEC_FSCALE_EXP))])
16800 (set (match_operand:DF 0 "register_operand" "")
16801 (float_truncate:DF (match_dup 10)))]
16802 "TARGET_USE_FANCY_MATH_387
16803 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16804 && flag_unsafe_math_optimizations && !optimize_size"
16809 for (i=2; i<12; i++)
16810 operands[i] = gen_reg_rtx (XFmode);
16811 temp = standard_80387_constant_rtx (6); /* fldl2t */
16812 emit_move_insn (operands[3], temp);
16813 emit_move_insn (operands[8], CONST1_RTX (XFmode)); /* fld1 */
16816 (define_expand "exp10xf2"
16817 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16819 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16820 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16821 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16822 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16823 (parallel [(set (match_operand:XF 0 "register_operand" "")
16824 (unspec:XF [(match_dup 8) (match_dup 4)]
16825 UNSPEC_FSCALE_FRACT))
16827 (unspec:XF [(match_dup 8) (match_dup 4)]
16828 UNSPEC_FSCALE_EXP))])]
16829 "TARGET_USE_FANCY_MATH_387
16830 && flag_unsafe_math_optimizations && !optimize_size"
16835 for (i=2; i<10; i++)
16836 operands[i] = gen_reg_rtx (XFmode);
16837 temp = standard_80387_constant_rtx (6); /* fldl2t */
16838 emit_move_insn (operands[2], temp);
16839 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16842 (define_expand "exp2sf2"
16843 [(set (match_dup 2)
16844 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16845 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16846 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16847 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16848 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16849 (parallel [(set (match_dup 8)
16850 (unspec:XF [(match_dup 7) (match_dup 3)]
16851 UNSPEC_FSCALE_FRACT))
16853 (unspec:XF [(match_dup 7) (match_dup 3)]
16854 UNSPEC_FSCALE_EXP))])
16855 (set (match_operand:SF 0 "register_operand" "")
16856 (float_truncate:SF (match_dup 8)))]
16857 "TARGET_USE_FANCY_MATH_387
16858 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16859 && flag_unsafe_math_optimizations && !optimize_size"
16863 for (i=2; i<10; i++)
16864 operands[i] = gen_reg_rtx (XFmode);
16865 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16868 (define_expand "exp2df2"
16869 [(set (match_dup 2)
16870 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16871 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16872 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16873 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16874 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16875 (parallel [(set (match_dup 8)
16876 (unspec:XF [(match_dup 7) (match_dup 3)]
16877 UNSPEC_FSCALE_FRACT))
16879 (unspec:XF [(match_dup 7) (match_dup 3)]
16880 UNSPEC_FSCALE_EXP))])
16881 (set (match_operand:DF 0 "register_operand" "")
16882 (float_truncate:DF (match_dup 8)))]
16883 "TARGET_USE_FANCY_MATH_387
16884 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16885 && flag_unsafe_math_optimizations && !optimize_size"
16889 for (i=2; i<10; i++)
16890 operands[i] = gen_reg_rtx (XFmode);
16891 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16894 (define_expand "exp2xf2"
16895 [(set (match_dup 2) (match_operand:XF 1 "register_operand" ""))
16896 (set (match_dup 3) (unspec:XF [(match_dup 2)] UNSPEC_FRNDINT))
16897 (set (match_dup 4) (minus:XF (match_dup 2) (match_dup 3)))
16898 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_F2XM1))
16899 (set (match_dup 7) (plus:XF (match_dup 5) (match_dup 6)))
16900 (parallel [(set (match_operand:XF 0 "register_operand" "")
16901 (unspec:XF [(match_dup 7) (match_dup 3)]
16902 UNSPEC_FSCALE_FRACT))
16904 (unspec:XF [(match_dup 7) (match_dup 3)]
16905 UNSPEC_FSCALE_EXP))])]
16906 "TARGET_USE_FANCY_MATH_387
16907 && flag_unsafe_math_optimizations && !optimize_size"
16911 for (i=2; i<9; i++)
16912 operands[i] = gen_reg_rtx (XFmode);
16913 emit_move_insn (operands[6], CONST1_RTX (XFmode)); /* fld1 */
16916 (define_expand "expm1df2"
16917 [(set (match_dup 2)
16918 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
16919 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16920 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16921 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16922 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16923 (parallel [(set (match_dup 8)
16924 (unspec:XF [(match_dup 7) (match_dup 5)]
16925 UNSPEC_FSCALE_FRACT))
16927 (unspec:XF [(match_dup 7) (match_dup 5)]
16928 UNSPEC_FSCALE_EXP))])
16929 (parallel [(set (match_dup 11)
16930 (unspec:XF [(match_dup 10) (match_dup 9)]
16931 UNSPEC_FSCALE_FRACT))
16932 (set (match_dup 12)
16933 (unspec:XF [(match_dup 10) (match_dup 9)]
16934 UNSPEC_FSCALE_EXP))])
16935 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16936 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16937 (set (match_operand:DF 0 "register_operand" "")
16938 (float_truncate:DF (match_dup 14)))]
16939 "TARGET_USE_FANCY_MATH_387
16940 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
16941 && flag_unsafe_math_optimizations && !optimize_size"
16946 for (i=2; i<15; i++)
16947 operands[i] = gen_reg_rtx (XFmode);
16948 temp = standard_80387_constant_rtx (5); /* fldl2e */
16949 emit_move_insn (operands[3], temp);
16950 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16953 (define_expand "expm1sf2"
16954 [(set (match_dup 2)
16955 (float_extend:XF (match_operand:SF 1 "register_operand" "")))
16956 (set (match_dup 4) (mult:XF (match_dup 2) (match_dup 3)))
16957 (set (match_dup 5) (unspec:XF [(match_dup 4)] UNSPEC_FRNDINT))
16958 (set (match_dup 6) (minus:XF (match_dup 4) (match_dup 5)))
16959 (set (match_dup 7) (unspec:XF [(match_dup 6)] UNSPEC_F2XM1))
16960 (parallel [(set (match_dup 8)
16961 (unspec:XF [(match_dup 7) (match_dup 5)]
16962 UNSPEC_FSCALE_FRACT))
16964 (unspec:XF [(match_dup 7) (match_dup 5)]
16965 UNSPEC_FSCALE_EXP))])
16966 (parallel [(set (match_dup 11)
16967 (unspec:XF [(match_dup 10) (match_dup 9)]
16968 UNSPEC_FSCALE_FRACT))
16969 (set (match_dup 12)
16970 (unspec:XF [(match_dup 10) (match_dup 9)]
16971 UNSPEC_FSCALE_EXP))])
16972 (set (match_dup 13) (minus:XF (match_dup 11) (match_dup 10)))
16973 (set (match_dup 14) (plus:XF (match_dup 13) (match_dup 8)))
16974 (set (match_operand:SF 0 "register_operand" "")
16975 (float_truncate:SF (match_dup 14)))]
16976 "TARGET_USE_FANCY_MATH_387
16977 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16978 && flag_unsafe_math_optimizations && !optimize_size"
16983 for (i=2; i<15; i++)
16984 operands[i] = gen_reg_rtx (XFmode);
16985 temp = standard_80387_constant_rtx (5); /* fldl2e */
16986 emit_move_insn (operands[3], temp);
16987 emit_move_insn (operands[10], CONST1_RTX (XFmode)); /* fld1 */
16990 (define_expand "expm1xf2"
16991 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16993 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16994 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16995 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16996 (parallel [(set (match_dup 7)
16997 (unspec:XF [(match_dup 6) (match_dup 4)]
16998 UNSPEC_FSCALE_FRACT))
17000 (unspec:XF [(match_dup 6) (match_dup 4)]
17001 UNSPEC_FSCALE_EXP))])
17002 (parallel [(set (match_dup 10)
17003 (unspec:XF [(match_dup 9) (match_dup 8)]
17004 UNSPEC_FSCALE_FRACT))
17005 (set (match_dup 11)
17006 (unspec:XF [(match_dup 9) (match_dup 8)]
17007 UNSPEC_FSCALE_EXP))])
17008 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17009 (set (match_operand:XF 0 "register_operand" "")
17010 (plus:XF (match_dup 12) (match_dup 7)))]
17011 "TARGET_USE_FANCY_MATH_387
17012 && flag_unsafe_math_optimizations && !optimize_size"
17017 for (i=2; i<13; i++)
17018 operands[i] = gen_reg_rtx (XFmode);
17019 temp = standard_80387_constant_rtx (5); /* fldl2e */
17020 emit_move_insn (operands[2], temp);
17021 emit_move_insn (operands[9], CONST1_RTX (XFmode)); /* fld1 */
17024 (define_expand "ldexpdf3"
17025 [(set (match_dup 3)
17026 (float_extend:XF (match_operand:DF 1 "register_operand" "")))
17028 (float:XF (match_operand:SI 2 "register_operand" "")))
17029 (parallel [(set (match_dup 5)
17030 (unspec:XF [(match_dup 3) (match_dup 4)]
17031 UNSPEC_FSCALE_FRACT))
17033 (unspec:XF [(match_dup 3) (match_dup 4)]
17034 UNSPEC_FSCALE_EXP))])
17035 (set (match_operand:DF 0 "register_operand" "")
17036 (float_truncate:DF (match_dup 5)))]
17037 "TARGET_USE_FANCY_MATH_387
17038 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17039 && flag_unsafe_math_optimizations && !optimize_size"
17043 for (i=3; i<7; i++)
17044 operands[i] = gen_reg_rtx (XFmode);
17047 (define_expand "ldexpsf3"
17048 [(set (match_dup 3)
17049 (float_extend:XF (match_operand:SF 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:SF 0 "register_operand" "")
17059 (float_truncate:SF (match_dup 5)))]
17060 "TARGET_USE_FANCY_MATH_387
17061 && (!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 "ldexpxf3"
17071 [(set (match_dup 3)
17072 (float:XF (match_operand:SI 2 "register_operand" "")))
17073 (parallel [(set (match_operand:XF 0 " register_operand" "")
17074 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17076 UNSPEC_FSCALE_FRACT))
17078 (unspec:XF [(match_dup 1) (match_dup 3)]
17079 UNSPEC_FSCALE_EXP))])]
17080 "TARGET_USE_FANCY_MATH_387
17081 && flag_unsafe_math_optimizations && !optimize_size"
17085 for (i=3; i<5; i++)
17086 operands[i] = gen_reg_rtx (XFmode);
17090 (define_insn "frndintxf2"
17091 [(set (match_operand:XF 0 "register_operand" "=f")
17092 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17094 "TARGET_USE_FANCY_MATH_387
17095 && flag_unsafe_math_optimizations"
17097 [(set_attr "type" "fpspc")
17098 (set_attr "mode" "XF")])
17100 (define_expand "rintdf2"
17101 [(use (match_operand:DF 0 "register_operand" ""))
17102 (use (match_operand:DF 1 "register_operand" ""))]
17103 "(TARGET_USE_FANCY_MATH_387
17104 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17105 && flag_unsafe_math_optimizations)
17106 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17107 && !flag_trapping_math
17108 && !optimize_size)"
17110 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17111 && !flag_trapping_math
17113 ix86_expand_rint (operand0, operand1);
17116 rtx op0 = gen_reg_rtx (XFmode);
17117 rtx op1 = gen_reg_rtx (XFmode);
17119 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17120 emit_insn (gen_frndintxf2 (op0, op1));
17122 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17127 (define_expand "rintsf2"
17128 [(use (match_operand:SF 0 "register_operand" ""))
17129 (use (match_operand:SF 1 "register_operand" ""))]
17130 "(TARGET_USE_FANCY_MATH_387
17131 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17132 && flag_unsafe_math_optimizations)
17133 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17134 && !flag_trapping_math
17135 && !optimize_size)"
17137 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17138 && !flag_trapping_math
17140 ix86_expand_rint (operand0, operand1);
17143 rtx op0 = gen_reg_rtx (XFmode);
17144 rtx op1 = gen_reg_rtx (XFmode);
17146 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17147 emit_insn (gen_frndintxf2 (op0, op1));
17149 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17154 (define_expand "rintxf2"
17155 [(use (match_operand:XF 0 "register_operand" ""))
17156 (use (match_operand:XF 1 "register_operand" ""))]
17157 "TARGET_USE_FANCY_MATH_387
17158 && flag_unsafe_math_optimizations && !optimize_size"
17160 emit_insn (gen_frndintxf2 (operands[0], operands[1]));
17164 (define_expand "roundsf2"
17165 [(match_operand:SF 0 "register_operand" "")
17166 (match_operand:SF 1 "nonimmediate_operand" "")]
17167 "SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17168 && !flag_trapping_math && !flag_rounding_math
17171 ix86_expand_round (operand0, operand1);
17175 (define_expand "rounddf2"
17176 [(match_operand:DF 0 "register_operand" "")
17177 (match_operand:DF 1 "nonimmediate_operand" "")]
17178 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17179 && !flag_trapping_math && !flag_rounding_math
17183 ix86_expand_round (operand0, operand1);
17185 ix86_expand_rounddf_32 (operand0, operand1);
17189 (define_insn_and_split "*fistdi2_1"
17190 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17191 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17193 "TARGET_USE_FANCY_MATH_387
17194 && !(reload_completed || reload_in_progress)"
17199 if (memory_operand (operands[0], VOIDmode))
17200 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17203 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17204 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17209 [(set_attr "type" "fpspc")
17210 (set_attr "mode" "DI")])
17212 (define_insn "fistdi2"
17213 [(set (match_operand:DI 0 "memory_operand" "=m")
17214 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17216 (clobber (match_scratch:XF 2 "=&1f"))]
17217 "TARGET_USE_FANCY_MATH_387"
17218 "* return output_fix_trunc (insn, operands, 0);"
17219 [(set_attr "type" "fpspc")
17220 (set_attr "mode" "DI")])
17222 (define_insn "fistdi2_with_temp"
17223 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17224 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17226 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
17227 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17228 "TARGET_USE_FANCY_MATH_387"
17230 [(set_attr "type" "fpspc")
17231 (set_attr "mode" "DI")])
17234 [(set (match_operand:DI 0 "register_operand" "")
17235 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17237 (clobber (match_operand:DI 2 "memory_operand" ""))
17238 (clobber (match_scratch 3 ""))]
17240 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17241 (clobber (match_dup 3))])
17242 (set (match_dup 0) (match_dup 2))]
17246 [(set (match_operand:DI 0 "memory_operand" "")
17247 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17249 (clobber (match_operand:DI 2 "memory_operand" ""))
17250 (clobber (match_scratch 3 ""))]
17252 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17253 (clobber (match_dup 3))])]
17256 (define_insn_and_split "*fist<mode>2_1"
17257 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17258 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17260 "TARGET_USE_FANCY_MATH_387
17261 && !(reload_completed || reload_in_progress)"
17266 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17267 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17271 [(set_attr "type" "fpspc")
17272 (set_attr "mode" "<MODE>")])
17274 (define_insn "fist<mode>2"
17275 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17276 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17278 "TARGET_USE_FANCY_MATH_387"
17279 "* return output_fix_trunc (insn, operands, 0);"
17280 [(set_attr "type" "fpspc")
17281 (set_attr "mode" "<MODE>")])
17283 (define_insn "fist<mode>2_with_temp"
17284 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17285 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17287 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17288 "TARGET_USE_FANCY_MATH_387"
17290 [(set_attr "type" "fpspc")
17291 (set_attr "mode" "<MODE>")])
17294 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17295 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17297 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17299 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)]
17301 (set (match_dup 0) (match_dup 2))]
17305 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17306 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17308 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17310 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17314 (define_expand "lrintxf<mode>2"
17315 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17316 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17318 "TARGET_USE_FANCY_MATH_387"
17321 (define_expand "lrint<mode>di2"
17322 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17323 (unspec:DI [(match_operand:SSEMODEF 1 "register_operand" "")]
17324 UNSPEC_FIX_NOTRUNC))]
17325 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT"
17328 (define_expand "lrint<mode>si2"
17329 [(set (match_operand:SI 0 "nonimmediate_operand" "")
17330 (unspec:SI [(match_operand:SSEMODEF 1 "register_operand" "")]
17331 UNSPEC_FIX_NOTRUNC))]
17332 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17335 (define_expand "lround<mode>di2"
17336 [(match_operand:DI 0 "nonimmediate_operand" "")
17337 (match_operand:SSEMODEF 1 "register_operand" "")]
17338 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17339 && !flag_trapping_math && !flag_rounding_math
17342 ix86_expand_lround (operand0, operand1);
17346 (define_expand "lround<mode>si2"
17347 [(match_operand:SI 0 "nonimmediate_operand" "")
17348 (match_operand:SSEMODEF 1 "register_operand" "")]
17349 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17350 && !flag_trapping_math && !flag_rounding_math
17353 ix86_expand_lround (operand0, operand1);
17357 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17358 (define_insn_and_split "frndintxf2_floor"
17359 [(set (match_operand:XF 0 "register_operand" "=f")
17360 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17361 UNSPEC_FRNDINT_FLOOR))
17362 (clobber (reg:CC FLAGS_REG))]
17363 "TARGET_USE_FANCY_MATH_387
17364 && flag_unsafe_math_optimizations
17365 && !(reload_completed || reload_in_progress)"
17370 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17372 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17373 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17375 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17376 operands[2], operands[3]));
17379 [(set_attr "type" "frndint")
17380 (set_attr "i387_cw" "floor")
17381 (set_attr "mode" "XF")])
17383 (define_insn "frndintxf2_floor_i387"
17384 [(set (match_operand:XF 0 "register_operand" "=f")
17385 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17386 UNSPEC_FRNDINT_FLOOR))
17387 (use (match_operand:HI 2 "memory_operand" "m"))
17388 (use (match_operand:HI 3 "memory_operand" "m"))]
17389 "TARGET_USE_FANCY_MATH_387
17390 && flag_unsafe_math_optimizations"
17391 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17392 [(set_attr "type" "frndint")
17393 (set_attr "i387_cw" "floor")
17394 (set_attr "mode" "XF")])
17396 (define_expand "floorxf2"
17397 [(use (match_operand:XF 0 "register_operand" ""))
17398 (use (match_operand:XF 1 "register_operand" ""))]
17399 "TARGET_USE_FANCY_MATH_387
17400 && flag_unsafe_math_optimizations && !optimize_size"
17402 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17406 (define_expand "floordf2"
17407 [(use (match_operand:DF 0 "register_operand" ""))
17408 (use (match_operand:DF 1 "register_operand" ""))]
17409 "((TARGET_USE_FANCY_MATH_387
17410 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17411 && flag_unsafe_math_optimizations)
17412 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17413 && !flag_trapping_math))
17416 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17417 && !flag_trapping_math)
17420 ix86_expand_floorceil (operand0, operand1, true);
17422 ix86_expand_floorceildf_32 (operand0, operand1, true);
17426 rtx op0 = gen_reg_rtx (XFmode);
17427 rtx op1 = gen_reg_rtx (XFmode);
17429 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17430 emit_insn (gen_frndintxf2_floor (op0, op1));
17432 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17437 (define_expand "floorsf2"
17438 [(use (match_operand:SF 0 "register_operand" ""))
17439 (use (match_operand:SF 1 "register_operand" ""))]
17440 "((TARGET_USE_FANCY_MATH_387
17441 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17442 && flag_unsafe_math_optimizations)
17443 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17444 && !flag_trapping_math))
17447 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17448 && !flag_trapping_math)
17449 ix86_expand_floorceil (operand0, operand1, true);
17452 rtx op0 = gen_reg_rtx (XFmode);
17453 rtx op1 = gen_reg_rtx (XFmode);
17455 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17456 emit_insn (gen_frndintxf2_floor (op0, op1));
17458 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17463 (define_insn_and_split "*fist<mode>2_floor_1"
17464 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17465 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17466 UNSPEC_FIST_FLOOR))
17467 (clobber (reg:CC FLAGS_REG))]
17468 "TARGET_USE_FANCY_MATH_387
17469 && flag_unsafe_math_optimizations
17470 && !(reload_completed || reload_in_progress)"
17475 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17477 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17478 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17479 if (memory_operand (operands[0], VOIDmode))
17480 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17481 operands[2], operands[3]));
17484 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17485 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17486 operands[2], operands[3],
17491 [(set_attr "type" "fistp")
17492 (set_attr "i387_cw" "floor")
17493 (set_attr "mode" "<MODE>")])
17495 (define_insn "fistdi2_floor"
17496 [(set (match_operand:DI 0 "memory_operand" "=m")
17497 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17498 UNSPEC_FIST_FLOOR))
17499 (use (match_operand:HI 2 "memory_operand" "m"))
17500 (use (match_operand:HI 3 "memory_operand" "m"))
17501 (clobber (match_scratch:XF 4 "=&1f"))]
17502 "TARGET_USE_FANCY_MATH_387
17503 && flag_unsafe_math_optimizations"
17504 "* return output_fix_trunc (insn, operands, 0);"
17505 [(set_attr "type" "fistp")
17506 (set_attr "i387_cw" "floor")
17507 (set_attr "mode" "DI")])
17509 (define_insn "fistdi2_floor_with_temp"
17510 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17511 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17512 UNSPEC_FIST_FLOOR))
17513 (use (match_operand:HI 2 "memory_operand" "m,m"))
17514 (use (match_operand:HI 3 "memory_operand" "m,m"))
17515 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17516 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17517 "TARGET_USE_FANCY_MATH_387
17518 && flag_unsafe_math_optimizations"
17520 [(set_attr "type" "fistp")
17521 (set_attr "i387_cw" "floor")
17522 (set_attr "mode" "DI")])
17525 [(set (match_operand:DI 0 "register_operand" "")
17526 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17527 UNSPEC_FIST_FLOOR))
17528 (use (match_operand:HI 2 "memory_operand" ""))
17529 (use (match_operand:HI 3 "memory_operand" ""))
17530 (clobber (match_operand:DI 4 "memory_operand" ""))
17531 (clobber (match_scratch 5 ""))]
17533 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17534 (use (match_dup 2))
17535 (use (match_dup 3))
17536 (clobber (match_dup 5))])
17537 (set (match_dup 0) (match_dup 4))]
17541 [(set (match_operand:DI 0 "memory_operand" "")
17542 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17543 UNSPEC_FIST_FLOOR))
17544 (use (match_operand:HI 2 "memory_operand" ""))
17545 (use (match_operand:HI 3 "memory_operand" ""))
17546 (clobber (match_operand:DI 4 "memory_operand" ""))
17547 (clobber (match_scratch 5 ""))]
17549 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17550 (use (match_dup 2))
17551 (use (match_dup 3))
17552 (clobber (match_dup 5))])]
17555 (define_insn "fist<mode>2_floor"
17556 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17557 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17558 UNSPEC_FIST_FLOOR))
17559 (use (match_operand:HI 2 "memory_operand" "m"))
17560 (use (match_operand:HI 3 "memory_operand" "m"))]
17561 "TARGET_USE_FANCY_MATH_387
17562 && flag_unsafe_math_optimizations"
17563 "* return output_fix_trunc (insn, operands, 0);"
17564 [(set_attr "type" "fistp")
17565 (set_attr "i387_cw" "floor")
17566 (set_attr "mode" "<MODE>")])
17568 (define_insn "fist<mode>2_floor_with_temp"
17569 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17570 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17571 UNSPEC_FIST_FLOOR))
17572 (use (match_operand:HI 2 "memory_operand" "m,m"))
17573 (use (match_operand:HI 3 "memory_operand" "m,m"))
17574 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17575 "TARGET_USE_FANCY_MATH_387
17576 && flag_unsafe_math_optimizations"
17578 [(set_attr "type" "fistp")
17579 (set_attr "i387_cw" "floor")
17580 (set_attr "mode" "<MODE>")])
17583 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17584 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17585 UNSPEC_FIST_FLOOR))
17586 (use (match_operand:HI 2 "memory_operand" ""))
17587 (use (match_operand:HI 3 "memory_operand" ""))
17588 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17590 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17591 UNSPEC_FIST_FLOOR))
17592 (use (match_dup 2))
17593 (use (match_dup 3))])
17594 (set (match_dup 0) (match_dup 4))]
17598 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17599 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17600 UNSPEC_FIST_FLOOR))
17601 (use (match_operand:HI 2 "memory_operand" ""))
17602 (use (match_operand:HI 3 "memory_operand" ""))
17603 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17605 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17606 UNSPEC_FIST_FLOOR))
17607 (use (match_dup 2))
17608 (use (match_dup 3))])]
17611 (define_expand "lfloorxf<mode>2"
17612 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17613 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17614 UNSPEC_FIST_FLOOR))
17615 (clobber (reg:CC FLAGS_REG))])]
17616 "TARGET_USE_FANCY_MATH_387
17617 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17618 && flag_unsafe_math_optimizations"
17621 (define_expand "lfloor<mode>di2"
17622 [(match_operand:DI 0 "nonimmediate_operand" "")
17623 (match_operand:SSEMODEF 1 "register_operand" "")]
17624 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17625 && !flag_trapping_math
17628 ix86_expand_lfloorceil (operand0, operand1, true);
17632 (define_expand "lfloor<mode>si2"
17633 [(match_operand:SI 0 "nonimmediate_operand" "")
17634 (match_operand:SSEMODEF 1 "register_operand" "")]
17635 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17636 && !flag_trapping_math
17637 && (!optimize_size || !TARGET_64BIT)"
17639 ix86_expand_lfloorceil (operand0, operand1, true);
17643 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17644 (define_insn_and_split "frndintxf2_ceil"
17645 [(set (match_operand:XF 0 "register_operand" "=f")
17646 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17647 UNSPEC_FRNDINT_CEIL))
17648 (clobber (reg:CC FLAGS_REG))]
17649 "TARGET_USE_FANCY_MATH_387
17650 && flag_unsafe_math_optimizations
17651 && !(reload_completed || reload_in_progress)"
17656 ix86_optimize_mode_switching[I387_CEIL] = 1;
17658 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17659 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17661 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17662 operands[2], operands[3]));
17665 [(set_attr "type" "frndint")
17666 (set_attr "i387_cw" "ceil")
17667 (set_attr "mode" "XF")])
17669 (define_insn "frndintxf2_ceil_i387"
17670 [(set (match_operand:XF 0 "register_operand" "=f")
17671 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17672 UNSPEC_FRNDINT_CEIL))
17673 (use (match_operand:HI 2 "memory_operand" "m"))
17674 (use (match_operand:HI 3 "memory_operand" "m"))]
17675 "TARGET_USE_FANCY_MATH_387
17676 && flag_unsafe_math_optimizations"
17677 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17678 [(set_attr "type" "frndint")
17679 (set_attr "i387_cw" "ceil")
17680 (set_attr "mode" "XF")])
17682 (define_expand "ceilxf2"
17683 [(use (match_operand:XF 0 "register_operand" ""))
17684 (use (match_operand:XF 1 "register_operand" ""))]
17685 "TARGET_USE_FANCY_MATH_387
17686 && flag_unsafe_math_optimizations && !optimize_size"
17688 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17692 (define_expand "ceildf2"
17693 [(use (match_operand:DF 0 "register_operand" ""))
17694 (use (match_operand:DF 1 "register_operand" ""))]
17695 "((TARGET_USE_FANCY_MATH_387
17696 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17697 && flag_unsafe_math_optimizations)
17698 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17699 && !flag_trapping_math))
17702 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17703 && !flag_trapping_math)
17706 ix86_expand_floorceil (operand0, operand1, false);
17708 ix86_expand_floorceildf_32 (operand0, operand1, false);
17712 rtx op0 = gen_reg_rtx (XFmode);
17713 rtx op1 = gen_reg_rtx (XFmode);
17715 emit_insn (gen_extenddfxf2 (op1, operands[1]));
17716 emit_insn (gen_frndintxf2_ceil (op0, op1));
17718 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
17723 (define_expand "ceilsf2"
17724 [(use (match_operand:SF 0 "register_operand" ""))
17725 (use (match_operand:SF 1 "register_operand" ""))]
17726 "((TARGET_USE_FANCY_MATH_387
17727 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17728 && flag_unsafe_math_optimizations)
17729 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17730 && !flag_trapping_math))
17733 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
17734 && !flag_trapping_math)
17735 ix86_expand_floorceil (operand0, operand1, false);
17738 rtx op0 = gen_reg_rtx (XFmode);
17739 rtx op1 = gen_reg_rtx (XFmode);
17741 emit_insn (gen_extendsfxf2 (op1, operands[1]));
17742 emit_insn (gen_frndintxf2_ceil (op0, op1));
17744 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
17749 (define_insn_and_split "*fist<mode>2_ceil_1"
17750 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
17751 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "f,f")]
17753 (clobber (reg:CC FLAGS_REG))]
17754 "TARGET_USE_FANCY_MATH_387
17755 && flag_unsafe_math_optimizations
17756 && !(reload_completed || reload_in_progress)"
17761 ix86_optimize_mode_switching[I387_CEIL] = 1;
17763 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17764 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17765 if (memory_operand (operands[0], VOIDmode))
17766 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17767 operands[2], operands[3]));
17770 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17771 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17772 operands[2], operands[3],
17777 [(set_attr "type" "fistp")
17778 (set_attr "i387_cw" "ceil")
17779 (set_attr "mode" "<MODE>")])
17781 (define_insn "fistdi2_ceil"
17782 [(set (match_operand:DI 0 "memory_operand" "=m")
17783 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17785 (use (match_operand:HI 2 "memory_operand" "m"))
17786 (use (match_operand:HI 3 "memory_operand" "m"))
17787 (clobber (match_scratch:XF 4 "=&1f"))]
17788 "TARGET_USE_FANCY_MATH_387
17789 && flag_unsafe_math_optimizations"
17790 "* return output_fix_trunc (insn, operands, 0);"
17791 [(set_attr "type" "fistp")
17792 (set_attr "i387_cw" "ceil")
17793 (set_attr "mode" "DI")])
17795 (define_insn "fistdi2_ceil_with_temp"
17796 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17797 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17799 (use (match_operand:HI 2 "memory_operand" "m,m"))
17800 (use (match_operand:HI 3 "memory_operand" "m,m"))
17801 (clobber (match_operand:DI 4 "memory_operand" "=m,m"))
17802 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17803 "TARGET_USE_FANCY_MATH_387
17804 && flag_unsafe_math_optimizations"
17806 [(set_attr "type" "fistp")
17807 (set_attr "i387_cw" "ceil")
17808 (set_attr "mode" "DI")])
17811 [(set (match_operand:DI 0 "register_operand" "")
17812 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17814 (use (match_operand:HI 2 "memory_operand" ""))
17815 (use (match_operand:HI 3 "memory_operand" ""))
17816 (clobber (match_operand:DI 4 "memory_operand" ""))
17817 (clobber (match_scratch 5 ""))]
17819 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17820 (use (match_dup 2))
17821 (use (match_dup 3))
17822 (clobber (match_dup 5))])
17823 (set (match_dup 0) (match_dup 4))]
17827 [(set (match_operand:DI 0 "memory_operand" "")
17828 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17830 (use (match_operand:HI 2 "memory_operand" ""))
17831 (use (match_operand:HI 3 "memory_operand" ""))
17832 (clobber (match_operand:DI 4 "memory_operand" ""))
17833 (clobber (match_scratch 5 ""))]
17835 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17836 (use (match_dup 2))
17837 (use (match_dup 3))
17838 (clobber (match_dup 5))])]
17841 (define_insn "fist<mode>2_ceil"
17842 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17843 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17845 (use (match_operand:HI 2 "memory_operand" "m"))
17846 (use (match_operand:HI 3 "memory_operand" "m"))]
17847 "TARGET_USE_FANCY_MATH_387
17848 && flag_unsafe_math_optimizations"
17849 "* return output_fix_trunc (insn, operands, 0);"
17850 [(set_attr "type" "fistp")
17851 (set_attr "i387_cw" "ceil")
17852 (set_attr "mode" "<MODE>")])
17854 (define_insn "fist<mode>2_ceil_with_temp"
17855 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17856 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17858 (use (match_operand:HI 2 "memory_operand" "m,m"))
17859 (use (match_operand:HI 3 "memory_operand" "m,m"))
17860 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=m,m"))]
17861 "TARGET_USE_FANCY_MATH_387
17862 && flag_unsafe_math_optimizations"
17864 [(set_attr "type" "fistp")
17865 (set_attr "i387_cw" "ceil")
17866 (set_attr "mode" "<MODE>")])
17869 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17870 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17872 (use (match_operand:HI 2 "memory_operand" ""))
17873 (use (match_operand:HI 3 "memory_operand" ""))
17874 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17876 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17878 (use (match_dup 2))
17879 (use (match_dup 3))])
17880 (set (match_dup 0) (match_dup 4))]
17884 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17885 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17887 (use (match_operand:HI 2 "memory_operand" ""))
17888 (use (match_operand:HI 3 "memory_operand" ""))
17889 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17891 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17893 (use (match_dup 2))
17894 (use (match_dup 3))])]
17897 (define_expand "lceilxf<mode>2"
17898 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17899 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17901 (clobber (reg:CC FLAGS_REG))])]
17902 "TARGET_USE_FANCY_MATH_387
17903 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17904 && flag_unsafe_math_optimizations"
17907 (define_expand "lceil<mode>di2"
17908 [(match_operand:DI 0 "nonimmediate_operand" "")
17909 (match_operand:SSEMODEF 1 "register_operand" "")]
17910 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17911 && !flag_trapping_math"
17913 ix86_expand_lfloorceil (operand0, operand1, false);
17917 (define_expand "lceil<mode>si2"
17918 [(match_operand:SI 0 "nonimmediate_operand" "")
17919 (match_operand:SSEMODEF 1 "register_operand" "")]
17920 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17921 && !flag_trapping_math"
17923 ix86_expand_lfloorceil (operand0, operand1, false);
17927 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17928 (define_insn_and_split "frndintxf2_trunc"
17929 [(set (match_operand:XF 0 "register_operand" "=f")
17930 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17931 UNSPEC_FRNDINT_TRUNC))
17932 (clobber (reg:CC FLAGS_REG))]
17933 "TARGET_USE_FANCY_MATH_387
17934 && flag_unsafe_math_optimizations
17935 && !(reload_completed || reload_in_progress)"
17940 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17942 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17943 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17945 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17946 operands[2], operands[3]));
17949 [(set_attr "type" "frndint")
17950 (set_attr "i387_cw" "trunc")
17951 (set_attr "mode" "XF")])
17953 (define_insn "frndintxf2_trunc_i387"
17954 [(set (match_operand:XF 0 "register_operand" "=f")
17955 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17956 UNSPEC_FRNDINT_TRUNC))
17957 (use (match_operand:HI 2 "memory_operand" "m"))
17958 (use (match_operand:HI 3 "memory_operand" "m"))]
17959 "TARGET_USE_FANCY_MATH_387
17960 && flag_unsafe_math_optimizations"
17961 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17962 [(set_attr "type" "frndint")
17963 (set_attr "i387_cw" "trunc")
17964 (set_attr "mode" "XF")])
17966 (define_expand "btruncxf2"
17967 [(use (match_operand:XF 0 "register_operand" ""))
17968 (use (match_operand:XF 1 "register_operand" ""))]
17969 "TARGET_USE_FANCY_MATH_387
17970 && flag_unsafe_math_optimizations && !optimize_size"
17972 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17976 (define_expand "btruncdf2"
17977 [(use (match_operand:DF 0 "register_operand" ""))
17978 (use (match_operand:DF 1 "register_operand" ""))]
17979 "((TARGET_USE_FANCY_MATH_387
17980 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
17981 && flag_unsafe_math_optimizations)
17982 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17983 && !flag_trapping_math))
17986 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH
17987 && !flag_trapping_math)
17990 ix86_expand_trunc (operand0, operand1);
17992 ix86_expand_truncdf_32 (operand0, operand1);
17996 rtx op0 = gen_reg_rtx (XFmode);
17997 rtx op1 = gen_reg_rtx (XFmode);
17999 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18000 emit_insn (gen_frndintxf2_trunc (op0, op1));
18002 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18007 (define_expand "btruncsf2"
18008 [(use (match_operand:SF 0 "register_operand" ""))
18009 (use (match_operand:SF 1 "register_operand" ""))]
18010 "((TARGET_USE_FANCY_MATH_387
18011 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18012 && flag_unsafe_math_optimizations)
18013 || (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18014 && !flag_trapping_math))
18017 if (SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH
18018 && !flag_trapping_math)
18019 ix86_expand_trunc (operand0, operand1);
18022 rtx op0 = gen_reg_rtx (XFmode);
18023 rtx op1 = gen_reg_rtx (XFmode);
18025 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18026 emit_insn (gen_frndintxf2_trunc (op0, op1));
18028 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18033 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18034 (define_insn_and_split "frndintxf2_mask_pm"
18035 [(set (match_operand:XF 0 "register_operand" "=f")
18036 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18037 UNSPEC_FRNDINT_MASK_PM))
18038 (clobber (reg:CC FLAGS_REG))]
18039 "TARGET_USE_FANCY_MATH_387
18040 && flag_unsafe_math_optimizations
18041 && !(reload_completed || reload_in_progress)"
18046 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18048 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18049 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18051 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18052 operands[2], operands[3]));
18055 [(set_attr "type" "frndint")
18056 (set_attr "i387_cw" "mask_pm")
18057 (set_attr "mode" "XF")])
18059 (define_insn "frndintxf2_mask_pm_i387"
18060 [(set (match_operand:XF 0 "register_operand" "=f")
18061 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18062 UNSPEC_FRNDINT_MASK_PM))
18063 (use (match_operand:HI 2 "memory_operand" "m"))
18064 (use (match_operand:HI 3 "memory_operand" "m"))]
18065 "TARGET_USE_FANCY_MATH_387
18066 && flag_unsafe_math_optimizations"
18067 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18068 [(set_attr "type" "frndint")
18069 (set_attr "i387_cw" "mask_pm")
18070 (set_attr "mode" "XF")])
18072 (define_expand "nearbyintxf2"
18073 [(use (match_operand:XF 0 "register_operand" ""))
18074 (use (match_operand:XF 1 "register_operand" ""))]
18075 "TARGET_USE_FANCY_MATH_387
18076 && flag_unsafe_math_optimizations"
18078 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18083 (define_expand "nearbyintdf2"
18084 [(use (match_operand:DF 0 "register_operand" ""))
18085 (use (match_operand:DF 1 "register_operand" ""))]
18086 "TARGET_USE_FANCY_MATH_387
18087 && (!(TARGET_SSE2 && TARGET_SSE_MATH) || TARGET_MIX_SSE_I387)
18088 && flag_unsafe_math_optimizations"
18090 rtx op0 = gen_reg_rtx (XFmode);
18091 rtx op1 = gen_reg_rtx (XFmode);
18093 emit_insn (gen_extenddfxf2 (op1, operands[1]));
18094 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18096 emit_insn (gen_truncxfdf2_i387_noop (operands[0], op0));
18100 (define_expand "nearbyintsf2"
18101 [(use (match_operand:SF 0 "register_operand" ""))
18102 (use (match_operand:SF 1 "register_operand" ""))]
18103 "TARGET_USE_FANCY_MATH_387
18104 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18105 && flag_unsafe_math_optimizations"
18107 rtx op0 = gen_reg_rtx (XFmode);
18108 rtx op1 = gen_reg_rtx (XFmode);
18110 emit_insn (gen_extendsfxf2 (op1, operands[1]));
18111 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18113 emit_insn (gen_truncxfsf2_i387_noop (operands[0], op0));
18118 ;; Block operation instructions
18121 [(set (reg:SI DIRFLAG_REG) (const_int 0))]
18124 [(set_attr "type" "cld")])
18126 (define_expand "movmemsi"
18127 [(use (match_operand:BLK 0 "memory_operand" ""))
18128 (use (match_operand:BLK 1 "memory_operand" ""))
18129 (use (match_operand:SI 2 "nonmemory_operand" ""))
18130 (use (match_operand:SI 3 "const_int_operand" ""))]
18131 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18133 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18139 (define_expand "movmemdi"
18140 [(use (match_operand:BLK 0 "memory_operand" ""))
18141 (use (match_operand:BLK 1 "memory_operand" ""))
18142 (use (match_operand:DI 2 "nonmemory_operand" ""))
18143 (use (match_operand:DI 3 "const_int_operand" ""))]
18146 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3]))
18152 ;; Most CPUs don't like single string operations
18153 ;; Handle this case here to simplify previous expander.
18155 (define_expand "strmov"
18156 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18157 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18158 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18159 (clobber (reg:CC FLAGS_REG))])
18160 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18161 (clobber (reg:CC FLAGS_REG))])]
18164 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18166 /* If .md ever supports :P for Pmode, these can be directly
18167 in the pattern above. */
18168 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18169 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18171 if (TARGET_SINGLE_STRINGOP || optimize_size)
18173 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18174 operands[2], operands[3],
18175 operands[5], operands[6]));
18179 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18182 (define_expand "strmov_singleop"
18183 [(parallel [(set (match_operand 1 "memory_operand" "")
18184 (match_operand 3 "memory_operand" ""))
18185 (set (match_operand 0 "register_operand" "")
18186 (match_operand 4 "" ""))
18187 (set (match_operand 2 "register_operand" "")
18188 (match_operand 5 "" ""))
18189 (use (reg:SI DIRFLAG_REG))])]
18190 "TARGET_SINGLE_STRINGOP || optimize_size"
18193 (define_insn "*strmovdi_rex_1"
18194 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18195 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18196 (set (match_operand:DI 0 "register_operand" "=D")
18197 (plus:DI (match_dup 2)
18199 (set (match_operand:DI 1 "register_operand" "=S")
18200 (plus:DI (match_dup 3)
18202 (use (reg:SI DIRFLAG_REG))]
18203 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18205 [(set_attr "type" "str")
18206 (set_attr "mode" "DI")
18207 (set_attr "memory" "both")])
18209 (define_insn "*strmovsi_1"
18210 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18211 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18212 (set (match_operand:SI 0 "register_operand" "=D")
18213 (plus:SI (match_dup 2)
18215 (set (match_operand:SI 1 "register_operand" "=S")
18216 (plus:SI (match_dup 3)
18218 (use (reg:SI DIRFLAG_REG))]
18219 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18221 [(set_attr "type" "str")
18222 (set_attr "mode" "SI")
18223 (set_attr "memory" "both")])
18225 (define_insn "*strmovsi_rex_1"
18226 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18227 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18228 (set (match_operand:DI 0 "register_operand" "=D")
18229 (plus:DI (match_dup 2)
18231 (set (match_operand:DI 1 "register_operand" "=S")
18232 (plus:DI (match_dup 3)
18234 (use (reg:SI DIRFLAG_REG))]
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 "*strmovhi_1"
18242 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18243 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18244 (set (match_operand:SI 0 "register_operand" "=D")
18245 (plus:SI (match_dup 2)
18247 (set (match_operand:SI 1 "register_operand" "=S")
18248 (plus:SI (match_dup 3)
18250 (use (reg:SI DIRFLAG_REG))]
18251 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18253 [(set_attr "type" "str")
18254 (set_attr "memory" "both")
18255 (set_attr "mode" "HI")])
18257 (define_insn "*strmovhi_rex_1"
18258 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18259 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18260 (set (match_operand:DI 0 "register_operand" "=D")
18261 (plus:DI (match_dup 2)
18263 (set (match_operand:DI 1 "register_operand" "=S")
18264 (plus:DI (match_dup 3)
18266 (use (reg:SI DIRFLAG_REG))]
18267 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18269 [(set_attr "type" "str")
18270 (set_attr "memory" "both")
18271 (set_attr "mode" "HI")])
18273 (define_insn "*strmovqi_1"
18274 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18275 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18276 (set (match_operand:SI 0 "register_operand" "=D")
18277 (plus:SI (match_dup 2)
18279 (set (match_operand:SI 1 "register_operand" "=S")
18280 (plus:SI (match_dup 3)
18282 (use (reg:SI DIRFLAG_REG))]
18283 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18285 [(set_attr "type" "str")
18286 (set_attr "memory" "both")
18287 (set_attr "mode" "QI")])
18289 (define_insn "*strmovqi_rex_1"
18290 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18291 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18292 (set (match_operand:DI 0 "register_operand" "=D")
18293 (plus:DI (match_dup 2)
18295 (set (match_operand:DI 1 "register_operand" "=S")
18296 (plus:DI (match_dup 3)
18298 (use (reg:SI DIRFLAG_REG))]
18299 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18301 [(set_attr "type" "str")
18302 (set_attr "memory" "both")
18303 (set_attr "mode" "QI")])
18305 (define_expand "rep_mov"
18306 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18307 (set (match_operand 0 "register_operand" "")
18308 (match_operand 5 "" ""))
18309 (set (match_operand 2 "register_operand" "")
18310 (match_operand 6 "" ""))
18311 (set (match_operand 1 "memory_operand" "")
18312 (match_operand 3 "memory_operand" ""))
18313 (use (match_dup 4))
18314 (use (reg:SI DIRFLAG_REG))])]
18318 (define_insn "*rep_movdi_rex64"
18319 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18320 (set (match_operand:DI 0 "register_operand" "=D")
18321 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18323 (match_operand:DI 3 "register_operand" "0")))
18324 (set (match_operand:DI 1 "register_operand" "=S")
18325 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18326 (match_operand:DI 4 "register_operand" "1")))
18327 (set (mem:BLK (match_dup 3))
18328 (mem:BLK (match_dup 4)))
18329 (use (match_dup 5))
18330 (use (reg:SI DIRFLAG_REG))]
18332 "{rep\;movsq|rep movsq}"
18333 [(set_attr "type" "str")
18334 (set_attr "prefix_rep" "1")
18335 (set_attr "memory" "both")
18336 (set_attr "mode" "DI")])
18338 (define_insn "*rep_movsi"
18339 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18340 (set (match_operand:SI 0 "register_operand" "=D")
18341 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18343 (match_operand:SI 3 "register_operand" "0")))
18344 (set (match_operand:SI 1 "register_operand" "=S")
18345 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18346 (match_operand:SI 4 "register_operand" "1")))
18347 (set (mem:BLK (match_dup 3))
18348 (mem:BLK (match_dup 4)))
18349 (use (match_dup 5))
18350 (use (reg:SI DIRFLAG_REG))]
18352 "{rep\;movsl|rep movsd}"
18353 [(set_attr "type" "str")
18354 (set_attr "prefix_rep" "1")
18355 (set_attr "memory" "both")
18356 (set_attr "mode" "SI")])
18358 (define_insn "*rep_movsi_rex64"
18359 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18360 (set (match_operand:DI 0 "register_operand" "=D")
18361 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18363 (match_operand:DI 3 "register_operand" "0")))
18364 (set (match_operand:DI 1 "register_operand" "=S")
18365 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18366 (match_operand:DI 4 "register_operand" "1")))
18367 (set (mem:BLK (match_dup 3))
18368 (mem:BLK (match_dup 4)))
18369 (use (match_dup 5))
18370 (use (reg:SI DIRFLAG_REG))]
18372 "{rep\;movsl|rep movsd}"
18373 [(set_attr "type" "str")
18374 (set_attr "prefix_rep" "1")
18375 (set_attr "memory" "both")
18376 (set_attr "mode" "SI")])
18378 (define_insn "*rep_movqi"
18379 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18380 (set (match_operand:SI 0 "register_operand" "=D")
18381 (plus:SI (match_operand:SI 3 "register_operand" "0")
18382 (match_operand:SI 5 "register_operand" "2")))
18383 (set (match_operand:SI 1 "register_operand" "=S")
18384 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18385 (set (mem:BLK (match_dup 3))
18386 (mem:BLK (match_dup 4)))
18387 (use (match_dup 5))
18388 (use (reg:SI DIRFLAG_REG))]
18390 "{rep\;movsb|rep movsb}"
18391 [(set_attr "type" "str")
18392 (set_attr "prefix_rep" "1")
18393 (set_attr "memory" "both")
18394 (set_attr "mode" "SI")])
18396 (define_insn "*rep_movqi_rex64"
18397 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18398 (set (match_operand:DI 0 "register_operand" "=D")
18399 (plus:DI (match_operand:DI 3 "register_operand" "0")
18400 (match_operand:DI 5 "register_operand" "2")))
18401 (set (match_operand:DI 1 "register_operand" "=S")
18402 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18403 (set (mem:BLK (match_dup 3))
18404 (mem:BLK (match_dup 4)))
18405 (use (match_dup 5))
18406 (use (reg:SI DIRFLAG_REG))]
18408 "{rep\;movsb|rep movsb}"
18409 [(set_attr "type" "str")
18410 (set_attr "prefix_rep" "1")
18411 (set_attr "memory" "both")
18412 (set_attr "mode" "SI")])
18414 (define_expand "setmemsi"
18415 [(use (match_operand:BLK 0 "memory_operand" ""))
18416 (use (match_operand:SI 1 "nonmemory_operand" ""))
18417 (use (match_operand 2 "const_int_operand" ""))
18418 (use (match_operand 3 "const_int_operand" ""))]
18421 /* If value to set is not zero, use the library routine. */
18422 if (operands[2] != const0_rtx)
18425 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18431 (define_expand "setmemdi"
18432 [(use (match_operand:BLK 0 "memory_operand" ""))
18433 (use (match_operand:DI 1 "nonmemory_operand" ""))
18434 (use (match_operand 2 "const_int_operand" ""))
18435 (use (match_operand 3 "const_int_operand" ""))]
18438 /* If value to set is not zero, use the library routine. */
18439 if (operands[2] != const0_rtx)
18442 if (ix86_expand_clrmem (operands[0], operands[1], operands[3]))
18448 ;; Most CPUs don't like single string operations
18449 ;; Handle this case here to simplify previous expander.
18451 (define_expand "strset"
18452 [(set (match_operand 1 "memory_operand" "")
18453 (match_operand 2 "register_operand" ""))
18454 (parallel [(set (match_operand 0 "register_operand" "")
18456 (clobber (reg:CC FLAGS_REG))])]
18459 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18460 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18462 /* If .md ever supports :P for Pmode, this can be directly
18463 in the pattern above. */
18464 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18465 GEN_INT (GET_MODE_SIZE (GET_MODE
18467 if (TARGET_SINGLE_STRINGOP || optimize_size)
18469 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18475 (define_expand "strset_singleop"
18476 [(parallel [(set (match_operand 1 "memory_operand" "")
18477 (match_operand 2 "register_operand" ""))
18478 (set (match_operand 0 "register_operand" "")
18479 (match_operand 3 "" ""))
18480 (use (reg:SI DIRFLAG_REG))])]
18481 "TARGET_SINGLE_STRINGOP || optimize_size"
18484 (define_insn "*strsetdi_rex_1"
18485 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18486 (match_operand:DI 2 "register_operand" "a"))
18487 (set (match_operand:DI 0 "register_operand" "=D")
18488 (plus:DI (match_dup 1)
18490 (use (reg:SI DIRFLAG_REG))]
18491 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18493 [(set_attr "type" "str")
18494 (set_attr "memory" "store")
18495 (set_attr "mode" "DI")])
18497 (define_insn "*strsetsi_1"
18498 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18499 (match_operand:SI 2 "register_operand" "a"))
18500 (set (match_operand:SI 0 "register_operand" "=D")
18501 (plus:SI (match_dup 1)
18503 (use (reg:SI DIRFLAG_REG))]
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 (use (reg:SI DIRFLAG_REG))]
18517 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18519 [(set_attr "type" "str")
18520 (set_attr "memory" "store")
18521 (set_attr "mode" "SI")])
18523 (define_insn "*strsethi_1"
18524 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18525 (match_operand:HI 2 "register_operand" "a"))
18526 (set (match_operand:SI 0 "register_operand" "=D")
18527 (plus:SI (match_dup 1)
18529 (use (reg:SI DIRFLAG_REG))]
18530 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18532 [(set_attr "type" "str")
18533 (set_attr "memory" "store")
18534 (set_attr "mode" "HI")])
18536 (define_insn "*strsethi_rex_1"
18537 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18538 (match_operand:HI 2 "register_operand" "a"))
18539 (set (match_operand:DI 0 "register_operand" "=D")
18540 (plus:DI (match_dup 1)
18542 (use (reg:SI DIRFLAG_REG))]
18543 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18545 [(set_attr "type" "str")
18546 (set_attr "memory" "store")
18547 (set_attr "mode" "HI")])
18549 (define_insn "*strsetqi_1"
18550 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18551 (match_operand:QI 2 "register_operand" "a"))
18552 (set (match_operand:SI 0 "register_operand" "=D")
18553 (plus:SI (match_dup 1)
18555 (use (reg:SI DIRFLAG_REG))]
18556 "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18558 [(set_attr "type" "str")
18559 (set_attr "memory" "store")
18560 (set_attr "mode" "QI")])
18562 (define_insn "*strsetqi_rex_1"
18563 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18564 (match_operand:QI 2 "register_operand" "a"))
18565 (set (match_operand:DI 0 "register_operand" "=D")
18566 (plus:DI (match_dup 1)
18568 (use (reg:SI DIRFLAG_REG))]
18569 "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18571 [(set_attr "type" "str")
18572 (set_attr "memory" "store")
18573 (set_attr "mode" "QI")])
18575 (define_expand "rep_stos"
18576 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18577 (set (match_operand 0 "register_operand" "")
18578 (match_operand 4 "" ""))
18579 (set (match_operand 2 "memory_operand" "") (const_int 0))
18580 (use (match_operand 3 "register_operand" ""))
18581 (use (match_dup 1))
18582 (use (reg:SI DIRFLAG_REG))])]
18586 (define_insn "*rep_stosdi_rex64"
18587 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18588 (set (match_operand:DI 0 "register_operand" "=D")
18589 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18591 (match_operand:DI 3 "register_operand" "0")))
18592 (set (mem:BLK (match_dup 3))
18594 (use (match_operand:DI 2 "register_operand" "a"))
18595 (use (match_dup 4))
18596 (use (reg:SI DIRFLAG_REG))]
18598 "{rep\;stosq|rep stosq}"
18599 [(set_attr "type" "str")
18600 (set_attr "prefix_rep" "1")
18601 (set_attr "memory" "store")
18602 (set_attr "mode" "DI")])
18604 (define_insn "*rep_stossi"
18605 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18606 (set (match_operand:SI 0 "register_operand" "=D")
18607 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18609 (match_operand:SI 3 "register_operand" "0")))
18610 (set (mem:BLK (match_dup 3))
18612 (use (match_operand:SI 2 "register_operand" "a"))
18613 (use (match_dup 4))
18614 (use (reg:SI DIRFLAG_REG))]
18616 "{rep\;stosl|rep stosd}"
18617 [(set_attr "type" "str")
18618 (set_attr "prefix_rep" "1")
18619 (set_attr "memory" "store")
18620 (set_attr "mode" "SI")])
18622 (define_insn "*rep_stossi_rex64"
18623 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18624 (set (match_operand:DI 0 "register_operand" "=D")
18625 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18627 (match_operand:DI 3 "register_operand" "0")))
18628 (set (mem:BLK (match_dup 3))
18630 (use (match_operand:SI 2 "register_operand" "a"))
18631 (use (match_dup 4))
18632 (use (reg:SI DIRFLAG_REG))]
18634 "{rep\;stosl|rep stosd}"
18635 [(set_attr "type" "str")
18636 (set_attr "prefix_rep" "1")
18637 (set_attr "memory" "store")
18638 (set_attr "mode" "SI")])
18640 (define_insn "*rep_stosqi"
18641 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18642 (set (match_operand:SI 0 "register_operand" "=D")
18643 (plus:SI (match_operand:SI 3 "register_operand" "0")
18644 (match_operand:SI 4 "register_operand" "1")))
18645 (set (mem:BLK (match_dup 3))
18647 (use (match_operand:QI 2 "register_operand" "a"))
18648 (use (match_dup 4))
18649 (use (reg:SI DIRFLAG_REG))]
18651 "{rep\;stosb|rep stosb}"
18652 [(set_attr "type" "str")
18653 (set_attr "prefix_rep" "1")
18654 (set_attr "memory" "store")
18655 (set_attr "mode" "QI")])
18657 (define_insn "*rep_stosqi_rex64"
18658 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18659 (set (match_operand:DI 0 "register_operand" "=D")
18660 (plus:DI (match_operand:DI 3 "register_operand" "0")
18661 (match_operand:DI 4 "register_operand" "1")))
18662 (set (mem:BLK (match_dup 3))
18664 (use (match_operand:QI 2 "register_operand" "a"))
18665 (use (match_dup 4))
18666 (use (reg:SI DIRFLAG_REG))]
18668 "{rep\;stosb|rep stosb}"
18669 [(set_attr "type" "str")
18670 (set_attr "prefix_rep" "1")
18671 (set_attr "memory" "store")
18672 (set_attr "mode" "QI")])
18674 (define_expand "cmpstrnsi"
18675 [(set (match_operand:SI 0 "register_operand" "")
18676 (compare:SI (match_operand:BLK 1 "general_operand" "")
18677 (match_operand:BLK 2 "general_operand" "")))
18678 (use (match_operand 3 "general_operand" ""))
18679 (use (match_operand 4 "immediate_operand" ""))]
18680 "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18682 rtx addr1, addr2, out, outlow, count, countreg, align;
18684 /* Can't use this if the user has appropriated esi or edi. */
18685 if (global_regs[4] || global_regs[5])
18689 if (GET_CODE (out) != REG)
18690 out = gen_reg_rtx (SImode);
18692 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18693 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18694 if (addr1 != XEXP (operands[1], 0))
18695 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18696 if (addr2 != XEXP (operands[2], 0))
18697 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18699 count = operands[3];
18700 countreg = ix86_zero_extend_to_Pmode (count);
18702 /* %%% Iff we are testing strict equality, we can use known alignment
18703 to good advantage. This may be possible with combine, particularly
18704 once cc0 is dead. */
18705 align = operands[4];
18707 emit_insn (gen_cld ());
18708 if (GET_CODE (count) == CONST_INT)
18710 if (INTVAL (count) == 0)
18712 emit_move_insn (operands[0], const0_rtx);
18715 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18716 operands[1], operands[2]));
18721 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18723 emit_insn (gen_cmpsi_1 (countreg, countreg));
18724 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18725 operands[1], operands[2]));
18728 outlow = gen_lowpart (QImode, out);
18729 emit_insn (gen_cmpintqi (outlow));
18730 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18732 if (operands[0] != out)
18733 emit_move_insn (operands[0], out);
18738 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18740 (define_expand "cmpintqi"
18741 [(set (match_dup 1)
18742 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18744 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18745 (parallel [(set (match_operand:QI 0 "register_operand" "")
18746 (minus:QI (match_dup 1)
18748 (clobber (reg:CC FLAGS_REG))])]
18750 "operands[1] = gen_reg_rtx (QImode);
18751 operands[2] = gen_reg_rtx (QImode);")
18753 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18754 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18756 (define_expand "cmpstrnqi_nz_1"
18757 [(parallel [(set (reg:CC FLAGS_REG)
18758 (compare:CC (match_operand 4 "memory_operand" "")
18759 (match_operand 5 "memory_operand" "")))
18760 (use (match_operand 2 "register_operand" ""))
18761 (use (match_operand:SI 3 "immediate_operand" ""))
18762 (use (reg:SI DIRFLAG_REG))
18763 (clobber (match_operand 0 "register_operand" ""))
18764 (clobber (match_operand 1 "register_operand" ""))
18765 (clobber (match_dup 2))])]
18769 (define_insn "*cmpstrnqi_nz_1"
18770 [(set (reg:CC FLAGS_REG)
18771 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18772 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18773 (use (match_operand:SI 6 "register_operand" "2"))
18774 (use (match_operand:SI 3 "immediate_operand" "i"))
18775 (use (reg:SI DIRFLAG_REG))
18776 (clobber (match_operand:SI 0 "register_operand" "=S"))
18777 (clobber (match_operand:SI 1 "register_operand" "=D"))
18778 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18781 [(set_attr "type" "str")
18782 (set_attr "mode" "QI")
18783 (set_attr "prefix_rep" "1")])
18785 (define_insn "*cmpstrnqi_nz_rex_1"
18786 [(set (reg:CC FLAGS_REG)
18787 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18788 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18789 (use (match_operand:DI 6 "register_operand" "2"))
18790 (use (match_operand:SI 3 "immediate_operand" "i"))
18791 (use (reg:SI DIRFLAG_REG))
18792 (clobber (match_operand:DI 0 "register_operand" "=S"))
18793 (clobber (match_operand:DI 1 "register_operand" "=D"))
18794 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18797 [(set_attr "type" "str")
18798 (set_attr "mode" "QI")
18799 (set_attr "prefix_rep" "1")])
18801 ;; The same, but the count is not known to not be zero.
18803 (define_expand "cmpstrnqi_1"
18804 [(parallel [(set (reg:CC FLAGS_REG)
18805 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18807 (compare:CC (match_operand 4 "memory_operand" "")
18808 (match_operand 5 "memory_operand" ""))
18810 (use (match_operand:SI 3 "immediate_operand" ""))
18811 (use (reg:CC FLAGS_REG))
18812 (use (reg:SI DIRFLAG_REG))
18813 (clobber (match_operand 0 "register_operand" ""))
18814 (clobber (match_operand 1 "register_operand" ""))
18815 (clobber (match_dup 2))])]
18819 (define_insn "*cmpstrnqi_1"
18820 [(set (reg:CC FLAGS_REG)
18821 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18823 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18824 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18826 (use (match_operand:SI 3 "immediate_operand" "i"))
18827 (use (reg:CC FLAGS_REG))
18828 (use (reg:SI DIRFLAG_REG))
18829 (clobber (match_operand:SI 0 "register_operand" "=S"))
18830 (clobber (match_operand:SI 1 "register_operand" "=D"))
18831 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18834 [(set_attr "type" "str")
18835 (set_attr "mode" "QI")
18836 (set_attr "prefix_rep" "1")])
18838 (define_insn "*cmpstrnqi_rex_1"
18839 [(set (reg:CC FLAGS_REG)
18840 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18842 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18843 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18845 (use (match_operand:SI 3 "immediate_operand" "i"))
18846 (use (reg:CC FLAGS_REG))
18847 (use (reg:SI DIRFLAG_REG))
18848 (clobber (match_operand:DI 0 "register_operand" "=S"))
18849 (clobber (match_operand:DI 1 "register_operand" "=D"))
18850 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18853 [(set_attr "type" "str")
18854 (set_attr "mode" "QI")
18855 (set_attr "prefix_rep" "1")])
18857 (define_expand "strlensi"
18858 [(set (match_operand:SI 0 "register_operand" "")
18859 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18860 (match_operand:QI 2 "immediate_operand" "")
18861 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18864 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18870 (define_expand "strlendi"
18871 [(set (match_operand:DI 0 "register_operand" "")
18872 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18873 (match_operand:QI 2 "immediate_operand" "")
18874 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18877 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18883 (define_expand "strlenqi_1"
18884 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18885 (use (reg:SI DIRFLAG_REG))
18886 (clobber (match_operand 1 "register_operand" ""))
18887 (clobber (reg:CC FLAGS_REG))])]
18891 (define_insn "*strlenqi_1"
18892 [(set (match_operand:SI 0 "register_operand" "=&c")
18893 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18894 (match_operand:QI 2 "register_operand" "a")
18895 (match_operand:SI 3 "immediate_operand" "i")
18896 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18897 (use (reg:SI DIRFLAG_REG))
18898 (clobber (match_operand:SI 1 "register_operand" "=D"))
18899 (clobber (reg:CC FLAGS_REG))]
18902 [(set_attr "type" "str")
18903 (set_attr "mode" "QI")
18904 (set_attr "prefix_rep" "1")])
18906 (define_insn "*strlenqi_rex_1"
18907 [(set (match_operand:DI 0 "register_operand" "=&c")
18908 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18909 (match_operand:QI 2 "register_operand" "a")
18910 (match_operand:DI 3 "immediate_operand" "i")
18911 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18912 (use (reg:SI DIRFLAG_REG))
18913 (clobber (match_operand:DI 1 "register_operand" "=D"))
18914 (clobber (reg:CC FLAGS_REG))]
18917 [(set_attr "type" "str")
18918 (set_attr "mode" "QI")
18919 (set_attr "prefix_rep" "1")])
18921 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18922 ;; handled in combine, but it is not currently up to the task.
18923 ;; When used for their truth value, the cmpstrn* expanders generate
18932 ;; The intermediate three instructions are unnecessary.
18934 ;; This one handles cmpstrn*_nz_1...
18937 (set (reg:CC FLAGS_REG)
18938 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18939 (mem:BLK (match_operand 5 "register_operand" ""))))
18940 (use (match_operand 6 "register_operand" ""))
18941 (use (match_operand:SI 3 "immediate_operand" ""))
18942 (use (reg:SI DIRFLAG_REG))
18943 (clobber (match_operand 0 "register_operand" ""))
18944 (clobber (match_operand 1 "register_operand" ""))
18945 (clobber (match_operand 2 "register_operand" ""))])
18946 (set (match_operand:QI 7 "register_operand" "")
18947 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18948 (set (match_operand:QI 8 "register_operand" "")
18949 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18950 (set (reg FLAGS_REG)
18951 (compare (match_dup 7) (match_dup 8)))
18953 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18955 (set (reg:CC FLAGS_REG)
18956 (compare:CC (mem:BLK (match_dup 4))
18957 (mem:BLK (match_dup 5))))
18958 (use (match_dup 6))
18959 (use (match_dup 3))
18960 (use (reg:SI DIRFLAG_REG))
18961 (clobber (match_dup 0))
18962 (clobber (match_dup 1))
18963 (clobber (match_dup 2))])]
18966 ;; ...and this one handles cmpstrn*_1.
18969 (set (reg:CC FLAGS_REG)
18970 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18972 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18973 (mem:BLK (match_operand 5 "register_operand" "")))
18975 (use (match_operand:SI 3 "immediate_operand" ""))
18976 (use (reg:CC FLAGS_REG))
18977 (use (reg:SI DIRFLAG_REG))
18978 (clobber (match_operand 0 "register_operand" ""))
18979 (clobber (match_operand 1 "register_operand" ""))
18980 (clobber (match_operand 2 "register_operand" ""))])
18981 (set (match_operand:QI 7 "register_operand" "")
18982 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18983 (set (match_operand:QI 8 "register_operand" "")
18984 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18985 (set (reg FLAGS_REG)
18986 (compare (match_dup 7) (match_dup 8)))
18988 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18990 (set (reg:CC FLAGS_REG)
18991 (if_then_else:CC (ne (match_dup 6)
18993 (compare:CC (mem:BLK (match_dup 4))
18994 (mem:BLK (match_dup 5)))
18996 (use (match_dup 3))
18997 (use (reg:CC FLAGS_REG))
18998 (use (reg:SI DIRFLAG_REG))
18999 (clobber (match_dup 0))
19000 (clobber (match_dup 1))
19001 (clobber (match_dup 2))])]
19006 ;; Conditional move instructions.
19008 (define_expand "movdicc"
19009 [(set (match_operand:DI 0 "register_operand" "")
19010 (if_then_else:DI (match_operand 1 "comparison_operator" "")
19011 (match_operand:DI 2 "general_operand" "")
19012 (match_operand:DI 3 "general_operand" "")))]
19014 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19016 (define_insn "x86_movdicc_0_m1_rex64"
19017 [(set (match_operand:DI 0 "register_operand" "=r")
19018 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19021 (clobber (reg:CC FLAGS_REG))]
19024 ; Since we don't have the proper number of operands for an alu insn,
19025 ; fill in all the blanks.
19026 [(set_attr "type" "alu")
19027 (set_attr "pent_pair" "pu")
19028 (set_attr "memory" "none")
19029 (set_attr "imm_disp" "false")
19030 (set_attr "mode" "DI")
19031 (set_attr "length_immediate" "0")])
19033 (define_insn "*movdicc_c_rex64"
19034 [(set (match_operand:DI 0 "register_operand" "=r,r")
19035 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19036 [(reg FLAGS_REG) (const_int 0)])
19037 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19038 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19039 "TARGET_64BIT && TARGET_CMOVE
19040 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19042 cmov%O2%C1\t{%2, %0|%0, %2}
19043 cmov%O2%c1\t{%3, %0|%0, %3}"
19044 [(set_attr "type" "icmov")
19045 (set_attr "mode" "DI")])
19047 (define_expand "movsicc"
19048 [(set (match_operand:SI 0 "register_operand" "")
19049 (if_then_else:SI (match_operand 1 "comparison_operator" "")
19050 (match_operand:SI 2 "general_operand" "")
19051 (match_operand:SI 3 "general_operand" "")))]
19053 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19055 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19056 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19057 ;; So just document what we're doing explicitly.
19059 (define_insn "x86_movsicc_0_m1"
19060 [(set (match_operand:SI 0 "register_operand" "=r")
19061 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19064 (clobber (reg:CC FLAGS_REG))]
19067 ; Since we don't have the proper number of operands for an alu insn,
19068 ; fill in all the blanks.
19069 [(set_attr "type" "alu")
19070 (set_attr "pent_pair" "pu")
19071 (set_attr "memory" "none")
19072 (set_attr "imm_disp" "false")
19073 (set_attr "mode" "SI")
19074 (set_attr "length_immediate" "0")])
19076 (define_insn "*movsicc_noc"
19077 [(set (match_operand:SI 0 "register_operand" "=r,r")
19078 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19079 [(reg FLAGS_REG) (const_int 0)])
19080 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19081 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19083 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19085 cmov%O2%C1\t{%2, %0|%0, %2}
19086 cmov%O2%c1\t{%3, %0|%0, %3}"
19087 [(set_attr "type" "icmov")
19088 (set_attr "mode" "SI")])
19090 (define_expand "movhicc"
19091 [(set (match_operand:HI 0 "register_operand" "")
19092 (if_then_else:HI (match_operand 1 "comparison_operator" "")
19093 (match_operand:HI 2 "general_operand" "")
19094 (match_operand:HI 3 "general_operand" "")))]
19095 "TARGET_HIMODE_MATH"
19096 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19098 (define_insn "*movhicc_noc"
19099 [(set (match_operand:HI 0 "register_operand" "=r,r")
19100 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19101 [(reg FLAGS_REG) (const_int 0)])
19102 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19103 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19105 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19107 cmov%O2%C1\t{%2, %0|%0, %2}
19108 cmov%O2%c1\t{%3, %0|%0, %3}"
19109 [(set_attr "type" "icmov")
19110 (set_attr "mode" "HI")])
19112 (define_expand "movqicc"
19113 [(set (match_operand:QI 0 "register_operand" "")
19114 (if_then_else:QI (match_operand 1 "comparison_operator" "")
19115 (match_operand:QI 2 "general_operand" "")
19116 (match_operand:QI 3 "general_operand" "")))]
19117 "TARGET_QIMODE_MATH"
19118 "if (!ix86_expand_int_movcc (operands)) FAIL; DONE;")
19120 (define_insn_and_split "*movqicc_noc"
19121 [(set (match_operand:QI 0 "register_operand" "=r,r")
19122 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19123 [(match_operand 4 "flags_reg_operand" "")
19125 (match_operand:QI 2 "register_operand" "r,0")
19126 (match_operand:QI 3 "register_operand" "0,r")))]
19127 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19129 "&& reload_completed"
19130 [(set (match_dup 0)
19131 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19134 "operands[0] = gen_lowpart (SImode, operands[0]);
19135 operands[2] = gen_lowpart (SImode, operands[2]);
19136 operands[3] = gen_lowpart (SImode, operands[3]);"
19137 [(set_attr "type" "icmov")
19138 (set_attr "mode" "SI")])
19140 (define_expand "movsfcc"
19141 [(set (match_operand:SF 0 "register_operand" "")
19142 (if_then_else:SF (match_operand 1 "comparison_operator" "")
19143 (match_operand:SF 2 "register_operand" "")
19144 (match_operand:SF 3 "register_operand" "")))]
19145 "(TARGET_80387 && TARGET_CMOVE) || TARGET_SSE_MATH"
19146 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19148 (define_insn "*movsfcc_1_387"
19149 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19150 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19151 [(reg FLAGS_REG) (const_int 0)])
19152 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19153 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19154 "TARGET_80387 && TARGET_CMOVE
19155 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19157 fcmov%F1\t{%2, %0|%0, %2}
19158 fcmov%f1\t{%3, %0|%0, %3}
19159 cmov%O2%C1\t{%2, %0|%0, %2}
19160 cmov%O2%c1\t{%3, %0|%0, %3}"
19161 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19162 (set_attr "mode" "SF,SF,SI,SI")])
19164 (define_expand "movdfcc"
19165 [(set (match_operand:DF 0 "register_operand" "")
19166 (if_then_else:DF (match_operand 1 "comparison_operator" "")
19167 (match_operand:DF 2 "register_operand" "")
19168 (match_operand:DF 3 "register_operand" "")))]
19169 "(TARGET_80387 && TARGET_CMOVE) || (TARGET_SSE2 && TARGET_SSE_MATH)"
19170 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19172 (define_insn "*movdfcc_1"
19173 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19174 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19175 [(reg FLAGS_REG) (const_int 0)])
19176 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19177 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19178 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19179 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19181 fcmov%F1\t{%2, %0|%0, %2}
19182 fcmov%f1\t{%3, %0|%0, %3}
19185 [(set_attr "type" "fcmov,fcmov,multi,multi")
19186 (set_attr "mode" "DF")])
19188 (define_insn "*movdfcc_1_rex64"
19189 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19190 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19191 [(reg FLAGS_REG) (const_int 0)])
19192 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19193 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19194 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19195 && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
19197 fcmov%F1\t{%2, %0|%0, %2}
19198 fcmov%f1\t{%3, %0|%0, %3}
19199 cmov%O2%C1\t{%2, %0|%0, %2}
19200 cmov%O2%c1\t{%3, %0|%0, %3}"
19201 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19202 (set_attr "mode" "DF")])
19205 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19206 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19207 [(match_operand 4 "flags_reg_operand" "")
19209 (match_operand:DF 2 "nonimmediate_operand" "")
19210 (match_operand:DF 3 "nonimmediate_operand" "")))]
19211 "!TARGET_64BIT && reload_completed"
19212 [(set (match_dup 2)
19213 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19217 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19220 "split_di (operands+2, 1, operands+5, operands+6);
19221 split_di (operands+3, 1, operands+7, operands+8);
19222 split_di (operands, 1, operands+2, operands+3);")
19224 (define_expand "movxfcc"
19225 [(set (match_operand:XF 0 "register_operand" "")
19226 (if_then_else:XF (match_operand 1 "comparison_operator" "")
19227 (match_operand:XF 2 "register_operand" "")
19228 (match_operand:XF 3 "register_operand" "")))]
19229 "TARGET_80387 && TARGET_CMOVE"
19230 "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
19232 (define_insn "*movxfcc_1"
19233 [(set (match_operand:XF 0 "register_operand" "=f,f")
19234 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19235 [(reg FLAGS_REG) (const_int 0)])
19236 (match_operand:XF 2 "register_operand" "f,0")
19237 (match_operand:XF 3 "register_operand" "0,f")))]
19238 "TARGET_80387 && TARGET_CMOVE"
19240 fcmov%F1\t{%2, %0|%0, %2}
19241 fcmov%f1\t{%3, %0|%0, %3}"
19242 [(set_attr "type" "fcmov")
19243 (set_attr "mode" "XF")])
19245 ;; These versions of the min/max patterns are intentionally ignorant of
19246 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19247 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19248 ;; are undefined in this condition, we're certain this is correct.
19250 (define_insn "sminsf3"
19251 [(set (match_operand:SF 0 "register_operand" "=x")
19252 (smin:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19253 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19255 "minss\t{%2, %0|%0, %2}"
19256 [(set_attr "type" "sseadd")
19257 (set_attr "mode" "SF")])
19259 (define_insn "smaxsf3"
19260 [(set (match_operand:SF 0 "register_operand" "=x")
19261 (smax:SF (match_operand:SF 1 "nonimmediate_operand" "%0")
19262 (match_operand:SF 2 "nonimmediate_operand" "xm")))]
19264 "maxss\t{%2, %0|%0, %2}"
19265 [(set_attr "type" "sseadd")
19266 (set_attr "mode" "SF")])
19268 (define_insn "smindf3"
19269 [(set (match_operand:DF 0 "register_operand" "=x")
19270 (smin:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19271 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19272 "TARGET_SSE2 && TARGET_SSE_MATH"
19273 "minsd\t{%2, %0|%0, %2}"
19274 [(set_attr "type" "sseadd")
19275 (set_attr "mode" "DF")])
19277 (define_insn "smaxdf3"
19278 [(set (match_operand:DF 0 "register_operand" "=x")
19279 (smax:DF (match_operand:DF 1 "nonimmediate_operand" "%0")
19280 (match_operand:DF 2 "nonimmediate_operand" "xm")))]
19281 "TARGET_SSE2 && TARGET_SSE_MATH"
19282 "maxsd\t{%2, %0|%0, %2}"
19283 [(set_attr "type" "sseadd")
19284 (set_attr "mode" "DF")])
19286 ;; These versions of the min/max patterns implement exactly the operations
19287 ;; min = (op1 < op2 ? op1 : op2)
19288 ;; max = (!(op1 < op2) ? op1 : op2)
19289 ;; Their operands are not commutative, and thus they may be used in the
19290 ;; presence of -0.0 and NaN.
19292 (define_insn "*ieee_sminsf3"
19293 [(set (match_operand:SF 0 "register_operand" "=x")
19294 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19295 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19298 "minss\t{%2, %0|%0, %2}"
19299 [(set_attr "type" "sseadd")
19300 (set_attr "mode" "SF")])
19302 (define_insn "*ieee_smaxsf3"
19303 [(set (match_operand:SF 0 "register_operand" "=x")
19304 (unspec:SF [(match_operand:SF 1 "register_operand" "0")
19305 (match_operand:SF 2 "nonimmediate_operand" "xm")]
19308 "maxss\t{%2, %0|%0, %2}"
19309 [(set_attr "type" "sseadd")
19310 (set_attr "mode" "SF")])
19312 (define_insn "*ieee_smindf3"
19313 [(set (match_operand:DF 0 "register_operand" "=x")
19314 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19315 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19317 "TARGET_SSE2 && TARGET_SSE_MATH"
19318 "minsd\t{%2, %0|%0, %2}"
19319 [(set_attr "type" "sseadd")
19320 (set_attr "mode" "DF")])
19322 (define_insn "*ieee_smaxdf3"
19323 [(set (match_operand:DF 0 "register_operand" "=x")
19324 (unspec:DF [(match_operand:DF 1 "register_operand" "0")
19325 (match_operand:DF 2 "nonimmediate_operand" "xm")]
19327 "TARGET_SSE2 && TARGET_SSE_MATH"
19328 "maxsd\t{%2, %0|%0, %2}"
19329 [(set_attr "type" "sseadd")
19330 (set_attr "mode" "DF")])
19332 ;; Make two stack loads independent:
19334 ;; fld %st(0) -> fld bb
19335 ;; fmul bb fmul %st(1), %st
19337 ;; Actually we only match the last two instructions for simplicity.
19339 [(set (match_operand 0 "fp_register_operand" "")
19340 (match_operand 1 "fp_register_operand" ""))
19342 (match_operator 2 "binary_fp_operator"
19344 (match_operand 3 "memory_operand" "")]))]
19345 "REGNO (operands[0]) != REGNO (operands[1])"
19346 [(set (match_dup 0) (match_dup 3))
19347 (set (match_dup 0) (match_dup 4))]
19349 ;; The % modifier is not operational anymore in peephole2's, so we have to
19350 ;; swap the operands manually in the case of addition and multiplication.
19351 "if (COMMUTATIVE_ARITH_P (operands[2]))
19352 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19353 operands[0], operands[1]);
19355 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19356 operands[1], operands[0]);")
19358 ;; Conditional addition patterns
19359 (define_expand "addqicc"
19360 [(match_operand:QI 0 "register_operand" "")
19361 (match_operand 1 "comparison_operator" "")
19362 (match_operand:QI 2 "register_operand" "")
19363 (match_operand:QI 3 "const_int_operand" "")]
19365 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19367 (define_expand "addhicc"
19368 [(match_operand:HI 0 "register_operand" "")
19369 (match_operand 1 "comparison_operator" "")
19370 (match_operand:HI 2 "register_operand" "")
19371 (match_operand:HI 3 "const_int_operand" "")]
19373 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19375 (define_expand "addsicc"
19376 [(match_operand:SI 0 "register_operand" "")
19377 (match_operand 1 "comparison_operator" "")
19378 (match_operand:SI 2 "register_operand" "")
19379 (match_operand:SI 3 "const_int_operand" "")]
19381 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19383 (define_expand "adddicc"
19384 [(match_operand:DI 0 "register_operand" "")
19385 (match_operand 1 "comparison_operator" "")
19386 (match_operand:DI 2 "register_operand" "")
19387 (match_operand:DI 3 "const_int_operand" "")]
19389 "if (!ix86_expand_int_addcc (operands)) FAIL; DONE;")
19392 ;; Misc patterns (?)
19394 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19395 ;; Otherwise there will be nothing to keep
19397 ;; [(set (reg ebp) (reg esp))]
19398 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19399 ;; (clobber (eflags)]
19400 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19402 ;; in proper program order.
19403 (define_insn "pro_epilogue_adjust_stack_1"
19404 [(set (match_operand:SI 0 "register_operand" "=r,r")
19405 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19406 (match_operand:SI 2 "immediate_operand" "i,i")))
19407 (clobber (reg:CC FLAGS_REG))
19408 (clobber (mem:BLK (scratch)))]
19411 switch (get_attr_type (insn))
19414 return "mov{l}\t{%1, %0|%0, %1}";
19417 if (GET_CODE (operands[2]) == CONST_INT
19418 && (INTVAL (operands[2]) == 128
19419 || (INTVAL (operands[2]) < 0
19420 && INTVAL (operands[2]) != -128)))
19422 operands[2] = GEN_INT (-INTVAL (operands[2]));
19423 return "sub{l}\t{%2, %0|%0, %2}";
19425 return "add{l}\t{%2, %0|%0, %2}";
19428 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19429 return "lea{l}\t{%a2, %0|%0, %a2}";
19432 gcc_unreachable ();
19435 [(set (attr "type")
19436 (cond [(eq_attr "alternative" "0")
19437 (const_string "alu")
19438 (match_operand:SI 2 "const0_operand" "")
19439 (const_string "imov")
19441 (const_string "lea")))
19442 (set_attr "mode" "SI")])
19444 (define_insn "pro_epilogue_adjust_stack_rex64"
19445 [(set (match_operand:DI 0 "register_operand" "=r,r")
19446 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19447 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19448 (clobber (reg:CC FLAGS_REG))
19449 (clobber (mem:BLK (scratch)))]
19452 switch (get_attr_type (insn))
19455 return "mov{q}\t{%1, %0|%0, %1}";
19458 if (GET_CODE (operands[2]) == CONST_INT
19459 /* Avoid overflows. */
19460 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19461 && (INTVAL (operands[2]) == 128
19462 || (INTVAL (operands[2]) < 0
19463 && INTVAL (operands[2]) != -128)))
19465 operands[2] = GEN_INT (-INTVAL (operands[2]));
19466 return "sub{q}\t{%2, %0|%0, %2}";
19468 return "add{q}\t{%2, %0|%0, %2}";
19471 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19472 return "lea{q}\t{%a2, %0|%0, %a2}";
19475 gcc_unreachable ();
19478 [(set (attr "type")
19479 (cond [(eq_attr "alternative" "0")
19480 (const_string "alu")
19481 (match_operand:DI 2 "const0_operand" "")
19482 (const_string "imov")
19484 (const_string "lea")))
19485 (set_attr "mode" "DI")])
19487 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19488 [(set (match_operand:DI 0 "register_operand" "=r,r")
19489 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19490 (match_operand:DI 3 "immediate_operand" "i,i")))
19491 (use (match_operand:DI 2 "register_operand" "r,r"))
19492 (clobber (reg:CC FLAGS_REG))
19493 (clobber (mem:BLK (scratch)))]
19496 switch (get_attr_type (insn))
19499 return "add{q}\t{%2, %0|%0, %2}";
19502 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19503 return "lea{q}\t{%a2, %0|%0, %a2}";
19506 gcc_unreachable ();
19509 [(set_attr "type" "alu,lea")
19510 (set_attr "mode" "DI")])
19512 (define_expand "allocate_stack_worker"
19513 [(match_operand:SI 0 "register_operand" "")]
19514 "TARGET_STACK_PROBE"
19516 if (reload_completed)
19519 emit_insn (gen_allocate_stack_worker_rex64_postreload (operands[0]));
19521 emit_insn (gen_allocate_stack_worker_postreload (operands[0]));
19526 emit_insn (gen_allocate_stack_worker_rex64 (operands[0]));
19528 emit_insn (gen_allocate_stack_worker_1 (operands[0]));
19533 (define_insn "allocate_stack_worker_1"
19534 [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19535 UNSPECV_STACK_PROBE)
19536 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19537 (clobber (match_scratch:SI 1 "=0"))
19538 (clobber (reg:CC FLAGS_REG))]
19539 "!TARGET_64BIT && TARGET_STACK_PROBE"
19541 [(set_attr "type" "multi")
19542 (set_attr "length" "5")])
19544 (define_expand "allocate_stack_worker_postreload"
19545 [(parallel [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "a")]
19546 UNSPECV_STACK_PROBE)
19547 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19548 (clobber (match_dup 0))
19549 (clobber (reg:CC FLAGS_REG))])]
19553 (define_insn "allocate_stack_worker_rex64"
19554 [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19555 UNSPECV_STACK_PROBE)
19556 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19557 (clobber (match_scratch:DI 1 "=0"))
19558 (clobber (reg:CC FLAGS_REG))]
19559 "TARGET_64BIT && TARGET_STACK_PROBE"
19561 [(set_attr "type" "multi")
19562 (set_attr "length" "5")])
19564 (define_expand "allocate_stack_worker_rex64_postreload"
19565 [(parallel [(unspec_volatile:DI [(match_operand:DI 0 "register_operand" "a")]
19566 UNSPECV_STACK_PROBE)
19567 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19568 (clobber (match_dup 0))
19569 (clobber (reg:CC FLAGS_REG))])]
19573 (define_expand "allocate_stack"
19574 [(parallel [(set (match_operand:SI 0 "register_operand" "=r")
19575 (minus:SI (reg:SI SP_REG)
19576 (match_operand:SI 1 "general_operand" "")))
19577 (clobber (reg:CC FLAGS_REG))])
19578 (parallel [(set (reg:SI SP_REG)
19579 (minus:SI (reg:SI SP_REG) (match_dup 1)))
19580 (clobber (reg:CC FLAGS_REG))])]
19581 "TARGET_STACK_PROBE"
19583 #ifdef CHECK_STACK_LIMIT
19584 if (GET_CODE (operands[1]) == CONST_INT
19585 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19586 emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx,
19590 emit_insn (gen_allocate_stack_worker (copy_to_mode_reg (SImode,
19593 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19597 (define_expand "builtin_setjmp_receiver"
19598 [(label_ref (match_operand 0 "" ""))]
19599 "!TARGET_64BIT && flag_pic"
19604 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19605 rtx label_rtx = gen_label_rtx ();
19606 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19607 xops[0] = xops[1] = picreg;
19608 xops[2] = gen_rtx_CONST (SImode,
19609 gen_rtx_MINUS (SImode,
19610 gen_rtx_LABEL_REF (SImode, label_rtx),
19611 gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19612 ix86_expand_binary_operator (MINUS, SImode, xops);
19615 emit_insn (gen_set_got (pic_offset_table_rtx));
19619 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19622 [(set (match_operand 0 "register_operand" "")
19623 (match_operator 3 "promotable_binary_operator"
19624 [(match_operand 1 "register_operand" "")
19625 (match_operand 2 "aligned_operand" "")]))
19626 (clobber (reg:CC FLAGS_REG))]
19627 "! TARGET_PARTIAL_REG_STALL && reload_completed
19628 && ((GET_MODE (operands[0]) == HImode
19629 && ((!optimize_size && !TARGET_FAST_PREFIX)
19630 /* ??? next two lines just !satisfies_constraint_K (...) */
19631 || GET_CODE (operands[2]) != CONST_INT
19632 || satisfies_constraint_K (operands[2])))
19633 || (GET_MODE (operands[0]) == QImode
19634 && (TARGET_PROMOTE_QImode || optimize_size)))"
19635 [(parallel [(set (match_dup 0)
19636 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19637 (clobber (reg:CC FLAGS_REG))])]
19638 "operands[0] = gen_lowpart (SImode, operands[0]);
19639 operands[1] = gen_lowpart (SImode, operands[1]);
19640 if (GET_CODE (operands[3]) != ASHIFT)
19641 operands[2] = gen_lowpart (SImode, operands[2]);
19642 PUT_MODE (operands[3], SImode);")
19644 ; Promote the QImode tests, as i386 has encoding of the AND
19645 ; instruction with 32-bit sign-extended immediate and thus the
19646 ; instruction size is unchanged, except in the %eax case for
19647 ; which it is increased by one byte, hence the ! optimize_size.
19649 [(set (match_operand 0 "flags_reg_operand" "")
19650 (match_operator 2 "compare_operator"
19651 [(and (match_operand 3 "aligned_operand" "")
19652 (match_operand 4 "const_int_operand" ""))
19654 (set (match_operand 1 "register_operand" "")
19655 (and (match_dup 3) (match_dup 4)))]
19656 "! TARGET_PARTIAL_REG_STALL && reload_completed
19657 /* Ensure that the operand will remain sign-extended immediate. */
19658 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)
19660 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19661 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))"
19662 [(parallel [(set (match_dup 0)
19663 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19666 (and:SI (match_dup 3) (match_dup 4)))])]
19669 = gen_int_mode (INTVAL (operands[4])
19670 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19671 operands[1] = gen_lowpart (SImode, operands[1]);
19672 operands[3] = gen_lowpart (SImode, operands[3]);
19675 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19676 ; the TEST instruction with 32-bit sign-extended immediate and thus
19677 ; the instruction size would at least double, which is not what we
19678 ; want even with ! optimize_size.
19680 [(set (match_operand 0 "flags_reg_operand" "")
19681 (match_operator 1 "compare_operator"
19682 [(and (match_operand:HI 2 "aligned_operand" "")
19683 (match_operand:HI 3 "const_int_operand" ""))
19685 "! TARGET_PARTIAL_REG_STALL && reload_completed
19686 /* Ensure that the operand will remain sign-extended immediate. */
19687 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)
19688 && ! TARGET_FAST_PREFIX
19689 && ! optimize_size"
19690 [(set (match_dup 0)
19691 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19695 = gen_int_mode (INTVAL (operands[3])
19696 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19697 operands[2] = gen_lowpart (SImode, operands[2]);
19701 [(set (match_operand 0 "register_operand" "")
19702 (neg (match_operand 1 "register_operand" "")))
19703 (clobber (reg:CC FLAGS_REG))]
19704 "! TARGET_PARTIAL_REG_STALL && reload_completed
19705 && (GET_MODE (operands[0]) == HImode
19706 || (GET_MODE (operands[0]) == QImode
19707 && (TARGET_PROMOTE_QImode || optimize_size)))"
19708 [(parallel [(set (match_dup 0)
19709 (neg:SI (match_dup 1)))
19710 (clobber (reg:CC FLAGS_REG))])]
19711 "operands[0] = gen_lowpart (SImode, operands[0]);
19712 operands[1] = gen_lowpart (SImode, operands[1]);")
19715 [(set (match_operand 0 "register_operand" "")
19716 (not (match_operand 1 "register_operand" "")))]
19717 "! TARGET_PARTIAL_REG_STALL && reload_completed
19718 && (GET_MODE (operands[0]) == HImode
19719 || (GET_MODE (operands[0]) == QImode
19720 && (TARGET_PROMOTE_QImode || optimize_size)))"
19721 [(set (match_dup 0)
19722 (not:SI (match_dup 1)))]
19723 "operands[0] = gen_lowpart (SImode, operands[0]);
19724 operands[1] = gen_lowpart (SImode, operands[1]);")
19727 [(set (match_operand 0 "register_operand" "")
19728 (if_then_else (match_operator 1 "comparison_operator"
19729 [(reg FLAGS_REG) (const_int 0)])
19730 (match_operand 2 "register_operand" "")
19731 (match_operand 3 "register_operand" "")))]
19732 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19733 && (GET_MODE (operands[0]) == HImode
19734 || (GET_MODE (operands[0]) == QImode
19735 && (TARGET_PROMOTE_QImode || optimize_size)))"
19736 [(set (match_dup 0)
19737 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19738 "operands[0] = gen_lowpart (SImode, operands[0]);
19739 operands[2] = gen_lowpart (SImode, operands[2]);
19740 operands[3] = gen_lowpart (SImode, operands[3]);")
19743 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19744 ;; transform a complex memory operation into two memory to register operations.
19746 ;; Don't push memory operands
19748 [(set (match_operand:SI 0 "push_operand" "")
19749 (match_operand:SI 1 "memory_operand" ""))
19750 (match_scratch:SI 2 "r")]
19751 "!optimize_size && !TARGET_PUSH_MEMORY
19752 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19753 [(set (match_dup 2) (match_dup 1))
19754 (set (match_dup 0) (match_dup 2))]
19758 [(set (match_operand:DI 0 "push_operand" "")
19759 (match_operand:DI 1 "memory_operand" ""))
19760 (match_scratch:DI 2 "r")]
19761 "!optimize_size && !TARGET_PUSH_MEMORY
19762 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19763 [(set (match_dup 2) (match_dup 1))
19764 (set (match_dup 0) (match_dup 2))]
19767 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19770 [(set (match_operand:SF 0 "push_operand" "")
19771 (match_operand:SF 1 "memory_operand" ""))
19772 (match_scratch:SF 2 "r")]
19773 "!optimize_size && !TARGET_PUSH_MEMORY
19774 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19775 [(set (match_dup 2) (match_dup 1))
19776 (set (match_dup 0) (match_dup 2))]
19780 [(set (match_operand:HI 0 "push_operand" "")
19781 (match_operand:HI 1 "memory_operand" ""))
19782 (match_scratch:HI 2 "r")]
19783 "!optimize_size && !TARGET_PUSH_MEMORY
19784 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19785 [(set (match_dup 2) (match_dup 1))
19786 (set (match_dup 0) (match_dup 2))]
19790 [(set (match_operand:QI 0 "push_operand" "")
19791 (match_operand:QI 1 "memory_operand" ""))
19792 (match_scratch:QI 2 "q")]
19793 "!optimize_size && !TARGET_PUSH_MEMORY
19794 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19795 [(set (match_dup 2) (match_dup 1))
19796 (set (match_dup 0) (match_dup 2))]
19799 ;; Don't move an immediate directly to memory when the instruction
19802 [(match_scratch:SI 1 "r")
19803 (set (match_operand:SI 0 "memory_operand" "")
19806 && ! TARGET_USE_MOV0
19807 && TARGET_SPLIT_LONG_MOVES
19808 && get_attr_length (insn) >= ix86_cost->large_insn
19809 && peep2_regno_dead_p (0, FLAGS_REG)"
19810 [(parallel [(set (match_dup 1) (const_int 0))
19811 (clobber (reg:CC FLAGS_REG))])
19812 (set (match_dup 0) (match_dup 1))]
19816 [(match_scratch:HI 1 "r")
19817 (set (match_operand:HI 0 "memory_operand" "")
19820 && ! TARGET_USE_MOV0
19821 && TARGET_SPLIT_LONG_MOVES
19822 && get_attr_length (insn) >= ix86_cost->large_insn
19823 && peep2_regno_dead_p (0, FLAGS_REG)"
19824 [(parallel [(set (match_dup 2) (const_int 0))
19825 (clobber (reg:CC FLAGS_REG))])
19826 (set (match_dup 0) (match_dup 1))]
19827 "operands[2] = gen_lowpart (SImode, operands[1]);")
19830 [(match_scratch:QI 1 "q")
19831 (set (match_operand:QI 0 "memory_operand" "")
19834 && ! TARGET_USE_MOV0
19835 && TARGET_SPLIT_LONG_MOVES
19836 && get_attr_length (insn) >= ix86_cost->large_insn
19837 && peep2_regno_dead_p (0, FLAGS_REG)"
19838 [(parallel [(set (match_dup 2) (const_int 0))
19839 (clobber (reg:CC FLAGS_REG))])
19840 (set (match_dup 0) (match_dup 1))]
19841 "operands[2] = gen_lowpart (SImode, operands[1]);")
19844 [(match_scratch:SI 2 "r")
19845 (set (match_operand:SI 0 "memory_operand" "")
19846 (match_operand:SI 1 "immediate_operand" ""))]
19848 && get_attr_length (insn) >= ix86_cost->large_insn
19849 && TARGET_SPLIT_LONG_MOVES"
19850 [(set (match_dup 2) (match_dup 1))
19851 (set (match_dup 0) (match_dup 2))]
19855 [(match_scratch:HI 2 "r")
19856 (set (match_operand:HI 0 "memory_operand" "")
19857 (match_operand:HI 1 "immediate_operand" ""))]
19858 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19859 && TARGET_SPLIT_LONG_MOVES"
19860 [(set (match_dup 2) (match_dup 1))
19861 (set (match_dup 0) (match_dup 2))]
19865 [(match_scratch:QI 2 "q")
19866 (set (match_operand:QI 0 "memory_operand" "")
19867 (match_operand:QI 1 "immediate_operand" ""))]
19868 "! optimize_size && get_attr_length (insn) >= ix86_cost->large_insn
19869 && TARGET_SPLIT_LONG_MOVES"
19870 [(set (match_dup 2) (match_dup 1))
19871 (set (match_dup 0) (match_dup 2))]
19874 ;; Don't compare memory with zero, load and use a test instead.
19876 [(set (match_operand 0 "flags_reg_operand" "")
19877 (match_operator 1 "compare_operator"
19878 [(match_operand:SI 2 "memory_operand" "")
19880 (match_scratch:SI 3 "r")]
19881 "ix86_match_ccmode (insn, CCNOmode) && ! optimize_size"
19882 [(set (match_dup 3) (match_dup 2))
19883 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19886 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19887 ;; Don't split NOTs with a displacement operand, because resulting XOR
19888 ;; will not be pairable anyway.
19890 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19891 ;; represented using a modRM byte. The XOR replacement is long decoded,
19892 ;; so this split helps here as well.
19894 ;; Note: Can't do this as a regular split because we can't get proper
19895 ;; lifetime information then.
19898 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19899 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19901 && peep2_regno_dead_p (0, FLAGS_REG)
19902 && ((TARGET_PENTIUM
19903 && (GET_CODE (operands[0]) != MEM
19904 || !memory_displacement_operand (operands[0], SImode)))
19905 || (TARGET_K6 && long_memory_operand (operands[0], SImode)))"
19906 [(parallel [(set (match_dup 0)
19907 (xor:SI (match_dup 1) (const_int -1)))
19908 (clobber (reg:CC FLAGS_REG))])]
19912 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19913 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19915 && peep2_regno_dead_p (0, FLAGS_REG)
19916 && ((TARGET_PENTIUM
19917 && (GET_CODE (operands[0]) != MEM
19918 || !memory_displacement_operand (operands[0], HImode)))
19919 || (TARGET_K6 && long_memory_operand (operands[0], HImode)))"
19920 [(parallel [(set (match_dup 0)
19921 (xor:HI (match_dup 1) (const_int -1)))
19922 (clobber (reg:CC FLAGS_REG))])]
19926 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19927 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19929 && peep2_regno_dead_p (0, FLAGS_REG)
19930 && ((TARGET_PENTIUM
19931 && (GET_CODE (operands[0]) != MEM
19932 || !memory_displacement_operand (operands[0], QImode)))
19933 || (TARGET_K6 && long_memory_operand (operands[0], QImode)))"
19934 [(parallel [(set (match_dup 0)
19935 (xor:QI (match_dup 1) (const_int -1)))
19936 (clobber (reg:CC FLAGS_REG))])]
19939 ;; Non pairable "test imm, reg" instructions can be translated to
19940 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19941 ;; byte opcode instead of two, have a short form for byte operands),
19942 ;; so do it for other CPUs as well. Given that the value was dead,
19943 ;; this should not create any new dependencies. Pass on the sub-word
19944 ;; versions if we're concerned about partial register stalls.
19947 [(set (match_operand 0 "flags_reg_operand" "")
19948 (match_operator 1 "compare_operator"
19949 [(and:SI (match_operand:SI 2 "register_operand" "")
19950 (match_operand:SI 3 "immediate_operand" ""))
19952 "ix86_match_ccmode (insn, CCNOmode)
19953 && (true_regnum (operands[2]) != 0
19954 || satisfies_constraint_K (operands[3]))
19955 && peep2_reg_dead_p (1, operands[2])"
19957 [(set (match_dup 0)
19958 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19961 (and:SI (match_dup 2) (match_dup 3)))])]
19964 ;; We don't need to handle HImode case, because it will be promoted to SImode
19965 ;; on ! TARGET_PARTIAL_REG_STALL
19968 [(set (match_operand 0 "flags_reg_operand" "")
19969 (match_operator 1 "compare_operator"
19970 [(and:QI (match_operand:QI 2 "register_operand" "")
19971 (match_operand:QI 3 "immediate_operand" ""))
19973 "! TARGET_PARTIAL_REG_STALL
19974 && ix86_match_ccmode (insn, CCNOmode)
19975 && true_regnum (operands[2]) != 0
19976 && peep2_reg_dead_p (1, operands[2])"
19978 [(set (match_dup 0)
19979 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19982 (and:QI (match_dup 2) (match_dup 3)))])]
19986 [(set (match_operand 0 "flags_reg_operand" "")
19987 (match_operator 1 "compare_operator"
19990 (match_operand 2 "ext_register_operand" "")
19993 (match_operand 3 "const_int_operand" ""))
19995 "! TARGET_PARTIAL_REG_STALL
19996 && ix86_match_ccmode (insn, CCNOmode)
19997 && true_regnum (operands[2]) != 0
19998 && peep2_reg_dead_p (1, operands[2])"
19999 [(parallel [(set (match_dup 0)
20008 (set (zero_extract:SI (match_dup 2)
20019 ;; Don't do logical operations with memory inputs.
20021 [(match_scratch:SI 2 "r")
20022 (parallel [(set (match_operand:SI 0 "register_operand" "")
20023 (match_operator:SI 3 "arith_or_logical_operator"
20025 (match_operand:SI 1 "memory_operand" "")]))
20026 (clobber (reg:CC FLAGS_REG))])]
20027 "! optimize_size && ! TARGET_READ_MODIFY"
20028 [(set (match_dup 2) (match_dup 1))
20029 (parallel [(set (match_dup 0)
20030 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20031 (clobber (reg:CC FLAGS_REG))])]
20035 [(match_scratch:SI 2 "r")
20036 (parallel [(set (match_operand:SI 0 "register_operand" "")
20037 (match_operator:SI 3 "arith_or_logical_operator"
20038 [(match_operand:SI 1 "memory_operand" "")
20040 (clobber (reg:CC FLAGS_REG))])]
20041 "! optimize_size && ! TARGET_READ_MODIFY"
20042 [(set (match_dup 2) (match_dup 1))
20043 (parallel [(set (match_dup 0)
20044 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20045 (clobber (reg:CC FLAGS_REG))])]
20048 ; Don't do logical operations with memory outputs
20050 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20051 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20052 ; the same decoder scheduling characteristics as the original.
20055 [(match_scratch:SI 2 "r")
20056 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20057 (match_operator:SI 3 "arith_or_logical_operator"
20059 (match_operand:SI 1 "nonmemory_operand" "")]))
20060 (clobber (reg:CC FLAGS_REG))])]
20061 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20062 [(set (match_dup 2) (match_dup 0))
20063 (parallel [(set (match_dup 2)
20064 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20065 (clobber (reg:CC FLAGS_REG))])
20066 (set (match_dup 0) (match_dup 2))]
20070 [(match_scratch:SI 2 "r")
20071 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20072 (match_operator:SI 3 "arith_or_logical_operator"
20073 [(match_operand:SI 1 "nonmemory_operand" "")
20075 (clobber (reg:CC FLAGS_REG))])]
20076 "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20077 [(set (match_dup 2) (match_dup 0))
20078 (parallel [(set (match_dup 2)
20079 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20080 (clobber (reg:CC FLAGS_REG))])
20081 (set (match_dup 0) (match_dup 2))]
20084 ;; Attempt to always use XOR for zeroing registers.
20086 [(set (match_operand 0 "register_operand" "")
20087 (match_operand 1 "const0_operand" ""))]
20088 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20089 && (! TARGET_USE_MOV0 || optimize_size)
20090 && GENERAL_REG_P (operands[0])
20091 && peep2_regno_dead_p (0, FLAGS_REG)"
20092 [(parallel [(set (match_dup 0) (const_int 0))
20093 (clobber (reg:CC FLAGS_REG))])]
20095 operands[0] = gen_lowpart (word_mode, operands[0]);
20099 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20101 "(GET_MODE (operands[0]) == QImode
20102 || GET_MODE (operands[0]) == HImode)
20103 && (! TARGET_USE_MOV0 || optimize_size)
20104 && peep2_regno_dead_p (0, FLAGS_REG)"
20105 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20106 (clobber (reg:CC FLAGS_REG))])])
20108 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20110 [(set (match_operand 0 "register_operand" "")
20112 "(GET_MODE (operands[0]) == HImode
20113 || GET_MODE (operands[0]) == SImode
20114 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20115 && (optimize_size || TARGET_PENTIUM)
20116 && peep2_regno_dead_p (0, FLAGS_REG)"
20117 [(parallel [(set (match_dup 0) (const_int -1))
20118 (clobber (reg:CC FLAGS_REG))])]
20119 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20122 ;; Attempt to convert simple leas to adds. These can be created by
20125 [(set (match_operand:SI 0 "register_operand" "")
20126 (plus:SI (match_dup 0)
20127 (match_operand:SI 1 "nonmemory_operand" "")))]
20128 "peep2_regno_dead_p (0, FLAGS_REG)"
20129 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20130 (clobber (reg:CC FLAGS_REG))])]
20134 [(set (match_operand:SI 0 "register_operand" "")
20135 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20136 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20137 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20138 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20139 (clobber (reg:CC FLAGS_REG))])]
20140 "operands[2] = gen_lowpart (SImode, operands[2]);")
20143 [(set (match_operand:DI 0 "register_operand" "")
20144 (plus:DI (match_dup 0)
20145 (match_operand:DI 1 "x86_64_general_operand" "")))]
20146 "peep2_regno_dead_p (0, FLAGS_REG)"
20147 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20148 (clobber (reg:CC FLAGS_REG))])]
20152 [(set (match_operand:SI 0 "register_operand" "")
20153 (mult:SI (match_dup 0)
20154 (match_operand:SI 1 "const_int_operand" "")))]
20155 "exact_log2 (INTVAL (operands[1])) >= 0
20156 && peep2_regno_dead_p (0, FLAGS_REG)"
20157 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20158 (clobber (reg:CC FLAGS_REG))])]
20159 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20162 [(set (match_operand:DI 0 "register_operand" "")
20163 (mult:DI (match_dup 0)
20164 (match_operand:DI 1 "const_int_operand" "")))]
20165 "exact_log2 (INTVAL (operands[1])) >= 0
20166 && peep2_regno_dead_p (0, FLAGS_REG)"
20167 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20168 (clobber (reg:CC FLAGS_REG))])]
20169 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20172 [(set (match_operand:SI 0 "register_operand" "")
20173 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20174 (match_operand:DI 2 "const_int_operand" "")) 0))]
20175 "exact_log2 (INTVAL (operands[2])) >= 0
20176 && REGNO (operands[0]) == REGNO (operands[1])
20177 && peep2_regno_dead_p (0, FLAGS_REG)"
20178 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20179 (clobber (reg:CC FLAGS_REG))])]
20180 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20182 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20183 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20184 ;; many CPUs it is also faster, since special hardware to avoid esp
20185 ;; dependencies is present.
20187 ;; While some of these conversions may be done using splitters, we use peepholes
20188 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20190 ;; Convert prologue esp subtractions to push.
20191 ;; We need register to push. In order to keep verify_flow_info happy we have
20193 ;; - use scratch and clobber it in order to avoid dependencies
20194 ;; - use already live register
20195 ;; We can't use the second way right now, since there is no reliable way how to
20196 ;; verify that given register is live. First choice will also most likely in
20197 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20198 ;; call clobbered registers are dead. We may want to use base pointer as an
20199 ;; alternative when no register is available later.
20202 [(match_scratch:SI 0 "r")
20203 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20204 (clobber (reg:CC FLAGS_REG))
20205 (clobber (mem:BLK (scratch)))])]
20206 "optimize_size || !TARGET_SUB_ESP_4"
20207 [(clobber (match_dup 0))
20208 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20209 (clobber (mem:BLK (scratch)))])])
20212 [(match_scratch:SI 0 "r")
20213 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20214 (clobber (reg:CC FLAGS_REG))
20215 (clobber (mem:BLK (scratch)))])]
20216 "optimize_size || !TARGET_SUB_ESP_8"
20217 [(clobber (match_dup 0))
20218 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20219 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20220 (clobber (mem:BLK (scratch)))])])
20222 ;; Convert esp subtractions to push.
20224 [(match_scratch:SI 0 "r")
20225 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20226 (clobber (reg:CC FLAGS_REG))])]
20227 "optimize_size || !TARGET_SUB_ESP_4"
20228 [(clobber (match_dup 0))
20229 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20232 [(match_scratch:SI 0 "r")
20233 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20234 (clobber (reg:CC FLAGS_REG))])]
20235 "optimize_size || !TARGET_SUB_ESP_8"
20236 [(clobber (match_dup 0))
20237 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20238 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20240 ;; Convert epilogue deallocator to pop.
20242 [(match_scratch:SI 0 "r")
20243 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20244 (clobber (reg:CC FLAGS_REG))
20245 (clobber (mem:BLK (scratch)))])]
20246 "optimize_size || !TARGET_ADD_ESP_4"
20247 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20248 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20249 (clobber (mem:BLK (scratch)))])]
20252 ;; Two pops case is tricky, since pop causes dependency on destination register.
20253 ;; We use two registers if available.
20255 [(match_scratch:SI 0 "r")
20256 (match_scratch:SI 1 "r")
20257 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20258 (clobber (reg:CC FLAGS_REG))
20259 (clobber (mem:BLK (scratch)))])]
20260 "optimize_size || !TARGET_ADD_ESP_8"
20261 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20262 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20263 (clobber (mem:BLK (scratch)))])
20264 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20265 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20269 [(match_scratch:SI 0 "r")
20270 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20271 (clobber (reg:CC FLAGS_REG))
20272 (clobber (mem:BLK (scratch)))])]
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 (clobber (mem:BLK (scratch)))])
20277 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20278 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20281 ;; Convert esp additions to pop.
20283 [(match_scratch:SI 0 "r")
20284 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20285 (clobber (reg:CC FLAGS_REG))])]
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 ;; Two pops case is tricky, since pop causes dependency on destination register.
20292 ;; We use two registers if available.
20294 [(match_scratch:SI 0 "r")
20295 (match_scratch:SI 1 "r")
20296 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20297 (clobber (reg:CC FLAGS_REG))])]
20299 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20300 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20301 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20302 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20306 [(match_scratch:SI 0 "r")
20307 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20308 (clobber (reg:CC FLAGS_REG))])]
20310 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20311 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20312 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20313 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20316 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20317 ;; required and register dies. Similarly for 128 to plus -128.
20319 [(set (match_operand 0 "flags_reg_operand" "")
20320 (match_operator 1 "compare_operator"
20321 [(match_operand 2 "register_operand" "")
20322 (match_operand 3 "const_int_operand" "")]))]
20323 "(INTVAL (operands[3]) == -1
20324 || INTVAL (operands[3]) == 1
20325 || INTVAL (operands[3]) == 128)
20326 && ix86_match_ccmode (insn, CCGCmode)
20327 && peep2_reg_dead_p (1, operands[2])"
20328 [(parallel [(set (match_dup 0)
20329 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20330 (clobber (match_dup 2))])]
20334 [(match_scratch:DI 0 "r")
20335 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20336 (clobber (reg:CC FLAGS_REG))
20337 (clobber (mem:BLK (scratch)))])]
20338 "optimize_size || !TARGET_SUB_ESP_4"
20339 [(clobber (match_dup 0))
20340 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20341 (clobber (mem:BLK (scratch)))])])
20344 [(match_scratch:DI 0 "r")
20345 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20346 (clobber (reg:CC FLAGS_REG))
20347 (clobber (mem:BLK (scratch)))])]
20348 "optimize_size || !TARGET_SUB_ESP_8"
20349 [(clobber (match_dup 0))
20350 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20351 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20352 (clobber (mem:BLK (scratch)))])])
20354 ;; Convert esp subtractions to push.
20356 [(match_scratch:DI 0 "r")
20357 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20358 (clobber (reg:CC FLAGS_REG))])]
20359 "optimize_size || !TARGET_SUB_ESP_4"
20360 [(clobber (match_dup 0))
20361 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20364 [(match_scratch:DI 0 "r")
20365 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20366 (clobber (reg:CC FLAGS_REG))])]
20367 "optimize_size || !TARGET_SUB_ESP_8"
20368 [(clobber (match_dup 0))
20369 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20370 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20372 ;; Convert epilogue deallocator to pop.
20374 [(match_scratch:DI 0 "r")
20375 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20376 (clobber (reg:CC FLAGS_REG))
20377 (clobber (mem:BLK (scratch)))])]
20378 "optimize_size || !TARGET_ADD_ESP_4"
20379 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20380 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20381 (clobber (mem:BLK (scratch)))])]
20384 ;; Two pops case is tricky, since pop causes dependency on destination register.
20385 ;; We use two registers if available.
20387 [(match_scratch:DI 0 "r")
20388 (match_scratch:DI 1 "r")
20389 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20390 (clobber (reg:CC FLAGS_REG))
20391 (clobber (mem:BLK (scratch)))])]
20392 "optimize_size || !TARGET_ADD_ESP_8"
20393 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20394 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20395 (clobber (mem:BLK (scratch)))])
20396 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20397 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20401 [(match_scratch:DI 0 "r")
20402 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20403 (clobber (reg:CC FLAGS_REG))
20404 (clobber (mem:BLK (scratch)))])]
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 (clobber (mem:BLK (scratch)))])
20409 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20410 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20413 ;; Convert esp additions to pop.
20415 [(match_scratch:DI 0 "r")
20416 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20417 (clobber (reg:CC FLAGS_REG))])]
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 ;; Two pops case is tricky, since pop causes dependency on destination register.
20424 ;; We use two registers if available.
20426 [(match_scratch:DI 0 "r")
20427 (match_scratch:DI 1 "r")
20428 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20429 (clobber (reg:CC FLAGS_REG))])]
20431 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20432 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20433 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20434 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20438 [(match_scratch:DI 0 "r")
20439 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20440 (clobber (reg:CC FLAGS_REG))])]
20442 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20443 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20444 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20445 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20448 ;; Convert imul by three, five and nine into lea
20451 [(set (match_operand:SI 0 "register_operand" "")
20452 (mult:SI (match_operand:SI 1 "register_operand" "")
20453 (match_operand:SI 2 "const_int_operand" "")))
20454 (clobber (reg:CC FLAGS_REG))])]
20455 "INTVAL (operands[2]) == 3
20456 || INTVAL (operands[2]) == 5
20457 || INTVAL (operands[2]) == 9"
20458 [(set (match_dup 0)
20459 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20461 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20465 [(set (match_operand:SI 0 "register_operand" "")
20466 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20467 (match_operand:SI 2 "const_int_operand" "")))
20468 (clobber (reg:CC FLAGS_REG))])]
20470 && (INTVAL (operands[2]) == 3
20471 || INTVAL (operands[2]) == 5
20472 || INTVAL (operands[2]) == 9)"
20473 [(set (match_dup 0) (match_dup 1))
20475 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20477 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20481 [(set (match_operand:DI 0 "register_operand" "")
20482 (mult:DI (match_operand:DI 1 "register_operand" "")
20483 (match_operand:DI 2 "const_int_operand" "")))
20484 (clobber (reg:CC FLAGS_REG))])]
20486 && (INTVAL (operands[2]) == 3
20487 || INTVAL (operands[2]) == 5
20488 || INTVAL (operands[2]) == 9)"
20489 [(set (match_dup 0)
20490 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20492 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20496 [(set (match_operand:DI 0 "register_operand" "")
20497 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20498 (match_operand:DI 2 "const_int_operand" "")))
20499 (clobber (reg:CC FLAGS_REG))])]
20502 && (INTVAL (operands[2]) == 3
20503 || INTVAL (operands[2]) == 5
20504 || INTVAL (operands[2]) == 9)"
20505 [(set (match_dup 0) (match_dup 1))
20507 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20509 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20511 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20512 ;; imul $32bit_imm, reg, reg is direct decoded.
20514 [(match_scratch:DI 3 "r")
20515 (parallel [(set (match_operand:DI 0 "register_operand" "")
20516 (mult:DI (match_operand:DI 1 "memory_operand" "")
20517 (match_operand:DI 2 "immediate_operand" "")))
20518 (clobber (reg:CC FLAGS_REG))])]
20519 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20520 && !satisfies_constraint_K (operands[2])"
20521 [(set (match_dup 3) (match_dup 1))
20522 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20523 (clobber (reg:CC FLAGS_REG))])]
20527 [(match_scratch:SI 3 "r")
20528 (parallel [(set (match_operand:SI 0 "register_operand" "")
20529 (mult:SI (match_operand:SI 1 "memory_operand" "")
20530 (match_operand:SI 2 "immediate_operand" "")))
20531 (clobber (reg:CC FLAGS_REG))])]
20532 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20533 && !satisfies_constraint_K (operands[2])"
20534 [(set (match_dup 3) (match_dup 1))
20535 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20536 (clobber (reg:CC FLAGS_REG))])]
20540 [(match_scratch:SI 3 "r")
20541 (parallel [(set (match_operand:DI 0 "register_operand" "")
20543 (mult:SI (match_operand:SI 1 "memory_operand" "")
20544 (match_operand:SI 2 "immediate_operand" ""))))
20545 (clobber (reg:CC FLAGS_REG))])]
20546 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20547 && !satisfies_constraint_K (operands[2])"
20548 [(set (match_dup 3) (match_dup 1))
20549 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20550 (clobber (reg:CC FLAGS_REG))])]
20553 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20554 ;; Convert it into imul reg, reg
20555 ;; It would be better to force assembler to encode instruction using long
20556 ;; immediate, but there is apparently no way to do so.
20558 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20559 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20560 (match_operand:DI 2 "const_int_operand" "")))
20561 (clobber (reg:CC FLAGS_REG))])
20562 (match_scratch:DI 3 "r")]
20563 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20564 && satisfies_constraint_K (operands[2])"
20565 [(set (match_dup 3) (match_dup 2))
20566 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20567 (clobber (reg:CC FLAGS_REG))])]
20569 if (!rtx_equal_p (operands[0], operands[1]))
20570 emit_move_insn (operands[0], operands[1]);
20574 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20575 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20576 (match_operand:SI 2 "const_int_operand" "")))
20577 (clobber (reg:CC FLAGS_REG))])
20578 (match_scratch:SI 3 "r")]
20579 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size
20580 && satisfies_constraint_K (operands[2])"
20581 [(set (match_dup 3) (match_dup 2))
20582 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20583 (clobber (reg:CC FLAGS_REG))])]
20585 if (!rtx_equal_p (operands[0], operands[1]))
20586 emit_move_insn (operands[0], operands[1]);
20590 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20591 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20592 (match_operand:HI 2 "immediate_operand" "")))
20593 (clobber (reg:CC FLAGS_REG))])
20594 (match_scratch:HI 3 "r")]
20595 "(TARGET_K8 || TARGET_GENERIC64) && !optimize_size"
20596 [(set (match_dup 3) (match_dup 2))
20597 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20598 (clobber (reg:CC FLAGS_REG))])]
20600 if (!rtx_equal_p (operands[0], operands[1]))
20601 emit_move_insn (operands[0], operands[1]);
20604 ;; After splitting up read-modify operations, array accesses with memory
20605 ;; operands might end up in form:
20607 ;; movl 4(%esp), %edx
20609 ;; instead of pre-splitting:
20611 ;; addl 4(%esp), %eax
20613 ;; movl 4(%esp), %edx
20614 ;; leal (%edx,%eax,4), %eax
20617 [(parallel [(set (match_operand 0 "register_operand" "")
20618 (ashift (match_operand 1 "register_operand" "")
20619 (match_operand 2 "const_int_operand" "")))
20620 (clobber (reg:CC FLAGS_REG))])
20621 (set (match_operand 3 "register_operand")
20622 (match_operand 4 "x86_64_general_operand" ""))
20623 (parallel [(set (match_operand 5 "register_operand" "")
20624 (plus (match_operand 6 "register_operand" "")
20625 (match_operand 7 "register_operand" "")))
20626 (clobber (reg:CC FLAGS_REG))])]
20627 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20628 /* Validate MODE for lea. */
20629 && ((!TARGET_PARTIAL_REG_STALL
20630 && (GET_MODE (operands[0]) == QImode
20631 || GET_MODE (operands[0]) == HImode))
20632 || GET_MODE (operands[0]) == SImode
20633 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20634 /* We reorder load and the shift. */
20635 && !rtx_equal_p (operands[1], operands[3])
20636 && !reg_overlap_mentioned_p (operands[0], operands[4])
20637 /* Last PLUS must consist of operand 0 and 3. */
20638 && !rtx_equal_p (operands[0], operands[3])
20639 && (rtx_equal_p (operands[3], operands[6])
20640 || rtx_equal_p (operands[3], operands[7]))
20641 && (rtx_equal_p (operands[0], operands[6])
20642 || rtx_equal_p (operands[0], operands[7]))
20643 /* The intermediate operand 0 must die or be same as output. */
20644 && (rtx_equal_p (operands[0], operands[5])
20645 || peep2_reg_dead_p (3, operands[0]))"
20646 [(set (match_dup 3) (match_dup 4))
20647 (set (match_dup 0) (match_dup 1))]
20649 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20650 int scale = 1 << INTVAL (operands[2]);
20651 rtx index = gen_lowpart (Pmode, operands[1]);
20652 rtx base = gen_lowpart (Pmode, operands[3]);
20653 rtx dest = gen_lowpart (mode, operands[5]);
20655 operands[1] = gen_rtx_PLUS (Pmode, base,
20656 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20658 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20659 operands[0] = dest;
20662 ;; Call-value patterns last so that the wildcard operand does not
20663 ;; disrupt insn-recog's switch tables.
20665 (define_insn "*call_value_pop_0"
20666 [(set (match_operand 0 "" "")
20667 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20668 (match_operand:SI 2 "" "")))
20669 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20670 (match_operand:SI 3 "immediate_operand" "")))]
20673 if (SIBLING_CALL_P (insn))
20676 return "call\t%P1";
20678 [(set_attr "type" "callv")])
20680 (define_insn "*call_value_pop_1"
20681 [(set (match_operand 0 "" "")
20682 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20683 (match_operand:SI 2 "" "")))
20684 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20685 (match_operand:SI 3 "immediate_operand" "i")))]
20688 if (constant_call_address_operand (operands[1], Pmode))
20690 if (SIBLING_CALL_P (insn))
20693 return "call\t%P1";
20695 if (SIBLING_CALL_P (insn))
20698 return "call\t%A1";
20700 [(set_attr "type" "callv")])
20702 (define_insn "*call_value_0"
20703 [(set (match_operand 0 "" "")
20704 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20705 (match_operand:SI 2 "" "")))]
20708 if (SIBLING_CALL_P (insn))
20711 return "call\t%P1";
20713 [(set_attr "type" "callv")])
20715 (define_insn "*call_value_0_rex64"
20716 [(set (match_operand 0 "" "")
20717 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20718 (match_operand:DI 2 "const_int_operand" "")))]
20721 if (SIBLING_CALL_P (insn))
20724 return "call\t%P1";
20726 [(set_attr "type" "callv")])
20728 (define_insn "*call_value_1"
20729 [(set (match_operand 0 "" "")
20730 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20731 (match_operand:SI 2 "" "")))]
20732 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20734 if (constant_call_address_operand (operands[1], Pmode))
20735 return "call\t%P1";
20736 return "call\t%A1";
20738 [(set_attr "type" "callv")])
20740 (define_insn "*sibcall_value_1"
20741 [(set (match_operand 0 "" "")
20742 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20743 (match_operand:SI 2 "" "")))]
20744 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20746 if (constant_call_address_operand (operands[1], Pmode))
20750 [(set_attr "type" "callv")])
20752 (define_insn "*call_value_1_rex64"
20753 [(set (match_operand 0 "" "")
20754 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20755 (match_operand:DI 2 "" "")))]
20756 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20758 if (constant_call_address_operand (operands[1], Pmode))
20759 return "call\t%P1";
20760 return "call\t%A1";
20762 [(set_attr "type" "callv")])
20764 (define_insn "*sibcall_value_1_rex64"
20765 [(set (match_operand 0 "" "")
20766 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20767 (match_operand:DI 2 "" "")))]
20768 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20770 [(set_attr "type" "callv")])
20772 (define_insn "*sibcall_value_1_rex64_v"
20773 [(set (match_operand 0 "" "")
20774 (call (mem:QI (reg:DI R11_REG))
20775 (match_operand:DI 1 "" "")))]
20776 "SIBLING_CALL_P (insn) && TARGET_64BIT"
20778 [(set_attr "type" "callv")])
20780 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20781 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20782 ;; caught for use by garbage collectors and the like. Using an insn that
20783 ;; maps to SIGILL makes it more likely the program will rightfully die.
20784 ;; Keeping with tradition, "6" is in honor of #UD.
20785 (define_insn "trap"
20786 [(trap_if (const_int 1) (const_int 6))]
20788 { return ASM_SHORT "0x0b0f"; }
20789 [(set_attr "length" "2")])
20791 (define_expand "sse_prologue_save"
20792 [(parallel [(set (match_operand:BLK 0 "" "")
20793 (unspec:BLK [(reg:DI 22)
20800 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20801 (use (match_operand:DI 1 "register_operand" ""))
20802 (use (match_operand:DI 2 "immediate_operand" ""))
20803 (use (label_ref:DI (match_operand 3 "" "")))])]
20807 (define_insn "*sse_prologue_save_insn"
20808 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20809 (match_operand:DI 4 "const_int_operand" "n")))
20810 (unspec:BLK [(reg:DI 22)
20817 (reg:DI 29)] UNSPEC_SSE_PROLOGUE_SAVE))
20818 (use (match_operand:DI 1 "register_operand" "r"))
20819 (use (match_operand:DI 2 "const_int_operand" "i"))
20820 (use (label_ref:DI (match_operand 3 "" "X")))]
20822 && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20823 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20827 operands[0] = gen_rtx_MEM (Pmode,
20828 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20829 output_asm_insn (\"jmp\\t%A1\", operands);
20830 for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20832 operands[4] = adjust_address (operands[0], DImode, i*16);
20833 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20834 PUT_MODE (operands[4], TImode);
20835 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20836 output_asm_insn (\"rex\", operands);
20837 output_asm_insn (\"movaps\\t{%5, %4|%4, %5}\", operands);
20839 (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
20840 CODE_LABEL_NUMBER (operands[3]));
20844 [(set_attr "type" "other")
20845 (set_attr "length_immediate" "0")
20846 (set_attr "length_address" "0")
20847 (set_attr "length" "135")
20848 (set_attr "memory" "store")
20849 (set_attr "modrm" "0")
20850 (set_attr "mode" "DI")])
20852 (define_expand "prefetch"
20853 [(prefetch (match_operand 0 "address_operand" "")
20854 (match_operand:SI 1 "const_int_operand" "")
20855 (match_operand:SI 2 "const_int_operand" ""))]
20856 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20858 int rw = INTVAL (operands[1]);
20859 int locality = INTVAL (operands[2]);
20861 gcc_assert (rw == 0 || rw == 1);
20862 gcc_assert (locality >= 0 && locality <= 3);
20863 gcc_assert (GET_MODE (operands[0]) == Pmode
20864 || GET_MODE (operands[0]) == VOIDmode);
20866 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20867 supported by SSE counterpart or the SSE prefetch is not available
20868 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20870 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20871 operands[2] = GEN_INT (3);
20873 operands[1] = const0_rtx;
20876 (define_insn "*prefetch_sse"
20877 [(prefetch (match_operand:SI 0 "address_operand" "p")
20879 (match_operand:SI 1 "const_int_operand" ""))]
20880 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20882 static const char * const patterns[4] = {
20883 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20886 int locality = INTVAL (operands[1]);
20887 gcc_assert (locality >= 0 && locality <= 3);
20889 return patterns[locality];
20891 [(set_attr "type" "sse")
20892 (set_attr "memory" "none")])
20894 (define_insn "*prefetch_sse_rex"
20895 [(prefetch (match_operand:DI 0 "address_operand" "p")
20897 (match_operand:SI 1 "const_int_operand" ""))]
20898 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20900 static const char * const patterns[4] = {
20901 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20904 int locality = INTVAL (operands[1]);
20905 gcc_assert (locality >= 0 && locality <= 3);
20907 return patterns[locality];
20909 [(set_attr "type" "sse")
20910 (set_attr "memory" "none")])
20912 (define_insn "*prefetch_3dnow"
20913 [(prefetch (match_operand:SI 0 "address_operand" "p")
20914 (match_operand:SI 1 "const_int_operand" "n")
20916 "TARGET_3DNOW && !TARGET_64BIT"
20918 if (INTVAL (operands[1]) == 0)
20919 return "prefetch\t%a0";
20921 return "prefetchw\t%a0";
20923 [(set_attr "type" "mmx")
20924 (set_attr "memory" "none")])
20926 (define_insn "*prefetch_3dnow_rex"
20927 [(prefetch (match_operand:DI 0 "address_operand" "p")
20928 (match_operand:SI 1 "const_int_operand" "n")
20930 "TARGET_3DNOW && TARGET_64BIT"
20932 if (INTVAL (operands[1]) == 0)
20933 return "prefetch\t%a0";
20935 return "prefetchw\t%a0";
20937 [(set_attr "type" "mmx")
20938 (set_attr "memory" "none")])
20940 (define_expand "stack_protect_set"
20941 [(match_operand 0 "memory_operand" "")
20942 (match_operand 1 "memory_operand" "")]
20945 #ifdef TARGET_THREAD_SSP_OFFSET
20947 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20948 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20950 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20951 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20954 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20956 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20961 (define_insn "stack_protect_set_si"
20962 [(set (match_operand:SI 0 "memory_operand" "=m")
20963 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20964 (set (match_scratch:SI 2 "=&r") (const_int 0))
20965 (clobber (reg:CC FLAGS_REG))]
20967 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20968 [(set_attr "type" "multi")])
20970 (define_insn "stack_protect_set_di"
20971 [(set (match_operand:DI 0 "memory_operand" "=m")
20972 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20973 (set (match_scratch:DI 2 "=&r") (const_int 0))
20974 (clobber (reg:CC FLAGS_REG))]
20976 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20977 [(set_attr "type" "multi")])
20979 (define_insn "stack_tls_protect_set_si"
20980 [(set (match_operand:SI 0 "memory_operand" "=m")
20981 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20982 (set (match_scratch:SI 2 "=&r") (const_int 0))
20983 (clobber (reg:CC FLAGS_REG))]
20985 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR %%gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20986 [(set_attr "type" "multi")])
20988 (define_insn "stack_tls_protect_set_di"
20989 [(set (match_operand:DI 0 "memory_operand" "=m")
20990 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20991 (set (match_scratch:DI 2 "=&r") (const_int 0))
20992 (clobber (reg:CC FLAGS_REG))]
20995 /* The kernel uses a different segment register for performance reasons; a
20996 system call would not have to trash the userspace segment register,
20997 which would be expensive */
20998 if (ix86_cmodel != CM_KERNEL)
20999 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR %%fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21001 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR %%gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21003 [(set_attr "type" "multi")])
21005 (define_expand "stack_protect_test"
21006 [(match_operand 0 "memory_operand" "")
21007 (match_operand 1 "memory_operand" "")
21008 (match_operand 2 "" "")]
21011 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21012 ix86_compare_op0 = operands[0];
21013 ix86_compare_op1 = operands[1];
21014 ix86_compare_emitted = flags;
21016 #ifdef TARGET_THREAD_SSP_OFFSET
21018 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21019 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21021 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21022 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21025 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21027 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21029 emit_jump_insn (gen_beq (operands[2]));
21033 (define_insn "stack_protect_test_si"
21034 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21035 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21036 (match_operand:SI 2 "memory_operand" "m")]
21038 (clobber (match_scratch:SI 3 "=&r"))]
21040 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21041 [(set_attr "type" "multi")])
21043 (define_insn "stack_protect_test_di"
21044 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21045 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21046 (match_operand:DI 2 "memory_operand" "m")]
21048 (clobber (match_scratch:DI 3 "=&r"))]
21050 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21051 [(set_attr "type" "multi")])
21053 (define_insn "stack_tls_protect_test_si"
21054 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21055 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21056 (match_operand:SI 2 "const_int_operand" "i")]
21057 UNSPEC_SP_TLS_TEST))
21058 (clobber (match_scratch:SI 3 "=r"))]
21060 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR %%gs:%P2}"
21061 [(set_attr "type" "multi")])
21063 (define_insn "stack_tls_protect_test_di"
21064 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21065 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21066 (match_operand:DI 2 "const_int_operand" "i")]
21067 UNSPEC_SP_TLS_TEST))
21068 (clobber (match_scratch:DI 3 "=r"))]
21071 /* The kernel uses a different segment register for performance reasons; a
21072 system call would not have to trash the userspace segment register,
21073 which would be expensive */
21074 if (ix86_cmodel != CM_KERNEL)
21075 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR %%fs:%P2}";
21077 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR %%gs:%P2}";
21079 [(set_attr "type" "multi")])
21083 (include "sync.md")